openclaw - ✅(Solved) Fix feat: pass requesterSenderId and senderIsOwner to ChannelAgentToolFactory [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#58806Fetched 2026-04-08 02:32:29
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Author
Participants
Timeline (top)
referenced ×2cross-referenced ×1

Fix Action

Fixed

PR fix notes

PR #58808: feat: pass requesterSenderId and senderIsOwner to ChannelAgentToolFactory

Description (problem / solution / changelog)

Summary

Pass trusted sender context (requesterSenderId and senderIsOwner) to ChannelAgentToolFactory, enabling channel plugins to implement sender-aware access control in their agent tools.

Problem

listChannelAgentTools() only passes { cfg } to channel agent tool factories, while the immediately following createOpenClawTools() call in the same function receives the full sender context. This gap means channel-registered agent tools cannot distinguish between different senders.

Changes

3 files changed, +17 / -3

src/channels/plugins/types.core.ts

  • Extended ChannelAgentToolFactory params type to include requesterSenderId?: string | null and senderIsOwner?: boolean

src/agents/channel-tools.ts

  • Updated listChannelAgentTools function signature to accept the new fields
  • These are already forwarded to the factory via entry(params)

src/agents/pi-tools.ts

  • Pass options?.senderId and options?.senderIsOwner from the existing options object into listChannelAgentTools()

Backward Compatibility

Fully backward compatible. Existing factories that only destructure { cfg } will simply ignore the new optional fields. No changes required for any existing channel plugin.

Use Case

The DMWork channel plugin needs sender-aware agent tools where:

  • Any user can query their own DM history with the bot
  • Any user can query groups they are a member of
  • Only the bot owner can query other users' DM history

Without sender context in the factory, the plugin must choose between ownerOnly: true (too restrictive) or no access control (too permissive).

Closes #58806

Changed files

  • src/agents/channel-tools.ts (modified, +5/-1)
  • src/agents/pi-tools.ts (modified, +5/-1)
  • src/channels/plugins/types.core.ts (modified, +7/-1)

Code Example

// pi-embedded (line ~119112)
...listChannelAgentTools({ cfg: options?.config }),

---

...createOpenClawTools({
  // ...
  requesterSenderId: options?.senderId,
  senderIsOwner: options?.senderIsOwner,
  // ...
})

---

export type ChannelAgentToolFactory = (params: {
  cfg?: OpenClawConfig;
  requesterSenderId?: string | null;  // new
  senderIsOwner?: boolean;            // new
}) => ChannelAgentTool[];

---

// In the tool composition function
...listChannelAgentTools({
  cfg: options?.config,
  requesterSenderId: options?.senderId,
  senderIsOwner: options?.senderIsOwner,
}),

---

function listChannelAgentTools(params) {
  const tools = [];
  for (const plugin of listChannelPlugins()) {
    const entry = plugin.agentTools;
    if (!entry) continue;
    const resolved = typeof entry === "function" ? entry(params) : entry;
    if (Array.isArray(resolved)) tools.push(...resolved);
  }
  return tools;
}
RAW_BUFFERClick to expand / collapse

Problem

listChannelAgentTools() currently only passes { cfg } to the ChannelAgentToolFactory:

// pi-embedded (line ~119112)
...listChannelAgentTools({ cfg: options?.config }),

However, in the same function, the immediately following createOpenClawTools() call receives the full context including senderId and senderIsOwner:

...createOpenClawTools({
  // ...
  requesterSenderId: options?.senderId,
  senderIsOwner: options?.senderIsOwner,
  // ...
})

This means channel-registered agent tools (via ChannelPlugin.agentTools) have no access to sender identity, while core tools do.

Impact

Channel plugins that register agent tools cannot implement sender-aware access control. The only available mechanism is the binary ownerOnly: true flag, which is too coarse for tools that need per-sender permission logic (e.g., "user can query their own DM history but not others'").

The handleAction path on the message tool does receive requesterSenderId via ChannelMessageActionContext, but that path is constrained by the hardcoded CHANNEL_MESSAGE_ACTION_NAMES whitelist, making it unsuitable for new custom actions.

Proposed Fix

1. Extend ChannelAgentToolFactory type

export type ChannelAgentToolFactory = (params: {
  cfg?: OpenClawConfig;
  requesterSenderId?: string | null;  // new
  senderIsOwner?: boolean;            // new
}) => ChannelAgentTool[];

2. Pass the context at the call site

// In the tool composition function
...listChannelAgentTools({
  cfg: options?.config,
  requesterSenderId: options?.senderId,
  senderIsOwner: options?.senderIsOwner,
}),

3. Forward in listChannelAgentTools

function listChannelAgentTools(params) {
  const tools = [];
  for (const plugin of listChannelPlugins()) {
    const entry = plugin.agentTools;
    if (!entry) continue;
    const resolved = typeof entry === "function" ? entry(params) : entry;
    if (Array.isArray(resolved)) tools.push(...resolved);
  }
  return tools;
}

Since params is already forwarded to the factory, extending the type and the call site is all that is needed.

Use Case

The DMWork channel plugin needs to register a cross-session message query tool where:

  • Any user can query their own DM history with the bot
  • Any user can query groups they are a member of
  • Only the bot owner can query other users' DM history

Without sender context in the factory, the plugin cannot create tools with sender-aware closures and must fall back to either ownerOnly: true (too restrictive) or no access control (too permissive).

Backward Compatibility

Fully backward compatible. Existing factories that only destructure { cfg } will simply ignore the new fields.

extent analysis

TL;DR

To fix the issue, extend the ChannelAgentToolFactory type to include requesterSenderId and senderIsOwner, and pass these parameters when calling listChannelAgentTools.

Guidance

  • Extend the ChannelAgentToolFactory type to include requesterSenderId and senderIsOwner as optional parameters.
  • Update the listChannelAgentTools call site to pass requesterSenderId and senderIsOwner in addition to cfg.
  • Verify that existing factories are not broken by the change, as they will ignore the new fields if not used.
  • Test the fix with a channel plugin that requires sender-aware access control, such as the DMWork channel plugin.

Example

export type ChannelAgentToolFactory = (params: {
  cfg?: OpenClawConfig;
  requesterSenderId?: string | null;
  senderIsOwner?: boolean;
}) => ChannelAgentTool[];

Notes

The proposed fix is fully backward compatible, as existing factories will ignore the new fields if not used. However, it's essential to test the fix thoroughly to ensure that it works as expected and does not introduce any new issues.

Recommendation

Apply the proposed workaround by extending the ChannelAgentToolFactory type and updating the listChannelAgentTools call site, as it provides the necessary sender context for channel plugins to implement sender-aware access control without breaking existing functionality.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix feat: pass requesterSenderId and senderIsOwner to ChannelAgentToolFactory [1 pull requests, 1 participants]