@strands-agents/sdk 0.4.0 → 0.5.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.
Files changed (141) hide show
  1. package/dist/src/__fixtures__/agent-helpers.d.ts +10 -1
  2. package/dist/src/__fixtures__/agent-helpers.d.ts.map +1 -1
  3. package/dist/src/__fixtures__/agent-helpers.js +13 -2
  4. package/dist/src/__fixtures__/agent-helpers.js.map +1 -1
  5. package/dist/src/__fixtures__/mock-span.d.ts +78 -0
  6. package/dist/src/__fixtures__/mock-span.d.ts.map +1 -0
  7. package/dist/src/__fixtures__/mock-span.js +93 -0
  8. package/dist/src/__fixtures__/mock-span.js.map +1 -0
  9. package/dist/src/__fixtures__/tool-helpers.d.ts +2 -2
  10. package/dist/src/__fixtures__/tool-helpers.d.ts.map +1 -1
  11. package/dist/src/__fixtures__/tool-helpers.js +4 -4
  12. package/dist/src/__fixtures__/tool-helpers.js.map +1 -1
  13. package/dist/src/__tests__/app-state.test.d.ts +2 -0
  14. package/dist/src/__tests__/app-state.test.d.ts.map +1 -0
  15. package/dist/src/{agent/__tests__/state.test.js → __tests__/app-state.test.js} +46 -46
  16. package/dist/src/__tests__/app-state.test.js.map +1 -0
  17. package/dist/src/__tests__/mcp.test.js +96 -15
  18. package/dist/src/__tests__/mcp.test.js.map +1 -1
  19. package/dist/src/agent/__tests__/agent.test.js +110 -0
  20. package/dist/src/agent/__tests__/agent.test.js.map +1 -1
  21. package/dist/src/agent/__tests__/agent.tracer.test.d.ts +2 -0
  22. package/dist/src/agent/__tests__/agent.tracer.test.d.ts.map +1 -0
  23. package/dist/src/agent/__tests__/agent.tracer.test.js +470 -0
  24. package/dist/src/agent/__tests__/agent.tracer.test.js.map +1 -0
  25. package/dist/src/agent/agent.d.ts +59 -6
  26. package/dist/src/agent/agent.d.ts.map +1 -1
  27. package/dist/src/agent/agent.js +187 -60
  28. package/dist/src/agent/agent.js.map +1 -1
  29. package/dist/src/{agent/state.d.ts → app-state.d.ts} +7 -7
  30. package/dist/src/app-state.d.ts.map +1 -0
  31. package/dist/src/{agent/state.js → app-state.js} +6 -6
  32. package/dist/src/app-state.js.map +1 -0
  33. package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts +1 -1
  34. package/dist/src/conversation-manager/sliding-window-conversation-manager.js +1 -1
  35. package/dist/src/index.d.ts +2 -1
  36. package/dist/src/index.d.ts.map +1 -1
  37. package/dist/src/index.js +4 -0
  38. package/dist/src/index.js.map +1 -1
  39. package/dist/src/mcp.d.ts +3 -0
  40. package/dist/src/mcp.d.ts.map +1 -1
  41. package/dist/src/mcp.js +38 -1
  42. package/dist/src/mcp.js.map +1 -1
  43. package/dist/src/models/__tests__/model.test.js +7 -0
  44. package/dist/src/models/__tests__/model.test.js.map +1 -1
  45. package/dist/src/models/model.d.ts +4 -0
  46. package/dist/src/models/model.d.ts.map +1 -1
  47. package/dist/src/models/model.js +6 -0
  48. package/dist/src/models/model.js.map +1 -1
  49. package/dist/src/models/streaming.d.ts +1 -1
  50. package/dist/src/multiagent/__tests__/events.test.d.ts +2 -0
  51. package/dist/src/multiagent/__tests__/events.test.d.ts.map +1 -0
  52. package/dist/src/multiagent/__tests__/events.test.js +189 -0
  53. package/dist/src/multiagent/__tests__/events.test.js.map +1 -0
  54. package/dist/src/multiagent/__tests__/nodes.test.js +102 -6
  55. package/dist/src/multiagent/__tests__/nodes.test.js.map +1 -1
  56. package/dist/src/multiagent/__tests__/queue.test.d.ts +2 -0
  57. package/dist/src/multiagent/__tests__/queue.test.d.ts.map +1 -0
  58. package/dist/src/multiagent/__tests__/queue.test.js +96 -0
  59. package/dist/src/multiagent/__tests__/queue.test.js.map +1 -0
  60. package/dist/src/multiagent/base.d.ts +25 -0
  61. package/dist/src/multiagent/base.d.ts.map +1 -0
  62. package/dist/src/multiagent/base.js +2 -0
  63. package/dist/src/multiagent/base.js.map +1 -0
  64. package/dist/src/multiagent/edge.d.ts +29 -0
  65. package/dist/src/multiagent/edge.d.ts.map +1 -0
  66. package/dist/src/multiagent/edge.js +15 -0
  67. package/dist/src/multiagent/edge.js.map +1 -0
  68. package/dist/src/multiagent/events.d.ts +115 -4
  69. package/dist/src/multiagent/events.d.ts.map +1 -1
  70. package/dist/src/multiagent/events.js +123 -2
  71. package/dist/src/multiagent/events.js.map +1 -1
  72. package/dist/src/multiagent/index.d.ts +8 -6
  73. package/dist/src/multiagent/index.d.ts.map +1 -1
  74. package/dist/src/multiagent/index.js +4 -3
  75. package/dist/src/multiagent/index.js.map +1 -1
  76. package/dist/src/multiagent/nodes.d.ts +62 -14
  77. package/dist/src/multiagent/nodes.d.ts.map +1 -1
  78. package/dist/src/multiagent/nodes.js +67 -20
  79. package/dist/src/multiagent/nodes.js.map +1 -1
  80. package/dist/src/multiagent/queue.d.ts +67 -0
  81. package/dist/src/multiagent/queue.d.ts.map +1 -0
  82. package/dist/src/multiagent/queue.js +59 -0
  83. package/dist/src/multiagent/queue.js.map +1 -0
  84. package/dist/src/multiagent/state.d.ts +77 -10
  85. package/dist/src/multiagent/state.d.ts.map +1 -1
  86. package/dist/src/multiagent/state.js +98 -9
  87. package/dist/src/multiagent/state.js.map +1 -1
  88. package/dist/src/telemetry/__tests__/config.test.node.d.ts +2 -0
  89. package/dist/src/telemetry/__tests__/config.test.node.d.ts.map +1 -0
  90. package/dist/src/telemetry/__tests__/config.test.node.js +129 -0
  91. package/dist/src/telemetry/__tests__/config.test.node.js.map +1 -0
  92. package/dist/src/telemetry/__tests__/json.test.d.ts +2 -0
  93. package/dist/src/telemetry/__tests__/json.test.d.ts.map +1 -0
  94. package/dist/src/telemetry/__tests__/json.test.js +89 -0
  95. package/dist/src/telemetry/__tests__/json.test.js.map +1 -0
  96. package/dist/src/telemetry/__tests__/tracer.test.node.d.ts +2 -0
  97. package/dist/src/telemetry/__tests__/tracer.test.node.d.ts.map +1 -0
  98. package/dist/src/telemetry/__tests__/tracer.test.node.js +611 -0
  99. package/dist/src/telemetry/__tests__/tracer.test.node.js.map +1 -0
  100. package/dist/src/telemetry/config.d.ts +61 -0
  101. package/dist/src/telemetry/config.d.ts.map +1 -0
  102. package/dist/src/telemetry/config.js +101 -0
  103. package/dist/src/telemetry/config.js.map +1 -0
  104. package/dist/src/telemetry/index.d.ts +34 -0
  105. package/dist/src/telemetry/index.d.ts.map +1 -0
  106. package/dist/src/telemetry/index.js +33 -0
  107. package/dist/src/telemetry/index.js.map +1 -0
  108. package/dist/src/telemetry/json.d.ts +11 -0
  109. package/dist/src/telemetry/json.d.ts.map +1 -0
  110. package/dist/src/telemetry/json.js +25 -0
  111. package/dist/src/telemetry/json.js.map +1 -0
  112. package/dist/src/telemetry/tracer.d.ts +219 -0
  113. package/dist/src/telemetry/tracer.d.ts.map +1 -0
  114. package/dist/src/telemetry/tracer.js +610 -0
  115. package/dist/src/telemetry/tracer.js.map +1 -0
  116. package/dist/src/telemetry/types.d.ts +101 -0
  117. package/dist/src/telemetry/types.d.ts.map +1 -0
  118. package/dist/src/telemetry/types.js +5 -0
  119. package/dist/src/{multiagent → telemetry}/types.js.map +1 -1
  120. package/dist/src/tools/tool.d.ts +1 -1
  121. package/dist/src/tools/tool.js +1 -1
  122. package/dist/src/tsconfig.tsbuildinfo +1 -1
  123. package/dist/src/types/agent.d.ts +3 -3
  124. package/dist/src/types/agent.d.ts.map +1 -1
  125. package/dist/src/types/messages.d.ts +4 -4
  126. package/dist/src/types/messages.js +1 -1
  127. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +2 -2
  128. package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +1 -1
  129. package/dist/src/vended-tools/file_editor/__tests__/file-editor.test.node.js +4 -4
  130. package/dist/src/vended-tools/file_editor/__tests__/file-editor.test.node.js.map +1 -1
  131. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js +2 -2
  132. package/dist/src/vended-tools/notebook/__tests__/notebook.test.js.map +1 -1
  133. package/package.json +11 -2
  134. package/dist/src/agent/__tests__/state.test.d.ts +0 -2
  135. package/dist/src/agent/__tests__/state.test.d.ts.map +0 -1
  136. package/dist/src/agent/__tests__/state.test.js.map +0 -1
  137. package/dist/src/agent/state.d.ts.map +0 -1
  138. package/dist/src/agent/state.js.map +0 -1
  139. package/dist/src/multiagent/types.d.ts +0 -5
  140. package/dist/src/multiagent/types.d.ts.map +0 -1
  141. package/dist/src/multiagent/types.js +0 -2
@@ -1,11 +1,13 @@
1
1
  import { AgentResult, type AgentStreamEvent, type ContentBlock, type ContentBlockData, type JSONValue, McpClient, Message, type MessageData, type SystemPrompt, type SystemPromptData, type Tool } from '../index.js';
2
- import type { BaseModelConfig, Model } from '../models/model.js';
2
+ import { Model } from '../models/model.js';
3
+ import type { BaseModelConfig } from '../models/model.js';
3
4
  import { ToolRegistry } from '../registry/tool-registry.js';
4
- import { AgentState } from './state.js';
5
+ import { AppState } from '../app-state.js';
5
6
  import type { AgentData } from '../types/agent.js';
6
7
  import type { HookProvider } from '../hooks/types.js';
7
8
  import { HookRegistryImplementation } from '../hooks/registry.js';
8
9
  import type { z } from 'zod';
10
+ import type { AttributeValue } from '@opentelemetry/api';
9
11
  /**
10
12
  * Recursive type definition for nested tool arrays.
11
13
  * Allows tools to be organized in nested arrays of any depth.
@@ -71,6 +73,20 @@ export type AgentConfig = {
71
73
  * Zod schema for structured output validation.
72
74
  */
73
75
  structuredOutputSchema?: z.ZodSchema;
76
+ /**
77
+ * Custom trace attributes to include in all spans.
78
+ * These attributes are merged with standard attributes in telemetry spans.
79
+ * Telemetry must be enabled globally via telemetry.setupTracer() for these to take effect.
80
+ */
81
+ traceAttributes?: Record<string, AttributeValue>;
82
+ /**
83
+ * Optional name for the agent. Defaults to "Strands Agent".
84
+ */
85
+ name?: string;
86
+ /**
87
+ * Optional unique identifier for the agent. Defaults to "default".
88
+ */
89
+ agentId?: string;
74
90
  };
75
91
  /**
76
92
  * Arguments for invoking an agent.
@@ -81,6 +97,15 @@ export type AgentConfig = {
81
97
  * - `Message[]` | `MessageData[]` - Array of messages (appends all to conversation)
82
98
  */
83
99
  export type InvokeArgs = string | ContentBlock[] | ContentBlockData[] | Message[] | MessageData[];
100
+ /**
101
+ * Options for a single agent invocation.
102
+ */
103
+ export interface InvokeOptions {
104
+ /**
105
+ * Zod schema for structured output validation, overriding the constructor-provided schema for this invocation only.
106
+ */
107
+ structuredOutputSchema?: z.ZodSchema;
108
+ }
84
109
  /**
85
110
  * Orchestrates the interaction between a model, a set of tools, and MCP clients.
86
111
  * The Agent is responsible for managing the lifecycle of tools and clients
@@ -92,10 +117,10 @@ export declare class Agent implements AgentData {
92
117
  */
93
118
  readonly messages: Message[];
94
119
  /**
95
- * Agent state storage accessible to tools and application logic.
120
+ * App state storage accessible to tools and application logic.
96
121
  * State is not passed to the model during inference.
97
122
  */
98
- readonly state: AgentState;
123
+ readonly state: AppState;
99
124
  /**
100
125
  * Conversation manager for handling message history and context overflow.
101
126
  */
@@ -113,12 +138,24 @@ export declare class Agent implements AgentData {
113
138
  * The system prompt to pass to the model provider.
114
139
  */
115
140
  systemPrompt?: SystemPrompt;
141
+ /**
142
+ * The name of the agent.
143
+ */
144
+ readonly name: string;
145
+ /**
146
+ * The unique identifier of the agent instance.
147
+ */
148
+ readonly agentId: string;
116
149
  private _toolRegistry;
117
150
  private _mcpClients;
118
151
  private _initialized;
119
152
  private _isInvoking;
120
153
  private _printer?;
121
154
  private _structuredOutputSchema?;
155
+ /** Tracer instance for creating and managing OpenTelemetry spans. */
156
+ private _tracer;
157
+ /** Running total of token usage across all model invocations in the current invocation. */
158
+ private _accumulatedTokenUsage;
122
159
  /**
123
160
  * Creates an instance of the Agent.
124
161
  * @param config - The configuration for the agent.
@@ -146,6 +183,7 @@ export declare class Agent implements AgentData {
146
183
  * streaming events.
147
184
  *
148
185
  * @param args - Arguments for invoking the agent
186
+ * @param options - Optional per-invocation options
149
187
  * @returns Promise that resolves to the final AgentResult
150
188
  *
151
189
  * @example
@@ -155,7 +193,7 @@ export declare class Agent implements AgentData {
155
193
  * console.log(result.lastMessage) // Agent's response
156
194
  * ```
157
195
  */
158
- invoke(args: InvokeArgs): Promise<AgentResult>;
196
+ invoke(args: InvokeArgs, options?: InvokeOptions): Promise<AgentResult>;
159
197
  /**
160
198
  * Streams the agent execution, yielding events and returning the final result.
161
199
  *
@@ -173,6 +211,7 @@ export declare class Agent implements AgentData {
173
211
  * with valid toolResponses
174
212
  *
175
213
  * @param args - Arguments for invoking the agent
214
+ * @param options - Optional per-invocation options
176
215
  * @returns Async generator that yields AgentStreamEvent objects and returns AgentResult
177
216
  *
178
217
  * @example
@@ -185,12 +224,13 @@ export declare class Agent implements AgentData {
185
224
  * // Messages array is mutated in place and contains the full conversation
186
225
  * ```
187
226
  */
188
- stream(args: InvokeArgs): AsyncGenerator<AgentStreamEvent, AgentResult, undefined>;
227
+ stream(args: InvokeArgs, options?: InvokeOptions): AsyncGenerator<AgentStreamEvent, AgentResult, undefined>;
189
228
  /**
190
229
  * Internal implementation of the agent streaming logic.
191
230
  * Separated to centralize printer event processing in the public stream method.
192
231
  *
193
232
  * @param args - Arguments for invoking the agent
233
+ * @param options - Optional per-invocation options
194
234
  * @returns Async generator that yields AgentStreamEvent objects and returns AgentResult
195
235
  */
196
236
  private _stream;
@@ -252,5 +292,18 @@ export declare class Agent implements AgentData {
252
292
  * @returns MessageAddedEvent to be yielded
253
293
  */
254
294
  private _appendMessage;
295
+ /**
296
+ * Creates an empty Usage object with all counters set to zero.
297
+ *
298
+ * @returns A Usage object with zeroed counters
299
+ */
300
+ private static _createEmptyUsage;
301
+ /**
302
+ * Accumulates token usage from a source into a target Usage object.
303
+ *
304
+ * @param target - The Usage object to accumulate into (mutated in place)
305
+ * @param source - The Usage object to accumulate from
306
+ */
307
+ private static _accumulateUsage;
255
308
  }
256
309
  //# sourceMappingURL=agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/agent/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/agent/agent.ts"],"names":[],"mappings":"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"}
@@ -53,15 +53,21 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
53
53
  import { AgentResult, BedrockModel, contentBlockFromData, McpClient, Message, TextBlock, ToolResultBlock, ToolUseBlock, } from '../index.js';
54
54
  import { systemPromptFromData } from '../types/messages.js';
55
55
  import { normalizeError, ConcurrentInvocationError, MaxTokensError } from '../errors.js';
56
+ import { Model } from '../models/model.js';
56
57
  import { isModelStreamEvent } from '../models/streaming.js';
57
58
  import { ToolRegistry } from '../registry/tool-registry.js';
58
- import { AgentState } from './state.js';
59
+ import { AppState } from '../app-state.js';
59
60
  import { AgentPrinter, getDefaultAppender } from './printer.js';
60
61
  import { SlidingWindowConversationManager } from '../conversation-manager/sliding-window-conversation-manager.js';
61
62
  import { HookRegistryImplementation } from '../hooks/registry.js';
62
63
  import { InitializedEvent, AfterInvocationEvent, AfterModelCallEvent, AfterToolCallEvent, AfterToolsEvent, BeforeInvocationEvent, BeforeModelCallEvent, BeforeToolCallEvent, BeforeToolsEvent, HookableEvent, MessageAddedEvent, ModelStreamUpdateEvent, ContentBlockEvent, ModelMessageEvent, ToolResultEvent, AgentResultEvent, ToolStreamUpdateEvent, } from '../hooks/events.js';
63
64
  import { createStructuredOutputContext } from '../structured-output/context.js';
64
65
  import { StructuredOutputException } from '../structured-output/exceptions.js';
66
+ import { Tracer } from '../telemetry/tracer.js';
67
+ /** Fallback name used when no agent name is provided in the config. */
68
+ const DEFAULT_AGENT_NAME = 'Strands Agent';
69
+ /** Fallback agent ID used when no agent ID is provided in the config. */
70
+ const DEFAULT_AGENT_ID = 'default';
65
71
  /**
66
72
  * Orchestrates the interaction between a model, a set of tools, and MCP clients.
67
73
  * The Agent is responsible for managing the lifecycle of tools and clients
@@ -73,7 +79,7 @@ export class Agent {
73
79
  */
74
80
  messages;
75
81
  /**
76
- * Agent state storage accessible to tools and application logic.
82
+ * App state storage accessible to tools and application logic.
77
83
  * State is not passed to the model during inference.
78
84
  */
79
85
  state;
@@ -94,12 +100,24 @@ export class Agent {
94
100
  * The system prompt to pass to the model provider.
95
101
  */
96
102
  systemPrompt;
103
+ /**
104
+ * The name of the agent.
105
+ */
106
+ name;
107
+ /**
108
+ * The unique identifier of the agent instance.
109
+ */
110
+ agentId;
97
111
  _toolRegistry;
98
112
  _mcpClients;
99
113
  _initialized;
100
114
  _isInvoking = false;
101
115
  _printer;
102
116
  _structuredOutputSchema;
117
+ /** Tracer instance for creating and managing OpenTelemetry spans. */
118
+ _tracer;
119
+ /** Running total of token usage across all model invocations in the current invocation. */
120
+ _accumulatedTokenUsage = Agent._createEmptyUsage();
103
121
  /**
104
122
  * Creates an instance of the Agent.
105
123
  * @param config - The configuration for the agent.
@@ -107,8 +125,10 @@ export class Agent {
107
125
  constructor(config) {
108
126
  // Initialize public fields
109
127
  this.messages = (config?.messages ?? []).map((msg) => (msg instanceof Message ? msg : Message.fromMessageData(msg)));
110
- this.state = new AgentState(config?.state);
128
+ this.state = new AppState(config?.state);
111
129
  this.conversationManager = config?.conversationManager ?? new SlidingWindowConversationManager({ windowSize: 40 });
130
+ this.name = config?.name ?? DEFAULT_AGENT_NAME;
131
+ this.agentId = config?.agentId ?? DEFAULT_AGENT_ID;
112
132
  // Initialize hooks and register conversation manager hooks
113
133
  this.hooks = new HookRegistryImplementation();
114
134
  this.hooks.addHook(this.conversationManager);
@@ -132,6 +152,8 @@ export class Agent {
132
152
  }
133
153
  // Store structured output schema
134
154
  this._structuredOutputSchema = config?.structuredOutputSchema;
155
+ // Initialize tracer - OTEL returns no-op tracer if not configured
156
+ this._tracer = new Tracer(config?.traceAttributes);
135
157
  this._initialized = false;
136
158
  }
137
159
  async initialize() {
@@ -180,6 +202,7 @@ export class Agent {
180
202
  * streaming events.
181
203
  *
182
204
  * @param args - Arguments for invoking the agent
205
+ * @param options - Optional per-invocation options
183
206
  * @returns Promise that resolves to the final AgentResult
184
207
  *
185
208
  * @example
@@ -189,8 +212,8 @@ export class Agent {
189
212
  * console.log(result.lastMessage) // Agent's response
190
213
  * ```
191
214
  */
192
- async invoke(args) {
193
- const gen = this.stream(args);
215
+ async invoke(args, options) {
216
+ const gen = this.stream(args, options);
194
217
  let result = await gen.next();
195
218
  while (!result.done) {
196
219
  result = await gen.next();
@@ -214,6 +237,7 @@ export class Agent {
214
237
  * with valid toolResponses
215
238
  *
216
239
  * @param args - Arguments for invoking the agent
240
+ * @param options - Optional per-invocation options
217
241
  * @returns Async generator that yields AgentStreamEvent objects and returns AgentResult
218
242
  *
219
243
  * @example
@@ -226,13 +250,13 @@ export class Agent {
226
250
  * // Messages array is mutated in place and contains the full conversation
227
251
  * ```
228
252
  */
229
- async *stream(args) {
253
+ async *stream(args, options) {
230
254
  const env_1 = { stack: [], error: void 0, hasError: false };
231
255
  try {
232
256
  const _lock = __addDisposableResource(env_1, this.acquireLock(), false);
233
257
  await this.initialize();
234
258
  // Delegate to _stream and process events through printer and hooks
235
- const streamGenerator = this._stream(args);
259
+ const streamGenerator = this._stream(args, options);
236
260
  let result = await streamGenerator.next();
237
261
  while (!result.done) {
238
262
  const event = result.value;
@@ -265,71 +289,119 @@ export class Agent {
265
289
  * Separated to centralize printer event processing in the public stream method.
266
290
  *
267
291
  * @param args - Arguments for invoking the agent
292
+ * @param options - Optional per-invocation options
268
293
  * @returns Async generator that yields AgentStreamEvent objects and returns AgentResult
269
294
  */
270
- async *_stream(args) {
295
+ async *_stream(args, options) {
271
296
  let currentArgs = args;
272
297
  let forcedToolChoice = undefined;
298
+ let result;
273
299
  // Create structured output context (uses null object pattern when no schema)
274
- const schema = this._structuredOutputSchema;
300
+ const schema = options?.structuredOutputSchema ?? this._structuredOutputSchema;
275
301
  const context = createStructuredOutputContext(schema);
276
302
  // Emit event before the try block
277
303
  yield new BeforeInvocationEvent({ agent: this });
304
+ // Normalize input to get the user messages for telemetry
305
+ const inputMessages = this._normalizeInput(args);
306
+ // Start agent trace span
307
+ this._accumulatedTokenUsage = Agent._createEmptyUsage();
308
+ const agentModelId = this.model.modelId;
309
+ const agentSpanOptions = {
310
+ messages: inputMessages,
311
+ agentName: this.name,
312
+ agentId: this.agentId,
313
+ tools: this.tools,
314
+ };
315
+ if (agentModelId)
316
+ agentSpanOptions.modelId = agentModelId;
317
+ if (this.systemPrompt)
318
+ agentSpanOptions.systemPrompt = this.systemPrompt;
319
+ const agentSpan = this._tracer.startAgentSpan(agentSpanOptions);
320
+ let caughtError;
278
321
  try {
279
322
  // Register structured output tool
280
323
  context.registerTool(this._toolRegistry);
281
324
  // Main agent loop - continues until model stops without requesting tools
282
- while (true) {
283
- const modelResult = yield* this.invokeModel(currentArgs, forcedToolChoice);
284
- currentArgs = undefined; // Only pass args on first invocation
285
- const wasForced = forcedToolChoice !== undefined;
286
- forcedToolChoice = undefined; // Clear after use
287
- if (modelResult.stopReason !== 'toolUse') {
288
- // Special handling for maxTokens - always fail regardless of whether we have structured output
289
- if (modelResult.stopReason === 'maxTokens') {
290
- throw new MaxTokensError('The model reached maxTokens before producing structured output. Consider increasing maxTokens in your model configuration.', modelResult.message);
291
- }
292
- // Check if we need to force structured output tool
293
- if (!context.hasResult()) {
294
- if (wasForced) {
295
- // Already tried forcing - LLM refused to use the tool
296
- throw new StructuredOutputException('The model failed to invoke the structured output tool even after it was forced.');
325
+ for (let cycleCount = 1;; cycleCount++) {
326
+ // Create agent loop cycle span within agent span context
327
+ const cycleSpan = this._tracer.startAgentLoopSpan({
328
+ cycleId: `cycle-${cycleCount}`,
329
+ messages: this.messages,
330
+ });
331
+ try {
332
+ const modelResult = yield* this.invokeModel(currentArgs, forcedToolChoice);
333
+ currentArgs = undefined; // Only pass args on first invocation
334
+ const wasForced = forcedToolChoice !== undefined;
335
+ forcedToolChoice = undefined; // Clear after use
336
+ if (modelResult.stopReason !== 'toolUse') {
337
+ // Special handling for maxTokens - always fail regardless of whether we have structured output
338
+ if (modelResult.stopReason === 'maxTokens') {
339
+ throw new MaxTokensError('The model reached maxTokens before producing structured output. Consider increasing maxTokens in your model configuration.', modelResult.message);
297
340
  }
298
- // Force the model to use the structured output tool
299
- const toolName = context.getToolName();
300
- forcedToolChoice = { tool: { name: toolName } };
301
- continue;
341
+ // Check if we need to force structured output tool
342
+ if (!context.hasResult()) {
343
+ if (wasForced) {
344
+ // Already tried forcing - LLM refused to use the tool
345
+ throw new StructuredOutputException('The model failed to invoke the structured output tool even after it was forced.');
346
+ }
347
+ // Force the model to use the structured output tool
348
+ const toolName = context.getToolName();
349
+ forcedToolChoice = { tool: { name: toolName } };
350
+ this._tracer.endAgentLoopSpan(cycleSpan);
351
+ continue;
352
+ }
353
+ // Loop terminates - no tool use requested (and structured output satisfied if needed)
354
+ yield this._appendMessage(modelResult.message);
355
+ // End cycle span
356
+ this._tracer.endAgentLoopSpan(cycleSpan);
357
+ const structuredOutput = context.getResult();
358
+ result = new AgentResult({
359
+ stopReason: modelResult.stopReason,
360
+ lastMessage: modelResult.message,
361
+ structuredOutput,
362
+ });
363
+ return result;
302
364
  }
303
- // Loop terminates - no tool use requested (and structured output satisfied if needed)
365
+ // Execute tools sequentially
366
+ const toolResultMessage = yield* this.executeTools(modelResult.message, this._toolRegistry);
367
+ /**
368
+ * Deferred append: both messages are added AFTER tool execution completes.
369
+ * This keeps agent.messages in a valid, reinvokable state at all times:
370
+ *
371
+ * - If interrupted during tool execution, messages has no dangling toolUse
372
+ * without a matching toolResult, so the agent can be reinvoked cleanly.
373
+ * - The Python SDK appends the assistant message BEFORE tool execution,
374
+ * requiring recovery logic (generate_missing_tool_result_content) on
375
+ * interrupts. We avoid that by deferring.
376
+ * - Trade-off: MessageAddedEvent for the assistant message fires after tools
377
+ * complete (not before as in Python), and agent.messages is incomplete
378
+ * during tool execution. Events like BeforeToolsEvent.message and
379
+ * BeforeToolCallEvent.toolUse provide the data directly.
380
+ */
304
381
  yield this._appendMessage(modelResult.message);
305
- const structuredOutput = context.getResult();
306
- return new AgentResult({
307
- stopReason: modelResult.stopReason,
308
- lastMessage: modelResult.message,
309
- structuredOutput,
310
- });
382
+ yield this._appendMessage(toolResultMessage);
383
+ // End cycle span
384
+ this._tracer.endAgentLoopSpan(cycleSpan);
385
+ // Continue loop
386
+ }
387
+ catch (error) {
388
+ // End cycle span with error
389
+ this._tracer.endAgentLoopSpan(cycleSpan, { error: error });
390
+ throw error;
311
391
  }
312
- // Execute tools sequentially
313
- const toolResultMessage = yield* this.executeTools(modelResult.message, this._toolRegistry);
314
- /**
315
- * Deferred append: both messages are added AFTER tool execution completes.
316
- * This keeps agent.messages in a valid, reinvokable state at all times:
317
- *
318
- * - If interrupted during tool execution, messages has no dangling toolUse
319
- * without a matching toolResult, so the agent can be reinvoked cleanly.
320
- * - The Python SDK appends the assistant message BEFORE tool execution,
321
- * requiring recovery logic (generate_missing_tool_result_content) on
322
- * interrupts. We avoid that by deferring.
323
- * - Trade-off: MessageAddedEvent for the assistant message fires after tools
324
- * complete (not before as in Python), and agent.messages is incomplete
325
- * during tool execution. Events like BeforeToolsEvent.message and
326
- * BeforeToolCallEvent.toolUse provide the data directly.
327
- */
328
- yield this._appendMessage(modelResult.message);
329
- yield this._appendMessage(toolResultMessage);
330
392
  }
331
393
  }
394
+ catch (error) {
395
+ caughtError = error;
396
+ throw error;
397
+ }
332
398
  finally {
399
+ this._tracer.endAgentSpan(agentSpan, {
400
+ ...(caughtError && { error: caughtError }),
401
+ ...(result?.lastMessage && { response: result.lastMessage }),
402
+ accumulatedUsage: this._accumulatedTokenUsage,
403
+ ...(result?.stopReason && { stopReason: result.stopReason }),
404
+ });
333
405
  // Cleanup structured output context
334
406
  context.cleanup(this._toolRegistry);
335
407
  // Always emit final event
@@ -414,8 +486,20 @@ export class Agent {
414
486
  streamOptions.toolChoice = forcedToolChoice;
415
487
  }
416
488
  yield new BeforeModelCallEvent({ agent: this });
489
+ // Start model span within loop span context
490
+ const modelId = this.model.modelId;
491
+ const modelSpan = this._tracer.startModelInvokeSpan({
492
+ messages: this.messages,
493
+ ...(modelId && { modelId }),
494
+ });
417
495
  try {
418
- const { message, stopReason } = yield* this._streamFromModel(this.messages, streamOptions);
496
+ const { message, stopReason, usage } = yield* this._streamFromModel(this.messages, streamOptions);
497
+ // Accumulate token usage
498
+ if (usage) {
499
+ Agent._accumulateUsage(this._accumulatedTokenUsage, usage);
500
+ }
501
+ // End model span with usage
502
+ this._tracer.endModelInvokeSpan(modelSpan, { output: message, stopReason, ...(usage && { usage }) });
419
503
  yield new ModelMessageEvent({ agent: this, message, stopReason });
420
504
  const afterModelCallEvent = new AfterModelCallEvent({ agent: this, stopData: { message, stopReason } });
421
505
  yield afterModelCallEvent;
@@ -426,6 +510,8 @@ export class Agent {
426
510
  }
427
511
  catch (error) {
428
512
  const modelError = normalizeError(error);
513
+ // End model span with error
514
+ this._tracer.endModelInvokeSpan(modelSpan, { error: modelError });
429
515
  // Create error event
430
516
  const errorEvent = new AfterModelCallEvent({ agent: this, error: modelError });
431
517
  // Yield error event - stream will invoke hooks
@@ -470,7 +556,11 @@ export class Agent {
470
556
  result = await streamGenerator.next();
471
557
  }
472
558
  // result.done is true, result.value contains the return value
473
- return result.value;
559
+ const { message, stopReason, metadata } = result.value;
560
+ const returnValue = { message, stopReason };
561
+ if (metadata?.usage)
562
+ returnValue.usage = metadata.usage;
563
+ return returnValue;
474
564
  }
475
565
  /**
476
566
  * Executes tools sequentially and streams all tool events.
@@ -514,7 +604,7 @@ export class Agent {
514
604
  */
515
605
  async *executeTool(toolUseBlock, toolRegistry) {
516
606
  const tool = toolRegistry.find((t) => t.name === toolUseBlock.name);
517
- // Create toolUse object for hook events
607
+ // Create toolUse object for hook events and telemetry
518
608
  const toolUse = {
519
609
  name: toolUseBlock.name,
520
610
  toolUseId: toolUseBlock.toolUseId,
@@ -523,6 +613,10 @@ export class Agent {
523
613
  // Retry loop for tool execution
524
614
  while (true) {
525
615
  yield new BeforeToolCallEvent({ agent: this, toolUse, tool });
616
+ // Start tool span within loop span context
617
+ const toolSpan = this._tracer.startToolCallSpan({
618
+ tool: toolUse,
619
+ });
526
620
  let toolResult;
527
621
  let error;
528
622
  if (!tool) {
@@ -534,7 +628,7 @@ export class Agent {
534
628
  });
535
629
  }
536
630
  else {
537
- // Execute tool and collect result
631
+ // Execute tool within the tool span context
538
632
  const toolContext = {
539
633
  toolUse: {
540
634
  name: toolUseBlock.name,
@@ -547,11 +641,13 @@ export class Agent {
547
641
  // Manually iterate tool stream to wrap each ToolStreamEvent in ToolStreamUpdateEvent.
548
642
  // This keeps the tool authoring interface unchanged — tools construct ToolStreamEvent
549
643
  // without knowledge of agents or hooks, and we wrap at the boundary.
550
- const toolGenerator = tool.stream(toolContext);
551
- let toolNext = await toolGenerator.next();
644
+ // Tool execution is ran within the tool span's context so that
645
+ // downstream calls (e.g., MCP clients) can propagate trace context
646
+ const toolGenerator = this._tracer.withSpanContext(toolSpan, () => tool.stream(toolContext));
647
+ let toolNext = await this._tracer.withSpanContext(toolSpan, () => toolGenerator.next());
552
648
  while (!toolNext.done) {
553
649
  yield new ToolStreamUpdateEvent({ agent: this, event: toolNext.value });
554
- toolNext = await toolGenerator.next();
650
+ toolNext = await this._tracer.withSpanContext(toolSpan, () => toolGenerator.next());
555
651
  }
556
652
  const result = toolNext.value;
557
653
  if (!result) {
@@ -578,6 +674,8 @@ export class Agent {
578
674
  });
579
675
  }
580
676
  }
677
+ // End tool span
678
+ this._tracer.endToolCallSpan(toolSpan, { toolResult, ...(error && { error }) });
581
679
  // Single point for AfterToolCallEvent
582
680
  const afterToolCallEvent = new AfterToolCallEvent({
583
681
  agent: this,
@@ -603,6 +701,35 @@ export class Agent {
603
701
  this.messages.push(message);
604
702
  return new MessageAddedEvent({ agent: this, message });
605
703
  }
704
+ /**
705
+ * Creates an empty Usage object with all counters set to zero.
706
+ *
707
+ * @returns A Usage object with zeroed counters
708
+ */
709
+ static _createEmptyUsage() {
710
+ return {
711
+ inputTokens: 0,
712
+ outputTokens: 0,
713
+ totalTokens: 0,
714
+ };
715
+ }
716
+ /**
717
+ * Accumulates token usage from a source into a target Usage object.
718
+ *
719
+ * @param target - The Usage object to accumulate into (mutated in place)
720
+ * @param source - The Usage object to accumulate from
721
+ */
722
+ static _accumulateUsage(target, source) {
723
+ target.inputTokens += source.inputTokens;
724
+ target.outputTokens += source.outputTokens;
725
+ target.totalTokens += source.totalTokens;
726
+ if (source.cacheReadInputTokens !== undefined) {
727
+ target.cacheReadInputTokens = (target.cacheReadInputTokens ?? 0) + source.cacheReadInputTokens;
728
+ }
729
+ if (source.cacheWriteInputTokens !== undefined) {
730
+ target.cacheWriteInputTokens = (target.cacheWriteInputTokens ?? 0) + source.cacheWriteInputTokens;
731
+ }
732
+ }
606
733
  }
607
734
  /**
608
735
  * Recursively flattens nested arrays of tools into a single flat array.