@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 +356 -2
- package/dist/agent.js +3 -3
- package/dist/builderFunctions.d.ts +53 -16
- package/dist/builderFunctions.js +83 -17
- package/dist/credential-provider.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/project.js +2 -2
- package/package.json +2 -2
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 | `
|
|
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 | `
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
-
* //
|
|
311
|
-
* const
|
|
312
|
-
* name: '
|
|
313
|
-
* description: '
|
|
314
|
-
* messageTemplate: '
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
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
|
|
360
|
+
* // Simple webhook trigger with no signature verification
|
|
324
361
|
* const simpleTrigger = trigger({
|
|
325
|
-
* name: '
|
|
326
|
-
* description: '
|
|
362
|
+
* name: 'Internal Webhook',
|
|
363
|
+
* description: 'Internal webhook with no signature',
|
|
327
364
|
* messageTemplate: 'New message: {{text}}'
|
|
328
365
|
* });
|
|
329
366
|
* ```
|
package/dist/builderFunctions.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
*
|
|
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
|
-
* //
|
|
365
|
-
* const
|
|
366
|
-
* name: '
|
|
367
|
-
* description: '
|
|
368
|
-
* messageTemplate: '
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
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
|
|
415
|
+
* // Simple webhook trigger with no signature verification
|
|
378
416
|
* const simpleTrigger = trigger({
|
|
379
|
-
* name: '
|
|
380
|
-
* description: '
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
19
|
+
"@inkeep/agents-core": "^0.43.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/js-yaml": "^4.0.9",
|