@inkeep/agents-run-api 0.0.0-dev-20260105192809 → 0.0.0-dev-20260105194521
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/a2a/handlers.js +2 -1
- package/dist/agents/Agent.d.ts +47 -1
- package/dist/agents/Agent.js +558 -569
- package/dist/agents/generateTaskHandler.js +12 -3
- package/dist/constants/execution-limits/defaults.d.ts +4 -0
- package/dist/constants/execution-limits/defaults.js +5 -1
- package/dist/constants/execution-limits/index.d.ts +2 -2
- package/dist/constants/execution-limits/index.js +8 -3
- package/dist/create-app.d.ts +2 -2
- package/dist/data/conversations.d.ts +43 -3
- package/dist/data/conversations.js +317 -10
- package/dist/handlers/executionHandler.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/services/AgentSession.d.ts +1 -1
- package/dist/services/AgentSession.js +1 -1
- package/dist/services/ArtifactService.js +2 -1
- 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/MidGenerationCompressor.d.ts +35 -63
- package/dist/services/MidGenerationCompressor.js +40 -311
- 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.js +20 -35
- package/dist/utils/model-context-utils.d.ts +10 -2
- package/dist/utils/model-context-utils.js +79 -47
- package/package.json +2 -2
|
@@ -11,6 +11,7 @@ import { TaskState, dbResultToMcpTool, generateId, getAgentById, getAgentWithDef
|
|
|
11
11
|
const logger = getLogger("generateTaskHandler");
|
|
12
12
|
const createTaskHandler = (config, credentialStoreRegistry) => {
|
|
13
13
|
return async (task) => {
|
|
14
|
+
let agent;
|
|
14
15
|
try {
|
|
15
16
|
const userMessage = task.input.parts.filter((part) => part.text).map((part) => part.text).join(" ");
|
|
16
17
|
if (!userMessage.trim()) return {
|
|
@@ -161,7 +162,7 @@ const createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
161
162
|
}
|
|
162
163
|
return mcpTool;
|
|
163
164
|
})) ?? [];
|
|
164
|
-
|
|
165
|
+
agent = new Agent({
|
|
165
166
|
id: config.subAgentId,
|
|
166
167
|
tenantId: config.tenantId,
|
|
167
168
|
projectId: config.projectId,
|
|
@@ -360,6 +361,7 @@ const createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
360
361
|
...config.apiKey ? { apiKey: config.apiKey } : {}
|
|
361
362
|
}
|
|
362
363
|
});
|
|
364
|
+
agent.cleanupCompression();
|
|
363
365
|
const stepContents = response.steps && Array.isArray(response.steps) ? response.steps.flatMap((step) => {
|
|
364
366
|
return step.content && Array.isArray(step.content) ? step.content : [];
|
|
365
367
|
}) : [];
|
|
@@ -410,7 +412,8 @@ const createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
410
412
|
parts: [{
|
|
411
413
|
kind: "data",
|
|
412
414
|
data: artifactData
|
|
413
|
-
}]
|
|
415
|
+
}],
|
|
416
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
414
417
|
}]
|
|
415
418
|
};
|
|
416
419
|
}
|
|
@@ -431,11 +434,17 @@ const createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
431
434
|
status: { state: TaskState.Completed },
|
|
432
435
|
artifacts: [{
|
|
433
436
|
artifactId: generateId(),
|
|
434
|
-
parts
|
|
437
|
+
parts,
|
|
438
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
435
439
|
}]
|
|
436
440
|
};
|
|
437
441
|
} catch (error) {
|
|
438
442
|
console.error("Task handler error:", error);
|
|
443
|
+
try {
|
|
444
|
+
if (agent) agent.cleanupCompression();
|
|
445
|
+
} catch (cleanupError) {
|
|
446
|
+
logger.warn({ cleanupError }, "Failed to cleanup agent compression on error");
|
|
447
|
+
}
|
|
439
448
|
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
440
449
|
const isConnectionRefused = errorMessage.includes("Connection refused. Please check if the MCP server is running.");
|
|
441
450
|
return {
|
|
@@ -42,6 +42,10 @@ declare const executionLimitsDefaults: {
|
|
|
42
42
|
readonly STREAM_TEXT_GAP_THRESHOLD_MS: 2000;
|
|
43
43
|
readonly STREAM_MAX_LIFETIME_MS: 600000;
|
|
44
44
|
readonly CONVERSATION_HISTORY_DEFAULT_LIMIT: 50;
|
|
45
|
+
readonly CONVERSATION_ARTIFACTS_LIMIT: 12;
|
|
46
|
+
readonly COMPRESSION_HARD_LIMIT: 120000;
|
|
47
|
+
readonly COMPRESSION_SAFETY_BUFFER: 20000;
|
|
48
|
+
readonly COMPRESSION_ENABLED: true;
|
|
45
49
|
};
|
|
46
50
|
//#endregion
|
|
47
51
|
export { executionLimitsDefaults };
|
|
@@ -41,7 +41,11 @@ const executionLimitsDefaults = {
|
|
|
41
41
|
STREAM_BUFFER_MAX_SIZE_BYTES: 5242880,
|
|
42
42
|
STREAM_TEXT_GAP_THRESHOLD_MS: 2e3,
|
|
43
43
|
STREAM_MAX_LIFETIME_MS: 6e5,
|
|
44
|
-
CONVERSATION_HISTORY_DEFAULT_LIMIT: 50
|
|
44
|
+
CONVERSATION_HISTORY_DEFAULT_LIMIT: 50,
|
|
45
|
+
CONVERSATION_ARTIFACTS_LIMIT: 12,
|
|
46
|
+
COMPRESSION_HARD_LIMIT: 12e4,
|
|
47
|
+
COMPRESSION_SAFETY_BUFFER: 2e4,
|
|
48
|
+
COMPRESSION_ENABLED: true
|
|
45
49
|
};
|
|
46
50
|
|
|
47
51
|
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { executionLimitsDefaults } from "./defaults.js";
|
|
2
2
|
|
|
3
3
|
//#region src/constants/execution-limits/index.d.ts
|
|
4
|
-
declare const AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS: 3, AGENT_EXECUTION_MAX_GENERATION_STEPS: 5, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING: 270000, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING: 90000, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS: 90000, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS: 600000, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT: 30000, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT: 4, FUNCTION_TOOL_SANDBOX_POOL_TTL_MS: 300000, FUNCTION_TOOL_SANDBOX_MAX_USE_COUNT: 50, FUNCTION_TOOL_SANDBOX_MAX_OUTPUT_SIZE_BYTES: 1048576, FUNCTION_TOOL_SANDBOX_QUEUE_WAIT_TIMEOUT_MS: 30000, FUNCTION_TOOL_SANDBOX_CLEANUP_INTERVAL_MS: 60000, MCP_TOOL_REQUEST_TIMEOUT_MS_DEFAULT: 60000, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS: 100, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS: 10000, DELEGATION_TOOL_BACKOFF_EXPONENT: 2, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS: 20000, A2A_BACKOFF_INITIAL_INTERVAL_MS: 500, A2A_BACKOFF_MAX_INTERVAL_MS: 60000, A2A_BACKOFF_EXPONENT: 1.5, A2A_BACKOFF_MAX_ELAPSED_TIME_MS: 30000, ARTIFACT_GENERATION_MAX_RETRIES: 3, ARTIFACT_SESSION_MAX_PENDING: 100, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES: 3, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS: 1000, ARTIFACT_GENERATION_BACKOFF_MAX_MS: 10000, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS: 300000, SESSION_CLEANUP_INTERVAL_MS: 60000, STATUS_UPDATE_DEFAULT_NUM_EVENTS: 1, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS: 2, STREAM_PARSER_MAX_SNAPSHOT_SIZE: 100, STREAM_PARSER_MAX_STREAMED_SIZE: 1000, STREAM_PARSER_MAX_COLLECTED_PARTS: 10000, STREAM_BUFFER_MAX_SIZE_BYTES: 5242880, STREAM_TEXT_GAP_THRESHOLD_MS: 2000, STREAM_MAX_LIFETIME_MS: 600000, CONVERSATION_HISTORY_DEFAULT_LIMIT: 50;
|
|
4
|
+
declare const AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS: 3, AGENT_EXECUTION_MAX_GENERATION_STEPS: 5, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING: 270000, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING: 90000, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS: 90000, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS: 600000, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT: 30000, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT: 4, FUNCTION_TOOL_SANDBOX_POOL_TTL_MS: 300000, FUNCTION_TOOL_SANDBOX_MAX_USE_COUNT: 50, FUNCTION_TOOL_SANDBOX_MAX_OUTPUT_SIZE_BYTES: 1048576, FUNCTION_TOOL_SANDBOX_QUEUE_WAIT_TIMEOUT_MS: 30000, FUNCTION_TOOL_SANDBOX_CLEANUP_INTERVAL_MS: 60000, MCP_TOOL_REQUEST_TIMEOUT_MS_DEFAULT: 60000, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS: 100, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS: 10000, DELEGATION_TOOL_BACKOFF_EXPONENT: 2, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS: 20000, A2A_BACKOFF_INITIAL_INTERVAL_MS: 500, A2A_BACKOFF_MAX_INTERVAL_MS: 60000, A2A_BACKOFF_EXPONENT: 1.5, A2A_BACKOFF_MAX_ELAPSED_TIME_MS: 30000, ARTIFACT_GENERATION_MAX_RETRIES: 3, ARTIFACT_SESSION_MAX_PENDING: 100, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES: 3, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS: 1000, ARTIFACT_GENERATION_BACKOFF_MAX_MS: 10000, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS: 300000, SESSION_CLEANUP_INTERVAL_MS: 60000, STATUS_UPDATE_DEFAULT_NUM_EVENTS: 1, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS: 2, STREAM_PARSER_MAX_SNAPSHOT_SIZE: 100, STREAM_PARSER_MAX_STREAMED_SIZE: 1000, STREAM_PARSER_MAX_COLLECTED_PARTS: 10000, STREAM_BUFFER_MAX_SIZE_BYTES: 5242880, STREAM_TEXT_GAP_THRESHOLD_MS: 2000, STREAM_MAX_LIFETIME_MS: 600000, CONVERSATION_HISTORY_DEFAULT_LIMIT: 50, CONVERSATION_ARTIFACTS_LIMIT: 12, COMPRESSION_HARD_LIMIT: 120000, COMPRESSION_SAFETY_BUFFER: 20000, COMPRESSION_ENABLED: true;
|
|
5
5
|
//#endregion
|
|
6
|
-
export { A2A_BACKOFF_EXPONENT, A2A_BACKOFF_INITIAL_INTERVAL_MS, A2A_BACKOFF_MAX_ELAPSED_TIME_MS, A2A_BACKOFF_MAX_INTERVAL_MS, AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS, AGENT_EXECUTION_MAX_GENERATION_STEPS, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS, ARTIFACT_GENERATION_BACKOFF_MAX_MS, ARTIFACT_GENERATION_MAX_RETRIES, ARTIFACT_SESSION_MAX_PENDING, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES, CONVERSATION_HISTORY_DEFAULT_LIMIT, DELEGATION_TOOL_BACKOFF_EXPONENT, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, FUNCTION_TOOL_SANDBOX_CLEANUP_INTERVAL_MS, FUNCTION_TOOL_SANDBOX_MAX_OUTPUT_SIZE_BYTES, FUNCTION_TOOL_SANDBOX_MAX_USE_COUNT, FUNCTION_TOOL_SANDBOX_POOL_TTL_MS, FUNCTION_TOOL_SANDBOX_QUEUE_WAIT_TIMEOUT_MS, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS, MCP_TOOL_REQUEST_TIMEOUT_MS_DEFAULT, SESSION_CLEANUP_INTERVAL_MS, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS, STATUS_UPDATE_DEFAULT_NUM_EVENTS, STREAM_BUFFER_MAX_SIZE_BYTES, STREAM_MAX_LIFETIME_MS, STREAM_PARSER_MAX_COLLECTED_PARTS, STREAM_PARSER_MAX_SNAPSHOT_SIZE, STREAM_PARSER_MAX_STREAMED_SIZE, STREAM_TEXT_GAP_THRESHOLD_MS, executionLimitsDefaults };
|
|
6
|
+
export { A2A_BACKOFF_EXPONENT, A2A_BACKOFF_INITIAL_INTERVAL_MS, A2A_BACKOFF_MAX_ELAPSED_TIME_MS, A2A_BACKOFF_MAX_INTERVAL_MS, AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS, AGENT_EXECUTION_MAX_GENERATION_STEPS, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS, ARTIFACT_GENERATION_BACKOFF_MAX_MS, ARTIFACT_GENERATION_MAX_RETRIES, ARTIFACT_SESSION_MAX_PENDING, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES, COMPRESSION_ENABLED, COMPRESSION_HARD_LIMIT, COMPRESSION_SAFETY_BUFFER, CONVERSATION_ARTIFACTS_LIMIT, CONVERSATION_HISTORY_DEFAULT_LIMIT, DELEGATION_TOOL_BACKOFF_EXPONENT, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, FUNCTION_TOOL_SANDBOX_CLEANUP_INTERVAL_MS, FUNCTION_TOOL_SANDBOX_MAX_OUTPUT_SIZE_BYTES, FUNCTION_TOOL_SANDBOX_MAX_USE_COUNT, FUNCTION_TOOL_SANDBOX_POOL_TTL_MS, FUNCTION_TOOL_SANDBOX_QUEUE_WAIT_TIMEOUT_MS, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS, MCP_TOOL_REQUEST_TIMEOUT_MS_DEFAULT, SESSION_CLEANUP_INTERVAL_MS, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS, STATUS_UPDATE_DEFAULT_NUM_EVENTS, STREAM_BUFFER_MAX_SIZE_BYTES, STREAM_MAX_LIFETIME_MS, STREAM_PARSER_MAX_COLLECTED_PARTS, STREAM_PARSER_MAX_SNAPSHOT_SIZE, STREAM_PARSER_MAX_STREAMED_SIZE, STREAM_TEXT_GAP_THRESHOLD_MS, executionLimitsDefaults };
|
|
@@ -4,13 +4,18 @@ import { loadEnvironmentFiles } from "@inkeep/agents-core";
|
|
|
4
4
|
|
|
5
5
|
//#region src/constants/execution-limits/index.ts
|
|
6
6
|
loadEnvironmentFiles();
|
|
7
|
-
const constantsSchema = z.object(Object.fromEntries(Object.keys(executionLimitsDefaults).map((key) =>
|
|
7
|
+
const constantsSchema = z.object(Object.fromEntries(Object.keys(executionLimitsDefaults).map((key) => {
|
|
8
|
+
const defaultValue = executionLimitsDefaults[key];
|
|
9
|
+
const envKey = `AGENTS_${key}`;
|
|
10
|
+
if (typeof defaultValue === "boolean") return [envKey, z.coerce.boolean().optional()];
|
|
11
|
+
else return [envKey, z.coerce.number().optional()];
|
|
12
|
+
})));
|
|
8
13
|
const parseConstants = () => {
|
|
9
14
|
const envOverrides = constantsSchema.parse(process.env);
|
|
10
15
|
return Object.fromEntries(Object.entries(executionLimitsDefaults).map(([key, defaultValue]) => [key, envOverrides[`AGENTS_${key}`] ?? defaultValue]));
|
|
11
16
|
};
|
|
12
17
|
const constants = parseConstants();
|
|
13
|
-
const { AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS, AGENT_EXECUTION_MAX_GENERATION_STEPS, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, FUNCTION_TOOL_SANDBOX_POOL_TTL_MS, FUNCTION_TOOL_SANDBOX_MAX_USE_COUNT, FUNCTION_TOOL_SANDBOX_MAX_OUTPUT_SIZE_BYTES, FUNCTION_TOOL_SANDBOX_QUEUE_WAIT_TIMEOUT_MS, FUNCTION_TOOL_SANDBOX_CLEANUP_INTERVAL_MS, MCP_TOOL_REQUEST_TIMEOUT_MS_DEFAULT, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_EXPONENT, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS, A2A_BACKOFF_INITIAL_INTERVAL_MS, A2A_BACKOFF_MAX_INTERVAL_MS, A2A_BACKOFF_EXPONENT, A2A_BACKOFF_MAX_ELAPSED_TIME_MS, ARTIFACT_GENERATION_MAX_RETRIES, ARTIFACT_SESSION_MAX_PENDING, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS, ARTIFACT_GENERATION_BACKOFF_MAX_MS, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS, SESSION_CLEANUP_INTERVAL_MS, STATUS_UPDATE_DEFAULT_NUM_EVENTS, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS, STREAM_PARSER_MAX_SNAPSHOT_SIZE, STREAM_PARSER_MAX_STREAMED_SIZE, STREAM_PARSER_MAX_COLLECTED_PARTS, STREAM_BUFFER_MAX_SIZE_BYTES, STREAM_TEXT_GAP_THRESHOLD_MS, STREAM_MAX_LIFETIME_MS, CONVERSATION_HISTORY_DEFAULT_LIMIT } = constants;
|
|
18
|
+
const { AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS, AGENT_EXECUTION_MAX_GENERATION_STEPS, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, FUNCTION_TOOL_SANDBOX_POOL_TTL_MS, FUNCTION_TOOL_SANDBOX_MAX_USE_COUNT, FUNCTION_TOOL_SANDBOX_MAX_OUTPUT_SIZE_BYTES, FUNCTION_TOOL_SANDBOX_QUEUE_WAIT_TIMEOUT_MS, FUNCTION_TOOL_SANDBOX_CLEANUP_INTERVAL_MS, MCP_TOOL_REQUEST_TIMEOUT_MS_DEFAULT, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_EXPONENT, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS, A2A_BACKOFF_INITIAL_INTERVAL_MS, A2A_BACKOFF_MAX_INTERVAL_MS, A2A_BACKOFF_EXPONENT, A2A_BACKOFF_MAX_ELAPSED_TIME_MS, ARTIFACT_GENERATION_MAX_RETRIES, ARTIFACT_SESSION_MAX_PENDING, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS, ARTIFACT_GENERATION_BACKOFF_MAX_MS, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS, SESSION_CLEANUP_INTERVAL_MS, STATUS_UPDATE_DEFAULT_NUM_EVENTS, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS, STREAM_PARSER_MAX_SNAPSHOT_SIZE, STREAM_PARSER_MAX_STREAMED_SIZE, STREAM_PARSER_MAX_COLLECTED_PARTS, STREAM_BUFFER_MAX_SIZE_BYTES, STREAM_TEXT_GAP_THRESHOLD_MS, STREAM_MAX_LIFETIME_MS, CONVERSATION_HISTORY_DEFAULT_LIMIT, CONVERSATION_ARTIFACTS_LIMIT, COMPRESSION_HARD_LIMIT, COMPRESSION_SAFETY_BUFFER, COMPRESSION_ENABLED } = constants;
|
|
14
19
|
|
|
15
20
|
//#endregion
|
|
16
|
-
export { A2A_BACKOFF_EXPONENT, A2A_BACKOFF_INITIAL_INTERVAL_MS, A2A_BACKOFF_MAX_ELAPSED_TIME_MS, A2A_BACKOFF_MAX_INTERVAL_MS, AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS, AGENT_EXECUTION_MAX_GENERATION_STEPS, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS, ARTIFACT_GENERATION_BACKOFF_MAX_MS, ARTIFACT_GENERATION_MAX_RETRIES, ARTIFACT_SESSION_MAX_PENDING, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES, CONVERSATION_HISTORY_DEFAULT_LIMIT, DELEGATION_TOOL_BACKOFF_EXPONENT, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, FUNCTION_TOOL_SANDBOX_CLEANUP_INTERVAL_MS, FUNCTION_TOOL_SANDBOX_MAX_OUTPUT_SIZE_BYTES, FUNCTION_TOOL_SANDBOX_MAX_USE_COUNT, FUNCTION_TOOL_SANDBOX_POOL_TTL_MS, FUNCTION_TOOL_SANDBOX_QUEUE_WAIT_TIMEOUT_MS, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS, MCP_TOOL_REQUEST_TIMEOUT_MS_DEFAULT, SESSION_CLEANUP_INTERVAL_MS, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS, STATUS_UPDATE_DEFAULT_NUM_EVENTS, STREAM_BUFFER_MAX_SIZE_BYTES, STREAM_MAX_LIFETIME_MS, STREAM_PARSER_MAX_COLLECTED_PARTS, STREAM_PARSER_MAX_SNAPSHOT_SIZE, STREAM_PARSER_MAX_STREAMED_SIZE, STREAM_TEXT_GAP_THRESHOLD_MS, executionLimitsDefaults };
|
|
21
|
+
export { A2A_BACKOFF_EXPONENT, A2A_BACKOFF_INITIAL_INTERVAL_MS, A2A_BACKOFF_MAX_ELAPSED_TIME_MS, A2A_BACKOFF_MAX_INTERVAL_MS, AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS, AGENT_EXECUTION_MAX_GENERATION_STEPS, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS, ARTIFACT_GENERATION_BACKOFF_MAX_MS, ARTIFACT_GENERATION_MAX_RETRIES, ARTIFACT_SESSION_MAX_PENDING, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES, COMPRESSION_ENABLED, COMPRESSION_HARD_LIMIT, COMPRESSION_SAFETY_BUFFER, CONVERSATION_ARTIFACTS_LIMIT, CONVERSATION_HISTORY_DEFAULT_LIMIT, DELEGATION_TOOL_BACKOFF_EXPONENT, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, FUNCTION_TOOL_SANDBOX_CLEANUP_INTERVAL_MS, FUNCTION_TOOL_SANDBOX_MAX_OUTPUT_SIZE_BYTES, FUNCTION_TOOL_SANDBOX_MAX_USE_COUNT, FUNCTION_TOOL_SANDBOX_POOL_TTL_MS, FUNCTION_TOOL_SANDBOX_QUEUE_WAIT_TIMEOUT_MS, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS, MCP_TOOL_REQUEST_TIMEOUT_MS_DEFAULT, SESSION_CLEANUP_INTERVAL_MS, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS, STATUS_UPDATE_DEFAULT_NUM_EVENTS, STREAM_BUFFER_MAX_SIZE_BYTES, STREAM_MAX_LIFETIME_MS, STREAM_PARSER_MAX_COLLECTED_PARTS, STREAM_PARSER_MAX_SNAPSHOT_SIZE, STREAM_PARSER_MAX_STREAMED_SIZE, STREAM_TEXT_GAP_THRESHOLD_MS, executionLimitsDefaults };
|
package/dist/create-app.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { SandboxConfig } from "./types/execution-context.js";
|
|
2
2
|
import { CredentialStoreRegistry, ServerConfig } from "@inkeep/agents-core";
|
|
3
3
|
import { Hono } from "hono";
|
|
4
|
-
import * as
|
|
4
|
+
import * as hono_types3 from "hono/types";
|
|
5
5
|
|
|
6
6
|
//#region src/create-app.d.ts
|
|
7
|
-
declare function createExecutionHono(serverConfig: ServerConfig, credentialStores: CredentialStoreRegistry, sandboxConfig?: SandboxConfig): Hono<
|
|
7
|
+
declare function createExecutionHono(serverConfig: ServerConfig, credentialStores: CredentialStoreRegistry, sandboxConfig?: SandboxConfig): Hono<hono_types3.BlankEnv, hono_types3.BlankSchema, "/">;
|
|
8
8
|
//#endregion
|
|
9
9
|
export { createExecutionHono };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AgentConversationHistoryConfig, Artifact, ConversationHistoryConfig, ConversationScopeOptions } from "@inkeep/agents-core";
|
|
2
2
|
|
|
3
3
|
//#region src/data/conversations.d.ts
|
|
4
|
-
|
|
4
|
+
declare const compressionLocks: Map<string, Promise<any>>;
|
|
5
5
|
/**
|
|
6
6
|
* Creates default conversation history configuration
|
|
7
7
|
* @param mode - The conversation history mode ('full' | 'scoped' | 'none')
|
|
@@ -64,7 +64,33 @@ declare function getFormattedConversationHistory({
|
|
|
64
64
|
conversationId,
|
|
65
65
|
currentMessage,
|
|
66
66
|
options,
|
|
67
|
-
filters
|
|
67
|
+
filters,
|
|
68
|
+
sessionId,
|
|
69
|
+
summarizerModel
|
|
70
|
+
}: {
|
|
71
|
+
tenantId: string;
|
|
72
|
+
projectId: string;
|
|
73
|
+
conversationId: string;
|
|
74
|
+
currentMessage?: string;
|
|
75
|
+
options?: ConversationHistoryConfig;
|
|
76
|
+
filters?: ConversationScopeOptions;
|
|
77
|
+
sessionId?: string;
|
|
78
|
+
summarizerModel?: any;
|
|
79
|
+
}): Promise<string>;
|
|
80
|
+
/**
|
|
81
|
+
* Modern conversation history retrieval with compression support
|
|
82
|
+
* Replaces getFormattedConversationHistory with built-in compression when needed
|
|
83
|
+
*/
|
|
84
|
+
declare function getConversationHistoryWithCompression({
|
|
85
|
+
tenantId,
|
|
86
|
+
projectId,
|
|
87
|
+
conversationId,
|
|
88
|
+
currentMessage,
|
|
89
|
+
options,
|
|
90
|
+
filters,
|
|
91
|
+
summarizerModel,
|
|
92
|
+
streamRequestId,
|
|
93
|
+
fullContextSize
|
|
68
94
|
}: {
|
|
69
95
|
tenantId: string;
|
|
70
96
|
projectId: string;
|
|
@@ -72,7 +98,21 @@ declare function getFormattedConversationHistory({
|
|
|
72
98
|
currentMessage?: string;
|
|
73
99
|
options?: ConversationHistoryConfig;
|
|
74
100
|
filters?: ConversationScopeOptions;
|
|
101
|
+
summarizerModel?: any;
|
|
102
|
+
streamRequestId?: string;
|
|
103
|
+
fullContextSize?: number;
|
|
75
104
|
}): Promise<string>;
|
|
105
|
+
/**
|
|
106
|
+
* Apply conversation compression using the BaseCompressor infrastructure
|
|
107
|
+
*/
|
|
108
|
+
declare function compressConversationIfNeeded(messages: any[], params: {
|
|
109
|
+
conversationId: string;
|
|
110
|
+
tenantId: string;
|
|
111
|
+
projectId: string;
|
|
112
|
+
summarizerModel: any;
|
|
113
|
+
streamRequestId?: string;
|
|
114
|
+
fullContextSize?: number;
|
|
115
|
+
}): Promise<any[]>;
|
|
76
116
|
/**
|
|
77
117
|
* Get artifacts that are within the scope of the conversation history
|
|
78
118
|
* Only returns artifacts from messages that are actually visible to the LLM
|
|
@@ -85,4 +125,4 @@ declare function getConversationScopedArtifacts(params: {
|
|
|
85
125
|
historyConfig: AgentConversationHistoryConfig;
|
|
86
126
|
}): Promise<Artifact[]>;
|
|
87
127
|
//#endregion
|
|
88
|
-
export { createDefaultConversationHistoryConfig, getConversationScopedArtifacts, getFormattedConversationHistory, getFullConversationContext, getScopedHistory, getUserFacingHistory, saveA2AMessageResponse };
|
|
128
|
+
export { compressConversationIfNeeded, compressionLocks, createDefaultConversationHistoryConfig, getConversationHistoryWithCompression, getConversationScopedArtifacts, getFormattedConversationHistory, getFullConversationContext, getScopedHistory, getUserFacingHistory, saveA2AMessageResponse };
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { getLogger } from "../logger.js";
|
|
1
2
|
import dbClient_default from "./db/dbClient.js";
|
|
2
|
-
import { CONVERSATION_HISTORY_DEFAULT_LIMIT as CONVERSATION_HISTORY_DEFAULT_LIMIT$1 } from "../constants/execution-limits/index.js";
|
|
3
|
+
import { CONVERSATION_ARTIFACTS_LIMIT, CONVERSATION_HISTORY_DEFAULT_LIMIT as CONVERSATION_HISTORY_DEFAULT_LIMIT$1 } from "../constants/execution-limits/index.js";
|
|
4
|
+
import { getCompressionConfigForModel } from "../utils/model-context-utils.js";
|
|
5
|
+
import { ConversationCompressor } from "../services/ConversationCompressor.js";
|
|
3
6
|
import { CONVERSATION_HISTORY_MAX_OUTPUT_TOKENS_DEFAULT, createMessage, generateId, getConversationHistory } from "@inkeep/agents-core";
|
|
4
7
|
|
|
5
8
|
//#region src/data/conversations.ts
|
|
9
|
+
const logger = getLogger("conversations");
|
|
10
|
+
const compressionLocks = /* @__PURE__ */ new Map();
|
|
6
11
|
/**
|
|
7
12
|
* Creates default conversation history configuration
|
|
8
13
|
* @param mode - The conversation history mode ('full' | 'scoped' | 'none')
|
|
@@ -64,14 +69,39 @@ async function saveA2AMessageResponse(response, params) {
|
|
|
64
69
|
*/
|
|
65
70
|
async function getScopedHistory({ tenantId, projectId, conversationId, filters, options }) {
|
|
66
71
|
try {
|
|
67
|
-
const
|
|
72
|
+
const allMessages = await getConversationHistory(dbClient_default)({
|
|
68
73
|
scopes: {
|
|
69
74
|
tenantId,
|
|
70
75
|
projectId
|
|
71
76
|
},
|
|
72
77
|
conversationId,
|
|
73
|
-
options
|
|
78
|
+
options: {
|
|
79
|
+
...options,
|
|
80
|
+
limit: 1e4,
|
|
81
|
+
includeInternal: true,
|
|
82
|
+
maxOutputTokens: void 0
|
|
83
|
+
}
|
|
74
84
|
});
|
|
85
|
+
const compressionSummaries = allMessages.filter((msg) => msg.messageType === "compression_summary" && msg.metadata?.compressionType === "conversation_history");
|
|
86
|
+
const latestCompressionSummary = compressionSummaries.length > 0 ? compressionSummaries.reduce((latest, current) => new Date(current.createdAt) > new Date(latest.createdAt) ? current : latest) : null;
|
|
87
|
+
let messages;
|
|
88
|
+
if (latestCompressionSummary) {
|
|
89
|
+
const summaryDate = new Date(latestCompressionSummary.createdAt);
|
|
90
|
+
messages = [latestCompressionSummary, ...allMessages.filter((msg) => new Date(msg.createdAt) > summaryDate && msg.messageType !== "compression_summary")];
|
|
91
|
+
logger.debug({
|
|
92
|
+
conversationId,
|
|
93
|
+
latestCompressionSummaryId: latestCompressionSummary.id,
|
|
94
|
+
summaryDate: summaryDate.toISOString(),
|
|
95
|
+
messagesAfterCompression: messages.length - 1,
|
|
96
|
+
totalMessages: allMessages.length
|
|
97
|
+
}, "Retrieved conversation with compression summary");
|
|
98
|
+
} else {
|
|
99
|
+
messages = allMessages;
|
|
100
|
+
logger.debug({
|
|
101
|
+
conversationId,
|
|
102
|
+
totalMessages: messages.length
|
|
103
|
+
}, "Retrieved conversation without compression summary");
|
|
104
|
+
}
|
|
75
105
|
if (!filters || !filters.subAgentId && !filters.taskId && !filters.delegationId && filters.isDelegated === void 0) return messages;
|
|
76
106
|
return messages.filter((msg) => {
|
|
77
107
|
if (msg.role === "user") return true;
|
|
@@ -139,7 +169,7 @@ async function getFullConversationContext(tenantId, projectId, conversationId, m
|
|
|
139
169
|
/**
|
|
140
170
|
* Get formatted conversation history for a2a
|
|
141
171
|
*/
|
|
142
|
-
async function getFormattedConversationHistory({ tenantId, projectId, conversationId, currentMessage, options, filters }) {
|
|
172
|
+
async function getFormattedConversationHistory({ tenantId, projectId, conversationId, currentMessage, options, filters, sessionId, summarizerModel }) {
|
|
143
173
|
const conversationHistory = await getScopedHistory({
|
|
144
174
|
tenantId,
|
|
145
175
|
projectId,
|
|
@@ -152,12 +182,284 @@ async function getFormattedConversationHistory({ tenantId, projectId, conversati
|
|
|
152
182
|
if (conversationHistory[conversationHistory.length - 1].content.text === currentMessage) messagesToFormat = conversationHistory.slice(0, -1);
|
|
153
183
|
}
|
|
154
184
|
if (!messagesToFormat.length) return "";
|
|
155
|
-
|
|
185
|
+
let finalMessagesToFormat = messagesToFormat;
|
|
186
|
+
if (sessionId && summarizerModel) finalMessagesToFormat = await compressConversationIfNeeded(messagesToFormat, {
|
|
187
|
+
conversationId,
|
|
188
|
+
tenantId,
|
|
189
|
+
projectId,
|
|
190
|
+
summarizerModel,
|
|
191
|
+
streamRequestId: sessionId
|
|
192
|
+
});
|
|
193
|
+
return `<conversation_history>\n${finalMessagesToFormat.map((msg) => {
|
|
194
|
+
let roleLabel;
|
|
195
|
+
if (msg.role === "user") roleLabel = "user";
|
|
196
|
+
else if (msg.role === "agent" && (msg.messageType === "a2a-request" || msg.messageType === "a2a-response")) roleLabel = `${msg.fromSubAgentId || msg.fromExternalAgentId || "unknown"} to ${msg.toSubAgentId || msg.toExternalAgentId || "unknown"}`;
|
|
197
|
+
else if (msg.role === "agent" && msg.messageType === "chat") roleLabel = `${msg.fromSubAgentId || "unknown"} to User`;
|
|
198
|
+
else if (msg.role === "assistant" && msg.messageType === "tool-result") roleLabel = `${msg.fromSubAgentId || "unknown"} tool: ${msg.metadata?.a2a_metadata?.toolName || "unknown"}`;
|
|
199
|
+
else roleLabel = msg.role || "system";
|
|
200
|
+
return `${roleLabel}: """${msg.content.text}"""`;
|
|
201
|
+
}).join("\n")}\n</conversation_history>\n`;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Modern conversation history retrieval with compression support
|
|
205
|
+
* Replaces getFormattedConversationHistory with built-in compression when needed
|
|
206
|
+
*/
|
|
207
|
+
async function getConversationHistoryWithCompression({ tenantId, projectId, conversationId, currentMessage, options, filters, summarizerModel, streamRequestId, fullContextSize }) {
|
|
208
|
+
const conversationHistory = await getScopedHistory({
|
|
209
|
+
tenantId,
|
|
210
|
+
projectId,
|
|
211
|
+
conversationId,
|
|
212
|
+
filters,
|
|
213
|
+
options: {
|
|
214
|
+
...options ?? createDefaultConversationHistoryConfig(),
|
|
215
|
+
includeInternal: true,
|
|
216
|
+
maxOutputTokens: void 0
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
let messagesToFormat = conversationHistory;
|
|
220
|
+
if (currentMessage && conversationHistory.length > 0) {
|
|
221
|
+
if (conversationHistory[conversationHistory.length - 1].content.text === currentMessage) messagesToFormat = conversationHistory.slice(0, -1);
|
|
222
|
+
}
|
|
223
|
+
if (!messagesToFormat.length) return "";
|
|
224
|
+
if (summarizerModel) {
|
|
225
|
+
const compressionInfo = getCompressionConfigForModel(summarizerModel, .5);
|
|
226
|
+
const estimatedTokens = messagesToFormat.reduce((total, msg) => {
|
|
227
|
+
const text = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
|
|
228
|
+
return total + Math.ceil(text.length / 4);
|
|
229
|
+
}, 0);
|
|
230
|
+
const remaining = compressionInfo.hardLimit - estimatedTokens;
|
|
231
|
+
const compressionNeeded = remaining <= compressionInfo.safetyBuffer;
|
|
232
|
+
const contextWindowUtilization = compressionInfo.modelContextInfo.contextWindow ? (estimatedTokens / compressionInfo.modelContextInfo.contextWindow * 100).toFixed(1) : "unknown";
|
|
233
|
+
logger.info({
|
|
234
|
+
conversationId,
|
|
235
|
+
model: summarizerModel.model,
|
|
236
|
+
modelContextWindow: compressionInfo.modelContextInfo.contextWindow,
|
|
237
|
+
currentTokens: estimatedTokens,
|
|
238
|
+
hardLimit: compressionInfo.hardLimit,
|
|
239
|
+
safetyBuffer: compressionInfo.safetyBuffer,
|
|
240
|
+
remaining,
|
|
241
|
+
compressionNeeded,
|
|
242
|
+
contextWindowUtilization: `${contextWindowUtilization}%`,
|
|
243
|
+
messageCount: messagesToFormat.length,
|
|
244
|
+
source: compressionInfo.source
|
|
245
|
+
}, "Conversation history fetch - model context analysis");
|
|
246
|
+
const compressionSummary = messagesToFormat.find((msg) => msg.messageType === "compression_summary" && msg.metadata?.compressionType === "conversation_history");
|
|
247
|
+
if (compressionSummary) {
|
|
248
|
+
const messagesAfterCompression = messagesToFormat.filter((msg) => new Date(msg.createdAt) > new Date(compressionSummary.createdAt) && msg.messageType !== "compression_summary");
|
|
249
|
+
if (messagesAfterCompression.length >= 10) {
|
|
250
|
+
logger.info({
|
|
251
|
+
conversationId,
|
|
252
|
+
messagesAfterLastCompression: messagesAfterCompression.length,
|
|
253
|
+
lastCompressionDate: compressionSummary.createdAt
|
|
254
|
+
}, "Checking if re-compression needed for new messages");
|
|
255
|
+
const newMessagesCompressed = await compressConversationIfNeeded(messagesAfterCompression, {
|
|
256
|
+
conversationId,
|
|
257
|
+
tenantId,
|
|
258
|
+
projectId,
|
|
259
|
+
summarizerModel,
|
|
260
|
+
streamRequestId,
|
|
261
|
+
fullContextSize
|
|
262
|
+
});
|
|
263
|
+
if (newMessagesCompressed.length === 1 && newMessagesCompressed[0].messageType === "compression_summary") {
|
|
264
|
+
messagesToFormat = [compressionSummary, ...newMessagesCompressed];
|
|
265
|
+
logger.info({
|
|
266
|
+
conversationId,
|
|
267
|
+
totalCompressedMessages: messagesToFormat.length
|
|
268
|
+
}, "Re-compression completed - combined with existing summary");
|
|
269
|
+
} else messagesToFormat = [compressionSummary, ...messagesAfterCompression];
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
messagesToFormat.length;
|
|
273
|
+
messagesToFormat = await compressConversationIfNeeded(messagesToFormat, {
|
|
274
|
+
conversationId,
|
|
275
|
+
tenantId,
|
|
276
|
+
projectId,
|
|
277
|
+
summarizerModel,
|
|
278
|
+
streamRequestId,
|
|
279
|
+
fullContextSize
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const compressedTokens = messagesToFormat.reduce((total, msg) => {
|
|
283
|
+
const text = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
|
|
284
|
+
return total + Math.ceil(text.length / 4);
|
|
285
|
+
}, 0);
|
|
286
|
+
const compressionSummaryMessages = messagesToFormat.filter((msg) => msg.messageType === "compression_summary");
|
|
287
|
+
if (compressionSummaryMessages.length > 0) logger.info({
|
|
288
|
+
conversationId,
|
|
289
|
+
finalMessages: messagesToFormat.length,
|
|
290
|
+
compressionSummaries: compressionSummaryMessages.length,
|
|
291
|
+
finalTokens: compressedTokens,
|
|
292
|
+
contextWindowUtilization: compressionInfo.modelContextInfo.contextWindow ? `${(compressedTokens / compressionInfo.modelContextInfo.contextWindow * 100).toFixed(1)}%` : "unknown"
|
|
293
|
+
}, "Final conversation history with compression summaries");
|
|
294
|
+
}
|
|
295
|
+
return formatMessagesAsConversationHistory(messagesToFormat);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Apply conversation compression using the BaseCompressor infrastructure
|
|
299
|
+
*/
|
|
300
|
+
async function compressConversationIfNeeded(messages, params) {
|
|
301
|
+
const { conversationId, tenantId, projectId, summarizerModel, streamRequestId } = params;
|
|
302
|
+
const lockKey = `${conversationId}_${tenantId}_${projectId}`;
|
|
303
|
+
if (compressionLocks.has(lockKey)) {
|
|
304
|
+
logger.debug({ conversationId }, "Waiting for existing compression to complete");
|
|
305
|
+
await compressionLocks.get(lockKey);
|
|
306
|
+
return messages;
|
|
307
|
+
}
|
|
308
|
+
const compressionPromise = performActualCompression(messages, params);
|
|
309
|
+
compressionLocks.set(lockKey, compressionPromise);
|
|
310
|
+
try {
|
|
311
|
+
return await compressionPromise;
|
|
312
|
+
} finally {
|
|
313
|
+
compressionLocks.delete(lockKey);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
async function performActualCompression(messages, params) {
|
|
317
|
+
const { conversationId, tenantId, projectId, summarizerModel, streamRequestId } = params;
|
|
318
|
+
const compressor = new ConversationCompressor(streamRequestId || conversationId, conversationId, tenantId, projectId, void 0, summarizerModel);
|
|
319
|
+
if (!compressor.isCompressionNeeded(messages)) return messages;
|
|
320
|
+
logger.info({
|
|
321
|
+
conversationId,
|
|
322
|
+
messageCount: messages.length
|
|
323
|
+
}, "Applying conversation-level compression");
|
|
324
|
+
try {
|
|
325
|
+
const compressionResult = await compressor.safeCompress(messages, params.fullContextSize);
|
|
326
|
+
if (compressionResult.summary) {
|
|
327
|
+
const compressionMessage = await createMessage(dbClient_default)({
|
|
328
|
+
id: generateId(),
|
|
329
|
+
tenantId,
|
|
330
|
+
projectId,
|
|
331
|
+
conversationId,
|
|
332
|
+
role: "system",
|
|
333
|
+
content: { text: buildCompressionSummaryMessage(compressionResult.summary, compressionResult.artifactIds) },
|
|
334
|
+
visibility: "internal",
|
|
335
|
+
messageType: "compression_summary",
|
|
336
|
+
metadata: { a2a_metadata: {
|
|
337
|
+
compressionType: "conversation_history",
|
|
338
|
+
artifactIds: compressionResult.artifactIds,
|
|
339
|
+
originalMessageCount: messages.length,
|
|
340
|
+
compressedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
341
|
+
summaryData: compressionResult.summary
|
|
342
|
+
} }
|
|
343
|
+
});
|
|
344
|
+
logger.debug({
|
|
345
|
+
conversationId,
|
|
346
|
+
originalMessageCount: messages.length,
|
|
347
|
+
artifactCount: compressionResult.artifactIds?.length || 0,
|
|
348
|
+
compressionMessageId: compressionMessage.id
|
|
349
|
+
}, "Conversation compression saved to messages table");
|
|
350
|
+
compressor.fullCleanup();
|
|
351
|
+
return [compressionMessage];
|
|
352
|
+
}
|
|
353
|
+
compressor.fullCleanup();
|
|
354
|
+
return messages;
|
|
355
|
+
} catch (error) {
|
|
356
|
+
logger.error({
|
|
357
|
+
conversationId,
|
|
358
|
+
error: error instanceof Error ? error.message : String(error)
|
|
359
|
+
}, "Conversation compression failed, using original messages");
|
|
360
|
+
compressor.fullCleanup();
|
|
361
|
+
return messages;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Build a summary message for compressed conversation content
|
|
366
|
+
*/
|
|
367
|
+
function buildCompressionSummaryMessage(summary, artifactIds) {
|
|
368
|
+
const parts = [];
|
|
369
|
+
parts.push("=== CONVERSATION SUMMARY ===");
|
|
370
|
+
parts.push("Previous conversation has been compressed to save context space.");
|
|
371
|
+
parts.push("");
|
|
372
|
+
if (summary.conversation_overview) parts.push(`📋 Overview: ${summary.conversation_overview}`);
|
|
373
|
+
if (summary.user_goals?.primary) {
|
|
374
|
+
parts.push(`🎯 Primary Goal: ${summary.user_goals.primary}`);
|
|
375
|
+
if (summary.user_goals.secondary && summary.user_goals.secondary.length > 0) {
|
|
376
|
+
parts.push(`🎯 Secondary Goals:`);
|
|
377
|
+
summary.user_goals.secondary.forEach((goal) => parts.push(` • ${goal}`));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
if (summary.key_outcomes) {
|
|
381
|
+
if (summary.key_outcomes.completed && summary.key_outcomes.completed.length > 0) {
|
|
382
|
+
parts.push(`✅ Completed:`);
|
|
383
|
+
summary.key_outcomes.completed.forEach((item) => parts.push(` • ${item}`));
|
|
384
|
+
}
|
|
385
|
+
if (summary.key_outcomes.discoveries && summary.key_outcomes.discoveries.length > 0) {
|
|
386
|
+
parts.push(`💡 Key Discoveries:`);
|
|
387
|
+
summary.key_outcomes.discoveries.forEach((discovery) => parts.push(` • ${discovery}`));
|
|
388
|
+
}
|
|
389
|
+
if (summary.key_outcomes.partial && summary.key_outcomes.partial.length > 0) {
|
|
390
|
+
parts.push(`⏳ In Progress:`);
|
|
391
|
+
summary.key_outcomes.partial.forEach((item) => parts.push(` • ${item}`));
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (summary.context_for_continuation) {
|
|
395
|
+
if (summary.context_for_continuation.current_state) parts.push(`📍 Current State: ${summary.context_for_continuation.current_state}`);
|
|
396
|
+
if (summary.context_for_continuation.next_logical_steps && summary.context_for_continuation.next_logical_steps.length > 0) {
|
|
397
|
+
parts.push(`📝 Next Steps:`);
|
|
398
|
+
summary.context_for_continuation.next_logical_steps.forEach((step) => parts.push(` • ${step}`));
|
|
399
|
+
}
|
|
400
|
+
if (summary.context_for_continuation.important_context && summary.context_for_continuation.important_context.length > 0) {
|
|
401
|
+
parts.push(`🔑 Key Context:`);
|
|
402
|
+
summary.context_for_continuation.important_context.forEach((context) => parts.push(` • ${context}`));
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (summary.technical_context) {
|
|
406
|
+
if (summary.technical_context.technologies && summary.technical_context.technologies.length > 0) parts.push(`🔧 Technologies: ${summary.technical_context.technologies.join(", ")}`);
|
|
407
|
+
if (summary.technical_context.issues_encountered && summary.technical_context.issues_encountered.length > 0) {
|
|
408
|
+
parts.push(`⚠️ Issues Encountered:`);
|
|
409
|
+
summary.technical_context.issues_encountered.forEach((issue) => parts.push(` • ${issue}`));
|
|
410
|
+
}
|
|
411
|
+
if (summary.technical_context.solutions_applied && summary.technical_context.solutions_applied.length > 0) {
|
|
412
|
+
parts.push(`✨ Solutions Applied:`);
|
|
413
|
+
summary.technical_context.solutions_applied.forEach((solution) => parts.push(` • ${solution}`));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (summary.high_level) parts.push(`📋 Overview: ${summary.high_level}`);
|
|
417
|
+
if (summary.user_intent) parts.push(`🎯 User Goal: ${summary.user_intent}`);
|
|
418
|
+
if (summary.decisions && summary.decisions.length > 0) {
|
|
419
|
+
parts.push(`✅ Key Decisions Made:`);
|
|
420
|
+
summary.decisions.forEach((decision) => parts.push(` • ${decision}`));
|
|
421
|
+
}
|
|
422
|
+
if (summary.next_steps && summary.next_steps.length > 0) {
|
|
423
|
+
parts.push(`📝 Planned Next Steps:`);
|
|
424
|
+
summary.next_steps.forEach((step) => parts.push(` • ${step}`));
|
|
425
|
+
}
|
|
426
|
+
if (summary.open_questions && summary.open_questions.length > 0) {
|
|
427
|
+
parts.push(`❓ Outstanding Questions:`);
|
|
428
|
+
summary.open_questions.forEach((question) => parts.push(` • ${question}`));
|
|
429
|
+
}
|
|
430
|
+
if (summary.conversation_artifacts && summary.conversation_artifacts.length > 0) {
|
|
431
|
+
parts.push(`💾 Research Artifacts: ${summary.conversation_artifacts.length} created from previous work`);
|
|
432
|
+
summary.conversation_artifacts.forEach((artifact) => {
|
|
433
|
+
parts.push(` [ARTIFACT: ${artifact.id}]`);
|
|
434
|
+
parts.push(` 📋 ${artifact.name || "Research Data"}`);
|
|
435
|
+
if (artifact.content_summary) parts.push(` 📝 ${artifact.content_summary}`);
|
|
436
|
+
if (artifact.tool_name && artifact.tool_name !== "unknown") parts.push(` 🔧 Source: ${artifact.tool_name}`);
|
|
437
|
+
parts.push(` 🔗 Reference: <artifact:ref id="${artifact.id}" tool_call_id="${artifact.tool_call_id}" />`);
|
|
438
|
+
parts.push("");
|
|
439
|
+
});
|
|
440
|
+
} else if (artifactIds && artifactIds.length > 0) {
|
|
441
|
+
parts.push(`💾 Research Artifacts: ${artifactIds.length} created from previous work`);
|
|
442
|
+
artifactIds.forEach((artifactId) => {
|
|
443
|
+
parts.push(` [ARTIFACT: ${artifactId}]`);
|
|
444
|
+
parts.push(` 🔗 Reference: <artifact:ref id="${artifactId}" />`);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
parts.push("");
|
|
448
|
+
parts.push("=== END SUMMARY ===");
|
|
449
|
+
parts.push("Recent conversation continues below...");
|
|
450
|
+
return parts.join("\n");
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Format messages into conversation history string (extracted from legacy method)
|
|
454
|
+
*/
|
|
455
|
+
function formatMessagesAsConversationHistory(messages) {
|
|
456
|
+
return `<conversation_history>\n${messages.map((msg) => {
|
|
156
457
|
let roleLabel;
|
|
157
458
|
if (msg.role === "user") roleLabel = "user";
|
|
158
459
|
else if (msg.role === "agent" && (msg.messageType === "a2a-request" || msg.messageType === "a2a-response")) roleLabel = `${msg.fromSubAgentId || msg.fromExternalAgentId || "unknown"} to ${msg.toSubAgentId || msg.toExternalAgentId || "unknown"}`;
|
|
159
460
|
else if (msg.role === "agent" && msg.messageType === "chat") roleLabel = `${msg.fromSubAgentId || "unknown"} to User`;
|
|
160
461
|
else if (msg.role === "assistant" && msg.messageType === "tool-result") roleLabel = `${msg.fromSubAgentId || "unknown"} tool: ${msg.metadata?.a2a_metadata?.toolName || "unknown"}`;
|
|
462
|
+
else if (msg.role === "system") roleLabel = "system";
|
|
161
463
|
else roleLabel = msg.role || "system";
|
|
162
464
|
return `${roleLabel}: """${msg.content.text}"""`;
|
|
163
465
|
}).join("\n")}\n</conversation_history>\n`;
|
|
@@ -194,14 +496,19 @@ async function getConversationScopedArtifacts(params) {
|
|
|
194
496
|
});
|
|
195
497
|
referenceArtifacts.push(...artifacts);
|
|
196
498
|
}
|
|
197
|
-
(await import("../logger.js")).getLogger("conversations")
|
|
499
|
+
const logger$1 = (await import("../logger.js")).getLogger("conversations");
|
|
500
|
+
const ARTIFACT_COUNT_LIMIT = CONVERSATION_ARTIFACTS_LIMIT;
|
|
501
|
+
const limitedArtifacts = referenceArtifacts.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()).slice(0, ARTIFACT_COUNT_LIMIT);
|
|
502
|
+
logger$1.debug({
|
|
198
503
|
conversationId,
|
|
199
504
|
visibleMessages: visibleMessages.length,
|
|
200
505
|
visibleTasks: visibleTaskIds.length,
|
|
201
|
-
|
|
506
|
+
totalArtifacts: referenceArtifacts.length,
|
|
507
|
+
limitedArtifacts: limitedArtifacts.length,
|
|
508
|
+
artifactLimit: ARTIFACT_COUNT_LIMIT,
|
|
202
509
|
historyMode: historyConfig.mode
|
|
203
|
-
}, "Loaded conversation-scoped artifacts");
|
|
204
|
-
return
|
|
510
|
+
}, "Loaded conversation-scoped artifacts with count limit");
|
|
511
|
+
return limitedArtifacts;
|
|
205
512
|
} catch (error) {
|
|
206
513
|
(await import("../logger.js")).getLogger("conversations").error({
|
|
207
514
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
@@ -212,4 +519,4 @@ async function getConversationScopedArtifacts(params) {
|
|
|
212
519
|
}
|
|
213
520
|
|
|
214
521
|
//#endregion
|
|
215
|
-
export { createDefaultConversationHistoryConfig, getConversationScopedArtifacts, getFormattedConversationHistory, getFullConversationContext, getScopedHistory, getUserFacingHistory, saveA2AMessageResponse };
|
|
522
|
+
export { compressConversationIfNeeded, compressionLocks, createDefaultConversationHistoryConfig, getConversationHistoryWithCompression, getConversationScopedArtifacts, getFormattedConversationHistory, getFullConversationContext, getScopedHistory, getUserFacingHistory, saveA2AMessageResponse };
|
|
@@ -2,8 +2,8 @@ import { getLogger } from "../logger.js";
|
|
|
2
2
|
import { flushBatchProcessor } from "../instrumentation.js";
|
|
3
3
|
import dbClient_default from "../data/db/dbClient.js";
|
|
4
4
|
import { AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS } from "../constants/execution-limits/index.js";
|
|
5
|
-
import { registerStreamHelper, unregisterStreamHelper } from "../utils/stream-registry.js";
|
|
6
5
|
import { tracer } from "../utils/tracer.js";
|
|
6
|
+
import { registerStreamHelper, unregisterStreamHelper } from "../utils/stream-registry.js";
|
|
7
7
|
import { agentSessionManager } from "../services/AgentSession.js";
|
|
8
8
|
import { resolveModelConfig } from "../utils/model-resolver.js";
|
|
9
9
|
import { agentInitializingOp, completionOp, errorOp } from "../utils/agent-operations.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -3,14 +3,14 @@ import { createExecutionHono } from "./create-app.js";
|
|
|
3
3
|
import "./env.js";
|
|
4
4
|
import { CredentialStore, ServerConfig } from "@inkeep/agents-core";
|
|
5
5
|
import { Hono } from "hono";
|
|
6
|
-
import * as
|
|
6
|
+
import * as hono_types0 from "hono/types";
|
|
7
7
|
|
|
8
8
|
//#region src/index.d.ts
|
|
9
|
-
declare const app: Hono<
|
|
9
|
+
declare const app: Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
|
|
10
10
|
declare function createExecutionApp(config?: {
|
|
11
11
|
serverConfig?: ServerConfig;
|
|
12
12
|
credentialStores?: CredentialStore[];
|
|
13
13
|
sandboxConfig?: SandboxConfig;
|
|
14
|
-
}): Hono<
|
|
14
|
+
}): Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { Hono, type NativeSandboxConfig, type SandboxConfig, type VercelSandboxConfig, createExecutionApp, createExecutionHono, app as default };
|
|
@@ -128,7 +128,7 @@ interface CompressionEventData {
|
|
|
128
128
|
artifactCount: number;
|
|
129
129
|
contextSizeBefore: number;
|
|
130
130
|
contextSizeAfter: number;
|
|
131
|
-
compressionType: 'mid_generation' | '
|
|
131
|
+
compressionType: 'mid_generation' | 'conversation_level';
|
|
132
132
|
}
|
|
133
133
|
interface ErrorEventData {
|
|
134
134
|
message: string;
|
|
@@ -2,10 +2,10 @@ import { getLogger } from "../logger.js";
|
|
|
2
2
|
import dbClient_default from "../data/db/dbClient.js";
|
|
3
3
|
import { ARTIFACT_GENERATION_BACKOFF_INITIAL_MS, ARTIFACT_GENERATION_BACKOFF_MAX_MS, ARTIFACT_GENERATION_MAX_RETRIES, ARTIFACT_SESSION_MAX_PENDING, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS, STATUS_UPDATE_DEFAULT_NUM_EVENTS } from "../constants/execution-limits/index.js";
|
|
4
4
|
import { toolSessionManager } from "../agents/ToolSessionManager.js";
|
|
5
|
+
import { setSpanWithError as setSpanWithError$1, tracer } from "../utils/tracer.js";
|
|
5
6
|
import { getFormattedConversationHistory } from "../data/conversations.js";
|
|
6
7
|
import { defaultStatusSchemas } from "../utils/default-status-schemas.js";
|
|
7
8
|
import { getStreamHelper } from "../utils/stream-registry.js";
|
|
8
|
-
import { setSpanWithError as setSpanWithError$1, tracer } from "../utils/tracer.js";
|
|
9
9
|
import { ArtifactService } from "./ArtifactService.js";
|
|
10
10
|
import { ArtifactParser } from "./ArtifactParser.js";
|
|
11
11
|
import { z } from "@hono/zod-openapi";
|