← Back to PRs

#22781: fix(webchat): persist chat attachments after guards and expose media paths

by Kansodata open 2026-02-21 17:21 View on GitHub →
app: web-ui gateway size: M
## Summary - Problem: `chat.send` webchat attachments were previously exposed to the agent as inline base64 blocks only, and persistence happened before request guards. - Why it matters: this breaks file-path-based media workflows and can create unnecessary temp files for requests that are later blocked/deduped. - What changed: - Persist attachments only after policy/idempotency/request guards pass. - Return `MediaPath`/`MediaPaths` and `MediaType`/`MediaTypes` in context while still passing inline images for model vision input. - Add/expand gateway tests for persisted media-path behavior. - Scope boundary: only gateway webchat attachment flow (`chat.send`) and related tests. ## Change Type - [x] Bug fix - [ ] Feature - [ ] Refactor - [ ] Docs - [ ] Security hardening - [ ] Chore/infra ## Scope - [ ] Gateway / orchestration - [x] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [ ] Integrations - [x] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Related #22314 (split into focused PRs for faster review) ## Repro + Verification - `pnpm vitest run src/gateway/chat-attachments.test.ts` - `pnpm check` ## Compatibility / Migration - Backward compatible: Yes - Config/env changes: No - Migration needed: No ## Security Impact - New permissions/capabilities: No - Secrets/tokens handling changed: No - New/changed network calls: No - Command/tool execution surface changed: Yes (context includes persisted media paths) - Data access scope changed: No <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR moves webchat attachment parsing and persistence to occur **after** policy, idempotency, and request guards, preventing unnecessary file I/O for blocked requests. The change adds `MediaPath`/`MediaPaths` and `MediaType`/`MediaTypes` to the agent context, enabling file-path-based media workflows while maintaining backward compatibility by still passing inline base64 images for vision models. - Moved `parseMessageWithAttachments` call in `chat.ts` from before guards (line 751) to after all guards pass (line 809-824) - Added `persistImagesToDisk: true` flag when calling `parseMessageWithAttachments` to enable file persistence - Persisted files use secure permissions (0o600) and are written to a safe tmp directory - Agent context now includes both inline images (for model vision) and persisted file paths (for file-based tools) - Added comprehensive test coverage for the persistence behavior in both unit and e2e tests <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk - The changes are well-architected with proper security considerations (file permissions, path sanitization), comprehensive test coverage (both unit and e2e tests), and clear separation of concerns. The move of attachment parsing after guards is a logical improvement that prevents wasted resources. No breaking changes or security vulnerabilities introduced. - No files require special attention <sub>Last reviewed commit: 368be6b</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs