chainlesschain 0.166.107 → 0.166.109
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 +18 -9
- package/package.json +1 -1
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-DCx6L_HW.js → AIOps-DkrNbDzS.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DYm1CN3Z.js → ActionButton-DJjFXDhv.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D5ItUS_y.js → Analytics-DyUbagRn.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Cb7XeRdH.js → AppLayout-p7kJWSvn.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-DDDeqCDQ.js → Artifacts-C3rVh4Ak.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BRt3x13w.js → Audit-Bch_L_YO.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C_oNALMd.js → BackgroundAgents-BNHy8zP6.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-PSU2p6CR.js → Backup-BUaye_Ys.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-G3oL4hcX.js → BaseInput-D49mzAVz.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-C2cLI10b.js → Chat-2MDzM_us.js} +6 -6
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DOX3Y5EJ.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-CHLnEgFD.js → Checkbox-5p1T_KEq.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DZm9g_Bc.js → Codegen-TKtiLaoZ.js} +1 -1
- package/src/assets/web-panel/assets/{Col-D5Z4zSay.js → Col-BVCMG9mS.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DHw69NSk.js → Community-D09-QczH.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-B-vjYNWz.js → Compact-QuRMCnj7.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DaIYVZQY.js → Compliance-CN0PV7fk.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CoA9U-gF.js → Cowork-5N2zhAty.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DXqmxlRC.js → Cron-BxT8UZ0S.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Cdkc3ue1.js → Crosschain-Dp-noQl4.js} +1 -1
- package/src/assets/web-panel/assets/{DID-oKfYyNSR.js → DID-B7MZFkjG.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-n_ycvgWu.js → Dashboard-DulJ3rKV.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-D38rZ8WY.js → Dropdown-DV4ov4zF.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BjreeBQ1.js → EmailListRenderer-DB2-ooz6.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-CTxA_SIq.js → EvolutionSettings-B1Rb6p7q.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DmECNwV5.js → FamilyGuardDashboard-U8aHayx-.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-B2IaaDmQ.js → Federation-BkQULBHY.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DgcgqUIk.js → FormItemContext-CtviG260.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-B1-du6Qm.js → GenericCardRenderer-DnPirB24.js} +1 -1
- package/src/assets/web-panel/assets/{Git-XceM21Il.js → Git-CK57Oro6.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CV97iz3z.js → Governance-DbI-LB8-.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CI7fj305.js → Inference-sEG4T1Jg.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-B5mekWRy.js → KnowledgeGraph-9SLJR3h9.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BlxFA0xY.js → Logs-BIZYcISQ.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-rDE-XyMY.js → MarkdownRenderer-9nfWupWP.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-DL1BVCiX.js → Marketplace-CRmLLwAE.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BPtwrO3c.js → McpTools-DkOFkSO1.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-DuSNw4E-.js → Memory-M29Kd9TU.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DTgY9ywI.js → MobileBridge-Tl6JvPw_.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-Bq-FPDzS.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-h4fCLjXw.js → Mtc-DkUjX1F5.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-fqMDY3-w.js → MtcAudit-BCqr1I4q.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-Do3FehBL.js → Multisig-DmoqYGQ5.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CQVY0kQF.js → NLProgramming-DNRQeRke.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-4c3oNvWh.js → Notes-CQSBeiY6.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BKr2JD4k.js → NotificationSettings-gNY9bbH6.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Bq4jgzRt.js → OrderTableRenderer-DW0CNjh8.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-Dy3XidyA.js → Organization-CthnbKag.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DFF0qN5K.js → Overflow-_GQ3sbXu.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DAgYYykd.js → P2P-BTr7ea6W.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-D9McHF9I.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-Cev6uSBc.js → Permissions-DMny2Cjs.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-DJzbN06K.js → PersonalDataHub-CyYlMSoI.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-CoJWvbQ5.js → Pipeline-FASu2Oc4.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DZxV6etm.js → Privacy-9bC5FnsJ.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BFW87JnM.js → ProjectInit-BOYZwB5G.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-LBrRT27p.js → ProjectSettings-45DViNG-.js} +2 -2
- package/src/assets/web-panel/assets/Projects-C2fZzMZc.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CnRbjOYk.js → Providers-BgjvZx9F.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BVFnIS3r.js → QrScannerModal-Brw-3csB.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DrcHx5f1.js → QuickAsk-DWG-A5zB.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CbRgrSJm.js → Recommend-DuQGxjIR.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-B2Uz_ElB.js → RemoteSession-T1cdSSRL.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-DS0ljTxL.js → Reputation-9FT2dI4G.js} +1 -1
- package/src/assets/web-panel/assets/{Row-ClLobFht.js → Row-yNIbNftX.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DxxcTD0x.js → RssFeed-BIchNoPd.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BbHN0Fik.js → Search-msDJ8UTZ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BAVU_EcY.js → Security-DE46oBYT.js} +3 -3
- package/src/assets/web-panel/assets/{Services-CtqRSVq_.js → Services-Dori7vc3.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-IJ8ZKdSZ.js → Skeleton-D3O3sUFz.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DXxcznnO.js → Skills-BV0ct8SO.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-fRkhnA3i.js → Sla-DflIVOrh.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Bi8sYJ-I.js → SpeechSettings-Cpbv2Zz6.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CjeplUtS.js → SyncSettings-Dgg6-wbe.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-D4KB2Hbx.js → Tasks-Cb6e4Klx.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BwVugi8n.js → Templates-GfdAATGz.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CsPuu5xK.js → Tenant-D0gecLXl.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DuaeOPjY.js → Terminal-BFRPJt-0.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-D-PMrFxO.js → TimelineRenderer-BobtChxX.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BXZuiQPZ.js → Tokens-CifeZtHV.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DgpTaHL3.js → Trigger-BHBvbBCf.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Bn7lEGRY.js → Trust-6lvqjKYp.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-zz-8JAAQ.js → UkeySign-CqzMc-G5.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DCzfQGTc.js → VideoEditing-OIiRG582.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BiRHM_zB.js → Wallet-4MeKq0q_.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-QmPo2JwU.js → WebAuthn-eHBRjGQG.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-gL7SsPnY.js → WorkflowEditor-DlzYdEqW.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BysvK4hk.js → chat-CBcjOzkX.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CQq20vqN.js → colors-zgwsYQSa.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CAHlOf1X.js → compact-item-Dcd9H5Bn.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BeF3ESj_.js → createContext-DR1tO-8r.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DYhpRtve.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CiqnRf-U.js → hasIn-CtfbUH_p.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cp3IRTDK.js → index-5XaB_Tjg.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKYbru3i.js → index-B3QUK1ks.js} +1 -1
- package/src/assets/web-panel/assets/{index-CCX0daFQ.js → index-BXfGHUz_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgkUkmEJ.js → index-BndPtS9D.js} +1 -1
- package/src/assets/web-panel/assets/{index-zNkw0IY7.js → index-BoxowMYS.js} +1 -1
- package/src/assets/web-panel/assets/{index-i9aJV9qk.js → index-C0kP88Pb.js} +1 -1
- package/src/assets/web-panel/assets/{index-BtWchYfW.js → index-C5XGvJb0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHpHGGmB.js → index-CPLLgPxA.js} +1 -1
- package/src/assets/web-panel/assets/{index-qjaCk1Mj.js → index-CSQCHpDo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CImCEo8S.js → index-CT7zIkqP.js} +1 -1
- package/src/assets/web-panel/assets/{index-Br5tGVbC.js → index-CaGNqkY0.js} +1 -1
- package/src/assets/web-panel/assets/{index-xwtRrgVY.js → index-Cdhy5ckh.js} +1 -1
- package/src/assets/web-panel/assets/{index-CowbNBJs.js → index-CmVIM-m2.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTp89vmg.js → index-CmzQzTY5.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7q5VH2n.js → index-Cur8LNNn.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeIL3-nY.js → index-CwHgaYVH.js} +1 -1
- package/src/assets/web-panel/assets/{index-jJhemX1R.js → index-D1GxtY-h.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTPUVm71.js → index-D7ZOiIKb.js} +1 -1
- package/src/assets/web-panel/assets/{index-QALafVsT.js → index-D8WPohye.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZBuJ6O6g.js → index-DA2-Bhy8.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5941vyo.js → index-DHEiuvhA.js} +1 -1
- package/src/assets/web-panel/assets/index-DPJXFIY7.js +1 -0
- package/src/assets/web-panel/assets/{index-BsnLkZjz.js → index-DSvcz0RO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHGtFwwR.js → index-DTx4FyLU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOiyW31p.js → index-DVpp9YSQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2AOvjgR.js → index-DWG98orp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BfJabF_8.js → index-DWuCGhHa.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBmGQHEz.js → index-DYPMJ5Mb.js} +3 -3
- package/src/assets/web-panel/assets/{index-B2xbtl_c.js → index-DeAi4CNt.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bvkbj3x-.js → index-DfzOYmOj.js} +1 -1
- package/src/assets/web-panel/assets/index-DjBhR5M_.js +1 -0
- package/src/assets/web-panel/assets/{index-DXsXhR7p.js → index-DvPOpvvH.js} +1 -1
- package/src/assets/web-panel/assets/{index-yFQWSRoW.js → index-J-ORW1i6.js} +1 -1
- package/src/assets/web-panel/assets/{index-TdVEaJfk.js → index-JSfldpw4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcccefJc.js → index-LN7Hkl1C.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dqkls2_6.js → index-dvF6C39V.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcVmt6u_.js → index-hTcre7U9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXT7MKkD.js → index-oWOlF7CM.js} +1 -1
- package/src/assets/web-panel/assets/{index-4a0Lmz_y.js → index-z8lrkcb-.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BQR2HnKb.js → initDefaultProps-CVMtDrWZ.js} +1 -1
- package/src/assets/web-panel/assets/{motion-gAz6l-nZ.js → motion-Dye3IU8k.js} +1 -1
- package/src/assets/web-panel/assets/{move-Cy5TN856.js → move-C251Zo34.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BeT7VrGi.js → mtc-parser-BDiOORoQ.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BLN3mlgK.js → omit-DTDA_RHv.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DtwZ8u2d.js → pickAttrs-CqEUTPcT.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-ViMwQSa-.js → placementArrow-BOB8QWH3.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-dEL3u4E7.js → responsiveObserve-CZDXP1d9.js} +1 -1
- package/src/assets/web-panel/assets/{slide-l05us-Gz.js → slide-DPaRw3E9.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Bk-Qn2Og.js → statusUtils-Ba9d7XZ7.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Bn186qeY.js → styleChecker-mZKU3lvW.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-WP-ugR3H.js → useFlexGapSupport-VcauLq0M.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-1SvoeSCL.js → useFs-Cal9KRcx.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CfNU8N3z.js → usePersonalDataHub-DISoRyQB.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Bd2Ya101.js → vnode-B58C6w6B.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Def_MeZv.js → zoom-BPlBAMKB.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/data/changelog.json +29 -3
- package/src/gateways/ws/llm-chat-protocol.js +12 -2
- package/src/gateways/ws/llm-creds.js +50 -22
- package/src/gateways/ws/ws-server.js +47 -0
- package/src/harness/jsonl-session-store.js +128 -5
- package/src/harness/prompt-compressor.js +18 -10
- package/src/harness/structured-handoff.js +151 -13
- package/src/lib/agent-session-export.js +20 -0
- package/src/lib/background-agent-supervisor.js +54 -0
- package/src/lib/coding-task-guidance.js +2 -1
- package/src/lib/context-memory-kernel/live-compaction.js +75 -12
- package/src/lib/read-file-loop-guard.js +124 -8
- package/src/lib/session-host-snapshot.js +3 -0
- package/src/lib/session-message-provenance.js +24 -5
- package/src/lib/session-tool-round.js +39 -0
- package/src/lib/session-transcript-history.js +2 -0
- package/src/lib/session-transcript-page.js +4 -1
- package/src/lib/session-transcript-structure.js +4 -0
- package/src/runtime/__tests__/message-roles.test.js +29 -0
- package/src/runtime/agent-core.js +115 -43
- package/src/runtime/headless-runner.js +191 -34
- package/src/runtime/headless-stream.js +140 -42
- package/src/runtime/message-roles.js +43 -0
- package/src/workers/background-agent-worker.js +146 -47
- package/src/assets/web-panel/assets/ChatBubbleRenderer-KX1OITf8.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-CTpVHJMa.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-DgNHa8b1.js +0 -7
- package/src/assets/web-panel/assets/Projects-O3uz76R1.js +0 -1
- package/src/assets/web-panel/assets/devWarning-D-Iugqxv.js +0 -1
- package/src/assets/web-panel/assets/index-B0Oz2_rQ.js +0 -1
- package/src/assets/web-panel/assets/index-DwoycEQa.js +0 -1
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
buildReadFileOutline,
|
|
47
47
|
} from "../lib/read-file-page.js";
|
|
48
48
|
import { ReadFileLoopGuard } from "../lib/read-file-loop-guard.js";
|
|
49
|
+
const READ_FILE_REQUEST_CONTEXT = Symbol("read-file-request-context");
|
|
49
50
|
import { gitToolInputError } from "../lib/git-tool-input.js";
|
|
50
51
|
import { shellOutputPage, shellOutputPreview } from "../lib/shell-output.js";
|
|
51
52
|
import { DIAGNOSTIC_WORKFLOW_GUIDANCE } from "../lib/diagnostic-workflow.js";
|
|
@@ -232,7 +233,10 @@ import {
|
|
|
232
233
|
formatStructuredHandoff,
|
|
233
234
|
} from "../harness/structured-handoff.js";
|
|
234
235
|
import { isMcpRpcError } from "../harness/mcp-client.js";
|
|
235
|
-
import {
|
|
236
|
+
import {
|
|
237
|
+
projectCanonicalResumeMessages,
|
|
238
|
+
markRuntimeOnlySessionMessage,
|
|
239
|
+
} from "../lib/session-message-provenance.js";
|
|
236
240
|
import { releaseOldLiveSessionResults } from "../lib/session-runtime-retention.js";
|
|
237
241
|
import {
|
|
238
242
|
pathMatchesOpenedFileIdentitySync,
|
|
@@ -4935,7 +4939,19 @@ export async function _withPostEditDiagnostics(
|
|
|
4935
4939
|
// Parsing the bytes we just wrote is safe even when starting a language
|
|
4936
4940
|
// server is forbidden. Feed definite local import mistakes back in the same
|
|
4937
4941
|
// tool result; a successful write still means persistence, not test success.
|
|
4938
|
-
let enriched =
|
|
4942
|
+
let enriched =
|
|
4943
|
+
result?.success === true && typeof writtenContent === "string"
|
|
4944
|
+
? {
|
|
4945
|
+
...result,
|
|
4946
|
+
validation: {
|
|
4947
|
+
persisted: true,
|
|
4948
|
+
testsExecuted: false,
|
|
4949
|
+
relativeImports: "not-checked",
|
|
4950
|
+
message:
|
|
4951
|
+
"File saved. This file operation did not run tests. Any import feedback checks explicit JavaScript relative references only and does not establish test or task acceptance.",
|
|
4952
|
+
},
|
|
4953
|
+
}
|
|
4954
|
+
: result;
|
|
4939
4955
|
if (
|
|
4940
4956
|
result?.success === true &&
|
|
4941
4957
|
typeof writtenContent === "string" &&
|
|
@@ -4956,9 +4972,21 @@ export async function _withPostEditDiagnostics(
|
|
|
4956
4972
|
content: writtenContent,
|
|
4957
4973
|
workspaceRoot: root,
|
|
4958
4974
|
});
|
|
4975
|
+
enriched = {
|
|
4976
|
+
...enriched,
|
|
4977
|
+
validation: {
|
|
4978
|
+
...enriched.validation,
|
|
4979
|
+
relativeImports: checked.status,
|
|
4980
|
+
checkedReferences: checked.checkedReferences,
|
|
4981
|
+
uncheckedReferences: checked.uncheckedReferences.length,
|
|
4982
|
+
truncated: checked.truncated,
|
|
4983
|
+
diagnosticsTruncated: checked.diagnostics.length > 8,
|
|
4984
|
+
...(checked.reason ? { skipReason: checked.reason } : {}),
|
|
4985
|
+
},
|
|
4986
|
+
};
|
|
4959
4987
|
if (checked.diagnostics.length) {
|
|
4960
4988
|
enriched = {
|
|
4961
|
-
...
|
|
4989
|
+
...enriched,
|
|
4962
4990
|
newDiagnostics: [
|
|
4963
4991
|
...(result.newDiagnostics || []),
|
|
4964
4992
|
...checked.diagnostics.slice(0, 8),
|
|
@@ -12103,6 +12131,10 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12103
12131
|
tools = projected.tools;
|
|
12104
12132
|
}
|
|
12105
12133
|
|
|
12134
|
+
if (options[READ_FILE_REQUEST_CONTEXT]) {
|
|
12135
|
+
options[READ_FILE_REQUEST_CONTEXT].messages = messages;
|
|
12136
|
+
}
|
|
12137
|
+
|
|
12106
12138
|
throwIfAborted(signal);
|
|
12107
12139
|
|
|
12108
12140
|
// Host accounting starts only after request admission. A rejected model
|
|
@@ -14697,7 +14729,9 @@ export async function* agentLoop(messages, options) {
|
|
|
14697
14729
|
// These tools are alternative ways to deliver content to the same target.
|
|
14698
14730
|
// A successful explicit replacement must settle a deferred edit (and vice
|
|
14699
14731
|
// versa); move/delete/notebook effects retain their distinct obligations.
|
|
14700
|
-
const effect = ["write_file", "edit_file", "edit_file_hashed"].includes(
|
|
14732
|
+
const effect = ["write_file", "edit_file", "edit_file_hashed"].includes(
|
|
14733
|
+
tool,
|
|
14734
|
+
)
|
|
14701
14735
|
? "file-content"
|
|
14702
14736
|
: tool;
|
|
14703
14737
|
const key = JSON.stringify([effect, targets]);
|
|
@@ -15850,10 +15884,12 @@ export async function* agentLoop(messages, options) {
|
|
|
15850
15884
|
// SubagentStop hooks are best-effort
|
|
15851
15885
|
}
|
|
15852
15886
|
}
|
|
15853
|
-
messages.push(
|
|
15854
|
-
|
|
15855
|
-
|
|
15856
|
-
|
|
15887
|
+
messages.push(
|
|
15888
|
+
markRuntimeOnlySessionMessage({
|
|
15889
|
+
role: "user",
|
|
15890
|
+
content: _backgroundSubAgentResultText(entry),
|
|
15891
|
+
}),
|
|
15892
|
+
);
|
|
15857
15893
|
taskProgressTracker.retainChildResult(
|
|
15858
15894
|
entry.id,
|
|
15859
15895
|
{
|
|
@@ -16002,6 +16038,11 @@ export async function* agentLoop(messages, options) {
|
|
|
16002
16038
|
];
|
|
16003
16039
|
}
|
|
16004
16040
|
}
|
|
16041
|
+
// Role normalization is request-only: durable history remains unchanged
|
|
16042
|
+
// for tool settlement and canonical compaction authority comparisons.
|
|
16043
|
+
if (typeof options.projectProviderMessages === "function") {
|
|
16044
|
+
callMessages = options.projectProviderMessages(callMessages);
|
|
16045
|
+
}
|
|
16005
16046
|
const contextMemoryTrustedSystemIndexes = [];
|
|
16006
16047
|
if (Number.isFinite(budget.limit)) {
|
|
16007
16048
|
// consume() already charged this dispatch. The current request may still
|
|
@@ -16197,10 +16238,15 @@ export async function* agentLoop(messages, options) {
|
|
|
16197
16238
|
const requestOptions = providerRequestId
|
|
16198
16239
|
? { ...plannedProviderOptions, providerRequestId }
|
|
16199
16240
|
: plannedProviderOptions;
|
|
16200
|
-
|
|
16201
|
-
|
|
16241
|
+
// Capture the custom adapter's input or the built-in adapter's final
|
|
16242
|
+
// projection. Commit visibility only after a successful model response.
|
|
16243
|
+
const readFileRequestContext = { messages: callMessages };
|
|
16244
|
+
const providerCallOptions = {
|
|
16245
|
+
[READ_FILE_REQUEST_CONTEXT]: readFileRequestContext,
|
|
16246
|
+
...(evolutionIngress !== null
|
|
16202
16247
|
? { ...requestOptions, evolutionIngress }
|
|
16203
|
-
: requestOptions
|
|
16248
|
+
: requestOptions),
|
|
16249
|
+
};
|
|
16204
16250
|
const modelUsageCall = {
|
|
16205
16251
|
type: "model-usage-started",
|
|
16206
16252
|
callId: _newModelUsageCallId("model"),
|
|
@@ -16302,6 +16348,7 @@ export async function* agentLoop(messages, options) {
|
|
|
16302
16348
|
},
|
|
16303
16349
|
"model_error",
|
|
16304
16350
|
);
|
|
16351
|
+
readFileLoopGuard.observeVisibleMessages(readFileRequestContext.messages);
|
|
16305
16352
|
providerReceipt = providerRequestId
|
|
16306
16353
|
? _snapshotProviderRequestReceipt(
|
|
16307
16354
|
result?.providerReceipt,
|
|
@@ -16463,17 +16510,24 @@ export async function* agentLoop(messages, options) {
|
|
|
16463
16510
|
);
|
|
16464
16511
|
_throwBackgroundUsageFailureState(backgroundUsageFailureState);
|
|
16465
16512
|
throwIfAborted(signal);
|
|
16466
|
-
messages.push(
|
|
16513
|
+
messages.push(
|
|
16514
|
+
markRuntimeOnlySessionMessage({
|
|
16515
|
+
role: "assistant",
|
|
16516
|
+
content: msg.content || "",
|
|
16517
|
+
}),
|
|
16518
|
+
);
|
|
16467
16519
|
for (const entry of _takeSettledBackgroundSubAgents(
|
|
16468
16520
|
backgroundSubAgents,
|
|
16469
16521
|
)) {
|
|
16470
16522
|
_throwBackgroundSubAgentUsageFailure(entry);
|
|
16471
|
-
messages.push(
|
|
16472
|
-
|
|
16473
|
-
|
|
16474
|
-
|
|
16475
|
-
|
|
16476
|
-
|
|
16523
|
+
messages.push(
|
|
16524
|
+
markRuntimeOnlySessionMessage({
|
|
16525
|
+
role: "user",
|
|
16526
|
+
content:
|
|
16527
|
+
_backgroundSubAgentResultText(entry) +
|
|
16528
|
+
"\n\nAll background sub-agents have finished. Incorporate their results and give your final answer.",
|
|
16529
|
+
}),
|
|
16530
|
+
);
|
|
16477
16531
|
taskProgressTracker.retainChildResult(
|
|
16478
16532
|
entry.id,
|
|
16479
16533
|
{
|
|
@@ -16498,17 +16552,24 @@ export async function* agentLoop(messages, options) {
|
|
|
16498
16552
|
const pending = [...pendingSubtreeMutations.values()];
|
|
16499
16553
|
if (!subtreeMutationReprompted && budget.remaining() > 0) {
|
|
16500
16554
|
subtreeMutationReprompted = true;
|
|
16501
|
-
messages.push(
|
|
16502
|
-
|
|
16503
|
-
|
|
16504
|
-
|
|
16505
|
-
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16511
|
-
|
|
16555
|
+
messages.push(
|
|
16556
|
+
markRuntimeOnlySessionMessage({
|
|
16557
|
+
role: "assistant",
|
|
16558
|
+
content: msg.content || "",
|
|
16559
|
+
}),
|
|
16560
|
+
);
|
|
16561
|
+
messages.push(
|
|
16562
|
+
markRuntimeOnlySessionMessage({
|
|
16563
|
+
role: "user",
|
|
16564
|
+
content:
|
|
16565
|
+
"Runtime status: these mutations were deferred before any effect: " +
|
|
16566
|
+
JSON.stringify(pending) +
|
|
16567
|
+
". Review the authoritative subtree instructions already returned. " +
|
|
16568
|
+
"If still authorized and appropriate, explicitly issue the required tool call. " +
|
|
16569
|
+
"Do not bypass rules or perform a prohibited write. Otherwise report the unfinished work and its blocker. " +
|
|
16570
|
+
"A promise to retry does not execute the mutation.",
|
|
16571
|
+
}),
|
|
16572
|
+
);
|
|
16512
16573
|
yield {
|
|
16513
16574
|
type: "iteration-warning",
|
|
16514
16575
|
message:
|
|
@@ -16551,13 +16612,17 @@ export async function* agentLoop(messages, options) {
|
|
|
16551
16612
|
const _contentEmpty = !String(msg.content || "").trim();
|
|
16552
16613
|
if (_contentEmpty && _thinking && !emptyThinkingReprompted) {
|
|
16553
16614
|
emptyThinkingReprompted = true;
|
|
16554
|
-
messages.push(
|
|
16555
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16615
|
+
messages.push(
|
|
16616
|
+
markRuntimeOnlySessionMessage({ role: "assistant", content: "" }),
|
|
16617
|
+
);
|
|
16618
|
+
messages.push(
|
|
16619
|
+
markRuntimeOnlySessionMessage({
|
|
16620
|
+
role: "user",
|
|
16621
|
+
content:
|
|
16622
|
+
"You ended your turn with only internal reasoning and no visible " +
|
|
16623
|
+
"response. Please provide your actual answer now.",
|
|
16624
|
+
}),
|
|
16625
|
+
);
|
|
16561
16626
|
yield { type: "empty-thinking-reprompt", runId };
|
|
16562
16627
|
continue;
|
|
16563
16628
|
}
|
|
@@ -16614,13 +16679,20 @@ export async function* agentLoop(messages, options) {
|
|
|
16614
16679
|
}
|
|
16615
16680
|
if (stopOutcome && stopOutcome.decision === "block") {
|
|
16616
16681
|
stopHookActive = true;
|
|
16617
|
-
messages.push(
|
|
16618
|
-
|
|
16619
|
-
|
|
16620
|
-
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16682
|
+
messages.push(
|
|
16683
|
+
markRuntimeOnlySessionMessage({
|
|
16684
|
+
role: "assistant",
|
|
16685
|
+
content: msg.content || "",
|
|
16686
|
+
}),
|
|
16687
|
+
);
|
|
16688
|
+
messages.push(
|
|
16689
|
+
markRuntimeOnlySessionMessage({
|
|
16690
|
+
role: "user",
|
|
16691
|
+
content:
|
|
16692
|
+
stopOutcome.reason ||
|
|
16693
|
+
"A Stop hook requested that you keep working.",
|
|
16694
|
+
}),
|
|
16695
|
+
);
|
|
16624
16696
|
yield {
|
|
16625
16697
|
type: "stop-hook-continue",
|
|
16626
16698
|
runId,
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
import { randomUUID } from "node:crypto";
|
|
26
|
+
import { isProxy } from "node:util/types";
|
|
26
27
|
import { transportErrorDetails } from "../lib/transport-error-details.js";
|
|
27
28
|
import { captureAgentExecutionPolicy } from "../lib/agent-execution-policy.js";
|
|
28
29
|
import { HERMETIC_CODING_SYSTEM_PROMPT } from "../lib/coding-task-guidance.js";
|
|
@@ -55,6 +56,8 @@ import {
|
|
|
55
56
|
appendToolCallCompact as jsonlAppendToolCallCompact,
|
|
56
57
|
appendLlmRetryCompact as jsonlAppendLlmRetryCompact,
|
|
57
58
|
appendCompactEvent as jsonlAppendCompactEvent,
|
|
59
|
+
appendCompactEventIfMessagesMatch as jsonlAppendCompactEventIfMessagesMatch,
|
|
60
|
+
appendToolRoundsIfMessagesMatch as jsonlAppendToolRoundsIfMessagesMatch,
|
|
58
61
|
appendEvent as jsonlAppendEvent,
|
|
59
62
|
appendAuthorityEvent as jsonlAppendAuthorityEvent,
|
|
60
63
|
readEvents as jsonlReadEvents,
|
|
@@ -68,6 +71,10 @@ import {
|
|
|
68
71
|
getLastSessionId as jsonlGetLastSessionId,
|
|
69
72
|
verifySession as jsonlVerifySession,
|
|
70
73
|
} from "../harness/jsonl-session-store.js";
|
|
74
|
+
import {
|
|
75
|
+
markRuntimeOnlySessionMessage,
|
|
76
|
+
projectCanonicalResumeMessages,
|
|
77
|
+
} from "../lib/session-message-provenance.js";
|
|
71
78
|
import { classifyStreamRetryReason } from "../lib/stream-retry.js";
|
|
72
79
|
import {
|
|
73
80
|
SideEffectLedger,
|
|
@@ -106,7 +113,7 @@ import { CLISkillLoader } from "../lib/skill-loader.js";
|
|
|
106
113
|
import { expandFileRefsAsync } from "./file-ref-expander.js";
|
|
107
114
|
import { composeSystemPrompt } from "./system-prompt.js";
|
|
108
115
|
import { buildUserContent } from "../lib/image-input.js";
|
|
109
|
-
import {
|
|
116
|
+
import { createResumeRoleProjection } from "./message-roles.js";
|
|
110
117
|
import { isHeadlessConfigCommand } from "../lib/headless-config-command.js";
|
|
111
118
|
import {
|
|
112
119
|
STREAM_PROTOCOL_VERSION,
|
|
@@ -1356,6 +1363,21 @@ async function runAgentHeadlessInWorkspace(
|
|
|
1356
1363
|
? () => null
|
|
1357
1364
|
: jsonlFindLatestEvent);
|
|
1358
1365
|
const store = {
|
|
1366
|
+
appendToolRoundsIfMessagesMatch:
|
|
1367
|
+
deps.appendToolRoundsIfMessagesMatch ||
|
|
1368
|
+
(hasInjectedSessionStore
|
|
1369
|
+
? unavailableAuthorityCapability("appendToolRoundsIfMessagesMatch")
|
|
1370
|
+
: jsonlAppendToolRoundsIfMessagesMatch),
|
|
1371
|
+
appendCompactEventIfMessagesMatch:
|
|
1372
|
+
deps.appendCompactEventIfMessagesMatch ||
|
|
1373
|
+
(hasInjectedSessionStore
|
|
1374
|
+
? unavailableAuthorityCapability("appendCompactEventIfMessagesMatch")
|
|
1375
|
+
: jsonlAppendCompactEventIfMessagesMatch),
|
|
1376
|
+
readVerifiedProjection:
|
|
1377
|
+
deps.readVerifiedProjection ||
|
|
1378
|
+
(hasInjectedSessionStore
|
|
1379
|
+
? unavailableAuthorityCapability("readVerifiedProjection")
|
|
1380
|
+
: jsonlReadVerifiedProjection),
|
|
1359
1381
|
sessionExists: deps.sessionExists || jsonlSessionExists,
|
|
1360
1382
|
rebuildMessages: deps.rebuildMessages || jsonlRebuildMessages,
|
|
1361
1383
|
startSession: deps.startSession || jsonlStartSession,
|
|
@@ -2150,12 +2172,14 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2150
2172
|
// content array (agent-core converts it per-provider for ollama/anthropic).
|
|
2151
2173
|
const userMessageContent = buildUserContent(userContent, options.images);
|
|
2152
2174
|
|
|
2153
|
-
//
|
|
2175
|
+
// Project consecutive same-role turns only at the provider boundary. A
|
|
2176
|
+
// resumed session whose previous run
|
|
2154
2177
|
// produced NO assistant response (history ends with a bare `user` turn) does
|
|
2155
2178
|
// not yield two adjacent `user` messages — which Anthropic/Bedrock reject as
|
|
2156
2179
|
// "roles must alternate", failing the resume (Claude Code 2.1.187 parity).
|
|
2157
2180
|
// No-op on a healthy alternating transcript.
|
|
2158
|
-
|
|
2181
|
+
// Keep the authority array identical to the durable transcript for CAS.
|
|
2182
|
+
const messages = [
|
|
2159
2183
|
{ role: "system", content: systemContent },
|
|
2160
2184
|
...(instructionsLoadedContext
|
|
2161
2185
|
? [{ role: "system", content: instructionsLoadedContext }]
|
|
@@ -2174,7 +2198,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2174
2198
|
: []),
|
|
2175
2199
|
...history,
|
|
2176
2200
|
{ role: "user", content: userMessageContent },
|
|
2177
|
-
]
|
|
2201
|
+
];
|
|
2178
2202
|
|
|
2179
2203
|
// Persist the user turn before model/tool side effects. A full or read-only
|
|
2180
2204
|
// session disk is a recoverability contract failure, so it fails closed
|
|
@@ -2199,7 +2223,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2199
2223
|
}
|
|
2200
2224
|
// Persist the expanded content so a resumed session faithfully replays
|
|
2201
2225
|
// what the model actually saw (the file snapshot, not just the @token).
|
|
2202
|
-
store.appendUserMessage(sessionId,
|
|
2226
|
+
store.appendUserMessage(sessionId, userMessageContent);
|
|
2203
2227
|
} catch (error) {
|
|
2204
2228
|
const persistenceError = createSessionPersistenceFailure(error, {
|
|
2205
2229
|
sessionId,
|
|
@@ -2393,19 +2417,20 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2393
2417
|
|
|
2394
2418
|
// IDE live context (Claude-Code parity): when an IDE bridge is connected,
|
|
2395
2419
|
// share the editor's selection/active file/open tabs with this turn. Appended
|
|
2396
|
-
//
|
|
2420
|
+
// as private live context only — AFTER persistence — so a resumed
|
|
2397
2421
|
// session replays the prompt, not a stale editor snapshot. Best-effort with
|
|
2398
2422
|
// a short timeout; CC_IDE_CONTEXT=0 disables.
|
|
2399
2423
|
if (!hermeticExecution) {
|
|
2400
2424
|
try {
|
|
2401
|
-
const { buildIdePromptContext,
|
|
2402
|
-
|
|
2403
|
-
|
|
2425
|
+
const { buildIdePromptContext, expandIdeMentions } = await import(
|
|
2426
|
+
"../lib/ide-context.js"
|
|
2427
|
+
);
|
|
2428
|
+
const ideBlocks = [];
|
|
2404
2429
|
const ideCtx = await (
|
|
2405
2430
|
deps.buildIdePromptContext || buildIdePromptContext
|
|
2406
2431
|
)(hostMcp);
|
|
2407
2432
|
if (ideCtx) {
|
|
2408
|
-
|
|
2433
|
+
ideBlocks.push(ideCtx);
|
|
2409
2434
|
}
|
|
2410
2435
|
// Explicit @selection / @diagnostics mentions in the user's prompt
|
|
2411
2436
|
// (Claude-Code parity). Scan the ORIGINAL prompt so injected file-ref
|
|
@@ -2414,7 +2439,15 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2414
2439
|
const mentioned = await expandIdeMentions(prompt, hostMcp);
|
|
2415
2440
|
for (const w of mentioned.warnings) writeErr(` @ide: ${w}\n`);
|
|
2416
2441
|
if (mentioned.block) {
|
|
2417
|
-
|
|
2442
|
+
ideBlocks.push(mentioned.block);
|
|
2443
|
+
}
|
|
2444
|
+
if (ideBlocks.length) {
|
|
2445
|
+
messages.push(
|
|
2446
|
+
markRuntimeOnlySessionMessage({
|
|
2447
|
+
role: "user",
|
|
2448
|
+
content: ideBlocks.join("\n\n"),
|
|
2449
|
+
}),
|
|
2450
|
+
);
|
|
2418
2451
|
}
|
|
2419
2452
|
} catch {
|
|
2420
2453
|
// IDE context is optional polish — never fail the run over it.
|
|
@@ -2811,10 +2844,65 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2811
2844
|
}
|
|
2812
2845
|
|
|
2813
2846
|
const childToolExecs = new Map();
|
|
2847
|
+
const synchronousAuthorityResult = (value, capability) => {
|
|
2848
|
+
if (isProxy(value)) {
|
|
2849
|
+
throw Object.assign(
|
|
2850
|
+
new Error(`${capability} must return non-Proxy authority`),
|
|
2851
|
+
{
|
|
2852
|
+
code: "SESSION_AUTHORITY_CAPABILITY_INVALID",
|
|
2853
|
+
},
|
|
2854
|
+
);
|
|
2855
|
+
}
|
|
2856
|
+
if (value && typeof value.then === "function") {
|
|
2857
|
+
void Promise.resolve(value).catch(() => {});
|
|
2858
|
+
throw Object.assign(
|
|
2859
|
+
new Error(`${capability} must settle synchronously`),
|
|
2860
|
+
{
|
|
2861
|
+
code: "SESSION_AUTHORITY_CAPABILITY_INVALID",
|
|
2862
|
+
},
|
|
2863
|
+
);
|
|
2864
|
+
}
|
|
2865
|
+
return value;
|
|
2866
|
+
};
|
|
2867
|
+
const settleToolRounds = () => {
|
|
2868
|
+
if (
|
|
2869
|
+
!persist ||
|
|
2870
|
+
!messages.some(
|
|
2871
|
+
(message) => message.role === "assistant" && message.tool_calls?.length,
|
|
2872
|
+
)
|
|
2873
|
+
)
|
|
2874
|
+
return;
|
|
2875
|
+
return persistRuntimeLedgerWrite(() => {
|
|
2876
|
+
sessionHostLease?.assert?.();
|
|
2877
|
+
const expected = synchronousAuthorityResult(
|
|
2878
|
+
store.readVerifiedProjection(sessionId, () => ({
|
|
2879
|
+
accept() {},
|
|
2880
|
+
finish(authority) {
|
|
2881
|
+
return authority.readMessages();
|
|
2882
|
+
},
|
|
2883
|
+
})),
|
|
2884
|
+
"readVerifiedProjection",
|
|
2885
|
+
);
|
|
2886
|
+
const appended = synchronousAuthorityResult(
|
|
2887
|
+
store.appendToolRoundsIfMessagesMatch(sessionId, messages, expected),
|
|
2888
|
+
"appendToolRoundsIfMessagesMatch",
|
|
2889
|
+
);
|
|
2890
|
+
if (typeof appended?.hash !== "string" || !appended.hash) {
|
|
2891
|
+
throw Object.assign(
|
|
2892
|
+
new Error("Tool round settlement did not return its durable head"),
|
|
2893
|
+
{
|
|
2894
|
+
code: "CC_SESSION_TOOL_ROUND_SETTLEMENT_HEAD_UNKNOWN",
|
|
2895
|
+
},
|
|
2896
|
+
);
|
|
2897
|
+
}
|
|
2898
|
+
return appended;
|
|
2899
|
+
});
|
|
2900
|
+
};
|
|
2814
2901
|
const loopOptions = {
|
|
2815
2902
|
...(evolutionIngress === null ? {} : { evolutionIngress }),
|
|
2816
2903
|
model,
|
|
2817
2904
|
provider,
|
|
2905
|
+
projectProviderMessages: createResumeRoleProjection(messages),
|
|
2818
2906
|
recorder: _otlpRecorder,
|
|
2819
2907
|
// --otlp-content: opt in to stamping prompt CONTENT onto --otlp spans. Off by
|
|
2820
2908
|
// default → content stays redacted (agent-core omits it entirely, so default
|
|
@@ -2916,6 +3004,28 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2916
3004
|
mcpDispatchAdmission: hermeticExecution
|
|
2917
3005
|
? null
|
|
2918
3006
|
: sessionHostLease?.admitMcpDispatch || null,
|
|
3007
|
+
persistCompaction: persist,
|
|
3008
|
+
onBeforeCompaction: settleToolRounds,
|
|
3009
|
+
onCompaction: persist
|
|
3010
|
+
? (stats, compacted, settlement = {}) =>
|
|
3011
|
+
persistRuntimeLedgerWrite(() => {
|
|
3012
|
+
sessionHostLease?.assert?.();
|
|
3013
|
+
return synchronousAuthorityResult(
|
|
3014
|
+
store.appendCompactEventIfMessagesMatch(
|
|
3015
|
+
sessionId,
|
|
3016
|
+
{
|
|
3017
|
+
...stats,
|
|
3018
|
+
trigger: settlement.trigger || "auto",
|
|
3019
|
+
messages: projectCanonicalResumeMessages(compacted, {
|
|
3020
|
+
strict: true,
|
|
3021
|
+
}),
|
|
3022
|
+
},
|
|
3023
|
+
settlement.expectedMessages,
|
|
3024
|
+
),
|
|
3025
|
+
"appendCompactEventIfMessagesMatch",
|
|
3026
|
+
);
|
|
3027
|
+
})
|
|
3028
|
+
: undefined,
|
|
2919
3029
|
// chatFn passthrough lets tests drive the loop deterministically.
|
|
2920
3030
|
chatFn: deps.chatFn || options.chatFn || undefined,
|
|
2921
3031
|
signal: options.signal || undefined,
|
|
@@ -3870,12 +3980,14 @@ async function runAgentHeadlessInWorkspace(
|
|
|
3870
3980
|
`${rw.error ? `: ${rw.error}` : ""}`,
|
|
3871
3981
|
)
|
|
3872
3982
|
.join("\n");
|
|
3873
|
-
messages.push(
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3983
|
+
messages.push(
|
|
3984
|
+
markRuntimeOnlySessionMessage({
|
|
3985
|
+
role: "user",
|
|
3986
|
+
content:
|
|
3987
|
+
`A background check flagged a problem after your last turn:\n${detail}\n` +
|
|
3988
|
+
`Investigate and fix it, then confirm it passes.`,
|
|
3989
|
+
}),
|
|
3990
|
+
);
|
|
3879
3991
|
if (isText)
|
|
3880
3992
|
writeErr(
|
|
3881
3993
|
` ↻ async-hook rewake — re-engaging agent (${rewakeBudget} re-drive(s) left)\n`,
|
|
@@ -3983,13 +4095,15 @@ async function runAgentHeadlessInWorkspace(
|
|
|
3983
4095
|
// and the next turn still resumes at the right point.
|
|
3984
4096
|
persistGoalSnapshot();
|
|
3985
4097
|
if (decision === _goalHelpers.GOAL_DECISION.CONTINUE) {
|
|
3986
|
-
messages.push(
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
4098
|
+
messages.push(
|
|
4099
|
+
markRuntimeOnlySessionMessage({
|
|
4100
|
+
role: "user",
|
|
4101
|
+
content:
|
|
4102
|
+
`The completion condition is not yet met: ${evaluation.reason}.\n` +
|
|
4103
|
+
`Keep working toward: "${cond.source}". When you believe it is ` +
|
|
4104
|
+
`satisfied, make sure it actually passes.`,
|
|
4105
|
+
}),
|
|
4106
|
+
);
|
|
3993
4107
|
finalText = "";
|
|
3994
4108
|
endReason = "complete";
|
|
3995
4109
|
if (isText)
|
|
@@ -4005,6 +4119,22 @@ async function runAgentHeadlessInWorkspace(
|
|
|
4005
4119
|
} catch (err) {
|
|
4006
4120
|
const runtimeLedgerPersistenceFailed =
|
|
4007
4121
|
err?.runtimeLedgerPersistence === true;
|
|
4122
|
+
const persistence = runtimeLedgerPersistenceFailed
|
|
4123
|
+
? projectSessionPersistenceFailure(
|
|
4124
|
+
createSessionPersistenceFailure(err, {
|
|
4125
|
+
sessionId,
|
|
4126
|
+
operation: "append-event",
|
|
4127
|
+
}),
|
|
4128
|
+
{ phase: "after-model" },
|
|
4129
|
+
)
|
|
4130
|
+
: null;
|
|
4131
|
+
if (persistence) {
|
|
4132
|
+
try {
|
|
4133
|
+
deps.onPersistenceFailure?.(persistence);
|
|
4134
|
+
} catch {
|
|
4135
|
+
// Observability cannot change persistence semantics.
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4008
4138
|
const sessionBudgetFailed =
|
|
4009
4139
|
err?.code === "CC_SESSION_BUDGET_EXHAUSTED" ||
|
|
4010
4140
|
err?.code === "CC_SESSION_BUDGET_USAGE_UNKNOWN" ||
|
|
@@ -4028,7 +4158,12 @@ async function runAgentHeadlessInWorkspace(
|
|
|
4028
4158
|
errorSubtype === "error" ? transportErrorDetails(err) : undefined;
|
|
4029
4159
|
const diagnosticFields = transportDetails
|
|
4030
4160
|
? { error_details: transportDetails }
|
|
4031
|
-
: {
|
|
4161
|
+
: {
|
|
4162
|
+
...(runtimeLedgerPersistenceFailed && err.code
|
|
4163
|
+
? { code: err.code }
|
|
4164
|
+
: {}),
|
|
4165
|
+
...(persistence ? { persistence } : {}),
|
|
4166
|
+
};
|
|
4032
4167
|
if (isStream) {
|
|
4033
4168
|
emitStream({
|
|
4034
4169
|
type: "result",
|
|
@@ -4067,6 +4202,8 @@ async function runAgentHeadlessInWorkspace(
|
|
|
4067
4202
|
: classifyLoopError(err),
|
|
4068
4203
|
result: message,
|
|
4069
4204
|
isError: true,
|
|
4205
|
+
...(persistence ? { persistence } : {}),
|
|
4206
|
+
...(runtimeLedgerPersistenceFailed && err.code ? { code: err.code } : {}),
|
|
4070
4207
|
};
|
|
4071
4208
|
} finally {
|
|
4072
4209
|
// Capture body-cache hits/misses caused by list_skills/run_skill during the
|
|
@@ -4250,16 +4387,21 @@ async function runAgentHeadlessInWorkspace(
|
|
|
4250
4387
|
: "success";
|
|
4251
4388
|
const durationMs = (deps.now ? deps.now() : Date.now()) - startedAt;
|
|
4252
4389
|
let persistenceFailure = null;
|
|
4390
|
+
let sessionPersistenceCode = null;
|
|
4253
4391
|
|
|
4254
|
-
//
|
|
4255
|
-
//
|
|
4256
|
-
if (persist
|
|
4392
|
+
// Complete tool evidence survives a clean budget stop. Only a successful
|
|
4393
|
+
// run appends a final assistant answer; settlement failure is always terminal.
|
|
4394
|
+
if (persist) {
|
|
4395
|
+
let persistenceOperation = "append-event";
|
|
4257
4396
|
try {
|
|
4258
|
-
|
|
4397
|
+
settleToolRounds();
|
|
4398
|
+
persistenceOperation = "assistant-turn-append";
|
|
4399
|
+
if (!isError && finalText)
|
|
4400
|
+
store.appendAssistantMessage(sessionId, finalText);
|
|
4259
4401
|
} catch (error) {
|
|
4260
4402
|
const persistenceError = createSessionPersistenceFailure(error, {
|
|
4261
4403
|
sessionId,
|
|
4262
|
-
operation:
|
|
4404
|
+
operation: persistenceOperation,
|
|
4263
4405
|
});
|
|
4264
4406
|
persistenceFailure = projectSessionPersistenceFailure(persistenceError, {
|
|
4265
4407
|
phase: "after-model",
|
|
@@ -4277,6 +4419,15 @@ async function runAgentHeadlessInWorkspace(
|
|
|
4277
4419
|
`CC_SESSION_PERSISTENCE_FAILED: assistant turn durability is ${persistenceFailure.commit_state} (${persistenceFailure.fs_code})\n`,
|
|
4278
4420
|
);
|
|
4279
4421
|
}
|
|
4422
|
+
} else if (error?.runtimeLedgerPersistence === true) {
|
|
4423
|
+
isError = true;
|
|
4424
|
+
subtype = "error_session_persistence";
|
|
4425
|
+
sessionPersistenceCode =
|
|
4426
|
+
error.code || "CC_SESSION_TOOL_ROUND_PERSISTENCE_FAILED";
|
|
4427
|
+
if (isText)
|
|
4428
|
+
writeErr(
|
|
4429
|
+
`${sessionPersistenceCode}: completed tool rounds could not be settled; refresh the session before continuing\n`,
|
|
4430
|
+
);
|
|
4280
4431
|
}
|
|
4281
4432
|
// Preserve legacy best-effort handling for errors outside the explicit
|
|
4282
4433
|
// ENOSPC/EROFS durability contract.
|
|
@@ -4416,11 +4567,12 @@ async function runAgentHeadlessInWorkspace(
|
|
|
4416
4567
|
? { compaction_degradations: compactionDegradations }
|
|
4417
4568
|
: {}),
|
|
4418
4569
|
...(persistenceFailure ? { persistence: persistenceFailure } : {}),
|
|
4570
|
+
...(sessionPersistenceCode ? { code: sessionPersistenceCode } : {}),
|
|
4419
4571
|
});
|
|
4420
4572
|
} else if (isJson) {
|
|
4421
4573
|
writeOut(
|
|
4422
|
-
JSON.stringify(
|
|
4423
|
-
buildResultEnvelope({
|
|
4574
|
+
JSON.stringify({
|
|
4575
|
+
...buildResultEnvelope({
|
|
4424
4576
|
subtype,
|
|
4425
4577
|
isError,
|
|
4426
4578
|
result: finalText,
|
|
@@ -4434,7 +4586,8 @@ async function runAgentHeadlessInWorkspace(
|
|
|
4434
4586
|
compactionDegradations,
|
|
4435
4587
|
persistence: persistenceFailure,
|
|
4436
4588
|
}),
|
|
4437
|
-
|
|
4589
|
+
...(sessionPersistenceCode ? { code: sessionPersistenceCode } : {}),
|
|
4590
|
+
}) + "\n",
|
|
4438
4591
|
);
|
|
4439
4592
|
} else {
|
|
4440
4593
|
// text: just the final answer on stdout.
|
|
@@ -4475,10 +4628,14 @@ async function runAgentHeadlessInWorkspace(
|
|
|
4475
4628
|
// Exit-code taxonomy: max-turns → 3, cost cap → 4 (both still non-zero, so
|
|
4476
4629
|
// "any failure" checks keep working; scripts can now tell exhaustion apart).
|
|
4477
4630
|
return {
|
|
4478
|
-
exitCode:
|
|
4631
|
+
exitCode:
|
|
4632
|
+
persistenceFailure || sessionPersistenceCode
|
|
4633
|
+
? 1
|
|
4634
|
+
: exitCodeForEndReason(endReason, isError),
|
|
4479
4635
|
result: finalText,
|
|
4480
4636
|
isError,
|
|
4481
4637
|
...(persistenceFailure ? { persistence: persistenceFailure } : {}),
|
|
4638
|
+
...(sessionPersistenceCode ? { code: sessionPersistenceCode } : {}),
|
|
4482
4639
|
};
|
|
4483
4640
|
}
|
|
4484
4641
|
|