/** * MAGI — pi extension entry point. * * Registers: * - the `magi` tool (LLM-callable) — runs a MAGI deliberation and returns a * structured {@link MagiOutput} recommendation. * - the `/magi ` command — runs the default council from the user. * - the `/magi:council` command — shows the active council configuration. * * MAGI advises CORTEX (or the main agent). It never executes work itself. * * Build priorities for the broader NERVous system put MAGI here; this package * is intentionally self-contained so it can be installed and used on its own. */ import * as path from "node:path"; import { fileURLToPath } from "node:url"; import type { AgentToolResult } from "@earendil-works/pi-agent-core"; import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent"; import { loadNervousConfig, resolveNervousModel } from "@nervous-system/state"; import { deliberate, type DeliberateStatus } from "./council.ts"; import { createSubprocessRunner } from "./subprocess.ts"; import { resolveCouncil } from "./config.ts"; import { MagiHistoryStore } from "./history.ts"; import { formatStatus, formatStatusWidget, renderMagiCall, renderMagiResult, summarizeOutput } from "./render.ts"; import { MagiToolParams, type CouncilConfig, type MagiInput, type MagiOutput, type MagiToolInput } from "./schema.ts"; const EXT_DIR = path.dirname(fileURLToPath(import.meta.url)); const BUNDLED_CONFIG_DIR = path.resolve(EXT_DIR, "..", "config"); async function runMagi(args: { input: MagiInput; councilSpec?: string; critiqueOverride?: boolean; cwd: string; isProjectTrusted?: boolean | (() => boolean); signal?: AbortSignal; onStatusText?: (text: string) => void; onStatus?: (status: DeliberateStatus) => void; }): Promise<{ output: MagiOutput; source: string }> { const resolved = resolveCouncil(args.councilSpec, { cwd: args.cwd, bundledConfigDir: BUNDLED_CONFIG_DIR }); const config = applyNervousModelDefaults({ ...resolved.config, councillors: resolved.config.councillors.map((c) => ({ ...c })) }, args.cwd, args.isProjectTrusted); if (args.critiqueOverride !== undefined) config.critique = args.critiqueOverride; const generate = createSubprocessRunner({ cwd: args.cwd }); const output = await deliberate({ input: args.input, config, generate, signal: args.signal, onUpdate: args.onStatusText || args.onStatus ? (status) => { args.onStatusText?.(formatStatus(status)); args.onStatus?.(status); } : undefined, }); return { output, source: resolved.source }; } type MagiDetails = MagiOutput & { source: string }; export function applyNervousModelDefaults( config: CouncilConfig, cwd: string, isProjectTrusted: boolean | (() => boolean) | undefined, ): CouncilConfig { const resolution = loadNervousConfig({ cwd, isProjectTrusted }); const model = resolveNervousModel(resolution, "magi.default").model ?? resolveNervousModel(resolution, "magi.fallback").model; const synthesizerId = config.synthesizer ?? config.councillors[config.councillors.length - 1]?.id; const synthesizerHadModel = Boolean(config.councillors.find((c) => c.id === synthesizerId)?.model?.trim()); if (model) { for (const councillor of config.councillors) { if (!councillor.model?.trim()) councillor.model = model; } if (!config.synthesis_model?.trim() && !synthesizerHadModel) config.synthesis_model = model; } return config; } export default function (pi: ExtensionAPI) { /* ----------------------------- magi tool ------------------------------ */ pi.registerTool({ name: "magi", label: "MAGI", description: [ "Convene the MAGI deliberation council (default: The Mind, The Heart, The Hand) to deliberate a hard,", "ambiguous, risky, or architecturally significant decision and return a structured recommendation.", "MAGI advises only — it does not execute tasks. CORTEX converts the recommendation into a plan.", ].join(" "), promptSnippet: "Convene the MAGI council to deliberate a hard decision and return a recommendation", promptGuidelines: [ "Opt-in: use/mention this component only for explicit NERVous, durable-state, orchestration, delegation, coordination, or risk-triage requests.", "Use the magi tool when facing an ambiguous, high-risk, or architecturally significant decision with unclear tradeoffs.", "Use the magi tool before final delivery to get a multi-perspective review of a major decision.", "Do not use the magi tool for simple, well-understood tasks — reserve it for decisions that warrant deliberation.", ], parameters: MagiToolParams, async execute(_toolCallId, params, signal, onUpdate, ctx) { const input: MagiInput = { issue: params.issue, context: params.context, constraints: params.constraints, decision_needed: params.decision_needed, options: params.options, }; try { const { output, source } = await runMagi({ input, councilSpec: params.council, critiqueOverride: params.critique, cwd: ctx.cwd, isProjectTrusted: () => ctx.isProjectTrusted?.() ?? false, signal, onStatusText: onUpdate ? (text) => { const partial: AgentToolResult = { content: [{ type: "text", text }], details: { ...emptyOutput(), source: "running" }, }; onUpdate(partial); } : undefined, }); await MagiHistoryStore.fromCwd(ctx.cwd).append(input, output, source); const details: MagiDetails = { ...output, source }; return { content: [{ type: "text", text: summarizeOutput(output) }], details, }; } catch (err) { const msg = err instanceof Error ? err.message : String(err); return { content: [{ type: "text", text: `MAGI deliberation failed: ${msg}` }], details: { ...emptyOutput(), source: "error" } as MagiDetails, isError: true, }; } }, renderCall(args, theme) { return renderMagiCall(args as { issue?: string; council?: string }, theme as never); }, renderResult(result, options, theme) { return renderMagiResult( result as Parameters[0], options as Parameters[1], theme as never, ); }, }); /* ------------------------- /magi command ---------------------- */ pi.registerCommand("magi", { description: "Convene the MAGI council to deliberate an issue (default council)", handler: async (rawArgs, ctx) => { const issue = (rawArgs ?? "").trim(); if (!issue) { ctx.ui.notify("Usage: /magi ", "info"); return; } await deliberateCommand(pi, ctx, { issue }); }, }); /* --------------------- /magi:council info command --------------------- */ pi.registerCommand("magi:council", { description: "Show the active MAGI council configuration", handler: async (_args, ctx) => { try { const resolved = resolveCouncil(undefined, { cwd: ctx.cwd, bundledConfigDir: BUNDLED_CONFIG_DIR, }); const lines = [ `MAGI council — source: ${resolved.source}`, `synthesizer: ${resolved.config.synthesizer ?? "(default)"} · critique: ${resolved.config.critique ? "on" : "off"}`, "", ...resolved.config.councillors.map((c) => `• ${c.id} — ${c.name}${c.symbol ? ` (${c.symbol})` : ""}`), ]; if (resolved.warnings.length) lines.push("", "Warnings:", ...resolved.warnings.map((w) => `- ${w}`)); for (const line of lines) ctx.ui.notify(line, "info"); } catch (err) { ctx.ui.notify(`MAGI config error: ${err instanceof Error ? err.message : err}`, "error"); } }, }); } /* -------------------------------------------------------------------------- */ /* helpers */ /* -------------------------------------------------------------------------- */ function emptyOutput(): MagiOutput { return { council_used: [], individual_opinions: [], points_of_agreement: [], points_of_disagreement: [], risks: [], rejected_options: [], final_recommendation: "", confidence: "low", meta: { critique_used: false, synthesizer: "", rounds: 0, warnings: [] }, }; } async function deliberateCommand( pi: ExtensionAPI, ctx: ExtensionContext, input: MagiInput, ): Promise { if (ctx.hasUI) { ctx.ui.notify("MAGI council convening…", "info"); ctx.ui.setStatus("magi", "MAGI deliberating…"); ctx.ui.setWidget("magi", ["MAGI council — starting", `Issue: ${input.issue.length > 96 ? `${input.issue.slice(0, 96)}…` : input.issue}`]); } try { const { output, source } = await runMagi({ input, cwd: ctx.cwd, isProjectTrusted: () => ctx.isProjectTrusted?.() ?? false, onStatusText: ctx.hasUI ? (text) => ctx.ui.setStatus("magi", text) : undefined, onStatus: ctx.hasUI ? (status) => ctx.ui.setWidget("magi", formatStatusWidget(status, input.issue)) : undefined, }); await MagiHistoryStore.fromCwd(ctx.cwd).append(input, output, source); if (ctx.hasUI) { ctx.ui.setStatus("magi", undefined); ctx.ui.setWidget("magi", undefined); } // Display the result in the transcript and notify a short summary. pi.sendMessage( { customType: "magi", content: summarizeOutput(output), display: true, details: { ...output, source }, }, { triggerTurn: false }, ); const short = output.final_recommendation.length > 120 ? `${output.final_recommendation.slice(0, 120)}…` : output.final_recommendation; ctx.ui.notify(`MAGI complete (${output.confidence}): ${short || "(no recommendation)"}`, "info"); } catch (err) { if (ctx.hasUI) { ctx.ui.setStatus("magi", undefined); ctx.ui.setWidget("magi", undefined); } ctx.ui.notify(`MAGI failed: ${err instanceof Error ? err.message : err}`, "error"); } }