import { test } from "node:test"; import assert from "node:assert/strict"; import { registerModuleTools, resetTools, invokeTool } from "@novox/mesh-sdk/tools"; import { connectAmqp } from "../dist/broker-amqp.js"; import { runTools } from "../dist/runtime.js"; // Requires a real broker at $MESH_BROKER_URL. The test harness spins LavinMQ (the mesh's broker) // and points this at it; skipped if it is not set, never failed for the environment. const url = process.env.MESH_BROKER_URL; test("a module's tool serves and is invoked over a real AMQP broker", { skip: !url }, async () => { resetTools(); // A module registers a real tool, exactly as umami does. registerModuleTools("demo", () => [ { name: "greet", description: "return a greeting", input: { who: { type: "string" } }, run: async (args) => ({ hello: String(args.who), from: "the tool runtime" }), }, ]); // The runtime binds the broker and serves the module (no module entrypoints to import here — the // tool is registered in-process — but this is the exact runtime that serves on a node). const serverBroker = await connectAmqp(url!); const stop = await runTools({ broker: serverBroker, moduleEntrypoints: [] }); // A separate connection — a caller, like mesh-control's command API — invokes over the broker, // by module and tool (novox/hq ADR 0047: served on serve.demo.greet, invoked as demo.greet). const caller = await connectAmqp(url!); const result = (await invokeTool(caller, "demo", "greet", { who: "mesh" })) as { hello: string }; assert.equal(result.hello, "mesh"); stop(); await caller.close(); await serverBroker.close(); });