@inkeep/agents-run-api 0.39.5 → 0.41.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 +576 -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 +268 -0
  18. package/dist/agents/Agent.js +1932 -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 +523 -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 +41 -0
  52. package/dist/handlers/executionHandler.js +457 -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 +305 -0
  69. package/dist/routes/chatDataStream.d.ts +13 -0
  70. package/dist/routes/chatDataStream.js +365 -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 +500 -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} +2 -3
  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 +10 -26
  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,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 };
@@ -0,0 +1,98 @@
1
+ import { StreamHelper } from "../utils/stream-helpers.js";
2
+ import { StreamPart } from "./ArtifactParser.js";
3
+
4
+ //#region src/services/IncrementalStreamParser.d.ts
5
+
6
+ /**
7
+ * Incremental parser that processes streaming text and formats artifacts/objects as they become complete
8
+ * Uses the unified ArtifactParser to eliminate redundancy
9
+ */
10
+ declare class IncrementalStreamParser {
11
+ private buffer;
12
+ private pendingTextBuffer;
13
+ private streamHelper;
14
+ private artifactParser;
15
+ private hasStartedRole;
16
+ private collectedParts;
17
+ private contextId;
18
+ private lastChunkWasToolResult;
19
+ private componentAccumulator;
20
+ private lastStreamedComponents;
21
+ private componentSnapshots;
22
+ private artifactMap?;
23
+ private subAgentId?;
24
+ private allStreamedContent;
25
+ private static readonly MAX_SNAPSHOT_SIZE;
26
+ private static readonly MAX_STREAMED_SIZE;
27
+ private static readonly MAX_COLLECTED_PARTS;
28
+ constructor(streamHelper: StreamHelper, tenantId: string, contextId: string, artifactParserOptions?: {
29
+ sessionId?: string;
30
+ taskId?: string;
31
+ projectId?: string;
32
+ artifactComponents?: any[];
33
+ streamRequestId?: string;
34
+ subAgentId?: string;
35
+ });
36
+ /**
37
+ * Initialize artifact map for artifact:ref lookups during streaming
38
+ * Should be called before processing chunks
39
+ */
40
+ initializeArtifactMap(): Promise<void>;
41
+ /**
42
+ * Mark that a tool result just completed, so next text should have spacing
43
+ */
44
+ markToolResult(): void;
45
+ /**
46
+ * Process a new text chunk for text streaming (handles artifact markers)
47
+ */
48
+ processTextChunk(chunk: string): Promise<void>;
49
+ /**
50
+ * Process object deltas directly from Vercel AI SDK's fullStream
51
+ * Accumulates components and streams them when they're stable (unchanged between deltas)
52
+ */
53
+ processObjectDelta(delta: any): Promise<void>;
54
+ /**
55
+ * Stream a component and mark it as streamed
56
+ * Note: Text components are handled separately with incremental streaming
57
+ */
58
+ private streamComponent;
59
+ /**
60
+ * Check if a component has the basic structure required for streaming
61
+ * Requires id, name, and props object with content
62
+ */
63
+ private isComponentComplete;
64
+ /**
65
+ * Deep merge helper for object deltas
66
+ */
67
+ private deepMerge;
68
+ /**
69
+ * Legacy method for backward compatibility - defaults to text processing
70
+ */
71
+ processChunk(chunk: string): Promise<void>;
72
+ /**
73
+ * Process any remaining buffer content at the end of stream
74
+ */
75
+ finalize(): Promise<void>;
76
+ /**
77
+ * Get all collected parts for building the final response
78
+ */
79
+ getCollectedParts(): StreamPart[];
80
+ /**
81
+ * Get all streamed content that was actually sent to the user
82
+ */
83
+ getAllStreamedContent(): StreamPart[];
84
+ /**
85
+ * Parse buffer for complete artifacts and text parts (for text streaming)
86
+ */
87
+ private parseTextBuffer;
88
+ /**
89
+ * Check if text might be the start of an artifact marker
90
+ */
91
+ private mightBeArtifactStart;
92
+ /**
93
+ * Stream a formatted part (text or data) with smart buffering
94
+ */
95
+ private streamPart;
96
+ }
97
+ //#endregion
98
+ export { IncrementalStreamParser };
@@ -0,0 +1,327 @@
1
+ import { getLogger } from "../logger.js";
2
+ import { STREAM_PARSER_MAX_COLLECTED_PARTS, STREAM_PARSER_MAX_SNAPSHOT_SIZE, STREAM_PARSER_MAX_STREAMED_SIZE } from "../constants/execution-limits/index.js";
3
+ import { ArtifactParser } from "./ArtifactParser.js";
4
+ import { agentSessionManager } from "./AgentSession.js";
5
+
6
+ //#region src/services/IncrementalStreamParser.ts
7
+ const logger = getLogger("IncrementalStreamParser");
8
+ /**
9
+ * Incremental parser that processes streaming text and formats artifacts/objects as they become complete
10
+ * Uses the unified ArtifactParser to eliminate redundancy
11
+ */
12
+ var IncrementalStreamParser = class IncrementalStreamParser {
13
+ buffer = "";
14
+ pendingTextBuffer = "";
15
+ streamHelper;
16
+ artifactParser;
17
+ hasStartedRole = false;
18
+ collectedParts = [];
19
+ contextId;
20
+ lastChunkWasToolResult = false;
21
+ componentAccumulator = {};
22
+ lastStreamedComponents = /* @__PURE__ */ new Map();
23
+ componentSnapshots = /* @__PURE__ */ new Map();
24
+ artifactMap;
25
+ subAgentId;
26
+ allStreamedContent = [];
27
+ static MAX_SNAPSHOT_SIZE = STREAM_PARSER_MAX_SNAPSHOT_SIZE;
28
+ static MAX_STREAMED_SIZE = STREAM_PARSER_MAX_STREAMED_SIZE;
29
+ static MAX_COLLECTED_PARTS = STREAM_PARSER_MAX_COLLECTED_PARTS;
30
+ constructor(streamHelper, tenantId, contextId, artifactParserOptions) {
31
+ this.streamHelper = streamHelper;
32
+ this.contextId = contextId;
33
+ this.subAgentId = artifactParserOptions?.subAgentId;
34
+ if (artifactParserOptions?.streamRequestId) {
35
+ const sessionParser = agentSessionManager.getArtifactParser(artifactParserOptions.streamRequestId);
36
+ if (sessionParser) {
37
+ this.artifactParser = sessionParser;
38
+ return;
39
+ }
40
+ }
41
+ let sharedArtifactService = null;
42
+ if (artifactParserOptions?.streamRequestId && typeof agentSessionManager.getArtifactService === "function") try {
43
+ sharedArtifactService = agentSessionManager.getArtifactService(artifactParserOptions.streamRequestId);
44
+ } catch (_error) {}
45
+ this.artifactParser = new ArtifactParser(tenantId, {
46
+ ...artifactParserOptions,
47
+ contextId,
48
+ artifactService: sharedArtifactService
49
+ });
50
+ }
51
+ /**
52
+ * Initialize artifact map for artifact:ref lookups during streaming
53
+ * Should be called before processing chunks
54
+ */
55
+ async initializeArtifactMap() {
56
+ try {
57
+ this.artifactMap = await this.artifactParser.getContextArtifacts(this.contextId);
58
+ logger.debug({
59
+ contextId: this.contextId,
60
+ artifactMapSize: this.artifactMap.size
61
+ }, "Initialized artifact map for streaming");
62
+ } catch (error) {
63
+ logger.warn({
64
+ error,
65
+ contextId: this.contextId
66
+ }, "Failed to initialize artifact map");
67
+ this.artifactMap = /* @__PURE__ */ new Map();
68
+ }
69
+ }
70
+ /**
71
+ * Mark that a tool result just completed, so next text should have spacing
72
+ */
73
+ markToolResult() {
74
+ this.lastChunkWasToolResult = true;
75
+ }
76
+ /**
77
+ * Process a new text chunk for text streaming (handles artifact markers)
78
+ */
79
+ async processTextChunk(chunk) {
80
+ if (this.lastChunkWasToolResult && this.buffer === "" && chunk) {
81
+ chunk = `\n\n${chunk}`;
82
+ this.lastChunkWasToolResult = false;
83
+ }
84
+ this.buffer += chunk;
85
+ const parseResult = await this.parseTextBuffer();
86
+ for (const part of parseResult.completeParts) await this.streamPart(part);
87
+ this.buffer = parseResult.remainingBuffer;
88
+ }
89
+ /**
90
+ * Process object deltas directly from Vercel AI SDK's fullStream
91
+ * Accumulates components and streams them when they're stable (unchanged between deltas)
92
+ */
93
+ async processObjectDelta(delta) {
94
+ if (!delta || typeof delta !== "object") return;
95
+ this.componentAccumulator = this.deepMerge(this.componentAccumulator, delta);
96
+ if (this.componentAccumulator.dataComponents && Array.isArray(this.componentAccumulator.dataComponents)) {
97
+ const components = this.componentAccumulator.dataComponents;
98
+ const currentComponentIds = new Set(components.filter((c) => c?.id).map((c) => c.id));
99
+ for (const [componentId, snapshot] of this.componentSnapshots.entries()) if (!currentComponentIds.has(componentId) && !this.lastStreamedComponents.has(componentId)) try {
100
+ const component = JSON.parse(snapshot);
101
+ if (this.isComponentComplete(component)) await this.streamComponent(component);
102
+ } catch (_e) {}
103
+ for (let i = 0; i < components.length; i++) {
104
+ const component = components[i];
105
+ if (!component?.id) continue;
106
+ const componentKey = component.id;
107
+ if (this.lastStreamedComponents.has(componentKey)) continue;
108
+ const currentSnapshot = JSON.stringify(component);
109
+ const previousSnapshot = this.componentSnapshots.get(componentKey);
110
+ this.componentSnapshots.set(componentKey, currentSnapshot);
111
+ if (this.componentSnapshots.size > IncrementalStreamParser.MAX_SNAPSHOT_SIZE) {
112
+ const firstKey = this.componentSnapshots.keys().next().value;
113
+ if (firstKey) this.componentSnapshots.delete(firstKey);
114
+ }
115
+ if (component.name === "Text" && component.props?.text) {
116
+ const previousTextContent = previousSnapshot ? JSON.parse(previousSnapshot).props?.text || "" : "";
117
+ const currentTextContent = component.props.text || "";
118
+ if (currentTextContent.length > previousTextContent.length) {
119
+ const newText = currentTextContent.slice(previousTextContent.length);
120
+ if (!this.hasStartedRole) {
121
+ await this.streamHelper.writeRole("assistant");
122
+ this.hasStartedRole = true;
123
+ }
124
+ await this.streamHelper.streamText(newText, 50);
125
+ const textPart = {
126
+ kind: "text",
127
+ text: newText
128
+ };
129
+ this.collectedParts.push(textPart);
130
+ this.allStreamedContent.push(textPart);
131
+ }
132
+ continue;
133
+ }
134
+ if (this.isComponentComplete(component)) {
135
+ const currentPropsSnapshot = JSON.stringify(component.props);
136
+ if ((previousSnapshot ? JSON.stringify(JSON.parse(previousSnapshot).props) : null) === currentPropsSnapshot) await this.streamComponent(component);
137
+ }
138
+ }
139
+ }
140
+ }
141
+ /**
142
+ * Stream a component and mark it as streamed
143
+ * Note: Text components are handled separately with incremental streaming
144
+ */
145
+ async streamComponent(component) {
146
+ const parts = await this.artifactParser.parseObject({ dataComponents: [component] }, this.artifactMap, this.subAgentId);
147
+ if (!Array.isArray(parts)) {
148
+ console.warn("parseObject returned non-array:", parts);
149
+ return;
150
+ }
151
+ for (const part of parts) await this.streamPart(part);
152
+ this.lastStreamedComponents.set(component.id, true);
153
+ if (this.lastStreamedComponents.size > IncrementalStreamParser.MAX_STREAMED_SIZE) {
154
+ const firstKey = this.lastStreamedComponents.keys().next().value;
155
+ if (firstKey) this.lastStreamedComponents.delete(firstKey);
156
+ }
157
+ this.componentSnapshots.delete(component.id);
158
+ }
159
+ /**
160
+ * Check if a component has the basic structure required for streaming
161
+ * Requires id, name, and props object with content
162
+ */
163
+ isComponentComplete(component) {
164
+ if (!component || !component.id || !component.name) return false;
165
+ if (!component.props || typeof component.props !== "object") return false;
166
+ if (component.name === "Artifact" || component.props.artifact_id && (component.props.tool_call_id || component.props.task_id)) return Boolean(component.props.artifact_id && (component.props.tool_call_id || component.props.task_id));
167
+ return true;
168
+ }
169
+ /**
170
+ * Deep merge helper for object deltas
171
+ */
172
+ deepMerge(target, source) {
173
+ if (!source) return target;
174
+ if (!target) return source;
175
+ const result = { ...target };
176
+ for (const key in source) if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) result[key] = this.deepMerge(target[key], source[key]);
177
+ else result[key] = source[key];
178
+ return result;
179
+ }
180
+ /**
181
+ * Legacy method for backward compatibility - defaults to text processing
182
+ */
183
+ async processChunk(chunk) {
184
+ await this.processTextChunk(chunk);
185
+ }
186
+ /**
187
+ * Process any remaining buffer content at the end of stream
188
+ */
189
+ async finalize() {
190
+ if (this.componentAccumulator.dataComponents && Array.isArray(this.componentAccumulator.dataComponents)) {
191
+ const components = this.componentAccumulator.dataComponents;
192
+ for (let i = 0; i < components.length; i++) {
193
+ const component = components[i];
194
+ if (!component?.id) continue;
195
+ const componentKey = component.id;
196
+ if (!this.lastStreamedComponents.has(componentKey) && this.isComponentComplete(component) && component.name !== "Text") {
197
+ const parts = await this.artifactParser.parseObject({ dataComponents: [component] }, this.artifactMap, this.subAgentId);
198
+ for (const part of parts) await this.streamPart(part);
199
+ this.lastStreamedComponents.set(componentKey, true);
200
+ if (this.lastStreamedComponents.size > IncrementalStreamParser.MAX_STREAMED_SIZE) {
201
+ const firstKey = this.lastStreamedComponents.keys().next().value;
202
+ if (firstKey) this.lastStreamedComponents.delete(firstKey);
203
+ }
204
+ this.componentSnapshots.delete(componentKey);
205
+ }
206
+ }
207
+ }
208
+ if (this.buffer) {
209
+ const part = {
210
+ kind: "text",
211
+ text: this.buffer
212
+ };
213
+ await this.streamPart(part);
214
+ }
215
+ if (this.pendingTextBuffer) {
216
+ const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/artifact:ref>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
217
+ if (cleanedText) {
218
+ const textPart = {
219
+ kind: "text",
220
+ text: cleanedText
221
+ };
222
+ this.collectedParts.push(textPart);
223
+ this.allStreamedContent.push(textPart);
224
+ await this.streamHelper.streamText(cleanedText, 50);
225
+ }
226
+ this.pendingTextBuffer = "";
227
+ }
228
+ this.componentSnapshots.clear();
229
+ this.lastStreamedComponents.clear();
230
+ this.componentAccumulator = {};
231
+ }
232
+ /**
233
+ * Get all collected parts for building the final response
234
+ */
235
+ getCollectedParts() {
236
+ return [...this.collectedParts];
237
+ }
238
+ /**
239
+ * Get all streamed content that was actually sent to the user
240
+ */
241
+ getAllStreamedContent() {
242
+ return [...this.allStreamedContent];
243
+ }
244
+ /**
245
+ * Parse buffer for complete artifacts and text parts (for text streaming)
246
+ */
247
+ async parseTextBuffer() {
248
+ const completeParts = [];
249
+ const workingBuffer = this.buffer;
250
+ if (this.artifactParser.hasIncompleteArtifact(workingBuffer)) {
251
+ const safeEnd = this.artifactParser.findSafeTextBoundary(workingBuffer);
252
+ if (safeEnd > 0) {
253
+ const safeText = workingBuffer.slice(0, safeEnd);
254
+ const parts$1 = await this.artifactParser.parseText(safeText, this.artifactMap, this.subAgentId);
255
+ completeParts.push(...parts$1);
256
+ return {
257
+ completeParts,
258
+ remainingBuffer: workingBuffer.slice(safeEnd)
259
+ };
260
+ }
261
+ return {
262
+ completeParts: [],
263
+ remainingBuffer: workingBuffer
264
+ };
265
+ }
266
+ const parts = await this.artifactParser.parseText(workingBuffer, this.artifactMap, this.subAgentId);
267
+ if (parts.length > 0 && parts[parts.length - 1].kind === "text") {
268
+ const lastText = parts[parts.length - 1].text || "";
269
+ if (this.mightBeArtifactStart(lastText)) {
270
+ parts.pop();
271
+ return {
272
+ completeParts: parts,
273
+ remainingBuffer: lastText
274
+ };
275
+ }
276
+ }
277
+ return {
278
+ completeParts: parts,
279
+ remainingBuffer: ""
280
+ };
281
+ }
282
+ /**
283
+ * Check if text might be the start of an artifact marker
284
+ */
285
+ mightBeArtifactStart(text) {
286
+ const lastChars = text.slice(-20);
287
+ return lastChars.includes("<") && !lastChars.includes("/>");
288
+ }
289
+ /**
290
+ * Stream a formatted part (text or data) with smart buffering
291
+ */
292
+ async streamPart(part) {
293
+ this.collectedParts.push({ ...part });
294
+ this.allStreamedContent.push({ ...part });
295
+ if (this.collectedParts.length > IncrementalStreamParser.MAX_COLLECTED_PARTS) {
296
+ const excess = this.collectedParts.length - IncrementalStreamParser.MAX_COLLECTED_PARTS;
297
+ this.collectedParts.splice(0, excess);
298
+ }
299
+ if (this.allStreamedContent.length > IncrementalStreamParser.MAX_COLLECTED_PARTS) {
300
+ const excess = this.allStreamedContent.length - IncrementalStreamParser.MAX_COLLECTED_PARTS;
301
+ this.allStreamedContent.splice(0, excess);
302
+ }
303
+ if (!this.hasStartedRole) {
304
+ await this.streamHelper.writeRole("assistant");
305
+ this.hasStartedRole = true;
306
+ }
307
+ if (part.kind === "text" && part.text) {
308
+ this.pendingTextBuffer += part.text;
309
+ if (!this.artifactParser.hasIncompleteArtifact(this.pendingTextBuffer)) {
310
+ const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/artifact:ref>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
311
+ if (cleanedText) await this.streamHelper.streamText(cleanedText, 50);
312
+ this.pendingTextBuffer = "";
313
+ }
314
+ } else if (part.kind === "data" && part.data) {
315
+ if (this.pendingTextBuffer) {
316
+ const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/artifact:ref>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
317
+ if (cleanedText) await this.streamHelper.streamText(cleanedText, 50);
318
+ this.pendingTextBuffer = "";
319
+ }
320
+ if (part.data.artifactId && part.data.toolCallId) await this.streamHelper.writeData("data-artifact", part.data);
321
+ else await this.streamHelper.writeData("data-component", part.data);
322
+ }
323
+ }
324
+ };
325
+
326
+ //#endregion
327
+ export { IncrementalStreamParser };
@@ -0,0 +1,63 @@
1
+ import { BaseCompressor, CompressionConfig, CompressionResult } from "./BaseCompressor.js";
2
+ import { ModelSettings } from "@inkeep/agents-core";
3
+
4
+ //#region src/services/MidGenerationCompressor.d.ts
5
+
6
+ /**
7
+ * Mid-generation compressor
8
+ * Compresses context when generate() steps get too large with manual compression support
9
+ */
10
+ declare class MidGenerationCompressor extends BaseCompressor {
11
+ private shouldCompress;
12
+ private lastProcessedMessageIndex;
13
+ constructor(sessionId: string, conversationId: string, tenantId: string, projectId: string, config?: CompressionConfig, summarizerModel?: ModelSettings, baseModel?: ModelSettings);
14
+ /**
15
+ * Get compression type for this compressor
16
+ */
17
+ getCompressionType(): 'mid_generation';
18
+ /**
19
+ * Manual compression request from LLM tool
20
+ */
21
+ requestManualCompression(reason?: string): void;
22
+ /**
23
+ * Check if compression is needed (either automatic or manual)
24
+ * Supports manual compression requests unique to mid-generation
25
+ */
26
+ isCompressionNeeded(messages: any[]): boolean;
27
+ /**
28
+ * Perform mid-generation compression with incremental processing
29
+ * Uses base class functionality with mid-generation specific logic
30
+ */
31
+ compress(messages: any[]): Promise<CompressionResult>;
32
+ /**
33
+ * Get current state for debugging
34
+ */
35
+ getState(): {
36
+ shouldCompress: boolean;
37
+ lastProcessedMessageIndex: number;
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;
60
+ };
61
+ }
62
+ //#endregion
63
+ export { MidGenerationCompressor };