feat(runtime): add DeepSeek Harness engine and no-resume history - #255
Draft
sam2tom wants to merge 2 commits into
Draft
feat(runtime): add DeepSeek Harness engine and no-resume history#255sam2tom wants to merge 2 commits into
sam2tom wants to merge 2 commits into
Conversation
Adds agent_kind="deepseek_harness" as a fifth daemon engine, driven through the harness's only supported automation surface, `dsh --profile headless <task>`: one prompt is one fresh dsh process that prints the final assistant text and exits. Verified against a real dsh install (0.1.0-rc.6 local, 0.1.0-rc.7 in an isolated prefix): the headless app takes a task positional only, its runner mints a random session id per invocation, and a second run in the same DSH_HOME/workspace has no memory of the first. The engine therefore advertises no streaming, usage, resume or permission capability, and the adapter never synthesizes a session id. Because that leaves every turn contextless, the server now injects a bounded transcript tail into the system-prompt slot for any engine whose heartbeat descriptor reports Capabilities.Resume=false — deepseek_harness and opencode today. Gating on the live descriptor rather than an engine name list means an engine that gains resume support stops receiving a duplicate transcript as soon as it advertises it. Daemon adapter: - state under ~/.parsar keyed by AgentStateKey (DSH_HOME), run-scoped `--patch` overlay deleted on cleanup, secrets only ever in env - managed models arrive as a declared llm-pi-ai route, reusing the pi wire-protocol mapping (both embed pi-ai) - unattended runs declare and select a permission preset pairing workspace-write with approval:never; patching the approval row alone fails dsh boot with "composed sandbox and approval defaults match no preset" and is re-pinned per session anyway Refactors pulled in by the new engine: - engine preflight moves from four hand-written probe blocks in connect.go to one table in agent_cli.go (identical operator output) - the AgentStateKey path sanitizer moves to internal/paths, shared with pi - the duplicated formatAgentKindLabel in RuntimePage and LocalDeviceRuntimesPanel becomes agentKindDisplayName in lib/ Also threads the trigger message id through PromptInput so the injected transcript excludes the task the run is already carrying, and pins DSH_VERSION in the sandbox image.
sam2tom
marked this pull request as draft
August 19, 2026 15:08
Both image builds hardcoded docker.io for their builder stages and took
Go's default module proxy, so a host that cannot reach proxy.golang.org
or docker.io could not build either image at all — `go mod download` and
the `FROM golang:`/`FROM node:` metadata lookups fail before any layer
runs.
Adds GOPROXY plus full-reference GO_IMAGE / NODE_IMAGE build args, the
same escape hatch BASE_IMAGE and RUNTIME_BASE already provide for the
runtime stages. Every default is byte-identical to the previous
behaviour, so CI and release builds are unchanged:
docker build -f infra/sandbox/Dockerfile \
--build-arg GOPROXY=https://goproxy.cn,direct \
--build-arg GO_IMAGE=<mirror>/library/golang:1.25-bookworm \
--build-arg BASE_IMAGE=<mirror>/library/ubuntu:22.04 .
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds agent_kind="deepseek_harness" as a fifth daemon engine, driven through the harness's only supported automation surface,
dsh --profile headless <task>: one prompt is one fresh dsh process that prints the final assistant text and exits.Verified against a real dsh install (0.1.0-rc.6 local, 0.1.0-rc.7 in an isolated prefix): the headless app takes a task positional only, its runner mints a random session id per invocation, and a second run in the same DSH_HOME/workspace has no memory of the first. The engine therefore advertises no streaming, usage, resume or permission capability, and the adapter never synthesizes a session id.
Because that leaves every turn contextless, the server now injects a bounded transcript tail into the system-prompt slot for any engine whose heartbeat descriptor reports Capabilities.Resume=false — deepseek_harness and opencode today. Gating on the live descriptor rather than an engine name list means an engine that gains resume support stops receiving a duplicate transcript as soon as it advertises it.
Daemon adapter:
--patchoverlay deleted on cleanup, secrets only ever in envRefactors pulled in by the new engine:
Also threads the trigger message id through PromptInput so the injected transcript excludes the task the run is already carrying, and pins DSH_VERSION in the sandbox image.
What & why
How
Verification
make check…Notes for reviewers