kilo-vision-bridge
v0.1.4
Published
Dynamic visual-response skill for Kilo. Registers the native vision_analyze tool (model configured by the user via the Kilo Code agent model override on vision-agent) with the vision-agent subagent as fallback, and teaches a text-only orchestrator to extr
Maintainers
Readme
Kilo Vision Bridge
Disclaimer: Kilo Vision Bridge is an independent, community-built project. It is not built by, endorsed by, or affiliated with the Kilo team. It is a port of wezzard/opencode-vision (MIT) to the Kilo plugin SDK, and builds on its design.
Introduction
Give text-only Kilo orchestrators (GLM-5.2, DeepSeek, and similar models) eyes by delegating visual tasks to a vision-capable model through a dynamically registered vision subagent.
When the orchestrator model is text-only and a task needs pixels — not just accessibility metadata — the plugin's vision skill detects the visual intent, extracts a task-specific JSON response template, delegates the task, and parses the structured findings back into the conversation.
Tool-first architecture. Delegation targets a native plugin tool, vision_analyze, registered through the @kilocode/plugin tool hook. The tool runs the visual judgment in-process — it reads the listed image files and calls the configured vision model directly, so no subagent nesting is required and the tool works from any session, including subagent sessions (depth >= 1) where spawning a further subagent would be blocked by subagent_depth and the auto-denied task tool. The skill calls vision_analyze first and falls back to spawning the vision-agent subagent only when the tool is unavailable in the session or the call fails with a provider/protocol/HTTP error. With the tool path, subagent_depth / permission.task configuration is not needed for visual delegation.
Requirements
- Kilo 7.4+
- At least one configured provider with an image-capable model (
enabled_providersand/orproviderentries in Kilo config). The plugin discovers models from your configured providers and Kilo's cached model catalog (~/.cache/kilo/models.json) — it does not ship a fixed model list.
Installation
# install globally (available to all projects) — installs the package and patches the config
kilo plugin kilo-vision-bridge --global
# or install for the current project only
kilo plugin kilo-vision-bridgePin a specific version with kilo plugin kilo-vision-bridge@<version> (e.g. @0.1.3).
After install, restart Kilo. The plugin registers the vision-agent subagent and the vision_analyze tool on launch, and the vision skill is discovered straight from the installed package directory — no manual copy and no postinstall steps are needed.
Why the plugin entry lands in
opencode.json?kilo pluginwrites server-type plugin entries to~/.config/kilo/opencode.json(a legacy config filename, fully read by Kilo on every launch). This is Kilo's official installer behavior, not a bug. You can move the entry tokilo.jsoncif you prefer — both files are read and merged — but note that re-runningkilo plugin(e.g. to upgrade) will createopencode.jsonagain, since that is where the official installer manages entries.Where does the package itself live?
kilo plugindownloads and manages the package under~/.cache/kilo/packages/<name>@<tag>/— Kilo's own package store, by official design. Do not move or delete it manually; usekilo pluginfor upgrades (e.g.kilo plugin kilo-vision-bridge --global --force). The package store is a cache: clearing~/.cache/kiloonly forces a re-download on the nextkilo pluginrun.
Updating
Re-run the install command with --force to replace the currently installed version. --force is required for any re-install/upgrade (per kilo plugin --help: "replace existing plugin version"); without it kilo plugin reports Already configured and leaves the existing version loading. It is not specific to pinning a version.
# update to the latest version
kilo plugin kilo-vision-bridge --global --force
# or pin a specific version
kilo plugin kilo-vision-bridge@<version> --global --forceRestart Kilo afterwards; the config entry and the package store are both managed by the official installer, so there is nothing else to clean up manually (an orphaned kilo-vision-bridge@latest/ store dir from the previous install can be deleted safely).
Uninstalling
kilo plugin has no uninstall subcommand (Kilo's kilo uninstall removes Kilo itself, not plugins), so removal is manual — two steps:
- Remove the plugin entry from the config: delete
"kilo-vision-bridge"from thepluginarray in~/.config/kilo/opencode.json(orkilo.jsonc, wherever it lives). If the array becomes empty, remove the wholepluginkey. - Delete the installed package from Kilo's package store:
~/.cache/kilo/packages/kilo-vision-bridge@latest/.
Restart Kilo afterwards: the vision-agent subagent and vision_analyze tool disappear, and the vision skill is no longer listed.
Quick start
- Install with
kilo plugin kilo-vision-bridge --globaland restart Kilo. - Set the vision model (see below):
agent["vision-agent"].model = "<provider-id>/<model-id>"— use any vision-capable model from your configured providers. - Drag an image into the Kilo input box (or reference an image path) and ask a visual question. The orchestrator detects the visual intent, delegates to
vision_analyze, and the vision model returns structured JSON matching the template.
Usage
The vision model knob
The plugin registers exactly one subagent, vision-agent, WITHOUT a default model — the plugin never writes model. The vision model is set by you through the Kilo Code agent model override on vision-agent:
{
"agent": {
"vision-agent": {
"model": "<provider-id>/<model-id>" // any vision-capable model from your configured providers
}
}
}If no override is set, Kilo falls back to the default model.
This override is the single vision model knob for both delegation paths: the vision_analyze tool's model source is exactly this override, and the vision-agent subagent fallback uses it too. The plugin never writes the field, so your override is always preserved.
Per-model vision routing
The plugin routes images based on the handling model of each request, not a single global toggle. The vision-agent subagent is always registered — regardless of the top-level model — so a text-only agent in a mixed config can always delegate.
- Multimodal (vision-capable) model. Image
FileParts pass through untouched in the messages transform — the model sees images natively. The system transform injects a[vision:native]instruction telling the model to inspect images directly and NOT use the vision skill, callvision_analyze, or spawn avision-agentsubagent. - Text-only model. Image
FileParts are materialized under the plugin's temp dir and rewritten to[vision:dropped-image]markers carrying the resulting path. The orchestrator then delegates via thevision_analyzetool, falling back to thevision-agentsubagent only when the tool is unavailable or errors with a provider/protocol/HTTP failure.
Capability is resolved per request: the messages transform checks the message's info.model first, then the agent's configured model, then the top-level config model as a final fallback. Provider/model ids match case-insensitively. To bypass the skill per task on a text-only model, prepend this to your prompt:
You MUST not use the vision skill.
The vision_analyze tool and permissions
The tool's arguments are images ([{id, path}] — short contract ids plus local image paths), question (the exact visual question), response_template (JSON string defining the required response shape), and optional response_rules. The tool reads the images, calls the configured vision model (OpenAI-compatible /chat/completions for OpenAI-style endpoints, Anthropic /messages for anthropic-style endpoints), and returns exactly one JSON object matching the template.
vision_analyze is auto-allowed: sessions — including subagent sessions — call it without permission prompts. An explicit user deny wins: set permission.vision_analyze = "deny" and the tool is removed from every session's toolset (the skill then cannot delegate via the tool). The plugin never downgrades a deny.
Disabling vision delegation
To stop delegation entirely, disable vision-agent in Kilo Code: set disable: true on agent["vision-agent"]. This disables both paths: the agent does not appear in kilo agent list and cannot be delegated to, and the vision_analyze tool is not registered in any session. The plugin never writes disable, so your setting stays effective.
Troubleshooting
- Plugin not loading: run Kilo with
kilo --print-logs --log-level DEBUGand check the output for plugin load errors. - Stale plugin cache: reset the plugin cache under
~/.cache/kilo(or the legacy~/.cache/opencode/packagesdirectory) and restart Kilo. - Missing
vision-agentsubagent /vision_analyzetool: no model is pre-configured — set one via the Kilo Code agent model override onvision-agent. Confirm the override is set and that~/.cache/kilo/models.jsoncontains the provider. The tool is also absent whendisable: trueis set onvision-agent. vision_analyzereturns "model not configured": setagent["vision-agent"].modelto a vision-capable provider/model from your configured providers; the skill does not fall back on this error.vision_analyzereturns a provider error: check the API key (kilo auth/auth.jsonentry for the provider, or its*_API_KEYenv var) and the endpoint (provider.<id>.options.baseURLin config, else the provider's catalog/built-in endpoint). The skill automatically falls back to thevision-agentsubagent on provider/protocol/HTTP errors.
License
MIT — see LICENSE.
Upstream design and implementation: wezzard/opencode-vision, MIT. See also I Gave GLM-5.2 Eyes for the design rationale.
