@agentmark-ai/shared-utils 0.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.
package/dist/index.js ADDED
@@ -0,0 +1,1546 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AiSdkTransformer: () => AiSdkTransformer,
34
+ MastraTransformer: () => MastraTransformer,
35
+ SpanType: () => SpanType,
36
+ TransformerRegistry: () => TransformerRegistry,
37
+ TypeClassifier: () => TypeClassifier,
38
+ convertOtlpAttributes: () => convertOtlpAttributes,
39
+ createSignature: () => createSignature,
40
+ detectVersion: () => detectVersion,
41
+ extractCustomMetadata: () => extractCustomMetadata,
42
+ extractReasoningFromProviderMetadata: () => extractReasoningFromProviderMetadata,
43
+ extractResourceScopeSpan: () => extractResourceScopeSpan,
44
+ fetchPromptsFrontmatter: () => fetchPromptsFrontmatter,
45
+ findPromptFiles: () => findPromptFiles,
46
+ generateTypeDefinitions: () => generateTypeDefinitions,
47
+ generateUnique8CharString: () => generateUnique8CharString,
48
+ normalizeOtlpSpans: () => normalizeOtlpSpans,
49
+ normalizeSpan: () => normalizeSpan,
50
+ parseAgentMarkAttributes: () => parseAgentMarkAttributes,
51
+ parseMetadata: () => parseMetadata,
52
+ parseTokens: () => parseTokens,
53
+ registry: () => registry,
54
+ toFrontMatter: () => toFrontMatter,
55
+ typeClassifier: () => typeClassifier,
56
+ verifySignature: () => verifySignature
57
+ });
58
+ module.exports = __toCommonJS(index_exports);
59
+
60
+ // src/generate-unique-8-char-string.ts
61
+ var generateUnique8CharString = () => {
62
+ const timestamp = Date.now().toString(36);
63
+ const randomChars = Math.random().toString(36).substr(2, 6);
64
+ return timestamp + randomChars;
65
+ };
66
+
67
+ // src/hmac-256-signature.ts
68
+ var encoder = new TextEncoder();
69
+ async function createSignature(secret = "", payload) {
70
+ if (!secret) {
71
+ secret = "DEFAULT";
72
+ }
73
+ const algorithm = { name: "HMAC", hash: { name: "SHA-256" } };
74
+ const keyBytes = encoder.encode(secret);
75
+ const extractable = false;
76
+ const key = await crypto.subtle.importKey(
77
+ "raw",
78
+ keyBytes,
79
+ algorithm,
80
+ extractable,
81
+ ["sign", "verify"]
82
+ );
83
+ const signature = await crypto.subtle.sign(
84
+ algorithm,
85
+ key,
86
+ encoder.encode(payload)
87
+ );
88
+ return `sha256=${toHexString(signature)}`;
89
+ }
90
+ function toHexString(signature) {
91
+ return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
92
+ }
93
+ async function verifySignature(secret, header, payload) {
94
+ if (!secret) {
95
+ secret = "DEFAULT";
96
+ }
97
+ const parts = header.split("=");
98
+ const sigHex = parts[1];
99
+ const algorithm = { name: "HMAC", hash: { name: "SHA-256" } };
100
+ const keyBytes = encoder.encode(secret);
101
+ const extractable = false;
102
+ const key = await crypto.subtle.importKey(
103
+ "raw",
104
+ keyBytes,
105
+ algorithm,
106
+ extractable,
107
+ ["sign", "verify"]
108
+ );
109
+ const sigBytes = hexToBytes(sigHex);
110
+ const dataBytes = encoder.encode(payload);
111
+ const equal = await crypto.subtle.verify(
112
+ algorithm.name,
113
+ key,
114
+ sigBytes,
115
+ dataBytes
116
+ );
117
+ return equal;
118
+ }
119
+ function hexToBytes(hex) {
120
+ const len = hex.length / 2;
121
+ const bytes = new Uint8Array(len);
122
+ let index = 0;
123
+ for (let i = 0; i < hex.length; i += 2) {
124
+ const c = hex.slice(i, i + 2);
125
+ const b = parseInt(c, 16);
126
+ bytes[index] = b;
127
+ index += 1;
128
+ }
129
+ return bytes;
130
+ }
131
+
132
+ // src/serialize.ts
133
+ function toFrontMatter(content) {
134
+ function jsonToFrontMatter(json, indent = 0) {
135
+ let frontMatter = "";
136
+ const indentation = " ".repeat(indent);
137
+ for (const key in json) {
138
+ if (Object.prototype.hasOwnProperty.call(json, key)) {
139
+ const value = json[key];
140
+ if (typeof value === "object" && !Array.isArray(value)) {
141
+ frontMatter += `${indentation}${key}:
142
+ `;
143
+ frontMatter += jsonToFrontMatter(value, indent + 1);
144
+ } else if (Array.isArray(value)) {
145
+ frontMatter += `${indentation}${key}:
146
+ `;
147
+ value.forEach((item) => {
148
+ if (typeof item === "object") {
149
+ frontMatter += `${indentation}-
150
+ `;
151
+ frontMatter += jsonToFrontMatter(item, indent + 2);
152
+ } else {
153
+ frontMatter += `${indentation}- ${item}
154
+ `;
155
+ }
156
+ });
157
+ } else {
158
+ frontMatter += `${indentation}${key}: ${value}
159
+ `;
160
+ }
161
+ }
162
+ }
163
+ return frontMatter;
164
+ }
165
+ return `---
166
+ ${jsonToFrontMatter(content)}---
167
+ `;
168
+ }
169
+
170
+ // src/generate-types.ts
171
+ var fs = __toESM(require("fs-extra"));
172
+ var import_path = __toESM(require("path"));
173
+ var import_front_matter = __toESM(require("front-matter"));
174
+ var _compile = null;
175
+ async function getCompile() {
176
+ var _a;
177
+ if (_compile) return _compile;
178
+ const mod = await import("json-schema-to-typescript");
179
+ const c = mod.compile || ((_a = mod.default) == null ? void 0 : _a.compile);
180
+ _compile = c.bind(mod);
181
+ return _compile;
182
+ }
183
+ function getInterfaceName(filePath) {
184
+ return filePath.replace(/\.prompt\.mdx$/, "").split("/").map((part) => {
185
+ return part.split(/[-_]|(?=[A-Z])/).map(
186
+ (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
187
+ ).join("").replace(/[^a-zA-Z0-9]/g, "");
188
+ }).join("$");
189
+ }
190
+ function getToolInterfaceName(toolName) {
191
+ return toolName.split(/[-_]|(?=[A-Z])/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
192
+ }
193
+ async function findPromptFiles(dir) {
194
+ const files = await fs.readdir(dir, { withFileTypes: true });
195
+ let promptFiles = [];
196
+ for (const file of files) {
197
+ const fullPath = import_path.default.join(dir, file.name);
198
+ if (file.isDirectory()) {
199
+ promptFiles = promptFiles.concat(await findPromptFiles(fullPath));
200
+ } else if (file.name.endsWith(".prompt.mdx")) {
201
+ promptFiles.push(fullPath);
202
+ }
203
+ }
204
+ return promptFiles;
205
+ }
206
+ async function generateTypeDefinitionsV1_0(prompts) {
207
+ const interfaces = [];
208
+ const headerComment = `// Auto-generated types from AgentMark
209
+ // Do not edit this file directly
210
+
211
+ `;
212
+ let output = "";
213
+ const typeMapping = [];
214
+ for (const prompt of prompts) {
215
+ const { path: promptPath, input_schema } = prompt;
216
+ const name = getInterfaceName(promptPath);
217
+ let tools = {};
218
+ try {
219
+ let kind = "text";
220
+ let output_schema = null;
221
+ if ("text_config" in prompt) {
222
+ kind = "text";
223
+ tools = prompt.text_config.tools || {};
224
+ } else if ("object_config" in prompt) {
225
+ kind = "object";
226
+ tools = prompt.object_config.tools || {};
227
+ output_schema = prompt.object_config.schema;
228
+ } else if ("image_config" in prompt) {
229
+ kind = "image";
230
+ tools = prompt.image_config.tools || {};
231
+ }
232
+ const compile = await getCompile();
233
+ const inputInterface = input_schema ? await compile(input_schema, `${name}In`, {
234
+ bannerComment: "",
235
+ additionalProperties: false
236
+ }) : `interface ${name}In { [key: string]: any }`;
237
+ const toolTypes = await generateToolTypes(tools);
238
+ const outputInterface = output_schema ? await compile(output_schema, `${name}Out`, {
239
+ bannerComment: "",
240
+ additionalProperties: false
241
+ }) : `type ${name}Out = string`;
242
+ interfaces.push(
243
+ inputInterface.replace("export interface", "interface"),
244
+ outputInterface.replace("export type", "type").replace("export interface", "interface")
245
+ );
246
+ output += toolTypes || "";
247
+ output += `type ${name} = {
248
+ kind: '${kind}';
249
+ input: ${name}In;
250
+ output: ${name}Out;${toolTypes ? `
251
+ tools?: Array<keyof Tools>;` : ""}
252
+ };
253
+
254
+ `;
255
+ typeMapping.push(` "${promptPath}": ${name}`);
256
+ const withoutMdx = promptPath.replace(/\.mdx$/, "");
257
+ if (withoutMdx !== promptPath) {
258
+ typeMapping.push(` "${withoutMdx}": ${name}`);
259
+ }
260
+ const shortName = promptPath.replace(/\.prompt\.mdx$/, "");
261
+ if (shortName !== promptPath && shortName !== withoutMdx) {
262
+ typeMapping.push(` "${shortName}": ${name}`);
263
+ }
264
+ } catch (error) {
265
+ console.error(`Error processing ${promptPath}:`, error);
266
+ interfaces.push(
267
+ `interface ${name}In { [key: string]: any }
268
+ type ${name}Out = string`
269
+ );
270
+ }
271
+ }
272
+ output += `export default interface AgentmarkTypes {
273
+ ${typeMapping.join(",\n")}
274
+ }
275
+ `;
276
+ return headerComment + interfaces.join("\n\n") + "\n\n" + output;
277
+ }
278
+ async function generateTypeDefinitionsV0(prompts) {
279
+ var _a, _b;
280
+ const interfaces = [];
281
+ const headerComment = `// Auto-generated types from AgentMark
282
+ // Do not edit this file directly
283
+
284
+ `;
285
+ let output = "";
286
+ const typeMapping = [];
287
+ for (const prompt of prompts) {
288
+ const { path: promptPath, metadata, input_schema } = prompt;
289
+ const name = getInterfaceName(promptPath);
290
+ try {
291
+ const compile = await getCompile();
292
+ const inputInterface = input_schema ? await compile(input_schema, `${name}In`, {
293
+ bannerComment: "",
294
+ additionalProperties: false
295
+ }) : `interface ${name}In { [key: string]: any }`;
296
+ const outputSchema = (_b = (_a = metadata == null ? void 0 : metadata.model) == null ? void 0 : _a.settings) == null ? void 0 : _b.schema;
297
+ const outputInterface = outputSchema ? await compile(outputSchema, `${name}Out`, {
298
+ bannerComment: "",
299
+ additionalProperties: false
300
+ }) : `type ${name}Out = string`;
301
+ interfaces.push(
302
+ inputInterface.replace("export interface", "interface"),
303
+ outputInterface.replace("export type", "type").replace("export interface", "interface")
304
+ );
305
+ output += `interface ${name} {
306
+ input: ${name}In;
307
+ output: ${name}Out;
308
+ }
309
+
310
+ `;
311
+ typeMapping.push(` "${promptPath}": ${name}`);
312
+ const withoutMdx = promptPath.replace(/\.mdx$/, "");
313
+ if (withoutMdx !== promptPath) {
314
+ typeMapping.push(` "${withoutMdx}": ${name}`);
315
+ }
316
+ const shortName = promptPath.replace(/\.prompt\.mdx$/, "");
317
+ if (shortName !== promptPath && shortName !== withoutMdx) {
318
+ typeMapping.push(` "${shortName}": ${name}`);
319
+ }
320
+ } catch (error) {
321
+ console.error(`Error processing ${promptPath}:`, error);
322
+ interfaces.push(
323
+ `interface ${name}In { [key: string]: any }
324
+ type ${name}Out = string`
325
+ );
326
+ output += `interface ${name} {
327
+ input: ${name}In;
328
+ output: ${name}Out;
329
+ }
330
+
331
+ `;
332
+ typeMapping.push(` "${promptPath}": ${name}`);
333
+ const withoutMdx = promptPath.replace(/\.mdx$/, "");
334
+ if (withoutMdx !== promptPath) {
335
+ typeMapping.push(` "${withoutMdx}": ${name}`);
336
+ }
337
+ const shortName = promptPath.replace(/\.prompt\.mdx$/, "");
338
+ if (shortName !== promptPath && shortName !== withoutMdx) {
339
+ typeMapping.push(` "${shortName}": ${name}`);
340
+ }
341
+ }
342
+ }
343
+ output += `export default interface AgentmarkTypes {
344
+ ${typeMapping.join(",\n")}
345
+ }
346
+ `;
347
+ return headerComment + interfaces.join("\n\n") + "\n\n" + output;
348
+ }
349
+ var isNewFormat = (frontmatter) => {
350
+ return frontmatter["text_config"] || frontmatter["object_config"] || frontmatter["image_config"];
351
+ };
352
+ async function generateTypeDefinitions(prompts) {
353
+ if (prompts[0].version === "1.0") {
354
+ return generateTypeDefinitionsV1_0(prompts);
355
+ }
356
+ return generateTypeDefinitionsV0(prompts);
357
+ }
358
+ async function fetchPromptsFrontmatter(options) {
359
+ if (options.local) {
360
+ const baseUrl = `http://localhost:${options.local}`;
361
+ try {
362
+ const pathsResponse = await fetch(`${baseUrl}/v1/prompts`);
363
+ if (!pathsResponse.ok) {
364
+ throw new Error(
365
+ `Failed to fetch prompt paths: ${pathsResponse.statusText}`
366
+ );
367
+ }
368
+ const { paths } = await pathsResponse.json();
369
+ return Promise.all(
370
+ paths.map(async (promptPath) => {
371
+ const templateResponse = await fetch(
372
+ `${baseUrl}/v1/templates?path=${promptPath}`
373
+ );
374
+ if (!templateResponse.ok) {
375
+ throw new Error(
376
+ `Failed to fetch template ${promptPath}: ${templateResponse.statusText}`
377
+ );
378
+ }
379
+ const { data: ast } = await templateResponse.json();
380
+ const yamlNode = ast.children.find(
381
+ (node) => node.type === "yaml"
382
+ );
383
+ if (!yamlNode) {
384
+ throw new Error(`No YAML frontmatter found in ${promptPath}`);
385
+ }
386
+ const { parse: parseYaml } = await import("yaml");
387
+ const frontmatter = parseYaml(yamlNode.value);
388
+ if (isNewFormat(frontmatter)) {
389
+ return {
390
+ path: promptPath,
391
+ ...frontmatter,
392
+ version: "1.0"
393
+ };
394
+ }
395
+ return {
396
+ path: promptPath,
397
+ ...frontmatter
398
+ };
399
+ })
400
+ );
401
+ } catch (error) {
402
+ if (error instanceof TypeError && error.message.includes("fetch failed")) {
403
+ console.error(`Connection failed to ${baseUrl}.`);
404
+ }
405
+ console.error("\nError details:", error);
406
+ throw error;
407
+ }
408
+ }
409
+ if (options.rootDir) {
410
+ if (!fs.existsSync(options.rootDir)) {
411
+ throw new Error(`Directory not found at: ${options.rootDir}`);
412
+ }
413
+ const promptFiles = await findPromptFiles(options.rootDir);
414
+ return Promise.all(
415
+ promptFiles.map(async (file) => {
416
+ const content = await fs.readFile(file, "utf-8");
417
+ const { attributes } = (0, import_front_matter.default)(content);
418
+ if (isNewFormat(attributes)) {
419
+ return {
420
+ path: import_path.default.relative(options.rootDir, file),
421
+ ...attributes,
422
+ version: "1.0"
423
+ };
424
+ }
425
+ return {
426
+ path: import_path.default.relative(options.rootDir, file),
427
+ ...attributes
428
+ };
429
+ })
430
+ );
431
+ }
432
+ throw new Error("Either --local or --root-dir must be specified");
433
+ }
434
+ async function generateToolTypes(tools) {
435
+ const toolArgTypes = [];
436
+ for (const [toolName, schema] of Object.entries(tools)) {
437
+ const typeName = `${getToolInterfaceName(toolName)}Args`;
438
+ try {
439
+ const compile = await getCompile();
440
+ const argInterface = schema.parameters ? await compile(schema.parameters, typeName, {
441
+ bannerComment: "",
442
+ additionalProperties: false
443
+ }) : `type ${typeName} = { ${Object.entries(schema.parameters || {}).map(([key]) => `${key}: any`).join("; ")} };`;
444
+ toolArgTypes.push(
445
+ argInterface.replace("export type", "type").replace("export interface", "interface")
446
+ );
447
+ } catch (error) {
448
+ console.error(`Error processing tool ${toolName}:`, error);
449
+ toolArgTypes.push(`type ${typeName} = { [key: string]: any };`);
450
+ }
451
+ }
452
+ if (Object.keys(tools).length > 0) {
453
+ const toolsInterface = `export interface Tools {
454
+ ${Object.keys(tools).map(
455
+ (toolName) => ` ${toolName}: { args: ${getToolInterfaceName(toolName)}Args };`
456
+ ).join("\n")}
457
+ }`;
458
+ return toolArgTypes.join("\n\n") + "\n\n" + toolsInterface + "\n\n";
459
+ }
460
+ return null;
461
+ }
462
+
463
+ // src/normalizer/types.ts
464
+ var SpanType = /* @__PURE__ */ ((SpanType2) => {
465
+ SpanType2["SPAN"] = "SPAN";
466
+ SpanType2["GENERATION"] = "GENERATION";
467
+ SpanType2["EVENT"] = "EVENT";
468
+ return SpanType2;
469
+ })(SpanType || {});
470
+
471
+ // src/normalizer/registry.ts
472
+ var TransformerRegistry = class {
473
+ constructor() {
474
+ this.transformers = /* @__PURE__ */ new Map();
475
+ this.defaultTransformer = null;
476
+ }
477
+ register(scope, transformer) {
478
+ this.transformers.set(scope, transformer);
479
+ }
480
+ setDefault(transformer) {
481
+ this.defaultTransformer = transformer;
482
+ }
483
+ getTransformer(scope) {
484
+ return this.transformers.get(scope) || this.defaultTransformer;
485
+ }
486
+ };
487
+ var registry = new TransformerRegistry();
488
+
489
+ // src/normalizer/transformers/ai-sdk/version-detector.ts
490
+ function detectVersion(attributes) {
491
+ if (attributes["ai.response.text"] !== void 0 && attributes["ai.response.text"] !== null || attributes["ai.response.toolCalls"] !== void 0 && attributes["ai.response.toolCalls"] !== null || attributes["ai.response.object"] !== void 0 && attributes["ai.response.object"] !== null) {
492
+ return "v5";
493
+ }
494
+ if (attributes["ai.result.text"] !== void 0 && attributes["ai.result.text"] !== null || attributes["ai.result.toolCalls"] !== void 0 && attributes["ai.result.toolCalls"] !== null || attributes["ai.result.object"] !== void 0 && attributes["ai.result.object"] !== null) {
495
+ return "v4";
496
+ }
497
+ if (attributes["ai.prompt.messages"] !== void 0 && attributes["ai.prompt.messages"] !== null || attributes["ai.prompt"] !== void 0 && attributes["ai.prompt"] !== null) {
498
+ return "v4";
499
+ }
500
+ return "unknown";
501
+ }
502
+
503
+ // src/normalizer/extractors/token-parser.ts
504
+ function parseTokens(attributes, keys) {
505
+ const result = {};
506
+ const parseIntSafe = (val) => {
507
+ if (typeof val === "number") return Math.floor(val);
508
+ if (typeof val === "string") {
509
+ try {
510
+ const parsed2 = JSON.parse(val);
511
+ if (typeof parsed2 === "number") return Math.floor(parsed2);
512
+ if (parsed2 && typeof parsed2.intValue === "number") return Math.floor(parsed2.intValue);
513
+ } catch {
514
+ }
515
+ const parsed = parseInt(val, 10);
516
+ return isNaN(parsed) ? void 0 : parsed;
517
+ }
518
+ return void 0;
519
+ };
520
+ if (keys.inputKey && attributes[keys.inputKey] !== void 0) {
521
+ result.inputTokens = parseIntSafe(attributes[keys.inputKey]);
522
+ } else if (keys.promptKey && attributes[keys.promptKey] !== void 0) {
523
+ result.inputTokens = parseIntSafe(attributes[keys.promptKey]);
524
+ }
525
+ if (keys.outputKey && attributes[keys.outputKey] !== void 0) {
526
+ result.outputTokens = parseIntSafe(attributes[keys.outputKey]);
527
+ } else if (keys.completionKey && attributes[keys.completionKey] !== void 0) {
528
+ result.outputTokens = parseIntSafe(attributes[keys.completionKey]);
529
+ }
530
+ if (keys.totalKey && attributes[keys.totalKey] !== void 0) {
531
+ result.totalTokens = parseIntSafe(attributes[keys.totalKey]);
532
+ }
533
+ if (result.totalTokens === void 0 && result.inputTokens !== void 0 && result.outputTokens !== void 0) {
534
+ result.totalTokens = result.inputTokens + result.outputTokens;
535
+ }
536
+ if (keys.reasoningKey && attributes[keys.reasoningKey] !== void 0) {
537
+ result.reasoningTokens = parseIntSafe(attributes[keys.reasoningKey]);
538
+ }
539
+ return result;
540
+ }
541
+
542
+ // src/normalizer/utils/key-sanitizer.ts
543
+ var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
544
+ function isSafeKey(key) {
545
+ return !DANGEROUS_KEYS.has(key);
546
+ }
547
+
548
+ // src/normalizer/extractors/metadata-parser.ts
549
+ var KNOWN_METADATA_FIELDS = /* @__PURE__ */ new Set([
550
+ "session_id",
551
+ "session_name",
552
+ "user_id",
553
+ "trace_name",
554
+ "dataset_run_id",
555
+ "dataset_run_name",
556
+ "dataset_path",
557
+ "dataset_item_name",
558
+ "dataset_expected_output",
559
+ "prompt_name",
560
+ "props",
561
+ "commit_sha"
562
+ ]);
563
+ function parseMetadata(attributes, prefix = "agentmark.metadata.") {
564
+ const result = {};
565
+ const get = (key) => attributes[`${prefix}${key}`];
566
+ if (get("session_id")) result.sessionId = String(get("session_id"));
567
+ if (get("session_name")) result.sessionName = String(get("session_name"));
568
+ if (get("user_id")) result.userId = String(get("user_id"));
569
+ if (get("trace_name")) result.traceName = String(get("trace_name"));
570
+ if (get("dataset_run_id")) result.datasetRunId = String(get("dataset_run_id"));
571
+ if (get("dataset_run_name")) result.datasetRunName = String(get("dataset_run_name"));
572
+ if (get("dataset_path")) result.datasetPath = String(get("dataset_path"));
573
+ if (get("dataset_item_name")) result.datasetItemName = String(get("dataset_item_name"));
574
+ if (get("dataset_expected_output")) result.datasetExpectedOutput = String(get("dataset_expected_output"));
575
+ if (get("prompt_name")) result.promptName = String(get("prompt_name"));
576
+ if (get("props")) result.props = String(get("props"));
577
+ if (get("commit_sha")) result.commitSha = String(get("commit_sha"));
578
+ return result;
579
+ }
580
+ function extractCustomMetadata(attributes, prefix = "agentmark.metadata.") {
581
+ const customMetadata = {};
582
+ for (const [key, value] of Object.entries(attributes)) {
583
+ if (key.startsWith(prefix)) {
584
+ const metadataKey = key.slice(prefix.length);
585
+ if (metadataKey && !KNOWN_METADATA_FIELDS.has(metadataKey) && isSafeKey(metadataKey)) {
586
+ customMetadata[metadataKey] = String(value);
587
+ }
588
+ }
589
+ }
590
+ return customMetadata;
591
+ }
592
+
593
+ // src/normalizer/transformers/ai-sdk/token-helpers.ts
594
+ function extractReasoningFromProviderMetadata(attributes) {
595
+ var _a;
596
+ const providerMetadata = attributes["ai.response.providerMetadata"];
597
+ if (!providerMetadata) return void 0;
598
+ try {
599
+ const parsed = typeof providerMetadata === "string" ? JSON.parse(providerMetadata) : providerMetadata;
600
+ if (((_a = parsed == null ? void 0 : parsed.openai) == null ? void 0 : _a.reasoningTokens) !== void 0) {
601
+ return typeof parsed.openai.reasoningTokens === "number" ? parsed.openai.reasoningTokens : void 0;
602
+ }
603
+ } catch {
604
+ }
605
+ return void 0;
606
+ }
607
+
608
+ // src/normalizer/transformers/ai-sdk/strategies/v4.ts
609
+ var AiSdkV4Strategy = class {
610
+ /**
611
+ * Normalize a content part from V4 format to standard format
612
+ */
613
+ normalizeContentPart(part) {
614
+ if (typeof part === "string") {
615
+ return part;
616
+ }
617
+ if (!part || typeof part !== "object") {
618
+ return part;
619
+ }
620
+ const type = part.type;
621
+ if (type === "text") {
622
+ return {
623
+ type: "text",
624
+ text: part.text || ""
625
+ };
626
+ }
627
+ if (type === "tool-call") {
628
+ return {
629
+ type: "tool-call",
630
+ toolCallId: part.toolCallId || "",
631
+ toolName: part.toolName || "",
632
+ args: part.args || {}
633
+ // V4 uses 'args' directly
634
+ };
635
+ }
636
+ if (type === "tool-result") {
637
+ return {
638
+ type: "tool-result",
639
+ toolCallId: part.toolCallId || "",
640
+ toolName: part.toolName || "",
641
+ result: part.result
642
+ // V4 uses 'result' directly
643
+ };
644
+ }
645
+ return part;
646
+ }
647
+ /**
648
+ * Normalize a single message from V4 format to standard format
649
+ */
650
+ normalizeMessage(message) {
651
+ if (!message || typeof message !== "object") {
652
+ return message;
653
+ }
654
+ const { role, content, ...rest } = message;
655
+ let normalizedContent;
656
+ if (typeof content === "string") {
657
+ normalizedContent = content;
658
+ } else if (Array.isArray(content)) {
659
+ normalizedContent = content.map((part) => this.normalizeContentPart(part));
660
+ } else if (content && typeof content === "object") {
661
+ normalizedContent = this.normalizeContentPart(content);
662
+ } else {
663
+ normalizedContent = content;
664
+ }
665
+ return {
666
+ role: role || "",
667
+ content: normalizedContent,
668
+ ...rest
669
+ };
670
+ }
671
+ /**
672
+ * Normalize messages array from V4 format to standard format
673
+ */
674
+ normalizeMessages(messages) {
675
+ if (!Array.isArray(messages)) {
676
+ return messages;
677
+ }
678
+ return messages.map((msg) => this.normalizeMessage(msg));
679
+ }
680
+ extractModel(attributes) {
681
+ return attributes["gen_ai.request.model"] || attributes["ai.model.id"];
682
+ }
683
+ extractInput(attributes) {
684
+ let messagesValue;
685
+ if (attributes["ai.prompt.messages"] !== void 0) {
686
+ messagesValue = attributes["ai.prompt.messages"];
687
+ } else if (attributes["ai.prompt"] !== void 0) {
688
+ const promptValue = attributes["ai.prompt"];
689
+ if (typeof promptValue === "string") {
690
+ try {
691
+ const parsed = JSON.parse(promptValue);
692
+ messagesValue = parsed.messages || parsed;
693
+ } catch {
694
+ return void 0;
695
+ }
696
+ } else {
697
+ messagesValue = promptValue.messages || promptValue;
698
+ }
699
+ } else {
700
+ return void 0;
701
+ }
702
+ let messages;
703
+ if (typeof messagesValue === "string") {
704
+ try {
705
+ messages = JSON.parse(messagesValue);
706
+ } catch {
707
+ return void 0;
708
+ }
709
+ } else {
710
+ messages = messagesValue;
711
+ }
712
+ if (!Array.isArray(messages)) {
713
+ return void 0;
714
+ }
715
+ return this.normalizeMessages(messages);
716
+ }
717
+ extractOutput(attributes) {
718
+ if (attributes["ai.result.text"] !== void 0) return attributes["ai.result.text"];
719
+ if (attributes["ai.response.text"] !== void 0) return attributes["ai.response.text"];
720
+ return void 0;
721
+ }
722
+ extractOutputObject(attributes) {
723
+ let objValue;
724
+ if (attributes["ai.result.object"] !== void 0) {
725
+ objValue = attributes["ai.result.object"];
726
+ } else if (attributes["ai.response.object"] !== void 0) {
727
+ objValue = attributes["ai.response.object"];
728
+ } else {
729
+ return void 0;
730
+ }
731
+ if (typeof objValue === "string") {
732
+ try {
733
+ return JSON.parse(objValue);
734
+ } catch {
735
+ return void 0;
736
+ }
737
+ }
738
+ return objValue;
739
+ }
740
+ extractToolCalls(attributes) {
741
+ let toolCallsValue;
742
+ if (attributes["ai.result.toolCalls"] !== void 0) {
743
+ toolCallsValue = attributes["ai.result.toolCalls"];
744
+ } else if (attributes["ai.response.toolCalls"] !== void 0) {
745
+ toolCallsValue = attributes["ai.response.toolCalls"];
746
+ } else {
747
+ if (attributes["ai.toolCall.name"] !== void 0) {
748
+ const toolCallId = attributes["ai.toolCall.id"];
749
+ const toolName = attributes["ai.toolCall.name"];
750
+ const argsValue = attributes["ai.toolCall.args"];
751
+ const resultValue = attributes["ai.toolCall.result"];
752
+ if (toolCallId && toolName) {
753
+ let args = {};
754
+ if (argsValue !== void 0) {
755
+ if (typeof argsValue === "string") {
756
+ try {
757
+ args = JSON.parse(argsValue);
758
+ } catch {
759
+ args = {};
760
+ }
761
+ } else if (typeof argsValue === "object" && argsValue !== null) {
762
+ args = argsValue;
763
+ }
764
+ }
765
+ let result;
766
+ if (resultValue !== void 0) {
767
+ if (typeof resultValue === "string") {
768
+ result = resultValue;
769
+ } else {
770
+ try {
771
+ result = JSON.stringify(resultValue);
772
+ } catch {
773
+ result = String(resultValue);
774
+ }
775
+ }
776
+ }
777
+ return [{
778
+ type: "tool-call",
779
+ toolCallId: String(toolCallId),
780
+ toolName: String(toolName),
781
+ args,
782
+ result
783
+ }];
784
+ }
785
+ }
786
+ return void 0;
787
+ }
788
+ let toolCalls;
789
+ if (typeof toolCallsValue === "string") {
790
+ try {
791
+ toolCalls = JSON.parse(toolCallsValue);
792
+ } catch {
793
+ return void 0;
794
+ }
795
+ } else {
796
+ toolCalls = toolCallsValue;
797
+ }
798
+ if (!Array.isArray(toolCalls)) {
799
+ return void 0;
800
+ }
801
+ return toolCalls.map((tc) => ({
802
+ type: tc.type || "tool-call",
803
+ toolCallId: tc.toolCallId,
804
+ toolName: tc.toolName,
805
+ args: tc.args || tc.input || {}
806
+ // v4 uses 'args', normalize to 'args'
807
+ }));
808
+ }
809
+ extractFinishReason(attributes) {
810
+ if (attributes["ai.result.finishReason"] !== void 0) {
811
+ return String(attributes["ai.result.finishReason"]);
812
+ }
813
+ if (attributes["ai.response.finishReason"] !== void 0) {
814
+ return String(attributes["ai.response.finishReason"]);
815
+ }
816
+ if (attributes["gen_ai.response.finish_reasons"] !== void 0) {
817
+ const reasons = attributes["gen_ai.response.finish_reasons"];
818
+ if (Array.isArray(reasons) && reasons.length > 0) {
819
+ return String(reasons[0]);
820
+ }
821
+ return String(reasons);
822
+ }
823
+ return void 0;
824
+ }
825
+ extractSettings(attributes) {
826
+ var _a, _b, _c, _d, _e;
827
+ const settings = {};
828
+ if (attributes["gen_ai.request.temperature"] !== void 0 || attributes["ai.settings.temperature"] !== void 0) {
829
+ const value = (_a = attributes["gen_ai.request.temperature"]) != null ? _a : attributes["ai.settings.temperature"];
830
+ settings.temperature = typeof value === "number" ? value : parseFloat(String(value));
831
+ }
832
+ if (attributes["gen_ai.request.max_tokens"] !== void 0 || attributes["ai.settings.maxTokens"] !== void 0) {
833
+ const value = (_b = attributes["gen_ai.request.max_tokens"]) != null ? _b : attributes["ai.settings.maxTokens"];
834
+ settings.maxTokens = typeof value === "number" ? value : parseInt(String(value), 10);
835
+ }
836
+ if (attributes["gen_ai.request.top_p"] !== void 0 || attributes["ai.settings.topP"] !== void 0) {
837
+ const value = (_c = attributes["gen_ai.request.top_p"]) != null ? _c : attributes["ai.settings.topP"];
838
+ settings.topP = typeof value === "number" ? value : parseFloat(String(value));
839
+ }
840
+ if (attributes["gen_ai.request.presence_penalty"] !== void 0 || attributes["ai.settings.presencePenalty"] !== void 0) {
841
+ const value = (_d = attributes["gen_ai.request.presence_penalty"]) != null ? _d : attributes["ai.settings.presencePenalty"];
842
+ settings.presencePenalty = typeof value === "number" ? value : parseFloat(String(value));
843
+ }
844
+ if (attributes["gen_ai.request.frequency_penalty"] !== void 0 || attributes["ai.settings.frequencyPenalty"] !== void 0) {
845
+ const value = (_e = attributes["gen_ai.request.frequency_penalty"]) != null ? _e : attributes["ai.settings.frequencyPenalty"];
846
+ settings.frequencyPenalty = typeof value === "number" ? value : parseFloat(String(value));
847
+ }
848
+ return Object.keys(settings).length > 0 ? settings : void 0;
849
+ }
850
+ extractTokens(attributes) {
851
+ const tokens = parseTokens(attributes, {
852
+ inputKey: "gen_ai.usage.prompt_tokens",
853
+ outputKey: "gen_ai.usage.completion_tokens",
854
+ totalKey: "gen_ai.usage.total_tokens",
855
+ promptKey: "ai.usage.promptTokens",
856
+ // SDK specific fallback
857
+ completionKey: "ai.usage.completionTokens"
858
+ // SDK specific fallback
859
+ });
860
+ tokens.reasoningTokens = extractReasoningFromProviderMetadata(attributes);
861
+ if (!tokens.reasoningTokens) {
862
+ tokens.reasoningTokens = 0;
863
+ }
864
+ return {
865
+ input: tokens.inputTokens,
866
+ output: tokens.outputTokens,
867
+ total: tokens.totalTokens,
868
+ reasoning: tokens.reasoningTokens
869
+ };
870
+ }
871
+ extractMetadata(attributes) {
872
+ const result = parseMetadata(attributes);
873
+ const aiTelemetryResult = parseMetadata(attributes, "ai.telemetry.metadata.");
874
+ const agentmarkCustomMetadata = extractCustomMetadata(attributes, "agentmark.metadata.");
875
+ const aiTelemetryCustomMetadata = extractCustomMetadata(attributes, "ai.telemetry.metadata.");
876
+ const mergedCustomMetadata = {
877
+ ...agentmarkCustomMetadata,
878
+ ...aiTelemetryCustomMetadata
879
+ };
880
+ return {
881
+ ...result,
882
+ ...aiTelemetryResult,
883
+ // Only include metadata field if there are custom metadata keys
884
+ ...Object.keys(mergedCustomMetadata).length > 0 ? { metadata: mergedCustomMetadata } : {}
885
+ };
886
+ }
887
+ };
888
+
889
+ // src/normalizer/transformers/ai-sdk/strategies/v5.ts
890
+ var AiSdkV5Strategy = class {
891
+ /**
892
+ * Normalize a content part from V5 format to standard format
893
+ */
894
+ normalizeContentPart(part) {
895
+ if (typeof part === "string") {
896
+ return part;
897
+ }
898
+ if (!part || typeof part !== "object") {
899
+ return part;
900
+ }
901
+ const type = part.type;
902
+ if (type === "text") {
903
+ return {
904
+ type: "text",
905
+ text: part.text || ""
906
+ };
907
+ }
908
+ if (type === "tool-call") {
909
+ return {
910
+ type: "tool-call",
911
+ toolCallId: part.toolCallId || "",
912
+ toolName: part.toolName || "",
913
+ args: part.input || part.args || {}
914
+ // V5 uses 'input', normalize to 'args'
915
+ };
916
+ }
917
+ if (type === "tool-result") {
918
+ let normalizedResult;
919
+ if (part.output !== void 0) {
920
+ if (typeof part.output === "object" && part.output !== null) {
921
+ if ("value" in part.output) {
922
+ normalizedResult = part.output.value;
923
+ } else {
924
+ normalizedResult = part.output;
925
+ }
926
+ } else {
927
+ normalizedResult = part.output;
928
+ }
929
+ } else if (part.result !== void 0) {
930
+ normalizedResult = part.result;
931
+ } else {
932
+ normalizedResult = void 0;
933
+ }
934
+ return {
935
+ type: "tool-result",
936
+ toolCallId: part.toolCallId || "",
937
+ toolName: part.toolName || "",
938
+ result: normalizedResult
939
+ };
940
+ }
941
+ return part;
942
+ }
943
+ /**
944
+ * Normalize a single message from V5 format to standard format
945
+ */
946
+ normalizeMessage(message) {
947
+ if (!message || typeof message !== "object") {
948
+ return message;
949
+ }
950
+ const { role, content, ...rest } = message;
951
+ let normalizedContent;
952
+ if (typeof content === "string") {
953
+ normalizedContent = content;
954
+ } else if (Array.isArray(content)) {
955
+ normalizedContent = content.map((part) => this.normalizeContentPart(part));
956
+ } else if (content && typeof content === "object") {
957
+ normalizedContent = this.normalizeContentPart(content);
958
+ } else {
959
+ normalizedContent = content;
960
+ }
961
+ return {
962
+ role: role || "",
963
+ content: normalizedContent,
964
+ ...rest
965
+ };
966
+ }
967
+ /**
968
+ * Normalize messages array from V5 format to standard format
969
+ */
970
+ normalizeMessages(messages) {
971
+ if (!Array.isArray(messages)) {
972
+ return messages;
973
+ }
974
+ return messages.map((msg) => this.normalizeMessage(msg));
975
+ }
976
+ extractModel(attributes) {
977
+ return attributes["gen_ai.request.model"] || attributes["ai.model.id"];
978
+ }
979
+ extractInput(attributes) {
980
+ let messagesValue;
981
+ if (attributes["ai.prompt.messages"] !== void 0) {
982
+ messagesValue = attributes["ai.prompt.messages"];
983
+ } else if (attributes["ai.prompt"] !== void 0) {
984
+ const promptValue = attributes["ai.prompt"];
985
+ if (typeof promptValue === "string") {
986
+ try {
987
+ const parsed = JSON.parse(promptValue);
988
+ messagesValue = parsed.messages || parsed;
989
+ } catch {
990
+ return void 0;
991
+ }
992
+ } else {
993
+ messagesValue = promptValue.messages || promptValue;
994
+ }
995
+ } else {
996
+ return void 0;
997
+ }
998
+ let messages;
999
+ if (typeof messagesValue === "string") {
1000
+ try {
1001
+ messages = JSON.parse(messagesValue);
1002
+ } catch {
1003
+ return void 0;
1004
+ }
1005
+ } else {
1006
+ messages = messagesValue;
1007
+ }
1008
+ if (!Array.isArray(messages)) {
1009
+ return void 0;
1010
+ }
1011
+ return this.normalizeMessages(messages);
1012
+ }
1013
+ extractOutput(attributes) {
1014
+ if (attributes["ai.response.text"] !== void 0) return attributes["ai.response.text"];
1015
+ return void 0;
1016
+ }
1017
+ extractOutputObject(attributes) {
1018
+ if (attributes["ai.response.object"] === void 0) {
1019
+ return void 0;
1020
+ }
1021
+ const objValue = attributes["ai.response.object"];
1022
+ if (typeof objValue === "string") {
1023
+ try {
1024
+ return JSON.parse(objValue);
1025
+ } catch {
1026
+ return void 0;
1027
+ }
1028
+ }
1029
+ if (typeof objValue === "object" && objValue !== null) {
1030
+ return objValue;
1031
+ }
1032
+ return void 0;
1033
+ }
1034
+ extractToolCalls(attributes) {
1035
+ if (attributes["ai.response.toolCalls"] !== void 0) {
1036
+ const toolCallsValue = attributes["ai.response.toolCalls"];
1037
+ let toolCalls;
1038
+ if (typeof toolCallsValue === "string") {
1039
+ try {
1040
+ toolCalls = JSON.parse(toolCallsValue);
1041
+ } catch {
1042
+ return void 0;
1043
+ }
1044
+ } else {
1045
+ toolCalls = toolCallsValue;
1046
+ }
1047
+ if (!Array.isArray(toolCalls)) {
1048
+ return void 0;
1049
+ }
1050
+ return toolCalls.map((tc) => ({
1051
+ type: tc.type || "tool-call",
1052
+ toolCallId: tc.toolCallId,
1053
+ toolName: tc.toolName,
1054
+ args: tc.input || tc.args || {},
1055
+ // v5 uses 'input', normalize to 'args'
1056
+ providerMetadata: tc.providerMetadata || tc.providerOptions
1057
+ }));
1058
+ }
1059
+ if (attributes["ai.toolCall.name"] !== void 0) {
1060
+ const toolCallId = attributes["ai.toolCall.id"];
1061
+ const toolName = attributes["ai.toolCall.name"];
1062
+ const argsValue = attributes["ai.toolCall.args"];
1063
+ const resultValue = attributes["ai.toolCall.result"];
1064
+ if (toolCallId && toolName) {
1065
+ let args = {};
1066
+ if (argsValue !== void 0) {
1067
+ if (typeof argsValue === "string") {
1068
+ try {
1069
+ args = JSON.parse(argsValue);
1070
+ } catch {
1071
+ args = {};
1072
+ }
1073
+ } else if (typeof argsValue === "object" && argsValue !== null) {
1074
+ args = argsValue;
1075
+ }
1076
+ }
1077
+ let result;
1078
+ if (resultValue !== void 0) {
1079
+ if (typeof resultValue === "string") {
1080
+ result = resultValue;
1081
+ } else {
1082
+ try {
1083
+ result = JSON.stringify(resultValue);
1084
+ } catch {
1085
+ result = String(resultValue);
1086
+ }
1087
+ }
1088
+ }
1089
+ return [{
1090
+ type: "tool-call",
1091
+ toolCallId: String(toolCallId),
1092
+ toolName: String(toolName),
1093
+ args,
1094
+ result
1095
+ }];
1096
+ }
1097
+ }
1098
+ return void 0;
1099
+ }
1100
+ extractFinishReason(attributes) {
1101
+ if (attributes["ai.response.finishReason"] !== void 0) {
1102
+ return String(attributes["ai.response.finishReason"]);
1103
+ }
1104
+ if (attributes["gen_ai.response.finish_reasons"] !== void 0) {
1105
+ const reasons = attributes["gen_ai.response.finish_reasons"];
1106
+ if (Array.isArray(reasons) && reasons.length > 0) {
1107
+ return String(reasons[0]);
1108
+ }
1109
+ return String(reasons);
1110
+ }
1111
+ return void 0;
1112
+ }
1113
+ extractSettings(attributes) {
1114
+ var _a, _b, _c, _d, _e;
1115
+ const settings = {};
1116
+ if (attributes["gen_ai.request.temperature"] !== void 0 || attributes["ai.settings.temperature"] !== void 0) {
1117
+ const value = (_a = attributes["gen_ai.request.temperature"]) != null ? _a : attributes["ai.settings.temperature"];
1118
+ settings.temperature = typeof value === "number" ? value : parseFloat(String(value));
1119
+ }
1120
+ if (attributes["gen_ai.request.max_tokens"] !== void 0 || attributes["ai.settings.maxTokens"] !== void 0) {
1121
+ const value = (_b = attributes["gen_ai.request.max_tokens"]) != null ? _b : attributes["ai.settings.maxTokens"];
1122
+ settings.maxTokens = typeof value === "number" ? value : parseInt(String(value), 10);
1123
+ }
1124
+ if (attributes["gen_ai.request.top_p"] !== void 0 || attributes["ai.settings.topP"] !== void 0) {
1125
+ const value = (_c = attributes["gen_ai.request.top_p"]) != null ? _c : attributes["ai.settings.topP"];
1126
+ settings.topP = typeof value === "number" ? value : parseFloat(String(value));
1127
+ }
1128
+ if (attributes["gen_ai.request.presence_penalty"] !== void 0 || attributes["ai.settings.presencePenalty"] !== void 0) {
1129
+ const value = (_d = attributes["gen_ai.request.presence_penalty"]) != null ? _d : attributes["ai.settings.presencePenalty"];
1130
+ settings.presencePenalty = typeof value === "number" ? value : parseFloat(String(value));
1131
+ }
1132
+ if (attributes["gen_ai.request.frequency_penalty"] !== void 0 || attributes["ai.settings.frequencyPenalty"] !== void 0) {
1133
+ const value = (_e = attributes["gen_ai.request.frequency_penalty"]) != null ? _e : attributes["ai.settings.frequencyPenalty"];
1134
+ settings.frequencyPenalty = typeof value === "number" ? value : parseFloat(String(value));
1135
+ }
1136
+ return Object.keys(settings).length > 0 ? settings : void 0;
1137
+ }
1138
+ extractTokens(attributes) {
1139
+ const tokens = parseTokens(attributes, {
1140
+ inputKey: "gen_ai.usage.input_tokens",
1141
+ outputKey: "gen_ai.usage.output_tokens",
1142
+ totalKey: "gen_ai.usage.total_tokens",
1143
+ promptKey: "ai.usage.promptTokens",
1144
+ // SDK specific fallback
1145
+ completionKey: "ai.usage.completionTokens",
1146
+ // SDK specific fallback
1147
+ reasoningKey: "ai.usage.reasoningTokens"
1148
+ // AI SDK v5 uses this
1149
+ });
1150
+ if (tokens.reasoningTokens === void 0) {
1151
+ tokens.reasoningTokens = extractReasoningFromProviderMetadata(attributes);
1152
+ }
1153
+ if (!tokens.reasoningTokens) {
1154
+ tokens.reasoningTokens = 0;
1155
+ }
1156
+ return {
1157
+ input: tokens.inputTokens,
1158
+ output: tokens.outputTokens,
1159
+ total: tokens.totalTokens,
1160
+ reasoning: tokens.reasoningTokens
1161
+ };
1162
+ }
1163
+ extractMetadata(attributes) {
1164
+ const result = parseMetadata(attributes);
1165
+ const aiTelemetryResult = parseMetadata(attributes, "ai.telemetry.metadata.");
1166
+ const agentmarkCustomMetadata = extractCustomMetadata(attributes, "agentmark.metadata.");
1167
+ const aiTelemetryCustomMetadata = extractCustomMetadata(attributes, "ai.telemetry.metadata.");
1168
+ const mergedCustomMetadata = {
1169
+ ...agentmarkCustomMetadata,
1170
+ ...aiTelemetryCustomMetadata
1171
+ };
1172
+ return {
1173
+ ...result,
1174
+ ...aiTelemetryResult,
1175
+ // Only include metadata field if there are custom metadata keys
1176
+ ...Object.keys(mergedCustomMetadata).length > 0 ? { metadata: mergedCustomMetadata } : {}
1177
+ };
1178
+ }
1179
+ };
1180
+
1181
+ // src/normalizer/transformers/ai-sdk/index.ts
1182
+ var AiSdkTransformer = class {
1183
+ constructor() {
1184
+ this.strategies = {
1185
+ v4: new AiSdkV4Strategy(),
1186
+ v5: new AiSdkV5Strategy()
1187
+ };
1188
+ }
1189
+ classify(span, _attributes) {
1190
+ const isGenerationSpan = span.name === "ai.generateText.doGenerate" || span.name === "ai.streamText.doStream" || span.name === "ai.generateObject.doGenerate" || span.name === "ai.streamObject.doStream";
1191
+ return isGenerationSpan ? "GENERATION" /* GENERATION */ : "SPAN" /* SPAN */;
1192
+ }
1193
+ transform(_span, attributes) {
1194
+ const version = detectVersion(attributes);
1195
+ const strategy = version === "v5" ? this.strategies.v5 : this.strategies.v4;
1196
+ const tokens = strategy.extractTokens(attributes);
1197
+ const toolCalls = strategy.extractToolCalls(attributes);
1198
+ const result = {
1199
+ model: strategy.extractModel(attributes),
1200
+ input: strategy.extractInput(attributes),
1201
+ output: strategy.extractOutput(attributes),
1202
+ outputObject: strategy.extractOutputObject(attributes),
1203
+ toolCalls,
1204
+ finishReason: strategy.extractFinishReason(attributes),
1205
+ settings: strategy.extractSettings(attributes),
1206
+ inputTokens: tokens.input,
1207
+ outputTokens: tokens.output,
1208
+ totalTokens: tokens.total,
1209
+ reasoningTokens: tokens.reasoning,
1210
+ ...strategy.extractMetadata(attributes)
1211
+ };
1212
+ const toolName = attributes["ai.toolCall.name"];
1213
+ if (toolName && typeof toolName === "string") {
1214
+ result.name = toolName;
1215
+ }
1216
+ return result;
1217
+ }
1218
+ };
1219
+
1220
+ // src/normalizer/transformers/mastra/index.ts
1221
+ var MastraTransformer = class {
1222
+ classify(span, _attributes) {
1223
+ const isGenerationSpan = span.name === "agent.streamLegacy" || span.name === "agent.stream" || span.name === "agent.streamObject" || span.name === "agent.generate" || span.name === "agent.generateObject";
1224
+ return isGenerationSpan ? "GENERATION" /* GENERATION */ : "SPAN" /* SPAN */;
1225
+ }
1226
+ transform(span, attributes) {
1227
+ const result = {};
1228
+ const modelConfig = this.extractModelConfig(attributes, span);
1229
+ if (modelConfig == null ? void 0 : modelConfig.modelId) {
1230
+ result.model = modelConfig.modelId;
1231
+ }
1232
+ const input = this.extractInput(span, attributes);
1233
+ if (input) {
1234
+ result.input = input;
1235
+ }
1236
+ const streamResult = this.extractStreamResult(span, attributes);
1237
+ if (streamResult) {
1238
+ if (streamResult.output) {
1239
+ result.output = streamResult.output;
1240
+ }
1241
+ if (streamResult.outputObject) {
1242
+ result.outputObject = streamResult.outputObject;
1243
+ }
1244
+ if (streamResult.usage) {
1245
+ result.inputTokens = streamResult.usage.promptTokens;
1246
+ result.outputTokens = streamResult.usage.completionTokens;
1247
+ result.totalTokens = streamResult.usage.totalTokens;
1248
+ }
1249
+ }
1250
+ if (attributes["agentmark.trace_name"]) {
1251
+ result.traceName = attributes["agentmark.trace_name"];
1252
+ } else if (attributes["componentName"]) {
1253
+ result.traceName = attributes["componentName"];
1254
+ }
1255
+ if (modelConfig == null ? void 0 : modelConfig.settings) {
1256
+ result.settings = modelConfig.settings;
1257
+ }
1258
+ return result;
1259
+ }
1260
+ extractModelConfig(attributes, _span) {
1261
+ var _a, _b;
1262
+ const resolveModelConfigResult = attributes["agent.resolveModelConfig.result"];
1263
+ if (resolveModelConfigResult) {
1264
+ try {
1265
+ const config = typeof resolveModelConfigResult === "string" ? JSON.parse(resolveModelConfigResult) : resolveModelConfigResult;
1266
+ if (config.modelId) {
1267
+ return {
1268
+ modelId: config.modelId,
1269
+ provider: (_a = config.config) == null ? void 0 : _a.provider,
1270
+ settings: config.settings
1271
+ };
1272
+ }
1273
+ } catch {
1274
+ }
1275
+ }
1276
+ const prepareLLMOptionsResult = attributes["agent.prepareLLMOptions.result"];
1277
+ if (prepareLLMOptionsResult) {
1278
+ try {
1279
+ const result = typeof prepareLLMOptionsResult === "string" ? JSON.parse(prepareLLMOptionsResult) : prepareLLMOptionsResult;
1280
+ if ((_b = result.llm) == null ? void 0 : _b.name) {
1281
+ }
1282
+ } catch {
1283
+ }
1284
+ }
1285
+ return null;
1286
+ }
1287
+ extractInput(span, attributes) {
1288
+ const spanName = span.name;
1289
+ const argument0 = attributes[`${spanName}.argument.0`] || attributes["agent.prepareLLMOptions.argument.0"] || attributes["agent.stream.argument.0"] || attributes["agent.streamLegacy.argument.0"];
1290
+ if (argument0) {
1291
+ try {
1292
+ const messages = typeof argument0 === "string" ? JSON.parse(argument0) : argument0;
1293
+ if (Array.isArray(messages)) {
1294
+ return messages;
1295
+ }
1296
+ } catch {
1297
+ }
1298
+ }
1299
+ return void 0;
1300
+ }
1301
+ extractStreamResult(span, attributes) {
1302
+ const spanName = span.name;
1303
+ const resultAttr = attributes[`${spanName}.result`] || attributes["agent.stream.result"] || attributes["agent.streamLegacy.result"] || attributes["agent.streamObject.result"];
1304
+ if (resultAttr) {
1305
+ try {
1306
+ const result = typeof resultAttr === "string" ? JSON.parse(resultAttr) : resultAttr;
1307
+ const extracted = {};
1308
+ if (result.usage) {
1309
+ extracted.usage = {
1310
+ promptTokens: result.usage.promptTokens,
1311
+ completionTokens: result.usage.completionTokens,
1312
+ totalTokens: result.usage.totalTokens
1313
+ };
1314
+ }
1315
+ if (result.object) {
1316
+ extracted.outputObject = result.object;
1317
+ extracted.output = JSON.stringify(result.object);
1318
+ } else if (result.text) {
1319
+ extracted.output = result.text;
1320
+ } else if (result.response) {
1321
+ if (typeof result.response === "string") {
1322
+ extracted.output = result.response;
1323
+ } else {
1324
+ extracted.output = JSON.stringify(result.response);
1325
+ extracted.outputObject = result.response;
1326
+ }
1327
+ }
1328
+ return extracted;
1329
+ } catch {
1330
+ }
1331
+ }
1332
+ return null;
1333
+ }
1334
+ };
1335
+
1336
+ // src/normalizer/converters/otlp-converter.ts
1337
+ function convertOtlpValue(value) {
1338
+ var _a;
1339
+ if (value.stringValue !== void 0) {
1340
+ return value.stringValue;
1341
+ }
1342
+ if (value.intValue !== void 0) {
1343
+ return typeof value.intValue === "string" ? parseInt(value.intValue, 10) : value.intValue;
1344
+ }
1345
+ if (value.doubleValue !== void 0) {
1346
+ return value.doubleValue;
1347
+ }
1348
+ if (value.boolValue !== void 0) {
1349
+ return value.boolValue;
1350
+ }
1351
+ if ((_a = value.arrayValue) == null ? void 0 : _a.values) {
1352
+ return value.arrayValue.values.map(convertOtlpValue);
1353
+ }
1354
+ if (value.bytesValue !== void 0) {
1355
+ return value.bytesValue;
1356
+ }
1357
+ return void 0;
1358
+ }
1359
+ function convertOtlpAttributes(attributes) {
1360
+ if (!attributes || attributes.length === 0) {
1361
+ return {};
1362
+ }
1363
+ const result = {};
1364
+ for (const attr of attributes) {
1365
+ if (attr.key && isSafeKey(attr.key)) {
1366
+ result[attr.key] = convertOtlpValue(attr.value);
1367
+ }
1368
+ }
1369
+ return result;
1370
+ }
1371
+ function extractResourceScopeSpan(resourceSpans) {
1372
+ var _a, _b, _c;
1373
+ const result = [];
1374
+ const resourceAttributes = convertOtlpAttributes((_a = resourceSpans.resource) == null ? void 0 : _a.attributes);
1375
+ for (const scopeSpans of resourceSpans.scopeSpans || []) {
1376
+ const scope = {
1377
+ name: (_b = scopeSpans.scope) == null ? void 0 : _b.name,
1378
+ version: (_c = scopeSpans.scope) == null ? void 0 : _c.version
1379
+ };
1380
+ for (const otlpSpan of scopeSpans.spans || []) {
1381
+ const spanAttributes = convertOtlpAttributes(otlpSpan.attributes);
1382
+ const events = (otlpSpan.events || []).map((otlpEvent) => ({
1383
+ timeUnixNano: otlpEvent.timeUnixNano,
1384
+ name: otlpEvent.name,
1385
+ attributes: convertOtlpAttributes(otlpEvent.attributes)
1386
+ }));
1387
+ const links = (otlpSpan.links || []).map((otlpLink) => ({
1388
+ traceId: otlpLink.traceId,
1389
+ spanId: otlpLink.spanId,
1390
+ traceState: otlpLink.traceState,
1391
+ attributes: convertOtlpAttributes(otlpLink.attributes)
1392
+ }));
1393
+ const span = {
1394
+ traceId: otlpSpan.traceId,
1395
+ spanId: otlpSpan.spanId,
1396
+ parentSpanId: otlpSpan.parentSpanId,
1397
+ traceState: otlpSpan.traceState,
1398
+ name: otlpSpan.name,
1399
+ kind: otlpSpan.kind,
1400
+ startTimeUnixNano: otlpSpan.startTimeUnixNano,
1401
+ endTimeUnixNano: otlpSpan.endTimeUnixNano,
1402
+ attributes: spanAttributes,
1403
+ events,
1404
+ links,
1405
+ status: otlpSpan.status
1406
+ };
1407
+ const resource = {
1408
+ attributes: resourceAttributes
1409
+ };
1410
+ result.push({ resource, scope, span });
1411
+ }
1412
+ }
1413
+ return result;
1414
+ }
1415
+
1416
+ // src/normalizer/extractors/agentmark-parser.ts
1417
+ function parseAgentMarkAttributes(attributes, prefix = "agentmark.") {
1418
+ const result = {};
1419
+ const get = (key) => attributes[`${prefix}${key}`];
1420
+ if (get("session_id")) result.sessionId = String(get("session_id"));
1421
+ if (get("session_name")) result.sessionName = String(get("session_name"));
1422
+ if (get("user_id")) result.userId = String(get("user_id"));
1423
+ if (get("trace_name")) result.traceName = String(get("trace_name"));
1424
+ if (get("dataset_run_id")) result.datasetRunId = String(get("dataset_run_id"));
1425
+ if (get("dataset_run_name")) result.datasetRunName = String(get("dataset_run_name"));
1426
+ if (get("dataset_item_name")) result.datasetItemName = String(get("dataset_item_name"));
1427
+ if (get("dataset_expected_output")) result.datasetExpectedOutput = String(get("dataset_expected_output"));
1428
+ return result;
1429
+ }
1430
+
1431
+ // src/normalizer/type-classifier.ts
1432
+ var TypeClassifier = class {
1433
+ classify(span, attributes) {
1434
+ if (attributes["gen_ai.system"] || attributes["gen_ai.request.model"] || attributes["gen_ai.operation.name"]) {
1435
+ return "GENERATION" /* GENERATION */;
1436
+ }
1437
+ if (attributes["ai.response.text"] || attributes["ai.result.text"] || attributes["ai.response.toolCalls"] || attributes["ai.result.toolCalls"]) {
1438
+ return "GENERATION" /* GENERATION */;
1439
+ }
1440
+ if (span.name.startsWith("ai.generate") || span.name.startsWith("ai.stream")) {
1441
+ return "GENERATION" /* GENERATION */;
1442
+ }
1443
+ return "SPAN" /* SPAN */;
1444
+ }
1445
+ };
1446
+ var typeClassifier = new TypeClassifier();
1447
+
1448
+ // src/normalizer/index.ts
1449
+ registry.register("ai", new AiSdkTransformer());
1450
+ registry.register("default-tracer", new MastraTransformer());
1451
+ registry.setDefault(new AiSdkTransformer());
1452
+ function normalizeSpan(resource, scope, span) {
1453
+ var _a, _b, _c;
1454
+ const allAttributes = {
1455
+ ...resource.attributes || {},
1456
+ ...span.attributes || {}
1457
+ };
1458
+ const transformer = registry.getTransformer(scope.name || "");
1459
+ const type = transformer ? transformer.classify(span, allAttributes) : "SPAN" /* SPAN */;
1460
+ const startNs = BigInt(span.startTimeUnixNano);
1461
+ const endNs = BigInt(span.endTimeUnixNano);
1462
+ const startMsInt = startNs / BigInt(1e6);
1463
+ const startMsRemainder = Number(startNs % BigInt(1e6)) / 1e6;
1464
+ const endMsInt = endNs / BigInt(1e6);
1465
+ const endMsRemainder = Number(endNs % BigInt(1e6)) / 1e6;
1466
+ const startMs = Number(startMsInt) + startMsRemainder;
1467
+ const endMs = Number(endMsInt) + endMsRemainder;
1468
+ const normalized = {
1469
+ // Identity
1470
+ traceId: span.traceId,
1471
+ spanId: span.spanId,
1472
+ parentSpanId: span.parentSpanId,
1473
+ traceState: span.traceState,
1474
+ // Type
1475
+ type,
1476
+ // Timing (convert nanoseconds to milliseconds: divide by 1,000,000)
1477
+ startTime: startMs,
1478
+ endTime: endMs,
1479
+ duration: endMs - startMs,
1480
+ // Metadata
1481
+ name: span.name,
1482
+ kind: span.kind.toString(),
1483
+ serviceName: (_a = resource.attributes) == null ? void 0 : _a["service.name"],
1484
+ statusCode: ((_b = span.status) == null ? void 0 : _b.code.toString()) || "0",
1485
+ statusMessage: (_c = span.status) == null ? void 0 : _c.message,
1486
+ // Raw Data
1487
+ resourceAttributes: resource.attributes || {},
1488
+ spanAttributes: span.attributes || {},
1489
+ events: (span.events || []).map((e) => ({
1490
+ timestamp: Number(BigInt(e.timeUnixNano)) / 1e6,
1491
+ name: e.name,
1492
+ attributes: e.attributes || {}
1493
+ })),
1494
+ links: (span.links || []).map((l) => ({
1495
+ traceId: l.traceId,
1496
+ spanId: l.spanId,
1497
+ traceState: l.traceState,
1498
+ attributes: l.attributes
1499
+ }))
1500
+ };
1501
+ if (transformer) {
1502
+ const transformed = transformer.transform(span, allAttributes);
1503
+ Object.assign(normalized, transformed);
1504
+ }
1505
+ const agentMarkAttributes = parseAgentMarkAttributes(allAttributes);
1506
+ Object.assign(normalized, agentMarkAttributes);
1507
+ return normalized;
1508
+ }
1509
+ function normalizeOtlpSpans(resourceSpans) {
1510
+ const normalizedSpans = [];
1511
+ for (const resourceSpan of resourceSpans) {
1512
+ const extracted = extractResourceScopeSpan(resourceSpan);
1513
+ for (const { resource, scope, span } of extracted) {
1514
+ normalizedSpans.push(normalizeSpan(resource, scope, span));
1515
+ }
1516
+ }
1517
+ return normalizedSpans;
1518
+ }
1519
+ // Annotate the CommonJS export names for ESM import in node:
1520
+ 0 && (module.exports = {
1521
+ AiSdkTransformer,
1522
+ MastraTransformer,
1523
+ SpanType,
1524
+ TransformerRegistry,
1525
+ TypeClassifier,
1526
+ convertOtlpAttributes,
1527
+ createSignature,
1528
+ detectVersion,
1529
+ extractCustomMetadata,
1530
+ extractReasoningFromProviderMetadata,
1531
+ extractResourceScopeSpan,
1532
+ fetchPromptsFrontmatter,
1533
+ findPromptFiles,
1534
+ generateTypeDefinitions,
1535
+ generateUnique8CharString,
1536
+ normalizeOtlpSpans,
1537
+ normalizeSpan,
1538
+ parseAgentMarkAttributes,
1539
+ parseMetadata,
1540
+ parseTokens,
1541
+ registry,
1542
+ toFrontMatter,
1543
+ typeClassifier,
1544
+ verifySignature
1545
+ });
1546
+ //# sourceMappingURL=index.js.map