@inkeep/agents-api 0.0.0-dev-20260123094230 → 0.0.0-dev-20260123205017

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 (34) hide show
  1. package/dist/.well-known/workflow/v1/flow.cjs +44 -44
  2. package/dist/.well-known/workflow/v1/flow.cjs.debug.json +2 -2
  3. package/dist/.well-known/workflow/v1/manifest.debug.json +19 -19
  4. package/dist/.well-known/workflow/v1/step.cjs +43414 -43267
  5. package/dist/.well-known/workflow/v1/step.cjs.debug.json +2 -2
  6. package/dist/data/db/runDbClient.d.ts +2 -2
  7. package/dist/domains/evals/routes/datasetTriggers.d.ts +2 -2
  8. package/dist/domains/evals/routes/index.d.ts +2 -2
  9. package/dist/domains/evals/workflow/routes.d.ts +2 -2
  10. package/dist/domains/manage/routes/conversations.d.ts +2 -2
  11. package/dist/domains/manage/routes/evals/evaluationResults.d.ts +2 -2
  12. package/dist/domains/manage/routes/index.d.ts +2 -2
  13. package/dist/domains/manage/routes/mcp.d.ts +2 -2
  14. package/dist/domains/manage/routes/triggers.js +49 -24
  15. package/dist/domains/run/agents/Agent.js +93 -2
  16. package/dist/domains/run/agents/relationTools.d.ts +2 -2
  17. package/dist/domains/run/routes/webhooks.js +4 -0
  18. package/dist/domains/run/services/TriggerService.d.ts +1 -1
  19. package/dist/domains/run/services/TriggerService.js +111 -11
  20. package/dist/domains/run/tools/NativeSandboxExecutor.js +0 -2
  21. package/dist/domains/run/utils/token-estimator.d.ts +2 -2
  22. package/dist/env.d.ts +2 -2
  23. package/dist/factory.d.ts +20 -20
  24. package/dist/index.d.ts +18 -18
  25. package/dist/middleware/evalsAuth.d.ts +2 -2
  26. package/dist/middleware/manageAuth.d.ts +2 -2
  27. package/dist/middleware/projectAccess.d.ts +2 -2
  28. package/dist/middleware/projectConfig.d.ts +3 -3
  29. package/dist/middleware/requirePermission.d.ts +2 -2
  30. package/dist/middleware/runAuth.d.ts +4 -4
  31. package/dist/middleware/sessionAuth.d.ts +3 -3
  32. package/dist/middleware/tenantAccess.d.ts +2 -2
  33. package/dist/middleware/tracing.d.ts +3 -3
  34. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "stepFiles": [
3
- "/home/runner/work/agents/agents/agents-api/src/domains/evals/workflow/functions/runDatasetItem.ts",
4
- "/home/runner/work/agents/agents/agents-api/src/domains/evals/workflow/functions/evaluateConversation.ts"
3
+ "/home/runner/work/agents/agents/agents-api/src/domains/evals/workflow/functions/evaluateConversation.ts",
4
+ "/home/runner/work/agents/agents/agents-api/src/domains/evals/workflow/functions/runDatasetItem.ts"
5
5
  ]
6
6
  }
@@ -1,6 +1,6 @@
1
- import * as _inkeep_agents_core3 from "@inkeep/agents-core";
1
+ import * as _inkeep_agents_core0 from "@inkeep/agents-core";
2
2
 
3
3
  //#region src/data/db/runDbClient.d.ts
4
- declare const runDbClient: _inkeep_agents_core3.AgentsRunDatabaseClient;
4
+ declare const runDbClient: _inkeep_agents_core0.AgentsRunDatabaseClient;
5
5
  //#endregion
6
6
  export { runDbClient as default };
@@ -1,7 +1,7 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
- import * as hono12 from "hono";
2
+ import * as hono14 from "hono";
3
3
 
4
4
  //#region src/domains/evals/routes/datasetTriggers.d.ts
5
- declare const app: OpenAPIHono<hono12.Env, {}, "/">;
5
+ declare const app: OpenAPIHono<hono14.Env, {}, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
- import * as hono13 from "hono";
2
+ import * as hono15 from "hono";
3
3
 
4
4
  //#region src/domains/evals/routes/index.d.ts
5
- declare const app: OpenAPIHono<hono13.Env, {}, "/">;
5
+ declare const app: OpenAPIHono<hono15.Env, {}, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types7 from "hono/types";
2
+ import * as hono_types5 from "hono/types";
3
3
 
4
4
  //#region src/domains/evals/workflow/routes.d.ts
5
- declare const workflowRoutes: Hono<hono_types7.BlankEnv, hono_types7.BlankSchema, "/">;
5
+ declare const workflowRoutes: Hono<hono_types5.BlankEnv, hono_types5.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { workflowRoutes };
@@ -1,7 +1,7 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
- import * as hono0 from "hono";
2
+ import * as hono16 from "hono";
3
3
 
4
4
  //#region src/domains/manage/routes/conversations.d.ts
5
- declare const app: OpenAPIHono<hono0.Env, {}, "/">;
5
+ declare const app: OpenAPIHono<hono16.Env, {}, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
- import * as hono14 from "hono";
2
+ import * as hono17 from "hono";
3
3
 
4
4
  //#region src/domains/manage/routes/evals/evaluationResults.d.ts
5
- declare const app: OpenAPIHono<hono14.Env, {}, "/">;
5
+ declare const app: OpenAPIHono<hono17.Env, {}, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
- import * as hono9 from "hono";
2
+ import * as hono18 from "hono";
3
3
 
4
4
  //#region src/domains/manage/routes/index.d.ts
5
- declare const app: OpenAPIHono<hono9.Env, {}, "/">;
5
+ declare const app: OpenAPIHono<hono18.Env, {}, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types5 from "hono/types";
2
+ import * as hono_types7 from "hono/types";
3
3
 
4
4
  //#region src/domains/manage/routes/mcp.d.ts
5
- declare const app: Hono<hono_types5.BlankEnv, hono_types5.BlankSchema, "/">;
5
+ declare const app: Hono<hono_types7.BlankEnv, hono_types7.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -4,21 +4,11 @@ import runDbClient_default from "../../../data/db/runDbClient.js";
4
4
  import { requireProjectPermission } from "../../../middleware/projectAccess.js";
5
5
  import { speakeasyOffsetLimitPagination } from "../../../utils/speakeasy.js";
6
6
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
7
- import { PaginationQueryParamsSchema, TenantProjectAgentIdParamsSchema, TenantProjectAgentParamsSchema, TriggerApiInsertSchema, TriggerApiSelectSchema, TriggerApiUpdateSchema, TriggerInvocationListResponse, TriggerInvocationResponse, TriggerInvocationStatusEnum, commonGetErrorResponses, createApiError, createTrigger, deleteTrigger, generateId, getTriggerById, getTriggerInvocationById, hashAuthenticationHeaders, listTriggerInvocationsPaginated, listTriggersPaginated, updateTrigger } from "@inkeep/agents-core";
7
+ import { PaginationQueryParamsSchema, TenantProjectAgentIdParamsSchema, TenantProjectAgentParamsSchema, TriggerApiInsertSchema, TriggerApiUpdateSchema, TriggerInvocationListResponse, TriggerInvocationResponse, TriggerInvocationStatusEnum, TriggerWithWebhookUrlListResponse, TriggerWithWebhookUrlResponse, commonGetErrorResponses, createApiError, createTrigger, deleteTrigger, generateId, getCredentialReference, getTriggerById, getTriggerInvocationById, hashAuthenticationHeaders, listTriggerInvocationsPaginated, listTriggersPaginated, updateTrigger } from "@inkeep/agents-core";
8
8
 
9
9
  //#region src/domains/manage/routes/triggers.ts
10
10
  const logger = getLogger$1("triggers");
11
11
  const app = new OpenAPIHono();
12
- const TriggerResponse = z.object({ data: TriggerApiSelectSchema.extend({ webhookUrl: z.string().describe("Fully qualified webhook URL for this trigger") }) });
13
- const TriggerListResponse = z.object({
14
- data: z.array(TriggerApiSelectSchema.extend({ webhookUrl: z.string().describe("Fully qualified webhook URL for this trigger") })),
15
- pagination: z.object({
16
- page: z.number(),
17
- limit: z.number(),
18
- total: z.number(),
19
- pages: z.number()
20
- })
21
- });
22
12
  app.use("/", async (c, next) => {
23
13
  if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
24
14
  return next();
@@ -51,7 +41,7 @@ app.openapi(createRoute({
51
41
  responses: {
52
42
  200: {
53
43
  description: "List of triggers retrieved successfully",
54
- content: { "application/json": { schema: TriggerListResponse } }
44
+ content: { "application/json": { schema: TriggerWithWebhookUrlListResponse } }
55
45
  },
56
46
  ...commonGetErrorResponses
57
47
  },
@@ -103,7 +93,7 @@ app.openapi(createRoute({
103
93
  responses: {
104
94
  200: {
105
95
  description: "Trigger found",
106
- content: { "application/json": { schema: TriggerResponse } }
96
+ content: { "application/json": { schema: TriggerWithWebhookUrlResponse } }
107
97
  },
108
98
  ...commonGetErrorResponses
109
99
  }
@@ -151,7 +141,7 @@ app.openapi(createRoute({
151
141
  responses: {
152
142
  201: {
153
143
  description: "Trigger created successfully",
154
- content: { "application/json": { schema: TriggerResponse } }
144
+ content: { "application/json": { schema: TriggerWithWebhookUrlResponse } }
155
145
  },
156
146
  ...commonGetErrorResponses
157
147
  }
@@ -161,12 +151,29 @@ app.openapi(createRoute({
161
151
  const body = c.req.valid("json");
162
152
  const apiBaseUrl = env.INKEEP_AGENTS_API_URL;
163
153
  const id = body.id || generateId();
164
- logger.info({
154
+ logger.debug({
165
155
  tenantId,
166
156
  projectId,
167
157
  agentId,
168
158
  triggerId: id
169
159
  }, "Creating trigger");
160
+ if (body.signingSecretCredentialReferenceId) {
161
+ const credentialRef = await getCredentialReference(db)({
162
+ scopes: {
163
+ tenantId,
164
+ projectId
165
+ },
166
+ id: body.signingSecretCredentialReferenceId
167
+ });
168
+ if (!credentialRef) throw createApiError({
169
+ code: "bad_request",
170
+ message: `Credential reference not found: ${body.signingSecretCredentialReferenceId}`
171
+ });
172
+ if (credentialRef.userId) throw createApiError({
173
+ code: "bad_request",
174
+ message: "Only project-scoped credentials can be attached to triggers. User-scoped credentials are not allowed."
175
+ });
176
+ }
170
177
  let hashedAuthentication;
171
178
  const authInput = body.authentication;
172
179
  if (authInput?.headers && authInput.headers.length > 0) hashedAuthentication = { headers: await hashAuthenticationHeaders(authInput.headers) };
@@ -182,7 +189,8 @@ app.openapi(createRoute({
182
189
  outputTransform: body.outputTransform,
183
190
  messageTemplate: body.messageTemplate,
184
191
  authentication: hashedAuthentication,
185
- signingSecret: body.signingSecret
192
+ signingSecretCredentialReferenceId: body.signingSecretCredentialReferenceId,
193
+ signatureVerification: body.signatureVerification
186
194
  });
187
195
  const { tenantId: _tid, projectId: _pid, agentId: _aid, ...triggerWithoutScopes } = trigger;
188
196
  return c.json({ data: {
@@ -212,7 +220,7 @@ app.openapi(createRoute({
212
220
  responses: {
213
221
  200: {
214
222
  description: "Trigger updated successfully",
215
- content: { "application/json": { schema: TriggerResponse } }
223
+ content: { "application/json": { schema: TriggerWithWebhookUrlResponse } }
216
224
  },
217
225
  ...commonGetErrorResponses
218
226
  }
@@ -221,16 +229,33 @@ app.openapi(createRoute({
221
229
  const { tenantId, projectId, agentId, id } = c.req.valid("param");
222
230
  const body = c.req.valid("json");
223
231
  const apiBaseUrl = env.INKEEP_AGENTS_API_URL;
224
- if (!(body.name !== void 0 || body.description !== void 0 || body.enabled !== void 0 || body.inputSchema !== void 0 || body.outputTransform !== void 0 || body.messageTemplate !== void 0 || body.authentication !== void 0 || body.signingSecret !== void 0 || body.keepExistingSigningSecret !== void 0)) throw createApiError({
232
+ if (!(body.name !== void 0 || body.description !== void 0 || body.enabled !== void 0 || body.inputSchema !== void 0 || body.outputTransform !== void 0 || body.messageTemplate !== void 0 || body.authentication !== void 0 || body.signingSecretCredentialReferenceId !== void 0 || body.signatureVerification !== void 0)) throw createApiError({
225
233
  code: "bad_request",
226
234
  message: "No fields to update"
227
235
  });
228
- logger.info({
236
+ logger.debug({
229
237
  tenantId,
230
238
  projectId,
231
239
  agentId,
232
240
  triggerId: id
233
241
  }, "Updating trigger");
242
+ if (body.signingSecretCredentialReferenceId) {
243
+ const credentialRef = await getCredentialReference(db)({
244
+ scopes: {
245
+ tenantId,
246
+ projectId
247
+ },
248
+ id: body.signingSecretCredentialReferenceId
249
+ });
250
+ if (!credentialRef) throw createApiError({
251
+ code: "bad_request",
252
+ message: `Credential reference not found: ${body.signingSecretCredentialReferenceId}`
253
+ });
254
+ if (credentialRef.userId) throw createApiError({
255
+ code: "bad_request",
256
+ message: "Only project-scoped credentials can be attached to triggers. User-scoped credentials are not allowed."
257
+ });
258
+ }
234
259
  let hashedAuthentication;
235
260
  const authInput = body.authentication;
236
261
  if (authInput?.headers && authInput.headers.length > 0) {
@@ -259,7 +284,6 @@ app.openapi(createRoute({
259
284
  }
260
285
  hashedAuthentication = hashedHeaders.length > 0 ? { headers: hashedHeaders } : void 0;
261
286
  } else if (body.authentication !== void 0) hashedAuthentication = body.authentication;
262
- const signingSecretUpdate = body.keepExistingSigningSecret ? void 0 : body.signingSecret;
263
287
  const updatedTrigger = await updateTrigger(db)({
264
288
  scopes: {
265
289
  tenantId,
@@ -275,7 +299,8 @@ app.openapi(createRoute({
275
299
  outputTransform: body.outputTransform,
276
300
  messageTemplate: body.messageTemplate,
277
301
  authentication: hashedAuthentication,
278
- signingSecret: signingSecretUpdate
302
+ signingSecretCredentialReferenceId: body.signingSecretCredentialReferenceId,
303
+ signatureVerification: body.signatureVerification
279
304
  }
280
305
  });
281
306
  if (!updatedTrigger) throw createApiError({
@@ -311,7 +336,7 @@ app.openapi(createRoute({
311
336
  }), async (c) => {
312
337
  const db = c.get("db");
313
338
  const { tenantId, projectId, agentId, id } = c.req.valid("param");
314
- logger.info({
339
+ logger.debug({
315
340
  tenantId,
316
341
  projectId,
317
342
  agentId,
@@ -372,7 +397,7 @@ app.openapi(createRoute({
372
397
  }), async (c) => {
373
398
  const { tenantId, projectId, agentId, id: triggerId } = c.req.valid("param");
374
399
  const { page, limit, status, from, to } = c.req.valid("query");
375
- logger.info({
400
+ logger.debug({
376
401
  tenantId,
377
402
  projectId,
378
403
  agentId,
@@ -426,7 +451,7 @@ app.openapi(createRoute({
426
451
  }
427
452
  }), async (c) => {
428
453
  const { tenantId, projectId, agentId, id: triggerId, invocationId } = c.req.valid("param");
429
- logger.info({
454
+ logger.debug({
430
455
  tenantId,
431
456
  projectId,
432
457
  agentId,
@@ -819,10 +819,12 @@ var Agent = class {
819
819
  continue;
820
820
  }
821
821
  const zodSchema = jsonSchemaToZod(functionData.inputSchema);
822
+ const toolPolicies = functionToolDef.toolPolicies;
823
+ const needsApproval = !!toolPolicies?.["*"]?.needsApproval || !!toolPolicies?.[functionToolDef.name]?.needsApproval;
822
824
  const aiTool = tool({
823
825
  description: functionToolDef.description || functionToolDef.name,
824
826
  inputSchema: zodSchema,
825
- execute: async (args, { toolCallId }) => {
827
+ execute: async (args, { toolCallId, providerMetadata }) => {
826
828
  let processedArgs;
827
829
  try {
828
830
  processedArgs = parseEmbeddedJson(args);
@@ -839,6 +841,95 @@ var Agent = class {
839
841
  processedArgs = args;
840
842
  }
841
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
+ }
842
933
  logger.debug({
843
934
  toolName: functionToolDef.name,
844
935
  toolCallId,
@@ -876,7 +967,7 @@ var Agent = class {
876
967
  }
877
968
  }
878
969
  });
879
- functionTools[functionToolDef.name] = this.wrapToolWithStreaming(functionToolDef.name, aiTool, streamRequestId || "", "tool");
970
+ functionTools[functionToolDef.name] = this.wrapToolWithStreaming(functionToolDef.name, aiTool, streamRequestId || "", "tool", { needsApproval });
880
971
  }
881
972
  } catch (error) {
882
973
  logger.error({ error }, "Failed to load function tools from database");
@@ -1,6 +1,6 @@
1
1
  import { AgentConfig, DelegateRelation } from "./Agent.js";
2
2
  import { InternalRelation } from "../utils/project.js";
3
- import * as _inkeep_agents_core0 from "@inkeep/agents-core";
3
+ import * as _inkeep_agents_core1 from "@inkeep/agents-core";
4
4
  import { CredentialStoreRegistry, FullExecutionContext } from "@inkeep/agents-core";
5
5
  import * as ai0 from "ai";
6
6
 
@@ -44,7 +44,7 @@ declare function createDelegateToAgentTool({
44
44
  message: string;
45
45
  }, {
46
46
  toolCallId: any;
47
- result: _inkeep_agents_core0.Message | _inkeep_agents_core0.Task;
47
+ result: _inkeep_agents_core1.Message | _inkeep_agents_core1.Task;
48
48
  }>;
49
49
  /**
50
50
  * Parameters for building a transfer relation config
@@ -55,6 +55,10 @@ const triggerWebhookRoute = createRoute({
55
55
  422: {
56
56
  description: "Payload transformation failed",
57
57
  content: { "application/json": { schema: z.object({ error: z.string() }) } }
58
+ },
59
+ 500: {
60
+ description: "Internal server error",
61
+ content: { "application/json": { schema: z.object({ error: z.string() }) } }
58
62
  }
59
63
  }
60
64
  });
@@ -19,7 +19,7 @@ type TriggerWebhookResult = {
19
19
  } | {
20
20
  success: false;
21
21
  error: string;
22
- status: 400 | 401 | 403 | 404 | 422;
22
+ status: 400 | 401 | 403 | 404 | 422 | 500;
23
23
  validationErrors?: string[];
24
24
  };
25
25
  /**
@@ -4,13 +4,15 @@ import manageDbPool_default from "../../../data/db/manageDbPool.js";
4
4
  import runDbClient_default from "../../../data/db/runDbClient.js";
5
5
  import { createSSEStreamHelper } from "../utils/stream-helpers.js";
6
6
  import { ExecutionHandler } from "../handlers/executionHandler.js";
7
- import { JsonTransformer, createMessage, createOrGetConversation, createTriggerInvocation, generateId, getConversationId, getFullProjectWithRelationIds, getTriggerById, interpolateTemplate, setActiveAgentForConversation, updateTriggerInvocationStatus, verifySigningSecret, verifyTriggerAuth, withRef } from "@inkeep/agents-core";
7
+ import { JsonTransformer, createKeyChainStore, createMessage, createOrGetConversation, createTriggerInvocation, generateId, getConversationId, getCredentialReference, getCredentialStoreLookupKeyFromRetrievalParams, getFullProjectWithRelationIds, getTriggerById, interpolateTemplate, setActiveAgentForConversation, updateTriggerInvocationStatus, verifySignatureWithConfig, verifyTriggerAuth, withRef } from "@inkeep/agents-core";
8
8
  import { ROOT_CONTEXT, SpanStatusCode, propagation, trace } from "@opentelemetry/api";
9
9
  import Ajv from "ajv";
10
10
 
11
11
  //#region src/domains/run/services/TriggerService.ts
12
12
  const logger = getLogger$1("TriggerService");
13
13
  const ajv = new Ajv({ allErrors: true });
14
+ const credentialCache = /* @__PURE__ */ new Map();
15
+ const CACHE_TTL_MS = 300 * 1e3;
14
16
  /**
15
17
  * Process a trigger webhook request.
16
18
  * Handles validation, transformation, and dispatches async execution.
@@ -37,7 +39,14 @@ async function processWebhook(params) {
37
39
  const payload = rawBody ? JSON.parse(rawBody) : {};
38
40
  const authResult = await verifyAuthentication(trigger, honoContext);
39
41
  if (!authResult.success) return authResult;
40
- const signatureResult = verifySignature(trigger, honoContext, rawBody);
42
+ const signatureResult = await verifySignature({
43
+ trigger,
44
+ tenantId,
45
+ projectId,
46
+ resolvedRef,
47
+ honoContext,
48
+ rawBody
49
+ });
41
50
  if (!signatureResult.success) return signatureResult;
42
51
  const validationResult = validatePayload(trigger, payload);
43
52
  if (!validationResult.success) return validationResult;
@@ -94,15 +103,106 @@ async function verifyAuthentication(trigger, honoContext) {
94
103
  }
95
104
  return { success: true };
96
105
  }
97
- function verifySignature(trigger, honoContext, rawBody) {
98
- if (!trigger.signingSecret) return { success: true };
99
- const signatureResult = verifySigningSecret(honoContext, trigger.signingSecret, rawBody);
100
- if (!signatureResult.success) return {
101
- success: false,
102
- error: signatureResult.message || "Invalid signature",
103
- status: 403
104
- };
105
- return { success: true };
106
+ /**
107
+ * Resolve signing secret from credential reference with caching
108
+ */
109
+ async function resolveSigningSecret(params) {
110
+ const { tenantId, projectId, credentialReferenceId, resolvedRef } = params;
111
+ const cacheKey = `${tenantId}:${projectId}:${credentialReferenceId}`;
112
+ const cached = credentialCache.get(cacheKey);
113
+ if (cached && cached.expiresAt > Date.now()) return cached.secret;
114
+ const credentialRef = await withRef(manageDbPool_default, resolvedRef, (db) => getCredentialReference(db)({
115
+ scopes: {
116
+ tenantId,
117
+ projectId
118
+ },
119
+ id: credentialReferenceId
120
+ }));
121
+ if (!credentialRef) {
122
+ logger.warn({
123
+ tenantId,
124
+ projectId,
125
+ credentialReferenceId
126
+ }, "Credential reference not found");
127
+ return null;
128
+ }
129
+ const lookupKey = getCredentialStoreLookupKeyFromRetrievalParams({
130
+ retrievalParams: credentialRef.retrievalParams ?? {},
131
+ credentialStoreType: credentialRef.type
132
+ });
133
+ if (!lookupKey) {
134
+ logger.warn({
135
+ tenantId,
136
+ projectId,
137
+ credentialReferenceId,
138
+ retrievalParams: credentialRef.retrievalParams
139
+ }, "Could not determine lookup key from credential reference");
140
+ return null;
141
+ }
142
+ let secret = null;
143
+ if (credentialRef.type === "keychain" || credentialRef.credentialStoreId?.startsWith("keychain")) secret = await createKeyChainStore(credentialRef.credentialStoreId ?? "keychain-default").get(lookupKey);
144
+ else {
145
+ logger.warn({
146
+ credentialStoreType: credentialRef.type,
147
+ credentialStoreId: credentialRef.credentialStoreId
148
+ }, "Unsupported credential store type for signing secret");
149
+ return null;
150
+ }
151
+ if (!secret) {
152
+ logger.warn({
153
+ tenantId,
154
+ projectId,
155
+ credentialReferenceId,
156
+ lookupKey
157
+ }, "No secret found in credential store");
158
+ return null;
159
+ }
160
+ if (secret.startsWith("{")) try {
161
+ const parsed = JSON.parse(secret);
162
+ const extractedSecret = parsed.access_token || parsed.secret || parsed.value || parsed.token || parsed.key;
163
+ if (extractedSecret && typeof extractedSecret === "string") secret = extractedSecret;
164
+ } catch {}
165
+ credentialCache.set(cacheKey, {
166
+ secret,
167
+ expiresAt: Date.now() + CACHE_TTL_MS
168
+ });
169
+ return secret;
170
+ }
171
+ async function verifySignature(params) {
172
+ const { trigger, tenantId, projectId, resolvedRef, honoContext, rawBody } = params;
173
+ if (!trigger.signatureVerification || !trigger.signingSecretCredentialReferenceId) return { success: true };
174
+ try {
175
+ const secret = await resolveSigningSecret({
176
+ tenantId,
177
+ projectId,
178
+ credentialReferenceId: trigger.signingSecretCredentialReferenceId,
179
+ resolvedRef
180
+ });
181
+ if (!secret) return {
182
+ success: false,
183
+ error: "Failed to resolve signing secret from credential reference",
184
+ status: 500
185
+ };
186
+ const result = verifySignatureWithConfig(honoContext, trigger.signatureVerification, secret, rawBody);
187
+ if (!result.success) return {
188
+ success: false,
189
+ error: result.message || "Invalid signature",
190
+ status: 403
191
+ };
192
+ return { success: true };
193
+ } catch (error) {
194
+ const errorMessage = error instanceof Error ? error.message : String(error);
195
+ logger.error({
196
+ error: errorMessage,
197
+ tenantId,
198
+ projectId
199
+ }, "Error during signature verification");
200
+ return {
201
+ success: false,
202
+ error: "Signature verification failed",
203
+ status: 500
204
+ };
205
+ }
106
206
  }
107
207
  function validatePayload(trigger, payload) {
108
208
  if (!trigger.inputSchema) return { success: true };
@@ -312,8 +312,6 @@ var NativeSandboxExecutor = class {
312
312
  mkdirSync(runDir, { recursive: true });
313
313
  writeFileSync(join(runDir, `index.${moduleType === "esm" ? "mjs" : "cjs"}`), executionCode, "utf8");
314
314
  return await this.executeInSandbox(runDir, config.sandboxConfig?.timeout || FUNCTION_TOOL_EXECUTION_TIMEOUT_MS_DEFAULT, moduleType, config.sandboxConfig);
315
- } catch (error) {
316
- throw error;
317
315
  } finally {
318
316
  if (runDir) try {
319
317
  rmSync(runDir, {
@@ -1,4 +1,4 @@
1
- import * as _inkeep_agents_core2 from "@inkeep/agents-core";
1
+ import * as _inkeep_agents_core3 from "@inkeep/agents-core";
2
2
  import { BreakdownComponentDef, ContextBreakdown, calculateBreakdownTotal, createEmptyBreakdown } from "@inkeep/agents-core";
3
3
 
4
4
  //#region src/domains/run/utils/token-estimator.d.ts
@@ -17,7 +17,7 @@ interface AssembleResult {
17
17
  /** The assembled prompt string */
18
18
  prompt: string;
19
19
  /** Token breakdown for each component */
20
- breakdown: _inkeep_agents_core2.ContextBreakdown;
20
+ breakdown: _inkeep_agents_core3.ContextBreakdown;
21
21
  }
22
22
  //#endregion
23
23
  export { AssembleResult, type BreakdownComponentDef, type ContextBreakdown, calculateBreakdownTotal, createEmptyBreakdown, estimateTokens };
package/dist/env.d.ts CHANGED
@@ -14,11 +14,11 @@ declare const envSchema: z.ZodObject<{
14
14
  pentest: "pentest";
15
15
  }>>;
16
16
  LOG_LEVEL: z.ZodDefault<z.ZodEnum<{
17
+ error: "error";
17
18
  trace: "trace";
18
19
  debug: "debug";
19
20
  info: "info";
20
21
  warn: "warn";
21
- error: "error";
22
22
  }>>;
23
23
  INKEEP_AGENTS_MANAGE_DATABASE_URL: z.ZodString;
24
24
  INKEEP_AGENTS_RUN_DATABASE_URL: z.ZodString;
@@ -53,7 +53,7 @@ declare const envSchema: z.ZodObject<{
53
53
  declare const env: {
54
54
  NODE_ENV: "development" | "production" | "test";
55
55
  ENVIRONMENT: "development" | "production" | "test" | "pentest";
56
- LOG_LEVEL: "trace" | "debug" | "info" | "warn" | "error";
56
+ LOG_LEVEL: "error" | "trace" | "debug" | "info" | "warn";
57
57
  INKEEP_AGENTS_MANAGE_DATABASE_URL: string;
58
58
  INKEEP_AGENTS_RUN_DATABASE_URL: string;
59
59
  INKEEP_AGENTS_API_URL: string;