@inkeep/agents-run-api 0.36.1 → 0.37.1
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/{SandboxExecutorFactory-NUNGK35F.js → SandboxExecutorFactory-FVKDJKKZ.js} +2 -3
- package/dist/{chunk-H2IQDFCM.js → chunk-AZFBQY6E.js} +1 -1
- package/dist/{chunk-UZXC6MEO.js → chunk-IYG4HUQ6.js} +2 -0
- package/dist/{chunk-7C3GUAQD.js → chunk-M46DFVYB.js} +2 -2
- package/dist/{chunk-CWFQPSTI.js → chunk-V4RNZ6BX.js} +1 -1
- package/dist/{conversations-ZCZG5434.js → conversations-NZLQK64L.js} +1 -1
- package/dist/dbClient-BXOIYVCJ.js +1 -0
- package/dist/index.cjs +575 -413
- package/dist/index.js +573 -410
- package/dist/instrumentation.cjs +2 -0
- package/dist/instrumentation.js +1 -1
- package/package.json +5 -4
- package/dist/dbClient-XO7KFTE7.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { flushBatchProcessor } from './chunk-
|
|
2
|
-
import { getFormattedConversationHistory, createDefaultConversationHistoryConfig, saveA2AMessageResponse } from './chunk-
|
|
3
|
-
import { dbClient_default } from './chunk-
|
|
4
|
-
import { env } from './chunk-
|
|
1
|
+
import { flushBatchProcessor } from './chunk-AZFBQY6E.js';
|
|
2
|
+
import { getFormattedConversationHistory, createDefaultConversationHistoryConfig, saveA2AMessageResponse } from './chunk-M46DFVYB.js';
|
|
3
|
+
import { dbClient_default } from './chunk-V4RNZ6BX.js';
|
|
4
|
+
import { env } from './chunk-IYG4HUQ6.js';
|
|
5
5
|
import { getLogger } from './chunk-A2S7GSHL.js';
|
|
6
6
|
import { SESSION_CLEANUP_INTERVAL_MS, AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS, SESSION_TOOL_RESULT_CACHE_TIMEOUT_MS, STREAM_MAX_LIFETIME_MS, STREAM_BUFFER_MAX_SIZE_BYTES, STREAM_TEXT_GAP_THRESHOLD_MS, ARTIFACT_GENERATION_MAX_RETRIES, ARTIFACT_SESSION_MAX_PENDING, STATUS_UPDATE_DEFAULT_INTERVAL_SECONDS, STATUS_UPDATE_DEFAULT_NUM_EVENTS, ARTIFACT_SESSION_MAX_PREVIOUS_SUMMARIES, AGENT_EXECUTION_MAX_GENERATION_STEPS, FUNCTION_TOOL_SANDBOX_VCPUS_DEFAULT, FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS, ARTIFACT_GENERATION_BACKOFF_INITIAL_MS, ARTIFACT_GENERATION_BACKOFF_MAX_MS, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING, LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING, LLM_GENERATION_SUBSEQUENT_CALL_TIMEOUT_MS, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS, DELEGATION_TOOL_BACKOFF_EXPONENT, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS, STREAM_PARSER_MAX_SNAPSHOT_SIZE, STREAM_PARSER_MAX_STREAMED_SIZE, STREAM_PARSER_MAX_COLLECTED_PARTS } from './chunk-IVALDC72.js';
|
|
7
|
-
import { getTracer, HeadersScopeSchema, getRequestExecutionContext, createApiError, getAgentWithDefaultSubAgent, contextValidationMiddleware, getConversationId, getFullAgent, createOrGetConversation, getActiveAgentForConversation, setActiveAgentForConversation, getSubAgentById, handleContextResolution, createMessage, generateId, commonGetErrorResponses, loggerFactory, createDefaultCredentialStores, CredentialStoreRegistry, createTask, getTask, updateTask, setSpanWithError, AGENT_EXECUTION_TRANSFER_COUNT_DEFAULT, updateConversation, handleApiError, TaskState, getAgentById, getProject, setActiveAgentForThread,
|
|
7
|
+
import { getTracer, HeadersScopeSchema, getRequestExecutionContext, createApiError, getAgentWithDefaultSubAgent, contextValidationMiddleware, getConversationId, getFullAgent, createOrGetConversation, getActiveAgentForConversation, setActiveAgentForConversation, getSubAgentById, handleContextResolution, createMessage, generateId, commonGetErrorResponses, loggerFactory, getConversation, createDefaultCredentialStores, CredentialStoreRegistry, createTask, getTask, updateTask, setSpanWithError, AGENT_EXECUTION_TRANSFER_COUNT_DEFAULT, updateConversation, handleApiError, TaskState, getAgentById, getProject, setActiveAgentForThread, getRelatedAgentsForAgent, getExternalAgentsForSubAgent, getTeamAgentsForSubAgent, getToolsForAgent, getDataComponentsForAgent, getArtifactComponentsForAgent, dbResultToMcpTool, CONVERSATION_HISTORY_MAX_OUTPUT_TOKENS_DEFAULT, CONVERSATION_HISTORY_DEFAULT_LIMIT, ModelFactory, verifyTempToken, validateAndGetApiKey, verifyServiceToken, validateTargetAgent, ContextResolver, CredentialStuffer, MCPServerType, getCredentialReference, McpClient, getFunctionToolsForSubAgent, getFunction, getContextConfigById, getFullAgentDefinition, TemplateEngine, listTaskIdsByContextId, getLedgerArtifacts, agentHasArtifactComponents, upsertLedgerArtifact, MCPTransportType, SPAN_KEYS, headers, generateServiceToken } from '@inkeep/agents-core';
|
|
8
8
|
import { otel } from '@hono/otel';
|
|
9
9
|
import { OpenAPIHono, createRoute, z as z$1 } from '@hono/zod-openapi';
|
|
10
10
|
import { trace, propagation, context, SpanStatusCode } from '@opentelemetry/api';
|
|
@@ -17,12 +17,6 @@ import { swaggerUI } from '@hono/swagger-ui';
|
|
|
17
17
|
import z5, { z } from 'zod';
|
|
18
18
|
import { streamSSE, stream } from 'hono/streaming';
|
|
19
19
|
import { createUIMessageStream, JsonToSseTransformStream, parsePartialJson, generateObject, tool, streamText, generateText, streamObject } from 'ai';
|
|
20
|
-
import { createAnthropic, anthropic } from '@ai-sdk/anthropic';
|
|
21
|
-
import { createGateway, gateway } from '@ai-sdk/gateway';
|
|
22
|
-
import { createGoogleGenerativeAI, google } from '@ai-sdk/google';
|
|
23
|
-
import { createOpenAI, openai } from '@ai-sdk/openai';
|
|
24
|
-
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
|
|
25
|
-
import { createOpenRouter, openrouter } from '@openrouter/ai-sdk-provider';
|
|
26
20
|
import jmespath from 'jmespath';
|
|
27
21
|
import Ajv from 'ajv';
|
|
28
22
|
import destr from 'destr';
|
|
@@ -47,6 +41,31 @@ function createExecutionContext(params) {
|
|
|
47
41
|
|
|
48
42
|
// src/middleware/api-key-auth.ts
|
|
49
43
|
var logger = getLogger("env-key-auth");
|
|
44
|
+
async function tryAuthenticateWithTempJwt(apiKey, baseUrl, subAgentId) {
|
|
45
|
+
if (!apiKey.startsWith("eyJ") || !env.INKEEP_AGENTS_TEMP_JWT_PUBLIC_KEY) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const publicKeyPem = Buffer.from(env.INKEEP_AGENTS_TEMP_JWT_PUBLIC_KEY, "base64").toString(
|
|
50
|
+
"utf-8"
|
|
51
|
+
);
|
|
52
|
+
const payload = await verifyTempToken(publicKeyPem, apiKey);
|
|
53
|
+
logger.info({}, "JWT temp token authenticated successfully");
|
|
54
|
+
return createExecutionContext({
|
|
55
|
+
apiKey,
|
|
56
|
+
tenantId: payload.tenantId,
|
|
57
|
+
projectId: payload.projectId,
|
|
58
|
+
agentId: payload.agentId,
|
|
59
|
+
apiKeyId: "temp-jwt",
|
|
60
|
+
baseUrl,
|
|
61
|
+
subAgentId,
|
|
62
|
+
metadata: { initiatedBy: payload.initiatedBy }
|
|
63
|
+
});
|
|
64
|
+
} catch (error) {
|
|
65
|
+
logger.debug({ error }, "JWT verification failed");
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
50
69
|
var apiKeyAuth = () => createMiddleware(async (c, next) => {
|
|
51
70
|
if (c.req.method === "OPTIONS") {
|
|
52
71
|
await next();
|
|
@@ -67,6 +86,12 @@ var apiKeyAuth = () => createMiddleware(async (c, next) => {
|
|
|
67
86
|
let executionContext;
|
|
68
87
|
if (authHeader?.startsWith("Bearer ")) {
|
|
69
88
|
const apiKey2 = authHeader.substring(7);
|
|
89
|
+
const jwtContext2 = await tryAuthenticateWithTempJwt(apiKey2, baseUrl, subAgentId);
|
|
90
|
+
if (jwtContext2) {
|
|
91
|
+
c.set("executionContext", jwtContext2);
|
|
92
|
+
await next();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
70
95
|
try {
|
|
71
96
|
executionContext = await extractContextFromApiKey(apiKey2, baseUrl);
|
|
72
97
|
if (subAgentId) {
|
|
@@ -119,6 +144,12 @@ var apiKeyAuth = () => createMiddleware(async (c, next) => {
|
|
|
119
144
|
});
|
|
120
145
|
}
|
|
121
146
|
const apiKey = authHeader.substring(7);
|
|
147
|
+
const jwtContext = await tryAuthenticateWithTempJwt(apiKey, baseUrl, subAgentId);
|
|
148
|
+
if (jwtContext) {
|
|
149
|
+
c.set("executionContext", jwtContext);
|
|
150
|
+
await next();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
122
153
|
if (env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET) {
|
|
123
154
|
if (apiKey === env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET) {
|
|
124
155
|
if (!tenantId || !projectId || !agentId) {
|
|
@@ -139,7 +170,8 @@ var apiKeyAuth = () => createMiddleware(async (c, next) => {
|
|
|
139
170
|
logger.info({}, "Bypass secret authenticated successfully");
|
|
140
171
|
await next();
|
|
141
172
|
return;
|
|
142
|
-
}
|
|
173
|
+
}
|
|
174
|
+
if (apiKey) {
|
|
143
175
|
try {
|
|
144
176
|
const executionContext = await extractContextFromApiKey(apiKey, baseUrl);
|
|
145
177
|
if (subAgentId) {
|
|
@@ -157,11 +189,10 @@ var apiKeyAuth = () => createMiddleware(async (c, next) => {
|
|
|
157
189
|
}
|
|
158
190
|
await next();
|
|
159
191
|
return;
|
|
160
|
-
} else {
|
|
161
|
-
throw new HTTPException(401, {
|
|
162
|
-
message: "Invalid Token"
|
|
163
|
-
});
|
|
164
192
|
}
|
|
193
|
+
throw new HTTPException(401, {
|
|
194
|
+
message: "Invalid Token"
|
|
195
|
+
});
|
|
165
196
|
}
|
|
166
197
|
if (!apiKey || apiKey.length < 16) {
|
|
167
198
|
throw new HTTPException(401, {
|
|
@@ -307,6 +338,19 @@ function setupOpenAPIRoutes(app6) {
|
|
|
307
338
|
}
|
|
308
339
|
]
|
|
309
340
|
});
|
|
341
|
+
document.components = {
|
|
342
|
+
...document.components,
|
|
343
|
+
securitySchemes: {
|
|
344
|
+
...document.components?.securitySchemes || {},
|
|
345
|
+
bearerAuth: {
|
|
346
|
+
type: "http",
|
|
347
|
+
scheme: "bearer",
|
|
348
|
+
bearerFormat: "API Key",
|
|
349
|
+
description: 'API key authentication. All endpoints require a valid API key in the Authorization header as "Bearer <api-key>". API keys can be created in the management UI.'
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
document.security = [{ bearerAuth: [] }];
|
|
310
354
|
return c.json(document);
|
|
311
355
|
} catch (error) {
|
|
312
356
|
console.error("OpenAPI document generation failed:", error);
|
|
@@ -931,269 +975,7 @@ async function handleTasksResubscribe(c, agent, request) {
|
|
|
931
975
|
});
|
|
932
976
|
}
|
|
933
977
|
}
|
|
934
|
-
var logger3 = getLogger("
|
|
935
|
-
var nimDefault = createOpenAICompatible({
|
|
936
|
-
name: "nim",
|
|
937
|
-
baseURL: "https://integrate.api.nvidia.com/v1",
|
|
938
|
-
headers: {
|
|
939
|
-
Authorization: `Bearer ${process.env.NIM_API_KEY}`
|
|
940
|
-
}
|
|
941
|
-
});
|
|
942
|
-
var ModelFactory = class _ModelFactory {
|
|
943
|
-
/**
|
|
944
|
-
* Create a provider instance with custom configuration
|
|
945
|
-
*/
|
|
946
|
-
static createProvider(provider, config) {
|
|
947
|
-
switch (provider) {
|
|
948
|
-
case "anthropic":
|
|
949
|
-
return createAnthropic(config);
|
|
950
|
-
case "openai":
|
|
951
|
-
return createOpenAI(config);
|
|
952
|
-
case "google":
|
|
953
|
-
return createGoogleGenerativeAI(config);
|
|
954
|
-
case "openrouter":
|
|
955
|
-
return {
|
|
956
|
-
...createOpenRouter(config),
|
|
957
|
-
textEmbeddingModel: () => {
|
|
958
|
-
throw new Error("OpenRouter does not support text embeddings");
|
|
959
|
-
},
|
|
960
|
-
imageModel: () => {
|
|
961
|
-
throw new Error("OpenRouter does not support image generation");
|
|
962
|
-
}
|
|
963
|
-
};
|
|
964
|
-
case "gateway":
|
|
965
|
-
return createGateway(config);
|
|
966
|
-
case "nim": {
|
|
967
|
-
const nimConfig = {
|
|
968
|
-
name: "nim",
|
|
969
|
-
baseURL: "https://integrate.api.nvidia.com/v1",
|
|
970
|
-
headers: {
|
|
971
|
-
Authorization: `Bearer ${process.env.NIM_API_KEY}`
|
|
972
|
-
},
|
|
973
|
-
...config
|
|
974
|
-
};
|
|
975
|
-
return createOpenAICompatible(nimConfig);
|
|
976
|
-
}
|
|
977
|
-
case "custom": {
|
|
978
|
-
if (!config.baseURL && !config.baseUrl) {
|
|
979
|
-
throw new Error(
|
|
980
|
-
"Custom provider requires baseURL. Please provide it in providerOptions.baseURL or providerOptions.baseUrl"
|
|
981
|
-
);
|
|
982
|
-
}
|
|
983
|
-
const customConfig = {
|
|
984
|
-
name: "custom",
|
|
985
|
-
baseURL: config.baseURL || config.baseUrl,
|
|
986
|
-
headers: {
|
|
987
|
-
...process.env.CUSTOM_LLM_API_KEY && {
|
|
988
|
-
Authorization: `Bearer ${process.env.CUSTOM_LLM_API_KEY}`
|
|
989
|
-
},
|
|
990
|
-
...config.headers || {}
|
|
991
|
-
},
|
|
992
|
-
...config
|
|
993
|
-
};
|
|
994
|
-
logger3.info(
|
|
995
|
-
{
|
|
996
|
-
config: {
|
|
997
|
-
baseURL: customConfig.baseURL,
|
|
998
|
-
hasApiKey: !!process.env.CUSTOM_LLM_API_KEY,
|
|
999
|
-
apiKeyPrefix: process.env.CUSTOM_LLM_API_KEY?.substring(0, 10) + "...",
|
|
1000
|
-
headers: Object.keys(customConfig.headers || {})
|
|
1001
|
-
}
|
|
1002
|
-
},
|
|
1003
|
-
"Creating custom OpenAI-compatible provider"
|
|
1004
|
-
);
|
|
1005
|
-
return createOpenAICompatible(customConfig);
|
|
1006
|
-
}
|
|
1007
|
-
default:
|
|
1008
|
-
throw new Error(`Unsupported provider: ${provider}`);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
/**
|
|
1012
|
-
* Extract provider configuration from providerOptions
|
|
1013
|
-
* Only includes settings that go to the provider constructor (baseURL, apiKey, etc.)
|
|
1014
|
-
*/
|
|
1015
|
-
static extractProviderConfig(providerOptions) {
|
|
1016
|
-
if (!providerOptions) {
|
|
1017
|
-
return {};
|
|
1018
|
-
}
|
|
1019
|
-
const providerConfig = {};
|
|
1020
|
-
if (providerOptions.baseUrl || providerOptions.baseURL) {
|
|
1021
|
-
providerConfig.baseURL = providerOptions.baseUrl || providerOptions.baseURL;
|
|
1022
|
-
}
|
|
1023
|
-
if (providerOptions.headers) {
|
|
1024
|
-
providerConfig.headers = providerOptions.headers;
|
|
1025
|
-
}
|
|
1026
|
-
if (providerOptions.gateway) {
|
|
1027
|
-
Object.assign(providerConfig, providerOptions.gateway);
|
|
1028
|
-
}
|
|
1029
|
-
if (providerOptions.nim) {
|
|
1030
|
-
Object.assign(providerConfig, providerOptions.nim);
|
|
1031
|
-
}
|
|
1032
|
-
if (providerOptions.custom) {
|
|
1033
|
-
Object.assign(providerConfig, providerOptions.custom);
|
|
1034
|
-
}
|
|
1035
|
-
return providerConfig;
|
|
1036
|
-
}
|
|
1037
|
-
/**
|
|
1038
|
-
* Create a language model instance from configuration
|
|
1039
|
-
* Throws error if no config provided - models must be configured at project level
|
|
1040
|
-
*/
|
|
1041
|
-
static createModel(config) {
|
|
1042
|
-
if (!config?.model?.trim()) {
|
|
1043
|
-
throw new Error(
|
|
1044
|
-
"Model configuration is required. Please configure models at the project level."
|
|
1045
|
-
);
|
|
1046
|
-
}
|
|
1047
|
-
const modelSettings = config;
|
|
1048
|
-
if (!modelSettings.model) {
|
|
1049
|
-
throw new Error("Model configuration is required");
|
|
1050
|
-
}
|
|
1051
|
-
const modelString = modelSettings.model.trim();
|
|
1052
|
-
const { provider, modelName } = _ModelFactory.parseModelString(modelString);
|
|
1053
|
-
logger3.debug(
|
|
1054
|
-
{
|
|
1055
|
-
provider,
|
|
1056
|
-
model: modelName,
|
|
1057
|
-
fullModelString: modelSettings.model,
|
|
1058
|
-
hasProviderOptions: !!modelSettings.providerOptions
|
|
1059
|
-
},
|
|
1060
|
-
"Creating language model from config"
|
|
1061
|
-
);
|
|
1062
|
-
const providerConfig = _ModelFactory.extractProviderConfig(modelSettings.providerOptions);
|
|
1063
|
-
if (Object.keys(providerConfig).length > 0) {
|
|
1064
|
-
logger3.info({ config: providerConfig }, `Applying custom ${provider} provider configuration`);
|
|
1065
|
-
const customProvider = _ModelFactory.createProvider(provider, providerConfig);
|
|
1066
|
-
return customProvider.languageModel(modelName);
|
|
1067
|
-
}
|
|
1068
|
-
switch (provider) {
|
|
1069
|
-
case "anthropic":
|
|
1070
|
-
return anthropic(modelName);
|
|
1071
|
-
case "openai":
|
|
1072
|
-
return openai(modelName);
|
|
1073
|
-
case "google":
|
|
1074
|
-
return google(modelName);
|
|
1075
|
-
case "openrouter":
|
|
1076
|
-
return openrouter(modelName);
|
|
1077
|
-
case "gateway":
|
|
1078
|
-
return gateway(modelName);
|
|
1079
|
-
case "nim":
|
|
1080
|
-
return nimDefault(modelName);
|
|
1081
|
-
case "custom":
|
|
1082
|
-
throw new Error(
|
|
1083
|
-
"Custom provider requires configuration. Please provide baseURL in providerOptions.custom.baseURL or providerOptions.baseURL"
|
|
1084
|
-
);
|
|
1085
|
-
default:
|
|
1086
|
-
throw new Error(
|
|
1087
|
-
`Unsupported provider: ${provider}. Supported providers are: ${_ModelFactory.BUILT_IN_PROVIDERS.join(", ")}. To access other models, use OpenRouter (openrouter/model-id), Vercel AI Gateway (gateway/model-id), NVIDIA NIM (nim/model-id), or Custom OpenAI-compatible (custom/model-id).`
|
|
1088
|
-
);
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
/**
|
|
1092
|
-
* Built-in providers that have special handling
|
|
1093
|
-
*/
|
|
1094
|
-
static BUILT_IN_PROVIDERS = [
|
|
1095
|
-
"anthropic",
|
|
1096
|
-
"openai",
|
|
1097
|
-
"google",
|
|
1098
|
-
"openrouter",
|
|
1099
|
-
"gateway",
|
|
1100
|
-
"nim",
|
|
1101
|
-
"custom"
|
|
1102
|
-
];
|
|
1103
|
-
/**
|
|
1104
|
-
* Parse model string to extract provider and model name
|
|
1105
|
-
* Examples: "anthropic/claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" }
|
|
1106
|
-
* "openrouter/anthropic/claude-sonnet-4" -> { provider: "openrouter", modelName: "anthropic/claude-sonnet-4" }
|
|
1107
|
-
* "claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" } (default to anthropic)
|
|
1108
|
-
*/
|
|
1109
|
-
static parseModelString(modelString) {
|
|
1110
|
-
if (modelString.includes("/")) {
|
|
1111
|
-
const [provider, ...modelParts] = modelString.split("/");
|
|
1112
|
-
const normalizedProvider = provider.toLowerCase();
|
|
1113
|
-
if (!_ModelFactory.BUILT_IN_PROVIDERS.includes(normalizedProvider)) {
|
|
1114
|
-
throw new Error(
|
|
1115
|
-
`Unsupported provider: ${normalizedProvider}. Supported providers are: ${_ModelFactory.BUILT_IN_PROVIDERS.join(", ")}. To access other models, use OpenRouter (openrouter/model-id), Vercel AI Gateway (gateway/model-id), NVIDIA NIM (nim/model-id), or Custom OpenAI-compatible (custom/model-id).`
|
|
1116
|
-
);
|
|
1117
|
-
}
|
|
1118
|
-
return {
|
|
1119
|
-
provider: normalizedProvider,
|
|
1120
|
-
modelName: modelParts.join("/")
|
|
1121
|
-
// In case model name has slashes
|
|
1122
|
-
};
|
|
1123
|
-
}
|
|
1124
|
-
throw new Error(`No provider specified in model string: ${modelString}`);
|
|
1125
|
-
}
|
|
1126
|
-
/**
|
|
1127
|
-
* Get generation parameters from provider options
|
|
1128
|
-
* These are parameters that get passed to generateText/streamText calls
|
|
1129
|
-
*/
|
|
1130
|
-
static getGenerationParams(providerOptions) {
|
|
1131
|
-
if (!providerOptions) {
|
|
1132
|
-
return {};
|
|
1133
|
-
}
|
|
1134
|
-
const excludedKeys = [
|
|
1135
|
-
"apiKey",
|
|
1136
|
-
"baseURL",
|
|
1137
|
-
"baseUrl",
|
|
1138
|
-
"maxDuration",
|
|
1139
|
-
"headers",
|
|
1140
|
-
"gateway",
|
|
1141
|
-
"nim",
|
|
1142
|
-
"custom"
|
|
1143
|
-
];
|
|
1144
|
-
const params = {};
|
|
1145
|
-
for (const [key, value] of Object.entries(providerOptions)) {
|
|
1146
|
-
if (!excludedKeys.includes(key) && value !== void 0) {
|
|
1147
|
-
params[key] = value;
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
return params;
|
|
1151
|
-
}
|
|
1152
|
-
/**
|
|
1153
|
-
* Prepare complete generation configuration from model settings
|
|
1154
|
-
* Returns model instance and generation parameters ready to spread into generateText/streamText
|
|
1155
|
-
* Includes maxDuration if specified in provider options (in seconds, following Vercel standard)
|
|
1156
|
-
*/
|
|
1157
|
-
static prepareGenerationConfig(modelSettings) {
|
|
1158
|
-
const modelString = modelSettings?.model?.trim();
|
|
1159
|
-
const model = _ModelFactory.createModel({
|
|
1160
|
-
model: modelString,
|
|
1161
|
-
providerOptions: modelSettings?.providerOptions
|
|
1162
|
-
});
|
|
1163
|
-
const generationParams = _ModelFactory.getGenerationParams(modelSettings?.providerOptions);
|
|
1164
|
-
const maxDuration = modelSettings?.providerOptions?.maxDuration;
|
|
1165
|
-
return {
|
|
1166
|
-
model,
|
|
1167
|
-
...generationParams,
|
|
1168
|
-
...maxDuration !== void 0 && { maxDuration }
|
|
1169
|
-
};
|
|
1170
|
-
}
|
|
1171
|
-
/**
|
|
1172
|
-
* Validate model settingsuration
|
|
1173
|
-
* Basic validation only - let AI SDK handle parameter-specific validation
|
|
1174
|
-
*/
|
|
1175
|
-
static validateConfig(config) {
|
|
1176
|
-
const errors = [];
|
|
1177
|
-
if (!config.model) {
|
|
1178
|
-
errors.push("Model name is required");
|
|
1179
|
-
}
|
|
1180
|
-
if (config.providerOptions) {
|
|
1181
|
-
if (config.providerOptions.apiKey) {
|
|
1182
|
-
errors.push(
|
|
1183
|
-
"API keys should not be stored in provider options. Use environment variables (ANTHROPIC_API_KEY, OPENAI_API_KEY) or credential store instead."
|
|
1184
|
-
);
|
|
1185
|
-
}
|
|
1186
|
-
if (config.providerOptions.maxDuration !== void 0) {
|
|
1187
|
-
const maxDuration = config.providerOptions.maxDuration;
|
|
1188
|
-
if (typeof maxDuration !== "number" || maxDuration <= 0) {
|
|
1189
|
-
errors.push("maxDuration must be a positive number (in seconds)");
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
return errors;
|
|
1194
|
-
}
|
|
1195
|
-
};
|
|
1196
|
-
var logger4 = getLogger("ToolSessionManager");
|
|
978
|
+
var logger3 = getLogger("ToolSessionManager");
|
|
1197
979
|
var ToolSessionManager = class _ToolSessionManager {
|
|
1198
980
|
static instance;
|
|
1199
981
|
sessions = /* @__PURE__ */ new Map();
|
|
@@ -1227,7 +1009,7 @@ var ToolSessionManager = class _ToolSessionManager {
|
|
|
1227
1009
|
createdAt: Date.now()
|
|
1228
1010
|
};
|
|
1229
1011
|
this.sessions.set(sessionId, session);
|
|
1230
|
-
|
|
1012
|
+
logger3.debug(
|
|
1231
1013
|
{
|
|
1232
1014
|
sessionId,
|
|
1233
1015
|
tenantId,
|
|
@@ -1245,10 +1027,10 @@ var ToolSessionManager = class _ToolSessionManager {
|
|
|
1245
1027
|
*/
|
|
1246
1028
|
ensureAgentSession(sessionId, tenantId, projectId, contextId, taskId) {
|
|
1247
1029
|
if (this.sessions.has(sessionId)) {
|
|
1248
|
-
|
|
1030
|
+
logger3.debug({ sessionId }, "Agent session already exists, reusing");
|
|
1249
1031
|
return sessionId;
|
|
1250
1032
|
}
|
|
1251
|
-
|
|
1033
|
+
logger3.debug(
|
|
1252
1034
|
{ sessionId, tenantId, contextId, taskId },
|
|
1253
1035
|
"Creating new agent-scoped tool session"
|
|
1254
1036
|
);
|
|
@@ -1260,7 +1042,7 @@ var ToolSessionManager = class _ToolSessionManager {
|
|
|
1260
1042
|
recordToolResult(sessionId, toolResult) {
|
|
1261
1043
|
const session = this.sessions.get(sessionId);
|
|
1262
1044
|
if (!session) {
|
|
1263
|
-
|
|
1045
|
+
logger3.warn(
|
|
1264
1046
|
{
|
|
1265
1047
|
sessionId,
|
|
1266
1048
|
toolCallId: toolResult.toolCallId,
|
|
@@ -1272,7 +1054,7 @@ var ToolSessionManager = class _ToolSessionManager {
|
|
|
1272
1054
|
return;
|
|
1273
1055
|
}
|
|
1274
1056
|
session.toolResults.set(toolResult.toolCallId, toolResult);
|
|
1275
|
-
|
|
1057
|
+
logger3.debug(
|
|
1276
1058
|
{
|
|
1277
1059
|
sessionId,
|
|
1278
1060
|
toolCallId: toolResult.toolCallId,
|
|
@@ -1287,7 +1069,7 @@ var ToolSessionManager = class _ToolSessionManager {
|
|
|
1287
1069
|
getToolResult(sessionId, toolCallId) {
|
|
1288
1070
|
const session = this.sessions.get(sessionId);
|
|
1289
1071
|
if (!session) {
|
|
1290
|
-
|
|
1072
|
+
logger3.warn(
|
|
1291
1073
|
{
|
|
1292
1074
|
sessionId,
|
|
1293
1075
|
toolCallId,
|
|
@@ -1300,7 +1082,7 @@ var ToolSessionManager = class _ToolSessionManager {
|
|
|
1300
1082
|
}
|
|
1301
1083
|
const result = session.toolResults.get(toolCallId);
|
|
1302
1084
|
if (!result) {
|
|
1303
|
-
|
|
1085
|
+
logger3.warn(
|
|
1304
1086
|
{
|
|
1305
1087
|
sessionId,
|
|
1306
1088
|
toolCallId,
|
|
@@ -1310,7 +1092,7 @@ var ToolSessionManager = class _ToolSessionManager {
|
|
|
1310
1092
|
"Tool result not found"
|
|
1311
1093
|
);
|
|
1312
1094
|
} else {
|
|
1313
|
-
|
|
1095
|
+
logger3.debug(
|
|
1314
1096
|
{
|
|
1315
1097
|
sessionId,
|
|
1316
1098
|
toolCallId,
|
|
@@ -1349,10 +1131,10 @@ var ToolSessionManager = class _ToolSessionManager {
|
|
|
1349
1131
|
}
|
|
1350
1132
|
for (const sessionId of expiredSessions) {
|
|
1351
1133
|
this.sessions.delete(sessionId);
|
|
1352
|
-
|
|
1134
|
+
logger3.debug({ sessionId }, "Cleaned up expired tool session");
|
|
1353
1135
|
}
|
|
1354
1136
|
if (expiredSessions.length > 0) {
|
|
1355
|
-
|
|
1137
|
+
logger3.info({ expiredCount: expiredSessions.length }, "Cleaned up expired tool sessions");
|
|
1356
1138
|
}
|
|
1357
1139
|
}
|
|
1358
1140
|
};
|
|
@@ -1420,7 +1202,7 @@ function extractFullFields(schema) {
|
|
|
1420
1202
|
}
|
|
1421
1203
|
|
|
1422
1204
|
// src/services/ArtifactService.ts
|
|
1423
|
-
var
|
|
1205
|
+
var logger5 = getLogger("ArtifactService");
|
|
1424
1206
|
var ArtifactService = class _ArtifactService {
|
|
1425
1207
|
constructor(context) {
|
|
1426
1208
|
this.context = context;
|
|
@@ -1453,7 +1235,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1453
1235
|
id: taskId
|
|
1454
1236
|
});
|
|
1455
1237
|
if (!task) {
|
|
1456
|
-
|
|
1238
|
+
logger5.warn({ taskId }, "Task not found when fetching artifacts");
|
|
1457
1239
|
continue;
|
|
1458
1240
|
}
|
|
1459
1241
|
const taskArtifacts = await getLedgerArtifacts(dbClient_default)({
|
|
@@ -1471,7 +1253,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1471
1253
|
}
|
|
1472
1254
|
}
|
|
1473
1255
|
} catch (error) {
|
|
1474
|
-
|
|
1256
|
+
logger5.error({ error, contextId }, "Error loading context artifacts");
|
|
1475
1257
|
}
|
|
1476
1258
|
return artifacts;
|
|
1477
1259
|
}
|
|
@@ -1480,12 +1262,12 @@ var ArtifactService = class _ArtifactService {
|
|
|
1480
1262
|
*/
|
|
1481
1263
|
async createArtifact(request, subAgentId) {
|
|
1482
1264
|
if (!this.context.sessionId) {
|
|
1483
|
-
|
|
1265
|
+
logger5.warn({ request }, "No session ID available for artifact creation");
|
|
1484
1266
|
return null;
|
|
1485
1267
|
}
|
|
1486
1268
|
const toolResult = toolSessionManager.getToolResult(this.context.sessionId, request.toolCallId);
|
|
1487
1269
|
if (!toolResult) {
|
|
1488
|
-
|
|
1270
|
+
logger5.warn(
|
|
1489
1271
|
{ request, sessionId: this.context.sessionId },
|
|
1490
1272
|
"Tool result not found for artifact"
|
|
1491
1273
|
);
|
|
@@ -1501,7 +1283,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1501
1283
|
selectedData = selectedData.length > 0 ? selectedData[0] : {};
|
|
1502
1284
|
}
|
|
1503
1285
|
if (!selectedData) {
|
|
1504
|
-
|
|
1286
|
+
logger5.warn(
|
|
1505
1287
|
{
|
|
1506
1288
|
request,
|
|
1507
1289
|
baseSelector: request.baseSelector
|
|
@@ -1572,7 +1354,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1572
1354
|
);
|
|
1573
1355
|
return artifactData;
|
|
1574
1356
|
} catch (error) {
|
|
1575
|
-
|
|
1357
|
+
logger5.error({ error, request }, "Failed to create artifact");
|
|
1576
1358
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1577
1359
|
throw new Error(`Artifact creation failed for ${request.artifactId}: ${errorMessage}`);
|
|
1578
1360
|
}
|
|
@@ -1601,7 +1383,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1601
1383
|
}
|
|
1602
1384
|
try {
|
|
1603
1385
|
if (!this.context.projectId || !this.context.taskId) {
|
|
1604
|
-
|
|
1386
|
+
logger5.warn(
|
|
1605
1387
|
{ artifactId, toolCallId },
|
|
1606
1388
|
"No projectId or taskId available for artifact lookup"
|
|
1607
1389
|
);
|
|
@@ -1625,7 +1407,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1625
1407
|
return this.formatArtifactSummaryData(artifacts[0], artifactId, toolCallId);
|
|
1626
1408
|
}
|
|
1627
1409
|
} catch (error) {
|
|
1628
|
-
|
|
1410
|
+
logger5.warn(
|
|
1629
1411
|
{ artifactId, toolCallId, taskId: this.context.taskId, error },
|
|
1630
1412
|
"Failed to fetch artifact"
|
|
1631
1413
|
);
|
|
@@ -1656,7 +1438,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1656
1438
|
}
|
|
1657
1439
|
try {
|
|
1658
1440
|
if (!this.context.projectId || !this.context.taskId) {
|
|
1659
|
-
|
|
1441
|
+
logger5.warn(
|
|
1660
1442
|
{ artifactId, toolCallId },
|
|
1661
1443
|
"No projectId or taskId available for artifact lookup"
|
|
1662
1444
|
);
|
|
@@ -1680,7 +1462,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1680
1462
|
return this.formatArtifactFullData(artifacts[0], artifactId, toolCallId);
|
|
1681
1463
|
}
|
|
1682
1464
|
} catch (error) {
|
|
1683
|
-
|
|
1465
|
+
logger5.warn(
|
|
1684
1466
|
{ artifactId, toolCallId, taskId: this.context.taskId, error },
|
|
1685
1467
|
"Failed to fetch artifact"
|
|
1686
1468
|
);
|
|
@@ -1697,7 +1479,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1697
1479
|
data = artifact.parts?.[0]?.data;
|
|
1698
1480
|
if (data && !(typeof data === "object" && Object.keys(data).length === 0)) {
|
|
1699
1481
|
dataSource = "parts[0].data (fallback)";
|
|
1700
|
-
|
|
1482
|
+
logger5.debug(
|
|
1701
1483
|
{ artifactId, toolCallId, dataSource },
|
|
1702
1484
|
"Using fallback data source for artifact summary"
|
|
1703
1485
|
);
|
|
@@ -1705,14 +1487,14 @@ var ArtifactService = class _ArtifactService {
|
|
|
1705
1487
|
data = artifact.data;
|
|
1706
1488
|
if (data && !(typeof data === "object" && Object.keys(data).length === 0)) {
|
|
1707
1489
|
dataSource = "artifact.data (fallback)";
|
|
1708
|
-
|
|
1490
|
+
logger5.debug(
|
|
1709
1491
|
{ artifactId, toolCallId, dataSource },
|
|
1710
1492
|
"Using fallback data source for artifact summary"
|
|
1711
1493
|
);
|
|
1712
1494
|
} else {
|
|
1713
1495
|
data = {};
|
|
1714
1496
|
dataSource = "empty (no data found)";
|
|
1715
|
-
|
|
1497
|
+
logger5.warn(
|
|
1716
1498
|
{
|
|
1717
1499
|
artifactId,
|
|
1718
1500
|
toolCallId,
|
|
@@ -1749,7 +1531,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1749
1531
|
data = artifact.parts?.[0]?.data;
|
|
1750
1532
|
if (data && !(typeof data === "object" && Object.keys(data).length === 0)) {
|
|
1751
1533
|
dataSource = "parts[0].data (fallback)";
|
|
1752
|
-
|
|
1534
|
+
logger5.debug(
|
|
1753
1535
|
{ artifactId, toolCallId, dataSource },
|
|
1754
1536
|
"Using fallback data source for artifact full data"
|
|
1755
1537
|
);
|
|
@@ -1757,14 +1539,14 @@ var ArtifactService = class _ArtifactService {
|
|
|
1757
1539
|
data = artifact.data;
|
|
1758
1540
|
if (data && !(typeof data === "object" && Object.keys(data).length === 0)) {
|
|
1759
1541
|
dataSource = "artifact.data (fallback)";
|
|
1760
|
-
|
|
1542
|
+
logger5.debug(
|
|
1761
1543
|
{ artifactId, toolCallId, dataSource },
|
|
1762
1544
|
"Using fallback data source for artifact full data"
|
|
1763
1545
|
);
|
|
1764
1546
|
} else {
|
|
1765
1547
|
data = {};
|
|
1766
1548
|
dataSource = "empty (no data found)";
|
|
1767
|
-
|
|
1549
|
+
logger5.warn(
|
|
1768
1550
|
{
|
|
1769
1551
|
artifactId,
|
|
1770
1552
|
toolCallId,
|
|
@@ -1818,7 +1600,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1818
1600
|
const error = new Error(
|
|
1819
1601
|
`Cannot save artifact: Missing required fields [${summaryValidation.missingRequired.join(", ")}] for '${artifactType}' schema. Required: [${summaryValidation.missingRequired.join(", ")}]. Found: [${summaryValidation.actualFields.join(", ")}]. Consider using a different artifact component type that matches your data structure.`
|
|
1820
1602
|
);
|
|
1821
|
-
|
|
1603
|
+
logger5.error(
|
|
1822
1604
|
{
|
|
1823
1605
|
artifactId,
|
|
1824
1606
|
artifactType,
|
|
@@ -1831,7 +1613,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1831
1613
|
throw error;
|
|
1832
1614
|
}
|
|
1833
1615
|
if (!summaryValidation.hasExpectedFields || summaryValidation.extraFields.length > 0) {
|
|
1834
|
-
|
|
1616
|
+
logger5.warn(
|
|
1835
1617
|
{
|
|
1836
1618
|
artifactId,
|
|
1837
1619
|
artifactType,
|
|
@@ -1845,7 +1627,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1845
1627
|
);
|
|
1846
1628
|
}
|
|
1847
1629
|
if (!fullValidation.hasExpectedFields || fullValidation.extraFields.length > 0) {
|
|
1848
|
-
|
|
1630
|
+
logger5.warn(
|
|
1849
1631
|
{
|
|
1850
1632
|
artifactId,
|
|
1851
1633
|
artifactType,
|
|
@@ -1917,7 +1699,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1917
1699
|
}
|
|
1918
1700
|
);
|
|
1919
1701
|
} else {
|
|
1920
|
-
|
|
1702
|
+
logger5.warn(
|
|
1921
1703
|
{
|
|
1922
1704
|
artifactId: request.artifactId,
|
|
1923
1705
|
hasStreamRequestId: !!this.context.streamRequestId,
|
|
@@ -1992,7 +1774,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1992
1774
|
summaryData = this.filterBySchema(artifact.data, previewSchema);
|
|
1993
1775
|
fullData = this.filterBySchema(artifact.data, fullSchema);
|
|
1994
1776
|
} catch (error) {
|
|
1995
|
-
|
|
1777
|
+
logger5.warn(
|
|
1996
1778
|
{
|
|
1997
1779
|
artifactType: artifact.type,
|
|
1998
1780
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -2030,7 +1812,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
2030
1812
|
artifact: artifactToSave
|
|
2031
1813
|
});
|
|
2032
1814
|
if (!result.created && result.existing) {
|
|
2033
|
-
|
|
1815
|
+
logger5.debug(
|
|
2034
1816
|
{
|
|
2035
1817
|
artifactId: artifact.artifactId,
|
|
2036
1818
|
taskId: this.context.taskId
|
|
@@ -2090,7 +1872,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
2090
1872
|
extracted[fieldName] = this.cleanEscapedContent(rawValue);
|
|
2091
1873
|
}
|
|
2092
1874
|
} catch (error) {
|
|
2093
|
-
|
|
1875
|
+
logger5.warn(
|
|
2094
1876
|
{ fieldName, error: error instanceof Error ? error.message : "Unknown error" },
|
|
2095
1877
|
"Failed to extract schema field"
|
|
2096
1878
|
);
|
|
@@ -2119,7 +1901,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
2119
1901
|
};
|
|
2120
1902
|
|
|
2121
1903
|
// src/services/ArtifactParser.ts
|
|
2122
|
-
var
|
|
1904
|
+
var logger6 = getLogger("ArtifactParser");
|
|
2123
1905
|
var ArtifactParser = class _ArtifactParser {
|
|
2124
1906
|
static ARTIFACT_CHECK_REGEX = /<artifact:ref\s+(?=.*id=['"][^'"]+['"])(?=.*tool=['"][^'"]+['"])[^>]*\/>/;
|
|
2125
1907
|
static ATTR_REGEX = /(\w+)="([^"]*)"|(\w+)='([^']*)'|(\w+)=({[^}]+})/g;
|
|
@@ -2230,7 +2012,7 @@ var ArtifactParser = class _ArtifactParser {
|
|
|
2230
2012
|
attrs[key] = value;
|
|
2231
2013
|
}
|
|
2232
2014
|
if (!attrs.id || !attrs.tool || !attrs.type || !attrs.base) {
|
|
2233
|
-
|
|
2015
|
+
logger6.warn({ attrs, attrString }, "Missing required attributes in artifact annotation");
|
|
2234
2016
|
return null;
|
|
2235
2017
|
}
|
|
2236
2018
|
return {
|
|
@@ -2291,7 +2073,7 @@ var ArtifactParser = class _ArtifactParser {
|
|
|
2291
2073
|
`Failed to create artifact "${annotation.artifactId}": Missing or invalid data`
|
|
2292
2074
|
);
|
|
2293
2075
|
processedText = processedText.replace(annotation.raw, "");
|
|
2294
|
-
|
|
2076
|
+
logger6.warn(
|
|
2295
2077
|
{ annotation, artifactData },
|
|
2296
2078
|
"Removed failed artifact:create annotation from output"
|
|
2297
2079
|
);
|
|
@@ -2302,11 +2084,11 @@ var ArtifactParser = class _ArtifactParser {
|
|
|
2302
2084
|
if (annotation.raw) {
|
|
2303
2085
|
processedText = processedText.replace(annotation.raw, "");
|
|
2304
2086
|
}
|
|
2305
|
-
|
|
2087
|
+
logger6.error({ annotation, error }, "Failed to extract artifact from create annotation");
|
|
2306
2088
|
}
|
|
2307
2089
|
}
|
|
2308
2090
|
if (failedAnnotations.length > 0) {
|
|
2309
|
-
|
|
2091
|
+
logger6.warn(
|
|
2310
2092
|
{
|
|
2311
2093
|
failedCount: failedAnnotations.length,
|
|
2312
2094
|
failures: failedAnnotations
|
|
@@ -2490,7 +2272,7 @@ var ArtifactParser = class _ArtifactParser {
|
|
|
2490
2272
|
};
|
|
2491
2273
|
|
|
2492
2274
|
// src/services/AgentSession.ts
|
|
2493
|
-
var
|
|
2275
|
+
var logger7 = getLogger("AgentSession");
|
|
2494
2276
|
var AgentSession = class {
|
|
2495
2277
|
// Whether to send data operations
|
|
2496
2278
|
constructor(sessionId, messageId, agentId, tenantId, projectId, contextId) {
|
|
@@ -2500,7 +2282,7 @@ var AgentSession = class {
|
|
|
2500
2282
|
this.tenantId = tenantId;
|
|
2501
2283
|
this.projectId = projectId;
|
|
2502
2284
|
this.contextId = contextId;
|
|
2503
|
-
|
|
2285
|
+
logger7.debug({ sessionId, messageId, agentId }, "AgentSession created");
|
|
2504
2286
|
if (tenantId && projectId) {
|
|
2505
2287
|
toolSessionManager.createSessionWithId(
|
|
2506
2288
|
sessionId,
|
|
@@ -2557,7 +2339,7 @@ var AgentSession = class {
|
|
|
2557
2339
|
*/
|
|
2558
2340
|
enableEmitOperations() {
|
|
2559
2341
|
this.isEmitOperations = true;
|
|
2560
|
-
|
|
2342
|
+
logger7.info(
|
|
2561
2343
|
{ sessionId: this.sessionId },
|
|
2562
2344
|
"\u{1F50D} DEBUG: Emit operations enabled for AgentSession"
|
|
2563
2345
|
);
|
|
@@ -2566,6 +2348,7 @@ var AgentSession = class {
|
|
|
2566
2348
|
* Send data operation to stream when emit operations is enabled
|
|
2567
2349
|
*/
|
|
2568
2350
|
async sendDataOperation(event) {
|
|
2351
|
+
console.log("sendDataOperation called with event", Date.now());
|
|
2569
2352
|
try {
|
|
2570
2353
|
const streamHelper = getStreamHelper(this.sessionId);
|
|
2571
2354
|
if (streamHelper) {
|
|
@@ -2581,7 +2364,7 @@ var AgentSession = class {
|
|
|
2581
2364
|
await streamHelper.writeOperation(formattedOperation);
|
|
2582
2365
|
}
|
|
2583
2366
|
} catch (error) {
|
|
2584
|
-
|
|
2367
|
+
logger7.error(
|
|
2585
2368
|
{
|
|
2586
2369
|
sessionId: this.sessionId,
|
|
2587
2370
|
eventType: event.eventType,
|
|
@@ -2640,7 +2423,7 @@ var AgentSession = class {
|
|
|
2640
2423
|
if (this.statusUpdateState.config.timeInSeconds) {
|
|
2641
2424
|
this.statusUpdateTimer = setInterval(async () => {
|
|
2642
2425
|
if (!this.statusUpdateState || this.isEnded) {
|
|
2643
|
-
|
|
2426
|
+
logger7.debug(
|
|
2644
2427
|
{ sessionId: this.sessionId },
|
|
2645
2428
|
"Timer triggered but session already cleaned up or ended"
|
|
2646
2429
|
);
|
|
@@ -2652,7 +2435,7 @@ var AgentSession = class {
|
|
|
2652
2435
|
}
|
|
2653
2436
|
await this.checkAndSendTimeBasedUpdate();
|
|
2654
2437
|
}, this.statusUpdateState.config.timeInSeconds * 1e3);
|
|
2655
|
-
|
|
2438
|
+
logger7.info(
|
|
2656
2439
|
{
|
|
2657
2440
|
sessionId: this.sessionId,
|
|
2658
2441
|
intervalMs: this.statusUpdateState.config.timeInSeconds * 1e3
|
|
@@ -2676,7 +2459,7 @@ var AgentSession = class {
|
|
|
2676
2459
|
this.sendDataOperation(dataOpEvent);
|
|
2677
2460
|
}
|
|
2678
2461
|
if (this.isEnded) {
|
|
2679
|
-
|
|
2462
|
+
logger7.debug(
|
|
2680
2463
|
{
|
|
2681
2464
|
sessionId: this.sessionId,
|
|
2682
2465
|
eventType,
|
|
@@ -2698,7 +2481,7 @@ var AgentSession = class {
|
|
|
2698
2481
|
if (artifactData.pendingGeneration) {
|
|
2699
2482
|
const artifactId = artifactData.artifactId;
|
|
2700
2483
|
if (this.pendingArtifacts.size >= this.MAX_PENDING_ARTIFACTS) {
|
|
2701
|
-
|
|
2484
|
+
logger7.warn(
|
|
2702
2485
|
{
|
|
2703
2486
|
sessionId: this.sessionId,
|
|
2704
2487
|
artifactId,
|
|
@@ -2720,7 +2503,7 @@ var AgentSession = class {
|
|
|
2720
2503
|
this.artifactProcessingErrors.set(artifactId, errorCount);
|
|
2721
2504
|
if (errorCount >= this.MAX_ARTIFACT_RETRIES) {
|
|
2722
2505
|
this.pendingArtifacts.delete(artifactId);
|
|
2723
|
-
|
|
2506
|
+
logger7.error(
|
|
2724
2507
|
{
|
|
2725
2508
|
sessionId: this.sessionId,
|
|
2726
2509
|
artifactId,
|
|
@@ -2732,7 +2515,7 @@ var AgentSession = class {
|
|
|
2732
2515
|
"Artifact processing failed after max retries, giving up"
|
|
2733
2516
|
);
|
|
2734
2517
|
} else {
|
|
2735
|
-
|
|
2518
|
+
logger7.warn(
|
|
2736
2519
|
{
|
|
2737
2520
|
sessionId: this.sessionId,
|
|
2738
2521
|
artifactId,
|
|
@@ -2755,14 +2538,14 @@ var AgentSession = class {
|
|
|
2755
2538
|
*/
|
|
2756
2539
|
checkStatusUpdates() {
|
|
2757
2540
|
if (this.isEnded) {
|
|
2758
|
-
|
|
2541
|
+
logger7.debug(
|
|
2759
2542
|
{ sessionId: this.sessionId },
|
|
2760
2543
|
"Session has ended - skipping status update check"
|
|
2761
2544
|
);
|
|
2762
2545
|
return;
|
|
2763
2546
|
}
|
|
2764
2547
|
if (!this.statusUpdateState) {
|
|
2765
|
-
|
|
2548
|
+
logger7.debug({ sessionId: this.sessionId }, "No status update state - skipping check");
|
|
2766
2549
|
return;
|
|
2767
2550
|
}
|
|
2768
2551
|
const statusUpdateState = this.statusUpdateState;
|
|
@@ -2773,11 +2556,11 @@ var AgentSession = class {
|
|
|
2773
2556
|
*/
|
|
2774
2557
|
async checkAndSendTimeBasedUpdate() {
|
|
2775
2558
|
if (this.isEnded) {
|
|
2776
|
-
|
|
2559
|
+
logger7.debug({ sessionId: this.sessionId }, "Session has ended - skipping time-based update");
|
|
2777
2560
|
return;
|
|
2778
2561
|
}
|
|
2779
2562
|
if (!this.statusUpdateState) {
|
|
2780
|
-
|
|
2563
|
+
logger7.debug(
|
|
2781
2564
|
{ sessionId: this.sessionId },
|
|
2782
2565
|
"No status updates configured for time-based check"
|
|
2783
2566
|
);
|
|
@@ -2790,7 +2573,7 @@ var AgentSession = class {
|
|
|
2790
2573
|
try {
|
|
2791
2574
|
await this.generateAndSendUpdate();
|
|
2792
2575
|
} catch (error) {
|
|
2793
|
-
|
|
2576
|
+
logger7.error(
|
|
2794
2577
|
{
|
|
2795
2578
|
sessionId: this.sessionId,
|
|
2796
2579
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -2893,29 +2676,29 @@ var AgentSession = class {
|
|
|
2893
2676
|
*/
|
|
2894
2677
|
async generateAndSendUpdate() {
|
|
2895
2678
|
if (this.isEnded) {
|
|
2896
|
-
|
|
2679
|
+
logger7.debug({ sessionId: this.sessionId }, "Session has ended - not generating update");
|
|
2897
2680
|
return;
|
|
2898
2681
|
}
|
|
2899
2682
|
if (this.isTextStreaming) {
|
|
2900
|
-
|
|
2683
|
+
logger7.debug(
|
|
2901
2684
|
{ sessionId: this.sessionId },
|
|
2902
2685
|
"Text is currently streaming - skipping status update"
|
|
2903
2686
|
);
|
|
2904
2687
|
return;
|
|
2905
2688
|
}
|
|
2906
2689
|
if (this.isGeneratingUpdate) {
|
|
2907
|
-
|
|
2690
|
+
logger7.debug(
|
|
2908
2691
|
{ sessionId: this.sessionId },
|
|
2909
2692
|
"Update already in progress - skipping duplicate generation"
|
|
2910
2693
|
);
|
|
2911
2694
|
return;
|
|
2912
2695
|
}
|
|
2913
2696
|
if (!this.statusUpdateState) {
|
|
2914
|
-
|
|
2697
|
+
logger7.warn({ sessionId: this.sessionId }, "No status update state - cannot generate update");
|
|
2915
2698
|
return;
|
|
2916
2699
|
}
|
|
2917
2700
|
if (!this.agentId) {
|
|
2918
|
-
|
|
2701
|
+
logger7.warn({ sessionId: this.sessionId }, "No agent ID - cannot generate update");
|
|
2919
2702
|
return;
|
|
2920
2703
|
}
|
|
2921
2704
|
const newEventCount = this.events.length - this.statusUpdateState.lastEventCount;
|
|
@@ -2927,7 +2710,7 @@ var AgentSession = class {
|
|
|
2927
2710
|
try {
|
|
2928
2711
|
const streamHelper = getStreamHelper(this.sessionId);
|
|
2929
2712
|
if (!streamHelper) {
|
|
2930
|
-
|
|
2713
|
+
logger7.warn(
|
|
2931
2714
|
{ sessionId: this.sessionId },
|
|
2932
2715
|
"No stream helper found - cannot send status update"
|
|
2933
2716
|
);
|
|
@@ -2947,7 +2730,7 @@ var AgentSession = class {
|
|
|
2947
2730
|
if (result.summaries && result.summaries.length > 0) {
|
|
2948
2731
|
for (const summary of result.summaries) {
|
|
2949
2732
|
if (!summary || !summary.type || !summary.data || !summary.data.label || Object.keys(summary.data).length === 0) {
|
|
2950
|
-
|
|
2733
|
+
logger7.warn(
|
|
2951
2734
|
{
|
|
2952
2735
|
sessionId: this.sessionId,
|
|
2953
2736
|
summary
|
|
@@ -2984,7 +2767,7 @@ var AgentSession = class {
|
|
|
2984
2767
|
this.statusUpdateState.lastEventCount = this.events.length;
|
|
2985
2768
|
}
|
|
2986
2769
|
} catch (error) {
|
|
2987
|
-
|
|
2770
|
+
logger7.error(
|
|
2988
2771
|
{
|
|
2989
2772
|
sessionId: this.sessionId,
|
|
2990
2773
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
@@ -3022,7 +2805,7 @@ var AgentSession = class {
|
|
|
3022
2805
|
this.releaseUpdateLock();
|
|
3023
2806
|
}
|
|
3024
2807
|
} catch (error) {
|
|
3025
|
-
|
|
2808
|
+
logger7.error(
|
|
3026
2809
|
{
|
|
3027
2810
|
sessionId: this.sessionId,
|
|
3028
2811
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -3101,7 +2884,7 @@ User's Question/Context:
|
|
|
3101
2884
|
${conversationHistory}
|
|
3102
2885
|
` : "";
|
|
3103
2886
|
} catch (error) {
|
|
3104
|
-
|
|
2887
|
+
logger7.warn(
|
|
3105
2888
|
{ sessionId: this.sessionId, error },
|
|
3106
2889
|
"Failed to fetch conversation history for structured status update"
|
|
3107
2890
|
);
|
|
@@ -3212,10 +2995,10 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
3212
2995
|
}
|
|
3213
2996
|
});
|
|
3214
2997
|
const result = object;
|
|
3215
|
-
|
|
2998
|
+
logger7.info({ result: JSON.stringify(result) }, "DEBUG: Result");
|
|
3216
2999
|
const summaries = [];
|
|
3217
3000
|
for (const [componentId, data] of Object.entries(result)) {
|
|
3218
|
-
|
|
3001
|
+
logger7.info({ componentId, data: JSON.stringify(data) }, "DEBUG: Component data");
|
|
3219
3002
|
if (componentId === "no_relevant_updates") {
|
|
3220
3003
|
continue;
|
|
3221
3004
|
}
|
|
@@ -3235,7 +3018,7 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
3235
3018
|
return { summaries };
|
|
3236
3019
|
} catch (error) {
|
|
3237
3020
|
setSpanWithError(span, error instanceof Error ? error : new Error(String(error)));
|
|
3238
|
-
|
|
3021
|
+
logger7.error({ error }, "Failed to generate structured update, using fallback");
|
|
3239
3022
|
return { summaries: [] };
|
|
3240
3023
|
} finally {
|
|
3241
3024
|
span.end();
|
|
@@ -3507,7 +3290,7 @@ Make it specific and relevant.`;
|
|
|
3507
3290
|
});
|
|
3508
3291
|
if (agentData && "models" in agentData && agentData.models?.base?.model) {
|
|
3509
3292
|
modelToUse = agentData.models.base;
|
|
3510
|
-
|
|
3293
|
+
logger7.info(
|
|
3511
3294
|
{
|
|
3512
3295
|
sessionId: this.sessionId,
|
|
3513
3296
|
artifactId: artifactData.artifactId,
|
|
@@ -3518,7 +3301,7 @@ Make it specific and relevant.`;
|
|
|
3518
3301
|
);
|
|
3519
3302
|
}
|
|
3520
3303
|
} catch (error) {
|
|
3521
|
-
|
|
3304
|
+
logger7.warn(
|
|
3522
3305
|
{
|
|
3523
3306
|
sessionId: this.sessionId,
|
|
3524
3307
|
artifactId: artifactData.artifactId,
|
|
@@ -3530,7 +3313,7 @@ Make it specific and relevant.`;
|
|
|
3530
3313
|
}
|
|
3531
3314
|
}
|
|
3532
3315
|
if (!modelToUse?.model?.trim()) {
|
|
3533
|
-
|
|
3316
|
+
logger7.warn(
|
|
3534
3317
|
{
|
|
3535
3318
|
sessionId: this.sessionId,
|
|
3536
3319
|
artifactId: artifactData.artifactId
|
|
@@ -3612,7 +3395,7 @@ Make it specific and relevant.`;
|
|
|
3612
3395
|
return result2;
|
|
3613
3396
|
} catch (error) {
|
|
3614
3397
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
3615
|
-
|
|
3398
|
+
logger7.warn(
|
|
3616
3399
|
{
|
|
3617
3400
|
sessionId: this.sessionId,
|
|
3618
3401
|
artifactId: artifactData.artifactId,
|
|
@@ -3660,7 +3443,7 @@ Make it specific and relevant.`;
|
|
|
3660
3443
|
});
|
|
3661
3444
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
3662
3445
|
} catch (saveError) {
|
|
3663
|
-
|
|
3446
|
+
logger7.error(
|
|
3664
3447
|
{
|
|
3665
3448
|
sessionId: this.sessionId,
|
|
3666
3449
|
artifactId: artifactData.artifactId,
|
|
@@ -3688,7 +3471,7 @@ Make it specific and relevant.`;
|
|
|
3688
3471
|
metadata: artifactData.metadata || {},
|
|
3689
3472
|
toolCallId: artifactData.toolCallId
|
|
3690
3473
|
});
|
|
3691
|
-
|
|
3474
|
+
logger7.info(
|
|
3692
3475
|
{
|
|
3693
3476
|
sessionId: this.sessionId,
|
|
3694
3477
|
artifactId: artifactData.artifactId
|
|
@@ -3699,7 +3482,7 @@ Make it specific and relevant.`;
|
|
|
3699
3482
|
} catch (fallbackError) {
|
|
3700
3483
|
const isDuplicateError = fallbackError instanceof Error && (fallbackError.message?.includes("UNIQUE") || fallbackError.message?.includes("duplicate"));
|
|
3701
3484
|
if (isDuplicateError) ; else {
|
|
3702
|
-
|
|
3485
|
+
logger7.error(
|
|
3703
3486
|
{
|
|
3704
3487
|
sessionId: this.sessionId,
|
|
3705
3488
|
artifactId: artifactData.artifactId,
|
|
@@ -3712,7 +3495,7 @@ Make it specific and relevant.`;
|
|
|
3712
3495
|
}
|
|
3713
3496
|
} catch (error) {
|
|
3714
3497
|
setSpanWithError(span, error instanceof Error ? error : new Error(String(error)));
|
|
3715
|
-
|
|
3498
|
+
logger7.error(
|
|
3716
3499
|
{
|
|
3717
3500
|
sessionId: this.sessionId,
|
|
3718
3501
|
artifactId: artifactData.artifactId,
|
|
@@ -3731,7 +3514,7 @@ Make it specific and relevant.`;
|
|
|
3731
3514
|
*/
|
|
3732
3515
|
setArtifactCache(key, artifact) {
|
|
3733
3516
|
this.artifactCache.set(key, artifact);
|
|
3734
|
-
|
|
3517
|
+
logger7.debug({ sessionId: this.sessionId, key }, "Artifact cached in session");
|
|
3735
3518
|
}
|
|
3736
3519
|
/**
|
|
3737
3520
|
* Get session-scoped ArtifactService instance
|
|
@@ -3750,7 +3533,7 @@ Make it specific and relevant.`;
|
|
|
3750
3533
|
*/
|
|
3751
3534
|
getArtifactCache(key) {
|
|
3752
3535
|
const artifact = this.artifactCache.get(key);
|
|
3753
|
-
|
|
3536
|
+
logger7.debug({ sessionId: this.sessionId, key, found: !!artifact }, "Artifact cache lookup");
|
|
3754
3537
|
return artifact || null;
|
|
3755
3538
|
}
|
|
3756
3539
|
/**
|
|
@@ -3771,7 +3554,7 @@ var AgentSessionManager = class {
|
|
|
3771
3554
|
const sessionId = messageId;
|
|
3772
3555
|
const session = new AgentSession(sessionId, messageId, agentId, tenantId, projectId, contextId);
|
|
3773
3556
|
this.sessions.set(sessionId, session);
|
|
3774
|
-
|
|
3557
|
+
logger7.info(
|
|
3775
3558
|
{ sessionId, messageId, agentId, tenantId, projectId, contextId },
|
|
3776
3559
|
"AgentSession created"
|
|
3777
3560
|
);
|
|
@@ -3785,7 +3568,7 @@ var AgentSessionManager = class {
|
|
|
3785
3568
|
if (session) {
|
|
3786
3569
|
session.initializeStatusUpdates(config, summarizerModel, baseModel);
|
|
3787
3570
|
} else {
|
|
3788
|
-
|
|
3571
|
+
logger7.error(
|
|
3789
3572
|
{
|
|
3790
3573
|
sessionId,
|
|
3791
3574
|
availableSessions: Array.from(this.sessions.keys())
|
|
@@ -3802,7 +3585,7 @@ var AgentSessionManager = class {
|
|
|
3802
3585
|
if (session) {
|
|
3803
3586
|
session.enableEmitOperations();
|
|
3804
3587
|
} else {
|
|
3805
|
-
|
|
3588
|
+
logger7.error(
|
|
3806
3589
|
{
|
|
3807
3590
|
sessionId,
|
|
3808
3591
|
availableSessions: Array.from(this.sessions.keys())
|
|
@@ -3824,7 +3607,7 @@ var AgentSessionManager = class {
|
|
|
3824
3607
|
recordEvent(sessionId, eventType, subAgentId, data) {
|
|
3825
3608
|
const session = this.sessions.get(sessionId);
|
|
3826
3609
|
if (!session) {
|
|
3827
|
-
|
|
3610
|
+
logger7.warn({ sessionId }, "Attempted to record event in non-existent session");
|
|
3828
3611
|
return;
|
|
3829
3612
|
}
|
|
3830
3613
|
session.recordEvent(eventType, subAgentId, data);
|
|
@@ -3835,12 +3618,12 @@ var AgentSessionManager = class {
|
|
|
3835
3618
|
endSession(sessionId) {
|
|
3836
3619
|
const session = this.sessions.get(sessionId);
|
|
3837
3620
|
if (!session) {
|
|
3838
|
-
|
|
3621
|
+
logger7.warn({ sessionId }, "Attempted to end non-existent session");
|
|
3839
3622
|
return [];
|
|
3840
3623
|
}
|
|
3841
3624
|
const events = session.getEvents();
|
|
3842
3625
|
const summary = session.getSummary();
|
|
3843
|
-
|
|
3626
|
+
logger7.info({ sessionId, summary }, "AgentSession ended");
|
|
3844
3627
|
session.cleanup();
|
|
3845
3628
|
this.sessions.delete(sessionId);
|
|
3846
3629
|
return events;
|
|
@@ -3939,7 +3722,7 @@ async function resolveModelConfig(agentId, subAgent) {
|
|
|
3939
3722
|
}
|
|
3940
3723
|
|
|
3941
3724
|
// src/services/IncrementalStreamParser.ts
|
|
3942
|
-
var
|
|
3725
|
+
var logger8 = getLogger("IncrementalStreamParser");
|
|
3943
3726
|
var IncrementalStreamParser = class _IncrementalStreamParser {
|
|
3944
3727
|
buffer = "";
|
|
3945
3728
|
pendingTextBuffer = "";
|
|
@@ -3997,7 +3780,7 @@ var IncrementalStreamParser = class _IncrementalStreamParser {
|
|
|
3997
3780
|
async initializeArtifactMap() {
|
|
3998
3781
|
try {
|
|
3999
3782
|
this.artifactMap = await this.artifactParser.getContextArtifacts(this.contextId);
|
|
4000
|
-
|
|
3783
|
+
logger8.debug(
|
|
4001
3784
|
{
|
|
4002
3785
|
contextId: this.contextId,
|
|
4003
3786
|
artifactMapSize: this.artifactMap.size
|
|
@@ -4005,7 +3788,7 @@ var IncrementalStreamParser = class _IncrementalStreamParser {
|
|
|
4005
3788
|
"Initialized artifact map for streaming"
|
|
4006
3789
|
);
|
|
4007
3790
|
} catch (error) {
|
|
4008
|
-
|
|
3791
|
+
logger8.warn({ error, contextId: this.contextId }, "Failed to initialize artifact map");
|
|
4009
3792
|
this.artifactMap = /* @__PURE__ */ new Map();
|
|
4010
3793
|
}
|
|
4011
3794
|
}
|
|
@@ -4338,6 +4121,142 @@ ${chunk}`;
|
|
|
4338
4121
|
}
|
|
4339
4122
|
};
|
|
4340
4123
|
|
|
4124
|
+
// src/services/PendingToolApprovalManager.ts
|
|
4125
|
+
var logger9 = getLogger("PendingToolApprovalManager");
|
|
4126
|
+
var APPROVAL_CLEANUP_INTERVAL_MS = 2 * 60 * 1e3;
|
|
4127
|
+
var APPROVAL_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
4128
|
+
var PendingToolApprovalManager = class _PendingToolApprovalManager {
|
|
4129
|
+
static instance;
|
|
4130
|
+
pendingApprovals = /* @__PURE__ */ new Map();
|
|
4131
|
+
constructor() {
|
|
4132
|
+
setInterval(() => this.cleanupExpiredApprovals(), APPROVAL_CLEANUP_INTERVAL_MS);
|
|
4133
|
+
}
|
|
4134
|
+
static getInstance() {
|
|
4135
|
+
if (!_PendingToolApprovalManager.instance) {
|
|
4136
|
+
_PendingToolApprovalManager.instance = new _PendingToolApprovalManager();
|
|
4137
|
+
}
|
|
4138
|
+
return _PendingToolApprovalManager.instance;
|
|
4139
|
+
}
|
|
4140
|
+
/**
|
|
4141
|
+
* Create a new pending approval and return a promise that resolves with approval status
|
|
4142
|
+
*/
|
|
4143
|
+
async waitForApproval(toolCallId, toolName, args, conversationId, subAgentId) {
|
|
4144
|
+
return new Promise((resolve, reject) => {
|
|
4145
|
+
const timeoutId = setTimeout(() => {
|
|
4146
|
+
this.pendingApprovals.delete(toolCallId);
|
|
4147
|
+
resolve({
|
|
4148
|
+
approved: false,
|
|
4149
|
+
reason: `Tool approval timeout for ${toolName} (${toolCallId})`
|
|
4150
|
+
});
|
|
4151
|
+
}, APPROVAL_TIMEOUT_MS);
|
|
4152
|
+
const approval = {
|
|
4153
|
+
toolCallId,
|
|
4154
|
+
toolName,
|
|
4155
|
+
args,
|
|
4156
|
+
conversationId,
|
|
4157
|
+
subAgentId,
|
|
4158
|
+
createdAt: Date.now(),
|
|
4159
|
+
resolve,
|
|
4160
|
+
reject,
|
|
4161
|
+
timeoutId
|
|
4162
|
+
};
|
|
4163
|
+
this.pendingApprovals.set(toolCallId, approval);
|
|
4164
|
+
logger9.info(
|
|
4165
|
+
{
|
|
4166
|
+
toolCallId,
|
|
4167
|
+
toolName,
|
|
4168
|
+
conversationId,
|
|
4169
|
+
subAgentId
|
|
4170
|
+
},
|
|
4171
|
+
"Tool approval request created, waiting for user response"
|
|
4172
|
+
);
|
|
4173
|
+
});
|
|
4174
|
+
}
|
|
4175
|
+
/**
|
|
4176
|
+
* Approve a pending tool call
|
|
4177
|
+
*/
|
|
4178
|
+
approveToolCall(toolCallId) {
|
|
4179
|
+
const approval = this.pendingApprovals.get(toolCallId);
|
|
4180
|
+
if (!approval) {
|
|
4181
|
+
logger9.warn({ toolCallId }, "Tool approval not found or already processed");
|
|
4182
|
+
return false;
|
|
4183
|
+
}
|
|
4184
|
+
logger9.info(
|
|
4185
|
+
{
|
|
4186
|
+
toolCallId,
|
|
4187
|
+
toolName: approval.toolName,
|
|
4188
|
+
conversationId: approval.conversationId
|
|
4189
|
+
},
|
|
4190
|
+
"Tool approved by user, resuming execution"
|
|
4191
|
+
);
|
|
4192
|
+
clearTimeout(approval.timeoutId);
|
|
4193
|
+
this.pendingApprovals.delete(toolCallId);
|
|
4194
|
+
approval.resolve({ approved: true });
|
|
4195
|
+
return true;
|
|
4196
|
+
}
|
|
4197
|
+
/**
|
|
4198
|
+
* Deny a pending tool call
|
|
4199
|
+
*/
|
|
4200
|
+
denyToolCall(toolCallId, reason) {
|
|
4201
|
+
const approval = this.pendingApprovals.get(toolCallId);
|
|
4202
|
+
if (!approval) {
|
|
4203
|
+
logger9.warn({ toolCallId }, "Tool approval not found or already processed");
|
|
4204
|
+
return false;
|
|
4205
|
+
}
|
|
4206
|
+
logger9.info(
|
|
4207
|
+
{
|
|
4208
|
+
toolCallId,
|
|
4209
|
+
toolName: approval.toolName,
|
|
4210
|
+
conversationId: approval.conversationId,
|
|
4211
|
+
reason
|
|
4212
|
+
},
|
|
4213
|
+
"Tool execution denied by user"
|
|
4214
|
+
);
|
|
4215
|
+
clearTimeout(approval.timeoutId);
|
|
4216
|
+
this.pendingApprovals.delete(toolCallId);
|
|
4217
|
+
approval.resolve({
|
|
4218
|
+
approved: false,
|
|
4219
|
+
reason: reason || "User denied approval"
|
|
4220
|
+
});
|
|
4221
|
+
return true;
|
|
4222
|
+
}
|
|
4223
|
+
/**
|
|
4224
|
+
* Clean up expired approvals (called by interval timer)
|
|
4225
|
+
*/
|
|
4226
|
+
cleanupExpiredApprovals() {
|
|
4227
|
+
const now = Date.now();
|
|
4228
|
+
let cleanedUp = 0;
|
|
4229
|
+
for (const [toolCallId, approval] of this.pendingApprovals) {
|
|
4230
|
+
if (now - approval.createdAt > APPROVAL_TIMEOUT_MS) {
|
|
4231
|
+
clearTimeout(approval.timeoutId);
|
|
4232
|
+
this.pendingApprovals.delete(toolCallId);
|
|
4233
|
+
approval.resolve({ approved: false, reason: "Tool approval expired" });
|
|
4234
|
+
cleanedUp++;
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
if (cleanedUp > 0) {
|
|
4238
|
+
logger9.info({ cleanedUp }, "Cleaned up expired tool approvals");
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
4241
|
+
/**
|
|
4242
|
+
* Get current status for monitoring
|
|
4243
|
+
*/
|
|
4244
|
+
getStatus() {
|
|
4245
|
+
return {
|
|
4246
|
+
pendingApprovals: this.pendingApprovals.size,
|
|
4247
|
+
approvals: Array.from(this.pendingApprovals.values()).map((approval) => ({
|
|
4248
|
+
toolCallId: approval.toolCallId,
|
|
4249
|
+
toolName: approval.toolName,
|
|
4250
|
+
conversationId: approval.conversationId,
|
|
4251
|
+
subAgentId: approval.subAgentId,
|
|
4252
|
+
createdAt: approval.createdAt,
|
|
4253
|
+
age: Date.now() - approval.createdAt
|
|
4254
|
+
}))
|
|
4255
|
+
};
|
|
4256
|
+
}
|
|
4257
|
+
};
|
|
4258
|
+
var pendingToolApprovalManager = PendingToolApprovalManager.getInstance();
|
|
4259
|
+
|
|
4341
4260
|
// src/services/ResponseFormatter.ts
|
|
4342
4261
|
var logger10 = getLogger("ResponseFormatter");
|
|
4343
4262
|
var ResponseFormatter = class {
|
|
@@ -7142,7 +7061,7 @@ var Agent = class {
|
|
|
7142
7061
|
/**
|
|
7143
7062
|
* Wraps a tool with streaming lifecycle tracking (start, complete, error) and AgentSession recording
|
|
7144
7063
|
*/
|
|
7145
|
-
wrapToolWithStreaming(toolName, toolDefinition, streamRequestId, toolType, relationshipId) {
|
|
7064
|
+
wrapToolWithStreaming(toolName, toolDefinition, streamRequestId, toolType, relationshipId, options) {
|
|
7146
7065
|
if (!toolDefinition || typeof toolDefinition !== "object" || !("execute" in toolDefinition)) {
|
|
7147
7066
|
return toolDefinition;
|
|
7148
7067
|
}
|
|
@@ -7164,13 +7083,24 @@ var Agent = class {
|
|
|
7164
7083
|
});
|
|
7165
7084
|
}
|
|
7166
7085
|
const isInternalTool = toolName.includes("save_tool_result") || toolName.includes("thinking_complete") || toolName.startsWith("transfer_to_");
|
|
7086
|
+
const needsApproval = options?.needsApproval || false;
|
|
7167
7087
|
if (streamRequestId && !isInternalTool) {
|
|
7168
|
-
|
|
7088
|
+
const toolCallData = {
|
|
7169
7089
|
toolName,
|
|
7170
7090
|
input: args,
|
|
7171
7091
|
toolCallId,
|
|
7172
7092
|
relationshipId
|
|
7173
|
-
}
|
|
7093
|
+
};
|
|
7094
|
+
if (needsApproval) {
|
|
7095
|
+
toolCallData.needsApproval = true;
|
|
7096
|
+
toolCallData.conversationId = this.conversationId;
|
|
7097
|
+
}
|
|
7098
|
+
await agentSessionManager.recordEvent(
|
|
7099
|
+
streamRequestId,
|
|
7100
|
+
"tool_call",
|
|
7101
|
+
this.config.id,
|
|
7102
|
+
toolCallData
|
|
7103
|
+
);
|
|
7174
7104
|
}
|
|
7175
7105
|
try {
|
|
7176
7106
|
const result = await originalExecute(args, context);
|
|
@@ -7215,7 +7145,8 @@ var Agent = class {
|
|
|
7215
7145
|
output: result,
|
|
7216
7146
|
toolCallId,
|
|
7217
7147
|
duration,
|
|
7218
|
-
relationshipId
|
|
7148
|
+
relationshipId,
|
|
7149
|
+
needsApproval
|
|
7219
7150
|
});
|
|
7220
7151
|
}
|
|
7221
7152
|
return result;
|
|
@@ -7229,7 +7160,8 @@ var Agent = class {
|
|
|
7229
7160
|
toolCallId,
|
|
7230
7161
|
duration,
|
|
7231
7162
|
error: errorMessage,
|
|
7232
|
-
relationshipId
|
|
7163
|
+
relationshipId,
|
|
7164
|
+
needsApproval
|
|
7233
7165
|
});
|
|
7234
7166
|
}
|
|
7235
7167
|
throw error;
|
|
@@ -7298,30 +7230,120 @@ var Agent = class {
|
|
|
7298
7230
|
const wrappedTools2 = {};
|
|
7299
7231
|
for (const [index, toolSet] of tools.entries()) {
|
|
7300
7232
|
const relationshipId = mcpTools[index]?.relationshipId;
|
|
7301
|
-
for (const [toolName, toolDef] of Object.entries(toolSet)) {
|
|
7233
|
+
for (const [toolName, toolDef] of Object.entries(toolSet.tools)) {
|
|
7234
|
+
const needsApproval = toolSet.toolPolicies?.[toolName]?.needsApproval || false;
|
|
7235
|
+
const enhancedTool = {
|
|
7236
|
+
...toolDef,
|
|
7237
|
+
needsApproval
|
|
7238
|
+
};
|
|
7302
7239
|
wrappedTools2[toolName] = this.wrapToolWithStreaming(
|
|
7303
7240
|
toolName,
|
|
7304
|
-
|
|
7241
|
+
enhancedTool,
|
|
7305
7242
|
streamRequestId,
|
|
7306
7243
|
"mcp",
|
|
7307
|
-
relationshipId
|
|
7244
|
+
relationshipId,
|
|
7245
|
+
{ needsApproval }
|
|
7308
7246
|
);
|
|
7309
7247
|
}
|
|
7310
7248
|
}
|
|
7311
7249
|
return wrappedTools2;
|
|
7312
7250
|
}
|
|
7313
7251
|
const wrappedTools = {};
|
|
7314
|
-
for (const [index,
|
|
7252
|
+
for (const [index, toolResult] of tools.entries()) {
|
|
7315
7253
|
const relationshipId = mcpTools[index]?.relationshipId;
|
|
7316
|
-
for (const [toolName, originalTool] of Object.entries(
|
|
7254
|
+
for (const [toolName, originalTool] of Object.entries(toolResult.tools)) {
|
|
7317
7255
|
if (!isValidTool(originalTool)) {
|
|
7318
7256
|
logger15.error({ toolName }, "Invalid MCP tool structure - missing required properties");
|
|
7319
7257
|
continue;
|
|
7320
7258
|
}
|
|
7259
|
+
const needsApproval = toolResult.toolPolicies?.[toolName]?.needsApproval || false;
|
|
7260
|
+
logger15.debug(
|
|
7261
|
+
{
|
|
7262
|
+
toolName,
|
|
7263
|
+
toolPolicies: toolResult.toolPolicies,
|
|
7264
|
+
needsApproval,
|
|
7265
|
+
policyForThisTool: toolResult.toolPolicies?.[toolName]
|
|
7266
|
+
},
|
|
7267
|
+
"Tool approval check"
|
|
7268
|
+
);
|
|
7321
7269
|
const sessionWrappedTool = tool({
|
|
7322
7270
|
description: originalTool.description,
|
|
7323
7271
|
inputSchema: originalTool.inputSchema,
|
|
7324
7272
|
execute: async (args, { toolCallId }) => {
|
|
7273
|
+
if (needsApproval) {
|
|
7274
|
+
logger15.info(
|
|
7275
|
+
{ toolName, toolCallId, args },
|
|
7276
|
+
"Tool requires approval - waiting for user response"
|
|
7277
|
+
);
|
|
7278
|
+
const currentSpan = trace.getActiveSpan();
|
|
7279
|
+
if (currentSpan) {
|
|
7280
|
+
currentSpan.addEvent("tool.approval.requested", {
|
|
7281
|
+
"tool.name": toolName,
|
|
7282
|
+
"tool.callId": toolCallId,
|
|
7283
|
+
"subAgent.id": this.config.id
|
|
7284
|
+
});
|
|
7285
|
+
}
|
|
7286
|
+
tracer.startActiveSpan(
|
|
7287
|
+
"tool.approval_requested",
|
|
7288
|
+
{
|
|
7289
|
+
attributes: {
|
|
7290
|
+
"tool.name": toolName,
|
|
7291
|
+
"tool.callId": toolCallId,
|
|
7292
|
+
"subAgent.id": this.config.id,
|
|
7293
|
+
"subAgent.name": this.config.name
|
|
7294
|
+
}
|
|
7295
|
+
},
|
|
7296
|
+
(requestSpan) => {
|
|
7297
|
+
requestSpan.setStatus({ code: SpanStatusCode.OK });
|
|
7298
|
+
requestSpan.end();
|
|
7299
|
+
}
|
|
7300
|
+
);
|
|
7301
|
+
const approvalResult = await pendingToolApprovalManager.waitForApproval(
|
|
7302
|
+
toolCallId,
|
|
7303
|
+
toolName,
|
|
7304
|
+
args,
|
|
7305
|
+
this.conversationId || "unknown",
|
|
7306
|
+
this.config.id
|
|
7307
|
+
);
|
|
7308
|
+
if (!approvalResult.approved) {
|
|
7309
|
+
return tracer.startActiveSpan(
|
|
7310
|
+
"tool.approval_denied",
|
|
7311
|
+
{
|
|
7312
|
+
attributes: {
|
|
7313
|
+
"tool.name": toolName,
|
|
7314
|
+
"tool.callId": toolCallId,
|
|
7315
|
+
"subAgent.id": this.config.id,
|
|
7316
|
+
"subAgent.name": this.config.name
|
|
7317
|
+
}
|
|
7318
|
+
},
|
|
7319
|
+
(denialSpan) => {
|
|
7320
|
+
logger15.info(
|
|
7321
|
+
{ toolName, toolCallId, reason: approvalResult.reason },
|
|
7322
|
+
"Tool execution denied by user"
|
|
7323
|
+
);
|
|
7324
|
+
denialSpan.setStatus({ code: SpanStatusCode.OK });
|
|
7325
|
+
denialSpan.end();
|
|
7326
|
+
return `User denied approval to run this tool: ${approvalResult.reason}`;
|
|
7327
|
+
}
|
|
7328
|
+
);
|
|
7329
|
+
}
|
|
7330
|
+
tracer.startActiveSpan(
|
|
7331
|
+
"tool.approval_approved",
|
|
7332
|
+
{
|
|
7333
|
+
attributes: {
|
|
7334
|
+
"tool.name": toolName,
|
|
7335
|
+
"tool.callId": toolCallId,
|
|
7336
|
+
"subAgent.id": this.config.id,
|
|
7337
|
+
"subAgent.name": this.config.name
|
|
7338
|
+
}
|
|
7339
|
+
},
|
|
7340
|
+
(approvedSpan) => {
|
|
7341
|
+
logger15.info({ toolName, toolCallId }, "Tool approved, continuing with execution");
|
|
7342
|
+
approvedSpan.setStatus({ code: SpanStatusCode.OK });
|
|
7343
|
+
approvedSpan.end();
|
|
7344
|
+
}
|
|
7345
|
+
);
|
|
7346
|
+
}
|
|
7325
7347
|
logger15.debug({ toolName, toolCallId }, "MCP Tool Called");
|
|
7326
7348
|
try {
|
|
7327
7349
|
const rawResult = await originalTool.execute(args, { toolCallId });
|
|
@@ -7387,7 +7409,8 @@ var Agent = class {
|
|
|
7387
7409
|
sessionWrappedTool,
|
|
7388
7410
|
streamRequestId,
|
|
7389
7411
|
"mcp",
|
|
7390
|
-
relationshipId
|
|
7412
|
+
relationshipId,
|
|
7413
|
+
{ needsApproval }
|
|
7391
7414
|
);
|
|
7392
7415
|
}
|
|
7393
7416
|
}
|
|
@@ -7426,8 +7449,10 @@ var Agent = class {
|
|
|
7426
7449
|
subAgentId: this.config.id
|
|
7427
7450
|
}
|
|
7428
7451
|
});
|
|
7429
|
-
const
|
|
7430
|
-
const
|
|
7452
|
+
const toolRelation = toolsForAgent.data.find((t) => t.toolId === tool3.id);
|
|
7453
|
+
const agentToolRelationHeaders = toolRelation?.headers || void 0;
|
|
7454
|
+
const selectedTools = toolRelation?.selectedTools || void 0;
|
|
7455
|
+
const toolPolicies = toolRelation?.toolPolicies || {};
|
|
7431
7456
|
let serverConfig;
|
|
7432
7457
|
if (credentialReferenceId && this.credentialStuffer) {
|
|
7433
7458
|
const credentialReference = await getCredentialReference(dbClient_default)({
|
|
@@ -7558,7 +7583,7 @@ var Agent = class {
|
|
|
7558
7583
|
);
|
|
7559
7584
|
}
|
|
7560
7585
|
}
|
|
7561
|
-
return tools;
|
|
7586
|
+
return { tools, toolPolicies };
|
|
7562
7587
|
}
|
|
7563
7588
|
async createMcpConnection(tool3, serverConfig) {
|
|
7564
7589
|
const client = new McpClient({
|
|
@@ -7581,12 +7606,12 @@ var Agent = class {
|
|
|
7581
7606
|
if (error?.cause && JSON.stringify(error.cause).includes("ECONNREFUSED")) {
|
|
7582
7607
|
const errorMessage = "Connection refused. Please check if the MCP server is running.";
|
|
7583
7608
|
throw new Error(errorMessage);
|
|
7584
|
-
}
|
|
7609
|
+
}
|
|
7610
|
+
if (error.message.includes("404")) {
|
|
7585
7611
|
const errorMessage = "Error accessing endpoint (HTTP 404)";
|
|
7586
7612
|
throw new Error(errorMessage);
|
|
7587
|
-
} else {
|
|
7588
|
-
throw new Error(`MCP server connection failed: ${error.message}`);
|
|
7589
7613
|
}
|
|
7614
|
+
throw new Error(`MCP server connection failed: ${error.message}`);
|
|
7590
7615
|
}
|
|
7591
7616
|
throw error;
|
|
7592
7617
|
}
|
|
@@ -7606,7 +7631,7 @@ var Agent = class {
|
|
|
7606
7631
|
if (functionToolsData.length === 0) {
|
|
7607
7632
|
return functionTools;
|
|
7608
7633
|
}
|
|
7609
|
-
const { SandboxExecutorFactory } = await import('./SandboxExecutorFactory-
|
|
7634
|
+
const { SandboxExecutorFactory } = await import('./SandboxExecutorFactory-FVKDJKKZ.js');
|
|
7610
7635
|
const sandboxExecutor = SandboxExecutorFactory.getInstance();
|
|
7611
7636
|
for (const functionToolDef of functionToolsData) {
|
|
7612
7637
|
const functionId = functionToolDef.functionId;
|
|
@@ -7900,7 +7925,7 @@ var Agent = class {
|
|
|
7900
7925
|
inputSchema: tool3.inputSchema || tool3.parameters || {},
|
|
7901
7926
|
usageGuidelines: name.startsWith("transfer_to_") || name.startsWith("delegate_to_") ? `Use this tool to ${name.startsWith("transfer_to_") ? "transfer" : "delegate"} to another agent when appropriate.` : "Use this tool when appropriate for the task at hand."
|
|
7902
7927
|
}));
|
|
7903
|
-
const { getConversationScopedArtifacts } = await import('./conversations-
|
|
7928
|
+
const { getConversationScopedArtifacts } = await import('./conversations-NZLQK64L.js');
|
|
7904
7929
|
const historyConfig = this.config.conversationHistoryConfig ?? createDefaultConversationHistoryConfig();
|
|
7905
7930
|
const referenceArtifacts = await getConversationScopedArtifacts({
|
|
7906
7931
|
tenantId: this.config.tenantId,
|
|
@@ -8484,13 +8509,13 @@ ${output}`;
|
|
|
8484
8509
|
parser.markToolResult();
|
|
8485
8510
|
}
|
|
8486
8511
|
break;
|
|
8487
|
-
case "error":
|
|
8512
|
+
case "error": {
|
|
8488
8513
|
if (event.error instanceof Error) {
|
|
8489
8514
|
throw event.error;
|
|
8490
|
-
} else {
|
|
8491
|
-
const errorMessage = event.error?.error?.message;
|
|
8492
|
-
throw new Error(errorMessage);
|
|
8493
8515
|
}
|
|
8516
|
+
const errorMessage = event.error?.error?.message;
|
|
8517
|
+
throw new Error(errorMessage);
|
|
8518
|
+
}
|
|
8494
8519
|
}
|
|
8495
8520
|
}
|
|
8496
8521
|
await parser.finalize();
|
|
@@ -9385,17 +9410,16 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9385
9410
|
}
|
|
9386
9411
|
]
|
|
9387
9412
|
};
|
|
9388
|
-
} else {
|
|
9389
|
-
logger16.warn(
|
|
9390
|
-
{
|
|
9391
|
-
hasToolResult: !!toolResult,
|
|
9392
|
-
hasOutput: !!toolResult?.output,
|
|
9393
|
-
validationPassed: false,
|
|
9394
|
-
output: toolResult?.output
|
|
9395
|
-
},
|
|
9396
|
-
"[DEBUG] Transfer validation FAILED"
|
|
9397
|
-
);
|
|
9398
9413
|
}
|
|
9414
|
+
logger16.warn(
|
|
9415
|
+
{
|
|
9416
|
+
hasToolResult: !!toolResult,
|
|
9417
|
+
hasOutput: !!toolResult?.output,
|
|
9418
|
+
validationPassed: false,
|
|
9419
|
+
output: toolResult?.output
|
|
9420
|
+
},
|
|
9421
|
+
"[DEBUG] Transfer validation FAILED"
|
|
9422
|
+
);
|
|
9399
9423
|
}
|
|
9400
9424
|
}
|
|
9401
9425
|
}
|
|
@@ -10295,7 +10319,7 @@ var VercelDataStreamHelper = class _VercelDataStreamHelper {
|
|
|
10295
10319
|
}
|
|
10296
10320
|
const now = Date.now();
|
|
10297
10321
|
const gapFromLastTextEnd = this.lastTextEndTimestamp > 0 ? now - this.lastTextEndTimestamp : Number.MAX_SAFE_INTEGER;
|
|
10298
|
-
if (this.isTextStreaming || gapFromLastTextEnd < STREAM_TEXT_GAP_THRESHOLD_MS) {
|
|
10322
|
+
if (operation.type !== "tool_call" && operation.type !== "tool_result" && (this.isTextStreaming || gapFromLastTextEnd < STREAM_TEXT_GAP_THRESHOLD_MS)) {
|
|
10299
10323
|
this.queuedEvents.push({ type: "data-operation", event: operation });
|
|
10300
10324
|
return;
|
|
10301
10325
|
}
|
|
@@ -11459,13 +11483,152 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
11459
11483
|
);
|
|
11460
11484
|
});
|
|
11461
11485
|
} catch (error) {
|
|
11462
|
-
logger22.error(
|
|
11486
|
+
logger22.error(
|
|
11487
|
+
{
|
|
11488
|
+
error,
|
|
11489
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
11490
|
+
errorStack: error instanceof Error ? error.stack : void 0,
|
|
11491
|
+
errorType: error?.constructor?.name
|
|
11492
|
+
},
|
|
11493
|
+
"chatDataStream error - DETAILED"
|
|
11494
|
+
);
|
|
11463
11495
|
throw createApiError({
|
|
11464
11496
|
code: "internal_server_error",
|
|
11465
11497
|
message: "Failed to process chat completion"
|
|
11466
11498
|
});
|
|
11467
11499
|
}
|
|
11468
11500
|
});
|
|
11501
|
+
var toolApprovalRoute = createRoute({
|
|
11502
|
+
method: "post",
|
|
11503
|
+
path: "/tool-approvals",
|
|
11504
|
+
tags: ["chat"],
|
|
11505
|
+
summary: "Approve or deny tool execution",
|
|
11506
|
+
description: "Handle user approval/denial of tool execution requests during conversations",
|
|
11507
|
+
security: [{ bearerAuth: [] }],
|
|
11508
|
+
request: {
|
|
11509
|
+
body: {
|
|
11510
|
+
content: {
|
|
11511
|
+
"application/json": {
|
|
11512
|
+
schema: z$1.object({
|
|
11513
|
+
conversationId: z$1.string().describe("The conversation ID"),
|
|
11514
|
+
toolCallId: z$1.string().describe("The tool call ID to respond to"),
|
|
11515
|
+
approved: z$1.boolean().describe("Whether the tool execution is approved"),
|
|
11516
|
+
reason: z$1.string().optional().describe("Optional reason for the decision")
|
|
11517
|
+
})
|
|
11518
|
+
}
|
|
11519
|
+
}
|
|
11520
|
+
}
|
|
11521
|
+
},
|
|
11522
|
+
responses: {
|
|
11523
|
+
200: {
|
|
11524
|
+
description: "Tool approval response processed successfully",
|
|
11525
|
+
content: {
|
|
11526
|
+
"application/json": {
|
|
11527
|
+
schema: z$1.object({
|
|
11528
|
+
success: z$1.boolean(),
|
|
11529
|
+
message: z$1.string().optional()
|
|
11530
|
+
})
|
|
11531
|
+
}
|
|
11532
|
+
}
|
|
11533
|
+
},
|
|
11534
|
+
400: {
|
|
11535
|
+
description: "Bad request - invalid tool call ID or conversation ID",
|
|
11536
|
+
content: {
|
|
11537
|
+
"application/json": {
|
|
11538
|
+
schema: z$1.object({
|
|
11539
|
+
error: z$1.string()
|
|
11540
|
+
})
|
|
11541
|
+
}
|
|
11542
|
+
}
|
|
11543
|
+
},
|
|
11544
|
+
404: {
|
|
11545
|
+
description: "Tool call not found or already processed",
|
|
11546
|
+
content: {
|
|
11547
|
+
"application/json": {
|
|
11548
|
+
schema: z$1.object({
|
|
11549
|
+
error: z$1.string()
|
|
11550
|
+
})
|
|
11551
|
+
}
|
|
11552
|
+
}
|
|
11553
|
+
},
|
|
11554
|
+
500: {
|
|
11555
|
+
description: "Internal server error",
|
|
11556
|
+
content: {
|
|
11557
|
+
"application/json": {
|
|
11558
|
+
schema: z$1.object({
|
|
11559
|
+
error: z$1.string(),
|
|
11560
|
+
message: z$1.string()
|
|
11561
|
+
})
|
|
11562
|
+
}
|
|
11563
|
+
}
|
|
11564
|
+
}
|
|
11565
|
+
}
|
|
11566
|
+
});
|
|
11567
|
+
app3.openapi(toolApprovalRoute, async (c) => {
|
|
11568
|
+
const tracer2 = trace.getTracer("tool-approval-handler");
|
|
11569
|
+
return tracer2.startActiveSpan("tool_approval_request", async (span) => {
|
|
11570
|
+
try {
|
|
11571
|
+
const executionContext = getRequestExecutionContext(c);
|
|
11572
|
+
const { tenantId, projectId } = executionContext;
|
|
11573
|
+
const requestBody = await c.req.json();
|
|
11574
|
+
const { conversationId, toolCallId, approved, reason } = requestBody;
|
|
11575
|
+
logger22.info(
|
|
11576
|
+
{
|
|
11577
|
+
conversationId,
|
|
11578
|
+
toolCallId,
|
|
11579
|
+
approved,
|
|
11580
|
+
reason,
|
|
11581
|
+
tenantId,
|
|
11582
|
+
projectId
|
|
11583
|
+
},
|
|
11584
|
+
"Processing tool approval request"
|
|
11585
|
+
);
|
|
11586
|
+
const conversation = await getConversation(dbClient_default)({
|
|
11587
|
+
scopes: { tenantId, projectId },
|
|
11588
|
+
conversationId
|
|
11589
|
+
});
|
|
11590
|
+
if (!conversation) {
|
|
11591
|
+
span.setStatus({ code: 1, message: "Conversation not found" });
|
|
11592
|
+
return c.json({ error: "Conversation not found" }, 404);
|
|
11593
|
+
}
|
|
11594
|
+
let success = false;
|
|
11595
|
+
if (approved) {
|
|
11596
|
+
success = pendingToolApprovalManager.approveToolCall(toolCallId);
|
|
11597
|
+
} else {
|
|
11598
|
+
success = pendingToolApprovalManager.denyToolCall(toolCallId, reason);
|
|
11599
|
+
}
|
|
11600
|
+
if (!success) {
|
|
11601
|
+
span.setStatus({ code: 1, message: "Tool call not found" });
|
|
11602
|
+
return c.json({ error: "Tool call not found or already processed" }, 404);
|
|
11603
|
+
}
|
|
11604
|
+
logger22.info({ conversationId, toolCallId, approved }, "Tool approval processed successfully");
|
|
11605
|
+
span.setStatus({ code: 1, message: "Success" });
|
|
11606
|
+
return c.json({
|
|
11607
|
+
success: true,
|
|
11608
|
+
message: approved ? "Tool execution approved" : "Tool execution denied"
|
|
11609
|
+
});
|
|
11610
|
+
} catch (error) {
|
|
11611
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
11612
|
+
logger22.error(
|
|
11613
|
+
{
|
|
11614
|
+
error: errorMessage,
|
|
11615
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
11616
|
+
},
|
|
11617
|
+
"Failed to process tool approval"
|
|
11618
|
+
);
|
|
11619
|
+
span.setStatus({ code: 2, message: errorMessage });
|
|
11620
|
+
return c.json(
|
|
11621
|
+
{
|
|
11622
|
+
error: "Internal server error",
|
|
11623
|
+
message: errorMessage
|
|
11624
|
+
},
|
|
11625
|
+
500
|
|
11626
|
+
);
|
|
11627
|
+
} finally {
|
|
11628
|
+
span.end();
|
|
11629
|
+
}
|
|
11630
|
+
});
|
|
11631
|
+
});
|
|
11469
11632
|
var chatDataStream_default = app3;
|
|
11470
11633
|
var logger23 = getLogger("mcp");
|
|
11471
11634
|
var MockResponseSingleton = class _MockResponseSingleton {
|
|
@@ -11544,7 +11707,8 @@ var validateSession = async (req, res, body, tenantId, projectId, agentId) => {
|
|
|
11544
11707
|
})
|
|
11545
11708
|
);
|
|
11546
11709
|
return false;
|
|
11547
|
-
}
|
|
11710
|
+
}
|
|
11711
|
+
if (Array.isArray(sessionId)) {
|
|
11548
11712
|
res.writeHead(400).end(
|
|
11549
11713
|
JSON.stringify({
|
|
11550
11714
|
jsonrpc: "2.0",
|
|
@@ -11967,16 +12131,15 @@ app4.openapi(
|
|
|
11967
12131
|
c,
|
|
11968
12132
|
credentialStores
|
|
11969
12133
|
);
|
|
11970
|
-
} else {
|
|
11971
|
-
return await handleExistingSessionRequest(
|
|
11972
|
-
body,
|
|
11973
|
-
executionContext,
|
|
11974
|
-
validatedContext,
|
|
11975
|
-
req,
|
|
11976
|
-
res,
|
|
11977
|
-
credentialStores
|
|
11978
|
-
);
|
|
11979
12134
|
}
|
|
12135
|
+
return await handleExistingSessionRequest(
|
|
12136
|
+
body,
|
|
12137
|
+
executionContext,
|
|
12138
|
+
validatedContext,
|
|
12139
|
+
req,
|
|
12140
|
+
res,
|
|
12141
|
+
credentialStores
|
|
12142
|
+
);
|
|
11980
12143
|
} catch (e) {
|
|
11981
12144
|
logger23.error(
|
|
11982
12145
|
{
|