opencode-plugin-image-attachment
v1.0.0
Published
OpenCode plugin: intercept image attachments and delegate to a multimodal sub-agent when the primary model cannot read images
Maintainers
Readme
opencode-plugin-image-attachment
OpenCode plugin that intercepts image attachments and delegates visual analysis to a multimodal sub-agent when the primary model cannot read images.
Problem
Your primary OpenCode agent (e.g. deepseek-v4-flash, glm-5.2) may not support image input. When a user pastes or uploads a screenshot, the model either errors out or sees nothing useful. This plugin:
- Detects image parts in incoming messages (base64 data URLs, file attachments with image MIME types,
.png/.jpg/etc. filenames). - Saves the image bytes to
.opencode/images/<sessionID>/so a multimodal sub-agent can read them later. - Replaces the raw image data with a text prompt telling the primary agent: "There's an image here, delegate to the vision-capable agent."
- Cleans up images older than 1 hour every 10 minutes.
Installation
Local install (from npm)
opencode plugin add opencode-plugin-image-attachmentLocal install (from source / GitHub)
Clone or download the plugin, then reference it in your opencode.jsonc:
{
"plugin": [
"./path/to/opencode-plugin-image-attachment/index.js"
]
}Prerequisites
You need a multimodal sub-agent configured in your OpenCode setup.
The plugin does not create one — it only tells the primary agent which agent to delegate to.
Example agent definition for AGENTS.md (or your agent config):
# multimodal-looker
Visual analysis specialist. Reads images, screenshots, charts, and other visual content.
## Tools
- read
- glob
- grep
- compress
## Constraint
No bash, no file edits. Purely a "look at the picture and describe it" role.Configuration
Configure the plugin in opencode.jsonc via the plugin entry:
{
"plugin": [
{
"name": "opencode-plugin-image-attachment",
"config": {
"targetAgent": "Observer",
"maxAge": 3600000,
"cleanupInterval": 600000
}
}
]
}| Option | Type | Default | Description |
|--------|------|---------|-------------|
| targetAgent | string | "multimodal-looker" | Name of the sub-agent that handles image analysis |
| maxAge | number | 3600000 (1h) | Image file TTL in milliseconds |
| cleanupInterval | number | 600000 (10min) | How often cleanup sweeps run in ms |
| promptTemplate | string | (built-in) | Custom prompt template. Placeholders: {paths}, {targetAgent}, {count} |
Via environment variable
Set OPENCODE_IMAGE_AGENT to override the target agent without editing config:
$env:OPENCODE_IMAGE_AGENT="Observer"Prompt template
Default template:
[Image attachment detected. Saved to: {paths}. The primary model cannot read images. Delegate visual analysis ({targetAgent}) when the user asks anything about this image: reading, seeing, OCR, describing, or analyzing.]Customize it:
{
"config": {
"promptTemplate": "[图 {count} 张已保存至 {paths},交给 {targetAgent} 处理]"
}
}How it works
User sends image
│
▼
Plugin hook (experimental.chat.messages.transform)
│
├── Detect: image type / MIME / extension?
│ └─ no → pass through, nothing changed
│
├── Decode base64 data URL
├── Save to .opencode/images/<sessionID>/<name>-<sha1[:8]><ext>
│
└── Replace image part(s) with text prompt:
"[Image attachment detected... Delegate to {targetAgent}]"
│
▼
Primary agent sees the prompt
and (if well-configured) spawns
the multimodal sub-agent to analyzePublishing to npm
# login
npm login
# publish
npm publish
# update version
npm version patch # or minor / major
npm publishLicense
MIT
