A seat's verb keeps a node of its own; only a module's tool gives it to the subject
The console moved every call's node into the subject (ADR 0159), so mesh-controller.push {node: x}
became a call to the seat's verb on machine x, which nothing serves — the mesh's own verbs could not
be given a machine from the console at all. A role's verb takes no machine from the console; its
arguments are its own.
This commit is contained in:
+10
-6
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import type { Broker } from "@novox/mesh-sdk/messaging";
|
||||
|
||||
import { callTool, seatsIn, toolsOn, whyItFailed, type Listing, type Seats } from "./client.js";
|
||||
import { callTool, seatsIn, toolKey, toolsOn, whyItFailed, type Listing, type Seats } from "./client.js";
|
||||
|
||||
/** The protocol version this speaks. Stated, because a host that wants another should be told so
|
||||
* rather than discovering it through a shape it did not expect. */
|
||||
@@ -134,13 +134,17 @@ export function mcpSurface(bus: Broker, who: string): Surface {
|
||||
const given = String(request.params?.name ?? "");
|
||||
const args = { ...((request.params?.arguments as Record<string, unknown> | undefined) ?? {}) };
|
||||
// The machine, when the caller names one, travels in the subject and never reaches the
|
||||
// module's arguments (novox/hq ADR 0159).
|
||||
const node = typeof args.node === "string" && args.node !== "" ? args.node : "";
|
||||
delete args.node;
|
||||
// module's arguments (novox/hq ADR 0159) — for a module's tool. A seat's verb takes no
|
||||
// machine from the console (the seat's scope decides), so a `node` among its arguments
|
||||
// is the verb's own, as `push` and `assign` take one, and is handed through untouched.
|
||||
const have = await listing().catch(() => undefined);
|
||||
const roles = have && seatsIn(have);
|
||||
const isSeatVerb = roles ? toolKey(given.split("@", 1)[0], roles).startsWith("seat:") : false;
|
||||
const node = !isSeatVerb && typeof args.node === "string" && args.node !== "" ? args.node : "";
|
||||
if (!isSeatVerb) delete args.node;
|
||||
const name = node && !given.includes("@") ? `${given}@${node}` : given;
|
||||
try {
|
||||
const have = await listing().catch(() => undefined);
|
||||
const { result, node: answeredBy } = await callTool(bus, name, args, have && seatsIn(have), have);
|
||||
const { result, node: answeredBy } = await callTool(bus, name, args, roles, have);
|
||||
// Text, because that is what every host renders. The content is the module's answer
|
||||
// as JSON, unshaped: an adapter that flattened it would be deciding what matters in
|
||||
// somebody else's answer. Which machine answered follows it as its own line.
|
||||
|
||||
Reference in New Issue
Block a user