@cognipeer/agent-sdk 0.17.0 → 0.19.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.cjs CHANGED
@@ -8,6 +8,8 @@ var path = require('path');
8
8
  var buffer = require('buffer');
9
9
  var nanoid = require('nanoid');
10
10
  var crypto = require('crypto');
11
+ var zlib = require('zlib');
12
+ var util = require('util');
11
13
  var AjvModule = require('ajv');
12
14
 
13
15
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
@@ -1231,9 +1233,1398 @@ function splitUsage(usage) {
1231
1233
  }
1232
1234
  return { own, subagent, ownCalls: ownEntries.length, subagentCalls: subagentEntries.length, ownEntries, subagentEntries };
1233
1235
  }
1236
+ function cacheWriteTokensOf(raw) {
1237
+ if (!raw || typeof raw !== "object") return void 0;
1238
+ const details = raw.prompt_tokens_details || raw.promptTokensDetails || raw.input_token_details || raw.inputTokenDetails || {};
1239
+ const candidates = [
1240
+ details.cache_write_tokens,
1241
+ details.cacheWriteTokens,
1242
+ details.cache_creation,
1243
+ raw.cache_write_tokens,
1244
+ raw.cacheWriteTokens,
1245
+ raw.cache_creation_input_tokens,
1246
+ raw.cacheCreationInputTokens,
1247
+ raw.cacheWriteInputTokens,
1248
+ raw.cacheWriteInputTokenCount
1249
+ ];
1250
+ for (const value of candidates) {
1251
+ const n = Number(value);
1252
+ if (Number.isFinite(n) && n > 0) return n;
1253
+ }
1254
+ return void 0;
1255
+ }
1234
1256
 
1235
1257
  // src/utils/tracing.ts
1236
1258
  init_content();
1259
+
1260
+ // src/version.ts
1261
+ var SDK_VERSION = "0.19.0";
1262
+
1263
+ // src/utils/otlp/content.ts
1264
+ init_content();
1265
+
1266
+ // src/utils/otlp/semconv.ts
1267
+ var GENAI_SEMCONV_COMMIT = "547934a";
1268
+ var ATTR = {
1269
+ operationName: "gen_ai.operation.name",
1270
+ providerName: "gen_ai.provider.name",
1271
+ requestModel: "gen_ai.request.model",
1272
+ responseModel: "gen_ai.response.model",
1273
+ responseId: "gen_ai.response.id",
1274
+ finishReasons: "gen_ai.response.finish_reasons",
1275
+ requestStream: "gen_ai.request.stream",
1276
+ outputType: "gen_ai.output.type",
1277
+ conversationId: "gen_ai.conversation.id",
1278
+ agentName: "gen_ai.agent.name",
1279
+ agentVersion: "gen_ai.agent.version",
1280
+ toolName: "gen_ai.tool.name",
1281
+ toolCallId: "gen_ai.tool.call.id",
1282
+ toolType: "gen_ai.tool.type",
1283
+ usageInput: "gen_ai.usage.input_tokens",
1284
+ usageOutput: "gen_ai.usage.output_tokens",
1285
+ usageCacheRead: "gen_ai.usage.cache_read.input_tokens",
1286
+ usageCacheWrite: "gen_ai.usage.cache_write.input_tokens",
1287
+ usageReasoning: "gen_ai.usage.reasoning.output_tokens",
1288
+ errorType: "error.type",
1289
+ // Content (opt-in).
1290
+ systemInstructions: "gen_ai.system_instructions",
1291
+ inputMessages: "gen_ai.input.messages",
1292
+ outputMessages: "gen_ai.output.messages",
1293
+ toolDefinitions: "gen_ai.tool.definitions",
1294
+ toolCallArguments: "gen_ai.tool.call.arguments",
1295
+ toolCallResult: "gen_ai.tool.call.result"
1296
+ };
1297
+ var OPERATION = {
1298
+ chat: "chat",
1299
+ executeTool: "execute_tool",
1300
+ invokeAgent: "invoke_agent"
1301
+ };
1302
+ var PROVIDERS = {
1303
+ openai: "openai",
1304
+ chatopenai: "openai",
1305
+ azure: "azure.ai.openai",
1306
+ azureopenai: "azure.ai.openai",
1307
+ azurechatopenai: "azure.ai.openai",
1308
+ azureaiopenai: "azure.ai.openai",
1309
+ azureaiinference: "azure.ai.inference",
1310
+ anthropic: "anthropic",
1311
+ chatanthropic: "anthropic",
1312
+ bedrock: "aws.bedrock",
1313
+ awsbedrock: "aws.bedrock",
1314
+ chatbedrock: "aws.bedrock",
1315
+ chatbedrockconverse: "aws.bedrock",
1316
+ vertex: "gcp.vertex_ai",
1317
+ vertexai: "gcp.vertex_ai",
1318
+ gcpvertexai: "gcp.vertex_ai",
1319
+ chatvertexai: "gcp.vertex_ai",
1320
+ gemini: "gcp.gemini",
1321
+ gcpgemini: "gcp.gemini",
1322
+ chatgooglegenerativeai: "gcp.gemini",
1323
+ // Gemini API or Vertex: the name alone does not say which.
1324
+ google: "gcp.gen_ai",
1325
+ gcpgenai: "gcp.gen_ai",
1326
+ mistral: "mistral",
1327
+ mistralai: "mistral",
1328
+ chatmistralai: "mistral",
1329
+ groq: "groq",
1330
+ chatgroq: "groq",
1331
+ deepseek: "deepseek",
1332
+ chatdeepseek: "deepseek",
1333
+ cohere: "cohere",
1334
+ chatcohere: "cohere",
1335
+ xai: "x_ai",
1336
+ chatxai: "x_ai",
1337
+ perplexity: "perplexity",
1338
+ chatperplexity: "perplexity",
1339
+ watsonx: "ibm.watsonx.ai",
1340
+ ibmwatsonxai: "ibm.watsonx.ai"
1341
+ };
1342
+ function genAiProviderName(hint) {
1343
+ if (!hint) return void 0;
1344
+ const key = hint.toLowerCase().replace(/[^a-z0-9]/g, "");
1345
+ return key ? PROVIDERS[key] : void 0;
1346
+ }
1347
+ function errorTypeOf(error) {
1348
+ if (!error) return "_OTHER";
1349
+ if (typeof error.type === "string" && error.type.length > 0) return error.type;
1350
+ if (typeof error.stack === "string") {
1351
+ const match = /^\s*([A-Za-z_$][\w$.]*)\s*(?::|$)/m.exec(error.stack.split("\n", 1)[0] ?? "");
1352
+ if (match) return match[1];
1353
+ }
1354
+ return "_OTHER";
1355
+ }
1356
+ function genAiUsageOf(event) {
1357
+ const num2 = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
1358
+ const input = num2(event.inputTokens);
1359
+ const output = num2(event.outputTokens);
1360
+ const cacheRead = num2(event.cachedInputTokens);
1361
+ const cacheWrite = num2(event.cacheWriteTokens);
1362
+ const reasoning = num2(event.reasoningTokens);
1363
+ if (input + output + cacheRead + cacheWrite + reasoning + num2(event.totalTokens) === 0) return void 0;
1364
+ const basis = event.usageBasis ?? {};
1365
+ return {
1366
+ input: basis.inputExcludesCache ? input + cacheRead + cacheWrite : input,
1367
+ output: basis.outputExcludesReasoning ? output + reasoning : output,
1368
+ ...cacheRead > 0 ? { cacheRead } : {},
1369
+ ...cacheWrite > 0 ? { cacheWrite } : {},
1370
+ ...reasoning > 0 ? { reasoning } : {}
1371
+ };
1372
+ }
1373
+
1374
+ // src/utils/otlp/content.ts
1375
+ var CAPTURE = Symbol.for("cognipeer.agent-sdk.traceCapture");
1376
+ var DEFAULTS = {
1377
+ maxStringChars: 4096,
1378
+ maxMessages: 32,
1379
+ maxAttributeBytes: 32768
1380
+ };
1381
+ var FIELDS = ["system", "input", "output", "tools", "toolArgs", "toolResults", "sections"];
1382
+ function resolveContentOptions(content) {
1383
+ const given = typeof content === "object" && content !== null ? content : {};
1384
+ const enabled = typeof content === "boolean" ? content : given.enabled === true;
1385
+ const positive = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : fallback;
1386
+ return {
1387
+ enabled,
1388
+ include: Array.isArray(given.include) ? given.include.filter((field) => FIELDS.includes(field)) : [...FIELDS],
1389
+ maxStringChars: positive(given.maxStringChars, DEFAULTS.maxStringChars),
1390
+ maxMessages: positive(given.maxMessages, DEFAULTS.maxMessages),
1391
+ maxAttributeBytes: positive(given.maxAttributeBytes, DEFAULTS.maxAttributeBytes),
1392
+ redact: typeof given.redact === "function" ? given.redact : void 0,
1393
+ encoding: given.encoding === "structured" ? "structured" : "json"
1394
+ };
1395
+ }
1396
+ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1397
+ function plain(value) {
1398
+ if (value === void 0) return void 0;
1399
+ try {
1400
+ const text = JSON.stringify(value);
1401
+ return text === void 0 ? void 0 : JSON.parse(text);
1402
+ } catch {
1403
+ return void 0;
1404
+ }
1405
+ }
1406
+ var TRUNCATED_MARKER = /\.\.\.\[truncated (\d+) chars\]$/;
1407
+ function truncateText(text, max) {
1408
+ const earlier = TRUNCATED_MARKER.exec(text);
1409
+ const body = earlier ? text.slice(0, earlier.index) : text;
1410
+ if (body.length <= max) return text;
1411
+ const lost = body.length - max + (earlier ? Number(earlier[1]) : 0);
1412
+ return `${body.slice(0, max)}...[truncated ${lost} chars]`;
1413
+ }
1414
+ function capStrings(value, max) {
1415
+ if (typeof value === "string") return truncateText(value, max);
1416
+ if (Array.isArray(value)) return value.map((item) => capStrings(item, max));
1417
+ if (isRecord2(value)) {
1418
+ const out = {};
1419
+ for (const [key, item] of Object.entries(value)) out[key] = capStrings(item, max);
1420
+ return out;
1421
+ }
1422
+ return value;
1423
+ }
1424
+ function asObject(value) {
1425
+ let parsed = value;
1426
+ if (typeof value === "string") {
1427
+ try {
1428
+ parsed = JSON.parse(value);
1429
+ } catch {
1430
+ parsed = value;
1431
+ }
1432
+ }
1433
+ const copy = plain(parsed);
1434
+ if (copy === void 0) return void 0;
1435
+ return isRecord2(copy) ? copy : { value: copy };
1436
+ }
1437
+ var REASONING_PART_TYPES = /* @__PURE__ */ new Set(["thinking", "redacted_thinking", "reasoning", "reasoning_content"]);
1438
+ function textOf(content) {
1439
+ if (content == null) return "";
1440
+ if (typeof content === "string") return content;
1441
+ if (!Array.isArray(content)) return contentPartToText(content, () => "");
1442
+ return content.filter((part) => !(isRecord2(part) && REASONING_PART_TYPES.has(String(part.type)))).map((part) => contentPartToText(part, () => "")).filter((text) => text.length > 0).join("\n");
1443
+ }
1444
+ function toolCallPartsOf(message) {
1445
+ const calls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
1446
+ const parts = [];
1447
+ for (const call of calls) {
1448
+ if (!isRecord2(call)) continue;
1449
+ const name = call.name ?? call.function?.name;
1450
+ if (typeof name !== "string" || !name) continue;
1451
+ const args = call.args ?? call.arguments ?? call.function?.arguments;
1452
+ const coerced = asObject(args ?? {});
1453
+ const id = typeof call.id === "string" && call.id && !call.idSynthesized ? call.id : void 0;
1454
+ parts.push({ type: "tool_call", ...id ? { id } : {}, name, arguments: coerced ?? {} });
1455
+ }
1456
+ return parts;
1457
+ }
1458
+ function messageOf(raw) {
1459
+ if (!isRecord2(raw)) return void 0;
1460
+ const role = typeof raw.role === "string" ? raw.role : "user";
1461
+ const parts = [];
1462
+ if (role === "tool") {
1463
+ const text2 = textOf(raw.content);
1464
+ const parsed = (() => {
1465
+ try {
1466
+ return JSON.parse(text2);
1467
+ } catch {
1468
+ return text2;
1469
+ }
1470
+ })();
1471
+ parts.push({
1472
+ type: "tool_call_response",
1473
+ ...typeof raw.tool_call_id === "string" && raw.tool_call_id ? { id: raw.tool_call_id } : {},
1474
+ response: plain(parsed) ?? text2
1475
+ });
1476
+ return { role, parts, ...typeof raw.name === "string" && raw.name ? { name: raw.name } : {} };
1477
+ }
1478
+ const text = textOf(raw.content);
1479
+ if (text) parts.push({ type: "text", content: text });
1480
+ if (role === "assistant") parts.push(...toolCallPartsOf(raw));
1481
+ if (parts.length === 0 && role !== "assistant") parts.push({ type: "text", content: "" });
1482
+ return { role, parts };
1483
+ }
1484
+ function buildCapturedContent(source, limits) {
1485
+ const out = {};
1486
+ if (Array.isArray(source.input)) {
1487
+ const system = [];
1488
+ const messages = [];
1489
+ for (const raw of source.input) {
1490
+ const message = messageOf(raw);
1491
+ if (!message) continue;
1492
+ if (message.role === "system") {
1493
+ const content = message.parts.map((part) => part.type === "text" ? part.content : "").join("\n");
1494
+ if (content) system.push({ type: "text", content });
1495
+ } else {
1496
+ messages.push(message);
1497
+ }
1498
+ }
1499
+ if (system.length > 0) out.system = capStrings(system, limits.maxStringChars);
1500
+ const recent = messages.slice(-limits.maxMessages);
1501
+ out.input = capStrings(recent, limits.maxStringChars);
1502
+ }
1503
+ if (source.output !== void 0 && source.output !== null) {
1504
+ const message = messageOf({ ...isRecord2(source.output) ? source.output : { content: String(source.output) }, role: "assistant" });
1505
+ if (message) out.output = capStrings(message, limits.maxStringChars);
1506
+ }
1507
+ if (Array.isArray(source.toolDefinitions) && source.toolDefinitions.length > 0) {
1508
+ out.tools = capStrings(
1509
+ source.toolDefinitions.filter((tool) => tool && typeof tool.name === "string").map((tool) => ({
1510
+ type: "function",
1511
+ name: tool.name,
1512
+ ...tool.description ? { description: tool.description } : {},
1513
+ ...tool.parameters !== void 0 ? { parameters: plain(tool.parameters) } : {}
1514
+ })),
1515
+ limits.maxStringChars
1516
+ );
1517
+ }
1518
+ if (source.toolArguments !== void 0) {
1519
+ const args = asObject(source.toolArguments);
1520
+ if (args !== void 0) out.toolArgs = capStrings(args, limits.maxStringChars);
1521
+ }
1522
+ if (source.hasToolResult || source.toolResult !== void 0) {
1523
+ const result = asObject(source.toolResult);
1524
+ if (result !== void 0) out.toolResults = capStrings(result, limits.maxStringChars);
1525
+ }
1526
+ return out;
1527
+ }
1528
+ function capturedContentOf(event) {
1529
+ return event?.[CAPTURE];
1530
+ }
1531
+ function attachCapturedContent(record, content) {
1532
+ Object.defineProperty(record, CAPTURE, { value: content, enumerable: false, configurable: true, writable: true });
1533
+ }
1534
+ var SEPARATE_SYSTEM = /* @__PURE__ */ new Set(["anthropic", "aws.bedrock", "gcp.vertex_ai", "gcp.gemini"]);
1535
+ function toAnyValue(value) {
1536
+ if (value === null || value === void 0) return void 0;
1537
+ if (typeof value === "string") return { stringValue: value };
1538
+ if (typeof value === "boolean") return { boolValue: value };
1539
+ if (typeof value === "number") {
1540
+ if (!Number.isFinite(value)) return void 0;
1541
+ return Number.isInteger(value) && Number.isSafeInteger(value) ? { intValue: String(value) } : { doubleValue: value };
1542
+ }
1543
+ if (Array.isArray(value)) {
1544
+ return { arrayValue: { values: value.map((item) => toAnyValue(item) ?? { stringValue: "" }) } };
1545
+ }
1546
+ if (isRecord2(value)) {
1547
+ const values = [];
1548
+ for (const [key, item] of Object.entries(value)) {
1549
+ const any = toAnyValue(item);
1550
+ if (any) values.push({ key, value: any });
1551
+ }
1552
+ return { kvlistValue: { values } };
1553
+ }
1554
+ return void 0;
1555
+ }
1556
+ var byteLength = (text) => buffer.Buffer.byteLength(text, "utf8");
1557
+ function render(value, field, options, info) {
1558
+ let working = plain(value);
1559
+ if (working === void 0) return void 0;
1560
+ if (options.redact) {
1561
+ try {
1562
+ working = options.redact(plain(working), { field, ...info });
1563
+ } catch {
1564
+ return void 0;
1565
+ }
1566
+ working = plain(working);
1567
+ if (working === void 0 || working === null) return void 0;
1568
+ }
1569
+ working = capStrings(working, options.maxStringChars);
1570
+ if ((field === "input" || field === "system" || field === "sections") && Array.isArray(working) && working.length > options.maxMessages) {
1571
+ working = working.slice(-options.maxMessages);
1572
+ }
1573
+ let text = JSON.stringify(working);
1574
+ if (text === void 0) return void 0;
1575
+ if (byteLength(text) > options.maxAttributeBytes) {
1576
+ if (field === "input" && Array.isArray(working)) {
1577
+ const messages = [...working];
1578
+ while (messages.length > 1 && byteLength(JSON.stringify(messages)) > options.maxAttributeBytes) messages.shift();
1579
+ working = messages;
1580
+ text = JSON.stringify(working);
1581
+ }
1582
+ if (byteLength(text) > options.maxAttributeBytes) {
1583
+ working = { truncated: true };
1584
+ text = JSON.stringify(working);
1585
+ }
1586
+ }
1587
+ return options.encoding === "structured" ? toAnyValue(working) : { stringValue: text };
1588
+ }
1589
+ function contentAttributes(kind, event, provider, options) {
1590
+ if (!options?.enabled) return [];
1591
+ const captured = capturedContentOf(event);
1592
+ if (!captured) return [];
1593
+ const include = new Set(options.include);
1594
+ const info = {
1595
+ eventType: event.type,
1596
+ ...event.spanId ? { spanId: event.spanId } : {},
1597
+ ...kind === "execute_tool" && event.actor?.name ? { toolName: event.actor.name } : {},
1598
+ ...event.model ? { model: event.model } : {}
1599
+ };
1600
+ const attrs = [];
1601
+ const add = (key, value) => {
1602
+ if (value) attrs.push({ key, value });
1603
+ };
1604
+ if (kind === "chat") {
1605
+ const separate = provider !== void 0 && SEPARATE_SYSTEM.has(provider);
1606
+ const system = captured.system ?? [];
1607
+ if (separate) {
1608
+ if (include.has("system") && system.length > 0) add(ATTR.systemInstructions, render(system, "system", options, info));
1609
+ if (include.has("input") && captured.input) add(ATTR.inputMessages, render(captured.input, "input", options, info));
1610
+ } else if (include.has("input") && (captured.input || system.length > 0)) {
1611
+ const messages = captured.input ?? [];
1612
+ const capped = messages.slice(-options.maxMessages);
1613
+ const withSystem = system.length > 0 ? [{ role: "system", parts: system }, ...capped] : capped;
1614
+ add(ATTR.inputMessages, render(withSystem, "input", { ...options, maxMessages: options.maxMessages + 1 }, info));
1615
+ }
1616
+ if (include.has("output") && captured.output) {
1617
+ const reason = event.rawFinishReason ?? event.finishReason;
1618
+ const finish = reason === "tool_calls" ? "tool_call" : reason;
1619
+ add(ATTR.outputMessages, render([{ ...captured.output, ...finish ? { finish_reason: finish } : {} }], "output", options, info));
1620
+ }
1621
+ if (include.has("tools") && captured.tools) add(ATTR.toolDefinitions, render(captured.tools, "tools", options, info));
1622
+ } else {
1623
+ if (include.has("toolArgs") && captured.toolArgs !== void 0) add(ATTR.toolCallArguments, render(captured.toolArgs, "toolArgs", options, info));
1624
+ if (include.has("toolResults") && captured.toolResults !== void 0) add(ATTR.toolCallResult, render(captured.toolResults, "toolResults", options, info));
1625
+ }
1626
+ return attrs;
1627
+ }
1628
+ function sectionsAttribute(sections, event, options) {
1629
+ if (!sections || sections.length === 0) return void 0;
1630
+ const identity2 = sections.filter((section) => section.identity === true);
1631
+ const payload = sections.filter((section) => section.identity !== true);
1632
+ let kept = [];
1633
+ if (options?.enabled && options.include.includes("sections") && payload.length > 0) {
1634
+ kept = redactedSections(payload, options, event);
1635
+ }
1636
+ const max = options?.maxAttributeBytes ?? DEFAULTS.maxAttributeBytes;
1637
+ const encode = (list) => {
1638
+ try {
1639
+ return JSON.stringify(list);
1640
+ } catch {
1641
+ return void 0;
1642
+ }
1643
+ };
1644
+ let text = encode([...identity2, ...kept]);
1645
+ while (text !== void 0 && kept.length > 0 && byteLength(text) > max) {
1646
+ kept.shift();
1647
+ text = encode([...identity2, ...kept]);
1648
+ }
1649
+ if (text === void 0) {
1650
+ text = encode(identity2);
1651
+ }
1652
+ if (text === void 0 || text === "[]") return void 0;
1653
+ return { key: "cognipeer.sections", value: { stringValue: text } };
1654
+ }
1655
+ function redactedSections(payload, options, event) {
1656
+ let working = plain(payload);
1657
+ if (working === void 0) return [];
1658
+ if (options.redact) {
1659
+ try {
1660
+ working = plain(options.redact(plain(working), {
1661
+ field: "sections",
1662
+ eventType: event.type,
1663
+ ...event.spanId ? { spanId: event.spanId } : {},
1664
+ ...event.model ? { model: event.model } : {}
1665
+ }));
1666
+ } catch {
1667
+ return [];
1668
+ }
1669
+ if (!Array.isArray(working)) return [];
1670
+ }
1671
+ const capped = capStrings(working, options.maxStringChars);
1672
+ return Array.isArray(capped) ? capped.slice(-options.maxMessages) : [];
1673
+ }
1674
+
1675
+ // src/utils/otlp/convert.ts
1676
+ var SCOPE_NAME = "cognipeer-agent-sdk";
1677
+ var SPAN_KIND_INTERNAL = 1;
1678
+ var SPAN_KIND_CLIENT = 3;
1679
+ var FLAG_HAS_PARENT = 256;
1680
+ var FLAG_REMOTE_PARENT = 512;
1681
+ var MAX_STATUS_MESSAGE = 1024;
1682
+ var str = (key, value) => value != null && value !== "" ? { key, value: { stringValue: value } } : null;
1683
+ var strAllowEmpty = (key, value) => value != null ? { key, value: { stringValue: value } } : null;
1684
+ var int = (key, value) => typeof value === "number" && Number.isFinite(value) ? { key, value: { intValue: String(Math.trunc(value)) } } : null;
1685
+ var dbl = (key, value) => typeof value === "number" && Number.isFinite(value) ? { key, value: { doubleValue: value } } : null;
1686
+ var bool = (key, value) => typeof value === "boolean" ? { key, value: { boolValue: value } } : null;
1687
+ var strArray = (key, values) => ({
1688
+ key,
1689
+ value: { arrayValue: { values: values.map((value) => ({ stringValue: value })) } }
1690
+ });
1691
+ var compact = (list) => list.filter((entry) => Boolean(entry));
1692
+ function msToNs(ms) {
1693
+ const whole = Math.floor(ms);
1694
+ return BigInt(whole) * 1000000n + BigInt(Math.round((ms - whole) * 1e6));
1695
+ }
1696
+ function parseMs(iso) {
1697
+ if (!iso) return void 0;
1698
+ const value = Date.parse(iso);
1699
+ return Number.isNaN(value) ? void 0 : value;
1700
+ }
1701
+ function durationNs(durationMs) {
1702
+ return typeof durationMs === "number" && Number.isFinite(durationMs) && durationMs > 0 ? msToNs(durationMs) : 0n;
1703
+ }
1704
+ function classify(event) {
1705
+ if (event.type === "ai_call" || event.type === "summarization") {
1706
+ if (event.skipReason === "cancelled") return "chat";
1707
+ if (event.skipReason || event.status === "skipped") return "plain";
1708
+ return "chat";
1709
+ }
1710
+ if (event.type === "tool_call") {
1711
+ const source = event.debug?.shortCircuitSource;
1712
+ if (event.skipReason || event.status === "skipped" || source === "cache" || source === "plugin") return "plain";
1713
+ if (event.status === "pending") return "plain";
1714
+ return "execute_tool";
1715
+ }
1716
+ if (event.type === "span" && event.actor?.role === "subagent") return "invoke_agent";
1717
+ return "plain";
1718
+ }
1719
+ var knownModel = (model) => model && model !== "unknown-model" && model !== "unknown_model" ? model : void 0;
1720
+ function toolNameOf(event) {
1721
+ if (event.actor?.name) return event.actor.name;
1722
+ const label = event.label.replace(/\s#\d+$/, "");
1723
+ const dash = label.indexOf(" - ");
1724
+ return dash >= 0 ? label.slice(dash + 3) : void 0;
1725
+ }
1726
+ var stripSequence = (label) => label.replace(/\s#\d+$/, "");
1727
+ function cappedMessage(message) {
1728
+ const text = message && message.length > 0 ? message : "Unknown error";
1729
+ return text.length > MAX_STATUS_MESSAGE ? text.slice(0, MAX_STATUS_MESSAGE) : text;
1730
+ }
1731
+ function exceptionEvent(timeNs, error) {
1732
+ return {
1733
+ timeUnixNano: timeNs.toString(),
1734
+ name: "exception",
1735
+ attributes: compact([
1736
+ str("exception.type", errorTypeOf(error)),
1737
+ strAllowEmpty("exception.message", error.message ?? "Unknown error"),
1738
+ str("exception.stacktrace", error.stack)
1739
+ ])
1740
+ };
1741
+ }
1742
+ function sessionToOtlp(file, options) {
1743
+ const useCognipeer = options.semconv !== "gen_ai";
1744
+ const useGenAi = options.semconv !== "cognipeer";
1745
+ const traceId = file.traceId || generateTraceId();
1746
+ const rootSpanId = file.rootSpanId || generateSpanId();
1747
+ const parent = options.parent;
1748
+ const traceState = parent?.traceState || void 0;
1749
+ const traceFlags = (typeof parent?.flags === "number" ? parent.flags : 1) & 255;
1750
+ const flags = traceFlags | FLAG_HAS_PARENT;
1751
+ const rootFlags = parent?.remote ? flags | FLAG_REMOTE_PARENT : flags;
1752
+ const agentName = file.agent?.name;
1753
+ const everyEvent = file.events;
1754
+ const exportedEvents = foldSupersededSpans(everyEvent).filter(
1755
+ (event) => options.terminal || !(event.type === "span" && (event.status === "pending" || event.status === "running"))
1756
+ );
1757
+ const startMs = parseMs(file.startedAt);
1758
+ const nodes = exportedEvents.map((event) => {
1759
+ const endMs = parseMs(event.timestamp) ?? startMs ?? Date.now();
1760
+ const endNs = msToNs(endMs);
1761
+ let startNs = endNs - durationNs(event.durationMs);
1762
+ if (startNs < 0n) startNs = 0n;
1763
+ return {
1764
+ event,
1765
+ spanId: event.spanId || generateSpanId(),
1766
+ parentId: event.parentSpanId || rootSpanId,
1767
+ startNs,
1768
+ endNs
1769
+ };
1770
+ });
1771
+ const childrenOf = /* @__PURE__ */ new Map();
1772
+ for (const node of nodes) {
1773
+ const list = childrenOf.get(node.parentId);
1774
+ if (list) list.push(node);
1775
+ else childrenOf.set(node.parentId, [node]);
1776
+ }
1777
+ const settled = /* @__PURE__ */ new Set();
1778
+ const inProgress = /* @__PURE__ */ new Set();
1779
+ const widen = (node) => {
1780
+ if (settled.has(node) || inProgress.has(node)) return;
1781
+ inProgress.add(node);
1782
+ for (const child of childrenOf.get(node.spanId) ?? []) {
1783
+ if (child === node) continue;
1784
+ widen(child);
1785
+ if (child.startNs < node.startNs) node.startNs = child.startNs;
1786
+ if (child.endNs > node.endNs) node.endNs = child.endNs;
1787
+ }
1788
+ inProgress.delete(node);
1789
+ settled.add(node);
1790
+ };
1791
+ for (const node of nodes) widen(node);
1792
+ const byId = /* @__PURE__ */ new Map();
1793
+ for (const event of everyEvent) if (event.spanId) byId.set(event.spanId, event);
1794
+ const agentOf = (event) => {
1795
+ let cursor = event;
1796
+ for (let hops = 0; cursor && hops < 64; hops++) {
1797
+ if (cursor !== event && cursor.type === "span" && cursor.actor?.role === "subagent") return cursor.actor.name;
1798
+ cursor = cursor.parentSpanId ? byId.get(cursor.parentSpanId) : void 0;
1799
+ }
1800
+ return agentName;
1801
+ };
1802
+ const spans = [];
1803
+ const sessionErrors = (file.errors ?? []).filter((error) => error.eventId === "session");
1804
+ if (options.terminal) {
1805
+ const earliestChild = nodes.reduce(
1806
+ (earliest, node) => earliest === void 0 || node.startNs < earliest ? node.startNs : earliest,
1807
+ void 0
1808
+ );
1809
+ let rootStart = startMs !== void 0 ? msToNs(startMs) : earliestChild ?? msToNs(Date.now());
1810
+ let rootEnd = msToNs(parseMs(file.endedAt) ?? (startMs !== void 0 ? startMs + (file.durationMs ?? 0) : Date.now()));
1811
+ for (const node of childrenOf.get(rootSpanId) ?? []) {
1812
+ if (node.startNs < rootStart) rootStart = node.startNs;
1813
+ if (node.endNs > rootEnd) rootEnd = node.endNs;
1814
+ }
1815
+ if (rootEnd < rootStart) rootEnd = rootStart;
1816
+ const rootName = useGenAi ? agentName ? `${OPERATION.invokeAgent} ${agentName}` : OPERATION.invokeAgent : `agent_session: ${agentName || "agent"}`;
1817
+ const summary = file.summary;
1818
+ const cumulativeEvents = summary?.eventCounts ? Object.values(summary.eventCounts).reduce((total, count) => total + (Number(count) || 0), 0) : file.events.length;
1819
+ const attributes = [];
1820
+ if (useCognipeer) {
1821
+ attributes.push(
1822
+ ...compact([
1823
+ strAllowEmpty("cognipeer.session.status", options.cancelled ? "partial" : file.status),
1824
+ dbl("cognipeer.session.duration_ms", file.durationMs),
1825
+ int("cognipeer.session.total_input_tokens", summary?.totalInputTokens),
1826
+ int("cognipeer.session.total_output_tokens", summary?.totalOutputTokens),
1827
+ int("cognipeer.session.total_cached_input_tokens", summary?.totalCachedInputTokens),
1828
+ int("cognipeer.session.total_bytes_in", summary?.totalBytesIn),
1829
+ int("cognipeer.session.total_bytes_out", summary?.totalBytesOut),
1830
+ int("cognipeer.session.event_count", cumulativeEvents)
1831
+ ])
1832
+ );
1833
+ for (const [key, count] of Object.entries(summary?.eventCounts ?? {})) {
1834
+ attributes.push({ key: `cognipeer.session.event_count.${key}`, value: { intValue: String(count) } });
1835
+ }
1836
+ }
1837
+ if (useGenAi) {
1838
+ attributes.push(
1839
+ ...compact([
1840
+ str(ATTR.operationName, OPERATION.invokeAgent),
1841
+ str(ATTR.agentName, agentName),
1842
+ str(ATTR.agentVersion, file.agent?.version),
1843
+ str(ATTR.requestModel, knownModel(file.agent?.model)),
1844
+ str(ATTR.conversationId, file.threadId)
1845
+ ])
1846
+ );
1847
+ }
1848
+ const root = {
1849
+ traceId,
1850
+ spanId: rootSpanId,
1851
+ parentSpanId: parent?.spanId ?? "",
1852
+ ...traceState ? { traceState } : {},
1853
+ flags: rootFlags,
1854
+ name: rootName,
1855
+ kind: SPAN_KIND_INTERNAL,
1856
+ startTimeUnixNano: rootStart.toString(),
1857
+ endTimeUnixNano: rootEnd.toString(),
1858
+ attributes,
1859
+ status: { code: 0 }
1860
+ };
1861
+ if (sessionErrors.length > 0) {
1862
+ root.status = {
1863
+ code: 2,
1864
+ message: cappedMessage(sessionErrors.map((error) => error.message).join("; "))
1865
+ };
1866
+ if (useGenAi) root.attributes.push({ key: ATTR.errorType, value: { stringValue: errorTypeOf({ type: sessionErrors[0].errorName, stack: sessionErrors[0].stack }) } });
1867
+ root.events = sessionErrors.map((error) => {
1868
+ const at = parseMs(error.timestamp);
1869
+ return exceptionEvent(at !== void 0 ? msToNs(at) : rootEnd, {
1870
+ message: error.message,
1871
+ stack: error.stack,
1872
+ type: error.errorName
1873
+ });
1874
+ });
1875
+ }
1876
+ spans.push(root);
1877
+ }
1878
+ for (const node of nodes) {
1879
+ const event = node.event;
1880
+ const kind = classify(event);
1881
+ const failed = event.status === "error";
1882
+ const cancelledChat = kind === "chat" && event.skipReason === "cancelled";
1883
+ const attributes = [];
1884
+ if (useCognipeer) {
1885
+ attributes.push(
1886
+ ...compact([
1887
+ strAllowEmpty("cognipeer.event.type", event.type),
1888
+ strAllowEmpty("cognipeer.event.label", event.label),
1889
+ int("cognipeer.event.sequence", event.sequence),
1890
+ strAllowEmpty("cognipeer.actor.scope", event.actor?.scope),
1891
+ strAllowEmpty("cognipeer.actor.name", event.actor?.name),
1892
+ strAllowEmpty("cognipeer.actor.role", event.actor?.role),
1893
+ strAllowEmpty("cognipeer.model", event.model),
1894
+ int("cognipeer.tokens.reasoning", event.reasoningTokens),
1895
+ strAllowEmpty("cognipeer.finish_reason", event.finishReason),
1896
+ strAllowEmpty("cognipeer.provider", event.provider),
1897
+ strAllowEmpty("cognipeer.tool.details", event.toolDetails ? JSON.stringify(event.toolDetails) : void 0),
1898
+ int("cognipeer.tokens.input", event.inputTokens),
1899
+ int("cognipeer.tokens.output", event.outputTokens),
1900
+ int("cognipeer.tokens.total", event.totalTokens),
1901
+ int("cognipeer.tokens.cached_input", event.cachedInputTokens),
1902
+ int("cognipeer.bytes.request", event.requestBytes),
1903
+ int("cognipeer.bytes.response", event.responseBytes),
1904
+ strAllowEmpty("cognipeer.tool.execution_id", event.toolExecutionId),
1905
+ strAllowEmpty("cognipeer.retry_of", event.retryOf),
1906
+ strAllowEmpty("cognipeer.event.id", event.id)
1907
+ ])
1908
+ );
1909
+ const sectionsAttr = sectionsAttribute(event.data?.sections, event, options.content);
1910
+ if (sectionsAttr) attributes.push(sectionsAttr);
1911
+ attributes.push({ key: "cognipeer.event.status", value: { stringValue: event.status } });
1912
+ }
1913
+ let name = event.label || event.type;
1914
+ let spanKind = SPAN_KIND_INTERNAL;
1915
+ if (kind === "chat") spanKind = SPAN_KIND_CLIENT;
1916
+ if (useGenAi) {
1917
+ const conversation = str(ATTR.conversationId, file.threadId);
1918
+ if (kind === "chat") {
1919
+ const model = knownModel(event.model);
1920
+ name = model ? `${OPERATION.chat} ${model}` : OPERATION.chat;
1921
+ attributes.push(
1922
+ ...compact([
1923
+ str(ATTR.operationName, OPERATION.chat),
1924
+ str(ATTR.providerName, genAiProviderName(event.provider)),
1925
+ str(ATTR.requestModel, model),
1926
+ str(ATTR.responseModel, event.responseModel),
1927
+ str(ATTR.responseId, event.responseId),
1928
+ bool(ATTR.requestStream, event.streaming),
1929
+ str(ATTR.outputType, event.outputType)
1930
+ ])
1931
+ );
1932
+ if (failed || cancelledChat) {
1933
+ attributes.push(strArray(ATTR.finishReasons, ["error"]));
1934
+ } else {
1935
+ const reason = event.rawFinishReason ?? event.finishReason;
1936
+ if (reason) attributes.push(strArray(ATTR.finishReasons, [reason]));
1937
+ }
1938
+ const usageAllowed = !failed && !cancelledChat && (event.type !== "summarization" || event.debug?.usageFromModel === true);
1939
+ const usage = usageAllowed ? genAiUsageOf(event) : void 0;
1940
+ if (usage) {
1941
+ attributes.push(
1942
+ ...compact([
1943
+ int(ATTR.usageInput, usage.input),
1944
+ int(ATTR.usageOutput, usage.output),
1945
+ int(ATTR.usageCacheRead, usage.cacheRead),
1946
+ int(ATTR.usageCacheWrite, usage.cacheWrite),
1947
+ int(ATTR.usageReasoning, usage.reasoning)
1948
+ ])
1949
+ );
1950
+ }
1951
+ if (conversation) attributes.push(conversation);
1952
+ attributes.push(...contentAttributes("chat", event, genAiProviderName(event.provider), options.content));
1953
+ } else if (kind === "execute_tool") {
1954
+ const tool = toolNameOf(event);
1955
+ name = tool ? `${OPERATION.executeTool} ${tool}` : OPERATION.executeTool;
1956
+ attributes.push(
1957
+ ...compact([
1958
+ str(ATTR.operationName, OPERATION.executeTool),
1959
+ str(ATTR.toolName, tool),
1960
+ str(ATTR.toolCallId, event.toolCallId),
1961
+ str(ATTR.toolType, "function"),
1962
+ str(ATTR.agentName, agentOf(event)),
1963
+ conversation
1964
+ ])
1965
+ );
1966
+ attributes.push(...contentAttributes("execute_tool", event, void 0, options.content));
1967
+ } else if (kind === "invoke_agent") {
1968
+ const child = event.actor?.name;
1969
+ name = child ? `${OPERATION.invokeAgent} ${child}` : OPERATION.invokeAgent;
1970
+ attributes.push(...compact([str(ATTR.operationName, OPERATION.invokeAgent), str(ATTR.agentName, child), conversation]));
1971
+ } else {
1972
+ name = stripSequence(name);
1973
+ }
1974
+ }
1975
+ const span = {
1976
+ traceId: event.traceId || traceId,
1977
+ spanId: node.spanId,
1978
+ parentSpanId: node.parentId,
1979
+ ...traceState ? { traceState } : {},
1980
+ flags,
1981
+ name,
1982
+ kind: spanKind,
1983
+ startTimeUnixNano: node.startNs.toString(),
1984
+ endTimeUnixNano: node.endNs.toString(),
1985
+ attributes,
1986
+ status: { code: 0 }
1987
+ };
1988
+ if (failed) {
1989
+ const error = event.error ?? { message: "Unknown error" };
1990
+ span.status = { code: 2, message: cappedMessage(error.message) };
1991
+ if (useGenAi) attributes.push({ key: ATTR.errorType, value: { stringValue: errorTypeOf(error) } });
1992
+ span.events = [exceptionEvent(node.endNs, error)];
1993
+ }
1994
+ spans.push(span);
1995
+ }
1996
+ return {
1997
+ resourceSpans: [
1998
+ {
1999
+ resource: { attributes: resourceAttributesOf(file, options, useCognipeer) },
2000
+ scopeSpans: [{ scope: { name: SCOPE_NAME, version: SDK_VERSION }, spans }]
2001
+ }
2002
+ ]
2003
+ };
2004
+ }
2005
+ function resourceAttributesOf(file, options, useCognipeer) {
2006
+ const custom = options.resourceAttributes ?? {};
2007
+ const serviceName = options.serviceName || custom["service.name"] || file.agent?.name || "cognipeer-agent";
2008
+ const attributes = compact([
2009
+ str("service.name", serviceName),
2010
+ str("service.version", file.agent?.version)
2011
+ ]);
2012
+ if (useCognipeer) {
2013
+ attributes.push(
2014
+ ...compact([
2015
+ str("cognipeer.session.id", file.sessionId),
2016
+ str("cognipeer.thread.id", file.threadId),
2017
+ str("cognipeer.agent.model", file.agent?.model),
2018
+ str("cognipeer.agent.provider", file.agent?.provider),
2019
+ ...Object.entries(file.metadata ?? {}).map(([key, value]) => str(`cognipeer.metadata.${key}`, value))
2020
+ ])
2021
+ );
2022
+ }
2023
+ attributes.push(
2024
+ ...compact([
2025
+ str("telemetry.sdk.name", SCOPE_NAME),
2026
+ str("telemetry.sdk.language", "nodejs"),
2027
+ str("telemetry.sdk.version", SDK_VERSION)
2028
+ ])
2029
+ );
2030
+ for (const [key, value] of Object.entries(custom)) {
2031
+ if (key === "service.name") continue;
2032
+ const index = attributes.findIndex((attr) => attr.key === key);
2033
+ const entry = str(key, value);
2034
+ if (!entry) continue;
2035
+ if (index >= 0) attributes[index] = entry;
2036
+ else attributes.push(entry);
2037
+ }
2038
+ return attributes;
2039
+ }
2040
+ function countSpans(request) {
2041
+ let total = 0;
2042
+ for (const rs of request.resourceSpans) for (const ss of rs.scopeSpans) total += ss.spans.length;
2043
+ return total;
2044
+ }
2045
+
2046
+ // src/utils/otlp/env.ts
2047
+ var warned = /* @__PURE__ */ new Set();
2048
+ function warnOnce(message) {
2049
+ if (warned.has(message)) return;
2050
+ warned.add(message);
2051
+ if (typeof console !== "undefined" && typeof console.warn === "function") console.warn(message);
2052
+ }
2053
+ function pick(env, ...names) {
2054
+ for (const name of names) {
2055
+ const value = env[name];
2056
+ if (typeof value === "string" && value.trim().length > 0) return value.trim();
2057
+ }
2058
+ return void 0;
2059
+ }
2060
+ function decode(value) {
2061
+ try {
2062
+ return decodeURIComponent(value);
2063
+ } catch {
2064
+ return value;
2065
+ }
2066
+ }
2067
+ function parseKeyValueList(raw) {
2068
+ const out = {};
2069
+ if (!raw) return out;
2070
+ for (const part of raw.split(",")) {
2071
+ const index = part.indexOf("=");
2072
+ if (index <= 0) continue;
2073
+ const key = part.slice(0, index).trim();
2074
+ if (!key) continue;
2075
+ out[key] = decode(part.slice(index + 1).trim());
2076
+ }
2077
+ return out;
2078
+ }
2079
+ function tracesEndpointFrom(base) {
2080
+ return `${base.replace(/\/+$/, "")}/v1/traces`;
2081
+ }
2082
+ function protocolFrom(raw, fallback) {
2083
+ if (!raw) return fallback;
2084
+ const value = raw.toLowerCase();
2085
+ if (value === "http/protobuf" || value === "http/json") return value;
2086
+ warnOnce(
2087
+ value === "grpc" ? `[agent-sdk] OTLP/gRPC is not supported; exporting over ${fallback} instead.` : `[agent-sdk] OTLP protocol "${raw}" is not supported (use http/json or http/protobuf); falling back to ${fallback}.`
2088
+ );
2089
+ return fallback;
2090
+ }
2091
+ function resolveOtlpEnv(env, explicit) {
2092
+ const explicitEndpoint = typeof explicit.endpoint === "string" ? explicit.endpoint.trim() : "";
2093
+ const envDriven = explicitEndpoint.length === 0;
2094
+ const resourceAttributes = parseKeyValueList(pick(env, "OTEL_RESOURCE_ATTRIBUTES"));
2095
+ const serviceName = pick(env, "OTEL_SERVICE_NAME");
2096
+ if (!envDriven) {
2097
+ return {
2098
+ envDriven,
2099
+ endpoint: explicitEndpoint,
2100
+ headers: { ...explicit.headers ?? {} },
2101
+ protocol: explicit.protocol ?? "http/json",
2102
+ compression: explicit.compression ?? "none",
2103
+ timeoutMs: explicit.timeoutMs,
2104
+ serviceName,
2105
+ resourceAttributes,
2106
+ disabled: false
2107
+ };
2108
+ }
2109
+ const tracesEndpoint = pick(env, "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT");
2110
+ const baseEndpoint = pick(env, "OTEL_EXPORTER_OTLP_ENDPOINT");
2111
+ const endpoint = tracesEndpoint ?? (baseEndpoint ? tracesEndpointFrom(baseEndpoint) : void 0);
2112
+ const envHeaders = {
2113
+ ...parseKeyValueList(pick(env, "OTEL_EXPORTER_OTLP_HEADERS")),
2114
+ ...parseKeyValueList(pick(env, "OTEL_EXPORTER_OTLP_TRACES_HEADERS"))
2115
+ };
2116
+ const timeoutRaw = pick(env, "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT", "OTEL_EXPORTER_OTLP_TIMEOUT");
2117
+ const timeout = timeoutRaw !== void 0 ? Number(timeoutRaw) : void 0;
2118
+ const compressionRaw = pick(env, "OTEL_EXPORTER_OTLP_TRACES_COMPRESSION", "OTEL_EXPORTER_OTLP_COMPRESSION")?.toLowerCase();
2119
+ return {
2120
+ envDriven,
2121
+ endpoint,
2122
+ headers: { ...envHeaders, ...explicit.headers ?? {} },
2123
+ protocol: explicit.protocol ?? protocolFrom(pick(env, "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "OTEL_EXPORTER_OTLP_PROTOCOL"), "http/protobuf"),
2124
+ compression: explicit.compression ?? (compressionRaw === "gzip" ? "gzip" : "none"),
2125
+ timeoutMs: explicit.timeoutMs ?? (timeout !== void 0 && Number.isFinite(timeout) && timeout > 0 ? timeout : void 0),
2126
+ serviceName,
2127
+ resourceAttributes,
2128
+ disabled: pick(env, "OTEL_SDK_DISABLED")?.toLowerCase() === "true" || pick(env, "OTEL_TRACES_EXPORTER")?.toLowerCase() === "none"
2129
+ };
2130
+ }
2131
+ function currentEnv() {
2132
+ return typeof process !== "undefined" && process.env ? process.env : {};
2133
+ }
2134
+ var WIRE_VARINT = 0;
2135
+ var WIRE_FIXED64 = 1;
2136
+ var WIRE_LEN = 2;
2137
+ var WIRE_FIXED32 = 5;
2138
+ var textEncoder = new TextEncoder();
2139
+ var Writer = class {
2140
+ constructor() {
2141
+ this.buf = new Uint8Array(128);
2142
+ this.len = 0;
2143
+ this.view = new DataView(this.buf.buffer);
2144
+ }
2145
+ ensure(extra) {
2146
+ if (this.len + extra <= this.buf.length) return;
2147
+ let size = this.buf.length * 2;
2148
+ while (size < this.len + extra) size *= 2;
2149
+ const next = new Uint8Array(size);
2150
+ next.set(this.buf.subarray(0, this.len));
2151
+ this.buf = next;
2152
+ this.view = new DataView(next.buffer);
2153
+ }
2154
+ byte(value) {
2155
+ this.ensure(1);
2156
+ this.buf[this.len++] = value;
2157
+ }
2158
+ varint(value) {
2159
+ if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) {
2160
+ let n2 = value;
2161
+ while (n2 >= 128) {
2162
+ this.byte(n2 % 128 | 128);
2163
+ n2 = Math.floor(n2 / 128);
2164
+ }
2165
+ this.byte(n2);
2166
+ return;
2167
+ }
2168
+ let n = BigInt.asUintN(64, BigInt(value));
2169
+ while (n >= 128n) {
2170
+ this.byte(Number(n & 127n) | 128);
2171
+ n >>= 7n;
2172
+ }
2173
+ this.byte(Number(n));
2174
+ }
2175
+ tag(field, wire) {
2176
+ this.varint(field * 8 + wire);
2177
+ }
2178
+ raw(bytes) {
2179
+ this.ensure(bytes.length);
2180
+ this.buf.set(bytes, this.len);
2181
+ this.len += bytes.length;
2182
+ }
2183
+ fixed64(value) {
2184
+ this.ensure(8);
2185
+ this.view.setBigUint64(this.len, BigInt.asUintN(64, value), true);
2186
+ this.len += 8;
2187
+ }
2188
+ fixed32(value) {
2189
+ this.ensure(4);
2190
+ this.view.setUint32(this.len, value >>> 0, true);
2191
+ this.len += 4;
2192
+ }
2193
+ double(value) {
2194
+ this.ensure(8);
2195
+ this.view.setFloat64(this.len, value, true);
2196
+ this.len += 8;
2197
+ }
2198
+ finish() {
2199
+ return this.buf.slice(0, this.len);
2200
+ }
2201
+ };
2202
+ function lenField(w, field, bytes) {
2203
+ w.tag(field, WIRE_LEN);
2204
+ w.varint(bytes.length);
2205
+ w.raw(bytes);
2206
+ }
2207
+ function stringField(w, field, value) {
2208
+ if (!value) return;
2209
+ lenField(w, field, textEncoder.encode(value));
2210
+ }
2211
+ function hexBytes(hex, bytes) {
2212
+ if (!hex) return void 0;
2213
+ const out = new Uint8Array(bytes);
2214
+ for (let i = 0; i < bytes; i++) {
2215
+ const pair = hex.slice(i * 2, i * 2 + 2);
2216
+ const value = /^[0-9a-fA-F]{2}$/.test(pair) ? parseInt(pair, 16) : 0;
2217
+ out[i] = value;
2218
+ }
2219
+ return out;
2220
+ }
2221
+ function base64Bytes(value) {
2222
+ return new Uint8Array(buffer.Buffer.from(value, "base64"));
2223
+ }
2224
+ function encodeAnyValue(value) {
2225
+ const w = new Writer();
2226
+ if (value.stringValue !== void 0) {
2227
+ lenField(w, 1, textEncoder.encode(value.stringValue));
2228
+ } else if (value.boolValue !== void 0) {
2229
+ w.tag(2, WIRE_VARINT);
2230
+ w.varint(value.boolValue ? 1 : 0);
2231
+ } else if (value.intValue !== void 0) {
2232
+ w.tag(3, WIRE_VARINT);
2233
+ w.varint(BigInt(value.intValue));
2234
+ } else if (value.doubleValue !== void 0) {
2235
+ w.tag(4, WIRE_FIXED64);
2236
+ w.double(value.doubleValue);
2237
+ } else if (value.arrayValue !== void 0) {
2238
+ const inner = new Writer();
2239
+ for (const item of value.arrayValue.values) lenField(inner, 1, encodeAnyValue(item));
2240
+ lenField(w, 5, inner.finish());
2241
+ } else if (value.kvlistValue !== void 0) {
2242
+ const inner = new Writer();
2243
+ for (const kv of value.kvlistValue.values) lenField(inner, 1, encodeKeyValue(kv));
2244
+ lenField(w, 6, inner.finish());
2245
+ } else if (value.bytesValue !== void 0) {
2246
+ lenField(w, 7, base64Bytes(value.bytesValue));
2247
+ }
2248
+ return w.finish();
2249
+ }
2250
+ function encodeKeyValue(kv) {
2251
+ const w = new Writer();
2252
+ stringField(w, 1, kv.key);
2253
+ lenField(w, 2, encodeAnyValue(kv.value));
2254
+ return w.finish();
2255
+ }
2256
+ function encodeSpanEvent(event) {
2257
+ const w = new Writer();
2258
+ w.tag(1, WIRE_FIXED64);
2259
+ w.fixed64(BigInt(event.timeUnixNano));
2260
+ stringField(w, 2, event.name);
2261
+ for (const attr of event.attributes) lenField(w, 3, encodeKeyValue(attr));
2262
+ return w.finish();
2263
+ }
2264
+ function encodeSpan(span) {
2265
+ const w = new Writer();
2266
+ const traceId = hexBytes(span.traceId, 16);
2267
+ if (traceId) lenField(w, 1, traceId);
2268
+ const spanId = hexBytes(span.spanId, 8);
2269
+ if (spanId) lenField(w, 2, spanId);
2270
+ stringField(w, 3, span.traceState);
2271
+ const parent = hexBytes(span.parentSpanId, 8);
2272
+ if (parent) lenField(w, 4, parent);
2273
+ stringField(w, 5, span.name);
2274
+ if (span.kind) {
2275
+ w.tag(6, WIRE_VARINT);
2276
+ w.varint(span.kind);
2277
+ }
2278
+ w.tag(7, WIRE_FIXED64);
2279
+ w.fixed64(BigInt(span.startTimeUnixNano));
2280
+ w.tag(8, WIRE_FIXED64);
2281
+ w.fixed64(BigInt(span.endTimeUnixNano));
2282
+ for (const attr of span.attributes) lenField(w, 9, encodeKeyValue(attr));
2283
+ for (const event of span.events ?? []) lenField(w, 11, encodeSpanEvent(event));
2284
+ const status = new Writer();
2285
+ stringField(status, 2, span.status.message);
2286
+ if (span.status.code) {
2287
+ status.tag(3, WIRE_VARINT);
2288
+ status.varint(span.status.code);
2289
+ }
2290
+ lenField(w, 15, status.finish());
2291
+ if (span.flags) {
2292
+ w.tag(16, WIRE_FIXED32);
2293
+ w.fixed32(span.flags);
2294
+ }
2295
+ return w.finish();
2296
+ }
2297
+ function encodeExportTraceServiceRequest(request) {
2298
+ const w = new Writer();
2299
+ for (const rs of request.resourceSpans) {
2300
+ const resourceSpans = new Writer();
2301
+ const resource = new Writer();
2302
+ for (const attr of rs.resource.attributes) lenField(resource, 1, encodeKeyValue(attr));
2303
+ lenField(resourceSpans, 1, resource.finish());
2304
+ for (const ss of rs.scopeSpans) {
2305
+ const scopeSpans = new Writer();
2306
+ const scope = new Writer();
2307
+ stringField(scope, 1, ss.scope.name);
2308
+ stringField(scope, 2, ss.scope.version);
2309
+ lenField(scopeSpans, 1, scope.finish());
2310
+ for (const span of ss.spans) lenField(scopeSpans, 2, encodeSpan(span));
2311
+ lenField(resourceSpans, 2, scopeSpans.finish());
2312
+ }
2313
+ stringField(resourceSpans, 3, rs.schemaUrl);
2314
+ lenField(w, 1, resourceSpans.finish());
2315
+ }
2316
+ return w.finish();
2317
+ }
2318
+ var Reader = class {
2319
+ constructor(bytes) {
2320
+ this.bytes = bytes;
2321
+ this.pos = 0;
2322
+ }
2323
+ get done() {
2324
+ return this.pos >= this.bytes.length;
2325
+ }
2326
+ varint() {
2327
+ let result = 0n;
2328
+ let shift = 0n;
2329
+ for (; ; ) {
2330
+ if (this.pos >= this.bytes.length) throw new Error("truncated varint");
2331
+ const byte = this.bytes[this.pos++];
2332
+ result |= BigInt(byte & 127) << shift;
2333
+ if ((byte & 128) === 0) return result;
2334
+ shift += 7n;
2335
+ if (shift > 70n) throw new Error("varint too long");
2336
+ }
2337
+ }
2338
+ slice(length) {
2339
+ if (this.pos + length > this.bytes.length) throw new Error("truncated field");
2340
+ const out = this.bytes.subarray(this.pos, this.pos + length);
2341
+ this.pos += length;
2342
+ return out;
2343
+ }
2344
+ skip(wire) {
2345
+ if (wire === WIRE_VARINT) this.varint();
2346
+ else if (wire === WIRE_FIXED64) this.slice(8);
2347
+ else if (wire === WIRE_FIXED32) this.slice(4);
2348
+ else if (wire === WIRE_LEN) this.slice(Number(this.varint()));
2349
+ else throw new Error(`unsupported wire type ${wire}`);
2350
+ }
2351
+ };
2352
+ function decodeExportTraceServiceResponse(bytes) {
2353
+ const top = new Reader(bytes);
2354
+ let result;
2355
+ while (!top.done) {
2356
+ const key = Number(top.varint());
2357
+ const field = key >>> 3;
2358
+ const wire = key & 7;
2359
+ if (field === 1 && wire === WIRE_LEN) {
2360
+ const inner = new Reader(top.slice(Number(top.varint())));
2361
+ let rejected = 0n;
2362
+ let message;
2363
+ while (!inner.done) {
2364
+ const innerKey = Number(inner.varint());
2365
+ const innerField = innerKey >>> 3;
2366
+ const innerWire = innerKey & 7;
2367
+ if (innerField === 1 && innerWire === WIRE_VARINT) rejected = BigInt.asIntN(64, inner.varint());
2368
+ else if (innerField === 2 && innerWire === WIRE_LEN) message = new TextDecoder().decode(inner.slice(Number(inner.varint())));
2369
+ else inner.skip(innerWire);
2370
+ }
2371
+ result = { rejectedSpans: Number(rejected), ...message ? { message } : {} };
2372
+ } else {
2373
+ top.skip(wire);
2374
+ }
2375
+ }
2376
+ return result;
2377
+ }
2378
+
2379
+ // src/utils/otlp/exporter.ts
2380
+ var gzipAsync = util.promisify(zlib.gzip);
2381
+ var DEFAULT_TIMEOUT_MS = 1e4;
2382
+ var RETRY_DEFAULTS = {
2383
+ maxAttempts: 3,
2384
+ initialDelayMs: 250,
2385
+ maxDelayMs: 4e3,
2386
+ maxElapsedMs: 25e3
2387
+ };
2388
+ var RETRYABLE_STATUS = /* @__PURE__ */ new Set([429, 502, 503, 504]);
2389
+ function retryPolicy(retry) {
2390
+ if (retry === false) return { ...RETRY_DEFAULTS, maxAttempts: 1 };
2391
+ const merged = { ...RETRY_DEFAULTS, ...retry ?? {} };
2392
+ return { ...merged, maxAttempts: Math.max(1, Math.floor(merged.maxAttempts)) };
2393
+ }
2394
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2395
+ function retryAfterMs(response) {
2396
+ let raw;
2397
+ try {
2398
+ raw = response?.headers?.get?.("retry-after");
2399
+ } catch {
2400
+ return void 0;
2401
+ }
2402
+ if (typeof raw !== "string" || raw.trim() === "") return void 0;
2403
+ const seconds = Number(raw);
2404
+ if (Number.isFinite(seconds)) return Math.max(0, seconds * 1e3);
2405
+ const date = Date.parse(raw);
2406
+ return Number.isNaN(date) ? void 0 : Math.max(0, date - Date.now());
2407
+ }
2408
+ async function attemptOnce(fetchFn, url, init, timeoutMs, protocol) {
2409
+ const controller = new AbortController();
2410
+ let timer;
2411
+ const timeout = new Promise((_, reject) => {
2412
+ timer = setTimeout(() => {
2413
+ controller.abort();
2414
+ reject(new Error(`timed out after ${timeoutMs} ms`));
2415
+ }, timeoutMs);
2416
+ });
2417
+ try {
2418
+ const pending = fetchFn(url, { ...init, signal: controller.signal });
2419
+ Promise.resolve(pending).catch(() => void 0);
2420
+ const response = await Promise.race([pending, timeout]);
2421
+ const status = typeof response?.status === "number" ? response.status : response?.ok ? 200 : 0;
2422
+ const ok = typeof response?.ok === "boolean" ? response.ok : status >= 200 && status < 300;
2423
+ if (ok) {
2424
+ const lateBody = timeout.catch(() => void 0);
2425
+ const partialSuccess = await Promise.race([readPartialSuccess(response, protocol), lateBody]);
2426
+ return { kind: "ok", status, ...partialSuccess ? { partialSuccess } : {} };
2427
+ }
2428
+ let body = "";
2429
+ try {
2430
+ if (typeof response?.text === "function") body = String(await response.text());
2431
+ } catch {
2432
+ }
2433
+ const statusText = typeof response?.statusText === "string" && response.statusText ? ` ${response.statusText}` : "";
2434
+ return {
2435
+ kind: "http",
2436
+ status,
2437
+ message: `HTTP ${status}${statusText}${body ? ` - ${body.slice(0, 200)}` : ""}`,
2438
+ retryable: RETRYABLE_STATUS.has(status),
2439
+ retryAfter: retryAfterMs(response)
2440
+ };
2441
+ } catch (err) {
2442
+ return { kind: "network", message: err instanceof Error ? err.message : String(err) };
2443
+ } finally {
2444
+ if (timer !== void 0) clearTimeout(timer);
2445
+ }
2446
+ }
2447
+ async function readPartialSuccess(response, protocol) {
2448
+ try {
2449
+ if (protocol === "http/protobuf") {
2450
+ if (typeof response?.arrayBuffer !== "function") return void 0;
2451
+ const bytes = new Uint8Array(await response.arrayBuffer());
2452
+ if (bytes.length === 0) return void 0;
2453
+ const decoded = decodeExportTraceServiceResponse(bytes);
2454
+ return decoded && (decoded.rejectedSpans > 0 || decoded.message) ? decoded : void 0;
2455
+ }
2456
+ if (typeof response?.text !== "function") return void 0;
2457
+ const text = String(await response.text());
2458
+ if (!text.trim()) return void 0;
2459
+ const partial = JSON.parse(text)?.partialSuccess;
2460
+ if (!partial || typeof partial !== "object") return void 0;
2461
+ const rejectedSpans = Number(partial.rejectedSpans ?? 0);
2462
+ const message = typeof partial.errorMessage === "string" && partial.errorMessage ? partial.errorMessage : void 0;
2463
+ if (!(rejectedSpans > 0) && !message) return void 0;
2464
+ return { rejectedSpans: Number.isFinite(rejectedSpans) ? rejectedSpans : 0, ...message ? { message } : {} };
2465
+ } catch {
2466
+ return void 0;
2467
+ }
2468
+ }
2469
+ function createOtlpExporter(options = {}) {
2470
+ const env = resolveOtlpEnv(currentEnv(), options);
2471
+ if (!env.endpoint && !env.disabled) {
2472
+ throw new Error(
2473
+ "[agent-sdk] OTLP export needs an `endpoint` (or OTEL_EXPORTER_OTLP_ENDPOINT / OTEL_EXPORTER_OTLP_TRACES_ENDPOINT in the environment)."
2474
+ );
2475
+ }
2476
+ const semconv = options.semconv ?? "both";
2477
+ const protocol = env.protocol;
2478
+ const compression = env.compression;
2479
+ const timeoutMs = env.timeoutMs ?? DEFAULT_TIMEOUT_MS;
2480
+ const policy = retryPolicy(options.retry);
2481
+ const serviceName = options.serviceName ?? env.serviceName;
2482
+ const resourceAttributes = { ...env.resourceAttributes, ...options.resourceAttributes ?? {} };
2483
+ const endpoint = env.endpoint ?? "";
2484
+ const content = resolveContentOptions(options.content);
2485
+ return {
2486
+ name: options.name ?? "otlp",
2487
+ endpoint,
2488
+ semconv,
2489
+ protocol,
2490
+ wantsContent: content.enabled,
2491
+ contentOptions: content,
2492
+ async exportSession(file, run) {
2493
+ try {
2494
+ if (env.disabled) {
2495
+ return { ok: true, skipped: true, reason: "disabled by the environment (OTEL_SDK_DISABLED / OTEL_TRACES_EXPORTER)", attempts: 0, spans: 0, bytes: 0 };
2496
+ }
2497
+ const convertOptions = {
2498
+ semconv,
2499
+ serviceName,
2500
+ resourceAttributes,
2501
+ terminal: run.terminal,
2502
+ cancelled: run.cancelled,
2503
+ parent: run.parent,
2504
+ content
2505
+ };
2506
+ const request = sessionToOtlp(file, convertOptions);
2507
+ const spans = countSpans(request);
2508
+ if (spans === 0) return { ok: true, skipped: true, reason: "no spans to export", attempts: 0, spans: 0, bytes: 0 };
2509
+ const fetchFn = options.fetch ?? (typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0);
2510
+ if (!fetchFn) return { ok: false, attempts: 0, spans, bytes: 0, error: "OTLP export requires fetch to be available in this runtime." };
2511
+ let body = protocol === "http/protobuf" ? encodeExportTraceServiceRequest(request) : JSON.stringify(request);
2512
+ const headers = {
2513
+ "content-type": protocol === "http/protobuf" ? "application/x-protobuf" : "application/json"
2514
+ };
2515
+ if (compression === "gzip") {
2516
+ body = await gzipAsync(typeof body === "string" ? buffer.Buffer.from(body, "utf8") : body);
2517
+ headers["content-encoding"] = "gzip";
2518
+ }
2519
+ Object.assign(headers, env.headers);
2520
+ const bytes = typeof body === "string" ? buffer.Buffer.byteLength(body, "utf8") : body.length;
2521
+ const started = Date.now();
2522
+ let attempts = 0;
2523
+ let lastError = "export failed";
2524
+ let lastStatus;
2525
+ for (; ; ) {
2526
+ attempts += 1;
2527
+ const remaining = policy.maxElapsedMs - (Date.now() - started);
2528
+ const outcome = await attemptOnce(
2529
+ fetchFn,
2530
+ env.endpoint,
2531
+ { method: "POST", headers, body },
2532
+ Math.max(1, Math.min(timeoutMs, remaining)),
2533
+ protocol
2534
+ );
2535
+ if (outcome.kind === "ok") {
2536
+ return { ok: true, attempts, status: outcome.status, spans, bytes, ...outcome.partialSuccess ? { partialSuccess: outcome.partialSuccess } : {} };
2537
+ }
2538
+ lastError = outcome.message;
2539
+ lastStatus = outcome.kind === "http" ? outcome.status : void 0;
2540
+ const retryable = outcome.kind === "network" || outcome.retryable;
2541
+ if (!retryable || attempts >= policy.maxAttempts) break;
2542
+ const ceiling = Math.min(policy.maxDelayMs, policy.initialDelayMs * 2 ** (attempts - 1));
2543
+ const wait = outcome.kind === "http" && outcome.retryAfter !== void 0 ? Math.min(outcome.retryAfter, policy.maxDelayMs) : Math.random() * ceiling;
2544
+ if (Date.now() - started + wait >= policy.maxElapsedMs) break;
2545
+ await sleep(wait);
2546
+ }
2547
+ return { ok: false, attempts, ...lastStatus !== void 0 ? { status: lastStatus } : {}, spans, bytes, error: lastError };
2548
+ } catch (err) {
2549
+ return { ok: false, attempts: 0, spans: 0, bytes: 0, error: err instanceof Error ? err.message : String(err) };
2550
+ }
2551
+ }
2552
+ };
2553
+ }
2554
+
2555
+ // src/utils/otlp/context.ts
2556
+ var TRACEPARENT = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})(-.*)?$/;
2557
+ var ALL_ZERO_TRACE = /^0{32}$/;
2558
+ var ALL_ZERO_SPAN = /^0{16}$/;
2559
+ var MAX_TRACESTATE = 512;
2560
+ function parseTraceparent(header) {
2561
+ if (typeof header !== "string") return void 0;
2562
+ const match = TRACEPARENT.exec(header.trim());
2563
+ if (!match) return void 0;
2564
+ const [, version, traceId, spanId, flagsHex, rest] = match;
2565
+ if (version === "ff") return void 0;
2566
+ if (version === "00" && rest) return void 0;
2567
+ if (ALL_ZERO_TRACE.test(traceId) || ALL_ZERO_SPAN.test(spanId)) return void 0;
2568
+ const flags = parseInt(flagsHex, 16);
2569
+ return { traceId, spanId, flags, sampled: (flags & 1) === 1 };
2570
+ }
2571
+ function formatTraceparent(parts) {
2572
+ const flags = typeof parts.flags === "number" ? parts.flags & 255 : parts.sampled === false ? 0 : 1;
2573
+ return `00-${parts.traceId}-${parts.spanId}-${flags.toString(16).padStart(2, "0")}`;
2574
+ }
2575
+ function traceparentOf(ctx) {
2576
+ if (!ctx?.traceId || !ctx.traceSpanId) return void 0;
2577
+ return formatTraceparent({ traceId: ctx.traceId, spanId: ctx.traceSpanId, flags: ctx.traceFlags ?? 1 });
2578
+ }
2579
+ function cleanTraceState(value) {
2580
+ if (typeof value !== "string") return void 0;
2581
+ const trimmed = value.trim();
2582
+ if (!trimmed || trimmed.length > MAX_TRACESTATE || !/^[\x20-\x7e]+$/.test(trimmed)) return void 0;
2583
+ return trimmed;
2584
+ }
2585
+ function resolveTraceParent(input) {
2586
+ if (input === void 0 || input === null) return void 0;
2587
+ const header = typeof input === "string" ? input : input?.traceparent;
2588
+ const parsed = parseTraceparent(header);
2589
+ if (!parsed) {
2590
+ warnOnce("[agent-sdk] Ignoring an invalid W3C traceparent; the trace starts a new root.");
2591
+ return void 0;
2592
+ }
2593
+ const traceState = typeof input === "object" ? cleanTraceState(input.tracestate) : void 0;
2594
+ return {
2595
+ traceId: parsed.traceId,
2596
+ spanId: parsed.spanId,
2597
+ flags: parsed.flags,
2598
+ sampled: parsed.sampled,
2599
+ remote: true,
2600
+ ...traceState ? { traceState } : {}
2601
+ };
2602
+ }
2603
+ function persistedParentOf(parent) {
2604
+ if (!parent) return void 0;
2605
+ return { spanId: parent.spanId, flags: parent.flags, ...parent.traceState ? { traceState: parent.traceState } : {} };
2606
+ }
2607
+ function readPersistedParent(value) {
2608
+ if (!value || typeof value !== "object") return void 0;
2609
+ const raw = value;
2610
+ if (typeof raw.spanId !== "string" || !/^[0-9a-f]{16}$/.test(raw.spanId) || ALL_ZERO_SPAN.test(raw.spanId)) return void 0;
2611
+ const flags = Number(raw.flags);
2612
+ if (!Number.isInteger(flags) || flags < 0 || flags > 255) return void 0;
2613
+ const traceState = cleanTraceState(raw.traceState);
2614
+ return { spanId: raw.spanId, flags, ...traceState ? { traceState } : {} };
2615
+ }
2616
+ function restoreParent(persisted, traceId) {
2617
+ return {
2618
+ traceId,
2619
+ spanId: persisted.spanId,
2620
+ flags: persisted.flags,
2621
+ sampled: (persisted.flags & 1) === 1,
2622
+ remote: true,
2623
+ ...persisted.traceState ? { traceState: persisted.traceState } : {}
2624
+ };
2625
+ }
2626
+
2627
+ // src/utils/tracing.ts
1237
2628
  var DEFAULT_COGNIPEER_URL = "https://console.cognipeer.com/api/client/v1/tracing/sessions";
1238
2629
  function fileSink(path2) {
1239
2630
  return { type: "file", path: path2 };
@@ -1259,8 +2650,9 @@ function cognipeerSink(first, second) {
1259
2650
  function httpSink(url, headers) {
1260
2651
  return { type: "http", url, headers };
1261
2652
  }
1262
- function otlpSink(endpoint, headers) {
1263
- return { type: "otlp", endpoint, headers };
2653
+ function otlpSink(first, headers, options) {
2654
+ if (first !== null && typeof first === "object") return { type: "otlp", ...first };
2655
+ return { type: "otlp", endpoint: first, headers, ...options ?? {} };
1264
2656
  }
1265
2657
  function resolveLogsBaseDir(customPath, ensureDirectory = true) {
1266
2658
  const root = process.cwd();
@@ -1333,23 +2725,23 @@ function extractMetadata(model, paths) {
1333
2725
  if (!model) return void 0;
1334
2726
  for (const path2 of paths) {
1335
2727
  const value = getNestedValue2(model, path2);
1336
- const str = coerceToString(value);
1337
- if (str) return str;
2728
+ const str2 = coerceToString(value);
2729
+ if (str2) return str2;
1338
2730
  }
1339
2731
  const maybeLc = model?._lc;
1340
2732
  if (maybeLc) {
1341
2733
  for (const path2 of paths) {
1342
2734
  const value = getNestedValue2(maybeLc, path2);
1343
- const str = coerceToString(value);
1344
- if (str) return str;
2735
+ const str2 = coerceToString(value);
2736
+ if (str2) return str2;
1345
2737
  }
1346
2738
  }
1347
2739
  const maybeClient = model?.client || model?.api || model?.service;
1348
2740
  if (maybeClient) {
1349
2741
  for (const path2 of paths) {
1350
2742
  const value = getNestedValue2(maybeClient, path2);
1351
- const str = coerceToString(value);
1352
- if (str) return str;
2743
+ const str2 = coerceToString(value);
2744
+ if (str2) return str2;
1353
2745
  }
1354
2746
  }
1355
2747
  const constructorName = model?.constructor?.name;
@@ -1380,8 +2772,8 @@ function inferModelFromMessages(messageList) {
1380
2772
  if (!message) continue;
1381
2773
  for (const path2 of messagePaths) {
1382
2774
  const value = getNestedValue2(message, path2);
1383
- const str = coerceToString(value);
1384
- if (str) return str;
2775
+ const str2 = coerceToString(value);
2776
+ if (str2) return str2;
1385
2777
  }
1386
2778
  }
1387
2779
  return void 0;
@@ -1399,8 +2791,8 @@ function inferProviderFromMessages(messageList) {
1399
2791
  if (!message) continue;
1400
2792
  for (const path2 of messagePaths) {
1401
2793
  const value = getNestedValue2(message, path2);
1402
- const str = coerceToString(value);
1403
- if (str) return str;
2794
+ const str2 = coerceToString(value);
2795
+ if (str2) return str2;
1404
2796
  }
1405
2797
  }
1406
2798
  return void 0;
@@ -1462,12 +2854,18 @@ function resolveSink(sink) {
1462
2854
  return headers ? { type: "http", url, headers } : { type: "http", url };
1463
2855
  }
1464
2856
  case "otlp": {
1465
- const endpoint = typeof candidate.endpoint === "string" ? candidate.endpoint.trim() : "";
1466
- if (!endpoint) {
2857
+ const given = candidate.endpoint;
2858
+ if (given !== void 0 && (typeof given !== "string" || given.trim().length === 0)) {
2859
+ throw new Error("otlp sink requires a non-empty endpoint");
2860
+ }
2861
+ let exporter;
2862
+ try {
2863
+ exporter = createOtlpExporter({ ...candidate, endpoint: given?.trim() });
2864
+ } catch {
1467
2865
  throw new Error("otlp sink requires a non-empty endpoint");
1468
2866
  }
1469
2867
  const headers = candidate.headers ? { ...candidate.headers } : void 0;
1470
- return headers ? { type: "otlp", endpoint, headers } : { type: "otlp", endpoint };
2868
+ return headers ? { type: "otlp", endpoint: exporter.endpoint, headers, exporter } : { type: "otlp", endpoint: exporter.endpoint, exporter };
1471
2869
  }
1472
2870
  default: {
1473
2871
  if (typeof console !== "undefined" && typeof console.warn === "function") {
@@ -1477,6 +2875,17 @@ function resolveSink(sink) {
1477
2875
  }
1478
2876
  }
1479
2877
  }
2878
+ function withoutUserinfo(endpoint) {
2879
+ try {
2880
+ const url = new URL(endpoint);
2881
+ if (!url.username && !url.password) return endpoint;
2882
+ url.username = "";
2883
+ url.password = "";
2884
+ return url.toString();
2885
+ } catch {
2886
+ return endpoint;
2887
+ }
2888
+ }
1480
2889
  function snapshotSink(runtime) {
1481
2890
  const sink = runtime.resolvedConfig.sink;
1482
2891
  switch (sink.type) {
@@ -1489,7 +2898,7 @@ function snapshotSink(runtime) {
1489
2898
  case "http":
1490
2899
  return { type: "http", url: sink.url };
1491
2900
  case "otlp":
1492
- return { type: "otlp", endpoint: sink.endpoint };
2901
+ return { type: "otlp", endpoint: withoutUserinfo(sink.endpoint) };
1493
2902
  default:
1494
2903
  return { type: "custom" };
1495
2904
  }
@@ -1507,11 +2916,11 @@ var TRACE_HTTP_RETRYABLE_STATUS = /* @__PURE__ */ new Set([404, 408, 425, 429, 5
1507
2916
  var TRACE_HTTP_RETRY_BASE_MS = 250;
1508
2917
  var TRACE_HTTP_RETRY_MAX_MS = 4e3;
1509
2918
  var RetryableHttpError = class extends Error {
1510
- constructor(status, message, retryAfterMs) {
2919
+ constructor(status, message, retryAfterMs2) {
1511
2920
  super(message);
1512
2921
  this.name = "RetryableHttpError";
1513
2922
  this.status = status;
1514
- this.retryAfterMs = retryAfterMs;
2923
+ this.retryAfterMs = retryAfterMs2;
1515
2924
  }
1516
2925
  };
1517
2926
  function traceSleep(ms) {
@@ -1604,206 +3013,23 @@ async function postStreamingSessionEnd(baseUrl, headers, payload) {
1604
3013
  const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/end`;
1605
3014
  await postJsonReliable(url, headers, payload, { retry: true });
1606
3015
  }
1607
- function isoToUnixNano(iso) {
1608
- const ms = new Date(iso).getTime();
1609
- return `${ms}000000`;
1610
- }
1611
- function toOtlpStatusCode(status) {
1612
- if (status === "error") return 2;
1613
- if (status === "success" || status === "completed") return 1;
1614
- return 0;
1615
- }
1616
- function toOtlpSpanKind(type) {
1617
- switch (type) {
1618
- case "ai_call":
1619
- case "summarization":
1620
- return 3;
1621
- // CLIENT — outgoing LLM request (the summarizer is one too)
1622
- case "tool_call":
1623
- return 1;
1624
- // INTERNAL
1625
- case "agent_iteration":
1626
- return 1;
1627
- // INTERNAL
1628
- default:
1629
- return 1;
1630
- }
1631
- }
1632
- function stringAttr(key, val) {
1633
- return val != null ? { key, value: { stringValue: val } } : null;
1634
- }
1635
- function intAttr(key, val) {
1636
- return val != null && !Number.isNaN(val) ? { key, value: { intValue: String(val) } } : null;
1637
- }
1638
- function doubleAttr(key, val) {
1639
- return val != null && !Number.isNaN(val) ? { key, value: { doubleValue: val } } : null;
1640
- }
1641
- function eventToOtlpSpan(event) {
1642
- const startNano = isoToUnixNano(event.timestamp);
1643
- const endNano = event.durationMs != null ? `${new Date(new Date(event.timestamp).getTime() + event.durationMs).getTime()}000000` : startNano;
1644
- const attrs = [
1645
- stringAttr("cognipeer.event.type", event.type),
1646
- stringAttr("cognipeer.event.label", event.label),
1647
- intAttr("cognipeer.event.sequence", event.sequence),
1648
- stringAttr("cognipeer.actor.scope", event.actor?.scope),
1649
- stringAttr("cognipeer.actor.name", event.actor?.name),
1650
- stringAttr("cognipeer.actor.role", event.actor?.role),
1651
- stringAttr("cognipeer.model", event.model),
1652
- intAttr("cognipeer.tokens.reasoning", event.reasoningTokens),
1653
- stringAttr("cognipeer.finish_reason", event.finishReason),
1654
- stringAttr("cognipeer.provider", event.provider),
1655
- stringAttr("cognipeer.tool.details", event.toolDetails ? JSON.stringify(event.toolDetails) : void 0),
1656
- intAttr("cognipeer.tokens.input", event.inputTokens),
1657
- intAttr("cognipeer.tokens.output", event.outputTokens),
1658
- intAttr("cognipeer.tokens.total", event.totalTokens),
1659
- intAttr("cognipeer.tokens.cached_input", event.cachedInputTokens),
1660
- intAttr("cognipeer.bytes.request", event.requestBytes),
1661
- intAttr("cognipeer.bytes.response", event.responseBytes),
1662
- stringAttr("cognipeer.tool.execution_id", event.toolExecutionId),
1663
- stringAttr("cognipeer.retry_of", event.retryOf),
1664
- stringAttr("cognipeer.event.id", event.id)
1665
- ].filter(Boolean);
1666
- if (event.data?.sections && event.data.sections.length > 0) {
1667
- try {
1668
- attrs.push({ key: "cognipeer.sections", value: { stringValue: JSON.stringify(event.data.sections) } });
1669
- } catch {
1670
- }
1671
- }
1672
- const span = {
1673
- traceId: event.traceId,
1674
- spanId: event.spanId,
1675
- parentSpanId: event.parentSpanId || "",
1676
- name: event.label || event.type,
1677
- kind: toOtlpSpanKind(event.type),
1678
- startTimeUnixNano: startNano,
1679
- endTimeUnixNano: endNano,
1680
- attributes: attrs,
1681
- status: {
1682
- code: toOtlpStatusCode(event.status),
1683
- ...event.status === "error" && event.error?.message ? { message: event.error.message } : {}
1684
- }
1685
- };
1686
- if (event.error) {
1687
- span.events = [{
1688
- timeUnixNano: startNano,
1689
- name: "exception",
1690
- attributes: [
1691
- { key: "exception.message", value: { stringValue: event.error.message } },
1692
- ...event.error.stack ? [{ key: "exception.stacktrace", value: { stringValue: event.error.stack } }] : []
1693
- ]
1694
- }];
1695
- }
1696
- return span;
1697
- }
1698
- function traceSessionToOtlp(session) {
1699
- const traceId = session.traceId || generateTraceId();
1700
- const rootSpanId = session.rootSpanId || generateSpanId();
1701
- const startNano = isoToUnixNano(session.startedAt);
1702
- const endNano = session.endedAt ? isoToUnixNano(session.endedAt) : startNano;
1703
- const resourceAttrs = [
1704
- { key: "service.name", value: { stringValue: session.agent?.name || "cognipeer-agent" } },
1705
- stringAttr("service.version", session.agent?.version),
1706
- stringAttr("cognipeer.session.id", session.sessionId),
1707
- stringAttr("cognipeer.thread.id", session.threadId),
1708
- stringAttr("cognipeer.agent.model", session.agent?.model),
1709
- stringAttr("cognipeer.agent.provider", session.agent?.provider),
1710
- ...Object.entries(session.metadata || {}).map(([key, value]) => stringAttr(`cognipeer.metadata.${key}`, value))
1711
- ].filter(Boolean);
1712
- const rootAttrs = [
1713
- stringAttr("cognipeer.session.status", session.status),
1714
- doubleAttr("cognipeer.session.duration_ms", session.durationMs),
1715
- intAttr("cognipeer.session.total_input_tokens", session.summary.totalInputTokens),
1716
- intAttr("cognipeer.session.total_output_tokens", session.summary.totalOutputTokens),
1717
- intAttr("cognipeer.session.total_cached_input_tokens", session.summary.totalCachedInputTokens),
1718
- intAttr("cognipeer.session.total_bytes_in", session.summary.totalBytesIn),
1719
- intAttr("cognipeer.session.total_bytes_out", session.summary.totalBytesOut),
1720
- intAttr("cognipeer.session.event_count", session.events.length)
1721
- ].filter(Boolean);
1722
- if (session.summary.eventCounts) {
1723
- for (const [key, count] of Object.entries(session.summary.eventCounts)) {
1724
- rootAttrs.push({ key: `cognipeer.session.event_count.${key}`, value: { intValue: String(count) } });
1725
- }
1726
- }
1727
- const rootSpan = {
1728
- traceId,
1729
- spanId: rootSpanId,
1730
- parentSpanId: "",
1731
- name: `agent_session: ${session.agent?.name || "agent"}`,
1732
- kind: 1,
1733
- // INTERNAL
1734
- startTimeUnixNano: startNano,
1735
- endTimeUnixNano: endNano,
1736
- attributes: rootAttrs,
1737
- status: {
1738
- code: toOtlpStatusCode(session.status),
1739
- ...session.status === "error" && session.errors.length > 0 ? { message: session.errors.map((e) => e.message).join("; ") } : {}
1740
- }
1741
- };
1742
- if (session.errors.length > 0) {
1743
- rootSpan.events = session.errors.map((err) => ({
1744
- timeUnixNano: err.timestamp ? isoToUnixNano(err.timestamp) : startNano,
1745
- name: "exception",
1746
- attributes: [
1747
- { key: "exception.message", value: { stringValue: err.message } },
1748
- ...err.stack ? [{ key: "exception.stacktrace", value: { stringValue: err.stack } }] : [],
1749
- ...err.type ? [{ key: "exception.type", value: { stringValue: err.type } }] : []
1750
- ]
1751
- }));
1752
- }
1753
- const childSpans = session.events.map((event) => {
1754
- const span = eventToOtlpSpan({
1755
- ...event,
1756
- traceId: event.traceId || traceId,
1757
- spanId: event.spanId || generateSpanId(),
1758
- parentSpanId: event.parentSpanId || rootSpanId
1759
- });
1760
- return span;
3016
+ function traceSessionToOtlp(session, options = {}) {
3017
+ return sessionToOtlp(session, {
3018
+ semconv: "both",
3019
+ terminal: session.status !== "paused" && session.status !== "in_progress",
3020
+ ...options,
3021
+ content: resolveContentOptions(options.content)
1761
3022
  });
1762
- return {
1763
- resourceSpans: [{
1764
- resource: { attributes: resourceAttrs },
1765
- scopeSpans: [{
1766
- scope: {
1767
- name: "cognipeer-agent-sdk",
1768
- version: "1.0.0"
1769
- },
1770
- spans: [rootSpan, ...childSpans]
1771
- }]
1772
- }]
1773
- };
1774
3023
  }
1775
- async function postOtlpTraces(endpoint, headers, payload) {
1776
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1777
- if (!fetchFn) {
1778
- throw new Error("OTLP sink requires fetch to be available in this runtime.");
1779
- }
1780
- const finalHeaders = {
1781
- "content-type": "application/json",
1782
- ...headers || {}
3024
+ function traceErrorOf(err) {
3025
+ const e = err;
3026
+ const message = typeof e?.message === "string" && e.message ? e.message : String(err);
3027
+ const type = err instanceof Error && typeof err.name === "string" && err.name ? err.name : void 0;
3028
+ return {
3029
+ message,
3030
+ ...typeof e?.stack === "string" ? { stack: e.stack } : {},
3031
+ ...type ? { type } : {}
1783
3032
  };
1784
- try {
1785
- const response = await fetchFn(endpoint, {
1786
- method: "POST",
1787
- headers: finalHeaders,
1788
- body: JSON.stringify(payload)
1789
- });
1790
- if (!response.ok) {
1791
- let responseText = "";
1792
- try {
1793
- responseText = await response.text();
1794
- } catch {
1795
- }
1796
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1797
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1798
- throw new Error(`${statusLine}${bodyPreview}`);
1799
- }
1800
- } catch (err) {
1801
- const errMsg = err instanceof Error ? err.message : String(err);
1802
- if (typeof console !== "undefined" && typeof console.error === "function") {
1803
- console.error("[Tracing] OTLP export failed:", errMsg);
1804
- }
1805
- throw err;
1806
- }
1807
3033
  }
1808
3034
  function createEmptySummary() {
1809
3035
  return {
@@ -1823,10 +3049,16 @@ function generateEventId(sequence) {
1823
3049
  return `evt_${String(sequence).padStart(4, "0")}_${nanoid.nanoid(4)}`;
1824
3050
  }
1825
3051
  function generateTraceId() {
1826
- return crypto__default.default.randomBytes(16).toString("hex");
3052
+ for (; ; ) {
3053
+ const id = crypto__default.default.randomBytes(16).toString("hex");
3054
+ if (/[1-9a-f]/.test(id)) return id;
3055
+ }
1827
3056
  }
1828
3057
  function generateSpanId() {
1829
- return crypto__default.default.randomBytes(8).toString("hex");
3058
+ for (; ; ) {
3059
+ const id = crypto__default.default.randomBytes(8).toString("hex");
3060
+ if (/[1-9a-f]/.test(id)) return id;
3061
+ }
1830
3062
  }
1831
3063
  function defaultEventLabel(type) {
1832
3064
  switch (type) {
@@ -2103,9 +3335,64 @@ function readTraceContinuation(value) {
2103
3335
  nextSequence,
2104
3336
  part,
2105
3337
  summary,
2106
- errors: Array.isArray(raw.errors) ? raw.errors : []
3338
+ errors: Array.isArray(raw.errors) ? raw.errors : [],
3339
+ ...(() => {
3340
+ const parent = readPersistedParent(raw.parent);
3341
+ return parent ? { parent } : {};
3342
+ })(),
3343
+ ...(() => {
3344
+ const pendingSpans = readPendingSpans(raw.pendingSpans);
3345
+ return pendingSpans.length > 0 ? { pendingSpans } : {};
3346
+ })()
3347
+ };
3348
+ }
3349
+ var MAX_CARRIED_SPANS = 64;
3350
+ var isSubagentSpanRecord = (event) => event.type === "span" && event.actor?.role === "subagent";
3351
+ function carriedSpanOf(record) {
3352
+ const identity2 = (record.data?.sections ?? []).filter(
3353
+ (section) => section.kind === "metadata" && section.identity === true
3354
+ );
3355
+ return {
3356
+ sessionId: record.sessionId,
3357
+ traceId: record.traceId,
3358
+ spanId: record.spanId,
3359
+ parentSpanId: record.parentSpanId,
3360
+ id: record.id,
3361
+ type: record.type,
3362
+ label: record.label,
3363
+ sequence: record.sequence,
3364
+ timestamp: record.timestamp,
3365
+ actor: record.actor,
3366
+ status: record.status,
3367
+ durationMs: record.durationMs,
3368
+ ...identity2.length > 0 ? { data: { sections: identity2 } } : {}
2107
3369
  };
2108
3370
  }
3371
+ function readPendingSpans(value) {
3372
+ if (!Array.isArray(value)) return [];
3373
+ const out = [];
3374
+ for (const item of value.slice(0, MAX_CARRIED_SPANS)) {
3375
+ if (!item || typeof item !== "object") continue;
3376
+ const raw = item;
3377
+ if (typeof raw.spanId !== "string" || raw.spanId.length === 0) continue;
3378
+ if (raw.status !== "pending" || !isSubagentSpanRecord(raw)) continue;
3379
+ if (typeof raw.sequence !== "number" || !Number.isInteger(raw.sequence) || raw.sequence < 1) continue;
3380
+ if (typeof raw.timestamp !== "string" || Number.isNaN(Date.parse(raw.timestamp))) continue;
3381
+ if (typeof raw.label !== "string" || typeof raw.id !== "string" || typeof raw.sessionId !== "string") continue;
3382
+ if (raw.parentSpanId !== void 0 && typeof raw.parentSpanId !== "string") continue;
3383
+ if (raw.durationMs !== void 0 && (typeof raw.durationMs !== "number" || !Number.isFinite(raw.durationMs))) continue;
3384
+ out.push(carriedSpanOf(raw));
3385
+ }
3386
+ return out;
3387
+ }
3388
+ function pendingSpansOf(session) {
3389
+ const candidates = [
3390
+ ...session.carriedSpans ?? [],
3391
+ ...session.events.filter(isSubagentSpanRecord)
3392
+ ];
3393
+ if (candidates.length === 0) return [];
3394
+ return foldSupersededSpans(candidates).filter((event) => event.status === "pending").slice(-MAX_CARRIED_SPANS).map(carriedSpanOf);
3395
+ }
2109
3396
  function traceContinuationOf(session) {
2110
3397
  return {
2111
3398
  v: 1,
@@ -2119,15 +3406,32 @@ function traceContinuationOf(session) {
2119
3406
  summary: JSON.parse(JSON.stringify(session.summary)),
2120
3407
  // Sink failures belong to the part that hit them; carrying them on would
2121
3408
  // mark every later part `partial`.
2122
- errors: session.errors.filter((error) => error.type !== "sink")
3409
+ errors: session.errors.filter((error) => error.type !== "sink"),
3410
+ // Where the root hangs, so the leg that ends the run exports it under the same remote parent.
3411
+ ...session.parent ? { parent: persistedParentOf(session.parent) } : {},
3412
+ ...(() => {
3413
+ const pendingSpans = pendingSpansOf(session);
3414
+ return pendingSpans.length > 0 ? { pendingSpans } : {};
3415
+ })()
2123
3416
  };
2124
3417
  }
2125
- function createTraceSession(opts, continuation) {
3418
+ function createTraceSession(opts, continuation, extras) {
2126
3419
  const cfg = withDefaults(opts.tracing);
2127
3420
  if (!cfg.enabled) return void 0;
3421
+ let parent;
3422
+ if (continuation) {
3423
+ if (continuation.parent && continuation.traceId) parent = restoreParent(continuation.parent, continuation.traceId);
3424
+ } else {
3425
+ parent = resolveTraceParent(extras?.traceParent ?? opts.tracing?.parent);
3426
+ }
3427
+ const exporters = [...extras?.exporters ?? []];
3428
+ const contentExporters = [
3429
+ ...cfg.sink.type === "otlp" ? [cfg.sink.exporter] : [],
3430
+ ...exporters
3431
+ ].filter((exporter) => exporter.wantsContent);
2128
3432
  const providedSessionId = opts.tracing?.sessionId?.trim();
2129
3433
  const sessionId = continuation?.sessionId || providedSessionId || generateSessionId();
2130
- const traceId = continuation?.traceId || generateTraceId();
3434
+ const traceId = continuation?.traceId || parent?.traceId || generateTraceId();
2131
3435
  const rootSpanId = continuation?.rootSpanId || generateSpanId();
2132
3436
  const runtime = {
2133
3437
  sessionId,
@@ -2146,7 +3450,20 @@ function createTraceSession(opts, continuation) {
2146
3450
  // again would reset a streaming receiver's copy.
2147
3451
  sessionStarted: Boolean(continuation),
2148
3452
  sequenceOffset: continuation ? continuation.nextSequence - 1 : 0,
2149
- part: continuation ? continuation.part + 1 : 1
3453
+ part: continuation ? continuation.part + 1 : 1,
3454
+ ...continuation?.pendingSpans?.length ? { carriedSpans: continuation.pendingSpans } : {},
3455
+ ...exporters.length ? { exporters } : {},
3456
+ exportReports: [],
3457
+ ...parent ? { parent } : {},
3458
+ ...contentExporters.length > 0 ? {
3459
+ captureContent: true,
3460
+ captureLimits: {
3461
+ // Headroom over the export cap: a redact hook runs before the cap and must see a
3462
+ // secret whole, even one that straddles the point where the export cuts.
3463
+ maxStringChars: 4 * Math.max(...contentExporters.map((exporter) => exporter.contentOptions?.maxStringChars ?? 4096)),
3464
+ maxMessages: Math.max(...contentExporters.map((exporter) => exporter.contentOptions?.maxMessages ?? 32))
3465
+ }
3466
+ } : {}
2150
3467
  };
2151
3468
  if (cfg.sink.type === "file") {
2152
3469
  const baseDir = cfg.sink.baseDir;
@@ -2262,8 +3579,15 @@ function recordTraceEvent(session, event) {
2262
3579
  }
2263
3580
  }
2264
3581
  }
3582
+ if (!session.resolvedConfig.logData && event.sections?.length) {
3583
+ const identity2 = event.sections.filter((section) => section.kind === "metadata" && section.identity === true);
3584
+ if (identity2.length > 0) sections = ensureUniqueSections(id, identity2);
3585
+ }
2265
3586
  if (event.alwaysSections?.length) {
2266
- sections = ensureUniqueSections(id, [...event.alwaysSections, ...sections ?? []]);
3587
+ const identity2 = event.alwaysSections.map(
3588
+ (section) => section.kind === "metadata" ? { ...section, identity: true } : section
3589
+ );
3590
+ sections = ensureUniqueSections(id, [...identity2, ...sections ?? []]);
2267
3591
  }
2268
3592
  const resolvedModel = event.model ?? inferModelFromMessages(event.messageList);
2269
3593
  const resolvedProvider = event.provider ?? inferProviderFromMessages(event.messageList);
@@ -2299,6 +3623,16 @@ function recordTraceEvent(session, event) {
2299
3623
  // different facts, and a zero would erase the difference.
2300
3624
  ...reasoningTokens !== void 0 && !Number.isNaN(reasoningTokens) ? { reasoningTokens } : {},
2301
3625
  ...event.finishReason ? { finishReason: event.finishReason } : {},
3626
+ // Provider facts: absent when the provider did not say, never zero or empty.
3627
+ ...event.responseId ? { responseId: event.responseId } : {},
3628
+ ...event.responseModel ? { responseModel: event.responseModel } : {},
3629
+ ...event.rawFinishReason ? { rawFinishReason: event.rawFinishReason } : {},
3630
+ ...typeof event.cacheWriteTokens === "number" && event.cacheWriteTokens > 0 ? { cacheWriteTokens: event.cacheWriteTokens } : {},
3631
+ ...event.usageBasis && (event.usageBasis.inputExcludesCache || event.usageBasis.outputExcludesReasoning) ? { usageBasis: { ...event.usageBasis } } : {},
3632
+ ...event.streaming ? { streaming: true } : {},
3633
+ ...event.outputType ? { outputType: event.outputType } : {},
3634
+ ...event.toolCallId ? { toolCallId: event.toolCallId } : {},
3635
+ ...event.skipReason ? { skipReason: event.skipReason } : {},
2302
3636
  requestBytes,
2303
3637
  responseBytes,
2304
3638
  model: resolvedModel,
@@ -2320,6 +3654,15 @@ function recordTraceEvent(session, event) {
2320
3654
  timestamp: timestampIso
2321
3655
  });
2322
3656
  }
3657
+ if (session.captureContent && event.capture) {
3658
+ try {
3659
+ attachCapturedContent(
3660
+ record,
3661
+ buildCapturedContent(event.capture, session.captureLimits ?? { maxStringChars: 4096, maxMessages: 32 })
3662
+ );
3663
+ } catch {
3664
+ }
3665
+ }
2323
3666
  session.events.push(record);
2324
3667
  const sink = session.resolvedConfig.sink;
2325
3668
  if (sink.type === "custom" && typeof sink.onEvent === "function") {
@@ -2414,6 +3757,19 @@ function recordSubagentSpan(session, span) {
2414
3757
  sections
2415
3758
  });
2416
3759
  }
3760
+ function foldSupersededSpans(events) {
3761
+ const rank = (event, index) => typeof event.sequence === "number" && Number.isFinite(event.sequence) ? event.sequence : index;
3762
+ const winner = /* @__PURE__ */ new Map();
3763
+ for (let i = 0; i < events.length; i++) {
3764
+ const id = events[i].spanId;
3765
+ if (!id) continue;
3766
+ const current = winner.get(id);
3767
+ if (current === void 0 || rank(events[i], i) >= rank(events[current], current)) winner.set(id, i);
3768
+ }
3769
+ return events.filter(
3770
+ (event, i) => !(event.spanId && (event.status === "pending" || event.status === "running") && winner.get(event.spanId) !== i)
3771
+ );
3772
+ }
2417
3773
  function recordOrDeferTraceEvent(ctx, event, options) {
2418
3774
  const session = ctx?.__traceSession;
2419
3775
  if (isTraceSessionOpen(session)) {
@@ -2424,7 +3780,8 @@ function recordOrDeferTraceEvent(ctx, event, options) {
2424
3780
  const held = Array.isArray(ctx?.[DEFERRED_TRACE_EVENTS_KEY]) ? ctx[DEFERRED_TRACE_EVENTS_KEY] : [];
2425
3781
  return {
2426
3782
  ...ctx || {},
2427
- [DEFERRED_TRACE_EVENTS_KEY]: [...held, { ...event, timestamp: event.timestamp ?? (/* @__PURE__ */ new Date()).toISOString() }]
3783
+ // `capture` (content for exporters) is never parked on ctx, which callers persist.
3784
+ [DEFERRED_TRACE_EVENTS_KEY]: [...held, { ...event, capture: void 0, timestamp: event.timestamp ?? (/* @__PURE__ */ new Date()).toISOString() }]
2428
3785
  };
2429
3786
  }
2430
3787
  function replayDeferredTraceEvents(session, deferred) {
@@ -2458,6 +3815,7 @@ async function finalizeTraceSession(session, params = {}) {
2458
3815
  message: params.error.message || "Unknown error",
2459
3816
  stack: params.error.stack,
2460
3817
  type: "session",
3818
+ ...params.error.name ? { errorName: params.error.name } : {},
2461
3819
  timestamp: endedAtIso
2462
3820
  });
2463
3821
  }
@@ -2481,24 +3839,62 @@ async function finalizeTraceSession(session, params = {}) {
2481
3839
  ...(session.part ?? 1) > 1 ? { continuation: { part: session.part, firstSequence: (session.sequenceOffset ?? 0) + 1 } } : {}
2482
3840
  });
2483
3841
  const payloadForSink = buildPayload(initialStatus);
3842
+ const carried = session.carriedSpans ?? [];
3843
+ const exportPayload = carried.length > 0 ? { ...payloadForSink, events: [...carried, ...payloadForSink.events] } : payloadForSink;
2484
3844
  let sinkFailed = false;
2485
3845
  const sink = session.resolvedConfig.sink;
2486
3846
  const isStreamingMode = session.resolvedConfig.mode === "streaming";
2487
- if (sink.type === "otlp") {
2488
- try {
2489
- const otlpPayload = traceSessionToOtlp(payloadForSink);
2490
- await postOtlpTraces(sink.endpoint, sink.headers, otlpPayload);
2491
- } catch (err) {
2492
- sinkFailed = true;
2493
- const message = err instanceof Error ? err.message : String(err);
2494
- session.errors.push({
2495
- eventId: "sink",
2496
- message,
2497
- type: "sink",
2498
- timestamp: endedAtIso
2499
- });
2500
- }
2501
- } else if (sink.type === "cognipeer" || sink.type === "http") {
3847
+ const terminal = initialStatus !== "paused" && initialStatus !== "in_progress";
3848
+ const exportTargets = [];
3849
+ if (sink.type === "otlp") exportTargets.push({ exporter: sink.exporter, isSink: true });
3850
+ if (!isSubagentTraceScope(session)) {
3851
+ for (const exporter of session.exporters ?? []) exportTargets.push({ exporter, isSink: false });
3852
+ }
3853
+ const unsampled = session.parent !== void 0 && !session.parent.sampled;
3854
+ if (exportTargets.length > 0) {
3855
+ const results = await Promise.all(
3856
+ exportTargets.map(async ({ exporter }) => {
3857
+ if (unsampled) {
3858
+ return { ok: true, skipped: true, reason: "the upstream traceparent is not sampled (sampled=0)", attempts: 0, spans: 0, bytes: 0 };
3859
+ }
3860
+ try {
3861
+ return await exporter.exportSession(exportPayload, {
3862
+ terminal,
3863
+ cancelled: params.cancelled,
3864
+ parent: session.parent
3865
+ });
3866
+ } catch (err) {
3867
+ return { ok: false, attempts: 0, spans: 0, bytes: 0, error: err instanceof Error ? err.message : String(err) };
3868
+ }
3869
+ })
3870
+ );
3871
+ results.forEach((result, index) => {
3872
+ const { exporter, isSink } = exportTargets[index];
3873
+ (session.exportReports ?? (session.exportReports = [])).push({ exporter: exporter.name, endpoint: exporter.endpoint, sink: isSink, terminal, result });
3874
+ if (result.ok) {
3875
+ const rejected = result.partialSuccess?.rejectedSpans ?? 0;
3876
+ if ((rejected > 0 || result.partialSuccess?.message) && typeof console !== "undefined" && typeof console.warn === "function") {
3877
+ const detail = result.partialSuccess?.message ? `: ${result.partialSuccess.message}` : "";
3878
+ console.warn(`[Tracing] OTLP exporter "${exporter.name}": the collector rejected ${rejected} span(s)${detail}`);
3879
+ }
3880
+ return;
3881
+ }
3882
+ const message = result.error ?? "OTLP export failed";
3883
+ if (isSink) {
3884
+ sinkFailed = true;
3885
+ session.errors.push({ eventId: "sink", message, type: "sink", timestamp: endedAtIso });
3886
+ if (typeof console !== "undefined" && typeof console.error === "function") {
3887
+ console.error("[Tracing] OTLP export failed:", message);
3888
+ }
3889
+ } else if (typeof console !== "undefined" && typeof console.warn === "function") {
3890
+ console.warn(`[Tracing] OTLP exporter "${exporter.name}" failed:`, message);
3891
+ }
3892
+ });
3893
+ }
3894
+ if (params.exportOnly) {
3895
+ return buildPayload(payloadForSink.status);
3896
+ }
3897
+ if (sink.type === "cognipeer" || sink.type === "http") {
2502
3898
  try {
2503
3899
  const headers = sink.type === "cognipeer" ? { Authorization: `Bearer ${sink.apiKey}` } : sink.headers;
2504
3900
  if (isStreamingMode && session.sessionStarted) {
@@ -2594,6 +3990,23 @@ async function finalizeTraceSession(session, params = {}) {
2594
3990
  }
2595
3991
  return finalPayload;
2596
3992
  }
3993
+ async function closeTraceContinuation(continuation, params = {}) {
3994
+ const parsed = readTraceContinuation(continuation);
3995
+ if (!parsed) return void 0;
3996
+ const tracing = { ...params.tracing ?? {}, enabled: true };
3997
+ const hasOtlpSink = withDefaults(tracing).sink.type === "otlp";
3998
+ if (!hasOtlpSink && !params.exporters?.length) return void 0;
3999
+ const session = createTraceSession({ tracing }, parsed, { exporters: params.exporters });
4000
+ if (!session) return void 0;
4001
+ replayDeferredTraceEvents(session, params.events);
4002
+ const status = params.status ?? "partial";
4003
+ return finalizeTraceSession(session, {
4004
+ agentRuntime: params.agentRuntime,
4005
+ status,
4006
+ error: status === "error" ? params.error ?? { message: "The run ended in an error before it could be resumed." } : null,
4007
+ exportOnly: true
4008
+ });
4009
+ }
2597
4010
  function sanitizeTracePayload(value) {
2598
4011
  if (value === void 0) return void 0;
2599
4012
  try {
@@ -2633,6 +4046,72 @@ function estimatePayloadBytes(value) {
2633
4046
  }
2634
4047
  }
2635
4048
  }
4049
+
4050
+ // src/providers/wireInfo.ts
4051
+ var WIRE_INFO = Symbol.for("cognipeer.agent-sdk.wireInfo");
4052
+ function usageBasisOf(provider) {
4053
+ switch (provider) {
4054
+ case "anthropic":
4055
+ case "bedrock":
4056
+ return { inputExcludesCache: true };
4057
+ case "vertex":
4058
+ return { outputExcludesReasoning: true };
4059
+ default:
4060
+ return void 0;
4061
+ }
4062
+ }
4063
+ function attachWireInfo(message, info) {
4064
+ const clean = {};
4065
+ if (info.provider) clean.provider = info.provider;
4066
+ if (info.responseId) clean.responseId = info.responseId;
4067
+ if (info.responseModel) clean.responseModel = info.responseModel;
4068
+ if (info.rawFinishReason) clean.rawFinishReason = info.rawFinishReason;
4069
+ if (info.streaming) clean.streaming = true;
4070
+ const basis = info.usageBasis ?? usageBasisOf(info.provider);
4071
+ if (basis) clean.usageBasis = basis;
4072
+ message[WIRE_INFO] = clean;
4073
+ return message;
4074
+ }
4075
+ function wireInfoOf(message) {
4076
+ if (!message || typeof message !== "object") return void 0;
4077
+ return message[WIRE_INFO];
4078
+ }
4079
+
4080
+ // src/utils/traceFacts.ts
4081
+ var nonEmpty2 = (value) => typeof value === "string" && value.trim().length > 0 ? value : void 0;
4082
+ var isRunId = (id) => /^(run-|lc_run)/i.test(id);
4083
+ function providerHintOf(model, response) {
4084
+ const named = getProviderName(model);
4085
+ if (named) return named;
4086
+ const fromWire = wireInfoOf(response)?.provider;
4087
+ if (fromWire) return fromWire;
4088
+ try {
4089
+ return nonEmpty2(getModelCapabilities(model).provider);
4090
+ } catch {
4091
+ return void 0;
4092
+ }
4093
+ }
4094
+ function traceResponseFacts(model, response, rawUsage, streaming) {
4095
+ const wire = wireInfoOf(response);
4096
+ const meta = response?.response_metadata ?? {};
4097
+ const message = response;
4098
+ const idCandidate = nonEmpty2(wire?.responseId) ?? nonEmpty2(meta.id) ?? nonEmpty2(message?.id);
4099
+ const responseId = idCandidate && !isRunId(idCandidate) ? idCandidate : void 0;
4100
+ const responseModel = nonEmpty2(wire?.responseModel) ?? nonEmpty2(meta.model_name) ?? nonEmpty2(meta.model) ?? nonEmpty2(meta.modelName);
4101
+ const rawFinishReason = nonEmpty2(wire?.rawFinishReason) ?? nonEmpty2(meta.stop_reason) ?? nonEmpty2(meta.finish_reason) ?? nonEmpty2(meta.finishReason);
4102
+ const cacheWriteTokens = cacheWriteTokensOf(rawUsage);
4103
+ const provider = providerHintOf(model, response);
4104
+ const isStreaming = streaming ?? wire?.streaming;
4105
+ return {
4106
+ ...provider ? { provider } : {},
4107
+ ...responseId ? { responseId } : {},
4108
+ ...responseModel ? { responseModel } : {},
4109
+ ...rawFinishReason ? { rawFinishReason } : {},
4110
+ ...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {},
4111
+ ...wire?.usageBasis ? { usageBasis: { ...wire.usageBasis } } : {},
4112
+ ...isStreaming ? { streaming: true } : {}
4113
+ };
4114
+ }
2636
4115
  function toMessageUsage(u) {
2637
4116
  return {
2638
4117
  prompt_tokens: u.inputTokens,
@@ -2655,7 +4134,12 @@ function fromNativeProvider(provider, options) {
2655
4134
  if (link.signal) request.signal = link.signal;
2656
4135
  request = await applyTransform(request);
2657
4136
  const response = await provider.complete(request);
2658
- return toBaseChatMessage(response);
4137
+ return attachWireInfo(toBaseChatMessage(response), {
4138
+ provider: provider.providerName,
4139
+ responseId: response.id,
4140
+ responseModel: response.model,
4141
+ rawFinishReason: response.rawFinishReason
4142
+ });
2659
4143
  } finally {
2660
4144
  link.dispose();
2661
4145
  }
@@ -2674,6 +4158,8 @@ function fromNativeProvider(provider, options) {
2674
4158
  let reasoningText = "";
2675
4159
  let finishReason;
2676
4160
  let responseModel;
4161
+ let responseId;
4162
+ let rawFinishReason;
2677
4163
  const toolCallBuffers = /* @__PURE__ */ new Map();
2678
4164
  for await (const chunk of provider.completeStream(request)) {
2679
4165
  if (chunk.delta.content) {
@@ -2681,6 +4167,8 @@ function fromNativeProvider(provider, options) {
2681
4167
  yield chunk.delta.content;
2682
4168
  }
2683
4169
  if (chunk.model) responseModel = chunk.model;
4170
+ if (chunk.id) responseId = chunk.id;
4171
+ if (chunk.rawFinishReason) rawFinishReason = chunk.rawFinishReason;
2684
4172
  if (chunk.finishReason) finishReason = chunk.finishReason;
2685
4173
  if (chunk.delta.reasoning?.blocks?.length) {
2686
4174
  reasoningBlocks = chunk.delta.reasoning.blocks;
@@ -2702,7 +4190,8 @@ function fromNativeProvider(provider, options) {
2702
4190
  id: tc.id,
2703
4191
  name: tc.name ?? "",
2704
4192
  arguments: tc.arguments ?? "",
2705
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4193
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4194
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
2706
4195
  });
2707
4196
  }
2708
4197
  }
@@ -2726,7 +4215,13 @@ function fromNativeProvider(provider, options) {
2726
4215
  ...responseModel ? { model_name: responseModel } : {}
2727
4216
  };
2728
4217
  }
2729
- yield finalMessage;
4218
+ yield attachWireInfo(finalMessage, {
4219
+ provider: provider.providerName,
4220
+ responseId,
4221
+ responseModel,
4222
+ rawFinishReason,
4223
+ streaming: true
4224
+ });
2730
4225
  } finally {
2731
4226
  link.dispose();
2732
4227
  }
@@ -3100,7 +4595,8 @@ function toBaseChatMessage(response) {
3100
4595
  id: tc.id,
3101
4596
  type: "function",
3102
4597
  function: { name: tc.name, arguments: tc.arguments },
3103
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4598
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4599
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
3104
4600
  }));
3105
4601
  }
3106
4602
  if (response.reasoning && (response.reasoning.blocks?.length || response.reasoning.summary)) {
@@ -3122,7 +4618,8 @@ function assembleMessage(content, toolCalls, usage) {
3122
4618
  id: tc.id,
3123
4619
  type: "function",
3124
4620
  function: { name: tc.name, arguments: tc.arguments },
3125
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4621
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4622
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
3126
4623
  }));
3127
4624
  }
3128
4625
  return msg;
@@ -4016,7 +5513,7 @@ var CCRStore = class _CCRStore {
4016
5513
  }
4017
5514
  static hashOf(value) {
4018
5515
  const serialized = typeof value === "string" ? value : JSON.stringify(value);
4019
- return crypto.createHash("sha1").update(serialized).digest("hex").slice(0, 16);
5516
+ return crypto.createHash("sha256").update(serialized).digest("hex").slice(0, 16);
4020
5517
  }
4021
5518
  };
4022
5519
  var DedupTracker = class {
@@ -4029,7 +5526,7 @@ var DedupTracker = class {
4029
5526
  * first time it has been seen.
4030
5527
  */
4031
5528
  checkAndRegister(content, executionId, toolName) {
4032
- const hash = crypto.createHash("sha1").update(content).digest("hex");
5529
+ const hash = crypto.createHash("sha256").update(content).digest("hex");
4033
5530
  const existing = this.seen.get(hash);
4034
5531
  if (!existing) {
4035
5532
  this.seen.set(hash, { executionId, toolName });
@@ -4566,7 +6063,7 @@ function createAgentCoreNode(opts) {
4566
6063
  const actorVersion = runtime.version ?? opts.version;
4567
6064
  let traceToolDefinitions;
4568
6065
  const computeTraceToolDefinitions = (menu) => {
4569
- if (!traceSession || !traceSession.resolvedConfig.logData || menu.length === 0) return void 0;
6066
+ if (!traceSession || !(traceSession.resolvedConfig.logData || traceSession.captureContent) || menu.length === 0) return void 0;
4570
6067
  try {
4571
6068
  const wire = shouldUseStrictToolCalling ? prepareStrictToolMenu(menu).menu : menu;
4572
6069
  return wire.map((tool) => {
@@ -4779,8 +6276,9 @@ ${append}`;
4779
6276
  // outcome, and an "error" status would flip the whole trace session
4780
6277
  // status to error for a run that behaved exactly as configured.
4781
6278
  status: "skipped",
6279
+ skipReason: "blocked",
4782
6280
  model: getModelName(runtime.model || opts.model),
4783
- provider: getProviderName(runtime.model || opts.model),
6281
+ provider: providerHintOf(runtime.model || opts.model),
4784
6282
  messageList: state.messages
4785
6283
  });
4786
6284
  return {
@@ -4809,9 +6307,12 @@ ${append}`;
4809
6307
  for (const key of ["usage", "usage_metadata", "response_metadata"]) {
4810
6308
  if (merged[key] === void 0 && original?.[key] !== void 0) merged[key] = original[key];
4811
6309
  }
6310
+ if (wireInfoOf(merged) === void 0 && wireInfoOf(original) !== void 0) merged[WIRE_INFO] = wireInfoOf(original);
4812
6311
  return merged;
4813
6312
  };
4814
6313
  let response;
6314
+ let sentMessages;
6315
+ let streamedCall = false;
4815
6316
  let modelAttempt = 0;
4816
6317
  const maxModelRetries = host?.maxModelRetries ?? 0;
4817
6318
  const finishCancelledTurn = (partialText) => {
@@ -4825,12 +6326,16 @@ ${append}`;
4825
6326
  // "skipped", not "error": the call did not fail, the caller ended it —
4826
6327
  // and an "error" would flip the whole session to error.
4827
6328
  status: "skipped",
6329
+ // The call reached the provider and was hung up on: still a model call, not a skipped one.
6330
+ skipReason: "cancelled",
6331
+ ...streamedCall ? { streaming: true } : {},
4828
6332
  durationMs: Date.now() - start,
4829
6333
  requestBytes: promptBytes,
4830
6334
  model: getModelName(runtime.model || opts.model),
4831
- provider: getProviderName(runtime.model || opts.model),
6335
+ provider: providerHintOf(runtime.model || opts.model),
4832
6336
  messageList: state.messages,
4833
- toolDefinitions: traceToolDefinitions
6337
+ toolDefinitions: traceToolDefinitions,
6338
+ capture: { input: sentMessages ?? wireMessages, toolDefinitions: traceToolDefinitions }
4834
6339
  });
4835
6340
  onEvent?.({ type: "cancelled", stage: "agent", reason });
4836
6341
  onProgress?.({ stage: "agent", message: "Cancelled", detail: { reason } });
@@ -4846,8 +6351,9 @@ ${append}`;
4846
6351
  label: "Assistant (plugin short-circuit)",
4847
6352
  actor: { scope: "agent", name: actorName, role: "assistant", version: actorVersion },
4848
6353
  status: "skipped",
6354
+ skipReason: "short_circuit",
4849
6355
  model: getModelName(runtime.model || opts.model),
4850
- provider: getProviderName(runtime.model || opts.model),
6356
+ provider: providerHintOf(runtime.model || opts.model),
4851
6357
  messageList: state.messages,
4852
6358
  toolDefinitions: traceToolDefinitions
4853
6359
  });
@@ -4855,8 +6361,10 @@ ${append}`;
4855
6361
  let streamedText = "";
4856
6362
  try {
4857
6363
  const normalizedMessages = normalizeBedrockToolPairing([...wireMessages]);
6364
+ sentMessages = normalizedMessages;
4858
6365
  debugToolPairing(normalizedMessages);
4859
6366
  if (streamingEnabled && typeof modelWithTools.stream === "function") {
6367
+ streamedCall = true;
4860
6368
  let streamedMessage;
4861
6369
  let cutByCancel = false;
4862
6370
  for await (const chunk of modelWithTools.stream(normalizedMessages, invokeParams)) {
@@ -4902,12 +6410,14 @@ ${append}`;
4902
6410
  durationMs: durationMs2,
4903
6411
  requestBytes: promptBytes,
4904
6412
  model: getModelName(runtime.model || opts.model),
4905
- provider: getProviderName(runtime.model || opts.model),
4906
- error: { message: err?.message || String(err), stack: err?.stack },
6413
+ provider: providerHintOf(runtime.model || opts.model),
6414
+ error: traceErrorOf(err),
6415
+ ...streamedCall ? { streaming: true } : {},
4907
6416
  messageList: state.messages,
4908
6417
  toolDefinitions: traceToolDefinitions,
4909
6418
  responseFormat: traceResponseFormat,
4910
- responseFormatStrategy: traceResponseFormatStrategy
6419
+ responseFormatStrategy: traceResponseFormatStrategy,
6420
+ capture: { input: sentMessages ?? wireMessages, toolDefinitions: traceToolDefinitions }
4911
6421
  });
4912
6422
  throw err;
4913
6423
  }
@@ -4960,6 +6470,8 @@ ${append}`;
4960
6470
  const responsePayload = shouldLogResponse ? sanitizeTracePayload(response) : void 0;
4961
6471
  const responseBytes = responsePayload !== void 0 ? estimatePayloadBytes(responsePayload) : void 0;
4962
6472
  const finishReason = response?.response_metadata?.finish_reason ?? response?.response_metadata?.finishReason ?? response?.finishReason;
6473
+ const facts = traceResponseFacts(runtime.model || opts.model, response, rawUsage, streamedCall);
6474
+ const jsonOutput = Boolean(responseFormat) && responseFormat?.response_format?.type !== "text" && responseFormat?.type !== "text";
4963
6475
  recordTraceEvent(traceSession, {
4964
6476
  type: "ai_call",
4965
6477
  label: "Assistant Response",
@@ -4976,11 +6488,13 @@ ${append}`;
4976
6488
  requestBytes: promptBytes,
4977
6489
  responseBytes,
4978
6490
  model: modelName,
4979
- provider: getProviderName(runtime.model || opts.model),
6491
+ ...facts,
6492
+ outputType: jsonOutput ? "json" : "text",
4980
6493
  messageList: messagesWithResponse,
4981
6494
  toolDefinitions: traceToolDefinitions,
4982
6495
  responseFormat: traceResponseFormat,
4983
- responseFormatStrategy: traceResponseFormatStrategy
6496
+ responseFormatStrategy: traceResponseFormatStrategy,
6497
+ capture: { input: sentMessages ?? wireMessages, output: response, toolDefinitions: traceToolDefinitions }
4984
6498
  });
4985
6499
  if (normalized) {
4986
6500
  recordUsage(state, modelName, normalized);
@@ -5006,6 +6520,12 @@ function sameJson(a, b) {
5006
6520
  return false;
5007
6521
  }
5008
6522
  }
6523
+ var idSection = (label, data) => ({
6524
+ kind: "metadata",
6525
+ label,
6526
+ data,
6527
+ identity: true
6528
+ });
5009
6529
  function recordApprovalRequested(session, entry) {
5010
6530
  if (!session || surfacedFromSubagent(entry) || !canPauseForHuman(session)) return;
5011
6531
  const logData = session.resolvedConfig.logData;
@@ -5031,7 +6551,7 @@ function recordApprovalRequested(session, entry) {
5031
6551
  timestamp: entry.requestedAt,
5032
6552
  status: "pending",
5033
6553
  actor: { scope: "agent", name: entry.toolName, role: "approval_request" },
5034
- sections
6554
+ sections: [...sections, idSection("Approval ids", { approvalId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt })]
5035
6555
  });
5036
6556
  }
5037
6557
  function recordHumanDecisions(session, state) {
@@ -5072,7 +6592,14 @@ function recordHumanDecisions(session, state) {
5072
6592
  durationMs: waitedMs(entry.requestedAt, entry.decidedAt),
5073
6593
  status: "success",
5074
6594
  actor: { scope: "human", name: entry.decidedBy || "reviewer", role: "approver" },
5075
- sections
6595
+ sections: [...sections, idSection("Decision ids", {
6596
+ approvalId: entry.id,
6597
+ toolCallId: entry.toolCallId,
6598
+ decision: entry.status,
6599
+ requestedAt: entry.requestedAt,
6600
+ decidedAt: entry.decidedAt,
6601
+ ...waitedMs(entry.requestedAt, entry.decidedAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.decidedAt) } : {}
6602
+ })]
5076
6603
  });
5077
6604
  entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
5078
6605
  }
@@ -5117,7 +6644,14 @@ function recordHumanDecisions(session, state) {
5117
6644
  durationMs: waitedMs(entry.requestedAt, entry.answeredAt),
5118
6645
  status: cancelled ? "skipped" : "success",
5119
6646
  actor: { scope: "human", name: entry.answeredBy || "user", role: "user" },
5120
- sections
6647
+ sections: [...sections, idSection("Answer ids", {
6648
+ questionId: entry.id,
6649
+ toolCallId: entry.toolCallId,
6650
+ status: entry.status,
6651
+ requestedAt: entry.requestedAt,
6652
+ answeredAt: entry.answeredAt,
6653
+ ...waitedMs(entry.requestedAt, entry.answeredAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.answeredAt) } : {}
6654
+ })]
5121
6655
  });
5122
6656
  entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
5123
6657
  }
@@ -5142,7 +6676,7 @@ function recordClientToolRequested(session, entry) {
5142
6676
  timestamp: entry.requestedAt,
5143
6677
  status: "pending",
5144
6678
  actor: { scope: "client", name: clientTool.name, role: "tool" },
5145
- sections
6679
+ sections: [...sections, idSection("Client tool ids", { questionId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt })]
5146
6680
  });
5147
6681
  }
5148
6682
  function readClientTool(entry) {
@@ -5189,7 +6723,14 @@ function recordClientToolResult(session, entry, clientTool, toolHistory) {
5189
6723
  durationMs: waitedMs(entry.requestedAt, entry.answeredAt) ?? ranMs,
5190
6724
  status: failed ? "error" : "success",
5191
6725
  actor: { scope: "client", name: clientTool.name, role: "tool" },
5192
- sections
6726
+ sections: [...sections, idSection("Client tool ids", {
6727
+ questionId: entry.id,
6728
+ toolCallId: entry.toolCallId,
6729
+ status: failed ? "error" : "answered",
6730
+ requestedAt: entry.requestedAt,
6731
+ answeredAt: entry.answeredAt,
6732
+ ...waitedMs(entry.requestedAt, entry.answeredAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.answeredAt) } : {}
6733
+ })]
5193
6734
  });
5194
6735
  }
5195
6736
 
@@ -5295,9 +6836,11 @@ function normalizeToolCall(call) {
5295
6836
  return {
5296
6837
  id: call.id,
5297
6838
  name,
5298
- args: call.args ?? call.arguments ?? call.input ?? call.function?.arguments ?? call.function_call?.arguments
6839
+ args: call.args ?? call.arguments ?? call.input ?? call.function?.arguments ?? call.function_call?.arguments,
6840
+ ...call.idSynthesized === true ? { idSynthesized: true } : {}
5299
6841
  };
5300
6842
  }
6843
+ var providerToolCallId = (tc) => tc.id && !tc.idSynthesized ? tc.id : void 0;
5301
6844
  function normalizeToolSchema(tool, toolName) {
5302
6845
  const schema = tool.schema;
5303
6846
  if (!schema) return void 0;
@@ -5555,6 +7098,8 @@ function createToolsNode(initialTools, opts) {
5555
7098
  label: `Tool Denied - ${toolName}`,
5556
7099
  actor: { scope: "tool", name: toolName, role: "tool" },
5557
7100
  status: "skipped",
7101
+ skipReason: "denied",
7102
+ toolCallId: providerToolCallId(tc),
5558
7103
  toolDetails,
5559
7104
  toolExecutionId: toolCallId,
5560
7105
  sections: buildToolTraceSections({
@@ -5626,6 +7171,8 @@ function createToolsNode(initialTools, opts) {
5626
7171
  label: `Tool Skipped - ${toolName}`,
5627
7172
  actor: { scope: "tool", name: toolName, role: "tool" },
5628
7173
  status: "skipped",
7174
+ skipReason: "skipped",
7175
+ toolCallId: providerToolCallId(tc),
5629
7176
  toolDetails,
5630
7177
  toolExecutionId: tc.id,
5631
7178
  sections: buildToolTraceSections({
@@ -5762,10 +7309,13 @@ function createToolsNode(initialTools, opts) {
5762
7309
  label: `Tool Error - ${toolName}`,
5763
7310
  actor: { scope: "tool", name: toolName, role: "tool" },
5764
7311
  status: "error",
7312
+ // The tool was not run: an open breaker refused the call.
7313
+ skipReason: "skipped",
7314
+ toolCallId: providerToolCallId(tc),
5765
7315
  requestBytes: inputBytes,
5766
7316
  toolDetails,
5767
7317
  toolExecutionId: toolCallId,
5768
- error: { message: breakerMsg },
7318
+ error: { message: breakerMsg, type: "circuit_breaker_open" },
5769
7319
  sections: buildToolTraceSections({
5770
7320
  args,
5771
7321
  executionId: toolCallId,
@@ -5825,6 +7375,9 @@ function createToolsNode(initialTools, opts) {
5825
7375
  type: "tool_call",
5826
7376
  label: shortCircuitSource === "plugin" ? `Tool Short-Circuited - ${toolName}` : `Tool Execution - ${toolName}`,
5827
7377
  actor: { scope: "tool", name: toolName, role: "tool" },
7378
+ // Answered from the cache or by a plugin: nothing executed.
7379
+ skipReason: "short_circuit",
7380
+ toolCallId: providerToolCallId(tc),
5828
7381
  durationMs: 0,
5829
7382
  requestBytes: inputBytes,
5830
7383
  responseBytes: outputBytes2,
@@ -5860,7 +7413,15 @@ function createToolsNode(initialTools, opts) {
5860
7413
  onProgress?.({ stage: "tools", message: `Running tool ${tc.name}` });
5861
7414
  const anyTool = tool;
5862
7415
  traceSpanId = traceSession ? generateSpanId() : void 0;
5863
- const callOptions = { cancellationToken, signal: abortSignal, toolCallId, ...traceSpanId ? { traceSpanId } : {} };
7416
+ const callOptions = {
7417
+ cancellationToken,
7418
+ signal: abortSignal,
7419
+ toolCallId,
7420
+ ...traceSpanId ? { traceSpanId } : {},
7421
+ // So the tool can propagate the trace to what it calls (traceparentOf).
7422
+ ...traceSpanId && traceSession?.traceId ? { traceId: traceSession.traceId } : {},
7423
+ ...traceSpanId && traceSession?.parent ? { traceFlags: traceSession.parent.flags } : {}
7424
+ };
5864
7425
  const invokeOnce = async () => {
5865
7426
  if (typeof anyTool.func === "function") return anyTool.func(args, callOptions);
5866
7427
  if (typeof anyTool.invoke === "function") return anyTool.invoke(args, callOptions);
@@ -6046,7 +7607,10 @@ function createToolsNode(initialTools, opts) {
6046
7607
  spanId: traceSpanId,
6047
7608
  label: `Tool Execution - ${toolName}`,
6048
7609
  actor: { scope: "tool", name: toolName, role: "tool" },
6049
- ...reportedFailure ? { status: "error", error: { message: reportedFailure } } : {},
7610
+ ...reportedFailure ? { status: "error", error: { message: reportedFailure, type: "tool_error" } } : {},
7611
+ toolCallId: providerToolCallId(tc),
7612
+ // `output` is already past postToolUse, so a redaction plugin has applied.
7613
+ capture: reportedFailure ? { toolArguments: args } : { toolArguments: args, toolResult: output, hasToolResult: true },
6050
7614
  durationMs,
6051
7615
  requestBytes: inputBytes,
6052
7616
  responseBytes: outputBytes,
@@ -6110,12 +7674,14 @@ function createToolsNode(initialTools, opts) {
6110
7674
  label: `Tool Error - ${toolName}`,
6111
7675
  actor: { scope: "tool", name: toolName, role: "tool" },
6112
7676
  status: "error",
7677
+ toolCallId: providerToolCallId(tc),
7678
+ capture: { toolArguments: args },
6113
7679
  durationMs,
6114
7680
  requestBytes: inputBytes,
6115
7681
  responseBytes: traceSession?.resolvedConfig.logData ? estimatePayloadBytes(errorOutput) : void 0,
6116
7682
  toolDetails,
6117
7683
  toolExecutionId: executionId,
6118
- error: { message, stack: host?.has("postToolUse") ? void 0 : error?.stack },
7684
+ error: { ...traceErrorOf(error), message, stack: host?.has("postToolUse") ? void 0 : error?.stack },
6119
7685
  sections: buildToolTraceSections({
6120
7686
  args: sanitizedArgs,
6121
7687
  durationMs,
@@ -6230,6 +7796,8 @@ function createToolsNode(initialTools, opts) {
6230
7796
  label: `Tool Skipped - ${tc.name}`,
6231
7797
  actor: { scope: "tool", name: tc.name, role: "tool" },
6232
7798
  status: "skipped",
7799
+ skipReason: "skipped",
7800
+ toolCallId: providerToolCallId(tc),
6233
7801
  toolDetails,
6234
7802
  toolExecutionId: tc.id,
6235
7803
  sections: buildToolTraceSections({
@@ -6396,7 +7964,7 @@ function createReflectionNode(opts, resolved) {
6396
7964
  label: "Reflection error",
6397
7965
  actor: { scope: "agent", name: opts.name || "agent", role: "reflection" },
6398
7966
  status: "error",
6399
- error: { message: err?.message || String(err) }
7967
+ error: traceErrorOf(err)
6400
7968
  });
6401
7969
  return {};
6402
7970
  }
@@ -7407,7 +8975,7 @@ function buildSubagentCatalogBlock(subagents, policy, toolNames, opts) {
7407
8975
  // src/plugins/host.ts
7408
8976
  init_content();
7409
8977
  var DEFAULT_PRIORITY = 100;
7410
- var DEFAULT_TIMEOUT_MS = 1e4;
8978
+ var DEFAULT_TIMEOUT_MS2 = 1e4;
7411
8979
  var HOOK_SPECS = {
7412
8980
  sessionStart: { kind: "gate", mutable: ["messages"], collect: ["systemPromptAppend"] },
7413
8981
  userPromptSubmit: {
@@ -7512,7 +9080,7 @@ function collectRegistrations(plugin, registrations, into, orderRef) {
7512
9080
  plugin: plugin.name,
7513
9081
  priority: plugin.priority ?? DEFAULT_PRIORITY,
7514
9082
  failureMode: plugin.failureMode ?? "open",
7515
- timeoutMs: plugin.timeoutMs ?? DEFAULT_TIMEOUT_MS,
9083
+ timeoutMs: plugin.timeoutMs ?? DEFAULT_TIMEOUT_MS2,
7516
9084
  order: orderRef.value++,
7517
9085
  handler
7518
9086
  });
@@ -7567,6 +9135,7 @@ function createPluginHost(plugins = [], options = {}) {
7567
9135
  let contributions = {
7568
9136
  tools: [],
7569
9137
  toolDescriptions: {},
9138
+ traceExporters: [],
7570
9139
  guardrails: [],
7571
9140
  applySystemPrompt: (base) => base,
7572
9141
  applyModelWrappers: (model) => model
@@ -7575,6 +9144,7 @@ function createPluginHost(plugins = [], options = {}) {
7575
9144
  async function runSetup(setupInput) {
7576
9145
  const tools = [];
7577
9146
  const toolDescriptions = {};
9147
+ const traceExporters = [];
7578
9148
  const guardrails = [];
7579
9149
  const promptSteps = [];
7580
9150
  const modelWrappers = [];
@@ -7612,6 +9182,7 @@ function createPluginHost(plugins = [], options = {}) {
7612
9182
  );
7613
9183
  }
7614
9184
  if (plugin.toolDescriptions) Object.assign(toolDescriptions, plugin.toolDescriptions);
9185
+ if (plugin.traceExporters?.length) traceExporters.push(...plugin.traceExporters.filter(Boolean));
7615
9186
  if (plugin.guardrails?.length) guardrails.push(...plugin.guardrails);
7616
9187
  if (typeof plugin.wrapModel === "function") {
7617
9188
  modelWrappers.push({ plugin: plugin.name, wrap: plugin.wrapModel });
@@ -7627,6 +9198,7 @@ function createPluginHost(plugins = [], options = {}) {
7627
9198
  contributions = {
7628
9199
  tools,
7629
9200
  toolDescriptions,
9201
+ traceExporters,
7630
9202
  guardrails,
7631
9203
  applySystemPrompt: (base) => promptSteps.reduce((current, step) => {
7632
9204
  try {
@@ -8650,7 +10222,10 @@ function createAgent(opts) {
8650
10222
  }
8651
10223
  emit({ type: "progress", ...progress });
8652
10224
  };
8653
- const traceSession = createTraceSession(opts, readTraceContinuation(input.ctx?.__traceContinuation));
10225
+ const traceSession = createTraceSession(opts, readTraceContinuation(input.ctx?.__traceContinuation), {
10226
+ exporters: pluginHost.contributions.traceExporters,
10227
+ traceParent: config?.traceParent
10228
+ });
8654
10229
  const ctx = {
8655
10230
  ...input.ctx || {},
8656
10231
  __onEvent: onEvent,
@@ -8802,7 +10377,7 @@ function createAgent(opts) {
8802
10377
  await finalizeTraceSession(traceSession, {
8803
10378
  agentRuntime: runtime,
8804
10379
  status: "error",
8805
- error: { message: err?.message, stack: err?.stack }
10380
+ error: { message: err?.message, stack: err?.stack, name: err?.name }
8806
10381
  });
8807
10382
  await endSession("error", { error: err instanceof Error ? err : new Error(String(err)), state: stateHolder.value });
8808
10383
  if (userTokenCounter) {
@@ -8823,7 +10398,10 @@ function createAgent(opts) {
8823
10398
  const midTurn = pausedForHuman || Boolean(res.ctx?.__needsSummarization);
8824
10399
  await finalizeTraceSession(traceSession, {
8825
10400
  agentRuntime: res.agent || runtime,
8826
- status: pausedForHuman ? "paused" : midTurn ? "in_progress" : "success"
10401
+ status: pausedForHuman ? "paused" : midTurn ? "in_progress" : "success",
10402
+ // The file says `success` for a cancelled run (it did not fail); the
10403
+ // exported root says `partial`, the old plugin mapping.
10404
+ cancelled: statusFor(res) === "cancelled"
8827
10405
  });
8828
10406
  if (traceSession && midTurn) {
8829
10407
  res.ctx = { ...res.ctx || {}, __traceContinuation: traceContinuationOf(traceSession) };
@@ -8968,14 +10546,16 @@ function createAgent(opts) {
8968
10546
  const startedAt = Date.now();
8969
10547
  const recordSpan = (status, extra) => {
8970
10548
  if (!traced || !isTraceSessionOpen(parentSession)) return;
10549
+ const running = status === "running";
8971
10550
  recordSubagentSpan(parentSession, {
8972
10551
  spanId: agentSpanId,
8973
- parentSpanId: context?.traceSpanId ?? parentIterationSpanId,
10552
+ // The delegating tool_call span only exists once the tool returns.
10553
+ parentSpanId: running ? parentIterationSpanId : context?.traceSpanId ?? parentIterationSpanId,
8974
10554
  name: opts.name || "agent",
8975
10555
  status,
8976
- durationMs: Date.now() - startedAt,
10556
+ durationMs: running ? void 0 : Date.now() - startedAt,
8977
10557
  error: extra.error,
8978
- info: { name: opts.name || "agent", mode: "asTool", depth: currentDepth + 1, parentToolCallId: context?.toolCallId, status: status === "success" ? "ok" : "error" },
10558
+ info: { name: opts.name || "agent", mode: "asTool", depth: currentDepth + 1, parentToolCallId: context?.toolCallId, status: running ? "running" : status === "success" ? "ok" : "error" },
8979
10559
  task: input,
8980
10560
  result: extra.result
8981
10561
  });
@@ -8995,6 +10575,7 @@ function createAgent(opts) {
8995
10575
  stream: Boolean(parentCtx.__streaming),
8996
10576
  cancellationToken: parentCtx.__cancellationToken ?? parentCtx.__abortSignal
8997
10577
  };
10578
+ recordSpan("running", {});
8998
10579
  let res;
8999
10580
  try {
9000
10581
  res = await instance.invoke({ messages: childMessages, ctx: childCtx }, childConfig);
@@ -9079,9 +10660,10 @@ function createAgentNode(opts) {
9079
10660
  durationMs: durationMs2,
9080
10661
  requestBytes: promptBytes,
9081
10662
  model: getModelName(runtime.model || opts.model),
9082
- provider: getProviderName(runtime.model || opts.model),
9083
- error: { message: err?.message || String(err), stack: err?.stack },
9084
- messageList: promptMessages
10663
+ provider: providerHintOf(runtime.model || opts.model),
10664
+ error: traceErrorOf(err),
10665
+ messageList: promptMessages,
10666
+ capture: { input: promptMessages }
9085
10667
  });
9086
10668
  throw err;
9087
10669
  }
@@ -9092,7 +10674,7 @@ function createAgentNode(opts) {
9092
10674
  const rawUsage = response?.usage || response?.usage_metadata || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage || response?.response_metadata?.usage_metadata || response?.response_metadata?.usageMetadata;
9093
10675
  const normalized = normalizeUsage(rawUsage);
9094
10676
  const modelName = getModelName(runtime.model || opts.model) || "unknown_model";
9095
- const providerName = getProviderName(runtime.model || opts.model);
10677
+ const facts = traceResponseFacts(runtime.model || opts.model, response, rawUsage);
9096
10678
  const durationMs = Date.now() - start;
9097
10679
  const shouldLogResponse = !!traceSession && traceSession.resolvedConfig.logData;
9098
10680
  const responsePayload = shouldLogResponse ? sanitizeTracePayload(response) : void 0;
@@ -9109,8 +10691,9 @@ function createAgentNode(opts) {
9109
10691
  requestBytes: promptBytes,
9110
10692
  responseBytes,
9111
10693
  model: modelName,
9112
- provider: providerName,
9113
- messageList: messagesWithResponse
10694
+ ...facts,
10695
+ messageList: messagesWithResponse,
10696
+ capture: { input: promptMessages, output: response }
9114
10697
  });
9115
10698
  if (normalized) {
9116
10699
  recordUsage(state, modelName, normalized);
@@ -9761,7 +11344,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9761
11344
  ];
9762
11345
  const inputTokensEstimate = countApproxTokens(summaryPrompt.map((m) => m.content).join("\n"));
9763
11346
  const modelName = getModelName(model);
9764
- const providerName = getProviderName(model);
11347
+ const providerName = providerHintOf(model);
9765
11348
  const tracingEnabled = Boolean(opts.tracing?.enabled);
9766
11349
  let ctxWithDeferredTrace;
9767
11350
  const traceSummarization = (event) => {
@@ -9792,6 +11375,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9792
11375
  let reasoningTokensActual;
9793
11376
  let fallback = false;
9794
11377
  let summarizerError;
11378
+ let responseFacts;
9795
11379
  const directivesSection = () => ({
9796
11380
  kind: "metadata",
9797
11381
  label: "User directives",
@@ -9833,6 +11417,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9833
11417
  summaryText = renderStructuredSummary(structuredSummary);
9834
11418
  const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
9835
11419
  const normalized = normalizeUsage(rawUsage);
11420
+ responseFacts = traceResponseFacts(model, response, rawUsage);
9836
11421
  if (normalized) {
9837
11422
  inputTokensActual = normalized.prompt_tokens;
9838
11423
  outputTokensActual = normalized.completion_tokens;
@@ -9869,7 +11454,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9869
11454
  ...droppedDirectives.length > 0 ? { droppedDirectives } : {}
9870
11455
  };
9871
11456
  onEvent?.(errorEvent);
9872
- summarizerError = { message: err?.message || String(err), stack: err?.stack };
11457
+ summarizerError = traceErrorOf(err);
9873
11458
  }
9874
11459
  const toolCallIdToAssistantIdx = /* @__PURE__ */ new Map();
9875
11460
  messages.forEach((m, idx) => {
@@ -10025,10 +11610,16 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
10025
11610
  outputTokens: outputTokensActual ?? outputTokensEstimate,
10026
11611
  cachedInputTokens,
10027
11612
  totalTokens: totalTokensActual,
10028
- ...reasoningTokensActual !== void 0 ? { reasoningTokens: reasoningTokensActual } : {}
11613
+ ...reasoningTokensActual !== void 0 ? { reasoningTokens: reasoningTokensActual } : {},
11614
+ // Which counting rules the usage above follows (only when the provider reported it).
11615
+ ...inputTokensActual !== void 0 && responseFacts?.usageBasis ? { usageBasis: responseFacts.usageBasis } : {},
11616
+ ...inputTokensActual !== void 0 && responseFacts?.cacheWriteTokens ? { cacheWriteTokens: responseFacts.cacheWriteTokens } : {}
10029
11617
  },
11618
+ ...responseFacts?.responseId ? { responseId: responseFacts.responseId } : {},
11619
+ ...responseFacts?.responseModel ? { responseModel: responseFacts.responseModel } : {},
11620
+ ...responseFacts?.rawFinishReason ? { rawFinishReason: responseFacts.rawFinishReason } : {},
10030
11621
  ...modelName ? { model: modelName } : {},
10031
- ...providerName ? { provider: providerName } : {},
11622
+ ...responseFacts?.provider ?? providerName ? { provider: responseFacts?.provider ?? providerName } : {},
10032
11623
  ...summarizerError ? { error: summarizerError } : {},
10033
11624
  sections: [
10034
11625
  ...promptAndOutputSections(),
@@ -11172,19 +12763,29 @@ async function runChild(spec, input, deps, ref, opts) {
11172
12763
  const childDepth = (Number(parentCtx.__delegationDepth) || 0) + 1;
11173
12764
  const parentSession = parentCtx.__traceSession;
11174
12765
  const traced = isTraceSessionOpen(parentSession);
11175
- const agentSpanId = generateSpanId();
12766
+ const sessionStart = traced ? parentSession.startedAt : void 0;
12767
+ const persistedId = opts.record?.agentSpanId;
12768
+ const agentSpanId = typeof persistedId === "string" && /^[0-9a-f]{16}$/.test(persistedId) ? persistedId : generateSpanId();
12769
+ const persistedStart = opts.record?.startedAt;
12770
+ const startValid = typeof persistedStart === "number" && Number.isFinite(persistedStart) && persistedStart > 0 && persistedStart <= start;
12771
+ const runStartedAt = startValid ? Math.min(start, Math.max(persistedStart, sessionStart ?? persistedStart)) : start;
12772
+ const persistedSegments = opts.record?.segments;
12773
+ const segment = (typeof persistedSegments === "number" && Number.isInteger(persistedSegments) && persistedSegments >= 1 && persistedSegments <= 1e3 ? persistedSegments : 0) + 1;
12774
+ const elapsedMs = () => Math.max(0, Date.now() - runStartedAt);
11176
12775
  const parentIterationSpanId = traced ? parentSession.currentIterationSpanId : void 0;
11177
12776
  const traceScope = traced ? createSubagentTraceScope(parentSession, { agentSpanId, name: spec.name, spawnId, mode: spec.mode, hitl: opts.allowHITL, iterations: opts.record?.iterations }) : void 0;
11178
12777
  const recordSegment = (status, info) => {
11179
12778
  if (!traced || !isTraceSessionOpen(parentSession)) return;
12779
+ const unfinished = status === "pending" || status === "running";
11180
12780
  recordSubagentSpan(parentSession, {
11181
12781
  spanId: agentSpanId,
11182
- // The tool_call span only exists once the tool returns; a paused child
11183
- // has not returned, so its span hangs off the iteration.
11184
- parentSpanId: status === "pending" ? parentIterationSpanId : opts.parentSpanId ?? parentIterationSpanId,
12782
+ // The tool_call span only exists once the tool returns; a running or
12783
+ // paused child has not returned, so its span hangs off the iteration.
12784
+ parentSpanId: unfinished ? parentIterationSpanId : opts.parentSpanId ?? parentIterationSpanId,
11185
12785
  name: spec.name,
11186
12786
  status,
11187
- durationMs: Date.now() - start,
12787
+ // A starting segment has no extent yet; a reader draws it over its children.
12788
+ durationMs: status === "running" ? void 0 : elapsedMs(),
11188
12789
  error: info.error,
11189
12790
  info: {
11190
12791
  id: spawnId,
@@ -11194,6 +12795,8 @@ async function runChild(spec, input, deps, ref, opts) {
11194
12795
  depth: childDepth,
11195
12796
  parentToolCallId: opts.parentToolCallId,
11196
12797
  status: info.subagentStatus,
12798
+ // Only a run that paused has more than one segment to tell about.
12799
+ ...segment > 1 || unfinished ? { segments: segment } : {},
11197
12800
  ...info.note ? { note: info.note } : {},
11198
12801
  ...spec.metadata ? { metadata: spec.metadata } : {}
11199
12802
  },
@@ -11317,6 +12920,7 @@ async function runChild(spec, input, deps, ref, opts) {
11317
12920
  }
11318
12921
  if (traceScope) childInput = { ...childInput, ctx: { ...childInput.ctx || {}, __traceSession: traceScope } };
11319
12922
  const usageBaseline = childInput.usage?.perRequest?.length ?? 0;
12923
+ recordSegment("running", { subagentStatus: "running", input });
11320
12924
  let res;
11321
12925
  try {
11322
12926
  res = await child.invoke(childInput, childConfig);
@@ -11358,7 +12962,10 @@ async function runChild(spec, input, deps, ref, opts) {
11358
12962
  pendingKind: "approval",
11359
12963
  pendingId: childEntry.id,
11360
12964
  spawnId,
11361
- iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0
12965
+ iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0,
12966
+ agentSpanId,
12967
+ startedAt: runStartedAt,
12968
+ segments: segment
11362
12969
  };
11363
12970
  recordSegment("pending", { subagentStatus: "paused", input });
11364
12971
  parentOnEvent?.({ type: "subagent", phase: "paused", name: spec.name, id: spawnId, mode: spec.mode, parentToolCallId: opts.parentToolCallId });
@@ -11384,7 +12991,10 @@ async function runChild(spec, input, deps, ref, opts) {
11384
12991
  pendingKind: "user_question",
11385
12992
  pendingId: childEntry.id,
11386
12993
  spawnId,
11387
- iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0
12994
+ iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0,
12995
+ agentSpanId,
12996
+ startedAt: runStartedAt,
12997
+ segments: segment
11388
12998
  };
11389
12999
  recordSegment("pending", { subagentStatus: "paused", input });
11390
13000
  parentOnEvent?.({ type: "subagent", phase: "paused", name: spec.name, id: spawnId, mode: spec.mode, parentToolCallId: opts.parentToolCallId });
@@ -12071,6 +13681,30 @@ ${pluginAppend}`;
12071
13681
  };
12072
13682
  }
12073
13683
  }
13684
+ const traceHandoff = {};
13685
+ const noteTraceHandoff = (current) => {
13686
+ traceHandoff.continuation = current.ctx?.__traceContinuation;
13687
+ traceHandoff.events = current.ctx?.[DEFERRED_TRACE_EVENTS_KEY];
13688
+ };
13689
+ const closeDanglingTrace = async (status, error) => {
13690
+ const continuation = traceHandoff.continuation;
13691
+ const events = traceHandoff.events;
13692
+ traceHandoff.continuation = void 0;
13693
+ traceHandoff.events = void 0;
13694
+ if (!continuation) return;
13695
+ try {
13696
+ await closeTraceContinuation(continuation, {
13697
+ tracing: opts.tracing,
13698
+ exporters: pluginHost?.contributions.traceExporters,
13699
+ status,
13700
+ error,
13701
+ agentRuntime: base.__runtime,
13702
+ events
13703
+ });
13704
+ } catch (closeError) {
13705
+ console.warn("[agent-sdk] closing the trace failed:", closeError);
13706
+ }
13707
+ };
12074
13708
  try {
12075
13709
  const toolSet = buildInvokeToolSet();
12076
13710
  const stateRef = toolSet.stateRef;
@@ -12149,11 +13783,15 @@ ${pluginAppend}`;
12149
13783
  const result = await trySummarize(state, rawMessages, stateRef);
12150
13784
  state = result.state;
12151
13785
  rawMessages = result.rawMessages;
13786
+ noteTraceHandoff(state);
12152
13787
  if (result.compressed) continue;
12153
13788
  }
12154
13789
  const modelMessages = buildModelMessages(state, resolved);
13790
+ traceHandoff.continuation = void 0;
13791
+ traceHandoff.events = void 0;
12155
13792
  const res = await base.invoke({ ...state, messages: modelMessages }, turnConfig);
12156
13793
  lastResult = res;
13794
+ noteTraceHandoff(res.state ?? state);
12157
13795
  const currentSummaries = state.summaries;
12158
13796
  const currentSummaryRecords = state.summaryRecords;
12159
13797
  const currentPlan = state.plan;
@@ -12180,6 +13818,7 @@ ${pluginAppend}`;
12180
13818
  const result = await trySummarize(state, rawMessages, stateRef);
12181
13819
  state = result.state;
12182
13820
  rawMessages = result.rawMessages;
13821
+ noteTraceHandoff(state);
12183
13822
  continue;
12184
13823
  }
12185
13824
  if (state.ctx?.__finalizedDueToStructuredOutput) break;
@@ -12191,6 +13830,7 @@ ${pluginAppend}`;
12191
13830
  const result = await trySummarize(state, rawMessages, stateRef);
12192
13831
  state = result.state;
12193
13832
  rawMessages = result.rawMessages;
13833
+ noteTraceHandoff(state);
12194
13834
  if (result.compressed) continue;
12195
13835
  }
12196
13836
  }
@@ -12201,6 +13841,7 @@ ${pluginAppend}`;
12201
13841
  lastResult = res;
12202
13842
  }
12203
13843
  if (state.ctx?.[DEFERRED_TRACE_EVENTS_KEY]) {
13844
+ traceHandoff.events = state.ctx[DEFERRED_TRACE_EVENTS_KEY];
12204
13845
  const ctx = { ...state.ctx || {} };
12205
13846
  delete ctx[DEFERRED_TRACE_EVENTS_KEY];
12206
13847
  state = { ...state, ctx };
@@ -12220,8 +13861,12 @@ ${pluginAppend}`;
12220
13861
  const strippedCtx = { ...endCtx };
12221
13862
  delete strippedCtx.__traceContinuation;
12222
13863
  lastResult = { ...lastResult, state: { ...lastResult.state, ctx: strippedCtx } };
13864
+ traceHandoff.continuation = endCtx.__traceContinuation;
13865
+ await closeDanglingTrace("success");
12223
13866
  }
12224
13867
  }
13868
+ traceHandoff.continuation = void 0;
13869
+ traceHandoff.events = void 0;
12225
13870
  if (skillsEnabled && lastResult.state) {
12226
13871
  const persisted = skillStateFromRegistry(toolSet.skillRegistryRef);
12227
13872
  if (persisted) {
@@ -12267,6 +13912,11 @@ ${pluginAppend}`;
12267
13912
  await endSession(endStatus, { result: lastResult });
12268
13913
  return lastResult;
12269
13914
  } catch (err) {
13915
+ await closeDanglingTrace("error", {
13916
+ message: err instanceof Error ? err.message : String(err),
13917
+ stack: err instanceof Error ? err.stack : void 0,
13918
+ name: err instanceof Error ? err.name : void 0
13919
+ });
12270
13920
  await endSession("error", { error: err instanceof Error ? err : new Error(String(err)) });
12271
13921
  throw err;
12272
13922
  }
@@ -13183,7 +14833,7 @@ function isHookImplemented(hook) {
13183
14833
  // src/plugins/builtin/guardrail.ts
13184
14834
  init_content();
13185
14835
  var ALLOW = { action: "allow" };
13186
- var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
14836
+ var RETRYABLE_STATUS2 = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
13187
14837
  var RetryableGuardrailError = class extends Error {
13188
14838
  constructor(message) {
13189
14839
  super(message);
@@ -13281,7 +14931,7 @@ function httpGuardrail(options) {
13281
14931
  } catch {
13282
14932
  }
13283
14933
  const message = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}${text ? ` - ${text.slice(0, 200)}` : ""}`;
13284
- if (RETRYABLE_STATUS.has(response.status)) throw new RetryableGuardrailError(message);
14934
+ if (RETRYABLE_STATUS2.has(response.status)) throw new RetryableGuardrailError(message);
13285
14935
  throw new Error(message);
13286
14936
  }
13287
14937
  return response.json();
@@ -13388,9 +15038,9 @@ function createGuardrailPlugin(options) {
13388
15038
  });
13389
15039
  const resolved = verdict ?? ALLOW;
13390
15040
  if (resolved.raw?.disabled === true) {
13391
- const warned = (_b = ctx.store).__disabledWarned ?? (_b.__disabledWarned = /* @__PURE__ */ new Set());
13392
- if (!warned.has(request.phase)) {
13393
- warned.add(request.phase);
15041
+ const warned2 = (_b = ctx.store).__disabledWarned ?? (_b.__disabledWarned = /* @__PURE__ */ new Set());
15042
+ if (!warned2.has(request.phase)) {
15043
+ warned2.add(request.phase);
13394
15044
  ctx.logger.warn(
13395
15045
  `guardrail reports it is not active for the "${request.phase}" surface; nothing is being enforced there`
13396
15046
  );
@@ -13887,7 +15537,7 @@ function safeJson(value) {
13887
15537
  function matches(pattern, toolName) {
13888
15538
  return typeof pattern === "string" ? pattern === toolName : pattern.test(toolName);
13889
15539
  }
13890
- function asObject(args) {
15540
+ function asObject2(args) {
13891
15541
  return args && typeof args === "object" ? args : {};
13892
15542
  }
13893
15543
  function toolPolicy(config = {}) {
@@ -13908,7 +15558,7 @@ function toolPolicy(config = {}) {
13908
15558
  hooks: {
13909
15559
  preToolUse: ({ toolName, args }, ctx) => {
13910
15560
  var _a;
13911
- const argObject = asObject(args);
15561
+ const argObject = asObject2(args);
13912
15562
  const isControlPlane = CONTROL_PLANE_TOOL_NAMES.includes(toolName);
13913
15563
  const allowListApplies = !isControlPlane || config.governControlPlaneTools === true;
13914
15564
  if (config.allowOnly && allowListApplies && !config.allowOnly.some((pattern) => matches(pattern, toolName))) {
@@ -13970,7 +15620,7 @@ function pathSandbox(config) {
13970
15620
  hooks: {
13971
15621
  preToolUse: ({ toolName, args }) => {
13972
15622
  if (config.tools && !config.tools.some((pattern) => matches(pattern, toolName))) return void 0;
13973
- const argObject = asObject(args);
15623
+ const argObject = asObject2(args);
13974
15624
  for (const key of argNames) {
13975
15625
  const value = argObject[key];
13976
15626
  if (typeof value !== "string" || value.length === 0) continue;
@@ -14738,7 +16388,7 @@ function mcp(config) {
14738
16388
  }
14739
16389
 
14740
16390
  // src/plugins/builtin/rateLimit.ts
14741
- function sleep(ms, signal) {
16391
+ function sleep2(ms, signal) {
14742
16392
  return new Promise((resolve) => {
14743
16393
  let timer;
14744
16394
  const done = () => {
@@ -14795,7 +16445,7 @@ function rateLimit(config = {}) {
14795
16445
  while (!attempt.ok) {
14796
16446
  const remaining = deadline - Date.now();
14797
16447
  if (!Number.isFinite(attempt.waitMs) || attempt.waitMs > remaining) break;
14798
- await sleep(Math.max(1, attempt.waitMs), ctx.signal);
16448
+ await sleep2(Math.max(1, attempt.waitMs), ctx.signal);
14799
16449
  if (ctx.signal?.aborted) break;
14800
16450
  attempt = consume(applicable);
14801
16451
  }
@@ -15891,18 +17541,21 @@ function langfuseTracing(config = {}) {
15891
17541
  }
15892
17542
 
15893
17543
  // src/plugins/builtin/otel.ts
15894
- function toSessionStatus(status) {
15895
- if (status === "success") return "success";
15896
- if (status === "error") return "error";
15897
- return status === "paused" ? "in_progress" : "partial";
15898
- }
15899
- function otelTracing(config) {
15900
- const endpoint = config.endpoint?.trim();
15901
- if (!endpoint) {
17544
+ function otelTracing(config = {}) {
17545
+ if (config.endpoint !== void 0 && !config.endpoint.trim()) {
15902
17546
  throw new Error("[agent-sdk] otelTracing requires a non-empty `endpoint`.");
15903
17547
  }
17548
+ const name = config.name ?? "otel-tracing";
17549
+ let exporter;
17550
+ try {
17551
+ exporter = createOtlpExporter({ ...config, endpoint: config.endpoint?.trim(), name });
17552
+ } catch {
17553
+ throw new Error(
17554
+ "[agent-sdk] otelTracing requires a non-empty `endpoint` (or OTEL_EXPORTER_OTLP_ENDPOINT / OTEL_EXPORTER_OTLP_TRACES_ENDPOINT in the environment)."
17555
+ );
17556
+ }
15904
17557
  return {
15905
- name: config.name ?? "otel-tracing",
17558
+ name,
15906
17559
  // Registers only the `sessionEnd` observer, and observers run concurrently,
15907
17560
  // so this number orders nothing at runtime. It is set above checkpointing
15908
17561
  // (900) to record intent: this plugin is the last thing interested in the
@@ -15910,8 +17563,9 @@ function otelTracing(config) {
15910
17563
  priority: 950,
15911
17564
  // Observability. A dropped export is a reporting gap, never a safety hole.
15912
17565
  failureMode: "open",
17566
+ traceExporters: [exporter],
15913
17567
  hooks: {
15914
- sessionEnd: async ({ status, durationMs, error }, ctx) => {
17568
+ sessionEnd: async (_event, ctx) => {
15915
17569
  const state = ctx.state;
15916
17570
  const session = state.ctx?.__traceSession;
15917
17571
  if (isSubagentTraceScope(session)) return;
@@ -15921,57 +17575,29 @@ function otelTracing(config) {
15921
17575
  ctx.emit({ type: "metadata", otelTracing: { exported: false, reason: message } });
15922
17576
  return;
15923
17577
  }
15924
- const endedAtMs = Date.now();
15925
- const startedAtIso = new Date(session.startedAt).toISOString();
15926
- const errors = error ? [...session.errors, { eventId: "session", message: error.message, stack: error.stack, type: "session" }] : session.errors;
15927
- const payload = {
15928
- sessionId: session.sessionId,
15929
- traceId: session.traceId,
15930
- rootSpanId: session.rootSpanId,
15931
- threadId: session.threadId,
15932
- startedAt: startedAtIso,
15933
- endedAt: new Date(endedAtMs).toISOString(),
15934
- durationMs: durationMs ?? endedAtMs - session.startedAt,
15935
- // `service.name` is read off `agent.name` inside the conversion, so
15936
- // the override is applied here rather than by editing spans after.
15937
- agent: {
15938
- ...session.agentInfo ?? {},
15939
- name: config.serviceName ?? session.agentInfo?.name ?? session.configAgentName ?? ctx.agentName
15940
- },
15941
- metadata: session.configMetadata,
15942
- // Carried only to satisfy the type: `traceSessionToOtlp` reads the
15943
- // events, summary and identifiers, never the sink snapshot.
15944
- config: { enabled: true, logData: session.resolvedConfig.logData, sink: { type: "otlp", endpoint } },
15945
- summary: session.summary,
15946
- events: session.events,
15947
- status: toSessionStatus(status),
15948
- errors
15949
- };
15950
- try {
15951
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
15952
- if (!fetchFn) {
15953
- ctx.logger.warn("otelTracing needs fetch to be available in this runtime; export skipped.");
15954
- return;
15955
- }
15956
- const response = await fetchFn(endpoint, {
15957
- method: "POST",
15958
- headers: { "content-type": "application/json", ...config.headers ?? {} },
15959
- body: JSON.stringify(traceSessionToOtlp(payload)),
15960
- // The run is over, but a host that cancelled it should not be made
15961
- // to wait on a collector that is refusing to answer.
15962
- signal: ctx.signal
15963
- });
15964
- if (!response.ok) {
15965
- ctx.logger.warn(`otelTracing export returned HTTP ${response.status}.`);
15966
- return;
15967
- }
15968
- ctx.emit({
15969
- type: "metadata",
15970
- otelTracing: { exported: true, endpoint, spans: session.events.length + 1 }
15971
- });
15972
- } catch (err) {
15973
- ctx.logger.warn("otelTracing export failed:", err instanceof Error ? err.message : err);
17578
+ const reports = (session.exportReports ?? []).filter((report2) => !report2.sink && report2.exporter === name);
17579
+ const report = reports[reports.length - 1];
17580
+ if (!report) return;
17581
+ const { result } = report;
17582
+ if (!result.ok) {
17583
+ ctx.logger.warn(`otelTracing export failed: ${result.error ?? "unknown error"}`);
17584
+ return;
17585
+ }
17586
+ if (result.skipped) {
17587
+ ctx.emit({ type: "metadata", otelTracing: { exported: false, reason: result.reason ?? "nothing to export" } });
17588
+ return;
15974
17589
  }
17590
+ ctx.emit({
17591
+ type: "metadata",
17592
+ otelTracing: {
17593
+ exported: true,
17594
+ endpoint: report.endpoint,
17595
+ spans: result.spans,
17596
+ terminal: report.terminal,
17597
+ // A 200 that refused some spans: the collector's count and message.
17598
+ ...result.partialSuccess ? { rejectedSpans: result.partialSuccess.rejectedSpans, ...result.partialSuccess.message ? { rejectionMessage: result.partialSuccess.message } : {} } : {}
17599
+ }
17600
+ });
15975
17601
  }
15976
17602
  }
15977
17603
  };
@@ -19007,9 +20633,9 @@ function mapAnthropicStopReason(reason) {
19007
20633
  return "stop";
19008
20634
  }
19009
20635
  }
19010
- function safeJsonParse(str) {
20636
+ function safeJsonParse(str2) {
19011
20637
  try {
19012
- return JSON.parse(str);
20638
+ return JSON.parse(str2);
19013
20639
  } catch {
19014
20640
  return {};
19015
20641
  }
@@ -19879,9 +21505,9 @@ function mediaTypeToFormat(mediaType) {
19879
21505
  };
19880
21506
  return map[mediaType] ?? "png";
19881
21507
  }
19882
- function safeJsonParse2(str) {
21508
+ function safeJsonParse2(str2) {
19883
21509
  try {
19884
- return JSON.parse(str);
21510
+ return JSON.parse(str2);
19885
21511
  } catch {
19886
21512
  return {};
19887
21513
  }
@@ -20278,10 +21904,13 @@ var VertexProvider = class extends BaseProvider {
20278
21904
  textParts.push(part.text);
20279
21905
  }
20280
21906
  } else if (part.functionCall) {
21907
+ const suppliedId = typeof part.functionCall.id === "string" && part.functionCall.id ? part.functionCall.id : void 0;
21908
+ const position = toolCallIdx++;
20281
21909
  toolCalls.push({
20282
- id: `call_${toolCallIdx++}`,
21910
+ id: suppliedId ?? `call_${position}`,
20283
21911
  name: part.functionCall.name,
20284
21912
  arguments: JSON.stringify(part.functionCall.args ?? {}),
21913
+ ...suppliedId ? {} : { idSynthesized: true },
20285
21914
  ...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
20286
21915
  });
20287
21916
  }
@@ -20321,12 +21950,15 @@ var VertexProvider = class extends BaseProvider {
20321
21950
  }
20322
21951
  } else if (part.functionCall) {
20323
21952
  if (!delta.toolCalls) delta.toolCalls = [];
21953
+ const suppliedId = typeof part.functionCall.id === "string" && part.functionCall.id ? part.functionCall.id : void 0;
21954
+ const position = counter.next++;
20324
21955
  delta.toolCalls.push({
20325
21956
  // Unique across the whole stream: the adapter merges chunks by id.
20326
- id: `call_${counter.next}`,
20327
- index: counter.next++,
21957
+ id: suppliedId ?? `call_${position}`,
21958
+ index: position,
20328
21959
  name: part.functionCall.name,
20329
21960
  arguments: JSON.stringify(part.functionCall.args ?? {}),
21961
+ ...suppliedId ? {} : { idSynthesized: true },
20330
21962
  ...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
20331
21963
  });
20332
21964
  }
@@ -20379,12 +22011,12 @@ function mapGeminiFinishReason(reason) {
20379
22011
  return "stop";
20380
22012
  }
20381
22013
  }
20382
- function base64url(str) {
20383
- return Buffer.from(str).toString("base64url");
22014
+ function base64url(str2) {
22015
+ return Buffer.from(str2).toString("base64url");
20384
22016
  }
20385
- function safeJsonParse3(str) {
22017
+ function safeJsonParse3(str2) {
20386
22018
  try {
20387
- return JSON.parse(str);
22019
+ return JSON.parse(str2);
20388
22020
  } catch {
20389
22021
  return {};
20390
22022
  }
@@ -20429,6 +22061,7 @@ exports.DEFAULT_SUBAGENT_TOOL_NAMES = DEFAULT_SUBAGENT_TOOL_NAMES;
20429
22061
  exports.DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS = DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS;
20430
22062
  exports.DELEGATION_TOOL_NAMES = DELEGATION_TOOL_NAMES;
20431
22063
  exports.DedupTracker = DedupTracker;
22064
+ exports.GENAI_SEMCONV_COMMIT = GENAI_SEMCONV_COMMIT;
20432
22065
  exports.GuardrailPhase = GuardrailPhase;
20433
22066
  exports.HOOK_CONTRACT_VERSION = HOOK_CONTRACT_VERSION;
20434
22067
  exports.HOOK_NAMES = HOOK_NAMES;
@@ -20469,6 +22102,7 @@ exports.canSpawn = canSpawn;
20469
22102
  exports.captureSnapshot = captureSnapshot;
20470
22103
  exports.checkpointing = checkpointing;
20471
22104
  exports.clearLearnedModelRules = clearLearnedModelRules;
22105
+ exports.closeTraceContinuation = closeTraceContinuation;
20472
22106
  exports.codePresenceRule = codePresenceRule;
20473
22107
  exports.coerceToolArgs = coerceToolArgs;
20474
22108
  exports.cognipeerGuardrail = cognipeerGuardrail;
@@ -20503,6 +22137,7 @@ exports.createJsonGuardrail = createJsonGuardrail;
20503
22137
  exports.createManageTodoListAliasTool = createManageTodoListAliasTool;
20504
22138
  exports.createManageTodoTool = createManageTodoTool;
20505
22139
  exports.createOpenSkillTool = createOpenSkillTool;
22140
+ exports.createOtlpExporter = createOtlpExporter;
20506
22141
  exports.createParallelTool = createParallelTool;
20507
22142
  exports.createPluginHost = createPluginHost;
20508
22143
  exports.createProvider = createProvider;
@@ -20539,6 +22174,8 @@ exports.extractMessageText = extractMessageText;
20539
22174
  exports.fileCheckpointStore = fileCheckpointStore;
20540
22175
  exports.fileSink = fileSink;
20541
22176
  exports.findSubagent = findSubagent;
22177
+ exports.foldSupersededSpans = foldSupersededSpans;
22178
+ exports.formatTraceparent = formatTraceparent;
20542
22179
  exports.formatZodError = formatZodError;
20543
22180
  exports.fromLangchainModel = fromLangchainModel;
20544
22181
  exports.fromLangchainTools = fromLangchainTools;
@@ -20586,6 +22223,7 @@ exports.outputGuard = outputGuard;
20586
22223
  exports.parseApprovalDecision = parseApprovalDecision;
20587
22224
  exports.parseModelError = parseModelError;
20588
22225
  exports.parseSkillFrontmatter = parseSkillFrontmatter;
22226
+ exports.parseTraceparent = parseTraceparent;
20589
22227
  exports.pathSandbox = pathSandbox;
20590
22228
  exports.piiRedaction = piiRedaction;
20591
22229
  exports.pluginCapabilities = pluginCapabilities;
@@ -20640,6 +22278,7 @@ exports.toolPolicy = toolPolicy;
20640
22278
  exports.traceContinuationOf = traceContinuationOf;
20641
22279
  exports.traceSectionsFromMessages = traceSectionsFromMessages;
20642
22280
  exports.traceSessionToOtlp = traceSessionToOtlp;
22281
+ exports.traceparentOf = traceparentOf;
20643
22282
  exports.validateReasoningConfig = validateReasoningConfig;
20644
22283
  exports.validateToolArgs = validateToolArgs;
20645
22284
  exports.webhookApproval = webhookApproval;