deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
Turn DeepSeek Harness conversations into a hive: one conversation can send a task straight into another conversation, wake it up, and get the result back automatically — peer-to-peer conversations, not subagents.
This is a plugin for DeepSeek Harness that exposes two model-facing tools:
list_sessions — list the conversations that are currently live in this process (id + status + cwd), so you can discover a target session id.send_to_session — deliver a text message directly into another conversation and wake it. The target conversation starts a new turn immediately, in its own independent context.DeepSeek Harness ships with a subagent system: a parent conversation forks a child agent that shares its context and dies when the task ends.
dsh-hive solves the opposite need: multiple independent, long-lived top-level conversations (each with its own context, tools, and history) that call each other directly, like colleagues.
Typical flow: a "coordinator" conversation breaks work into subtasks and sends each one to a "worker" conversation via send_to_session. Each worker works in its own context — which can be long and messy without polluting the coordinator — and reports back only a short result summary when done. The coordinator wakes up automatically with the result and continues.
concludesTurn), so it does not sit and wait for a reply it cannot see; the reply arrives as a new message in a later turn and wakes it.This is a DeepSeek Harness bundle (it declares dsh.bundle and ships a cordis.patch.yml), installed through dsh plugin add — the same workflow as the official "Package and install a plugin" tutorial. No manual editing of the harness checkout is required.
This section is written so that another agent can perform the installation by following the steps literally.
dsh plugin --profile <name> add github:llluchy/dsh-hive
Details to be aware of when using the git source:
A git install fetches sources, not built artifacts, so pnpm runs the package's prepare script (which transpiles src/ into lib/ with esbuild; every harness import is externalized and resolves at runtime from the installed harness — no sibling monorepo is assumed).
pnpm ≥ 10 refuses to run a git dependency's build script until it is allowlisted. The first add points at the fix: copy the exact package key into the profile's pnpm-workspace.yaml, for example:
allowBuilds:
dsh-hive: true
then re-run the add. Treat this allowance as permission to execute the package's code at install time — only allow it if you trust the source, and pin a commit (github:llluchy/dsh-hive#<sha>).
Either publish to npm (with lib/ built at publish time) and:
dsh plugin --profile <name> add dsh-hive
or ship a tarball:
pnpm pack # produces dsh-hive-<version>.tgz
dsh plugin --profile <name> add ./dsh-hive-<version>.tgz
The repository already ships a prebuilt lib/index.js and lib/index.d.ts, so the tarball installs without running any build.
dsh --profile <name> --dump-config
The output shows a dsh-hive layer containing:
- id: dsh-hive
name: dsh-hive
Then boot with dsh --profile <name> and, in any conversation, ask the agent to call list_sessions — it should return the live conversations.
Tell the sender conversation:
Call
list_sessionsto find the target conversation's id, then callsend_to_sessionwith that id and the task text.
The sender delivers the task and ends its turn. The receiver wakes up, works in its own context, and — because the task message automatically carries the callback instruction — sends its result back with send_to_session. The sender is then woken by the reply in its next turn.
List the targets, then make several send_to_session calls in one planning round. All of them are delivered (the send-and-yield behaviour applies after the whole batch), and each reply arrives tagged with its own 完成的任务:…-style task label.
Pass expectReply: false. The message is delivered as-is, with no callback instruction appended. Use this when the message itself IS a reply (to avoid reply loops).
list_sessionsReturns { ok, count, sessions: [{ id, status, cwd? }] }.
send_to_session| Parameter | Type | Required | Meaning |
|---|---|---|---|
sessionId |
string | yes | Target conversation id (from list_sessions) |
message |
string | yes | The message body |
expectReply |
boolean | no | Whether to append the automatic callback instruction. Defaults to true. Set false when this message is itself a reply. |
Returns { ok: true, deliveredTo, expectReply, senderId } on success, or { ok: false, error } with a descriptive message (empty fields, unknown session, or self-delivery).
A: send_to_session(sessionId=B, message="task…")
└─ agents.get(B).followup(userMessage) // deliver into B's next-turn inbox, wake B
└─ appends: "when done, send_to_session back to <A>, expectReply=false"
└─ concludesTurn // A's current turn ends (after the whole tool batch)
B: wakes up, works in its own context
└─ send_to_session(sessionId=A, message="完成的任务:… result", expectReply=false)
└─ A wakes up in a new turn and sees the result
The underlying primitive is DeepSeek Harness's built-in agents.get(id).followup(message). This plugin wraps it into model-callable tools and adds the callback convention on top.
list_sessions and send_to_session only see conversations that are currently live in the process. A conversation that has not been opened cannot be targeted. (Targeting cold sessions would require session-query + cold resume, which is intentionally out of scope.)expectReply: false on its reply). There is no hard state machine preventing reply loops.MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。