@agentmark-ai/shared-utils 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -251,9 +251,11 @@ interface NormalizedSpan {
251
251
  datasetItemName?: string;
252
252
  datasetExpectedOutput?: string;
253
253
  datasetInput?: string;
254
+ experimentKey?: string;
254
255
  promptName?: string;
255
256
  props?: string;
256
257
  commitSha?: string;
258
+ sourceTreeHash?: string;
257
259
  metadata?: Record<string, string>;
258
260
  resourceAttributes: Record<string, any>;
259
261
  spanAttributes: Record<string, any>;
@@ -448,7 +450,7 @@ declare function parseAgentMarkAttributes(attributes: Record<string, any>, prefi
448
450
  declare const SEMANTIC_KINDS: readonly ["function", "llm", "tool", "agent", "retrieval", "embedding", "guardrail"];
449
451
  type SemanticKind = typeof SEMANTIC_KINDS[number];
450
452
  /**
451
- * Resolve the semantic kind of a span using an 8-level priority chain.
453
+ * Resolve the semantic kind of a span using a 9-level priority chain.
452
454
  *
453
455
  * Priority:
454
456
  * 1. normalized.semanticKind (from agentmark.span.kind attribute) — if valid
@@ -456,9 +458,11 @@ type SemanticKind = typeof SEMANTIC_KINDS[number];
456
458
  * 3. Framework-specific attributes (Vercel AI SDK, Traceloop, LangChain, Genkit)
457
459
  * 4. gen_ai.operation.name → llm/embedding
458
460
  * 5. Type = GENERATION → llm
459
- * 6. Has non-empty ToolCallstool
460
- * 7. Name-based heuristics
461
- * 8. Defaultfunction
461
+ * 6. Carries a model (gen_ai.request.model) llm — vendor-neutral generation
462
+ * signal; catches model calls the framework maps above don't name.
463
+ * 7. Has non-empty ToolCalls tool
464
+ * 8. Name-based heuristics
465
+ * 9. Default → function
462
466
  */
463
467
  declare function resolveSemanticKind(normalized: Partial<NormalizedSpan> & {
464
468
  type: SpanType;
@@ -558,43 +562,4 @@ declare function normalizeSpan(resource: OtelResource, scope: OtelScope, span: O
558
562
  */
559
563
  declare function normalizeOtlpSpans(resourceSpans: OtlpResourceSpans[]): NormalizedSpan[];
560
564
 
561
- /**
562
- * Compute a stable identifier for a dataset row, derived from its input.
563
- *
564
- * The identifier survives row reordering, additions, and deletions in the
565
- * dataset — anything that doesn't change the row's *content* keeps the same
566
- * id. This is the property regression-vs-baseline comparisons need: the
567
- * same logical test case in two different runs must produce the same name
568
- * so the baseline lookup can match them.
569
- *
570
- * Format: first 12 hex characters of the MD5 digest of the row's input,
571
- * canonicalised with sorted keys at every level. This matches the Python
572
- * runner's implementation byte-for-byte so cross-runtime comparisons
573
- * (TS-emitted baseline vs. Python-emitted PR run, or vice versa) produce
574
- * matching identifiers.
575
- *
576
- * Falls back to the positional index as a string when the row has no
577
- * input — in that case there is nothing stable to hash, so positional is
578
- * the best we can do.
579
- *
580
- * Note: we use MD5 here for compatibility with the existing Python
581
- * implementation. MD5 is not used as a security primitive — it's used as a
582
- * non-cryptographic content fingerprint, which is its appropriate role.
583
- */
584
- declare function computeDatasetItemName(input: unknown, fallbackIndex: number): string;
585
- /**
586
- * Stringify a value as canonical JSON with object keys sorted recursively.
587
- *
588
- * Differs from `JSON.stringify`:
589
- * - Object keys are sorted lexicographically at every level of nesting, so
590
- * `{a: 1, b: 2}` and `{b: 2, a: 1}` produce the same output.
591
- * - Non-serializable values (functions, symbols, bigints, undefined) are
592
- * coerced to strings via `String(value)`, matching Python's `default=str`
593
- * behavior in `json.dumps`.
594
- *
595
- * Exported for testing and for callers that need the same canonicalisation
596
- * for purposes other than item-name hashing.
597
- */
598
- declare function canonicalJsonStringify(value: unknown): string;
599
-
600
- export { AGENTMARK_SCOPE_NAME, AgentMarkTransformer, type AgentmarkConfig, type AgentmarkModelConfig, type AgentmarkModelSchema, type AgentmarkModelSettingsConfig, type AgentmarkModelSettingsSchema, AiSdkTransformer, type AiSdkVersion, type AttributeExtractor, AgentMarkTransformer as ClaudeAgentTransformer, type GenerateTypesLanguage, MastraTransformer, type McpServerConfig, type McpServers, type McpStdioServerConfig, type McpUrlServerConfig, type Message, type ModelSettingsTypeAspectRatio, type ModelSettingsTypeImageSize, type ModelSettingsTypeSelect, type ModelSettingsTypeSlider, type NormalizedSpan, type OtelEvent, OtelGenAiTransformer, type OtelLink, type OtelResource, type OtelScope, type OtelSpan, type OtlpAttribute, type OtlpAttributeValue, type OtlpEvent, type OtlpLink, type OtlpResource, type OtlpResourceSpans, type OtlpScope, type OtlpScopeSpans, type OtlpSpan, SEMANTIC_KINDS, type ScopeTransformer, type SemanticKind, SpanType, type StandardMessageContent, type StandardTextContent, type StandardToolCallContent, type StandardToolResultContent, type ToolCall, TransformerRegistry, TypeClassifier, canonicalJsonStringify, computeDatasetItemName, convertOtlpAttributes, createSignature, detectVersion, extractCustomMetadata, extractReasoningFromProviderMetadata, extractResourceScopeSpan, fetchPromptsFrontmatter, findPromptFiles, generateTypeDefinitions, generateUnique8CharString, normalizeOtlpSpans, normalizeSpan, parseAgentMarkAttributes, parseMetadata, parseTokens, registry, resolveSemanticKind, toFrontMatter, typeClassifier, verifySignature };
565
+ export { AGENTMARK_SCOPE_NAME, AgentMarkTransformer, type AgentmarkConfig, type AgentmarkModelConfig, type AgentmarkModelSchema, type AgentmarkModelSettingsConfig, type AgentmarkModelSettingsSchema, AiSdkTransformer, type AiSdkVersion, type AttributeExtractor, AgentMarkTransformer as ClaudeAgentTransformer, type GenerateTypesLanguage, MastraTransformer, type McpServerConfig, type McpServers, type McpStdioServerConfig, type McpUrlServerConfig, type Message, type ModelSettingsTypeAspectRatio, type ModelSettingsTypeImageSize, type ModelSettingsTypeSelect, type ModelSettingsTypeSlider, type NormalizedSpan, type OtelEvent, OtelGenAiTransformer, type OtelLink, type OtelResource, type OtelScope, type OtelSpan, type OtlpAttribute, type OtlpAttributeValue, type OtlpEvent, type OtlpLink, type OtlpResource, type OtlpResourceSpans, type OtlpScope, type OtlpScopeSpans, type OtlpSpan, SEMANTIC_KINDS, type ScopeTransformer, type SemanticKind, SpanType, type StandardMessageContent, type StandardTextContent, type StandardToolCallContent, type StandardToolResultContent, type ToolCall, TransformerRegistry, TypeClassifier, convertOtlpAttributes, createSignature, detectVersion, extractCustomMetadata, extractReasoningFromProviderMetadata, extractResourceScopeSpan, fetchPromptsFrontmatter, findPromptFiles, generateTypeDefinitions, generateUnique8CharString, normalizeOtlpSpans, normalizeSpan, parseAgentMarkAttributes, parseMetadata, parseTokens, registry, resolveSemanticKind, toFrontMatter, typeClassifier, verifySignature };
package/dist/index.d.ts CHANGED
@@ -251,9 +251,11 @@ interface NormalizedSpan {
251
251
  datasetItemName?: string;
252
252
  datasetExpectedOutput?: string;
253
253
  datasetInput?: string;
254
+ experimentKey?: string;
254
255
  promptName?: string;
255
256
  props?: string;
256
257
  commitSha?: string;
258
+ sourceTreeHash?: string;
257
259
  metadata?: Record<string, string>;
258
260
  resourceAttributes: Record<string, any>;
259
261
  spanAttributes: Record<string, any>;
@@ -448,7 +450,7 @@ declare function parseAgentMarkAttributes(attributes: Record<string, any>, prefi
448
450
  declare const SEMANTIC_KINDS: readonly ["function", "llm", "tool", "agent", "retrieval", "embedding", "guardrail"];
449
451
  type SemanticKind = typeof SEMANTIC_KINDS[number];
450
452
  /**
451
- * Resolve the semantic kind of a span using an 8-level priority chain.
453
+ * Resolve the semantic kind of a span using a 9-level priority chain.
452
454
  *
453
455
  * Priority:
454
456
  * 1. normalized.semanticKind (from agentmark.span.kind attribute) — if valid
@@ -456,9 +458,11 @@ type SemanticKind = typeof SEMANTIC_KINDS[number];
456
458
  * 3. Framework-specific attributes (Vercel AI SDK, Traceloop, LangChain, Genkit)
457
459
  * 4. gen_ai.operation.name → llm/embedding
458
460
  * 5. Type = GENERATION → llm
459
- * 6. Has non-empty ToolCallstool
460
- * 7. Name-based heuristics
461
- * 8. Defaultfunction
461
+ * 6. Carries a model (gen_ai.request.model) llm — vendor-neutral generation
462
+ * signal; catches model calls the framework maps above don't name.
463
+ * 7. Has non-empty ToolCalls tool
464
+ * 8. Name-based heuristics
465
+ * 9. Default → function
462
466
  */
463
467
  declare function resolveSemanticKind(normalized: Partial<NormalizedSpan> & {
464
468
  type: SpanType;
@@ -558,43 +562,4 @@ declare function normalizeSpan(resource: OtelResource, scope: OtelScope, span: O
558
562
  */
559
563
  declare function normalizeOtlpSpans(resourceSpans: OtlpResourceSpans[]): NormalizedSpan[];
560
564
 
561
- /**
562
- * Compute a stable identifier for a dataset row, derived from its input.
563
- *
564
- * The identifier survives row reordering, additions, and deletions in the
565
- * dataset — anything that doesn't change the row's *content* keeps the same
566
- * id. This is the property regression-vs-baseline comparisons need: the
567
- * same logical test case in two different runs must produce the same name
568
- * so the baseline lookup can match them.
569
- *
570
- * Format: first 12 hex characters of the MD5 digest of the row's input,
571
- * canonicalised with sorted keys at every level. This matches the Python
572
- * runner's implementation byte-for-byte so cross-runtime comparisons
573
- * (TS-emitted baseline vs. Python-emitted PR run, or vice versa) produce
574
- * matching identifiers.
575
- *
576
- * Falls back to the positional index as a string when the row has no
577
- * input — in that case there is nothing stable to hash, so positional is
578
- * the best we can do.
579
- *
580
- * Note: we use MD5 here for compatibility with the existing Python
581
- * implementation. MD5 is not used as a security primitive — it's used as a
582
- * non-cryptographic content fingerprint, which is its appropriate role.
583
- */
584
- declare function computeDatasetItemName(input: unknown, fallbackIndex: number): string;
585
- /**
586
- * Stringify a value as canonical JSON with object keys sorted recursively.
587
- *
588
- * Differs from `JSON.stringify`:
589
- * - Object keys are sorted lexicographically at every level of nesting, so
590
- * `{a: 1, b: 2}` and `{b: 2, a: 1}` produce the same output.
591
- * - Non-serializable values (functions, symbols, bigints, undefined) are
592
- * coerced to strings via `String(value)`, matching Python's `default=str`
593
- * behavior in `json.dumps`.
594
- *
595
- * Exported for testing and for callers that need the same canonicalisation
596
- * for purposes other than item-name hashing.
597
- */
598
- declare function canonicalJsonStringify(value: unknown): string;
599
-
600
- export { AGENTMARK_SCOPE_NAME, AgentMarkTransformer, type AgentmarkConfig, type AgentmarkModelConfig, type AgentmarkModelSchema, type AgentmarkModelSettingsConfig, type AgentmarkModelSettingsSchema, AiSdkTransformer, type AiSdkVersion, type AttributeExtractor, AgentMarkTransformer as ClaudeAgentTransformer, type GenerateTypesLanguage, MastraTransformer, type McpServerConfig, type McpServers, type McpStdioServerConfig, type McpUrlServerConfig, type Message, type ModelSettingsTypeAspectRatio, type ModelSettingsTypeImageSize, type ModelSettingsTypeSelect, type ModelSettingsTypeSlider, type NormalizedSpan, type OtelEvent, OtelGenAiTransformer, type OtelLink, type OtelResource, type OtelScope, type OtelSpan, type OtlpAttribute, type OtlpAttributeValue, type OtlpEvent, type OtlpLink, type OtlpResource, type OtlpResourceSpans, type OtlpScope, type OtlpScopeSpans, type OtlpSpan, SEMANTIC_KINDS, type ScopeTransformer, type SemanticKind, SpanType, type StandardMessageContent, type StandardTextContent, type StandardToolCallContent, type StandardToolResultContent, type ToolCall, TransformerRegistry, TypeClassifier, canonicalJsonStringify, computeDatasetItemName, convertOtlpAttributes, createSignature, detectVersion, extractCustomMetadata, extractReasoningFromProviderMetadata, extractResourceScopeSpan, fetchPromptsFrontmatter, findPromptFiles, generateTypeDefinitions, generateUnique8CharString, normalizeOtlpSpans, normalizeSpan, parseAgentMarkAttributes, parseMetadata, parseTokens, registry, resolveSemanticKind, toFrontMatter, typeClassifier, verifySignature };
565
+ export { AGENTMARK_SCOPE_NAME, AgentMarkTransformer, type AgentmarkConfig, type AgentmarkModelConfig, type AgentmarkModelSchema, type AgentmarkModelSettingsConfig, type AgentmarkModelSettingsSchema, AiSdkTransformer, type AiSdkVersion, type AttributeExtractor, AgentMarkTransformer as ClaudeAgentTransformer, type GenerateTypesLanguage, MastraTransformer, type McpServerConfig, type McpServers, type McpStdioServerConfig, type McpUrlServerConfig, type Message, type ModelSettingsTypeAspectRatio, type ModelSettingsTypeImageSize, type ModelSettingsTypeSelect, type ModelSettingsTypeSlider, type NormalizedSpan, type OtelEvent, OtelGenAiTransformer, type OtelLink, type OtelResource, type OtelScope, type OtelSpan, type OtlpAttribute, type OtlpAttributeValue, type OtlpEvent, type OtlpLink, type OtlpResource, type OtlpResourceSpans, type OtlpScope, type OtlpScopeSpans, type OtlpSpan, SEMANTIC_KINDS, type ScopeTransformer, type SemanticKind, SpanType, type StandardMessageContent, type StandardTextContent, type StandardToolCallContent, type StandardToolResultContent, type ToolCall, TransformerRegistry, TypeClassifier, convertOtlpAttributes, createSignature, detectVersion, extractCustomMetadata, extractReasoningFromProviderMetadata, extractResourceScopeSpan, fetchPromptsFrontmatter, findPromptFiles, generateTypeDefinitions, generateUnique8CharString, normalizeOtlpSpans, normalizeSpan, parseAgentMarkAttributes, parseMetadata, parseTokens, registry, resolveSemanticKind, toFrontMatter, typeClassifier, verifySignature };
package/dist/index.js CHANGED
@@ -40,8 +40,6 @@ __export(index_exports, {
40
40
  SpanType: () => SpanType,
41
41
  TransformerRegistry: () => TransformerRegistry,
42
42
  TypeClassifier: () => TypeClassifier,
43
- canonicalJsonStringify: () => canonicalJsonStringify,
44
- computeDatasetItemName: () => computeDatasetItemName,
45
43
  convertOtlpAttributes: () => convertOtlpAttributes,
46
44
  createSignature: () => createSignature,
47
45
  detectVersion: () => detectVersion,
@@ -988,39 +986,50 @@ var AiSdkV4Strategy = class {
988
986
  return attributes["gen_ai.request.model"] || attributes["ai.model.id"];
989
987
  }
990
988
  extractInput(attributes) {
991
- let messagesValue;
992
- if (attributes["ai.prompt.messages"] !== void 0) {
993
- messagesValue = attributes["ai.prompt.messages"];
994
- } else if (attributes["ai.prompt"] !== void 0) {
995
- const promptValue = attributes["ai.prompt"];
996
- if (typeof promptValue === "string") {
997
- try {
998
- const parsed = JSON.parse(promptValue);
999
- messagesValue = parsed.messages || parsed;
1000
- } catch {
1001
- return void 0;
1002
- }
1003
- } else {
1004
- messagesValue = promptValue.messages || promptValue;
1005
- }
1006
- } else {
989
+ const raw = attributes["ai.prompt.messages"] !== void 0 ? attributes["ai.prompt.messages"] : attributes["ai.prompt"];
990
+ if (raw === void 0) {
1007
991
  return void 0;
1008
992
  }
1009
- let messages;
1010
- if (typeof messagesValue === "string") {
993
+ let value = raw;
994
+ if (typeof value === "string") {
1011
995
  try {
1012
- messages = JSON.parse(messagesValue);
996
+ value = JSON.parse(value);
1013
997
  } catch {
1014
- return void 0;
1015
998
  }
1016
- } else {
1017
- messages = messagesValue;
1018
999
  }
1019
- if (!Array.isArray(messages)) {
1000
+ const messages = this.coerceToMessages(value);
1001
+ if (!messages) {
1020
1002
  return void 0;
1021
1003
  }
1022
1004
  return this.normalizeMessages(messages);
1023
1005
  }
1006
+ /**
1007
+ * Coerce the shapes `ai.prompt` / `ai.prompt.messages` can take into a
1008
+ * messages array: a raw array, `{ messages, system? }`,
1009
+ * `{ prompt, system? }` (string prompt), or a bare string.
1010
+ */
1011
+ coerceToMessages(value) {
1012
+ if (typeof value === "string") {
1013
+ return [{ role: "user", content: value }];
1014
+ }
1015
+ if (Array.isArray(value)) {
1016
+ return value;
1017
+ }
1018
+ if (value && typeof value === "object") {
1019
+ if (Array.isArray(value.messages)) {
1020
+ return typeof value.system === "string" ? [{ role: "system", content: value.system }, ...value.messages] : value.messages;
1021
+ }
1022
+ if (typeof value.prompt === "string") {
1023
+ const messages = [];
1024
+ if (typeof value.system === "string") {
1025
+ messages.push({ role: "system", content: value.system });
1026
+ }
1027
+ messages.push({ role: "user", content: value.prompt });
1028
+ return messages;
1029
+ }
1030
+ }
1031
+ return void 0;
1032
+ }
1024
1033
  extractOutput(attributes) {
1025
1034
  if (attributes["ai.result.text"] !== void 0) return attributes["ai.result.text"];
1026
1035
  if (attributes["ai.response.text"] !== void 0) return attributes["ai.response.text"];
@@ -1284,39 +1293,54 @@ var AiSdkV5Strategy = class {
1284
1293
  return attributes["gen_ai.request.model"] || attributes["ai.model.id"];
1285
1294
  }
1286
1295
  extractInput(attributes) {
1287
- let messagesValue;
1288
- if (attributes["ai.prompt.messages"] !== void 0) {
1289
- messagesValue = attributes["ai.prompt.messages"];
1290
- } else if (attributes["ai.prompt"] !== void 0) {
1291
- const promptValue = attributes["ai.prompt"];
1292
- if (typeof promptValue === "string") {
1293
- try {
1294
- const parsed = JSON.parse(promptValue);
1295
- messagesValue = parsed.messages || parsed;
1296
- } catch {
1297
- return void 0;
1298
- }
1299
- } else {
1300
- messagesValue = promptValue.messages || promptValue;
1301
- }
1302
- } else {
1296
+ const raw = attributes["ai.prompt.messages"] !== void 0 ? attributes["ai.prompt.messages"] : attributes["ai.prompt"];
1297
+ if (raw === void 0) {
1303
1298
  return void 0;
1304
1299
  }
1305
- let messages;
1306
- if (typeof messagesValue === "string") {
1300
+ let value = raw;
1301
+ if (typeof value === "string") {
1307
1302
  try {
1308
- messages = JSON.parse(messagesValue);
1303
+ value = JSON.parse(value);
1309
1304
  } catch {
1310
- return void 0;
1311
1305
  }
1312
- } else {
1313
- messages = messagesValue;
1314
1306
  }
1315
- if (!Array.isArray(messages)) {
1307
+ const messages = this.coerceToMessages(value);
1308
+ if (!messages) {
1316
1309
  return void 0;
1317
1310
  }
1318
1311
  return this.normalizeMessages(messages);
1319
1312
  }
1313
+ /**
1314
+ * Coerce the shapes `ai.prompt` / `ai.prompt.messages` can take into a
1315
+ * messages array:
1316
+ * - `[ ...messages ]` — ai.prompt.messages (leaf spans)
1317
+ * - `{ messages: [...], system? }` — ai.prompt with messages
1318
+ * - `{ prompt: "text", system? }` — ai.prompt for a string prompt
1319
+ * (the parent wrapper spans)
1320
+ * - `"text"` — a bare (non-JSON) prompt string
1321
+ */
1322
+ coerceToMessages(value) {
1323
+ if (typeof value === "string") {
1324
+ return [{ role: "user", content: value }];
1325
+ }
1326
+ if (Array.isArray(value)) {
1327
+ return value;
1328
+ }
1329
+ if (value && typeof value === "object") {
1330
+ if (Array.isArray(value.messages)) {
1331
+ return typeof value.system === "string" ? [{ role: "system", content: value.system }, ...value.messages] : value.messages;
1332
+ }
1333
+ if (typeof value.prompt === "string") {
1334
+ const messages = [];
1335
+ if (typeof value.system === "string") {
1336
+ messages.push({ role: "system", content: value.system });
1337
+ }
1338
+ messages.push({ role: "user", content: value.prompt });
1339
+ return messages;
1340
+ }
1341
+ }
1342
+ return void 0;
1343
+ }
1320
1344
  extractOutput(attributes) {
1321
1345
  if (attributes["ai.response.text"] !== void 0) return attributes["ai.response.text"];
1322
1346
  return void 0;
@@ -1657,6 +1681,8 @@ function parseAgentMarkAttributes(attributes, prefix = "agentmark.") {
1657
1681
  if (get("dataset_expected_output")) result.datasetExpectedOutput = String(get("dataset_expected_output"));
1658
1682
  if (get("dataset_input")) result.datasetInput = String(get("dataset_input"));
1659
1683
  if (get("dataset_path")) result.datasetPath = String(get("dataset_path"));
1684
+ if (get("experiment_key")) result.experimentKey = String(get("experiment_key"));
1685
+ if (get("source_tree_hash")) result.sourceTreeHash = String(get("source_tree_hash"));
1660
1686
  return result;
1661
1687
  }
1662
1688
 
@@ -2171,13 +2197,20 @@ var FRAMEWORK_MAPPINGS = [
2171
2197
  {
2172
2198
  key: "ai.operationId",
2173
2199
  // Vercel AI SDK
2200
+ // The AI SDK emits ai.operationId WITH the "ai." prefix (e.g.
2201
+ // "ai.generateText"); accept both prefixed and unprefixed so generation
2202
+ // wrappers resolve to "llm" instead of falling through to "function".
2174
2203
  map: {
2175
2204
  "embed": "embedding",
2176
2205
  "ai.embed": "embedding",
2177
2206
  "generateText": "llm",
2207
+ "ai.generateText": "llm",
2178
2208
  "streamText": "llm",
2209
+ "ai.streamText": "llm",
2179
2210
  "generateObject": "llm",
2180
- "streamObject": "llm"
2211
+ "ai.generateObject": "llm",
2212
+ "streamObject": "llm",
2213
+ "ai.streamObject": "llm"
2181
2214
  }
2182
2215
  },
2183
2216
  {
@@ -2221,6 +2254,9 @@ function resolveSemanticKind(normalized, allAttributes) {
2221
2254
  if (normalized.type === "GENERATION" /* GENERATION */) {
2222
2255
  return "llm";
2223
2256
  }
2257
+ if (normalized.model) {
2258
+ return "llm";
2259
+ }
2224
2260
  if (normalized.toolCalls && normalized.toolCalls.length > 0) {
2225
2261
  return "tool";
2226
2262
  }
@@ -2322,36 +2358,6 @@ function normalizeOtlpSpans(resourceSpans) {
2322
2358
  }
2323
2359
  return normalizedSpans;
2324
2360
  }
2325
-
2326
- // src/dataset-item-name.ts
2327
- var import_node_crypto = require("crypto");
2328
- function computeDatasetItemName(input, fallbackIndex) {
2329
- if (input === void 0 || input === null) {
2330
- return String(fallbackIndex);
2331
- }
2332
- const canonical = canonicalJsonStringify(input);
2333
- return (0, import_node_crypto.createHash)("md5").update(canonical).digest("hex").slice(0, 12);
2334
- }
2335
- function canonicalJsonStringify(value) {
2336
- if (value === null) return "null";
2337
- if (value === void 0) return JSON.stringify(String(void 0));
2338
- const t = typeof value;
2339
- if (t === "string" || t === "number" || t === "boolean") {
2340
- return JSON.stringify(value);
2341
- }
2342
- if (t === "bigint" || t === "function" || t === "symbol") {
2343
- return JSON.stringify(String(value));
2344
- }
2345
- if (Array.isArray(value)) {
2346
- return "[" + value.map(canonicalJsonStringify).join(",") + "]";
2347
- }
2348
- const obj = value;
2349
- const keys = Object.keys(obj).sort();
2350
- const parts = keys.map((k) => {
2351
- return JSON.stringify(k) + ":" + canonicalJsonStringify(obj[k]);
2352
- });
2353
- return "{" + parts.join(",") + "}";
2354
- }
2355
2361
  // Annotate the CommonJS export names for ESM import in node:
2356
2362
  0 && (module.exports = {
2357
2363
  AGENTMARK_SCOPE_NAME,
@@ -2364,8 +2370,6 @@ function canonicalJsonStringify(value) {
2364
2370
  SpanType,
2365
2371
  TransformerRegistry,
2366
2372
  TypeClassifier,
2367
- canonicalJsonStringify,
2368
- computeDatasetItemName,
2369
2373
  convertOtlpAttributes,
2370
2374
  createSignature,
2371
2375
  detectVersion,