@caupulican/pi-agent-core 0.93.16 → 0.93.18

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.
@@ -4,8 +4,8 @@
4
4
  * Pure functions for compaction logic. The session manager handles I/O,
5
5
  * and after compaction the session is reloaded.
6
6
  */
7
- import type { AssistantMessage, Context, Model, SimpleStreamOptions, Usage } from "@caupulican/pi-ai/types";
8
- import { type SessionEntry } from "../session/session-manager.ts";
7
+ import type { AssistantMessage, CacheRetention, Context, Model, SimpleStreamOptions, Usage } from "@caupulican/pi-ai/types";
8
+ import { type CompactionRetention, type SessionEntry } from "../session/session-manager.ts";
9
9
  import type { AgentMessage, StreamFn, ThinkingLevel } from "../types.ts";
10
10
  import { type CompactionFacts } from "./extraction.ts";
11
11
  import { type FileOperations } from "./utils.ts";
@@ -33,6 +33,8 @@ export interface CompactionResult<T = unknown> {
33
33
  summary: string;
34
34
  firstKeptEntryId: string;
35
35
  tokensBefore: number;
36
+ /** Sparse history retained when compaction atomically replaces the provider-visible session. */
37
+ retention?: CompactionRetention;
36
38
  /** Provider usage spent generating this checkpoint, including chunk and verification retries. */
37
39
  usage?: Usage;
38
40
  /** Extension-specific data (e.g., ArtifactIndex, version markers for structured compaction) */
@@ -43,6 +45,17 @@ export interface CompactionResult<T = unknown> {
43
45
  }
44
46
  /** Host-owned provider boundary for shared compaction request enforcement and accounting. */
45
47
  export type CompactionCompletion = (model: Model<any>, context: Context, options: SimpleStreamOptions) => Promise<AssistantMessage>;
48
+ /** Existing provider-visible prefix reused by a session-replacement summary request. */
49
+ export interface StructuredCompactionRequest {
50
+ context: Context;
51
+ sessionId: string;
52
+ cacheRetention: Exclude<CacheRetention, "none">;
53
+ }
54
+ export interface CompactionExecutionOptions {
55
+ chunked?: boolean;
56
+ completion?: CompactionCompletion;
57
+ structuredRequest?: StructuredCompactionRequest;
58
+ }
46
59
  /**
47
60
  * Carry failed LLM verification attempts into the result that the retry ladder eventually applies.
48
61
  * Only bounded numeric/check identifiers are persisted in details; raw facts stay in the in-memory reports.
@@ -60,6 +73,8 @@ export interface CompactionSettings {
60
73
  * reserve-based behavior while large windows compact earlier. `0`/`1`+ disables the fractional cap.
61
74
  */
62
75
  triggerPercent?: number;
76
+ /** Provider-neutral request/history strategy selected by the host adapter. */
77
+ strategy?: "session-replacement";
63
78
  }
64
79
  export declare const DEFAULT_COMPACTION_SETTINGS: CompactionSettings;
65
80
  /**
@@ -161,8 +176,8 @@ export declare function findCutPoint(entries: SessionEntry[], startIndex: number
161
176
  * the same message span across multiple attempts (a verification-gate retry), compute this once
162
177
  * via {@link prepareSummarizationConversationText} and pass it to every attempt.
163
178
  */
164
- export declare function generateSummary(currentMessages: AgentMessage[], model: Model<any>, reserveTokens: number, apiKey: string | undefined, headers?: Record<string, string>, signal?: AbortSignal, customInstructions?: string, previousSummary?: string, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn, preDigest?: (conversationText: string, signal?: AbortSignal) => Promise<string>, factsBlock?: string, chunked?: boolean, precomputedConversationText?: string, completion?: CompactionCompletion): Promise<string>;
165
- export declare function generateSummaryWithUsage(currentMessages: AgentMessage[], model: Model<any>, reserveTokens: number, apiKey: string | undefined, headers?: Record<string, string>, signal?: AbortSignal, customInstructions?: string, previousSummary?: string, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn, preDigest?: (conversationText: string, signal?: AbortSignal) => Promise<string>, factsBlock?: string, chunked?: boolean, precomputedConversationText?: string, completion?: CompactionCompletion): Promise<{
179
+ export declare function generateSummary(currentMessages: AgentMessage[], model: Model<any>, reserveTokens: number, apiKey: string | undefined, headers?: Record<string, string>, signal?: AbortSignal, customInstructions?: string, previousSummary?: string, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn, preDigest?: (conversationText: string, signal?: AbortSignal) => Promise<string>, factsBlock?: string, chunked?: boolean, precomputedConversationText?: string, completion?: CompactionCompletion, structuredRequest?: StructuredCompactionRequest): Promise<string>;
180
+ export declare function generateSummaryWithUsage(currentMessages: AgentMessage[], model: Model<any>, reserveTokens: number, apiKey: string | undefined, headers?: Record<string, string>, signal?: AbortSignal, customInstructions?: string, previousSummary?: string, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn, preDigest?: (conversationText: string, signal?: AbortSignal) => Promise<string>, factsBlock?: string, chunked?: boolean, precomputedConversationText?: string, completion?: CompactionCompletion, structuredRequest?: StructuredCompactionRequest): Promise<{
166
181
  text: string;
167
182
  usage: Usage;
168
183
  }>;
@@ -191,6 +206,8 @@ export interface CompactionPreparation {
191
206
  tokensBefore: number;
192
207
  /** Summary from previous compaction, for iterative update */
193
208
  previousSummary?: string;
209
+ /** Sparse history contract persisted with a session-replacement checkpoint. */
210
+ retention?: CompactionRetention;
194
211
  /** File operations extracted from messagesToSummarize */
195
212
  fileOps: FileOperations;
196
213
  /** Facts extracted from the compacted span for verification gating */
@@ -208,9 +225,6 @@ export declare function prepareCompaction(pathEntries: SessionEntry[], settings:
208
225
  * @param preparation - Pre-calculated preparation from prepareCompaction()
209
226
  * @param customInstructions - Optional custom focus for the summary
210
227
  */
211
- export declare function compact(preparation: CompactionPreparation, model: Model<any>, apiKey: string | undefined, headers?: Record<string, string>, customInstructions?: string, signal?: AbortSignal, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn, preDigest?: (conversationText: string, signal?: AbortSignal) => Promise<string>, executionOptions?: {
212
- chunked?: boolean;
213
- completion?: CompactionCompletion;
214
- }): Promise<CompactionResult>;
228
+ export declare function compact(preparation: CompactionPreparation, model: Model<any>, apiKey: string | undefined, headers?: Record<string, string>, customInstructions?: string, signal?: AbortSignal, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn, preDigest?: (conversationText: string, signal?: AbortSignal) => Promise<string>, executionOptions?: CompactionExecutionOptions): Promise<CompactionResult>;
215
229
  export declare function createDeterministicCompaction(preparation: CompactionPreparation): CompactionResult;
216
230
  //# sourceMappingURL=compaction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../src/compaction/compaction.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAS5G,OAAO,EAA6C,KAAK,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7G,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,EAEN,KAAK,eAAe,EAIpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAKN,KAAK,cAAc,EAMnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAKN,KAAK,kBAAkB,EAEvB,MAAM,mBAAmB,CAAC;AAM3B,kEAAkE;AAClE,MAAM,WAAW,gCAAgC;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAC;IAC1E,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC/B;AA0ED,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,OAAO;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,iGAAiG;IACjG,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,+FAA+F;IAC/F,OAAO,CAAC,EAAE,CAAC,CAAC;IACZ,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,wBAAwB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAChD,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,6FAA6F;AAC7F,MAAM,MAAM,oBAAoB,GAAG,CAClC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,mBAAmB,KACxB,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B;;;GAGG;AACH,wBAAgB,kCAAkC,CACjD,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,SAAS,kBAAkB,EAAE,GACpC,gBAAgB,CAmBlB;AAmCD,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,2BAA2B,EAAE,kBAKzC,CAAC;AAMF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAE3D;AAgBD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,GAAG,SAAS,CAShF;AAED,MAAM,WAAW,oBAAoB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,SAAS,YAAY,EAAE,GAC/B;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAc7C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,oBAAoB,CA4B7F;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvD,oGAAoG;AACpG,wBAAgB,oBAAoB,CACnC,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,kBAAkB,EAC5B,aAAa,CAAC,EAAE,MAAM,GACpB,cAAc,CAmBhB;AAED,wBAAgB,aAAa,CAC5B,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,kBAAkB,EAC5B,aAAa,CAAC,EAAE,MAAM,GACpB,OAAO,CAET;AAsBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAwC5D;AAiDD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAe1G;AAED,MAAM,WAAW,cAAc;IAC9B,mCAAmC;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,cAAc,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,WAAW,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC3B,OAAO,EAAE,YAAY,EAAE,EACvB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,GACtB,cAAc,CAyDhB;AA4GD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACpC,eAAe,EAAE,YAAY,EAAE,EAC/B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,MAAM,CAAC,EAAE,WAAW,EACpB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,eAAe,CAAC,EAAE,MAAM,EACxB,aAAa,CAAC,EAAE,aAAa,EAC7B,QAAQ,CAAC,EAAE,QAAQ,EACnB,SAAS,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,EAC/E,UAAU,SAA6f,EACvgB,OAAO,UAAQ,EACf,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,oBAAoB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAED,wBAAsB,wBAAwB,CAC7C,eAAe,EAAE,YAAY,EAAE,EAC/B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,MAAM,CAAC,EAAE,WAAW,EACpB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,eAAe,CAAC,EAAE,MAAM,EACxB,aAAa,CAAC,EAAE,aAAa,EAC7B,QAAQ,CAAC,EAAE,QAAQ,EACnB,SAAS,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,EAC/E,UAAU,SAA6f,EACvgB,OAAO,UAAQ,EACf,2BAA2B,CAAC,EAAE,MAAM,EACpC,UAAU,CAAC,EAAE,oBAAoB,GAC/B,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,CAiEzC;AAOD,qGAAqG;AACrG,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAkC/C;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAI5F;AAgBD,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjG;AAsID,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAMD,MAAM,WAAW,qBAAqB;IACrC,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,mBAAmB,EAAE,YAAY,EAAE,CAAC;IACpC,2EAA2E;IAC3E,kBAAkB,EAAE,YAAY,EAAE,CAAC;IACnC,iEAAiE;IACjE,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,OAAO,EAAE,cAAc,CAAC;IACxB,sEAAsE;IACtE,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,8CAA8C;IAC9C,QAAQ,EAAE,kBAAkB,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAChC,WAAW,EAAE,YAAY,EAAE,EAC3B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE;IAAE,iCAAiC,CAAC,EAAE,OAAO,CAAA;CAAE,GACvD,qBAAqB,GAAG,SAAS,CAuFnC;AAuFD;;;;;;GAMG;AACH,wBAAsB,OAAO,CAC5B,WAAW,EAAE,qBAAqB,EAClC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,kBAAkB,CAAC,EAAE,MAAM,EAC3B,MAAM,CAAC,EAAE,WAAW,EACpB,aAAa,CAAC,EAAE,aAAa,EAC7B,QAAQ,CAAC,EAAE,QAAQ,EACnB,SAAS,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,EAC/E,gBAAgB,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,oBAAoB,CAAA;CAAE,GACzE,OAAO,CAAC,gBAAgB,CAAC,CA0E3B;AAED,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,qBAAqB,GAAG,gBAAgB,CAqFlG"}
1
+ {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../src/compaction/compaction.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,8 @@
7
7
  import { completeSimple } from "@caupulican/pi-ai/stream";
8
8
  import { uuidv7 } from "@caupulican/pi-ai/uuid";
9
9
  import { convertToLlm, createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "../messages.js";
10
- import { ESTIMATED_IMAGE_CHARS } from "../provider-request-estimator.js";
11
- import { buildSessionContext } from "../session/session-manager.js";
10
+ import { ESTIMATED_IMAGE_CHARS, estimateProviderRequestTokens } from "../provider-request-estimator.js";
11
+ import { buildSessionContext, } from "../session/session-manager.js";
12
12
  import { addUsage, createEmptyUsage } from "../usage.js";
13
13
  import { ACTIVE_TASK_SOURCE_MAX_CHARS, extractCompactionFacts, mergePersistentCompactionUserFacts, renderFactsBlock, } from "./extraction.js";
14
14
  import { addPersistedFileOperations, computeFileLists, createFileOps, extractFileOpsFromMessage, isPlainRecord, SUMMARIZATION_PROMPT, SUMMARIZATION_SYSTEM_PROMPT, serializeConversation, UPDATE_SUMMARIZATION_PROMPT, } from "./utils.js";
@@ -445,22 +445,39 @@ export function findCutPoint(entries, startIndex, endIndex, keepRecentTokens) {
445
445
  // ============================================================================
446
446
  // Summarization
447
447
  // ============================================================================
448
- function createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel) {
449
- // Summaries are one-shot prompts. A fresh affinity identity prevents them from contaminating the
450
- // foreground continuation cache, while "none" prevents cache writes that cannot be reused.
448
+ function createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel, affinity) {
449
+ // Standalone summaries are isolated one-shot prompts. A session-replacement request deliberately
450
+ // reuses the live affinity so the provider can reuse and validate the exact structured prefix.
451
451
  const options = {
452
452
  maxTokens,
453
453
  signal,
454
454
  apiKey,
455
455
  headers,
456
- cacheRetention: "none",
457
- sessionId: uuidv7(),
456
+ cacheRetention: affinity?.cacheRetention ?? "none",
457
+ sessionId: affinity?.sessionId ?? uuidv7(),
458
458
  };
459
459
  if (model.reasoning && thinkingLevel && thinkingLevel !== "off") {
460
460
  options.reasoning = thinkingLevel;
461
461
  }
462
462
  return options;
463
463
  }
464
+ const STRUCTURED_SUMMARIZATION_CONTROL = `Create a replacement checkpoint for the conversation above.
465
+ The preceding messages are source history; this final temporary message is control data and must not appear in the checkpoint.
466
+ Do not continue the task and do not call tools. Return only the checkpoint.
467
+ Preserve the owner's exact active request and prohibitions, durable decisions, paths, commands, errors, completed work, pending work, and immediate next step. Never include secrets, credentials, or tokens; write [REDACTED].`;
468
+ function buildStructuredSummarizationContext(promptText, request) {
469
+ return {
470
+ ...request.context,
471
+ messages: [
472
+ ...request.context.messages,
473
+ {
474
+ role: "user",
475
+ content: [{ type: "text", text: `${STRUCTURED_SUMMARIZATION_CONTROL}\n\n${promptText}` }],
476
+ timestamp: Date.now(),
477
+ },
478
+ ],
479
+ };
480
+ }
464
481
  async function completeSummarization(model, context, options, streamFn, completion) {
465
482
  if (completion)
466
483
  return completion(model, context, options);
@@ -470,6 +487,14 @@ async function completeSummarization(model, context, options, streamFn, completi
470
487
  const stream = await streamFn(model, context, options);
471
488
  return stream.result();
472
489
  }
490
+ function accountAndValidateSummarization(response, usage, failureLabel) {
491
+ if (usage)
492
+ addUsage(usage, response.usage);
493
+ if (response.stopReason === "error") {
494
+ throw new Error(`${failureLabel} failed: ${response.errorMessage || "Unknown error"}`);
495
+ }
496
+ return response;
497
+ }
473
498
  async function completeSummarizationPrompt(promptText, model, maxTokens, apiKey, headers, signal, thinkingLevel, streamFn, completion, usage, failureLabel = "Summarization") {
474
499
  const response = await completeSummarization(model, {
475
500
  systemPrompt: SUMMARIZATION_SYSTEM_PROMPT,
@@ -481,12 +506,19 @@ async function completeSummarizationPrompt(promptText, model, maxTokens, apiKey,
481
506
  },
482
507
  ],
483
508
  }, createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel), streamFn, completion);
484
- if (usage)
485
- addUsage(usage, response.usage);
486
- if (response.stopReason === "error") {
487
- throw new Error(`${failureLabel} failed: ${response.errorMessage || "Unknown error"}`);
509
+ return accountAndValidateSummarization(response, usage, failureLabel);
510
+ }
511
+ async function completeStructuredSummarizationPrompt(context, request, model, maxTokens, apiKey, headers, signal, thinkingLevel, streamFn, completion, usage) {
512
+ const response = await completeSummarization(model, context, createSummarizationOptions(model, maxTokens, apiKey, headers, signal, thinkingLevel, request), streamFn, completion);
513
+ return accountAndValidateSummarization(response, usage, "Summarization");
514
+ }
515
+ function finalizeSummaryResponse(response, summaryBudget, usage) {
516
+ // A length-stopped checkpoint silently lost its tail sections — gating it as if complete
517
+ // guarantees a verification failure. Fail loudly so the compaction ladder escalates instead.
518
+ if (response.stopReason === "length") {
519
+ throw new Error("summary-length-stop: summarizer hit its output cap before completing the checkpoint");
488
520
  }
489
- return response;
521
+ return { text: truncateSummaryToBudget(extractTextContent(response), summaryBudget), usage };
490
522
  }
491
523
  /**
492
524
  * Serialize messages to conversation text and, if a `preDigest` callback is supplied, run it
@@ -520,10 +552,10 @@ async function prepareSummarizationConversationText(currentMessages, preDigest,
520
552
  * the same message span across multiple attempts (a verification-gate retry), compute this once
521
553
  * via {@link prepareSummarizationConversationText} and pass it to every attempt.
522
554
  */
523
- export async function generateSummary(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, preDigest, factsBlock = "verification demands:\nfiles-modified-recall (must appear in ## Files):\nfiles-read-recall (must appear as exact paths in ## Files, path recall threshold applies):\nworking-set-recall (must appear in ## Working Set):\nopen-errors-recall (must appear in ## Open Problems):\nactions-recall (must appear in ## Done):\nmandatory-rules-recall (must appear in ### Mandatory Rules):\nactive-task-containment (must appear in ## Active Task):\ncancelled-work-dropped (must NOT appear outside ### Mandatory Rules):", chunked = false, precomputedConversationText, completion) {
524
- return (await generateSummaryWithUsage(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, preDigest, factsBlock, chunked, precomputedConversationText, completion)).text;
555
+ export async function generateSummary(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, preDigest, factsBlock = "verification demands:\nfiles-modified-recall (must appear in ## Files):\nfiles-read-recall (must appear as exact paths in ## Files, path recall threshold applies):\nworking-set-recall (must appear in ## Working Set):\nopen-errors-recall (must appear in ## Open Problems):\nactions-recall (must appear in ## Done):\nmandatory-rules-recall (must appear in ### Mandatory Rules):\nactive-task-containment (must appear in ## Active Task):\ncancelled-work-dropped (must NOT appear outside ### Mandatory Rules):", chunked = false, precomputedConversationText, completion, structuredRequest) {
556
+ return (await generateSummaryWithUsage(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, preDigest, factsBlock, chunked, precomputedConversationText, completion, structuredRequest)).text;
525
557
  }
526
- export async function generateSummaryWithUsage(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, preDigest, factsBlock = "verification demands:\nfiles-modified-recall (must appear in ## Files):\nfiles-read-recall (must appear as exact paths in ## Files, path recall threshold applies):\nworking-set-recall (must appear in ## Working Set):\nopen-errors-recall (must appear in ## Open Problems):\nactions-recall (must appear in ## Done):\nmandatory-rules-recall (must appear in ### Mandatory Rules):\nactive-task-containment (must appear in ## Active Task):\ncancelled-work-dropped (must NOT appear outside ### Mandatory Rules):", chunked = false, precomputedConversationText, completion) {
558
+ export async function generateSummaryWithUsage(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, preDigest, factsBlock = "verification demands:\nfiles-modified-recall (must appear in ## Files):\nfiles-read-recall (must appear as exact paths in ## Files, path recall threshold applies):\nworking-set-recall (must appear in ## Working Set):\nopen-errors-recall (must appear in ## Open Problems):\nactions-recall (must appear in ## Done):\nmandatory-rules-recall (must appear in ### Mandatory Rules):\nactive-task-containment (must appear in ## Active Task):\ncancelled-work-dropped (must NOT appear outside ### Mandatory Rules):", chunked = false, precomputedConversationText, completion, structuredRequest) {
527
559
  const usage = createEmptyUsage();
528
560
  const summaryBudget = getSummaryBudget(reserveTokens, model, factsBlock);
529
561
  const maxTokens = summaryBudget;
@@ -531,10 +563,20 @@ export async function generateSummaryWithUsage(currentMessages, model, reserveTo
531
563
  if (customInstructions) {
532
564
  promptSuffix = `${promptSuffix}\n\nAdditional focus: ${customInstructions}`;
533
565
  }
566
+ const inputBound = getSummarizerInputBound(model, maxTokens);
567
+ if (structuredRequest) {
568
+ const structuredContext = buildStructuredSummarizationContext(promptSuffix, structuredRequest);
569
+ if (estimateProviderRequestTokens(structuredContext, model) <= inputBound) {
570
+ const response = await completeStructuredSummarizationPrompt(structuredContext, structuredRequest, model, maxTokens, apiKey, headers, signal, thinkingLevel, streamFn, completion, usage);
571
+ return finalizeSummaryResponse(response, summaryBudget, usage);
572
+ }
573
+ if (!chunked) {
574
+ throw new Error("input-overflow: structured summarization request exceeds summarizer window");
575
+ }
576
+ }
534
577
  let conversationText = precomputedConversationText !== undefined
535
578
  ? precomputedConversationText
536
579
  : await prepareSummarizationConversationText(currentMessages, preDigest, signal);
537
- const inputBound = getSummarizerInputBound(model, maxTokens);
538
580
  const initialPromptText = buildSummarizationPrompt(conversationText, previousSummary, promptSuffix);
539
581
  if (estimateStringTokens(initialPromptText) > inputBound) {
540
582
  if (!chunked) {
@@ -547,12 +589,7 @@ export async function generateSummaryWithUsage(currentMessages, model, reserveTo
547
589
  throw new Error("input-overflow: chunked summarization merge still exceeds summarizer window");
548
590
  }
549
591
  const response = await completeSummarizationPrompt(promptText, model, maxTokens, apiKey, headers, signal, thinkingLevel, streamFn, completion, usage);
550
- // A length-stopped checkpoint silently lost its tail sections — gating it as if complete
551
- // guarantees a verification failure. Fail loudly so the compaction ladder escalates instead.
552
- if (response.stopReason === "length") {
553
- throw new Error("summary-length-stop: summarizer hit its output cap before completing the checkpoint");
554
- }
555
- return { text: truncateSummaryToBudget(extractTextContent(response), summaryBudget), usage };
592
+ return finalizeSummaryResponse(response, summaryBudget, usage);
556
593
  }
557
594
  function fillPromptTemplate(template, factsBlock, budget) {
558
595
  return template.replaceAll("{FACTS_BLOCK}", factsBlock).replaceAll("{BUDGET}", String(budget));
@@ -716,7 +753,34 @@ export function prepareCompaction(pathEntries, settings, options) {
716
753
  const boundaryEnd = options?.allowTrailingCompactionAsPrevious && pathEntries[pathEntries.length - 1]?.type === "compaction"
717
754
  ? pathEntries.length - 1
718
755
  : pathEntries.length;
719
- const tokensBefore = estimateContextTokens(buildSessionContext(pathEntries).messages).tokens;
756
+ const liveMessages = buildSessionContext(pathEntries).messages;
757
+ const tokensBefore = estimateContextTokens(liveMessages).tokens;
758
+ if (settings.strategy === "session-replacement") {
759
+ const previousRetention = prevCompactionIndex >= 0 ? pathEntries[prevCompactionIndex].retention : undefined;
760
+ const originalUserEntry = pathEntries.find((entry) => entry.type === "message" &&
761
+ entry.message.role === "user" &&
762
+ (previousRetention?.mode !== "original-user" || entry.id === previousRetention.userEntryId));
763
+ if (!originalUserEntry?.id)
764
+ return undefined;
765
+ const fileOps = extractFileOperations(liveMessages, pathEntries, prevCompactionIndex);
766
+ const factStart = prevCompactionIndex >= 0 ? prevCompactionIndex + 1 : 0;
767
+ let facts = extractCompactionFacts(pathEntries, factStart, boundaryEnd);
768
+ if (prevCompactionIndex >= 0) {
769
+ const persistedUserFacts = previousUserFacts ?? extractCompactionFacts(pathEntries, 0, boundaryEnd);
770
+ facts = mergePersistentCompactionUserFacts(facts, persistedUserFacts);
771
+ }
772
+ return {
773
+ firstKeptEntryId: originalUserEntry.id,
774
+ messagesToSummarize: liveMessages,
775
+ turnPrefixMessages: [],
776
+ isSplitTurn: false,
777
+ tokensBefore,
778
+ retention: { mode: "original-user", userEntryId: originalUserEntry.id },
779
+ fileOps,
780
+ facts,
781
+ settings,
782
+ };
783
+ }
720
784
  const cutPoint = findCutPoint(pathEntries, boundaryStart, boundaryEnd, settings.keepRecentTokens);
721
785
  // Get UUID of first kept entry
722
786
  const firstKeptEntry = pathEntries[cutPoint.firstKeptEntryIndex];
@@ -772,9 +836,11 @@ async function generateVerifiedSummary(options) {
772
836
  let retryInstructions = options.customInstructions;
773
837
  const usage = createEmptyUsage();
774
838
  const verificationGateFailures = [];
775
- const precomputedConversationText = await prepareSummarizationConversationText(options.messages, options.preDigest, options.signal);
839
+ const precomputedConversationText = options.structuredRequest
840
+ ? undefined
841
+ : await prepareSummarizationConversationText(options.messages, options.preDigest, options.signal);
776
842
  for (let attempt = 0; attempt < 2; attempt++) {
777
- const generated = await generateSummaryWithUsage(options.messages, options.model, options.reserveTokens, options.apiKey, options.headers, options.signal, retryInstructions, options.previousSummary, options.thinkingLevel, options.streamFn, options.preDigest, options.factsBlock, options.chunked, precomputedConversationText, options.completion);
843
+ const generated = await generateSummaryWithUsage(options.messages, options.model, options.reserveTokens, options.apiKey, options.headers, options.signal, retryInstructions, options.previousSummary, options.thinkingLevel, options.streamFn, options.preDigest, options.factsBlock, options.chunked, precomputedConversationText, options.completion, options.structuredRequest);
778
844
  addUsage(usage, generated.usage);
779
845
  const summary = generated.text;
780
846
  const verification = verifySummary(summary, options.facts);
@@ -810,7 +876,7 @@ async function generateVerifiedSummary(options) {
810
876
  * @param customInstructions - Optional custom focus for the summary
811
877
  */
812
878
  export async function compact(preparation, model, apiKey, headers, customInstructions, signal, thinkingLevel, streamFn, preDigest, executionOptions) {
813
- const { firstKeptEntryId, messagesToSummarize, turnPrefixMessages, isSplitTurn, tokensBefore, previousSummary, fileOps, settings, facts: factsFromPreparation, } = preparation;
879
+ const { firstKeptEntryId, messagesToSummarize, turnPrefixMessages, isSplitTurn, tokensBefore, previousSummary, retention, fileOps, settings, facts: factsFromPreparation, } = preparation;
814
880
  const facts = factsFromPreparation ?? {
815
881
  files: [],
816
882
  workingSet: [],
@@ -834,6 +900,7 @@ export async function compact(preparation, model, apiKey, headers, customInstruc
834
900
  thinkingLevel,
835
901
  streamFn,
836
902
  completion: executionOptions?.completion,
903
+ structuredRequest: executionOptions?.structuredRequest,
837
904
  preDigest,
838
905
  facts,
839
906
  factsBlock,
@@ -852,6 +919,7 @@ export async function compact(preparation, model, apiKey, headers, customInstruc
852
919
  summary,
853
920
  firstKeptEntryId,
854
921
  tokensBefore,
922
+ retention,
855
923
  usage: summaryUsage,
856
924
  details: {
857
925
  readFiles,
@@ -867,7 +935,7 @@ export async function compact(preparation, model, apiKey, headers, customInstruc
867
935
  }, verified.verificationGateFailures);
868
936
  }
869
937
  export function createDeterministicCompaction(preparation) {
870
- const { firstKeptEntryId, tokensBefore, fileOps, facts } = preparation;
938
+ const { firstKeptEntryId, tokensBefore, retention, fileOps, facts } = preparation;
871
939
  if (!firstKeptEntryId) {
872
940
  throw new Error("First kept entry has no UUID - session may need migration");
873
941
  }
@@ -935,6 +1003,7 @@ export function createDeterministicCompaction(preparation) {
935
1003
  summary,
936
1004
  firstKeptEntryId,
937
1005
  tokensBefore,
1006
+ retention,
938
1007
  details: {
939
1008
  readFiles,
940
1009
  modifiedFiles,