openclaw/src
fuller-stack-dev c9449d77b4
feat(gateway): persist webchat inbound images to disk (#51324)
* feat(gateway): persist webchat inbound images to disk

Images sent via the webchat control UI (chat.send RPC) were parsed into
content blocks but never written to disk, unlike WhatsApp and Telegram
handlers which call saveMediaBuffer(). This caused:

- Images lost after conversation compaction (only existed as ephemeral base64)
- Image editing/generation workflows failing for webchat-origin images
- Incomplete ~/.openclaw/media/inbound/ directory

After parseMessageWithAttachments extracts parsedImages, iterate and
persist each via saveMediaBuffer(buffer, mimeType, 'inbound'). Uses
fire-and-forget (.catch + warn log) so disk I/O never blocks the
chat.send response path.

Fixes #47930

* fix(gateway): address PR review comments on webchat image persistence

- Move saveMediaBuffer calls after sendPolicy/stop/dedupe checks so
  rejected or retried requests don't write files to disk (Codex P1)
- Await all saves and collect SavedMedia results into persistedImages
  so the persisted paths are available in scope (Greptile P1)
- Preserve Error stack trace in warn log instead of coercing to
  toString() (Greptile P2)
- Switch to Promise.all for concurrent writes

* fix(gateway): address remaining review comments on webchat image persistence

- Revert to fire-and-forget pattern (no await) to eliminate race window
  where retried requests miss the in-flight guard during image saves
- Remove unused SavedMedia import and persistedImages collection
- Use formatForLog for consistent error logging with stack traces
- Add NOTE comment about path propagation being a follow-up task

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(gateway): gate image persistence to webchat callers and defer base64 decode

* fix: drop unrelated format churn in lifecycle.test.ts

* gateway: clarify image persistence scope covers all chat.send callers

* fix(gateway): use generic chat.send log prefix for image persistence warnings

* fix(gateway): persist chat.send image refs in transcript

* fix(gateway): keep chat.send image refs off visible text

* fix(gateway): persist chat send media refs on dispatch

* fix(gateway): serialize chat send image persistence

* fix(gateway): persist chat send media after dispatch

* fix: persist chat.send inbound images across follow-ups (#51324) (thanks @fuller-stack-dev)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-21 19:05:11 +05:30
..
acp test: trim plugin-heavy unit test imports 2026-03-20 18:35:39 +00:00
agents feat(github-copilot): resolve any model ID dynamically (#51325) 2026-03-21 17:37:50 +05:30
auto-reply fix(agents): register simple completion transports 2026-03-21 17:22:31 +05:30
bindings
browser
canvas-host
channels test: trim more extension startup from unit tests 2026-03-20 19:28:32 +00:00
cli pairing: keep setup codes bootstrap-token only (#51259) 2026-03-20 13:27:39 -07:00
commands CLI: respect full timeout for loopback gateway probes (#47533) 2026-03-21 10:57:50 +05:30
compat
config fix: trim config validation startup imports (#51574) 2026-03-21 09:31:39 -04:00
context-engine feat(context-engine): pass incoming prompt to assemble (#50848) 2026-03-20 17:03:21 -07:00
cron test: trim singleton cold-start reloads 2026-03-20 23:14:28 +00:00
daemon
docs
gateway feat(gateway): persist webchat inbound images to disk (#51324) 2026-03-21 19:05:11 +05:30
hooks fix(ci): stabilize bundle hooks and mcp path seams 2026-03-19 14:26:52 -07:00
i18n
image-generation test(openai): cover bundle media surfaces 2026-03-20 15:53:12 -07:00
infra iOS: improve QR pairing flow (#51359) 2026-03-21 01:10:29 -05:00
interactive refactor: deduplicate reply payload handling 2026-03-18 18:14:57 +00:00
line LINE: harden Express webhook parsing to verified raw body (#51202) 2026-03-20 15:32:55 -05:00
link-understanding
logging fix: stabilize windows temp and path handling 2026-03-18 23:29:14 -05:00
markdown
media Gateway: harden OpenResponses file-context escaping (#50782) 2026-03-19 22:02:13 -05:00
media-understanding test: trim singleton cold-start reloads 2026-03-20 23:14:28 +00:00
memory fix(ci): reduce test runtime retention hotspots 2026-03-19 14:49:01 -07:00
node-host test: align extension runtime mocks with plugin-sdk (#51289) 2026-03-20 15:59:53 -07:00
pairing pairing: keep setup codes bootstrap-token only (#51259) 2026-03-20 13:27:39 -07:00
plugin-sdk feat(telegram): auto-rename DM topics on first message (#51502) 2026-03-21 16:53:30 +05:30
plugins fix: trim config validation startup imports (#51574) 2026-03-21 09:31:39 -04:00
process
providers refactor: shrink sdk helper surfaces 2026-03-20 15:43:14 +00:00
routing
scripts fix(ci): share compat matrix and restore skill python gating 2026-03-20 00:27:50 -07:00
secrets test: align extension runtime mocks with plugin-sdk (#51289) 2026-03-20 15:59:53 -07:00
security test: parallelize safe audit case tables 2026-03-20 21:16:01 +00:00
sessions Session management improvements and dashboard API (#50101) 2026-03-19 12:12:30 +09:00
shared refactor(channels): share route format and binding helpers 2026-03-20 09:30:34 -07:00
terminal refactor: replace "seam" terminology across codebase 2026-03-18 00:20:15 -07:00
test-helpers
test-utils
tts fix(agents): register simple completion transports 2026-03-21 17:22:31 +05:30
tui fix(tui): split assistant error formatting seam 2026-03-20 00:06:12 -07:00
types fix(pi): align package graph and declare compaction summaries 2026-03-19 11:02:18 -07:00
utils fix(config): share json compatibility parsing 2026-03-20 10:17:53 -07:00
web-search Web: derive search provider metadata from plugin contracts (#50935) 2026-03-20 12:41:04 -07:00
whatsapp
wizard test: drop duplicate web search helper 2026-03-20 20:25:24 +00:00
bundled-web-search-registry.ts test: align extension runtime mocks with plugin-sdk (#51289) 2026-03-20 15:59:53 -07:00
channel-web.ts refactor: untangle whatsapp runtime boundary 2026-03-19 03:13:48 +00:00
docker-build-cache.test.ts
docker-image-digests.test.ts
docker-setup.e2e.test.ts refactor(scripts): move container setup entrypoints 2026-03-19 13:40:26 -07:00
dockerfile.test.ts Stabilize plugin loader and Docker extension smoke (#50058) 2026-03-18 23:35:32 -05:00
entry.test.ts
entry.ts
entry.version-fast-path.test.ts
extensionAPI.test.ts restore extension-api backward compatibility with migration warning 2026-03-20 13:27:30 -05:00
extensionAPI.ts restore extension-api backward compatibility with migration warning 2026-03-20 13:27:30 -05:00
globals.ts
index.test.ts fix: isolate CLI startup imports (#50212) 2026-03-19 10:34:29 +05:30
index.ts fix: isolate CLI startup imports (#50212) 2026-03-19 10:34:29 +05:30
install-sh-version.test.ts
library.ts refactor: untangle whatsapp runtime boundary 2026-03-19 03:13:48 +00:00
logger.test.ts
logger.ts
logging.ts
param-key.ts
poll-params.test.ts
poll-params.ts
polls.test.ts
polls.ts
runtime.ts
utils.test.ts
utils.ts
version.test.ts
version.ts