@bismawy/pi-vision-watcher

extensionmaintained

Give text-only pi models vision — describe images with a vision model you pick via an interactive picker, then hand off the text description to non-vision models

by — · v1.0.14 · published 4d ago

$ pi install npm:@bismawy/pi-vision-watcher
downloads/mo
786
stars
0
last push
4d ago
open issues
0

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

No downloads in the last 12 weeks.

README

pi-vision-watcher

Give text-only pi models vision — images are described by a vision model you pick, then handed off to text-only coding models without interrupting your workflow.

pi package · npm · Issues

npm license

pi-vision-watcher

What it does

Paste an image, attach a file, or have the agent read one — pi-vision-watcher describes it in the background with your chosen vision model and feeds the description to whatever text-only model you're using (DeepSeek, local models, etc.).

  • Connected-only picker: /vision-watcher shows only vision-capable models from providers where you actually have credentials.
  • Batching & cache: multiple images across parallel tool calls are batched into one describer request; cached images (SHA-256) are never re-described.
  • False-vision healing: aggregator providers sometimes flag text-only models as multimodal, causing HTTP 400s. The extension proactively forces handoff for them and auto-heals models.json in-process.
  • Thinking controls: adjust reasoning effort (off – max) for reasoning-capable vision models.
  • Fallback chains: automatically falls back to backup vision models when the primary is rate-limited or down.

Install

pi install npm:@bismawy/pi-vision-watcher

Then run /vision-watcher to pick your vision model (or set it directly: /vision-watcher model openai/gpt-4o). Handoff is on by default — just switch to any text-only model and work as usual.

Commands

CommandAction
/vision-watcherInteractive picker for connected vision models
/vision-watcher model <provider/id>Set primary vision describer directly
/vision-watcher statusView current configuration
/vision-watcher auto <on|off>Toggle automatic handoff (default: on)
/vision-watcher add <provider/id>Force handoff on a specific model
/vision-watcher remove <provider/id>Remove model from forced handoff list
/vision-watcher thinking <level>Configure reasoning effort
/vision-watcher timeout <ms>Set the base per-image description timeout (default 45000)
/vision-watcher prewarm <on|off>Describe pasted images at paste-time (opt-in)
/vision-watcher async <on|off>Inject pasted-image descriptions asynchronously when no matching read wins (alias: fallback)
/vision-watcher clearClear the configured vision model
/vision-watcher enable / disableToggle extension active state
/vision-watcher helpList all subcommands

async is the async clipboard fallback and has nothing to do with the fallbackModels failover chain.

In the picker:

KeyAction
spaceSelect the highlighted model as the primary describer (press again to clear)
ctrl+qToggle the highlighted model in/out of the failover chain (marked 🔁, max 3). Not a mnemonic, and that's on purpose: ctrl+f is pi's find-text (bound since pi 0.85), alt+f is editor word-right, and ctrl+alt+f never survives Windows conhost/Windows Terminal. pi 0.85 also binds ctrl+q to app.message.followUp, which is inert while a picker is open — if it ever double-fires, f2 is the free fallback (unbound in 0.84 and 0.85)
ctrl+tWalk the thinking ladder: off → minimal → low → medium → high → xhigh → max → off → …
ctrl+aToggle async paste handoff
enter / ctrl+sSave (primary and chain together)
escCancel

The detail pane always shows the current configuration — primary, chain, thinking, async handoff — so every keypress shows exactly what will be saved. space is left to the search box while a filter query is present, so multi-word searches like gemini 3.8 stay typeable.

How it works

Configuration (~/.pi/agent/extensions/pi-vision-watcher.json)
{
  "enabled": true,
  "visionModel": "openai/gpt-4o",
  "fallbackModels": [],
  "autoHandoff": true,
  "handoffModels": [],
  "thinking": false,
  "thinkingLevel": "medium",
  "describeTimeoutMs": 45000,
  "prewarmPastedImages": false,
  "asyncClipboardHandoff": false,
  "maxTokens": null,
  "cacheMax": 50,
  "maxDescriptionLines": 0
}

Most fields have sane defaults — visionModel is the only one you normally set.

fallbackModels is the failover chain: when the primary describer fails (timeout, rate limit, auth), each entry is tried in order — fallback 1 fails, fallback 2 runs, and so on until one returns a description. The picker caps the chain at 3 entries (ctrl+q). Set it from the picker instead of hand-editing the file.

Diagnostics & recovery
  • Failed vision calls log with stack traces to ~/.pi/agent/logs/pi-vision-watcher/errors.log and degrade gracefully to [Image: description unavailable].
  • When a model falsely advertises image capability and 400s, the error is captured on message_end, modelOverrides.<model>.input = ["text"] is written to models.json, and the registry refreshes in-process.
Development
bun install
bun run test          # Vitest suite (240+ unit tests)
bun run typecheck
bun run lint:dead

License

Distributed under the MIT license.

Developer

Developed and maintained by Bisma.