tool-schemas.expected.json 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. {
  2. "initial": [
  3. {
  4. "name": "bash",
  5. "description": "Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under <mode> mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. Attempting a command the sandbox may deny is safe and expected: run it and read the marker rather than assuming the denial. When a command is denied and a wider mode would let it succeed, escalate immediately in the same turn — the one sanctioned exception to a denial: retry the exact same command once with `sandbox_permissions` (the narrowest wider mode that suffices) plus a one-sentence `justification`. Do not detour through chat to ask permission first — the approval prompt raised by that retry is how the user consents. If the session states approval prompts are disabled, there is no exception: a denial is final — do not set `sandbox_permissions`. Never escalate speculatively: ground the request in a real denial — normally the one this command just hit; escalating up front is fine only when this session already denied the same access. A rejected escalation is final for that command — stop and explain, never work around it — but it does not forbid attempting or escalating other commands later.",
  6. "parameters": {
  7. "type": "object",
  8. "properties": {
  9. "command": {
  10. "type": "string",
  11. "description": "The bash command to execute."
  12. },
  13. "description": {
  14. "type": "string",
  15. "description": "Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"."
  16. },
  17. "timeoutMs": {
  18. "type": "number",
  19. "description": "Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry."
  20. },
  21. "workdir": {
  22. "type": "string",
  23. "description": "Working directory for this command. Defaults to the session workspace; a relative path is resolved against it."
  24. },
  25. "run_in_background": {
  26. "type": "boolean",
  27. "description": "Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies."
  28. },
  29. "sandbox_permissions": {
  30. "type": "string",
  31. "description": "The wider sandbox mode this command needs. Only valid as a one-shot retry of a command the sandbox just denied; requires justification and user approval.",
  32. "enum": [
  33. "workspace-write",
  34. "danger-full-access"
  35. ]
  36. },
  37. "justification": {
  38. "type": "string",
  39. "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact command needs the wider access."
  40. }
  41. },
  42. "required": [
  43. "command",
  44. "description"
  45. ]
  46. }
  47. },
  48. {
  49. "name": "edit",
  50. "description": "Edit an existing UTF-8 text file by replacing literal text.",
  51. "parameters": {
  52. "type": "object",
  53. "properties": {
  54. "file_path": {
  55. "type": "string",
  56. "description": "Path to edit, resolved by the filesystem backend."
  57. },
  58. "old_string": {
  59. "type": "string",
  60. "description": "Literal text to replace. Must match exactly."
  61. },
  62. "new_string": {
  63. "type": "string",
  64. "description": "Literal replacement text. Use an empty string to delete the match."
  65. },
  66. "replace_all": {
  67. "type": "boolean",
  68. "description": "Replace all matches. Defaults to false; when false, old_string must appear exactly once."
  69. },
  70. "sandbox_permissions": {
  71. "type": "string",
  72. "description": "The wider sandbox mode this file operation needs. Only valid as a one-shot retry of an operation the sandbox just denied; requires justification and user approval.",
  73. "enum": [
  74. "workspace-write",
  75. "danger-full-access"
  76. ]
  77. },
  78. "justification": {
  79. "type": "string",
  80. "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access."
  81. }
  82. },
  83. "required": [
  84. "file_path",
  85. "old_string",
  86. "new_string"
  87. ]
  88. }
  89. },
  90. {
  91. "name": "read",
  92. "description": "Read a UTF-8 text file and return line-numbered content.",
  93. "parameters": {
  94. "type": "object",
  95. "properties": {
  96. "file_path": {
  97. "type": "string",
  98. "description": "Path to read, resolved by the filesystem backend."
  99. },
  100. "offset": {
  101. "type": "number",
  102. "description": "1-based first line to return. Defaults to 1."
  103. },
  104. "limit": {
  105. "type": "number",
  106. "description": "Maximum number of lines to return. Defaults to 2000."
  107. }
  108. },
  109. "required": [
  110. "file_path"
  111. ]
  112. }
  113. },
  114. {
  115. "name": "skill",
  116. "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.",
  117. "parameters": {
  118. "type": "object",
  119. "properties": {
  120. "name": {
  121. "type": "string",
  122. "description": "The exact skill name from the available skills list."
  123. }
  124. },
  125. "required": [
  126. "name"
  127. ]
  128. }
  129. },
  130. {
  131. "name": "subagent",
  132. "description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to return a task id; collect with `task_output` and stop with `task_kill`.",
  133. "parameters": {
  134. "type": "object",
  135. "properties": {
  136. "description": {
  137. "type": "string",
  138. "description": "A short (3-5 word) description of the delegated task, for display."
  139. },
  140. "prompt": {
  141. "type": "string",
  142. "description": "The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs."
  143. },
  144. "run_in_background": {
  145. "type": "boolean",
  146. "description": "Run as a background task and return its id; collect with task_output or stop with task_kill."
  147. }
  148. },
  149. "required": [
  150. "description",
  151. "prompt"
  152. ]
  153. }
  154. },
  155. {
  156. "name": "subagent_fork",
  157. "description": "Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to return a task id; collect with `task_output` and stop with `task_kill`.",
  158. "parameters": {
  159. "type": "object",
  160. "properties": {
  161. "description": {
  162. "type": "string",
  163. "description": "A short (3-5 word) description of the delegated task, for display."
  164. },
  165. "prompt": {
  166. "type": "string",
  167. "description": "The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new."
  168. },
  169. "run_in_background": {
  170. "type": "boolean",
  171. "description": "Run as a background task and return its id; collect with task_output or stop with task_kill."
  172. }
  173. },
  174. "required": [
  175. "description",
  176. "prompt"
  177. ]
  178. }
  179. },
  180. {
  181. "name": "task_kill",
  182. "description": "Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.",
  183. "parameters": {
  184. "type": "object",
  185. "properties": {
  186. "task_id": {
  187. "type": "string",
  188. "description": "Task id returned by the tool that started the background work."
  189. },
  190. "reason": {
  191. "type": "string",
  192. "description": "Optional short reason, recorded in the log and forwarded to the task."
  193. }
  194. },
  195. "required": [
  196. "task_id"
  197. ]
  198. }
  199. },
  200. {
  201. "name": "task_list",
  202. "description": "List your background tasks (running and finished) with their ids, kinds, and statuses.",
  203. "parameters": {
  204. "type": "object",
  205. "properties": {}
  206. }
  207. },
  208. {
  209. "name": "task_output",
  210. "description": "Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.",
  211. "parameters": {
  212. "type": "object",
  213. "properties": {
  214. "task_id": {
  215. "type": "string",
  216. "description": "Task id returned by the tool that started the background work."
  217. },
  218. "wait": {
  219. "type": "boolean",
  220. "description": "Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive."
  221. },
  222. "timeout_ms": {
  223. "type": "number",
  224. "description": "Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum."
  225. }
  226. },
  227. "required": [
  228. "task_id"
  229. ]
  230. }
  231. },
  232. {
  233. "name": "todo_write",
  234. "description": "Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Keep AT MOST ONE todo `in_progress` at a time; while work remains, exactly one active task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).",
  235. "parameters": {
  236. "type": "object",
  237. "properties": {
  238. "todos": {
  239. "type": "array",
  240. "description": "The COMPLETE task list, replacing any previous list.",
  241. "items": {
  242. "type": "object",
  243. "properties": {
  244. "content": {
  245. "type": "string",
  246. "description": "What the task is — a short imperative line."
  247. },
  248. "status": {
  249. "type": "string",
  250. "description": "pending (not started) | in_progress (now) | completed (done).",
  251. "enum": [
  252. "pending",
  253. "in_progress",
  254. "completed"
  255. ]
  256. }
  257. },
  258. "required": [
  259. "content",
  260. "status"
  261. ]
  262. }
  263. }
  264. },
  265. "required": [
  266. "todos"
  267. ]
  268. }
  269. },
  270. {
  271. "name": "workflow",
  272. "description": "Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return <value>` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise<any>` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const — no oneOf/pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise<any[]>` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise<any[]>` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.",
  273. "parameters": {
  274. "type": "object",
  275. "properties": {
  276. "script": {
  277. "type": "string",
  278. "description": "The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return <json-value>`)."
  279. },
  280. "meta": {
  281. "type": "object",
  282. "description": "The workflow identity block (plain JSON — never code).",
  283. "properties": {
  284. "name": {
  285. "type": "string",
  286. "description": "Short kebab-case workflow name."
  287. },
  288. "description": {
  289. "type": "string",
  290. "description": "One-line description of what the workflow does."
  291. },
  292. "whenToUse": {
  293. "type": "string",
  294. "description": "Optional guidance on when this workflow applies."
  295. },
  296. "phases": {
  297. "type": "array",
  298. "description": "Optional phase declarations matched by phase() calls.",
  299. "items": {
  300. "type": "object",
  301. "properties": {
  302. "title": {
  303. "type": "string",
  304. "description": "The phase title phase() calls match by exact string."
  305. },
  306. "detail": {
  307. "type": "string",
  308. "description": "Optional one-line description of the phase."
  309. },
  310. "provider": {
  311. "type": "string",
  312. "description": "Optional provider override this phase is expected to use."
  313. },
  314. "model": {
  315. "type": "string",
  316. "description": "Optional model override this phase is expected to use."
  317. }
  318. },
  319. "required": [
  320. "title"
  321. ]
  322. }
  323. }
  324. },
  325. "required": [
  326. "name",
  327. "description"
  328. ]
  329. },
  330. "args": {
  331. "type": "object",
  332. "description": "Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]})."
  333. }
  334. },
  335. "required": [
  336. "script",
  337. "meta"
  338. ]
  339. }
  340. },
  341. {
  342. "name": "write",
  343. "description": "Create or fully replace a UTF-8 text file.",
  344. "parameters": {
  345. "type": "object",
  346. "properties": {
  347. "file_path": {
  348. "type": "string",
  349. "description": "Path to write, resolved by the filesystem backend."
  350. },
  351. "content": {
  352. "type": "string",
  353. "description": "Full UTF-8 text content to write."
  354. },
  355. "sandbox_permissions": {
  356. "type": "string",
  357. "description": "The wider sandbox mode this file operation needs. Only valid as a one-shot retry of an operation the sandbox just denied; requires justification and user approval.",
  358. "enum": [
  359. "workspace-write",
  360. "danger-full-access"
  361. ]
  362. },
  363. "justification": {
  364. "type": "string",
  365. "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access."
  366. }
  367. },
  368. "required": [
  369. "file_path",
  370. "content"
  371. ]
  372. }
  373. }
  374. ],
  375. "changes": []
  376. }