@inkeep/agents-run-api 0.0.0-dev-20260113172432 → 0.0.0-dev-20260115183047
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/README.md +2 -1
- package/dist/a2a/client.d.ts +3 -1
- package/dist/a2a/client.js +23 -9
- package/dist/a2a/handlers.js +11 -5
- package/dist/a2a/transfer.d.ts +6 -1
- package/dist/a2a/transfer.js +10 -6
- package/dist/agents/Agent.d.ts +8 -4
- package/dist/agents/Agent.js +226 -92
- package/dist/agents/ToolSessionManager.js +2 -2
- package/dist/agents/generateTaskHandler.d.ts +4 -9
- package/dist/agents/generateTaskHandler.js +107 -246
- package/dist/agents/relationTools.d.ts +19 -8
- package/dist/agents/relationTools.js +105 -14
- package/dist/agents/types.d.ts +4 -2
- package/dist/agents/versions/v1/Phase1Config.d.ts +4 -3
- package/dist/agents/versions/v1/Phase1Config.js +33 -20
- package/dist/constants/execution-limits/index.js +1 -1
- package/dist/context/ContextFetcher.d.ts +68 -0
- package/dist/context/ContextFetcher.js +276 -0
- package/dist/context/ContextResolver.d.ts +56 -0
- package/dist/context/ContextResolver.js +273 -0
- package/dist/context/context.d.ts +19 -0
- package/dist/context/context.js +108 -0
- package/dist/context/contextCache.d.ts +56 -0
- package/dist/context/contextCache.js +175 -0
- package/dist/context/index.d.ts +6 -0
- package/dist/context/index.js +7 -0
- package/dist/context/validation.d.ts +39 -0
- package/dist/context/validation.js +255 -0
- package/dist/create-app.d.ts +2 -2
- package/dist/create-app.js +7 -2
- package/dist/data/agent.d.ts +2 -2
- package/dist/data/agent.js +17 -22
- package/dist/data/agents.d.ts +2 -2
- package/dist/data/agents.js +34 -42
- package/dist/data/conversations.d.ts +2 -1
- package/dist/data/conversations.js +7 -8
- package/dist/data/db/dbClient.d.ts +2 -2
- package/dist/data/db/dbClient.js +2 -10
- package/dist/env.d.ts +6 -2
- package/dist/env.js +3 -1
- package/dist/handlers/executionHandler.d.ts +3 -2
- package/dist/handlers/executionHandler.js +46 -22
- package/dist/index.d.ts +3 -3
- package/dist/middleware/api-key-auth.d.ts +4 -10
- package/dist/middleware/api-key-auth.js +164 -163
- package/dist/middleware/index.d.ts +3 -2
- package/dist/middleware/index.js +3 -2
- package/dist/middleware/projectConfig.d.ts +19 -0
- package/dist/middleware/projectConfig.js +80 -0
- package/dist/routes/agents.d.ts +2 -1
- package/dist/routes/agents.js +7 -13
- package/dist/routes/chat.d.ts +2 -1
- package/dist/routes/chat.js +29 -52
- package/dist/routes/chatDataStream.d.ts +2 -1
- package/dist/routes/chatDataStream.js +28 -30
- package/dist/routes/mcp.d.ts +2 -1
- package/dist/routes/mcp.js +25 -37
- package/dist/services/AgentSession.d.ts +5 -7
- package/dist/services/AgentSession.js +25 -34
- package/dist/services/ArtifactParser.d.ts +2 -2
- package/dist/services/ArtifactParser.js +2 -2
- package/dist/services/ArtifactService.d.ts +2 -3
- package/dist/services/ArtifactService.js +23 -20
- package/dist/services/BaseCompressor.js +2 -2
- package/dist/services/IncrementalStreamParser.d.ts +2 -2
- package/dist/services/IncrementalStreamParser.js +2 -2
- package/dist/services/ResponseFormatter.d.ts +2 -2
- package/dist/services/ResponseFormatter.js +2 -2
- package/dist/services/evaluationHttpClient.d.ts +21 -0
- package/dist/services/evaluationHttpClient.js +48 -0
- package/dist/services/evaluationRunConfigMatcher.d.ts +6 -0
- package/dist/services/evaluationRunConfigMatcher.js +7 -0
- package/dist/tools/NativeSandboxExecutor.js +1 -1
- package/dist/tools/distill-conversation-history-tool.js +2 -2
- package/dist/tools/distill-conversation-tool.js +2 -2
- package/dist/types/execution-context.d.ts +8 -14
- package/dist/types/execution-context.js +3 -2
- package/dist/utils/model-resolver.d.ts +2 -2
- package/dist/utils/model-resolver.js +3 -13
- package/dist/utils/project.d.ts +207 -0
- package/dist/utils/project.js +315 -0
- package/dist/utils/token-estimator.d.ts +6 -52
- package/dist/utils/token-estimator.js +2 -38
- package/package.json +2 -2
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { env } from "../env.js";
|
|
2
|
+
import { getLogger as getLogger$1 } from "../logger.js";
|
|
2
3
|
import dbClient_default from "../data/db/dbClient.js";
|
|
4
|
+
import { getUserIdFromContext } from "../types/execution-context.js";
|
|
3
5
|
import { DELEGATION_TOOL_BACKOFF_EXPONENT, DELEGATION_TOOL_BACKOFF_INITIAL_INTERVAL_MS, DELEGATION_TOOL_BACKOFF_MAX_ELAPSED_TIME_MS, DELEGATION_TOOL_BACKOFF_MAX_INTERVAL_MS } from "../constants/execution-limits/index.js";
|
|
4
6
|
import { toolSessionManager } from "./ToolSessionManager.js";
|
|
5
7
|
import { saveA2AMessageResponse } from "../data/conversations.js";
|
|
6
8
|
import { agentSessionManager } from "../services/AgentSession.js";
|
|
9
|
+
import { getExternalAgentRelationsForTargetSubAgent, getToolsForSubAgent, getTransferRelationsForTargetSubAgent } from "../utils/project.js";
|
|
10
|
+
import { ContextResolver } from "../context/ContextResolver.js";
|
|
11
|
+
import "../context/index.js";
|
|
7
12
|
import { A2AClient } from "../a2a/client.js";
|
|
8
13
|
import { z } from "@hono/zod-openapi";
|
|
9
|
-
import {
|
|
14
|
+
import { CredentialStuffer, InternalServices, ManagementApiClient, SPAN_KEYS, TemplateEngine, createMessage, generateId, generateServiceToken, headers } from "@inkeep/agents-core";
|
|
10
15
|
import { trace } from "@opentelemetry/api";
|
|
11
16
|
import { tool } from "ai";
|
|
12
17
|
|
|
13
18
|
//#region src/agents/relationTools.ts
|
|
14
|
-
const logger = getLogger("relationships Tools");
|
|
19
|
+
const logger = getLogger$1("relationships Tools");
|
|
15
20
|
const A2A_RETRY_STATUS_CODES = [
|
|
16
21
|
"429",
|
|
17
22
|
"500",
|
|
@@ -124,7 +129,8 @@ const createTransferToAgentTool = ({ transferConfig, callingAgentId, subAgent, s
|
|
|
124
129
|
}
|
|
125
130
|
});
|
|
126
131
|
};
|
|
127
|
-
function createDelegateToAgentTool({ delegateConfig, callingAgentId,
|
|
132
|
+
function createDelegateToAgentTool({ delegateConfig, callingAgentId, executionContext, contextId, metadata, sessionId, subAgent, credentialStoreRegistry }) {
|
|
133
|
+
const { tenantId, projectId, agentId, project } = executionContext;
|
|
128
134
|
return tool({
|
|
129
135
|
description: generateDelegateToolDescription(delegateConfig),
|
|
130
136
|
inputSchema: z.object({ message: z.string() }),
|
|
@@ -148,7 +154,7 @@ function createDelegateToAgentTool({ delegateConfig, callingAgentId, tenantId, p
|
|
|
148
154
|
let resolvedHeaders = {};
|
|
149
155
|
if (isExternal) {
|
|
150
156
|
if ((delegateConfig.config.credentialReferenceId || delegateConfig.config.headers) && credentialStoreRegistry) {
|
|
151
|
-
const credentialStuffer = new CredentialStuffer(credentialStoreRegistry, new ContextResolver(
|
|
157
|
+
const credentialStuffer = new CredentialStuffer(credentialStoreRegistry, new ContextResolver(executionContext, credentialStoreRegistry));
|
|
152
158
|
const credentialContext = {
|
|
153
159
|
tenantId,
|
|
154
160
|
projectId,
|
|
@@ -158,13 +164,8 @@ function createDelegateToAgentTool({ delegateConfig, callingAgentId, tenantId, p
|
|
|
158
164
|
};
|
|
159
165
|
let storeReference;
|
|
160
166
|
if (delegateConfig.config.credentialReferenceId) {
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
tenantId,
|
|
164
|
-
projectId
|
|
165
|
-
},
|
|
166
|
-
id: delegateConfig.config.credentialReferenceId
|
|
167
|
-
});
|
|
167
|
+
const id = delegateConfig.config.credentialReferenceId;
|
|
168
|
+
const credentialReference = project.credentialReferences?.[id];
|
|
168
169
|
if (credentialReference) storeReference = {
|
|
169
170
|
credentialStoreId: credentialReference.credentialStoreId,
|
|
170
171
|
retrievalParams: credentialReference.retrievalParams || {}
|
|
@@ -177,7 +178,7 @@ function createDelegateToAgentTool({ delegateConfig, callingAgentId, tenantId, p
|
|
|
177
178
|
});
|
|
178
179
|
}
|
|
179
180
|
} else if (isTeam) {
|
|
180
|
-
const context$2 = await new ContextResolver(
|
|
181
|
+
const context$2 = await new ContextResolver(executionContext, credentialStoreRegistry).resolveHeaders(metadata.conversationId, contextId);
|
|
181
182
|
for (const [key, value] of Object.entries(headers)) resolvedHeaders[key] = TemplateEngine.render(value, context$2, { strict: true });
|
|
182
183
|
resolvedHeaders.Authorization = `Bearer ${await generateServiceToken({
|
|
183
184
|
tenantId,
|
|
@@ -235,6 +236,7 @@ function createDelegateToAgentTool({ delegateConfig, callingAgentId, tenantId, p
|
|
|
235
236
|
fromSubAgentId: callingAgentId,
|
|
236
237
|
...isInternal ? { toSubAgentId: delegateConfig.config.id } : { toExternalAgentId: delegateConfig.config.id }
|
|
237
238
|
});
|
|
239
|
+
logger.info({ messageToSend }, "Created message in database");
|
|
238
240
|
const response = await a2aClient.sendMessage({ message: messageToSend });
|
|
239
241
|
if (response.error) throw new Error(response.error.message);
|
|
240
242
|
await saveA2AMessageResponse(response, {
|
|
@@ -269,6 +271,95 @@ function createDelegateToAgentTool({ delegateConfig, callingAgentId, tenantId, p
|
|
|
269
271
|
}
|
|
270
272
|
});
|
|
271
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Build a transfer relation config for an internal relation.
|
|
276
|
+
* Fetches tools, transfer relations, and external agent relations for the target sub-agent.
|
|
277
|
+
*/
|
|
278
|
+
async function buildTransferRelationConfig(params) {
|
|
279
|
+
const { relation, executionContext, baseUrl, apiKey } = params;
|
|
280
|
+
const { tenantId, projectId, project, agentId } = executionContext;
|
|
281
|
+
const agent = executionContext.project.agents[agentId];
|
|
282
|
+
const targetSubAgent = agent.subAgents?.[relation.id];
|
|
283
|
+
if (!targetSubAgent) throw new Error(`Target sub-agent not found: ${relation.id}`);
|
|
284
|
+
const targetToolsForSubAgent = getToolsForSubAgent({
|
|
285
|
+
agent,
|
|
286
|
+
project,
|
|
287
|
+
subAgent: targetSubAgent
|
|
288
|
+
});
|
|
289
|
+
const manageApiClient = new ManagementApiClient({
|
|
290
|
+
apiUrl: env.INKEEP_AGENTS_MANAGE_API_URL,
|
|
291
|
+
tenantId,
|
|
292
|
+
projectId,
|
|
293
|
+
auth: {
|
|
294
|
+
mode: "internalService",
|
|
295
|
+
internalServiceName: InternalServices.INKEEP_AGENTS_RUN_API
|
|
296
|
+
},
|
|
297
|
+
ref: executionContext.resolvedRef.name,
|
|
298
|
+
userId: getUserIdFromContext(executionContext)
|
|
299
|
+
});
|
|
300
|
+
const targetAgentTools = await Promise.all(targetToolsForSubAgent.map(async (item) => {
|
|
301
|
+
const mcpTool = await manageApiClient.getMcpTool(item.tool.id);
|
|
302
|
+
if (item.relationshipId) mcpTool.relationshipId = item.relationshipId;
|
|
303
|
+
if (item.selectedTools && item.selectedTools.length > 0) {
|
|
304
|
+
const selectedToolsSet = new Set(item.selectedTools);
|
|
305
|
+
mcpTool.availableTools = mcpTool.availableTools?.filter((tool$1) => selectedToolsSet.has(tool$1.name)) || [];
|
|
306
|
+
}
|
|
307
|
+
return mcpTool;
|
|
308
|
+
}));
|
|
309
|
+
const targetTransferRelations = getTransferRelationsForTargetSubAgent({
|
|
310
|
+
agent,
|
|
311
|
+
subAgentId: relation.id
|
|
312
|
+
});
|
|
313
|
+
const targetExternalAgentRelations = getExternalAgentRelationsForTargetSubAgent({
|
|
314
|
+
agent,
|
|
315
|
+
project,
|
|
316
|
+
subAgentId: relation.id
|
|
317
|
+
});
|
|
318
|
+
const targetTransferRelationsConfig = targetTransferRelations.map((rel) => ({
|
|
319
|
+
baseUrl,
|
|
320
|
+
apiKey,
|
|
321
|
+
id: rel.id,
|
|
322
|
+
tenantId,
|
|
323
|
+
projectId,
|
|
324
|
+
agentId,
|
|
325
|
+
name: rel.name,
|
|
326
|
+
description: rel.description || void 0,
|
|
327
|
+
prompt: "",
|
|
328
|
+
delegateRelations: [],
|
|
329
|
+
subAgentRelations: [],
|
|
330
|
+
transferRelations: [],
|
|
331
|
+
project
|
|
332
|
+
}));
|
|
333
|
+
const targetDelegateRelationsConfig = targetExternalAgentRelations.map((rel) => ({
|
|
334
|
+
type: "external",
|
|
335
|
+
config: {
|
|
336
|
+
relationId: rel.relationId || `external-${rel.externalAgent.id}`,
|
|
337
|
+
id: rel.externalAgent.id,
|
|
338
|
+
name: rel.externalAgent.name,
|
|
339
|
+
description: rel.externalAgent.description || "",
|
|
340
|
+
ref: executionContext.resolvedRef,
|
|
341
|
+
baseUrl: rel.externalAgent.baseUrl,
|
|
342
|
+
headers: rel.headers || void 0,
|
|
343
|
+
credentialReferenceId: rel.externalAgent.credentialReferenceId,
|
|
344
|
+
relationType: "delegate"
|
|
345
|
+
}
|
|
346
|
+
}));
|
|
347
|
+
return {
|
|
348
|
+
baseUrl,
|
|
349
|
+
apiKey,
|
|
350
|
+
id: relation.id,
|
|
351
|
+
tenantId,
|
|
352
|
+
projectId,
|
|
353
|
+
agentId,
|
|
354
|
+
name: relation.name,
|
|
355
|
+
description: relation.description || void 0,
|
|
356
|
+
prompt: "",
|
|
357
|
+
delegateRelations: targetDelegateRelationsConfig,
|
|
358
|
+
subAgentRelations: [],
|
|
359
|
+
transferRelations: targetTransferRelationsConfig,
|
|
360
|
+
tools: targetAgentTools
|
|
361
|
+
};
|
|
362
|
+
}
|
|
272
363
|
|
|
273
364
|
//#endregion
|
|
274
|
-
export { createDelegateToAgentTool, createTransferToAgentTool };
|
|
365
|
+
export { buildTransferRelationConfig, createDelegateToAgentTool, createTransferToAgentTool };
|
package/dist/agents/types.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { AssembleResult } from "../utils/token-estimator.js";
|
|
2
|
-
import { Artifact, ArtifactComponentApiInsert, DataComponentApiInsert } from "@inkeep/agents-core";
|
|
2
|
+
import { Artifact, ArtifactComponentApiInsert, BreakdownComponentDef, DataComponentApiInsert } from "@inkeep/agents-core";
|
|
3
3
|
|
|
4
4
|
//#region src/agents/types.d.ts
|
|
5
5
|
interface VersionConfig<TConfig> {
|
|
6
6
|
loadTemplates(): Map<string, string>;
|
|
7
7
|
assemble(templates: Map<string, string>, config: TConfig): AssembleResult;
|
|
8
|
+
/** Returns the breakdown schema defining which components this version tracks */
|
|
9
|
+
getBreakdownSchema(): BreakdownComponentDef[];
|
|
8
10
|
}
|
|
9
11
|
interface SystemPromptV1 {
|
|
10
12
|
corePrompt: string;
|
|
@@ -25,4 +27,4 @@ interface ToolData {
|
|
|
25
27
|
usageGuidelines?: string;
|
|
26
28
|
}
|
|
27
29
|
//#endregion
|
|
28
|
-
export { SystemPromptV1, ToolData, VersionConfig };
|
|
30
|
+
export { type BreakdownComponentDef, SystemPromptV1, ToolData, VersionConfig };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { AssembleResult } from "../../../utils/token-estimator.js";
|
|
1
|
+
import { AssembleResult, BreakdownComponentDef } from "../../../utils/token-estimator.js";
|
|
2
2
|
import { SystemPromptV1, ToolData, VersionConfig } from "../../types.js";
|
|
3
|
-
import { McpTool } from "@inkeep/agents-core";
|
|
3
|
+
import { McpTool, V1_BREAKDOWN_SCHEMA } from "@inkeep/agents-core";
|
|
4
4
|
|
|
5
5
|
//#region src/agents/versions/v1/Phase1Config.d.ts
|
|
6
6
|
declare class Phase1Config implements VersionConfig<SystemPromptV1> {
|
|
7
7
|
loadTemplates(): Map<string, string>;
|
|
8
|
+
getBreakdownSchema(): BreakdownComponentDef[];
|
|
8
9
|
static convertMcpToolsToToolData(mcpTools: McpTool[] | undefined): ToolData[];
|
|
9
10
|
private isToolDataArray;
|
|
10
11
|
private normalizeSchema;
|
|
@@ -24,4 +25,4 @@ declare class Phase1Config implements VersionConfig<SystemPromptV1> {
|
|
|
24
25
|
private generateParametersXml;
|
|
25
26
|
}
|
|
26
27
|
//#endregion
|
|
27
|
-
export { Phase1Config };
|
|
28
|
+
export { Phase1Config, V1_BREAKDOWN_SCHEMA };
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { getLogger } from "../../../logger.js";
|
|
1
|
+
import { getLogger as getLogger$1 } from "../../../logger.js";
|
|
2
2
|
import { calculateBreakdownTotal, createEmptyBreakdown, estimateTokens } from "../../../utils/token-estimator.js";
|
|
3
3
|
import system_prompt_default from "../../../_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/system-prompt.js";
|
|
4
4
|
import thinking_preparation_default from "../../../_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/thinking-preparation.js";
|
|
5
5
|
import tool_default from "../../../_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/phase1/tool.js";
|
|
6
6
|
import artifact_default from "../../../_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/shared/artifact.js";
|
|
7
7
|
import artifact_retrieval_guidance_default from "../../../_virtual/_raw_/home/runner/work/agents/agents/agents-run-api/templates/v1/shared/artifact-retrieval-guidance.js";
|
|
8
|
+
import { V1_BREAKDOWN_SCHEMA } from "@inkeep/agents-core";
|
|
8
9
|
import { convertZodToJsonSchema, isZodSchema } from "@inkeep/agents-core/utils/schema-conversion";
|
|
9
10
|
|
|
10
11
|
//#region src/agents/versions/v1/Phase1Config.ts
|
|
11
|
-
getLogger("Phase1Config");
|
|
12
|
+
getLogger$1("Phase1Config");
|
|
12
13
|
var Phase1Config = class Phase1Config {
|
|
13
14
|
loadTemplates() {
|
|
14
15
|
const templates = /* @__PURE__ */ new Map();
|
|
@@ -19,15 +20,23 @@ var Phase1Config = class Phase1Config {
|
|
|
19
20
|
templates.set("thinking-preparation", thinking_preparation_default);
|
|
20
21
|
return templates;
|
|
21
22
|
}
|
|
23
|
+
getBreakdownSchema() {
|
|
24
|
+
return V1_BREAKDOWN_SCHEMA;
|
|
25
|
+
}
|
|
22
26
|
static convertMcpToolsToToolData(mcpTools) {
|
|
23
27
|
if (!mcpTools || mcpTools.length === 0) return [];
|
|
24
28
|
const toolData = [];
|
|
25
|
-
for (const mcpTool of mcpTools) if (mcpTool.availableTools) for (const toolDef of mcpTool.availableTools)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
for (const mcpTool of mcpTools) if (mcpTool.availableTools) for (const toolDef of mcpTool.availableTools) {
|
|
30
|
+
let usageGuidelines = "";
|
|
31
|
+
if (mcpTool.config.mcp.prompt) usageGuidelines = `${mcpTool.config.mcp.prompt}\n\n`;
|
|
32
|
+
usageGuidelines += `Use this tool from ${mcpTool.name} server when appropriate.`;
|
|
33
|
+
toolData.push({
|
|
34
|
+
name: toolDef.name,
|
|
35
|
+
description: toolDef.description || "No description available",
|
|
36
|
+
inputSchema: toolDef.inputSchema || {},
|
|
37
|
+
usageGuidelines
|
|
38
|
+
});
|
|
39
|
+
}
|
|
31
40
|
return toolData;
|
|
32
41
|
}
|
|
33
42
|
isToolDataArray(tools) {
|
|
@@ -45,17 +54,17 @@ var Phase1Config = class Phase1Config {
|
|
|
45
54
|
return inputSchema;
|
|
46
55
|
}
|
|
47
56
|
assemble(templates, config) {
|
|
48
|
-
const breakdown = createEmptyBreakdown();
|
|
57
|
+
const breakdown = createEmptyBreakdown(this.getBreakdownSchema());
|
|
49
58
|
const systemPromptTemplateContent = templates.get("system-prompt");
|
|
50
59
|
if (!systemPromptTemplateContent) throw new Error("System prompt template not loaded");
|
|
51
|
-
breakdown.systemPromptTemplate = estimateTokens(systemPromptTemplateContent.replace("{{CORE_INSTRUCTIONS}}", "").replace("{{AGENT_CONTEXT_SECTION}}", "").replace("{{ARTIFACTS_SECTION}}", "").replace("{{TOOLS_SECTION}}", "").replace("{{THINKING_PREPARATION_INSTRUCTIONS}}", "").replace("{{TRANSFER_INSTRUCTIONS}}", "").replace("{{DELEGATION_INSTRUCTIONS}}", ""));
|
|
60
|
+
breakdown.components["systemPromptTemplate"] = estimateTokens(systemPromptTemplateContent.replace("{{CORE_INSTRUCTIONS}}", "").replace("{{AGENT_CONTEXT_SECTION}}", "").replace("{{ARTIFACTS_SECTION}}", "").replace("{{TOOLS_SECTION}}", "").replace("{{THINKING_PREPARATION_INSTRUCTIONS}}", "").replace("{{TRANSFER_INSTRUCTIONS}}", "").replace("{{DELEGATION_INSTRUCTIONS}}", ""));
|
|
52
61
|
let systemPrompt = systemPromptTemplateContent;
|
|
53
62
|
if (config.corePrompt && config.corePrompt.trim()) {
|
|
54
|
-
breakdown.coreInstructions = estimateTokens(config.corePrompt);
|
|
63
|
+
breakdown.components["coreInstructions"] = estimateTokens(config.corePrompt);
|
|
55
64
|
systemPrompt = systemPrompt.replace("{{CORE_INSTRUCTIONS}}", config.corePrompt);
|
|
56
65
|
} else systemPrompt = systemPrompt.replace(/<core_instructions>\s*\{\{CORE_INSTRUCTIONS\}\}\s*<\/core_instructions>/g, "");
|
|
57
66
|
const agentContextSection = this.generateAgentContextSection(config.prompt);
|
|
58
|
-
breakdown.agentPrompt = estimateTokens(agentContextSection);
|
|
67
|
+
breakdown.components["agentPrompt"] = estimateTokens(agentContextSection);
|
|
59
68
|
systemPrompt = systemPrompt.replace("{{AGENT_CONTEXT_SECTION}}", agentContextSection);
|
|
60
69
|
const toolData = (this.isToolDataArray(config.tools) ? config.tools : Phase1Config.convertMcpToolsToToolData(config.tools)).map((tool) => ({
|
|
61
70
|
...tool,
|
|
@@ -64,21 +73,25 @@ var Phase1Config = class Phase1Config {
|
|
|
64
73
|
const hasArtifactComponents = Boolean(config.artifactComponents && config.artifactComponents.length > 0);
|
|
65
74
|
const artifactsSection = this.generateArtifactsSection(templates, config.artifacts, hasArtifactComponents, config.artifactComponents, config.hasAgentArtifactComponents);
|
|
66
75
|
const artifactInstructionsTokens = this.getArtifactInstructionsTokens(templates, hasArtifactComponents, config.artifactComponents, config.hasAgentArtifactComponents, (config.artifacts?.length ?? 0) > 0);
|
|
67
|
-
breakdown.systemPromptTemplate += artifactInstructionsTokens;
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
breakdown.components["systemPromptTemplate"] += artifactInstructionsTokens;
|
|
77
|
+
const actualArtifactsXml = config.artifacts?.length > 0 ? config.artifacts.map((artifact) => this.generateArtifactXml(templates, artifact)).join("\n ") : "";
|
|
78
|
+
breakdown.components["artifactsSection"] = estimateTokens(actualArtifactsXml);
|
|
79
|
+
if (hasArtifactComponents) {
|
|
80
|
+
const creationInstructions = this.getArtifactCreationInstructions(hasArtifactComponents, config.artifactComponents);
|
|
81
|
+
breakdown.components["artifactComponents"] = estimateTokens(creationInstructions);
|
|
82
|
+
}
|
|
70
83
|
systemPrompt = systemPrompt.replace("{{ARTIFACTS_SECTION}}", artifactsSection);
|
|
71
84
|
const toolsSection = this.generateToolsSection(templates, toolData);
|
|
72
|
-
breakdown.toolsSection = estimateTokens(toolsSection);
|
|
85
|
+
breakdown.components["toolsSection"] = estimateTokens(toolsSection);
|
|
73
86
|
systemPrompt = systemPrompt.replace("{{TOOLS_SECTION}}", toolsSection);
|
|
74
87
|
const thinkingPreparationSection = this.generateThinkingPreparationSection(templates, config.isThinkingPreparation);
|
|
75
|
-
breakdown.thinkingPreparation = estimateTokens(thinkingPreparationSection);
|
|
88
|
+
breakdown.components["thinkingPreparation"] = estimateTokens(thinkingPreparationSection);
|
|
76
89
|
systemPrompt = systemPrompt.replace("{{THINKING_PREPARATION_INSTRUCTIONS}}", thinkingPreparationSection);
|
|
77
90
|
const transferSection = this.generateTransferInstructions(config.hasTransferRelations);
|
|
78
|
-
breakdown.transferInstructions = estimateTokens(transferSection);
|
|
91
|
+
breakdown.components["transferInstructions"] = estimateTokens(transferSection);
|
|
79
92
|
systemPrompt = systemPrompt.replace("{{TRANSFER_INSTRUCTIONS}}", transferSection);
|
|
80
93
|
const delegationSection = this.generateDelegationInstructions(config.hasDelegateRelations);
|
|
81
|
-
breakdown.delegationInstructions = estimateTokens(delegationSection);
|
|
94
|
+
breakdown.components["delegationInstructions"] = estimateTokens(delegationSection);
|
|
82
95
|
systemPrompt = systemPrompt.replace("{{DELEGATION_INSTRUCTIONS}}", delegationSection);
|
|
83
96
|
calculateBreakdownTotal(breakdown);
|
|
84
97
|
return {
|
|
@@ -432,4 +445,4 @@ ${creationInstructions}
|
|
|
432
445
|
};
|
|
433
446
|
|
|
434
447
|
//#endregion
|
|
435
|
-
export { Phase1Config };
|
|
448
|
+
export { Phase1Config, V1_BREAKDOWN_SCHEMA };
|
|
@@ -8,7 +8,7 @@ const constantsSchema = z.object(Object.fromEntries(Object.keys(executionLimitsD
|
|
|
8
8
|
const defaultValue = executionLimitsDefaults[key];
|
|
9
9
|
const envKey = `AGENTS_${key}`;
|
|
10
10
|
if (typeof defaultValue === "boolean") return [envKey, z.coerce.boolean().optional()];
|
|
11
|
-
|
|
11
|
+
return [envKey, z.coerce.number().optional()];
|
|
12
12
|
})));
|
|
13
13
|
const parseConstants = () => {
|
|
14
14
|
const envOverrides = constantsSchema.parse(process.env);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ContextFetchDefinition, CredentialStoreRegistry, FullExecutionContext, TemplateContext } from "@inkeep/agents-core";
|
|
2
|
+
|
|
3
|
+
//#region src/context/ContextFetcher.d.ts
|
|
4
|
+
declare class MissingRequiredVariableError extends Error {
|
|
5
|
+
constructor(variable: string);
|
|
6
|
+
}
|
|
7
|
+
interface FetchResult {
|
|
8
|
+
data: unknown;
|
|
9
|
+
source: string;
|
|
10
|
+
durationMs: number;
|
|
11
|
+
}
|
|
12
|
+
declare class ContextFetcher {
|
|
13
|
+
private executionContext;
|
|
14
|
+
private defaultTimeout;
|
|
15
|
+
private credentialStuffer?;
|
|
16
|
+
constructor(executionContext: FullExecutionContext, credentialStoreRegistry?: CredentialStoreRegistry, defaultTimeout?: number);
|
|
17
|
+
/**
|
|
18
|
+
* Fetch data according to a fetch definition
|
|
19
|
+
*/
|
|
20
|
+
fetch(definition: ContextFetchDefinition, context: TemplateContext): Promise<{
|
|
21
|
+
data: unknown;
|
|
22
|
+
resolvedUrl: string;
|
|
23
|
+
}>;
|
|
24
|
+
private getCredential;
|
|
25
|
+
/**
|
|
26
|
+
* Resolve template variables in fetch configuration and inject credential headers
|
|
27
|
+
*/
|
|
28
|
+
private resolveTemplateVariables;
|
|
29
|
+
/**
|
|
30
|
+
* Interpolate template variables in a string using TemplateEngine
|
|
31
|
+
*/
|
|
32
|
+
private interpolateTemplate;
|
|
33
|
+
/**
|
|
34
|
+
* Interpolate template variables in an object recursively using TemplateEngine
|
|
35
|
+
*/
|
|
36
|
+
private interpolateObjectTemplates;
|
|
37
|
+
/**
|
|
38
|
+
* Perform HTTP request
|
|
39
|
+
*/
|
|
40
|
+
private performRequest;
|
|
41
|
+
/**
|
|
42
|
+
* Transform response data using JsonTransformer (JMESPath)
|
|
43
|
+
*/
|
|
44
|
+
private transformResponse;
|
|
45
|
+
/**
|
|
46
|
+
* Validate response against JSON Schema
|
|
47
|
+
*/
|
|
48
|
+
private validateResponseWithJsonSchema;
|
|
49
|
+
/**
|
|
50
|
+
* Test a fetch definition without caching
|
|
51
|
+
*/
|
|
52
|
+
test(definition: ContextFetchDefinition, context: TemplateContext): Promise<{
|
|
53
|
+
success: boolean;
|
|
54
|
+
data?: unknown;
|
|
55
|
+
resolvedUrl?: string;
|
|
56
|
+
error?: string;
|
|
57
|
+
durationMs: number;
|
|
58
|
+
}>;
|
|
59
|
+
/**
|
|
60
|
+
* Get fetcher statistics
|
|
61
|
+
*/
|
|
62
|
+
getStats(): {
|
|
63
|
+
tenantId: string;
|
|
64
|
+
defaultTimeout: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { ContextFetcher, FetchResult, MissingRequiredVariableError };
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { validateAgainstJsonSchema } from "./validation.js";
|
|
2
|
+
import { CredentialStuffer, JsonTransformer, TemplateEngine, getLogger } from "@inkeep/agents-core";
|
|
3
|
+
|
|
4
|
+
//#region src/context/ContextFetcher.ts
|
|
5
|
+
const logger = getLogger("context-fetcher");
|
|
6
|
+
var MissingRequiredVariableError = class extends Error {
|
|
7
|
+
constructor(variable) {
|
|
8
|
+
super(`Missing required variable: ${variable}`);
|
|
9
|
+
this.name = "MissingRequiredVariableError";
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* GraphQL error checker - validates response for GraphQL errors and throws if found
|
|
14
|
+
*/
|
|
15
|
+
const checkGraphQLErrors = (data) => {
|
|
16
|
+
if (data && typeof data === "object" && "errors" in data) {
|
|
17
|
+
const errorObj = data;
|
|
18
|
+
if (Array.isArray(errorObj.errors) && errorObj.errors.length > 0) {
|
|
19
|
+
const agentqlErrors = errorObj.errors;
|
|
20
|
+
const errorMessage = `GraphQL request failed with ${agentqlErrors.length} errors: ${agentqlErrors.map((e) => e.message || "Unknown error").join(", ")}`;
|
|
21
|
+
throw new Error(errorMessage);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const responseErrorCheckers = [checkGraphQLErrors];
|
|
26
|
+
var ContextFetcher = class {
|
|
27
|
+
executionContext;
|
|
28
|
+
defaultTimeout;
|
|
29
|
+
credentialStuffer;
|
|
30
|
+
constructor(executionContext, credentialStoreRegistry, defaultTimeout = 1e4) {
|
|
31
|
+
this.executionContext = executionContext;
|
|
32
|
+
this.defaultTimeout = defaultTimeout;
|
|
33
|
+
if (credentialStoreRegistry) this.credentialStuffer = new CredentialStuffer(credentialStoreRegistry);
|
|
34
|
+
logger.info({
|
|
35
|
+
tenantId: this.executionContext.tenantId,
|
|
36
|
+
defaultTimeout: this.defaultTimeout,
|
|
37
|
+
hasCredentialSupport: !!this.credentialStuffer
|
|
38
|
+
}, "ContextFetcher initialized");
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetch data according to a fetch definition
|
|
42
|
+
*/
|
|
43
|
+
async fetch(definition, context) {
|
|
44
|
+
const startTime = Date.now();
|
|
45
|
+
logger.info({
|
|
46
|
+
definitionId: definition.id,
|
|
47
|
+
url: definition.fetchConfig.url
|
|
48
|
+
}, "Starting context fetch");
|
|
49
|
+
try {
|
|
50
|
+
const resolvedConfig = await this.resolveTemplateVariables(definition.fetchConfig, context, definition.credentialReferenceId);
|
|
51
|
+
const response = await this.performRequest(resolvedConfig);
|
|
52
|
+
let transformedData = response.data;
|
|
53
|
+
if (definition.fetchConfig.transform) transformedData = await this.transformResponse(response.data, definition.fetchConfig.transform);
|
|
54
|
+
if (definition.responseSchema) this.validateResponseWithJsonSchema(transformedData, definition.responseSchema, definition.id);
|
|
55
|
+
const durationMs = Date.now() - startTime;
|
|
56
|
+
logger.info({
|
|
57
|
+
definitionId: definition.id,
|
|
58
|
+
source: response.source,
|
|
59
|
+
durationMs
|
|
60
|
+
}, "Context fetch completed successfully");
|
|
61
|
+
return {
|
|
62
|
+
data: transformedData,
|
|
63
|
+
resolvedUrl: resolvedConfig.url
|
|
64
|
+
};
|
|
65
|
+
} catch (error) {
|
|
66
|
+
const durationMs = Date.now() - startTime;
|
|
67
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
68
|
+
if (error instanceof MissingRequiredVariableError) logger.error({
|
|
69
|
+
definitionId: definition.id,
|
|
70
|
+
error: errorMessage,
|
|
71
|
+
durationMs
|
|
72
|
+
}, "Context fetch skipped due to missing required variable");
|
|
73
|
+
logger.error({
|
|
74
|
+
definitionId: definition.id,
|
|
75
|
+
error: errorMessage,
|
|
76
|
+
durationMs
|
|
77
|
+
}, "Context fetch failed");
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async getCredential(credentialReferenceId) {
|
|
82
|
+
const { project, tenantId, projectId } = this.executionContext;
|
|
83
|
+
try {
|
|
84
|
+
const credentialReference = project.credentialReferences?.[credentialReferenceId];
|
|
85
|
+
logger.info({ credentialReference }, "Credential reference");
|
|
86
|
+
if (!credentialReference || !this.credentialStuffer) throw new Error(`Credential store not found for reference ID: ${credentialReferenceId}`);
|
|
87
|
+
const credentialContext = {
|
|
88
|
+
tenantId,
|
|
89
|
+
projectId
|
|
90
|
+
};
|
|
91
|
+
const storeReference = {
|
|
92
|
+
credentialStoreId: credentialReference.credentialStoreId,
|
|
93
|
+
retrievalParams: credentialReference.retrievalParams || {}
|
|
94
|
+
};
|
|
95
|
+
return await this.credentialStuffer.getCredentials(credentialContext, storeReference);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
logger.error({
|
|
98
|
+
credentialReferenceId,
|
|
99
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
100
|
+
}, "Failed to resolve credentials for fetch request");
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Resolve template variables in fetch configuration and inject credential headers
|
|
106
|
+
*/
|
|
107
|
+
async resolveTemplateVariables(fetchConfig, context, credentialReferenceId) {
|
|
108
|
+
const resolved = { ...fetchConfig };
|
|
109
|
+
const filteredRequiredToFetch = fetchConfig.requiredToFetch?.filter((variable) => variable.startsWith("{{") && variable.endsWith("}}"));
|
|
110
|
+
if (filteredRequiredToFetch) for (const variable of filteredRequiredToFetch) {
|
|
111
|
+
let resolvedVariable;
|
|
112
|
+
try {
|
|
113
|
+
resolvedVariable = this.interpolateTemplate(variable, context);
|
|
114
|
+
} catch {
|
|
115
|
+
throw new MissingRequiredVariableError(variable);
|
|
116
|
+
}
|
|
117
|
+
if (resolvedVariable === "" || resolvedVariable === variable) throw new MissingRequiredVariableError(variable);
|
|
118
|
+
}
|
|
119
|
+
resolved.url = this.interpolateTemplate(fetchConfig.url, context);
|
|
120
|
+
logger.info({ resolvedUrl: resolved.url }, "Resolved URL");
|
|
121
|
+
if (fetchConfig.headers) {
|
|
122
|
+
resolved.headers = {};
|
|
123
|
+
for (const [key, value] of Object.entries(fetchConfig.headers)) resolved.headers[key] = this.interpolateTemplate(value, context);
|
|
124
|
+
}
|
|
125
|
+
if (fetchConfig.body) resolved.body = this.interpolateObjectTemplates(fetchConfig.body, context);
|
|
126
|
+
if (credentialReferenceId && this.credentialStuffer) try {
|
|
127
|
+
const credentialHeaders = (await this.getCredential(credentialReferenceId))?.headers;
|
|
128
|
+
if (credentialHeaders) {
|
|
129
|
+
resolved.headers = {
|
|
130
|
+
...resolved.headers,
|
|
131
|
+
...credentialHeaders
|
|
132
|
+
};
|
|
133
|
+
logger.info({ credentialReferenceId }, "Added credential headers to fetch request");
|
|
134
|
+
}
|
|
135
|
+
} catch (error) {
|
|
136
|
+
logger.error({
|
|
137
|
+
credentialReferenceId,
|
|
138
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
139
|
+
}, "Failed to resolve credentials for fetch request");
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
return resolved;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Interpolate template variables in a string using TemplateEngine
|
|
146
|
+
*/
|
|
147
|
+
interpolateTemplate(template, context) {
|
|
148
|
+
try {
|
|
149
|
+
return TemplateEngine.render(template, context, {
|
|
150
|
+
strict: false,
|
|
151
|
+
preserveUnresolved: true
|
|
152
|
+
});
|
|
153
|
+
} catch (error) {
|
|
154
|
+
logger.error({
|
|
155
|
+
template,
|
|
156
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
157
|
+
}, "Failed to interpolate template variable");
|
|
158
|
+
return template;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Interpolate template variables in an object recursively using TemplateEngine
|
|
163
|
+
*/
|
|
164
|
+
interpolateObjectTemplates(obj, context) {
|
|
165
|
+
const result = {};
|
|
166
|
+
for (const [key, value] of Object.entries(obj)) if (typeof value === "string") result[key] = this.interpolateTemplate(value, context);
|
|
167
|
+
else if (value && typeof value === "object" && !Array.isArray(value)) result[key] = this.interpolateObjectTemplates(value, context);
|
|
168
|
+
else result[key] = value;
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Perform HTTP request
|
|
173
|
+
*/
|
|
174
|
+
async performRequest(config) {
|
|
175
|
+
const startTime = Date.now();
|
|
176
|
+
try {
|
|
177
|
+
logger.debug({
|
|
178
|
+
url: config.url,
|
|
179
|
+
method: config.method
|
|
180
|
+
}, "Performing HTTP request");
|
|
181
|
+
const response = await fetch(config.url, {
|
|
182
|
+
method: config.method,
|
|
183
|
+
headers: config.headers,
|
|
184
|
+
body: config.body ? JSON.stringify(config.body) : void 0,
|
|
185
|
+
signal: AbortSignal.timeout(config.timeout || this.defaultTimeout)
|
|
186
|
+
});
|
|
187
|
+
if (!response.ok) {
|
|
188
|
+
const errorText = await response.text();
|
|
189
|
+
throw /* @__PURE__ */ new Error(`HTTP ${response.status}: ${response.statusText} - ${errorText}`);
|
|
190
|
+
}
|
|
191
|
+
const contentType = response.headers.get("content-type") || "";
|
|
192
|
+
let data;
|
|
193
|
+
if (contentType.includes("application/json")) data = await response.json();
|
|
194
|
+
else data = await response.text();
|
|
195
|
+
const durationMs = Date.now() - startTime;
|
|
196
|
+
for (const checker of responseErrorCheckers) checker(data);
|
|
197
|
+
return {
|
|
198
|
+
data,
|
|
199
|
+
source: config.url,
|
|
200
|
+
durationMs
|
|
201
|
+
};
|
|
202
|
+
} catch (error) {
|
|
203
|
+
const durationMs = Date.now() - startTime;
|
|
204
|
+
const requestError = error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown error");
|
|
205
|
+
logger.warn({
|
|
206
|
+
url: config.url,
|
|
207
|
+
error: requestError.message,
|
|
208
|
+
durationMs
|
|
209
|
+
}, "HTTP request failed");
|
|
210
|
+
throw requestError;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Transform response data using JsonTransformer (JMESPath)
|
|
215
|
+
*/
|
|
216
|
+
async transformResponse(data, transform) {
|
|
217
|
+
try {
|
|
218
|
+
return await JsonTransformer.transform(data, transform);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
logger.error({
|
|
221
|
+
transform,
|
|
222
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
223
|
+
}, "Failed to transform response data");
|
|
224
|
+
return data;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Validate response against JSON Schema
|
|
229
|
+
*/
|
|
230
|
+
validateResponseWithJsonSchema(data, jsonSchema, definitionId) {
|
|
231
|
+
try {
|
|
232
|
+
if (!validateAgainstJsonSchema(jsonSchema, data)) throw new Error("Data does not match JSON Schema");
|
|
233
|
+
} catch (error) {
|
|
234
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown validation error";
|
|
235
|
+
logger.error({
|
|
236
|
+
definitionId,
|
|
237
|
+
jsonSchema,
|
|
238
|
+
error: errorMessage
|
|
239
|
+
}, "JSON Schema response validation failed");
|
|
240
|
+
throw new Error(`Response validation failed: ${errorMessage}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Test a fetch definition without caching
|
|
245
|
+
*/
|
|
246
|
+
async test(definition, context) {
|
|
247
|
+
const startTime = Date.now();
|
|
248
|
+
try {
|
|
249
|
+
const result = await this.fetch(definition, context);
|
|
250
|
+
return {
|
|
251
|
+
success: true,
|
|
252
|
+
data: result.data,
|
|
253
|
+
resolvedUrl: result.resolvedUrl,
|
|
254
|
+
durationMs: Date.now() - startTime
|
|
255
|
+
};
|
|
256
|
+
} catch (error) {
|
|
257
|
+
return {
|
|
258
|
+
success: false,
|
|
259
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
260
|
+
durationMs: Date.now() - startTime
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get fetcher statistics
|
|
266
|
+
*/
|
|
267
|
+
getStats() {
|
|
268
|
+
return {
|
|
269
|
+
tenantId: this.executionContext.tenantId,
|
|
270
|
+
defaultTimeout: this.defaultTimeout
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
//#endregion
|
|
276
|
+
export { ContextFetcher, MissingRequiredVariableError };
|