@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.
Files changed (85) hide show
  1. package/README.md +2 -1
  2. package/dist/a2a/client.d.ts +3 -1
  3. package/dist/a2a/client.js +23 -9
  4. package/dist/a2a/handlers.js +11 -5
  5. package/dist/a2a/transfer.d.ts +6 -1
  6. package/dist/a2a/transfer.js +10 -6
  7. package/dist/agents/Agent.d.ts +8 -4
  8. package/dist/agents/Agent.js +226 -92
  9. package/dist/agents/ToolSessionManager.js +2 -2
  10. package/dist/agents/generateTaskHandler.d.ts +4 -9
  11. package/dist/agents/generateTaskHandler.js +107 -246
  12. package/dist/agents/relationTools.d.ts +19 -8
  13. package/dist/agents/relationTools.js +105 -14
  14. package/dist/agents/types.d.ts +4 -2
  15. package/dist/agents/versions/v1/Phase1Config.d.ts +4 -3
  16. package/dist/agents/versions/v1/Phase1Config.js +33 -20
  17. package/dist/constants/execution-limits/index.js +1 -1
  18. package/dist/context/ContextFetcher.d.ts +68 -0
  19. package/dist/context/ContextFetcher.js +276 -0
  20. package/dist/context/ContextResolver.d.ts +56 -0
  21. package/dist/context/ContextResolver.js +273 -0
  22. package/dist/context/context.d.ts +19 -0
  23. package/dist/context/context.js +108 -0
  24. package/dist/context/contextCache.d.ts +56 -0
  25. package/dist/context/contextCache.js +175 -0
  26. package/dist/context/index.d.ts +6 -0
  27. package/dist/context/index.js +7 -0
  28. package/dist/context/validation.d.ts +39 -0
  29. package/dist/context/validation.js +255 -0
  30. package/dist/create-app.d.ts +2 -2
  31. package/dist/create-app.js +7 -2
  32. package/dist/data/agent.d.ts +2 -2
  33. package/dist/data/agent.js +17 -22
  34. package/dist/data/agents.d.ts +2 -2
  35. package/dist/data/agents.js +34 -42
  36. package/dist/data/conversations.d.ts +2 -1
  37. package/dist/data/conversations.js +7 -8
  38. package/dist/data/db/dbClient.d.ts +2 -2
  39. package/dist/data/db/dbClient.js +2 -10
  40. package/dist/env.d.ts +6 -2
  41. package/dist/env.js +3 -1
  42. package/dist/handlers/executionHandler.d.ts +3 -2
  43. package/dist/handlers/executionHandler.js +46 -22
  44. package/dist/index.d.ts +3 -3
  45. package/dist/middleware/api-key-auth.d.ts +4 -10
  46. package/dist/middleware/api-key-auth.js +164 -163
  47. package/dist/middleware/index.d.ts +3 -2
  48. package/dist/middleware/index.js +3 -2
  49. package/dist/middleware/projectConfig.d.ts +19 -0
  50. package/dist/middleware/projectConfig.js +80 -0
  51. package/dist/routes/agents.d.ts +2 -1
  52. package/dist/routes/agents.js +7 -13
  53. package/dist/routes/chat.d.ts +2 -1
  54. package/dist/routes/chat.js +29 -52
  55. package/dist/routes/chatDataStream.d.ts +2 -1
  56. package/dist/routes/chatDataStream.js +28 -30
  57. package/dist/routes/mcp.d.ts +2 -1
  58. package/dist/routes/mcp.js +25 -37
  59. package/dist/services/AgentSession.d.ts +5 -7
  60. package/dist/services/AgentSession.js +25 -34
  61. package/dist/services/ArtifactParser.d.ts +2 -2
  62. package/dist/services/ArtifactParser.js +2 -2
  63. package/dist/services/ArtifactService.d.ts +2 -3
  64. package/dist/services/ArtifactService.js +23 -20
  65. package/dist/services/BaseCompressor.js +2 -2
  66. package/dist/services/IncrementalStreamParser.d.ts +2 -2
  67. package/dist/services/IncrementalStreamParser.js +2 -2
  68. package/dist/services/ResponseFormatter.d.ts +2 -2
  69. package/dist/services/ResponseFormatter.js +2 -2
  70. package/dist/services/evaluationHttpClient.d.ts +21 -0
  71. package/dist/services/evaluationHttpClient.js +48 -0
  72. package/dist/services/evaluationRunConfigMatcher.d.ts +6 -0
  73. package/dist/services/evaluationRunConfigMatcher.js +7 -0
  74. package/dist/tools/NativeSandboxExecutor.js +1 -1
  75. package/dist/tools/distill-conversation-history-tool.js +2 -2
  76. package/dist/tools/distill-conversation-tool.js +2 -2
  77. package/dist/types/execution-context.d.ts +8 -14
  78. package/dist/types/execution-context.js +3 -2
  79. package/dist/utils/model-resolver.d.ts +2 -2
  80. package/dist/utils/model-resolver.js +3 -13
  81. package/dist/utils/project.d.ts +207 -0
  82. package/dist/utils/project.js +315 -0
  83. package/dist/utils/token-estimator.d.ts +6 -52
  84. package/dist/utils/token-estimator.js +2 -38
  85. package/package.json +2 -2
package/dist/env.d.ts CHANGED
@@ -13,8 +13,10 @@ declare const envSchema: z.ZodObject<{
13
13
  test: "test";
14
14
  pentest: "pentest";
15
15
  }>>>;
16
- DATABASE_URL: z.ZodOptional<z.ZodString>;
17
16
  INKEEP_AGENTS_RUN_API_URL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
17
+ INKEEP_AGENTS_MANAGE_API_URL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
18
+ INKEEP_AGENTS_EVAL_API_URL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
19
+ INKEEP_AGENTS_RUN_DATABASE_URL: z.ZodOptional<z.ZodString>;
18
20
  AGENTS_MANAGE_UI_URL: z.ZodDefault<z.ZodOptional<z.ZodString>>;
19
21
  LOG_LEVEL: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
20
22
  trace: "trace";
@@ -37,6 +39,8 @@ declare const envSchema: z.ZodObject<{
37
39
  declare const env: {
38
40
  ENVIRONMENT: "development" | "production" | "test" | "pentest";
39
41
  INKEEP_AGENTS_RUN_API_URL: string;
42
+ INKEEP_AGENTS_MANAGE_API_URL: string;
43
+ INKEEP_AGENTS_EVAL_API_URL: string;
40
44
  AGENTS_MANAGE_UI_URL: string;
41
45
  LOG_LEVEL: "trace" | "debug" | "info" | "warn" | "error";
42
46
  NANGO_SERVER_URL: string;
@@ -44,7 +48,7 @@ declare const env: {
44
48
  OTEL_BSP_SCHEDULE_DELAY: number;
45
49
  OTEL_BSP_MAX_EXPORT_BATCH_SIZE: number;
46
50
  NODE_ENV?: "development" | "production" | "test" | undefined;
47
- DATABASE_URL?: string | undefined;
51
+ INKEEP_AGENTS_RUN_DATABASE_URL?: string | undefined;
48
52
  NANGO_SECRET_KEY?: string | undefined;
49
53
  OPENAI_API_KEY?: string | undefined;
50
54
  GOOGLE_GENERATIVE_AI_API_KEY?: string | undefined;
package/dist/env.js CHANGED
@@ -15,8 +15,10 @@ const envSchema = z.object({
15
15
  "pentest",
16
16
  "test"
17
17
  ]).optional().default("development"),
18
- DATABASE_URL: z.string().optional(),
19
18
  INKEEP_AGENTS_RUN_API_URL: z.string().optional().default("http://localhost:3003"),
19
+ INKEEP_AGENTS_MANAGE_API_URL: z.string().optional().default("http://localhost:3002"),
20
+ INKEEP_AGENTS_EVAL_API_URL: z.string().optional().default("http://localhost:3005"),
21
+ INKEEP_AGENTS_RUN_DATABASE_URL: z.string().optional(),
20
22
  AGENTS_MANAGE_UI_URL: z.string().optional().default("http://localhost:3000"),
21
23
  LOG_LEVEL: z.enum([
22
24
  "trace",
@@ -1,15 +1,16 @@
1
1
  import { StreamHelper } from "../utils/stream-helpers.js";
2
- import { ExecutionContext } from "@inkeep/agents-core";
2
+ import { FullExecutionContext } from "@inkeep/agents-core";
3
3
 
4
4
  //#region src/handlers/executionHandler.d.ts
5
5
  interface ExecutionHandlerParams {
6
- executionContext: ExecutionContext;
6
+ executionContext: FullExecutionContext;
7
7
  conversationId: string;
8
8
  userMessage: string;
9
9
  initialAgentId: string;
10
10
  requestId: string;
11
11
  sseHelper: StreamHelper;
12
12
  emitOperations?: boolean;
13
+ datasetRunId?: string;
13
14
  /** Headers to forward to MCP servers (e.g., x-forwarded-cookie for auth) */
14
15
  forwardedHeaders?: Record<string, string>;
15
16
  }
@@ -1,6 +1,7 @@
1
- import { getLogger } from "../logger.js";
1
+ import { getLogger as getLogger$1 } from "../logger.js";
2
2
  import { flushBatchProcessor } from "../instrumentation.js";
3
3
  import dbClient_default from "../data/db/dbClient.js";
4
+ import { getUserIdFromContext } from "../types/execution-context.js";
4
5
  import { AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS } from "../constants/execution-limits/index.js";
5
6
  import { tracer } from "../utils/tracer.js";
6
7
  import { registerStreamHelper, unregisterStreamHelper } from "../utils/stream-registry.js";
@@ -10,11 +11,12 @@ import { agentInitializingOp, completionOp, errorOp } from "../utils/agent-opera
10
11
  import { A2AClient } from "../a2a/client.js";
11
12
  import { extractTransferData, isTransferTask } from "../a2a/types.js";
12
13
  import { executeTransfer } from "../a2a/transfer.js";
14
+ import { triggerConversationEvaluationHttp } from "../services/evaluationHttpClient.js";
13
15
  import { BufferingStreamHelper } from "../utils/stream-helpers.js";
14
- import { AGENT_EXECUTION_TRANSFER_COUNT_DEFAULT, createMessage, createTask, generateId, getActiveAgentForConversation, getAgentWithDefaultSubAgent, getFullAgent, getTask, setSpanWithError, updateTask } from "@inkeep/agents-core";
16
+ import { AGENT_EXECUTION_TRANSFER_COUNT_DEFAULT, createMessage, createTask, generateId, getActiveAgentForConversation, getTask, setSpanWithError, updateTask } from "@inkeep/agents-core";
15
17
 
16
18
  //#region src/handlers/executionHandler.ts
17
- const logger = getLogger("ExecutionHandler");
19
+ const logger = getLogger$1("ExecutionHandler");
18
20
  var ExecutionHandler = class {
19
21
  MAX_ERRORS = AGENT_EXECUTION_MAX_CONSECUTIVE_ERRORS;
20
22
  /**
@@ -33,9 +35,9 @@ var ExecutionHandler = class {
33
35
  */
34
36
  async execute(params) {
35
37
  const { executionContext, conversationId, userMessage, initialAgentId, requestId, sseHelper, emitOperations, forwardedHeaders } = params;
36
- const { tenantId, projectId, agentId, apiKey, baseUrl } = executionContext;
38
+ const { tenantId, projectId, project, agentId, apiKey, baseUrl, resolvedRef } = executionContext;
37
39
  registerStreamHelper(requestId, sseHelper);
38
- agentSessionManager.createSession(requestId, agentId, tenantId, projectId, conversationId);
40
+ agentSessionManager.createSession(requestId, executionContext, conversationId);
39
41
  if (emitOperations) agentSessionManager.enableEmitOperations(requestId);
40
42
  logger.info({
41
43
  sessionId: requestId,
@@ -43,21 +45,12 @@ var ExecutionHandler = class {
43
45
  conversationId,
44
46
  emitOperations
45
47
  }, "Created AgentSession for message execution");
46
- let agentConfig = null;
48
+ const agentConfig = null;
47
49
  try {
48
- agentConfig = await getFullAgent(dbClient_default)({ scopes: {
49
- tenantId,
50
- projectId,
51
- agentId
52
- } });
53
- if (agentConfig?.statusUpdates && agentConfig.statusUpdates.enabled !== false) try {
54
- const agentWithDefault = await getAgentWithDefaultSubAgent(dbClient_default)({ scopes: {
55
- tenantId,
56
- projectId,
57
- agentId
58
- } });
59
- if (agentWithDefault?.defaultSubAgent) {
60
- const resolvedModels = await resolveModelConfig(agentId, agentWithDefault.defaultSubAgent);
50
+ const agent = project.agents[agentId];
51
+ if (agent?.statusUpdates && agent.statusUpdates.enabled !== false) try {
52
+ if (agent?.defaultSubAgentId) {
53
+ const resolvedModels = await resolveModelConfig(executionContext, agent.subAgents[agent.defaultSubAgentId]);
61
54
  agentSessionManager.initializeStatusUpdates(requestId, agentConfig.statusUpdates, resolvedModels.summarizer, resolvedModels.base);
62
55
  } else agentSessionManager.initializeStatusUpdates(requestId, agentConfig.statusUpdates, agentConfig.models?.summarizer);
63
56
  } catch (modelError) {
@@ -96,6 +89,7 @@ var ExecutionHandler = class {
96
89
  subAgentId: currentAgentId,
97
90
  contextId: conversationId,
98
91
  status: "pending",
92
+ ref: resolvedRef,
99
93
  metadata: {
100
94
  conversation_id: conversationId,
101
95
  message_id: requestId,
@@ -205,7 +199,10 @@ var ExecutionHandler = class {
205
199
  logger.error({
206
200
  currentAgentId,
207
201
  iterations,
208
- errorCount
202
+ errorCount,
203
+ hasError: !!messageResponse?.error,
204
+ errorDetails: messageResponse?.error,
205
+ fullResponse: messageResponse
209
206
  }, `No response from agent ${currentAgentId} on iteration ${iterations} (error ${errorCount}/${this.MAX_ERRORS})`);
210
207
  if (errorCount >= this.MAX_ERRORS) {
211
208
  const errorMessage$1 = `Maximum error limit (${this.MAX_ERRORS}) reached`;
@@ -272,7 +269,9 @@ var ExecutionHandler = class {
272
269
  projectId,
273
270
  tenantId,
274
271
  threadId: conversationId,
275
- targetSubAgentId
272
+ agentId,
273
+ targetSubAgentId,
274
+ ref: resolvedRef
276
275
  });
277
276
  if (success) {
278
277
  fromSubAgentId = currentAgentId;
@@ -306,7 +305,7 @@ var ExecutionHandler = class {
306
305
  span.setAttributes({
307
306
  "ai.response.content": textContent || "No response content",
308
307
  "ai.response.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
309
- "subAgent.name": agentConfig?.subAgents[currentAgentId]?.name,
308
+ "subAgent.name": project.agents[agentId]?.subAgents[currentAgentId]?.name,
310
309
  "subAgent.id": currentAgentId
311
310
  });
312
311
  await createMessage(dbClient_default)({
@@ -356,6 +355,18 @@ var ExecutionHandler = class {
356
355
  let response;
357
356
  if (sseHelper instanceof BufferingStreamHelper) response = sseHelper.getCapturedResponse().text || "No response content";
358
357
  logger.info({}, "ExecutionHandler returning success");
358
+ if (!params.datasetRunId) triggerConversationEvaluationHttp({
359
+ tenantId,
360
+ projectId,
361
+ conversationId
362
+ }).catch((error) => {
363
+ logger.error({
364
+ error,
365
+ conversationId,
366
+ tenantId,
367
+ projectId
368
+ }, "Failed to trigger conversation evaluation (non-blocking)");
369
+ });
359
370
  return {
360
371
  success: true,
361
372
  iterations,
@@ -396,6 +407,19 @@ var ExecutionHandler = class {
396
407
  });
397
408
  await agentSessionManager.endSession(requestId);
398
409
  unregisterStreamHelper(requestId);
410
+ if (!params.datasetRunId) triggerConversationEvaluationHttp({
411
+ tenantId,
412
+ projectId,
413
+ conversationId,
414
+ userId: getUserIdFromContext(executionContext)
415
+ }).catch((error) => {
416
+ logger.error({
417
+ error,
418
+ conversationId,
419
+ tenantId,
420
+ projectId
421
+ }, "Failed to trigger conversation evaluation (non-blocking)");
422
+ });
399
423
  return {
400
424
  success: false,
401
425
  error: errorMessage$1,
package/dist/index.d.ts CHANGED
@@ -3,14 +3,14 @@ import { createExecutionHono } from "./create-app.js";
3
3
  import "./env.js";
4
4
  import { CredentialStore, ServerConfig } from "@inkeep/agents-core";
5
5
  import { Hono } from "hono";
6
- import * as hono_types0 from "hono/types";
6
+ import * as hono_types1 from "hono/types";
7
7
 
8
8
  //#region src/index.d.ts
9
- declare const app: Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
9
+ declare const app: Hono<hono_types1.BlankEnv, hono_types1.BlankSchema, "/">;
10
10
  declare function createExecutionApp(config?: {
11
11
  serverConfig?: ServerConfig;
12
12
  credentialStores?: CredentialStore[];
13
13
  sandboxConfig?: SandboxConfig;
14
- }): Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
14
+ }): Hono<hono_types1.BlankEnv, hono_types1.BlankSchema, "/">;
15
15
  //#endregion
16
16
  export { Hono, type NativeSandboxConfig, type SandboxConfig, type VercelSandboxConfig, createExecutionApp, createExecutionHono, app as default };
@@ -1,26 +1,20 @@
1
- import { ExecutionContext } from "@inkeep/agents-core";
1
+ import { BaseExecutionContext } from "@inkeep/agents-core";
2
2
  import * as hono0 from "hono";
3
3
 
4
4
  //#region src/middleware/api-key-auth.d.ts
5
5
  declare const apiKeyAuth: () => hono0.MiddlewareHandler<{
6
6
  Variables: {
7
- executionContext: ExecutionContext;
7
+ executionContext: BaseExecutionContext;
8
8
  };
9
9
  }, string, {}, Response>;
10
- declare const extractContextFromApiKey: (apiKey: string, baseUrl?: string) => Promise<ExecutionContext>;
11
- /**
12
- * Extract execution context from a team agent JWT token
13
- * Team agent tokens are used for intra-tenant agent delegation
14
- */
15
- declare const extractContextFromTeamAgentToken: (token: string, baseUrl?: string, expectedSubAgentId?: string) => Promise<ExecutionContext>;
16
10
  /**
17
11
  * Helper middleware for endpoints that optionally support API key authentication
18
12
  * If no auth header is present, it continues without setting the executionContext
19
13
  */
20
14
  declare const optionalAuth: () => hono0.MiddlewareHandler<{
21
15
  Variables: {
22
- executionContext?: ExecutionContext;
16
+ executionContext?: BaseExecutionContext;
23
17
  };
24
18
  }, string, {}, Response>;
25
19
  //#endregion
26
- export { apiKeyAuth, extractContextFromApiKey, extractContextFromTeamAgentToken, optionalAuth };
20
+ export { apiKeyAuth, optionalAuth };
@@ -1,198 +1,105 @@
1
1
  import { env } from "../env.js";
2
- import { getLogger } from "../logger.js";
2
+ import { getLogger as getLogger$1 } from "../logger.js";
3
3
  import dbClient_default from "../data/db/dbClient.js";
4
- import { createExecutionContext } from "../types/execution-context.js";
5
- import { getAgentById, validateAndGetApiKey, validateTargetAgent, verifyServiceToken, verifyTempToken } from "@inkeep/agents-core";
4
+ import { createBaseExecutionContext } from "../types/execution-context.js";
5
+ import { validateAndGetApiKey, validateTargetAgent, verifyServiceToken, verifyTempToken } from "@inkeep/agents-core";
6
6
  import { HTTPException } from "hono/http-exception";
7
7
  import { createMiddleware } from "hono/factory";
8
8
 
9
9
  //#region src/middleware/api-key-auth.ts
10
- const logger = getLogger("env-key-auth");
10
+ const logger = getLogger$1("env-key-auth");
11
+ /**
12
+ * Extract common request data from the Hono context
13
+ */
14
+ function extractRequestData(c) {
15
+ const authHeader = c.req.header("Authorization");
16
+ const tenantId = c.req.header("x-inkeep-tenant-id");
17
+ const projectId = c.req.header("x-inkeep-project-id");
18
+ const agentId = c.req.header("x-inkeep-agent-id");
19
+ const subAgentId = c.req.header("x-inkeep-sub-agent-id");
20
+ const proto = c.req.header("x-forwarded-proto")?.split(",")[0].trim();
21
+ const host = c.req.header("x-forwarded-host")?.split(",")[0].trim() ?? c.req.header("host");
22
+ const reqUrl = new URL(c.req.url);
23
+ const ref = c.req.query("ref");
24
+ const baseUrl = proto && host ? `${proto}://${host}` : host ? `${reqUrl.protocol}//${host}` : `${reqUrl.origin}`;
25
+ return {
26
+ authHeader,
27
+ apiKey: authHeader?.startsWith("Bearer ") ? authHeader.substring(7) : void 0,
28
+ tenantId,
29
+ projectId,
30
+ agentId,
31
+ subAgentId,
32
+ ref,
33
+ baseUrl
34
+ };
35
+ }
36
+ /**
37
+ * Build the final execution context from auth result and request data
38
+ */
39
+ function buildExecutionContext(authResult, reqData) {
40
+ return createBaseExecutionContext({
41
+ apiKey: authResult.apiKey,
42
+ tenantId: authResult.tenantId,
43
+ projectId: authResult.projectId,
44
+ agentId: authResult.agentId,
45
+ apiKeyId: authResult.apiKeyId,
46
+ baseUrl: reqData.baseUrl,
47
+ subAgentId: reqData.subAgentId,
48
+ ref: reqData.ref,
49
+ metadata: authResult.metadata
50
+ });
51
+ }
11
52
  /**
12
53
  * Attempts to authenticate using a JWT temporary token
13
- * Returns execution context if successful, null if token is invalid or not a JWT
14
54
  */
15
- async function tryAuthenticateWithTempJwt(apiKey, baseUrl, subAgentId) {
55
+ async function tryTempJwtAuth(apiKey) {
16
56
  if (!apiKey.startsWith("eyJ") || !env.INKEEP_AGENTS_TEMP_JWT_PUBLIC_KEY) return null;
17
57
  try {
18
58
  const payload = await verifyTempToken(Buffer.from(env.INKEEP_AGENTS_TEMP_JWT_PUBLIC_KEY, "base64").toString("utf-8"), apiKey);
19
59
  logger.info({}, "JWT temp token authenticated successfully");
20
- return createExecutionContext({
60
+ return {
21
61
  apiKey,
22
62
  tenantId: payload.tenantId,
23
63
  projectId: payload.projectId,
24
64
  agentId: payload.agentId,
25
65
  apiKeyId: "temp-jwt",
26
- baseUrl,
27
- subAgentId,
28
66
  metadata: { initiatedBy: payload.initiatedBy }
29
- });
67
+ };
30
68
  } catch (error) {
31
69
  logger.debug({ error }, "JWT verification failed");
32
70
  return null;
33
71
  }
34
72
  }
35
- const apiKeyAuth = () => createMiddleware(async (c, next) => {
36
- if (c.req.method === "OPTIONS") {
37
- await next();
38
- return;
39
- }
40
- const authHeader = c.req.header("Authorization");
41
- const tenantId = c.req.header("x-inkeep-tenant-id");
42
- const projectId = c.req.header("x-inkeep-project-id");
43
- const agentId = c.req.header("x-inkeep-agent-id");
44
- const subAgentId = c.req.header("x-inkeep-sub-agent-id");
45
- const proto = c.req.header("x-forwarded-proto")?.split(",")[0].trim();
46
- const host = c.req.header("x-forwarded-host")?.split(",")[0].trim() ?? c.req.header("host");
47
- const reqUrl = new URL(c.req.url);
48
- const baseUrl = proto && host ? `${proto}://${host}` : host ? `${reqUrl.protocol}//${host}` : `${reqUrl.origin}`;
49
- if (process.env.ENVIRONMENT === "development" || process.env.ENVIRONMENT === "test") {
50
- logger.info({}, "development environment");
51
- let executionContext;
52
- if (authHeader?.startsWith("Bearer ")) {
53
- const apiKey$1 = authHeader.substring(7);
54
- const jwtContext$1 = await tryAuthenticateWithTempJwt(apiKey$1, baseUrl, subAgentId);
55
- if (jwtContext$1) {
56
- c.set("executionContext", jwtContext$1);
57
- await next();
58
- return;
59
- }
60
- try {
61
- executionContext = await extractContextFromApiKey(apiKey$1, baseUrl);
62
- if (subAgentId) executionContext.subAgentId = subAgentId;
63
- c.set("executionContext", executionContext);
64
- } catch {
65
- try {
66
- executionContext = await extractContextFromTeamAgentToken(apiKey$1, baseUrl, subAgentId);
67
- c.set("executionContext", executionContext);
68
- } catch {
69
- executionContext = createExecutionContext({
70
- apiKey: "development",
71
- tenantId: tenantId || "test-tenant",
72
- projectId: projectId || "test-project",
73
- agentId: agentId || "test-agent",
74
- apiKeyId: "test-key",
75
- baseUrl,
76
- subAgentId
77
- });
78
- c.set("executionContext", executionContext);
79
- logger.info({}, "Development/test environment - fallback to default context due to invalid API key");
80
- }
81
- }
82
- } else {
83
- executionContext = createExecutionContext({
84
- apiKey: "development",
85
- tenantId: tenantId || "test-tenant",
86
- projectId: projectId || "test-project",
87
- agentId: agentId || "test-agent",
88
- apiKeyId: "test-key",
89
- baseUrl,
90
- subAgentId
91
- });
92
- c.set("executionContext", executionContext);
93
- logger.info({}, "Development/test environment - no API key provided, using default context");
94
- }
95
- await next();
96
- return;
97
- }
98
- if (!authHeader || !authHeader.startsWith("Bearer ")) throw new HTTPException(401, { message: "Missing or invalid authorization header. Expected: Bearer <api_key>" });
99
- const apiKey = authHeader.substring(7);
100
- const jwtContext = await tryAuthenticateWithTempJwt(apiKey, baseUrl, subAgentId);
101
- if (jwtContext) {
102
- c.set("executionContext", jwtContext);
103
- await next();
104
- return;
105
- }
106
- if (env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET) {
107
- if (apiKey === env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET) {
108
- if (!tenantId || !projectId || !agentId) throw new HTTPException(401, { message: "Missing or invalid tenant, project, or agent ID" });
109
- const executionContext = createExecutionContext({
110
- apiKey,
111
- tenantId,
112
- projectId,
113
- agentId,
114
- apiKeyId: "bypass",
115
- baseUrl,
116
- subAgentId
117
- });
118
- c.set("executionContext", executionContext);
119
- logger.info({}, "Bypass secret authenticated successfully");
120
- await next();
121
- return;
122
- }
123
- if (apiKey) {
124
- try {
125
- const executionContext = await extractContextFromApiKey(apiKey, baseUrl);
126
- if (subAgentId) executionContext.subAgentId = subAgentId;
127
- c.set("executionContext", executionContext);
128
- logger.info({}, "API key authenticated successfully");
129
- } catch {
130
- const executionContext = await extractContextFromTeamAgentToken(apiKey, baseUrl, subAgentId);
131
- c.set("executionContext", executionContext);
132
- }
133
- await next();
134
- return;
135
- }
136
- throw new HTTPException(401, { message: "Invalid Token" });
137
- }
138
- if (!apiKey || apiKey.length < 16) throw new HTTPException(401, { message: "Invalid API key format" });
139
- try {
140
- const executionContext = await extractContextFromApiKey(apiKey, baseUrl);
141
- if (subAgentId) executionContext.subAgentId = subAgentId;
142
- c.set("executionContext", executionContext);
143
- logger.debug({
144
- tenantId: executionContext.tenantId,
145
- projectId: executionContext.projectId,
146
- agentId: executionContext.agentId,
147
- subAgentId: executionContext.subAgentId
148
- }, "API key authenticated successfully");
149
- await next();
150
- } catch {
151
- try {
152
- const executionContext = await extractContextFromTeamAgentToken(apiKey, baseUrl, subAgentId);
153
- c.set("executionContext", executionContext);
154
- await next();
155
- } catch (error) {
156
- if (error instanceof HTTPException) throw error;
157
- logger.error({ error }, "API key authentication error");
158
- throw new HTTPException(500, { message: "Authentication failed" });
159
- }
160
- }
161
- });
162
- const extractContextFromApiKey = async (apiKey, baseUrl) => {
73
+ /**
74
+ * Authenticate using a regular API key
75
+ */
76
+ async function tryApiKeyAuth(apiKey) {
163
77
  const apiKeyRecord = await validateAndGetApiKey(apiKey, dbClient_default);
164
- if (!apiKeyRecord) throw new HTTPException(401, { message: "Invalid or expired API key" });
165
- const agent = await getAgentById(dbClient_default)({ scopes: {
166
- tenantId: apiKeyRecord.tenantId,
167
- projectId: apiKeyRecord.projectId,
168
- agentId: apiKeyRecord.agentId
169
- } });
170
- if (!agent) throw new HTTPException(401, { message: "Invalid or expired API key" });
78
+ if (!apiKeyRecord) return null;
171
79
  logger.debug({
172
80
  tenantId: apiKeyRecord.tenantId,
173
81
  projectId: apiKeyRecord.projectId,
174
- agentId: apiKeyRecord.agentId,
175
- subAgentId: agent.defaultSubAgentId || void 0
82
+ agentId: apiKeyRecord.agentId
176
83
  }, "API key authenticated successfully");
177
- return createExecutionContext({
84
+ return {
178
85
  apiKey,
179
86
  tenantId: apiKeyRecord.tenantId,
180
87
  projectId: apiKeyRecord.projectId,
181
88
  agentId: apiKeyRecord.agentId,
182
- apiKeyId: apiKeyRecord.id,
183
- baseUrl,
184
- subAgentId: agent.defaultSubAgentId || void 0
185
- });
186
- };
89
+ apiKeyId: apiKeyRecord.id
90
+ };
91
+ }
187
92
  /**
188
- * Extract execution context from a team agent JWT token
189
- * Team agent tokens are used for intra-tenant agent delegation
93
+ * Authenticate using a team agent JWT token (for intra-tenant delegation)
190
94
  */
191
- const extractContextFromTeamAgentToken = async (token, baseUrl, expectedSubAgentId) => {
95
+ async function tryTeamAgentAuth(token, expectedSubAgentId) {
192
96
  const result = await verifyServiceToken(token);
193
97
  if (!result.valid || !result.payload) {
194
98
  logger.warn({ error: result.error }, "Invalid team agent JWT token");
195
- throw new HTTPException(401, { message: `Invalid team agent token: ${result.error || "Unknown error"}` });
99
+ return {
100
+ authResult: null,
101
+ failureMessage: `Invalid team agent token: ${result.error || "Invalid token"}`
102
+ };
196
103
  }
197
104
  const payload = result.payload;
198
105
  if (expectedSubAgentId && !validateTargetAgent(payload, expectedSubAgentId)) {
@@ -209,20 +116,114 @@ const extractContextFromTeamAgentToken = async (token, baseUrl, expectedSubAgent
209
116
  tenantId: payload.tenantId,
210
117
  projectId: payload.projectId
211
118
  }, "Team agent JWT token authenticated successfully");
212
- return createExecutionContext({
119
+ return { authResult: {
213
120
  apiKey: "team-agent-jwt",
214
121
  tenantId: payload.tenantId,
215
122
  projectId: payload.projectId,
216
123
  agentId: payload.aud,
217
124
  apiKeyId: "team-agent-token",
218
- baseUrl,
219
- subAgentId: void 0,
220
125
  metadata: {
221
126
  teamDelegation: true,
222
127
  originAgentId: payload.sub
223
128
  }
224
- });
225
- };
129
+ } };
130
+ }
131
+ /**
132
+ * Authenticate using bypass secret (production mode bypass)
133
+ */
134
+ function tryBypassAuth(apiKey, reqData) {
135
+ if (!env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET) return null;
136
+ if (apiKey !== env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET) return null;
137
+ if (!reqData.tenantId || !reqData.projectId || !reqData.agentId) throw new HTTPException(401, { message: "Missing or invalid tenant, project, or agent ID" });
138
+ logger.info({}, "Bypass secret authenticated successfully");
139
+ return {
140
+ apiKey,
141
+ tenantId: reqData.tenantId,
142
+ projectId: reqData.projectId,
143
+ agentId: reqData.agentId,
144
+ apiKeyId: "bypass"
145
+ };
146
+ }
147
+ /**
148
+ * Create default development context
149
+ */
150
+ function createDevContext(reqData) {
151
+ const result = {
152
+ apiKey: "development",
153
+ tenantId: reqData.tenantId || "test-tenant",
154
+ projectId: reqData.projectId || "test-project",
155
+ agentId: reqData.agentId || "test-agent",
156
+ apiKeyId: "test-key"
157
+ };
158
+ if (!reqData.tenantId || !reqData.projectId) logger.warn({
159
+ hasTenantId: !!reqData.tenantId,
160
+ hasProjectId: !!reqData.projectId,
161
+ hasApiKey: !!reqData.apiKey,
162
+ apiKeyPrefix: reqData.apiKey?.substring(0, 10),
163
+ resultTenantId: result.tenantId,
164
+ resultProjectId: result.projectId
165
+ }, "createDevContext: Using fallback test values due to missing tenant/project in request");
166
+ return result;
167
+ }
168
+ /**
169
+ * Try all auth strategies in order, returning the first successful result
170
+ */
171
+ async function authenticateRequest(reqData) {
172
+ const { apiKey, subAgentId } = reqData;
173
+ if (!apiKey) return { authResult: null };
174
+ const jwtResult = await tryTempJwtAuth(apiKey);
175
+ if (jwtResult) return { authResult: jwtResult };
176
+ const bypassResult = tryBypassAuth(apiKey, reqData);
177
+ if (bypassResult) return { authResult: bypassResult };
178
+ const apiKeyResult = await tryApiKeyAuth(apiKey);
179
+ if (apiKeyResult) return { authResult: apiKeyResult };
180
+ const teamAttempt = await tryTeamAgentAuth(apiKey, subAgentId);
181
+ if (teamAttempt.authResult) return { authResult: teamAttempt.authResult };
182
+ return {
183
+ authResult: null,
184
+ failureMessage: teamAttempt.failureMessage
185
+ };
186
+ }
187
+ const apiKeyAuth = () => createMiddleware(async (c, next) => {
188
+ if (c.req.method === "OPTIONS") {
189
+ await next();
190
+ return;
191
+ }
192
+ const reqData = extractRequestData(c);
193
+ if (process.env.ENVIRONMENT === "development" || process.env.ENVIRONMENT === "test") {
194
+ logger.info({}, "development environment");
195
+ const attempt$1 = await authenticateRequest(reqData);
196
+ if (attempt$1.authResult) c.set("executionContext", buildExecutionContext(attempt$1.authResult, reqData));
197
+ else {
198
+ logger.info({}, reqData.apiKey ? "Development/test environment - fallback to default context due to invalid API key" : "Development/test environment - no API key provided, using default context");
199
+ c.set("executionContext", buildExecutionContext(createDevContext(reqData), reqData));
200
+ }
201
+ await next();
202
+ return;
203
+ }
204
+ if (!reqData.authHeader || !reqData.authHeader.startsWith("Bearer ")) throw new HTTPException(401, { message: "Missing or invalid authorization header. Expected: Bearer <api_key>" });
205
+ if (!reqData.apiKey || reqData.apiKey.length < 16) throw new HTTPException(401, { message: "Invalid API key format" });
206
+ let attempt = { authResult: null };
207
+ try {
208
+ attempt = await authenticateRequest(reqData);
209
+ } catch (error) {
210
+ if (error instanceof HTTPException) throw error;
211
+ logger.error({ error }, "Authentication failed");
212
+ throw new HTTPException(500, { message: "Authentication failed" });
213
+ }
214
+ if (!attempt.authResult) {
215
+ logger.error({}, "API key authentication error - no valid auth method found");
216
+ throw new HTTPException(401, { message: attempt.failureMessage || "Invalid Token" });
217
+ }
218
+ logger.debug({
219
+ tenantId: attempt.authResult.tenantId,
220
+ projectId: attempt.authResult.projectId,
221
+ agentId: attempt.authResult.agentId,
222
+ subAgentId: reqData.subAgentId
223
+ }, "API key authenticated successfully");
224
+ c.set("executionContext", buildExecutionContext(attempt.authResult, reqData));
225
+ await next();
226
+ });
226
227
  /**
227
228
  * Helper middleware for endpoints that optionally support API key authentication
228
229
  * If no auth header is present, it continues without setting the executionContext
@@ -237,4 +238,4 @@ const optionalAuth = () => createMiddleware(async (c, next) => {
237
238
  });
238
239
 
239
240
  //#endregion
240
- export { apiKeyAuth, extractContextFromApiKey, extractContextFromTeamAgentToken, optionalAuth };
241
+ export { apiKeyAuth, optionalAuth };
@@ -1,2 +1,3 @@
1
- import { apiKeyAuth, extractContextFromApiKey, extractContextFromTeamAgentToken, optionalAuth } from "./api-key-auth.js";
2
- export { apiKeyAuth, extractContextFromApiKey, extractContextFromTeamAgentToken, optionalAuth };
1
+ import { apiKeyAuth, optionalAuth } from "./api-key-auth.js";
2
+ import { projectConfigMiddleware } from "./projectConfig.js";
3
+ export { apiKeyAuth, optionalAuth, projectConfigMiddleware };
@@ -1,3 +1,4 @@
1
- import { apiKeyAuth, extractContextFromApiKey, extractContextFromTeamAgentToken, optionalAuth } from "./api-key-auth.js";
1
+ import { apiKeyAuth, optionalAuth } from "./api-key-auth.js";
2
+ import { projectConfigMiddleware } from "./projectConfig.js";
2
3
 
3
- export { apiKeyAuth, extractContextFromApiKey, extractContextFromTeamAgentToken, optionalAuth };
4
+ export { apiKeyAuth, optionalAuth, projectConfigMiddleware };
@@ -0,0 +1,19 @@
1
+ import { FullExecutionContext } from "@inkeep/agents-core";
2
+ import * as hono0 from "hono";
3
+
4
+ //#region src/middleware/projectConfig.d.ts
5
+
6
+ /**
7
+ * Middleware that fetches the full project definition from the Management API
8
+ * and adds it to the Hono context for use in route handlers.
9
+ *
10
+ * This middleware should be applied after authentication middleware since it
11
+ * requires the execution context to be set.
12
+ */
13
+ declare const projectConfigMiddleware: hono0.MiddlewareHandler<{
14
+ Variables: {
15
+ executionContext: FullExecutionContext;
16
+ };
17
+ }, string, {}, Response>;
18
+ //#endregion
19
+ export { projectConfigMiddleware };