@linxiraos/pi-agent-core 1.1.19 → 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.
- package/CHANGELOG.md +253 -10
- package/README.md +4 -3
- package/THIRD-PARTY-NOTICES.txt +3 -40
- package/dist/types/agent-loop.d.ts +14 -1
- package/dist/types/agent.d.ts +36 -0
- package/dist/types/compaction/anthropic.d.ts +22 -52
- package/dist/types/compaction/branch-summarization.d.ts +1 -1
- package/dist/types/compaction/compaction.d.ts +4 -2
- package/dist/types/compaction/messages.d.ts +9 -0
- package/dist/types/compaction/openai.d.ts +11 -0
- package/dist/types/compaction/pruning.d.ts +9 -0
- package/dist/types/compaction/transcript-tokens.d.ts +25 -2
- package/dist/types/index.d.ts +3 -0
- package/dist/types/live-steering.d.ts +34 -0
- package/dist/types/output-budget.d.ts +54 -0
- package/dist/types/sent-tool-definitions.d.ts +17 -0
- package/dist/types/speculative-execution.d.ts +2 -1
- package/dist/types/telemetry.d.ts +103 -60
- package/dist/types/tool-context.d.ts +32 -0
- package/dist/types/types.d.ts +105 -7
- package/package.json +10 -10
- package/src/agent-loop.ts +386 -90
- package/src/agent.ts +175 -26
- package/src/compaction/anthropic.ts +62 -105
- package/src/compaction/branch-summarization.ts +1 -1
- package/src/compaction/compaction-v2-streaming.ts +13 -4
- package/src/compaction/compaction.ts +63 -51
- package/src/compaction/messages.ts +12 -2
- package/src/compaction/openai.ts +37 -9
- package/src/compaction/prompts/anthropic-compaction-instructions.md +2 -6
- package/src/compaction/pruning.ts +1 -1
- package/src/compaction/transcript-tokens.ts +64 -3
- package/src/index.ts +6 -0
- package/src/live-steering.ts +89 -0
- package/src/output-budget.ts +142 -0
- package/src/sent-tool-definitions.ts +40 -0
- package/src/speculative-execution.ts +12 -0
- package/src/telemetry.ts +240 -117
- package/src/tokenizer.ts +45 -6
- package/src/tool-context.ts +55 -0
- package/src/types.ts +109 -7
package/dist/types/types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { Dialect } from "@linxiraos/pi-ai/dialect";
|
|
|
3
3
|
import type { HarmonyAuditEvent } from "@linxiraos/pi-ai/utils/harmony-leak";
|
|
4
4
|
import type { AppendOnlyContextManager } from "./append-only-context.js";
|
|
5
5
|
import type { AgentRunCoverage, AgentRunSummary } from "./run-collector.js";
|
|
6
|
+
import type { SentToolDefinitions } from "./sent-tool-definitions.js";
|
|
6
7
|
import type { AgentTelemetryConfig } from "./telemetry.js";
|
|
7
8
|
/** Stream function - can return sync or Promise for async config lookup */
|
|
8
9
|
export type StreamFn = (...args: Parameters<typeof streamSimple>) => AssistantMessageEventStream | Promise<AssistantMessageEventStream>;
|
|
@@ -35,6 +36,12 @@ export interface AgentTurnEndContext {
|
|
|
35
36
|
message: AgentMessage;
|
|
36
37
|
/** Tool results produced by this turn, already paired with `message` in the live context. */
|
|
37
38
|
toolResults: ToolResultMessage[];
|
|
39
|
+
/**
|
|
40
|
+
* Passive model-visible messages appended after the tool results at this
|
|
41
|
+
* boundary. The agent loop always sends an array (possibly empty);
|
|
42
|
+
* absent is equivalent to empty for hosts that construct the context.
|
|
43
|
+
*/
|
|
44
|
+
additionalMessages?: AgentMessage[];
|
|
38
45
|
/** True when the current tool-loop batch is continuing without yielding to post-turn steering. */
|
|
39
46
|
willContinue: boolean;
|
|
40
47
|
}
|
|
@@ -117,8 +124,10 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
117
124
|
model: Model;
|
|
118
125
|
/**
|
|
119
126
|
* When to interrupt tool execution for steering messages.
|
|
120
|
-
* - "immediate" =
|
|
121
|
-
*
|
|
127
|
+
* - "immediate" = cut interruptible waits short and raise the cooperative
|
|
128
|
+
* `steeringSignal` for other running tools (default)
|
|
129
|
+
* - "wait" = let non-interruptible tools finish undisturbed; interruptible
|
|
130
|
+
* waits are still cut short, since they have no work to complete
|
|
122
131
|
*/
|
|
123
132
|
interruptMode?: "immediate" | "wait";
|
|
124
133
|
/**
|
|
@@ -185,6 +194,8 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
185
194
|
* and provider send.
|
|
186
195
|
*/
|
|
187
196
|
transformProviderContext?: (context: Context, model: Model) => Context | Promise<Context>;
|
|
197
|
+
/** Remembers sent tool definitions to fill {@link Context.inactiveTools}. */
|
|
198
|
+
sentToolDefinitions?: SentToolDefinitions;
|
|
188
199
|
/**
|
|
189
200
|
* Resolves the API key or resolver for the current model before each LLM call.
|
|
190
201
|
*
|
|
@@ -204,8 +215,9 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
204
215
|
/**
|
|
205
216
|
* Peeks whether steering messages are queued, without consuming them.
|
|
206
217
|
*
|
|
207
|
-
* Polled while a tool batch runs (
|
|
208
|
-
* whether to abort in-flight and skip
|
|
218
|
+
* Polled while a tool batch runs (in "wait" mode, only when the batch holds an
|
|
219
|
+
* interruptible tool) to decide whether to abort in-flight and skip
|
|
220
|
+
* not-yet-started *interruptible* waits;
|
|
209
221
|
* every other already-emitted call still executes and the message injects
|
|
210
222
|
* at the batch boundary. The queue keeps
|
|
211
223
|
* owning its messages until the loop reaches the next injection boundary and
|
|
@@ -228,14 +240,35 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
228
240
|
* {@link getSteeringMessages}.
|
|
229
241
|
*/
|
|
230
242
|
waitForSteeringMessages?: (signal?: AbortSignal) => Promise<void>;
|
|
243
|
+
/**
|
|
244
|
+
* Called when live steering dequeues messages via {@link getSteeringMessages}
|
|
245
|
+
* for the response being streamed. The loop records them in the transcript
|
|
246
|
+
* after that response (or its tool batch); an abort before then leaves them
|
|
247
|
+
* unrecorded for the host to requeue.
|
|
248
|
+
*/
|
|
249
|
+
onLiveSteeringTaken?: (messages: AgentMessage[]) => void;
|
|
231
250
|
/**
|
|
232
251
|
* Peeks whether IRC messages should interrupt an interruptible waiting tool.
|
|
233
252
|
*
|
|
234
253
|
* Uses the same delivery rules as steering: the poll is non-consuming, only
|
|
235
|
-
* runs for interruptible tools, and
|
|
254
|
+
* runs for interruptible tools, and cuts them short even when interruptMode
|
|
255
|
+
* is "wait".
|
|
236
256
|
* The host owns message injection at the next boundary.
|
|
237
257
|
*/
|
|
238
258
|
hasIrcInterrupts?: () => boolean | Promise<boolean>;
|
|
259
|
+
/**
|
|
260
|
+
* Peeks whether a background completion (finished job, exited supervised
|
|
261
|
+
* process) is queued for aside injection at the next boundary.
|
|
262
|
+
*
|
|
263
|
+
* Same rules as {@link hasIrcInterrupts}: non-consuming, only cuts
|
|
264
|
+
* *interruptible* waits short, in either interruptMode. Without
|
|
265
|
+
* it a completion notice sits behind an hour-long `wait` that the agent
|
|
266
|
+
* would have abandoned had it seen the notice. Unlike a peer IRC it never
|
|
267
|
+
* raises {@link ToolCallContext.steeringSignal}: a queued completion must
|
|
268
|
+
* not push ordinary foreground work (auto-background bash/eval) into the
|
|
269
|
+
* background.
|
|
270
|
+
*/
|
|
271
|
+
hasBackgroundCompletions?: () => boolean | Promise<boolean>;
|
|
239
272
|
/**
|
|
240
273
|
* Returns follow-up messages to process after the agent would otherwise stop.
|
|
241
274
|
*
|
|
@@ -264,7 +297,11 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
264
297
|
onBeforeYield?: () => Promise<void> | void;
|
|
265
298
|
/**
|
|
266
299
|
* Provides tool execution context, resolved per tool call.
|
|
267
|
-
* Use for late-bound UI or session state access.
|
|
300
|
+
* Use for late-bound UI or session state access. The loop passes the tool
|
|
301
|
+
* call's {@link ToolCallContext}; hosts that support passive tool context
|
|
302
|
+
* surface its `addAdditionalContext` sink as
|
|
303
|
+
* {@link AgentToolContext.addAdditionalContext}. The returned object is
|
|
304
|
+
* handed to the tool as-is.
|
|
268
305
|
*/
|
|
269
306
|
getToolContext?: (toolCall?: ToolCallContext) => AgentToolContext | undefined;
|
|
270
307
|
/**
|
|
@@ -338,6 +375,12 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
338
375
|
* model's text output back into canonical `toolCall` blocks.
|
|
339
376
|
*/
|
|
340
377
|
dialect?: Dialect;
|
|
378
|
+
/**
|
|
379
|
+
* Per-call owned-dialect resolver, read once per LLM call with the model
|
|
380
|
+
* being requested. Authoritative when set: its return value (including
|
|
381
|
+
* `undefined` = native tool calling) replaces the static {@link dialect}.
|
|
382
|
+
*/
|
|
383
|
+
getDialect?: (model: Model) => Dialect | undefined;
|
|
341
384
|
/**
|
|
342
385
|
* When owned (in-band) tool calling is active and the model starts
|
|
343
386
|
* fabricating a tool result inside its own turn, control how the loop reacts:
|
|
@@ -472,6 +515,13 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
472
515
|
* the turn).
|
|
473
516
|
*/
|
|
474
517
|
transformAssistantMessage?: (message: AssistantMessage, signal?: AbortSignal) => Promise<void> | void;
|
|
518
|
+
/**
|
|
519
|
+
* Declares that {@link transformAssistantMessage} never rewrites or removes a
|
|
520
|
+
* tool call the model streamed (it may edit text or append new calls). Stream
|
|
521
|
+
* speculation sessions and direct speculative candidates plan from streamed
|
|
522
|
+
* calls, so they stay disabled under a transform unless this is set.
|
|
523
|
+
*/
|
|
524
|
+
transformAssistantMessagePreservesToolCalls?: boolean;
|
|
475
525
|
/**
|
|
476
526
|
* Called after a tool finishes executing, before `tool_execution_end` and the
|
|
477
527
|
* tool-result message are emitted.
|
|
@@ -515,6 +565,13 @@ export interface ToolCallContext {
|
|
|
515
565
|
* always safe (the message injects at the next batch boundary).
|
|
516
566
|
*/
|
|
517
567
|
steeringSignal?: AbortSignal;
|
|
568
|
+
/**
|
|
569
|
+
* Loop-owned sink for passive context reported while this call executes.
|
|
570
|
+
* Values join the call's context at the batch boundary and are injected
|
|
571
|
+
* after the batch's tool results, in assistant tool-call order, before the
|
|
572
|
+
* next provider request. Blank values are ignored.
|
|
573
|
+
*/
|
|
574
|
+
addAdditionalContext?: (context: string) => void;
|
|
518
575
|
}
|
|
519
576
|
/** A single tool-call content block emitted by an assistant message. */
|
|
520
577
|
export type AgentToolCall = Extract<AssistantMessage["content"][number], {
|
|
@@ -609,8 +666,22 @@ export interface SpeculativeExecutionHost {
|
|
|
609
666
|
validate?(context: SpeculativeCommitContext): boolean | Promise<boolean>;
|
|
610
667
|
commit?(context: SpeculativeCommitContext, commitDefault: () => Promise<AgentToolResult<unknown>>): Promise<SpeculativeCommitDecision>;
|
|
611
668
|
discard?(context: SpeculativeDiscardContext): void | Promise<void>;
|
|
669
|
+
/**
|
|
670
|
+
* Authorize a stream session to start effectful work (e.g. subagents) from
|
|
671
|
+
* partially streamed arguments. The session owns that work and must abort it
|
|
672
|
+
* when the finalized call is invalid, blocked, or changed. Hosts without this
|
|
673
|
+
* hook deny every launch.
|
|
674
|
+
*/
|
|
675
|
+
authorizeLaunch?(context: SpeculativeLaunchContext): SpeculativeAuthorization | Promise<SpeculativeAuthorization>;
|
|
612
676
|
close?(reason: string): void | Promise<void>;
|
|
613
677
|
}
|
|
678
|
+
/** Effectful work a tool-owned stream session asks to start before its outer call dispatches. */
|
|
679
|
+
export interface SpeculativeLaunchContext {
|
|
680
|
+
tool: SpeculativeToolReference;
|
|
681
|
+
toolCall: AgentToolCall;
|
|
682
|
+
/** Arguments the launch was planned from: the streamed prefix of the outer call. */
|
|
683
|
+
args: Readonly<Record<string, unknown>>;
|
|
684
|
+
}
|
|
614
685
|
export interface ToolSpeculationStreamContext {
|
|
615
686
|
readonly coordinator: SpeculativeOperationSink;
|
|
616
687
|
readonly parentToolCallId: string;
|
|
@@ -653,6 +724,8 @@ export interface ToolSpeculationStreamSession {
|
|
|
653
724
|
export interface SpeculativeOperationSink {
|
|
654
725
|
readonly maxInFlight: number;
|
|
655
726
|
admit(definition: SpeculativeChildDefinition): Promise<SpeculativeChildHandle | undefined>;
|
|
727
|
+
/** Host-gated permission for effectful stream work; see {@link SpeculativeExecutionHost.authorizeLaunch}. */
|
|
728
|
+
authorizeLaunch?(context: SpeculativeLaunchContext): Promise<SpeculativeAuthorization>;
|
|
656
729
|
discardChildren?(parentToolCallId: string, reason: string): void | Promise<void>;
|
|
657
730
|
close(reason: string): void | Promise<void>;
|
|
658
731
|
}
|
|
@@ -703,11 +776,20 @@ export interface SpeculativeToolExecutionConfig {
|
|
|
703
776
|
* written back to the tool-call block on the assistant message, and seen by
|
|
704
777
|
* history, scheduling, execution events, and `tool.execute` alike. It is
|
|
705
778
|
* ignored when `block` is true.
|
|
779
|
+
*
|
|
780
|
+
* Set `additionalContext` to attach passive model-visible context to this call.
|
|
781
|
+
* Non-empty values from a tool batch are injected in assistant tool-call order,
|
|
782
|
+
* a value identical to an earlier one in the batch only once,
|
|
783
|
+
* after every result settles and before the next provider request. It is
|
|
784
|
+
* dropped when the call is blocked or skipped, or when its final result is an
|
|
785
|
+
* error (including an approval denial raised by the tool's own gate). Within a
|
|
786
|
+
* call it follows any context the tool reported during execution.
|
|
706
787
|
*/
|
|
707
788
|
export interface BeforeToolCallResult {
|
|
708
789
|
block?: boolean;
|
|
709
790
|
reason?: string;
|
|
710
791
|
args?: Record<string, unknown>;
|
|
792
|
+
additionalContext?: string;
|
|
711
793
|
}
|
|
712
794
|
/**
|
|
713
795
|
* Partial override returned from `afterToolCall`.
|
|
@@ -854,6 +936,16 @@ export type ToolApproval = ToolApprovalDecision | ((args: unknown) => ToolApprov
|
|
|
854
936
|
* Apps can extend via declaration merging.
|
|
855
937
|
*/
|
|
856
938
|
export interface AgentToolContext {
|
|
939
|
+
/**
|
|
940
|
+
* Attach trusted, agent-authored instructions to the next provider request.
|
|
941
|
+
* The host emits them after tool results with developer/system priority where
|
|
942
|
+
* the selected transport supports it. Do not use this channel for raw tool
|
|
943
|
+
* output, retrieved documents, web content, or other untrusted data; return
|
|
944
|
+
* those through the ordinary tool result instead. Hosts populate it from
|
|
945
|
+
* {@link ToolCallContext.addAdditionalContext} (or their own collector for
|
|
946
|
+
* calls dispatched outside the loop); absent when the host has no sink.
|
|
947
|
+
*/
|
|
948
|
+
addAdditionalContext?(context: string): void;
|
|
857
949
|
/** Present only while the matching outer tool owns its finalized stream session. */
|
|
858
950
|
[SPECULATIVE_STREAM_SESSION]?: ToolSpeculationStreamSession;
|
|
859
951
|
}
|
|
@@ -890,6 +982,12 @@ export interface AgentTool<TParameters extends TSchema = TSchema, TDetails = any
|
|
|
890
982
|
loadMode?: ToolLoadMode;
|
|
891
983
|
/** Short one-line summary used for tool discovery indexes. */
|
|
892
984
|
summary?: string;
|
|
985
|
+
/**
|
|
986
|
+
* On-demand documentation topics (`topic → markdown`), readable as
|
|
987
|
+
* `xd://<tool>/<topic>`. Lets a tool keep large sub-surfaces out of its
|
|
988
|
+
* description and advertise only a one-line pointer per topic.
|
|
989
|
+
*/
|
|
990
|
+
docTopics?(): Readonly<Record<string, string>>;
|
|
893
991
|
/**
|
|
894
992
|
* Concurrency mode for tool scheduling when multiple calls are in one turn.
|
|
895
993
|
* - "shared": can run alongside other shared tools (default)
|
|
@@ -913,7 +1011,7 @@ export interface AgentTool<TParameters extends TSchema = TSchema, TDetails = any
|
|
|
913
1011
|
* cleanly (e.g. `job` poll), so the abort surfaces the tool's current
|
|
914
1012
|
* snapshot rather than corrupting a side effect. Every other call runs to
|
|
915
1013
|
* completion even when steering is queued; the message lands at the next
|
|
916
|
-
* batch boundary. Honored
|
|
1014
|
+
* batch boundary. Honored in both `interruptMode`s.
|
|
917
1015
|
*/
|
|
918
1016
|
interruptible?: boolean | ((args: Partial<Static<TParameters>>) => boolean);
|
|
919
1017
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@linxiraos/pi-agent-core",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.22",
|
|
5
5
|
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
|
6
6
|
"homepage": "https://linxira-os.github.io/zeta/",
|
|
7
7
|
"author": "Linxira-OS",
|
|
@@ -35,19 +35,19 @@
|
|
|
35
35
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@
|
|
39
|
-
"@linxiraos/pi-
|
|
40
|
-
"@linxiraos/pi-
|
|
41
|
-
"@linxiraos/pi-
|
|
42
|
-
"@linxiraos/pi-
|
|
43
|
-
"@linxiraos/pi-
|
|
44
|
-
"@
|
|
38
|
+
"@linxiraos/pi-ai": "1.1.22",
|
|
39
|
+
"@linxiraos/pi-catalog": "1.1.22",
|
|
40
|
+
"@linxiraos/pi-natives": "1.1.22",
|
|
41
|
+
"@linxiraos/pi-utils": "1.1.22",
|
|
42
|
+
"@linxiraos/pi-wire": "1.1.22",
|
|
43
|
+
"@linxiraos/pi-snapcompact": "1.1.22",
|
|
44
|
+
"@opentelemetry/api": "^1.9.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
+
"@linxiraos/pi-omptype": "1.1.22",
|
|
47
48
|
"@opentelemetry/context-async-hooks": "^2.9.0",
|
|
48
49
|
"@opentelemetry/sdk-trace-base": "^2.9.0",
|
|
49
|
-
"@types/bun": "^1.3.14"
|
|
50
|
-
"@linxiraos/pi-omptype": "1.1.19"
|
|
50
|
+
"@types/bun": "^1.3.14"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"bun": ">=1.3.14"
|