Skip to content

feat(#3996): fall back to an explicit user-prompt filename for one unnamed image - #4027

Draft
aheritier wants to merge 2 commits into
workspace-media-escape-confirmfrom
workspace-media-naming
Draft

feat(#3996): fall back to an explicit user-prompt filename for one unnamed image#4027
aheritier wants to merge 2 commits into
workspace-media-escape-confirmfrom
workspace-media-naming

Conversation

@aheritier

@aheritier aheritier commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

What

Uses an explicit filename from the user prompt when exactly one generated image has no filename, with marker parsing and streaming coverage.

Why

Produces predictable, user-friendly names without guessing when the prompt supplies a clear name.

Validation

task test; filename extraction, marker, Gemini instruction, and streaming tests.

Test instructions

Run:

task test

Request exactly one unnamed generated image with an explicit filename in the user prompt. Expected: that filename is used. Repeat with an ambiguous prompt or multiple images; expected: the safe fallback naming behavior is retained.

Explicitly image-output-capable Gemini gateway requests now carry a
system instruction asking the model to emit one exact
"[media-file: relative/path]" line per generated image, echoing an
explicitly requested name or choosing a meaningful kebab-case one, and
to produce a single image unless variations are requested.

handleStream filters those marker lines out of both the live event
stream and the persisted assistant text with a chunk-split-safe,
strictly bounded line parser, then pairs the extracted paths
positionally onto the accumulated media blobs via
MediaDelta.RequestedPath. Naming precedence stays marker -> provider
display name -> generated-N, and marker paths remain untrusted input:
they flow through the existing workspacemedia classification, MIME
extension correction, escape elicitation/redirect, and never-overwrite
writer unchanged. Extra blobs still materialize under their fallback
names; extra markers are stripped but ignored.
…named image

A live image-output model can ignore the [media-file:] marker instruction
entirely, leaving a prompt like "Generate an image as sunshine.jpg" to land
as generated-1.png. Add a deterministic fallback: when a turn returns
exactly ONE media blob that marker pairing left unnamed, parse a single
unambiguous explicit output filename from the triggering user message.

The cue grammar is strict, deliberately not NLP: save (it) as / save to /
write to / output to / name it / call it / filename:=, plus bare "as" only
inside a narrow imperative output context (generation verb +
optionally-articled media noun, e.g. "Generate an image as sunshine.jpg"),
and a companion of-phrase form (generation verb + media noun +
"of <subject>" + "as <filename>") so "Generate an image of a red panda as
assets/red-panda.jpg" extracts the intended name. The of-phrase subject
cannot cross quotes, clause punctuation, or CR/LF, and any subject
containing "as", "with", or "in" is refused because those prepositions
introduce open-ended attribute phrases whose trailing "as" compares — a
false reject only costs the generic generated-N name, while a false
capture could engage the escape-confirmation policy for a merely
referenced file. Bare "called" and unanchored "as" are NOT cues, so
comparative references to existing files never extract a name. Candidates
are keyed by the filename capture's position: one occurrence matched by
both grammars counts once; distinct occurrences stay ambiguous and extract
nothing. Names may be quoted, backticked, or unquoted with a known image
extension; zero or multiple candidates extract nothing.

Precedence stays marker -> user-prompt filename -> provider display name ->
generic generated-N, and the extracted path only fills
MediaDelta.RequestedPath, so the existing untrusted-path pipeline
(MIME/extension correction, collision suffixing, workspace containment and
escape confirmation) applies unchanged.
@aheritier aheritier added area/providers/gemini Google Gemini provider support area/runtime Runtime engine, agent loop execution, tool dispatch, loop detection 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/providers/gemini Google Gemini provider support area/runtime Runtime engine, agent loop execution, tool dispatch, loop detection 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