@contractspec/lib.ai-agent 2.0.0 → 2.1.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.
@@ -14,24 +14,78 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
14
14
 
15
15
  // src/telemetry/adapter.ts
16
16
  function parseAgentId(agentId) {
17
- const match = agentId.match(/^(.+)\.v(\s+)$/);
17
+ const match = agentId.match(/^(.+)\.v(\d+)$/);
18
18
  if (match) {
19
19
  return { name: match[1], version: match[2] };
20
20
  }
21
21
  return { name: agentId, version: "1.0.0" };
22
22
  }
23
- async function trackAgentStep(collector, agentId, step, durationMs) {
23
+ function getRecord(value) {
24
+ return value && typeof value === "object" ? value : undefined;
25
+ }
26
+ function getStepResponse(step) {
27
+ const response = getRecord(step.response);
28
+ if (!response)
29
+ return;
30
+ return {
31
+ id: response["id"],
32
+ modelId: response["modelId"],
33
+ timestamp: response["timestamp"],
34
+ headers: response["headers"],
35
+ body: response["body"],
36
+ messages: response["messages"]
37
+ };
38
+ }
39
+ function getRequestBodyValue(request, key) {
40
+ const body = request?.["body"];
41
+ if (!body)
42
+ return;
43
+ if (typeof body === "string") {
44
+ try {
45
+ const parsed = JSON.parse(body);
46
+ return typeof parsed[key] === "string" ? parsed[key] : undefined;
47
+ } catch {
48
+ return;
49
+ }
50
+ }
51
+ const record = getRecord(body);
52
+ return typeof record?.[key] === "string" ? record[key] : undefined;
53
+ }
54
+ async function trackAgentStep(collector, agentId, step, durationMs, context) {
24
55
  const { name, version } = parseAgentId(agentId);
56
+ const response = getStepResponse(step);
57
+ const providerMetadata = step.providerMetadata;
58
+ const warnings = step.warnings;
59
+ const rawFinishReason = step.rawFinishReason;
60
+ const request = getRecord(step.request);
61
+ const traceId = context?.traceId ?? getRequestBodyValue(request, "$ai_trace_id");
62
+ const sessionId = context?.sessionId ?? getRequestBodyValue(request, "$ai_session_id");
63
+ const parentSpanId = response?.id;
25
64
  for (const toolCall of step.toolCalls ?? []) {
65
+ const toolResult = step.toolResults?.find((r) => r.toolCallId === toolCall.toolCallId);
66
+ const toolError = getRecord(toolResult?.output)?.["error"];
26
67
  const toolSample = {
27
68
  operation: { name: `${name}.${toolCall.toolName}`, version },
28
69
  durationMs: durationMs ?? 0,
29
70
  success: step.toolResults?.some((r) => r.toolCallId === toolCall.toolCallId && r.output !== undefined) ?? false,
30
71
  timestamp: new Date,
31
72
  metadata: {
73
+ telemetryEvent: "span",
74
+ traceId,
75
+ sessionId,
76
+ spanId: toolCall.toolCallId,
77
+ parentSpanId,
78
+ spanName: `tool.${toolCall.toolName}`,
32
79
  agentId,
80
+ actorId: context?.actorId,
81
+ tenantId: context?.tenantId,
82
+ stepIndex: context?.stepIndex,
33
83
  toolName: toolCall.toolName,
34
- finishReason: step.finishReason
84
+ toolCallArgs: toolCall.input,
85
+ toolResultOutput: toolResult?.output,
86
+ errorMessage: typeof toolError === "string" ? toolError : typeof toolResult?.output === "string" ? toolResult.output : undefined,
87
+ finishReason: step.finishReason,
88
+ rawFinishReason
35
89
  }
36
90
  };
37
91
  await collector.collect(toolSample);
@@ -42,10 +96,36 @@ async function trackAgentStep(collector, agentId, step, durationMs) {
42
96
  success: step.finishReason !== "error",
43
97
  timestamp: new Date,
44
98
  metadata: {
99
+ telemetryEvent: "generation",
100
+ traceId,
101
+ sessionId,
102
+ spanId: response?.id,
103
+ spanName: `agent.${name}.step`,
45
104
  agentId,
105
+ actorId: context?.actorId,
106
+ tenantId: context?.tenantId,
107
+ stepIndex: context?.stepIndex,
108
+ stepStartedAt: context?.stepStartedAt,
46
109
  finishReason: step.finishReason,
110
+ rawFinishReason,
47
111
  tokenUsage: step.usage,
48
- toolCallCount: step.toolCalls?.length ?? 0
112
+ totalUsage: step.totalUsage,
113
+ providerMetadata,
114
+ warnings,
115
+ stepText: step.text,
116
+ stepReasoningText: step.reasoningText,
117
+ responseId: response?.id,
118
+ responseModelId: response?.modelId,
119
+ responseTimestamp: response?.timestamp,
120
+ responseHeaders: response?.headers,
121
+ responseBody: response?.body,
122
+ responseMessages: response?.messages,
123
+ requestBody: request?.["body"],
124
+ requestHeaders: request?.["headers"],
125
+ toolCallCount: step.toolCalls?.length ?? 0,
126
+ toolCalls: step.toolCalls,
127
+ toolResults: step.toolResults,
128
+ errorMessage: step.finishReason === "error" ? step.text : undefined
49
129
  }
50
130
  };
51
131
  await collector.collect(stepSample);
@@ -105,23 +185,60 @@ class PostHogTelemetryCollector {
105
185
  }
106
186
  async collect(sample) {
107
187
  const client = await this.getClient();
108
- const distinctId = this.config.defaults?.posthogDistinctId ?? sample.metadata?.["actorId"] ?? "system";
188
+ const metadata = asRecord(sample.metadata);
189
+ const distinctId = this.config.defaults?.posthogDistinctId ?? asString(metadata["actorId"]) ?? "system";
190
+ const traceId = asString(metadata["traceId"]) ?? this.config.defaults?.posthogTraceId;
191
+ const sessionId = asString(metadata["sessionId"]);
192
+ const telemetryEvent = asString(metadata["telemetryEvent"]);
193
+ const event = telemetryEvent === "span" ? "$ai_span" : "$ai_generation";
194
+ const tokenUsage = metadata["tokenUsage"];
195
+ const totalUsage = metadata["totalUsage"];
196
+ const errorMessage = asString(metadata["errorMessage"]);
109
197
  client.capture({
110
198
  distinctId,
111
- event: "$ai_generation",
199
+ event,
112
200
  properties: {
113
- $ai_model: sample.operation.name,
114
- $ai_provider: "contractspec",
201
+ $ai_model: asString(metadata["responseModelId"]) ?? sample.operation.name,
202
+ $ai_provider: asString(metadata["provider"]) ?? "contractspec",
115
203
  $ai_latency: sample.durationMs / 1000,
116
204
  $ai_is_error: !sample.success,
117
- $ai_trace_id: this.config.defaults?.posthogTraceId,
118
- ...sample.metadata?.["tokenUsage"] ? mapTokenUsage(sample.metadata["tokenUsage"]) : {},
205
+ $ai_error: !sample.success ? errorMessage : undefined,
206
+ $ai_trace_id: traceId,
207
+ $ai_session_id: sessionId,
208
+ $ai_span_id: asString(metadata["spanId"]),
209
+ $ai_parent_id: asString(metadata["parentSpanId"]),
210
+ $ai_span_name: asString(metadata["spanName"]) ?? sample.operation.name,
211
+ ...tokenUsage ? mapTokenUsage(tokenUsage) : {},
212
+ ...totalUsage ? mapTotalUsage(totalUsage) : {},
213
+ $ai_http_status: asNumber(metadata["httpStatus"]),
214
+ $ai_request_url: asString(metadata["requestUrl"]),
215
+ $ai_base_url: asString(metadata["baseUrl"]),
119
216
  ...this.config.defaults?.posthogProperties,
120
217
  contractspec_operation: sample.operation.name,
121
218
  contractspec_version: sample.operation.version,
122
- contractspec_agent_id: sample.metadata?.["agentId"],
123
- contractspec_finish_reason: sample.metadata?.["finishReason"],
124
- contractspec_tool_count: sample.metadata?.["toolCallCount"]
219
+ contractspec_agent_id: asString(metadata["agentId"]),
220
+ contractspec_tenant_id: asString(metadata["tenantId"]),
221
+ contractspec_actor_id: asString(metadata["actorId"]),
222
+ contractspec_step_index: asNumber(metadata["stepIndex"]),
223
+ contractspec_step_started_at: asDateIso(metadata["stepStartedAt"]),
224
+ contractspec_finish_reason: asString(metadata["finishReason"]),
225
+ contractspec_finish_reason_raw: asString(metadata["rawFinishReason"]),
226
+ contractspec_tool_count: asNumber(metadata["toolCallCount"]),
227
+ contractspec_tool_name: asString(metadata["toolName"]),
228
+ contractspec_tool_call_args: metadata["toolCallArgs"],
229
+ contractspec_tool_result_output: metadata["toolResultOutput"],
230
+ contractspec_provider_metadata: metadata["providerMetadata"],
231
+ contractspec_step_warnings: metadata["warnings"],
232
+ contractspec_response_id: asString(metadata["responseId"]),
233
+ contractspec_response_model_id: asString(metadata["responseModelId"]),
234
+ contractspec_response_timestamp: asDateIso(metadata["responseTimestamp"]),
235
+ contractspec_response_headers: metadata["responseHeaders"],
236
+ contractspec_response_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseBody"],
237
+ contractspec_response_messages: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseMessages"],
238
+ contractspec_request_headers: metadata["requestHeaders"],
239
+ contractspec_request_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["requestBody"],
240
+ contractspec_step_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepText"],
241
+ contractspec_step_reasoning_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepReasoningText"]
125
242
  },
126
243
  groups: this.config.defaults?.posthogGroups
127
244
  });
@@ -182,11 +299,44 @@ async function resolvePostHogClient(config) {
182
299
  }
183
300
  }
184
301
  function mapTokenUsage(usage) {
302
+ const usageRecord = asRecord(usage);
303
+ const inputTokenDetails = asRecord(usageRecord["inputTokenDetails"]);
304
+ const outputTokenDetails = asRecord(usageRecord["outputTokenDetails"]);
185
305
  return {
186
- $ai_input_tokens: usage["promptTokens"],
187
- $ai_output_tokens: usage["completionTokens"]
306
+ $ai_input_tokens: asNumber(usageRecord["inputTokens"]) ?? asNumber(usageRecord["promptTokens"]),
307
+ $ai_output_tokens: asNumber(usageRecord["outputTokens"]) ?? asNumber(usageRecord["completionTokens"]),
308
+ $ai_reasoning_tokens: asNumber(outputTokenDetails["reasoningTokens"]) ?? asNumber(usageRecord["reasoningTokens"]),
309
+ $ai_cache_read_input_tokens: asNumber(inputTokenDetails["cacheReadTokens"]) ?? asNumber(usageRecord["cachedInputTokens"]),
310
+ $ai_cache_creation_input_tokens: asNumber(inputTokenDetails["cacheWriteTokens"]),
311
+ $ai_usage: maybeRecord(usageRecord["raw"]) ?? usageRecord
188
312
  };
189
313
  }
314
+ function mapTotalUsage(usage) {
315
+ const usageRecord = asRecord(usage);
316
+ return {
317
+ contractspec_total_input_tokens: asNumber(usageRecord["inputTokens"]),
318
+ contractspec_total_output_tokens: asNumber(usageRecord["outputTokens"]),
319
+ contractspec_total_tokens: asNumber(usageRecord["totalTokens"]),
320
+ contractspec_total_usage_raw: maybeRecord(usageRecord["raw"]) ?? usageRecord
321
+ };
322
+ }
323
+ function asRecord(value) {
324
+ return value && typeof value === "object" ? value : {};
325
+ }
326
+ function maybeRecord(value) {
327
+ return value && typeof value === "object" ? value : undefined;
328
+ }
329
+ function asString(value) {
330
+ return typeof value === "string" && value.length > 0 ? value : undefined;
331
+ }
332
+ function asNumber(value) {
333
+ return typeof value === "number" ? value : undefined;
334
+ }
335
+ function asDateIso(value) {
336
+ if (value instanceof Date)
337
+ return value.toISOString();
338
+ return;
339
+ }
190
340
  // src/telemetry/index.ts
191
341
  init_adapter();
192
342
  export {
@@ -41,23 +41,60 @@ class PostHogTelemetryCollector {
41
41
  }
42
42
  async collect(sample) {
43
43
  const client = await this.getClient();
44
- const distinctId = this.config.defaults?.posthogDistinctId ?? sample.metadata?.["actorId"] ?? "system";
44
+ const metadata = asRecord(sample.metadata);
45
+ const distinctId = this.config.defaults?.posthogDistinctId ?? asString(metadata["actorId"]) ?? "system";
46
+ const traceId = asString(metadata["traceId"]) ?? this.config.defaults?.posthogTraceId;
47
+ const sessionId = asString(metadata["sessionId"]);
48
+ const telemetryEvent = asString(metadata["telemetryEvent"]);
49
+ const event = telemetryEvent === "span" ? "$ai_span" : "$ai_generation";
50
+ const tokenUsage = metadata["tokenUsage"];
51
+ const totalUsage = metadata["totalUsage"];
52
+ const errorMessage = asString(metadata["errorMessage"]);
45
53
  client.capture({
46
54
  distinctId,
47
- event: "$ai_generation",
55
+ event,
48
56
  properties: {
49
- $ai_model: sample.operation.name,
50
- $ai_provider: "contractspec",
57
+ $ai_model: asString(metadata["responseModelId"]) ?? sample.operation.name,
58
+ $ai_provider: asString(metadata["provider"]) ?? "contractspec",
51
59
  $ai_latency: sample.durationMs / 1000,
52
60
  $ai_is_error: !sample.success,
53
- $ai_trace_id: this.config.defaults?.posthogTraceId,
54
- ...sample.metadata?.["tokenUsage"] ? mapTokenUsage(sample.metadata["tokenUsage"]) : {},
61
+ $ai_error: !sample.success ? errorMessage : undefined,
62
+ $ai_trace_id: traceId,
63
+ $ai_session_id: sessionId,
64
+ $ai_span_id: asString(metadata["spanId"]),
65
+ $ai_parent_id: asString(metadata["parentSpanId"]),
66
+ $ai_span_name: asString(metadata["spanName"]) ?? sample.operation.name,
67
+ ...tokenUsage ? mapTokenUsage(tokenUsage) : {},
68
+ ...totalUsage ? mapTotalUsage(totalUsage) : {},
69
+ $ai_http_status: asNumber(metadata["httpStatus"]),
70
+ $ai_request_url: asString(metadata["requestUrl"]),
71
+ $ai_base_url: asString(metadata["baseUrl"]),
55
72
  ...this.config.defaults?.posthogProperties,
56
73
  contractspec_operation: sample.operation.name,
57
74
  contractspec_version: sample.operation.version,
58
- contractspec_agent_id: sample.metadata?.["agentId"],
59
- contractspec_finish_reason: sample.metadata?.["finishReason"],
60
- contractspec_tool_count: sample.metadata?.["toolCallCount"]
75
+ contractspec_agent_id: asString(metadata["agentId"]),
76
+ contractspec_tenant_id: asString(metadata["tenantId"]),
77
+ contractspec_actor_id: asString(metadata["actorId"]),
78
+ contractspec_step_index: asNumber(metadata["stepIndex"]),
79
+ contractspec_step_started_at: asDateIso(metadata["stepStartedAt"]),
80
+ contractspec_finish_reason: asString(metadata["finishReason"]),
81
+ contractspec_finish_reason_raw: asString(metadata["rawFinishReason"]),
82
+ contractspec_tool_count: asNumber(metadata["toolCallCount"]),
83
+ contractspec_tool_name: asString(metadata["toolName"]),
84
+ contractspec_tool_call_args: metadata["toolCallArgs"],
85
+ contractspec_tool_result_output: metadata["toolResultOutput"],
86
+ contractspec_provider_metadata: metadata["providerMetadata"],
87
+ contractspec_step_warnings: metadata["warnings"],
88
+ contractspec_response_id: asString(metadata["responseId"]),
89
+ contractspec_response_model_id: asString(metadata["responseModelId"]),
90
+ contractspec_response_timestamp: asDateIso(metadata["responseTimestamp"]),
91
+ contractspec_response_headers: metadata["responseHeaders"],
92
+ contractspec_response_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseBody"],
93
+ contractspec_response_messages: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["responseMessages"],
94
+ contractspec_request_headers: metadata["requestHeaders"],
95
+ contractspec_request_body: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["requestBody"],
96
+ contractspec_step_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepText"],
97
+ contractspec_step_reasoning_text: this.config.defaults?.posthogPrivacyMode ? undefined : metadata["stepReasoningText"]
61
98
  },
62
99
  groups: this.config.defaults?.posthogGroups
63
100
  });
@@ -118,11 +155,44 @@ async function resolvePostHogClient(config) {
118
155
  }
119
156
  }
120
157
  function mapTokenUsage(usage) {
158
+ const usageRecord = asRecord(usage);
159
+ const inputTokenDetails = asRecord(usageRecord["inputTokenDetails"]);
160
+ const outputTokenDetails = asRecord(usageRecord["outputTokenDetails"]);
121
161
  return {
122
- $ai_input_tokens: usage["promptTokens"],
123
- $ai_output_tokens: usage["completionTokens"]
162
+ $ai_input_tokens: asNumber(usageRecord["inputTokens"]) ?? asNumber(usageRecord["promptTokens"]),
163
+ $ai_output_tokens: asNumber(usageRecord["outputTokens"]) ?? asNumber(usageRecord["completionTokens"]),
164
+ $ai_reasoning_tokens: asNumber(outputTokenDetails["reasoningTokens"]) ?? asNumber(usageRecord["reasoningTokens"]),
165
+ $ai_cache_read_input_tokens: asNumber(inputTokenDetails["cacheReadTokens"]) ?? asNumber(usageRecord["cachedInputTokens"]),
166
+ $ai_cache_creation_input_tokens: asNumber(inputTokenDetails["cacheWriteTokens"]),
167
+ $ai_usage: maybeRecord(usageRecord["raw"]) ?? usageRecord
124
168
  };
125
169
  }
170
+ function mapTotalUsage(usage) {
171
+ const usageRecord = asRecord(usage);
172
+ return {
173
+ contractspec_total_input_tokens: asNumber(usageRecord["inputTokens"]),
174
+ contractspec_total_output_tokens: asNumber(usageRecord["outputTokens"]),
175
+ contractspec_total_tokens: asNumber(usageRecord["totalTokens"]),
176
+ contractspec_total_usage_raw: maybeRecord(usageRecord["raw"]) ?? usageRecord
177
+ };
178
+ }
179
+ function asRecord(value) {
180
+ return value && typeof value === "object" ? value : {};
181
+ }
182
+ function maybeRecord(value) {
183
+ return value && typeof value === "object" ? value : undefined;
184
+ }
185
+ function asString(value) {
186
+ return typeof value === "string" && value.length > 0 ? value : undefined;
187
+ }
188
+ function asNumber(value) {
189
+ return typeof value === "number" ? value : undefined;
190
+ }
191
+ function asDateIso(value) {
192
+ if (value instanceof Date)
193
+ return value.toISOString();
194
+ return;
195
+ }
126
196
  export {
127
197
  createPostHogTracedModel,
128
198
  createPostHogTelemetryCollector,
@@ -26,6 +26,14 @@ export interface TelemetryCollector {
26
26
  */
27
27
  collect(sample: OperationMetricSample): Promise<void>;
28
28
  }
29
+ interface TrackAgentStepContext {
30
+ sessionId?: string;
31
+ tenantId?: string;
32
+ actorId?: string;
33
+ traceId?: string;
34
+ stepIndex?: number;
35
+ stepStartedAt?: Date;
36
+ }
29
37
  /**
30
38
  * Track an agent step for telemetry.
31
39
  *
@@ -37,7 +45,7 @@ export interface TelemetryCollector {
37
45
  * @param step - AI SDK step result
38
46
  * @param durationMs - Optional step duration in milliseconds
39
47
  */
40
- export declare function trackAgentStep(collector: TelemetryCollector, agentId: string, step: StepResult<ToolSet>, durationMs?: number): Promise<void>;
48
+ export declare function trackAgentStep(collector: TelemetryCollector, agentId: string, step: StepResult<ToolSet>, durationMs?: number, context?: TrackAgentStepContext): Promise<void>;
41
49
  /**
42
50
  * In-memory telemetry collector for testing.
43
51
  */
@@ -65,3 +73,4 @@ export declare function createInMemoryTelemetryCollector(): InMemoryTelemetryCol
65
73
  * No-op telemetry collector that discards all metrics.
66
74
  */
67
75
  export declare const noopTelemetryCollector: TelemetryCollector;
76
+ export {};
@@ -14,24 +14,78 @@ var __require = import.meta.require;
14
14
 
15
15
  // src/telemetry/adapter.ts
16
16
  function parseAgentId(agentId) {
17
- const match = agentId.match(/^(.+)\.v(\s+)$/);
17
+ const match = agentId.match(/^(.+)\.v(\d+)$/);
18
18
  if (match) {
19
19
  return { name: match[1], version: match[2] };
20
20
  }
21
21
  return { name: agentId, version: "1.0.0" };
22
22
  }
23
- async function trackAgentStep(collector, agentId, step, durationMs) {
23
+ function getRecord(value) {
24
+ return value && typeof value === "object" ? value : undefined;
25
+ }
26
+ function getStepResponse(step) {
27
+ const response = getRecord(step.response);
28
+ if (!response)
29
+ return;
30
+ return {
31
+ id: response["id"],
32
+ modelId: response["modelId"],
33
+ timestamp: response["timestamp"],
34
+ headers: response["headers"],
35
+ body: response["body"],
36
+ messages: response["messages"]
37
+ };
38
+ }
39
+ function getRequestBodyValue(request, key) {
40
+ const body = request?.["body"];
41
+ if (!body)
42
+ return;
43
+ if (typeof body === "string") {
44
+ try {
45
+ const parsed = JSON.parse(body);
46
+ return typeof parsed[key] === "string" ? parsed[key] : undefined;
47
+ } catch {
48
+ return;
49
+ }
50
+ }
51
+ const record = getRecord(body);
52
+ return typeof record?.[key] === "string" ? record[key] : undefined;
53
+ }
54
+ async function trackAgentStep(collector, agentId, step, durationMs, context) {
24
55
  const { name, version } = parseAgentId(agentId);
56
+ const response = getStepResponse(step);
57
+ const providerMetadata = step.providerMetadata;
58
+ const warnings = step.warnings;
59
+ const rawFinishReason = step.rawFinishReason;
60
+ const request = getRecord(step.request);
61
+ const traceId = context?.traceId ?? getRequestBodyValue(request, "$ai_trace_id");
62
+ const sessionId = context?.sessionId ?? getRequestBodyValue(request, "$ai_session_id");
63
+ const parentSpanId = response?.id;
25
64
  for (const toolCall of step.toolCalls ?? []) {
65
+ const toolResult = step.toolResults?.find((r) => r.toolCallId === toolCall.toolCallId);
66
+ const toolError = getRecord(toolResult?.output)?.["error"];
26
67
  const toolSample = {
27
68
  operation: { name: `${name}.${toolCall.toolName}`, version },
28
69
  durationMs: durationMs ?? 0,
29
70
  success: step.toolResults?.some((r) => r.toolCallId === toolCall.toolCallId && r.output !== undefined) ?? false,
30
71
  timestamp: new Date,
31
72
  metadata: {
73
+ telemetryEvent: "span",
74
+ traceId,
75
+ sessionId,
76
+ spanId: toolCall.toolCallId,
77
+ parentSpanId,
78
+ spanName: `tool.${toolCall.toolName}`,
32
79
  agentId,
80
+ actorId: context?.actorId,
81
+ tenantId: context?.tenantId,
82
+ stepIndex: context?.stepIndex,
33
83
  toolName: toolCall.toolName,
34
- finishReason: step.finishReason
84
+ toolCallArgs: toolCall.input,
85
+ toolResultOutput: toolResult?.output,
86
+ errorMessage: typeof toolError === "string" ? toolError : typeof toolResult?.output === "string" ? toolResult.output : undefined,
87
+ finishReason: step.finishReason,
88
+ rawFinishReason
35
89
  }
36
90
  };
37
91
  await collector.collect(toolSample);
@@ -42,10 +96,36 @@ async function trackAgentStep(collector, agentId, step, durationMs) {
42
96
  success: step.finishReason !== "error",
43
97
  timestamp: new Date,
44
98
  metadata: {
99
+ telemetryEvent: "generation",
100
+ traceId,
101
+ sessionId,
102
+ spanId: response?.id,
103
+ spanName: `agent.${name}.step`,
45
104
  agentId,
105
+ actorId: context?.actorId,
106
+ tenantId: context?.tenantId,
107
+ stepIndex: context?.stepIndex,
108
+ stepStartedAt: context?.stepStartedAt,
46
109
  finishReason: step.finishReason,
110
+ rawFinishReason,
47
111
  tokenUsage: step.usage,
48
- toolCallCount: step.toolCalls?.length ?? 0
112
+ totalUsage: step.totalUsage,
113
+ providerMetadata,
114
+ warnings,
115
+ stepText: step.text,
116
+ stepReasoningText: step.reasoningText,
117
+ responseId: response?.id,
118
+ responseModelId: response?.modelId,
119
+ responseTimestamp: response?.timestamp,
120
+ responseHeaders: response?.headers,
121
+ responseBody: response?.body,
122
+ responseMessages: response?.messages,
123
+ requestBody: request?.["body"],
124
+ requestHeaders: request?.["headers"],
125
+ toolCallCount: step.toolCalls?.length ?? 0,
126
+ toolCalls: step.toolCalls,
127
+ toolResults: step.toolResults,
128
+ errorMessage: step.finishReason === "error" ? step.text : undefined
49
129
  }
50
130
  };
51
131
  await collector.collect(stepSample);
@@ -0,0 +1 @@
1
+ export {};