mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-23 14:45:46 +00:00
refactor(agents): enrich tool descriptions
This commit is contained in:
@@ -52,6 +52,7 @@ import {
|
||||
truncateMiddle,
|
||||
} from "./bash-tools.shared.js";
|
||||
import { assertSandboxPath } from "./sandbox-paths.js";
|
||||
import { EXEC_TOOL_DISPLAY_SUMMARY } from "./tool-description-presets.js";
|
||||
import { failedTextResult, textResult } from "./tools/common.js";
|
||||
|
||||
export type { BashSandboxConfig } from "./bash-tools.shared.js";
|
||||
@@ -1219,6 +1220,7 @@ export function createExecTool(
|
||||
return {
|
||||
name: "exec",
|
||||
label: "exec",
|
||||
displaySummary: EXEC_TOOL_DISPLAY_SUMMARY,
|
||||
get description() {
|
||||
return describeExecTool({ agentId, hasCronTool: defaults?.hasCronTool === true });
|
||||
},
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
import { deriveSessionName, pad, sliceLogLines, truncateMiddle } from "./bash-tools.shared.js";
|
||||
import { recordCommandPoll, resetCommandPollCount } from "./command-poll-backoff.js";
|
||||
import { encodeKeySequence, encodePaste, hasCursorModeSensitiveKeys } from "./pty-keys.js";
|
||||
import { PROCESS_TOOL_DISPLAY_SUMMARY } from "./tool-description-presets.js";
|
||||
|
||||
export type ProcessToolDefaults = {
|
||||
cleanupMs?: number;
|
||||
@@ -162,6 +163,7 @@ export function createProcessTool(
|
||||
return {
|
||||
name: "process",
|
||||
label: "process",
|
||||
displaySummary: PROCESS_TOOL_DISPLAY_SUMMARY,
|
||||
description: describeProcessTool({ hasCronTool: defaults?.hasCronTool === true }),
|
||||
parameters: processSchema,
|
||||
execute: async (_toolCallId, args, _signal, _onUpdate): Promise<AgentToolResult<unknown>> => {
|
||||
|
||||
@@ -440,8 +440,12 @@ describe("buildAgentSystemPrompt", () => {
|
||||
docsPath: "/tmp/openclaw/docs",
|
||||
});
|
||||
|
||||
expect(prompt).toContain("- Read: Read file contents");
|
||||
expect(prompt).toContain("- Exec: Run shell commands");
|
||||
expect(prompt).toContain(
|
||||
"Tool names are case-sensitive. Call tools exactly as listed in the structured tool definitions.",
|
||||
);
|
||||
expect(prompt).toContain(
|
||||
"For long waits, avoid rapid poll loops: use Exec with enough yieldMs or process(action=poll, timeout=<ms>).",
|
||||
);
|
||||
expect(prompt).toContain(
|
||||
"- If exactly one skill clearly applies: read its SKILL.md at <location> with `Read`, then follow it.",
|
||||
);
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
import {
|
||||
CRON_TOOL_DISPLAY_SUMMARY,
|
||||
EXEC_TOOL_DISPLAY_SUMMARY,
|
||||
PROCESS_TOOL_DISPLAY_SUMMARY,
|
||||
SESSIONS_HISTORY_TOOL_DISPLAY_SUMMARY,
|
||||
SESSIONS_LIST_TOOL_DISPLAY_SUMMARY,
|
||||
SESSIONS_SEND_TOOL_DISPLAY_SUMMARY,
|
||||
SESSIONS_SPAWN_TOOL_DISPLAY_SUMMARY,
|
||||
SESSION_STATUS_TOOL_DISPLAY_SUMMARY,
|
||||
} from "./tool-description-presets.js";
|
||||
|
||||
export type ToolProfileId = "minimal" | "coding" | "messaging" | "full";
|
||||
|
||||
type ToolProfilePolicy = {
|
||||
@@ -70,14 +81,14 @@ const CORE_TOOL_DEFINITIONS: CoreToolDefinition[] = [
|
||||
{
|
||||
id: "exec",
|
||||
label: "exec",
|
||||
description: "Run shell commands",
|
||||
description: EXEC_TOOL_DISPLAY_SUMMARY,
|
||||
sectionId: "runtime",
|
||||
profiles: ["coding"],
|
||||
},
|
||||
{
|
||||
id: "process",
|
||||
label: "process",
|
||||
description: "Manage background processes",
|
||||
description: PROCESS_TOOL_DISPLAY_SUMMARY,
|
||||
sectionId: "runtime",
|
||||
profiles: ["coding"],
|
||||
},
|
||||
@@ -132,7 +143,7 @@ const CORE_TOOL_DEFINITIONS: CoreToolDefinition[] = [
|
||||
{
|
||||
id: "sessions_list",
|
||||
label: "sessions_list",
|
||||
description: "List sessions",
|
||||
description: SESSIONS_LIST_TOOL_DISPLAY_SUMMARY,
|
||||
sectionId: "sessions",
|
||||
profiles: ["coding", "messaging"],
|
||||
includeInOpenClawGroup: true,
|
||||
@@ -140,7 +151,7 @@ const CORE_TOOL_DEFINITIONS: CoreToolDefinition[] = [
|
||||
{
|
||||
id: "sessions_history",
|
||||
label: "sessions_history",
|
||||
description: "Session history",
|
||||
description: SESSIONS_HISTORY_TOOL_DISPLAY_SUMMARY,
|
||||
sectionId: "sessions",
|
||||
profiles: ["coding", "messaging"],
|
||||
includeInOpenClawGroup: true,
|
||||
@@ -148,7 +159,7 @@ const CORE_TOOL_DEFINITIONS: CoreToolDefinition[] = [
|
||||
{
|
||||
id: "sessions_send",
|
||||
label: "sessions_send",
|
||||
description: "Send to session",
|
||||
description: SESSIONS_SEND_TOOL_DISPLAY_SUMMARY,
|
||||
sectionId: "sessions",
|
||||
profiles: ["coding", "messaging"],
|
||||
includeInOpenClawGroup: true,
|
||||
@@ -156,7 +167,7 @@ const CORE_TOOL_DEFINITIONS: CoreToolDefinition[] = [
|
||||
{
|
||||
id: "sessions_spawn",
|
||||
label: "sessions_spawn",
|
||||
description: "Spawn sub-agent",
|
||||
description: SESSIONS_SPAWN_TOOL_DISPLAY_SUMMARY,
|
||||
sectionId: "sessions",
|
||||
profiles: ["coding"],
|
||||
includeInOpenClawGroup: true,
|
||||
@@ -180,7 +191,7 @@ const CORE_TOOL_DEFINITIONS: CoreToolDefinition[] = [
|
||||
{
|
||||
id: "session_status",
|
||||
label: "session_status",
|
||||
description: "Session status",
|
||||
description: SESSION_STATUS_TOOL_DISPLAY_SUMMARY,
|
||||
sectionId: "sessions",
|
||||
profiles: ["minimal", "coding", "messaging"],
|
||||
includeInOpenClawGroup: true,
|
||||
@@ -212,7 +223,7 @@ const CORE_TOOL_DEFINITIONS: CoreToolDefinition[] = [
|
||||
{
|
||||
id: "cron",
|
||||
label: "cron",
|
||||
description: "Schedule tasks",
|
||||
description: CRON_TOOL_DISPLAY_SUMMARY,
|
||||
sectionId: "automation",
|
||||
profiles: ["coding"],
|
||||
includeInOpenClawGroup: true,
|
||||
|
||||
48
src/agents/tool-description-presets.ts
Normal file
48
src/agents/tool-description-presets.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
export const EXEC_TOOL_DISPLAY_SUMMARY = "Run shell commands that start now.";
|
||||
export const PROCESS_TOOL_DISPLAY_SUMMARY = "Inspect and control running exec sessions.";
|
||||
export const CRON_TOOL_DISPLAY_SUMMARY = "Schedule cron jobs, reminders, and wake events.";
|
||||
export const SESSIONS_LIST_TOOL_DISPLAY_SUMMARY =
|
||||
"List visible sessions and optional recent messages.";
|
||||
export const SESSIONS_HISTORY_TOOL_DISPLAY_SUMMARY =
|
||||
"Read sanitized message history for a visible session.";
|
||||
export const SESSIONS_SEND_TOOL_DISPLAY_SUMMARY = "Send a message to another visible session.";
|
||||
export const SESSIONS_SPAWN_TOOL_DISPLAY_SUMMARY = "Spawn sub-agent or ACP sessions.";
|
||||
export const SESSION_STATUS_TOOL_DISPLAY_SUMMARY = "Show session status, usage, and model state.";
|
||||
|
||||
export function describeSessionsListTool(): string {
|
||||
return [
|
||||
"List visible sessions with optional filters for kind, recent activity, and last messages.",
|
||||
"Use this to discover a target session before calling sessions_history or sessions_send.",
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
export function describeSessionsHistoryTool(): string {
|
||||
return [
|
||||
"Fetch sanitized message history for a visible session.",
|
||||
"Supports limits and optional tool messages; use this to inspect another session before replying, debugging, or resuming work.",
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
export function describeSessionsSendTool(): string {
|
||||
return [
|
||||
"Send a message into another visible session by sessionKey or label.",
|
||||
"Use this to delegate follow-up work to an existing session; waits for the target run and returns the updated assistant reply when available.",
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
export function describeSessionsSpawnTool(): string {
|
||||
return [
|
||||
'Spawn an isolated session with `runtime="subagent"` or `runtime="acp"`.',
|
||||
'`mode="run"` is one-shot and `mode="session"` is persistent or thread-bound.',
|
||||
"Subagents inherit the parent workspace directory automatically.",
|
||||
"Use this when the work should happen in a fresh child session instead of the current one.",
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
export function describeSessionStatusTool(): string {
|
||||
return [
|
||||
"Show a /status-equivalent session status card for the current or another visible session, including usage, time, cost when available, and linked background task context.",
|
||||
"Optional `model` sets a per-session model override; `model=default` resets overrides.",
|
||||
"Use this for questions like what model is active or how a session is configured.",
|
||||
].join(" ");
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { extractTextFromChatContent } from "../../shared/chat-content.js";
|
||||
import { isRecord, truncateUtf16Safe } from "../../utils.js";
|
||||
import { resolveSessionAgentId } from "../agent-scope.js";
|
||||
import { optionalStringEnum, stringEnum } from "../schema/typebox.js";
|
||||
import { CRON_TOOL_DISPLAY_SUMMARY } from "../tool-description-presets.js";
|
||||
import { type AnyAgentTool, jsonResult, readStringParam } from "./common.js";
|
||||
import { callGatewayTool, readGatewayCallOptions, type GatewayCallOptions } from "./gateway.js";
|
||||
import { resolveInternalSessionKey, resolveMainSessionAlias } from "./sessions-helpers.js";
|
||||
@@ -424,7 +425,7 @@ export function createCronTool(opts?: CronToolOptions, deps?: CronToolDeps): Any
|
||||
label: "Cron",
|
||||
name: "cron",
|
||||
ownerOnly: true,
|
||||
displaySummary: "Schedule and manage cron jobs and wake events.",
|
||||
displaySummary: CRON_TOOL_DISPLAY_SUMMARY,
|
||||
description: `Manage Gateway cron jobs (status/list/add/update/remove/run/runs) and send wake events. Use this for reminders, "check back later" requests, delayed follow-ups, and recurring tasks. Do not emulate scheduling with exec sleep or process polling.
|
||||
|
||||
Main-session cron jobs enqueue system events for heartbeat handling. Isolated cron jobs create background task runs that appear in \`openclaw tasks\`.
|
||||
|
||||
@@ -32,6 +32,10 @@ import {
|
||||
resolveDefaultModelForAgent,
|
||||
resolveModelRefFromString,
|
||||
} from "../model-selection.js";
|
||||
import {
|
||||
describeSessionStatusTool,
|
||||
SESSION_STATUS_TOOL_DISPLAY_SUMMARY,
|
||||
} from "../tool-description-presets.js";
|
||||
import type { AnyAgentTool } from "./common.js";
|
||||
import { readStringParam } from "./common.js";
|
||||
import {
|
||||
@@ -212,8 +216,8 @@ export function createSessionStatusTool(opts?: {
|
||||
return {
|
||||
label: "Session Status",
|
||||
name: "session_status",
|
||||
description:
|
||||
"Show a /status-equivalent session status card (usage + time + cost when available), including linked background task context when present. Use for model-use questions (📊 session_status). Optional: set per-session model override (model=default resets overrides).",
|
||||
displaySummary: SESSION_STATUS_TOOL_DISPLAY_SUMMARY,
|
||||
description: describeSessionStatusTool(),
|
||||
parameters: SessionStatusToolSchema,
|
||||
execute: async (_toolCallId, args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
|
||||
@@ -5,6 +5,10 @@ import { capArrayByJsonBytes } from "../../gateway/session-utils.fs.js";
|
||||
import { jsonUtf8Bytes } from "../../infra/json-utf8-bytes.js";
|
||||
import { redactSensitiveText } from "../../logging/redact.js";
|
||||
import { truncateUtf16Safe } from "../../utils.js";
|
||||
import {
|
||||
describeSessionsHistoryTool,
|
||||
SESSIONS_HISTORY_TOOL_DISPLAY_SUMMARY,
|
||||
} from "../tool-description-presets.js";
|
||||
import type { AnyAgentTool } from "./common.js";
|
||||
import { jsonResult, readStringParam } from "./common.js";
|
||||
import {
|
||||
@@ -176,7 +180,8 @@ export function createSessionsHistoryTool(opts?: {
|
||||
return {
|
||||
label: "Session History",
|
||||
name: "sessions_history",
|
||||
description: "Fetch message history for a session.",
|
||||
displaySummary: SESSIONS_HISTORY_TOOL_DISPLAY_SUMMARY,
|
||||
description: describeSessionsHistoryTool(),
|
||||
parameters: SessionsHistoryToolSchema,
|
||||
execute: async (_toolCallId, args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
|
||||
@@ -8,6 +8,10 @@ import {
|
||||
} from "../../config/sessions.js";
|
||||
import { callGateway } from "../../gateway/call.js";
|
||||
import { resolveAgentIdFromSessionKey } from "../../routing/session-key.js";
|
||||
import {
|
||||
describeSessionsListTool,
|
||||
SESSIONS_LIST_TOOL_DISPLAY_SUMMARY,
|
||||
} from "../tool-description-presets.js";
|
||||
import type { AnyAgentTool } from "./common.js";
|
||||
import { jsonResult, readStringArrayParam } from "./common.js";
|
||||
import {
|
||||
@@ -41,7 +45,8 @@ export function createSessionsListTool(opts?: {
|
||||
return {
|
||||
label: "Sessions",
|
||||
name: "sessions_list",
|
||||
description: "List sessions with optional filters and last messages.",
|
||||
displaySummary: SESSIONS_LIST_TOOL_DISPLAY_SUMMARY,
|
||||
description: describeSessionsListTool(),
|
||||
parameters: SessionsListToolSchema,
|
||||
execute: async (_toolCallId, args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
|
||||
@@ -13,6 +13,10 @@ import {
|
||||
readLatestAssistantReplySnapshot,
|
||||
waitForAgentRunAndReadUpdatedAssistantReply,
|
||||
} from "../run-wait.js";
|
||||
import {
|
||||
describeSessionsSendTool,
|
||||
SESSIONS_SEND_TOOL_DISPLAY_SUMMARY,
|
||||
} from "../tool-description-presets.js";
|
||||
import type { AnyAgentTool } from "./common.js";
|
||||
import { jsonResult, readStringParam } from "./common.js";
|
||||
import {
|
||||
@@ -78,8 +82,8 @@ export function createSessionsSendTool(opts?: {
|
||||
return {
|
||||
label: "Session Send",
|
||||
name: "sessions_send",
|
||||
description:
|
||||
"Send a message into another session. Use sessionKey or label to identify the target.",
|
||||
displaySummary: SESSIONS_SEND_TOOL_DISPLAY_SUMMARY,
|
||||
description: describeSessionsSendTool(),
|
||||
parameters: SessionsSendToolSchema,
|
||||
execute: async (_toolCallId, args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
|
||||
@@ -8,6 +8,10 @@ import { optionalStringEnum } from "../schema/typebox.js";
|
||||
import type { SpawnedToolContext } from "../spawned-context.js";
|
||||
import { registerSubagentRun } from "../subagent-registry.js";
|
||||
import { SUBAGENT_SPAWN_MODES, spawnSubagentDirect } from "../subagent-spawn.js";
|
||||
import {
|
||||
describeSessionsSpawnTool,
|
||||
SESSIONS_SPAWN_TOOL_DISPLAY_SUMMARY,
|
||||
} from "../tool-description-presets.js";
|
||||
import type { AnyAgentTool } from "./common.js";
|
||||
import { jsonResult, readStringParam, ToolInputError } from "./common.js";
|
||||
import {
|
||||
@@ -131,8 +135,8 @@ export function createSessionsSpawnTool(
|
||||
return {
|
||||
label: "Sessions",
|
||||
name: "sessions_spawn",
|
||||
description:
|
||||
'Spawn an isolated session (runtime="subagent" or runtime="acp"). mode="run" is one-shot and mode="session" is persistent/thread-bound. Subagents inherit the parent workspace directory automatically.',
|
||||
displaySummary: SESSIONS_SPAWN_TOOL_DISPLAY_SUMMARY,
|
||||
description: describeSessionsSpawnTool(),
|
||||
parameters: SessionsSpawnToolSchema,
|
||||
execute: async (_toolCallId, args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
|
||||
Reference in New Issue
Block a user