UnforgetMemory/um-dsh-azimg

um-dsh-azimg

Give DeepSeek Harness (DSH) agents eyes: local image analysis via vision models — um_analyze_img tool, model-capability recognition, hot-switch settings UI.

Uncategorizedai-agentscordisdeepseek-harness

um-dsh-azimg — let agents see images

um-dsh-azimg

Give DeepSeek Harness agents eyes — a dynamic plugin for local image analysis

English | 简体中文


um-dsh-azimg is a dynamic Cordis plugin for DSH. It gives agents — especially text-only ones — the ability to analyze local images: it registers the um_analyze_img tool, hands local images to a chosen vision model, and returns a structured analysis.

✨ Features

  • Multi-image analysis — 1–8 local images per call, all handled by the same vision model, with order and filenames carried in the prompt
  • True format sniffing — magic-number detection for PNG / JPEG / GIF / WebP instead of trusting extensions; attachment limit pre-checks + atomic batch ingestion
  • Smart model routing — three-way image-capability detection per provider model (image / text / unknown) with adapter re-verification; automatic failover with aggregated attribution (credentials / stopReason / diagnostic)
  • Hot switching — selection in the settings page takes effect immediately, no restart; availability probing + last-call echo
  • Native UI — settings page and tool card built entirely on DSH design tokens (--dsw-alias-*), adapting to light/dark themes automatically
  • i18n — full bilingual support (简体中文 / English) on settings page and tool card, following DSH locale service conventions with automatic re-render on language switch

🚀 Quick Start

This repository is a function-body source snapshot of a dynamic plugin: host.js / client.js are the verbatim code.host / code.client values for cordis_define (plain JS function bodies — no TS / import / JSX).

To restore the plugin inside a DSH session:

  1. Read host.js and client.js from this repository
  2. Submit them as code.host / code.client to cordis_define
  3. Activate with cordis_run

Once active, the agent can call:

um_analyze_img(image_paths: ["C:/path/a.png", "C:/path/b.jpg"], question: "Describe the images")

This repository is a complete profile bundle (package.json → dsh.bundle + dsh.client → a single dual-face row in cordis.patch.yml):

dsh plugin --profile <name> add github:UnforgetMemory/um-dsh-azimg

Installation joins the profile layer stack and activates the plugin: the host half lib/index.js registers the um_analyze_img tool and the umimg/* settings-data service (Typert Remote, exposed via SRC fallback), while the client half lib/client.js (hand-written factory-form bundle, zero build) provides the settings page and tool card. It persists with the profile across restarts. To upgrade:

dsh plugin --profile <name> update

Fallback: the row can be disabled from the profile's own cordis.patch.yml with - id: umimg, disabled: true.

⚙️ How It Works

Model calls um_analyze_img(image_paths[1..8], question?)
   │
   ▼
Host plugin ── limit pre-check → magic-number sniffing → atomic batch ingestion → prompt assembly (text + N image blocks)
   │
   ▼
Candidates ── panel selection set → try only that model (no silent switching)
              not set             → try every image-capable model in turn (automatic failover)
   │
   ▼
llm.stream({ provider, model, messages }) → direct in-process vision call (attachment pixels resolved by the adapter in place)
   │
   ▼
{ analysis, meta } — the model reads analysis; the tool card reads meta (model / images / attempts / elapsed)

Host service dependencies: tools · llm · attachments · fs

🖥️ Settings Page & Tool Card

  • Settings page (settings.section · 「图片分析」): lists every model grouped by provider with image-capability labels (supported / undeclared / text-only), hot switching, availability probing, and last-call echo
  • Tool card (tool.call.toolview): status badge, model chip, failover count, clickable image names, collapsible result, elapsed time

🔌 RPC Contract (Client → Host, package-private)

methodinputoutput
state{ refresh?: boolean }{ selection, groups, stats, lastRun, limits, toolName }
select{ provider, model } or null{ selection, warning } (non-empty warning = model is not in the image-capable list)
probe{ provider, model }{ ok: true, provider, model, name, inputModalities, contextWindow } / { ok: false, detail, code }

📦 Repository Files

filecontent
host.js / client.jsDynamic-form source snapshots (in-session cordis_define restore; see Quick Start)
lib/index.jsStatic host half: um_analyze_img tool + umimg/* Remote settings service
lib/client.jsStatic client half: hand-written factory-form browser bundle (zero build)
package.json / cordis.patch.ymldsh.bundle + dsh.client declarations and the single dual-face layer row
README.md简体中文 README(默认)
hero.jpgHero artwork referenced by the READMEs (original kept locally in .um.agents/local/, untracked)

Code organization: each function body is internally sectioned into libraries → provider → scenario → app layers (in-body layering under the single-function-body constraint; dependencies point downward only), with execute as the linear orchestration entry point.

📋 Version

Current 0.3.0 — see CHANGELOG.md for history.

☕ Support

If this plugin helps you, buy me a coffee:

📝 Notes

  • A dynamic plugin lives as long as its DSH process: it disappears when the process exits and can be restored by resubmitting the sources; the model selection (selection) is not persisted and resets to "auto" on restart
  • Permanent installation: this repository is already a complete static bundle — dsh plugin add activates it with the profile layer (lib/index.js + lib/client.js), no in-session cordis_define required