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
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createEvidenceJsonTextBoundary,
|
|
3
|
+
AGENT_CODE_TEXT_RESULT_TOOLS,
|
|
4
|
+
} from "./evolution/evidence-json-text.js";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
|
|
7
|
+
// Keep host identity outside the JSON evidence object. External JSON results
|
|
8
|
+
// cannot nominate a digest or borrow an earlier command's output identity.
|
|
9
|
+
const HOST_OUTPUT_IDENTITIES = new WeakMap();
|
|
10
|
+
export function registerHostToolOutput(result, output) {
|
|
11
|
+
HOST_OUTPUT_IDENTITIES.set(
|
|
12
|
+
result,
|
|
13
|
+
Object.freeze({
|
|
14
|
+
chars: output.length,
|
|
15
|
+
digest: createHash("sha256").update(output).digest("hex"),
|
|
16
|
+
visibleOutput: result.output,
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
export function copyHostToolOutputIdentity(result, source) {
|
|
22
|
+
const identity = HOST_OUTPUT_IDENTITIES.get(source);
|
|
23
|
+
if (identity) HOST_OUTPUT_IDENTITIES.set(result, identity);
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
export function hostToolOutputIdentity(result) {
|
|
27
|
+
const identity = HOST_OUTPUT_IDENTITIES.get(result);
|
|
28
|
+
return identity?.visibleOutput === result?.output ? identity : undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const PREVIEW_HINT =
|
|
32
|
+
"Tool output truncated. Narrow the request: filter/count locally, select fields, search_files, or read_file with offset/limit. Omitted text is not full-output evidence.";
|
|
33
|
+
|
|
34
|
+
/** Check only host-created excerpts; original uncut tool text still reaches ingress. */
|
|
35
|
+
function completeExcerpt(text, tool) {
|
|
36
|
+
const scan = createEvidenceJsonTextBoundary((message) => new Error(message));
|
|
37
|
+
const visit = (value, layer) => {
|
|
38
|
+
if (typeof value === "string") return project(value, layer);
|
|
39
|
+
if (Array.isArray(value)) return value.map((child) => visit(child, layer));
|
|
40
|
+
if (value && typeof value === "object") {
|
|
41
|
+
return Object.fromEntries(
|
|
42
|
+
Object.entries(value).map(([key, child]) => [key, visit(child, layer)]),
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
return value;
|
|
46
|
+
};
|
|
47
|
+
const project = (value, layer = 0) =>
|
|
48
|
+
scan(value, {
|
|
49
|
+
layer,
|
|
50
|
+
codeText: AGENT_CODE_TEXT_RESULT_TOOLS.includes(tool),
|
|
51
|
+
visit,
|
|
52
|
+
plain: (plain) => plain,
|
|
53
|
+
equal: (left, right) => JSON.stringify(left) === JSON.stringify(right),
|
|
54
|
+
});
|
|
55
|
+
try {
|
|
56
|
+
project(text);
|
|
57
|
+
return true;
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function omitted(chars) {
|
|
64
|
+
return `Text omitted (${chars} chars); narrow the request to inspect a complete value.`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const STATUS_KEYS = new Set([
|
|
68
|
+
"success",
|
|
69
|
+
"error",
|
|
70
|
+
"exitCode",
|
|
71
|
+
"status",
|
|
72
|
+
"code",
|
|
73
|
+
"signal",
|
|
74
|
+
"path",
|
|
75
|
+
"range",
|
|
76
|
+
"nextRead",
|
|
77
|
+
"duration",
|
|
78
|
+
"language",
|
|
79
|
+
]);
|
|
80
|
+
|
|
81
|
+
// Native JSON.parse is used only after checking its lossy cases: duplicate
|
|
82
|
+
// decoded keys and non-finite/unsafe numbers must never turn into a safe-looking
|
|
83
|
+
// preview. This pass does not repair syntax or decode text leaves.
|
|
84
|
+
function parsePreviewJson(text) {
|
|
85
|
+
const value = JSON.parse(text);
|
|
86
|
+
const stack = [];
|
|
87
|
+
for (let index = 0; index < text.length; index++) {
|
|
88
|
+
const char = text[index];
|
|
89
|
+
if (char === '"') {
|
|
90
|
+
const start = index;
|
|
91
|
+
while (++index < text.length) {
|
|
92
|
+
if (text[index] === "\\") index++;
|
|
93
|
+
else if (text[index] === '"') break;
|
|
94
|
+
}
|
|
95
|
+
const object = stack.at(-1);
|
|
96
|
+
if (object?.key) {
|
|
97
|
+
const key = JSON.parse(text.slice(start, index + 1));
|
|
98
|
+
if (object.keys.has(key)) throw new TypeError("Ambiguous JSON keys");
|
|
99
|
+
object.keys.add(key);
|
|
100
|
+
object.key = false;
|
|
101
|
+
}
|
|
102
|
+
} else if (char === "{") stack.push({ keys: new Set(), key: true });
|
|
103
|
+
else if (char === "[") stack.push(null);
|
|
104
|
+
else if (char === "}" || char === "]") stack.pop();
|
|
105
|
+
else if (char === "," && stack.at(-1)) stack.at(-1).key = true;
|
|
106
|
+
else if (/[\d-]/u.test(char)) {
|
|
107
|
+
const token = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/u.exec(
|
|
108
|
+
text.slice(index),
|
|
109
|
+
)[0];
|
|
110
|
+
const number = Number(token);
|
|
111
|
+
if (
|
|
112
|
+
!Number.isFinite(number) ||
|
|
113
|
+
(Number.isInteger(number) && !Number.isSafeInteger(number))
|
|
114
|
+
)
|
|
115
|
+
throw new TypeError("Unsafe JSON number");
|
|
116
|
+
index += token.length - 1;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Produce complete JSON values, never prefixes of a JSON leaf. */
|
|
123
|
+
export function boundedToolResultText(text, max) {
|
|
124
|
+
if (text.length <= max) return text;
|
|
125
|
+
let original;
|
|
126
|
+
try {
|
|
127
|
+
original = parsePreviewJson(text);
|
|
128
|
+
} catch {
|
|
129
|
+
// Plain output can retain a prefix only when it cannot contain a sliced
|
|
130
|
+
// structured span. In particular, do not hide broken JSON in a preview.
|
|
131
|
+
if (!/[{}\[\]"']/u.test(text)) {
|
|
132
|
+
const marker = `\nTool output truncated (${text.length} chars). Narrow the request.`;
|
|
133
|
+
if (marker.length < max) {
|
|
134
|
+
let end = max - marker.length;
|
|
135
|
+
if (/[\uD800-\uDBFF]/u.test(text[end - 1] ?? "")) end--;
|
|
136
|
+
return text.slice(0, end) + marker;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
original = omitted(text.length);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for (const limit of [8192, 2048, 512, 128, 0]) {
|
|
143
|
+
let nodes = 0;
|
|
144
|
+
const preview = (value, depth = 0) => {
|
|
145
|
+
if (++nodes > 128 || depth > 6)
|
|
146
|
+
return "Value omitted; select a smaller subtree.";
|
|
147
|
+
if (typeof value === "string")
|
|
148
|
+
return JSON.stringify(value).length > limit
|
|
149
|
+
? omitted(value.length)
|
|
150
|
+
: value;
|
|
151
|
+
if (!value || typeof value !== "object") return value;
|
|
152
|
+
if (Array.isArray(value)) {
|
|
153
|
+
const kept = [];
|
|
154
|
+
for (const child of value) {
|
|
155
|
+
if (kept.length >= 32 || nodes >= 128) break;
|
|
156
|
+
kept.push(preview(child, depth + 1));
|
|
157
|
+
}
|
|
158
|
+
if (kept.length < value.length)
|
|
159
|
+
kept.push(
|
|
160
|
+
`Items omitted (${value.length - kept.length}); narrow the request.`,
|
|
161
|
+
);
|
|
162
|
+
return kept;
|
|
163
|
+
}
|
|
164
|
+
const kept = Object.create(null);
|
|
165
|
+
const entries = Object.entries(value).sort(
|
|
166
|
+
([a], [b]) => Number(STATUS_KEYS.has(b)) - Number(STATUS_KEYS.has(a)),
|
|
167
|
+
);
|
|
168
|
+
let count = 0;
|
|
169
|
+
for (const [key, child] of entries) {
|
|
170
|
+
if (count >= 32 || nodes >= 128) break;
|
|
171
|
+
if (key.length > 256) continue;
|
|
172
|
+
Object.defineProperty(kept, key, {
|
|
173
|
+
enumerable: true,
|
|
174
|
+
value: preview(child, depth + 1),
|
|
175
|
+
});
|
|
176
|
+
count++;
|
|
177
|
+
}
|
|
178
|
+
if (count < entries.length) {
|
|
179
|
+
let marker = "_omittedFields";
|
|
180
|
+
while (Object.hasOwn(kept, marker)) marker += "_";
|
|
181
|
+
Object.defineProperty(kept, marker, {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
value: entries.length - count,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return kept;
|
|
187
|
+
};
|
|
188
|
+
const value = preview(original);
|
|
189
|
+
const result =
|
|
190
|
+
value && !Array.isArray(value) && typeof value === "object"
|
|
191
|
+
? value
|
|
192
|
+
: { preview: value };
|
|
193
|
+
let marker = "_toolOutputPreview";
|
|
194
|
+
while (Object.hasOwn(result, marker)) marker += "_";
|
|
195
|
+
Object.defineProperty(result, marker, {
|
|
196
|
+
enumerable: true,
|
|
197
|
+
value: {
|
|
198
|
+
truncated: true,
|
|
199
|
+
originalChars: text.length,
|
|
200
|
+
hint: PREVIEW_HINT,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
const serialized = JSON.stringify(result);
|
|
204
|
+
if (serialized.length <= max) return serialized;
|
|
205
|
+
}
|
|
206
|
+
const summary = JSON.stringify({
|
|
207
|
+
truncated: true,
|
|
208
|
+
originalChars: text.length,
|
|
209
|
+
hint: PREVIEW_HINT,
|
|
210
|
+
});
|
|
211
|
+
if (summary.length <= max) return summary;
|
|
212
|
+
if (max >= 18) return '{"truncated":true}';
|
|
213
|
+
return max >= 4 ? "null" : max >= 2 ? "{}" : "0";
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Keep cursors/status, but remove JSON fragments created by host paging. */
|
|
217
|
+
export function safeHostToolResultForModel(tool, result) {
|
|
218
|
+
if (!result || typeof result !== "object" || Array.isArray(result))
|
|
219
|
+
return result;
|
|
220
|
+
const fields = [];
|
|
221
|
+
if (
|
|
222
|
+
tool === "read_file" &&
|
|
223
|
+
(result.truncated || result.range || result.nextRead)
|
|
224
|
+
)
|
|
225
|
+
fields.push("content");
|
|
226
|
+
if (tool === "run_code" && result.truncated) fields.push("output");
|
|
227
|
+
if (tool === "check_shell") fields.push("stdout", "stderr");
|
|
228
|
+
if (tool === "run_shell" || tool === "git") {
|
|
229
|
+
for (const field of ["stdout", "stderr"])
|
|
230
|
+
if (result[`${field}_truncated`])
|
|
231
|
+
fields.push(field, `${field}_diagnostics`);
|
|
232
|
+
}
|
|
233
|
+
let safe = result;
|
|
234
|
+
for (const field of fields) {
|
|
235
|
+
const text = result[field];
|
|
236
|
+
if (typeof text !== "string" || completeExcerpt(text, tool)) continue;
|
|
237
|
+
if (safe === result) safe = { ...result };
|
|
238
|
+
safe[field] = omitted(text.length);
|
|
239
|
+
safe[`${field}Omitted`] = true;
|
|
240
|
+
safe[`${field}OmittedChars`] = text.length;
|
|
241
|
+
}
|
|
242
|
+
return safe;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Prefer a whole JSON tree over slicing stdout through an embedded value. */
|
|
246
|
+
export function boundedCommandOutput(output, max, tool = "run_code") {
|
|
247
|
+
const encoded = JSON.stringify(output);
|
|
248
|
+
if (encoded.length <= max) return output;
|
|
249
|
+
// If stdout itself is JSON, preview that tree rather than its quoted form.
|
|
250
|
+
let json = false;
|
|
251
|
+
try {
|
|
252
|
+
parsePreviewJson(output);
|
|
253
|
+
json = true;
|
|
254
|
+
} catch {
|
|
255
|
+
/* Plain command text. */
|
|
256
|
+
}
|
|
257
|
+
if (json) {
|
|
258
|
+
const preview = boundedToolResultText(
|
|
259
|
+
output,
|
|
260
|
+
Math.max(1, Math.floor(max / 2)),
|
|
261
|
+
);
|
|
262
|
+
if (JSON.stringify(preview).length <= max && completeExcerpt(preview, tool))
|
|
263
|
+
return preview;
|
|
264
|
+
} else if (!/[{}\[\]"']/u.test(output)) {
|
|
265
|
+
let low = 0;
|
|
266
|
+
let high = Math.min(output.length, max);
|
|
267
|
+
while (low < high) {
|
|
268
|
+
const middle = Math.ceil((low + high) / 2);
|
|
269
|
+
if (JSON.stringify(output.slice(0, middle)).length <= max) low = middle;
|
|
270
|
+
else high = middle - 1;
|
|
271
|
+
}
|
|
272
|
+
if (/[\uD800-\uDBFF]/u.test(output[low - 1] ?? "")) low--;
|
|
273
|
+
return output.slice(0, low);
|
|
274
|
+
}
|
|
275
|
+
return omitted(output.length);
|
|
276
|
+
}
|
|
@@ -56,6 +56,13 @@ import { ReadFileLoopGuard } from "../lib/read-file-loop-guard.js";
|
|
|
56
56
|
const READ_FILE_REQUEST_CONTEXT = Symbol("read-file-request-context");
|
|
57
57
|
import { gitToolInputError } from "../lib/git-tool-input.js";
|
|
58
58
|
import { shellOutputPage, shellOutputPreview } from "../lib/shell-output.js";
|
|
59
|
+
import {
|
|
60
|
+
boundedToolResultText,
|
|
61
|
+
boundedCommandOutput,
|
|
62
|
+
safeHostToolResultForModel,
|
|
63
|
+
registerHostToolOutput,
|
|
64
|
+
copyHostToolOutputIdentity,
|
|
65
|
+
} from "../lib/tool-result-preview.js";
|
|
59
66
|
import { DIAGNOSTIC_WORKFLOW_GUIDANCE } from "../lib/diagnostic-workflow.js";
|
|
60
67
|
import { CODING_TASK_QUALITY_GUIDANCE } from "../lib/coding-task-guidance.js";
|
|
61
68
|
import { RemoteReadLoopGuard } from "../lib/remote-read-loop-guard.js";
|
|
@@ -4593,7 +4600,7 @@ export function editNotebookCell(notebookText, args = {}) {
|
|
|
4593
4600
|
const out = (summary, cellId) => ({
|
|
4594
4601
|
text: JSON.stringify(nb, null, 1) + "\n",
|
|
4595
4602
|
summary,
|
|
4596
|
-
cellId,
|
|
4603
|
+
cellId: cellId ?? null,
|
|
4597
4604
|
});
|
|
4598
4605
|
const locate = () => {
|
|
4599
4606
|
if (args.cell_id != null) {
|
|
@@ -5725,14 +5732,28 @@ async function executeToolInner(
|
|
|
5725
5732
|
descriptor
|
|
5726
5733
|
? {
|
|
5727
5734
|
name: descriptor.name,
|
|
5728
|
-
kind:
|
|
5729
|
-
|
|
5735
|
+
kind:
|
|
5736
|
+
descriptor.kind ||
|
|
5737
|
+
descriptor.category ||
|
|
5738
|
+
descriptor.telemetry?.category ||
|
|
5739
|
+
descriptor.source ||
|
|
5740
|
+
null,
|
|
5741
|
+
category:
|
|
5742
|
+
descriptor.category ??
|
|
5743
|
+
descriptor.telemetry?.category ??
|
|
5744
|
+
descriptor.kind ??
|
|
5745
|
+
null,
|
|
5730
5746
|
}
|
|
5731
5747
|
: null;
|
|
5732
5748
|
const descriptorPayload = buildPayload(runtimeDescriptor);
|
|
5733
5749
|
const attachDescriptor = (payload, overrideDescriptor = null) => {
|
|
5734
5750
|
const descriptor = buildPayload(overrideDescriptor || runtimeDescriptor);
|
|
5735
|
-
return descriptor
|
|
5751
|
+
return descriptor
|
|
5752
|
+
? copyHostToolOutputIdentity(
|
|
5753
|
+
{ ...payload, toolDescriptor: descriptor },
|
|
5754
|
+
payload,
|
|
5755
|
+
)
|
|
5756
|
+
: payload;
|
|
5736
5757
|
};
|
|
5737
5758
|
const localToolExecutor =
|
|
5738
5759
|
externalToolExecutors && typeof externalToolExecutors === "object"
|
|
@@ -7562,7 +7583,7 @@ async function executeToolInner(
|
|
|
7562
7583
|
? shellOutputPreview(err.stdout, "stdout", 16000)
|
|
7563
7584
|
: {}),
|
|
7564
7585
|
...shellOutputPreview(err.stderr, "stderr", 4000),
|
|
7565
|
-
exitCode: err.status,
|
|
7586
|
+
exitCode: err.status ?? null,
|
|
7566
7587
|
...(typeof err.code === "string" && err.code
|
|
7567
7588
|
? {
|
|
7568
7589
|
policy: {
|
|
@@ -7697,8 +7718,8 @@ async function executeToolInner(
|
|
|
7697
7718
|
) {
|
|
7698
7719
|
return attachDescriptor({
|
|
7699
7720
|
success: true,
|
|
7700
|
-
|
|
7701
|
-
|
|
7721
|
+
...shellOutputPreview(res.stdout, "stdout", 30000),
|
|
7722
|
+
...shellOutputPreview(res.stderr, "stderr", 2000),
|
|
7702
7723
|
exitCode: res.status,
|
|
7703
7724
|
command: normalizedCommand,
|
|
7704
7725
|
readOnly: true,
|
|
@@ -7707,11 +7728,13 @@ async function executeToolInner(
|
|
|
7707
7728
|
});
|
|
7708
7729
|
}
|
|
7709
7730
|
if (res.status !== 0) {
|
|
7710
|
-
const stderr = String(res.stderr || "")
|
|
7731
|
+
const stderr = String(res.stderr || "");
|
|
7711
7732
|
return attachDescriptor({
|
|
7712
|
-
error:
|
|
7713
|
-
|
|
7714
|
-
|
|
7733
|
+
error:
|
|
7734
|
+
boundedCommandOutput(stderr, 2000) ||
|
|
7735
|
+
`git exited with code ${res.status}`,
|
|
7736
|
+
...shellOutputPreview(res.stdout, "stdout", 30000),
|
|
7737
|
+
...shellOutputPreview(stderr, "stderr", 2000),
|
|
7715
7738
|
exitCode: res.status,
|
|
7716
7739
|
command: normalizedCommand,
|
|
7717
7740
|
readOnly,
|
|
@@ -7725,7 +7748,7 @@ async function executeToolInner(
|
|
|
7725
7748
|
});
|
|
7726
7749
|
}
|
|
7727
7750
|
return attachDescriptor({
|
|
7728
|
-
|
|
7751
|
+
...shellOutputPreview(res.stdout, "stdout", 30000),
|
|
7729
7752
|
exitCode: 0,
|
|
7730
7753
|
command: normalizedCommand,
|
|
7731
7754
|
readOnly,
|
|
@@ -8000,7 +8023,7 @@ async function executeToolInner(
|
|
|
8000
8023
|
const available = discoverCommands(cwd).map((c) => ({
|
|
8001
8024
|
name: c.name,
|
|
8002
8025
|
scope: c.scope,
|
|
8003
|
-
description: c.description
|
|
8026
|
+
...(c.description ? { description: c.description } : {}),
|
|
8004
8027
|
}));
|
|
8005
8028
|
return attachDescriptor({
|
|
8006
8029
|
error: `Unknown slash command "${head}".`,
|
|
@@ -8023,7 +8046,7 @@ async function executeToolInner(
|
|
|
8023
8046
|
command: macro.name,
|
|
8024
8047
|
scope: macro.scope,
|
|
8025
8048
|
expandedPrompt: expanded,
|
|
8026
|
-
warnings
|
|
8049
|
+
...(warnings?.length ? { warnings } : {}),
|
|
8027
8050
|
instructions:
|
|
8028
8051
|
"The expandedPrompt is the command's instructions. Carry them out " +
|
|
8029
8052
|
"now using your normal tools.",
|
|
@@ -10301,7 +10324,7 @@ async function _executeRunCode(args, cwd) {
|
|
|
10301
10324
|
error: `Invalid package name: "${packageName}"`,
|
|
10302
10325
|
...classified,
|
|
10303
10326
|
language: lang,
|
|
10304
|
-
|
|
10327
|
+
...(persist ? { scriptPath } : {}),
|
|
10305
10328
|
};
|
|
10306
10329
|
}
|
|
10307
10330
|
|
|
@@ -10323,13 +10346,13 @@ async function _executeRunCode(args, cwd) {
|
|
|
10323
10346
|
outcome: "disabled",
|
|
10324
10347
|
});
|
|
10325
10348
|
return {
|
|
10326
|
-
error: (stderr || message
|
|
10327
|
-
stderr: stderr
|
|
10328
|
-
exitCode: err.status,
|
|
10349
|
+
error: boundedCommandOutput(stderr || message, 5000),
|
|
10350
|
+
stderr: boundedCommandOutput(stderr, 5000),
|
|
10351
|
+
exitCode: err.status ?? null,
|
|
10329
10352
|
language: lang,
|
|
10330
10353
|
...classified,
|
|
10331
10354
|
hint: autoInstallDisabledHint(packageName),
|
|
10332
|
-
|
|
10355
|
+
...(persist ? { scriptPath } : {}),
|
|
10333
10356
|
};
|
|
10334
10357
|
}
|
|
10335
10358
|
if (!isPackageAllowed(packageName, installPolicy.allowlist)) {
|
|
@@ -10340,13 +10363,13 @@ async function _executeRunCode(args, cwd) {
|
|
|
10340
10363
|
outcome: "blocked",
|
|
10341
10364
|
});
|
|
10342
10365
|
return {
|
|
10343
|
-
error: (stderr || message
|
|
10344
|
-
stderr: stderr
|
|
10345
|
-
exitCode: err.status,
|
|
10366
|
+
error: boundedCommandOutput(stderr || message, 5000),
|
|
10367
|
+
stderr: boundedCommandOutput(stderr, 5000),
|
|
10368
|
+
exitCode: err.status ?? null,
|
|
10346
10369
|
language: lang,
|
|
10347
10370
|
...classified,
|
|
10348
10371
|
hint: `Package "${packageName}" is not in runCode.installAllowlist — install it manually or add it to the allowlist.`,
|
|
10349
|
-
|
|
10372
|
+
...(persist ? { scriptPath } : {}),
|
|
10350
10373
|
};
|
|
10351
10374
|
}
|
|
10352
10375
|
|
|
@@ -10396,13 +10419,13 @@ async function _executeRunCode(args, cwd) {
|
|
|
10396
10419
|
),
|
|
10397
10420
|
);
|
|
10398
10421
|
return {
|
|
10399
|
-
error: (stderr || message
|
|
10400
|
-
stderr: stderr
|
|
10401
|
-
exitCode: err.status,
|
|
10422
|
+
error: boundedCommandOutput(stderr || message, 5000),
|
|
10423
|
+
stderr: boundedCommandOutput(stderr, 5000),
|
|
10424
|
+
exitCode: err.status ?? null,
|
|
10402
10425
|
language: lang,
|
|
10403
10426
|
...classified,
|
|
10404
10427
|
hint: `Failed to auto-install "${packageName}". ${(installError.stderr || installError.message || "").substring(0, 500)}`,
|
|
10405
|
-
|
|
10428
|
+
...(persist ? { scriptPath } : {}),
|
|
10406
10429
|
};
|
|
10407
10430
|
};
|
|
10408
10431
|
|
|
@@ -10453,14 +10476,13 @@ async function _executeRunCode(args, cwd) {
|
|
|
10453
10476
|
);
|
|
10454
10477
|
const retryDuration = Date.now() - retryStart;
|
|
10455
10478
|
|
|
10456
|
-
return {
|
|
10479
|
+
return Object.assign(boundedCodeOutput(retryOutput), {
|
|
10457
10480
|
success: true,
|
|
10458
|
-
...boundedCodeOutput(retryOutput),
|
|
10459
10481
|
language: lang,
|
|
10460
10482
|
duration: `${retryDuration}ms`,
|
|
10461
10483
|
autoInstalled: [packageName],
|
|
10462
|
-
|
|
10463
|
-
};
|
|
10484
|
+
...(persist ? { scriptPath } : {}),
|
|
10485
|
+
});
|
|
10464
10486
|
} catch (retryErr) {
|
|
10465
10487
|
rethrowRunCodeSandboxFailure(retryErr);
|
|
10466
10488
|
const retryStderr = (retryErr.stderr || "").toString();
|
|
@@ -10472,37 +10494,36 @@ async function _executeRunCode(args, cwd) {
|
|
|
10472
10494
|
lang,
|
|
10473
10495
|
);
|
|
10474
10496
|
return {
|
|
10475
|
-
error: (retryStderr || retryMessage
|
|
10476
|
-
stderr: retryStderr
|
|
10477
|
-
exitCode: retryErr.status,
|
|
10497
|
+
error: boundedCommandOutput(retryStderr || retryMessage, 5000),
|
|
10498
|
+
stderr: boundedCommandOutput(retryStderr, 5000),
|
|
10499
|
+
exitCode: retryErr.status ?? null,
|
|
10478
10500
|
language: lang,
|
|
10479
10501
|
...retryClassified,
|
|
10480
10502
|
hint: `Package "${packageName}" was installed, but the script retry failed.`,
|
|
10481
10503
|
autoInstalled: [packageName],
|
|
10482
|
-
|
|
10504
|
+
...(persist ? { scriptPath } : {}),
|
|
10483
10505
|
};
|
|
10484
10506
|
}
|
|
10485
10507
|
}
|
|
10486
10508
|
}
|
|
10487
10509
|
|
|
10488
10510
|
return {
|
|
10489
|
-
error: (stderr || message
|
|
10490
|
-
stderr: stderr
|
|
10491
|
-
exitCode: err.status,
|
|
10511
|
+
error: boundedCommandOutput(stderr || message, 5000),
|
|
10512
|
+
stderr: boundedCommandOutput(stderr, 5000),
|
|
10513
|
+
exitCode: err.status ?? null,
|
|
10492
10514
|
language: lang,
|
|
10493
10515
|
...classified,
|
|
10494
|
-
|
|
10516
|
+
...(persist ? { scriptPath } : {}),
|
|
10495
10517
|
};
|
|
10496
10518
|
}
|
|
10497
10519
|
|
|
10498
10520
|
const duration = Date.now() - start;
|
|
10499
|
-
return {
|
|
10521
|
+
return Object.assign(boundedCodeOutput(output), {
|
|
10500
10522
|
success: true,
|
|
10501
|
-
...boundedCodeOutput(output),
|
|
10502
10523
|
language: lang,
|
|
10503
10524
|
duration: `${duration}ms`,
|
|
10504
|
-
|
|
10505
|
-
};
|
|
10525
|
+
...(persist ? { scriptPath } : {}),
|
|
10526
|
+
});
|
|
10506
10527
|
} finally {
|
|
10507
10528
|
// Only clean up if not persisting
|
|
10508
10529
|
if (!persist) {
|
|
@@ -10537,14 +10558,9 @@ export const MAX_SUB_AGENT_DEPTH = 5;
|
|
|
10537
10558
|
export const MAX_SUB_AGENTS_PER_RUN = 32;
|
|
10538
10559
|
|
|
10539
10560
|
/**
|
|
10540
|
-
*
|
|
10541
|
-
*
|
|
10542
|
-
*
|
|
10543
|
-
* `substring(0, 5000)` that sliced mid-content with no marker and undercut even
|
|
10544
|
-
* read_file's own 50k self-limit. Tools that self-limit (read_file, notebook
|
|
10545
|
-
* render) stay below this; it is the final safety net for the ones that don't
|
|
10546
|
-
* (run_shell, search_files, run_code, MCP). CC_MAX_TOOL_RESULT_CHARS may only
|
|
10547
|
-
* tighten the host ceiling; it cannot raise or disable it.
|
|
10561
|
+
* Total character cap fed back to the model, including truncation metadata.
|
|
10562
|
+
* Complete JSON previews retain status and small fields while omitting large
|
|
10563
|
+
* leaves. CC_MAX_TOOL_RESULT_CHARS may only tighten the host ceiling.
|
|
10548
10564
|
*/
|
|
10549
10565
|
export const MAX_TOOL_RESULT_CHARS_HARD_LIMIT = 50000;
|
|
10550
10566
|
|
|
@@ -10560,47 +10576,38 @@ export const MAX_TOOL_RESULT_CHARS = resolveMaxToolResultChars(
|
|
|
10560
10576
|
);
|
|
10561
10577
|
|
|
10562
10578
|
/**
|
|
10563
|
-
* Cap a serialized tool result
|
|
10564
|
-
*
|
|
10565
|
-
* so the model never silently receives a mid-content slice. Pure; exported for
|
|
10566
|
-
* tests.
|
|
10579
|
+
* Cap a serialized tool result without splitting JSON values. Plain prefixes
|
|
10580
|
+
* are allowed only when they cannot contain a truncated structured span.
|
|
10567
10581
|
*/
|
|
10568
10582
|
export function capToolResultString(serialized, max = MAX_TOOL_RESULT_CHARS) {
|
|
10569
10583
|
const s = String(serialized ?? "");
|
|
10570
10584
|
const effectiveMax = resolveMaxToolResultChars(max);
|
|
10571
|
-
|
|
10572
|
-
return (
|
|
10573
|
-
s.slice(0, effectiveMax) +
|
|
10574
|
-
`\n…[tool output truncated: showing the first ${effectiveMax} of ${s.length} chars` +
|
|
10575
|
-
` — narrow the request (read a line range, grep, or paginate) to see the rest]`
|
|
10576
|
-
);
|
|
10585
|
+
return boundedToolResultText(s, effectiveMax);
|
|
10577
10586
|
}
|
|
10578
10587
|
|
|
10579
10588
|
/** Leave room for JSON escaping and execution metadata, including the hint. */
|
|
10580
10589
|
export function boundedCodeOutput(value) {
|
|
10581
10590
|
const output = String(value ?? "");
|
|
10582
10591
|
const budget = Math.max(0, MAX_TOOL_RESULT_CHARS - 4096);
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
returnedChars: low,
|
|
10596
|
-
hint: "Only an output prefix is shown. Do not rerun the same full-file print: filter/count locally and print a bounded summary with source line numbers, or use read_file with offset/limit for a missing section. This prefix is not evidence of the entire file.",
|
|
10597
|
-
output: output.slice(0, low),
|
|
10598
|
-
};
|
|
10592
|
+
if (JSON.stringify(output).length <= budget) return { output };
|
|
10593
|
+
const preview = boundedCommandOutput(output, Math.max(1, budget));
|
|
10594
|
+
return registerHostToolOutput(
|
|
10595
|
+
{
|
|
10596
|
+
truncated: true,
|
|
10597
|
+
outputChars: output.length,
|
|
10598
|
+
returnedChars: preview.length,
|
|
10599
|
+
hint: "Output is incomplete. Do not rerun the same full-file print: filter/count locally and print a bounded summary with source line numbers, or use read_file with offset/limit for a missing section. Omitted text is not evidence of the entire file.",
|
|
10600
|
+
output: preview,
|
|
10601
|
+
},
|
|
10602
|
+
output,
|
|
10603
|
+
);
|
|
10599
10604
|
}
|
|
10600
10605
|
|
|
10601
10606
|
/** Avoid injecting the same file page twice while its original is still visible. */
|
|
10602
10607
|
export function toolResultForModel(tool, result, messages) {
|
|
10603
|
-
const serialized = capToolResultString(
|
|
10608
|
+
const serialized = capToolResultString(
|
|
10609
|
+
safeStringifyToolResult(safeHostToolResultForModel(tool, result)),
|
|
10610
|
+
);
|
|
10604
10611
|
if (
|
|
10605
10612
|
(tool === "run_code" || tool === "run_shell") &&
|
|
10606
10613
|
!result?.error &&
|