40 lines
1.6 KiB
TypeScript
40 lines
1.6 KiB
TypeScript
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();
|
|
});
|