chainlesschain 0.166.114 → 0.166.117
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 +23 -3
- 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/assets/{AIOps-CVac3rIN.js → AIOps-C9tSCImB.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-ChM9GxMl.js → ActionButton-CXKExmT_.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CV5399Js.js → Analytics-DE8WBWHo.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CuonVXhg.js → AppLayout-BdpwNM08.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-D9qKfgb6.js → Artifacts-94TQpe38.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DUvLysQc.js → Audit-DdDEv5Ej.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DfKohQeT.js → BackgroundAgents-TU9nlV7j.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CohoEI8R.js → Backup-C0GPoUUq.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BwdoA3xv.js → BaseInput-iyrVn2I6.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DRkuz1d2.js → Chat-Dqo8spwp.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-v3pzeHNC.js → ChatBubbleRenderer-CDqHSzc4.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-B-GNGpKv.js → Checkbox-BF_XJvQi.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Bs2lAsoZ.js → Codegen-5tUWoOa9.js} +1 -1
- package/src/assets/web-panel/assets/{Col-Bk1mJKDZ.js → Col-BQxSeRvG.js} +1 -1
- package/src/assets/web-panel/assets/{Community-B_FDSCOo.js → Community-B2Ra7w-J.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-No1qSLLH.js → Compact-GjxJwlr0.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CcrG43-d.js → Compliance-BTUP6RTA.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DLkj2ywK.js → Cowork-DiwfL16s.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-sQHELVEz.js → Cron-1ceOo5ux.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CRTZ3GZg.js → Crosschain-aHYxLu0u.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Ds2bjvxE.js → DID-eeTjzOLV.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DOONG2NX.js → Dashboard-CT3fpkvX.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Br3PNA2L.js → Dropdown-B3UpOy-N.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DT6UUqjZ.js → EmailListRenderer-Ba2Rvoru.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-BSLuEjlT.js → EvolutionSettings-CGtn93on.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-2aEM9avE.js → FamilyGuardDashboard-C0IUdHQt.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D3B0tlQU.js → Federation-1QIDwemn.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DTVkVVQP.js → FormItemContext-NGbSsdje.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BgFEgP4y.js → GenericCardRenderer-DzVZc2Ba.js} +1 -1
- package/src/assets/web-panel/assets/{Git-3t71m6Xd.js → Git-B_1TDbSr.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DS7WvlaX.js → Governance-BDl_ySyI.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CeT-xWrI.js → Inference-CAp-wcCK.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BQzMncp5.js → KnowledgeGraph-DRjRcxul.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CC5DOKhV.js → Logs-qSuwMwk7.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-BgnYTegK.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-CpYDyy3o.js → Marketplace-DfiXL6UO.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DRdAZPMr.js → McpTools-D9rIvFjN.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-CBLRr-l8.js → Memory-D-p7yDzj.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Bnj9veNN.js → MobileBridge-D0XT5B6m.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-lYFPD24p.js → MobileProjects-CL9cHVIk.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BMU_C9vD.js → Mtc-CME4kDmC.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-DQV-zumU.js → MtcAudit-BjGOXFnn.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-LpqpqV1d.js → Multisig-CSzc53e0.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-C4OMklSO.js → NLProgramming-BYjZnaH8.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Cg0QCinP.js → Notes-BUPOYE0C.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-amoZoMna.js → NotificationSettings-BK8YADru.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-CxNvhf5n.js → OrderTableRenderer-B5F8bnWt.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BetJmyX5.js → Organization-B0WNlhMd.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DbeoPtVD.js → Overflow-CED6ZO87.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-B5sitQWT.js → P2P-CBdc8fkP.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-AP9SG2ic.js → PdhVaultBrowser-DuauYi03.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-Bc7fgNKx.js → Permissions-kfgY0ukN.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BwdGMcWZ.js → PersonalDataHub-CDY3I1Do.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-DVuJA9BA.js → Pipeline-B9x0wKSK.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BGzwOYRG.js → Privacy-Cqhcr_Qv.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BpHcC5br.js → ProjectInit-CFhoyo57.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BI5G5gsc.js → ProjectSettings-DCBjV2Hm.js} +2 -2
- package/src/assets/web-panel/assets/Projects-C51w0LnM.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CRHCcLFS.js → Providers-BuCIWZY1.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-qSeg5xag.js → QrScannerModal-CEXNL5CB.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CA8oSceR.js → QuickAsk-DgK8aLAU.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DMvPodNo.js → Recommend-BxEYQRAs.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BWsapEyN.js → RemoteSession-PRsxNsYU.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-BZJETVmC.js → Reputation-S-tQH70r.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CUE1OSMp.js → Row-U1Ws3CJl.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DvMazcUD.js → RssFeed-BftCyeii.js} +3 -3
- package/src/assets/web-panel/assets/{Search-e1c-NXWv.js → Search-o4gK0cPy.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Dc9GZsx2.js → Security-U2ZRpsbA.js} +3 -3
- package/src/assets/web-panel/assets/{Services-AFz6ke-4.js → Services-D0tRjWl_.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-gow6MYcY.js → Skeleton-DzZ8TFsB.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-h6AxYjUP.js → Skills-B1cC7rju.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Cr4CkJ0O.js → Sla-CtIHOR0J.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Bd5yuBtH.js → SpeechSettings-CD8ZlQpW.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-1t4QZMLW.js → SyncSettings-BilFQWQk.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-u-DrjLRM.js → Tasks-Bmg2qLXl.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-C0yLUC9b.js → Templates-D6yofyC1.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-ds1YT5iS.js → Tenant-BzttD-Gp.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BoIskW2m.js → Terminal-DyRXeYuH.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BkdVK24X.js → TimelineRenderer-Bdmkx-Tr.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-djyDgmfk.js → Tokens-10RcVAVJ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CYefDS3H.js → Trigger-CKV-9DdV.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CE_dbep_.js → Trust-BEc-sW1q.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DwVs_fey.js → UkeySign-BSql8piX.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BTUqMHAV.js → VideoEditing-C4OH2f4s.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Bu_E7Rrc.js → Wallet-BSSvWKmv.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DTbre5AB.js → WebAuthn-LxIzXo9d.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-BsBzd3gt.js → WorkflowEditor-DWwdfcte.js} +1 -1
- package/src/assets/web-panel/assets/{chat-tdifQQvu.js → chat-DWxYYLD5.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D3SNW2Vx.js → colors-BxEcQqtg.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-UBlCjrAW.js → compact-item-DNbezFOJ.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DKsnEnFt.js → createContext-DaJXc5nx.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CRyXoGo9.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BkeySXWe.js → hasIn-BMrw3sg3.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXkn77ZN.js → index-2c0bL3SE.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtxUSZSS.js → index-6W0V5G2t.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFMrIEIt.js → index-7zzLqfvI.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9m1HQzl.js → index-B9b6UaZl.js} +1 -1
- package/src/assets/web-panel/assets/{index-bOIcWW8F.js → index-BAV07GDK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BV2zQteq.js → index-BCCd8Rj6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlO6HdD9.js → index-BNZDGV2q.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfrW-iVs.js → index-BR4nWOmR.js} +1 -1
- package/src/assets/web-panel/assets/{index-PWScrdlX.js → index-B_b9_6wQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-SpQ26gD6.js → index-BaByEdBj.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5Umd_Z-.js → index-BcuytRTa.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dg8-Duze.js → index-Bs2QyMPQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlEIp1gJ.js → index-Bum_aSyd.js} +1 -1
- package/src/assets/web-panel/assets/index-C-W0Ntk_.js +1 -0
- package/src/assets/web-panel/assets/{index-D6es7MSG.js → index-C25ig6EV.js} +1 -1
- package/src/assets/web-panel/assets/index-CCk_qhBx.js +1 -0
- package/src/assets/web-panel/assets/{index-Bw0k3VgD.js → index-CL-36X3A.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYFjOyTH.js → index-Ca2hwPMo.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVvz3ntc.js → index-CaxzeSIM.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9um0YVl.js → index-CiEdfbB9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DugZRCiI.js → index-Cm9DYzhC.js} +1 -1
- package/src/assets/web-panel/assets/{index-pgGKNvmm.js → index-CpwgF7vh.js} +1 -1
- package/src/assets/web-panel/assets/{index-P-ailFQY.js → index-DEvdSKT4.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9ImNw5O.js → index-DL0k35f0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSCiZJXb.js → index-DarVV5yG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BIeFLaMV.js → index-DpSp97J8.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-KTHSUE.js → index-Dr18agDl.js} +1 -1
- package/src/assets/web-panel/assets/{index-DiDgwRty.js → index-Dwg38xTG.js} +1 -1
- package/src/assets/web-panel/assets/{index-D93iSDUw.js → index-DzZHBzCb.js} +1 -1
- package/src/assets/web-panel/assets/{index-6Nvzgytx.js → index-IX0g0s2t.js} +1 -1
- package/src/assets/web-panel/assets/{index-CG_b1xyX.js → index-LRb0QX6S.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cuz2QCFT.js → index-NEW5EN2w.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUjyL0ZS.js → index-T4T84G6X.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdyTv6yc.js → index-VD-dTYQE.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEiHKah0.js → index-cCqCEa9X.js} +3 -3
- package/src/assets/web-panel/assets/{index-DD6dD3LV.js → index-cKBpcInt.js} +1 -1
- package/src/assets/web-panel/assets/{index-TLBpgN30.js → index-hPy_f08G.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSe_7MSy.js → index-pzYLf5qu.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZ6JUooI.js → index-rFaCnjXi.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CVCXG2Hv.js → initDefaultProps-BWVLgWhF.js} +1 -1
- package/src/assets/web-panel/assets/{motion-Dv00jw87.js → motion-KJZ1xfDE.js} +1 -1
- package/src/assets/web-panel/assets/{move-BFz51iHf.js → move-DGqU6H7M.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BK2woIDE.js → mtc-parser-Dg0xkI5J.js} +1 -1
- package/src/assets/web-panel/assets/{omit-D2X_Gwoo.js → omit-B6RnMJAQ.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CLmFyJ1q.js → pickAttrs-Ctw2i3jb.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CCzPddQm.js → placementArrow-D3F3x8Jm.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-hcm_Zlxd.js → responsiveObserve-W6eHE0nM.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BxfZEFVp.js → slide-BlFf8sY5.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-kzB9pT-t.js → statusUtils-Cd6LMwmy.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CDFd7YCI.js → styleChecker-Bg5-U4Y1.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Czl7NNhS.js → useFlexGapSupport-DTkLS3tn.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-y0SAzirG.js → useFs-CwYGzoBt.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BvdPznrA.js → usePersonalDataHub-PCgFQXZP.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D8mNbyZ7.js → vnode-CJM7MkrB.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-_hun6w9W.js → zoom-CP0mgaFi.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/compact.js +7 -2
- package/src/data/changelog.json +28 -2
- package/src/harness/jsonl-session-store.js +78 -73
- package/src/harness/prompt-compressor.js +57 -3
- 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 +62 -12
- package/src/lib/evolution/agent-model-projection.js +90 -18
- package/src/lib/evolution/evidence-json-text.js +279 -42
- package/src/lib/evolution/evolution-evidence-projector.js +169 -26
- package/src/lib/evolution/governed-model-turn.js +2 -2
- package/src/lib/evolution/local-ui-evolution-deployment.js +2 -2
- package/src/lib/evolution/local-ui-evolution-runtime.js +4 -4
- package/src/lib/evolution/opaque-hex-id.js +8 -0
- package/src/lib/image-token-estimate.js +59 -0
- package/src/lib/read-file-loop-guard.js +9 -6
- package/src/lib/session-history-origins.js +25 -5
- package/src/lib/session-transcript-history.js +5 -1
- package/src/lib/tool-result-preview.js +276 -0
- package/src/runtime/agent-core.js +85 -78
- package/src/runtime/headless-stream.js +32 -17
- package/src/assets/web-panel/assets/MarkdownRenderer-5jYM4kYG.js +0 -1
- package/src/assets/web-panel/assets/Projects-Ce92-l1V.js +0 -1
- package/src/assets/web-panel/assets/devWarning-BBnVfJHh.js +0 -1
- package/src/assets/web-panel/assets/index-B2w_3mtS.js +0 -1
- package/src/assets/web-panel/assets/index-BoHurydC.js +0 -1
|
@@ -12,6 +12,22 @@ export const EVIDENCE_JSON_POLICY = Object.freeze({
|
|
|
12
12
|
numbers: "finite-safe-integers-pii-to-string",
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
+
export const AGENT_CODE_TEXT_RESULT_TOOLS = Object.freeze([
|
|
16
|
+
"run_code",
|
|
17
|
+
"read_file",
|
|
18
|
+
"run_shell",
|
|
19
|
+
"check_shell",
|
|
20
|
+
"git",
|
|
21
|
+
"search_files",
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
/* eslint-disable no-control-regex -- Quoted literals exclude unescaped control bytes. */
|
|
25
|
+
const JSON_STRING_PREFIX =
|
|
26
|
+
/^"(?:[^"\\\x00-\x1f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/u;
|
|
27
|
+
const CODE_DOUBLE_QUOTED_PREFIX = /^"(?:[^"\\\x00-\x1f]|\\[\s\S])*"/u;
|
|
28
|
+
const CODE_SINGLE_QUOTED_PREFIX = /^'(?:[^'\\\x00-\x1f]|\\[\s\S])*'/u;
|
|
29
|
+
/* eslint-enable no-control-regex */
|
|
30
|
+
|
|
15
31
|
export function isAgentToolArgumentsPath(path) {
|
|
16
32
|
return (
|
|
17
33
|
path.length === 6 &&
|
|
@@ -35,15 +51,103 @@ function assignmentKeyBefore(text, start, end) {
|
|
|
35
51
|
return keyEnd > index + 1 ? text.slice(index + 1, keyEnd) : undefined;
|
|
36
52
|
}
|
|
37
53
|
|
|
38
|
-
export function createEvidenceJsonTextBoundary(
|
|
54
|
+
export function createEvidenceJsonTextBoundary(
|
|
55
|
+
fail,
|
|
56
|
+
policy = EVIDENCE_JSON_POLICY,
|
|
57
|
+
) {
|
|
39
58
|
let nodes = 0;
|
|
40
59
|
let bytes = 0;
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
const PARSE_FAILURE = Symbol("evidence-json-parse-failure");
|
|
61
|
+
const reject = (
|
|
62
|
+
message = "Agent model JSON text is malformed or ambiguous",
|
|
63
|
+
) => {
|
|
64
|
+
throw fail(message);
|
|
65
|
+
};
|
|
66
|
+
const rejectParseFailure = (error) => {
|
|
67
|
+
reject(
|
|
68
|
+
error?.[PARSE_FAILURE] === "budget"
|
|
69
|
+
? "Agent model JSON text exceeds its budget"
|
|
70
|
+
: "Agent model JSON text is malformed or ambiguous",
|
|
44
71
|
);
|
|
45
72
|
};
|
|
46
|
-
const
|
|
73
|
+
const parserReject = (kind) => {
|
|
74
|
+
const error = new Error(kind);
|
|
75
|
+
Object.defineProperty(error, PARSE_FAILURE, { value: kind });
|
|
76
|
+
throw error;
|
|
77
|
+
};
|
|
78
|
+
const decodeSourceString = (literal, quote) => {
|
|
79
|
+
let output = "";
|
|
80
|
+
for (let index = 1; index < literal.length - 1; index++) {
|
|
81
|
+
const char = literal[index];
|
|
82
|
+
if (char !== "\\") {
|
|
83
|
+
output += char;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const escaped = literal[++index];
|
|
87
|
+
if (/[0-7]/u.test(escaped ?? "")) {
|
|
88
|
+
const digits = /^[0-7]{1,3}/u.exec(literal.slice(index))[0];
|
|
89
|
+
output += String.fromCodePoint(Number.parseInt(digits, 8));
|
|
90
|
+
index += digits.length - 1;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// Python named Unicode escapes require a Unicode-name database. Refuse
|
|
94
|
+
// them instead of treating an encoded sensitive key/value as plain text.
|
|
95
|
+
if (escaped === "N" && literal[index + 1] === "{")
|
|
96
|
+
return parserReject("syntax");
|
|
97
|
+
const simple = {
|
|
98
|
+
"'": "'",
|
|
99
|
+
'"': '"',
|
|
100
|
+
"\\": "\\",
|
|
101
|
+
b: "\b",
|
|
102
|
+
f: "\f",
|
|
103
|
+
n: "\n",
|
|
104
|
+
r: "\r",
|
|
105
|
+
t: "\t",
|
|
106
|
+
v: "\v",
|
|
107
|
+
0: "\0",
|
|
108
|
+
};
|
|
109
|
+
if (escaped === quote || Object.hasOwn(simple, escaped)) {
|
|
110
|
+
output += simple[escaped] ?? escaped;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (escaped === "x" || escaped === "u" || escaped === "U") {
|
|
114
|
+
if (escaped === "u" && literal[index + 1] === "{") {
|
|
115
|
+
const close = literal.indexOf("}", index + 2);
|
|
116
|
+
const digits = close < 0 ? "" : literal.slice(index + 2, close);
|
|
117
|
+
if (/^[0-9a-fA-F]{1,6}$/u.test(digits)) {
|
|
118
|
+
const codePoint = Number.parseInt(digits, 16);
|
|
119
|
+
if (codePoint <= 0x10ffff) {
|
|
120
|
+
output += String.fromCodePoint(codePoint);
|
|
121
|
+
index = close;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const count = escaped === "x" ? 2 : escaped === "u" ? 4 : 8;
|
|
127
|
+
const digits = literal.slice(index + 1, index + 1 + count);
|
|
128
|
+
if (new RegExp(`^[0-9a-fA-F]{${count}}$`, "u").test(digits)) {
|
|
129
|
+
const codePoint = Number.parseInt(digits, 16);
|
|
130
|
+
if (codePoint <= 0x10ffff) {
|
|
131
|
+
output += String.fromCodePoint(codePoint);
|
|
132
|
+
index += count;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
output += `\\${escaped}`;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// Keep line continuations and language-specific escapes bounded to the
|
|
140
|
+
// source literal. The decoded value is used only for evidence scanning.
|
|
141
|
+
if (escaped === "\n") continue;
|
|
142
|
+
if (escaped === "\r" && literal[index + 1] === "\n") {
|
|
143
|
+
index++;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
output += escaped;
|
|
147
|
+
}
|
|
148
|
+
return output;
|
|
149
|
+
};
|
|
150
|
+
const parser = (text, start, { allowSingleQuotedStrings = false } = {}) => {
|
|
47
151
|
let index = start;
|
|
48
152
|
const whitespace = () => {
|
|
49
153
|
while (/[ \t\r\n]/u.test(text[index] ?? "x")) index++;
|
|
@@ -57,21 +161,32 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
57
161
|
try {
|
|
58
162
|
return JSON.parse(text.slice(begin, index));
|
|
59
163
|
} catch {
|
|
60
|
-
|
|
164
|
+
if (allowSingleQuotedStrings)
|
|
165
|
+
return decodeSourceString(text.slice(begin, index), '"');
|
|
166
|
+
return parserReject("syntax");
|
|
61
167
|
}
|
|
62
168
|
}
|
|
63
169
|
}
|
|
64
|
-
return
|
|
170
|
+
return parserReject("syntax");
|
|
171
|
+
};
|
|
172
|
+
const singleQuotedString = () => {
|
|
173
|
+
const begin = index++;
|
|
174
|
+
while (index < text.length) {
|
|
175
|
+
const char = text[index++];
|
|
176
|
+
if (char === "\\") index++;
|
|
177
|
+
else if (char === "'")
|
|
178
|
+
return decodeSourceString(text.slice(begin, index), "'");
|
|
179
|
+
}
|
|
180
|
+
return parserReject("syntax");
|
|
65
181
|
};
|
|
66
182
|
const value = (depth = 0) => {
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
depth > EVIDENCE_JSON_POLICY.maxDepth
|
|
70
|
-
)
|
|
71
|
-
reject();
|
|
183
|
+
if (++nodes > policy.maxNodes || depth > policy.maxDepth)
|
|
184
|
+
parserReject("budget");
|
|
72
185
|
whitespace();
|
|
73
186
|
const char = text[index];
|
|
74
187
|
if (char === '"') return string();
|
|
188
|
+
if (char === "'" && allowSingleQuotedStrings) return singleQuotedString();
|
|
189
|
+
if (char === "'") return parserReject("code-expression");
|
|
75
190
|
if (char === "{" || char === "[") {
|
|
76
191
|
const array = char === "[";
|
|
77
192
|
const end = array ? "]" : "}";
|
|
@@ -85,11 +200,19 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
85
200
|
while (index < text.length) {
|
|
86
201
|
let key;
|
|
87
202
|
if (!array) {
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
203
|
+
if (
|
|
204
|
+
text[index] !== '"' &&
|
|
205
|
+
!(allowSingleQuotedStrings && text[index] === "'")
|
|
206
|
+
)
|
|
207
|
+
parserReject(
|
|
208
|
+
text[index] === "'" || /^[A-Za-z_$]/u.test(text[index] ?? "")
|
|
209
|
+
? "code-expression"
|
|
210
|
+
: "syntax",
|
|
211
|
+
);
|
|
212
|
+
key = text[index] === "'" ? singleQuotedString() : string();
|
|
213
|
+
if (Object.hasOwn(output, key)) parserReject("ambiguous");
|
|
91
214
|
whitespace();
|
|
92
|
-
if (text[index++] !== ":")
|
|
215
|
+
if (text[index++] !== ":") parserReject("syntax");
|
|
93
216
|
}
|
|
94
217
|
const child = value(depth + 1);
|
|
95
218
|
if (array) output.push(child);
|
|
@@ -103,16 +226,34 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
103
226
|
index++;
|
|
104
227
|
return output;
|
|
105
228
|
}
|
|
106
|
-
if (text[index
|
|
229
|
+
if (text[index] !== ",") {
|
|
230
|
+
// Slices, comprehensions and member/call/arithmetic expressions
|
|
231
|
+
// are source syntax. Missing delimiters and trailing commas stay
|
|
232
|
+
// malformed JSON, including in run_code output.
|
|
233
|
+
parserReject(
|
|
234
|
+
(array && text[index] === ":") ||
|
|
235
|
+
/^[.(+*/?]/u.test(text[index] ?? "") ||
|
|
236
|
+
/^for\b/u.test(text.slice(index))
|
|
237
|
+
? "code-expression"
|
|
238
|
+
: "syntax",
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
index++;
|
|
107
242
|
whitespace();
|
|
108
243
|
}
|
|
109
|
-
return
|
|
244
|
+
return parserReject("syntax");
|
|
110
245
|
}
|
|
111
246
|
const token =
|
|
112
247
|
/^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)/u.exec(
|
|
113
248
|
text.slice(index),
|
|
114
249
|
)?.[0];
|
|
115
|
-
if (!token)
|
|
250
|
+
if (!token) {
|
|
251
|
+
return parserReject(
|
|
252
|
+
/^[A-Za-z_$][A-Za-z0-9_$]*|^\(/u.test(text.slice(index))
|
|
253
|
+
? "code-expression"
|
|
254
|
+
: "syntax",
|
|
255
|
+
);
|
|
256
|
+
}
|
|
116
257
|
index += token.length;
|
|
117
258
|
const parsed = JSON.parse(token);
|
|
118
259
|
if (
|
|
@@ -120,7 +261,7 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
120
261
|
(!Number.isFinite(parsed) ||
|
|
121
262
|
(Number.isInteger(parsed) && !Number.isSafeInteger(parsed)))
|
|
122
263
|
)
|
|
123
|
-
|
|
264
|
+
parserReject("budget");
|
|
124
265
|
return parsed;
|
|
125
266
|
};
|
|
126
267
|
return {
|
|
@@ -130,16 +271,26 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
130
271
|
};
|
|
131
272
|
};
|
|
132
273
|
|
|
133
|
-
return (
|
|
274
|
+
return (
|
|
275
|
+
text,
|
|
276
|
+
{ layer = 0, objectOnly = false, codeText = false, visit, plain, equal },
|
|
277
|
+
) => {
|
|
134
278
|
bytes += Buffer.byteLength(text, "utf8");
|
|
135
|
-
if (bytes >
|
|
279
|
+
if (bytes > policy.maxDecodedBytes)
|
|
280
|
+
reject("Agent model JSON text exceeds its budget");
|
|
136
281
|
const transform = (parsed) => {
|
|
137
|
-
if (layer >=
|
|
282
|
+
if (layer >= policy.maxLayers)
|
|
283
|
+
reject("Agent model JSON text exceeds its budget");
|
|
138
284
|
return visit(parsed, layer + 1);
|
|
139
285
|
};
|
|
140
286
|
if (objectOnly) {
|
|
141
287
|
const reader = parser(text, 0);
|
|
142
|
-
|
|
288
|
+
let parsed;
|
|
289
|
+
try {
|
|
290
|
+
parsed = reader.value();
|
|
291
|
+
} catch (error) {
|
|
292
|
+
rejectParseFailure(error);
|
|
293
|
+
}
|
|
143
294
|
reader.whitespace();
|
|
144
295
|
if (
|
|
145
296
|
reader.end() !== text.length ||
|
|
@@ -157,7 +308,7 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
157
308
|
// as objects. Ordinary code braces and projection markers are not JSON.
|
|
158
309
|
let output = "";
|
|
159
310
|
let plainStart = 0;
|
|
160
|
-
for (let index = 0; index < text.length;) {
|
|
311
|
+
for (let index = 0; index < text.length; ) {
|
|
161
312
|
const char = text[index];
|
|
162
313
|
const next =
|
|
163
314
|
char === "{" || char === "["
|
|
@@ -173,7 +324,8 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
173
324
|
/^\s*(?:-\d|(?:true|false|null)(?=[\s,\]]))/u.test(
|
|
174
325
|
text.slice(index + 1),
|
|
175
326
|
)));
|
|
176
|
-
|
|
327
|
+
const quoted = char === '"' || (codeText && char === "'");
|
|
328
|
+
if (!container && !quoted) {
|
|
177
329
|
index++;
|
|
178
330
|
continue;
|
|
179
331
|
}
|
|
@@ -181,34 +333,110 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
181
333
|
// lexically valid JSON string is a candidate outside JSON containers.
|
|
182
334
|
if (
|
|
183
335
|
!container &&
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
text.slice(index)
|
|
187
|
-
|
|
336
|
+
char === '"' &&
|
|
337
|
+
!(codeText
|
|
338
|
+
? CODE_DOUBLE_QUOTED_PREFIX.test(text.slice(index))
|
|
339
|
+
: JSON_STRING_PREFIX.test(text.slice(index)))
|
|
188
340
|
) {
|
|
189
341
|
index++;
|
|
190
342
|
continue;
|
|
191
343
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
344
|
+
if (
|
|
345
|
+
codeText &&
|
|
346
|
+
char === "'" &&
|
|
347
|
+
!CODE_SINGLE_QUOTED_PREFIX.test(text.slice(index))
|
|
348
|
+
) {
|
|
349
|
+
index++;
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
const reader = parser(text, index, {
|
|
353
|
+
// A recognized container is always tried as strict JSON first, even
|
|
354
|
+
// inside code. Only an explicit non-JSON token allows literal scanning.
|
|
355
|
+
allowSingleQuotedStrings: codeText && !container,
|
|
356
|
+
});
|
|
357
|
+
let parsed;
|
|
358
|
+
let valueEnd;
|
|
359
|
+
try {
|
|
360
|
+
parsed = reader.value();
|
|
361
|
+
valueEnd = reader.end();
|
|
362
|
+
} catch (error) {
|
|
363
|
+
const kind = error?.[PARSE_FAILURE];
|
|
364
|
+
if (!codeText || kind !== "code-expression") rejectParseFailure(error);
|
|
365
|
+
// Python/JavaScript containers may contain single quotes or expressions.
|
|
366
|
+
// Scan their literals individually, preserving nested strict JSON scans.
|
|
367
|
+
// Keep consumed nodes charged so repeated fallback cannot reset budgets.
|
|
368
|
+
index++;
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
195
371
|
reader.whitespace();
|
|
196
|
-
|
|
372
|
+
let pair = quoted && text[reader.end()] === ":";
|
|
373
|
+
let pairValueEnd;
|
|
374
|
+
const requireSafeExpressionKey = () => {
|
|
375
|
+
// An expression cannot be visited as a decoded JSON value. Preserve
|
|
376
|
+
// the decoded key boundary: otherwise a password list/call expression
|
|
377
|
+
// could expose its string literals when scanning resumes inside it.
|
|
378
|
+
const probe = Object.defineProperty(Object.create(null), parsed, {
|
|
379
|
+
value: "source-expression",
|
|
380
|
+
enumerable: true,
|
|
381
|
+
});
|
|
382
|
+
if (!equal(probe, transform(probe)))
|
|
383
|
+
reject(
|
|
384
|
+
"Agent model code expression under a sensitive key cannot be safely projected",
|
|
385
|
+
);
|
|
386
|
+
};
|
|
387
|
+
if (pair) {
|
|
388
|
+
const rhsStart = reader.end() + 1;
|
|
389
|
+
const codeExpression = codeText
|
|
390
|
+
? /^\s*([A-Za-z_$][A-Za-z0-9_$]*)/u.exec(text.slice(rhsStart))?.[1]
|
|
391
|
+
: undefined;
|
|
392
|
+
if (
|
|
393
|
+
codeExpression &&
|
|
394
|
+
!["true", "false", "null"].includes(codeExpression)
|
|
395
|
+
) {
|
|
396
|
+
requireSafeExpressionKey();
|
|
397
|
+
pair = false;
|
|
398
|
+
} else {
|
|
399
|
+
try {
|
|
400
|
+
const rhsContainer = /^[ \t\r\n]*[\[{]/u.test(text.slice(rhsStart));
|
|
401
|
+
const rhs = parser(text, rhsStart, {
|
|
402
|
+
allowSingleQuotedStrings: codeText && !rhsContainer,
|
|
403
|
+
});
|
|
404
|
+
const entry = rhs.value();
|
|
405
|
+
const entryEnd = rhs.end();
|
|
406
|
+
rhs.whitespace();
|
|
407
|
+
if (
|
|
408
|
+
codeText &&
|
|
409
|
+
/^[+\-*/%?.([<>&|^=!"']/u.test(text[rhs.end()] ?? "")
|
|
410
|
+
)
|
|
411
|
+
requireSafeExpressionKey();
|
|
412
|
+
parsed = Object.defineProperty(Object.create(null), parsed, {
|
|
413
|
+
value: entry,
|
|
414
|
+
enumerable: true,
|
|
415
|
+
});
|
|
416
|
+
pairValueEnd = entryEnd;
|
|
417
|
+
} catch (error) {
|
|
418
|
+
const kind = error?.[PARSE_FAILURE];
|
|
419
|
+
if (kind === undefined) throw error;
|
|
420
|
+
if (!codeText || kind !== "code-expression")
|
|
421
|
+
rejectParseFailure(error);
|
|
422
|
+
// In a run_code source/result string, a quoted key followed by a
|
|
423
|
+
// Python/JavaScript expression is code, not a broken JSON pair.
|
|
424
|
+
// Resume the scan at the next literal so any string value still
|
|
425
|
+
// receives key-aware or ordinary secret scanning.
|
|
426
|
+
requireSafeExpressionKey();
|
|
427
|
+
pair = false;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
197
431
|
const assignmentKey =
|
|
198
|
-
|
|
432
|
+
quoted && !pair
|
|
199
433
|
? // Scan backward once; an unanchored greedy key regex would retry at
|
|
200
434
|
// every offset of a long ordinary prefix before a quoted fragment.
|
|
201
435
|
assignmentKeyBefore(text, plainStart, index)
|
|
202
436
|
: undefined;
|
|
203
437
|
let end = valueEnd;
|
|
204
438
|
if (pair) {
|
|
205
|
-
|
|
206
|
-
const entry = rhs.value();
|
|
207
|
-
parsed = Object.defineProperty(Object.create(null), parsed, {
|
|
208
|
-
value: entry,
|
|
209
|
-
enumerable: true,
|
|
210
|
-
});
|
|
211
|
-
end = rhs.end();
|
|
439
|
+
end = pairValueEnd;
|
|
212
440
|
} else if (assignmentKey) {
|
|
213
441
|
// Bare assignments followed by a quoted value cross a text/JSON span.
|
|
214
442
|
// Reuse decoded field rules rather than a second credential-key list.
|
|
@@ -218,6 +446,15 @@ export function createEvidenceJsonTextBoundary(fail) {
|
|
|
218
446
|
});
|
|
219
447
|
}
|
|
220
448
|
const safe = transform(parsed);
|
|
449
|
+
if (
|
|
450
|
+
codeText &&
|
|
451
|
+
assignmentKey &&
|
|
452
|
+
!equal(parsed, safe) &&
|
|
453
|
+
/^\s*[+\-*/%?.([<>&|^=!"']/u.test(text.slice(end))
|
|
454
|
+
)
|
|
455
|
+
reject(
|
|
456
|
+
"Agent model code expression under a sensitive key cannot be safely projected",
|
|
457
|
+
);
|
|
221
458
|
let replacement = text.slice(index, end);
|
|
222
459
|
if (!equal(parsed, safe)) {
|
|
223
460
|
replacement = JSON.stringify(safe);
|