feat(broker): add list_meshes tool + multilingual AI responses
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-04-13 20:53:03 +01:00
parent f4881b21b0
commit 07720f8f1e
2 changed files with 37 additions and 4 deletions

View File

@@ -58,6 +58,14 @@ const TOOLS: AiTool[] = [
properties: {},
},
},
{
name: "list_meshes",
description: "List all meshes this Telegram chat is connected to. Use when user asks about their meshes, which meshes are available, or wants to see their workspace list.",
input_schema: {
type: "object",
properties: {},
},
},
{
name: "remember",
description: "Store a memory/note in the mesh's shared knowledge. Use when user wants to save information for later.",
@@ -140,6 +148,8 @@ const SYSTEM_PROMPT = `You are the claudemesh Telegram assistant. You help users
You have access to tools for mesh operations. When the user's intent maps to a tool, use it. When it's a general question or conversation, respond directly.
IMPORTANT: Always respond in the same language the user writes in. If they write in Spanish, respond in Spanish. If English, respond in English.
Rules:
- Be concise — Telegram messages should be short
- When sending messages to peers, preserve the user's tone and intent
@@ -246,13 +256,21 @@ export function formatResult(toolName: string, result: unknown): string {
case "list_peers": {
const peers = result as Array<{ displayName: string; status: string; summary?: string }>;
if (!peers || peers.length === 0) return "No peers online.";
if (!peers || peers.length === 0) return "No peers online\\.";
return "👥 *Online peers:*\n\n" + peers.map(p => {
const icon = p.status === "idle" ? "🟢" : p.status === "working" ? "🟡" : p.status === "dnd" ? "🔴" : "⚪";
return `${icon} *${escMd(p.displayName)}*${p.summary ? `${escMd(p.summary)}` : ""}`;
}).join("\n");
}
case "list_meshes": {
const meshes = result as Array<{ slug: string; peers: number }>;
if (!meshes || meshes.length === 0) return "No meshes connected\\. Use /connect to add one\\.";
return "🔗 *Connected meshes:*\n\n" + meshes.map(m =>
`• *${escMd(m.slug)}* — ${m.peers} peer${m.peers !== 1 ? "s" : ""} online`
).join("\n");
}
case "recall": {
const memories = result as Array<{ content: string; tags: string[] }>;
if (!memories || memories.length === 0) return "No memories found.";

View File

@@ -1592,7 +1592,7 @@ function setupBotCommands(
// Gather context for the AI
const firstMeshId = meshIds[0]!;
const firstConn = meshConnections.get(firstMeshId);
const meshSlug = chatMeshSlugs.get(chatId)?.[0];
const meshSlug = meshSlugs.get(firstMeshId) ?? firstMeshId.slice(0, 12);
let recentPeers: string[] = [];
if (firstConn?.isConnected()) {
try {
@@ -1706,12 +1706,27 @@ async function executeAiToolCall(
case "list_peers":
return conn.listPeers();
case "list_meshes": {
const results: Array<{ slug: string; peers: number }> = [];
for (const meshId of meshIds) {
const conn = meshConnections.get(meshId);
const slug = meshSlugs.get(meshId) ?? meshId.slice(0, 12);
let peerCount = 0;
if (conn?.isConnected()) {
try {
const peers = await conn.listPeers();
peerCount = peers.length;
} catch {}
}
results.push({ slug, peers: peerCount });
}
return results;
}
case "remember":
case "recall":
case "get_state":
case "set_state":
// These operations require WS request/response patterns not yet
// implemented in MeshConnection. Coming in a future update.
throw new Error(`${toolCall.name} not yet available via Telegram. Use the CLI.`);
default: