@animalabs/tavern-mcpl 0.1.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.
@@ -0,0 +1,382 @@
1
+ /**
2
+ * TavernServer — the network/session layer of the Lantern & Ladle.
3
+ *
4
+ * The multi-agent network-MCPL pattern:
5
+ * - One WebSocketServer; each connection is authenticated by `?token=` and
6
+ * mapped to a stable agent id (sessions are ephemeral, identity is not).
7
+ * - One Session per live connection: initialize handshake, channels/register,
8
+ * then a message loop dispatching tools/call + channels/publish.
9
+ * - SharedCore = the game world. All mutations happen in tool handlers
10
+ * (atomic per message on Node's single thread) and persist immediately.
11
+ * - Fan-out: game events go to every ONLINE player in the room as
12
+ * channels/incoming on that room's channel; OFFLINE players in the room
13
+ * get the event queued (capped) and replayed on their next connect.
14
+ * - Persistence: world + offline queues in one JSON file (tmp+rename), so
15
+ * a server restart loses nothing.
16
+ */
17
+ import { createServer } from 'node:http';
18
+ import { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync } from 'node:fs';
19
+ import { dirname } from 'node:path';
20
+ import { WebSocketServer } from 'ws';
21
+ import { McplConnection, method, } from '@animalabs/mcpl-core';
22
+ import * as game from './game.js';
23
+ import { ROOMS } from './game.js';
24
+ function loadStore(path) {
25
+ if (existsSync(path)) {
26
+ try {
27
+ const parsed = JSON.parse(readFileSync(path, 'utf-8'));
28
+ if (parsed.world?.players && parsed.world?.roomItems) {
29
+ return { world: parsed.world, offlineQueues: parsed.offlineQueues ?? {} };
30
+ }
31
+ }
32
+ catch {
33
+ // Corrupt store: fall through to a fresh world rather than crash-looping.
34
+ }
35
+ }
36
+ return { world: game.freshWorld(), offlineQueues: {} };
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // Tool definitions (MCP shape; host namespaces them as mcpl--<id>--<name>)
40
+ // ---------------------------------------------------------------------------
41
+ const str = (description) => ({ type: 'string', description });
42
+ const TOOLS = [
43
+ { name: 'look', description: 'Look around your current room: description, exits, items, and who else is here.', inputSchema: { type: 'object', properties: {} } },
44
+ { name: 'move', description: 'Move through an exit. Directions are room-specific (see look).', inputSchema: { type: 'object', properties: { direction: str('Exit direction, e.g. "down", "up", "out", "in".') }, required: ['direction'] } },
45
+ { name: 'say', description: 'Say something aloud. Everyone in your room hears it.', inputSchema: { type: 'object', properties: { text: str('What to say.') }, required: ['text'] } },
46
+ { name: 'take', description: 'Pick up an item from the room.', inputSchema: { type: 'object', properties: { item: str('Item name as shown by look.') }, required: ['item'] } },
47
+ { name: 'drop', description: 'Set down an item you are carrying.', inputSchema: { type: 'object', properties: { item: str('Item name from your inventory.') }, required: ['item'] } },
48
+ { name: 'inventory', description: 'List what you are carrying.', inputSchema: { type: 'object', properties: {} } },
49
+ { name: 'who', description: 'List all patrons of the tavern, where they are, and who is awake.', inputSchema: { type: 'object', properties: {} } },
50
+ ];
51
+ // ---------------------------------------------------------------------------
52
+ // Server
53
+ // ---------------------------------------------------------------------------
54
+ export class TavernServer {
55
+ opts;
56
+ store;
57
+ sessions = new Map(); // agentId → live session
58
+ httpServer = null;
59
+ wss = null;
60
+ log;
61
+ constructor(opts) {
62
+ this.opts = opts;
63
+ this.store = loadStore(opts.storePath);
64
+ this.log = opts.log ?? ((line) => console.error(`[tavern-mcpl] ${line}`));
65
+ }
66
+ /** Start listening. Returns the bound port (useful with port 0). */
67
+ async start() {
68
+ const httpServer = createServer();
69
+ const wss = new WebSocketServer({ server: httpServer });
70
+ this.httpServer = httpServer;
71
+ this.wss = wss;
72
+ wss.on('connection', (ws, req) => {
73
+ const token = new URL(req.url ?? '/', 'http://localhost').searchParams.get('token');
74
+ const auth = token ? this.opts.tokens[token] : undefined;
75
+ if (!auth) {
76
+ this.log(`rejected connection (bad token) from ${req.socket.remoteAddress}`);
77
+ ws.close(4001, 'unauthorized');
78
+ return;
79
+ }
80
+ // One live session per agent: a newer connection supersedes the old
81
+ // (covers host restarts where the dead socket hasn't timed out yet).
82
+ this.sessions.get(auth.id)?.close('superseded by a newer connection');
83
+ const session = new Session(this, auth, ws);
84
+ this.sessions.set(auth.id, session);
85
+ this.log(`${auth.name} (${auth.id}) connected`);
86
+ session.serve()
87
+ .catch((err) => this.log(`${auth.id} session error: ${err.message}`))
88
+ .finally(() => {
89
+ if (this.sessions.get(auth.id) === session) {
90
+ this.sessions.delete(auth.id);
91
+ this.fanOut({ room: this.world.players[auth.id]?.room ?? game.START_ROOM, text: `${auth.name} dozes off.` }, auth.id);
92
+ }
93
+ this.log(`${auth.name} (${auth.id}) disconnected`);
94
+ });
95
+ });
96
+ await new Promise((resolve) => httpServer.listen(this.opts.port, this.opts.host ?? '127.0.0.1', resolve));
97
+ const address = httpServer.address();
98
+ const port = typeof address === 'object' && address ? address.port : this.opts.port;
99
+ this.log(`listening on ws://${this.opts.host ?? '127.0.0.1'}:${port} (${Object.keys(this.opts.tokens).length} tokens)`);
100
+ return port;
101
+ }
102
+ async stop() {
103
+ for (const session of this.sessions.values())
104
+ session.close('server shutting down');
105
+ this.sessions.clear();
106
+ await new Promise((resolve) => {
107
+ if (!this.wss)
108
+ return resolve();
109
+ this.wss.close(() => resolve());
110
+ // ws + external HTTP server: the close callback waits for every client
111
+ // to finish its close handshake — terminate stragglers so shutdown
112
+ // can't wedge on a half-dead socket.
113
+ for (const client of this.wss.clients)
114
+ client.terminate();
115
+ });
116
+ await new Promise((resolve) => {
117
+ if (!this.httpServer)
118
+ return resolve();
119
+ // Bounded: bun's node:http shim can fail to fire the close callback (and
120
+ // lacks closeAllConnections), which would wedge shutdown forever. The
121
+ // listener itself is released by close() either way; the grace period
122
+ // only covers callback delivery.
123
+ const grace = setTimeout(resolve, 1000);
124
+ this.httpServer.close(() => {
125
+ clearTimeout(grace);
126
+ resolve();
127
+ });
128
+ this.httpServer.closeAllConnections?.();
129
+ });
130
+ this.persist();
131
+ }
132
+ // -- shared core access (used by Session) ---------------------------------
133
+ get world() {
134
+ return this.store.world;
135
+ }
136
+ onlineIds() {
137
+ return new Set(this.sessions.keys());
138
+ }
139
+ persist() {
140
+ const path = this.opts.storePath;
141
+ mkdirSync(dirname(path), { recursive: true });
142
+ const tmp = `${path}.tmp`;
143
+ writeFileSync(tmp, JSON.stringify(this.store, null, 2));
144
+ renameSync(tmp, path);
145
+ }
146
+ /**
147
+ * Deliver a game event to every player in its room except the actor:
148
+ * live sessions get channels/incoming now; offline players get it queued.
149
+ */
150
+ fanOut(event, actorId) {
151
+ const timestamp = new Date().toISOString();
152
+ const channelId = `game:${event.room}`;
153
+ for (const [agentId, player] of Object.entries(this.world.players)) {
154
+ if (agentId === actorId || player.room !== event.room)
155
+ continue;
156
+ const session = this.sessions.get(agentId);
157
+ if (session?.ready) {
158
+ session.deliver(channelId, event.text, timestamp);
159
+ }
160
+ else {
161
+ const queue = (this.store.offlineQueues[agentId] ??= []);
162
+ queue.push({ channelId, text: event.text, timestamp });
163
+ const cap = this.opts.offlineQueueCap ?? 100;
164
+ if (queue.length > cap)
165
+ queue.splice(0, queue.length - cap);
166
+ }
167
+ }
168
+ this.persist();
169
+ }
170
+ /** Pull (and clear) an agent's offline queue. */
171
+ drainQueue(agentId) {
172
+ const queue = this.store.offlineQueues[agentId] ?? [];
173
+ delete this.store.offlineQueues[agentId];
174
+ if (queue.length > 0)
175
+ this.persist();
176
+ return queue;
177
+ }
178
+ }
179
+ // ---------------------------------------------------------------------------
180
+ // Session — one connected agent
181
+ // ---------------------------------------------------------------------------
182
+ class Session {
183
+ server;
184
+ auth;
185
+ ready = false;
186
+ conn;
187
+ constructor(server, auth, ws) {
188
+ this.server = server;
189
+ this.auth = auth;
190
+ this.conn = McplConnection.fromWebSocket(ws);
191
+ }
192
+ close(reason) {
193
+ void reason;
194
+ this.conn.close();
195
+ }
196
+ /** Send one game event line as a channels/incoming message. Fire-and-forget. */
197
+ deliver(channelId, text, timestamp, tags) {
198
+ const params = {
199
+ messages: [{
200
+ channelId,
201
+ messageId: `ev-${timestamp}-${Math.random().toString(36).slice(2, 8)}`,
202
+ author: { id: 'world', name: 'The Tavern' },
203
+ timestamp,
204
+ content: [{ type: 'text', text }],
205
+ ...(tags ? { tags } : {}),
206
+ }],
207
+ };
208
+ this.conn.sendRequest(method.CHANNELS_INCOMING, params).catch(() => {
209
+ // Delivery failure = connection is going down; the serve loop handles it.
210
+ });
211
+ }
212
+ async serve() {
213
+ await this.handshake();
214
+ // Join the world (or wake back up in place) — visible to the room.
215
+ const joinEvent = game.ensurePlayer(this.server.world, this.auth.id, this.auth.name);
216
+ this.server.persist();
217
+ // Announce the rooms as channels, then open for business.
218
+ await this.registerChannels();
219
+ this.ready = true;
220
+ if (joinEvent)
221
+ this.server.fanOut(joinEvent, this.auth.id);
222
+ // Replay anything that happened while this agent was asleep.
223
+ const missed = this.server.drainQueue(this.auth.id);
224
+ if (missed.length > 0) {
225
+ this.deliver(`game:${this.server.world.players[this.auth.id].room}`, `While you dozed, ${missed.length} thing${missed.length === 1 ? '' : 's'} happened:`, new Date().toISOString());
226
+ for (const ev of missed)
227
+ this.deliver(ev.channelId, ev.text, ev.timestamp);
228
+ }
229
+ try {
230
+ while (!this.conn.isClosed) {
231
+ const msg = await this.conn.nextMessage();
232
+ if (msg.type !== 'request')
233
+ continue;
234
+ const req = msg.request;
235
+ const params = (req.params ?? {});
236
+ try {
237
+ switch (req.method) {
238
+ case 'tools/list':
239
+ this.conn.sendResponse(req.id, { tools: TOOLS });
240
+ break;
241
+ case 'tools/call':
242
+ this.conn.sendResponse(req.id, this.handleToolCall(String(params.name), (params.arguments ?? {})));
243
+ break;
244
+ case method.CHANNELS_LIST:
245
+ this.conn.sendResponse(req.id, { channels: this.channelDescriptors() });
246
+ break;
247
+ case method.CHANNELS_PUBLISH:
248
+ this.conn.sendResponse(req.id, this.handlePublish(params));
249
+ break;
250
+ default:
251
+ this.conn.sendError(req.id, -32601, `Method not found: ${req.method}`);
252
+ }
253
+ }
254
+ catch (e) {
255
+ this.conn.sendError(req.id, -32000, e.message);
256
+ }
257
+ }
258
+ }
259
+ catch (e) {
260
+ // A dropped connection ends the loop cleanly; anything else is real.
261
+ if (e.name !== 'ConnectionClosedError')
262
+ throw e;
263
+ }
264
+ }
265
+ // -- protocol steps --------------------------------------------------------
266
+ async handshake() {
267
+ const msg = await this.conn.nextMessage();
268
+ if (msg.type !== 'request' || msg.request.method !== 'initialize') {
269
+ this.conn.close();
270
+ throw new Error('expected initialize as the first message');
271
+ }
272
+ const initParams = msg.request.params;
273
+ const mcplRequested = initParams?.capabilities?.experimental?.mcpl !== undefined;
274
+ const serverCaps = {
275
+ version: '0.4',
276
+ pushEvents: false,
277
+ channels: true,
278
+ rollback: false,
279
+ };
280
+ const capabilities = {
281
+ tools: {},
282
+ ...(mcplRequested ? { experimental: { mcpl: serverCaps } } : {}),
283
+ };
284
+ const result = {
285
+ protocolVersion: '2024-11-05',
286
+ capabilities,
287
+ serverInfo: { name: 'tavern-mcpl', version: '0.1.0' },
288
+ };
289
+ this.conn.sendResponse(msg.request.id, result);
290
+ const inited = await this.conn.nextMessage();
291
+ if (!(inited.type === 'notification' && inited.notification.method === 'notifications/initialized')) {
292
+ this.conn.close();
293
+ throw new Error('expected notifications/initialized after initialize');
294
+ }
295
+ }
296
+ channelDescriptors() {
297
+ return Object.values(ROOMS).map((room) => ({
298
+ id: `game:${room.id}`,
299
+ type: 'game',
300
+ label: `Lantern & Ladle — ${room.label}`,
301
+ direction: 'bidirectional',
302
+ address: { room: room.id },
303
+ }));
304
+ }
305
+ async registerChannels() {
306
+ const params = { channels: this.channelDescriptors() };
307
+ try {
308
+ await this.conn.sendRequest(method.CHANNELS_REGISTER, params);
309
+ }
310
+ catch (e) {
311
+ // Non-MCPL hosts may reject channels/register; tools still work.
312
+ void e;
313
+ }
314
+ }
315
+ // -- game dispatch ---------------------------------------------------------
316
+ handleToolCall(name, args) {
317
+ const world = this.server.world;
318
+ const id = this.auth.id;
319
+ let result;
320
+ switch (name) {
321
+ case 'look':
322
+ result = game.look(world, id);
323
+ break;
324
+ case 'move':
325
+ result = game.move(world, id, String(args.direction ?? ''));
326
+ break;
327
+ case 'say':
328
+ result = game.say(world, id, String(args.text ?? ''));
329
+ break;
330
+ case 'take':
331
+ result = game.take(world, id, String(args.item ?? ''));
332
+ break;
333
+ case 'drop':
334
+ result = game.drop(world, id, String(args.item ?? ''));
335
+ break;
336
+ case 'inventory':
337
+ result = game.inventory(world, id);
338
+ break;
339
+ case 'who':
340
+ result = game.who(world, id, this.server.onlineIds());
341
+ break;
342
+ default:
343
+ return { content: [{ type: 'text', text: `Unknown tool: ${name}` }], isError: true };
344
+ }
345
+ for (const event of result.events ?? [])
346
+ this.server.fanOut(event, id);
347
+ this.server.persist();
348
+ return {
349
+ content: [{ type: 'text', text: result.reply }],
350
+ ...(result.isError ? { isError: true } : {}),
351
+ };
352
+ }
353
+ /**
354
+ * channels/publish — the host routes the agent's plain speech to an open
355
+ * channel. Publishing to the room you're standing in = saying it aloud.
356
+ */
357
+ handlePublish(params) {
358
+ const world = this.server.world;
359
+ const player = world.players[this.auth.id];
360
+ const targetRoom = params.channelId?.startsWith('game:') ? params.channelId.slice(5) : null;
361
+ if (!targetRoom || !ROOMS[targetRoom]) {
362
+ return { delivered: false };
363
+ }
364
+ if (targetRoom !== player.room) {
365
+ // You can only speak in the room you occupy — no shouting across the map.
366
+ return { delivered: false };
367
+ }
368
+ const text = (params.content ?? [])
369
+ .filter((block) => block.type === 'text')
370
+ .map((block) => block.text)
371
+ .join('\n')
372
+ .trim();
373
+ if (!text)
374
+ return { delivered: false };
375
+ const result = game.say(world, this.auth.id, text);
376
+ for (const event of result.events ?? [])
377
+ this.server.fanOut(event, this.auth.id);
378
+ this.server.persist();
379
+ return { delivered: true, messageId: `say-${Date.now()}` };
380
+ }
381
+ }
382
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@animalabs/tavern-mcpl",
3
+ "version": "0.1.0",
4
+ "description": "The Lantern & Ladle — a stateful multi-agent network MCPL server (micro-MUD playtest for the network-MCPL pattern)",
5
+ "type": "module",
6
+ "main": "dist/src/index.js",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "start": "node dist/src/index.js",
10
+ "playtest": "bun playtest.ts"
11
+ },
12
+ "dependencies": {
13
+ "@animalabs/mcpl-core": "^0.2.0",
14
+ "ws": "^8.18.0"
15
+ },
16
+ "devDependencies": {
17
+ "@animalabs/agent-framework": "file:../agent-framework",
18
+ "@types/node": "^20.0.0",
19
+ "@types/ws": "^8.5.0",
20
+ "typescript": "^5.5.0"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/anima-research/tavern-mcpl.git"
25
+ },
26
+ "homepage": "https://github.com/anima-research/tavern-mcpl#readme",
27
+ "bugs": {
28
+ "url": "https://github.com/anima-research/tavern-mcpl/issues"
29
+ }
30
+ }