@inkeep/agents-sdk 0.42.0 → 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.
package/README.md CHANGED
@@ -58,7 +58,7 @@ const token = await credentials.get('MY_TOKEN'); // Returns 'env-token'
58
58
  | Type | Description | Requirements |
59
59
  |------|-------------|--------------|
60
60
  | `memory` | In-memory storage with env var fallback | None (default) |
61
- | `keychain` | OS keychain storage | `keytar` package |
61
+ | `keychain` | OS keychain storage | `@napi-rs/keyring` package |
62
62
  | `nango` | OAuth credential management | `@nangohq/node`, `@nangohq/types` |
63
63
  | `custom` | Your own implementation | Implement `CredentialStore` interface |
64
64
 
@@ -117,6 +117,359 @@ tracer.startActiveSpan('my-operation', (span) => {
117
117
  | `ConsoleTelemetryProvider` | Logs to console | None |
118
118
  | Custom OpenTelemetry | Full observability | `@opentelemetry/*` packages |
119
119
 
120
+ ## Webhook Triggers with Signature Verification
121
+
122
+ Webhook triggers allow your agents to be invoked by external services like GitHub, Slack, Stripe, and Zendesk. The SDK provides flexible HMAC signature verification to ensure webhook requests are authentic.
123
+
124
+ ### Basic Webhook Trigger
125
+
126
+ Create a simple webhook trigger without signature verification:
127
+
128
+ ```typescript
129
+ import { trigger, credentialReference } from '@inkeep/agents-sdk';
130
+
131
+ export const myWebhook = trigger({
132
+ id: 'github-webhook',
133
+ name: 'GitHub Webhook',
134
+ description: 'Triggered by GitHub push events',
135
+ });
136
+ ```
137
+
138
+ ### Webhook Signature Verification
139
+
140
+ Different webhook providers use different signature patterns. The SDK supports all common patterns through flexible configuration.
141
+
142
+ #### Quick Examples
143
+
144
+ **GitHub Webhooks:**
145
+
146
+ ```typescript
147
+ import { trigger, credentialReference } from '@inkeep/agents-sdk';
148
+
149
+ export const githubWebhook = trigger({
150
+ id: 'github-webhook',
151
+ name: 'GitHub Webhook',
152
+ description: 'Verified GitHub webhook',
153
+ signingSecretCredentialReference: credentialReference({
154
+ id: 'github-webhook-secret',
155
+ }),
156
+ signatureVerification: {
157
+ algorithm: 'sha256',
158
+ encoding: 'hex',
159
+ signature: {
160
+ source: 'header',
161
+ key: 'X-Hub-Signature-256',
162
+ prefix: 'sha256=',
163
+ },
164
+ signedComponents: [
165
+ {
166
+ source: 'body',
167
+ required: true,
168
+ },
169
+ ],
170
+ componentJoin: {
171
+ strategy: 'concatenate',
172
+ separator: '',
173
+ },
174
+ },
175
+ });
176
+ ```
177
+
178
+ **Slack Webhooks:**
179
+
180
+ ```typescript
181
+ export const slackWebhook = trigger({
182
+ id: 'slack-webhook',
183
+ name: 'Slack Webhook',
184
+ description: 'Verified Slack webhook',
185
+ signingSecretCredentialReference: credentialReference({
186
+ id: 'slack-signing-secret',
187
+ }),
188
+ signatureVerification: {
189
+ algorithm: 'sha256',
190
+ encoding: 'hex',
191
+ signature: {
192
+ source: 'header',
193
+ key: 'X-Slack-Signature',
194
+ prefix: 'v0=',
195
+ },
196
+ signedComponents: [
197
+ {
198
+ source: 'literal',
199
+ value: 'v0',
200
+ required: true,
201
+ },
202
+ {
203
+ source: 'header',
204
+ key: 'X-Slack-Request-Timestamp',
205
+ required: true,
206
+ },
207
+ {
208
+ source: 'body',
209
+ required: true,
210
+ },
211
+ ],
212
+ componentJoin: {
213
+ strategy: 'concatenate',
214
+ separator: ':',
215
+ },
216
+ },
217
+ });
218
+ ```
219
+
220
+ **Zendesk Webhooks:**
221
+
222
+ ```typescript
223
+ export const zendeskWebhook = trigger({
224
+ id: 'zendesk-webhook',
225
+ name: 'Zendesk Webhook',
226
+ description: 'Verified Zendesk webhook',
227
+ signingSecretCredentialReference: credentialReference({
228
+ id: 'zendesk-signing-secret',
229
+ }),
230
+ signatureVerification: {
231
+ algorithm: 'sha256',
232
+ encoding: 'base64',
233
+ signature: {
234
+ source: 'header',
235
+ key: 'X-Zendesk-Webhook-Signature',
236
+ },
237
+ signedComponents: [
238
+ {
239
+ source: 'header',
240
+ key: 'X-Zendesk-Webhook-Signature-Timestamp',
241
+ required: true,
242
+ },
243
+ {
244
+ source: 'body',
245
+ required: true,
246
+ },
247
+ ],
248
+ componentJoin: {
249
+ strategy: 'concatenate',
250
+ separator: '',
251
+ },
252
+ },
253
+ });
254
+ ```
255
+
256
+ **Stripe Webhooks:**
257
+
258
+ ```typescript
259
+ export const stripeWebhook = trigger({
260
+ id: 'stripe-webhook',
261
+ name: 'Stripe Webhook',
262
+ description: 'Verified Stripe webhook',
263
+ signingSecretCredentialReference: credentialReference({
264
+ id: 'stripe-webhook-secret',
265
+ }),
266
+ signatureVerification: {
267
+ algorithm: 'sha256',
268
+ encoding: 'hex',
269
+ signature: {
270
+ source: 'header',
271
+ key: 'Stripe-Signature',
272
+ regex: 'v1=([a-f0-9]+)',
273
+ },
274
+ signedComponents: [
275
+ {
276
+ source: 'header',
277
+ key: 'Stripe-Signature',
278
+ regex: 't=([0-9]+)',
279
+ required: true,
280
+ },
281
+ {
282
+ source: 'body',
283
+ required: true,
284
+ },
285
+ ],
286
+ componentJoin: {
287
+ strategy: 'concatenate',
288
+ separator: '.',
289
+ },
290
+ },
291
+ });
292
+ ```
293
+
294
+ ### Configuration Reference
295
+
296
+ #### SignatureVerificationConfig
297
+
298
+ The `signatureVerification` object configures how webhook signatures are verified.
299
+
300
+ **Fields:**
301
+
302
+ - `algorithm` - HMAC algorithm: `'sha256'` | `'sha512'` | `'sha384'` | `'sha1'` | `'md5'`
303
+ - **Recommended:** `'sha256'` (most secure and widely supported)
304
+ - **Warning:** `'sha1'` and `'md5'` are cryptographically weak and only supported for legacy systems
305
+
306
+ - `encoding` - Signature encoding: `'hex'` | `'base64'`
307
+ - **Default:** `'hex'` (used by most providers)
308
+
309
+ - `signature` - Where and how to extract the signature from the request
310
+
311
+ - `signedComponents` - Array of components that make up the signed data
312
+
313
+ - `componentJoin` - How to join multiple components before verification
314
+
315
+ - `validation` (optional) - Advanced validation options
316
+
317
+ #### Signature Source
318
+
319
+ The `signature` field specifies where to find the signature in the webhook request.
320
+
321
+ **Fields:**
322
+
323
+ - `source` - Location: `'header'` | `'query'` | `'body'`
324
+ - `'header'` - Extract from HTTP header (most common)
325
+ - `'query'` - Extract from URL query parameter
326
+ - `'body'` - Extract from request body using JMESPath
327
+
328
+ - `key` - Identifier for the signature:
329
+ - For headers: Header name (e.g., `'X-Hub-Signature-256'`)
330
+ - For query params: Parameter name (e.g., `'signature'`)
331
+ - For body: JMESPath expression (e.g., `'signature'` or `'headers."X-Signature"'`)
332
+
333
+ - `prefix` (optional) - Prefix to strip from signature (e.g., `'sha256='`, `'v0='`)
334
+
335
+ - `regex` (optional) - Regular expression with capture group for complex formats (e.g., `'v1=([a-f0-9]+)'`)
336
+
337
+ #### Signed Components
338
+
339
+ The `signedComponents` array specifies what data was signed by the webhook provider. Components are joined in order using the `componentJoin` configuration.
340
+
341
+ **Component Fields:**
342
+
343
+ - `source` - Component location: `'header'` | `'body'` | `'literal'`
344
+ - `'header'` - Extract from HTTP header
345
+ - `'body'` - Extract from request body (uses entire body as string)
346
+ - `'literal'` - Use a fixed string value
347
+
348
+ - `key` (optional) - Identifier:
349
+ - For headers: Header name (e.g., `'X-Slack-Request-Timestamp'`)
350
+ - For body: JMESPath expression (e.g., `'data.timestamp'`)
351
+ - Not used for literal components
352
+
353
+ - `value` (optional) - Static string value (only for `source: 'literal'`)
354
+
355
+ - `regex` (optional) - Regex with capture group to extract part of the value
356
+
357
+ - `required` - Whether component must be present (default: `true`)
358
+ - If `false`, missing components are treated as empty strings
359
+
360
+ #### Component Join
361
+
362
+ The `componentJoin` field specifies how to combine multiple signed components.
363
+
364
+ **Fields:**
365
+
366
+ - `strategy` - Join strategy: `'concatenate'` (only option currently)
367
+
368
+ - `separator` - String to insert between components:
369
+ - `''` (empty) - Direct concatenation (GitHub, Zendesk)
370
+ - `':'` - Colon separator (Slack)
371
+ - `'.'` - Dot separator (Stripe)
372
+
373
+ #### Advanced Validation Options
374
+
375
+ The optional `validation` field provides fine-grained control over verification behavior.
376
+
377
+ **Fields:**
378
+
379
+ - `headerCaseSensitive` (default: `false`) - Whether header names are case-sensitive
380
+ - `false` - Case-insensitive matching (HTTP standard, recommended)
381
+ - `true` - Exact case match required
382
+
383
+ - `allowEmptyBody` (default: `true`) - Whether to allow requests with empty bodies
384
+ - `true` - Empty bodies are valid (some webhooks send header-only verification requests)
385
+ - `false` - Reject requests with empty bodies
386
+
387
+ - `normalizeUnicode` (default: `false`) - Whether to normalize Unicode to NFC form
388
+ - `false` - Use raw body bytes
389
+ - `true` - Normalize to NFC before verification (handles different Unicode representations)
390
+
391
+ **Example with validation options:**
392
+
393
+ ```typescript
394
+ signatureVerification: {
395
+ algorithm: 'sha256',
396
+ encoding: 'hex',
397
+ signature: {
398
+ source: 'header',
399
+ key: 'X-Signature',
400
+ },
401
+ signedComponents: [{ source: 'body', required: true }],
402
+ componentJoin: { strategy: 'concatenate', separator: '' },
403
+ validation: {
404
+ headerCaseSensitive: true,
405
+ allowEmptyBody: false,
406
+ normalizeUnicode: true,
407
+ },
408
+ },
409
+ ```
410
+
411
+ ### Migration from Legacy `signingSecret`
412
+
413
+ **Breaking Change:** The legacy `signingSecret` parameter has been removed. All triggers must use credential references and the new `signatureVerification` configuration.
414
+
415
+ **Before (deprecated):**
416
+
417
+ ```typescript
418
+ export const webhook = trigger({
419
+ id: 'my-webhook',
420
+ signingSecret: 'my-secret-key', // ❌ No longer supported
421
+ });
422
+ ```
423
+
424
+ **After (current):**
425
+
426
+ ```typescript
427
+ export const webhook = trigger({
428
+ id: 'my-webhook',
429
+ signingSecretCredentialReference: credentialReference({
430
+ id: 'webhook-secret',
431
+ }),
432
+ signatureVerification: {
433
+ algorithm: 'sha256',
434
+ encoding: 'hex',
435
+ signature: {
436
+ source: 'header',
437
+ key: 'X-Hub-Signature-256',
438
+ prefix: 'sha256=',
439
+ },
440
+ signedComponents: [{ source: 'body', required: true }],
441
+ componentJoin: { strategy: 'concatenate', separator: '' },
442
+ },
443
+ });
444
+ ```
445
+
446
+ ### Security Best Practices
447
+
448
+ 1. **Always use credential references** - Never hardcode signing secrets in your code
449
+ 2. **Use strong algorithms** - Prefer `sha256` or stronger; avoid `sha1` and `md5`
450
+ 3. **Validate all webhooks** - Always configure signature verification for production webhooks
451
+ 4. **Use HTTPS** - Always receive webhooks over HTTPS to prevent man-in-the-middle attacks
452
+ 5. **Rotate secrets regularly** - Update signing secrets periodically
453
+ 6. **Monitor failed verifications** - Failed signature checks may indicate an attack
454
+
455
+ ### Troubleshooting
456
+
457
+ **Signature verification always fails:**
458
+
459
+ 1. Verify your signing secret is correct in the credential store
460
+ 2. Check that the `algorithm` matches what the provider uses
461
+ 3. Verify the `encoding` (hex vs base64)
462
+ 4. Ensure `signedComponents` match what the provider actually signs
463
+ 5. Check the `separator` in `componentJoin`
464
+ 6. For body-based components, ensure you're not modifying the raw body
465
+
466
+ **Provider-specific tips:**
467
+
468
+ - **GitHub:** Requires `prefix: 'sha256='` and signs only the raw body
469
+ - **Slack:** Signs three components with colons: `v0:{timestamp}:{body}`
470
+ - **Stripe:** Uses regex extraction for both signature and timestamp from the same header
471
+ - **Zendesk:** Uses base64 encoding instead of hex
472
+
120
473
  ## API Reference
121
474
 
122
475
  ### Builders
@@ -124,6 +477,7 @@ tracer.startActiveSpan('my-operation', (span) => {
124
477
  - `agent()` - Create an agent (top-level container with multiple sub-agents)
125
478
  - `subAgent()` - Create a sub-agent configuration
126
479
  - `tool()` - Create a tool configuration
480
+ - `trigger()` - Create a webhook trigger configuration
127
481
  - `mcpServer()` - Create an MCP server configuration
128
482
  - `mcpTool()` - Create an MCP tool
129
483
  - `dataComponent()` - Create a data component
@@ -190,7 +544,7 @@ The SDK has minimal required dependencies. Advanced features require optional pa
190
544
  | Feature | Required Packages |
191
545
  |---------|------------------|
192
546
  | Nango credentials | `@nangohq/node`, `@nangohq/types` |
193
- | Keychain storage | `keytar` |
547
+ | Keychain storage | `@napi-rs/keyring` |
194
548
  | OpenTelemetry | `@opentelemetry/api`, `@opentelemetry/sdk-node` |
195
549
 
196
550
  Install only what you need:
package/dist/agent.js CHANGED
@@ -58,7 +58,7 @@ var Agent = class {
58
58
  agentCount: this.subAgents.length,
59
59
  defaultSubAgent: this.defaultSubAgent?.getName(),
60
60
  triggerCount: this.triggers.length
61
- }, "Agent created");
61
+ }, "Agent initialized");
62
62
  }
63
63
  /**
64
64
  * Set or update the configuration (tenantId, projectId and apiUrl)
@@ -82,7 +82,7 @@ var Agent = class {
82
82
  tenantId: this.tenantId,
83
83
  projectId: this.projectId,
84
84
  apiUrl: this.baseURL
85
- }, "Agent configuration updated");
85
+ }, "Agent configured");
86
86
  }
87
87
  /**
88
88
  * Convert the Agent to FullAgentDefinition format for the new agent endpoint
@@ -246,7 +246,7 @@ var Agent = class {
246
246
  contextConfig: this.contextConfig?.toObject(),
247
247
  ...Object.keys(functionToolsObject).length > 0 && { functionTools: functionToolsObject },
248
248
  ...Object.keys(functionsObject).length > 0 && { functions: functionsObject },
249
- ...Object.keys(triggersObject).length > 0 && { triggers: triggersObject },
249
+ triggers: triggersObject,
250
250
  models: this.models,
251
251
  stopWhen: this.stopWhen,
252
252
  statusUpdates: processedStatusUpdates,
@@ -274,16 +274,24 @@ declare function functionTool(config: FunctionToolConfig): FunctionTool;
274
274
  *
275
275
  * Triggers allow external services to invoke agents via webhooks.
276
276
  * They support authentication via arbitrary header key-value pairs,
277
- * payload transformation, and input validation.
277
+ * payload transformation, input validation, and signature verification.
278
278
  *
279
279
  * @param config - Trigger configuration
280
280
  * @returns A Trigger instance
281
+ * @throws {Error} If signatureVerification config validation fails
281
282
  *
282
283
  * @example
283
284
  * ```typescript
284
285
  * import { z } from 'zod';
285
286
  *
286
- * // GitHub webhook trigger with header-based authentication
287
+ * // GitHub webhook trigger with signature verification
288
+ * const githubWebhookSecret = credential({
289
+ * id: 'github-webhook-secret',
290
+ * name: 'GitHub Webhook Secret',
291
+ * type: 'bearer',
292
+ * value: process.env.GITHUB_WEBHOOK_SECRET
293
+ * });
294
+ *
287
295
  * const githubTrigger = trigger({
288
296
  * name: 'GitHub Events',
289
297
  * description: 'Handle GitHub webhook events',
@@ -304,26 +312,55 @@ declare function functionTool(config: FunctionToolConfig): FunctionTool;
304
312
  * { name: 'X-GitHub-Token', value: process.env.GITHUB_TOKEN }
305
313
  * ]
306
314
  * },
307
- * signingSecret: process.env.GITHUB_WEBHOOK_SECRET
315
+ * signingSecretCredentialReference: githubWebhookSecret,
316
+ * signatureVerification: {
317
+ * algorithm: 'sha256',
318
+ * encoding: 'hex',
319
+ * signature: {
320
+ * source: 'header',
321
+ * key: 'x-hub-signature-256',
322
+ * prefix: 'sha256='
323
+ * },
324
+ * signedComponents: [
325
+ * { source: 'body', required: true }
326
+ * ],
327
+ * componentJoin: {
328
+ * strategy: 'concatenate',
329
+ * separator: ''
330
+ * }
331
+ * }
308
332
  * });
309
333
  *
310
- * // Multiple authentication headers
311
- * const multiHeaderTrigger = trigger({
312
- * name: 'Secure Webhook',
313
- * description: 'Webhook with multiple auth headers',
314
- * messageTemplate: 'Received: {{data}}',
315
- * authentication: {
316
- * headers: [
317
- * { name: 'X-API-Key', value: process.env.API_KEY },
318
- * { name: 'X-Client-ID', value: process.env.CLIENT_ID }
319
- * ]
334
+ * // Slack webhook trigger with complex signature
335
+ * const slackTrigger = trigger({
336
+ * name: 'Slack Events',
337
+ * description: 'Handle Slack webhook events',
338
+ * messageTemplate: 'Slack event: {{type}}',
339
+ * signingSecretCredentialReference: slackSecret,
340
+ * signatureVerification: {
341
+ * algorithm: 'sha256',
342
+ * encoding: 'hex',
343
+ * signature: {
344
+ * source: 'header',
345
+ * key: 'x-slack-signature',
346
+ * prefix: 'v0='
347
+ * },
348
+ * signedComponents: [
349
+ * { source: 'literal', value: 'v0', required: true },
350
+ * { source: 'header', key: 'x-slack-request-timestamp', required: true },
351
+ * { source: 'body', required: true }
352
+ * ],
353
+ * componentJoin: {
354
+ * strategy: 'concatenate',
355
+ * separator: ':'
356
+ * }
320
357
  * }
321
358
  * });
322
359
  *
323
- * // Simple webhook trigger with no auth
360
+ * // Simple webhook trigger with no signature verification
324
361
  * const simpleTrigger = trigger({
325
- * name: 'Slack Message',
326
- * description: 'Handle Slack messages',
362
+ * name: 'Internal Webhook',
363
+ * description: 'Internal webhook with no signature',
327
364
  * messageTemplate: 'New message: {{text}}'
328
365
  * });
329
366
  * ```
@@ -8,7 +8,8 @@ import { StatusComponent as StatusComponent$1 } from "./status-component.js";
8
8
  import { Tool } from "./tool.js";
9
9
  import { SubAgent } from "./subAgent.js";
10
10
  import { Trigger } from "./trigger.js";
11
- import { CredentialReferenceApiInsertSchema, MCPToolConfigSchema } from "@inkeep/agents-core";
11
+ import { CredentialReferenceApiInsertSchema, MCPToolConfigSchema, SignatureVerificationConfigSchema } from "@inkeep/agents-core";
12
+ import { validateJMESPath, validateRegex } from "@inkeep/agents-core/utils/signature-validation";
12
13
 
13
14
  //#region src/builderFunctions.ts
14
15
  /**
@@ -328,16 +329,24 @@ function functionTool(config) {
328
329
  *
329
330
  * Triggers allow external services to invoke agents via webhooks.
330
331
  * They support authentication via arbitrary header key-value pairs,
331
- * payload transformation, and input validation.
332
+ * payload transformation, input validation, and signature verification.
332
333
  *
333
334
  * @param config - Trigger configuration
334
335
  * @returns A Trigger instance
336
+ * @throws {Error} If signatureVerification config validation fails
335
337
  *
336
338
  * @example
337
339
  * ```typescript
338
340
  * import { z } from 'zod';
339
341
  *
340
- * // GitHub webhook trigger with header-based authentication
342
+ * // GitHub webhook trigger with signature verification
343
+ * const githubWebhookSecret = credential({
344
+ * id: 'github-webhook-secret',
345
+ * name: 'GitHub Webhook Secret',
346
+ * type: 'bearer',
347
+ * value: process.env.GITHUB_WEBHOOK_SECRET
348
+ * });
349
+ *
341
350
  * const githubTrigger = trigger({
342
351
  * name: 'GitHub Events',
343
352
  * description: 'Handle GitHub webhook events',
@@ -358,31 +367,88 @@ function functionTool(config) {
358
367
  * { name: 'X-GitHub-Token', value: process.env.GITHUB_TOKEN }
359
368
  * ]
360
369
  * },
361
- * signingSecret: process.env.GITHUB_WEBHOOK_SECRET
370
+ * signingSecretCredentialReference: githubWebhookSecret,
371
+ * signatureVerification: {
372
+ * algorithm: 'sha256',
373
+ * encoding: 'hex',
374
+ * signature: {
375
+ * source: 'header',
376
+ * key: 'x-hub-signature-256',
377
+ * prefix: 'sha256='
378
+ * },
379
+ * signedComponents: [
380
+ * { source: 'body', required: true }
381
+ * ],
382
+ * componentJoin: {
383
+ * strategy: 'concatenate',
384
+ * separator: ''
385
+ * }
386
+ * }
362
387
  * });
363
388
  *
364
- * // Multiple authentication headers
365
- * const multiHeaderTrigger = trigger({
366
- * name: 'Secure Webhook',
367
- * description: 'Webhook with multiple auth headers',
368
- * messageTemplate: 'Received: {{data}}',
369
- * authentication: {
370
- * headers: [
371
- * { name: 'X-API-Key', value: process.env.API_KEY },
372
- * { name: 'X-Client-ID', value: process.env.CLIENT_ID }
373
- * ]
389
+ * // Slack webhook trigger with complex signature
390
+ * const slackTrigger = trigger({
391
+ * name: 'Slack Events',
392
+ * description: 'Handle Slack webhook events',
393
+ * messageTemplate: 'Slack event: {{type}}',
394
+ * signingSecretCredentialReference: slackSecret,
395
+ * signatureVerification: {
396
+ * algorithm: 'sha256',
397
+ * encoding: 'hex',
398
+ * signature: {
399
+ * source: 'header',
400
+ * key: 'x-slack-signature',
401
+ * prefix: 'v0='
402
+ * },
403
+ * signedComponents: [
404
+ * { source: 'literal', value: 'v0', required: true },
405
+ * { source: 'header', key: 'x-slack-request-timestamp', required: true },
406
+ * { source: 'body', required: true }
407
+ * ],
408
+ * componentJoin: {
409
+ * strategy: 'concatenate',
410
+ * separator: ':'
411
+ * }
374
412
  * }
375
413
  * });
376
414
  *
377
- * // Simple webhook trigger with no auth
415
+ * // Simple webhook trigger with no signature verification
378
416
  * const simpleTrigger = trigger({
379
- * name: 'Slack Message',
380
- * description: 'Handle Slack messages',
417
+ * name: 'Internal Webhook',
418
+ * description: 'Internal webhook with no signature',
381
419
  * messageTemplate: 'New message: {{text}}'
382
420
  * });
383
421
  * ```
384
422
  */
385
423
  function trigger(config) {
424
+ if (config.signatureVerification !== void 0 && config.signatureVerification !== null) {
425
+ const triggerName = config.name || "unknown";
426
+ try {
427
+ SignatureVerificationConfigSchema.parse(config.signatureVerification);
428
+ } catch (error) {
429
+ if (error instanceof Error) throw new Error(`Invalid signatureVerification config in trigger '${triggerName}': ${error.message}`);
430
+ throw error;
431
+ }
432
+ const sigConfig = config.signatureVerification;
433
+ if (sigConfig.signature.regex) {
434
+ const result = validateRegex(sigConfig.signature.regex);
435
+ if (!result.valid) throw new Error(`Invalid signatureVerification config in trigger '${triggerName}': ${result.error}`);
436
+ }
437
+ if (sigConfig.signature.source === "body" && sigConfig.signature.key) {
438
+ const result = validateJMESPath(sigConfig.signature.key);
439
+ if (!result.valid) throw new Error(`Invalid signatureVerification config in trigger '${triggerName}': ${result.error}`);
440
+ }
441
+ for (const component of sigConfig.signedComponents) {
442
+ if (component.regex) {
443
+ const result = validateRegex(component.regex);
444
+ if (!result.valid) throw new Error(`Invalid signatureVerification config in trigger '${triggerName}': ${result.error}`);
445
+ }
446
+ if (component.source === "body" && component.key) {
447
+ const result = validateJMESPath(component.key);
448
+ if (!result.valid) throw new Error(`Invalid signatureVerification config in trigger '${triggerName}': ${result.error}`);
449
+ }
450
+ }
451
+ }
386
452
  return new Trigger(config);
387
453
  }
388
454
 
@@ -111,7 +111,7 @@ var InkeepCredentialProvider = class {
111
111
  } catch {
112
112
  return {
113
113
  available: false,
114
- reason: "Keychain store requires keytar package to be installed"
114
+ reason: "Keychain store requires @napi-rs/keyring package to be installed"
115
115
  };
116
116
  }
117
117
  }
package/dist/index.d.ts CHANGED
@@ -17,5 +17,5 @@ import { EvaluationClient, EvaluationClientConfig, evaluationClient } from "./ev
17
17
  import { createFullProjectViaAPI, deleteFullProjectViaAPI, getFullProjectViaAPI, updateFullProjectViaAPI } from "./projectFullClient.js";
18
18
  import { Runner, raceAgents, run, stream } from "./runner.js";
19
19
  import { ConsoleTelemetryProvider, InkeepTelemetryProvider, NoOpTelemetryProvider, OpenTelemetryConfig, SpanOptions, SpanStatus, SpanStatusType, TelemetryConfig, TelemetryLogger, TelemetryMetrics, TelemetryProvider, TelemetrySpan, TelemetryTracer, createConsoleTelemetryProvider, createNoOpTelemetryProvider, createOpenTelemetryProvider, getGlobalTelemetryProvider, setGlobalTelemetryProvider } from "./telemetry-provider.js";
20
- import { ANTHROPIC_MODELS, GOOGLE_MODELS, OPENAI_MODELS } from "@inkeep/agents-core";
21
- export { ANTHROPIC_MODELS, AgentConfig, AgentError, AgentInterface, AgentResponse, AgentTool, AllDelegateInputInterface, AllDelegateOutputInterface, ArtifactComponent, type ArtifactComponentInterface, ArtifactComponentWithZodProps, AssistantMessage, BuilderAgentConfig, BuilderRelationConfig, BuilderToolConfig, ConsoleTelemetryProvider, type CredentialProviderConfig, type CredentialProviderType, type CredentialReference, type CredentialStore, type CustomCredentialConfig, DataComponent, type DataComponentInterface, DataComponentWithZodProps, EvaluationClient, type EvaluationClientConfig, ExternalAgent, ExternalAgentInterface, type ExtractCredentialIds, FetchDefinitionConfig, FunctionTool, FunctionToolConfig, GOOGLE_MODELS, GenerateOptions, InkeepCredentialProvider, InkeepTelemetryProvider, type KeychainCredentialConfig, MCPToolConfig, MaxTurnsExceededError, type MemoryCredentialConfig, Message, MessageInput, ModelSettings, type NangoCredentialConfig, NoOpTelemetryProvider, OPENAI_MODELS, type OpenTelemetryConfig, Project, RequestSchemaConfig, RequestSchemaDefinition, RunResult, Runner, ServerConfig, type SpanOptions, SpanStatus, type SpanStatusType, StatusComponent, type StatusComponentInterface, StreamEvent, StreamResponse, SubAgent, SubAgentCanUseType, SubAgentConfig, SubAgentInterface, SystemMessage, type TelemetryConfig, type TelemetryLogger, type TelemetryMetrics, type TelemetryProvider, type TelemetrySpan, type TelemetryTracer, Tool, ToolCall, ToolConfig, ToolExecutionError, ToolMessage, ToolResult, TransferConfig, TransferError, Trigger, type TriggerConfig, type TriggerInterface, type UnionCredentialIds, UserMessage, agent, agentMcp, artifactComponent, createConsoleTelemetryProvider, createCredentialProvider, createEnvironmentSettings, createFullProjectViaAPI, createNoOpTelemetryProvider, createOpenTelemetryProvider, credential, credentialRef, dataComponent, deleteFullProjectViaAPI, evaluationClient, externalAgent, externalAgents, functionTool, getFullProjectViaAPI, getGlobalTelemetryProvider, isCredentialReference, mcpServer, mcpTool, project, raceAgents, registerEnvironmentSettings, run, setGlobalTelemetryProvider, statusComponent, stream, subAgent, subAgentExternalAgentInterface, subAgentTeamAgentInterface, transfer, trigger, updateFullProjectViaAPI };
20
+ import { ANTHROPIC_MODELS, GOOGLE_MODELS, OPENAI_MODELS, SignatureSource, SignatureVerificationConfig, SignedComponent } from "@inkeep/agents-core";
21
+ export { ANTHROPIC_MODELS, AgentConfig, AgentError, AgentInterface, AgentResponse, AgentTool, AllDelegateInputInterface, AllDelegateOutputInterface, ArtifactComponent, type ArtifactComponentInterface, ArtifactComponentWithZodProps, AssistantMessage, BuilderAgentConfig, BuilderRelationConfig, BuilderToolConfig, ConsoleTelemetryProvider, type CredentialProviderConfig, type CredentialProviderType, type CredentialReference, type CredentialStore, type CustomCredentialConfig, DataComponent, type DataComponentInterface, DataComponentWithZodProps, EvaluationClient, type EvaluationClientConfig, ExternalAgent, ExternalAgentInterface, type ExtractCredentialIds, FetchDefinitionConfig, FunctionTool, FunctionToolConfig, GOOGLE_MODELS, GenerateOptions, InkeepCredentialProvider, InkeepTelemetryProvider, type KeychainCredentialConfig, MCPToolConfig, MaxTurnsExceededError, type MemoryCredentialConfig, Message, MessageInput, ModelSettings, type NangoCredentialConfig, NoOpTelemetryProvider, OPENAI_MODELS, type OpenTelemetryConfig, Project, RequestSchemaConfig, RequestSchemaDefinition, RunResult, Runner, ServerConfig, type SignatureSource, type SignatureVerificationConfig, type SignedComponent, type SpanOptions, SpanStatus, type SpanStatusType, StatusComponent, type StatusComponentInterface, StreamEvent, StreamResponse, SubAgent, SubAgentCanUseType, SubAgentConfig, SubAgentInterface, SystemMessage, type TelemetryConfig, type TelemetryLogger, type TelemetryMetrics, type TelemetryProvider, type TelemetrySpan, type TelemetryTracer, Tool, ToolCall, ToolConfig, ToolExecutionError, ToolMessage, ToolResult, TransferConfig, TransferError, Trigger, type TriggerConfig, type TriggerInterface, type UnionCredentialIds, UserMessage, agent, agentMcp, artifactComponent, createConsoleTelemetryProvider, createCredentialProvider, createEnvironmentSettings, createFullProjectViaAPI, createNoOpTelemetryProvider, createOpenTelemetryProvider, credential, credentialRef, dataComponent, deleteFullProjectViaAPI, evaluationClient, externalAgent, externalAgents, functionTool, getFullProjectViaAPI, getGlobalTelemetryProvider, isCredentialReference, mcpServer, mcpTool, project, raceAgents, registerEnvironmentSettings, run, setGlobalTelemetryProvider, statusComponent, stream, subAgent, subAgentExternalAgentInterface, subAgentTeamAgentInterface, transfer, trigger, updateFullProjectViaAPI };
package/dist/project.js CHANGED
@@ -74,7 +74,7 @@ var Project = class {
74
74
  projectId: this.projectId,
75
75
  tenantId: this.tenantId,
76
76
  agentCount: this.agents.length
77
- }, "Project created");
77
+ }, "Project loaded");
78
78
  }
79
79
  /**
80
80
  * Set or update the configuration (tenantId and apiUrl)
@@ -93,7 +93,7 @@ var Project = class {
93
93
  apiUrl: this.baseURL,
94
94
  hasModels: !!this.models,
95
95
  hasApiKey: !!this.apiKey
96
- }, "Project configuration updated");
96
+ }, "Project configured");
97
97
  }
98
98
  /**
99
99
  * Set credential references for the project
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-sdk",
3
- "version": "0.42.0",
3
+ "version": "0.43.0",
4
4
  "description": "Agents SDK for building and managing agents in the Inkeep Agent Framework",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -16,7 +16,7 @@
16
16
  "js-yaml": "^4.1.0",
17
17
  "typescript": "^5.3.3",
18
18
  "zod": "^4.1.11",
19
- "@inkeep/agents-core": "^0.42.0"
19
+ "@inkeep/agents-core": "^0.43.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/js-yaml": "^4.0.9",