@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.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;
@@ -2726,83 +2617,6 @@ function createAgentNode(opts) {
2726
2617
  };
2727
2618
  }
2728
2619
 
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
2620
  // src/nodes/contextSummarize.ts
2807
2621
  var systemMessage = (content) => ({ role: "system", content });
2808
2622
  var humanMessage = (content) => ({ role: "user", content });
@@ -2861,7 +2675,8 @@ function createContextSummarizeNode(opts) {
2861
2675
  if (compressableMessages.length === 0) {
2862
2676
  return {};
2863
2677
  }
2864
- const tokenCountBefore = countMessagesTokens(messages);
2678
+ 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");
2679
+ const tokenCountBefore = countApproxTokens(allTextBefore);
2865
2680
  const summaryPromptMaxTokens = config.summaryPromptMaxTokens;
2866
2681
  const availableTokensForConversation = summaryPromptMaxTokens - 500;
2867
2682
  const messageTexts = [];
@@ -2924,7 +2739,7 @@ Summary:`;
2924
2739
  durationMs = Date.now() - startTime;
2925
2740
  summaryText = typeof response.content === "string" ? response.content : Array.isArray(response.content) ? response.content.map((c) => c.text || "").join("") : JSON.stringify(response.content);
2926
2741
  outputTokensEstimate = countApproxTokens(summaryText);
2927
- const rawUsage = response?.usage_metadata || response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
2742
+ const rawUsage = response?.usage || response?.response_metadata?.token_usage || response?.response_metadata?.tokenUsage || response?.response_metadata?.usage;
2928
2743
  const normalized = normalizeUsage(rawUsage);
2929
2744
  if (normalized) {
2930
2745
  inputTokensActual = normalized.prompt_tokens;
@@ -2956,16 +2771,7 @@ Summary:`;
2956
2771
  inputTokens: inputTokensEstimate,
2957
2772
  outputTokens: 0,
2958
2773
  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
- })
2774
+ messageList: sanitizeTracePayload(summaryPrompt)
2969
2775
  });
2970
2776
  return {};
2971
2777
  }
@@ -3019,7 +2825,8 @@ Summary:`;
3019
2825
  };
3020
2826
  const summaries = Array.isArray(state.summaries) ? [...state.summaries, summaryText] : [summaryText];
3021
2827
  const finalMessages = [...validatedMessages, assistantSummaryCall, toolSummaryResponse];
3022
- const tokenCountAfter = countMessagesTokens(finalMessages);
2828
+ 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");
2829
+ const tokenCountAfter = countApproxTokens(allTextAfter);
3023
2830
  const summarizationEvent = {
3024
2831
  type: "summarization",
3025
2832
  summary: summaryText,
@@ -3046,21 +2853,10 @@ Summary:`;
3046
2853
  outputTokens: outputTokensActual ?? outputTokensEstimate,
3047
2854
  cachedInputTokens,
3048
2855
  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
- }),
2856
+ messageList: sanitizeTracePayload([
2857
+ ...summaryPrompt,
2858
+ { role: "assistant", content: summaryText, name: "summarization_result" }
2859
+ ]),
3064
2860
  debug: {
3065
2861
  messagesCompressed: compressableMessages.length,
3066
2862
  tokenCountBefore,
@@ -3184,8 +2980,30 @@ function needsSummarization(state, opts, summarizationEnabled) {
3184
2980
  maxTok = 5e4;
3185
2981
  }
3186
2982
  try {
3187
- const tokenCount = countMessagesTokens(state.messages || []);
3188
- return tokenCount > maxTok;
2983
+ const allText = (state.messages || []).map((m) => {
2984
+ if (typeof m.content === "string") return m.content;
2985
+ if (Array.isArray(m.content)) {
2986
+ return m.content.map((c) => typeof c === "string" ? c : c?.text ?? c?.content ?? JSON.stringify(c)).join("");
2987
+ }
2988
+ if (m.content && typeof m.content === "object") {
2989
+ return JSON.stringify(m.content);
2990
+ }
2991
+ return "";
2992
+ }).join("\n");
2993
+ const tokenCount = countApproxTokens(allText);
2994
+ const needsSum = tokenCount > maxTok;
2995
+ if (process.env.DEBUG_SUMMARIZATION) {
2996
+ const msgCount = (state.messages || []).length;
2997
+ const toolMsgs = (state.messages || []).filter((m) => m.role === "tool");
2998
+ const toolDetails = toolMsgs.map((m, i) => {
2999
+ const contentStr = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
3000
+ return `[${i}] id:${m.tool_call_id?.slice(-8) || "none"} len:${contentStr.length} preview:"${contentStr.slice(0, 30)}..."`;
3001
+ });
3002
+ console.log(`[Summarization] Messages: ${msgCount}, Tool messages: ${toolMsgs.length}`);
3003
+ toolDetails.forEach((d) => console.log(` ${d}`));
3004
+ console.log(`[Summarization] Token count: ${tokenCount}, Max: ${maxTok}, Needs summarization: ${needsSum}`);
3005
+ }
3006
+ return needsSum;
3189
3007
  } catch (e) {
3190
3008
  return false;
3191
3009
  }