1HelloMan1/dsh-vision-fallback2

dsh-vision-fallback

DSH 静默视觉增强:主模型照常选择,图片自动交给固定视觉模型后以隐藏上下文返回主模型。

包名
dsh-vision-fallback
版本
0.9.0
许可证
MIT
最近更新
2026年8月17日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:1HelloMan1/dsh-vision-fallback

Configuration

Two ways, both live (no restart needed after saving):

Web settings page

Open Settings → 视觉增强 / Vision Enhancement in the DSH web UI. It exposes only:

FieldDefaultMeaning
EnabledtrueMaster switch
Vision modelmimo-v2.5OpenAI-compatible model
Base URLhttps://opencode.ai/zen/go/v1The plugin appends /chat/completions
Credential refOPENCODE_GO_API_KEYKey resolved from the DSH credential store (never written to env files)
Max tokens / Timeout / Max bytes1536 / 60000 / 15MBVision request limits
Recent contextincludeRecentContext: true, contextMessages: 6, contextMaxChars: 6000How much recent chat to attach for the vision model
Prompt(Chinese detailed-analysis prompt)Analysis instruction; the user's question is appended automatically
Tag resulttruePrepend 【视觉观察:】 to the observation

settings.yaml

vision-fallback:
  enabled: true
  model: mimo-v2.5
  baseURL: https://opencode.ai/zen/go/v1
  apiKeyRef: OPENCODE_GO_API_KEY
  maxTokens: 1536
  timeoutMs: 60000
  maxBytes: 15728640
  includeRecentContext: true
  contextMessages: 6
  contextMaxChars: 6000
  prompt: "请分析这张图片..."
  tagResult: true

The API key is resolved through the DSH credentials system (~/.dsh/.credentials.yaml), with process.env[apiKeyRef] as a fallback — it is never materialized into shell environment files by the plugin.

Usage records (usage.jsonl)

With recordUsage enabled, every real vision call (success or failure) appends one JSON line to /vision-fallback/usage.jsonl (override via usageLogPath in the settings page), consumed by usage-dashboard. Fields:

FieldMeaning
tsCall start time (epoch ms)
durationMsResponse latency of this call (ms)
kindAlways "vision"
status"ok" success / "error" failure
modelVision model name
inputTokens / outputTokensInput / output tokens
cacheReadTokensCached input tokens served
errorError message (failure entries only)
imageName / mediaType / imageBytesImage filename / media type / byte size
imageIndex / imageTotalThis image's position / total images in the request

Reusing a remembered observation (observations.json) does not append a line — this file counts real external vision calls only.

Observation cache semantics

Observations are keyed by the image's occurrence in a session (session id + message id):

  • The same image at the same message position processed again (restart recovery, replay, compaction) → reused, no re-recognition;
  • The same image at a new position in the session (new turn, main model asking to "look again") → re-recognized with fresh context;
  • Observations are not shared across sessions.

The cache is capped at 256 entries (LRU eviction); failed results are never cached.

Cache location: when usageLogPath is set, observations.json is written beside that log; otherwise it is stored at /vision-fallback/observations.json. This lets compaction, event replay, and service restarts reuse successful observations.

Compaction, tool results, and restarts

When the main model can already see images, the bridge does not call the vision model. If a later text-only compaction model encounters the original image event, the plugin first reuses the main model's projected observation and the persistent cache, then handles only images that truly have no observation. This prevents every compaction from re-describing the entire image history while still allowing the same image at a new message position to be re-read with fresh context.