@linxiraos/pi-agent-core 1.1.26 → 1.2.0

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +6 -243
  2. package/README.md +1 -1
  3. package/dist/types/agent.d.ts +27 -7
  4. package/dist/types/compaction/anthropic.d.ts +14 -8
  5. package/dist/types/compaction/branch-summarization.d.ts +1 -1
  6. package/dist/types/compaction/compaction-v2-streaming.d.ts +5 -1
  7. package/dist/types/compaction/compaction.d.ts +24 -2
  8. package/dist/types/compaction/entries.d.ts +2 -2
  9. package/dist/types/compaction/messages.d.ts +6 -0
  10. package/dist/types/compaction/openai.d.ts +14 -2
  11. package/dist/types/compaction/pruning.d.ts +64 -16
  12. package/dist/types/compaction/tool-protection.d.ts +2 -1
  13. package/dist/types/compaction/utils.d.ts +5 -0
  14. package/dist/types/image-tokens.d.ts +29 -0
  15. package/dist/types/index.d.ts +1 -0
  16. package/dist/types/speculative-execution.d.ts +1 -1
  17. package/dist/types/telemetry.d.ts +70 -60
  18. package/dist/types/tokenizer.d.ts +9 -6
  19. package/dist/types/tool-arguments.d.ts +19 -0
  20. package/dist/types/types.d.ts +12 -1
  21. package/package.json +8 -8
  22. package/src/agent-loop.ts +191 -34
  23. package/src/agent.ts +126 -21
  24. package/src/append-only-context.ts +38 -29
  25. package/src/compaction/anthropic.ts +30 -12
  26. package/src/compaction/branch-summarization.ts +1 -1
  27. package/src/compaction/compaction-v2-streaming.ts +23 -16
  28. package/src/compaction/compaction.ts +163 -73
  29. package/src/compaction/entries.ts +2 -2
  30. package/src/compaction/message-cache.ts +1 -1
  31. package/src/compaction/messages.ts +25 -0
  32. package/src/compaction/openai.ts +65 -28
  33. package/src/compaction/pruning.ts +328 -96
  34. package/src/compaction/tool-protection.ts +8 -2
  35. package/src/compaction/utils.ts +9 -0
  36. package/src/image-tokens.ts +77 -0
  37. package/src/index.ts +2 -0
  38. package/src/prompts/dsml-tool-call-leak.md +19 -0
  39. package/src/speculative-execution.ts +5 -9
  40. package/src/telemetry.ts +100 -81
  41. package/src/tokenizer.ts +24 -17
  42. package/src/tool-arguments.ts +38 -0
  43. package/src/types.ts +12 -1
package/CHANGELOG.md CHANGED
@@ -1,249 +1,8 @@
1
- # Changelog
2
-
3
1
  ## [Unreleased]
4
2
 
5
- ## [1.1.26] - 2026-10-03
6
-
7
- - 版本线推进至 1.1.26;本版无独立用户可见变化。
8
-
9
- ## [14.9.5] - 2026-05-12
10
-
11
- ### Added
12
-
13
- - Added an `isError?: boolean` field on `AgentToolResult` so tools can flag a non-throwing failure (e.g. an aggregator that catches per-entry errors). `coerceToolResult` preserves the flag and the agent loop surfaces it as a tool error on the wire.
14
-
15
- ## [14.9.3] - 2026-05-10
16
-
17
- ### Added
18
-
19
- - Added `onHarmonyLeak` option on `Agent`/loop config to receive GPT-5 Harmony leak audit callbacks
20
- - Added harmony-leak detection and audit exports to the package index for programmatic leak detection and recovery hooks
21
-
22
- ### Changed
23
-
24
- - Changed OpenAI Codex model runs to detect GPT-5 Harmony protocol leakage during streaming and automatically retry or recover tool calls instead of sending contaminated arguments downstream
25
-
26
- ### Security
27
-
28
- - Hardened tool-call handling against leaked `to=functions.*` protocol tails by truncating or retrying before execution
29
- - Hardened failure handling so repeated GPT-5 Harmony leak mitigation is retried only up to two times before escalating to an explicit error
30
-
31
- ## [14.9.0] - 2026-05-10
32
-
33
- ### Added
34
-
35
- - Added `Agent#metadata` field forwarded to every API request; callers can set arbitrary provider metadata (e.g. `metadata.user_id`) once and have it applied to all subsequent stream calls without modifying per-call options
36
- - Added `Agent#setMetadataResolver(fn)` for installing a function that resolves request metadata at call time. The `metadata` getter dispatches through the resolver on every read (including the snapshot taken per `prompt()`), so callers reflect mutable external state (e.g. live OAuth account UUID after a token refresh) without manual re-syncs. Plain `agent.metadata = …` continues to set a static value and clears any installed resolver.
37
- - Added an `onSseEvent` agent option and loop config forwarding path for raw provider SSE diagnostics.
38
-
39
- ## [14.7.6] - 2026-05-07
40
-
41
- ### Added
42
-
43
- - Added `hideThinkingSummary` option/getter/setter on `Agent` and `AgentLoopConfig`. Forwarded to the underlying stream call so providers can omit reasoning/thinking summaries on demand.
44
-
45
- ## [14.7.2] - 2026-05-06
46
-
47
- ### Added
48
-
49
- - Added `loadMode` option to `AgentTool` to mark built-in tools as `essential` for initial loading or `discoverable` for search activation
50
- - Added optional `summary` field to `AgentTool` definitions for one-line text used in tool discovery indexes
51
-
52
- ## [14.7.0] - 2026-05-04
53
-
54
- ### Breaking Changes
55
-
56
- - Changed `Agent` API types so `systemPrompt` is now a list of prompt strings, requiring callers to pass and update system prompts via string arrays
57
-
58
- ### Changed
59
-
60
- - Removed automatic project-context injection into each model call from loop logic
61
-
62
- ### Removed
63
-
64
- - Removed the `projectPrompt` field from agent state/context and the `setProjectPrompt` mutator
65
-
66
- ## [14.6.2] - 2026-05-03
67
-
68
- ### Fixed
69
-
70
- - Fixed unhandled promise rejection when `getApiKey` or any other async error occurs during `streamAssistantResponse`: agent loop IIFEs now catch and route errors through `EventStream.fail()`, which terminates the `for await` loop and lets `Agent#runLoop`'s catch block create a proper error assistant message instead of crashing
71
-
72
- ## [14.6.0] - 2026-05-02
73
-
74
- ### Fixed
75
-
76
- - Fixed request cancellation before provider events by emitting an aborted assistant message and ending the stream with `stopReason: "aborted"`
77
-
78
- ## [14.5.10] - 2026-04-30
79
-
80
- ### Added
81
-
82
- - Added an `onResponse` stream option for observing provider response metadata after response headers arrive.
83
-
84
- ## [14.2.0] - 2026-04-23
85
-
86
- ### Changed
87
-
88
- - Changed tool dispatch to match model-returned tool calls by either internal tool name or custom wire name, enabling custom OpenAI tool names such as `apply_patch`.
89
-
90
- ## [14.0.1] - 2026-04-08
91
-
92
- ### Added
93
-
94
- - Added `onAssistantMessageEvent` callback option to inspect assistant streaming events before they are emitted, enabling abort decisions before buffered events continue flowing
95
- - Added `setAssistantMessageEventInterceptor()` method to dynamically set or update the assistant message event interceptor
96
-
97
- ## [13.13.0] - 2026-03-18
98
-
99
- ### Added
100
-
101
- - Added `startup.checkUpdate` setting, set to `true` by default, can be disabled to skip the update check on agent initialization
102
-
103
- ## [13.12.7] - 2026-03-16
104
-
105
- ### Added
106
-
107
- - Added overload for `prompt()` method accepting a string input with optional options parameter
108
-
109
- ### Fixed
110
-
111
- - Fixed stale forced toolChoice being passed to provider after tools are refreshed mid-turn
112
-
113
- ## [13.9.16] - 2026-03-10
114
-
115
- ### Added
116
-
117
- - Added `onPayload` option to `AgentOptions` to inspect or replace provider payloads before they are sent
118
-
119
- ## [13.9.3] - 2026-03-07
120
-
121
- ### Added
122
-
123
- - Exported `ThinkingLevel` selector constants and types for configuring agent reasoning behavior
124
- - Added `inherit` thinking level option to defer reasoning configuration to higher-level selectors
125
- - Added `serviceTier` option to configure service tier for agent requests
126
-
127
- ### Changed
128
-
129
- - Changed `thinkingLevel` from required string to optional `Effort` type, allowing undefined state
130
- - Updated `setThinkingLevel()` method to accept `Effort | undefined` instead of `ThinkingLevel` string
131
-
132
- ## [13.4.0] - 2026-03-01
133
-
134
- ### Added
135
-
136
- - Added `getToolChoice` option to dynamically override tool choice per LLM call
137
-
138
- ## [13.3.8] - 2026-02-28
139
-
140
- ### Changed
141
-
142
- - Changed intent field name from `agent__intent` to `_i` in tool schemas
143
-
144
- ### Fixed
145
-
146
- - Fixed synthetic tool result text formatting so aborted/error tool results no longer emit `Tool execution was aborted.: Request was aborted` style punctuation.
147
-
148
- ## [13.3.7] - 2026-02-27
149
-
150
- ### Added
151
-
152
- - Added `lenientArgValidation` option to tools to allow graceful handling of argument validation errors by passing raw arguments to execute() instead of returning an error to the LLM
153
-
154
- ## [13.3.1] - 2026-02-26
155
-
156
- ### Added
157
-
158
- - Added `topP`, `topK`, `minP`, `presencePenalty`, and `repetitionPenalty` options to `AgentOptions` for fine-grained sampling control
159
- - Added getter and setter properties for sampling parameters on the `Agent` class to allow runtime configuration
160
-
161
- ## [13.1.0] - 2026-02-23
162
-
163
- ### Changed
164
-
165
- - Removed per-tool `agent__intent` field description from injected schema to reduce token usage; intent format is now documented once in the system prompt instead of repeated in every tool definition
166
-
167
- ## [12.19.0] - 2026-02-22
168
-
169
- ### Changed
170
-
171
- - Updated tool result messages to include error details when tool execution fails
172
-
173
- ## [12.14.0] - 2026-02-19
174
-
175
- ### Added
176
-
177
- - Added `intentTracing` option to enable intent goal extraction from tool calls, allowing models to specify high-level goals via a required `_intent` field that is automatically injected into tool schemas and stripped from arguments before execution
178
-
179
- ## [12.11.0] - 2026-02-19
180
-
181
- ### Added
182
-
183
- - Exported `AgentBusyError` exception class for handling concurrent agent operations
184
-
185
- ### Changed
186
-
187
- - Agent now throws `AgentBusyError` instead of generic `Error` when attempting concurrent operations
3
+ ## [1.2.0] - 2026-10-12
188
4
 
189
- ## [12.8.0] - 2026-02-16
190
-
191
- ### Added
192
-
193
- - Added `transformToolCallArguments` option to `AgentOptions` and `AgentLoopConfig` for transforming tool call arguments before execution (e.g. secret deobfuscation)
194
-
195
- ## [12.2.0] - 2026-02-13
196
-
197
- ### Added
198
-
199
- - Added `providerSessionState` option to share provider state map for session-scoped transport and session caches
200
- - Added `preferWebsockets` option to hint that websocket transport should be preferred when supported by the provider implementation
201
-
202
- ## [11.10.0] - 2026-02-10
203
-
204
- ### Added
205
-
206
- - Added `temperature` option to `AgentOptions` to control LLM sampling temperature
207
- - Added `temperature` getter and setter to `Agent` class for runtime configuration
208
-
209
- ## [11.6.0] - 2026-02-07
210
-
211
- ### Added
212
-
213
- - Added `hasQueuedMessages()` method to check for pending steering/follow-up messages
214
- - Resume queued steering and follow-up messages from `continue()` after auto-compaction
215
-
216
- ### Changed
217
-
218
- - Extracted `dequeueSteeringMessages()` and `dequeueFollowUpMessages()` from inline config callbacks
219
- - Added `skipInitialSteeringPoll` option to `_runLoop()` for correct queue resume ordering
220
-
221
- ## [11.3.0] - 2026-02-06
222
-
223
- ### Added
224
-
225
- - Added `maxRetryDelayMs` option to AgentOptions to cap server-requested retry delays, allowing higher-level retry logic to handle long waits with user visibility
226
-
227
- ### Changed
228
-
229
- - Updated ThinkingLevel documentation to include support for gpt-5.3 and gpt-5.3-codex models with 'xhigh' thinking level
230
-
231
- ## [11.2.0] - 2026-02-05
232
-
233
- ### Fixed
234
-
235
- - Fixed handling of aborted requests to properly throw abort errors when stream terminates without a terminal event
236
-
237
- ## [10.5.0] - 2026-02-04
238
-
239
- ### Added
240
-
241
- - Added `concurrency` option to `AgentTool` to control tool scheduling: "shared" (default, runs in parallel) or "exclusive" (runs alone)
242
- - Implemented parallel execution of shared tools within a single agent turn for improved performance
243
-
244
- ### Changed
245
-
246
- - Refactored tool execution to support concurrent scheduling with proper interrupt handling and steering message checks
5
+ - 版本线推进至 1.2.0;本版无独立用户可见变化。
247
6
 
248
7
  ## [9.2.2] - 2026-01-31
249
8
 
@@ -375,6 +134,10 @@
375
134
 
376
135
  Initial release under @oh-my-pi scope. See previous releases at [badlogic/pi-mono](https://github.com/badlogic/pi-mono).
377
136
 
137
+ ## [1.1.27] - 2026-10-07
138
+
139
+ - 版本线推进至 1.1.27;本版无独立用户可见变化。
140
+
378
141
  ## [1.1.25] - 2026-10-03
379
142
 
380
143
  - 版本线推进至 1.1.25;本版无独立用户可见变化。
package/README.md CHANGED
@@ -466,7 +466,7 @@ const runCoverage = aggregateAgentRunCoverage(coverages);
466
466
 
467
467
  ### Tool status reporting
468
468
 
469
- `execute_tool` spans carry `omp.gen_ai.tool.status` ∈
469
+ `execute_tool` spans carry `zeta.gen_ai.tool.status` ∈
470
470
  `"ok" | "error" | "skipped" | "blocked" | "timeout" | "aborted"`.
471
471
  `beforeToolCall` blocks throw a distinguishable `ToolCallBlockedError`
472
472
  internally; the catch path reports `status: "blocked"` instead of conflating
@@ -270,6 +270,11 @@ export declare class Agent {
270
270
  * are queued for the next boundary.
271
271
  */
272
272
  hasBackgroundCompletions?: AgentLoopConfig["hasBackgroundCompletions"];
273
+ /**
274
+ * Hook that peeks whether a passive aside is queued for the next boundary;
275
+ * ends an interruptible wait without interrupting other tools.
276
+ */
277
+ hasQueuedAsides?: AgentLoopConfig["hasQueuedAsides"];
273
278
  constructor(opts?: AgentOptions);
274
279
  /**
275
280
  * Get the current session ID used for provider caching.
@@ -390,8 +395,8 @@ export declare class Agent {
390
395
  get state(): AgentState;
391
396
  /**
392
397
  * Tokenizer for the active model. The instance is replaced whenever the
393
- * active model's encoding changes (see {@link setModel}), so callers must
394
- * not cache it across model switches.
398
+ * active model's encoding or snapcompact frame pricing changes (see
399
+ * {@link setModel}), so callers must not cache it across model switches.
395
400
  */
396
401
  get tokenizer(): Tokenizer;
397
402
  get appendOnlyContext(): AppendOnlyContextManager | undefined;
@@ -412,7 +417,8 @@ export declare class Agent {
412
417
  buildSideRequestContext(llmMessages: Message[], systemPrompt?: string[]): Promise<Context>;
413
418
  subscribe(fn: (e: AgentEvent) => void): () => void;
414
419
  /** Register a listener notified after any steering/follow-up queue mutator
415
- * (enqueue, dequeue-on-delivery, clear, restore) runs. Internal-only signal —
420
+ * (enqueue, dequeue-on-delivery, clear, restore, live-steering adoption,
421
+ * withdrawal, and landing in the transcript) runs. Internal-only signal —
416
422
  * the queue itself has no concept of display filtering — so listeners
417
423
  * recompute their own snapshot from `peekSteeringQueue()`/`peekFollowUpQueue()`
418
424
  * (or a higher-level view) on notification. */
@@ -422,10 +428,15 @@ export declare class Agent {
422
428
  /** Register an independently removable hook that runs immediately before each model call. */
423
429
  addBeforeModelCallHook(hook: (signal?: AbortSignal) => Promise<void> | void): () => void;
424
430
  /**
425
- * Take back live-steered messages ahead of an abort (Esc restores them to the editor):
426
- * the aborted run then neither records nor requeues them.
431
+ * Take back dequeued input the transcript has not recorded yet, ahead of an abort (Esc restores
432
+ * it to the editor): steering live steering took for the in-flight response, then each batch
433
+ * dequeued for the next model call, oldest first. The aborted run then neither records it (or
434
+ * the context prepared for it) nor requeues it.
427
435
  */
428
- withdrawLiveSteering(): AgentMessage[];
436
+ withdrawUndeliveredQueuedMessages(): {
437
+ steering: AgentMessage[];
438
+ followUp: AgentMessage[];
439
+ };
429
440
  /** Steering live steering took for the streaming response; the transcript records it once
430
441
  * that response (or its tool batch) ends, which is when the model switches to it. */
431
442
  peekLiveSteeredMessages(): AgentMessage[];
@@ -434,6 +445,8 @@ export declare class Agent {
434
445
  setAssistantMessageEventInterceptor(fn: ((message: AssistantMessage, event: AssistantMessageEvent) => void) | undefined): void;
435
446
  setOnBeforeYield(fn: (() => Promise<void> | void) | undefined): void;
436
447
  setOnTurnEnd(fn: ((messages: AgentMessage[], signal?: AbortSignal, context?: AgentTurnEndContext) => Promise<void> | void) | undefined): void;
448
+ /** Called with the exact system prompt each model call is built from, after before-model-call hooks. */
449
+ setOnModelCallSystemPrompt(fn: ((systemPrompt: string[]) => void) | undefined): void;
437
450
  /**
438
451
  * Install or replace the host pre-model-call gate; pass `undefined` to
439
452
  * remove it. Gates are sampled when a run starts: installing the first
@@ -450,12 +463,19 @@ export declare class Agent {
450
463
  /**
451
464
  * Provide a source of non-interrupting "aside" messages (e.g. background-job
452
465
  * completions, late LSP diagnostics) drained at each step boundary. Never
453
- * aborts in-flight tools. See `AgentLoopConfig.getAsideMessages`.
466
+ * aborts foreground tools; an interruptible `wait` may end early through the
467
+ * peek hooks. See `AgentLoopConfig.getAsideMessages`.
454
468
  */
455
469
  setAsideMessageProvider(fn: (() => AsideMessage[] | Promise<AsideMessage[]>) | undefined): void;
456
470
  emitExternalEvent(event: AgentEvent): void;
457
471
  setSystemPrompt(v: string[] | string): void;
458
472
  setModel(model: Model): void;
473
+ /**
474
+ * Route every model this agent adopts through `resolver` (e.g. to fit a
475
+ * shared catalog row to this agent's own settings), starting with the
476
+ * current one; `undefined` adopts models as given from now on.
477
+ */
478
+ setModelResolver(resolver: ((model: Model) => Model) | undefined): void;
459
479
  setThinkingLevel(l: Effort | undefined): void;
460
480
  setDisableReasoning(disabled: boolean): void;
461
481
  setSteeringMode(mode: "all" | "one-at-a-time"): void;
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * Anthropic on-demand compaction (`compact-2026-09-04` beta).
3
3
  *
4
- * The request sends only the prefix to summarize, with the live conversation's
5
- * system prompt, tools and thinking settings. The returned signed block
6
- * replaces that prefix; the retained tail is replayed from session entries.
4
+ * The request sends only the prefix to summarize, as the live conversation
5
+ * sent it: same system prompt, tools, history bytes and thinking settings.
6
+ * The returned signed block replaces that prefix; the retained tail is
7
+ * replayed from session entries.
7
8
  */
8
- import type { AnthropicCompactionPayload, ApiKey, Effort, Message, Model, SimpleStreamOptions, Tool, Usage } from "@linxiraos/pi-ai";
9
+ import type { AnthropicCompactionFiles, AnthropicCompactionPayload, ApiKey, Context, Effort, Model, SimpleStreamOptions, Usage } from "@linxiraos/pi-ai";
9
10
  import { type InstrumentedChatSpanOptions } from "../telemetry.js";
10
11
  import type { AgentMessage } from "../types.js";
11
12
  export declare const ANTHROPIC_COMPACTION_PRESERVE_KEY = "anthropicCompaction";
@@ -17,8 +18,12 @@ export interface AnthropicCompactionPreserveData {
17
18
  signature?: string;
18
19
  /** Legacy threshold block state; replay-only. */
19
20
  encryptedContent?: string;
20
- /** Harness file metadata (`<files>` section) replayed after the native block. */
21
+ /** Harness file metadata (`<files>` section) replayed after the retained tail. */
21
22
  filesText?: string;
23
+ /** Earlier summaries' file metadata replayed inside the retained tail. */
24
+ retainedFiles?: AnthropicCompactionFiles[];
25
+ /** The retained tail replays unchanged (see `AnthropicCompactionPayload.exactTail`). */
26
+ exactTail?: true;
22
27
  /** Model that wrote the summary. */
23
28
  model?: string;
24
29
  /** Prompt tokens the compaction request processed, for display. */
@@ -51,10 +56,11 @@ export declare function findAnthropicCompactionCut(messages: readonly (AgentMess
51
56
  /** Instructions replace the API default; the request contains only summarized messages. */
52
57
  export declare function buildAnthropicCompactionInstructions(basePrompt: string, customInstructions: string | undefined, extraContext: string | undefined): string;
53
58
  export interface AnthropicNativeCompactionRequest {
54
- systemPrompt: string[];
55
- messages: Message[];
56
- tools?: Tool[];
59
+ /** The summarized prefix as the live turn would send it. */
60
+ context: Context;
57
61
  instructions: string;
62
+ /** Replayed file metadata due before this time ends the request (see `AnthropicCompactionRequest.filesDueBefore`). */
63
+ filesDueBefore?: number;
58
64
  maxTokens: number;
59
65
  reasoning?: Effort;
60
66
  }
@@ -55,7 +55,7 @@ export interface GenerateBranchSummaryOptions {
55
55
  convertToLlm?: ConvertToLlm;
56
56
  /**
57
57
  * Optional telemetry handle. When provided, the branch summary LLM call is
58
- * wrapped in an OTEL chat span tagged with `omp.gen_ai.oneshot.kind = "branch_summary"`.
58
+ * wrapped in an OTEL chat span tagged with `zeta.gen_ai.oneshot.kind = "branch_summary"`.
59
59
  */
60
60
  telemetry?: AgentTelemetry;
61
61
  /**
@@ -26,6 +26,8 @@ export interface CompactionV2Usage {
26
26
  export interface CompactionV2Request {
27
27
  body: OpenAICodexCompactionBody;
28
28
  input: unknown[];
29
+ /** Serialized user-written turns to keep next to the compaction item; defaults to `input`. */
30
+ retainedUserItems: unknown[];
29
31
  retainedMessageBudget: number;
30
32
  sessionId?: string;
31
33
  promptCacheKey?: string;
@@ -56,12 +58,14 @@ export declare function buildCompactionV2Request(model: Model, input: unknown[],
56
58
  sessionId?: string;
57
59
  promptCacheKey?: string;
58
60
  retainedMessageBudget?: number;
61
+ retainedUserItems?: unknown[];
59
62
  }): CompactionV2Request;
60
63
  /** Wrap a body built by the normal Codex serializer for V2 compaction transport. */
61
64
  export declare function buildCompactionV2RequestFromBody(model: Model, body: OpenAICodexCompactionBody, options?: {
62
65
  sessionId?: string;
63
66
  promptCacheKey?: string;
64
67
  retainedMessageBudget?: number;
68
+ retainedUserItems?: unknown[];
65
69
  }): CompactionV2Request;
66
70
  /** Request V2 compaction over the normal OpenAI Responses streaming endpoint. */
67
71
  export declare function requestCompactionV2Streaming(model: Model, apiKey: string, request: CompactionV2Request, signal?: AbortSignal, options?: {
@@ -72,7 +76,7 @@ export declare function requestCompactionV2Streaming(model: Model, apiKey: strin
72
76
  codexCompaction?: CodexCompactionContext;
73
77
  preferWebsockets?: boolean;
74
78
  }): Promise<CompactionV2Response>;
75
- /** Build Codex-style V2 replacement history from prompt input plus compaction output. */
79
+ /** Build Codex-style V2 replacement history from retention candidates plus compaction output. */
76
80
  export declare function buildCompactionV2ReplacementHistory(input: unknown[], compactionItem: Record<string, unknown>, retainedMessageBudget?: number): {
77
81
  replacementHistory: Array<Record<string, unknown>>;
78
82
  retainedImageCount: number;
@@ -34,6 +34,14 @@ export interface CompactionSettings {
34
34
  strategy?: "context-full" | "handoff" | "shake" | "snapcompact" | "off";
35
35
  thresholdPercent?: number;
36
36
  thresholdTokens?: number;
37
+ /**
38
+ * Stands in for the context window when the percentage or reserve-based
39
+ * threshold is computed (when `> 0` and smaller than the window); a positive
40
+ * `thresholdTokens` still wins and is checked against the real window (at
41
+ * or past it, the window less its reserve applies). Set by per-model
42
+ * compaction limits; request and overflow budgets keep the real window.
43
+ */
44
+ baseWindowTokens?: number;
37
45
  midTurnEnabled?: boolean;
38
46
  /**
39
47
  * Tokens reserved below the context window for the next prompt + response.
@@ -177,10 +185,24 @@ export interface SummaryOptions {
177
185
  initiatorOverride?: MessageAttribution;
178
186
  metadata?: Record<string, unknown>;
179
187
  convertToLlm?: ConvertToLlm;
188
+ /**
189
+ * The provider context a live turn sends for `summarized` + `retained`, cut to
190
+ * `summarized`. Anthropic on-demand compaction sends it so retained signed
191
+ * thinking keeps its prefix; without it the request uses `remoteSystemPrompt`,
192
+ * `tools` and `convertToLlm`.
193
+ */
194
+ buildProviderContext?: (summarized: AgentMessage[], retained: AgentMessage[], signal?: AbortSignal) => Promise<Context>;
195
+ /**
196
+ * Whether a message is a turn the user wrote. Remote Compaction V2 keeps these
197
+ * next to the compaction item. Defaults to `role === "user"`; hosts whose
198
+ * user-initiated turns also arrive as custom messages (e.g. skill invocations)
199
+ * widen it.
200
+ */
201
+ isUserAuthored?: (message: AgentMessage) => boolean;
180
202
  /**
181
203
  * Optional telemetry handle. When provided, every LLM call emitted during
182
204
  * compaction is wrapped in an OTEL chat span tagged with
183
- * `omp.gen_ai.oneshot.kind` (`compaction_summary`, `compaction_short_summary`,
205
+ * `zeta.gen_ai.oneshot.kind` (`compaction_summary`, `compaction_short_summary`,
184
206
  * or `compaction_turn_prefix`). `undefined` keeps the call paths zero-cost.
185
207
  */
186
208
  telemetry?: AgentTelemetry;
@@ -243,7 +265,7 @@ export interface HandoffOptions {
243
265
  metadata?: Record<string, unknown>;
244
266
  /**
245
267
  * Optional telemetry handle. When provided, the handoff LLM call is
246
- * wrapped in an OTEL chat span tagged with `omp.gen_ai.oneshot.kind = "handoff"`.
268
+ * wrapped in an OTEL chat span tagged with `zeta.gen_ai.oneshot.kind = "handoff"`.
247
269
  */
248
270
  telemetry?: AgentTelemetry;
249
271
  /**
@@ -88,8 +88,8 @@ export interface TtsrInjectionEntry extends SessionEntryBase {
88
88
  }
89
89
  export interface SessionInitEntry extends SessionEntryBase {
90
90
  type: "session_init";
91
- /** Full system prompt sent to the model */
92
- systemPrompt: string;
91
+ /** System prompt blocks exactly as sent to the model; files written before blocks were kept store one joined string. */
92
+ systemPrompt: string[] | string;
93
93
  /** Initial task/user message */
94
94
  task: string;
95
95
  /** Tools available to the agent */
@@ -1,5 +1,6 @@
1
1
  import type { ImageContent, Message, MessageAttribution, ProviderPayload, TextContent } from "@linxiraos/pi-ai";
2
2
  import type { AgentMessage } from "../types.js";
3
+ import type { SessionEntry } from "./entries.js";
3
4
  export interface CustomMessage<T = unknown> {
4
5
  role: "custom";
5
6
  customType: string;
@@ -110,3 +111,8 @@ export declare function convertMessageToLlm(message: AgentMessage): Message | un
110
111
  * core LLM roles and the compaction messages owned by this package.
111
112
  */
112
113
  export declare function defaultConvertToLlm(messages: AgentMessage[]): Message[];
114
+ /**
115
+ * The context message a session entry contributes, or `undefined` for entries
116
+ * that don't reach the LLM (compaction markers, labels, model changes, ...).
117
+ */
118
+ export declare function getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined;
@@ -28,19 +28,31 @@ export declare const OPENAI_REMOTE_COMPACTION_PRESERVE_KEY = "openaiRemoteCompac
28
28
  */
29
29
  export declare const REMOTE_COMPACTION_TIMEOUT_MS = 300000;
30
30
  export declare const CONTEXT_WINDOW_TRUNCATED_OUTPUT_MESSAGE: string;
31
+ /**
32
+ * Tokens of stored Responses replacement history. Retained `input_image` parts
33
+ * count at their image estimate rather than as base64 text; everything else,
34
+ * opaque compaction state included, counts as serialized.
35
+ */
36
+ export declare function countResponsesHistoryTokens(items: unknown[], tokenizer: Tokenizer): number;
31
37
  export interface TrimRemoteCompactionInputResult {
32
38
  input: Array<Record<string, unknown>>;
33
39
  rewrittenOutputs: number;
34
40
  estimatedTokensBefore: number;
35
41
  estimatedTokensAfter: number;
36
- /** Whether `input` fits the model window; false means it must not be sent. */
42
+ /**
43
+ * Whether `input` may be sent; false means it must not be. True when the
44
+ * full estimate fits, or when only the image estimate pushes it over (image
45
+ * pricing is a guess; the provider's own accounting decides).
46
+ */
37
47
  fits: boolean;
38
48
  }
39
49
  /**
40
50
  * Preserve the full native transcript unless trailing tool outputs alone push a
41
51
  * remote compaction request beyond the model window. Replacing only those
42
52
  * outputs keeps call/result pairing and all earlier assistant/reasoning history,
43
- * matching Codex's recovery path for oversized tool turns.
53
+ * matching Codex's recovery path for oversized tool turns. A request whose text
54
+ * fits but whose image estimate does not is still sendable: refusing it on an
55
+ * image guess would skip native compaction the provider would have accepted.
44
56
  */
45
57
  export declare function trimRemoteCompactionInputToContextWindow(input: Array<Record<string, unknown>>, tokenizer: Tokenizer, contextWindow: number | null | undefined, instructions: string, tools?: unknown[]): TrimRemoteCompactionInputResult;
46
58
  /**