@cognipeer/agent-sdk 0.16.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
+ })()
2097
3337
  };
2098
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 } } : {}
3359
+ };
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;
@@ -2203,7 +3520,7 @@ function recordTraceEvent(session, event) {
2203
3520
  const baseLabel = event.label?.trim().length ? event.label.trim() : defaultEventLabel(event.type);
2204
3521
  const eventLabel = `${baseLabel} #${sequence}`;
2205
3522
  const durationMs = event.durationMs !== void 0 ? Number(event.durationMs) : void 0;
2206
- if (!Number.isNaN(durationMs ?? NaN) && durationMs !== void 0) {
3523
+ if (!Number.isNaN(durationMs ?? NaN) && durationMs !== void 0 && event.countDuration !== false && !isSubagentTraceScope(session)) {
2207
3524
  session.summary.totalDurationMs += durationMs;
2208
3525
  }
2209
3526
  const inputTokens = event.inputTokens !== void 0 ? Number(event.inputTokens) : void 0;
@@ -2252,10 +3569,20 @@ 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
+ }
3576
+ if (event.alwaysSections?.length) {
3577
+ const identity2 = event.alwaysSections.map(
3578
+ (section) => section.kind === "metadata" ? { ...section, identity: true } : section
3579
+ );
3580
+ sections = ensureUniqueSections(id, [...identity2, ...sections ?? []]);
3581
+ }
2255
3582
  const resolvedModel = event.model ?? inferModelFromMessages(event.messageList);
2256
3583
  const resolvedProvider = event.provider ?? inferProviderFromMessages(event.messageList);
2257
3584
  const isAiCall = event.type === "ai_call";
2258
- const spanId = generateSpanId();
3585
+ const spanId = event.spanId || generateSpanId();
2259
3586
  const parentSpanId = event.parentSpanId || session.currentIterationSpanId || session.rootSpanId;
2260
3587
  const record = {
2261
3588
  sessionId: session.sessionId,
@@ -2286,6 +3613,16 @@ function recordTraceEvent(session, event) {
2286
3613
  // different facts, and a zero would erase the difference.
2287
3614
  ...reasoningTokens !== void 0 && !Number.isNaN(reasoningTokens) ? { reasoningTokens } : {},
2288
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 } : {},
2289
3626
  requestBytes,
2290
3627
  responseBytes,
2291
3628
  model: resolvedModel,
@@ -2307,6 +3644,15 @@ function recordTraceEvent(session, event) {
2307
3644
  timestamp: timestampIso
2308
3645
  });
2309
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
+ }
2310
3656
  session.events.push(record);
2311
3657
  const sink = session.resolvedConfig.sink;
2312
3658
  if (sink.type === "custom" && typeof sink.onEvent === "function") {
@@ -2349,6 +3695,69 @@ var DEFERRED_TRACE_EVENTS_KEY = "__deferredTraceEvents";
2349
3695
  function isTraceSessionOpen(session) {
2350
3696
  return Boolean(session) && !session.closed;
2351
3697
  }
3698
+ var SUBAGENT_TRACE_SCOPE = Symbol("subagentTraceScope");
3699
+ function createSubagentTraceScope(parent, info) {
3700
+ const scope = { ...info, iterations: info.iterations ?? 0 };
3701
+ let currentIterationSpanId;
3702
+ return new Proxy(parent, {
3703
+ get(target, prop) {
3704
+ if (prop === SUBAGENT_TRACE_SCOPE) return scope;
3705
+ if (prop === "rootSpanId") return scope.agentSpanId;
3706
+ if (prop === "currentIterationSpanId") return currentIterationSpanId;
3707
+ return Reflect.get(target, prop);
3708
+ },
3709
+ set(target, prop, value) {
3710
+ if (prop === "currentIterationSpanId") {
3711
+ currentIterationSpanId = value;
3712
+ return true;
3713
+ }
3714
+ return Reflect.set(target, prop, value);
3715
+ }
3716
+ });
3717
+ }
3718
+ function subagentTraceScopeOf(session) {
3719
+ if (!session) return void 0;
3720
+ return session[SUBAGENT_TRACE_SCOPE];
3721
+ }
3722
+ function canPauseForHuman(session) {
3723
+ return subagentTraceScopeOf(session)?.hitl !== false;
3724
+ }
3725
+ function isSubagentTraceScope(session) {
3726
+ return subagentTraceScopeOf(session) !== void 0;
3727
+ }
3728
+ function recordSubagentSpan(session, span) {
3729
+ const sections = [];
3730
+ if (session.resolvedConfig.logData) {
3731
+ if (span.task !== void 0) sections.push({ kind: "message", label: "Task", role: "user", content: span.task });
3732
+ if (span.result) sections.push({ kind: "message", label: "Result", role: "assistant", content: span.result });
3733
+ }
3734
+ recordTraceEvent(session, {
3735
+ type: "span",
3736
+ spanId: span.spanId,
3737
+ parentSpanId: span.parentSpanId,
3738
+ label: `Sub-agent ${span.name}`,
3739
+ actor: { scope: "agent", name: span.name, role: "subagent" },
3740
+ status: span.status,
3741
+ durationMs: span.durationMs,
3742
+ // The child's own calls and the delegating tool_call already hold this time.
3743
+ countDuration: false,
3744
+ ...span.error ? { error: { message: span.error } } : {},
3745
+ // The Console reads which sub-agent ran from here, so it survives logData off.
3746
+ alwaysSections: [{ kind: "metadata", label: "Sub-agent", data: sanitizeTracePayload(span.info) }],
3747
+ sections
3748
+ });
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
+ }
2352
3761
  function recordOrDeferTraceEvent(ctx, event, options) {
2353
3762
  const session = ctx?.__traceSession;
2354
3763
  if (isTraceSessionOpen(session)) {
@@ -2359,7 +3768,8 @@ function recordOrDeferTraceEvent(ctx, event, options) {
2359
3768
  const held = Array.isArray(ctx?.[DEFERRED_TRACE_EVENTS_KEY]) ? ctx[DEFERRED_TRACE_EVENTS_KEY] : [];
2360
3769
  return {
2361
3770
  ...ctx || {},
2362
- [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() }]
2363
3773
  };
2364
3774
  }
2365
3775
  function replayDeferredTraceEvents(session, deferred) {
@@ -2393,6 +3803,7 @@ async function finalizeTraceSession(session, params = {}) {
2393
3803
  message: params.error.message || "Unknown error",
2394
3804
  stack: params.error.stack,
2395
3805
  type: "session",
3806
+ ...params.error.name ? { errorName: params.error.name } : {},
2396
3807
  timestamp: endedAtIso
2397
3808
  });
2398
3809
  }
@@ -2416,24 +3827,62 @@ async function finalizeTraceSession(session, params = {}) {
2416
3827
  ...(session.part ?? 1) > 1 ? { continuation: { part: session.part, firstSequence: (session.sequenceOffset ?? 0) + 1 } } : {}
2417
3828
  });
2418
3829
  const payloadForSink = buildPayload(initialStatus);
3830
+ const carried = session.carriedSpans ?? [];
3831
+ const exportPayload = carried.length > 0 ? { ...payloadForSink, events: [...carried, ...payloadForSink.events] } : payloadForSink;
2419
3832
  let sinkFailed = false;
2420
3833
  const sink = session.resolvedConfig.sink;
2421
3834
  const isStreamingMode = session.resolvedConfig.mode === "streaming";
2422
- if (sink.type === "otlp") {
2423
- try {
2424
- const otlpPayload = traceSessionToOtlp(payloadForSink);
2425
- await postOtlpTraces(sink.endpoint, sink.headers, otlpPayload);
2426
- } catch (err) {
2427
- sinkFailed = true;
2428
- const message = err instanceof Error ? err.message : String(err);
2429
- session.errors.push({
2430
- eventId: "sink",
2431
- message,
2432
- type: "sink",
2433
- timestamp: endedAtIso
2434
- });
2435
- }
2436
- } 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") {
2437
3886
  try {
2438
3887
  const headers = sink.type === "cognipeer" ? { Authorization: `Bearer ${sink.apiKey}` } : sink.headers;
2439
3888
  if (isStreamingMode && session.sessionStarted) {
@@ -2529,6 +3978,23 @@ async function finalizeTraceSession(session, params = {}) {
2529
3978
  }
2530
3979
  return finalPayload;
2531
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
+ }
2532
3998
  function sanitizeTracePayload(value) {
2533
3999
  if (value === void 0) return void 0;
2534
4000
  try {
@@ -2568,6 +4034,72 @@ function estimatePayloadBytes(value) {
2568
4034
  }
2569
4035
  }
2570
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
+ }
2571
4103
  function toMessageUsage(u) {
2572
4104
  return {
2573
4105
  prompt_tokens: u.inputTokens,
@@ -2590,7 +4122,12 @@ function fromNativeProvider(provider, options) {
2590
4122
  if (link.signal) request.signal = link.signal;
2591
4123
  request = await applyTransform(request);
2592
4124
  const response = await provider.complete(request);
2593
- 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
+ });
2594
4131
  } finally {
2595
4132
  link.dispose();
2596
4133
  }
@@ -2609,6 +4146,8 @@ function fromNativeProvider(provider, options) {
2609
4146
  let reasoningText = "";
2610
4147
  let finishReason;
2611
4148
  let responseModel;
4149
+ let responseId;
4150
+ let rawFinishReason;
2612
4151
  const toolCallBuffers = /* @__PURE__ */ new Map();
2613
4152
  for await (const chunk of provider.completeStream(request)) {
2614
4153
  if (chunk.delta.content) {
@@ -2616,6 +4155,8 @@ function fromNativeProvider(provider, options) {
2616
4155
  yield chunk.delta.content;
2617
4156
  }
2618
4157
  if (chunk.model) responseModel = chunk.model;
4158
+ if (chunk.id) responseId = chunk.id;
4159
+ if (chunk.rawFinishReason) rawFinishReason = chunk.rawFinishReason;
2619
4160
  if (chunk.finishReason) finishReason = chunk.finishReason;
2620
4161
  if (chunk.delta.reasoning?.blocks?.length) {
2621
4162
  reasoningBlocks = chunk.delta.reasoning.blocks;
@@ -2637,7 +4178,8 @@ function fromNativeProvider(provider, options) {
2637
4178
  id: tc.id,
2638
4179
  name: tc.name ?? "",
2639
4180
  arguments: tc.arguments ?? "",
2640
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4181
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4182
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
2641
4183
  });
2642
4184
  }
2643
4185
  }
@@ -2661,7 +4203,13 @@ function fromNativeProvider(provider, options) {
2661
4203
  ...responseModel ? { model_name: responseModel } : {}
2662
4204
  };
2663
4205
  }
2664
- yield finalMessage;
4206
+ yield attachWireInfo(finalMessage, {
4207
+ provider: provider.providerName,
4208
+ responseId,
4209
+ responseModel,
4210
+ rawFinishReason,
4211
+ streaming: true
4212
+ });
2665
4213
  } finally {
2666
4214
  link.dispose();
2667
4215
  }
@@ -3035,7 +4583,8 @@ function toBaseChatMessage(response) {
3035
4583
  id: tc.id,
3036
4584
  type: "function",
3037
4585
  function: { name: tc.name, arguments: tc.arguments },
3038
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4586
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4587
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
3039
4588
  }));
3040
4589
  }
3041
4590
  if (response.reasoning && (response.reasoning.blocks?.length || response.reasoning.summary)) {
@@ -3057,7 +4606,8 @@ function assembleMessage(content, toolCalls, usage) {
3057
4606
  id: tc.id,
3058
4607
  type: "function",
3059
4608
  function: { name: tc.name, arguments: tc.arguments },
3060
- ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
4609
+ ...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
4610
+ ...tc.idSynthesized ? { idSynthesized: true } : {}
3061
4611
  }));
3062
4612
  }
3063
4613
  return msg;
@@ -3951,7 +5501,7 @@ var CCRStore = class _CCRStore {
3951
5501
  }
3952
5502
  static hashOf(value) {
3953
5503
  const serialized = typeof value === "string" ? value : JSON.stringify(value);
3954
- return createHash("sha1").update(serialized).digest("hex").slice(0, 16);
5504
+ return createHash("sha256").update(serialized).digest("hex").slice(0, 16);
3955
5505
  }
3956
5506
  };
3957
5507
  var DedupTracker = class {
@@ -3964,7 +5514,7 @@ var DedupTracker = class {
3964
5514
  * first time it has been seen.
3965
5515
  */
3966
5516
  checkAndRegister(content, executionId, toolName) {
3967
- const hash = createHash("sha1").update(content).digest("hex");
5517
+ const hash = createHash("sha256").update(content).digest("hex");
3968
5518
  const existing = this.seen.get(hash);
3969
5519
  if (!existing) {
3970
5520
  this.seen.set(hash, { executionId, toolName });
@@ -4501,7 +6051,7 @@ function createAgentCoreNode(opts) {
4501
6051
  const actorVersion = runtime.version ?? opts.version;
4502
6052
  let traceToolDefinitions;
4503
6053
  const computeTraceToolDefinitions = (menu) => {
4504
- 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;
4505
6055
  try {
4506
6056
  const wire = shouldUseStrictToolCalling ? prepareStrictToolMenu(menu).menu : menu;
4507
6057
  return wire.map((tool) => {
@@ -4714,8 +6264,9 @@ ${append}`;
4714
6264
  // outcome, and an "error" status would flip the whole trace session
4715
6265
  // status to error for a run that behaved exactly as configured.
4716
6266
  status: "skipped",
6267
+ skipReason: "blocked",
4717
6268
  model: getModelName(runtime.model || opts.model),
4718
- provider: getProviderName(runtime.model || opts.model),
6269
+ provider: providerHintOf(runtime.model || opts.model),
4719
6270
  messageList: state.messages
4720
6271
  });
4721
6272
  return {
@@ -4744,9 +6295,12 @@ ${append}`;
4744
6295
  for (const key of ["usage", "usage_metadata", "response_metadata"]) {
4745
6296
  if (merged[key] === void 0 && original?.[key] !== void 0) merged[key] = original[key];
4746
6297
  }
6298
+ if (wireInfoOf(merged) === void 0 && wireInfoOf(original) !== void 0) merged[WIRE_INFO] = wireInfoOf(original);
4747
6299
  return merged;
4748
6300
  };
4749
6301
  let response;
6302
+ let sentMessages;
6303
+ let streamedCall = false;
4750
6304
  let modelAttempt = 0;
4751
6305
  const maxModelRetries = host?.maxModelRetries ?? 0;
4752
6306
  const finishCancelledTurn = (partialText) => {
@@ -4760,12 +6314,16 @@ ${append}`;
4760
6314
  // "skipped", not "error": the call did not fail, the caller ended it —
4761
6315
  // and an "error" would flip the whole session to error.
4762
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 } : {},
4763
6320
  durationMs: Date.now() - start,
4764
6321
  requestBytes: promptBytes,
4765
6322
  model: getModelName(runtime.model || opts.model),
4766
- provider: getProviderName(runtime.model || opts.model),
6323
+ provider: providerHintOf(runtime.model || opts.model),
4767
6324
  messageList: state.messages,
4768
- toolDefinitions: traceToolDefinitions
6325
+ toolDefinitions: traceToolDefinitions,
6326
+ capture: { input: sentMessages ?? wireMessages, toolDefinitions: traceToolDefinitions }
4769
6327
  });
4770
6328
  onEvent?.({ type: "cancelled", stage: "agent", reason });
4771
6329
  onProgress?.({ stage: "agent", message: "Cancelled", detail: { reason } });
@@ -4781,8 +6339,9 @@ ${append}`;
4781
6339
  label: "Assistant (plugin short-circuit)",
4782
6340
  actor: { scope: "agent", name: actorName, role: "assistant", version: actorVersion },
4783
6341
  status: "skipped",
6342
+ skipReason: "short_circuit",
4784
6343
  model: getModelName(runtime.model || opts.model),
4785
- provider: getProviderName(runtime.model || opts.model),
6344
+ provider: providerHintOf(runtime.model || opts.model),
4786
6345
  messageList: state.messages,
4787
6346
  toolDefinitions: traceToolDefinitions
4788
6347
  });
@@ -4790,8 +6349,10 @@ ${append}`;
4790
6349
  let streamedText = "";
4791
6350
  try {
4792
6351
  const normalizedMessages = normalizeBedrockToolPairing([...wireMessages]);
6352
+ sentMessages = normalizedMessages;
4793
6353
  debugToolPairing(normalizedMessages);
4794
6354
  if (streamingEnabled && typeof modelWithTools.stream === "function") {
6355
+ streamedCall = true;
4795
6356
  let streamedMessage;
4796
6357
  let cutByCancel = false;
4797
6358
  for await (const chunk of modelWithTools.stream(normalizedMessages, invokeParams)) {
@@ -4837,12 +6398,14 @@ ${append}`;
4837
6398
  durationMs: durationMs2,
4838
6399
  requestBytes: promptBytes,
4839
6400
  model: getModelName(runtime.model || opts.model),
4840
- provider: getProviderName(runtime.model || opts.model),
4841
- error: { message: err?.message || String(err), stack: err?.stack },
6401
+ provider: providerHintOf(runtime.model || opts.model),
6402
+ error: traceErrorOf(err),
6403
+ ...streamedCall ? { streaming: true } : {},
4842
6404
  messageList: state.messages,
4843
6405
  toolDefinitions: traceToolDefinitions,
4844
6406
  responseFormat: traceResponseFormat,
4845
- responseFormatStrategy: traceResponseFormatStrategy
6407
+ responseFormatStrategy: traceResponseFormatStrategy,
6408
+ capture: { input: sentMessages ?? wireMessages, toolDefinitions: traceToolDefinitions }
4846
6409
  });
4847
6410
  throw err;
4848
6411
  }
@@ -4895,6 +6458,8 @@ ${append}`;
4895
6458
  const responsePayload = shouldLogResponse ? sanitizeTracePayload(response) : void 0;
4896
6459
  const responseBytes = responsePayload !== void 0 ? estimatePayloadBytes(responsePayload) : void 0;
4897
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";
4898
6463
  recordTraceEvent(traceSession, {
4899
6464
  type: "ai_call",
4900
6465
  label: "Assistant Response",
@@ -4911,11 +6476,13 @@ ${append}`;
4911
6476
  requestBytes: promptBytes,
4912
6477
  responseBytes,
4913
6478
  model: modelName,
4914
- provider: getProviderName(runtime.model || opts.model),
6479
+ ...facts,
6480
+ outputType: jsonOutput ? "json" : "text",
4915
6481
  messageList: messagesWithResponse,
4916
6482
  toolDefinitions: traceToolDefinitions,
4917
6483
  responseFormat: traceResponseFormat,
4918
- responseFormatStrategy: traceResponseFormatStrategy
6484
+ responseFormatStrategy: traceResponseFormatStrategy,
6485
+ capture: { input: sentMessages ?? wireMessages, output: response, toolDefinitions: traceToolDefinitions }
4919
6486
  });
4920
6487
  if (normalized) {
4921
6488
  recordUsage(state, modelName, normalized);
@@ -4926,6 +6493,9 @@ ${append}`;
4926
6493
 
4927
6494
  // src/utils/traceDecisions.ts
4928
6495
  var TRACED_KEY = "__outcomeTraced";
6496
+ function surfacedFromSubagent(entry) {
6497
+ return Boolean(entry.metadata?.__subagent);
6498
+ }
4929
6499
  function waitedMs(from, to) {
4930
6500
  if (!from || !to) return void 0;
4931
6501
  const ms = Date.parse(to) - Date.parse(from);
@@ -4938,8 +6508,14 @@ function sameJson(a, b) {
4938
6508
  return false;
4939
6509
  }
4940
6510
  }
6511
+ var idSection = (label, data) => ({
6512
+ kind: "metadata",
6513
+ label,
6514
+ data,
6515
+ identity: true
6516
+ });
4941
6517
  function recordApprovalRequested(session, entry) {
4942
- if (!session) return;
6518
+ if (!session || surfacedFromSubagent(entry) || !canPauseForHuman(session)) return;
4943
6519
  const logData = session.resolvedConfig.logData;
4944
6520
  const sections = [
4945
6521
  {
@@ -4963,14 +6539,14 @@ function recordApprovalRequested(session, entry) {
4963
6539
  timestamp: entry.requestedAt,
4964
6540
  status: "pending",
4965
6541
  actor: { scope: "agent", name: entry.toolName, role: "approval_request" },
4966
- sections
6542
+ sections: [...sections, idSection("Approval ids", { approvalId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt })]
4967
6543
  });
4968
6544
  }
4969
6545
  function recordHumanDecisions(session, state) {
4970
6546
  if (!session) return;
4971
6547
  const logData = session.resolvedConfig.logData;
4972
6548
  for (const entry of state.pendingApprovals ?? []) {
4973
- if (!entry.decidedAt || entry.metadata?.[TRACED_KEY]) continue;
6549
+ if (!entry.decidedAt || entry.metadata?.[TRACED_KEY] || surfacedFromSubagent(entry)) continue;
4974
6550
  if (entry.status !== "approved" && entry.status !== "rejected") continue;
4975
6551
  const approved = entry.status === "approved";
4976
6552
  const edited = approved && entry.approvedArgs !== void 0 && !sameJson(entry.approvedArgs, entry.args);
@@ -5004,12 +6580,19 @@ function recordHumanDecisions(session, state) {
5004
6580
  durationMs: waitedMs(entry.requestedAt, entry.decidedAt),
5005
6581
  status: "success",
5006
6582
  actor: { scope: "human", name: entry.decidedBy || "reviewer", role: "approver" },
5007
- 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
+ })]
5008
6591
  });
5009
6592
  entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
5010
6593
  }
5011
6594
  for (const entry of state.pendingUserQuestions ?? []) {
5012
- if (!entry.answeredAt || entry.metadata?.[TRACED_KEY]) continue;
6595
+ if (!entry.answeredAt || entry.metadata?.[TRACED_KEY] || surfacedFromSubagent(entry)) continue;
5013
6596
  if (entry.status !== "answered" && entry.status !== "cancelled") continue;
5014
6597
  const clientTool = readClientTool(entry);
5015
6598
  if (clientTool) {
@@ -5049,13 +6632,20 @@ function recordHumanDecisions(session, state) {
5049
6632
  durationMs: waitedMs(entry.requestedAt, entry.answeredAt),
5050
6633
  status: cancelled ? "skipped" : "success",
5051
6634
  actor: { scope: "human", name: entry.answeredBy || "user", role: "user" },
5052
- 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
+ })]
5053
6643
  });
5054
6644
  entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
5055
6645
  }
5056
6646
  }
5057
6647
  function recordClientToolRequested(session, entry) {
5058
- if (!session) return;
6648
+ if (!session || surfacedFromSubagent(entry) || !canPauseForHuman(session)) return;
5059
6649
  const clientTool = readClientTool(entry);
5060
6650
  if (!clientTool) return;
5061
6651
  const sections = [
@@ -5074,7 +6664,7 @@ function recordClientToolRequested(session, entry) {
5074
6664
  timestamp: entry.requestedAt,
5075
6665
  status: "pending",
5076
6666
  actor: { scope: "client", name: clientTool.name, role: "tool" },
5077
- sections
6667
+ sections: [...sections, idSection("Client tool ids", { questionId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt })]
5078
6668
  });
5079
6669
  }
5080
6670
  function readClientTool(entry) {
@@ -5121,7 +6711,14 @@ function recordClientToolResult(session, entry, clientTool, toolHistory) {
5121
6711
  durationMs: waitedMs(entry.requestedAt, entry.answeredAt) ?? ranMs,
5122
6712
  status: failed ? "error" : "success",
5123
6713
  actor: { scope: "client", name: clientTool.name, role: "tool" },
5124
- 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
+ })]
5125
6722
  });
5126
6723
  }
5127
6724
 
@@ -5227,9 +6824,11 @@ function normalizeToolCall(call) {
5227
6824
  return {
5228
6825
  id: call.id,
5229
6826
  name,
5230
- 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 } : {}
5231
6829
  };
5232
6830
  }
6831
+ var providerToolCallId = (tc) => tc.id && !tc.idSynthesized ? tc.id : void 0;
5233
6832
  function normalizeToolSchema(tool, toolName) {
5234
6833
  const schema = tool.schema;
5235
6834
  if (!schema) return void 0;
@@ -5487,6 +7086,8 @@ function createToolsNode(initialTools, opts) {
5487
7086
  label: `Tool Denied - ${toolName}`,
5488
7087
  actor: { scope: "tool", name: toolName, role: "tool" },
5489
7088
  status: "skipped",
7089
+ skipReason: "denied",
7090
+ toolCallId: providerToolCallId(tc),
5490
7091
  toolDetails,
5491
7092
  toolExecutionId: toolCallId,
5492
7093
  sections: buildToolTraceSections({
@@ -5558,6 +7159,8 @@ function createToolsNode(initialTools, opts) {
5558
7159
  label: `Tool Skipped - ${toolName}`,
5559
7160
  actor: { scope: "tool", name: toolName, role: "tool" },
5560
7161
  status: "skipped",
7162
+ skipReason: "skipped",
7163
+ toolCallId: providerToolCallId(tc),
5561
7164
  toolDetails,
5562
7165
  toolExecutionId: tc.id,
5563
7166
  sections: buildToolTraceSections({
@@ -5694,10 +7297,13 @@ function createToolsNode(initialTools, opts) {
5694
7297
  label: `Tool Error - ${toolName}`,
5695
7298
  actor: { scope: "tool", name: toolName, role: "tool" },
5696
7299
  status: "error",
7300
+ // The tool was not run: an open breaker refused the call.
7301
+ skipReason: "skipped",
7302
+ toolCallId: providerToolCallId(tc),
5697
7303
  requestBytes: inputBytes,
5698
7304
  toolDetails,
5699
7305
  toolExecutionId: toolCallId,
5700
- error: { message: breakerMsg },
7306
+ error: { message: breakerMsg, type: "circuit_breaker_open" },
5701
7307
  sections: buildToolTraceSections({
5702
7308
  args,
5703
7309
  executionId: toolCallId,
@@ -5711,6 +7317,7 @@ function createToolsNode(initialTools, opts) {
5711
7317
  toolCount += 1;
5712
7318
  return { status: "error" };
5713
7319
  }
7320
+ let traceSpanId;
5714
7321
  try {
5715
7322
  if (cachedHit !== void 0) {
5716
7323
  const executionId2 = nanoid();
@@ -5756,6 +7363,9 @@ function createToolsNode(initialTools, opts) {
5756
7363
  type: "tool_call",
5757
7364
  label: shortCircuitSource === "plugin" ? `Tool Short-Circuited - ${toolName}` : `Tool Execution - ${toolName}`,
5758
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),
5759
7369
  durationMs: 0,
5760
7370
  requestBytes: inputBytes,
5761
7371
  responseBytes: outputBytes2,
@@ -5790,7 +7400,16 @@ function createToolsNode(initialTools, opts) {
5790
7400
  onEvent?.({ type: "tool_call", phase: "start", name: toolName, id: tc.id, args });
5791
7401
  onProgress?.({ stage: "tools", message: `Running tool ${tc.name}` });
5792
7402
  const anyTool = tool;
5793
- const callOptions = { cancellationToken, signal: abortSignal, toolCallId };
7403
+ traceSpanId = traceSession ? generateSpanId() : void 0;
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
+ };
5794
7413
  const invokeOnce = async () => {
5795
7414
  if (typeof anyTool.func === "function") return anyTool.func(args, callOptions);
5796
7415
  if (typeof anyTool.invoke === "function") return anyTool.invoke(args, callOptions);
@@ -5973,9 +7592,13 @@ function createToolsNode(initialTools, opts) {
5973
7592
  const outputBytes = traceSession?.resolvedConfig.logData ? estimatePayloadBytes(sanitizedOutput) : void 0;
5974
7593
  recordTraceEvent(traceSession, {
5975
7594
  type: "tool_call",
7595
+ spanId: traceSpanId,
5976
7596
  label: `Tool Execution - ${toolName}`,
5977
7597
  actor: { scope: "tool", name: toolName, role: "tool" },
5978
- ...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 },
5979
7602
  durationMs,
5980
7603
  requestBytes: inputBytes,
5981
7604
  responseBytes: outputBytes,
@@ -6035,15 +7658,18 @@ function createToolsNode(initialTools, opts) {
6035
7658
  const errorOutput = { message, stack: host?.has("postToolUse") ? void 0 : error?.stack };
6036
7659
  recordTraceEvent(traceSession, {
6037
7660
  type: "tool_call",
7661
+ spanId: traceSpanId,
6038
7662
  label: `Tool Error - ${toolName}`,
6039
7663
  actor: { scope: "tool", name: toolName, role: "tool" },
6040
7664
  status: "error",
7665
+ toolCallId: providerToolCallId(tc),
7666
+ capture: { toolArguments: args },
6041
7667
  durationMs,
6042
7668
  requestBytes: inputBytes,
6043
7669
  responseBytes: traceSession?.resolvedConfig.logData ? estimatePayloadBytes(errorOutput) : void 0,
6044
7670
  toolDetails,
6045
7671
  toolExecutionId: executionId,
6046
- error: { message, stack: host?.has("postToolUse") ? void 0 : error?.stack },
7672
+ error: { ...traceErrorOf(error), message, stack: host?.has("postToolUse") ? void 0 : error?.stack },
6047
7673
  sections: buildToolTraceSections({
6048
7674
  args: sanitizedArgs,
6049
7675
  durationMs,
@@ -6158,6 +7784,8 @@ function createToolsNode(initialTools, opts) {
6158
7784
  label: `Tool Skipped - ${tc.name}`,
6159
7785
  actor: { scope: "tool", name: tc.name, role: "tool" },
6160
7786
  status: "skipped",
7787
+ skipReason: "skipped",
7788
+ toolCallId: providerToolCallId(tc),
6161
7789
  toolDetails,
6162
7790
  toolExecutionId: tc.id,
6163
7791
  sections: buildToolTraceSections({
@@ -6324,7 +7952,7 @@ function createReflectionNode(opts, resolved) {
6324
7952
  label: "Reflection error",
6325
7953
  actor: { scope: "agent", name: opts.name || "agent", role: "reflection" },
6326
7954
  status: "error",
6327
- error: { message: err?.message || String(err) }
7955
+ error: traceErrorOf(err)
6328
7956
  });
6329
7957
  return {};
6330
7958
  }
@@ -6995,7 +8623,7 @@ function createAskUserQuestionTool(stateRef, config) {
6995
8623
  questions: entry.questions,
6996
8624
  allowFreeText
6997
8625
  });
6998
- recordTraceEvent(ctx.__traceSession, {
8626
+ if (canPauseForHuman(ctx.__traceSession)) recordTraceEvent(ctx.__traceSession, {
6999
8627
  type: "user_question",
7000
8628
  label: "Question to user",
7001
8629
  timestamp: entry.requestedAt,
@@ -7335,7 +8963,7 @@ function buildSubagentCatalogBlock(subagents, policy, toolNames, opts) {
7335
8963
  // src/plugins/host.ts
7336
8964
  init_content();
7337
8965
  var DEFAULT_PRIORITY = 100;
7338
- var DEFAULT_TIMEOUT_MS = 1e4;
8966
+ var DEFAULT_TIMEOUT_MS2 = 1e4;
7339
8967
  var HOOK_SPECS = {
7340
8968
  sessionStart: { kind: "gate", mutable: ["messages"], collect: ["systemPromptAppend"] },
7341
8969
  userPromptSubmit: {
@@ -7440,7 +9068,7 @@ function collectRegistrations(plugin, registrations, into, orderRef) {
7440
9068
  plugin: plugin.name,
7441
9069
  priority: plugin.priority ?? DEFAULT_PRIORITY,
7442
9070
  failureMode: plugin.failureMode ?? "open",
7443
- timeoutMs: plugin.timeoutMs ?? DEFAULT_TIMEOUT_MS,
9071
+ timeoutMs: plugin.timeoutMs ?? DEFAULT_TIMEOUT_MS2,
7444
9072
  order: orderRef.value++,
7445
9073
  handler
7446
9074
  });
@@ -7495,6 +9123,7 @@ function createPluginHost(plugins = [], options = {}) {
7495
9123
  let contributions = {
7496
9124
  tools: [],
7497
9125
  toolDescriptions: {},
9126
+ traceExporters: [],
7498
9127
  guardrails: [],
7499
9128
  applySystemPrompt: (base) => base,
7500
9129
  applyModelWrappers: (model) => model
@@ -7503,6 +9132,7 @@ function createPluginHost(plugins = [], options = {}) {
7503
9132
  async function runSetup(setupInput) {
7504
9133
  const tools = [];
7505
9134
  const toolDescriptions = {};
9135
+ const traceExporters = [];
7506
9136
  const guardrails = [];
7507
9137
  const promptSteps = [];
7508
9138
  const modelWrappers = [];
@@ -7540,6 +9170,7 @@ function createPluginHost(plugins = [], options = {}) {
7540
9170
  );
7541
9171
  }
7542
9172
  if (plugin.toolDescriptions) Object.assign(toolDescriptions, plugin.toolDescriptions);
9173
+ if (plugin.traceExporters?.length) traceExporters.push(...plugin.traceExporters.filter(Boolean));
7543
9174
  if (plugin.guardrails?.length) guardrails.push(...plugin.guardrails);
7544
9175
  if (typeof plugin.wrapModel === "function") {
7545
9176
  modelWrappers.push({ plugin: plugin.name, wrap: plugin.wrapModel });
@@ -7555,6 +9186,7 @@ function createPluginHost(plugins = [], options = {}) {
7555
9186
  contributions = {
7556
9187
  tools,
7557
9188
  toolDescriptions,
9189
+ traceExporters,
7558
9190
  guardrails,
7559
9191
  applySystemPrompt: (base) => promptSteps.reduce((current, step) => {
7560
9192
  try {
@@ -8278,19 +9910,22 @@ function createAgent(opts) {
8278
9910
  detail: { reason: budget.reason, iteration: iterations }
8279
9911
  });
8280
9912
  }
9913
+ recordHumanDecisions(state.ctx?.__traceSession, state);
8281
9914
  const ctx = { ...state.ctx || {}, __limitBreached: budget.reason };
8282
9915
  state = { ...state, ctx };
8283
9916
  break;
8284
9917
  }
8285
9918
  const traceSession = state.ctx?.__traceSession;
8286
9919
  if (traceSession) {
8287
- const iterationNumber = (traceSession.summary.eventCounts.agent_iteration ?? 0) + 1;
9920
+ const subagentScope = subagentTraceScopeOf(traceSession);
9921
+ const iterationNumber = subagentScope ? ++subagentScope.iterations : (traceSession.summary.eventCounts.agent_iteration ?? 0) - (traceSession.summary.subagentIterations ?? 0) + 1;
8288
9922
  const iterEvent = recordTraceEvent(traceSession, {
8289
9923
  type: "agent_iteration",
8290
9924
  label: `Iteration ${iterationNumber}`,
8291
9925
  actor: { scope: "agent", name: opts.name || "agent", role: "orchestrator" },
8292
9926
  parentSpanId: traceSession.rootSpanId
8293
9927
  });
9928
+ if (subagentScope) traceSession.summary.subagentIterations = (traceSession.summary.subagentIterations ?? 0) + 1;
8294
9929
  if (iterEvent) {
8295
9930
  traceSession.currentIterationSpanId = iterEvent.spanId;
8296
9931
  }
@@ -8575,7 +10210,10 @@ function createAgent(opts) {
8575
10210
  }
8576
10211
  emit({ type: "progress", ...progress });
8577
10212
  };
8578
- 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
+ });
8579
10217
  const ctx = {
8580
10218
  ...input.ctx || {},
8581
10219
  __onEvent: onEvent,
@@ -8600,7 +10238,9 @@ function createAgent(opts) {
8600
10238
  const inheritedSession = config?.__pluginSession;
8601
10239
  ctx.__runId = inheritedSession?.runId ?? traceSession?.sessionId ?? `run_${nanoid(10)}`;
8602
10240
  const stateHolder = inheritedSession?.stateHolder ?? { value: void 0 };
8603
- const traceRecorder = createPluginTraceRecorder(() => traceSession);
10241
+ const traceRecorder = createPluginTraceRecorder(
10242
+ () => traceSession ?? (subagentTraceScopeOf(ctx.__traceSession) ? ctx.__traceSession : void 0)
10243
+ );
8604
10244
  const runHost = inheritedSession?.host ?? (pluginHost.hasAny() ? pluginHost.beginRun({
8605
10245
  runId: ctx.__runId,
8606
10246
  agentName: opts.name,
@@ -8725,7 +10365,7 @@ function createAgent(opts) {
8725
10365
  await finalizeTraceSession(traceSession, {
8726
10366
  agentRuntime: runtime,
8727
10367
  status: "error",
8728
- error: { message: err?.message, stack: err?.stack }
10368
+ error: { message: err?.message, stack: err?.stack, name: err?.name }
8729
10369
  });
8730
10370
  await endSession("error", { error: err instanceof Error ? err : new Error(String(err)), state: stateHolder.value });
8731
10371
  if (userTokenCounter) {
@@ -8746,7 +10386,10 @@ function createAgent(opts) {
8746
10386
  const midTurn = pausedForHuman || Boolean(res.ctx?.__needsSummarization);
8747
10387
  await finalizeTraceSession(traceSession, {
8748
10388
  agentRuntime: res.agent || runtime,
8749
- 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"
8750
10393
  });
8751
10394
  if (traceSession && midTurn) {
8752
10395
  res.ctx = { ...res.ctx || {}, __traceContinuation: traceContinuationOf(traceSession) };
@@ -8843,7 +10486,7 @@ function createAgent(opts) {
8843
10486
  name: toolName,
8844
10487
  description: description || `Delegate task to agent ${opts.name || "Agent"}`,
8845
10488
  schema,
8846
- func: async ({ input }) => {
10489
+ func: async ({ input }, context) => {
8847
10490
  const ref = delegatedTool._stateRef;
8848
10491
  const parentCtx = ref.ctx || {};
8849
10492
  const parentMessages = Array.isArray(ref.messages) ? ref.messages : [];
@@ -8876,6 +10519,33 @@ function createAgent(opts) {
8876
10519
  input
8877
10520
  );
8878
10521
  const childCtx = { __delegationDepth: currentDepth + 1 };
10522
+ const parentSession = parentCtx.__traceSession;
10523
+ const traced = isTraceSessionOpen(parentSession);
10524
+ const agentSpanId = generateSpanId();
10525
+ const parentIterationSpanId = traced ? parentSession.currentIterationSpanId : void 0;
10526
+ if (traced && !withDefaults(opts.tracing).enabled) {
10527
+ childCtx.__traceSession = createSubagentTraceScope(parentSession, {
10528
+ agentSpanId,
10529
+ name: opts.name || "agent",
10530
+ mode: "asTool",
10531
+ hitl: false
10532
+ });
10533
+ }
10534
+ const startedAt = Date.now();
10535
+ const recordSpan = (status, extra) => {
10536
+ if (!traced || !isTraceSessionOpen(parentSession)) return;
10537
+ recordSubagentSpan(parentSession, {
10538
+ spanId: agentSpanId,
10539
+ parentSpanId: context?.traceSpanId ?? parentIterationSpanId,
10540
+ name: opts.name || "agent",
10541
+ status,
10542
+ durationMs: Date.now() - startedAt,
10543
+ error: extra.error,
10544
+ info: { name: opts.name || "agent", mode: "asTool", depth: currentDepth + 1, parentToolCallId: context?.toolCallId, status: status === "success" ? "ok" : "error" },
10545
+ task: input,
10546
+ result: extra.result
10547
+ });
10548
+ };
8879
10549
  const childConfig = {
8880
10550
  onEvent: parentCtx.__onEvent ? (e) => {
8881
10551
  if (e?.type === "finalAnswer" || e?.type === "metadata") return;
@@ -8891,7 +10561,14 @@ function createAgent(opts) {
8891
10561
  stream: Boolean(parentCtx.__streaming),
8892
10562
  cancellationToken: parentCtx.__cancellationToken ?? parentCtx.__abortSignal
8893
10563
  };
8894
- const res = await instance.invoke({ messages: childMessages, ctx: childCtx }, childConfig);
10564
+ let res;
10565
+ try {
10566
+ res = await instance.invoke({ messages: childMessages, ctx: childCtx }, childConfig);
10567
+ } catch (err) {
10568
+ recordSpan("error", { error: err?.message || String(err) });
10569
+ throw err;
10570
+ }
10571
+ recordSpan("success", { result: res.content });
8895
10572
  return {
8896
10573
  content: res.content,
8897
10574
  output: res.output,
@@ -8968,9 +10645,10 @@ function createAgentNode(opts) {
8968
10645
  durationMs: durationMs2,
8969
10646
  requestBytes: promptBytes,
8970
10647
  model: getModelName(runtime.model || opts.model),
8971
- provider: getProviderName(runtime.model || opts.model),
8972
- error: { message: err?.message || String(err), stack: err?.stack },
8973
- messageList: promptMessages
10648
+ provider: providerHintOf(runtime.model || opts.model),
10649
+ error: traceErrorOf(err),
10650
+ messageList: promptMessages,
10651
+ capture: { input: promptMessages }
8974
10652
  });
8975
10653
  throw err;
8976
10654
  }
@@ -8981,7 +10659,7 @@ function createAgentNode(opts) {
8981
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;
8982
10660
  const normalized = normalizeUsage(rawUsage);
8983
10661
  const modelName = getModelName(runtime.model || opts.model) || "unknown_model";
8984
- const providerName = getProviderName(runtime.model || opts.model);
10662
+ const facts = traceResponseFacts(runtime.model || opts.model, response, rawUsage);
8985
10663
  const durationMs = Date.now() - start;
8986
10664
  const shouldLogResponse = !!traceSession && traceSession.resolvedConfig.logData;
8987
10665
  const responsePayload = shouldLogResponse ? sanitizeTracePayload(response) : void 0;
@@ -8998,8 +10676,9 @@ function createAgentNode(opts) {
8998
10676
  requestBytes: promptBytes,
8999
10677
  responseBytes,
9000
10678
  model: modelName,
9001
- provider: providerName,
9002
- messageList: messagesWithResponse
10679
+ ...facts,
10680
+ messageList: messagesWithResponse,
10681
+ capture: { input: promptMessages, output: response }
9003
10682
  });
9004
10683
  if (normalized) {
9005
10684
  recordUsage(state, modelName, normalized);
@@ -9650,7 +11329,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9650
11329
  ];
9651
11330
  const inputTokensEstimate = countApproxTokens(summaryPrompt.map((m) => m.content).join("\n"));
9652
11331
  const modelName = getModelName(model);
9653
- const providerName = getProviderName(model);
11332
+ const providerName = providerHintOf(model);
9654
11333
  const tracingEnabled = Boolean(opts.tracing?.enabled);
9655
11334
  let ctxWithDeferredTrace;
9656
11335
  const traceSummarization = (event) => {
@@ -9681,6 +11360,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9681
11360
  let reasoningTokensActual;
9682
11361
  let fallback = false;
9683
11362
  let summarizerError;
11363
+ let responseFacts;
9684
11364
  const directivesSection = () => ({
9685
11365
  kind: "metadata",
9686
11366
  label: "User directives",
@@ -9722,6 +11402,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9722
11402
  summaryText = renderStructuredSummary(structuredSummary);
9723
11403
  const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
9724
11404
  const normalized = normalizeUsage(rawUsage);
11405
+ responseFacts = traceResponseFacts(model, response, rawUsage);
9725
11406
  if (normalized) {
9726
11407
  inputTokensActual = normalized.prompt_tokens;
9727
11408
  outputTokensActual = normalized.completion_tokens;
@@ -9758,7 +11439,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9758
11439
  ...droppedDirectives.length > 0 ? { droppedDirectives } : {}
9759
11440
  };
9760
11441
  onEvent?.(errorEvent);
9761
- summarizerError = { message: err?.message || String(err), stack: err?.stack };
11442
+ summarizerError = traceErrorOf(err);
9762
11443
  }
9763
11444
  const toolCallIdToAssistantIdx = /* @__PURE__ */ new Map();
9764
11445
  messages.forEach((m, idx) => {
@@ -9914,10 +11595,16 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
9914
11595
  outputTokens: outputTokensActual ?? outputTokensEstimate,
9915
11596
  cachedInputTokens,
9916
11597
  totalTokens: totalTokensActual,
9917
- ...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 } : {}
9918
11602
  },
11603
+ ...responseFacts?.responseId ? { responseId: responseFacts.responseId } : {},
11604
+ ...responseFacts?.responseModel ? { responseModel: responseFacts.responseModel } : {},
11605
+ ...responseFacts?.rawFinishReason ? { rawFinishReason: responseFacts.rawFinishReason } : {},
9919
11606
  ...modelName ? { model: modelName } : {},
9920
- ...providerName ? { provider: providerName } : {},
11607
+ ...responseFacts?.provider ?? providerName ? { provider: responseFacts?.provider ?? providerName } : {},
9921
11608
  ...summarizerError ? { error: summarizerError } : {},
9922
11609
  sections: [
9923
11610
  ...promptAndOutputSections(),
@@ -11054,11 +12741,52 @@ function mergeChildUsage(ref, childState, baseline, tag) {
11054
12741
  async function runChild(spec, input, deps, ref, opts) {
11055
12742
  const parentCtx = ref.ctx || {};
11056
12743
  const parentOnEvent = parentCtx.__onEvent;
11057
- const spawnId = `sa_${nanoid(6)}`;
12744
+ const spawnId = opts.record?.spawnId ?? `sa_${nanoid(6)}`;
11058
12745
  const start = Date.now();
11059
12746
  const usageTag = { name: spec.name, id: spawnId, mode: spec.mode };
11060
12747
  const parentHost = parentCtx.__plugins;
11061
12748
  const childDepth = (Number(parentCtx.__delegationDepth) || 0) + 1;
12749
+ const parentSession = parentCtx.__traceSession;
12750
+ const traced = isTraceSessionOpen(parentSession);
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);
12760
+ const parentIterationSpanId = traced ? parentSession.currentIterationSpanId : void 0;
12761
+ const traceScope = traced ? createSubagentTraceScope(parentSession, { agentSpanId, name: spec.name, spawnId, mode: spec.mode, hitl: opts.allowHITL, iterations: opts.record?.iterations }) : void 0;
12762
+ const recordSegment = (status, info) => {
12763
+ if (!traced || !isTraceSessionOpen(parentSession)) return;
12764
+ recordSubagentSpan(parentSession, {
12765
+ spanId: agentSpanId,
12766
+ // The tool_call span only exists once the tool returns; a paused child
12767
+ // has not returned, so its span hangs off the iteration.
12768
+ parentSpanId: status === "pending" ? parentIterationSpanId : opts.parentSpanId ?? parentIterationSpanId,
12769
+ name: spec.name,
12770
+ status,
12771
+ durationMs: elapsedMs(),
12772
+ error: info.error,
12773
+ info: {
12774
+ id: spawnId,
12775
+ name: spec.name,
12776
+ mode: spec.mode,
12777
+ parallel: opts.parallel,
12778
+ depth: childDepth,
12779
+ parentToolCallId: opts.parentToolCallId,
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 } : {},
12783
+ ...info.note ? { note: info.note } : {},
12784
+ ...spec.metadata ? { metadata: spec.metadata } : {}
12785
+ },
12786
+ task: info.input,
12787
+ result: info.content
12788
+ });
12789
+ };
11062
12790
  const emitStart = (task) => {
11063
12791
  parentOnEvent?.({ type: "subagent", phase: "start", name: spec.name, id: spawnId, mode: spec.mode, parallel: opts.parallel, parentToolCallId: opts.parentToolCallId, input: task });
11064
12792
  };
@@ -11066,6 +12794,15 @@ async function runChild(spec, input, deps, ref, opts) {
11066
12794
  result2.durationMs ?? (result2.durationMs = Date.now() - start);
11067
12795
  deps.registryRef.results.push(result2);
11068
12796
  const message = result2.error || result2.note || result2.status;
12797
+ const traceStatus = result2.status === "ok" || result2.status === "incomplete" ? "success" : result2.status === "blocked" ? "skipped" : "error";
12798
+ recordSegment(traceStatus, {
12799
+ subagentStatus: result2.status,
12800
+ input,
12801
+ // `message` falls back to the status itself ("ok"): only a failed or refused run has an error to show.
12802
+ error: traceStatus === "success" ? void 0 : message,
12803
+ note: result2.note,
12804
+ content: result2.content
12805
+ });
11069
12806
  parentOnEvent?.({
11070
12807
  type: "subagent",
11071
12808
  phase: FAILED_STATUSES.has(result2.status) ? "error" : "result",
@@ -11164,6 +12901,7 @@ async function runChild(spec, input, deps, ref, opts) {
11164
12901
  ctx: { __delegationDepth: currentDepth + 1 }
11165
12902
  };
11166
12903
  }
12904
+ if (traceScope) childInput = { ...childInput, ctx: { ...childInput.ctx || {}, __traceSession: traceScope } };
11167
12905
  const usageBaseline = childInput.usage?.perRequest?.length ?? 0;
11168
12906
  let res;
11169
12907
  try {
@@ -11204,8 +12942,14 @@ async function runChild(spec, input, deps, ref, opts) {
11204
12942
  input,
11205
12943
  childState: cleanChildState(childState),
11206
12944
  pendingKind: "approval",
11207
- pendingId: childEntry.id
12945
+ pendingId: childEntry.id,
12946
+ spawnId,
12947
+ iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0,
12948
+ agentSpanId,
12949
+ startedAt: runStartedAt,
12950
+ segments: segment
11208
12951
  };
12952
+ recordSegment("pending", { subagentStatus: "paused", input });
11209
12953
  parentOnEvent?.({ type: "subagent", phase: "paused", name: spec.name, id: spawnId, mode: spec.mode, parentToolCallId: opts.parentToolCallId });
11210
12954
  return { kind: "approval", toolCallId: surfaced.toolCallId, approvalId: surfaced.id };
11211
12955
  }
@@ -11227,8 +12971,14 @@ async function runChild(spec, input, deps, ref, opts) {
11227
12971
  input,
11228
12972
  childState: cleanChildState(childState),
11229
12973
  pendingKind: "user_question",
11230
- pendingId: childEntry.id
12974
+ pendingId: childEntry.id,
12975
+ spawnId,
12976
+ iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0,
12977
+ agentSpanId,
12978
+ startedAt: runStartedAt,
12979
+ segments: segment
11231
12980
  };
12981
+ recordSegment("pending", { subagentStatus: "paused", input });
11232
12982
  parentOnEvent?.({ type: "subagent", phase: "paused", name: spec.name, id: spawnId, mode: spec.mode, parentToolCallId: opts.parentToolCallId });
11233
12983
  return { kind: "user_question", toolCallId: surfaced.toolCallId, id: surfaced.id };
11234
12984
  }
@@ -11332,7 +13082,7 @@ function createDelegateTool(deps) {
11332
13082
  if (!budget.ok) return refusal(budget.reason);
11333
13083
  d.registryRef.spawnedCount += 1;
11334
13084
  }
11335
- return toToolReturn(await runChild(spec, record?.input ?? input, d, ref, { allowHITL: true, parentToolCallId, isResume: !!record, record, reserved: !record }));
13085
+ return toToolReturn(await runChild(spec, record?.input ?? input, d, ref, { allowHITL: true, parentToolCallId, isResume: !!record, record, reserved: !record, parentSpanId: context?.traceSpanId }));
11336
13086
  }
11337
13087
  });
11338
13088
  tool._deps = deps;
@@ -11377,7 +13127,7 @@ function createSpawnTool(deps) {
11377
13127
  if (!budget.ok) return refusal(budget.reason);
11378
13128
  d.registryRef.spawnedCount += 1;
11379
13129
  }
11380
- return toToolReturn(await runChild(spec, record?.input ?? args.input, d, ref, { allowHITL: true, parentToolCallId, isResume: !!record, record, reserved: !record }));
13130
+ return toToolReturn(await runChild(spec, record?.input ?? args.input, d, ref, { allowHITL: true, parentToolCallId, isResume: !!record, record, reserved: !record, parentSpanId: context?.traceSpanId }));
11381
13131
  }
11382
13132
  });
11383
13133
  tool._deps = deps;
@@ -11460,7 +13210,8 @@ function createParallelTool(deps) {
11460
13210
  allowHITL: false,
11461
13211
  parentToolCallId: `${parentToolCallId}#${i}`,
11462
13212
  parallel: true,
11463
- reserved: true
13213
+ reserved: true,
13214
+ parentSpanId: context?.traceSpanId
11464
13215
  });
11465
13216
  results[i] = outcome.kind === "result" ? outcome.result : { name: entry.spec.name, mode: entry.spec.mode, status: "error", input: entry.input, error: "Unexpected pause in parallel child." };
11466
13217
  }
@@ -11912,6 +13663,30 @@ ${pluginAppend}`;
11912
13663
  };
11913
13664
  }
11914
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
+ };
11915
13690
  try {
11916
13691
  const toolSet = buildInvokeToolSet();
11917
13692
  const stateRef = toolSet.stateRef;
@@ -11990,11 +13765,15 @@ ${pluginAppend}`;
11990
13765
  const result = await trySummarize(state, rawMessages, stateRef);
11991
13766
  state = result.state;
11992
13767
  rawMessages = result.rawMessages;
13768
+ noteTraceHandoff(state);
11993
13769
  if (result.compressed) continue;
11994
13770
  }
11995
13771
  const modelMessages = buildModelMessages(state, resolved);
13772
+ traceHandoff.continuation = void 0;
13773
+ traceHandoff.events = void 0;
11996
13774
  const res = await base.invoke({ ...state, messages: modelMessages }, turnConfig);
11997
13775
  lastResult = res;
13776
+ noteTraceHandoff(res.state ?? state);
11998
13777
  const currentSummaries = state.summaries;
11999
13778
  const currentSummaryRecords = state.summaryRecords;
12000
13779
  const currentPlan = state.plan;
@@ -12021,6 +13800,7 @@ ${pluginAppend}`;
12021
13800
  const result = await trySummarize(state, rawMessages, stateRef);
12022
13801
  state = result.state;
12023
13802
  rawMessages = result.rawMessages;
13803
+ noteTraceHandoff(state);
12024
13804
  continue;
12025
13805
  }
12026
13806
  if (state.ctx?.__finalizedDueToStructuredOutput) break;
@@ -12032,6 +13812,7 @@ ${pluginAppend}`;
12032
13812
  const result = await trySummarize(state, rawMessages, stateRef);
12033
13813
  state = result.state;
12034
13814
  rawMessages = result.rawMessages;
13815
+ noteTraceHandoff(state);
12035
13816
  if (result.compressed) continue;
12036
13817
  }
12037
13818
  }
@@ -12042,6 +13823,7 @@ ${pluginAppend}`;
12042
13823
  lastResult = res;
12043
13824
  }
12044
13825
  if (state.ctx?.[DEFERRED_TRACE_EVENTS_KEY]) {
13826
+ traceHandoff.events = state.ctx[DEFERRED_TRACE_EVENTS_KEY];
12045
13827
  const ctx = { ...state.ctx || {} };
12046
13828
  delete ctx[DEFERRED_TRACE_EVENTS_KEY];
12047
13829
  state = { ...state, ctx };
@@ -12061,8 +13843,12 @@ ${pluginAppend}`;
12061
13843
  const strippedCtx = { ...endCtx };
12062
13844
  delete strippedCtx.__traceContinuation;
12063
13845
  lastResult = { ...lastResult, state: { ...lastResult.state, ctx: strippedCtx } };
13846
+ traceHandoff.continuation = endCtx.__traceContinuation;
13847
+ await closeDanglingTrace("success");
12064
13848
  }
12065
13849
  }
13850
+ traceHandoff.continuation = void 0;
13851
+ traceHandoff.events = void 0;
12066
13852
  if (skillsEnabled && lastResult.state) {
12067
13853
  const persisted = skillStateFromRegistry(toolSet.skillRegistryRef);
12068
13854
  if (persisted) {
@@ -12108,6 +13894,11 @@ ${pluginAppend}`;
12108
13894
  await endSession(endStatus, { result: lastResult });
12109
13895
  return lastResult;
12110
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
+ });
12111
13902
  await endSession("error", { error: err instanceof Error ? err : new Error(String(err)) });
12112
13903
  throw err;
12113
13904
  }
@@ -13024,7 +14815,7 @@ function isHookImplemented(hook) {
13024
14815
  // src/plugins/builtin/guardrail.ts
13025
14816
  init_content();
13026
14817
  var ALLOW = { action: "allow" };
13027
- 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]);
13028
14819
  var RetryableGuardrailError = class extends Error {
13029
14820
  constructor(message) {
13030
14821
  super(message);
@@ -13122,7 +14913,7 @@ function httpGuardrail(options) {
13122
14913
  } catch {
13123
14914
  }
13124
14915
  const message = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}${text ? ` - ${text.slice(0, 200)}` : ""}`;
13125
- if (RETRYABLE_STATUS.has(response.status)) throw new RetryableGuardrailError(message);
14916
+ if (RETRYABLE_STATUS2.has(response.status)) throw new RetryableGuardrailError(message);
13126
14917
  throw new Error(message);
13127
14918
  }
13128
14919
  return response.json();
@@ -13229,9 +15020,9 @@ function createGuardrailPlugin(options) {
13229
15020
  });
13230
15021
  const resolved = verdict ?? ALLOW;
13231
15022
  if (resolved.raw?.disabled === true) {
13232
- const warned = (_b = ctx.store).__disabledWarned ?? (_b.__disabledWarned = /* @__PURE__ */ new Set());
13233
- if (!warned.has(request.phase)) {
13234
- 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);
13235
15026
  ctx.logger.warn(
13236
15027
  `guardrail reports it is not active for the "${request.phase}" surface; nothing is being enforced there`
13237
15028
  );
@@ -13728,7 +15519,7 @@ function safeJson(value) {
13728
15519
  function matches(pattern, toolName) {
13729
15520
  return typeof pattern === "string" ? pattern === toolName : pattern.test(toolName);
13730
15521
  }
13731
- function asObject(args) {
15522
+ function asObject2(args) {
13732
15523
  return args && typeof args === "object" ? args : {};
13733
15524
  }
13734
15525
  function toolPolicy(config = {}) {
@@ -13749,7 +15540,7 @@ function toolPolicy(config = {}) {
13749
15540
  hooks: {
13750
15541
  preToolUse: ({ toolName, args }, ctx) => {
13751
15542
  var _a;
13752
- const argObject = asObject(args);
15543
+ const argObject = asObject2(args);
13753
15544
  const isControlPlane = CONTROL_PLANE_TOOL_NAMES.includes(toolName);
13754
15545
  const allowListApplies = !isControlPlane || config.governControlPlaneTools === true;
13755
15546
  if (config.allowOnly && allowListApplies && !config.allowOnly.some((pattern) => matches(pattern, toolName))) {
@@ -13811,7 +15602,7 @@ function pathSandbox(config) {
13811
15602
  hooks: {
13812
15603
  preToolUse: ({ toolName, args }) => {
13813
15604
  if (config.tools && !config.tools.some((pattern) => matches(pattern, toolName))) return void 0;
13814
- const argObject = asObject(args);
15605
+ const argObject = asObject2(args);
13815
15606
  for (const key of argNames) {
13816
15607
  const value = argObject[key];
13817
15608
  if (typeof value !== "string" || value.length === 0) continue;
@@ -14579,7 +16370,7 @@ function mcp(config) {
14579
16370
  }
14580
16371
 
14581
16372
  // src/plugins/builtin/rateLimit.ts
14582
- function sleep(ms, signal) {
16373
+ function sleep2(ms, signal) {
14583
16374
  return new Promise((resolve) => {
14584
16375
  let timer;
14585
16376
  const done = () => {
@@ -14636,7 +16427,7 @@ function rateLimit(config = {}) {
14636
16427
  while (!attempt.ok) {
14637
16428
  const remaining = deadline - Date.now();
14638
16429
  if (!Number.isFinite(attempt.waitMs) || attempt.waitMs > remaining) break;
14639
- await sleep(Math.max(1, attempt.waitMs), ctx.signal);
16430
+ await sleep2(Math.max(1, attempt.waitMs), ctx.signal);
14640
16431
  if (ctx.signal?.aborted) break;
14641
16432
  attempt = consume(applicable);
14642
16433
  }
@@ -15732,18 +17523,21 @@ function langfuseTracing(config = {}) {
15732
17523
  }
15733
17524
 
15734
17525
  // src/plugins/builtin/otel.ts
15735
- function toSessionStatus(status) {
15736
- if (status === "success") return "success";
15737
- if (status === "error") return "error";
15738
- return status === "paused" ? "in_progress" : "partial";
15739
- }
15740
- function otelTracing(config) {
15741
- const endpoint = config.endpoint?.trim();
15742
- if (!endpoint) {
17526
+ function otelTracing(config = {}) {
17527
+ if (config.endpoint !== void 0 && !config.endpoint.trim()) {
15743
17528
  throw new Error("[agent-sdk] otelTracing requires a non-empty `endpoint`.");
15744
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
+ }
15745
17539
  return {
15746
- name: config.name ?? "otel-tracing",
17540
+ name,
15747
17541
  // Registers only the `sessionEnd` observer, and observers run concurrently,
15748
17542
  // so this number orders nothing at runtime. It is set above checkpointing
15749
17543
  // (900) to record intent: this plugin is the last thing interested in the
@@ -15751,67 +17545,41 @@ function otelTracing(config) {
15751
17545
  priority: 950,
15752
17546
  // Observability. A dropped export is a reporting gap, never a safety hole.
15753
17547
  failureMode: "open",
17548
+ traceExporters: [exporter],
15754
17549
  hooks: {
15755
- sessionEnd: async ({ status, durationMs, error }, ctx) => {
17550
+ sessionEnd: async (_event, ctx) => {
15756
17551
  const state = ctx.state;
15757
17552
  const session = state.ctx?.__traceSession;
17553
+ if (isSubagentTraceScope(session)) return;
15758
17554
  if (!session) {
15759
17555
  const message = "otelTracing exported nothing: the agent has no trace session. Enable the SDK's tracing runtime with `tracing: { enabled: true }` \u2014 the plugin exports the session the runtime records, it does not record one itself.";
15760
17556
  ctx.logger.warn(message);
15761
17557
  ctx.emit({ type: "metadata", otelTracing: { exported: false, reason: message } });
15762
17558
  return;
15763
17559
  }
15764
- const endedAtMs = Date.now();
15765
- const startedAtIso = new Date(session.startedAt).toISOString();
15766
- const errors = error ? [...session.errors, { eventId: "session", message: error.message, stack: error.stack, type: "session" }] : session.errors;
15767
- const payload = {
15768
- sessionId: session.sessionId,
15769
- traceId: session.traceId,
15770
- rootSpanId: session.rootSpanId,
15771
- threadId: session.threadId,
15772
- startedAt: startedAtIso,
15773
- endedAt: new Date(endedAtMs).toISOString(),
15774
- durationMs: durationMs ?? endedAtMs - session.startedAt,
15775
- // `service.name` is read off `agent.name` inside the conversion, so
15776
- // the override is applied here rather than by editing spans after.
15777
- agent: {
15778
- ...session.agentInfo ?? {},
15779
- name: config.serviceName ?? session.agentInfo?.name ?? session.configAgentName ?? ctx.agentName
15780
- },
15781
- metadata: session.configMetadata,
15782
- // Carried only to satisfy the type: `traceSessionToOtlp` reads the
15783
- // events, summary and identifiers, never the sink snapshot.
15784
- config: { enabled: true, logData: session.resolvedConfig.logData, sink: { type: "otlp", endpoint } },
15785
- summary: session.summary,
15786
- events: session.events,
15787
- status: toSessionStatus(status),
15788
- errors
15789
- };
15790
- try {
15791
- const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
15792
- if (!fetchFn) {
15793
- ctx.logger.warn("otelTracing needs fetch to be available in this runtime; export skipped.");
15794
- return;
15795
- }
15796
- const response = await fetchFn(endpoint, {
15797
- method: "POST",
15798
- headers: { "content-type": "application/json", ...config.headers ?? {} },
15799
- body: JSON.stringify(traceSessionToOtlp(payload)),
15800
- // The run is over, but a host that cancelled it should not be made
15801
- // to wait on a collector that is refusing to answer.
15802
- signal: ctx.signal
15803
- });
15804
- if (!response.ok) {
15805
- ctx.logger.warn(`otelTracing export returned HTTP ${response.status}.`);
15806
- return;
15807
- }
15808
- ctx.emit({
15809
- type: "metadata",
15810
- otelTracing: { exported: true, endpoint, spans: session.events.length + 1 }
15811
- });
15812
- } catch (err) {
15813
- 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;
15814
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
+ });
15815
17583
  }
15816
17584
  }
15817
17585
  };
@@ -18847,9 +20615,9 @@ function mapAnthropicStopReason(reason) {
18847
20615
  return "stop";
18848
20616
  }
18849
20617
  }
18850
- function safeJsonParse(str) {
20618
+ function safeJsonParse(str2) {
18851
20619
  try {
18852
- return JSON.parse(str);
20620
+ return JSON.parse(str2);
18853
20621
  } catch {
18854
20622
  return {};
18855
20623
  }
@@ -19719,9 +21487,9 @@ function mediaTypeToFormat(mediaType) {
19719
21487
  };
19720
21488
  return map[mediaType] ?? "png";
19721
21489
  }
19722
- function safeJsonParse2(str) {
21490
+ function safeJsonParse2(str2) {
19723
21491
  try {
19724
- return JSON.parse(str);
21492
+ return JSON.parse(str2);
19725
21493
  } catch {
19726
21494
  return {};
19727
21495
  }
@@ -20118,10 +21886,13 @@ var VertexProvider = class extends BaseProvider {
20118
21886
  textParts.push(part.text);
20119
21887
  }
20120
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++;
20121
21891
  toolCalls.push({
20122
- id: `call_${toolCallIdx++}`,
21892
+ id: suppliedId ?? `call_${position}`,
20123
21893
  name: part.functionCall.name,
20124
21894
  arguments: JSON.stringify(part.functionCall.args ?? {}),
21895
+ ...suppliedId ? {} : { idSynthesized: true },
20125
21896
  ...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
20126
21897
  });
20127
21898
  }
@@ -20161,12 +21932,15 @@ var VertexProvider = class extends BaseProvider {
20161
21932
  }
20162
21933
  } else if (part.functionCall) {
20163
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++;
20164
21937
  delta.toolCalls.push({
20165
21938
  // Unique across the whole stream: the adapter merges chunks by id.
20166
- id: `call_${counter.next}`,
20167
- index: counter.next++,
21939
+ id: suppliedId ?? `call_${position}`,
21940
+ index: position,
20168
21941
  name: part.functionCall.name,
20169
21942
  arguments: JSON.stringify(part.functionCall.args ?? {}),
21943
+ ...suppliedId ? {} : { idSynthesized: true },
20170
21944
  ...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
20171
21945
  });
20172
21946
  }
@@ -20219,12 +21993,12 @@ function mapGeminiFinishReason(reason) {
20219
21993
  return "stop";
20220
21994
  }
20221
21995
  }
20222
- function base64url(str) {
20223
- return Buffer.from(str).toString("base64url");
21996
+ function base64url(str2) {
21997
+ return Buffer.from(str2).toString("base64url");
20224
21998
  }
20225
- function safeJsonParse3(str) {
21999
+ function safeJsonParse3(str2) {
20226
22000
  try {
20227
- return JSON.parse(str);
22001
+ return JSON.parse(str2);
20228
22002
  } catch {
20229
22003
  return {};
20230
22004
  }
@@ -20252,6 +22026,6 @@ function createProvider(config) {
20252
22026
  }
20253
22027
  }
20254
22028
 
20255
- 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 };
20256
22030
  //# sourceMappingURL=index.mjs.map
20257
22031
  //# sourceMappingURL=index.mjs.map