@cognipeer/agent-sdk 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +143 -178
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -16
- package/dist/index.d.ts +20 -16
- package/dist/index.mjs +143 -179
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -192,7 +192,9 @@ function fromLangchainModel(lcModel) {
|
|
|
192
192
|
stream: async function* (messages, options) {
|
|
193
193
|
if (typeof lcModel.stream !== "function") return;
|
|
194
194
|
const lcMessages = messages.map(toLC);
|
|
195
|
-
|
|
195
|
+
const streamResult = lcModel.stream(lcMessages, options);
|
|
196
|
+
const stream = typeof streamResult?.then === "function" ? await streamResult : streamResult;
|
|
197
|
+
for await (const chunk of stream) {
|
|
196
198
|
yield chunk;
|
|
197
199
|
}
|
|
198
200
|
},
|
|
@@ -314,17 +316,17 @@ function normalizeUsage(raw) {
|
|
|
314
316
|
raw.totalTokens,
|
|
315
317
|
(typeof prompt === "number" ? prompt : 0) + (typeof completion === "number" ? completion : 0)
|
|
316
318
|
);
|
|
317
|
-
const promptDetailsSrc = raw.prompt_tokens_details || raw.promptTokensDetails || {};
|
|
318
|
-
const completionDetailsSrc = raw.completion_tokens_details || raw.completionTokensDetails || {};
|
|
319
|
+
const promptDetailsSrc = raw.prompt_tokens_details || raw.promptTokensDetails || raw.input_token_details || raw.inputTokenDetails || {};
|
|
320
|
+
const completionDetailsSrc = raw.completion_tokens_details || raw.completionTokensDetails || raw.output_token_details || raw.outputTokenDetails || {};
|
|
319
321
|
const normalized = {
|
|
320
322
|
prompt_tokens: safe(prompt),
|
|
321
323
|
completion_tokens: safe(completion),
|
|
322
324
|
total_tokens: safe(total || (prompt || 0) + (completion || 0)),
|
|
323
325
|
prompt_tokens_details: {
|
|
324
326
|
cached_tokens: safe(
|
|
325
|
-
promptDetailsSrc.cached_tokens || promptDetailsSrc.cached || raw.cached_input_tokens || raw.cached_prompt_tokens
|
|
327
|
+
promptDetailsSrc.cached_tokens || promptDetailsSrc.cached || promptDetailsSrc.cache_read || raw.cached_input_tokens || raw.cached_prompt_tokens || raw.cache_read_input_tokens
|
|
326
328
|
),
|
|
327
|
-
audio_tokens: safe(promptDetailsSrc.audio_tokens)
|
|
329
|
+
audio_tokens: safe(promptDetailsSrc.audio_tokens || promptDetailsSrc.audio)
|
|
328
330
|
},
|
|
329
331
|
completion_tokens_details: {
|
|
330
332
|
reasoning_tokens: safe(completionDetailsSrc.reasoning_tokens),
|
|
@@ -645,7 +647,7 @@ async function postStreamingSessionStart(baseUrl, headers, payload) {
|
|
|
645
647
|
if (!fetchFn) {
|
|
646
648
|
throw new Error("HTTP sink requires fetch to be available in this runtime.");
|
|
647
649
|
}
|
|
648
|
-
const url = `${baseUrl.replace(/\/$/, "")}/${payload.sessionId}/start`;
|
|
650
|
+
const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/start`;
|
|
649
651
|
const finalHeaders = { ...headers || {} };
|
|
650
652
|
if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
|
|
651
653
|
finalHeaders["content-type"] = "application/json";
|
|
@@ -679,7 +681,7 @@ async function postStreamingEvent(baseUrl, headers, sessionId, event) {
|
|
|
679
681
|
if (!fetchFn) {
|
|
680
682
|
throw new Error("HTTP sink requires fetch to be available in this runtime.");
|
|
681
683
|
}
|
|
682
|
-
const url = `${baseUrl.replace(/\/$/, "")}/${sessionId}/events`;
|
|
684
|
+
const url = `${baseUrl.replace(/\/$/, "")}/stream/${sessionId}/events`;
|
|
683
685
|
const finalHeaders = { ...headers || {} };
|
|
684
686
|
if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
|
|
685
687
|
finalHeaders["content-type"] = "application/json";
|
|
@@ -713,7 +715,7 @@ async function postStreamingSessionEnd(baseUrl, headers, payload) {
|
|
|
713
715
|
if (!fetchFn) {
|
|
714
716
|
throw new Error("HTTP sink requires fetch to be available in this runtime.");
|
|
715
717
|
}
|
|
716
|
-
const url = `${baseUrl.replace(/\/$/, "")}/${payload.sessionId}/end`;
|
|
718
|
+
const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/end`;
|
|
717
719
|
const finalHeaders = { ...headers || {} };
|
|
718
720
|
if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
|
|
719
721
|
finalHeaders["content-type"] = "application/json";
|
|
@@ -1010,8 +1012,12 @@ function recordTraceEvent(session, event) {
|
|
|
1010
1012
|
session.summary.eventCounts[event.type] = (session.summary.eventCounts[event.type] || 0) + 1;
|
|
1011
1013
|
let sections;
|
|
1012
1014
|
if (session.resolvedConfig.logData) {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
+
if (event.sections && event.sections.length > 0) {
|
|
1016
|
+
sections = ensureUniqueSections(id, event.sections);
|
|
1017
|
+
} else {
|
|
1018
|
+
const converted = convertMessageListToSections(event.messageList);
|
|
1019
|
+
sections = ensureUniqueSections(id, converted);
|
|
1020
|
+
}
|
|
1015
1021
|
}
|
|
1016
1022
|
const resolvedModel = event.model ?? inferModelFromMessages(event.messageList);
|
|
1017
1023
|
const resolvedProvider = event.provider ?? inferProviderFromMessages(event.messageList);
|
|
@@ -1274,18 +1280,7 @@ function createAgentCoreNode(opts) {
|
|
|
1274
1280
|
outputSchema: opts.outputSchema,
|
|
1275
1281
|
tracing: opts.tracing
|
|
1276
1282
|
};
|
|
1277
|
-
const
|
|
1278
|
-
const seenNames = /* @__PURE__ */ new Map();
|
|
1279
|
-
const tools = [];
|
|
1280
|
-
for (const t of rawTools) {
|
|
1281
|
-
const tName = t.name ?? t.schema?.title;
|
|
1282
|
-
if (tName && seenNames.has(tName)) {
|
|
1283
|
-
tools[seenNames.get(tName)] = t;
|
|
1284
|
-
} else {
|
|
1285
|
-
if (tName) seenNames.set(tName, tools.length);
|
|
1286
|
-
tools.push(t);
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1283
|
+
const tools = runtime.tools ?? [];
|
|
1289
1284
|
const modelWithTools = runtime.model?.bindTools ? runtime.model.bindTools(tools) : runtime.model;
|
|
1290
1285
|
const traceSession = state.ctx?.__traceSession;
|
|
1291
1286
|
const actorName = runtime.name ?? opts.name ?? "agent";
|
|
@@ -1338,6 +1333,26 @@ function createAgentCoreNode(opts) {
|
|
|
1338
1333
|
}
|
|
1339
1334
|
return filteredMsgs;
|
|
1340
1335
|
};
|
|
1336
|
+
const debugToolPairing = (messagesToSend) => {
|
|
1337
|
+
try {
|
|
1338
|
+
const msgs = Array.isArray(messagesToSend) ? messagesToSend : [];
|
|
1339
|
+
const toolUseIds = [];
|
|
1340
|
+
const missingResults = [];
|
|
1341
|
+
for (let i = 0; i < msgs.length; i++) {
|
|
1342
|
+
const m = msgs[i];
|
|
1343
|
+
if (m?.role === "assistant") {
|
|
1344
|
+
for (const tu of extractToolUses(m)) {
|
|
1345
|
+
toolUseIds.push(tu.id);
|
|
1346
|
+
const next = msgs[i + 1];
|
|
1347
|
+
if (!(next && next.role === "tool" && (next.tool_call_id === tu.id || next.tool_call_id === m?.tool_call_id))) {
|
|
1348
|
+
missingResults.push({ id: tu.id, atIndex: i, tool: tu.name });
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
} catch (e) {
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1341
1356
|
const onEvent = state.ctx?.__onEvent;
|
|
1342
1357
|
const onStream = state.ctx?.__onStream;
|
|
1343
1358
|
const streamingEnabled = Boolean(state.ctx?.__streaming);
|
|
@@ -1356,124 +1371,8 @@ function createAgentCoreNode(opts) {
|
|
|
1356
1371
|
};
|
|
1357
1372
|
let response;
|
|
1358
1373
|
try {
|
|
1359
|
-
const
|
|
1360
|
-
|
|
1361
|
-
const usedIds = /* @__PURE__ */ new Set();
|
|
1362
|
-
let counter = 0;
|
|
1363
|
-
for (let i = 0; i < msgs.length; i++) {
|
|
1364
|
-
const m = msgs[i];
|
|
1365
|
-
if (m?.role !== "assistant") continue;
|
|
1366
|
-
const hasToolCalls = Array.isArray(m.tool_calls) && m.tool_calls.length > 0;
|
|
1367
|
-
const contentArr = Array.isArray(m.content) ? m.content : [];
|
|
1368
|
-
const hasContentToolUse = contentArr.some((c) => c?.type === "tool_use" && c?.id);
|
|
1369
|
-
const hasAdditionalToolCalls = Array.isArray(m.additional_kwargs?.tool_calls) && m.additional_kwargs.tool_calls.length > 0;
|
|
1370
|
-
if (!hasToolCalls && !hasContentToolUse && !hasAdditionalToolCalls) continue;
|
|
1371
|
-
if (hasToolCalls && hasContentToolUse) {
|
|
1372
|
-
const toolCallIds = new Set(
|
|
1373
|
-
m.tool_calls.filter((tc) => tc?.id).map((tc) => tc.id)
|
|
1374
|
-
);
|
|
1375
|
-
const filtered = contentArr.filter((c) => {
|
|
1376
|
-
if (c?.type === "tool_use" && c?.id && toolCallIds.has(c.id)) return false;
|
|
1377
|
-
return true;
|
|
1378
|
-
});
|
|
1379
|
-
if (filtered.length === 0) {
|
|
1380
|
-
m.content = "";
|
|
1381
|
-
} else if (filtered.length !== contentArr.length) {
|
|
1382
|
-
m.content = filtered.length === 1 && filtered[0]?.type === "text" ? filtered[0].text ?? "" : filtered;
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
if (hasAdditionalToolCalls && Array.isArray(m.content)) {
|
|
1386
|
-
const akIds = new Set(
|
|
1387
|
-
m.additional_kwargs.tool_calls.filter((tc) => tc?.id).map((tc) => tc.id)
|
|
1388
|
-
);
|
|
1389
|
-
const arr = m.content;
|
|
1390
|
-
const filtered = arr.filter((c) => {
|
|
1391
|
-
if (c?.type === "tool_use" && c?.id && akIds.has(c.id)) return false;
|
|
1392
|
-
return true;
|
|
1393
|
-
});
|
|
1394
|
-
if (filtered.length !== arr.length) {
|
|
1395
|
-
m.content = filtered.length === 0 ? "" : filtered.length === 1 && filtered[0]?.type === "text" ? filtered[0].text ?? "" : filtered;
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
if (hasToolCalls) {
|
|
1399
|
-
m.tool_calls = m.tool_calls.map((tc) => ({ ...tc }));
|
|
1400
|
-
}
|
|
1401
|
-
if (hasAdditionalToolCalls) {
|
|
1402
|
-
m.additional_kwargs = { ...m.additional_kwargs };
|
|
1403
|
-
m.additional_kwargs.tool_calls = m.additional_kwargs.tool_calls.map((tc) => ({ ...tc }));
|
|
1404
|
-
}
|
|
1405
|
-
const remainingContentArr = Array.isArray(m.content) ? m.content : [];
|
|
1406
|
-
const hasRemainingContentToolUse = remainingContentArr.some((c) => c?.type === "tool_use" && c?.id);
|
|
1407
|
-
if (hasRemainingContentToolUse) {
|
|
1408
|
-
m.content = remainingContentArr.map(
|
|
1409
|
-
(c) => c && typeof c === "object" ? { ...c } : c
|
|
1410
|
-
);
|
|
1411
|
-
}
|
|
1412
|
-
const idsInMessage = /* @__PURE__ */ new Set();
|
|
1413
|
-
if (hasToolCalls) {
|
|
1414
|
-
for (const tc of m.tool_calls) {
|
|
1415
|
-
if (tc?.id) idsInMessage.add(tc.id);
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
if (hasRemainingContentToolUse) {
|
|
1419
|
-
for (const c of m.content) {
|
|
1420
|
-
if (c?.type === "tool_use" && c?.id) idsInMessage.add(c.id);
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
if (hasAdditionalToolCalls) {
|
|
1424
|
-
for (const tc of m.additional_kwargs.tool_calls) {
|
|
1425
|
-
if (tc?.id) idsInMessage.add(tc.id);
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
for (const id of idsInMessage) {
|
|
1429
|
-
if (!usedIds.has(id)) {
|
|
1430
|
-
usedIds.add(id);
|
|
1431
|
-
continue;
|
|
1432
|
-
}
|
|
1433
|
-
const newId = `${id}_${Date.now()}_${counter++}`;
|
|
1434
|
-
if (hasToolCalls) {
|
|
1435
|
-
for (const tc of m.tool_calls) {
|
|
1436
|
-
if (tc.id === id) tc.id = newId;
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
if (hasRemainingContentToolUse && Array.isArray(m.content)) {
|
|
1440
|
-
for (const c of m.content) {
|
|
1441
|
-
if (c?.type === "tool_use" && c.id === id) c.id = newId;
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
if (hasAdditionalToolCalls) {
|
|
1445
|
-
for (const tc of m.additional_kwargs.tool_calls) {
|
|
1446
|
-
if (tc.id === id) tc.id = newId;
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
for (let j = i + 1; j < msgs.length; j++) {
|
|
1450
|
-
const next = msgs[j];
|
|
1451
|
-
if (next?.role === "assistant") break;
|
|
1452
|
-
if (next?.role === "tool" && next.tool_call_id === id) {
|
|
1453
|
-
next.tool_call_id = newId;
|
|
1454
|
-
}
|
|
1455
|
-
if (Array.isArray(next?.content)) {
|
|
1456
|
-
let contentCloned = false;
|
|
1457
|
-
for (let k = 0; k < next.content.length; k++) {
|
|
1458
|
-
const block = next.content[k];
|
|
1459
|
-
if (block?.type === "tool_result" && block.tool_use_id === id) {
|
|
1460
|
-
if (!contentCloned) {
|
|
1461
|
-
next.content = next.content.map((x) => x && typeof x === "object" ? { ...x } : x);
|
|
1462
|
-
contentCloned = true;
|
|
1463
|
-
}
|
|
1464
|
-
next.content[k].tool_use_id = newId;
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
usedIds.add(newId);
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
return msgs;
|
|
1473
|
-
};
|
|
1474
|
-
const normalizedMessages = ensureUniqueToolCallIds(
|
|
1475
|
-
normalizeBedrockToolPairing([...state.messages])
|
|
1476
|
-
);
|
|
1374
|
+
const normalizedMessages = normalizeBedrockToolPairing([...state.messages]);
|
|
1375
|
+
debugToolPairing(normalizedMessages);
|
|
1477
1376
|
if (streamingEnabled && typeof modelWithTools.stream === "function") {
|
|
1478
1377
|
let streamedText = "";
|
|
1479
1378
|
let streamedMessage;
|
|
@@ -1613,41 +1512,6 @@ function createToolsNode(initialTools, opts) {
|
|
|
1613
1512
|
const remaining = Math.max(0, limits.maxToolCalls - toolCount);
|
|
1614
1513
|
const planned = toolCalls.slice(0, remaining);
|
|
1615
1514
|
const skipped = toolCalls.slice(remaining);
|
|
1616
|
-
for (const tc of skipped) {
|
|
1617
|
-
onEvent?.({ type: "tool_call", phase: "skipped", name: tc.name, id: tc.id, args: tc.args });
|
|
1618
|
-
const sanitizedArgs = sanitizeTracePayload(tc.args);
|
|
1619
|
-
const messageList = [
|
|
1620
|
-
{
|
|
1621
|
-
role: "assistant",
|
|
1622
|
-
name: tc.name,
|
|
1623
|
-
content: `Skipped tool due to tool-call limit: ${tc.name}`,
|
|
1624
|
-
tool_calls: [
|
|
1625
|
-
{
|
|
1626
|
-
id: tc.id,
|
|
1627
|
-
type: "function",
|
|
1628
|
-
function: {
|
|
1629
|
-
name: tc.name,
|
|
1630
|
-
arguments: sanitizedArgs
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
]
|
|
1634
|
-
}
|
|
1635
|
-
];
|
|
1636
|
-
recordTraceEvent(traceSession, {
|
|
1637
|
-
type: "tool_call",
|
|
1638
|
-
label: `Tool Skipped - ${tc.name}`,
|
|
1639
|
-
actor: { scope: "tool", name: tc.name, role: "tool" },
|
|
1640
|
-
status: "skipped",
|
|
1641
|
-
toolExecutionId: tc.id,
|
|
1642
|
-
messageList
|
|
1643
|
-
});
|
|
1644
|
-
appended.push({
|
|
1645
|
-
role: "tool",
|
|
1646
|
-
content: `Skipped tool due to tool-call limit: ${tc.name}`,
|
|
1647
|
-
tool_call_id: tc.id || `${tc.name}_${appended.length}`,
|
|
1648
|
-
name: tc.name
|
|
1649
|
-
});
|
|
1650
|
-
}
|
|
1651
1515
|
const isCancelled = () => {
|
|
1652
1516
|
if (abortSignal?.aborted) return { cancelled: true, reason: "aborted" };
|
|
1653
1517
|
if (cancellationToken && cancellationToken.isCancellationRequested) return { cancelled: true, reason: "cancelled" };
|
|
@@ -1888,6 +1752,42 @@ function createToolsNode(initialTools, opts) {
|
|
|
1888
1752
|
break;
|
|
1889
1753
|
}
|
|
1890
1754
|
}
|
|
1755
|
+
for (const tc of skipped) {
|
|
1756
|
+
onEvent?.({ type: "tool_call", phase: "skipped", name: tc.name, id: tc.id, args: tc.args });
|
|
1757
|
+
const sanitizedArgs = sanitizeTracePayload(tc.args);
|
|
1758
|
+
const messageList = [
|
|
1759
|
+
{
|
|
1760
|
+
role: "assistant",
|
|
1761
|
+
name: tc.name,
|
|
1762
|
+
content: `Skipped tool due to tool-call limit: ${tc.name}`,
|
|
1763
|
+
tool_calls: [
|
|
1764
|
+
{
|
|
1765
|
+
id: tc.id,
|
|
1766
|
+
type: "function",
|
|
1767
|
+
function: {
|
|
1768
|
+
name: tc.name,
|
|
1769
|
+
arguments: sanitizedArgs
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
]
|
|
1773
|
+
}
|
|
1774
|
+
];
|
|
1775
|
+
recordTraceEvent(traceSession, {
|
|
1776
|
+
type: "tool_call",
|
|
1777
|
+
label: `Tool Skipped - ${tc.name}`,
|
|
1778
|
+
actor: { scope: "tool", name: tc.name, role: "tool" },
|
|
1779
|
+
status: "skipped",
|
|
1780
|
+
toolExecutionId: tc.id,
|
|
1781
|
+
messageList
|
|
1782
|
+
});
|
|
1783
|
+
appended.push({
|
|
1784
|
+
role: "tool",
|
|
1785
|
+
content: `Skipped tool due to tool-call limit: ${tc.name}`,
|
|
1786
|
+
tool_call_id: tc.id || `${tc.name}_${appended.length}`,
|
|
1787
|
+
name: tc.name
|
|
1788
|
+
});
|
|
1789
|
+
toolCount += 1;
|
|
1790
|
+
}
|
|
1891
1791
|
if (!awaitingApproval && state.ctx?.__awaitingApproval) {
|
|
1892
1792
|
const ctx = { ...state.ctx };
|
|
1893
1793
|
delete ctx.__awaitingApproval;
|
|
@@ -2123,6 +2023,59 @@ function countApproxTokens(text) {
|
|
|
2123
2023
|
const asciiCount = text.length - nonAsciiCount;
|
|
2124
2024
|
return Math.ceil(asciiCount / 4 + nonAsciiCount / 1.5);
|
|
2125
2025
|
}
|
|
2026
|
+
function extractMessageText(m) {
|
|
2027
|
+
if (!m) return "";
|
|
2028
|
+
const parts = [];
|
|
2029
|
+
parts.push(m.role || "");
|
|
2030
|
+
if (m.name) parts.push(m.name);
|
|
2031
|
+
if (typeof m.content === "string") {
|
|
2032
|
+
parts.push(m.content);
|
|
2033
|
+
} else if (Array.isArray(m.content)) {
|
|
2034
|
+
for (const c of m.content) {
|
|
2035
|
+
if (typeof c === "string") parts.push(c);
|
|
2036
|
+
else if (c?.text) parts.push(c.text);
|
|
2037
|
+
else if (c?.content) parts.push(c.content);
|
|
2038
|
+
else if (c?.type === "tool_use" && c?.input) {
|
|
2039
|
+
parts.push(c.name || "");
|
|
2040
|
+
parts.push(typeof c.input === "string" ? c.input : JSON.stringify(c.input));
|
|
2041
|
+
} else if (c != null && typeof c === "object") {
|
|
2042
|
+
parts.push(JSON.stringify(c));
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
} else if (m.content != null && typeof m.content === "object") {
|
|
2046
|
+
parts.push(JSON.stringify(m.content));
|
|
2047
|
+
}
|
|
2048
|
+
if (Array.isArray(m.tool_calls)) {
|
|
2049
|
+
for (const tc of m.tool_calls) {
|
|
2050
|
+
if (tc?.function?.name) parts.push(tc.function.name);
|
|
2051
|
+
if (tc?.function?.arguments) {
|
|
2052
|
+
parts.push(
|
|
2053
|
+
typeof tc.function.arguments === "string" ? tc.function.arguments : JSON.stringify(tc.function.arguments)
|
|
2054
|
+
);
|
|
2055
|
+
}
|
|
2056
|
+
if (tc?.name && !tc?.function?.name) parts.push(tc.name);
|
|
2057
|
+
if (tc?.args && !tc?.function?.arguments) {
|
|
2058
|
+
parts.push(typeof tc.args === "string" ? tc.args : JSON.stringify(tc.args));
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
if (Array.isArray(m.additional_kwargs?.tool_calls)) {
|
|
2063
|
+
for (const tc of m.additional_kwargs.tool_calls) {
|
|
2064
|
+
if (tc?.function?.name) parts.push(tc.function.name);
|
|
2065
|
+
if (tc?.function?.arguments) {
|
|
2066
|
+
parts.push(
|
|
2067
|
+
typeof tc.function.arguments === "string" ? tc.function.arguments : JSON.stringify(tc.function.arguments)
|
|
2068
|
+
);
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
return parts.join("\n");
|
|
2073
|
+
}
|
|
2074
|
+
function countMessagesTokens(messages) {
|
|
2075
|
+
if (!Array.isArray(messages) || messages.length === 0) return 0;
|
|
2076
|
+
const allText = messages.map(extractMessageText).join("\n");
|
|
2077
|
+
return countApproxTokens(allText) + messages.length * 4;
|
|
2078
|
+
}
|
|
2126
2079
|
|
|
2127
2080
|
// src/agent.ts
|
|
2128
2081
|
function createAgent(opts) {
|
|
@@ -2292,8 +2245,7 @@ function createAgent(opts) {
|
|
|
2292
2245
|
maxTok = 5e4;
|
|
2293
2246
|
}
|
|
2294
2247
|
if (maxTok) {
|
|
2295
|
-
const
|
|
2296
|
-
const tokenCount = countApproxTokens(allText);
|
|
2248
|
+
const tokenCount = countMessagesTokens(state.messages || []);
|
|
2297
2249
|
if (tokenCount > maxTok) {
|
|
2298
2250
|
const ctx = { ...state.ctx || {}, __needsSummarization: true };
|
|
2299
2251
|
state = { ...state, ctx };
|
|
@@ -3048,7 +3000,19 @@ function needsSummarization(state, opts, summarizationEnabled) {
|
|
|
3048
3000
|
return "";
|
|
3049
3001
|
}).join("\n");
|
|
3050
3002
|
const tokenCount = countApproxTokens(allText);
|
|
3051
|
-
|
|
3003
|
+
const needsSum = tokenCount > maxTok;
|
|
3004
|
+
if (process.env.DEBUG_SUMMARIZATION) {
|
|
3005
|
+
const msgCount = (state.messages || []).length;
|
|
3006
|
+
const toolMsgs = (state.messages || []).filter((m) => m.role === "tool");
|
|
3007
|
+
const toolDetails = toolMsgs.map((m, i) => {
|
|
3008
|
+
const contentStr = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
|
|
3009
|
+
return `[${i}] id:${m.tool_call_id?.slice(-8) || "none"} len:${contentStr.length} preview:"${contentStr.slice(0, 30)}..."`;
|
|
3010
|
+
});
|
|
3011
|
+
console.log(`[Summarization] Messages: ${msgCount}, Tool messages: ${toolMsgs.length}`);
|
|
3012
|
+
toolDetails.forEach((d) => console.log(` ${d}`));
|
|
3013
|
+
console.log(`[Summarization] Token count: ${tokenCount}, Max: ${maxTok}, Needs summarization: ${needsSum}`);
|
|
3014
|
+
}
|
|
3015
|
+
return needsSum;
|
|
3052
3016
|
} catch (e) {
|
|
3053
3017
|
return false;
|
|
3054
3018
|
}
|
|
@@ -3454,6 +3418,7 @@ exports.captureSnapshot = captureSnapshot;
|
|
|
3454
3418
|
exports.codePresenceRule = codePresenceRule;
|
|
3455
3419
|
exports.cognipeerSink = cognipeerSink;
|
|
3456
3420
|
exports.countApproxTokens = countApproxTokens;
|
|
3421
|
+
exports.countMessagesTokens = countMessagesTokens;
|
|
3457
3422
|
exports.createAgent = createAgent;
|
|
3458
3423
|
exports.createAgentNode = createAgentNode;
|
|
3459
3424
|
exports.createCodeGuardrail = createCodeGuardrail;
|