@cognipeer/agent-sdk 0.17.0 → 0.18.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.mjs CHANGED
@@ -6,6 +6,8 @@ import path from 'path';
6
6
  import { Buffer as Buffer$1 } from 'buffer';
7
7
  import { nanoid } from 'nanoid';
8
8
  import crypto, { createHash, randomUUID, createHmac } from 'crypto';
9
+ import { gzip } from 'zlib';
10
+ import { promisify } from 'util';
9
11
  import AjvModule from 'ajv';
10
12
 
11
13
  var __defProp = Object.defineProperty;
@@ -1221,9 +1223,1398 @@ function splitUsage(usage) {
1221
1223
  }
1222
1224
  return { own, subagent, ownCalls: ownEntries.length, subagentCalls: subagentEntries.length, ownEntries, subagentEntries };
1223
1225
  }
1226
+ function cacheWriteTokensOf(raw) {
1227
+ if (!raw || typeof raw !== "object") return void 0;
1228
+ const details = raw.prompt_tokens_details || raw.promptTokensDetails || raw.input_token_details || raw.inputTokenDetails || {};
1229
+ const candidates = [
1230
+ details.cache_write_tokens,
1231
+ details.cacheWriteTokens,
1232
+ details.cache_creation,
1233
+ raw.cache_write_tokens,
1234
+ raw.cacheWriteTokens,
1235
+ raw.cache_creation_input_tokens,
1236
+ raw.cacheCreationInputTokens,
1237
+ raw.cacheWriteInputTokens,
1238
+ raw.cacheWriteInputTokenCount
1239
+ ];
1240
+ for (const value of candidates) {
1241
+ const n = Number(value);
1242
+ if (Number.isFinite(n) && n > 0) return n;
1243
+ }
1244
+ return void 0;
1245
+ }
1224
1246
 
1225
1247
  // src/utils/tracing.ts
1226
1248
  init_content();
1249
+
1250
+ // src/version.ts
1251
+ var SDK_VERSION = "0.18.0";
1252
+
1253
+ // src/utils/otlp/content.ts
1254
+ init_content();
1255
+
1256
+ // src/utils/otlp/semconv.ts
1257
+ var GENAI_SEMCONV_COMMIT = "547934a";
1258
+ var ATTR = {
1259
+ operationName: "gen_ai.operation.name",
1260
+ providerName: "gen_ai.provider.name",
1261
+ requestModel: "gen_ai.request.model",
1262
+ responseModel: "gen_ai.response.model",
1263
+ responseId: "gen_ai.response.id",
1264
+ finishReasons: "gen_ai.response.finish_reasons",
1265
+ requestStream: "gen_ai.request.stream",
1266
+ outputType: "gen_ai.output.type",
1267
+ conversationId: "gen_ai.conversation.id",
1268
+ agentName: "gen_ai.agent.name",
1269
+ agentVersion: "gen_ai.agent.version",
1270
+ toolName: "gen_ai.tool.name",
1271
+ toolCallId: "gen_ai.tool.call.id",
1272
+ toolType: "gen_ai.tool.type",
1273
+ usageInput: "gen_ai.usage.input_tokens",
1274
+ usageOutput: "gen_ai.usage.output_tokens",
1275
+ usageCacheRead: "gen_ai.usage.cache_read.input_tokens",
1276
+ usageCacheWrite: "gen_ai.usage.cache_write.input_tokens",
1277
+ usageReasoning: "gen_ai.usage.reasoning.output_tokens",
1278
+ errorType: "error.type",
1279
+ // Content (opt-in).
1280
+ systemInstructions: "gen_ai.system_instructions",
1281
+ inputMessages: "gen_ai.input.messages",
1282
+ outputMessages: "gen_ai.output.messages",
1283
+ toolDefinitions: "gen_ai.tool.definitions",
1284
+ toolCallArguments: "gen_ai.tool.call.arguments",
1285
+ toolCallResult: "gen_ai.tool.call.result"
1286
+ };
1287
+ var OPERATION = {
1288
+ chat: "chat",
1289
+ executeTool: "execute_tool",
1290
+ invokeAgent: "invoke_agent"
1291
+ };
1292
+ var PROVIDERS = {
1293
+ openai: "openai",
1294
+ chatopenai: "openai",
1295
+ azure: "azure.ai.openai",
1296
+ azureopenai: "azure.ai.openai",
1297
+ azurechatopenai: "azure.ai.openai",
1298
+ azureaiopenai: "azure.ai.openai",
1299
+ azureaiinference: "azure.ai.inference",
1300
+ anthropic: "anthropic",
1301
+ chatanthropic: "anthropic",
1302
+ bedrock: "aws.bedrock",
1303
+ awsbedrock: "aws.bedrock",
1304
+ chatbedrock: "aws.bedrock",
1305
+ chatbedrockconverse: "aws.bedrock",
1306
+ vertex: "gcp.vertex_ai",
1307
+ vertexai: "gcp.vertex_ai",
1308
+ gcpvertexai: "gcp.vertex_ai",
1309
+ chatvertexai: "gcp.vertex_ai",
1310
+ gemini: "gcp.gemini",
1311
+ gcpgemini: "gcp.gemini",
1312
+ chatgooglegenerativeai: "gcp.gemini",
1313
+ // Gemini API or Vertex: the name alone does not say which.
1314
+ google: "gcp.gen_ai",
1315
+ gcpgenai: "gcp.gen_ai",
1316
+ mistral: "mistral",
1317
+ mistralai: "mistral",
1318
+ chatmistralai: "mistral",
1319
+ groq: "groq",
1320
+ chatgroq: "groq",
1321
+ deepseek: "deepseek",
1322
+ chatdeepseek: "deepseek",
1323
+ cohere: "cohere",
1324
+ chatcohere: "cohere",
1325
+ xai: "x_ai",
1326
+ chatxai: "x_ai",
1327
+ perplexity: "perplexity",
1328
+ chatperplexity: "perplexity",
1329
+ watsonx: "ibm.watsonx.ai",
1330
+ ibmwatsonxai: "ibm.watsonx.ai"
1331
+ };
1332
+ function genAiProviderName(hint) {
1333
+ if (!hint) return void 0;
1334
+ const key = hint.toLowerCase().replace(/[^a-z0-9]/g, "");
1335
+ return key ? PROVIDERS[key] : void 0;
1336
+ }
1337
+ function errorTypeOf(error) {
1338
+ if (!error) return "_OTHER";
1339
+ if (typeof error.type === "string" && error.type.length > 0) return error.type;
1340
+ if (typeof error.stack === "string") {
1341
+ const match = /^\s*([A-Za-z_$][\w$.]*)\s*(?::|$)/m.exec(error.stack.split("\n", 1)[0] ?? "");
1342
+ if (match) return match[1];
1343
+ }
1344
+ return "_OTHER";
1345
+ }
1346
+ function genAiUsageOf(event) {
1347
+ const num2 = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
1348
+ const input = num2(event.inputTokens);
1349
+ const output = num2(event.outputTokens);
1350
+ const cacheRead = num2(event.cachedInputTokens);
1351
+ const cacheWrite = num2(event.cacheWriteTokens);
1352
+ const reasoning = num2(event.reasoningTokens);
1353
+ if (input + output + cacheRead + cacheWrite + reasoning + num2(event.totalTokens) === 0) return void 0;
1354
+ const basis = event.usageBasis ?? {};
1355
+ return {
1356
+ input: basis.inputExcludesCache ? input + cacheRead + cacheWrite : input,
1357
+ output: basis.outputExcludesReasoning ? output + reasoning : output,
1358
+ ...cacheRead > 0 ? { cacheRead } : {},
1359
+ ...cacheWrite > 0 ? { cacheWrite } : {},
1360
+ ...reasoning > 0 ? { reasoning } : {}
1361
+ };
1362
+ }
1363
+
1364
+ // src/utils/otlp/content.ts
1365
+ var CAPTURE = Symbol.for("cognipeer.agent-sdk.traceCapture");
1366
+ var DEFAULTS = {
1367
+ maxStringChars: 4096,
1368
+ maxMessages: 32,
1369
+ maxAttributeBytes: 32768
1370
+ };
1371
+ var FIELDS = ["system", "input", "output", "tools", "toolArgs", "toolResults", "sections"];
1372
+ function resolveContentOptions(content) {
1373
+ const given = typeof content === "object" && content !== null ? content : {};
1374
+ const enabled = typeof content === "boolean" ? content : given.enabled === true;
1375
+ const positive = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : fallback;
1376
+ return {
1377
+ enabled,
1378
+ include: Array.isArray(given.include) ? given.include.filter((field) => FIELDS.includes(field)) : [...FIELDS],
1379
+ maxStringChars: positive(given.maxStringChars, DEFAULTS.maxStringChars),
1380
+ maxMessages: positive(given.maxMessages, DEFAULTS.maxMessages),
1381
+ maxAttributeBytes: positive(given.maxAttributeBytes, DEFAULTS.maxAttributeBytes),
1382
+ redact: typeof given.redact === "function" ? given.redact : void 0,
1383
+ encoding: given.encoding === "structured" ? "structured" : "json"
1384
+ };
1385
+ }
1386
+ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1387
+ function plain(value) {
1388
+ if (value === void 0) return void 0;
1389
+ try {
1390
+ const text = JSON.stringify(value);
1391
+ return text === void 0 ? void 0 : JSON.parse(text);
1392
+ } catch {
1393
+ return void 0;
1394
+ }
1395
+ }
1396
+ var TRUNCATED_MARKER = /\.\.\.\[truncated (\d+) chars\]$/;
1397
+ function truncateText(text, max) {
1398
+ const earlier = TRUNCATED_MARKER.exec(text);
1399
+ const body = earlier ? text.slice(0, earlier.index) : text;
1400
+ if (body.length <= max) return text;
1401
+ const lost = body.length - max + (earlier ? Number(earlier[1]) : 0);
1402
+ return `${body.slice(0, max)}...[truncated ${lost} chars]`;
1403
+ }
1404
+ function capStrings(value, max) {
1405
+ if (typeof value === "string") return truncateText(value, max);
1406
+ if (Array.isArray(value)) return value.map((item) => capStrings(item, max));
1407
+ if (isRecord2(value)) {
1408
+ const out = {};
1409
+ for (const [key, item] of Object.entries(value)) out[key] = capStrings(item, max);
1410
+ return out;
1411
+ }
1412
+ return value;
1413
+ }
1414
+ function asObject(value) {
1415
+ let parsed = value;
1416
+ if (typeof value === "string") {
1417
+ try {
1418
+ parsed = JSON.parse(value);
1419
+ } catch {
1420
+ parsed = value;
1421
+ }
1422
+ }
1423
+ const copy = plain(parsed);
1424
+ if (copy === void 0) return void 0;
1425
+ return isRecord2(copy) ? copy : { value: copy };
1426
+ }
1427
+ var REASONING_PART_TYPES = /* @__PURE__ */ new Set(["thinking", "redacted_thinking", "reasoning", "reasoning_content"]);
1428
+ function textOf(content) {
1429
+ if (content == null) return "";
1430
+ if (typeof content === "string") return content;
1431
+ if (!Array.isArray(content)) return contentPartToText(content, () => "");
1432
+ return content.filter((part) => !(isRecord2(part) && REASONING_PART_TYPES.has(String(part.type)))).map((part) => contentPartToText(part, () => "")).filter((text) => text.length > 0).join("\n");
1433
+ }
1434
+ function toolCallPartsOf(message) {
1435
+ const calls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
1436
+ const parts = [];
1437
+ for (const call of calls) {
1438
+ if (!isRecord2(call)) continue;
1439
+ const name = call.name ?? call.function?.name;
1440
+ if (typeof name !== "string" || !name) continue;
1441
+ const args = call.args ?? call.arguments ?? call.function?.arguments;
1442
+ const coerced = asObject(args ?? {});
1443
+ const id = typeof call.id === "string" && call.id && !call.idSynthesized ? call.id : void 0;
1444
+ parts.push({ type: "tool_call", ...id ? { id } : {}, name, arguments: coerced ?? {} });
1445
+ }
1446
+ return parts;
1447
+ }
1448
+ function messageOf(raw) {
1449
+ if (!isRecord2(raw)) return void 0;
1450
+ const role = typeof raw.role === "string" ? raw.role : "user";
1451
+ const parts = [];
1452
+ if (role === "tool") {
1453
+ const text2 = textOf(raw.content);
1454
+ const parsed = (() => {
1455
+ try {
1456
+ return JSON.parse(text2);
1457
+ } catch {
1458
+ return text2;
1459
+ }
1460
+ })();
1461
+ parts.push({
1462
+ type: "tool_call_response",
1463
+ ...typeof raw.tool_call_id === "string" && raw.tool_call_id ? { id: raw.tool_call_id } : {},
1464
+ response: plain(parsed) ?? text2
1465
+ });
1466
+ return { role, parts, ...typeof raw.name === "string" && raw.name ? { name: raw.name } : {} };
1467
+ }
1468
+ const text = textOf(raw.content);
1469
+ if (text) parts.push({ type: "text", content: text });
1470
+ if (role === "assistant") parts.push(...toolCallPartsOf(raw));
1471
+ if (parts.length === 0 && role !== "assistant") parts.push({ type: "text", content: "" });
1472
+ return { role, parts };
1473
+ }
1474
+ function buildCapturedContent(source, limits) {
1475
+ const out = {};
1476
+ if (Array.isArray(source.input)) {
1477
+ const system = [];
1478
+ const messages = [];
1479
+ for (const raw of source.input) {
1480
+ const message = messageOf(raw);
1481
+ if (!message) continue;
1482
+ if (message.role === "system") {
1483
+ const content = message.parts.map((part) => part.type === "text" ? part.content : "").join("\n");
1484
+ if (content) system.push({ type: "text", content });
1485
+ } else {
1486
+ messages.push(message);
1487
+ }
1488
+ }
1489
+ if (system.length > 0) out.system = capStrings(system, limits.maxStringChars);
1490
+ const recent = messages.slice(-limits.maxMessages);
1491
+ out.input = capStrings(recent, limits.maxStringChars);
1492
+ }
1493
+ if (source.output !== void 0 && source.output !== null) {
1494
+ const message = messageOf({ ...isRecord2(source.output) ? source.output : { content: String(source.output) }, role: "assistant" });
1495
+ if (message) out.output = capStrings(message, limits.maxStringChars);
1496
+ }
1497
+ if (Array.isArray(source.toolDefinitions) && source.toolDefinitions.length > 0) {
1498
+ out.tools = capStrings(
1499
+ source.toolDefinitions.filter((tool) => tool && typeof tool.name === "string").map((tool) => ({
1500
+ type: "function",
1501
+ name: tool.name,
1502
+ ...tool.description ? { description: tool.description } : {},
1503
+ ...tool.parameters !== void 0 ? { parameters: plain(tool.parameters) } : {}
1504
+ })),
1505
+ limits.maxStringChars
1506
+ );
1507
+ }
1508
+ if (source.toolArguments !== void 0) {
1509
+ const args = asObject(source.toolArguments);
1510
+ if (args !== void 0) out.toolArgs = capStrings(args, limits.maxStringChars);
1511
+ }
1512
+ if (source.hasToolResult || source.toolResult !== void 0) {
1513
+ const result = asObject(source.toolResult);
1514
+ if (result !== void 0) out.toolResults = capStrings(result, limits.maxStringChars);
1515
+ }
1516
+ return out;
1517
+ }
1518
+ function capturedContentOf(event) {
1519
+ return event?.[CAPTURE];
1520
+ }
1521
+ function attachCapturedContent(record, content) {
1522
+ Object.defineProperty(record, CAPTURE, { value: content, enumerable: false, configurable: true, writable: true });
1523
+ }
1524
+ var SEPARATE_SYSTEM = /* @__PURE__ */ new Set(["anthropic", "aws.bedrock", "gcp.vertex_ai", "gcp.gemini"]);
1525
+ function toAnyValue(value) {
1526
+ if (value === null || value === void 0) return void 0;
1527
+ if (typeof value === "string") return { stringValue: value };
1528
+ if (typeof value === "boolean") return { boolValue: value };
1529
+ if (typeof value === "number") {
1530
+ if (!Number.isFinite(value)) return void 0;
1531
+ return Number.isInteger(value) && Number.isSafeInteger(value) ? { intValue: String(value) } : { doubleValue: value };
1532
+ }
1533
+ if (Array.isArray(value)) {
1534
+ return { arrayValue: { values: value.map((item) => toAnyValue(item) ?? { stringValue: "" }) } };
1535
+ }
1536
+ if (isRecord2(value)) {
1537
+ const values = [];
1538
+ for (const [key, item] of Object.entries(value)) {
1539
+ const any = toAnyValue(item);
1540
+ if (any) values.push({ key, value: any });
1541
+ }
1542
+ return { kvlistValue: { values } };
1543
+ }
1544
+ return void 0;
1545
+ }
1546
+ var byteLength = (text) => Buffer$1.byteLength(text, "utf8");
1547
+ function render(value, field, options, info) {
1548
+ let working = plain(value);
1549
+ if (working === void 0) return void 0;
1550
+ if (options.redact) {
1551
+ try {
1552
+ working = options.redact(plain(working), { field, ...info });
1553
+ } catch {
1554
+ return void 0;
1555
+ }
1556
+ working = plain(working);
1557
+ if (working === void 0 || working === null) return void 0;
1558
+ }
1559
+ working = capStrings(working, options.maxStringChars);
1560
+ if ((field === "input" || field === "system" || field === "sections") && Array.isArray(working) && working.length > options.maxMessages) {
1561
+ working = working.slice(-options.maxMessages);
1562
+ }
1563
+ let text = JSON.stringify(working);
1564
+ if (text === void 0) return void 0;
1565
+ if (byteLength(text) > options.maxAttributeBytes) {
1566
+ if (field === "input" && Array.isArray(working)) {
1567
+ const messages = [...working];
1568
+ while (messages.length > 1 && byteLength(JSON.stringify(messages)) > options.maxAttributeBytes) messages.shift();
1569
+ working = messages;
1570
+ text = JSON.stringify(working);
1571
+ }
1572
+ if (byteLength(text) > options.maxAttributeBytes) {
1573
+ working = { truncated: true };
1574
+ text = JSON.stringify(working);
1575
+ }
1576
+ }
1577
+ return options.encoding === "structured" ? toAnyValue(working) : { stringValue: text };
1578
+ }
1579
+ function contentAttributes(kind, event, provider, options) {
1580
+ if (!options?.enabled) return [];
1581
+ const captured = capturedContentOf(event);
1582
+ if (!captured) return [];
1583
+ const include = new Set(options.include);
1584
+ const info = {
1585
+ eventType: event.type,
1586
+ ...event.spanId ? { spanId: event.spanId } : {},
1587
+ ...kind === "execute_tool" && event.actor?.name ? { toolName: event.actor.name } : {},
1588
+ ...event.model ? { model: event.model } : {}
1589
+ };
1590
+ const attrs = [];
1591
+ const add = (key, value) => {
1592
+ if (value) attrs.push({ key, value });
1593
+ };
1594
+ if (kind === "chat") {
1595
+ const separate = provider !== void 0 && SEPARATE_SYSTEM.has(provider);
1596
+ const system = captured.system ?? [];
1597
+ if (separate) {
1598
+ if (include.has("system") && system.length > 0) add(ATTR.systemInstructions, render(system, "system", options, info));
1599
+ if (include.has("input") && captured.input) add(ATTR.inputMessages, render(captured.input, "input", options, info));
1600
+ } else if (include.has("input") && (captured.input || system.length > 0)) {
1601
+ const messages = captured.input ?? [];
1602
+ const capped = messages.slice(-options.maxMessages);
1603
+ const withSystem = system.length > 0 ? [{ role: "system", parts: system }, ...capped] : capped;
1604
+ add(ATTR.inputMessages, render(withSystem, "input", { ...options, maxMessages: options.maxMessages + 1 }, info));
1605
+ }
1606
+ if (include.has("output") && captured.output) {
1607
+ const reason = event.rawFinishReason ?? event.finishReason;
1608
+ const finish = reason === "tool_calls" ? "tool_call" : reason;
1609
+ add(ATTR.outputMessages, render([{ ...captured.output, ...finish ? { finish_reason: finish } : {} }], "output", options, info));
1610
+ }
1611
+ if (include.has("tools") && captured.tools) add(ATTR.toolDefinitions, render(captured.tools, "tools", options, info));
1612
+ } else {
1613
+ if (include.has("toolArgs") && captured.toolArgs !== void 0) add(ATTR.toolCallArguments, render(captured.toolArgs, "toolArgs", options, info));
1614
+ if (include.has("toolResults") && captured.toolResults !== void 0) add(ATTR.toolCallResult, render(captured.toolResults, "toolResults", options, info));
1615
+ }
1616
+ return attrs;
1617
+ }
1618
+ function sectionsAttribute(sections, event, options) {
1619
+ if (!sections || sections.length === 0) return void 0;
1620
+ const identity2 = sections.filter((section) => section.identity === true);
1621
+ const payload = sections.filter((section) => section.identity !== true);
1622
+ let kept = [];
1623
+ if (options?.enabled && options.include.includes("sections") && payload.length > 0) {
1624
+ kept = redactedSections(payload, options, event);
1625
+ }
1626
+ const max = options?.maxAttributeBytes ?? DEFAULTS.maxAttributeBytes;
1627
+ const encode = (list) => {
1628
+ try {
1629
+ return JSON.stringify(list);
1630
+ } catch {
1631
+ return void 0;
1632
+ }
1633
+ };
1634
+ let text = encode([...identity2, ...kept]);
1635
+ while (text !== void 0 && kept.length > 0 && byteLength(text) > max) {
1636
+ kept.shift();
1637
+ text = encode([...identity2, ...kept]);
1638
+ }
1639
+ if (text === void 0) {
1640
+ text = encode(identity2);
1641
+ }
1642
+ if (text === void 0 || text === "[]") return void 0;
1643
+ return { key: "cognipeer.sections", value: { stringValue: text } };
1644
+ }
1645
+ function redactedSections(payload, options, event) {
1646
+ let working = plain(payload);
1647
+ if (working === void 0) return [];
1648
+ if (options.redact) {
1649
+ try {
1650
+ working = plain(options.redact(plain(working), {
1651
+ field: "sections",
1652
+ eventType: event.type,
1653
+ ...event.spanId ? { spanId: event.spanId } : {},
1654
+ ...event.model ? { model: event.model } : {}
1655
+ }));
1656
+ } catch {
1657
+ return [];
1658
+ }
1659
+ if (!Array.isArray(working)) return [];
1660
+ }
1661
+ const capped = capStrings(working, options.maxStringChars);
1662
+ return Array.isArray(capped) ? capped.slice(-options.maxMessages) : [];
1663
+ }
1664
+
1665
+ // src/utils/otlp/convert.ts
1666
+ var SCOPE_NAME = "cognipeer-agent-sdk";
1667
+ var SPAN_KIND_INTERNAL = 1;
1668
+ var SPAN_KIND_CLIENT = 3;
1669
+ var FLAG_HAS_PARENT = 256;
1670
+ var FLAG_REMOTE_PARENT = 512;
1671
+ var MAX_STATUS_MESSAGE = 1024;
1672
+ var str = (key, value) => value != null && value !== "" ? { key, value: { stringValue: value } } : null;
1673
+ var strAllowEmpty = (key, value) => value != null ? { key, value: { stringValue: value } } : null;
1674
+ var int = (key, value) => typeof value === "number" && Number.isFinite(value) ? { key, value: { intValue: String(Math.trunc(value)) } } : null;
1675
+ var dbl = (key, value) => typeof value === "number" && Number.isFinite(value) ? { key, value: { doubleValue: value } } : null;
1676
+ var bool = (key, value) => typeof value === "boolean" ? { key, value: { boolValue: value } } : null;
1677
+ var strArray = (key, values) => ({
1678
+ key,
1679
+ value: { arrayValue: { values: values.map((value) => ({ stringValue: value })) } }
1680
+ });
1681
+ var compact = (list) => list.filter((entry) => Boolean(entry));
1682
+ function msToNs(ms) {
1683
+ const whole = Math.floor(ms);
1684
+ return BigInt(whole) * 1000000n + BigInt(Math.round((ms - whole) * 1e6));
1685
+ }
1686
+ function parseMs(iso) {
1687
+ if (!iso) return void 0;
1688
+ const value = Date.parse(iso);
1689
+ return Number.isNaN(value) ? void 0 : value;
1690
+ }
1691
+ function durationNs(durationMs) {
1692
+ return typeof durationMs === "number" && Number.isFinite(durationMs) && durationMs > 0 ? msToNs(durationMs) : 0n;
1693
+ }
1694
+ function classify(event) {
1695
+ if (event.type === "ai_call" || event.type === "summarization") {
1696
+ if (event.skipReason === "cancelled") return "chat";
1697
+ if (event.skipReason || event.status === "skipped") return "plain";
1698
+ return "chat";
1699
+ }
1700
+ if (event.type === "tool_call") {
1701
+ const source = event.debug?.shortCircuitSource;
1702
+ if (event.skipReason || event.status === "skipped" || source === "cache" || source === "plugin") return "plain";
1703
+ if (event.status === "pending") return "plain";
1704
+ return "execute_tool";
1705
+ }
1706
+ if (event.type === "span" && event.actor?.role === "subagent") return "invoke_agent";
1707
+ return "plain";
1708
+ }
1709
+ var knownModel = (model) => model && model !== "unknown-model" && model !== "unknown_model" ? model : void 0;
1710
+ function toolNameOf(event) {
1711
+ if (event.actor?.name) return event.actor.name;
1712
+ const label = event.label.replace(/\s#\d+$/, "");
1713
+ const dash = label.indexOf(" - ");
1714
+ return dash >= 0 ? label.slice(dash + 3) : void 0;
1715
+ }
1716
+ var stripSequence = (label) => label.replace(/\s#\d+$/, "");
1717
+ function cappedMessage(message) {
1718
+ const text = message && message.length > 0 ? message : "Unknown error";
1719
+ return text.length > MAX_STATUS_MESSAGE ? text.slice(0, MAX_STATUS_MESSAGE) : text;
1720
+ }
1721
+ function exceptionEvent(timeNs, error) {
1722
+ return {
1723
+ timeUnixNano: timeNs.toString(),
1724
+ name: "exception",
1725
+ attributes: compact([
1726
+ str("exception.type", errorTypeOf(error)),
1727
+ strAllowEmpty("exception.message", error.message ?? "Unknown error"),
1728
+ str("exception.stacktrace", error.stack)
1729
+ ])
1730
+ };
1731
+ }
1732
+ function sessionToOtlp(file, options) {
1733
+ const useCognipeer = options.semconv !== "gen_ai";
1734
+ const useGenAi = options.semconv !== "cognipeer";
1735
+ const traceId = file.traceId || generateTraceId();
1736
+ const rootSpanId = file.rootSpanId || generateSpanId();
1737
+ const parent = options.parent;
1738
+ const traceState = parent?.traceState || void 0;
1739
+ const traceFlags = (typeof parent?.flags === "number" ? parent.flags : 1) & 255;
1740
+ const flags = traceFlags | FLAG_HAS_PARENT;
1741
+ const rootFlags = parent?.remote ? flags | FLAG_REMOTE_PARENT : flags;
1742
+ const agentName = file.agent?.name;
1743
+ const everyEvent = file.events;
1744
+ const exportedEvents = foldSupersededSpans(everyEvent).filter(
1745
+ (event) => options.terminal || !(event.type === "span" && event.status === "pending")
1746
+ );
1747
+ const startMs = parseMs(file.startedAt);
1748
+ const nodes = exportedEvents.map((event) => {
1749
+ const endMs = parseMs(event.timestamp) ?? startMs ?? Date.now();
1750
+ const endNs = msToNs(endMs);
1751
+ let startNs = endNs - durationNs(event.durationMs);
1752
+ if (startNs < 0n) startNs = 0n;
1753
+ return {
1754
+ event,
1755
+ spanId: event.spanId || generateSpanId(),
1756
+ parentId: event.parentSpanId || rootSpanId,
1757
+ startNs,
1758
+ endNs
1759
+ };
1760
+ });
1761
+ const childrenOf = /* @__PURE__ */ new Map();
1762
+ for (const node of nodes) {
1763
+ const list = childrenOf.get(node.parentId);
1764
+ if (list) list.push(node);
1765
+ else childrenOf.set(node.parentId, [node]);
1766
+ }
1767
+ const settled = /* @__PURE__ */ new Set();
1768
+ const inProgress = /* @__PURE__ */ new Set();
1769
+ const widen = (node) => {
1770
+ if (settled.has(node) || inProgress.has(node)) return;
1771
+ inProgress.add(node);
1772
+ for (const child of childrenOf.get(node.spanId) ?? []) {
1773
+ if (child === node) continue;
1774
+ widen(child);
1775
+ if (child.startNs < node.startNs) node.startNs = child.startNs;
1776
+ if (child.endNs > node.endNs) node.endNs = child.endNs;
1777
+ }
1778
+ inProgress.delete(node);
1779
+ settled.add(node);
1780
+ };
1781
+ for (const node of nodes) widen(node);
1782
+ const byId = /* @__PURE__ */ new Map();
1783
+ for (const event of everyEvent) if (event.spanId) byId.set(event.spanId, event);
1784
+ const agentOf = (event) => {
1785
+ let cursor = event;
1786
+ for (let hops = 0; cursor && hops < 64; hops++) {
1787
+ if (cursor !== event && cursor.type === "span" && cursor.actor?.role === "subagent") return cursor.actor.name;
1788
+ cursor = cursor.parentSpanId ? byId.get(cursor.parentSpanId) : void 0;
1789
+ }
1790
+ return agentName;
1791
+ };
1792
+ const spans = [];
1793
+ const sessionErrors = (file.errors ?? []).filter((error) => error.eventId === "session");
1794
+ if (options.terminal) {
1795
+ const earliestChild = nodes.reduce(
1796
+ (earliest, node) => earliest === void 0 || node.startNs < earliest ? node.startNs : earliest,
1797
+ void 0
1798
+ );
1799
+ let rootStart = startMs !== void 0 ? msToNs(startMs) : earliestChild ?? msToNs(Date.now());
1800
+ let rootEnd = msToNs(parseMs(file.endedAt) ?? (startMs !== void 0 ? startMs + (file.durationMs ?? 0) : Date.now()));
1801
+ for (const node of childrenOf.get(rootSpanId) ?? []) {
1802
+ if (node.startNs < rootStart) rootStart = node.startNs;
1803
+ if (node.endNs > rootEnd) rootEnd = node.endNs;
1804
+ }
1805
+ if (rootEnd < rootStart) rootEnd = rootStart;
1806
+ const rootName = useGenAi ? agentName ? `${OPERATION.invokeAgent} ${agentName}` : OPERATION.invokeAgent : `agent_session: ${agentName || "agent"}`;
1807
+ const summary = file.summary;
1808
+ const cumulativeEvents = summary?.eventCounts ? Object.values(summary.eventCounts).reduce((total, count) => total + (Number(count) || 0), 0) : file.events.length;
1809
+ const attributes = [];
1810
+ if (useCognipeer) {
1811
+ attributes.push(
1812
+ ...compact([
1813
+ strAllowEmpty("cognipeer.session.status", options.cancelled ? "partial" : file.status),
1814
+ dbl("cognipeer.session.duration_ms", file.durationMs),
1815
+ int("cognipeer.session.total_input_tokens", summary?.totalInputTokens),
1816
+ int("cognipeer.session.total_output_tokens", summary?.totalOutputTokens),
1817
+ int("cognipeer.session.total_cached_input_tokens", summary?.totalCachedInputTokens),
1818
+ int("cognipeer.session.total_bytes_in", summary?.totalBytesIn),
1819
+ int("cognipeer.session.total_bytes_out", summary?.totalBytesOut),
1820
+ int("cognipeer.session.event_count", cumulativeEvents)
1821
+ ])
1822
+ );
1823
+ for (const [key, count] of Object.entries(summary?.eventCounts ?? {})) {
1824
+ attributes.push({ key: `cognipeer.session.event_count.${key}`, value: { intValue: String(count) } });
1825
+ }
1826
+ }
1827
+ if (useGenAi) {
1828
+ attributes.push(
1829
+ ...compact([
1830
+ str(ATTR.operationName, OPERATION.invokeAgent),
1831
+ str(ATTR.agentName, agentName),
1832
+ str(ATTR.agentVersion, file.agent?.version),
1833
+ str(ATTR.requestModel, knownModel(file.agent?.model)),
1834
+ str(ATTR.conversationId, file.threadId)
1835
+ ])
1836
+ );
1837
+ }
1838
+ const root = {
1839
+ traceId,
1840
+ spanId: rootSpanId,
1841
+ parentSpanId: parent?.spanId ?? "",
1842
+ ...traceState ? { traceState } : {},
1843
+ flags: rootFlags,
1844
+ name: rootName,
1845
+ kind: SPAN_KIND_INTERNAL,
1846
+ startTimeUnixNano: rootStart.toString(),
1847
+ endTimeUnixNano: rootEnd.toString(),
1848
+ attributes,
1849
+ status: { code: 0 }
1850
+ };
1851
+ if (sessionErrors.length > 0) {
1852
+ root.status = {
1853
+ code: 2,
1854
+ message: cappedMessage(sessionErrors.map((error) => error.message).join("; "))
1855
+ };
1856
+ if (useGenAi) root.attributes.push({ key: ATTR.errorType, value: { stringValue: errorTypeOf({ type: sessionErrors[0].errorName, stack: sessionErrors[0].stack }) } });
1857
+ root.events = sessionErrors.map((error) => {
1858
+ const at = parseMs(error.timestamp);
1859
+ return exceptionEvent(at !== void 0 ? msToNs(at) : rootEnd, {
1860
+ message: error.message,
1861
+ stack: error.stack,
1862
+ type: error.errorName
1863
+ });
1864
+ });
1865
+ }
1866
+ spans.push(root);
1867
+ }
1868
+ for (const node of nodes) {
1869
+ const event = node.event;
1870
+ const kind = classify(event);
1871
+ const failed = event.status === "error";
1872
+ const cancelledChat = kind === "chat" && event.skipReason === "cancelled";
1873
+ const attributes = [];
1874
+ if (useCognipeer) {
1875
+ attributes.push(
1876
+ ...compact([
1877
+ strAllowEmpty("cognipeer.event.type", event.type),
1878
+ strAllowEmpty("cognipeer.event.label", event.label),
1879
+ int("cognipeer.event.sequence", event.sequence),
1880
+ strAllowEmpty("cognipeer.actor.scope", event.actor?.scope),
1881
+ strAllowEmpty("cognipeer.actor.name", event.actor?.name),
1882
+ strAllowEmpty("cognipeer.actor.role", event.actor?.role),
1883
+ strAllowEmpty("cognipeer.model", event.model),
1884
+ int("cognipeer.tokens.reasoning", event.reasoningTokens),
1885
+ strAllowEmpty("cognipeer.finish_reason", event.finishReason),
1886
+ strAllowEmpty("cognipeer.provider", event.provider),
1887
+ strAllowEmpty("cognipeer.tool.details", event.toolDetails ? JSON.stringify(event.toolDetails) : void 0),
1888
+ int("cognipeer.tokens.input", event.inputTokens),
1889
+ int("cognipeer.tokens.output", event.outputTokens),
1890
+ int("cognipeer.tokens.total", event.totalTokens),
1891
+ int("cognipeer.tokens.cached_input", event.cachedInputTokens),
1892
+ int("cognipeer.bytes.request", event.requestBytes),
1893
+ int("cognipeer.bytes.response", event.responseBytes),
1894
+ strAllowEmpty("cognipeer.tool.execution_id", event.toolExecutionId),
1895
+ strAllowEmpty("cognipeer.retry_of", event.retryOf),
1896
+ strAllowEmpty("cognipeer.event.id", event.id)
1897
+ ])
1898
+ );
1899
+ const sectionsAttr = sectionsAttribute(event.data?.sections, event, options.content);
1900
+ if (sectionsAttr) attributes.push(sectionsAttr);
1901
+ attributes.push({ key: "cognipeer.event.status", value: { stringValue: event.status } });
1902
+ }
1903
+ let name = event.label || event.type;
1904
+ let spanKind = SPAN_KIND_INTERNAL;
1905
+ if (kind === "chat") spanKind = SPAN_KIND_CLIENT;
1906
+ if (useGenAi) {
1907
+ const conversation = str(ATTR.conversationId, file.threadId);
1908
+ if (kind === "chat") {
1909
+ const model = knownModel(event.model);
1910
+ name = model ? `${OPERATION.chat} ${model}` : OPERATION.chat;
1911
+ attributes.push(
1912
+ ...compact([
1913
+ str(ATTR.operationName, OPERATION.chat),
1914
+ str(ATTR.providerName, genAiProviderName(event.provider)),
1915
+ str(ATTR.requestModel, model),
1916
+ str(ATTR.responseModel, event.responseModel),
1917
+ str(ATTR.responseId, event.responseId),
1918
+ bool(ATTR.requestStream, event.streaming),
1919
+ str(ATTR.outputType, event.outputType)
1920
+ ])
1921
+ );
1922
+ if (failed || cancelledChat) {
1923
+ attributes.push(strArray(ATTR.finishReasons, ["error"]));
1924
+ } else {
1925
+ const reason = event.rawFinishReason ?? event.finishReason;
1926
+ if (reason) attributes.push(strArray(ATTR.finishReasons, [reason]));
1927
+ }
1928
+ const usageAllowed = !failed && !cancelledChat && (event.type !== "summarization" || event.debug?.usageFromModel === true);
1929
+ const usage = usageAllowed ? genAiUsageOf(event) : void 0;
1930
+ if (usage) {
1931
+ attributes.push(
1932
+ ...compact([
1933
+ int(ATTR.usageInput, usage.input),
1934
+ int(ATTR.usageOutput, usage.output),
1935
+ int(ATTR.usageCacheRead, usage.cacheRead),
1936
+ int(ATTR.usageCacheWrite, usage.cacheWrite),
1937
+ int(ATTR.usageReasoning, usage.reasoning)
1938
+ ])
1939
+ );
1940
+ }
1941
+ if (conversation) attributes.push(conversation);
1942
+ attributes.push(...contentAttributes("chat", event, genAiProviderName(event.provider), options.content));
1943
+ } else if (kind === "execute_tool") {
1944
+ const tool = toolNameOf(event);
1945
+ name = tool ? `${OPERATION.executeTool} ${tool}` : OPERATION.executeTool;
1946
+ attributes.push(
1947
+ ...compact([
1948
+ str(ATTR.operationName, OPERATION.executeTool),
1949
+ str(ATTR.toolName, tool),
1950
+ str(ATTR.toolCallId, event.toolCallId),
1951
+ str(ATTR.toolType, "function"),
1952
+ str(ATTR.agentName, agentOf(event)),
1953
+ conversation
1954
+ ])
1955
+ );
1956
+ attributes.push(...contentAttributes("execute_tool", event, void 0, options.content));
1957
+ } else if (kind === "invoke_agent") {
1958
+ const child = event.actor?.name;
1959
+ name = child ? `${OPERATION.invokeAgent} ${child}` : OPERATION.invokeAgent;
1960
+ attributes.push(...compact([str(ATTR.operationName, OPERATION.invokeAgent), str(ATTR.agentName, child), conversation]));
1961
+ } else {
1962
+ name = stripSequence(name);
1963
+ }
1964
+ }
1965
+ const span = {
1966
+ traceId: event.traceId || traceId,
1967
+ spanId: node.spanId,
1968
+ parentSpanId: node.parentId,
1969
+ ...traceState ? { traceState } : {},
1970
+ flags,
1971
+ name,
1972
+ kind: spanKind,
1973
+ startTimeUnixNano: node.startNs.toString(),
1974
+ endTimeUnixNano: node.endNs.toString(),
1975
+ attributes,
1976
+ status: { code: 0 }
1977
+ };
1978
+ if (failed) {
1979
+ const error = event.error ?? { message: "Unknown error" };
1980
+ span.status = { code: 2, message: cappedMessage(error.message) };
1981
+ if (useGenAi) attributes.push({ key: ATTR.errorType, value: { stringValue: errorTypeOf(error) } });
1982
+ span.events = [exceptionEvent(node.endNs, error)];
1983
+ }
1984
+ spans.push(span);
1985
+ }
1986
+ return {
1987
+ resourceSpans: [
1988
+ {
1989
+ resource: { attributes: resourceAttributesOf(file, options, useCognipeer) },
1990
+ scopeSpans: [{ scope: { name: SCOPE_NAME, version: SDK_VERSION }, spans }]
1991
+ }
1992
+ ]
1993
+ };
1994
+ }
1995
+ function resourceAttributesOf(file, options, useCognipeer) {
1996
+ const custom = options.resourceAttributes ?? {};
1997
+ const serviceName = options.serviceName || custom["service.name"] || file.agent?.name || "cognipeer-agent";
1998
+ const attributes = compact([
1999
+ str("service.name", serviceName),
2000
+ str("service.version", file.agent?.version)
2001
+ ]);
2002
+ if (useCognipeer) {
2003
+ attributes.push(
2004
+ ...compact([
2005
+ str("cognipeer.session.id", file.sessionId),
2006
+ str("cognipeer.thread.id", file.threadId),
2007
+ str("cognipeer.agent.model", file.agent?.model),
2008
+ str("cognipeer.agent.provider", file.agent?.provider),
2009
+ ...Object.entries(file.metadata ?? {}).map(([key, value]) => str(`cognipeer.metadata.${key}`, value))
2010
+ ])
2011
+ );
2012
+ }
2013
+ attributes.push(
2014
+ ...compact([
2015
+ str("telemetry.sdk.name", SCOPE_NAME),
2016
+ str("telemetry.sdk.language", "nodejs"),
2017
+ str("telemetry.sdk.version", SDK_VERSION)
2018
+ ])
2019
+ );
2020
+ for (const [key, value] of Object.entries(custom)) {
2021
+ if (key === "service.name") continue;
2022
+ const index = attributes.findIndex((attr) => attr.key === key);
2023
+ const entry = str(key, value);
2024
+ if (!entry) continue;
2025
+ if (index >= 0) attributes[index] = entry;
2026
+ else attributes.push(entry);
2027
+ }
2028
+ return attributes;
2029
+ }
2030
+ function countSpans(request) {
2031
+ let total = 0;
2032
+ for (const rs of request.resourceSpans) for (const ss of rs.scopeSpans) total += ss.spans.length;
2033
+ return total;
2034
+ }
2035
+
2036
+ // src/utils/otlp/env.ts
2037
+ var warned = /* @__PURE__ */ new Set();
2038
+ function warnOnce(message) {
2039
+ if (warned.has(message)) return;
2040
+ warned.add(message);
2041
+ if (typeof console !== "undefined" && typeof console.warn === "function") console.warn(message);
2042
+ }
2043
+ function pick(env, ...names) {
2044
+ for (const name of names) {
2045
+ const value = env[name];
2046
+ if (typeof value === "string" && value.trim().length > 0) return value.trim();
2047
+ }
2048
+ return void 0;
2049
+ }
2050
+ function decode(value) {
2051
+ try {
2052
+ return decodeURIComponent(value);
2053
+ } catch {
2054
+ return value;
2055
+ }
2056
+ }
2057
+ function parseKeyValueList(raw) {
2058
+ const out = {};
2059
+ if (!raw) return out;
2060
+ for (const part of raw.split(",")) {
2061
+ const index = part.indexOf("=");
2062
+ if (index <= 0) continue;
2063
+ const key = part.slice(0, index).trim();
2064
+ if (!key) continue;
2065
+ out[key] = decode(part.slice(index + 1).trim());
2066
+ }
2067
+ return out;
2068
+ }
2069
+ function tracesEndpointFrom(base) {
2070
+ return `${base.replace(/\/+$/, "")}/v1/traces`;
2071
+ }
2072
+ function protocolFrom(raw, fallback) {
2073
+ if (!raw) return fallback;
2074
+ const value = raw.toLowerCase();
2075
+ if (value === "http/protobuf" || value === "http/json") return value;
2076
+ warnOnce(
2077
+ 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}.`
2078
+ );
2079
+ return fallback;
2080
+ }
2081
+ function resolveOtlpEnv(env, explicit) {
2082
+ const explicitEndpoint = typeof explicit.endpoint === "string" ? explicit.endpoint.trim() : "";
2083
+ const envDriven = explicitEndpoint.length === 0;
2084
+ const resourceAttributes = parseKeyValueList(pick(env, "OTEL_RESOURCE_ATTRIBUTES"));
2085
+ const serviceName = pick(env, "OTEL_SERVICE_NAME");
2086
+ if (!envDriven) {
2087
+ return {
2088
+ envDriven,
2089
+ endpoint: explicitEndpoint,
2090
+ headers: { ...explicit.headers ?? {} },
2091
+ protocol: explicit.protocol ?? "http/json",
2092
+ compression: explicit.compression ?? "none",
2093
+ timeoutMs: explicit.timeoutMs,
2094
+ serviceName,
2095
+ resourceAttributes,
2096
+ disabled: false
2097
+ };
2098
+ }
2099
+ const tracesEndpoint = pick(env, "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT");
2100
+ const baseEndpoint = pick(env, "OTEL_EXPORTER_OTLP_ENDPOINT");
2101
+ const endpoint = tracesEndpoint ?? (baseEndpoint ? tracesEndpointFrom(baseEndpoint) : void 0);
2102
+ const envHeaders = {
2103
+ ...parseKeyValueList(pick(env, "OTEL_EXPORTER_OTLP_HEADERS")),
2104
+ ...parseKeyValueList(pick(env, "OTEL_EXPORTER_OTLP_TRACES_HEADERS"))
2105
+ };
2106
+ const timeoutRaw = pick(env, "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT", "OTEL_EXPORTER_OTLP_TIMEOUT");
2107
+ const timeout = timeoutRaw !== void 0 ? Number(timeoutRaw) : void 0;
2108
+ const compressionRaw = pick(env, "OTEL_EXPORTER_OTLP_TRACES_COMPRESSION", "OTEL_EXPORTER_OTLP_COMPRESSION")?.toLowerCase();
2109
+ return {
2110
+ envDriven,
2111
+ endpoint,
2112
+ headers: { ...envHeaders, ...explicit.headers ?? {} },
2113
+ protocol: explicit.protocol ?? protocolFrom(pick(env, "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "OTEL_EXPORTER_OTLP_PROTOCOL"), "http/protobuf"),
2114
+ compression: explicit.compression ?? (compressionRaw === "gzip" ? "gzip" : "none"),
2115
+ timeoutMs: explicit.timeoutMs ?? (timeout !== void 0 && Number.isFinite(timeout) && timeout > 0 ? timeout : void 0),
2116
+ serviceName,
2117
+ resourceAttributes,
2118
+ disabled: pick(env, "OTEL_SDK_DISABLED")?.toLowerCase() === "true" || pick(env, "OTEL_TRACES_EXPORTER")?.toLowerCase() === "none"
2119
+ };
2120
+ }
2121
+ function currentEnv() {
2122
+ return typeof process !== "undefined" && process.env ? process.env : {};
2123
+ }
2124
+ var WIRE_VARINT = 0;
2125
+ var WIRE_FIXED64 = 1;
2126
+ var WIRE_LEN = 2;
2127
+ var WIRE_FIXED32 = 5;
2128
+ var textEncoder = new TextEncoder();
2129
+ var Writer = class {
2130
+ constructor() {
2131
+ this.buf = new Uint8Array(128);
2132
+ this.len = 0;
2133
+ this.view = new DataView(this.buf.buffer);
2134
+ }
2135
+ ensure(extra) {
2136
+ if (this.len + extra <= this.buf.length) return;
2137
+ let size = this.buf.length * 2;
2138
+ while (size < this.len + extra) size *= 2;
2139
+ const next = new Uint8Array(size);
2140
+ next.set(this.buf.subarray(0, this.len));
2141
+ this.buf = next;
2142
+ this.view = new DataView(next.buffer);
2143
+ }
2144
+ byte(value) {
2145
+ this.ensure(1);
2146
+ this.buf[this.len++] = value;
2147
+ }
2148
+ varint(value) {
2149
+ if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) {
2150
+ let n2 = value;
2151
+ while (n2 >= 128) {
2152
+ this.byte(n2 % 128 | 128);
2153
+ n2 = Math.floor(n2 / 128);
2154
+ }
2155
+ this.byte(n2);
2156
+ return;
2157
+ }
2158
+ let n = BigInt.asUintN(64, BigInt(value));
2159
+ while (n >= 128n) {
2160
+ this.byte(Number(n & 127n) | 128);
2161
+ n >>= 7n;
2162
+ }
2163
+ this.byte(Number(n));
2164
+ }
2165
+ tag(field, wire) {
2166
+ this.varint(field * 8 + wire);
2167
+ }
2168
+ raw(bytes) {
2169
+ this.ensure(bytes.length);
2170
+ this.buf.set(bytes, this.len);
2171
+ this.len += bytes.length;
2172
+ }
2173
+ fixed64(value) {
2174
+ this.ensure(8);
2175
+ this.view.setBigUint64(this.len, BigInt.asUintN(64, value), true);
2176
+ this.len += 8;
2177
+ }
2178
+ fixed32(value) {
2179
+ this.ensure(4);
2180
+ this.view.setUint32(this.len, value >>> 0, true);
2181
+ this.len += 4;
2182
+ }
2183
+ double(value) {
2184
+ this.ensure(8);
2185
+ this.view.setFloat64(this.len, value, true);
2186
+ this.len += 8;
2187
+ }
2188
+ finish() {
2189
+ return this.buf.slice(0, this.len);
2190
+ }
2191
+ };
2192
+ function lenField(w, field, bytes) {
2193
+ w.tag(field, WIRE_LEN);
2194
+ w.varint(bytes.length);
2195
+ w.raw(bytes);
2196
+ }
2197
+ function stringField(w, field, value) {
2198
+ if (!value) return;
2199
+ lenField(w, field, textEncoder.encode(value));
2200
+ }
2201
+ function hexBytes(hex, bytes) {
2202
+ if (!hex) return void 0;
2203
+ const out = new Uint8Array(bytes);
2204
+ for (let i = 0; i < bytes; i++) {
2205
+ const pair = hex.slice(i * 2, i * 2 + 2);
2206
+ const value = /^[0-9a-fA-F]{2}$/.test(pair) ? parseInt(pair, 16) : 0;
2207
+ out[i] = value;
2208
+ }
2209
+ return out;
2210
+ }
2211
+ function base64Bytes(value) {
2212
+ return new Uint8Array(Buffer$1.from(value, "base64"));
2213
+ }
2214
+ function encodeAnyValue(value) {
2215
+ const w = new Writer();
2216
+ if (value.stringValue !== void 0) {
2217
+ lenField(w, 1, textEncoder.encode(value.stringValue));
2218
+ } else if (value.boolValue !== void 0) {
2219
+ w.tag(2, WIRE_VARINT);
2220
+ w.varint(value.boolValue ? 1 : 0);
2221
+ } else if (value.intValue !== void 0) {
2222
+ w.tag(3, WIRE_VARINT);
2223
+ w.varint(BigInt(value.intValue));
2224
+ } else if (value.doubleValue !== void 0) {
2225
+ w.tag(4, WIRE_FIXED64);
2226
+ w.double(value.doubleValue);
2227
+ } else if (value.arrayValue !== void 0) {
2228
+ const inner = new Writer();
2229
+ for (const item of value.arrayValue.values) lenField(inner, 1, encodeAnyValue(item));
2230
+ lenField(w, 5, inner.finish());
2231
+ } else if (value.kvlistValue !== void 0) {
2232
+ const inner = new Writer();
2233
+ for (const kv of value.kvlistValue.values) lenField(inner, 1, encodeKeyValue(kv));
2234
+ lenField(w, 6, inner.finish());
2235
+ } else if (value.bytesValue !== void 0) {
2236
+ lenField(w, 7, base64Bytes(value.bytesValue));
2237
+ }
2238
+ return w.finish();
2239
+ }
2240
+ function encodeKeyValue(kv) {
2241
+ const w = new Writer();
2242
+ stringField(w, 1, kv.key);
2243
+ lenField(w, 2, encodeAnyValue(kv.value));
2244
+ return w.finish();
2245
+ }
2246
+ function encodeSpanEvent(event) {
2247
+ const w = new Writer();
2248
+ w.tag(1, WIRE_FIXED64);
2249
+ w.fixed64(BigInt(event.timeUnixNano));
2250
+ stringField(w, 2, event.name);
2251
+ for (const attr of event.attributes) lenField(w, 3, encodeKeyValue(attr));
2252
+ return w.finish();
2253
+ }
2254
+ function encodeSpan(span) {
2255
+ const w = new Writer();
2256
+ const traceId = hexBytes(span.traceId, 16);
2257
+ if (traceId) lenField(w, 1, traceId);
2258
+ const spanId = hexBytes(span.spanId, 8);
2259
+ if (spanId) lenField(w, 2, spanId);
2260
+ stringField(w, 3, span.traceState);
2261
+ const parent = hexBytes(span.parentSpanId, 8);
2262
+ if (parent) lenField(w, 4, parent);
2263
+ stringField(w, 5, span.name);
2264
+ if (span.kind) {
2265
+ w.tag(6, WIRE_VARINT);
2266
+ w.varint(span.kind);
2267
+ }
2268
+ w.tag(7, WIRE_FIXED64);
2269
+ w.fixed64(BigInt(span.startTimeUnixNano));
2270
+ w.tag(8, WIRE_FIXED64);
2271
+ w.fixed64(BigInt(span.endTimeUnixNano));
2272
+ for (const attr of span.attributes) lenField(w, 9, encodeKeyValue(attr));
2273
+ for (const event of span.events ?? []) lenField(w, 11, encodeSpanEvent(event));
2274
+ const status = new Writer();
2275
+ stringField(status, 2, span.status.message);
2276
+ if (span.status.code) {
2277
+ status.tag(3, WIRE_VARINT);
2278
+ status.varint(span.status.code);
2279
+ }
2280
+ lenField(w, 15, status.finish());
2281
+ if (span.flags) {
2282
+ w.tag(16, WIRE_FIXED32);
2283
+ w.fixed32(span.flags);
2284
+ }
2285
+ return w.finish();
2286
+ }
2287
+ function encodeExportTraceServiceRequest(request) {
2288
+ const w = new Writer();
2289
+ for (const rs of request.resourceSpans) {
2290
+ const resourceSpans = new Writer();
2291
+ const resource = new Writer();
2292
+ for (const attr of rs.resource.attributes) lenField(resource, 1, encodeKeyValue(attr));
2293
+ lenField(resourceSpans, 1, resource.finish());
2294
+ for (const ss of rs.scopeSpans) {
2295
+ const scopeSpans = new Writer();
2296
+ const scope = new Writer();
2297
+ stringField(scope, 1, ss.scope.name);
2298
+ stringField(scope, 2, ss.scope.version);
2299
+ lenField(scopeSpans, 1, scope.finish());
2300
+ for (const span of ss.spans) lenField(scopeSpans, 2, encodeSpan(span));
2301
+ lenField(resourceSpans, 2, scopeSpans.finish());
2302
+ }
2303
+ stringField(resourceSpans, 3, rs.schemaUrl);
2304
+ lenField(w, 1, resourceSpans.finish());
2305
+ }
2306
+ return w.finish();
2307
+ }
2308
+ var Reader = class {
2309
+ constructor(bytes) {
2310
+ this.bytes = bytes;
2311
+ this.pos = 0;
2312
+ }
2313
+ get done() {
2314
+ return this.pos >= this.bytes.length;
2315
+ }
2316
+ varint() {
2317
+ let result = 0n;
2318
+ let shift = 0n;
2319
+ for (; ; ) {
2320
+ if (this.pos >= this.bytes.length) throw new Error("truncated varint");
2321
+ const byte = this.bytes[this.pos++];
2322
+ result |= BigInt(byte & 127) << shift;
2323
+ if ((byte & 128) === 0) return result;
2324
+ shift += 7n;
2325
+ if (shift > 70n) throw new Error("varint too long");
2326
+ }
2327
+ }
2328
+ slice(length) {
2329
+ if (this.pos + length > this.bytes.length) throw new Error("truncated field");
2330
+ const out = this.bytes.subarray(this.pos, this.pos + length);
2331
+ this.pos += length;
2332
+ return out;
2333
+ }
2334
+ skip(wire) {
2335
+ if (wire === WIRE_VARINT) this.varint();
2336
+ else if (wire === WIRE_FIXED64) this.slice(8);
2337
+ else if (wire === WIRE_FIXED32) this.slice(4);
2338
+ else if (wire === WIRE_LEN) this.slice(Number(this.varint()));
2339
+ else throw new Error(`unsupported wire type ${wire}`);
2340
+ }
2341
+ };
2342
+ function decodeExportTraceServiceResponse(bytes) {
2343
+ const top = new Reader(bytes);
2344
+ let result;
2345
+ while (!top.done) {
2346
+ const key = Number(top.varint());
2347
+ const field = key >>> 3;
2348
+ const wire = key & 7;
2349
+ if (field === 1 && wire === WIRE_LEN) {
2350
+ const inner = new Reader(top.slice(Number(top.varint())));
2351
+ let rejected = 0n;
2352
+ let message;
2353
+ while (!inner.done) {
2354
+ const innerKey = Number(inner.varint());
2355
+ const innerField = innerKey >>> 3;
2356
+ const innerWire = innerKey & 7;
2357
+ if (innerField === 1 && innerWire === WIRE_VARINT) rejected = BigInt.asIntN(64, inner.varint());
2358
+ else if (innerField === 2 && innerWire === WIRE_LEN) message = new TextDecoder().decode(inner.slice(Number(inner.varint())));
2359
+ else inner.skip(innerWire);
2360
+ }
2361
+ result = { rejectedSpans: Number(rejected), ...message ? { message } : {} };
2362
+ } else {
2363
+ top.skip(wire);
2364
+ }
2365
+ }
2366
+ return result;
2367
+ }
2368
+
2369
+ // src/utils/otlp/exporter.ts
2370
+ var gzipAsync = promisify(gzip);
2371
+ var DEFAULT_TIMEOUT_MS = 1e4;
2372
+ var RETRY_DEFAULTS = {
2373
+ maxAttempts: 3,
2374
+ initialDelayMs: 250,
2375
+ maxDelayMs: 4e3,
2376
+ maxElapsedMs: 25e3
2377
+ };
2378
+ var RETRYABLE_STATUS = /* @__PURE__ */ new Set([429, 502, 503, 504]);
2379
+ function retryPolicy(retry) {
2380
+ if (retry === false) return { ...RETRY_DEFAULTS, maxAttempts: 1 };
2381
+ const merged = { ...RETRY_DEFAULTS, ...retry ?? {} };
2382
+ return { ...merged, maxAttempts: Math.max(1, Math.floor(merged.maxAttempts)) };
2383
+ }
2384
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2385
+ function retryAfterMs(response) {
2386
+ let raw;
2387
+ try {
2388
+ raw = response?.headers?.get?.("retry-after");
2389
+ } catch {
2390
+ return void 0;
2391
+ }
2392
+ if (typeof raw !== "string" || raw.trim() === "") return void 0;
2393
+ const seconds = Number(raw);
2394
+ if (Number.isFinite(seconds)) return Math.max(0, seconds * 1e3);
2395
+ const date = Date.parse(raw);
2396
+ return Number.isNaN(date) ? void 0 : Math.max(0, date - Date.now());
2397
+ }
2398
+ async function attemptOnce(fetchFn, url, init, timeoutMs, protocol) {
2399
+ const controller = new AbortController();
2400
+ let timer;
2401
+ const timeout = new Promise((_, reject) => {
2402
+ timer = setTimeout(() => {
2403
+ controller.abort();
2404
+ reject(new Error(`timed out after ${timeoutMs} ms`));
2405
+ }, timeoutMs);
2406
+ });
2407
+ try {
2408
+ const pending = fetchFn(url, { ...init, signal: controller.signal });
2409
+ Promise.resolve(pending).catch(() => void 0);
2410
+ const response = await Promise.race([pending, timeout]);
2411
+ const status = typeof response?.status === "number" ? response.status : response?.ok ? 200 : 0;
2412
+ const ok = typeof response?.ok === "boolean" ? response.ok : status >= 200 && status < 300;
2413
+ if (ok) {
2414
+ const lateBody = timeout.catch(() => void 0);
2415
+ const partialSuccess = await Promise.race([readPartialSuccess(response, protocol), lateBody]);
2416
+ return { kind: "ok", status, ...partialSuccess ? { partialSuccess } : {} };
2417
+ }
2418
+ let body = "";
2419
+ try {
2420
+ if (typeof response?.text === "function") body = String(await response.text());
2421
+ } catch {
2422
+ }
2423
+ const statusText = typeof response?.statusText === "string" && response.statusText ? ` ${response.statusText}` : "";
2424
+ return {
2425
+ kind: "http",
2426
+ status,
2427
+ message: `HTTP ${status}${statusText}${body ? ` - ${body.slice(0, 200)}` : ""}`,
2428
+ retryable: RETRYABLE_STATUS.has(status),
2429
+ retryAfter: retryAfterMs(response)
2430
+ };
2431
+ } catch (err) {
2432
+ return { kind: "network", message: err instanceof Error ? err.message : String(err) };
2433
+ } finally {
2434
+ if (timer !== void 0) clearTimeout(timer);
2435
+ }
2436
+ }
2437
+ async function readPartialSuccess(response, protocol) {
2438
+ try {
2439
+ if (protocol === "http/protobuf") {
2440
+ if (typeof response?.arrayBuffer !== "function") return void 0;
2441
+ const bytes = new Uint8Array(await response.arrayBuffer());
2442
+ if (bytes.length === 0) return void 0;
2443
+ const decoded = decodeExportTraceServiceResponse(bytes);
2444
+ return decoded && (decoded.rejectedSpans > 0 || decoded.message) ? decoded : void 0;
2445
+ }
2446
+ if (typeof response?.text !== "function") return void 0;
2447
+ const text = String(await response.text());
2448
+ if (!text.trim()) return void 0;
2449
+ const partial = JSON.parse(text)?.partialSuccess;
2450
+ if (!partial || typeof partial !== "object") return void 0;
2451
+ const rejectedSpans = Number(partial.rejectedSpans ?? 0);
2452
+ const message = typeof partial.errorMessage === "string" && partial.errorMessage ? partial.errorMessage : void 0;
2453
+ if (!(rejectedSpans > 0) && !message) return void 0;
2454
+ return { rejectedSpans: Number.isFinite(rejectedSpans) ? rejectedSpans : 0, ...message ? { message } : {} };
2455
+ } catch {
2456
+ return void 0;
2457
+ }
2458
+ }
2459
+ function createOtlpExporter(options = {}) {
2460
+ const env = resolveOtlpEnv(currentEnv(), options);
2461
+ if (!env.endpoint && !env.disabled) {
2462
+ throw new Error(
2463
+ "[agent-sdk] OTLP export needs an `endpoint` (or OTEL_EXPORTER_OTLP_ENDPOINT / OTEL_EXPORTER_OTLP_TRACES_ENDPOINT in the environment)."
2464
+ );
2465
+ }
2466
+ const semconv = options.semconv ?? "both";
2467
+ const protocol = env.protocol;
2468
+ const compression = env.compression;
2469
+ const timeoutMs = env.timeoutMs ?? DEFAULT_TIMEOUT_MS;
2470
+ const policy = retryPolicy(options.retry);
2471
+ const serviceName = options.serviceName ?? env.serviceName;
2472
+ const resourceAttributes = { ...env.resourceAttributes, ...options.resourceAttributes ?? {} };
2473
+ const endpoint = env.endpoint ?? "";
2474
+ const content = resolveContentOptions(options.content);
2475
+ return {
2476
+ name: options.name ?? "otlp",
2477
+ endpoint,
2478
+ semconv,
2479
+ protocol,
2480
+ wantsContent: content.enabled,
2481
+ contentOptions: content,
2482
+ async exportSession(file, run) {
2483
+ try {
2484
+ if (env.disabled) {
2485
+ return { ok: true, skipped: true, reason: "disabled by the environment (OTEL_SDK_DISABLED / OTEL_TRACES_EXPORTER)", attempts: 0, spans: 0, bytes: 0 };
2486
+ }
2487
+ const convertOptions = {
2488
+ semconv,
2489
+ serviceName,
2490
+ resourceAttributes,
2491
+ terminal: run.terminal,
2492
+ cancelled: run.cancelled,
2493
+ parent: run.parent,
2494
+ content
2495
+ };
2496
+ const request = sessionToOtlp(file, convertOptions);
2497
+ const spans = countSpans(request);
2498
+ if (spans === 0) return { ok: true, skipped: true, reason: "no spans to export", attempts: 0, spans: 0, bytes: 0 };
2499
+ const fetchFn = options.fetch ?? (typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0);
2500
+ if (!fetchFn) return { ok: false, attempts: 0, spans, bytes: 0, error: "OTLP export requires fetch to be available in this runtime." };
2501
+ let body = protocol === "http/protobuf" ? encodeExportTraceServiceRequest(request) : JSON.stringify(request);
2502
+ const headers = {
2503
+ "content-type": protocol === "http/protobuf" ? "application/x-protobuf" : "application/json"
2504
+ };
2505
+ if (compression === "gzip") {
2506
+ body = await gzipAsync(typeof body === "string" ? Buffer$1.from(body, "utf8") : body);
2507
+ headers["content-encoding"] = "gzip";
2508
+ }
2509
+ Object.assign(headers, env.headers);
2510
+ const bytes = typeof body === "string" ? Buffer$1.byteLength(body, "utf8") : body.length;
2511
+ const started = Date.now();
2512
+ let attempts = 0;
2513
+ let lastError = "export failed";
2514
+ let lastStatus;
2515
+ for (; ; ) {
2516
+ attempts += 1;
2517
+ const remaining = policy.maxElapsedMs - (Date.now() - started);
2518
+ const outcome = await attemptOnce(
2519
+ fetchFn,
2520
+ env.endpoint,
2521
+ { method: "POST", headers, body },
2522
+ Math.max(1, Math.min(timeoutMs, remaining)),
2523
+ protocol
2524
+ );
2525
+ if (outcome.kind === "ok") {
2526
+ return { ok: true, attempts, status: outcome.status, spans, bytes, ...outcome.partialSuccess ? { partialSuccess: outcome.partialSuccess } : {} };
2527
+ }
2528
+ lastError = outcome.message;
2529
+ lastStatus = outcome.kind === "http" ? outcome.status : void 0;
2530
+ const retryable = outcome.kind === "network" || outcome.retryable;
2531
+ if (!retryable || attempts >= policy.maxAttempts) break;
2532
+ const ceiling = Math.min(policy.maxDelayMs, policy.initialDelayMs * 2 ** (attempts - 1));
2533
+ const wait = outcome.kind === "http" && outcome.retryAfter !== void 0 ? Math.min(outcome.retryAfter, policy.maxDelayMs) : Math.random() * ceiling;
2534
+ if (Date.now() - started + wait >= policy.maxElapsedMs) break;
2535
+ await sleep(wait);
2536
+ }
2537
+ return { ok: false, attempts, ...lastStatus !== void 0 ? { status: lastStatus } : {}, spans, bytes, error: lastError };
2538
+ } catch (err) {
2539
+ return { ok: false, attempts: 0, spans: 0, bytes: 0, error: err instanceof Error ? err.message : String(err) };
2540
+ }
2541
+ }
2542
+ };
2543
+ }
2544
+
2545
+ // src/utils/otlp/context.ts
2546
+ var TRACEPARENT = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})(-.*)?$/;
2547
+ var ALL_ZERO_TRACE = /^0{32}$/;
2548
+ var ALL_ZERO_SPAN = /^0{16}$/;
2549
+ var MAX_TRACESTATE = 512;
2550
+ function parseTraceparent(header) {
2551
+ if (typeof header !== "string") return void 0;
2552
+ const match = TRACEPARENT.exec(header.trim());
2553
+ if (!match) return void 0;
2554
+ const [, version, traceId, spanId, flagsHex, rest] = match;
2555
+ if (version === "ff") return void 0;
2556
+ if (version === "00" && rest) return void 0;
2557
+ if (ALL_ZERO_TRACE.test(traceId) || ALL_ZERO_SPAN.test(spanId)) return void 0;
2558
+ const flags = parseInt(flagsHex, 16);
2559
+ return { traceId, spanId, flags, sampled: (flags & 1) === 1 };
2560
+ }
2561
+ function formatTraceparent(parts) {
2562
+ const flags = typeof parts.flags === "number" ? parts.flags & 255 : parts.sampled === false ? 0 : 1;
2563
+ return `00-${parts.traceId}-${parts.spanId}-${flags.toString(16).padStart(2, "0")}`;
2564
+ }
2565
+ function traceparentOf(ctx) {
2566
+ if (!ctx?.traceId || !ctx.traceSpanId) return void 0;
2567
+ return formatTraceparent({ traceId: ctx.traceId, spanId: ctx.traceSpanId, flags: ctx.traceFlags ?? 1 });
2568
+ }
2569
+ function cleanTraceState(value) {
2570
+ if (typeof value !== "string") return void 0;
2571
+ const trimmed = value.trim();
2572
+ if (!trimmed || trimmed.length > MAX_TRACESTATE || !/^[\x20-\x7e]+$/.test(trimmed)) return void 0;
2573
+ return trimmed;
2574
+ }
2575
+ function resolveTraceParent(input) {
2576
+ if (input === void 0 || input === null) return void 0;
2577
+ const header = typeof input === "string" ? input : input?.traceparent;
2578
+ const parsed = parseTraceparent(header);
2579
+ if (!parsed) {
2580
+ warnOnce("[agent-sdk] Ignoring an invalid W3C traceparent; the trace starts a new root.");
2581
+ return void 0;
2582
+ }
2583
+ const traceState = typeof input === "object" ? cleanTraceState(input.tracestate) : void 0;
2584
+ return {
2585
+ traceId: parsed.traceId,
2586
+ spanId: parsed.spanId,
2587
+ flags: parsed.flags,
2588
+ sampled: parsed.sampled,
2589
+ remote: true,
2590
+ ...traceState ? { traceState } : {}
2591
+ };
2592
+ }
2593
+ function persistedParentOf(parent) {
2594
+ if (!parent) return void 0;
2595
+ return { spanId: parent.spanId, flags: parent.flags, ...parent.traceState ? { traceState: parent.traceState } : {} };
2596
+ }
2597
+ function readPersistedParent(value) {
2598
+ if (!value || typeof value !== "object") return void 0;
2599
+ const raw = value;
2600
+ if (typeof raw.spanId !== "string" || !/^[0-9a-f]{16}$/.test(raw.spanId) || ALL_ZERO_SPAN.test(raw.spanId)) return void 0;
2601
+ const flags = Number(raw.flags);
2602
+ if (!Number.isInteger(flags) || flags < 0 || flags > 255) return void 0;
2603
+ const traceState = cleanTraceState(raw.traceState);
2604
+ return { spanId: raw.spanId, flags, ...traceState ? { traceState } : {} };
2605
+ }
2606
+ function restoreParent(persisted, traceId) {
2607
+ return {
2608
+ traceId,
2609
+ spanId: persisted.spanId,
2610
+ flags: persisted.flags,
2611
+ sampled: (persisted.flags & 1) === 1,
2612
+ remote: true,
2613
+ ...persisted.traceState ? { traceState: persisted.traceState } : {}
2614
+ };
2615
+ }
2616
+
2617
+ // src/utils/tracing.ts
1227
2618
  var DEFAULT_COGNIPEER_URL = "https://console.cognipeer.com/api/client/v1/tracing/sessions";
1228
2619
  function fileSink(path2) {
1229
2620
  return { type: "file", path: path2 };
@@ -1249,8 +2640,9 @@ function cognipeerSink(first, second) {
1249
2640
  function httpSink(url, headers) {
1250
2641
  return { type: "http", url, headers };
1251
2642
  }
1252
- function otlpSink(endpoint, headers) {
1253
- return { type: "otlp", endpoint, headers };
2643
+ function otlpSink(first, headers, options) {
2644
+ if (first !== null && typeof first === "object") return { type: "otlp", ...first };
2645
+ return { type: "otlp", endpoint: first, headers, ...options ?? {} };
1254
2646
  }
1255
2647
  function resolveLogsBaseDir(customPath, ensureDirectory = true) {
1256
2648
  const root = process.cwd();
@@ -1323,23 +2715,23 @@ function extractMetadata(model, paths) {
1323
2715
  if (!model) return void 0;
1324
2716
  for (const path2 of paths) {
1325
2717
  const value = getNestedValue2(model, path2);
1326
- const str = coerceToString(value);
1327
- if (str) return str;
2718
+ const str2 = coerceToString(value);
2719
+ if (str2) return str2;
1328
2720
  }
1329
2721
  const maybeLc = model?._lc;
1330
2722
  if (maybeLc) {
1331
2723
  for (const path2 of paths) {
1332
2724
  const value = getNestedValue2(maybeLc, path2);
1333
- const str = coerceToString(value);
1334
- if (str) return str;
2725
+ const str2 = coerceToString(value);
2726
+ if (str2) return str2;
1335
2727
  }
1336
2728
  }
1337
2729
  const maybeClient = model?.client || model?.api || model?.service;
1338
2730
  if (maybeClient) {
1339
2731
  for (const path2 of paths) {
1340
2732
  const value = getNestedValue2(maybeClient, path2);
1341
- const str = coerceToString(value);
1342
- if (str) return str;
2733
+ const str2 = coerceToString(value);
2734
+ if (str2) return str2;
1343
2735
  }
1344
2736
  }
1345
2737
  const constructorName = model?.constructor?.name;
@@ -1370,8 +2762,8 @@ function inferModelFromMessages(messageList) {
1370
2762
  if (!message) continue;
1371
2763
  for (const path2 of messagePaths) {
1372
2764
  const value = getNestedValue2(message, path2);
1373
- const str = coerceToString(value);
1374
- if (str) return str;
2765
+ const str2 = coerceToString(value);
2766
+ if (str2) return str2;
1375
2767
  }
1376
2768
  }
1377
2769
  return void 0;
@@ -1389,8 +2781,8 @@ function inferProviderFromMessages(messageList) {
1389
2781
  if (!message) continue;
1390
2782
  for (const path2 of messagePaths) {
1391
2783
  const value = getNestedValue2(message, path2);
1392
- const str = coerceToString(value);
1393
- if (str) return str;
2784
+ const str2 = coerceToString(value);
2785
+ if (str2) return str2;
1394
2786
  }
1395
2787
  }
1396
2788
  return void 0;
@@ -1452,12 +2844,18 @@ function resolveSink(sink) {
1452
2844
  return headers ? { type: "http", url, headers } : { type: "http", url };
1453
2845
  }
1454
2846
  case "otlp": {
1455
- const endpoint = typeof candidate.endpoint === "string" ? candidate.endpoint.trim() : "";
1456
- if (!endpoint) {
2847
+ const given = candidate.endpoint;
2848
+ if (given !== void 0 && (typeof given !== "string" || given.trim().length === 0)) {
2849
+ throw new Error("otlp sink requires a non-empty endpoint");
2850
+ }
2851
+ let exporter;
2852
+ try {
2853
+ exporter = createOtlpExporter({ ...candidate, endpoint: given?.trim() });
2854
+ } catch {
1457
2855
  throw new Error("otlp sink requires a non-empty endpoint");
1458
2856
  }
1459
2857
  const headers = candidate.headers ? { ...candidate.headers } : void 0;
1460
- return headers ? { type: "otlp", endpoint, headers } : { type: "otlp", endpoint };
2858
+ return headers ? { type: "otlp", endpoint: exporter.endpoint, headers, exporter } : { type: "otlp", endpoint: exporter.endpoint, exporter };
1461
2859
  }
1462
2860
  default: {
1463
2861
  if (typeof console !== "undefined" && typeof console.warn === "function") {
@@ -1467,6 +2865,17 @@ function resolveSink(sink) {
1467
2865
  }
1468
2866
  }
1469
2867
  }
2868
+ function withoutUserinfo(endpoint) {
2869
+ try {
2870
+ const url = new URL(endpoint);
2871
+ if (!url.username && !url.password) return endpoint;
2872
+ url.username = "";
2873
+ url.password = "";
2874
+ return url.toString();
2875
+ } catch {
2876
+ return endpoint;
2877
+ }
2878
+ }
1470
2879
  function snapshotSink(runtime) {
1471
2880
  const sink = runtime.resolvedConfig.sink;
1472
2881
  switch (sink.type) {
@@ -1479,7 +2888,7 @@ function snapshotSink(runtime) {
1479
2888
  case "http":
1480
2889
  return { type: "http", url: sink.url };
1481
2890
  case "otlp":
1482
- return { type: "otlp", endpoint: sink.endpoint };
2891
+ return { type: "otlp", endpoint: withoutUserinfo(sink.endpoint) };
1483
2892
  default:
1484
2893
  return { type: "custom" };
1485
2894
  }
@@ -1497,11 +2906,11 @@ var TRACE_HTTP_RETRYABLE_STATUS = /* @__PURE__ */ new Set([404, 408, 425, 429, 5
1497
2906
  var TRACE_HTTP_RETRY_BASE_MS = 250;
1498
2907
  var TRACE_HTTP_RETRY_MAX_MS = 4e3;
1499
2908
  var RetryableHttpError = class extends Error {
1500
- constructor(status, message, retryAfterMs) {
2909
+ constructor(status, message, retryAfterMs2) {
1501
2910
  super(message);
1502
2911
  this.name = "RetryableHttpError";
1503
2912
  this.status = status;
1504
- this.retryAfterMs = retryAfterMs;
2913
+ this.retryAfterMs = retryAfterMs2;
1505
2914
  }
1506
2915
  };
1507
2916
  function traceSleep(ms) {
@@ -1594,206 +3003,23 @@ async function postStreamingSessionEnd(baseUrl, headers, payload) {
1594
3003
  const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/end`;
1595
3004
  await postJsonReliable(url, headers, payload, { retry: true });
1596
3005
  }
1597
- function isoToUnixNano(iso) {
1598
- const ms = new Date(iso).getTime();
1599
- return `${ms}000000`;
1600
- }
1601
- function toOtlpStatusCode(status) {
1602
- if (status === "error") return 2;
1603
- if (status === "success" || status === "completed") return 1;
1604
- return 0;
1605
- }
1606
- function toOtlpSpanKind(type) {
1607
- switch (type) {
1608
- case "ai_call":
1609
- case "summarization":
1610
- return 3;
1611
- // CLIENT — outgoing LLM request (the summarizer is one too)
1612
- case "tool_call":
1613
- return 1;
1614
- // INTERNAL
1615
- case "agent_iteration":
1616
- return 1;
1617
- // INTERNAL
1618
- default:
1619
- return 1;
1620
- }
1621
- }
1622
- function stringAttr(key, val) {
1623
- return val != null ? { key, value: { stringValue: val } } : null;
1624
- }
1625
- function intAttr(key, val) {
1626
- return val != null && !Number.isNaN(val) ? { key, value: { intValue: String(val) } } : null;
1627
- }
1628
- function doubleAttr(key, val) {
1629
- return val != null && !Number.isNaN(val) ? { key, value: { doubleValue: val } } : null;
1630
- }
1631
- function eventToOtlpSpan(event) {
1632
- const startNano = isoToUnixNano(event.timestamp);
1633
- const endNano = event.durationMs != null ? `${new Date(new Date(event.timestamp).getTime() + event.durationMs).getTime()}000000` : startNano;
1634
- const attrs = [
1635
- stringAttr("cognipeer.event.type", event.type),
1636
- stringAttr("cognipeer.event.label", event.label),
1637
- intAttr("cognipeer.event.sequence", event.sequence),
1638
- stringAttr("cognipeer.actor.scope", event.actor?.scope),
1639
- stringAttr("cognipeer.actor.name", event.actor?.name),
1640
- stringAttr("cognipeer.actor.role", event.actor?.role),
1641
- stringAttr("cognipeer.model", event.model),
1642
- intAttr("cognipeer.tokens.reasoning", event.reasoningTokens),
1643
- stringAttr("cognipeer.finish_reason", event.finishReason),
1644
- stringAttr("cognipeer.provider", event.provider),
1645
- stringAttr("cognipeer.tool.details", event.toolDetails ? JSON.stringify(event.toolDetails) : void 0),
1646
- intAttr("cognipeer.tokens.input", event.inputTokens),
1647
- intAttr("cognipeer.tokens.output", event.outputTokens),
1648
- intAttr("cognipeer.tokens.total", event.totalTokens),
1649
- intAttr("cognipeer.tokens.cached_input", event.cachedInputTokens),
1650
- intAttr("cognipeer.bytes.request", event.requestBytes),
1651
- intAttr("cognipeer.bytes.response", event.responseBytes),
1652
- stringAttr("cognipeer.tool.execution_id", event.toolExecutionId),
1653
- stringAttr("cognipeer.retry_of", event.retryOf),
1654
- stringAttr("cognipeer.event.id", event.id)
1655
- ].filter(Boolean);
1656
- if (event.data?.sections && event.data.sections.length > 0) {
1657
- try {
1658
- attrs.push({ key: "cognipeer.sections", value: { stringValue: JSON.stringify(event.data.sections) } });
1659
- } catch {
1660
- }
1661
- }
1662
- const span = {
1663
- traceId: event.traceId,
1664
- spanId: event.spanId,
1665
- parentSpanId: event.parentSpanId || "",
1666
- name: event.label || event.type,
1667
- kind: toOtlpSpanKind(event.type),
1668
- startTimeUnixNano: startNano,
1669
- endTimeUnixNano: endNano,
1670
- attributes: attrs,
1671
- status: {
1672
- code: toOtlpStatusCode(event.status),
1673
- ...event.status === "error" && event.error?.message ? { message: event.error.message } : {}
1674
- }
1675
- };
1676
- if (event.error) {
1677
- span.events = [{
1678
- timeUnixNano: startNano,
1679
- name: "exception",
1680
- attributes: [
1681
- { key: "exception.message", value: { stringValue: event.error.message } },
1682
- ...event.error.stack ? [{ key: "exception.stacktrace", value: { stringValue: event.error.stack } }] : []
1683
- ]
1684
- }];
1685
- }
1686
- return span;
1687
- }
1688
- function traceSessionToOtlp(session) {
1689
- const traceId = session.traceId || generateTraceId();
1690
- const rootSpanId = session.rootSpanId || generateSpanId();
1691
- const startNano = isoToUnixNano(session.startedAt);
1692
- const endNano = session.endedAt ? isoToUnixNano(session.endedAt) : startNano;
1693
- const resourceAttrs = [
1694
- { key: "service.name", value: { stringValue: session.agent?.name || "cognipeer-agent" } },
1695
- stringAttr("service.version", session.agent?.version),
1696
- stringAttr("cognipeer.session.id", session.sessionId),
1697
- stringAttr("cognipeer.thread.id", session.threadId),
1698
- stringAttr("cognipeer.agent.model", session.agent?.model),
1699
- stringAttr("cognipeer.agent.provider", session.agent?.provider),
1700
- ...Object.entries(session.metadata || {}).map(([key, value]) => stringAttr(`cognipeer.metadata.${key}`, value))
1701
- ].filter(Boolean);
1702
- const rootAttrs = [
1703
- stringAttr("cognipeer.session.status", session.status),
1704
- doubleAttr("cognipeer.session.duration_ms", session.durationMs),
1705
- intAttr("cognipeer.session.total_input_tokens", session.summary.totalInputTokens),
1706
- intAttr("cognipeer.session.total_output_tokens", session.summary.totalOutputTokens),
1707
- intAttr("cognipeer.session.total_cached_input_tokens", session.summary.totalCachedInputTokens),
1708
- intAttr("cognipeer.session.total_bytes_in", session.summary.totalBytesIn),
1709
- intAttr("cognipeer.session.total_bytes_out", session.summary.totalBytesOut),
1710
- intAttr("cognipeer.session.event_count", session.events.length)
1711
- ].filter(Boolean);
1712
- if (session.summary.eventCounts) {
1713
- for (const [key, count] of Object.entries(session.summary.eventCounts)) {
1714
- rootAttrs.push({ key: `cognipeer.session.event_count.${key}`, value: { intValue: String(count) } });
1715
- }
1716
- }
1717
- const rootSpan = {
1718
- traceId,
1719
- spanId: rootSpanId,
1720
- parentSpanId: "",
1721
- name: `agent_session: ${session.agent?.name || "agent"}`,
1722
- kind: 1,
1723
- // INTERNAL
1724
- startTimeUnixNano: startNano,
1725
- endTimeUnixNano: endNano,
1726
- attributes: rootAttrs,
1727
- status: {
1728
- code: toOtlpStatusCode(session.status),
1729
- ...session.status === "error" && session.errors.length > 0 ? { message: session.errors.map((e) => e.message).join("; ") } : {}
1730
- }
1731
- };
1732
- if (session.errors.length > 0) {
1733
- rootSpan.events = session.errors.map((err) => ({
1734
- timeUnixNano: err.timestamp ? isoToUnixNano(err.timestamp) : startNano,
1735
- name: "exception",
1736
- attributes: [
1737
- { key: "exception.message", value: { stringValue: err.message } },
1738
- ...err.stack ? [{ key: "exception.stacktrace", value: { stringValue: err.stack } }] : [],
1739
- ...err.type ? [{ key: "exception.type", value: { stringValue: err.type } }] : []
1740
- ]
1741
- }));
1742
- }
1743
- const childSpans = session.events.map((event) => {
1744
- const span = eventToOtlpSpan({
1745
- ...event,
1746
- traceId: event.traceId || traceId,
1747
- spanId: event.spanId || generateSpanId(),
1748
- parentSpanId: event.parentSpanId || rootSpanId
1749
- });
1750
- return span;
3006
+ function traceSessionToOtlp(session, options = {}) {
3007
+ return sessionToOtlp(session, {
3008
+ semconv: "both",
3009
+ terminal: session.status !== "paused" && session.status !== "in_progress",
3010
+ ...options,
3011
+ content: resolveContentOptions(options.content)
1751
3012
  });
1752
- return {
1753
- resourceSpans: [{
1754
- resource: { attributes: resourceAttrs },
1755
- scopeSpans: [{
1756
- scope: {
1757
- name: "cognipeer-agent-sdk",
1758
- version: "1.0.0"
1759
- },
1760
- spans: [rootSpan, ...childSpans]
1761
- }]
1762
- }]
1763
- };
1764
3013
  }
1765
- async function postOtlpTraces(endpoint, headers, payload) {
1766
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
1767
- if (!fetchFn) {
1768
- throw new Error("OTLP sink requires fetch to be available in this runtime.");
1769
- }
1770
- const finalHeaders = {
1771
- "content-type": "application/json",
1772
- ...headers || {}
3014
+ function traceErrorOf(err) {
3015
+ const e = err;
3016
+ const message = typeof e?.message === "string" && e.message ? e.message : String(err);
3017
+ const type = err instanceof Error && typeof err.name === "string" && err.name ? err.name : void 0;
3018
+ return {
3019
+ message,
3020
+ ...typeof e?.stack === "string" ? { stack: e.stack } : {},
3021
+ ...type ? { type } : {}
1773
3022
  };
1774
- try {
1775
- const response = await fetchFn(endpoint, {
1776
- method: "POST",
1777
- headers: finalHeaders,
1778
- body: JSON.stringify(payload)
1779
- });
1780
- if (!response.ok) {
1781
- let responseText = "";
1782
- try {
1783
- responseText = await response.text();
1784
- } catch {
1785
- }
1786
- const statusLine = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
1787
- const bodyPreview = responseText ? ` - ${responseText.slice(0, 200)}` : "";
1788
- throw new Error(`${statusLine}${bodyPreview}`);
1789
- }
1790
- } catch (err) {
1791
- const errMsg = err instanceof Error ? err.message : String(err);
1792
- if (typeof console !== "undefined" && typeof console.error === "function") {
1793
- console.error("[Tracing] OTLP export failed:", errMsg);
1794
- }
1795
- throw err;
1796
- }
1797
3023
  }
1798
3024
  function createEmptySummary() {
1799
3025
  return {
@@ -1813,10 +3039,16 @@ function generateEventId(sequence) {
1813
3039
  return `evt_${String(sequence).padStart(4, "0")}_${nanoid(4)}`;
1814
3040
  }
1815
3041
  function generateTraceId() {
1816
- return crypto.randomBytes(16).toString("hex");
3042
+ for (; ; ) {
3043
+ const id = crypto.randomBytes(16).toString("hex");
3044
+ if (/[1-9a-f]/.test(id)) return id;
3045
+ }
1817
3046
  }
1818
3047
  function generateSpanId() {
1819
- return crypto.randomBytes(8).toString("hex");
3048
+ for (; ; ) {
3049
+ const id = crypto.randomBytes(8).toString("hex");
3050
+ if (/[1-9a-f]/.test(id)) return id;
3051
+ }
1820
3052
  }
1821
3053
  function defaultEventLabel(type) {
1822
3054
  switch (type) {
@@ -2093,9 +3325,64 @@ function readTraceContinuation(value) {
2093
3325
  nextSequence,
2094
3326
  part,
2095
3327
  summary,
2096
- errors: Array.isArray(raw.errors) ? raw.errors : []
3328
+ errors: Array.isArray(raw.errors) ? raw.errors : [],
3329
+ ...(() => {
3330
+ const parent = readPersistedParent(raw.parent);
3331
+ return parent ? { parent } : {};
3332
+ })(),
3333
+ ...(() => {
3334
+ const pendingSpans = readPendingSpans(raw.pendingSpans);
3335
+ return pendingSpans.length > 0 ? { pendingSpans } : {};
3336
+ })()
3337
+ };
3338
+ }
3339
+ var MAX_CARRIED_SPANS = 64;
3340
+ var isSubagentSpanRecord = (event) => event.type === "span" && event.actor?.role === "subagent";
3341
+ function carriedSpanOf(record) {
3342
+ const identity2 = (record.data?.sections ?? []).filter(
3343
+ (section) => section.kind === "metadata" && section.identity === true
3344
+ );
3345
+ return {
3346
+ sessionId: record.sessionId,
3347
+ traceId: record.traceId,
3348
+ spanId: record.spanId,
3349
+ parentSpanId: record.parentSpanId,
3350
+ id: record.id,
3351
+ type: record.type,
3352
+ label: record.label,
3353
+ sequence: record.sequence,
3354
+ timestamp: record.timestamp,
3355
+ actor: record.actor,
3356
+ status: record.status,
3357
+ durationMs: record.durationMs,
3358
+ ...identity2.length > 0 ? { data: { sections: identity2 } } : {}
2097
3359
  };
2098
3360
  }
3361
+ function readPendingSpans(value) {
3362
+ if (!Array.isArray(value)) return [];
3363
+ const out = [];
3364
+ for (const item of value.slice(0, MAX_CARRIED_SPANS)) {
3365
+ if (!item || typeof item !== "object") continue;
3366
+ const raw = item;
3367
+ if (typeof raw.spanId !== "string" || raw.spanId.length === 0) continue;
3368
+ if (raw.status !== "pending" || !isSubagentSpanRecord(raw)) continue;
3369
+ if (typeof raw.sequence !== "number" || !Number.isInteger(raw.sequence) || raw.sequence < 1) continue;
3370
+ if (typeof raw.timestamp !== "string" || Number.isNaN(Date.parse(raw.timestamp))) continue;
3371
+ if (typeof raw.label !== "string" || typeof raw.id !== "string" || typeof raw.sessionId !== "string") continue;
3372
+ if (raw.parentSpanId !== void 0 && typeof raw.parentSpanId !== "string") continue;
3373
+ if (raw.durationMs !== void 0 && (typeof raw.durationMs !== "number" || !Number.isFinite(raw.durationMs))) continue;
3374
+ out.push(carriedSpanOf(raw));
3375
+ }
3376
+ return out;
3377
+ }
3378
+ function pendingSpansOf(session) {
3379
+ const candidates = [
3380
+ ...session.carriedSpans ?? [],
3381
+ ...session.events.filter(isSubagentSpanRecord)
3382
+ ];
3383
+ if (candidates.length === 0) return [];
3384
+ return foldSupersededSpans(candidates).filter((event) => event.status === "pending").slice(-MAX_CARRIED_SPANS).map(carriedSpanOf);
3385
+ }
2099
3386
  function traceContinuationOf(session) {
2100
3387
  return {
2101
3388
  v: 1,
@@ -2109,15 +3396,32 @@ function traceContinuationOf(session) {
2109
3396
  summary: JSON.parse(JSON.stringify(session.summary)),
2110
3397
  // Sink failures belong to the part that hit them; carrying them on would
2111
3398
  // mark every later part `partial`.
2112
- errors: session.errors.filter((error) => error.type !== "sink")
3399
+ errors: session.errors.filter((error) => error.type !== "sink"),
3400
+ // Where the root hangs, so the leg that ends the run exports it under the same remote parent.
3401
+ ...session.parent ? { parent: persistedParentOf(session.parent) } : {},
3402
+ ...(() => {
3403
+ const pendingSpans = pendingSpansOf(session);
3404
+ return pendingSpans.length > 0 ? { pendingSpans } : {};
3405
+ })()
2113
3406
  };
2114
3407
  }
2115
- function createTraceSession(opts, continuation) {
3408
+ function createTraceSession(opts, continuation, extras) {
2116
3409
  const cfg = withDefaults(opts.tracing);
2117
3410
  if (!cfg.enabled) return void 0;
3411
+ let parent;
3412
+ if (continuation) {
3413
+ if (continuation.parent && continuation.traceId) parent = restoreParent(continuation.parent, continuation.traceId);
3414
+ } else {
3415
+ parent = resolveTraceParent(extras?.traceParent ?? opts.tracing?.parent);
3416
+ }
3417
+ const exporters = [...extras?.exporters ?? []];
3418
+ const contentExporters = [
3419
+ ...cfg.sink.type === "otlp" ? [cfg.sink.exporter] : [],
3420
+ ...exporters
3421
+ ].filter((exporter) => exporter.wantsContent);
2118
3422
  const providedSessionId = opts.tracing?.sessionId?.trim();
2119
3423
  const sessionId = continuation?.sessionId || providedSessionId || generateSessionId();
2120
- const traceId = continuation?.traceId || generateTraceId();
3424
+ const traceId = continuation?.traceId || parent?.traceId || generateTraceId();
2121
3425
  const rootSpanId = continuation?.rootSpanId || generateSpanId();
2122
3426
  const runtime = {
2123
3427
  sessionId,
@@ -2136,7 +3440,20 @@ function createTraceSession(opts, continuation) {
2136
3440
  // again would reset a streaming receiver's copy.
2137
3441
  sessionStarted: Boolean(continuation),
2138
3442
  sequenceOffset: continuation ? continuation.nextSequence - 1 : 0,
2139
- part: continuation ? continuation.part + 1 : 1
3443
+ part: continuation ? continuation.part + 1 : 1,
3444
+ ...continuation?.pendingSpans?.length ? { carriedSpans: continuation.pendingSpans } : {},
3445
+ ...exporters.length ? { exporters } : {},
3446
+ exportReports: [],
3447
+ ...parent ? { parent } : {},
3448
+ ...contentExporters.length > 0 ? {
3449
+ captureContent: true,
3450
+ captureLimits: {
3451
+ // Headroom over the export cap: a redact hook runs before the cap and must see a
3452
+ // secret whole, even one that straddles the point where the export cuts.
3453
+ maxStringChars: 4 * Math.max(...contentExporters.map((exporter) => exporter.contentOptions?.maxStringChars ?? 4096)),
3454
+ maxMessages: Math.max(...contentExporters.map((exporter) => exporter.contentOptions?.maxMessages ?? 32))
3455
+ }
3456
+ } : {}
2140
3457
  };
2141
3458
  if (cfg.sink.type === "file") {
2142
3459
  const baseDir = cfg.sink.baseDir;
@@ -2252,8 +3569,15 @@ function recordTraceEvent(session, event) {
2252
3569
  }
2253
3570
  }
2254
3571
  }
3572
+ if (!session.resolvedConfig.logData && event.sections?.length) {
3573
+ const identity2 = event.sections.filter((section) => section.kind === "metadata" && section.identity === true);
3574
+ if (identity2.length > 0) sections = ensureUniqueSections(id, identity2);
3575
+ }
2255
3576
  if (event.alwaysSections?.length) {
2256
- sections = ensureUniqueSections(id, [...event.alwaysSections, ...sections ?? []]);
3577
+ const identity2 = event.alwaysSections.map(
3578
+ (section) => section.kind === "metadata" ? { ...section, identity: true } : section
3579
+ );
3580
+ sections = ensureUniqueSections(id, [...identity2, ...sections ?? []]);
2257
3581
  }
2258
3582
  const resolvedModel = event.model ?? inferModelFromMessages(event.messageList);
2259
3583
  const resolvedProvider = event.provider ?? inferProviderFromMessages(event.messageList);
@@ -2289,6 +3613,16 @@ function recordTraceEvent(session, event) {
2289
3613
  // different facts, and a zero would erase the difference.
2290
3614
  ...reasoningTokens !== void 0 && !Number.isNaN(reasoningTokens) ? { reasoningTokens } : {},
2291
3615
  ...event.finishReason ? { finishReason: event.finishReason } : {},
3616
+ // Provider facts: absent when the provider did not say, never zero or empty.
3617
+ ...event.responseId ? { responseId: event.responseId } : {},
3618
+ ...event.responseModel ? { responseModel: event.responseModel } : {},
3619
+ ...event.rawFinishReason ? { rawFinishReason: event.rawFinishReason } : {},
3620
+ ...typeof event.cacheWriteTokens === "number" && event.cacheWriteTokens > 0 ? { cacheWriteTokens: event.cacheWriteTokens } : {},
3621
+ ...event.usageBasis && (event.usageBasis.inputExcludesCache || event.usageBasis.outputExcludesReasoning) ? { usageBasis: { ...event.usageBasis } } : {},
3622
+ ...event.streaming ? { streaming: true } : {},
3623
+ ...event.outputType ? { outputType: event.outputType } : {},
3624
+ ...event.toolCallId ? { toolCallId: event.toolCallId } : {},
3625
+ ...event.skipReason ? { skipReason: event.skipReason } : {},
2292
3626
  requestBytes,
2293
3627
  responseBytes,
2294
3628
  model: resolvedModel,
@@ -2310,6 +3644,15 @@ function recordTraceEvent(session, event) {
2310
3644
  timestamp: timestampIso
2311
3645
  });
2312
3646
  }
3647
+ if (session.captureContent && event.capture) {
3648
+ try {
3649
+ attachCapturedContent(
3650
+ record,
3651
+ buildCapturedContent(event.capture, session.captureLimits ?? { maxStringChars: 4096, maxMessages: 32 })
3652
+ );
3653
+ } catch {
3654
+ }
3655
+ }
2313
3656
  session.events.push(record);
2314
3657
  const sink = session.resolvedConfig.sink;
2315
3658
  if (sink.type === "custom" && typeof sink.onEvent === "function") {
@@ -2404,6 +3747,17 @@ function recordSubagentSpan(session, span) {
2404
3747
  sections
2405
3748
  });
2406
3749
  }
3750
+ function foldSupersededSpans(events) {
3751
+ const rank = (event, index) => typeof event.sequence === "number" && Number.isFinite(event.sequence) ? event.sequence : index;
3752
+ const winner = /* @__PURE__ */ new Map();
3753
+ for (let i = 0; i < events.length; i++) {
3754
+ const id = events[i].spanId;
3755
+ if (!id) continue;
3756
+ const current = winner.get(id);
3757
+ if (current === void 0 || rank(events[i], i) >= rank(events[current], current)) winner.set(id, i);
3758
+ }
3759
+ return events.filter((event, i) => !(event.spanId && event.status === "pending" && winner.get(event.spanId) !== i));
3760
+ }
2407
3761
  function recordOrDeferTraceEvent(ctx, event, options) {
2408
3762
  const session = ctx?.__traceSession;
2409
3763
  if (isTraceSessionOpen(session)) {
@@ -2414,7 +3768,8 @@ function recordOrDeferTraceEvent(ctx, event, options) {
2414
3768
  const held = Array.isArray(ctx?.[DEFERRED_TRACE_EVENTS_KEY]) ? ctx[DEFERRED_TRACE_EVENTS_KEY] : [];
2415
3769
  return {
2416
3770
  ...ctx || {},
2417
- [DEFERRED_TRACE_EVENTS_KEY]: [...held, { ...event, timestamp: event.timestamp ?? (/* @__PURE__ */ new Date()).toISOString() }]
3771
+ // `capture` (content for exporters) is never parked on ctx, which callers persist.
3772
+ [DEFERRED_TRACE_EVENTS_KEY]: [...held, { ...event, capture: void 0, timestamp: event.timestamp ?? (/* @__PURE__ */ new Date()).toISOString() }]
2418
3773
  };
2419
3774
  }
2420
3775
  function replayDeferredTraceEvents(session, deferred) {
@@ -2448,6 +3803,7 @@ async function finalizeTraceSession(session, params = {}) {
2448
3803
  message: params.error.message || "Unknown error",
2449
3804
  stack: params.error.stack,
2450
3805
  type: "session",
3806
+ ...params.error.name ? { errorName: params.error.name } : {},
2451
3807
  timestamp: endedAtIso
2452
3808
  });
2453
3809
  }
@@ -2471,24 +3827,62 @@ async function finalizeTraceSession(session, params = {}) {
2471
3827
  ...(session.part ?? 1) > 1 ? { continuation: { part: session.part, firstSequence: (session.sequenceOffset ?? 0) + 1 } } : {}
2472
3828
  });
2473
3829
  const payloadForSink = buildPayload(initialStatus);
3830
+ const carried = session.carriedSpans ?? [];
3831
+ const exportPayload = carried.length > 0 ? { ...payloadForSink, events: [...carried, ...payloadForSink.events] } : payloadForSink;
2474
3832
  let sinkFailed = false;
2475
3833
  const sink = session.resolvedConfig.sink;
2476
3834
  const isStreamingMode = session.resolvedConfig.mode === "streaming";
2477
- if (sink.type === "otlp") {
2478
- try {
2479
- const otlpPayload = traceSessionToOtlp(payloadForSink);
2480
- await postOtlpTraces(sink.endpoint, sink.headers, otlpPayload);
2481
- } catch (err) {
2482
- sinkFailed = true;
2483
- const message = err instanceof Error ? err.message : String(err);
2484
- session.errors.push({
2485
- eventId: "sink",
2486
- message,
2487
- type: "sink",
2488
- timestamp: endedAtIso
2489
- });
2490
- }
2491
- } else if (sink.type === "cognipeer" || sink.type === "http") {
3835
+ const terminal = initialStatus !== "paused" && initialStatus !== "in_progress";
3836
+ const exportTargets = [];
3837
+ if (sink.type === "otlp") exportTargets.push({ exporter: sink.exporter, isSink: true });
3838
+ if (!isSubagentTraceScope(session)) {
3839
+ for (const exporter of session.exporters ?? []) exportTargets.push({ exporter, isSink: false });
3840
+ }
3841
+ const unsampled = session.parent !== void 0 && !session.parent.sampled;
3842
+ if (exportTargets.length > 0) {
3843
+ const results = await Promise.all(
3844
+ exportTargets.map(async ({ exporter }) => {
3845
+ if (unsampled) {
3846
+ return { ok: true, skipped: true, reason: "the upstream traceparent is not sampled (sampled=0)", attempts: 0, spans: 0, bytes: 0 };
3847
+ }
3848
+ try {
3849
+ return await exporter.exportSession(exportPayload, {
3850
+ terminal,
3851
+ cancelled: params.cancelled,
3852
+ parent: session.parent
3853
+ });
3854
+ } catch (err) {
3855
+ return { ok: false, attempts: 0, spans: 0, bytes: 0, error: err instanceof Error ? err.message : String(err) };
3856
+ }
3857
+ })
3858
+ );
3859
+ results.forEach((result, index) => {
3860
+ const { exporter, isSink } = exportTargets[index];
3861
+ (session.exportReports ?? (session.exportReports = [])).push({ exporter: exporter.name, endpoint: exporter.endpoint, sink: isSink, terminal, result });
3862
+ if (result.ok) {
3863
+ const rejected = result.partialSuccess?.rejectedSpans ?? 0;
3864
+ if ((rejected > 0 || result.partialSuccess?.message) && typeof console !== "undefined" && typeof console.warn === "function") {
3865
+ const detail = result.partialSuccess?.message ? `: ${result.partialSuccess.message}` : "";
3866
+ console.warn(`[Tracing] OTLP exporter "${exporter.name}": the collector rejected ${rejected} span(s)${detail}`);
3867
+ }
3868
+ return;
3869
+ }
3870
+ const message = result.error ?? "OTLP export failed";
3871
+ if (isSink) {
3872
+ sinkFailed = true;
3873
+ session.errors.push({ eventId: "sink", message, type: "sink", timestamp: endedAtIso });
3874
+ if (typeof console !== "undefined" && typeof console.error === "function") {
3875
+ console.error("[Tracing] OTLP export failed:", message);
3876
+ }
3877
+ } else if (typeof console !== "undefined" && typeof console.warn === "function") {
3878
+ console.warn(`[Tracing] OTLP exporter "${exporter.name}" failed:`, message);
3879
+ }
3880
+ });
3881
+ }
3882
+ if (params.exportOnly) {
3883
+ return buildPayload(payloadForSink.status);
3884
+ }
3885
+ if (sink.type === "cognipeer" || sink.type === "http") {
2492
3886
  try {
2493
3887
  const headers = sink.type === "cognipeer" ? { Authorization: `Bearer ${sink.apiKey}` } : sink.headers;
2494
3888
  if (isStreamingMode && session.sessionStarted) {
@@ -2584,6 +3978,23 @@ async function finalizeTraceSession(session, params = {}) {
2584
3978
  }
2585
3979
  return finalPayload;
2586
3980
  }
3981
+ async function closeTraceContinuation(continuation, params = {}) {
3982
+ const parsed = readTraceContinuation(continuation);
3983
+ if (!parsed) return void 0;
3984
+ const tracing = { ...params.tracing ?? {}, enabled: true };
3985
+ const hasOtlpSink = withDefaults(tracing).sink.type === "otlp";
3986
+ if (!hasOtlpSink && !params.exporters?.length) return void 0;
3987
+ const session = createTraceSession({ tracing }, parsed, { exporters: params.exporters });
3988
+ if (!session) return void 0;
3989
+ replayDeferredTraceEvents(session, params.events);
3990
+ const status = params.status ?? "partial";
3991
+ return finalizeTraceSession(session, {
3992
+ agentRuntime: params.agentRuntime,
3993
+ status,
3994
+ error: status === "error" ? params.error ?? { message: "The run ended in an error before it could be resumed." } : null,
3995
+ exportOnly: true
3996
+ });
3997
+ }
2587
3998
  function sanitizeTracePayload(value) {
2588
3999
  if (value === void 0) return void 0;
2589
4000
  try {
@@ -2623,6 +4034,72 @@ function estimatePayloadBytes(value) {
2623
4034
  }
2624
4035
  }
2625
4036
  }
4037
+
4038
+ // src/providers/wireInfo.ts
4039
+ var WIRE_INFO = Symbol.for("cognipeer.agent-sdk.wireInfo");
4040
+ function usageBasisOf(provider) {
4041
+ switch (provider) {
4042
+ case "anthropic":
4043
+ case "bedrock":
4044
+ return { inputExcludesCache: true };
4045
+ case "vertex":
4046
+ return { outputExcludesReasoning: true };
4047
+ default:
4048
+ return void 0;
4049
+ }
4050
+ }
4051
+ function attachWireInfo(message, info) {
4052
+ const clean = {};
4053
+ if (info.provider) clean.provider = info.provider;
4054
+ if (info.responseId) clean.responseId = info.responseId;
4055
+ if (info.responseModel) clean.responseModel = info.responseModel;
4056
+ if (info.rawFinishReason) clean.rawFinishReason = info.rawFinishReason;
4057
+ if (info.streaming) clean.streaming = true;
4058
+ const basis = info.usageBasis ?? usageBasisOf(info.provider);
4059
+ if (basis) clean.usageBasis = basis;
4060
+ message[WIRE_INFO] = clean;
4061
+ return message;
4062
+ }
4063
+ function wireInfoOf(message) {
4064
+ if (!message || typeof message !== "object") return void 0;
4065
+ return message[WIRE_INFO];
4066
+ }
4067
+
4068
+ // src/utils/traceFacts.ts
4069
+ var nonEmpty2 = (value) => typeof value === "string" && value.trim().length > 0 ? value : void 0;
4070
+ var isRunId = (id) => /^(run-|lc_run)/i.test(id);
4071
+ function providerHintOf(model, response) {
4072
+ const named = getProviderName(model);
4073
+ if (named) return named;
4074
+ const fromWire = wireInfoOf(response)?.provider;
4075
+ if (fromWire) return fromWire;
4076
+ try {
4077
+ return nonEmpty2(getModelCapabilities(model).provider);
4078
+ } catch {
4079
+ return void 0;
4080
+ }
4081
+ }
4082
+ function traceResponseFacts(model, response, rawUsage, streaming) {
4083
+ const wire = wireInfoOf(response);
4084
+ const meta = response?.response_metadata ?? {};
4085
+ const message = response;
4086
+ const idCandidate = nonEmpty2(wire?.responseId) ?? nonEmpty2(meta.id) ?? nonEmpty2(message?.id);
4087
+ const responseId = idCandidate && !isRunId(idCandidate) ? idCandidate : void 0;
4088
+ const responseModel = nonEmpty2(wire?.responseModel) ?? nonEmpty2(meta.model_name) ?? nonEmpty2(meta.model) ?? nonEmpty2(meta.modelName);
4089
+ const rawFinishReason = nonEmpty2(wire?.rawFinishReason) ?? nonEmpty2(meta.stop_reason) ?? nonEmpty2(meta.finish_reason) ?? nonEmpty2(meta.finishReason);
4090
+ const cacheWriteTokens = cacheWriteTokensOf(rawUsage);
4091
+ const provider = providerHintOf(model, response);
4092
+ const isStreaming = streaming ?? wire?.streaming;
4093
+ return {
4094
+ ...provider ? { provider } : {},
4095
+ ...responseId ? { responseId } : {},
4096
+ ...responseModel ? { responseModel } : {},
4097
+ ...rawFinishReason ? { rawFinishReason } : {},
4098
+ ...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {},
4099
+ ...wire?.usageBasis ? { usageBasis: { ...wire.usageBasis } } : {},
4100
+ ...isStreaming ? { streaming: true } : {}
4101
+ };
4102
+ }
2626
4103
  function toMessageUsage(u) {
2627
4104
  return {
2628
4105
  prompt_tokens: u.inputTokens,
@@ -2645,7 +4122,12 @@ function fromNativeProvider(provider, options) {
2645
4122
  if (link.signal) request.signal = link.signal;
2646
4123
  request = await applyTransform(request);
2647
4124
  const response = await provider.complete(request);
2648
- return toBaseChatMessage(response);
4125
+ return attachWireInfo(toBaseChatMessage(response), {
4126
+ provider: provider.providerName,
4127
+ responseId: response.id,
4128
+ responseModel: response.model,
4129
+ rawFinishReason: response.rawFinishReason
4130
+ });
2649
4131
  } finally {
2650
4132
  link.dispose();
2651
4133
  }
@@ -2664,6 +4146,8 @@ function fromNativeProvider(provider, options) {
2664
4146
  let reasoningText = "";
2665
4147
  let finishReason;
2666
4148
  let responseModel;
4149
+ let responseId;
4150
+ let rawFinishReason;
2667
4151
  const toolCallBuffers = /* @__PURE__ */ new Map();
2668
4152
  for await (const chunk of provider.completeStream(request)) {
2669
4153
  if (chunk.delta.content) {
@@ -2671,6 +4155,8 @@ function fromNativeProvider(provider, options) {
2671
4155
  yield chunk.delta.content;
2672
4156
  }
2673
4157
  if (chunk.model) responseModel = chunk.model;
4158
+ if (chunk.id) responseId = chunk.id;
4159
+ if (chunk.rawFinishReason) rawFinishReason = chunk.rawFinishReason;
2674
4160
  if (chunk.finishReason) finishReason = chunk.finishReason;
2675
4161
  if (chunk.delta.reasoning?.blocks?.length) {
2676
4162
  reasoningBlocks = chunk.delta.reasoning.blocks;
@@ -2692,7 +4178,8 @@ function fromNativeProvider(provider, options) {
2692
4178
  id: tc.id,
2693
4179
  name: tc.name ?? "",
2694
4180
  arguments: tc.arguments ?? "",
2695
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4181
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4182
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
2696
4183
  });
2697
4184
  }
2698
4185
  }
@@ -2716,7 +4203,13 @@ function fromNativeProvider(provider, options) {
2716
4203
  ...responseModel ? { model_name: responseModel } : {}
2717
4204
  };
2718
4205
  }
2719
- yield finalMessage;
4206
+ yield attachWireInfo(finalMessage, {
4207
+ provider: provider.providerName,
4208
+ responseId,
4209
+ responseModel,
4210
+ rawFinishReason,
4211
+ streaming: true
4212
+ });
2720
4213
  } finally {
2721
4214
  link.dispose();
2722
4215
  }
@@ -3090,7 +4583,8 @@ function toBaseChatMessage(response) {
3090
4583
  id: tc.id,
3091
4584
  type: "function",
3092
4585
  function: { name: tc.name, arguments: tc.arguments },
3093
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4586
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4587
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
3094
4588
  }));
3095
4589
  }
3096
4590
  if (response.reasoning && (response.reasoning.blocks?.length || response.reasoning.summary)) {
@@ -3112,7 +4606,8 @@ function assembleMessage(content, toolCalls, usage) {
3112
4606
  id: tc.id,
3113
4607
  type: "function",
3114
4608
  function: { name: tc.name, arguments: tc.arguments },
3115
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4609
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4610
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
3116
4611
  }));
3117
4612
  }
3118
4613
  return msg;
@@ -4006,7 +5501,7 @@ var CCRStore = class _CCRStore {
4006
5501
  }
4007
5502
  static hashOf(value) {
4008
5503
  const serialized = typeof value === "string" ? value : JSON.stringify(value);
4009
- return createHash("sha1").update(serialized).digest("hex").slice(0, 16);
5504
+ return createHash("sha256").update(serialized).digest("hex").slice(0, 16);
4010
5505
  }
4011
5506
  };
4012
5507
  var DedupTracker = class {
@@ -4019,7 +5514,7 @@ var DedupTracker = class {
4019
5514
  * first time it has been seen.
4020
5515
  */
4021
5516
  checkAndRegister(content, executionId, toolName) {
4022
- const hash = createHash("sha1").update(content).digest("hex");
5517
+ const hash = createHash("sha256").update(content).digest("hex");
4023
5518
  const existing = this.seen.get(hash);
4024
5519
  if (!existing) {
4025
5520
  this.seen.set(hash, { executionId, toolName });
@@ -4556,7 +6051,7 @@ function createAgentCoreNode(opts) {
4556
6051
  const actorVersion = runtime.version ?? opts.version;
4557
6052
  let traceToolDefinitions;
4558
6053
  const computeTraceToolDefinitions = (menu) => {
4559
- if (!traceSession || !traceSession.resolvedConfig.logData || menu.length === 0) return void 0;
6054
+ if (!traceSession || !(traceSession.resolvedConfig.logData || traceSession.captureContent) || menu.length === 0) return void 0;
4560
6055
  try {
4561
6056
  const wire = shouldUseStrictToolCalling ? prepareStrictToolMenu(menu).menu : menu;
4562
6057
  return wire.map((tool) => {
@@ -4769,8 +6264,9 @@ ${append}`;
4769
6264
  // outcome, and an "error" status would flip the whole trace session
4770
6265
  // status to error for a run that behaved exactly as configured.
4771
6266
  status: "skipped",
6267
+ skipReason: "blocked",
4772
6268
  model: getModelName(runtime.model || opts.model),
4773
- provider: getProviderName(runtime.model || opts.model),
6269
+ provider: providerHintOf(runtime.model || opts.model),
4774
6270
  messageList: state.messages
4775
6271
  });
4776
6272
  return {
@@ -4799,9 +6295,12 @@ ${append}`;
4799
6295
  for (const key of ["usage", "usage_metadata", "response_metadata"]) {
4800
6296
  if (merged[key] === void 0 && original?.[key] !== void 0) merged[key] = original[key];
4801
6297
  }
6298
+ if (wireInfoOf(merged) === void 0 && wireInfoOf(original) !== void 0) merged[WIRE_INFO] = wireInfoOf(original);
4802
6299
  return merged;
4803
6300
  };
4804
6301
  let response;
6302
+ let sentMessages;
6303
+ let streamedCall = false;
4805
6304
  let modelAttempt = 0;
4806
6305
  const maxModelRetries = host?.maxModelRetries ?? 0;
4807
6306
  const finishCancelledTurn = (partialText) => {
@@ -4815,12 +6314,16 @@ ${append}`;
4815
6314
  // "skipped", not "error": the call did not fail, the caller ended it —
4816
6315
  // and an "error" would flip the whole session to error.
4817
6316
  status: "skipped",
6317
+ // The call reached the provider and was hung up on: still a model call, not a skipped one.
6318
+ skipReason: "cancelled",
6319
+ ...streamedCall ? { streaming: true } : {},
4818
6320
  durationMs: Date.now() - start,
4819
6321
  requestBytes: promptBytes,
4820
6322
  model: getModelName(runtime.model || opts.model),
4821
- provider: getProviderName(runtime.model || opts.model),
6323
+ provider: providerHintOf(runtime.model || opts.model),
4822
6324
  messageList: state.messages,
4823
- toolDefinitions: traceToolDefinitions
6325
+ toolDefinitions: traceToolDefinitions,
6326
+ capture: { input: sentMessages ?? wireMessages, toolDefinitions: traceToolDefinitions }
4824
6327
  });
4825
6328
  onEvent?.({ type: "cancelled", stage: "agent", reason });
4826
6329
  onProgress?.({ stage: "agent", message: "Cancelled", detail: { reason } });
@@ -4836,8 +6339,9 @@ ${append}`;
4836
6339
  label: "Assistant (plugin short-circuit)",
4837
6340
  actor: { scope: "agent", name: actorName, role: "assistant", version: actorVersion },
4838
6341
  status: "skipped",
6342
+ skipReason: "short_circuit",
4839
6343
  model: getModelName(runtime.model || opts.model),
4840
- provider: getProviderName(runtime.model || opts.model),
6344
+ provider: providerHintOf(runtime.model || opts.model),
4841
6345
  messageList: state.messages,
4842
6346
  toolDefinitions: traceToolDefinitions
4843
6347
  });
@@ -4845,8 +6349,10 @@ ${append}`;
4845
6349
  let streamedText = "";
4846
6350
  try {
4847
6351
  const normalizedMessages = normalizeBedrockToolPairing([...wireMessages]);
6352
+ sentMessages = normalizedMessages;
4848
6353
  debugToolPairing(normalizedMessages);
4849
6354
  if (streamingEnabled && typeof modelWithTools.stream === "function") {
6355
+ streamedCall = true;
4850
6356
  let streamedMessage;
4851
6357
  let cutByCancel = false;
4852
6358
  for await (const chunk of modelWithTools.stream(normalizedMessages, invokeParams)) {
@@ -4892,12 +6398,14 @@ ${append}`;
4892
6398
  durationMs: durationMs2,
4893
6399
  requestBytes: promptBytes,
4894
6400
  model: getModelName(runtime.model || opts.model),
4895
- provider: getProviderName(runtime.model || opts.model),
4896
- error: { message: err?.message || String(err), stack: err?.stack },
6401
+ provider: providerHintOf(runtime.model || opts.model),
6402
+ error: traceErrorOf(err),
6403
+ ...streamedCall ? { streaming: true } : {},
4897
6404
  messageList: state.messages,
4898
6405
  toolDefinitions: traceToolDefinitions,
4899
6406
  responseFormat: traceResponseFormat,
4900
- responseFormatStrategy: traceResponseFormatStrategy
6407
+ responseFormatStrategy: traceResponseFormatStrategy,
6408
+ capture: { input: sentMessages ?? wireMessages, toolDefinitions: traceToolDefinitions }
4901
6409
  });
4902
6410
  throw err;
4903
6411
  }
@@ -4950,6 +6458,8 @@ ${append}`;
4950
6458
  const responsePayload = shouldLogResponse ? sanitizeTracePayload(response) : void 0;
4951
6459
  const responseBytes = responsePayload !== void 0 ? estimatePayloadBytes(responsePayload) : void 0;
4952
6460
  const finishReason = response?.response_metadata?.finish_reason ?? response?.response_metadata?.finishReason ?? response?.finishReason;
6461
+ const facts = traceResponseFacts(runtime.model || opts.model, response, rawUsage, streamedCall);
6462
+ const jsonOutput = Boolean(responseFormat) && responseFormat?.response_format?.type !== "text" && responseFormat?.type !== "text";
4953
6463
  recordTraceEvent(traceSession, {
4954
6464
  type: "ai_call",
4955
6465
  label: "Assistant Response",
@@ -4966,11 +6476,13 @@ ${append}`;
4966
6476
  requestBytes: promptBytes,
4967
6477
  responseBytes,
4968
6478
  model: modelName,
4969
- provider: getProviderName(runtime.model || opts.model),
6479
+ ...facts,
6480
+ outputType: jsonOutput ? "json" : "text",
4970
6481
  messageList: messagesWithResponse,
4971
6482
  toolDefinitions: traceToolDefinitions,
4972
6483
  responseFormat: traceResponseFormat,
4973
- responseFormatStrategy: traceResponseFormatStrategy
6484
+ responseFormatStrategy: traceResponseFormatStrategy,
6485
+ capture: { input: sentMessages ?? wireMessages, output: response, toolDefinitions: traceToolDefinitions }
4974
6486
  });
4975
6487
  if (normalized) {
4976
6488
  recordUsage(state, modelName, normalized);
@@ -4996,6 +6508,12 @@ function sameJson(a, b) {
4996
6508
  return false;
4997
6509
  }
4998
6510
  }
6511
+ var idSection = (label, data) => ({
6512
+ kind: "metadata",
6513
+ label,
6514
+ data,
6515
+ identity: true
6516
+ });
4999
6517
  function recordApprovalRequested(session, entry) {
5000
6518
  if (!session || surfacedFromSubagent(entry) || !canPauseForHuman(session)) return;
5001
6519
  const logData = session.resolvedConfig.logData;
@@ -5021,7 +6539,7 @@ function recordApprovalRequested(session, entry) {
5021
6539
  timestamp: entry.requestedAt,
5022
6540
  status: "pending",
5023
6541
  actor: { scope: "agent", name: entry.toolName, role: "approval_request" },
5024
- sections
6542
+ sections: [...sections, idSection("Approval ids", { approvalId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt })]
5025
6543
  });
5026
6544
  }
5027
6545
  function recordHumanDecisions(session, state) {
@@ -5062,7 +6580,14 @@ function recordHumanDecisions(session, state) {
5062
6580
  durationMs: waitedMs(entry.requestedAt, entry.decidedAt),
5063
6581
  status: "success",
5064
6582
  actor: { scope: "human", name: entry.decidedBy || "reviewer", role: "approver" },
5065
- sections
6583
+ sections: [...sections, idSection("Decision ids", {
6584
+ approvalId: entry.id,
6585
+ toolCallId: entry.toolCallId,
6586
+ decision: entry.status,
6587
+ requestedAt: entry.requestedAt,
6588
+ decidedAt: entry.decidedAt,
6589
+ ...waitedMs(entry.requestedAt, entry.decidedAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.decidedAt) } : {}
6590
+ })]
5066
6591
  });
5067
6592
  entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
5068
6593
  }
@@ -5107,7 +6632,14 @@ function recordHumanDecisions(session, state) {
5107
6632
  durationMs: waitedMs(entry.requestedAt, entry.answeredAt),
5108
6633
  status: cancelled ? "skipped" : "success",
5109
6634
  actor: { scope: "human", name: entry.answeredBy || "user", role: "user" },
5110
- sections
6635
+ sections: [...sections, idSection("Answer ids", {
6636
+ questionId: entry.id,
6637
+ toolCallId: entry.toolCallId,
6638
+ status: entry.status,
6639
+ requestedAt: entry.requestedAt,
6640
+ answeredAt: entry.answeredAt,
6641
+ ...waitedMs(entry.requestedAt, entry.answeredAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.answeredAt) } : {}
6642
+ })]
5111
6643
  });
5112
6644
  entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
5113
6645
  }
@@ -5132,7 +6664,7 @@ function recordClientToolRequested(session, entry) {
5132
6664
  timestamp: entry.requestedAt,
5133
6665
  status: "pending",
5134
6666
  actor: { scope: "client", name: clientTool.name, role: "tool" },
5135
- sections
6667
+ sections: [...sections, idSection("Client tool ids", { questionId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt })]
5136
6668
  });
5137
6669
  }
5138
6670
  function readClientTool(entry) {
@@ -5179,7 +6711,14 @@ function recordClientToolResult(session, entry, clientTool, toolHistory) {
5179
6711
  durationMs: waitedMs(entry.requestedAt, entry.answeredAt) ?? ranMs,
5180
6712
  status: failed ? "error" : "success",
5181
6713
  actor: { scope: "client", name: clientTool.name, role: "tool" },
5182
- sections
6714
+ sections: [...sections, idSection("Client tool ids", {
6715
+ questionId: entry.id,
6716
+ toolCallId: entry.toolCallId,
6717
+ status: failed ? "error" : "answered",
6718
+ requestedAt: entry.requestedAt,
6719
+ answeredAt: entry.answeredAt,
6720
+ ...waitedMs(entry.requestedAt, entry.answeredAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.answeredAt) } : {}
6721
+ })]
5183
6722
  });
5184
6723
  }
5185
6724
 
@@ -5285,9 +6824,11 @@ function normalizeToolCall(call) {
5285
6824
  return {
5286
6825
  id: call.id,
5287
6826
  name,
5288
- args: call.args ?? call.arguments ?? call.input ?? call.function?.arguments ?? call.function_call?.arguments
6827
+ args: call.args ?? call.arguments ?? call.input ?? call.function?.arguments ?? call.function_call?.arguments,
6828
+ ...call.idSynthesized === true ? { idSynthesized: true } : {}
5289
6829
  };
5290
6830
  }
6831
+ var providerToolCallId = (tc) => tc.id && !tc.idSynthesized ? tc.id : void 0;
5291
6832
  function normalizeToolSchema(tool, toolName) {
5292
6833
  const schema = tool.schema;
5293
6834
  if (!schema) return void 0;
@@ -5545,6 +7086,8 @@ function createToolsNode(initialTools, opts) {
5545
7086
  label: `Tool Denied - ${toolName}`,
5546
7087
  actor: { scope: "tool", name: toolName, role: "tool" },
5547
7088
  status: "skipped",
7089
+ skipReason: "denied",
7090
+ toolCallId: providerToolCallId(tc),
5548
7091
  toolDetails,
5549
7092
  toolExecutionId: toolCallId,
5550
7093
  sections: buildToolTraceSections({
@@ -5616,6 +7159,8 @@ function createToolsNode(initialTools, opts) {
5616
7159
  label: `Tool Skipped - ${toolName}`,
5617
7160
  actor: { scope: "tool", name: toolName, role: "tool" },
5618
7161
  status: "skipped",
7162
+ skipReason: "skipped",
7163
+ toolCallId: providerToolCallId(tc),
5619
7164
  toolDetails,
5620
7165
  toolExecutionId: tc.id,
5621
7166
  sections: buildToolTraceSections({
@@ -5752,10 +7297,13 @@ function createToolsNode(initialTools, opts) {
5752
7297
  label: `Tool Error - ${toolName}`,
5753
7298
  actor: { scope: "tool", name: toolName, role: "tool" },
5754
7299
  status: "error",
7300
+ // The tool was not run: an open breaker refused the call.
7301
+ skipReason: "skipped",
7302
+ toolCallId: providerToolCallId(tc),
5755
7303
  requestBytes: inputBytes,
5756
7304
  toolDetails,
5757
7305
  toolExecutionId: toolCallId,
5758
- error: { message: breakerMsg },
7306
+ error: { message: breakerMsg, type: "circuit_breaker_open" },
5759
7307
  sections: buildToolTraceSections({
5760
7308
  args,
5761
7309
  executionId: toolCallId,
@@ -5815,6 +7363,9 @@ function createToolsNode(initialTools, opts) {
5815
7363
  type: "tool_call",
5816
7364
  label: shortCircuitSource === "plugin" ? `Tool Short-Circuited - ${toolName}` : `Tool Execution - ${toolName}`,
5817
7365
  actor: { scope: "tool", name: toolName, role: "tool" },
7366
+ // Answered from the cache or by a plugin: nothing executed.
7367
+ skipReason: "short_circuit",
7368
+ toolCallId: providerToolCallId(tc),
5818
7369
  durationMs: 0,
5819
7370
  requestBytes: inputBytes,
5820
7371
  responseBytes: outputBytes2,
@@ -5850,7 +7401,15 @@ function createToolsNode(initialTools, opts) {
5850
7401
  onProgress?.({ stage: "tools", message: `Running tool ${tc.name}` });
5851
7402
  const anyTool = tool;
5852
7403
  traceSpanId = traceSession ? generateSpanId() : void 0;
5853
- const callOptions = { cancellationToken, signal: abortSignal, toolCallId, ...traceSpanId ? { traceSpanId } : {} };
7404
+ const callOptions = {
7405
+ cancellationToken,
7406
+ signal: abortSignal,
7407
+ toolCallId,
7408
+ ...traceSpanId ? { traceSpanId } : {},
7409
+ // So the tool can propagate the trace to what it calls (traceparentOf).
7410
+ ...traceSpanId && traceSession?.traceId ? { traceId: traceSession.traceId } : {},
7411
+ ...traceSpanId && traceSession?.parent ? { traceFlags: traceSession.parent.flags } : {}
7412
+ };
5854
7413
  const invokeOnce = async () => {
5855
7414
  if (typeof anyTool.func === "function") return anyTool.func(args, callOptions);
5856
7415
  if (typeof anyTool.invoke === "function") return anyTool.invoke(args, callOptions);
@@ -6036,7 +7595,10 @@ function createToolsNode(initialTools, opts) {
6036
7595
  spanId: traceSpanId,
6037
7596
  label: `Tool Execution - ${toolName}`,
6038
7597
  actor: { scope: "tool", name: toolName, role: "tool" },
6039
- ...reportedFailure ? { status: "error", error: { message: reportedFailure } } : {},
7598
+ ...reportedFailure ? { status: "error", error: { message: reportedFailure, type: "tool_error" } } : {},
7599
+ toolCallId: providerToolCallId(tc),
7600
+ // `output` is already past postToolUse, so a redaction plugin has applied.
7601
+ capture: reportedFailure ? { toolArguments: args } : { toolArguments: args, toolResult: output, hasToolResult: true },
6040
7602
  durationMs,
6041
7603
  requestBytes: inputBytes,
6042
7604
  responseBytes: outputBytes,
@@ -6100,12 +7662,14 @@ function createToolsNode(initialTools, opts) {
6100
7662
  label: `Tool Error - ${toolName}`,
6101
7663
  actor: { scope: "tool", name: toolName, role: "tool" },
6102
7664
  status: "error",
7665
+ toolCallId: providerToolCallId(tc),
7666
+ capture: { toolArguments: args },
6103
7667
  durationMs,
6104
7668
  requestBytes: inputBytes,
6105
7669
  responseBytes: traceSession?.resolvedConfig.logData ? estimatePayloadBytes(errorOutput) : void 0,
6106
7670
  toolDetails,
6107
7671
  toolExecutionId: executionId,
6108
- error: { message, stack: host?.has("postToolUse") ? void 0 : error?.stack },
7672
+ error: { ...traceErrorOf(error), message, stack: host?.has("postToolUse") ? void 0 : error?.stack },
6109
7673
  sections: buildToolTraceSections({
6110
7674
  args: sanitizedArgs,
6111
7675
  durationMs,
@@ -6220,6 +7784,8 @@ function createToolsNode(initialTools, opts) {
6220
7784
  label: `Tool Skipped - ${tc.name}`,
6221
7785
  actor: { scope: "tool", name: tc.name, role: "tool" },
6222
7786
  status: "skipped",
7787
+ skipReason: "skipped",
7788
+ toolCallId: providerToolCallId(tc),
6223
7789
  toolDetails,
6224
7790
  toolExecutionId: tc.id,
6225
7791
  sections: buildToolTraceSections({
@@ -6386,7 +7952,7 @@ function createReflectionNode(opts, resolved) {
6386
7952
  label: "Reflection error",
6387
7953
  actor: { scope: "agent", name: opts.name || "agent", role: "reflection" },
6388
7954
  status: "error",
6389
- error: { message: err?.message || String(err) }
7955
+ error: traceErrorOf(err)
6390
7956
  });
6391
7957
  return {};
6392
7958
  }
@@ -7397,7 +8963,7 @@ function buildSubagentCatalogBlock(subagents, policy, toolNames, opts) {
7397
8963
  // src/plugins/host.ts
7398
8964
  init_content();
7399
8965
  var DEFAULT_PRIORITY = 100;
7400
- var DEFAULT_TIMEOUT_MS = 1e4;
8966
+ var DEFAULT_TIMEOUT_MS2 = 1e4;
7401
8967
  var HOOK_SPECS = {
7402
8968
  sessionStart: { kind: "gate", mutable: ["messages"], collect: ["systemPromptAppend"] },
7403
8969
  userPromptSubmit: {
@@ -7502,7 +9068,7 @@ function collectRegistrations(plugin, registrations, into, orderRef) {
7502
9068
  plugin: plugin.name,
7503
9069
  priority: plugin.priority ?? DEFAULT_PRIORITY,
7504
9070
  failureMode: plugin.failureMode ?? "open",
7505
- timeoutMs: plugin.timeoutMs ?? DEFAULT_TIMEOUT_MS,
9071
+ timeoutMs: plugin.timeoutMs ?? DEFAULT_TIMEOUT_MS2,
7506
9072
  order: orderRef.value++,
7507
9073
  handler
7508
9074
  });
@@ -7557,6 +9123,7 @@ function createPluginHost(plugins = [], options = {}) {
7557
9123
  let contributions = {
7558
9124
  tools: [],
7559
9125
  toolDescriptions: {},
9126
+ traceExporters: [],
7560
9127
  guardrails: [],
7561
9128
  applySystemPrompt: (base) => base,
7562
9129
  applyModelWrappers: (model) => model
@@ -7565,6 +9132,7 @@ function createPluginHost(plugins = [], options = {}) {
7565
9132
  async function runSetup(setupInput) {
7566
9133
  const tools = [];
7567
9134
  const toolDescriptions = {};
9135
+ const traceExporters = [];
7568
9136
  const guardrails = [];
7569
9137
  const promptSteps = [];
7570
9138
  const modelWrappers = [];
@@ -7602,6 +9170,7 @@ function createPluginHost(plugins = [], options = {}) {
7602
9170
  );
7603
9171
  }
7604
9172
  if (plugin.toolDescriptions) Object.assign(toolDescriptions, plugin.toolDescriptions);
9173
+ if (plugin.traceExporters?.length) traceExporters.push(...plugin.traceExporters.filter(Boolean));
7605
9174
  if (plugin.guardrails?.length) guardrails.push(...plugin.guardrails);
7606
9175
  if (typeof plugin.wrapModel === "function") {
7607
9176
  modelWrappers.push({ plugin: plugin.name, wrap: plugin.wrapModel });
@@ -7617,6 +9186,7 @@ function createPluginHost(plugins = [], options = {}) {
7617
9186
  contributions = {
7618
9187
  tools,
7619
9188
  toolDescriptions,
9189
+ traceExporters,
7620
9190
  guardrails,
7621
9191
  applySystemPrompt: (base) => promptSteps.reduce((current, step) => {
7622
9192
  try {
@@ -8640,7 +10210,10 @@ function createAgent(opts) {
8640
10210
  }
8641
10211
  emit({ type: "progress", ...progress });
8642
10212
  };
8643
- const traceSession = createTraceSession(opts, readTraceContinuation(input.ctx?.__traceContinuation));
10213
+ const traceSession = createTraceSession(opts, readTraceContinuation(input.ctx?.__traceContinuation), {
10214
+ exporters: pluginHost.contributions.traceExporters,
10215
+ traceParent: config?.traceParent
10216
+ });
8644
10217
  const ctx = {
8645
10218
  ...input.ctx || {},
8646
10219
  __onEvent: onEvent,
@@ -8792,7 +10365,7 @@ function createAgent(opts) {
8792
10365
  await finalizeTraceSession(traceSession, {
8793
10366
  agentRuntime: runtime,
8794
10367
  status: "error",
8795
- error: { message: err?.message, stack: err?.stack }
10368
+ error: { message: err?.message, stack: err?.stack, name: err?.name }
8796
10369
  });
8797
10370
  await endSession("error", { error: err instanceof Error ? err : new Error(String(err)), state: stateHolder.value });
8798
10371
  if (userTokenCounter) {
@@ -8813,7 +10386,10 @@ function createAgent(opts) {
8813
10386
  const midTurn = pausedForHuman || Boolean(res.ctx?.__needsSummarization);
8814
10387
  await finalizeTraceSession(traceSession, {
8815
10388
  agentRuntime: res.agent || runtime,
8816
- status: pausedForHuman ? "paused" : midTurn ? "in_progress" : "success"
10389
+ status: pausedForHuman ? "paused" : midTurn ? "in_progress" : "success",
10390
+ // The file says `success` for a cancelled run (it did not fail); the
10391
+ // exported root says `partial`, the old plugin mapping.
10392
+ cancelled: statusFor(res) === "cancelled"
8817
10393
  });
8818
10394
  if (traceSession && midTurn) {
8819
10395
  res.ctx = { ...res.ctx || {}, __traceContinuation: traceContinuationOf(traceSession) };
@@ -9069,9 +10645,10 @@ function createAgentNode(opts) {
9069
10645
  durationMs: durationMs2,
9070
10646
  requestBytes: promptBytes,
9071
10647
  model: getModelName(runtime.model || opts.model),
9072
- provider: getProviderName(runtime.model || opts.model),
9073
- error: { message: err?.message || String(err), stack: err?.stack },
9074
- messageList: promptMessages
10648
+ provider: providerHintOf(runtime.model || opts.model),
10649
+ error: traceErrorOf(err),
10650
+ messageList: promptMessages,
10651
+ capture: { input: promptMessages }
9075
10652
  });
9076
10653
  throw err;
9077
10654
  }
@@ -9082,7 +10659,7 @@ function createAgentNode(opts) {
9082
10659
  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;
9083
10660
  const normalized = normalizeUsage(rawUsage);
9084
10661
  const modelName = getModelName(runtime.model || opts.model) || "unknown_model";
9085
- const providerName = getProviderName(runtime.model || opts.model);
10662
+ const facts = traceResponseFacts(runtime.model || opts.model, response, rawUsage);
9086
10663
  const durationMs = Date.now() - start;
9087
10664
  const shouldLogResponse = !!traceSession && traceSession.resolvedConfig.logData;
9088
10665
  const responsePayload = shouldLogResponse ? sanitizeTracePayload(response) : void 0;
@@ -9099,8 +10676,9 @@ function createAgentNode(opts) {
9099
10676
  requestBytes: promptBytes,
9100
10677
  responseBytes,
9101
10678
  model: modelName,
9102
- provider: providerName,
9103
- messageList: messagesWithResponse
10679
+ ...facts,
10680
+ messageList: messagesWithResponse,
10681
+ capture: { input: promptMessages, output: response }
9104
10682
  });
9105
10683
  if (normalized) {
9106
10684
  recordUsage(state, modelName, normalized);
@@ -9751,7 +11329,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9751
11329
  ];
9752
11330
  const inputTokensEstimate = countApproxTokens(summaryPrompt.map((m) => m.content).join("\n"));
9753
11331
  const modelName = getModelName(model);
9754
- const providerName = getProviderName(model);
11332
+ const providerName = providerHintOf(model);
9755
11333
  const tracingEnabled = Boolean(opts.tracing?.enabled);
9756
11334
  let ctxWithDeferredTrace;
9757
11335
  const traceSummarization = (event) => {
@@ -9782,6 +11360,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9782
11360
  let reasoningTokensActual;
9783
11361
  let fallback = false;
9784
11362
  let summarizerError;
11363
+ let responseFacts;
9785
11364
  const directivesSection = () => ({
9786
11365
  kind: "metadata",
9787
11366
  label: "User directives",
@@ -9823,6 +11402,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9823
11402
  summaryText = renderStructuredSummary(structuredSummary);
9824
11403
  const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
9825
11404
  const normalized = normalizeUsage(rawUsage);
11405
+ responseFacts = traceResponseFacts(model, response, rawUsage);
9826
11406
  if (normalized) {
9827
11407
  inputTokensActual = normalized.prompt_tokens;
9828
11408
  outputTokensActual = normalized.completion_tokens;
@@ -9859,7 +11439,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9859
11439
  ...droppedDirectives.length > 0 ? { droppedDirectives } : {}
9860
11440
  };
9861
11441
  onEvent?.(errorEvent);
9862
- summarizerError = { message: err?.message || String(err), stack: err?.stack };
11442
+ summarizerError = traceErrorOf(err);
9863
11443
  }
9864
11444
  const toolCallIdToAssistantIdx = /* @__PURE__ */ new Map();
9865
11445
  messages.forEach((m, idx) => {
@@ -10015,10 +11595,16 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
10015
11595
  outputTokens: outputTokensActual ?? outputTokensEstimate,
10016
11596
  cachedInputTokens,
10017
11597
  totalTokens: totalTokensActual,
10018
- ...reasoningTokensActual !== void 0 ? { reasoningTokens: reasoningTokensActual } : {}
11598
+ ...reasoningTokensActual !== void 0 ? { reasoningTokens: reasoningTokensActual } : {},
11599
+ // Which counting rules the usage above follows (only when the provider reported it).
11600
+ ...inputTokensActual !== void 0 && responseFacts?.usageBasis ? { usageBasis: responseFacts.usageBasis } : {},
11601
+ ...inputTokensActual !== void 0 && responseFacts?.cacheWriteTokens ? { cacheWriteTokens: responseFacts.cacheWriteTokens } : {}
10019
11602
  },
11603
+ ...responseFacts?.responseId ? { responseId: responseFacts.responseId } : {},
11604
+ ...responseFacts?.responseModel ? { responseModel: responseFacts.responseModel } : {},
11605
+ ...responseFacts?.rawFinishReason ? { rawFinishReason: responseFacts.rawFinishReason } : {},
10020
11606
  ...modelName ? { model: modelName } : {},
10021
- ...providerName ? { provider: providerName } : {},
11607
+ ...responseFacts?.provider ?? providerName ? { provider: responseFacts?.provider ?? providerName } : {},
10022
11608
  ...summarizerError ? { error: summarizerError } : {},
10023
11609
  sections: [
10024
11610
  ...promptAndOutputSections(),
@@ -11162,7 +12748,15 @@ async function runChild(spec, input, deps, ref, opts) {
11162
12748
  const childDepth = (Number(parentCtx.__delegationDepth) || 0) + 1;
11163
12749
  const parentSession = parentCtx.__traceSession;
11164
12750
  const traced = isTraceSessionOpen(parentSession);
11165
- const agentSpanId = generateSpanId();
12751
+ const sessionStart = traced ? parentSession.startedAt : void 0;
12752
+ const persistedId = opts.record?.agentSpanId;
12753
+ const agentSpanId = typeof persistedId === "string" && /^[0-9a-f]{16}$/.test(persistedId) ? persistedId : generateSpanId();
12754
+ const persistedStart = opts.record?.startedAt;
12755
+ const startValid = typeof persistedStart === "number" && Number.isFinite(persistedStart) && persistedStart > 0 && persistedStart <= start;
12756
+ const runStartedAt = startValid ? Math.min(start, Math.max(persistedStart, sessionStart ?? persistedStart)) : start;
12757
+ const persistedSegments = opts.record?.segments;
12758
+ const segment = (typeof persistedSegments === "number" && Number.isInteger(persistedSegments) && persistedSegments >= 1 && persistedSegments <= 1e3 ? persistedSegments : 0) + 1;
12759
+ const elapsedMs = () => Math.max(0, Date.now() - runStartedAt);
11166
12760
  const parentIterationSpanId = traced ? parentSession.currentIterationSpanId : void 0;
11167
12761
  const traceScope = traced ? createSubagentTraceScope(parentSession, { agentSpanId, name: spec.name, spawnId, mode: spec.mode, hitl: opts.allowHITL, iterations: opts.record?.iterations }) : void 0;
11168
12762
  const recordSegment = (status, info) => {
@@ -11174,7 +12768,7 @@ async function runChild(spec, input, deps, ref, opts) {
11174
12768
  parentSpanId: status === "pending" ? parentIterationSpanId : opts.parentSpanId ?? parentIterationSpanId,
11175
12769
  name: spec.name,
11176
12770
  status,
11177
- durationMs: Date.now() - start,
12771
+ durationMs: elapsedMs(),
11178
12772
  error: info.error,
11179
12773
  info: {
11180
12774
  id: spawnId,
@@ -11184,6 +12778,8 @@ async function runChild(spec, input, deps, ref, opts) {
11184
12778
  depth: childDepth,
11185
12779
  parentToolCallId: opts.parentToolCallId,
11186
12780
  status: info.subagentStatus,
12781
+ // Only a run that paused has more than one segment to tell about.
12782
+ ...segment > 1 || status === "pending" ? { segments: segment } : {},
11187
12783
  ...info.note ? { note: info.note } : {},
11188
12784
  ...spec.metadata ? { metadata: spec.metadata } : {}
11189
12785
  },
@@ -11348,7 +12944,10 @@ async function runChild(spec, input, deps, ref, opts) {
11348
12944
  pendingKind: "approval",
11349
12945
  pendingId: childEntry.id,
11350
12946
  spawnId,
11351
- iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0
12947
+ iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0,
12948
+ agentSpanId,
12949
+ startedAt: runStartedAt,
12950
+ segments: segment
11352
12951
  };
11353
12952
  recordSegment("pending", { subagentStatus: "paused", input });
11354
12953
  parentOnEvent?.({ type: "subagent", phase: "paused", name: spec.name, id: spawnId, mode: spec.mode, parentToolCallId: opts.parentToolCallId });
@@ -11374,7 +12973,10 @@ async function runChild(spec, input, deps, ref, opts) {
11374
12973
  pendingKind: "user_question",
11375
12974
  pendingId: childEntry.id,
11376
12975
  spawnId,
11377
- iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0
12976
+ iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0,
12977
+ agentSpanId,
12978
+ startedAt: runStartedAt,
12979
+ segments: segment
11378
12980
  };
11379
12981
  recordSegment("pending", { subagentStatus: "paused", input });
11380
12982
  parentOnEvent?.({ type: "subagent", phase: "paused", name: spec.name, id: spawnId, mode: spec.mode, parentToolCallId: opts.parentToolCallId });
@@ -12061,6 +13663,30 @@ ${pluginAppend}`;
12061
13663
  };
12062
13664
  }
12063
13665
  }
13666
+ const traceHandoff = {};
13667
+ const noteTraceHandoff = (current) => {
13668
+ traceHandoff.continuation = current.ctx?.__traceContinuation;
13669
+ traceHandoff.events = current.ctx?.[DEFERRED_TRACE_EVENTS_KEY];
13670
+ };
13671
+ const closeDanglingTrace = async (status, error) => {
13672
+ const continuation = traceHandoff.continuation;
13673
+ const events = traceHandoff.events;
13674
+ traceHandoff.continuation = void 0;
13675
+ traceHandoff.events = void 0;
13676
+ if (!continuation) return;
13677
+ try {
13678
+ await closeTraceContinuation(continuation, {
13679
+ tracing: opts.tracing,
13680
+ exporters: pluginHost?.contributions.traceExporters,
13681
+ status,
13682
+ error,
13683
+ agentRuntime: base.__runtime,
13684
+ events
13685
+ });
13686
+ } catch (closeError) {
13687
+ console.warn("[agent-sdk] closing the trace failed:", closeError);
13688
+ }
13689
+ };
12064
13690
  try {
12065
13691
  const toolSet = buildInvokeToolSet();
12066
13692
  const stateRef = toolSet.stateRef;
@@ -12139,11 +13765,15 @@ ${pluginAppend}`;
12139
13765
  const result = await trySummarize(state, rawMessages, stateRef);
12140
13766
  state = result.state;
12141
13767
  rawMessages = result.rawMessages;
13768
+ noteTraceHandoff(state);
12142
13769
  if (result.compressed) continue;
12143
13770
  }
12144
13771
  const modelMessages = buildModelMessages(state, resolved);
13772
+ traceHandoff.continuation = void 0;
13773
+ traceHandoff.events = void 0;
12145
13774
  const res = await base.invoke({ ...state, messages: modelMessages }, turnConfig);
12146
13775
  lastResult = res;
13776
+ noteTraceHandoff(res.state ?? state);
12147
13777
  const currentSummaries = state.summaries;
12148
13778
  const currentSummaryRecords = state.summaryRecords;
12149
13779
  const currentPlan = state.plan;
@@ -12170,6 +13800,7 @@ ${pluginAppend}`;
12170
13800
  const result = await trySummarize(state, rawMessages, stateRef);
12171
13801
  state = result.state;
12172
13802
  rawMessages = result.rawMessages;
13803
+ noteTraceHandoff(state);
12173
13804
  continue;
12174
13805
  }
12175
13806
  if (state.ctx?.__finalizedDueToStructuredOutput) break;
@@ -12181,6 +13812,7 @@ ${pluginAppend}`;
12181
13812
  const result = await trySummarize(state, rawMessages, stateRef);
12182
13813
  state = result.state;
12183
13814
  rawMessages = result.rawMessages;
13815
+ noteTraceHandoff(state);
12184
13816
  if (result.compressed) continue;
12185
13817
  }
12186
13818
  }
@@ -12191,6 +13823,7 @@ ${pluginAppend}`;
12191
13823
  lastResult = res;
12192
13824
  }
12193
13825
  if (state.ctx?.[DEFERRED_TRACE_EVENTS_KEY]) {
13826
+ traceHandoff.events = state.ctx[DEFERRED_TRACE_EVENTS_KEY];
12194
13827
  const ctx = { ...state.ctx || {} };
12195
13828
  delete ctx[DEFERRED_TRACE_EVENTS_KEY];
12196
13829
  state = { ...state, ctx };
@@ -12210,8 +13843,12 @@ ${pluginAppend}`;
12210
13843
  const strippedCtx = { ...endCtx };
12211
13844
  delete strippedCtx.__traceContinuation;
12212
13845
  lastResult = { ...lastResult, state: { ...lastResult.state, ctx: strippedCtx } };
13846
+ traceHandoff.continuation = endCtx.__traceContinuation;
13847
+ await closeDanglingTrace("success");
12213
13848
  }
12214
13849
  }
13850
+ traceHandoff.continuation = void 0;
13851
+ traceHandoff.events = void 0;
12215
13852
  if (skillsEnabled && lastResult.state) {
12216
13853
  const persisted = skillStateFromRegistry(toolSet.skillRegistryRef);
12217
13854
  if (persisted) {
@@ -12257,6 +13894,11 @@ ${pluginAppend}`;
12257
13894
  await endSession(endStatus, { result: lastResult });
12258
13895
  return lastResult;
12259
13896
  } catch (err) {
13897
+ await closeDanglingTrace("error", {
13898
+ message: err instanceof Error ? err.message : String(err),
13899
+ stack: err instanceof Error ? err.stack : void 0,
13900
+ name: err instanceof Error ? err.name : void 0
13901
+ });
12260
13902
  await endSession("error", { error: err instanceof Error ? err : new Error(String(err)) });
12261
13903
  throw err;
12262
13904
  }
@@ -13173,7 +14815,7 @@ function isHookImplemented(hook) {
13173
14815
  // src/plugins/builtin/guardrail.ts
13174
14816
  init_content();
13175
14817
  var ALLOW = { action: "allow" };
13176
- var RETRYABLE_STATUS = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
14818
+ var RETRYABLE_STATUS2 = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
13177
14819
  var RetryableGuardrailError = class extends Error {
13178
14820
  constructor(message) {
13179
14821
  super(message);
@@ -13271,7 +14913,7 @@ function httpGuardrail(options) {
13271
14913
  } catch {
13272
14914
  }
13273
14915
  const message = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}${text ? ` - ${text.slice(0, 200)}` : ""}`;
13274
- if (RETRYABLE_STATUS.has(response.status)) throw new RetryableGuardrailError(message);
14916
+ if (RETRYABLE_STATUS2.has(response.status)) throw new RetryableGuardrailError(message);
13275
14917
  throw new Error(message);
13276
14918
  }
13277
14919
  return response.json();
@@ -13378,9 +15020,9 @@ function createGuardrailPlugin(options) {
13378
15020
  });
13379
15021
  const resolved = verdict ?? ALLOW;
13380
15022
  if (resolved.raw?.disabled === true) {
13381
- const warned = (_b = ctx.store).__disabledWarned ?? (_b.__disabledWarned = /* @__PURE__ */ new Set());
13382
- if (!warned.has(request.phase)) {
13383
- warned.add(request.phase);
15023
+ const warned2 = (_b = ctx.store).__disabledWarned ?? (_b.__disabledWarned = /* @__PURE__ */ new Set());
15024
+ if (!warned2.has(request.phase)) {
15025
+ warned2.add(request.phase);
13384
15026
  ctx.logger.warn(
13385
15027
  `guardrail reports it is not active for the "${request.phase}" surface; nothing is being enforced there`
13386
15028
  );
@@ -13877,7 +15519,7 @@ function safeJson(value) {
13877
15519
  function matches(pattern, toolName) {
13878
15520
  return typeof pattern === "string" ? pattern === toolName : pattern.test(toolName);
13879
15521
  }
13880
- function asObject(args) {
15522
+ function asObject2(args) {
13881
15523
  return args && typeof args === "object" ? args : {};
13882
15524
  }
13883
15525
  function toolPolicy(config = {}) {
@@ -13898,7 +15540,7 @@ function toolPolicy(config = {}) {
13898
15540
  hooks: {
13899
15541
  preToolUse: ({ toolName, args }, ctx) => {
13900
15542
  var _a;
13901
- const argObject = asObject(args);
15543
+ const argObject = asObject2(args);
13902
15544
  const isControlPlane = CONTROL_PLANE_TOOL_NAMES.includes(toolName);
13903
15545
  const allowListApplies = !isControlPlane || config.governControlPlaneTools === true;
13904
15546
  if (config.allowOnly && allowListApplies && !config.allowOnly.some((pattern) => matches(pattern, toolName))) {
@@ -13960,7 +15602,7 @@ function pathSandbox(config) {
13960
15602
  hooks: {
13961
15603
  preToolUse: ({ toolName, args }) => {
13962
15604
  if (config.tools && !config.tools.some((pattern) => matches(pattern, toolName))) return void 0;
13963
- const argObject = asObject(args);
15605
+ const argObject = asObject2(args);
13964
15606
  for (const key of argNames) {
13965
15607
  const value = argObject[key];
13966
15608
  if (typeof value !== "string" || value.length === 0) continue;
@@ -14728,7 +16370,7 @@ function mcp(config) {
14728
16370
  }
14729
16371
 
14730
16372
  // src/plugins/builtin/rateLimit.ts
14731
- function sleep(ms, signal) {
16373
+ function sleep2(ms, signal) {
14732
16374
  return new Promise((resolve) => {
14733
16375
  let timer;
14734
16376
  const done = () => {
@@ -14785,7 +16427,7 @@ function rateLimit(config = {}) {
14785
16427
  while (!attempt.ok) {
14786
16428
  const remaining = deadline - Date.now();
14787
16429
  if (!Number.isFinite(attempt.waitMs) || attempt.waitMs > remaining) break;
14788
- await sleep(Math.max(1, attempt.waitMs), ctx.signal);
16430
+ await sleep2(Math.max(1, attempt.waitMs), ctx.signal);
14789
16431
  if (ctx.signal?.aborted) break;
14790
16432
  attempt = consume(applicable);
14791
16433
  }
@@ -15881,18 +17523,21 @@ function langfuseTracing(config = {}) {
15881
17523
  }
15882
17524
 
15883
17525
  // src/plugins/builtin/otel.ts
15884
- function toSessionStatus(status) {
15885
- if (status === "success") return "success";
15886
- if (status === "error") return "error";
15887
- return status === "paused" ? "in_progress" : "partial";
15888
- }
15889
- function otelTracing(config) {
15890
- const endpoint = config.endpoint?.trim();
15891
- if (!endpoint) {
17526
+ function otelTracing(config = {}) {
17527
+ if (config.endpoint !== void 0 && !config.endpoint.trim()) {
15892
17528
  throw new Error("[agent-sdk] otelTracing requires a non-empty `endpoint`.");
15893
17529
  }
17530
+ const name = config.name ?? "otel-tracing";
17531
+ let exporter;
17532
+ try {
17533
+ exporter = createOtlpExporter({ ...config, endpoint: config.endpoint?.trim(), name });
17534
+ } catch {
17535
+ throw new Error(
17536
+ "[agent-sdk] otelTracing requires a non-empty `endpoint` (or OTEL_EXPORTER_OTLP_ENDPOINT / OTEL_EXPORTER_OTLP_TRACES_ENDPOINT in the environment)."
17537
+ );
17538
+ }
15894
17539
  return {
15895
- name: config.name ?? "otel-tracing",
17540
+ name,
15896
17541
  // Registers only the `sessionEnd` observer, and observers run concurrently,
15897
17542
  // so this number orders nothing at runtime. It is set above checkpointing
15898
17543
  // (900) to record intent: this plugin is the last thing interested in the
@@ -15900,8 +17545,9 @@ function otelTracing(config) {
15900
17545
  priority: 950,
15901
17546
  // Observability. A dropped export is a reporting gap, never a safety hole.
15902
17547
  failureMode: "open",
17548
+ traceExporters: [exporter],
15903
17549
  hooks: {
15904
- sessionEnd: async ({ status, durationMs, error }, ctx) => {
17550
+ sessionEnd: async (_event, ctx) => {
15905
17551
  const state = ctx.state;
15906
17552
  const session = state.ctx?.__traceSession;
15907
17553
  if (isSubagentTraceScope(session)) return;
@@ -15911,57 +17557,29 @@ function otelTracing(config) {
15911
17557
  ctx.emit({ type: "metadata", otelTracing: { exported: false, reason: message } });
15912
17558
  return;
15913
17559
  }
15914
- const endedAtMs = Date.now();
15915
- const startedAtIso = new Date(session.startedAt).toISOString();
15916
- const errors = error ? [...session.errors, { eventId: "session", message: error.message, stack: error.stack, type: "session" }] : session.errors;
15917
- const payload = {
15918
- sessionId: session.sessionId,
15919
- traceId: session.traceId,
15920
- rootSpanId: session.rootSpanId,
15921
- threadId: session.threadId,
15922
- startedAt: startedAtIso,
15923
- endedAt: new Date(endedAtMs).toISOString(),
15924
- durationMs: durationMs ?? endedAtMs - session.startedAt,
15925
- // `service.name` is read off `agent.name` inside the conversion, so
15926
- // the override is applied here rather than by editing spans after.
15927
- agent: {
15928
- ...session.agentInfo ?? {},
15929
- name: config.serviceName ?? session.agentInfo?.name ?? session.configAgentName ?? ctx.agentName
15930
- },
15931
- metadata: session.configMetadata,
15932
- // Carried only to satisfy the type: `traceSessionToOtlp` reads the
15933
- // events, summary and identifiers, never the sink snapshot.
15934
- config: { enabled: true, logData: session.resolvedConfig.logData, sink: { type: "otlp", endpoint } },
15935
- summary: session.summary,
15936
- events: session.events,
15937
- status: toSessionStatus(status),
15938
- errors
15939
- };
15940
- try {
15941
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
15942
- if (!fetchFn) {
15943
- ctx.logger.warn("otelTracing needs fetch to be available in this runtime; export skipped.");
15944
- return;
15945
- }
15946
- const response = await fetchFn(endpoint, {
15947
- method: "POST",
15948
- headers: { "content-type": "application/json", ...config.headers ?? {} },
15949
- body: JSON.stringify(traceSessionToOtlp(payload)),
15950
- // The run is over, but a host that cancelled it should not be made
15951
- // to wait on a collector that is refusing to answer.
15952
- signal: ctx.signal
15953
- });
15954
- if (!response.ok) {
15955
- ctx.logger.warn(`otelTracing export returned HTTP ${response.status}.`);
15956
- return;
15957
- }
15958
- ctx.emit({
15959
- type: "metadata",
15960
- otelTracing: { exported: true, endpoint, spans: session.events.length + 1 }
15961
- });
15962
- } catch (err) {
15963
- ctx.logger.warn("otelTracing export failed:", err instanceof Error ? err.message : err);
17560
+ const reports = (session.exportReports ?? []).filter((report2) => !report2.sink && report2.exporter === name);
17561
+ const report = reports[reports.length - 1];
17562
+ if (!report) return;
17563
+ const { result } = report;
17564
+ if (!result.ok) {
17565
+ ctx.logger.warn(`otelTracing export failed: ${result.error ?? "unknown error"}`);
17566
+ return;
17567
+ }
17568
+ if (result.skipped) {
17569
+ ctx.emit({ type: "metadata", otelTracing: { exported: false, reason: result.reason ?? "nothing to export" } });
17570
+ return;
15964
17571
  }
17572
+ ctx.emit({
17573
+ type: "metadata",
17574
+ otelTracing: {
17575
+ exported: true,
17576
+ endpoint: report.endpoint,
17577
+ spans: result.spans,
17578
+ terminal: report.terminal,
17579
+ // A 200 that refused some spans: the collector's count and message.
17580
+ ...result.partialSuccess ? { rejectedSpans: result.partialSuccess.rejectedSpans, ...result.partialSuccess.message ? { rejectionMessage: result.partialSuccess.message } : {} } : {}
17581
+ }
17582
+ });
15965
17583
  }
15966
17584
  }
15967
17585
  };
@@ -18997,9 +20615,9 @@ function mapAnthropicStopReason(reason) {
18997
20615
  return "stop";
18998
20616
  }
18999
20617
  }
19000
- function safeJsonParse(str) {
20618
+ function safeJsonParse(str2) {
19001
20619
  try {
19002
- return JSON.parse(str);
20620
+ return JSON.parse(str2);
19003
20621
  } catch {
19004
20622
  return {};
19005
20623
  }
@@ -19869,9 +21487,9 @@ function mediaTypeToFormat(mediaType) {
19869
21487
  };
19870
21488
  return map[mediaType] ?? "png";
19871
21489
  }
19872
- function safeJsonParse2(str) {
21490
+ function safeJsonParse2(str2) {
19873
21491
  try {
19874
- return JSON.parse(str);
21492
+ return JSON.parse(str2);
19875
21493
  } catch {
19876
21494
  return {};
19877
21495
  }
@@ -20268,10 +21886,13 @@ var VertexProvider = class extends BaseProvider {
20268
21886
  textParts.push(part.text);
20269
21887
  }
20270
21888
  } else if (part.functionCall) {
21889
+ const suppliedId = typeof part.functionCall.id === "string" && part.functionCall.id ? part.functionCall.id : void 0;
21890
+ const position = toolCallIdx++;
20271
21891
  toolCalls.push({
20272
- id: `call_${toolCallIdx++}`,
21892
+ id: suppliedId ?? `call_${position}`,
20273
21893
  name: part.functionCall.name,
20274
21894
  arguments: JSON.stringify(part.functionCall.args ?? {}),
21895
+ ...suppliedId ? {} : { idSynthesized: true },
20275
21896
  ...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
20276
21897
  });
20277
21898
  }
@@ -20311,12 +21932,15 @@ var VertexProvider = class extends BaseProvider {
20311
21932
  }
20312
21933
  } else if (part.functionCall) {
20313
21934
  if (!delta.toolCalls) delta.toolCalls = [];
21935
+ const suppliedId = typeof part.functionCall.id === "string" && part.functionCall.id ? part.functionCall.id : void 0;
21936
+ const position = counter.next++;
20314
21937
  delta.toolCalls.push({
20315
21938
  // Unique across the whole stream: the adapter merges chunks by id.
20316
- id: `call_${counter.next}`,
20317
- index: counter.next++,
21939
+ id: suppliedId ?? `call_${position}`,
21940
+ index: position,
20318
21941
  name: part.functionCall.name,
20319
21942
  arguments: JSON.stringify(part.functionCall.args ?? {}),
21943
+ ...suppliedId ? {} : { idSynthesized: true },
20320
21944
  ...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
20321
21945
  });
20322
21946
  }
@@ -20369,12 +21993,12 @@ function mapGeminiFinishReason(reason) {
20369
21993
  return "stop";
20370
21994
  }
20371
21995
  }
20372
- function base64url(str) {
20373
- return Buffer.from(str).toString("base64url");
21996
+ function base64url(str2) {
21997
+ return Buffer.from(str2).toString("base64url");
20374
21998
  }
20375
- function safeJsonParse3(str) {
21999
+ function safeJsonParse3(str2) {
20376
22000
  try {
20377
- return JSON.parse(str);
22001
+ return JSON.parse(str2);
20378
22002
  } catch {
20379
22003
  return {};
20380
22004
  }
@@ -20402,6 +22026,6 @@ function createProvider(config) {
20402
22026
  }
20403
22027
  }
20404
22028
 
20405
- export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, GuardrailPhase, HOOK_CONTRACT_VERSION, HOOK_NAMES, HookTimeoutError, InMemoryMemoryStore, JevProvider, LAST_SUMMARIZATION_CALL_KEY, MAX_ADJUSTMENTS, MODEL_RULES, ModelRequestError, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, PREOPEN_TOOL_CALL_PREFIX, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, allowsSampling, appendBoundTools, applyDropParams, asModelRequestError, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, clearLearnedModelRules, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentPartToText, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, describeContentPart, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, effortBudget, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText, fileCheckpointStore, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getLearnedModelRulePatch, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasMediaPart, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isOpenAIHostedEndpoint, isSmartModel, isTraceSessionOpen, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, listLearnedModelRules, loadSkillsFromDisk, mapConsoleHookVerdict, mapReasoningEffort, mapTextParts, mcp, mediaKindOf, mediaPolicy, mergeRulePatch, modelIdCandidates, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseModelError, parseSkillFrontmatter, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, prepareStrictToolMenu, promptInjectionGuard, rateLimit, readMemoryFacts, readTraceContinuation, recordOrDeferTraceEvent, redactText, regexGuardrail, regexRule, rememberModelRulePatch, replaceTextContent, replayDeferredTraceEvents, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveModelRule, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, restoreToolCalls, runSmartAgentEvalHarness, runWithModelAdjustments, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, supportsAdaptiveThinking, textFromContent, toMessageUsage, toModelResult, toStrictCompatible, toStrictToolSchema, tokenize, toolPolicy, traceContinuationOf, traceSectionsFromMessages, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
22029
+ export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, GENAI_SEMCONV_COMMIT, GuardrailPhase, HOOK_CONTRACT_VERSION, HOOK_NAMES, HookTimeoutError, InMemoryMemoryStore, JevProvider, LAST_SUMMARIZATION_CALL_KEY, MAX_ADJUSTMENTS, MODEL_RULES, ModelRequestError, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, PREOPEN_TOOL_CALL_PREFIX, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, allowsSampling, appendBoundTools, applyDropParams, asModelRequestError, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, clearLearnedModelRules, closeTraceContinuation, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentPartToText, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createOtlpExporter, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, describeContentPart, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, effortBudget, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText, fileCheckpointStore, fileSink, findSubagent, foldSupersededSpans, formatTraceparent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getLearnedModelRulePatch, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasMediaPart, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isOpenAIHostedEndpoint, isSmartModel, isTraceSessionOpen, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, listLearnedModelRules, loadSkillsFromDisk, mapConsoleHookVerdict, mapReasoningEffort, mapTextParts, mcp, mediaKindOf, mediaPolicy, mergeRulePatch, modelIdCandidates, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseModelError, parseSkillFrontmatter, parseTraceparent, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, prepareStrictToolMenu, promptInjectionGuard, rateLimit, readMemoryFacts, readTraceContinuation, recordOrDeferTraceEvent, redactText, regexGuardrail, regexRule, rememberModelRulePatch, replaceTextContent, replayDeferredTraceEvents, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveModelRule, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, restoreToolCalls, runSmartAgentEvalHarness, runWithModelAdjustments, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, supportsAdaptiveThinking, textFromContent, toMessageUsage, toModelResult, toStrictCompatible, toStrictToolSchema, tokenize, toolPolicy, traceContinuationOf, traceSectionsFromMessages, traceSessionToOtlp, traceparentOf, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
20406
22030
  //# sourceMappingURL=index.mjs.map
20407
22031
  //# sourceMappingURL=index.mjs.map