@linxiraos/pi-agent-core 1.1.20 → 1.1.22

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 (41) hide show
  1. package/CHANGELOG.md +241 -2
  2. package/README.md +4 -3
  3. package/THIRD-PARTY-NOTICES.txt +3 -40
  4. package/dist/types/agent-loop.d.ts +14 -1
  5. package/dist/types/agent.d.ts +36 -0
  6. package/dist/types/compaction/anthropic.d.ts +22 -52
  7. package/dist/types/compaction/branch-summarization.d.ts +1 -1
  8. package/dist/types/compaction/compaction.d.ts +4 -2
  9. package/dist/types/compaction/messages.d.ts +9 -0
  10. package/dist/types/compaction/openai.d.ts +11 -0
  11. package/dist/types/compaction/pruning.d.ts +9 -0
  12. package/dist/types/compaction/transcript-tokens.d.ts +25 -2
  13. package/dist/types/index.d.ts +3 -0
  14. package/dist/types/live-steering.d.ts +34 -0
  15. package/dist/types/output-budget.d.ts +54 -0
  16. package/dist/types/sent-tool-definitions.d.ts +17 -0
  17. package/dist/types/speculative-execution.d.ts +2 -1
  18. package/dist/types/telemetry.d.ts +103 -60
  19. package/dist/types/tool-context.d.ts +32 -0
  20. package/dist/types/types.d.ts +105 -7
  21. package/package.json +10 -10
  22. package/src/agent-loop.ts +386 -90
  23. package/src/agent.ts +175 -26
  24. package/src/compaction/anthropic.ts +62 -105
  25. package/src/compaction/branch-summarization.ts +1 -1
  26. package/src/compaction/compaction-v2-streaming.ts +13 -4
  27. package/src/compaction/compaction.ts +63 -51
  28. package/src/compaction/messages.ts +12 -2
  29. package/src/compaction/openai.ts +37 -9
  30. package/src/compaction/prompts/anthropic-compaction-instructions.md +2 -6
  31. package/src/compaction/pruning.ts +1 -1
  32. package/src/compaction/transcript-tokens.ts +64 -3
  33. package/src/index.ts +6 -0
  34. package/src/live-steering.ts +89 -0
  35. package/src/output-budget.ts +142 -0
  36. package/src/sent-tool-definitions.ts +40 -0
  37. package/src/speculative-execution.ts +12 -0
  38. package/src/telemetry.ts +240 -117
  39. package/src/tokenizer.ts +45 -6
  40. package/src/tool-context.ts +55 -0
  41. package/src/types.ts +109 -7
package/CHANGELOG.md CHANGED
@@ -2,9 +2,248 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ## [1.1.20] - 2026-09-23
5
+ ## [1.1.22] - 2026-09-30
6
6
 
7
- - 版本线推进;`__piNatives` 哨兵派生规则与 set-version 对齐(dots-only → 全部非字母数字),prerelease 下不再推出非法 Rust 标识符。
7
+ - 随 1.1.22 版本线:CLI bin 命名(zeta-c)相关的用量文案与文档对齐。
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
188
+
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
8
247
 
9
248
  ## [9.2.2] - 2026-01-31
10
249
 
package/README.md CHANGED
@@ -154,8 +154,9 @@ const agent = new Agent({
154
154
  // Dynamic model-scoped API key resolution (for expiring OAuth tokens)
155
155
  getApiKey: async (model) => tokenForModel(model),
156
156
 
157
- // Tool execution context (late-bound UI/session access)
158
- getToolContext: () => ({ /* app-defined */ }),
157
+ // Tool execution context (late-bound UI/session access). Surface the loop's
158
+ // passive-context sink so tools can call ctx.addAdditionalContext(...).
159
+ getToolContext: toolCall => ({ addAdditionalContext: toolCall?.addAdditionalContext /* app-defined */ }),
159
160
  });
160
161
  ```
161
162
 
@@ -461,7 +462,7 @@ const runCoverage = aggregateAgentRunCoverage(coverages);
461
462
 
462
463
  ### Tool status reporting
463
464
 
464
- `execute_tool` spans carry `pi.gen_ai.tool.status` ∈
465
+ `execute_tool` spans carry `omp.gen_ai.tool.status` ∈
465
466
  `"ok" | "error" | "skipped" | "blocked" | "timeout" | "aborted"`.
466
467
  `beforeToolCall` blocks throw a distinguishable `ToolCallBlockedError`
467
468
  internally; the catch path reports `status: "blocked"` instead of conflating
@@ -78,8 +78,8 @@ below.
78
78
  uutils coreutils (https://github.com/uutils/coreutils), MIT
79
79
  --------------------------------------------------------------------------------
80
80
  Covers: base32, base64, basename, cat, cksum (shared checksum machinery),
81
- b2sum, md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, comm, cut,
82
- date, dirname, head, hostname, ln, ls, mkdir, mktemp, mv, nproc, paste,
81
+ b2sum, md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, comm, cp,
82
+ cut, date, dirname, head, hostname, ln, ls, mkdir, mktemp, mv, nproc, paste,
83
83
  printenv, readlink, realpath, rm, seq, sort, stat, tac, tail, tee, touch, tr,
84
84
  truncate, uname, uniq, wc, whoami, yes.
85
85
 
@@ -293,7 +293,7 @@ MIT License
293
293
  Copyright (c) 2026 Sander Land
294
294
  (measured tokenizer vocabulary data, reconstruction model, and reference
295
295
  implementation: https://github.com/sanderland/ctok)
296
- Copyright (c) 2026 Can Bölük and the Oh My Pi contributors
296
+ Copyright (c) 2026 Can Bölük and the omp contributors
297
297
  Copyright (c) 2026 Stencil Labs, Inc.
298
298
  (Rust implementation and the compact binary vocabulary encoding in
299
299
  crates/pi-natives/src/utok/claude)
@@ -335,43 +335,6 @@ This license allows the work and adaptations of it to be shared and used
335
335
  commercially, as long as it is attributed to Poppy Works. The font is bundled
336
336
  here (crates/pi-natives/src/fonts/Silver.ttf) as a CJK/Unicode bitmap fallback.
337
337
 
338
- -------------------------------------------------------------------------------
339
- packages/utils/src/vendor/mermaid-ascii/NOTICE
340
-
341
- This directory contains an in-house Mermaid-diagram-to-ASCII renderer adapted
342
- from beautiful-mermaid (https://github.com/lukilabs/beautiful-mermaid), used
343
- under the MIT License.
344
-
345
- Copyright (c) 2026 Craft Docs
346
-
347
- Only the ASCII rendering pipeline is ported (flowchart/state, sequence, class,
348
- ER, and xychart diagrams); the SVG renderer and its `elkjs` graph-layout
349
- dependency, the browser entry point, and the SVG theme/style modules were
350
- dropped. Terminal display width is reimplemented on `Bun.stringWidth`, and
351
- inline label formatting (HTML tags, markdown emphasis) is reduced to plain text
352
- for ASCII output. Layout and edge-routing logic is preserved faithfully so
353
- ASCII output matches the upstream package.
354
-
355
- MIT License
356
-
357
- Permission is hereby granted, free of charge, to any person obtaining a copy
358
- of this software and associated documentation files (the "Software"), to deal
359
- in the Software without restriction, including without limitation the rights
360
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
361
- copies of the Software, and to permit persons to whom the Software is
362
- furnished to do so, subject to the following conditions:
363
-
364
- The above copyright notice and this permission notice shall be included in all
365
- copies or substantial portions of the Software.
366
-
367
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
368
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
369
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
370
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
371
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
372
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
373
- SOFTWARE.
374
-
375
338
  -------------------------------------------------------------------------------
376
339
  packages/coding-agent/src/markit/NOTICE
377
340
 
@@ -5,7 +5,7 @@
5
5
  import { type AssistantMessage, type Context, EventStream, type ToolResultMessage } from "@linxiraos/pi-ai";
6
6
  import { type Dialect } from "@linxiraos/pi-ai/dialect";
7
7
  import { type AgentRunCoverage, type AgentRunSummary } from "./run-collector.js";
8
- import type { AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, StreamFn } from "./types.js";
8
+ import type { AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, SteeringQueueState, StreamFn } from "./types.js";
9
9
  /** Stop-details marker for a provider error after assistant content/tool args already streamed. */
10
10
  export declare const STREAM_INTERRUPTED_AFTER_CONTENT_STOP_DETAIL = "stream_interrupted_after_content";
11
11
  /**
@@ -32,6 +32,12 @@ export declare function createToolScopedAbortReason(message: string, toolCallMes
32
32
  * boundary; this reason stops after persisting the completed tool batch.
33
33
  */
34
34
  export declare const TERMINAL_TOOL_RESULT_ABORT_REASON: unique symbol;
35
+ /**
36
+ * Abort reason carried by an interruptible tool's signal when queued steering,
37
+ * a peer IRC, or a background completion cut it short. Lets a wait tell the
38
+ * designed wake path apart from an external/user abort of the run.
39
+ */
40
+ export declare const TOOL_INTERRUPT_ABORT_REASON: unique symbol;
35
41
  export declare function resolveOwnedDialectFromEnv(value: string | undefined): Dialect | undefined;
36
42
  /**
37
43
  * Start an agent loop with a new prompt message.
@@ -100,6 +106,13 @@ export interface NormalizeToolsOptions {
100
106
  pruneDescriptions?: boolean;
101
107
  }
102
108
  export declare function normalizeTools(tools: AgentContext["tools"], options: NormalizeToolsOptions): Context["tools"];
109
+ /**
110
+ * Classify the first `count` steering messages for a tool-batch interrupt:
111
+ * any user-authored message wins, then agent-attributed user messages, else
112
+ * system steering (advisor cards, hidden directives). Shared by the agent's
113
+ * queue peek and the loop's live-taken steering.
114
+ */
115
+ export declare function steeringQueueState(messages: readonly AgentMessage[], count?: number): SteeringQueueState;
103
116
  /** Resolve the human-readable reason an abort carried. A caller that aborts via
104
117
  * `AbortController.abort(reason)` with a string or a non-`AbortError` `Error`
105
118
  * (e.g. the coding agent's user-interrupt label) gets that text surfaced on the
@@ -159,6 +159,11 @@ export interface AgentOptions {
159
159
  pruneToolDescriptions?: boolean;
160
160
  /** Owned tool-calling dialect. Undefined keeps provider-native tool calling. */
161
161
  dialect?: Dialect;
162
+ /**
163
+ * Per-request owned-dialect resolver, consulted with the model being requested.
164
+ * Authoritative when set (like {@link serviceTierResolver}): replaces {@link dialect}.
165
+ */
166
+ dialectResolver?: (model: Model) => Dialect | undefined;
162
167
  /**
163
168
  * When owned tool calling is active and the model fabricates a tool result
164
169
  * mid-turn: `true` (default) aborts the provider request immediately; `false`
@@ -216,6 +221,8 @@ export interface AgentOptions {
216
221
  * tool-call arguments). See {@link AgentLoopConfig.transformAssistantMessage}.
217
222
  */
218
223
  transformAssistantMessage?: AgentLoopConfig["transformAssistantMessage"];
224
+ /** See {@link AgentLoopConfig.transformAssistantMessagePreservesToolCalls}. */
225
+ transformAssistantMessagePreservesToolCalls?: boolean;
219
226
  /**
220
227
  * Opt-in OpenTelemetry instrumentation. Passing `{}` enables the loop's
221
228
  * GenAI-semantic-convention spans using the global tracer provider. See
@@ -252,10 +259,17 @@ export declare class Agent {
252
259
  * UI emission, and tool dispatch. Reassign at any time to swap the implementation.
253
260
  */
254
261
  transformAssistantMessage?: AgentLoopConfig["transformAssistantMessage"];
262
+ /** Declares {@link transformAssistantMessage} never rewrites streamed tool calls; reassign alongside it. */
263
+ transformAssistantMessagePreservesToolCalls?: boolean;
255
264
  /**
256
265
  * Hook that peeks whether interrupting IRC asides are queued for the next boundary.
257
266
  */
258
267
  hasIrcInterrupts?: AgentLoopConfig["hasIrcInterrupts"];
268
+ /**
269
+ * Hook that peeks whether background completions (jobs, supervised processes)
270
+ * are queued for the next boundary.
271
+ */
272
+ hasBackgroundCompletions?: AgentLoopConfig["hasBackgroundCompletions"];
259
273
  constructor(opts?: AgentOptions);
260
274
  /**
261
275
  * Get the current session ID used for provider caching.
@@ -355,6 +369,15 @@ export declare class Agent {
355
369
  set serviceTierResolver(value: ((model: Model) => ServiceTier | undefined) | undefined);
356
370
  get hideThinkingSummary(): boolean | undefined;
357
371
  set hideThinkingSummary(value: boolean | undefined);
372
+ /** Strip tool descriptions from provider-bound specs; read per request. */
373
+ get pruneToolDescriptions(): boolean;
374
+ set pruneToolDescriptions(value: boolean);
375
+ /** Inject/strip the intent field on tool calls; applies from the next prompt run. */
376
+ get intentTracing(): boolean;
377
+ set intentTracing(value: boolean);
378
+ /** Abort the provider request on a fabricated tool result; applies from the next prompt run. */
379
+ get abortOnFabricatedToolResult(): boolean | undefined;
380
+ set abortOnFabricatedToolResult(value: boolean | undefined);
358
381
  /**
359
382
  * Get the current max retry delay in milliseconds.
360
383
  */
@@ -392,6 +415,14 @@ export declare class Agent {
392
415
  addBeforeQueuedMessageDequeueHook(hook: (signal?: AbortSignal) => Promise<void> | void): () => void;
393
416
  /** Register an independently removable hook that runs immediately before each model call. */
394
417
  addBeforeModelCallHook(hook: (signal?: AbortSignal) => Promise<void> | void): () => void;
418
+ /**
419
+ * Take back live-steered messages ahead of an abort (Esc restores them to the editor):
420
+ * the aborted run then neither records nor requeues them.
421
+ */
422
+ withdrawLiveSteering(): AgentMessage[];
423
+ /** Steering live steering took for the streaming response; the transcript records it once
424
+ * that response (or its tool batch) ends, which is when the model switches to it. */
425
+ peekLiveSteeredMessages(): AgentMessage[];
395
426
  setProviderResponseInterceptor(fn: SimpleStreamOptions["onResponse"] | undefined): void;
396
427
  setRawSseEventInterceptor(fn: SimpleStreamOptions["onSseEvent"] | undefined): void;
397
428
  setAssistantMessageEventInterceptor(fn: ((message: AssistantMessage, event: AssistantMessageEvent) => void) | undefined): void;
@@ -457,6 +488,11 @@ export declare class Agent {
457
488
  * single source of truth. Includes exclusively claimed originals while
458
489
  * preparation is pending, so editor restoration can cancel their delivery. */
459
490
  peekSteeringQueue(): readonly AgentMessage[];
491
+ /** Dequeued messages not yet in the transcript, e.g. steering a provider
492
+ * took into its in-flight response via live steering. Aborting the run
493
+ * requeues them, so the session's empty-submit interrupt counts them as
494
+ * pending input even though {@link peekSteeringQueue} no longer does. */
495
+ peekUndeliveredQueuedMessages(): AgentMessage[];
460
496
  /** Non-consuming view of the pending follow-up queue. See
461
497
  * {@link peekSteeringQueue}. */
462
498
  peekFollowUpQueue(): readonly AgentMessage[];
@@ -1,33 +1,21 @@
1
1
  /**
2
- * Anthropic server-side compaction (`compact-2026-01-12` beta).
2
+ * Anthropic on-demand compaction (`compact-2026-09-04` beta).
3
3
  *
4
- * The compaction request is the live turn's own request shape — same system
5
- * prompt, tools, and message history — plus the `compact_20260112` edit with
6
- * `pause_after_compaction`. The API summarizes the prompt from the already
7
- * cached prefix and stops; the summary arrives as a `compaction` block that
8
- * the provider surfaces as an `anthropicCompaction` payload. The summary is
9
- * plain text, so it doubles as the compaction entry's readable summary for
10
- * every other provider, while the Anthropic provider replays it as a native
11
- * block (the API drops everything that precedes it). The retained tail after
12
- * the cut point is replayed from session entries exactly like a local summary.
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.
13
7
  */
14
8
  import type { AnthropicCompactionPayload, ApiKey, Effort, Message, Model, SimpleStreamOptions, Tool, Usage } from "@linxiraos/pi-ai";
15
9
  import { type InstrumentedChatSpanOptions } from "../telemetry.js";
10
+ import type { AgentMessage } from "../types.js";
16
11
  export declare const ANTHROPIC_COMPACTION_PRESERVE_KEY = "anthropicCompaction";
17
- /** The API rejects a `compact_20260112` trigger below this many input tokens. */
18
- export declare const ANTHROPIC_COMPACTION_MIN_TRIGGER_TOKENS = 50000;
19
- /**
20
- * Smallest context the native lane accepts. The trigger sits at the API
21
- * floor, so a prompt that lands below it is answered instead of compacted;
22
- * the margin over the floor absorbs the difference between the last reported
23
- * context size and the compaction request's own input.
24
- */
25
- export declare const ANTHROPIC_COMPACTION_MIN_CONTEXT_TOKENS = 55000;
26
12
  /** Summary persisted under {@link ANTHROPIC_COMPACTION_PRESERVE_KEY}. */
27
13
  export interface AnthropicCompactionPreserveData {
28
14
  provider: string;
29
15
  content: string;
30
- /** Opaque provider state the API attached to the block; replayed verbatim. */
16
+ /** Signature attached to an on-demand block; replayed verbatim. */
17
+ signature?: string;
18
+ /** Legacy threshold block state; replay-only. */
31
19
  encryptedContent?: string;
32
20
  /** Harness file metadata (`<files>` section) replayed after the native block. */
33
21
  filesText?: string;
@@ -51,33 +39,17 @@ export declare function withAnthropicCompactionPreserveData(preserveData: Record
51
39
  /** Replay payload for a compaction summary the active model produced natively. */
52
40
  export declare function getAnthropicCompactionPayload(preserveData: Record<string, unknown> | undefined): AnthropicCompactionPayload | undefined;
53
41
  /**
54
- * The retained tail as the model will see it, for the summarization
55
- * instructions: how many of the conversation's final wire messages stay in
56
- * context verbatim, and the role of the first. The compaction request carries
57
- * the whole conversation so the prompt cache the live turn wrote is read, but
58
- * the summary must cover only the history before that tail — the local
59
- * summarizer never sees the tail, and the rebuilt context replays it after the
60
- * summary. Counting mirrors the provider's message conversion (consecutive
61
- * tool results collapse into one user message; developer messages are user
62
- * messages). Structured for the prompt template, which renders the
63
- * singular/plural wording; the description quotes no content: quoting the
64
- * tail would hand the summarizer the very facts it must leave to the tail.
42
+ * Move the existing keep-tail boundary forward until the summary/tail boundary
43
+ * alternates wire roles and no tool call is separated from its result. If no
44
+ * boundary is safe, the request summarizes the entire snapshot (empty tail).
65
45
  */
66
- export interface RetainedTailScope {
67
- count: number;
68
- role: "assistant" | "user";
69
- }
70
- export declare function describeRetainedTail(messages: readonly Message[]): RetainedTailScope | undefined;
71
- /**
72
- * Summarization prompt sent as the edit's `instructions`, which replace the
73
- * API default entirely. The template lays out the retained-tail boundary
74
- * first, so the summary covers only the history the rebuilt context drops,
75
- * then the caller's extra context, the same structure prompt as the local
76
- * summarizer, the caller's focus, and the tool-abstention clause the API
77
- * recommends when tools are defined (a summarization pass that calls a tool
78
- * yields no summary).
79
- */
80
- export declare function buildAnthropicCompactionInstructions(basePrompt: string, customInstructions: string | undefined, extraContext: string | undefined, retainedTail: RetainedTailScope | undefined): string;
46
+ export declare function findAnthropicCompactionCut(messages: readonly (AgentMessage | {
47
+ role: "system";
48
+ content: string;
49
+ timestamp: number;
50
+ })[], initialCut: number): number;
51
+ /** Instructions replace the API default; the request contains only summarized messages. */
52
+ export declare function buildAnthropicCompactionInstructions(basePrompt: string, customInstructions: string | undefined, extraContext: string | undefined): string;
81
53
  export interface AnthropicNativeCompactionRequest {
82
54
  systemPrompt: string[];
83
55
  messages: Message[];
@@ -88,21 +60,19 @@ export interface AnthropicNativeCompactionRequest {
88
60
  }
89
61
  export interface AnthropicNativeCompactionResponse {
90
62
  content: string;
91
- encryptedContent?: string;
63
+ signature: string;
92
64
  usage: Usage;
93
65
  model: string;
94
66
  }
95
67
  export interface AnthropicNativeCompactionOptions extends Pick<SimpleStreamOptions, "initiatorOverride" | "metadata" | "fetch" | "sessionId" | "promptCacheKey" | "providerSessionState" | "maxInFlightRequests">, Pick<InstrumentedChatSpanOptions, "completeImpl" | "telemetry" | "retry"> {
96
68
  }
97
69
  /**
98
- * Run one compaction request and return the summary the API wrote, with the
99
- * opaque `encrypted_content` the API attached for the replay. `completeSimple`
70
+ * Run one compaction request and return the summary and signature the API wrote. `completeSimple`
100
71
  * resolves terminal failures as messages, so their classification is restored
101
72
  * here: an aborted response is an `AbortError` (a cancellation, never a native
102
73
  * failure) and an error response keeps its HTTP status, so auth and timeout
103
74
  * handling downstream classify it the same way as the OpenAI lanes. A response
104
- * without a summary is a native failure — the API answers the prompt instead
105
- * when its input never reached the trigger, and returns an empty block when
106
- * the model called a tool during summarization.
75
+ * without a summary is a native failure, including tool use, refusals and
76
+ * output limits; the configured method order can then choose a fallback.
107
77
  */
108
78
  export declare function requestAnthropicNativeCompaction(model: Model<"anthropic-messages">, apiKey: ApiKey, request: AnthropicNativeCompactionRequest, signal: AbortSignal | undefined, options: AnthropicNativeCompactionOptions): Promise<AnthropicNativeCompactionResponse>;
@@ -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 `pi.gen_ai.oneshot.kind = "branch_summary"`.
58
+ * wrapped in an OTEL chat span tagged with `omp.gen_ai.oneshot.kind = "branch_summary"`.
59
59
  */
60
60
  telemetry?: AgentTelemetry;
61
61
  /**
@@ -180,7 +180,7 @@ export interface SummaryOptions {
180
180
  /**
181
181
  * Optional telemetry handle. When provided, every LLM call emitted during
182
182
  * compaction is wrapped in an OTEL chat span tagged with
183
- * `pi.gen_ai.oneshot.kind` (`compaction_summary`, `compaction_short_summary`,
183
+ * `omp.gen_ai.oneshot.kind` (`compaction_summary`, `compaction_short_summary`,
184
184
  * or `compaction_turn_prefix`). `undefined` keeps the call paths zero-cost.
185
185
  */
186
186
  telemetry?: AgentTelemetry;
@@ -243,7 +243,7 @@ export interface HandoffOptions {
243
243
  metadata?: Record<string, unknown>;
244
244
  /**
245
245
  * Optional telemetry handle. When provided, the handoff LLM call is
246
- * wrapped in an OTEL chat span tagged with `pi.gen_ai.oneshot.kind = "handoff"`.
246
+ * wrapped in an OTEL chat span tagged with `omp.gen_ai.oneshot.kind = "handoff"`.
247
247
  */
248
248
  telemetry?: AgentTelemetry;
249
249
  /**
@@ -297,6 +297,8 @@ export interface CompactionPreparation {
297
297
  turnPrefixMessages: AgentMessage[];
298
298
  /** Messages kept in full after compaction (recent history) */
299
299
  recentMessages: AgentMessage[];
300
+ /** Entry IDs parallel to recentMessages, for an Anthropic-safe keep-tail boundary. */
301
+ recentEntryIds?: string[];
300
302
  /** Whether this is a split turn (cut point in middle of turn) */
301
303
  isSplitTurn: boolean;
302
304
  tokensBefore: number;
@@ -45,6 +45,13 @@ export interface CompactionSummaryMessage {
45
45
  images?: ImageContent[];
46
46
  /** Post-pass dead-end warning attached to this compaction (progress guard). */
47
47
  warning?: string;
48
+ /**
49
+ * Thinking-binding rewrite marker when it must differ from `timestamp`: a
50
+ * natively replayed summary predates it before the retained tail so that
51
+ * tail's bound thinking stays valid. `timestamp` remains the commit time,
52
+ * which is what invalidates the tail's pre-compaction usage reports.
53
+ */
54
+ historyRewriteAt?: number;
48
55
  timestamp: number;
49
56
  }
50
57
  export type CoreCompactionMessage = CustomMessage | HookMessage | BranchSummaryMessage | CompactionSummaryMessage;
@@ -79,6 +86,8 @@ export interface CompactionSummaryMessageOptions {
79
86
  method?: string;
80
87
  /** Estimated context tokens after the rewrite, for display alongside `tokensBefore`. */
81
88
  tokensAfter?: number;
89
+ /** See {@link CompactionSummaryMessage.historyRewriteAt}. */
90
+ historyRewriteAt?: number;
82
91
  }
83
92
  export declare function createCompactionSummaryMessage(summary: string, tokensBefore: number, timestamp: string, options?: CompactionSummaryMessageOptions): CompactionSummaryMessage;
84
93
  export declare function createCustomMessage(customType: string, content: string | (TextContent | ImageContent)[], display: boolean, details: unknown | undefined, timestamp: string, attribution?: MessageAttribution): CustomMessage;
@@ -33,6 +33,8 @@ export interface TrimRemoteCompactionInputResult {
33
33
  rewrittenOutputs: number;
34
34
  estimatedTokensBefore: number;
35
35
  estimatedTokensAfter: number;
36
+ /** Whether `input` fits the model window; false means it must not be sent. */
37
+ fits: boolean;
36
38
  }
37
39
  /**
38
40
  * Preserve the full native transcript unless trailing tool outputs alone push a
@@ -41,6 +43,15 @@ export interface TrimRemoteCompactionInputResult {
41
43
  * matching Codex's recovery path for oversized tool turns.
42
44
  */
43
45
  export declare function trimRemoteCompactionInputToContextWindow(input: Array<Record<string, unknown>>, tokenizer: Tokenizer, contextWindow: number | null | undefined, instructions: string, tools?: unknown[]): TrimRemoteCompactionInputResult;
46
+ /**
47
+ * Refuse a native compaction request whose prepared input cannot fit the model
48
+ * window, before any network I/O. Re-expanded history behind an unreadable
49
+ * native boundary can exceed the window even when live context does not.
50
+ *
51
+ * @throws Error flagged `ContextOverflow` when `trimmed.fits` is false, so
52
+ * compaction callers skip retries and advance to the next method.
53
+ */
54
+ export declare function assertRemoteCompactionInputFits(trimmed: TrimRemoteCompactionInputResult, model: Model): void;
44
55
  export type OpenAiRemoteCompactionItem = {
45
56
  type: "compaction" | "compaction_summary";
46
57
  encrypted_content?: string;