@inkeep/agents-run-api 0.38.0 → 0.38.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/index.cjs +1371 -322
- package/dist/index.js +1439 -395
- package/package.json +2 -5
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import { dbClient_default } from './chunk-EVOISBFH.js';
|
|
|
4
4
|
import { env } from './chunk-KBZIYCPJ.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-THWNUGWP.js';
|
|
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, getUserScopedCredentialReference, getCredentialReference, McpClient, getFunctionToolsForSubAgent, getFunction, jsonSchemaToZod, getContextConfigById, getFullAgentDefinition, TemplateEngine, listTaskIdsByContextId,
|
|
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, getLedgerArtifacts, verifyTempToken, validateAndGetApiKey, verifyServiceToken, validateTargetAgent, ContextResolver, CredentialStuffer, MCPServerType, getUserScopedCredentialReference, getCredentialReference, McpClient, getFunctionToolsForSubAgent, getFunction, jsonSchemaToZod, getContextConfigById, getFullAgentDefinition, TemplateEngine, listTaskIdsByContextId, agentHasArtifactComponents, upsertLedgerArtifact, MCPTransportType, SPAN_KEYS, headers, generateServiceToken } from '@inkeep/agents-core';
|
|
8
8
|
import { otel } from '@hono/otel';
|
|
9
|
-
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
|
|
9
|
+
import { OpenAPIHono, createRoute, z as z$1 } from '@hono/zod-openapi';
|
|
10
10
|
import { trace, propagation, context, SpanStatusCode } from '@opentelemetry/api';
|
|
11
11
|
import { Hono } from 'hono';
|
|
12
12
|
import { cors } from 'hono/cors';
|
|
@@ -18,6 +18,8 @@ import { streamSSE, stream } from 'hono/streaming';
|
|
|
18
18
|
import { createUIMessageStream, JsonToSseTransformStream, parsePartialJson, generateObject, tool, streamText, generateText, streamObject } from 'ai';
|
|
19
19
|
import jmespath from 'jmespath';
|
|
20
20
|
import Ajv from 'ajv';
|
|
21
|
+
import { randomUUID } from 'crypto';
|
|
22
|
+
import { z } from 'zod';
|
|
21
23
|
import destr from 'destr';
|
|
22
24
|
import traverse from 'traverse';
|
|
23
25
|
import { McpServer } from '@alcyone-labs/modelcontextprotocol-sdk/server/mcp.js';
|
|
@@ -1615,7 +1617,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1615
1617
|
const summaryValidation = validateAgainstSchema(summaryData, previewSchema);
|
|
1616
1618
|
const fullValidation = validateAgainstSchema(fullData, fullSchema);
|
|
1617
1619
|
if (!summaryValidation.hasRequiredFields) {
|
|
1618
|
-
|
|
1620
|
+
new Error(
|
|
1619
1621
|
`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.`
|
|
1620
1622
|
);
|
|
1621
1623
|
logger5.error(
|
|
@@ -1626,9 +1628,13 @@ var ArtifactService = class _ArtifactService {
|
|
|
1626
1628
|
actualFields: summaryValidation.actualFields,
|
|
1627
1629
|
schemaExpected: previewSchema?.properties ? Object.keys(previewSchema.properties) : []
|
|
1628
1630
|
},
|
|
1629
|
-
"
|
|
1631
|
+
"Artifact creation failed due to missing required fields - continuing with generation"
|
|
1630
1632
|
);
|
|
1631
|
-
|
|
1633
|
+
return {
|
|
1634
|
+
summary: summaryValidation,
|
|
1635
|
+
full: fullValidation,
|
|
1636
|
+
schemaFound: !!previewSchema
|
|
1637
|
+
};
|
|
1632
1638
|
}
|
|
1633
1639
|
if (!summaryValidation.hasExpectedFields || summaryValidation.extraFields.length > 0) {
|
|
1634
1640
|
logger5.warn(
|
|
@@ -1778,7 +1784,7 @@ var ArtifactService = class _ArtifactService {
|
|
|
1778
1784
|
* Used by AgentSession to save artifacts after name/description generation
|
|
1779
1785
|
*/
|
|
1780
1786
|
async saveArtifact(artifact) {
|
|
1781
|
-
let summaryData = artifact.data;
|
|
1787
|
+
let summaryData = artifact.summaryData || artifact.data;
|
|
1782
1788
|
let fullData = artifact.data;
|
|
1783
1789
|
if (this.context.artifactComponents) {
|
|
1784
1790
|
const artifactComponent = this.context.artifactComponents.find(
|
|
@@ -2366,7 +2372,6 @@ var AgentSession = class {
|
|
|
2366
2372
|
* Send data operation to stream when emit operations is enabled
|
|
2367
2373
|
*/
|
|
2368
2374
|
async sendDataOperation(event) {
|
|
2369
|
-
console.log("sendDataOperation called with event", Date.now());
|
|
2370
2375
|
try {
|
|
2371
2376
|
const streamHelper = getStreamHelper(this.sessionId);
|
|
2372
2377
|
if (streamHelper) {
|
|
@@ -2417,6 +2422,8 @@ var AgentSession = class {
|
|
|
2417
2422
|
return `Task completed: ${event.data.targetSubAgent} \u2192 ${event.data.fromSubAgent}`;
|
|
2418
2423
|
case "artifact_saved":
|
|
2419
2424
|
return `Artifact saved: ${event.data.artifactType || "unknown type"}`;
|
|
2425
|
+
case "compression":
|
|
2426
|
+
return `Compressed ${event.data.messageCount} messages and ${event.data.artifactCount} artifacts (${event.data.reason})`;
|
|
2420
2427
|
default:
|
|
2421
2428
|
return `${event.eventType} event`;
|
|
2422
2429
|
}
|
|
@@ -2929,12 +2936,12 @@ ${conversationHistory}
|
|
|
2929
2936
|
Previous updates sent to user:
|
|
2930
2937
|
${previousSummaries.map((s, i) => `${i + 1}. ${s}`).join("\n")}
|
|
2931
2938
|
` : "";
|
|
2932
|
-
const selectionSchema = z.object(
|
|
2939
|
+
const selectionSchema = z$1.object(
|
|
2933
2940
|
Object.fromEntries([
|
|
2934
2941
|
[
|
|
2935
2942
|
"no_relevant_updates",
|
|
2936
|
-
z.object({
|
|
2937
|
-
no_updates: z.boolean().default(true)
|
|
2943
|
+
z$1.object({
|
|
2944
|
+
no_updates: z$1.boolean().default(true)
|
|
2938
2945
|
}).optional().describe(
|
|
2939
2946
|
"Use when nothing substantially new to report. Should only use on its own."
|
|
2940
2947
|
)
|
|
@@ -3068,8 +3075,8 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
3068
3075
|
if (component.detailsSchema && "properties" in component.detailsSchema) {
|
|
3069
3076
|
return this.buildZodSchemaFromJson(component.detailsSchema);
|
|
3070
3077
|
}
|
|
3071
|
-
return z.object({
|
|
3072
|
-
label: z.string().describe(
|
|
3078
|
+
return z$1.object({
|
|
3079
|
+
label: z$1.string().describe(
|
|
3073
3080
|
'A short 3-5 word phrase, that is a descriptive label for the update component. This Label must be EXTREMELY unique to represent the UNIQUE update we are providing. The ACTUAL finding or result, not the action. What specific information was discovered? (e.g., "Slack requires OAuth 2.0 setup", "Found 5 integration methods", "API rate limit is 100/minute"). Include the actual detail or insight, not just that you searched or processed. CRITICAL: Only use facts explicitly found in the activities - NEVER invent names, people, organizations, or details that are not present in the actual tool results.'
|
|
3074
3081
|
)
|
|
3075
3082
|
});
|
|
@@ -3079,56 +3086,56 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
3079
3086
|
*/
|
|
3080
3087
|
buildZodSchemaFromJson(jsonSchema) {
|
|
3081
3088
|
const properties = {};
|
|
3082
|
-
properties.label = z.string().describe(
|
|
3089
|
+
properties.label = z$1.string().describe(
|
|
3083
3090
|
'A short 3-5 word phrase, that is a descriptive label for the update component. This Label must be EXTREMELY unique to represent the UNIQUE update we are providing. The SPECIFIC finding, result, or insight discovered (e.g., "Slack bot needs workspace admin role", "Found ingestion requires 3 steps", "Channel history limited to 10k messages"). State the ACTUAL information found, not that you searched. What did you LEARN or DISCOVER? What specific detail is now known? CRITICAL: Only use facts explicitly found in the activities - NEVER invent names, people, organizations, or details that are not present in the actual tool results.'
|
|
3084
3091
|
);
|
|
3085
3092
|
for (const [key, value] of Object.entries(jsonSchema.properties)) {
|
|
3086
3093
|
let zodType;
|
|
3087
3094
|
if (value.enum && Array.isArray(value.enum)) {
|
|
3088
3095
|
if (value.enum.length === 1) {
|
|
3089
|
-
zodType = z.literal(value.enum[0]);
|
|
3096
|
+
zodType = z$1.literal(value.enum[0]);
|
|
3090
3097
|
} else {
|
|
3091
3098
|
const [first, ...rest] = value.enum;
|
|
3092
|
-
zodType = z.enum([first, ...rest]);
|
|
3099
|
+
zodType = z$1.enum([first, ...rest]);
|
|
3093
3100
|
}
|
|
3094
3101
|
} else if (value.type === "string") {
|
|
3095
|
-
zodType = z.string();
|
|
3102
|
+
zodType = z$1.string();
|
|
3096
3103
|
if (value.minLength) zodType = zodType.min(value.minLength);
|
|
3097
3104
|
if (value.maxLength) zodType = zodType.max(value.maxLength);
|
|
3098
3105
|
if (value.format === "email") zodType = zodType.email();
|
|
3099
3106
|
if (value.format === "url" || value.format === "uri")
|
|
3100
3107
|
zodType = zodType.url();
|
|
3101
3108
|
} else if (value.type === "number" || value.type === "integer") {
|
|
3102
|
-
zodType = value.type === "integer" ? z.number().int() : z.number();
|
|
3109
|
+
zodType = value.type === "integer" ? z$1.number().int() : z$1.number();
|
|
3103
3110
|
if (value.minimum !== void 0) zodType = zodType.min(value.minimum);
|
|
3104
3111
|
if (value.maximum !== void 0) zodType = zodType.max(value.maximum);
|
|
3105
3112
|
} else if (value.type === "boolean") {
|
|
3106
|
-
zodType = z.boolean();
|
|
3113
|
+
zodType = z$1.boolean();
|
|
3107
3114
|
} else if (value.type === "array") {
|
|
3108
3115
|
if (value.items) {
|
|
3109
3116
|
if (value.items.enum && Array.isArray(value.items.enum)) {
|
|
3110
3117
|
const [first, ...rest] = value.items.enum;
|
|
3111
|
-
zodType = z.array(z.enum([first, ...rest]));
|
|
3118
|
+
zodType = z$1.array(z$1.enum([first, ...rest]));
|
|
3112
3119
|
} else if (value.items.type === "string") {
|
|
3113
|
-
zodType = z.array(z.string());
|
|
3120
|
+
zodType = z$1.array(z$1.string());
|
|
3114
3121
|
} else if (value.items.type === "number") {
|
|
3115
|
-
zodType = z.array(z.number());
|
|
3122
|
+
zodType = z$1.array(z$1.number());
|
|
3116
3123
|
} else if (value.items.type === "boolean") {
|
|
3117
|
-
zodType = z.array(z.boolean());
|
|
3124
|
+
zodType = z$1.array(z$1.boolean());
|
|
3118
3125
|
} else if (value.items.type === "object") {
|
|
3119
|
-
zodType = z.array(z.record(z.string(), z.any()));
|
|
3126
|
+
zodType = z$1.array(z$1.record(z$1.string(), z$1.any()));
|
|
3120
3127
|
} else {
|
|
3121
|
-
zodType = z.array(z.any());
|
|
3128
|
+
zodType = z$1.array(z$1.any());
|
|
3122
3129
|
}
|
|
3123
3130
|
} else {
|
|
3124
|
-
zodType = z.array(z.any());
|
|
3131
|
+
zodType = z$1.array(z$1.any());
|
|
3125
3132
|
}
|
|
3126
3133
|
if (value.minItems) zodType = zodType.min(value.minItems);
|
|
3127
3134
|
if (value.maxItems) zodType = zodType.max(value.maxItems);
|
|
3128
3135
|
} else if (value.type === "object") {
|
|
3129
|
-
zodType = z.record(z.string(), z.any());
|
|
3136
|
+
zodType = z$1.record(z$1.string(), z$1.any());
|
|
3130
3137
|
} else {
|
|
3131
|
-
zodType = z.any();
|
|
3138
|
+
zodType = z$1.any();
|
|
3132
3139
|
}
|
|
3133
3140
|
if (value.description) {
|
|
3134
3141
|
zodType = zodType.describe(value.description);
|
|
@@ -3138,7 +3145,7 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
3138
3145
|
}
|
|
3139
3146
|
properties[key] = zodType;
|
|
3140
3147
|
}
|
|
3141
|
-
return z.object(properties);
|
|
3148
|
+
return z$1.object(properties);
|
|
3142
3149
|
}
|
|
3143
3150
|
/**
|
|
3144
3151
|
* Extract user-visible activities with rich formatting and complete information
|
|
@@ -3299,17 +3306,59 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
|
|
|
3299
3306
|
(event) => event.eventType === "tool_result" && event.data && "toolCallId" in event.data && event.data.toolCallId === artifactData.metadata?.toolCallId
|
|
3300
3307
|
);
|
|
3301
3308
|
const toolContext = toolCallEvent ? {
|
|
3302
|
-
toolName: toolCallEvent.data.toolName,
|
|
3303
3309
|
args: toolCallEvent.data.args
|
|
3304
3310
|
} : null;
|
|
3305
|
-
|
|
3311
|
+
let existingNames = [];
|
|
3312
|
+
try {
|
|
3313
|
+
if (artifactData.tenantId && artifactData.projectId && artifactData.taskId) {
|
|
3314
|
+
const existingArtifacts = await getLedgerArtifacts(dbClient_default)({
|
|
3315
|
+
scopes: { tenantId: artifactData.tenantId, projectId: artifactData.projectId },
|
|
3316
|
+
taskId: artifactData.taskId
|
|
3317
|
+
});
|
|
3318
|
+
existingNames = existingArtifacts.map((a) => a.name).filter(Boolean);
|
|
3319
|
+
}
|
|
3320
|
+
} catch (error) {
|
|
3321
|
+
logger7.warn(
|
|
3322
|
+
{
|
|
3323
|
+
sessionId: this.sessionId,
|
|
3324
|
+
artifactId: artifactData.artifactId,
|
|
3325
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
3326
|
+
},
|
|
3327
|
+
"Failed to fetch existing artifact names for context"
|
|
3328
|
+
);
|
|
3329
|
+
}
|
|
3330
|
+
const toolName = artifactData.metadata?.toolName || "unknown";
|
|
3331
|
+
const toolCallId = artifactData.metadata?.toolCallId || "unknown";
|
|
3332
|
+
const prompt = `Create a unique name and description for this tool result artifact.
|
|
3306
3333
|
|
|
3307
|
-
|
|
3308
|
-
Context: ${conversationHistory?.slice(-200) || "Processing"}
|
|
3309
|
-
Type: ${artifactData.artifactType || "data"}
|
|
3310
|
-
Data: ${JSON.stringify(artifactData.data || artifactData.summaryData, null, 2)}
|
|
3334
|
+
CRITICAL: Your name must be different from these existing artifacts: ${existingNames.length > 0 ? existingNames.join(", ") : "None yet"}
|
|
3311
3335
|
|
|
3312
|
-
|
|
3336
|
+
Tool Context: ${toolContext ? JSON.stringify(toolContext.args, null, 2) : "No args"}
|
|
3337
|
+
Context: ${conversationHistory?.slice(-200) || "No context"}
|
|
3338
|
+
Type: ${artifactData.artifactType || "data"}
|
|
3339
|
+
Data: ${JSON.stringify(artifactData.data || artifactData.summaryData || {}, null, 2)}
|
|
3340
|
+
|
|
3341
|
+
Requirements:
|
|
3342
|
+
- Name: Max 50 chars, be extremely specific to THIS EXACT tool execution
|
|
3343
|
+
- Description: Max 150 chars, describe what THIS SPECIFIC tool call returned
|
|
3344
|
+
- Focus on the unique aspects of this particular tool execution result
|
|
3345
|
+
- Be descriptive about the actual content returned, not just the tool type
|
|
3346
|
+
|
|
3347
|
+
BAD Examples (too generic):
|
|
3348
|
+
- "Search Results"
|
|
3349
|
+
- "Tool Results"
|
|
3350
|
+
- "${toolName} Results"
|
|
3351
|
+
- "Data from ${toolName}"
|
|
3352
|
+
- "Tool Output"
|
|
3353
|
+
- "Search Data"
|
|
3354
|
+
|
|
3355
|
+
GOOD Examples:
|
|
3356
|
+
- "GitHub API Rate Limits & Auth Methods"
|
|
3357
|
+
- "React Component Props Documentation"
|
|
3358
|
+
- "Database Schema for User Tables"
|
|
3359
|
+
- "Pricing Tiers with Enterprise Features"
|
|
3360
|
+
|
|
3361
|
+
Make the name extremely specific to what this tool call actually returned, not generic.`;
|
|
3313
3362
|
let modelToUse = this.statusUpdateState?.summarizerModel;
|
|
3314
3363
|
if (!modelToUse?.model?.trim()) {
|
|
3315
3364
|
if (!this.statusUpdateState?.baseModel?.model?.trim()) {
|
|
@@ -3363,15 +3412,16 @@ Make it specific and relevant.`;
|
|
|
3363
3412
|
}
|
|
3364
3413
|
let result;
|
|
3365
3414
|
if (!modelToUse) {
|
|
3415
|
+
const toolCallSuffix = artifactData.metadata?.toolCallId?.slice(-8) || Date.now().toString().slice(-8);
|
|
3366
3416
|
result = {
|
|
3367
|
-
name:
|
|
3368
|
-
description: `${artifactData.artifactType || "Data"} from ${artifactData.metadata?.toolCallId || "tool results"}`
|
|
3417
|
+
name: `${artifactData.artifactType || "Artifact"} ${toolCallSuffix}`,
|
|
3418
|
+
description: `${artifactData.artifactType || "Data"} from ${artifactData.metadata?.toolName || "tool"} (${artifactData.metadata?.toolCallId || "tool results"})`
|
|
3369
3419
|
};
|
|
3370
3420
|
} else {
|
|
3371
3421
|
const model = ModelFactory.createModel(modelToUse);
|
|
3372
|
-
const schema = z.object({
|
|
3373
|
-
name: z.string().describe("Concise, descriptive name for the artifact"),
|
|
3374
|
-
description: z.string().describe("Brief description of the artifact's relevance to the user's question")
|
|
3422
|
+
const schema = z$1.object({
|
|
3423
|
+
name: z$1.string().describe("Concise, descriptive name for the artifact"),
|
|
3424
|
+
description: z$1.string().describe("Brief description of the artifact's relevance to the user's question")
|
|
3375
3425
|
});
|
|
3376
3426
|
const { object } = await tracer.startActiveSpan(
|
|
3377
3427
|
"agent_session.generate_artifact_metadata",
|
|
@@ -3460,6 +3510,21 @@ Make it specific and relevant.`;
|
|
|
3460
3510
|
);
|
|
3461
3511
|
result = object;
|
|
3462
3512
|
}
|
|
3513
|
+
if (existingNames.includes(result.name)) {
|
|
3514
|
+
const toolCallSuffix = toolCallId.slice(-8);
|
|
3515
|
+
const originalName = result.name;
|
|
3516
|
+
result.name = result.name.length + toolCallSuffix.length + 1 <= 50 ? `${result.name} ${toolCallSuffix}` : `${result.name.substring(0, 50 - toolCallSuffix.length - 1)} ${toolCallSuffix}`;
|
|
3517
|
+
logger7.info(
|
|
3518
|
+
{
|
|
3519
|
+
sessionId: this.sessionId,
|
|
3520
|
+
artifactId: artifactData.artifactId,
|
|
3521
|
+
originalName,
|
|
3522
|
+
uniqueName: result.name,
|
|
3523
|
+
reason: "Name conflict resolved with toolCallId suffix"
|
|
3524
|
+
},
|
|
3525
|
+
"Updated artifact name for uniqueness"
|
|
3526
|
+
);
|
|
3527
|
+
}
|
|
3463
3528
|
try {
|
|
3464
3529
|
if (!this.artifactService) {
|
|
3465
3530
|
throw new Error("ArtifactService is not initialized");
|
|
@@ -3470,6 +3535,7 @@ Make it specific and relevant.`;
|
|
|
3470
3535
|
description: result.description,
|
|
3471
3536
|
type: artifactData.artifactType || "source",
|
|
3472
3537
|
data: artifactData.data || {},
|
|
3538
|
+
summaryData: artifactData.summaryData,
|
|
3473
3539
|
metadata: artifactData.metadata || {},
|
|
3474
3540
|
toolCallId: artifactData.toolCallId
|
|
3475
3541
|
});
|
|
@@ -3485,7 +3551,13 @@ Make it specific and relevant.`;
|
|
|
3485
3551
|
{
|
|
3486
3552
|
sessionId: this.sessionId,
|
|
3487
3553
|
artifactId: artifactData.artifactId,
|
|
3488
|
-
error: saveError instanceof Error ? saveError.message : "Unknown error"
|
|
3554
|
+
error: saveError instanceof Error ? saveError.message : "Unknown error",
|
|
3555
|
+
errorName: saveError instanceof Error ? saveError.name : void 0,
|
|
3556
|
+
errorCause: saveError instanceof Error ? saveError.cause : void 0,
|
|
3557
|
+
errorCode: saveError?.code || saveError?.errno || void 0,
|
|
3558
|
+
artifactType: artifactData.artifactType,
|
|
3559
|
+
dataKeys: artifactData.data ? Object.keys(artifactData.data) : [],
|
|
3560
|
+
metadataKeys: artifactData.metadata ? Object.keys(artifactData.metadata) : []
|
|
3489
3561
|
},
|
|
3490
3562
|
"Main artifact save failed, will attempt fallback"
|
|
3491
3563
|
);
|
|
@@ -3506,6 +3578,7 @@ Make it specific and relevant.`;
|
|
|
3506
3578
|
description: `${artifactData.artifactType || "Data"} from ${artifactData.metadata?.toolName || "tool results"}`,
|
|
3507
3579
|
type: artifactData.artifactType || "source",
|
|
3508
3580
|
data: artifactData.data || {},
|
|
3581
|
+
summaryData: artifactData.summaryData,
|
|
3509
3582
|
metadata: artifactData.metadata || {},
|
|
3510
3583
|
toolCallId: artifactData.toolCallId
|
|
3511
3584
|
});
|
|
@@ -3524,7 +3597,13 @@ Make it specific and relevant.`;
|
|
|
3524
3597
|
{
|
|
3525
3598
|
sessionId: this.sessionId,
|
|
3526
3599
|
artifactId: artifactData.artifactId,
|
|
3527
|
-
error: fallbackError instanceof Error ? fallbackError.message : "Unknown error"
|
|
3600
|
+
error: fallbackError instanceof Error ? fallbackError.message : "Unknown error",
|
|
3601
|
+
errorName: fallbackError instanceof Error ? fallbackError.name : void 0,
|
|
3602
|
+
errorCause: fallbackError instanceof Error ? fallbackError.cause : void 0,
|
|
3603
|
+
errorCode: fallbackError?.code || fallbackError?.errno || void 0,
|
|
3604
|
+
artifactType: artifactData.artifactType,
|
|
3605
|
+
dataKeys: artifactData.data ? Object.keys(artifactData.data) : [],
|
|
3606
|
+
metadataKeys: artifactData.metadata ? Object.keys(artifactData.metadata) : []
|
|
3528
3607
|
},
|
|
3529
3608
|
"Failed to save artifact even with fallback"
|
|
3530
3609
|
);
|
|
@@ -4158,9 +4237,654 @@ ${chunk}`;
|
|
|
4158
4237
|
}
|
|
4159
4238
|
}
|
|
4160
4239
|
};
|
|
4240
|
+
var logger9 = getLogger("distill-conversation-tool");
|
|
4241
|
+
var ConversationSummarySchema = z.object({
|
|
4242
|
+
type: z.literal("conversation_summary_v1"),
|
|
4243
|
+
session_id: z.string().nullable().optional(),
|
|
4244
|
+
high_level: z.string().describe("1-3 sentences capturing what was discovered and learned"),
|
|
4245
|
+
user_intent: z.string().describe("Current main goal or what the user wants to accomplish"),
|
|
4246
|
+
decisions: z.array(z.string()).describe("Concrete decisions made about approach or implementation (\u22645 items)"),
|
|
4247
|
+
open_questions: z.array(z.string()).describe("Unresolved questions about the subject matter (\u22645 items)"),
|
|
4248
|
+
next_steps: z.object({
|
|
4249
|
+
for_agent: z.array(z.string()).describe(
|
|
4250
|
+
"Content-focused actions: what to discover, analyze, or present. Don't get trapped in an infinite loop of tool calls. You have already done a lot of work that is why you are being compressed. Don't encourage too much more work."
|
|
4251
|
+
),
|
|
4252
|
+
for_user: z.array(z.string()).describe("Actions for user based on discovered content")
|
|
4253
|
+
}),
|
|
4254
|
+
related_artifacts: z.array(
|
|
4255
|
+
z.object({
|
|
4256
|
+
id: z.string().describe("Artifact ID"),
|
|
4257
|
+
name: z.string().describe("Human-readable name describing the content"),
|
|
4258
|
+
tool_name: z.string().describe("Tool that generated this artifact (e.g. search-inkeep-docs)"),
|
|
4259
|
+
tool_call_id: z.string().describe("Specific tool call ID for precise referencing"),
|
|
4260
|
+
content_type: z.string().describe("Type of content (e.g. search_results, api_response, documentation)"),
|
|
4261
|
+
key_findings: z.array(z.string()).describe("2-3 most important findings from this specific artifact")
|
|
4262
|
+
})
|
|
4263
|
+
).optional().describe("Artifacts containing detailed findings with citation info")
|
|
4264
|
+
});
|
|
4265
|
+
async function distillConversation(params) {
|
|
4266
|
+
const { messages, conversationId, currentSummary, summarizerModel, toolCallToArtifactMap } = params;
|
|
4267
|
+
try {
|
|
4268
|
+
const modelToUse = summarizerModel;
|
|
4269
|
+
if (!modelToUse?.model?.trim()) {
|
|
4270
|
+
throw new Error("Summarizer model is required");
|
|
4271
|
+
}
|
|
4272
|
+
const model = ModelFactory.createModel(modelToUse);
|
|
4273
|
+
const existingSummaryContext = currentSummary ? `**Current summary:**
|
|
4274
|
+
|
|
4275
|
+
\`\`\`json
|
|
4276
|
+
${JSON.stringify(currentSummary, null, 2)}
|
|
4277
|
+
\`\`\`` : "**Current summary:** None (first distillation)";
|
|
4278
|
+
const formattedMessages = messages.map((msg) => {
|
|
4279
|
+
const parts = [];
|
|
4280
|
+
if (typeof msg.content === "string") {
|
|
4281
|
+
parts.push(msg.content);
|
|
4282
|
+
} else if (Array.isArray(msg.content)) {
|
|
4283
|
+
for (const block of msg.content) {
|
|
4284
|
+
if (block.type === "text") {
|
|
4285
|
+
parts.push(block.text);
|
|
4286
|
+
} else if (block.type === "tool-call") {
|
|
4287
|
+
parts.push(
|
|
4288
|
+
`[TOOL CALL] ${block.toolName}(${JSON.stringify(block.input)}) [ID: ${block.toolCallId}]`
|
|
4289
|
+
);
|
|
4290
|
+
} else if (block.type === "tool-result") {
|
|
4291
|
+
const artifactId = toolCallToArtifactMap?.[block.toolCallId];
|
|
4292
|
+
const artifactInfo = artifactId ? `
|
|
4293
|
+
[ARTIFACT CREATED: ${artifactId}]` : "";
|
|
4294
|
+
parts.push(
|
|
4295
|
+
`[TOOL RESULT] ${block.toolName} [ID: ${block.toolCallId}]${artifactInfo}
|
|
4296
|
+
Result: ${JSON.stringify(block.result)}`
|
|
4297
|
+
);
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
} else if (msg.content?.text) {
|
|
4301
|
+
parts.push(msg.content.text);
|
|
4302
|
+
}
|
|
4303
|
+
return parts.length > 0 ? `${msg.role || "system"}: ${parts.join("\n")}` : "";
|
|
4304
|
+
}).filter((line) => line.trim().length > 0).join("\n\n");
|
|
4305
|
+
logger9.debug(
|
|
4306
|
+
{
|
|
4307
|
+
conversationId,
|
|
4308
|
+
messageCount: messages.length,
|
|
4309
|
+
formattedLength: formattedMessages.length,
|
|
4310
|
+
sampleMessages: messages.slice(0, 2).map((m) => ({ role: m.role, contentType: typeof m.content, hasContent: !!m.content }))
|
|
4311
|
+
},
|
|
4312
|
+
"Formatting messages for distillation"
|
|
4313
|
+
);
|
|
4314
|
+
const prompt = `You are a conversation summarization assistant. Your job is to create or update a compact, structured summary that captures VALUABLE CONTENT and FINDINGS, not just operational details.
|
|
4315
|
+
|
|
4316
|
+
${existingSummaryContext}
|
|
4317
|
+
|
|
4318
|
+
**Messages to summarize:**
|
|
4319
|
+
|
|
4320
|
+
\`\`\`text
|
|
4321
|
+
${formattedMessages}
|
|
4322
|
+
\`\`\`
|
|
4323
|
+
|
|
4324
|
+
Create/update a summary using this exact JSON schema:
|
|
4325
|
+
|
|
4326
|
+
\`\`\`json
|
|
4327
|
+
{
|
|
4328
|
+
"type": "conversation_summary_v1",
|
|
4329
|
+
"session_id": "<conversationId>",
|
|
4330
|
+
"high_level": "<1\u20133 sentences capturing what was discovered and learned>",
|
|
4331
|
+
"user_intent": "<current main goal>",
|
|
4332
|
+
"decisions": ["<concrete decisions made>"],
|
|
4333
|
+
"open_questions": ["<unresolved issues>"],
|
|
4334
|
+
"next_steps": {
|
|
4335
|
+
"for_agent": ["<what agent should do>"],
|
|
4336
|
+
"for_user": ["<what user should do>"]
|
|
4337
|
+
},
|
|
4338
|
+
"related_artifacts": [
|
|
4339
|
+
{
|
|
4340
|
+
"id": "<artifact_id>",
|
|
4341
|
+
"name": "<descriptive name>",
|
|
4342
|
+
"tool_name": "<tool_name>",
|
|
4343
|
+
"tool_call_id": "<tool_call_id>",
|
|
4344
|
+
"content_type": "<search_results|api_response|documentation>",
|
|
4345
|
+
"key_findings": ["<important finding 1>", "<important finding 2>"]
|
|
4346
|
+
}
|
|
4347
|
+
]
|
|
4348
|
+
}
|
|
4349
|
+
\`\`\`
|
|
4350
|
+
|
|
4351
|
+
**CRITICAL RULES - FOCUS ON CONTENT NOT OPERATIONS:**
|
|
4352
|
+
\u{1F3AF} **EXTRACT VALUABLE FINDINGS**: Capture the actual information discovered, data retrieved, insights gained
|
|
4353
|
+
\u{1F3AF} **IGNORE OPERATIONAL DETAILS**: Don't mention "tool was used", "artifact was created", "messages were compressed"
|
|
4354
|
+
\u{1F3AF} **PRESERVE SUBSTANCE**: Include specific facts, features, capabilities, configurations, results found
|
|
4355
|
+
\u{1F3AF} **BUILD KNOWLEDGE**: When updating existing summary, ADD new discoveries to existing knowledge
|
|
4356
|
+
\u{1F3AF} **BE CONCRETE**: Use specific details from tool results, not generic descriptions
|
|
4357
|
+
\u{1F3AF} **BE CONCISE**: Keep ALL fields brief - you are compressing to save context, not writing a report
|
|
4358
|
+
\u{1F3AF} **LIMIT NEXT STEPS**: Agent has already done substantial work - suggest minimal follow-up actions only
|
|
4359
|
+
|
|
4360
|
+
**Examples:**
|
|
4361
|
+
\u274C BAD: "Assistant used search tool and created artifacts"
|
|
4362
|
+
\u2705 GOOD: "Inkeep supports streaming structured objects, OpenAI-compatible APIs, analytics logging, and Zendesk integration"
|
|
4363
|
+
|
|
4364
|
+
\u274C BAD: "Tool calls were made to gather information"
|
|
4365
|
+
\u2705 GOOD: "Platform includes 10 feature categories: chat widgets, knowledge base, analytics, integrations, theming options"
|
|
4366
|
+
|
|
4367
|
+
**Focus on WHAT WAS LEARNED, not HOW IT WAS LEARNED**
|
|
4368
|
+
|
|
4369
|
+
Return **only** valid JSON.`;
|
|
4370
|
+
const { object: summary } = await generateObject({
|
|
4371
|
+
model,
|
|
4372
|
+
prompt,
|
|
4373
|
+
schema: ConversationSummarySchema
|
|
4374
|
+
});
|
|
4375
|
+
summary.session_id = conversationId;
|
|
4376
|
+
logger9.info(
|
|
4377
|
+
{
|
|
4378
|
+
conversationId,
|
|
4379
|
+
messageCount: messages.length,
|
|
4380
|
+
artifactsCount: summary.related_artifacts?.length || 0,
|
|
4381
|
+
decisionsCount: summary.decisions.length
|
|
4382
|
+
},
|
|
4383
|
+
"Successfully distilled conversation"
|
|
4384
|
+
);
|
|
4385
|
+
return summary;
|
|
4386
|
+
} catch (error) {
|
|
4387
|
+
logger9.error(
|
|
4388
|
+
{
|
|
4389
|
+
conversationId,
|
|
4390
|
+
messageCount: messages.length,
|
|
4391
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
4392
|
+
},
|
|
4393
|
+
"Failed to distill conversation"
|
|
4394
|
+
);
|
|
4395
|
+
return {
|
|
4396
|
+
type: "conversation_summary_v1",
|
|
4397
|
+
session_id: conversationId,
|
|
4398
|
+
high_level: "Ongoing conversation session",
|
|
4399
|
+
user_intent: "Continue working on current task",
|
|
4400
|
+
related_artifacts: [],
|
|
4401
|
+
decisions: [],
|
|
4402
|
+
open_questions: ["Review recent work and determine next steps"],
|
|
4403
|
+
next_steps: {
|
|
4404
|
+
for_agent: ["Continue with current task"],
|
|
4405
|
+
for_user: ["Provide additional guidance if needed"]
|
|
4406
|
+
}
|
|
4407
|
+
};
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
|
|
4411
|
+
// src/services/MidGenerationCompressor.ts
|
|
4412
|
+
var logger10 = getLogger("MidGenerationCompressor");
|
|
4413
|
+
function getCompressionConfigFromEnv() {
|
|
4414
|
+
return {
|
|
4415
|
+
hardLimit: parseInt(process.env.AGENTS_COMPRESSION_HARD_LIMIT || "120000"),
|
|
4416
|
+
safetyBuffer: parseInt(process.env.AGENTS_COMPRESSION_SAFETY_BUFFER || "20000"),
|
|
4417
|
+
enabled: process.env.AGENTS_COMPRESSION_ENABLED !== "false"
|
|
4418
|
+
// Default enabled
|
|
4419
|
+
};
|
|
4420
|
+
}
|
|
4421
|
+
var MidGenerationCompressor = class {
|
|
4422
|
+
// Track cumulative summary across compression cycles
|
|
4423
|
+
constructor(sessionId, conversationId, tenantId, projectId, config, summarizerModel, baseModel) {
|
|
4424
|
+
this.sessionId = sessionId;
|
|
4425
|
+
this.conversationId = conversationId;
|
|
4426
|
+
this.tenantId = tenantId;
|
|
4427
|
+
this.projectId = projectId;
|
|
4428
|
+
this.config = config;
|
|
4429
|
+
this.summarizerModel = summarizerModel;
|
|
4430
|
+
this.baseModel = baseModel;
|
|
4431
|
+
}
|
|
4432
|
+
shouldCompress = false;
|
|
4433
|
+
processedToolCalls = /* @__PURE__ */ new Set();
|
|
4434
|
+
// Track already compressed tool call IDs
|
|
4435
|
+
lastProcessedMessageIndex = 0;
|
|
4436
|
+
// Track where we left off in message processing
|
|
4437
|
+
cumulativeSummary = null;
|
|
4438
|
+
/**
|
|
4439
|
+
* Get the hard limit for compression decisions
|
|
4440
|
+
*/
|
|
4441
|
+
getHardLimit() {
|
|
4442
|
+
return this.config.hardLimit;
|
|
4443
|
+
}
|
|
4444
|
+
/**
|
|
4445
|
+
* Estimate tokens (4 chars = 1 token)
|
|
4446
|
+
*/
|
|
4447
|
+
estimateTokens(content) {
|
|
4448
|
+
const text = typeof content === "string" ? content : JSON.stringify(content);
|
|
4449
|
+
return Math.ceil(text.length / 4);
|
|
4450
|
+
}
|
|
4451
|
+
/**
|
|
4452
|
+
* Calculate total context size
|
|
4453
|
+
*/
|
|
4454
|
+
calculateContextSize(messages) {
|
|
4455
|
+
const messageTokens = messages.reduce((total, msg) => {
|
|
4456
|
+
let msgTokens = 0;
|
|
4457
|
+
if (Array.isArray(msg.content)) {
|
|
4458
|
+
for (const block of msg.content) {
|
|
4459
|
+
if (block.type === "text") {
|
|
4460
|
+
msgTokens += this.estimateTokens(block.text || "");
|
|
4461
|
+
} else if (block.type === "tool-call") {
|
|
4462
|
+
msgTokens += this.estimateTokens(
|
|
4463
|
+
JSON.stringify({
|
|
4464
|
+
toolCallId: block.toolCallId,
|
|
4465
|
+
toolName: block.toolName,
|
|
4466
|
+
input: block.input
|
|
4467
|
+
})
|
|
4468
|
+
);
|
|
4469
|
+
} else if (block.type === "tool-result") {
|
|
4470
|
+
msgTokens += this.estimateTokens(
|
|
4471
|
+
JSON.stringify({
|
|
4472
|
+
toolCallId: block.toolCallId,
|
|
4473
|
+
toolName: block.toolName,
|
|
4474
|
+
output: block.output
|
|
4475
|
+
})
|
|
4476
|
+
);
|
|
4477
|
+
}
|
|
4478
|
+
}
|
|
4479
|
+
} else if (typeof msg.content === "string") {
|
|
4480
|
+
msgTokens += this.estimateTokens(msg.content);
|
|
4481
|
+
} else if (msg.content) {
|
|
4482
|
+
msgTokens += this.estimateTokens(JSON.stringify(msg.content));
|
|
4483
|
+
}
|
|
4484
|
+
return total + msgTokens;
|
|
4485
|
+
}, 0);
|
|
4486
|
+
return messageTokens;
|
|
4487
|
+
}
|
|
4488
|
+
/**
|
|
4489
|
+
* Manual compression request from LLM tool
|
|
4490
|
+
*/
|
|
4491
|
+
requestManualCompression(reason) {
|
|
4492
|
+
this.shouldCompress = true;
|
|
4493
|
+
logger10.info(
|
|
4494
|
+
{
|
|
4495
|
+
sessionId: this.sessionId,
|
|
4496
|
+
reason: reason || "Manual request from LLM"
|
|
4497
|
+
},
|
|
4498
|
+
"Manual compression requested"
|
|
4499
|
+
);
|
|
4500
|
+
}
|
|
4501
|
+
/**
|
|
4502
|
+
* Check if compression is needed (either automatic or manual)
|
|
4503
|
+
*/
|
|
4504
|
+
isCompressionNeeded(messages) {
|
|
4505
|
+
if (this.shouldCompress) return true;
|
|
4506
|
+
const contextSize = this.calculateContextSize(messages);
|
|
4507
|
+
const remaining = this.config.hardLimit - contextSize;
|
|
4508
|
+
return remaining <= this.config.safetyBuffer;
|
|
4509
|
+
}
|
|
4510
|
+
/**
|
|
4511
|
+
* Perform compression: save all tool results as artifacts and create summary
|
|
4512
|
+
*/
|
|
4513
|
+
async compress(messages) {
|
|
4514
|
+
const contextSizeBefore = this.calculateContextSize(messages);
|
|
4515
|
+
logger10.info(
|
|
4516
|
+
{
|
|
4517
|
+
sessionId: this.sessionId,
|
|
4518
|
+
messageCount: messages.length,
|
|
4519
|
+
contextSize: contextSizeBefore
|
|
4520
|
+
},
|
|
4521
|
+
"COMPRESSION: Starting compression"
|
|
4522
|
+
);
|
|
4523
|
+
const toolResultCount = messages.reduce((count, msg) => {
|
|
4524
|
+
if (Array.isArray(msg.content)) {
|
|
4525
|
+
return count + msg.content.filter((block) => block.type === "tool-result").length;
|
|
4526
|
+
}
|
|
4527
|
+
return count;
|
|
4528
|
+
}, 0);
|
|
4529
|
+
logger10.debug({ toolResultCount }, "Tool results found for compression");
|
|
4530
|
+
const toolCallToArtifactMap = await this.saveToolResultsAsArtifacts(messages);
|
|
4531
|
+
const summary = await this.createConversationSummary(messages, toolCallToArtifactMap);
|
|
4532
|
+
const contextSizeAfter = this.estimateTokens(JSON.stringify(summary));
|
|
4533
|
+
const session = agentSessionManager.getSession(this.sessionId);
|
|
4534
|
+
if (session) {
|
|
4535
|
+
const wasManualRequest = this.shouldCompress;
|
|
4536
|
+
session.recordEvent("compression", this.sessionId, {
|
|
4537
|
+
reason: wasManualRequest ? "manual" : "automatic",
|
|
4538
|
+
messageCount: messages.length,
|
|
4539
|
+
artifactCount: Object.keys(toolCallToArtifactMap).length,
|
|
4540
|
+
contextSizeBefore,
|
|
4541
|
+
contextSizeAfter,
|
|
4542
|
+
compressionType: "mid_generation"
|
|
4543
|
+
});
|
|
4544
|
+
}
|
|
4545
|
+
this.shouldCompress = false;
|
|
4546
|
+
logger10.info(
|
|
4547
|
+
{
|
|
4548
|
+
sessionId: this.sessionId,
|
|
4549
|
+
artifactsCreated: Object.keys(toolCallToArtifactMap).length,
|
|
4550
|
+
messageCount: messages.length,
|
|
4551
|
+
contextSizeBefore,
|
|
4552
|
+
contextSizeAfter,
|
|
4553
|
+
artifactIds: Object.values(toolCallToArtifactMap)
|
|
4554
|
+
},
|
|
4555
|
+
"COMPRESSION: Compression completed successfully"
|
|
4556
|
+
);
|
|
4557
|
+
return { artifactIds: Object.values(toolCallToArtifactMap), summary };
|
|
4558
|
+
}
|
|
4559
|
+
/**
|
|
4560
|
+
* 1. Save NEW tool results as artifacts (only process messages since last compression)
|
|
4561
|
+
*/
|
|
4562
|
+
async saveToolResultsAsArtifacts(messages) {
|
|
4563
|
+
const session = agentSessionManager.getSession(this.sessionId);
|
|
4564
|
+
if (!session) {
|
|
4565
|
+
throw new Error(`No session found: ${this.sessionId}`);
|
|
4566
|
+
}
|
|
4567
|
+
const toolCallToArtifactMap = {};
|
|
4568
|
+
const newMessages = messages.slice(this.lastProcessedMessageIndex);
|
|
4569
|
+
logger10.debug(
|
|
4570
|
+
{
|
|
4571
|
+
totalMessages: messages.length,
|
|
4572
|
+
newMessages: newMessages.length,
|
|
4573
|
+
startIndex: this.lastProcessedMessageIndex
|
|
4574
|
+
},
|
|
4575
|
+
"Starting compression artifact processing"
|
|
4576
|
+
);
|
|
4577
|
+
for (const message of newMessages) {
|
|
4578
|
+
if (Array.isArray(message.content)) {
|
|
4579
|
+
for (const block of message.content) {
|
|
4580
|
+
if (block.type === "tool-result") {
|
|
4581
|
+
if (block.toolName === "get_reference_artifact" || block.toolName === "thinking_complete") {
|
|
4582
|
+
logger10.debug(
|
|
4583
|
+
{
|
|
4584
|
+
toolCallId: block.toolCallId,
|
|
4585
|
+
toolName: block.toolName
|
|
4586
|
+
},
|
|
4587
|
+
"Skipping special tool - not creating artifacts"
|
|
4588
|
+
);
|
|
4589
|
+
this.processedToolCalls.add(block.toolCallId);
|
|
4590
|
+
continue;
|
|
4591
|
+
}
|
|
4592
|
+
if (this.processedToolCalls.has(block.toolCallId)) {
|
|
4593
|
+
logger10.debug(
|
|
4594
|
+
{
|
|
4595
|
+
toolCallId: block.toolCallId,
|
|
4596
|
+
toolName: block.toolName
|
|
4597
|
+
},
|
|
4598
|
+
"Skipping already processed tool call"
|
|
4599
|
+
);
|
|
4600
|
+
continue;
|
|
4601
|
+
}
|
|
4602
|
+
const artifactId = `compress_${block.toolName || "tool"}_${block.toolCallId || Date.now()}_${randomUUID().slice(0, 8)}`;
|
|
4603
|
+
logger10.debug(
|
|
4604
|
+
{
|
|
4605
|
+
artifactId,
|
|
4606
|
+
toolName: block.toolName,
|
|
4607
|
+
toolCallId: block.toolCallId
|
|
4608
|
+
},
|
|
4609
|
+
"Saving compression artifact"
|
|
4610
|
+
);
|
|
4611
|
+
let toolInput = null;
|
|
4612
|
+
if (Array.isArray(message.content)) {
|
|
4613
|
+
const toolCall = message.content.find(
|
|
4614
|
+
(b) => b.type === "tool-call" && b.toolCallId === block.toolCallId
|
|
4615
|
+
);
|
|
4616
|
+
toolInput = toolCall?.input;
|
|
4617
|
+
}
|
|
4618
|
+
const cleanToolResult = this.removeStructureHints(block.output);
|
|
4619
|
+
const toolResultData = {
|
|
4620
|
+
toolName: block.toolName,
|
|
4621
|
+
toolInput,
|
|
4622
|
+
toolResult: cleanToolResult,
|
|
4623
|
+
compressedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4624
|
+
};
|
|
4625
|
+
if (this.isEmpty(toolResultData)) {
|
|
4626
|
+
logger10.debug(
|
|
4627
|
+
{
|
|
4628
|
+
toolName: block.toolName,
|
|
4629
|
+
toolCallId: block.toolCallId
|
|
4630
|
+
},
|
|
4631
|
+
"Skipping empty tool result"
|
|
4632
|
+
);
|
|
4633
|
+
continue;
|
|
4634
|
+
}
|
|
4635
|
+
const artifactData = {
|
|
4636
|
+
artifactId,
|
|
4637
|
+
taskId: `task_${this.conversationId}-${this.sessionId}`,
|
|
4638
|
+
toolCallId: block.toolCallId,
|
|
4639
|
+
artifactType: "tool_result",
|
|
4640
|
+
pendingGeneration: true,
|
|
4641
|
+
// Triggers LLM-generated name/description
|
|
4642
|
+
tenantId: this.tenantId,
|
|
4643
|
+
projectId: this.projectId,
|
|
4644
|
+
contextId: this.conversationId,
|
|
4645
|
+
subAgentId: this.sessionId,
|
|
4646
|
+
metadata: {
|
|
4647
|
+
toolCallId: block.toolCallId,
|
|
4648
|
+
toolName: block.toolName,
|
|
4649
|
+
compressionReason: "mid_generation_context_limit"
|
|
4650
|
+
},
|
|
4651
|
+
// Pass data in the format expected by ArtifactSavedData interface
|
|
4652
|
+
summaryData: {
|
|
4653
|
+
toolName: block.toolName,
|
|
4654
|
+
note: "Compressed tool result - see full data for details"
|
|
4655
|
+
},
|
|
4656
|
+
data: toolResultData
|
|
4657
|
+
// Full tool result data
|
|
4658
|
+
};
|
|
4659
|
+
const fullData = artifactData.data;
|
|
4660
|
+
const hasFullData = fullData && typeof fullData === "object" && Object.keys(fullData).length > 0 && // Check if toolResult specifically has content
|
|
4661
|
+
fullData.toolResult && (typeof fullData.toolResult !== "object" || Object.keys(fullData.toolResult).length > 0);
|
|
4662
|
+
if (!hasFullData) {
|
|
4663
|
+
logger10.debug(
|
|
4664
|
+
{
|
|
4665
|
+
artifactId,
|
|
4666
|
+
toolName: block.toolName,
|
|
4667
|
+
toolCallId: block.toolCallId
|
|
4668
|
+
},
|
|
4669
|
+
"Skipping empty compression artifact"
|
|
4670
|
+
);
|
|
4671
|
+
continue;
|
|
4672
|
+
}
|
|
4673
|
+
session.recordEvent("artifact_saved", this.sessionId, artifactData);
|
|
4674
|
+
this.processedToolCalls.add(block.toolCallId);
|
|
4675
|
+
toolCallToArtifactMap[block.toolCallId] = artifactId;
|
|
4676
|
+
}
|
|
4677
|
+
}
|
|
4678
|
+
}
|
|
4679
|
+
}
|
|
4680
|
+
this.lastProcessedMessageIndex = messages.length;
|
|
4681
|
+
logger10.debug(
|
|
4682
|
+
{
|
|
4683
|
+
totalArtifactsCreated: Object.keys(toolCallToArtifactMap).length,
|
|
4684
|
+
newMessageIndex: this.lastProcessedMessageIndex
|
|
4685
|
+
},
|
|
4686
|
+
"Compression artifact processing completed"
|
|
4687
|
+
);
|
|
4688
|
+
return toolCallToArtifactMap;
|
|
4689
|
+
}
|
|
4690
|
+
/**
|
|
4691
|
+
* 3. Create conversation summary with artifact references
|
|
4692
|
+
*/
|
|
4693
|
+
async createConversationSummary(messages, toolCallToArtifactMap) {
|
|
4694
|
+
const textMessages = this.extractTextMessages(messages, toolCallToArtifactMap);
|
|
4695
|
+
logger10.debug(
|
|
4696
|
+
{
|
|
4697
|
+
sessionId: this.sessionId,
|
|
4698
|
+
messageCount: messages.length,
|
|
4699
|
+
textMessageCount: textMessages.length,
|
|
4700
|
+
artifactCount: Object.keys(toolCallToArtifactMap).length,
|
|
4701
|
+
sampleMessages: messages.slice(0, 2).map((m) => ({
|
|
4702
|
+
role: m.role,
|
|
4703
|
+
contentType: typeof m.content,
|
|
4704
|
+
contentPreview: typeof m.content === "string" ? m.content.substring(0, 100) : "array/object"
|
|
4705
|
+
}))
|
|
4706
|
+
},
|
|
4707
|
+
"Starting distillation with debug info"
|
|
4708
|
+
);
|
|
4709
|
+
const summary = await distillConversation({
|
|
4710
|
+
messages,
|
|
4711
|
+
conversationId: this.conversationId,
|
|
4712
|
+
currentSummary: this.cumulativeSummary,
|
|
4713
|
+
// Pass existing summary for cumulative building
|
|
4714
|
+
summarizerModel: this.summarizerModel,
|
|
4715
|
+
toolCallToArtifactMap
|
|
4716
|
+
// Pass mapping for message formatting
|
|
4717
|
+
});
|
|
4718
|
+
this.cumulativeSummary = summary;
|
|
4719
|
+
logger10.debug(
|
|
4720
|
+
{
|
|
4721
|
+
sessionId: this.sessionId,
|
|
4722
|
+
summaryGenerated: !!summary,
|
|
4723
|
+
summaryHighLevel: summary?.high_level,
|
|
4724
|
+
artifactsCount: summary?.related_artifacts?.length || 0
|
|
4725
|
+
},
|
|
4726
|
+
"Distillation completed"
|
|
4727
|
+
);
|
|
4728
|
+
return {
|
|
4729
|
+
text_messages: textMessages,
|
|
4730
|
+
summary
|
|
4731
|
+
};
|
|
4732
|
+
}
|
|
4733
|
+
/**
|
|
4734
|
+
* Extract text messages and convert tool calls to descriptive text
|
|
4735
|
+
* Avoids API tool-call/tool-result pairing issues while preserving context
|
|
4736
|
+
*/
|
|
4737
|
+
extractTextMessages(messages, toolCallToArtifactMap) {
|
|
4738
|
+
const textMessages = [];
|
|
4739
|
+
const toolCallPairs = /* @__PURE__ */ new Map();
|
|
4740
|
+
for (const message of messages) {
|
|
4741
|
+
if (Array.isArray(message.content)) {
|
|
4742
|
+
for (const block of message.content) {
|
|
4743
|
+
if (block.type === "tool-call") {
|
|
4744
|
+
if (!toolCallPairs.has(block.toolCallId)) {
|
|
4745
|
+
toolCallPairs.set(block.toolCallId, { call: block, result: null });
|
|
4746
|
+
} else {
|
|
4747
|
+
toolCallPairs.get(block.toolCallId).call = block;
|
|
4748
|
+
}
|
|
4749
|
+
} else if (block.type === "tool-result") {
|
|
4750
|
+
if (!toolCallPairs.has(block.toolCallId)) {
|
|
4751
|
+
toolCallPairs.set(block.toolCallId, { call: null, result: block });
|
|
4752
|
+
} else {
|
|
4753
|
+
toolCallPairs.get(block.toolCallId).result = block;
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4756
|
+
}
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
4759
|
+
for (const message of messages) {
|
|
4760
|
+
if (message.role === "assistant" && typeof message.content === "string") {
|
|
4761
|
+
textMessages.push({
|
|
4762
|
+
role: message.role,
|
|
4763
|
+
content: message.content
|
|
4764
|
+
});
|
|
4765
|
+
} else if (message.role === "assistant" && Array.isArray(message.content)) {
|
|
4766
|
+
const textParts = [];
|
|
4767
|
+
const toolCallsInMessage = /* @__PURE__ */ new Set();
|
|
4768
|
+
const preservedBlocks = [];
|
|
4769
|
+
for (const block of message.content) {
|
|
4770
|
+
if (block.type === "text") {
|
|
4771
|
+
textParts.push(block.text);
|
|
4772
|
+
} else if (block.type === "tool-call" && block.toolName === "thinking_complete") ; else if (block.type === "tool-call") {
|
|
4773
|
+
toolCallsInMessage.add(block.toolCallId);
|
|
4774
|
+
}
|
|
4775
|
+
}
|
|
4776
|
+
for (const toolCallId of toolCallsInMessage) {
|
|
4777
|
+
const pair = toolCallPairs.get(toolCallId);
|
|
4778
|
+
const artifactId = toolCallToArtifactMap[toolCallId];
|
|
4779
|
+
if (pair?.call) {
|
|
4780
|
+
const args = JSON.stringify(pair.call.input);
|
|
4781
|
+
const artifactText = artifactId ? ` Results compressed into artifact: ${artifactId}.` : " Results were compressed but not saved.";
|
|
4782
|
+
textParts.push(`I called ${pair.call.toolName}(${args}).${artifactText}`);
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
if (preservedBlocks.length > 0 && textParts.length > 0) {
|
|
4786
|
+
const content = [...preservedBlocks];
|
|
4787
|
+
if (textParts.length > 0) {
|
|
4788
|
+
content.push({ type: "text", text: textParts.join("\n\n") });
|
|
4789
|
+
}
|
|
4790
|
+
textMessages.push({
|
|
4791
|
+
role: message.role,
|
|
4792
|
+
content
|
|
4793
|
+
});
|
|
4794
|
+
} else if (preservedBlocks.length > 0) {
|
|
4795
|
+
textMessages.push({
|
|
4796
|
+
role: message.role,
|
|
4797
|
+
content: preservedBlocks
|
|
4798
|
+
});
|
|
4799
|
+
} else if (textParts.length > 0) {
|
|
4800
|
+
textMessages.push({
|
|
4801
|
+
role: message.role,
|
|
4802
|
+
content: textParts.join("\n\n")
|
|
4803
|
+
});
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
}
|
|
4807
|
+
return textMessages;
|
|
4808
|
+
}
|
|
4809
|
+
// Removed focus hint helper methods - no longer needed since tool results are in formatted messages
|
|
4810
|
+
/**
|
|
4811
|
+
* Check if tool result data is effectively empty
|
|
4812
|
+
*/
|
|
4813
|
+
isEmpty(toolResultData) {
|
|
4814
|
+
if (!toolResultData || typeof toolResultData !== "object") {
|
|
4815
|
+
return true;
|
|
4816
|
+
}
|
|
4817
|
+
const { toolResult } = toolResultData;
|
|
4818
|
+
if (!toolResult) {
|
|
4819
|
+
return true;
|
|
4820
|
+
}
|
|
4821
|
+
if (typeof toolResult === "object" && !Array.isArray(toolResult)) {
|
|
4822
|
+
const keys = Object.keys(toolResult);
|
|
4823
|
+
if (keys.length === 0) {
|
|
4824
|
+
return true;
|
|
4825
|
+
}
|
|
4826
|
+
return keys.every((key) => {
|
|
4827
|
+
const value = toolResult[key];
|
|
4828
|
+
if (value === null || value === void 0 || value === "") {
|
|
4829
|
+
return true;
|
|
4830
|
+
}
|
|
4831
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
4832
|
+
return true;
|
|
4833
|
+
}
|
|
4834
|
+
if (typeof value === "object" && Object.keys(value).length === 0) {
|
|
4835
|
+
return true;
|
|
4836
|
+
}
|
|
4837
|
+
return false;
|
|
4838
|
+
});
|
|
4839
|
+
}
|
|
4840
|
+
if (Array.isArray(toolResult) && toolResult.length === 0) {
|
|
4841
|
+
return true;
|
|
4842
|
+
}
|
|
4843
|
+
if (typeof toolResult === "string" && toolResult.trim() === "") {
|
|
4844
|
+
return true;
|
|
4845
|
+
}
|
|
4846
|
+
return false;
|
|
4847
|
+
}
|
|
4848
|
+
/**
|
|
4849
|
+
* Recursively remove _structureHints from an object
|
|
4850
|
+
*/
|
|
4851
|
+
removeStructureHints(obj) {
|
|
4852
|
+
if (obj === null || obj === void 0) {
|
|
4853
|
+
return obj;
|
|
4854
|
+
}
|
|
4855
|
+
if (Array.isArray(obj)) {
|
|
4856
|
+
return obj.map((item) => this.removeStructureHints(item));
|
|
4857
|
+
}
|
|
4858
|
+
if (typeof obj === "object") {
|
|
4859
|
+
const cleaned = {};
|
|
4860
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
4861
|
+
if (key !== "_structureHints") {
|
|
4862
|
+
cleaned[key] = this.removeStructureHints(value);
|
|
4863
|
+
}
|
|
4864
|
+
}
|
|
4865
|
+
return cleaned;
|
|
4866
|
+
}
|
|
4867
|
+
return obj;
|
|
4868
|
+
}
|
|
4869
|
+
/**
|
|
4870
|
+
* Get current state for debugging
|
|
4871
|
+
*/
|
|
4872
|
+
getState() {
|
|
4873
|
+
return {
|
|
4874
|
+
shouldCompress: this.shouldCompress,
|
|
4875
|
+
config: this.config
|
|
4876
|
+
};
|
|
4877
|
+
}
|
|
4878
|
+
/**
|
|
4879
|
+
* Get the current compression summary
|
|
4880
|
+
*/
|
|
4881
|
+
getCompressionSummary() {
|
|
4882
|
+
return this.cumulativeSummary;
|
|
4883
|
+
}
|
|
4884
|
+
};
|
|
4161
4885
|
|
|
4162
4886
|
// src/services/PendingToolApprovalManager.ts
|
|
4163
|
-
var
|
|
4887
|
+
var logger11 = getLogger("PendingToolApprovalManager");
|
|
4164
4888
|
var APPROVAL_CLEANUP_INTERVAL_MS = 2 * 60 * 1e3;
|
|
4165
4889
|
var APPROVAL_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
4166
4890
|
var PendingToolApprovalManager = class _PendingToolApprovalManager {
|
|
@@ -4199,7 +4923,7 @@ var PendingToolApprovalManager = class _PendingToolApprovalManager {
|
|
|
4199
4923
|
timeoutId
|
|
4200
4924
|
};
|
|
4201
4925
|
this.pendingApprovals.set(toolCallId, approval);
|
|
4202
|
-
|
|
4926
|
+
logger11.info(
|
|
4203
4927
|
{
|
|
4204
4928
|
toolCallId,
|
|
4205
4929
|
toolName,
|
|
@@ -4216,10 +4940,10 @@ var PendingToolApprovalManager = class _PendingToolApprovalManager {
|
|
|
4216
4940
|
approveToolCall(toolCallId) {
|
|
4217
4941
|
const approval = this.pendingApprovals.get(toolCallId);
|
|
4218
4942
|
if (!approval) {
|
|
4219
|
-
|
|
4943
|
+
logger11.warn({ toolCallId }, "Tool approval not found or already processed");
|
|
4220
4944
|
return false;
|
|
4221
4945
|
}
|
|
4222
|
-
|
|
4946
|
+
logger11.info(
|
|
4223
4947
|
{
|
|
4224
4948
|
toolCallId,
|
|
4225
4949
|
toolName: approval.toolName,
|
|
@@ -4238,10 +4962,10 @@ var PendingToolApprovalManager = class _PendingToolApprovalManager {
|
|
|
4238
4962
|
denyToolCall(toolCallId, reason) {
|
|
4239
4963
|
const approval = this.pendingApprovals.get(toolCallId);
|
|
4240
4964
|
if (!approval) {
|
|
4241
|
-
|
|
4965
|
+
logger11.warn({ toolCallId }, "Tool approval not found or already processed");
|
|
4242
4966
|
return false;
|
|
4243
4967
|
}
|
|
4244
|
-
|
|
4968
|
+
logger11.info(
|
|
4245
4969
|
{
|
|
4246
4970
|
toolCallId,
|
|
4247
4971
|
toolName: approval.toolName,
|
|
@@ -4273,7 +4997,7 @@ var PendingToolApprovalManager = class _PendingToolApprovalManager {
|
|
|
4273
4997
|
}
|
|
4274
4998
|
}
|
|
4275
4999
|
if (cleanedUp > 0) {
|
|
4276
|
-
|
|
5000
|
+
logger11.info({ cleanedUp }, "Cleaned up expired tool approvals");
|
|
4277
5001
|
}
|
|
4278
5002
|
}
|
|
4279
5003
|
/**
|
|
@@ -4296,7 +5020,7 @@ var PendingToolApprovalManager = class _PendingToolApprovalManager {
|
|
|
4296
5020
|
var pendingToolApprovalManager = PendingToolApprovalManager.getInstance();
|
|
4297
5021
|
|
|
4298
5022
|
// src/services/ResponseFormatter.ts
|
|
4299
|
-
var
|
|
5023
|
+
var logger12 = getLogger("ResponseFormatter");
|
|
4300
5024
|
var ResponseFormatter = class {
|
|
4301
5025
|
artifactParser;
|
|
4302
5026
|
subAgentId;
|
|
@@ -4355,7 +5079,7 @@ var ResponseFormatter = class {
|
|
|
4355
5079
|
return { parts };
|
|
4356
5080
|
} catch (error) {
|
|
4357
5081
|
setSpanWithError(span, error instanceof Error ? error : new Error(String(error)));
|
|
4358
|
-
|
|
5082
|
+
logger12.error({ error, responseObject }, "Error formatting object response");
|
|
4359
5083
|
return {
|
|
4360
5084
|
parts: [{ kind: "data", data: responseObject }]
|
|
4361
5085
|
};
|
|
@@ -4411,7 +5135,7 @@ var ResponseFormatter = class {
|
|
|
4411
5135
|
return { parts };
|
|
4412
5136
|
} catch (error) {
|
|
4413
5137
|
setSpanWithError(span, error instanceof Error ? error : new Error(String(error)));
|
|
4414
|
-
|
|
5138
|
+
logger12.error({ error, responseText }, "Error formatting response");
|
|
4415
5139
|
return { text: responseText };
|
|
4416
5140
|
} finally {
|
|
4417
5141
|
span.end();
|
|
@@ -4728,9 +5452,9 @@ var ArtifactReferenceSchema = class _ArtifactReferenceSchema {
|
|
|
4728
5452
|
* Get the standard Zod schema for artifact reference components
|
|
4729
5453
|
*/
|
|
4730
5454
|
static getSchema() {
|
|
4731
|
-
return z.object({
|
|
4732
|
-
id: z.string(),
|
|
4733
|
-
name: z.literal("Artifact"),
|
|
5455
|
+
return z$1.object({
|
|
5456
|
+
id: z$1.string(),
|
|
5457
|
+
name: z$1.literal("Artifact"),
|
|
4734
5458
|
props: jsonSchemaToZod(_ArtifactReferenceSchema.ARTIFACT_PROPS_SCHEMA)
|
|
4735
5459
|
});
|
|
4736
5460
|
}
|
|
@@ -4781,9 +5505,9 @@ var ArtifactCreateSchema = class {
|
|
|
4781
5505
|
},
|
|
4782
5506
|
required: ["id", "tool_call_id", "type", "base_selector"]
|
|
4783
5507
|
};
|
|
4784
|
-
return z.object({
|
|
4785
|
-
id: z.string(),
|
|
4786
|
-
name: z.literal(`ArtifactCreate_${component.name}`),
|
|
5508
|
+
return z$1.object({
|
|
5509
|
+
id: z$1.string(),
|
|
5510
|
+
name: z$1.literal(`ArtifactCreate_${component.name}`),
|
|
4787
5511
|
props: jsonSchemaToZod(propsSchema)
|
|
4788
5512
|
});
|
|
4789
5513
|
});
|
|
@@ -4843,7 +5567,7 @@ function parseEmbeddedJson(data) {
|
|
|
4843
5567
|
}
|
|
4844
5568
|
|
|
4845
5569
|
// src/a2a/client.ts
|
|
4846
|
-
var
|
|
5570
|
+
var logger13 = getLogger("a2aClient");
|
|
4847
5571
|
var DEFAULT_BACKOFF = {
|
|
4848
5572
|
initialInterval: 500,
|
|
4849
5573
|
maxInterval: 6e4,
|
|
@@ -5050,7 +5774,7 @@ var A2AClient = class {
|
|
|
5050
5774
|
try {
|
|
5051
5775
|
const res = await fn();
|
|
5052
5776
|
if (attempt > 0) {
|
|
5053
|
-
|
|
5777
|
+
logger13.info(
|
|
5054
5778
|
{
|
|
5055
5779
|
attempts: attempt + 1,
|
|
5056
5780
|
elapsedTime: Date.now() - start
|
|
@@ -5065,7 +5789,7 @@ var A2AClient = class {
|
|
|
5065
5789
|
}
|
|
5066
5790
|
const elapsed = Date.now() - start;
|
|
5067
5791
|
if (elapsed > maxElapsedTime) {
|
|
5068
|
-
|
|
5792
|
+
logger13.warn(
|
|
5069
5793
|
{
|
|
5070
5794
|
attempts: attempt + 1,
|
|
5071
5795
|
elapsedTime: elapsed,
|
|
@@ -5086,7 +5810,7 @@ var A2AClient = class {
|
|
|
5086
5810
|
retryInterval = initialInterval * attempt ** exponent + Math.random() * 1e3;
|
|
5087
5811
|
}
|
|
5088
5812
|
const delayMs = Math.min(retryInterval, maxInterval);
|
|
5089
|
-
|
|
5813
|
+
logger13.info(
|
|
5090
5814
|
{
|
|
5091
5815
|
attempt: attempt + 1,
|
|
5092
5816
|
delayMs,
|
|
@@ -5177,7 +5901,7 @@ var A2AClient = class {
|
|
|
5177
5901
|
});
|
|
5178
5902
|
}
|
|
5179
5903
|
if (rpcResponse.id !== requestId2) {
|
|
5180
|
-
|
|
5904
|
+
logger13.warn(
|
|
5181
5905
|
{
|
|
5182
5906
|
method,
|
|
5183
5907
|
expectedId: requestId2,
|
|
@@ -5374,7 +6098,7 @@ var A2AClient = class {
|
|
|
5374
6098
|
try {
|
|
5375
6099
|
while (true) {
|
|
5376
6100
|
const { done, value } = await reader.read();
|
|
5377
|
-
|
|
6101
|
+
logger13.info({ done, value }, "parseA2ASseStream");
|
|
5378
6102
|
if (done) {
|
|
5379
6103
|
if (eventDataBuffer.trim()) {
|
|
5380
6104
|
const result = this._processSseEventData(
|
|
@@ -5461,7 +6185,7 @@ var A2AClient = class {
|
|
|
5461
6185
|
};
|
|
5462
6186
|
|
|
5463
6187
|
// src/agents/relationTools.ts
|
|
5464
|
-
var
|
|
6188
|
+
var logger14 = getLogger("relationships Tools");
|
|
5465
6189
|
var A2A_RETRY_STATUS_CODES = ["429", "500", "502", "503", "504"];
|
|
5466
6190
|
var generateTransferToolDescription = (config) => {
|
|
5467
6191
|
let toolsSection = "";
|
|
@@ -5486,9 +6210,9 @@ Can Delegate To:
|
|
|
5486
6210
|
${delegateList}`;
|
|
5487
6211
|
}
|
|
5488
6212
|
if (config.tools && config.tools.length > 0) {
|
|
5489
|
-
const toolDescriptions = config.tools.map((
|
|
5490
|
-
const toolsList =
|
|
5491
|
-
return `MCP Server: ${
|
|
6213
|
+
const toolDescriptions = config.tools.map((tool4) => {
|
|
6214
|
+
const toolsList = tool4.availableTools?.map((t) => ` - ${t.name}: ${t.description || "No description available"}`).join("\n") || "";
|
|
6215
|
+
return `MCP Server: ${tool4.name}
|
|
5492
6216
|
${toolsList}`;
|
|
5493
6217
|
}).join("\n\n");
|
|
5494
6218
|
toolsSection = `
|
|
@@ -5514,9 +6238,9 @@ var generateDelegateToolDescription = (delegateRelation) => {
|
|
|
5514
6238
|
if (delegateRelation.type === "internal" && "tools" in config) {
|
|
5515
6239
|
const agentConfig = config;
|
|
5516
6240
|
if (agentConfig.tools && agentConfig.tools.length > 0) {
|
|
5517
|
-
const toolDescriptions = agentConfig.tools.map((
|
|
5518
|
-
const toolsList =
|
|
5519
|
-
return `MCP Server: ${
|
|
6241
|
+
const toolDescriptions = agentConfig.tools.map((tool4) => {
|
|
6242
|
+
const toolsList = tool4.availableTools?.map((t) => ` - ${t.name}: ${t.description || "No description available"}`).join("\n") || "";
|
|
6243
|
+
return `MCP Server: ${tool4.name}
|
|
5520
6244
|
${toolsList}`;
|
|
5521
6245
|
}).join("\n\n");
|
|
5522
6246
|
toolsSection = `
|
|
@@ -5563,7 +6287,7 @@ var createTransferToAgentTool = ({
|
|
|
5563
6287
|
const toolDescription = generateTransferToolDescription(transferConfig);
|
|
5564
6288
|
return tool({
|
|
5565
6289
|
description: toolDescription,
|
|
5566
|
-
inputSchema: z.object({}),
|
|
6290
|
+
inputSchema: z$1.object({}),
|
|
5567
6291
|
execute: async () => {
|
|
5568
6292
|
const activeSpan = trace.getActiveSpan();
|
|
5569
6293
|
if (activeSpan) {
|
|
@@ -5572,7 +6296,7 @@ var createTransferToAgentTool = ({
|
|
|
5572
6296
|
[SPAN_KEYS.TRANSFER_TO_SUB_AGENT_ID]: transferConfig.id ?? "unknown"
|
|
5573
6297
|
});
|
|
5574
6298
|
}
|
|
5575
|
-
|
|
6299
|
+
logger14.info(
|
|
5576
6300
|
{
|
|
5577
6301
|
transferTo: transferConfig.id ?? "unknown",
|
|
5578
6302
|
fromSubAgent: callingAgentId
|
|
@@ -5593,7 +6317,7 @@ var createTransferToAgentTool = ({
|
|
|
5593
6317
|
fromSubAgentId: callingAgentId
|
|
5594
6318
|
// Include the calling agent ID for tracking
|
|
5595
6319
|
};
|
|
5596
|
-
|
|
6320
|
+
logger14.info(
|
|
5597
6321
|
{
|
|
5598
6322
|
transferResult,
|
|
5599
6323
|
transferResultKeys: Object.keys(transferResult)
|
|
@@ -5618,7 +6342,7 @@ function createDelegateToAgentTool({
|
|
|
5618
6342
|
}) {
|
|
5619
6343
|
return tool({
|
|
5620
6344
|
description: generateDelegateToolDescription(delegateConfig),
|
|
5621
|
-
inputSchema: z.object({ message: z.string() }),
|
|
6345
|
+
inputSchema: z$1.object({ message: z$1.string() }),
|
|
5622
6346
|
execute: async (input, context) => {
|
|
5623
6347
|
const delegationId = `del_${generateId()}`;
|
|
5624
6348
|
const activeSpan = trace.getActiveSpan();
|
|
@@ -5740,7 +6464,7 @@ function createDelegateToAgentTool({
|
|
|
5740
6464
|
...isInternal ? { fromSubAgentId: callingAgentId } : { fromExternalAgentId: callingAgentId }
|
|
5741
6465
|
}
|
|
5742
6466
|
};
|
|
5743
|
-
|
|
6467
|
+
logger14.info({ messageToSend }, "messageToSend");
|
|
5744
6468
|
await createMessage(dbClient_default)({
|
|
5745
6469
|
id: generateId(),
|
|
5746
6470
|
tenantId,
|
|
@@ -5802,7 +6526,7 @@ function createDelegateToAgentTool({
|
|
|
5802
6526
|
}
|
|
5803
6527
|
|
|
5804
6528
|
// src/agents/SystemPromptBuilder.ts
|
|
5805
|
-
var
|
|
6529
|
+
var logger15 = getLogger("SystemPromptBuilder");
|
|
5806
6530
|
var SystemPromptBuilder = class {
|
|
5807
6531
|
constructor(version, versionConfig) {
|
|
5808
6532
|
this.version = version;
|
|
@@ -5818,12 +6542,12 @@ var SystemPromptBuilder = class {
|
|
|
5818
6542
|
this.templates.set(name, content);
|
|
5819
6543
|
}
|
|
5820
6544
|
this.loaded = true;
|
|
5821
|
-
|
|
6545
|
+
logger15.debug(
|
|
5822
6546
|
{ templateCount: this.templates.size, version: this.version },
|
|
5823
6547
|
`Loaded ${this.templates.size} templates for version ${this.version}`
|
|
5824
6548
|
);
|
|
5825
6549
|
} catch (error) {
|
|
5826
|
-
|
|
6550
|
+
logger15.error({ error }, `Failed to load templates for version ${this.version}`);
|
|
5827
6551
|
throw new Error(`Template loading failed: ${error}`);
|
|
5828
6552
|
}
|
|
5829
6553
|
}
|
|
@@ -6213,6 +6937,8 @@ CREATING ARTIFACTS (SERVES AS CITATION):
|
|
|
6213
6937
|
Use the artifact:create annotation to extract data from tool results. The creation itself serves as a citation.
|
|
6214
6938
|
Format: <artifact:create id="unique-id" tool="tool_call_id" type="TypeName" base="selector.path" details='{"key":"jmespath_selector"}' />
|
|
6215
6939
|
|
|
6940
|
+
\u26A0\uFE0F IMPORTANT: Do not create artifacts from get_reference_artifact tool results - these are already compressed artifacts being retrieved. Only create artifacts from original research and analysis tools.
|
|
6941
|
+
|
|
6216
6942
|
\u{1F6A8} CRITICAL: DETAILS PROPS USE JMESPATH SELECTORS, NOT LITERAL VALUES! \u{1F6A8}
|
|
6217
6943
|
|
|
6218
6944
|
\u274C WRONG - Using literal values:
|
|
@@ -6431,27 +7157,27 @@ ${creationInstructions}
|
|
|
6431
7157
|
if (tools.length === 0) {
|
|
6432
7158
|
return '<available_tools description="No tools are currently available"></available_tools>';
|
|
6433
7159
|
}
|
|
6434
|
-
const toolsXml = tools.map((
|
|
7160
|
+
const toolsXml = tools.map((tool4) => this.generateToolXml(templates, tool4)).join("\n ");
|
|
6435
7161
|
return `<available_tools description="These are the tools available for you to use to accomplish tasks">
|
|
6436
7162
|
${toolsXml}
|
|
6437
7163
|
</available_tools>`;
|
|
6438
7164
|
}
|
|
6439
|
-
generateToolXml(templates,
|
|
7165
|
+
generateToolXml(templates, tool4) {
|
|
6440
7166
|
const toolTemplate = templates.get("tool");
|
|
6441
7167
|
if (!toolTemplate) {
|
|
6442
7168
|
throw new Error("Tool template not loaded");
|
|
6443
7169
|
}
|
|
6444
7170
|
let toolXml = toolTemplate;
|
|
6445
|
-
toolXml = toolXml.replace("{{TOOL_NAME}}",
|
|
7171
|
+
toolXml = toolXml.replace("{{TOOL_NAME}}", tool4.name);
|
|
6446
7172
|
toolXml = toolXml.replace(
|
|
6447
7173
|
"{{TOOL_DESCRIPTION}}",
|
|
6448
|
-
|
|
7174
|
+
tool4.description || "No description available"
|
|
6449
7175
|
);
|
|
6450
7176
|
toolXml = toolXml.replace(
|
|
6451
7177
|
"{{TOOL_USAGE_GUIDELINES}}",
|
|
6452
|
-
|
|
7178
|
+
tool4.usageGuidelines || "Use this tool when appropriate."
|
|
6453
7179
|
);
|
|
6454
|
-
const parametersXml = this.generateParametersXml(
|
|
7180
|
+
const parametersXml = this.generateParametersXml(tool4.inputSchema);
|
|
6455
7181
|
toolXml = toolXml.replace("{{TOOL_PARAMETERS_SCHEMA}}", parametersXml);
|
|
6456
7182
|
return toolXml;
|
|
6457
7183
|
}
|
|
@@ -6634,6 +7360,8 @@ CREATING ARTIFACTS (SERVES AS CITATION):
|
|
|
6634
7360
|
Use the appropriate ArtifactCreate_[Type] component to extract and structure data from tool results.
|
|
6635
7361
|
The creation itself serves as a citation - no additional reference needed.
|
|
6636
7362
|
|
|
7363
|
+
\u26A0\uFE0F IMPORTANT: Do not create artifacts from get_reference_artifact tool results - these are already compressed artifacts being retrieved. Only create artifacts from original research and analysis tools.
|
|
7364
|
+
|
|
6637
7365
|
\u{1F6AB} FORBIDDEN JMESPATH PATTERNS:
|
|
6638
7366
|
\u274C NEVER: [?title~'.*text.*'] (regex patterns with ~ operator)
|
|
6639
7367
|
\u274C NEVER: [?field~'pattern.*'] (any ~ operator usage)
|
|
@@ -6913,7 +7641,7 @@ function hasToolCallWithPrefix(prefix) {
|
|
|
6913
7641
|
return false;
|
|
6914
7642
|
};
|
|
6915
7643
|
}
|
|
6916
|
-
var
|
|
7644
|
+
var logger16 = getLogger("Agent");
|
|
6917
7645
|
function validateModel(modelString, modelType) {
|
|
6918
7646
|
if (!modelString?.trim()) {
|
|
6919
7647
|
throw new Error(
|
|
@@ -6922,8 +7650,8 @@ function validateModel(modelString, modelType) {
|
|
|
6922
7650
|
}
|
|
6923
7651
|
return modelString.trim();
|
|
6924
7652
|
}
|
|
6925
|
-
function isValidTool(
|
|
6926
|
-
return
|
|
7653
|
+
function isValidTool(tool4) {
|
|
7654
|
+
return tool4 && typeof tool4 === "object" && typeof tool4.description === "string" && tool4.inputSchema && typeof tool4.execute === "function";
|
|
6927
7655
|
}
|
|
6928
7656
|
var Agent = class {
|
|
6929
7657
|
config;
|
|
@@ -6939,6 +7667,7 @@ var Agent = class {
|
|
|
6939
7667
|
credentialStoreRegistry;
|
|
6940
7668
|
mcpClientCache = /* @__PURE__ */ new Map();
|
|
6941
7669
|
mcpConnectionLocks = /* @__PURE__ */ new Map();
|
|
7670
|
+
currentCompressor = null;
|
|
6942
7671
|
constructor(config, credentialStoreRegistry) {
|
|
6943
7672
|
this.artifactComponents = config.artifactComponents || [];
|
|
6944
7673
|
let processedDataComponents = config.dataComponents || [];
|
|
@@ -7024,17 +7753,17 @@ var Agent = class {
|
|
|
7024
7753
|
}
|
|
7025
7754
|
#getRelationshipIdForTool(toolName, toolType) {
|
|
7026
7755
|
if (toolType === "mcp") {
|
|
7027
|
-
const matchingTool = this.config.tools?.find((
|
|
7028
|
-
if (
|
|
7756
|
+
const matchingTool = this.config.tools?.find((tool4) => {
|
|
7757
|
+
if (tool4.config?.type !== "mcp") {
|
|
7029
7758
|
return false;
|
|
7030
7759
|
}
|
|
7031
|
-
if (
|
|
7760
|
+
if (tool4.availableTools?.some((available) => available.name === toolName)) {
|
|
7032
7761
|
return true;
|
|
7033
7762
|
}
|
|
7034
|
-
if (
|
|
7763
|
+
if (tool4.config.mcp.activeTools?.includes(toolName)) {
|
|
7035
7764
|
return true;
|
|
7036
7765
|
}
|
|
7037
|
-
return
|
|
7766
|
+
return tool4.name === toolName;
|
|
7038
7767
|
});
|
|
7039
7768
|
return matchingTool?.relationshipId;
|
|
7040
7769
|
}
|
|
@@ -7088,9 +7817,59 @@ var Agent = class {
|
|
|
7088
7817
|
providerOptions: baseConfig.providerOptions
|
|
7089
7818
|
};
|
|
7090
7819
|
}
|
|
7820
|
+
/**
|
|
7821
|
+
* Get the model settings for summarization/distillation
|
|
7822
|
+
* Falls back to base model if summarizer not configured
|
|
7823
|
+
*/
|
|
7824
|
+
getSummarizerModel() {
|
|
7825
|
+
if (!this.config.models) {
|
|
7826
|
+
throw new Error(
|
|
7827
|
+
"Model configuration is required. Please configure models at the project level."
|
|
7828
|
+
);
|
|
7829
|
+
}
|
|
7830
|
+
const summarizerConfig = this.config.models.summarizer;
|
|
7831
|
+
const baseConfig = this.config.models.base;
|
|
7832
|
+
if (summarizerConfig) {
|
|
7833
|
+
return {
|
|
7834
|
+
model: validateModel(summarizerConfig.model, "Summarizer"),
|
|
7835
|
+
providerOptions: summarizerConfig.providerOptions
|
|
7836
|
+
};
|
|
7837
|
+
}
|
|
7838
|
+
if (!baseConfig) {
|
|
7839
|
+
throw new Error(
|
|
7840
|
+
"Base model configuration is required for summarizer fallback. Please configure models at the project level."
|
|
7841
|
+
);
|
|
7842
|
+
}
|
|
7843
|
+
return {
|
|
7844
|
+
model: validateModel(baseConfig.model, "Base (fallback for summarizer)"),
|
|
7845
|
+
providerOptions: baseConfig.providerOptions
|
|
7846
|
+
};
|
|
7847
|
+
}
|
|
7091
7848
|
setConversationId(conversationId) {
|
|
7092
7849
|
this.conversationId = conversationId;
|
|
7093
7850
|
}
|
|
7851
|
+
/**
|
|
7852
|
+
* Simple compression fallback: drop oldest messages to fit under token limit
|
|
7853
|
+
*/
|
|
7854
|
+
simpleCompression(messages, targetTokens) {
|
|
7855
|
+
if (messages.length === 0) return messages;
|
|
7856
|
+
const estimateTokens = (msg) => {
|
|
7857
|
+
const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
|
|
7858
|
+
return Math.ceil(content.length / 4);
|
|
7859
|
+
};
|
|
7860
|
+
let totalTokens = messages.reduce((sum, msg) => sum + estimateTokens(msg), 0);
|
|
7861
|
+
if (totalTokens <= targetTokens) {
|
|
7862
|
+
return messages;
|
|
7863
|
+
}
|
|
7864
|
+
const result = [...messages];
|
|
7865
|
+
while (totalTokens > targetTokens && result.length > 1) {
|
|
7866
|
+
const dropped = result.shift();
|
|
7867
|
+
if (dropped) {
|
|
7868
|
+
totalTokens -= estimateTokens(dropped);
|
|
7869
|
+
}
|
|
7870
|
+
}
|
|
7871
|
+
return result;
|
|
7872
|
+
}
|
|
7094
7873
|
/**
|
|
7095
7874
|
* Set delegation status for this agent instance
|
|
7096
7875
|
*/
|
|
@@ -7126,14 +7905,21 @@ var Agent = class {
|
|
|
7126
7905
|
const toolCallId = context?.toolCallId || generateToolId();
|
|
7127
7906
|
const activeSpan = trace.getActiveSpan();
|
|
7128
7907
|
if (activeSpan) {
|
|
7129
|
-
|
|
7908
|
+
const attributes = {
|
|
7130
7909
|
"conversation.id": this.conversationId,
|
|
7131
7910
|
"tool.purpose": toolDefinition.description || "No description provided",
|
|
7132
7911
|
"ai.toolType": toolType || "unknown",
|
|
7133
7912
|
"subAgent.name": this.config.name || "unknown",
|
|
7134
7913
|
"subAgent.id": this.config.id || "unknown",
|
|
7135
7914
|
"agent.id": this.config.agentId || "unknown"
|
|
7136
|
-
}
|
|
7915
|
+
};
|
|
7916
|
+
if (options?.mcpServerId) {
|
|
7917
|
+
attributes["ai.toolCall.mcpServerId"] = options.mcpServerId;
|
|
7918
|
+
}
|
|
7919
|
+
if (options?.mcpServerName) {
|
|
7920
|
+
attributes["ai.toolCall.mcpServerName"] = options.mcpServerName;
|
|
7921
|
+
}
|
|
7922
|
+
activeSpan.setAttributes(attributes);
|
|
7137
7923
|
}
|
|
7138
7924
|
const isInternalTool = toolName.includes("save_tool_result") || toolName.includes("thinking_complete") || toolName.startsWith("transfer_to_");
|
|
7139
7925
|
const needsApproval = options?.needsApproval || false;
|
|
@@ -7186,7 +7972,7 @@ var Agent = class {
|
|
|
7186
7972
|
};
|
|
7187
7973
|
await createMessage(dbClient_default)(messagePayload);
|
|
7188
7974
|
} catch (error) {
|
|
7189
|
-
|
|
7975
|
+
logger16.warn(
|
|
7190
7976
|
{ error, toolName, toolCallId, conversationId: toolResultConversationId },
|
|
7191
7977
|
"Failed to store tool result in conversation history"
|
|
7192
7978
|
);
|
|
@@ -7274,10 +8060,10 @@ var Agent = class {
|
|
|
7274
8060
|
]);
|
|
7275
8061
|
}
|
|
7276
8062
|
async getMcpTools(sessionId, streamRequestId) {
|
|
7277
|
-
const mcpTools = this.config.tools?.filter((
|
|
7278
|
-
return
|
|
8063
|
+
const mcpTools = this.config.tools?.filter((tool4) => {
|
|
8064
|
+
return tool4.config?.type === "mcp";
|
|
7279
8065
|
}) || [];
|
|
7280
|
-
const tools = await Promise.all(mcpTools.map((
|
|
8066
|
+
const tools = await Promise.all(mcpTools.map((tool4) => this.getMcpTool(tool4)) || []) || [];
|
|
7281
8067
|
if (!sessionId) {
|
|
7282
8068
|
const wrappedTools2 = {};
|
|
7283
8069
|
for (const toolSet of tools) {
|
|
@@ -7292,7 +8078,11 @@ var Agent = class {
|
|
|
7292
8078
|
enhancedTool,
|
|
7293
8079
|
streamRequestId,
|
|
7294
8080
|
"mcp",
|
|
7295
|
-
{
|
|
8081
|
+
{
|
|
8082
|
+
needsApproval,
|
|
8083
|
+
mcpServerId: toolSet.mcpServerId,
|
|
8084
|
+
mcpServerName: toolSet.mcpServerName
|
|
8085
|
+
}
|
|
7296
8086
|
);
|
|
7297
8087
|
}
|
|
7298
8088
|
}
|
|
@@ -7302,11 +8092,11 @@ var Agent = class {
|
|
|
7302
8092
|
for (const toolResult of tools) {
|
|
7303
8093
|
for (const [toolName, originalTool] of Object.entries(toolResult.tools)) {
|
|
7304
8094
|
if (!isValidTool(originalTool)) {
|
|
7305
|
-
|
|
8095
|
+
logger16.error({ toolName }, "Invalid MCP tool structure - missing required properties");
|
|
7306
8096
|
continue;
|
|
7307
8097
|
}
|
|
7308
8098
|
const needsApproval = toolResult.toolPolicies?.[toolName]?.needsApproval || false;
|
|
7309
|
-
|
|
8099
|
+
logger16.debug(
|
|
7310
8100
|
{
|
|
7311
8101
|
toolName,
|
|
7312
8102
|
toolPolicies: toolResult.toolPolicies,
|
|
@@ -7320,7 +8110,7 @@ var Agent = class {
|
|
|
7320
8110
|
inputSchema: originalTool.inputSchema,
|
|
7321
8111
|
execute: async (args, { toolCallId }) => {
|
|
7322
8112
|
if (needsApproval) {
|
|
7323
|
-
|
|
8113
|
+
logger16.info(
|
|
7324
8114
|
{ toolName, toolCallId, args },
|
|
7325
8115
|
"Tool requires approval - waiting for user response"
|
|
7326
8116
|
);
|
|
@@ -7366,7 +8156,7 @@ var Agent = class {
|
|
|
7366
8156
|
}
|
|
7367
8157
|
},
|
|
7368
8158
|
(denialSpan) => {
|
|
7369
|
-
|
|
8159
|
+
logger16.info(
|
|
7370
8160
|
{ toolName, toolCallId, reason: approvalResult.reason },
|
|
7371
8161
|
"Tool execution denied by user"
|
|
7372
8162
|
);
|
|
@@ -7387,18 +8177,18 @@ var Agent = class {
|
|
|
7387
8177
|
}
|
|
7388
8178
|
},
|
|
7389
8179
|
(approvedSpan) => {
|
|
7390
|
-
|
|
8180
|
+
logger16.info({ toolName, toolCallId }, "Tool approved, continuing with execution");
|
|
7391
8181
|
approvedSpan.setStatus({ code: SpanStatusCode.OK });
|
|
7392
8182
|
approvedSpan.end();
|
|
7393
8183
|
}
|
|
7394
8184
|
);
|
|
7395
8185
|
}
|
|
7396
|
-
|
|
8186
|
+
logger16.debug({ toolName, toolCallId }, "MCP Tool Called");
|
|
7397
8187
|
try {
|
|
7398
8188
|
const rawResult = await originalTool.execute(args, { toolCallId });
|
|
7399
8189
|
if (rawResult && typeof rawResult === "object" && rawResult.isError) {
|
|
7400
8190
|
const errorMessage = rawResult.content?.[0]?.text || "MCP tool returned an error";
|
|
7401
|
-
|
|
8191
|
+
logger16.error(
|
|
7402
8192
|
{ toolName, toolCallId, errorMessage, rawResult },
|
|
7403
8193
|
"MCP tool returned error status"
|
|
7404
8194
|
);
|
|
@@ -7449,7 +8239,7 @@ var Agent = class {
|
|
|
7449
8239
|
});
|
|
7450
8240
|
return { result: enhancedResult, toolCallId };
|
|
7451
8241
|
} catch (error) {
|
|
7452
|
-
|
|
8242
|
+
logger16.error({ toolName, toolCallId, error }, "MCP tool execution failed");
|
|
7453
8243
|
throw error;
|
|
7454
8244
|
}
|
|
7455
8245
|
}
|
|
@@ -7459,7 +8249,11 @@ var Agent = class {
|
|
|
7459
8249
|
sessionWrappedTool,
|
|
7460
8250
|
streamRequestId,
|
|
7461
8251
|
"mcp",
|
|
7462
|
-
{
|
|
8252
|
+
{
|
|
8253
|
+
needsApproval,
|
|
8254
|
+
mcpServerId: toolResult.mcpServerId,
|
|
8255
|
+
mcpServerName: toolResult.mcpServerName
|
|
8256
|
+
}
|
|
7463
8257
|
);
|
|
7464
8258
|
}
|
|
7465
8259
|
}
|
|
@@ -7468,28 +8262,28 @@ var Agent = class {
|
|
|
7468
8262
|
/**
|
|
7469
8263
|
* Convert database McpTool to builder MCPToolConfig format
|
|
7470
8264
|
*/
|
|
7471
|
-
convertToMCPToolConfig(
|
|
7472
|
-
if (
|
|
7473
|
-
throw new Error(`Cannot convert non-MCP tool to MCP config: ${
|
|
8265
|
+
convertToMCPToolConfig(tool4, agentToolRelationHeaders) {
|
|
8266
|
+
if (tool4.config.type !== "mcp") {
|
|
8267
|
+
throw new Error(`Cannot convert non-MCP tool to MCP config: ${tool4.id}`);
|
|
7474
8268
|
}
|
|
7475
8269
|
return {
|
|
7476
|
-
id:
|
|
7477
|
-
name:
|
|
7478
|
-
description:
|
|
8270
|
+
id: tool4.id,
|
|
8271
|
+
name: tool4.name,
|
|
8272
|
+
description: tool4.name,
|
|
7479
8273
|
// Use name as description fallback
|
|
7480
|
-
serverUrl:
|
|
7481
|
-
activeTools:
|
|
7482
|
-
mcpType:
|
|
7483
|
-
transport:
|
|
8274
|
+
serverUrl: tool4.config.mcp.server.url,
|
|
8275
|
+
activeTools: tool4.config.mcp.activeTools,
|
|
8276
|
+
mcpType: tool4.config.mcp.server.url.includes("api.nango.dev") ? MCPServerType.nango : MCPServerType.generic,
|
|
8277
|
+
transport: tool4.config.mcp.transport,
|
|
7484
8278
|
headers: {
|
|
7485
|
-
...
|
|
8279
|
+
...tool4.headers,
|
|
7486
8280
|
...agentToolRelationHeaders
|
|
7487
8281
|
}
|
|
7488
8282
|
};
|
|
7489
8283
|
}
|
|
7490
|
-
async getMcpTool(
|
|
7491
|
-
const cacheKey = `${this.config.tenantId}-${this.config.projectId}-${
|
|
7492
|
-
const credentialReferenceId =
|
|
8284
|
+
async getMcpTool(tool4) {
|
|
8285
|
+
const cacheKey = `${this.config.tenantId}-${this.config.projectId}-${tool4.id}-${tool4.credentialReferenceId || "no-cred"}`;
|
|
8286
|
+
const credentialReferenceId = tool4.credentialReferenceId;
|
|
7493
8287
|
const toolsForAgent = await getToolsForAgent(dbClient_default)({
|
|
7494
8288
|
scopes: {
|
|
7495
8289
|
tenantId: this.config.tenantId,
|
|
@@ -7498,12 +8292,12 @@ var Agent = class {
|
|
|
7498
8292
|
subAgentId: this.config.id
|
|
7499
8293
|
}
|
|
7500
8294
|
});
|
|
7501
|
-
const toolRelation = toolsForAgent.data.find((t) => t.toolId ===
|
|
8295
|
+
const toolRelation = toolsForAgent.data.find((t) => t.toolId === tool4.id);
|
|
7502
8296
|
const agentToolRelationHeaders = toolRelation?.headers || void 0;
|
|
7503
8297
|
const selectedTools = toolRelation?.selectedTools || void 0;
|
|
7504
8298
|
const toolPolicies = toolRelation?.toolPolicies || {};
|
|
7505
8299
|
let serverConfig;
|
|
7506
|
-
const isUserScoped =
|
|
8300
|
+
const isUserScoped = tool4.credentialScope === "user";
|
|
7507
8301
|
const userId = this.config.userId;
|
|
7508
8302
|
if (isUserScoped && userId && this.credentialStuffer) {
|
|
7509
8303
|
const userCredentialReference = await getUserScopedCredentialReference(dbClient_default)({
|
|
@@ -7511,7 +8305,7 @@ var Agent = class {
|
|
|
7511
8305
|
tenantId: this.config.tenantId,
|
|
7512
8306
|
projectId: this.config.projectId
|
|
7513
8307
|
},
|
|
7514
|
-
toolId:
|
|
8308
|
+
toolId: tool4.id,
|
|
7515
8309
|
userId
|
|
7516
8310
|
});
|
|
7517
8311
|
if (userCredentialReference) {
|
|
@@ -7526,13 +8320,13 @@ var Agent = class {
|
|
|
7526
8320
|
contextConfigId: this.config.contextConfigId || void 0,
|
|
7527
8321
|
conversationId: this.conversationId || void 0
|
|
7528
8322
|
},
|
|
7529
|
-
this.convertToMCPToolConfig(
|
|
8323
|
+
this.convertToMCPToolConfig(tool4, agentToolRelationHeaders),
|
|
7530
8324
|
storeReference,
|
|
7531
8325
|
selectedTools
|
|
7532
8326
|
);
|
|
7533
8327
|
} else {
|
|
7534
|
-
|
|
7535
|
-
{ toolId:
|
|
8328
|
+
logger16.warn(
|
|
8329
|
+
{ toolId: tool4.id, userId },
|
|
7536
8330
|
"User-scoped tool has no credential connected for this user"
|
|
7537
8331
|
);
|
|
7538
8332
|
serverConfig = await this.credentialStuffer.buildMcpServerConfig(
|
|
@@ -7542,7 +8336,7 @@ var Agent = class {
|
|
|
7542
8336
|
contextConfigId: this.config.contextConfigId || void 0,
|
|
7543
8337
|
conversationId: this.conversationId || void 0
|
|
7544
8338
|
},
|
|
7545
|
-
this.convertToMCPToolConfig(
|
|
8339
|
+
this.convertToMCPToolConfig(tool4, agentToolRelationHeaders),
|
|
7546
8340
|
void 0,
|
|
7547
8341
|
selectedTools
|
|
7548
8342
|
);
|
|
@@ -7569,7 +8363,7 @@ var Agent = class {
|
|
|
7569
8363
|
contextConfigId: this.config.contextConfigId || void 0,
|
|
7570
8364
|
conversationId: this.conversationId || void 0
|
|
7571
8365
|
},
|
|
7572
|
-
this.convertToMCPToolConfig(
|
|
8366
|
+
this.convertToMCPToolConfig(tool4, agentToolRelationHeaders),
|
|
7573
8367
|
storeReference,
|
|
7574
8368
|
selectedTools
|
|
7575
8369
|
);
|
|
@@ -7581,28 +8375,41 @@ var Agent = class {
|
|
|
7581
8375
|
contextConfigId: this.config.contextConfigId || void 0,
|
|
7582
8376
|
conversationId: this.conversationId || void 0
|
|
7583
8377
|
},
|
|
7584
|
-
this.convertToMCPToolConfig(
|
|
8378
|
+
this.convertToMCPToolConfig(tool4, agentToolRelationHeaders),
|
|
7585
8379
|
void 0,
|
|
7586
8380
|
selectedTools
|
|
7587
8381
|
);
|
|
7588
8382
|
} else {
|
|
7589
|
-
if (
|
|
7590
|
-
throw new Error(`Cannot build server config for non-MCP tool: ${
|
|
8383
|
+
if (tool4.config.type !== "mcp") {
|
|
8384
|
+
throw new Error(`Cannot build server config for non-MCP tool: ${tool4.id}`);
|
|
7591
8385
|
}
|
|
7592
8386
|
serverConfig = {
|
|
7593
|
-
type:
|
|
7594
|
-
url:
|
|
7595
|
-
activeTools:
|
|
8387
|
+
type: tool4.config.mcp.transport?.type || MCPTransportType.streamableHttp,
|
|
8388
|
+
url: tool4.config.mcp.server.url,
|
|
8389
|
+
activeTools: tool4.config.mcp.activeTools,
|
|
7596
8390
|
selectedTools,
|
|
7597
8391
|
headers: agentToolRelationHeaders
|
|
7598
8392
|
};
|
|
7599
8393
|
}
|
|
7600
|
-
|
|
8394
|
+
if (serverConfig.url?.toString().includes("composio.dev")) {
|
|
8395
|
+
const urlObj = new URL(serverConfig.url.toString());
|
|
8396
|
+
if (isUserScoped && userId) {
|
|
8397
|
+
urlObj.searchParams.set("user_id", userId);
|
|
8398
|
+
} else {
|
|
8399
|
+
const SEPARATOR = "||";
|
|
8400
|
+
urlObj.searchParams.set(
|
|
8401
|
+
"user_id",
|
|
8402
|
+
`${this.config.tenantId}${SEPARATOR}${this.config.projectId}`
|
|
8403
|
+
);
|
|
8404
|
+
}
|
|
8405
|
+
serverConfig.url = urlObj.toString();
|
|
8406
|
+
}
|
|
8407
|
+
logger16.info(
|
|
7601
8408
|
{
|
|
7602
|
-
toolName:
|
|
8409
|
+
toolName: tool4.name,
|
|
7603
8410
|
credentialReferenceId,
|
|
7604
8411
|
transportType: serverConfig.type,
|
|
7605
|
-
headers:
|
|
8412
|
+
headers: tool4.headers
|
|
7606
8413
|
},
|
|
7607
8414
|
"Built MCP server config with credentials"
|
|
7608
8415
|
);
|
|
@@ -7614,7 +8421,7 @@ var Agent = class {
|
|
|
7614
8421
|
if (!client) {
|
|
7615
8422
|
let connectionPromise = this.mcpConnectionLocks.get(cacheKey);
|
|
7616
8423
|
if (!connectionPromise) {
|
|
7617
|
-
connectionPromise = this.createMcpConnection(
|
|
8424
|
+
connectionPromise = this.createMcpConnection(tool4, serverConfig);
|
|
7618
8425
|
this.mcpConnectionLocks.set(cacheKey, connectionPromise);
|
|
7619
8426
|
}
|
|
7620
8427
|
try {
|
|
@@ -7622,9 +8429,9 @@ var Agent = class {
|
|
|
7622
8429
|
this.mcpClientCache.set(cacheKey, client);
|
|
7623
8430
|
} catch (error) {
|
|
7624
8431
|
this.mcpConnectionLocks.delete(cacheKey);
|
|
7625
|
-
|
|
8432
|
+
logger16.error(
|
|
7626
8433
|
{
|
|
7627
|
-
toolName:
|
|
8434
|
+
toolName: tool4.name,
|
|
7628
8435
|
subAgentId: this.config.id,
|
|
7629
8436
|
cacheKey,
|
|
7630
8437
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -7642,13 +8449,13 @@ var Agent = class {
|
|
|
7642
8449
|
"ai.toolCall",
|
|
7643
8450
|
{
|
|
7644
8451
|
attributes: {
|
|
7645
|
-
"ai.toolCall.name":
|
|
8452
|
+
"ai.toolCall.name": tool4.name,
|
|
7646
8453
|
"ai.toolCall.args": JSON.stringify({ operation: "mcp_tool_discovery" }),
|
|
7647
8454
|
"ai.toolCall.result": JSON.stringify({
|
|
7648
8455
|
status: "no_tools_available",
|
|
7649
8456
|
message: `MCP server has 0 effective tools. Double check the selected tools in your agent and the active tools in the MCP server configuration.`,
|
|
7650
|
-
serverUrl:
|
|
7651
|
-
originalToolName:
|
|
8457
|
+
serverUrl: tool4.config.type === "mcp" ? tool4.config.mcp.server.url : "unknown",
|
|
8458
|
+
originalToolName: tool4.name
|
|
7652
8459
|
}),
|
|
7653
8460
|
"ai.toolType": "mcp",
|
|
7654
8461
|
"subAgent.name": this.config.name || "unknown",
|
|
@@ -7660,14 +8467,14 @@ var Agent = class {
|
|
|
7660
8467
|
}
|
|
7661
8468
|
},
|
|
7662
8469
|
(span) => {
|
|
7663
|
-
setSpanWithError(span, new Error(`0 effective tools available for ${
|
|
8470
|
+
setSpanWithError(span, new Error(`0 effective tools available for ${tool4.name}`));
|
|
7664
8471
|
agentSessionManager.recordEvent(streamRequestId, "error", this.config.id, {
|
|
7665
8472
|
message: `MCP server has 0 effective tools. Double check the selected tools in your graph and the active tools in the MCP server configuration.`,
|
|
7666
8473
|
code: "no_tools_available",
|
|
7667
8474
|
severity: "error",
|
|
7668
8475
|
context: {
|
|
7669
|
-
toolName:
|
|
7670
|
-
serverUrl:
|
|
8476
|
+
toolName: tool4.name,
|
|
8477
|
+
serverUrl: tool4.config.type === "mcp" ? tool4.config.mcp.server.url : "unknown",
|
|
7671
8478
|
operation: "mcp_tool_discovery"
|
|
7672
8479
|
}
|
|
7673
8480
|
});
|
|
@@ -7676,20 +8483,20 @@ var Agent = class {
|
|
|
7676
8483
|
);
|
|
7677
8484
|
}
|
|
7678
8485
|
}
|
|
7679
|
-
return { tools, toolPolicies };
|
|
8486
|
+
return { tools, toolPolicies, mcpServerId: tool4.id, mcpServerName: tool4.name };
|
|
7680
8487
|
}
|
|
7681
|
-
async createMcpConnection(
|
|
8488
|
+
async createMcpConnection(tool4, serverConfig) {
|
|
7682
8489
|
const client = new McpClient({
|
|
7683
|
-
name:
|
|
8490
|
+
name: tool4.name,
|
|
7684
8491
|
server: serverConfig
|
|
7685
8492
|
});
|
|
7686
8493
|
try {
|
|
7687
8494
|
await client.connect();
|
|
7688
8495
|
return client;
|
|
7689
8496
|
} catch (error) {
|
|
7690
|
-
|
|
8497
|
+
logger16.error(
|
|
7691
8498
|
{
|
|
7692
|
-
toolName:
|
|
8499
|
+
toolName: tool4.name,
|
|
7693
8500
|
subAgentId: this.config.id,
|
|
7694
8501
|
error: error instanceof Error ? error.message : String(error)
|
|
7695
8502
|
},
|
|
@@ -7729,7 +8536,7 @@ var Agent = class {
|
|
|
7729
8536
|
for (const functionToolDef of functionToolsData) {
|
|
7730
8537
|
const functionId = functionToolDef.functionId;
|
|
7731
8538
|
if (!functionId) {
|
|
7732
|
-
|
|
8539
|
+
logger16.warn(
|
|
7733
8540
|
{ functionToolId: functionToolDef.id },
|
|
7734
8541
|
"Function tool missing functionId reference"
|
|
7735
8542
|
);
|
|
@@ -7743,7 +8550,7 @@ var Agent = class {
|
|
|
7743
8550
|
}
|
|
7744
8551
|
});
|
|
7745
8552
|
if (!functionData) {
|
|
7746
|
-
|
|
8553
|
+
logger16.warn(
|
|
7747
8554
|
{ functionId, functionToolId: functionToolDef.id },
|
|
7748
8555
|
"Function not found in functions table"
|
|
7749
8556
|
);
|
|
@@ -7754,7 +8561,7 @@ var Agent = class {
|
|
|
7754
8561
|
description: functionToolDef.description || functionToolDef.name,
|
|
7755
8562
|
inputSchema: zodSchema,
|
|
7756
8563
|
execute: async (args, { toolCallId }) => {
|
|
7757
|
-
|
|
8564
|
+
logger16.debug(
|
|
7758
8565
|
{ toolName: functionToolDef.name, toolCallId, args },
|
|
7759
8566
|
"Function Tool Called"
|
|
7760
8567
|
);
|
|
@@ -7781,7 +8588,7 @@ var Agent = class {
|
|
|
7781
8588
|
});
|
|
7782
8589
|
return { result, toolCallId };
|
|
7783
8590
|
} catch (error) {
|
|
7784
|
-
|
|
8591
|
+
logger16.error(
|
|
7785
8592
|
{
|
|
7786
8593
|
toolName: functionToolDef.name,
|
|
7787
8594
|
toolCallId,
|
|
@@ -7801,7 +8608,7 @@ var Agent = class {
|
|
|
7801
8608
|
);
|
|
7802
8609
|
}
|
|
7803
8610
|
} catch (error) {
|
|
7804
|
-
|
|
8611
|
+
logger16.error({ error }, "Failed to load function tools from database");
|
|
7805
8612
|
}
|
|
7806
8613
|
return functionTools;
|
|
7807
8614
|
}
|
|
@@ -7811,7 +8618,7 @@ var Agent = class {
|
|
|
7811
8618
|
async getResolvedContext(conversationId, headers2) {
|
|
7812
8619
|
try {
|
|
7813
8620
|
if (!this.config.contextConfigId) {
|
|
7814
|
-
|
|
8621
|
+
logger16.debug({ agentId: this.config.agentId }, "No context config found for agent");
|
|
7815
8622
|
return null;
|
|
7816
8623
|
}
|
|
7817
8624
|
const contextConfig = await getContextConfigById(dbClient_default)({
|
|
@@ -7823,7 +8630,7 @@ var Agent = class {
|
|
|
7823
8630
|
id: this.config.contextConfigId
|
|
7824
8631
|
});
|
|
7825
8632
|
if (!contextConfig) {
|
|
7826
|
-
|
|
8633
|
+
logger16.warn({ contextConfigId: this.config.contextConfigId }, "Context config not found");
|
|
7827
8634
|
return null;
|
|
7828
8635
|
}
|
|
7829
8636
|
if (!this.contextResolver) {
|
|
@@ -7839,7 +8646,7 @@ var Agent = class {
|
|
|
7839
8646
|
...result.resolvedContext,
|
|
7840
8647
|
$env: process.env
|
|
7841
8648
|
};
|
|
7842
|
-
|
|
8649
|
+
logger16.debug(
|
|
7843
8650
|
{
|
|
7844
8651
|
conversationId,
|
|
7845
8652
|
contextConfigId: contextConfig.id,
|
|
@@ -7853,7 +8660,7 @@ var Agent = class {
|
|
|
7853
8660
|
);
|
|
7854
8661
|
return contextWithBuiltins;
|
|
7855
8662
|
} catch (error) {
|
|
7856
|
-
|
|
8663
|
+
logger16.error(
|
|
7857
8664
|
{
|
|
7858
8665
|
conversationId,
|
|
7859
8666
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -7877,7 +8684,7 @@ var Agent = class {
|
|
|
7877
8684
|
});
|
|
7878
8685
|
return agentDefinition?.prompt || void 0;
|
|
7879
8686
|
} catch (error) {
|
|
7880
|
-
|
|
8687
|
+
logger16.warn(
|
|
7881
8688
|
{
|
|
7882
8689
|
agentId: this.config.agentId,
|
|
7883
8690
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -7906,7 +8713,7 @@ var Agent = class {
|
|
|
7906
8713
|
(subAgent) => "artifactComponents" in subAgent && subAgent.artifactComponents && subAgent.artifactComponents.length > 0
|
|
7907
8714
|
);
|
|
7908
8715
|
} catch (error) {
|
|
7909
|
-
|
|
8716
|
+
logger16.warn(
|
|
7910
8717
|
{
|
|
7911
8718
|
agentId: this.config.agentId,
|
|
7912
8719
|
tenantId: this.config.tenantId,
|
|
@@ -7924,7 +8731,8 @@ var Agent = class {
|
|
|
7924
8731
|
*/
|
|
7925
8732
|
async buildPhase2SystemPrompt(runtimeContext) {
|
|
7926
8733
|
const phase2Config = new Phase2Config();
|
|
7927
|
-
const
|
|
8734
|
+
const compressionConfig = getCompressionConfigFromEnv();
|
|
8735
|
+
const hasAgentArtifactComponents = await this.hasAgentArtifactComponents() || compressionConfig.enabled;
|
|
7928
8736
|
const conversationId = runtimeContext?.metadata?.conversationId || runtimeContext?.contextId;
|
|
7929
8737
|
const resolvedContext = conversationId ? await this.getResolvedContext(conversationId) : null;
|
|
7930
8738
|
let processedPrompt = this.config.prompt || "";
|
|
@@ -7935,7 +8743,7 @@ var Agent = class {
|
|
|
7935
8743
|
preserveUnresolved: false
|
|
7936
8744
|
});
|
|
7937
8745
|
} catch (error) {
|
|
7938
|
-
|
|
8746
|
+
logger16.error(
|
|
7939
8747
|
{
|
|
7940
8748
|
conversationId,
|
|
7941
8749
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -7982,7 +8790,7 @@ var Agent = class {
|
|
|
7982
8790
|
preserveUnresolved: false
|
|
7983
8791
|
});
|
|
7984
8792
|
} catch (error) {
|
|
7985
|
-
|
|
8793
|
+
logger16.error(
|
|
7986
8794
|
{
|
|
7987
8795
|
conversationId,
|
|
7988
8796
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -7997,25 +8805,25 @@ var Agent = class {
|
|
|
7997
8805
|
const functionTools = await this.getFunctionTools(streamRequestId || "");
|
|
7998
8806
|
const relationTools = this.getRelationTools(runtimeContext);
|
|
7999
8807
|
const allTools = { ...mcpTools, ...functionTools, ...relationTools };
|
|
8000
|
-
|
|
8808
|
+
logger16.info(
|
|
8001
8809
|
{
|
|
8002
8810
|
mcpTools: Object.keys(mcpTools),
|
|
8003
8811
|
functionTools: Object.keys(functionTools),
|
|
8004
8812
|
relationTools: Object.keys(relationTools),
|
|
8005
8813
|
allTools: Object.keys(allTools),
|
|
8006
|
-
functionToolsDetails: Object.entries(functionTools).map(([name,
|
|
8814
|
+
functionToolsDetails: Object.entries(functionTools).map(([name, tool4]) => ({
|
|
8007
8815
|
name,
|
|
8008
|
-
hasExecute: typeof
|
|
8009
|
-
hasDescription: !!
|
|
8010
|
-
hasInputSchema: !!
|
|
8816
|
+
hasExecute: typeof tool4.execute === "function",
|
|
8817
|
+
hasDescription: !!tool4.description,
|
|
8818
|
+
hasInputSchema: !!tool4.inputSchema
|
|
8011
8819
|
}))
|
|
8012
8820
|
},
|
|
8013
8821
|
"Tools loaded for agent"
|
|
8014
8822
|
);
|
|
8015
|
-
const toolDefinitions = Object.entries(allTools).map(([name,
|
|
8823
|
+
const toolDefinitions = Object.entries(allTools).map(([name, tool4]) => ({
|
|
8016
8824
|
name,
|
|
8017
|
-
description:
|
|
8018
|
-
inputSchema:
|
|
8825
|
+
description: tool4.description || "",
|
|
8826
|
+
inputSchema: tool4.inputSchema || tool4.parameters || {},
|
|
8019
8827
|
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."
|
|
8020
8828
|
}));
|
|
8021
8829
|
const { getConversationScopedArtifacts } = await import('./conversations-XPSTWUMK.js');
|
|
@@ -8036,7 +8844,7 @@ var Agent = class {
|
|
|
8036
8844
|
preserveUnresolved: false
|
|
8037
8845
|
});
|
|
8038
8846
|
} catch (error) {
|
|
8039
|
-
|
|
8847
|
+
logger16.error(
|
|
8040
8848
|
{
|
|
8041
8849
|
conversationId,
|
|
8042
8850
|
error: error instanceof Error ? error.message : "Unknown error"
|
|
@@ -8046,7 +8854,8 @@ var Agent = class {
|
|
|
8046
8854
|
}
|
|
8047
8855
|
}
|
|
8048
8856
|
const shouldIncludeArtifactComponents = !excludeDataComponents;
|
|
8049
|
-
const
|
|
8857
|
+
const compressionConfig = getCompressionConfigFromEnv();
|
|
8858
|
+
const hasAgentArtifactComponents = await this.hasAgentArtifactComponents() || compressionConfig.enabled;
|
|
8050
8859
|
const config = {
|
|
8051
8860
|
corePrompt: processedPrompt,
|
|
8052
8861
|
prompt,
|
|
@@ -8064,12 +8873,12 @@ var Agent = class {
|
|
|
8064
8873
|
getArtifactTools() {
|
|
8065
8874
|
return tool({
|
|
8066
8875
|
description: "Call this tool to get the complete artifact data with the given artifactId. This retrieves the full artifact content (not just the summary). Only use this when you need the complete artifact data and the summary shown in your context is insufficient.",
|
|
8067
|
-
inputSchema: z.object({
|
|
8068
|
-
artifactId: z.string().describe("The unique identifier of the artifact to get."),
|
|
8069
|
-
toolCallId: z.string().describe("The tool call ID associated with this artifact.")
|
|
8876
|
+
inputSchema: z$1.object({
|
|
8877
|
+
artifactId: z$1.string().describe("The unique identifier of the artifact to get."),
|
|
8878
|
+
toolCallId: z$1.string().describe("The tool call ID associated with this artifact.")
|
|
8070
8879
|
}),
|
|
8071
8880
|
execute: async ({ artifactId, toolCallId }) => {
|
|
8072
|
-
|
|
8881
|
+
logger16.info({ artifactId, toolCallId }, "get_artifact_full executed");
|
|
8073
8882
|
const streamRequestId = this.getStreamRequestId();
|
|
8074
8883
|
const artifactService = agentSessionManager.getArtifactService(streamRequestId);
|
|
8075
8884
|
if (!artifactService) {
|
|
@@ -8093,9 +8902,9 @@ var Agent = class {
|
|
|
8093
8902
|
createThinkingCompleteTool() {
|
|
8094
8903
|
return tool({
|
|
8095
8904
|
description: "\u{1F6A8} CRITICAL: Call this tool IMMEDIATELY when you have gathered enough information to answer the user. This is MANDATORY - you CANNOT provide text responses in thinking mode, only tool calls. Call thinking_complete as soon as you have sufficient data to generate a structured response.",
|
|
8096
|
-
inputSchema: z.object({
|
|
8097
|
-
complete: z.boolean().describe("ALWAYS set to true - marks end of research phase"),
|
|
8098
|
-
summary: z.string().describe(
|
|
8905
|
+
inputSchema: z$1.object({
|
|
8906
|
+
complete: z$1.boolean().describe("ALWAYS set to true - marks end of research phase"),
|
|
8907
|
+
summary: z$1.string().describe(
|
|
8099
8908
|
"Brief summary of what information was gathered and why it is sufficient to answer the user"
|
|
8100
8909
|
)
|
|
8101
8910
|
}),
|
|
@@ -8105,7 +8914,8 @@ var Agent = class {
|
|
|
8105
8914
|
// Provide a default tool set that is always available to the agent.
|
|
8106
8915
|
async getDefaultTools(streamRequestId) {
|
|
8107
8916
|
const defaultTools = {};
|
|
8108
|
-
|
|
8917
|
+
const compressionConfig = getCompressionConfigFromEnv();
|
|
8918
|
+
if (await this.agentHasArtifactComponents() || compressionConfig.enabled) {
|
|
8109
8919
|
defaultTools.get_reference_artifact = this.getArtifactTools();
|
|
8110
8920
|
}
|
|
8111
8921
|
const hasStructuredOutput = this.config.dataComponents && this.config.dataComponents.length > 0;
|
|
@@ -8120,6 +8930,37 @@ var Agent = class {
|
|
|
8120
8930
|
);
|
|
8121
8931
|
}
|
|
8122
8932
|
}
|
|
8933
|
+
logger16.info(
|
|
8934
|
+
{ agentId: this.config.id, streamRequestId },
|
|
8935
|
+
"Adding compress_context tool to defaultTools"
|
|
8936
|
+
);
|
|
8937
|
+
defaultTools.compress_context = tool({
|
|
8938
|
+
description: "Manually compress the current conversation context to save space. Use when shifting topics, completing major tasks, or when context feels cluttered.",
|
|
8939
|
+
inputSchema: z$1.object({
|
|
8940
|
+
reason: z$1.string().describe(
|
|
8941
|
+
'Why you are requesting compression (e.g., "shifting from research to coding", "completed analysis phase")'
|
|
8942
|
+
)
|
|
8943
|
+
}),
|
|
8944
|
+
execute: async ({ reason }) => {
|
|
8945
|
+
logger16.info(
|
|
8946
|
+
{
|
|
8947
|
+
agentId: this.config.id,
|
|
8948
|
+
streamRequestId,
|
|
8949
|
+
reason
|
|
8950
|
+
},
|
|
8951
|
+
"Manual compression requested by LLM"
|
|
8952
|
+
);
|
|
8953
|
+
if (this.currentCompressor) {
|
|
8954
|
+
this.currentCompressor.requestManualCompression(reason);
|
|
8955
|
+
}
|
|
8956
|
+
return {
|
|
8957
|
+
status: "compression_requested",
|
|
8958
|
+
reason,
|
|
8959
|
+
message: "Context compression will be applied on the next generation step. Previous work has been summarized and saved as artifacts."
|
|
8960
|
+
};
|
|
8961
|
+
}
|
|
8962
|
+
});
|
|
8963
|
+
logger16.info("getDefaultTools returning tools:", Object.keys(defaultTools).join(", "));
|
|
8123
8964
|
return defaultTools;
|
|
8124
8965
|
}
|
|
8125
8966
|
getStreamRequestId() {
|
|
@@ -8365,7 +9206,7 @@ ${output}`;
|
|
|
8365
9206
|
};
|
|
8366
9207
|
return enhanced;
|
|
8367
9208
|
} catch (error) {
|
|
8368
|
-
|
|
9209
|
+
logger16.warn({ error }, "Failed to enhance tool result with structure hints");
|
|
8369
9210
|
return result;
|
|
8370
9211
|
}
|
|
8371
9212
|
}
|
|
@@ -8380,7 +9221,7 @@ ${output}`;
|
|
|
8380
9221
|
}
|
|
8381
9222
|
});
|
|
8382
9223
|
} catch (error) {
|
|
8383
|
-
|
|
9224
|
+
logger16.error(
|
|
8384
9225
|
{ error, agentId: this.config.agentId },
|
|
8385
9226
|
"Failed to check agent artifact components"
|
|
8386
9227
|
);
|
|
@@ -8497,7 +9338,7 @@ ${output}`;
|
|
|
8497
9338
|
const configuredTimeout = modelSettings.maxDuration ? Math.min(modelSettings.maxDuration * 1e3, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS) : shouldStreamPhase1 ? LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_STREAMING : LLM_GENERATION_FIRST_CALL_TIMEOUT_MS_NON_STREAMING;
|
|
8498
9339
|
const timeoutMs = Math.min(configuredTimeout, LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS);
|
|
8499
9340
|
if (modelSettings.maxDuration && modelSettings.maxDuration * 1e3 > LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS) {
|
|
8500
|
-
|
|
9341
|
+
logger16.warn(
|
|
8501
9342
|
{
|
|
8502
9343
|
requestedTimeout: modelSettings.maxDuration * 1e3,
|
|
8503
9344
|
appliedTimeout: timeoutMs,
|
|
@@ -8516,6 +9357,18 @@ ${output}`;
|
|
|
8516
9357
|
role: "user",
|
|
8517
9358
|
content: userMessage
|
|
8518
9359
|
});
|
|
9360
|
+
const originalMessageCount = messages.length;
|
|
9361
|
+
const compressionConfig = getCompressionConfigFromEnv();
|
|
9362
|
+
const compressor = compressionConfig.enabled ? new MidGenerationCompressor(
|
|
9363
|
+
sessionId,
|
|
9364
|
+
contextId,
|
|
9365
|
+
this.config.tenantId,
|
|
9366
|
+
this.config.projectId,
|
|
9367
|
+
compressionConfig,
|
|
9368
|
+
this.getSummarizerModel(),
|
|
9369
|
+
primaryModelSettings
|
|
9370
|
+
) : null;
|
|
9371
|
+
this.currentCompressor = compressor;
|
|
8519
9372
|
if (shouldStreamPhase1) {
|
|
8520
9373
|
const streamConfig = {
|
|
8521
9374
|
...modelSettings,
|
|
@@ -8526,6 +9379,87 @@ ${output}`;
|
|
|
8526
9379
|
...streamConfig,
|
|
8527
9380
|
messages,
|
|
8528
9381
|
tools: sanitizedTools,
|
|
9382
|
+
prepareStep: async ({ messages: stepMessages }) => {
|
|
9383
|
+
if (!compressor) {
|
|
9384
|
+
return {};
|
|
9385
|
+
}
|
|
9386
|
+
const compressionNeeded = compressor.isCompressionNeeded(stepMessages);
|
|
9387
|
+
if (compressionNeeded) {
|
|
9388
|
+
logger16.info(
|
|
9389
|
+
{
|
|
9390
|
+
compressorState: compressor.getState()
|
|
9391
|
+
},
|
|
9392
|
+
"Triggering layered mid-generation compression"
|
|
9393
|
+
);
|
|
9394
|
+
try {
|
|
9395
|
+
const originalMessages = stepMessages.slice(0, originalMessageCount);
|
|
9396
|
+
const generatedMessages = stepMessages.slice(originalMessageCount);
|
|
9397
|
+
if (generatedMessages.length > 0) {
|
|
9398
|
+
const compressionResult = await compressor.compress(generatedMessages);
|
|
9399
|
+
const finalMessages = [...originalMessages];
|
|
9400
|
+
if (compressionResult.summary.text_messages && compressionResult.summary.text_messages.length > 0) {
|
|
9401
|
+
finalMessages.push(...compressionResult.summary.text_messages);
|
|
9402
|
+
}
|
|
9403
|
+
const summaryMessage = JSON.stringify({
|
|
9404
|
+
high_level: compressionResult.summary?.summary?.high_level,
|
|
9405
|
+
user_intent: compressionResult.summary?.summary?.user_intent,
|
|
9406
|
+
decisions: compressionResult.summary?.summary?.decisions,
|
|
9407
|
+
open_questions: compressionResult.summary?.summary?.open_questions,
|
|
9408
|
+
next_steps: compressionResult.summary?.summary?.next_steps,
|
|
9409
|
+
related_artifacts: compressionResult?.summary?.summary?.related_artifacts
|
|
9410
|
+
});
|
|
9411
|
+
finalMessages.push({
|
|
9412
|
+
role: "user",
|
|
9413
|
+
content: `Based on your research, here's what you've discovered: ${summaryMessage}
|
|
9414
|
+
|
|
9415
|
+
Now please provide your answer to my original question using this context.`
|
|
9416
|
+
});
|
|
9417
|
+
logger16.info(
|
|
9418
|
+
{
|
|
9419
|
+
originalTotal: stepMessages.length,
|
|
9420
|
+
compressed: finalMessages.length,
|
|
9421
|
+
originalKept: originalMessages.length,
|
|
9422
|
+
generatedCompressed: generatedMessages.length
|
|
9423
|
+
},
|
|
9424
|
+
"Generated content compression completed"
|
|
9425
|
+
);
|
|
9426
|
+
logger16.info({ summaryMessage }, "Summary message");
|
|
9427
|
+
return { messages: finalMessages };
|
|
9428
|
+
}
|
|
9429
|
+
return {};
|
|
9430
|
+
} catch (error) {
|
|
9431
|
+
logger16.error(
|
|
9432
|
+
{
|
|
9433
|
+
error: error instanceof Error ? error.message : String(error),
|
|
9434
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
9435
|
+
},
|
|
9436
|
+
"Smart compression failed, falling back to simple compression"
|
|
9437
|
+
);
|
|
9438
|
+
try {
|
|
9439
|
+
const targetSize = Math.floor(compressor.getHardLimit() * 0.5);
|
|
9440
|
+
const fallbackMessages = this.simpleCompression(stepMessages, targetSize);
|
|
9441
|
+
logger16.info(
|
|
9442
|
+
{
|
|
9443
|
+
originalCount: stepMessages.length,
|
|
9444
|
+
compressedCount: fallbackMessages.length,
|
|
9445
|
+
compressionType: "simple_fallback"
|
|
9446
|
+
},
|
|
9447
|
+
"Simple compression fallback completed"
|
|
9448
|
+
);
|
|
9449
|
+
return { messages: fallbackMessages };
|
|
9450
|
+
} catch (fallbackError) {
|
|
9451
|
+
logger16.error(
|
|
9452
|
+
{
|
|
9453
|
+
error: fallbackError instanceof Error ? fallbackError.message : String(fallbackError)
|
|
9454
|
+
},
|
|
9455
|
+
"Fallback compression also failed, continuing without compression"
|
|
9456
|
+
);
|
|
9457
|
+
return {};
|
|
9458
|
+
}
|
|
9459
|
+
}
|
|
9460
|
+
}
|
|
9461
|
+
return {};
|
|
9462
|
+
},
|
|
8529
9463
|
stopWhen: async ({ steps }) => {
|
|
8530
9464
|
const last = steps.at(-1);
|
|
8531
9465
|
if (last && "text" in last && last.text) {
|
|
@@ -8539,7 +9473,7 @@ ${output}`;
|
|
|
8539
9473
|
}
|
|
8540
9474
|
);
|
|
8541
9475
|
} catch (error) {
|
|
8542
|
-
|
|
9476
|
+
logger16.debug({ error }, "Failed to track agent reasoning");
|
|
8543
9477
|
}
|
|
8544
9478
|
}
|
|
8545
9479
|
if (last && last["content"] && last["content"].length > 0) {
|
|
@@ -8661,6 +9595,87 @@ ${output}`;
|
|
|
8661
9595
|
...genConfig,
|
|
8662
9596
|
messages,
|
|
8663
9597
|
tools: sanitizedTools,
|
|
9598
|
+
prepareStep: async ({ messages: stepMessages }) => {
|
|
9599
|
+
if (!compressor) {
|
|
9600
|
+
return {};
|
|
9601
|
+
}
|
|
9602
|
+
const compressionNeeded = compressor.isCompressionNeeded(stepMessages);
|
|
9603
|
+
if (compressionNeeded) {
|
|
9604
|
+
logger16.info(
|
|
9605
|
+
{
|
|
9606
|
+
compressorState: compressor.getState()
|
|
9607
|
+
},
|
|
9608
|
+
"Triggering layered mid-generation compression"
|
|
9609
|
+
);
|
|
9610
|
+
try {
|
|
9611
|
+
const originalMessages = stepMessages.slice(0, originalMessageCount);
|
|
9612
|
+
const generatedMessages = stepMessages.slice(originalMessageCount);
|
|
9613
|
+
if (generatedMessages.length > 0) {
|
|
9614
|
+
const compressionResult = await compressor.compress(generatedMessages);
|
|
9615
|
+
const finalMessages = [...originalMessages];
|
|
9616
|
+
if (compressionResult.summary.text_messages && compressionResult.summary.text_messages.length > 0) {
|
|
9617
|
+
finalMessages.push(...compressionResult.summary.text_messages);
|
|
9618
|
+
}
|
|
9619
|
+
const summaryMessage = JSON.stringify({
|
|
9620
|
+
high_level: compressionResult.summary?.summary?.high_level,
|
|
9621
|
+
user_intent: compressionResult.summary?.summary?.user_intent,
|
|
9622
|
+
decisions: compressionResult.summary?.summary?.decisions,
|
|
9623
|
+
open_questions: compressionResult.summary?.summary?.open_questions,
|
|
9624
|
+
next_steps: compressionResult.summary?.summary?.next_steps,
|
|
9625
|
+
related_artifacts: compressionResult?.summary?.summary?.related_artifacts
|
|
9626
|
+
});
|
|
9627
|
+
finalMessages.push({
|
|
9628
|
+
role: "user",
|
|
9629
|
+
content: `Based on your research, here's what you've discovered: ${summaryMessage}
|
|
9630
|
+
|
|
9631
|
+
Now please provide your answer to my original question using this context.`
|
|
9632
|
+
});
|
|
9633
|
+
logger16.info(
|
|
9634
|
+
{
|
|
9635
|
+
originalTotal: stepMessages.length,
|
|
9636
|
+
compressed: finalMessages.length,
|
|
9637
|
+
originalKept: originalMessages.length,
|
|
9638
|
+
generatedCompressed: generatedMessages.length
|
|
9639
|
+
},
|
|
9640
|
+
"Generated content compression completed"
|
|
9641
|
+
);
|
|
9642
|
+
logger16.info({ summaryMessage }, "Summary message");
|
|
9643
|
+
return { messages: finalMessages };
|
|
9644
|
+
}
|
|
9645
|
+
return {};
|
|
9646
|
+
} catch (error) {
|
|
9647
|
+
logger16.error(
|
|
9648
|
+
{
|
|
9649
|
+
error: error instanceof Error ? error.message : String(error),
|
|
9650
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
9651
|
+
},
|
|
9652
|
+
"Smart compression failed, falling back to simple compression"
|
|
9653
|
+
);
|
|
9654
|
+
try {
|
|
9655
|
+
const targetSize = Math.floor(compressor.getHardLimit() * 0.5);
|
|
9656
|
+
const fallbackMessages = this.simpleCompression(stepMessages, targetSize);
|
|
9657
|
+
logger16.info(
|
|
9658
|
+
{
|
|
9659
|
+
originalCount: stepMessages.length,
|
|
9660
|
+
compressedCount: fallbackMessages.length,
|
|
9661
|
+
compressionType: "simple_fallback"
|
|
9662
|
+
},
|
|
9663
|
+
"Simple compression fallback completed"
|
|
9664
|
+
);
|
|
9665
|
+
return { messages: fallbackMessages };
|
|
9666
|
+
} catch (fallbackError) {
|
|
9667
|
+
logger16.error(
|
|
9668
|
+
{
|
|
9669
|
+
error: fallbackError instanceof Error ? fallbackError.message : String(fallbackError)
|
|
9670
|
+
},
|
|
9671
|
+
"Fallback compression also failed, continuing without compression"
|
|
9672
|
+
);
|
|
9673
|
+
return {};
|
|
9674
|
+
}
|
|
9675
|
+
}
|
|
9676
|
+
}
|
|
9677
|
+
return {};
|
|
9678
|
+
},
|
|
8664
9679
|
stopWhen: async ({ steps }) => {
|
|
8665
9680
|
const last = steps.at(-1);
|
|
8666
9681
|
if (last && "text" in last && last.text) {
|
|
@@ -8674,7 +9689,7 @@ ${output}`;
|
|
|
8674
9689
|
}
|
|
8675
9690
|
);
|
|
8676
9691
|
} catch (error) {
|
|
8677
|
-
|
|
9692
|
+
logger16.debug({ error }, "Failed to track agent reasoning");
|
|
8678
9693
|
}
|
|
8679
9694
|
}
|
|
8680
9695
|
if (steps.length >= 2) {
|
|
@@ -8712,7 +9727,22 @@ ${output}`;
|
|
|
8712
9727
|
const thinkingCompleteCall = response.steps?.flatMap((s) => s.toolCalls || [])?.find((tc) => tc.toolName === "thinking_complete");
|
|
8713
9728
|
if (thinkingCompleteCall) {
|
|
8714
9729
|
const reasoningFlow = [];
|
|
8715
|
-
|
|
9730
|
+
const compressionSummary = this.currentCompressor?.getCompressionSummary();
|
|
9731
|
+
if (compressionSummary) {
|
|
9732
|
+
const summaryContent = JSON.stringify(compressionSummary, null, 2);
|
|
9733
|
+
reasoningFlow.push({
|
|
9734
|
+
role: "assistant",
|
|
9735
|
+
content: `## Research Summary (Compressed)
|
|
9736
|
+
|
|
9737
|
+
Based on tool executions, here's the comprehensive summary:
|
|
9738
|
+
|
|
9739
|
+
\`\`\`json
|
|
9740
|
+
${summaryContent}
|
|
9741
|
+
\`\`\`
|
|
9742
|
+
|
|
9743
|
+
This summary represents all tool execution results in compressed form. Full details are preserved in artifacts.`
|
|
9744
|
+
});
|
|
9745
|
+
} else if (response.steps) {
|
|
8716
9746
|
response.steps.forEach((step) => {
|
|
8717
9747
|
if (step.toolCalls && step.toolResults) {
|
|
8718
9748
|
step.toolCalls.forEach((call, index) => {
|
|
@@ -8786,9 +9816,9 @@ ${output}${structureHintsFormatted}`;
|
|
|
8786
9816
|
this.config.dataComponents.forEach((dc) => {
|
|
8787
9817
|
const propsSchema = jsonSchemaToZod(dc.props);
|
|
8788
9818
|
componentSchemas.push(
|
|
8789
|
-
z.object({
|
|
8790
|
-
id: z.string(),
|
|
8791
|
-
name: z.literal(dc.name),
|
|
9819
|
+
z$1.object({
|
|
9820
|
+
id: z$1.string(),
|
|
9821
|
+
name: z$1.literal(dc.name),
|
|
8792
9822
|
props: propsSchema
|
|
8793
9823
|
})
|
|
8794
9824
|
);
|
|
@@ -8805,7 +9835,7 @@ ${output}${structureHintsFormatted}`;
|
|
|
8805
9835
|
if (componentSchemas.length === 1) {
|
|
8806
9836
|
dataComponentsSchema = componentSchemas[0];
|
|
8807
9837
|
} else {
|
|
8808
|
-
dataComponentsSchema = z.union(
|
|
9838
|
+
dataComponentsSchema = z$1.union(
|
|
8809
9839
|
componentSchemas
|
|
8810
9840
|
);
|
|
8811
9841
|
}
|
|
@@ -8821,7 +9851,7 @@ ${output}${structureHintsFormatted}`;
|
|
|
8821
9851
|
LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS
|
|
8822
9852
|
);
|
|
8823
9853
|
if (structuredModelSettings.maxDuration && structuredModelSettings.maxDuration * 1e3 > LLM_GENERATION_MAX_ALLOWED_TIMEOUT_MS) {
|
|
8824
|
-
|
|
9854
|
+
logger16.warn(
|
|
8825
9855
|
{
|
|
8826
9856
|
requestedTimeout: structuredModelSettings.maxDuration * 1e3,
|
|
8827
9857
|
appliedTimeout: phase2TimeoutMs,
|
|
@@ -8844,11 +9874,17 @@ ${output}${structureHintsFormatted}`;
|
|
|
8844
9874
|
}
|
|
8845
9875
|
phase2Messages.push({ role: "user", content: userMessage });
|
|
8846
9876
|
phase2Messages.push(...reasoningFlow);
|
|
9877
|
+
if (reasoningFlow.length > 0 && reasoningFlow[reasoningFlow.length - 1]?.role === "assistant") {
|
|
9878
|
+
phase2Messages.push({
|
|
9879
|
+
role: "user",
|
|
9880
|
+
content: "Continue with the structured response."
|
|
9881
|
+
});
|
|
9882
|
+
}
|
|
8847
9883
|
const streamResult = streamObject({
|
|
8848
9884
|
...structuredModelSettings,
|
|
8849
9885
|
messages: phase2Messages,
|
|
8850
|
-
schema: z.object({
|
|
8851
|
-
dataComponents: z.array(dataComponentsSchema)
|
|
9886
|
+
schema: z$1.object({
|
|
9887
|
+
dataComponents: z$1.array(dataComponentsSchema)
|
|
8852
9888
|
}),
|
|
8853
9889
|
experimental_telemetry: {
|
|
8854
9890
|
isEnabled: true,
|
|
@@ -8914,12 +9950,18 @@ ${output}${structureHintsFormatted}`;
|
|
|
8914
9950
|
}
|
|
8915
9951
|
phase2Messages.push({ role: "user", content: userMessage });
|
|
8916
9952
|
phase2Messages.push(...reasoningFlow);
|
|
9953
|
+
if (reasoningFlow.length > 0 && reasoningFlow[reasoningFlow.length - 1]?.role === "assistant") {
|
|
9954
|
+
phase2Messages.push({
|
|
9955
|
+
role: "user",
|
|
9956
|
+
content: "Continue with the structured response."
|
|
9957
|
+
});
|
|
9958
|
+
}
|
|
8917
9959
|
const structuredResponse = await generateObject(
|
|
8918
9960
|
withJsonPostProcessing({
|
|
8919
9961
|
...structuredModelSettings,
|
|
8920
9962
|
messages: phase2Messages,
|
|
8921
|
-
schema: z.object({
|
|
8922
|
-
dataComponents: z.array(dataComponentsSchema)
|
|
9963
|
+
schema: z$1.object({
|
|
9964
|
+
dataComponents: z$1.array(dataComponentsSchema)
|
|
8923
9965
|
}),
|
|
8924
9966
|
experimental_telemetry: {
|
|
8925
9967
|
isEnabled: true,
|
|
@@ -8984,8 +10026,10 @@ ${output}${structureHintsFormatted}`;
|
|
|
8984
10026
|
generationType
|
|
8985
10027
|
});
|
|
8986
10028
|
}
|
|
10029
|
+
this.currentCompressor = null;
|
|
8987
10030
|
return formattedResponse;
|
|
8988
10031
|
} catch (error) {
|
|
10032
|
+
this.currentCompressor = null;
|
|
8989
10033
|
const errorToThrow = error instanceof Error ? error : new Error(String(error));
|
|
8990
10034
|
setSpanWithError(span, errorToThrow);
|
|
8991
10035
|
span.end();
|
|
@@ -8997,7 +10041,7 @@ ${output}${structureHintsFormatted}`;
|
|
|
8997
10041
|
};
|
|
8998
10042
|
|
|
8999
10043
|
// src/agents/generateTaskHandler.ts
|
|
9000
|
-
var
|
|
10044
|
+
var logger17 = getLogger("generateTaskHandler");
|
|
9001
10045
|
var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
9002
10046
|
return async (task) => {
|
|
9003
10047
|
try {
|
|
@@ -9115,7 +10159,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9115
10159
|
return { ...relation, description: enhancedDescription };
|
|
9116
10160
|
}
|
|
9117
10161
|
} catch (error) {
|
|
9118
|
-
|
|
10162
|
+
logger17.warn({ subAgentId: relation.id, error }, "Failed to enhance agent description");
|
|
9119
10163
|
}
|
|
9120
10164
|
return relation;
|
|
9121
10165
|
})
|
|
@@ -9173,7 +10217,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9173
10217
|
};
|
|
9174
10218
|
}
|
|
9175
10219
|
} catch (error) {
|
|
9176
|
-
|
|
10220
|
+
logger17.warn(
|
|
9177
10221
|
{ targetAgentId: relation.targetAgentId, error },
|
|
9178
10222
|
"Failed to enhance team agent description"
|
|
9179
10223
|
);
|
|
@@ -9195,7 +10239,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9195
10239
|
);
|
|
9196
10240
|
if (item.selectedTools && item.selectedTools.length > 0) {
|
|
9197
10241
|
const selectedToolsSet = new Set(item.selectedTools);
|
|
9198
|
-
mcpTool.availableTools = mcpTool.availableTools?.filter((
|
|
10242
|
+
mcpTool.availableTools = mcpTool.availableTools?.filter((tool4) => selectedToolsSet.has(tool4.name)) || [];
|
|
9199
10243
|
}
|
|
9200
10244
|
return mcpTool;
|
|
9201
10245
|
})
|
|
@@ -9262,7 +10306,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9262
10306
|
targetTransferRelations = transferRel;
|
|
9263
10307
|
targetDelegateRelations = delegateRel;
|
|
9264
10308
|
} catch (err) {
|
|
9265
|
-
|
|
10309
|
+
logger17.info(
|
|
9266
10310
|
{
|
|
9267
10311
|
agentId: relation.id,
|
|
9268
10312
|
error: err?.message || "Unknown error"
|
|
@@ -9282,7 +10326,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9282
10326
|
if (item.selectedTools && item.selectedTools.length > 0) {
|
|
9283
10327
|
const selectedToolsSet = new Set(item.selectedTools);
|
|
9284
10328
|
mcpTool.availableTools = mcpTool.availableTools?.filter(
|
|
9285
|
-
(
|
|
10329
|
+
(tool4) => selectedToolsSet.has(tool4.name)
|
|
9286
10330
|
) || [];
|
|
9287
10331
|
}
|
|
9288
10332
|
return mcpTool;
|
|
@@ -9403,7 +10447,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9403
10447
|
const taskIdMatch = task.id.match(/^task_([^-]+-[^-]+-\d+)-/);
|
|
9404
10448
|
if (taskIdMatch) {
|
|
9405
10449
|
contextId = taskIdMatch[1];
|
|
9406
|
-
|
|
10450
|
+
logger17.info(
|
|
9407
10451
|
{
|
|
9408
10452
|
taskId: task.id,
|
|
9409
10453
|
extractedContextId: contextId,
|
|
@@ -9421,7 +10465,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9421
10465
|
agent.setDelegationStatus(isDelegation);
|
|
9422
10466
|
agent.setDelegationId(delegationId);
|
|
9423
10467
|
if (isDelegation) {
|
|
9424
|
-
|
|
10468
|
+
logger17.info(
|
|
9425
10469
|
{ subAgentId: config.subAgentId, taskId: task.id, delegationId },
|
|
9426
10470
|
"Delegated agent - streaming disabled"
|
|
9427
10471
|
);
|
|
@@ -9458,7 +10502,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9458
10502
|
const toolResult = allToolResults.find(
|
|
9459
10503
|
(result) => result.toolCallId === toolCall.toolCallId
|
|
9460
10504
|
);
|
|
9461
|
-
|
|
10505
|
+
logger17.info(
|
|
9462
10506
|
{
|
|
9463
10507
|
toolCallName: toolCall.toolName,
|
|
9464
10508
|
toolCallId: toolCall.toolCallId,
|
|
@@ -9475,7 +10519,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9475
10519
|
const transferReason = responseText || allThoughts[allThoughts.length - 1]?.text || "Agent requested transfer. No reason provided.";
|
|
9476
10520
|
if (toolResult?.output && isValidTransferResult(toolResult.output)) {
|
|
9477
10521
|
const transferResult = toolResult.output;
|
|
9478
|
-
|
|
10522
|
+
logger17.info(
|
|
9479
10523
|
{
|
|
9480
10524
|
validationPassed: true,
|
|
9481
10525
|
transferResult,
|
|
@@ -9492,7 +10536,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9492
10536
|
reason: transferReason,
|
|
9493
10537
|
original_message: userMessage
|
|
9494
10538
|
};
|
|
9495
|
-
|
|
10539
|
+
logger17.info(
|
|
9496
10540
|
{
|
|
9497
10541
|
artifactData,
|
|
9498
10542
|
artifactDataKeys: Object.keys(artifactData)
|
|
@@ -9517,7 +10561,7 @@ var createTaskHandler = (config, credentialStoreRegistry) => {
|
|
|
9517
10561
|
]
|
|
9518
10562
|
};
|
|
9519
10563
|
}
|
|
9520
|
-
|
|
10564
|
+
logger17.warn(
|
|
9521
10565
|
{
|
|
9522
10566
|
hasToolResult: !!toolResult,
|
|
9523
10567
|
hasOutput: !!toolResult?.output,
|
|
@@ -9609,7 +10653,7 @@ var createTaskHandlerConfig = async (params) => {
|
|
|
9609
10653
|
};
|
|
9610
10654
|
|
|
9611
10655
|
// src/data/agents.ts
|
|
9612
|
-
var
|
|
10656
|
+
var logger18 = getLogger("agents");
|
|
9613
10657
|
function createAgentCard({
|
|
9614
10658
|
dbAgent,
|
|
9615
10659
|
baseUrl
|
|
@@ -9720,7 +10764,7 @@ async function getRegisteredAgent(params) {
|
|
|
9720
10764
|
const agent = await getAgentWithDefaultSubAgent(dbClient_default)({
|
|
9721
10765
|
scopes: { tenantId, projectId, agentId }
|
|
9722
10766
|
});
|
|
9723
|
-
|
|
10767
|
+
logger18.info({ agent }, "agent with default sub agent");
|
|
9724
10768
|
if (!agent || !agent.defaultSubAgent) {
|
|
9725
10769
|
return null;
|
|
9726
10770
|
}
|
|
@@ -9752,7 +10796,7 @@ async function getRegisteredAgent(params) {
|
|
|
9752
10796
|
|
|
9753
10797
|
// src/routes/agents.ts
|
|
9754
10798
|
var app = new OpenAPIHono();
|
|
9755
|
-
var
|
|
10799
|
+
var logger19 = getLogger("agents");
|
|
9756
10800
|
app.openapi(
|
|
9757
10801
|
createRoute({
|
|
9758
10802
|
method: "get",
|
|
@@ -9767,14 +10811,14 @@ app.openapi(
|
|
|
9767
10811
|
description: "Agent Card for A2A discovery",
|
|
9768
10812
|
content: {
|
|
9769
10813
|
"application/json": {
|
|
9770
|
-
schema: z.object({
|
|
9771
|
-
name: z.string(),
|
|
9772
|
-
description: z.string().optional(),
|
|
9773
|
-
url: z.string(),
|
|
9774
|
-
version: z.string(),
|
|
9775
|
-
defaultInputModes: z.array(z.string()),
|
|
9776
|
-
defaultOutputModes: z.array(z.string()),
|
|
9777
|
-
skills: z.array(z.any())
|
|
10814
|
+
schema: z$1.object({
|
|
10815
|
+
name: z$1.string(),
|
|
10816
|
+
description: z$1.string().optional(),
|
|
10817
|
+
url: z$1.string(),
|
|
10818
|
+
version: z$1.string(),
|
|
10819
|
+
defaultInputModes: z$1.array(z$1.string()),
|
|
10820
|
+
defaultOutputModes: z$1.array(z$1.string()),
|
|
10821
|
+
skills: z$1.array(z$1.any())
|
|
9778
10822
|
})
|
|
9779
10823
|
}
|
|
9780
10824
|
}
|
|
@@ -9790,7 +10834,7 @@ app.openapi(
|
|
|
9790
10834
|
tracestate: c.req.header("tracestate"),
|
|
9791
10835
|
baggage: c.req.header("baggage")
|
|
9792
10836
|
};
|
|
9793
|
-
|
|
10837
|
+
logger19.info(
|
|
9794
10838
|
{
|
|
9795
10839
|
otelHeaders,
|
|
9796
10840
|
path: c.req.path,
|
|
@@ -9800,8 +10844,8 @@ app.openapi(
|
|
|
9800
10844
|
);
|
|
9801
10845
|
const executionContext = getRequestExecutionContext(c);
|
|
9802
10846
|
const { tenantId, projectId, agentId, subAgentId } = executionContext;
|
|
9803
|
-
|
|
9804
|
-
|
|
10847
|
+
logger19.info({ executionContext }, "executionContext");
|
|
10848
|
+
logger19.info(
|
|
9805
10849
|
{
|
|
9806
10850
|
message: "getRegisteredAgent (agent-level)",
|
|
9807
10851
|
tenantId,
|
|
@@ -9818,7 +10862,7 @@ app.openapi(
|
|
|
9818
10862
|
credentialStoreRegistry: credentialStores,
|
|
9819
10863
|
sandboxConfig
|
|
9820
10864
|
});
|
|
9821
|
-
|
|
10865
|
+
logger19.info({ agent }, "agent registered: well-known agent.json");
|
|
9822
10866
|
if (!agent) {
|
|
9823
10867
|
throw createApiError({
|
|
9824
10868
|
code: "not_found",
|
|
@@ -9834,7 +10878,7 @@ app.post("/a2a", async (c) => {
|
|
|
9834
10878
|
tracestate: c.req.header("tracestate"),
|
|
9835
10879
|
baggage: c.req.header("baggage")
|
|
9836
10880
|
};
|
|
9837
|
-
|
|
10881
|
+
logger19.info(
|
|
9838
10882
|
{
|
|
9839
10883
|
otelHeaders,
|
|
9840
10884
|
path: c.req.path,
|
|
@@ -9845,7 +10889,7 @@ app.post("/a2a", async (c) => {
|
|
|
9845
10889
|
const executionContext = getRequestExecutionContext(c);
|
|
9846
10890
|
const { tenantId, projectId, agentId, subAgentId } = executionContext;
|
|
9847
10891
|
if (subAgentId) {
|
|
9848
|
-
|
|
10892
|
+
logger19.info(
|
|
9849
10893
|
{
|
|
9850
10894
|
message: "a2a (agent-level)",
|
|
9851
10895
|
tenantId,
|
|
@@ -9874,7 +10918,7 @@ app.post("/a2a", async (c) => {
|
|
|
9874
10918
|
}
|
|
9875
10919
|
return a2aHandler(c, agent2);
|
|
9876
10920
|
}
|
|
9877
|
-
|
|
10921
|
+
logger19.info(
|
|
9878
10922
|
{
|
|
9879
10923
|
message: "a2a (agent-level)",
|
|
9880
10924
|
tenantId,
|
|
@@ -9952,14 +10996,14 @@ function extractTransferData(task) {
|
|
|
9952
10996
|
}
|
|
9953
10997
|
|
|
9954
10998
|
// src/a2a/transfer.ts
|
|
9955
|
-
var
|
|
10999
|
+
var logger20 = getLogger("Transfer");
|
|
9956
11000
|
async function executeTransfer({
|
|
9957
11001
|
tenantId,
|
|
9958
11002
|
threadId,
|
|
9959
11003
|
projectId,
|
|
9960
11004
|
targetSubAgentId
|
|
9961
11005
|
}) {
|
|
9962
|
-
|
|
11006
|
+
logger20.info(
|
|
9963
11007
|
{
|
|
9964
11008
|
targetAgent: targetSubAgentId,
|
|
9965
11009
|
threadId,
|
|
@@ -9974,12 +11018,12 @@ async function executeTransfer({
|
|
|
9974
11018
|
threadId,
|
|
9975
11019
|
subAgentId: targetSubAgentId
|
|
9976
11020
|
});
|
|
9977
|
-
|
|
11021
|
+
logger20.info(
|
|
9978
11022
|
{ targetAgent: targetSubAgentId, threadId },
|
|
9979
11023
|
"Successfully updated active_sub_agent_id in database"
|
|
9980
11024
|
);
|
|
9981
11025
|
} catch (error) {
|
|
9982
|
-
|
|
11026
|
+
logger20.error(
|
|
9983
11027
|
{ error, targetAgent: targetSubAgentId, threadId },
|
|
9984
11028
|
"Failed to update active_sub_agent_id"
|
|
9985
11029
|
);
|
|
@@ -10543,7 +11587,7 @@ function createBufferingStreamHelper() {
|
|
|
10543
11587
|
var createMCPStreamHelper = createBufferingStreamHelper;
|
|
10544
11588
|
|
|
10545
11589
|
// src/handlers/executionHandler.ts
|
|
10546
|
-
var
|
|
11590
|
+
var logger21 = getLogger("ExecutionHandler");
|
|
10547
11591
|
var ExecutionHandler = class {
|
|
10548
11592
|
MAX_ERRORS = AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS;
|
|
10549
11593
|
/**
|
|
@@ -10576,7 +11620,7 @@ var ExecutionHandler = class {
|
|
|
10576
11620
|
if (emitOperations) {
|
|
10577
11621
|
agentSessionManager.enableEmitOperations(requestId2);
|
|
10578
11622
|
}
|
|
10579
|
-
|
|
11623
|
+
logger21.info(
|
|
10580
11624
|
{ sessionId: requestId2, agentId, conversationId, emitOperations },
|
|
10581
11625
|
"Created AgentSession for message execution"
|
|
10582
11626
|
);
|
|
@@ -10609,7 +11653,7 @@ var ExecutionHandler = class {
|
|
|
10609
11653
|
);
|
|
10610
11654
|
}
|
|
10611
11655
|
} catch (modelError) {
|
|
10612
|
-
|
|
11656
|
+
logger21.warn(
|
|
10613
11657
|
{
|
|
10614
11658
|
error: modelError instanceof Error ? modelError.message : "Unknown error",
|
|
10615
11659
|
agentId
|
|
@@ -10624,7 +11668,7 @@ var ExecutionHandler = class {
|
|
|
10624
11668
|
}
|
|
10625
11669
|
}
|
|
10626
11670
|
} catch (error) {
|
|
10627
|
-
|
|
11671
|
+
logger21.error(
|
|
10628
11672
|
{
|
|
10629
11673
|
error: error instanceof Error ? error.message : "Unknown error",
|
|
10630
11674
|
stack: error instanceof Error ? error.stack : void 0
|
|
@@ -10640,7 +11684,7 @@ var ExecutionHandler = class {
|
|
|
10640
11684
|
try {
|
|
10641
11685
|
await sseHelper.writeOperation(agentInitializingOp(requestId2, agentId));
|
|
10642
11686
|
const taskId = `task_${conversationId}-${requestId2}`;
|
|
10643
|
-
|
|
11687
|
+
logger21.info(
|
|
10644
11688
|
{ taskId, currentAgentId, conversationId, requestId: requestId2 },
|
|
10645
11689
|
"Attempting to create or reuse existing task"
|
|
10646
11690
|
);
|
|
@@ -10664,7 +11708,7 @@ var ExecutionHandler = class {
|
|
|
10664
11708
|
sub_agent_id: currentAgentId
|
|
10665
11709
|
}
|
|
10666
11710
|
});
|
|
10667
|
-
|
|
11711
|
+
logger21.info(
|
|
10668
11712
|
{
|
|
10669
11713
|
taskId,
|
|
10670
11714
|
createdTaskMetadata: Array.isArray(task) ? task[0]?.metadata : task?.metadata
|
|
@@ -10673,27 +11717,27 @@ var ExecutionHandler = class {
|
|
|
10673
11717
|
);
|
|
10674
11718
|
} catch (error) {
|
|
10675
11719
|
if (error?.cause?.code === "23505") {
|
|
10676
|
-
|
|
11720
|
+
logger21.info(
|
|
10677
11721
|
{ taskId, error: error.message },
|
|
10678
11722
|
"Task already exists, fetching existing task"
|
|
10679
11723
|
);
|
|
10680
11724
|
const existingTask = await getTask(dbClient_default)({ id: taskId });
|
|
10681
11725
|
if (existingTask) {
|
|
10682
11726
|
task = existingTask;
|
|
10683
|
-
|
|
11727
|
+
logger21.info(
|
|
10684
11728
|
{ taskId, existingTask },
|
|
10685
11729
|
"Successfully reused existing task from race condition"
|
|
10686
11730
|
);
|
|
10687
11731
|
} else {
|
|
10688
|
-
|
|
11732
|
+
logger21.error({ taskId, error }, "Task constraint failed but task not found");
|
|
10689
11733
|
throw error;
|
|
10690
11734
|
}
|
|
10691
11735
|
} else {
|
|
10692
|
-
|
|
11736
|
+
logger21.error({ taskId, error }, "Failed to create task due to non-constraint error");
|
|
10693
11737
|
throw error;
|
|
10694
11738
|
}
|
|
10695
11739
|
}
|
|
10696
|
-
|
|
11740
|
+
logger21.debug(
|
|
10697
11741
|
{
|
|
10698
11742
|
timestamp: /* @__PURE__ */ new Date(),
|
|
10699
11743
|
executionType: "create_initial_task",
|
|
@@ -10712,7 +11756,7 @@ var ExecutionHandler = class {
|
|
|
10712
11756
|
const maxTransfers = agentConfig?.stopWhen?.transferCountIs ?? AGENT_EXECUTION_TRANSFER_COUNT_DEFAULT;
|
|
10713
11757
|
while (iterations < maxTransfers) {
|
|
10714
11758
|
iterations++;
|
|
10715
|
-
|
|
11759
|
+
logger21.info(
|
|
10716
11760
|
{ iterations, currentAgentId, agentId, conversationId, fromSubAgentId },
|
|
10717
11761
|
`Execution loop iteration ${iterations} with agent ${currentAgentId}, transfer from: ${fromSubAgentId || "none"}`
|
|
10718
11762
|
);
|
|
@@ -10720,10 +11764,10 @@ var ExecutionHandler = class {
|
|
|
10720
11764
|
scopes: { tenantId, projectId },
|
|
10721
11765
|
conversationId
|
|
10722
11766
|
});
|
|
10723
|
-
|
|
11767
|
+
logger21.info({ activeAgent }, "activeAgent");
|
|
10724
11768
|
if (activeAgent && activeAgent.activeSubAgentId !== currentAgentId) {
|
|
10725
11769
|
currentAgentId = activeAgent.activeSubAgentId;
|
|
10726
|
-
|
|
11770
|
+
logger21.info({ currentAgentId }, `Updated current agent to: ${currentAgentId}`);
|
|
10727
11771
|
}
|
|
10728
11772
|
const agentBaseUrl = `${baseUrl}/agents`;
|
|
10729
11773
|
const a2aClient = new A2AClient(agentBaseUrl, {
|
|
@@ -10764,13 +11808,13 @@ var ExecutionHandler = class {
|
|
|
10764
11808
|
});
|
|
10765
11809
|
if (!messageResponse?.result) {
|
|
10766
11810
|
errorCount++;
|
|
10767
|
-
|
|
11811
|
+
logger21.error(
|
|
10768
11812
|
{ currentAgentId, iterations, errorCount },
|
|
10769
11813
|
`No response from agent ${currentAgentId} on iteration ${iterations} (error ${errorCount}/${this.MAX_ERRORS})`
|
|
10770
11814
|
);
|
|
10771
11815
|
if (errorCount >= this.MAX_ERRORS) {
|
|
10772
11816
|
const errorMessage2 = `Maximum error limit (${this.MAX_ERRORS}) reached`;
|
|
10773
|
-
|
|
11817
|
+
logger21.error({ maxErrors: this.MAX_ERRORS, errorCount }, errorMessage2);
|
|
10774
11818
|
await sseHelper.writeOperation(errorOp(errorMessage2, currentAgentId || "system"));
|
|
10775
11819
|
if (task) {
|
|
10776
11820
|
await updateTask(dbClient_default)({
|
|
@@ -10794,7 +11838,7 @@ var ExecutionHandler = class {
|
|
|
10794
11838
|
if (isTransferTask(messageResponse.result)) {
|
|
10795
11839
|
const transferData = extractTransferData(messageResponse.result);
|
|
10796
11840
|
if (!transferData) {
|
|
10797
|
-
|
|
11841
|
+
logger21.error(
|
|
10798
11842
|
{ result: messageResponse.result },
|
|
10799
11843
|
"Transfer detected but no transfer data found"
|
|
10800
11844
|
);
|
|
@@ -10803,7 +11847,7 @@ var ExecutionHandler = class {
|
|
|
10803
11847
|
const { targetSubAgentId, fromSubAgentId: transferFromAgent } = transferData;
|
|
10804
11848
|
const firstArtifact = messageResponse.result.artifacts[0];
|
|
10805
11849
|
const transferReason = firstArtifact?.parts[1]?.kind === "text" ? firstArtifact.parts[1].text : "Transfer initiated";
|
|
10806
|
-
|
|
11850
|
+
logger21.info({ targetSubAgentId, transferReason, transferFromAgent }, "Transfer response");
|
|
10807
11851
|
await createMessage(dbClient_default)({
|
|
10808
11852
|
id: generateId(),
|
|
10809
11853
|
tenantId,
|
|
@@ -10834,7 +11878,7 @@ var ExecutionHandler = class {
|
|
|
10834
11878
|
if (success) {
|
|
10835
11879
|
fromSubAgentId = currentAgentId;
|
|
10836
11880
|
currentAgentId = newAgentId;
|
|
10837
|
-
|
|
11881
|
+
logger21.info(
|
|
10838
11882
|
{
|
|
10839
11883
|
transferFrom: fromSubAgentId,
|
|
10840
11884
|
transferTo: currentAgentId,
|
|
@@ -10848,7 +11892,7 @@ var ExecutionHandler = class {
|
|
|
10848
11892
|
let responseParts = [];
|
|
10849
11893
|
if (messageResponse.result.streamedContent?.parts) {
|
|
10850
11894
|
responseParts = messageResponse.result.streamedContent.parts;
|
|
10851
|
-
|
|
11895
|
+
logger21.info(
|
|
10852
11896
|
{ partsCount: responseParts.length },
|
|
10853
11897
|
"Using streamed content for conversation history"
|
|
10854
11898
|
);
|
|
@@ -10856,7 +11900,7 @@ var ExecutionHandler = class {
|
|
|
10856
11900
|
responseParts = messageResponse.result.artifacts?.flatMap(
|
|
10857
11901
|
(artifact) => artifact.parts || []
|
|
10858
11902
|
) || [];
|
|
10859
|
-
|
|
11903
|
+
logger21.info(
|
|
10860
11904
|
{ partsCount: responseParts.length },
|
|
10861
11905
|
"Using artifacts for conversation history (fallback)"
|
|
10862
11906
|
);
|
|
@@ -10865,7 +11909,7 @@ var ExecutionHandler = class {
|
|
|
10865
11909
|
const agentSessionData = agentSessionManager.getSession(requestId2);
|
|
10866
11910
|
if (agentSessionData) {
|
|
10867
11911
|
const sessionSummary = agentSessionData.getSummary();
|
|
10868
|
-
|
|
11912
|
+
logger21.info(sessionSummary, "AgentSession data after completion");
|
|
10869
11913
|
}
|
|
10870
11914
|
let textContent = "";
|
|
10871
11915
|
for (const part of responseParts) {
|
|
@@ -10919,22 +11963,22 @@ var ExecutionHandler = class {
|
|
|
10919
11963
|
}
|
|
10920
11964
|
});
|
|
10921
11965
|
const updateTaskEnd = Date.now();
|
|
10922
|
-
|
|
11966
|
+
logger21.info(
|
|
10923
11967
|
{ duration: updateTaskEnd - updateTaskStart },
|
|
10924
11968
|
"Completed updateTask operation"
|
|
10925
11969
|
);
|
|
10926
11970
|
await sseHelper.writeOperation(completionOp(currentAgentId, iterations));
|
|
10927
11971
|
await sseHelper.complete();
|
|
10928
|
-
|
|
11972
|
+
logger21.info({}, "Ending AgentSession and cleaning up");
|
|
10929
11973
|
await agentSessionManager.endSession(requestId2);
|
|
10930
|
-
|
|
11974
|
+
logger21.info({}, "Cleaning up streamHelper");
|
|
10931
11975
|
unregisterStreamHelper(requestId2);
|
|
10932
11976
|
let response;
|
|
10933
11977
|
if (sseHelper instanceof BufferingStreamHelper) {
|
|
10934
11978
|
const captured = sseHelper.getCapturedResponse();
|
|
10935
11979
|
response = captured.text || "No response content";
|
|
10936
11980
|
}
|
|
10937
|
-
|
|
11981
|
+
logger21.info({}, "ExecutionHandler returning success");
|
|
10938
11982
|
return { success: true, iterations, response };
|
|
10939
11983
|
} catch (error) {
|
|
10940
11984
|
setSpanWithError(span, error instanceof Error ? error : new Error(String(error)));
|
|
@@ -10945,13 +11989,13 @@ var ExecutionHandler = class {
|
|
|
10945
11989
|
});
|
|
10946
11990
|
}
|
|
10947
11991
|
errorCount++;
|
|
10948
|
-
|
|
11992
|
+
logger21.warn(
|
|
10949
11993
|
{ iterations, errorCount },
|
|
10950
11994
|
`No valid response or transfer on iteration ${iterations} (error ${errorCount}/${this.MAX_ERRORS})`
|
|
10951
11995
|
);
|
|
10952
11996
|
if (errorCount >= this.MAX_ERRORS) {
|
|
10953
11997
|
const errorMessage2 = `Maximum error limit (${this.MAX_ERRORS}) reached`;
|
|
10954
|
-
|
|
11998
|
+
logger21.error({ maxErrors: this.MAX_ERRORS, errorCount }, errorMessage2);
|
|
10955
11999
|
await sseHelper.writeOperation(errorOp(errorMessage2, currentAgentId || "system"));
|
|
10956
12000
|
if (task) {
|
|
10957
12001
|
await updateTask(dbClient_default)({
|
|
@@ -10972,7 +12016,7 @@ var ExecutionHandler = class {
|
|
|
10972
12016
|
}
|
|
10973
12017
|
}
|
|
10974
12018
|
const errorMessage = `Maximum transfer limit (${maxTransfers}) reached without completion`;
|
|
10975
|
-
|
|
12019
|
+
logger21.error({ maxTransfers, iterations }, errorMessage);
|
|
10976
12020
|
await sseHelper.writeOperation(errorOp(errorMessage, currentAgentId || "system"));
|
|
10977
12021
|
if (task) {
|
|
10978
12022
|
await updateTask(dbClient_default)({
|
|
@@ -10991,7 +12035,7 @@ var ExecutionHandler = class {
|
|
|
10991
12035
|
unregisterStreamHelper(requestId2);
|
|
10992
12036
|
return { success: false, error: errorMessage, iterations };
|
|
10993
12037
|
} catch (error) {
|
|
10994
|
-
|
|
12038
|
+
logger21.error({ error }, "Error in execution handler");
|
|
10995
12039
|
const errorMessage = error instanceof Error ? error.message : "Unknown execution error";
|
|
10996
12040
|
await sseHelper.writeOperation(
|
|
10997
12041
|
errorOp(`Execution error: ${errorMessage}`, currentAgentId || "system")
|
|
@@ -11018,7 +12062,7 @@ var ExecutionHandler = class {
|
|
|
11018
12062
|
|
|
11019
12063
|
// src/routes/chat.ts
|
|
11020
12064
|
var app2 = new OpenAPIHono();
|
|
11021
|
-
var
|
|
12065
|
+
var logger22 = getLogger("completionsHandler");
|
|
11022
12066
|
var chatCompletionsRoute = createRoute({
|
|
11023
12067
|
method: "post",
|
|
11024
12068
|
path: "/completions",
|
|
@@ -11030,36 +12074,36 @@ var chatCompletionsRoute = createRoute({
|
|
|
11030
12074
|
body: {
|
|
11031
12075
|
content: {
|
|
11032
12076
|
"application/json": {
|
|
11033
|
-
schema: z.object({
|
|
11034
|
-
model: z.string().describe("The model to use for the completion"),
|
|
11035
|
-
messages: z.array(
|
|
11036
|
-
z.object({
|
|
11037
|
-
role: z.enum(["system", "user", "assistant", "function", "tool"]).describe("The role of the message"),
|
|
11038
|
-
content: z.union([
|
|
11039
|
-
z.string(),
|
|
11040
|
-
z.array(
|
|
11041
|
-
z.strictObject({
|
|
11042
|
-
type: z.string(),
|
|
11043
|
-
text: z.string().optional()
|
|
12077
|
+
schema: z$1.object({
|
|
12078
|
+
model: z$1.string().describe("The model to use for the completion"),
|
|
12079
|
+
messages: z$1.array(
|
|
12080
|
+
z$1.object({
|
|
12081
|
+
role: z$1.enum(["system", "user", "assistant", "function", "tool"]).describe("The role of the message"),
|
|
12082
|
+
content: z$1.union([
|
|
12083
|
+
z$1.string(),
|
|
12084
|
+
z$1.array(
|
|
12085
|
+
z$1.strictObject({
|
|
12086
|
+
type: z$1.string(),
|
|
12087
|
+
text: z$1.string().optional()
|
|
11044
12088
|
})
|
|
11045
12089
|
)
|
|
11046
12090
|
]).describe("The message content"),
|
|
11047
|
-
name: z.string().optional().describe("The name of the message sender")
|
|
12091
|
+
name: z$1.string().optional().describe("The name of the message sender")
|
|
11048
12092
|
})
|
|
11049
12093
|
).describe("The conversation messages"),
|
|
11050
|
-
temperature: z.number().optional().describe("Controls randomness (0-1)"),
|
|
11051
|
-
top_p: z.number().optional().describe("Controls nucleus sampling"),
|
|
11052
|
-
n: z.number().optional().describe("Number of completions to generate"),
|
|
11053
|
-
stream: z.boolean().optional().describe("Whether to stream the response"),
|
|
11054
|
-
max_tokens: z.number().optional().describe("Maximum tokens to generate"),
|
|
11055
|
-
presence_penalty: z.number().optional().describe("Presence penalty (-2 to 2)"),
|
|
11056
|
-
frequency_penalty: z.number().optional().describe("Frequency penalty (-2 to 2)"),
|
|
11057
|
-
logit_bias: z.record(z.string(), z.number()).optional().describe("Token logit bias"),
|
|
11058
|
-
user: z.string().optional().describe("User identifier"),
|
|
11059
|
-
conversationId: z.string().optional().describe("Conversation ID for multi-turn chat"),
|
|
11060
|
-
tools: z.array(z.string()).optional().describe("Available tools"),
|
|
11061
|
-
runConfig: z.record(z.string(), z.unknown()).optional().describe("Run configuration"),
|
|
11062
|
-
headers: z.record(z.string(), z.unknown()).optional().describe(
|
|
12094
|
+
temperature: z$1.number().optional().describe("Controls randomness (0-1)"),
|
|
12095
|
+
top_p: z$1.number().optional().describe("Controls nucleus sampling"),
|
|
12096
|
+
n: z$1.number().optional().describe("Number of completions to generate"),
|
|
12097
|
+
stream: z$1.boolean().optional().describe("Whether to stream the response"),
|
|
12098
|
+
max_tokens: z$1.number().optional().describe("Maximum tokens to generate"),
|
|
12099
|
+
presence_penalty: z$1.number().optional().describe("Presence penalty (-2 to 2)"),
|
|
12100
|
+
frequency_penalty: z$1.number().optional().describe("Frequency penalty (-2 to 2)"),
|
|
12101
|
+
logit_bias: z$1.record(z$1.string(), z$1.number()).optional().describe("Token logit bias"),
|
|
12102
|
+
user: z$1.string().optional().describe("User identifier"),
|
|
12103
|
+
conversationId: z$1.string().optional().describe("Conversation ID for multi-turn chat"),
|
|
12104
|
+
tools: z$1.array(z$1.string()).optional().describe("Available tools"),
|
|
12105
|
+
runConfig: z$1.record(z$1.string(), z$1.unknown()).optional().describe("Run configuration"),
|
|
12106
|
+
headers: z$1.record(z$1.string(), z$1.unknown()).optional().describe(
|
|
11063
12107
|
"Headers data for template processing (validated against context config schema)"
|
|
11064
12108
|
)
|
|
11065
12109
|
})
|
|
@@ -11070,14 +12114,14 @@ var chatCompletionsRoute = createRoute({
|
|
|
11070
12114
|
responses: {
|
|
11071
12115
|
200: {
|
|
11072
12116
|
description: "Streaming chat completion response in Server-Sent Events format",
|
|
11073
|
-
headers: z.object({
|
|
11074
|
-
"Content-Type": z.string().default("text/event-stream"),
|
|
11075
|
-
"Cache-Control": z.string().default("no-cache"),
|
|
11076
|
-
Connection: z.string().default("keep-alive")
|
|
12117
|
+
headers: z$1.object({
|
|
12118
|
+
"Content-Type": z$1.string().default("text/event-stream"),
|
|
12119
|
+
"Cache-Control": z$1.string().default("no-cache"),
|
|
12120
|
+
Connection: z$1.string().default("keep-alive")
|
|
11077
12121
|
}),
|
|
11078
12122
|
content: {
|
|
11079
12123
|
"text/event-stream": {
|
|
11080
|
-
schema: z.string().describe("Server-Sent Events stream with chat completion chunks")
|
|
12124
|
+
schema: z$1.string().describe("Server-Sent Events stream with chat completion chunks")
|
|
11081
12125
|
}
|
|
11082
12126
|
}
|
|
11083
12127
|
},
|
|
@@ -11085,13 +12129,13 @@ var chatCompletionsRoute = createRoute({
|
|
|
11085
12129
|
description: "Invalid request context or parameters",
|
|
11086
12130
|
content: {
|
|
11087
12131
|
"application/json": {
|
|
11088
|
-
schema: z.object({
|
|
11089
|
-
error: z.string(),
|
|
11090
|
-
details: z.array(
|
|
11091
|
-
z.object({
|
|
11092
|
-
field: z.string(),
|
|
11093
|
-
message: z.string(),
|
|
11094
|
-
value: z.unknown().optional()
|
|
12132
|
+
schema: z$1.object({
|
|
12133
|
+
error: z$1.string(),
|
|
12134
|
+
details: z$1.array(
|
|
12135
|
+
z$1.object({
|
|
12136
|
+
field: z$1.string(),
|
|
12137
|
+
message: z$1.string(),
|
|
12138
|
+
value: z$1.unknown().optional()
|
|
11095
12139
|
})
|
|
11096
12140
|
).optional()
|
|
11097
12141
|
})
|
|
@@ -11102,8 +12146,8 @@ var chatCompletionsRoute = createRoute({
|
|
|
11102
12146
|
description: "Agent or agent not found",
|
|
11103
12147
|
content: {
|
|
11104
12148
|
"application/json": {
|
|
11105
|
-
schema: z.object({
|
|
11106
|
-
error: z.string()
|
|
12149
|
+
schema: z$1.object({
|
|
12150
|
+
error: z$1.string()
|
|
11107
12151
|
})
|
|
11108
12152
|
}
|
|
11109
12153
|
}
|
|
@@ -11112,9 +12156,9 @@ var chatCompletionsRoute = createRoute({
|
|
|
11112
12156
|
description: "Internal server error",
|
|
11113
12157
|
content: {
|
|
11114
12158
|
"application/json": {
|
|
11115
|
-
schema: z.object({
|
|
11116
|
-
error: z.string(),
|
|
11117
|
-
message: z.string()
|
|
12159
|
+
schema: z$1.object({
|
|
12160
|
+
error: z$1.string(),
|
|
12161
|
+
message: z$1.string()
|
|
11118
12162
|
})
|
|
11119
12163
|
}
|
|
11120
12164
|
}
|
|
@@ -11136,7 +12180,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
11136
12180
|
tracestate: c.req.header("tracestate"),
|
|
11137
12181
|
baggage: c.req.header("baggage")
|
|
11138
12182
|
};
|
|
11139
|
-
|
|
12183
|
+
logger22.info(
|
|
11140
12184
|
{
|
|
11141
12185
|
otelHeaders,
|
|
11142
12186
|
path: c.req.path,
|
|
@@ -11245,7 +12289,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
11245
12289
|
dbClient: dbClient_default,
|
|
11246
12290
|
credentialStores
|
|
11247
12291
|
});
|
|
11248
|
-
|
|
12292
|
+
logger22.info(
|
|
11249
12293
|
{
|
|
11250
12294
|
tenantId,
|
|
11251
12295
|
projectId,
|
|
@@ -11293,7 +12337,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
11293
12337
|
try {
|
|
11294
12338
|
const sseHelper = createSSEStreamHelper(stream2, requestId2, timestamp);
|
|
11295
12339
|
await sseHelper.writeRole();
|
|
11296
|
-
|
|
12340
|
+
logger22.info({ subAgentId }, "Starting execution");
|
|
11297
12341
|
const emitOperationsHeader = c.req.header("x-emit-operations");
|
|
11298
12342
|
const emitOperations = emitOperationsHeader === "true";
|
|
11299
12343
|
const executionHandler = new ExecutionHandler();
|
|
@@ -11306,7 +12350,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
11306
12350
|
sseHelper,
|
|
11307
12351
|
emitOperations
|
|
11308
12352
|
});
|
|
11309
|
-
|
|
12353
|
+
logger22.info(
|
|
11310
12354
|
{ result },
|
|
11311
12355
|
`Execution completed: ${result.success ? "success" : "failed"} after ${result.iterations} iterations`
|
|
11312
12356
|
);
|
|
@@ -11320,7 +12364,7 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
11320
12364
|
}
|
|
11321
12365
|
await sseHelper.complete();
|
|
11322
12366
|
} catch (error) {
|
|
11323
|
-
|
|
12367
|
+
logger22.error(
|
|
11324
12368
|
{
|
|
11325
12369
|
error: error instanceof Error ? error.message : error,
|
|
11326
12370
|
stack: error instanceof Error ? error.stack : void 0
|
|
@@ -11337,13 +12381,13 @@ app2.openapi(chatCompletionsRoute, async (c) => {
|
|
|
11337
12381
|
);
|
|
11338
12382
|
await sseHelper.complete();
|
|
11339
12383
|
} catch (streamError) {
|
|
11340
|
-
|
|
12384
|
+
logger22.error({ streamError }, "Failed to write error to stream");
|
|
11341
12385
|
}
|
|
11342
12386
|
}
|
|
11343
12387
|
});
|
|
11344
12388
|
});
|
|
11345
12389
|
} catch (error) {
|
|
11346
|
-
|
|
12390
|
+
logger22.error(
|
|
11347
12391
|
{
|
|
11348
12392
|
error: error instanceof Error ? error.message : error,
|
|
11349
12393
|
stack: error instanceof Error ? error.stack : void 0
|
|
@@ -11367,7 +12411,7 @@ var getMessageText = (content) => {
|
|
|
11367
12411
|
};
|
|
11368
12412
|
var chat_default = app2;
|
|
11369
12413
|
var app3 = new OpenAPIHono();
|
|
11370
|
-
var
|
|
12414
|
+
var logger23 = getLogger("chatDataStream");
|
|
11371
12415
|
var chatDataStreamRoute = createRoute({
|
|
11372
12416
|
method: "post",
|
|
11373
12417
|
path: "/chat",
|
|
@@ -11379,29 +12423,29 @@ var chatDataStreamRoute = createRoute({
|
|
|
11379
12423
|
body: {
|
|
11380
12424
|
content: {
|
|
11381
12425
|
"application/json": {
|
|
11382
|
-
schema: z.object({
|
|
11383
|
-
model: z.string().optional(),
|
|
11384
|
-
messages: z.array(
|
|
11385
|
-
z.object({
|
|
11386
|
-
role: z.enum(["system", "user", "assistant", "function", "tool"]),
|
|
11387
|
-
content: z.any(),
|
|
11388
|
-
parts: z.array(
|
|
11389
|
-
z.object({
|
|
11390
|
-
type: z.union([
|
|
11391
|
-
z.enum(["text", "image", "audio", "video", "file"]),
|
|
11392
|
-
z.string().regex(/^data-/, 'Type must start with "data-"')
|
|
12426
|
+
schema: z$1.object({
|
|
12427
|
+
model: z$1.string().optional(),
|
|
12428
|
+
messages: z$1.array(
|
|
12429
|
+
z$1.object({
|
|
12430
|
+
role: z$1.enum(["system", "user", "assistant", "function", "tool"]),
|
|
12431
|
+
content: z$1.any(),
|
|
12432
|
+
parts: z$1.array(
|
|
12433
|
+
z$1.object({
|
|
12434
|
+
type: z$1.union([
|
|
12435
|
+
z$1.enum(["text", "image", "audio", "video", "file"]),
|
|
12436
|
+
z$1.string().regex(/^data-/, 'Type must start with "data-"')
|
|
11393
12437
|
]),
|
|
11394
|
-
text: z.string().optional()
|
|
12438
|
+
text: z$1.string().optional()
|
|
11395
12439
|
})
|
|
11396
12440
|
).optional()
|
|
11397
12441
|
})
|
|
11398
12442
|
),
|
|
11399
|
-
id: z.string().optional(),
|
|
11400
|
-
conversationId: z.string().optional(),
|
|
11401
|
-
stream: z.boolean().optional().describe("Whether to stream the response").default(true),
|
|
11402
|
-
max_tokens: z.number().optional().describe("Maximum tokens to generate"),
|
|
11403
|
-
headers: z.record(z.string(), z.unknown()).optional().describe("Headers data for template processing"),
|
|
11404
|
-
runConfig: z.record(z.string(), z.unknown()).optional().describe("Run configuration")
|
|
12443
|
+
id: z$1.string().optional(),
|
|
12444
|
+
conversationId: z$1.string().optional(),
|
|
12445
|
+
stream: z$1.boolean().optional().describe("Whether to stream the response").default(true),
|
|
12446
|
+
max_tokens: z$1.number().optional().describe("Maximum tokens to generate"),
|
|
12447
|
+
headers: z$1.record(z$1.string(), z$1.unknown()).optional().describe("Headers data for template processing"),
|
|
12448
|
+
runConfig: z$1.record(z$1.string(), z$1.unknown()).optional().describe("Run configuration")
|
|
11405
12449
|
})
|
|
11406
12450
|
}
|
|
11407
12451
|
}
|
|
@@ -11410,9 +12454,9 @@ var chatDataStreamRoute = createRoute({
|
|
|
11410
12454
|
responses: {
|
|
11411
12455
|
200: {
|
|
11412
12456
|
description: "Streamed chat completion",
|
|
11413
|
-
headers: z.object({
|
|
11414
|
-
"Content-Type": z.string().default("text/plain; charset=utf-8"),
|
|
11415
|
-
"x-vercel-ai-data-stream": z.string().default("v1")
|
|
12457
|
+
headers: z$1.object({
|
|
12458
|
+
"Content-Type": z$1.string().default("text/plain; charset=utf-8"),
|
|
12459
|
+
"x-vercel-ai-data-stream": z$1.string().default("v1")
|
|
11416
12460
|
})
|
|
11417
12461
|
},
|
|
11418
12462
|
...commonGetErrorResponses
|
|
@@ -11494,7 +12538,7 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
11494
12538
|
});
|
|
11495
12539
|
const lastUserMessage = body.messages.filter((m) => m.role === "user").slice(-1)[0];
|
|
11496
12540
|
const userText = typeof lastUserMessage?.content === "string" ? lastUserMessage.content : lastUserMessage?.parts?.map((p) => p.text).join("") || "";
|
|
11497
|
-
|
|
12541
|
+
logger23.info({ userText, lastUserMessage }, "userText");
|
|
11498
12542
|
const messageSpan = trace.getActiveSpan();
|
|
11499
12543
|
if (messageSpan) {
|
|
11500
12544
|
messageSpan.setAttributes({
|
|
@@ -11577,7 +12621,7 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
11577
12621
|
await streamHelper.writeOperation(errorOp("Unable to process request", "system"));
|
|
11578
12622
|
}
|
|
11579
12623
|
} catch (err) {
|
|
11580
|
-
|
|
12624
|
+
logger23.error({ err }, "Streaming error");
|
|
11581
12625
|
await streamHelper.writeOperation(errorOp("Internal server error", "system"));
|
|
11582
12626
|
} finally {
|
|
11583
12627
|
if ("cleanup" in streamHelper && typeof streamHelper.cleanup === "function") {
|
|
@@ -11599,7 +12643,7 @@ app3.openapi(chatDataStreamRoute, async (c) => {
|
|
|
11599
12643
|
);
|
|
11600
12644
|
});
|
|
11601
12645
|
} catch (error) {
|
|
11602
|
-
|
|
12646
|
+
logger23.error(
|
|
11603
12647
|
{
|
|
11604
12648
|
error,
|
|
11605
12649
|
errorMessage: error instanceof Error ? error.message : String(error),
|
|
@@ -11625,11 +12669,11 @@ var toolApprovalRoute = createRoute({
|
|
|
11625
12669
|
body: {
|
|
11626
12670
|
content: {
|
|
11627
12671
|
"application/json": {
|
|
11628
|
-
schema: z.object({
|
|
11629
|
-
conversationId: z.string().describe("The conversation ID"),
|
|
11630
|
-
toolCallId: z.string().describe("The tool call ID to respond to"),
|
|
11631
|
-
approved: z.boolean().describe("Whether the tool execution is approved"),
|
|
11632
|
-
reason: z.string().optional().describe("Optional reason for the decision")
|
|
12672
|
+
schema: z$1.object({
|
|
12673
|
+
conversationId: z$1.string().describe("The conversation ID"),
|
|
12674
|
+
toolCallId: z$1.string().describe("The tool call ID to respond to"),
|
|
12675
|
+
approved: z$1.boolean().describe("Whether the tool execution is approved"),
|
|
12676
|
+
reason: z$1.string().optional().describe("Optional reason for the decision")
|
|
11633
12677
|
})
|
|
11634
12678
|
}
|
|
11635
12679
|
}
|
|
@@ -11640,9 +12684,9 @@ var toolApprovalRoute = createRoute({
|
|
|
11640
12684
|
description: "Tool approval response processed successfully",
|
|
11641
12685
|
content: {
|
|
11642
12686
|
"application/json": {
|
|
11643
|
-
schema: z.object({
|
|
11644
|
-
success: z.boolean(),
|
|
11645
|
-
message: z.string().optional()
|
|
12687
|
+
schema: z$1.object({
|
|
12688
|
+
success: z$1.boolean(),
|
|
12689
|
+
message: z$1.string().optional()
|
|
11646
12690
|
})
|
|
11647
12691
|
}
|
|
11648
12692
|
}
|
|
@@ -11651,8 +12695,8 @@ var toolApprovalRoute = createRoute({
|
|
|
11651
12695
|
description: "Bad request - invalid tool call ID or conversation ID",
|
|
11652
12696
|
content: {
|
|
11653
12697
|
"application/json": {
|
|
11654
|
-
schema: z.object({
|
|
11655
|
-
error: z.string()
|
|
12698
|
+
schema: z$1.object({
|
|
12699
|
+
error: z$1.string()
|
|
11656
12700
|
})
|
|
11657
12701
|
}
|
|
11658
12702
|
}
|
|
@@ -11661,8 +12705,8 @@ var toolApprovalRoute = createRoute({
|
|
|
11661
12705
|
description: "Tool call not found or already processed",
|
|
11662
12706
|
content: {
|
|
11663
12707
|
"application/json": {
|
|
11664
|
-
schema: z.object({
|
|
11665
|
-
error: z.string()
|
|
12708
|
+
schema: z$1.object({
|
|
12709
|
+
error: z$1.string()
|
|
11666
12710
|
})
|
|
11667
12711
|
}
|
|
11668
12712
|
}
|
|
@@ -11671,9 +12715,9 @@ var toolApprovalRoute = createRoute({
|
|
|
11671
12715
|
description: "Internal server error",
|
|
11672
12716
|
content: {
|
|
11673
12717
|
"application/json": {
|
|
11674
|
-
schema: z.object({
|
|
11675
|
-
error: z.string(),
|
|
11676
|
-
message: z.string()
|
|
12718
|
+
schema: z$1.object({
|
|
12719
|
+
error: z$1.string(),
|
|
12720
|
+
message: z$1.string()
|
|
11677
12721
|
})
|
|
11678
12722
|
}
|
|
11679
12723
|
}
|
|
@@ -11688,7 +12732,7 @@ app3.openapi(toolApprovalRoute, async (c) => {
|
|
|
11688
12732
|
const { tenantId, projectId } = executionContext;
|
|
11689
12733
|
const requestBody = await c.req.json();
|
|
11690
12734
|
const { conversationId, toolCallId, approved, reason } = requestBody;
|
|
11691
|
-
|
|
12735
|
+
logger23.info(
|
|
11692
12736
|
{
|
|
11693
12737
|
conversationId,
|
|
11694
12738
|
toolCallId,
|
|
@@ -11717,7 +12761,7 @@ app3.openapi(toolApprovalRoute, async (c) => {
|
|
|
11717
12761
|
span.setStatus({ code: 1, message: "Tool call not found" });
|
|
11718
12762
|
return c.json({ error: "Tool call not found or already processed" }, 404);
|
|
11719
12763
|
}
|
|
11720
|
-
|
|
12764
|
+
logger23.info({ conversationId, toolCallId, approved }, "Tool approval processed successfully");
|
|
11721
12765
|
span.setStatus({ code: 1, message: "Success" });
|
|
11722
12766
|
return c.json({
|
|
11723
12767
|
success: true,
|
|
@@ -11725,7 +12769,7 @@ app3.openapi(toolApprovalRoute, async (c) => {
|
|
|
11725
12769
|
});
|
|
11726
12770
|
} catch (error) {
|
|
11727
12771
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
11728
|
-
|
|
12772
|
+
logger23.error(
|
|
11729
12773
|
{
|
|
11730
12774
|
error: errorMessage,
|
|
11731
12775
|
stack: error instanceof Error ? error.stack : void 0
|
|
@@ -11746,7 +12790,7 @@ app3.openapi(toolApprovalRoute, async (c) => {
|
|
|
11746
12790
|
});
|
|
11747
12791
|
});
|
|
11748
12792
|
var chatDataStream_default = app3;
|
|
11749
|
-
var
|
|
12793
|
+
var logger24 = getLogger("mcp");
|
|
11750
12794
|
var MockResponseSingleton = class _MockResponseSingleton {
|
|
11751
12795
|
static instance;
|
|
11752
12796
|
mockRes;
|
|
@@ -11800,21 +12844,21 @@ var createSpoofInitMessage = (mcpProtocolVersion) => ({
|
|
|
11800
12844
|
id: 0
|
|
11801
12845
|
});
|
|
11802
12846
|
var spoofTransportInitialization = async (transport, req, sessionId, mcpProtocolVersion) => {
|
|
11803
|
-
|
|
12847
|
+
logger24.info({ sessionId }, "Spoofing initialization message to set transport state");
|
|
11804
12848
|
const spoofInitMessage = createSpoofInitMessage(mcpProtocolVersion);
|
|
11805
12849
|
const mockRes = MockResponseSingleton.getInstance().getMockResponse();
|
|
11806
12850
|
try {
|
|
11807
12851
|
await transport.handleRequest(req, mockRes, spoofInitMessage);
|
|
11808
|
-
|
|
12852
|
+
logger24.info({ sessionId }, "Successfully spoofed initialization");
|
|
11809
12853
|
} catch (spoofError) {
|
|
11810
|
-
|
|
12854
|
+
logger24.warn({ sessionId, error: spoofError }, "Spoof initialization failed, continuing anyway");
|
|
11811
12855
|
}
|
|
11812
12856
|
};
|
|
11813
12857
|
var validateSession = async (req, res, body, tenantId, projectId, agentId) => {
|
|
11814
12858
|
const sessionId = req.headers["mcp-session-id"];
|
|
11815
|
-
|
|
12859
|
+
logger24.info({ sessionId }, "Received MCP session ID");
|
|
11816
12860
|
if (!sessionId) {
|
|
11817
|
-
|
|
12861
|
+
logger24.info({ body }, "Missing session ID");
|
|
11818
12862
|
res.writeHead(400).end(
|
|
11819
12863
|
JSON.stringify({
|
|
11820
12864
|
jsonrpc: "2.0",
|
|
@@ -11841,7 +12885,7 @@ var validateSession = async (req, res, body, tenantId, projectId, agentId) => {
|
|
|
11841
12885
|
scopes: { tenantId, projectId },
|
|
11842
12886
|
conversationId: sessionId
|
|
11843
12887
|
});
|
|
11844
|
-
|
|
12888
|
+
logger24.info(
|
|
11845
12889
|
{
|
|
11846
12890
|
sessionId,
|
|
11847
12891
|
conversationFound: !!conversation,
|
|
@@ -11852,7 +12896,7 @@ var validateSession = async (req, res, body, tenantId, projectId, agentId) => {
|
|
|
11852
12896
|
"Conversation lookup result"
|
|
11853
12897
|
);
|
|
11854
12898
|
if (!conversation || conversation.metadata?.sessionData?.sessionType !== "mcp" || conversation.metadata?.sessionData?.agentId !== agentId) {
|
|
11855
|
-
|
|
12899
|
+
logger24.info(
|
|
11856
12900
|
{ sessionId, conversationId: conversation?.id },
|
|
11857
12901
|
"MCP session not found or invalid"
|
|
11858
12902
|
);
|
|
@@ -11913,7 +12957,7 @@ var executeAgentQuery = async (executionContext, conversationId, query, defaultS
|
|
|
11913
12957
|
requestId: requestId2,
|
|
11914
12958
|
sseHelper: mcpStreamHelper
|
|
11915
12959
|
});
|
|
11916
|
-
|
|
12960
|
+
logger24.info(
|
|
11917
12961
|
{ result },
|
|
11918
12962
|
`Execution completed: ${result.success ? "success" : "failed"} after ${result.iterations} iterations`
|
|
11919
12963
|
);
|
|
@@ -11957,7 +13001,7 @@ var getServer = async (headers2, executionContext, conversationId, credentialSto
|
|
|
11957
13001
|
"send-query-to-agent",
|
|
11958
13002
|
`Send a query to the ${agent.name} agent. The agent has the following description: ${agent.description}`,
|
|
11959
13003
|
{
|
|
11960
|
-
query: z.string().describe("The query to send to the agent")
|
|
13004
|
+
query: z$1.string().describe("The query to send to the agent")
|
|
11961
13005
|
},
|
|
11962
13006
|
async ({ query }) => {
|
|
11963
13007
|
try {
|
|
@@ -11997,7 +13041,7 @@ var getServer = async (headers2, executionContext, conversationId, credentialSto
|
|
|
11997
13041
|
dbClient: dbClient_default,
|
|
11998
13042
|
credentialStores
|
|
11999
13043
|
});
|
|
12000
|
-
|
|
13044
|
+
logger24.info(
|
|
12001
13045
|
{
|
|
12002
13046
|
tenantId,
|
|
12003
13047
|
projectId,
|
|
@@ -12059,7 +13103,7 @@ var validateRequestParameters = (c) => {
|
|
|
12059
13103
|
};
|
|
12060
13104
|
var handleInitializationRequest = async (body, executionContext, validatedContext, req, res, c, credentialStores) => {
|
|
12061
13105
|
const { tenantId, projectId, agentId } = executionContext;
|
|
12062
|
-
|
|
13106
|
+
logger24.info({ body }, "Received initialization request");
|
|
12063
13107
|
const sessionId = getConversationId();
|
|
12064
13108
|
const activeSpan = trace.getActiveSpan();
|
|
12065
13109
|
if (activeSpan) {
|
|
@@ -12115,7 +13159,7 @@ var handleInitializationRequest = async (body, executionContext, validatedContex
|
|
|
12115
13159
|
}
|
|
12116
13160
|
}
|
|
12117
13161
|
});
|
|
12118
|
-
|
|
13162
|
+
logger24.info(
|
|
12119
13163
|
{ sessionId, conversationId: conversation.id },
|
|
12120
13164
|
"Created MCP session as conversation"
|
|
12121
13165
|
);
|
|
@@ -12124,9 +13168,9 @@ var handleInitializationRequest = async (body, executionContext, validatedContex
|
|
|
12124
13168
|
});
|
|
12125
13169
|
const server = await getServer(validatedContext, executionContext, sessionId, credentialStores);
|
|
12126
13170
|
await server.connect(transport);
|
|
12127
|
-
|
|
13171
|
+
logger24.info({ sessionId }, "Server connected for initialization");
|
|
12128
13172
|
res.setHeader("Mcp-Session-Id", sessionId);
|
|
12129
|
-
|
|
13173
|
+
logger24.info(
|
|
12130
13174
|
{
|
|
12131
13175
|
sessionId,
|
|
12132
13176
|
bodyMethod: body?.method,
|
|
@@ -12135,7 +13179,7 @@ var handleInitializationRequest = async (body, executionContext, validatedContex
|
|
|
12135
13179
|
"About to handle initialization request"
|
|
12136
13180
|
);
|
|
12137
13181
|
await transport.handleRequest(req, res, body);
|
|
12138
|
-
|
|
13182
|
+
logger24.info({ sessionId }, "Successfully handled initialization request");
|
|
12139
13183
|
return toFetchResponse(res);
|
|
12140
13184
|
});
|
|
12141
13185
|
};
|
|
@@ -12162,8 +13206,8 @@ var handleExistingSessionRequest = async (body, executionContext, validatedConte
|
|
|
12162
13206
|
sessionId,
|
|
12163
13207
|
conversation.metadata?.session_data?.mcpProtocolVersion
|
|
12164
13208
|
);
|
|
12165
|
-
|
|
12166
|
-
|
|
13209
|
+
logger24.info({ sessionId }, "Server connected and transport initialized");
|
|
13210
|
+
logger24.info(
|
|
12167
13211
|
{
|
|
12168
13212
|
sessionId,
|
|
12169
13213
|
bodyKeys: Object.keys(body || {}),
|
|
@@ -12177,9 +13221,9 @@ var handleExistingSessionRequest = async (body, executionContext, validatedConte
|
|
|
12177
13221
|
);
|
|
12178
13222
|
try {
|
|
12179
13223
|
await transport.handleRequest(req, res, body);
|
|
12180
|
-
|
|
13224
|
+
logger24.info({ sessionId }, "Successfully handled MCP request");
|
|
12181
13225
|
} catch (transportError) {
|
|
12182
|
-
|
|
13226
|
+
logger24.error(
|
|
12183
13227
|
{
|
|
12184
13228
|
sessionId,
|
|
12185
13229
|
error: transportError,
|
|
@@ -12230,13 +13274,13 @@ app4.openapi(
|
|
|
12230
13274
|
}
|
|
12231
13275
|
const { executionContext } = paramValidation;
|
|
12232
13276
|
const body = c.get("requestBody") || {};
|
|
12233
|
-
|
|
13277
|
+
logger24.info({ body, bodyKeys: Object.keys(body || {}) }, "Parsed request body");
|
|
12234
13278
|
const isInitRequest = body.method === "initialize";
|
|
12235
13279
|
const { req, res } = toReqRes(c.req.raw);
|
|
12236
13280
|
const validatedContext = c.get("validatedContext") || {};
|
|
12237
13281
|
const credentialStores = c.get("credentialStores");
|
|
12238
|
-
|
|
12239
|
-
|
|
13282
|
+
logger24.info({ validatedContext }, "Validated context");
|
|
13283
|
+
logger24.info({ req }, "request");
|
|
12240
13284
|
if (isInitRequest) {
|
|
12241
13285
|
return await handleInitializationRequest(
|
|
12242
13286
|
body,
|
|
@@ -12257,7 +13301,7 @@ app4.openapi(
|
|
|
12257
13301
|
credentialStores
|
|
12258
13302
|
);
|
|
12259
13303
|
} catch (e) {
|
|
12260
|
-
|
|
13304
|
+
logger24.error(
|
|
12261
13305
|
{
|
|
12262
13306
|
error: e instanceof Error ? e.message : e,
|
|
12263
13307
|
stack: e instanceof Error ? e.stack : void 0
|
|
@@ -12269,7 +13313,7 @@ app4.openapi(
|
|
|
12269
13313
|
}
|
|
12270
13314
|
);
|
|
12271
13315
|
app4.get("/", async (c) => {
|
|
12272
|
-
|
|
13316
|
+
logger24.info({}, "Received GET MCP request");
|
|
12273
13317
|
return c.json(
|
|
12274
13318
|
{
|
|
12275
13319
|
jsonrpc: "2.0",
|
|
@@ -12283,7 +13327,7 @@ app4.get("/", async (c) => {
|
|
|
12283
13327
|
);
|
|
12284
13328
|
});
|
|
12285
13329
|
app4.delete("/", async (c) => {
|
|
12286
|
-
|
|
13330
|
+
logger24.info({}, "Received DELETE MCP request");
|
|
12287
13331
|
return c.json(
|
|
12288
13332
|
{
|
|
12289
13333
|
jsonrpc: "2.0",
|
|
@@ -12296,7 +13340,7 @@ app4.delete("/", async (c) => {
|
|
|
12296
13340
|
var mcp_default = app4;
|
|
12297
13341
|
|
|
12298
13342
|
// src/app.ts
|
|
12299
|
-
var
|
|
13343
|
+
var logger25 = getLogger("agents-run-api");
|
|
12300
13344
|
function createExecutionHono(serverConfig, credentialStores, sandboxConfig) {
|
|
12301
13345
|
const app6 = new OpenAPIHono();
|
|
12302
13346
|
app6.use("*", otel());
|
|
@@ -12315,7 +13359,7 @@ function createExecutionHono(serverConfig, credentialStores, sandboxConfig) {
|
|
|
12315
13359
|
const body = await c.req.json();
|
|
12316
13360
|
c.set("requestBody", body);
|
|
12317
13361
|
} catch (error) {
|
|
12318
|
-
|
|
13362
|
+
logger25.debug({ error }, "Failed to parse JSON body, continuing without parsed body");
|
|
12319
13363
|
}
|
|
12320
13364
|
}
|
|
12321
13365
|
return next();
|
|
@@ -12366,8 +13410,8 @@ function createExecutionHono(serverConfig, credentialStores, sandboxConfig) {
|
|
|
12366
13410
|
if (!isExpectedError) {
|
|
12367
13411
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
12368
13412
|
const errorStack = err instanceof Error ? err.stack : void 0;
|
|
12369
|
-
if (
|
|
12370
|
-
|
|
13413
|
+
if (logger25) {
|
|
13414
|
+
logger25.error(
|
|
12371
13415
|
{
|
|
12372
13416
|
error: err,
|
|
12373
13417
|
message: errorMessage,
|
|
@@ -12379,8 +13423,8 @@ function createExecutionHono(serverConfig, credentialStores, sandboxConfig) {
|
|
|
12379
13423
|
);
|
|
12380
13424
|
}
|
|
12381
13425
|
} else {
|
|
12382
|
-
if (
|
|
12383
|
-
|
|
13426
|
+
if (logger25) {
|
|
13427
|
+
logger25.error(
|
|
12384
13428
|
{
|
|
12385
13429
|
error: err,
|
|
12386
13430
|
path: c.req.path,
|
|
@@ -12397,8 +13441,8 @@ function createExecutionHono(serverConfig, credentialStores, sandboxConfig) {
|
|
|
12397
13441
|
const response = err.getResponse();
|
|
12398
13442
|
return response;
|
|
12399
13443
|
} catch (responseError) {
|
|
12400
|
-
if (
|
|
12401
|
-
|
|
13444
|
+
if (logger25) {
|
|
13445
|
+
logger25.error({ error: responseError }, "Error while handling HTTPException response");
|
|
12402
13446
|
}
|
|
12403
13447
|
}
|
|
12404
13448
|
}
|
|
@@ -12432,7 +13476,7 @@ function createExecutionHono(serverConfig, credentialStores, sandboxConfig) {
|
|
|
12432
13476
|
app6.use("*", async (c, next) => {
|
|
12433
13477
|
const executionContext = c.get("executionContext");
|
|
12434
13478
|
if (!executionContext) {
|
|
12435
|
-
|
|
13479
|
+
logger25.debug({}, "Empty execution context");
|
|
12436
13480
|
return next();
|
|
12437
13481
|
}
|
|
12438
13482
|
const { tenantId, projectId, agentId } = executionContext;
|
|
@@ -12441,7 +13485,7 @@ function createExecutionHono(serverConfig, credentialStores, sandboxConfig) {
|
|
|
12441
13485
|
if (requestBody) {
|
|
12442
13486
|
conversationId = requestBody.conversationId;
|
|
12443
13487
|
if (!conversationId) {
|
|
12444
|
-
|
|
13488
|
+
logger25.debug({ requestBody }, "No conversation ID found in request body");
|
|
12445
13489
|
}
|
|
12446
13490
|
}
|
|
12447
13491
|
const entries = Object.fromEntries(
|
|
@@ -12456,7 +13500,7 @@ function createExecutionHono(serverConfig, credentialStores, sandboxConfig) {
|
|
|
12456
13500
|
})
|
|
12457
13501
|
);
|
|
12458
13502
|
if (!Object.keys(entries).length) {
|
|
12459
|
-
|
|
13503
|
+
logger25.debug({}, "Empty entries for baggage");
|
|
12460
13504
|
return next();
|
|
12461
13505
|
}
|
|
12462
13506
|
const bag = Object.entries(entries).reduce(
|