import type { CommandHandler } from "./commands-types.js"; import { callGateway } from "../../gateway/call.js"; import { logVerbose } from "../../globals.js"; import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../utils/message-channel.js"; type MeshPlanShape = { planId: string; goal: string; createdAt: number; steps: Array<{ id: string; name?: string; prompt: string; dependsOn?: string[] }>; }; type CachedMeshPlan = { plan: MeshPlanShape; createdAt: number }; type ParsedMeshCommand = | { ok: true; action: "help" } | { ok: true; action: "run" | "plan"; target: string } | { ok: true; action: "status"; runId: string } | { ok: true; action: "retry"; runId: string; stepIds?: string[] } | { ok: false; message: string } | null; const meshPlanCache = new Map(); const MAX_CACHED_MESH_PLANS = 200; function trimMeshPlanCache() { if (meshPlanCache.size <= MAX_CACHED_MESH_PLANS) { return; } const oldest = [...meshPlanCache.entries()] .sort((a, b) => a[1].createdAt - b[1].createdAt) .slice(0, meshPlanCache.size - MAX_CACHED_MESH_PLANS); for (const [key] of oldest) { meshPlanCache.delete(key); } } function parseMeshCommand(commandBody: string): ParsedMeshCommand { const trimmed = commandBody.trim(); if (!/^\/mesh\b/i.test(trimmed)) { return null; } const rest = trimmed.replace(/^\/mesh\b:?/i, "").trim(); if (!rest || /^help$/i.test(rest)) { return { ok: true, action: "help" }; } const tokens = rest.split(/\s+/).filter(Boolean); if (tokens.length === 0) { return { ok: true, action: "help" }; } const actionCandidate = tokens[0]?.toLowerCase() ?? ""; const explicitAction = actionCandidate === "run" || actionCandidate === "plan" || actionCandidate === "status" || actionCandidate === "retry" ? actionCandidate : null; if (!explicitAction) { // Shorthand: `/mesh ` => auto plan + run return { ok: true, action: "run", target: rest }; } const actionArgs = rest.slice(tokens[0]?.length ?? 0).trim(); if (explicitAction === "plan" || explicitAction === "run") { if (!actionArgs) { return { ok: false, message: `Usage: /mesh ${explicitAction} ` }; } return { ok: true, action: explicitAction, target: actionArgs }; } if (explicitAction === "status") { if (!actionArgs) { return { ok: false, message: "Usage: /mesh status " }; } return { ok: true, action: "status", runId: actionArgs.split(/\s+/)[0] }; } // retry const argsTokens = actionArgs.split(/\s+/).filter(Boolean); if (argsTokens.length === 0) { return { ok: false, message: "Usage: /mesh retry [step1,step2,...]" }; } const runId = argsTokens[0]; const stepArg = argsTokens.slice(1).join(" ").trim(); const stepIds = stepArg.length > 0 ? stepArg .split(",") .map((entry) => entry.trim()) .filter(Boolean) : undefined; return { ok: true, action: "retry", runId, stepIds }; } function cacheKeyForPlan(params: Parameters[0], planId: string) { const sender = params.command.senderId ?? "unknown"; const channel = params.command.channel || "unknown"; return `${channel}:${sender}:${planId}`; } function putCachedPlan(params: Parameters[0], plan: MeshPlanShape) { meshPlanCache.set(cacheKeyForPlan(params, plan.planId), { plan, createdAt: Date.now() }); trimMeshPlanCache(); } function getCachedPlan(params: Parameters[0], planId: string): MeshPlanShape | null { return meshPlanCache.get(cacheKeyForPlan(params, planId))?.plan ?? null; } function looksLikeMeshPlanId(value: string) { return /^mesh-plan-[a-z0-9-]+$/i.test(value.trim()); } function resolveMeshCommandBody(params: Parameters[0]) { return ( params.ctx.BodyForCommands ?? params.ctx.CommandBody ?? params.ctx.RawBody ?? params.ctx.Body ?? params.command.commandBodyNormalized ); } function formatPlanSummary(plan: { goal: string; steps: Array<{ id: string; name?: string; prompt: string; dependsOn?: string[] }>; }) { const lines = [`πŸ•ΈοΈ Mesh Plan`, `Goal: ${plan.goal}`, "", `Steps (${plan.steps.length}):`]; for (const step of plan.steps) { const dependsOn = Array.isArray(step.dependsOn) && step.dependsOn.length > 0; const depLine = dependsOn ? ` (depends on: ${step.dependsOn?.join(", ")})` : ""; lines.push(`- ${step.id}${step.name ? ` β€” ${step.name}` : ""}${depLine}`); lines.push(` ${step.prompt}`); } return lines.join("\n"); } function formatRunSummary(payload: { runId: string; status: string; stats?: { total?: number; succeeded?: number; failed?: number; skipped?: number; running?: number; pending?: number; }; }) { const stats = payload.stats ?? {}; return [ `πŸ•ΈοΈ Mesh Run`, `Run: ${payload.runId}`, `Status: ${payload.status}`, `Steps: total=${stats.total ?? 0}, ok=${stats.succeeded ?? 0}, failed=${stats.failed ?? 0}, skipped=${stats.skipped ?? 0}, running=${stats.running ?? 0}, pending=${stats.pending ?? 0}`, ].join("\n"); } function meshUsageText() { return [ "πŸ•ΈοΈ Mesh command", "Usage:", "- /mesh (auto plan + run)", "- /mesh plan ", "- /mesh run ", "- /mesh status ", "- /mesh retry [step1,step2,...]", ].join("\n"); } function resolveMeshClientLabel(params: Parameters[0]) { const channel = params.command.channel; const sender = params.command.senderId ?? "unknown"; return `Chat mesh (${channel}:${sender})`; } export const handleMeshCommand: CommandHandler = async (params, allowTextCommands) => { if (!allowTextCommands) { return null; } const parsed = parseMeshCommand(resolveMeshCommandBody(params)); if (!parsed) { return null; } if (!params.command.isAuthorizedSender) { logVerbose(`Ignoring /mesh from unauthorized sender: ${params.command.senderId || ""}`); return { shouldContinue: false }; } if (!parsed.ok) { return { shouldContinue: false, reply: { text: parsed.message } }; } if (parsed.action === "help") { return { shouldContinue: false, reply: { text: meshUsageText() } }; } const clientDisplayName = resolveMeshClientLabel(params); const commonGateway = { clientName: GATEWAY_CLIENT_NAMES.GATEWAY_CLIENT, clientDisplayName, mode: GATEWAY_CLIENT_MODES.BACKEND, } as const; try { if (parsed.action === "plan") { const planResp = await callGateway<{ plan: MeshPlanShape; order?: string[]; source?: string; }>({ method: "mesh.plan.auto", params: { goal: parsed.target, agentId: params.agentId ?? "main", }, ...commonGateway, }); putCachedPlan(params, planResp.plan); const sourceLine = planResp.source ? `\nPlanner source: ${planResp.source}` : ""; return { shouldContinue: false, reply: { text: `${formatPlanSummary(planResp.plan)}${sourceLine}\n\nRun exact plan: /mesh run ${planResp.plan.planId}`, }, }; } if (parsed.action === "run") { let runPlan: MeshPlanShape; if (looksLikeMeshPlanId(parsed.target)) { const cached = getCachedPlan(params, parsed.target.trim()); if (!cached) { return { shouldContinue: false, reply: { text: `Plan ${parsed.target.trim()} not found in this chat.\nCreate one first: /mesh plan `, }, }; } runPlan = cached; } else { const planResp = await callGateway<{ plan: MeshPlanShape; order?: string[]; source?: string; }>({ method: "mesh.plan.auto", params: { goal: parsed.target, agentId: params.agentId ?? "main", }, ...commonGateway, }); putCachedPlan(params, planResp.plan); runPlan = planResp.plan; } const runResp = await callGateway<{ runId: string; status: string; stats?: { total?: number; succeeded?: number; failed?: number; skipped?: number; running?: number; pending?: number; }; }>({ method: "mesh.run", params: { plan: runPlan, }, ...commonGateway, }); return { shouldContinue: false, reply: { text: `${formatPlanSummary(runPlan)}\n\n${formatRunSummary(runResp)}`, }, }; } if (parsed.action === "status") { const statusResp = await callGateway<{ runId: string; status: string; stats?: { total?: number; succeeded?: number; failed?: number; skipped?: number; running?: number; pending?: number; }; }>({ method: "mesh.status", params: { runId: parsed.runId }, ...commonGateway, }); return { shouldContinue: false, reply: { text: formatRunSummary(statusResp) }, }; } if (parsed.action === "retry") { const retryResp = await callGateway<{ runId: string; status: string; stats?: { total?: number; succeeded?: number; failed?: number; skipped?: number; running?: number; pending?: number; }; }>({ method: "mesh.retry", params: { runId: parsed.runId, ...(parsed.stepIds && parsed.stepIds.length > 0 ? { stepIds: parsed.stepIds } : {}), }, ...commonGateway, }); return { shouldContinue: false, reply: { text: `πŸ” Retry submitted\n${formatRunSummary(retryResp)}` }, }; } return null; } catch (err) { const message = err instanceof Error ? err.message : String(err); return { shouldContinue: false, reply: { text: `❌ Mesh command failed: ${message}`, }, }; } };