Repository navigation
Description
Continued in the community repository
Following the maintainer's guidance in kagent#3195, this integration has moved to kagent-dev/byo-ext#2. Closing this core feature request because the work will continue as a community BYO integration. The community PR is still open and has not been merged. The original proposal below is retained as historical context.
📋 Prerequisites
- I have searched the existing issues to avoid creating a duplicate
- By submitting this issue, you agree to follow our Code of Conduct
📝 Feature Summary
Support DeepSeek Harness (DSH) as a kagent-managed agent through a maintained BYO integration or a native runtime adapter.
❓ Problem Statement / Motivation
DSH users should be able to keep its execution loop, plugins, and conversation state while using kagent for lifecycle management and access through the existing API and UI.
kagent 1.x alpha supports kagent, codex, claude, and byo runtimes. A BYO container must implement kagent's A2A gRPC service and readiness contract, so a DSH deployment still needs a protocol bridge. Using a DeepSeek model with another runtime does not provide DSH's execution behavior.
💡 Proposed Solution
Evaluate a pinned DSH version, then choose between a documented BYO integration and a native adapter. The evaluation should cover:
- Mapping prompts, assistant output, tool events, and completion or failure to A2A tasks.
- Applying model configuration, credential handling, workspace paths, and MCP bindings.
- Canceling a turn and continuing the same conversation afterward.
- Preserving the required DSH state across Actor suspension, restoration, and replacement.
DSH's ACP interface supports session creation and resumption, MCP attachment, cancellation, and permission requests. It emits semantic updates rather than raw provider deltas and does not support transcript replay. Output granularity and history ownership need an explicit mapping.
The SDK exposes subprocess control and event subscriptions, but currently lacks mid-turn cancellation and an implemented interactive approval flow. Its run() result is the last committed assistant response in an activity interval, not necessarily a response to one prompt. Protocol selection should account for these limits.
A native adapter should reuse kagent's shared runtime event model and A2A executor. API changes can follow agreement on the adapter's scope.
Validation should include consecutive turns, tool success and failure, cancellation followed by another turn, and conversation continuity after suspend/resume. If approvals are included, test allow, reject, and cancellation while awaiting a decision. Document any unsupported capabilities.
🔄 Alternatives Considered
- Run DSH independently, with separate lifecycle and conversation management.
- Build a custom BYO bridge and maintain its protocol mapping and version compatibility locally.
- Use an existing kagent runtime with a DeepSeek model when DSH's execution loop and plugins are not required.
🎯 Affected Service(s)
Multiple services / System-wide
📚 Additional Context
This request has not been validated with a working integration. DSH's README warns that its preview can introduce breaking changes, so support needs pinned versions and an upgrade policy.
Maintainer feedback is requested on whether DSH integration fits the project's scope, whether BYO or a native adapter is preferred, which capabilities are required initially, and whether a separate Enhancement Proposal is needed.
🙋 Are you willing to contribute?
- I am willing to submit a PR for this feature
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsBacklog
Activity
foxj77 commentedon Oct 17, 2026
I've been looking into this as well and ran a spike against a real DSH process to get evidence for the BYO vs native question. @Jacob953, you mentioned you're willing to submit a PR. Happy to coordinate so we don't duplicate work.
Setup:
@deepseek-ai/dsh@0.2.1-alpha.5(commit1517a4db), driven from Go over ACP (dsh --profile acp). Model calls went to a local Anthropic-compatible mock throughDEEPSEEK_BASE_URL, including kagent's ownmockllmunmodified. Run on macOS. Linux/pod behaviour is not tested yet.What works
cancelledin ~6 ms; a running bash tool is killed; the next prompt workssession/resume, including after SIGKILL. Requires the workspace at the same real path (symlinks are fine); otherwise it fails cleanly with-32602mcp__<server>__<tool>, auth headers pass through. MCP servers must be re-sent on every resumecompression: none): input/output/cache tokens on every call. No reasoning-token countGaps
session/request_permission, sorequireApprovalcan't be honoured. A pending approval also doesn't survive a process restart. I'd expect the harness to reportApprovals: false.dsh_session_log, up to 8 MiB) and a plugin inventory to every model request, including to a customDEEPSEEK_BASE_URL. Telemetry exports to DeepSeek unlessDSH_TELEMETRY_DISABLEDis set. A small profile overlay turns all of this off; I verified it on the wire.Proposal
go/adk/pkg/appandgo/harness/runtime/a2agets the shared executor (cancellation, HITL parking, continuation, tracing) with no API change. The native-only work is controller-side: compiler, capability record, images, Helm, CI.Questions for maintainers:
DeepSeekHarnessbe welcome later as experimental?requireApproval, documented as unsupported?Anthropicwith a base-URL override for now, and propose a DeepSeek provider separately?I've opened discussions upstream for the streaming and upload-default gaps: . I'm happy to share the spike code and captured transcripts if useful.
Jacob953 commentedon Oct 17, 2026
Thanks for sharing the spike and offering to coordinate. The DSH integration has moved to the community repo following the maintainers’ guidance: proposal and PR.
The adapter already implements MCP
requireApprovalthrough a proxy that holds calls before dispatch and persists approval state in Actor DATA. We’ve verified approval restoration after Worker replacement and continuation from settled forks in a real cluster. Native ACP permissions still require the original process, so that limitation remains, butApprovals: falsewould understate the adapter’s capabilities.We currently pin DSH
0.2.0-rc.2, while your spike uses0.2.1-alpha.5. We also wait forsession/closeand its persistence flush before completing the task, disable telemetry, and build with an npm lockfile. Incremental output remains a gap.Your per-call usage findings are particularly useful—we’ve now confirmed those records in our pinned version too, but haven’t connected them to kagent telemetry yet. Would you be interested in coordinating on usage reporting or compatibility with the newer DSH version? Your spike code and captured transcripts would be helpful.
foxj77 commentedon Oct 17, 2026
Thanks @Jacob953, and thanks for pointing me to byo-ext. I hadn't seen #3195 or the move.
You're right about approvals. I was only looking at what DSH exposes natively. Holding MCP calls in a proxy before dispatch, with the decision persisted in Actor DATA, is a better answer than
Approvals: false. I've corrected that in the write-up.I'm not going to be able to take on work in the PR myself, but I'm happy to share everything from the spike in case it's useful for yours. I'll ping you an invite to the code.
It's throwaway evidence code, not something to merge:
0.2.1-alpha.5, DSH'sllm-deepseekprovider, macOS, mock model servers only. It includes the probe code, ACP transcripts (multi-turn, cancel during a stream and a tool, resume after SIGKILL, MCP, the four permission cases), raw session logs, and a findings doc.A few things that may help directly:
Usage mapping. This is how the spike maps the session log onto
runtime.ModelCall:runtime.ModelCallProvider,ResponseModelassistant/message.data.message.source.{provider,model}RequestModelrequest/context.data.modelOutputTokens,CacheReadTokens,CacheWriteTokensdata.usage.*StopReasonfinishchunk indata.stream(stop/tool-calls/max-tokens)Start/Endstep/start.timefor the same turn/step /assistant/message.timeCanceled+UsagePartialdata.interrupted: truewith nousage(a cancelled call has no usage)ReasoningOutputTokens,ResponseID,RequestIDllm-deepseekpathOne caveat. On the
llm-deepseek(Anthropic wire) path,inputTokensexcludes cache tokens, so kagent'sInputTokensneedscacheReadTokens + cacheWriteTokensadded back. byo-ext usesllm-pi-ai, which may normalise differently. If itsinputalready includes cached tokens, the same rule would double-count, so it's worth checkingtotalTokensagainst the parts on a record from your pinned version.Newer DSH versions. A session created by
0.2.0-rc.2resumes under0.2.1-alpha.5, and the reverse works too, on a sharedDSH_HOMEwith raw JSONL. Recall works, there's still onesession.v4.jsonlgeneration, and no migration is needed. (npm'slatestis rc.2, which sorts below0.2.1-alpha.5, so "newer" means the alpha line.) I didn't run byo-ext itself against alpha.5.Durability. In my runs, the
session/promptresponse arrived about 1 ms before that turn'sturn/endwas on disk, and a SIGKILL in that window dropped a reply the client had already seen. Yoursession/closeflush covers this. If closing every task ever becomes a cost, waiting for the turn'sturn/endrecord took about 1.5 ms in my measurements and keeps the session open.Good luck with the PR and shout if I can be of any help.