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.
@@ -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
@@ -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. Defaults to 10. */
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
@@ -9,7 +9,8 @@ export type ThinkingLevel =
9
9
  | "low"
10
10
  | "medium"
11
11
  | "high"
12
- | "xhigh";
12
+ | "xhigh"
13
+ | "max";
13
14
 
14
15
  // Internal normalized config (SDK-internal, not exposed as Agent flag)
15
16
  /** Internal normalized reasoning configuration passed to providers. */
@@ -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> = (
@@ -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
+ }