@agimon-ai/doompi-autocompact 0.0.1-alpha.70 → 0.0.1-alpha.71

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.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.cjs","names":[],"sources":["../../src/constants/runtime.ts"],"sourcesContent":["export const ROOT_WORKING_LEAF = '@root';\nexport const PLAN_DOCUMENT_ENTRY = 'agent-harness-plan-document';\nexport const FOOTER_SOURCE = 'doom-autocompact';\nexport const FOOTER_ORDER = 20;\nexport const STATUS_KEY = 'doom-autocompact';\nexport const STATE_PHASE = {\n waiting: 'waiting',\n checkpointPending: 'checkpoint_pending',\n checkpointReady: 'checkpoint_ready',\n compacting: 'compacting',\n} as const;\n"],"mappings":"AAAA,MAKa,EAAc,CACzB,QAAS,UACT,kBAAmB,qBACnB,gBAAiB,mBACjB,WAAY,YACd"}
1
+ {"version":3,"file":"runtime.cjs","names":[],"sources":["../../src/constants/runtime.ts"],"sourcesContent":["export const ROOT_WORKING_LEAF = '@root';\nexport const PLAN_DOCUMENT_ENTRY = 'agent-harness-plan-document';\nexport const FOOTER_SOURCE = 'doom-autocompact';\nexport const FOOTER_ORDER = 20;\nexport const STATUS_KEY = 'doom-autocompact';\nexport const STATE_PHASE = {\n waiting: 'waiting',\n checkpointPending: 'checkpoint_pending',\n checkpointReady: 'checkpoint_ready',\n compacting: 'compacting',\n} as const;\n\n/**\n * Above this, the context hook is worth a telemetry event. Below it the hook is\n * noise against a round trip measured in seconds, and it runs on every request.\n */\nexport const SLOW_CONTEXT_HOOK_MS = 25;\n"],"mappings":"AAAA,MAKa,EAAc,CACzB,QAAS,UACT,kBAAmB,qBACnB,gBAAiB,mBACjB,WAAY,YACd"}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":[],"sources":["../../src/constants/runtime.ts"],"sourcesContent":["export const ROOT_WORKING_LEAF = '@root';\nexport const PLAN_DOCUMENT_ENTRY = 'agent-harness-plan-document';\nexport const FOOTER_SOURCE = 'doom-autocompact';\nexport const FOOTER_ORDER = 20;\nexport const STATUS_KEY = 'doom-autocompact';\nexport const STATE_PHASE = {\n waiting: 'waiting',\n checkpointPending: 'checkpoint_pending',\n checkpointReady: 'checkpoint_ready',\n compacting: 'compacting',\n} as const;\n"],"mappings":"AAAA,MAAa,EAAoB,QACpB,EAAsB,8BACtB,EAAgB,mBAEhB,EAAa,mBACb,EAAc,CACzB,QAAS,UACT,kBAAmB,qBACnB,gBAAiB,mBACjB,WAAY,YACd"}
1
+ {"version":3,"file":"runtime.mjs","names":[],"sources":["../../src/constants/runtime.ts"],"sourcesContent":["export const ROOT_WORKING_LEAF = '@root';\nexport const PLAN_DOCUMENT_ENTRY = 'agent-harness-plan-document';\nexport const FOOTER_SOURCE = 'doom-autocompact';\nexport const FOOTER_ORDER = 20;\nexport const STATUS_KEY = 'doom-autocompact';\nexport const STATE_PHASE = {\n waiting: 'waiting',\n checkpointPending: 'checkpoint_pending',\n checkpointReady: 'checkpoint_ready',\n compacting: 'compacting',\n} as const;\n\n/**\n * Above this, the context hook is worth a telemetry event. Below it the hook is\n * noise against a round trip measured in seconds, and it runs on every request.\n */\nexport const SLOW_CONTEXT_HOOK_MS = 25;\n"],"mappings":"AAAA,MAAa,EAAoB,QACpB,EAAsB,8BACtB,EAAgB,mBAEhB,EAAa,mBACb,EAAc,CACzB,QAAS,UACT,kBAAmB,qBACnB,gBAAiB,mBACjB,WAAY,YACd"}
@@ -40,5 +40,5 @@ ${n}Return only the decision tag when required, followed by a concise structured
40
40
  ### Blocked
41
41
  ## Key Decisions
42
42
  ## Next Steps
43
- ## Critical Context`}function C(e,n,r){let i=t.projectContextMessages((0,o.buildSessionContext)(n).messages,n).messages;if(e===1||!r)return i;let a=n.findIndex(e=>e.id===r);return a===-1?i:n.slice(a+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,o.sessionEntryToContextMessages)(e))}const w={enabled:!0,ratios:{},overrides:[]};function T(e,t){let n;try{n=(0,s.loadDoomConfig)((0,s.getHarnessState)().root??e).modes}catch(e){return process.emitWarning(`Doom autocompact configuration could not be loaded; using the active session model instead.`),t?.(e),w}let r=n?.autocompact,i=(r&&(r.model!==void 0||r.thinking!==void 0)?{...r.model?{model:r.model}:{},...r.thinking?{thinking:r.thinking}:{}}:void 0)??n?.planning?.subagents,a=r?.thresholds;return{enabled:r?.enabled??!0,...i?{agent:i}:{},ratios:{...a?.pass1===void 0?{}:{1:a.pass1},...a?.pass2===void 0?{}:{2:a.pass2},...a?.pass3===void 0?{}:{3:a.pass3}},overrides:r?.overrides??[]}}function E(e){let t=T(e.cwd).agent,n=t?.model?a.parseModelReference(t.model):void 0,r=n?e.modelRegistry.find(n.provider,n.modelId):void 0,i=r??e.model;if(!i)return;let o=t?.thinking??(r?n?.thinking:void 0)??e.thinkingLevel;return{model:i,...o?{thinkingLevel:o}:{}}}async function D(e,t){let n=t(e.context);if(!n)throw Error(`No active model is available for autocompact summarization.`);let r=await e.context.modelRegistry.getApiKeyAndHeaders(n.model);if(!r.ok)throw Error(r.error);let i=e.context.modelRegistry.getProvider(n.model.provider);if(!i)throw Error(`No provider is registered for "${n.model.provider}" in this session.`);return(0,o.generateSummary)(e.messages,n.model,o.DEFAULT_COMPACTION_SETTINGS.reserveTokens,r.apiKey,r.headers,e.signal,e.instructions,e.previousCheckpoint,n.thinkingLevel,(e,t,n)=>i.streamSimple(e,t,n),r.env)}function O(e,t,n=`info`){e?.hasUI&&e.ui.notify(t,n)}function k(a,s={}){let p=s.resolveModel??E,h=s.generateCheckpoint??(e=>D(e,p)),_=s.telemetry??r.createAutocompactTelemetry(),x=s.doomIntegrations??!0,w=new Set,k=new Set,A=new Set,j=!0,M=0,N=t.createInitialState(),P,F,I,L,R=!1,z=async()=>{j=!1,M+=1,F?.abort(Error(`Autocompact runtime is shutting down.`)),F=void 0,await Promise.allSettled(A),I=void 0,L=void 0,P=void 0,w.clear(),k.clear(),N=t.createInitialState(),R=!1,await _.shutdown()},B=e=>{e.inject([c.DOOM_CONTEXT_CONTRIBUTIONS_SERVICE],e=>{let t=(0,c.requireDoomContextContributions)(e);return L=t,()=>{L===t&&(L=void 0)}}),x&&e.inject([l.DOOM_UI_HUB_SERVICE],e=>{let t=(0,l.requireDoomUiHub)(e).registerFooter({source:n.FOOTER_SOURCE,id:`autocompact`,order:20});return I=t,()=>{t.dispose(),I===t&&(I=void 0)}})},V=e=>{if(!j)return;let t=N.phase===n.STATE_PHASE.checkpointPending?`summarizing`:N.phase===n.STATE_PHASE.checkpointReady?`applying`:void 0;I?.update(t?{fullText:`Compacting p${N.pass}`,compactText:`C${N.pass}`}:void 0);let r=e??P;r?.hasUI&&r.ui.setStatus(n.STATUS_KEY,t?`Compacting pass ${N.pass} (${t})…`:void 0)},H=()=>{j&&(a.appendEntry(e.STATE_CUSTOM_TYPE,{...N}),V())},U=()=>{delete N.requestId,delete N.snapshotLeafId,delete N.snapshotTokens,delete N.pendingCheckpoint,delete N.compactionPass},W=e=>{N.checkpointQueue=N.checkpointQueue.filter(t=>t!==e)},G=e=>{j&&(N=d(e.sessionManager.getBranch())??t.createInitialState(),!(N.phase===n.STATE_PHASE.checkpointReady&&N.requestId&&N.snapshotLeafId&&N.pendingCheckpoint||N.phase===n.STATE_PHASE.waiting)&&(F?.abort(),F=void 0,N.phase=n.STATE_PHASE.waiting,U(),H()))},ee=t=>{j&&a.sendMessage({customType:e.RESUME_MESSAGE_TYPE,content:`${t} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,display:!1,details:{version:2,cycle:N.cycle,pass:N.pass}},{triggerTurn:!0,deliverAs:`steer`})},K=(e,t)=>{let r=N.invalidAttempts+1,i=r>=3;return N.phase=n.STATE_PHASE.waiting,t&&(N.lastAttemptLeafId=t),i?(W(e),N.exhaustedPasses=[...N.exhaustedPasses,e],N.invalidAttempts=0):N.invalidAttempts=r,U(),H(),{attempts:r,exhausted:i}},te=(e,t)=>{if(!j||e!==N.requestId||N.phase!==n.STATE_PHASE.checkpointPending)return;let r=N.pass,{attempts:i,exhausted:a}=K(r,N.snapshotLeafId),o=t instanceof Error?t.message:String(t);O(P,a?`Doom autocompact summarization pass ${r} failed ${i} times and was abandoned: ${o}`:`Doom autocompact summarization pass ${r} failed: ${o}`,`error`)},ne=(e,t)=>{j&&!R&&(R=!0,_.recordWarning(r.AUTOCOMPACT_EVENT.configurationLoadFailed,t,u(e,{"autocompact.cycle":N.cycle,"autocompact.pass":N.pass})))},q=(e,t,n)=>{if(j)for(let i of t.errors)O(e,`Doom autocompact context contribution degraded (${i.source}/${i.id}): ${i.message}`,`warning`),_.recordWarning(r.AUTOCOMPACT_EVENT.contextContributionDegraded,Error(i.message),{...n,"autocompact.context_contribution.source":i.source,"autocompact.context_contribution.id":i.id,"autocompact.context_contribution.order":i.order})},J=(t,n,r)=>{if(!j)return{contributions:[],contributionErrors:[]};let i=g(L);q(t,i,r);let o=v(n,i);return a.sendMessage({customType:e.RUNTIME_STATE_MESSAGE_TYPE,content:y(o),display:!1,details:{version:2,...o}}),o},re=(i,s)=>{if(!j||!N.requestId||!N.snapshotLeafId||!N.pendingCheckpoint)return!1;let c=s.sessionManager.getBranch(),l=t.projectContextMessages((0,o.buildSessionContext)(c).messages,c).messages,d=t.mergeFileDetails(N,t.fileOperationsFromMessages(l)),p=N.requestId,m=N.cycle,h=t.withCanonicalFileSections(N.pendingCheckpoint,d),g={...d,doomAutocompact:{version:2,cycle:m,pass:i,requestId:p,snapshotLeafId:N.snapshotLeafId,tokensBefore:N.snapshotTokens??s.getContextUsage()?.tokens??0},retainedMessages:t.retainedMessagesAfterSnapshot(c,N.snapshotLeafId)},v=s.isIdle();a.sendMessage({customType:e.CONTEXT_MESSAGE_TYPE,content:h,display:!1,details:g});let y=f(s),x=u(s,{"autocompact.request.id":p,"autocompact.cycle":m,"autocompact.pass":i}),S=J(s,c,x);return v&&a.setLabel(y,`autocompact:c${m}:p${i}`),N.readFiles=d.readFiles,N.modifiedFiles=d.modifiedFiles,delete N.latestCheckpointSnapshotLeafId,N.phase=n.STATE_PHASE.waiting,N.checkpointQueue=[],N.exhaustedPasses=[],N.invalidAttempts=0,N.baselinePending=!0,delete N.lastAttemptLeafId,U(),N.cycle+=1,N.pass=1,H(),_.recordEvent(r.AUTOCOMPACT_EVENT.contextCommitted,u(s,{"autocompact.request.id":p,"autocompact.cycle":m,"autocompact.pass":i,"autocompact.snapshot_leaf_id":g.doomAutocompact.snapshotLeafId,"autocompact.tokens_before":g.doomAutocompact.tokensBefore,"autocompact.message_count.before":l.length,"autocompact.message_count.retained":g.retainedMessages.length,"autocompact.apply_mode":v?`idle`:`turn_end`,...b(S)})),v&&ee(`Asynchronous compaction completed.`),!0},ie=(e,i,a)=>{if(!j)return;let o=M,s=i.sessionManager.getBranch(),c=f(i),l=t.createRequestId(i.sessionManager.getSessionId(),N.cycle,e,c),d=e>1?t.checkpointSummaryFromEntry(t.latestCheckpointArtifactEntry(s)):void 0,p=C(e,s,N.latestCheckpointSnapshotLeafId),v=g(L),y=u(i,{"autocompact.request.id":l,"autocompact.cycle":N.cycle,"autocompact.pass":e,"autocompact.snapshot_leaf_id":c,"autocompact.tokens_before":a,"autocompact.message_count.before":p.length});q(i,v,y),N.phase=n.STATE_PHASE.checkpointPending,N.pass=e,N.requestId=l,N.snapshotLeafId=c,N.snapshotTokens=a,delete N.pendingCheckpoint,delete N.compactionPass,delete N.lastAttemptLeafId,H(),F?.abort(),F=new AbortController;let b=F.signal,x=_.runInSpan(`doom_autocompact.checkpoint`,y,async()=>{await _.recordEvent(r.AUTOCOMPACT_EVENT.checkpointStarted,y);try{let t=await h({messages:p,instructions:S(e,{plan:m(s),contextContributions:v,readFiles:N.readFiles,modifiedFiles:N.modifiedFiles}),...d?{previousCheckpoint:d}:{},context:i,signal:b});if(!j||o!==M)throw b.reason??Error(`Autocompact checkpoint became stale.`);if(!t.trim())throw Error(`Summarization returned an empty checkpoint.`);return await _.recordEvent(r.AUTOCOMPACT_EVENT.checkpointCompleted,{...y,"autocompact.checkpoint.characters":t.length}),t}catch(e){throw j&&o===M&&await _.recordError(r.AUTOCOMPACT_EVENT.checkpointFailed,e,y),e}}).then(e=>{j&&o===M&&l===N.requestId&&N.phase===n.STATE_PHASE.checkpointPending&&(N.phase=n.STATE_PHASE.checkpointReady,N.pendingCheckpoint=e.trim(),H(),P&&Q(P))}).catch(e=>{j&&o===M&&te(l,e)});A.add(x),x.finally(()=>A.delete(x))},Y=e=>{if(!j||N.phase!==n.STATE_PHASE.waiting||e.hasPendingMessages())return!1;let r=T(e.cwd,t=>ne(e,t));if(!r.enabled)return!1;let a=e.getContextUsage();if(!a||a.tokens===null)return!1;if(N.baselinePending)return t.baselineUsageIsSettled(e.sessionManager.getBranch())?(N.baselineTokens=a.tokens,N.baselinePending=!1,H(),!1):!1;let o=f(e);if(N.lastAttemptLeafId===o)return!1;let s=i.resolveModelTokenOverrides(e.model,r.overrides),c=t.effectiveThresholds(a.contextWindow,N.baselineTokens,r.ratios,s);for(let e of[1,2,3])e<N.pass||N.checkpointQueue.includes(e)||N.exhaustedPasses.includes(e)||a.tokens>=c[e]&&N.checkpointQueue.push(e);let l=N.checkpointQueue[0];return l?(ie(l,e,a.tokens),!0):!1},X=(n,r)=>{if(!j)return;let i=N.snapshotLeafId;a.appendEntry(e.CHECKPOINT_MESSAGE_TYPE,{...t.checkpointRequestDetails(N.cycle,n,N.requestId??`completed`),summary:r}),i&&(N.latestCheckpointSnapshotLeafId=i)},Z=e=>{if(!j||N.phase!==n.STATE_PHASE.checkpointReady||!N.requestId||!N.pendingCheckpoint)return`none`;let i=N.pass,a=t.parseCheckpointDecision(N.pendingCheckpoint);if(!t.isStructuredCheckpoint(a.summary)){let t=N.snapshotLeafId,n=N.requestId,{attempts:a,exhausted:o}=K(i,t),s=Error(`Summarization pass ${i} returned an incomplete checkpoint.`);return O(e,o?`Doom autocompact summarization pass ${i} returned an incomplete checkpoint ${a} times and was abandoned.`:`Doom autocompact summarization pass ${i} returned an incomplete checkpoint.`,`error`),_.recordError(r.AUTOCOMPACT_EVENT.checkpointInvalid,s,u(e,{"autocompact.cycle":N.cycle,"autocompact.pass":i,"autocompact.checkpoint.attempts":a,"autocompact.checkpoint.exhausted":o,...n?{"autocompact.request.id":n}:{}})),`invalid`}return N.invalidAttempts=0,i===1?(X(1,a.summary),W(1),N.phase=n.STATE_PHASE.waiting,N.pass=2,U(),H(),`pass1`):i===2&&a.shouldCompact!==!0?(X(2,a.summary),W(2),N.phase=n.STATE_PHASE.waiting,N.pass=3,U(),H(),`deferred`):(N.pendingCheckpoint=a.summary,re(i,e)?`committed`:`invalid`)};function Q(e){j&&(P=e,e.isIdle()&&Z(e)!==`committed`&&Y(e))}let $=e=>{j&&(M+=1,F?.abort(Error(`Autocompact session generation was replaced.`)),F=void 0,w.clear(),k.clear(),P=e,G(e),Q(e))};return{plugin:B,stop:z,events:{context:(e,n)=>{if(!j)return;let i=t.projectContextMessages(e.messages,n.sessionManager.getBranch());if(i.invalidMarker){let e=n.sessionManager.getLeafId()??`@root`;k.has(e)||(k.add(e),_.recordError(r.AUTOCOMPACT_EVENT.contextMarkerInvalid,Error(`Doom autocompact context marker is malformed.`),u(n,{"autocompact.leaf_id":e})));return}if(i.marker)return w.has(i.marker.requestId)||(w.add(i.marker.requestId),_.recordEvent(r.AUTOCOMPACT_EVENT.contextApplied,u(n,{"autocompact.request.id":i.marker.requestId,"autocompact.cycle":i.marker.cycle,"autocompact.pass":i.marker.pass,"autocompact.snapshot_leaf_id":i.marker.snapshotLeafId,"autocompact.tokens_before":i.marker.tokensBefore,"autocompact.message_count.before":e.messages.length,"autocompact.message_count.after":i.messages.length,"autocompact.message_count.retained":i.retainedMessageCount}))),{messages:i.messages}},session_start:(e,t)=>$(t),session_tree:(e,t)=>$(t),turn_end:(e,t)=>{if(j){if(P=t,t.isIdle()){Q(t);return}N.phase===n.STATE_PHASE.checkpointReady&&(e.toolResults?.length??0)>0&&!t.hasPendingMessages()&&Z(t)!==`none`||Y(t)}},agent_settled:(e,t)=>{j&&Q(t)},session_before_compact:e=>{if(j&&e.reason===`threshold`)return N.phase===n.STATE_PHASE.checkpointPending||N.phase===n.STATE_PHASE.checkpointReady||N.baselinePending?{cancel:!0}:void 0},session_compact:(e,i)=>{if(!j)return;M+=1,F?.abort(),F=void 0;let o=t.fileDetailsFromUnknown(e.compactionEntry.details),s=t.mergeFileDetails(N,void 0,o);N.readFiles=s.readFiles,N.modifiedFiles=s.modifiedFiles,delete N.latestCheckpointSnapshotLeafId,N.baselinePending=!0,N.phase=n.STATE_PHASE.waiting,U(),N.checkpointQueue=[],N.exhaustedPasses=[],N.invalidAttempts=0,delete N.lastAttemptLeafId,a.setLabel(e.compactionEntry.id,`autocompact:c${N.cycle}:external`);let c=N.cycle,l=u(i,{"autocompact.cycle":c,"autocompact.native.reason":e.reason}),d=J(i,i.sessionManager.getBranch(),l);N.cycle+=1,N.pass=1,H(),_.recordEvent(r.AUTOCOMPACT_EVENT.nativeCompactionCompleted,u(i,{"autocompact.cycle":c,"autocompact.native.reason":e.reason,"autocompact.native.from_extension":e.fromExtension,"autocompact.tokens_before":e.compactionEntry.tokensBefore,...b(d)}))}}}}exports.autocompactRuntimeConfig=T,exports.createAutocompactRuntime=k,exports.generateCheckpointWithPi=D,exports.resolveDoomSummarizationModel=E;
43
+ ## Critical Context`}function C(e,n,r){let i=t.projectContextMessages((0,o.buildSessionContext)(n).messages,n).messages;if(e===1||!r)return i;let a=n.findIndex(e=>e.id===r);return a===-1?i:n.slice(a+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>(0,o.sessionEntryToContextMessages)(e))}const w={enabled:!0,ratios:{},overrides:[]};function T(e,t){let n;try{n=(0,s.loadDoomConfig)((0,s.getHarnessState)().root??e).modes}catch(e){return process.emitWarning(`Doom autocompact configuration could not be loaded; using the active session model instead.`),t?.(e),w}let r=n?.autocompact,i=(r&&(r.model!==void 0||r.thinking!==void 0)?{...r.model?{model:r.model}:{},...r.thinking?{thinking:r.thinking}:{}}:void 0)??n?.planning?.subagents,a=r?.thresholds;return{enabled:r?.enabled??!0,...i?{agent:i}:{},ratios:{...a?.pass1===void 0?{}:{1:a.pass1},...a?.pass2===void 0?{}:{2:a.pass2},...a?.pass3===void 0?{}:{3:a.pass3}},overrides:r?.overrides??[]}}function E(e){let t=T(e.cwd).agent,n=t?.model?a.parseModelReference(t.model):void 0,r=n?e.modelRegistry.find(n.provider,n.modelId):void 0,i=r??e.model;if(!i)return;let o=t?.thinking??(r?n?.thinking:void 0)??e.thinkingLevel;return{model:i,...o?{thinkingLevel:o}:{}}}async function D(e,t){let n=t(e.context);if(!n)throw Error(`No active model is available for autocompact summarization.`);let r=await e.context.modelRegistry.getApiKeyAndHeaders(n.model);if(!r.ok)throw Error(r.error);let i=e.context.modelRegistry.getProvider(n.model.provider);if(!i)throw Error(`No provider is registered for "${n.model.provider}" in this session.`);return(0,o.generateSummary)(e.messages,n.model,o.DEFAULT_COMPACTION_SETTINGS.reserveTokens,r.apiKey,r.headers,e.signal,e.instructions,e.previousCheckpoint,n.thinkingLevel,(e,t,n)=>i.streamSimple(e,t,n),r.env)}function O(e,t,n=`info`){e?.hasUI&&e.ui.notify(t,n)}function k(a,s={}){let p=s.resolveModel??E,h=s.generateCheckpoint??(e=>D(e,p)),_=s.telemetry??r.createAutocompactTelemetry(),x=s.doomIntegrations??!0,w=new Set,k=new Set,A=new Set,j=!0,M=0,N=t.createInitialState(),P,F,I,L,R=!1,z=async()=>{j=!1,M+=1,F?.abort(Error(`Autocompact runtime is shutting down.`)),F=void 0,await Promise.allSettled(A),I=void 0,L=void 0,P=void 0,w.clear(),k.clear(),N=t.createInitialState(),R=!1,await _.shutdown()},B=e=>{e.inject([c.DOOM_CONTEXT_CONTRIBUTIONS_SERVICE],e=>{let t=(0,c.requireDoomContextContributions)(e);return L=t,()=>{L===t&&(L=void 0)}}),x&&e.inject([l.DOOM_UI_HUB_SERVICE],e=>{let t=(0,l.requireDoomUiHub)(e).registerFooter({source:n.FOOTER_SOURCE,id:`autocompact`,order:20});return I=t,()=>{t.dispose(),I===t&&(I=void 0)}})},V=e=>{if(!j)return;let t=N.phase===n.STATE_PHASE.checkpointPending?`summarizing`:N.phase===n.STATE_PHASE.checkpointReady?`applying`:void 0;I?.update(t?{fullText:`Compacting p${N.pass}`,compactText:`C${N.pass}`}:void 0);let r=e??P;r?.hasUI&&r.ui.setStatus(n.STATUS_KEY,t?`Compacting pass ${N.pass} (${t})…`:void 0)},H=()=>{j&&(a.appendEntry(e.STATE_CUSTOM_TYPE,{...N}),V())},U=()=>{delete N.requestId,delete N.snapshotLeafId,delete N.snapshotTokens,delete N.pendingCheckpoint,delete N.compactionPass},W=e=>{N.checkpointQueue=N.checkpointQueue.filter(t=>t!==e)},G=e=>{j&&(N=d(e.sessionManager.getBranch())??t.createInitialState(),!(N.phase===n.STATE_PHASE.checkpointReady&&N.requestId&&N.snapshotLeafId&&N.pendingCheckpoint||N.phase===n.STATE_PHASE.waiting)&&(F?.abort(),F=void 0,N.phase=n.STATE_PHASE.waiting,U(),H()))},ee=t=>{j&&a.sendMessage({customType:e.RESUME_MESSAGE_TYPE,content:`${t} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,display:!1,details:{version:2,cycle:N.cycle,pass:N.pass}},{triggerTurn:!0,deliverAs:`steer`})},K=(e,t)=>{let r=N.invalidAttempts+1,i=r>=3;return N.phase=n.STATE_PHASE.waiting,t&&(N.lastAttemptLeafId=t),i?(W(e),N.exhaustedPasses=[...N.exhaustedPasses,e],N.invalidAttempts=0):N.invalidAttempts=r,U(),H(),{attempts:r,exhausted:i}},te=(e,t)=>{if(!j||e!==N.requestId||N.phase!==n.STATE_PHASE.checkpointPending)return;let r=N.pass,{attempts:i,exhausted:a}=K(r,N.snapshotLeafId),o=t instanceof Error?t.message:String(t);O(P,a?`Doom autocompact summarization pass ${r} failed ${i} times and was abandoned: ${o}`:`Doom autocompact summarization pass ${r} failed: ${o}`,`error`)},ne=(e,t)=>{j&&!R&&(R=!0,_.recordWarning(r.AUTOCOMPACT_EVENT.configurationLoadFailed,t,u(e,{"autocompact.cycle":N.cycle,"autocompact.pass":N.pass})))},q=(e,t,n)=>{if(j)for(let i of t.errors)O(e,`Doom autocompact context contribution degraded (${i.source}/${i.id}): ${i.message}`,`warning`),_.recordWarning(r.AUTOCOMPACT_EVENT.contextContributionDegraded,Error(i.message),{...n,"autocompact.context_contribution.source":i.source,"autocompact.context_contribution.id":i.id,"autocompact.context_contribution.order":i.order})},J=(t,n,r)=>{if(!j)return{contributions:[],contributionErrors:[]};let i=g(L);q(t,i,r);let o=v(n,i);return a.sendMessage({customType:e.RUNTIME_STATE_MESSAGE_TYPE,content:y(o),display:!1,details:{version:2,...o}}),o},re=(i,s)=>{if(!j||!N.requestId||!N.snapshotLeafId||!N.pendingCheckpoint)return!1;let c=s.sessionManager.getBranch(),l=t.projectContextMessages((0,o.buildSessionContext)(c).messages,c).messages,d=t.mergeFileDetails(N,t.fileOperationsFromMessages(l)),p=N.requestId,m=N.cycle,h=t.withCanonicalFileSections(N.pendingCheckpoint,d),g={...d,doomAutocompact:{version:2,cycle:m,pass:i,requestId:p,snapshotLeafId:N.snapshotLeafId,tokensBefore:N.snapshotTokens??s.getContextUsage()?.tokens??0},retainedMessages:t.retainedMessagesAfterSnapshot(c,N.snapshotLeafId)},v=s.isIdle();a.sendMessage({customType:e.CONTEXT_MESSAGE_TYPE,content:h,display:!1,details:g});let y=f(s),x=u(s,{"autocompact.request.id":p,"autocompact.cycle":m,"autocompact.pass":i}),S=J(s,c,x);return v&&a.setLabel(y,`autocompact:c${m}:p${i}`),N.readFiles=d.readFiles,N.modifiedFiles=d.modifiedFiles,delete N.latestCheckpointSnapshotLeafId,N.phase=n.STATE_PHASE.waiting,N.checkpointQueue=[],N.exhaustedPasses=[],N.invalidAttempts=0,N.baselinePending=!0,delete N.lastAttemptLeafId,U(),N.cycle+=1,N.pass=1,H(),_.recordEvent(r.AUTOCOMPACT_EVENT.contextCommitted,u(s,{"autocompact.request.id":p,"autocompact.cycle":m,"autocompact.pass":i,"autocompact.snapshot_leaf_id":g.doomAutocompact.snapshotLeafId,"autocompact.tokens_before":g.doomAutocompact.tokensBefore,"autocompact.message_count.before":l.length,"autocompact.message_count.retained":g.retainedMessages.length,"autocompact.apply_mode":v?`idle`:`turn_end`,...b(S)})),v&&ee(`Asynchronous compaction completed.`),!0},ie=(e,i,a)=>{if(!j)return;let o=M,s=i.sessionManager.getBranch(),c=f(i),l=t.createRequestId(i.sessionManager.getSessionId(),N.cycle,e,c),d=e>1?t.checkpointSummaryFromEntry(t.latestCheckpointArtifactEntry(s)):void 0,p=C(e,s,N.latestCheckpointSnapshotLeafId),v=g(L),y=u(i,{"autocompact.request.id":l,"autocompact.cycle":N.cycle,"autocompact.pass":e,"autocompact.snapshot_leaf_id":c,"autocompact.tokens_before":a,"autocompact.message_count.before":p.length});q(i,v,y),N.phase=n.STATE_PHASE.checkpointPending,N.pass=e,N.requestId=l,N.snapshotLeafId=c,N.snapshotTokens=a,delete N.pendingCheckpoint,delete N.compactionPass,delete N.lastAttemptLeafId,H(),F?.abort(),F=new AbortController;let b=F.signal,x=_.runInSpan(`doom_autocompact.checkpoint`,y,async()=>{await _.recordEvent(r.AUTOCOMPACT_EVENT.checkpointStarted,y);try{let t=await h({messages:p,instructions:S(e,{plan:m(s),contextContributions:v,readFiles:N.readFiles,modifiedFiles:N.modifiedFiles}),...d?{previousCheckpoint:d}:{},context:i,signal:b});if(!j||o!==M)throw b.reason??Error(`Autocompact checkpoint became stale.`);if(!t.trim())throw Error(`Summarization returned an empty checkpoint.`);return await _.recordEvent(r.AUTOCOMPACT_EVENT.checkpointCompleted,{...y,"autocompact.checkpoint.characters":t.length}),t}catch(e){throw j&&o===M&&await _.recordError(r.AUTOCOMPACT_EVENT.checkpointFailed,e,y),e}}).then(e=>{j&&o===M&&l===N.requestId&&N.phase===n.STATE_PHASE.checkpointPending&&(N.phase=n.STATE_PHASE.checkpointReady,N.pendingCheckpoint=e.trim(),H(),P&&Q(P))}).catch(e=>{j&&o===M&&te(l,e)});A.add(x),x.finally(()=>A.delete(x))},Y=e=>{if(!j||N.phase!==n.STATE_PHASE.waiting||e.hasPendingMessages())return!1;let r=T(e.cwd,t=>ne(e,t));if(!r.enabled)return!1;let a=e.getContextUsage();if(!a||a.tokens===null)return!1;if(N.baselinePending)return t.baselineUsageIsSettled(e.sessionManager.getBranch())?(N.baselineTokens=a.tokens,N.baselinePending=!1,H(),!1):!1;let o=f(e);if(N.lastAttemptLeafId===o)return!1;let s=i.resolveModelTokenOverrides(e.model,r.overrides),c=t.effectiveThresholds(a.contextWindow,N.baselineTokens,r.ratios,s);for(let e of[1,2,3])e<N.pass||N.checkpointQueue.includes(e)||N.exhaustedPasses.includes(e)||a.tokens>=c[e]&&N.checkpointQueue.push(e);let l=N.checkpointQueue[0];return l?(ie(l,e,a.tokens),!0):!1},X=(n,r)=>{if(!j)return;let i=N.snapshotLeafId;a.appendEntry(e.CHECKPOINT_MESSAGE_TYPE,{...t.checkpointRequestDetails(N.cycle,n,N.requestId??`completed`),summary:r}),i&&(N.latestCheckpointSnapshotLeafId=i)},Z=e=>{if(!j||N.phase!==n.STATE_PHASE.checkpointReady||!N.requestId||!N.pendingCheckpoint)return`none`;let i=N.pass,a=t.parseCheckpointDecision(N.pendingCheckpoint);if(!t.isStructuredCheckpoint(a.summary)){let t=N.snapshotLeafId,n=N.requestId,{attempts:a,exhausted:o}=K(i,t),s=Error(`Summarization pass ${i} returned an incomplete checkpoint.`);return O(e,o?`Doom autocompact summarization pass ${i} returned an incomplete checkpoint ${a} times and was abandoned.`:`Doom autocompact summarization pass ${i} returned an incomplete checkpoint.`,`error`),_.recordError(r.AUTOCOMPACT_EVENT.checkpointInvalid,s,u(e,{"autocompact.cycle":N.cycle,"autocompact.pass":i,"autocompact.checkpoint.attempts":a,"autocompact.checkpoint.exhausted":o,...n?{"autocompact.request.id":n}:{}})),`invalid`}return N.invalidAttempts=0,i===1?(X(1,a.summary),W(1),N.phase=n.STATE_PHASE.waiting,N.pass=2,U(),H(),`pass1`):i===2&&a.shouldCompact!==!0?(X(2,a.summary),W(2),N.phase=n.STATE_PHASE.waiting,N.pass=3,U(),H(),`deferred`):(N.pendingCheckpoint=a.summary,re(i,e)?`committed`:`invalid`)};function Q(e){j&&(P=e,e.isIdle()&&Z(e)!==`committed`&&Y(e))}let $=e=>{j&&(M+=1,F?.abort(Error(`Autocompact session generation was replaced.`)),F=void 0,w.clear(),k.clear(),P=e,G(e),Q(e))},ae=(e,n)=>{if(!j)return;let i=t.projectContextMessages(e.messages,n.sessionManager.getBranch());if(i.invalidMarker){let e=n.sessionManager.getLeafId()??`@root`;k.has(e)||(k.add(e),_.recordError(r.AUTOCOMPACT_EVENT.contextMarkerInvalid,Error(`Doom autocompact context marker is malformed.`),u(n,{"autocompact.leaf_id":e})));return}if(i.marker)return w.has(i.marker.requestId)||(w.add(i.marker.requestId),_.recordEvent(r.AUTOCOMPACT_EVENT.contextApplied,u(n,{"autocompact.request.id":i.marker.requestId,"autocompact.cycle":i.marker.cycle,"autocompact.pass":i.marker.pass,"autocompact.snapshot_leaf_id":i.marker.snapshotLeafId,"autocompact.tokens_before":i.marker.tokensBefore,"autocompact.message_count.before":e.messages.length,"autocompact.message_count.after":i.messages.length,"autocompact.message_count.retained":i.retainedMessageCount}))),{messages:i.messages}};return{plugin:B,stop:z,events:{context:(e,t)=>{let n=Date.now();try{return ae(e,t)}finally{let i=Date.now()-n;i>=25&&_.recordEvent(r.AUTOCOMPACT_EVENT.contextHookSlow,u(t,{hook_ms:i,"autocompact.message_count":e.messages.length}))}},session_start:(e,t)=>$(t),session_tree:(e,t)=>$(t),turn_end:(e,t)=>{if(j){if(P=t,t.isIdle()){Q(t);return}N.phase===n.STATE_PHASE.checkpointReady&&(e.toolResults?.length??0)>0&&!t.hasPendingMessages()&&Z(t)!==`none`||Y(t)}},agent_settled:(e,t)=>{j&&Q(t)},session_before_compact:e=>{if(j&&e.reason===`threshold`)return N.phase===n.STATE_PHASE.checkpointPending||N.phase===n.STATE_PHASE.checkpointReady||N.baselinePending?{cancel:!0}:void 0},session_compact:(e,i)=>{if(!j)return;M+=1,F?.abort(),F=void 0;let o=t.fileDetailsFromUnknown(e.compactionEntry.details),s=t.mergeFileDetails(N,void 0,o);N.readFiles=s.readFiles,N.modifiedFiles=s.modifiedFiles,delete N.latestCheckpointSnapshotLeafId,N.baselinePending=!0,N.phase=n.STATE_PHASE.waiting,U(),N.checkpointQueue=[],N.exhaustedPasses=[],N.invalidAttempts=0,delete N.lastAttemptLeafId,a.setLabel(e.compactionEntry.id,`autocompact:c${N.cycle}:external`);let c=N.cycle,l=u(i,{"autocompact.cycle":c,"autocompact.native.reason":e.reason}),d=J(i,i.sessionManager.getBranch(),l);N.cycle+=1,N.pass=1,H(),_.recordEvent(r.AUTOCOMPACT_EVENT.nativeCompactionCompleted,u(i,{"autocompact.cycle":c,"autocompact.native.reason":e.reason,"autocompact.native.from_extension":e.fromExtension,"autocompact.tokens_before":e.compactionEntry.tokensBefore,...b(d)}))}}}}exports.autocompactRuntimeConfig=T,exports.createAutocompactRuntime=k,exports.generateCheckpointWithPi=D,exports.resolveDoomSummarizationModel=E;
44
44
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["parseState","ROOT_WORKING_LEAF","DOOM_CONTEXT_CONTRIBUTIONS_SERVICE","projectContextMessages","buildSessionContext","sessionEntryToContextMessages","loadDoomConfig","getHarnessState","parseModelReference","generateSummary","DEFAULT_COMPACTION_SETTINGS","createAutocompactTelemetry","createInitialState","requireDoomContextContributions","DOOM_UI_HUB_SERVICE","requireDoomUiHub","FOOTER_SOURCE","STATE_PHASE","STATUS_KEY","STATE_CUSTOM_TYPE","RESUME_MESSAGE_TYPE","AUTOCOMPACT_EVENT","RUNTIME_STATE_MESSAGE_TYPE","mergeFileDetails","fileOperationsFromMessages","withCanonicalFileSections","retainedMessagesAfterSnapshot","CONTEXT_MESSAGE_TYPE","createRequestId","checkpointSummaryFromEntry","latestCheckpointArtifactEntry","baselineUsageIsSettled","resolveModelTokenOverrides","effectiveThresholds","CHECKPOINT_MESSAGE_TYPE","checkpointRequestDetails","parseCheckpointDecision","isStructuredCheckpoint","fileDetailsFromUnknown"],"sources":["../../../src/services/autocompactRuntime/index.ts"],"sourcesContent":["import {\n getHarnessState,\n loadDoomConfig,\n type AutocompactOverrideConfig,\n type PlanningAgentConfig,\n} from '@agimon-ai/doompi-config';\nimport {\n DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n requireDoomContextContributions,\n type DoomContextContributionEntry,\n type DoomContextContributionError,\n type DoomContextContributionsService,\n type DoomContextContributionsSnapshot,\n} from '@agimon-ai/doompi-core/context-contributions';\nimport type { DoomFooterContributionHandle } from '@agimon-ai/doompi-core/footer';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/ui-hub';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext, SessionEntry } from '@earendil-works/pi-coding-agent';\nimport {\n buildSessionContext,\n DEFAULT_COMPACTION_SETTINGS,\n generateSummary,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\n\nimport {\n CHECKPOINT_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n MAX_INVALID_CHECKPOINT_ATTEMPTS,\n RESUME_MESSAGE_TYPE,\n RUNTIME_STATE_MESSAGE_TYPE,\n STATE_CUSTOM_TYPE,\n STATE_VERSION,\n} from '../../constants/autocompact';\nimport {\n ROOT_WORKING_LEAF,\n PLAN_DOCUMENT_ENTRY,\n FOOTER_SOURCE,\n FOOTER_ORDER,\n STATUS_KEY,\n STATE_PHASE,\n} from '../../constants/runtime';\nimport type {\n AutocompactContextDetails,\n AutocompactPass,\n AutocompactRatioOverrides,\n AutocompactState,\n} from '../../types/autocompact';\nimport type { AutocompactEventAttributes, AutocompactTelemetry } from '../autocompactTelemetry';\nimport { AUTOCOMPACT_EVENT, createAutocompactTelemetry } from '../autocompactTelemetry';\nimport {\n baselineUsageIsSettled,\n checkpointRequestDetails,\n checkpointSummaryFromEntry,\n createInitialState,\n createRequestId,\n fileDetailsFromUnknown,\n fileOperationsFromMessages,\n isStructuredCheckpoint,\n latestCheckpointArtifactEntry,\n mergeFileDetails,\n parseCheckpointDecision,\n parseState,\n projectContextMessages,\n retainedMessagesAfterSnapshot,\n effectiveThresholds,\n withCanonicalFileSections,\n} from '../compactionPolicy';\nimport { resolveModelTokenOverrides } from '../modelOverrides';\nimport { parseModelReference, type SummarizationModel } from '../summarizationModel';\nimport type { AutocompactRuntime } from './type';\ntype CheckpointCapture = 'none' | 'pass1' | 'committed' | 'deferred' | 'invalid';\ntype CheckpointMessages = ReturnType<typeof buildSessionContext>['messages'];\n\ninterface PlanSnapshot {\n content: string;\n path: string;\n}\n\ninterface SteeringSnapshot {\n plan?: PlanSnapshot;\n contextContributions: DoomContextContributionsSnapshot;\n readFiles: string[];\n modifiedFiles: string[];\n}\n\ninterface RuntimeStateSnapshot {\n planPath?: string;\n contributions: readonly DoomContextContributionEntry[];\n contributionErrors: readonly DoomContextContributionError[];\n}\n\ninterface CheckpointGenerationInput {\n messages: CheckpointMessages;\n instructions: string;\n previousCheckpoint?: string;\n context: ExtensionContext;\n signal: AbortSignal;\n}\n\nexport interface AutocompactDependencies {\n generateCheckpoint?: (input: CheckpointGenerationInput) => Promise<string>;\n resolveModel?: (context: ExtensionContext) => SummarizationModel | undefined;\n telemetry?: AutocompactTelemetry;\n doomIntegrations?: boolean;\n}\n\nfunction telemetryAttributes(\n context: ExtensionContext,\n attributes: AutocompactEventAttributes = {},\n): AutocompactEventAttributes {\n return {\n 'pi.session.id': context.sessionManager.getSessionId(),\n ...attributes,\n };\n}\n\nfunction latestPersistedState(branch: SessionEntry[]): AutocompactState | undefined {\n for (let index = branch.length - 1; index >= 0; index -= 1) {\n const entry = branch[index];\n if (entry?.type !== 'custom' || entry.customType !== STATE_CUSTOM_TYPE) continue;\n const parsed = parseState(entry.data);\n if (parsed) return parsed;\n }\n return undefined;\n}\n\nfunction workingLeafId(ctx: ExtensionContext): string {\n for (const entry of ctx.sessionManager.getBranch().toReversed()) {\n if (entry.type === 'custom' && entry.customType === STATE_CUSTOM_TYPE) continue;\n if (entry.type === 'label') continue;\n return entry.id;\n }\n return ROOT_WORKING_LEAF;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction latestPlanSnapshot(branch: SessionEntry[]): PlanSnapshot | undefined {\n for (const entry of branch.toReversed()) {\n if (entry.type !== 'custom' || entry.customType !== PLAN_DOCUMENT_ENTRY) continue;\n if (!entry.data || typeof entry.data !== 'object') return undefined;\n const data = entry.data as Record<string, unknown>;\n if (typeof data.content !== 'string' || typeof data.path !== 'string') return undefined;\n return { content: data.content, path: data.path };\n }\n return undefined;\n}\n\nconst EMPTY_CONTEXT_CONTRIBUTIONS: DoomContextContributionsSnapshot = Object.freeze({\n entries: Object.freeze([]),\n errors: Object.freeze([]),\n});\n\nfunction readContextContributionsSnapshot(\n service: DoomContextContributionsService | undefined,\n): DoomContextContributionsSnapshot {\n if (!service) return EMPTY_CONTEXT_CONTRIBUTIONS;\n try {\n return service.snapshot();\n } catch (error) {\n return {\n entries: [],\n errors: [\n {\n source: DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n id: 'service-snapshot',\n label: 'Context contributions',\n order: 0,\n message: errorMessage(error),\n },\n ],\n };\n }\n}\n\nfunction formatContextContributions(snapshot: DoomContextContributionsSnapshot): string {\n const sections = snapshot.entries.map((entry) => `### ${entry.label}\\n${entry.text}`);\n sections.push(...snapshot.errors.map((error) => `### ${error.label}\\n(unavailable: ${error.message})`));\n return sections.length > 0 ? sections.join('\\n\\n') : '(no registered context contributions)';\n}\n\nfunction runtimeStateSnapshot(\n branch: SessionEntry[],\n contextContributions: DoomContextContributionsSnapshot,\n): RuntimeStateSnapshot {\n const plan = latestPlanSnapshot(branch);\n return {\n ...(plan ? { planPath: plan.path } : {}),\n contributions: contextContributions.entries,\n contributionErrors: contextContributions.errors,\n };\n}\n\nfunction formatRuntimeState(snapshot: RuntimeStateSnapshot): string {\n const plan = snapshot.planPath\n ? `Source: ${snapshot.planPath}\\nExact plan content is restored separately by Doom Plan.`\n : '(no active plan document)';\n return `<compaction-runtime-state>\nAuthoritative runtime state captured when compaction committed. Use it to resume coordination without reconstructing state from the summary.\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions({ entries: snapshot.contributions, errors: snapshot.contributionErrors })}\n</context-contributions>\n</compaction-runtime-state>`;\n}\n\nfunction runtimeTelemetryAttributes(snapshot: RuntimeStateSnapshot): AutocompactEventAttributes {\n return {\n 'autocompact.runtime.plan_present': Boolean(snapshot.planPath),\n 'autocompact.runtime.contribution_count': snapshot.contributions.length,\n 'autocompact.runtime.contribution_error_count': snapshot.contributionErrors.length,\n };\n}\n\nfunction steeringEnvelope(snapshot: SteeringSnapshot): string {\n const plan = snapshot.plan\n ? `Source: ${snapshot.plan.path}\\n\\n${snapshot.plan.content}`\n : '(no active plan document)';\n const importantContext = [\n snapshot.readFiles.length > 0 ? `Read files: ${snapshot.readFiles.join(', ')}` : undefined,\n snapshot.modifiedFiles.length > 0 ? `Modified files: ${snapshot.modifiedFiles.join(', ')}` : undefined,\n ].filter((value): value is string => Boolean(value));\n\n return `<compaction-steering priority=\"user,plan,context-contributions,important-context,recent-messages\">\n<user-prompt source=\"conversation\">\nTreat the user's explicit goals, constraints, corrections, and preferences in the conversation as authoritative. Newer user instructions override older ones.\n</user-prompt>\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions(snapshot.contextContributions)}\n</context-contributions>\n<important-context>\n${importantContext.length > 0 ? importantContext.join('\\n') : '(none recorded outside the conversation)'}\n</important-context>\n</compaction-steering>`;\n}\n\nfunction checkpointInstructions(pass: AutocompactPass, steering: SteeringSnapshot): string {\n const decision =\n pass === 2\n ? 'Start with exactly <shouldCompact>true</shouldCompact> or <shouldCompact>false</shouldCompact>. Use true when the staged summary safely retains the important parent context. Use false only when it is not yet sufficient for safe compaction.\\n\\n'\n : '';\n\n // Summarization is a tool-less single LLM call, so instructions describe only what to\n // produce. Directives aimed at an implementing agent leak into the checkpoint body.\n return `Create Doom autocompact checkpoint pass ${pass}.\n\n${steeringEnvelope(steering)}\n\nApply the steering evidence in priority order. Do not invent plan or contributed runtime state. Preserve verified facts and mark unresolved inference explicitly. Newer evidence replaces superseded information.\n\n${decision}Return only the decision tag when required, followed by a concise structured checkpoint using every heading below. Keep exact goals, constraints, decisions, blockers, commands, errors, file paths, validation evidence, and the immediate next action. Separate verified facts from unresolved inference.\n\n## Goal\n## Constraints & Preferences\n## Progress\n### Done\n### In Progress\n### Blocked\n## Key Decisions\n## Next Steps\n## Critical Context`;\n}\n\nfunction messagesForCheckpoint(\n pass: AutocompactPass,\n branch: SessionEntry[],\n previousSnapshotLeafId: string | undefined,\n): CheckpointMessages {\n const projected = projectContextMessages(buildSessionContext(branch).messages, branch).messages;\n if (pass === 1 || !previousSnapshotLeafId) return projected;\n const snapshotIndex = branch.findIndex((entry) => entry.id === previousSnapshotLeafId);\n if (snapshotIndex === -1) return projected;\n return branch\n .slice(snapshotIndex + 1)\n .filter((entry) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\ninterface AutocompactRuntimeConfig {\n /** Off leaves compaction to Pi; unset is on. */\n enabled: boolean;\n /** The agent that writes the summaries, from autocompact's own keys or planning's. */\n agent?: PlanningAgentConfig;\n ratios: AutocompactRatioOverrides;\n /** Per-model absolute token checkpoints, tried in file order. */\n overrides: AutocompactOverrideConfig[];\n}\n\nconst DEFAULT_RUNTIME_CONFIG: AutocompactRuntimeConfig = { enabled: true, ratios: {}, overrides: [] };\n\n/**\n * What the Doom config says about this package.\n *\n * `modes.autocompact` is read first and `modes.planning.subagents` is the\n * fallback, because summarization borrowed the planning subagent model before\n * it had keys of its own and existing files still spell it that way.\n */\nexport function autocompactRuntimeConfig(\n cwd: string,\n onLoadFailure?: (error: unknown) => void,\n): AutocompactRuntimeConfig {\n let modes: ReturnType<typeof loadDoomConfig>['modes'];\n try {\n modes = loadDoomConfig(getHarnessState().root ?? cwd).modes;\n } catch (error) {\n process.emitWarning('Doom autocompact configuration could not be loaded; using the active session model instead.');\n onLoadFailure?.(error);\n return DEFAULT_RUNTIME_CONFIG;\n }\n const configured = modes?.autocompact;\n const ownAgent: PlanningAgentConfig | undefined =\n configured && (configured.model !== undefined || configured.thinking !== undefined)\n ? {\n ...(configured.model ? { model: configured.model } : {}),\n ...(configured.thinking ? { thinking: configured.thinking } : {}),\n }\n : undefined;\n const agent = ownAgent ?? modes?.planning?.subagents;\n const thresholds = configured?.thresholds;\n return {\n enabled: configured?.enabled ?? true,\n ...(agent ? { agent } : {}),\n ratios: {\n ...(thresholds?.pass1 === undefined ? {} : { 1: thresholds.pass1 }),\n ...(thresholds?.pass2 === undefined ? {} : { 2: thresholds.pass2 }),\n ...(thresholds?.pass3 === undefined ? {} : { 3: thresholds.pass3 }),\n },\n overrides: configured?.overrides ?? [],\n };\n}\n\n/** Explicit Doom model selection honors the configured summarization model. */\nexport function resolveDoomSummarizationModel(ctx: ExtensionContext): SummarizationModel | undefined {\n const configured = autocompactRuntimeConfig(ctx.cwd).agent;\n const reference = configured?.model ? parseModelReference(configured.model) : undefined;\n const configuredModel = reference ? ctx.modelRegistry.find(reference.provider, reference.modelId) : undefined;\n const model = configuredModel ?? ctx.model;\n if (!model) return undefined;\n const thinkingLevel =\n configured?.thinking ?? (configuredModel ? reference?.thinking : undefined) ?? ctx.thinkingLevel;\n return { model, ...(thinkingLevel ? { thinkingLevel } : {}) };\n}\n\n/**\n * Summarization borrows the session's own provider instead of re-resolving one.\n *\n * The selected model can come from a Pi provider extension, and that extension's\n * `streamSimple` closure lives only in this process: it is never in Pi's global api\n * registry, so any other thread or process sees `No API provider registered for api`.\n * Passing the composed provider in as `generateSummary`'s stream function keeps\n * summarization on exactly the path the agent's own requests take.\n */\nexport async function generateCheckpointWithPi(\n input: CheckpointGenerationInput,\n resolveModel: (context: ExtensionContext) => SummarizationModel | undefined,\n): Promise<string> {\n const selection = resolveModel(input.context);\n if (!selection) throw new Error('No active model is available for autocompact summarization.');\n const auth = await input.context.modelRegistry.getApiKeyAndHeaders(selection.model);\n if (!auth.ok) throw new Error(auth.error);\n const provider = input.context.modelRegistry.getProvider(selection.model.provider);\n if (!provider) {\n throw new Error(`No provider is registered for \"${selection.model.provider}\" in this session.`);\n }\n return generateSummary(\n input.messages,\n selection.model,\n DEFAULT_COMPACTION_SETTINGS.reserveTokens,\n auth.apiKey,\n // A null header value suppresses a provider default, which the narrower\n // `generateSummary` signature does not model but every provider honors.\n auth.headers as Record<string, string> | undefined,\n input.signal,\n input.instructions,\n input.previousCheckpoint,\n selection.thinkingLevel,\n (model, context, options) => provider.streamSimple(model, context, options),\n auth.env,\n );\n}\n\nfunction notify(ctx: ExtensionContext | undefined, message: string, level: 'info' | 'warning' | 'error' = 'info') {\n if (ctx?.hasUI) ctx.ui.notify(message, level);\n}\n\nexport function createAutocompactRuntime(\n pi: ExtensionAPI,\n dependencies: AutocompactDependencies = {},\n): AutocompactRuntime {\n const resolveModel = dependencies.resolveModel ?? resolveDoomSummarizationModel;\n const generateCheckpoint =\n dependencies.generateCheckpoint ??\n ((input: CheckpointGenerationInput) => generateCheckpointWithPi(input, resolveModel));\n const telemetry = dependencies.telemetry ?? createAutocompactTelemetry();\n const doomIntegrations = dependencies.doomIntegrations ?? true;\n const appliedContextRequests = new Set<string>();\n const invalidContextLeaves = new Set<string>();\n const checkpointWork = new Set<Promise<void>>();\n let active = true;\n let sessionGeneration = 0;\n let state = createInitialState();\n let currentContext: ExtensionContext | undefined;\n let checkpointController: AbortController | undefined;\n let footerContribution: DoomFooterContributionHandle | undefined;\n let contextContributionsService: DoomContextContributionsService | undefined;\n let configLoadFailureReported = false;\n\n const stop = async (): Promise<void> => {\n active = false;\n sessionGeneration += 1;\n checkpointController?.abort(new Error('Autocompact runtime is shutting down.'));\n checkpointController = undefined;\n await Promise.allSettled(checkpointWork);\n footerContribution = undefined;\n contextContributionsService = undefined;\n currentContext = undefined;\n appliedContextRequests.clear();\n invalidContextLeaves.clear();\n state = createInitialState();\n configLoadFailureReported = false;\n await telemetry.shutdown();\n };\n\n const plugin = (cordis: Context): void => {\n cordis.inject([DOOM_CONTEXT_CONTRIBUTIONS_SERVICE], (contextContributionsContext) => {\n const service = requireDoomContextContributions(contextContributionsContext);\n contextContributionsService = service;\n return () => {\n if (contextContributionsService === service) contextContributionsService = undefined;\n };\n });\n\n if (doomIntegrations) {\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n const contribution = requireDoomUiHub(uiContext).registerFooter({\n source: FOOTER_SOURCE,\n id: 'autocompact',\n order: FOOTER_ORDER,\n });\n footerContribution = contribution;\n return () => {\n contribution.dispose();\n if (footerContribution === contribution) footerContribution = undefined;\n };\n });\n }\n };\n\n /** Compaction runs off the main thread, so the phase is the only signal the user gets. */\n const refreshStatus = (ctx?: ExtensionContext): void => {\n if (!active) return;\n const phase =\n state.phase === STATE_PHASE.checkpointPending\n ? 'summarizing'\n : state.phase === STATE_PHASE.checkpointReady\n ? 'applying'\n : undefined;\n footerContribution?.update(\n phase ? { fullText: `Compacting p${state.pass}`, compactText: `C${state.pass}` } : undefined,\n );\n const target = ctx ?? currentContext;\n if (target?.hasUI) target.ui.setStatus(STATUS_KEY, phase ? `Compacting pass ${state.pass} (${phase})…` : undefined);\n };\n\n // Every phase transition persists, so this is the one place that keeps the status honest.\n const persist = (): void => {\n if (!active) return;\n pi.appendEntry(STATE_CUSTOM_TYPE, { ...state });\n refreshStatus();\n };\n\n const clearPendingCheckpoint = (): void => {\n delete state.requestId;\n delete state.snapshotLeafId;\n delete state.snapshotTokens;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n };\n\n const completeQueuedPass = (pass: AutocompactPass): void => {\n state.checkpointQueue = state.checkpointQueue.filter((queuedPass) => queuedPass !== pass);\n };\n\n const restore = (ctx: ExtensionContext): void => {\n if (!active) return;\n state = latestPersistedState(ctx.sessionManager.getBranch()) ?? createInitialState();\n const resumablePending =\n state.phase === STATE_PHASE.checkpointReady && state.requestId && state.snapshotLeafId && state.pendingCheckpoint;\n if (resumablePending || state.phase === STATE_PHASE.waiting) return;\n\n checkpointController?.abort();\n checkpointController = undefined;\n state.phase = STATE_PHASE.waiting;\n clearPendingCheckpoint();\n persist();\n };\n\n const resumeAgent = (message: string): void => {\n if (!active) return;\n pi.sendMessage(\n {\n customType: RESUME_MESSAGE_TYPE,\n content: `${message} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,\n display: false,\n details: { version: STATE_VERSION, cycle: state.cycle, pass: state.pass },\n },\n { triggerTurn: true, deliverAs: 'steer' },\n );\n };\n\n /**\n * Both failure paths share one attempt budget: a summarizer that keeps failing would\n * otherwise cost a full summarization call every turn for the rest of the session, so the\n * pass is abandoned once the budget is spent and becomes eligible again on the next cycle.\n */\n const registerFailedAttempt = (\n pass: AutocompactPass,\n failedLeafId: string | undefined,\n ): { attempts: number; exhausted: boolean } => {\n const attempts = state.invalidAttempts + 1;\n const exhausted = attempts >= MAX_INVALID_CHECKPOINT_ATTEMPTS;\n state.phase = STATE_PHASE.waiting;\n if (failedLeafId) state.lastAttemptLeafId = failedLeafId;\n if (exhausted) {\n completeQueuedPass(pass);\n state.exhaustedPasses = [...state.exhaustedPasses, pass];\n state.invalidAttempts = 0;\n } else {\n state.invalidAttempts = attempts;\n }\n clearPendingCheckpoint();\n persist();\n return { attempts, exhausted };\n };\n\n const failCheckpoint = (requestId: string, error: unknown): void => {\n if (!active || requestId !== state.requestId || state.phase !== STATE_PHASE.checkpointPending) return;\n const pass = state.pass;\n const { attempts, exhausted } = registerFailedAttempt(pass, state.snapshotLeafId);\n const reason = error instanceof Error ? error.message : String(error);\n notify(\n currentContext,\n exhausted\n ? `Doom autocompact summarization pass ${pass} failed ${attempts} times and was abandoned: ${reason}`\n : `Doom autocompact summarization pass ${pass} failed: ${reason}`,\n 'error',\n );\n };\n\n // A configuration that cannot be read degrades every later pass silently, and the process\n // warning never reaches the log sink. Report it once per session instead of once per turn.\n const reportConfigLoadFailure = (ctx: ExtensionContext, error: unknown): void => {\n if (!active || configLoadFailureReported) return;\n configLoadFailureReported = true;\n void telemetry.recordWarning(\n AUTOCOMPACT_EVENT.configurationLoadFailed,\n error,\n telemetryAttributes(ctx, { 'autocompact.cycle': state.cycle, 'autocompact.pass': state.pass }),\n );\n };\n\n const reportContributionFailures = (\n ctx: ExtensionContext,\n snapshot: DoomContextContributionsSnapshot,\n attributes: AutocompactEventAttributes,\n ): void => {\n if (!active) return;\n for (const error of snapshot.errors) {\n notify(\n ctx,\n `Doom autocompact context contribution degraded (${error.source}/${error.id}): ${error.message}`,\n 'warning',\n );\n void telemetry.recordWarning(AUTOCOMPACT_EVENT.contextContributionDegraded, new Error(error.message), {\n ...attributes,\n 'autocompact.context_contribution.source': error.source,\n 'autocompact.context_contribution.id': error.id,\n 'autocompact.context_contribution.order': error.order,\n });\n }\n };\n\n const preserveRuntimeState = (\n ctx: ExtensionContext,\n branch: SessionEntry[],\n attributes: AutocompactEventAttributes,\n ): RuntimeStateSnapshot => {\n if (!active) {\n return { contributions: [], contributionErrors: [] };\n }\n const contextContributions = readContextContributionsSnapshot(contextContributionsService);\n reportContributionFailures(ctx, contextContributions, attributes);\n const snapshot = runtimeStateSnapshot(branch, contextContributions);\n pi.sendMessage({\n customType: RUNTIME_STATE_MESSAGE_TYPE,\n content: formatRuntimeState(snapshot),\n display: false,\n details: { version: 2, ...snapshot },\n });\n return snapshot;\n };\n\n const commitCheckpoint = (pass: 2 | 3, ctx: ExtensionContext): boolean => {\n if (!active || !state.requestId || !state.snapshotLeafId || !state.pendingCheckpoint) return false;\n const branch = ctx.sessionManager.getBranch();\n const projected = projectContextMessages(buildSessionContext(branch).messages, branch).messages;\n const fileDetails = mergeFileDetails(state, fileOperationsFromMessages(projected));\n const requestId = state.requestId;\n const cycle = state.cycle;\n const summary = withCanonicalFileSections(state.pendingCheckpoint, fileDetails);\n const details: AutocompactContextDetails = {\n ...fileDetails,\n doomAutocompact: {\n version: STATE_VERSION,\n cycle,\n pass,\n requestId,\n snapshotLeafId: state.snapshotLeafId,\n tokensBefore: state.snapshotTokens ?? ctx.getContextUsage()?.tokens ?? 0,\n },\n retainedMessages: retainedMessagesAfterSnapshot(branch, state.snapshotLeafId),\n };\n\n const committedWhileIdle = ctx.isIdle();\n pi.sendMessage({ customType: CONTEXT_MESSAGE_TYPE, content: summary, display: false, details });\n const contextMessageLeafId = workingLeafId(ctx);\n const runtimeAttributes = telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': cycle,\n 'autocompact.pass': pass,\n });\n const runtimeSnapshot = preserveRuntimeState(ctx, branch, runtimeAttributes);\n // Mid-run the marker is queued as a steering message, so its entry id is not resolvable yet.\n if (committedWhileIdle) pi.setLabel(contextMessageLeafId, `autocompact:c${cycle}:p${pass}`);\n\n state.readFiles = fileDetails.readFiles;\n state.modifiedFiles = fileDetails.modifiedFiles;\n delete state.latestCheckpointSnapshotLeafId;\n state.phase = STATE_PHASE.waiting;\n state.checkpointQueue = [];\n // A compacted context is a fresh ladder: passes abandoned in the previous cycle are eligible again.\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n state.baselinePending = true;\n delete state.lastAttemptLeafId;\n clearPendingCheckpoint();\n state.cycle += 1;\n state.pass = 1;\n persist();\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextCommitted,\n telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': cycle,\n 'autocompact.pass': pass,\n 'autocompact.snapshot_leaf_id': details.doomAutocompact.snapshotLeafId,\n 'autocompact.tokens_before': details.doomAutocompact.tokensBefore,\n 'autocompact.message_count.before': projected.length,\n 'autocompact.message_count.retained': details.retainedMessages.length,\n 'autocompact.apply_mode': committedWhileIdle ? 'idle' : 'turn_end',\n ...runtimeTelemetryAttributes(runtimeSnapshot),\n }),\n );\n // A mid-run commit needs no resume steer: the agent is already continuing.\n if (committedWhileIdle) resumeAgent('Asynchronous compaction completed.');\n return true;\n };\n\n const requestCheckpoint = (pass: AutocompactPass, ctx: ExtensionContext, tokensBefore: number): void => {\n if (!active) return;\n const generation = sessionGeneration;\n const branch = ctx.sessionManager.getBranch();\n const snapshotLeafId = workingLeafId(ctx);\n const requestId = createRequestId(ctx.sessionManager.getSessionId(), state.cycle, pass, snapshotLeafId);\n const previousCheckpoint = pass > 1 ? checkpointSummaryFromEntry(latestCheckpointArtifactEntry(branch)) : undefined;\n const messages = messagesForCheckpoint(pass, branch, state.latestCheckpointSnapshotLeafId);\n const contextContributions = readContextContributionsSnapshot(contextContributionsService);\n const attributes = telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': pass,\n 'autocompact.snapshot_leaf_id': snapshotLeafId,\n 'autocompact.tokens_before': tokensBefore,\n 'autocompact.message_count.before': messages.length,\n });\n reportContributionFailures(ctx, contextContributions, attributes);\n\n state.phase = STATE_PHASE.checkpointPending;\n state.pass = pass;\n state.requestId = requestId;\n state.snapshotLeafId = snapshotLeafId;\n state.snapshotTokens = tokensBefore;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n delete state.lastAttemptLeafId;\n persist();\n\n checkpointController?.abort();\n checkpointController = new AbortController();\n const checkpointSignal = checkpointController.signal;\n const operation = telemetry\n .runInSpan('doom_autocompact.checkpoint', attributes, async () => {\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointStarted, attributes);\n try {\n const checkpoint = await generateCheckpoint({\n messages,\n instructions: checkpointInstructions(pass, {\n plan: latestPlanSnapshot(branch),\n contextContributions,\n readFiles: state.readFiles,\n modifiedFiles: state.modifiedFiles,\n }),\n ...(previousCheckpoint ? { previousCheckpoint } : {}),\n context: ctx,\n signal: checkpointSignal,\n });\n if (!active || generation !== sessionGeneration) {\n throw checkpointSignal.reason ?? new Error('Autocompact checkpoint became stale.');\n }\n if (!checkpoint.trim()) throw new Error('Summarization returned an empty checkpoint.');\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointCompleted, {\n ...attributes,\n 'autocompact.checkpoint.characters': checkpoint.length,\n });\n return checkpoint;\n } catch (error) {\n if (active && generation === sessionGeneration) {\n await telemetry.recordError(AUTOCOMPACT_EVENT.checkpointFailed, error, attributes);\n }\n throw error;\n }\n })\n .then((checkpoint) => {\n if (\n !active ||\n generation !== sessionGeneration ||\n requestId !== state.requestId ||\n state.phase !== STATE_PHASE.checkpointPending\n ) {\n return;\n }\n state.phase = STATE_PHASE.checkpointReady;\n state.pendingCheckpoint = checkpoint.trim();\n persist();\n if (currentContext) processProgress(currentContext);\n })\n .catch((error: unknown) => {\n if (active && generation === sessionGeneration) failCheckpoint(requestId, error);\n });\n checkpointWork.add(operation);\n void operation.finally(() => checkpointWork.delete(operation));\n };\n\n const evaluateUsage = (ctx: ExtensionContext): boolean => {\n if (!active || state.phase !== STATE_PHASE.waiting || ctx.hasPendingMessages()) return false;\n // Read per evaluation rather than once at install, so turning the ladder off\n // or moving a threshold in settings takes effect on the next turn instead of\n // the next session.\n const configured = autocompactRuntimeConfig(ctx.cwd, (error) => reportConfigLoadFailure(ctx, error));\n if (!configured.enabled) return false;\n const usage = ctx.getContextUsage();\n if (!usage || usage.tokens === null) return false;\n if (state.baselinePending) {\n // Reported usage still describes the pre-compaction context until an assistant\n // responds against the projected one, and capturing it early poisons every threshold.\n if (!baselineUsageIsSettled(ctx.sessionManager.getBranch())) return false;\n state.baselineTokens = usage.tokens;\n state.baselinePending = false;\n persist();\n return false;\n }\n const leafId = workingLeafId(ctx);\n if (state.lastAttemptLeafId === leafId) return false;\n\n // The baseline branch above always returns, so by here it is settled for this cycle and the\n // token overrides can be compared against it without re-checking `baselinePending`.\n const tokenOverrides = resolveModelTokenOverrides(ctx.model, configured.overrides);\n const thresholds = effectiveThresholds(\n usage.contextWindow,\n state.baselineTokens,\n configured.ratios,\n tokenOverrides,\n );\n for (const pass of [1, 2, 3] as const) {\n if (pass < state.pass || state.checkpointQueue.includes(pass) || state.exhaustedPasses.includes(pass)) continue;\n if (usage.tokens >= thresholds[pass]) {\n state.checkpointQueue.push(pass);\n }\n }\n const nextPass = state.checkpointQueue[0];\n if (!nextPass) return false;\n requestCheckpoint(nextPass, ctx, usage.tokens);\n return true;\n };\n\n // Staged checkpoints seed the next summarization pass only. They are appended as plain\n // session entries so they never enter the agent's LLM context: delivering them as messages\n // reads like a user instruction and derails the run (\"Checkpoint acknowledged...\").\n const stageCheckpoint = (pass: 1 | 2, summary: string): void => {\n if (!active) return;\n const checkpointSnapshotLeafId = state.snapshotLeafId;\n pi.appendEntry(CHECKPOINT_MESSAGE_TYPE, {\n ...checkpointRequestDetails(state.cycle, pass, state.requestId ?? 'completed'),\n summary,\n });\n if (checkpointSnapshotLeafId) state.latestCheckpointSnapshotLeafId = checkpointSnapshotLeafId;\n };\n\n const captureReadyCheckpoint = (ctx: ExtensionContext): CheckpointCapture => {\n if (!active || state.phase !== STATE_PHASE.checkpointReady || !state.requestId || !state.pendingCheckpoint) {\n return 'none';\n }\n const pass = state.pass;\n const decision = parseCheckpointDecision(state.pendingCheckpoint);\n if (!isStructuredCheckpoint(decision.summary)) {\n const failedLeafId = state.snapshotLeafId;\n const invalidRequestId = state.requestId;\n // A queued pass is retried once per new leaf, so an output the summarizer never formats\n // correctly would otherwise burn a full summarization call every turn for the session.\n const { attempts, exhausted } = registerFailedAttempt(pass, failedLeafId);\n const error = new Error(`Summarization pass ${pass} returned an incomplete checkpoint.`);\n notify(\n ctx,\n exhausted\n ? `Doom autocompact summarization pass ${pass} returned an incomplete checkpoint ${attempts} times and was abandoned.`\n : `Doom autocompact summarization pass ${pass} returned an incomplete checkpoint.`,\n 'error',\n );\n void telemetry.recordError(\n AUTOCOMPACT_EVENT.checkpointInvalid,\n error,\n telemetryAttributes(ctx, {\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': pass,\n 'autocompact.checkpoint.attempts': attempts,\n 'autocompact.checkpoint.exhausted': exhausted,\n ...(invalidRequestId ? { 'autocompact.request.id': invalidRequestId } : {}),\n }),\n );\n return 'invalid';\n }\n\n state.invalidAttempts = 0;\n\n if (pass === 1) {\n stageCheckpoint(1, decision.summary);\n completeQueuedPass(1);\n state.phase = STATE_PHASE.waiting;\n state.pass = 2;\n clearPendingCheckpoint();\n persist();\n return 'pass1';\n }\n\n if (pass === 2 && decision.shouldCompact !== true) {\n stageCheckpoint(2, decision.summary);\n completeQueuedPass(2);\n state.phase = STATE_PHASE.waiting;\n state.pass = 3;\n clearPendingCheckpoint();\n persist();\n return 'deferred';\n }\n\n state.pendingCheckpoint = decision.summary;\n return commitCheckpoint(pass, ctx) ? 'committed' : 'invalid';\n };\n\n function processProgress(ctx: ExtensionContext): void {\n if (!active) return;\n currentContext = ctx;\n if (!ctx.isIdle()) return;\n if (captureReadyCheckpoint(ctx) !== 'committed') evaluateUsage(ctx);\n }\n\n const beginSessionGeneration = (ctx: ExtensionContext): void => {\n if (!active) return;\n sessionGeneration += 1;\n checkpointController?.abort(new Error('Autocompact session generation was replaced.'));\n checkpointController = undefined;\n appliedContextRequests.clear();\n invalidContextLeaves.clear();\n currentContext = ctx;\n restore(ctx);\n processProgress(ctx);\n };\n\n return {\n plugin,\n stop,\n events: {\n context: (event, ctx) => {\n if (!active) return undefined;\n const projection = projectContextMessages(event.messages, ctx.sessionManager.getBranch());\n if (projection.invalidMarker) {\n const leafId = ctx.sessionManager.getLeafId() ?? ROOT_WORKING_LEAF;\n if (!invalidContextLeaves.has(leafId)) {\n invalidContextLeaves.add(leafId);\n void telemetry.recordError(\n AUTOCOMPACT_EVENT.contextMarkerInvalid,\n new Error('Doom autocompact context marker is malformed.'),\n telemetryAttributes(ctx, { 'autocompact.leaf_id': leafId }),\n );\n }\n return undefined;\n }\n if (!projection.marker) return undefined;\n if (!appliedContextRequests.has(projection.marker.requestId)) {\n appliedContextRequests.add(projection.marker.requestId);\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextApplied,\n telemetryAttributes(ctx, {\n 'autocompact.request.id': projection.marker.requestId,\n 'autocompact.cycle': projection.marker.cycle,\n 'autocompact.pass': projection.marker.pass,\n 'autocompact.snapshot_leaf_id': projection.marker.snapshotLeafId,\n 'autocompact.tokens_before': projection.marker.tokensBefore,\n 'autocompact.message_count.before': event.messages.length,\n 'autocompact.message_count.after': projection.messages.length,\n 'autocompact.message_count.retained': projection.retainedMessageCount,\n }),\n );\n }\n return { messages: projection.messages };\n },\n\n session_start: (_event, ctx) => beginSessionGeneration(ctx),\n\n session_tree: (_event, ctx) => beginSessionGeneration(ctx),\n\n turn_end: (event, ctx) => {\n if (!active) return;\n currentContext = ctx;\n if (ctx.isIdle()) {\n processProgress(ctx);\n return;\n }\n // A ready checkpoint must be applied without waiting for the run to finish, otherwise\n // context keeps growing past the window for the rest of a long autonomous run. Tool\n // results confirm the run continues, so the queued marker lands before the next request.\n const canApplyDuringRun =\n state.phase === STATE_PHASE.checkpointReady &&\n (event.toolResults?.length ?? 0) > 0 &&\n !ctx.hasPendingMessages();\n if (canApplyDuringRun && captureReadyCheckpoint(ctx) !== 'none') return;\n evaluateUsage(ctx);\n },\n\n agent_settled: (_event, ctx) => {\n if (!active) return;\n processProgress(ctx);\n },\n\n session_before_compact: (event) => {\n if (!active || event.reason !== 'threshold') return undefined;\n // Native compaction stays cancelled while our own machinery is working, and stays\n // available as the emergency backstop once that machinery has stalled or declined.\n const machineryActive =\n state.phase === STATE_PHASE.checkpointPending ||\n state.phase === STATE_PHASE.checkpointReady ||\n state.baselinePending;\n return machineryActive ? { cancel: true } : undefined;\n },\n\n session_compact: (event, ctx) => {\n if (!active) return;\n sessionGeneration += 1;\n // Native compaction supersedes any summarization still in flight.\n checkpointController?.abort();\n checkpointController = undefined;\n const eventDetails = fileDetailsFromUnknown(event.compactionEntry.details);\n const cumulative = mergeFileDetails(state, undefined, eventDetails);\n state.readFiles = cumulative.readFiles;\n state.modifiedFiles = cumulative.modifiedFiles;\n delete state.latestCheckpointSnapshotLeafId;\n // Reported usage still describes the pre-compaction context here too, so the baseline\n // waits for the first assistant response measured against the compacted one.\n state.baselinePending = true;\n state.phase = STATE_PHASE.waiting;\n clearPendingCheckpoint();\n state.checkpointQueue = [];\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n delete state.lastAttemptLeafId;\n\n pi.setLabel(event.compactionEntry.id, `autocompact:c${state.cycle}:external`);\n const completedCycle = state.cycle;\n const runtimeAttributes = telemetryAttributes(ctx, {\n 'autocompact.cycle': completedCycle,\n 'autocompact.native.reason': event.reason,\n });\n const runtimeSnapshot = preserveRuntimeState(ctx, ctx.sessionManager.getBranch(), runtimeAttributes);\n state.cycle += 1;\n state.pass = 1;\n persist();\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.nativeCompactionCompleted,\n telemetryAttributes(ctx, {\n 'autocompact.cycle': completedCycle,\n 'autocompact.native.reason': event.reason,\n 'autocompact.native.from_extension': event.fromExtension,\n 'autocompact.tokens_before': event.compactionEntry.tokensBefore,\n ...runtimeTelemetryAttributes(runtimeSnapshot),\n }),\n );\n },\n },\n };\n}\n"],"mappings":"wcA2GA,SAAS,EACP,EACA,EAAyC,CAAC,EACd,CAC5B,MAAO,CACL,gBAAiB,EAAQ,eAAe,aAAa,EACrD,GAAG,CACL,CACF,CAEA,SAAS,EAAqB,EAAsD,CAClF,IAAK,IAAI,EAAQ,EAAO,OAAS,EAAG,GAAS,EAAG,IAAY,CAC1D,IAAM,EAAQ,EAAO,GACrB,GAAI,GAAO,OAAS,UAAY,EAAM,aAAA,yBAAkC,SACxE,IAAM,EAASA,EAAAA,WAAW,EAAM,IAAI,EACpC,GAAI,EAAQ,OAAO,CACrB,CAEF,CAEA,SAAS,EAAc,EAA+B,CACpD,IAAK,IAAM,KAAS,EAAI,eAAe,UAAU,CAAC,CAAC,WAAW,EACxD,MAAM,OAAS,UAAY,EAAM,aAAA,2BACjC,EAAM,OAAS,QACnB,OAAO,EAAM,GAEf,OAAOC,EAAAA,iBACT,CAEA,SAAS,EAAa,EAAwB,CAC5C,OAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,CAC9D,CAEA,SAAS,EAAmB,EAAkD,CAC5E,IAAK,IAAM,KAAS,EAAO,WAAW,EAAG,CACvC,GAAI,EAAM,OAAS,UAAY,EAAM,aAAA,8BAAoC,SACzE,GAAI,CAAC,EAAM,MAAQ,OAAO,EAAM,MAAS,SAAU,OACnD,IAAM,EAAO,EAAM,KAEnB,OADI,OAAO,EAAK,SAAY,UAAY,OAAO,EAAK,MAAS,SAAU,OAChE,CAAE,QAAS,EAAK,QAAS,KAAM,EAAK,IAAK,CAClD,CAEF,CAEA,MAAM,EAAgE,OAAO,OAAO,CAClF,QAAS,OAAO,OAAO,CAAC,CAAC,EACzB,OAAQ,OAAO,OAAO,CAAC,CAAC,CAC1B,CAAC,EAED,SAAS,EACP,EACkC,CAClC,GAAI,CAAC,EAAS,OAAO,EACrB,GAAI,CACF,OAAO,EAAQ,SAAS,CAC1B,OAAS,EAAO,CACd,MAAO,CACL,QAAS,CAAC,EACV,OAAQ,CACN,CACE,OAAQC,EAAAA,mCACR,GAAI,mBACJ,MAAO,wBACP,MAAO,EACP,QAAS,EAAa,CAAK,CAC7B,CACF,CACF,CACF,CACF,CAEA,SAAS,EAA2B,EAAoD,CACtF,IAAM,EAAW,EAAS,QAAQ,IAAK,GAAU,OAAO,EAAM,MAAM,IAAI,EAAM,MAAM,EAEpF,OADA,EAAS,KAAK,GAAG,EAAS,OAAO,IAAK,GAAU,OAAO,EAAM,MAAM,kBAAkB,EAAM,QAAQ,EAAE,CAAC,EAC/F,EAAS,OAAS,EAAI,EAAS,KAAK;;CAAM,EAAI,uCACvD,CAEA,SAAS,EACP,EACA,EACsB,CACtB,IAAM,EAAO,EAAmB,CAAM,EACtC,MAAO,CACL,GAAI,EAAO,CAAE,SAAU,EAAK,IAAK,EAAI,CAAC,EACtC,cAAe,EAAqB,QACpC,mBAAoB,EAAqB,MAC3C,CACF,CAEA,SAAS,EAAmB,EAAwC,CAIlE,MAAO;;;EAHM,EAAS,SAClB,WAAW,EAAS,SAAS,2DAC7B,4BAIC;;;EAGL,EAA2B,CAAE,QAAS,EAAS,cAAe,OAAQ,EAAS,kBAAmB,CAAC,EAAE;;4BAGvG,CAEA,SAAS,EAA2B,EAA4D,CAC9F,MAAO,CACL,mCAAoC,EAAQ,EAAS,SACrD,yCAA0C,EAAS,cAAc,OACjE,+CAAgD,EAAS,mBAAmB,MAC9E,CACF,CAEA,SAAS,EAAiB,EAAoC,CAC5D,IAAM,EAAO,EAAS,KAClB,WAAW,EAAS,KAAK,KAAK,MAAM,EAAS,KAAK,UAClD,4BACE,EAAmB,CACvB,EAAS,UAAU,OAAS,EAAI,eAAe,EAAS,UAAU,KAAK,IAAI,IAAM,IAAA,GACjF,EAAS,cAAc,OAAS,EAAI,mBAAmB,EAAS,cAAc,KAAK,IAAI,IAAM,IAAA,EAC/F,CAAC,CAAC,OAAQ,GAA2B,EAAQ,CAAM,EAEnD,MAAO;;;;;EAKP,EAAK;;;EAGL,EAA2B,EAAS,oBAAoB,EAAE;;;EAG1D,EAAiB,OAAS,EAAI,EAAiB,KAAK;CAAI,EAAI,2CAA2C;;uBAGzG,CAEA,SAAS,EAAuB,EAAuB,EAAoC,CACzF,IAAM,EACJ,IAAS,EACL;;EACA,GAIN,MAAO,2CAA2C,EAAK;;EAEvD,EAAiB,CAAQ,EAAE;;;;EAI3B,EAAS;;;;;;;;;;oBAWX,CAEA,SAAS,EACP,EACA,EACA,EACoB,CACpB,IAAM,EAAYC,EAAAA,wBAAAA,EAAuBC,EAAAA,oBAAAA,CAAoB,CAAM,CAAC,CAAC,SAAU,CAAM,CAAC,CAAC,SACvF,GAAI,IAAS,GAAK,CAAC,EAAwB,OAAO,EAClD,IAAM,EAAgB,EAAO,UAAW,GAAU,EAAM,KAAO,CAAsB,EAErF,OADI,IAAkB,GAAW,EAC1B,EACJ,MAAM,EAAgB,CAAC,CAAC,CACxB,OAAQ,GAAU,EAAM,OAAS,kBAAoB,EAAM,aAAA,6BAAsC,CAAC,CAClG,QAAS,IAAA,EAAUC,EAAAA,8BAAAA,CAA8B,CAAK,CAAC,CAC5D,CAYA,MAAM,EAAmD,CAAE,QAAS,GAAM,OAAQ,CAAC,EAAG,UAAW,CAAC,CAAE,EASpG,SAAgB,EACd,EACA,EAC0B,CAC1B,IAAI,EACJ,GAAI,CACF,GAAA,EAAQC,EAAAA,eAAAA,EAAAA,EAAeC,EAAAA,gBAAAA,CAAgB,CAAC,CAAC,MAAQ,CAAG,CAAC,CAAC,KACxD,OAAS,EAAO,CAGd,OAFA,QAAQ,YAAY,6FAA6F,EACjH,IAAgB,CAAK,EACd,CACT,CACA,IAAM,EAAa,GAAO,YAQpB,GANJ,IAAe,EAAW,QAAU,IAAA,IAAa,EAAW,WAAa,IAAA,IACrE,CACE,GAAI,EAAW,MAAQ,CAAE,MAAO,EAAW,KAAM,EAAI,CAAC,EACtD,GAAI,EAAW,SAAW,CAAE,SAAU,EAAW,QAAS,EAAI,CAAC,CACjE,EACA,IAAA,KACoB,GAAO,UAAU,UACrC,EAAa,GAAY,WAC/B,MAAO,CACL,QAAS,GAAY,SAAW,GAChC,GAAI,EAAQ,CAAE,OAAM,EAAI,CAAC,EACzB,OAAQ,CACN,GAAI,GAAY,QAAU,IAAA,GAAY,CAAC,EAAI,CAAE,EAAG,EAAW,KAAM,EACjE,GAAI,GAAY,QAAU,IAAA,GAAY,CAAC,EAAI,CAAE,EAAG,EAAW,KAAM,EACjE,GAAI,GAAY,QAAU,IAAA,GAAY,CAAC,EAAI,CAAE,EAAG,EAAW,KAAM,CACnE,EACA,UAAW,GAAY,WAAa,CAAC,CACvC,CACF,CAGA,SAAgB,EAA8B,EAAuD,CACnG,IAAM,EAAa,EAAyB,EAAI,GAAG,CAAC,CAAC,MAC/C,EAAY,GAAY,MAAQC,EAAAA,oBAAoB,EAAW,KAAK,EAAI,IAAA,GACxE,EAAkB,EAAY,EAAI,cAAc,KAAK,EAAU,SAAU,EAAU,OAAO,EAAI,IAAA,GAC9F,EAAQ,GAAmB,EAAI,MACrC,GAAI,CAAC,EAAO,OACZ,IAAM,EACJ,GAAY,WAAa,EAAkB,GAAW,SAAW,IAAA,KAAc,EAAI,cACrF,MAAO,CAAE,QAAO,GAAI,EAAgB,CAAE,eAAc,EAAI,CAAC,CAAG,CAC9D,CAWA,eAAsB,EACpB,EACA,EACiB,CACjB,IAAM,EAAY,EAAa,EAAM,OAAO,EAC5C,GAAI,CAAC,EAAW,MAAU,MAAM,6DAA6D,EAC7F,IAAM,EAAO,MAAM,EAAM,QAAQ,cAAc,oBAAoB,EAAU,KAAK,EAClF,GAAI,CAAC,EAAK,GAAI,MAAU,MAAM,EAAK,KAAK,EACxC,IAAM,EAAW,EAAM,QAAQ,cAAc,YAAY,EAAU,MAAM,QAAQ,EACjF,GAAI,CAAC,EACH,MAAU,MAAM,kCAAkC,EAAU,MAAM,SAAS,mBAAmB,EAEhG,OAAA,EAAOC,EAAAA,gBAAAA,CACL,EAAM,SACN,EAAU,MACVC,EAAAA,4BAA4B,cAC5B,EAAK,OAGL,EAAK,QACL,EAAM,OACN,EAAM,aACN,EAAM,mBACN,EAAU,eACT,EAAO,EAAS,IAAY,EAAS,aAAa,EAAO,EAAS,CAAO,EAC1E,EAAK,GACP,CACF,CAEA,SAAS,EAAO,EAAmC,EAAiB,EAAsC,OAAQ,CAC5G,GAAK,OAAO,EAAI,GAAG,OAAO,EAAS,CAAK,CAC9C,CAEA,SAAgB,EACd,EACA,EAAwC,CAAC,EACrB,CACpB,IAAM,EAAe,EAAa,cAAgB,EAC5C,EACJ,EAAa,qBACX,GAAqC,EAAyB,EAAO,CAAY,GAC/E,EAAY,EAAa,WAAaC,EAAAA,2BAA2B,EACjE,EAAmB,EAAa,kBAAoB,GACpD,EAAyB,IAAI,IAC7B,EAAuB,IAAI,IAC3B,EAAiB,IAAI,IACvB,EAAS,GACT,EAAoB,EACpB,EAAQC,EAAAA,mBAAmB,EAC3B,EACA,EACA,EACA,EACA,EAA4B,GAE1B,EAAO,SAA2B,CACtC,EAAS,GACT,GAAqB,EACrB,GAAsB,MAAU,MAAM,uCAAuC,CAAC,EAC9E,EAAuB,IAAA,GACvB,MAAM,QAAQ,WAAW,CAAc,EACvC,EAAqB,IAAA,GACrB,EAA8B,IAAA,GAC9B,EAAiB,IAAA,GACjB,EAAuB,MAAM,EAC7B,EAAqB,MAAM,EAC3B,EAAQA,EAAAA,mBAAmB,EAC3B,EAA4B,GAC5B,MAAM,EAAU,SAAS,CAC3B,EAEM,EAAU,GAA0B,CACxC,EAAO,OAAO,CAACV,EAAAA,kCAAkC,EAAI,GAAgC,CACnF,IAAM,GAAA,EAAUW,EAAAA,gCAAAA,CAAgC,CAA2B,EAE3E,MADA,GAA8B,MACjB,CACP,IAAgC,IAAS,EAA8B,IAAA,GAC7E,CACF,CAAC,EAEG,GACF,EAAO,OAAO,CAACC,EAAAA,mBAAmB,EAAI,GAAc,CAClD,IAAM,GAAA,EAAeC,EAAAA,iBAAAA,CAAiB,CAAS,CAAC,CAAC,eAAe,CAC9D,OAAQC,EAAAA,cACR,GAAI,cACJ,MAAA,EACF,CAAC,EAED,MADA,GAAqB,MACR,CACX,EAAa,QAAQ,EACjB,IAAuB,IAAc,EAAqB,IAAA,GAChE,CACF,CAAC,CAEL,EAGM,EAAiB,GAAiC,CACtD,GAAI,CAAC,EAAQ,OACb,IAAM,EACJ,EAAM,QAAUC,EAAAA,YAAY,kBACxB,cACA,EAAM,QAAUA,EAAAA,YAAY,gBAC1B,WACA,IAAA,GACR,GAAoB,OAClB,EAAQ,CAAE,SAAU,eAAe,EAAM,OAAQ,YAAa,IAAI,EAAM,MAAO,EAAI,IAAA,EACrF,EACA,IAAM,EAAS,GAAO,EAClB,GAAQ,OAAO,EAAO,GAAG,UAAUC,EAAAA,WAAY,EAAQ,mBAAmB,EAAM,KAAK,IAAI,EAAM,IAAM,IAAA,EAAS,CACpH,EAGM,MAAsB,CACrB,IACL,EAAG,YAAYC,EAAAA,kBAAmB,CAAE,GAAG,CAAM,CAAC,EAC9C,EAAc,EAChB,EAEM,MAAqC,CACzC,OAAO,EAAM,UACb,OAAO,EAAM,eACb,OAAO,EAAM,eACb,OAAO,EAAM,kBACb,OAAO,EAAM,cACf,EAEM,EAAsB,GAAgC,CAC1D,EAAM,gBAAkB,EAAM,gBAAgB,OAAQ,GAAe,IAAe,CAAI,CAC1F,EAEM,EAAW,GAAgC,CAC1C,IACL,EAAQ,EAAqB,EAAI,eAAe,UAAU,CAAC,GAAKP,EAAAA,mBAAmB,EAEjF,IAAM,QAAUK,EAAAA,YAAY,iBAAmB,EAAM,WAAa,EAAM,gBAAkB,EAAM,mBAC1E,EAAM,QAAUA,EAAAA,YAAY,WAEpD,GAAsB,MAAM,EAC5B,EAAuB,IAAA,GACvB,EAAM,MAAQA,EAAAA,YAAY,QAC1B,EAAuB,EACvB,EAAQ,GACV,EAEM,GAAe,GAA0B,CACxC,GACL,EAAG,YACD,CACE,WAAYG,EAAAA,oBACZ,QAAS,GAAG,EAAQ,mGACpB,QAAS,GACT,QAAS,CAAE,QAAA,EAAwB,MAAO,EAAM,MAAO,KAAM,EAAM,IAAK,CAC1E,EACA,CAAE,YAAa,GAAM,UAAW,OAAQ,CAC1C,CACF,EAOM,GACJ,EACA,IAC6C,CAC7C,IAAM,EAAW,EAAM,gBAAkB,EACnC,EAAY,GAAA,EAYlB,MAXA,GAAM,MAAQH,EAAAA,YAAY,QACtB,IAAc,EAAM,kBAAoB,GACxC,GACF,EAAmB,CAAI,EACvB,EAAM,gBAAkB,CAAC,GAAG,EAAM,gBAAiB,CAAI,EACvD,EAAM,gBAAkB,GAExB,EAAM,gBAAkB,EAE1B,EAAuB,EACvB,EAAQ,EACD,CAAE,WAAU,WAAU,CAC/B,EAEM,IAAkB,EAAmB,IAAyB,CAClE,GAAI,CAAC,GAAU,IAAc,EAAM,WAAa,EAAM,QAAUA,EAAAA,YAAY,kBAAmB,OAC/F,IAAM,EAAO,EAAM,KACb,CAAE,WAAU,aAAc,EAAsB,EAAM,EAAM,cAAc,EAC1E,EAAS,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EACpE,EACE,EACA,EACI,uCAAuC,EAAK,UAAU,EAAS,4BAA4B,IAC3F,uCAAuC,EAAK,WAAW,IAC3D,OACF,CACF,EAIM,IAA2B,EAAuB,IAAyB,CAC1E,GAAU,KACf,EAA4B,GAC5B,EAAe,cACbI,EAAAA,kBAAkB,wBAClB,EACA,EAAoB,EAAK,CAAE,oBAAqB,EAAM,MAAO,mBAAoB,EAAM,IAAK,CAAC,CAC/F,EACF,EAEM,GACJ,EACA,EACA,IACS,CACJ,KACL,IAAK,IAAM,KAAS,EAAS,OAC3B,EACE,EACA,mDAAmD,EAAM,OAAO,GAAG,EAAM,GAAG,KAAK,EAAM,UACvF,SACF,EACA,EAAe,cAAcA,EAAAA,kBAAkB,4BAAiC,MAAM,EAAM,OAAO,EAAG,CACpG,GAAG,EACH,0CAA2C,EAAM,OACjD,sCAAuC,EAAM,GAC7C,yCAA0C,EAAM,KAClD,CAAC,CAEL,EAEM,GACJ,EACA,EACA,IACyB,CACzB,GAAI,CAAC,EACH,MAAO,CAAE,cAAe,CAAC,EAAG,mBAAoB,CAAC,CAAE,EAErD,IAAM,EAAuB,EAAiC,CAA2B,EACzF,EAA2B,EAAK,EAAsB,CAAU,EAChE,IAAM,EAAW,EAAqB,EAAQ,CAAoB,EAOlE,OANA,EAAG,YAAY,CACb,WAAYC,EAAAA,2BACZ,QAAS,EAAmB,CAAQ,EACpC,QAAS,GACT,QAAS,CAAE,QAAS,EAAG,GAAG,CAAS,CACrC,CAAC,EACM,CACT,EAEM,IAAoB,EAAa,IAAmC,CACxE,GAAI,CAAC,GAAU,CAAC,EAAM,WAAa,CAAC,EAAM,gBAAkB,CAAC,EAAM,kBAAmB,MAAO,GAC7F,IAAM,EAAS,EAAI,eAAe,UAAU,EACtC,EAAYnB,EAAAA,wBAAAA,EAAuBC,EAAAA,oBAAAA,CAAoB,CAAM,CAAC,CAAC,SAAU,CAAM,CAAC,CAAC,SACjF,EAAcmB,EAAAA,iBAAiB,EAAOC,EAAAA,2BAA2B,CAAS,CAAC,EAC3E,EAAY,EAAM,UAClB,EAAQ,EAAM,MACd,EAAUC,EAAAA,0BAA0B,EAAM,kBAAmB,CAAW,EACxE,EAAqC,CACzC,GAAG,EACH,gBAAiB,CACf,QAAA,EACA,QACA,OACA,YACA,eAAgB,EAAM,eACtB,aAAc,EAAM,gBAAkB,EAAI,gBAAgB,CAAC,EAAE,QAAU,CACzE,EACA,iBAAkBC,EAAAA,8BAA8B,EAAQ,EAAM,cAAc,CAC9E,EAEM,EAAqB,EAAI,OAAO,EACtC,EAAG,YAAY,CAAE,WAAYC,EAAAA,qBAAsB,QAAS,EAAS,QAAS,GAAO,SAAQ,CAAC,EAC9F,IAAM,EAAuB,EAAc,CAAG,EACxC,EAAoB,EAAoB,EAAK,CACjD,yBAA0B,EAC1B,oBAAqB,EACrB,mBAAoB,CACtB,CAAC,EACK,EAAkB,EAAqB,EAAK,EAAQ,CAAiB,EAkC3E,OAhCI,GAAoB,EAAG,SAAS,EAAsB,gBAAgB,EAAM,IAAI,GAAM,EAE1F,EAAM,UAAY,EAAY,UAC9B,EAAM,cAAgB,EAAY,cAClC,OAAO,EAAM,+BACb,EAAM,MAAQV,EAAAA,YAAY,QAC1B,EAAM,gBAAkB,CAAC,EAEzB,EAAM,gBAAkB,CAAC,EACzB,EAAM,gBAAkB,EACxB,EAAM,gBAAkB,GACxB,OAAO,EAAM,kBACb,EAAuB,EACvB,EAAM,OAAS,EACf,EAAM,KAAO,EACb,EAAQ,EACR,EAAe,YACbI,EAAAA,kBAAkB,iBAClB,EAAoB,EAAK,CACvB,yBAA0B,EAC1B,oBAAqB,EACrB,mBAAoB,EACpB,+BAAgC,EAAQ,gBAAgB,eACxD,4BAA6B,EAAQ,gBAAgB,aACrD,mCAAoC,EAAU,OAC9C,qCAAsC,EAAQ,iBAAiB,OAC/D,yBAA0B,EAAqB,OAAS,WACxD,GAAG,EAA2B,CAAe,CAC/C,CAAC,CACH,EAEI,GAAoB,GAAY,oCAAoC,EACjE,EACT,EAEM,IAAqB,EAAuB,EAAuB,IAA+B,CACtG,GAAI,CAAC,EAAQ,OACb,IAAM,EAAa,EACb,EAAS,EAAI,eAAe,UAAU,EACtC,EAAiB,EAAc,CAAG,EAClC,EAAYO,EAAAA,gBAAgB,EAAI,eAAe,aAAa,EAAG,EAAM,MAAO,EAAM,CAAc,EAChG,EAAqB,EAAO,EAAIC,EAAAA,2BAA2BC,EAAAA,8BAA8B,CAAM,CAAC,EAAI,IAAA,GACpG,EAAW,EAAsB,EAAM,EAAQ,EAAM,8BAA8B,EACnF,EAAuB,EAAiC,CAA2B,EACnF,EAAa,EAAoB,EAAK,CAC1C,yBAA0B,EAC1B,oBAAqB,EAAM,MAC3B,mBAAoB,EACpB,+BAAgC,EAChC,4BAA6B,EAC7B,mCAAoC,EAAS,MAC/C,CAAC,EACD,EAA2B,EAAK,EAAsB,CAAU,EAEhE,EAAM,MAAQb,EAAAA,YAAY,kBAC1B,EAAM,KAAO,EACb,EAAM,UAAY,EAClB,EAAM,eAAiB,EACvB,EAAM,eAAiB,EACvB,OAAO,EAAM,kBACb,OAAO,EAAM,eACb,OAAO,EAAM,kBACb,EAAQ,EAER,GAAsB,MAAM,EAC5B,EAAuB,IAAI,gBAC3B,IAAM,EAAmB,EAAqB,OACxC,EAAY,EACf,UAAU,8BAA+B,EAAY,SAAY,CAChE,MAAM,EAAU,YAAYI,EAAAA,kBAAkB,kBAAmB,CAAU,EAC3E,GAAI,CACF,IAAM,EAAa,MAAM,EAAmB,CAC1C,WACA,aAAc,EAAuB,EAAM,CACzC,KAAM,EAAmB,CAAM,EAC/B,uBACA,UAAW,EAAM,UACjB,cAAe,EAAM,aACvB,CAAC,EACD,GAAI,EAAqB,CAAE,oBAAmB,EAAI,CAAC,EACnD,QAAS,EACT,OAAQ,CACV,CAAC,EACD,GAAI,CAAC,GAAU,IAAe,EAC5B,MAAM,EAAiB,QAAc,MAAM,sCAAsC,EAEnF,GAAI,CAAC,EAAW,KAAK,EAAG,MAAU,MAAM,6CAA6C,EAKrF,OAJA,MAAM,EAAU,YAAYA,EAAAA,kBAAkB,oBAAqB,CACjE,GAAG,EACH,oCAAqC,EAAW,MAClD,CAAC,EACM,CACT,OAAS,EAAO,CAId,MAHI,GAAU,IAAe,GAC3B,MAAM,EAAU,YAAYA,EAAAA,kBAAkB,iBAAkB,EAAO,CAAU,EAE7E,CACR,CACF,CAAC,CAAC,CACD,KAAM,GAAe,CAEjB,GACD,IAAe,GACf,IAAc,EAAM,WACpB,EAAM,QAAUJ,EAAAA,YAAY,oBAI9B,EAAM,MAAQA,EAAAA,YAAY,gBAC1B,EAAM,kBAAoB,EAAW,KAAK,EAC1C,EAAQ,EACJ,GAAgB,EAAgB,CAAc,EACpD,CAAC,CAAC,CACD,MAAO,GAAmB,CACrB,GAAU,IAAe,GAAmB,GAAe,EAAW,CAAK,CACjF,CAAC,EACH,EAAe,IAAI,CAAS,EAC5B,EAAe,YAAc,EAAe,OAAO,CAAS,CAAC,CAC/D,EAEM,EAAiB,GAAmC,CACxD,GAAI,CAAC,GAAU,EAAM,QAAUA,EAAAA,YAAY,SAAW,EAAI,mBAAmB,EAAG,MAAO,GAIvF,IAAM,EAAa,EAAyB,EAAI,IAAM,GAAU,GAAwB,EAAK,CAAK,CAAC,EACnG,GAAI,CAAC,EAAW,QAAS,MAAO,GAChC,IAAM,EAAQ,EAAI,gBAAgB,EAClC,GAAI,CAAC,GAAS,EAAM,SAAW,KAAM,MAAO,GAC5C,GAAI,EAAM,gBAOR,OAJKc,EAAAA,uBAAuB,EAAI,eAAe,UAAU,CAAC,GAC1D,EAAM,eAAiB,EAAM,OAC7B,EAAM,gBAAkB,GACxB,EAAQ,EACD,IAJ6D,GAMtE,IAAM,EAAS,EAAc,CAAG,EAChC,GAAI,EAAM,oBAAsB,EAAQ,MAAO,GAI/C,IAAM,EAAiBC,EAAAA,2BAA2B,EAAI,MAAO,EAAW,SAAS,EAC3E,EAAaC,EAAAA,oBACjB,EAAM,cACN,EAAM,eACN,EAAW,OACX,CACF,EACA,IAAK,IAAM,IAAQ,CAAC,EAAG,EAAG,CAAC,EACrB,EAAO,EAAM,MAAQ,EAAM,gBAAgB,SAAS,CAAI,GAAK,EAAM,gBAAgB,SAAS,CAAI,GAChG,EAAM,QAAU,EAAW,IAC7B,EAAM,gBAAgB,KAAK,CAAI,EAGnC,IAAM,EAAW,EAAM,gBAAgB,GAGvC,OAFK,GACL,GAAkB,EAAU,EAAK,EAAM,MAAM,EACtC,IAFe,EAGxB,EAKM,GAAmB,EAAa,IAA0B,CAC9D,GAAI,CAAC,EAAQ,OACb,IAAM,EAA2B,EAAM,eACvC,EAAG,YAAYC,EAAAA,wBAAyB,CACtC,GAAGC,EAAAA,yBAAyB,EAAM,MAAO,EAAM,EAAM,WAAa,WAAW,EAC7E,SACF,CAAC,EACG,IAA0B,EAAM,+BAAiC,EACvE,EAEM,EAA0B,GAA6C,CAC3E,GAAI,CAAC,GAAU,EAAM,QAAUlB,EAAAA,YAAY,iBAAmB,CAAC,EAAM,WAAa,CAAC,EAAM,kBACvF,MAAO,OAET,IAAM,EAAO,EAAM,KACb,EAAWmB,EAAAA,wBAAwB,EAAM,iBAAiB,EAChE,GAAI,CAACC,EAAAA,uBAAuB,EAAS,OAAO,EAAG,CAC7C,IAAM,EAAe,EAAM,eACrB,EAAmB,EAAM,UAGzB,CAAE,WAAU,aAAc,EAAsB,EAAM,CAAY,EAClE,EAAY,MAAM,sBAAsB,EAAK,oCAAoC,EAmBvF,OAlBA,EACE,EACA,EACI,uCAAuC,EAAK,qCAAqC,EAAS,2BAC1F,uCAAuC,EAAK,qCAChD,OACF,EACA,EAAe,YACbhB,EAAAA,kBAAkB,kBAClB,EACA,EAAoB,EAAK,CACvB,oBAAqB,EAAM,MAC3B,mBAAoB,EACpB,kCAAmC,EACnC,mCAAoC,EACpC,GAAI,EAAmB,CAAE,yBAA0B,CAAiB,EAAI,CAAC,CAC3E,CAAC,CACH,EACO,SACT,CAyBA,MAvBA,GAAM,gBAAkB,EAEpB,IAAS,GACX,EAAgB,EAAG,EAAS,OAAO,EACnC,EAAmB,CAAC,EACpB,EAAM,MAAQJ,EAAAA,YAAY,QAC1B,EAAM,KAAO,EACb,EAAuB,EACvB,EAAQ,EACD,SAGL,IAAS,GAAK,EAAS,gBAAkB,IAC3C,EAAgB,EAAG,EAAS,OAAO,EACnC,EAAmB,CAAC,EACpB,EAAM,MAAQA,EAAAA,YAAY,QAC1B,EAAM,KAAO,EACb,EAAuB,EACvB,EAAQ,EACD,aAGT,EAAM,kBAAoB,EAAS,QAC5B,GAAiB,EAAM,CAAG,EAAI,YAAc,UACrD,EAEA,SAAS,EAAgB,EAA6B,CAC/C,IACL,EAAiB,EACZ,EAAI,OAAO,GACZ,EAAuB,CAAG,IAAM,aAAa,EAAc,CAAG,EACpE,CAEA,IAAM,EAA0B,GAAgC,CACzD,IACL,GAAqB,EACrB,GAAsB,MAAU,MAAM,8CAA8C,CAAC,EACrF,EAAuB,IAAA,GACvB,EAAuB,MAAM,EAC7B,EAAqB,MAAM,EAC3B,EAAiB,EACjB,EAAQ,CAAG,EACX,EAAgB,CAAG,EACrB,EAEA,MAAO,CACL,SACA,OACA,OAAQ,CACN,SAAU,EAAO,IAAQ,CACvB,GAAI,CAAC,EAAQ,OACb,IAAM,EAAad,EAAAA,uBAAuB,EAAM,SAAU,EAAI,eAAe,UAAU,CAAC,EACxF,GAAI,EAAW,cAAe,CAC5B,IAAM,EAAS,EAAI,eAAe,UAAU,GAAA,QACvC,EAAqB,IAAI,CAAM,IAClC,EAAqB,IAAI,CAAM,EAC/B,EAAe,YACbkB,EAAAA,kBAAkB,qBACd,MAAM,+CAA+C,EACzD,EAAoB,EAAK,CAAE,sBAAuB,CAAO,CAAC,CAC5D,GAEF,MACF,CACK,KAAW,OAiBhB,OAhBK,EAAuB,IAAI,EAAW,OAAO,SAAS,IACzD,EAAuB,IAAI,EAAW,OAAO,SAAS,EACtD,EAAe,YACbA,EAAAA,kBAAkB,eAClB,EAAoB,EAAK,CACvB,yBAA0B,EAAW,OAAO,UAC5C,oBAAqB,EAAW,OAAO,MACvC,mBAAoB,EAAW,OAAO,KACtC,+BAAgC,EAAW,OAAO,eAClD,4BAA6B,EAAW,OAAO,aAC/C,mCAAoC,EAAM,SAAS,OACnD,kCAAmC,EAAW,SAAS,OACvD,qCAAsC,EAAW,oBACnD,CAAC,CACH,GAEK,CAAE,SAAU,EAAW,QAAS,CACzC,EAEA,eAAgB,EAAQ,IAAQ,EAAuB,CAAG,EAE1D,cAAe,EAAQ,IAAQ,EAAuB,CAAG,EAEzD,UAAW,EAAO,IAAQ,CACnB,KAEL,IADA,EAAiB,EACb,EAAI,OAAO,EAAG,CAChB,EAAgB,CAAG,EACnB,MACF,CAKE,EAAM,QAAUJ,EAAAA,YAAY,kBAC3B,EAAM,aAAa,QAAU,GAAK,GACnC,CAAC,EAAI,mBAAmB,GACD,EAAuB,CAAG,IAAM,QACzD,EAAc,CAAG,CATjB,CAUF,EAEA,eAAgB,EAAQ,IAAQ,CACzB,GACL,EAAgB,CAAG,CACrB,EAEA,uBAAyB,GAAU,CAC7B,GAAC,GAAU,EAAM,SAAW,YAOhC,OAHE,EAAM,QAAUA,EAAAA,YAAY,mBAC5B,EAAM,QAAUA,EAAAA,YAAY,iBAC5B,EAAM,gBACiB,CAAE,OAAQ,EAAK,EAAI,IAAA,EAC9C,EAEA,iBAAkB,EAAO,IAAQ,CAC/B,GAAI,CAAC,EAAQ,OACb,GAAqB,EAErB,GAAsB,MAAM,EAC5B,EAAuB,IAAA,GACvB,IAAM,EAAeqB,EAAAA,uBAAuB,EAAM,gBAAgB,OAAO,EACnE,EAAaf,EAAAA,iBAAiB,EAAO,IAAA,GAAW,CAAY,EAClE,EAAM,UAAY,EAAW,UAC7B,EAAM,cAAgB,EAAW,cACjC,OAAO,EAAM,+BAGb,EAAM,gBAAkB,GACxB,EAAM,MAAQN,EAAAA,YAAY,QAC1B,EAAuB,EACvB,EAAM,gBAAkB,CAAC,EACzB,EAAM,gBAAkB,CAAC,EACzB,EAAM,gBAAkB,EACxB,OAAO,EAAM,kBAEb,EAAG,SAAS,EAAM,gBAAgB,GAAI,gBAAgB,EAAM,MAAM,UAAU,EAC5E,IAAM,EAAiB,EAAM,MACvB,EAAoB,EAAoB,EAAK,CACjD,oBAAqB,EACrB,4BAA6B,EAAM,MACrC,CAAC,EACK,EAAkB,EAAqB,EAAK,EAAI,eAAe,UAAU,EAAG,CAAiB,EACnG,EAAM,OAAS,EACf,EAAM,KAAO,EACb,EAAQ,EACR,EAAe,YACbI,EAAAA,kBAAkB,0BAClB,EAAoB,EAAK,CACvB,oBAAqB,EACrB,4BAA6B,EAAM,OACnC,oCAAqC,EAAM,cAC3C,4BAA6B,EAAM,gBAAgB,aACnD,GAAG,EAA2B,CAAe,CAC/C,CAAC,CACH,CACF,CACF,CACF,CACF"}
1
+ {"version":3,"file":"index.cjs","names":["parseState","ROOT_WORKING_LEAF","DOOM_CONTEXT_CONTRIBUTIONS_SERVICE","projectContextMessages","buildSessionContext","sessionEntryToContextMessages","loadDoomConfig","getHarnessState","parseModelReference","generateSummary","DEFAULT_COMPACTION_SETTINGS","createAutocompactTelemetry","createInitialState","requireDoomContextContributions","DOOM_UI_HUB_SERVICE","requireDoomUiHub","FOOTER_SOURCE","STATE_PHASE","STATUS_KEY","STATE_CUSTOM_TYPE","RESUME_MESSAGE_TYPE","AUTOCOMPACT_EVENT","RUNTIME_STATE_MESSAGE_TYPE","mergeFileDetails","fileOperationsFromMessages","withCanonicalFileSections","retainedMessagesAfterSnapshot","CONTEXT_MESSAGE_TYPE","createRequestId","checkpointSummaryFromEntry","latestCheckpointArtifactEntry","baselineUsageIsSettled","resolveModelTokenOverrides","effectiveThresholds","CHECKPOINT_MESSAGE_TYPE","checkpointRequestDetails","parseCheckpointDecision","isStructuredCheckpoint","fileDetailsFromUnknown"],"sources":["../../../src/services/autocompactRuntime/index.ts"],"sourcesContent":["import {\n getHarnessState,\n loadDoomConfig,\n type AutocompactOverrideConfig,\n type PlanningAgentConfig,\n} from '@agimon-ai/doompi-config';\nimport {\n DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n requireDoomContextContributions,\n type DoomContextContributionEntry,\n type DoomContextContributionError,\n type DoomContextContributionsService,\n type DoomContextContributionsSnapshot,\n} from '@agimon-ai/doompi-core/context-contributions';\nimport type { DoomFooterContributionHandle } from '@agimon-ai/doompi-core/footer';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/ui-hub';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ContextEvent, ExtensionAPI, ExtensionContext, SessionEntry } from '@earendil-works/pi-coding-agent';\nimport {\n buildSessionContext,\n DEFAULT_COMPACTION_SETTINGS,\n generateSummary,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\n\nimport {\n CHECKPOINT_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n MAX_INVALID_CHECKPOINT_ATTEMPTS,\n RESUME_MESSAGE_TYPE,\n RUNTIME_STATE_MESSAGE_TYPE,\n STATE_CUSTOM_TYPE,\n STATE_VERSION,\n} from '../../constants/autocompact';\nimport {\n ROOT_WORKING_LEAF,\n PLAN_DOCUMENT_ENTRY,\n FOOTER_SOURCE,\n FOOTER_ORDER,\n STATUS_KEY,\n STATE_PHASE,\n SLOW_CONTEXT_HOOK_MS,\n} from '../../constants/runtime';\nimport type {\n AutocompactContextDetails,\n AutocompactPass,\n AutocompactRatioOverrides,\n AutocompactState,\n} from '../../types/autocompact';\nimport type { AutocompactEventAttributes, AutocompactTelemetry } from '../autocompactTelemetry';\nimport { AUTOCOMPACT_EVENT, createAutocompactTelemetry } from '../autocompactTelemetry';\nimport {\n baselineUsageIsSettled,\n checkpointRequestDetails,\n checkpointSummaryFromEntry,\n createInitialState,\n createRequestId,\n fileDetailsFromUnknown,\n fileOperationsFromMessages,\n isStructuredCheckpoint,\n latestCheckpointArtifactEntry,\n mergeFileDetails,\n parseCheckpointDecision,\n parseState,\n projectContextMessages,\n retainedMessagesAfterSnapshot,\n effectiveThresholds,\n withCanonicalFileSections,\n} from '../compactionPolicy';\nimport { resolveModelTokenOverrides } from '../modelOverrides';\nimport { parseModelReference, type SummarizationModel } from '../summarizationModel';\nimport type { AutocompactRuntime } from './type';\ntype CheckpointCapture = 'none' | 'pass1' | 'committed' | 'deferred' | 'invalid';\ntype CheckpointMessages = ReturnType<typeof buildSessionContext>['messages'];\n\ninterface PlanSnapshot {\n content: string;\n path: string;\n}\n\ninterface SteeringSnapshot {\n plan?: PlanSnapshot;\n contextContributions: DoomContextContributionsSnapshot;\n readFiles: string[];\n modifiedFiles: string[];\n}\n\ninterface RuntimeStateSnapshot {\n planPath?: string;\n contributions: readonly DoomContextContributionEntry[];\n contributionErrors: readonly DoomContextContributionError[];\n}\n\ninterface CheckpointGenerationInput {\n messages: CheckpointMessages;\n instructions: string;\n previousCheckpoint?: string;\n context: ExtensionContext;\n signal: AbortSignal;\n}\n\nexport interface AutocompactDependencies {\n generateCheckpoint?: (input: CheckpointGenerationInput) => Promise<string>;\n resolveModel?: (context: ExtensionContext) => SummarizationModel | undefined;\n telemetry?: AutocompactTelemetry;\n doomIntegrations?: boolean;\n}\n\nfunction telemetryAttributes(\n context: ExtensionContext,\n attributes: AutocompactEventAttributes = {},\n): AutocompactEventAttributes {\n return {\n 'pi.session.id': context.sessionManager.getSessionId(),\n ...attributes,\n };\n}\n\nfunction latestPersistedState(branch: SessionEntry[]): AutocompactState | undefined {\n for (let index = branch.length - 1; index >= 0; index -= 1) {\n const entry = branch[index];\n if (entry?.type !== 'custom' || entry.customType !== STATE_CUSTOM_TYPE) continue;\n const parsed = parseState(entry.data);\n if (parsed) return parsed;\n }\n return undefined;\n}\n\nfunction workingLeafId(ctx: ExtensionContext): string {\n for (const entry of ctx.sessionManager.getBranch().toReversed()) {\n if (entry.type === 'custom' && entry.customType === STATE_CUSTOM_TYPE) continue;\n if (entry.type === 'label') continue;\n return entry.id;\n }\n return ROOT_WORKING_LEAF;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction latestPlanSnapshot(branch: SessionEntry[]): PlanSnapshot | undefined {\n for (const entry of branch.toReversed()) {\n if (entry.type !== 'custom' || entry.customType !== PLAN_DOCUMENT_ENTRY) continue;\n if (!entry.data || typeof entry.data !== 'object') return undefined;\n const data = entry.data as Record<string, unknown>;\n if (typeof data.content !== 'string' || typeof data.path !== 'string') return undefined;\n return { content: data.content, path: data.path };\n }\n return undefined;\n}\n\nconst EMPTY_CONTEXT_CONTRIBUTIONS: DoomContextContributionsSnapshot = Object.freeze({\n entries: Object.freeze([]),\n errors: Object.freeze([]),\n});\n\nfunction readContextContributionsSnapshot(\n service: DoomContextContributionsService | undefined,\n): DoomContextContributionsSnapshot {\n if (!service) return EMPTY_CONTEXT_CONTRIBUTIONS;\n try {\n return service.snapshot();\n } catch (error) {\n return {\n entries: [],\n errors: [\n {\n source: DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n id: 'service-snapshot',\n label: 'Context contributions',\n order: 0,\n message: errorMessage(error),\n },\n ],\n };\n }\n}\n\nfunction formatContextContributions(snapshot: DoomContextContributionsSnapshot): string {\n const sections = snapshot.entries.map((entry) => `### ${entry.label}\\n${entry.text}`);\n sections.push(...snapshot.errors.map((error) => `### ${error.label}\\n(unavailable: ${error.message})`));\n return sections.length > 0 ? sections.join('\\n\\n') : '(no registered context contributions)';\n}\n\nfunction runtimeStateSnapshot(\n branch: SessionEntry[],\n contextContributions: DoomContextContributionsSnapshot,\n): RuntimeStateSnapshot {\n const plan = latestPlanSnapshot(branch);\n return {\n ...(plan ? { planPath: plan.path } : {}),\n contributions: contextContributions.entries,\n contributionErrors: contextContributions.errors,\n };\n}\n\nfunction formatRuntimeState(snapshot: RuntimeStateSnapshot): string {\n const plan = snapshot.planPath\n ? `Source: ${snapshot.planPath}\\nExact plan content is restored separately by Doom Plan.`\n : '(no active plan document)';\n return `<compaction-runtime-state>\nAuthoritative runtime state captured when compaction committed. Use it to resume coordination without reconstructing state from the summary.\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions({ entries: snapshot.contributions, errors: snapshot.contributionErrors })}\n</context-contributions>\n</compaction-runtime-state>`;\n}\n\nfunction runtimeTelemetryAttributes(snapshot: RuntimeStateSnapshot): AutocompactEventAttributes {\n return {\n 'autocompact.runtime.plan_present': Boolean(snapshot.planPath),\n 'autocompact.runtime.contribution_count': snapshot.contributions.length,\n 'autocompact.runtime.contribution_error_count': snapshot.contributionErrors.length,\n };\n}\n\nfunction steeringEnvelope(snapshot: SteeringSnapshot): string {\n const plan = snapshot.plan\n ? `Source: ${snapshot.plan.path}\\n\\n${snapshot.plan.content}`\n : '(no active plan document)';\n const importantContext = [\n snapshot.readFiles.length > 0 ? `Read files: ${snapshot.readFiles.join(', ')}` : undefined,\n snapshot.modifiedFiles.length > 0 ? `Modified files: ${snapshot.modifiedFiles.join(', ')}` : undefined,\n ].filter((value): value is string => Boolean(value));\n\n return `<compaction-steering priority=\"user,plan,context-contributions,important-context,recent-messages\">\n<user-prompt source=\"conversation\">\nTreat the user's explicit goals, constraints, corrections, and preferences in the conversation as authoritative. Newer user instructions override older ones.\n</user-prompt>\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions(snapshot.contextContributions)}\n</context-contributions>\n<important-context>\n${importantContext.length > 0 ? importantContext.join('\\n') : '(none recorded outside the conversation)'}\n</important-context>\n</compaction-steering>`;\n}\n\nfunction checkpointInstructions(pass: AutocompactPass, steering: SteeringSnapshot): string {\n const decision =\n pass === 2\n ? 'Start with exactly <shouldCompact>true</shouldCompact> or <shouldCompact>false</shouldCompact>. Use true when the staged summary safely retains the important parent context. Use false only when it is not yet sufficient for safe compaction.\\n\\n'\n : '';\n\n // Summarization is a tool-less single LLM call, so instructions describe only what to\n // produce. Directives aimed at an implementing agent leak into the checkpoint body.\n return `Create Doom autocompact checkpoint pass ${pass}.\n\n${steeringEnvelope(steering)}\n\nApply the steering evidence in priority order. Do not invent plan or contributed runtime state. Preserve verified facts and mark unresolved inference explicitly. Newer evidence replaces superseded information.\n\n${decision}Return only the decision tag when required, followed by a concise structured checkpoint using every heading below. Keep exact goals, constraints, decisions, blockers, commands, errors, file paths, validation evidence, and the immediate next action. Separate verified facts from unresolved inference.\n\n## Goal\n## Constraints & Preferences\n## Progress\n### Done\n### In Progress\n### Blocked\n## Key Decisions\n## Next Steps\n## Critical Context`;\n}\n\nfunction messagesForCheckpoint(\n pass: AutocompactPass,\n branch: SessionEntry[],\n previousSnapshotLeafId: string | undefined,\n): CheckpointMessages {\n const projected = projectContextMessages(buildSessionContext(branch).messages, branch).messages;\n if (pass === 1 || !previousSnapshotLeafId) return projected;\n const snapshotIndex = branch.findIndex((entry) => entry.id === previousSnapshotLeafId);\n if (snapshotIndex === -1) return projected;\n return branch\n .slice(snapshotIndex + 1)\n .filter((entry) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\ninterface AutocompactRuntimeConfig {\n /** Off leaves compaction to Pi; unset is on. */\n enabled: boolean;\n /** The agent that writes the summaries, from autocompact's own keys or planning's. */\n agent?: PlanningAgentConfig;\n ratios: AutocompactRatioOverrides;\n /** Per-model absolute token checkpoints, tried in file order. */\n overrides: AutocompactOverrideConfig[];\n}\n\nconst DEFAULT_RUNTIME_CONFIG: AutocompactRuntimeConfig = { enabled: true, ratios: {}, overrides: [] };\n\n/**\n * What the Doom config says about this package.\n *\n * `modes.autocompact` is read first and `modes.planning.subagents` is the\n * fallback, because summarization borrowed the planning subagent model before\n * it had keys of its own and existing files still spell it that way.\n */\nexport function autocompactRuntimeConfig(\n cwd: string,\n onLoadFailure?: (error: unknown) => void,\n): AutocompactRuntimeConfig {\n let modes: ReturnType<typeof loadDoomConfig>['modes'];\n try {\n modes = loadDoomConfig(getHarnessState().root ?? cwd).modes;\n } catch (error) {\n process.emitWarning('Doom autocompact configuration could not be loaded; using the active session model instead.');\n onLoadFailure?.(error);\n return DEFAULT_RUNTIME_CONFIG;\n }\n const configured = modes?.autocompact;\n const ownAgent: PlanningAgentConfig | undefined =\n configured && (configured.model !== undefined || configured.thinking !== undefined)\n ? {\n ...(configured.model ? { model: configured.model } : {}),\n ...(configured.thinking ? { thinking: configured.thinking } : {}),\n }\n : undefined;\n const agent = ownAgent ?? modes?.planning?.subagents;\n const thresholds = configured?.thresholds;\n return {\n enabled: configured?.enabled ?? true,\n ...(agent ? { agent } : {}),\n ratios: {\n ...(thresholds?.pass1 === undefined ? {} : { 1: thresholds.pass1 }),\n ...(thresholds?.pass2 === undefined ? {} : { 2: thresholds.pass2 }),\n ...(thresholds?.pass3 === undefined ? {} : { 3: thresholds.pass3 }),\n },\n overrides: configured?.overrides ?? [],\n };\n}\n\n/** Explicit Doom model selection honors the configured summarization model. */\nexport function resolveDoomSummarizationModel(ctx: ExtensionContext): SummarizationModel | undefined {\n const configured = autocompactRuntimeConfig(ctx.cwd).agent;\n const reference = configured?.model ? parseModelReference(configured.model) : undefined;\n const configuredModel = reference ? ctx.modelRegistry.find(reference.provider, reference.modelId) : undefined;\n const model = configuredModel ?? ctx.model;\n if (!model) return undefined;\n const thinkingLevel =\n configured?.thinking ?? (configuredModel ? reference?.thinking : undefined) ?? ctx.thinkingLevel;\n return { model, ...(thinkingLevel ? { thinkingLevel } : {}) };\n}\n\n/**\n * Summarization borrows the session's own provider instead of re-resolving one.\n *\n * The selected model can come from a Pi provider extension, and that extension's\n * `streamSimple` closure lives only in this process: it is never in Pi's global api\n * registry, so any other thread or process sees `No API provider registered for api`.\n * Passing the composed provider in as `generateSummary`'s stream function keeps\n * summarization on exactly the path the agent's own requests take.\n */\nexport async function generateCheckpointWithPi(\n input: CheckpointGenerationInput,\n resolveModel: (context: ExtensionContext) => SummarizationModel | undefined,\n): Promise<string> {\n const selection = resolveModel(input.context);\n if (!selection) throw new Error('No active model is available for autocompact summarization.');\n const auth = await input.context.modelRegistry.getApiKeyAndHeaders(selection.model);\n if (!auth.ok) throw new Error(auth.error);\n const provider = input.context.modelRegistry.getProvider(selection.model.provider);\n if (!provider) {\n throw new Error(`No provider is registered for \"${selection.model.provider}\" in this session.`);\n }\n return generateSummary(\n input.messages,\n selection.model,\n DEFAULT_COMPACTION_SETTINGS.reserveTokens,\n auth.apiKey,\n // A null header value suppresses a provider default, which the narrower\n // `generateSummary` signature does not model but every provider honors.\n auth.headers as Record<string, string> | undefined,\n input.signal,\n input.instructions,\n input.previousCheckpoint,\n selection.thinkingLevel,\n (model, context, options) => provider.streamSimple(model, context, options),\n auth.env,\n );\n}\n\nfunction notify(ctx: ExtensionContext | undefined, message: string, level: 'info' | 'warning' | 'error' = 'info') {\n if (ctx?.hasUI) ctx.ui.notify(message, level);\n}\n\nexport function createAutocompactRuntime(\n pi: ExtensionAPI,\n dependencies: AutocompactDependencies = {},\n): AutocompactRuntime {\n const resolveModel = dependencies.resolveModel ?? resolveDoomSummarizationModel;\n const generateCheckpoint =\n dependencies.generateCheckpoint ??\n ((input: CheckpointGenerationInput) => generateCheckpointWithPi(input, resolveModel));\n const telemetry = dependencies.telemetry ?? createAutocompactTelemetry();\n const doomIntegrations = dependencies.doomIntegrations ?? true;\n const appliedContextRequests = new Set<string>();\n const invalidContextLeaves = new Set<string>();\n const checkpointWork = new Set<Promise<void>>();\n let active = true;\n let sessionGeneration = 0;\n let state = createInitialState();\n let currentContext: ExtensionContext | undefined;\n let checkpointController: AbortController | undefined;\n let footerContribution: DoomFooterContributionHandle | undefined;\n let contextContributionsService: DoomContextContributionsService | undefined;\n let configLoadFailureReported = false;\n\n const stop = async (): Promise<void> => {\n active = false;\n sessionGeneration += 1;\n checkpointController?.abort(new Error('Autocompact runtime is shutting down.'));\n checkpointController = undefined;\n await Promise.allSettled(checkpointWork);\n footerContribution = undefined;\n contextContributionsService = undefined;\n currentContext = undefined;\n appliedContextRequests.clear();\n invalidContextLeaves.clear();\n state = createInitialState();\n configLoadFailureReported = false;\n await telemetry.shutdown();\n };\n\n const plugin = (cordis: Context): void => {\n cordis.inject([DOOM_CONTEXT_CONTRIBUTIONS_SERVICE], (contextContributionsContext) => {\n const service = requireDoomContextContributions(contextContributionsContext);\n contextContributionsService = service;\n return () => {\n if (contextContributionsService === service) contextContributionsService = undefined;\n };\n });\n\n if (doomIntegrations) {\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n const contribution = requireDoomUiHub(uiContext).registerFooter({\n source: FOOTER_SOURCE,\n id: 'autocompact',\n order: FOOTER_ORDER,\n });\n footerContribution = contribution;\n return () => {\n contribution.dispose();\n if (footerContribution === contribution) footerContribution = undefined;\n };\n });\n }\n };\n\n /** Compaction runs off the main thread, so the phase is the only signal the user gets. */\n const refreshStatus = (ctx?: ExtensionContext): void => {\n if (!active) return;\n const phase =\n state.phase === STATE_PHASE.checkpointPending\n ? 'summarizing'\n : state.phase === STATE_PHASE.checkpointReady\n ? 'applying'\n : undefined;\n footerContribution?.update(\n phase ? { fullText: `Compacting p${state.pass}`, compactText: `C${state.pass}` } : undefined,\n );\n const target = ctx ?? currentContext;\n if (target?.hasUI) target.ui.setStatus(STATUS_KEY, phase ? `Compacting pass ${state.pass} (${phase})…` : undefined);\n };\n\n // Every phase transition persists, so this is the one place that keeps the status honest.\n const persist = (): void => {\n if (!active) return;\n pi.appendEntry(STATE_CUSTOM_TYPE, { ...state });\n refreshStatus();\n };\n\n const clearPendingCheckpoint = (): void => {\n delete state.requestId;\n delete state.snapshotLeafId;\n delete state.snapshotTokens;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n };\n\n const completeQueuedPass = (pass: AutocompactPass): void => {\n state.checkpointQueue = state.checkpointQueue.filter((queuedPass) => queuedPass !== pass);\n };\n\n const restore = (ctx: ExtensionContext): void => {\n if (!active) return;\n state = latestPersistedState(ctx.sessionManager.getBranch()) ?? createInitialState();\n const resumablePending =\n state.phase === STATE_PHASE.checkpointReady && state.requestId && state.snapshotLeafId && state.pendingCheckpoint;\n if (resumablePending || state.phase === STATE_PHASE.waiting) return;\n\n checkpointController?.abort();\n checkpointController = undefined;\n state.phase = STATE_PHASE.waiting;\n clearPendingCheckpoint();\n persist();\n };\n\n const resumeAgent = (message: string): void => {\n if (!active) return;\n pi.sendMessage(\n {\n customType: RESUME_MESSAGE_TYPE,\n content: `${message} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,\n display: false,\n details: { version: STATE_VERSION, cycle: state.cycle, pass: state.pass },\n },\n { triggerTurn: true, deliverAs: 'steer' },\n );\n };\n\n /**\n * Both failure paths share one attempt budget: a summarizer that keeps failing would\n * otherwise cost a full summarization call every turn for the rest of the session, so the\n * pass is abandoned once the budget is spent and becomes eligible again on the next cycle.\n */\n const registerFailedAttempt = (\n pass: AutocompactPass,\n failedLeafId: string | undefined,\n ): { attempts: number; exhausted: boolean } => {\n const attempts = state.invalidAttempts + 1;\n const exhausted = attempts >= MAX_INVALID_CHECKPOINT_ATTEMPTS;\n state.phase = STATE_PHASE.waiting;\n if (failedLeafId) state.lastAttemptLeafId = failedLeafId;\n if (exhausted) {\n completeQueuedPass(pass);\n state.exhaustedPasses = [...state.exhaustedPasses, pass];\n state.invalidAttempts = 0;\n } else {\n state.invalidAttempts = attempts;\n }\n clearPendingCheckpoint();\n persist();\n return { attempts, exhausted };\n };\n\n const failCheckpoint = (requestId: string, error: unknown): void => {\n if (!active || requestId !== state.requestId || state.phase !== STATE_PHASE.checkpointPending) return;\n const pass = state.pass;\n const { attempts, exhausted } = registerFailedAttempt(pass, state.snapshotLeafId);\n const reason = error instanceof Error ? error.message : String(error);\n notify(\n currentContext,\n exhausted\n ? `Doom autocompact summarization pass ${pass} failed ${attempts} times and was abandoned: ${reason}`\n : `Doom autocompact summarization pass ${pass} failed: ${reason}`,\n 'error',\n );\n };\n\n // A configuration that cannot be read degrades every later pass silently, and the process\n // warning never reaches the log sink. Report it once per session instead of once per turn.\n const reportConfigLoadFailure = (ctx: ExtensionContext, error: unknown): void => {\n if (!active || configLoadFailureReported) return;\n configLoadFailureReported = true;\n void telemetry.recordWarning(\n AUTOCOMPACT_EVENT.configurationLoadFailed,\n error,\n telemetryAttributes(ctx, { 'autocompact.cycle': state.cycle, 'autocompact.pass': state.pass }),\n );\n };\n\n const reportContributionFailures = (\n ctx: ExtensionContext,\n snapshot: DoomContextContributionsSnapshot,\n attributes: AutocompactEventAttributes,\n ): void => {\n if (!active) return;\n for (const error of snapshot.errors) {\n notify(\n ctx,\n `Doom autocompact context contribution degraded (${error.source}/${error.id}): ${error.message}`,\n 'warning',\n );\n void telemetry.recordWarning(AUTOCOMPACT_EVENT.contextContributionDegraded, new Error(error.message), {\n ...attributes,\n 'autocompact.context_contribution.source': error.source,\n 'autocompact.context_contribution.id': error.id,\n 'autocompact.context_contribution.order': error.order,\n });\n }\n };\n\n const preserveRuntimeState = (\n ctx: ExtensionContext,\n branch: SessionEntry[],\n attributes: AutocompactEventAttributes,\n ): RuntimeStateSnapshot => {\n if (!active) {\n return { contributions: [], contributionErrors: [] };\n }\n const contextContributions = readContextContributionsSnapshot(contextContributionsService);\n reportContributionFailures(ctx, contextContributions, attributes);\n const snapshot = runtimeStateSnapshot(branch, contextContributions);\n pi.sendMessage({\n customType: RUNTIME_STATE_MESSAGE_TYPE,\n content: formatRuntimeState(snapshot),\n display: false,\n details: { version: 2, ...snapshot },\n });\n return snapshot;\n };\n\n const commitCheckpoint = (pass: 2 | 3, ctx: ExtensionContext): boolean => {\n if (!active || !state.requestId || !state.snapshotLeafId || !state.pendingCheckpoint) return false;\n const branch = ctx.sessionManager.getBranch();\n const projected = projectContextMessages(buildSessionContext(branch).messages, branch).messages;\n const fileDetails = mergeFileDetails(state, fileOperationsFromMessages(projected));\n const requestId = state.requestId;\n const cycle = state.cycle;\n const summary = withCanonicalFileSections(state.pendingCheckpoint, fileDetails);\n const details: AutocompactContextDetails = {\n ...fileDetails,\n doomAutocompact: {\n version: STATE_VERSION,\n cycle,\n pass,\n requestId,\n snapshotLeafId: state.snapshotLeafId,\n tokensBefore: state.snapshotTokens ?? ctx.getContextUsage()?.tokens ?? 0,\n },\n retainedMessages: retainedMessagesAfterSnapshot(branch, state.snapshotLeafId),\n };\n\n const committedWhileIdle = ctx.isIdle();\n pi.sendMessage({ customType: CONTEXT_MESSAGE_TYPE, content: summary, display: false, details });\n const contextMessageLeafId = workingLeafId(ctx);\n const runtimeAttributes = telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': cycle,\n 'autocompact.pass': pass,\n });\n const runtimeSnapshot = preserveRuntimeState(ctx, branch, runtimeAttributes);\n // Mid-run the marker is queued as a steering message, so its entry id is not resolvable yet.\n if (committedWhileIdle) pi.setLabel(contextMessageLeafId, `autocompact:c${cycle}:p${pass}`);\n\n state.readFiles = fileDetails.readFiles;\n state.modifiedFiles = fileDetails.modifiedFiles;\n delete state.latestCheckpointSnapshotLeafId;\n state.phase = STATE_PHASE.waiting;\n state.checkpointQueue = [];\n // A compacted context is a fresh ladder: passes abandoned in the previous cycle are eligible again.\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n state.baselinePending = true;\n delete state.lastAttemptLeafId;\n clearPendingCheckpoint();\n state.cycle += 1;\n state.pass = 1;\n persist();\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextCommitted,\n telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': cycle,\n 'autocompact.pass': pass,\n 'autocompact.snapshot_leaf_id': details.doomAutocompact.snapshotLeafId,\n 'autocompact.tokens_before': details.doomAutocompact.tokensBefore,\n 'autocompact.message_count.before': projected.length,\n 'autocompact.message_count.retained': details.retainedMessages.length,\n 'autocompact.apply_mode': committedWhileIdle ? 'idle' : 'turn_end',\n ...runtimeTelemetryAttributes(runtimeSnapshot),\n }),\n );\n // A mid-run commit needs no resume steer: the agent is already continuing.\n if (committedWhileIdle) resumeAgent('Asynchronous compaction completed.');\n return true;\n };\n\n const requestCheckpoint = (pass: AutocompactPass, ctx: ExtensionContext, tokensBefore: number): void => {\n if (!active) return;\n const generation = sessionGeneration;\n const branch = ctx.sessionManager.getBranch();\n const snapshotLeafId = workingLeafId(ctx);\n const requestId = createRequestId(ctx.sessionManager.getSessionId(), state.cycle, pass, snapshotLeafId);\n const previousCheckpoint = pass > 1 ? checkpointSummaryFromEntry(latestCheckpointArtifactEntry(branch)) : undefined;\n const messages = messagesForCheckpoint(pass, branch, state.latestCheckpointSnapshotLeafId);\n const contextContributions = readContextContributionsSnapshot(contextContributionsService);\n const attributes = telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': pass,\n 'autocompact.snapshot_leaf_id': snapshotLeafId,\n 'autocompact.tokens_before': tokensBefore,\n 'autocompact.message_count.before': messages.length,\n });\n reportContributionFailures(ctx, contextContributions, attributes);\n\n state.phase = STATE_PHASE.checkpointPending;\n state.pass = pass;\n state.requestId = requestId;\n state.snapshotLeafId = snapshotLeafId;\n state.snapshotTokens = tokensBefore;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n delete state.lastAttemptLeafId;\n persist();\n\n checkpointController?.abort();\n checkpointController = new AbortController();\n const checkpointSignal = checkpointController.signal;\n const operation = telemetry\n .runInSpan('doom_autocompact.checkpoint', attributes, async () => {\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointStarted, attributes);\n try {\n const checkpoint = await generateCheckpoint({\n messages,\n instructions: checkpointInstructions(pass, {\n plan: latestPlanSnapshot(branch),\n contextContributions,\n readFiles: state.readFiles,\n modifiedFiles: state.modifiedFiles,\n }),\n ...(previousCheckpoint ? { previousCheckpoint } : {}),\n context: ctx,\n signal: checkpointSignal,\n });\n if (!active || generation !== sessionGeneration) {\n throw checkpointSignal.reason ?? new Error('Autocompact checkpoint became stale.');\n }\n if (!checkpoint.trim()) throw new Error('Summarization returned an empty checkpoint.');\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointCompleted, {\n ...attributes,\n 'autocompact.checkpoint.characters': checkpoint.length,\n });\n return checkpoint;\n } catch (error) {\n if (active && generation === sessionGeneration) {\n await telemetry.recordError(AUTOCOMPACT_EVENT.checkpointFailed, error, attributes);\n }\n throw error;\n }\n })\n .then((checkpoint) => {\n if (\n !active ||\n generation !== sessionGeneration ||\n requestId !== state.requestId ||\n state.phase !== STATE_PHASE.checkpointPending\n ) {\n return;\n }\n state.phase = STATE_PHASE.checkpointReady;\n state.pendingCheckpoint = checkpoint.trim();\n persist();\n if (currentContext) processProgress(currentContext);\n })\n .catch((error: unknown) => {\n if (active && generation === sessionGeneration) failCheckpoint(requestId, error);\n });\n checkpointWork.add(operation);\n void operation.finally(() => checkpointWork.delete(operation));\n };\n\n const evaluateUsage = (ctx: ExtensionContext): boolean => {\n if (!active || state.phase !== STATE_PHASE.waiting || ctx.hasPendingMessages()) return false;\n // Read per evaluation rather than once at install, so turning the ladder off\n // or moving a threshold in settings takes effect on the next turn instead of\n // the next session.\n const configured = autocompactRuntimeConfig(ctx.cwd, (error) => reportConfigLoadFailure(ctx, error));\n if (!configured.enabled) return false;\n const usage = ctx.getContextUsage();\n if (!usage || usage.tokens === null) return false;\n if (state.baselinePending) {\n // Reported usage still describes the pre-compaction context until an assistant\n // responds against the projected one, and capturing it early poisons every threshold.\n if (!baselineUsageIsSettled(ctx.sessionManager.getBranch())) return false;\n state.baselineTokens = usage.tokens;\n state.baselinePending = false;\n persist();\n return false;\n }\n const leafId = workingLeafId(ctx);\n if (state.lastAttemptLeafId === leafId) return false;\n\n // The baseline branch above always returns, so by here it is settled for this cycle and the\n // token overrides can be compared against it without re-checking `baselinePending`.\n const tokenOverrides = resolveModelTokenOverrides(ctx.model, configured.overrides);\n const thresholds = effectiveThresholds(\n usage.contextWindow,\n state.baselineTokens,\n configured.ratios,\n tokenOverrides,\n );\n for (const pass of [1, 2, 3] as const) {\n if (pass < state.pass || state.checkpointQueue.includes(pass) || state.exhaustedPasses.includes(pass)) continue;\n if (usage.tokens >= thresholds[pass]) {\n state.checkpointQueue.push(pass);\n }\n }\n const nextPass = state.checkpointQueue[0];\n if (!nextPass) return false;\n requestCheckpoint(nextPass, ctx, usage.tokens);\n return true;\n };\n\n // Staged checkpoints seed the next summarization pass only. They are appended as plain\n // session entries so they never enter the agent's LLM context: delivering them as messages\n // reads like a user instruction and derails the run (\"Checkpoint acknowledged...\").\n const stageCheckpoint = (pass: 1 | 2, summary: string): void => {\n if (!active) return;\n const checkpointSnapshotLeafId = state.snapshotLeafId;\n pi.appendEntry(CHECKPOINT_MESSAGE_TYPE, {\n ...checkpointRequestDetails(state.cycle, pass, state.requestId ?? 'completed'),\n summary,\n });\n if (checkpointSnapshotLeafId) state.latestCheckpointSnapshotLeafId = checkpointSnapshotLeafId;\n };\n\n const captureReadyCheckpoint = (ctx: ExtensionContext): CheckpointCapture => {\n if (!active || state.phase !== STATE_PHASE.checkpointReady || !state.requestId || !state.pendingCheckpoint) {\n return 'none';\n }\n const pass = state.pass;\n const decision = parseCheckpointDecision(state.pendingCheckpoint);\n if (!isStructuredCheckpoint(decision.summary)) {\n const failedLeafId = state.snapshotLeafId;\n const invalidRequestId = state.requestId;\n // A queued pass is retried once per new leaf, so an output the summarizer never formats\n // correctly would otherwise burn a full summarization call every turn for the session.\n const { attempts, exhausted } = registerFailedAttempt(pass, failedLeafId);\n const error = new Error(`Summarization pass ${pass} returned an incomplete checkpoint.`);\n notify(\n ctx,\n exhausted\n ? `Doom autocompact summarization pass ${pass} returned an incomplete checkpoint ${attempts} times and was abandoned.`\n : `Doom autocompact summarization pass ${pass} returned an incomplete checkpoint.`,\n 'error',\n );\n void telemetry.recordError(\n AUTOCOMPACT_EVENT.checkpointInvalid,\n error,\n telemetryAttributes(ctx, {\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': pass,\n 'autocompact.checkpoint.attempts': attempts,\n 'autocompact.checkpoint.exhausted': exhausted,\n ...(invalidRequestId ? { 'autocompact.request.id': invalidRequestId } : {}),\n }),\n );\n return 'invalid';\n }\n\n state.invalidAttempts = 0;\n\n if (pass === 1) {\n stageCheckpoint(1, decision.summary);\n completeQueuedPass(1);\n state.phase = STATE_PHASE.waiting;\n state.pass = 2;\n clearPendingCheckpoint();\n persist();\n return 'pass1';\n }\n\n if (pass === 2 && decision.shouldCompact !== true) {\n stageCheckpoint(2, decision.summary);\n completeQueuedPass(2);\n state.phase = STATE_PHASE.waiting;\n state.pass = 3;\n clearPendingCheckpoint();\n persist();\n return 'deferred';\n }\n\n state.pendingCheckpoint = decision.summary;\n return commitCheckpoint(pass, ctx) ? 'committed' : 'invalid';\n };\n\n function processProgress(ctx: ExtensionContext): void {\n if (!active) return;\n currentContext = ctx;\n if (!ctx.isIdle()) return;\n if (captureReadyCheckpoint(ctx) !== 'committed') evaluateUsage(ctx);\n }\n\n const beginSessionGeneration = (ctx: ExtensionContext): void => {\n if (!active) return;\n sessionGeneration += 1;\n checkpointController?.abort(new Error('Autocompact session generation was replaced.'));\n checkpointController = undefined;\n appliedContextRequests.clear();\n invalidContextLeaves.clear();\n currentContext = ctx;\n restore(ctx);\n processProgress(ctx);\n };\n\n /**\n * Replaces the messages pi is about to send with the projection the last\n * applied checkpoint describes. Split out from the hook so the hook can time\n * it without threading a duration through three return paths.\n */\n const shapeContext = (event: ContextEvent, ctx: ExtensionContext) => {\n if (!active) return undefined;\n const projection = projectContextMessages(event.messages, ctx.sessionManager.getBranch());\n if (projection.invalidMarker) {\n const leafId = ctx.sessionManager.getLeafId() ?? ROOT_WORKING_LEAF;\n if (!invalidContextLeaves.has(leafId)) {\n invalidContextLeaves.add(leafId);\n void telemetry.recordError(\n AUTOCOMPACT_EVENT.contextMarkerInvalid,\n new Error('Doom autocompact context marker is malformed.'),\n telemetryAttributes(ctx, { 'autocompact.leaf_id': leafId }),\n );\n }\n return undefined;\n }\n if (!projection.marker) return undefined;\n if (!appliedContextRequests.has(projection.marker.requestId)) {\n appliedContextRequests.add(projection.marker.requestId);\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextApplied,\n telemetryAttributes(ctx, {\n 'autocompact.request.id': projection.marker.requestId,\n 'autocompact.cycle': projection.marker.cycle,\n 'autocompact.pass': projection.marker.pass,\n 'autocompact.snapshot_leaf_id': projection.marker.snapshotLeafId,\n 'autocompact.tokens_before': projection.marker.tokensBefore,\n 'autocompact.message_count.before': event.messages.length,\n 'autocompact.message_count.after': projection.messages.length,\n 'autocompact.message_count.retained': projection.retainedMessageCount,\n }),\n );\n }\n return { messages: projection.messages };\n };\n return {\n plugin,\n stop,\n events: {\n context: (event, ctx) => {\n // pi awaits this hook inside every request and the body walks the whole\n // branch, so it is one of the few costs that can grow with a session's\n // length. Reported only past the threshold: a hook this hot would\n // otherwise emit an event per request.\n const hookStartedAt = Date.now();\n try {\n return shapeContext(event, ctx);\n } finally {\n const hookMs = Date.now() - hookStartedAt;\n if (hookMs >= SLOW_CONTEXT_HOOK_MS) {\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextHookSlow,\n telemetryAttributes(ctx, { hook_ms: hookMs, 'autocompact.message_count': event.messages.length }),\n );\n }\n }\n },\n\n session_start: (_event, ctx) => beginSessionGeneration(ctx),\n\n session_tree: (_event, ctx) => beginSessionGeneration(ctx),\n\n turn_end: (event, ctx) => {\n if (!active) return;\n currentContext = ctx;\n if (ctx.isIdle()) {\n processProgress(ctx);\n return;\n }\n // A ready checkpoint must be applied without waiting for the run to finish, otherwise\n // context keeps growing past the window for the rest of a long autonomous run. Tool\n // results confirm the run continues, so the queued marker lands before the next request.\n const canApplyDuringRun =\n state.phase === STATE_PHASE.checkpointReady &&\n (event.toolResults?.length ?? 0) > 0 &&\n !ctx.hasPendingMessages();\n if (canApplyDuringRun && captureReadyCheckpoint(ctx) !== 'none') return;\n evaluateUsage(ctx);\n },\n\n agent_settled: (_event, ctx) => {\n if (!active) return;\n processProgress(ctx);\n },\n\n session_before_compact: (event) => {\n if (!active || event.reason !== 'threshold') return undefined;\n // Native compaction stays cancelled while our own machinery is working, and stays\n // available as the emergency backstop once that machinery has stalled or declined.\n const machineryActive =\n state.phase === STATE_PHASE.checkpointPending ||\n state.phase === STATE_PHASE.checkpointReady ||\n state.baselinePending;\n return machineryActive ? { cancel: true } : undefined;\n },\n\n session_compact: (event, ctx) => {\n if (!active) return;\n sessionGeneration += 1;\n // Native compaction supersedes any summarization still in flight.\n checkpointController?.abort();\n checkpointController = undefined;\n const eventDetails = fileDetailsFromUnknown(event.compactionEntry.details);\n const cumulative = mergeFileDetails(state, undefined, eventDetails);\n state.readFiles = cumulative.readFiles;\n state.modifiedFiles = cumulative.modifiedFiles;\n delete state.latestCheckpointSnapshotLeafId;\n // Reported usage still describes the pre-compaction context here too, so the baseline\n // waits for the first assistant response measured against the compacted one.\n state.baselinePending = true;\n state.phase = STATE_PHASE.waiting;\n clearPendingCheckpoint();\n state.checkpointQueue = [];\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n delete state.lastAttemptLeafId;\n\n pi.setLabel(event.compactionEntry.id, `autocompact:c${state.cycle}:external`);\n const completedCycle = state.cycle;\n const runtimeAttributes = telemetryAttributes(ctx, {\n 'autocompact.cycle': completedCycle,\n 'autocompact.native.reason': event.reason,\n });\n const runtimeSnapshot = preserveRuntimeState(ctx, ctx.sessionManager.getBranch(), runtimeAttributes);\n state.cycle += 1;\n state.pass = 1;\n persist();\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.nativeCompactionCompleted,\n telemetryAttributes(ctx, {\n 'autocompact.cycle': completedCycle,\n 'autocompact.native.reason': event.reason,\n 'autocompact.native.from_extension': event.fromExtension,\n 'autocompact.tokens_before': event.compactionEntry.tokensBefore,\n ...runtimeTelemetryAttributes(runtimeSnapshot),\n }),\n );\n },\n },\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/autocompactRuntime/index.ts"],"mappings":";;;;;;;KAwEK,qBAAqB,kBAAkB;UAoBlC;EACR,UAAU;EACV;EACA;EACA,SAAS;EACT,QAAQ;;iBAGO;EACf,sBAAsB,OAAO,8BAA8B;EAC3D,gBAAgB,SAAS,qBAAqB;EAC9C,YAAY;EACZ"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/autocompactRuntime/index.ts"],"mappings":";;;;;;;KAyEK,qBAAqB,kBAAkB;UAoBlC;EACR,UAAU;EACV;EACA;EACA,SAAS;EACT,QAAQ;;iBAGO;EACf,sBAAsB,OAAO,8BAA8B;EAC3D,gBAAgB,SAAS,qBAAqB;EAC9C,YAAY;EACZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/autocompactRuntime/index.ts"],"mappings":";;;;;;;KAwEK,qBAAqB,kBAAkB;UAoBlC;EACR,UAAU;EACV;EACA;EACA,SAAS;EACT,QAAQ;;iBAGO;EACf,sBAAsB,OAAO,8BAA8B;EAC3D,gBAAgB,SAAS,qBAAqB;EAC9C,YAAY;EACZ"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/autocompactRuntime/index.ts"],"mappings":";;;;;;;KAyEK,qBAAqB,kBAAkB;UAoBlC;EACR,UAAU;EACV;EACA;EACA,SAAS;EACT,QAAQ;;iBAGO;EACf,sBAAsB,OAAO,8BAA8B;EAC3D,gBAAgB,SAAS,qBAAqB;EAC9C,YAAY;EACZ"}
@@ -40,5 +40,5 @@ ${n}Return only the decision tag when required, followed by a concise structured
40
40
  ### Blocked
41
41
  ## Key Decisions
42
42
  ## Next Steps
43
- ## Critical Context`}function me(e,t,n){let r=_(C(t).messages,t).messages;if(e===1||!n)return r;let i=t.findIndex(e=>e.id===n);return i===-1?r:t.slice(i+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>T(e))}const R={enabled:!0,ratios:{},overrides:[]};function z(e,t){let n;try{n=D(E().root??e).modes}catch(e){return process.emitWarning(`Doom autocompact configuration could not be loaded; using the active session model instead.`),t?.(e),R}let r=n?.autocompact,i=(r&&(r.model!==void 0||r.thinking!==void 0)?{...r.model?{model:r.model}:{},...r.thinking?{thinking:r.thinking}:{}}:void 0)??n?.planning?.subagents,a=r?.thresholds;return{enabled:r?.enabled??!0,...i?{agent:i}:{},ratios:{...a?.pass1===void 0?{}:{1:a.pass1},...a?.pass2===void 0?{}:{2:a.pass2},...a?.pass3===void 0?{}:{3:a.pass3}},overrides:r?.overrides??[]}}function B(e){let t=z(e.cwd).agent,n=t?.model?x(t.model):void 0,r=n?e.modelRegistry.find(n.provider,n.modelId):void 0,i=r??e.model;if(!i)return;let a=t?.thinking??(r?n?.thinking:void 0)??e.thinkingLevel;return{model:i,...a?{thinkingLevel:a}:{}}}async function V(e,t){let n=t(e.context);if(!n)throw Error(`No active model is available for autocompact summarization.`);let r=await e.context.modelRegistry.getApiKeyAndHeaders(n.model);if(!r.ok)throw Error(r.error);let i=e.context.modelRegistry.getProvider(n.model.provider);if(!i)throw Error(`No provider is registered for "${n.model.provider}" in this session.`);return w(e.messages,n.model,S.reserveTokens,r.apiKey,r.headers,e.signal,e.instructions,e.previousCheckpoint,n.thinkingLevel,(e,t,n)=>i.streamSimple(e,t,n),r.env)}function H(e,t,n=`info`){e?.hasUI&&e.ui.notify(t,n)}function U(g,v={}){let x=v.resolveModel??B,S=v.generateCheckpoint??(e=>V(e,x)),w=v.telemetry??ae(),T=v.doomIntegrations??!0,E=new Set,D=new Set,j=new Set,N=!0,F=0,L=c(),R,U,W,G,K=!1,he=async()=>{N=!1,F+=1,U?.abort(Error(`Autocompact runtime is shutting down.`)),U=void 0,await Promise.allSettled(j),W=void 0,G=void 0,R=void 0,E.clear(),D.clear(),L=c(),K=!1,await w.shutdown()},ge=e=>{e.inject([O],e=>{let t=se(e);return G=t,()=>{G===t&&(G=void 0)}}),T&&e.inject([ce],e=>{let t=le(e).registerFooter({source:re,id:`autocompact`,order:20});return W=t,()=>{t.dispose(),W===t&&(W=void 0)}})},_e=e=>{if(!N)return;let t=L.phase===y.checkpointPending?`summarizing`:L.phase===y.checkpointReady?`applying`:void 0;W?.update(t?{fullText:`Compacting p${L.pass}`,compactText:`C${L.pass}`}:void 0);let n=e??R;n?.hasUI&&n.ui.setStatus(ie,t?`Compacting pass ${L.pass} (${t})…`:void 0)},q=()=>{N&&(g.appendEntry(i,{...L}),_e())},J=()=>{delete L.requestId,delete L.snapshotLeafId,delete L.snapshotTokens,delete L.pendingCheckpoint,delete L.compactionPass},Y=e=>{L.checkpointQueue=L.checkpointQueue.filter(t=>t!==e)},ve=e=>{N&&(L=ue(e.sessionManager.getBranch())??c(),!(L.phase===y.checkpointReady&&L.requestId&&L.snapshotLeafId&&L.pendingCheckpoint||L.phase===y.waiting)&&(U?.abort(),U=void 0,L.phase=y.waiting,J(),q()))},ye=e=>{N&&g.sendMessage({customType:n,content:`${e} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,display:!1,details:{version:2,cycle:L.cycle,pass:L.pass}},{triggerTurn:!0,deliverAs:`steer`})},X=(e,t)=>{let n=L.invalidAttempts+1,r=n>=3;return L.phase=y.waiting,t&&(L.lastAttemptLeafId=t),r?(Y(e),L.exhaustedPasses=[...L.exhaustedPasses,e],L.invalidAttempts=0):L.invalidAttempts=n,J(),q(),{attempts:n,exhausted:r}},be=(e,t)=>{if(!N||e!==L.requestId||L.phase!==y.checkpointPending)return;let n=L.pass,{attempts:r,exhausted:i}=X(n,L.snapshotLeafId),a=t instanceof Error?t.message:String(t);H(R,i?`Doom autocompact summarization pass ${n} failed ${r} times and was abandoned: ${a}`:`Doom autocompact summarization pass ${n} failed: ${a}`,`error`)},xe=(e,t)=>{N&&!K&&(K=!0,w.recordWarning(b.configurationLoadFailed,t,k(e,{"autocompact.cycle":L.cycle,"autocompact.pass":L.pass})))},Se=(e,t,n)=>{if(N)for(let r of t.errors)H(e,`Doom autocompact context contribution degraded (${r.source}/${r.id}): ${r.message}`,`warning`),w.recordWarning(b.contextContributionDegraded,Error(r.message),{...n,"autocompact.context_contribution.source":r.source,"autocompact.context_contribution.id":r.id,"autocompact.context_contribution.order":r.order})},Z=(e,t,n)=>{if(!N)return{contributions:[],contributionErrors:[]};let i=P(G);Se(e,i,n);let a=de(t,i);return g.sendMessage({customType:r,content:fe(a),display:!1,details:{version:2,...a}}),a},Ce=(e,n)=>{if(!N||!L.requestId||!L.snapshotLeafId||!L.pendingCheckpoint)return!1;let r=n.sessionManager.getBranch(),i=_(C(r).messages,r).messages,a=h(L,f(i)),o=L.requestId,s=L.cycle,c=ne(L.pendingCheckpoint,a),l={...a,doomAutocompact:{version:2,cycle:s,pass:e,requestId:o,snapshotLeafId:L.snapshotLeafId,tokensBefore:L.snapshotTokens??n.getContextUsage()?.tokens??0},retainedMessages:te(r,L.snapshotLeafId)},u=n.isIdle();g.sendMessage({customType:t,content:c,display:!1,details:l});let d=A(n),p=k(n,{"autocompact.request.id":o,"autocompact.cycle":s,"autocompact.pass":e}),m=Z(n,r,p);return u&&g.setLabel(d,`autocompact:c${s}:p${e}`),L.readFiles=a.readFiles,L.modifiedFiles=a.modifiedFiles,delete L.latestCheckpointSnapshotLeafId,L.phase=y.waiting,L.checkpointQueue=[],L.exhaustedPasses=[],L.invalidAttempts=0,L.baselinePending=!0,delete L.lastAttemptLeafId,J(),L.cycle+=1,L.pass=1,q(),w.recordEvent(b.contextCommitted,k(n,{"autocompact.request.id":o,"autocompact.cycle":s,"autocompact.pass":e,"autocompact.snapshot_leaf_id":l.doomAutocompact.snapshotLeafId,"autocompact.tokens_before":l.doomAutocompact.tokensBefore,"autocompact.message_count.before":i.length,"autocompact.message_count.retained":l.retainedMessages.length,"autocompact.apply_mode":u?`idle`:`turn_end`,...I(m)})),u&&ye(`Asynchronous compaction completed.`),!0},we=(e,t,n)=>{if(!N)return;let r=F,i=t.sessionManager.getBranch(),a=A(t),o=l(t.sessionManager.getSessionId(),L.cycle,e,a),c=e>1?s(m(i)):void 0,u=me(e,i,L.latestCheckpointSnapshotLeafId),d=P(G),f=k(t,{"autocompact.request.id":o,"autocompact.cycle":L.cycle,"autocompact.pass":e,"autocompact.snapshot_leaf_id":a,"autocompact.tokens_before":n,"autocompact.message_count.before":u.length});Se(t,d,f),L.phase=y.checkpointPending,L.pass=e,L.requestId=o,L.snapshotLeafId=a,L.snapshotTokens=n,delete L.pendingCheckpoint,delete L.compactionPass,delete L.lastAttemptLeafId,q(),U?.abort(),U=new AbortController;let p=U.signal,h=w.runInSpan(`doom_autocompact.checkpoint`,f,async()=>{await w.recordEvent(b.checkpointStarted,f);try{let n=await S({messages:u,instructions:pe(e,{plan:M(i),contextContributions:d,readFiles:L.readFiles,modifiedFiles:L.modifiedFiles}),...c?{previousCheckpoint:c}:{},context:t,signal:p});if(!N||r!==F)throw p.reason??Error(`Autocompact checkpoint became stale.`);if(!n.trim())throw Error(`Summarization returned an empty checkpoint.`);return await w.recordEvent(b.checkpointCompleted,{...f,"autocompact.checkpoint.characters":n.length}),n}catch(e){throw N&&r===F&&await w.recordError(b.checkpointFailed,e,f),e}}).then(e=>{N&&r===F&&o===L.requestId&&L.phase===y.checkpointPending&&(L.phase=y.checkpointReady,L.pendingCheckpoint=e.trim(),q(),R&&Q(R))}).catch(e=>{N&&r===F&&be(o,e)});j.add(h),h.finally(()=>j.delete(h))},Te=e=>{if(!N||L.phase!==y.waiting||e.hasPendingMessages())return!1;let t=z(e.cwd,t=>xe(e,t));if(!t.enabled)return!1;let n=e.getContextUsage();if(!n||n.tokens===null)return!1;if(L.baselinePending)return a(e.sessionManager.getBranch())?(L.baselineTokens=n.tokens,L.baselinePending=!1,q(),!1):!1;let r=A(e);if(L.lastAttemptLeafId===r)return!1;let i=oe(e.model,t.overrides),o=u(n.contextWindow,L.baselineTokens,t.ratios,i);for(let e of[1,2,3])e<L.pass||L.checkpointQueue.includes(e)||L.exhaustedPasses.includes(e)||n.tokens>=o[e]&&L.checkpointQueue.push(e);let s=L.checkpointQueue[0];return s?(we(s,e,n.tokens),!0):!1},Ee=(t,n)=>{if(!N)return;let r=L.snapshotLeafId;g.appendEntry(e,{...o(L.cycle,t,L.requestId??`completed`),summary:n}),r&&(L.latestCheckpointSnapshotLeafId=r)},De=e=>{if(!N||L.phase!==y.checkpointReady||!L.requestId||!L.pendingCheckpoint)return`none`;let t=L.pass,n=ee(L.pendingCheckpoint);if(!p(n.summary)){let n=L.snapshotLeafId,r=L.requestId,{attempts:i,exhausted:a}=X(t,n),o=Error(`Summarization pass ${t} returned an incomplete checkpoint.`);return H(e,a?`Doom autocompact summarization pass ${t} returned an incomplete checkpoint ${i} times and was abandoned.`:`Doom autocompact summarization pass ${t} returned an incomplete checkpoint.`,`error`),w.recordError(b.checkpointInvalid,o,k(e,{"autocompact.cycle":L.cycle,"autocompact.pass":t,"autocompact.checkpoint.attempts":i,"autocompact.checkpoint.exhausted":a,...r?{"autocompact.request.id":r}:{}})),`invalid`}return L.invalidAttempts=0,t===1?(Ee(1,n.summary),Y(1),L.phase=y.waiting,L.pass=2,J(),q(),`pass1`):t===2&&n.shouldCompact!==!0?(Ee(2,n.summary),Y(2),L.phase=y.waiting,L.pass=3,J(),q(),`deferred`):(L.pendingCheckpoint=n.summary,Ce(t,e)?`committed`:`invalid`)};function Q(e){N&&(R=e,e.isIdle()&&De(e)!==`committed`&&Te(e))}let $=e=>{N&&(F+=1,U?.abort(Error(`Autocompact session generation was replaced.`)),U=void 0,E.clear(),D.clear(),R=e,ve(e),Q(e))};return{plugin:ge,stop:he,events:{context:(e,t)=>{if(!N)return;let n=_(e.messages,t.sessionManager.getBranch());if(n.invalidMarker){let e=t.sessionManager.getLeafId()??`@root`;D.has(e)||(D.add(e),w.recordError(b.contextMarkerInvalid,Error(`Doom autocompact context marker is malformed.`),k(t,{"autocompact.leaf_id":e})));return}if(n.marker)return E.has(n.marker.requestId)||(E.add(n.marker.requestId),w.recordEvent(b.contextApplied,k(t,{"autocompact.request.id":n.marker.requestId,"autocompact.cycle":n.marker.cycle,"autocompact.pass":n.marker.pass,"autocompact.snapshot_leaf_id":n.marker.snapshotLeafId,"autocompact.tokens_before":n.marker.tokensBefore,"autocompact.message_count.before":e.messages.length,"autocompact.message_count.after":n.messages.length,"autocompact.message_count.retained":n.retainedMessageCount}))),{messages:n.messages}},session_start:(e,t)=>$(t),session_tree:(e,t)=>$(t),turn_end:(e,t)=>{if(N){if(R=t,t.isIdle()){Q(t);return}L.phase===y.checkpointReady&&(e.toolResults?.length??0)>0&&!t.hasPendingMessages()&&De(t)!==`none`||Te(t)}},agent_settled:(e,t)=>{N&&Q(t)},session_before_compact:e=>{if(N&&e.reason===`threshold`)return L.phase===y.checkpointPending||L.phase===y.checkpointReady||L.baselinePending?{cancel:!0}:void 0},session_compact:(e,t)=>{if(!N)return;F+=1,U?.abort(),U=void 0;let n=d(e.compactionEntry.details),r=h(L,void 0,n);L.readFiles=r.readFiles,L.modifiedFiles=r.modifiedFiles,delete L.latestCheckpointSnapshotLeafId,L.baselinePending=!0,L.phase=y.waiting,J(),L.checkpointQueue=[],L.exhaustedPasses=[],L.invalidAttempts=0,delete L.lastAttemptLeafId,g.setLabel(e.compactionEntry.id,`autocompact:c${L.cycle}:external`);let i=L.cycle,a=k(t,{"autocompact.cycle":i,"autocompact.native.reason":e.reason}),o=Z(t,t.sessionManager.getBranch(),a);L.cycle+=1,L.pass=1,q(),w.recordEvent(b.nativeCompactionCompleted,k(t,{"autocompact.cycle":i,"autocompact.native.reason":e.reason,"autocompact.native.from_extension":e.fromExtension,"autocompact.tokens_before":e.compactionEntry.tokensBefore,...I(o)}))}}}}export{z as autocompactRuntimeConfig,U as createAutocompactRuntime,V as generateCheckpointWithPi,B as resolveDoomSummarizationModel};
43
+ ## Critical Context`}function me(e,t,n){let r=_(C(t).messages,t).messages;if(e===1||!n)return r;let i=t.findIndex(e=>e.id===n);return i===-1?r:t.slice(i+1).filter(e=>e.type!==`custom_message`||e.customType!==`doom-autocompact-checkpoint`).flatMap(e=>T(e))}const R={enabled:!0,ratios:{},overrides:[]};function z(e,t){let n;try{n=D(E().root??e).modes}catch(e){return process.emitWarning(`Doom autocompact configuration could not be loaded; using the active session model instead.`),t?.(e),R}let r=n?.autocompact,i=(r&&(r.model!==void 0||r.thinking!==void 0)?{...r.model?{model:r.model}:{},...r.thinking?{thinking:r.thinking}:{}}:void 0)??n?.planning?.subagents,a=r?.thresholds;return{enabled:r?.enabled??!0,...i?{agent:i}:{},ratios:{...a?.pass1===void 0?{}:{1:a.pass1},...a?.pass2===void 0?{}:{2:a.pass2},...a?.pass3===void 0?{}:{3:a.pass3}},overrides:r?.overrides??[]}}function B(e){let t=z(e.cwd).agent,n=t?.model?x(t.model):void 0,r=n?e.modelRegistry.find(n.provider,n.modelId):void 0,i=r??e.model;if(!i)return;let a=t?.thinking??(r?n?.thinking:void 0)??e.thinkingLevel;return{model:i,...a?{thinkingLevel:a}:{}}}async function V(e,t){let n=t(e.context);if(!n)throw Error(`No active model is available for autocompact summarization.`);let r=await e.context.modelRegistry.getApiKeyAndHeaders(n.model);if(!r.ok)throw Error(r.error);let i=e.context.modelRegistry.getProvider(n.model.provider);if(!i)throw Error(`No provider is registered for "${n.model.provider}" in this session.`);return w(e.messages,n.model,S.reserveTokens,r.apiKey,r.headers,e.signal,e.instructions,e.previousCheckpoint,n.thinkingLevel,(e,t,n)=>i.streamSimple(e,t,n),r.env)}function H(e,t,n=`info`){e?.hasUI&&e.ui.notify(t,n)}function U(g,v={}){let x=v.resolveModel??B,S=v.generateCheckpoint??(e=>V(e,x)),w=v.telemetry??ae(),T=v.doomIntegrations??!0,E=new Set,D=new Set,j=new Set,N=!0,F=0,L=c(),R,U,W,G,K=!1,he=async()=>{N=!1,F+=1,U?.abort(Error(`Autocompact runtime is shutting down.`)),U=void 0,await Promise.allSettled(j),W=void 0,G=void 0,R=void 0,E.clear(),D.clear(),L=c(),K=!1,await w.shutdown()},ge=e=>{e.inject([O],e=>{let t=se(e);return G=t,()=>{G===t&&(G=void 0)}}),T&&e.inject([ce],e=>{let t=le(e).registerFooter({source:re,id:`autocompact`,order:20});return W=t,()=>{t.dispose(),W===t&&(W=void 0)}})},_e=e=>{if(!N)return;let t=L.phase===y.checkpointPending?`summarizing`:L.phase===y.checkpointReady?`applying`:void 0;W?.update(t?{fullText:`Compacting p${L.pass}`,compactText:`C${L.pass}`}:void 0);let n=e??R;n?.hasUI&&n.ui.setStatus(ie,t?`Compacting pass ${L.pass} (${t})…`:void 0)},q=()=>{N&&(g.appendEntry(i,{...L}),_e())},J=()=>{delete L.requestId,delete L.snapshotLeafId,delete L.snapshotTokens,delete L.pendingCheckpoint,delete L.compactionPass},Y=e=>{L.checkpointQueue=L.checkpointQueue.filter(t=>t!==e)},ve=e=>{N&&(L=ue(e.sessionManager.getBranch())??c(),!(L.phase===y.checkpointReady&&L.requestId&&L.snapshotLeafId&&L.pendingCheckpoint||L.phase===y.waiting)&&(U?.abort(),U=void 0,L.phase=y.waiting,J(),q()))},ye=e=>{N&&g.sendMessage({customType:n,content:`${e} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,display:!1,details:{version:2,cycle:L.cycle,pass:L.pass}},{triggerTurn:!0,deliverAs:`steer`})},X=(e,t)=>{let n=L.invalidAttempts+1,r=n>=3;return L.phase=y.waiting,t&&(L.lastAttemptLeafId=t),r?(Y(e),L.exhaustedPasses=[...L.exhaustedPasses,e],L.invalidAttempts=0):L.invalidAttempts=n,J(),q(),{attempts:n,exhausted:r}},be=(e,t)=>{if(!N||e!==L.requestId||L.phase!==y.checkpointPending)return;let n=L.pass,{attempts:r,exhausted:i}=X(n,L.snapshotLeafId),a=t instanceof Error?t.message:String(t);H(R,i?`Doom autocompact summarization pass ${n} failed ${r} times and was abandoned: ${a}`:`Doom autocompact summarization pass ${n} failed: ${a}`,`error`)},xe=(e,t)=>{N&&!K&&(K=!0,w.recordWarning(b.configurationLoadFailed,t,k(e,{"autocompact.cycle":L.cycle,"autocompact.pass":L.pass})))},Se=(e,t,n)=>{if(N)for(let r of t.errors)H(e,`Doom autocompact context contribution degraded (${r.source}/${r.id}): ${r.message}`,`warning`),w.recordWarning(b.contextContributionDegraded,Error(r.message),{...n,"autocompact.context_contribution.source":r.source,"autocompact.context_contribution.id":r.id,"autocompact.context_contribution.order":r.order})},Z=(e,t,n)=>{if(!N)return{contributions:[],contributionErrors:[]};let i=P(G);Se(e,i,n);let a=de(t,i);return g.sendMessage({customType:r,content:fe(a),display:!1,details:{version:2,...a}}),a},Ce=(e,n)=>{if(!N||!L.requestId||!L.snapshotLeafId||!L.pendingCheckpoint)return!1;let r=n.sessionManager.getBranch(),i=_(C(r).messages,r).messages,a=h(L,f(i)),o=L.requestId,s=L.cycle,c=ne(L.pendingCheckpoint,a),l={...a,doomAutocompact:{version:2,cycle:s,pass:e,requestId:o,snapshotLeafId:L.snapshotLeafId,tokensBefore:L.snapshotTokens??n.getContextUsage()?.tokens??0},retainedMessages:te(r,L.snapshotLeafId)},u=n.isIdle();g.sendMessage({customType:t,content:c,display:!1,details:l});let d=A(n),p=k(n,{"autocompact.request.id":o,"autocompact.cycle":s,"autocompact.pass":e}),m=Z(n,r,p);return u&&g.setLabel(d,`autocompact:c${s}:p${e}`),L.readFiles=a.readFiles,L.modifiedFiles=a.modifiedFiles,delete L.latestCheckpointSnapshotLeafId,L.phase=y.waiting,L.checkpointQueue=[],L.exhaustedPasses=[],L.invalidAttempts=0,L.baselinePending=!0,delete L.lastAttemptLeafId,J(),L.cycle+=1,L.pass=1,q(),w.recordEvent(b.contextCommitted,k(n,{"autocompact.request.id":o,"autocompact.cycle":s,"autocompact.pass":e,"autocompact.snapshot_leaf_id":l.doomAutocompact.snapshotLeafId,"autocompact.tokens_before":l.doomAutocompact.tokensBefore,"autocompact.message_count.before":i.length,"autocompact.message_count.retained":l.retainedMessages.length,"autocompact.apply_mode":u?`idle`:`turn_end`,...I(m)})),u&&ye(`Asynchronous compaction completed.`),!0},we=(e,t,n)=>{if(!N)return;let r=F,i=t.sessionManager.getBranch(),a=A(t),o=l(t.sessionManager.getSessionId(),L.cycle,e,a),c=e>1?s(m(i)):void 0,u=me(e,i,L.latestCheckpointSnapshotLeafId),d=P(G),f=k(t,{"autocompact.request.id":o,"autocompact.cycle":L.cycle,"autocompact.pass":e,"autocompact.snapshot_leaf_id":a,"autocompact.tokens_before":n,"autocompact.message_count.before":u.length});Se(t,d,f),L.phase=y.checkpointPending,L.pass=e,L.requestId=o,L.snapshotLeafId=a,L.snapshotTokens=n,delete L.pendingCheckpoint,delete L.compactionPass,delete L.lastAttemptLeafId,q(),U?.abort(),U=new AbortController;let p=U.signal,h=w.runInSpan(`doom_autocompact.checkpoint`,f,async()=>{await w.recordEvent(b.checkpointStarted,f);try{let n=await S({messages:u,instructions:pe(e,{plan:M(i),contextContributions:d,readFiles:L.readFiles,modifiedFiles:L.modifiedFiles}),...c?{previousCheckpoint:c}:{},context:t,signal:p});if(!N||r!==F)throw p.reason??Error(`Autocompact checkpoint became stale.`);if(!n.trim())throw Error(`Summarization returned an empty checkpoint.`);return await w.recordEvent(b.checkpointCompleted,{...f,"autocompact.checkpoint.characters":n.length}),n}catch(e){throw N&&r===F&&await w.recordError(b.checkpointFailed,e,f),e}}).then(e=>{N&&r===F&&o===L.requestId&&L.phase===y.checkpointPending&&(L.phase=y.checkpointReady,L.pendingCheckpoint=e.trim(),q(),R&&Q(R))}).catch(e=>{N&&r===F&&be(o,e)});j.add(h),h.finally(()=>j.delete(h))},Te=e=>{if(!N||L.phase!==y.waiting||e.hasPendingMessages())return!1;let t=z(e.cwd,t=>xe(e,t));if(!t.enabled)return!1;let n=e.getContextUsage();if(!n||n.tokens===null)return!1;if(L.baselinePending)return a(e.sessionManager.getBranch())?(L.baselineTokens=n.tokens,L.baselinePending=!1,q(),!1):!1;let r=A(e);if(L.lastAttemptLeafId===r)return!1;let i=oe(e.model,t.overrides),o=u(n.contextWindow,L.baselineTokens,t.ratios,i);for(let e of[1,2,3])e<L.pass||L.checkpointQueue.includes(e)||L.exhaustedPasses.includes(e)||n.tokens>=o[e]&&L.checkpointQueue.push(e);let s=L.checkpointQueue[0];return s?(we(s,e,n.tokens),!0):!1},Ee=(t,n)=>{if(!N)return;let r=L.snapshotLeafId;g.appendEntry(e,{...o(L.cycle,t,L.requestId??`completed`),summary:n}),r&&(L.latestCheckpointSnapshotLeafId=r)},De=e=>{if(!N||L.phase!==y.checkpointReady||!L.requestId||!L.pendingCheckpoint)return`none`;let t=L.pass,n=ee(L.pendingCheckpoint);if(!p(n.summary)){let n=L.snapshotLeafId,r=L.requestId,{attempts:i,exhausted:a}=X(t,n),o=Error(`Summarization pass ${t} returned an incomplete checkpoint.`);return H(e,a?`Doom autocompact summarization pass ${t} returned an incomplete checkpoint ${i} times and was abandoned.`:`Doom autocompact summarization pass ${t} returned an incomplete checkpoint.`,`error`),w.recordError(b.checkpointInvalid,o,k(e,{"autocompact.cycle":L.cycle,"autocompact.pass":t,"autocompact.checkpoint.attempts":i,"autocompact.checkpoint.exhausted":a,...r?{"autocompact.request.id":r}:{}})),`invalid`}return L.invalidAttempts=0,t===1?(Ee(1,n.summary),Y(1),L.phase=y.waiting,L.pass=2,J(),q(),`pass1`):t===2&&n.shouldCompact!==!0?(Ee(2,n.summary),Y(2),L.phase=y.waiting,L.pass=3,J(),q(),`deferred`):(L.pendingCheckpoint=n.summary,Ce(t,e)?`committed`:`invalid`)};function Q(e){N&&(R=e,e.isIdle()&&De(e)!==`committed`&&Te(e))}let $=e=>{N&&(F+=1,U?.abort(Error(`Autocompact session generation was replaced.`)),U=void 0,E.clear(),D.clear(),R=e,ve(e),Q(e))},Oe=(e,t)=>{if(!N)return;let n=_(e.messages,t.sessionManager.getBranch());if(n.invalidMarker){let e=t.sessionManager.getLeafId()??`@root`;D.has(e)||(D.add(e),w.recordError(b.contextMarkerInvalid,Error(`Doom autocompact context marker is malformed.`),k(t,{"autocompact.leaf_id":e})));return}if(n.marker)return E.has(n.marker.requestId)||(E.add(n.marker.requestId),w.recordEvent(b.contextApplied,k(t,{"autocompact.request.id":n.marker.requestId,"autocompact.cycle":n.marker.cycle,"autocompact.pass":n.marker.pass,"autocompact.snapshot_leaf_id":n.marker.snapshotLeafId,"autocompact.tokens_before":n.marker.tokensBefore,"autocompact.message_count.before":e.messages.length,"autocompact.message_count.after":n.messages.length,"autocompact.message_count.retained":n.retainedMessageCount}))),{messages:n.messages}};return{plugin:ge,stop:he,events:{context:(e,t)=>{let n=Date.now();try{return Oe(e,t)}finally{let r=Date.now()-n;r>=25&&w.recordEvent(b.contextHookSlow,k(t,{hook_ms:r,"autocompact.message_count":e.messages.length}))}},session_start:(e,t)=>$(t),session_tree:(e,t)=>$(t),turn_end:(e,t)=>{if(N){if(R=t,t.isIdle()){Q(t);return}L.phase===y.checkpointReady&&(e.toolResults?.length??0)>0&&!t.hasPendingMessages()&&De(t)!==`none`||Te(t)}},agent_settled:(e,t)=>{N&&Q(t)},session_before_compact:e=>{if(N&&e.reason===`threshold`)return L.phase===y.checkpointPending||L.phase===y.checkpointReady||L.baselinePending?{cancel:!0}:void 0},session_compact:(e,t)=>{if(!N)return;F+=1,U?.abort(),U=void 0;let n=d(e.compactionEntry.details),r=h(L,void 0,n);L.readFiles=r.readFiles,L.modifiedFiles=r.modifiedFiles,delete L.latestCheckpointSnapshotLeafId,L.baselinePending=!0,L.phase=y.waiting,J(),L.checkpointQueue=[],L.exhaustedPasses=[],L.invalidAttempts=0,delete L.lastAttemptLeafId,g.setLabel(e.compactionEntry.id,`autocompact:c${L.cycle}:external`);let i=L.cycle,a=k(t,{"autocompact.cycle":i,"autocompact.native.reason":e.reason}),o=Z(t,t.sessionManager.getBranch(),a);L.cycle+=1,L.pass=1,q(),w.recordEvent(b.nativeCompactionCompleted,k(t,{"autocompact.cycle":i,"autocompact.native.reason":e.reason,"autocompact.native.from_extension":e.fromExtension,"autocompact.tokens_before":e.compactionEntry.tokensBefore,...I(o)}))}}}}export{z as autocompactRuntimeConfig,U as createAutocompactRuntime,V as generateCheckpointWithPi,B as resolveDoomSummarizationModel};
44
44
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/autocompactRuntime/index.ts"],"sourcesContent":["import {\n getHarnessState,\n loadDoomConfig,\n type AutocompactOverrideConfig,\n type PlanningAgentConfig,\n} from '@agimon-ai/doompi-config';\nimport {\n DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n requireDoomContextContributions,\n type DoomContextContributionEntry,\n type DoomContextContributionError,\n type DoomContextContributionsService,\n type DoomContextContributionsSnapshot,\n} from '@agimon-ai/doompi-core/context-contributions';\nimport type { DoomFooterContributionHandle } from '@agimon-ai/doompi-core/footer';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/ui-hub';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext, SessionEntry } from '@earendil-works/pi-coding-agent';\nimport {\n buildSessionContext,\n DEFAULT_COMPACTION_SETTINGS,\n generateSummary,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\n\nimport {\n CHECKPOINT_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n MAX_INVALID_CHECKPOINT_ATTEMPTS,\n RESUME_MESSAGE_TYPE,\n RUNTIME_STATE_MESSAGE_TYPE,\n STATE_CUSTOM_TYPE,\n STATE_VERSION,\n} from '../../constants/autocompact';\nimport {\n ROOT_WORKING_LEAF,\n PLAN_DOCUMENT_ENTRY,\n FOOTER_SOURCE,\n FOOTER_ORDER,\n STATUS_KEY,\n STATE_PHASE,\n} from '../../constants/runtime';\nimport type {\n AutocompactContextDetails,\n AutocompactPass,\n AutocompactRatioOverrides,\n AutocompactState,\n} from '../../types/autocompact';\nimport type { AutocompactEventAttributes, AutocompactTelemetry } from '../autocompactTelemetry';\nimport { AUTOCOMPACT_EVENT, createAutocompactTelemetry } from '../autocompactTelemetry';\nimport {\n baselineUsageIsSettled,\n checkpointRequestDetails,\n checkpointSummaryFromEntry,\n createInitialState,\n createRequestId,\n fileDetailsFromUnknown,\n fileOperationsFromMessages,\n isStructuredCheckpoint,\n latestCheckpointArtifactEntry,\n mergeFileDetails,\n parseCheckpointDecision,\n parseState,\n projectContextMessages,\n retainedMessagesAfterSnapshot,\n effectiveThresholds,\n withCanonicalFileSections,\n} from '../compactionPolicy';\nimport { resolveModelTokenOverrides } from '../modelOverrides';\nimport { parseModelReference, type SummarizationModel } from '../summarizationModel';\nimport type { AutocompactRuntime } from './type';\ntype CheckpointCapture = 'none' | 'pass1' | 'committed' | 'deferred' | 'invalid';\ntype CheckpointMessages = ReturnType<typeof buildSessionContext>['messages'];\n\ninterface PlanSnapshot {\n content: string;\n path: string;\n}\n\ninterface SteeringSnapshot {\n plan?: PlanSnapshot;\n contextContributions: DoomContextContributionsSnapshot;\n readFiles: string[];\n modifiedFiles: string[];\n}\n\ninterface RuntimeStateSnapshot {\n planPath?: string;\n contributions: readonly DoomContextContributionEntry[];\n contributionErrors: readonly DoomContextContributionError[];\n}\n\ninterface CheckpointGenerationInput {\n messages: CheckpointMessages;\n instructions: string;\n previousCheckpoint?: string;\n context: ExtensionContext;\n signal: AbortSignal;\n}\n\nexport interface AutocompactDependencies {\n generateCheckpoint?: (input: CheckpointGenerationInput) => Promise<string>;\n resolveModel?: (context: ExtensionContext) => SummarizationModel | undefined;\n telemetry?: AutocompactTelemetry;\n doomIntegrations?: boolean;\n}\n\nfunction telemetryAttributes(\n context: ExtensionContext,\n attributes: AutocompactEventAttributes = {},\n): AutocompactEventAttributes {\n return {\n 'pi.session.id': context.sessionManager.getSessionId(),\n ...attributes,\n };\n}\n\nfunction latestPersistedState(branch: SessionEntry[]): AutocompactState | undefined {\n for (let index = branch.length - 1; index >= 0; index -= 1) {\n const entry = branch[index];\n if (entry?.type !== 'custom' || entry.customType !== STATE_CUSTOM_TYPE) continue;\n const parsed = parseState(entry.data);\n if (parsed) return parsed;\n }\n return undefined;\n}\n\nfunction workingLeafId(ctx: ExtensionContext): string {\n for (const entry of ctx.sessionManager.getBranch().toReversed()) {\n if (entry.type === 'custom' && entry.customType === STATE_CUSTOM_TYPE) continue;\n if (entry.type === 'label') continue;\n return entry.id;\n }\n return ROOT_WORKING_LEAF;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction latestPlanSnapshot(branch: SessionEntry[]): PlanSnapshot | undefined {\n for (const entry of branch.toReversed()) {\n if (entry.type !== 'custom' || entry.customType !== PLAN_DOCUMENT_ENTRY) continue;\n if (!entry.data || typeof entry.data !== 'object') return undefined;\n const data = entry.data as Record<string, unknown>;\n if (typeof data.content !== 'string' || typeof data.path !== 'string') return undefined;\n return { content: data.content, path: data.path };\n }\n return undefined;\n}\n\nconst EMPTY_CONTEXT_CONTRIBUTIONS: DoomContextContributionsSnapshot = Object.freeze({\n entries: Object.freeze([]),\n errors: Object.freeze([]),\n});\n\nfunction readContextContributionsSnapshot(\n service: DoomContextContributionsService | undefined,\n): DoomContextContributionsSnapshot {\n if (!service) return EMPTY_CONTEXT_CONTRIBUTIONS;\n try {\n return service.snapshot();\n } catch (error) {\n return {\n entries: [],\n errors: [\n {\n source: DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n id: 'service-snapshot',\n label: 'Context contributions',\n order: 0,\n message: errorMessage(error),\n },\n ],\n };\n }\n}\n\nfunction formatContextContributions(snapshot: DoomContextContributionsSnapshot): string {\n const sections = snapshot.entries.map((entry) => `### ${entry.label}\\n${entry.text}`);\n sections.push(...snapshot.errors.map((error) => `### ${error.label}\\n(unavailable: ${error.message})`));\n return sections.length > 0 ? sections.join('\\n\\n') : '(no registered context contributions)';\n}\n\nfunction runtimeStateSnapshot(\n branch: SessionEntry[],\n contextContributions: DoomContextContributionsSnapshot,\n): RuntimeStateSnapshot {\n const plan = latestPlanSnapshot(branch);\n return {\n ...(plan ? { planPath: plan.path } : {}),\n contributions: contextContributions.entries,\n contributionErrors: contextContributions.errors,\n };\n}\n\nfunction formatRuntimeState(snapshot: RuntimeStateSnapshot): string {\n const plan = snapshot.planPath\n ? `Source: ${snapshot.planPath}\\nExact plan content is restored separately by Doom Plan.`\n : '(no active plan document)';\n return `<compaction-runtime-state>\nAuthoritative runtime state captured when compaction committed. Use it to resume coordination without reconstructing state from the summary.\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions({ entries: snapshot.contributions, errors: snapshot.contributionErrors })}\n</context-contributions>\n</compaction-runtime-state>`;\n}\n\nfunction runtimeTelemetryAttributes(snapshot: RuntimeStateSnapshot): AutocompactEventAttributes {\n return {\n 'autocompact.runtime.plan_present': Boolean(snapshot.planPath),\n 'autocompact.runtime.contribution_count': snapshot.contributions.length,\n 'autocompact.runtime.contribution_error_count': snapshot.contributionErrors.length,\n };\n}\n\nfunction steeringEnvelope(snapshot: SteeringSnapshot): string {\n const plan = snapshot.plan\n ? `Source: ${snapshot.plan.path}\\n\\n${snapshot.plan.content}`\n : '(no active plan document)';\n const importantContext = [\n snapshot.readFiles.length > 0 ? `Read files: ${snapshot.readFiles.join(', ')}` : undefined,\n snapshot.modifiedFiles.length > 0 ? `Modified files: ${snapshot.modifiedFiles.join(', ')}` : undefined,\n ].filter((value): value is string => Boolean(value));\n\n return `<compaction-steering priority=\"user,plan,context-contributions,important-context,recent-messages\">\n<user-prompt source=\"conversation\">\nTreat the user's explicit goals, constraints, corrections, and preferences in the conversation as authoritative. Newer user instructions override older ones.\n</user-prompt>\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions(snapshot.contextContributions)}\n</context-contributions>\n<important-context>\n${importantContext.length > 0 ? importantContext.join('\\n') : '(none recorded outside the conversation)'}\n</important-context>\n</compaction-steering>`;\n}\n\nfunction checkpointInstructions(pass: AutocompactPass, steering: SteeringSnapshot): string {\n const decision =\n pass === 2\n ? 'Start with exactly <shouldCompact>true</shouldCompact> or <shouldCompact>false</shouldCompact>. Use true when the staged summary safely retains the important parent context. Use false only when it is not yet sufficient for safe compaction.\\n\\n'\n : '';\n\n // Summarization is a tool-less single LLM call, so instructions describe only what to\n // produce. Directives aimed at an implementing agent leak into the checkpoint body.\n return `Create Doom autocompact checkpoint pass ${pass}.\n\n${steeringEnvelope(steering)}\n\nApply the steering evidence in priority order. Do not invent plan or contributed runtime state. Preserve verified facts and mark unresolved inference explicitly. Newer evidence replaces superseded information.\n\n${decision}Return only the decision tag when required, followed by a concise structured checkpoint using every heading below. Keep exact goals, constraints, decisions, blockers, commands, errors, file paths, validation evidence, and the immediate next action. Separate verified facts from unresolved inference.\n\n## Goal\n## Constraints & Preferences\n## Progress\n### Done\n### In Progress\n### Blocked\n## Key Decisions\n## Next Steps\n## Critical Context`;\n}\n\nfunction messagesForCheckpoint(\n pass: AutocompactPass,\n branch: SessionEntry[],\n previousSnapshotLeafId: string | undefined,\n): CheckpointMessages {\n const projected = projectContextMessages(buildSessionContext(branch).messages, branch).messages;\n if (pass === 1 || !previousSnapshotLeafId) return projected;\n const snapshotIndex = branch.findIndex((entry) => entry.id === previousSnapshotLeafId);\n if (snapshotIndex === -1) return projected;\n return branch\n .slice(snapshotIndex + 1)\n .filter((entry) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\ninterface AutocompactRuntimeConfig {\n /** Off leaves compaction to Pi; unset is on. */\n enabled: boolean;\n /** The agent that writes the summaries, from autocompact's own keys or planning's. */\n agent?: PlanningAgentConfig;\n ratios: AutocompactRatioOverrides;\n /** Per-model absolute token checkpoints, tried in file order. */\n overrides: AutocompactOverrideConfig[];\n}\n\nconst DEFAULT_RUNTIME_CONFIG: AutocompactRuntimeConfig = { enabled: true, ratios: {}, overrides: [] };\n\n/**\n * What the Doom config says about this package.\n *\n * `modes.autocompact` is read first and `modes.planning.subagents` is the\n * fallback, because summarization borrowed the planning subagent model before\n * it had keys of its own and existing files still spell it that way.\n */\nexport function autocompactRuntimeConfig(\n cwd: string,\n onLoadFailure?: (error: unknown) => void,\n): AutocompactRuntimeConfig {\n let modes: ReturnType<typeof loadDoomConfig>['modes'];\n try {\n modes = loadDoomConfig(getHarnessState().root ?? cwd).modes;\n } catch (error) {\n process.emitWarning('Doom autocompact configuration could not be loaded; using the active session model instead.');\n onLoadFailure?.(error);\n return DEFAULT_RUNTIME_CONFIG;\n }\n const configured = modes?.autocompact;\n const ownAgent: PlanningAgentConfig | undefined =\n configured && (configured.model !== undefined || configured.thinking !== undefined)\n ? {\n ...(configured.model ? { model: configured.model } : {}),\n ...(configured.thinking ? { thinking: configured.thinking } : {}),\n }\n : undefined;\n const agent = ownAgent ?? modes?.planning?.subagents;\n const thresholds = configured?.thresholds;\n return {\n enabled: configured?.enabled ?? true,\n ...(agent ? { agent } : {}),\n ratios: {\n ...(thresholds?.pass1 === undefined ? {} : { 1: thresholds.pass1 }),\n ...(thresholds?.pass2 === undefined ? {} : { 2: thresholds.pass2 }),\n ...(thresholds?.pass3 === undefined ? {} : { 3: thresholds.pass3 }),\n },\n overrides: configured?.overrides ?? [],\n };\n}\n\n/** Explicit Doom model selection honors the configured summarization model. */\nexport function resolveDoomSummarizationModel(ctx: ExtensionContext): SummarizationModel | undefined {\n const configured = autocompactRuntimeConfig(ctx.cwd).agent;\n const reference = configured?.model ? parseModelReference(configured.model) : undefined;\n const configuredModel = reference ? ctx.modelRegistry.find(reference.provider, reference.modelId) : undefined;\n const model = configuredModel ?? ctx.model;\n if (!model) return undefined;\n const thinkingLevel =\n configured?.thinking ?? (configuredModel ? reference?.thinking : undefined) ?? ctx.thinkingLevel;\n return { model, ...(thinkingLevel ? { thinkingLevel } : {}) };\n}\n\n/**\n * Summarization borrows the session's own provider instead of re-resolving one.\n *\n * The selected model can come from a Pi provider extension, and that extension's\n * `streamSimple` closure lives only in this process: it is never in Pi's global api\n * registry, so any other thread or process sees `No API provider registered for api`.\n * Passing the composed provider in as `generateSummary`'s stream function keeps\n * summarization on exactly the path the agent's own requests take.\n */\nexport async function generateCheckpointWithPi(\n input: CheckpointGenerationInput,\n resolveModel: (context: ExtensionContext) => SummarizationModel | undefined,\n): Promise<string> {\n const selection = resolveModel(input.context);\n if (!selection) throw new Error('No active model is available for autocompact summarization.');\n const auth = await input.context.modelRegistry.getApiKeyAndHeaders(selection.model);\n if (!auth.ok) throw new Error(auth.error);\n const provider = input.context.modelRegistry.getProvider(selection.model.provider);\n if (!provider) {\n throw new Error(`No provider is registered for \"${selection.model.provider}\" in this session.`);\n }\n return generateSummary(\n input.messages,\n selection.model,\n DEFAULT_COMPACTION_SETTINGS.reserveTokens,\n auth.apiKey,\n // A null header value suppresses a provider default, which the narrower\n // `generateSummary` signature does not model but every provider honors.\n auth.headers as Record<string, string> | undefined,\n input.signal,\n input.instructions,\n input.previousCheckpoint,\n selection.thinkingLevel,\n (model, context, options) => provider.streamSimple(model, context, options),\n auth.env,\n );\n}\n\nfunction notify(ctx: ExtensionContext | undefined, message: string, level: 'info' | 'warning' | 'error' = 'info') {\n if (ctx?.hasUI) ctx.ui.notify(message, level);\n}\n\nexport function createAutocompactRuntime(\n pi: ExtensionAPI,\n dependencies: AutocompactDependencies = {},\n): AutocompactRuntime {\n const resolveModel = dependencies.resolveModel ?? resolveDoomSummarizationModel;\n const generateCheckpoint =\n dependencies.generateCheckpoint ??\n ((input: CheckpointGenerationInput) => generateCheckpointWithPi(input, resolveModel));\n const telemetry = dependencies.telemetry ?? createAutocompactTelemetry();\n const doomIntegrations = dependencies.doomIntegrations ?? true;\n const appliedContextRequests = new Set<string>();\n const invalidContextLeaves = new Set<string>();\n const checkpointWork = new Set<Promise<void>>();\n let active = true;\n let sessionGeneration = 0;\n let state = createInitialState();\n let currentContext: ExtensionContext | undefined;\n let checkpointController: AbortController | undefined;\n let footerContribution: DoomFooterContributionHandle | undefined;\n let contextContributionsService: DoomContextContributionsService | undefined;\n let configLoadFailureReported = false;\n\n const stop = async (): Promise<void> => {\n active = false;\n sessionGeneration += 1;\n checkpointController?.abort(new Error('Autocompact runtime is shutting down.'));\n checkpointController = undefined;\n await Promise.allSettled(checkpointWork);\n footerContribution = undefined;\n contextContributionsService = undefined;\n currentContext = undefined;\n appliedContextRequests.clear();\n invalidContextLeaves.clear();\n state = createInitialState();\n configLoadFailureReported = false;\n await telemetry.shutdown();\n };\n\n const plugin = (cordis: Context): void => {\n cordis.inject([DOOM_CONTEXT_CONTRIBUTIONS_SERVICE], (contextContributionsContext) => {\n const service = requireDoomContextContributions(contextContributionsContext);\n contextContributionsService = service;\n return () => {\n if (contextContributionsService === service) contextContributionsService = undefined;\n };\n });\n\n if (doomIntegrations) {\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n const contribution = requireDoomUiHub(uiContext).registerFooter({\n source: FOOTER_SOURCE,\n id: 'autocompact',\n order: FOOTER_ORDER,\n });\n footerContribution = contribution;\n return () => {\n contribution.dispose();\n if (footerContribution === contribution) footerContribution = undefined;\n };\n });\n }\n };\n\n /** Compaction runs off the main thread, so the phase is the only signal the user gets. */\n const refreshStatus = (ctx?: ExtensionContext): void => {\n if (!active) return;\n const phase =\n state.phase === STATE_PHASE.checkpointPending\n ? 'summarizing'\n : state.phase === STATE_PHASE.checkpointReady\n ? 'applying'\n : undefined;\n footerContribution?.update(\n phase ? { fullText: `Compacting p${state.pass}`, compactText: `C${state.pass}` } : undefined,\n );\n const target = ctx ?? currentContext;\n if (target?.hasUI) target.ui.setStatus(STATUS_KEY, phase ? `Compacting pass ${state.pass} (${phase})…` : undefined);\n };\n\n // Every phase transition persists, so this is the one place that keeps the status honest.\n const persist = (): void => {\n if (!active) return;\n pi.appendEntry(STATE_CUSTOM_TYPE, { ...state });\n refreshStatus();\n };\n\n const clearPendingCheckpoint = (): void => {\n delete state.requestId;\n delete state.snapshotLeafId;\n delete state.snapshotTokens;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n };\n\n const completeQueuedPass = (pass: AutocompactPass): void => {\n state.checkpointQueue = state.checkpointQueue.filter((queuedPass) => queuedPass !== pass);\n };\n\n const restore = (ctx: ExtensionContext): void => {\n if (!active) return;\n state = latestPersistedState(ctx.sessionManager.getBranch()) ?? createInitialState();\n const resumablePending =\n state.phase === STATE_PHASE.checkpointReady && state.requestId && state.snapshotLeafId && state.pendingCheckpoint;\n if (resumablePending || state.phase === STATE_PHASE.waiting) return;\n\n checkpointController?.abort();\n checkpointController = undefined;\n state.phase = STATE_PHASE.waiting;\n clearPendingCheckpoint();\n persist();\n };\n\n const resumeAgent = (message: string): void => {\n if (!active) return;\n pi.sendMessage(\n {\n customType: RESUME_MESSAGE_TYPE,\n content: `${message} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,\n display: false,\n details: { version: STATE_VERSION, cycle: state.cycle, pass: state.pass },\n },\n { triggerTurn: true, deliverAs: 'steer' },\n );\n };\n\n /**\n * Both failure paths share one attempt budget: a summarizer that keeps failing would\n * otherwise cost a full summarization call every turn for the rest of the session, so the\n * pass is abandoned once the budget is spent and becomes eligible again on the next cycle.\n */\n const registerFailedAttempt = (\n pass: AutocompactPass,\n failedLeafId: string | undefined,\n ): { attempts: number; exhausted: boolean } => {\n const attempts = state.invalidAttempts + 1;\n const exhausted = attempts >= MAX_INVALID_CHECKPOINT_ATTEMPTS;\n state.phase = STATE_PHASE.waiting;\n if (failedLeafId) state.lastAttemptLeafId = failedLeafId;\n if (exhausted) {\n completeQueuedPass(pass);\n state.exhaustedPasses = [...state.exhaustedPasses, pass];\n state.invalidAttempts = 0;\n } else {\n state.invalidAttempts = attempts;\n }\n clearPendingCheckpoint();\n persist();\n return { attempts, exhausted };\n };\n\n const failCheckpoint = (requestId: string, error: unknown): void => {\n if (!active || requestId !== state.requestId || state.phase !== STATE_PHASE.checkpointPending) return;\n const pass = state.pass;\n const { attempts, exhausted } = registerFailedAttempt(pass, state.snapshotLeafId);\n const reason = error instanceof Error ? error.message : String(error);\n notify(\n currentContext,\n exhausted\n ? `Doom autocompact summarization pass ${pass} failed ${attempts} times and was abandoned: ${reason}`\n : `Doom autocompact summarization pass ${pass} failed: ${reason}`,\n 'error',\n );\n };\n\n // A configuration that cannot be read degrades every later pass silently, and the process\n // warning never reaches the log sink. Report it once per session instead of once per turn.\n const reportConfigLoadFailure = (ctx: ExtensionContext, error: unknown): void => {\n if (!active || configLoadFailureReported) return;\n configLoadFailureReported = true;\n void telemetry.recordWarning(\n AUTOCOMPACT_EVENT.configurationLoadFailed,\n error,\n telemetryAttributes(ctx, { 'autocompact.cycle': state.cycle, 'autocompact.pass': state.pass }),\n );\n };\n\n const reportContributionFailures = (\n ctx: ExtensionContext,\n snapshot: DoomContextContributionsSnapshot,\n attributes: AutocompactEventAttributes,\n ): void => {\n if (!active) return;\n for (const error of snapshot.errors) {\n notify(\n ctx,\n `Doom autocompact context contribution degraded (${error.source}/${error.id}): ${error.message}`,\n 'warning',\n );\n void telemetry.recordWarning(AUTOCOMPACT_EVENT.contextContributionDegraded, new Error(error.message), {\n ...attributes,\n 'autocompact.context_contribution.source': error.source,\n 'autocompact.context_contribution.id': error.id,\n 'autocompact.context_contribution.order': error.order,\n });\n }\n };\n\n const preserveRuntimeState = (\n ctx: ExtensionContext,\n branch: SessionEntry[],\n attributes: AutocompactEventAttributes,\n ): RuntimeStateSnapshot => {\n if (!active) {\n return { contributions: [], contributionErrors: [] };\n }\n const contextContributions = readContextContributionsSnapshot(contextContributionsService);\n reportContributionFailures(ctx, contextContributions, attributes);\n const snapshot = runtimeStateSnapshot(branch, contextContributions);\n pi.sendMessage({\n customType: RUNTIME_STATE_MESSAGE_TYPE,\n content: formatRuntimeState(snapshot),\n display: false,\n details: { version: 2, ...snapshot },\n });\n return snapshot;\n };\n\n const commitCheckpoint = (pass: 2 | 3, ctx: ExtensionContext): boolean => {\n if (!active || !state.requestId || !state.snapshotLeafId || !state.pendingCheckpoint) return false;\n const branch = ctx.sessionManager.getBranch();\n const projected = projectContextMessages(buildSessionContext(branch).messages, branch).messages;\n const fileDetails = mergeFileDetails(state, fileOperationsFromMessages(projected));\n const requestId = state.requestId;\n const cycle = state.cycle;\n const summary = withCanonicalFileSections(state.pendingCheckpoint, fileDetails);\n const details: AutocompactContextDetails = {\n ...fileDetails,\n doomAutocompact: {\n version: STATE_VERSION,\n cycle,\n pass,\n requestId,\n snapshotLeafId: state.snapshotLeafId,\n tokensBefore: state.snapshotTokens ?? ctx.getContextUsage()?.tokens ?? 0,\n },\n retainedMessages: retainedMessagesAfterSnapshot(branch, state.snapshotLeafId),\n };\n\n const committedWhileIdle = ctx.isIdle();\n pi.sendMessage({ customType: CONTEXT_MESSAGE_TYPE, content: summary, display: false, details });\n const contextMessageLeafId = workingLeafId(ctx);\n const runtimeAttributes = telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': cycle,\n 'autocompact.pass': pass,\n });\n const runtimeSnapshot = preserveRuntimeState(ctx, branch, runtimeAttributes);\n // Mid-run the marker is queued as a steering message, so its entry id is not resolvable yet.\n if (committedWhileIdle) pi.setLabel(contextMessageLeafId, `autocompact:c${cycle}:p${pass}`);\n\n state.readFiles = fileDetails.readFiles;\n state.modifiedFiles = fileDetails.modifiedFiles;\n delete state.latestCheckpointSnapshotLeafId;\n state.phase = STATE_PHASE.waiting;\n state.checkpointQueue = [];\n // A compacted context is a fresh ladder: passes abandoned in the previous cycle are eligible again.\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n state.baselinePending = true;\n delete state.lastAttemptLeafId;\n clearPendingCheckpoint();\n state.cycle += 1;\n state.pass = 1;\n persist();\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextCommitted,\n telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': cycle,\n 'autocompact.pass': pass,\n 'autocompact.snapshot_leaf_id': details.doomAutocompact.snapshotLeafId,\n 'autocompact.tokens_before': details.doomAutocompact.tokensBefore,\n 'autocompact.message_count.before': projected.length,\n 'autocompact.message_count.retained': details.retainedMessages.length,\n 'autocompact.apply_mode': committedWhileIdle ? 'idle' : 'turn_end',\n ...runtimeTelemetryAttributes(runtimeSnapshot),\n }),\n );\n // A mid-run commit needs no resume steer: the agent is already continuing.\n if (committedWhileIdle) resumeAgent('Asynchronous compaction completed.');\n return true;\n };\n\n const requestCheckpoint = (pass: AutocompactPass, ctx: ExtensionContext, tokensBefore: number): void => {\n if (!active) return;\n const generation = sessionGeneration;\n const branch = ctx.sessionManager.getBranch();\n const snapshotLeafId = workingLeafId(ctx);\n const requestId = createRequestId(ctx.sessionManager.getSessionId(), state.cycle, pass, snapshotLeafId);\n const previousCheckpoint = pass > 1 ? checkpointSummaryFromEntry(latestCheckpointArtifactEntry(branch)) : undefined;\n const messages = messagesForCheckpoint(pass, branch, state.latestCheckpointSnapshotLeafId);\n const contextContributions = readContextContributionsSnapshot(contextContributionsService);\n const attributes = telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': pass,\n 'autocompact.snapshot_leaf_id': snapshotLeafId,\n 'autocompact.tokens_before': tokensBefore,\n 'autocompact.message_count.before': messages.length,\n });\n reportContributionFailures(ctx, contextContributions, attributes);\n\n state.phase = STATE_PHASE.checkpointPending;\n state.pass = pass;\n state.requestId = requestId;\n state.snapshotLeafId = snapshotLeafId;\n state.snapshotTokens = tokensBefore;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n delete state.lastAttemptLeafId;\n persist();\n\n checkpointController?.abort();\n checkpointController = new AbortController();\n const checkpointSignal = checkpointController.signal;\n const operation = telemetry\n .runInSpan('doom_autocompact.checkpoint', attributes, async () => {\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointStarted, attributes);\n try {\n const checkpoint = await generateCheckpoint({\n messages,\n instructions: checkpointInstructions(pass, {\n plan: latestPlanSnapshot(branch),\n contextContributions,\n readFiles: state.readFiles,\n modifiedFiles: state.modifiedFiles,\n }),\n ...(previousCheckpoint ? { previousCheckpoint } : {}),\n context: ctx,\n signal: checkpointSignal,\n });\n if (!active || generation !== sessionGeneration) {\n throw checkpointSignal.reason ?? new Error('Autocompact checkpoint became stale.');\n }\n if (!checkpoint.trim()) throw new Error('Summarization returned an empty checkpoint.');\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointCompleted, {\n ...attributes,\n 'autocompact.checkpoint.characters': checkpoint.length,\n });\n return checkpoint;\n } catch (error) {\n if (active && generation === sessionGeneration) {\n await telemetry.recordError(AUTOCOMPACT_EVENT.checkpointFailed, error, attributes);\n }\n throw error;\n }\n })\n .then((checkpoint) => {\n if (\n !active ||\n generation !== sessionGeneration ||\n requestId !== state.requestId ||\n state.phase !== STATE_PHASE.checkpointPending\n ) {\n return;\n }\n state.phase = STATE_PHASE.checkpointReady;\n state.pendingCheckpoint = checkpoint.trim();\n persist();\n if (currentContext) processProgress(currentContext);\n })\n .catch((error: unknown) => {\n if (active && generation === sessionGeneration) failCheckpoint(requestId, error);\n });\n checkpointWork.add(operation);\n void operation.finally(() => checkpointWork.delete(operation));\n };\n\n const evaluateUsage = (ctx: ExtensionContext): boolean => {\n if (!active || state.phase !== STATE_PHASE.waiting || ctx.hasPendingMessages()) return false;\n // Read per evaluation rather than once at install, so turning the ladder off\n // or moving a threshold in settings takes effect on the next turn instead of\n // the next session.\n const configured = autocompactRuntimeConfig(ctx.cwd, (error) => reportConfigLoadFailure(ctx, error));\n if (!configured.enabled) return false;\n const usage = ctx.getContextUsage();\n if (!usage || usage.tokens === null) return false;\n if (state.baselinePending) {\n // Reported usage still describes the pre-compaction context until an assistant\n // responds against the projected one, and capturing it early poisons every threshold.\n if (!baselineUsageIsSettled(ctx.sessionManager.getBranch())) return false;\n state.baselineTokens = usage.tokens;\n state.baselinePending = false;\n persist();\n return false;\n }\n const leafId = workingLeafId(ctx);\n if (state.lastAttemptLeafId === leafId) return false;\n\n // The baseline branch above always returns, so by here it is settled for this cycle and the\n // token overrides can be compared against it without re-checking `baselinePending`.\n const tokenOverrides = resolveModelTokenOverrides(ctx.model, configured.overrides);\n const thresholds = effectiveThresholds(\n usage.contextWindow,\n state.baselineTokens,\n configured.ratios,\n tokenOverrides,\n );\n for (const pass of [1, 2, 3] as const) {\n if (pass < state.pass || state.checkpointQueue.includes(pass) || state.exhaustedPasses.includes(pass)) continue;\n if (usage.tokens >= thresholds[pass]) {\n state.checkpointQueue.push(pass);\n }\n }\n const nextPass = state.checkpointQueue[0];\n if (!nextPass) return false;\n requestCheckpoint(nextPass, ctx, usage.tokens);\n return true;\n };\n\n // Staged checkpoints seed the next summarization pass only. They are appended as plain\n // session entries so they never enter the agent's LLM context: delivering them as messages\n // reads like a user instruction and derails the run (\"Checkpoint acknowledged...\").\n const stageCheckpoint = (pass: 1 | 2, summary: string): void => {\n if (!active) return;\n const checkpointSnapshotLeafId = state.snapshotLeafId;\n pi.appendEntry(CHECKPOINT_MESSAGE_TYPE, {\n ...checkpointRequestDetails(state.cycle, pass, state.requestId ?? 'completed'),\n summary,\n });\n if (checkpointSnapshotLeafId) state.latestCheckpointSnapshotLeafId = checkpointSnapshotLeafId;\n };\n\n const captureReadyCheckpoint = (ctx: ExtensionContext): CheckpointCapture => {\n if (!active || state.phase !== STATE_PHASE.checkpointReady || !state.requestId || !state.pendingCheckpoint) {\n return 'none';\n }\n const pass = state.pass;\n const decision = parseCheckpointDecision(state.pendingCheckpoint);\n if (!isStructuredCheckpoint(decision.summary)) {\n const failedLeafId = state.snapshotLeafId;\n const invalidRequestId = state.requestId;\n // A queued pass is retried once per new leaf, so an output the summarizer never formats\n // correctly would otherwise burn a full summarization call every turn for the session.\n const { attempts, exhausted } = registerFailedAttempt(pass, failedLeafId);\n const error = new Error(`Summarization pass ${pass} returned an incomplete checkpoint.`);\n notify(\n ctx,\n exhausted\n ? `Doom autocompact summarization pass ${pass} returned an incomplete checkpoint ${attempts} times and was abandoned.`\n : `Doom autocompact summarization pass ${pass} returned an incomplete checkpoint.`,\n 'error',\n );\n void telemetry.recordError(\n AUTOCOMPACT_EVENT.checkpointInvalid,\n error,\n telemetryAttributes(ctx, {\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': pass,\n 'autocompact.checkpoint.attempts': attempts,\n 'autocompact.checkpoint.exhausted': exhausted,\n ...(invalidRequestId ? { 'autocompact.request.id': invalidRequestId } : {}),\n }),\n );\n return 'invalid';\n }\n\n state.invalidAttempts = 0;\n\n if (pass === 1) {\n stageCheckpoint(1, decision.summary);\n completeQueuedPass(1);\n state.phase = STATE_PHASE.waiting;\n state.pass = 2;\n clearPendingCheckpoint();\n persist();\n return 'pass1';\n }\n\n if (pass === 2 && decision.shouldCompact !== true) {\n stageCheckpoint(2, decision.summary);\n completeQueuedPass(2);\n state.phase = STATE_PHASE.waiting;\n state.pass = 3;\n clearPendingCheckpoint();\n persist();\n return 'deferred';\n }\n\n state.pendingCheckpoint = decision.summary;\n return commitCheckpoint(pass, ctx) ? 'committed' : 'invalid';\n };\n\n function processProgress(ctx: ExtensionContext): void {\n if (!active) return;\n currentContext = ctx;\n if (!ctx.isIdle()) return;\n if (captureReadyCheckpoint(ctx) !== 'committed') evaluateUsage(ctx);\n }\n\n const beginSessionGeneration = (ctx: ExtensionContext): void => {\n if (!active) return;\n sessionGeneration += 1;\n checkpointController?.abort(new Error('Autocompact session generation was replaced.'));\n checkpointController = undefined;\n appliedContextRequests.clear();\n invalidContextLeaves.clear();\n currentContext = ctx;\n restore(ctx);\n processProgress(ctx);\n };\n\n return {\n plugin,\n stop,\n events: {\n context: (event, ctx) => {\n if (!active) return undefined;\n const projection = projectContextMessages(event.messages, ctx.sessionManager.getBranch());\n if (projection.invalidMarker) {\n const leafId = ctx.sessionManager.getLeafId() ?? ROOT_WORKING_LEAF;\n if (!invalidContextLeaves.has(leafId)) {\n invalidContextLeaves.add(leafId);\n void telemetry.recordError(\n AUTOCOMPACT_EVENT.contextMarkerInvalid,\n new Error('Doom autocompact context marker is malformed.'),\n telemetryAttributes(ctx, { 'autocompact.leaf_id': leafId }),\n );\n }\n return undefined;\n }\n if (!projection.marker) return undefined;\n if (!appliedContextRequests.has(projection.marker.requestId)) {\n appliedContextRequests.add(projection.marker.requestId);\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextApplied,\n telemetryAttributes(ctx, {\n 'autocompact.request.id': projection.marker.requestId,\n 'autocompact.cycle': projection.marker.cycle,\n 'autocompact.pass': projection.marker.pass,\n 'autocompact.snapshot_leaf_id': projection.marker.snapshotLeafId,\n 'autocompact.tokens_before': projection.marker.tokensBefore,\n 'autocompact.message_count.before': event.messages.length,\n 'autocompact.message_count.after': projection.messages.length,\n 'autocompact.message_count.retained': projection.retainedMessageCount,\n }),\n );\n }\n return { messages: projection.messages };\n },\n\n session_start: (_event, ctx) => beginSessionGeneration(ctx),\n\n session_tree: (_event, ctx) => beginSessionGeneration(ctx),\n\n turn_end: (event, ctx) => {\n if (!active) return;\n currentContext = ctx;\n if (ctx.isIdle()) {\n processProgress(ctx);\n return;\n }\n // A ready checkpoint must be applied without waiting for the run to finish, otherwise\n // context keeps growing past the window for the rest of a long autonomous run. Tool\n // results confirm the run continues, so the queued marker lands before the next request.\n const canApplyDuringRun =\n state.phase === STATE_PHASE.checkpointReady &&\n (event.toolResults?.length ?? 0) > 0 &&\n !ctx.hasPendingMessages();\n if (canApplyDuringRun && captureReadyCheckpoint(ctx) !== 'none') return;\n evaluateUsage(ctx);\n },\n\n agent_settled: (_event, ctx) => {\n if (!active) return;\n processProgress(ctx);\n },\n\n session_before_compact: (event) => {\n if (!active || event.reason !== 'threshold') return undefined;\n // Native compaction stays cancelled while our own machinery is working, and stays\n // available as the emergency backstop once that machinery has stalled or declined.\n const machineryActive =\n state.phase === STATE_PHASE.checkpointPending ||\n state.phase === STATE_PHASE.checkpointReady ||\n state.baselinePending;\n return machineryActive ? { cancel: true } : undefined;\n },\n\n session_compact: (event, ctx) => {\n if (!active) return;\n sessionGeneration += 1;\n // Native compaction supersedes any summarization still in flight.\n checkpointController?.abort();\n checkpointController = undefined;\n const eventDetails = fileDetailsFromUnknown(event.compactionEntry.details);\n const cumulative = mergeFileDetails(state, undefined, eventDetails);\n state.readFiles = cumulative.readFiles;\n state.modifiedFiles = cumulative.modifiedFiles;\n delete state.latestCheckpointSnapshotLeafId;\n // Reported usage still describes the pre-compaction context here too, so the baseline\n // waits for the first assistant response measured against the compacted one.\n state.baselinePending = true;\n state.phase = STATE_PHASE.waiting;\n clearPendingCheckpoint();\n state.checkpointQueue = [];\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n delete state.lastAttemptLeafId;\n\n pi.setLabel(event.compactionEntry.id, `autocompact:c${state.cycle}:external`);\n const completedCycle = state.cycle;\n const runtimeAttributes = telemetryAttributes(ctx, {\n 'autocompact.cycle': completedCycle,\n 'autocompact.native.reason': event.reason,\n });\n const runtimeSnapshot = preserveRuntimeState(ctx, ctx.sessionManager.getBranch(), runtimeAttributes);\n state.cycle += 1;\n state.pass = 1;\n persist();\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.nativeCompactionCompleted,\n telemetryAttributes(ctx, {\n 'autocompact.cycle': completedCycle,\n 'autocompact.native.reason': event.reason,\n 'autocompact.native.from_extension': event.fromExtension,\n 'autocompact.tokens_before': event.compactionEntry.tokensBefore,\n ...runtimeTelemetryAttributes(runtimeSnapshot),\n }),\n );\n },\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/autocompactRuntime/index.ts"],"sourcesContent":["import {\n getHarnessState,\n loadDoomConfig,\n type AutocompactOverrideConfig,\n type PlanningAgentConfig,\n} from '@agimon-ai/doompi-config';\nimport {\n DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n requireDoomContextContributions,\n type DoomContextContributionEntry,\n type DoomContextContributionError,\n type DoomContextContributionsService,\n type DoomContextContributionsSnapshot,\n} from '@agimon-ai/doompi-core/context-contributions';\nimport type { DoomFooterContributionHandle } from '@agimon-ai/doompi-core/footer';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/ui-hub';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ContextEvent, ExtensionAPI, ExtensionContext, SessionEntry } from '@earendil-works/pi-coding-agent';\nimport {\n buildSessionContext,\n DEFAULT_COMPACTION_SETTINGS,\n generateSummary,\n sessionEntryToContextMessages,\n} from '@earendil-works/pi-coding-agent';\n\nimport {\n CHECKPOINT_MESSAGE_TYPE,\n CONTEXT_MESSAGE_TYPE,\n MAX_INVALID_CHECKPOINT_ATTEMPTS,\n RESUME_MESSAGE_TYPE,\n RUNTIME_STATE_MESSAGE_TYPE,\n STATE_CUSTOM_TYPE,\n STATE_VERSION,\n} from '../../constants/autocompact';\nimport {\n ROOT_WORKING_LEAF,\n PLAN_DOCUMENT_ENTRY,\n FOOTER_SOURCE,\n FOOTER_ORDER,\n STATUS_KEY,\n STATE_PHASE,\n SLOW_CONTEXT_HOOK_MS,\n} from '../../constants/runtime';\nimport type {\n AutocompactContextDetails,\n AutocompactPass,\n AutocompactRatioOverrides,\n AutocompactState,\n} from '../../types/autocompact';\nimport type { AutocompactEventAttributes, AutocompactTelemetry } from '../autocompactTelemetry';\nimport { AUTOCOMPACT_EVENT, createAutocompactTelemetry } from '../autocompactTelemetry';\nimport {\n baselineUsageIsSettled,\n checkpointRequestDetails,\n checkpointSummaryFromEntry,\n createInitialState,\n createRequestId,\n fileDetailsFromUnknown,\n fileOperationsFromMessages,\n isStructuredCheckpoint,\n latestCheckpointArtifactEntry,\n mergeFileDetails,\n parseCheckpointDecision,\n parseState,\n projectContextMessages,\n retainedMessagesAfterSnapshot,\n effectiveThresholds,\n withCanonicalFileSections,\n} from '../compactionPolicy';\nimport { resolveModelTokenOverrides } from '../modelOverrides';\nimport { parseModelReference, type SummarizationModel } from '../summarizationModel';\nimport type { AutocompactRuntime } from './type';\ntype CheckpointCapture = 'none' | 'pass1' | 'committed' | 'deferred' | 'invalid';\ntype CheckpointMessages = ReturnType<typeof buildSessionContext>['messages'];\n\ninterface PlanSnapshot {\n content: string;\n path: string;\n}\n\ninterface SteeringSnapshot {\n plan?: PlanSnapshot;\n contextContributions: DoomContextContributionsSnapshot;\n readFiles: string[];\n modifiedFiles: string[];\n}\n\ninterface RuntimeStateSnapshot {\n planPath?: string;\n contributions: readonly DoomContextContributionEntry[];\n contributionErrors: readonly DoomContextContributionError[];\n}\n\ninterface CheckpointGenerationInput {\n messages: CheckpointMessages;\n instructions: string;\n previousCheckpoint?: string;\n context: ExtensionContext;\n signal: AbortSignal;\n}\n\nexport interface AutocompactDependencies {\n generateCheckpoint?: (input: CheckpointGenerationInput) => Promise<string>;\n resolveModel?: (context: ExtensionContext) => SummarizationModel | undefined;\n telemetry?: AutocompactTelemetry;\n doomIntegrations?: boolean;\n}\n\nfunction telemetryAttributes(\n context: ExtensionContext,\n attributes: AutocompactEventAttributes = {},\n): AutocompactEventAttributes {\n return {\n 'pi.session.id': context.sessionManager.getSessionId(),\n ...attributes,\n };\n}\n\nfunction latestPersistedState(branch: SessionEntry[]): AutocompactState | undefined {\n for (let index = branch.length - 1; index >= 0; index -= 1) {\n const entry = branch[index];\n if (entry?.type !== 'custom' || entry.customType !== STATE_CUSTOM_TYPE) continue;\n const parsed = parseState(entry.data);\n if (parsed) return parsed;\n }\n return undefined;\n}\n\nfunction workingLeafId(ctx: ExtensionContext): string {\n for (const entry of ctx.sessionManager.getBranch().toReversed()) {\n if (entry.type === 'custom' && entry.customType === STATE_CUSTOM_TYPE) continue;\n if (entry.type === 'label') continue;\n return entry.id;\n }\n return ROOT_WORKING_LEAF;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction latestPlanSnapshot(branch: SessionEntry[]): PlanSnapshot | undefined {\n for (const entry of branch.toReversed()) {\n if (entry.type !== 'custom' || entry.customType !== PLAN_DOCUMENT_ENTRY) continue;\n if (!entry.data || typeof entry.data !== 'object') return undefined;\n const data = entry.data as Record<string, unknown>;\n if (typeof data.content !== 'string' || typeof data.path !== 'string') return undefined;\n return { content: data.content, path: data.path };\n }\n return undefined;\n}\n\nconst EMPTY_CONTEXT_CONTRIBUTIONS: DoomContextContributionsSnapshot = Object.freeze({\n entries: Object.freeze([]),\n errors: Object.freeze([]),\n});\n\nfunction readContextContributionsSnapshot(\n service: DoomContextContributionsService | undefined,\n): DoomContextContributionsSnapshot {\n if (!service) return EMPTY_CONTEXT_CONTRIBUTIONS;\n try {\n return service.snapshot();\n } catch (error) {\n return {\n entries: [],\n errors: [\n {\n source: DOOM_CONTEXT_CONTRIBUTIONS_SERVICE,\n id: 'service-snapshot',\n label: 'Context contributions',\n order: 0,\n message: errorMessage(error),\n },\n ],\n };\n }\n}\n\nfunction formatContextContributions(snapshot: DoomContextContributionsSnapshot): string {\n const sections = snapshot.entries.map((entry) => `### ${entry.label}\\n${entry.text}`);\n sections.push(...snapshot.errors.map((error) => `### ${error.label}\\n(unavailable: ${error.message})`));\n return sections.length > 0 ? sections.join('\\n\\n') : '(no registered context contributions)';\n}\n\nfunction runtimeStateSnapshot(\n branch: SessionEntry[],\n contextContributions: DoomContextContributionsSnapshot,\n): RuntimeStateSnapshot {\n const plan = latestPlanSnapshot(branch);\n return {\n ...(plan ? { planPath: plan.path } : {}),\n contributions: contextContributions.entries,\n contributionErrors: contextContributions.errors,\n };\n}\n\nfunction formatRuntimeState(snapshot: RuntimeStateSnapshot): string {\n const plan = snapshot.planPath\n ? `Source: ${snapshot.planPath}\\nExact plan content is restored separately by Doom Plan.`\n : '(no active plan document)';\n return `<compaction-runtime-state>\nAuthoritative runtime state captured when compaction committed. Use it to resume coordination without reconstructing state from the summary.\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions({ entries: snapshot.contributions, errors: snapshot.contributionErrors })}\n</context-contributions>\n</compaction-runtime-state>`;\n}\n\nfunction runtimeTelemetryAttributes(snapshot: RuntimeStateSnapshot): AutocompactEventAttributes {\n return {\n 'autocompact.runtime.plan_present': Boolean(snapshot.planPath),\n 'autocompact.runtime.contribution_count': snapshot.contributions.length,\n 'autocompact.runtime.contribution_error_count': snapshot.contributionErrors.length,\n };\n}\n\nfunction steeringEnvelope(snapshot: SteeringSnapshot): string {\n const plan = snapshot.plan\n ? `Source: ${snapshot.plan.path}\\n\\n${snapshot.plan.content}`\n : '(no active plan document)';\n const importantContext = [\n snapshot.readFiles.length > 0 ? `Read files: ${snapshot.readFiles.join(', ')}` : undefined,\n snapshot.modifiedFiles.length > 0 ? `Modified files: ${snapshot.modifiedFiles.join(', ')}` : undefined,\n ].filter((value): value is string => Boolean(value));\n\n return `<compaction-steering priority=\"user,plan,context-contributions,important-context,recent-messages\">\n<user-prompt source=\"conversation\">\nTreat the user's explicit goals, constraints, corrections, and preferences in the conversation as authoritative. Newer user instructions override older ones.\n</user-prompt>\n<active-plan>\n${plan}\n</active-plan>\n<context-contributions>\n${formatContextContributions(snapshot.contextContributions)}\n</context-contributions>\n<important-context>\n${importantContext.length > 0 ? importantContext.join('\\n') : '(none recorded outside the conversation)'}\n</important-context>\n</compaction-steering>`;\n}\n\nfunction checkpointInstructions(pass: AutocompactPass, steering: SteeringSnapshot): string {\n const decision =\n pass === 2\n ? 'Start with exactly <shouldCompact>true</shouldCompact> or <shouldCompact>false</shouldCompact>. Use true when the staged summary safely retains the important parent context. Use false only when it is not yet sufficient for safe compaction.\\n\\n'\n : '';\n\n // Summarization is a tool-less single LLM call, so instructions describe only what to\n // produce. Directives aimed at an implementing agent leak into the checkpoint body.\n return `Create Doom autocompact checkpoint pass ${pass}.\n\n${steeringEnvelope(steering)}\n\nApply the steering evidence in priority order. Do not invent plan or contributed runtime state. Preserve verified facts and mark unresolved inference explicitly. Newer evidence replaces superseded information.\n\n${decision}Return only the decision tag when required, followed by a concise structured checkpoint using every heading below. Keep exact goals, constraints, decisions, blockers, commands, errors, file paths, validation evidence, and the immediate next action. Separate verified facts from unresolved inference.\n\n## Goal\n## Constraints & Preferences\n## Progress\n### Done\n### In Progress\n### Blocked\n## Key Decisions\n## Next Steps\n## Critical Context`;\n}\n\nfunction messagesForCheckpoint(\n pass: AutocompactPass,\n branch: SessionEntry[],\n previousSnapshotLeafId: string | undefined,\n): CheckpointMessages {\n const projected = projectContextMessages(buildSessionContext(branch).messages, branch).messages;\n if (pass === 1 || !previousSnapshotLeafId) return projected;\n const snapshotIndex = branch.findIndex((entry) => entry.id === previousSnapshotLeafId);\n if (snapshotIndex === -1) return projected;\n return branch\n .slice(snapshotIndex + 1)\n .filter((entry) => entry.type !== 'custom_message' || entry.customType !== CHECKPOINT_MESSAGE_TYPE)\n .flatMap((entry) => sessionEntryToContextMessages(entry));\n}\n\ninterface AutocompactRuntimeConfig {\n /** Off leaves compaction to Pi; unset is on. */\n enabled: boolean;\n /** The agent that writes the summaries, from autocompact's own keys or planning's. */\n agent?: PlanningAgentConfig;\n ratios: AutocompactRatioOverrides;\n /** Per-model absolute token checkpoints, tried in file order. */\n overrides: AutocompactOverrideConfig[];\n}\n\nconst DEFAULT_RUNTIME_CONFIG: AutocompactRuntimeConfig = { enabled: true, ratios: {}, overrides: [] };\n\n/**\n * What the Doom config says about this package.\n *\n * `modes.autocompact` is read first and `modes.planning.subagents` is the\n * fallback, because summarization borrowed the planning subagent model before\n * it had keys of its own and existing files still spell it that way.\n */\nexport function autocompactRuntimeConfig(\n cwd: string,\n onLoadFailure?: (error: unknown) => void,\n): AutocompactRuntimeConfig {\n let modes: ReturnType<typeof loadDoomConfig>['modes'];\n try {\n modes = loadDoomConfig(getHarnessState().root ?? cwd).modes;\n } catch (error) {\n process.emitWarning('Doom autocompact configuration could not be loaded; using the active session model instead.');\n onLoadFailure?.(error);\n return DEFAULT_RUNTIME_CONFIG;\n }\n const configured = modes?.autocompact;\n const ownAgent: PlanningAgentConfig | undefined =\n configured && (configured.model !== undefined || configured.thinking !== undefined)\n ? {\n ...(configured.model ? { model: configured.model } : {}),\n ...(configured.thinking ? { thinking: configured.thinking } : {}),\n }\n : undefined;\n const agent = ownAgent ?? modes?.planning?.subagents;\n const thresholds = configured?.thresholds;\n return {\n enabled: configured?.enabled ?? true,\n ...(agent ? { agent } : {}),\n ratios: {\n ...(thresholds?.pass1 === undefined ? {} : { 1: thresholds.pass1 }),\n ...(thresholds?.pass2 === undefined ? {} : { 2: thresholds.pass2 }),\n ...(thresholds?.pass3 === undefined ? {} : { 3: thresholds.pass3 }),\n },\n overrides: configured?.overrides ?? [],\n };\n}\n\n/** Explicit Doom model selection honors the configured summarization model. */\nexport function resolveDoomSummarizationModel(ctx: ExtensionContext): SummarizationModel | undefined {\n const configured = autocompactRuntimeConfig(ctx.cwd).agent;\n const reference = configured?.model ? parseModelReference(configured.model) : undefined;\n const configuredModel = reference ? ctx.modelRegistry.find(reference.provider, reference.modelId) : undefined;\n const model = configuredModel ?? ctx.model;\n if (!model) return undefined;\n const thinkingLevel =\n configured?.thinking ?? (configuredModel ? reference?.thinking : undefined) ?? ctx.thinkingLevel;\n return { model, ...(thinkingLevel ? { thinkingLevel } : {}) };\n}\n\n/**\n * Summarization borrows the session's own provider instead of re-resolving one.\n *\n * The selected model can come from a Pi provider extension, and that extension's\n * `streamSimple` closure lives only in this process: it is never in Pi's global api\n * registry, so any other thread or process sees `No API provider registered for api`.\n * Passing the composed provider in as `generateSummary`'s stream function keeps\n * summarization on exactly the path the agent's own requests take.\n */\nexport async function generateCheckpointWithPi(\n input: CheckpointGenerationInput,\n resolveModel: (context: ExtensionContext) => SummarizationModel | undefined,\n): Promise<string> {\n const selection = resolveModel(input.context);\n if (!selection) throw new Error('No active model is available for autocompact summarization.');\n const auth = await input.context.modelRegistry.getApiKeyAndHeaders(selection.model);\n if (!auth.ok) throw new Error(auth.error);\n const provider = input.context.modelRegistry.getProvider(selection.model.provider);\n if (!provider) {\n throw new Error(`No provider is registered for \"${selection.model.provider}\" in this session.`);\n }\n return generateSummary(\n input.messages,\n selection.model,\n DEFAULT_COMPACTION_SETTINGS.reserveTokens,\n auth.apiKey,\n // A null header value suppresses a provider default, which the narrower\n // `generateSummary` signature does not model but every provider honors.\n auth.headers as Record<string, string> | undefined,\n input.signal,\n input.instructions,\n input.previousCheckpoint,\n selection.thinkingLevel,\n (model, context, options) => provider.streamSimple(model, context, options),\n auth.env,\n );\n}\n\nfunction notify(ctx: ExtensionContext | undefined, message: string, level: 'info' | 'warning' | 'error' = 'info') {\n if (ctx?.hasUI) ctx.ui.notify(message, level);\n}\n\nexport function createAutocompactRuntime(\n pi: ExtensionAPI,\n dependencies: AutocompactDependencies = {},\n): AutocompactRuntime {\n const resolveModel = dependencies.resolveModel ?? resolveDoomSummarizationModel;\n const generateCheckpoint =\n dependencies.generateCheckpoint ??\n ((input: CheckpointGenerationInput) => generateCheckpointWithPi(input, resolveModel));\n const telemetry = dependencies.telemetry ?? createAutocompactTelemetry();\n const doomIntegrations = dependencies.doomIntegrations ?? true;\n const appliedContextRequests = new Set<string>();\n const invalidContextLeaves = new Set<string>();\n const checkpointWork = new Set<Promise<void>>();\n let active = true;\n let sessionGeneration = 0;\n let state = createInitialState();\n let currentContext: ExtensionContext | undefined;\n let checkpointController: AbortController | undefined;\n let footerContribution: DoomFooterContributionHandle | undefined;\n let contextContributionsService: DoomContextContributionsService | undefined;\n let configLoadFailureReported = false;\n\n const stop = async (): Promise<void> => {\n active = false;\n sessionGeneration += 1;\n checkpointController?.abort(new Error('Autocompact runtime is shutting down.'));\n checkpointController = undefined;\n await Promise.allSettled(checkpointWork);\n footerContribution = undefined;\n contextContributionsService = undefined;\n currentContext = undefined;\n appliedContextRequests.clear();\n invalidContextLeaves.clear();\n state = createInitialState();\n configLoadFailureReported = false;\n await telemetry.shutdown();\n };\n\n const plugin = (cordis: Context): void => {\n cordis.inject([DOOM_CONTEXT_CONTRIBUTIONS_SERVICE], (contextContributionsContext) => {\n const service = requireDoomContextContributions(contextContributionsContext);\n contextContributionsService = service;\n return () => {\n if (contextContributionsService === service) contextContributionsService = undefined;\n };\n });\n\n if (doomIntegrations) {\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n const contribution = requireDoomUiHub(uiContext).registerFooter({\n source: FOOTER_SOURCE,\n id: 'autocompact',\n order: FOOTER_ORDER,\n });\n footerContribution = contribution;\n return () => {\n contribution.dispose();\n if (footerContribution === contribution) footerContribution = undefined;\n };\n });\n }\n };\n\n /** Compaction runs off the main thread, so the phase is the only signal the user gets. */\n const refreshStatus = (ctx?: ExtensionContext): void => {\n if (!active) return;\n const phase =\n state.phase === STATE_PHASE.checkpointPending\n ? 'summarizing'\n : state.phase === STATE_PHASE.checkpointReady\n ? 'applying'\n : undefined;\n footerContribution?.update(\n phase ? { fullText: `Compacting p${state.pass}`, compactText: `C${state.pass}` } : undefined,\n );\n const target = ctx ?? currentContext;\n if (target?.hasUI) target.ui.setStatus(STATUS_KEY, phase ? `Compacting pass ${state.pass} (${phase})…` : undefined);\n };\n\n // Every phase transition persists, so this is the one place that keeps the status honest.\n const persist = (): void => {\n if (!active) return;\n pi.appendEntry(STATE_CUSTOM_TYPE, { ...state });\n refreshStatus();\n };\n\n const clearPendingCheckpoint = (): void => {\n delete state.requestId;\n delete state.snapshotLeafId;\n delete state.snapshotTokens;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n };\n\n const completeQueuedPass = (pass: AutocompactPass): void => {\n state.checkpointQueue = state.checkpointQueue.filter((queuedPass) => queuedPass !== pass);\n };\n\n const restore = (ctx: ExtensionContext): void => {\n if (!active) return;\n state = latestPersistedState(ctx.sessionManager.getBranch()) ?? createInitialState();\n const resumablePending =\n state.phase === STATE_PHASE.checkpointReady && state.requestId && state.snapshotLeafId && state.pendingCheckpoint;\n if (resumablePending || state.phase === STATE_PHASE.waiting) return;\n\n checkpointController?.abort();\n checkpointController = undefined;\n state.phase = STATE_PHASE.waiting;\n clearPendingCheckpoint();\n persist();\n };\n\n const resumeAgent = (message: string): void => {\n if (!active) return;\n pi.sendMessage(\n {\n customType: RESUME_MESSAGE_TYPE,\n content: `${message} Continue from the compacted checkpoint's immediate next action without repeating completed work.`,\n display: false,\n details: { version: STATE_VERSION, cycle: state.cycle, pass: state.pass },\n },\n { triggerTurn: true, deliverAs: 'steer' },\n );\n };\n\n /**\n * Both failure paths share one attempt budget: a summarizer that keeps failing would\n * otherwise cost a full summarization call every turn for the rest of the session, so the\n * pass is abandoned once the budget is spent and becomes eligible again on the next cycle.\n */\n const registerFailedAttempt = (\n pass: AutocompactPass,\n failedLeafId: string | undefined,\n ): { attempts: number; exhausted: boolean } => {\n const attempts = state.invalidAttempts + 1;\n const exhausted = attempts >= MAX_INVALID_CHECKPOINT_ATTEMPTS;\n state.phase = STATE_PHASE.waiting;\n if (failedLeafId) state.lastAttemptLeafId = failedLeafId;\n if (exhausted) {\n completeQueuedPass(pass);\n state.exhaustedPasses = [...state.exhaustedPasses, pass];\n state.invalidAttempts = 0;\n } else {\n state.invalidAttempts = attempts;\n }\n clearPendingCheckpoint();\n persist();\n return { attempts, exhausted };\n };\n\n const failCheckpoint = (requestId: string, error: unknown): void => {\n if (!active || requestId !== state.requestId || state.phase !== STATE_PHASE.checkpointPending) return;\n const pass = state.pass;\n const { attempts, exhausted } = registerFailedAttempt(pass, state.snapshotLeafId);\n const reason = error instanceof Error ? error.message : String(error);\n notify(\n currentContext,\n exhausted\n ? `Doom autocompact summarization pass ${pass} failed ${attempts} times and was abandoned: ${reason}`\n : `Doom autocompact summarization pass ${pass} failed: ${reason}`,\n 'error',\n );\n };\n\n // A configuration that cannot be read degrades every later pass silently, and the process\n // warning never reaches the log sink. Report it once per session instead of once per turn.\n const reportConfigLoadFailure = (ctx: ExtensionContext, error: unknown): void => {\n if (!active || configLoadFailureReported) return;\n configLoadFailureReported = true;\n void telemetry.recordWarning(\n AUTOCOMPACT_EVENT.configurationLoadFailed,\n error,\n telemetryAttributes(ctx, { 'autocompact.cycle': state.cycle, 'autocompact.pass': state.pass }),\n );\n };\n\n const reportContributionFailures = (\n ctx: ExtensionContext,\n snapshot: DoomContextContributionsSnapshot,\n attributes: AutocompactEventAttributes,\n ): void => {\n if (!active) return;\n for (const error of snapshot.errors) {\n notify(\n ctx,\n `Doom autocompact context contribution degraded (${error.source}/${error.id}): ${error.message}`,\n 'warning',\n );\n void telemetry.recordWarning(AUTOCOMPACT_EVENT.contextContributionDegraded, new Error(error.message), {\n ...attributes,\n 'autocompact.context_contribution.source': error.source,\n 'autocompact.context_contribution.id': error.id,\n 'autocompact.context_contribution.order': error.order,\n });\n }\n };\n\n const preserveRuntimeState = (\n ctx: ExtensionContext,\n branch: SessionEntry[],\n attributes: AutocompactEventAttributes,\n ): RuntimeStateSnapshot => {\n if (!active) {\n return { contributions: [], contributionErrors: [] };\n }\n const contextContributions = readContextContributionsSnapshot(contextContributionsService);\n reportContributionFailures(ctx, contextContributions, attributes);\n const snapshot = runtimeStateSnapshot(branch, contextContributions);\n pi.sendMessage({\n customType: RUNTIME_STATE_MESSAGE_TYPE,\n content: formatRuntimeState(snapshot),\n display: false,\n details: { version: 2, ...snapshot },\n });\n return snapshot;\n };\n\n const commitCheckpoint = (pass: 2 | 3, ctx: ExtensionContext): boolean => {\n if (!active || !state.requestId || !state.snapshotLeafId || !state.pendingCheckpoint) return false;\n const branch = ctx.sessionManager.getBranch();\n const projected = projectContextMessages(buildSessionContext(branch).messages, branch).messages;\n const fileDetails = mergeFileDetails(state, fileOperationsFromMessages(projected));\n const requestId = state.requestId;\n const cycle = state.cycle;\n const summary = withCanonicalFileSections(state.pendingCheckpoint, fileDetails);\n const details: AutocompactContextDetails = {\n ...fileDetails,\n doomAutocompact: {\n version: STATE_VERSION,\n cycle,\n pass,\n requestId,\n snapshotLeafId: state.snapshotLeafId,\n tokensBefore: state.snapshotTokens ?? ctx.getContextUsage()?.tokens ?? 0,\n },\n retainedMessages: retainedMessagesAfterSnapshot(branch, state.snapshotLeafId),\n };\n\n const committedWhileIdle = ctx.isIdle();\n pi.sendMessage({ customType: CONTEXT_MESSAGE_TYPE, content: summary, display: false, details });\n const contextMessageLeafId = workingLeafId(ctx);\n const runtimeAttributes = telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': cycle,\n 'autocompact.pass': pass,\n });\n const runtimeSnapshot = preserveRuntimeState(ctx, branch, runtimeAttributes);\n // Mid-run the marker is queued as a steering message, so its entry id is not resolvable yet.\n if (committedWhileIdle) pi.setLabel(contextMessageLeafId, `autocompact:c${cycle}:p${pass}`);\n\n state.readFiles = fileDetails.readFiles;\n state.modifiedFiles = fileDetails.modifiedFiles;\n delete state.latestCheckpointSnapshotLeafId;\n state.phase = STATE_PHASE.waiting;\n state.checkpointQueue = [];\n // A compacted context is a fresh ladder: passes abandoned in the previous cycle are eligible again.\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n state.baselinePending = true;\n delete state.lastAttemptLeafId;\n clearPendingCheckpoint();\n state.cycle += 1;\n state.pass = 1;\n persist();\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextCommitted,\n telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': cycle,\n 'autocompact.pass': pass,\n 'autocompact.snapshot_leaf_id': details.doomAutocompact.snapshotLeafId,\n 'autocompact.tokens_before': details.doomAutocompact.tokensBefore,\n 'autocompact.message_count.before': projected.length,\n 'autocompact.message_count.retained': details.retainedMessages.length,\n 'autocompact.apply_mode': committedWhileIdle ? 'idle' : 'turn_end',\n ...runtimeTelemetryAttributes(runtimeSnapshot),\n }),\n );\n // A mid-run commit needs no resume steer: the agent is already continuing.\n if (committedWhileIdle) resumeAgent('Asynchronous compaction completed.');\n return true;\n };\n\n const requestCheckpoint = (pass: AutocompactPass, ctx: ExtensionContext, tokensBefore: number): void => {\n if (!active) return;\n const generation = sessionGeneration;\n const branch = ctx.sessionManager.getBranch();\n const snapshotLeafId = workingLeafId(ctx);\n const requestId = createRequestId(ctx.sessionManager.getSessionId(), state.cycle, pass, snapshotLeafId);\n const previousCheckpoint = pass > 1 ? checkpointSummaryFromEntry(latestCheckpointArtifactEntry(branch)) : undefined;\n const messages = messagesForCheckpoint(pass, branch, state.latestCheckpointSnapshotLeafId);\n const contextContributions = readContextContributionsSnapshot(contextContributionsService);\n const attributes = telemetryAttributes(ctx, {\n 'autocompact.request.id': requestId,\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': pass,\n 'autocompact.snapshot_leaf_id': snapshotLeafId,\n 'autocompact.tokens_before': tokensBefore,\n 'autocompact.message_count.before': messages.length,\n });\n reportContributionFailures(ctx, contextContributions, attributes);\n\n state.phase = STATE_PHASE.checkpointPending;\n state.pass = pass;\n state.requestId = requestId;\n state.snapshotLeafId = snapshotLeafId;\n state.snapshotTokens = tokensBefore;\n delete state.pendingCheckpoint;\n delete state.compactionPass;\n delete state.lastAttemptLeafId;\n persist();\n\n checkpointController?.abort();\n checkpointController = new AbortController();\n const checkpointSignal = checkpointController.signal;\n const operation = telemetry\n .runInSpan('doom_autocompact.checkpoint', attributes, async () => {\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointStarted, attributes);\n try {\n const checkpoint = await generateCheckpoint({\n messages,\n instructions: checkpointInstructions(pass, {\n plan: latestPlanSnapshot(branch),\n contextContributions,\n readFiles: state.readFiles,\n modifiedFiles: state.modifiedFiles,\n }),\n ...(previousCheckpoint ? { previousCheckpoint } : {}),\n context: ctx,\n signal: checkpointSignal,\n });\n if (!active || generation !== sessionGeneration) {\n throw checkpointSignal.reason ?? new Error('Autocompact checkpoint became stale.');\n }\n if (!checkpoint.trim()) throw new Error('Summarization returned an empty checkpoint.');\n await telemetry.recordEvent(AUTOCOMPACT_EVENT.checkpointCompleted, {\n ...attributes,\n 'autocompact.checkpoint.characters': checkpoint.length,\n });\n return checkpoint;\n } catch (error) {\n if (active && generation === sessionGeneration) {\n await telemetry.recordError(AUTOCOMPACT_EVENT.checkpointFailed, error, attributes);\n }\n throw error;\n }\n })\n .then((checkpoint) => {\n if (\n !active ||\n generation !== sessionGeneration ||\n requestId !== state.requestId ||\n state.phase !== STATE_PHASE.checkpointPending\n ) {\n return;\n }\n state.phase = STATE_PHASE.checkpointReady;\n state.pendingCheckpoint = checkpoint.trim();\n persist();\n if (currentContext) processProgress(currentContext);\n })\n .catch((error: unknown) => {\n if (active && generation === sessionGeneration) failCheckpoint(requestId, error);\n });\n checkpointWork.add(operation);\n void operation.finally(() => checkpointWork.delete(operation));\n };\n\n const evaluateUsage = (ctx: ExtensionContext): boolean => {\n if (!active || state.phase !== STATE_PHASE.waiting || ctx.hasPendingMessages()) return false;\n // Read per evaluation rather than once at install, so turning the ladder off\n // or moving a threshold in settings takes effect on the next turn instead of\n // the next session.\n const configured = autocompactRuntimeConfig(ctx.cwd, (error) => reportConfigLoadFailure(ctx, error));\n if (!configured.enabled) return false;\n const usage = ctx.getContextUsage();\n if (!usage || usage.tokens === null) return false;\n if (state.baselinePending) {\n // Reported usage still describes the pre-compaction context until an assistant\n // responds against the projected one, and capturing it early poisons every threshold.\n if (!baselineUsageIsSettled(ctx.sessionManager.getBranch())) return false;\n state.baselineTokens = usage.tokens;\n state.baselinePending = false;\n persist();\n return false;\n }\n const leafId = workingLeafId(ctx);\n if (state.lastAttemptLeafId === leafId) return false;\n\n // The baseline branch above always returns, so by here it is settled for this cycle and the\n // token overrides can be compared against it without re-checking `baselinePending`.\n const tokenOverrides = resolveModelTokenOverrides(ctx.model, configured.overrides);\n const thresholds = effectiveThresholds(\n usage.contextWindow,\n state.baselineTokens,\n configured.ratios,\n tokenOverrides,\n );\n for (const pass of [1, 2, 3] as const) {\n if (pass < state.pass || state.checkpointQueue.includes(pass) || state.exhaustedPasses.includes(pass)) continue;\n if (usage.tokens >= thresholds[pass]) {\n state.checkpointQueue.push(pass);\n }\n }\n const nextPass = state.checkpointQueue[0];\n if (!nextPass) return false;\n requestCheckpoint(nextPass, ctx, usage.tokens);\n return true;\n };\n\n // Staged checkpoints seed the next summarization pass only. They are appended as plain\n // session entries so they never enter the agent's LLM context: delivering them as messages\n // reads like a user instruction and derails the run (\"Checkpoint acknowledged...\").\n const stageCheckpoint = (pass: 1 | 2, summary: string): void => {\n if (!active) return;\n const checkpointSnapshotLeafId = state.snapshotLeafId;\n pi.appendEntry(CHECKPOINT_MESSAGE_TYPE, {\n ...checkpointRequestDetails(state.cycle, pass, state.requestId ?? 'completed'),\n summary,\n });\n if (checkpointSnapshotLeafId) state.latestCheckpointSnapshotLeafId = checkpointSnapshotLeafId;\n };\n\n const captureReadyCheckpoint = (ctx: ExtensionContext): CheckpointCapture => {\n if (!active || state.phase !== STATE_PHASE.checkpointReady || !state.requestId || !state.pendingCheckpoint) {\n return 'none';\n }\n const pass = state.pass;\n const decision = parseCheckpointDecision(state.pendingCheckpoint);\n if (!isStructuredCheckpoint(decision.summary)) {\n const failedLeafId = state.snapshotLeafId;\n const invalidRequestId = state.requestId;\n // A queued pass is retried once per new leaf, so an output the summarizer never formats\n // correctly would otherwise burn a full summarization call every turn for the session.\n const { attempts, exhausted } = registerFailedAttempt(pass, failedLeafId);\n const error = new Error(`Summarization pass ${pass} returned an incomplete checkpoint.`);\n notify(\n ctx,\n exhausted\n ? `Doom autocompact summarization pass ${pass} returned an incomplete checkpoint ${attempts} times and was abandoned.`\n : `Doom autocompact summarization pass ${pass} returned an incomplete checkpoint.`,\n 'error',\n );\n void telemetry.recordError(\n AUTOCOMPACT_EVENT.checkpointInvalid,\n error,\n telemetryAttributes(ctx, {\n 'autocompact.cycle': state.cycle,\n 'autocompact.pass': pass,\n 'autocompact.checkpoint.attempts': attempts,\n 'autocompact.checkpoint.exhausted': exhausted,\n ...(invalidRequestId ? { 'autocompact.request.id': invalidRequestId } : {}),\n }),\n );\n return 'invalid';\n }\n\n state.invalidAttempts = 0;\n\n if (pass === 1) {\n stageCheckpoint(1, decision.summary);\n completeQueuedPass(1);\n state.phase = STATE_PHASE.waiting;\n state.pass = 2;\n clearPendingCheckpoint();\n persist();\n return 'pass1';\n }\n\n if (pass === 2 && decision.shouldCompact !== true) {\n stageCheckpoint(2, decision.summary);\n completeQueuedPass(2);\n state.phase = STATE_PHASE.waiting;\n state.pass = 3;\n clearPendingCheckpoint();\n persist();\n return 'deferred';\n }\n\n state.pendingCheckpoint = decision.summary;\n return commitCheckpoint(pass, ctx) ? 'committed' : 'invalid';\n };\n\n function processProgress(ctx: ExtensionContext): void {\n if (!active) return;\n currentContext = ctx;\n if (!ctx.isIdle()) return;\n if (captureReadyCheckpoint(ctx) !== 'committed') evaluateUsage(ctx);\n }\n\n const beginSessionGeneration = (ctx: ExtensionContext): void => {\n if (!active) return;\n sessionGeneration += 1;\n checkpointController?.abort(new Error('Autocompact session generation was replaced.'));\n checkpointController = undefined;\n appliedContextRequests.clear();\n invalidContextLeaves.clear();\n currentContext = ctx;\n restore(ctx);\n processProgress(ctx);\n };\n\n /**\n * Replaces the messages pi is about to send with the projection the last\n * applied checkpoint describes. Split out from the hook so the hook can time\n * it without threading a duration through three return paths.\n */\n const shapeContext = (event: ContextEvent, ctx: ExtensionContext) => {\n if (!active) return undefined;\n const projection = projectContextMessages(event.messages, ctx.sessionManager.getBranch());\n if (projection.invalidMarker) {\n const leafId = ctx.sessionManager.getLeafId() ?? ROOT_WORKING_LEAF;\n if (!invalidContextLeaves.has(leafId)) {\n invalidContextLeaves.add(leafId);\n void telemetry.recordError(\n AUTOCOMPACT_EVENT.contextMarkerInvalid,\n new Error('Doom autocompact context marker is malformed.'),\n telemetryAttributes(ctx, { 'autocompact.leaf_id': leafId }),\n );\n }\n return undefined;\n }\n if (!projection.marker) return undefined;\n if (!appliedContextRequests.has(projection.marker.requestId)) {\n appliedContextRequests.add(projection.marker.requestId);\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextApplied,\n telemetryAttributes(ctx, {\n 'autocompact.request.id': projection.marker.requestId,\n 'autocompact.cycle': projection.marker.cycle,\n 'autocompact.pass': projection.marker.pass,\n 'autocompact.snapshot_leaf_id': projection.marker.snapshotLeafId,\n 'autocompact.tokens_before': projection.marker.tokensBefore,\n 'autocompact.message_count.before': event.messages.length,\n 'autocompact.message_count.after': projection.messages.length,\n 'autocompact.message_count.retained': projection.retainedMessageCount,\n }),\n );\n }\n return { messages: projection.messages };\n };\n return {\n plugin,\n stop,\n events: {\n context: (event, ctx) => {\n // pi awaits this hook inside every request and the body walks the whole\n // branch, so it is one of the few costs that can grow with a session's\n // length. Reported only past the threshold: a hook this hot would\n // otherwise emit an event per request.\n const hookStartedAt = Date.now();\n try {\n return shapeContext(event, ctx);\n } finally {\n const hookMs = Date.now() - hookStartedAt;\n if (hookMs >= SLOW_CONTEXT_HOOK_MS) {\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.contextHookSlow,\n telemetryAttributes(ctx, { hook_ms: hookMs, 'autocompact.message_count': event.messages.length }),\n );\n }\n }\n },\n\n session_start: (_event, ctx) => beginSessionGeneration(ctx),\n\n session_tree: (_event, ctx) => beginSessionGeneration(ctx),\n\n turn_end: (event, ctx) => {\n if (!active) return;\n currentContext = ctx;\n if (ctx.isIdle()) {\n processProgress(ctx);\n return;\n }\n // A ready checkpoint must be applied without waiting for the run to finish, otherwise\n // context keeps growing past the window for the rest of a long autonomous run. Tool\n // results confirm the run continues, so the queued marker lands before the next request.\n const canApplyDuringRun =\n state.phase === STATE_PHASE.checkpointReady &&\n (event.toolResults?.length ?? 0) > 0 &&\n !ctx.hasPendingMessages();\n if (canApplyDuringRun && captureReadyCheckpoint(ctx) !== 'none') return;\n evaluateUsage(ctx);\n },\n\n agent_settled: (_event, ctx) => {\n if (!active) return;\n processProgress(ctx);\n },\n\n session_before_compact: (event) => {\n if (!active || event.reason !== 'threshold') return undefined;\n // Native compaction stays cancelled while our own machinery is working, and stays\n // available as the emergency backstop once that machinery has stalled or declined.\n const machineryActive =\n state.phase === STATE_PHASE.checkpointPending ||\n state.phase === STATE_PHASE.checkpointReady ||\n state.baselinePending;\n return machineryActive ? { cancel: true } : undefined;\n },\n\n session_compact: (event, ctx) => {\n if (!active) return;\n sessionGeneration += 1;\n // Native compaction supersedes any summarization still in flight.\n checkpointController?.abort();\n checkpointController = undefined;\n const eventDetails = fileDetailsFromUnknown(event.compactionEntry.details);\n const cumulative = mergeFileDetails(state, undefined, eventDetails);\n state.readFiles = cumulative.readFiles;\n state.modifiedFiles = cumulative.modifiedFiles;\n delete state.latestCheckpointSnapshotLeafId;\n // Reported usage still describes the pre-compaction context here too, so the baseline\n // waits for the first assistant response measured against the compacted one.\n state.baselinePending = true;\n state.phase = STATE_PHASE.waiting;\n clearPendingCheckpoint();\n state.checkpointQueue = [];\n state.exhaustedPasses = [];\n state.invalidAttempts = 0;\n delete state.lastAttemptLeafId;\n\n pi.setLabel(event.compactionEntry.id, `autocompact:c${state.cycle}:external`);\n const completedCycle = state.cycle;\n const runtimeAttributes = telemetryAttributes(ctx, {\n 'autocompact.cycle': completedCycle,\n 'autocompact.native.reason': event.reason,\n });\n const runtimeSnapshot = preserveRuntimeState(ctx, ctx.sessionManager.getBranch(), runtimeAttributes);\n state.cycle += 1;\n state.pass = 1;\n persist();\n void telemetry.recordEvent(\n AUTOCOMPACT_EVENT.nativeCompactionCompleted,\n telemetryAttributes(ctx, {\n 'autocompact.cycle': completedCycle,\n 'autocompact.native.reason': event.reason,\n 'autocompact.native.from_extension': event.fromExtension,\n 'autocompact.tokens_before': event.compactionEntry.tokensBefore,\n ...runtimeTelemetryAttributes(runtimeSnapshot),\n }),\n );\n },\n },\n };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- let e=require("@agimon-ai/doompi-telemetry");const t={checkpointStarted:`doom_autocompact.checkpoint_started`,checkpointCompleted:`doom_autocompact.checkpoint_completed`,checkpointFailed:`doom_autocompact.checkpoint_failed`,checkpointInvalid:`doom_autocompact.checkpoint_invalid`,configurationLoadFailed:`doom_autocompact.configuration_load_failed`,contextContributionDegraded:`doom_autocompact.context_contribution_degraded`,contextCommitted:`doom_autocompact.context_committed`,contextApplied:`doom_autocompact.context_applied`,contextMarkerInvalid:`doom_autocompact.context_marker_invalid`,nativeCompactionCompleted:`doom_autocompact.native_compaction_completed`};function n(t={}){let n=(0,e.createDoomTelemetry)({serviceName:`doom-autocompact`,packageName:`@agimon-ai/doompi-autocompact`,cwd:t.cwd,workspaceRoot:t.workspaceRoot,env:t.env,telemetryFactory:t.telemetryFactory,warn:t.warn,enableLogs:!0,enableTraces:!0});return{recordError:(e,t,r)=>n.recordError(e,t,r),recordWarning:(e,t,r)=>n.recordWarning(e,t,r),recordEvent:(e,t)=>n.recordEvent(e,t),runInSpan:(e,t,r)=>n.runInSpan(e,t,r),flush:()=>n.flush(),shutdown:()=>n.shutdown()}}exports.AUTOCOMPACT_EVENT=t,exports.createAutocompactTelemetry=n;
1
+ let e=require("@agimon-ai/doompi-telemetry");const t={checkpointStarted:`doom_autocompact.checkpoint_started`,checkpointCompleted:`doom_autocompact.checkpoint_completed`,checkpointFailed:`doom_autocompact.checkpoint_failed`,checkpointInvalid:`doom_autocompact.checkpoint_invalid`,configurationLoadFailed:`doom_autocompact.configuration_load_failed`,contextContributionDegraded:`doom_autocompact.context_contribution_degraded`,contextCommitted:`doom_autocompact.context_committed`,contextApplied:`doom_autocompact.context_applied`,contextMarkerInvalid:`doom_autocompact.context_marker_invalid`,contextHookSlow:`doom_autocompact.context_hook_slow`,nativeCompactionCompleted:`doom_autocompact.native_compaction_completed`};function n(t={}){let n=(0,e.createDoomTelemetry)({serviceName:`doom-autocompact`,packageName:`@agimon-ai/doompi-autocompact`,cwd:t.cwd,workspaceRoot:t.workspaceRoot,env:t.env,telemetryFactory:t.telemetryFactory,warn:t.warn,enableLogs:!0,enableTraces:!0});return{recordError:(e,t,r)=>n.recordError(e,t,r),recordWarning:(e,t,r)=>n.recordWarning(e,t,r),recordEvent:(e,t)=>n.recordEvent(e,t),runInSpan:(e,t,r)=>n.runInSpan(e,t,r),flush:()=>n.flush(),shutdown:()=>n.shutdown()}}exports.AUTOCOMPACT_EVENT=t,exports.createAutocompactTelemetry=n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createDoomTelemetry"],"sources":["../../../src/services/autocompactTelemetry/index.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-autocompact';\nconst PACKAGE_NAME = '@agimon-ai/doompi-autocompact';\n\nexport const AUTOCOMPACT_EVENT = {\n checkpointStarted: 'doom_autocompact.checkpoint_started',\n checkpointCompleted: 'doom_autocompact.checkpoint_completed',\n checkpointFailed: 'doom_autocompact.checkpoint_failed',\n checkpointInvalid: 'doom_autocompact.checkpoint_invalid',\n configurationLoadFailed: 'doom_autocompact.configuration_load_failed',\n contextContributionDegraded: 'doom_autocompact.context_contribution_degraded',\n contextCommitted: 'doom_autocompact.context_committed',\n contextApplied: 'doom_autocompact.context_applied',\n contextMarkerInvalid: 'doom_autocompact.context_marker_invalid',\n nativeCompactionCompleted: 'doom_autocompact.native_compaction_completed',\n} as const;\n\nexport type AutocompactEventName = (typeof AUTOCOMPACT_EVENT)[keyof typeof AUTOCOMPACT_EVENT];\nexport type AutocompactEventAttributes = Record<string, string | number | boolean>;\n\nexport interface AutocompactTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface AutocompactTelemetry {\n recordError(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordWarning(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordEvent(event: AutocompactEventName, attributes?: AutocompactEventAttributes): Promise<void>;\n runInSpan<T>(name: string, attributes: AutocompactEventAttributes, callback: () => Promise<T>): Promise<T>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createAutocompactTelemetry(options: AutocompactTelemetryOptions = {}): AutocompactTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n runInSpan: (name, attributes, callback) => telemetry.runInSpan(name, attributes, callback),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"6CAEA,MAGa,EAAoB,CAC/B,kBAAmB,sCACnB,oBAAqB,wCACrB,iBAAkB,qCAClB,kBAAmB,sCACnB,wBAAyB,6CACzB,4BAA6B,iDAC7B,iBAAkB,qCAClB,eAAgB,mCAChB,qBAAsB,0CACtB,0BAA2B,8CAC7B,EAsBA,SAAgB,EAA2B,EAAuC,CAAC,EAAyB,CAC1G,IAAM,GAAA,EAA2BA,EAAAA,oBAAAA,CAAoB,CACnD,YAAa,mBACb,YAAa,gCACb,IAAK,EAAQ,IACb,cAAe,EAAQ,cACvB,IAAK,EAAQ,IACb,iBAAkB,EAAQ,iBAC1B,KAAM,EAAQ,KACd,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,MAAO,CACL,aAAc,EAAO,EAAO,IAAe,EAAU,YAAY,EAAO,EAAO,CAAU,EACzF,eAAgB,EAAO,EAAO,IAAe,EAAU,cAAc,EAAO,EAAO,CAAU,EAC7F,aAAc,EAAO,IAAe,EAAU,YAAY,EAAO,CAAU,EAC3E,WAAY,EAAM,EAAY,IAAa,EAAU,UAAU,EAAM,EAAY,CAAQ,EACzF,UAAa,EAAU,MAAM,EAC7B,aAAgB,EAAU,SAAS,CACrC,CACF"}
1
+ {"version":3,"file":"index.cjs","names":["createDoomTelemetry"],"sources":["../../../src/services/autocompactTelemetry/index.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-autocompact';\nconst PACKAGE_NAME = '@agimon-ai/doompi-autocompact';\n\nexport const AUTOCOMPACT_EVENT = {\n checkpointStarted: 'doom_autocompact.checkpoint_started',\n checkpointCompleted: 'doom_autocompact.checkpoint_completed',\n checkpointFailed: 'doom_autocompact.checkpoint_failed',\n checkpointInvalid: 'doom_autocompact.checkpoint_invalid',\n configurationLoadFailed: 'doom_autocompact.configuration_load_failed',\n contextContributionDegraded: 'doom_autocompact.context_contribution_degraded',\n contextCommitted: 'doom_autocompact.context_committed',\n contextApplied: 'doom_autocompact.context_applied',\n contextMarkerInvalid: 'doom_autocompact.context_marker_invalid',\n contextHookSlow: 'doom_autocompact.context_hook_slow',\n nativeCompactionCompleted: 'doom_autocompact.native_compaction_completed',\n} as const;\n\nexport type AutocompactEventName = (typeof AUTOCOMPACT_EVENT)[keyof typeof AUTOCOMPACT_EVENT];\nexport type AutocompactEventAttributes = Record<string, string | number | boolean>;\n\nexport interface AutocompactTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface AutocompactTelemetry {\n recordError(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordWarning(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordEvent(event: AutocompactEventName, attributes?: AutocompactEventAttributes): Promise<void>;\n runInSpan<T>(name: string, attributes: AutocompactEventAttributes, callback: () => Promise<T>): Promise<T>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createAutocompactTelemetry(options: AutocompactTelemetryOptions = {}): AutocompactTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n runInSpan: (name, attributes, callback) => telemetry.runInSpan(name, attributes, callback),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"6CAEA,MAGa,EAAoB,CAC/B,kBAAmB,sCACnB,oBAAqB,wCACrB,iBAAkB,qCAClB,kBAAmB,sCACnB,wBAAyB,6CACzB,4BAA6B,iDAC7B,iBAAkB,qCAClB,eAAgB,mCAChB,qBAAsB,0CACtB,gBAAiB,qCACjB,0BAA2B,8CAC7B,EAsBA,SAAgB,EAA2B,EAAuC,CAAC,EAAyB,CAC1G,IAAM,GAAA,EAA2BA,EAAAA,oBAAAA,CAAoB,CACnD,YAAa,mBACb,YAAa,gCACb,IAAK,EAAQ,IACb,cAAe,EAAQ,cACvB,IAAK,EAAQ,IACb,iBAAkB,EAAQ,iBAC1B,KAAM,EAAQ,KACd,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,MAAO,CACL,aAAc,EAAO,EAAO,IAAe,EAAU,YAAY,EAAO,EAAO,CAAU,EACzF,eAAgB,EAAO,EAAO,IAAe,EAAU,cAAc,EAAO,EAAO,CAAU,EAC7F,aAAc,EAAO,IAAe,EAAU,YAAY,EAAO,CAAU,EAC3E,WAAY,EAAM,EAAY,IAAa,EAAU,UAAU,EAAM,EAAY,CAAQ,EACzF,UAAa,EAAU,MAAM,EAC7B,aAAgB,EAAU,SAAS,CACrC,CACF"}
@@ -10,6 +10,7 @@ export declare const AUTOCOMPACT_EVENT: {
10
10
  readonly contextCommitted: 'doom_autocompact.context_committed';
11
11
  readonly contextApplied: 'doom_autocompact.context_applied';
12
12
  readonly contextMarkerInvalid: 'doom_autocompact.context_marker_invalid';
13
+ readonly contextHookSlow: 'doom_autocompact.context_hook_slow';
13
14
  readonly nativeCompactionCompleted: 'doom_autocompact.native_compaction_completed';
14
15
  };
15
16
  export type AutocompactEventName = (typeof AUTOCOMPACT_EVENT)[keyof typeof AUTOCOMPACT_EVENT];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/autocompactTelemetry/index.ts"],"mappings":";;qBAKa;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;YAGU,+BAA+B,gCAAgC;YAC/D,6BAA6B;iBAUxB;EACf,YAAY,OAAO,sBAAsB,gBAAgB,aAAa,6BAA6B;EACnG,cAAc,OAAO,sBAAsB,gBAAgB,aAAa,6BAA6B;EACrG,YAAY,OAAO,sBAAsB,aAAa,6BAA6B;EACnF,UAAU,GAAG,cAAc,YAAY,4BAA4B,gBAAgB,QAAQ,KAAK,QAAQ;EACxG,SAAS;EACT,YAAY"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/autocompactTelemetry/index.ts"],"mappings":";;qBAKa;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;YAGU,+BAA+B,gCAAgC;YAC/D,6BAA6B;iBAUxB;EACf,YAAY,OAAO,sBAAsB,gBAAgB,aAAa,6BAA6B;EACnG,cAAc,OAAO,sBAAsB,gBAAgB,aAAa,6BAA6B;EACrG,YAAY,OAAO,sBAAsB,aAAa,6BAA6B;EACnF,UAAU,GAAG,cAAc,YAAY,4BAA4B,gBAAgB,QAAQ,KAAK,QAAQ;EACxG,SAAS;EACT,YAAY"}
@@ -10,6 +10,7 @@ export declare const AUTOCOMPACT_EVENT: {
10
10
  readonly contextCommitted: 'doom_autocompact.context_committed';
11
11
  readonly contextApplied: 'doom_autocompact.context_applied';
12
12
  readonly contextMarkerInvalid: 'doom_autocompact.context_marker_invalid';
13
+ readonly contextHookSlow: 'doom_autocompact.context_hook_slow';
13
14
  readonly nativeCompactionCompleted: 'doom_autocompact.native_compaction_completed';
14
15
  };
15
16
  export type AutocompactEventName = (typeof AUTOCOMPACT_EVENT)[keyof typeof AUTOCOMPACT_EVENT];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/autocompactTelemetry/index.ts"],"mappings":";;qBAKa;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;YAGU,+BAA+B,gCAAgC;YAC/D,6BAA6B;iBAUxB;EACf,YAAY,OAAO,sBAAsB,gBAAgB,aAAa,6BAA6B;EACnG,cAAc,OAAO,sBAAsB,gBAAgB,aAAa,6BAA6B;EACrG,YAAY,OAAO,sBAAsB,aAAa,6BAA6B;EACnF,UAAU,GAAG,cAAc,YAAY,4BAA4B,gBAAgB,QAAQ,KAAK,QAAQ;EACxG,SAAS;EACT,YAAY"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/autocompactTelemetry/index.ts"],"mappings":";;qBAKa;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;YAGU,+BAA+B,gCAAgC;YAC/D,6BAA6B;iBAUxB;EACf,YAAY,OAAO,sBAAsB,gBAAgB,aAAa,6BAA6B;EACnG,cAAc,OAAO,sBAAsB,gBAAgB,aAAa,6BAA6B;EACrG,YAAY,OAAO,sBAAsB,aAAa,6BAA6B;EACnF,UAAU,GAAG,cAAc,YAAY,4BAA4B,gBAAgB,QAAQ,KAAK,QAAQ;EACxG,SAAS;EACT,YAAY"}
@@ -1,2 +1,2 @@
1
- import{createDoomTelemetry as e}from"@agimon-ai/doompi-telemetry";const t={checkpointStarted:`doom_autocompact.checkpoint_started`,checkpointCompleted:`doom_autocompact.checkpoint_completed`,checkpointFailed:`doom_autocompact.checkpoint_failed`,checkpointInvalid:`doom_autocompact.checkpoint_invalid`,configurationLoadFailed:`doom_autocompact.configuration_load_failed`,contextContributionDegraded:`doom_autocompact.context_contribution_degraded`,contextCommitted:`doom_autocompact.context_committed`,contextApplied:`doom_autocompact.context_applied`,contextMarkerInvalid:`doom_autocompact.context_marker_invalid`,nativeCompactionCompleted:`doom_autocompact.native_compaction_completed`};function n(t={}){let n=e({serviceName:`doom-autocompact`,packageName:`@agimon-ai/doompi-autocompact`,cwd:t.cwd,workspaceRoot:t.workspaceRoot,env:t.env,telemetryFactory:t.telemetryFactory,warn:t.warn,enableLogs:!0,enableTraces:!0});return{recordError:(e,t,r)=>n.recordError(e,t,r),recordWarning:(e,t,r)=>n.recordWarning(e,t,r),recordEvent:(e,t)=>n.recordEvent(e,t),runInSpan:(e,t,r)=>n.runInSpan(e,t,r),flush:()=>n.flush(),shutdown:()=>n.shutdown()}}export{t as AUTOCOMPACT_EVENT,n as createAutocompactTelemetry};
1
+ import{createDoomTelemetry as e}from"@agimon-ai/doompi-telemetry";const t={checkpointStarted:`doom_autocompact.checkpoint_started`,checkpointCompleted:`doom_autocompact.checkpoint_completed`,checkpointFailed:`doom_autocompact.checkpoint_failed`,checkpointInvalid:`doom_autocompact.checkpoint_invalid`,configurationLoadFailed:`doom_autocompact.configuration_load_failed`,contextContributionDegraded:`doom_autocompact.context_contribution_degraded`,contextCommitted:`doom_autocompact.context_committed`,contextApplied:`doom_autocompact.context_applied`,contextMarkerInvalid:`doom_autocompact.context_marker_invalid`,contextHookSlow:`doom_autocompact.context_hook_slow`,nativeCompactionCompleted:`doom_autocompact.native_compaction_completed`};function n(t={}){let n=e({serviceName:`doom-autocompact`,packageName:`@agimon-ai/doompi-autocompact`,cwd:t.cwd,workspaceRoot:t.workspaceRoot,env:t.env,telemetryFactory:t.telemetryFactory,warn:t.warn,enableLogs:!0,enableTraces:!0});return{recordError:(e,t,r)=>n.recordError(e,t,r),recordWarning:(e,t,r)=>n.recordWarning(e,t,r),recordEvent:(e,t)=>n.recordEvent(e,t),runInSpan:(e,t,r)=>n.runInSpan(e,t,r),flush:()=>n.flush(),shutdown:()=>n.shutdown()}}export{t as AUTOCOMPACT_EVENT,n as createAutocompactTelemetry};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/autocompactTelemetry/index.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-autocompact';\nconst PACKAGE_NAME = '@agimon-ai/doompi-autocompact';\n\nexport const AUTOCOMPACT_EVENT = {\n checkpointStarted: 'doom_autocompact.checkpoint_started',\n checkpointCompleted: 'doom_autocompact.checkpoint_completed',\n checkpointFailed: 'doom_autocompact.checkpoint_failed',\n checkpointInvalid: 'doom_autocompact.checkpoint_invalid',\n configurationLoadFailed: 'doom_autocompact.configuration_load_failed',\n contextContributionDegraded: 'doom_autocompact.context_contribution_degraded',\n contextCommitted: 'doom_autocompact.context_committed',\n contextApplied: 'doom_autocompact.context_applied',\n contextMarkerInvalid: 'doom_autocompact.context_marker_invalid',\n nativeCompactionCompleted: 'doom_autocompact.native_compaction_completed',\n} as const;\n\nexport type AutocompactEventName = (typeof AUTOCOMPACT_EVENT)[keyof typeof AUTOCOMPACT_EVENT];\nexport type AutocompactEventAttributes = Record<string, string | number | boolean>;\n\nexport interface AutocompactTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface AutocompactTelemetry {\n recordError(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordWarning(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordEvent(event: AutocompactEventName, attributes?: AutocompactEventAttributes): Promise<void>;\n runInSpan<T>(name: string, attributes: AutocompactEventAttributes, callback: () => Promise<T>): Promise<T>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createAutocompactTelemetry(options: AutocompactTelemetryOptions = {}): AutocompactTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n runInSpan: (name, attributes, callback) => telemetry.runInSpan(name, attributes, callback),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"kEAEA,MAGa,EAAoB,CAC/B,kBAAmB,sCACnB,oBAAqB,wCACrB,iBAAkB,qCAClB,kBAAmB,sCACnB,wBAAyB,6CACzB,4BAA6B,iDAC7B,iBAAkB,qCAClB,eAAgB,mCAChB,qBAAsB,0CACtB,0BAA2B,8CAC7B,EAsBA,SAAgB,EAA2B,EAAuC,CAAC,EAAyB,CAC1G,IAAM,EAA2B,EAAoB,CACnD,YAAa,mBACb,YAAa,gCACb,IAAK,EAAQ,IACb,cAAe,EAAQ,cACvB,IAAK,EAAQ,IACb,iBAAkB,EAAQ,iBAC1B,KAAM,EAAQ,KACd,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,MAAO,CACL,aAAc,EAAO,EAAO,IAAe,EAAU,YAAY,EAAO,EAAO,CAAU,EACzF,eAAgB,EAAO,EAAO,IAAe,EAAU,cAAc,EAAO,EAAO,CAAU,EAC7F,aAAc,EAAO,IAAe,EAAU,YAAY,EAAO,CAAU,EAC3E,WAAY,EAAM,EAAY,IAAa,EAAU,UAAU,EAAM,EAAY,CAAQ,EACzF,UAAa,EAAU,MAAM,EAC7B,aAAgB,EAAU,SAAS,CACrC,CACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/autocompactTelemetry/index.ts"],"sourcesContent":["import { createDoomTelemetry, type DoomTelemetry, type DoomTelemetryOptions } from '@agimon-ai/doompi-telemetry';\n\nconst SERVICE_NAME = 'doom-autocompact';\nconst PACKAGE_NAME = '@agimon-ai/doompi-autocompact';\n\nexport const AUTOCOMPACT_EVENT = {\n checkpointStarted: 'doom_autocompact.checkpoint_started',\n checkpointCompleted: 'doom_autocompact.checkpoint_completed',\n checkpointFailed: 'doom_autocompact.checkpoint_failed',\n checkpointInvalid: 'doom_autocompact.checkpoint_invalid',\n configurationLoadFailed: 'doom_autocompact.configuration_load_failed',\n contextContributionDegraded: 'doom_autocompact.context_contribution_degraded',\n contextCommitted: 'doom_autocompact.context_committed',\n contextApplied: 'doom_autocompact.context_applied',\n contextMarkerInvalid: 'doom_autocompact.context_marker_invalid',\n contextHookSlow: 'doom_autocompact.context_hook_slow',\n nativeCompactionCompleted: 'doom_autocompact.native_compaction_completed',\n} as const;\n\nexport type AutocompactEventName = (typeof AUTOCOMPACT_EVENT)[keyof typeof AUTOCOMPACT_EVENT];\nexport type AutocompactEventAttributes = Record<string, string | number | boolean>;\n\nexport interface AutocompactTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<DoomTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n}\n\nexport interface AutocompactTelemetry {\n recordError(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordWarning(event: AutocompactEventName, error: unknown, attributes?: AutocompactEventAttributes): Promise<void>;\n recordEvent(event: AutocompactEventName, attributes?: AutocompactEventAttributes): Promise<void>;\n runInSpan<T>(name: string, attributes: AutocompactEventAttributes, callback: () => Promise<T>): Promise<T>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createAutocompactTelemetry(options: AutocompactTelemetryOptions = {}): AutocompactTelemetry {\n const telemetry: DoomTelemetry = createDoomTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n return {\n recordError: (event, error, attributes) => telemetry.recordError(event, error, attributes),\n recordWarning: (event, error, attributes) => telemetry.recordWarning(event, error, attributes),\n recordEvent: (event, attributes) => telemetry.recordEvent(event, attributes),\n runInSpan: (name, attributes, callback) => telemetry.runInSpan(name, attributes, callback),\n flush: () => telemetry.flush(),\n shutdown: () => telemetry.shutdown(),\n };\n}\n"],"mappings":"kEAEA,MAGa,EAAoB,CAC/B,kBAAmB,sCACnB,oBAAqB,wCACrB,iBAAkB,qCAClB,kBAAmB,sCACnB,wBAAyB,6CACzB,4BAA6B,iDAC7B,iBAAkB,qCAClB,eAAgB,mCAChB,qBAAsB,0CACtB,gBAAiB,qCACjB,0BAA2B,8CAC7B,EAsBA,SAAgB,EAA2B,EAAuC,CAAC,EAAyB,CAC1G,IAAM,EAA2B,EAAoB,CACnD,YAAa,mBACb,YAAa,gCACb,IAAK,EAAQ,IACb,cAAe,EAAQ,cACvB,IAAK,EAAQ,IACb,iBAAkB,EAAQ,iBAC1B,KAAM,EAAQ,KACd,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,MAAO,CACL,aAAc,EAAO,EAAO,IAAe,EAAU,YAAY,EAAO,EAAO,CAAU,EACzF,eAAgB,EAAO,EAAO,IAAe,EAAU,cAAc,EAAO,EAAO,CAAU,EAC7F,aAAc,EAAO,IAAe,EAAU,YAAY,EAAO,CAAU,EAC3E,WAAY,EAAM,EAAY,IAAa,EAAU,UAAU,EAAM,EAAY,CAAQ,EACzF,UAAa,EAAU,MAAM,EAC7B,aAAgB,EAAU,SAAS,CACrC,CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/doompi-autocompact",
3
- "version": "0.0.1-alpha.70",
3
+ "version": "0.0.1-alpha.71",
4
4
  "description": "Iterative context compaction and checkpoint summaries for Pi and DoomPi agent sessions.",
5
5
  "keywords": [
6
6
  "ai",
@@ -58,15 +58,15 @@
58
58
  "access": "public"
59
59
  },
60
60
  "dependencies": {
61
+ "@agimon-ai/doompi-config": "0.0.1-alpha.71",
62
+ "@agimon-ai/doompi-core": "0.0.1-alpha.72",
63
+ "@agimon-ai/doompi-telemetry": "0.0.1-alpha.69",
61
64
  "@deepseek-ai/cordis": "4.0.2",
62
- "minimatch": "10.2.6",
63
- "@agimon-ai/doompi-config": "0.0.1-alpha.70",
64
- "@agimon-ai/doompi-core": "0.0.1-alpha.71",
65
- "@agimon-ai/doompi-telemetry": "0.0.1-alpha.68"
65
+ "minimatch": "10.2.6"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@earendil-works/pi-coding-agent": "0.85.1",
69
- "@types/node": "26.4.1",
69
+ "@types/node": "26.5.1",
70
70
  "@vitest/coverage-v8": "5.0.0",
71
71
  "typescript": "7.0.2",
72
72
  "vitest": "5.0.0"