agent-accelerator 0.2.0 → 0.3.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.
- package/README.md +94 -14
- package/package.json +1 -1
- package/src/agent/agent.ts +194 -2
- package/src/agent/delegation.ts +388 -24
- package/src/agent/loop.ts +112 -5
- package/src/index.ts +34 -2
- package/src/models/catalog.ts +4 -3
- package/src/providers.ts +11 -9
- package/src/session/store.ts +806 -0
- package/src/tools/executor.ts +4 -1
- package/src/types/agent.ts +25 -1
- package/src/types/core.ts +2 -1
- package/src/types/response.ts +24 -0
- package/src/types/tool.ts +2 -0
- package/src/utils/session.ts +36 -0
package/src/tools/executor.ts
CHANGED
|
@@ -13,6 +13,8 @@ export interface ExecuteToolsOptions {
|
|
|
13
13
|
parallel?: boolean;
|
|
14
14
|
signal?: AbortSignal;
|
|
15
15
|
sessionId?: string;
|
|
16
|
+
/** Forwards live sub-agent deltas (realtime worker thinking/text) to the caller. */
|
|
17
|
+
onSubagentEvent?: (event: { trackingId: string; delta?: string; thinkingDelta?: string; partialText?: string; partialThinking?: string }) => void;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
const DEFAULT_TOOL_CONCURRENCY = 8;
|
|
@@ -233,7 +235,7 @@ async function executeAttempt(
|
|
|
233
235
|
export async function executeToolCalls(
|
|
234
236
|
options: ExecuteToolsOptions
|
|
235
237
|
): Promise<ToolResultRecord[]> {
|
|
236
|
-
const { tools, toolCalls, agentName, parallel = true, signal, sessionId } = options;
|
|
238
|
+
const { tools, toolCalls, agentName, parallel = true, signal, sessionId, onSubagentEvent } = options;
|
|
237
239
|
const globalSemaphore = new Semaphore(DEFAULT_TOOL_CONCURRENCY);
|
|
238
240
|
const perToolSemaphores = new Map<string, Semaphore>();
|
|
239
241
|
|
|
@@ -282,6 +284,7 @@ export async function executeToolCalls(
|
|
|
282
284
|
agentName,
|
|
283
285
|
signal,
|
|
284
286
|
sessionId,
|
|
287
|
+
onSubagentEvent,
|
|
285
288
|
};
|
|
286
289
|
|
|
287
290
|
// Validate input if Zod schema is provided
|
package/src/types/agent.ts
CHANGED
|
@@ -45,12 +45,20 @@ export interface AgentConfig {
|
|
|
45
45
|
sessionId?: string;
|
|
46
46
|
/** Headers merged into every provider request. */
|
|
47
47
|
headers?: Record<string, string>;
|
|
48
|
-
/** Maximum model/tool turns per run.
|
|
48
|
+
/** Maximum model/tool turns per run. `0` or omitted means infinite. */
|
|
49
49
|
maxTurns?: number;
|
|
50
50
|
/** Fixed worker agents exposed as delegation tools. */
|
|
51
51
|
subagents?: (Agent | { name: string; description: string; agent: Agent })[];
|
|
52
52
|
/** Clears conversation state before and after every run. */
|
|
53
53
|
stateless?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Durable session persistence: when set, the session file is rewritten
|
|
56
|
+
* after every step (user turn, assistant turn, tool batch, sub-agent
|
|
57
|
+
* step) so a crash loses at most the in-flight step. Pass `{ dir }` for
|
|
58
|
+
* `sessions/<sessionId>/session.json` layout or `{ file }` for a single
|
|
59
|
+
* pretty `.session.json` file. Writes are atomic and never fail a turn.
|
|
60
|
+
*/
|
|
61
|
+
persist?: { dir?: string; file?: string };
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
/** Developer-configured policy for LLM-spawned dynamic sub-agents. */
|
|
@@ -91,4 +99,20 @@ export interface AgentRunOptions {
|
|
|
91
99
|
onEvent?: (event: import("./response.ts").StreamEvent) => void;
|
|
92
100
|
/** When true, wraps reasoning stream as <think>\n...\n</think>\n\n — no manual isThinking needed. */
|
|
93
101
|
wrapThinking?: boolean;
|
|
102
|
+
/** Called after every model/tool turn with a turn summary (also drives sub-agent step logs + durable persistence). */
|
|
103
|
+
onTurn?: (turn: AgentTurnEvent) => void;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Turn summary emitted to `AgentRunOptions.onTurn` after each loop turn. */
|
|
107
|
+
export interface AgentTurnEvent {
|
|
108
|
+
/** 1-based turn count within this run. */
|
|
109
|
+
turns: number;
|
|
110
|
+
/** Assistant text produced this turn, if any. */
|
|
111
|
+
text?: string;
|
|
112
|
+
/** Reasoning produced this turn, if any. */
|
|
113
|
+
thinking?: string;
|
|
114
|
+
/** Tool calls requested this turn, if any. */
|
|
115
|
+
toolCalls?: Array<{ id: string; name: string }>;
|
|
116
|
+
/** Tool results executed this turn, if any. */
|
|
117
|
+
toolResults?: Array<{ id: string; name: string; isError?: boolean }>;
|
|
94
118
|
}
|
package/src/types/core.ts
CHANGED
package/src/types/response.ts
CHANGED
|
@@ -2,6 +2,19 @@ import type { TokenUsage } from "./core.ts";
|
|
|
2
2
|
import type { ToolCallRecord, ToolResultRecord } from "./tool.ts";
|
|
3
3
|
import type { ProviderRawData, ProviderId } from "./model.ts";
|
|
4
4
|
|
|
5
|
+
/** One logged step inside a sub-agent worker run (surfaced via `agent.track(id)`). */
|
|
6
|
+
export interface SubAgentStep {
|
|
7
|
+
turn: number;
|
|
8
|
+
type: "assistant" | "tool_call" | "tool_result";
|
|
9
|
+
name?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
thinking?: string;
|
|
12
|
+
isError?: boolean;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
/** True while the worker is still streaming this step; finalized on turn end. */
|
|
15
|
+
partial?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
5
18
|
/** Per-worker result and usage metadata attached to an AgentResponse. */
|
|
6
19
|
export interface SubAgentExecutionMetadata {
|
|
7
20
|
name: string;
|
|
@@ -20,6 +33,14 @@ export interface SubAgentExecutionMetadata {
|
|
|
20
33
|
raw?: ProviderRawData;
|
|
21
34
|
isError?: boolean;
|
|
22
35
|
error?: string;
|
|
36
|
+
/** Stable display id: `SUBAGENT-NAME-{TrackingID}` (32-char hex, see `createTrackingId`). */
|
|
37
|
+
trackingId?: string;
|
|
38
|
+
/** Provider session id used by this worker (≤64 chars, affinity-safe). */
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
/** Parent session this worker was spawned from. */
|
|
41
|
+
parentSessionId?: string;
|
|
42
|
+
/** Ordered step log for this worker (also persisted in the session file). */
|
|
43
|
+
steps?: SubAgentStep[];
|
|
23
44
|
}
|
|
24
45
|
|
|
25
46
|
/** JSON representation returned by AgentResponse.toJSON(). */
|
|
@@ -136,6 +157,7 @@ export type StreamEventType =
|
|
|
136
157
|
| "tool_call_complete"
|
|
137
158
|
| "tool_result"
|
|
138
159
|
| "subagent_complete"
|
|
160
|
+
| "subagent_delta"
|
|
139
161
|
| "usage"
|
|
140
162
|
| "done"
|
|
141
163
|
| "error";
|
|
@@ -148,6 +170,8 @@ export interface StreamEvent {
|
|
|
148
170
|
toolCall?: ToolCallRecord;
|
|
149
171
|
toolResult?: ToolResultRecord;
|
|
150
172
|
subagent?: SubAgentExecutionMetadata;
|
|
173
|
+
/** Tracking id of the worker emitting a `subagent_delta` event. */
|
|
174
|
+
subagentTrackingId?: string;
|
|
151
175
|
usage?: TokenUsage;
|
|
152
176
|
responseId?: string;
|
|
153
177
|
finishReason?: string;
|
package/src/types/tool.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface ToolExecutionContext {
|
|
|
9
9
|
signal?: AbortSignal;
|
|
10
10
|
/** Session identifier associated with this invocation. */
|
|
11
11
|
sessionId?: string;
|
|
12
|
+
/** Forwards live sub-agent deltas (used by `spawn_subagents` for realtime tracking). */
|
|
13
|
+
onSubagentEvent?: (event: { trackingId: string; delta?: string; thinkingDelta?: string; partialText?: string; partialThinking?: string }) => void;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export type ToolExecuteFn<TInput = any, TOutput = any> = (
|
package/src/utils/session.ts
CHANGED
|
@@ -24,3 +24,39 @@ export function createSessionId(prefix = "accel"): string {
|
|
|
24
24
|
}
|
|
25
25
|
return clampCacheKey(id) || id;
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Short stable hash (FNV-1a, 8 hex chars) for embedding parent lineage
|
|
30
|
+
* into truncated child session IDs without extra dependencies.
|
|
31
|
+
*/
|
|
32
|
+
export function hashSessionPart(value: string): string {
|
|
33
|
+
let h = 0x811c9dc5;
|
|
34
|
+
for (let i = 0; i < value.length; i++) {
|
|
35
|
+
h ^= value.charCodeAt(i);
|
|
36
|
+
h = Math.imul(h, 0x01000193);
|
|
37
|
+
}
|
|
38
|
+
return (h >>> 0).toString(16).padStart(8, "0");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* System-generated 32-char TrackingID for one sub-agent (lowercase hex, no
|
|
43
|
+
* dashes). Surfaced as the suffix in `SUBAGENT-NAME-{TrackingID}` display ids
|
|
44
|
+
* so `agent.track(id)` can address one worker among many concurrent ones.
|
|
45
|
+
*/
|
|
46
|
+
export function createTrackingId(): string {
|
|
47
|
+
try {
|
|
48
|
+
const c = (globalThis as any)?.crypto;
|
|
49
|
+
if (c && typeof c.randomUUID === "function") {
|
|
50
|
+
return String(c.randomUUID()).replace(/-/g, "").slice(0, 32);
|
|
51
|
+
}
|
|
52
|
+
} catch {}
|
|
53
|
+
try {
|
|
54
|
+
const nodeCrypto: any = (globalThis as any)?.process?.getBuiltinModule?.("node:crypto") ?? null;
|
|
55
|
+
if (nodeCrypto?.randomUUID) {
|
|
56
|
+
return String(nodeCrypto.randomUUID()).replace(/-/g, "").slice(0, 32);
|
|
57
|
+
}
|
|
58
|
+
} catch {}
|
|
59
|
+
let out = "";
|
|
60
|
+
while (out.length < 32) out += Math.random().toString(16).slice(2);
|
|
61
|
+
return out.slice(0, 32);
|
|
62
|
+
}
|