@cognipeer/agent-sdk 0.2.7 → 0.2.9

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;
@@ -2526,6 +2417,7 @@ function createAgent(opts) {
2526
2417
  };
2527
2418
  let res;
2528
2419
  try {
2420
+ await startStreamingSession(traceSession, runtimeWithInvokeLimits);
2529
2421
  res = await runLoop(initial, config, emit);
2530
2422
  } catch (err) {
2531
2423
  await finalizeTraceSession(traceSession, {
@@ -2735,83 +2627,6 @@ function createAgentNode(opts) {
2735
2627
  };
2736
2628
  }
2737
2629
 
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
2630
  // src/nodes/contextSummarize.ts
2816
2631
  var systemMessage = (content) => ({ role: "system", content });
2817
2632
  var humanMessage = (content) => ({ role: "user", content });
@@ -2870,7 +2685,8 @@ function createContextSummarizeNode(opts) {
2870
2685
  if (compressableMessages.length === 0) {
2871
2686
  return {};
2872
2687
  }
2873
- const tokenCountBefore = countMessagesTokens(messages);
2688
+ 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");
2689
+ const tokenCountBefore = countApproxTokens(allTextBefore);
2874
2690
  const summaryPromptMaxTokens = config.summaryPromptMaxTokens;
2875
2691
  const availableTokensForConversation = summaryPromptMaxTokens - 500;
2876
2692
  const messageTexts = [];
@@ -2933,7 +2749,7 @@ Summary:`;
2933
2749
  durationMs = Date.now() - startTime;
2934
2750
  summaryText = typeof response.content === "string" ? response.content : Array.isArray(response.content) ? response.content.map((c) => c.text || "").join("") : JSON.stringify(response.content);
2935
2751
  outputTokensEstimate = countApproxTokens(summaryText);
2936
- const rawUsage = response?.usage_metadata || response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
2752
+ const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
2937
2753
  const normalized = normalizeUsage(rawUsage);
2938
2754
  if (normalized) {
2939
2755
  inputTokensActual = normalized.prompt_tokens;
@@ -2965,16 +2781,7 @@ Summary:`;
2965
2781
  inputTokens: inputTokensEstimate,
2966
2782
  outputTokens: 0,
2967
2783
  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
- })
2784
+ messageList: sanitizeTracePayload(summaryPrompt)
2978
2785
  });
2979
2786
  return {};
2980
2787
  }
@@ -3028,7 +2835,8 @@ Summary:`;
3028
2835
  };
3029
2836
  const summaries = Array.isArray(state.summaries) ? [...state.summaries, summaryText] : [summaryText];
3030
2837
  const finalMessages = [...validatedMessages, assistantSummaryCall, toolSummaryResponse];
3031
- const tokenCountAfter = countMessagesTokens(finalMessages);
2838
+ 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");
2839
+ const tokenCountAfter = countApproxTokens(allTextAfter);
3032
2840
  const summarizationEvent = {
3033
2841
  type: "summarization",
3034
2842
  summary: summaryText,
@@ -3055,21 +2863,10 @@ Summary:`;
3055
2863
  outputTokens: outputTokensActual ?? outputTokensEstimate,
3056
2864
  cachedInputTokens,
3057
2865
  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
- }),
2866
+ messageList: sanitizeTracePayload([
2867
+ ...summaryPrompt,
2868
+ { role: "assistant", content: summaryText, name: "summarization_result" }
2869
+ ]),
3073
2870
  debug: {
3074
2871
  messagesCompressed: compressableMessages.length,
3075
2872
  tokenCountBefore,
@@ -3193,8 +2990,30 @@ function needsSummarization(state, opts, summarizationEnabled) {
3193
2990
  maxTok = 5e4;
3194
2991
  }
3195
2992
  try {
3196
- const tokenCount = countMessagesTokens(state.messages || []);
3197
- return tokenCount > maxTok;
2993
+ const allText = (state.messages || []).map((m) => {
2994
+ if (typeof m.content === "string") return m.content;
2995
+ if (Array.isArray(m.content)) {
2996
+ return m.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? JSON.stringify(c)).join("");
2997
+ }
2998
+ if (m.content && typeof m.content === "object") {
2999
+ return JSON.stringify(m.content);
3000
+ }
3001
+ return "";
3002
+ }).join("\n");
3003
+ const tokenCount = countApproxTokens(allText);
3004
+ const needsSum = tokenCount > maxTok;
3005
+ if (process.env.DEBUG_SUMMARIZATION) {
3006
+ const msgCount = (state.messages || []).length;
3007
+ const toolMsgs = (state.messages || []).filter((m) => m.role === "tool");
3008
+ const toolDetails = toolMsgs.map((m, i) => {
3009
+ const contentStr = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
3010
+ return `[${i}] id:${m.tool_call_id?.slice(-8) || "none"} len:${contentStr.length} preview:"${contentStr.slice(0, 30)}..."`;
3011
+ });
3012
+ console.log(`[Summarization] Messages: ${msgCount}, Tool messages: ${toolMsgs.length}`);
3013
+ toolDetails.forEach((d) => console.log(` ${d}`));
3014
+ console.log(`[Summarization] Token count: ${tokenCount}, Max: ${maxTok}, Needs summarization: ${needsSum}`);
3015
+ }
3016
+ return needsSum;
3198
3017
  } catch (e) {
3199
3018
  return false;
3200
3019
  }