@backendkit-labs/agent-web 0.6.4 → 0.6.6
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 +82 -193
- package/package.json +51 -51
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# @backendkit-labs/agent-web
|
|
2
2
|
|
|
3
|
-
> **Status: `stable`** — Maintained and production-ready. `TriggerBus` (cron/webhook/BullMQ) is `experimental` and frozen during the pilot phase.
|
|
4
|
-
|
|
5
3
|
HTTP/WebSocket server layer for [@backendkit-labs/agent-core](https://www.npmjs.com/package/@backendkit-labs/agent-core).
|
|
6
4
|
|
|
7
5
|
Wraps `AgentEngine` in a Fastify 5 server with streaming WebSocket sessions, JWT authentication, Prometheus metrics, rate limiting, a real-time monitor bus, and a flexible trigger system (cron jobs, webhooks, BullMQ queues).
|
|
@@ -222,53 +220,49 @@ const engineFactory: EngineFactory = (sessionId, transport) => {
|
|
|
222
220
|
};
|
|
223
221
|
```
|
|
224
222
|
|
|
225
|
-
### Factory with
|
|
223
|
+
### Factory with per-user context
|
|
226
224
|
|
|
227
|
-
When
|
|
225
|
+
Each WebSocket connection to `/chat` gets its own session with a random `sessionId`, and the factory builds a fresh engine for it. When `auth` is set, the authenticated user (the JWT `sub`) becomes the **owner** of the session: other users cannot see it in `/sessions` or `/monitor`. To load per-user settings in the engine, keep your own map from session to user, or read them inside your tools.
|
|
228
226
|
|
|
229
227
|
```typescript
|
|
230
|
-
const engineFactory: EngineFactory = (sessionId, transport) =>
|
|
231
|
-
|
|
232
|
-
const userConfig = getUserConfig(sessionId); // look up per-user settings
|
|
233
|
-
|
|
234
|
-
return new AgentEngine({
|
|
235
|
-
transport,
|
|
236
|
-
sessionId,
|
|
237
|
-
projectContext: `User: ${userConfig.name}\nRole: ${userConfig.role}`,
|
|
228
|
+
const engineFactory: EngineFactory = (sessionId, transport) =>
|
|
229
|
+
new AgentEngine({
|
|
238
230
|
...baseConfig,
|
|
231
|
+
transport,
|
|
232
|
+
sessionId, // also the session's id in metrics, monitor and audit
|
|
239
233
|
});
|
|
240
|
-
};
|
|
241
234
|
```
|
|
242
235
|
|
|
243
236
|
---
|
|
244
237
|
|
|
245
238
|
## SessionManager
|
|
246
239
|
|
|
247
|
-
`SessionManager` creates, tracks
|
|
240
|
+
`SessionManager` creates, tracks and cleans up sessions. `AgentServer` creates one internally; you can also use it on your own WebSocket server.
|
|
248
241
|
|
|
249
242
|
```typescript
|
|
250
243
|
import { SessionManager } from '@backendkit-labs/agent-web';
|
|
251
244
|
|
|
252
245
|
const sessions = new SessionManager({
|
|
253
246
|
engineFactory,
|
|
254
|
-
maxIdleMs: 30 * 60 * 1000, // close after 30 min of inactivity
|
|
255
|
-
maxSessions: 100,
|
|
247
|
+
maxIdleMs: 30 * 60 * 1000, // close after 30 min of inactivity (default)
|
|
248
|
+
maxSessions: 100, // reject new sessions beyond this (default)
|
|
256
249
|
monitorBus: myMonitorBus,
|
|
257
250
|
metrics: myMetricsCollector,
|
|
258
251
|
store: myMetaStore,
|
|
259
252
|
});
|
|
260
253
|
|
|
261
|
-
//
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
254
|
+
const session = sessions.create(socket, userId); // one per WebSocket connection; userId is the owner
|
|
255
|
+
sessions.get(session.id);
|
|
256
|
+
sessions.list(); // [{ id, createdAt, lastActivityAt, userId }]
|
|
257
|
+
sessions.destroy(session.id);
|
|
258
|
+
sessions.close(); // all sessions, on shutdown
|
|
265
259
|
```
|
|
266
260
|
|
|
267
261
|
---
|
|
268
262
|
|
|
269
263
|
## JWT authentication
|
|
270
264
|
|
|
271
|
-
`JwtAuth` validates Bearer tokens
|
|
265
|
+
`JwtAuth` validates Bearer tokens on HTTP routes and on the WebSocket handshake. Browsers cannot set headers on a WebSocket, so the token can also travel as the subprotocol `bearer, <jwt>`. A `?token=` query parameter still works unless `allowQueryToken: false`.
|
|
272
266
|
|
|
273
267
|
### Strict mode
|
|
274
268
|
|
|
@@ -291,47 +285,26 @@ new AgentServer({ engineFactory, host: '0.0.0.0', auth, strict: true, cors: ['ht
|
|
|
291
285
|
import { AgentServer, JwtAuth } from '@backendkit-labs/agent-web';
|
|
292
286
|
|
|
293
287
|
const jwt = new JwtAuth({
|
|
294
|
-
secret:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
288
|
+
secret: process.env.JWT_SECRET!, // or publicKey for RS256 / ES256
|
|
289
|
+
algorithms: ['HS256'], // accepted algorithms
|
|
290
|
+
audience: 'agents', // optional checks
|
|
291
|
+
issuer: 'https://login.company.com',
|
|
298
292
|
});
|
|
299
293
|
|
|
300
|
-
const server = new AgentServer({
|
|
301
|
-
port: 3000,
|
|
302
|
-
engineFactory,
|
|
303
|
-
auth: jwt.hook(), // AuthHook applied to all routes
|
|
304
|
-
});
|
|
294
|
+
const server = new AgentServer({ port: 3000, engineFactory, auth: jwt.hook() });
|
|
305
295
|
```
|
|
306
296
|
|
|
307
|
-
|
|
297
|
+
The token must carry `sub` (the user id, owner of the sessions it opens); `email` and `roles` are read when present. `adminRole` in `AgentServerOptions` names the role that may see every session.
|
|
308
298
|
|
|
309
|
-
|
|
310
|
-
import { JwtAuth } from '@backendkit-labs/agent-web';
|
|
299
|
+
### Issuing tokens
|
|
311
300
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
// Issue a token for an authenticated user
|
|
315
|
-
const token = jwt.sign({
|
|
316
|
-
sub: 'user-123',
|
|
317
|
-
role: 'admin',
|
|
318
|
-
name: 'Alice',
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
// Return to client — they send it as:
|
|
322
|
-
// Authorization: Bearer <token>
|
|
323
|
-
// or ws://host/chat?token=<token>
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
### Per-user session isolation
|
|
327
|
-
|
|
328
|
-
When `sessionIdClaim` is `'sub'`, every user gets their own session automatically. Two requests with the same token always hit the same session:
|
|
301
|
+
`JwtAuth` only verifies. Issue tokens in your login endpoint with any JWT library and the same secret or key pair:
|
|
329
302
|
|
|
330
303
|
```typescript
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
304
|
+
import jwt from 'jsonwebtoken';
|
|
305
|
+
|
|
306
|
+
const token = jwt.sign({ sub: 'user-123', roles: ['admin'] }, process.env.JWT_SECRET!, { expiresIn: '24h' });
|
|
307
|
+
// The client sends it as Authorization: Bearer <token>, or as the WebSocket subprotocol `bearer, <token>`.
|
|
335
308
|
```
|
|
336
309
|
|
|
337
310
|
### Custom auth hook
|
|
@@ -385,13 +358,15 @@ import { MetricsCollector } from '@backendkit-labs/agent-web';
|
|
|
385
358
|
|
|
386
359
|
const collector = new MetricsCollector({ prefix: 'my_agent_' });
|
|
387
360
|
|
|
388
|
-
// Record a
|
|
389
|
-
const endRun = collector.
|
|
390
|
-
// ... after
|
|
361
|
+
// Record a run
|
|
362
|
+
const endRun = collector.runStarted();
|
|
363
|
+
// ... after it completes:
|
|
391
364
|
endRun('success'); // or endRun('error')
|
|
392
365
|
|
|
393
|
-
//
|
|
394
|
-
|
|
366
|
+
collector.sessionOpened(); // and sessionClosed(), messageReceived()
|
|
367
|
+
|
|
368
|
+
// Prometheus text format (serve it with collector.contentType)
|
|
369
|
+
const text = await collector.collect();
|
|
395
370
|
// # HELP my_agent_runs_total ...
|
|
396
371
|
// my_agent_runs_total{status="success"} 42
|
|
397
372
|
```
|
|
@@ -484,7 +459,13 @@ unsub();
|
|
|
484
459
|
|
|
485
460
|
## TriggerBus — cron, webhooks, queues
|
|
486
461
|
|
|
487
|
-
`TriggerBus`
|
|
462
|
+
`TriggerBus` runs agents without a WebSocket client: on a schedule, on an incoming webhook, or for each job of a BullMQ queue. Each run gets a fresh engine from the factory and a `HeadlessTransport`, and shows up in the monitor.
|
|
463
|
+
|
|
464
|
+
Every trigger has the same three callbacks:
|
|
465
|
+
|
|
466
|
+
- `buildPrompt(payload)` returns the prompt. `payload` is `undefined` for cron, the parsed body for a webhook, and `job.data` for a queue job.
|
|
467
|
+
- `onComplete(result)` receives `{ sessionId, triggerName, firedAt, durationMs, output, events }`.
|
|
468
|
+
- `onError(err, triggerName)` is called when the run throws.
|
|
488
469
|
|
|
489
470
|
### Cron trigger (requires `node-cron`)
|
|
490
471
|
|
|
@@ -496,20 +477,19 @@ const triggers = new TriggerBus(engineFactory)
|
|
|
496
477
|
name: 'daily-report',
|
|
497
478
|
schedule: '0 8 * * 1-5', // weekdays at 8 AM
|
|
498
479
|
buildPrompt: () => 'Generate the daily engineering standup summary from recent commits.',
|
|
499
|
-
runOnStart: false,
|
|
500
|
-
|
|
501
|
-
onError: (err) => logger.error(
|
|
480
|
+
runOnStart: false, // true fires once when the bus starts
|
|
481
|
+
onComplete: ({ output }) => slack.send('#daily', output),
|
|
482
|
+
onError: (err, name) => logger.error(`[${name}]`, err),
|
|
502
483
|
})
|
|
503
484
|
.addCron({
|
|
504
485
|
name: 'health-check',
|
|
505
|
-
schedule: '*/15 * * * *',
|
|
486
|
+
schedule: '*/15 * * * *',
|
|
506
487
|
buildPrompt: () => 'Check all API endpoints and report any that are down.',
|
|
507
|
-
|
|
488
|
+
onComplete: ({ output }) => { if (output.includes('DOWN')) pagerduty.alert(output); },
|
|
508
489
|
});
|
|
509
490
|
|
|
510
|
-
const server = new AgentServer({
|
|
511
|
-
await server.start();
|
|
512
|
-
// Cron jobs start automatically with the server
|
|
491
|
+
const server = new AgentServer({ ...opts, triggers });
|
|
492
|
+
await server.start(); // cron jobs start with the server
|
|
513
493
|
```
|
|
514
494
|
|
|
515
495
|
### Webhook trigger
|
|
@@ -518,207 +498,116 @@ await server.start();
|
|
|
518
498
|
const triggers = new TriggerBus(engineFactory)
|
|
519
499
|
.addWebhook({
|
|
520
500
|
name: 'github-pr',
|
|
521
|
-
path: '/webhooks/github',
|
|
522
|
-
secret: process.env.GITHUB_SECRET,
|
|
501
|
+
path: '/webhooks/github', // POST /webhooks/github (method: 'GET' | 'POST' | 'PUT')
|
|
502
|
+
secret: process.env.GITHUB_SECRET, // HMAC X-Hub-Signature-256 over the raw body
|
|
523
503
|
buildPrompt: (body) => {
|
|
524
|
-
const pr = body.pull_request;
|
|
504
|
+
const pr = (body as { pull_request: { number: number; title: string; diff_url: string } }).pull_request;
|
|
525
505
|
return `Review PR #${pr.number}: "${pr.title}"\n${pr.diff_url}`;
|
|
526
506
|
},
|
|
527
|
-
|
|
528
|
-
onError: (err) => logger.error('[github-pr]', err),
|
|
529
|
-
})
|
|
530
|
-
.addWebhook({
|
|
531
|
-
name: 'jira-issue',
|
|
532
|
-
path: '/webhooks/jira',
|
|
533
|
-
buildPrompt: (body) => `Analyze Jira issue ${body.issue.key}: ${body.issue.fields.summary}`,
|
|
534
|
-
onResult: (out) => jira.addComment(body.issue.key, out),
|
|
507
|
+
onComplete: ({ output }) => github.comment(output),
|
|
535
508
|
});
|
|
536
509
|
```
|
|
537
510
|
|
|
538
|
-
|
|
511
|
+
The webhook answers immediately and the run continues in the background; use `onComplete` to act on the result. If the payload is needed there, capture it in `buildPrompt`.
|
|
539
512
|
|
|
540
513
|
```bash
|
|
541
514
|
curl -X POST http://localhost:3000/webhooks/github \
|
|
542
515
|
-H "Content-Type: application/json" \
|
|
543
|
-
-H "X-Hub-Signature-256: sha256=<hmac>" \
|
|
544
|
-
-d '{ "pull_request": { "number": 42, "title": "Add auth module" } }'
|
|
516
|
+
-H "X-Hub-Signature-256: sha256=<hmac of the exact body>" \
|
|
517
|
+
-d '{ "pull_request": { "number": 42, "title": "Add auth module", "diff_url": "..." } }'
|
|
545
518
|
```
|
|
546
519
|
|
|
547
520
|
### Queue trigger (BullMQ — requires `bullmq`)
|
|
548
521
|
|
|
549
522
|
```typescript
|
|
550
|
-
import { TriggerBus } from '@backendkit-labs/agent-web';
|
|
551
|
-
|
|
552
523
|
const triggers = new TriggerBus(engineFactory)
|
|
553
524
|
.addQueue({
|
|
554
525
|
name: 'document-processor',
|
|
555
|
-
queueName: 'documents',
|
|
556
|
-
connection: process.env.REDIS_URL!,
|
|
557
|
-
concurrency: 3,
|
|
558
|
-
buildPrompt: (
|
|
559
|
-
|
|
560
|
-
},
|
|
561
|
-
onResult: (out, job) => {
|
|
562
|
-
db.documents.update(job.data.id, { summary: out });
|
|
563
|
-
},
|
|
564
|
-
onError: (err, job) => {
|
|
565
|
-
logger.error(`[queue] Failed to process document ${job?.data?.id}:`, err);
|
|
566
|
-
// The error is re-thrown so BullMQ marks the job as failed and applies retry policy
|
|
567
|
-
},
|
|
526
|
+
queueName: 'documents',
|
|
527
|
+
connection: process.env.REDIS_URL!, // URL, or { host, port, password, username, db, tls }
|
|
528
|
+
concurrency: 3, // default 1
|
|
529
|
+
buildPrompt: (data) => `Summarize and extract key points:\n\n${(data as { content: string }).content}`,
|
|
530
|
+
onComplete: ({ output }) => saveSummary(output),
|
|
568
531
|
});
|
|
569
532
|
```
|
|
570
533
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
```typescript
|
|
574
|
-
import { Queue } from 'bullmq';
|
|
575
|
-
|
|
576
|
-
const queue = new Queue('documents', { connection: process.env.REDIS_URL! });
|
|
577
|
-
|
|
578
|
-
await queue.add('process-doc', {
|
|
579
|
-
id: 'doc-456',
|
|
580
|
-
content: 'Full document text...',
|
|
581
|
-
}, {
|
|
582
|
-
attempts: 3,
|
|
583
|
-
backoff: { type: 'exponential', delay: 2000 },
|
|
584
|
-
removeOnComplete: 100,
|
|
585
|
-
removeOnFail: 50,
|
|
586
|
-
});
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
### Queue connection options
|
|
590
|
-
|
|
591
|
-
```typescript
|
|
592
|
-
// URL string
|
|
593
|
-
connection: 'redis://localhost:6379'
|
|
594
|
-
connection: 'redis://:password@redis-host:6380/1'
|
|
595
|
-
|
|
596
|
-
// Connection object
|
|
597
|
-
connection: {
|
|
598
|
-
host: 'redis-host',
|
|
599
|
-
port: 6380,
|
|
600
|
-
password: 'mypassword',
|
|
601
|
-
username: 'default',
|
|
602
|
-
db: 1,
|
|
603
|
-
tls: {}, // enable TLS
|
|
604
|
-
}
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
### CronTriggerDef with all options
|
|
608
|
-
|
|
609
|
-
```typescript
|
|
610
|
-
interface CronTriggerDef {
|
|
611
|
-
name: string; // unique name for the trigger
|
|
612
|
-
schedule: string; // standard cron expression
|
|
613
|
-
buildPrompt: (ts: Date) => string; // returns the prompt to run
|
|
614
|
-
agentId?: string; // override default agent
|
|
615
|
-
runOnStart?: boolean; // fire immediately on server start
|
|
616
|
-
onResult?: (output: string) => void;
|
|
617
|
-
onError?: (err: Error) => void;
|
|
618
|
-
}
|
|
619
|
-
```
|
|
534
|
+
A failed run is rethrown to BullMQ, so the job is marked failed and its retry policy applies. Jobs are published with BullMQ as usual (`new Queue('documents', { connection }).add('process', { id, content }, { attempts: 3 })`).
|
|
620
535
|
|
|
621
536
|
---
|
|
622
537
|
|
|
623
538
|
## HeadlessTransport
|
|
624
539
|
|
|
625
|
-
`
|
|
540
|
+
A `Transport` with no socket: it buffers every `AgentEvent` in memory. `TriggerBus` uses it for autonomous runs; use it to run an engine from a script.
|
|
626
541
|
|
|
627
542
|
```typescript
|
|
628
543
|
import { HeadlessTransport } from '@backendkit-labs/agent-web';
|
|
629
544
|
|
|
630
545
|
const transport = new HeadlessTransport();
|
|
631
|
-
|
|
632
546
|
const engine = new AgentEngine({ ...opts, transport });
|
|
633
547
|
await engine.run('Generate a daily report');
|
|
634
548
|
|
|
635
|
-
//
|
|
636
|
-
|
|
637
|
-
const tokens = events
|
|
638
|
-
.filter(e => e.type === 'chunk')
|
|
639
|
-
.map(e => e.content)
|
|
640
|
-
.join('');
|
|
641
|
-
|
|
642
|
-
console.log('Final output:', tokens);
|
|
549
|
+
transport.getOutput(); // concatenated text of the 'token' events
|
|
550
|
+
transport.getEvents(); // every event, in order
|
|
643
551
|
```
|
|
644
552
|
|
|
645
553
|
---
|
|
646
554
|
|
|
647
555
|
## Full production example
|
|
648
556
|
|
|
649
|
-
|
|
557
|
+
JWT auth, Redis sessions, Prometheus metrics, a cron job, a webhook and a queue:
|
|
650
558
|
|
|
651
559
|
```typescript
|
|
652
560
|
import { AgentServer, JwtAuth, TriggerBus, RedisSessionMetaStore } from '@backendkit-labs/agent-web';
|
|
653
561
|
import { createEnterpriseSetup } from '@backendkit-labs/agent-enterprise';
|
|
654
|
-
import { ProviderRegistry
|
|
562
|
+
import { ProviderRegistry } from '@backendkit-labs/agent-core';
|
|
563
|
+
import { DeepSeekProvider } from '@backendkit-labs/agent-providers';
|
|
655
564
|
import Redis from 'ioredis';
|
|
656
565
|
|
|
657
|
-
// LLM providers
|
|
658
566
|
const providers = new ProviderRegistry();
|
|
659
|
-
providers.register('deepseek', new DeepSeekProvider({
|
|
660
|
-
apiKey: process.env.DEEPSEEK_API_KEY!,
|
|
661
|
-
model: 'deepseek-chat',
|
|
662
|
-
}));
|
|
663
|
-
|
|
664
|
-
// Enterprise setup (RAG + 6 agent profiles)
|
|
665
|
-
const enterprise = createEnterpriseSetup({
|
|
666
|
-
vaultPath: process.env.VAULT_PATH!,
|
|
667
|
-
providers,
|
|
668
|
-
defaultProvider: 'deepseek',
|
|
669
|
-
});
|
|
670
|
-
await enterprise.indexAll();
|
|
567
|
+
providers.register('deepseek', new DeepSeekProvider({ apiKey: process.env.DEEPSEEK_API_KEY!, model: 'deepseek-chat' }));
|
|
671
568
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
// JWT auth
|
|
676
|
-
const jwt = new JwtAuth({
|
|
677
|
-
secret: process.env.JWT_SECRET!,
|
|
678
|
-
sessionIdClaim: 'sub',
|
|
679
|
-
});
|
|
569
|
+
const enterprise = createEnterpriseSetup({ vaultPath: process.env.VAULT_PATH!, providers, defaultProvider: 'deepseek' });
|
|
570
|
+
await enterprise.indexAll();
|
|
680
571
|
|
|
681
|
-
// Autonomous triggers
|
|
682
572
|
const triggers = new TriggerBus(enterprise.engineFactory)
|
|
683
573
|
.addCron({
|
|
684
574
|
name: 'weekly-digest',
|
|
685
|
-
schedule: '0 9 * * 1',
|
|
575
|
+
schedule: '0 9 * * 1',
|
|
686
576
|
buildPrompt: () => 'Generate a weekly digest of all knowledge base changes.',
|
|
687
|
-
|
|
577
|
+
onComplete: ({ output }) => slack.send('#general', output),
|
|
688
578
|
})
|
|
689
579
|
.addWebhook({
|
|
690
580
|
name: 'support-ticket',
|
|
691
581
|
path: '/webhooks/support',
|
|
692
582
|
secret: process.env.WEBHOOK_SECRET,
|
|
693
|
-
buildPrompt: (body) =>
|
|
694
|
-
|
|
583
|
+
buildPrompt: (body) => {
|
|
584
|
+
const t = body as { id: string; subject: string; description: string };
|
|
585
|
+
return `Handle support ticket #${t.id}: ${t.subject}\n${t.description}`;
|
|
586
|
+
},
|
|
695
587
|
})
|
|
696
588
|
.addQueue({
|
|
697
589
|
name: 'email-processor',
|
|
698
590
|
queueName: 'emails',
|
|
699
591
|
connection: process.env.REDIS_URL!,
|
|
700
592
|
concurrency: 5,
|
|
701
|
-
buildPrompt: (
|
|
702
|
-
onResult: (out, job) => emailService.send({ to: job.data.from, body: out }),
|
|
593
|
+
buildPrompt: (data) => `Draft a professional reply to this email:\n\n${(data as { body: string }).body}`,
|
|
703
594
|
});
|
|
704
595
|
|
|
705
|
-
// Server
|
|
706
596
|
const server = new AgentServer({
|
|
707
597
|
port: 3000,
|
|
598
|
+
host: '0.0.0.0',
|
|
708
599
|
engineFactory: enterprise.engineFactory,
|
|
709
|
-
auth:
|
|
710
|
-
|
|
600
|
+
auth: new JwtAuth({ secret: process.env.JWT_SECRET!, allowQueryToken: false }).hook(),
|
|
601
|
+
strict: true,
|
|
602
|
+
store: new RedisSessionMetaStore(new Redis(process.env.REDIS_URL!)),
|
|
711
603
|
cors: ['https://app.company.com'],
|
|
712
604
|
logger: { level: 'info' },
|
|
713
605
|
rateLimiting: { max: 60, timeWindow: '1 minute' },
|
|
714
|
-
metrics: { enabled: true
|
|
606
|
+
metrics: { enabled: true },
|
|
715
607
|
maxIdleMs: 30 * 60 * 1000,
|
|
716
608
|
triggers,
|
|
717
609
|
});
|
|
718
610
|
|
|
719
611
|
await server.start();
|
|
720
|
-
console.log('Agent server running on :3000');
|
|
721
|
-
|
|
722
|
-
// Graceful shutdown
|
|
723
612
|
process.on('SIGTERM', () => server.stop());
|
|
724
613
|
```
|
package/package.json
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@backendkit-labs/agent-web",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "HTTP/WebSocket server layer for agent-core — browser-ready streaming agent sessions",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist/",
|
|
9
|
-
"client/",
|
|
10
|
-
"README.md"
|
|
11
|
-
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "tsc",
|
|
14
|
-
"dev": "tsc --watch",
|
|
15
|
-
"typecheck": "tsc --noEmit",
|
|
16
|
-
"test": "jest",
|
|
17
|
-
"prepublishOnly": "npm run build"
|
|
18
|
-
},
|
|
19
|
-
"peerDependencies": {
|
|
20
|
-
"@backendkit-labs/agent-core": ">=0.24.0 <0.
|
|
21
|
-
},
|
|
22
|
-
"dependencies": {
|
|
23
|
-
"@fastify/websocket": "^11.0.0",
|
|
24
|
-
"fastify": "^5.0.0",
|
|
25
|
-
"jsonwebtoken": "^9.0.0",
|
|
26
|
-
"prom-client": "^15.0.0"
|
|
27
|
-
},
|
|
28
|
-
"optionalDependencies": {
|
|
29
|
-
"@fastify/rate-limit": "^9.0.0",
|
|
30
|
-
"bullmq": "^5.0.0",
|
|
31
|
-
"node-cron": "^4.2.1"
|
|
32
|
-
},
|
|
33
|
-
"devDependencies": {
|
|
34
|
-
"@backendkit-labs/agent-core": "^0.
|
|
35
|
-
"@types/jest": "^29.5.14",
|
|
36
|
-
"@types/jsonwebtoken": "^9.0.0",
|
|
37
|
-
"@types/node": "^20.0.0",
|
|
38
|
-
"@types/ws": "^8.0.0",
|
|
39
|
-
"bullmq": "^5.0.0",
|
|
40
|
-
"jest": "^29.7.0",
|
|
41
|
-
"ts-jest": "^29.4.11",
|
|
42
|
-
"typescript": "^5.4.0",
|
|
43
|
-
"ws": "^8.21.0"
|
|
44
|
-
},
|
|
45
|
-
"engines": {
|
|
46
|
-
"node": ">=20.0.0"
|
|
47
|
-
},
|
|
48
|
-
"publishConfig": {
|
|
49
|
-
"access": "public"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@backendkit-labs/agent-web",
|
|
3
|
+
"version": "0.6.6",
|
|
4
|
+
"description": "HTTP/WebSocket server layer for agent-core — browser-ready streaming agent sessions",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/",
|
|
9
|
+
"client/",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"dev": "tsc --watch",
|
|
15
|
+
"typecheck": "tsc --noEmit",
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@backendkit-labs/agent-core": ">=0.24.0 <0.41.0"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@fastify/websocket": "^11.0.0",
|
|
24
|
+
"fastify": "^5.0.0",
|
|
25
|
+
"jsonwebtoken": "^9.0.0",
|
|
26
|
+
"prom-client": "^15.0.0"
|
|
27
|
+
},
|
|
28
|
+
"optionalDependencies": {
|
|
29
|
+
"@fastify/rate-limit": "^9.0.0",
|
|
30
|
+
"bullmq": "^5.0.0",
|
|
31
|
+
"node-cron": "^4.2.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@backendkit-labs/agent-core": "^0.39.0",
|
|
35
|
+
"@types/jest": "^29.5.14",
|
|
36
|
+
"@types/jsonwebtoken": "^9.0.0",
|
|
37
|
+
"@types/node": "^20.0.0",
|
|
38
|
+
"@types/ws": "^8.0.0",
|
|
39
|
+
"bullmq": "^5.0.0",
|
|
40
|
+
"jest": "^29.7.0",
|
|
41
|
+
"ts-jest": "^29.4.11",
|
|
42
|
+
"typescript": "^5.4.0",
|
|
43
|
+
"ws": "^8.21.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.0.0"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|