chainlesschain 0.166.46 → 0.166.48
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 +6 -4
- package/package.json +4 -2
- package/src/assets/web-panel/assets/{AIOps-Cp8KiMmv.js → AIOps-BLGEffkh.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-B4d9BGsm.js → ActionButton-Cz1z2VGD.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Cf9yXTkv.js → Analytics-C3j9cf6q.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-40UkmxtP.js → AppLayout-BR9ERuCA.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-Ckkb4oOA.js → Artifacts-CozJCm4y.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-Dnf569k5.js → Audit-DC5g9Ra2.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-CA6bLem4.js → BackgroundAgents-B1zrQ0dW.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-ChQU0I_Q.js → Backup-ChVnfjpm.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BHeZXnNN.js → BaseInput-8_vLQsLf.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DcFVYB2E.js → Chat-Dct9bm6L.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BvoSsCKh.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-2PDbejv2.js → Checkbox-DZQIsCIC.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DJBn1RAu.js → Codegen-CdzHxmnq.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CPRq7n6y.js → Col-DdAN8LeW.js} +1 -1
- package/src/assets/web-panel/assets/{Community-axvINFMi.js → Community-CNgjT9MA.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-_OX4Qbe0.js → Compact-BtQiX6G-.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DWAkvzRL.js → Compliance-OGX5ma3j.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CUIJ25oj.js → Cowork-CgugQnGM.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-nR0m7H3_.js → Cron-Bpg7cPFD.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CgTLXzh_.js → Crosschain-D1hsuswf.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BllzRB6Q.js → DID-miDRsMBw.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-C9f0IIBN.js → Dashboard-CGcl8htP.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BkahetiO.js → Dropdown-BFaxTdVE.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-rartVC-k.js → EmailListRenderer-BQdGLZIO.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-BqpG3XHV.js → EvolutionSettings-bMvgBk6r.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DgUdFvw1.js → FamilyGuardDashboard-c1WVC_--.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-oFpIQU6g.js → Federation-DyAcFrQY.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BUH5xlyP.js → FormItemContext-CfwpfD2B.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-ilRa-ueg.js → GenericCardRenderer-DkJcbBpS.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DlHHSF8j.js → Git-DgYIrPJh.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-yQiiXIWe.js → Governance-BF1tYPJ6.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BUDRVGOP.js → Inference-BFkwRIrU.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BaGyIoN1.js → KnowledgeGraph-DpCoqhBa.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-C1cO6zE0.js → Logs-DU2qAJmD.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-_z_Iaoes.js → MarkdownRenderer-QWv7UJLq.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CM8cGL0K.js → Marketplace-Dz9NUrfo.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CDqAMU0U.js → McpTools-B67I3d5v.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-CfB0-Ofv.js → Memory-crkElJSy.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BL18ytvB.js → MobileBridge-BO20VbdX.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-PIyyxbuJ.js → MobileProjects-Ba-3gZZd.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BTTrFCol.js → Mtc-BAHZM084.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-JHZn037c.js → MtcAudit-CL3DzajL.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-CMf9NEdB.js → Multisig-BSWWzvWH.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Dhk3qaus.js → NLProgramming-fnxqXM_3.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-6F8EarNN.js → Notes-qUZPIQXT.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-gxdaVEit.js → NotificationSettings-x9Xrixqu.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-gVgXQWdc.js → OrderTableRenderer-BtMtQUt7.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CzvHcDNO.js → Organization-C946Hzna.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Dclx30Vv.js → Overflow-BYf8KIts.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CM0Wm9vZ.js → P2P-Cbqf5dnv.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-rmxp0cuF.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-B_oATenG.js → Permissions-CZBw45EW.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-CptiVBh5.js → PersonalDataHub-BKwUAt43.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-DkHzgyyI.js → Pipeline-DmFD2QW4.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DzZvwcKh.js → Privacy-KpuwWvt5.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CzkCs-5G.js → ProjectInit-Bt8UheX6.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BB8dcxRD.js → ProjectSettings-2ZeAn9CP.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-B7PW9CFY.js → Projects-zBuet8Zs.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-Tfx-ti1V.js → Providers-DcEAnw6L.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-EvWlNhfX.js → QrScannerModal-qF7liYG9.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CUspgbNC.js → QuickAsk-qiESlVBJ.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-COY2g77J.js → Recommend-Bk-cQyi9.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BzMBU6E6.js → RemoteSession-CwrekErS.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-RtYRF4YP.js → Reputation-Bmw_UQtW.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Bva3l9Lc.js → Row-CPdqZIUX.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BhjzLvW3.js → RssFeed-D_W-xxvS.js} +2 -2
- package/src/assets/web-panel/assets/{Search-BYzT2PTR.js → Search-Hu0oDFj_.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Bcl4-KTv.js → Security-DeRxUwmq.js} +3 -3
- package/src/assets/web-panel/assets/{Services-BRRa4A0f.js → Services-CsNmHFkf.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DYQ016qy.js → Skeleton-gv_Vz0tN.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CAUKL9JA.js → Skills-Dgg-_rCB.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BTyUqfuD.js → Sla-Bpu-bsEJ.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CUjMihrs.js → SpeechSettings-CrhleHuF.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CvfOSupr.js → SyncSettings-JHjUN6I9.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-EvjNXrWH.js → Tasks-DKRWKkl9.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-wPAp0EoM.js → Templates-leiWntLq.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CP0D-q9Q.js → Tenant--1bYulvn.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CQ0f2iFg.js → Terminal-C0y6FvSS.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-D3JrGSPb.js → TimelineRenderer-CQK4PVv4.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-yXf2PPp9.js → Tokens-DbIvF-DV.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DfmMOoZ2.js → Trigger-CkXJ2vuq.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BTCyMgf1.js → Trust-B02WXJPw.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DKCwIBHi.js → UkeySign-VPMkfzmw.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CQpDSzLO.js → VideoEditing-C5ezUnah.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CyFrzC3K.js → Wallet-CYfvYRrY.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-D6Nr_1kd.js → WebAuthn-DtKl-kpr.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-CgR9tNrB.js → WorkflowEditor-DACITF-u.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CRG_IeyP.js → chat-qnygfnLi.js} +1 -1
- package/src/assets/web-panel/assets/{colors-MdE3TStI.js → colors-D4mISLBD.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-B0LRuiNV.js → compact-item-BBPfxYGL.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-B_V5fjcX.js → createContext-Byx4ndHp.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DBy6gsuI.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DSL-c_hr.js → hasIn-CGjLkkn3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DE7bSYmW.js → index-B8UpadHC.js} +1 -1
- package/src/assets/web-panel/assets/{index-BD0w-888.js → index-B9jH-h4X.js} +1 -1
- package/src/assets/web-panel/assets/{index-BbZZ7P_c.js → index-BN7_TSgU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BIDCNwy6.js → index-BNe2lCk6.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkN53KiJ.js → index-B_fHPZ8E.js} +1 -1
- package/src/assets/web-panel/assets/index-BfEDXk_E.js +1 -0
- package/src/assets/web-panel/assets/{index-BsAEd-Do.js → index-BklGH3YI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CS3bOhV7.js → index-BmKYaaGP.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3iW-mhn.js → index-BxQF1wCU.js} +1 -1
- package/src/assets/web-panel/assets/{index-SmQfEHjp.js → index-ByA1NyFP.js} +1 -1
- package/src/assets/web-panel/assets/{index-0200QxC4.js → index-BzeBBAl5.js} +1 -1
- package/src/assets/web-panel/assets/{index-c8OqO3rq.js → index-C3abGsSW.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-aKWR2v.js → index-C9tcHs46.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNhWoD6d.js → index-CD5Btq6p.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVDi4rS9.js → index-CFMWjuav.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEOAZm5j.js → index-CMj8qmpX.js} +1 -1
- package/src/assets/web-panel/assets/{index-C67dPW0L.js → index-CVUJjQAT.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3pJBTvo.js → index-CWhI8G14.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtOTppk8.js → index-CZjNamSU.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRRY44XP.js → index-CmHE-lY_.js} +1 -1
- package/src/assets/web-panel/assets/{index-Tg3yl8wc.js → index-CoA8WsVr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXMeisJK.js → index-Cpg3AWRy.js} +1 -1
- package/src/assets/web-panel/assets/index-CrxUwNM8.js +1 -0
- package/src/assets/web-panel/assets/{index-Bq8-2Ibv.js → index-CsVuQsY1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHp1nSur.js → index-CydHMjwc.js} +1 -1
- package/src/assets/web-panel/assets/{index-CPYshcic.js → index-DH6iC5b2.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBwBZwio.js → index-DZXhKAk9.js} +1 -1
- package/src/assets/web-panel/assets/{index-Didyuq2Z.js → index-D_g9mA1N.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdHMc9LQ.js → index-DboTeuPF.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5dqieYX.js → index-DfgpKd64.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdplnAS9.js → index-Dmfe0L2Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-KaSejHjf.js → index-Dzni_5Qw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpwGsAA-.js → index-J5JkStvY.js} +1 -1
- package/src/assets/web-panel/assets/{index-OBhlHSMN.js → index-Ne8UGllV.js} +3 -3
- package/src/assets/web-panel/assets/{index-CZICtYJ0.js → index-O09jXbir.js} +1 -1
- package/src/assets/web-panel/assets/{index-DVgTf7CZ.js → index-Y7el_3WS.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQAsL19t.js → index-c_tBkIlU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BMm8tO2X.js → index-lKJWAmd4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNytQuFq.js → index-xzRKTy0R.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-P8SBN6Di.js → initDefaultProps-XuhfEIhB.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BubbjUT_.js → motion-Cbxh6AxO.js} +1 -1
- package/src/assets/web-panel/assets/{move-Chcykv0I.js → move-C7IEnFly.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DyiYuGDu.js → mtc-parser-lLADx4LL.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Rdwb_Neb.js → omit-mIbic_k-.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CCr0MYHl.js → pickAttrs-_xIYEqu3.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B1ZXz3bb.js → placementArrow-ClB-E0ny.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BGEdwej6.js → responsiveObserve-D36Bg2ut.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CpnsUMaT.js → slide-CUuO08Bl.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-C7x-TVp_.js → statusUtils-BKahwLbv.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CC5k_791.js → styleChecker-2pT-T8vy.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BpZFKsJW.js → useFlexGapSupport-DyH5g7Rg.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CVq5HySy.js → useFs-CTOauB3X.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BGkdLryu.js → usePersonalDataHub-B02JYIMe.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-uLtOUEK-.js → vnode-Do22wQrc.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BfVC9iUs.js → zoom-BfnL7rit.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +8 -0
- package/src/commands/background-session.js +31 -3
- package/src/commands/chat.js +5 -1
- package/src/commands/eval.js +86 -28
- package/src/commands/llm.js +104 -1
- package/src/commands/plugin.js +161 -1
- package/src/commands/sandbox.js +121 -2
- package/src/commands/serve.js +11 -2
- package/src/commands/skill.js +29 -0
- package/src/data/changelog.json +26 -0
- package/src/gateways/ws/session-protocol.js +13 -0
- package/src/gateways/ws/ws-agent-handler.js +17 -0
- package/src/gateways/ws/ws-server.js +3 -0
- package/src/gateways/ws/ws-session-state.js +131 -0
- package/src/generated/cc-agent-protocol.schema.json +48 -1
- package/src/lazy-dispatch.js +8 -1
- package/src/lib/agent-sandbox.js +337 -53
- package/src/lib/app-server/cli-agent-kernel-adapter.js +28 -0
- package/src/lib/app-server/server.js +93 -0
- package/src/lib/background-agent-keeper-client.js +2 -0
- package/src/lib/background-agent-keeper-protocol.js +7 -0
- package/src/lib/background-agent-list-index.js +222 -0
- package/src/lib/background-agent-supervisor.js +232 -47
- package/src/lib/codex-app-server-adapter.js +82 -27
- package/src/lib/context-memory-kernel/durable-memory-port.js +31 -8
- package/src/lib/context-memory-kernel/provider-context.js +118 -19
- package/src/lib/deferred-question-context.js +278 -0
- package/src/lib/eval/evidence.js +202 -64
- package/src/lib/eval/plugin-suite.js +1181 -0
- package/src/lib/eval/runner.js +10 -3
- package/src/lib/evolution/agent-evolution-runtime-composition.js +236 -1
- package/src/lib/evolution/agent-model-projection.js +97 -1
- package/src/lib/evolution/evidence-backed-wiki-maintainer.js +154 -1
- package/src/lib/evolution/evolution-artifact-ports.js +6 -0
- package/src/lib/evolution/evolution-deployment-loader.js +87 -3
- package/src/lib/evolution/evolution-eval-gate.js +8 -0
- package/src/lib/evolution/evolution-eval-runtime-composition.js +255 -0
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +58 -2
- package/src/lib/evolution/evolution-ledger-file-backend.js +23 -2
- package/src/lib/evolution/evolution-ledger-manifest-chain.js +223 -7
- package/src/lib/evolution/evolution-ledger-v2-journal.js +525 -0
- package/src/lib/evolution/evolution-ledger-v2-manifest-backend.js +46 -2
- package/src/lib/evolution/evolution-ledger.js +57 -1
- package/src/lib/evolution/evolution-run-ledger-adapter.js +93 -0
- package/src/lib/evolution/evolution-run-wiki-evidence-resolver.js +259 -0
- package/src/lib/evolution/governed-hub-llm.js +238 -5
- package/src/lib/evolution/governed-hub-resolver.js +82 -4
- package/src/lib/evolution/governed-hub-skill.js +11 -5
- package/src/lib/evolution/governed-skill-synthesis-provider-chat.js +10 -1
- package/src/lib/evolution/skill-runtime-revalidation-ledger-adapter.js +254 -0
- package/src/lib/evolution/skill-runtime-revalidation.js +530 -0
- package/src/lib/evolution/skill-target-matrix-eval.js +4 -4
- package/src/lib/evolution/wiki-evidence-commit-guard.js +366 -0
- package/src/lib/evolution/wiki-informed-skill-proposer.js +13 -1
- package/src/lib/goal-context.js +14 -5
- package/src/lib/interaction-adapter.js +166 -1
- package/src/lib/model-capabilities.js +271 -0
- package/src/lib/model-context-catalog.js +105 -0
- package/src/lib/model-context-window.js +4 -49
- package/src/lib/openai-responses.js +428 -0
- package/src/lib/plugin-runtime/scopes.js +7 -1
- package/src/lib/remote-read-loop-guard.js +2 -2
- package/src/lib/runtime-usage-ledger.js +16 -0
- package/src/lib/session-host-snapshot.js +16 -0
- package/src/lib/skill-loader.js +12 -0
- package/src/lib/with-file-lock.js +3 -1
- package/src/repl/agent-repl.js +5 -1
- package/src/runtime/agent-core.js +348 -23
- package/src/runtime/agent-runtime.js +7 -0
- package/src/runtime/coding-agent-contract-shared.cjs +13 -1
- package/src/runtime/headless-runner.js +4 -1
- package/src/runtime/headless-stream.js +283 -45
- package/src/runtime/runtime-factory.js +26 -2
- package/src/workers/background-agent-keeper.js +23 -13
- package/src/workers/background-agent-worker.js +27 -13
- package/src/assets/web-panel/assets/ChatBubbleRenderer-Bi2SY9E_.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-fYmQzmTA.js +0 -7
- package/src/assets/web-panel/assets/devWarning-BtFLt3qI.js +0 -1
- package/src/assets/web-panel/assets/index-BhuWQHeG.js +0 -1
- package/src/assets/web-panel/assets/index-D-4tFek3.js +0 -1
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
const RESPONSES_FAILURE_CODE = "CC_OPENAI_RESPONSES_FAILED";
|
|
2
|
+
const MAX_REASONING_ITEMS = 16;
|
|
3
|
+
const MAX_REASONING_SUMMARY_CHARS = 8_192;
|
|
4
|
+
|
|
5
|
+
function nonNegativeInteger(value) {
|
|
6
|
+
return Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function printableString(value, fallback = "") {
|
|
10
|
+
return typeof value === "string" ? value : fallback;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function jsonText(value) {
|
|
14
|
+
if (typeof value === "string") return value;
|
|
15
|
+
try {
|
|
16
|
+
const encoded = JSON.stringify(value);
|
|
17
|
+
return typeof encoded === "string" ? encoded : "";
|
|
18
|
+
} catch {
|
|
19
|
+
return String(value ?? "");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function responseFailure(data) {
|
|
24
|
+
const providerCode = printableString(
|
|
25
|
+
data?.error?.code || data?.incomplete_details?.reason || data?.status,
|
|
26
|
+
"unknown",
|
|
27
|
+
).slice(0, 128);
|
|
28
|
+
const error = new Error(`OpenAI Responses request failed (${providerCode})`);
|
|
29
|
+
error.code = RESPONSES_FAILURE_CODE;
|
|
30
|
+
error.providerCode = providerCode;
|
|
31
|
+
return error;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function normalizeImageBlock(block) {
|
|
35
|
+
const imageUrl =
|
|
36
|
+
typeof block?.image_url === "string"
|
|
37
|
+
? block.image_url
|
|
38
|
+
: block?.image_url?.url;
|
|
39
|
+
if (typeof imageUrl !== "string" || !imageUrl) return null;
|
|
40
|
+
return {
|
|
41
|
+
type: "input_image",
|
|
42
|
+
image_url: imageUrl,
|
|
43
|
+
...(typeof block?.image_url?.detail === "string"
|
|
44
|
+
? { detail: block.image_url.detail }
|
|
45
|
+
: typeof block?.detail === "string"
|
|
46
|
+
? { detail: block.detail }
|
|
47
|
+
: {}),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function normalizeMessageContent(content, role) {
|
|
52
|
+
if (!Array.isArray(content)) return jsonText(content);
|
|
53
|
+
const assistant = role === "assistant";
|
|
54
|
+
return content.map((block) => {
|
|
55
|
+
if (block?.type === "image_url" || block?.type === "input_image") {
|
|
56
|
+
return (
|
|
57
|
+
normalizeImageBlock(block) || {
|
|
58
|
+
type: assistant ? "output_text" : "input_text",
|
|
59
|
+
text: "[invalid image input]",
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
if (block?.type === "input_file" && !assistant) return block;
|
|
64
|
+
const text = printableString(
|
|
65
|
+
block?.text ?? block?.refusal,
|
|
66
|
+
jsonText(block),
|
|
67
|
+
);
|
|
68
|
+
return {
|
|
69
|
+
type: assistant ? "output_text" : "input_text",
|
|
70
|
+
text,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function sanitizeReasoningItems(items) {
|
|
76
|
+
if (!Array.isArray(items)) return [];
|
|
77
|
+
const output = [];
|
|
78
|
+
for (const item of items.slice(0, MAX_REASONING_ITEMS)) {
|
|
79
|
+
if (!item || item.type !== "reasoning") continue;
|
|
80
|
+
const id = printableString(item.id);
|
|
81
|
+
const encryptedContent = printableString(item.encrypted_content);
|
|
82
|
+
const status = ["completed", "in_progress", "incomplete"].includes(
|
|
83
|
+
item.status,
|
|
84
|
+
)
|
|
85
|
+
? item.status
|
|
86
|
+
: null;
|
|
87
|
+
const summary = Array.isArray(item.summary)
|
|
88
|
+
? item.summary
|
|
89
|
+
.filter((part) => part?.type === "summary_text")
|
|
90
|
+
.map((part) => ({
|
|
91
|
+
type: "summary_text",
|
|
92
|
+
text: printableString(part.text).slice(
|
|
93
|
+
0,
|
|
94
|
+
MAX_REASONING_SUMMARY_CHARS,
|
|
95
|
+
),
|
|
96
|
+
}))
|
|
97
|
+
: [];
|
|
98
|
+
if (!id && !encryptedContent && summary.length === 0) continue;
|
|
99
|
+
output.push({
|
|
100
|
+
type: "reasoning",
|
|
101
|
+
...(id ? { id } : {}),
|
|
102
|
+
...(encryptedContent ? { encrypted_content: encryptedContent } : {}),
|
|
103
|
+
...(summary.length ? { summary } : {}),
|
|
104
|
+
...(status ? { status } : {}),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return output;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Convert the internal Chat-Completions-shaped history into Responses items. */
|
|
111
|
+
export function toOpenAIResponsesInput(messages) {
|
|
112
|
+
const input = [];
|
|
113
|
+
for (const message of messages || []) {
|
|
114
|
+
if (!message || typeof message !== "object") continue;
|
|
115
|
+
if (message.role === "tool") {
|
|
116
|
+
input.push({
|
|
117
|
+
type: "function_call_output",
|
|
118
|
+
call_id: printableString(message.tool_call_id),
|
|
119
|
+
output: jsonText(message.content),
|
|
120
|
+
});
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (message.role === "assistant") {
|
|
124
|
+
input.push(...sanitizeReasoningItems(message._openaiReasoningItems));
|
|
125
|
+
}
|
|
126
|
+
const content = normalizeMessageContent(message.content, message.role);
|
|
127
|
+
const hasContent = Array.isArray(content)
|
|
128
|
+
? content.length > 0
|
|
129
|
+
: content.length > 0;
|
|
130
|
+
if (hasContent || message.role !== "assistant") {
|
|
131
|
+
input.push({
|
|
132
|
+
role: ["system", "developer", "assistant", "user"].includes(
|
|
133
|
+
message.role,
|
|
134
|
+
)
|
|
135
|
+
? message.role
|
|
136
|
+
: "user",
|
|
137
|
+
content,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if (message.role === "assistant" && Array.isArray(message.tool_calls)) {
|
|
141
|
+
for (const toolCall of message.tool_calls) {
|
|
142
|
+
const name = printableString(toolCall?.function?.name);
|
|
143
|
+
const callId = printableString(toolCall?.id);
|
|
144
|
+
if (!name || !callId) continue;
|
|
145
|
+
input.push({
|
|
146
|
+
type: "function_call",
|
|
147
|
+
call_id: callId,
|
|
148
|
+
name,
|
|
149
|
+
arguments: printableString(toolCall?.function?.arguments, "{}"),
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return input;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Flatten Chat Completions function descriptors into Responses tools. */
|
|
158
|
+
export function toOpenAIResponsesTools(tools) {
|
|
159
|
+
return (tools || [])
|
|
160
|
+
.filter((tool) => tool?.type === "function" && tool.function?.name)
|
|
161
|
+
.map((tool) => ({
|
|
162
|
+
type: "function",
|
|
163
|
+
name: tool.function.name,
|
|
164
|
+
description: printableString(tool.function.description),
|
|
165
|
+
parameters: tool.function.parameters || { type: "object" },
|
|
166
|
+
...(typeof tool.function.strict === "boolean"
|
|
167
|
+
? { strict: tool.function.strict }
|
|
168
|
+
: {}),
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function createOpenAIResponsesBody({
|
|
173
|
+
model,
|
|
174
|
+
messages,
|
|
175
|
+
tools,
|
|
176
|
+
maxOutputTokens = null,
|
|
177
|
+
reasoning = null,
|
|
178
|
+
stream = false,
|
|
179
|
+
}) {
|
|
180
|
+
return {
|
|
181
|
+
model,
|
|
182
|
+
input: toOpenAIResponsesInput(messages),
|
|
183
|
+
tools: toOpenAIResponsesTools(tools),
|
|
184
|
+
store: false,
|
|
185
|
+
include: ["reasoning.encrypted_content"],
|
|
186
|
+
...(maxOutputTokens ? { max_output_tokens: maxOutputTokens } : {}),
|
|
187
|
+
...(reasoning ? { reasoning } : {}),
|
|
188
|
+
...(stream ? { stream: true } : {}),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export function normalizeOpenAIResponsesUsage(usage) {
|
|
193
|
+
if (!usage || typeof usage !== "object" || Array.isArray(usage)) return null;
|
|
194
|
+
const input = nonNegativeInteger(usage.input_tokens);
|
|
195
|
+
const output = nonNegativeInteger(usage.output_tokens);
|
|
196
|
+
if (input === null || output === null) return null;
|
|
197
|
+
const details = usage.input_tokens_details;
|
|
198
|
+
const outputDetails = usage.output_tokens_details;
|
|
199
|
+
let cached = 0;
|
|
200
|
+
let reasoning = null;
|
|
201
|
+
if (details != null) {
|
|
202
|
+
if (typeof details !== "object" || Array.isArray(details)) return null;
|
|
203
|
+
if (Object.hasOwn(details, "cached_tokens")) {
|
|
204
|
+
cached = nonNegativeInteger(details.cached_tokens);
|
|
205
|
+
if (cached === null || cached > input) return null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (outputDetails != null) {
|
|
209
|
+
if (typeof outputDetails !== "object" || Array.isArray(outputDetails)) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
if (Object.hasOwn(outputDetails, "reasoning_tokens")) {
|
|
213
|
+
reasoning = nonNegativeInteger(outputDetails.reasoning_tokens);
|
|
214
|
+
// OpenAI reports reasoning tokens as a subset of output tokens. Keep the
|
|
215
|
+
// dimension independently, but reject impossible usage rather than
|
|
216
|
+
// allowing it to inflate or contradict the billable output total.
|
|
217
|
+
if (reasoning === null || reasoning > output) return null;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
input_tokens: input - cached,
|
|
222
|
+
output_tokens: output,
|
|
223
|
+
cache_read_input_tokens: cached,
|
|
224
|
+
...(reasoning !== null ? { reasoning_tokens: reasoning } : {}),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function responseOutput(data) {
|
|
229
|
+
return Array.isArray(data?.output) ? data.output : [];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Normalize one completed/incomplete Responses object for the existing loop. */
|
|
233
|
+
export function normalizeOpenAIResponsesResponse(data) {
|
|
234
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
235
|
+
throw responseFailure({ status: "invalid_response" });
|
|
236
|
+
}
|
|
237
|
+
if (data.error || ["failed", "cancelled"].includes(data.status)) {
|
|
238
|
+
throw responseFailure(data);
|
|
239
|
+
}
|
|
240
|
+
if (data.status && !["completed", "incomplete"].includes(data.status)) {
|
|
241
|
+
throw responseFailure(data);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const output = responseOutput(data);
|
|
245
|
+
const text = [];
|
|
246
|
+
const toolCalls = [];
|
|
247
|
+
const reasoningItems = [];
|
|
248
|
+
const reasoningSummary = [];
|
|
249
|
+
for (const item of output) {
|
|
250
|
+
if (item?.type === "message" && Array.isArray(item.content)) {
|
|
251
|
+
for (const part of item.content) {
|
|
252
|
+
if (part?.type === "output_text" && typeof part.text === "string") {
|
|
253
|
+
text.push(part.text);
|
|
254
|
+
} else if (
|
|
255
|
+
part?.type === "refusal" &&
|
|
256
|
+
typeof part.refusal === "string"
|
|
257
|
+
) {
|
|
258
|
+
text.push(part.refusal);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
} else if (item?.type === "function_call") {
|
|
262
|
+
const id = printableString(item.call_id || item.id);
|
|
263
|
+
const name = printableString(item.name);
|
|
264
|
+
if (id && name) {
|
|
265
|
+
toolCalls.push({
|
|
266
|
+
id,
|
|
267
|
+
type: "function",
|
|
268
|
+
function: {
|
|
269
|
+
name,
|
|
270
|
+
arguments: printableString(item.arguments, "{}"),
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
} else if (item?.type === "reasoning") {
|
|
275
|
+
reasoningItems.push(item);
|
|
276
|
+
for (const part of item.summary || []) {
|
|
277
|
+
if (part?.type === "summary_text" && typeof part.text === "string") {
|
|
278
|
+
reasoningSummary.push(part.text);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const message = { role: "assistant", content: text.join("") };
|
|
285
|
+
if (toolCalls.length) message.tool_calls = toolCalls;
|
|
286
|
+
const safeReasoning = sanitizeReasoningItems(reasoningItems);
|
|
287
|
+
if (safeReasoning.length) message._openaiReasoningItems = safeReasoning;
|
|
288
|
+
if (reasoningSummary.length) {
|
|
289
|
+
message._openaiReasoningSummary = reasoningSummary
|
|
290
|
+
.join("")
|
|
291
|
+
.slice(0, MAX_REASONING_SUMMARY_CHARS);
|
|
292
|
+
}
|
|
293
|
+
if (data.status === "incomplete") {
|
|
294
|
+
delete message.tool_calls;
|
|
295
|
+
delete message._openaiReasoningItems;
|
|
296
|
+
message._truncated = true;
|
|
297
|
+
}
|
|
298
|
+
const result = {
|
|
299
|
+
message,
|
|
300
|
+
responseId: printableString(data.id) || null,
|
|
301
|
+
};
|
|
302
|
+
const usage = normalizeOpenAIResponsesUsage(data.usage);
|
|
303
|
+
if (usage) result.usage = usage;
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export function createOpenAIResponsesStreamState() {
|
|
308
|
+
return {
|
|
309
|
+
responseId: null,
|
|
310
|
+
text: "",
|
|
311
|
+
reasoningSummary: "",
|
|
312
|
+
outputItems: [],
|
|
313
|
+
normalized: null,
|
|
314
|
+
terminalError: null,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function streamItem(state, event) {
|
|
319
|
+
const index = Number.isSafeInteger(event.output_index)
|
|
320
|
+
? event.output_index
|
|
321
|
+
: state.outputItems.length;
|
|
322
|
+
if (!state.outputItems[index]) {
|
|
323
|
+
state.outputItems[index] = {
|
|
324
|
+
type: "function_call",
|
|
325
|
+
call_id: printableString(event.call_id || event.item_id),
|
|
326
|
+
name: printableString(event.name),
|
|
327
|
+
arguments: "",
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
return state.outputItems[index];
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export function reduceOpenAIResponsesStreamLine(
|
|
334
|
+
state,
|
|
335
|
+
raw,
|
|
336
|
+
onToken,
|
|
337
|
+
onThinking,
|
|
338
|
+
) {
|
|
339
|
+
const line = printableString(raw).trim();
|
|
340
|
+
if (!line.startsWith("data:")) return state;
|
|
341
|
+
const payload = line.slice(5).trim();
|
|
342
|
+
if (!payload || payload === "[DONE]") return state;
|
|
343
|
+
let event;
|
|
344
|
+
try {
|
|
345
|
+
event = JSON.parse(payload);
|
|
346
|
+
} catch {
|
|
347
|
+
return state;
|
|
348
|
+
}
|
|
349
|
+
state.responseId ||= printableString(event.response_id || event.response?.id);
|
|
350
|
+
if (event.type === "response.output_text.delta") {
|
|
351
|
+
const delta = printableString(event.delta);
|
|
352
|
+
state.text += delta;
|
|
353
|
+
onToken?.(delta);
|
|
354
|
+
} else if (event.type === "response.refusal.delta") {
|
|
355
|
+
const delta = printableString(event.delta);
|
|
356
|
+
state.text += delta;
|
|
357
|
+
onToken?.(delta);
|
|
358
|
+
} else if (event.type === "response.reasoning_summary_text.delta") {
|
|
359
|
+
const delta = printableString(event.delta);
|
|
360
|
+
state.reasoningSummary += delta;
|
|
361
|
+
onThinking?.(delta);
|
|
362
|
+
} else if (event.type === "response.output_item.added" && event.item) {
|
|
363
|
+
const index = Number.isSafeInteger(event.output_index)
|
|
364
|
+
? event.output_index
|
|
365
|
+
: state.outputItems.length;
|
|
366
|
+
state.outputItems[index] = event.item;
|
|
367
|
+
} else if (event.type === "response.output_item.done" && event.item) {
|
|
368
|
+
const index = Number.isSafeInteger(event.output_index)
|
|
369
|
+
? event.output_index
|
|
370
|
+
: state.outputItems.length;
|
|
371
|
+
state.outputItems[index] = event.item;
|
|
372
|
+
} else if (event.type === "response.function_call_arguments.delta") {
|
|
373
|
+
const item = streamItem(state, event);
|
|
374
|
+
item.arguments = `${printableString(item.arguments)}${printableString(event.delta)}`;
|
|
375
|
+
} else if (event.type === "response.function_call_arguments.done") {
|
|
376
|
+
const item = streamItem(state, event);
|
|
377
|
+
item.arguments = printableString(event.arguments, item.arguments || "{}");
|
|
378
|
+
} else if (
|
|
379
|
+
event.type === "response.completed" ||
|
|
380
|
+
event.type === "response.incomplete"
|
|
381
|
+
) {
|
|
382
|
+
try {
|
|
383
|
+
state.normalized = normalizeOpenAIResponsesResponse(event.response);
|
|
384
|
+
} catch (error) {
|
|
385
|
+
state.terminalError = error;
|
|
386
|
+
}
|
|
387
|
+
} else if (event.type === "response.failed" || event.type === "error") {
|
|
388
|
+
state.terminalError = responseFailure(event.response || event);
|
|
389
|
+
}
|
|
390
|
+
return state;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export function finalizeOpenAIResponsesStream(state) {
|
|
394
|
+
if (state.terminalError) throw state.terminalError;
|
|
395
|
+
if (state.normalized) return state.normalized;
|
|
396
|
+
const output = state.outputItems.filter(Boolean);
|
|
397
|
+
let normalized;
|
|
398
|
+
if (output.length) {
|
|
399
|
+
normalized = normalizeOpenAIResponsesResponse({
|
|
400
|
+
id: state.responseId,
|
|
401
|
+
status: "completed",
|
|
402
|
+
output,
|
|
403
|
+
});
|
|
404
|
+
} else {
|
|
405
|
+
normalized = {
|
|
406
|
+
message: { role: "assistant", content: state.text },
|
|
407
|
+
responseId: state.responseId,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
if (!normalized.message.content && state.text) {
|
|
411
|
+
normalized.message.content = state.text;
|
|
412
|
+
}
|
|
413
|
+
if (!normalized.message._openaiReasoningSummary && state.reasoningSummary) {
|
|
414
|
+
normalized.message._openaiReasoningSummary = state.reasoningSummary.slice(
|
|
415
|
+
0,
|
|
416
|
+
MAX_REASONING_SUMMARY_CHARS,
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
return normalized;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
export function accumulateOpenAIResponsesStream(lines, onToken, onThinking) {
|
|
423
|
+
const state = createOpenAIResponsesStreamState();
|
|
424
|
+
for (const line of lines) {
|
|
425
|
+
reduceOpenAIResponsesStreamLine(state, line, onToken, onThinking);
|
|
426
|
+
}
|
|
427
|
+
return finalizeOpenAIResponsesStream(state);
|
|
428
|
+
}
|
|
@@ -226,7 +226,13 @@ export function discoverPlugins(opts = {}) {
|
|
|
226
226
|
) {
|
|
227
227
|
return [];
|
|
228
228
|
}
|
|
229
|
-
const
|
|
229
|
+
const envScopes = String((opts.env || process.env).CC_PLUGIN_SCOPES || "")
|
|
230
|
+
.split(",")
|
|
231
|
+
.map((scope) => scope.trim())
|
|
232
|
+
.filter(Boolean);
|
|
233
|
+
const requestedScopes = new Set(
|
|
234
|
+
opts.scopes || (envScopes.length > 0 ? envScopes : SCOPES),
|
|
235
|
+
);
|
|
230
236
|
for (const requested of requestedScopes) {
|
|
231
237
|
if (!SCOPES.includes(requested)) {
|
|
232
238
|
throw new Error(`unknown plugin scope: ${requested}`);
|
|
@@ -387,7 +387,7 @@ export class RemoteReadLoopGuard {
|
|
|
387
387
|
"For git-tool-reroute, call the dedicated git tool with git arguments and the repository cwd, without the leading git, pipes or 2>&1. " +
|
|
388
388
|
"If the dedicated tool fails, inspect its actual stderr and verify cwd/remotes before continuing. " +
|
|
389
389
|
"For a policy denial with no authorized route, report the exact blocker and completed findings; the task is not complete. " +
|
|
390
|
-
"
|
|
390
|
+
"Keep execution permissions unchanged and use only authorized tool routes. Respect the execution policy; when it denies the command, stop and report the blocked action."
|
|
391
391
|
);
|
|
392
392
|
}
|
|
393
393
|
if (this.targets.get(this.activeKey)?.gitRepository) {
|
|
@@ -406,7 +406,7 @@ export class RemoteReadLoopGuard {
|
|
|
406
406
|
"Inspect stdout/stderr for command errors first. gh pr --json uses state and mergedAt, not merged; " +
|
|
407
407
|
"use gh pr list --help or gh pr view --help to check supported fields. " +
|
|
408
408
|
"If metadata is missing, request gh pr view <number> --repo <owner/repo> --json number,title,state,mergedAt,headRefOid,baseRefOid once. " +
|
|
409
|
-
"For a shell-policy git reroute, use the dedicated git tool with command arguments only (no leading git, pipes, or 2>&1);
|
|
409
|
+
"For a shell-policy git reroute, use the dedicated git tool with command arguments only (no leading git, pipes, or 2>&1). Respect the execution policy; when it denies the command, stop and report the blocked action. " +
|
|
410
410
|
"Compare the specific PR diff/commits with the target branch to decide the requested fix or disposition. " +
|
|
411
411
|
"For review, synthesize evidence-backed findings; do not create edits merely to reset the loop. " +
|
|
412
412
|
"Perform only already-authorized PR actions. If a required fact or authorization remains unavailable, report the concrete blocker and useful findings. " +
|
|
@@ -122,6 +122,22 @@ export function projectRuntimeTokenUsage(event = {}) {
|
|
|
122
122
|
required: index < 2,
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
|
+
if (
|
|
126
|
+
Object.hasOwn(event.usage, "reasoning_tokens") ||
|
|
127
|
+
Object.hasOwn(event.usage, "reasoningTokens")
|
|
128
|
+
) {
|
|
129
|
+
const reasoningTokens = tokenCount(
|
|
130
|
+
event.usage,
|
|
131
|
+
"reasoning_tokens",
|
|
132
|
+
"reasoningTokens",
|
|
133
|
+
);
|
|
134
|
+
if (reasoningTokens > usage.output_tokens) {
|
|
135
|
+
throw new TypeError(
|
|
136
|
+
"runtime reasoning token usage exceeds output tokens",
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
usage.reasoning_tokens = reasoningTokens;
|
|
140
|
+
}
|
|
125
141
|
if (Object.hasOwn(event.usage, "total_tokens")) {
|
|
126
142
|
const total = event.usage.total_tokens;
|
|
127
143
|
if (
|
|
@@ -28,6 +28,10 @@ import {
|
|
|
28
28
|
} from "./session-message-provenance.js";
|
|
29
29
|
import { createSessionTranscriptStructureProjection } from "./session-transcript-structure.js";
|
|
30
30
|
import { normalizeSessionBudgetRootConfig } from "./session-budget-production-root.js";
|
|
31
|
+
import {
|
|
32
|
+
createDeferredQuestionEventReducer,
|
|
33
|
+
reduceDeferredQuestionEvents,
|
|
34
|
+
} from "./deferred-question-context.js";
|
|
31
35
|
|
|
32
36
|
export const SESSION_HOST_SNAPSHOT_SCHEMA =
|
|
33
37
|
"chainlesschain.session-host-snapshot/v1";
|
|
@@ -292,6 +296,7 @@ export function projectVerifiedSessionHostSnapshot(sessionId, events) {
|
|
|
292
296
|
sessionId,
|
|
293
297
|
verified: true,
|
|
294
298
|
});
|
|
299
|
+
const deferred = reduceDeferredQuestionEvents(safeEvents, { sessionId });
|
|
295
300
|
return Object.freeze({
|
|
296
301
|
snapshot: projectSessionHostObservation({
|
|
297
302
|
sessionId,
|
|
@@ -301,6 +306,9 @@ export function projectVerifiedSessionHostSnapshot(sessionId, events) {
|
|
|
301
306
|
}),
|
|
302
307
|
messages,
|
|
303
308
|
recovery,
|
|
309
|
+
deferredQuestions: deferred.pendingQuestions,
|
|
310
|
+
deferredAnswers: deferred.answers,
|
|
311
|
+
deferredQuestionSequence: deferred.maxSequence,
|
|
304
312
|
sessionBudgetRoot: sessionBudgetRootFromEvents(safeEvents),
|
|
305
313
|
});
|
|
306
314
|
}
|
|
@@ -316,6 +324,9 @@ function createStreamingSessionHostProjection(sessionId) {
|
|
|
316
324
|
sessionId,
|
|
317
325
|
verified: true,
|
|
318
326
|
});
|
|
327
|
+
const deferredQuestionReducer = createDeferredQuestionEventReducer({
|
|
328
|
+
sessionId,
|
|
329
|
+
});
|
|
319
330
|
|
|
320
331
|
return {
|
|
321
332
|
accept(event) {
|
|
@@ -337,6 +348,7 @@ function createStreamingSessionHostProjection(sessionId) {
|
|
|
337
348
|
lastEventType =
|
|
338
349
|
typeof safeEvent.type === "string" ? safeEvent.type : null;
|
|
339
350
|
mcpReducer.accept(safeEvent);
|
|
351
|
+
deferredQuestionReducer.accept(safeEvent);
|
|
340
352
|
},
|
|
341
353
|
finish({ headHash, eventCount, readMessages }) {
|
|
342
354
|
structure.finish();
|
|
@@ -351,6 +363,7 @@ function createStreamingSessionHostProjection(sessionId) {
|
|
|
351
363
|
projectCanonicalResumeMessages(recoveredMessages, { strict: true }),
|
|
352
364
|
);
|
|
353
365
|
const recovery = mcpReducer.finish();
|
|
366
|
+
const deferred = deferredQuestionReducer.finish();
|
|
354
367
|
return Object.freeze({
|
|
355
368
|
snapshot: projectSessionHostProjection({
|
|
356
369
|
sessionId,
|
|
@@ -363,6 +376,9 @@ function createStreamingSessionHostProjection(sessionId) {
|
|
|
363
376
|
}),
|
|
364
377
|
messages,
|
|
365
378
|
recovery,
|
|
379
|
+
deferredQuestions: deferred.pendingQuestions,
|
|
380
|
+
deferredAnswers: deferred.answers,
|
|
381
|
+
deferredQuestionSequence: deferred.maxSequence,
|
|
366
382
|
sessionBudgetRoot,
|
|
367
383
|
});
|
|
368
384
|
},
|
package/src/lib/skill-loader.js
CHANGED
|
@@ -32,6 +32,10 @@ import { normalizeSkillPaths } from "./skill-path-scope.js";
|
|
|
32
32
|
import { discoverPluginSkillLayers } from "./plugin-runtime/skills.js";
|
|
33
33
|
import settingsLoader from "./settings-loader.cjs";
|
|
34
34
|
import contextSourceLedger from "./context-source-ledger.js";
|
|
35
|
+
import {
|
|
36
|
+
bindSkillRuntimeAdmission,
|
|
37
|
+
assertSkillRuntimeAdmission,
|
|
38
|
+
} from "./evolution/skill-runtime-revalidation.js";
|
|
35
39
|
import {
|
|
36
40
|
createAbortError,
|
|
37
41
|
isAbortError,
|
|
@@ -375,6 +379,8 @@ export class CLISkillLoader {
|
|
|
375
379
|
contextLedger = contextSourceLedger,
|
|
376
380
|
reauthorizeSkill = null,
|
|
377
381
|
executionAuthority = null,
|
|
382
|
+
skillRuntimeAdmission = null,
|
|
383
|
+
skillRuntimeAdmissionRequired = false,
|
|
378
384
|
limits = {},
|
|
379
385
|
// Only package-owned, immutable-at-install sources are trusted by
|
|
380
386
|
// default. The historical "managed" layer is actually the user-writable
|
|
@@ -386,6 +392,9 @@ export class CLISkillLoader {
|
|
|
386
392
|
throw new TypeError("reauthorizeSkill must be a function or null");
|
|
387
393
|
}
|
|
388
394
|
this._cache = null;
|
|
395
|
+
bindSkillRuntimeAdmission(this, skillRuntimeAdmission, {
|
|
396
|
+
required: skillRuntimeAdmissionRequired,
|
|
397
|
+
});
|
|
389
398
|
this._bodyCache = new Map();
|
|
390
399
|
this._contextLedger = contextLedger;
|
|
391
400
|
this._reauthorizeSkill = reauthorizeSkill;
|
|
@@ -653,6 +662,7 @@ export class CLISkillLoader {
|
|
|
653
662
|
}
|
|
654
663
|
|
|
655
664
|
async materializeSkillForExecution(skill, context = {}) {
|
|
665
|
+
assertSkillRuntimeAdmission({ skill, loader: this, context });
|
|
656
666
|
const executionLease = this.acquireSkillExecution(skill, {
|
|
657
667
|
signal: context.signal,
|
|
658
668
|
});
|
|
@@ -918,6 +928,7 @@ export class CLISkillLoader {
|
|
|
918
928
|
* size/mtime metadata, and provenance records never include source content.
|
|
919
929
|
*/
|
|
920
930
|
materializeSkill(skill, context = {}) {
|
|
931
|
+
assertSkillRuntimeAdmission({ skill, loader: this, context });
|
|
921
932
|
throwIfAborted(
|
|
922
933
|
context.signal,
|
|
923
934
|
"Skill execution materialization was interrupted",
|
|
@@ -1118,6 +1129,7 @@ export class CLISkillLoader {
|
|
|
1118
1129
|
} catch {
|
|
1119
1130
|
// Context observability must never make a valid skill unloadable.
|
|
1120
1131
|
}
|
|
1132
|
+
assertSkillRuntimeAdmission({ skill, loader: this, context });
|
|
1121
1133
|
return skill;
|
|
1122
1134
|
}
|
|
1123
1135
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* lock convoys.
|
|
23
23
|
*
|
|
24
24
|
* @param {string} targetPath the file being guarded (lock is `${targetPath}.lock`)
|
|
25
|
-
* @param {(ctx:{locked:boolean,publishReleaseAfterPathRemoved:(pendingPath:string)=>boolean})=>T} fn
|
|
25
|
+
* @param {(ctx:{locked:boolean,waitMs:number,attempts:number,publishReleaseAfterPathRemoved:(pendingPath:string)=>boolean})=>T} fn
|
|
26
26
|
* critical section; `publishReleaseAfterPathRemoved` lets a transaction
|
|
27
27
|
* publish an exact, contender-completable handoff before its final atomic
|
|
28
28
|
* rename removes a uniquely named staging path
|
|
@@ -188,6 +188,8 @@ export function withFileLock(targetPath, fn, opts = {}) {
|
|
|
188
188
|
try {
|
|
189
189
|
result = fn({
|
|
190
190
|
locked: held,
|
|
191
|
+
waitMs: Math.max(0, _now() - owner.startedAt),
|
|
192
|
+
attempts: retryAttempt + 1,
|
|
191
193
|
publishReleaseAfterPathRemoved(pendingPath) {
|
|
192
194
|
if (!held || typeof pendingPath !== "string" || !pendingPath) {
|
|
193
195
|
return false;
|
package/src/repl/agent-repl.js
CHANGED
|
@@ -25,6 +25,7 @@ import path from "path";
|
|
|
25
25
|
import { createHash, randomUUID } from "node:crypto";
|
|
26
26
|
import { isPromise, isProxy } from "node:util/types";
|
|
27
27
|
import { logger } from "../lib/logger.js";
|
|
28
|
+
import { captureSkillRuntimeDependencies } from "../lib/evolution/skill-runtime-revalidation.js";
|
|
28
29
|
import { captureAmbientExecutionLocation } from "../lib/execution-location-runtime.js";
|
|
29
30
|
import { issueMcpStdioExecutionAuthority } from "../lib/mcp-stdio-execution-authority.js";
|
|
30
31
|
import { getPlanModeManager, PlanState } from "../lib/plan-mode.js";
|
|
@@ -4076,7 +4077,9 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
4076
4077
|
let _loadedReplInstructions = null;
|
|
4077
4078
|
let _loadedReplPersonaSkills = [];
|
|
4078
4079
|
let _replSkillCacheLedger = null;
|
|
4079
|
-
const _replSkillLoader =
|
|
4080
|
+
const _replSkillLoader =
|
|
4081
|
+
options.skillLoader ||
|
|
4082
|
+
new CLISkillLoader(captureSkillRuntimeDependencies(options));
|
|
4080
4083
|
const _buildReplBaseSystem = () =>
|
|
4081
4084
|
composeSystemPrompt(
|
|
4082
4085
|
buildSystemPrompt(process.cwd(), {
|
|
@@ -9612,6 +9615,7 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
9612
9615
|
usageEvents,
|
|
9613
9616
|
thinking: reasoning,
|
|
9614
9617
|
} = await agentLoop(messages, {
|
|
9618
|
+
...captureSkillRuntimeDependencies(options),
|
|
9615
9619
|
...liveOpts,
|
|
9616
9620
|
waitForOutput: _replOutputFlow.wait,
|
|
9617
9621
|
mergeRoles: _mergeRolesThisTurn,
|