chainlesschain 0.166.117 → 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 +26 -4
- package/package.json +3 -3
- 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-C9tSCImB.js → AIOps-BGySwMIP.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CXKExmT_.js → ActionButton-Chn7fBLr.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DE8WBWHo.js → Analytics-ORH7UkGa.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BdpwNM08.js → AppLayout-8xV4jWjP.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-94TQpe38.js → Artifacts-26SBK-x-.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DdDEv5Ej.js → Audit-CtXpqbXg.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-TU9nlV7j.js → BackgroundAgents-C5zLvQis.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-C0GPoUUq.js → Backup-C93xY4vO.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-iyrVn2I6.js → BaseInput-DpVCHfAn.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Dqo8spwp.js → Chat-DM0LblR2.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CDqHSzc4.js → ChatBubbleRenderer-unlQUF1T.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-BF_XJvQi.js → Checkbox-BsAt3cKR.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-5tUWoOa9.js → Codegen-E_kp4KFd.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BQxSeRvG.js → Col-6msR3T6I.js} +1 -1
- package/src/assets/web-panel/assets/{Community-B2Ra7w-J.js → Community-PyX9c5D-.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-GjxJwlr0.js → Compact-7G1bVDSH.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BTUP6RTA.js → Compliance-DcHN7GlD.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DiwfL16s.js → Cowork-WUIHJYDx.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-1ceOo5ux.js → Cron-CWgCbptg.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-aHYxLu0u.js → Crosschain-BzKZ6roD.js} +1 -1
- package/src/assets/web-panel/assets/{DID-eeTjzOLV.js → DID-r7zxeItn.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CT3fpkvX.js → Dashboard-D3pBiN2H.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-B3UpOy-N.js → Dropdown-C4otRJlZ.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-Ba2Rvoru.js → EmailListRenderer-CzDTC8lm.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-CGtn93on.js → EvolutionSettings-DGkXiIs-.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-C0IUdHQt.js → FamilyGuardDashboard-BKdEyuiR.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-1QIDwemn.js → Federation-dsI-xcpf.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-NGbSsdje.js → FormItemContext-CEEb1fMR.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DzVZc2Ba.js → GenericCardRenderer-D_mfO3Ts.js} +1 -1
- package/src/assets/web-panel/assets/{Git-B_1TDbSr.js → Git-CBwr2ZI3.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BDl_ySyI.js → Governance-D-Wy2Jjr.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CAp-wcCK.js → Inference-B4Yk_IRx.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DRjRcxul.js → KnowledgeGraph-DoI7bi6m.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-qSuwMwk7.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-DfiXL6UO.js → Marketplace-CsIEByzK.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-D9rIvFjN.js → McpTools-_DRzjcIn.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-D-p7yDzj.js → Memory-zvLpyi__.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-D0XT5B6m.js → MobileBridge-DXd1ik2Z.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CL9cHVIk.js → MobileProjects-DKh2q-Y9.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CME4kDmC.js → Mtc-Ct-fhtIx.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-BjGOXFnn.js → MtcAudit-J4zY3Oqk.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-CSzc53e0.js → Multisig-B2HJMCKe.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-BYjZnaH8.js → NLProgramming-CwcSmU4q.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BUPOYE0C.js → Notes-Da53L6wb.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BK8YADru.js → NotificationSettings-BxhufdrA.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-B5F8bnWt.js → OrderTableRenderer-BoFwohAi.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-B0WNlhMd.js → Organization-MIsMrUes.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CED6ZO87.js → Overflow-Dy2P4v3q.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CBdc8fkP.js → P2P-CD9Sxn2y.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DuauYi03.js → PdhVaultBrowser-BvBWgfG0.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-kfgY0ukN.js → Permissions-CwOlDRis.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CDY3I1Do.js → PersonalDataHub-CZYaxEpv.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-B9x0wKSK.js → Pipeline-kLU7PUbB.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Cqhcr_Qv.js → Privacy-BVRycSiI.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CFhoyo57.js → ProjectInit-DP3pr7uJ.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DCBjV2Hm.js → ProjectSettings-CACaDYjs.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-C51w0LnM.js → Projects-CB1k4zTC.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BuCIWZY1.js → Providers-D7Y9WHRE.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CEXNL5CB.js → QrScannerModal-CeP8xzs1.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DgK8aLAU.js → QuickAsk-iJVFrhZ2.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BxEYQRAs.js → Recommend-DmTpnagw.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-PRsxNsYU.js → RemoteSession-C6ek8Uni.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-S-tQH70r.js → Reputation-CPfwc9de.js} +1 -1
- package/src/assets/web-panel/assets/{Row-U1Ws3CJl.js → Row-C1wwtSMJ.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BftCyeii.js → RssFeed-BiDJsqaH.js} +3 -3
- package/src/assets/web-panel/assets/{Search-o4gK0cPy.js → Search-BF6Aon95.js} +1 -1
- package/src/assets/web-panel/assets/{Security-U2ZRpsbA.js → Security-Bps0XnV4.js} +3 -3
- package/src/assets/web-panel/assets/{Services-D0tRjWl_.js → Services-uf92smGR.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DzZ8TFsB.js → Skeleton-DQd4eVWW.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-B1cC7rju.js → Skills-DgamiYa5.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CtIHOR0J.js → Sla-CF1IVIrm.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CD8ZlQpW.js → SpeechSettings-Bzxmjbpc.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BilFQWQk.js → SyncSettings-B8zKauiq.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Bmg2qLXl.js → Tasks-DPKV_xSt.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D6yofyC1.js → Templates-BikeSZIF.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BzttD-Gp.js → Tenant-CEaUaDkJ.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DyRXeYuH.js → Terminal-ZPgOSQ_q.js} +3 -3
- package/src/assets/web-panel/assets/{TimelineRenderer-Bdmkx-Tr.js → TimelineRenderer-DmyB4Udk.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-10RcVAVJ.js → Tokens-g85Pm5TO.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CKV-9DdV.js → Trigger-D202hx9a.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BEc-sW1q.js → Trust-DzvQYVFy.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BSql8piX.js → UkeySign-KRzwddVg.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C4OH2f4s.js → VideoEditing-IRBXLO2z.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BSSvWKmv.js → Wallet-DSf5KPgQ.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-LxIzXo9d.js → WebAuthn-DNPxLTCc.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-DWwdfcte.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-DWxYYLD5.js → chat-q3XXUtv2.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BxEcQqtg.js → colors-CF54SNei.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DNbezFOJ.js → compact-item-BaRkvZuT.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DaJXc5nx.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-BMrw3sg3.js → hasIn-DlC--S8R.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpSp97J8.js → index-B0Ptc7yu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DzZHBzCb.js → index-B0V9rgdu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEvdSKT4.js → index-BEiUlFKb.js} +1 -1
- package/src/assets/web-panel/assets/{index-pzYLf5qu.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-2c0bL3SE.js → index-BU5DJqk7.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dr18agDl.js → index-BY-Tf3OM.js} +1 -1
- package/src/assets/web-panel/assets/{index-T4T84G6X.js → index-BZrE0Go8.js} +1 -1
- package/src/assets/web-panel/assets/{index-LRb0QX6S.js → index-BizdX2X5.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9b6UaZl.js → index-C87Yr3h1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAV07GDK.js → index-C9Wypz9e.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_b9_6wQ.js → index-CAoG_E-q.js} +1 -1
- package/src/assets/web-panel/assets/{index-NEW5EN2w.js → index-CAxSyMrF.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dwg38xTG.js → index-CC5HjNM6.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bs2QyMPQ.js → index-CNZQEZ9g.js} +1 -1
- package/src/assets/web-panel/assets/{index-BR4nWOmR.js → index-CPvIhha6.js} +1 -1
- package/src/assets/web-panel/assets/{index-hPy_f08G.js → index-CR_wqMGy.js} +1 -1
- package/src/assets/web-panel/assets/{index-IX0g0s2t.js → index-CSClXoB3.js} +1 -1
- package/src/assets/web-panel/assets/{index-cCqCEa9X.js → index-CZ8azVgB.js} +3 -3
- package/src/assets/web-panel/assets/{index-C25ig6EV.js → index-Ccc5z8eJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-7zzLqfvI.js → index-CeiKbM3a.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpwgF7vh.js → index-Cl6av3X7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNZDGV2q.js → index-CtGfeD7E.js} +1 -1
- package/src/assets/web-panel/assets/{index-6W0V5G2t.js → index-Ctid12Gq.js} +1 -1
- package/src/assets/web-panel/assets/{index-BaByEdBj.js → index-D0H-N0uG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCCd8Rj6.js → index-D0vIgprF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CL-36X3A.js → index-D4wUDFRg.js} +1 -1
- package/src/assets/web-panel/assets/{index-DL0k35f0.js → index-DJFipyK7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcuytRTa.js → index-DX2REKNp.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cm9DYzhC.js → index-Dc3gD0cw.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bum_aSyd.js → index-DiQzer2R.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaxzeSIM.js → index-DntKLOs9.js} +1 -1
- package/src/assets/web-panel/assets/{index-cKBpcInt.js → index-Dplhl6gh.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ca2hwPMo.js → index-Dq8q_PWB.js} +1 -1
- package/src/assets/web-panel/assets/{index-DarVV5yG.js → index-IVQdOBNN.js} +1 -1
- package/src/assets/web-panel/assets/{index-rFaCnjXi.js → index-Kerduyao.js} +1 -1
- package/src/assets/web-panel/assets/{index-VD-dTYQE.js → index-W6cLGjpW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CiEdfbB9.js → index-qZDNFll9.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BWVLgWhF.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-KJZ1xfDE.js → motion-BlCLpVDp.js} +1 -1
- package/src/assets/web-panel/assets/{move-DGqU6H7M.js → move-B80G7fLU.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-Dg0xkI5J.js → mtc-parser-Djw08NJh.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B6RnMJAQ.js → omit-Bg_G1eUr.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Ctw2i3jb.js → pickAttrs-Df9zYUg2.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-D3F3x8Jm.js → placementArrow-DjCDLhJ4.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-W6eHE0nM.js → responsiveObserve--Naz7NgY.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BlFf8sY5.js → slide-CHn3ald-.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Cd6LMwmy.js → statusUtils-BiGwoIK_.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Bg5-U4Y1.js → styleChecker-Zf2dQx1j.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DTkLS3tn.js → useFlexGapSupport-sLES8nyD.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CwYGzoBt.js → useFs-DV1Hl4qu.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-PCgFQXZP.js → usePersonalDataHub-CZXr2Qxg.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CJM7MkrB.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-CP0mgaFi.js → zoom-B8A6xKMF.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/data/changelog.json +15 -2
- package/src/harness/jsonl-session-store.js +2 -1
- package/src/lib/artifact-store.js +129 -20
- package/src/lib/bounded-artifact-file-read.js +128 -46
- package/src/lib/evolution/agent-evolution-ingress.js +41 -7
- package/src/lib/evolution/agent-evolution-runtime-composition.js +65 -27
- package/src/lib/evolution/evidence-json-text.js +65 -3
- 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 +35 -3
- 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/ollama-provider-fetch.js +33 -0
- package/src/lib/provider-stream.js +14 -13
- package/src/lib/session-history-origins.js +71 -32
- package/src/lib/session-message-provenance.js +26 -2
- package/src/lib/session-runtime-retention.js +10 -1
- package/src/lib/session-transcript-migration.js +67 -12
- package/src/lib/storage-failure-cause-codes.js +449 -0
- package/src/runtime/agent-core.js +54 -33
- package/src/runtime/headless-stream.js +89 -10
- package/src/assets/web-panel/assets/MarkdownRenderer-BgnYTegK.js +0 -1
- package/src/assets/web-panel/assets/devWarning-CRyXoGo9.js +0 -1
- package/src/assets/web-panel/assets/index-C-W0Ntk_.js +0 -1
- package/src/assets/web-panel/assets/index-CCk_qhBx.js +0 -1
- package/src/assets/web-panel/assets/markdown-CsiA8-E5.js +0 -50
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { readBoundedDescriptor } from "./evolution/bounded-descriptor-read.js";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
withEvolutionDirectoryFileIdentity,
|
|
7
|
+
withEvolutionFileIdentity,
|
|
8
|
+
} from "./evolution/evolution-file-identity.js";
|
|
6
9
|
import { artifactPhysicalIdentity } from "./evolution/evolution-artifact-identity.js";
|
|
7
10
|
|
|
8
11
|
export const ARTIFACT_BOUNDED_READ_FAILED_CODE =
|
|
@@ -67,10 +70,10 @@ function sameStat(left, right) {
|
|
|
67
70
|
);
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
function assertReadArguments(args) {
|
|
74
|
+
const [target, expectedSize, maximumBytes] = args;
|
|
72
75
|
if (
|
|
73
|
-
|
|
76
|
+
args.length !== 3 ||
|
|
74
77
|
typeof target !== "string" ||
|
|
75
78
|
!path.isAbsolute(target) ||
|
|
76
79
|
path.resolve(target) !== target ||
|
|
@@ -83,49 +86,128 @@ export function readBoundedArtifactFile(target, expectedSize, maximumBytes) {
|
|
|
83
86
|
throw new TypeError(
|
|
84
87
|
"bounded artifact read requires a canonical path and finite size bounds",
|
|
85
88
|
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function readWithIdentity(target, expectedSize, maximumBytes, samePathHandle) {
|
|
92
|
+
const before = fs.lstatSync(target, { bigint: true });
|
|
93
|
+
safeStat(before, expectedSize, maximumBytes, "artifact path");
|
|
94
|
+
if (canonical(fs.realpathSync.native(target)) !== canonical(target))
|
|
95
|
+
fail("artifact path is not physically canonical");
|
|
96
|
+
const fd = fs.openSync(
|
|
97
|
+
target,
|
|
98
|
+
fs.constants.O_RDONLY |
|
|
99
|
+
(fs.constants.O_NOFOLLOW || 0) |
|
|
100
|
+
(fs.constants.O_NONBLOCK || 0),
|
|
101
|
+
);
|
|
86
102
|
try {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
103
|
+
const opened = fs.fstatSync(fd, { bigint: true });
|
|
104
|
+
safeStat(opened, expectedSize, maximumBytes, "artifact descriptor");
|
|
105
|
+
if (!samePathHandle(before, opened) || !sameMetadata(before, opened))
|
|
106
|
+
fail("artifact path and descriptor identities differ");
|
|
107
|
+
const bytes = readBoundedDescriptor(
|
|
108
|
+
fs,
|
|
109
|
+
fd,
|
|
110
|
+
Number(opened.size),
|
|
111
|
+
maximumBytes,
|
|
112
|
+
);
|
|
113
|
+
const closed = fs.fstatSync(fd, { bigint: true });
|
|
114
|
+
const after = fs.lstatSync(target, { bigint: true });
|
|
115
|
+
safeStat(closed, expectedSize, maximumBytes, "artifact descriptor");
|
|
116
|
+
safeStat(after, expectedSize, maximumBytes, "artifact path");
|
|
117
|
+
if (!sameStat(opened, closed))
|
|
118
|
+
fail("artifact descriptor changed during bounded read");
|
|
119
|
+
if (
|
|
120
|
+
!sameStat(before, after) ||
|
|
121
|
+
!samePathHandle(after, closed) ||
|
|
122
|
+
!sameMetadata(after, closed) ||
|
|
123
|
+
canonical(fs.realpathSync.native(target)) !== canonical(target)
|
|
124
|
+
)
|
|
125
|
+
fail("artifact pathname changed during bounded read");
|
|
126
|
+
return bytes;
|
|
127
|
+
} finally {
|
|
128
|
+
fs.closeSync(fd);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function wrapReadFailure(cause) {
|
|
133
|
+
if (cause?.code === ARTIFACT_BOUNDED_READ_FAILED_CODE) throw cause;
|
|
134
|
+
fail("artifact bounded descriptor read failed", cause);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Read one stable window only. Callers retain hash/signature and root checks. */
|
|
138
|
+
export function readBoundedArtifactFile(target, expectedSize, maximumBytes) {
|
|
139
|
+
assertReadArguments(arguments);
|
|
140
|
+
try {
|
|
141
|
+
return withEvolutionFileIdentity(DIRECTORY_FS, target, (samePathHandle) =>
|
|
142
|
+
readWithIdentity(target, expectedSize, maximumBytes, samePathHandle),
|
|
143
|
+
);
|
|
144
|
+
} catch (cause) {
|
|
145
|
+
wrapReadFailure(cause);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* A synchronous batch shares one authenticated parent handle, never file
|
|
151
|
+
* contents or authority. Each child keeps the complete independent read
|
|
152
|
+
* window above. The parent is reattested before the batch can return.
|
|
153
|
+
*/
|
|
154
|
+
export function withBoundedArtifactDirectoryRead(directory, callback) {
|
|
155
|
+
if (
|
|
156
|
+
arguments.length !== 2 ||
|
|
157
|
+
typeof directory !== "string" ||
|
|
158
|
+
!path.isAbsolute(directory) ||
|
|
159
|
+
path.resolve(directory) !== directory ||
|
|
160
|
+
typeof callback !== "function" ||
|
|
161
|
+
callback.constructor?.name === "AsyncFunction"
|
|
162
|
+
)
|
|
163
|
+
throw new TypeError(
|
|
164
|
+
"bounded artifact directory read requires a canonical directory and synchronous callback",
|
|
165
|
+
);
|
|
166
|
+
let callbackFailure = null;
|
|
167
|
+
try {
|
|
168
|
+
return withEvolutionDirectoryFileIdentity(
|
|
169
|
+
DIRECTORY_FS,
|
|
170
|
+
directory,
|
|
171
|
+
(samePathHandle, _sameStableHandle, { parentPath }) => {
|
|
172
|
+
if (canonical(parentPath) !== canonical(directory))
|
|
173
|
+
fail("artifact batch parent is not physically canonical");
|
|
174
|
+
let active = true;
|
|
175
|
+
const read = Object.freeze((...args) => {
|
|
176
|
+
if (!active) fail("artifact batch read window is closed");
|
|
177
|
+
assertReadArguments(args);
|
|
178
|
+
const [target, expectedSize, maximumBytes] = args;
|
|
179
|
+
if (canonical(path.dirname(target)) !== canonical(parentPath))
|
|
180
|
+
fail(
|
|
181
|
+
"artifact batch read must name a direct child of its captured parent",
|
|
182
|
+
);
|
|
183
|
+
try {
|
|
184
|
+
return readWithIdentity(
|
|
185
|
+
target,
|
|
186
|
+
expectedSize,
|
|
187
|
+
maximumBytes,
|
|
188
|
+
samePathHandle,
|
|
189
|
+
);
|
|
190
|
+
} catch (cause) {
|
|
191
|
+
wrapReadFailure(cause);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
try {
|
|
195
|
+
const result = callback(read);
|
|
196
|
+
if (result && typeof result.then === "function")
|
|
197
|
+
throw new TypeError(
|
|
198
|
+
"artifact batch callback must not return a promise",
|
|
199
|
+
);
|
|
200
|
+
return result;
|
|
201
|
+
} catch (cause) {
|
|
202
|
+
callbackFailure = cause;
|
|
203
|
+
throw cause;
|
|
204
|
+
} finally {
|
|
205
|
+
active = false;
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
);
|
|
127
209
|
} catch (cause) {
|
|
128
|
-
if (cause
|
|
129
|
-
|
|
210
|
+
if (cause === callbackFailure) throw cause;
|
|
211
|
+
wrapReadFailure(cause);
|
|
130
212
|
}
|
|
131
213
|
}
|
|
@@ -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,7 +9,14 @@ 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";
|
|
@@ -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
|
|
|
@@ -347,13 +372,14 @@ export function createAgentEvolutionIngress({
|
|
|
347
372
|
"Agent evidence persistence returned an unbound result",
|
|
348
373
|
);
|
|
349
374
|
}
|
|
350
|
-
const
|
|
351
|
-
|
|
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 = {
|
|
352
379
|
schema: EVOLUTION_RUN_EVENT_SCHEMA,
|
|
353
380
|
tenantId: descriptor.tenantId,
|
|
354
381
|
runId: descriptor.runId,
|
|
355
382
|
eventId,
|
|
356
|
-
sequence: current.events.length + 1,
|
|
357
383
|
type: EVENT_TYPES.RAW_EVENT_REFERENCED,
|
|
358
384
|
subjectId: persisted.evidenceId,
|
|
359
385
|
payloadDigest: persisted.manifest.digest,
|
|
@@ -371,7 +397,14 @@ export function createAgentEvolutionIngress({
|
|
|
371
397
|
candidateSetDigest: skillDecisionRequest.candidateSetDigest,
|
|
372
398
|
}),
|
|
373
399
|
},
|
|
374
|
-
}
|
|
400
|
+
};
|
|
401
|
+
const appended =
|
|
402
|
+
appendNext !== null
|
|
403
|
+
? appendNext(event)
|
|
404
|
+
: runAdapter.appendEvent({
|
|
405
|
+
...event,
|
|
406
|
+
sequence: current.events.length + 1,
|
|
407
|
+
});
|
|
375
408
|
if (kind === "model-input") {
|
|
376
409
|
lastModelResponse = null;
|
|
377
410
|
modelAdmissionPending = true;
|
|
@@ -677,6 +710,7 @@ export function createAgentEvolutionIngress({
|
|
|
677
710
|
serialize(async () => {
|
|
678
711
|
if (admissionFailure !== null) throw admissionFailure;
|
|
679
712
|
const loaded = runAdapter.load();
|
|
713
|
+
assertLoadedLayout(loaded);
|
|
680
714
|
let projection;
|
|
681
715
|
if (loaded.projection?.status === "completed") {
|
|
682
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,
|
|
@@ -21,6 +21,43 @@ export const AGENT_CODE_TEXT_RESULT_TOOLS = Object.freeze([
|
|
|
21
21
|
"search_files",
|
|
22
22
|
]);
|
|
23
23
|
|
|
24
|
+
export const AGENT_FENCED_CODE_LANGUAGES = Object.freeze([
|
|
25
|
+
"javascript",
|
|
26
|
+
"js",
|
|
27
|
+
"typescript",
|
|
28
|
+
"ts",
|
|
29
|
+
"jsx",
|
|
30
|
+
"tsx",
|
|
31
|
+
"python",
|
|
32
|
+
"py",
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
function fencedCodeRanges(text, languages) {
|
|
36
|
+
const ranges = [];
|
|
37
|
+
const fences = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/gmu;
|
|
38
|
+
let opening = null;
|
|
39
|
+
for (const match of text.matchAll(fences)) {
|
|
40
|
+
const marker = match[1];
|
|
41
|
+
const info = match[2].trim().toLowerCase();
|
|
42
|
+
if (opening === null) {
|
|
43
|
+
opening = {
|
|
44
|
+
marker,
|
|
45
|
+
supported: languages.includes(info),
|
|
46
|
+
start: match.index + match[0].length,
|
|
47
|
+
};
|
|
48
|
+
} else if (
|
|
49
|
+
marker[0] === opening.marker[0] &&
|
|
50
|
+
marker.length >= opening.marker.length &&
|
|
51
|
+
info === ""
|
|
52
|
+
) {
|
|
53
|
+
if (opening.supported) ranges.push([opening.start, match.index]);
|
|
54
|
+
opening = null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Unclosed/unknown fences never acquire code semantics.
|
|
58
|
+
return ranges;
|
|
59
|
+
}
|
|
60
|
+
|
|
24
61
|
/* eslint-disable no-control-regex -- Quoted literals exclude unescaped control bytes. */
|
|
25
62
|
const JSON_STRING_PREFIX =
|
|
26
63
|
/^"(?:[^"\\\x00-\x1f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/u;
|
|
@@ -271,10 +308,35 @@ export function createEvidenceJsonTextBoundary(
|
|
|
271
308
|
};
|
|
272
309
|
};
|
|
273
310
|
|
|
274
|
-
return (
|
|
311
|
+
return function scanText(
|
|
275
312
|
text,
|
|
276
|
-
{
|
|
277
|
-
|
|
313
|
+
{
|
|
314
|
+
layer = 0,
|
|
315
|
+
objectOnly = false,
|
|
316
|
+
codeText = false,
|
|
317
|
+
fencedCodeLanguages = null,
|
|
318
|
+
visit,
|
|
319
|
+
plain,
|
|
320
|
+
equal,
|
|
321
|
+
},
|
|
322
|
+
) {
|
|
323
|
+
if (!objectOnly && !codeText && fencedCodeLanguages) {
|
|
324
|
+
const ranges = fencedCodeRanges(text, fencedCodeLanguages);
|
|
325
|
+
if (ranges.length > 0) {
|
|
326
|
+
let output = "";
|
|
327
|
+
let offset = 0;
|
|
328
|
+
const options = { layer, visit, plain, equal };
|
|
329
|
+
for (const [start, end] of ranges) {
|
|
330
|
+
output += scanText(text.slice(offset, start), options);
|
|
331
|
+
output += scanText(text.slice(start, end), {
|
|
332
|
+
...options,
|
|
333
|
+
codeText: true,
|
|
334
|
+
});
|
|
335
|
+
offset = end;
|
|
336
|
+
}
|
|
337
|
+
return output + scanText(text.slice(offset), options);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
278
340
|
bytes += Buffer.byteLength(text, "utf8");
|
|
279
341
|
if (bytes > policy.maxDecodedBytes)
|
|
280
342
|
reject("Agent model JSON text exceeds its budget");
|