send images to opencode, which never needed the fork
B4 properly. The composer gate was the honest stopgap; this is the fix. opencode run takes attachments with --file, so images work on the subprocess path we already use — the parity doc had them down as phase 4, behind the serve migration, and they were not. The bug was one omission: handleOpenCodeChat`s msg type had no images field, so the browser sent them, the bubble rendered them, and they stopped at that signature. Nothing reported a loss anywhere. Attachments are paths, not inline data, so the sidecar spills each image to a temp file for the length of the turn and removes it in settle — the same place every other per-turn resource is released, so a killed or superseded turn cleans up too. The load-bearing detail is `--` before the prompt: --file is an array option, so without the separator the prompt is eaten as another filename and the turn dies with "File not found:" followed by the entire message. Confirmed against the binary, and pinned by a test that records argv from a stub. list-models now reports each model own capability instead of a hardcoded false — opencode publishes capabilities.input.image per model and nothing had ever read it. Defaults to false, so a model that does not declare it keeps the affordance hidden. Verified end to end: a red png sent over the chat socket to opencode/claude-sonnet-4-6 came back "Red". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -197,6 +197,14 @@ export type OpenCodeRunParams = {
|
||||
cwd?: string; // passed to `opencode run --dir` — hard-re-anchors tools to this directory
|
||||
model?: string; // `providerID/modelID` (e.g. opencode/claude-haiku-4-5); passed to --model verbatim
|
||||
resumeSessionId?: string; // OpenCode `ses_…` id to continue (`--session`)
|
||||
/**
|
||||
* Images for this turn, base64 as the browser sent them.
|
||||
*
|
||||
* `opencode run` takes attachments as PATHS (`-f`), not inline data, so the sidecar writes each one to
|
||||
* a temp file and deletes it when the turn ends. They travel as data because that is what crosses the
|
||||
* websocket from the browser, and because officer and the sidecar are not guaranteed to share a disk.
|
||||
*/
|
||||
images?: PromptImage[];
|
||||
durable?: boolean; // commit turn output to chat_session_events (default true) — see ClaudeSpawnStreamingParams
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user