@inkeep/agents-run-api 0.39.4 → 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.
- package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/system-prompt.js +5 -0
- package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/thinking-preparation.js +5 -0
- package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/tool.js +5 -0
- package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/data-component.js +5 -0
- package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/data-components.js +5 -0
- package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase2/system-prompt.js +5 -0
- package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/shared/artifact-retrieval-guidance.js +5 -0
- package/dist/_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/shared/artifact.js +5 -0
- package/dist/a2a/client.d.ts +184 -0
- package/dist/a2a/client.js +510 -0
- package/dist/a2a/handlers.d.ts +7 -0
- package/dist/a2a/handlers.js +560 -0
- package/dist/a2a/transfer.d.ts +22 -0
- package/dist/a2a/transfer.js +46 -0
- package/dist/a2a/types.d.ts +79 -0
- package/dist/a2a/types.js +22 -0
- package/dist/agents/Agent.d.ts +266 -0
- package/dist/agents/Agent.js +1927 -0
- package/dist/agents/ModelFactory.d.ts +63 -0
- package/dist/agents/ModelFactory.js +194 -0
- package/dist/agents/SystemPromptBuilder.d.ts +21 -0
- package/dist/agents/SystemPromptBuilder.js +48 -0
- package/dist/agents/ToolSessionManager.d.ts +63 -0
- package/dist/agents/ToolSessionManager.js +146 -0
- package/dist/agents/generateTaskHandler.d.ts +49 -0
- package/dist/agents/generateTaskHandler.js +521 -0
- package/dist/agents/relationTools.d.ts +57 -0
- package/dist/agents/relationTools.js +262 -0
- package/dist/agents/types.d.ts +28 -0
- package/dist/agents/types.js +1 -0
- package/dist/agents/versions/v1/Phase1Config.d.ts +27 -0
- package/dist/agents/versions/v1/Phase1Config.js +424 -0
- package/dist/agents/versions/v1/Phase2Config.d.ts +31 -0
- package/dist/agents/versions/v1/Phase2Config.js +330 -0
- package/dist/constants/execution-limits/defaults.d.ts +51 -0
- package/dist/constants/execution-limits/defaults.js +52 -0
- package/dist/constants/execution-limits/index.d.ts +6 -0
- package/dist/constants/execution-limits/index.js +21 -0
- package/dist/create-app.d.ts +9 -0
- package/dist/create-app.js +195 -0
- package/dist/data/agent.d.ts +7 -0
- package/dist/data/agent.js +72 -0
- package/dist/data/agents.d.ts +34 -0
- package/dist/data/agents.js +139 -0
- package/dist/data/conversations.d.ts +128 -0
- package/dist/data/conversations.js +522 -0
- package/dist/data/db/dbClient.d.ts +6 -0
- package/dist/data/db/dbClient.js +17 -0
- package/dist/env.d.ts +57 -0
- package/dist/env.js +1 -2
- package/dist/handlers/executionHandler.d.ts +39 -0
- package/dist/handlers/executionHandler.js +456 -0
- package/dist/index.d.ts +8 -29
- package/dist/index.js +5 -11235
- package/dist/instrumentation.d.ts +1 -2
- package/dist/instrumentation.js +66 -3
- package/dist/{logger2.js → logger.d.ts} +1 -2
- package/dist/logger.js +1 -1
- package/dist/middleware/api-key-auth.d.ts +26 -0
- package/dist/middleware/api-key-auth.js +240 -0
- package/dist/middleware/index.d.ts +2 -0
- package/dist/middleware/index.js +3 -0
- package/dist/openapi.d.ts +4 -0
- package/dist/openapi.js +54 -0
- package/dist/routes/agents.d.ts +12 -0
- package/dist/routes/agents.js +147 -0
- package/dist/routes/chat.d.ts +13 -0
- package/dist/routes/chat.js +293 -0
- package/dist/routes/chatDataStream.d.ts +13 -0
- package/dist/routes/chatDataStream.js +352 -0
- package/dist/routes/mcp.d.ts +13 -0
- package/dist/routes/mcp.js +495 -0
- package/dist/services/AgentSession.d.ts +356 -0
- package/dist/services/AgentSession.js +1208 -0
- package/dist/services/ArtifactParser.d.ts +105 -0
- package/dist/services/ArtifactParser.js +338 -0
- package/dist/services/ArtifactService.d.ts +123 -0
- package/dist/services/ArtifactService.js +612 -0
- package/dist/services/BaseCompressor.d.ts +183 -0
- package/dist/services/BaseCompressor.js +504 -0
- package/dist/services/ConversationCompressor.d.ts +32 -0
- package/dist/services/ConversationCompressor.js +91 -0
- package/dist/services/IncrementalStreamParser.d.ts +98 -0
- package/dist/services/IncrementalStreamParser.js +327 -0
- package/dist/services/MidGenerationCompressor.d.ts +63 -0
- package/dist/services/MidGenerationCompressor.js +104 -0
- package/dist/services/PendingToolApprovalManager.d.ts +62 -0
- package/dist/services/PendingToolApprovalManager.js +133 -0
- package/dist/services/ResponseFormatter.d.ts +39 -0
- package/dist/services/ResponseFormatter.js +152 -0
- package/dist/tools/NativeSandboxExecutor.d.ts +38 -0
- package/dist/tools/NativeSandboxExecutor.js +432 -0
- package/dist/tools/SandboxExecutorFactory.d.ts +36 -0
- package/dist/tools/SandboxExecutorFactory.js +80 -0
- package/dist/tools/VercelSandboxExecutor.d.ts +71 -0
- package/dist/tools/VercelSandboxExecutor.js +340 -0
- package/dist/tools/distill-conversation-history-tool.d.ts +62 -0
- package/dist/tools/distill-conversation-history-tool.js +206 -0
- package/dist/tools/distill-conversation-tool.d.ts +41 -0
- package/dist/tools/distill-conversation-tool.js +141 -0
- package/dist/tools/sandbox-utils.d.ts +18 -0
- package/dist/tools/sandbox-utils.js +53 -0
- package/dist/types/chat.d.ts +27 -0
- package/dist/types/chat.js +1 -0
- package/dist/types/execution-context.d.ts +46 -0
- package/dist/types/execution-context.js +27 -0
- package/dist/types/xml.d.ts +5 -0
- package/dist/utils/SchemaProcessor.d.ts +52 -0
- package/dist/utils/SchemaProcessor.js +182 -0
- package/dist/utils/agent-operations.d.ts +62 -0
- package/dist/utils/agent-operations.js +53 -0
- package/dist/utils/artifact-component-schema.d.ts +42 -0
- package/dist/utils/artifact-component-schema.js +186 -0
- package/dist/utils/cleanup.d.ts +21 -0
- package/dist/utils/cleanup.js +59 -0
- package/dist/utils/data-component-schema.d.ts +2 -0
- package/dist/utils/data-component-schema.js +3 -0
- package/dist/utils/default-status-schemas.d.ts +20 -0
- package/dist/utils/default-status-schemas.js +24 -0
- package/dist/utils/json-postprocessor.d.ts +13 -0
- package/dist/{json-postprocessor.cjs → utils/json-postprocessor.js} +1 -2
- package/dist/utils/model-context-utils.d.ts +39 -0
- package/dist/utils/model-context-utils.js +181 -0
- package/dist/utils/model-resolver.d.ts +6 -0
- package/dist/utils/model-resolver.js +34 -0
- package/dist/utils/schema-validation.d.ts +44 -0
- package/dist/utils/schema-validation.js +97 -0
- package/dist/utils/stream-helpers.d.ts +197 -0
- package/dist/utils/stream-helpers.js +518 -0
- package/dist/utils/stream-registry.d.ts +22 -0
- package/dist/utils/stream-registry.js +34 -0
- package/dist/utils/token-estimator.d.ts +69 -0
- package/dist/utils/token-estimator.js +53 -0
- package/dist/utils/tracer.d.ts +7 -0
- package/dist/utils/tracer.js +7 -0
- package/package.json +5 -20
- package/dist/SandboxExecutorFactory.cjs +0 -895
- package/dist/SandboxExecutorFactory.js +0 -893
- package/dist/SandboxExecutorFactory.js.map +0 -1
- package/dist/chunk-VBDAOXYI.cjs +0 -927
- package/dist/chunk-VBDAOXYI.js +0 -832
- package/dist/chunk-VBDAOXYI.js.map +0 -1
- package/dist/chunk.cjs +0 -34
- package/dist/conversations.cjs +0 -7
- package/dist/conversations.js +0 -7
- package/dist/conversations2.cjs +0 -209
- package/dist/conversations2.js +0 -180
- package/dist/conversations2.js.map +0 -1
- package/dist/dbClient.cjs +0 -9676
- package/dist/dbClient.js +0 -9670
- package/dist/dbClient.js.map +0 -1
- package/dist/dbClient2.cjs +0 -5
- package/dist/dbClient2.js +0 -5
- package/dist/env.cjs +0 -59
- package/dist/env.js.map +0 -1
- package/dist/execution-limits.cjs +0 -260
- package/dist/execution-limits.js +0 -63
- package/dist/execution-limits.js.map +0 -1
- package/dist/index.cjs +0 -11260
- package/dist/index.d.cts +0 -36
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/instrumentation.cjs +0 -12
- package/dist/instrumentation.d.cts +0 -18
- package/dist/instrumentation.d.cts.map +0 -1
- package/dist/instrumentation.d.ts.map +0 -1
- package/dist/instrumentation2.cjs +0 -116
- package/dist/instrumentation2.js +0 -69
- package/dist/instrumentation2.js.map +0 -1
- package/dist/json-postprocessor.js +0 -20
- package/dist/json-postprocessor.js.map +0 -1
- package/dist/logger.cjs +0 -5
- package/dist/logger2.cjs +0 -1
- package/dist/nodefs.cjs +0 -29
- package/dist/nodefs.js +0 -27
- package/dist/nodefs.js.map +0 -1
- package/dist/opfs-ahp.cjs +0 -367
- package/dist/opfs-ahp.js +0 -368
- 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 };
|