Skip to content

feat(#3996): render generated images inline via manifest-gated resolution - #4029

Draft
aheritier wants to merge 1 commit into
gemini-direct-image-outputfrom
generated-image-inline-tui
Draft

feat(#3996): render generated images inline via manifest-gated resolution#4029
aheritier wants to merge 1 commit into
gemini-direct-image-outputfrom
generated-image-inline-tui

Conversation

@aheritier

@aheritier aheritier commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

What

Renders generated images inline in the TUI through manifest-gated file resolution, with runtime events, app state, and component coverage.

Why

Users can inspect generated images directly in chat while resolution remains restricted to known session manifest entries.

Validation

task test; generated-file, runtime, message, TUI component, and chat tests.

Test instructions

Run:

task test

Start a TUI session, generate an image, and inspect the chat. Expected: the generated image renders inline. Attempt to reference an unmanifested path; expected: it is not resolved or displayed.

…tion

Render model-generated images inline in the same assistant turn (with a
filename-only fallback on non-graphics terminals), resolving strictly
through LocalRuntime.ResolveGeneratedFile: one recorded reference resolves
to bytes plus a validated canonical path, gated on the generated-media
manifest, the owning session's persisted WorkingDir (bounded parent
fallback, never the viewer cwd), os.Root containment, and symlink-free
path components — a forged DocumentSource or a symlink swapped in after
materialization selects nothing. Per-owner roots and manifest records are
cached on the runtime and seeded at materialization.

The chat page attaches a sanitized "unavailable" placeholder synchronously
and resolves inside a routed tea.Cmd — never in Update — then swaps
results in by ID, for live MessageAddedEvents and for restored session
messages. Successful resolution shows the canonical workspace path in the
non-graphics fallback; every failure (missing, replaced, tampered,
unknown root kind, unrecorded) degrades to the filename-only wording. Runtimes
without the capability (remote) render nothing.

TUI regression tests pin that same-turn labels and fallbacks come from the
final persisted Document name and the resolver-validated canonical
workspace path (including collision-suffixed names) — the TUI never
constructs paths or sees provisional MediaDelta names.
@aheritier aheritier added area/agent For work that has to do with the general agent loop/agentic features of the app area/runtime Runtime engine, agent loop execution, tool dispatch, loop detection area/tui For features/issues/fixes related to the TUI kind/feat PR adds a new feature (maps to feat:). Use on PRs only. labels Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent For work that has to do with the general agent loop/agentic features of the app area/runtime Runtime engine, agent loop execution, tool dispatch, loop detection area/tui For features/issues/fixes related to the TUI kind/feat PR adds a new feature (maps to feat:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant