@linxiraos/pi-agent-core 1.1.27 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,270 +1,8 @@
1
- # Changelog
2
-
3
1
  ## [Unreleased]
4
2
 
5
- ## [1.1.27] - 2026-10-07
6
-
7
- - 版本线推进至 1.1.27;本版无独立用户可见变化。
8
-
9
- ### Breaking Changes
10
-
11
- - `Agent.withdrawUndeliveredQueuedMessages()` replaces `withdrawLiveSteering()` and returns `{ steering, followUp }`: it also takes back queued input already dequeued for the next model call, which the aborted run then neither records nor reports in `agent_end` ([#14179](https://github.com/can1357/oh-my-pi/pull/14179) by [@andrebrait](https://github.com/andrebrait))
12
-
13
- ### Added
14
-
15
- - Added `Agent.setOnModelCallSystemPrompt`, called with the exact system prompt each model call is built from ([#14338](https://github.com/can1357/oh-my-pi/pull/14338) by [@will-bogusz](https://github.com/will-bogusz))
16
-
17
- ### Changed
18
-
19
- - `SessionInitEntry.systemPrompt` holds the system prompt blocks as sent; session files written earlier keep one joined string ([#14338](https://github.com/can1357/oh-my-pi/pull/14338) by [@will-bogusz](https://github.com/will-bogusz))
20
- - Image token estimates now use the catalog's `imageTokens()` formula with its OpenAI Responses wire rule; values are unchanged ([#14286](https://github.com/can1357/oh-my-pi/pull/14286) by [@will-bogusz](https://github.com/will-bogusz)).
21
-
22
- ### Fixed
23
-
24
- - Fixed the context count and auto-compaction trigger pricing every snapcompact archive frame at Opus's high-res rate, which overcounted Codex and Gemini sessions and could re-trigger compaction right after compacting ([#14291](https://github.com/can1357/oh-my-pi/pull/14291) by [@will-bogusz](https://github.com/will-bogusz))
25
- - Fixed native (OpenAI) compaction being refused as over the context window in sessions with many screenshots. Images were counted as about 1,200 tokens when deciding to compact but 12,000 when checking whether the compaction request fits; both checks now estimate images from their actual dimensions, and a request is no longer refused when only the image estimate pushes it over the window ([#14260](https://github.com/can1357/oh-my-pi/pull/14260) by [@H4vC](https://github.com/H4vC)).
26
- - Fixed OpenAI and Codex Remote Compaction V2 dropping your recent messages instead of keeping them next to the compaction summary ([#14247](https://github.com/can1357/oh-my-pi/pull/14247) by [@will-bogusz](https://github.com/will-bogusz))
27
- - Fixed the failed V2 remote compaction warning claiming a V1 fallback on Codex, where V1 does not run ([#14245](https://github.com/can1357/oh-my-pi/pull/14245) by [@will-bogusz](https://github.com/will-bogusz))
28
- - Fixed Anthropic native compaction being rejected with `Invalid signature in thinking block` (or silently dropping the summarized thinking) on models with preserved thinking ([#14251](https://github.com/can1357/oh-my-pi/pull/14251) by [@will-bogusz](https://github.com/will-bogusz))
29
-
30
- ## [14.9.5] - 2026-05-12
31
-
32
- ### Added
33
-
34
- - 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.
35
-
36
- ## [14.9.3] - 2026-05-10
37
-
38
- ### Added
39
-
40
- - Added `onHarmonyLeak` option on `Agent`/loop config to receive GPT-5 Harmony leak audit callbacks
41
- - Added harmony-leak detection and audit exports to the package index for programmatic leak detection and recovery hooks
42
-
43
- ### Changed
44
-
45
- - 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
46
-
47
- ### Security
48
-
49
- - Hardened tool-call handling against leaked `to=functions.*` protocol tails by truncating or retrying before execution
50
- - Hardened failure handling so repeated GPT-5 Harmony leak mitigation is retried only up to two times before escalating to an explicit error
51
-
52
- ## [14.9.0] - 2026-05-10
53
-
54
- ### Added
55
-
56
- - 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
57
- - 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.
58
- - Added an `onSseEvent` agent option and loop config forwarding path for raw provider SSE diagnostics.
59
-
60
- ## [14.7.6] - 2026-05-07
61
-
62
- ### Added
63
-
64
- - Added `hideThinkingSummary` option/getter/setter on `Agent` and `AgentLoopConfig`. Forwarded to the underlying stream call so providers can omit reasoning/thinking summaries on demand.
65
-
66
- ## [14.7.2] - 2026-05-06
67
-
68
- ### Added
69
-
70
- - Added `loadMode` option to `AgentTool` to mark built-in tools as `essential` for initial loading or `discoverable` for search activation
71
- - Added optional `summary` field to `AgentTool` definitions for one-line text used in tool discovery indexes
72
-
73
- ## [14.7.0] - 2026-05-04
74
-
75
- ### Breaking Changes
76
-
77
- - Changed `Agent` API types so `systemPrompt` is now a list of prompt strings, requiring callers to pass and update system prompts via string arrays
78
-
79
- ### Changed
80
-
81
- - Removed automatic project-context injection into each model call from loop logic
82
-
83
- ### Removed
84
-
85
- - Removed the `projectPrompt` field from agent state/context and the `setProjectPrompt` mutator
86
-
87
- ## [14.6.2] - 2026-05-03
88
-
89
- ### Fixed
90
-
91
- - 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
92
-
93
- ## [14.6.0] - 2026-05-02
94
-
95
- ### Fixed
96
-
97
- - Fixed request cancellation before provider events by emitting an aborted assistant message and ending the stream with `stopReason: "aborted"`
98
-
99
- ## [14.5.10] - 2026-04-30
100
-
101
- ### Added
102
-
103
- - Added an `onResponse` stream option for observing provider response metadata after response headers arrive.
104
-
105
- ## [14.2.0] - 2026-04-23
106
-
107
- ### Changed
108
-
109
- - 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`.
110
-
111
- ## [14.0.1] - 2026-04-08
112
-
113
- ### Added
114
-
115
- - Added `onAssistantMessageEvent` callback option to inspect assistant streaming events before they are emitted, enabling abort decisions before buffered events continue flowing
116
- - Added `setAssistantMessageEventInterceptor()` method to dynamically set or update the assistant message event interceptor
117
-
118
- ## [13.13.0] - 2026-03-18
119
-
120
- ### Added
121
-
122
- - Added `startup.checkUpdate` setting, set to `true` by default, can be disabled to skip the update check on agent initialization
123
-
124
- ## [13.12.7] - 2026-03-16
125
-
126
- ### Added
127
-
128
- - Added overload for `prompt()` method accepting a string input with optional options parameter
129
-
130
- ### Fixed
131
-
132
- - Fixed stale forced toolChoice being passed to provider after tools are refreshed mid-turn
133
-
134
- ## [13.9.16] - 2026-03-10
135
-
136
- ### Added
137
-
138
- - Added `onPayload` option to `AgentOptions` to inspect or replace provider payloads before they are sent
3
+ ## [1.2.0] - 2026-10-12
139
4
 
140
- ## [13.9.3] - 2026-03-07
141
-
142
- ### Added
143
-
144
- - Exported `ThinkingLevel` selector constants and types for configuring agent reasoning behavior
145
- - Added `inherit` thinking level option to defer reasoning configuration to higher-level selectors
146
- - Added `serviceTier` option to configure service tier for agent requests
147
-
148
- ### Changed
149
-
150
- - Changed `thinkingLevel` from required string to optional `Effort` type, allowing undefined state
151
- - Updated `setThinkingLevel()` method to accept `Effort | undefined` instead of `ThinkingLevel` string
152
-
153
- ## [13.4.0] - 2026-03-01
154
-
155
- ### Added
156
-
157
- - Added `getToolChoice` option to dynamically override tool choice per LLM call
158
-
159
- ## [13.3.8] - 2026-02-28
160
-
161
- ### Changed
162
-
163
- - Changed intent field name from `agent__intent` to `_i` in tool schemas
164
-
165
- ### Fixed
166
-
167
- - Fixed synthetic tool result text formatting so aborted/error tool results no longer emit `Tool execution was aborted.: Request was aborted` style punctuation.
168
-
169
- ## [13.3.7] - 2026-02-27
170
-
171
- ### Added
172
-
173
- - 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
174
-
175
- ## [13.3.1] - 2026-02-26
176
-
177
- ### Added
178
-
179
- - Added `topP`, `topK`, `minP`, `presencePenalty`, and `repetitionPenalty` options to `AgentOptions` for fine-grained sampling control
180
- - Added getter and setter properties for sampling parameters on the `Agent` class to allow runtime configuration
181
-
182
- ## [13.1.0] - 2026-02-23
183
-
184
- ### Changed
185
-
186
- - 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
187
-
188
- ## [12.19.0] - 2026-02-22
189
-
190
- ### Changed
191
-
192
- - Updated tool result messages to include error details when tool execution fails
193
-
194
- ## [12.14.0] - 2026-02-19
195
-
196
- ### Added
197
-
198
- - 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
199
-
200
- ## [12.11.0] - 2026-02-19
201
-
202
- ### Added
203
-
204
- - Exported `AgentBusyError` exception class for handling concurrent agent operations
205
-
206
- ### Changed
207
-
208
- - Agent now throws `AgentBusyError` instead of generic `Error` when attempting concurrent operations
209
-
210
- ## [12.8.0] - 2026-02-16
211
-
212
- ### Added
213
-
214
- - Added `transformToolCallArguments` option to `AgentOptions` and `AgentLoopConfig` for transforming tool call arguments before execution (e.g. secret deobfuscation)
215
-
216
- ## [12.2.0] - 2026-02-13
217
-
218
- ### Added
219
-
220
- - Added `providerSessionState` option to share provider state map for session-scoped transport and session caches
221
- - Added `preferWebsockets` option to hint that websocket transport should be preferred when supported by the provider implementation
222
-
223
- ## [11.10.0] - 2026-02-10
224
-
225
- ### Added
226
-
227
- - Added `temperature` option to `AgentOptions` to control LLM sampling temperature
228
- - Added `temperature` getter and setter to `Agent` class for runtime configuration
229
-
230
- ## [11.6.0] - 2026-02-07
231
-
232
- ### Added
233
-
234
- - Added `hasQueuedMessages()` method to check for pending steering/follow-up messages
235
- - Resume queued steering and follow-up messages from `continue()` after auto-compaction
236
-
237
- ### Changed
238
-
239
- - Extracted `dequeueSteeringMessages()` and `dequeueFollowUpMessages()` from inline config callbacks
240
- - Added `skipInitialSteeringPoll` option to `_runLoop()` for correct queue resume ordering
241
-
242
- ## [11.3.0] - 2026-02-06
243
-
244
- ### Added
245
-
246
- - Added `maxRetryDelayMs` option to AgentOptions to cap server-requested retry delays, allowing higher-level retry logic to handle long waits with user visibility
247
-
248
- ### Changed
249
-
250
- - Updated ThinkingLevel documentation to include support for gpt-5.3 and gpt-5.3-codex models with 'xhigh' thinking level
251
-
252
- ## [11.2.0] - 2026-02-05
253
-
254
- ### Fixed
255
-
256
- - Fixed handling of aborted requests to properly throw abort errors when stream terminates without a terminal event
257
-
258
- ## [10.5.0] - 2026-02-04
259
-
260
- ### Added
261
-
262
- - Added `concurrency` option to `AgentTool` to control tool scheduling: "shared" (default, runs in parallel) or "exclusive" (runs alone)
263
- - Implemented parallel execution of shared tools within a single agent turn for improved performance
264
-
265
- ### Changed
266
-
267
- - Refactored tool execution to support concurrent scheduling with proper interrupt handling and steering message checks
5
+ - 版本线推进至 1.2.0;本版无独立用户可见变化。
268
6
 
269
7
  ## [9.2.2] - 2026-01-31
270
8
 
@@ -396,6 +134,10 @@
396
134
 
397
135
  Initial release under @oh-my-pi scope. See previous releases at [badlogic/pi-mono](https://github.com/badlogic/pi-mono).
398
136
 
137
+ ## [1.1.27] - 2026-10-07
138
+
139
+ - 版本线推进至 1.1.27;本版无独立用户可见变化。
140
+
399
141
  ## [1.1.25] - 2026-10-03
400
142
 
401
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.
@@ -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. */
@@ -457,12 +463,19 @@ export declare class Agent {
457
463
  /**
458
464
  * Provide a source of non-interrupting "aside" messages (e.g. background-job
459
465
  * completions, late LSP diagnostics) drained at each step boundary. Never
460
- * 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`.
461
468
  */
462
469
  setAsideMessageProvider(fn: (() => AsideMessage[] | Promise<AsideMessage[]>) | undefined): void;
463
470
  emitExternalEvent(event: AgentEvent): void;
464
471
  setSystemPrompt(v: string[] | string): void;
465
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;
466
479
  setThinkingLevel(l: Effort | undefined): void;
467
480
  setDisableReasoning(disabled: boolean): void;
468
481
  setSteeringMode(mode: "all" | "one-at-a-time"): void;
@@ -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
  /**
@@ -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.
@@ -194,7 +202,7 @@ export interface SummaryOptions {
194
202
  /**
195
203
  * Optional telemetry handle. When provided, every LLM call emitted during
196
204
  * compaction is wrapped in an OTEL chat span tagged with
197
- * `omp.gen_ai.oneshot.kind` (`compaction_summary`, `compaction_short_summary`,
205
+ * `zeta.gen_ai.oneshot.kind` (`compaction_summary`, `compaction_short_summary`,
198
206
  * or `compaction_turn_prefix`). `undefined` keeps the call paths zero-cost.
199
207
  */
200
208
  telemetry?: AgentTelemetry;
@@ -257,7 +265,7 @@ export interface HandoffOptions {
257
265
  metadata?: Record<string, unknown>;
258
266
  /**
259
267
  * Optional telemetry handle. When provided, the handoff LLM call is
260
- * 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"`.
261
269
  */
262
270
  telemetry?: AgentTelemetry;
263
271
  /**
@@ -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;
@@ -4,8 +4,26 @@
4
4
  import type { ToolResultMessage } from "@linxiraos/pi-ai";
5
5
  import type { Tokenizer } from "../tokenizer.js";
6
6
  import type { SessionEntry } from "./entries.js";
7
+ import { type ConvertToLlm } from "./messages.js";
7
8
  import { type ProtectedToolMatcher } from "./tool-protection.js";
8
- export interface PruneConfig {
9
+ /** Bound warm-cache pruning by the provider's prompt-cache lookback window. */
10
+ export interface CacheLookbackConfig {
11
+ /**
12
+ * Prompt-cache lookback of the model the next request goes to, in block
13
+ * positions (catalog `prompt-cache-lookback`; Anthropic: 20). When set,
14
+ * warm-cache pruning also leaves a result whose rewrite would put the next
15
+ * request's cache lookup out of reach, whatever its token suffix (see
16
+ * `cacheLookbackFloor`). Undefined = no lookback bound.
17
+ */
18
+ cacheLookbackPositions?: number;
19
+ /**
20
+ * Projects context messages to what the provider receives, so lookback
21
+ * positions count app roles (file mentions, command output, custom
22
+ * messages) as sent. Default {@link defaultConvertToLlm}.
23
+ */
24
+ convertToLlm?: ConvertToLlm;
25
+ }
26
+ export interface PruneConfig extends CacheLookbackConfig {
9
27
  /** Keep the most recent tool output tokens intact. */
10
28
  protectTokens: number;
11
29
  /** Only prune if total savings meets this threshold. */
@@ -37,7 +55,8 @@ export interface PruneConfig {
37
55
  * already-sent cache prefix: mutating it forces the provider to re-write the
38
56
  * whole suffix (cacheWrite premium). Such results — including superseded and
39
57
  * useless ones, which otherwise bypass {@link protectTokens} — are left for
40
- * compaction/shake (which rebuild the cache anyway) to reclaim. Undefined =
58
+ * compaction/shake (which rebuild the cache anyway) to reclaim, as are
59
+ * results beyond {@link CacheLookbackConfig.cacheLookbackPositions}. Undefined =
41
60
  * no cache guard (legacy: superseded/useless prune at any depth).
42
61
  */
43
62
  cacheWarmSuffixTokens?: number;
@@ -72,7 +91,7 @@ export type SupersedeKeyFn = (toolName: string, args: Record<string, unknown>) =
72
91
  * range reads). A summary, truncated page, or notice is not complete.
73
92
  */
74
93
  export type SupersedeCompleteFn = (message: ToolResultMessage) => boolean;
75
- export interface SupersedePruneConfig {
94
+ export interface SupersedePruneConfig extends CacheLookbackConfig {
76
95
  /** Supersede key function; a newer successful result with the same key supersedes older ones (see {@link SupersedeKeyFn}). */
77
96
  supersedeKey?: SupersedeKeyFn;
78
97
  /**
@@ -90,7 +109,11 @@ export interface SupersedePruneConfig {
90
109
  supersedeComplete?: SupersedeCompleteFn;
91
110
  /** Also prune results flagged useless by their tool. Default false. */
92
111
  pruneUseless?: boolean;
93
- /** Prune a candidate now when all messages after it total at most this many estimated tokens. Default 8 000. */
112
+ /**
113
+ * Prune a candidate now when all messages after it total at most this many
114
+ * estimated tokens and it sits within
115
+ * {@link CacheLookbackConfig.cacheLookbackPositions}. Default 8 000.
116
+ */
94
117
  suffixTokenLimit?: number;
95
118
  /**
96
119
  * Prune all candidates when the last message is at least this old: the
@@ -127,10 +150,11 @@ export declare const MIN_PRUNE_TOKENS = 50;
127
150
  * candidate is pruned now only when the suffix after it is small (tail case —
128
151
  * the read→edit→read loop) or when the context has been idle long enough that
129
152
  * the provider cache is cold anyway (then all still-sent candidates flush).
130
- * Never mutates entries before `keepBoundaryId` (summarized away — not sent).
153
+ * Never mutates entries before `keepBoundaryId` (summarized away — not sent),
154
+ * and never walks them unless a sent result's call lives there.
131
155
  */
132
- export declare function pruneSupersededToolResults(entries: SessionEntry[], tokenizer: Tokenizer, config: SupersedePruneConfig): PruneResult;
133
- export declare function pruneToolOutputs(entries: SessionEntry[], tokenizer: Tokenizer, config?: PruneConfig): PruneResult;
156
+ export declare function pruneSupersededToolResults(entries: readonly SessionEntry[], tokenizer: Tokenizer, config: SupersedePruneConfig): PruneResult;
157
+ export declare function pruneToolOutputs(entries: readonly SessionEntry[], tokenizer: Tokenizer, config?: PruneConfig): PruneResult;
134
158
  /**
135
159
  * Supersede key for the `read` tool: the file path with the trailing line/raw
136
160
  * selector stripped (the read tool's own splitter grammar via
@@ -6,7 +6,8 @@ export interface ProtectedToolContext {
6
6
  readonly toolCall: AgentToolCall | undefined;
7
7
  }
8
8
  export type ProtectedToolMatcher = string | ((context: ProtectedToolContext) => boolean);
9
- export declare function collectToolCallsById(entries: readonly SessionEntry[]): Map<string, AgentToolCall>;
9
+ /** Map tool-call ids to their calls across `entries[start, end)` (later calls win). */
10
+ export declare function collectToolCallsById(entries: readonly SessionEntry[], start?: number, end?: number): Map<string, AgentToolCall>;
10
11
  /** Return the tool-result message carried by a session entry, if any. */
11
12
  export declare function getToolResultMessage(entry: SessionEntry): ToolResultMessage | undefined;
12
13
  /**
@@ -13,5 +13,6 @@ export * from "./telemetry.js";
13
13
  export * from "./thinking.js";
14
14
  export * from "./tool-context.js";
15
15
  export * from "./tokenizer.js";
16
+ export * from "./tool-arguments.js";
16
17
  export * from "./types.js";
17
18
  export * from "./utils/yield.js";
@@ -1,4 +1,4 @@
1
- import { type AssistantMessage } from "@linxiraos/pi-ai";
1
+ import type { AssistantMessage } from "@linxiraos/pi-ai";
2
2
  import type { AgentContext, AgentLoopConfig, AgentTool, AgentToolCall, AgentToolResult, SpeculativeAuthorization, SpeculativeChildDefinition, SpeculativeChildHandle, SpeculativeLaunchContext, SpeculativeToolExecutionConfig, ToolSpeculationEffect, ToolSpeculationStreamSession } from "./types.js";
3
3
  export type SpeculativeRawOutcome = {
4
4
  result: AgentToolResult<unknown>;