1jehuang / 1jehuang/jcode

Pasted images are never rendered in the transcript, only the [image N] placeholder

Open
#1,207 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: no bug triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Summary

Paste an image and press Enter: the transcript only ever shows the literal [image N] placeholder. The bytes do reach the model, but nothing renders, so there is no way to confirm which image was actually attached.

Images coming back the other way (tool results, generated images) already render inline, so the two directions behave inconsistently.

This is a UX gap rather than a defect. Filing it because the rendering machinery is already fully in place and unused, which makes it look intentional when reading the code.

Environment

  • macOS 15, aarch64
  • jcode v0.84.0 and current master

What already exists

Everything needed is present:

  • RenderedImageSource::UserInput — the variant for exactly this case
  • RenderedImageAnchor::UserPrompt { ordinal } — the anchor for exactly this case
  • resolve_anchored_items_inner buckets by prompt ordinal (by_prompt)
  • render_message_into emits those buckets under the user's message
  • the server-side history renderer (session/render.rs) does anchor user images via image_anchor_for_message

The gap

Nothing pushes a RenderedImage for the images the client just submitted.

submit_input takes pending_images, sends them to the provider, and stores them on the session, but never adds a rendered image for the live transcript. A remote client only rebuilds remote_side_pane_images from a full History payload, so the attachment stays invisible for the whole turn even though the model received it.

Net effect: the persisted session knows the image belongs to that prompt, but the live view never shows it.

Suggested fix

Echo the submitted images as RenderedImage { source: UserInput, anchor: UserPrompt { ordinal } } right after the user's DisplayMessage is pushed, in both paths that consume pending_images:

  • submit_input (local turns)
  • submit_prepared_remote_input (remote turns)

Two details that cost me a debugging cycle, in case they help:

  1. The ordinal must be counted the way the renderer counts it: rendered user display messages, excluding synthetic attached-image label messages, matching prepare_body_incremental and session/render.rs.
  2. compacted_hidden_user_prompts() must not be added. It offsets the human-visible prompt number, not the anchor, which is relative to the rendered window. Adding it pushes every image past its real bucket. I got this wrong first.

The local side_pane_images merge dedupes on (media_type, data), so echoing before the turn is persisted does not double-render.

Branch, if useful as a reference: https://github.com/aphelion31/jcode/tree/fix/macos-clipboard-image-applescript

Tests cover presence, payload identity, per-prompt ordinal advance (a fixed ordinal stacks turn 2 under turn 1), and that a text-only turn fabricates nothing. All three fail against the unpatched submit paths.

Not covered

stage_turn_for_remote_tick_loop (queued / interleave sends) still echoes nothing. Those hand the images to process_remote_followups, which owns its own user-message echo, so wiring that up wants its own change rather than a second echo site.

Note

Filing as an issue rather than a PR because pull_request_creation_policy is collaborators_only, so CreatePullRequest is rejected for non-collaborators. Happy to open one if that changes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at submit_input and submit_prepared_remote_input, then read session/render.rs and the existing ordinal logic in prepare_body_incremental. Verify how pending_images and RenderedImageSource::UserInput are handled, and run the tests described in the issue. Done means submitted images render under the correct user prompt in both local and remote turns without fabricating images for text-only turns.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.