@inkeep/agents-run-api 0.41.0 → 0.41.2

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.
@@ -52,11 +52,9 @@ async function handleMessageSend(c, agent, request) {
52
52
  const { agentId } = getRequestExecutionContext(c);
53
53
  const forwardedHeaders = {};
54
54
  const xForwardedCookie = c.req.header("x-forwarded-cookie");
55
- const authorization = c.req.header("authorization");
56
55
  const cookie = c.req.header("cookie");
57
56
  if (xForwardedCookie) forwardedHeaders["x-forwarded-cookie"] = xForwardedCookie;
58
57
  else if (cookie) forwardedHeaders["x-forwarded-cookie"] = cookie;
59
- if (authorization) forwardedHeaders.authorization = authorization;
60
58
  const task = {
61
59
  id: generateId(),
62
60
  input: { parts: params.message.parts.map((part) => ({
@@ -307,11 +305,9 @@ async function handleMessageStream(c, agent, request) {
307
305
  });
308
306
  const forwardedHeaders = {};
309
307
  const xForwardedCookie = c.req.header("x-forwarded-cookie");
310
- const authorization = c.req.header("authorization");
311
308
  const cookie = c.req.header("cookie");
312
309
  if (xForwardedCookie) forwardedHeaders["x-forwarded-cookie"] = xForwardedCookie;
313
310
  else if (cookie) forwardedHeaders["x-forwarded-cookie"] = cookie;
314
- if (authorization) forwardedHeaders.authorization = authorization;
315
311
  const task = {
316
312
  id: generateId(),
317
313
  input: { parts: params.message.parts.map((part) => ({
@@ -1047,7 +1047,7 @@ var Agent = class {
1047
1047
  }
1048
1048
  getArtifactTools() {
1049
1049
  return tool({
1050
- 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.",
1050
+ description: "Call this tool to retrieve EXISTING artifacts that were previously created and saved. This tool is for accessing artifacts that already exist, NOT for extracting tool results. Only use this when you need the complete artifact data and the summary shown in your context is insufficient.",
1051
1051
  inputSchema: z.object({
1052
1052
  artifactId: z.string().describe("The unique identifier of the artifact to get."),
1053
1053
  toolCallId: z.string().describe("The tool call ID associated with this artifact.")
@@ -1643,11 +1643,13 @@ ${typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, nu
1643
1643
  if (error && typeof error === "object" && "name" in error && error.name === "connection_refused") return true;
1644
1644
  }
1645
1645
  }
1646
- if (steps.length >= 2) {
1647
- const previousStep = steps[steps.length - 2];
1648
- if (previousStep && "toolCalls" in previousStep && previousStep.toolCalls) {
1649
- const stopToolNames = includeThinkingComplete ? ["transfer_to_", "thinking_complete"] : ["transfer_to_"];
1650
- if (previousStep.toolCalls.some((tc) => stopToolNames.some((toolName) => toolName.endsWith("_") ? tc.toolName.startsWith(toolName) : tc.toolName === toolName)) && "toolResults" in previousStep && previousStep.toolResults) return true;
1646
+ if (steps.length >= 1) {
1647
+ const currentStep = steps[steps.length - 1];
1648
+ if (currentStep && "toolCalls" in currentStep && currentStep.toolCalls) {
1649
+ const hasTransferTool = currentStep.toolCalls.some((tc) => tc.toolName.startsWith("transfer_to_"));
1650
+ const hasThinkingComplete = currentStep.toolCalls.some((tc) => tc.toolName === "thinking_complete");
1651
+ if (hasTransferTool) return true;
1652
+ if (includeThinkingComplete && hasThinkingComplete && "toolResults" in currentStep && currentStep.toolResults) return true;
1651
1653
  }
1652
1654
  }
1653
1655
  return steps.length >= this.getMaxGenerationSteps();
@@ -1777,8 +1779,13 @@ ${output}${structureHintsFormatted}`;
1777
1779
  componentSchemas.push(ArtifactReferenceSchema.getSchema());
1778
1780
  }
1779
1781
  let dataComponentsSchema;
1780
- if (componentSchemas.length === 1) dataComponentsSchema = componentSchemas[0];
1781
- else dataComponentsSchema = z.union(componentSchemas);
1782
+ if (componentSchemas.length === 1) {
1783
+ dataComponentsSchema = componentSchemas[0];
1784
+ logger.info({ agentId: this.config.id }, "Using single schema (no union needed)");
1785
+ } else {
1786
+ dataComponentsSchema = z.union(componentSchemas);
1787
+ logger.info({ agentId: this.config.id }, "Created union schema");
1788
+ }
1782
1789
  return dataComponentsSchema;
1783
1790
  }
1784
1791
  calculatePhase2Timeout(structuredModelSettings) {
@@ -38,14 +38,24 @@ ${config.tools.map((tool$1) => {
38
38
  const toolsList = tool$1.availableTools?.map((t) => ` - ${t.name}: ${t.description || "No description available"}`).join("\n") || "";
39
39
  return `MCP Server: ${tool$1.name}\n${toolsList}`;
40
40
  }).join("\n\n")}`;
41
- return `Hand off the conversation to agent ${config.id}.
41
+ return `🚨 CRITICAL TRANSFER PROTOCOL 🚨
42
+
43
+ This tool immediately transfers conversation control to agent ${config.id}.
44
+
45
+ ⚠️ MANDATORY BEHAVIOR:
46
+ 1. DO NOT write any response to the user
47
+ 2. DO NOT explain what you're doing
48
+ 3. DO NOT provide partial answers
49
+ 4. ONLY call this tool and STOP
42
50
 
43
51
  Agent Information:
44
52
  - ID: ${config.id}
45
53
  - Name: ${config.name ?? "No name provided"}
46
54
  - Description: ${config.description ?? "No description provided"}${toolsSection}${transferSection}${delegateSection}
47
55
 
48
- Hand off the conversation to agent ${config.id} when the user's request would be better handled by this specialized agent.`;
56
+ 🔄 Use when: The user's request is better handled by this specialized agent.
57
+
58
+ ⛔ VIOLATION WARNING: Any text generation before/after this tool call will create a disjointed user experience. The receiving agent will provide the complete response.`;
49
59
  };
50
60
  const generateDelegateToolDescription = (delegateRelation) => {
51
61
  const config = delegateRelation.config;
@@ -70,7 +80,7 @@ ${agentConfig.transferRelations.map((transfer) => ` - ${transfer.name || transf
70
80
  Can Delegate To:
71
81
  ${agentConfig.delegateRelations.map((delegate) => ` - ${delegate.config.name || delegate.config.id}: ${delegate.config.description || "No description available"} (${delegate.type})`).join("\n")}`;
72
82
  }
73
- return `Delegate a specific task to another agent.
83
+ return `Delegate a specific task to another agent and wait for their response.
74
84
 
75
85
  Agent Information:
76
86
  - ID: ${config.id}
@@ -78,7 +88,9 @@ Agent Information:
78
88
  - Description: ${config.description || "No description provided"}
79
89
  - Type: ${delegateRelation.type}${toolsSection}${transferSection}${delegateSection}
80
90
 
81
- Delegate a specific task to agent ${config.id} when it seems like the agent can do relevant work.`;
91
+ Delegate a specific task to agent ${config.id} when it can do relevant work. The delegated agent will return results that you can incorporate into your response to the user.
92
+
93
+ NOTE: Unlike transfers, delegation returns control back to you with the delegated agent's results.`;
82
94
  };
83
95
  const createTransferToAgentTool = ({ transferConfig, callingAgentId, subAgent, streamRequestId }) => {
84
96
  return tool({
@@ -103,9 +103,20 @@ var Phase1Config = class Phase1Config {
103
103
  if (!hasTransferRelations) return "";
104
104
  return `You are part of a single unified assistant composed of specialized agents. To the user, you must always appear as one continuous, confident voice.
105
105
 
106
- You have transfer_to_* tools that seamlessly continue the conversation. When you determine another agent should handle a request: ONLY call the appropriate transfer_to_* tool. Do not provide any substantive answer, limitation, or explanation before transferring. NEVER announce, describe, or apologize for a transfer.
107
-
108
- Do NOT stream any text when transferring - call the transfer tool IMMEDIATELY. Do NOT acknowledge the request, do NOT say "Looking into that...", "Let me search...", "I'll help you find...", or provide ANY explanatory text. Place all reasoning or handoff details inside the transfer tool call, not in the user message. The tool call is sufficient - no additional text should be generated.
106
+ 🚨 CRITICAL TRANSFER PROTOCOL 🚨
107
+ When you determine another agent should handle a request:
108
+ 1. IMMEDIATELY call the appropriate transfer_to_* tool
109
+ 2. Generate ZERO text in your response - no words, no explanations, no acknowledgments
110
+ 3. Do NOT stream any content - the tool call must be your ONLY output
111
+
112
+ FORBIDDEN BEFORE TRANSFERS:
113
+ ❌ Do NOT acknowledge the request ("I understand you want...")
114
+ ❌ Do NOT provide partial answers ("The basics are..." then transfer)
115
+ ❌ Do NOT explain what you're doing ("Let me search...", "I'll help you find...")
116
+ ❌ Do NOT apologize or announce transfers ("I'll need to transfer you...")
117
+ ❌ Do NOT generate ANY text content whatsoever - just call the transfer tool
118
+
119
+ REMEMBER: Tool call = complete response. No additional text generation allowed.
109
120
 
110
121
  CRITICAL: When you receive a user message that ends with "Please continue from where this conversation was left off" - this indicates you are continuing a conversation that another agent started. You should:
111
122
  - Review the conversation history to see what was already communicated to the user
package/dist/env.d.ts CHANGED
@@ -17,11 +17,11 @@ declare const envSchema: z.ZodObject<{
17
17
  INKEEP_AGENTS_RUN_API_URL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
18
18
  AGENTS_MANAGE_UI_URL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
19
19
  LOG_LEVEL: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
20
- error: "error";
21
20
  trace: "trace";
22
21
  debug: "debug";
23
22
  info: "info";
24
23
  warn: "warn";
24
+ error: "error";
25
25
  }>>>;
26
26
  NANGO_SERVER_URL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
27
27
  NANGO_SECRET_KEY: z.ZodOptional<z.ZodString>;
@@ -38,7 +38,7 @@ declare const env: {
38
38
  ENVIRONMENT: "development" | "production" | "test" | "pentest";
39
39
  INKEEP_AGENTS_RUN_API_URL: string;
40
40
  AGENTS_MANAGE_UI_URL: string;
41
- LOG_LEVEL: "error" | "trace" | "debug" | "info" | "warn";
41
+ LOG_LEVEL: "trace" | "debug" | "info" | "warn" | "error";
42
42
  NANGO_SERVER_URL: string;
43
43
  ANTHROPIC_API_KEY: string;
44
44
  OTEL_BSP_SCHEDULE_DELAY: number;
@@ -517,16 +517,22 @@ var AgentSession = class {
517
517
  }, "Failed to fetch conversation history for structured status update");
518
518
  }
519
519
  const previousSummaryContext = previousSummaries.length > 0 ? `\nPrevious updates sent to user:\n${previousSummaries.map((s, i) => `${i + 1}. ${s}`).join("\n")}\n` : "";
520
- const selectionSchema = z.object(Object.fromEntries([["no_relevant_updates", z.object({ no_updates: z.boolean().default(true) }).optional().describe("Use when nothing substantially new to report. Should only use on its own.")], ...statusComponents.map((component) => [component.type, this.getComponentSchema(component).optional().describe(component.description || component.type)])]));
520
+ const selectionSchema = z.object({ updates: z.array(z.union([z.object({
521
+ type: z.literal("no_relevant_updates"),
522
+ data: z.object({ no_updates: z.boolean().default(true) }).describe("Use when nothing substantially new to report. Should only use on its own.")
523
+ }), ...statusComponents.map((component) => z.object({
524
+ type: z.literal(component.type),
525
+ data: this.getComponentSchema(component).describe(component.description || component.type)
526
+ }))])) });
521
527
  const prompt = `Generate status updates for relevant components based on what the user has asked for.${conversationContext}${previousSummaries.length > 0 ? `\n${previousSummaryContext}` : ""}
522
528
 
523
529
  Activities:\n${userVisibleActivities.join("\n") || "No New Activities"}
524
530
 
525
- Available components: no_relevant_updates, ${statusComponents.map((c) => c.type).join(", ")}
531
+ Available component types: no_relevant_updates, ${statusComponents.map((c) => c.type).join(", ")}
526
532
 
527
533
  Rules:
528
- - Fill in data for relevant components only
529
- - Use 'no_relevant_updates' if nothing substantially new to report. DO NOT WRITE LABELS OR USE OTHER COMPONENTS IF YOU USE THIS COMPONENT.
534
+ - Return an array of updates for relevant components
535
+ - Use 'no_relevant_updates' type if nothing substantially new to report. DO NOT INCLUDE OTHER COMPONENT TYPES IF YOU USE THIS ONE.
530
536
  - Never repeat previous values, make every update EXTREMELY unique. If you cannot do that the update is not worth mentioning.
531
537
  - Labels MUST be short 3-7 word phrases with ACTUAL information discovered. NEVER MAKE UP SOMETHING WITHOUT BACKING IT UP WITH ACTUAL INFORMATION.
532
538
  - Use sentence case: only capitalize the first word and proper nouns (e.g., "Admin permissions required", not "Admin Permissions Required"). ALWAYS capitalize the first word of the label.
@@ -595,21 +601,19 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
595
601
  const result = object;
596
602
  logger.info({ result: JSON.stringify(result) }, "DEBUG: Result");
597
603
  const summaries = [];
598
- for (const [componentId, data] of Object.entries(result)) {
599
- logger.info({
600
- componentId,
601
- data: JSON.stringify(data)
602
- }, "DEBUG: Component data");
603
- if (componentId === "no_relevant_updates") continue;
604
- if (data && typeof data === "object" && Object.keys(data).length > 0) summaries.push({
605
- type: componentId,
606
- data
604
+ const updates = result.updates || [];
605
+ for (const update of updates) {
606
+ logger.info({ update: JSON.stringify(update) }, "DEBUG: Update data");
607
+ if (update.type === "no_relevant_updates") continue;
608
+ if (update.data && typeof update.data === "object" && Object.keys(update.data).length > 0) summaries.push({
609
+ type: update.type,
610
+ data: update.data
607
611
  });
608
612
  }
609
613
  span.setAttributes({
610
614
  "summaries.count": summaries.length,
611
615
  "user_activities.count": userVisibleActivities.length,
612
- "result_keys.count": Object.keys(result).length
616
+ "updates.count": updates.length
613
617
  });
614
618
  span.setStatus({ code: SpanStatusCode.OK });
615
619
  return { summaries };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-run-api",
3
- "version": "0.41.0",
3
+ "version": "0.41.2",
4
4
  "description": "Agents Run API for Inkeep Agent Framework - handles chat, agent execution, and streaming",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -41,7 +41,7 @@
41
41
  "hono": "^4.10.4",
42
42
  "jmespath": "^0.16.0",
43
43
  "llm-info": "^1.0.69",
44
- "@inkeep/agents-core": "^0.41.0"
44
+ "@inkeep/agents-core": "^0.41.2"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@hono/zod-openapi": "^1.1.5",