@cognipeer/agent-sdk 0.2.7 → 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 CHANGED
@@ -647,7 +647,7 @@ async function postStreamingSessionStart(baseUrl, headers, payload) {
647
647
  if (!fetchFn) {
648
648
  throw new Error("HTTP sink requires fetch to be available in this runtime.");
649
649
  }
650
- const url = `${baseUrl.replace(/\/$/, "")}/${payload.sessionId}/start`;
650
+ const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/start`;
651
651
  const finalHeaders = { ...headers || {} };
652
652
  if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
653
653
  finalHeaders["content-type"] = "application/json";
@@ -681,7 +681,7 @@ async function postStreamingEvent(baseUrl, headers, sessionId, event) {
681
681
  if (!fetchFn) {
682
682
  throw new Error("HTTP sink requires fetch to be available in this runtime.");
683
683
  }
684
- const url = `${baseUrl.replace(/\/$/, "")}/${sessionId}/events`;
684
+ const url = `${baseUrl.replace(/\/$/, "")}/stream/${sessionId}/events`;
685
685
  const finalHeaders = { ...headers || {} };
686
686
  if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
687
687
  finalHeaders["content-type"] = "application/json";
@@ -715,7 +715,7 @@ async function postStreamingSessionEnd(baseUrl, headers, payload) {
715
715
  if (!fetchFn) {
716
716
  throw new Error("HTTP sink requires fetch to be available in this runtime.");
717
717
  }
718
- const url = `${baseUrl.replace(/\/$/, "")}/${payload.sessionId}/end`;
718
+ const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/end`;
719
719
  const finalHeaders = { ...headers || {} };
720
720
  if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
721
721
  finalHeaders["content-type"] = "application/json";
@@ -1280,18 +1280,7 @@ function createAgentCoreNode(opts) {
1280
1280
  outputSchema: opts.outputSchema,
1281
1281
  tracing: opts.tracing
1282
1282
  };
1283
- const rawTools = runtime.tools ?? [];
1284
- const seenNames = /* @__PURE__ */ new Map();
1285
- const tools = [];
1286
- for (const t of rawTools) {
1287
- const tName = t.name ?? t.schema?.title;
1288
- if (tName && seenNames.has(tName)) {
1289
- tools[seenNames.get(tName)] = t;
1290
- } else {
1291
- if (tName) seenNames.set(tName, tools.length);
1292
- tools.push(t);
1293
- }
1294
- }
1283
+ const tools = runtime.tools ?? [];
1295
1284
  const modelWithTools = runtime.model?.bindTools ? runtime.model.bindTools(tools) : runtime.model;
1296
1285
  const traceSession = state.ctx?.__traceSession;
1297
1286
  const actorName = runtime.name ?? opts.name ?? "agent";
@@ -1344,6 +1333,26 @@ function createAgentCoreNode(opts) {
1344
1333
  }
1345
1334
  return filteredMsgs;
1346
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
+ };
1347
1356
  const onEvent = state.ctx?.__onEvent;
1348
1357
  const onStream = state.ctx?.__onStream;
1349
1358
  const streamingEnabled = Boolean(state.ctx?.__streaming);
@@ -1362,130 +1371,12 @@ function createAgentCoreNode(opts) {
1362
1371
  };
1363
1372
  let response;
1364
1373
  try {
1365
- const ensureUniqueToolCallIds = (input) => {
1366
- const msgs = Array.isArray(input) ? input.map((m) => ({ ...m })) : [];
1367
- const usedIds = /* @__PURE__ */ new Set();
1368
- let counter = 0;
1369
- for (let i = 0; i < msgs.length; i++) {
1370
- const m = msgs[i];
1371
- if (m?.role !== "assistant") continue;
1372
- const hasToolCalls = Array.isArray(m.tool_calls) && m.tool_calls.length > 0;
1373
- const contentArr = Array.isArray(m.content) ? m.content : [];
1374
- const hasContentToolUse = contentArr.some((c) => c?.type === "tool_use" && c?.id);
1375
- const hasAdditionalToolCalls = Array.isArray(m.additional_kwargs?.tool_calls) && m.additional_kwargs.tool_calls.length > 0;
1376
- if (!hasToolCalls && !hasContentToolUse && !hasAdditionalToolCalls) continue;
1377
- if (hasToolCalls && hasContentToolUse) {
1378
- const toolCallIds = new Set(
1379
- m.tool_calls.filter((tc) => tc?.id).map((tc) => tc.id)
1380
- );
1381
- const filtered = contentArr.filter((c) => {
1382
- if (c?.type === "tool_use" && c?.id && toolCallIds.has(c.id)) return false;
1383
- return true;
1384
- });
1385
- if (filtered.length === 0) {
1386
- m.content = "";
1387
- } else if (filtered.length !== contentArr.length) {
1388
- m.content = filtered.length === 1 && filtered[0]?.type === "text" ? filtered[0].text ?? "" : filtered;
1389
- }
1390
- }
1391
- if (hasAdditionalToolCalls && Array.isArray(m.content)) {
1392
- const akIds = new Set(
1393
- m.additional_kwargs.tool_calls.filter((tc) => tc?.id).map((tc) => tc.id)
1394
- );
1395
- const arr = m.content;
1396
- const filtered = arr.filter((c) => {
1397
- if (c?.type === "tool_use" && c?.id && akIds.has(c.id)) return false;
1398
- return true;
1399
- });
1400
- if (filtered.length !== arr.length) {
1401
- m.content = filtered.length === 0 ? "" : filtered.length === 1 && filtered[0]?.type === "text" ? filtered[0].text ?? "" : filtered;
1402
- }
1403
- }
1404
- if (hasToolCalls) {
1405
- m.tool_calls = m.tool_calls.map((tc) => ({ ...tc }));
1406
- }
1407
- if (hasAdditionalToolCalls) {
1408
- m.additional_kwargs = { ...m.additional_kwargs };
1409
- m.additional_kwargs.tool_calls = m.additional_kwargs.tool_calls.map((tc) => ({ ...tc }));
1410
- }
1411
- const remainingContentArr = Array.isArray(m.content) ? m.content : [];
1412
- const hasRemainingContentToolUse = remainingContentArr.some((c) => c?.type === "tool_use" && c?.id);
1413
- if (hasRemainingContentToolUse) {
1414
- m.content = remainingContentArr.map(
1415
- (c) => c && typeof c === "object" ? { ...c } : c
1416
- );
1417
- }
1418
- const idsInMessage = /* @__PURE__ */ new Set();
1419
- if (hasToolCalls) {
1420
- for (const tc of m.tool_calls) {
1421
- if (tc?.id) idsInMessage.add(tc.id);
1422
- }
1423
- }
1424
- if (hasRemainingContentToolUse) {
1425
- for (const c of m.content) {
1426
- if (c?.type === "tool_use" && c?.id) idsInMessage.add(c.id);
1427
- }
1428
- }
1429
- if (hasAdditionalToolCalls) {
1430
- for (const tc of m.additional_kwargs.tool_calls) {
1431
- if (tc?.id) idsInMessage.add(tc.id);
1432
- }
1433
- }
1434
- for (const id of idsInMessage) {
1435
- if (!usedIds.has(id)) {
1436
- usedIds.add(id);
1437
- continue;
1438
- }
1439
- const newId = `${id}_${Date.now()}_${counter++}`;
1440
- if (hasToolCalls) {
1441
- for (const tc of m.tool_calls) {
1442
- if (tc.id === id) tc.id = newId;
1443
- }
1444
- }
1445
- if (hasRemainingContentToolUse && Array.isArray(m.content)) {
1446
- for (const c of m.content) {
1447
- if (c?.type === "tool_use" && c.id === id) c.id = newId;
1448
- }
1449
- }
1450
- if (hasAdditionalToolCalls) {
1451
- for (const tc of m.additional_kwargs.tool_calls) {
1452
- if (tc.id === id) tc.id = newId;
1453
- }
1454
- }
1455
- for (let j = i + 1; j < msgs.length; j++) {
1456
- const next = msgs[j];
1457
- if (next?.role === "assistant") break;
1458
- if (next?.role === "tool" && next.tool_call_id === id) {
1459
- next.tool_call_id = newId;
1460
- }
1461
- if (Array.isArray(next?.content)) {
1462
- let contentCloned = false;
1463
- for (let k = 0; k < next.content.length; k++) {
1464
- const block = next.content[k];
1465
- if (block?.type === "tool_result" && block.tool_use_id === id) {
1466
- if (!contentCloned) {
1467
- next.content = next.content.map((x) => x && typeof x === "object" ? { ...x } : x);
1468
- contentCloned = true;
1469
- }
1470
- next.content[k].tool_use_id = newId;
1471
- }
1472
- }
1473
- }
1474
- }
1475
- usedIds.add(newId);
1476
- }
1477
- }
1478
- return msgs;
1479
- };
1480
- const normalizedMessages = ensureUniqueToolCallIds(
1481
- normalizeBedrockToolPairing([...state.messages])
1482
- );
1374
+ const normalizedMessages = normalizeBedrockToolPairing([...state.messages]);
1375
+ debugToolPairing(normalizedMessages);
1483
1376
  if (streamingEnabled && typeof modelWithTools.stream === "function") {
1484
1377
  let streamedText = "";
1485
1378
  let streamedMessage;
1486
- const streamResult = modelWithTools.stream(normalizedMessages, { signal: abortSignal, cancellationToken });
1487
- const stream = typeof streamResult?.then === "function" ? await streamResult : streamResult;
1488
- for await (const chunk of stream) {
1379
+ for await (const chunk of modelWithTools.stream(normalizedMessages, { signal: abortSignal, cancellationToken })) {
1489
1380
  if (cancellationToken && cancellationToken.isCancellationRequested || abortSignal?.aborted) {
1490
1381
  break;
1491
1382
  }
@@ -1530,7 +1421,7 @@ function createAgentCoreNode(opts) {
1530
1421
  ...state.messages,
1531
1422
  response
1532
1423
  ];
1533
- const rawUsage = response?.usage_metadata || response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
1424
+ const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
1534
1425
  const normalized = normalizeUsage(rawUsage);
1535
1426
  const modelName = getModelName(runtime.model || opts.model) || "unknown_model";
1536
1427
  const durationMs = Date.now() - start;
@@ -2735,83 +2626,6 @@ function createAgentNode(opts) {
2735
2626
  };
2736
2627
  }
2737
2628
 
2738
- // src/utils/traceSections.ts
2739
- function formatMessageContent(content) {
2740
- if (content == null) return "";
2741
- if (typeof content === "string") return content;
2742
- if (Array.isArray(content)) {
2743
- return content.map((item) => {
2744
- if (typeof item === "string") return item;
2745
- if (item && typeof item === "object") {
2746
- if (typeof item.text === "string") return item.text;
2747
- if (typeof item.content === "string") return item.content;
2748
- try {
2749
- return JSON.stringify(item);
2750
- } catch {
2751
- return String(item);
2752
- }
2753
- }
2754
- try {
2755
- return JSON.stringify(item);
2756
- } catch {
2757
- return String(item);
2758
- }
2759
- }).filter(Boolean).join("\n");
2760
- }
2761
- if (typeof content === "object") {
2762
- if (typeof content.text === "string") return content.text;
2763
- if (typeof content.content === "string") return content.content;
2764
- try {
2765
- return JSON.stringify(content, null, 2);
2766
- } catch {
2767
- return String(content);
2768
- }
2769
- }
2770
- return String(content);
2771
- }
2772
- function buildSummarizationSections(opts) {
2773
- const sections = [];
2774
- sections.push({
2775
- kind: "summary",
2776
- label: "Context Summary",
2777
- content: opts.summaryText
2778
- });
2779
- const tokensSaved = opts.tokenCountBefore - opts.tokenCountAfter;
2780
- const reductionPct = opts.tokenCountBefore > 0 ? Math.round(tokensSaved / opts.tokenCountBefore * 100) : 0;
2781
- const metaData = {
2782
- messagesCompressed: opts.messagesCompressed,
2783
- tokenCountBefore: opts.tokenCountBefore,
2784
- tokenCountAfter: opts.tokenCountAfter,
2785
- tokensSaved,
2786
- reductionPercent: reductionPct
2787
- };
2788
- if (opts.inputTokens !== void 0) metaData.inputTokens = opts.inputTokens;
2789
- if (opts.outputTokens !== void 0) metaData.outputTokens = opts.outputTokens;
2790
- if (opts.cachedInputTokens !== void 0) metaData.cachedInputTokens = opts.cachedInputTokens;
2791
- if (opts.durationMs !== void 0) metaData.durationMs = opts.durationMs;
2792
- if (opts.previousSummary) metaData.previousSummaryLength = opts.previousSummary.length;
2793
- sections.push({
2794
- kind: "metadata",
2795
- label: "Summarization Stats",
2796
- data: metaData
2797
- });
2798
- if (Array.isArray(opts.promptMessages) && opts.promptMessages.length > 0) {
2799
- for (const msg of opts.promptMessages) {
2800
- const role = typeof msg?.role === "string" ? msg.role : "system";
2801
- const content = formatMessageContent(msg?.content ?? "");
2802
- if (content) {
2803
- sections.push({
2804
- kind: "message",
2805
- label: `Summarization Prompt (${role})`,
2806
- role,
2807
- content
2808
- });
2809
- }
2810
- }
2811
- }
2812
- return sections;
2813
- }
2814
-
2815
2629
  // src/nodes/contextSummarize.ts
2816
2630
  var systemMessage = (content) => ({ role: "system", content });
2817
2631
  var humanMessage = (content) => ({ role: "user", content });
@@ -2870,7 +2684,8 @@ function createContextSummarizeNode(opts) {
2870
2684
  if (compressableMessages.length === 0) {
2871
2685
  return {};
2872
2686
  }
2873
- const tokenCountBefore = countMessagesTokens(messages);
2687
+ const allTextBefore = messages.map((m) => typeof m.content === "string" ? m.content : Array.isArray(m.content) ? m.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? "").join("") : "").join("\n");
2688
+ const tokenCountBefore = countApproxTokens(allTextBefore);
2874
2689
  const summaryPromptMaxTokens = config.summaryPromptMaxTokens;
2875
2690
  const availableTokensForConversation = summaryPromptMaxTokens - 500;
2876
2691
  const messageTexts = [];
@@ -2933,7 +2748,7 @@ Summary:`;
2933
2748
  durationMs = Date.now() - startTime;
2934
2749
  summaryText = typeof response.content === "string" ? response.content : Array.isArray(response.content) ? response.content.map((c) => c.text || "").join("") : JSON.stringify(response.content);
2935
2750
  outputTokensEstimate = countApproxTokens(summaryText);
2936
- const rawUsage = response?.usage_metadata || response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
2751
+ const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
2937
2752
  const normalized = normalizeUsage(rawUsage);
2938
2753
  if (normalized) {
2939
2754
  inputTokensActual = normalized.prompt_tokens;
@@ -2965,16 +2780,7 @@ Summary:`;
2965
2780
  inputTokens: inputTokensEstimate,
2966
2781
  outputTokens: 0,
2967
2782
  error: { message: err?.message || String(err), stack: err?.stack },
2968
- sections: buildSummarizationSections({
2969
- summaryText: "",
2970
- messagesCompressed: 0,
2971
- tokenCountBefore,
2972
- tokenCountAfter: tokenCountBefore,
2973
- inputTokens: inputTokensEstimate,
2974
- outputTokens: 0,
2975
- durationMs,
2976
- promptMessages: summaryPrompt
2977
- })
2783
+ messageList: sanitizeTracePayload(summaryPrompt)
2978
2784
  });
2979
2785
  return {};
2980
2786
  }
@@ -3028,7 +2834,8 @@ Summary:`;
3028
2834
  };
3029
2835
  const summaries = Array.isArray(state.summaries) ? [...state.summaries, summaryText] : [summaryText];
3030
2836
  const finalMessages = [...validatedMessages, assistantSummaryCall, toolSummaryResponse];
3031
- const tokenCountAfter = countMessagesTokens(finalMessages);
2837
+ const allTextAfter = finalMessages.map((m) => typeof m.content === "string" ? m.content : Array.isArray(m.content) ? m.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? "").join("") : "").join("\n");
2838
+ const tokenCountAfter = countApproxTokens(allTextAfter);
3032
2839
  const summarizationEvent = {
3033
2840
  type: "summarization",
3034
2841
  summary: summaryText,
@@ -3055,21 +2862,10 @@ Summary:`;
3055
2862
  outputTokens: outputTokensActual ?? outputTokensEstimate,
3056
2863
  cachedInputTokens,
3057
2864
  totalTokens: totalTokensActual,
3058
- sections: buildSummarizationSections({
3059
- summaryText,
3060
- previousSummary: previousSummary || void 0,
3061
- messagesCompressed: compressableMessages.length,
3062
- tokenCountBefore,
3063
- tokenCountAfter,
3064
- inputTokens: inputTokensActual ?? inputTokensEstimate,
3065
- outputTokens: outputTokensActual ?? outputTokensEstimate,
3066
- cachedInputTokens,
3067
- durationMs,
3068
- promptMessages: sanitizeTracePayload([
3069
- ...summaryPrompt,
3070
- { role: "assistant", content: summaryText, name: "summarization_result" }
3071
- ])
3072
- }),
2865
+ messageList: sanitizeTracePayload([
2866
+ ...summaryPrompt,
2867
+ { role: "assistant", content: summaryText, name: "summarization_result" }
2868
+ ]),
3073
2869
  debug: {
3074
2870
  messagesCompressed: compressableMessages.length,
3075
2871
  tokenCountBefore,
@@ -3193,8 +2989,30 @@ function needsSummarization(state, opts, summarizationEnabled) {
3193
2989
  maxTok = 5e4;
3194
2990
  }
3195
2991
  try {
3196
- const tokenCount = countMessagesTokens(state.messages || []);
3197
- return tokenCount > maxTok;
2992
+ const allText = (state.messages || []).map((m) => {
2993
+ if (typeof m.content === "string") return m.content;
2994
+ if (Array.isArray(m.content)) {
2995
+ return m.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? JSON.stringify(c)).join("");
2996
+ }
2997
+ if (m.content && typeof m.content === "object") {
2998
+ return JSON.stringify(m.content);
2999
+ }
3000
+ return "";
3001
+ }).join("\n");
3002
+ const tokenCount = countApproxTokens(allText);
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;
3198
3016
  } catch (e) {
3199
3017
  return false;
3200
3018
  }