At a glance
What it does
A DeepSeek Harness plugin that routes a request to a configured modality-capable fallback model without changing the session's primary model.
Deepseek Harness Profile, Cordis Profile
@deepseek-ai/cordis ^4.0.1; @deepseek-ai/dsh-agent ^0.1.0-rc.7; @deepseek-ai/dsh-llm ^0.1.0-rc.7
Evidence-verified
Checked Aug 21, 2026, 12:01 AM UTC
Code-evidenced contributions
What it adds to DSH
Routes image-bearing requests to a configured fallback model when the resolved model lacks image input support.
Mechanism evidence ↗Before you choose it
The Cordis plugin inspects derived message history and, when configured, routes requests containing unsupported image input to a fallback provider/model for that request only.
Best for
DeepSeek Harness users and developers composing Cordis plugins.
Common tasks
- Keep the session's selected model for ordinary requests while routing image-bearing requests to a compatible fallback.
- Install from a source-pinned GitHub repository and configure fallback routes in a profile patch.
Permissions and data
The plugin reads derived session message history and calls model capability resolution; configured adapters may perform their own provider I/O.
Permissions- Access to the DeepSeek Harness agent/request waterfall and session-derived messages.
- Configured provider/model capability resolution through the host harness.
- Inspects message content to detect image blocks.
- May emit a warning when capability probing fails; no broader data handling is evidenced.
- Configured DeepSeek Harness model providers or adapters.
- GitHub for source delivery when installed from the documented repository.
- Credentials required by the configured model provider, if any.
- DeepSeek Harness profile configuration access.
Limitations
- Only image modality detection is documented.
- Only one missing modality is routed per request.
- read_image and ApiProxy gates are not changed and may still reject before request construction.
- Unknown model capability is treated as capable.
- Fallback routing drops inherited reasoning effort.
- Capability-probe failures fail open.
- Runtime behavior and installation success were not tested in the supplied evidence.
What DSHub checked
- MIT license and package metadata are present (package-1).
- dsh.bundle patch declaration and patch contents are present and structure-verified (package-1, bundle-patch-1).
- README documents source-pinned GitHub installation, configuration, and known limitations (readme).
What DSHub did not check
- Runtime execution, build success, and installation success were not tested.
- npm registry availability for version 0.1.0 was not verified.
Pinned install
Install Modality Fallback
dsh plugin --profile deepseek-harness add github:lilei0311/dsh-plugin-modality-fallback#dc850393fcf290dffab25894dc95e6e2e003cc3cThe copy action is fixed to the reviewed package version. Evidence-verified confirms structure and distribution; it is not a security certification or runtime guarantee.
Upstream project
Project README
English | 中文
A DeepSeek Harness (dsh) plugin. Route one request to a modality-capable fallback model instead of forcing the whole session onto a single model.
The problem
A dsh session (Agent) selects one provider/model for its entire lifetime. That single model may not accept every modality that shows up in the session's history — today that means images. Without this plugin:
- The built-in
read_imagetool refuses outright when the session's model does not declareimageinput: "switch to an image-capable model to read images." ApiProxyrefuses to send a message, or to switch models, when the session's history already contains an image the target model can't accept.
Every one of these paths tells the user to manually switch the whole session to an image-capable model and back — losing the differentiated model choice they made for everything else in that conversation.
What this plugin does
It wraps dsh's agent/request waterfall (the extension point dsh-agent-default-model's own README documents as deferred: "per-session selection remains the entry point's responsibility"). Before a request goes out:
- It reads the session's derived message history (
agent.session.deriveMessages()). - If that history needs a modality beyond plain text (currently:
image) and the model resolved by every other listener does not declare that modality (llm.resolveModelInfo(...).inputModalities), it looks up a configured fallback route for that modality. - If one is configured, it swaps
provider/modelfor that request only. The session's own selection is untouched — the next request (once the image scrolls out of context, or the user switches models) resolves normally again.
No core deepseek-harness code is modified. This is an ordinary Cordis plugin, loaded alongside the rest of your dsh composition.
Install
This package declares a dsh.bundle manifest, so dsh plugin installs and wires it into a profile in one step:
dsh plugin --profile web add dsh-plugin-modality-fallback
# or straight from GitHub, no npm publish needed:
dsh plugin --profile web add github:lilei0311/dsh-plugin-modality-fallback
That appends this package to the profile's dsh.profile.bundles and applies cordis.patch.yml, which inserts the plugin row with an empty fallback: {} (no routes configured yet — every request behaves exactly as before). Configure a real route by restating that row's config in your own profile's or $DSH_HOME's cordis.patch.yml (a patch replaces the whole config, so restate the id too):
- id: modality-fallback
config:
fallback:
image: { provider: deepseek-official, model: deepseek-vision }
dsh --profile web --dump-config shows the composed row so you can confirm it landed. See deepseek-harness's plugin-install tutorial for the full bundle/profile mechanics this relies on.
Programmatic use (embedding dsh yourself)
import ModalityFallback from 'dsh-plugin-modality-fallback'
await ctx.plugin(ModalityFallback, {
fallback: {
image: { provider: 'deepseek-official', model: 'deepseek-vision' },
},
})
Load it after your llm and agent/agent-loop plugins so ctx.llm and the agent/request waterfall already exist.
Known limitations
- Only
imageis detected today. The modality vocabulary (ModelModality) is open-ended, but this plugin's content check only walks for image blocks. Extending it to another modality means adding a content predicate, not changing the routing mechanism. - At most one missing modality is resolved per request. If a future modality check finds more than one unmet modality at once, only the first is routed; the rest fall through unchanged.
read_imageandApiProxy's own gates are unaffected. Those refuse before a request is ever built, based only on the session's currently selected model, so they refuse even when this plugin has a working fallback configured for the very modality they're gating. Fixing that requires a change indeepseek-harnesscore itself (those gates would need to consult this plugin, or an equivalent capability, before refusing) — out of scope for a plugin that doesn't touch core.- Unknown model capability is treated as capable. When
resolveModelInfo(...).inputModalitiesisundefined(capability unknown), the plugin does not redirect — matchingApiProxy's existing send/switch-model gates, not the stricterread_imagegate (which refuses on unknown capability). A deployment that wants redirection on unknown capability too should have its adapter declareinputModalitiesexplicitly. - A route switch drops the inherited reasoning effort rather than forwarding one the fallback model may not support; the fallback route's own adapter/provider default applies instead.
- A capability-probe failure fails open.
resolveModelInfois adapter-owned I/O and can reject (network, an adapter returning invalid metadata, etc.). This plugin only ever helps route around a missing modality, so a probe failure logs a warning (ctx.logger.warn) and leaves the route unchanged rather than failing the whole request — even one whose already-resolved model didn't need a fallback in the first place. The probe itself is also skipped entirely when none of the request's needed modalities have a configured route (the default install,fallback: {}, never calls it at all), so this failure mode only matters once you've actually configured a route.
Why a plugin, not a deepseek-harness PR
deepseek-harness is still at an early developer-preview stage and its CONTRIBUTING.md states the project does not accept external pull requests yet. Its own guidance for this situation is to build a plugin and share it — this repository does that, tagged with the dsh-plugin GitHub topic for discoverability.
License
MIT
Operate deliberately
Install and manage
Prerequisites and target Profile
Target: Deepseek Harness Profile, Cordis Profile
Delivery: Dsh Bundle Git — github:lilei0311/dsh-plugin-modality-fallback#dc850393fcf290dffab25894dc95e6e2e003cc3c。
Verify, update, and remove
Show lifecycle commands
dsh plugin --profile deepseek-harness listdsh plugin --profile deepseek-harness remove dsh-plugin-modality-fallbackCompatibility and access
Manifest Compatible: @deepseek-ai/cordis ^4.0.1; @deepseek-ai/dsh-agent ^0.1.0-rc.7; @deepseek-ai/dsh-llm ^0.1.0-rc.7。
Review compatibility evidence ↗
Risk facts
Install lifecycle runs a documented build
Evidence ↗npm package version not found; source delivery is documented
Evidence ↗Evidence and editorial reviewManifest, Bundle patch, distribution and freshness
Immutable evidence
Review status and source activity
Publish as a source-only Bundle using the pinned repository commit; npm distribution is unavailable in the supplied evidence.
Human reviewed Aug 21, 2026, 12:06 AM UTC。GitHub facts last checked Aug 21, 2026, 12:06 AM UTC。
No material source change has been recorded since this evidence baseline.