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