chainlesschain 0.162.177 → 0.162.178
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/README.md +10 -0
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-DT-VPWuN.js → AIOps-DRftcSue.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DyOreOVN.js → ActionButton-BFvUaMKR.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DslNsKux.js → Analytics-C0-Rru4P.js} +3 -3
- package/src/assets/web-panel/assets/AppLayout-bx-BCljj.js +9 -0
- package/src/assets/web-panel/assets/{Artifacts-DoaAtEcY.js → Artifacts-DAJ8B3Un.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DPG3WdJ9.js → Audit-hOk4L1lr.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C_JO6R5G.js → BackgroundAgents-3pbDpM9z.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Cv3BooyX.js → Backup-BtziGDn9.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-D2uQXWu-.js → BaseInput-kmshphJ3.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-B4Vczyf3.js → Chat-d7tGSosA.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-p-_PBpX_.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-qTgk4VeP.js → Checkbox-C4Eh4Tz5.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DlLWcIzj.js → Codegen-r7gmhZyA.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DNO73qp7.js → Col-U7mDaGlL.js} +1 -1
- package/src/assets/web-panel/assets/{Community-vRDNpc4j.js → Community-Bpu8aH1T.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CEWtIXni.js → Compact-CHb2XBJe.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-KgYC9Fxi.js → Compliance-Cn_r4dey.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-zj5wvkpT.js → Cowork-CdMWfDcz.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-BLDoCozU.js → Cron-BtnREHWy.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BYnff4VY.js → Crosschain-BKI9TSzr.js} +1 -1
- package/src/assets/web-panel/assets/{DID-C75VFsVm.js → DID-pkNubzzJ.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-1rrz1snN.js +3 -0
- package/src/assets/web-panel/assets/{Dropdown-B5dbO4Kx.js → Dropdown-DLyFVxDc.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BDipZtHJ.js → EmailListRenderer-CtUWfYVq.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DmIzt8jj.js → FamilyGuardDashboard-B8eX2Qe4.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D9QOS-uW.js → Federation-D8lsDGus.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-B47HRwAm.js → FormItemContext-CRYt_aIw.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-3R4mXmgV.js → GenericCardRenderer-ClKzY8_N.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DrNXZf1C.js → Git-BXj5Dney.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BGd7JR98.js → Governance-Cm-I8RMz.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-D-2he1ed.js → Inference-CPvbhvgt.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-C0sHIbK5.js → KnowledgeGraph-sYNDZaoi.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DiBQO-jL.js → Logs-BZY_3CRZ.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DL_5eV2D.js → MarkdownRenderer-up0BW6pv.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-VR59OdrC.js → Marketplace-C5MEJ2Qe.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DrPzwSd3.js → McpTools-ihdrn43I.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-CBgKALwQ.js → Memory-Br8bPMlh.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-pQ9Tn-Mn.js → MobileBridge-BNntgrYW.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-mASB6jyj.js → MobileProjects-BdV915mw.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DTMgE7HC.js → Mtc-A3wDmlqL.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-CwTnCtiL.js → MtcAudit-CF-mBLWM.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-ngm6WU8f.js → Multisig-Iy2k_MSo.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-4YO4Qww9.js → NLProgramming-kk0W7HUb.js} +1 -1
- package/src/assets/web-panel/assets/Notes-B5u5t_4S.js +7 -0
- package/src/assets/web-panel/assets/{NotificationSettings-r2H8yPKb.js → NotificationSettings-BN0POf6_.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-CHkSUrXB.js +1 -0
- package/src/assets/web-panel/assets/{Organization-DrO7jRWS.js → Organization-DwWQESuN.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Cnwu4i4t.js → Overflow-DG6klrcC.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-zi-cDwA_.js → P2P-BwJcKkgZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DBEryDv7.js → PdhVaultBrowser-BwOHG0in.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-lqXK2C3x.js → Permissions-CGMXe4TX.js} +4 -4
- package/src/assets/web-panel/assets/PersonalDataHub-ziYqg7-A.js +8 -0
- package/src/assets/web-panel/assets/{Pipeline-Kep5KAGW.js → Pipeline-BzJfeoGt.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CHdvOAh1.js → Privacy-DLh3Bblx.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BhKfdwe9.js → ProjectInit-USVWW36c.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Yavk9K8A.js → ProjectSettings-CiiOn62h.js} +2 -2
- package/src/assets/web-panel/assets/Projects-6V-PNmcA.js +1 -0
- package/src/assets/web-panel/assets/{Providers-Bfym6SQn.js → Providers-CBPWWzpu.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CLSQcrlR.js → QrScannerModal-QVwoRUq3.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-VPa2WKQN.js → QuickAsk-CXnR-2Vn.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CGXR8jVU.js → Recommend-ClaNzjmF.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C_20YfMB.js → RemoteSession-C3rGw8vJ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-awZh68UV.js → Reputation-Ci-OWAoP.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Ctb4oiYN.js → Row-DRhAwXOS.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-D3sdjvUV.js → RssFeed-BQLJQ2_y.js} +3 -3
- package/src/assets/web-panel/assets/{Search-C-zfA4kT.js → Search-QQUpkfFd.js} +1 -1
- package/src/assets/web-panel/assets/{Security-D9XlmHA3.js → Security-DdXKzuKT.js} +4 -4
- package/src/assets/web-panel/assets/{Services-C3UKnr41.js → Services-x2Zh62Qd.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BQxagZfF.js → Skeleton-GdY4KwRz.js} +1 -1
- package/src/assets/web-panel/assets/Skills-Bv4tY1Fd.js +1 -0
- package/src/assets/web-panel/assets/{Sla-DveENvek.js → Sla-C3QnM-11.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BFjXLNgF.js → SpeechSettings-Bl3ytvmI.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BpHgbaP9.js → SyncSettings-Wp9IwTsP.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-CF3rIrDe.js +1 -0
- package/src/assets/web-panel/assets/{Templates-DEiaoyve.js → Templates-CGfvVVM9.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-ITg774nY.js → Tenant-CVXmwQ3U.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-D3ZBcvnb.js → Terminal-bvwrt03E.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BsLU6JjU.js → TimelineRenderer-D0g74KhH.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-Cb5Pquc9.js → Tokens-BH4IwzlT.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-Dwfy-m9N.js → Trigger-DJOpM533.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CnlSRGG0.js → Trust-B43EPRLr.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-Y4TlvKVo.js → UkeySign-BmBFG-em.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BpKLtTTO.js → VideoEditing-n9oJwB8k.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-LLBzIq8x.js → Wallet-D5QeivHp.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BeSRiusP.js → WebAuthn-DcNy7igO.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BK_l1tXO.js → WorkflowEditor-BVjc7-5-.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DYd-X7Wg.js → chat-Dy5Tfj3m.js} +1 -1
- package/src/assets/web-panel/assets/{colors-C9uip71j.js → colors-C4c2CNZU.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-JBrfjUP6.js → compact-item-DPa3O5vN.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-D03fbuiq.js → createContext-TLcfNA6_.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BAwdDA_5.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DLQOR6l-.js → hasIn-D41LVFkp.js} +1 -1
- package/src/assets/web-panel/assets/{index-rIxxfdTN.js → index-0oevYjfT.js} +1 -1
- package/src/assets/web-panel/assets/{index-CChaISMb.js → index-388pLGJ1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfOs_bmg.js → index-B8nLBZbv.js} +3 -3
- package/src/assets/web-panel/assets/{index-D-1SqEpQ.js → index-BPTGAjee.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYv-LWdy.js → index-BPtrOBmW.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cpn19c9k.js → index-BQiIxHBy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpYKLrUT.js → index-BSM1cHVK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CS63r8h3.js → index-BYPr9fkz.js} +1 -1
- package/src/assets/web-panel/assets/{index-Q7mmL6w4.js → index-BsQ7Ev6i.js} +1 -1
- package/src/assets/web-panel/assets/{index-SO6lgMg0.js → index-Btk9qLL2.js} +1 -1
- package/src/assets/web-panel/assets/{index-iahNhZwm.js → index-BvmziZSG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnQgRjsm.js → index-BvopLC_T.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ba-Ps_AJ.js → index-C7xhTVyP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuNFCZCx.js → index-CNk_ZooP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CL0ixCxk.js → index-CQrEHoOG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CChQBM1d.js → index-CSxex23J.js} +1 -1
- package/src/assets/web-panel/assets/{index-5YN7F5bO.js → index-CVjgm992.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwoDpKzW.js → index-CWK4zOPe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcBZwlnG.js → index-CX0VsoP4.js} +1 -1
- package/src/assets/web-panel/assets/{index-B46YcgsV.js → index-CXl0YPNG.js} +1 -1
- package/src/assets/web-panel/assets/{index-l08afIbV.js → index-Cip7LWml.js} +1 -1
- package/src/assets/web-panel/assets/{index-6GuLRpBQ.js → index-Cq_hlWNt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYLZY4uh.js → index-CzZ49YZL.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0X76LjX.js → index-D2Nkivlm.js} +1 -1
- package/src/assets/web-panel/assets/{index-BdH9l8wl.js → index-DBUgRs4D.js} +1 -1
- package/src/assets/web-panel/assets/index-DEjVkdzq.js +1 -0
- package/src/assets/web-panel/assets/{index-D4UY5Z60.js → index-DNsBj2Ob.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ce0Bf1YF.js → index-Di4X8cfI.js} +1 -1
- package/src/assets/web-panel/assets/{index-ByHO3SqZ.js → index-DljFsVGI.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2zmOsyD.js → index-Korc3QIe.js} +1 -1
- package/src/assets/web-panel/assets/index-LMOc5xrS.js +1 -0
- package/src/assets/web-panel/assets/{index-BNCdRmWf.js → index-MKZDje0H.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8KvuDz0.js → index-OHAfRu_3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaokIHt3.js → index-WEJr8PL5.js} +1 -1
- package/src/assets/web-panel/assets/{index-CILVyK3b.js → index-WinCp6du.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVZWiUE_.js → index-Yjr6cqSK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqWk1FLG.js → index-iQ6gtFih.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNMAAUVk.js → index-pt3s7yvV.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ck17i0OD.js → index-tQ3igERQ.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CG9z1c6w.js → initDefaultProps-BFZu87WZ.js} +1 -1
- package/src/assets/web-panel/assets/{motion-B1Ky7Zff.js → motion-DJIo7qvt.js} +1 -1
- package/src/assets/web-panel/assets/{move-DME8X2P1.js → move-Cfr5qknL.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-cuJYSWB7.js → mtc-parser-Bgc-OadH.js} +1 -1
- package/src/assets/web-panel/assets/{omit-UI_EE0uZ.js → omit-X3WI-TNp.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BIoE_Z_V.js → pickAttrs-pJhU9IxK.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B48-9HKN.js → placementArrow-BNg_Vj3T.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-D7x_GDgD.js → responsiveObserve-TeSEGQ5-.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DjzC5_7m.js → slide-D_t_P0bv.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-C6BIymhh.js → statusUtils-DrrIMwAT.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-B4dGrdD9.js → styleChecker-BjZCuFRm.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Bken4aNE.js → useFlexGapSupport-rTFdlqdQ.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BMlqECqv.js → useFs-BidCpfLX.js} +1 -1
- package/src/assets/web-panel/assets/usePersonalDataHub-C5mHttA9.js +1 -0
- package/src/assets/web-panel/assets/{vnode-CKJQmxa0.js → vnode-BrbcRiHZ.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CaZunuau.js → zoom-PISX7AkR.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/__tests__/hub-wechat.test.js +45 -0
- package/src/commands/background-session.js +5 -2
- package/src/commands/context.js +33 -1
- package/src/commands/hub.js +473 -39
- package/src/commands/init.js +212 -110
- package/src/commands/llm.js +22 -6
- package/src/commands/skill.js +11 -1
- package/src/data/changelog.json +76 -270
- package/src/gateways/ws/personal-data-hub-protocol.js +22 -2
- package/src/harness/golden-transcript.js +3 -0
- package/src/index.js +18 -7
- package/src/lib/approval-authority-store.js +891 -0
- package/src/lib/background-interaction-resolver.js +399 -54
- package/src/lib/background-session-transport.js +3 -1
- package/src/lib/context-breakdown.js +82 -3
- package/src/lib/event-runtime-host.js +225 -0
- package/src/lib/event-runtime-store.js +102 -21
- package/src/lib/event-runtime-worker.js +70 -2
- package/src/lib/hooks-v2-producers.js +33 -8
- package/src/lib/hooks-v2-runtime.js +360 -40
- package/src/lib/interaction-adapter.js +66 -0
- package/src/lib/operation-fingerprint.js +107 -2
- package/src/lib/pdh-dedicated-batch-collectors.js +124 -0
- package/src/lib/personal-data-hub-wiring.js +327 -52
- package/src/lib/process-execution-broker/credential-agent.js +954 -111
- package/src/lib/process-execution-broker/index.js +369 -85
- package/src/lib/process-execution-broker/platform-sandbox.js +320 -140
- package/src/lib/provider-http-error.js +94 -0
- package/src/lib/remote-approval-bridge.js +222 -26
- package/src/lib/side-effect-ledger-store.js +65 -14
- package/src/lib/skill-loader.js +215 -12
- package/src/lib/skill-process-broker.js +15 -1
- package/src/lib/sub-agent-context.js +42 -0
- package/src/lib/turn-binding-store.js +64 -15
- package/src/lib/turn-binding.js +85 -16
- package/src/repl/agent-repl.js +40 -6
- package/src/repl/remote-approval.js +13 -13
- package/src/repl/repl-turn-binding.js +46 -16
- package/src/runtime/agent-core.js +286 -35
- package/src/runtime/coding-agent-contract-shared.cjs +16 -0
- package/src/runtime/headless-runner.js +147 -34
- package/src/runtime/headless-stream.js +147 -7
- package/src/workers/background-agent-worker.js +70 -38
- package/src/assets/web-panel/assets/AppLayout-BNJJAYME.js +0 -9
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DE6reP99.js +0 -1
- package/src/assets/web-panel/assets/Dashboard-C4Gutni2.js +0 -3
- package/src/assets/web-panel/assets/Notes-DP1k45mF.js +0 -7
- package/src/assets/web-panel/assets/OrderTableRenderer-CoM_Zw0J.js +0 -1
- package/src/assets/web-panel/assets/PersonalDataHub-b63T3HJM.js +0 -9
- package/src/assets/web-panel/assets/Projects-CN8E_5Mq.js +0 -1
- package/src/assets/web-panel/assets/Skills-q6eb6KPZ.js +0 -1
- package/src/assets/web-panel/assets/Tasks-DvepRb8-.js +0 -1
- package/src/assets/web-panel/assets/devWarning-B8LQ8leS.js +0 -1
- package/src/assets/web-panel/assets/index-Bh8BPtqR.js +0 -1
- package/src/assets/web-panel/assets/index-CeVrHLzZ.js +0 -1
- package/src/assets/web-panel/assets/usePersonalDataHub-DLdrfmMa.js +0 -1
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
} from "../lib/idempotency.js";
|
|
60
60
|
import { buildSearchCommand } from "../lib/search-command.js";
|
|
61
61
|
import { discoverCommands } from "../lib/slash-commands.js";
|
|
62
|
+
import { createSkillProcessBroker } from "../lib/skill-process-broker.js";
|
|
62
63
|
import {
|
|
63
64
|
isRetryableStreamError,
|
|
64
65
|
STREAM_RETRY_BASE_MS,
|
|
@@ -79,12 +80,21 @@ import {
|
|
|
79
80
|
imageUrlBlockToAnthropic,
|
|
80
81
|
} from "../lib/image-input.js";
|
|
81
82
|
import { executeToolSearch, gateDeferredMcpCall } from "./mcp-tool-search.js";
|
|
82
|
-
import {
|
|
83
|
+
import {
|
|
84
|
+
emitHooksV2Event,
|
|
85
|
+
executeHooksV2Event,
|
|
86
|
+
} from "../lib/hooks-v2-producers.js";
|
|
83
87
|
import {
|
|
84
88
|
admitTool,
|
|
85
89
|
buildToolAttribution,
|
|
86
90
|
} from "../lib/agent-tool-admission.js";
|
|
87
91
|
import { evaluateUnattendedShellAction } from "../lib/unattended-action-policy.js";
|
|
92
|
+
import {
|
|
93
|
+
formatProviderHttpError,
|
|
94
|
+
formatProviderResponseError,
|
|
95
|
+
} from "../lib/provider-http-error.js";
|
|
96
|
+
|
|
97
|
+
export { formatProviderHttpError };
|
|
88
98
|
|
|
89
99
|
/**
|
|
90
100
|
* Names of MCP servers currently mounted by an in-flight run_skill call.
|
|
@@ -660,6 +670,33 @@ async function requestInteractivePermission(
|
|
|
660
670
|
cwd,
|
|
661
671
|
confirmArgs,
|
|
662
672
|
) {
|
|
673
|
+
const hooksV2 = await executeHooksV2Event(
|
|
674
|
+
"PermissionRequest",
|
|
675
|
+
{
|
|
676
|
+
schema_version: 1,
|
|
677
|
+
session_id: context.sessionId || null,
|
|
678
|
+
turn_id: context.turnId || null,
|
|
679
|
+
tool_use_id: context.toolCallId || null,
|
|
680
|
+
tool_name: name,
|
|
681
|
+
input_keys:
|
|
682
|
+
args && typeof args === "object" ? Object.keys(args).sort() : [],
|
|
683
|
+
reason: confirmArgs?.reason || null,
|
|
684
|
+
cwd,
|
|
685
|
+
},
|
|
686
|
+
{ failClosed: true },
|
|
687
|
+
);
|
|
688
|
+
if (hooksV2.decision === "allow") return true;
|
|
689
|
+
if (hooksV2.blocked || hooksV2.decision === "block") {
|
|
690
|
+
emitHooksV2Event("PermissionDenied", {
|
|
691
|
+
schema_version: 1,
|
|
692
|
+
session_id: context.sessionId || null,
|
|
693
|
+
turn_id: context.turnId || null,
|
|
694
|
+
tool_use_id: context.toolCallId || null,
|
|
695
|
+
tool_name: name,
|
|
696
|
+
source: "hooks-v2",
|
|
697
|
+
});
|
|
698
|
+
return false;
|
|
699
|
+
}
|
|
663
700
|
const verdict = runSettingsPermissionRequestHooks(
|
|
664
701
|
name,
|
|
665
702
|
args,
|
|
@@ -668,9 +705,31 @@ async function requestInteractivePermission(
|
|
|
668
705
|
confirmArgs?.reason,
|
|
669
706
|
);
|
|
670
707
|
if (verdict.decision === "allow") return true;
|
|
671
|
-
if (verdict.decision === "deny")
|
|
708
|
+
if (verdict.decision === "deny") {
|
|
709
|
+
emitHooksV2Event("PermissionDenied", {
|
|
710
|
+
schema_version: 1,
|
|
711
|
+
session_id: context.sessionId || null,
|
|
712
|
+
turn_id: context.turnId || null,
|
|
713
|
+
tool_use_id: context.toolCallId || null,
|
|
714
|
+
tool_name: name,
|
|
715
|
+
source: "settings-hook",
|
|
716
|
+
});
|
|
717
|
+
return false;
|
|
718
|
+
}
|
|
672
719
|
const confirm = context.permissionConfirm || context.shellConfirm || null;
|
|
673
|
-
|
|
720
|
+
const approved =
|
|
721
|
+
typeof confirm === "function" ? await confirm(confirmArgs) : false;
|
|
722
|
+
if (!approved) {
|
|
723
|
+
emitHooksV2Event("PermissionDenied", {
|
|
724
|
+
schema_version: 1,
|
|
725
|
+
session_id: context.sessionId || null,
|
|
726
|
+
turn_id: context.turnId || null,
|
|
727
|
+
tool_use_id: context.toolCallId || null,
|
|
728
|
+
tool_name: name,
|
|
729
|
+
source: typeof confirm === "function" ? "user" : "no-confirmer",
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
return approved;
|
|
674
733
|
}
|
|
675
734
|
|
|
676
735
|
// ─── Tool definitions ────────────────────────────────────────────────────
|
|
@@ -1006,13 +1065,14 @@ export function buildSystemPrompt(cwd, opts = {}) {
|
|
|
1006
1065
|
|
|
1007
1066
|
// Append auto-activated persona skills
|
|
1008
1067
|
try {
|
|
1009
|
-
const loader = new CLISkillLoader();
|
|
1010
|
-
const
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1068
|
+
const loader = opts.skillLoader || new CLISkillLoader();
|
|
1069
|
+
const personaSkills = loader.getAutoActivatedPersonas({
|
|
1070
|
+
sessionId: opts.sessionId,
|
|
1071
|
+
turnId: opts.turnId,
|
|
1072
|
+
loadedBecause: "persona_auto",
|
|
1073
|
+
});
|
|
1014
1074
|
if (typeof opts.onSkillsLoaded === "function") {
|
|
1015
|
-
opts.onSkillsLoaded(personaSkills);
|
|
1075
|
+
opts.onSkillsLoaded(personaSkills, loader.getCacheLedger());
|
|
1016
1076
|
}
|
|
1017
1077
|
for (const p of personaSkills) {
|
|
1018
1078
|
if (p.body?.trim()) {
|
|
@@ -1810,6 +1870,52 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1810
1870
|
// capable: a `block` (exit 2 / {decision:block}) stops the tool here, an
|
|
1811
1871
|
// `ask` routes to the confirmer. Runs after permission resolution so a
|
|
1812
1872
|
// settings deny / host deny short-circuits before any hook process spawns.
|
|
1873
|
+
const hooksV2Pre = await executeHooksV2Event(
|
|
1874
|
+
"PreToolUse",
|
|
1875
|
+
{
|
|
1876
|
+
schema_version: 1,
|
|
1877
|
+
session_id: context.sessionId || null,
|
|
1878
|
+
turn_id: context.turnId || null,
|
|
1879
|
+
tool_use_id: context.toolCallId || null,
|
|
1880
|
+
tool_name: name,
|
|
1881
|
+
input_keys:
|
|
1882
|
+
args && typeof args === "object" ? Object.keys(args).sort() : [],
|
|
1883
|
+
cwd,
|
|
1884
|
+
},
|
|
1885
|
+
{ failClosed: true },
|
|
1886
|
+
);
|
|
1887
|
+
if (hooksV2Pre.blocked || hooksV2Pre.decision === "block") {
|
|
1888
|
+
return {
|
|
1889
|
+
error: `[Hook v2] PreToolUse blocked "${name}".`,
|
|
1890
|
+
policy: { decision: "block", via: "hooks-v2" },
|
|
1891
|
+
};
|
|
1892
|
+
}
|
|
1893
|
+
if (hooksV2Pre.requiresApproval || hooksV2Pre.decision === "ask") {
|
|
1894
|
+
const confirm = context.permissionConfirm || context.shellConfirm || null;
|
|
1895
|
+
const approved =
|
|
1896
|
+
typeof confirm === "function"
|
|
1897
|
+
? await confirm({
|
|
1898
|
+
tool: name,
|
|
1899
|
+
args,
|
|
1900
|
+
reason: "Hooks v2 PreToolUse requested confirmation",
|
|
1901
|
+
source: "hooks-v2",
|
|
1902
|
+
})
|
|
1903
|
+
: false;
|
|
1904
|
+
if (!approved) {
|
|
1905
|
+
emitHooksV2Event("PermissionDenied", {
|
|
1906
|
+
schema_version: 1,
|
|
1907
|
+
session_id: context.sessionId || null,
|
|
1908
|
+
turn_id: context.turnId || null,
|
|
1909
|
+
tool_use_id: context.toolCallId || null,
|
|
1910
|
+
tool_name: name,
|
|
1911
|
+
source: "hooks-v2",
|
|
1912
|
+
});
|
|
1913
|
+
return {
|
|
1914
|
+
error: `[Hook v2] PreToolUse confirmation denied for "${name}".`,
|
|
1915
|
+
policy: { decision: "deny", via: "hooks-v2" },
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1813
1919
|
if (hookDb) {
|
|
1814
1920
|
try {
|
|
1815
1921
|
await executeHooks(hookDb, HookEvents.PreToolUse, {
|
|
@@ -1849,6 +1955,8 @@ export async function executeTool(name, args, context = {}) {
|
|
|
1849
1955
|
parentMessages: context.parentMessages,
|
|
1850
1956
|
interaction: context.interaction,
|
|
1851
1957
|
sessionId: context.sessionId || null,
|
|
1958
|
+
turnId: context.turnId || null,
|
|
1959
|
+
toolCallId: context.toolCallId || null,
|
|
1852
1960
|
// Parent LLM config — documented at toolContext as forwarded to
|
|
1853
1961
|
// spawn_sub_agent for provider/key inheritance; without this line it
|
|
1854
1962
|
// never actually reached executeToolInner (sub-agents silently fell
|
|
@@ -2660,6 +2768,8 @@ async function executeToolInner(
|
|
|
2660
2768
|
parentMessages,
|
|
2661
2769
|
interaction,
|
|
2662
2770
|
sessionId,
|
|
2771
|
+
turnId,
|
|
2772
|
+
toolCallId,
|
|
2663
2773
|
hostManagedToolPolicy,
|
|
2664
2774
|
externalToolDescriptors,
|
|
2665
2775
|
externalToolExecutors,
|
|
@@ -3883,16 +3993,62 @@ async function executeToolInner(
|
|
|
3883
3993
|
multiSelect: args.multiSelect === true,
|
|
3884
3994
|
timeoutMs:
|
|
3885
3995
|
typeof args.timeoutMs === "number" ? args.timeoutMs : 60000,
|
|
3996
|
+
defaultValue: args.defaultValue,
|
|
3997
|
+
onTimeout: args.onTimeout || "error",
|
|
3998
|
+
onReject: args.onReject || "error",
|
|
3886
3999
|
sessionId,
|
|
4000
|
+
turnId,
|
|
4001
|
+
toolUseId: toolCallId,
|
|
3887
4002
|
});
|
|
3888
4003
|
return attachDescriptor({ answer });
|
|
3889
4004
|
} catch (err) {
|
|
3890
|
-
|
|
4005
|
+
const failureKind =
|
|
4006
|
+
err?.code === "USER_TIMEOUT"
|
|
4007
|
+
? "timeout"
|
|
4008
|
+
: [
|
|
4009
|
+
"USER_REJECTED",
|
|
4010
|
+
"INTERACTION_REJECTED",
|
|
4011
|
+
"INTERACTION_CANCELLED",
|
|
4012
|
+
].includes(err?.code)
|
|
4013
|
+
? "reject"
|
|
4014
|
+
: null;
|
|
4015
|
+
const strategy =
|
|
4016
|
+
failureKind === "timeout"
|
|
4017
|
+
? args.onTimeout || "error"
|
|
4018
|
+
: failureKind === "reject"
|
|
4019
|
+
? args.onReject || "error"
|
|
4020
|
+
: "error";
|
|
4021
|
+
if (failureKind && strategy === "useDefault") {
|
|
4022
|
+
if (!Object.prototype.hasOwnProperty.call(args, "defaultValue")) {
|
|
4023
|
+
return attachDescriptor({
|
|
4024
|
+
error: `${failureKind === "timeout" ? "user_timeout" : "user_rejected"}: useDefault requires defaultValue`,
|
|
4025
|
+
});
|
|
4026
|
+
}
|
|
4027
|
+
return attachDescriptor({
|
|
4028
|
+
answer: args.defaultValue,
|
|
4029
|
+
fallback: "default",
|
|
4030
|
+
reason: failureKind,
|
|
4031
|
+
});
|
|
4032
|
+
}
|
|
4033
|
+
if (failureKind && strategy === "skip") {
|
|
4034
|
+
return attachDescriptor({
|
|
4035
|
+
answer: null,
|
|
4036
|
+
skipped: true,
|
|
4037
|
+
reason: failureKind,
|
|
4038
|
+
});
|
|
4039
|
+
}
|
|
4040
|
+
if (failureKind === "timeout") {
|
|
3891
4041
|
return attachDescriptor({
|
|
3892
4042
|
error: "user_timeout",
|
|
3893
4043
|
hint: "User did not respond in time. Proceed with best judgement.",
|
|
3894
4044
|
});
|
|
3895
4045
|
}
|
|
4046
|
+
if (failureKind === "reject") {
|
|
4047
|
+
return attachDescriptor({
|
|
4048
|
+
error: "user_rejected",
|
|
4049
|
+
hint: "The user declined this question. Do not assume consent.",
|
|
4050
|
+
});
|
|
4051
|
+
}
|
|
3896
4052
|
return attachDescriptor({
|
|
3897
4053
|
error: `ask_user_question failed: ${err.message}`,
|
|
3898
4054
|
});
|
|
@@ -4421,7 +4577,7 @@ async function executeToolInner(
|
|
|
4421
4577
|
: "No skills found. Make sure you're in the ChainlessChain project root or have skills installed.",
|
|
4422
4578
|
});
|
|
4423
4579
|
}
|
|
4424
|
-
|
|
4580
|
+
let match = allSkills.find(
|
|
4425
4581
|
(s) => s.id === args.skill_name || s.dirName === args.skill_name,
|
|
4426
4582
|
);
|
|
4427
4583
|
if (!match || !match.hasHandler) {
|
|
@@ -4429,6 +4585,20 @@ async function executeToolInner(
|
|
|
4429
4585
|
error: `Skill "${args.skill_name}" not found or has no handler. Use list_skills to see available skills.`,
|
|
4430
4586
|
});
|
|
4431
4587
|
}
|
|
4588
|
+
try {
|
|
4589
|
+
if (typeof skillLoader.materializeSkill === "function") {
|
|
4590
|
+
match = skillLoader.materializeSkill(match, {
|
|
4591
|
+
sessionId,
|
|
4592
|
+
turnId,
|
|
4593
|
+
loadedBecause: "run_skill",
|
|
4594
|
+
bodyIncluded: false,
|
|
4595
|
+
});
|
|
4596
|
+
}
|
|
4597
|
+
} catch (error) {
|
|
4598
|
+
return attachDescriptor({
|
|
4599
|
+
error: `Skill "${args.skill_name}" body could not be loaded: ${error.message}`,
|
|
4600
|
+
});
|
|
4601
|
+
}
|
|
4432
4602
|
|
|
4433
4603
|
// Check if skill requests isolation (via SKILL.md frontmatter)
|
|
4434
4604
|
const skillIsolation = match.isolation === true;
|
|
@@ -4534,6 +4704,7 @@ async function executeToolInner(
|
|
|
4534
4704
|
const taskContext = {
|
|
4535
4705
|
projectRoot: cwd,
|
|
4536
4706
|
workspacePath: cwd,
|
|
4707
|
+
processBroker: createSkillProcessBroker(match),
|
|
4537
4708
|
// Expose the MCP client + mounted servers so the skill handler
|
|
4538
4709
|
// can call MCP tools directly without going through the agent
|
|
4539
4710
|
// loop. Handlers that don't need MCP can ignore these.
|
|
@@ -4586,6 +4757,11 @@ async function executeToolInner(
|
|
|
4586
4757
|
s.category.toLowerCase().includes(q),
|
|
4587
4758
|
);
|
|
4588
4759
|
}
|
|
4760
|
+
skillLoader.recordDescriptorUse?.(skills, {
|
|
4761
|
+
sessionId,
|
|
4762
|
+
turnId,
|
|
4763
|
+
loadedBecause: "list_skills",
|
|
4764
|
+
});
|
|
4589
4765
|
return attachDescriptor({
|
|
4590
4766
|
count: skills.length,
|
|
4591
4767
|
skills: skills.map((s) => ({
|
|
@@ -5121,6 +5297,55 @@ export function safeStringifyToolResult(value) {
|
|
|
5121
5297
|
}
|
|
5122
5298
|
}
|
|
5123
5299
|
|
|
5300
|
+
function emitToolHookLifecycle({
|
|
5301
|
+
tool,
|
|
5302
|
+
args,
|
|
5303
|
+
result,
|
|
5304
|
+
error = null,
|
|
5305
|
+
sessionId = null,
|
|
5306
|
+
turnId = null,
|
|
5307
|
+
toolUseId = null,
|
|
5308
|
+
cwd = process.cwd(),
|
|
5309
|
+
}) {
|
|
5310
|
+
const failed = Boolean(error || result?.error);
|
|
5311
|
+
const base = {
|
|
5312
|
+
schema_version: 1,
|
|
5313
|
+
session_id: sessionId,
|
|
5314
|
+
turn_id: turnId,
|
|
5315
|
+
tool_use_id: toolUseId,
|
|
5316
|
+
tool_name: tool,
|
|
5317
|
+
duration_ms: Number(result?.toolTelemetryRecord?.durationMs || 0),
|
|
5318
|
+
cwd,
|
|
5319
|
+
};
|
|
5320
|
+
emitHooksV2Event(failed ? "PostToolUseFailure" : "PostToolUse", {
|
|
5321
|
+
...base,
|
|
5322
|
+
...(failed
|
|
5323
|
+
? {
|
|
5324
|
+
error_code:
|
|
5325
|
+
result?.error?.code ||
|
|
5326
|
+
result?.code ||
|
|
5327
|
+
(typeof error === "object" ? error?.code : null) ||
|
|
5328
|
+
"tool_error",
|
|
5329
|
+
}
|
|
5330
|
+
: {}),
|
|
5331
|
+
});
|
|
5332
|
+
if (!failed && GUARDED_FILE_MUTATION_TOOLS.has(tool)) {
|
|
5333
|
+
const changedPath =
|
|
5334
|
+
args?.path ||
|
|
5335
|
+
args?.filePath ||
|
|
5336
|
+
args?.file_path ||
|
|
5337
|
+
args?.targetPath ||
|
|
5338
|
+
args?.target_path ||
|
|
5339
|
+
null;
|
|
5340
|
+
emitHooksV2Event("FileChanged", {
|
|
5341
|
+
...base,
|
|
5342
|
+
path: changedPath == null ? null : String(changedPath),
|
|
5343
|
+
operation: tool,
|
|
5344
|
+
});
|
|
5345
|
+
}
|
|
5346
|
+
return failed;
|
|
5347
|
+
}
|
|
5348
|
+
|
|
5124
5349
|
/**
|
|
5125
5350
|
* Execute a spawn_sub_agent tool call.
|
|
5126
5351
|
* Creates an isolated SubAgentContext, runs it, and returns only the summary.
|
|
@@ -5784,6 +6009,8 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
5784
6009
|
outcome: null,
|
|
5785
6010
|
hookFeedback: null,
|
|
5786
6011
|
promise: null,
|
|
6012
|
+
recoveryBinding: () =>
|
|
6013
|
+
subCtx.recoveryBinding(entry.outcome?.result || null),
|
|
5787
6014
|
};
|
|
5788
6015
|
// Settle-capture wrapper: the stored promise NEVER rejects, so an
|
|
5789
6016
|
// unconsumed handle can't surface as an unhandled rejection.
|
|
@@ -5830,6 +6057,7 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
5830
6057
|
subAgentId: subCtx.id,
|
|
5831
6058
|
role: subCtx.role,
|
|
5832
6059
|
parentSessionId,
|
|
6060
|
+
childBinding: subCtx.recoveryBinding(),
|
|
5833
6061
|
note: "Sub-agent is running in the background. Its result will be delivered to you automatically in a later turn — continue with other work; the run will not finish before the result arrives.",
|
|
5834
6062
|
};
|
|
5835
6063
|
}
|
|
@@ -5877,6 +6105,7 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
5877
6105
|
subAgentId: subCtx.id,
|
|
5878
6106
|
role: subCtx.role,
|
|
5879
6107
|
parentSessionId,
|
|
6108
|
+
childBinding: subCtx.recoveryBinding(result),
|
|
5880
6109
|
summary: result.summary,
|
|
5881
6110
|
toolsUsed: result.toolsUsed,
|
|
5882
6111
|
iterationCount: result.iterationCount,
|
|
@@ -5908,6 +6137,7 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
5908
6137
|
subAgentId: subCtx.id,
|
|
5909
6138
|
role: subCtx.role,
|
|
5910
6139
|
parentSessionId,
|
|
6140
|
+
childBinding: subCtx.recoveryBinding(subCtx.result),
|
|
5911
6141
|
};
|
|
5912
6142
|
}
|
|
5913
6143
|
}
|
|
@@ -5998,7 +6228,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
5998
6228
|
}),
|
|
5999
6229
|
});
|
|
6000
6230
|
if (!response.ok) {
|
|
6001
|
-
throw new Error(
|
|
6231
|
+
throw new Error(await formatProviderResponseError("ollama", response));
|
|
6002
6232
|
}
|
|
6003
6233
|
const data = await response.json();
|
|
6004
6234
|
if (data.prompt_eval_count || data.eval_count) {
|
|
@@ -6125,7 +6355,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
6125
6355
|
});
|
|
6126
6356
|
|
|
6127
6357
|
if (!response.ok) {
|
|
6128
|
-
throw new Error(
|
|
6358
|
+
throw new Error(await formatProviderResponseError("anthropic", response));
|
|
6129
6359
|
}
|
|
6130
6360
|
|
|
6131
6361
|
const data = await response.json();
|
|
@@ -6232,7 +6462,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
6232
6462
|
});
|
|
6233
6463
|
|
|
6234
6464
|
if (!response.ok) {
|
|
6235
|
-
throw new Error(
|
|
6465
|
+
throw new Error(await formatProviderResponseError(provider, response));
|
|
6236
6466
|
}
|
|
6237
6467
|
|
|
6238
6468
|
const data = await response.json();
|
|
@@ -6355,23 +6585,9 @@ export function _streamErrorDisposition(err, signal, partialText) {
|
|
|
6355
6585
|
* means a missing/invalid API key for the ACTIVE provider — and because the
|
|
6356
6586
|
* provider is resolved from config, a surprise "anthropic 401" usually means
|
|
6357
6587
|
* the effective provider differs from what the user configured. Name the
|
|
6358
|
-
* provider and point at the
|
|
6359
|
-
* exported for tests.
|
|
6588
|
+
* provider and point at the appropriate key, billing, or permission fix
|
|
6589
|
+
* instead of dumping a bare status code. Pure + exported for tests.
|
|
6360
6590
|
*/
|
|
6361
|
-
export function formatProviderHttpError(provider, status) {
|
|
6362
|
-
const base = `${provider} API error: HTTP ${status}`;
|
|
6363
|
-
if (status === 401 || status === 403) {
|
|
6364
|
-
return (
|
|
6365
|
-
`${base} — authentication failed: the API key for provider "${provider}" ` +
|
|
6366
|
-
`is missing or invalid. Check "cc config get llm.provider" and ` +
|
|
6367
|
-
`"cc config get llm.apiKey" (or run Configure LLM). A surprise "${provider}" ` +
|
|
6368
|
-
`here usually means the effective provider differs from the one you configured.`
|
|
6369
|
-
);
|
|
6370
|
-
}
|
|
6371
|
-
if (status === 429) return `${base} — rate limited; please retry shortly.`;
|
|
6372
|
-
return base;
|
|
6373
|
-
}
|
|
6374
|
-
|
|
6375
6591
|
/**
|
|
6376
6592
|
* Is this error from a streaming chat request a transient API CONNECTION drop
|
|
6377
6593
|
* that is safe to retry? True only for genuine network failures (reset /
|
|
@@ -6565,7 +6781,7 @@ async function _chatOllamaStreaming(
|
|
|
6565
6781
|
body: JSON.stringify({ ...body, stream: true }),
|
|
6566
6782
|
});
|
|
6567
6783
|
if (!response.ok) {
|
|
6568
|
-
throw new Error(
|
|
6784
|
+
throw new Error(await formatProviderResponseError("ollama", response));
|
|
6569
6785
|
}
|
|
6570
6786
|
const state = _ollamaInitState();
|
|
6571
6787
|
const reader = response.body.getReader();
|
|
@@ -6751,7 +6967,7 @@ async function _chatAnthropicStreaming(
|
|
|
6751
6967
|
body: JSON.stringify(body),
|
|
6752
6968
|
});
|
|
6753
6969
|
if (!response.ok) {
|
|
6754
|
-
throw new Error(
|
|
6970
|
+
throw new Error(await formatProviderResponseError("anthropic", response));
|
|
6755
6971
|
}
|
|
6756
6972
|
const state = _anthropicInitState();
|
|
6757
6973
|
const reader = response.body.getReader();
|
|
@@ -6903,7 +7119,7 @@ async function _chatOpenAIStreaming(
|
|
|
6903
7119
|
body: JSON.stringify(body),
|
|
6904
7120
|
});
|
|
6905
7121
|
if (!response.ok) {
|
|
6906
|
-
throw new Error(
|
|
7122
|
+
throw new Error(await formatProviderResponseError(provider, response));
|
|
6907
7123
|
}
|
|
6908
7124
|
const state = _openaiInitState();
|
|
6909
7125
|
const reader = response.body.getReader();
|
|
@@ -7333,6 +7549,10 @@ export async function* agentLoop(messages, options) {
|
|
|
7333
7549
|
cwd: options.cwd || process.cwd(),
|
|
7334
7550
|
planManager: options.planManager || null,
|
|
7335
7551
|
sessionId: options.sessionId || null,
|
|
7552
|
+
// One agentLoop invocation represents one user turn even when it performs
|
|
7553
|
+
// several model/tool iterations. Hosts may supply their persisted turn id;
|
|
7554
|
+
// otherwise the run id is the stable in-process binding.
|
|
7555
|
+
turnId: options.turnId || runId,
|
|
7336
7556
|
hostManagedToolPolicy: options.hostManagedToolPolicy || null,
|
|
7337
7557
|
externalToolDescriptors: options.externalToolDescriptors || null,
|
|
7338
7558
|
externalToolExecutors: options.externalToolExecutors || null,
|
|
@@ -7762,6 +7982,7 @@ export async function* agentLoop(messages, options) {
|
|
|
7762
7982
|
role: entry.role,
|
|
7763
7983
|
error: entry.outcome?.error || null,
|
|
7764
7984
|
summary: entry.outcome?.result?.summary || null,
|
|
7985
|
+
childBinding: entry.recoveryBinding?.() || null,
|
|
7765
7986
|
};
|
|
7766
7987
|
}
|
|
7767
7988
|
}
|
|
@@ -7905,6 +8126,7 @@ export async function* agentLoop(messages, options) {
|
|
|
7905
8126
|
role: entry.role,
|
|
7906
8127
|
error: entry.outcome?.error || null,
|
|
7907
8128
|
summary: entry.outcome?.result?.summary || null,
|
|
8129
|
+
childBinding: entry.recoveryBinding?.() || null,
|
|
7908
8130
|
};
|
|
7909
8131
|
}
|
|
7910
8132
|
continue;
|
|
@@ -8050,6 +8272,8 @@ export async function* agentLoop(messages, options) {
|
|
|
8050
8272
|
type: "tool-executing",
|
|
8051
8273
|
tool: call.function.name,
|
|
8052
8274
|
args: toolArgs,
|
|
8275
|
+
tool_use_id: call.id,
|
|
8276
|
+
turn_id: `${runId}:t${budget.consumed}`,
|
|
8053
8277
|
};
|
|
8054
8278
|
const { result: toolResult, error: toolError } = await promise;
|
|
8055
8279
|
throwIfAborted(signal);
|
|
@@ -8065,6 +8289,12 @@ export async function* agentLoop(messages, options) {
|
|
|
8065
8289
|
tool: call.function.name,
|
|
8066
8290
|
result: toolResult,
|
|
8067
8291
|
error: toolError,
|
|
8292
|
+
tool_use_id: call.id,
|
|
8293
|
+
turn_id: `${runId}:t${budget.consumed}`,
|
|
8294
|
+
permission_decision_id: permissionDecisionId(
|
|
8295
|
+
call.id,
|
|
8296
|
+
toolResult?.policy,
|
|
8297
|
+
),
|
|
8068
8298
|
};
|
|
8069
8299
|
messages.push({
|
|
8070
8300
|
role: "tool",
|
|
@@ -8093,6 +8323,8 @@ export async function* agentLoop(messages, options) {
|
|
|
8093
8323
|
tool: "(unknown)",
|
|
8094
8324
|
result: { error: reason },
|
|
8095
8325
|
error: reason,
|
|
8326
|
+
tool_use_id: call?.id || null,
|
|
8327
|
+
turn_id: `${runId}:t${budget.consumed}`,
|
|
8096
8328
|
};
|
|
8097
8329
|
messages.push({
|
|
8098
8330
|
role: "tool",
|
|
@@ -8119,9 +8351,22 @@ export async function* agentLoop(messages, options) {
|
|
|
8119
8351
|
toolName,
|
|
8120
8352
|
toolArgs,
|
|
8121
8353
|
);
|
|
8122
|
-
if (cpId)
|
|
8354
|
+
if (cpId)
|
|
8355
|
+
yield {
|
|
8356
|
+
type: "checkpoint",
|
|
8357
|
+
id: cpId,
|
|
8358
|
+
tool: toolName,
|
|
8359
|
+
tool_use_id: call.id,
|
|
8360
|
+
turn_id: `${runId}:t${budget.consumed}`,
|
|
8361
|
+
};
|
|
8123
8362
|
|
|
8124
|
-
yield {
|
|
8363
|
+
yield {
|
|
8364
|
+
type: "tool-executing",
|
|
8365
|
+
tool: toolName,
|
|
8366
|
+
args: toolArgs,
|
|
8367
|
+
tool_use_id: call.id,
|
|
8368
|
+
turn_id: `${runId}:t${budget.consumed}`,
|
|
8369
|
+
};
|
|
8125
8370
|
|
|
8126
8371
|
let toolResult;
|
|
8127
8372
|
let toolError = null;
|
|
@@ -8218,6 +8463,12 @@ export async function* agentLoop(messages, options) {
|
|
|
8218
8463
|
tool: toolName,
|
|
8219
8464
|
result: toolResult,
|
|
8220
8465
|
error: toolError,
|
|
8466
|
+
tool_use_id: call.id,
|
|
8467
|
+
turn_id: `${runId}:t${budget.consumed}`,
|
|
8468
|
+
permission_decision_id: permissionDecisionId(
|
|
8469
|
+
call.id,
|
|
8470
|
+
toolResult?.policy,
|
|
8471
|
+
),
|
|
8221
8472
|
};
|
|
8222
8473
|
|
|
8223
8474
|
messages.push({
|
|
@@ -876,6 +876,22 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
|
|
|
876
876
|
type: "number",
|
|
877
877
|
description: "Max wait for user reply in ms (default: 60000)",
|
|
878
878
|
},
|
|
879
|
+
defaultValue: {
|
|
880
|
+
description:
|
|
881
|
+
"Fallback answer used only when onTimeout/onReject is useDefault",
|
|
882
|
+
},
|
|
883
|
+
onTimeout: {
|
|
884
|
+
type: "string",
|
|
885
|
+
enum: ["error", "useDefault", "skip"],
|
|
886
|
+
description:
|
|
887
|
+
"Timeout policy: error (default), useDefault, or skip with a null answer",
|
|
888
|
+
},
|
|
889
|
+
onReject: {
|
|
890
|
+
type: "string",
|
|
891
|
+
enum: ["error", "useDefault", "skip"],
|
|
892
|
+
description:
|
|
893
|
+
"User-rejection policy: error (default), useDefault, or skip with a null answer",
|
|
894
|
+
},
|
|
879
895
|
},
|
|
880
896
|
required: ["question"],
|
|
881
897
|
},
|