diff --git a/apps/broker/src/telegram-ai.ts b/apps/broker/src/telegram-ai.ts index 13c1fae..b941bf3 100644 --- a/apps/broker/src/telegram-ai.ts +++ b/apps/broker/src/telegram-ai.ts @@ -133,6 +133,22 @@ const TOOLS: AiTool[] = [ }, }, }, + { + name: "list_services", + description: "List all deployed MCP services and skills in the mesh. Use when user asks about available tools, services, MCPs, skills, or capabilities.", + input_schema: { + type: "object", + properties: {}, + }, + }, + { + name: "list_commands", + description: "Show available Telegram bot commands. Use when user asks what commands are available, what they can do, or asks for help.", + input_schema: { + type: "object", + properties: {}, + }, + }, ]; // Actions that need user confirmation before executing @@ -370,6 +386,32 @@ export function formatResult(toolName: string, result: unknown): string { case "share_mesh": return typeof result === "string" ? `🔗 Invite: ${result}` : "✅ Invite sent."; + case "list_services": { + const services = result as Array<{ name: string; type: string; tools: number; status: string }>; + if (!services || services.length === 0) return "No services deployed in this mesh."; + return "⚙️ Mesh services:\n\n" + services.map(s => + `• ${escHtml(s.name)} (${s.type}) — ${s.tools} tool${s.tools !== 1 ? "s" : ""} [${s.status}]` + ).join("\n"); + } + + case "list_commands": + return `📋 Available commands: + +/connect — connect to a mesh +/disconnect — disconnect from mesh +/peers — list online peers +/meshes — list connected meshes +/dm @Name message — send direct message +/broadcast message — send to all peers +/status — connection status +/help — show help + +Or just type naturally: +• "who's online?" +• "tell Nedas the API is ready" +• "list my meshes" +• "what services are available?"`; + default: return `✅ Done: ${JSON.stringify(result)}`; } diff --git a/apps/broker/src/telegram-bridge.ts b/apps/broker/src/telegram-bridge.ts index a591e6b..87795da 100644 --- a/apps/broker/src/telegram-bridge.ts +++ b/apps/broker/src/telegram-bridge.ts @@ -1721,6 +1721,28 @@ async function executeAiToolCall( case "list_peers": return conn.listPeers(); + case "list_services": { + // Query deployed services from the broker DB + try { + const { listDbMeshServices } = await import("./broker"); + const allServices: Array<{ name: string; type: string; tools: number; status: string }> = []; + for (const meshId of meshIds) { + const services = await listDbMeshServices(meshId); + for (const s of services) { + allServices.push({ + name: s.name, + type: s.type ?? "mcp", + tools: s.tool_count ?? 0, + status: s.status ?? "running", + }); + } + } + return allServices; + } catch { + return []; + } + } + case "list_meshes": { const results: Array<{ slug: string; peers: number }> = []; for (const meshId of meshIds) { @@ -1738,6 +1760,9 @@ async function executeAiToolCall( return results; } + case "list_commands": + return null; // The formatter handles this — no execution needed + case "remember": case "recall": case "get_state":