New:Socket for Asana Is Now Available.Learn more
Get Started

dsh-plugin-vision

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dsh-plugin-vision

Lets a text-only agent call a multimodal model mid-task: the vision tool sends one image file to Qwen, Kimi, OpenAI, Claude, Gemini or a self-hosted endpoint and returns structured evidence — summary, verbatim OCR, layout, entities, and what the model cou

latest
Source
npmnpm
Version
0.1.0
Version published
Maintainers
1
Created
Source

vision

English · 中文

Lets a text-only agent call a multimodal model in the middle of a task. The vision tool sends one image file to Qwen, Kimi, OpenAI, Claude, Gemini or your own endpoint, and returns what that model reports — the image never enters the main model's context, so a text-only route keeps working and the picture costs one tool call instead of a model switch.

Vendored from gloryxpnv/dsh-tool-vision (MIT, v0.3.0, commit 35789ca) and maintained here. See what changed.

The tool

vision(file_path, question?) — reads a PNG, JPEG, WebP or GIF, absolute or relative to the session workspace, and asks the configured vision model about it. Without a question it asks for a full description.

In structured mode (the default) the vision model is asked for fixed-shape evidence rather than prose, and the reply is parsed into:

FieldWhat it holds
summaryone paragraph of overview
ocrevery visible character, transcribed verbatim, plus per-line text
layoutregions in reading order — title, paragraph, table, chart, form, code …
semanticsthe scene, named entities with where each was seen, and relations
visualdominant colours, style, notes
uncertaintywhat the model could not determine

That last field is the point of the shape. A vision model asked for prose will smooth over what it could not read; asked for an explicit uncertainty list, it has somewhere to put it, and the main model can quote the transcription instead of trusting a retelling. The schema deliberately has no bounding boxes and no confidence scores — vision models invent those.

Set structured: false to get the plain answer string instead.

Install

dsh plugin --profile web add dsh-plugin-vision

Providers

Pick one and supply a key. The endpoint, the wire format and a starting model id come with it:

providerEndpointFormatStarting model
qwen (default)DashScope compatible modeOpenAIqwen-vl-max-latest
kimiMoonshotOpenAImoonshot-v1-8k-vision-preview
openaiOpenAIOpenAIgpt-4o
claudeAnthropicAnthropicclaude-sonnet-5
geminiGoogleGeminigemini-2.5-flash
customyoursprotocol decides

Three wire formats are spoken, because they genuinely differ: OpenAI posts /chat/completions with the image as a data: URI and a bearer token; Anthropic posts /messages with a base64 source block, an x-api-key header and a required anthropic-version; Gemini posts /models/<id>:generateContent with inline_data and an x-goog-api-key. The starting model ids are a place to begin, not a claim about your account — override model with whatever your key is entitled to.

- id: vision
  config:
    provider: kimi
    apiKey: '…'

A self-hosted or local runtime is provider: custom with its own baseURL, model and protocol; a loopback endpoint needs no key, so LM Studio on http://127.0.0.1:1234/v1 works with apiKey left empty.

Until the route is complete the plugin registers no tool at all, and the system prompt tells the model plainly that it cannot see images and names what is missing — rather than leaving it a tool that always fails. The log says the same thing, because "the plugin does nothing" is otherwise the whole report.

[!IMPORTANT] The plugin states the endpoint and model in the system prompt before the model needs them, and tells it to report a failure rather than describe an image it could not see. A model that discovers a broken endpoint by calling it will otherwise describe the picture from its filename — this is the same failure that made the finance plugins declare their credentials up front.

Failures name what was dialled: vision: request to http://127.0.0.1:1234/v1 failed (…), an HTTP status with the endpoint's own body, or an empty answer naming the model.

The bridge

The plugin also provides an optional vision-bridge service. Where the tool is the agent deciding to look at a file, the bridge covers an image the user pastes into a text-only conversation: each image part is followed by a description so the prompt is admissible. On any failure it returns nothing and the host keeps its original refusal — a refusal is better than an invented description.

  • autoDescribe: true (default) calls the vision model at admission time, which takes as long as the model takes.
  • autoDescribe: false keeps the thumbnail and points the model at the workspace file, leaving it to call vision when it actually needs to look — one deliberate call instead of an automatic one plus a follow-up.
  • keepThumbnail requires a host whose text-only serialiser drops image blocks before the wire. Leave it off on a stock host, which rejects image content on a text-only route.

Config

KeyDefaultWhat it decides
providerqwenwhich service looks, and so the endpoint and format
apiKey(empty — required unless local)the credential for that service
baseURL(empty — the provider's)endpoint root; required for custom
model(empty — the provider's)the vision model id
protocolopenaiwire format, only when provider: custom
structuredtruefixed-shape evidence instead of prose
maxTokens8192output budget — reasoning models spend part of it thinking
timeoutMs180000wall time for one request
maxImageBytes50 MiBlargest image accepted
autoDescribetruebridge calls the model at admission time
keepThumbnailfalsebridge keeps the image block in history

What changed from upstream

  • Renamed to dsh-plugin-vision for this repository's naming convention, with the plugin row and exported name following
  • Claude, Gemini and OpenAI-format providers are all supported. Upstream spoke one wire format; the three differ in the endpoint path, the auth header and how an image is encoded, so each is a small table entry and the rest of the plugin is protocol-agnostic
  • Providers instead of a hardcoded endpoint. Upstream shipped a local LM Studio address and model id, which works until it doesn't: an unconfigured install posts images at whatever holds that port. Now a provider carries its own endpoint and format, the key is the only required field, and without one the plugin registers nothing and says so in the prompt
  • Failures name the endpoint they dialled. Upstream said "LM Studio request failed" whatever the configured baseURL was, which misdirects everyone pointing it at something else
  • The tool declares timeoutMs, above its own request cap, so a slow endpoint fails with a reason instead of being cut down by the tool-call timeout policy
  • The capability is declared in the system prompt rather than discovered by failing
  • Added dsh.category, repository.directory, and this bilingual README pair
  • Tests rewritten on node:test, covering the JSON recovery, the evidence normalisation, and every failure path through a fake endpoint

Upstream's copyright and MIT licence are kept in LICENSE.

Licence

MIT — see LICENSE.

Keywords

dsh

FAQs

Package last updated on 20 Aug 2026

Related posts