@lantanios/agentic-server 0.1.0 → 0.1.1
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 +397 -0
- package/package.json +8 -2
package/README.md
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# @lantanios/agentic-server
|
|
2
|
+
|
|
3
|
+
Real-time Socket.IO server combining memory, audio, and event communication for AI agents.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔌 **Socket.IO namespaces** — Separate channels for memory, audio, events
|
|
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
|
+
- 🔄 **Priority providers** — Local-first audio with cloud fallback
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @lantanios/agentic-server
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Configuration
|
|
20
|
+
|
|
21
|
+
Create `.env`:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Server
|
|
25
|
+
PORT=3847
|
|
26
|
+
CORS_ORIGINS=http://localhost:3000,http://localhost:5173
|
|
27
|
+
|
|
28
|
+
# MongoDB (required)
|
|
29
|
+
MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/Agentic
|
|
30
|
+
|
|
31
|
+
# OpenAI (required for embeddings, optional for TTS)
|
|
32
|
+
OPENAI_API_KEY=sk-...
|
|
33
|
+
|
|
34
|
+
# Local audio server (optional, for local STT/TTS)
|
|
35
|
+
LOCAL_STT_ENDPOINT=http://localhost:8001
|
|
36
|
+
LOCAL_TTS_ENDPOINT=http://localhost:8001
|
|
37
|
+
|
|
38
|
+
# Cloud fallbacks (optional)
|
|
39
|
+
DEEPGRAM_API_KEY=...
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
### Run the Server
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Using npx
|
|
48
|
+
npx @lantanios/agentic-server
|
|
49
|
+
|
|
50
|
+
# Or in code
|
|
51
|
+
import '@lantanios/agentic-server';
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Connect from Client
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { io } from 'socket.io-client';
|
|
58
|
+
|
|
59
|
+
// Connect to memory namespace
|
|
60
|
+
const memory = io('http://localhost:3847/memory', {
|
|
61
|
+
auth: { agentId: 'pip' } // Required: your agent ID
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Connect to audio namespace
|
|
65
|
+
const audio = io('http://localhost:3847/audio', {
|
|
66
|
+
auth: { agentId: 'pip' }
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Connect to events namespace
|
|
70
|
+
const events = io('http://localhost:3847/events', {
|
|
71
|
+
auth: { agentId: 'pip' }
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Socket.IO Namespaces
|
|
76
|
+
|
|
77
|
+
### `/memory` — Memory Operations
|
|
78
|
+
|
|
79
|
+
All operations require `agentId` in auth. Agents can only access their own memories.
|
|
80
|
+
|
|
81
|
+
#### Create Memory
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
memory.emit('create', {
|
|
85
|
+
type: 'fact',
|
|
86
|
+
content: 'User prefers dark mode',
|
|
87
|
+
metadata: {
|
|
88
|
+
importance: 4,
|
|
89
|
+
tags: ['preferences', 'ui'],
|
|
90
|
+
project: 'settings',
|
|
91
|
+
}
|
|
92
|
+
}, (response) => {
|
|
93
|
+
if (response.success) {
|
|
94
|
+
console.log('Created:', response.memory);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### List Memories
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
memory.emit('list', {
|
|
103
|
+
type: 'fact', // optional filter
|
|
104
|
+
project: 'settings', // optional filter
|
|
105
|
+
minImportance: 3, // optional filter
|
|
106
|
+
limit: 20,
|
|
107
|
+
offset: 0,
|
|
108
|
+
}, (response) => {
|
|
109
|
+
console.log(response.memories);
|
|
110
|
+
console.log(`Total: ${response.total}`);
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Vector Search
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
memory.emit('search', {
|
|
118
|
+
query: 'what are the user preferences?',
|
|
119
|
+
limit: 10,
|
|
120
|
+
minScore: 0.7,
|
|
121
|
+
}, (response) => {
|
|
122
|
+
response.results.forEach(r => {
|
|
123
|
+
console.log(`${r.score.toFixed(2)}: ${r.content}`);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Recall Context
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
memory.emit('recall', {
|
|
132
|
+
context: 'Starting work on the Lantanios project',
|
|
133
|
+
limit: 30,
|
|
134
|
+
}, (response) => {
|
|
135
|
+
console.log('Important:', response.breakdown.important);
|
|
136
|
+
console.log('Context-matched:', response.breakdown.contextMatched);
|
|
137
|
+
console.log('Recent:', response.breakdown.recent);
|
|
138
|
+
console.log('Memories:', response.memories);
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Other Operations
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Get single memory
|
|
146
|
+
memory.emit('get', memoryId, callback);
|
|
147
|
+
|
|
148
|
+
// Update memory
|
|
149
|
+
memory.emit('update', { id: memoryId, content: 'Updated content' }, callback);
|
|
150
|
+
|
|
151
|
+
// Delete memory (soft delete)
|
|
152
|
+
memory.emit('delete', memoryId, callback);
|
|
153
|
+
|
|
154
|
+
// Get summary stats
|
|
155
|
+
memory.emit('summary', (response) => {
|
|
156
|
+
console.log(response.summary);
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### `/audio` — Audio Streaming
|
|
161
|
+
|
|
162
|
+
#### Stream Recording
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Start recording
|
|
166
|
+
audio.emit('stream:start', {}, (response) => {
|
|
167
|
+
console.log('Recording started');
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Send audio chunks (from microphone)
|
|
171
|
+
mediaRecorder.ondataavailable = (e) => {
|
|
172
|
+
audio.emit('stream:chunk', e.data);
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Stop and get transcription
|
|
176
|
+
audio.emit('stream:stop', { language: 'en' }, (response) => {
|
|
177
|
+
if (response.success) {
|
|
178
|
+
console.log('Transcript:', response.result.text);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Also emitted as event
|
|
183
|
+
audio.on('transcription', (result) => {
|
|
184
|
+
console.log('Transcript:', result.text);
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### One-shot Transcription
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
audio.emit('transcribe', {
|
|
192
|
+
audio: audioBuffer, // Buffer or ArrayBuffer
|
|
193
|
+
language: 'en',
|
|
194
|
+
provider: 'local-whisper', // optional: force provider
|
|
195
|
+
}, (response) => {
|
|
196
|
+
console.log(response.result.text);
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### Text to Speech
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// One-shot TTS
|
|
204
|
+
audio.emit('speak', {
|
|
205
|
+
text: 'Hello, how can I help you?',
|
|
206
|
+
voice: 'nova',
|
|
207
|
+
speed: 1.0,
|
|
208
|
+
format: 'mp3',
|
|
209
|
+
}, (response) => {
|
|
210
|
+
if (response.success) {
|
|
211
|
+
playAudio(response.audio); // Buffer
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Streaming TTS
|
|
216
|
+
audio.emit('speak:stream', {
|
|
217
|
+
text: 'This is a long response that will be streamed...',
|
|
218
|
+
voice: 'nova',
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
audio.on('speak:start', () => console.log('TTS started'));
|
|
222
|
+
audio.on('speak:chunk', (chunk) => streamToSpeaker(chunk));
|
|
223
|
+
audio.on('speak:end', () => console.log('TTS finished'));
|
|
224
|
+
audio.on('speak:error', (err) => console.error(err));
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Check Providers
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
audio.emit('providers:status', (response) => {
|
|
231
|
+
console.log(response.status);
|
|
232
|
+
// { stt: { 'local-whisper': true }, tts: { 'local-piper': false, 'openai-tts': true } }
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### `/events` — Agent Communication
|
|
237
|
+
|
|
238
|
+
#### Subscribe to Channels
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
events.emit('subscribe', 'project-updates', (response) => {
|
|
242
|
+
console.log(`Subscribed to ${response.channel}`);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
events.emit('unsubscribe', 'project-updates', callback);
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### Publish to Channel
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
events.emit('publish', {
|
|
252
|
+
channel: 'project-updates',
|
|
253
|
+
event: 'task-completed',
|
|
254
|
+
payload: { taskId: '123', status: 'done' },
|
|
255
|
+
}, (response) => {
|
|
256
|
+
console.log(`Delivered to ${response.delivered} subscribers`);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Receive events
|
|
260
|
+
events.on('event', (data) => {
|
|
261
|
+
console.log(`[${data.channel}] ${data.event} from ${data.from}:`, data.payload);
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
#### Broadcast to All Agents
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
events.emit('broadcast', {
|
|
269
|
+
event: 'system-alert',
|
|
270
|
+
payload: { message: 'Server restarting in 5 minutes' },
|
|
271
|
+
}, (response) => {
|
|
272
|
+
console.log(`Broadcast to ${response.delivered} agents`);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
events.on('broadcast', (data) => {
|
|
276
|
+
console.log(`Broadcast from ${data.from}:`, data.event, data.payload);
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### Direct Message
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
events.emit('dm', {
|
|
284
|
+
to: 'deep', // Target agent ID
|
|
285
|
+
event: 'private-message',
|
|
286
|
+
payload: { text: 'Hey Deep, can you check the Lantanios logs?' },
|
|
287
|
+
}, (response) => {
|
|
288
|
+
console.log(response.delivered ? 'Delivered' : 'Agent not online');
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
events.on('dm', (data) => {
|
|
292
|
+
console.log(`DM from ${data.from}:`, data.event, data.payload);
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### List Online Agents
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
events.emit('agents:list', (response) => {
|
|
300
|
+
console.log('Online agents:', response.agents);
|
|
301
|
+
// ['pip', 'deep']
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## REST Endpoints
|
|
306
|
+
|
|
307
|
+
| Method | Path | Description |
|
|
308
|
+
|--------|------|-------------|
|
|
309
|
+
| `GET` | `/health` | Health check with MongoDB and socket status |
|
|
310
|
+
| `GET` | `/providers` | Audio provider availability |
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
curl http://localhost:3847/health
|
|
314
|
+
# { "status": "ok", "mongodb": "connected", "sockets": 2 }
|
|
315
|
+
|
|
316
|
+
curl http://localhost:3847/providers
|
|
317
|
+
# { "status": "ok", "providers": { "stt": {...}, "tts": {...} } }
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Architecture
|
|
321
|
+
|
|
322
|
+
```
|
|
323
|
+
Client (Browser/Node)
|
|
324
|
+
│
|
|
325
|
+
├── Socket.IO ─────► /memory ────► MongoDB + OpenAI Embeddings
|
|
326
|
+
│
|
|
327
|
+
├── Socket.IO ─────► /audio ────► Local Whisper/Piper
|
|
328
|
+
│ └──► Deepgram/OpenAI (fallback)
|
|
329
|
+
│
|
|
330
|
+
└── Socket.IO ─────► /events ────► Pub/Sub (in-memory)
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Example: Full Agent Connection
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
import { io } from 'socket.io-client';
|
|
337
|
+
|
|
338
|
+
class AgentClient {
|
|
339
|
+
private memory;
|
|
340
|
+
private audio;
|
|
341
|
+
private events;
|
|
342
|
+
|
|
343
|
+
constructor(serverUrl: string, agentId: string) {
|
|
344
|
+
const auth = { agentId };
|
|
345
|
+
|
|
346
|
+
this.memory = io(`${serverUrl}/memory`, { auth });
|
|
347
|
+
this.audio = io(`${serverUrl}/audio`, { auth });
|
|
348
|
+
this.events = io(`${serverUrl}/events`, { auth });
|
|
349
|
+
|
|
350
|
+
// Subscribe to relevant channels
|
|
351
|
+
this.events.emit('subscribe', 'system');
|
|
352
|
+
this.events.on('event', this.handleEvent.bind(this));
|
|
353
|
+
this.events.on('dm', this.handleDM.bind(this));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
async remember(content: string, type = 'fact', importance = 3) {
|
|
357
|
+
return new Promise((resolve) => {
|
|
358
|
+
this.memory.emit('create', { type, content, metadata: { importance } }, resolve);
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
async search(query: string) {
|
|
363
|
+
return new Promise((resolve) => {
|
|
364
|
+
this.memory.emit('search', { query, limit: 10 }, resolve);
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
async transcribe(audioBuffer: Buffer) {
|
|
369
|
+
return new Promise((resolve) => {
|
|
370
|
+
this.audio.emit('transcribe', { audio: audioBuffer }, resolve);
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async speak(text: string) {
|
|
375
|
+
return new Promise((resolve) => {
|
|
376
|
+
this.audio.emit('speak', { text }, resolve);
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private handleEvent(data) {
|
|
381
|
+
console.log(`Event from ${data.from}:`, data.event);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
private handleDM(data) {
|
|
385
|
+
console.log(`DM from ${data.from}:`, data.payload);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Usage
|
|
390
|
+
const agent = new AgentClient('http://localhost:3847', 'pip');
|
|
391
|
+
await agent.remember('User asked about weather', 'conversation', 2);
|
|
392
|
+
const results = await agent.search('weather conversations');
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## License
|
|
396
|
+
|
|
397
|
+
Private - Lantanios
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lantanios/agentic-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Real-time server with Socket.IO for memory and audio streaming",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
"start": "node dist/index.js",
|
|
11
11
|
"lint": "eslint src --ext .ts"
|
|
12
12
|
},
|
|
13
|
-
"keywords": [
|
|
13
|
+
"keywords": [
|
|
14
|
+
"socket.io",
|
|
15
|
+
"realtime",
|
|
16
|
+
"audio",
|
|
17
|
+
"memory",
|
|
18
|
+
"ai"
|
|
19
|
+
],
|
|
14
20
|
"author": "Lantanios",
|
|
15
21
|
"license": "UNLICENSED",
|
|
16
22
|
"publishConfig": {
|