DeepSeek Harness (dsh) as a hive vessel.
io.github.hive-agi/hive-deepseek {:mvn/version "RELEASE"}
Pin the version from the Clojars badge.
Addons describe what should appear once, as
hive-vessel ops. hive-deepseek gets those ops into a
running dsh, where they show up in dsh's own UI: panels in the right
Sidebar, notices, file navigation, and events other dsh plugins can listen to.
addon intent ─ translators ─▶ :ui/* primitives ─ :json dialect ─▶ native message
│ │
hive.deepseek IAddon ── hive-vessel.executor.sse ── SSE ──▶ dsh-hive-vessel (browser plugin)
│
right Sidebar "Hive" tab, notices, file viewer
Two halves, one repository:
| half | path | runs in |
|---|---|---|
hive.deepseek IAddon + IVessel | src/, resources/META-INF/hive-addons/ | the hive JVM |
dsh-hive-vessel plugin | dsh/ | DeepSeek Harness (host + browser) |
hive-deepseek.addon/addon-ctor, manifest id hive.deepseek.
Config: :deepseek/port (7925), :deepseek/host (loopback),
:deepseek/token, :deepseek/presenter-id (:deepseek),
:deepseek/present-on (#{}).
On initialize it starts the bridge and builds its registry: hive-vessel's
standard translators, plus the :vessel/translators hook of every injected
dependency. A dependency named in :deepseek/present-on (a set of addon
ids) that exposes a register-presenter! hook (hive-carto-flow does) gets
this vessel's delivery registered, so its frames reach dsh. Neither side's
code names the other.
Presenting is opt-in. hive-carto-flow-deepseek already registers a presenter
under :deepseek. If hive.deepseek also swept every dependency's
register-presenter!, the two would replace each other on every mount. To
have this addon present for hive.carto-flow in place of the brick, set
:deepseek/present-on #{"hive.carto-flow"}.
Hooks:
| hook | returns |
|---|---|
:vessel/target | the hive-vessel target (:vessel/id :deepseek, :json) |
:vessel/instance | a hive-addon IVessel (capability :delivery) |
:deepseek/vessel | host-neutral descriptor with :vessel/addon |
:vessel/dispatch! | (fn [op-or-ops]) through the registry |
:vessel/register-translators! | add translators at runtime |
:deepseek/bridge | port, connected clients, retained panels, inbox |
:delivery accepts ops and presenter envelopes ({:type :payload}).
# hive side: bridge on 7925, pushes a demo sequence once a dsh tab connects
clojure -M:dev -m hive-deepseek.demo 7925 600 /path/to/a/file
# dsh side
dsh plugin --profile web add ./dsh
dsh --profile web
dsh/hive-dsh boots dsh on the providers the swarm already uses. It reads
hive-mcp's ~/.config/hive-mcp/config.edn (:llm-providers for URLs and
models, :secrets for where each key lives) and writes those routes as a
llm-pi-ai patch next to the profile. Nothing about a provider is restated in
dsh's config.
dsh/hive-dsh --dump --only venice,axon # the patch, no keys read
dsh/hive-dsh --check # HTTP status per keyed provider
dsh/hive-dsh --profile hive --default venice/deepseek-v4-flash -- --no-open --port 3190
pass: secret references are used. The wrapper runs
pass show and exports each key into dsh's environment only. The patch
names the variable (VENICE_API_KEY), never the value. A secret that is
not a pass: reference is skipped and reported.--no-verify skips the probe.
OpenRouter and Venice are probed on endpoints that need auth, because
OpenRouter serves /models without it.--probe-balance also sends each keyed provider a
one-token completion and leaves out one that answers 402. It costs one call
per provider, so it is off by default.CLJW, default cljw) and starts in
about 70 ms. The shell half exists only because cljw cannot spawn a
process. DSH_BIN picks the dsh executable.The routes are computed by hive-deepseek.providers, a pure .cljc
namespace covered by the JVM test suite.
clojure -M:test # IAddon boundary with stub dependencies
(cd dsh && npm test) # browser half, no dsh needed
e2e/run.sh /tmp/hive-deepseek-e2e # real dsh + headless Chromium
e2e/run.sh does four things:
@deepseek-ai/dsh into a scratch directory.dsh plugin add.It then checks:
json/event is recordedui/open-file and panel links open the file in dsh's viewerTo develop against sibling checkouts of hive-addon and hive-vessel, point
an untracked local.deps.edn at them and run
clojure -Sdeps "$(cat local.deps.edn)" -M:test.
Every push to main that changes src/, resources/, test/, deps.edn or
version.edn runs the suite, bumps the patch version, regenerates
CHANGELOG.md, tags vX.Y.Z and deploys to Clojars through
hive-build. Do not bump VERSION by hand.
MIT
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |