@vauban-org/agent-sdk 1.6.4 → 1.7.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.
@@ -32,7 +32,7 @@ export { alwaysOn } from "./guards/always-on.js";
32
32
  export type { ImageMediaType, AudioMediaType, MultiModalObservation, AnthropicTextBlock, AnthropicImageBlock, AnthropicDocumentBlock, AnthropicContentBlock, } from "./multimodal.js";
33
33
  export { isMultiModal, multiModalToAnthropicContent } from "./multimodal.js";
34
34
  export type { ChildAgentPort, ChildAgentOptions, ChildAgentResult, } from "./child-agent.js";
35
- export type { ToolCall, ReactStep, ReactResult, LLMCompletionFn, ReactMessage, LLMReactResponse, ReactLoopOptions, } from "./react-loop.js";
35
+ export type { ToolCall, ReactStep, ReactResult, LLMCompletionFn, ReactMessage, LLMReactResponse, ReactLoopOptions, ReactStepMeta, ReactLoopLogger, } from "./react-loop.js";
36
36
  export { reactLoop } from "./react-loop.js";
37
37
  export type { PlanStep, Plan, StepResult, PlanExecutionResult, } from "./plan-execute.js";
38
38
  export { decomposeTask, executeStep } from "./plan-execute.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/orchestration/ooda/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/orchestration/ooda/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/orchestration/ooda/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAU/C,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,wFAAwF;AACxF,OAAO,EACL,aAAa,EACb,eAAe,EACf,YAAY,GACb,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAQrD,OAAO,EACL,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD,yEAAyE;AACzE,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mCAAmC,CAAC;AAO3C,2DAA2D;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAYjD,OAAO,EAAE,YAAY,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAmB7E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAS5C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAI/D,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAStE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtE,2CAA2C;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/orchestration/ooda/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAU/C,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,wFAAwF;AACxF,OAAO,EACL,aAAa,EACb,eAAe,EACf,YAAY,GACb,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAQrD,OAAO,EACL,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD,yEAAyE;AACzE,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,mCAAmC,CAAC;AAO3C,2DAA2D;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAYjD,OAAO,EAAE,YAAY,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAqB7E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAS5C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAI/D,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAStE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtE,2CAA2C;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -67,6 +67,29 @@ export interface LLMReactResponse {
67
67
  /** Whether this is a final answer (no tool calls). */
68
68
  isFinal: boolean;
69
69
  }
70
+ /**
71
+ * Per-iteration telemetry callback metadata.
72
+ *
73
+ * @since 1.7.0
74
+ * @public
75
+ */
76
+ export interface ReactStepMeta {
77
+ /** Iteration index (mirrors `step.index`). */
78
+ iteration: number;
79
+ /** Wall-clock duration of the iteration in milliseconds. */
80
+ durationMs: number;
81
+ /** Caller-supplied correlation id from `ReactLoopOptions.loopId`. */
82
+ loopId?: string;
83
+ }
84
+ /**
85
+ * Minimal logger contract for swallowed onStep errors.
86
+ *
87
+ * @since 1.7.0
88
+ * @public
89
+ */
90
+ export interface ReactLoopLogger {
91
+ warn: (msg: string, meta?: Record<string, unknown>) => void;
92
+ }
70
93
  export interface ReactLoopOptions {
71
94
  /** Max steps before forced stop (default: 10). */
72
95
  maxSteps?: number;
@@ -84,6 +107,29 @@ export interface ReactLoopOptions {
84
107
  maxToolCallSize?: number;
85
108
  /** Allowed tool names. Unlisted tools get an error feedback. */
86
109
  allowedTools?: string[];
110
+ /**
111
+ * Called after each iteration with the completed step + timing.
112
+ * Fire-and-forget — errors caught + logged via opts.logger, never
113
+ * propagate to the loop. Use this to emit ctx.insertStep telemetry.
114
+ *
115
+ * @since 1.7.0
116
+ */
117
+ onStep?: (step: ReactStep, meta: ReactStepMeta) => void | Promise<void>;
118
+ /**
119
+ * Optional correlation id propagated into `meta.loopId` of every
120
+ * `onStep` call, so callers can correlate multiple reactLoops within
121
+ * one OODA cycle.
122
+ *
123
+ * @since 1.7.0
124
+ */
125
+ loopId?: string;
126
+ /**
127
+ * Logger used when `onStep` throws / rejects. Defaults to no-op
128
+ * (errors are silently swallowed).
129
+ *
130
+ * @since 1.7.0
131
+ */
132
+ logger?: ReactLoopLogger;
87
133
  }
88
134
  /**
89
135
  * Run a ReAct (Reasoning + Acting) loop.
@@ -1 +1 @@
1
- {"version":3,"file":"react-loop.d.ts","sourceRoot":"","sources":["../../../src/orchestration/ooda/react-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,WAAW,QAAQ;IACvB,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,SAAS;IACxB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,QAAQ,EAAE,YAAY,EAAE,KACrB,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE/B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,GAAG,EAAE,eAAe,CAAC;IACrB,iDAAiD;IACjD,WAAW,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,oCAAoC;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AASD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CA8E5E"}
1
+ {"version":3,"file":"react-loop.d.ts","sourceRoot":"","sources":["../../../src/orchestration/ooda/react-loop.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,29 @@
18
18
  // ─── Constants ──────────────────────────────────────────────────────────────────
19
19
  const DEFAULT_MAX_STEPS = 10;
20
20
  const DEFAULT_MAX_TOOL_CALL_SIZE = 10_240; // 10KB
21
+ // ─── Helpers ────────────────────────────────────────────────────────────────────
22
+ /**
23
+ * Invoke the user-supplied `onStep` callback with try/catch. Errors are
24
+ * logged via `opts.logger?.warn` and never propagate to the caller.
25
+ *
26
+ * Handles both sync void and async returns.
27
+ */
28
+ async function safeOnStep(cb, step, meta, logger) {
29
+ try {
30
+ const ret = cb(step, meta);
31
+ if (ret && typeof ret.then === "function") {
32
+ await ret;
33
+ }
34
+ }
35
+ catch (err) {
36
+ const message = err instanceof Error ? err.message : String(err);
37
+ logger?.warn?.("reactLoop.onStep threw — error swallowed", {
38
+ iteration: meta.iteration,
39
+ loopId: meta.loopId,
40
+ error: message,
41
+ });
42
+ }
43
+ }
21
44
  // ─── Loop ───────────────────────────────────────────────────────────────────────
22
45
  /**
23
46
  * Run a ReAct (Reasoning + Acting) loop.
@@ -35,10 +58,19 @@ export async function reactLoop(opts) {
35
58
  { role: "system", content: opts.systemPrompt },
36
59
  { role: "user", content: opts.task },
37
60
  ];
61
+ const { onStep, loopId, logger } = opts;
62
+ /** Build telemetry meta for iteration `i`, given its start timestamp. */
63
+ const buildMeta = (i, iterationStart) => ({
64
+ iteration: i,
65
+ durationMs: Date.now() - iterationStart,
66
+ loopId,
67
+ });
38
68
  for (let i = 0; i < maxSteps; i++) {
39
69
  if (opts.signal?.aborted) {
70
+ // Aborted iteration — step is not finalized, onStep is NOT called.
40
71
  return { answer: "", steps, totalSteps: i, truncated: true };
41
72
  }
73
+ const iterationStart = Date.now();
42
74
  // Thought → Action
43
75
  const response = await opts.llm(messages);
44
76
  steps.push({
@@ -47,8 +79,18 @@ export async function reactLoop(opts) {
47
79
  action: response.toolCalls?.[0],
48
80
  });
49
81
  // Final answer — no tool call
50
- if (response.isFinal || !response.toolCalls || response.toolCalls.length === 0) {
51
- return { answer: response.content, steps, totalSteps: i + 1, truncated: false };
82
+ if (response.isFinal ||
83
+ !response.toolCalls ||
84
+ response.toolCalls.length === 0) {
85
+ if (onStep) {
86
+ await safeOnStep(onStep, steps[i], buildMeta(i, iterationStart), logger);
87
+ }
88
+ return {
89
+ answer: response.content,
90
+ steps,
91
+ totalSteps: i + 1,
92
+ truncated: false,
93
+ };
52
94
  }
53
95
  const toolCall = response.toolCalls[0];
54
96
  // Validate tool call size
@@ -56,14 +98,28 @@ export async function reactLoop(opts) {
56
98
  if (toolJson.length > maxToolCallSize) {
57
99
  steps[i].error = `Tool call exceeds ${maxToolCallSize}B limit`;
58
100
  steps[i].observation = `Error: tool call too large (${toolJson.length}B > ${maxToolCallSize}B limit)`;
59
- messages.push({ role: "assistant", content: response.content, name: toolCall.tool }, { role: "tool", content: steps[i].observation, tool_call_id: `call_${i}` });
101
+ messages.push({ role: "assistant", content: response.content, name: toolCall.tool }, {
102
+ role: "tool",
103
+ content: steps[i].observation,
104
+ tool_call_id: `call_${i}`,
105
+ });
106
+ if (onStep) {
107
+ await safeOnStep(onStep, steps[i], buildMeta(i, iterationStart), logger);
108
+ }
60
109
  continue;
61
110
  }
62
111
  // Check allowed tools
63
112
  if (allowedTools && !allowedTools.includes(toolCall.tool)) {
64
113
  steps[i].error = `Tool "${toolCall.tool}" not in allowed list`;
65
114
  steps[i].observation = `Error: tool "${toolCall.tool}" is not allowed. Available tools: ${allowedTools.join(", ")}`;
66
- messages.push({ role: "assistant", content: response.content, name: toolCall.tool }, { role: "tool", content: steps[i].observation, tool_call_id: `call_${i}` });
115
+ messages.push({ role: "assistant", content: response.content, name: toolCall.tool }, {
116
+ role: "tool",
117
+ content: steps[i].observation,
118
+ tool_call_id: `call_${i}`,
119
+ });
120
+ if (onStep) {
121
+ await safeOnStep(onStep, steps[i], buildMeta(i, iterationStart), logger);
122
+ }
67
123
  continue;
68
124
  }
69
125
  // Observation — execute tool
@@ -76,7 +132,15 @@ export async function reactLoop(opts) {
76
132
  steps[i].observation = `Error executing tool "${toolCall.tool}": ${steps[i].error}`;
77
133
  }
78
134
  // Feed observation back into the conversation
79
- messages.push({ role: "assistant", content: response.content, name: toolCall.tool }, { role: "tool", content: steps[i].observation, tool_call_id: `call_${i}` });
135
+ messages.push({ role: "assistant", content: response.content, name: toolCall.tool }, {
136
+ role: "tool",
137
+ content: steps[i].observation,
138
+ tool_call_id: `call_${i}`,
139
+ });
140
+ // Step is fully finalized (thought + action + observation/error).
141
+ if (onStep) {
142
+ await safeOnStep(onStep, steps[i], buildMeta(i, iterationStart), logger);
143
+ }
80
144
  }
81
145
  // Truncated — max steps reached
82
146
  const lastStep = steps[steps.length - 1];
@@ -1 +1 @@
1
- {"version":3,"file":"react-loop.js","sourceRoot":"","sources":["../../../src/orchestration/ooda/react-loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react-loop.js","sourceRoot":"","sources":["../../../src/orchestration/ooda/react-loop.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vauban-org/agent-sdk",
3
- "version": "1.6.4",
3
+ "version": "1.7.0",
4
4
  "description": "Vauban agent primitives: loop, budget, routing, HITL, permissions, tracking, durable execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -114,7 +114,7 @@ export type {
114
114
  ChildAgentResult,
115
115
  } from "./child-agent.js";
116
116
 
117
- // ReactLoop — sprint-565:3
117
+ // ReactLoop — sprint-565:3 (+ 1.7.0 onStep telemetry)
118
118
  export type {
119
119
  ToolCall,
120
120
  ReactStep,
@@ -123,6 +123,8 @@ export type {
123
123
  ReactMessage,
124
124
  LLMReactResponse,
125
125
  ReactLoopOptions,
126
+ ReactStepMeta,
127
+ ReactLoopLogger,
126
128
  } from "./react-loop.js";
127
129
  export { reactLoop } from "./react-loop.js";
128
130
 
@@ -78,6 +78,31 @@ export interface LLMReactResponse {
78
78
  isFinal: boolean;
79
79
  }
80
80
 
81
+ /**
82
+ * Per-iteration telemetry callback metadata.
83
+ *
84
+ * @since 1.7.0
85
+ * @public
86
+ */
87
+ export interface ReactStepMeta {
88
+ /** Iteration index (mirrors `step.index`). */
89
+ iteration: number;
90
+ /** Wall-clock duration of the iteration in milliseconds. */
91
+ durationMs: number;
92
+ /** Caller-supplied correlation id from `ReactLoopOptions.loopId`. */
93
+ loopId?: string;
94
+ }
95
+
96
+ /**
97
+ * Minimal logger contract for swallowed onStep errors.
98
+ *
99
+ * @since 1.7.0
100
+ * @public
101
+ */
102
+ export interface ReactLoopLogger {
103
+ warn: (msg: string, meta?: Record<string, unknown>) => void;
104
+ }
105
+
81
106
  export interface ReactLoopOptions {
82
107
  /** Max steps before forced stop (default: 10). */
83
108
  maxSteps?: number;
@@ -95,6 +120,29 @@ export interface ReactLoopOptions {
95
120
  maxToolCallSize?: number;
96
121
  /** Allowed tool names. Unlisted tools get an error feedback. */
97
122
  allowedTools?: string[];
123
+ /**
124
+ * Called after each iteration with the completed step + timing.
125
+ * Fire-and-forget — errors caught + logged via opts.logger, never
126
+ * propagate to the loop. Use this to emit ctx.insertStep telemetry.
127
+ *
128
+ * @since 1.7.0
129
+ */
130
+ onStep?: (step: ReactStep, meta: ReactStepMeta) => void | Promise<void>;
131
+ /**
132
+ * Optional correlation id propagated into `meta.loopId` of every
133
+ * `onStep` call, so callers can correlate multiple reactLoops within
134
+ * one OODA cycle.
135
+ *
136
+ * @since 1.7.0
137
+ */
138
+ loopId?: string;
139
+ /**
140
+ * Logger used when `onStep` throws / rejects. Defaults to no-op
141
+ * (errors are silently swallowed).
142
+ *
143
+ * @since 1.7.0
144
+ */
145
+ logger?: ReactLoopLogger;
98
146
  }
99
147
 
100
148
  // ─── Constants ──────────────────────────────────────────────────────────────────
@@ -102,6 +150,35 @@ export interface ReactLoopOptions {
102
150
  const DEFAULT_MAX_STEPS = 10;
103
151
  const DEFAULT_MAX_TOOL_CALL_SIZE = 10_240; // 10KB
104
152
 
153
+ // ─── Helpers ────────────────────────────────────────────────────────────────────
154
+
155
+ /**
156
+ * Invoke the user-supplied `onStep` callback with try/catch. Errors are
157
+ * logged via `opts.logger?.warn` and never propagate to the caller.
158
+ *
159
+ * Handles both sync void and async returns.
160
+ */
161
+ async function safeOnStep(
162
+ cb: NonNullable<ReactLoopOptions["onStep"]>,
163
+ step: ReactStep,
164
+ meta: ReactStepMeta,
165
+ logger: ReactLoopLogger | undefined
166
+ ): Promise<void> {
167
+ try {
168
+ const ret = cb(step, meta);
169
+ if (ret && typeof (ret as Promise<void>).then === "function") {
170
+ await ret;
171
+ }
172
+ } catch (err) {
173
+ const message = err instanceof Error ? err.message : String(err);
174
+ logger?.warn?.("reactLoop.onStep threw — error swallowed", {
175
+ iteration: meta.iteration,
176
+ loopId: meta.loopId,
177
+ error: message,
178
+ });
179
+ }
180
+ }
181
+
105
182
  // ─── Loop ───────────────────────────────────────────────────────────────────────
106
183
 
107
184
  /**
@@ -122,11 +199,23 @@ export async function reactLoop(opts: ReactLoopOptions): Promise<ReactResult> {
122
199
  { role: "user", content: opts.task },
123
200
  ];
124
201
 
202
+ const { onStep, loopId, logger } = opts;
203
+
204
+ /** Build telemetry meta for iteration `i`, given its start timestamp. */
205
+ const buildMeta = (i: number, iterationStart: number): ReactStepMeta => ({
206
+ iteration: i,
207
+ durationMs: Date.now() - iterationStart,
208
+ loopId,
209
+ });
210
+
125
211
  for (let i = 0; i < maxSteps; i++) {
126
212
  if (opts.signal?.aborted) {
213
+ // Aborted iteration — step is not finalized, onStep is NOT called.
127
214
  return { answer: "", steps, totalSteps: i, truncated: true };
128
215
  }
129
216
 
217
+ const iterationStart = Date.now();
218
+
130
219
  // Thought → Action
131
220
  const response = await opts.llm(messages);
132
221
  steps.push({
@@ -136,8 +225,25 @@ export async function reactLoop(opts: ReactLoopOptions): Promise<ReactResult> {
136
225
  });
137
226
 
138
227
  // Final answer — no tool call
139
- if (response.isFinal || !response.toolCalls || response.toolCalls.length === 0) {
140
- return { answer: response.content, steps, totalSteps: i + 1, truncated: false };
228
+ if (
229
+ response.isFinal ||
230
+ !response.toolCalls ||
231
+ response.toolCalls.length === 0
232
+ ) {
233
+ if (onStep) {
234
+ await safeOnStep(
235
+ onStep,
236
+ steps[i],
237
+ buildMeta(i, iterationStart),
238
+ logger
239
+ );
240
+ }
241
+ return {
242
+ answer: response.content,
243
+ steps,
244
+ totalSteps: i + 1,
245
+ truncated: false,
246
+ };
141
247
  }
142
248
 
143
249
  const toolCall = response.toolCalls[0];
@@ -146,22 +252,50 @@ export async function reactLoop(opts: ReactLoopOptions): Promise<ReactResult> {
146
252
  const toolJson = JSON.stringify(toolCall);
147
253
  if (toolJson.length > maxToolCallSize) {
148
254
  steps[i].error = `Tool call exceeds ${maxToolCallSize}B limit`;
149
- steps[i].observation = `Error: tool call too large (${toolJson.length}B > ${maxToolCallSize}B limit)`;
255
+ steps[
256
+ i
257
+ ].observation = `Error: tool call too large (${toolJson.length}B > ${maxToolCallSize}B limit)`;
150
258
  messages.push(
151
259
  { role: "assistant", content: response.content, name: toolCall.tool },
152
- { role: "tool", content: steps[i].observation!, tool_call_id: `call_${i}` }
260
+ {
261
+ role: "tool",
262
+ content: steps[i].observation!,
263
+ tool_call_id: `call_${i}`,
264
+ }
153
265
  );
266
+ if (onStep) {
267
+ await safeOnStep(
268
+ onStep,
269
+ steps[i],
270
+ buildMeta(i, iterationStart),
271
+ logger
272
+ );
273
+ }
154
274
  continue;
155
275
  }
156
276
 
157
277
  // Check allowed tools
158
278
  if (allowedTools && !allowedTools.includes(toolCall.tool)) {
159
279
  steps[i].error = `Tool "${toolCall.tool}" not in allowed list`;
160
- steps[i].observation = `Error: tool "${toolCall.tool}" is not allowed. Available tools: ${allowedTools.join(", ")}`;
280
+ steps[i].observation = `Error: tool "${
281
+ toolCall.tool
282
+ }" is not allowed. Available tools: ${allowedTools.join(", ")}`;
161
283
  messages.push(
162
284
  { role: "assistant", content: response.content, name: toolCall.tool },
163
- { role: "tool", content: steps[i].observation!, tool_call_id: `call_${i}` }
285
+ {
286
+ role: "tool",
287
+ content: steps[i].observation!,
288
+ tool_call_id: `call_${i}`,
289
+ }
164
290
  );
291
+ if (onStep) {
292
+ await safeOnStep(
293
+ onStep,
294
+ steps[i],
295
+ buildMeta(i, iterationStart),
296
+ logger
297
+ );
298
+ }
165
299
  continue;
166
300
  }
167
301
 
@@ -171,14 +305,25 @@ export async function reactLoop(opts: ReactLoopOptions): Promise<ReactResult> {
171
305
  steps[i].observation = observation;
172
306
  } catch (err) {
173
307
  steps[i].error = err instanceof Error ? err.message : String(err);
174
- steps[i].observation = `Error executing tool "${toolCall.tool}": ${steps[i].error}`;
308
+ steps[
309
+ i
310
+ ].observation = `Error executing tool "${toolCall.tool}": ${steps[i].error}`;
175
311
  }
176
312
 
177
313
  // Feed observation back into the conversation
178
314
  messages.push(
179
315
  { role: "assistant", content: response.content, name: toolCall.tool },
180
- { role: "tool", content: steps[i].observation!, tool_call_id: `call_${i}` }
316
+ {
317
+ role: "tool",
318
+ content: steps[i].observation!,
319
+ tool_call_id: `call_${i}`,
320
+ }
181
321
  );
322
+
323
+ // Step is fully finalized (thought + action + observation/error).
324
+ if (onStep) {
325
+ await safeOnStep(onStep, steps[i], buildMeta(i, iterationStart), logger);
326
+ }
182
327
  }
183
328
 
184
329
  // Truncated — max steps reached