fix(plugin): force automatic source-reply delivery (fixes no-reply)
OpenClaw defaults group-chat replies to sourceReplyDeliveryMode 'message_tool_only', which suppresses auto-delivery of the agent's text reply (it expects the agent to call a message tool). With ChatType 'group', the Fabric plugin's deliver callback was therefore NEVER invoked — the agent ran but no reply ever returned to Fabric. Fabric already gates *when* an agent speaks via the per-recipient wakeup flag, so once a turn is dispatched the reply must always flow back. Pass replyOptions.sourceReplyDeliveryMode='automatic' so OpenClaw delivers the agent's reply through regardless of the group default (source-reply-delivery-mode honors a truthy requested mode). Verified live end-to-end: human posts -> wakeup -> agent runs -> 'fabric: deliver' + 'fabric: posted reply' -> agent message appears in the Fabric channel. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
17
dist/fabric/src/inbound.js
vendored
17
dist/fabric/src/inbound.js
vendored
@@ -233,8 +233,21 @@ export class FabricInbound {
|
|||||||
},
|
},
|
||||||
onRecordError: (err) => this.log.warn(`fabric: session record failed agent=${agentId}: ${String(err)}`),
|
onRecordError: (err) => this.log.warn(`fabric: session record failed agent=${agentId}: ${String(err)}`),
|
||||||
onDispatchError: (err, info) => this.log.warn(`fabric: ${info.kind} dispatch failed agent=${agentId}: ${String(err)}`),
|
onDispatchError: (err, info) => this.log.warn(`fabric: ${info.kind} dispatch failed agent=${agentId}: ${String(err)}`),
|
||||||
// Fabric has no length limit: deliver the whole reply as ONE message.
|
// - disableBlockStreaming: Fabric has no length limit, deliver the
|
||||||
replyOptions: { disableBlockStreaming: true },
|
// whole reply as ONE message.
|
||||||
|
// - sourceReplyDeliveryMode 'automatic': OpenClaw defaults group
|
||||||
|
// chats to "message_tool_only", which SUPPRESSES auto-delivery of
|
||||||
|
// the agent's text reply (it expects the agent to call a message
|
||||||
|
// tool). Fabric already gates *when* an agent speaks via the
|
||||||
|
// per-recipient wakeup flag, so once a turn is dispatched the
|
||||||
|
// reply must always flow back through `deliver`. Forcing
|
||||||
|
// 'automatic' overrides the group default so the reply is
|
||||||
|
// delivered. (source-reply-delivery-mode: a truthy `requested`
|
||||||
|
// wins unless it's message_tool_only with no tool available.)
|
||||||
|
replyOptions: {
|
||||||
|
disableBlockStreaming: true,
|
||||||
|
sourceReplyDeliveryMode: 'automatic',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
this.log.info(`fabric: dispatch returned agent=${agentId} channel=${channelId}`);
|
this.log.info(`fabric: dispatch returned agent=${agentId} channel=${channelId}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -279,8 +279,21 @@ export class FabricInbound {
|
|||||||
this.log.warn(`fabric: session record failed agent=${agentId}: ${String(err)}`),
|
this.log.warn(`fabric: session record failed agent=${agentId}: ${String(err)}`),
|
||||||
onDispatchError: (err: unknown, info: { kind: string }) =>
|
onDispatchError: (err: unknown, info: { kind: string }) =>
|
||||||
this.log.warn(`fabric: ${info.kind} dispatch failed agent=${agentId}: ${String(err)}`),
|
this.log.warn(`fabric: ${info.kind} dispatch failed agent=${agentId}: ${String(err)}`),
|
||||||
// Fabric has no length limit: deliver the whole reply as ONE message.
|
// - disableBlockStreaming: Fabric has no length limit, deliver the
|
||||||
replyOptions: { disableBlockStreaming: true } as never,
|
// whole reply as ONE message.
|
||||||
|
// - sourceReplyDeliveryMode 'automatic': OpenClaw defaults group
|
||||||
|
// chats to "message_tool_only", which SUPPRESSES auto-delivery of
|
||||||
|
// the agent's text reply (it expects the agent to call a message
|
||||||
|
// tool). Fabric already gates *when* an agent speaks via the
|
||||||
|
// per-recipient wakeup flag, so once a turn is dispatched the
|
||||||
|
// reply must always flow back through `deliver`. Forcing
|
||||||
|
// 'automatic' overrides the group default so the reply is
|
||||||
|
// delivered. (source-reply-delivery-mode: a truthy `requested`
|
||||||
|
// wins unless it's message_tool_only with no tool available.)
|
||||||
|
replyOptions: {
|
||||||
|
disableBlockStreaming: true,
|
||||||
|
sourceReplyDeliveryMode: 'automatic',
|
||||||
|
} as never,
|
||||||
});
|
});
|
||||||
this.log.info(`fabric: dispatch returned agent=${agentId} channel=${channelId}`);
|
this.log.info(`fabric: dispatch returned agent=${agentId} channel=${channelId}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user