Summary
Add a channel-neutral outbound artifact delivery guard that turns validated generated file/media references into real attachments and strips unsafe raw path/directive text from the final chat.
Problem to solve
File-generating agent workflows can end with text such as MEDIA:./exports/report.xlsx, File: /workspace/exports/report.xlsx, file://..., or structured assistant content/metadata that carries media URLs separately from final prose. If that path is not normalized and delivered through the channel attachment path, the user may see a raw local path or a claim that a file was attached when no attachment was actually sent.
Prompt-only guidance and per-skill conventions are not enough because this is a final-mile transport invariant: the system needs to know whether the attachment actually delivered before deciding whether to strip, keep, or replace the final text.
Proposed solution
Introduce an upstream, generic guard/hook near outbound reply rendering and channel delivery:
- Inspect assistant final text, structured text blocks, and parsed media metadata for local generated-artifact references.
- Validate references against narrow configurable roots, e.g. workspace exports plus explicit generated-media roots.
- Deliver validated artifacts through the existing channel attachment/media adapter.
- Strip raw
MEDIA:/local-path delivery text only after concrete send success.
- On delivery failure, avoid silently claiming success; emit a safe user-facing failure payload and retain useful logs/metadata for debugging.
- Cover with a synthetic channel test that exercises raw text, structured text blocks, metadata media, success stripping, and failure fallback.
This should stay channel-neutral. Telegram can be one supported channel, but the core behavior should not be a Telegram-specific patch.
Alternatives considered
- Prompt instructions: cheap but unreliable; models and skills still leak raw paths.
- Per-skill wrappers only: helpful, but any new skill/tool can miss the contract.
- Telegram-only middleware: fixes one transport while leaving the same bug class in other channels.
- Leaving raw paths in final text: debuggable for developers, but wrong for end users and unsafe for hosted/sandboxed paths.
Impact
Affected users/systems/channels:
- Agents that create documents, images, audio, PDFs, spreadsheets, or other artifacts.
- Multi-channel deployments where the same agent can answer over Telegram, Slack, web chat, or other transports.
Severity: medium to high for artifact-heavy workflows because users can believe a file was sent when it was not, or receive unusable local paths.
Frequency: intermittent but recurring in workflows where tools emit final text plus file paths/media directives.
Consequence: failed deliveries, raw local path leakage, extra manual re-uploading, and brittle per-skill workarounds.
Evidence/examples
In a private OpenClaw deployment, a downstream guard proved useful by catching these cases before final chat delivery:
- raw text
MEDIA:./exports/...
- final text blocks containing
MEDIA:
- parsed
metadata.mediaUrls
- local-path claims such as
Archivo: /workspace/exports/file.xlsx
- audio plus document delivery in the same assistant message
The implementation is deployment-specific today, so I am opening this as an upstream design issue first rather than proposing a direct copy into core.
Additional information
This pairs well with transcript hygiene: raw delivery directives are transport instructions, not durable assistant prose. A follow-up PR could start with a small generic parser/guard and synthetic-channel tests once the maintainers agree on the hook location.
Summary
Add a channel-neutral outbound artifact delivery guard that turns validated generated file/media references into real attachments and strips unsafe raw path/directive text from the final chat.
Problem to solve
File-generating agent workflows can end with text such as
MEDIA:./exports/report.xlsx,File: /workspace/exports/report.xlsx,file://..., or structured assistant content/metadata that carries media URLs separately from final prose. If that path is not normalized and delivered through the channel attachment path, the user may see a raw local path or a claim that a file was attached when no attachment was actually sent.Prompt-only guidance and per-skill conventions are not enough because this is a final-mile transport invariant: the system needs to know whether the attachment actually delivered before deciding whether to strip, keep, or replace the final text.
Proposed solution
Introduce an upstream, generic guard/hook near outbound reply rendering and channel delivery:
MEDIA:/local-path delivery text only after concrete send success.This should stay channel-neutral. Telegram can be one supported channel, but the core behavior should not be a Telegram-specific patch.
Alternatives considered
Impact
Affected users/systems/channels:
Severity: medium to high for artifact-heavy workflows because users can believe a file was sent when it was not, or receive unusable local paths.
Frequency: intermittent but recurring in workflows where tools emit final text plus file paths/media directives.
Consequence: failed deliveries, raw local path leakage, extra manual re-uploading, and brittle per-skill workarounds.
Evidence/examples
In a private OpenClaw deployment, a downstream guard proved useful by catching these cases before final chat delivery:
MEDIA:./exports/...MEDIA:metadata.mediaUrlsArchivo: /workspace/exports/file.xlsxThe implementation is deployment-specific today, so I am opening this as an upstream design issue first rather than proposing a direct copy into core.
Additional information
This pairs well with transcript hygiene: raw delivery directives are transport instructions, not durable assistant prose. A follow-up PR could start with a small generic parser/guard and synthetic-channel tests once the maintainers agree on the hook location.