@keywordsai/keywordsai-sdk 0.0.11 → 0.0.12
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/dist/exporters/index.d.ts +1 -0
- package/dist/exporters/index.js +2 -0
- package/dist/exporters/index.js.map +1 -0
- package/dist/exporters/vercelExporter.d.ts +42 -0
- package/dist/exporters/vercelExporter.js +548 -0
- package/dist/exporters/vercelExporter.js.map +1 -0
- package/dist/types/logTypes.d.ts +73 -259
- package/dist/types/logTypes.js +4 -35
- package/dist/types/logTypes.js.map +1 -1
- package/package.json +2 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./vercelExporter";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exporters/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ExportResult } from "@opentelemetry/core";
|
|
2
|
+
import { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-base";
|
|
3
|
+
export declare class KeywordsAIExporter implements SpanExporter {
|
|
4
|
+
private readonly debug;
|
|
5
|
+
private readonly apiKey;
|
|
6
|
+
private readonly baseUrl;
|
|
7
|
+
private readonly url;
|
|
8
|
+
constructor(params?: {
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
});
|
|
13
|
+
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): Promise<void>;
|
|
14
|
+
private createPayload;
|
|
15
|
+
private parseToolCalls;
|
|
16
|
+
private parseCompletionMessages;
|
|
17
|
+
private calculateLatency;
|
|
18
|
+
private sendToKeywords;
|
|
19
|
+
private parseModel;
|
|
20
|
+
private parsePromptMessages;
|
|
21
|
+
private parsePromptTokens;
|
|
22
|
+
private parseCompletionTokens;
|
|
23
|
+
private parseTimeToFirstToken;
|
|
24
|
+
private parseCost;
|
|
25
|
+
private parseGenerationTime;
|
|
26
|
+
private parseTtft;
|
|
27
|
+
private parseWarnings;
|
|
28
|
+
private parseType;
|
|
29
|
+
private parseMetadata;
|
|
30
|
+
private isGenerationSpan;
|
|
31
|
+
private isAiSdkSpan;
|
|
32
|
+
private logDebug;
|
|
33
|
+
shutdown(): Promise<void>;
|
|
34
|
+
private compareHrTime;
|
|
35
|
+
private findRootSpan;
|
|
36
|
+
private formatTimestamp;
|
|
37
|
+
private parseToolChoice;
|
|
38
|
+
private parseTools;
|
|
39
|
+
private parseCustomerParams;
|
|
40
|
+
private parseLogType;
|
|
41
|
+
private deduplicateSpans;
|
|
42
|
+
}
|
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
import { ExportResultCode } from "@opentelemetry/core";
|
|
2
|
+
import { KeywordsPayloadSchema } from "../types/logTypes";
|
|
3
|
+
import { VERCEL_SPAN_TO_KEYWORDS_LOG_TYPE, } from "../constants";
|
|
4
|
+
export class KeywordsAIExporter {
|
|
5
|
+
debug;
|
|
6
|
+
apiKey;
|
|
7
|
+
baseUrl;
|
|
8
|
+
url;
|
|
9
|
+
constructor(params = {}) {
|
|
10
|
+
this.debug = params.debug ?? false;
|
|
11
|
+
this.apiKey = params.apiKey ?? (process.env.KEYWORDSAI_API_KEY || "");
|
|
12
|
+
if (!this.apiKey) {
|
|
13
|
+
throw new Error("KEYWORDSAI_API_KEY is required");
|
|
14
|
+
}
|
|
15
|
+
this.baseUrl = params.baseUrl ?? "https://api.keywordsai.co/api";
|
|
16
|
+
this.url = `${this.baseUrl}/api/integrations/v1/traces/ingest`;
|
|
17
|
+
}
|
|
18
|
+
async export(spans, resultCallback) {
|
|
19
|
+
try {
|
|
20
|
+
const sortedSpans = spans
|
|
21
|
+
.slice()
|
|
22
|
+
.sort((a, b) => this.compareHrTime(a.startTime, b.startTime));
|
|
23
|
+
// Filter for AI SDK spans instead of just generation spans
|
|
24
|
+
const aiSdkSpans = sortedSpans.filter((span) => this.isAiSdkSpan(span));
|
|
25
|
+
if (aiSdkSpans.length === 0) {
|
|
26
|
+
this.logDebug("No AI SDK spans found");
|
|
27
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// Deduplicate spans - prefer doStream/doGenerate over their parent spans
|
|
31
|
+
const deduplicatedSpans = this.deduplicateSpans(aiSdkSpans);
|
|
32
|
+
this.logDebug(`Filtered ${aiSdkSpans.length} spans to ${deduplicatedSpans.length} after deduplication`);
|
|
33
|
+
// Prepare all payloads
|
|
34
|
+
const allPayloads = [];
|
|
35
|
+
for (const span of deduplicatedSpans) {
|
|
36
|
+
try {
|
|
37
|
+
const rawPayload = await this.createPayload(span, sortedSpans);
|
|
38
|
+
try {
|
|
39
|
+
const validatedPayload = KeywordsPayloadSchema.parse(rawPayload);
|
|
40
|
+
allPayloads.push(validatedPayload);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
this.logDebug("Payload validation failed", error);
|
|
44
|
+
// If validation fails, include the raw payload in full_request
|
|
45
|
+
try {
|
|
46
|
+
const fallbackPayload = KeywordsPayloadSchema.parse({
|
|
47
|
+
...rawPayload,
|
|
48
|
+
full_request: rawPayload,
|
|
49
|
+
});
|
|
50
|
+
allPayloads.push(fallbackPayload);
|
|
51
|
+
}
|
|
52
|
+
catch (fallbackError) {
|
|
53
|
+
this.logDebug("Fallback validation also failed", fallbackError);
|
|
54
|
+
// Last resort - create minimal valid payload with error info
|
|
55
|
+
const minimalPayload = KeywordsPayloadSchema.parse({
|
|
56
|
+
model: "unknown",
|
|
57
|
+
prompt_messages: [
|
|
58
|
+
{ role: "system", content: "Error processing span" },
|
|
59
|
+
],
|
|
60
|
+
prompt_tokens: 0,
|
|
61
|
+
timestamp: this.formatTimestamp(span.endTime),
|
|
62
|
+
customer_identifier: "default_user",
|
|
63
|
+
stream: false,
|
|
64
|
+
metadata: {
|
|
65
|
+
error: String(error),
|
|
66
|
+
span_id: span.spanContext().spanId,
|
|
67
|
+
trace_id: span.spanContext().traceId,
|
|
68
|
+
span_name: span.name,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
allPayloads.push(minimalPayload);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
this.logDebug("Failed to create payload for span", error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
console.log("allPayloads", allPayloads);
|
|
80
|
+
// Send all payloads in one request
|
|
81
|
+
if (allPayloads.length > 0) {
|
|
82
|
+
await this.sendToKeywords(allPayloads);
|
|
83
|
+
}
|
|
84
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
this.logDebug("Export failed", err);
|
|
88
|
+
resultCallback({
|
|
89
|
+
code: ExportResultCode.FAILED,
|
|
90
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async createPayload(span, relatedSpans) {
|
|
95
|
+
const metadata = this.parseMetadata(span);
|
|
96
|
+
const isError = span.status.code !== 0;
|
|
97
|
+
const model = this.parseModel(span);
|
|
98
|
+
const toolCalls = this.parseToolCalls(span);
|
|
99
|
+
const messages = this.parseCompletionMessages(span, toolCalls);
|
|
100
|
+
const payload = {
|
|
101
|
+
model,
|
|
102
|
+
start_time: this.formatTimestamp(span.startTime),
|
|
103
|
+
timestamp: this.formatTimestamp(span.endTime),
|
|
104
|
+
prompt_messages: this.parsePromptMessages(span),
|
|
105
|
+
completion_message: messages[0],
|
|
106
|
+
customer_identifier: metadata.userId || "default_user",
|
|
107
|
+
thread_identifier: metadata.userId,
|
|
108
|
+
prompt_tokens: this.parsePromptTokens(span),
|
|
109
|
+
completion_tokens: this.parseCompletionTokens(span),
|
|
110
|
+
cost: this.parseCost(span),
|
|
111
|
+
generation_time: this.parseGenerationTime(span),
|
|
112
|
+
latency: this.calculateLatency(span),
|
|
113
|
+
ttft: this.parseTtft(span),
|
|
114
|
+
metadata: {
|
|
115
|
+
...metadata,
|
|
116
|
+
span_type: span.name, // Add span type to metadata
|
|
117
|
+
},
|
|
118
|
+
environment: process.env.NODE_ENV || "prod",
|
|
119
|
+
time_to_first_token: this.parseTimeToFirstToken(span),
|
|
120
|
+
trace_unique_id: span.spanContext().traceId,
|
|
121
|
+
span_unique_id: span.spanContext().spanId,
|
|
122
|
+
span_name: span.name,
|
|
123
|
+
span_parent_id: span.attributes["span.parent_id"]?.toString() ||
|
|
124
|
+
span.attributes["parentSpanId"]?.toString(),
|
|
125
|
+
span_path: span.attributes["ai.path"]?.toString(),
|
|
126
|
+
stream: span.name.includes("doStream"),
|
|
127
|
+
status_code: isError ? 500 : 200,
|
|
128
|
+
warnings: this.parseWarnings(span),
|
|
129
|
+
error_message: span.status.message || "",
|
|
130
|
+
type: this.parseType(span),
|
|
131
|
+
log_type: this.parseLogType(span),
|
|
132
|
+
is_test: process.env.NODE_ENV === "development",
|
|
133
|
+
posthog_integration: process.env.POSTHOG_API_KEY
|
|
134
|
+
? {
|
|
135
|
+
posthog_api_key: process.env.POSTHOG_API_KEY,
|
|
136
|
+
posthog_base_url: "https://us.i.posthog.com",
|
|
137
|
+
}
|
|
138
|
+
: undefined,
|
|
139
|
+
tool_choice: this.parseToolChoice(span),
|
|
140
|
+
tools: this.parseTools(span),
|
|
141
|
+
tool_calls: toolCalls,
|
|
142
|
+
field_name: "data: ",
|
|
143
|
+
delimiter: "\n\n",
|
|
144
|
+
disable_log: false,
|
|
145
|
+
request_breakdown: false,
|
|
146
|
+
disable_fallback: false,
|
|
147
|
+
...this.parseCustomerParams(span),
|
|
148
|
+
};
|
|
149
|
+
return payload;
|
|
150
|
+
}
|
|
151
|
+
// Helper method to parse tool calls from span attributes
|
|
152
|
+
parseToolCalls(span) {
|
|
153
|
+
try {
|
|
154
|
+
// Check for tool calls in various attribute formats
|
|
155
|
+
const toolCallAttributes = [
|
|
156
|
+
"ai.response.toolCalls",
|
|
157
|
+
"ai.toolCall",
|
|
158
|
+
"ai.toolCalls",
|
|
159
|
+
];
|
|
160
|
+
// Try to find tool calls in any of the standard attribute locations
|
|
161
|
+
for (const attr of toolCallAttributes) {
|
|
162
|
+
if (span.attributes[attr]) {
|
|
163
|
+
const rawData = span.attributes[attr];
|
|
164
|
+
if (!rawData)
|
|
165
|
+
continue;
|
|
166
|
+
// Handle both string and object formats
|
|
167
|
+
let parsed;
|
|
168
|
+
try {
|
|
169
|
+
parsed =
|
|
170
|
+
typeof rawData === "string" ? JSON.parse(rawData) : rawData;
|
|
171
|
+
}
|
|
172
|
+
catch (e) {
|
|
173
|
+
this.logDebug(`Failed to parse ${attr}:`, e);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
// Standardize to array
|
|
177
|
+
const toolCalls = Array.isArray(parsed) ? parsed : [parsed];
|
|
178
|
+
// Process each tool call with minimal transformation
|
|
179
|
+
return toolCalls.map((call) => {
|
|
180
|
+
// Ensure we have a valid object
|
|
181
|
+
if (!call || typeof call !== "object") {
|
|
182
|
+
return { type: "function" };
|
|
183
|
+
}
|
|
184
|
+
// Make a copy to avoid mutating the original
|
|
185
|
+
const result = { ...call };
|
|
186
|
+
// Ensure the object has a type
|
|
187
|
+
if (!result.type) {
|
|
188
|
+
result.type = "function";
|
|
189
|
+
}
|
|
190
|
+
// Handle ID normalization (only if needed)
|
|
191
|
+
if (!result.id && (result.toolCallId || result.tool_call_id)) {
|
|
192
|
+
result.id = result.toolCallId || result.tool_call_id;
|
|
193
|
+
}
|
|
194
|
+
return result;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// If we didn't find tool calls in the standard places, check for individual attributes
|
|
199
|
+
if (span.attributes["ai.toolCall.id"] ||
|
|
200
|
+
span.attributes["ai.toolCall.name"] ||
|
|
201
|
+
span.attributes["ai.toolCall.args"]) {
|
|
202
|
+
// Build a tool call object from individual attributes
|
|
203
|
+
const toolCall = { type: "function" };
|
|
204
|
+
// Copy all tool call attributes
|
|
205
|
+
for (const [key, value] of Object.entries(span.attributes)) {
|
|
206
|
+
if (key.startsWith("ai.toolCall.")) {
|
|
207
|
+
const propName = key.replace("ai.toolCall.", "");
|
|
208
|
+
toolCall[propName] = value;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return [toolCall];
|
|
212
|
+
}
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
this.logDebug("Error parsing tool calls:", error);
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
parseCompletionMessages(span, toolCalls) {
|
|
221
|
+
const message = {
|
|
222
|
+
role: "assistant",
|
|
223
|
+
content: String(span.attributes["ai.response.text"] || ""),
|
|
224
|
+
...(toolCalls && toolCalls.length > 0 && { tool_calls: toolCalls }),
|
|
225
|
+
};
|
|
226
|
+
// Check if there's a tool result to add as a separate message
|
|
227
|
+
const toolResults = [];
|
|
228
|
+
if (span.attributes["ai.toolCall.result"]) {
|
|
229
|
+
toolResults.push({
|
|
230
|
+
role: "tool",
|
|
231
|
+
tool_call_id: String(span.attributes["ai.toolCall.id"] || ""),
|
|
232
|
+
content: String(span.attributes["ai.toolCall.result"] || ""),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return toolResults.length > 0 ? [message, ...toolResults] : [message];
|
|
236
|
+
}
|
|
237
|
+
calculateLatency(span) {
|
|
238
|
+
return span.duration[0] / 1e9 + span.duration[1] / 1e9;
|
|
239
|
+
}
|
|
240
|
+
async sendToKeywords(payloads) {
|
|
241
|
+
if (payloads.length === 0) {
|
|
242
|
+
this.logDebug("No payloads to send");
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
this.logDebug(`Sending ${payloads.length} payloads to Keywords`);
|
|
247
|
+
const response = await fetch(this.url, {
|
|
248
|
+
method: "POST",
|
|
249
|
+
headers: {
|
|
250
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
251
|
+
"Content-Type": "application/json",
|
|
252
|
+
},
|
|
253
|
+
body: JSON.stringify(payloads),
|
|
254
|
+
});
|
|
255
|
+
if (!response.ok) {
|
|
256
|
+
const text = await response.text();
|
|
257
|
+
this.logDebug("Failed to send to Keywords", text);
|
|
258
|
+
throw new Error(`Failed to send to Keywords: ${response.statusText}`);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
this.logDebug("Successfully sent payloads to Keywords");
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
this.logDebug("Error sending to Keywords", error);
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
parseModel(span) {
|
|
270
|
+
const model = String(span.attributes["ai.model.id"] || "unknown").toLowerCase();
|
|
271
|
+
if (model.includes("gemini-2.0-flash-001")) {
|
|
272
|
+
return "gemini/gemini-2.0-flash";
|
|
273
|
+
}
|
|
274
|
+
if (model.includes("gemini-2.0-pro")) {
|
|
275
|
+
return "gemini/gemini-2.0-pro-exp-02-05";
|
|
276
|
+
}
|
|
277
|
+
if (model.includes("claude-3-5-sonnet")) {
|
|
278
|
+
return "claude-3-5-sonnet-20241022";
|
|
279
|
+
}
|
|
280
|
+
if (model.includes("deepseek")) {
|
|
281
|
+
return "deepseek/" + model;
|
|
282
|
+
}
|
|
283
|
+
if (model.includes("o3-mini")) {
|
|
284
|
+
return "o3-mini";
|
|
285
|
+
}
|
|
286
|
+
return model;
|
|
287
|
+
}
|
|
288
|
+
parsePromptMessages(span) {
|
|
289
|
+
try {
|
|
290
|
+
const messages = span.attributes["ai.prompt.messages"];
|
|
291
|
+
const parsedMessages = messages ? JSON.parse(String(messages)) : [];
|
|
292
|
+
return KeywordsPayloadSchema.shape.prompt_messages.parse(parsedMessages);
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
this.logDebug("Error parsing messages:", error);
|
|
296
|
+
return [
|
|
297
|
+
{
|
|
298
|
+
role: "user",
|
|
299
|
+
content: String(span.attributes["ai.prompt"] || ""),
|
|
300
|
+
},
|
|
301
|
+
];
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
parsePromptTokens(span) {
|
|
305
|
+
return parseInt(String(span.attributes["gen_ai.usage.input_tokens"] || "0"));
|
|
306
|
+
}
|
|
307
|
+
parseCompletionTokens(span) {
|
|
308
|
+
return parseInt(String(span.attributes["gen_ai.usage.output_tokens"] || "0"));
|
|
309
|
+
}
|
|
310
|
+
parseTimeToFirstToken(span) {
|
|
311
|
+
const msToFinish = span.attributes["ai.response.msToFinish"];
|
|
312
|
+
const sToFinish = msToFinish ? msToFinish / 1000 : 0;
|
|
313
|
+
return sToFinish;
|
|
314
|
+
}
|
|
315
|
+
parseCost(span) {
|
|
316
|
+
const cost = span.attributes["gen_ai.usage.cost"];
|
|
317
|
+
return cost ? parseFloat(String(cost)) : undefined;
|
|
318
|
+
}
|
|
319
|
+
parseGenerationTime(span) {
|
|
320
|
+
const generationTime = span.attributes["gen_ai.usage.generation_time"];
|
|
321
|
+
return generationTime ? parseFloat(String(generationTime)) : undefined;
|
|
322
|
+
}
|
|
323
|
+
parseTtft(span) {
|
|
324
|
+
const ttft = span.attributes["gen_ai.usage.ttft"];
|
|
325
|
+
return ttft ? parseFloat(String(ttft)) : undefined;
|
|
326
|
+
}
|
|
327
|
+
parseWarnings(span) {
|
|
328
|
+
const warnings = span.attributes["gen_ai.usage.warnings"];
|
|
329
|
+
return warnings ? String(warnings) : undefined;
|
|
330
|
+
}
|
|
331
|
+
parseType(span) {
|
|
332
|
+
const type = span.attributes["gen_ai.usage.type"];
|
|
333
|
+
return type ? type : undefined;
|
|
334
|
+
}
|
|
335
|
+
parseMetadata(span) {
|
|
336
|
+
return Object.entries(span.attributes)
|
|
337
|
+
.filter(([key]) => key.startsWith("ai.telemetry.metadata."))
|
|
338
|
+
.reduce((acc, [key, value]) => {
|
|
339
|
+
const cleanKey = key.replace("ai.telemetry.metadata.", "");
|
|
340
|
+
acc[cleanKey] = value?.toString();
|
|
341
|
+
return acc;
|
|
342
|
+
}, {});
|
|
343
|
+
}
|
|
344
|
+
isGenerationSpan(span) {
|
|
345
|
+
return ["doGenerate", "doStream"].some((part) => span.name.includes(part));
|
|
346
|
+
}
|
|
347
|
+
isAiSdkSpan(span) {
|
|
348
|
+
// Check if the span is from the Vercel AI SDK
|
|
349
|
+
return (
|
|
350
|
+
// Check for ai-related attributes
|
|
351
|
+
span.attributes["ai.sdk"] === true ||
|
|
352
|
+
span.name.includes("ai.") ||
|
|
353
|
+
// Check for other AI SDK related attributes
|
|
354
|
+
Object.keys(span.attributes).some((key) => key.startsWith("ai.") || key.startsWith("gen_ai.")));
|
|
355
|
+
}
|
|
356
|
+
logDebug(message, ...args) {
|
|
357
|
+
if (!this.debug)
|
|
358
|
+
return;
|
|
359
|
+
console.log(`[${new Date().toISOString()}] [KeywordsAIExporter] ${message}`, ...args);
|
|
360
|
+
}
|
|
361
|
+
async shutdown() {
|
|
362
|
+
// Nothing to clean up
|
|
363
|
+
}
|
|
364
|
+
compareHrTime(a, b) {
|
|
365
|
+
if (a[0] !== b[0])
|
|
366
|
+
return a[0] - b[0];
|
|
367
|
+
return a[1] - b[1];
|
|
368
|
+
}
|
|
369
|
+
findRootSpan(span, spans) {
|
|
370
|
+
const parentId = span.attributes["span.parent_id"]?.toString() ||
|
|
371
|
+
span.attributes["parentSpanId"]?.toString();
|
|
372
|
+
if (!parentId)
|
|
373
|
+
return span;
|
|
374
|
+
return spans.find((s) => s.spanContext().spanId === parentId);
|
|
375
|
+
}
|
|
376
|
+
formatTimestamp(hrTime) {
|
|
377
|
+
const epochMs = hrTime[0] * 1000 + hrTime[1] / 1e6;
|
|
378
|
+
return new Date(epochMs).toISOString();
|
|
379
|
+
}
|
|
380
|
+
parseToolChoice(span) {
|
|
381
|
+
try {
|
|
382
|
+
const toolChoice = span.attributes["gen_ai.usage.tool_choice"];
|
|
383
|
+
if (!toolChoice)
|
|
384
|
+
return undefined;
|
|
385
|
+
const parsed = JSON.parse(String(toolChoice));
|
|
386
|
+
return {
|
|
387
|
+
type: String(parsed.type),
|
|
388
|
+
function: {
|
|
389
|
+
name: String(parsed.function.name),
|
|
390
|
+
},
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
catch {
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
parseTools(span) {
|
|
398
|
+
try {
|
|
399
|
+
const tools = span.attributes["ai.prompt.tools"] || [];
|
|
400
|
+
const parsed = Array.isArray(tools) ? tools : [tools];
|
|
401
|
+
return parsed.map((tool) => JSON.parse(String(tool)));
|
|
402
|
+
}
|
|
403
|
+
catch {
|
|
404
|
+
return undefined;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
parseCustomerParams(span) {
|
|
408
|
+
const customerParams = span.attributes["ai.telemetry.metadata.customer_params"];
|
|
409
|
+
if (customerParams) {
|
|
410
|
+
const parsed = JSON.parse(String(customerParams));
|
|
411
|
+
return {
|
|
412
|
+
customer_identifier: parsed.customer_identifier,
|
|
413
|
+
customer_email: parsed.customer_email,
|
|
414
|
+
customer_name: parsed.customer_name,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
const customerEmail = span.attributes["ai.telemetry.metadata.customer_email"];
|
|
419
|
+
const customerName = span.attributes["ai.telemetry.metadata.customer_name"];
|
|
420
|
+
const customerIdentifier = span.attributes["ai.telemetry.metadata.customer_identifier"];
|
|
421
|
+
if (!customerIdentifier)
|
|
422
|
+
return undefined;
|
|
423
|
+
else {
|
|
424
|
+
return {
|
|
425
|
+
customer_email: String(customerEmail || ""),
|
|
426
|
+
customer_name: String(customerName || ""),
|
|
427
|
+
customer_identifier: String(customerIdentifier),
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
parseLogType(span) {
|
|
433
|
+
// Try to match span name directly to a known type
|
|
434
|
+
const spanName = span.name;
|
|
435
|
+
// Check if span name is in our mapping
|
|
436
|
+
if (spanName in VERCEL_SPAN_TO_KEYWORDS_LOG_TYPE) {
|
|
437
|
+
return VERCEL_SPAN_TO_KEYWORDS_LOG_TYPE[spanName];
|
|
438
|
+
}
|
|
439
|
+
// For spans with operationId attribute, check for more specific mapping
|
|
440
|
+
const operationId = span.attributes["ai.operationId"]?.toString();
|
|
441
|
+
if (operationId && operationId in VERCEL_SPAN_TO_KEYWORDS_LOG_TYPE) {
|
|
442
|
+
return VERCEL_SPAN_TO_KEYWORDS_LOG_TYPE[operationId];
|
|
443
|
+
}
|
|
444
|
+
// Check for specific attributes that indicate the span type
|
|
445
|
+
// Check for embedding-related attributes
|
|
446
|
+
if (span.attributes["ai.embedding"] ||
|
|
447
|
+
span.attributes["ai.embeddings"] ||
|
|
448
|
+
spanName.includes("embed") ||
|
|
449
|
+
operationId?.includes("embed")) {
|
|
450
|
+
return "embedding";
|
|
451
|
+
}
|
|
452
|
+
// Check for tool-related attributes
|
|
453
|
+
if (span.attributes["ai.toolCall.id"] ||
|
|
454
|
+
span.attributes["ai.toolCall.name"] ||
|
|
455
|
+
span.attributes["ai.toolCall.args"] ||
|
|
456
|
+
span.attributes["ai.toolCall.result"] ||
|
|
457
|
+
span.attributes["ai.response.toolCalls"] ||
|
|
458
|
+
spanName.includes("tool") ||
|
|
459
|
+
operationId?.includes("tool")) {
|
|
460
|
+
return "tool";
|
|
461
|
+
}
|
|
462
|
+
// Check for agent-related attributes
|
|
463
|
+
if (span.attributes["ai.agent.id"] ||
|
|
464
|
+
spanName.includes("agent") ||
|
|
465
|
+
operationId?.includes("agent")) {
|
|
466
|
+
return "agent";
|
|
467
|
+
}
|
|
468
|
+
// Check for workflow-related attributes
|
|
469
|
+
if (span.attributes["ai.workflow.id"] ||
|
|
470
|
+
spanName.includes("workflow") ||
|
|
471
|
+
operationId?.includes("workflow")) {
|
|
472
|
+
return "workflow";
|
|
473
|
+
}
|
|
474
|
+
// Check for transcription-related attributes
|
|
475
|
+
if (span.attributes["ai.transcript"] ||
|
|
476
|
+
spanName.includes("transcript") ||
|
|
477
|
+
operationId?.includes("transcript")) {
|
|
478
|
+
return "transcription";
|
|
479
|
+
}
|
|
480
|
+
// Check for speech-related attributes
|
|
481
|
+
if (span.attributes["ai.speech"] ||
|
|
482
|
+
spanName.includes("speech") ||
|
|
483
|
+
operationId?.includes("speech")) {
|
|
484
|
+
return "speech";
|
|
485
|
+
}
|
|
486
|
+
// Default to TEXT for any generation-related spans
|
|
487
|
+
if (this.isGenerationSpan(span)) {
|
|
488
|
+
return "text";
|
|
489
|
+
}
|
|
490
|
+
// Fall back to unknown for anything else
|
|
491
|
+
return "unknown";
|
|
492
|
+
}
|
|
493
|
+
// Add a new method to deduplicate spans
|
|
494
|
+
deduplicateSpans(spans) {
|
|
495
|
+
// First, group spans by their trace ID
|
|
496
|
+
const traceGroups = {};
|
|
497
|
+
// Group spans by trace ID
|
|
498
|
+
for (const span of spans) {
|
|
499
|
+
const traceId = span.spanContext().traceId;
|
|
500
|
+
if (!traceGroups[traceId]) {
|
|
501
|
+
traceGroups[traceId] = [];
|
|
502
|
+
}
|
|
503
|
+
traceGroups[traceId].push(span);
|
|
504
|
+
}
|
|
505
|
+
const deduplicatedSpans = [];
|
|
506
|
+
// Process each trace group
|
|
507
|
+
Object.values(traceGroups).forEach((traceSpans) => {
|
|
508
|
+
// Group by base operation name
|
|
509
|
+
const operationGroups = {};
|
|
510
|
+
// Group spans by operation name (without .doStream or .doGenerate suffix)
|
|
511
|
+
for (const span of traceSpans) {
|
|
512
|
+
let opKey = span.name;
|
|
513
|
+
if (opKey.endsWith(".doStream")) {
|
|
514
|
+
opKey = opKey.replace(".doStream", "");
|
|
515
|
+
}
|
|
516
|
+
else if (opKey.endsWith(".doGenerate")) {
|
|
517
|
+
opKey = opKey.replace(".doGenerate", "");
|
|
518
|
+
}
|
|
519
|
+
if (!operationGroups[opKey]) {
|
|
520
|
+
operationGroups[opKey] = [];
|
|
521
|
+
}
|
|
522
|
+
operationGroups[opKey].push(span);
|
|
523
|
+
}
|
|
524
|
+
// Process each operation group
|
|
525
|
+
Object.values(operationGroups).forEach((opSpans) => {
|
|
526
|
+
// If we have multiple spans for the same operation, prefer the more detailed one
|
|
527
|
+
if (opSpans.length > 1) {
|
|
528
|
+
// Find doStream or doGenerate span
|
|
529
|
+
const detailedSpan = opSpans.find((s) => s.name.endsWith(".doStream") || s.name.endsWith(".doGenerate"));
|
|
530
|
+
if (detailedSpan) {
|
|
531
|
+
// Only use the detailed span
|
|
532
|
+
deduplicatedSpans.push(detailedSpan);
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
// No detailed span found, keep all spans
|
|
536
|
+
deduplicatedSpans.push(...opSpans);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
// Only one span, keep it
|
|
541
|
+
deduplicatedSpans.push(opSpans[0]);
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
});
|
|
545
|
+
return deduplicatedSpans;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
//# sourceMappingURL=vercelExporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercelExporter.js","sourceRoot":"","sources":["../../src/exporters/vercelExporter.ts"],"names":[],"mappings":"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"}
|