@inkeep/agents-run-api 0.39.5 → 0.40.0

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.
Files changed (180) hide show
  1. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/system-prompt.js +5 -0
  2. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/thinking-preparation.js +5 -0
  3. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/tool.js +5 -0
  4. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/data-component.js +5 -0
  5. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/data-components.js +5 -0
  6. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/system-prompt.js +5 -0
  7. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/shared/artifact-retrieval-guidance.js +5 -0
  8. package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/shared/artifact.js +5 -0
  9. package/dist/a2a/client.d.ts +184 -0
  10. package/dist/a2a/client.js +510 -0
  11. package/dist/a2a/handlers.d.ts +7 -0
  12. package/dist/a2a/handlers.js +560 -0
  13. package/dist/a2a/transfer.d.ts +22 -0
  14. package/dist/a2a/transfer.js +46 -0
  15. package/dist/a2a/types.d.ts +79 -0
  16. package/dist/a2a/types.js +22 -0
  17. package/dist/agents/Agent.d.ts +266 -0
  18. package/dist/agents/Agent.js +1927 -0
  19. package/dist/agents/ModelFactory.d.ts +63 -0
  20. package/dist/agents/ModelFactory.js +194 -0
  21. package/dist/agents/SystemPromptBuilder.d.ts +21 -0
  22. package/dist/agents/SystemPromptBuilder.js +48 -0
  23. package/dist/agents/ToolSessionManager.d.ts +63 -0
  24. package/dist/agents/ToolSessionManager.js +146 -0
  25. package/dist/agents/generateTaskHandler.d.ts +49 -0
  26. package/dist/agents/generateTaskHandler.js +521 -0
  27. package/dist/agents/relationTools.d.ts +57 -0
  28. package/dist/agents/relationTools.js +262 -0
  29. package/dist/agents/types.d.ts +28 -0
  30. package/dist/agents/types.js +1 -0
  31. package/dist/agents/versions/v1/Phase1Config.d.ts +27 -0
  32. package/dist/agents/versions/v1/Phase1Config.js +424 -0
  33. package/dist/agents/versions/v1/Phase2Config.d.ts +31 -0
  34. package/dist/agents/versions/v1/Phase2Config.js +330 -0
  35. package/dist/constants/execution-limits/defaults.d.ts +51 -0
  36. package/dist/constants/execution-limits/defaults.js +52 -0
  37. package/dist/constants/execution-limits/index.d.ts +6 -0
  38. package/dist/constants/execution-limits/index.js +21 -0
  39. package/dist/create-app.d.ts +9 -0
  40. package/dist/create-app.js +195 -0
  41. package/dist/data/agent.d.ts +7 -0
  42. package/dist/data/agent.js +72 -0
  43. package/dist/data/agents.d.ts +34 -0
  44. package/dist/data/agents.js +139 -0
  45. package/dist/data/conversations.d.ts +128 -0
  46. package/dist/data/conversations.js +522 -0
  47. package/dist/data/db/dbClient.d.ts +6 -0
  48. package/dist/data/db/dbClient.js +17 -0
  49. package/dist/env.d.ts +57 -0
  50. package/dist/env.js +1 -2
  51. package/dist/handlers/executionHandler.d.ts +39 -0
  52. package/dist/handlers/executionHandler.js +456 -0
  53. package/dist/index.d.ts +8 -29
  54. package/dist/index.js +5 -11386
  55. package/dist/instrumentation.d.ts +1 -2
  56. package/dist/instrumentation.js +66 -3
  57. package/dist/{logger2.js → logger.d.ts} +1 -2
  58. package/dist/logger.js +1 -1
  59. package/dist/middleware/api-key-auth.d.ts +26 -0
  60. package/dist/middleware/api-key-auth.js +240 -0
  61. package/dist/middleware/index.d.ts +2 -0
  62. package/dist/middleware/index.js +3 -0
  63. package/dist/openapi.d.ts +4 -0
  64. package/dist/openapi.js +54 -0
  65. package/dist/routes/agents.d.ts +12 -0
  66. package/dist/routes/agents.js +147 -0
  67. package/dist/routes/chat.d.ts +13 -0
  68. package/dist/routes/chat.js +293 -0
  69. package/dist/routes/chatDataStream.d.ts +13 -0
  70. package/dist/routes/chatDataStream.js +352 -0
  71. package/dist/routes/mcp.d.ts +13 -0
  72. package/dist/routes/mcp.js +495 -0
  73. package/dist/services/AgentSession.d.ts +356 -0
  74. package/dist/services/AgentSession.js +1208 -0
  75. package/dist/services/ArtifactParser.d.ts +105 -0
  76. package/dist/services/ArtifactParser.js +338 -0
  77. package/dist/services/ArtifactService.d.ts +123 -0
  78. package/dist/services/ArtifactService.js +612 -0
  79. package/dist/services/BaseCompressor.d.ts +183 -0
  80. package/dist/services/BaseCompressor.js +504 -0
  81. package/dist/services/ConversationCompressor.d.ts +32 -0
  82. package/dist/services/ConversationCompressor.js +91 -0
  83. package/dist/services/IncrementalStreamParser.d.ts +98 -0
  84. package/dist/services/IncrementalStreamParser.js +327 -0
  85. package/dist/services/MidGenerationCompressor.d.ts +63 -0
  86. package/dist/services/MidGenerationCompressor.js +104 -0
  87. package/dist/services/PendingToolApprovalManager.d.ts +62 -0
  88. package/dist/services/PendingToolApprovalManager.js +133 -0
  89. package/dist/services/ResponseFormatter.d.ts +39 -0
  90. package/dist/services/ResponseFormatter.js +152 -0
  91. package/dist/tools/NativeSandboxExecutor.d.ts +38 -0
  92. package/dist/tools/NativeSandboxExecutor.js +432 -0
  93. package/dist/tools/SandboxExecutorFactory.d.ts +36 -0
  94. package/dist/tools/SandboxExecutorFactory.js +80 -0
  95. package/dist/tools/VercelSandboxExecutor.d.ts +71 -0
  96. package/dist/tools/VercelSandboxExecutor.js +340 -0
  97. package/dist/tools/distill-conversation-history-tool.d.ts +62 -0
  98. package/dist/tools/distill-conversation-history-tool.js +206 -0
  99. package/dist/tools/distill-conversation-tool.d.ts +41 -0
  100. package/dist/tools/distill-conversation-tool.js +141 -0
  101. package/dist/tools/sandbox-utils.d.ts +18 -0
  102. package/dist/tools/sandbox-utils.js +53 -0
  103. package/dist/types/chat.d.ts +27 -0
  104. package/dist/types/chat.js +1 -0
  105. package/dist/types/execution-context.d.ts +46 -0
  106. package/dist/types/execution-context.js +27 -0
  107. package/dist/types/xml.d.ts +5 -0
  108. package/dist/utils/SchemaProcessor.d.ts +52 -0
  109. package/dist/utils/SchemaProcessor.js +182 -0
  110. package/dist/utils/agent-operations.d.ts +62 -0
  111. package/dist/utils/agent-operations.js +53 -0
  112. package/dist/utils/artifact-component-schema.d.ts +42 -0
  113. package/dist/utils/artifact-component-schema.js +186 -0
  114. package/dist/utils/cleanup.d.ts +21 -0
  115. package/dist/utils/cleanup.js +59 -0
  116. package/dist/utils/data-component-schema.d.ts +2 -0
  117. package/dist/utils/data-component-schema.js +3 -0
  118. package/dist/utils/default-status-schemas.d.ts +20 -0
  119. package/dist/utils/default-status-schemas.js +24 -0
  120. package/dist/utils/json-postprocessor.d.ts +13 -0
  121. package/dist/{json-postprocessor.cjs → utils/json-postprocessor.js} +1 -2
  122. package/dist/utils/model-context-utils.d.ts +39 -0
  123. package/dist/utils/model-context-utils.js +181 -0
  124. package/dist/utils/model-resolver.d.ts +6 -0
  125. package/dist/utils/model-resolver.js +34 -0
  126. package/dist/utils/schema-validation.d.ts +44 -0
  127. package/dist/utils/schema-validation.js +97 -0
  128. package/dist/utils/stream-helpers.d.ts +197 -0
  129. package/dist/utils/stream-helpers.js +518 -0
  130. package/dist/utils/stream-registry.d.ts +22 -0
  131. package/dist/utils/stream-registry.js +34 -0
  132. package/dist/utils/token-estimator.d.ts +69 -0
  133. package/dist/utils/token-estimator.js +53 -0
  134. package/dist/utils/tracer.d.ts +7 -0
  135. package/dist/utils/tracer.js +7 -0
  136. package/package.json +4 -20
  137. package/dist/SandboxExecutorFactory.cjs +0 -895
  138. package/dist/SandboxExecutorFactory.js +0 -893
  139. package/dist/SandboxExecutorFactory.js.map +0 -1
  140. package/dist/chunk-VBDAOXYI.cjs +0 -927
  141. package/dist/chunk-VBDAOXYI.js +0 -832
  142. package/dist/chunk-VBDAOXYI.js.map +0 -1
  143. package/dist/chunk.cjs +0 -34
  144. package/dist/conversations.cjs +0 -7
  145. package/dist/conversations.js +0 -7
  146. package/dist/conversations2.cjs +0 -209
  147. package/dist/conversations2.js +0 -180
  148. package/dist/conversations2.js.map +0 -1
  149. package/dist/dbClient.cjs +0 -9676
  150. package/dist/dbClient.js +0 -9670
  151. package/dist/dbClient.js.map +0 -1
  152. package/dist/dbClient2.cjs +0 -5
  153. package/dist/dbClient2.js +0 -5
  154. package/dist/env.cjs +0 -59
  155. package/dist/env.js.map +0 -1
  156. package/dist/execution-limits.cjs +0 -260
  157. package/dist/execution-limits.js +0 -63
  158. package/dist/execution-limits.js.map +0 -1
  159. package/dist/index.cjs +0 -11411
  160. package/dist/index.d.cts +0 -36
  161. package/dist/index.d.cts.map +0 -1
  162. package/dist/index.d.ts.map +0 -1
  163. package/dist/index.js.map +0 -1
  164. package/dist/instrumentation.cjs +0 -12
  165. package/dist/instrumentation.d.cts +0 -18
  166. package/dist/instrumentation.d.cts.map +0 -1
  167. package/dist/instrumentation.d.ts.map +0 -1
  168. package/dist/instrumentation2.cjs +0 -116
  169. package/dist/instrumentation2.js +0 -69
  170. package/dist/instrumentation2.js.map +0 -1
  171. package/dist/json-postprocessor.js +0 -20
  172. package/dist/json-postprocessor.js.map +0 -1
  173. package/dist/logger.cjs +0 -5
  174. package/dist/logger2.cjs +0 -1
  175. package/dist/nodefs.cjs +0 -29
  176. package/dist/nodefs.js +0 -27
  177. package/dist/nodefs.js.map +0 -1
  178. package/dist/opfs-ahp.cjs +0 -367
  179. package/dist/opfs-ahp.js +0 -368
  180. package/dist/opfs-ahp.js.map +0 -1
@@ -0,0 +1,183 @@
1
+ import { ConversationSummary } from "../tools/distill-conversation-tool.js";
2
+ import { ModelSettings } from "@inkeep/agents-core";
3
+
4
+ //#region src/services/BaseCompressor.d.ts
5
+ interface CompressionConfig {
6
+ hardLimit: number;
7
+ safetyBuffer: number;
8
+ enabled?: boolean;
9
+ }
10
+ interface CompressionResult {
11
+ artifactIds: string[];
12
+ summary: any;
13
+ }
14
+ interface CompressionEventData {
15
+ reason: 'manual' | 'automatic';
16
+ messageCount: number;
17
+ artifactCount: number;
18
+ contextSizeBefore: number;
19
+ contextSizeAfter: number;
20
+ compressionType: 'mid_generation' | 'conversation_level';
21
+ }
22
+ /**
23
+ * Base compressor class containing shared functionality for all compression types
24
+ */
25
+ declare abstract class BaseCompressor {
26
+ protected sessionId: string;
27
+ protected conversationId: string;
28
+ protected tenantId: string;
29
+ protected projectId: string;
30
+ protected config: CompressionConfig;
31
+ protected summarizerModel?: ModelSettings | undefined;
32
+ protected baseModel?: ModelSettings | undefined;
33
+ protected processedToolCalls: Set<string>;
34
+ protected cumulativeSummary: ConversationSummary | null;
35
+ constructor(sessionId: string, conversationId: string, tenantId: string, projectId: string, config: CompressionConfig, summarizerModel?: ModelSettings | undefined, baseModel?: ModelSettings | undefined);
36
+ /**
37
+ * Get the hard limit for compression decisions
38
+ */
39
+ getHardLimit(): number;
40
+ /**
41
+ * Estimate tokens (4 chars = 1 token)
42
+ */
43
+ protected estimateTokens(content: any): number;
44
+ /**
45
+ * Calculate total context size for messages
46
+ */
47
+ protected calculateContextSize(messages: any[]): number;
48
+ /**
49
+ * Save tool results as artifacts
50
+ */
51
+ saveToolResultsAsArtifacts(messages: any[], startIndex?: number): Promise<Record<string, string>>;
52
+ /**
53
+ * Extract all tool call IDs from messages for batch lookup
54
+ */
55
+ private extractToolCallIds;
56
+ /**
57
+ * Batch lookup existing artifacts for multiple tool call IDs (solves N+1 query problem)
58
+ */
59
+ private batchFindExistingArtifacts;
60
+ /**
61
+ * Query database for existing artifacts using enhanced getLedgerArtifacts with batch support
62
+ */
63
+ private queryExistingArtifactsBatch;
64
+ /**
65
+ * Convert database format tool-result messages to Vercel AI SDK format
66
+ */
67
+ private convertDatabaseFormatMessage;
68
+ /**
69
+ * Process all tool results in a message
70
+ */
71
+ private processMessageToolResults;
72
+ /**
73
+ * Process a single tool result block
74
+ */
75
+ private processToolResult;
76
+ /**
77
+ * Check if a tool should be skipped
78
+ */
79
+ private shouldSkipToolCall;
80
+ /**
81
+ * Create a new artifact for a tool call
82
+ */
83
+ private createNewArtifact;
84
+ /**
85
+ * Find tool input for a given tool call ID
86
+ */
87
+ private findToolInput;
88
+ /**
89
+ * Build artifact data structure
90
+ */
91
+ private buildArtifactData;
92
+ /**
93
+ * Validate artifact data has meaningful content
94
+ */
95
+ private validateArtifactData;
96
+ /**
97
+ * Create conversation summary using distillConversation
98
+ */
99
+ protected createConversationSummary(messages: any[], toolCallToArtifactMap: Record<string, string>): Promise<any>;
100
+ /**
101
+ * Record compression event in session
102
+ */
103
+ /**
104
+ * Generate a preview of the tool result for the artifact summary
105
+ */
106
+ protected generateResultPreview(toolResult: any): string;
107
+ protected recordCompressionEvent(eventData: CompressionEventData): void;
108
+ /**
109
+ * Check if tool result data is effectively empty
110
+ */
111
+ protected isEmpty(toolResultData: any): boolean;
112
+ /**
113
+ * Recursively remove _structureHints from an object
114
+ */
115
+ protected removeStructureHints(obj: any): any;
116
+ /**
117
+ * Get current compression summary
118
+ */
119
+ getCompressionSummary(): ConversationSummary | null;
120
+ /**
121
+ * Clean up memory by clearing processed tool calls and optionally resetting summary
122
+ * Call this at the end of agent generation or after compression cycles
123
+ */
124
+ cleanup(options?: {
125
+ resetSummary?: boolean;
126
+ keepRecentToolCalls?: number;
127
+ }): void;
128
+ /**
129
+ * Partial cleanup that preserves recent state for ongoing conversations
130
+ */
131
+ partialCleanup(): void;
132
+ /**
133
+ * Full cleanup that resets all state - use when conversation/session ends
134
+ */
135
+ fullCleanup(): void;
136
+ /**
137
+ * Get current state for debugging
138
+ */
139
+ getState(): {
140
+ config: CompressionConfig;
141
+ processedToolCalls: string[];
142
+ cumulativeSummary: {
143
+ type: "conversation_summary_v1";
144
+ high_level: string;
145
+ user_intent: string;
146
+ decisions: string[];
147
+ open_questions: string[];
148
+ next_steps: {
149
+ for_agent: string[];
150
+ for_user: string[];
151
+ };
152
+ session_id?: string | null | undefined;
153
+ related_artifacts?: {
154
+ id: string;
155
+ name: string;
156
+ tool_name: string;
157
+ tool_call_id: string;
158
+ content_type: string;
159
+ key_findings: string[];
160
+ }[] | undefined;
161
+ } | null;
162
+ };
163
+ /**
164
+ * Safe compression wrapper with fallback handling
165
+ */
166
+ safeCompress(messages: any[], fullContextSize?: number): Promise<CompressionResult>;
167
+ /**
168
+ * Simple compression fallback using the same logic as Agent.simpleCompression
169
+ * Returns the compressed messages, not just a summary
170
+ */
171
+ protected simpleCompressionFallback(messages: any[]): Promise<CompressionResult>;
172
+ abstract isCompressionNeeded(messages: any[]): boolean;
173
+ abstract compress(messages: any[]): Promise<CompressionResult>;
174
+ abstract getCompressionType(): string;
175
+ }
176
+ /**
177
+ * Get model-aware compression config for any model
178
+ * @param modelSettings - Model settings to get context window for
179
+ * @param targetPercentage - Target percentage of context window (e.g., 0.5 for conversation, undefined for aggressive)
180
+ */
181
+ declare function getModelAwareCompressionConfig(modelSettings?: ModelSettings, targetPercentage?: number): CompressionConfig;
182
+ //#endregion
183
+ export { BaseCompressor, CompressionConfig, CompressionEventData, CompressionResult, getModelAwareCompressionConfig };
@@ -0,0 +1,504 @@
1
+ import { getLogger } from "../logger.js";
2
+ import dbClient_default from "../data/db/dbClient.js";
3
+ import { distillConversation } from "../tools/distill-conversation-tool.js";
4
+ import { getCompressionConfigForModel } from "../utils/model-context-utils.js";
5
+ import { tracer } from "../utils/tracer.js";
6
+ import { agentSessionManager } from "./AgentSession.js";
7
+ import { getLedgerArtifacts, upsertLedgerArtifact } from "@inkeep/agents-core";
8
+ import { SpanStatusCode } from "@opentelemetry/api";
9
+ import { randomUUID } from "crypto";
10
+
11
+ //#region src/services/BaseCompressor.ts
12
+ const logger = getLogger("BaseCompressor");
13
+ /**
14
+ * Base compressor class containing shared functionality for all compression types
15
+ */
16
+ var BaseCompressor = class {
17
+ processedToolCalls = /* @__PURE__ */ new Set();
18
+ cumulativeSummary = null;
19
+ constructor(sessionId, conversationId, tenantId, projectId, config, summarizerModel, baseModel) {
20
+ this.sessionId = sessionId;
21
+ this.conversationId = conversationId;
22
+ this.tenantId = tenantId;
23
+ this.projectId = projectId;
24
+ this.config = config;
25
+ this.summarizerModel = summarizerModel;
26
+ this.baseModel = baseModel;
27
+ }
28
+ /**
29
+ * Get the hard limit for compression decisions
30
+ */
31
+ getHardLimit() {
32
+ return this.config.hardLimit;
33
+ }
34
+ /**
35
+ * Estimate tokens (4 chars = 1 token)
36
+ */
37
+ estimateTokens(content) {
38
+ const text = typeof content === "string" ? content : JSON.stringify(content);
39
+ return Math.ceil(text.length / 4);
40
+ }
41
+ /**
42
+ * Calculate total context size for messages
43
+ */
44
+ calculateContextSize(messages) {
45
+ return messages.reduce((total, msg) => {
46
+ let msgTokens = 0;
47
+ if (Array.isArray(msg.content)) {
48
+ for (const block of msg.content) if (block.type === "text") msgTokens += this.estimateTokens(block.text || "");
49
+ else if (block.type === "tool-call") msgTokens += this.estimateTokens(JSON.stringify({
50
+ toolCallId: block.toolCallId,
51
+ toolName: block.toolName,
52
+ input: block.input
53
+ }));
54
+ else if (block.type === "tool-result") msgTokens += this.estimateTokens(JSON.stringify({
55
+ toolCallId: block.toolCallId,
56
+ toolName: block.toolName,
57
+ output: block.output
58
+ }));
59
+ } else if (typeof msg.content === "string") msgTokens += this.estimateTokens(msg.content);
60
+ else if (msg.content) msgTokens += this.estimateTokens(JSON.stringify(msg.content));
61
+ return total + msgTokens;
62
+ }, 0);
63
+ }
64
+ /**
65
+ * Save tool results as artifacts
66
+ */
67
+ async saveToolResultsAsArtifacts(messages, startIndex = 0) {
68
+ const session = agentSessionManager.getSession(this.sessionId);
69
+ if (!session) throw new Error(`No session found: ${this.sessionId}`);
70
+ const messagesToProcess = messages.slice(startIndex);
71
+ const toolCallIds = this.extractToolCallIds(messagesToProcess);
72
+ const existingArtifacts = await this.batchFindExistingArtifacts(toolCallIds);
73
+ const toolCallToArtifactMap = {};
74
+ for (const message of messagesToProcess) {
75
+ this.convertDatabaseFormatMessage(message);
76
+ if (Array.isArray(message.content)) {
77
+ const messageArtifacts = await this.processMessageToolResults(message, session, existingArtifacts);
78
+ Object.assign(toolCallToArtifactMap, messageArtifacts);
79
+ }
80
+ }
81
+ return toolCallToArtifactMap;
82
+ }
83
+ /**
84
+ * Extract all tool call IDs from messages for batch lookup
85
+ */
86
+ extractToolCallIds(messages) {
87
+ const toolCallIds = [];
88
+ for (const message of messages) {
89
+ if (message.messageType === "tool-result" && !Array.isArray(message.content)) {
90
+ const toolCallId = message.metadata?.a2a_metadata?.toolCallId;
91
+ if (toolCallId && !this.shouldSkipToolCall(message.metadata?.a2a_metadata?.toolName)) toolCallIds.push(toolCallId);
92
+ }
93
+ if (Array.isArray(message.content)) {
94
+ for (const block of message.content) if (block.type === "tool-result" && !this.shouldSkipToolCall(block.toolName)) toolCallIds.push(block.toolCallId);
95
+ }
96
+ }
97
+ return [...new Set(toolCallIds)];
98
+ }
99
+ /**
100
+ * Batch lookup existing artifacts for multiple tool call IDs (solves N+1 query problem)
101
+ */
102
+ async batchFindExistingArtifacts(toolCallIds) {
103
+ const existingArtifacts = /* @__PURE__ */ new Map();
104
+ if (toolCallIds.length === 0) return existingArtifacts;
105
+ try {
106
+ const artifacts = await this.queryExistingArtifactsBatch(toolCallIds);
107
+ for (const artifact of artifacts) if (artifact.toolCallId) existingArtifacts.set(artifact.toolCallId, artifact.artifactId);
108
+ logger.debug({
109
+ sessionId: this.sessionId,
110
+ toolCallIds: toolCallIds.length,
111
+ foundArtifacts: existingArtifacts.size
112
+ }, "Batched artifact lookup completed");
113
+ } catch (error) {
114
+ logger.debug({
115
+ sessionId: this.sessionId,
116
+ error: error instanceof Error ? error.message : String(error)
117
+ }, "Batch artifact lookup failed, will create new artifacts");
118
+ }
119
+ return existingArtifacts;
120
+ }
121
+ /**
122
+ * Query database for existing artifacts using enhanced getLedgerArtifacts with batch support
123
+ */
124
+ async queryExistingArtifactsBatch(toolCallIds) {
125
+ if (toolCallIds.length === 0) return [];
126
+ try {
127
+ return (await getLedgerArtifacts(dbClient_default)({
128
+ scopes: {
129
+ tenantId: this.tenantId,
130
+ projectId: this.projectId
131
+ },
132
+ toolCallIds
133
+ })).map((artifact) => ({
134
+ artifactId: artifact.artifactId,
135
+ toolCallId: artifact.toolCallId
136
+ }));
137
+ } catch (error) {
138
+ logger.debug({
139
+ sessionId: this.sessionId,
140
+ toolCallIds: toolCallIds.length,
141
+ error: error instanceof Error ? error.message : String(error)
142
+ }, "Batch artifact lookup failed");
143
+ return [];
144
+ }
145
+ }
146
+ /**
147
+ * Convert database format tool-result messages to Vercel AI SDK format
148
+ */
149
+ convertDatabaseFormatMessage(message) {
150
+ if (message.messageType === "tool-result" && !Array.isArray(message.content) && message.content?.text) {
151
+ const toolName = message.metadata?.a2a_metadata?.toolName;
152
+ const toolCallId = message.metadata?.a2a_metadata?.toolCallId;
153
+ if (this.shouldSkipToolCall(toolName)) return;
154
+ if (toolName && toolCallId) message.content = [{
155
+ type: "tool-result",
156
+ toolCallId,
157
+ toolName,
158
+ output: message.content.text
159
+ }];
160
+ }
161
+ }
162
+ /**
163
+ * Process all tool results in a message
164
+ */
165
+ async processMessageToolResults(message, session, existingArtifacts) {
166
+ const toolCallToArtifactMap = {};
167
+ for (const block of message.content) if (block.type === "tool-result") {
168
+ const artifactId = await this.processToolResult(block, message, session, existingArtifacts);
169
+ if (artifactId) toolCallToArtifactMap[block.toolCallId] = artifactId;
170
+ }
171
+ return toolCallToArtifactMap;
172
+ }
173
+ /**
174
+ * Process a single tool result block
175
+ */
176
+ async processToolResult(block, message, session, existingArtifacts) {
177
+ if (this.shouldSkipToolCall(block.toolName)) {
178
+ logger.debug({
179
+ toolCallId: block.toolCallId,
180
+ toolName: block.toolName
181
+ }, "Skipping special tool - not creating artifacts");
182
+ this.processedToolCalls.add(block.toolCallId);
183
+ return null;
184
+ }
185
+ if (this.processedToolCalls.has(block.toolCallId)) {
186
+ logger.debug({
187
+ toolCallId: block.toolCallId,
188
+ toolName: block.toolName
189
+ }, "Skipping already processed tool call");
190
+ return null;
191
+ }
192
+ const existingArtifactId = existingArtifacts.get(block.toolCallId);
193
+ if (existingArtifactId) {
194
+ logger.debug({
195
+ toolCallId: block.toolCallId,
196
+ existingArtifactId,
197
+ toolName: block.toolName
198
+ }, "Reusing existing artifact from batch lookup");
199
+ return existingArtifactId;
200
+ }
201
+ return await this.createNewArtifact(block, message, session);
202
+ }
203
+ /**
204
+ * Check if a tool should be skipped
205
+ */
206
+ shouldSkipToolCall(toolName) {
207
+ return toolName === "get_reference_artifact" || toolName === "thinking_complete" || toolName?.includes("save_tool_result") || toolName?.startsWith("transfer_to_");
208
+ }
209
+ /**
210
+ * Create a new artifact for a tool call
211
+ */
212
+ async createNewArtifact(block, message, session) {
213
+ const artifactId = `compress_${block.toolName || "tool"}_${block.toolCallId || Date.now()}_${randomUUID().slice(0, 8)}`;
214
+ const toolInput = this.findToolInput(message, block.toolCallId);
215
+ const toolResultData = {
216
+ toolName: block.toolName,
217
+ toolInput,
218
+ toolResult: this.removeStructureHints(block.output),
219
+ compressedAt: (/* @__PURE__ */ new Date()).toISOString()
220
+ };
221
+ if (this.isEmpty(toolResultData)) {
222
+ logger.debug({
223
+ toolName: block.toolName,
224
+ toolCallId: block.toolCallId
225
+ }, "Skipping empty tool result");
226
+ return null;
227
+ }
228
+ const artifactData = this.buildArtifactData(artifactId, block, toolResultData);
229
+ if (!this.validateArtifactData(artifactData)) {
230
+ logger.debug({
231
+ artifactId,
232
+ toolName: block.toolName,
233
+ toolCallId: block.toolCallId
234
+ }, "Skipping empty compression artifact");
235
+ return null;
236
+ }
237
+ session.recordEvent("artifact_saved", this.sessionId, artifactData);
238
+ this.processedToolCalls.add(block.toolCallId);
239
+ logger.debug({
240
+ artifactId,
241
+ toolName: block.toolName,
242
+ toolCallId: block.toolCallId
243
+ }, "Created new compression artifact");
244
+ return artifactId;
245
+ }
246
+ /**
247
+ * Find tool input for a given tool call ID
248
+ */
249
+ findToolInput(message, toolCallId) {
250
+ if (!Array.isArray(message.content)) return null;
251
+ return message.content.find((b) => b.type === "tool-call" && b.toolCallId === toolCallId)?.input || null;
252
+ }
253
+ /**
254
+ * Build artifact data structure
255
+ */
256
+ buildArtifactData(artifactId, block, toolResultData) {
257
+ return {
258
+ artifactId,
259
+ taskId: `task_${this.conversationId}-${this.sessionId}`,
260
+ toolCallId: block.toolCallId,
261
+ artifactType: "tool_result",
262
+ pendingGeneration: true,
263
+ tenantId: this.tenantId,
264
+ projectId: this.projectId,
265
+ contextId: this.conversationId,
266
+ subAgentId: this.sessionId,
267
+ metadata: {
268
+ toolCallId: block.toolCallId,
269
+ toolName: block.toolName,
270
+ compressionReason: this.getCompressionType()
271
+ },
272
+ summaryData: {
273
+ toolCallId: block.toolCallId,
274
+ toolName: block.toolName,
275
+ resultPreview: this.generateResultPreview(toolResultData.toolResult),
276
+ note: `Tool result from ${block.toolName} - compressed to save context space`
277
+ },
278
+ data: toolResultData
279
+ };
280
+ }
281
+ /**
282
+ * Validate artifact data has meaningful content
283
+ */
284
+ validateArtifactData(artifactData) {
285
+ const fullData = artifactData.data;
286
+ return fullData && typeof fullData === "object" && Object.keys(fullData).length > 0 && fullData.toolResult && (typeof fullData.toolResult !== "object" || Object.keys(fullData.toolResult).length > 0);
287
+ }
288
+ /**
289
+ * Create conversation summary using distillConversation
290
+ */
291
+ async createConversationSummary(messages, toolCallToArtifactMap) {
292
+ const summary = await distillConversation({
293
+ messages,
294
+ conversationId: this.conversationId,
295
+ currentSummary: this.cumulativeSummary,
296
+ summarizerModel: this.summarizerModel,
297
+ toolCallToArtifactMap
298
+ });
299
+ this.cumulativeSummary = summary;
300
+ return summary;
301
+ }
302
+ /**
303
+ * Record compression event in session
304
+ */
305
+ /**
306
+ * Generate a preview of the tool result for the artifact summary
307
+ */
308
+ generateResultPreview(toolResult) {
309
+ try {
310
+ if (!toolResult) return "No result data";
311
+ let preview;
312
+ if (typeof toolResult === "string") preview = toolResult;
313
+ else if (typeof toolResult === "object") preview = JSON.stringify(toolResult);
314
+ else preview = String(toolResult);
315
+ return preview.slice(0, 150).replace(/\s+/g, " ").trim() + (preview.length > 150 ? "..." : "");
316
+ } catch (error) {
317
+ return "Preview unavailable";
318
+ }
319
+ }
320
+ recordCompressionEvent(eventData) {
321
+ const session = agentSessionManager.getSession(this.sessionId);
322
+ if (session) session.recordEvent("compression", this.sessionId, eventData);
323
+ }
324
+ /**
325
+ * Check if tool result data is effectively empty
326
+ */
327
+ isEmpty(toolResultData) {
328
+ if (!toolResultData || typeof toolResultData !== "object") return true;
329
+ const { toolResult } = toolResultData;
330
+ if (!toolResult) return true;
331
+ if (typeof toolResult === "object" && !Array.isArray(toolResult)) {
332
+ const keys = Object.keys(toolResult);
333
+ if (keys.length === 0) return true;
334
+ return keys.every((key) => {
335
+ const value = toolResult[key];
336
+ if (value === null || value === void 0 || value === "") return true;
337
+ if (Array.isArray(value) && value.length === 0) return true;
338
+ if (typeof value === "object" && Object.keys(value).length === 0) return true;
339
+ return false;
340
+ });
341
+ }
342
+ if (Array.isArray(toolResult) && toolResult.length === 0) return true;
343
+ if (typeof toolResult === "string" && toolResult.trim() === "") return true;
344
+ return false;
345
+ }
346
+ /**
347
+ * Recursively remove _structureHints from an object
348
+ */
349
+ removeStructureHints(obj) {
350
+ if (obj === null || obj === void 0) return obj;
351
+ if (Array.isArray(obj)) return obj.map((item) => this.removeStructureHints(item));
352
+ if (typeof obj === "object") {
353
+ const cleaned = {};
354
+ for (const [key, value] of Object.entries(obj)) if (key !== "_structureHints") cleaned[key] = this.removeStructureHints(value);
355
+ return cleaned;
356
+ }
357
+ return obj;
358
+ }
359
+ /**
360
+ * Get current compression summary
361
+ */
362
+ getCompressionSummary() {
363
+ return this.cumulativeSummary;
364
+ }
365
+ /**
366
+ * Clean up memory by clearing processed tool calls and optionally resetting summary
367
+ * Call this at the end of agent generation or after compression cycles
368
+ */
369
+ cleanup(options = {}) {
370
+ const { resetSummary = false, keepRecentToolCalls = 0 } = options;
371
+ if (keepRecentToolCalls > 0) {
372
+ const recentCalls = Array.from(this.processedToolCalls).slice(-keepRecentToolCalls);
373
+ this.processedToolCalls = new Set(recentCalls);
374
+ } else this.processedToolCalls.clear();
375
+ if (resetSummary) this.cumulativeSummary = null;
376
+ logger.debug({
377
+ sessionId: this.sessionId,
378
+ conversationId: this.conversationId,
379
+ processedToolCallsSize: this.processedToolCalls.size,
380
+ summaryReset: resetSummary
381
+ }, "BaseCompressor cleanup completed");
382
+ }
383
+ /**
384
+ * Partial cleanup that preserves recent state for ongoing conversations
385
+ */
386
+ partialCleanup() {
387
+ this.cleanup({ keepRecentToolCalls: 50 });
388
+ }
389
+ /**
390
+ * Full cleanup that resets all state - use when conversation/session ends
391
+ */
392
+ fullCleanup() {
393
+ this.cleanup({ resetSummary: true });
394
+ }
395
+ /**
396
+ * Get current state for debugging
397
+ */
398
+ getState() {
399
+ return {
400
+ config: this.config,
401
+ processedToolCalls: Array.from(this.processedToolCalls),
402
+ cumulativeSummary: this.cumulativeSummary
403
+ };
404
+ }
405
+ /**
406
+ * Safe compression wrapper with fallback handling
407
+ */
408
+ async safeCompress(messages, fullContextSize) {
409
+ return await tracer.startActiveSpan("compressor.safe_compress", { attributes: {
410
+ "compression.type": this.getCompressionType(),
411
+ "compression.session_id": this.sessionId,
412
+ "compression.conversation_id": this.conversationId,
413
+ "compression.message_count": messages.length,
414
+ "compression.input_tokens": fullContextSize ?? this.calculateContextSize(messages),
415
+ "compression.hard_limit": this.getHardLimit(),
416
+ "compression.safety_buffer": this.config.safetyBuffer
417
+ } }, async (compressionSpan) => {
418
+ try {
419
+ const result = await this.compress(messages);
420
+ const resultTokens = Array.isArray(result.summary) ? this.calculateContextSize(result.summary) : this.estimateTokens(result.summary);
421
+ compressionSpan.setAttributes({
422
+ "compression.result.artifact_count": result.artifactIds.length,
423
+ "compression.result.output_tokens": resultTokens,
424
+ "compression.result.compression_ratio": (fullContextSize ?? this.calculateContextSize(messages)) > 0 ? ((fullContextSize ?? this.calculateContextSize(messages)) - resultTokens) / (fullContextSize ?? this.calculateContextSize(messages)) : 0,
425
+ "compression.success": true,
426
+ "compression.fallback_used": false
427
+ });
428
+ compressionSpan.setStatus({ code: SpanStatusCode.OK });
429
+ return result;
430
+ } catch (error) {
431
+ logger.error({
432
+ sessionId: this.sessionId,
433
+ conversationId: this.conversationId,
434
+ error: error instanceof Error ? error.message : String(error),
435
+ stack: error instanceof Error ? error.stack : void 0
436
+ }, "Compression failed, using simple fallback");
437
+ compressionSpan.setAttributes({
438
+ "compression.error": error instanceof Error ? error.message : String(error),
439
+ "compression.fallback_used": true
440
+ });
441
+ const fallbackResult = await this.simpleCompressionFallback(messages);
442
+ const fallbackTokens = Array.isArray(fallbackResult.summary) ? this.calculateContextSize(fallbackResult.summary) : this.estimateTokens(fallbackResult.summary);
443
+ compressionSpan.setAttributes({
444
+ "compression.result.artifact_count": fallbackResult.artifactIds.length,
445
+ "compression.result.output_tokens": fallbackTokens,
446
+ "compression.result.compression_ratio": (fullContextSize ?? this.calculateContextSize(messages)) > 0 ? ((fullContextSize ?? this.calculateContextSize(messages)) - fallbackTokens) / (fullContextSize ?? this.calculateContextSize(messages)) : 0,
447
+ "compression.success": true
448
+ });
449
+ compressionSpan.setStatus({ code: SpanStatusCode.OK });
450
+ return fallbackResult;
451
+ } finally {
452
+ compressionSpan.end();
453
+ }
454
+ });
455
+ }
456
+ /**
457
+ * Simple compression fallback using the same logic as Agent.simpleCompression
458
+ * Returns the compressed messages, not just a summary
459
+ */
460
+ async simpleCompressionFallback(messages) {
461
+ if (messages.length === 0) return {
462
+ artifactIds: [],
463
+ summary: []
464
+ };
465
+ const targetTokens = Math.floor(this.getHardLimit() * .5);
466
+ let totalTokens = this.calculateContextSize(messages);
467
+ if (totalTokens <= targetTokens) return {
468
+ artifactIds: [],
469
+ summary: messages
470
+ };
471
+ const result = [...messages];
472
+ while (totalTokens > targetTokens && result.length > 1) {
473
+ const dropped = result.shift();
474
+ if (dropped) totalTokens -= this.estimateTokens(dropped);
475
+ }
476
+ logger.info({
477
+ sessionId: this.sessionId,
478
+ conversationId: this.conversationId,
479
+ originalCount: messages.length,
480
+ compressedCount: result.length,
481
+ compressionType: "simple_fallback"
482
+ }, "Simple compression fallback completed");
483
+ return {
484
+ artifactIds: [],
485
+ summary: result
486
+ };
487
+ }
488
+ };
489
+ /**
490
+ * Get model-aware compression config for any model
491
+ * @param modelSettings - Model settings to get context window for
492
+ * @param targetPercentage - Target percentage of context window (e.g., 0.5 for conversation, undefined for aggressive)
493
+ */
494
+ function getModelAwareCompressionConfig(modelSettings, targetPercentage) {
495
+ const config = getCompressionConfigForModel(modelSettings, targetPercentage);
496
+ return {
497
+ hardLimit: config.hardLimit,
498
+ safetyBuffer: config.safetyBuffer,
499
+ enabled: config.enabled
500
+ };
501
+ }
502
+
503
+ //#endregion
504
+ export { BaseCompressor, getModelAwareCompressionConfig };