Skip to content

feat: isolate inbound media storage per agent - #194

Open
DREAMDREAM66 wants to merge 1 commit into
Tencent:mainfrom
DREAMDREAM66:feature/wecom-per-agent-workspace
Open

feat: isolate inbound media storage per agent#194
DREAMDREAM66 wants to merge 1 commit into
Tencent:mainfrom
DREAMDREAM66:feature/wecom-per-agent-workspace

Conversation

@DREAMDREAM66

@DREAMDREAM66 DREAMDREAM66 commented Jun 12, 2026

Copy link
Copy Markdown

Problem

All inbound media files (images, videos, files, voice) from WeChat users are saved to a single flat directory (~/.openclaw/media/inbound/). When multiple agents are configured, files from different agents are mixed together with no way to tell which agent received which file.

Motivation

I maintain an internal OpenClaw deployment for my company's IT department. Recently, many colleagues have started using OpenClaw with WeChat, and we encountered a critical issue:

  • Agent A receives a contract file from WeChat
  • Agent B receives an invoice file
  • Both files land in ~/.openclaw/media/inbound/
  • Agent A may read Agent B's file, causing confusion and potential data leakage

I first tried to mitigate this via AGENTS.md rules, but that's fundamentally impossible — agents cannot be instructed to read from different folders when all files are co-located in a single flat directory.

After debugging, I identified the root cause in the WeChat plugin. I also examined the DingTalk plugin, which already implements per-agent media isolation. This PR gives the WeChat plugin similar per-agent separation to what DingTalk already has.

This fix would directly improve our production setup at work, and I believe many other multi-agent users would benefit as well.

Why this approach

The plugin uses OpenClaw's channelRuntime.media.saveMediaBuffer to persist inbound media. This SDK method manages the media store internally and does not expose the agent's workspace path — we cannot tell it to save directly to ~/.openclaw/agents/<id>/workspace.

The saveMediaBuffer API does accept a subdir parameter for organizing files within its media store. By resolving the agent route early and passing wecom/<agentId>/inbound as the subdirectory, we achieve per-agent file isolation with minimal code change — no SDK modification, no path traversal, no custom file copy logic.

Changes

  • src/messaging/process-message.ts: Move resolveAgentRoute before the media download step (it only depends on cfg, accountId, and from_user_id, all available before download). Construct mediaSubdir from the resolved agentId and pass it to downloadMediaFromItem.
  • src/media/media-download.ts: Accept an optional subdir parameter (defaults to "inbound" for backward compatibility). Use it instead of the
    hardcoded "inbound" in all saveMedia calls.

Before

~/.openclaw/media/inbound/.png

After

~/.openclaw/media/wecom/agentId/inbound/.png

Notes

  • When agentId cannot be resolved, falls back to the original "inbound" directory.
  • No new tests needed — both changed files are excluded from coverage thresholds, and existing tests pass.

Test Results

  • 366 passed, 6 failed (372 total)
  • 19 test files passed, 5 failed (24 total)
  • All 6 failures are pre-existing and unrelated to this change:
Test Cause
state-dir.test.ts > resolveStateDir > falls back to ~/.openclaw Windows path separator (\ vs /)
sync-buf.test.ts > getSyncBufFilePath > returns path under accounts dir Timeout (>5s)
account-index.test.ts > listIndexedWeixinAccountIds > returns empty array when file does not exist Timeout (>5s)
account-store.test.ts > loadWeixinAccount > returns null when no account file exists Timeout (>5s)
pairing.test.ts > resolveFrameworkAllowFromPath > returns correct path Timeout (>5s)
pairing.test.ts > registerUserInFrameworkStore > uses withFileLock Assertion (mock not called)

All failures are in src/auth/ and src/storage/ test files — none touch src/messaging/ or src/media/ where this change was made.

@NewFuture

Copy link
Copy Markdown

Thanks for raising the per-agent media-isolation problem. Preventing one agent from observing another agent's inbound files is important, and we would welcome an author-led port or redesign in the current community repository:

https://github.com/NewFuture/openclaw-weixin

For the current architecture, the PR should preserve sender authorization and routing order, use a channel-consistent and sanitized media subdirectory, confirm the OpenClaw media-store contract, and keep previously stored media accessible. Please also add regression coverage for multiple agents, rejected senders, unresolved routes, legacy paths, and account isolation rather than relying only on the existing suite.

Contribution guide:
https://github.com/NewFuture/openclaw-weixin/blob/main/CONTRIBUTING.md

For transparency, NewFuture/openclaw-weixin is a community-maintained distribution, not the official Tencent/Weixin release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants