zidane 7.2.5 → 8.0.4
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/LICENSE +21 -0
- package/README.md +34 -6
- package/dist/{acp-D-tVyUjw.js → acp-DQDhi2dj.js} +230 -77
- package/dist/acp-DQDhi2dj.js.map +1 -0
- package/dist/acp-cli.d.ts +1 -1
- package/dist/acp-cli.js +9 -66
- package/dist/acp-cli.js.map +1 -1
- package/dist/acp.d.ts +10 -590
- package/dist/acp.d.ts.map +1 -1
- package/dist/acp.js +3 -3
- package/dist/{agent-D0zZnGbt.js → agent-DSLNmBp0.js} +14401 -13214
- package/dist/agent-DSLNmBp0.js.map +1 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +3 -2
- package/dist/aliasing-lVFbm81n.js +217 -0
- package/dist/aliasing-lVFbm81n.js.map +1 -0
- package/dist/{anthropic-C2aole0G.js → anthropic-CD00LhUP.js} +1442 -1264
- package/dist/anthropic-CD00LhUP.js.map +1 -0
- package/dist/artifacts-CV2hUKnL.js.map +1 -1
- package/dist/{atomic-write-B7zr1ddF.js → atomic-write-Ijgf2Mhc.js} +13 -3
- package/dist/atomic-write-Ijgf2Mhc.js.map +1 -0
- package/dist/call-tool-dHlbGOIY.js +70 -0
- package/dist/call-tool-dHlbGOIY.js.map +1 -0
- package/dist/chat/pure.d.ts +372 -6
- package/dist/chat/pure.d.ts.map +1 -1
- package/dist/chat/pure.js +35 -244
- package/dist/chat/pure.js.map +1 -1
- package/dist/{approvals-DKaJZYlm.js → chat-JPJJ8uu5.js} +15879 -14631
- package/dist/chat-JPJJ8uu5.js.map +1 -0
- package/dist/chat.d.ts +4 -6
- package/dist/chat.js +23 -12
- package/dist/cli-shared-C-YCaglL.js +159 -0
- package/dist/cli-shared-C-YCaglL.js.map +1 -0
- package/dist/client-core-BQSyDALT.d.ts +2115 -0
- package/dist/client-core-BQSyDALT.d.ts.map +1 -0
- package/dist/codemode-worker.d.ts +1 -0
- package/dist/codemode-worker.js +155 -0
- package/dist/codemode-worker.js.map +1 -0
- package/dist/codemode.d.ts +352 -0
- package/dist/codemode.d.ts.map +1 -0
- package/dist/codemode.js +5 -0
- package/dist/connection-Dr-Js4yZ.d.ts +28 -0
- package/dist/connection-Dr-Js4yZ.d.ts.map +1 -0
- package/dist/connection-loop-gdh22LTI.js +112 -0
- package/dist/connection-loop-gdh22LTI.js.map +1 -0
- package/dist/context-segments-BHKlagL6.js +1016 -0
- package/dist/context-segments-BHKlagL6.js.map +1 -0
- package/dist/{context-transport-T_6AYIvy.js → context-transport-DSMTUsK1.js} +3 -3
- package/dist/{context-transport-T_6AYIvy.js.map → context-transport-DSMTUsK1.js.map} +1 -1
- package/dist/contexts/daytona.d.ts +19 -8
- package/dist/contexts/daytona.d.ts.map +1 -1
- package/dist/contexts/daytona.js +1 -440
- package/dist/contexts/docker.d.ts +36 -7
- package/dist/contexts/docker.d.ts.map +1 -1
- package/dist/contexts/docker.js +1 -456
- package/dist/contexts/e2b.d.ts +68 -13
- package/dist/contexts/e2b.d.ts.map +1 -1
- package/dist/contexts/e2b.js +1 -382
- package/dist/contexts/sandbox.d.ts +1 -1
- package/dist/contexts/sandbox.js +5 -0
- package/dist/contexts/sandbox.js.map +1 -1
- package/dist/{contexts-CRE9pw07.js → contexts-d7UolYot.js} +1059 -524
- package/dist/contexts-d7UolYot.js.map +1 -0
- package/dist/contexts.d.ts +3 -3
- package/dist/contexts.js +1 -1
- package/dist/cred-keys-GpBg71cP.js +105 -0
- package/dist/cred-keys-GpBg71cP.js.map +1 -0
- package/dist/{auth-BG2rVKSt.js → credentials-JttEuRON.js} +55 -206
- package/dist/credentials-JttEuRON.js.map +1 -0
- package/dist/{cursor-iojRXHF9.js → cursor-CdjaQTBW.js} +3 -3
- package/dist/{cursor-iojRXHF9.js.map → cursor-CdjaQTBW.js.map} +1 -1
- package/dist/daemon-cli.d.ts +1 -1
- package/dist/daemon-cli.js +3 -2
- package/dist/daemon-cli.js.map +1 -1
- package/dist/daytona-DG3omipZ.js +513 -0
- package/dist/daytona-DG3omipZ.js.map +1 -0
- package/dist/defaults-Cx3zvDOV.js +23 -0
- package/dist/defaults-Cx3zvDOV.js.map +1 -0
- package/dist/dispatcher-BMlu2BmZ.js +4941 -0
- package/dist/dispatcher-BMlu2BmZ.js.map +1 -0
- package/dist/docker-BZhMMJUp.js +727 -0
- package/dist/docker-BZhMMJUp.js.map +1 -0
- package/dist/e2b-CEVOdRib.js +480 -0
- package/dist/e2b-CEVOdRib.js.map +1 -0
- package/dist/edit-utils-EGosADZq.js +234 -0
- package/dist/edit-utils-EGosADZq.js.map +1 -0
- package/dist/environment-8wsKE2Ln.js +214 -0
- package/dist/environment-8wsKE2Ln.js.map +1 -0
- package/dist/eval-BNcvle_J.js +1595 -0
- package/dist/eval-BNcvle_J.js.map +1 -0
- package/dist/eval.d.ts +2 -2
- package/dist/eval.js +1 -1489
- package/dist/executor-Cx5-8yqi.js +621 -0
- package/dist/executor-Cx5-8yqi.js.map +1 -0
- package/dist/extension-authoring-DyGGmq9V.js +385 -0
- package/dist/extension-authoring-DyGGmq9V.js.map +1 -0
- package/dist/extensions.d.ts +2 -2
- package/dist/extensions.js +3 -3
- package/dist/{fetch-url-DX75gpL0.js → fetch-url-Ct2TjDWt.js} +4 -4
- package/dist/{fetch-url-DX75gpL0.js.map → fetch-url-Ct2TjDWt.js.map} +1 -1
- package/dist/{format-BF745pLL.js → format-C2NQEVUH.js} +39 -2
- package/dist/format-C2NQEVUH.js.map +1 -0
- package/dist/format-bytes-C7tfc3Zm.js +55 -0
- package/dist/format-bytes-C7tfc3Zm.js.map +1 -0
- package/dist/headless-C_rNUuYC.js +960 -0
- package/dist/headless-C_rNUuYC.js.map +1 -0
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -413
- package/dist/{history-search-C4bk1Wz_.js → history-search-CcYzF8-0.js} +7 -3
- package/dist/history-search-CcYzF8-0.js.map +1 -0
- package/dist/history-search-worker.d.ts +1 -1
- package/dist/history-search-worker.js +1 -1
- package/dist/host-D7NrI03V.js +378 -0
- package/dist/host-D7NrI03V.js.map +1 -0
- package/dist/host-signals-BcP5QKUD.js +118 -0
- package/dist/host-signals-BcP5QKUD.js.map +1 -0
- package/dist/identity-CwfO8K-t.js +26 -0
- package/dist/identity-CwfO8K-t.js.map +1 -0
- package/dist/{index-BgN1T3lk.d.ts → index-BGe1fQT7.d.ts} +10987 -9320
- package/dist/index-BGe1fQT7.d.ts.map +1 -0
- package/dist/index-BVQsIKGn.d.ts +448 -0
- package/dist/index-BVQsIKGn.d.ts.map +1 -0
- package/dist/{index-C6NEd5y_.d.ts → index-CHABJd-L.d.ts} +3386 -502
- package/dist/index-CHABJd-L.d.ts.map +1 -0
- package/dist/{index-C37_ppWv.d.ts → index-D6a7qXpg.d.ts} +2 -3
- package/dist/index-D6a7qXpg.d.ts.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +27 -23
- package/dist/{completion-core-BRo86R_L.js → inline-ghost-BVRQeGoL.js} +50 -2
- package/dist/inline-ghost-BVRQeGoL.js.map +1 -0
- package/dist/ipc/remote.d.ts +313 -0
- package/dist/ipc/remote.d.ts.map +1 -0
- package/dist/ipc/remote.js +4 -0
- package/dist/ipc.d.ts +6 -964
- package/dist/ipc.js +403 -4
- package/dist/ipc.js.map +1 -0
- package/dist/{isolation-Kfoof0MM.d.ts → isolation-D9L650W5.d.ts} +100 -15
- package/dist/isolation-D9L650W5.d.ts.map +1 -0
- package/dist/json-rpc--HXQti1E.js +350 -0
- package/dist/json-rpc--HXQti1E.js.map +1 -0
- package/dist/links-j8rED1sR.js +603 -0
- package/dist/links-j8rED1sR.js.map +1 -0
- package/dist/local-terminal-D8QThwo_.js +252 -0
- package/dist/local-terminal-D8QThwo_.js.map +1 -0
- package/dist/{logger--C1VQjwJ.js → logger-Gtqlayx8.js} +199 -173
- package/dist/logger-Gtqlayx8.js.map +1 -0
- package/dist/logs-view-CWG8aUAG.js.map +1 -1
- package/dist/{mcp-CgNd-f3F.js → mcp-_wecH9Qe.js} +608 -562
- package/dist/mcp-_wecH9Qe.js.map +1 -0
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +2 -2
- package/dist/media-sniff-UKijEaiQ.js.map +1 -1
- package/dist/{messages-2jcOA_5R.js → messages-BqiwcD2Q.js} +1017 -1014
- package/dist/messages-BqiwcD2Q.js.map +1 -0
- package/dist/{oauth-DxHO17JE.js → oauth-Px_pBB9W.js} +5 -5
- package/dist/{oauth-DxHO17JE.js.map → oauth-Px_pBB9W.js.map} +1 -1
- package/dist/{openai-compat-Dy56weK8.js → openai-compat-CFrpH7uq.js} +432 -589
- package/dist/openai-compat-CFrpH7uq.js.map +1 -0
- package/dist/orchestration-BCGmB8Ps.js +511 -0
- package/dist/orchestration-BCGmB8Ps.js.map +1 -0
- package/dist/output/stream-json.d.ts +1 -2
- package/dist/output/stream-json.d.ts.map +1 -1
- package/dist/output/stream-json.js +1 -1
- package/dist/output/terminal.d.ts +1 -2
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +13 -7
- package/dist/output/terminal.js.map +1 -1
- package/dist/{plugins-gbI7SBA6.js → plugins-DS7mahzZ.js} +20 -101
- package/dist/plugins-DS7mahzZ.js.map +1 -0
- package/dist/plugins.d.ts +1 -1
- package/dist/plugins.js +1 -2
- package/dist/prelude-Cxo4t74B.js +517 -0
- package/dist/prelude-Cxo4t74B.js.map +1 -0
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -2
- package/dist/project-root-B8zADr4o.js +167 -0
- package/dist/project-root-B8zADr4o.js.map +1 -0
- package/dist/project-user-paths-BSgtrRxl.js +58 -0
- package/dist/project-user-paths-BSgtrRxl.js.map +1 -0
- package/dist/{prompts-Pqc3JdW_.d.ts → prompts-DYcvqShf.d.ts} +14 -11
- package/dist/prompts-DYcvqShf.d.ts.map +1 -0
- package/dist/protocol-DnhqqSmE.js +13 -0
- package/dist/protocol-DnhqqSmE.js.map +1 -0
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +1 -2
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/arcee.js +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/baseten.js +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/cerebras.js +3 -2
- package/dist/providers/cerebras.js.map +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/local.js +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai-compat.js +1 -2
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +15 -12
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +3 -2
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +3 -3
- package/dist/{providers-BVhnFyiY.js → providers-XUR7F4Hi.js} +4 -4
- package/dist/{providers-BVhnFyiY.js.map → providers-XUR7F4Hi.js.map} +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/registry-D6ShBWJU.js +5234 -0
- package/dist/registry-D6ShBWJU.js.map +1 -0
- package/dist/remote-hosts-BtA_9ZGp.js +97 -0
- package/dist/remote-hosts-BtA_9ZGp.js.map +1 -0
- package/dist/restate.d.ts +2 -3
- package/dist/restate.d.ts.map +1 -1
- package/dist/restate.js +631 -572
- package/dist/restate.js.map +1 -1
- package/dist/run-summary-CklLiZ4y.js +288 -0
- package/dist/run-summary-CklLiZ4y.js.map +1 -0
- package/dist/{sandbox-BH0WQkXn.d.ts → sandbox-C5dR5DwQ.d.ts} +6 -3
- package/dist/sandbox-C5dR5DwQ.d.ts.map +1 -0
- package/dist/session/sqlite.d.ts +1 -2
- package/dist/session/sqlite.d.ts.map +1 -1
- package/dist/session/sqlite.js +1 -616
- package/dist/session-factory-BUGY5P40.js +1576 -0
- package/dist/session-factory-BUGY5P40.js.map +1 -0
- package/dist/{session-BqRP1hS7.js → session-xh9JXu6i.js} +94 -52
- package/dist/session-xh9JXu6i.js.map +1 -0
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/settings-keys-Ckf29NeM.js +677 -0
- package/dist/settings-keys-Ckf29NeM.js.map +1 -0
- package/dist/shell-path-Dqaoow2J.js +412 -0
- package/dist/shell-path-Dqaoow2J.js.map +1 -0
- package/dist/{skills-BC3dodWp.js → skills-DKqZJm4X.js} +430 -470
- package/dist/skills-DKqZJm4X.js.map +1 -0
- package/dist/skills.d.ts +2 -2
- package/dist/skills.js +1 -2
- package/dist/source-mPExaUm8.js +381 -0
- package/dist/source-mPExaUm8.js.map +1 -0
- package/dist/sqlite-DV1DQzN2.js +698 -0
- package/dist/sqlite-DV1DQzN2.js.map +1 -0
- package/dist/{src-CkNQKFKr.js → src-BRMYRJib.js} +903 -1121
- package/dist/src-BRMYRJib.js.map +1 -0
- package/dist/{stdio-DPpBDPx5.js → stdio-C6YyoW3I.js} +4 -4
- package/dist/{stdio-DPpBDPx5.js.map → stdio-C6YyoW3I.js.map} +1 -1
- package/dist/{stdio-loader-Bbx19dMZ.js → stdio-loader-C830Vg-Z.js} +4 -4
- package/dist/{stdio-loader-Bbx19dMZ.js.map → stdio-loader-C830Vg-Z.js.map} +1 -1
- package/dist/system-prompt-MNVHatSD.d.ts.map +1 -1
- package/dist/timeout-DEaqslLO.d.ts.map +1 -1
- package/dist/todo-edits-Dn251YUP.js +1790 -0
- package/dist/todo-edits-Dn251YUP.js.map +1 -0
- package/dist/{turn-operations-DrbJlpq9.js → tool-formatters-IQFDrdrs.js} +1456 -2120
- package/dist/tool-formatters-IQFDrdrs.js.map +1 -0
- package/dist/tool-state-Dku6YqAB.js +989 -0
- package/dist/tool-state-Dku6YqAB.js.map +1 -0
- package/dist/tools/fetch-url.d.ts +1 -2
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +1 -2
- package/dist/tools/prompts.d.ts +1 -1
- package/dist/tools/prompts.js +7 -7
- package/dist/tools/prompts.js.map +1 -1
- package/dist/tools/web-search.d.ts +1 -2
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +2 -2
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools-_DnT3AGM.js +578 -0
- package/dist/tools-_DnT3AGM.js.map +1 -0
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +4 -2
- package/dist/tui.d.ts +534 -517
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +34933 -27243
- package/dist/tui.js.map +1 -1
- package/dist/turn-operations-B8sokwi5.js +333 -0
- package/dist/turn-operations-B8sokwi5.js.map +1 -0
- package/dist/turn-operations-DQX5ZZni.d.ts +3089 -0
- package/dist/turn-operations-DQX5ZZni.d.ts.map +1 -0
- package/dist/types-C7ZFOztE.d.ts +132 -0
- package/dist/types-C7ZFOztE.d.ts.map +1 -0
- package/dist/types-CH5XpIHw.js +114 -0
- package/dist/types-CH5XpIHw.js.map +1 -0
- package/dist/{types-CWgENVLY.js → types-Cu0ZGDu9.js} +10 -6
- package/dist/types-Cu0ZGDu9.js.map +1 -0
- package/dist/types-IqegbJEE.d.ts +624 -0
- package/dist/types-IqegbJEE.d.ts.map +1 -0
- package/dist/types.d.ts +4 -4
- package/dist/types.js +1 -1
- package/dist/url-D8HCl65b.js +1259 -0
- package/dist/url-D8HCl65b.js.map +1 -0
- package/dist/wasm-BVT-j5cl.js +33 -0
- package/dist/wasm-BVT-j5cl.js.map +1 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js +355 -0
- package/dist/workspace-exec-stream-SV2R9d5S.js.map +1 -0
- package/dist/ws-CIHMvlSh.js +952 -0
- package/dist/ws-CIHMvlSh.js.map +1 -0
- package/dist/ws-client-N7NxzvQp.js +230 -0
- package/dist/ws-client-N7NxzvQp.js.map +1 -0
- package/dist/{xai-CazjStOK.js → xai-CvJTeLrI.js} +165 -5
- package/dist/xai-CvJTeLrI.js.map +1 -0
- package/dist/xdg-zweed0-t.js +117 -0
- package/dist/xdg-zweed0-t.js.map +1 -0
- package/docs/ACP.md +52 -0
- package/docs/ARCHITECTURE.md +103 -6
- package/docs/ARTIFACTS.md +8 -4
- package/docs/CHAT.md +165 -14
- package/docs/EXECUTION_CONTEXT.md +8 -0
- package/docs/EXTENSIONS.md +123 -2
- package/docs/HEADLESS.md +2 -0
- package/docs/IPC.md +775 -64
- package/docs/MACHINES.md +456 -0
- package/docs/PANELS.md +3 -0
- package/docs/README.md +4 -0
- package/docs/RESTATE.md +3 -2
- package/docs/RUN_IN_BACKGROUND.md +10 -2
- package/docs/SERVER.md +1085 -0
- package/docs/SKILL.md +6 -1
- package/docs/TERMINAL.md +75 -0
- package/docs/TUI.md +65 -14
- package/package.json +58 -26
- package/scripts/eval.ts +4 -0
- package/dist/acp-D-tVyUjw.js.map +0 -1
- package/dist/agent-D0zZnGbt.js.map +0 -1
- package/dist/anthropic-C2aole0G.js.map +0 -1
- package/dist/approvals-DKaJZYlm.js.map +0 -1
- package/dist/atomic-write-B7zr1ddF.js.map +0 -1
- package/dist/auth-BG2rVKSt.js.map +0 -1
- package/dist/completion-core-BRo86R_L.js.map +0 -1
- package/dist/contexts/daytona.js.map +0 -1
- package/dist/contexts/docker.js.map +0 -1
- package/dist/contexts/e2b.js.map +0 -1
- package/dist/contexts-CRE9pw07.js.map +0 -1
- package/dist/eval.js.map +0 -1
- package/dist/format-BF745pLL.js.map +0 -1
- package/dist/glob-DluQFSw1.js +0 -270
- package/dist/glob-DluQFSw1.js.map +0 -1
- package/dist/headless.js.map +0 -1
- package/dist/history-search-C4bk1Wz_.js.map +0 -1
- package/dist/index-BgN1T3lk.d.ts.map +0 -1
- package/dist/index-C37_ppWv.d.ts.map +0 -1
- package/dist/index-C6NEd5y_.d.ts.map +0 -1
- package/dist/ipc-BKVIIOqH.js +0 -331
- package/dist/ipc-BKVIIOqH.js.map +0 -1
- package/dist/ipc.d.ts.map +0 -1
- package/dist/isolation-Kfoof0MM.d.ts.map +0 -1
- package/dist/json-rpc-rSWMUh9b.js +0 -192
- package/dist/json-rpc-rSWMUh9b.js.map +0 -1
- package/dist/logger--C1VQjwJ.js.map +0 -1
- package/dist/mcp-CgNd-f3F.js.map +0 -1
- package/dist/messages-2jcOA_5R.js.map +0 -1
- package/dist/openai-compat-Dy56weK8.js.map +0 -1
- package/dist/output-cap-C9zukcCj.js +0 -100
- package/dist/output-cap-C9zukcCj.js.map +0 -1
- package/dist/panels-B6gRk4bf.js +0 -789
- package/dist/panels-B6gRk4bf.js.map +0 -1
- package/dist/plugins-gbI7SBA6.js.map +0 -1
- package/dist/prompts-Pqc3JdW_.d.ts.map +0 -1
- package/dist/run-summary-BU_NgwUT.js +0 -269
- package/dist/run-summary-BU_NgwUT.js.map +0 -1
- package/dist/sandbox-BH0WQkXn.d.ts.map +0 -1
- package/dist/session/sqlite.js.map +0 -1
- package/dist/session-BqRP1hS7.js.map +0 -1
- package/dist/shell-path-DfdXrGg9.js +0 -1549
- package/dist/shell-path-DfdXrGg9.js.map +0 -1
- package/dist/skills-BC3dodWp.js.map +0 -1
- package/dist/src-CkNQKFKr.js.map +0 -1
- package/dist/todo-edits-UOwgxGKu.js +0 -528
- package/dist/todo-edits-UOwgxGKu.js.map +0 -1
- package/dist/tool-formatters-DoRLnfuD.d.ts +0 -759
- package/dist/tool-formatters-DoRLnfuD.d.ts.map +0 -1
- package/dist/transcript-anchors-BeudMbXx.d.ts +0 -1762
- package/dist/transcript-anchors-BeudMbXx.d.ts.map +0 -1
- package/dist/turn-operations-C8bMBDl_.d.ts +0 -1258
- package/dist/turn-operations-C8bMBDl_.d.ts.map +0 -1
- package/dist/turn-operations-DrbJlpq9.js.map +0 -1
- package/dist/types-CWgENVLY.js.map +0 -1
- package/dist/xai-CazjStOK.js.map +0 -1
|
@@ -0,0 +1,960 @@
|
|
|
1
|
+
import { At as basic_default, Ft as isSpawnTool, t as createAgent } from "./agent-DSLNmBp0.js";
|
|
2
|
+
import { a as documentBlockMarker, d as toolResultToText, r as assertResolvedMediaBlock, s as isWireTurn } from "./types-Cu0ZGDu9.js";
|
|
3
|
+
import { t as audioFormatFromMediaType } from "./media-sniff-UKijEaiQ.js";
|
|
4
|
+
import { O as parseFrontmatter } from "./skills-DKqZJm4X.js";
|
|
5
|
+
import { t as findGitRoot } from "./project-root-B8zADr4o.js";
|
|
6
|
+
import { t as projectUserPaths } from "./project-user-paths-BSgtrRxl.js";
|
|
7
|
+
import { _ as ensureToolResultPairing, u as toAnthropic } from "./messages-BqiwcD2Q.js";
|
|
8
|
+
import { d as createMemoryStore, t as createSession } from "./session-xh9JXu6i.js";
|
|
9
|
+
import { t as createProcessContext } from "./contexts-d7UolYot.js";
|
|
10
|
+
import { n as DEFAULT_MEDIA_BUDGET, t as DEFAULT_MAX_IMAGE_EDGE } from "./defaults-Cx3zvDOV.js";
|
|
11
|
+
import { t as createRunSummaryCollector } from "./run-summary-CklLiZ4y.js";
|
|
12
|
+
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
13
|
+
import { join, resolve } from "node:path";
|
|
14
|
+
import { homedir } from "node:os";
|
|
15
|
+
//#region src/markdown-defs/model-aliases.ts
|
|
16
|
+
/**
|
|
17
|
+
* Claude Code's agent `model:` aliases. Bump alongside `../anthropic-models.ts`
|
|
18
|
+
* when the Anthropic lineup changes.
|
|
19
|
+
*/
|
|
20
|
+
const CLAUDE_MODEL_ALIASES = {
|
|
21
|
+
haiku: "claude-haiku-4-5-20251001",
|
|
22
|
+
sonnet: "claude-sonnet-5-5",
|
|
23
|
+
opus: "claude-opus-5-5",
|
|
24
|
+
fable: "claude-fable-5-1"
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Without a catalog, spawn sends a raw id to the PARENT's provider, so a
|
|
28
|
+
* Claude id under an OpenAI parent would fail mid-run. Unresolvable aliases
|
|
29
|
+
* therefore inherit instead of failing the spawn.
|
|
30
|
+
*/
|
|
31
|
+
function resolveModelAlias(value, ctx, path) {
|
|
32
|
+
const raw = value?.trim();
|
|
33
|
+
if (!raw || raw.toLowerCase() === "inherit") return {};
|
|
34
|
+
const key = raw.toLowerCase();
|
|
35
|
+
if (!Object.hasOwn(CLAUDE_MODEL_ALIASES, key)) return { model: raw };
|
|
36
|
+
const target = CLAUDE_MODEL_ALIASES[key];
|
|
37
|
+
if (ctx.parentProvider === "anthropic" || ctx.catalogIds?.has(target)) return { model: target };
|
|
38
|
+
return { diagnostic: {
|
|
39
|
+
path,
|
|
40
|
+
kind: "agent",
|
|
41
|
+
message: `model alias "${raw}" needs an Anthropic parent; inheriting the parent model`
|
|
42
|
+
} };
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/markdown-defs/tool-map.ts
|
|
46
|
+
/** Claude Code tool names → zidane `spec.name`. */
|
|
47
|
+
const CLAUDE_TOOL_MAP = {
|
|
48
|
+
Read: "read_file",
|
|
49
|
+
Write: "write_file",
|
|
50
|
+
Edit: "edit",
|
|
51
|
+
MultiEdit: "multi_edit",
|
|
52
|
+
Bash: "shell",
|
|
53
|
+
Grep: "grep",
|
|
54
|
+
Glob: "glob",
|
|
55
|
+
LS: "list_files",
|
|
56
|
+
WebFetch: "fetch_url",
|
|
57
|
+
WebSearch: "web_search",
|
|
58
|
+
Task: "spawn",
|
|
59
|
+
Agent: "spawn"
|
|
60
|
+
};
|
|
61
|
+
const NATIVE_TOOLS = new Set(Object.values(CLAUDE_TOOL_MAP));
|
|
62
|
+
const PATTERNED = /^([A-Z]\w*)\(.*\)$/;
|
|
63
|
+
/**
|
|
64
|
+
* Translate an agent file's `tools:` list. Patterns (`Bash(git:*)`) are not
|
|
65
|
+
* enforced by spawn's allowlist, so they collapse to the bare tool with a
|
|
66
|
+
* diagnostic. Unknown names are dropped loudly instead of narrowing nothing.
|
|
67
|
+
*/
|
|
68
|
+
function mapClaudeTools(names, path) {
|
|
69
|
+
const tools = /* @__PURE__ */ new Set();
|
|
70
|
+
const diagnostics = [];
|
|
71
|
+
for (const raw of names) {
|
|
72
|
+
const name = raw.trim();
|
|
73
|
+
if (!name) continue;
|
|
74
|
+
if (NATIVE_TOOLS.has(name) || name.startsWith("mcp__")) {
|
|
75
|
+
tools.add(name);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const patterned = PATTERNED.exec(name);
|
|
79
|
+
const base = patterned ? patterned[1] : name;
|
|
80
|
+
const mapped = Object.hasOwn(CLAUDE_TOOL_MAP, base) ? CLAUDE_TOOL_MAP[base] : void 0;
|
|
81
|
+
if (!mapped) {
|
|
82
|
+
diagnostics.push({
|
|
83
|
+
path,
|
|
84
|
+
kind: "agent",
|
|
85
|
+
message: `unknown tool "${name}" dropped`
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (patterned) diagnostics.push({
|
|
90
|
+
path,
|
|
91
|
+
kind: "agent",
|
|
92
|
+
message: `tool pattern "${name}" is not enforced; granted ${mapped} unrestricted`
|
|
93
|
+
});
|
|
94
|
+
tools.add(mapped);
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
tools: [...tools],
|
|
98
|
+
diagnostics
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/markdown-defs/agents.ts
|
|
103
|
+
const IGNORED_KEYS$1 = [
|
|
104
|
+
"color",
|
|
105
|
+
"isolation",
|
|
106
|
+
"memory",
|
|
107
|
+
"hooks"
|
|
108
|
+
];
|
|
109
|
+
/** Keys that narrow a child's tools; a duplicate of any of them drops the agent. */
|
|
110
|
+
const RESTRICTION_KEYS = [
|
|
111
|
+
"tools",
|
|
112
|
+
"disallowedTools",
|
|
113
|
+
"readonly",
|
|
114
|
+
"permissionMode"
|
|
115
|
+
];
|
|
116
|
+
/**
|
|
117
|
+
* `tools:` arrives as a YAML list, `[a, b]`, `a, b`, or `a b`. Comma input
|
|
118
|
+
* splits on commas only; otherwise it splits on whitespace outside parens, so
|
|
119
|
+
* `Bash(git log:*)` survives intact either way.
|
|
120
|
+
*/
|
|
121
|
+
function toStringList(value) {
|
|
122
|
+
if (value === void 0 || value === null) return void 0;
|
|
123
|
+
if (Array.isArray(value)) return value.filter((v) => typeof v === "string").map((v) => v.trim()).filter(Boolean);
|
|
124
|
+
if (typeof value !== "string") return void 0;
|
|
125
|
+
const inner = value.trim().replace(/^\[(.*)\]$/, "$1");
|
|
126
|
+
return (inner.includes(",") ? inner.split(",") : splitOutsideParens(inner)).map((p) => p.trim()).filter(Boolean);
|
|
127
|
+
}
|
|
128
|
+
function splitOutsideParens(input) {
|
|
129
|
+
const parts = [];
|
|
130
|
+
let depth = 0;
|
|
131
|
+
let current = "";
|
|
132
|
+
for (const ch of input) {
|
|
133
|
+
if (ch === "(") depth++;
|
|
134
|
+
else if (ch === ")") depth = Math.max(0, depth - 1);
|
|
135
|
+
if (depth === 0 && /\s/.test(ch)) {
|
|
136
|
+
parts.push(current);
|
|
137
|
+
current = "";
|
|
138
|
+
} else current += ch;
|
|
139
|
+
}
|
|
140
|
+
parts.push(current);
|
|
141
|
+
return parts;
|
|
142
|
+
}
|
|
143
|
+
/** `true`/`false` as a boolean or the strings `'true'`/`'false'`; `undefined` for anything else. */
|
|
144
|
+
function toBool(value) {
|
|
145
|
+
if (typeof value === "boolean") return value;
|
|
146
|
+
if (typeof value === "string") {
|
|
147
|
+
const v = value.trim().toLowerCase();
|
|
148
|
+
if (v === "true") return true;
|
|
149
|
+
if (v === "false") return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function isListShaped(value) {
|
|
153
|
+
return typeof value === "string" || Array.isArray(value);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* `explicitReadonlyFalse` reports a file that wrote `readonly: false`, so the
|
|
157
|
+
* loader can tell "unset" from "opted out" when a file overrides a builtin.
|
|
158
|
+
*/
|
|
159
|
+
function parseAgentFile(file, content, modelContext) {
|
|
160
|
+
const diagnostics = [];
|
|
161
|
+
const note = (message) => diagnostics.push({
|
|
162
|
+
path: file.path,
|
|
163
|
+
kind: "agent",
|
|
164
|
+
message
|
|
165
|
+
});
|
|
166
|
+
const parsed = parseFrontmatter(content);
|
|
167
|
+
for (const d of parsed.diagnostics) note(d.message);
|
|
168
|
+
const fm = parsed.frontmatter;
|
|
169
|
+
const name = typeof fm.name === "string" && fm.name.trim() ? fm.name.trim() : file.name;
|
|
170
|
+
if (!parsed.body) {
|
|
171
|
+
note("empty agent body; skipped");
|
|
172
|
+
return { diagnostics };
|
|
173
|
+
}
|
|
174
|
+
if (typeof fm.description !== "string" || !fm.description.trim()) {
|
|
175
|
+
note("missing description; skipped");
|
|
176
|
+
return { diagnostics };
|
|
177
|
+
}
|
|
178
|
+
const def = {
|
|
179
|
+
system: parsed.body,
|
|
180
|
+
description: fm.description.trim()
|
|
181
|
+
};
|
|
182
|
+
const duplicated = RESTRICTION_KEYS.filter((key) => parsed.diagnostics.some((d) => d.code === "duplicate-key" && d.field === key));
|
|
183
|
+
if (duplicated.length > 0) {
|
|
184
|
+
note(`duplicate restriction keys: ${duplicated.join(", ")}; skipped`);
|
|
185
|
+
return { diagnostics };
|
|
186
|
+
}
|
|
187
|
+
let explicitReadonlyFalse = false;
|
|
188
|
+
if (fm.readonly !== void 0 && fm.readonly !== null) {
|
|
189
|
+
const ro = toBool(fm.readonly);
|
|
190
|
+
if (ro === void 0) {
|
|
191
|
+
note("unreadable readonly value; skipped");
|
|
192
|
+
return { diagnostics };
|
|
193
|
+
}
|
|
194
|
+
if (ro) def.readonly = true;
|
|
195
|
+
else explicitReadonlyFalse = true;
|
|
196
|
+
}
|
|
197
|
+
if (fm.tools !== void 0 && fm.tools !== null && !isListShaped(fm.tools)) {
|
|
198
|
+
note("unreadable tools value; skipped");
|
|
199
|
+
return { diagnostics };
|
|
200
|
+
}
|
|
201
|
+
if (fm.disallowedTools !== void 0 && fm.disallowedTools !== null && !isListShaped(fm.disallowedTools)) {
|
|
202
|
+
note("unreadable disallowedTools value; skipped");
|
|
203
|
+
return { diagnostics };
|
|
204
|
+
}
|
|
205
|
+
const rawTools = toStringList(fm.tools);
|
|
206
|
+
if (rawTools !== void 0) {
|
|
207
|
+
if (rawTools.length === 0) {
|
|
208
|
+
note("empty tools list; skipped (an empty list would inherit every tool)");
|
|
209
|
+
return { diagnostics };
|
|
210
|
+
}
|
|
211
|
+
const mapped = mapClaudeTools(rawTools, file.path);
|
|
212
|
+
diagnostics.push(...mapped.diagnostics);
|
|
213
|
+
if (mapped.tools.length === 0) {
|
|
214
|
+
note("no usable tools after mapping; skipped");
|
|
215
|
+
return { diagnostics };
|
|
216
|
+
}
|
|
217
|
+
def.tools = mapped.tools;
|
|
218
|
+
}
|
|
219
|
+
const rawDisallowed = toStringList(fm.disallowedTools);
|
|
220
|
+
if (rawDisallowed !== void 0) {
|
|
221
|
+
if (rawDisallowed.length === 0) {
|
|
222
|
+
note("empty disallowedTools list; skipped");
|
|
223
|
+
return { diagnostics };
|
|
224
|
+
}
|
|
225
|
+
const mapped = mapClaudeTools(rawDisallowed, file.path);
|
|
226
|
+
diagnostics.push(...mapped.diagnostics);
|
|
227
|
+
const blocked = new Set(mapped.tools);
|
|
228
|
+
if (def.tools) def.tools = def.tools.filter((t) => !blocked.has(t));
|
|
229
|
+
else {
|
|
230
|
+
note("disallowedTools without tools restricts to native tools; MCP and extension tools are excluded");
|
|
231
|
+
def.tools = [...new Set(Object.values(CLAUDE_TOOL_MAP))].filter((t) => !blocked.has(t));
|
|
232
|
+
}
|
|
233
|
+
if (def.tools.length === 0) {
|
|
234
|
+
note("no tools left after disallowedTools; skipped");
|
|
235
|
+
return { diagnostics };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
const model = resolveModelAlias(typeof fm.model === "string" ? fm.model : void 0, modelContext, file.path);
|
|
239
|
+
if (model.diagnostic) diagnostics.push(model.diagnostic);
|
|
240
|
+
if (model.model) def.model = model.model;
|
|
241
|
+
const permissionMode = typeof fm.permissionMode === "string" ? fm.permissionMode.trim() : void 0;
|
|
242
|
+
if (permissionMode === "plan") def.readonly = true;
|
|
243
|
+
const ignored = IGNORED_KEYS$1.filter((key) => fm[key] !== void 0);
|
|
244
|
+
if (fm.permissionMode !== void 0 && permissionMode !== "plan") ignored.push("permissionMode");
|
|
245
|
+
if (ignored.length > 0) note(`ignored frontmatter keys: ${ignored.join(", ")}`);
|
|
246
|
+
return {
|
|
247
|
+
entry: [name, def],
|
|
248
|
+
diagnostics,
|
|
249
|
+
explicitReadonlyFalse
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region src/markdown-defs/builtin-agents.ts
|
|
254
|
+
/**
|
|
255
|
+
* Claude-trained models emit `subagent_type: 'Explore'` / `'Plan'`. Shipping
|
|
256
|
+
* both gives those calls a target. No `model`: the `subagentModels` setting
|
|
257
|
+
* or the parent model applies. A file agent with the same name overrides.
|
|
258
|
+
*/
|
|
259
|
+
const BUILTIN_SUBAGENTS = {
|
|
260
|
+
Explore: {
|
|
261
|
+
readonly: true,
|
|
262
|
+
description: "Read-only codebase search. Use for broad fan-out searches; returns conclusions, not file dumps.",
|
|
263
|
+
system: "You are a read-only search agent. Search with the available read-only tools, read only the excerpts you need, and report findings concisely with file:line references. Do not paste whole files."
|
|
264
|
+
},
|
|
265
|
+
Plan: {
|
|
266
|
+
readonly: true,
|
|
267
|
+
description: "Read-only planning. Returns a step-by-step implementation plan with the critical files.",
|
|
268
|
+
system: "You are a read-only planning agent. Explore the code you need, then return a numbered implementation plan: the files to change, what changes in each, and the risks. Do not edit files."
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/markdown-defs/commands.ts
|
|
273
|
+
const TOKEN = /\\\$|\$ARGUMENTS|\$([1-9])(?!\d)/g;
|
|
274
|
+
const IGNORED_KEYS = ["model", "allowed-tools"];
|
|
275
|
+
const DESCRIPTION_MAX = 120;
|
|
276
|
+
/**
|
|
277
|
+
* Claude Code command templating. Replacers are functions so `$&` / `$1`
|
|
278
|
+
* typed by the user land verbatim instead of being re-expanded by
|
|
279
|
+
* `String.replace`'s replacement-pattern syntax.
|
|
280
|
+
*/
|
|
281
|
+
function expandCommandTemplate(body, args, argv) {
|
|
282
|
+
let hasPlaceholder = false;
|
|
283
|
+
const out = body.replace(TOKEN, (match, n) => {
|
|
284
|
+
if (match === "\\$") return "$";
|
|
285
|
+
hasPlaceholder = true;
|
|
286
|
+
return n ? argv[Number(n) - 1] ?? "" : args;
|
|
287
|
+
});
|
|
288
|
+
if (!hasPlaceholder) return args.trim() ? `${out}\n\n${args}` : out;
|
|
289
|
+
return out;
|
|
290
|
+
}
|
|
291
|
+
function parseCommandFile(file, content) {
|
|
292
|
+
const diagnostics = [];
|
|
293
|
+
const note = (message) => diagnostics.push({
|
|
294
|
+
path: file.path,
|
|
295
|
+
kind: "command",
|
|
296
|
+
message
|
|
297
|
+
});
|
|
298
|
+
const parsed = parseFrontmatter(content);
|
|
299
|
+
for (const d of parsed.diagnostics) note(d.message);
|
|
300
|
+
if (!file.name || /\s/.test(file.name) || file.name.startsWith("/")) {
|
|
301
|
+
note(`invalid command name "${file.name}"; skipped`);
|
|
302
|
+
return { diagnostics };
|
|
303
|
+
}
|
|
304
|
+
const body = parsed.body;
|
|
305
|
+
if (!body) {
|
|
306
|
+
note("empty command body; skipped");
|
|
307
|
+
return { diagnostics };
|
|
308
|
+
}
|
|
309
|
+
for (const key of IGNORED_KEYS) if (parsed.frontmatter[key] !== void 0) note(`frontmatter "${key}" is ignored for commands`);
|
|
310
|
+
const fm = parsed.frontmatter;
|
|
311
|
+
const firstLine = body.split("\n").find((line) => line.trim())?.trim().replace(/^#+\s*/, "") || file.name;
|
|
312
|
+
let description = typeof fm.description === "string" && fm.description.trim() ? fm.description.trim() : firstLine.slice(0, DESCRIPTION_MAX);
|
|
313
|
+
if (typeof fm["argument-hint"] === "string" && fm["argument-hint"].trim()) description = `${description} (args: ${fm["argument-hint"].trim()})`;
|
|
314
|
+
return {
|
|
315
|
+
command: {
|
|
316
|
+
name: file.name,
|
|
317
|
+
description,
|
|
318
|
+
run: async (ctx) => {
|
|
319
|
+
await ctx.runAgent(expandCommandTemplate(body, ctx.args, ctx.argv));
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
diagnostics
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
//#endregion
|
|
326
|
+
//#region src/markdown-defs/roots.ts
|
|
327
|
+
/**
|
|
328
|
+
* Claude Code's markdown command / agent dirs, project first. Claude only:
|
|
329
|
+
* Codex and pi have no equivalent format. Project root is the git root, as
|
|
330
|
+
* for the other foreign configs.
|
|
331
|
+
*/
|
|
332
|
+
function foreignMarkdownScanPaths(kind, opts = {}) {
|
|
333
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
334
|
+
const projectRoot = findGitRoot(cwd) ?? cwd;
|
|
335
|
+
const home = opts.home ?? homedir();
|
|
336
|
+
return [{
|
|
337
|
+
path: resolve(projectRoot, `.claude/${kind}`),
|
|
338
|
+
source: "project"
|
|
339
|
+
}, {
|
|
340
|
+
path: resolve(home, `.claude/${kind}`),
|
|
341
|
+
source: "user"
|
|
342
|
+
}];
|
|
343
|
+
}
|
|
344
|
+
/** Native project, native user, then (opt-in) foreign project, foreign user. Same order as skills. */
|
|
345
|
+
function markdownDefRoots(opts) {
|
|
346
|
+
const native = projectUserPaths({
|
|
347
|
+
subPath: opts.kind,
|
|
348
|
+
cwd: opts.cwd,
|
|
349
|
+
home: opts.home,
|
|
350
|
+
prefix: opts.prefix
|
|
351
|
+
}).map((p) => ({
|
|
352
|
+
path: p.path,
|
|
353
|
+
source: p.source,
|
|
354
|
+
foreign: false
|
|
355
|
+
}));
|
|
356
|
+
const foreign = opts.includeForeign ? foreignMarkdownScanPaths(opts.kind, {
|
|
357
|
+
cwd: opts.cwd,
|
|
358
|
+
home: opts.home
|
|
359
|
+
}).map((p) => ({
|
|
360
|
+
path: p.path,
|
|
361
|
+
source: p.source,
|
|
362
|
+
foreign: true
|
|
363
|
+
})) : [];
|
|
364
|
+
const all = [...native, ...foreign];
|
|
365
|
+
return opts.includeProject === false ? all.filter((r) => r.source !== "project") : all;
|
|
366
|
+
}
|
|
367
|
+
//#endregion
|
|
368
|
+
//#region src/markdown-defs/scan.ts
|
|
369
|
+
const MAX_DEPTH = 3;
|
|
370
|
+
/** Dot entries (dirs and dotfiles) are skipped separately. Not the skills skip set: `build/` and `dist/` are legitimate command namespaces. */
|
|
371
|
+
const SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules"]);
|
|
372
|
+
/**
|
|
373
|
+
* Every `*.md` under each root, in root order. No dedupe here: agent files
|
|
374
|
+
* can rename themselves via frontmatter, so first-wins runs after parsing.
|
|
375
|
+
*/
|
|
376
|
+
function listMarkdownDefFiles(roots) {
|
|
377
|
+
const files = [];
|
|
378
|
+
for (const root of roots) walk(root, root.path, [], files);
|
|
379
|
+
return files;
|
|
380
|
+
}
|
|
381
|
+
function walk(root, dir, segments, out) {
|
|
382
|
+
let entries;
|
|
383
|
+
try {
|
|
384
|
+
entries = readdirSync(dir).sort();
|
|
385
|
+
} catch {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
for (const entry of entries) {
|
|
389
|
+
if (entry.startsWith(".") || SKIP_DIRS.has(entry)) continue;
|
|
390
|
+
const path = join(dir, entry);
|
|
391
|
+
let isDir;
|
|
392
|
+
try {
|
|
393
|
+
isDir = statSync(path).isDirectory();
|
|
394
|
+
} catch {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
if (isDir) {
|
|
398
|
+
if (segments.length < MAX_DEPTH) walk(root, path, [...segments, entry], out);
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
if (!entry.endsWith(".md")) continue;
|
|
402
|
+
const name = [...segments, entry.slice(0, -3)].join(":").toLowerCase();
|
|
403
|
+
out.push({
|
|
404
|
+
path,
|
|
405
|
+
name,
|
|
406
|
+
source: root.source,
|
|
407
|
+
foreign: root.foreign
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region src/markdown-defs/index.ts
|
|
413
|
+
/** Names that would collide with `Object.prototype` keys in a plain registry. */
|
|
414
|
+
const RESERVED_NAMES = /* @__PURE__ */ new Set([
|
|
415
|
+
"__proto__",
|
|
416
|
+
"constructor",
|
|
417
|
+
"prototype"
|
|
418
|
+
]);
|
|
419
|
+
function filesFor(kind, opts) {
|
|
420
|
+
return listMarkdownDefFiles(markdownDefRoots({
|
|
421
|
+
kind,
|
|
422
|
+
...opts
|
|
423
|
+
}));
|
|
424
|
+
}
|
|
425
|
+
function read(path) {
|
|
426
|
+
try {
|
|
427
|
+
return readFileSync(path, "utf8");
|
|
428
|
+
} catch {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/** Markdown slash commands, first-wins by name in root order. Never throws. */
|
|
433
|
+
function loadMarkdownCommands(opts) {
|
|
434
|
+
const commands = [];
|
|
435
|
+
const diagnostics = [];
|
|
436
|
+
const winners = /* @__PURE__ */ new Map();
|
|
437
|
+
for (const file of filesFor("commands", opts)) {
|
|
438
|
+
const content = read(file.path);
|
|
439
|
+
if (content === void 0) continue;
|
|
440
|
+
const parsed = parseCommandFile(file, content);
|
|
441
|
+
diagnostics.push(...parsed.diagnostics);
|
|
442
|
+
if (!parsed.command) continue;
|
|
443
|
+
const key = parsed.command.name.toLowerCase();
|
|
444
|
+
if (RESERVED_NAMES.has(key)) {
|
|
445
|
+
diagnostics.push({
|
|
446
|
+
path: file.path,
|
|
447
|
+
kind: "command",
|
|
448
|
+
message: "reserved command name"
|
|
449
|
+
});
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
if (opts.isSkillName?.(key)) {
|
|
453
|
+
diagnostics.push({
|
|
454
|
+
path: file.path,
|
|
455
|
+
kind: "command",
|
|
456
|
+
message: `skill "${key}" has the same name and wins; rename the command or the skill`
|
|
457
|
+
});
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
const winner = winners.get(key);
|
|
461
|
+
if (winner) {
|
|
462
|
+
diagnostics.push({
|
|
463
|
+
path: file.path,
|
|
464
|
+
kind: "command",
|
|
465
|
+
message: `shadowed by ${winner}`
|
|
466
|
+
});
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
winners.set(key, file.path);
|
|
470
|
+
commands.push(parsed.command);
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
commands,
|
|
474
|
+
diagnostics
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Builtin Explore/Plan plus markdown agents. Files override builtins;
|
|
479
|
+
* among files, first-wins by name in root order. Never throws.
|
|
480
|
+
*/
|
|
481
|
+
function loadMarkdownAgents(opts) {
|
|
482
|
+
const fromFiles = Object.create(null);
|
|
483
|
+
const winners = /* @__PURE__ */ new Map();
|
|
484
|
+
const diagnostics = [];
|
|
485
|
+
for (const file of filesFor("agents", opts)) {
|
|
486
|
+
const content = read(file.path);
|
|
487
|
+
if (content === void 0) continue;
|
|
488
|
+
const parsed = parseAgentFile(file, content, opts.modelContext);
|
|
489
|
+
diagnostics.push(...parsed.diagnostics);
|
|
490
|
+
if (!parsed.entry) continue;
|
|
491
|
+
const [name, def] = parsed.entry;
|
|
492
|
+
if (RESERVED_NAMES.has(name)) {
|
|
493
|
+
diagnostics.push({
|
|
494
|
+
path: file.path,
|
|
495
|
+
kind: "agent",
|
|
496
|
+
message: "reserved agent name"
|
|
497
|
+
});
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
if (Object.hasOwn(BUILTIN_SUBAGENTS, name)) {
|
|
501
|
+
if (file.source === "project") {
|
|
502
|
+
diagnostics.push({
|
|
503
|
+
path: file.path,
|
|
504
|
+
kind: "agent",
|
|
505
|
+
message: `project files cannot replace builtin ${name}; rename the agent or move it to the user folder`
|
|
506
|
+
});
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
if (!def.tools && !parsed.explicitReadonlyFalse) def.readonly = true;
|
|
510
|
+
}
|
|
511
|
+
const winner = winners.get(name);
|
|
512
|
+
if (winner) {
|
|
513
|
+
diagnostics.push({
|
|
514
|
+
path: file.path,
|
|
515
|
+
kind: "agent",
|
|
516
|
+
message: `shadowed by ${winner}`
|
|
517
|
+
});
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
winners.set(name, file.path);
|
|
521
|
+
fromFiles[name] = def;
|
|
522
|
+
}
|
|
523
|
+
const subagents = {};
|
|
524
|
+
for (const [name, def] of Object.entries(BUILTIN_SUBAGENTS)) subagents[name] = { ...def };
|
|
525
|
+
for (const [name, def] of Object.entries(fromFiles)) subagents[name] = def;
|
|
526
|
+
return {
|
|
527
|
+
subagents,
|
|
528
|
+
diagnostics
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Fold markdown/builtin agents into the preset's spawn tool, filling gaps
|
|
533
|
+
* only: an agent the profile or an extension already registered keeps its
|
|
534
|
+
* definition. Runs after `composeExtensionPreset`, so precedence is
|
|
535
|
+
* builtin < file < extension without threading files through composition.
|
|
536
|
+
*/
|
|
537
|
+
function applyMarkdownSubagents(preset, subagents) {
|
|
538
|
+
const spawn = preset.tools?.spawn;
|
|
539
|
+
const entries = Object.entries(subagents);
|
|
540
|
+
if (!spawn || !isSpawnTool(spawn) || entries.length === 0) return preset;
|
|
541
|
+
const overrides = Object.create(null);
|
|
542
|
+
for (const [name, def] of entries) overrides[name] = (current) => current ?? def;
|
|
543
|
+
return {
|
|
544
|
+
...preset,
|
|
545
|
+
tools: {
|
|
546
|
+
...preset.tools,
|
|
547
|
+
spawn: spawn.withSubagents({}, overrides)
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
//#endregion
|
|
552
|
+
//#region src/headless.ts
|
|
553
|
+
function exitCodeForHeadlessResult(result) {
|
|
554
|
+
switch (result.status) {
|
|
555
|
+
case "completed": return 0;
|
|
556
|
+
case "timeout": return 124;
|
|
557
|
+
case "aborted": return 130;
|
|
558
|
+
default: return 1;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
/** Serialize one event as a newline-terminated JSON line (stream-json). */
|
|
562
|
+
function headlessEventToJsonl(event) {
|
|
563
|
+
return `${JSON.stringify(event)}\n`;
|
|
564
|
+
}
|
|
565
|
+
function formattedHeadlessTurnEventToJsonl(event) {
|
|
566
|
+
return `${JSON.stringify(event)}\n`;
|
|
567
|
+
}
|
|
568
|
+
function providerTranscriptFormatForProvider(providerName) {
|
|
569
|
+
return providerName === "anthropic" ? "anthropic" : "openai";
|
|
570
|
+
}
|
|
571
|
+
function transcriptToProviderMessages(turns, providerName) {
|
|
572
|
+
if (providerTranscriptFormatForProvider(providerName) === "anthropic") return turns.filter(isWireTurn).map((turn) => toAnthropic({
|
|
573
|
+
role: turn.role,
|
|
574
|
+
content: turn.content
|
|
575
|
+
}));
|
|
576
|
+
return transcriptToOpenAIMessages(turns, { strictToolPairing: false });
|
|
577
|
+
}
|
|
578
|
+
function formatHeadlessResult(result, options) {
|
|
579
|
+
if (options.format === "zidane") return result;
|
|
580
|
+
return transcriptToProviderMessages(result.transcript, options.providerName);
|
|
581
|
+
}
|
|
582
|
+
function formatHeadlessTurnEvent(event, options) {
|
|
583
|
+
if (options.format === "zidane") return event;
|
|
584
|
+
return transcriptToProviderMessages([event.turn], options.providerName);
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Run a prompt to completion, headless, and return a single serializable
|
|
588
|
+
* {@link HeadlessResult}. Safe to call concurrently for parallel rollouts —
|
|
589
|
+
* each call builds its own agent + session and tears them down in `finally`.
|
|
590
|
+
*/
|
|
591
|
+
async function runHeadless(opts) {
|
|
592
|
+
const startedAt = Date.now();
|
|
593
|
+
const execution = opts.execution ?? createProcessContext({ cwd: opts.cwd });
|
|
594
|
+
const session = opts.session ?? await createSession({ store: opts.store ?? createMemoryStore() });
|
|
595
|
+
const basePreset = opts.subagents ? applyMarkdownSubagents(opts.preset ?? basic_default, opts.subagents) : opts.preset ?? basic_default;
|
|
596
|
+
const behavior = {
|
|
597
|
+
mediaBudget: DEFAULT_MEDIA_BUDGET,
|
|
598
|
+
maxImageEdge: DEFAULT_MAX_IMAGE_EDGE,
|
|
599
|
+
...basePreset.behavior,
|
|
600
|
+
...opts.behavior ?? {}
|
|
601
|
+
};
|
|
602
|
+
if (opts.maxTurns !== void 0) behavior.maxTurns = opts.maxTurns;
|
|
603
|
+
if (opts.maxTokens !== void 0) behavior.maxTokens = opts.maxTokens;
|
|
604
|
+
if (opts.schema !== void 0) behavior.schema = opts.schema;
|
|
605
|
+
const agent = createAgent({
|
|
606
|
+
...basePreset,
|
|
607
|
+
provider: opts.provider,
|
|
608
|
+
execution,
|
|
609
|
+
session,
|
|
610
|
+
behavior,
|
|
611
|
+
...opts.tools !== void 0 ? { tools: opts.tools } : {},
|
|
612
|
+
...opts.mcpServers !== void 0 ? { mcpServers: opts.mcpServers } : {},
|
|
613
|
+
...opts.skills !== void 0 ? { skills: opts.skills } : {},
|
|
614
|
+
...opts.extensions !== void 0 ? { extensions: opts.extensions } : {}
|
|
615
|
+
});
|
|
616
|
+
const collector = createRunSummaryCollector();
|
|
617
|
+
const uninstallSummary = collector.install(agent.hooks);
|
|
618
|
+
const uninstallEvents = opts.onEvent ? installHeadlessEventAdapter(agent.hooks, opts.onEvent) : noop;
|
|
619
|
+
const runStartIndex = session.turns.length;
|
|
620
|
+
const controller = new AbortController();
|
|
621
|
+
const onExternalAbort = () => controller.abort(opts.signal.reason);
|
|
622
|
+
if (opts.signal) {
|
|
623
|
+
if (opts.signal.aborted) controller.abort(opts.signal.reason);
|
|
624
|
+
else opts.signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
625
|
+
}
|
|
626
|
+
let timedOut = false;
|
|
627
|
+
const timer = opts.timeoutMs && opts.timeoutMs > 0 ? setTimeout(() => {
|
|
628
|
+
timedOut = true;
|
|
629
|
+
controller.abort(/* @__PURE__ */ new Error(`Headless run timed out after ${opts.timeoutMs}ms`));
|
|
630
|
+
}, opts.timeoutMs) : void 0;
|
|
631
|
+
let stats;
|
|
632
|
+
let error;
|
|
633
|
+
try {
|
|
634
|
+
stats = await agent.run({
|
|
635
|
+
prompt: opts.prompt,
|
|
636
|
+
signal: controller.signal,
|
|
637
|
+
...opts.model !== void 0 ? { model: opts.model } : {},
|
|
638
|
+
...opts.system !== void 0 ? { system: opts.system } : {},
|
|
639
|
+
...opts.thinking !== void 0 ? { thinking: opts.thinking } : {}
|
|
640
|
+
});
|
|
641
|
+
} catch (err) {
|
|
642
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
643
|
+
error = {
|
|
644
|
+
message: e.message,
|
|
645
|
+
type: e.name
|
|
646
|
+
};
|
|
647
|
+
} finally {
|
|
648
|
+
if (timer) clearTimeout(timer);
|
|
649
|
+
opts.signal?.removeEventListener("abort", onExternalAbort);
|
|
650
|
+
uninstallEvents();
|
|
651
|
+
uninstallSummary();
|
|
652
|
+
await agent.destroy();
|
|
653
|
+
}
|
|
654
|
+
let status;
|
|
655
|
+
if (error) status = timedOut ? "timeout" : controller.signal.aborted ? "aborted" : "error";
|
|
656
|
+
else if (controller.signal.aborted) status = timedOut ? "timeout" : "aborted";
|
|
657
|
+
else status = "completed";
|
|
658
|
+
const rawTranscript = session.turns.slice(runStartIndex);
|
|
659
|
+
const transcript = opts.includeThinking === false ? stripThinking(rawTranscript) : rawTranscript;
|
|
660
|
+
const summary = collector.latest();
|
|
661
|
+
const result = {
|
|
662
|
+
status,
|
|
663
|
+
finalText: extractFinalText(rawTranscript),
|
|
664
|
+
...stats?.output ? { output: stats.output } : {},
|
|
665
|
+
usage: {
|
|
666
|
+
input: stats?.totalIn ?? 0,
|
|
667
|
+
output: stats?.totalOut ?? 0,
|
|
668
|
+
cacheRead: stats?.totalCacheRead ?? 0,
|
|
669
|
+
cacheCreation: stats?.totalCacheCreation ?? 0,
|
|
670
|
+
...typeof stats?.cost === "number" ? { cost: stats.cost } : {}
|
|
671
|
+
},
|
|
672
|
+
turns: stats?.turns ?? 0,
|
|
673
|
+
durationMs: stats?.elapsed ?? Date.now() - startedAt,
|
|
674
|
+
numToolCalls: countToolCalls(rawTranscript),
|
|
675
|
+
...status !== "aborted" && status !== "timeout" && lastFinishReason(stats) ? { finishReason: lastFinishReason(stats) } : {},
|
|
676
|
+
...error ? { error } : {},
|
|
677
|
+
sessionId: session.id,
|
|
678
|
+
...summary ? { summary } : {},
|
|
679
|
+
transcript
|
|
680
|
+
};
|
|
681
|
+
opts.onEvent?.({
|
|
682
|
+
type: "result",
|
|
683
|
+
result
|
|
684
|
+
});
|
|
685
|
+
return result;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Convert raw `session.turns` into standard OpenAI chat-completion messages:
|
|
689
|
+
* assistant turns carry `tool_calls`, and each `tool_result` becomes its own
|
|
690
|
+
* `role: 'tool'` message. This is the drop-in shape for an SFT renderer —
|
|
691
|
+
* unlike `toOpenAI` (session/messages.ts), which emits an internal `_tag`
|
|
692
|
+
* envelope meant for re-sending to a provider, not for training data.
|
|
693
|
+
*
|
|
694
|
+
* Fails closed on corrupt raw turns instead of fabricating tool results; silent
|
|
695
|
+
* placeholders would create structurally-valid but semantically-poisoned SFT
|
|
696
|
+
* examples.
|
|
697
|
+
*/
|
|
698
|
+
function transcriptToOpenAIMessages(turns, options = {}) {
|
|
699
|
+
const { strictToolPairing = true } = options;
|
|
700
|
+
const messages = [];
|
|
701
|
+
let chunk = [];
|
|
702
|
+
const flushChunk = () => {
|
|
703
|
+
if (chunk.length === 0) return;
|
|
704
|
+
let paired = chunk;
|
|
705
|
+
if (strictToolPairing) {
|
|
706
|
+
const repairs = [];
|
|
707
|
+
paired = ensureToolResultPairing(chunk, { onRepair: (repair) => repairs.push(repair) });
|
|
708
|
+
if (repairs.length > 0) throw new Error(`Cannot convert transcript to OpenAI messages: tool pairing repair required (${repairs.map((r) => r.mode).join(", ")})`);
|
|
709
|
+
}
|
|
710
|
+
for (const msg of paired) pushOpenAIChatMessage(messages, msg);
|
|
711
|
+
chunk = [];
|
|
712
|
+
};
|
|
713
|
+
for (const turn of turns) {
|
|
714
|
+
if (turn.role === "system") {
|
|
715
|
+
flushChunk();
|
|
716
|
+
messages.push({
|
|
717
|
+
role: "system",
|
|
718
|
+
content: textOf(turn.content)
|
|
719
|
+
});
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
if (!isWireTurn(turn)) continue;
|
|
723
|
+
chunk.push({
|
|
724
|
+
role: turn.role,
|
|
725
|
+
content: turn.content
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
flushChunk();
|
|
729
|
+
return messages;
|
|
730
|
+
}
|
|
731
|
+
function pushOpenAIChatMessage(messages, msg) {
|
|
732
|
+
const text = textOf(msg.content);
|
|
733
|
+
if (msg.role === "assistant") {
|
|
734
|
+
const toolCalls = msg.content.filter((b) => b.type === "tool_call");
|
|
735
|
+
const out = {
|
|
736
|
+
role: "assistant",
|
|
737
|
+
content: text || null
|
|
738
|
+
};
|
|
739
|
+
if (toolCalls.length > 0) out.tool_calls = toolCalls.map((b) => ({
|
|
740
|
+
id: b.id,
|
|
741
|
+
type: "function",
|
|
742
|
+
function: {
|
|
743
|
+
name: b.name,
|
|
744
|
+
arguments: JSON.stringify(b.input)
|
|
745
|
+
}
|
|
746
|
+
}));
|
|
747
|
+
messages.push(out);
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const userParts = contentPartsFromBlocks(msg.content);
|
|
751
|
+
if (userParts.length > 0) messages.push({
|
|
752
|
+
role: "user",
|
|
753
|
+
content: simplifyOpenAIContent(userParts)
|
|
754
|
+
});
|
|
755
|
+
for (const tr of msg.content.filter((b) => b.type === "tool_result")) {
|
|
756
|
+
const { text, images } = summarizeToolResultForOpenAI(tr.output);
|
|
757
|
+
if (images.length === 0) {
|
|
758
|
+
messages.push({
|
|
759
|
+
role: "tool",
|
|
760
|
+
tool_call_id: tr.callId,
|
|
761
|
+
content: text
|
|
762
|
+
});
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
const noun = images.length === 1 ? "image" : "images";
|
|
766
|
+
const marker = `[${images.length} ${noun} attached — see next user message]`;
|
|
767
|
+
messages.push({
|
|
768
|
+
role: "tool",
|
|
769
|
+
tool_call_id: tr.callId,
|
|
770
|
+
content: text.length > 0 ? `${text}\n\n${marker}` : marker
|
|
771
|
+
});
|
|
772
|
+
messages.push({
|
|
773
|
+
role: "user",
|
|
774
|
+
content: [...images.map(toOpenAIImagePart), {
|
|
775
|
+
type: "text",
|
|
776
|
+
text: `(${noun} returned by tool call ${tr.callId})`
|
|
777
|
+
}]
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
function noop() {}
|
|
782
|
+
function textOf(content) {
|
|
783
|
+
return content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
784
|
+
}
|
|
785
|
+
function contentPartsFromBlocks(content) {
|
|
786
|
+
const parts = [];
|
|
787
|
+
for (const block of content) if (block.type === "image") {
|
|
788
|
+
assertResolvedMediaBlock(block, "OpenAI transcript messages");
|
|
789
|
+
parts.push(toOpenAIImagePart(block));
|
|
790
|
+
} else if (block.type === "audio") parts.push({
|
|
791
|
+
type: "input_audio",
|
|
792
|
+
input_audio: {
|
|
793
|
+
data: block.data,
|
|
794
|
+
format: audioFormatFromMediaType(block.mediaType)
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
else if (block.type === "video") parts.push({
|
|
798
|
+
type: "video_url",
|
|
799
|
+
video_url: { url: `data:${block.mediaType};base64,${block.data}` }
|
|
800
|
+
});
|
|
801
|
+
else if (block.type === "document") {
|
|
802
|
+
assertResolvedMediaBlock(block, "OpenAI transcript messages");
|
|
803
|
+
parts.push({
|
|
804
|
+
type: "text",
|
|
805
|
+
text: documentMarker(block)
|
|
806
|
+
});
|
|
807
|
+
} else if (block.type === "text" && block.text.length > 0) parts.push({
|
|
808
|
+
type: "text",
|
|
809
|
+
text: block.text
|
|
810
|
+
});
|
|
811
|
+
return parts;
|
|
812
|
+
}
|
|
813
|
+
function simplifyOpenAIContent(parts) {
|
|
814
|
+
if (parts.length === 1 && parts[0].type === "text") return parts[0].text;
|
|
815
|
+
return parts;
|
|
816
|
+
}
|
|
817
|
+
function toOpenAIImagePart(image) {
|
|
818
|
+
return {
|
|
819
|
+
type: "image_url",
|
|
820
|
+
image_url: { url: `data:${image.mediaType};base64,${image.data}` }
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
function summarizeToolResultForOpenAI(output) {
|
|
824
|
+
if (typeof output === "string") return {
|
|
825
|
+
text: output,
|
|
826
|
+
images: []
|
|
827
|
+
};
|
|
828
|
+
const texts = [];
|
|
829
|
+
const images = [];
|
|
830
|
+
for (const block of output) if (block.type === "text") texts.push(block.text);
|
|
831
|
+
else if (block.type === "image") {
|
|
832
|
+
assertResolvedMediaBlock(block, "OpenAI transcript messages");
|
|
833
|
+
images.push({
|
|
834
|
+
mediaType: block.mediaType,
|
|
835
|
+
data: block.data
|
|
836
|
+
});
|
|
837
|
+
} else if (block.type === "audio") texts.push(`[audio: ${block.mediaType}]`);
|
|
838
|
+
else if (block.type === "video") texts.push(`[video: ${block.mediaType}]`);
|
|
839
|
+
else {
|
|
840
|
+
assertResolvedMediaBlock(block, "OpenAI transcript messages");
|
|
841
|
+
texts.push(documentMarker(block));
|
|
842
|
+
}
|
|
843
|
+
return {
|
|
844
|
+
text: texts.join("\n"),
|
|
845
|
+
images
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
function documentMarker(doc) {
|
|
849
|
+
return documentBlockMarker(doc, "document omitted");
|
|
850
|
+
}
|
|
851
|
+
function extractFinalText(turns) {
|
|
852
|
+
for (let i = turns.length - 1; i >= 0; i--) {
|
|
853
|
+
const turn = turns[i];
|
|
854
|
+
if (turn.role !== "assistant") continue;
|
|
855
|
+
const text = textOf(turn.content);
|
|
856
|
+
if (text) return text;
|
|
857
|
+
}
|
|
858
|
+
return "";
|
|
859
|
+
}
|
|
860
|
+
function countToolCalls(turns) {
|
|
861
|
+
let n = 0;
|
|
862
|
+
for (const turn of turns) for (const block of turn.content) if (block.type === "tool_call") n++;
|
|
863
|
+
return n;
|
|
864
|
+
}
|
|
865
|
+
function lastFinishReason(stats) {
|
|
866
|
+
const usages = stats?.turnUsage;
|
|
867
|
+
if (!usages) return void 0;
|
|
868
|
+
for (let i = usages.length - 1; i >= 0; i--) if (usages[i].finishReason) return usages[i].finishReason;
|
|
869
|
+
}
|
|
870
|
+
function stripThinking(turns) {
|
|
871
|
+
return turns.map((turn) => ({
|
|
872
|
+
...turn,
|
|
873
|
+
content: turn.content.filter((b) => b.type !== "thinking" && b.type !== "redacted_thinking")
|
|
874
|
+
}));
|
|
875
|
+
}
|
|
876
|
+
function installHeadlessEventAdapter(hooks, onEvent) {
|
|
877
|
+
const unregs = [];
|
|
878
|
+
const emittedTurnIds = /* @__PURE__ */ new Set();
|
|
879
|
+
const emit = (event) => {
|
|
880
|
+
try {
|
|
881
|
+
onEvent(event);
|
|
882
|
+
} catch {}
|
|
883
|
+
};
|
|
884
|
+
unregs.push(hooks.hook("agent:start", (ctx) => emit({
|
|
885
|
+
type: "start",
|
|
886
|
+
runId: ctx.runId,
|
|
887
|
+
...ctx.providerName ? { provider: ctx.providerName } : {}
|
|
888
|
+
})));
|
|
889
|
+
unregs.push(hooks.hook("stream:text", (ctx) => emit({
|
|
890
|
+
type: "text",
|
|
891
|
+
delta: ctx.delta
|
|
892
|
+
})));
|
|
893
|
+
unregs.push(hooks.hook("stream:thinking", (ctx) => emit({
|
|
894
|
+
type: "thinking",
|
|
895
|
+
delta: ctx.delta
|
|
896
|
+
})));
|
|
897
|
+
unregs.push(hooks.hook("tool:before", (ctx) => emit({
|
|
898
|
+
type: "tool_call",
|
|
899
|
+
callId: ctx.callId,
|
|
900
|
+
name: ctx.name,
|
|
901
|
+
input: ctx.input
|
|
902
|
+
})));
|
|
903
|
+
unregs.push(hooks.hook("tool:after", (ctx) => emit({
|
|
904
|
+
type: "tool_result",
|
|
905
|
+
callId: ctx.callId,
|
|
906
|
+
name: ctx.name,
|
|
907
|
+
output: toolResultToText(ctx.result),
|
|
908
|
+
isError: false
|
|
909
|
+
})));
|
|
910
|
+
unregs.push(hooks.hook("tool:error", (ctx) => emit({
|
|
911
|
+
type: "tool_result",
|
|
912
|
+
callId: ctx.callId,
|
|
913
|
+
name: ctx.name,
|
|
914
|
+
output: ctx.error.message,
|
|
915
|
+
isError: true
|
|
916
|
+
})));
|
|
917
|
+
unregs.push(hooks.hook("session:turns", (ctx) => {
|
|
918
|
+
const startIndex = ctx.count - ctx.turns.length;
|
|
919
|
+
ctx.turns.forEach((turn, i) => {
|
|
920
|
+
if (emittedTurnIds.has(turn.id)) return;
|
|
921
|
+
emittedTurnIds.add(turn.id);
|
|
922
|
+
emit({
|
|
923
|
+
type: "turn",
|
|
924
|
+
index: startIndex + i,
|
|
925
|
+
turn
|
|
926
|
+
});
|
|
927
|
+
});
|
|
928
|
+
}));
|
|
929
|
+
unregs.push(hooks.hook("spawn:before", (ctx) => emit({
|
|
930
|
+
type: "spawn",
|
|
931
|
+
event: "before",
|
|
932
|
+
id: ctx.id
|
|
933
|
+
})));
|
|
934
|
+
unregs.push(hooks.hook("spawn:complete", (ctx) => emit({
|
|
935
|
+
type: "spawn",
|
|
936
|
+
event: "complete",
|
|
937
|
+
id: ctx.id,
|
|
938
|
+
info: { status: ctx.status ?? "completed" }
|
|
939
|
+
})));
|
|
940
|
+
unregs.push(hooks.hook("spawn:error", (ctx) => emit({
|
|
941
|
+
type: "spawn",
|
|
942
|
+
event: "error",
|
|
943
|
+
id: ctx.id,
|
|
944
|
+
info: { message: ctx.error.message }
|
|
945
|
+
})));
|
|
946
|
+
unregs.push(hooks.hook("stream:error", (ctx) => emit({
|
|
947
|
+
type: "error",
|
|
948
|
+
message: ctx.err instanceof Error ? ctx.err.message : String(ctx.err),
|
|
949
|
+
...ctx.err instanceof Error ? { errorType: ctx.err.name } : {}
|
|
950
|
+
})));
|
|
951
|
+
return () => {
|
|
952
|
+
for (const un of unregs) try {
|
|
953
|
+
un();
|
|
954
|
+
} catch {}
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
//#endregion
|
|
958
|
+
export { headlessEventToJsonl as a, runHeadless as c, applyMarkdownSubagents as d, loadMarkdownAgents as f, BUILTIN_SUBAGENTS as g, markdownDefRoots as h, formattedHeadlessTurnEventToJsonl as i, transcriptToOpenAIMessages as l, listMarkdownDefFiles as m, formatHeadlessResult as n, installHeadlessEventAdapter as o, loadMarkdownCommands as p, formatHeadlessTurnEvent as r, providerTranscriptFormatForProvider as s, exitCodeForHeadlessResult as t, transcriptToProviderMessages as u };
|
|
959
|
+
|
|
960
|
+
//# sourceMappingURL=headless-C_rNUuYC.js.map
|