@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.d.cts CHANGED
@@ -75,15 +75,16 @@ interface ToolInterface<TInput = any, TOutput = any, TCallOptions = any> {
75
75
  approvalDefaults?: any;
76
76
  [key: string]: any;
77
77
  }
78
- type RunnableConfig = Record<string, unknown>;
78
+ type RunnableConfig = {
79
+ [key: string]: any;
80
+ };
79
81
  type BaseMessage = {
80
82
  role: string;
81
83
  name?: string;
82
84
  content: string | ContentPart[];
83
85
  tool_calls?: any;
84
86
  tool_call_id?: string;
85
- metadata?: Record<string, any>;
86
- additional_kwargs?: Record<string, any>;
87
+ [key: string]: any;
87
88
  };
88
89
  type AIMessage = BaseMessage & {
89
90
  role: 'assistant';
@@ -143,7 +144,6 @@ type AgentLimits = {
143
144
  maxToolCalls?: number;
144
145
  maxParallelTools?: number;
145
146
  };
146
- /** @deprecated Use AgentLimits instead */
147
147
  type SmartAgentLimits = AgentLimits;
148
148
  type TraceSinkFileConfig = {
149
149
  type: "file";
@@ -168,20 +168,15 @@ type TraceSinkConfig = TraceSinkFileConfig | TraceSinkCustomConfig | TraceSinkCo
168
168
  type TracingMode = "batched" | "streaming";
169
169
  type TracingConfig = {
170
170
  enabled: boolean;
171
- logData?: boolean;
172
- /** Tracing mode:
173
- * - "batched" (default): Events are collected and sent together when session ends
174
- * - "streaming": Session starts immediately, events are sent in real-time as they occur
175
- */
176
171
  mode?: TracingMode;
172
+ logData?: boolean;
177
173
  sink?: TraceSinkConfig;
178
174
  };
179
- /** @deprecated Use TracingConfig instead */
180
175
  type SmartAgentTracingConfig = TracingConfig;
181
176
  type AgentOptions = {
182
177
  name?: string;
183
178
  version?: string;
184
- model: BaseChatModel;
179
+ model: any;
185
180
  tools?: Array<ToolInterface<any, any, any>>;
186
181
  guardrails?: ConversationGuardrail[];
187
182
  handoffs?: HandoffDescriptor[];
@@ -193,7 +188,7 @@ type AgentOptions = {
193
188
  type SmartAgentOptions = {
194
189
  name?: string;
195
190
  version?: string;
196
- model: BaseChatModel;
191
+ model: any;
197
192
  tools?: Array<ToolInterface<any, any, any>>;
198
193
  guardrails?: ConversationGuardrail[];
199
194
  handoffs?: HandoffDescriptor[];
@@ -215,7 +210,7 @@ type SmartAgentOptions = {
215
210
  type AgentRuntimeConfig = {
216
211
  name?: string;
217
212
  version?: string;
218
- model: BaseChatModel;
213
+ model: any;
219
214
  tools: Array<ToolInterface<any, any, any>>;
220
215
  guardrails?: ConversationGuardrail[];
221
216
  systemPrompt?: string;
@@ -393,9 +388,7 @@ type TraceSessionRuntime = {
393
388
  errors: TraceErrorRecord[];
394
389
  fileBaseDir?: string;
395
390
  fileSessionDir?: string;
396
- /** For streaming mode: whether session start has been sent to sink */
397
391
  sessionStarted?: boolean;
398
- /** Agent info for streaming mode session start */
399
392
  agentInfo?: {
400
393
  name?: string;
401
394
  version?: string;
package/dist/index.d.ts CHANGED
@@ -75,15 +75,16 @@ interface ToolInterface<TInput = any, TOutput = any, TCallOptions = any> {
75
75
  approvalDefaults?: any;
76
76
  [key: string]: any;
77
77
  }
78
- type RunnableConfig = Record<string, unknown>;
78
+ type RunnableConfig = {
79
+ [key: string]: any;
80
+ };
79
81
  type BaseMessage = {
80
82
  role: string;
81
83
  name?: string;
82
84
  content: string | ContentPart[];
83
85
  tool_calls?: any;
84
86
  tool_call_id?: string;
85
- metadata?: Record<string, any>;
86
- additional_kwargs?: Record<string, any>;
87
+ [key: string]: any;
87
88
  };
88
89
  type AIMessage = BaseMessage & {
89
90
  role: 'assistant';
@@ -143,7 +144,6 @@ type AgentLimits = {
143
144
  maxToolCalls?: number;
144
145
  maxParallelTools?: number;
145
146
  };
146
- /** @deprecated Use AgentLimits instead */
147
147
  type SmartAgentLimits = AgentLimits;
148
148
  type TraceSinkFileConfig = {
149
149
  type: "file";
@@ -168,20 +168,15 @@ type TraceSinkConfig = TraceSinkFileConfig | TraceSinkCustomConfig | TraceSinkCo
168
168
  type TracingMode = "batched" | "streaming";
169
169
  type TracingConfig = {
170
170
  enabled: boolean;
171
- logData?: boolean;
172
- /** Tracing mode:
173
- * - "batched" (default): Events are collected and sent together when session ends
174
- * - "streaming": Session starts immediately, events are sent in real-time as they occur
175
- */
176
171
  mode?: TracingMode;
172
+ logData?: boolean;
177
173
  sink?: TraceSinkConfig;
178
174
  };
179
- /** @deprecated Use TracingConfig instead */
180
175
  type SmartAgentTracingConfig = TracingConfig;
181
176
  type AgentOptions = {
182
177
  name?: string;
183
178
  version?: string;
184
- model: BaseChatModel;
179
+ model: any;
185
180
  tools?: Array<ToolInterface<any, any, any>>;
186
181
  guardrails?: ConversationGuardrail[];
187
182
  handoffs?: HandoffDescriptor[];
@@ -193,7 +188,7 @@ type AgentOptions = {
193
188
  type SmartAgentOptions = {
194
189
  name?: string;
195
190
  version?: string;
196
- model: BaseChatModel;
191
+ model: any;
197
192
  tools?: Array<ToolInterface<any, any, any>>;
198
193
  guardrails?: ConversationGuardrail[];
199
194
  handoffs?: HandoffDescriptor[];
@@ -215,7 +210,7 @@ type SmartAgentOptions = {
215
210
  type AgentRuntimeConfig = {
216
211
  name?: string;
217
212
  version?: string;
218
- model: BaseChatModel;
213
+ model: any;
219
214
  tools: Array<ToolInterface<any, any, any>>;
220
215
  guardrails?: ConversationGuardrail[];
221
216
  systemPrompt?: string;
@@ -393,9 +388,7 @@ type TraceSessionRuntime = {
393
388
  errors: TraceErrorRecord[];
394
389
  fileBaseDir?: string;
395
390
  fileSessionDir?: string;
396
- /** For streaming mode: whether session start has been sent to sink */
397
391
  sessionStarted?: boolean;
398
- /** Agent info for streaming mode session start */
399
392
  agentInfo?: {
400
393
  name?: string;
401
394
  version?: string;
package/dist/index.mjs CHANGED
@@ -638,7 +638,7 @@ async function postStreamingSessionStart(baseUrl, headers, payload) {
638
638
  if (!fetchFn) {
639
639
  throw new Error("HTTP sink requires fetch to be available in this runtime.");
640
640
  }
641
- const url = `${baseUrl.replace(/\/$/, "")}/${payload.sessionId}/start`;
641
+ const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/start`;
642
642
  const finalHeaders = { ...headers || {} };
643
643
  if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
644
644
  finalHeaders["content-type"] = "application/json";
@@ -672,7 +672,7 @@ async function postStreamingEvent(baseUrl, headers, sessionId, event) {
672
672
  if (!fetchFn) {
673
673
  throw new Error("HTTP sink requires fetch to be available in this runtime.");
674
674
  }
675
- const url = `${baseUrl.replace(/\/$/, "")}/${sessionId}/events`;
675
+ const url = `${baseUrl.replace(/\/$/, "")}/stream/${sessionId}/events`;
676
676
  const finalHeaders = { ...headers || {} };
677
677
  if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
678
678
  finalHeaders["content-type"] = "application/json";
@@ -706,7 +706,7 @@ async function postStreamingSessionEnd(baseUrl, headers, payload) {
706
706
  if (!fetchFn) {
707
707
  throw new Error("HTTP sink requires fetch to be available in this runtime.");
708
708
  }
709
- const url = `${baseUrl.replace(/\/$/, "")}/${payload.sessionId}/end`;
709
+ const url = `${baseUrl.replace(/\/$/, "")}/stream/${payload.sessionId}/end`;
710
710
  const finalHeaders = { ...headers || {} };
711
711
  if (!Object.keys(finalHeaders).some((key) => key.toLowerCase() === "content-type")) {
712
712
  finalHeaders["content-type"] = "application/json";
@@ -1271,18 +1271,7 @@ function createAgentCoreNode(opts) {
1271
1271
  outputSchema: opts.outputSchema,
1272
1272
  tracing: opts.tracing
1273
1273
  };
1274
- const rawTools = runtime.tools ?? [];
1275
- const seenNames = /* @__PURE__ */ new Map();
1276
- const tools = [];
1277
- for (const t of rawTools) {
1278
- const tName = t.name ?? t.schema?.title;
1279
- if (tName && seenNames.has(tName)) {
1280
- tools[seenNames.get(tName)] = t;
1281
- } else {
1282
- if (tName) seenNames.set(tName, tools.length);
1283
- tools.push(t);
1284
- }
1285
- }
1274
+ const tools = runtime.tools ?? [];
1286
1275
  const modelWithTools = runtime.model?.bindTools ? runtime.model.bindTools(tools) : runtime.model;
1287
1276
  const traceSession = state.ctx?.__traceSession;
1288
1277
  const actorName = runtime.name ?? opts.name ?? "agent";
@@ -1335,6 +1324,26 @@ function createAgentCoreNode(opts) {
1335
1324
  }
1336
1325
  return filteredMsgs;
1337
1326
  };
1327
+ const debugToolPairing = (messagesToSend) => {
1328
+ try {
1329
+ const msgs = Array.isArray(messagesToSend) ? messagesToSend : [];
1330
+ const toolUseIds = [];
1331
+ const missingResults = [];
1332
+ for (let i = 0; i < msgs.length; i++) {
1333
+ const m = msgs[i];
1334
+ if (m?.role === "assistant") {
1335
+ for (const tu of extractToolUses(m)) {
1336
+ toolUseIds.push(tu.id);
1337
+ const next = msgs[i + 1];
1338
+ if (!(next && next.role === "tool" && (next.tool_call_id === tu.id || next.tool_call_id === m?.tool_call_id))) {
1339
+ missingResults.push({ id: tu.id, atIndex: i, tool: tu.name });
1340
+ }
1341
+ }
1342
+ }
1343
+ }
1344
+ } catch (e) {
1345
+ }
1346
+ };
1338
1347
  const onEvent = state.ctx?.__onEvent;
1339
1348
  const onStream = state.ctx?.__onStream;
1340
1349
  const streamingEnabled = Boolean(state.ctx?.__streaming);
@@ -1353,130 +1362,12 @@ function createAgentCoreNode(opts) {
1353
1362
  };
1354
1363
  let response;
1355
1364
  try {
1356
- const ensureUniqueToolCallIds = (input) => {
1357
- const msgs = Array.isArray(input) ? input.map((m) => ({ ...m })) : [];
1358
- const usedIds = /* @__PURE__ */ new Set();
1359
- let counter = 0;
1360
- for (let i = 0; i < msgs.length; i++) {
1361
- const m = msgs[i];
1362
- if (m?.role !== "assistant") continue;
1363
- const hasToolCalls = Array.isArray(m.tool_calls) && m.tool_calls.length > 0;
1364
- const contentArr = Array.isArray(m.content) ? m.content : [];
1365
- const hasContentToolUse = contentArr.some((c) => c?.type === "tool_use" && c?.id);
1366
- const hasAdditionalToolCalls = Array.isArray(m.additional_kwargs?.tool_calls) && m.additional_kwargs.tool_calls.length > 0;
1367
- if (!hasToolCalls && !hasContentToolUse && !hasAdditionalToolCalls) continue;
1368
- if (hasToolCalls && hasContentToolUse) {
1369
- const toolCallIds = new Set(
1370
- m.tool_calls.filter((tc) => tc?.id).map((tc) => tc.id)
1371
- );
1372
- const filtered = contentArr.filter((c) => {
1373
- if (c?.type === "tool_use" && c?.id && toolCallIds.has(c.id)) return false;
1374
- return true;
1375
- });
1376
- if (filtered.length === 0) {
1377
- m.content = "";
1378
- } else if (filtered.length !== contentArr.length) {
1379
- m.content = filtered.length === 1 && filtered[0]?.type === "text" ? filtered[0].text ?? "" : filtered;
1380
- }
1381
- }
1382
- if (hasAdditionalToolCalls && Array.isArray(m.content)) {
1383
- const akIds = new Set(
1384
- m.additional_kwargs.tool_calls.filter((tc) => tc?.id).map((tc) => tc.id)
1385
- );
1386
- const arr = m.content;
1387
- const filtered = arr.filter((c) => {
1388
- if (c?.type === "tool_use" && c?.id && akIds.has(c.id)) return false;
1389
- return true;
1390
- });
1391
- if (filtered.length !== arr.length) {
1392
- m.content = filtered.length === 0 ? "" : filtered.length === 1 && filtered[0]?.type === "text" ? filtered[0].text ?? "" : filtered;
1393
- }
1394
- }
1395
- if (hasToolCalls) {
1396
- m.tool_calls = m.tool_calls.map((tc) => ({ ...tc }));
1397
- }
1398
- if (hasAdditionalToolCalls) {
1399
- m.additional_kwargs = { ...m.additional_kwargs };
1400
- m.additional_kwargs.tool_calls = m.additional_kwargs.tool_calls.map((tc) => ({ ...tc }));
1401
- }
1402
- const remainingContentArr = Array.isArray(m.content) ? m.content : [];
1403
- const hasRemainingContentToolUse = remainingContentArr.some((c) => c?.type === "tool_use" && c?.id);
1404
- if (hasRemainingContentToolUse) {
1405
- m.content = remainingContentArr.map(
1406
- (c) => c && typeof c === "object" ? { ...c } : c
1407
- );
1408
- }
1409
- const idsInMessage = /* @__PURE__ */ new Set();
1410
- if (hasToolCalls) {
1411
- for (const tc of m.tool_calls) {
1412
- if (tc?.id) idsInMessage.add(tc.id);
1413
- }
1414
- }
1415
- if (hasRemainingContentToolUse) {
1416
- for (const c of m.content) {
1417
- if (c?.type === "tool_use" && c?.id) idsInMessage.add(c.id);
1418
- }
1419
- }
1420
- if (hasAdditionalToolCalls) {
1421
- for (const tc of m.additional_kwargs.tool_calls) {
1422
- if (tc?.id) idsInMessage.add(tc.id);
1423
- }
1424
- }
1425
- for (const id of idsInMessage) {
1426
- if (!usedIds.has(id)) {
1427
- usedIds.add(id);
1428
- continue;
1429
- }
1430
- const newId = `${id}_${Date.now()}_${counter++}`;
1431
- if (hasToolCalls) {
1432
- for (const tc of m.tool_calls) {
1433
- if (tc.id === id) tc.id = newId;
1434
- }
1435
- }
1436
- if (hasRemainingContentToolUse && Array.isArray(m.content)) {
1437
- for (const c of m.content) {
1438
- if (c?.type === "tool_use" && c.id === id) c.id = newId;
1439
- }
1440
- }
1441
- if (hasAdditionalToolCalls) {
1442
- for (const tc of m.additional_kwargs.tool_calls) {
1443
- if (tc.id === id) tc.id = newId;
1444
- }
1445
- }
1446
- for (let j = i + 1; j < msgs.length; j++) {
1447
- const next = msgs[j];
1448
- if (next?.role === "assistant") break;
1449
- if (next?.role === "tool" && next.tool_call_id === id) {
1450
- next.tool_call_id = newId;
1451
- }
1452
- if (Array.isArray(next?.content)) {
1453
- let contentCloned = false;
1454
- for (let k = 0; k < next.content.length; k++) {
1455
- const block = next.content[k];
1456
- if (block?.type === "tool_result" && block.tool_use_id === id) {
1457
- if (!contentCloned) {
1458
- next.content = next.content.map((x) => x && typeof x === "object" ? { ...x } : x);
1459
- contentCloned = true;
1460
- }
1461
- next.content[k].tool_use_id = newId;
1462
- }
1463
- }
1464
- }
1465
- }
1466
- usedIds.add(newId);
1467
- }
1468
- }
1469
- return msgs;
1470
- };
1471
- const normalizedMessages = ensureUniqueToolCallIds(
1472
- normalizeBedrockToolPairing([...state.messages])
1473
- );
1365
+ const normalizedMessages = normalizeBedrockToolPairing([...state.messages]);
1366
+ debugToolPairing(normalizedMessages);
1474
1367
  if (streamingEnabled && typeof modelWithTools.stream === "function") {
1475
1368
  let streamedText = "";
1476
1369
  let streamedMessage;
1477
- const streamResult = modelWithTools.stream(normalizedMessages, { signal: abortSignal, cancellationToken });
1478
- const stream = typeof streamResult?.then === "function" ? await streamResult : streamResult;
1479
- for await (const chunk of stream) {
1370
+ for await (const chunk of modelWithTools.stream(normalizedMessages, { signal: abortSignal, cancellationToken })) {
1480
1371
  if (cancellationToken && cancellationToken.isCancellationRequested || abortSignal?.aborted) {
1481
1372
  break;
1482
1373
  }
@@ -1521,7 +1412,7 @@ function createAgentCoreNode(opts) {
1521
1412
  ...state.messages,
1522
1413
  response
1523
1414
  ];
1524
- const rawUsage = response?.usage_metadata || response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
1415
+ const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
1525
1416
  const normalized = normalizeUsage(rawUsage);
1526
1417
  const modelName = getModelName(runtime.model || opts.model) || "unknown_model";
1527
1418
  const durationMs = Date.now() - start;
@@ -2517,6 +2408,7 @@ function createAgent(opts) {
2517
2408
  };
2518
2409
  let res;
2519
2410
  try {
2411
+ await startStreamingSession(traceSession, runtimeWithInvokeLimits);
2520
2412
  res = await runLoop(initial, config, emit);
2521
2413
  } catch (err) {
2522
2414
  await finalizeTraceSession(traceSession, {
@@ -2726,83 +2618,6 @@ function createAgentNode(opts) {
2726
2618
  };
2727
2619
  }
2728
2620
 
2729
- // src/utils/traceSections.ts
2730
- function formatMessageContent(content) {
2731
- if (content == null) return "";
2732
- if (typeof content === "string") return content;
2733
- if (Array.isArray(content)) {
2734
- return content.map((item) => {
2735
- if (typeof item === "string") return item;
2736
- if (item && typeof item === "object") {
2737
- if (typeof item.text === "string") return item.text;
2738
- if (typeof item.content === "string") return item.content;
2739
- try {
2740
- return JSON.stringify(item);
2741
- } catch {
2742
- return String(item);
2743
- }
2744
- }
2745
- try {
2746
- return JSON.stringify(item);
2747
- } catch {
2748
- return String(item);
2749
- }
2750
- }).filter(Boolean).join("\n");
2751
- }
2752
- if (typeof content === "object") {
2753
- if (typeof content.text === "string") return content.text;
2754
- if (typeof content.content === "string") return content.content;
2755
- try {
2756
- return JSON.stringify(content, null, 2);
2757
- } catch {
2758
- return String(content);
2759
- }
2760
- }
2761
- return String(content);
2762
- }
2763
- function buildSummarizationSections(opts) {
2764
- const sections = [];
2765
- sections.push({
2766
- kind: "summary",
2767
- label: "Context Summary",
2768
- content: opts.summaryText
2769
- });
2770
- const tokensSaved = opts.tokenCountBefore - opts.tokenCountAfter;
2771
- const reductionPct = opts.tokenCountBefore > 0 ? Math.round(tokensSaved / opts.tokenCountBefore * 100) : 0;
2772
- const metaData = {
2773
- messagesCompressed: opts.messagesCompressed,
2774
- tokenCountBefore: opts.tokenCountBefore,
2775
- tokenCountAfter: opts.tokenCountAfter,
2776
- tokensSaved,
2777
- reductionPercent: reductionPct
2778
- };
2779
- if (opts.inputTokens !== void 0) metaData.inputTokens = opts.inputTokens;
2780
- if (opts.outputTokens !== void 0) metaData.outputTokens = opts.outputTokens;
2781
- if (opts.cachedInputTokens !== void 0) metaData.cachedInputTokens = opts.cachedInputTokens;
2782
- if (opts.durationMs !== void 0) metaData.durationMs = opts.durationMs;
2783
- if (opts.previousSummary) metaData.previousSummaryLength = opts.previousSummary.length;
2784
- sections.push({
2785
- kind: "metadata",
2786
- label: "Summarization Stats",
2787
- data: metaData
2788
- });
2789
- if (Array.isArray(opts.promptMessages) && opts.promptMessages.length > 0) {
2790
- for (const msg of opts.promptMessages) {
2791
- const role = typeof msg?.role === "string" ? msg.role : "system";
2792
- const content = formatMessageContent(msg?.content ?? "");
2793
- if (content) {
2794
- sections.push({
2795
- kind: "message",
2796
- label: `Summarization Prompt (${role})`,
2797
- role,
2798
- content
2799
- });
2800
- }
2801
- }
2802
- }
2803
- return sections;
2804
- }
2805
-
2806
2621
  // src/nodes/contextSummarize.ts
2807
2622
  var systemMessage = (content) => ({ role: "system", content });
2808
2623
  var humanMessage = (content) => ({ role: "user", content });
@@ -2861,7 +2676,8 @@ function createContextSummarizeNode(opts) {
2861
2676
  if (compressableMessages.length === 0) {
2862
2677
  return {};
2863
2678
  }
2864
- const tokenCountBefore = countMessagesTokens(messages);
2679
+ 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");
2680
+ const tokenCountBefore = countApproxTokens(allTextBefore);
2865
2681
  const summaryPromptMaxTokens = config.summaryPromptMaxTokens;
2866
2682
  const availableTokensForConversation = summaryPromptMaxTokens - 500;
2867
2683
  const messageTexts = [];
@@ -2924,7 +2740,7 @@ Summary:`;
2924
2740
  durationMs = Date.now() - startTime;
2925
2741
  summaryText = typeof response.content === "string" ? response.content : Array.isArray(response.content) ? response.content.map((c) => c.text || "").join("") : JSON.stringify(response.content);
2926
2742
  outputTokensEstimate = countApproxTokens(summaryText);
2927
- const rawUsage = response?.usage_metadata || response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
2743
+ const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
2928
2744
  const normalized = normalizeUsage(rawUsage);
2929
2745
  if (normalized) {
2930
2746
  inputTokensActual = normalized.prompt_tokens;
@@ -2956,16 +2772,7 @@ Summary:`;
2956
2772
  inputTokens: inputTokensEstimate,
2957
2773
  outputTokens: 0,
2958
2774
  error: { message: err?.message || String(err), stack: err?.stack },
2959
- sections: buildSummarizationSections({
2960
- summaryText: "",
2961
- messagesCompressed: 0,
2962
- tokenCountBefore,
2963
- tokenCountAfter: tokenCountBefore,
2964
- inputTokens: inputTokensEstimate,
2965
- outputTokens: 0,
2966
- durationMs,
2967
- promptMessages: summaryPrompt
2968
- })
2775
+ messageList: sanitizeTracePayload(summaryPrompt)
2969
2776
  });
2970
2777
  return {};
2971
2778
  }
@@ -3019,7 +2826,8 @@ Summary:`;
3019
2826
  };
3020
2827
  const summaries = Array.isArray(state.summaries) ? [...state.summaries, summaryText] : [summaryText];
3021
2828
  const finalMessages = [...validatedMessages, assistantSummaryCall, toolSummaryResponse];
3022
- const tokenCountAfter = countMessagesTokens(finalMessages);
2829
+ 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");
2830
+ const tokenCountAfter = countApproxTokens(allTextAfter);
3023
2831
  const summarizationEvent = {
3024
2832
  type: "summarization",
3025
2833
  summary: summaryText,
@@ -3046,21 +2854,10 @@ Summary:`;
3046
2854
  outputTokens: outputTokensActual ?? outputTokensEstimate,
3047
2855
  cachedInputTokens,
3048
2856
  totalTokens: totalTokensActual,
3049
- sections: buildSummarizationSections({
3050
- summaryText,
3051
- previousSummary: previousSummary || void 0,
3052
- messagesCompressed: compressableMessages.length,
3053
- tokenCountBefore,
3054
- tokenCountAfter,
3055
- inputTokens: inputTokensActual ?? inputTokensEstimate,
3056
- outputTokens: outputTokensActual ?? outputTokensEstimate,
3057
- cachedInputTokens,
3058
- durationMs,
3059
- promptMessages: sanitizeTracePayload([
3060
- ...summaryPrompt,
3061
- { role: "assistant", content: summaryText, name: "summarization_result" }
3062
- ])
3063
- }),
2857
+ messageList: sanitizeTracePayload([
2858
+ ...summaryPrompt,
2859
+ { role: "assistant", content: summaryText, name: "summarization_result" }
2860
+ ]),
3064
2861
  debug: {
3065
2862
  messagesCompressed: compressableMessages.length,
3066
2863
  tokenCountBefore,
@@ -3184,8 +2981,30 @@ function needsSummarization(state, opts, summarizationEnabled) {
3184
2981
  maxTok = 5e4;
3185
2982
  }
3186
2983
  try {
3187
- const tokenCount = countMessagesTokens(state.messages || []);
3188
- return tokenCount > maxTok;
2984
+ const allText = (state.messages || []).map((m) => {
2985
+ if (typeof m.content === "string") return m.content;
2986
+ if (Array.isArray(m.content)) {
2987
+ return m.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? JSON.stringify(c)).join("");
2988
+ }
2989
+ if (m.content && typeof m.content === "object") {
2990
+ return JSON.stringify(m.content);
2991
+ }
2992
+ return "";
2993
+ }).join("\n");
2994
+ const tokenCount = countApproxTokens(allText);
2995
+ const needsSum = tokenCount > maxTok;
2996
+ if (process.env.DEBUG_SUMMARIZATION) {
2997
+ const msgCount = (state.messages || []).length;
2998
+ const toolMsgs = (state.messages || []).filter((m) => m.role === "tool");
2999
+ const toolDetails = toolMsgs.map((m, i) => {
3000
+ const contentStr = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
3001
+ return `[${i}] id:${m.tool_call_id?.slice(-8) || "none"} len:${contentStr.length} preview:"${contentStr.slice(0, 30)}..."`;
3002
+ });
3003
+ console.log(`[Summarization] Messages: ${msgCount}, Tool messages: ${toolMsgs.length}`);
3004
+ toolDetails.forEach((d) => console.log(` ${d}`));
3005
+ console.log(`[Summarization] Token count: ${tokenCount}, Max: ${maxTok}, Needs summarization: ${needsSum}`);
3006
+ }
3007
+ return needsSum;
3189
3008
  } catch (e) {
3190
3009
  return false;
3191
3010
  }