@inkeep/agents-run-api 0.0.0-dev-20260105192809 → 0.0.0-dev-20260105194521

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.
@@ -0,0 +1,32 @@
1
+ import { BaseCompressor, CompressionConfig, CompressionResult } from "./BaseCompressor.js";
2
+ import { ModelSettings } from "@inkeep/agents-core";
3
+
4
+ //#region src/services/ConversationCompressor.d.ts
5
+
6
+ /**
7
+ * Conversation-level compressor
8
+ * Compresses entire conversations for long-term storage or analysis
9
+ */
10
+ declare class ConversationCompressor extends BaseCompressor {
11
+ constructor(sessionId: string, conversationId: string, tenantId: string, projectId: string, config?: CompressionConfig, summarizerModel?: ModelSettings, baseModel?: ModelSettings);
12
+ /**
13
+ * Get compression type for this compressor
14
+ */
15
+ getCompressionType(): 'conversation_level';
16
+ /**
17
+ * Check if compression is needed based on total context size exceeding conversation limits
18
+ */
19
+ isCompressionNeeded(messages: any[]): boolean;
20
+ /**
21
+ * Perform conversation-level compression
22
+ * Unlike mid-generation, this compresses ALL messages in the conversation
23
+ */
24
+ compress(messages: any[]): Promise<CompressionResult>;
25
+ /**
26
+ * Override createConversationSummary for conversation-level compression
27
+ * Uses specialized conversation history distillation instead of the base implementation
28
+ */
29
+ protected createConversationSummary(messages: any[], toolCallToArtifactMap: Record<string, string>): Promise<any>;
30
+ }
31
+ //#endregion
32
+ export { ConversationCompressor };
@@ -0,0 +1,91 @@
1
+ import { getLogger } from "../logger.js";
2
+ import { distillConversationHistory } from "../tools/distill-conversation-history-tool.js";
3
+ import { BaseCompressor, getModelAwareCompressionConfig } from "./BaseCompressor.js";
4
+
5
+ //#region src/services/ConversationCompressor.ts
6
+ const logger = getLogger("ConversationCompressor");
7
+ /**
8
+ * Conversation-level compressor
9
+ * Compresses entire conversations for long-term storage or analysis
10
+ */
11
+ var ConversationCompressor = class extends BaseCompressor {
12
+ constructor(sessionId, conversationId, tenantId, projectId, config, summarizerModel, baseModel) {
13
+ const compressionConfig = config || getModelAwareCompressionConfig(summarizerModel, .5);
14
+ super(sessionId, conversationId, tenantId, projectId, compressionConfig, summarizerModel, baseModel);
15
+ }
16
+ /**
17
+ * Get compression type for this compressor
18
+ */
19
+ getCompressionType() {
20
+ return "conversation_level";
21
+ }
22
+ /**
23
+ * Check if compression is needed based on total context size exceeding conversation limits
24
+ */
25
+ isCompressionNeeded(messages) {
26
+ const contextSize = this.calculateContextSize(messages);
27
+ const remaining = this.config.hardLimit - contextSize;
28
+ const needsCompression = remaining <= this.config.safetyBuffer;
29
+ logger.debug({
30
+ sessionId: this.sessionId,
31
+ contextSize,
32
+ hardLimit: this.config.hardLimit,
33
+ safetyBuffer: this.config.safetyBuffer,
34
+ remaining,
35
+ needsCompression
36
+ }, "Checking conversation compression criteria");
37
+ return needsCompression;
38
+ }
39
+ /**
40
+ * Perform conversation-level compression
41
+ * Unlike mid-generation, this compresses ALL messages in the conversation
42
+ */
43
+ async compress(messages) {
44
+ const contextSizeBefore = this.calculateContextSize(messages);
45
+ logger.info({
46
+ sessionId: this.sessionId,
47
+ messageCount: messages.length,
48
+ contextSize: contextSizeBefore
49
+ }, "CONVERSATION COMPRESSION: Starting compression");
50
+ const toolCallToArtifactMap = await this.saveToolResultsAsArtifacts(messages, 0);
51
+ const summary = await this.createConversationSummary(messages, toolCallToArtifactMap);
52
+ const contextSizeAfter = this.estimateTokens(JSON.stringify(summary));
53
+ this.recordCompressionEvent({
54
+ reason: "automatic",
55
+ messageCount: messages.length,
56
+ artifactCount: Object.keys(toolCallToArtifactMap).length,
57
+ contextSizeBefore,
58
+ contextSizeAfter,
59
+ compressionType: this.getCompressionType()
60
+ });
61
+ logger.info({
62
+ sessionId: this.sessionId,
63
+ artifactsCreated: Object.keys(toolCallToArtifactMap).length,
64
+ messageCount: messages.length,
65
+ contextSizeBefore,
66
+ contextSizeAfter,
67
+ compressionRatio: contextSizeAfter / contextSizeBefore,
68
+ artifactIds: Object.values(toolCallToArtifactMap)
69
+ }, "CONVERSATION COMPRESSION: Compression completed successfully");
70
+ return {
71
+ artifactIds: Object.values(toolCallToArtifactMap),
72
+ summary
73
+ };
74
+ }
75
+ /**
76
+ * Override createConversationSummary for conversation-level compression
77
+ * Uses specialized conversation history distillation instead of the base implementation
78
+ */
79
+ async createConversationSummary(messages, toolCallToArtifactMap) {
80
+ if (!this.summarizerModel) throw new Error("Summarizer model is required for conversation history compression");
81
+ return await distillConversationHistory({
82
+ messages,
83
+ conversationId: this.conversationId,
84
+ summarizerModel: this.summarizerModel,
85
+ toolCallToArtifactMap
86
+ });
87
+ }
88
+ };
89
+
90
+ //#endregion
91
+ export { ConversationCompressor };
@@ -1,91 +1,63 @@
1
+ import { BaseCompressor, CompressionConfig, CompressionResult } from "./BaseCompressor.js";
1
2
  import { ModelSettings } from "@inkeep/agents-core";
2
3
 
3
4
  //#region src/services/MidGenerationCompressor.d.ts
4
- interface CompressionConfig {
5
- hardLimit: number;
6
- safetyBuffer: number;
7
- enabled?: boolean;
8
- }
9
- /**
10
- * Get compression config from environment variables
11
- */
12
- declare function getCompressionConfigFromEnv(): CompressionConfig;
5
+
13
6
  /**
14
- * Simple mid-generation compressor
15
- * Compresses context when generate() steps get too large
7
+ * Mid-generation compressor
8
+ * Compresses context when generate() steps get too large with manual compression support
16
9
  */
17
- declare class MidGenerationCompressor {
18
- private sessionId;
19
- private conversationId;
20
- private tenantId;
21
- private projectId;
22
- private config;
23
- private summarizerModel?;
24
- private baseModel?;
10
+ declare class MidGenerationCompressor extends BaseCompressor {
25
11
  private shouldCompress;
26
- private processedToolCalls;
27
12
  private lastProcessedMessageIndex;
28
- private cumulativeSummary;
29
- constructor(sessionId: string, conversationId: string, tenantId: string, projectId: string, config: CompressionConfig, summarizerModel?: ModelSettings | undefined, baseModel?: ModelSettings | undefined);
30
- /**
31
- * Get the hard limit for compression decisions
32
- */
33
- getHardLimit(): number;
34
- /**
35
- * Estimate tokens (4 chars = 1 token)
36
- */
37
- private estimateTokens;
13
+ constructor(sessionId: string, conversationId: string, tenantId: string, projectId: string, config?: CompressionConfig, summarizerModel?: ModelSettings, baseModel?: ModelSettings);
38
14
  /**
39
- * Calculate total context size
15
+ * Get compression type for this compressor
40
16
  */
41
- private calculateContextSize;
17
+ getCompressionType(): 'mid_generation';
42
18
  /**
43
19
  * Manual compression request from LLM tool
44
20
  */
45
21
  requestManualCompression(reason?: string): void;
46
22
  /**
47
23
  * Check if compression is needed (either automatic or manual)
24
+ * Supports manual compression requests unique to mid-generation
48
25
  */
49
26
  isCompressionNeeded(messages: any[]): boolean;
50
27
  /**
51
- * Perform compression: save all tool results as artifacts and create summary
52
- */
53
- compress(messages: any[]): Promise<{
54
- artifactIds: string[];
55
- summary: any;
56
- }>;
57
- /**
58
- * 1. Save NEW tool results as artifacts (only process messages since last compression)
28
+ * Perform mid-generation compression with incremental processing
29
+ * Uses base class functionality with mid-generation specific logic
59
30
  */
60
- private saveToolResultsAsArtifacts;
61
- /**
62
- * 3. Create conversation summary with artifact references
63
- */
64
- private createConversationSummary;
65
- /**
66
- * Extract text messages and convert tool calls to descriptive text
67
- * Avoids API tool-call/tool-result pairing issues while preserving context
68
- */
69
- private extractTextMessages;
70
- /**
71
- * Check if tool result data is effectively empty
72
- */
73
- private isEmpty;
74
- /**
75
- * Recursively remove _structureHints from an object
76
- */
77
- private removeStructureHints;
31
+ compress(messages: any[]): Promise<CompressionResult>;
78
32
  /**
79
33
  * Get current state for debugging
80
34
  */
81
35
  getState(): {
82
36
  shouldCompress: boolean;
37
+ lastProcessedMessageIndex: number;
83
38
  config: CompressionConfig;
39
+ processedToolCalls: string[];
40
+ cumulativeSummary: {
41
+ type: "conversation_summary_v1";
42
+ high_level: string;
43
+ user_intent: string;
44
+ decisions: string[];
45
+ open_questions: string[];
46
+ next_steps: {
47
+ for_agent: string[];
48
+ for_user: string[];
49
+ };
50
+ session_id?: string | null | undefined;
51
+ related_artifacts?: {
52
+ id: string;
53
+ name: string;
54
+ tool_name: string;
55
+ tool_call_id: string;
56
+ content_type: string;
57
+ key_findings: string[];
58
+ }[] | undefined;
59
+ } | null;
84
60
  };
85
- /**
86
- * Get the current compression summary
87
- */
88
- getCompressionSummary(): any;
89
61
  }
90
62
  //#endregion
91
- export { CompressionConfig, MidGenerationCompressor, getCompressionConfigFromEnv };
63
+ export { MidGenerationCompressor };
@@ -1,73 +1,24 @@
1
1
  import { getLogger } from "../logger.js";
2
- import { agentSessionManager } from "./AgentSession.js";
3
- import { distillConversation } from "../tools/distill-conversation-tool.js";
4
- import { randomUUID } from "crypto";
2
+ import { BaseCompressor, getModelAwareCompressionConfig } from "./BaseCompressor.js";
5
3
 
6
4
  //#region src/services/MidGenerationCompressor.ts
7
5
  const logger = getLogger("MidGenerationCompressor");
8
6
  /**
9
- * Get compression config from environment variables
7
+ * Mid-generation compressor
8
+ * Compresses context when generate() steps get too large with manual compression support
10
9
  */
11
- function getCompressionConfigFromEnv() {
12
- return {
13
- hardLimit: parseInt(process.env.AGENTS_COMPRESSION_HARD_LIMIT || "120000"),
14
- safetyBuffer: parseInt(process.env.AGENTS_COMPRESSION_SAFETY_BUFFER || "20000"),
15
- enabled: process.env.AGENTS_COMPRESSION_ENABLED !== "false"
16
- };
17
- }
18
- /**
19
- * Simple mid-generation compressor
20
- * Compresses context when generate() steps get too large
21
- */
22
- var MidGenerationCompressor = class {
10
+ var MidGenerationCompressor = class extends BaseCompressor {
23
11
  shouldCompress = false;
24
- processedToolCalls = /* @__PURE__ */ new Set();
25
12
  lastProcessedMessageIndex = 0;
26
- cumulativeSummary = null;
27
13
  constructor(sessionId, conversationId, tenantId, projectId, config, summarizerModel, baseModel) {
28
- this.sessionId = sessionId;
29
- this.conversationId = conversationId;
30
- this.tenantId = tenantId;
31
- this.projectId = projectId;
32
- this.config = config;
33
- this.summarizerModel = summarizerModel;
34
- this.baseModel = baseModel;
35
- }
36
- /**
37
- * Get the hard limit for compression decisions
38
- */
39
- getHardLimit() {
40
- return this.config.hardLimit;
41
- }
42
- /**
43
- * Estimate tokens (4 chars = 1 token)
44
- */
45
- estimateTokens(content) {
46
- const text = typeof content === "string" ? content : JSON.stringify(content);
47
- return Math.ceil(text.length / 4);
14
+ const compressionConfig = config || getModelAwareCompressionConfig(summarizerModel);
15
+ super(sessionId, conversationId, tenantId, projectId, compressionConfig, summarizerModel, baseModel);
48
16
  }
49
17
  /**
50
- * Calculate total context size
18
+ * Get compression type for this compressor
51
19
  */
52
- calculateContextSize(messages) {
53
- return messages.reduce((total, msg) => {
54
- let msgTokens = 0;
55
- if (Array.isArray(msg.content)) {
56
- for (const block of msg.content) if (block.type === "text") msgTokens += this.estimateTokens(block.text || "");
57
- else if (block.type === "tool-call") msgTokens += this.estimateTokens(JSON.stringify({
58
- toolCallId: block.toolCallId,
59
- toolName: block.toolName,
60
- input: block.input
61
- }));
62
- else if (block.type === "tool-result") msgTokens += this.estimateTokens(JSON.stringify({
63
- toolCallId: block.toolCallId,
64
- toolName: block.toolName,
65
- output: block.output
66
- }));
67
- } else if (typeof msg.content === "string") msgTokens += this.estimateTokens(msg.content);
68
- else if (msg.content) msgTokens += this.estimateTokens(JSON.stringify(msg.content));
69
- return total + msgTokens;
70
- }, 0);
20
+ getCompressionType() {
21
+ return "mid_generation";
71
22
  }
72
23
  /**
73
24
  * Manual compression request from LLM tool
@@ -81,14 +32,27 @@ var MidGenerationCompressor = class {
81
32
  }
82
33
  /**
83
34
  * Check if compression is needed (either automatic or manual)
35
+ * Supports manual compression requests unique to mid-generation
84
36
  */
85
37
  isCompressionNeeded(messages) {
86
38
  if (this.shouldCompress) return true;
87
39
  const contextSize = this.calculateContextSize(messages);
88
- return this.config.hardLimit - contextSize <= this.config.safetyBuffer;
40
+ const remaining = this.config.hardLimit - contextSize;
41
+ const needsCompression = remaining <= this.config.safetyBuffer;
42
+ logger.debug({
43
+ sessionId: this.sessionId,
44
+ contextSize,
45
+ hardLimit: this.config.hardLimit,
46
+ safetyBuffer: this.config.safetyBuffer,
47
+ remaining,
48
+ needsCompression,
49
+ manualRequest: this.shouldCompress
50
+ }, "Checking mid-generation compression criteria");
51
+ return needsCompression;
89
52
  }
90
53
  /**
91
- * Perform compression: save all tool results as artifacts and create summary
54
+ * Perform mid-generation compression with incremental processing
55
+ * Uses base class functionality with mid-generation specific logic
92
56
  */
93
57
  async compress(messages) {
94
58
  const contextSizeBefore = this.calculateContextSize(messages);
@@ -96,280 +60,45 @@ var MidGenerationCompressor = class {
96
60
  sessionId: this.sessionId,
97
61
  messageCount: messages.length,
98
62
  contextSize: contextSizeBefore
99
- }, "COMPRESSION: Starting compression");
100
- const toolResultCount = messages.reduce((count, msg) => {
101
- if (Array.isArray(msg.content)) return count + msg.content.filter((block) => block.type === "tool-result").length;
102
- return count;
103
- }, 0);
104
- logger.debug({ toolResultCount }, "Tool results found for compression");
105
- const toolCallToArtifactMap = await this.saveToolResultsAsArtifacts(messages);
63
+ }, "MID-GENERATION COMPRESSION: Starting compression");
64
+ const toolCallToArtifactMap = await this.saveToolResultsAsArtifacts(messages, this.lastProcessedMessageIndex);
106
65
  const summary = await this.createConversationSummary(messages, toolCallToArtifactMap);
107
66
  const contextSizeAfter = this.estimateTokens(JSON.stringify(summary));
108
- const session = agentSessionManager.getSession(this.sessionId);
109
- if (session) {
110
- const wasManualRequest = this.shouldCompress;
111
- session.recordEvent("compression", this.sessionId, {
112
- reason: wasManualRequest ? "manual" : "automatic",
113
- messageCount: messages.length,
114
- artifactCount: Object.keys(toolCallToArtifactMap).length,
115
- contextSizeBefore,
116
- contextSizeAfter,
117
- compressionType: "mid_generation"
118
- });
119
- }
67
+ this.recordCompressionEvent({
68
+ reason: this.shouldCompress ? "manual" : "automatic",
69
+ messageCount: messages.length,
70
+ artifactCount: Object.keys(toolCallToArtifactMap).length,
71
+ contextSizeBefore,
72
+ contextSizeAfter,
73
+ compressionType: this.getCompressionType()
74
+ });
120
75
  this.shouldCompress = false;
76
+ this.lastProcessedMessageIndex = messages.length;
121
77
  logger.info({
122
78
  sessionId: this.sessionId,
123
79
  artifactsCreated: Object.keys(toolCallToArtifactMap).length,
124
80
  messageCount: messages.length,
125
81
  contextSizeBefore,
126
82
  contextSizeAfter,
83
+ compressionRatio: contextSizeAfter / contextSizeBefore,
127
84
  artifactIds: Object.values(toolCallToArtifactMap)
128
- }, "COMPRESSION: Compression completed successfully");
85
+ }, "MID-GENERATION COMPRESSION: Compression completed successfully");
129
86
  return {
130
87
  artifactIds: Object.values(toolCallToArtifactMap),
131
88
  summary
132
89
  };
133
90
  }
134
91
  /**
135
- * 1. Save NEW tool results as artifacts (only process messages since last compression)
136
- */
137
- async saveToolResultsAsArtifacts(messages) {
138
- const session = agentSessionManager.getSession(this.sessionId);
139
- if (!session) throw new Error(`No session found: ${this.sessionId}`);
140
- const toolCallToArtifactMap = {};
141
- const newMessages = messages.slice(this.lastProcessedMessageIndex);
142
- logger.debug({
143
- totalMessages: messages.length,
144
- newMessages: newMessages.length,
145
- startIndex: this.lastProcessedMessageIndex
146
- }, "Starting compression artifact processing");
147
- for (const message of newMessages) if (Array.isArray(message.content)) {
148
- for (const block of message.content) if (block.type === "tool-result") {
149
- if (block.toolName === "get_reference_artifact" || block.toolName === "thinking_complete") {
150
- logger.debug({
151
- toolCallId: block.toolCallId,
152
- toolName: block.toolName
153
- }, "Skipping special tool - not creating artifacts");
154
- this.processedToolCalls.add(block.toolCallId);
155
- continue;
156
- }
157
- if (this.processedToolCalls.has(block.toolCallId)) {
158
- logger.debug({
159
- toolCallId: block.toolCallId,
160
- toolName: block.toolName
161
- }, "Skipping already processed tool call");
162
- continue;
163
- }
164
- const artifactId = `compress_${block.toolName || "tool"}_${block.toolCallId || Date.now()}_${randomUUID().slice(0, 8)}`;
165
- logger.debug({
166
- artifactId,
167
- toolName: block.toolName,
168
- toolCallId: block.toolCallId
169
- }, "Saving compression artifact");
170
- let toolInput = null;
171
- if (Array.isArray(message.content)) toolInput = message.content.find((b) => b.type === "tool-call" && b.toolCallId === block.toolCallId)?.input;
172
- const cleanToolResult = this.removeStructureHints(block.output);
173
- const toolResultData = {
174
- toolName: block.toolName,
175
- toolInput,
176
- toolResult: cleanToolResult,
177
- compressedAt: (/* @__PURE__ */ new Date()).toISOString()
178
- };
179
- if (this.isEmpty(toolResultData)) {
180
- logger.debug({
181
- toolName: block.toolName,
182
- toolCallId: block.toolCallId
183
- }, "Skipping empty tool result");
184
- continue;
185
- }
186
- const artifactData = {
187
- artifactId,
188
- taskId: `task_${this.conversationId}-${this.sessionId}`,
189
- toolCallId: block.toolCallId,
190
- artifactType: "tool_result",
191
- pendingGeneration: true,
192
- tenantId: this.tenantId,
193
- projectId: this.projectId,
194
- contextId: this.conversationId,
195
- subAgentId: this.sessionId,
196
- metadata: {
197
- toolCallId: block.toolCallId,
198
- toolName: block.toolName,
199
- compressionReason: "mid_generation_context_limit"
200
- },
201
- summaryData: {
202
- toolName: block.toolName,
203
- note: "Compressed tool result - see full data for details"
204
- },
205
- data: toolResultData
206
- };
207
- const fullData = artifactData.data;
208
- if (!(fullData && typeof fullData === "object" && Object.keys(fullData).length > 0 && fullData.toolResult && (typeof fullData.toolResult !== "object" || Object.keys(fullData.toolResult).length > 0))) {
209
- logger.debug({
210
- artifactId,
211
- toolName: block.toolName,
212
- toolCallId: block.toolCallId
213
- }, "Skipping empty compression artifact");
214
- continue;
215
- }
216
- session.recordEvent("artifact_saved", this.sessionId, artifactData);
217
- this.processedToolCalls.add(block.toolCallId);
218
- toolCallToArtifactMap[block.toolCallId] = artifactId;
219
- }
220
- }
221
- this.lastProcessedMessageIndex = messages.length;
222
- logger.debug({
223
- totalArtifactsCreated: Object.keys(toolCallToArtifactMap).length,
224
- newMessageIndex: this.lastProcessedMessageIndex
225
- }, "Compression artifact processing completed");
226
- return toolCallToArtifactMap;
227
- }
228
- /**
229
- * 3. Create conversation summary with artifact references
230
- */
231
- async createConversationSummary(messages, toolCallToArtifactMap) {
232
- const textMessages = this.extractTextMessages(messages, toolCallToArtifactMap);
233
- logger.debug({
234
- sessionId: this.sessionId,
235
- messageCount: messages.length,
236
- textMessageCount: textMessages.length,
237
- artifactCount: Object.keys(toolCallToArtifactMap).length,
238
- sampleMessages: messages.slice(0, 2).map((m) => ({
239
- role: m.role,
240
- contentType: typeof m.content,
241
- contentPreview: typeof m.content === "string" ? m.content.substring(0, 100) : "array/object"
242
- }))
243
- }, "Starting distillation with debug info");
244
- const summary = await distillConversation({
245
- messages,
246
- conversationId: this.conversationId,
247
- currentSummary: this.cumulativeSummary,
248
- summarizerModel: this.summarizerModel,
249
- toolCallToArtifactMap
250
- });
251
- this.cumulativeSummary = summary;
252
- logger.debug({
253
- sessionId: this.sessionId,
254
- summaryGenerated: !!summary,
255
- summaryHighLevel: summary?.high_level,
256
- artifactsCount: summary?.related_artifacts?.length || 0
257
- }, "Distillation completed");
258
- return {
259
- text_messages: textMessages,
260
- summary
261
- };
262
- }
263
- /**
264
- * Extract text messages and convert tool calls to descriptive text
265
- * Avoids API tool-call/tool-result pairing issues while preserving context
266
- */
267
- extractTextMessages(messages, toolCallToArtifactMap) {
268
- const textMessages = [];
269
- const toolCallPairs = /* @__PURE__ */ new Map();
270
- for (const message of messages) if (Array.isArray(message.content)) {
271
- for (const block of message.content) if (block.type === "tool-call") if (!toolCallPairs.has(block.toolCallId)) toolCallPairs.set(block.toolCallId, {
272
- call: block,
273
- result: null
274
- });
275
- else toolCallPairs.get(block.toolCallId).call = block;
276
- else if (block.type === "tool-result") if (!toolCallPairs.has(block.toolCallId)) toolCallPairs.set(block.toolCallId, {
277
- call: null,
278
- result: block
279
- });
280
- else toolCallPairs.get(block.toolCallId).result = block;
281
- }
282
- for (const message of messages) if (message.role === "assistant" && typeof message.content === "string") textMessages.push({
283
- role: message.role,
284
- content: message.content
285
- });
286
- else if (message.role === "assistant" && Array.isArray(message.content)) {
287
- const textParts = [];
288
- const toolCallsInMessage = /* @__PURE__ */ new Set();
289
- const preservedBlocks = [];
290
- for (const block of message.content) if (block.type === "text") textParts.push(block.text);
291
- else if (block.type === "tool-call" && block.toolName === "thinking_complete") {} else if (block.type === "tool-call") toolCallsInMessage.add(block.toolCallId);
292
- for (const toolCallId of toolCallsInMessage) {
293
- const pair = toolCallPairs.get(toolCallId);
294
- const artifactId = toolCallToArtifactMap[toolCallId];
295
- if (pair?.call) {
296
- const args = JSON.stringify(pair.call.input);
297
- const artifactText = artifactId ? ` Results compressed into artifact: ${artifactId}.` : " Results were compressed but not saved.";
298
- textParts.push(`I called ${pair.call.toolName}(${args}).${artifactText}`);
299
- }
300
- }
301
- if (preservedBlocks.length > 0 && textParts.length > 0) {
302
- const content = [...preservedBlocks];
303
- if (textParts.length > 0) content.push({
304
- type: "text",
305
- text: textParts.join("\n\n")
306
- });
307
- textMessages.push({
308
- role: message.role,
309
- content
310
- });
311
- } else if (preservedBlocks.length > 0) textMessages.push({
312
- role: message.role,
313
- content: preservedBlocks
314
- });
315
- else if (textParts.length > 0) textMessages.push({
316
- role: message.role,
317
- content: textParts.join("\n\n")
318
- });
319
- }
320
- return textMessages;
321
- }
322
- /**
323
- * Check if tool result data is effectively empty
324
- */
325
- isEmpty(toolResultData) {
326
- if (!toolResultData || typeof toolResultData !== "object") return true;
327
- const { toolResult } = toolResultData;
328
- if (!toolResult) return true;
329
- if (typeof toolResult === "object" && !Array.isArray(toolResult)) {
330
- const keys = Object.keys(toolResult);
331
- if (keys.length === 0) return true;
332
- return keys.every((key) => {
333
- const value = toolResult[key];
334
- if (value === null || value === void 0 || value === "") return true;
335
- if (Array.isArray(value) && value.length === 0) return true;
336
- if (typeof value === "object" && Object.keys(value).length === 0) return true;
337
- return false;
338
- });
339
- }
340
- if (Array.isArray(toolResult) && toolResult.length === 0) return true;
341
- if (typeof toolResult === "string" && toolResult.trim() === "") return true;
342
- return false;
343
- }
344
- /**
345
- * Recursively remove _structureHints from an object
346
- */
347
- removeStructureHints(obj) {
348
- if (obj === null || obj === void 0) return obj;
349
- if (Array.isArray(obj)) return obj.map((item) => this.removeStructureHints(item));
350
- if (typeof obj === "object") {
351
- const cleaned = {};
352
- for (const [key, value] of Object.entries(obj)) if (key !== "_structureHints") cleaned[key] = this.removeStructureHints(value);
353
- return cleaned;
354
- }
355
- return obj;
356
- }
357
- /**
358
92
  * Get current state for debugging
359
93
  */
360
94
  getState() {
361
95
  return {
96
+ ...super.getState(),
362
97
  shouldCompress: this.shouldCompress,
363
- config: this.config
98
+ lastProcessedMessageIndex: this.lastProcessedMessageIndex
364
99
  };
365
100
  }
366
- /**
367
- * Get the current compression summary
368
- */
369
- getCompressionSummary() {
370
- return this.cumulativeSummary;
371
- }
372
101
  };
373
102
 
374
103
  //#endregion
375
- export { MidGenerationCompressor, getCompressionConfigFromEnv };
104
+ export { MidGenerationCompressor };