@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.
- 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 -11386
- 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 +4 -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 -11411
- 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,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 };
|