feat(gateway): add WebSocket gateway with JSON-RPC protocol and auth
Phase 2 of the Flynn roadmap. Adds a WebSocket gateway server that starts alongside the Telegram bot, providing real-time API access to the agent, sessions, and tools. Protocol: JSON-RPC-like (request/response/event) over WebSocket. 8 methods: agent.send, agent.cancel, sessions.list, sessions.history, sessions.create, tools.list, tools.invoke, system.health. Auth: Bearer token + Tailscale identity header support. Session bridge: per-connection agent instances with shared model router. New files: src/gateway/ (protocol, router, server, auth, session-bridge, handlers for agent/sessions/tools/system). 57 new tests (181 total), typecheck clean.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import type { GatewayRequest, OutboundMessage } from '../protocol.js';
|
||||
import { makeResponse, makeError, ErrorCode } from '../protocol.js';
|
||||
import type { ToolRegistry } from '../../tools/registry.js';
|
||||
import type { ToolExecutor } from '../../tools/executor.js';
|
||||
|
||||
export interface ToolHandlerDeps {
|
||||
toolRegistry: ToolRegistry;
|
||||
toolExecutor: ToolExecutor;
|
||||
}
|
||||
|
||||
export function createToolHandlers(deps: ToolHandlerDeps) {
|
||||
return {
|
||||
'tools.list': async (request: GatewayRequest): Promise<OutboundMessage> => {
|
||||
const tools = deps.toolRegistry.list().map(t => ({
|
||||
name: t.name,
|
||||
description: t.description,
|
||||
inputSchema: t.inputSchema,
|
||||
}));
|
||||
return makeResponse(request.id, { tools });
|
||||
},
|
||||
|
||||
'tools.invoke': async (request: GatewayRequest): Promise<OutboundMessage> => {
|
||||
const params = request.params as { tool?: string; args?: Record<string, unknown> } | undefined;
|
||||
if (!params?.tool) {
|
||||
return makeError(request.id, ErrorCode.InvalidRequest, 'tool name is required');
|
||||
}
|
||||
|
||||
const tool = deps.toolRegistry.get(params.tool);
|
||||
if (!tool) {
|
||||
return makeError(request.id, ErrorCode.ToolNotFound, `Tool not found: ${params.tool}`);
|
||||
}
|
||||
|
||||
const result = await deps.toolExecutor.execute(params.tool, params.args ?? {});
|
||||
return makeResponse(request.id, result);
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user