Introduction¶
In DSH, /model takes effect immediately: if you switch models while a turn is still running (for example, waiting to retry after a disconnection), the retry will be sent using the new model. Thus, this “turn” is silently changed to a model it was not when it started. For workflows where you want to control and reproduce which model serves each turn, this is a hidden pitfall.
The dsh-flow-queue plugin introduced below targets this problem: it turns prompt submission, model switching, command execution, branching, and looping into nodes in a graph. The engine only advances when turn/end is persisted and the session’s Agent is idle, so switching always falls between two turns. This plugin is maintained by Eclipse-NotFound, belongs to the “Workflow” category in the community directory, and is licensed under MIT.
What is it¶
One-sentence positioning: A visual flowchart editor for DeepSeek Harness (DSH) where the entire canvas lives in the right sidebar, with no independent window.
It visualizes prompts, model switching, command execution, conditional branching, loops, breakpoints, sub-agent fan-out, and cross-session send/wait as a directed graph. It executes in the order of connections, and only at turn boundaries. On top of this, it overlays a “Fleet” view to manage collaborative sessions in the workspace.
Problems solved:
- In-flight requests and every retry of them always use the model they started with, not interrupted by mid-turn switching;
- Model switching happens only between turns, semantically meaning “before the next input”;
- The order on the graph equals the execution order; you can see in real-time where the process has run and what the results are.
Core Features¶
Nine Step Nodes. For each step, just click one in the second row to add it to the canvas:
- Prompt: Submits a user message, can carry images and file attachments, and can specify a model specifically for this step;
- Switch Model: Switches the session to a specified model at a turn boundary; when the model declares a thinking intensity tier, it can be specified together;
- Execute Command: Runs slash commands (e.g.,
/compact,/plan, etc., usingcommands.execute); - Conditional Branch: Selects “Yes” or “No” paths based on conditions;
- Loop: Takes the “Exit Loop” path when the exit condition is met or the maximum number of turns is reached; otherwise, it takes “Loop Again”;
- Breakpoint: Stops and waits for someone to click “Continue”;
- Fan-out Sub-agents: Sends the same prompt to up to 8 one-time sub-agents (
spawnbackend). Each path can force its own model/intensity, leaving it empty to inherit the session routing; aggregation happens after collection. There are three aggregation methods:All Complete,First k Complete(cancel the slow ones once enough are done), andFirst Complete. The parent turn is unaffected; fan-out waits next to the turn boundary, not crossing it; - Send Message: Sends a message to another session in the Fleet (persists first, backs off and retries, strictly preserves order to the same target, dead letters block the queue until manual retry); can carry a file manifest of changes made in this turn for the current session (only for files written by the file tool, blind spots marked as such);
- Wait for Session: Waits for the target to complete a turn and become idle after starting to wait, or waits for the target’s most recent output to contain a marker (default
[[FLOW:REPORT).
How Conditions are Evaluated. Conditions are evaluated against the most recent output: Prompt nodes check the assistant’s output text and tool failure records for that turn; Command nodes check the command result. Optional conditions include Always, Regex match previous output (multi-line mode), Contains text, Contains completion marker (default [[FLOW:DONE]]), Tool failure in previous turn, Previous step failed, and Model Judgment (natural language condition; a minimal decision turn is initiated when executing this step, instruction is approx 40 tokens + the original condition, requiring the model to answer only YES or NO on the first line; if it cannot answer, the step is judged as failed no-decision). Each condition can be negated. Model Judgment does not register global tools and does not modify any session’s tool table; each round in the loop re-evaluates, not reusing old conclusions.
Additional Capabilities of Prompt Blocks. In addition to multi-line text, they can carry image attachments (read as base64, saved via the host’s attachments.saveImages and sent as an image content part) and arbitrary file attachments. The prompt editor inherits two habits from the input box: typing / at the start of a line pops up available commands and skills directory; typing @ pops up workspace file references (the semantics of @path are consistent with the native one, it is a text reference rather than content injection, the model reads it itself). If the entire text block is exactly a prompt step for a host command (e.g., just writing /compact), it runs as the command when executed, rather than being sent to the model. There is a maximum of 8 image/file attachments per step.
Runtime Status and Safe Behavior. States are Not Run / Running / Waiting for Continue (Breakpoint) / Paused / Completed / Error. Three design trade-offs are worth mentioning:
- No “ghost success”: When a turn ends with error/aborted/interrupted, that step is marked as failed;
- No “deadlock”: If a prompt is accepted but no new turn occurs within 30 seconds, the step fails with
no-turn, and the entire turn is marked as error; - Safe restart: When the process restarts, steps marked as executed still display as
interrupted, and the running status changes to “Paused”; they won’t secretly continue running on their own.
Each step card displays status, duration, the actual model serving it (taken from request/header for that turn), errors, and command results.
Flow Packages. ⋯ → Flow Package can save the current graph to $DSH_PROFILE_DIR/flow-queue/packages/*.json, to be loaded or deleted in any session. It saves nodes and connections, not runtime state. Flow packages can declare parameter variables: writing {{task}} in prompts / fan-out / send text fills the blanks one by one when loading; un-filled placeholders remain as is and will never secretly become an empty prompt. Two built-in flow packages (write once, never overwrite): report-protocol (worker prompt template with four-state turn-end markers + matching wait-for-marker step) and superagent-review (superagent full lifecycle graph: worker dispatch → four-state marker branch verify readiness → independent reviewer review → bounded follow-up loop ≤3 turns → pass to delivery gate, loading fills {{task}} and {{ticket}} parameters).
Installation and Enablement¶
The official installation command is one line (from README, do not splice other forms based on the package name):
dsh plugin --profile web add github:Eclipse-NotFound/dsh-flow-queue
After installation, you must restart the Harness web runtime (bundle is assembled at startup), then refresh the page. The version requirement is DSH >=0.2.1-rc.1 <0.3.0 (the engines.dsh field in package.json also specifies this range).
Verification. An icon for the plugin appears at the bottom of the left sidebar (next to settings). Hovering displays “Open Flow Queue”. Click this icon, or the “Flow Queue” card in the “Start” page of the right sidebar, and the “Flow Queue” tab will appear in the right sidebar, with the canvas inside the tab. Next to the title are two view switches: “Flow” and “Fleet”. Most daily operations for this plugin stay on the “Flow” page.
The plugin registers /flow-queue/api/… routes under the same origin (e.g., GET /flow-queue/api/state?sessionId=…, GET /flow-queue/api/models, POST /flow-queue/api/command, etc.), all checked by ctx.connection.requestRejection, and only authenticated pages can call them. It only saves content you create in each session (graph and flow package directory), and does not send data anywhere.
Typical Usage¶
The README gives a five-minute runnable minimal flow: Prompt -> Switch Model -> Conditional Branch. The steps are as follows.
1. Add three cards. Click +Prompt, +Switch Model, and +Conditional Branch in the second row one by one. The first added “Prompt” is the starting point of the flow.
2. Fill in the three steps. Clicking a card (without dragging after pressing) opens an inspector drawer at the bottom of the canvas. The header is “Edit Step”. Write a verifiable prompt in the prompt box, for example, “Confirm in one sentence that you received this message, then on a new line only output: FLOW-OK”. Save with Ctrl/⌘ + Enter (saving also happens on blur). Keep “Model” as “Not set (inherit current)”. Select the target model from the “Model” dropdown on the Switch Model card. In the Conditional Branch, set the condition to “Contains text” and the match content to FLOW-OK. At this point, the main text of the three cards displays the first line of the prompt, Provider / Model, and Contains text · FLOW-OK respectively.
3. Connect. Drag from the dot on the right side of the Prompt card to the Switch Model card (or click the dot then click the target card), then connect Switch Model to the Conditional Branch. The branch has two output dots “Yes” and “No”. To see the direction clearly, you can add a Breakpoint card with +Breakpoint and connect “Yes” to it.
4. Run. Click “Start” in the top bar. The prompt is submitted as a real user message into the current session; after that turn ends and before the next input, the session switches to the new model; then the branch evaluates the reply for that turn. The running status first changes to “Running”, and becomes “Completed” after the whole flow finishes. If a breakpoint is added, if the reply contains FLOW-OK, it goes to “Yes” and stops at the breakpoint, the status changes to “Waiting for Continue”, and you finish by clicking “Continue”; if it does not contain it, it goes to “No”, and the flow directly becomes “Completed”, while the Breakpoint card remains “Not Run”.
Remember two running rules: editing the graph must be done when not running (it will be rejected while running; you must click “Pause” or “Stop” first); clicking “Start” again will clear the status of each step and rerun from the start. For DEBUG and recovery, you can run directly on a card: the drawer header has “Start from this step”, click ↓ to collapse the drawer.
Use ⋯ → Flow Package to save when you want to reuse the entire flow.
Suitable Scenarios and Notes¶
Who is it for:
- Want to map out multi-step agent operations (prompts, switching models, running commands, splitting) in one go and run them repeatedly, rather than typing them by hand every time;
- Workflows that require strict control over “which model serves which turn”, for example, long turns with retries cannot have the model changed mid-way;
- Want to mix “stop and wait for confirmation” into an automated process (using a breakpoint node);
- Need to send operations of the same session to multiple one-time sub-agents for parallel processing (fan-out node);
- Multi-session collaboration scenarios where you need to send a message from one session to another, wait for it to reply, and then continue (Send Message / Wait for Session).
Notes:
- The plugin runs with the permissions of the current dsh process, including access to sessions, commands, and the file system. Before installing, please read the source code (repository is public,
index.js,client.js,cordis.patch.ymlunder themainbranch) and the MIT license to decide whether to enable it; - It only declares compatibility within the DSH range
>=0.2.1-rc.1 <0.3.0; you need to verify yourself if the version is outside this range; - The plugin depends on the host CLI; commands that only appear as client pop-ups (like the
/modelselector) will not appear in the/menu; - Currently not implemented: thumbnail preview of image attachments, drag-and-drop sorting, multi-select/box select, undo/redo, fan-out of more than 8 paths, and viewing the canvas and inspector simultaneously on the same panel (narrow sidebar is an either/or choice, use ← to return to canvas when a step is selected).
Conclusion¶
The value of dsh-flow-queue lies in making both the structure and execution timing of the workflow explicit: the order on the graph is the execution order, and everything happens only at turn boundaries. The entire plugin is maintained by Eclipse-NotFound alone. It is not large, has a clear single-file code structure, and installing it gives you a tab in the right sidebar. If it meets your workflow needs, the source code and installation method are below.
- Community Directory Page: https://www.skillhub.cn/plugins/Eclipse-NotFound/dsh-flow-queue
- GitHub: https://github.com/Eclipse-NotFound/dsh-flow-queue