fix(tools): execute receives (callId, args), not (args) — pre-existing bug

OpenClaw plugin-sdk's registerTool execute signature is:
  execute: async (_id: string, params) => { ... }

Fabric tools were calling it as `(p) => { ... }`, so `p` held the
call id (a string) and the real args were silently dropped onto the
floor. Every tool that read a required field from `p` failed with
the field surfacing as undefined.

fabric-guild-list (just added) appeared to work because all its
properties are optional — `p.nameFilter` and `p.purposeFilter`
both being undefined produced empty filter needles, which let the
unfiltered guild list through. The real bug surfaced the moment
fabric-channel-list (required: guildNodeId) was invoked: the
ctxGuild helper saw `undefined` and reported `agent not a member
of guild undefined`.

Compare dialectic plugin's tools.ts which has always used the
correct `async (_id: string, params) => {...}` shape and worked
end-to-end. Aligning the fabric signature to match.

Verified end-to-end on sim:
  - fabric-guild-list returns 1 guild with the purpose set via the
    new `cli node set-purpose`
  - fabric-channel-list returns 3 channels including a now-populated
    `purpose` field on each row
  - fabric-channel-set-purpose successfully patches a channel and
    the subsequent fabric-channel-list shows the new purpose
This commit is contained in:
h z
2026-05-23 19:35:38 +01:00
parent 5ff464a055
commit 0e36457d8f
2 changed files with 18 additions and 18 deletions

View File

@@ -48,7 +48,7 @@ export function registerFabricTools(api, client, identity) {
},
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };
@@ -84,7 +84,7 @@ export function registerFabricTools(api, client, identity) {
callbackChannelId: { type: 'string', description: 'optional channel to also post the summary to' },
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };
@@ -128,7 +128,7 @@ export function registerFabricTools(api, client, identity) {
},
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };
@@ -188,7 +188,7 @@ export function registerFabricTools(api, client, identity) {
channelId: { type: 'string' },
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };
@@ -235,7 +235,7 @@ export function registerFabricTools(api, client, identity) {
content: { type: 'string', description: 'Message body (markdown supported by the renderer).' },
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };
@@ -270,7 +270,7 @@ export function registerFabricTools(api, client, identity) {
includeClosed: { type: 'boolean', description: 'default false — closed channels filtered out' },
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };
@@ -330,7 +330,7 @@ export function registerFabricTools(api, client, identity) {
},
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };
@@ -387,7 +387,7 @@ export function registerFabricTools(api, client, identity) {
},
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };
@@ -422,7 +422,7 @@ export function registerFabricTools(api, client, identity) {
limit: { type: 'integer', minimum: 1, maximum: 200, description: 'default 20' },
},
},
execute: async (p) => {
execute: async (_id, p) => {
const agentId = ctx.agentId;
if (!agentId)
return { ok: false, error: 'no agent context' };