chainlesschain 0.166.48 → 0.166.58
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 +22 -0
- package/package.json +2 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-BLGEffkh.js → AIOps-DoyI29Aw.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Cz1z2VGD.js → ActionButton-eZKcEoxc.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-C3j9cf6q.js → Analytics-B2C2e9A7.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BR9ERuCA.js → AppLayout-DkZJiu4X.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CozJCm4y.js → Artifacts-8PD3BXVa.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DC5g9Ra2.js → Audit-Cv6sRlFu.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-B1zrQ0dW.js → BackgroundAgents-D-V84Qpm.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-ChVnfjpm.js → Backup-DYJQcxj1.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-8_vLQsLf.js → BaseInput-KL2IeywH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Dct9bm6L.js → Chat-Bt9wy_Yn.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BvoSsCKh.js → ChatBubbleRenderer-ChB6fH-W.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DZQIsCIC.js → Checkbox-Dm-nfdnd.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CdzHxmnq.js → Codegen-CYi3yDzv.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DdAN8LeW.js → Col-C7sQywfG.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CNgjT9MA.js → Community-DjxuqAM4.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BtQiX6G-.js → Compact-CD_4lbxr.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-OGX5ma3j.js → Compliance-BtDpNJrS.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CgugQnGM.js → Cowork-l19ANH6Q.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Bpg7cPFD.js → Cron-Br-rBoEK.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-D1hsuswf.js → Crosschain-60UVvKET.js} +1 -1
- package/src/assets/web-panel/assets/{DID-miDRsMBw.js → DID-B9dqar51.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CGcl8htP.js → Dashboard-B39hhdHb.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BFaxTdVE.js → Dropdown-Bm5rCfvF.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BQdGLZIO.js → EmailListRenderer-BI9HANDl.js} +1 -1
- package/src/assets/web-panel/assets/EvolutionSettings-Cfqn_yCq.js +1 -0
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-c1WVC_--.js → FamilyGuardDashboard-9Y4_zyhT.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DyAcFrQY.js → Federation-vnbbmMdF.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CfwpfD2B.js → FormItemContext-BEKNtNF9.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DkJcbBpS.js → GenericCardRenderer-BmWr16IL.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DgYIrPJh.js → Git-CUUwAXdn.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BF1tYPJ6.js → Governance-Bw8XZmH9.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-BFkwRIrU.js → Inference-CNrml6dn.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DpCoqhBa.js → KnowledgeGraph-BhxOwpW_.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DU2qAJmD.js → Logs-BV8WViUG.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-CO1qbiOY.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Dz9NUrfo.js → Marketplace-ztcu4mg4.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-B67I3d5v.js → McpTools-D-wzRO7z.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-crkElJSy.js → Memory-ChdjWC1R.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BO20VbdX.js → MobileBridge-B1QHzIjE.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Ba-3gZZd.js → MobileProjects-DmaRtaMw.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BAHZM084.js → Mtc-DRQMr4WP.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CL3DzajL.js → MtcAudit-Cwo0on-u.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-BSWWzvWH.js → Multisig-QplgySFt.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-fnxqXM_3.js → NLProgramming-BWkMyuAy.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-qUZPIQXT.js → Notes-BI_pSEM0.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-x9Xrixqu.js → NotificationSettings-DiuFo6Xe.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BtMtQUt7.js → OrderTableRenderer-DZzQhujZ.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-C946Hzna.js → Organization-DqEdqWB0.js} +2 -2
- package/src/assets/web-panel/assets/{Overflow-BYf8KIts.js → Overflow-CO7_2YLN.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Cbqf5dnv.js → P2P-BN5RiNst.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-CapfG4bl.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-CZBw45EW.js → Permissions-B24c5fWW.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BKwUAt43.js → PersonalDataHub-D7Mb3_vh.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-DmFD2QW4.js → Pipeline-BsfxlbOQ.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-KpuwWvt5.js → Privacy-Bq7c7IYy.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Bt8UheX6.js → ProjectInit-Clse2DPl.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-2ZeAn9CP.js → ProjectSettings-CHAEdjri.js} +2 -2
- package/src/assets/web-panel/assets/Projects-C1UHvBEK.js +1 -0
- package/src/assets/web-panel/assets/{Providers-DcEAnw6L.js → Providers-DQyH3PXU.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-qF7liYG9.js → QrScannerModal-t2Z-N49o.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-qiESlVBJ.js → QuickAsk-BacR7PlI.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Bk-cQyi9.js → Recommend-D-NAy0CQ.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-CwrekErS.js → RemoteSession-CjI3GeVQ.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-Bmw_UQtW.js → Reputation-HoQ3i2oW.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CPdqZIUX.js → Row-CY2jczWa.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-D_W-xxvS.js → RssFeed-Bd3o20IY.js} +2 -2
- package/src/assets/web-panel/assets/{Search-Hu0oDFj_.js → Search-C88KjgTv.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DeRxUwmq.js → Security-yfmfvujK.js} +3 -3
- package/src/assets/web-panel/assets/{Services-CsNmHFkf.js → Services-DLPBWoxT.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-gv_Vz0tN.js → Skeleton-DzDjvVQi.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Dgg-_rCB.js → Skills-DqfrJIyP.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Bpu-bsEJ.js → Sla-BXhsGzkm.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CrhleHuF.js → SpeechSettings-jxSl2JDo.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-JHjUN6I9.js → SyncSettings-BX2xKtI3.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DKRWKkl9.js → Tasks-P9MmRYt4.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-leiWntLq.js → Templates-CTpj9f62.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant--1bYulvn.js → Tenant-nnQuhdPg.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-C0y6FvSS.js → Terminal-cJ0vbuTe.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-CQK4PVv4.js → TimelineRenderer-DN08D0SD.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DbIvF-DV.js → Tokens-C8BWWBUD.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CkXJ2vuq.js → Trigger-DhD-LUoe.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-B02WXJPw.js → Trust-D0nFyc_Z.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-VPMkfzmw.js → UkeySign-B59G57LP.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C5ezUnah.js → VideoEditing-BpYACxVC.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CYfvYRrY.js → Wallet-DlZ3rKGD.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DtKl-kpr.js → WebAuthn-De4dNyig.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-DACITF-u.js → WorkflowEditor-C2Tewnhp.js} +1 -1
- package/src/assets/web-panel/assets/{chat-qnygfnLi.js → chat-CDBn4JLE.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D4mISLBD.js → colors-BNawl0d_.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BBPfxYGL.js → compact-item-n65WDhze.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-Byx4ndHp.js → createContext-DAKgOdIy.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-sBSSW127.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CGjLkkn3.js → hasIn-DhxFG46W.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWhI8G14.js → index--76HBS1k.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dmfe0L2Z.js → index-0Y-ncsVy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BzeBBAl5.js → index-5oJjovnA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFMWjuav.js → index-BAogaHa9.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8UpadHC.js → index-BBFjMjmp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BmKYaaGP.js → index-BDTrf8WH.js} +1 -1
- package/src/assets/web-panel/assets/index-BIJTDSLY.js +1 -0
- package/src/assets/web-panel/assets/{index-CD5Btq6p.js → index-BQFAuU1c.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVUJjQAT.js → index-BRyzRluv.js} +1 -1
- package/src/assets/web-panel/assets/{index-O09jXbir.js → index-BZI8xwwt.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMj8qmpX.js → index-BfXdTvku.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_g9mA1N.js → index-BudfMkBy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BN7_TSgU.js → index-By-zGgUp.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ne8UGllV.js → index-ByDs4cW4.js} +3 -3
- package/src/assets/web-panel/assets/{index-CZjNamSU.js → index-BzONk4rW.js} +1 -1
- package/src/assets/web-panel/assets/{index-xzRKTy0R.js → index-CE6OcLof.js} +1 -1
- package/src/assets/web-panel/assets/{index-J5JkStvY.js → index-CSOgoyqx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BklGH3YI.js → index-CW_OUdP8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmHE-lY_.js → index-CZJrAg98.js} +1 -1
- package/src/assets/web-panel/assets/index-CrBauOkp.js +1 -0
- package/src/assets/web-panel/assets/{index-lKJWAmd4.js → index-Cv7LqHwv.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dzni_5Qw.js → index-D34AXxN9.js} +1 -1
- package/src/assets/web-panel/assets/{index-c_tBkIlU.js → index-D6sWUgN6.js} +1 -1
- package/src/assets/web-panel/assets/{index-Y7el_3WS.js → index-DCujBaFg.js} +1 -1
- package/src/assets/web-panel/assets/{index-BxQF1wCU.js → index-DFkamspD.js} +1 -1
- package/src/assets/web-panel/assets/{index-CsVuQsY1.js → index-DLFRz0_7.js} +1 -1
- package/src/assets/web-panel/assets/{index-ByA1NyFP.js → index-DV6iHrUO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DboTeuPF.js → index-D_-6qQf0.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9tcHs46.js → index-DeTlqus4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DH6iC5b2.js → index-DkW0HGr-.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9jH-h4X.js → index-DleKcclQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cpg3AWRy.js → index-Ds290C06.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_fHPZ8E.js → index-KT94nMha.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3abGsSW.js → index-KZkt4e9N.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZXhKAk9.js → index-L1QnA0gW.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfgpKd64.js → index-PlOBwfR1.js} +1 -1
- package/src/assets/web-panel/assets/{index-CoA8WsVr.js → index-gG1WJBpa.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNe2lCk6.js → index-hA9VUXGr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CydHMjwc.js → index-pzEYIGNA.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-XuhfEIhB.js → initDefaultProps-B3bCivrt.js} +1 -1
- package/src/assets/web-panel/assets/{motion-Cbxh6AxO.js → motion-CF5pGsxz.js} +1 -1
- package/src/assets/web-panel/assets/{move-C7IEnFly.js → move-CaOFtFLU.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-lLADx4LL.js → mtc-parser-Z4-50Y1c.js} +1 -1
- package/src/assets/web-panel/assets/{omit-mIbic_k-.js → omit-AK4WqVTT.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-_xIYEqu3.js → pickAttrs-Dbye0px4.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-ClB-E0ny.js → placementArrow-DCmr-Dks.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-D36Bg2ut.js → responsiveObserve-CJ3Zm_-H.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CUuO08Bl.js → slide-BuSk5-ue.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BKahwLbv.js → statusUtils-8u_lKSFJ.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-2pT-T8vy.js → styleChecker-sy6_m42F.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DyH5g7Rg.js → useFlexGapSupport-Di5EfYGo.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CTOauB3X.js → useFs-BTfX_Ri1.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-B02JYIMe.js → usePersonalDataHub-kqurO26X.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Do22wQrc.js → vnode-DRkH4mPV.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BfnL7rit.js → zoom-ON_-UuD_.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +5 -0
- package/src/commands/config.js +19 -10
- package/src/commands/context.js +31 -11
- package/src/commands/eval.js +39 -4
- package/src/commands/evolution-deployment.js +70 -0
- package/src/data/changelog.json +91 -0
- package/src/gateways/ws/evolution-deployment-topic-handlers.js +20 -0
- package/src/harness/prompt-compressor.js +12 -4
- package/src/lib/diagnostic-excerpt.js +51 -0
- package/src/lib/diagnostic-workflow.js +10 -0
- package/src/lib/eval/evidence.js +19 -10
- package/src/lib/eval/outcomes.js +373 -0
- package/src/lib/eval/runner.js +6 -0
- package/src/lib/evolution/evolution-deployment-config.js +16 -1
- package/src/lib/evolution/evolution-deployment-profile.js +102 -58
- package/src/lib/evolution/evolution-test-deployment.js +386 -0
- package/src/lib/git-tool-input.js +37 -0
- package/src/lib/llm-config-defaults.js +32 -9
- package/src/lib/model-context-window.js +3 -2
- package/src/lib/read-file-loop-guard.js +54 -0
- package/src/lib/remote-read-loop-guard.js +12 -14
- package/src/lib/runtime-usage-ledger.js +5 -0
- package/src/lib/session-message-fabric.js +74 -37
- package/src/lib/shell-output.js +30 -0
- package/src/lib/task-progress-tracker.js +88 -0
- package/src/repl/agent-repl.js +19 -4
- package/src/runtime/agent-core.js +108 -22
- package/src/runtime/headless-runner.js +4 -0
- package/src/runtime/headless-stream.js +34 -1
- package/src/assets/web-panel/assets/EvolutionSettings-bMvgBk6r.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-QWv7UJLq.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-rmxp0cuF.js +0 -7
- package/src/assets/web-panel/assets/Projects-zBuet8Zs.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DBy6gsuI.js +0 -1
- package/src/assets/web-panel/assets/index-BfEDXk_E.js +0 -1
- package/src/assets/web-panel/assets/index-CrxUwNM8.js +0 -1
|
@@ -55,6 +55,7 @@ export async function reconcileConfigLlmProvider(cfgLlm = {}) {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
import { resolveApiKeyFromHelper } from "./api-key-helper.js";
|
|
58
|
+
import { modelForeignToProvider } from "./runnable-provider.js";
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
61
|
* Key backfill order: config llm.apiKey (plaintext, legacy) first, then
|
|
@@ -111,12 +112,27 @@ function optionalModel(value) {
|
|
|
111
112
|
return model || null;
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Claude settings and ANTHROPIC_MODEL carry a model name but no provider.
|
|
117
|
+
* Do not pair an unmistakably provider-specific inherited model with another
|
|
118
|
+
* configured provider. Explicit CLI/--settings choices may opt out because
|
|
119
|
+
* they provide the user's intent for this invocation.
|
|
120
|
+
*/
|
|
121
|
+
export function inheritedModelCompatible(provider, model) {
|
|
122
|
+
const candidate = optionalModel(model);
|
|
123
|
+
return (
|
|
124
|
+
!candidate || !provider || !modelForeignToProvider(provider, candidate)
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
114
128
|
/**
|
|
115
129
|
* Resolve the model precedence used by `cc agent` without allowing a default
|
|
116
130
|
* from one source to silently outrank an explicit choice from another:
|
|
117
131
|
*
|
|
118
|
-
* CLI --model > ANTHROPIC_MODEL
|
|
119
|
-
* > ANTHROPIC_DEFAULT_MODEL (new sessions only)
|
|
132
|
+
* CLI --model > provider-compatible ANTHROPIC_MODEL/settings.model >
|
|
133
|
+
* config/organization model > ANTHROPIC_DEFAULT_MODEL (new sessions only)
|
|
134
|
+
* > runtime provider default. An explicit --settings file or managed setting
|
|
135
|
+
* may authorize a foreign-looking alias for a custom provider endpoint.
|
|
120
136
|
*
|
|
121
137
|
* Environment values are supplied by the caller from the process startup
|
|
122
138
|
* environment, before settings-file `env` entries are merged. That prevents a
|
|
@@ -128,18 +144,25 @@ export function applyAgentModelDefaults(options = {}, cfgLlm = {}, opts = {}) {
|
|
|
128
144
|
const settingsModel = optionalModel(opts.settingsModel);
|
|
129
145
|
const defaultModel = optionalModel(opts.anthropicDefaultModel);
|
|
130
146
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
let inheritedModel = environmentModel || settingsModel;
|
|
148
|
+
const targetProvider = options.provider || cfgLlm.provider;
|
|
149
|
+
if (
|
|
150
|
+
inheritedModel &&
|
|
151
|
+
opts.allowForeignInheritedModel !== true &&
|
|
152
|
+
!inheritedModelCompatible(targetProvider, inheritedModel)
|
|
153
|
+
) {
|
|
154
|
+
if (options.model === inheritedModel) delete options.model;
|
|
155
|
+
inheritedModel = null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!explicitModel && inheritedModel) {
|
|
159
|
+
options.model = inheritedModel;
|
|
137
160
|
}
|
|
138
161
|
|
|
139
162
|
applyConfigLlmDefaults(options, cfgLlm, {
|
|
140
163
|
// Reuse the existing config/provider wiring, but do not let its configured
|
|
141
164
|
// model overwrite one selected by a higher-priority source above.
|
|
142
|
-
explicitModel: explicitModel ||
|
|
165
|
+
explicitModel: explicitModel || inheritedModel,
|
|
143
166
|
});
|
|
144
167
|
|
|
145
168
|
if (!options.model && opts.isNewSession !== false && defaultModel) {
|
|
@@ -2,6 +2,7 @@ import { resolveModelCapabilityProfile } from "./model-capabilities.js";
|
|
|
2
2
|
|
|
3
3
|
export { CONTEXT_WINDOWS } from "./model-context-catalog.js";
|
|
4
4
|
|
|
5
|
-
export function getContextWindow(model, provider) {
|
|
6
|
-
return resolveModelCapabilityProfile({ model, provider })
|
|
5
|
+
export function getContextWindow(model, provider, options = {}) {
|
|
6
|
+
return resolveModelCapabilityProfile({ ...options, model, provider })
|
|
7
|
+
.contextWindowTokens;
|
|
7
8
|
}
|
|
@@ -30,6 +30,46 @@ export class ReadFileLoopGuard {
|
|
|
30
30
|
this.recoveryOfferedAt = 0;
|
|
31
31
|
this.batch = null;
|
|
32
32
|
this.largeOutputs = new Set();
|
|
33
|
+
this.editRecoveryReads = new Map();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
recordEditRecovery(result) {
|
|
37
|
+
if (result?.success === true && result.path) {
|
|
38
|
+
this.editRecoveryReads.delete(keyFor(result.path, { hashed: true }));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const request = result?.recoveryRead;
|
|
42
|
+
if (
|
|
43
|
+
!request ||
|
|
44
|
+
!["hash_mismatch", "content_mismatch"].includes(result.error)
|
|
45
|
+
)
|
|
46
|
+
return;
|
|
47
|
+
const key = keyFor(request.path, { hashed: true });
|
|
48
|
+
// One refresh per file until an edit succeeds. Repeating the failed edit
|
|
49
|
+
// must not mint an unlimited read allowance.
|
|
50
|
+
if (
|
|
51
|
+
!this.editRecoveryReads.has(key) &&
|
|
52
|
+
this.editRecoveryReads.size < MAX_FILES
|
|
53
|
+
) {
|
|
54
|
+
this.editRecoveryReads.set(key, { ...request, used: false });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get hasEditRecoveryReads() {
|
|
59
|
+
return [...this.editRecoveryReads.values()].some((entry) => !entry.used);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
canRecoverEdit(filePath, args = {}) {
|
|
63
|
+
const entry = this.editRecoveryReads.get(keyFor(filePath, args));
|
|
64
|
+
return !!(
|
|
65
|
+
entry &&
|
|
66
|
+
!entry.used &&
|
|
67
|
+
args.hashed === true &&
|
|
68
|
+
args.raw !== true &&
|
|
69
|
+
args.column == null &&
|
|
70
|
+
args.offset === entry.offset &&
|
|
71
|
+
args.limit === entry.limit
|
|
72
|
+
);
|
|
33
73
|
}
|
|
34
74
|
|
|
35
75
|
startBatch() {
|
|
@@ -51,6 +91,16 @@ export class ReadFileLoopGuard {
|
|
|
51
91
|
}
|
|
52
92
|
let page = readPage(args);
|
|
53
93
|
if (page.error || !page.readSpan) return page;
|
|
94
|
+
if (this.canRecoverEdit(filePath, args)) {
|
|
95
|
+
this.editRecoveryReads.get(key).used = true;
|
|
96
|
+
// The authorized read implementation has already refreshed stat/content.
|
|
97
|
+
// Return the requested anchors even if ordinary coverage is exhausted.
|
|
98
|
+
return {
|
|
99
|
+
...page,
|
|
100
|
+
readRecovery: { action: "edit-anchor-refresh" },
|
|
101
|
+
readProgress: { newContent: false },
|
|
102
|
+
};
|
|
103
|
+
}
|
|
54
104
|
const span = page.readSpan;
|
|
55
105
|
const covered = entry.spans.some(
|
|
56
106
|
([start, end]) => start <= span.start && end >= span.end,
|
|
@@ -160,6 +210,8 @@ export class ReadFileLoopGuard {
|
|
|
160
210
|
)
|
|
161
211
|
return;
|
|
162
212
|
if (tool === "read_file") {
|
|
213
|
+
if (result?.readRecovery?.action === "edit-anchor-refresh")
|
|
214
|
+
this.batch.advanced = true;
|
|
163
215
|
if (result?.readProgress?.newContent === true) this.batch.advanced = true;
|
|
164
216
|
if (result?.readProgress?.newContent === false) this.batch.duplicates++;
|
|
165
217
|
} else if (
|
|
@@ -207,12 +259,14 @@ export class ReadFileLoopGuard {
|
|
|
207
259
|
|
|
208
260
|
get hasRecoveryReads() {
|
|
209
261
|
return (
|
|
262
|
+
this.hasEditRecoveryReads ||
|
|
210
263
|
this.hasUnreadPages ||
|
|
211
264
|
[...this.progress.values()].some((entry) => entry.rereads.size < 3)
|
|
212
265
|
);
|
|
213
266
|
}
|
|
214
267
|
|
|
215
268
|
canContinue(filePath, args = {}) {
|
|
269
|
+
if (this.canRecoverEdit(filePath, args)) return true;
|
|
216
270
|
const entry = this.progress.get(keyFor(filePath, args));
|
|
217
271
|
return (
|
|
218
272
|
entry?.summary?.reachedEnd === false ||
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { diagnosticExcerpt } from "./diagnostic-excerpt.js";
|
|
3
|
+
import { DIAGNOSTIC_WORKFLOW_GUIDANCE } from "./diagnostic-workflow.js";
|
|
2
4
|
|
|
3
5
|
const MAX_TARGETS = 32;
|
|
4
6
|
const RECOVERY_AFTER = 3;
|
|
@@ -196,19 +198,7 @@ function failedResult(result) {
|
|
|
196
198
|
}
|
|
197
199
|
|
|
198
200
|
function excerpt(value) {
|
|
199
|
-
|
|
200
|
-
if (text.length <= 1600) return text;
|
|
201
|
-
// Retain failure lines from full CI logs as well as the opening context.
|
|
202
|
-
const failures = text
|
|
203
|
-
.split("\n")
|
|
204
|
-
.filter((line) => /FAIL|Error:|AssertionError|error TS|×|✕/.test(line))
|
|
205
|
-
.slice(0, 12)
|
|
206
|
-
.join("\n");
|
|
207
|
-
return (
|
|
208
|
-
text.slice(0, 400) +
|
|
209
|
-
"\n[excerpt]\n" +
|
|
210
|
-
(failures || text.slice(-1100)).slice(0, 1100)
|
|
211
|
-
);
|
|
201
|
+
return diagnosticExcerpt(value);
|
|
212
202
|
}
|
|
213
203
|
|
|
214
204
|
/** Per agentLoop, independent of history compaction and other agents' evidence. */
|
|
@@ -290,13 +280,19 @@ export class RemoteReadLoopGuard {
|
|
|
290
280
|
this.activeKey = target.key;
|
|
291
281
|
const previous = this.targets.get(target.key);
|
|
292
282
|
const digests = previous?.digests || new Set();
|
|
293
|
-
const
|
|
283
|
+
const primaryContent =
|
|
294
284
|
result?.output ??
|
|
295
285
|
result?.stdout ??
|
|
296
286
|
result?.content ??
|
|
297
287
|
result?.matches ??
|
|
298
288
|
result?.body ??
|
|
299
289
|
"";
|
|
290
|
+
const content =
|
|
291
|
+
result?.stdout_diagnostics || result?.stderr_diagnostics
|
|
292
|
+
? [result.stdout_diagnostics, result.stderr_diagnostics, primaryContent]
|
|
293
|
+
.filter(Boolean)
|
|
294
|
+
.join("\n")
|
|
295
|
+
: primaryContent;
|
|
300
296
|
const digest = createHash("sha256")
|
|
301
297
|
.update(typeof content === "string" ? content : JSON.stringify(content))
|
|
302
298
|
.digest("hex");
|
|
@@ -453,6 +449,8 @@ export class RemoteReadLoopGuard {
|
|
|
453
449
|
"An aggregate or incomplete-matrix gate can be a downstream symptom; inspect the dependency jobs' conclusions before assuming that the gate itself is wrong. " +
|
|
454
450
|
"When a job is cancelled or logs are unavailable, record that fact and the command error; do not cycle through the same web page and log downloads. " +
|
|
455
451
|
"Use one focused run/job metadata query to resolve the missing status or cancellation reason, then inspect the relevant workflow and make the justified, authorized fix with validation. " +
|
|
452
|
+
DIAGNOSTIC_WORKFLOW_GUIDANCE +
|
|
453
|
+
" " +
|
|
456
454
|
"If available evidence cannot establish a fix, report the specific missing evidence and what was verified. Do not disable a release or safety gate just to make CI pass. " +
|
|
457
455
|
"For a research/review request, synthesize the findings without unsolicited edits; for monitoring, use status queries instead of repeated logs."
|
|
458
456
|
);
|
|
@@ -162,6 +162,11 @@ export function projectRuntimeTokenUsage(event = {}) {
|
|
|
162
162
|
...(projectedOperationId ? { operationId: projectedOperationId } : {}),
|
|
163
163
|
...(event.source ? { source: source(event.source) } : {}),
|
|
164
164
|
...(attribution ? { attribution } : {}),
|
|
165
|
+
...(Number.isSafeInteger(event.contextWindow) &&
|
|
166
|
+
event.contextWindow >= 1024 &&
|
|
167
|
+
event.contextWindow <= 16777216
|
|
168
|
+
? { contextWindow: event.contextWindow }
|
|
169
|
+
: {}),
|
|
165
170
|
};
|
|
166
171
|
}
|
|
167
172
|
|
|
@@ -31,6 +31,31 @@ export const SESSION_MESSAGE_POLICIES = Object.freeze([
|
|
|
31
31
|
"refuse",
|
|
32
32
|
]);
|
|
33
33
|
|
|
34
|
+
// Windows can briefly retain a handle on a just-written state file while an
|
|
35
|
+
// antivirus scanner, indexer, or another process observes it. Retrying the
|
|
36
|
+
// atomic write is safe while this process still owns the state lock: no
|
|
37
|
+
// business mutation is re-run, and no error after the final rename is retried.
|
|
38
|
+
// Keep this deliberately short so genuine filesystem failures remain
|
|
39
|
+
// fail-closed.
|
|
40
|
+
const TRANSIENT_ATOMIC_WRITE_ERROR_CODES = new Set([
|
|
41
|
+
"EACCES",
|
|
42
|
+
"EBUSY",
|
|
43
|
+
"EPERM",
|
|
44
|
+
]);
|
|
45
|
+
const MAX_ATOMIC_WRITE_ATTEMPTS = 5;
|
|
46
|
+
|
|
47
|
+
function waitForAtomicWriteRetry(attempt) {
|
|
48
|
+
const delayMs = Math.min(100, 5 * 2 ** attempt);
|
|
49
|
+
try {
|
|
50
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, delayMs);
|
|
51
|
+
} catch {
|
|
52
|
+
const deadline = Date.now() + delayMs;
|
|
53
|
+
while (Date.now() < deadline) {
|
|
54
|
+
// SharedArrayBuffer is unavailable only in constrained runtimes.
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
34
59
|
export const SESSION_MESSAGE_RECEIPT_STATUSES = Object.freeze([
|
|
35
60
|
"delivered",
|
|
36
61
|
"held",
|
|
@@ -756,50 +781,62 @@ export class SessionMessageFabric {
|
|
|
756
781
|
|
|
757
782
|
_writeState(state) {
|
|
758
783
|
const directory = path.dirname(this.statePath);
|
|
759
|
-
const
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
descriptor = fs.openSync(temporary, "wx", 0o600);
|
|
766
|
-
fs.writeFileSync(
|
|
767
|
-
descriptor,
|
|
768
|
-
`${JSON.stringify(state, null, 2)}\n`,
|
|
769
|
-
"utf8",
|
|
784
|
+
const serialized = `${JSON.stringify(state, null, 2)}\n`;
|
|
785
|
+
let lastCause;
|
|
786
|
+
for (let attempt = 0; attempt < MAX_ATOMIC_WRITE_ATTEMPTS; attempt += 1) {
|
|
787
|
+
const temporary = path.join(
|
|
788
|
+
directory,
|
|
789
|
+
`.${path.basename(this.statePath)}.${process.pid}.${this._createId()}.tmp`,
|
|
770
790
|
);
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
791
|
+
let descriptor = null;
|
|
792
|
+
let renamed = false;
|
|
793
|
+
try {
|
|
794
|
+
descriptor = fs.openSync(temporary, "wx", 0o600);
|
|
795
|
+
fs.writeFileSync(descriptor, serialized, "utf8");
|
|
796
|
+
fs.fsyncSync(descriptor);
|
|
797
|
+
fs.closeSync(descriptor);
|
|
798
|
+
descriptor = null;
|
|
799
|
+
fs.renameSync(temporary, this.statePath);
|
|
800
|
+
renamed = true;
|
|
801
|
+
if (process.platform !== "win32") {
|
|
802
|
+
const directoryDescriptor = fs.openSync(directory, "r");
|
|
803
|
+
try {
|
|
804
|
+
fs.fsyncSync(directoryDescriptor);
|
|
805
|
+
} finally {
|
|
806
|
+
fs.closeSync(directoryDescriptor);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
return;
|
|
810
|
+
} catch (cause) {
|
|
811
|
+
lastCause = cause;
|
|
812
|
+
if (descriptor != null) {
|
|
813
|
+
try {
|
|
814
|
+
fs.closeSync(descriptor);
|
|
815
|
+
} catch {
|
|
816
|
+
// Preserve the original write failure.
|
|
817
|
+
}
|
|
781
818
|
}
|
|
782
|
-
}
|
|
783
|
-
} catch (cause) {
|
|
784
|
-
if (descriptor != null) {
|
|
785
819
|
try {
|
|
786
|
-
fs.
|
|
820
|
+
fs.unlinkSync(temporary);
|
|
787
821
|
} catch {
|
|
788
|
-
//
|
|
822
|
+
// The rename may already have committed, or no temporary was created.
|
|
789
823
|
}
|
|
824
|
+
if (
|
|
825
|
+
renamed ||
|
|
826
|
+
!TRANSIENT_ATOMIC_WRITE_ERROR_CODES.has(cause?.code) ||
|
|
827
|
+
attempt + 1 >= MAX_ATOMIC_WRITE_ATTEMPTS
|
|
828
|
+
) {
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
waitForAtomicWriteRetry(attempt);
|
|
790
832
|
}
|
|
791
|
-
try {
|
|
792
|
-
fs.unlinkSync(temporary);
|
|
793
|
-
} catch {
|
|
794
|
-
// The rename may already have committed, or no temporary was created.
|
|
795
|
-
}
|
|
796
|
-
throw fabricError(
|
|
797
|
-
SESSION_MESSAGE_FABRIC_ERROR_CODES.STATE_UNAVAILABLE,
|
|
798
|
-
"Could not atomically persist session message state",
|
|
799
|
-
{},
|
|
800
|
-
cause,
|
|
801
|
-
);
|
|
802
833
|
}
|
|
834
|
+
throw fabricError(
|
|
835
|
+
SESSION_MESSAGE_FABRIC_ERROR_CODES.STATE_UNAVAILABLE,
|
|
836
|
+
"Could not atomically persist session message state",
|
|
837
|
+
{},
|
|
838
|
+
lastCause,
|
|
839
|
+
);
|
|
803
840
|
}
|
|
804
841
|
|
|
805
842
|
_transaction(mutator, { expectedRevision = null } = {}) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { diagnosticExcerpt } from "./diagnostic-excerpt.js";
|
|
2
|
+
|
|
3
|
+
/** Page size includes JSON escaping so later serialization does not lose data. */
|
|
4
|
+
export function shellOutputPage(value, budget) {
|
|
5
|
+
const text = String(value ?? "");
|
|
6
|
+
let low = 0;
|
|
7
|
+
let high = Math.min(text.length, budget);
|
|
8
|
+
while (low < high) {
|
|
9
|
+
const mid = Math.ceil((low + high) / 2);
|
|
10
|
+
if (JSON.stringify(text.slice(0, mid)).length <= budget) low = mid;
|
|
11
|
+
else high = mid - 1;
|
|
12
|
+
}
|
|
13
|
+
if (low > 0 && /[\uD800-\uDBFF]/.test(text[low - 1])) low--;
|
|
14
|
+
return { text: text.slice(0, low), remaining: text.length - low };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Foreground commands cannot be repolled; expose omitted diagnostic context. */
|
|
18
|
+
export function shellOutputPreview(value, field, budget) {
|
|
19
|
+
const text = String(value ?? "");
|
|
20
|
+
const page = shellOutputPage(text, budget);
|
|
21
|
+
if (!page.remaining) return { [field]: page.text };
|
|
22
|
+
return {
|
|
23
|
+
[`${field}_truncated`]: true,
|
|
24
|
+
[`${field}_total_chars`]: text.length,
|
|
25
|
+
[`${field}_diagnostics`]: diagnosticExcerpt(text),
|
|
26
|
+
[field]: page.text,
|
|
27
|
+
output_hint:
|
|
28
|
+
"Output is incomplete. Diagnostic excerpts are source evidence, not a root-cause verdict. For long reproductions use run_in_background and drain check_shell with task_id; preserve a full CI log once before filtering it.",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { remoteReadTarget } from "./remote-read-loop-guard.js";
|
|
3
|
+
import { diagnosticExcerpt } from "./diagnostic-excerpt.js";
|
|
4
|
+
import { DIAGNOSTIC_WORKFLOW_GUIDANCE } from "./diagnostic-workflow.js";
|
|
3
5
|
|
|
4
6
|
// Discovery and bookkeeping are useful, but are not evidence that the task
|
|
5
7
|
// advanced. In particular, dispatching a child must not buy a fresh budget.
|
|
@@ -82,6 +84,7 @@ export class TaskProgressTracker {
|
|
|
82
84
|
this.lastActions = [];
|
|
83
85
|
this.remoteInspections = [];
|
|
84
86
|
this.localFindings = [];
|
|
87
|
+
this.diagnostics = [];
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
retainChildResult(id, result, owner = "root") {
|
|
@@ -121,6 +124,82 @@ export class TaskProgressTracker {
|
|
|
121
124
|
typeof args.old_string === "string" &&
|
|
122
125
|
args.old_string === args.new_string);
|
|
123
126
|
|
|
127
|
+
// Preserve observed reproduction results through compaction, including
|
|
128
|
+
// failed runs and completed background tasks. They do not establish that
|
|
129
|
+
// the original CI failure was reproduced or fixed.
|
|
130
|
+
if (
|
|
131
|
+
["run_shell", "run_code", "check_shell"].includes(tool) &&
|
|
132
|
+
result?.code !== "CC_TOOL_RECOVERY_PAUSED" &&
|
|
133
|
+
!(tool === "check_shell" && !args.task_id)
|
|
134
|
+
) {
|
|
135
|
+
const taskId = result?.task_id || args.task_id || null;
|
|
136
|
+
const previous =
|
|
137
|
+
taskId &&
|
|
138
|
+
this.diagnostics.find(
|
|
139
|
+
(entry) => entry.owner === owner && entry.taskId === taskId,
|
|
140
|
+
);
|
|
141
|
+
const output = [
|
|
142
|
+
result?.stdout_diagnostics,
|
|
143
|
+
result?.stderr_diagnostics,
|
|
144
|
+
result?.error,
|
|
145
|
+
result?.output,
|
|
146
|
+
result?.stdout,
|
|
147
|
+
result?.stderr,
|
|
148
|
+
]
|
|
149
|
+
.filter(Boolean)
|
|
150
|
+
.join("\n");
|
|
151
|
+
if (output || taskId || Number.isInteger(result?.exitCode)) {
|
|
152
|
+
const command = args.command || result?.command || args.code || "";
|
|
153
|
+
const remoteTarget = remoteReadTarget(tool, args);
|
|
154
|
+
const entry = {
|
|
155
|
+
owner,
|
|
156
|
+
tool,
|
|
157
|
+
taskId,
|
|
158
|
+
observedAt: this.now(),
|
|
159
|
+
remoteTarget: remoteTarget?.key || previous?.remoteTarget || null,
|
|
160
|
+
source:
|
|
161
|
+
previous?.source ||
|
|
162
|
+
(remoteTarget?.github || isRemoteInspectionCommand(command)
|
|
163
|
+
? "remote-inspection"
|
|
164
|
+
: "local-execution"),
|
|
165
|
+
invocation: boundedText(command || previous?.invocation, 1000),
|
|
166
|
+
invocationTruncated: command
|
|
167
|
+
? command.length > 1000
|
|
168
|
+
: previous?.invocationTruncated || false,
|
|
169
|
+
exitCode: result?.exitCode ?? result?.exit_code ?? null,
|
|
170
|
+
status:
|
|
171
|
+
result?.status ||
|
|
172
|
+
(result?.background ? "running" : failed ? "failed" : "completed"),
|
|
173
|
+
outputLost:
|
|
174
|
+
previous?.outputLost === true ||
|
|
175
|
+
!!result?.stdout_dropped_bytes ||
|
|
176
|
+
!!result?.stderr_dropped_bytes,
|
|
177
|
+
outputIncomplete:
|
|
178
|
+
previous?.outputLost === true ||
|
|
179
|
+
result?.has_more_output === true ||
|
|
180
|
+
result?.stdout_truncated === true ||
|
|
181
|
+
result?.stderr_truncated === true ||
|
|
182
|
+
result?.truncated === true ||
|
|
183
|
+
!!result?.stdout_dropped_bytes ||
|
|
184
|
+
!!result?.stderr_dropped_bytes,
|
|
185
|
+
output: diagnosticExcerpt(
|
|
186
|
+
[previous?.output, output].filter(Boolean).join("\n"),
|
|
187
|
+
1200,
|
|
188
|
+
),
|
|
189
|
+
};
|
|
190
|
+
const owned = [
|
|
191
|
+
...this.diagnostics.filter(
|
|
192
|
+
(item) => item.owner === owner && item !== previous,
|
|
193
|
+
),
|
|
194
|
+
entry,
|
|
195
|
+
].slice(-4);
|
|
196
|
+
this.diagnostics = [
|
|
197
|
+
...this.diagnostics.filter((item) => item.owner !== owner),
|
|
198
|
+
...owned,
|
|
199
|
+
].slice(-MAX_CHECKPOINT_OWNERS * 4);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
124
203
|
if (!failed && (tool === "search_files" || tool === "read_file")) {
|
|
125
204
|
const evidence = result.content ?? result.matches ?? result.output;
|
|
126
205
|
const excerpt = boundedText(
|
|
@@ -252,6 +331,8 @@ export class TaskProgressTracker {
|
|
|
252
331
|
message +
|
|
253
332
|
" For an implementation task, make the smallest justified, authorized change and validate it. " +
|
|
254
333
|
"For a bug fix, state the observed failure, your leading root-cause hypothesis and the smallest test that can disprove it. Run that focused reproduction or diagnostic next; use its actual output to choose the next step. Do not keep reading adjacent files without naming the specific missing fact. A timeout alone does not establish that increasing the timeout is the fix. " +
|
|
334
|
+
DIAGNOSTIC_WORKFLOW_GUIDANCE +
|
|
335
|
+
" " +
|
|
255
336
|
"For research/review, synthesize evidence-backed findings; do not write files merely to clear this warning. " +
|
|
256
337
|
"If evidence is insufficient, name the exact missing fact and use a focused search or bounded computation. " +
|
|
257
338
|
"Do not restart general investigation, rewrite the plan, or delegate the same research. " +
|
|
@@ -268,11 +349,15 @@ export class TaskProgressTracker {
|
|
|
268
349
|
!this.childFindings.size &&
|
|
269
350
|
!this.lastActions.length &&
|
|
270
351
|
!this.remoteInspections.length &&
|
|
352
|
+
!this.diagnostics.length &&
|
|
271
353
|
!this.localFindings.length
|
|
272
354
|
)
|
|
273
355
|
return null;
|
|
274
356
|
const checkpoint = {
|
|
275
357
|
bounded: true,
|
|
358
|
+
recentDiagnostics: this.diagnostics
|
|
359
|
+
.filter((entry) => entry.owner === owner)
|
|
360
|
+
.map(({ owner: _owner, ...entry }) => entry),
|
|
276
361
|
recentLocalFindings: this.localFindings
|
|
277
362
|
.filter((entry) => entry.owner === owner)
|
|
278
363
|
.map(({ owner: _owner, ...entry }) => entry),
|
|
@@ -300,6 +385,7 @@ export class TaskProgressTracker {
|
|
|
300
385
|
!checkpoint.recentLocalFindings.length &&
|
|
301
386
|
!checkpoint.recentToolOutcomes.length &&
|
|
302
387
|
!checkpoint.recentRemoteInspections.length &&
|
|
388
|
+
!checkpoint.recentDiagnostics.length &&
|
|
303
389
|
!checkpoint.reportedPlans.length &&
|
|
304
390
|
!checkpoint.childFindings.length
|
|
305
391
|
)
|
|
@@ -312,6 +398,8 @@ export class TaskProgressTracker {
|
|
|
312
398
|
checkpoint.recentLocalFindings.shift();
|
|
313
399
|
else if (checkpoint.recentRemoteInspections.length)
|
|
314
400
|
checkpoint.recentRemoteInspections.shift();
|
|
401
|
+
else if (checkpoint.recentDiagnostics.length)
|
|
402
|
+
checkpoint.recentDiagnostics.shift();
|
|
315
403
|
else if (checkpoint.recentToolOutcomes.length)
|
|
316
404
|
checkpoint.recentToolOutcomes.shift();
|
|
317
405
|
else checkpoint.reportedPlans.pop();
|
package/src/repl/agent-repl.js
CHANGED
|
@@ -5579,6 +5579,7 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
5579
5579
|
let _customStatus = false; // true when a settings.json command is configured
|
|
5580
5580
|
let _curModel = model; // tracks the per-turn active model for the readout
|
|
5581
5581
|
let _ctxUsedTokens = 0;
|
|
5582
|
+
let _ctxRequestWindow = null;
|
|
5582
5583
|
let _turnCount = 0;
|
|
5583
5584
|
const _costStore = newCostStore(); // running token spend for `/cost`
|
|
5584
5585
|
let _renderStatus = null;
|
|
@@ -5598,7 +5599,8 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
5598
5599
|
provider,
|
|
5599
5600
|
cwd: process.cwd(),
|
|
5600
5601
|
usedTokens: _ctxUsedTokens,
|
|
5601
|
-
contextWindow:
|
|
5602
|
+
contextWindow:
|
|
5603
|
+
_ctxRequestWindow ?? getContextWindow(_curModel, provider, options),
|
|
5602
5604
|
turn: _turnCount,
|
|
5603
5605
|
});
|
|
5604
5606
|
// Custom command wins; otherwise the built-in context-usage render.
|
|
@@ -7190,7 +7192,9 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
7190
7192
|
messages,
|
|
7191
7193
|
estimateTokens,
|
|
7192
7194
|
);
|
|
7193
|
-
const window =
|
|
7195
|
+
const window =
|
|
7196
|
+
_ctxRequestWindow ??
|
|
7197
|
+
(getContextWindow(model, provider, options) || 0);
|
|
7194
7198
|
logger.log(chalk.bold("\nContext usage (live session):"));
|
|
7195
7199
|
const rows = [
|
|
7196
7200
|
["system", buckets.system, counts.system],
|
|
@@ -9756,8 +9760,19 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
9756
9760
|
_curModel = activeModel;
|
|
9757
9761
|
_turnCount += 1;
|
|
9758
9762
|
if (usageEvents?.length) {
|
|
9759
|
-
const
|
|
9760
|
-
|
|
9763
|
+
const lastCall = [...usageEvents]
|
|
9764
|
+
.reverse()
|
|
9765
|
+
.find(
|
|
9766
|
+
(event) =>
|
|
9767
|
+
!event.attribution && (!event.source || event.source === "model"),
|
|
9768
|
+
);
|
|
9769
|
+
_ctxRequestWindow = lastCall?.contextWindow ?? null;
|
|
9770
|
+
const last = lastCall?.usage || {};
|
|
9771
|
+
const used =
|
|
9772
|
+
(last.input_tokens || 0) +
|
|
9773
|
+
(last.output_tokens || 0) +
|
|
9774
|
+
(last.cache_read_input_tokens || 0) +
|
|
9775
|
+
(last.cache_creation_input_tokens || 0);
|
|
9761
9776
|
if (used > 0) _ctxUsedTokens = used;
|
|
9762
9777
|
}
|
|
9763
9778
|
|