@lantanios/agentic-server 0.2.0 → 0.2.2
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 +300 -13
- package/package.json +42 -42
package/README.md
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
# @lantanios/agentic-server
|
|
2
2
|
|
|
3
|
-
Real-time Socket.IO server combining memory, audio,
|
|
3
|
+
Real-time Socket.IO server combining memory, audio, event communication, context assembly, and cache synchronization for AI agents.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
7
|
+
- **Socket.IO namespaces** — Separate channels for memory, audio, events, context, and sync
|
|
8
|
+
- **Memory namespace** — CRUD + vector search via WebSocket
|
|
9
|
+
- **Audio namespace** — Real-time STT/TTS streaming
|
|
10
|
+
- **Events namespace** — Pub/sub, broadcast, direct messaging between agents
|
|
11
|
+
- **Context namespace** — Context assembly, hybrid recall, goal tracking, and conversation summarization
|
|
12
|
+
- **Sync namespace** — Redis-backed cache synchronization for offline-first memory access
|
|
13
|
+
- **Priority providers** — Local-first audio with cloud fallback
|
|
14
|
+
- **Redis integration** — Pub/sub and caching layer for sync operations
|
|
12
15
|
|
|
13
16
|
## Installation
|
|
14
17
|
|
|
@@ -28,6 +31,9 @@ CORS_ORIGINS=http://localhost:3000,http://localhost:5173
|
|
|
28
31
|
# MongoDB (required)
|
|
29
32
|
MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/Agentic
|
|
30
33
|
|
|
34
|
+
# Redis (required for /sync namespace, optional otherwise)
|
|
35
|
+
REDIS_URL=redis://localhost:6379
|
|
36
|
+
|
|
31
37
|
# OpenAI (required for embeddings, optional for TTS)
|
|
32
38
|
OPENAI_API_KEY=sk-...
|
|
33
39
|
|
|
@@ -70,6 +76,16 @@ const audio = io('http://localhost:3847/audio', {
|
|
|
70
76
|
const events = io('http://localhost:3847/events', {
|
|
71
77
|
auth: { agentId: 'pip' }
|
|
72
78
|
});
|
|
79
|
+
|
|
80
|
+
// Connect to context namespace
|
|
81
|
+
const context = io('http://localhost:3847/context', {
|
|
82
|
+
auth: { agentId: 'pip' }
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Connect to sync namespace
|
|
86
|
+
const sync = io('http://localhost:3847/sync', {
|
|
87
|
+
auth: { agentId: 'pip' }
|
|
88
|
+
});
|
|
73
89
|
```
|
|
74
90
|
|
|
75
91
|
## Socket.IO Namespaces
|
|
@@ -302,6 +318,232 @@ events.emit('agents:list', (response) => {
|
|
|
302
318
|
});
|
|
303
319
|
```
|
|
304
320
|
|
|
321
|
+
### `/context` — Context Assembly & Goals
|
|
322
|
+
|
|
323
|
+
Handles context window management, hybrid recall across memories and summaries, conversation compression, and goal tracking. All operations require `agentId` in auth.
|
|
324
|
+
|
|
325
|
+
#### Search Memories (Atlas Vector Search)
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
context.emit('search:memories', {
|
|
329
|
+
query: 'user preferences for the dashboard',
|
|
330
|
+
limit: 10,
|
|
331
|
+
minScore: 0.7,
|
|
332
|
+
}, (response) => {
|
|
333
|
+
if (response.success) {
|
|
334
|
+
response.results.forEach(r => {
|
|
335
|
+
console.log(`${r.score.toFixed(2)}: ${r.content}`);
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### Search Summaries (Atlas Vector Search)
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
context.emit('search:summaries', {
|
|
345
|
+
query: 'previous discussions about deployment',
|
|
346
|
+
limit: 5,
|
|
347
|
+
minScore: 0.6,
|
|
348
|
+
}, (response) => {
|
|
349
|
+
if (response.success) {
|
|
350
|
+
response.results.forEach(r => {
|
|
351
|
+
console.log(`${r.score.toFixed(2)}: ${r.summary}`);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### Hybrid Recall
|
|
358
|
+
|
|
359
|
+
Combines important memories, recent memories, semantic search results, and summaries into a single ranked context payload.
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
context.emit('recall', {
|
|
363
|
+
query: 'What has the user said about the API redesign?',
|
|
364
|
+
sessionId: 'session-abc-123',
|
|
365
|
+
limit: 30,
|
|
366
|
+
}, (response) => {
|
|
367
|
+
if (response.success) {
|
|
368
|
+
console.log('Important:', response.breakdown.important);
|
|
369
|
+
console.log('Recent:', response.breakdown.recent);
|
|
370
|
+
console.log('Semantic:', response.breakdown.semantic);
|
|
371
|
+
console.log('Summaries:', response.breakdown.summaries);
|
|
372
|
+
console.log('Combined memories:', response.memories);
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
#### Compress & Store Summary
|
|
378
|
+
|
|
379
|
+
Stores a conversation summary along with extracted facts for future recall.
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
context.emit('compress:store', {
|
|
383
|
+
sessionId: 'session-abc-123',
|
|
384
|
+
summary: 'User discussed API redesign. Decided on REST over GraphQL. Key concern: backwards compatibility.',
|
|
385
|
+
facts: [
|
|
386
|
+
{ content: 'User chose REST over GraphQL for API redesign', type: 'decision', importance: 5 },
|
|
387
|
+
{ content: 'Backwards compatibility is a key concern', type: 'fact', importance: 4 },
|
|
388
|
+
],
|
|
389
|
+
tokensSaved: 1200,
|
|
390
|
+
}, (response) => {
|
|
391
|
+
if (response.success) {
|
|
392
|
+
console.log('Summary stored:', response.summaryId);
|
|
393
|
+
console.log('Facts created:', response.factsCreated);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### Get Context State
|
|
399
|
+
|
|
400
|
+
Retrieve the current context window state for a session (tokens used, model, window size).
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
context.emit('state:get', {
|
|
404
|
+
sessionId: 'session-abc-123',
|
|
405
|
+
}, (response) => {
|
|
406
|
+
if (response.success) {
|
|
407
|
+
console.log('Tokens used:', response.state.tokensUsed);
|
|
408
|
+
console.log('Context window:', response.state.contextWindow);
|
|
409
|
+
console.log('Model:', response.state.model);
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
#### Update Context State
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
context.emit('state:update', {
|
|
418
|
+
sessionId: 'session-abc-123',
|
|
419
|
+
tokensUsed: 14500,
|
|
420
|
+
model: 'claude-opus-4-6',
|
|
421
|
+
contextWindow: 200000,
|
|
422
|
+
}, (response) => {
|
|
423
|
+
if (response.success) {
|
|
424
|
+
console.log('State updated');
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### Get Goals
|
|
430
|
+
|
|
431
|
+
Retrieve active, blocked, or filtered goals for the agent.
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
context.emit('goals:get', {
|
|
435
|
+
status: 'active', // optional: 'active' | 'blocked' | 'completed' | 'abandoned'
|
|
436
|
+
priority: 'high', // optional: 'low' | 'medium' | 'high' | 'critical'
|
|
437
|
+
limit: 20,
|
|
438
|
+
}, (response) => {
|
|
439
|
+
if (response.success) {
|
|
440
|
+
response.goals.forEach(g => {
|
|
441
|
+
console.log(`[${g.priority}] ${g.description} — ${g.status}`);
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
#### Update Goal
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
context.emit('goals:update', {
|
|
451
|
+
goalId: 'goal-xyz-789',
|
|
452
|
+
status: 'completed',
|
|
453
|
+
description: 'Finish API redesign proposal', // optional
|
|
454
|
+
priority: 'high', // optional
|
|
455
|
+
}, (response) => {
|
|
456
|
+
if (response.success) {
|
|
457
|
+
console.log('Goal updated:', response.goal);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
#### Create Goal
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
context.emit('goals:create', {
|
|
466
|
+
description: 'Implement Redis caching layer for sync namespace',
|
|
467
|
+
priority: 'high',
|
|
468
|
+
status: 'active',
|
|
469
|
+
metadata: {
|
|
470
|
+
project: 'agentic-server',
|
|
471
|
+
tags: ['infrastructure', 'performance'],
|
|
472
|
+
},
|
|
473
|
+
}, (response) => {
|
|
474
|
+
if (response.success) {
|
|
475
|
+
console.log('Goal created:', response.goal.id);
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### `/sync` — Cache Synchronization
|
|
481
|
+
|
|
482
|
+
Enables offline-first memory access with Redis-backed cache synchronization. Agents can pull recently updated memories, push locally-created ones, and check sync state. Requires Redis (`REDIS_URL` env var).
|
|
483
|
+
|
|
484
|
+
#### Pull Updates
|
|
485
|
+
|
|
486
|
+
Fetch memories that have been updated since a given timestamp, for local cache hydration.
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
sync.emit('sync:pull', {
|
|
490
|
+
since: '2026-02-05T00:00:00.000Z', // ISO timestamp
|
|
491
|
+
limit: 100,
|
|
492
|
+
}, (response) => {
|
|
493
|
+
if (response.success) {
|
|
494
|
+
console.log(`Pulled ${response.memories.length} updated memories`);
|
|
495
|
+
console.log('Server timestamp:', response.serverTimestamp);
|
|
496
|
+
// Store response.serverTimestamp for next pull
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
#### Push Local Memories
|
|
502
|
+
|
|
503
|
+
Push memories created locally (while offline or in a local cache) up to MongoDB.
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
sync.emit('sync:push', {
|
|
507
|
+
memories: [
|
|
508
|
+
{
|
|
509
|
+
localId: 'local-001',
|
|
510
|
+
type: 'fact',
|
|
511
|
+
content: 'User mentioned they use VS Code',
|
|
512
|
+
metadata: { importance: 3, tags: ['tools'] },
|
|
513
|
+
createdAt: '2026-02-05T12:30:00.000Z',
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
localId: 'local-002',
|
|
517
|
+
type: 'conversation',
|
|
518
|
+
content: 'Discussed project timelines for Q2',
|
|
519
|
+
metadata: { importance: 4, tags: ['planning'] },
|
|
520
|
+
createdAt: '2026-02-05T12:35:00.000Z',
|
|
521
|
+
},
|
|
522
|
+
],
|
|
523
|
+
}, (response) => {
|
|
524
|
+
if (response.success) {
|
|
525
|
+
console.log(`Pushed ${response.created} memories`);
|
|
526
|
+
// response.mapping: { 'local-001': 'mongo-id-abc', 'local-002': 'mongo-id-def' }
|
|
527
|
+
console.log('ID mapping:', response.mapping);
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
#### Sync Status
|
|
533
|
+
|
|
534
|
+
Check the current sync state for the agent, including last sync time and pending counts.
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
sync.emit('sync:status', (response) => {
|
|
538
|
+
if (response.success) {
|
|
539
|
+
console.log('Last pull:', response.status.lastPull);
|
|
540
|
+
console.log('Last push:', response.status.lastPush);
|
|
541
|
+
console.log('Pending pushes:', response.status.pendingPushes);
|
|
542
|
+
console.log('Server behind by:', response.status.serverDelta, 'records');
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
```
|
|
546
|
+
|
|
305
547
|
## REST Endpoints
|
|
306
548
|
|
|
307
549
|
| Method | Path | Description |
|
|
@@ -321,13 +563,20 @@ curl http://localhost:3847/providers
|
|
|
321
563
|
|
|
322
564
|
```
|
|
323
565
|
Client (Browser/Node)
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
566
|
+
|
|
|
567
|
+
|--- Socket.IO ------> /memory -------> MongoDB + OpenAI Embeddings
|
|
568
|
+
|
|
|
569
|
+
|--- Socket.IO ------> /audio -------> Local Whisper/Piper
|
|
570
|
+
| +---> Deepgram/OpenAI (fallback)
|
|
571
|
+
|
|
|
572
|
+
|--- Socket.IO ------> /events -------> Pub/Sub (in-memory)
|
|
573
|
+
|
|
|
574
|
+
|--- Socket.IO ------> /context -------> MongoDB Atlas Vector Search
|
|
575
|
+
| +---> Goals collection
|
|
576
|
+
| +---> Summaries collection
|
|
577
|
+
|
|
|
578
|
+
+--- Socket.IO ------> /sync -------> Redis (cache + pub/sub)
|
|
579
|
+
+---> MongoDB (persistence)
|
|
331
580
|
```
|
|
332
581
|
|
|
333
582
|
## Example: Full Agent Connection
|
|
@@ -339,6 +588,8 @@ class AgentClient {
|
|
|
339
588
|
private memory;
|
|
340
589
|
private audio;
|
|
341
590
|
private events;
|
|
591
|
+
private context;
|
|
592
|
+
private sync;
|
|
342
593
|
|
|
343
594
|
constructor(serverUrl: string, agentId: string) {
|
|
344
595
|
const auth = { agentId };
|
|
@@ -346,6 +597,8 @@ class AgentClient {
|
|
|
346
597
|
this.memory = io(`${serverUrl}/memory`, { auth });
|
|
347
598
|
this.audio = io(`${serverUrl}/audio`, { auth });
|
|
348
599
|
this.events = io(`${serverUrl}/events`, { auth });
|
|
600
|
+
this.context = io(`${serverUrl}/context`, { auth });
|
|
601
|
+
this.sync = io(`${serverUrl}/sync`, { auth });
|
|
349
602
|
|
|
350
603
|
// Subscribe to relevant channels
|
|
351
604
|
this.events.emit('subscribe', 'system');
|
|
@@ -365,6 +618,36 @@ class AgentClient {
|
|
|
365
618
|
});
|
|
366
619
|
}
|
|
367
620
|
|
|
621
|
+
async recall(query: string, sessionId: string) {
|
|
622
|
+
return new Promise((resolve) => {
|
|
623
|
+
this.context.emit('recall', { query, sessionId, limit: 30 }, resolve);
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
async getGoals(status = 'active') {
|
|
628
|
+
return new Promise((resolve) => {
|
|
629
|
+
this.context.emit('goals:get', { status }, resolve);
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
async createGoal(description: string, priority = 'medium') {
|
|
634
|
+
return new Promise((resolve) => {
|
|
635
|
+
this.context.emit('goals:create', { description, priority, status: 'active' }, resolve);
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
async syncPull(since: string) {
|
|
640
|
+
return new Promise((resolve) => {
|
|
641
|
+
this.sync.emit('sync:pull', { since }, resolve);
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
async syncPush(memories: any[]) {
|
|
646
|
+
return new Promise((resolve) => {
|
|
647
|
+
this.sync.emit('sync:push', { memories }, resolve);
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
|
|
368
651
|
async transcribe(audioBuffer: Buffer) {
|
|
369
652
|
return new Promise((resolve) => {
|
|
370
653
|
this.audio.emit('transcribe', { audio: audioBuffer }, resolve);
|
|
@@ -390,6 +673,10 @@ class AgentClient {
|
|
|
390
673
|
const agent = new AgentClient('http://localhost:3847', 'pip');
|
|
391
674
|
await agent.remember('User asked about weather', 'conversation', 2);
|
|
392
675
|
const results = await agent.search('weather conversations');
|
|
676
|
+
const context = await agent.recall('weather conversations', 'session-001');
|
|
677
|
+
const goals = await agent.getGoals('active');
|
|
678
|
+
await agent.createGoal('Investigate weather API options', 'high');
|
|
679
|
+
await agent.syncPull('2026-02-05T00:00:00.000Z');
|
|
393
680
|
```
|
|
394
681
|
|
|
395
682
|
## License
|
package/package.json
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@lantanios/agentic-server",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Real-time server with Socket.IO for memory and audio streaming",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"@lantanios/agentic-audio": "
|
|
27
|
-
"@lantanios/agentic-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@lantanios/agentic-server",
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Real-time server with Socket.IO for memory and audio streaming",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "ts-node-dev --respawn src/index.ts",
|
|
10
|
+
"start": "node dist/index.js",
|
|
11
|
+
"lint": "eslint src --ext .ts"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"socket.io",
|
|
15
|
+
"realtime",
|
|
16
|
+
"audio",
|
|
17
|
+
"memory",
|
|
18
|
+
"ai"
|
|
19
|
+
],
|
|
20
|
+
"author": "Lantanios",
|
|
21
|
+
"license": "UNLICENSED",
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "restricted"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@lantanios/agentic-audio": "workspace:*",
|
|
27
|
+
"@lantanios/agentic-memory": "workspace:*",
|
|
28
|
+
"@lantanios/agentic-redis": "workspace:*",
|
|
29
|
+
"cors": "^2.8.5",
|
|
30
|
+
"dotenv": "^16.0.0",
|
|
31
|
+
"express": "^4.18.0",
|
|
32
|
+
"mongoose": "^8.0.0",
|
|
33
|
+
"socket.io": "^4.7.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/cors": "^2.8.0",
|
|
37
|
+
"@types/express": "^4.17.0",
|
|
38
|
+
"@types/node": "^20.0.0",
|
|
39
|
+
"ts-node-dev": "^2.0.0",
|
|
40
|
+
"typescript": "^5.0.0"
|
|
41
|
+
}
|
|
42
|
+
}
|