feat: return typed values from Code Mode
This commit is contained in:
@@ -92,7 +92,7 @@
|
||||
{"type":"assistant/chunk","seq":90,"time":1783611772685,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":"return"}}}
|
||||
{"type":"assistant/chunk","seq":91,"time":1783611772685,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":" out"}}}
|
||||
{"type":"assistant/chunk","seq":92,"time":1783611772713,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":"1"}}}
|
||||
{"type":"assistant/chunk","seq":93,"time":1783611772714,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":".trim"}}}
|
||||
{"type":"assistant/chunk","seq":93,"time":1783611772714,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":".stdout.text.trim"}}}
|
||||
{"type":"assistant/chunk","seq":94,"time":1783611772714,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":"()"}}}
|
||||
{"type":"assistant/chunk","seq":95,"time":1783611772714,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":" +"}}}
|
||||
{"type":"assistant/chunk","seq":96,"time":1783611772714,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":" \\\"+"}}}
|
||||
@@ -100,16 +100,16 @@
|
||||
{"type":"assistant/chunk","seq":98,"time":1783611772744,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":" +"}}}
|
||||
{"type":"assistant/chunk","seq":99,"time":1783611772745,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":" out"}}}
|
||||
{"type":"assistant/chunk","seq":100,"time":1783611772745,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":"2"}}}
|
||||
{"type":"assistant/chunk","seq":101,"time":1783611772745,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":".trim"}}}
|
||||
{"type":"assistant/chunk","seq":101,"time":1783611772745,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":".stdout.text.trim"}}}
|
||||
{"type":"assistant/chunk","seq":102,"time":1783611772745,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":"();"}}}
|
||||
{"type":"assistant/chunk","seq":103,"time":1783611772772,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":"\""}}}
|
||||
{"type":"assistant/chunk","seq":104,"time":1783611772773,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","argumentsDelta":"}"}}}
|
||||
{"type":"assistant/chunk","seq":105,"time":1783611772836,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants a single run_code program that calls bash twice, then returns the two outputs joined with a plus sign. Let me write this."}}}}
|
||||
{"type":"assistant/chunk","seq":106,"time":1783611772836,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","arguments":"{\"code\": \"const out1 = await tools.bash({ command: \\\"echo CODE_ONE\\\", description: \\\"First echo\\\" });\\nconst out2 = await tools.bash({ command: \\\"echo CODE_TWO\\\", description: \\\"Second echo\\\" });\\nreturn out1.trim() + \\\"+\\\" + out2.trim();\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":106,"time":1783611772836,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","arguments":"{\"code\": \"const out1 = await tools.bash({ command: \\\"echo CODE_ONE\\\", description: \\\"First echo\\\" });\\nconst out2 = await tools.bash({ command: \\\"echo CODE_TWO\\\", description: \\\"Second echo\\\" });\\nreturn out1.stdout.text.trim() + \\\"+\\\" + out2.stdout.text.trim();\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":107,"time":1783611772836,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3009,"outputTokens":133,"cacheReadTokens":0,"reasoningTokens":29}}}}
|
||||
{"type":"assistant/chunk","seq":108,"time":1783611772836,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":109,"time":1783611772840,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants a single run_code program that calls bash twice, then returns the two outputs joined with a plus sign. Let me write this."},{"type":"tool-call","id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","arguments":"{\"code\": \"const out1 = await tools.bash({ command: \\\"echo CODE_ONE\\\", description: \\\"First echo\\\" });\\nconst out2 = await tools.bash({ command: \\\"echo CODE_TWO\\\", description: \\\"Second echo\\\" });\\nreturn out1.trim() + \\\"+\\\" + out2.trim();\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3009,"outputTokens":133,"cacheReadTokens":0,"reasoningTokens":29}},"sourceEventSeqs":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":110,"time":1783611772840,"data":{"turn":1,"step":1,"callId":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","arguments":"{\"code\": \"const out1 = await tools.bash({ command: \\\"echo CODE_ONE\\\", description: \\\"First echo\\\" });\\nconst out2 = await tools.bash({ command: \\\"echo CODE_TWO\\\", description: \\\"Second echo\\\" });\\nreturn out1.trim() + \\\"+\\\" + out2.trim();\"}"}}
|
||||
{"type":"assistant/message","seq":109,"time":1783611772840,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants a single run_code program that calls bash twice, then returns the two outputs joined with a plus sign. Let me write this."},{"type":"tool-call","id":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","arguments":"{\"code\": \"const out1 = await tools.bash({ command: \\\"echo CODE_ONE\\\", description: \\\"First echo\\\" });\\nconst out2 = await tools.bash({ command: \\\"echo CODE_TWO\\\", description: \\\"Second echo\\\" });\\nreturn out1.stdout.text.trim() + \\\"+\\\" + out2.stdout.text.trim();\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3009,"outputTokens":133,"cacheReadTokens":0,"reasoningTokens":29}},"sourceEventSeqs":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":110,"time":1783611772840,"data":{"turn":1,"step":1,"callId":"call_00_DRxnM6R1TThfDwcudW0f2050","name":"run_code","arguments":"{\"code\": \"const out1 = await tools.bash({ command: \\\"echo CODE_ONE\\\", description: \\\"First echo\\\" });\\nconst out2 = await tools.bash({ command: \\\"echo CODE_TWO\\\", description: \\\"Second echo\\\" });\\nreturn out1.stdout.text.trim() + \\\"+\\\" + out2.stdout.text.trim();\"}"}}
|
||||
{"type":"tool/code-dispatch","seq":111,"time":1783611772933,"data":{"parentCallId":"call_00_DRxnM6R1TThfDwcudW0f2050","subCallId":"call_00_DRxnM6R1TThfDwcudW0f2050:code:1","name":"bash","arguments":{"command":"echo CODE_ONE","description":"First echo"},"isError":false,"resultSummary":"CODE_ONE\n"}}
|
||||
{"type":"tool/code-dispatch","seq":112,"time":1783611772936,"data":{"parentCallId":"call_00_DRxnM6R1TThfDwcudW0f2050","subCallId":"call_00_DRxnM6R1TThfDwcudW0f2050:code:2","name":"bash","arguments":{"command":"echo CODE_TWO","description":"Second echo"},"isError":false,"resultSummary":"CODE_TWO\n"}}
|
||||
{"type":"tool/result","seq":113,"time":1783611772937,"data":{"turn":1,"step":1,"callId":"call_00_DRxnM6R1TThfDwcudW0f2050","content":[{"type":"text","text":"CODE_ONE+CODE_TWO"}],"isError":false,"meta":{"logs":[]}},"sourceEventSeqs":[110],"surfaceOp":"append"}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" write"}}}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" this"}}}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"."}}}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call","toolCallId":"call_00_DRxnM6R1TThfDwcudW0f2050","title":"const out1 = await tools.bash({ command: \"echo CODE_ONE\", description: \"First echo\" });\nconst out2 = await tools.bash({ command: \"echo CODE_TWO\", description: \"Second echo\" });\nreturn out1.trim() + \"+\" + out2.trim();","kind":"execute","status":"in_progress","rawInput":"const out1 = await tools.bash({ command: \"echo CODE_ONE\", description: \"First echo\" });\nconst out2 = await tools.bash({ command: \"echo CODE_TWO\", description: \"Second echo\" });\nreturn out1.trim() + \"+\" + out2.trim();"}}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call","toolCallId":"call_00_DRxnM6R1TThfDwcudW0f2050","title":"const out1 = await tools.bash({ command: \"echo CODE_ONE\", description: \"First echo\" });\nconst out2 = await tools.bash({ command: \"echo CODE_TWO\", description: \"Second echo\" });\nreturn out1.stdout.text.trim() + \"+\" + out2.stdout.text.trim();","kind":"execute","status":"in_progress","rawInput":"const out1 = await tools.bash({ command: \"echo CODE_ONE\", description: \"First echo\" });\nconst out2 = await tools.bash({ command: \"echo CODE_TWO\", description: \"Second echo\" });\nreturn out1.stdout.text.trim() + \"+\" + out2.stdout.text.trim();"}}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"tool_call_update","toolCallId":"call_00_DRxnM6R1TThfDwcudW0f2050","status":"completed","content":[{"type":"content","content":{"type":"text","text":"CODE_ONE+CODE_TWO"}}]}}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":"The"}}}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_thought_chunk","content":{"type":"text","text":" output"}}}}
|
||||
|
||||
@@ -28,8 +28,8 @@ Use the ralph tool ONLY when the direct human explicitly asks for a Ralph loop o
|
||||
|
||||
Pass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:
|
||||
|
||||
- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools["my-tool"](args)`. Every call resolves to the tool's text output as a string. Tool arguments must be JSON-serializable.
|
||||
- A FAILED tool call rejects with an `Error` carrying the tool's error text — `try/catch` it to handle and continue.
|
||||
- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools["my-tool"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.
|
||||
- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.
|
||||
- Calls execute sequentially, even under `Promise.all`.
|
||||
- Emit results with `return` and/or `console.log(...)`. ONLY what you print or return comes back to you — intermediate tool results never enter the conversation, so extract just what you need.
|
||||
|
||||
@@ -38,9 +38,9 @@ The available tools:
|
||||
```ts
|
||||
type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }
|
||||
|
||||
declare const tools: {
|
||||
interface ToolArgsMap {
|
||||
/** Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under <mode> mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. Attempting a command the sandbox may deny is safe and expected: run it and read the marker rather than assuming the denial. When a command is denied and a wider mode would let it succeed, escalate immediately in the same turn — the one sanctioned exception to a denial: retry the exact same command once with `sandbox_permissions` (the narrowest wider mode that suffices) plus a one-sentence `justification`. Do not detour through chat to ask permission first — the approval prompt raised by that retry is how the user consents. If the session states approval prompts are disabled, there is no exception: a denial is final — do not set `sandbox_permissions`. Never escalate speculatively: ground the request in a real denial — normally the one this command just hit; escalating up front is fine only when this session already denied the same access. A rejected escalation is final for that command — stop and explain, never work around it — but it does not forbid attempting or escalating other commands later. */
|
||||
bash(args: {
|
||||
bash: {
|
||||
/** The bash command to execute. */
|
||||
command: string;
|
||||
/** Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: "ls" → "List files in current directory"; "git status" → "Show working tree status"; "npm install" → "Install package dependencies". */
|
||||
@@ -55,16 +55,16 @@ declare const tools: {
|
||||
sandbox_permissions?: "workspace-write" | "danger-full-access";
|
||||
/** Required with sandbox_permissions: one sentence for the user explaining why this exact command needs the wider access. */
|
||||
justification?: string;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Create one persisted same-session completion goal when the current direct human request is a long-running objective that should continue across autonomous goal rounds. You may infer that intent without requiring the user to say "create a goal". Do not use this for trivial single-turn work. Execution rejects non-human and subagent authority. */
|
||||
create_goal(args: {
|
||||
create_goal: {
|
||||
/** The concrete completion objective inferred from the direct human request. */
|
||||
objective: string;
|
||||
/** Optional positive safe-integer limit on automatic continuation rounds. */
|
||||
max_goal_rounds?: number;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Edit an existing UTF-8 text file by replacing literal text. */
|
||||
edit(args: {
|
||||
edit: {
|
||||
/** Path to edit, resolved by the filesystem backend. */
|
||||
file_path: string;
|
||||
/** Literal text to replace. Must match exactly. */
|
||||
@@ -77,68 +77,68 @@ declare const tools: {
|
||||
sandbox_permissions?: "workspace-write" | "danger-full-access";
|
||||
/** Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access. */
|
||||
justification?: string;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Read the current same-session goal, including its exact id/revision, objective, phase, completed continuation rounds, round limit, blocker reason when present, and whether another continuation is armed. Call this before updating a goal. */
|
||||
get_goal(args: Record<string, JsonValue>): Promise<string>;
|
||||
get_goal: Record<string, JsonValue>;
|
||||
/** Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools. */
|
||||
ralph(args: {
|
||||
ralph: {
|
||||
/** The immutable completion objective for every fresh Ralph round. */
|
||||
objective: string;
|
||||
/** Optional positive safe-integer round cap, bounded by the deployment ceiling. */
|
||||
maxRounds?: number;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Read a UTF-8 text file and return line-numbered content. */
|
||||
read(args: {
|
||||
read: {
|
||||
/** Path to read, resolved by the filesystem backend. */
|
||||
file_path: string;
|
||||
/** 1-based first line to return. Defaults to 1. */
|
||||
offset?: number;
|
||||
/** Maximum number of lines to return. Defaults to 2000. */
|
||||
limit?: number;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */
|
||||
skill(args: {
|
||||
skill: {
|
||||
/** The exact skill name from the available skills list. */
|
||||
name: string;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to return a task id; collect with `task_output` and stop with `task_kill`. */
|
||||
subagent(args: {
|
||||
subagent: {
|
||||
/** A short (3-5 word) description of the delegated task, for display. */
|
||||
description: string;
|
||||
/** The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs. */
|
||||
prompt: string;
|
||||
/** Run as a background task and return its id; collect with task_output or stop with task_kill. */
|
||||
run_in_background?: boolean;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to return a task id; collect with `task_output` and stop with `task_kill`. */
|
||||
subagent_fork(args: {
|
||||
subagent_fork: {
|
||||
/** A short (3-5 word) description of the delegated task, for display. */
|
||||
description: string;
|
||||
/** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */
|
||||
prompt: string;
|
||||
/** Run as a background task and return its id; collect with task_output or stop with task_kill. */
|
||||
run_in_background?: boolean;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */
|
||||
task_kill(args: {
|
||||
task_kill: {
|
||||
/** Task id returned by the tool that started the background work. */
|
||||
task_id: string;
|
||||
/** Optional short reason, recorded in the log and forwarded to the task. */
|
||||
reason?: string;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** List your background tasks (running and finished) with their ids, kinds, and statuses. */
|
||||
task_list(args: Record<string, JsonValue>): Promise<string>;
|
||||
task_list: Record<string, JsonValue>;
|
||||
/** Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */
|
||||
task_output(args: {
|
||||
task_output: {
|
||||
/** Task id returned by the tool that started the background work. */
|
||||
task_id: string;
|
||||
/** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */
|
||||
wait?: boolean;
|
||||
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
|
||||
timeout_ms?: number;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Keep AT MOST ONE todo `in_progress` at a time; while work remains, exactly one active task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished). */
|
||||
todo_write(args: {
|
||||
todo_write: {
|
||||
/** The COMPLETE task list, replacing any previous list. */
|
||||
todos: ({
|
||||
/** What the task is — a short imperative line. */
|
||||
@@ -146,9 +146,9 @@ declare const tools: {
|
||||
/** pending (not started) | in_progress (now) | completed (done). */
|
||||
status: "pending" | "in_progress" | "completed";
|
||||
} & Record<string, JsonValue>)[];
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Update the exact current goal revision. edit, pause, and resume require a direct top-level human request. During an automatic continuation of the current goal, complete and blocked are also allowed. blocked is rejected before the configured minimum round count; the model remains responsible for judging that the same condition persisted across those rounds and must explain it in blocked_reason. */
|
||||
update_goal(args: {
|
||||
update_goal: {
|
||||
/** Exact id returned by get_goal. */
|
||||
goal_id: string;
|
||||
/** Exact positive revision returned by get_goal. */
|
||||
@@ -161,9 +161,9 @@ declare const tools: {
|
||||
max_goal_rounds?: number;
|
||||
/** Concrete blocking condition; required only with action blocked. */
|
||||
blocked_reason?: string;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn. The workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return <value>` — the value must be JSON-serializable and is this tool's result. Script-body hooks: - `agent(prompt, opts?): Promise<any>` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const — no oneOf/pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly. - `pipeline(items, ...stages): Promise<any[]>` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages. - `parallel(thunks): Promise<any[]>` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`. - `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim. Misused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`. Constraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes. */
|
||||
workflow(args: {
|
||||
workflow: {
|
||||
/** The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return <json-value>`). */
|
||||
script: string;
|
||||
/** The workflow identity block (plain JSON — never code). */
|
||||
@@ -188,9 +188,9 @@ declare const tools: {
|
||||
} & Record<string, JsonValue>;
|
||||
/** Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {"files": [...]}). */
|
||||
args?: Record<string, JsonValue>;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Create or fully replace a UTF-8 text file. */
|
||||
write(args: {
|
||||
write: {
|
||||
/** Path to write, resolved by the filesystem backend. */
|
||||
file_path: string;
|
||||
/** Full UTF-8 text content to write. */
|
||||
@@ -199,6 +199,203 @@ declare const tools: {
|
||||
sandbox_permissions?: "workspace-write" | "danger-full-access";
|
||||
/** Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access. */
|
||||
justification?: string;
|
||||
} & Record<string, JsonValue>): Promise<string>;
|
||||
} & Record<string, JsonValue>;
|
||||
}
|
||||
|
||||
interface ToolOutputMap {
|
||||
bash: {
|
||||
kind: "background";
|
||||
taskId: string;
|
||||
} | {
|
||||
kind: "foreground";
|
||||
exitCode: number | null;
|
||||
signal: string | null;
|
||||
timedOut: boolean;
|
||||
aborted: boolean;
|
||||
timeoutMs: number;
|
||||
stdout: {
|
||||
text: string;
|
||||
truncated: boolean;
|
||||
spillPath?: string;
|
||||
};
|
||||
stderr: {
|
||||
text: string;
|
||||
truncated: boolean;
|
||||
spillPath?: string;
|
||||
};
|
||||
sandbox?: {
|
||||
mode: string;
|
||||
denied: boolean;
|
||||
enforcement?: string;
|
||||
runnerFailed?: boolean;
|
||||
};
|
||||
};
|
||||
create_goal: {
|
||||
goal: null;
|
||||
} | {
|
||||
goal: {
|
||||
id: string;
|
||||
revision: number;
|
||||
objective: string;
|
||||
phase: "active" | "paused" | "blocked" | "complete";
|
||||
roundsStarted: number;
|
||||
maxGoalRounds: number;
|
||||
blockedReason?: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
};
|
||||
activation: "armed" | "disarmed";
|
||||
};
|
||||
edit: {
|
||||
path: string;
|
||||
before: string;
|
||||
after: string;
|
||||
};
|
||||
get_goal: {
|
||||
goal: null;
|
||||
} | {
|
||||
goal: {
|
||||
id: string;
|
||||
revision: number;
|
||||
objective: string;
|
||||
phase: "active" | "paused" | "blocked" | "complete";
|
||||
roundsStarted: number;
|
||||
maxGoalRounds: number;
|
||||
blockedReason?: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
};
|
||||
activation: "armed" | "disarmed";
|
||||
};
|
||||
ralph: {
|
||||
runId: string;
|
||||
agentsStarted: number;
|
||||
result: JsonValue;
|
||||
};
|
||||
read: {
|
||||
path: string;
|
||||
offset: number;
|
||||
lines: {
|
||||
number: number;
|
||||
text: string;
|
||||
}[];
|
||||
totalLines: number;
|
||||
};
|
||||
skill: {
|
||||
name: string;
|
||||
provider: string;
|
||||
resourceBase?: {
|
||||
kind: "directory";
|
||||
path: string;
|
||||
} | {
|
||||
kind: "url";
|
||||
url: string;
|
||||
} | {
|
||||
kind: "opaque";
|
||||
description: string;
|
||||
};
|
||||
content: string;
|
||||
};
|
||||
subagent: {
|
||||
kind: "background";
|
||||
taskId: string;
|
||||
} | {
|
||||
kind: "foreground";
|
||||
runId: string;
|
||||
output: JsonValue[];
|
||||
};
|
||||
subagent_fork: {
|
||||
kind: "background";
|
||||
taskId: string;
|
||||
} | {
|
||||
kind: "foreground";
|
||||
runId: string;
|
||||
output: JsonValue[];
|
||||
};
|
||||
task_kill: {
|
||||
outcome: "cancellation-requested" | "already-finished";
|
||||
task: {
|
||||
id: string;
|
||||
kind: string;
|
||||
label: string;
|
||||
status: "running" | "stopping" | "completed" | "killed" | "failed";
|
||||
detail?: string;
|
||||
startedAt: number;
|
||||
finishedAt?: number;
|
||||
};
|
||||
};
|
||||
task_list: ({
|
||||
id: string;
|
||||
kind: string;
|
||||
label: string;
|
||||
status: "running" | "stopping" | "completed" | "killed" | "failed";
|
||||
detail?: string;
|
||||
startedAt: number;
|
||||
finishedAt?: number;
|
||||
})[];
|
||||
task_output: {
|
||||
text: string;
|
||||
task: {
|
||||
id: string;
|
||||
kind: string;
|
||||
label: string;
|
||||
status: "running" | "stopping" | "completed" | "killed" | "failed";
|
||||
detail?: string;
|
||||
startedAt: number;
|
||||
finishedAt?: number;
|
||||
};
|
||||
};
|
||||
todo_write: {
|
||||
todos: ({
|
||||
content: string;
|
||||
status: "pending" | "in_progress" | "completed";
|
||||
})[];
|
||||
counts: {
|
||||
pending: number;
|
||||
inProgress: number;
|
||||
completed: number;
|
||||
};
|
||||
};
|
||||
update_goal: {
|
||||
goal: null;
|
||||
} | {
|
||||
goal: {
|
||||
id: string;
|
||||
revision: number;
|
||||
objective: string;
|
||||
phase: "active" | "paused" | "blocked" | "complete";
|
||||
roundsStarted: number;
|
||||
maxGoalRounds: number;
|
||||
blockedReason?: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
};
|
||||
activation: "armed" | "disarmed";
|
||||
};
|
||||
workflow: {
|
||||
runId: string;
|
||||
agentsStarted: number;
|
||||
result: JsonValue;
|
||||
};
|
||||
write: {
|
||||
path: string;
|
||||
operation: "create" | "update";
|
||||
before: string | null;
|
||||
after: string;
|
||||
};
|
||||
}
|
||||
|
||||
type ToolName = keyof ToolOutputMap
|
||||
|
||||
declare class ToolCallError extends Error {
|
||||
readonly name: "ToolCallError";
|
||||
readonly toolName: ToolName;
|
||||
}
|
||||
|
||||
declare const tools: {
|
||||
[K in ToolName]: (args: ToolArgsMap[K]) => Promise<ToolOutputMap[K]>;
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user