@cognipeer/agent-sdk 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +2012 -373
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +581 -40
- package/dist/index.d.ts +581 -40
- package/dist/index.mjs +2006 -374
- package/dist/index.mjs.map +1 -1
- package/dist/{model-rules-Bg9nSqyN.d.cts → model-rules--welxWDw.d.cts} +2 -0
- package/dist/{model-rules-Bg9nSqyN.d.ts → model-rules--welxWDw.d.ts} +2 -0
- package/dist/model-rules.d.cts +1 -1
- package/dist/model-rules.d.ts +1 -1
- package/package.json +2 -1
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.19.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" || event.status === "running"))
|
|
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(
|
|
1253
|
-
return { type: "otlp",
|
|
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
|
|
1327
|
-
if (
|
|
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
|
|
1334
|
-
if (
|
|
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
|
|
1342
|
-
if (
|
|
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
|
|
1374
|
-
if (
|
|
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
|
|
1393
|
-
if (
|
|
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
|
|
1456
|
-
if (
|
|
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,
|
|
2909
|
+
constructor(status, message, retryAfterMs2) {
|
|
1501
2910
|
super(message);
|
|
1502
2911
|
this.name = "RetryableHttpError";
|
|
1503
2912
|
this.status = status;
|
|
1504
|
-
this.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
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
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
|
-
|
|
1766
|
-
const
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
"
|
|
1772
|
-
...
|
|
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
|
-
|
|
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
|
-
|
|
3048
|
+
for (; ; ) {
|
|
3049
|
+
const id = crypto.randomBytes(8).toString("hex");
|
|
3050
|
+
if (/[1-9a-f]/.test(id)) return id;
|
|
3051
|
+
}
|
|
1820
3052
|
}
|
|
1821
3053
|
function defaultEventLabel(type) {
|
|
1822
3054
|
switch (type) {
|
|
@@ -2093,9 +3325,64 @@ function readTraceContinuation(value) {
|
|
|
2093
3325
|
nextSequence,
|
|
2094
3326
|
part,
|
|
2095
3327
|
summary,
|
|
2096
|
-
errors: Array.isArray(raw.errors) ? raw.errors : []
|
|
3328
|
+
errors: Array.isArray(raw.errors) ? raw.errors : [],
|
|
3329
|
+
...(() => {
|
|
3330
|
+
const parent = readPersistedParent(raw.parent);
|
|
3331
|
+
return parent ? { parent } : {};
|
|
3332
|
+
})(),
|
|
3333
|
+
...(() => {
|
|
3334
|
+
const pendingSpans = readPendingSpans(raw.pendingSpans);
|
|
3335
|
+
return pendingSpans.length > 0 ? { pendingSpans } : {};
|
|
3336
|
+
})()
|
|
3337
|
+
};
|
|
3338
|
+
}
|
|
3339
|
+
var MAX_CARRIED_SPANS = 64;
|
|
3340
|
+
var isSubagentSpanRecord = (event) => event.type === "span" && event.actor?.role === "subagent";
|
|
3341
|
+
function carriedSpanOf(record) {
|
|
3342
|
+
const identity2 = (record.data?.sections ?? []).filter(
|
|
3343
|
+
(section) => section.kind === "metadata" && section.identity === true
|
|
3344
|
+
);
|
|
3345
|
+
return {
|
|
3346
|
+
sessionId: record.sessionId,
|
|
3347
|
+
traceId: record.traceId,
|
|
3348
|
+
spanId: record.spanId,
|
|
3349
|
+
parentSpanId: record.parentSpanId,
|
|
3350
|
+
id: record.id,
|
|
3351
|
+
type: record.type,
|
|
3352
|
+
label: record.label,
|
|
3353
|
+
sequence: record.sequence,
|
|
3354
|
+
timestamp: record.timestamp,
|
|
3355
|
+
actor: record.actor,
|
|
3356
|
+
status: record.status,
|
|
3357
|
+
durationMs: record.durationMs,
|
|
3358
|
+
...identity2.length > 0 ? { data: { sections: identity2 } } : {}
|
|
2097
3359
|
};
|
|
2098
3360
|
}
|
|
3361
|
+
function readPendingSpans(value) {
|
|
3362
|
+
if (!Array.isArray(value)) return [];
|
|
3363
|
+
const out = [];
|
|
3364
|
+
for (const item of value.slice(0, MAX_CARRIED_SPANS)) {
|
|
3365
|
+
if (!item || typeof item !== "object") continue;
|
|
3366
|
+
const raw = item;
|
|
3367
|
+
if (typeof raw.spanId !== "string" || raw.spanId.length === 0) continue;
|
|
3368
|
+
if (raw.status !== "pending" || !isSubagentSpanRecord(raw)) continue;
|
|
3369
|
+
if (typeof raw.sequence !== "number" || !Number.isInteger(raw.sequence) || raw.sequence < 1) continue;
|
|
3370
|
+
if (typeof raw.timestamp !== "string" || Number.isNaN(Date.parse(raw.timestamp))) continue;
|
|
3371
|
+
if (typeof raw.label !== "string" || typeof raw.id !== "string" || typeof raw.sessionId !== "string") continue;
|
|
3372
|
+
if (raw.parentSpanId !== void 0 && typeof raw.parentSpanId !== "string") continue;
|
|
3373
|
+
if (raw.durationMs !== void 0 && (typeof raw.durationMs !== "number" || !Number.isFinite(raw.durationMs))) continue;
|
|
3374
|
+
out.push(carriedSpanOf(raw));
|
|
3375
|
+
}
|
|
3376
|
+
return out;
|
|
3377
|
+
}
|
|
3378
|
+
function pendingSpansOf(session) {
|
|
3379
|
+
const candidates = [
|
|
3380
|
+
...session.carriedSpans ?? [],
|
|
3381
|
+
...session.events.filter(isSubagentSpanRecord)
|
|
3382
|
+
];
|
|
3383
|
+
if (candidates.length === 0) return [];
|
|
3384
|
+
return foldSupersededSpans(candidates).filter((event) => event.status === "pending").slice(-MAX_CARRIED_SPANS).map(carriedSpanOf);
|
|
3385
|
+
}
|
|
2099
3386
|
function traceContinuationOf(session) {
|
|
2100
3387
|
return {
|
|
2101
3388
|
v: 1,
|
|
@@ -2109,15 +3396,32 @@ function traceContinuationOf(session) {
|
|
|
2109
3396
|
summary: JSON.parse(JSON.stringify(session.summary)),
|
|
2110
3397
|
// Sink failures belong to the part that hit them; carrying them on would
|
|
2111
3398
|
// mark every later part `partial`.
|
|
2112
|
-
errors: session.errors.filter((error) => error.type !== "sink")
|
|
3399
|
+
errors: session.errors.filter((error) => error.type !== "sink"),
|
|
3400
|
+
// Where the root hangs, so the leg that ends the run exports it under the same remote parent.
|
|
3401
|
+
...session.parent ? { parent: persistedParentOf(session.parent) } : {},
|
|
3402
|
+
...(() => {
|
|
3403
|
+
const pendingSpans = pendingSpansOf(session);
|
|
3404
|
+
return pendingSpans.length > 0 ? { pendingSpans } : {};
|
|
3405
|
+
})()
|
|
2113
3406
|
};
|
|
2114
3407
|
}
|
|
2115
|
-
function createTraceSession(opts, continuation) {
|
|
3408
|
+
function createTraceSession(opts, continuation, extras) {
|
|
2116
3409
|
const cfg = withDefaults(opts.tracing);
|
|
2117
3410
|
if (!cfg.enabled) return void 0;
|
|
3411
|
+
let parent;
|
|
3412
|
+
if (continuation) {
|
|
3413
|
+
if (continuation.parent && continuation.traceId) parent = restoreParent(continuation.parent, continuation.traceId);
|
|
3414
|
+
} else {
|
|
3415
|
+
parent = resolveTraceParent(extras?.traceParent ?? opts.tracing?.parent);
|
|
3416
|
+
}
|
|
3417
|
+
const exporters = [...extras?.exporters ?? []];
|
|
3418
|
+
const contentExporters = [
|
|
3419
|
+
...cfg.sink.type === "otlp" ? [cfg.sink.exporter] : [],
|
|
3420
|
+
...exporters
|
|
3421
|
+
].filter((exporter) => exporter.wantsContent);
|
|
2118
3422
|
const providedSessionId = opts.tracing?.sessionId?.trim();
|
|
2119
3423
|
const sessionId = continuation?.sessionId || providedSessionId || generateSessionId();
|
|
2120
|
-
const traceId = continuation?.traceId || generateTraceId();
|
|
3424
|
+
const traceId = continuation?.traceId || parent?.traceId || generateTraceId();
|
|
2121
3425
|
const rootSpanId = continuation?.rootSpanId || generateSpanId();
|
|
2122
3426
|
const runtime = {
|
|
2123
3427
|
sessionId,
|
|
@@ -2136,7 +3440,20 @@ function createTraceSession(opts, continuation) {
|
|
|
2136
3440
|
// again would reset a streaming receiver's copy.
|
|
2137
3441
|
sessionStarted: Boolean(continuation),
|
|
2138
3442
|
sequenceOffset: continuation ? continuation.nextSequence - 1 : 0,
|
|
2139
|
-
part: continuation ? continuation.part + 1 : 1
|
|
3443
|
+
part: continuation ? continuation.part + 1 : 1,
|
|
3444
|
+
...continuation?.pendingSpans?.length ? { carriedSpans: continuation.pendingSpans } : {},
|
|
3445
|
+
...exporters.length ? { exporters } : {},
|
|
3446
|
+
exportReports: [],
|
|
3447
|
+
...parent ? { parent } : {},
|
|
3448
|
+
...contentExporters.length > 0 ? {
|
|
3449
|
+
captureContent: true,
|
|
3450
|
+
captureLimits: {
|
|
3451
|
+
// Headroom over the export cap: a redact hook runs before the cap and must see a
|
|
3452
|
+
// secret whole, even one that straddles the point where the export cuts.
|
|
3453
|
+
maxStringChars: 4 * Math.max(...contentExporters.map((exporter) => exporter.contentOptions?.maxStringChars ?? 4096)),
|
|
3454
|
+
maxMessages: Math.max(...contentExporters.map((exporter) => exporter.contentOptions?.maxMessages ?? 32))
|
|
3455
|
+
}
|
|
3456
|
+
} : {}
|
|
2140
3457
|
};
|
|
2141
3458
|
if (cfg.sink.type === "file") {
|
|
2142
3459
|
const baseDir = cfg.sink.baseDir;
|
|
@@ -2252,8 +3569,15 @@ function recordTraceEvent(session, event) {
|
|
|
2252
3569
|
}
|
|
2253
3570
|
}
|
|
2254
3571
|
}
|
|
3572
|
+
if (!session.resolvedConfig.logData && event.sections?.length) {
|
|
3573
|
+
const identity2 = event.sections.filter((section) => section.kind === "metadata" && section.identity === true);
|
|
3574
|
+
if (identity2.length > 0) sections = ensureUniqueSections(id, identity2);
|
|
3575
|
+
}
|
|
2255
3576
|
if (event.alwaysSections?.length) {
|
|
2256
|
-
|
|
3577
|
+
const identity2 = event.alwaysSections.map(
|
|
3578
|
+
(section) => section.kind === "metadata" ? { ...section, identity: true } : section
|
|
3579
|
+
);
|
|
3580
|
+
sections = ensureUniqueSections(id, [...identity2, ...sections ?? []]);
|
|
2257
3581
|
}
|
|
2258
3582
|
const resolvedModel = event.model ?? inferModelFromMessages(event.messageList);
|
|
2259
3583
|
const resolvedProvider = event.provider ?? inferProviderFromMessages(event.messageList);
|
|
@@ -2289,6 +3613,16 @@ function recordTraceEvent(session, event) {
|
|
|
2289
3613
|
// different facts, and a zero would erase the difference.
|
|
2290
3614
|
...reasoningTokens !== void 0 && !Number.isNaN(reasoningTokens) ? { reasoningTokens } : {},
|
|
2291
3615
|
...event.finishReason ? { finishReason: event.finishReason } : {},
|
|
3616
|
+
// Provider facts: absent when the provider did not say, never zero or empty.
|
|
3617
|
+
...event.responseId ? { responseId: event.responseId } : {},
|
|
3618
|
+
...event.responseModel ? { responseModel: event.responseModel } : {},
|
|
3619
|
+
...event.rawFinishReason ? { rawFinishReason: event.rawFinishReason } : {},
|
|
3620
|
+
...typeof event.cacheWriteTokens === "number" && event.cacheWriteTokens > 0 ? { cacheWriteTokens: event.cacheWriteTokens } : {},
|
|
3621
|
+
...event.usageBasis && (event.usageBasis.inputExcludesCache || event.usageBasis.outputExcludesReasoning) ? { usageBasis: { ...event.usageBasis } } : {},
|
|
3622
|
+
...event.streaming ? { streaming: true } : {},
|
|
3623
|
+
...event.outputType ? { outputType: event.outputType } : {},
|
|
3624
|
+
...event.toolCallId ? { toolCallId: event.toolCallId } : {},
|
|
3625
|
+
...event.skipReason ? { skipReason: event.skipReason } : {},
|
|
2292
3626
|
requestBytes,
|
|
2293
3627
|
responseBytes,
|
|
2294
3628
|
model: resolvedModel,
|
|
@@ -2310,6 +3644,15 @@ function recordTraceEvent(session, event) {
|
|
|
2310
3644
|
timestamp: timestampIso
|
|
2311
3645
|
});
|
|
2312
3646
|
}
|
|
3647
|
+
if (session.captureContent && event.capture) {
|
|
3648
|
+
try {
|
|
3649
|
+
attachCapturedContent(
|
|
3650
|
+
record,
|
|
3651
|
+
buildCapturedContent(event.capture, session.captureLimits ?? { maxStringChars: 4096, maxMessages: 32 })
|
|
3652
|
+
);
|
|
3653
|
+
} catch {
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
2313
3656
|
session.events.push(record);
|
|
2314
3657
|
const sink = session.resolvedConfig.sink;
|
|
2315
3658
|
if (sink.type === "custom" && typeof sink.onEvent === "function") {
|
|
@@ -2404,6 +3747,19 @@ function recordSubagentSpan(session, span) {
|
|
|
2404
3747
|
sections
|
|
2405
3748
|
});
|
|
2406
3749
|
}
|
|
3750
|
+
function foldSupersededSpans(events) {
|
|
3751
|
+
const rank = (event, index) => typeof event.sequence === "number" && Number.isFinite(event.sequence) ? event.sequence : index;
|
|
3752
|
+
const winner = /* @__PURE__ */ new Map();
|
|
3753
|
+
for (let i = 0; i < events.length; i++) {
|
|
3754
|
+
const id = events[i].spanId;
|
|
3755
|
+
if (!id) continue;
|
|
3756
|
+
const current = winner.get(id);
|
|
3757
|
+
if (current === void 0 || rank(events[i], i) >= rank(events[current], current)) winner.set(id, i);
|
|
3758
|
+
}
|
|
3759
|
+
return events.filter(
|
|
3760
|
+
(event, i) => !(event.spanId && (event.status === "pending" || event.status === "running") && winner.get(event.spanId) !== i)
|
|
3761
|
+
);
|
|
3762
|
+
}
|
|
2407
3763
|
function recordOrDeferTraceEvent(ctx, event, options) {
|
|
2408
3764
|
const session = ctx?.__traceSession;
|
|
2409
3765
|
if (isTraceSessionOpen(session)) {
|
|
@@ -2414,7 +3770,8 @@ function recordOrDeferTraceEvent(ctx, event, options) {
|
|
|
2414
3770
|
const held = Array.isArray(ctx?.[DEFERRED_TRACE_EVENTS_KEY]) ? ctx[DEFERRED_TRACE_EVENTS_KEY] : [];
|
|
2415
3771
|
return {
|
|
2416
3772
|
...ctx || {},
|
|
2417
|
-
|
|
3773
|
+
// `capture` (content for exporters) is never parked on ctx, which callers persist.
|
|
3774
|
+
[DEFERRED_TRACE_EVENTS_KEY]: [...held, { ...event, capture: void 0, timestamp: event.timestamp ?? (/* @__PURE__ */ new Date()).toISOString() }]
|
|
2418
3775
|
};
|
|
2419
3776
|
}
|
|
2420
3777
|
function replayDeferredTraceEvents(session, deferred) {
|
|
@@ -2448,6 +3805,7 @@ async function finalizeTraceSession(session, params = {}) {
|
|
|
2448
3805
|
message: params.error.message || "Unknown error",
|
|
2449
3806
|
stack: params.error.stack,
|
|
2450
3807
|
type: "session",
|
|
3808
|
+
...params.error.name ? { errorName: params.error.name } : {},
|
|
2451
3809
|
timestamp: endedAtIso
|
|
2452
3810
|
});
|
|
2453
3811
|
}
|
|
@@ -2471,24 +3829,62 @@ async function finalizeTraceSession(session, params = {}) {
|
|
|
2471
3829
|
...(session.part ?? 1) > 1 ? { continuation: { part: session.part, firstSequence: (session.sequenceOffset ?? 0) + 1 } } : {}
|
|
2472
3830
|
});
|
|
2473
3831
|
const payloadForSink = buildPayload(initialStatus);
|
|
3832
|
+
const carried = session.carriedSpans ?? [];
|
|
3833
|
+
const exportPayload = carried.length > 0 ? { ...payloadForSink, events: [...carried, ...payloadForSink.events] } : payloadForSink;
|
|
2474
3834
|
let sinkFailed = false;
|
|
2475
3835
|
const sink = session.resolvedConfig.sink;
|
|
2476
3836
|
const isStreamingMode = session.resolvedConfig.mode === "streaming";
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
3837
|
+
const terminal = initialStatus !== "paused" && initialStatus !== "in_progress";
|
|
3838
|
+
const exportTargets = [];
|
|
3839
|
+
if (sink.type === "otlp") exportTargets.push({ exporter: sink.exporter, isSink: true });
|
|
3840
|
+
if (!isSubagentTraceScope(session)) {
|
|
3841
|
+
for (const exporter of session.exporters ?? []) exportTargets.push({ exporter, isSink: false });
|
|
3842
|
+
}
|
|
3843
|
+
const unsampled = session.parent !== void 0 && !session.parent.sampled;
|
|
3844
|
+
if (exportTargets.length > 0) {
|
|
3845
|
+
const results = await Promise.all(
|
|
3846
|
+
exportTargets.map(async ({ exporter }) => {
|
|
3847
|
+
if (unsampled) {
|
|
3848
|
+
return { ok: true, skipped: true, reason: "the upstream traceparent is not sampled (sampled=0)", attempts: 0, spans: 0, bytes: 0 };
|
|
3849
|
+
}
|
|
3850
|
+
try {
|
|
3851
|
+
return await exporter.exportSession(exportPayload, {
|
|
3852
|
+
terminal,
|
|
3853
|
+
cancelled: params.cancelled,
|
|
3854
|
+
parent: session.parent
|
|
3855
|
+
});
|
|
3856
|
+
} catch (err) {
|
|
3857
|
+
return { ok: false, attempts: 0, spans: 0, bytes: 0, error: err instanceof Error ? err.message : String(err) };
|
|
3858
|
+
}
|
|
3859
|
+
})
|
|
3860
|
+
);
|
|
3861
|
+
results.forEach((result, index) => {
|
|
3862
|
+
const { exporter, isSink } = exportTargets[index];
|
|
3863
|
+
(session.exportReports ?? (session.exportReports = [])).push({ exporter: exporter.name, endpoint: exporter.endpoint, sink: isSink, terminal, result });
|
|
3864
|
+
if (result.ok) {
|
|
3865
|
+
const rejected = result.partialSuccess?.rejectedSpans ?? 0;
|
|
3866
|
+
if ((rejected > 0 || result.partialSuccess?.message) && typeof console !== "undefined" && typeof console.warn === "function") {
|
|
3867
|
+
const detail = result.partialSuccess?.message ? `: ${result.partialSuccess.message}` : "";
|
|
3868
|
+
console.warn(`[Tracing] OTLP exporter "${exporter.name}": the collector rejected ${rejected} span(s)${detail}`);
|
|
3869
|
+
}
|
|
3870
|
+
return;
|
|
3871
|
+
}
|
|
3872
|
+
const message = result.error ?? "OTLP export failed";
|
|
3873
|
+
if (isSink) {
|
|
3874
|
+
sinkFailed = true;
|
|
3875
|
+
session.errors.push({ eventId: "sink", message, type: "sink", timestamp: endedAtIso });
|
|
3876
|
+
if (typeof console !== "undefined" && typeof console.error === "function") {
|
|
3877
|
+
console.error("[Tracing] OTLP export failed:", message);
|
|
3878
|
+
}
|
|
3879
|
+
} else if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
3880
|
+
console.warn(`[Tracing] OTLP exporter "${exporter.name}" failed:`, message);
|
|
3881
|
+
}
|
|
3882
|
+
});
|
|
3883
|
+
}
|
|
3884
|
+
if (params.exportOnly) {
|
|
3885
|
+
return buildPayload(payloadForSink.status);
|
|
3886
|
+
}
|
|
3887
|
+
if (sink.type === "cognipeer" || sink.type === "http") {
|
|
2492
3888
|
try {
|
|
2493
3889
|
const headers = sink.type === "cognipeer" ? { Authorization: `Bearer ${sink.apiKey}` } : sink.headers;
|
|
2494
3890
|
if (isStreamingMode && session.sessionStarted) {
|
|
@@ -2584,6 +3980,23 @@ async function finalizeTraceSession(session, params = {}) {
|
|
|
2584
3980
|
}
|
|
2585
3981
|
return finalPayload;
|
|
2586
3982
|
}
|
|
3983
|
+
async function closeTraceContinuation(continuation, params = {}) {
|
|
3984
|
+
const parsed = readTraceContinuation(continuation);
|
|
3985
|
+
if (!parsed) return void 0;
|
|
3986
|
+
const tracing = { ...params.tracing ?? {}, enabled: true };
|
|
3987
|
+
const hasOtlpSink = withDefaults(tracing).sink.type === "otlp";
|
|
3988
|
+
if (!hasOtlpSink && !params.exporters?.length) return void 0;
|
|
3989
|
+
const session = createTraceSession({ tracing }, parsed, { exporters: params.exporters });
|
|
3990
|
+
if (!session) return void 0;
|
|
3991
|
+
replayDeferredTraceEvents(session, params.events);
|
|
3992
|
+
const status = params.status ?? "partial";
|
|
3993
|
+
return finalizeTraceSession(session, {
|
|
3994
|
+
agentRuntime: params.agentRuntime,
|
|
3995
|
+
status,
|
|
3996
|
+
error: status === "error" ? params.error ?? { message: "The run ended in an error before it could be resumed." } : null,
|
|
3997
|
+
exportOnly: true
|
|
3998
|
+
});
|
|
3999
|
+
}
|
|
2587
4000
|
function sanitizeTracePayload(value) {
|
|
2588
4001
|
if (value === void 0) return void 0;
|
|
2589
4002
|
try {
|
|
@@ -2623,6 +4036,72 @@ function estimatePayloadBytes(value) {
|
|
|
2623
4036
|
}
|
|
2624
4037
|
}
|
|
2625
4038
|
}
|
|
4039
|
+
|
|
4040
|
+
// src/providers/wireInfo.ts
|
|
4041
|
+
var WIRE_INFO = Symbol.for("cognipeer.agent-sdk.wireInfo");
|
|
4042
|
+
function usageBasisOf(provider) {
|
|
4043
|
+
switch (provider) {
|
|
4044
|
+
case "anthropic":
|
|
4045
|
+
case "bedrock":
|
|
4046
|
+
return { inputExcludesCache: true };
|
|
4047
|
+
case "vertex":
|
|
4048
|
+
return { outputExcludesReasoning: true };
|
|
4049
|
+
default:
|
|
4050
|
+
return void 0;
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
function attachWireInfo(message, info) {
|
|
4054
|
+
const clean = {};
|
|
4055
|
+
if (info.provider) clean.provider = info.provider;
|
|
4056
|
+
if (info.responseId) clean.responseId = info.responseId;
|
|
4057
|
+
if (info.responseModel) clean.responseModel = info.responseModel;
|
|
4058
|
+
if (info.rawFinishReason) clean.rawFinishReason = info.rawFinishReason;
|
|
4059
|
+
if (info.streaming) clean.streaming = true;
|
|
4060
|
+
const basis = info.usageBasis ?? usageBasisOf(info.provider);
|
|
4061
|
+
if (basis) clean.usageBasis = basis;
|
|
4062
|
+
message[WIRE_INFO] = clean;
|
|
4063
|
+
return message;
|
|
4064
|
+
}
|
|
4065
|
+
function wireInfoOf(message) {
|
|
4066
|
+
if (!message || typeof message !== "object") return void 0;
|
|
4067
|
+
return message[WIRE_INFO];
|
|
4068
|
+
}
|
|
4069
|
+
|
|
4070
|
+
// src/utils/traceFacts.ts
|
|
4071
|
+
var nonEmpty2 = (value) => typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
4072
|
+
var isRunId = (id) => /^(run-|lc_run)/i.test(id);
|
|
4073
|
+
function providerHintOf(model, response) {
|
|
4074
|
+
const named = getProviderName(model);
|
|
4075
|
+
if (named) return named;
|
|
4076
|
+
const fromWire = wireInfoOf(response)?.provider;
|
|
4077
|
+
if (fromWire) return fromWire;
|
|
4078
|
+
try {
|
|
4079
|
+
return nonEmpty2(getModelCapabilities(model).provider);
|
|
4080
|
+
} catch {
|
|
4081
|
+
return void 0;
|
|
4082
|
+
}
|
|
4083
|
+
}
|
|
4084
|
+
function traceResponseFacts(model, response, rawUsage, streaming) {
|
|
4085
|
+
const wire = wireInfoOf(response);
|
|
4086
|
+
const meta = response?.response_metadata ?? {};
|
|
4087
|
+
const message = response;
|
|
4088
|
+
const idCandidate = nonEmpty2(wire?.responseId) ?? nonEmpty2(meta.id) ?? nonEmpty2(message?.id);
|
|
4089
|
+
const responseId = idCandidate && !isRunId(idCandidate) ? idCandidate : void 0;
|
|
4090
|
+
const responseModel = nonEmpty2(wire?.responseModel) ?? nonEmpty2(meta.model_name) ?? nonEmpty2(meta.model) ?? nonEmpty2(meta.modelName);
|
|
4091
|
+
const rawFinishReason = nonEmpty2(wire?.rawFinishReason) ?? nonEmpty2(meta.stop_reason) ?? nonEmpty2(meta.finish_reason) ?? nonEmpty2(meta.finishReason);
|
|
4092
|
+
const cacheWriteTokens = cacheWriteTokensOf(rawUsage);
|
|
4093
|
+
const provider = providerHintOf(model, response);
|
|
4094
|
+
const isStreaming = streaming ?? wire?.streaming;
|
|
4095
|
+
return {
|
|
4096
|
+
...provider ? { provider } : {},
|
|
4097
|
+
...responseId ? { responseId } : {},
|
|
4098
|
+
...responseModel ? { responseModel } : {},
|
|
4099
|
+
...rawFinishReason ? { rawFinishReason } : {},
|
|
4100
|
+
...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {},
|
|
4101
|
+
...wire?.usageBasis ? { usageBasis: { ...wire.usageBasis } } : {},
|
|
4102
|
+
...isStreaming ? { streaming: true } : {}
|
|
4103
|
+
};
|
|
4104
|
+
}
|
|
2626
4105
|
function toMessageUsage(u) {
|
|
2627
4106
|
return {
|
|
2628
4107
|
prompt_tokens: u.inputTokens,
|
|
@@ -2645,7 +4124,12 @@ function fromNativeProvider(provider, options) {
|
|
|
2645
4124
|
if (link.signal) request.signal = link.signal;
|
|
2646
4125
|
request = await applyTransform(request);
|
|
2647
4126
|
const response = await provider.complete(request);
|
|
2648
|
-
return toBaseChatMessage(response)
|
|
4127
|
+
return attachWireInfo(toBaseChatMessage(response), {
|
|
4128
|
+
provider: provider.providerName,
|
|
4129
|
+
responseId: response.id,
|
|
4130
|
+
responseModel: response.model,
|
|
4131
|
+
rawFinishReason: response.rawFinishReason
|
|
4132
|
+
});
|
|
2649
4133
|
} finally {
|
|
2650
4134
|
link.dispose();
|
|
2651
4135
|
}
|
|
@@ -2664,6 +4148,8 @@ function fromNativeProvider(provider, options) {
|
|
|
2664
4148
|
let reasoningText = "";
|
|
2665
4149
|
let finishReason;
|
|
2666
4150
|
let responseModel;
|
|
4151
|
+
let responseId;
|
|
4152
|
+
let rawFinishReason;
|
|
2667
4153
|
const toolCallBuffers = /* @__PURE__ */ new Map();
|
|
2668
4154
|
for await (const chunk of provider.completeStream(request)) {
|
|
2669
4155
|
if (chunk.delta.content) {
|
|
@@ -2671,6 +4157,8 @@ function fromNativeProvider(provider, options) {
|
|
|
2671
4157
|
yield chunk.delta.content;
|
|
2672
4158
|
}
|
|
2673
4159
|
if (chunk.model) responseModel = chunk.model;
|
|
4160
|
+
if (chunk.id) responseId = chunk.id;
|
|
4161
|
+
if (chunk.rawFinishReason) rawFinishReason = chunk.rawFinishReason;
|
|
2674
4162
|
if (chunk.finishReason) finishReason = chunk.finishReason;
|
|
2675
4163
|
if (chunk.delta.reasoning?.blocks?.length) {
|
|
2676
4164
|
reasoningBlocks = chunk.delta.reasoning.blocks;
|
|
@@ -2692,7 +4180,8 @@ function fromNativeProvider(provider, options) {
|
|
|
2692
4180
|
id: tc.id,
|
|
2693
4181
|
name: tc.name ?? "",
|
|
2694
4182
|
arguments: tc.arguments ?? "",
|
|
2695
|
-
...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
|
|
4183
|
+
...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
|
|
4184
|
+
...tc.idSynthesized ? { idSynthesized: true } : {}
|
|
2696
4185
|
});
|
|
2697
4186
|
}
|
|
2698
4187
|
}
|
|
@@ -2716,7 +4205,13 @@ function fromNativeProvider(provider, options) {
|
|
|
2716
4205
|
...responseModel ? { model_name: responseModel } : {}
|
|
2717
4206
|
};
|
|
2718
4207
|
}
|
|
2719
|
-
yield finalMessage
|
|
4208
|
+
yield attachWireInfo(finalMessage, {
|
|
4209
|
+
provider: provider.providerName,
|
|
4210
|
+
responseId,
|
|
4211
|
+
responseModel,
|
|
4212
|
+
rawFinishReason,
|
|
4213
|
+
streaming: true
|
|
4214
|
+
});
|
|
2720
4215
|
} finally {
|
|
2721
4216
|
link.dispose();
|
|
2722
4217
|
}
|
|
@@ -3090,7 +4585,8 @@ function toBaseChatMessage(response) {
|
|
|
3090
4585
|
id: tc.id,
|
|
3091
4586
|
type: "function",
|
|
3092
4587
|
function: { name: tc.name, arguments: tc.arguments },
|
|
3093
|
-
...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
|
|
4588
|
+
...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
|
|
4589
|
+
...tc.idSynthesized ? { idSynthesized: true } : {}
|
|
3094
4590
|
}));
|
|
3095
4591
|
}
|
|
3096
4592
|
if (response.reasoning && (response.reasoning.blocks?.length || response.reasoning.summary)) {
|
|
@@ -3112,7 +4608,8 @@ function assembleMessage(content, toolCalls, usage) {
|
|
|
3112
4608
|
id: tc.id,
|
|
3113
4609
|
type: "function",
|
|
3114
4610
|
function: { name: tc.name, arguments: tc.arguments },
|
|
3115
|
-
...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {}
|
|
4611
|
+
...tc.thoughtSignature ? { thoughtSignature: tc.thoughtSignature } : {},
|
|
4612
|
+
...tc.idSynthesized ? { idSynthesized: true } : {}
|
|
3116
4613
|
}));
|
|
3117
4614
|
}
|
|
3118
4615
|
return msg;
|
|
@@ -4006,7 +5503,7 @@ var CCRStore = class _CCRStore {
|
|
|
4006
5503
|
}
|
|
4007
5504
|
static hashOf(value) {
|
|
4008
5505
|
const serialized = typeof value === "string" ? value : JSON.stringify(value);
|
|
4009
|
-
return createHash("
|
|
5506
|
+
return createHash("sha256").update(serialized).digest("hex").slice(0, 16);
|
|
4010
5507
|
}
|
|
4011
5508
|
};
|
|
4012
5509
|
var DedupTracker = class {
|
|
@@ -4019,7 +5516,7 @@ var DedupTracker = class {
|
|
|
4019
5516
|
* first time it has been seen.
|
|
4020
5517
|
*/
|
|
4021
5518
|
checkAndRegister(content, executionId, toolName) {
|
|
4022
|
-
const hash = createHash("
|
|
5519
|
+
const hash = createHash("sha256").update(content).digest("hex");
|
|
4023
5520
|
const existing = this.seen.get(hash);
|
|
4024
5521
|
if (!existing) {
|
|
4025
5522
|
this.seen.set(hash, { executionId, toolName });
|
|
@@ -4556,7 +6053,7 @@ function createAgentCoreNode(opts) {
|
|
|
4556
6053
|
const actorVersion = runtime.version ?? opts.version;
|
|
4557
6054
|
let traceToolDefinitions;
|
|
4558
6055
|
const computeTraceToolDefinitions = (menu) => {
|
|
4559
|
-
if (!traceSession || !traceSession.resolvedConfig.logData || menu.length === 0) return void 0;
|
|
6056
|
+
if (!traceSession || !(traceSession.resolvedConfig.logData || traceSession.captureContent) || menu.length === 0) return void 0;
|
|
4560
6057
|
try {
|
|
4561
6058
|
const wire = shouldUseStrictToolCalling ? prepareStrictToolMenu(menu).menu : menu;
|
|
4562
6059
|
return wire.map((tool) => {
|
|
@@ -4769,8 +6266,9 @@ ${append}`;
|
|
|
4769
6266
|
// outcome, and an "error" status would flip the whole trace session
|
|
4770
6267
|
// status to error for a run that behaved exactly as configured.
|
|
4771
6268
|
status: "skipped",
|
|
6269
|
+
skipReason: "blocked",
|
|
4772
6270
|
model: getModelName(runtime.model || opts.model),
|
|
4773
|
-
provider:
|
|
6271
|
+
provider: providerHintOf(runtime.model || opts.model),
|
|
4774
6272
|
messageList: state.messages
|
|
4775
6273
|
});
|
|
4776
6274
|
return {
|
|
@@ -4799,9 +6297,12 @@ ${append}`;
|
|
|
4799
6297
|
for (const key of ["usage", "usage_metadata", "response_metadata"]) {
|
|
4800
6298
|
if (merged[key] === void 0 && original?.[key] !== void 0) merged[key] = original[key];
|
|
4801
6299
|
}
|
|
6300
|
+
if (wireInfoOf(merged) === void 0 && wireInfoOf(original) !== void 0) merged[WIRE_INFO] = wireInfoOf(original);
|
|
4802
6301
|
return merged;
|
|
4803
6302
|
};
|
|
4804
6303
|
let response;
|
|
6304
|
+
let sentMessages;
|
|
6305
|
+
let streamedCall = false;
|
|
4805
6306
|
let modelAttempt = 0;
|
|
4806
6307
|
const maxModelRetries = host?.maxModelRetries ?? 0;
|
|
4807
6308
|
const finishCancelledTurn = (partialText) => {
|
|
@@ -4815,12 +6316,16 @@ ${append}`;
|
|
|
4815
6316
|
// "skipped", not "error": the call did not fail, the caller ended it —
|
|
4816
6317
|
// and an "error" would flip the whole session to error.
|
|
4817
6318
|
status: "skipped",
|
|
6319
|
+
// The call reached the provider and was hung up on: still a model call, not a skipped one.
|
|
6320
|
+
skipReason: "cancelled",
|
|
6321
|
+
...streamedCall ? { streaming: true } : {},
|
|
4818
6322
|
durationMs: Date.now() - start,
|
|
4819
6323
|
requestBytes: promptBytes,
|
|
4820
6324
|
model: getModelName(runtime.model || opts.model),
|
|
4821
|
-
provider:
|
|
6325
|
+
provider: providerHintOf(runtime.model || opts.model),
|
|
4822
6326
|
messageList: state.messages,
|
|
4823
|
-
toolDefinitions: traceToolDefinitions
|
|
6327
|
+
toolDefinitions: traceToolDefinitions,
|
|
6328
|
+
capture: { input: sentMessages ?? wireMessages, toolDefinitions: traceToolDefinitions }
|
|
4824
6329
|
});
|
|
4825
6330
|
onEvent?.({ type: "cancelled", stage: "agent", reason });
|
|
4826
6331
|
onProgress?.({ stage: "agent", message: "Cancelled", detail: { reason } });
|
|
@@ -4836,8 +6341,9 @@ ${append}`;
|
|
|
4836
6341
|
label: "Assistant (plugin short-circuit)",
|
|
4837
6342
|
actor: { scope: "agent", name: actorName, role: "assistant", version: actorVersion },
|
|
4838
6343
|
status: "skipped",
|
|
6344
|
+
skipReason: "short_circuit",
|
|
4839
6345
|
model: getModelName(runtime.model || opts.model),
|
|
4840
|
-
provider:
|
|
6346
|
+
provider: providerHintOf(runtime.model || opts.model),
|
|
4841
6347
|
messageList: state.messages,
|
|
4842
6348
|
toolDefinitions: traceToolDefinitions
|
|
4843
6349
|
});
|
|
@@ -4845,8 +6351,10 @@ ${append}`;
|
|
|
4845
6351
|
let streamedText = "";
|
|
4846
6352
|
try {
|
|
4847
6353
|
const normalizedMessages = normalizeBedrockToolPairing([...wireMessages]);
|
|
6354
|
+
sentMessages = normalizedMessages;
|
|
4848
6355
|
debugToolPairing(normalizedMessages);
|
|
4849
6356
|
if (streamingEnabled && typeof modelWithTools.stream === "function") {
|
|
6357
|
+
streamedCall = true;
|
|
4850
6358
|
let streamedMessage;
|
|
4851
6359
|
let cutByCancel = false;
|
|
4852
6360
|
for await (const chunk of modelWithTools.stream(normalizedMessages, invokeParams)) {
|
|
@@ -4892,12 +6400,14 @@ ${append}`;
|
|
|
4892
6400
|
durationMs: durationMs2,
|
|
4893
6401
|
requestBytes: promptBytes,
|
|
4894
6402
|
model: getModelName(runtime.model || opts.model),
|
|
4895
|
-
provider:
|
|
4896
|
-
error:
|
|
6403
|
+
provider: providerHintOf(runtime.model || opts.model),
|
|
6404
|
+
error: traceErrorOf(err),
|
|
6405
|
+
...streamedCall ? { streaming: true } : {},
|
|
4897
6406
|
messageList: state.messages,
|
|
4898
6407
|
toolDefinitions: traceToolDefinitions,
|
|
4899
6408
|
responseFormat: traceResponseFormat,
|
|
4900
|
-
responseFormatStrategy: traceResponseFormatStrategy
|
|
6409
|
+
responseFormatStrategy: traceResponseFormatStrategy,
|
|
6410
|
+
capture: { input: sentMessages ?? wireMessages, toolDefinitions: traceToolDefinitions }
|
|
4901
6411
|
});
|
|
4902
6412
|
throw err;
|
|
4903
6413
|
}
|
|
@@ -4950,6 +6460,8 @@ ${append}`;
|
|
|
4950
6460
|
const responsePayload = shouldLogResponse ? sanitizeTracePayload(response) : void 0;
|
|
4951
6461
|
const responseBytes = responsePayload !== void 0 ? estimatePayloadBytes(responsePayload) : void 0;
|
|
4952
6462
|
const finishReason = response?.response_metadata?.finish_reason ?? response?.response_metadata?.finishReason ?? response?.finishReason;
|
|
6463
|
+
const facts = traceResponseFacts(runtime.model || opts.model, response, rawUsage, streamedCall);
|
|
6464
|
+
const jsonOutput = Boolean(responseFormat) && responseFormat?.response_format?.type !== "text" && responseFormat?.type !== "text";
|
|
4953
6465
|
recordTraceEvent(traceSession, {
|
|
4954
6466
|
type: "ai_call",
|
|
4955
6467
|
label: "Assistant Response",
|
|
@@ -4966,11 +6478,13 @@ ${append}`;
|
|
|
4966
6478
|
requestBytes: promptBytes,
|
|
4967
6479
|
responseBytes,
|
|
4968
6480
|
model: modelName,
|
|
4969
|
-
|
|
6481
|
+
...facts,
|
|
6482
|
+
outputType: jsonOutput ? "json" : "text",
|
|
4970
6483
|
messageList: messagesWithResponse,
|
|
4971
6484
|
toolDefinitions: traceToolDefinitions,
|
|
4972
6485
|
responseFormat: traceResponseFormat,
|
|
4973
|
-
responseFormatStrategy: traceResponseFormatStrategy
|
|
6486
|
+
responseFormatStrategy: traceResponseFormatStrategy,
|
|
6487
|
+
capture: { input: sentMessages ?? wireMessages, output: response, toolDefinitions: traceToolDefinitions }
|
|
4974
6488
|
});
|
|
4975
6489
|
if (normalized) {
|
|
4976
6490
|
recordUsage(state, modelName, normalized);
|
|
@@ -4996,6 +6510,12 @@ function sameJson(a, b) {
|
|
|
4996
6510
|
return false;
|
|
4997
6511
|
}
|
|
4998
6512
|
}
|
|
6513
|
+
var idSection = (label, data) => ({
|
|
6514
|
+
kind: "metadata",
|
|
6515
|
+
label,
|
|
6516
|
+
data,
|
|
6517
|
+
identity: true
|
|
6518
|
+
});
|
|
4999
6519
|
function recordApprovalRequested(session, entry) {
|
|
5000
6520
|
if (!session || surfacedFromSubagent(entry) || !canPauseForHuman(session)) return;
|
|
5001
6521
|
const logData = session.resolvedConfig.logData;
|
|
@@ -5021,7 +6541,7 @@ function recordApprovalRequested(session, entry) {
|
|
|
5021
6541
|
timestamp: entry.requestedAt,
|
|
5022
6542
|
status: "pending",
|
|
5023
6543
|
actor: { scope: "agent", name: entry.toolName, role: "approval_request" },
|
|
5024
|
-
sections
|
|
6544
|
+
sections: [...sections, idSection("Approval ids", { approvalId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt })]
|
|
5025
6545
|
});
|
|
5026
6546
|
}
|
|
5027
6547
|
function recordHumanDecisions(session, state) {
|
|
@@ -5062,7 +6582,14 @@ function recordHumanDecisions(session, state) {
|
|
|
5062
6582
|
durationMs: waitedMs(entry.requestedAt, entry.decidedAt),
|
|
5063
6583
|
status: "success",
|
|
5064
6584
|
actor: { scope: "human", name: entry.decidedBy || "reviewer", role: "approver" },
|
|
5065
|
-
sections
|
|
6585
|
+
sections: [...sections, idSection("Decision ids", {
|
|
6586
|
+
approvalId: entry.id,
|
|
6587
|
+
toolCallId: entry.toolCallId,
|
|
6588
|
+
decision: entry.status,
|
|
6589
|
+
requestedAt: entry.requestedAt,
|
|
6590
|
+
decidedAt: entry.decidedAt,
|
|
6591
|
+
...waitedMs(entry.requestedAt, entry.decidedAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.decidedAt) } : {}
|
|
6592
|
+
})]
|
|
5066
6593
|
});
|
|
5067
6594
|
entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
|
|
5068
6595
|
}
|
|
@@ -5107,7 +6634,14 @@ function recordHumanDecisions(session, state) {
|
|
|
5107
6634
|
durationMs: waitedMs(entry.requestedAt, entry.answeredAt),
|
|
5108
6635
|
status: cancelled ? "skipped" : "success",
|
|
5109
6636
|
actor: { scope: "human", name: entry.answeredBy || "user", role: "user" },
|
|
5110
|
-
sections
|
|
6637
|
+
sections: [...sections, idSection("Answer ids", {
|
|
6638
|
+
questionId: entry.id,
|
|
6639
|
+
toolCallId: entry.toolCallId,
|
|
6640
|
+
status: entry.status,
|
|
6641
|
+
requestedAt: entry.requestedAt,
|
|
6642
|
+
answeredAt: entry.answeredAt,
|
|
6643
|
+
...waitedMs(entry.requestedAt, entry.answeredAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.answeredAt) } : {}
|
|
6644
|
+
})]
|
|
5111
6645
|
});
|
|
5112
6646
|
entry.metadata = { ...entry.metadata || {}, [TRACED_KEY]: true };
|
|
5113
6647
|
}
|
|
@@ -5132,7 +6666,7 @@ function recordClientToolRequested(session, entry) {
|
|
|
5132
6666
|
timestamp: entry.requestedAt,
|
|
5133
6667
|
status: "pending",
|
|
5134
6668
|
actor: { scope: "client", name: clientTool.name, role: "tool" },
|
|
5135
|
-
sections
|
|
6669
|
+
sections: [...sections, idSection("Client tool ids", { questionId: entry.id, toolCallId: entry.toolCallId, status: "pending", requestedAt: entry.requestedAt })]
|
|
5136
6670
|
});
|
|
5137
6671
|
}
|
|
5138
6672
|
function readClientTool(entry) {
|
|
@@ -5179,7 +6713,14 @@ function recordClientToolResult(session, entry, clientTool, toolHistory) {
|
|
|
5179
6713
|
durationMs: waitedMs(entry.requestedAt, entry.answeredAt) ?? ranMs,
|
|
5180
6714
|
status: failed ? "error" : "success",
|
|
5181
6715
|
actor: { scope: "client", name: clientTool.name, role: "tool" },
|
|
5182
|
-
sections
|
|
6716
|
+
sections: [...sections, idSection("Client tool ids", {
|
|
6717
|
+
questionId: entry.id,
|
|
6718
|
+
toolCallId: entry.toolCallId,
|
|
6719
|
+
status: failed ? "error" : "answered",
|
|
6720
|
+
requestedAt: entry.requestedAt,
|
|
6721
|
+
answeredAt: entry.answeredAt,
|
|
6722
|
+
...waitedMs(entry.requestedAt, entry.answeredAt) !== void 0 ? { waitedMs: waitedMs(entry.requestedAt, entry.answeredAt) } : {}
|
|
6723
|
+
})]
|
|
5183
6724
|
});
|
|
5184
6725
|
}
|
|
5185
6726
|
|
|
@@ -5285,9 +6826,11 @@ function normalizeToolCall(call) {
|
|
|
5285
6826
|
return {
|
|
5286
6827
|
id: call.id,
|
|
5287
6828
|
name,
|
|
5288
|
-
args: call.args ?? call.arguments ?? call.input ?? call.function?.arguments ?? call.function_call?.arguments
|
|
6829
|
+
args: call.args ?? call.arguments ?? call.input ?? call.function?.arguments ?? call.function_call?.arguments,
|
|
6830
|
+
...call.idSynthesized === true ? { idSynthesized: true } : {}
|
|
5289
6831
|
};
|
|
5290
6832
|
}
|
|
6833
|
+
var providerToolCallId = (tc) => tc.id && !tc.idSynthesized ? tc.id : void 0;
|
|
5291
6834
|
function normalizeToolSchema(tool, toolName) {
|
|
5292
6835
|
const schema = tool.schema;
|
|
5293
6836
|
if (!schema) return void 0;
|
|
@@ -5545,6 +7088,8 @@ function createToolsNode(initialTools, opts) {
|
|
|
5545
7088
|
label: `Tool Denied - ${toolName}`,
|
|
5546
7089
|
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
5547
7090
|
status: "skipped",
|
|
7091
|
+
skipReason: "denied",
|
|
7092
|
+
toolCallId: providerToolCallId(tc),
|
|
5548
7093
|
toolDetails,
|
|
5549
7094
|
toolExecutionId: toolCallId,
|
|
5550
7095
|
sections: buildToolTraceSections({
|
|
@@ -5616,6 +7161,8 @@ function createToolsNode(initialTools, opts) {
|
|
|
5616
7161
|
label: `Tool Skipped - ${toolName}`,
|
|
5617
7162
|
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
5618
7163
|
status: "skipped",
|
|
7164
|
+
skipReason: "skipped",
|
|
7165
|
+
toolCallId: providerToolCallId(tc),
|
|
5619
7166
|
toolDetails,
|
|
5620
7167
|
toolExecutionId: tc.id,
|
|
5621
7168
|
sections: buildToolTraceSections({
|
|
@@ -5752,10 +7299,13 @@ function createToolsNode(initialTools, opts) {
|
|
|
5752
7299
|
label: `Tool Error - ${toolName}`,
|
|
5753
7300
|
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
5754
7301
|
status: "error",
|
|
7302
|
+
// The tool was not run: an open breaker refused the call.
|
|
7303
|
+
skipReason: "skipped",
|
|
7304
|
+
toolCallId: providerToolCallId(tc),
|
|
5755
7305
|
requestBytes: inputBytes,
|
|
5756
7306
|
toolDetails,
|
|
5757
7307
|
toolExecutionId: toolCallId,
|
|
5758
|
-
error: { message: breakerMsg },
|
|
7308
|
+
error: { message: breakerMsg, type: "circuit_breaker_open" },
|
|
5759
7309
|
sections: buildToolTraceSections({
|
|
5760
7310
|
args,
|
|
5761
7311
|
executionId: toolCallId,
|
|
@@ -5815,6 +7365,9 @@ function createToolsNode(initialTools, opts) {
|
|
|
5815
7365
|
type: "tool_call",
|
|
5816
7366
|
label: shortCircuitSource === "plugin" ? `Tool Short-Circuited - ${toolName}` : `Tool Execution - ${toolName}`,
|
|
5817
7367
|
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
7368
|
+
// Answered from the cache or by a plugin: nothing executed.
|
|
7369
|
+
skipReason: "short_circuit",
|
|
7370
|
+
toolCallId: providerToolCallId(tc),
|
|
5818
7371
|
durationMs: 0,
|
|
5819
7372
|
requestBytes: inputBytes,
|
|
5820
7373
|
responseBytes: outputBytes2,
|
|
@@ -5850,7 +7403,15 @@ function createToolsNode(initialTools, opts) {
|
|
|
5850
7403
|
onProgress?.({ stage: "tools", message: `Running tool ${tc.name}` });
|
|
5851
7404
|
const anyTool = tool;
|
|
5852
7405
|
traceSpanId = traceSession ? generateSpanId() : void 0;
|
|
5853
|
-
const callOptions = {
|
|
7406
|
+
const callOptions = {
|
|
7407
|
+
cancellationToken,
|
|
7408
|
+
signal: abortSignal,
|
|
7409
|
+
toolCallId,
|
|
7410
|
+
...traceSpanId ? { traceSpanId } : {},
|
|
7411
|
+
// So the tool can propagate the trace to what it calls (traceparentOf).
|
|
7412
|
+
...traceSpanId && traceSession?.traceId ? { traceId: traceSession.traceId } : {},
|
|
7413
|
+
...traceSpanId && traceSession?.parent ? { traceFlags: traceSession.parent.flags } : {}
|
|
7414
|
+
};
|
|
5854
7415
|
const invokeOnce = async () => {
|
|
5855
7416
|
if (typeof anyTool.func === "function") return anyTool.func(args, callOptions);
|
|
5856
7417
|
if (typeof anyTool.invoke === "function") return anyTool.invoke(args, callOptions);
|
|
@@ -6036,7 +7597,10 @@ function createToolsNode(initialTools, opts) {
|
|
|
6036
7597
|
spanId: traceSpanId,
|
|
6037
7598
|
label: `Tool Execution - ${toolName}`,
|
|
6038
7599
|
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
6039
|
-
...reportedFailure ? { status: "error", error: { message: reportedFailure } } : {},
|
|
7600
|
+
...reportedFailure ? { status: "error", error: { message: reportedFailure, type: "tool_error" } } : {},
|
|
7601
|
+
toolCallId: providerToolCallId(tc),
|
|
7602
|
+
// `output` is already past postToolUse, so a redaction plugin has applied.
|
|
7603
|
+
capture: reportedFailure ? { toolArguments: args } : { toolArguments: args, toolResult: output, hasToolResult: true },
|
|
6040
7604
|
durationMs,
|
|
6041
7605
|
requestBytes: inputBytes,
|
|
6042
7606
|
responseBytes: outputBytes,
|
|
@@ -6100,12 +7664,14 @@ function createToolsNode(initialTools, opts) {
|
|
|
6100
7664
|
label: `Tool Error - ${toolName}`,
|
|
6101
7665
|
actor: { scope: "tool", name: toolName, role: "tool" },
|
|
6102
7666
|
status: "error",
|
|
7667
|
+
toolCallId: providerToolCallId(tc),
|
|
7668
|
+
capture: { toolArguments: args },
|
|
6103
7669
|
durationMs,
|
|
6104
7670
|
requestBytes: inputBytes,
|
|
6105
7671
|
responseBytes: traceSession?.resolvedConfig.logData ? estimatePayloadBytes(errorOutput) : void 0,
|
|
6106
7672
|
toolDetails,
|
|
6107
7673
|
toolExecutionId: executionId,
|
|
6108
|
-
error: { message, stack: host?.has("postToolUse") ? void 0 : error?.stack },
|
|
7674
|
+
error: { ...traceErrorOf(error), message, stack: host?.has("postToolUse") ? void 0 : error?.stack },
|
|
6109
7675
|
sections: buildToolTraceSections({
|
|
6110
7676
|
args: sanitizedArgs,
|
|
6111
7677
|
durationMs,
|
|
@@ -6220,6 +7786,8 @@ function createToolsNode(initialTools, opts) {
|
|
|
6220
7786
|
label: `Tool Skipped - ${tc.name}`,
|
|
6221
7787
|
actor: { scope: "tool", name: tc.name, role: "tool" },
|
|
6222
7788
|
status: "skipped",
|
|
7789
|
+
skipReason: "skipped",
|
|
7790
|
+
toolCallId: providerToolCallId(tc),
|
|
6223
7791
|
toolDetails,
|
|
6224
7792
|
toolExecutionId: tc.id,
|
|
6225
7793
|
sections: buildToolTraceSections({
|
|
@@ -6386,7 +7954,7 @@ function createReflectionNode(opts, resolved) {
|
|
|
6386
7954
|
label: "Reflection error",
|
|
6387
7955
|
actor: { scope: "agent", name: opts.name || "agent", role: "reflection" },
|
|
6388
7956
|
status: "error",
|
|
6389
|
-
error:
|
|
7957
|
+
error: traceErrorOf(err)
|
|
6390
7958
|
});
|
|
6391
7959
|
return {};
|
|
6392
7960
|
}
|
|
@@ -7397,7 +8965,7 @@ function buildSubagentCatalogBlock(subagents, policy, toolNames, opts) {
|
|
|
7397
8965
|
// src/plugins/host.ts
|
|
7398
8966
|
init_content();
|
|
7399
8967
|
var DEFAULT_PRIORITY = 100;
|
|
7400
|
-
var
|
|
8968
|
+
var DEFAULT_TIMEOUT_MS2 = 1e4;
|
|
7401
8969
|
var HOOK_SPECS = {
|
|
7402
8970
|
sessionStart: { kind: "gate", mutable: ["messages"], collect: ["systemPromptAppend"] },
|
|
7403
8971
|
userPromptSubmit: {
|
|
@@ -7502,7 +9070,7 @@ function collectRegistrations(plugin, registrations, into, orderRef) {
|
|
|
7502
9070
|
plugin: plugin.name,
|
|
7503
9071
|
priority: plugin.priority ?? DEFAULT_PRIORITY,
|
|
7504
9072
|
failureMode: plugin.failureMode ?? "open",
|
|
7505
|
-
timeoutMs: plugin.timeoutMs ??
|
|
9073
|
+
timeoutMs: plugin.timeoutMs ?? DEFAULT_TIMEOUT_MS2,
|
|
7506
9074
|
order: orderRef.value++,
|
|
7507
9075
|
handler
|
|
7508
9076
|
});
|
|
@@ -7557,6 +9125,7 @@ function createPluginHost(plugins = [], options = {}) {
|
|
|
7557
9125
|
let contributions = {
|
|
7558
9126
|
tools: [],
|
|
7559
9127
|
toolDescriptions: {},
|
|
9128
|
+
traceExporters: [],
|
|
7560
9129
|
guardrails: [],
|
|
7561
9130
|
applySystemPrompt: (base) => base,
|
|
7562
9131
|
applyModelWrappers: (model) => model
|
|
@@ -7565,6 +9134,7 @@ function createPluginHost(plugins = [], options = {}) {
|
|
|
7565
9134
|
async function runSetup(setupInput) {
|
|
7566
9135
|
const tools = [];
|
|
7567
9136
|
const toolDescriptions = {};
|
|
9137
|
+
const traceExporters = [];
|
|
7568
9138
|
const guardrails = [];
|
|
7569
9139
|
const promptSteps = [];
|
|
7570
9140
|
const modelWrappers = [];
|
|
@@ -7602,6 +9172,7 @@ function createPluginHost(plugins = [], options = {}) {
|
|
|
7602
9172
|
);
|
|
7603
9173
|
}
|
|
7604
9174
|
if (plugin.toolDescriptions) Object.assign(toolDescriptions, plugin.toolDescriptions);
|
|
9175
|
+
if (plugin.traceExporters?.length) traceExporters.push(...plugin.traceExporters.filter(Boolean));
|
|
7605
9176
|
if (plugin.guardrails?.length) guardrails.push(...plugin.guardrails);
|
|
7606
9177
|
if (typeof plugin.wrapModel === "function") {
|
|
7607
9178
|
modelWrappers.push({ plugin: plugin.name, wrap: plugin.wrapModel });
|
|
@@ -7617,6 +9188,7 @@ function createPluginHost(plugins = [], options = {}) {
|
|
|
7617
9188
|
contributions = {
|
|
7618
9189
|
tools,
|
|
7619
9190
|
toolDescriptions,
|
|
9191
|
+
traceExporters,
|
|
7620
9192
|
guardrails,
|
|
7621
9193
|
applySystemPrompt: (base) => promptSteps.reduce((current, step) => {
|
|
7622
9194
|
try {
|
|
@@ -8640,7 +10212,10 @@ function createAgent(opts) {
|
|
|
8640
10212
|
}
|
|
8641
10213
|
emit({ type: "progress", ...progress });
|
|
8642
10214
|
};
|
|
8643
|
-
const traceSession = createTraceSession(opts, readTraceContinuation(input.ctx?.__traceContinuation)
|
|
10215
|
+
const traceSession = createTraceSession(opts, readTraceContinuation(input.ctx?.__traceContinuation), {
|
|
10216
|
+
exporters: pluginHost.contributions.traceExporters,
|
|
10217
|
+
traceParent: config?.traceParent
|
|
10218
|
+
});
|
|
8644
10219
|
const ctx = {
|
|
8645
10220
|
...input.ctx || {},
|
|
8646
10221
|
__onEvent: onEvent,
|
|
@@ -8792,7 +10367,7 @@ function createAgent(opts) {
|
|
|
8792
10367
|
await finalizeTraceSession(traceSession, {
|
|
8793
10368
|
agentRuntime: runtime,
|
|
8794
10369
|
status: "error",
|
|
8795
|
-
error: { message: err?.message, stack: err?.stack }
|
|
10370
|
+
error: { message: err?.message, stack: err?.stack, name: err?.name }
|
|
8796
10371
|
});
|
|
8797
10372
|
await endSession("error", { error: err instanceof Error ? err : new Error(String(err)), state: stateHolder.value });
|
|
8798
10373
|
if (userTokenCounter) {
|
|
@@ -8813,7 +10388,10 @@ function createAgent(opts) {
|
|
|
8813
10388
|
const midTurn = pausedForHuman || Boolean(res.ctx?.__needsSummarization);
|
|
8814
10389
|
await finalizeTraceSession(traceSession, {
|
|
8815
10390
|
agentRuntime: res.agent || runtime,
|
|
8816
|
-
status: pausedForHuman ? "paused" : midTurn ? "in_progress" : "success"
|
|
10391
|
+
status: pausedForHuman ? "paused" : midTurn ? "in_progress" : "success",
|
|
10392
|
+
// The file says `success` for a cancelled run (it did not fail); the
|
|
10393
|
+
// exported root says `partial`, the old plugin mapping.
|
|
10394
|
+
cancelled: statusFor(res) === "cancelled"
|
|
8817
10395
|
});
|
|
8818
10396
|
if (traceSession && midTurn) {
|
|
8819
10397
|
res.ctx = { ...res.ctx || {}, __traceContinuation: traceContinuationOf(traceSession) };
|
|
@@ -8958,14 +10536,16 @@ function createAgent(opts) {
|
|
|
8958
10536
|
const startedAt = Date.now();
|
|
8959
10537
|
const recordSpan = (status, extra) => {
|
|
8960
10538
|
if (!traced || !isTraceSessionOpen(parentSession)) return;
|
|
10539
|
+
const running = status === "running";
|
|
8961
10540
|
recordSubagentSpan(parentSession, {
|
|
8962
10541
|
spanId: agentSpanId,
|
|
8963
|
-
|
|
10542
|
+
// The delegating tool_call span only exists once the tool returns.
|
|
10543
|
+
parentSpanId: running ? parentIterationSpanId : context?.traceSpanId ?? parentIterationSpanId,
|
|
8964
10544
|
name: opts.name || "agent",
|
|
8965
10545
|
status,
|
|
8966
|
-
durationMs: Date.now() - startedAt,
|
|
10546
|
+
durationMs: running ? void 0 : Date.now() - startedAt,
|
|
8967
10547
|
error: extra.error,
|
|
8968
|
-
info: { name: opts.name || "agent", mode: "asTool", depth: currentDepth + 1, parentToolCallId: context?.toolCallId, status: status === "success" ? "ok" : "error" },
|
|
10548
|
+
info: { name: opts.name || "agent", mode: "asTool", depth: currentDepth + 1, parentToolCallId: context?.toolCallId, status: running ? "running" : status === "success" ? "ok" : "error" },
|
|
8969
10549
|
task: input,
|
|
8970
10550
|
result: extra.result
|
|
8971
10551
|
});
|
|
@@ -8985,6 +10565,7 @@ function createAgent(opts) {
|
|
|
8985
10565
|
stream: Boolean(parentCtx.__streaming),
|
|
8986
10566
|
cancellationToken: parentCtx.__cancellationToken ?? parentCtx.__abortSignal
|
|
8987
10567
|
};
|
|
10568
|
+
recordSpan("running", {});
|
|
8988
10569
|
let res;
|
|
8989
10570
|
try {
|
|
8990
10571
|
res = await instance.invoke({ messages: childMessages, ctx: childCtx }, childConfig);
|
|
@@ -9069,9 +10650,10 @@ function createAgentNode(opts) {
|
|
|
9069
10650
|
durationMs: durationMs2,
|
|
9070
10651
|
requestBytes: promptBytes,
|
|
9071
10652
|
model: getModelName(runtime.model || opts.model),
|
|
9072
|
-
provider:
|
|
9073
|
-
error:
|
|
9074
|
-
messageList: promptMessages
|
|
10653
|
+
provider: providerHintOf(runtime.model || opts.model),
|
|
10654
|
+
error: traceErrorOf(err),
|
|
10655
|
+
messageList: promptMessages,
|
|
10656
|
+
capture: { input: promptMessages }
|
|
9075
10657
|
});
|
|
9076
10658
|
throw err;
|
|
9077
10659
|
}
|
|
@@ -9082,7 +10664,7 @@ function createAgentNode(opts) {
|
|
|
9082
10664
|
const rawUsage = response?.usage || response?.usage_metadata || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage || response?.response_metadata?.usage_metadata || response?.response_metadata?.usageMetadata;
|
|
9083
10665
|
const normalized = normalizeUsage(rawUsage);
|
|
9084
10666
|
const modelName = getModelName(runtime.model || opts.model) || "unknown_model";
|
|
9085
|
-
const
|
|
10667
|
+
const facts = traceResponseFacts(runtime.model || opts.model, response, rawUsage);
|
|
9086
10668
|
const durationMs = Date.now() - start;
|
|
9087
10669
|
const shouldLogResponse = !!traceSession && traceSession.resolvedConfig.logData;
|
|
9088
10670
|
const responsePayload = shouldLogResponse ? sanitizeTracePayload(response) : void 0;
|
|
@@ -9099,8 +10681,9 @@ function createAgentNode(opts) {
|
|
|
9099
10681
|
requestBytes: promptBytes,
|
|
9100
10682
|
responseBytes,
|
|
9101
10683
|
model: modelName,
|
|
9102
|
-
|
|
9103
|
-
messageList: messagesWithResponse
|
|
10684
|
+
...facts,
|
|
10685
|
+
messageList: messagesWithResponse,
|
|
10686
|
+
capture: { input: promptMessages, output: response }
|
|
9104
10687
|
});
|
|
9105
10688
|
if (normalized) {
|
|
9106
10689
|
recordUsage(state, modelName, normalized);
|
|
@@ -9751,7 +11334,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
9751
11334
|
];
|
|
9752
11335
|
const inputTokensEstimate = countApproxTokens(summaryPrompt.map((m) => m.content).join("\n"));
|
|
9753
11336
|
const modelName = getModelName(model);
|
|
9754
|
-
const providerName =
|
|
11337
|
+
const providerName = providerHintOf(model);
|
|
9755
11338
|
const tracingEnabled = Boolean(opts.tracing?.enabled);
|
|
9756
11339
|
let ctxWithDeferredTrace;
|
|
9757
11340
|
const traceSummarization = (event) => {
|
|
@@ -9782,6 +11365,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
9782
11365
|
let reasoningTokensActual;
|
|
9783
11366
|
let fallback = false;
|
|
9784
11367
|
let summarizerError;
|
|
11368
|
+
let responseFacts;
|
|
9785
11369
|
const directivesSection = () => ({
|
|
9786
11370
|
kind: "metadata",
|
|
9787
11371
|
label: "User directives",
|
|
@@ -9823,6 +11407,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
9823
11407
|
summaryText = renderStructuredSummary(structuredSummary);
|
|
9824
11408
|
const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
|
|
9825
11409
|
const normalized = normalizeUsage(rawUsage);
|
|
11410
|
+
responseFacts = traceResponseFacts(model, response, rawUsage);
|
|
9826
11411
|
if (normalized) {
|
|
9827
11412
|
inputTokensActual = normalized.prompt_tokens;
|
|
9828
11413
|
outputTokensActual = normalized.completion_tokens;
|
|
@@ -9859,7 +11444,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
9859
11444
|
...droppedDirectives.length > 0 ? { droppedDirectives } : {}
|
|
9860
11445
|
};
|
|
9861
11446
|
onEvent?.(errorEvent);
|
|
9862
|
-
summarizerError =
|
|
11447
|
+
summarizerError = traceErrorOf(err);
|
|
9863
11448
|
}
|
|
9864
11449
|
const toolCallIdToAssistantIdx = /* @__PURE__ */ new Map();
|
|
9865
11450
|
messages.forEach((m, idx) => {
|
|
@@ -10015,10 +11600,16 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
10015
11600
|
outputTokens: outputTokensActual ?? outputTokensEstimate,
|
|
10016
11601
|
cachedInputTokens,
|
|
10017
11602
|
totalTokens: totalTokensActual,
|
|
10018
|
-
...reasoningTokensActual !== void 0 ? { reasoningTokens: reasoningTokensActual } : {}
|
|
11603
|
+
...reasoningTokensActual !== void 0 ? { reasoningTokens: reasoningTokensActual } : {},
|
|
11604
|
+
// Which counting rules the usage above follows (only when the provider reported it).
|
|
11605
|
+
...inputTokensActual !== void 0 && responseFacts?.usageBasis ? { usageBasis: responseFacts.usageBasis } : {},
|
|
11606
|
+
...inputTokensActual !== void 0 && responseFacts?.cacheWriteTokens ? { cacheWriteTokens: responseFacts.cacheWriteTokens } : {}
|
|
10019
11607
|
},
|
|
11608
|
+
...responseFacts?.responseId ? { responseId: responseFacts.responseId } : {},
|
|
11609
|
+
...responseFacts?.responseModel ? { responseModel: responseFacts.responseModel } : {},
|
|
11610
|
+
...responseFacts?.rawFinishReason ? { rawFinishReason: responseFacts.rawFinishReason } : {},
|
|
10020
11611
|
...modelName ? { model: modelName } : {},
|
|
10021
|
-
...providerName ? { provider: providerName } : {},
|
|
11612
|
+
...responseFacts?.provider ?? providerName ? { provider: responseFacts?.provider ?? providerName } : {},
|
|
10022
11613
|
...summarizerError ? { error: summarizerError } : {},
|
|
10023
11614
|
sections: [
|
|
10024
11615
|
...promptAndOutputSections(),
|
|
@@ -11162,19 +12753,29 @@ async function runChild(spec, input, deps, ref, opts) {
|
|
|
11162
12753
|
const childDepth = (Number(parentCtx.__delegationDepth) || 0) + 1;
|
|
11163
12754
|
const parentSession = parentCtx.__traceSession;
|
|
11164
12755
|
const traced = isTraceSessionOpen(parentSession);
|
|
11165
|
-
const
|
|
12756
|
+
const sessionStart = traced ? parentSession.startedAt : void 0;
|
|
12757
|
+
const persistedId = opts.record?.agentSpanId;
|
|
12758
|
+
const agentSpanId = typeof persistedId === "string" && /^[0-9a-f]{16}$/.test(persistedId) ? persistedId : generateSpanId();
|
|
12759
|
+
const persistedStart = opts.record?.startedAt;
|
|
12760
|
+
const startValid = typeof persistedStart === "number" && Number.isFinite(persistedStart) && persistedStart > 0 && persistedStart <= start;
|
|
12761
|
+
const runStartedAt = startValid ? Math.min(start, Math.max(persistedStart, sessionStart ?? persistedStart)) : start;
|
|
12762
|
+
const persistedSegments = opts.record?.segments;
|
|
12763
|
+
const segment = (typeof persistedSegments === "number" && Number.isInteger(persistedSegments) && persistedSegments >= 1 && persistedSegments <= 1e3 ? persistedSegments : 0) + 1;
|
|
12764
|
+
const elapsedMs = () => Math.max(0, Date.now() - runStartedAt);
|
|
11166
12765
|
const parentIterationSpanId = traced ? parentSession.currentIterationSpanId : void 0;
|
|
11167
12766
|
const traceScope = traced ? createSubagentTraceScope(parentSession, { agentSpanId, name: spec.name, spawnId, mode: spec.mode, hitl: opts.allowHITL, iterations: opts.record?.iterations }) : void 0;
|
|
11168
12767
|
const recordSegment = (status, info) => {
|
|
11169
12768
|
if (!traced || !isTraceSessionOpen(parentSession)) return;
|
|
12769
|
+
const unfinished = status === "pending" || status === "running";
|
|
11170
12770
|
recordSubagentSpan(parentSession, {
|
|
11171
12771
|
spanId: agentSpanId,
|
|
11172
|
-
// The tool_call span only exists once the tool returns; a
|
|
11173
|
-
// has not returned, so its span hangs off the iteration.
|
|
11174
|
-
parentSpanId:
|
|
12772
|
+
// The tool_call span only exists once the tool returns; a running or
|
|
12773
|
+
// paused child has not returned, so its span hangs off the iteration.
|
|
12774
|
+
parentSpanId: unfinished ? parentIterationSpanId : opts.parentSpanId ?? parentIterationSpanId,
|
|
11175
12775
|
name: spec.name,
|
|
11176
12776
|
status,
|
|
11177
|
-
|
|
12777
|
+
// A starting segment has no extent yet; a reader draws it over its children.
|
|
12778
|
+
durationMs: status === "running" ? void 0 : elapsedMs(),
|
|
11178
12779
|
error: info.error,
|
|
11179
12780
|
info: {
|
|
11180
12781
|
id: spawnId,
|
|
@@ -11184,6 +12785,8 @@ async function runChild(spec, input, deps, ref, opts) {
|
|
|
11184
12785
|
depth: childDepth,
|
|
11185
12786
|
parentToolCallId: opts.parentToolCallId,
|
|
11186
12787
|
status: info.subagentStatus,
|
|
12788
|
+
// Only a run that paused has more than one segment to tell about.
|
|
12789
|
+
...segment > 1 || unfinished ? { segments: segment } : {},
|
|
11187
12790
|
...info.note ? { note: info.note } : {},
|
|
11188
12791
|
...spec.metadata ? { metadata: spec.metadata } : {}
|
|
11189
12792
|
},
|
|
@@ -11307,6 +12910,7 @@ async function runChild(spec, input, deps, ref, opts) {
|
|
|
11307
12910
|
}
|
|
11308
12911
|
if (traceScope) childInput = { ...childInput, ctx: { ...childInput.ctx || {}, __traceSession: traceScope } };
|
|
11309
12912
|
const usageBaseline = childInput.usage?.perRequest?.length ?? 0;
|
|
12913
|
+
recordSegment("running", { subagentStatus: "running", input });
|
|
11310
12914
|
let res;
|
|
11311
12915
|
try {
|
|
11312
12916
|
res = await child.invoke(childInput, childConfig);
|
|
@@ -11348,7 +12952,10 @@ async function runChild(spec, input, deps, ref, opts) {
|
|
|
11348
12952
|
pendingKind: "approval",
|
|
11349
12953
|
pendingId: childEntry.id,
|
|
11350
12954
|
spawnId,
|
|
11351
|
-
iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0
|
|
12955
|
+
iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0,
|
|
12956
|
+
agentSpanId,
|
|
12957
|
+
startedAt: runStartedAt,
|
|
12958
|
+
segments: segment
|
|
11352
12959
|
};
|
|
11353
12960
|
recordSegment("pending", { subagentStatus: "paused", input });
|
|
11354
12961
|
parentOnEvent?.({ type: "subagent", phase: "paused", name: spec.name, id: spawnId, mode: spec.mode, parentToolCallId: opts.parentToolCallId });
|
|
@@ -11374,7 +12981,10 @@ async function runChild(spec, input, deps, ref, opts) {
|
|
|
11374
12981
|
pendingKind: "user_question",
|
|
11375
12982
|
pendingId: childEntry.id,
|
|
11376
12983
|
spawnId,
|
|
11377
|
-
iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0
|
|
12984
|
+
iterations: traceScope ? subagentTraceScopeOf(traceScope)?.iterations : void 0,
|
|
12985
|
+
agentSpanId,
|
|
12986
|
+
startedAt: runStartedAt,
|
|
12987
|
+
segments: segment
|
|
11378
12988
|
};
|
|
11379
12989
|
recordSegment("pending", { subagentStatus: "paused", input });
|
|
11380
12990
|
parentOnEvent?.({ type: "subagent", phase: "paused", name: spec.name, id: spawnId, mode: spec.mode, parentToolCallId: opts.parentToolCallId });
|
|
@@ -12061,6 +13671,30 @@ ${pluginAppend}`;
|
|
|
12061
13671
|
};
|
|
12062
13672
|
}
|
|
12063
13673
|
}
|
|
13674
|
+
const traceHandoff = {};
|
|
13675
|
+
const noteTraceHandoff = (current) => {
|
|
13676
|
+
traceHandoff.continuation = current.ctx?.__traceContinuation;
|
|
13677
|
+
traceHandoff.events = current.ctx?.[DEFERRED_TRACE_EVENTS_KEY];
|
|
13678
|
+
};
|
|
13679
|
+
const closeDanglingTrace = async (status, error) => {
|
|
13680
|
+
const continuation = traceHandoff.continuation;
|
|
13681
|
+
const events = traceHandoff.events;
|
|
13682
|
+
traceHandoff.continuation = void 0;
|
|
13683
|
+
traceHandoff.events = void 0;
|
|
13684
|
+
if (!continuation) return;
|
|
13685
|
+
try {
|
|
13686
|
+
await closeTraceContinuation(continuation, {
|
|
13687
|
+
tracing: opts.tracing,
|
|
13688
|
+
exporters: pluginHost?.contributions.traceExporters,
|
|
13689
|
+
status,
|
|
13690
|
+
error,
|
|
13691
|
+
agentRuntime: base.__runtime,
|
|
13692
|
+
events
|
|
13693
|
+
});
|
|
13694
|
+
} catch (closeError) {
|
|
13695
|
+
console.warn("[agent-sdk] closing the trace failed:", closeError);
|
|
13696
|
+
}
|
|
13697
|
+
};
|
|
12064
13698
|
try {
|
|
12065
13699
|
const toolSet = buildInvokeToolSet();
|
|
12066
13700
|
const stateRef = toolSet.stateRef;
|
|
@@ -12139,11 +13773,15 @@ ${pluginAppend}`;
|
|
|
12139
13773
|
const result = await trySummarize(state, rawMessages, stateRef);
|
|
12140
13774
|
state = result.state;
|
|
12141
13775
|
rawMessages = result.rawMessages;
|
|
13776
|
+
noteTraceHandoff(state);
|
|
12142
13777
|
if (result.compressed) continue;
|
|
12143
13778
|
}
|
|
12144
13779
|
const modelMessages = buildModelMessages(state, resolved);
|
|
13780
|
+
traceHandoff.continuation = void 0;
|
|
13781
|
+
traceHandoff.events = void 0;
|
|
12145
13782
|
const res = await base.invoke({ ...state, messages: modelMessages }, turnConfig);
|
|
12146
13783
|
lastResult = res;
|
|
13784
|
+
noteTraceHandoff(res.state ?? state);
|
|
12147
13785
|
const currentSummaries = state.summaries;
|
|
12148
13786
|
const currentSummaryRecords = state.summaryRecords;
|
|
12149
13787
|
const currentPlan = state.plan;
|
|
@@ -12170,6 +13808,7 @@ ${pluginAppend}`;
|
|
|
12170
13808
|
const result = await trySummarize(state, rawMessages, stateRef);
|
|
12171
13809
|
state = result.state;
|
|
12172
13810
|
rawMessages = result.rawMessages;
|
|
13811
|
+
noteTraceHandoff(state);
|
|
12173
13812
|
continue;
|
|
12174
13813
|
}
|
|
12175
13814
|
if (state.ctx?.__finalizedDueToStructuredOutput) break;
|
|
@@ -12181,6 +13820,7 @@ ${pluginAppend}`;
|
|
|
12181
13820
|
const result = await trySummarize(state, rawMessages, stateRef);
|
|
12182
13821
|
state = result.state;
|
|
12183
13822
|
rawMessages = result.rawMessages;
|
|
13823
|
+
noteTraceHandoff(state);
|
|
12184
13824
|
if (result.compressed) continue;
|
|
12185
13825
|
}
|
|
12186
13826
|
}
|
|
@@ -12191,6 +13831,7 @@ ${pluginAppend}`;
|
|
|
12191
13831
|
lastResult = res;
|
|
12192
13832
|
}
|
|
12193
13833
|
if (state.ctx?.[DEFERRED_TRACE_EVENTS_KEY]) {
|
|
13834
|
+
traceHandoff.events = state.ctx[DEFERRED_TRACE_EVENTS_KEY];
|
|
12194
13835
|
const ctx = { ...state.ctx || {} };
|
|
12195
13836
|
delete ctx[DEFERRED_TRACE_EVENTS_KEY];
|
|
12196
13837
|
state = { ...state, ctx };
|
|
@@ -12210,8 +13851,12 @@ ${pluginAppend}`;
|
|
|
12210
13851
|
const strippedCtx = { ...endCtx };
|
|
12211
13852
|
delete strippedCtx.__traceContinuation;
|
|
12212
13853
|
lastResult = { ...lastResult, state: { ...lastResult.state, ctx: strippedCtx } };
|
|
13854
|
+
traceHandoff.continuation = endCtx.__traceContinuation;
|
|
13855
|
+
await closeDanglingTrace("success");
|
|
12213
13856
|
}
|
|
12214
13857
|
}
|
|
13858
|
+
traceHandoff.continuation = void 0;
|
|
13859
|
+
traceHandoff.events = void 0;
|
|
12215
13860
|
if (skillsEnabled && lastResult.state) {
|
|
12216
13861
|
const persisted = skillStateFromRegistry(toolSet.skillRegistryRef);
|
|
12217
13862
|
if (persisted) {
|
|
@@ -12257,6 +13902,11 @@ ${pluginAppend}`;
|
|
|
12257
13902
|
await endSession(endStatus, { result: lastResult });
|
|
12258
13903
|
return lastResult;
|
|
12259
13904
|
} catch (err) {
|
|
13905
|
+
await closeDanglingTrace("error", {
|
|
13906
|
+
message: err instanceof Error ? err.message : String(err),
|
|
13907
|
+
stack: err instanceof Error ? err.stack : void 0,
|
|
13908
|
+
name: err instanceof Error ? err.name : void 0
|
|
13909
|
+
});
|
|
12260
13910
|
await endSession("error", { error: err instanceof Error ? err : new Error(String(err)) });
|
|
12261
13911
|
throw err;
|
|
12262
13912
|
}
|
|
@@ -13173,7 +14823,7 @@ function isHookImplemented(hook) {
|
|
|
13173
14823
|
// src/plugins/builtin/guardrail.ts
|
|
13174
14824
|
init_content();
|
|
13175
14825
|
var ALLOW = { action: "allow" };
|
|
13176
|
-
var
|
|
14826
|
+
var RETRYABLE_STATUS2 = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
13177
14827
|
var RetryableGuardrailError = class extends Error {
|
|
13178
14828
|
constructor(message) {
|
|
13179
14829
|
super(message);
|
|
@@ -13271,7 +14921,7 @@ function httpGuardrail(options) {
|
|
|
13271
14921
|
} catch {
|
|
13272
14922
|
}
|
|
13273
14923
|
const message = `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ""}${text ? ` - ${text.slice(0, 200)}` : ""}`;
|
|
13274
|
-
if (
|
|
14924
|
+
if (RETRYABLE_STATUS2.has(response.status)) throw new RetryableGuardrailError(message);
|
|
13275
14925
|
throw new Error(message);
|
|
13276
14926
|
}
|
|
13277
14927
|
return response.json();
|
|
@@ -13378,9 +15028,9 @@ function createGuardrailPlugin(options) {
|
|
|
13378
15028
|
});
|
|
13379
15029
|
const resolved = verdict ?? ALLOW;
|
|
13380
15030
|
if (resolved.raw?.disabled === true) {
|
|
13381
|
-
const
|
|
13382
|
-
if (!
|
|
13383
|
-
|
|
15031
|
+
const warned2 = (_b = ctx.store).__disabledWarned ?? (_b.__disabledWarned = /* @__PURE__ */ new Set());
|
|
15032
|
+
if (!warned2.has(request.phase)) {
|
|
15033
|
+
warned2.add(request.phase);
|
|
13384
15034
|
ctx.logger.warn(
|
|
13385
15035
|
`guardrail reports it is not active for the "${request.phase}" surface; nothing is being enforced there`
|
|
13386
15036
|
);
|
|
@@ -13877,7 +15527,7 @@ function safeJson(value) {
|
|
|
13877
15527
|
function matches(pattern, toolName) {
|
|
13878
15528
|
return typeof pattern === "string" ? pattern === toolName : pattern.test(toolName);
|
|
13879
15529
|
}
|
|
13880
|
-
function
|
|
15530
|
+
function asObject2(args) {
|
|
13881
15531
|
return args && typeof args === "object" ? args : {};
|
|
13882
15532
|
}
|
|
13883
15533
|
function toolPolicy(config = {}) {
|
|
@@ -13898,7 +15548,7 @@ function toolPolicy(config = {}) {
|
|
|
13898
15548
|
hooks: {
|
|
13899
15549
|
preToolUse: ({ toolName, args }, ctx) => {
|
|
13900
15550
|
var _a;
|
|
13901
|
-
const argObject =
|
|
15551
|
+
const argObject = asObject2(args);
|
|
13902
15552
|
const isControlPlane = CONTROL_PLANE_TOOL_NAMES.includes(toolName);
|
|
13903
15553
|
const allowListApplies = !isControlPlane || config.governControlPlaneTools === true;
|
|
13904
15554
|
if (config.allowOnly && allowListApplies && !config.allowOnly.some((pattern) => matches(pattern, toolName))) {
|
|
@@ -13960,7 +15610,7 @@ function pathSandbox(config) {
|
|
|
13960
15610
|
hooks: {
|
|
13961
15611
|
preToolUse: ({ toolName, args }) => {
|
|
13962
15612
|
if (config.tools && !config.tools.some((pattern) => matches(pattern, toolName))) return void 0;
|
|
13963
|
-
const argObject =
|
|
15613
|
+
const argObject = asObject2(args);
|
|
13964
15614
|
for (const key of argNames) {
|
|
13965
15615
|
const value = argObject[key];
|
|
13966
15616
|
if (typeof value !== "string" || value.length === 0) continue;
|
|
@@ -14728,7 +16378,7 @@ function mcp(config) {
|
|
|
14728
16378
|
}
|
|
14729
16379
|
|
|
14730
16380
|
// src/plugins/builtin/rateLimit.ts
|
|
14731
|
-
function
|
|
16381
|
+
function sleep2(ms, signal) {
|
|
14732
16382
|
return new Promise((resolve) => {
|
|
14733
16383
|
let timer;
|
|
14734
16384
|
const done = () => {
|
|
@@ -14785,7 +16435,7 @@ function rateLimit(config = {}) {
|
|
|
14785
16435
|
while (!attempt.ok) {
|
|
14786
16436
|
const remaining = deadline - Date.now();
|
|
14787
16437
|
if (!Number.isFinite(attempt.waitMs) || attempt.waitMs > remaining) break;
|
|
14788
|
-
await
|
|
16438
|
+
await sleep2(Math.max(1, attempt.waitMs), ctx.signal);
|
|
14789
16439
|
if (ctx.signal?.aborted) break;
|
|
14790
16440
|
attempt = consume(applicable);
|
|
14791
16441
|
}
|
|
@@ -15881,18 +17531,21 @@ function langfuseTracing(config = {}) {
|
|
|
15881
17531
|
}
|
|
15882
17532
|
|
|
15883
17533
|
// src/plugins/builtin/otel.ts
|
|
15884
|
-
function
|
|
15885
|
-
if (
|
|
15886
|
-
if (status === "error") return "error";
|
|
15887
|
-
return status === "paused" ? "in_progress" : "partial";
|
|
15888
|
-
}
|
|
15889
|
-
function otelTracing(config) {
|
|
15890
|
-
const endpoint = config.endpoint?.trim();
|
|
15891
|
-
if (!endpoint) {
|
|
17534
|
+
function otelTracing(config = {}) {
|
|
17535
|
+
if (config.endpoint !== void 0 && !config.endpoint.trim()) {
|
|
15892
17536
|
throw new Error("[agent-sdk] otelTracing requires a non-empty `endpoint`.");
|
|
15893
17537
|
}
|
|
17538
|
+
const name = config.name ?? "otel-tracing";
|
|
17539
|
+
let exporter;
|
|
17540
|
+
try {
|
|
17541
|
+
exporter = createOtlpExporter({ ...config, endpoint: config.endpoint?.trim(), name });
|
|
17542
|
+
} catch {
|
|
17543
|
+
throw new Error(
|
|
17544
|
+
"[agent-sdk] otelTracing requires a non-empty `endpoint` (or OTEL_EXPORTER_OTLP_ENDPOINT / OTEL_EXPORTER_OTLP_TRACES_ENDPOINT in the environment)."
|
|
17545
|
+
);
|
|
17546
|
+
}
|
|
15894
17547
|
return {
|
|
15895
|
-
name
|
|
17548
|
+
name,
|
|
15896
17549
|
// Registers only the `sessionEnd` observer, and observers run concurrently,
|
|
15897
17550
|
// so this number orders nothing at runtime. It is set above checkpointing
|
|
15898
17551
|
// (900) to record intent: this plugin is the last thing interested in the
|
|
@@ -15900,8 +17553,9 @@ function otelTracing(config) {
|
|
|
15900
17553
|
priority: 950,
|
|
15901
17554
|
// Observability. A dropped export is a reporting gap, never a safety hole.
|
|
15902
17555
|
failureMode: "open",
|
|
17556
|
+
traceExporters: [exporter],
|
|
15903
17557
|
hooks: {
|
|
15904
|
-
sessionEnd: async (
|
|
17558
|
+
sessionEnd: async (_event, ctx) => {
|
|
15905
17559
|
const state = ctx.state;
|
|
15906
17560
|
const session = state.ctx?.__traceSession;
|
|
15907
17561
|
if (isSubagentTraceScope(session)) return;
|
|
@@ -15911,57 +17565,29 @@ function otelTracing(config) {
|
|
|
15911
17565
|
ctx.emit({ type: "metadata", otelTracing: { exported: false, reason: message } });
|
|
15912
17566
|
return;
|
|
15913
17567
|
}
|
|
15914
|
-
const
|
|
15915
|
-
const
|
|
15916
|
-
|
|
15917
|
-
const
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
|
|
15922
|
-
|
|
15923
|
-
|
|
15924
|
-
|
|
15925
|
-
// `service.name` is read off `agent.name` inside the conversion, so
|
|
15926
|
-
// the override is applied here rather than by editing spans after.
|
|
15927
|
-
agent: {
|
|
15928
|
-
...session.agentInfo ?? {},
|
|
15929
|
-
name: config.serviceName ?? session.agentInfo?.name ?? session.configAgentName ?? ctx.agentName
|
|
15930
|
-
},
|
|
15931
|
-
metadata: session.configMetadata,
|
|
15932
|
-
// Carried only to satisfy the type: `traceSessionToOtlp` reads the
|
|
15933
|
-
// events, summary and identifiers, never the sink snapshot.
|
|
15934
|
-
config: { enabled: true, logData: session.resolvedConfig.logData, sink: { type: "otlp", endpoint } },
|
|
15935
|
-
summary: session.summary,
|
|
15936
|
-
events: session.events,
|
|
15937
|
-
status: toSessionStatus(status),
|
|
15938
|
-
errors
|
|
15939
|
-
};
|
|
15940
|
-
try {
|
|
15941
|
-
const fetchFn = typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0;
|
|
15942
|
-
if (!fetchFn) {
|
|
15943
|
-
ctx.logger.warn("otelTracing needs fetch to be available in this runtime; export skipped.");
|
|
15944
|
-
return;
|
|
15945
|
-
}
|
|
15946
|
-
const response = await fetchFn(endpoint, {
|
|
15947
|
-
method: "POST",
|
|
15948
|
-
headers: { "content-type": "application/json", ...config.headers ?? {} },
|
|
15949
|
-
body: JSON.stringify(traceSessionToOtlp(payload)),
|
|
15950
|
-
// The run is over, but a host that cancelled it should not be made
|
|
15951
|
-
// to wait on a collector that is refusing to answer.
|
|
15952
|
-
signal: ctx.signal
|
|
15953
|
-
});
|
|
15954
|
-
if (!response.ok) {
|
|
15955
|
-
ctx.logger.warn(`otelTracing export returned HTTP ${response.status}.`);
|
|
15956
|
-
return;
|
|
15957
|
-
}
|
|
15958
|
-
ctx.emit({
|
|
15959
|
-
type: "metadata",
|
|
15960
|
-
otelTracing: { exported: true, endpoint, spans: session.events.length + 1 }
|
|
15961
|
-
});
|
|
15962
|
-
} catch (err) {
|
|
15963
|
-
ctx.logger.warn("otelTracing export failed:", err instanceof Error ? err.message : err);
|
|
17568
|
+
const reports = (session.exportReports ?? []).filter((report2) => !report2.sink && report2.exporter === name);
|
|
17569
|
+
const report = reports[reports.length - 1];
|
|
17570
|
+
if (!report) return;
|
|
17571
|
+
const { result } = report;
|
|
17572
|
+
if (!result.ok) {
|
|
17573
|
+
ctx.logger.warn(`otelTracing export failed: ${result.error ?? "unknown error"}`);
|
|
17574
|
+
return;
|
|
17575
|
+
}
|
|
17576
|
+
if (result.skipped) {
|
|
17577
|
+
ctx.emit({ type: "metadata", otelTracing: { exported: false, reason: result.reason ?? "nothing to export" } });
|
|
17578
|
+
return;
|
|
15964
17579
|
}
|
|
17580
|
+
ctx.emit({
|
|
17581
|
+
type: "metadata",
|
|
17582
|
+
otelTracing: {
|
|
17583
|
+
exported: true,
|
|
17584
|
+
endpoint: report.endpoint,
|
|
17585
|
+
spans: result.spans,
|
|
17586
|
+
terminal: report.terminal,
|
|
17587
|
+
// A 200 that refused some spans: the collector's count and message.
|
|
17588
|
+
...result.partialSuccess ? { rejectedSpans: result.partialSuccess.rejectedSpans, ...result.partialSuccess.message ? { rejectionMessage: result.partialSuccess.message } : {} } : {}
|
|
17589
|
+
}
|
|
17590
|
+
});
|
|
15965
17591
|
}
|
|
15966
17592
|
}
|
|
15967
17593
|
};
|
|
@@ -18997,9 +20623,9 @@ function mapAnthropicStopReason(reason) {
|
|
|
18997
20623
|
return "stop";
|
|
18998
20624
|
}
|
|
18999
20625
|
}
|
|
19000
|
-
function safeJsonParse(
|
|
20626
|
+
function safeJsonParse(str2) {
|
|
19001
20627
|
try {
|
|
19002
|
-
return JSON.parse(
|
|
20628
|
+
return JSON.parse(str2);
|
|
19003
20629
|
} catch {
|
|
19004
20630
|
return {};
|
|
19005
20631
|
}
|
|
@@ -19869,9 +21495,9 @@ function mediaTypeToFormat(mediaType) {
|
|
|
19869
21495
|
};
|
|
19870
21496
|
return map[mediaType] ?? "png";
|
|
19871
21497
|
}
|
|
19872
|
-
function safeJsonParse2(
|
|
21498
|
+
function safeJsonParse2(str2) {
|
|
19873
21499
|
try {
|
|
19874
|
-
return JSON.parse(
|
|
21500
|
+
return JSON.parse(str2);
|
|
19875
21501
|
} catch {
|
|
19876
21502
|
return {};
|
|
19877
21503
|
}
|
|
@@ -20268,10 +21894,13 @@ var VertexProvider = class extends BaseProvider {
|
|
|
20268
21894
|
textParts.push(part.text);
|
|
20269
21895
|
}
|
|
20270
21896
|
} else if (part.functionCall) {
|
|
21897
|
+
const suppliedId = typeof part.functionCall.id === "string" && part.functionCall.id ? part.functionCall.id : void 0;
|
|
21898
|
+
const position = toolCallIdx++;
|
|
20271
21899
|
toolCalls.push({
|
|
20272
|
-
id: `call_${
|
|
21900
|
+
id: suppliedId ?? `call_${position}`,
|
|
20273
21901
|
name: part.functionCall.name,
|
|
20274
21902
|
arguments: JSON.stringify(part.functionCall.args ?? {}),
|
|
21903
|
+
...suppliedId ? {} : { idSynthesized: true },
|
|
20275
21904
|
...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
|
|
20276
21905
|
});
|
|
20277
21906
|
}
|
|
@@ -20311,12 +21940,15 @@ var VertexProvider = class extends BaseProvider {
|
|
|
20311
21940
|
}
|
|
20312
21941
|
} else if (part.functionCall) {
|
|
20313
21942
|
if (!delta.toolCalls) delta.toolCalls = [];
|
|
21943
|
+
const suppliedId = typeof part.functionCall.id === "string" && part.functionCall.id ? part.functionCall.id : void 0;
|
|
21944
|
+
const position = counter.next++;
|
|
20314
21945
|
delta.toolCalls.push({
|
|
20315
21946
|
// Unique across the whole stream: the adapter merges chunks by id.
|
|
20316
|
-
id: `call_${
|
|
20317
|
-
index:
|
|
21947
|
+
id: suppliedId ?? `call_${position}`,
|
|
21948
|
+
index: position,
|
|
20318
21949
|
name: part.functionCall.name,
|
|
20319
21950
|
arguments: JSON.stringify(part.functionCall.args ?? {}),
|
|
21951
|
+
...suppliedId ? {} : { idSynthesized: true },
|
|
20320
21952
|
...part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}
|
|
20321
21953
|
});
|
|
20322
21954
|
}
|
|
@@ -20369,12 +22001,12 @@ function mapGeminiFinishReason(reason) {
|
|
|
20369
22001
|
return "stop";
|
|
20370
22002
|
}
|
|
20371
22003
|
}
|
|
20372
|
-
function base64url(
|
|
20373
|
-
return Buffer.from(
|
|
22004
|
+
function base64url(str2) {
|
|
22005
|
+
return Buffer.from(str2).toString("base64url");
|
|
20374
22006
|
}
|
|
20375
|
-
function safeJsonParse3(
|
|
22007
|
+
function safeJsonParse3(str2) {
|
|
20376
22008
|
try {
|
|
20377
|
-
return JSON.parse(
|
|
22009
|
+
return JSON.parse(str2);
|
|
20378
22010
|
} catch {
|
|
20379
22011
|
return {};
|
|
20380
22012
|
}
|
|
@@ -20402,6 +22034,6 @@ function createProvider(config) {
|
|
|
20402
22034
|
}
|
|
20403
22035
|
}
|
|
20404
22036
|
|
|
20405
|
-
export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, GuardrailPhase, HOOK_CONTRACT_VERSION, HOOK_NAMES, HookTimeoutError, InMemoryMemoryStore, JevProvider, LAST_SUMMARIZATION_CALL_KEY, MAX_ADJUSTMENTS, MODEL_RULES, ModelRequestError, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, PREOPEN_TOOL_CALL_PREFIX, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, allowsSampling, appendBoundTools, applyDropParams, asModelRequestError, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, clearLearnedModelRules, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentPartToText, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, describeContentPart, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, effortBudget, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText, fileCheckpointStore, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getLearnedModelRulePatch, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasMediaPart, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isOpenAIHostedEndpoint, isSmartModel, isTraceSessionOpen, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, listLearnedModelRules, loadSkillsFromDisk, mapConsoleHookVerdict, mapReasoningEffort, mapTextParts, mcp, mediaKindOf, mediaPolicy, mergeRulePatch, modelIdCandidates, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseModelError, parseSkillFrontmatter, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, prepareStrictToolMenu, promptInjectionGuard, rateLimit, readMemoryFacts, readTraceContinuation, recordOrDeferTraceEvent, redactText, regexGuardrail, regexRule, rememberModelRulePatch, replaceTextContent, replayDeferredTraceEvents, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveModelRule, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, restoreToolCalls, runSmartAgentEvalHarness, runWithModelAdjustments, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, supportsAdaptiveThinking, textFromContent, toMessageUsage, toModelResult, toStrictCompatible, toStrictToolSchema, tokenize, toolPolicy, traceContinuationOf, traceSectionsFromMessages, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
|
|
22037
|
+
export { ASK_USER_TOOL_NAME, AnthropicProvider, AzureProvider, BaseProvider, BedrockProvider, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, GENAI_SEMCONV_COMMIT, GuardrailPhase, HOOK_CONTRACT_VERSION, HOOK_NAMES, HookTimeoutError, InMemoryMemoryStore, JevProvider, LAST_SUMMARIZATION_CALL_KEY, MAX_ADJUSTMENTS, MODEL_RULES, ModelRequestError, NativeJsonSchemaStrategy, OpenAICompatibleProvider, OpenAIProvider, PREOPEN_TOOL_CALL_PREFIX, ProviderError, SMALL_TIER_SKILL_POLICY, StructuredOutputManager, TOOL_INPUT_DIGEST_KEY, ToolBasedStrategy, VertexProvider, agentVerdictRule, allowsSampling, appendBoundTools, applyDropParams, asModelRequestError, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, clearLearnedModelRules, closeTraceContinuation, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentPartToText, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createOtlpExporter, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, describeContentPart, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, effortBudget, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText, fileCheckpointStore, fileSink, findSubagent, foldSupersededSpans, formatTraceparent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getLearnedModelRulePatch, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasMediaPart, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isOpenAIHostedEndpoint, isSmartModel, isTraceSessionOpen, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, listLearnedModelRules, loadSkillsFromDisk, mapConsoleHookVerdict, mapReasoningEffort, mapTextParts, mcp, mediaKindOf, mediaPolicy, mergeRulePatch, modelIdCandidates, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseModelError, parseSkillFrontmatter, parseTraceparent, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, prepareStrictToolMenu, promptInjectionGuard, rateLimit, readMemoryFacts, readTraceContinuation, recordOrDeferTraceEvent, redactText, regexGuardrail, regexRule, rememberModelRulePatch, replaceTextContent, replayDeferredTraceEvents, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveModelRule, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, restoreToolCalls, runSmartAgentEvalHarness, runWithModelAdjustments, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, supportsAdaptiveThinking, textFromContent, toMessageUsage, toModelResult, toStrictCompatible, toStrictToolSchema, tokenize, toolPolicy, traceContinuationOf, traceSectionsFromMessages, traceSessionToOtlp, traceparentOf, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };
|
|
20406
22038
|
//# sourceMappingURL=index.mjs.map
|
|
20407
22039
|
//# sourceMappingURL=index.mjs.map
|