@inkeep/agents-api 0.0.1 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/dist/.well-known/workflow/v1/flow.cjs +43 -106
  2. package/dist/.well-known/workflow/v1/flow.cjs.debug.json +2 -4
  3. package/dist/.well-known/workflow/v1/manifest.debug.json +17 -55
  4. package/dist/.well-known/workflow/v1/step.cjs +45938 -45976
  5. package/dist/.well-known/workflow/v1/step.cjs.debug.json +2 -4
  6. package/dist/_virtual/rolldown_runtime.js +7 -0
  7. package/dist/createApp.js +40 -12
  8. package/dist/domains/evals/api/.well-known/workflow/v1/flow.d.ts +4 -0
  9. package/dist/domains/evals/api/.well-known/workflow/v1/flow.js +12 -0
  10. package/dist/domains/evals/api/.well-known/workflow/v1/step.d.ts +4 -0
  11. package/dist/domains/evals/api/.well-known/workflow/v1/step.js +12 -0
  12. package/dist/domains/evals/routes/datasetTriggers.d.ts +2 -2
  13. package/dist/domains/evals/routes/index.d.ts +2 -2
  14. package/dist/domains/evals/scripts/build-workflow.js +2 -2
  15. package/dist/domains/evals/workflow/functions/evaluateConversation.d.ts +4 -1
  16. package/dist/domains/evals/workflow/functions/evaluateConversation.js +2 -1
  17. package/dist/domains/evals/workflow/functions/runDatasetItem.d.ts +4 -1
  18. package/dist/domains/evals/workflow/functions/runDatasetItem.js +2 -1
  19. package/dist/domains/evals/workflow/routes.d.ts +2 -2
  20. package/dist/domains/evals/workflow/world.js +3 -2
  21. package/dist/domains/github/config.d.ts +14 -0
  22. package/dist/domains/github/config.js +47 -0
  23. package/dist/domains/github/index.d.ts +12 -0
  24. package/dist/domains/github/index.js +18 -0
  25. package/dist/domains/github/installation.d.ts +34 -0
  26. package/dist/domains/github/installation.js +172 -0
  27. package/dist/domains/github/jwks.d.ts +20 -0
  28. package/dist/domains/github/jwks.js +85 -0
  29. package/dist/domains/github/oidcToken.d.ts +22 -0
  30. package/dist/domains/github/oidcToken.js +140 -0
  31. package/dist/domains/github/routes/tokenExchange.d.ts +7 -0
  32. package/dist/domains/github/routes/tokenExchange.js +130 -0
  33. package/dist/domains/manage/index.js +0 -2
  34. package/dist/domains/manage/routes/agent.js +9 -4
  35. package/dist/domains/manage/routes/agentFull.js +9 -6
  36. package/dist/domains/manage/routes/apiKeys.js +1 -2
  37. package/dist/domains/manage/routes/artifactComponents.js +5 -5
  38. package/dist/domains/manage/routes/cliAuth.js +3 -3
  39. package/dist/domains/manage/routes/contextConfigs.js +5 -5
  40. package/dist/domains/manage/routes/conversations.d.ts +2 -2
  41. package/dist/domains/manage/routes/credentialStores.js +2 -2
  42. package/dist/domains/manage/routes/credentials.js +6 -7
  43. package/dist/domains/manage/routes/dataComponents.js +6 -7
  44. package/dist/domains/manage/routes/externalAgents.js +1 -2
  45. package/dist/domains/manage/routes/index.d.ts +2 -2
  46. package/dist/domains/manage/routes/index.js +4 -0
  47. package/dist/domains/manage/routes/invitations.js +1 -1
  48. package/dist/domains/manage/routes/mcp.d.ts +2 -2
  49. package/dist/domains/manage/routes/playgroundToken.js +1 -2
  50. package/dist/domains/manage/routes/projectFull.js +33 -11
  51. package/dist/domains/manage/routes/projectMembers.js +16 -35
  52. package/dist/domains/manage/routes/projectPermissions.js +17 -10
  53. package/dist/domains/manage/routes/projects.js +4 -5
  54. package/dist/domains/manage/routes/signoz.d.ts +2 -2
  55. package/dist/domains/manage/routes/signoz.js +6 -3
  56. package/dist/domains/manage/routes/subAgentArtifactComponents.js +5 -5
  57. package/dist/domains/manage/routes/subAgentDataComponents.js +5 -5
  58. package/dist/domains/manage/routes/subAgentExternalAgentRelations.js +5 -5
  59. package/dist/domains/manage/routes/subAgentFunctionTools.js +5 -5
  60. package/dist/domains/manage/routes/subAgentRelations.js +6 -6
  61. package/dist/domains/manage/routes/subAgentTeamAgentRelations.js +6 -6
  62. package/dist/domains/manage/routes/subAgentToolRelations.js +6 -6
  63. package/dist/domains/manage/routes/subAgents.js +5 -5
  64. package/dist/domains/manage/routes/tools.js +24 -3
  65. package/dist/domains/manage/routes/triggers.js +82 -25
  66. package/dist/domains/manage/routes/userOrganizations.js +4 -4
  67. package/dist/domains/manage/routes/{agentToolRelations.d.ts → userProjectMemberships.d.ts} +1 -1
  68. package/dist/domains/manage/routes/userProjectMemberships.js +45 -0
  69. package/dist/domains/mcp/routes/mcp.d.ts +7 -0
  70. package/dist/domains/mcp/routes/mcp.js +45 -0
  71. package/dist/domains/run/a2a/handlers.js +2 -10
  72. package/dist/domains/run/a2a/types.d.ts +2 -6
  73. package/dist/domains/run/agents/Agent.d.ts +1 -0
  74. package/dist/domains/run/agents/Agent.js +207 -44
  75. package/dist/domains/run/agents/generateTaskHandler.js +14 -2
  76. package/dist/domains/run/context/ContextFetcher.js +8 -7
  77. package/dist/domains/run/context/ContextResolver.js +1 -1
  78. package/dist/domains/run/handlers/executionHandler.d.ts +3 -1
  79. package/dist/domains/run/handlers/executionHandler.js +149 -84
  80. package/dist/domains/run/routes/agents.js +1 -1
  81. package/dist/domains/run/routes/chat.js +47 -1
  82. package/dist/domains/run/routes/chatDataStream.js +107 -14
  83. package/dist/domains/run/routes/webhooks.js +40 -329
  84. package/dist/domains/run/services/AgentSession.d.ts +3 -0
  85. package/dist/domains/run/services/AgentSession.js +9 -0
  86. package/dist/domains/run/services/BaseCompressor.js +1 -1
  87. package/dist/domains/run/services/ToolApprovalUiBus.d.ts +28 -0
  88. package/dist/domains/run/services/ToolApprovalUiBus.js +44 -0
  89. package/dist/domains/run/services/TriggerService.d.ts +31 -0
  90. package/dist/domains/run/services/TriggerService.js +543 -0
  91. package/dist/domains/run/tools/NativeSandboxExecutor.d.ts +3 -2
  92. package/dist/domains/run/tools/NativeSandboxExecutor.js +76 -48
  93. package/dist/domains/run/tools/SandboxExecutorFactory.d.ts +11 -1
  94. package/dist/domains/run/tools/SandboxExecutorFactory.js +27 -3
  95. package/dist/domains/run/tools/VercelSandboxExecutor.d.ts +3 -11
  96. package/dist/domains/run/tools/VercelSandboxExecutor.js +137 -127
  97. package/dist/domains/run/types/xml.d.ts +1 -5
  98. package/dist/domains/run/utils/stream-helpers.d.ts +134 -0
  99. package/dist/domains/run/utils/stream-helpers.js +182 -0
  100. package/dist/factory.d.ts +278 -272
  101. package/dist/index.d.ts +275 -269
  102. package/dist/index.js +16 -1
  103. package/dist/initialization.js +9 -2
  104. package/dist/middleware/cors.js +1 -1
  105. package/dist/middleware/evalsAuth.d.ts +2 -2
  106. package/dist/middleware/manageAuth.d.ts +2 -2
  107. package/dist/middleware/projectAccess.d.ts +4 -11
  108. package/dist/middleware/projectAccess.js +1 -17
  109. package/dist/middleware/projectConfig.d.ts +3 -3
  110. package/dist/middleware/requirePermission.d.ts +2 -2
  111. package/dist/middleware/runAuth.d.ts +4 -4
  112. package/dist/middleware/sessionAuth.d.ts +3 -3
  113. package/dist/middleware/tenantAccess.d.ts +2 -2
  114. package/dist/middleware/tenantAccess.js +4 -4
  115. package/dist/middleware/tracing.d.ts +3 -3
  116. package/dist/openapi.d.ts +35 -1
  117. package/dist/openapi.js +39 -95
  118. package/dist/routes/healthChecks.d.ts +10 -0
  119. package/dist/routes/healthChecks.js +75 -0
  120. package/dist/templates/v1/phase1/system-prompt.js +1 -1
  121. package/dist/templates/v1/phase1/thinking-preparation.js +1 -1
  122. package/dist/templates/v1/phase1/tool.js +1 -1
  123. package/dist/templates/v1/phase2/data-component.js +1 -1
  124. package/dist/templates/v1/phase2/data-components.js +1 -1
  125. package/dist/templates/v1/phase2/system-prompt.js +1 -1
  126. package/dist/templates/v1/shared/artifact-retrieval-guidance.js +1 -1
  127. package/dist/templates/v1/shared/artifact.js +1 -1
  128. package/dist/types/app.d.ts +2 -0
  129. package/dist/utils/healthChecks.d.ts +8 -0
  130. package/dist/utils/healthChecks.js +38 -0
  131. package/dist/utils/signozHelpers.d.ts +2 -2
  132. package/dist/utils/signozHelpers.js +15 -3
  133. package/package.json +25 -28
  134. package/dist/domains/evals/services/startEvaluation.d.ts +0 -19
  135. package/dist/domains/evals/services/startEvaluation.js +0 -18
  136. package/dist/domains/index.d.ts +0 -4
  137. package/dist/domains/index.js +0 -5
  138. package/dist/domains/manage/routes/agentToolRelations.js +0 -289
  139. package/dist/domains/run/agents/ModelFactory.d.ts +0 -63
  140. package/dist/domains/run/agents/ModelFactory.js +0 -194
  141. package/dist/domains/run/data/agent.d.ts +0 -7
  142. package/dist/domains/run/data/agent.js +0 -67
  143. package/dist/domains/run/services/evaluationRunConfigMatcher.d.ts +0 -4
  144. package/dist/domains/run/services/evaluationRunConfigMatcher.js +0 -7
  145. package/dist/domains/run/utils/cleanup.d.ts +0 -21
  146. package/dist/domains/run/utils/cleanup.js +0 -59
  147. package/dist/utils/tempApiKeys.d.ts +0 -17
  148. package/dist/utils/tempApiKeys.js +0 -26
  149. package/dist/utils/workflowApiHelpers.d.ts +0 -1
  150. package/dist/utils/workflowApiHelpers.js +0 -1
@@ -0,0 +1,45 @@
1
+ import { env } from "../../../env.js";
2
+ import { Hono } from "hono";
3
+ import { StreamableHTTPTransport } from "@hono/mcp";
4
+ import { HeaderForwardingHook, InkeepAgentsCore, SDKHooks, createConsoleLogger, createMCPServer } from "@inkeep/agents-mcp";
5
+
6
+ //#region src/domains/mcp/routes/mcp.ts
7
+ const app = new Hono();
8
+ /**
9
+ * Headers to forward from incoming requests to downstream API calls.
10
+ * x-forwarded-cookie is mapped to cookie for browser compatibility
11
+ * (browsers don't allow setting Cookie header directly).
12
+ */
13
+ const FORWARDED_HEADERS = [
14
+ "x-forwarded-cookie",
15
+ "authorization",
16
+ "cookie"
17
+ ];
18
+ app.all("/", async (c) => {
19
+ const transport = new StreamableHTTPTransport();
20
+ const noOpLogger = createConsoleLogger("error");
21
+ const headersToForward = {};
22
+ for (const headerName of FORWARDED_HEADERS) {
23
+ const value = c.req.header(headerName);
24
+ if (value) headersToForward[headerName] = value;
25
+ }
26
+ if (headersToForward["x-forwarded-cookie"] && !headersToForward.cookie) headersToForward.cookie = headersToForward["x-forwarded-cookie"];
27
+ const createSDKWithHeaders = () => {
28
+ const hooks = new SDKHooks();
29
+ hooks.registerBeforeRequestHook(new HeaderForwardingHook(headersToForward));
30
+ return new InkeepAgentsCore({
31
+ serverURL: env.INKEEP_AGENTS_API_URL,
32
+ hooks
33
+ });
34
+ };
35
+ await createMCPServer({
36
+ logger: noOpLogger,
37
+ serverURL: env.INKEEP_AGENTS_API_URL,
38
+ getSDK: createSDKWithHeaders
39
+ }).server.connect(transport);
40
+ return transport.handleRequest(c);
41
+ });
42
+ var mcp_default = app;
43
+
44
+ //#endregion
45
+ export { mcp_default as default };
@@ -61,11 +61,7 @@ async function handleMessageSend(c, agent, request) {
61
61
  };
62
62
  const task = {
63
63
  id: generateId(),
64
- input: { parts: params.message.parts.map((part) => ({
65
- kind: part.kind,
66
- text: part.kind === "text" ? part.text : void 0,
67
- data: part.kind === "data" ? part.data : void 0
68
- })) },
64
+ input: { parts: params.message.parts },
69
65
  context: {
70
66
  conversationId: params.message.contextId,
71
67
  metadata: {
@@ -320,11 +316,7 @@ async function handleMessageStream(c, agent, request) {
320
316
  else if (cookie) forwardedHeaders["x-forwarded-cookie"] = cookie;
321
317
  const task = {
322
318
  id: generateId(),
323
- input: { parts: params.message.parts.map((part) => ({
324
- kind: part.kind,
325
- text: part.kind === "text" ? part.text : void 0,
326
- data: part.kind === "data" ? part.data : void 0
327
- })) },
319
+ input: { parts: params.message.parts },
328
320
  context: {
329
321
  conversationId: params.message.contextId,
330
322
  metadata: {
@@ -1,4 +1,4 @@
1
- import { AgentCard, Artifact, Message, Task, TaskState } from "@inkeep/agents-core";
1
+ import { AgentCard, Artifact, Message, Part, Task, TaskState } from "@inkeep/agents-core";
2
2
 
3
3
  //#region src/domains/run/a2a/types.d.ts
4
4
  interface RegisteredAgent {
@@ -12,11 +12,7 @@ interface RegisteredAgent {
12
12
  interface A2ATask {
13
13
  id: string;
14
14
  input: {
15
- parts: Array<{
16
- kind: string;
17
- text?: string;
18
- data?: any;
19
- }>;
15
+ parts: Part[];
20
16
  };
21
17
  context?: {
22
18
  conversationId?: string;
@@ -99,6 +99,7 @@ declare class Agent {
99
99
  private mcpConnectionLocks;
100
100
  private currentCompressor;
101
101
  private executionContext;
102
+ private functionToolRelationshipIdByName;
102
103
  constructor(config: AgentConfig, executionContext: FullExecutionContext, credentialStoreRegistry?: CredentialStoreRegistry);
103
104
  /**
104
105
  * Get the maximum number of generation steps for this agent
@@ -15,6 +15,7 @@ import { IncrementalStreamParser } from "../services/IncrementalStreamParser.js"
15
15
  import { MidGenerationCompressor } from "../services/MidGenerationCompressor.js";
16
16
  import { pendingToolApprovalManager } from "../services/PendingToolApprovalManager.js";
17
17
  import { ResponseFormatter } from "../services/ResponseFormatter.js";
18
+ import { toolApprovalUiBus } from "../services/ToolApprovalUiBus.js";
18
19
  import { generateToolId } from "../utils/agent-operations.js";
19
20
  import { jsonSchemaToZod } from "../utils/data-component-schema.js";
20
21
  import { ArtifactCreateSchema, ArtifactReferenceSchema } from "../utils/artifact-component-schema.js";
@@ -25,7 +26,7 @@ import { SystemPromptBuilder } from "./SystemPromptBuilder.js";
25
26
  import { Phase1Config, V1_BREAKDOWN_SCHEMA } from "./versions/v1/Phase1Config.js";
26
27
  import { Phase2Config } from "./versions/v1/Phase2Config.js";
27
28
  import { z } from "@hono/zod-openapi";
28
- import { CredentialStuffer, JsonTransformer, MCPServerType, MCPTransportType, McpClient, ModelFactory, TemplateEngine, createMessage, generateId, getFunctionToolsForSubAgent, getLedgerArtifacts, listTaskIdsByContextId, parseEmbeddedJson, withRef } from "@inkeep/agents-core";
29
+ import { CredentialStuffer, JsonTransformer, MCPServerType, MCPTransportType, McpClient, ModelFactory, TemplateEngine, buildComposioMCPUrl, createMessage, generateId, getFunctionToolsForSubAgent, getLedgerArtifacts, listTaskIdsByContextId, parseEmbeddedJson, withRef } from "@inkeep/agents-core";
29
30
  import { Output, generateText, streamText, tool } from "ai";
30
31
  import { SpanStatusCode, trace } from "@opentelemetry/api";
31
32
 
@@ -66,6 +67,7 @@ var Agent = class {
66
67
  mcpConnectionLocks = /* @__PURE__ */ new Map();
67
68
  currentCompressor = null;
68
69
  executionContext;
70
+ functionToolRelationshipIdByName = /* @__PURE__ */ new Map();
69
71
  constructor(config, executionContext, credentialStoreRegistry) {
70
72
  this.artifactComponents = config.artifactComponents || [];
71
73
  this.executionContext = executionContext;
@@ -135,6 +137,7 @@ var Agent = class {
135
137
  if (tool$1.config.mcp.activeTools?.includes(toolName)) return true;
136
138
  return tool$1.name === toolName;
137
139
  }))?.relationshipId;
140
+ if (toolType === "tool") return this.functionToolRelationshipIdByName.get(toolName);
138
141
  if (toolType === "delegation") return this.config.delegateRelations.find((relation) => this.#createRelationToolName("delegate", relation.config.id) === toolName)?.config.relationId;
139
142
  }
140
143
  /**
@@ -221,6 +224,12 @@ var Agent = class {
221
224
  execute: async (args, context$1) => {
222
225
  const startTime = Date.now();
223
226
  const toolCallId = context$1?.toolCallId || generateToolId();
227
+ const streamHelper = this.getStreamingHelper();
228
+ const chunkString = (s, size = 16) => {
229
+ const out = [];
230
+ for (let i = 0; i < s.length; i += size) out.push(s.slice(i, i + size));
231
+ return out;
232
+ };
224
233
  const activeSpan = trace.getActiveSpan();
225
234
  if (activeSpan) {
226
235
  const attributes = {
@@ -235,14 +244,32 @@ var Agent = class {
235
244
  if (options?.mcpServerName) attributes["ai.toolCall.mcpServerName"] = options.mcpServerName;
236
245
  activeSpan.setAttributes(attributes);
237
246
  }
238
- const isInternalTool = toolName.includes("save_tool_result") || toolName.includes("thinking_complete") || toolName.startsWith("transfer_to_");
247
+ const isInternalToolForUi = toolName.includes("save_tool_result") || toolName.includes("thinking_complete") || toolName.startsWith("transfer_to_") || toolName.startsWith("delegate_to_");
239
248
  const needsApproval = options?.needsApproval || false;
240
- if (streamRequestId && !isInternalTool) {
249
+ if (streamRequestId && streamHelper && !isInternalToolForUi) {
250
+ const inputText = JSON.stringify(args ?? {});
251
+ await streamHelper.writeToolInputStart({
252
+ toolCallId,
253
+ toolName
254
+ });
255
+ for (const part of chunkString(inputText, 16)) await streamHelper.writeToolInputDelta({
256
+ toolCallId,
257
+ inputTextDelta: part
258
+ });
259
+ await streamHelper.writeToolInputAvailable({
260
+ toolCallId,
261
+ toolName,
262
+ input: args ?? {},
263
+ providerMetadata: context$1?.providerMetadata
264
+ });
265
+ }
266
+ if (streamRequestId && !isInternalToolForUi) {
241
267
  const toolCallData = {
242
268
  toolName,
243
269
  input: args,
244
270
  toolCallId,
245
- relationshipId
271
+ relationshipId,
272
+ inDelegatedAgent: this.isDelegatedAgent
246
273
  };
247
274
  if (needsApproval) {
248
275
  toolCallData.needsApproval = true;
@@ -254,7 +281,7 @@ var Agent = class {
254
281
  const result = await originalExecute(args, context$1);
255
282
  const duration = Date.now() - startTime;
256
283
  const toolResultConversationId = this.getToolResultConversationId();
257
- if (streamRequestId && !isInternalTool && toolResultConversationId) try {
284
+ if (streamRequestId && !isInternalToolForUi && toolResultConversationId) try {
258
285
  const messagePayload = {
259
286
  id: generateId(),
260
287
  tenantId: this.config.tenantId,
@@ -282,26 +309,38 @@ var Agent = class {
282
309
  conversationId: toolResultConversationId
283
310
  }, "Failed to store tool result in conversation history");
284
311
  }
285
- if (streamRequestId && !isInternalTool) agentSessionManager.recordEvent(streamRequestId, "tool_result", this.config.id, {
312
+ if (streamRequestId && !isInternalToolForUi) agentSessionManager.recordEvent(streamRequestId, "tool_result", this.config.id, {
286
313
  toolName,
287
314
  output: result,
288
315
  toolCallId,
289
316
  duration,
290
317
  relationshipId,
291
- needsApproval
318
+ needsApproval,
319
+ inDelegatedAgent: this.isDelegatedAgent
320
+ });
321
+ const isDeniedResult = !!result && typeof result === "object" && "__inkeepToolDenied" in result && result.__inkeepToolDenied === true;
322
+ if (streamRequestId && streamHelper && !isInternalToolForUi) if (isDeniedResult) await streamHelper.writeToolOutputDenied({ toolCallId });
323
+ else await streamHelper.writeToolOutputAvailable({
324
+ toolCallId,
325
+ output: result
292
326
  });
293
327
  return result;
294
328
  } catch (error) {
295
329
  const duration = Date.now() - startTime;
296
330
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
297
- if (streamRequestId && !isInternalTool) agentSessionManager.recordEvent(streamRequestId, "tool_result", this.config.id, {
331
+ if (streamRequestId && !isInternalToolForUi) agentSessionManager.recordEvent(streamRequestId, "tool_result", this.config.id, {
298
332
  toolName,
299
333
  output: null,
300
334
  toolCallId,
301
335
  duration,
302
336
  error: errorMessage,
303
337
  relationshipId,
304
- needsApproval
338
+ needsApproval,
339
+ inDelegatedAgent: this.isDelegatedAgent
340
+ });
341
+ if (streamRequestId && streamHelper && !isInternalToolForUi) await streamHelper.writeToolOutputError({
342
+ toolCallId,
343
+ errorText: errorMessage
305
344
  });
306
345
  throw error;
307
346
  }
@@ -372,7 +411,7 @@ var Agent = class {
372
411
  const sessionWrappedTool = tool({
373
412
  description: originalTool.description,
374
413
  inputSchema: originalTool.inputSchema,
375
- execute: async (args, { toolCallId }) => {
414
+ execute: async (args, { toolCallId, providerMetadata }) => {
376
415
  let processedArgs;
377
416
  try {
378
417
  processedArgs = parseEmbeddedJson(args);
@@ -410,22 +449,52 @@ var Agent = class {
410
449
  requestSpan.setStatus({ code: SpanStatusCode.OK });
411
450
  requestSpan.end();
412
451
  });
413
- const approvalResult = await pendingToolApprovalManager.waitForApproval(toolCallId, toolName, args, this.conversationId || "unknown", this.config.id);
414
- if (!approvalResult.approved) return tracer.startActiveSpan("tool.approval_denied", { attributes: {
415
- "tool.name": toolName,
416
- "tool.callId": toolCallId,
417
- "subAgent.id": this.config.id,
418
- "subAgent.name": this.config.name
419
- } }, (denialSpan) => {
420
- logger.info({
421
- toolName,
422
- toolCallId,
423
- reason: approvalResult.reason
424
- }, "Tool execution denied by user");
425
- denialSpan.setStatus({ code: SpanStatusCode.OK });
426
- denialSpan.end();
427
- return `User denied approval to run this tool: ${approvalResult.reason}`;
452
+ const streamHelper = this.getStreamingHelper();
453
+ if (streamHelper) await streamHelper.writeToolApprovalRequest({
454
+ approvalId: `aitxt-${toolCallId}`,
455
+ toolCallId
428
456
  });
457
+ else if (this.isDelegatedAgent) {
458
+ const streamRequestId$1 = this.getStreamRequestId();
459
+ if (streamRequestId$1) await toolApprovalUiBus.publish(streamRequestId$1, {
460
+ type: "approval-needed",
461
+ toolCallId,
462
+ toolName,
463
+ input: finalArgs,
464
+ providerMetadata,
465
+ approvalId: `aitxt-${toolCallId}`
466
+ });
467
+ }
468
+ const approvalResult = await pendingToolApprovalManager.waitForApproval(toolCallId, toolName, args, this.conversationId || "unknown", this.config.id);
469
+ if (!approvalResult.approved) {
470
+ if (!streamHelper && this.isDelegatedAgent) {
471
+ const streamRequestId$1 = this.getStreamRequestId();
472
+ if (streamRequestId$1) await toolApprovalUiBus.publish(streamRequestId$1, {
473
+ type: "approval-resolved",
474
+ toolCallId,
475
+ approved: false
476
+ });
477
+ }
478
+ return tracer.startActiveSpan("tool.approval_denied", { attributes: {
479
+ "tool.name": toolName,
480
+ "tool.callId": toolCallId,
481
+ "subAgent.id": this.config.id,
482
+ "subAgent.name": this.config.name
483
+ } }, (denialSpan) => {
484
+ logger.info({
485
+ toolName,
486
+ toolCallId,
487
+ reason: approvalResult.reason
488
+ }, "Tool execution denied by user");
489
+ denialSpan.setStatus({ code: SpanStatusCode.OK });
490
+ denialSpan.end();
491
+ return {
492
+ __inkeepToolDenied: true,
493
+ toolCallId,
494
+ reason: approvalResult.reason
495
+ };
496
+ });
497
+ }
429
498
  tracer.startActiveSpan("tool.approval_approved", { attributes: {
430
499
  "tool.name": toolName,
431
500
  "tool.callId": toolCallId,
@@ -439,6 +508,14 @@ var Agent = class {
439
508
  approvedSpan.setStatus({ code: SpanStatusCode.OK });
440
509
  approvedSpan.end();
441
510
  });
511
+ if (!streamHelper && this.isDelegatedAgent) {
512
+ const streamRequestId$1 = this.getStreamRequestId();
513
+ if (streamRequestId$1) await toolApprovalUiBus.publish(streamRequestId$1, {
514
+ type: "approval-resolved",
515
+ toolCallId,
516
+ approved: true
517
+ });
518
+ }
442
519
  }
443
520
  logger.debug({
444
521
  toolName,
@@ -475,7 +552,8 @@ var Agent = class {
475
552
  toolCallId,
476
553
  errorMessage,
477
554
  relationshipId
478
- }
555
+ },
556
+ relationshipId
479
557
  });
480
558
  }
481
559
  const activeSpan = trace.getActiveSpan();
@@ -498,10 +576,7 @@ var Agent = class {
498
576
  result: enhancedResult,
499
577
  timestamp: Date.now()
500
578
  });
501
- return {
502
- result: enhancedResult,
503
- toolCallId
504
- };
579
+ return enhancedResult;
505
580
  } catch (error) {
506
581
  logger.error({
507
582
  toolName,
@@ -606,12 +681,7 @@ var Agent = class {
606
681
  headers: agentToolRelationHeaders
607
682
  };
608
683
  }
609
- if (serverConfig.url?.toString().includes("composio.dev")) {
610
- const urlObj = new URL(serverConfig.url.toString());
611
- if (isUserScoped && userId) urlObj.searchParams.set("user_id", userId);
612
- else urlObj.searchParams.set("user_id", `${this.config.tenantId}||${this.config.projectId}`);
613
- serverConfig.url = urlObj.toString();
614
- }
684
+ if (serverConfig.url) serverConfig.url = buildComposioMCPUrl(serverConfig.url.toString(), this.config.tenantId, this.config.projectId, isUserScoped ? "user" : "project", userId);
615
685
  if (this.config.forwardedHeaders && Object.keys(this.config.forwardedHeaders).length > 0) serverConfig.headers = {
616
686
  ...serverConfig.headers,
617
687
  ...this.config.forwardedHeaders
@@ -670,6 +740,7 @@ var Agent = class {
670
740
  "project.id": this.config.projectId || "unknown"
671
741
  } }, (span) => {
672
742
  setSpanWithError$1(span, /* @__PURE__ */ new Error(`0 effective tools available for ${tool$1.name}`));
743
+ const relationshipId = this.#getRelationshipIdForTool(tool$1.name, "mcp");
673
744
  agentSessionManager.recordEvent(streamRequestId, "error", this.config.id, {
674
745
  message: `MCP server has 0 effective tools. Double check the selected tools in your graph and the active tools in the MCP server configuration.`,
675
746
  code: "no_tools_available",
@@ -678,7 +749,8 @@ var Agent = class {
678
749
  toolName: tool$1.name,
679
750
  serverUrl: tool$1.config.type === "mcp" ? tool$1.config.mcp.server.url : "unknown",
680
751
  operation: "mcp_tool_discovery"
681
- }
752
+ },
753
+ relationshipId
682
754
  });
683
755
  span.end();
684
756
  });
@@ -727,8 +799,11 @@ var Agent = class {
727
799
  });
728
800
  })).data ?? [];
729
801
  if (functionToolsData.length === 0) return functionTools;
802
+ this.functionToolRelationshipIdByName = new Map(functionToolsData.flatMap((t) => {
803
+ return t.relationshipId ? [[t.name, t.relationshipId]] : [];
804
+ }));
730
805
  const { SandboxExecutorFactory } = await import("../tools/SandboxExecutorFactory.js");
731
- const sandboxExecutor = SandboxExecutorFactory.getInstance();
806
+ const sandboxExecutor = sessionId ? SandboxExecutorFactory.getForSession(sessionId) : new SandboxExecutorFactory();
732
807
  for (const functionToolDef of functionToolsData) {
733
808
  const functionId = functionToolDef.functionId;
734
809
  if (!functionId) {
@@ -744,10 +819,12 @@ var Agent = class {
744
819
  continue;
745
820
  }
746
821
  const zodSchema = jsonSchemaToZod(functionData.inputSchema);
822
+ const toolPolicies = functionToolDef.toolPolicies;
823
+ const needsApproval = !!toolPolicies?.["*"]?.needsApproval || !!toolPolicies?.[functionToolDef.name]?.needsApproval;
747
824
  const aiTool = tool({
748
825
  description: functionToolDef.description || functionToolDef.name,
749
826
  inputSchema: zodSchema,
750
- execute: async (args, { toolCallId }) => {
827
+ execute: async (args, { toolCallId, providerMetadata }) => {
751
828
  let processedArgs;
752
829
  try {
753
830
  processedArgs = parseEmbeddedJson(args);
@@ -764,6 +841,95 @@ var Agent = class {
764
841
  processedArgs = args;
765
842
  }
766
843
  const finalArgs = processedArgs;
844
+ if (needsApproval) {
845
+ logger.info({
846
+ toolName: functionToolDef.name,
847
+ toolCallId,
848
+ args: finalArgs
849
+ }, "Function tool requires approval - waiting for user response");
850
+ const currentSpan = trace.getActiveSpan();
851
+ if (currentSpan) currentSpan.addEvent("tool.approval.requested", {
852
+ "tool.name": functionToolDef.name,
853
+ "tool.callId": toolCallId,
854
+ "subAgent.id": this.config.id
855
+ });
856
+ tracer.startActiveSpan("tool.approval_requested", { attributes: {
857
+ "tool.name": functionToolDef.name,
858
+ "tool.callId": toolCallId,
859
+ "subAgent.id": this.config.id,
860
+ "subAgent.name": this.config.name
861
+ } }, (requestSpan) => {
862
+ requestSpan.setStatus({ code: SpanStatusCode.OK });
863
+ requestSpan.end();
864
+ });
865
+ const streamHelper = this.getStreamingHelper();
866
+ if (streamHelper) await streamHelper.writeToolApprovalRequest({
867
+ approvalId: `aitxt-${toolCallId}`,
868
+ toolCallId
869
+ });
870
+ else if (this.isDelegatedAgent) {
871
+ const streamRequestId$1 = this.getStreamRequestId();
872
+ if (streamRequestId$1) await toolApprovalUiBus.publish(streamRequestId$1, {
873
+ type: "approval-needed",
874
+ toolCallId,
875
+ toolName: functionToolDef.name,
876
+ input: finalArgs,
877
+ providerMetadata,
878
+ approvalId: `aitxt-${toolCallId}`
879
+ });
880
+ }
881
+ const approvalResult = await pendingToolApprovalManager.waitForApproval(toolCallId, functionToolDef.name, args, this.conversationId || "unknown", this.config.id);
882
+ if (!approvalResult.approved) {
883
+ if (!streamHelper && this.isDelegatedAgent) {
884
+ const streamRequestId$1 = this.getStreamRequestId();
885
+ if (streamRequestId$1) await toolApprovalUiBus.publish(streamRequestId$1, {
886
+ type: "approval-resolved",
887
+ toolCallId,
888
+ approved: false
889
+ });
890
+ }
891
+ return tracer.startActiveSpan("tool.approval_denied", { attributes: {
892
+ "tool.name": functionToolDef.name,
893
+ "tool.callId": toolCallId,
894
+ "subAgent.id": this.config.id,
895
+ "subAgent.name": this.config.name
896
+ } }, (denialSpan) => {
897
+ logger.info({
898
+ toolName: functionToolDef.name,
899
+ toolCallId,
900
+ reason: approvalResult.reason
901
+ }, "Function tool execution denied by user");
902
+ denialSpan.setStatus({ code: SpanStatusCode.OK });
903
+ denialSpan.end();
904
+ return {
905
+ __inkeepToolDenied: true,
906
+ toolCallId,
907
+ reason: approvalResult.reason
908
+ };
909
+ });
910
+ }
911
+ tracer.startActiveSpan("tool.approval_approved", { attributes: {
912
+ "tool.name": functionToolDef.name,
913
+ "tool.callId": toolCallId,
914
+ "subAgent.id": this.config.id,
915
+ "subAgent.name": this.config.name
916
+ } }, (approvedSpan) => {
917
+ logger.info({
918
+ toolName: functionToolDef.name,
919
+ toolCallId
920
+ }, "Function tool approved, continuing with execution");
921
+ approvedSpan.setStatus({ code: SpanStatusCode.OK });
922
+ approvedSpan.end();
923
+ });
924
+ if (!streamHelper && this.isDelegatedAgent) {
925
+ const streamRequestId$1 = this.getStreamRequestId();
926
+ if (streamRequestId$1) await toolApprovalUiBus.publish(streamRequestId$1, {
927
+ type: "approval-resolved",
928
+ toolCallId,
929
+ approved: true
930
+ });
931
+ }
932
+ }
767
933
  logger.debug({
768
934
  toolName: functionToolDef.name,
769
935
  toolCallId,
@@ -790,10 +956,7 @@ var Agent = class {
790
956
  result,
791
957
  timestamp: Date.now()
792
958
  });
793
- return {
794
- result,
795
- toolCallId
796
- };
959
+ return result;
797
960
  } catch (error) {
798
961
  logger.error({
799
962
  toolName: functionToolDef.name,
@@ -804,7 +967,7 @@ var Agent = class {
804
967
  }
805
968
  }
806
969
  });
807
- functionTools[functionToolDef.name] = this.wrapToolWithStreaming(functionToolDef.name, aiTool, streamRequestId || "", "tool");
970
+ functionTools[functionToolDef.name] = this.wrapToolWithStreaming(functionToolDef.name, aiTool, streamRequestId || "", "tool", { needsApproval });
808
971
  }
809
972
  } catch (error) {
810
973
  logger.error({ error }, "Failed to load function tools from database");
@@ -15,7 +15,13 @@ const createTaskHandler = (config, credentialStoreRegistry) => {
15
15
  return async (task) => {
16
16
  let agent;
17
17
  try {
18
- const userMessage = task.input.parts.filter((part) => part.text).map((part) => part.text).join(" ");
18
+ const textParts = task.input.parts.filter((part) => part.kind === "text").map((part) => part.text).join(" ");
19
+ const dataParts = task.input.parts.filter((part) => part.kind === "data" && part.data != null);
20
+ let userMessage = textParts;
21
+ if (dataParts.length > 0) userMessage = `${textParts}${dataParts.map((part) => {
22
+ const metadata = part.metadata;
23
+ return `\n\n<structured_data${metadata?.source ? ` (source: ${metadata.source})` : ""}>\n${JSON.stringify(part.data, null, 2)}\n</structured_data>`;
24
+ }).join("")}`;
19
25
  if (!userMessage.trim()) return {
20
26
  status: {
21
27
  state: TaskState.Failed,
@@ -224,7 +230,13 @@ const createTaskHandler = (config, credentialStoreRegistry) => {
224
230
  if (streamRequestId && tenantId && projectId) toolSessionManager.ensureAgentSession(streamRequestId, tenantId, projectId, contextId, task.id);
225
231
  }
226
232
  logger.info({ contextId }, "Context ID");
227
- logger.info({ userMessage }, "User Message");
233
+ logger.info({
234
+ userMessage: userMessage.substring(0, 500),
235
+ inputPartsCount: task.input.parts.length,
236
+ textPartsCount: task.input.parts.filter((p) => p.kind === "text").length,
237
+ dataPartsCount: task.input.parts.filter((p) => p.kind === "data").length,
238
+ hasDataParts: task.input.parts.some((p) => p.kind === "data")
239
+ }, "User Message with parts breakdown");
228
240
  const response = await agent.generate(userMessage, {
229
241
  contextId,
230
242
  metadata: {
@@ -1,4 +1,4 @@
1
- import { validateAgainstJsonSchema } from "./validation.js";
1
+ import { validationHelper } from "./validation.js";
2
2
  import { CredentialStuffer, JsonTransformer, TemplateEngine, getLogger } from "@inkeep/agents-core";
3
3
 
4
4
  //#region src/domains/run/context/ContextFetcher.ts
@@ -228,16 +228,17 @@ var ContextFetcher = class {
228
228
  * Validate response against JSON Schema
229
229
  */
230
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";
231
+ const validate = validationHelper(jsonSchema);
232
+ if (!validate(data)) {
233
+ const errors = validate.errors || [];
234
+ const formattedErrors = errors.map((e) => `${e.instancePath || "/"}: ${e.message}`).join("; ");
235
235
  logger.error({
236
236
  definitionId,
237
237
  jsonSchema,
238
- error: errorMessage
238
+ errors,
239
+ formattedErrors
239
240
  }, "JSON Schema response validation failed");
240
- throw new Error(`Response validation failed: ${errorMessage}`);
241
+ throw new Error(`Response validation failed: ${formattedErrors}`);
241
242
  }
242
243
  }
243
244
  /**
@@ -1,8 +1,8 @@
1
1
  import { ContextCache } from "./contextCache.js";
2
2
  import { ContextFetcher, MissingRequiredVariableError } from "./ContextFetcher.js";
3
3
  import { getLogger, getTracer, setSpanWithError } from "@inkeep/agents-core";
4
- import { SpanStatusCode } from "@opentelemetry/api";
5
4
  import crypto from "node:crypto";
5
+ import { SpanStatusCode } from "@opentelemetry/api";
6
6
 
7
7
  //#region src/domains/run/context/ContextResolver.ts
8
8
  const logger = getLogger("context-resolver");
@@ -1,11 +1,13 @@
1
1
  import { StreamHelper } from "../utils/stream-helpers.js";
2
- import { FullExecutionContext } from "@inkeep/agents-core";
2
+ import { FullExecutionContext, Part } from "@inkeep/agents-core";
3
3
 
4
4
  //#region src/domains/run/handlers/executionHandler.d.ts
5
5
  interface ExecutionHandlerParams {
6
6
  executionContext: FullExecutionContext;
7
7
  conversationId: string;
8
8
  userMessage: string;
9
+ /** Optional message parts for rich content (text + data). Used on first iteration only. */
10
+ messageParts?: Part[];
9
11
  initialAgentId: string;
10
12
  requestId: string;
11
13
  sseHelper: StreamHelper;