zidane 8.2.1 → 8.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acp-cli.js +8 -8
- package/dist/{acp-D7Pr8NGt.js → acp-oYRjlh71.js} +6 -6
- package/dist/{acp-D7Pr8NGt.js.map → acp-oYRjlh71.js.map} +1 -1
- package/dist/acp.d.ts +2 -2
- package/dist/acp.js +1 -1
- package/dist/{agent-DecDtKA_.js → agent-CBQglXtH.js} +9 -379
- package/dist/agent-CBQglXtH.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/{builtin-artifact-kinds-B_OEgf8b.js → builtin-artifact-kinds-BmorPkgz.js} +36 -9
- package/dist/builtin-artifact-kinds-BmorPkgz.js.map +1 -0
- package/dist/chat/pure.d.ts +3 -3
- package/dist/chat/pure.js +4 -4
- package/dist/chat.d.ts +4 -4
- package/dist/chat.js +14 -14
- package/dist/{cli-shared-Dx4vmif6.js → cli-shared-E5m_pI8A.js} +2 -2
- package/dist/{cli-shared-Dx4vmif6.js.map → cli-shared-E5m_pI8A.js.map} +1 -1
- package/dist/{client-core-imHuBWV3.d.ts → client-core-BdD20sOv.d.ts} +24 -5
- package/dist/{client-core-imHuBWV3.d.ts.map → client-core-BdD20sOv.d.ts.map} +1 -1
- package/dist/{connection-loop-CdHt3iQi.d.ts → connection-loop-DTk82YVl.d.ts} +3 -3
- package/dist/{connection-loop-CdHt3iQi.d.ts.map → connection-loop-DTk82YVl.d.ts.map} +1 -1
- package/dist/contexts/daytona.d.ts +1 -1
- package/dist/contexts/e2b.d.ts +1 -1
- package/dist/{credentials-Dti61yoi.js → credentials-B9DfBJP9.js} +11 -7
- package/dist/credentials-B9DfBJP9.js.map +1 -0
- package/dist/daemon-cli.js +2 -2
- package/dist/{dispatcher-vy3J6JMA.js → dispatcher-BICXFGiJ.js} +27 -13
- package/dist/dispatcher-BICXFGiJ.js.map +1 -0
- package/dist/{engine-BN6PjWAW.js → engine-QCX3GV-i.js} +5 -5
- package/dist/{engine-BN6PjWAW.js.map → engine-QCX3GV-i.js.map} +1 -1
- package/dist/{eval-BaJtxLCW.js → eval-CfQlBR81.js} +2 -2
- package/dist/{eval-BaJtxLCW.js.map → eval-CfQlBR81.js.map} +1 -1
- package/dist/eval.d.ts +1 -1
- package/dist/eval.js +1 -1
- package/dist/{executor-CT4oUkg6.js → executor-B8GoXaaE.js} +2 -2
- package/dist/{executor-CT4oUkg6.js.map → executor-B8GoXaaE.js.map} +1 -1
- package/dist/{extensions-BKt7lxxv.js → extensions-BeH3D-bq.js} +114 -113
- package/dist/extensions-BeH3D-bq.js.map +1 -0
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +2 -2
- package/dist/{fold-rules-BYedvsH7.d.ts → fold-rules-DSypi36k.d.ts} +2 -2
- package/dist/{fold-rules-BYedvsH7.d.ts.map → fold-rules-DSypi36k.d.ts.map} +1 -1
- package/dist/google-O6pRnddf.js +881 -0
- package/dist/google-O6pRnddf.js.map +1 -0
- package/dist/{headless-Ebd1ZEzC.js → headless-R4pbpTkm.js} +3 -3
- package/dist/{headless-Ebd1ZEzC.js.map → headless-R4pbpTkm.js.map} +1 -1
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -1
- package/dist/{host-scoped-settings-Cy_zbmB_.js → host-scoped-settings-CCnaBkCV.js} +2 -2
- package/dist/{host-scoped-settings-Cy_zbmB_.js.map → host-scoped-settings-CCnaBkCV.js.map} +1 -1
- package/dist/{host-signals-Cx2IAbHh.js → host-signals-DI9JQvR9.js} +5 -5
- package/dist/{host-signals-Cx2IAbHh.js.map → host-signals-DI9JQvR9.js.map} +1 -1
- package/dist/{index-pc71ADi6.d.ts → index-BkNeiJYI.d.ts} +71 -4
- package/dist/index-BkNeiJYI.d.ts.map +1 -0
- package/dist/{index-CidMTcxS.d.ts → index-DyQyDLX1.d.ts} +167 -10
- package/dist/index-DyQyDLX1.d.ts.map +1 -0
- package/dist/{index-Bt_G2Z_2.d.ts → index-lcuvhQfF.d.ts} +5 -5
- package/dist/{index-Bt_G2Z_2.d.ts.map → index-lcuvhQfF.d.ts.map} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +15 -15
- package/dist/ipc/remote.d.ts +5 -5
- package/dist/ipc/remote.js +3 -3
- package/dist/ipc.d.ts +5 -5
- package/dist/ipc.js +6 -6
- package/dist/{links-DSZ4uQ5w.js → links-CN5JFFde.js} +9 -9
- package/dist/{links-DSZ4uQ5w.js.map → links-CN5JFFde.js.map} +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/{oauth-BSqXgads.js → oauth-TVPPye84.js} +155 -25
- package/dist/oauth-TVPPye84.js.map +1 -0
- package/dist/{openai-dTmPxM6T.js → openai-Rh6u5NXF.js} +121 -2
- package/dist/openai-Rh6u5NXF.js.map +1 -0
- package/dist/{openrouter-CtZbQDa0.js → openrouter-Dg0yaI-o.js} +91 -2
- package/dist/openrouter-Dg0yaI-o.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -1
- package/dist/output/terminal.d.ts +1 -1
- package/dist/plugins.d.ts +1 -1
- package/dist/{presets-EzlHyFSi.js → presets-DXeHsd24.js} +3 -3
- package/dist/{presets-EzlHyFSi.js.map → presets-DXeHsd24.js.map} +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -1
- package/dist/{prompts-D2lPHLOV.d.ts → prompts-DmY13jvF.d.ts} +2 -1
- package/dist/prompts-DmY13jvF.d.ts.map +1 -0
- package/dist/protocol-BIv1Yuvl.js.map +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/google.d.ts +1 -1
- package/dist/providers/google.js +1 -784
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/neuralwatt.d.ts +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +1 -101
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +6 -5
- package/dist/{registry-BBaEgTsX.js → registry-PNi9rsGi.js} +3 -3
- package/dist/{registry-BBaEgTsX.js.map → registry-PNi9rsGi.js.map} +1 -1
- package/dist/{remote-hosts-bO7wOt44.js → remote-hosts-b6Luwdhu.js} +4 -4
- package/dist/{remote-hosts-bO7wOt44.js.map → remote-hosts-b6Luwdhu.js.map} +1 -1
- package/dist/restate.d.ts +1 -1
- package/dist/{secret-shapes-Cda65uDH.js → secret-shapes-CEoGmfEE.js} +10 -1
- package/dist/secret-shapes-CEoGmfEE.js.map +1 -0
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/{session-factory-BazyVdzj.js → session-factory-CMwIXE-7.js} +5 -5
- package/dist/{session-factory-BazyVdzj.js.map → session-factory-CMwIXE-7.js.map} +1 -1
- package/dist/session.d.ts +1 -1
- package/dist/{settings-keys-zYaer8DY.js → settings-keys-DssjmqAV.js} +3 -3
- package/dist/{settings-keys-zYaer8DY.js.map → settings-keys-DssjmqAV.js.map} +1 -1
- package/dist/{shell-path-od9XHRPt.js → shell-path-BUFwqU_A.js} +3 -3
- package/dist/{shell-path-od9XHRPt.js.map → shell-path-BUFwqU_A.js.map} +1 -1
- package/dist/{skills-use-D68a1gyZ.js → skills-use-CssTEaIj.js} +375 -2
- package/dist/skills-use-CssTEaIj.js.map +1 -0
- package/dist/skills.d.ts +1 -1
- package/dist/{system-freeze-DXvJpveP.js → system-freeze-Um9ZJiPo.js} +24 -9
- package/dist/system-freeze-Um9ZJiPo.js.map +1 -0
- package/dist/{todo-edits-CmqNFvLJ.js → todo-edits-H77ROt6X.js} +2 -2
- package/dist/{todo-edits-CmqNFvLJ.js.map → todo-edits-H77ROt6X.js.map} +1 -1
- package/dist/tools/fetch-url.d.ts +1 -1
- package/dist/tools/prompts.d.ts +1 -1
- package/dist/tools/prompts.js +7 -0
- package/dist/tools/prompts.js.map +1 -1
- package/dist/tools/web-search.d.ts +1 -1
- package/dist/{tools-9Dpm8F-f.js → tools-pZVFIJ_K.js} +273 -2
- package/dist/tools-pZVFIJ_K.js.map +1 -0
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +4 -4
- package/dist/{transcript-anchors-B3TFJqr_.js → transcript-anchors-s-yxh0jt.js} +10 -10
- package/dist/{transcript-anchors-B3TFJqr_.js.map → transcript-anchors-s-yxh0jt.js.map} +1 -1
- package/dist/{transcript-reconcile-BC2DbTmp.js → transcript-reconcile-DeFLIQ14.js} +19 -2
- package/dist/{transcript-reconcile-BC2DbTmp.js.map → transcript-reconcile-DeFLIQ14.js.map} +1 -1
- package/dist/tui.d.ts +7 -7
- package/dist/tui.js +24 -22
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-CIFoOebZ.d.ts → turn-operations-BbGJ-KSt.d.ts} +2 -2
- package/dist/{turn-operations-CIFoOebZ.d.ts.map → turn-operations-BbGJ-KSt.d.ts.map} +1 -1
- package/dist/{types-iFLlZKd0.d.ts → types-C0PJmBaO.d.ts} +2 -2
- package/dist/{types-iFLlZKd0.d.ts.map → types-C0PJmBaO.d.ts.map} +1 -1
- package/dist/types-JzccL5GE.js +24 -0
- package/dist/types-JzccL5GE.js.map +1 -0
- package/dist/types.d.ts +2 -2
- package/dist/{url-BTH-HE9Y.js → url-CLl0u4Z8.js} +2 -2
- package/dist/{url-BTH-HE9Y.js.map → url-CLl0u4Z8.js.map} +1 -1
- package/dist/{version-4T82xRxQ.js → version-v77Y4A3C.js} +2 -2
- package/dist/{version-4T82xRxQ.js.map → version-v77Y4A3C.js.map} +1 -1
- package/dist/wire-DH77Z-rr.js +80 -0
- package/dist/wire-DH77Z-rr.js.map +1 -0
- package/dist/{workspace-exec-stream-By8na6vz.js → workspace-exec-stream-kqARO8iC.js} +4 -4
- package/dist/{workspace-exec-stream-By8na6vz.js.map → workspace-exec-stream-kqARO8iC.js.map} +1 -1
- package/dist/{write-file-B4vi3SvQ.js → write-file-QYrcDdl3.js} +3 -3
- package/dist/{write-file-B4vi3SvQ.js.map → write-file-QYrcDdl3.js.map} +1 -1
- package/dist/{ws-CS312Jpx.js → ws-BD9FN98u.js} +5 -5
- package/dist/{ws-CS312Jpx.js.map → ws-BD9FN98u.js.map} +1 -1
- package/dist/{ws-client-wWka-Jku.js → ws-client-D7eb2UbH.js} +3 -3
- package/dist/{ws-client-wWka-Jku.js.map → ws-client-D7eb2UbH.js.map} +1 -1
- package/dist/xai-CStTwCV2.js +182 -0
- package/dist/xai-CStTwCV2.js.map +1 -0
- package/docs/ARCHITECTURE.md +1 -0
- package/docs/ARTIFACTS.md +1 -1
- package/docs/EXTENSIONS.md +9 -5
- package/package.json +2 -2
- package/dist/agent-DecDtKA_.js.map +0 -1
- package/dist/builtin-artifact-kinds-B_OEgf8b.js.map +0 -1
- package/dist/credentials-Dti61yoi.js.map +0 -1
- package/dist/dispatcher-vy3J6JMA.js.map +0 -1
- package/dist/extensions-BKt7lxxv.js.map +0 -1
- package/dist/index-CidMTcxS.d.ts.map +0 -1
- package/dist/index-pc71ADi6.d.ts.map +0 -1
- package/dist/oauth-BSqXgads.js.map +0 -1
- package/dist/openai-dTmPxM6T.js.map +0 -1
- package/dist/openrouter-CtZbQDa0.js.map +0 -1
- package/dist/prompts-D2lPHLOV.d.ts.map +0 -1
- package/dist/providers/google.js.map +0 -1
- package/dist/providers/xai.js.map +0 -1
- package/dist/secret-shapes-Cda65uDH.js.map +0 -1
- package/dist/skills-use-D68a1gyZ.js.map +0 -1
- package/dist/system-freeze-DXvJpveP.js.map +0 -1
- package/dist/tools-9Dpm8F-f.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { QT as ToolDef } from "../index-DyQyDLX1.js";
|
|
2
2
|
//#region src/tools/fetch-url.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Tells whether an IP address is in a range the SSRF guard refuses: loopback, private, link-local, multicast and similar. Anything that is not an IP literal is refused too.
|
package/dist/tools/prompts.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as toolPrompts, t as ToolPrompts } from "../prompts-
|
|
1
|
+
import { n as toolPrompts, t as ToolPrompts } from "../prompts-DmY13jvF.js";
|
|
2
2
|
export { ToolPrompts, toolPrompts };
|
package/dist/tools/prompts.js
CHANGED
|
@@ -64,6 +64,13 @@ const toolPrompts = {
|
|
|
64
64
|
"By default it returns only the turns added since your last read; pass `mode: \"recent\"` for the latest turns regardless.",
|
|
65
65
|
"Read-only, and bound to that one conversation: it accepts no session id."
|
|
66
66
|
].join("\n"),
|
|
67
|
+
generate_image: [
|
|
68
|
+
"Generate images from a text prompt with an image model and save them as files in the workspace.",
|
|
69
|
+
"Use it when the user asks for an image asset: a texture, icon, sprite, illustration, concept art or mockup.",
|
|
70
|
+
"To edit an image or match its style, pass workspace image paths in `references` (models marked [ref]). To keep a set of assets consistent, pass an earlier result as a reference.",
|
|
71
|
+
"The result shows a small preview. Use `read_file` on the saved file to look at it in full.",
|
|
72
|
+
"Every call costs money on the provider. Generate one image, look at it, then adjust the prompt."
|
|
73
|
+
].join("\n"),
|
|
67
74
|
model_search: [
|
|
68
75
|
"List the models available for spawned subagents, with per-Mtok pricing and context windows.",
|
|
69
76
|
"Use it to cost-tier delegation: find a cheap, fast model for mechanical or high-volume work before calling `spawn` with its id in the `model` field.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","names":[],"sources":["../../src/tools/prompts.ts"],"sourcesContent":["/**\n * Every native tool's LLM-facing description, in one place.\n *\n * This module is the source of truth: each tool file imports its\n * `spec.description` from here rather than inlining it. It has no runtime\n * dependencies (pure strings and tiny template functions) so hosts can import\n * it from a config file — `zidane/tools/prompts` — read the defaults, and feed\n * adjusted text into `AgentOptions.toolDescriptions`:\n *\n * ```ts\n * import { toolPrompts } from 'zidane/tools/prompts'\n *\n * createAgent({\n * toolDescriptions: {\n * read_file: toolPrompts.read_file.replace('Claude Code', 'the editor'),\n * shell: cur => cur.replace(toolPrompts.shell.core, myShellIntro),\n * },\n * })\n * ```\n *\n * Scope is the top-level `spec.description` — the surface `toolDescriptions`\n * overrides. Parameter descriptions live with their schemas in the tool files.\n *\n * Static tools are plain strings. Tools whose description depends on runtime\n * configuration expose named fragments the factory joins conditionally; the\n * fragments are the exact bytes the model receives, so `String#replace`\n * against them is a precise edit.\n */\n\nexport const toolPrompts = {\n read_file: 'Read a file by path. Text files return lines [offset..offset+limit). Default offset=1, limit=2000; a negative offset reads from the end (`-50` = last 50 lines). Pass `paths` to read several files, or several ranges of one file, in one call. Each line is prefixed with its 1-indexed line number followed by a tab (e.g. `42\\\\tconst foo = bar`); the prefix is metadata, not part of the file. Mirrors Claude Code\\'s `cat -n`-style compact output for token efficiency. A trailing footer explains how to read the rest when truncated. Images (png/jpg/gif/webp) and PDFs return structured attachments for capable models; other binary files return a short marker rather than mojibake.',\n\n write_file: 'Write `content` to `path`, creating any missing parent directories. Overwrites existing files in full; prefer `edit` / `multi_edit` for surgical changes when you only want to alter part of a file. Returns one of: `Created <path> (N bytes)` (file did not exist), `Updated <path> (N bytes)` (content differed), or `No change needed: <path> already at target state (N bytes)`, so the model can detect no-ops without a separate `read_file`. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.',\n\n edit: 'Replace exact `old_string` with `new_string` in a file. Fails if `old_string` is not unique unless `replace_all: true`. Prefer over `write_file` for surgical changes: preserves the rest of the file. Tolerates `read_file` line-number prefixes (`<N>\\\\t…`, `<N>|…`, or `<N>→…`) in `old_string` / `new_string`; they are stripped before matching/writing, so you can paste a numbered chunk verbatim. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.',\n\n multi_edit: 'Apply a sequential list of edits to a file. Each edit operates on the result of the previous APPLIED edit. Prefer this over multiple `edit` calls when several non-overlapping changes are needed in the same file. Edits run best-effort: a per-step failure (`old_string` not found, ambiguous match without `replace_all`, identical strings) is reported in the result but does NOT block the remaining steps. The file is written iff at least one step applied. The result lists per-hunk outcomes (`applied` / `failed`) so the model can re-issue just the failures without resending the whole batch. Each step tolerates `read_file` line-number prefixes (`<N>\\\\t…`, `<N>|…`, or `<N>→…`) in `old_string` / `new_string`. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.',\n\n glob: 'Match files by glob pattern (supports **, *, ?). Relative to the execution context cwd; patterns may reach outside the workspace (e.g. \"../shared/**/*.ts\"). By default each row is `<path>\\\\t<size-bytes>\\\\t<mtime-iso>`; set `metadata: false` for a plain newline-separated list of paths. Always sorted.',\n\n grep: 'Search file contents by regex. Returns matching paths (default), match content, or per-file counts. One call covers several patterns (`patterns`), several roots (`paths`), context lines, literal (`fixed_strings`) or whole-word (`-w`) matching, and dropping noise lines (`exclude`); `head_limit` caps output. Backed by ripgrep when available, with a portable shell-listing + regex fallback when `rg` is absent.',\n\n list_files: 'List the immediate entries (files and subdirectories) at literal directory `path`. Returns a newline-separated list; subdirectories carry a trailing `/`; or `(empty directory)` when the directory exists but is empty. Non-recursive: use `glob` for pattern matching across nested directories.',\n\n fetch_url: 'Fetch a public URL and return its body as plain text. HTML is reduced to text (scripts, styles, tags stripped; entities decoded). If a `web_search` tool is also available, use it first when you do not already know the exact URL. Only http(s) URLs are accepted; loopback, link-local, private, and cloud-metadata addresses are refused. Output is capped (default 200 KiB).',\n\n shell_kill: [\n 'Terminate a running background task started by `shell({ run_in_background: true })`.',\n 'Sends SIGTERM to the whole process group so the shell wrapper AND its child commands die together.',\n 'Returns the final exit info (status, exit code, output path) or a \"no such task\" message when the id is unknown / already cleaned up.',\n 'Idempotent: calling on a task that has already terminated returns the cached exit info without re-killing.',\n ].join('\\n'),\n\n wait_task: [\n 'Wait for a background task started by `shell({ run_in_background: true })` to exit, then return its final status.',\n 'Returns immediately when the task has already terminated. On timeout the task keeps running and you can wait again, keep working, or `shell_kill` it.',\n 'Prefer ending your turn and receiving the `<task-notification>` when you have other useful work or nothing depends on the result; use wait_task only when the next step genuinely needs the task\\'s outcome.',\n ].join('\\n'),\n\n record_artifact: [\n 'Record a deliverable this session produced so the user can find it later in the artifacts panel. An artifact is an OUTPUT the user would want a link to — not a step of the work.',\n 'Worth recording: a pull request or merge request URL, a deployment / preview URL, an issue or ticket you filed, a release or tag, a generated report / export / dataset the user asked for, a build output they will pick up.',\n 'Not worth recording: source files you edited or created as part of implementing a change, scratch files, logs, intermediate results, anything already implied by the diff.',\n 'Pull requests from `gh pr create`, `git commit` commits and newly created branches are detected automatically — record those only when the automatic path could not see them (e.g. a PR opened from a background shell task).',\n 'Idempotent per (kind, uri): recording the same artifact again refreshes its label/meta.',\n ].join('\\n'),\n\n read_chat_turns: [\n 'Read selected turns from a previous chat explicitly referenced by the user with `#<chat>` in the current prompt.',\n 'Use this when the user asks to continue from, compare with, or inspect a referenced chat.',\n 'The tool refuses chats that were not referenced in the current user prompt.',\n ].join(' '),\n\n read_parent_session: [\n 'Read the conversation this side chat is about: its live status (running, the tool it is in, how long the run has gone, what it waits on), its todo list, and its turns.',\n 'By default it returns only the turns added since your last read; pass `mode: \"recent\"` for the latest turns regardless.',\n 'Read-only, and bound to that one conversation: it accepts no session id.',\n ].join('\\n'),\n\n model_search: [\n 'List the models available for spawned subagents, with per-Mtok pricing and context windows.',\n 'Use it to cost-tier delegation: find a cheap, fast model for mechanical or high-volume work before calling `spawn` with its id in the `model` field.',\n 'Pass `query` to filter by substring across model id, name, and provider; omit it to list everything.',\n ].join('\\n'),\n\n skills_use: 'Activate or deactivate a specialized skill. '\n + 'Call with `mode: \"activate\"` (default) to load a skill\\'s full instructions when a task matches its catalog description. '\n + 'Call with `mode: \"deactivate\"` to release a skill whose allowed-tools restrictions are now in the way, e.g. when the skill\\'s work is done or the active skill is blocking unrelated tool calls. '\n + 'After activating, follow the returned instructions; use skills_read to load referenced files and skills_run_script to execute bundled scripts.',\n\n skills_read: 'Read a bundled resource file from an active skill. '\n + 'The skill must have been activated via skills_use first. '\n + 'Path is relative to the skill\\'s directory (e.g. \"references/REFERENCE.md\", \"assets/template.txt\").',\n\n skills_run_script: 'Execute a script bundled with an active skill (from its scripts/ directory). '\n + 'The skill must have been activated via skills_use first. '\n + 'Returns stdout, stderr, and the exit code. Honors the script\\'s shebang.',\n\n /** Default for `createInteractionTool` when the host passes no `description`. */\n interaction: 'Request structured input from the user or external system.',\n\n /**\n * `shell` is assembled per run by `createShellTool`: `core` always; the\n * `preferDedicated` block only for sibling tools actually registered\n * (`swapHints` filtered by canonical name, tool names alias-resolved);\n * `background` only when `run_in_background` is available.\n */\n shell: {\n core: [\n 'Execute a shell command from the workspace root (the `Cwd` in your environment) and return its combined stdout/stderr. Every call starts there; `cd` never persists between calls. Use relative paths (`cd src/app && bun test`, `ls docs`), not absolute ones.',\n 'Output is tail-priority truncated at 32 KiB by default; errors and exit-code summaries live in the tail.',\n 'By default each call appends a `(exit N, Nms)` footer and surfaces non-empty stderr in a separate section even on success; set `metadata: false` to return only stdout. Set maxOutputBytes=0 to disable truncation.',\n 'Pass a short `description` (5-10 words) explaining the intent of the command; it surfaces in the user-facing transcript so the human can follow your reasoning at a glance. Skip it only for trivial reads where the command speaks for itself.',\n ].join('\\n'),\n preferDedicated: 'When a dedicated tool fits, prefer it over shell:',\n /** One `- <label>: use \\`<tool>\\` (not <instead>)` line per registered sibling. */\n swapHints: [\n { canonical: 'read_file', label: 'Read files', instead: 'cat/head/tail/sed -n' },\n { canonical: 'glob', label: 'File search', instead: 'find/ls' },\n { canonical: 'grep', label: 'Content search', instead: 'grep/rg' },\n { canonical: 'list_files', label: 'Directory listings', instead: 'ls' },\n { canonical: 'edit', label: 'Edit files', instead: 'sed/awk/python scripts' },\n { canonical: 'write_file', label: 'Write files', instead: 'echo>/heredoc' },\n ],\n reminder: 'Re-running `ls`/`cat` on the same path is not useful: the prior result is still current unless you wrote to that path since.',\n background: [\n 'Long-running commands (`npm run dev`, `python train.py`, anything that would otherwise block your turn for minutes) → `run_in_background: true`. The call returns immediately with `{ task_id, output_path, pid }`; stdout + stderr stream to the log file at `output_path`.',\n 'After spawning a background task: end your current turn (do NOT keep iterating). A `<task-notification>` arrives on the agent\\'s NEXT user-turn with the final status. Polling the log file in a loop wastes tokens and blocks your turn: the notification IS the wake-up. If you NEED to check progress immediately (rare), call `read_file({ path: output_path, ... })` exactly once and decide. To terminate, use `shell_kill({ task_id })`. If, and only if, your very next step depends on the task\\'s outcome, block on it with `wait_task({ task_id })` instead of polling.',\n 'When called from inside a `spawn`\\'d subagent: you have NO next user-turn; your `agent.run` ends as soon as you finish responding. Start the background task, return a brief summary including the `task_id`, and end your turn. Ownership of the task is transferred to the parent agent when your run finishes; the parent will see the notification on ITS next user-turn.',\n ].join('\\n\\n'),\n },\n\n /**\n * `spawn`: `core` always; `modelTiering` when a model catalog is wired;\n * `resume` when the tool persists child turns (`persist: true`).\n */\n spawn: {\n core: 'Spawn a sub-agent for a self-contained task that benefits from isolation (separate context window, separate retries): for example, a deep research dive or a long codegen pass on a specific file. The sub-agent inherits your tool set (including `spawn` itself, depth-capped) and your system prompt unless overridden, runs independently, and returns its final response. Do NOT spawn for sequential steps you could do yourself.',\n modelTiering: ' Children can run on a DIFFERENT model via the `model` field: cost-tier your delegation: mechanical, parallelizable, or high-volume search work belongs on cheaper/faster models, while synthesis and judgment stay on your own model.',\n resume: ' A stopped or failed sub-agent can be CONTINUED instead of restarted: pass `resume` with its child label (e.g. \"child-2\") and put the continuation instruction in `task`; the child picks up with its prior conversation intact.',\n },\n\n /**\n * `tool_search`: `core` + one closing sentence — `callableVia(dispatcher)`\n * in dispatch mode (`call_tool`), `callable` otherwise.\n */\n tool_search: {\n core: [\n 'Discover and load schemas for additional tools listed in <searchable_tools>.',\n 'Tools listed there are advertised by name + description only; their input',\n 'schemas are not loaded into context until you surface them through this tool.',\n 'Pass `query` for a substring search, `names` to load specific tools, or `server`',\n 'to load every tool from one MCP server.',\n ].join(' '),\n callable: 'Returned tools become callable for the rest of this run.',\n callableVia: (dispatcher: string): string =>\n `Returned tools become callable through \\`${dispatcher}\\` (name + arguments) for the rest of this run.`,\n },\n\n /** `call_tool` names the discovery tool (`tool_search` or the host's wire name). */\n call_tool: (discovery: string): string =>\n `Invoke a tool listed in <searchable_tools>. Load its schema with \\`${discovery}\\` first `\n + '(the result shows the exact `name` and input schema), then call it here with `name` '\n + 'set to that tool name and `arguments` set to an object matching its schema. '\n + 'Arguments are validated against the tool\\'s own schema; a validation error names '\n + 'the offending field.',\n\n /** `web_search`: `core` + `recency`. Static, so the tool list stays byte-stable. */\n web_search: {\n core: 'Search the public web and return ranked title / URL / snippet results. '\n + 'Use this to look up documentation, error messages, library versions, or recent events. '\n + 'If a `fetch_url` tool is also available, follow up with it to read a specific page in full.',\n recency: 'IMPORTANT: When you search for recent information, docs, or current events, use the current date '\n + 'from your context, such as the Date line in <env>, not your training cutoff year '\n + '(e.g. search \"React docs\" with the current year, not an older one).',\n },\n} as const\n\n/** Shape of {@link toolPrompts}. */\nexport type ToolPrompts = typeof toolPrompts\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAa,cAAc;CACzB,WAAW;CAEX,YAAY;CAEZ,MAAM;CAEN,YAAY;CAEZ,MAAM;CAEN,MAAM;CAEN,YAAY;CAEZ,WAAW;CAEX,YAAY;EACV;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,WAAW;EACT;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,iBAAiB;EACf;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,iBAAiB;EACf;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CAEV,qBAAqB;EACnB;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,cAAc;EACZ;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,YAAY;CAKZ,aAAa;CAIb,mBAAmB;;CAKnB,aAAa;;;;;;;CAQb,OAAO;EACL,MAAM;GACJ;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,IAAI;EACX,iBAAiB;;EAEjB,WAAW;GACT;IAAE,WAAW;IAAa,OAAO;IAAc,SAAS;GAAuB;GAC/E;IAAE,WAAW;IAAQ,OAAO;IAAe,SAAS;GAAU;GAC9D;IAAE,WAAW;IAAQ,OAAO;IAAkB,SAAS;GAAU;GACjE;IAAE,WAAW;IAAc,OAAO;IAAsB,SAAS;GAAK;GACtE;IAAE,WAAW;IAAQ,OAAO;IAAc,SAAS;GAAyB;GAC5E;IAAE,WAAW;IAAc,OAAO;IAAe,SAAS;GAAgB;EAC5E;EACA,UAAU;EACV,YAAY;GACV;GACA;GACA;EACF,CAAC,CAAC,KAAK,MAAM;CACf;;;;;CAMA,OAAO;EACL,MAAM;EACN,cAAc;EACd,QAAQ;CACV;;;;;CAMA,aAAa;EACX,MAAM;GACJ;GACA;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,GAAG;EACV,UAAU;EACV,cAAc,eACZ,4CAA4C,WAAW;CAC3D;;CAGA,YAAY,cACV,sEAAsE,UAAU;;CAOlF,YAAY;EACV,MAAM;EAGN,SAAS;CAGX;AACF"}
|
|
1
|
+
{"version":3,"file":"prompts.js","names":[],"sources":["../../src/tools/prompts.ts"],"sourcesContent":["/**\n * Every native tool's LLM-facing description, in one place.\n *\n * This module is the source of truth: each tool file imports its\n * `spec.description` from here rather than inlining it. It has no runtime\n * dependencies (pure strings and tiny template functions) so hosts can import\n * it from a config file — `zidane/tools/prompts` — read the defaults, and feed\n * adjusted text into `AgentOptions.toolDescriptions`:\n *\n * ```ts\n * import { toolPrompts } from 'zidane/tools/prompts'\n *\n * createAgent({\n * toolDescriptions: {\n * read_file: toolPrompts.read_file.replace('Claude Code', 'the editor'),\n * shell: cur => cur.replace(toolPrompts.shell.core, myShellIntro),\n * },\n * })\n * ```\n *\n * Scope is the top-level `spec.description` — the surface `toolDescriptions`\n * overrides. Parameter descriptions live with their schemas in the tool files.\n *\n * Static tools are plain strings. Tools whose description depends on runtime\n * configuration expose named fragments the factory joins conditionally; the\n * fragments are the exact bytes the model receives, so `String#replace`\n * against them is a precise edit.\n */\n\nexport const toolPrompts = {\n read_file: 'Read a file by path. Text files return lines [offset..offset+limit). Default offset=1, limit=2000; a negative offset reads from the end (`-50` = last 50 lines). Pass `paths` to read several files, or several ranges of one file, in one call. Each line is prefixed with its 1-indexed line number followed by a tab (e.g. `42\\\\tconst foo = bar`); the prefix is metadata, not part of the file. Mirrors Claude Code\\'s `cat -n`-style compact output for token efficiency. A trailing footer explains how to read the rest when truncated. Images (png/jpg/gif/webp) and PDFs return structured attachments for capable models; other binary files return a short marker rather than mojibake.',\n\n write_file: 'Write `content` to `path`, creating any missing parent directories. Overwrites existing files in full; prefer `edit` / `multi_edit` for surgical changes when you only want to alter part of a file. Returns one of: `Created <path> (N bytes)` (file did not exist), `Updated <path> (N bytes)` (content differed), or `No change needed: <path> already at target state (N bytes)`, so the model can detect no-ops without a separate `read_file`. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.',\n\n edit: 'Replace exact `old_string` with `new_string` in a file. Fails if `old_string` is not unique unless `replace_all: true`. Prefer over `write_file` for surgical changes: preserves the rest of the file. Tolerates `read_file` line-number prefixes (`<N>\\\\t…`, `<N>|…`, or `<N>→…`) in `old_string` / `new_string`; they are stripped before matching/writing, so you can paste a numbered chunk verbatim. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.',\n\n multi_edit: 'Apply a sequential list of edits to a file. Each edit operates on the result of the previous APPLIED edit. Prefer this over multiple `edit` calls when several non-overlapping changes are needed in the same file. Edits run best-effort: a per-step failure (`old_string` not found, ambiguous match without `replace_all`, identical strings) is reported in the result but does NOT block the remaining steps. The file is written iff at least one step applied. The result lists per-hunk outcomes (`applied` / `failed`) so the model can re-issue just the failures without resending the whole batch. Each step tolerates `read_file` line-number prefixes (`<N>\\\\t…`, `<N>|…`, or `<N>→…`) in `old_string` / `new_string`. Several `edit` / `multi_edit` / `write_file` calls and a verifying `shell` call (tests, typecheck) in one message run in order, in a single round-trip.',\n\n glob: 'Match files by glob pattern (supports **, *, ?). Relative to the execution context cwd; patterns may reach outside the workspace (e.g. \"../shared/**/*.ts\"). By default each row is `<path>\\\\t<size-bytes>\\\\t<mtime-iso>`; set `metadata: false` for a plain newline-separated list of paths. Always sorted.',\n\n grep: 'Search file contents by regex. Returns matching paths (default), match content, or per-file counts. One call covers several patterns (`patterns`), several roots (`paths`), context lines, literal (`fixed_strings`) or whole-word (`-w`) matching, and dropping noise lines (`exclude`); `head_limit` caps output. Backed by ripgrep when available, with a portable shell-listing + regex fallback when `rg` is absent.',\n\n list_files: 'List the immediate entries (files and subdirectories) at literal directory `path`. Returns a newline-separated list; subdirectories carry a trailing `/`; or `(empty directory)` when the directory exists but is empty. Non-recursive: use `glob` for pattern matching across nested directories.',\n\n fetch_url: 'Fetch a public URL and return its body as plain text. HTML is reduced to text (scripts, styles, tags stripped; entities decoded). If a `web_search` tool is also available, use it first when you do not already know the exact URL. Only http(s) URLs are accepted; loopback, link-local, private, and cloud-metadata addresses are refused. Output is capped (default 200 KiB).',\n\n shell_kill: [\n 'Terminate a running background task started by `shell({ run_in_background: true })`.',\n 'Sends SIGTERM to the whole process group so the shell wrapper AND its child commands die together.',\n 'Returns the final exit info (status, exit code, output path) or a \"no such task\" message when the id is unknown / already cleaned up.',\n 'Idempotent: calling on a task that has already terminated returns the cached exit info without re-killing.',\n ].join('\\n'),\n\n wait_task: [\n 'Wait for a background task started by `shell({ run_in_background: true })` to exit, then return its final status.',\n 'Returns immediately when the task has already terminated. On timeout the task keeps running and you can wait again, keep working, or `shell_kill` it.',\n 'Prefer ending your turn and receiving the `<task-notification>` when you have other useful work or nothing depends on the result; use wait_task only when the next step genuinely needs the task\\'s outcome.',\n ].join('\\n'),\n\n record_artifact: [\n 'Record a deliverable this session produced so the user can find it later in the artifacts panel. An artifact is an OUTPUT the user would want a link to — not a step of the work.',\n 'Worth recording: a pull request or merge request URL, a deployment / preview URL, an issue or ticket you filed, a release or tag, a generated report / export / dataset the user asked for, a build output they will pick up.',\n 'Not worth recording: source files you edited or created as part of implementing a change, scratch files, logs, intermediate results, anything already implied by the diff.',\n 'Pull requests from `gh pr create`, `git commit` commits and newly created branches are detected automatically — record those only when the automatic path could not see them (e.g. a PR opened from a background shell task).',\n 'Idempotent per (kind, uri): recording the same artifact again refreshes its label/meta.',\n ].join('\\n'),\n\n read_chat_turns: [\n 'Read selected turns from a previous chat explicitly referenced by the user with `#<chat>` in the current prompt.',\n 'Use this when the user asks to continue from, compare with, or inspect a referenced chat.',\n 'The tool refuses chats that were not referenced in the current user prompt.',\n ].join(' '),\n\n read_parent_session: [\n 'Read the conversation this side chat is about: its live status (running, the tool it is in, how long the run has gone, what it waits on), its todo list, and its turns.',\n 'By default it returns only the turns added since your last read; pass `mode: \"recent\"` for the latest turns regardless.',\n 'Read-only, and bound to that one conversation: it accepts no session id.',\n ].join('\\n'),\n\n generate_image: [\n 'Generate images from a text prompt with an image model and save them as files in the workspace.',\n 'Use it when the user asks for an image asset: a texture, icon, sprite, illustration, concept art or mockup.',\n 'To edit an image or match its style, pass workspace image paths in `references` (models marked [ref]). To keep a set of assets consistent, pass an earlier result as a reference.',\n 'The result shows a small preview. Use `read_file` on the saved file to look at it in full.',\n 'Every call costs money on the provider. Generate one image, look at it, then adjust the prompt.',\n ].join('\\n'),\n\n model_search: [\n 'List the models available for spawned subagents, with per-Mtok pricing and context windows.',\n 'Use it to cost-tier delegation: find a cheap, fast model for mechanical or high-volume work before calling `spawn` with its id in the `model` field.',\n 'Pass `query` to filter by substring across model id, name, and provider; omit it to list everything.',\n ].join('\\n'),\n\n skills_use: 'Activate or deactivate a specialized skill. '\n + 'Call with `mode: \"activate\"` (default) to load a skill\\'s full instructions when a task matches its catalog description. '\n + 'Call with `mode: \"deactivate\"` to release a skill whose allowed-tools restrictions are now in the way, e.g. when the skill\\'s work is done or the active skill is blocking unrelated tool calls. '\n + 'After activating, follow the returned instructions; use skills_read to load referenced files and skills_run_script to execute bundled scripts.',\n\n skills_read: 'Read a bundled resource file from an active skill. '\n + 'The skill must have been activated via skills_use first. '\n + 'Path is relative to the skill\\'s directory (e.g. \"references/REFERENCE.md\", \"assets/template.txt\").',\n\n skills_run_script: 'Execute a script bundled with an active skill (from its scripts/ directory). '\n + 'The skill must have been activated via skills_use first. '\n + 'Returns stdout, stderr, and the exit code. Honors the script\\'s shebang.',\n\n /** Default for `createInteractionTool` when the host passes no `description`. */\n interaction: 'Request structured input from the user or external system.',\n\n /**\n * `shell` is assembled per run by `createShellTool`: `core` always; the\n * `preferDedicated` block only for sibling tools actually registered\n * (`swapHints` filtered by canonical name, tool names alias-resolved);\n * `background` only when `run_in_background` is available.\n */\n shell: {\n core: [\n 'Execute a shell command from the workspace root (the `Cwd` in your environment) and return its combined stdout/stderr. Every call starts there; `cd` never persists between calls. Use relative paths (`cd src/app && bun test`, `ls docs`), not absolute ones.',\n 'Output is tail-priority truncated at 32 KiB by default; errors and exit-code summaries live in the tail.',\n 'By default each call appends a `(exit N, Nms)` footer and surfaces non-empty stderr in a separate section even on success; set `metadata: false` to return only stdout. Set maxOutputBytes=0 to disable truncation.',\n 'Pass a short `description` (5-10 words) explaining the intent of the command; it surfaces in the user-facing transcript so the human can follow your reasoning at a glance. Skip it only for trivial reads where the command speaks for itself.',\n ].join('\\n'),\n preferDedicated: 'When a dedicated tool fits, prefer it over shell:',\n /** One `- <label>: use \\`<tool>\\` (not <instead>)` line per registered sibling. */\n swapHints: [\n { canonical: 'read_file', label: 'Read files', instead: 'cat/head/tail/sed -n' },\n { canonical: 'glob', label: 'File search', instead: 'find/ls' },\n { canonical: 'grep', label: 'Content search', instead: 'grep/rg' },\n { canonical: 'list_files', label: 'Directory listings', instead: 'ls' },\n { canonical: 'edit', label: 'Edit files', instead: 'sed/awk/python scripts' },\n { canonical: 'write_file', label: 'Write files', instead: 'echo>/heredoc' },\n ],\n reminder: 'Re-running `ls`/`cat` on the same path is not useful: the prior result is still current unless you wrote to that path since.',\n background: [\n 'Long-running commands (`npm run dev`, `python train.py`, anything that would otherwise block your turn for minutes) → `run_in_background: true`. The call returns immediately with `{ task_id, output_path, pid }`; stdout + stderr stream to the log file at `output_path`.',\n 'After spawning a background task: end your current turn (do NOT keep iterating). A `<task-notification>` arrives on the agent\\'s NEXT user-turn with the final status. Polling the log file in a loop wastes tokens and blocks your turn: the notification IS the wake-up. If you NEED to check progress immediately (rare), call `read_file({ path: output_path, ... })` exactly once and decide. To terminate, use `shell_kill({ task_id })`. If, and only if, your very next step depends on the task\\'s outcome, block on it with `wait_task({ task_id })` instead of polling.',\n 'When called from inside a `spawn`\\'d subagent: you have NO next user-turn; your `agent.run` ends as soon as you finish responding. Start the background task, return a brief summary including the `task_id`, and end your turn. Ownership of the task is transferred to the parent agent when your run finishes; the parent will see the notification on ITS next user-turn.',\n ].join('\\n\\n'),\n },\n\n /**\n * `spawn`: `core` always; `modelTiering` when a model catalog is wired;\n * `resume` when the tool persists child turns (`persist: true`).\n */\n spawn: {\n core: 'Spawn a sub-agent for a self-contained task that benefits from isolation (separate context window, separate retries): for example, a deep research dive or a long codegen pass on a specific file. The sub-agent inherits your tool set (including `spawn` itself, depth-capped) and your system prompt unless overridden, runs independently, and returns its final response. Do NOT spawn for sequential steps you could do yourself.',\n modelTiering: ' Children can run on a DIFFERENT model via the `model` field: cost-tier your delegation: mechanical, parallelizable, or high-volume search work belongs on cheaper/faster models, while synthesis and judgment stay on your own model.',\n resume: ' A stopped or failed sub-agent can be CONTINUED instead of restarted: pass `resume` with its child label (e.g. \"child-2\") and put the continuation instruction in `task`; the child picks up with its prior conversation intact.',\n },\n\n /**\n * `tool_search`: `core` + one closing sentence — `callableVia(dispatcher)`\n * in dispatch mode (`call_tool`), `callable` otherwise.\n */\n tool_search: {\n core: [\n 'Discover and load schemas for additional tools listed in <searchable_tools>.',\n 'Tools listed there are advertised by name + description only; their input',\n 'schemas are not loaded into context until you surface them through this tool.',\n 'Pass `query` for a substring search, `names` to load specific tools, or `server`',\n 'to load every tool from one MCP server.',\n ].join(' '),\n callable: 'Returned tools become callable for the rest of this run.',\n callableVia: (dispatcher: string): string =>\n `Returned tools become callable through \\`${dispatcher}\\` (name + arguments) for the rest of this run.`,\n },\n\n /** `call_tool` names the discovery tool (`tool_search` or the host's wire name). */\n call_tool: (discovery: string): string =>\n `Invoke a tool listed in <searchable_tools>. Load its schema with \\`${discovery}\\` first `\n + '(the result shows the exact `name` and input schema), then call it here with `name` '\n + 'set to that tool name and `arguments` set to an object matching its schema. '\n + 'Arguments are validated against the tool\\'s own schema; a validation error names '\n + 'the offending field.',\n\n /** `web_search`: `core` + `recency`. Static, so the tool list stays byte-stable. */\n web_search: {\n core: 'Search the public web and return ranked title / URL / snippet results. '\n + 'Use this to look up documentation, error messages, library versions, or recent events. '\n + 'If a `fetch_url` tool is also available, follow up with it to read a specific page in full.',\n recency: 'IMPORTANT: When you search for recent information, docs, or current events, use the current date '\n + 'from your context, such as the Date line in <env>, not your training cutoff year '\n + '(e.g. search \"React docs\" with the current year, not an older one).',\n },\n} as const\n\n/** Shape of {@link toolPrompts}. */\nexport type ToolPrompts = typeof toolPrompts\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAa,cAAc;CACzB,WAAW;CAEX,YAAY;CAEZ,MAAM;CAEN,YAAY;CAEZ,MAAM;CAEN,MAAM;CAEN,YAAY;CAEZ,WAAW;CAEX,YAAY;EACV;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,WAAW;EACT;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,iBAAiB;EACf;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,iBAAiB;EACf;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CAEV,qBAAqB;EACnB;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,gBAAgB;EACd;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,cAAc;EACZ;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAEX,YAAY;CAKZ,aAAa;CAIb,mBAAmB;;CAKnB,aAAa;;;;;;;CAQb,OAAO;EACL,MAAM;GACJ;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,IAAI;EACX,iBAAiB;;EAEjB,WAAW;GACT;IAAE,WAAW;IAAa,OAAO;IAAc,SAAS;GAAuB;GAC/E;IAAE,WAAW;IAAQ,OAAO;IAAe,SAAS;GAAU;GAC9D;IAAE,WAAW;IAAQ,OAAO;IAAkB,SAAS;GAAU;GACjE;IAAE,WAAW;IAAc,OAAO;IAAsB,SAAS;GAAK;GACtE;IAAE,WAAW;IAAQ,OAAO;IAAc,SAAS;GAAyB;GAC5E;IAAE,WAAW;IAAc,OAAO;IAAe,SAAS;GAAgB;EAC5E;EACA,UAAU;EACV,YAAY;GACV;GACA;GACA;EACF,CAAC,CAAC,KAAK,MAAM;CACf;;;;;CAMA,OAAO;EACL,MAAM;EACN,cAAc;EACd,QAAQ;CACV;;;;;CAMA,aAAa;EACX,MAAM;GACJ;GACA;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,GAAG;EACV,UAAU;EACV,cAAc,eACZ,4CAA4C,WAAW;CAC3D;;CAGA,YAAY,cACV,sEAAsE,UAAU;;CAOlF,YAAY;EACV,MAAM;EAGN,SAAS;CAGX;AACF"}
|
|
@@ -1,9 +1,280 @@
|
|
|
1
1
|
import { h as isAbortLikeError, p as errorMessage } from "./errors-C3z7pmOx.js";
|
|
2
|
+
import { n as reconcileImageMediaType } from "./media-sniff-DZaaJt2S.js";
|
|
2
3
|
import { n as shellQuote } from "./shell-quote-BmnhZmdM.js";
|
|
3
4
|
import { n as GIT_LS_FILES_COMMAND, r as parseGitLsFiles } from "./git-ls-files-BrK6UBWi.js";
|
|
5
|
+
import { c as pathArgError } from "./wait-task-BZiNOAcc.js";
|
|
6
|
+
import { c as imageSizeFromBase64, s as shrinkImageBase64 } from "./skills-use-CssTEaIj.js";
|
|
4
7
|
import { toolPrompts } from "./tools/prompts.js";
|
|
5
8
|
import { n as isToolFailure, t as ToolFailure } from "./failure-_rDKdaLk.js";
|
|
9
|
+
import { a as readFileAsBase64, i as imageMediaTypeFor } from "./write-file-QYrcDdl3.js";
|
|
10
|
+
import { t as IMAGE_ASPECT_RATIOS } from "./types-JzccL5GE.js";
|
|
6
11
|
import { Buffer } from "node:buffer";
|
|
12
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
13
|
+
import { randomBytes } from "node:crypto";
|
|
14
|
+
/** Folder for images saved without a `path`. */
|
|
15
|
+
const DEFAULT_IMAGE_DIR = "generated-images";
|
|
16
|
+
/** Most reference images one call takes. */
|
|
17
|
+
const MAX_REFERENCES = 8;
|
|
18
|
+
/** Largest reference image, in bytes. Image APIs cap uploads near this size. */
|
|
19
|
+
const MAX_REFERENCE_BYTES = 20971520;
|
|
20
|
+
function entriesOf(sources) {
|
|
21
|
+
return sources.flatMap((source) => source.images.models.map((model) => ({
|
|
22
|
+
source,
|
|
23
|
+
model,
|
|
24
|
+
ref: `${source.provider}/${model.id}`
|
|
25
|
+
})));
|
|
26
|
+
}
|
|
27
|
+
function sourcesFromContext(ctx) {
|
|
28
|
+
return (ctx.providers?.length ? ctx.providers : [ctx.provider]).flatMap((provider) => {
|
|
29
|
+
const images = provider.images;
|
|
30
|
+
return images && images.availability().available ? [{
|
|
31
|
+
provider: provider.name,
|
|
32
|
+
images
|
|
33
|
+
}] : [];
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/** The entry `ref` names: an exact `<provider>/<id>`, else a model id only one source serves. */
|
|
37
|
+
function findEntry(entries, ref) {
|
|
38
|
+
const exact = entries.find((e) => e.ref === ref);
|
|
39
|
+
if (exact) return exact;
|
|
40
|
+
const byId = entries.filter((e) => e.model.id === ref);
|
|
41
|
+
return byId.length === 1 ? byId[0] : void 0;
|
|
42
|
+
}
|
|
43
|
+
function defaultEntry(entries, sources, configured) {
|
|
44
|
+
const picked = configured ? findEntry(entries, configured) : void 0;
|
|
45
|
+
if (picked) return picked;
|
|
46
|
+
const first = sources[0];
|
|
47
|
+
return first ? findEntry(entries, `${first.provider}/${first.images.defaultModel}`) ?? entries[0] : void 0;
|
|
48
|
+
}
|
|
49
|
+
/** One line per model: `provider/id · name · [ref] [alpha]`, `(default)` on the default one. */
|
|
50
|
+
function modelLine(entry, isDefault) {
|
|
51
|
+
const parts = [entry.ref];
|
|
52
|
+
if (entry.model.name && entry.model.name !== entry.model.id) parts.push(entry.model.name);
|
|
53
|
+
const flags = [
|
|
54
|
+
...entry.model.input.includes("image") ? ["[ref]"] : [],
|
|
55
|
+
...entry.model.transparency ? ["[alpha]"] : [],
|
|
56
|
+
...isDefault ? ["(default)"] : []
|
|
57
|
+
];
|
|
58
|
+
return `- ${parts.join(" · ")}${flags.length ? ` ${flags.join(" ")}` : ""}`;
|
|
59
|
+
}
|
|
60
|
+
function describeModels(entries, def) {
|
|
61
|
+
if (entries.length === 0) return "Call with `list: true` to see the image models of the connected providers.";
|
|
62
|
+
const ordered = def ? [def, ...entries.filter((e) => e !== def)] : [...entries];
|
|
63
|
+
const shown = ordered.slice(0, 15);
|
|
64
|
+
const lines = ["Models (`model` argument; [ref]: takes reference images, [alpha]: transparent background):", ...shown.map((e) => modelLine(e, e === def))];
|
|
65
|
+
if (ordered.length > shown.length) lines.push(`Call with \`list: true\` for all ${ordered.length} models.`);
|
|
66
|
+
return lines.join("\n");
|
|
67
|
+
}
|
|
68
|
+
const EXTENSION_BY_TYPE = {
|
|
69
|
+
"image/png": "png",
|
|
70
|
+
"image/jpeg": "jpg",
|
|
71
|
+
"image/webp": "webp",
|
|
72
|
+
"image/gif": "gif"
|
|
73
|
+
};
|
|
74
|
+
/** A file-name stem from the first words of the prompt: `snowy-pine-forest-texture`. */
|
|
75
|
+
function slugOf(prompt) {
|
|
76
|
+
return prompt.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim().split(" ").slice(0, 6).join("-") || "image";
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* `YYYYMMDD-HHMMSS-xxxx` of `now`; the random tail keeps two calls with the
|
|
80
|
+
* same prompt in the same second (parallel tool calls) from overwriting each other.
|
|
81
|
+
*/
|
|
82
|
+
function timeStamp(now) {
|
|
83
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
84
|
+
return `${`${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`}-${[
|
|
85
|
+
now.getHours(),
|
|
86
|
+
now.getMinutes(),
|
|
87
|
+
now.getSeconds()
|
|
88
|
+
].map(pad).join("")}-${randomBytes(2).toString("hex")}`;
|
|
89
|
+
}
|
|
90
|
+
/** The record next to an image: the image's full name plus `.json`, so it never lands on a project file like `package.json`. */
|
|
91
|
+
function recordPathOf(file) {
|
|
92
|
+
return `${file}.json`;
|
|
93
|
+
}
|
|
94
|
+
/** `path` without an image extension, or the default stem when absent. */
|
|
95
|
+
function stemOf(path, prompt, now) {
|
|
96
|
+
if (!path) return `${DEFAULT_IMAGE_DIR}/${slugOf(prompt)}-${timeStamp(now)}`;
|
|
97
|
+
return imageMediaTypeFor(path) ? path.slice(0, path.lastIndexOf(".")) : path;
|
|
98
|
+
}
|
|
99
|
+
/** The workspace-relative `path`, or a failure when it leaves the working directory. */
|
|
100
|
+
function confinedPath(ctx, path, field) {
|
|
101
|
+
const err = pathArgError(path, field);
|
|
102
|
+
if (err) throw new ToolFailure(`generate_image error: ${err}`);
|
|
103
|
+
const cwd = ctx.handle.cwd;
|
|
104
|
+
const rel = relative(cwd, resolve(cwd, path));
|
|
105
|
+
if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) throw new ToolFailure(`generate_image error: \`${field}\` must be a file inside the working directory (${cwd}), got "${path}".`);
|
|
106
|
+
return rel;
|
|
107
|
+
}
|
|
108
|
+
async function readReference(ctx, path) {
|
|
109
|
+
const rel = confinedPath(ctx, path, "references");
|
|
110
|
+
const extMedia = imageMediaTypeFor(rel);
|
|
111
|
+
if (!extMedia) throw new ToolFailure(`generate_image error: reference "${path}" is not a PNG, JPEG, WebP or GIF file.`);
|
|
112
|
+
const size = await ctx.execution.fileSize?.(ctx.handle, rel) ?? null;
|
|
113
|
+
if (size !== null && size > MAX_REFERENCE_BYTES) throw new ToolFailure(`generate_image error: reference "${path}" is ${size} bytes; the limit is ${MAX_REFERENCE_BYTES}.`);
|
|
114
|
+
try {
|
|
115
|
+
const { base64 } = await readFileAsBase64(ctx.execution, ctx.handle, rel);
|
|
116
|
+
return {
|
|
117
|
+
data: base64,
|
|
118
|
+
mediaType: reconcileImageMediaType(extMedia, base64)
|
|
119
|
+
};
|
|
120
|
+
} catch (err) {
|
|
121
|
+
throw new ToolFailure(`generate_image error: cannot read reference "${path}": ${errorMessage(err)}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function listText(entries, def) {
|
|
125
|
+
if (entries.length === 0) return "No image models are available. Connect a provider with image generation (OpenRouter, OpenAI with a platform key, Google Gemini or xAI) in the provider settings.";
|
|
126
|
+
const ordered = def ? [def, ...entries.filter((e) => e !== def)] : entries;
|
|
127
|
+
return [`${entries.length} image model${entries.length === 1 ? "" : "s"}:`, ...ordered.map((e) => modelLine(e, e === def))].join("\n");
|
|
128
|
+
}
|
|
129
|
+
function formatCost(usd) {
|
|
130
|
+
return usd < .01 ? `$${usd.toFixed(4)}` : `$${usd.toFixed(2)}`;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Build the `generate_image` tool.
|
|
134
|
+
*
|
|
135
|
+
* @param options - Providers to generate with and the default model.
|
|
136
|
+
*/
|
|
137
|
+
function createGenerateImageTool(options = {}) {
|
|
138
|
+
const fixedSources = options.sources;
|
|
139
|
+
const fixedEntries = fixedSources ? entriesOf(fixedSources) : [];
|
|
140
|
+
const fixedDefault = fixedSources ? defaultEntry(fixedEntries, fixedSources, options.defaultModel) : void 0;
|
|
141
|
+
return {
|
|
142
|
+
spec: {
|
|
143
|
+
name: "generate_image",
|
|
144
|
+
description: `${toolPrompts.generate_image}\n\n${describeModels(fixedEntries, fixedDefault)}`,
|
|
145
|
+
inputSchema: {
|
|
146
|
+
type: "object",
|
|
147
|
+
properties: {
|
|
148
|
+
prompt: {
|
|
149
|
+
type: "string",
|
|
150
|
+
description: "What to draw: subject, style, colors, lighting, framing. For an edit, what to change."
|
|
151
|
+
},
|
|
152
|
+
model: {
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "Image model as `<provider>/<model id>` from the list. Omit to use the default."
|
|
155
|
+
},
|
|
156
|
+
path: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: `Where to save, relative to the working directory, for example \`assets/textures/snow.png\`. The extension follows the format the model returns. Several images get \`-1\`, \`-2\` suffixes. Omit to save under \`${DEFAULT_IMAGE_DIR}/\`.`
|
|
159
|
+
},
|
|
160
|
+
aspect_ratio: {
|
|
161
|
+
type: "string",
|
|
162
|
+
enum: [...IMAGE_ASPECT_RATIOS],
|
|
163
|
+
description: "Shape of the image. Omit to let the model choose (usually square)."
|
|
164
|
+
},
|
|
165
|
+
n: {
|
|
166
|
+
type: "number",
|
|
167
|
+
description: `How many variations to generate, 1 to 4. Default 1. Each one costs.`
|
|
168
|
+
},
|
|
169
|
+
references: {
|
|
170
|
+
type: "array",
|
|
171
|
+
items: { type: "string" },
|
|
172
|
+
description: `Workspace image paths to edit or to match the style of, up to ${MAX_REFERENCES}. Only for models marked [ref].`
|
|
173
|
+
},
|
|
174
|
+
transparent: {
|
|
175
|
+
type: "boolean",
|
|
176
|
+
description: "Ask for a transparent background (sprites, icons). Only for models marked [alpha]."
|
|
177
|
+
},
|
|
178
|
+
list: {
|
|
179
|
+
type: "boolean",
|
|
180
|
+
description: "List every available image model and generate nothing."
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
async execute(input, ctx) {
|
|
186
|
+
const sources = fixedSources ?? sourcesFromContext(ctx);
|
|
187
|
+
const entries = fixedSources ? fixedEntries : entriesOf(sources);
|
|
188
|
+
const def = fixedSources ? fixedDefault : defaultEntry(entries, sources, options.defaultModel);
|
|
189
|
+
if (input.list === true) return listText(entries, def);
|
|
190
|
+
const prompt = typeof input.prompt === "string" ? input.prompt.trim() : "";
|
|
191
|
+
if (!prompt) throw new ToolFailure("generate_image error: `prompt` is required.");
|
|
192
|
+
if (entries.length === 0) throw new ToolFailure(`generate_image error: ${listText(entries, def)}`);
|
|
193
|
+
const requested = typeof input.model === "string" && input.model.trim() ? input.model.trim() : void 0;
|
|
194
|
+
const entry = requested ? findEntry(entries, requested) : def;
|
|
195
|
+
if (!entry) throw new ToolFailure(`generate_image error: unknown model "${requested}". Use \`<provider>/<model id>\`:\n${listText(entries, def)}`);
|
|
196
|
+
const aspectRatio = typeof input.aspect_ratio === "string" ? input.aspect_ratio : void 0;
|
|
197
|
+
if (aspectRatio && !IMAGE_ASPECT_RATIOS.includes(aspectRatio)) throw new ToolFailure(`generate_image error: \`aspect_ratio\` must be one of ${IMAGE_ASPECT_RATIOS.join(", ")}.`);
|
|
198
|
+
const count = typeof input.n === "number" && Number.isFinite(input.n) ? Math.floor(input.n) : 1;
|
|
199
|
+
if (count < 1 || count > 4) throw new ToolFailure(`generate_image error: \`n\` must be from 1 to 4.`);
|
|
200
|
+
const transparent = input.transparent === true;
|
|
201
|
+
if (transparent && !entry.model.transparency) {
|
|
202
|
+
const capable = entries.filter((e) => e.model.transparency).map((e) => e.ref);
|
|
203
|
+
throw new ToolFailure(`generate_image error: ${entry.ref} cannot make a transparent background.${capable.length ? ` Models that can: ${capable.join(", ")}.` : ""}`);
|
|
204
|
+
}
|
|
205
|
+
const referencePaths = Array.isArray(input.references) ? input.references.filter((p) => typeof p === "string" && p.trim() !== "") : [];
|
|
206
|
+
if (referencePaths.length > 0 && !entry.model.input.includes("image")) throw new ToolFailure(`generate_image error: ${entry.ref} does not take reference images. Pick a model marked [ref].`);
|
|
207
|
+
if (referencePaths.length > MAX_REFERENCES) throw new ToolFailure(`generate_image error: at most ${MAX_REFERENCES} references per call.`);
|
|
208
|
+
const now = /* @__PURE__ */ new Date();
|
|
209
|
+
const pathArg = typeof input.path === "string" && input.path.trim() ? input.path.trim() : void 0;
|
|
210
|
+
const stem = stemOf(pathArg ? confinedPath(ctx, pathArg, "path") : void 0, prompt, now);
|
|
211
|
+
const references = await Promise.all(referencePaths.map((p) => readReference(ctx, p)));
|
|
212
|
+
const started = Date.now();
|
|
213
|
+
let response;
|
|
214
|
+
try {
|
|
215
|
+
response = await entry.source.images.generate({
|
|
216
|
+
model: entry.model.id,
|
|
217
|
+
prompt,
|
|
218
|
+
...references.length ? { references } : {},
|
|
219
|
+
...aspectRatio ? { aspectRatio } : {},
|
|
220
|
+
count,
|
|
221
|
+
...transparent ? { transparent } : {}
|
|
222
|
+
}, ctx.signal);
|
|
223
|
+
} catch (err) {
|
|
224
|
+
if (isAbortLikeError(err) || ctx.signal.aborted) throw err;
|
|
225
|
+
throw new ToolFailure(`generate_image error (${entry.ref}): ${errorMessage(err)}`);
|
|
226
|
+
}
|
|
227
|
+
const seconds = (Date.now() - started) / 1e3;
|
|
228
|
+
const images = response.images.slice(0, count);
|
|
229
|
+
const saved = [];
|
|
230
|
+
for (const [i, image] of images.entries()) {
|
|
231
|
+
const ext = EXTENSION_BY_TYPE[image.mediaType] ?? "png";
|
|
232
|
+
const file = `${stem}${images.length > 1 ? `-${i + 1}` : ""}.${ext}`;
|
|
233
|
+
const record = {
|
|
234
|
+
prompt,
|
|
235
|
+
provider: entry.source.provider,
|
|
236
|
+
model: response.model || entry.model.id,
|
|
237
|
+
...aspectRatio ? { aspectRatio } : {},
|
|
238
|
+
...transparent ? { transparent } : {},
|
|
239
|
+
...referencePaths.length ? { references: referencePaths } : {},
|
|
240
|
+
...response.costUsd !== void 0 ? { costUsd: response.costUsd / images.length } : {},
|
|
241
|
+
createdAt: now.toISOString()
|
|
242
|
+
};
|
|
243
|
+
try {
|
|
244
|
+
await ctx.execution.writeFile(ctx.handle, file, Buffer.from(image.data, "base64"));
|
|
245
|
+
await ctx.execution.writeFile(ctx.handle, recordPathOf(file), `${JSON.stringify(record, null, 2)}\n`);
|
|
246
|
+
} catch (err) {
|
|
247
|
+
throw new ToolFailure(`generate_image error: the image was generated but saving ${file} failed: ${errorMessage(err)}`);
|
|
248
|
+
}
|
|
249
|
+
saved.push(file);
|
|
250
|
+
}
|
|
251
|
+
const sizes = images.map((image) => {
|
|
252
|
+
const size = imageSizeFromBase64(image.data);
|
|
253
|
+
return size ? `${size.width}x${size.height}` : image.mediaType;
|
|
254
|
+
});
|
|
255
|
+
const lines = [
|
|
256
|
+
`Generated ${images.length} image${images.length === 1 ? "" : "s"} with ${entry.ref} in ${seconds.toFixed(1)} s.`,
|
|
257
|
+
...saved.map((file, i) => `Saved: ${file} (${sizes[i]})`),
|
|
258
|
+
`Records: ${saved.map(recordPathOf).join(", ")}`,
|
|
259
|
+
...response.costUsd !== void 0 ? [`Cost: ${formatCost(response.costUsd)}`] : [],
|
|
260
|
+
...response.text ? [`Model note: ${response.text}`] : []
|
|
261
|
+
];
|
|
262
|
+
const previews = images.map((image) => {
|
|
263
|
+
const shrunk = shrinkImageBase64(image.data, image.mediaType, 768);
|
|
264
|
+
return {
|
|
265
|
+
type: "image",
|
|
266
|
+
mediaType: shrunk?.mediaType ?? image.mediaType,
|
|
267
|
+
data: shrunk?.data ?? image.data
|
|
268
|
+
};
|
|
269
|
+
});
|
|
270
|
+
return [{
|
|
271
|
+
type: "text",
|
|
272
|
+
text: lines.join("\n")
|
|
273
|
+
}, ...previews];
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
7
278
|
//#region src/tools/glob.ts
|
|
8
279
|
/** Default cap on returned matches. A `limit` argument overrides it. */
|
|
9
280
|
const DEFAULT_LIMIT = 1e3;
|
|
@@ -588,6 +859,6 @@ function createInteractionTool(options) {
|
|
|
588
859
|
};
|
|
589
860
|
}
|
|
590
861
|
//#endregion
|
|
591
|
-
export { grep as n, glob as r, createInteractionTool as t };
|
|
862
|
+
export { createGenerateImageTool as a, DEFAULT_IMAGE_DIR as i, grep as n, glob as r, createInteractionTool as t };
|
|
592
863
|
|
|
593
|
-
//# sourceMappingURL=tools-
|
|
864
|
+
//# sourceMappingURL=tools-pZVFIJ_K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools-pZVFIJ_K.js","names":[],"sources":["../src/tools/generate-image.ts","../src/tools/glob.ts","../src/tools/grep.ts","../src/tools/interaction.ts"],"sourcesContent":["/**\n * `generate_image`: text to image (or image to image) with any image model\n * of the providers the run can reach (`Provider.images`).\n *\n * The tool saves full-size files into the workspace, writes a `<file>.json`\n * record next to each one (prompt, provider, model, date, cost) so an asset's origin\n * stays on disk, and returns the paths plus a preview capped at\n * {@link PREVIEW_EDGE} px. The preview is what the model sees and what the\n * transcript shows; the file keeps the full resolution.\n *\n * The description lists up to {@link LISTED_MODELS} models so the model can\n * pick one without a round trip; `list: true` returns all of them.\n */\n\nimport type { ImageAspectRatio, ImageData, ImageModelInfo, ProviderImageResponse, ProviderImages } from '../providers/images'\nimport type { ToolResultContent } from '../types'\nimport type { ToolContext, ToolDef } from './types'\nimport { Buffer } from 'node:buffer'\nimport { randomBytes } from 'node:crypto'\nimport { isAbsolute, relative, resolve } from 'node:path'\nimport { errorMessage, isAbortLikeError } from '../errors'\nimport { imageSizeFromBase64 } from '../media/image-size'\nimport { shrinkImageBase64 } from '../media/png-downscale'\nimport { IMAGE_ASPECT_RATIOS, MAX_IMAGES_PER_REQUEST } from '../providers/images'\nimport { imageMediaTypeFor, readFileAsBase64 } from './binary-read'\nimport { ToolFailure } from './failure'\nimport { reconcileImageMediaType } from './media-sniff'\nimport { toolPrompts } from './prompts'\nimport { pathArgError } from './validation'\n\n/** Longest edge of the preview returned to the model, in px. */\nexport const PREVIEW_EDGE = 768\n\n/** Models named in the tool description; the rest are behind `list: true`. */\nexport const LISTED_MODELS = 15\n\n/** Folder for images saved without a `path`. */\nexport const DEFAULT_IMAGE_DIR = 'generated-images'\n\n/** Most reference images one call takes. */\nconst MAX_REFERENCES = 8\n\n/** Largest reference image, in bytes. Image APIs cap uploads near this size. */\nconst MAX_REFERENCE_BYTES = 20 * 1024 * 1024\n\n/** A provider the tool can generate with. */\nexport interface ImageModelSource {\n /** Provider name as the `model` argument spells it: `<provider>/<model id>`. */\n provider: string\n /** Display name of the provider, for the model list. */\n label?: string\n /** The provider's image endpoint. */\n images: ProviderImages\n}\n\n/** Options for {@link createGenerateImageTool}. */\nexport interface GenerateImageToolOptions {\n /**\n * Providers to generate with. Omitted: the run's providers that have an\n * available image endpoint (`ToolContext.providers`, else `provider`).\n */\n sources?: readonly ImageModelSource[]\n /** Model used when a call names none, as `<provider>/<model id>`. Default: the first source's default model. */\n defaultModel?: string\n}\n\n/** One model of one source. */\ninterface ModelEntry {\n source: ImageModelSource\n model: ImageModelInfo\n /** `<provider>/<model id>`. */\n ref: string\n}\n\nfunction entriesOf(sources: readonly ImageModelSource[]): ModelEntry[] {\n return sources.flatMap(source => source.images.models.map(model => ({ source, model, ref: `${source.provider}/${model.id}` })))\n}\n\nfunction sourcesFromContext(ctx: ToolContext): ImageModelSource[] {\n const providers = ctx.providers?.length ? ctx.providers : [ctx.provider]\n return providers.flatMap((provider) => {\n const images = provider.images\n return images && images.availability().available ? [{ provider: provider.name, images }] : []\n })\n}\n\n/** The entry `ref` names: an exact `<provider>/<id>`, else a model id only one source serves. */\nfunction findEntry(entries: readonly ModelEntry[], ref: string): ModelEntry | undefined {\n const exact = entries.find(e => e.ref === ref)\n if (exact)\n return exact\n const byId = entries.filter(e => e.model.id === ref)\n return byId.length === 1 ? byId[0] : undefined\n}\n\nfunction defaultEntry(entries: readonly ModelEntry[], sources: readonly ImageModelSource[], configured: string | undefined): ModelEntry | undefined {\n const picked = configured ? findEntry(entries, configured) : undefined\n if (picked)\n return picked\n const first = sources[0]\n return first ? findEntry(entries, `${first.provider}/${first.images.defaultModel}`) ?? entries[0] : undefined\n}\n\n/** One line per model: `provider/id · name · [ref] [alpha]`, `(default)` on the default one. */\nfunction modelLine(entry: ModelEntry, isDefault: boolean): string {\n const parts = [entry.ref]\n if (entry.model.name && entry.model.name !== entry.model.id)\n parts.push(entry.model.name)\n const flags = [\n ...(entry.model.input.includes('image') ? ['[ref]'] : []),\n ...(entry.model.transparency ? ['[alpha]'] : []),\n ...(isDefault ? ['(default)'] : []),\n ]\n return `- ${parts.join(' · ')}${flags.length ? ` ${flags.join(' ')}` : ''}`\n}\n\nfunction describeModels(entries: readonly ModelEntry[], def: ModelEntry | undefined): string {\n if (entries.length === 0)\n return 'Call with `list: true` to see the image models of the connected providers.'\n // The default first, then in source order.\n const ordered = def ? [def, ...entries.filter(e => e !== def)] : [...entries]\n const shown = ordered.slice(0, LISTED_MODELS)\n const lines = [\n 'Models (`model` argument; [ref]: takes reference images, [alpha]: transparent background):',\n ...shown.map(e => modelLine(e, e === def)),\n ]\n if (ordered.length > shown.length)\n lines.push(`Call with \\`list: true\\` for all ${ordered.length} models.`)\n return lines.join('\\n')\n}\n\nconst EXTENSION_BY_TYPE: Readonly<Record<string, string>> = {\n 'image/png': 'png',\n 'image/jpeg': 'jpg',\n 'image/webp': 'webp',\n 'image/gif': 'gif',\n}\n\n/** A file-name stem from the first words of the prompt: `snowy-pine-forest-texture`. */\nfunction slugOf(prompt: string): string {\n const slug = prompt.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim().split(' ').slice(0, 6).join('-')\n return slug || 'image'\n}\n\n/**\n * `YYYYMMDD-HHMMSS-xxxx` of `now`; the random tail keeps two calls with the\n * same prompt in the same second (parallel tool calls) from overwriting each other.\n */\nfunction timeStamp(now: Date): string {\n const pad = (n: number) => String(n).padStart(2, '0')\n const date = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`\n const time = [now.getHours(), now.getMinutes(), now.getSeconds()].map(pad).join('')\n return `${date}-${time}-${randomBytes(2).toString('hex')}`\n}\n\n/** The record next to an image: the image's full name plus `.json`, so it never lands on a project file like `package.json`. */\nfunction recordPathOf(file: string): string {\n return `${file}.json`\n}\n\n/** `path` without an image extension, or the default stem when absent. */\nfunction stemOf(path: string | undefined, prompt: string, now: Date): string {\n if (!path)\n return `${DEFAULT_IMAGE_DIR}/${slugOf(prompt)}-${timeStamp(now)}`\n return imageMediaTypeFor(path) ? path.slice(0, path.lastIndexOf('.')) : path\n}\n\n/** The workspace-relative `path`, or a failure when it leaves the working directory. */\nfunction confinedPath(ctx: ToolContext, path: string, field: string): string {\n const err = pathArgError(path, field)\n if (err)\n throw new ToolFailure(`generate_image error: ${err}`)\n const cwd = ctx.handle.cwd\n const rel = relative(cwd, resolve(cwd, path))\n if (rel === '' || rel.startsWith('..') || isAbsolute(rel))\n throw new ToolFailure(`generate_image error: \\`${field}\\` must be a file inside the working directory (${cwd}), got \"${path}\".`)\n return rel\n}\n\nasync function readReference(ctx: ToolContext, path: string): Promise<ImageData> {\n const rel = confinedPath(ctx, path, 'references')\n const extMedia = imageMediaTypeFor(rel)\n if (!extMedia)\n throw new ToolFailure(`generate_image error: reference \"${path}\" is not a PNG, JPEG, WebP or GIF file.`)\n const size = await ctx.execution.fileSize?.(ctx.handle, rel) ?? null\n if (size !== null && size > MAX_REFERENCE_BYTES)\n throw new ToolFailure(`generate_image error: reference \"${path}\" is ${size} bytes; the limit is ${MAX_REFERENCE_BYTES}.`)\n try {\n const { base64 } = await readFileAsBase64(ctx.execution, ctx.handle, rel)\n return { data: base64, mediaType: reconcileImageMediaType(extMedia, base64) }\n }\n catch (err) {\n throw new ToolFailure(`generate_image error: cannot read reference \"${path}\": ${errorMessage(err)}`)\n }\n}\n\nfunction listText(entries: readonly ModelEntry[], def: ModelEntry | undefined): string {\n if (entries.length === 0)\n return 'No image models are available. Connect a provider with image generation (OpenRouter, OpenAI with a platform key, Google Gemini or xAI) in the provider settings.'\n const ordered = def ? [def, ...entries.filter(e => e !== def)] : entries\n return [`${entries.length} image model${entries.length === 1 ? '' : 's'}:`, ...ordered.map(e => modelLine(e, e === def))].join('\\n')\n}\n\nfunction formatCost(usd: number): string {\n return usd < 0.01 ? `$${usd.toFixed(4)}` : `$${usd.toFixed(2)}`\n}\n\n/**\n * Build the `generate_image` tool.\n *\n * @param options - Providers to generate with and the default model.\n */\nexport function createGenerateImageTool(options: GenerateImageToolOptions = {}): ToolDef {\n const fixedSources = options.sources\n const fixedEntries = fixedSources ? entriesOf(fixedSources) : []\n const fixedDefault = fixedSources ? defaultEntry(fixedEntries, fixedSources, options.defaultModel) : undefined\n\n return {\n spec: {\n name: 'generate_image',\n description: `${toolPrompts.generate_image}\\n\\n${describeModels(fixedEntries, fixedDefault)}`,\n inputSchema: {\n type: 'object',\n properties: {\n prompt: {\n type: 'string',\n description: 'What to draw: subject, style, colors, lighting, framing. For an edit, what to change.',\n },\n model: {\n type: 'string',\n description: 'Image model as `<provider>/<model id>` from the list. Omit to use the default.',\n },\n path: {\n type: 'string',\n description: `Where to save, relative to the working directory, for example \\`assets/textures/snow.png\\`. The extension follows the format the model returns. Several images get \\`-1\\`, \\`-2\\` suffixes. Omit to save under \\`${DEFAULT_IMAGE_DIR}/\\`.`,\n },\n aspect_ratio: {\n type: 'string',\n enum: [...IMAGE_ASPECT_RATIOS],\n description: 'Shape of the image. Omit to let the model choose (usually square).',\n },\n n: {\n type: 'number',\n description: `How many variations to generate, 1 to ${MAX_IMAGES_PER_REQUEST}. Default 1. Each one costs.`,\n },\n references: {\n type: 'array',\n items: { type: 'string' },\n description: `Workspace image paths to edit or to match the style of, up to ${MAX_REFERENCES}. Only for models marked [ref].`,\n },\n transparent: {\n type: 'boolean',\n description: 'Ask for a transparent background (sprites, icons). Only for models marked [alpha].',\n },\n list: {\n type: 'boolean',\n description: 'List every available image model and generate nothing.',\n },\n },\n },\n },\n async execute(input, ctx): Promise<string | ToolResultContent[]> {\n const sources = fixedSources ?? sourcesFromContext(ctx)\n const entries = fixedSources ? fixedEntries : entriesOf(sources)\n const def = fixedSources ? fixedDefault : defaultEntry(entries, sources, options.defaultModel)\n\n if (input.list === true)\n return listText(entries, def)\n\n const prompt = typeof input.prompt === 'string' ? input.prompt.trim() : ''\n if (!prompt)\n throw new ToolFailure('generate_image error: `prompt` is required.')\n if (entries.length === 0)\n throw new ToolFailure(`generate_image error: ${listText(entries, def)}`)\n\n const requested = typeof input.model === 'string' && input.model.trim() ? input.model.trim() : undefined\n const entry = requested ? findEntry(entries, requested) : def\n if (!entry) {\n throw new ToolFailure(`generate_image error: unknown model \"${requested}\". Use \\`<provider>/<model id>\\`:\\n${listText(entries, def)}`)\n }\n\n const aspectRatio = typeof input.aspect_ratio === 'string' ? input.aspect_ratio as ImageAspectRatio : undefined\n if (aspectRatio && !IMAGE_ASPECT_RATIOS.includes(aspectRatio))\n throw new ToolFailure(`generate_image error: \\`aspect_ratio\\` must be one of ${IMAGE_ASPECT_RATIOS.join(', ')}.`)\n const count = typeof input.n === 'number' && Number.isFinite(input.n) ? Math.floor(input.n) : 1\n if (count < 1 || count > MAX_IMAGES_PER_REQUEST)\n throw new ToolFailure(`generate_image error: \\`n\\` must be from 1 to ${MAX_IMAGES_PER_REQUEST}.`)\n const transparent = input.transparent === true\n if (transparent && !entry.model.transparency) {\n const capable = entries.filter(e => e.model.transparency).map(e => e.ref)\n throw new ToolFailure(`generate_image error: ${entry.ref} cannot make a transparent background.${capable.length ? ` Models that can: ${capable.join(', ')}.` : ''}`)\n }\n\n const referencePaths = Array.isArray(input.references) ? input.references.filter((p): p is string => typeof p === 'string' && p.trim() !== '') : []\n if (referencePaths.length > 0 && !entry.model.input.includes('image'))\n throw new ToolFailure(`generate_image error: ${entry.ref} does not take reference images. Pick a model marked [ref].`)\n if (referencePaths.length > MAX_REFERENCES)\n throw new ToolFailure(`generate_image error: at most ${MAX_REFERENCES} references per call.`)\n\n const now = new Date()\n const pathArg = typeof input.path === 'string' && input.path.trim() ? input.path.trim() : undefined\n const stem = stemOf(pathArg ? confinedPath(ctx, pathArg, 'path') : undefined, prompt, now)\n const references = await Promise.all(referencePaths.map(p => readReference(ctx, p)))\n\n const started = Date.now()\n let response: ProviderImageResponse\n try {\n response = await entry.source.images.generate({\n model: entry.model.id,\n prompt,\n ...(references.length ? { references } : {}),\n ...(aspectRatio ? { aspectRatio } : {}),\n count,\n ...(transparent ? { transparent } : {}),\n }, ctx.signal)\n }\n catch (err) {\n if (isAbortLikeError(err) || ctx.signal.aborted)\n throw err\n throw new ToolFailure(`generate_image error (${entry.ref}): ${errorMessage(err)}`)\n }\n const seconds = (Date.now() - started) / 1000\n\n const images = response.images.slice(0, count)\n const saved: string[] = []\n for (const [i, image] of images.entries()) {\n const ext = EXTENSION_BY_TYPE[image.mediaType] ?? 'png'\n const file = `${stem}${images.length > 1 ? `-${i + 1}` : ''}.${ext}`\n const record = {\n prompt,\n provider: entry.source.provider,\n model: response.model || entry.model.id,\n ...(aspectRatio ? { aspectRatio } : {}),\n ...(transparent ? { transparent } : {}),\n ...(referencePaths.length ? { references: referencePaths } : {}),\n ...(response.costUsd !== undefined ? { costUsd: response.costUsd / images.length } : {}),\n createdAt: now.toISOString(),\n }\n try {\n await ctx.execution.writeFile(ctx.handle, file, Buffer.from(image.data, 'base64'))\n await ctx.execution.writeFile(ctx.handle, recordPathOf(file), `${JSON.stringify(record, null, 2)}\\n`)\n }\n catch (err) {\n throw new ToolFailure(`generate_image error: the image was generated but saving ${file} failed: ${errorMessage(err)}`)\n }\n saved.push(file)\n }\n\n const sizes = images.map((image) => {\n const size = imageSizeFromBase64(image.data)\n return size ? `${size.width}x${size.height}` : image.mediaType\n })\n const lines = [\n `Generated ${images.length} image${images.length === 1 ? '' : 's'} with ${entry.ref} in ${seconds.toFixed(1)} s.`,\n ...saved.map((file, i) => `Saved: ${file} (${sizes[i]})`),\n `Records: ${saved.map(recordPathOf).join(', ')}`,\n ...(response.costUsd !== undefined ? [`Cost: ${formatCost(response.costUsd)}`] : []),\n ...(response.text ? [`Model note: ${response.text}`] : []),\n ]\n const previews: ToolResultContent[] = images.map((image) => {\n const shrunk = shrinkImageBase64(image.data, image.mediaType, PREVIEW_EDGE)\n return { type: 'image', mediaType: shrunk?.mediaType ?? image.mediaType, data: shrunk?.data ?? image.data }\n })\n return [{ type: 'text', text: lines.join('\\n') }, ...previews]\n },\n }\n}\n","import type { ListFileMetadata, ListFilesEntry } from '../contexts'\nimport type { ToolContext, ToolDef } from './types'\nimport { errorMessage, isAbortLikeError } from '../errors'\nimport { ToolFailure } from './failure'\nimport { toolPrompts } from './prompts'\n\n/** Default cap on returned matches. A `limit` argument overrides it. */\nconst DEFAULT_LIMIT = 1000\n\n/** Backstop so a pathological walk can never hang the agent's turn. */\nconst GLOB_TIMEOUT_MS = 20_000\n\nfunction entryPath(entry: ListFilesEntry): string {\n return typeof entry === 'string' ? entry : entry.path\n}\n\nfunction entryMetadata(entry: ListFilesEntry): ListFileMetadata | undefined {\n return typeof entry === 'string' ? undefined : entry\n}\n\nfunction renderEntry(entry: ListFilesEntry, wantMetadata: boolean): string {\n const path = entryPath(entry)\n const meta = entryMetadata(entry)\n if (!wantMetadata || typeof meta?.size !== 'number' || typeof meta.mtimeMs !== 'number')\n return path\n return `${path}\\t${meta.size}\\t${new Date(meta.mtimeMs).toISOString()}`\n}\n\n/**\n * The `glob` tool. Lists files in the execution context that match a glob pattern.\n *\n * Delegates matching to {@link ExecutionContext.listFiles} with `{ glob:\n * true }`. This keeps filesystem semantics inside the execution context\n * (process / docker / sandbox) instead of reaching around it from the tool.\n *\n * Results are capped at 1000 entries by default to keep model input bounded.\n * The cap applies after the directory filter, so dirs don't consume the\n * file budget.\n *\n * Patterns are deliberately NOT confined to the workspace: like\n * `read_file`, `../`-prefixed patterns may match outside the cwd — the\n * execution context is the sandbox boundary, not this tool.\n *\n * By default, contexts that can cheaply provide metadata return\n * `<path>\\t<size>\\t<mtime>` rows. Contexts without cheap metadata support return\n * paths only. Pass `metadata: false` to request plain newline-separated paths.\n */\nexport const glob: ToolDef = {\n // Filesystem listing only — safe to fan out alongside other reads.\n isConcurrencySafe: true,\n spec: {\n name: 'glob',\n description: toolPrompts.glob,\n inputSchema: {\n type: 'object',\n properties: {\n pattern: {\n type: 'string',\n description: 'Glob pattern (e.g. \"src/**/*.ts\", \"*.md\", \"test/**/fixtures/*\").',\n },\n limit: {\n type: 'number',\n description: `Maximum number of matches to return. Default: ${DEFAULT_LIMIT}.`,\n },\n metadata: {\n type: 'boolean',\n description: 'Append size (bytes) and mtime (ISO) per row, tab-separated. Default: true. In-process only; non-process execution contexts always return paths.',\n },\n gitignore: {\n type: 'boolean',\n description: 'Skip files git ignores (.gitignore, .git/info/exclude, global excludes). Default: true. Set false to include ignored files like node_modules. Honored where git is available; a no-op otherwise.',\n },\n },\n required: ['pattern'],\n },\n },\n async execute({ pattern, limit, metadata, gitignore }, ctx: ToolContext) {\n const pat = pattern as string\n const max = typeof limit === 'number' && limit > 0 ? limit : DEFAULT_LIMIT\n const wantMetadata = metadata !== false\n\n try {\n if (ctx.execution.capabilities.glob !== true)\n throw new Error(`The active execution context (${ctx.execution.type}) does not support glob matching.`)\n\n // Backstop: a pathological walk must never hang the turn. Abort the\n // listing and return a steer after GLOB_TIMEOUT_MS — raced so the tool\n // settles on time even if a streaming matcher is slow to yield control.\n // The controller is also linked to the caller's signal.\n const controller = new AbortController()\n const onAbort = () => controller.abort()\n ctx.signal.addEventListener('abort', onAbort, { once: true })\n let timer: ReturnType<typeof setTimeout> | undefined\n const timeout = new Promise<'timeout'>((resolve) => {\n timer = setTimeout(() => {\n controller.abort()\n resolve('timeout')\n }, GLOB_TIMEOUT_MS)\n })\n try {\n const outcome = await Promise.race([\n ctx.execution.listFiles(ctx.handle, pat, {\n glob: true,\n limit: max,\n metadata: wantMetadata,\n gitignore: gitignore as boolean | undefined,\n signal: controller.signal,\n }),\n timeout,\n ])\n if (outcome === 'timeout')\n return `Glob timed out after ${GLOB_TIMEOUT_MS}ms: narrow the pattern (anchor a literal prefix like \\`src/**\\`) or scope it to a subdirectory.`\n if (outcome.length === 0)\n return '(no matches)'\n return outcome.map(entry => renderEntry(entry, wantMetadata)).join('\\n')\n }\n finally {\n clearTimeout(timer)\n ctx.signal.removeEventListener('abort', onAbort)\n }\n }\n catch (err) {\n if (isAbortLikeError(err))\n throw err\n throw new ToolFailure(`Glob error: ${errorMessage(err)}`)\n }\n },\n}\n","import type { ToolContext, ToolDef } from './types'\nimport { Buffer } from 'node:buffer'\nimport { GIT_LS_FILES_COMMAND, parseGitLsFiles } from '../contexts/git-ls-files'\nimport { errorMessage, isAbortLikeError } from '../errors'\nimport { isToolFailure, ToolFailure } from './failure'\nimport { toolPrompts } from './prompts'\nimport { shellQuote } from './shell-quote'\n\n/** Default cap on output lines (`head_limit`). */\nconst DEFAULT_HEAD_LIMIT = 250\n\n/**\n * Per-line byte cap. ripgrep reports a match as the whole matching LINE, so a\n * minified / single-line file (one line = the entire file) would otherwise be\n * returned in full. Clip each line so a single line can't dump unbounded bytes\n * into the model context.\n */\nconst MAX_LINE_BYTES = 2000\n\n/**\n * OOM guard for the no-ripgrep fallback: it reads each candidate WHOLE\n * into memory (the execution interface has no streaming read), so one\n * multi-GB artifact would take the process down. Enforced twice — the\n * `find` walk excludes oversized files via the portable `-size`\n * predicate (POSIX `c` suffix, GNU + BSD), and the read loop probes\n * process-local sizes to cover the single-file fast path that bypasses\n * the walk. A documented divergence from the ripgrep path, which\n * streams and searches such files fine.\n */\nconst FALLBACK_MAX_FILE_BYTES = 16 * 1024 * 1024\n\n/** Total output byte cap, mirroring read_file's `DEFAULT_BYTE_CAP`. */\nconst OUTPUT_BYTE_CAP = 262_144\n\nconst DEFAULT_OUTPUT_MODE: OutputMode = 'files_with_matches'\n\ntype OutputMode = 'content' | 'files_with_matches' | 'count'\n\ninterface GrepInput {\n 'pattern': string\n 'patterns'?: string[]\n 'exclude'?: string\n 'fixed_strings'?: boolean\n '-w'?: boolean\n 'path'?: string\n 'paths'?: string[]\n 'glob'?: string\n 'type'?: string\n 'output_mode'?: OutputMode\n '-i'?: boolean\n '-n'?: boolean\n '-A'?: number\n '-B'?: number\n '-C'?: number\n 'multiline'?: boolean\n 'head_limit'?: number\n 'offset'?: number\n 'gitignore'?: boolean\n}\n\n/**\n * The `grep` tool. Searches file contents for regular expressions, using ripgrep when it is available and a JavaScript fallback otherwise.\n *\n * Wraps ripgrep (`rg`) when available; when it's not, falls back to a\n * regex search that enumerates files via the execution context's shell\n * (`find` over `exec`) and reads them via `ctx.execution.readFile`. Both\n * legs go through the {@link ToolContext.execution} seam, so the search\n * runs wherever the context's files actually live — in-process, a\n * container, or a remote sandbox — without the tool ever touching the host\n * filesystem directly.\n *\n * The tool surface mirrors Claude Code's `Grep` so models authored against the\n * Anthropic tool surface need no relearning. Output modes:\n * - `files_with_matches` (default) — newline-separated paths.\n * - `content` — `path:line:match` (line numbers on by default).\n * - `count` — `path:N` per matching file.\n *\n * Results are capped via `head_limit` (default 250) to keep model input\n * bounded; `offset` lets the caller page through. Pagination operates on\n * OUTPUT LINES, not match groups — in content mode, context lines and `--`\n * separators consume the budget too (documented in the schema).\n *\n * A line cap is not enough on its own: ripgrep is line-oriented, so a minified\n * / single-line file collapses to ONE match line that is the entire file, and\n * `head_limit` would happily return megabytes — enough to blow the model's\n * context window. Output is therefore ALSO byte-bounded: each line is clipped\n * to `MAX_LINE_BYTES` and the total to `OUTPUT_BYTE_CAP`, mirroring the byte\n * discipline `read_file` already enforces.\n *\n * `path` is deliberately NOT confined to the workspace: like `read_file`,\n * absolute paths and `../` traversal are allowed — the execution context is\n * the sandbox boundary, not this tool.\n */\n\nexport const grep: ToolDef = {\n // Searches files without touching them — concurrency-safe.\n isConcurrencySafe: true,\n spec: {\n name: 'grep',\n description: toolPrompts.grep,\n inputSchema: {\n type: 'object',\n properties: {\n 'pattern': { type: 'string', description: 'Regex (PCRE-flavored via ripgrep, JS regex via fallback).' },\n 'patterns': { type: 'array', items: { type: 'string' }, description: 'More regexes; a line matches if it matches `pattern` OR any of these (like `rg -e a -e b`).' },\n 'exclude': { type: 'string', description: 'Drop output lines matching this regex (applied to the whole output line, like piping through `grep -v`).' },\n 'fixed_strings': { type: 'boolean', description: 'Treat patterns as literal strings, not regexes (`-F`).' },\n '-w': { type: 'boolean', description: 'Match whole words only.' },\n 'path': { type: 'string', description: 'File or directory to search. Default: \".\". May be absolute or outside the workspace (no confinement; consistent with read_file).' },\n 'paths': { type: 'array', items: { type: 'string' }, description: 'Several files or directories to search in one call (combined with `path` when both are set).' },\n 'glob': { type: 'string', description: 'Restrict to files matching this glob, e.g. \"**/*.ts\".' },\n 'type': { type: 'string', description: 'rg file type filter, e.g. \"ts\", \"py\", \"rust\". Ignored by the fallback.' },\n 'output_mode': { type: 'string', enum: ['content', 'files_with_matches', 'count'], description: 'Default: \"files_with_matches\".' },\n '-i': { type: 'boolean', description: 'Case-insensitive match.' },\n '-n': { type: 'boolean', description: 'Show line numbers (content mode). Default: true.' },\n '-A': { type: 'integer', description: 'Lines of trailing context (content mode).' },\n '-B': { type: 'integer', description: 'Lines of leading context (content mode).' },\n '-C': { type: 'integer', description: 'Lines of surrounding context (content mode). Overridden by -A/-B if set.' },\n 'multiline': { type: 'boolean', description: 'Allow patterns to match across line boundaries.' },\n 'gitignore': { type: 'boolean', description: 'Skip files git ignores (.gitignore, .git/info/exclude, global excludes). Default: true. Set false to also search ignored files like node_modules.' },\n 'head_limit': { type: 'integer', description: `Cap output lines. Default: 250. Set 0 for unlimited lines. In content mode, context lines (-A/-B/-C) and \"--\" separators count toward the cap, so the number of matches shown may be lower. Output is independently byte-bounded: each line is clipped to ${MAX_LINE_BYTES} bytes and the total to ${OUTPUT_BYTE_CAP} bytes, so long (e.g. minified) lines never overflow the context window.` },\n 'offset': { type: 'integer', description: 'Skip first N output lines. Default: 0.' },\n },\n required: ['pattern'],\n },\n },\n async execute(rawInput, ctx: ToolContext) {\n const input = rawInput as unknown as GrepInput\n const invalid = validateInput(input)\n if (invalid)\n throw new ToolFailure(`grep error: ${invalid}`)\n\n try {\n if (await isRipgrepAvailable(ctx))\n return await runViaRipgrep(input, ctx)\n return await runFallback(input, ctx)\n }\n catch (err) {\n // grep must never leak a raw exception to the model. An abort is the\n // sole exception we re-throw — the loop renders its canonical\n // interrupt/cascade marker; everything else (a broken `exec`, an\n // unreadable tree, a remote transport error) becomes a `grep error:`.\n if (isAbortLikeError(err) || isToolFailure(err))\n throw err\n throw new ToolFailure(`grep error: ${errorMessage(err)}`)\n }\n },\n}\n\n// ---------------------------------------------------------------------------\n// ripgrep path\n// ---------------------------------------------------------------------------\n\n/**\n * Probe ripgrep availability **per call**. The probe is intentionally not\n * cached: caching at module scope would leak across execution contexts (an\n * orchestrator running an in-process agent and a docker agent in the same\n * Node process must be able to differ on whether `rg` exists), and caching\n * per handle adds bookkeeping for negligible savings — `rg --version` is\n * ~5 ms, and grep is invoked at most a few times per turn.\n */\nasync function isRipgrepAvailable(ctx: ToolContext): Promise<boolean> {\n const result = await ctx.execution.exec(ctx.handle, 'rg --version', { signal: ctx.signal })\n return result.exitCode === 0\n}\n\n/**\n * Every regex the call matches on: `pattern` plus non-empty `patterns`. An\n * empty `pattern` next to non-empty `patterns` is dropped: it would match\n * every line.\n */\nfunction allPatterns(input: GrepInput): string[] {\n const extra = Array.isArray(input.patterns) ? input.patterns.filter(p => typeof p === 'string' && p.length > 0) : []\n if (input.pattern === '' && extra.length > 0)\n return extra\n return [input.pattern, ...extra]\n}\n\n/** Search roots: `path` and `paths` combined, defaulting to `.`. */\nfunction searchRoots(input: GrepInput): string[] {\n const roots = [\n ...(typeof input.path === 'string' && input.path.length > 0 ? [input.path] : []),\n ...(Array.isArray(input.paths) ? input.paths.filter(p => typeof p === 'string' && p.length > 0) : []),\n ]\n return roots.length > 0 ? [...new Set(roots)] : ['.']\n}\n\nfunction validateInput(input: GrepInput): string | undefined {\n if (typeof input.pattern !== 'string')\n return '`pattern` must be a string.'\n if (input.patterns !== undefined && (!Array.isArray(input.patterns) || input.patterns.some(p => typeof p !== 'string')))\n return '`patterns` must be an array of strings.'\n if (input.paths !== undefined && (!Array.isArray(input.paths) || input.paths.some(p => typeof p !== 'string')))\n return '`paths` must be an array of strings.'\n if (input.exclude !== undefined) {\n if (typeof input.exclude !== 'string')\n return '`exclude` must be a string.'\n try {\n void new RegExp(input.exclude)\n }\n catch (err) {\n return `invalid exclude regex: ${errorMessage(err)}`\n }\n }\n return undefined\n}\n\nasync function runViaRipgrep(input: GrepInput, ctx: ToolContext): Promise<string> {\n const args = ['rg']\n const mode = (input.output_mode ?? DEFAULT_OUTPUT_MODE) as OutputMode\n\n if (mode === 'files_with_matches')\n args.push('--files-with-matches')\n else if (mode === 'count')\n args.push('--count')\n else\n args.push((input['-n'] ?? true) ? '--line-number' : '--no-line-number')\n\n if (input['-i'])\n args.push('-i')\n if (input.fixed_strings)\n args.push('--fixed-strings')\n if (input['-w'])\n args.push('--word-regexp')\n\n if (mode === 'content') {\n if (typeof input['-A'] === 'number')\n args.push('-A', String(input['-A']))\n if (typeof input['-B'] === 'number')\n args.push('-B', String(input['-B']))\n if (typeof input['-C'] === 'number' && typeof input['-A'] !== 'number' && typeof input['-B'] !== 'number')\n args.push('-C', String(input['-C']))\n }\n\n if (input.multiline)\n args.push('--multiline', '--multiline-dotall')\n\n // ripgrep respects .gitignore by default; only disable it on explicit opt-out.\n if (input.gitignore === false)\n args.push('--no-ignore')\n\n if (input.glob)\n args.push('--glob', input.glob)\n\n if (input.type)\n args.push('--type', input.type)\n\n // `-e` per pattern (OR semantics); `-e` also keeps a leading-dash pattern\n // from parsing as a flag.\n for (const pattern of allPatterns(input))\n args.push('-e', pattern)\n\n // Always pass a path — rg reads from stdin when invoked from a non-TTY child\n // process without a path argument, which hangs forever waiting for input.\n args.push('--', ...searchRoots(input))\n\n const command = args.map(shellQuote).join(' ')\n const result = await ctx.execution.exec(ctx.handle, command, { signal: ctx.signal })\n\n // ripgrep exits 1 when there are no matches — that's not an error here.\n if (result.exitCode !== 0 && result.exitCode !== 1) {\n throw new ToolFailure(`grep error: ${result.stderr.trim() || `rg exited with code ${result.exitCode}`}`)\n }\n\n return formatPaginated(result.stdout, input)\n}\n\n// ---------------------------------------------------------------------------\n// Fallback path (context-routed `find` enumeration + readFile + JS regex)\n// ---------------------------------------------------------------------------\n\nasync function runFallback(input: GrepInput, ctx: ToolContext): Promise<string> {\n const mode = (input.output_mode ?? DEFAULT_OUTPUT_MODE) as OutputMode\n const flags = `${input['-i'] ? 'i' : ''}${input.multiline ? 's' : ''}${mode !== 'content' ? '' : 'g'}`\n\n let regex: RegExp\n try {\n regex = new RegExp(fallbackSource(input), flags || undefined)\n }\n catch (err) {\n throw new ToolFailure(`grep error: invalid regex: ${errorMessage(err)}`)\n }\n\n const multilineRegex = input.multiline ? new RegExp(regex.source, `${flags.replace(/g/, '')}g`) : undefined\n const files: string[] = []\n for (const root of searchRoots(input)) {\n for (const file of await enumerateFiles(input, root, ctx)) {\n if (!files.includes(file))\n files.push(file)\n }\n }\n const showLineNumbers = input['-n'] ?? true\n const before = (input['-B'] ?? input['-C'] ?? 0)\n const after = (input['-A'] ?? input['-C'] ?? 0)\n\n // Second layer of the fallback's OOM guard, scoped to the single-file\n // fast path ONLY: walk-enumerated files are already size-filtered by\n // the find predicate, and probing each of them would cost one exec per\n // file on exec-probed contexts (docker/sandbox) — N extra round-trips\n // for zero added protection. The fast path bypasses the walk, so it is\n // the one entry that needs the probe. (Contexts without the capability\n // proceed unguarded: same accepted residual as whole-read-guard.ts.)\n const viaSingleFileFastPath = files.length === 1 && searchRoots(input).includes(files[0] as string)\n if (viaSingleFileFastPath) {\n const size = await ctx.execution.fileSize?.(ctx.handle, files[0] as string) ?? null\n if (size !== null && size > FALLBACK_MAX_FILE_BYTES)\n return '(no matches)'\n }\n\n const lines: string[] = []\n for (const path of files) {\n let content: string\n try {\n content = await ctx.execution.readFile(ctx.handle, path)\n }\n catch (err) {\n // Skip unreadable / binary / vanished files — but let an abort\n // propagate (a remote readFile may reject with AbortError on cancel).\n if (isAbortLikeError(err))\n throw err\n continue\n }\n if (multilineRegex) {\n // Multiline mode: scan the whole buffer with /g semantics.\n const allMatches = [...content.matchAll(multilineRegex)]\n if (allMatches.length === 0)\n continue\n if (mode === 'files_with_matches') {\n lines.push(path)\n continue\n }\n if (mode === 'count') {\n lines.push(`${path}:${allMatches.length}`)\n continue\n }\n // content mode — emit each match's surrounding line context. Line\n // numbers advance incrementally (matches arrive in index order) instead\n // of re-splitting the prefix per match (which costs O(matches x size)).\n let lineNo = 1\n let scannedTo = 0\n for (const m of allMatches) {\n const lineStart = content.lastIndexOf('\\n', m.index! - 1) + 1\n const lineEnd = content.indexOf('\\n', m.index!)\n const snippet = content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd)\n for (let nl = content.indexOf('\\n', scannedTo); nl !== -1 && nl < m.index!; nl = content.indexOf('\\n', nl + 1))\n lineNo++\n scannedTo = m.index!\n lines.push(formatContentLine(path, lineNo, snippet, showLineNumbers))\n }\n continue\n }\n\n const fileLines = content.split('\\n')\n const matched: number[] = []\n for (let i = 0; i < fileLines.length; i++) {\n regex.lastIndex = 0\n if (regex.test(fileLines[i]))\n matched.push(i)\n }\n if (matched.length === 0)\n continue\n\n if (mode === 'files_with_matches') {\n lines.push(path)\n continue\n }\n if (mode === 'count') {\n lines.push(`${path}:${matched.length}`)\n continue\n }\n\n const includeLineNos = new Set<number>()\n for (const m of matched) {\n for (let i = Math.max(0, m - before); i <= Math.min(fileLines.length - 1, m + after); i++)\n includeLineNos.add(i)\n }\n const sorted = [...includeLineNos].sort((a, b) => a - b)\n let prev = -2\n for (const lineNo of sorted) {\n if (lineNo > prev + 1 && lines.length > 0)\n lines.push('--')\n const snippet = fileLines[lineNo]\n lines.push(formatContentLine(path, lineNo + 1, snippet, showLineNumbers))\n prev = lineNo\n }\n }\n\n return formatPaginated(lines.join('\\n'), input)\n}\n\nfunction formatContentLine(path: string, lineNo: number, snippet: string, showLineNumbers: boolean): string {\n return showLineNumbers ? `${path}:${lineNo}:${snippet}` : `${path}:${snippet}`\n}\n\n/**\n * JS regex source for the fallback: patterns OR'ed together, escaped under\n * `fixed_strings`, wrapped in word boundaries under `-w`.\n */\nfunction fallbackSource(input: GrepInput): string {\n const parts = allPatterns(input).map(p => input.fixed_strings ? p.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') : p)\n const joined = parts.length === 1 ? parts[0] : parts.map(p => `(?:${p})`).join('|')\n return input['-w'] ? `\\\\b(?:${joined})\\\\b` : joined\n}\n\nasync function enumerateFiles(input: GrepInput, root: string, ctx: ToolContext): Promise<string[]> {\n // Single-file fast path: if the root names a file, search just it. Routed\n // through `exec` so the check runs inside the context, not on the host.\n if (root !== '.' && !root.includes('*') && !root.includes('?')) {\n const probe = await ctx.execution.exec(ctx.handle, `test -f ${shellQuote(root)} && echo file || echo dir`, { signal: ctx.signal })\n if (probe.stdout.trim() === 'file')\n return [root]\n }\n\n // Enumerate through the execution context's shell so the listing comes from\n // wherever the context's files live — never the host filesystem. `find` is\n // the same primitive the `glob` tool's portable path uses.\n const result = await ctx.execution.exec(ctx.handle, buildFindCommand(root, input.glob), { signal: ctx.signal })\n\n // A non-zero exit with NO output is a real failure (find unavailable, bad\n // root) — surface it like ripgrep would for a bad path. A non-zero exit WITH\n // output is a partial walk (e.g. an unreadable subdir): keep what we got.\n // `find` writes diagnostics to\n // stderr, so stdout stays a clean newline-separated path list either way.\n if (result.exitCode !== 0 && !result.stdout.trim())\n throw new Error(result.stderr.trim() || `find exited with code ${result.exitCode}`)\n\n const files = result.stdout\n .split('\\n')\n .map(line => line.replace(/^\\.\\//, ''))\n .filter(line => line.length > 0)\n .sort()\n\n // `find` honors no ignore rules, so the no-`rg` fallback would otherwise\n // walk `node_modules` etc. — inconsistent with the ripgrep path. Restrict to\n // git's non-ignored set by default; `gitignore: false` keeps everything.\n if (input.gitignore === false)\n return files\n return filterByGitignore(files, root, ctx)\n}\n\n/**\n * Best-effort intersection of `files` with `git ls-files` (non-ignored set).\n * Returns `files` unchanged when git is unavailable, the dir isn't a repo, or\n * `root` escapes the repo (absolute / `..`) — the filter can only fail open.\n */\nasync function filterByGitignore(files: string[], root: string, ctx: ToolContext): Promise<string[]> {\n if (files.length === 0)\n return files\n if (root !== '.' && (root.startsWith('/') || root.split('/').includes('..')))\n return files\n try {\n const res = await ctx.execution.exec(ctx.handle, GIT_LS_FILES_COMMAND, { signal: ctx.signal })\n if (res.exitCode !== 0)\n return files\n const allowed = new Set(parseGitLsFiles(res.stdout))\n if (allowed.size === 0)\n return files\n return files.filter(file => allowed.has(file))\n }\n catch {\n return files\n }\n}\n\n/**\n * Build a `find` command listing files under `root`, optionally filtered by\n * `glob`. Mirrors `glob`'s shell fallback:\n * - a bare basename, or one behind a leading recursive-wildcard segment,\n * with no inner slash → `-name` (matches at any depth, including the top\n * level — preserving the recursive-glob semantics).\n * - anything with a slash → `-path` against the full relative path. `find`'s\n * `*` spans `/`, so the single- and double-star forms collapse to the\n * same matcher; close enough for the no-`rg` fallback.\n */\nfunction buildFindCommand(root: string, glob?: string): string {\n const findRoot = normalizeFindRoot(root)\n const base = shellQuote(findRoot)\n const sizeGuard = `! -size +${FALLBACK_MAX_FILE_BYTES}c`\n if (!glob)\n return `find ${base} -type f ${sizeGuard}`\n const anyDepth = glob.match(/^(?:\\*\\*\\/)?([^/]+)$/)\n if (anyDepth)\n return `find ${base} -type f ${sizeGuard} -name ${shellQuote(anyDepth[1])}`\n const normRoot = findRoot.replace(/\\/$/, '')\n const pathPattern = root === '.' ? `./${glob}` : `${normRoot}/${glob}`\n return `find ${base} -type f ${sizeGuard} -path ${shellQuote(pathPattern)}`\n}\n\nfunction normalizeFindRoot(root: string): string {\n // POSIX `find` parses a leading-dash first operand as an expression/option.\n // Prefix relative paths like `-fixtures` so they remain path operands.\n return root.startsWith('-') ? `./${root}` : root\n}\n\nfunction formatPaginated(text: string, input: GrepInput): string {\n const headLimit = typeof input.head_limit === 'number' && input.head_limit >= 0\n ? input.head_limit\n : DEFAULT_HEAD_LIMIT\n const offset = typeof input.offset === 'number' && input.offset > 0\n ? Math.floor(input.offset)\n : 0\n\n if (!text.trim())\n return '(no matches)'\n\n const lines = applyExclude(text.split('\\n').filter(l => l.length > 0), input.exclude)\n if (lines.length === 0)\n return '(no matches after exclude)'\n const total = lines.length\n\n const sliced = headLimit === 0\n ? lines.slice(offset)\n : lines.slice(offset, offset + headLimit)\n\n if (sliced.length === 0)\n return '(no matches in this slice)'\n\n // Byte budget. `head_limit` caps the LINE count, but a single line can be\n // arbitrarily large (a minified / one-line file is one match line = the whole\n // file), so a line cap alone leaves byte output unbounded and can overflow the\n // model context. Clip each line, then stop once the total crosses the cap.\n const capped: string[] = []\n let bytesUsed = 0\n let byteCut = false\n for (const line of sliced) {\n const clipped = clipLine(line)\n const lineBytes = Buffer.byteLength(clipped) + 1 // +1 for the rejoining '\\n'\n if (bytesUsed + lineBytes > OUTPUT_BYTE_CAP && capped.length > 0) {\n byteCut = true\n break\n }\n capped.push(clipped)\n bytesUsed += lineBytes\n }\n\n const shown = capped.length\n const truncatedHead = offset > 0\n // Lines withheld by the line-count window, independent of the byte cut.\n const lineCutTail = headLimit > 0 && offset + headLimit < total\n\n // Markers say \"lines\", not \"matches\" — in content mode the pagination\n // unit includes context lines and `--` separators.\n let out = capped.join('\\n')\n if (truncatedHead)\n out = `…(${offset} earlier lines skipped)…\\n${out}`\n if (byteCut)\n out = `${out}\\n…(output truncated at ${OUTPUT_BYTE_CAP} bytes after ${shown} of ${total - offset} matching lines; narrow the pattern or page with offset=${offset + shown})`\n else if (lineCutTail)\n out = `${out}\\n…(${total - offset - headLimit} more lines; re-run with offset=${offset + headLimit} or larger head_limit)`\n return out\n}\n\n/**\n * Drop output lines matching `exclude` (validated upfront). Context-group\n * `--` separators are kept only between surviving lines, never doubled or at\n * the edges.\n */\nfunction applyExclude(lines: string[], exclude: string | undefined): string[] {\n if (!exclude)\n return lines\n const re = new RegExp(exclude)\n const kept: string[] = []\n for (const line of lines) {\n if (line === '--') {\n if (kept.length > 0 && kept[kept.length - 1] !== '--')\n kept.push(line)\n continue\n }\n if (!re.test(line))\n kept.push(line)\n }\n while (kept.length > 0 && kept[kept.length - 1] === '--')\n kept.pop()\n return kept\n}\n\n/**\n * Clip one output line to `MAX_LINE_BYTES` at a UTF-8-safe boundary, appending\n * a marker that reports how many bytes were withheld. Lines within budget pass\n * through untouched.\n */\nfunction clipLine(line: string): string {\n if (Buffer.byteLength(line) <= MAX_LINE_BYTES)\n return line\n let cut = Math.min(line.length, MAX_LINE_BYTES)\n while (cut > 0 && Buffer.byteLength(line.slice(0, cut)) > MAX_LINE_BYTES)\n cut--\n const omitted = Buffer.byteLength(line) - Buffer.byteLength(line.slice(0, cut))\n return `${line.slice(0, cut)}… [line clipped, ${omitted} more bytes]`\n}\n","/**\n * Interaction tool — lets the agent request structured input from the outside world.\n *\n * Not included in any preset by default. Add it explicitly:\n *\n * import { createInteractionTool } from 'zidane'\n *\n * const askUser = createInteractionTool({\n * schema: { type: 'object', properties: { question: { type: 'string' } }, required: ['question'] },\n * onRequest: async (payload) => {\n * const answer = await promptUser(payload.question)\n * return { answer }\n * },\n * })\n *\n * const preset = definePreset({ name: 'interactive', tools: { ...basicTools, ask_user: askUser } })\n */\n\nimport type { ToolContext, ToolDef } from './types'\nimport { toolPrompts } from './prompts'\n\nfunction abortReason(signal: AbortSignal): string {\n return typeof signal.reason === 'string' && signal.reason.length > 0\n ? signal.reason\n : 'Interaction aborted'\n}\n\n/** Options for {@link createInteractionTool}. */\nexport interface InteractionToolOptions {\n /** JSON Schema for the request payload the model sends */\n schema: Record<string, unknown>\n /** Tool name (default: 'interaction') */\n name?: string\n /** Tool description shown to the model */\n description?: string\n /** Called when the model invokes this tool. Receives the validated payload and tool context, returns data for the model. */\n onRequest: (payload: Record<string, unknown>, ctx: ToolContext) => Promise<Record<string, unknown> | string>\n}\n\n/**\n * Create an interaction tool that lets the agent request structured input.\n *\n * The model calls this tool with a payload matching the schema.\n * `onRequest` is called with the payload and should return the response\n * (string or object) that gets sent back to the model as the tool result.\n * @param options - Payload schema, optional name and description, and the `onRequest` handler.\n * @example\n * ```ts\n * import { createInteractionTool } from 'zidane/tools'\n *\n * const askUser = createInteractionTool({\n * name: 'ask_user',\n * schema: { type: 'object', properties: { question: { type: 'string' } }, required: ['question'] },\n * onRequest: async payload => `Answer to: ${String(payload.question)}`,\n * })\n * ```\n */\nexport function createInteractionTool(options: InteractionToolOptions): ToolDef {\n const name = options.name ?? 'interaction'\n const description = options.description ?? toolPrompts.interaction\n\n return {\n spec: {\n name,\n description,\n inputSchema: options.schema,\n },\n async execute(input, ctx) {\n // Race the host resolver against the run's abort signal. `onRequest`\n // settles only on external (human/system) action, so without this an\n // `agent.abort()` / `agent.destroy()` — every teardown/cancel path —\n // would leave the tool body (and the run) hanging on a promise that can\n // never settle. On abort we reject so the loop unwinds cleanly.\n const { signal } = ctx\n if (signal?.aborted)\n throw new Error(abortReason(signal))\n\n let onAbort: (() => void) | undefined\n const abortPromise = signal\n ? new Promise<never>((_, reject) => {\n onAbort = () => reject(new Error(abortReason(signal)))\n signal.addEventListener('abort', onAbort, { once: true })\n })\n : undefined\n\n try {\n const result = abortPromise\n ? await Promise.race([options.onRequest(input, ctx), abortPromise])\n : await options.onRequest(input, ctx)\n return typeof result === 'string' ? result : JSON.stringify(result)\n }\n finally {\n if (signal && onAbort)\n signal.removeEventListener('abort', onAbort)\n }\n },\n }\n}\n"],"mappings":"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"}
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { $
|
|
2
|
-
import { n as toolPrompts, t as ToolPrompts } from "./prompts-
|
|
3
|
-
export { type ChildAgent, type CreateShellToolOptions, type ExtensionSubagentDef, type HydrateReadStateOptions, type InteractionToolOptions, type LazyToolEntry, RECORD_ARTIFACT_TOOL, type ReadStateEntry, type ReadStateMap, type SkillsReadToolOptions, type SkillsRunScriptToolOptions, type SkillsUseToolOptions, type SpawnModelEntry, type SpawnTaskInput, type SpawnTaskOutcome, type SpawnTool, type SpawnToolOptions, type SpawnToolState, type SubagentDef, type SubagentOverride, type SubagentRegistry, type TailTruncateOptions, type ToolContext, type ToolDef, type ToolDescriptionOverride, type ToolDescriptionTarget, type ToolDescriptions, type ToolMap, type ToolPrompts, type ToolSearchToolOptions, type ValidationResult, WAIT_TASK_TIMED_OUT_PREFIX, createInteractionTool, createModelSearchTool, createShellTool, createSkillsReadTool, createSkillsRunScriptTool, createSkillsUseTool, createSpawnTool, createToolSearchTool, edit, formatModelLine, getReadState, glob, grep, hashContent, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, isSpawnTool, listFiles, matchModelEntries, multiEdit, readFile, readStateKey, recordArtifact, resolveReadStateMap, shell, shellKill, tailTruncate, toolPrompts, validateToolArgs, waitTask, withIsolatedSpawnTool, writeFile };
|
|
1
|
+
import { $T as ToolDescriptionOverride, $r as edit, $u as ExtensionSubagentDef, Ar as SkillsUseToolOptions, Br as RECORD_ARTIFACT_TOOL, Cr as writeFile, Da as ToolSearchToolOptions, Dr as validateToolArgs, Ea as LazyToolEntry, Er as ValidationResult, Fr as createSkillsReadTool, Gr as InteractionToolOptions, Hr as readFile, Ir as shellKill, Jr as glob, Kr as createInteractionTool, Lr as CreateShellToolOptions, Mr as SkillsRunScriptToolOptions, Nr as createSkillsRunScriptTool, Oa as createToolSearchTool, Or as TailTruncateOptions, Pr as SkillsReadToolOptions, QT as ToolDef, Qr as createGenerateImageTool, Qu as ChildAgent, Rr as createShellTool, Tr as waitTask, Ur as multiEdit, Vr as recordArtifact, Wr as listFiles, Xr as GenerateImageToolOptions, Yr as DEFAULT_IMAGE_DIR, ZT as ToolContext, Zr as ImageModelSource, aE as ReadStateMap, ad as SubagentDef, cE as hydrateReadStateFromSession, cd as createSpawnTool, dE as resolveReadStateMap, dd as SpawnModelEntry, eE as ToolDescriptionTarget, ed as SpawnTaskInput, fd as createModelSearchTool, iE as ReadStateEntry, id as SpawnToolState, jr as createSkillsUseTool, kr as tailTruncate, lE as hydrateReadStateFromSessionAsync, ld as withIsolatedSpawnTool, md as matchModelEntries, nE as ToolMap, nd as SpawnTool, oE as getReadState, od as SubagentOverride, pd as formatModelLine, qr as grep, rE as HydrateReadStateOptions, rd as SpawnToolOptions, sE as hashContent, sd as SubagentRegistry, tE as ToolDescriptions, td as SpawnTaskOutcome, uE as readStateKey, ud as isSpawnTool, wr as WAIT_TASK_TIMED_OUT_PREFIX, zr as shell } from "./index-DyQyDLX1.js";
|
|
2
|
+
import { n as toolPrompts, t as ToolPrompts } from "./prompts-DmY13jvF.js";
|
|
3
|
+
export { type ChildAgent, type CreateShellToolOptions, DEFAULT_IMAGE_DIR, type ExtensionSubagentDef, type GenerateImageToolOptions, type HydrateReadStateOptions, type ImageModelSource, type InteractionToolOptions, type LazyToolEntry, RECORD_ARTIFACT_TOOL, type ReadStateEntry, type ReadStateMap, type SkillsReadToolOptions, type SkillsRunScriptToolOptions, type SkillsUseToolOptions, type SpawnModelEntry, type SpawnTaskInput, type SpawnTaskOutcome, type SpawnTool, type SpawnToolOptions, type SpawnToolState, type SubagentDef, type SubagentOverride, type SubagentRegistry, type TailTruncateOptions, type ToolContext, type ToolDef, type ToolDescriptionOverride, type ToolDescriptionTarget, type ToolDescriptions, type ToolMap, type ToolPrompts, type ToolSearchToolOptions, type ValidationResult, WAIT_TASK_TIMED_OUT_PREFIX, createGenerateImageTool, createInteractionTool, createModelSearchTool, createShellTool, createSkillsReadTool, createSkillsRunScriptTool, createSkillsUseTool, createSpawnTool, createToolSearchTool, edit, formatModelLine, getReadState, glob, grep, hashContent, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, isSpawnTool, listFiles, matchModelEntries, multiEdit, readFile, readStateKey, recordArtifact, resolveReadStateMap, shell, shellKill, tailTruncate, toolPrompts, validateToolArgs, waitTask, withIsolatedSpawnTool, writeFile };
|