chainlesschain 0.166.100 → 0.166.102
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/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-Cd4iUOPt.js → AIOps-CyHIMEd8.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton--ucr-zko.js → ActionButton-vuNxDpHm.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DbejYMWk.js → Analytics-D0quEM0q.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CLgKxeGw.js → AppLayout-xRSVpbCs.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CTT5BIL5.js → Artifacts-ktfVAZBC.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DP-WBWe9.js → Audit-UJW6maH4.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-B6VqheJk.js → BackgroundAgents-BYrfdCoT.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-VWJK5zim.js → Backup-IBgsJ7BK.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-YGFO9RHd.js → BaseInput-BmP8_zxy.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CVfydnCd.js → Chat-urkw8_BF.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BICpB-qU.js → ChatBubbleRenderer-Cw44zZbh.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-Bd5vKRMk.js → Checkbox-CYboo-__.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DHNgPHvg.js → Codegen-DaqR_Ay8.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CA2BYQ8T.js → Col-04BSIj_z.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DnKJ-qpI.js → Community-DxFk7Trv.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-C9BZ8t4r.js → Compact-mjgWlMCB.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-ByyQ2FOl.js → Compliance-CC5ee7QV.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-rXTwXE_c.js → Cowork-BK4BhHZd.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-BuW-HODy.js → Cron-CP6jAxq0.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-OudNtbYW.js → Crosschain-DJPaViZS.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BQ6BxYNN.js → DID-BTLxkuOj.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Cz5HG8tz.js → Dashboard-Djkiqh3d.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BzclHOVv.js → Dropdown-t_eUhqom.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CbJETFdy.js → EmailListRenderer-7w6USx_J.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-Dx_pJG3d.js → EvolutionSettings-mU5IHEk5.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-6JCS1MNg.js → FamilyGuardDashboard-BCh-VBBC.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BrPkMYaf.js → Federation-Be_VpjI2.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Bhc9pobs.js → FormItemContext-D_lzQ7PI.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BxOh07uQ.js → GenericCardRenderer-LYu3KapV.js} +1 -1
- package/src/assets/web-panel/assets/{Git-D_idoujr.js → Git-BBeF-PP4.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-ZGfIRE-x.js → Governance-CoF8Kzg7.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DpAmcwbw.js → Inference-C4DLMnXS.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-D1S1UTgP.js → KnowledgeGraph-B2mlNewk.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-2sc8V5XV.js → Logs-DMZ_44Ya.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-Ck7Iv_9e.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-0xlFUKbe.js → Marketplace-BqDzTew_.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-D25eJLGm.js → McpTools-BbwSbDN9.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-BLRGd9hM.js → Memory-DAaTWgrm.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-zpFINGzn.js → MobileBridge-BjbTGxoR.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Cbyd-8kx.js → MobileProjects-DMODOBr-.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DgXgUlHc.js → Mtc-DT9N2rCs.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-DzcL-dKH.js → MtcAudit-DagMfUVv.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-C3OrZ6VN.js → Multisig-C1BKP6nM.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Bqp_vWA7.js → NLProgramming-B5LFh72i.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Dyn45-Ht.js → Notes-Q77V3ltW.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CLjafGZr.js → NotificationSettings-HxdpNIBs.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Dc0DpvBH.js +1 -0
- package/src/assets/web-panel/assets/{Organization-5gr9hyLm.js → Organization-QL3NZ7uW.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BRdU02hT.js → Overflow-B_gqOKho.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DIi7fzh6.js → P2P-BBJubU8Z.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BCbS1KpA.js → PdhVaultBrowser-CFnGd-2E.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BjeP9VtA.js → Permissions-BKkznIUM.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-y8PXOQUc.js → PersonalDataHub-DYK7ZAcd.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-B0fL5uxY.js → Pipeline-CoeKpjoN.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-C8jCDn8Z.js → Privacy-Diw4G-92.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-B_L6Dc6V.js → ProjectInit-CHBOFkma.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Bb1CYbZh.js → ProjectSettings-BJIsgdOf.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-CUSV10Cn.js → Projects-GJjItXIk.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-mBSTDJ0E.js → Providers-o8QCimor.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CHxgalvt.js → QrScannerModal-z2W-zvhW.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DI9KIMEV.js → QuickAsk-_yubhsna.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-B5_zW1JH.js → Recommend-CucgJwih.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BkH4bmM5.js → RemoteSession-EzfIIRg1.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-DJrAqwAq.js → Reputation-_shttE67.js} +1 -1
- package/src/assets/web-panel/assets/{Row-xZ3MAM34.js → Row-DQA_S8-9.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CCsrLLiu.js → RssFeed-BOqWawXT.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CTCRKvaP.js → Search-Dx1v2xOq.js} +1 -1
- package/src/assets/web-panel/assets/{Security-D7joyfp2.js → Security-Bt4HHsT4.js} +4 -4
- package/src/assets/web-panel/assets/{Services-oqHPmTG4.js → Services-sruHiQ-r.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-BR_32bTG.js → Skeleton-CiBxvmOJ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BoRz9mln.js → Skills-De9qKODU.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-UAGUHZ9b.js → Sla-B_6yn8Wp.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DeP_rMgv.js → SpeechSettings-C2CafExS.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CSzzMmeA.js → SyncSettings-Dhh3Qmb0.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-CcqOLsLB.js → Tasks-Mvo5mTWm.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-cDbkGSDG.js → Templates-D7WVTQQy.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DmOy58cq.js → Tenant-7ur9Yfxd.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CsRZH5vr.js → Terminal-BgzrOA6k.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BgJrk6HG.js → TimelineRenderer-Dco20pT1.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CCQglKDE.js → Tokens-hN6qBPag.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-t-Gt3oBY.js → Trigger-C4f_twAM.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DQgu2kI0.js → Trust-Wf1SMypp.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-Cod2WUGj.js → UkeySign-DUXSyg3N.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-SGN5zaVK.js → VideoEditing-BvqsJaL0.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CnLEL-LD.js → Wallet-CgAbcjKl.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-C2keUpD6.js → WebAuthn-DaLT0W3s.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-B1GvrwWJ.js → WorkflowEditor-CQqAXoaS.js} +1 -1
- package/src/assets/web-panel/assets/{chat-1E9_P_qY.js → chat-BhlohFTB.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DuU6Os4q.js → colors-D7HqXIL8.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C5NfOAcM.js → compact-item-Bqk4FCLY.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-D4Fxz9qQ.js → createContext-CEmWrWf0.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-YPX_TU7w.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-C6C49iFk.js → hasIn-CDY0pFi2.js} +1 -1
- package/src/assets/web-panel/assets/{index-DP2DCKD-.js → index-1HBam9t1.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-bb-R99.js → index-6f6n0KFR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BmvU4Tp_.js → index-B8L3_-sG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsH8mFp4.js → index-BHGOdvOQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVE2wCeb.js → index-BNrvBWDS.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJS6GTpv.js → index-BPmRkxeX.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7mh6xlu.js → index-BXRooi-O.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZKRZYTX.js → index-BiLu-ImR.js} +1 -1
- package/src/assets/web-panel/assets/{index-jFg3CPlQ.js → index-BuKGuH_y.js} +1 -1
- package/src/assets/web-panel/assets/{index-BULggEX6.js → index-BxXFRLTZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPzunJER.js → index-BxYO6nde.js} +1 -1
- package/src/assets/web-panel/assets/{index-AO6iDCSL.js → index-C02yDu4f.js} +1 -1
- package/src/assets/web-panel/assets/{index-BU5mPkNX.js → index-C3opQg47.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSypQU1h.js → index-C9mvnSii.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZgT7pH-.js → index-CVrwozwH.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpiOzt7U.js → index-CYcjOnDX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlHkc48f.js → index-Cf1ha8l0.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXb8gEWh.js → index-Chxt0t-A.js} +1 -1
- package/src/assets/web-panel/assets/{index-HQXFl8fh.js → index-CkjgSHVz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpaGe-dr.js → index-CkqBoCiu.js} +3 -3
- package/src/assets/web-panel/assets/{index-C2nO02uW.js → index-CqK0J4Sj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bu6qMjf4.js → index-CrsM-oiD.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bk-paNL3.js → index-Cur88hoN.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXn-e3ki.js → index-D0nfNmbq.js} +1 -1
- package/src/assets/web-panel/assets/index-D53szVZQ.js +1 -0
- package/src/assets/web-panel/assets/{index-CDVwN9Sv.js → index-DEzL7s7P.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_ON9La1.js → index-DGKRAO61.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQJoh5rw.js → index-DPBoWNwq.js} +1 -1
- package/src/assets/web-panel/assets/{index-cnDfwWU5.js → index-DRcDWMwP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBVqlelF.js → index-DmKdCWq1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYg1dtne.js → index-DpI1LqJX.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5lzRoHp.js → index-DuMt3ewl.js} +1 -1
- package/src/assets/web-panel/assets/{index-gh11zJ9h.js → index-Dwob5XoD.js} +1 -1
- package/src/assets/web-panel/assets/index-Ub2nJbV2.js +1 -0
- package/src/assets/web-panel/assets/{index-D1TXgNPA.js → index-XErJQ1yF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFK6PTGJ.js → index-aBHlgMrq.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dh-vezHe.js → index-e9oCy7_4.js} +1 -1
- package/src/assets/web-panel/assets/{index-bW6vfpLH.js → index-lBAbMOzg.js} +1 -1
- package/src/assets/web-panel/assets/{index-lNmDaf3J.js → index-o_lc3eww.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-3DSfnIpD.js → initDefaultProps-CIeEUxIN.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DxGLmgA0.js → motion-IPIj1ZtP.js} +1 -1
- package/src/assets/web-panel/assets/{move-DrlLG6m5.js → move-BfSeXZ-f.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BITbrJSb.js → mtc-parser-DX03-Xp4.js} +1 -1
- package/src/assets/web-panel/assets/{omit-D7k5vIbk.js → omit-z9EannfX.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BJSvYFWo.js → pickAttrs-DXKmRkqZ.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-Bf4to1jA.js → placementArrow-k2HV7cIU.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BXzeyzTa.js → responsiveObserve-bX7CsyWy.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DLzNUNdj.js → slide-NskjQLbJ.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-wBBnrRm_.js → statusUtils-B3IoG-Er.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BnmJzXNr.js → styleChecker-DHv_UilX.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DrN8MrJb.js → useFlexGapSupport-DEqGB5Ng.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-dnkYGkjY.js → useFs-Bl9CbrqZ.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-k_xkv7-k.js → usePersonalDataHub-O-Ukv93M.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-B-v8PXpK.js → vnode-hGCHTaZt.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Coue8wAK.js → zoom-BWhIVeKQ.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agent.js +64 -40
- package/src/commands/eval.js +11 -8
- package/src/data/changelog.json +26 -0
- package/src/harness/provider-backed-compaction.js +13 -5
- package/src/lib/config-schema.js +18 -5
- package/src/lib/context-memory-kernel/live-compaction.js +142 -61
- package/src/lib/context-memory-kernel/memory-query-index.js +5 -2
- package/src/lib/context-memory-kernel/runtime.js +4 -0
- package/src/lib/context-memory-kernel/segmented-memory-port.js +28 -3
- package/src/lib/context-source-ledger.js +52 -9
- package/src/lib/formal-budget-authority.js +533 -0
- package/src/lib/formal-budget-contract.js +609 -0
- package/src/lib/formal-budget-transport.js +345 -0
- package/src/lib/goal-condition-engine.js +25 -2
- package/src/lib/llm-config-defaults.js +10 -4
- package/src/lib/llm-pricing.js +16 -4
- package/src/lib/model-capabilities.js +26 -0
- package/src/lib/model-catalog-review.js +18 -1
- package/src/lib/model-context-catalog.js +41 -1
- package/src/lib/openai-responses.js +8 -0
- package/src/lib/skill-retrieval-router.js +1 -0
- package/src/lib/usage-pricing-context.js +33 -2
- package/src/repl/agent-repl.js +247 -153
- package/src/runtime/agent-core.js +371 -97
- package/src/runtime/coding-agent-contract-shared.cjs +14 -1
- package/src/runtime/headless-runner.js +1 -0
- package/src/runtime/headless-stream.js +137 -4
- package/src/runtime/mcp-tool-search.js +0 -0
- package/src/runtime/provider-stream-state.js +14 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-575jjYE6.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Bx8wMauC.js +0 -1
- package/src/assets/web-panel/assets/devWarning-zDWbYMr7.js +0 -1
- package/src/assets/web-panel/assets/index-BPBsZZnT.js +0 -1
- package/src/assets/web-panel/assets/index-CtGQDg7m.js +0 -1
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import {
|
|
3
3
|
canonicalDigest,
|
|
4
4
|
InMemorySessionContextPort,
|
|
5
|
+
getCompactionPlanRejection,
|
|
5
6
|
} from "@chainlesschain/context-memory-kernel";
|
|
6
7
|
import { sessionExists } from "../../harness/jsonl-session-store.js";
|
|
7
8
|
import {
|
|
@@ -11,6 +12,17 @@ import {
|
|
|
11
12
|
} from "./message-adapter.js";
|
|
12
13
|
import { JsonlSessionContextPort } from "./jsonl-session-context-port.js";
|
|
13
14
|
import { createCliContextMemoryRuntime } from "./runtime.js";
|
|
15
|
+
import { projectRuntimeTokenUsage } from "../runtime-usage-ledger.js";
|
|
16
|
+
|
|
17
|
+
const rejectedCompactionUsage = new WeakMap();
|
|
18
|
+
|
|
19
|
+
// Only the owned canonical adapter can associate an error with its completed
|
|
20
|
+
// summarizer. A caller-supplied error property is never a settlement authority.
|
|
21
|
+
export function getRejectedCompactionUsage(error) {
|
|
22
|
+
return error && typeof error === "object"
|
|
23
|
+
? rejectedCompactionUsage.get(error) || null
|
|
24
|
+
: null;
|
|
25
|
+
}
|
|
14
26
|
|
|
15
27
|
function estimatedTokens(messages) {
|
|
16
28
|
return Math.max(
|
|
@@ -20,7 +32,9 @@ function estimatedTokens(messages) {
|
|
|
20
32
|
typeof message?.content === "string"
|
|
21
33
|
? message.content
|
|
22
34
|
: JSON.stringify(message?.content ?? "");
|
|
23
|
-
return
|
|
35
|
+
return (
|
|
36
|
+
total + Math.max(1, Math.ceil(Buffer.byteLength(content, "utf8") / 4))
|
|
37
|
+
);
|
|
24
38
|
}, 0),
|
|
25
39
|
);
|
|
26
40
|
}
|
|
@@ -125,13 +139,22 @@ class CallbackSessionContextPort extends InMemorySessionContextPort {
|
|
|
125
139
|
}
|
|
126
140
|
|
|
127
141
|
function kernelBudget(compressor) {
|
|
128
|
-
const inputBudget = Math.max(
|
|
129
|
-
|
|
142
|
+
const inputBudget = Math.max(
|
|
143
|
+
256,
|
|
144
|
+
Math.trunc(Number(compressor?.maxTokens)) || 16_384,
|
|
145
|
+
);
|
|
146
|
+
const reservedOutputTokens = Math.max(
|
|
147
|
+
1,
|
|
148
|
+
Math.min(2048, Math.floor(inputBudget / 10)),
|
|
149
|
+
);
|
|
130
150
|
return {
|
|
131
151
|
modelWindowTokens: inputBudget + reservedOutputTokens,
|
|
132
152
|
reservedOutputTokens,
|
|
133
153
|
safetyMarginTokens: 0,
|
|
134
|
-
recoveryReserveTokens: Math.min(
|
|
154
|
+
recoveryReserveTokens: Math.min(
|
|
155
|
+
256,
|
|
156
|
+
Math.max(1, Math.floor(inputBudget * 0.05)),
|
|
157
|
+
),
|
|
135
158
|
};
|
|
136
159
|
}
|
|
137
160
|
|
|
@@ -175,7 +198,10 @@ function usageReceipt(stats, provider, model) {
|
|
|
175
198
|
* summarizer for the Kernel-selected dropped partition; it cannot commit or
|
|
176
199
|
* choose the authoritative output on its own.
|
|
177
200
|
*/
|
|
178
|
-
export async function compactLiveMessagesCanonical(
|
|
201
|
+
export async function compactLiveMessagesCanonical(
|
|
202
|
+
messagesInput,
|
|
203
|
+
options = {},
|
|
204
|
+
) {
|
|
179
205
|
const messages = Array.isArray(messagesInput) ? [...messagesInput] : [];
|
|
180
206
|
const sessionId = String(options.sessionId || `live-${randomUUID()}`);
|
|
181
207
|
const operationId = String(options.operationId || `compact-${randomUUID()}`);
|
|
@@ -185,10 +211,13 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
|
|
|
185
211
|
new Date(Number((options.clock || Date.now)())).toISOString();
|
|
186
212
|
const compressor = options.compressor;
|
|
187
213
|
if (!compressor || typeof compressor.compress !== "function") {
|
|
188
|
-
throw new TypeError(
|
|
214
|
+
throw new TypeError(
|
|
215
|
+
"canonical live compaction requires a compatibility summarizer",
|
|
216
|
+
);
|
|
189
217
|
}
|
|
190
218
|
|
|
191
219
|
let summaryStats = null;
|
|
220
|
+
let summaryReceipt = null;
|
|
192
221
|
let runtime;
|
|
193
222
|
let verifiedAuthoritySnapshot = null;
|
|
194
223
|
const persistentSession =
|
|
@@ -227,9 +256,7 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
|
|
|
227
256
|
memoryPort: bootstrapRuntime.memoryPort,
|
|
228
257
|
sessionPort,
|
|
229
258
|
});
|
|
230
|
-
} else if (
|
|
231
|
-
persistentSession
|
|
232
|
-
) {
|
|
259
|
+
} else if (persistentSession) {
|
|
233
260
|
runtime = createCliContextMemoryRuntime({
|
|
234
261
|
sessionId,
|
|
235
262
|
scopeKey: `cli:session:${sessionId}`,
|
|
@@ -265,13 +292,13 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
|
|
|
265
292
|
});
|
|
266
293
|
}
|
|
267
294
|
if (!runtime.decision.canonical) {
|
|
268
|
-
const error = new Error(
|
|
295
|
+
const error = new Error(
|
|
296
|
+
"canonical live compaction is not authoritative for this cohort",
|
|
297
|
+
);
|
|
269
298
|
error.code = "legacy_writer_fenced";
|
|
270
299
|
throw error;
|
|
271
300
|
}
|
|
272
|
-
if (
|
|
273
|
-
persistentSession
|
|
274
|
-
) {
|
|
301
|
+
if (persistentSession) {
|
|
275
302
|
const authority =
|
|
276
303
|
verifiedAuthoritySnapshot ||
|
|
277
304
|
(await runtime.sessionPort.readSnapshot(sessionId));
|
|
@@ -296,52 +323,102 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
|
|
|
296
323
|
const provider = options.provider || "provider.local";
|
|
297
324
|
const model = options.model || "default";
|
|
298
325
|
const memoryRevision = await runtime.memoryPort.getRevision();
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
:
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
326
|
+
let receipt;
|
|
327
|
+
try {
|
|
328
|
+
receipt = await runtime.kernel.compactContext({
|
|
329
|
+
operationId,
|
|
330
|
+
sessionId,
|
|
331
|
+
...kernelBudget(compressor),
|
|
332
|
+
sink: provider,
|
|
333
|
+
scopeAdmissions: [{ scope: "session", scopeId: sessionId }],
|
|
334
|
+
policyVersion: "cli-context-policy-v1",
|
|
335
|
+
modelProfile: model,
|
|
336
|
+
memoryRevision,
|
|
337
|
+
allowFallback: false,
|
|
338
|
+
now: operationNow,
|
|
339
|
+
metadata: {
|
|
340
|
+
inputMessageCount: messages.length,
|
|
341
|
+
originalTokens: estimatedTokens(messages),
|
|
342
|
+
trigger,
|
|
343
|
+
provider,
|
|
344
|
+
model,
|
|
345
|
+
},
|
|
346
|
+
summarizer: async (droppedItems, context) => {
|
|
347
|
+
const droppedMessages = contextItemsToMessages(droppedItems);
|
|
348
|
+
const result = await compressor.compress(droppedMessages, {
|
|
349
|
+
preserveToolPairs: true,
|
|
350
|
+
...(options.compressOptions || {}),
|
|
351
|
+
});
|
|
352
|
+
summaryStats = result.stats || {};
|
|
353
|
+
summaryReceipt = usageReceipt(summaryStats, provider, model);
|
|
354
|
+
const reduced =
|
|
355
|
+
Number(summaryStats.saved || 0) > 0 ||
|
|
356
|
+
result.messages.length < droppedMessages.length;
|
|
357
|
+
const item = reduced
|
|
358
|
+
? createSummaryContextItem({
|
|
359
|
+
messages: result.messages,
|
|
360
|
+
parents: droppedItems,
|
|
361
|
+
operationId: context.operationId,
|
|
362
|
+
now: operationNow,
|
|
363
|
+
})
|
|
364
|
+
: null;
|
|
365
|
+
return {
|
|
366
|
+
items: item ? [item] : [],
|
|
367
|
+
usageReceipt: summaryReceipt,
|
|
368
|
+
degraded: summaryStats.degraded === true,
|
|
369
|
+
...(summaryStats.degradedReason
|
|
370
|
+
? {
|
|
371
|
+
degradedReason: String(summaryStats.degradedReason).slice(
|
|
372
|
+
0,
|
|
373
|
+
160,
|
|
374
|
+
),
|
|
375
|
+
}
|
|
376
|
+
: {}),
|
|
377
|
+
};
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
} catch (error) {
|
|
381
|
+
const rejection = getCompactionPlanRejection(error);
|
|
382
|
+
if (
|
|
383
|
+
rejection?.operationId === operationId &&
|
|
384
|
+
rejection.sessionId === sessionId &&
|
|
385
|
+
summaryReceipt !== null &&
|
|
386
|
+
rejection.usageReceipt &&
|
|
387
|
+
canonicalDigest(rejection.usageReceipt) ===
|
|
388
|
+
canonicalDigest(summaryReceipt) &&
|
|
389
|
+
summaryStats?.summaryUsageUnknown !== true
|
|
390
|
+
) {
|
|
391
|
+
try {
|
|
392
|
+
const usage = projectRuntimeTokenUsage({
|
|
393
|
+
...(summaryStats.summaryCallId
|
|
394
|
+
? { callId: summaryStats.summaryCallId }
|
|
395
|
+
: {}),
|
|
396
|
+
provider: summaryStats.summaryProvider || provider,
|
|
397
|
+
model: summaryStats.summaryModel || model,
|
|
398
|
+
source: "semantic-compaction",
|
|
399
|
+
usage: {
|
|
400
|
+
input_tokens: summaryStats.summaryUsage?.inputTokens,
|
|
401
|
+
output_tokens: summaryStats.summaryUsage?.outputTokens,
|
|
402
|
+
cache_read_input_tokens:
|
|
403
|
+
summaryStats.summaryUsage?.cacheReadTokens ?? 0,
|
|
404
|
+
cache_creation_input_tokens:
|
|
405
|
+
summaryStats.summaryUsage?.cacheCreationTokens ?? 0,
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
rejectedCompactionUsage.set(
|
|
409
|
+
error,
|
|
410
|
+
Object.freeze({
|
|
411
|
+
...usage,
|
|
412
|
+
usage: Object.freeze(usage.usage),
|
|
413
|
+
receipt: Object.freeze({ ...summaryReceipt }),
|
|
414
|
+
}),
|
|
415
|
+
);
|
|
416
|
+
} catch {
|
|
417
|
+
// Missing or invalid usage retains the caller's unknown outcome path.
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
throw error;
|
|
421
|
+
}
|
|
345
422
|
if (!["committed", "degraded"].includes(receipt.status)) {
|
|
346
423
|
return {
|
|
347
424
|
messages,
|
|
@@ -361,12 +438,16 @@ export async function compactLiveMessagesCanonical(messagesInput, options = {})
|
|
|
361
438
|
messages: outputMessages,
|
|
362
439
|
stats: {
|
|
363
440
|
...(summaryStats || {}),
|
|
364
|
-
strategy:
|
|
441
|
+
strategy:
|
|
442
|
+
receipt.status === "degraded" ? "deterministic-fallback" : "canonical",
|
|
365
443
|
originalMessages: messages.length,
|
|
366
444
|
compressedMessages: outputMessages.length,
|
|
367
445
|
originalTokens: estimatedTokens(messages),
|
|
368
446
|
compressedTokens: estimatedTokens(outputMessages),
|
|
369
|
-
saved: Math.max(
|
|
447
|
+
saved: Math.max(
|
|
448
|
+
0,
|
|
449
|
+
estimatedTokens(messages) - estimatedTokens(outputMessages),
|
|
450
|
+
),
|
|
370
451
|
canonicalAlreadySettled: true,
|
|
371
452
|
canonicalReceipt: receipt,
|
|
372
453
|
},
|
|
@@ -2,6 +2,9 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
|
|
3
3
|
export const MEMORY_QUERY_INDEX_SCHEMA = "chainlesschain.memory-query-index/v1";
|
|
4
4
|
const CURSOR_SCHEMA = "chainlesschain.memory-list-cursor/v1";
|
|
5
|
+
// Preserve the existing English collation while avoiding constructing locale
|
|
6
|
+
// options for every comparison during shard sorts, cursor search and merging.
|
|
7
|
+
const memoryRowCollator = new Intl.Collator("en");
|
|
5
8
|
|
|
6
9
|
export function queryDigest(bytes) {
|
|
7
10
|
return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
@@ -10,8 +13,8 @@ export function queryDigest(bytes) {
|
|
|
10
13
|
export function compareMemoryRows(left, right) {
|
|
11
14
|
return (
|
|
12
15
|
right.importance - left.importance ||
|
|
13
|
-
right.updatedAt
|
|
14
|
-
left.memoryId
|
|
16
|
+
memoryRowCollator.compare(right.updatedAt, left.updatedAt) ||
|
|
17
|
+
memoryRowCollator.compare(left.memoryId, right.memoryId)
|
|
15
18
|
);
|
|
16
19
|
}
|
|
17
20
|
|
|
@@ -22,6 +22,10 @@ export function createCliContextMemoryRuntime(options = {}) {
|
|
|
22
22
|
const memoryPort =
|
|
23
23
|
options.memoryPort ||
|
|
24
24
|
new SegmentedMemoryPort({
|
|
25
|
+
queryIndexCacheMode:
|
|
26
|
+
options.memoryQueryIndexCacheMode ||
|
|
27
|
+
(options.env || process.env).CC_CONTEXT_MEMORY_QUERY_CACHE ||
|
|
28
|
+
"validate-disk",
|
|
25
29
|
readOnly: !decision.canonical,
|
|
26
30
|
...(options.memoryFilePath ? { filePath: options.memoryFilePath } : {}),
|
|
27
31
|
});
|
|
@@ -170,6 +170,7 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
|
|
|
170
170
|
maxTotalBytes = DEFAULT_MAX_TOTAL_BYTES,
|
|
171
171
|
maxEvents = DEFAULT_SEGMENTED_MAX_EVENTS,
|
|
172
172
|
readOnly = false,
|
|
173
|
+
queryIndexCacheMode = "validate-disk",
|
|
173
174
|
...options
|
|
174
175
|
} = {}) {
|
|
175
176
|
super({ ...options, maxEvents });
|
|
@@ -177,6 +178,9 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
|
|
|
177
178
|
throw new TypeError("maxTotalBytes must be a positive safe integer");
|
|
178
179
|
this.maxTotalBytes = maxTotalBytes;
|
|
179
180
|
this.readOnly = Boolean(readOnly);
|
|
181
|
+
if (!["validate-disk", "verified-memory"].includes(queryIndexCacheMode))
|
|
182
|
+
throw new TypeError("Unknown query index cache mode");
|
|
183
|
+
this.queryIndexCacheMode = queryIndexCacheMode;
|
|
180
184
|
this.filePath = resolve(this.filePath);
|
|
181
185
|
this.shardDirectory = `${this.filePath}.shards`;
|
|
182
186
|
this._queryIndexes = new Map();
|
|
@@ -656,6 +660,27 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
|
|
|
656
660
|
|
|
657
661
|
_readQueryIndex(manifest, bucket) {
|
|
658
662
|
const descriptor = manifest.shards[bucket];
|
|
663
|
+
const binding = JSON.stringify([
|
|
664
|
+
manifest.digest,
|
|
665
|
+
manifest.storeRevision,
|
|
666
|
+
descriptor.digest,
|
|
667
|
+
descriptor.queryDigest,
|
|
668
|
+
descriptor.queryBytes,
|
|
669
|
+
descriptor.recordCount,
|
|
670
|
+
]);
|
|
671
|
+
const cached = this._queryIndexes.get(bucket);
|
|
672
|
+
// This is an already verified, host-owned decoded snapshot, never a trust
|
|
673
|
+
// decision based on filesystem timestamps. Re-read and verify the current
|
|
674
|
+
// manifest on every operation; any generation/authority change invalidates
|
|
675
|
+
// this binding. Selected authority shards are still read and verified.
|
|
676
|
+
// Disk repair remains eager in validate-disk mode; verified-memory repairs
|
|
677
|
+
// a derived index on the next cache miss, rather than every warm query.
|
|
678
|
+
if (
|
|
679
|
+
this.queryIndexCacheMode === "verified-memory" &&
|
|
680
|
+
descriptor.queryDigest &&
|
|
681
|
+
cached?.binding === binding
|
|
682
|
+
)
|
|
683
|
+
return cached.index;
|
|
659
684
|
let bytes;
|
|
660
685
|
if (descriptor.queryDigest) {
|
|
661
686
|
const file = this._queryIndexPath(bucket, descriptor);
|
|
@@ -705,8 +730,8 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
|
|
|
705
730
|
bytes = encodeQueryIndex(this._readShard(manifest, bucket));
|
|
706
731
|
}
|
|
707
732
|
const digest = descriptor.queryDigest || queryDigest(bytes);
|
|
708
|
-
|
|
709
|
-
|
|
733
|
+
if (cached?.digest === digest && cached.binding === binding)
|
|
734
|
+
return cached.index;
|
|
710
735
|
let index;
|
|
711
736
|
try {
|
|
712
737
|
index = compileQueryIndex(bytes, descriptor);
|
|
@@ -717,7 +742,7 @@ export class SegmentedMemoryPort extends DurableJsonMemoryPort {
|
|
|
717
742
|
cause,
|
|
718
743
|
);
|
|
719
744
|
}
|
|
720
|
-
this._queryIndexes.set(bucket, { digest, index });
|
|
745
|
+
this._queryIndexes.set(bucket, { digest, binding, index });
|
|
721
746
|
return index;
|
|
722
747
|
}
|
|
723
748
|
|
|
@@ -40,7 +40,28 @@ class ContextSourceLedger {
|
|
|
40
40
|
* @returns {string} entryId
|
|
41
41
|
*/
|
|
42
42
|
record(entry) {
|
|
43
|
+
if (
|
|
44
|
+
entry.tokenCount != null &&
|
|
45
|
+
(!Number.isSafeInteger(entry.tokenCount) || entry.tokenCount < 0)
|
|
46
|
+
) {
|
|
47
|
+
throw new TypeError(
|
|
48
|
+
"Context tokenCount must be a non-negative safe integer",
|
|
49
|
+
);
|
|
50
|
+
}
|
|
43
51
|
const entryId = entry.entryId || crypto.randomUUID();
|
|
52
|
+
const previous = this._entries.get(entryId);
|
|
53
|
+
if (previous) {
|
|
54
|
+
for (const [index, key] of [
|
|
55
|
+
[this._byTurn, previous.turnId],
|
|
56
|
+
[this._bySession, previous.sessionId],
|
|
57
|
+
]) {
|
|
58
|
+
const remaining = (index.get(key) || []).filter(
|
|
59
|
+
(item) => item.entryId !== entryId,
|
|
60
|
+
);
|
|
61
|
+
if (remaining.length) index.set(key, remaining);
|
|
62
|
+
else index.delete(key);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
44
65
|
const full = {
|
|
45
66
|
entryId,
|
|
46
67
|
traceId: entry.traceId || null,
|
|
@@ -53,6 +74,7 @@ class ContextSourceLedger {
|
|
|
53
74
|
summary: entry.summary,
|
|
54
75
|
metadata: entry.metadata,
|
|
55
76
|
tokenCount: entry.tokenCount || 0,
|
|
77
|
+
tokenBasis: entry.tokenBasis === "observed" ? "observed" : "estimated",
|
|
56
78
|
insertedAt: new Date(),
|
|
57
79
|
tags: entry.tags || [],
|
|
58
80
|
};
|
|
@@ -64,7 +86,8 @@ class ContextSourceLedger {
|
|
|
64
86
|
this._byTurn.get(full.turnId).push(full);
|
|
65
87
|
|
|
66
88
|
// Index by session
|
|
67
|
-
if (!this._bySession.has(full.sessionId))
|
|
89
|
+
if (!this._bySession.has(full.sessionId))
|
|
90
|
+
this._bySession.set(full.sessionId, []);
|
|
68
91
|
this._bySession.get(full.sessionId).push(full);
|
|
69
92
|
|
|
70
93
|
return entryId;
|
|
@@ -82,6 +105,7 @@ class ContextSourceLedger {
|
|
|
82
105
|
summary: entry.summary || entry.content,
|
|
83
106
|
metadata: entry.metadata,
|
|
84
107
|
tokenCount: entry.tokenCount ?? entry.tokens ?? 0,
|
|
108
|
+
tokenBasis: entry.tokenBasis,
|
|
85
109
|
traceId: entry.traceId,
|
|
86
110
|
});
|
|
87
111
|
}
|
|
@@ -95,14 +119,31 @@ class ContextSourceLedger {
|
|
|
95
119
|
}
|
|
96
120
|
|
|
97
121
|
/** Aggregate token usage by source type. */
|
|
98
|
-
getTokenBreakdown() {
|
|
99
|
-
const
|
|
122
|
+
getTokenBreakdown(options = {}) {
|
|
123
|
+
const sources = new Map();
|
|
100
124
|
let total = 0;
|
|
101
|
-
for (const entry of this.
|
|
125
|
+
for (const entry of this.getProvenance(options)) {
|
|
102
126
|
total += entry.tokenCount;
|
|
103
|
-
|
|
127
|
+
sources.set(
|
|
128
|
+
entry.sourceType,
|
|
129
|
+
(sources.get(entry.sourceType) || 0) + entry.tokenCount,
|
|
130
|
+
);
|
|
104
131
|
}
|
|
105
|
-
return { total, bySource };
|
|
132
|
+
return { total, bySource: Object.fromEntries(sources) };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Source attribution is separate from provider request usage and billing. */
|
|
136
|
+
getTokenReport(options = {}) {
|
|
137
|
+
const entries = this.getProvenance(options);
|
|
138
|
+
const byBasis = { estimated: 0, observed: 0 };
|
|
139
|
+
for (const entry of entries) byBasis[entry.tokenBasis] += entry.tokenCount;
|
|
140
|
+
return {
|
|
141
|
+
...this.getTokenBreakdown(options),
|
|
142
|
+
byBasis,
|
|
143
|
+
entries: entries.length,
|
|
144
|
+
currentRequestVerified: false,
|
|
145
|
+
billingVerified: false,
|
|
146
|
+
};
|
|
106
147
|
}
|
|
107
148
|
|
|
108
149
|
/** Clear the in-memory ledger (test/runtime lifecycle boundary). */
|
|
@@ -146,7 +187,8 @@ class ContextSourceLedger {
|
|
|
146
187
|
|
|
147
188
|
for (const e of entries) {
|
|
148
189
|
byType[e.sourceType] = (byType[e.sourceType] || 0) + 1;
|
|
149
|
-
byPermission[e.permissionMode] =
|
|
190
|
+
byPermission[e.permissionMode] =
|
|
191
|
+
(byPermission[e.permissionMode] || 0) + 1;
|
|
150
192
|
bySource[e.sourceId] = (bySource[e.sourceId] || 0) + 1;
|
|
151
193
|
totalTokens += e.tokenCount;
|
|
152
194
|
avgConfidence += e.confidence;
|
|
@@ -162,7 +204,7 @@ class ContextSourceLedger {
|
|
|
162
204
|
byType,
|
|
163
205
|
byPermission,
|
|
164
206
|
bySource,
|
|
165
|
-
entries: entries.map(e => ({
|
|
207
|
+
entries: entries.map((e) => ({
|
|
166
208
|
sourceType: e.sourceType,
|
|
167
209
|
sourceId: e.sourceId,
|
|
168
210
|
permissionMode: e.permissionMode,
|
|
@@ -184,8 +226,9 @@ class ContextSourceLedger {
|
|
|
184
226
|
this._entries.delete(e.entryId);
|
|
185
227
|
const turnEntries = this._byTurn.get(e.turnId);
|
|
186
228
|
if (turnEntries) {
|
|
187
|
-
const idx = turnEntries.findIndex(x => x.entryId === e.entryId);
|
|
229
|
+
const idx = turnEntries.findIndex((x) => x.entryId === e.entryId);
|
|
188
230
|
if (idx >= 0) turnEntries.splice(idx, 1);
|
|
231
|
+
if (!turnEntries.length) this._byTurn.delete(e.turnId);
|
|
189
232
|
}
|
|
190
233
|
}
|
|
191
234
|
this._bySession.delete(sessionId);
|