Skip to main content
Glama

omp-dsh-workers

test

Führen Sie DeepSeek-Harness-Worker (DSH) aus Ihrer oh-my-pi-Sitzung aus. oh-my-pi (OMP) ist ein Terminal-Coding-Agent; DeepSeek Harness (dsh) ist die Agenten-Laufzeitumgebung von DeepSeek. Die Sitzung wird zum Director: Sie verteilt Aufträge mit dsh_spawn, jeder Worker läuft als persistente dsh --profile headless-Sitzung, und Rückfragen und Ergebnisse der Worker kommen als native Nachrichten zurück, die von einem Skript weitergeleitet werden.

Experimentell v0.1: Die Schnittstellen sind in docs/contracts/ eingefroren, aber nichts davon hat bisher einen öffentlichen Release-Zyklus durchlaufen.

Warum

Der OMP-Harness ist pro Aufgabe teuer, und ein nativer Sub-Agent zahlt diese Kosten bei jedem Auftrag. Hier wird sie einmal auf Director-Ebene bezahlt; die Arbeit läuft in DSH, schnell und token-sparsam, mit nur einem Skript dazwischen: null Modell-Tokens pro Aufgabe. DSH macht Läufe persistent (--resume auf einer echten Sitzungs-ID). Wenn Sie DSH nicht benötigen, sind native Sub-Agents weiterhin die richtige Wahl.

Related MCP server: dsh-crew

So funktioniert es

Zwei Modellebenen, bewusst getrennt:

Ebene

Wer

Modell kommt von

1

Director — Ihre Haupt-OMP-Sitzung im /dvibe-Modus

das Modell Ihrer OMP-Sitzung

2

DSH-Executor — ein DSH-Headless-Prozess pro Lauf

model von dsh_spawn, sonst die @dsh-Rolle, sonst das Modell Ihrer Sitzung, sonst DSH-Standard

@dsh benennt also das geerbte Modell des Executors, wenn dsh_spawn kein model hat — der Beobachter ist Code, kein Modell.

flowchart TD
    D["Director<br/>main OMP session, /dvibe on"]
    B["dsh-bridge<br/>argv spawn · run registry · steer channel"]
    X["DSH headless run<br/>+ resume plugin"]
    L["relay.ts<br/>script representative, in-process"]
    D -->|"dsh_spawn — brief, label, model"| B
    B -->|"dsh --profile headless [--resume]"| X
    X -->|"Envelope v1 (last stdout line)"| B
    B -->|"pollRun, 1s"| L
    L -->|"⟨label⟩ question / result / failure (followUp)"| D
    D -->|"dsh_answer — resumes the session"| B
    D -.->|"steering: dsh_list → dsh_send / dsh_wait by runId"| B
    D -.->|"dsh_kill by runId"| B

Der Director startet mit dsh_spawn, antwortet mit dsh_answer, steuert mit dsh_send, wartet mit dsh_wait und bricht mit dsh_kill ab; dsh_list löst ein Label in eine runId auf.

Komponenten

Pfad

Was es ist

extensions/dsh-task/

Die OMP-Erweiterung: dsh_task, dsh_spawn, dsh_answer, dsh_wait, dsh_kill, dsh_send, dsh_list, das Relay-Skript (relay.ts), /dvibe, ein Watchdog für verwaiste Prozesse.

tools/dsh-bridge/

bridge-core: Start in einer eigenen, abgetrennten Prozessgruppe, Lauf-Registry, Envelope v1, Steuerkanal, Owner-Lease und Reaping. Node ≥ 22, reines ESM-JavaScript, keine Abhängigkeiten und kein Build-Schritt.

plugins/dsh-headless-resume/

Cordis-Plugin im Headless-Profil von DSH: fügt --resume hinzu, gibt Envelope v1 aus, führt Modell-Preflight aus, liest den Steuerkanal.

scripts/

Installation: Symlinks in das Live-OMP-Verzeichnis, der DSH-Profil-Patch, Verknüpfung der Plugin-Abhängigkeiten.

Voraussetzungen

  • oh-my-pi v18 — geprüft gegen 18.0.3 / 18.0.4; @oh-my-pi/* auf ^18.0.4 gepinnt.

  • DSH ≥ 0.1.1-rc.2 auf PATH, mit vorhandenem headless-Profil.

  • bun für die Testskripte; Node ≥ 22 für bridge-core.

  • Ein Modellanbieter, der in Ihren DSH-Einstellungen konfiguriert ist; die Erweiterung ist anbieterneutral: Sie übergibt einen <provider>/<model>[:<effort>]-String an DSH.

DSH befindet sich in der Release-Candidate-Phase. Das Resume-Plugin hängt sich über die Eintrags-ID an, sodass ein Release, das diese IDs umbenennt, dazu führt, dass der Patch stillschweigend nicht mehr angewendet wird. Führen Sie nach jedem DSH-Upgrade erneut dsh --profile headless --help aus: Wenn --resume fehlt, ist das Plugin nicht eingebunden; docs/dsh-update-checklist.md enthält die vollständige Checkliste.

Installation

Das Repository ist die Quelle der Wahrheit; Live-Verzeichnisse erhalten immer nur Symlinks zurück darauf.

1. Erweiterung in OMP verlinken.

scripts/install-omp-links.sh [--dry-run] [--uninstall] [--omp-dir DIR]

Erstellt einen Symlink extensions/dsh-task unter $OMP_DIR (Standard: $HOME/.omp/agent). Idempotent — ein Link mit derselben Quelle bleibt unangetastet, ein Link, der woandershin zeigt, wird umgebogen, und eine echte Datei am Ziel bricht das Skript ab. --uninstall entfernt nur Links, die hierher zeigen.

2. Das Resume-Plugin in das DSH-Headless-Profil einbinden.

scripts/install-resume-plugin.sh              # install
scripts/install-resume-plugin.sh --uninstall  # remove

Erstellt vor jeder Änderung ein Backup; erfordert dsh auf PATH und ${DSH_HOME:-$HOME/.dsh}/profiles/headless. Dann:

  • Verlinkt @deepseek-ai und commander aus $DSH_MODULES in das node_modules-Verzeichnis des Plugins.

  • Fügt das Plugin hinzu: dsh plugin --profile headless add link:<plugin dir>, nachdem package.json gesichert wurde.

  • Hängt einen cordis.patch.yml-Block an, der headless-startup / headless-runner deaktiviert und headless-resume-startup / headless-resume-runner einfügt.

  • Verifiziert: Erfolg nur, wenn dsh --profile headless --help --resume erwähnt.

3. (nur Tests) scripts/link-plugin-deps.sh verlinkt Abhängigkeiten selbstständig; bun run test:resume ruft es auf.

Verwendung

Director-Modus

  • /dvibe schaltet den Director-Modus um; /dvibe on / /dvibe off sind explizit. Das Modell kann ihn auch über das Tool dvibe umschalten (action: "on" | "off"), das im verkleinerten Toolset erhalten bleibt.

  • Solange er aktiv ist, verkleinert sich das Toolset auf read, todo, dsh_spawn, dsh_answer, dsh_send, dsh_wait, dsh_list, dsh_kill, dvibe, plus eine Director-Direktive, die dem Systemprompt angehängt wird. Das dvibe-Tool gibt diese Direktive in seinem Ergebnis zurück: Das Modell ruft es auf, nachdem before_agent_start gelaufen ist, sodass der Turn-Prompt die Regeln nicht enthalten kann.

  • Aufträge gehen unverändert in dsh_spawn. Rückfragen von Workern kommen als ⟨label⟩-Nachrichten von relay.ts und werden mit dsh_answer beantwortet; Ergebnisse kommen auf demselben Weg.

  • Die Zustellung ist at-least-once: Ein Ereignis wird alle 120 s erneut angekündigt, bis ein passendes message_start beweist, dass das followUp in den Turn-Kontext gelangt ist; maximal 3 Versuche pro Ereignis. Ein zugestelltes need_input bleibt beobachtet, bis dsh_answer kommt.

  • Fertig mit dem Verteilen von Arbeit? Beenden Sie den Turn: Ereignisse kommen dann von selbst als Nachrichten.

  • dsh_wait ist die synchrone Alternative, nur wenn der nächste Schritt auf genau diesen Lauf blockiert und nichts mehr zu verteilen ist; ein so gelesenes Envelope kommt nie doppelt an.

  • Bei /dvibe off, Herunterfahren oder einem In-Process-Sitzungswechsel wird das vorherige Toolset wiederhergestellt.

Aufträge, Modelle, Resume

  • Geben Sie jeder Aufgabe ein kurzes label und optional ein model, beide als Parameter von dsh_spawn; das Label findet den Lauf später in dsh_list, dsh_answer, dsh_send.

  • Die Modellnotation ist <provider>/<model>[:<effort>]; Effort-Stufen: off, minimal, low, medium, high, xhigh, max. Das Suffix nach dem letzten : zählt nur dann als Effort, wenn es eine dieser Stufen ist, sonst gehört der Doppelpunkt zum Modellnamen. Keine Leerzeichen oder Steuerzeichen; Provider/Modell jeweils ≤ 200 Zeichen, Spezifikation ≤ 512; eine fehlerhafte Spezifikation schlägt vor dem Start fehl: error [invalid_model].

  • Ohne model erbt der Lauf die @dsh-Rolle von OMP (modelRoles.dsh), fällt auf das Modell Ihrer Sitzung zurück und dann auf DSHs eigenen Standard.

  • Resume: Übergeben Sie resumeFromRunId; die Bridge schlägt dessen sessionId nach. Geben Sie keine runId in resumeSessionId an: verschiedene Bezeichner, Sie erhalten resume_not_found.

  • Resume funktioniert, sobald der Lauf ein Envelope auf der Platte hinterlassen hat; ohne eines wirft dsh_spawn has no session to resume — sowohl für einen noch laufenden als auch für einen beendeten Lauf (früh beendet, beim Start abgestürzt, aufgeräumt). Prüfen Sie, welcher Fall vorliegt, bevor Sie reagieren: Ein neuer Auftrag für einen noch arbeitenden Lauf verdoppelt die Arbeit.

  • Die Modellüberschreibung ist nicht dauerhaft: Ein Resume ohne model berechnet das Modell neu. dsh_answer hat überhaupt keinen model-Parameter; um mit einem anderen Modell fortzufahren, verwenden Sie dsh_spawn mit resumeFromRunId und einem expliziten model.

Was der Director sieht

Tool-Karten werden für Menschen gerendert, getrennt von dem Text, den das Modell erhält: ▶ dsh spawn → <label>, ✓ started <label> (<runId8>) · pid …, dann ⏳ still running mit den letzten Ausgabezeilen oder ✓ completed · model: … · session: … plus den ersten Ergebniszeilen. Solange Läufe verfolgt werden, befindet sich ein dsh runs-Board über dem Editor und die Fußzeile zeigt dsh: N running · M done. Die Textausgabe der Tools bleibt unverändert: Sie bleibt der Vertrag.

Tools

Tool

Parameter

Text, den der Aufrufer erhält

dsh_spawn

task, label?, model?, timeoutMs?, resumeFromRunId?, resumeSessionId?

started <runId> (pid <pid>), plus label=… und model=…, wenn angegeben

dsh_answer

runId / label (mindestens eines; bei beiden wählt runId den Ziellauf, label benennt den neuen Lauf), plus answer

answered <oldRunId> -> <newRunId>

dsh_wait

runId, waitMs? (Standard 30000; 0 = einzelne Abfrage)

das Ergebnis des Laufs, oder still running: <runId>, oder wait cancelled for <runId>; run still active

dsh_send

runId, text

sent to <runId> / pending: … / NOT delivered: run ended before reading; message lost

dsh_kill

runId

kill <runId>: killed (…) oder kill <runId>: not killed (…)

dsh_list

no active runs, oder eine Zeile pro Lauf

dsh_task

task, model?, timeoutMs?, resumeFromRunId?, resumeSessionId?

das Ergebnis des Laufs (blockierend, einmalig)

Ein Timeout bei dsh_wait ist normal: Der Lauf bleibt am Leben und kann erneut abgewartet werden; das Abbrechen eines Wartens stoppt den Lauf nie. pending von dsh_send bedeutet, dass der Schreibvorgang den Kanal erreicht hat und der Lauf bei der erneuten Prüfung noch aktiv war — keine bestätigte Zustellung; warten Sie, statt erneut zu senden. dsh_task hinterlässt kein Envelope, daher kann sein Lauf nicht fortgesetzt werden; Ketten laufen über dsh_spawn.

Zeilen, auf die der Director sich verlassen kann

Diese Zeilen gehen in die Textausgabe des Tools, nicht nur in details, damit ein Director, der reinen Text liest, Executor, Kontinuität und Fehlercodes überprüfen kann:

model: <provider>/<model>[:<effort>]
session: <sessionId>
error [<code>]: <message>

# and one line per run from dsh_list:
<runId> state=<state> label=<label|-> model=<spec|default> started=<ISO-8601>

Fehlercodes

Jeder Fehler wird als expliziter Fehler-Turn mit einem Envelope-Code zurückgegeben, niemals als Teilerfolg.

Envelope-Code

Bedeutung

spawn_failed

Die DSH-Binärdatei wurde nicht gestartet.

nonzero_exit

Der Lauf endete mit einem Fehler-Exitcode.

timeout

Der Lauf endete nicht innerhalb seiner Frist.

killed

Der Lauf wurde abgebrochen.

malformed_output

DSH hat kein gültiges Envelope v1 zurückgegeben.

resume_not_found

Es gibt keine solche Sitzung zum Fortsetzen.

resume_corrupt

Die gespeicherte Sitzung ist beschädigt oder wird nicht unterstützt.

resume_busy

Die Sitzung ist bereits aktiv, oder ihre gespeicherte Vorbereitung ist reserviert.

owner_gone

Niemand hat die Lease des Laufs erneuert; der Watchdog hat sie zurückgefordert.

deadline_exceeded

Der Lauf hat seine Frist überschritten und wurde beendet.

model_not_found

Der Provider/das Modell ist nicht im DSH-Katalog enthalten.

invalid_model

Das Modell existiert, aber der Aufwand oder die Metadaten passen nicht dazu.

Standardwerte: Lauf-Frist 30 Min.; Owner-Lease 5 Min., erneuert durch jedes dsh_wait-Fenster.

Tests

bun run test          # unit + integration + bridge = 370 tests, no installed DSH needed
bun run test:resume   # resume plugin — needs an installed DSH

Verifizierte Zahlen in diesem Baum: 195 Unit- + 11 Integrations- + 164 Bridge-Tests = 370 Tests, die ohne installiertes DSH bestehen. Unit-Tests mocken bridge-core; Integrations- und Bridge-Tests laufen gegen ein gefälschtes dsh-Binary, das über DSH_BINARY injiziert wird. CI führt dieselben drei Suiten mit einem sauberen HOME aus, nach typecheck, lint, format:check (strenges tsc, Biome). test:resume importiert @deepseek-ai/* zur Laufzeit — DSH muss installiert sein.

Einschränkungen

  • Verwaiste Läufe werden beseitigt, nicht verhindert. DSH-Läufe überleben die OMP-Sitzung; das Beseitigen erfolgt beim Laden und alle 30 s. Bei sauberem session_shutdown beendet die Erweiterung ihre eigenen Läufe (SIGTERM synchron, SIGKILL bestmöglich), ohne die Registrierung zu leeren.

  • Keine Absturzwiederherstellung während der Ausführung: Ein Absturz mitten in einem Turn wird nicht wiederhergestellt; nur die DSH-Sitzung kann fortgesetzt werden.

  • Kompaktierung beim Fortsetzen liest den Header des vorherigen Laufs, bis der erste neue Request-Header geschrieben wird.

  • model im Envelope ist Best-Effort: letzte vorbereitete Request-Konfiguration, kein Nachweis des Versands.

  • Modell-Override ist pro Lauf, nicht über resumeFromRunId vererbt.

  • Hub-Metriken sehen keine DSH-Tokens.

Status, Historie, Lizenz

Experimentell v0.1 (0.1.0). Die Schnittstellenverträge liegen in docs/contracts/; docs/dsh-update-checklist.md behandelt DSH-Upgrades. Alles, was ein Benutzer oder ein Modell liest, ist Englisch; Kommentare im Code und Testnamen sind Russisch. MIT-Lizenz.

Related MCP Connectors

Related MCP Servers