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' };

View File

@@ -71,7 +71,7 @@ export function registerFabricTools(
},
},
},
execute: async (p: {
execute: async (_id: string, p: {
guildNodeId: string;
name: string;
isPublic?: boolean;
@@ -114,7 +114,7 @@ export function registerFabricTools(
callbackChannelId: { type: 'string', description: 'optional channel to also post the summary to' },
},
},
execute: async (p: {
execute: async (_id: string, p: {
guildNodeId: string;
channelId: string;
summary: string;
@@ -164,7 +164,7 @@ export function registerFabricTools(
},
},
},
execute: async (p: {
execute: async (_id: string, p: {
action: 'read' | 'share' | 'update' | 'close';
guildNodeId: string;
channelId: string;
@@ -229,7 +229,7 @@ export function registerFabricTools(
channelId: { type: 'string' },
},
},
execute: async (p: {
execute: async (_id: string, p: {
action: 'members' | 'join' | 'leave';
guildNodeId: string;
channelId: string;
@@ -281,7 +281,7 @@ export function registerFabricTools(
content: { type: 'string', description: 'Message body (markdown supported by the renderer).' },
},
},
execute: async (p: { guildNodeId: string; channelId: string; content: string }) => {
execute: async (_id: string, p: { guildNodeId: string; channelId: string; content: string }) => {
const agentId = ctx.agentId;
if (!agentId) return { ok: false, error: 'no agent context' };
const { session, guild, token } = await ctxGuild(agentId, p.guildNodeId);
@@ -323,7 +323,7 @@ export function registerFabricTools(
includeClosed: { type: 'boolean', description: 'default false — closed channels filtered out' },
},
},
execute: async (p: {
execute: async (_id: string, p: {
guildNodeId: string;
nameFilter?: string;
xType?: string;
@@ -387,7 +387,7 @@ export function registerFabricTools(
},
},
},
execute: async (p: { nameFilter?: string; purposeFilter?: string }) => {
execute: async (_id: string, p: { nameFilter?: string; purposeFilter?: string }) => {
const agentId = ctx.agentId;
if (!agentId) return { ok: false, error: 'no agent context' };
const entry = identity.findByAgentId(agentId);
@@ -442,7 +442,7 @@ export function registerFabricTools(
},
},
},
execute: async (p: { guildNodeId: string; channelId: string; purpose: string }) => {
execute: async (_id: string, p: { guildNodeId: string; channelId: string; purpose: string }) => {
const agentId = ctx.agentId;
if (!agentId) return { ok: false, error: 'no agent context' };
const { guild, token } = await ctxGuild(agentId, p.guildNodeId);
@@ -483,7 +483,7 @@ export function registerFabricTools(
limit: { type: 'integer', minimum: 1, maximum: 200, description: 'default 20' },
},
},
execute: async (p: {
execute: async (_id: string, p: {
guildNodeId: string;
channelId: string;
seqFrom?: number;