chainlesschain 0.166.115 → 0.166.118
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 +43 -5
- package/package.json +4 -4
- 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/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-BsoSoDNb.js → AIOps-BGySwMIP.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Dcx7Gm5t.js → ActionButton-Chn7fBLr.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-S1hsBIz3.js → Analytics-ORH7UkGa.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-B2j067qM.js → AppLayout-8xV4jWjP.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-D5iGV9ic.js → Artifacts-26SBK-x-.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-C8ChVvXu.js → Audit-CtXpqbXg.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-Cg97AAJS.js → BackgroundAgents-C5zLvQis.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CyxU9IUg.js → Backup-C93xY4vO.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CKlWjA8I.js → BaseInput-DpVCHfAn.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-C-EqZza6.js → Chat-DM0LblR2.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BRFiXKPX.js → ChatBubbleRenderer-unlQUF1T.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-kkI13tSJ.js → Checkbox-BsAt3cKR.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-NlqEDwHK.js → Codegen-E_kp4KFd.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CfepEu79.js → Col-6msR3T6I.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BRo0qLXM.js → Community-PyX9c5D-.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BMu8TP0E.js → Compact-7G1bVDSH.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-B7Q3Moef.js → Compliance-DcHN7GlD.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BVwt7Xmc.js → Cowork-WUIHJYDx.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-CgBv20Qy.js → Cron-CWgCbptg.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CwcSBJk2.js → Crosschain-BzKZ6roD.js} +1 -1
- package/src/assets/web-panel/assets/{DID-d20rCiIm.js → DID-r7zxeItn.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-PpZaUYpS.js → Dashboard-D3pBiN2H.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DjsLdX_Z.js → Dropdown-C4otRJlZ.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CaPkrtxn.js → EmailListRenderer-CzDTC8lm.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-DDY8cQnE.js → EvolutionSettings-DGkXiIs-.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-VQavMjyj.js → FamilyGuardDashboard-BKdEyuiR.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D0GvKQgI.js → Federation-dsI-xcpf.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Dl_TWHmb.js → FormItemContext-CEEb1fMR.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Bny2uagG.js → GenericCardRenderer-D_mfO3Ts.js} +1 -1
- package/src/assets/web-panel/assets/{Git-B01KXq47.js → Git-CBwr2ZI3.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-F4c4Vwo1.js → Governance-D-Wy2Jjr.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-_025Q-8K.js → Inference-B4Yk_IRx.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DwbTmQb1.js → KnowledgeGraph-DoI7bi6m.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CnNo0hCm.js → Logs-Ce1IiKAj.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-GND_8y0V.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Dkz5bv7F.js → Marketplace-CsIEByzK.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CBtRwDW_.js → McpTools-_DRzjcIn.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-Y9jnyTb7.js → Memory-zvLpyi__.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Br1urkOz.js → MobileBridge-DXd1ik2Z.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DnsyuerX.js → MobileProjects-DKh2q-Y9.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-he3ZzieF.js → Mtc-Ct-fhtIx.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-BadphAuN.js → MtcAudit-J4zY3Oqk.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-3_pVLymK.js → Multisig-B2HJMCKe.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DmtmHfsI.js → NLProgramming-CwcSmU4q.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CE4L2O55.js → Notes-Da53L6wb.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-B7QmfJn9.js → NotificationSettings-BxhufdrA.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-O0wRSyJ0.js → OrderTableRenderer-BoFwohAi.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BrlMSsyT.js → Organization-MIsMrUes.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CY4ULPrZ.js → Overflow-Dy2P4v3q.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-kIANZYKd.js → P2P-CD9Sxn2y.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DEgB4rvF.js → PdhVaultBrowser-BvBWgfG0.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-CWxywRp5.js → Permissions-CwOlDRis.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DAg7iCbr.js → PersonalDataHub-CZYaxEpv.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-Brc6ONnR.js → Pipeline-kLU7PUbB.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CcinYTL8.js → Privacy-BVRycSiI.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Bz8XEsom.js → ProjectInit-DP3pr7uJ.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CsOMlSTZ.js → ProjectSettings-CACaDYjs.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CB1k4zTC.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CeunOQiH.js → Providers-D7Y9WHRE.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CN2a2_Fb.js → QrScannerModal-CeP8xzs1.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CVeLif3e.js → QuickAsk-iJVFrhZ2.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-1k9WOEGM.js → Recommend-DmTpnagw.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Q8UCqIMw.js → RemoteSession-C6ek8Uni.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CkrCgXKM.js → Reputation-CPfwc9de.js} +1 -1
- package/src/assets/web-panel/assets/{Row-JFdvuTzi.js → Row-C1wwtSMJ.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C74JHCmk.js → RssFeed-BiDJsqaH.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DrJiVO1T.js → Search-BF6Aon95.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BJzNlSJq.js → Security-Bps0XnV4.js} +3 -3
- package/src/assets/web-panel/assets/{Services-D4TLMnJm.js → Services-uf92smGR.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-cswTDqhh.js → Skeleton-DQd4eVWW.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Bv0rM1BS.js → Skills-DgamiYa5.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-D9rE7hNh.js → Sla-CF1IVIrm.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-Bzxmjbpc.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-BwnMG8kq.js → SyncSettings-B8zKauiq.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-wJvU24cB.js → Tasks-DPKV_xSt.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CZbRU3tN.js → Templates-BikeSZIF.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-_jbpFJPZ.js → Tenant-CEaUaDkJ.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BzNm5WKZ.js → Terminal-ZPgOSQ_q.js} +3 -3
- package/src/assets/web-panel/assets/{TimelineRenderer-bmybWjuS.js → TimelineRenderer-DmyB4Udk.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-o1WDcqVQ.js → Tokens-g85Pm5TO.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BB1D6sIB.js → Trigger-D202hx9a.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CLxdCfy2.js → Trust-DzvQYVFy.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B9LS6vS0.js → UkeySign-KRzwddVg.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Bg0-wxjz.js → VideoEditing-IRBXLO2z.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Bw0G2F6P.js → Wallet-DSf5KPgQ.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-irEiNY9b.js → WebAuthn-DNPxLTCc.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-Bh08FbJs.js → WorkflowEditor-C3wAtVcK.js} +1 -1
- package/src/assets/web-panel/assets/{addon-fit-CK6X9sAG.js → addon-fit-CbkjSUJl.js} +1 -1
- package/src/assets/web-panel/assets/{chat-De-FPjVT.js → chat-q3XXUtv2.js} +1 -1
- package/src/assets/web-panel/assets/{colors-ygdyvinU.js → colors-CF54SNei.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BQ9jH9KV.js → compact-item-BaRkvZuT.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BFuVSyox.js → createContext-CDR9hsfs.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-1LO-NplX.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-i19GtR1P.js → hasIn-DlC--S8R.js} +1 -1
- package/src/assets/web-panel/assets/{index-DS1IwwGL.js → index-B0Ptc7yu.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1IsP_JO.js → index-B0V9rgdu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWfgeaG4.js → index-BEiUlFKb.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTY20pWu.js → index-BJO0n1LQ.js} +1 -1
- package/src/assets/web-panel/assets/index-BLaJsev4.js +1 -0
- package/src/assets/web-panel/assets/index-BLmviChG.js +1 -0
- package/src/assets/web-panel/assets/{index-IXkif6J_.js → index-BU5DJqk7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVhtukYX.js → index-BY-Tf3OM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKlU5VZy.js → index-BZrE0Go8.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bw5pTpnI.js → index-BizdX2X5.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGMxK155.js → index-C87Yr3h1.js} +1 -1
- package/src/assets/web-panel/assets/{index-DVnFgasM.js → index-C9Wypz9e.js} +1 -1
- package/src/assets/web-panel/assets/{index-C61w3omz.js → index-CAoG_E-q.js} +1 -1
- package/src/assets/web-panel/assets/{index-l5-J0jHx.js → index-CAxSyMrF.js} +1 -1
- package/src/assets/web-panel/assets/{index-28DjsABm.js → index-CC5HjNM6.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPUCvc8i.js → index-CNZQEZ9g.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpdXhhMY.js → index-CPvIhha6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAboGZTw.js → index-CR_wqMGy.js} +1 -1
- package/src/assets/web-panel/assets/{index-DL7ewjD2.js → index-CSClXoB3.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bhf-MuUh.js → index-CZ8azVgB.js} +3 -3
- package/src/assets/web-panel/assets/{index-BaaydJcC.js → index-Ccc5z8eJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2LieObB.js → index-CeiKbM3a.js} +1 -1
- package/src/assets/web-panel/assets/{index-We2nK3ju.js → index-Cl6av3X7.js} +1 -1
- package/src/assets/web-panel/assets/{index-m8waSAyv.js → index-CtGfeD7E.js} +1 -1
- package/src/assets/web-panel/assets/{index-cDJsyAkI.js → index-Ctid12Gq.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlwxUZQL.js → index-D0H-N0uG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBYiCI1d.js → index-D0vIgprF.js} +1 -1
- package/src/assets/web-panel/assets/{index-_9tUBcLm.js → index-D4wUDFRg.js} +1 -1
- package/src/assets/web-panel/assets/{index-4HoFz1MA.js → index-DJFipyK7.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cq9k4-Ws.js → index-DX2REKNp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuuOX5u3.js → index-Dc3gD0cw.js} +1 -1
- package/src/assets/web-panel/assets/{index-DgjLaB7k.js → index-DiQzer2R.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMNjaSir.js → index-DntKLOs9.js} +1 -1
- package/src/assets/web-panel/assets/{index-vXtH3o6O.js → index-Dplhl6gh.js} +1 -1
- package/src/assets/web-panel/assets/{index-BLMtCKAY.js → index-Dq8q_PWB.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXrk8OYO.js → index-IVQdOBNN.js} +1 -1
- package/src/assets/web-panel/assets/{index-CBVcGaxk.js → index-Kerduyao.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKblSCL9.js → index-W6cLGjpW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgoSgmjK.js → index-qZDNFll9.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-B_EZHeqN.js → initDefaultProps-Ccz7v71u.js} +1 -1
- package/src/assets/web-panel/assets/{markdown-Yo_c6Krv.js → markdown-Bq2x0XsR.js} +1 -1
- package/src/assets/web-panel/assets/markdown-DUKxbhE4.js +51 -0
- package/src/assets/web-panel/assets/{motion-BrVb_Gy1.js → motion-BlCLpVDp.js} +1 -1
- package/src/assets/web-panel/assets/{move-CKxVRL_J.js → move-B80G7fLU.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C80rvQ1J.js → mtc-parser-Djw08NJh.js} +1 -1
- package/src/assets/web-panel/assets/{omit-De5vD7BR.js → omit-Bg_G1eUr.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BTyEDjth.js → pickAttrs-Df9zYUg2.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BWR94AjR.js → placementArrow-DjCDLhJ4.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-1g-Vnibk.js → responsiveObserve--Naz7NgY.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Dmg6dYuF.js → slide-CHn3ald-.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Ddj6rSab.js → statusUtils-BiGwoIK_.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DyP1mPDf.js → styleChecker-Zf2dQx1j.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D3d_0YuY.js → useFlexGapSupport-sLES8nyD.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-M3vq-gE2.js → useFs-DV1Hl4qu.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-GtP2TgtK.js → usePersonalDataHub-CZXr2Qxg.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BurE2ATQ.js → vnode-e8Eo3Oyl.js} +1 -1
- package/src/assets/web-panel/assets/{xterm-BZcWGsqw.js → xterm-zbskxxGA.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Ch-ViiDe.js → zoom-B8A6xKMF.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/compact.js +7 -2
- package/src/data/changelog.json +27 -1
- package/src/harness/jsonl-session-store.js +80 -74
- package/src/harness/prompt-compressor.js +57 -3
- package/src/lib/artifact-store.js +129 -20
- package/src/lib/bounded-artifact-file-read.js +128 -46
- package/src/lib/context-memory-kernel/context-image-transport.js +248 -0
- package/src/lib/context-memory-kernel/jsonl-session-context-port.js +4 -1
- package/src/lib/context-memory-kernel/live-compaction.js +40 -10
- package/src/lib/context-memory-kernel/message-adapter.js +80 -10
- package/src/lib/context-memory-kernel/message-bundle-store.js +1140 -0
- package/src/lib/context-memory-kernel/provider-context.js +23 -8
- package/src/lib/evolution/agent-evolution-ingress.js +103 -19
- package/src/lib/evolution/agent-evolution-runtime-composition.js +65 -27
- package/src/lib/evolution/agent-model-projection.js +90 -18
- package/src/lib/evolution/evidence-json-text.js +341 -42
- package/src/lib/evolution/evolution-artifact-ports.js +1005 -83
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +59 -15
- package/src/lib/evolution/evolution-evidence-projector.js +153 -16
- package/src/lib/evolution/evolution-evidence-storage-layout.js +115 -0
- package/src/lib/evolution/evolution-file-witness.js +7 -3
- package/src/lib/evolution/evolution-ledger-file-manifest-catalog.js +6 -2
- package/src/lib/evolution/evolution-ledger-file-manifest-head-store.js +6 -2
- package/src/lib/evolution/evolution-ledger.js +226 -55
- package/src/lib/evolution/evolution-private-storage.js +20 -0
- package/src/lib/evolution/evolution-run-ledger-adapter.js +298 -11
- package/src/lib/evolution/evolution-windows-directory-durability.js +215 -32
- package/src/lib/evolution/local-ui-evolution-runtime.js +3 -38
- package/src/lib/evolution/local-ui-signing-authority.js +69 -0
- package/src/lib/image-token-estimate.js +59 -0
- package/src/lib/ollama-provider-fetch.js +33 -0
- package/src/lib/provider-stream.js +14 -13
- package/src/lib/read-file-loop-guard.js +7 -4
- package/src/lib/session-history-origins.js +94 -35
- package/src/lib/session-message-provenance.js +26 -2
- package/src/lib/session-runtime-retention.js +10 -1
- package/src/lib/session-transcript-history.js +5 -1
- package/src/lib/session-transcript-migration.js +67 -12
- package/src/lib/storage-failure-cause-codes.js +449 -0
- package/src/lib/tool-result-preview.js +276 -0
- package/src/runtime/agent-core.js +111 -92
- package/src/runtime/headless-stream.js +121 -27
- package/src/assets/web-panel/assets/MarkdownRenderer-D8_iZief.js +0 -1
- package/src/assets/web-panel/assets/Projects-BeSOM6wi.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-Bfhvin8B.js +0 -1
- package/src/assets/web-panel/assets/devWarning-c2I2Rn4_.js +0 -1
- package/src/assets/web-panel/assets/index-CTs4dYcV.js +0 -1
- package/src/assets/web-panel/assets/index-DeuvaW15.js +0 -1
- package/src/assets/web-panel/assets/markdown-CsiA8-E5.js +0 -50
|
@@ -11,6 +11,11 @@ import {
|
|
|
11
11
|
memoryRecordsToContextItems,
|
|
12
12
|
messagesToContextItems,
|
|
13
13
|
} from "./message-adapter.js";
|
|
14
|
+
import {
|
|
15
|
+
adjustContextImageTokenEstimates,
|
|
16
|
+
captureContextImageTransport,
|
|
17
|
+
restoreContextImageTransport,
|
|
18
|
+
} from "./context-image-transport.js";
|
|
14
19
|
|
|
15
20
|
export const SEMANTIC_CANDIDATE_REQUEST_SCHEMA =
|
|
16
21
|
"chainlesschain.context-memory-semantic-candidate-request/v1";
|
|
@@ -217,12 +222,17 @@ export async function prepareCanonicalProviderContext(
|
|
|
217
222
|
),
|
|
218
223
|
...(semanticCandidates === undefined ? {} : { semanticCandidates }),
|
|
219
224
|
});
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
const imageTransport = captureContextImageTransport(messages);
|
|
226
|
+
const messageItems = adjustContextImageTokenEstimates(
|
|
227
|
+
messagesToContextItems(imageTransport.messages, {
|
|
228
|
+
sessionId,
|
|
229
|
+
allowedSinks: [sink],
|
|
230
|
+
trustCurrentSystemPolicy: true,
|
|
231
|
+
trustedSystemIndexes: options.contextMemoryTrustedSystemIndexes,
|
|
232
|
+
allowExternalization: false,
|
|
233
|
+
}),
|
|
234
|
+
imageTransport.captures,
|
|
235
|
+
);
|
|
226
236
|
const memoryItems = memoryRecordsToContextItems(
|
|
227
237
|
recall.results.map((entry) => entry.record),
|
|
228
238
|
{ insertionSequence: Math.max(0, messages.length - 1) },
|
|
@@ -290,9 +300,14 @@ export async function prepareCanonicalProviderContext(
|
|
|
290
300
|
sessionHead,
|
|
291
301
|
memoryRevision: recall.memoryRevision,
|
|
292
302
|
});
|
|
303
|
+
const selectedMessages = contextItemsToMessages(
|
|
304
|
+
plan.selected.filter((item) => item.kind !== "tool-schema"),
|
|
305
|
+
{ sessionId },
|
|
306
|
+
);
|
|
293
307
|
return {
|
|
294
|
-
messages:
|
|
295
|
-
|
|
308
|
+
messages: restoreContextImageTransport(
|
|
309
|
+
selectedMessages,
|
|
310
|
+
imageTransport.captures,
|
|
296
311
|
),
|
|
297
312
|
selectedToolNames: toolItems
|
|
298
313
|
.filter((item) => plan.selectedItemIds.includes(item.itemId))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { types } from "node:util";
|
|
3
3
|
import evolutionRun from "@chainlesschain/session-core/evolution-run";
|
|
4
|
+
import { storageFailureCauseSuffix } from "../storage-failure-cause-codes.js";
|
|
4
5
|
|
|
5
6
|
import { EvolutionEvidenceArtifactAdapter } from "./evolution-evidence-artifact-adapter.js";
|
|
6
7
|
import {
|
|
@@ -8,13 +9,21 @@ import {
|
|
|
8
9
|
EVOLUTION_SKILL_DECISION_PROJECTION_RULESET_DIGEST,
|
|
9
10
|
EVOLUTION_PROJECTION_RULESET_DIGEST,
|
|
10
11
|
} from "./evolution-evidence-projector.js";
|
|
11
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
EvolutionRunLedgerAdapter,
|
|
14
|
+
captureEvolutionRunAppendNext,
|
|
15
|
+
} from "./evolution-run-ledger-adapter.js";
|
|
16
|
+
import {
|
|
17
|
+
evidenceStorageLayoutForRun,
|
|
18
|
+
validateEvidenceStorageLayout,
|
|
19
|
+
} from "./evolution-evidence-storage-layout.js";
|
|
12
20
|
import { captureEvolutionRunWikiMaintenanceProducer } from "./evolution-run-wiki-maintenance-source.js";
|
|
13
21
|
import { WIKI_MAINTENANCE_TRIGGER_KIND } from "./wiki-maintenance-trigger-ledger-adapter.js";
|
|
14
22
|
import { captureEvolutionReleaseTrain } from "./evolution-release-train.js";
|
|
15
23
|
import {
|
|
16
24
|
snapshotAgentModelRequest,
|
|
17
25
|
buildAgentModelRequest,
|
|
26
|
+
projectAgentOpaqueTransportBlock,
|
|
18
27
|
} from "./agent-model-projection.js";
|
|
19
28
|
import {
|
|
20
29
|
snapshotSkillDecisionRequest,
|
|
@@ -28,8 +37,7 @@ export const AGENT_EVOLUTION_INGRESS_SCHEMA =
|
|
|
28
37
|
export const AGENT_EVOLUTION_INGRESS_FAILED_CODE =
|
|
29
38
|
"CC_AGENT_EVOLUTION_INGRESS_FAILED";
|
|
30
39
|
|
|
31
|
-
const RESPONSE_CACHE_RECORD_SCHEMA =
|
|
32
|
-
"chainlesschain.model-response-cache/v2";
|
|
40
|
+
const RESPONSE_CACHE_RECORD_SCHEMA = "chainlesschain.model-response-cache/v2";
|
|
33
41
|
const LEGACY_RESPONSE_CACHE_RECORD_SCHEMA =
|
|
34
42
|
"chainlesschain.model-response-cache/v1";
|
|
35
43
|
const RESPONSE_CACHE_IDENTIFIER_BINDING_SCHEMA =
|
|
@@ -152,6 +160,7 @@ function ingressFailure(cause) {
|
|
|
152
160
|
`Agent evolution ingress failed: ${cause?.message || String(cause)}`,
|
|
153
161
|
{ cause },
|
|
154
162
|
);
|
|
163
|
+
error.message += storageFailureCauseSuffix(cause);
|
|
155
164
|
error.code = AGENT_EVOLUTION_INGRESS_FAILED_CODE;
|
|
156
165
|
return error;
|
|
157
166
|
}
|
|
@@ -165,6 +174,7 @@ function guardIngress(operation) {
|
|
|
165
174
|
export function createAgentEvolutionIngress({
|
|
166
175
|
evidenceAdapter,
|
|
167
176
|
runAdapter,
|
|
177
|
+
evidenceStorageLayout = "legacy",
|
|
168
178
|
sourceEnvelopeAuthority,
|
|
169
179
|
openCacheSourceRun = null,
|
|
170
180
|
wikiMaintenanceProducer = null,
|
|
@@ -173,6 +183,7 @@ export function createAgentEvolutionIngress({
|
|
|
173
183
|
now = () => new Date(),
|
|
174
184
|
idGenerator = () => crypto.randomUUID(),
|
|
175
185
|
} = {}) {
|
|
186
|
+
validateEvidenceStorageLayout(evidenceStorageLayout);
|
|
176
187
|
if (!(evidenceAdapter instanceof EvolutionEvidenceArtifactAdapter)) {
|
|
177
188
|
throw new TypeError("an EvolutionEvidenceArtifactAdapter is required");
|
|
178
189
|
}
|
|
@@ -245,10 +256,24 @@ export function createAgentEvolutionIngress({
|
|
|
245
256
|
return timestamp(iso, "ingress timestamp");
|
|
246
257
|
};
|
|
247
258
|
|
|
259
|
+
const assertLoadedLayout = (loaded) => {
|
|
260
|
+
if (
|
|
261
|
+
evidenceStorageLayoutForRun(loaded.events, evidenceStorageLayout) !==
|
|
262
|
+
evidenceStorageLayout
|
|
263
|
+
)
|
|
264
|
+
throw new Error("Authenticated Run Evidence storage layout changed");
|
|
265
|
+
};
|
|
266
|
+
|
|
248
267
|
const appendStarted = () => {
|
|
249
268
|
const loaded = runAdapter.load();
|
|
269
|
+
assertLoadedLayout(loaded);
|
|
250
270
|
if (loaded.events.length > 0) return loaded.projection;
|
|
251
271
|
const occurredAt = currentTimestamp();
|
|
272
|
+
const data = {
|
|
273
|
+
occurredAt,
|
|
274
|
+
runtime: "agent",
|
|
275
|
+
...(evidenceStorageLayout === "legacy" ? {} : { evidenceStorageLayout }),
|
|
276
|
+
};
|
|
252
277
|
return runAdapter.appendEvent({
|
|
253
278
|
schema: EVOLUTION_RUN_EVENT_SCHEMA,
|
|
254
279
|
tenantId: descriptor.tenantId,
|
|
@@ -257,10 +282,10 @@ export function createAgentEvolutionIngress({
|
|
|
257
282
|
sequence: 1,
|
|
258
283
|
type: EVENT_TYPES.RUN_STARTED,
|
|
259
284
|
subjectId: descriptor.runId,
|
|
260
|
-
payloadDigest: digest(
|
|
285
|
+
payloadDigest: digest(data),
|
|
261
286
|
artifactRef: null,
|
|
262
287
|
keyRef: null,
|
|
263
|
-
data
|
|
288
|
+
data,
|
|
264
289
|
}).projection;
|
|
265
290
|
};
|
|
266
291
|
|
|
@@ -294,8 +319,7 @@ export function createAgentEvolutionIngress({
|
|
|
294
319
|
const payload = cacheRecord
|
|
295
320
|
? {
|
|
296
321
|
schema: RESPONSE_CACHE_RECORD_SCHEMA,
|
|
297
|
-
identifierBindingSchema:
|
|
298
|
-
RESPONSE_CACHE_IDENTIFIER_BINDING_SCHEMA,
|
|
322
|
+
identifierBindingSchema: RESPONSE_CACHE_IDENTIFIER_BINDING_SCHEMA,
|
|
299
323
|
requestKeyBinding: cacheIdentifierBinding(
|
|
300
324
|
"request key",
|
|
301
325
|
evidence.requestKey,
|
|
@@ -348,13 +372,14 @@ export function createAgentEvolutionIngress({
|
|
|
348
372
|
"Agent evidence persistence returned an unbound result",
|
|
349
373
|
);
|
|
350
374
|
}
|
|
351
|
-
const
|
|
352
|
-
|
|
375
|
+
const appendNext = captureEvolutionRunAppendNext(runAdapter);
|
|
376
|
+
// Custom ports keep their established load-before-append phase.
|
|
377
|
+
const current = appendNext === null ? runAdapter.load() : null;
|
|
378
|
+
const event = {
|
|
353
379
|
schema: EVOLUTION_RUN_EVENT_SCHEMA,
|
|
354
380
|
tenantId: descriptor.tenantId,
|
|
355
381
|
runId: descriptor.runId,
|
|
356
382
|
eventId,
|
|
357
|
-
sequence: current.events.length + 1,
|
|
358
383
|
type: EVENT_TYPES.RAW_EVENT_REFERENCED,
|
|
359
384
|
subjectId: persisted.evidenceId,
|
|
360
385
|
payloadDigest: persisted.manifest.digest,
|
|
@@ -372,7 +397,14 @@ export function createAgentEvolutionIngress({
|
|
|
372
397
|
candidateSetDigest: skillDecisionRequest.candidateSetDigest,
|
|
373
398
|
}),
|
|
374
399
|
},
|
|
375
|
-
}
|
|
400
|
+
};
|
|
401
|
+
const appended =
|
|
402
|
+
appendNext !== null
|
|
403
|
+
? appendNext(event)
|
|
404
|
+
: runAdapter.appendEvent({
|
|
405
|
+
...event,
|
|
406
|
+
sequence: current.events.length + 1,
|
|
407
|
+
});
|
|
376
408
|
if (kind === "model-input") {
|
|
377
409
|
lastModelResponse = null;
|
|
378
410
|
modelAdmissionPending = true;
|
|
@@ -537,12 +569,11 @@ export function createAgentEvolutionIngress({
|
|
|
537
569
|
throw new Error(
|
|
538
570
|
"Cache response projection is not safe or request-bound",
|
|
539
571
|
);
|
|
540
|
-
const responseEvent = loaded.events.find(
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
record.sourceEventIdBinding,
|
|
572
|
+
const responseEvent = loaded.events.find((item) =>
|
|
573
|
+
legacyRecord
|
|
574
|
+
? item.eventId === record.sourceEventId
|
|
575
|
+
: cacheIdentifierBinding("source event ID", item.eventId) ===
|
|
576
|
+
record.sourceEventIdBinding,
|
|
546
577
|
);
|
|
547
578
|
if (
|
|
548
579
|
responseEvent?.data?.evidenceKind !== "response-completed" ||
|
|
@@ -589,8 +620,60 @@ export function createAgentEvolutionIngress({
|
|
|
589
620
|
}
|
|
590
621
|
return ingest("model-input", snapshot, {}, snapshot);
|
|
591
622
|
},
|
|
592
|
-
ingestUserPrompt: async (input, options) =>
|
|
593
|
-
|
|
623
|
+
ingestUserPrompt: async (input, options) => {
|
|
624
|
+
const snapshot = cloneEvidence(input);
|
|
625
|
+
try {
|
|
626
|
+
if (
|
|
627
|
+
Array.isArray(snapshot?.messages) &&
|
|
628
|
+
typeof snapshot.source === "string"
|
|
629
|
+
) {
|
|
630
|
+
const captured = snapshotAgentModelRequest({
|
|
631
|
+
messages: snapshot.messages,
|
|
632
|
+
tools: [],
|
|
633
|
+
});
|
|
634
|
+
// User-prompt is a small event, not a second image transport. Bind
|
|
635
|
+
// each image to its complete original block; model-input admission
|
|
636
|
+
// separately retains the original image in encrypted Raw evidence.
|
|
637
|
+
snapshot.messages = captured.messages.map(
|
|
638
|
+
(message, messageIndex) => ({
|
|
639
|
+
...message,
|
|
640
|
+
...(Array.isArray(message.content)
|
|
641
|
+
? {
|
|
642
|
+
content: message.content.map((block, blockIndex) =>
|
|
643
|
+
block.type === "image_url"
|
|
644
|
+
? projectAgentOpaqueTransportBlock(
|
|
645
|
+
block,
|
|
646
|
+
`messages.${messageIndex}.content.${blockIndex}`,
|
|
647
|
+
)
|
|
648
|
+
: block,
|
|
649
|
+
),
|
|
650
|
+
}
|
|
651
|
+
: {}),
|
|
652
|
+
}),
|
|
653
|
+
);
|
|
654
|
+
} else if (Array.isArray(snapshot?.content)) {
|
|
655
|
+
const captured = snapshotAgentModelRequest({
|
|
656
|
+
messages: [{ role: "user", content: snapshot.content }],
|
|
657
|
+
tools: [],
|
|
658
|
+
});
|
|
659
|
+
// REPL callers pass the current user content directly, without a
|
|
660
|
+
// source label or a messages wrapper. Apply the same image binding.
|
|
661
|
+
snapshot.content = captured.messages[0].content.map(
|
|
662
|
+
(block, blockIndex) =>
|
|
663
|
+
block.type === "image_url"
|
|
664
|
+
? projectAgentOpaqueTransportBlock(
|
|
665
|
+
block,
|
|
666
|
+
`messages.0.content.${blockIndex}`,
|
|
667
|
+
)
|
|
668
|
+
: block,
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
} catch (error) {
|
|
672
|
+
admissionFailure ??= ingressFailure(error);
|
|
673
|
+
throw admissionFailure;
|
|
674
|
+
}
|
|
675
|
+
return ingest("user-prompt", { input: snapshot }, options);
|
|
676
|
+
},
|
|
594
677
|
ingestAgentEvent: async (event, options) => {
|
|
595
678
|
if (admissionFailure !== null) throw admissionFailure;
|
|
596
679
|
let type;
|
|
@@ -627,6 +710,7 @@ export function createAgentEvolutionIngress({
|
|
|
627
710
|
serialize(async () => {
|
|
628
711
|
if (admissionFailure !== null) throw admissionFailure;
|
|
629
712
|
const loaded = runAdapter.load();
|
|
713
|
+
assertLoadedLayout(loaded);
|
|
630
714
|
let projection;
|
|
631
715
|
if (loaded.projection?.status === "completed") {
|
|
632
716
|
projection = loaded.projection;
|
|
@@ -14,6 +14,11 @@ import {
|
|
|
14
14
|
EvolutionEvidenceReader,
|
|
15
15
|
} from "./evolution-evidence-projector.js";
|
|
16
16
|
import { EvolutionArtifactPorts } from "./evolution-artifact-ports.js";
|
|
17
|
+
import {
|
|
18
|
+
createTypedEvidenceArtifactPorts,
|
|
19
|
+
evidenceStorageLayoutForRun,
|
|
20
|
+
validateEvidenceStorageLayout,
|
|
21
|
+
} from "./evolution-evidence-storage-layout.js";
|
|
17
22
|
import {
|
|
18
23
|
captureEvolutionLedgerFileBackend,
|
|
19
24
|
createEvolutionLedgerFileBackend,
|
|
@@ -172,16 +177,14 @@ function layout(stateRootDir, tenantId, runId, initialize = true, fsImpl = fs) {
|
|
|
172
177
|
const result = Object.freeze({
|
|
173
178
|
rootDir,
|
|
174
179
|
artifactDir: path.join(scope, "artifacts"),
|
|
180
|
+
evidenceArtifactDir: path.join(scope, "evidence-artifacts"),
|
|
175
181
|
rawDir: path.join(scope, "raw"),
|
|
176
182
|
ledgerRootDir: path.join(scope, "ledger-events"),
|
|
177
183
|
ledgerAuthorityRootDir: path.join(scope, "ledger-authority"),
|
|
178
184
|
witnessFilePath: path.join(scope, "witness", "checkpoint.json"),
|
|
179
185
|
});
|
|
180
186
|
if (initialize) {
|
|
181
|
-
ensureDirectoryTreeDurable(
|
|
182
|
-
fsImpl,
|
|
183
|
-
path.dirname(result.witnessFilePath),
|
|
184
|
-
);
|
|
187
|
+
ensureDirectoryTreeDurable(fsImpl, path.dirname(result.witnessFilePath));
|
|
185
188
|
}
|
|
186
189
|
return result;
|
|
187
190
|
}
|
|
@@ -224,6 +227,7 @@ export function createAgentEvolutionRuntimeComposition({
|
|
|
224
227
|
stateRootDir,
|
|
225
228
|
authorities: authorityInput,
|
|
226
229
|
evidenceTtlMs,
|
|
230
|
+
evidenceStorageLayout = "legacy",
|
|
227
231
|
witnessId: witnessIdInput,
|
|
228
232
|
clock: clockInput = Date.now,
|
|
229
233
|
evidenceIdGenerator,
|
|
@@ -240,6 +244,7 @@ export function createAgentEvolutionRuntimeComposition({
|
|
|
240
244
|
witnessMaximumBytes,
|
|
241
245
|
ledgerV2: ledgerV2Input = null,
|
|
242
246
|
} = {}) {
|
|
247
|
+
validateEvidenceStorageLayout(evidenceStorageLayout);
|
|
243
248
|
const ledgerV2 =
|
|
244
249
|
ledgerV2Input === null
|
|
245
250
|
? null
|
|
@@ -445,14 +450,6 @@ export function createAgentEvolutionRuntimeComposition({
|
|
|
445
450
|
attestationVerifier: ports.attestationVerifier,
|
|
446
451
|
now: () => new Date(clock()),
|
|
447
452
|
});
|
|
448
|
-
const evidenceAdapter = new EvolutionEvidenceArtifactAdapter({
|
|
449
|
-
tenantId,
|
|
450
|
-
audience,
|
|
451
|
-
projector,
|
|
452
|
-
bundleVerifier,
|
|
453
|
-
artifactPorts,
|
|
454
|
-
...(evidenceTtlMs === undefined ? {} : { ttlMs: evidenceTtlMs }),
|
|
455
|
-
});
|
|
456
453
|
const ledgerArtifactResolver =
|
|
457
454
|
artifactPorts.createEvolutionLedgerArtifactResolver({
|
|
458
455
|
purpose: "evolution-ledger",
|
|
@@ -516,6 +513,46 @@ export function createAgentEvolutionRuntimeComposition({
|
|
|
516
513
|
ledgerArtifactResolver,
|
|
517
514
|
now: clock,
|
|
518
515
|
});
|
|
516
|
+
const createEvidenceAdapter = (run, runStorage, mainPorts, emptyLayout) => {
|
|
517
|
+
const loaded = run.load();
|
|
518
|
+
const selectedLayout = evidenceStorageLayoutForRun(
|
|
519
|
+
loaded.events,
|
|
520
|
+
emptyLayout,
|
|
521
|
+
);
|
|
522
|
+
return {
|
|
523
|
+
selectedLayout,
|
|
524
|
+
adapter: new EvolutionEvidenceArtifactAdapter({
|
|
525
|
+
tenantId,
|
|
526
|
+
audience,
|
|
527
|
+
projector,
|
|
528
|
+
bundleVerifier,
|
|
529
|
+
...(selectedLayout === "legacy"
|
|
530
|
+
? { artifactPorts: mainPorts }
|
|
531
|
+
: {
|
|
532
|
+
typedArtifactPorts: createTypedEvidenceArtifactPorts({
|
|
533
|
+
rootDir: runStorage.evidenceArtifactDir,
|
|
534
|
+
tenantId,
|
|
535
|
+
audience,
|
|
536
|
+
artifactAuthority: {
|
|
537
|
+
envelopeSigner: ports.artifactEnvelopeSigner,
|
|
538
|
+
envelopeVerifier: ports.artifactEnvelopeVerifier,
|
|
539
|
+
currentAuthorityResolver:
|
|
540
|
+
ports.artifactCurrentAuthorityResolver,
|
|
541
|
+
},
|
|
542
|
+
now: clock,
|
|
543
|
+
existingRun: loaded.events.length > 0,
|
|
544
|
+
}),
|
|
545
|
+
}),
|
|
546
|
+
...(evidenceTtlMs === undefined ? {} : { ttlMs: evidenceTtlMs }),
|
|
547
|
+
}),
|
|
548
|
+
};
|
|
549
|
+
};
|
|
550
|
+
const { adapter: evidenceAdapter, selectedLayout } = createEvidenceAdapter(
|
|
551
|
+
runAdapter,
|
|
552
|
+
storage,
|
|
553
|
+
artifactPorts,
|
|
554
|
+
evidenceStorageLayout,
|
|
555
|
+
);
|
|
519
556
|
let wikiMaintenance = null;
|
|
520
557
|
let wikiMaintainer = null;
|
|
521
558
|
if (wikiConfiguration !== null) {
|
|
@@ -707,6 +744,7 @@ export function createAgentEvolutionRuntimeComposition({
|
|
|
707
744
|
const evolutionIngress = createAgentEvolutionIngress({
|
|
708
745
|
evidenceAdapter,
|
|
709
746
|
runAdapter,
|
|
747
|
+
evidenceStorageLayout: selectedLayout,
|
|
710
748
|
openCacheSourceRun: (input) => {
|
|
711
749
|
const sourceRunId = identifier(input, "cache source runId");
|
|
712
750
|
const sourceStorage = layout(
|
|
@@ -758,22 +796,22 @@ export function createAgentEvolutionRuntimeComposition({
|
|
|
758
796
|
...(lockTimeoutMs === undefined ? {} : { lockTimeoutMs }),
|
|
759
797
|
...(witnessMaximumBytes === undefined ? {} : { witnessMaximumBytes }),
|
|
760
798
|
});
|
|
799
|
+
const sourceRunAdapter = new EvolutionRunLedgerAdapter({
|
|
800
|
+
descriptor: { ...runAdapter.descriptor, runId: sourceRunId },
|
|
801
|
+
artifactPorts: sourcePorts,
|
|
802
|
+
ledger: sourceBackend.ledger,
|
|
803
|
+
ledgerArtifactResolver: sourceResolver,
|
|
804
|
+
now: clock,
|
|
805
|
+
});
|
|
806
|
+
const sourceEvidence = createEvidenceAdapter(
|
|
807
|
+
sourceRunAdapter,
|
|
808
|
+
sourceStorage,
|
|
809
|
+
sourcePorts,
|
|
810
|
+
"legacy",
|
|
811
|
+
);
|
|
761
812
|
return {
|
|
762
|
-
runAdapter:
|
|
763
|
-
|
|
764
|
-
artifactPorts: sourcePorts,
|
|
765
|
-
ledger: sourceBackend.ledger,
|
|
766
|
-
ledgerArtifactResolver: sourceResolver,
|
|
767
|
-
now: clock,
|
|
768
|
-
}),
|
|
769
|
-
evidenceAdapter: new EvolutionEvidenceArtifactAdapter({
|
|
770
|
-
tenantId,
|
|
771
|
-
audience,
|
|
772
|
-
projector,
|
|
773
|
-
bundleVerifier,
|
|
774
|
-
artifactPorts: sourcePorts,
|
|
775
|
-
...(evidenceTtlMs === undefined ? {} : { ttlMs: evidenceTtlMs }),
|
|
776
|
-
}),
|
|
813
|
+
runAdapter: sourceRunAdapter,
|
|
814
|
+
evidenceAdapter: sourceEvidence.adapter,
|
|
777
815
|
};
|
|
778
816
|
},
|
|
779
817
|
sourceEnvelopeAuthority: ports.sourceEnvelope,
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { types } from "node:util";
|
|
3
3
|
import { isAgentToolArgumentsPath } from "./evidence-json-text.js";
|
|
4
|
+
import {
|
|
5
|
+
MAX_INPUT_IMAGES,
|
|
6
|
+
MAX_INPUT_IMAGE_BYTES,
|
|
7
|
+
} from "../image-file-boundary.js";
|
|
4
8
|
|
|
5
|
-
const
|
|
6
|
-
|
|
9
|
+
export const AGENT_MODEL_REQUEST_LIMITS = Object.freeze({
|
|
10
|
+
maxNodes: 32_768,
|
|
11
|
+
maxBytes: 1024 * 1024,
|
|
12
|
+
maxDepth: 24,
|
|
13
|
+
});
|
|
14
|
+
export const AGENT_MODEL_IMAGE_LIMITS = Object.freeze({
|
|
15
|
+
maxImageBytes: MAX_INPUT_IMAGE_BYTES,
|
|
16
|
+
maxMessageImageBytes: MAX_INPUT_IMAGE_BYTES,
|
|
17
|
+
maxMessageImages: MAX_INPUT_IMAGES,
|
|
18
|
+
maxRequestImageBytes: 40 * 1024 * 1024,
|
|
19
|
+
// Includes bounded base64 expansion, the text allocation and URL headers.
|
|
20
|
+
maxCanonicalRequestBytes: 56 * 1024 * 1024,
|
|
21
|
+
});
|
|
22
|
+
const MAX_NODES = AGENT_MODEL_REQUEST_LIMITS.maxNodes;
|
|
23
|
+
const MAX_BYTES = AGENT_MODEL_REQUEST_LIMITS.maxBytes;
|
|
7
24
|
const MESSAGE_KEYS = new Set([
|
|
8
25
|
"role",
|
|
9
26
|
"content",
|
|
@@ -59,6 +76,32 @@ function blockDigest(value) {
|
|
|
59
76
|
.digest("hex")}`;
|
|
60
77
|
}
|
|
61
78
|
|
|
79
|
+
function imageDataUrlBudget(url) {
|
|
80
|
+
if (
|
|
81
|
+
typeof url !== "string" ||
|
|
82
|
+
url.length > Math.ceil(AGENT_MODEL_IMAGE_LIMITS.maxImageBytes / 3) * 4 + 128
|
|
83
|
+
)
|
|
84
|
+
throw new TypeError(
|
|
85
|
+
`Agent image exceeds its ${AGENT_MODEL_IMAGE_LIMITS.maxImageBytes / 1024 / 1024} MiB image byte budget`,
|
|
86
|
+
);
|
|
87
|
+
const match = /^data:([^;,]+);base64,([A-Za-z0-9+/]*={0,2})$/u.exec(url);
|
|
88
|
+
if (!match || !IMAGE_MEDIA_TYPES.has(match[1]) || match[2].length % 4 !== 0)
|
|
89
|
+
throw new TypeError(
|
|
90
|
+
"Agent image block requires a supported base64 data URL",
|
|
91
|
+
);
|
|
92
|
+
const decodedBytes =
|
|
93
|
+
(match[2].length / 4) * 3 -
|
|
94
|
+
(match[2].endsWith("==") ? 2 : match[2].endsWith("=") ? 1 : 0);
|
|
95
|
+
if (decodedBytes > AGENT_MODEL_IMAGE_LIMITS.maxImageBytes)
|
|
96
|
+
throw new TypeError(
|
|
97
|
+
`Agent image exceeds its ${AGENT_MODEL_IMAGE_LIMITS.maxImageBytes / 1024 / 1024} MiB image byte budget`,
|
|
98
|
+
);
|
|
99
|
+
const decoded = Buffer.from(match[2], "base64");
|
|
100
|
+
if (!decoded.length || decoded.toString("base64") !== match[2])
|
|
101
|
+
throw new TypeError("Agent image block contains non-canonical base64");
|
|
102
|
+
return { decodedBytes, encodedBytes: match[2].length };
|
|
103
|
+
}
|
|
104
|
+
|
|
62
105
|
function imageBlock(value) {
|
|
63
106
|
if (!exactKeys(value, new Set(["type", "image_url"]))) return null;
|
|
64
107
|
const imageKeys = new Set(
|
|
@@ -74,18 +117,7 @@ function imageBlock(value) {
|
|
|
74
117
|
) {
|
|
75
118
|
throw new TypeError("Agent image block has an unsupported protocol shape");
|
|
76
119
|
}
|
|
77
|
-
|
|
78
|
-
value.image_url.url,
|
|
79
|
-
);
|
|
80
|
-
if (!match || !IMAGE_MEDIA_TYPES.has(match[1]) || match[2].length % 4 !== 0) {
|
|
81
|
-
throw new TypeError(
|
|
82
|
-
"Agent image block requires a supported base64 data URL",
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
const decoded = Buffer.from(match[2], "base64");
|
|
86
|
-
if (!decoded.length || decoded.toString("base64") !== match[2]) {
|
|
87
|
-
throw new TypeError("Agent image block contains non-canonical base64");
|
|
88
|
-
}
|
|
120
|
+
imageDataUrlBudget(value.image_url.url);
|
|
89
121
|
return value;
|
|
90
122
|
}
|
|
91
123
|
|
|
@@ -319,18 +351,54 @@ export function snapshotAgentModelRequest(
|
|
|
319
351
|
) {
|
|
320
352
|
let nodes = 0;
|
|
321
353
|
let bytes = 0;
|
|
354
|
+
let imageBytes = 0;
|
|
355
|
+
let encodedImageBytes = 0;
|
|
356
|
+
const messageImageBudgets = new Map();
|
|
322
357
|
const seen = new Set();
|
|
323
358
|
const visit = (entry, depth, path = "") => {
|
|
324
|
-
if (++nodes > MAX_NODES || depth >
|
|
359
|
+
if (++nodes > MAX_NODES || depth > AGENT_MODEL_REQUEST_LIMITS.maxDepth) {
|
|
325
360
|
throw new TypeError("Agent model request exceeds the input budget");
|
|
326
361
|
}
|
|
327
362
|
if (typeof entry === "string") {
|
|
328
|
-
|
|
363
|
+
const imageUrl = /^messages\.\d+\.content\.\d+\.image_url\.url$/u.test(
|
|
364
|
+
path,
|
|
365
|
+
);
|
|
366
|
+
let imageBudget = null;
|
|
367
|
+
if (imageUrl) {
|
|
368
|
+
imageBudget = imageDataUrlBudget(entry);
|
|
369
|
+
const messageIndex = path.split(".")[1];
|
|
370
|
+
const messageBudget = messageImageBudgets.get(messageIndex) ?? {
|
|
371
|
+
bytes: 0,
|
|
372
|
+
count: 0,
|
|
373
|
+
};
|
|
374
|
+
messageBudget.bytes += imageBudget.decodedBytes;
|
|
375
|
+
messageBudget.count++;
|
|
376
|
+
messageImageBudgets.set(messageIndex, messageBudget);
|
|
377
|
+
if (
|
|
378
|
+
messageBudget.bytes > AGENT_MODEL_IMAGE_LIMITS.maxMessageImageBytes ||
|
|
379
|
+
messageBudget.count > AGENT_MODEL_IMAGE_LIMITS.maxMessageImages
|
|
380
|
+
)
|
|
381
|
+
throw new TypeError(
|
|
382
|
+
`Agent images exceed the per-message image budget (${AGENT_MODEL_IMAGE_LIMITS.maxMessageImages} images / ${AGENT_MODEL_IMAGE_LIMITS.maxMessageImageBytes / 1024 / 1024} MiB)`,
|
|
383
|
+
);
|
|
384
|
+
imageBytes += imageBudget.decodedBytes;
|
|
385
|
+
encodedImageBytes += imageBudget.encodedBytes;
|
|
386
|
+
if (imageBytes > AGENT_MODEL_IMAGE_LIMITS.maxRequestImageBytes)
|
|
387
|
+
throw new TypeError(
|
|
388
|
+
`Agent images exceed the ${AGENT_MODEL_IMAGE_LIMITS.maxRequestImageBytes / 1024 / 1024} MiB request image byte budget`,
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
if (
|
|
392
|
+
entry.length > 8192 &&
|
|
393
|
+
!imageUrl &&
|
|
394
|
+
!textPath(path, allowStructuredArgumentText)
|
|
395
|
+
) {
|
|
329
396
|
throw new TypeError(
|
|
330
397
|
"Agent model protocol metadata exceeds the text budget",
|
|
331
398
|
);
|
|
332
399
|
}
|
|
333
|
-
bytes +=
|
|
400
|
+
bytes +=
|
|
401
|
+
Buffer.byteLength(entry, "utf8") - (imageBudget?.encodedBytes ?? 0);
|
|
334
402
|
if (bytes > MAX_BYTES)
|
|
335
403
|
throw new TypeError("Agent model request is too large");
|
|
336
404
|
return entry;
|
|
@@ -405,7 +473,11 @@ export function snapshotAgentModelRequest(
|
|
|
405
473
|
);
|
|
406
474
|
// Include escaping, punctuation and numeric values in the transport/storage
|
|
407
475
|
// budget, not just string values. Whole fields are never split or truncated.
|
|
408
|
-
|
|
476
|
+
const canonicalBytes = Buffer.byteLength(JSON.stringify(request), "utf8");
|
|
477
|
+
if (
|
|
478
|
+
canonicalBytes - encodedImageBytes > MAX_BYTES ||
|
|
479
|
+
canonicalBytes > AGENT_MODEL_IMAGE_LIMITS.maxCanonicalRequestBytes
|
|
480
|
+
) {
|
|
409
481
|
throw new TypeError("Agent model request is too large");
|
|
410
482
|
}
|
|
411
483
|
return request;
|