Skip to content

feat: add DeepSeek Harness BYO integration - #3195

Draft
Jacob953 wants to merge 15 commits into
kagent-dev:mainfrom
Jacob953:feat/dsh-byo
Draft

Jacob953 wants to merge 15 commits into
kagent-dev:mainfrom
Jacob953:feat/dsh-byo

Conversation

@Jacob953

@Jacob953 Jacob953 commented Oct 14, 2026 •

Copy link
Copy Markdown

Migration to a community harness repository

This integration will move to a separate community harness repository. Following the maintainer's guidance, I agreed to contribute there. The destination repository and its contribution process are still awaiting confirmation.

This draft preserves the implementation, tests and review context until that move is coordinated. It is not a request to add another maintained harness to kagent core. Shared runtime/controller fixes belong in their own upstream PRs; the community integration will consume those contracts. The adapter, optional approval service, images, deployment example and tests will move together, with their dependencies and acceptance gaps documented below.

Implementation reviewed here: 20ed48c1. Dependency statuses checked on 2026-10-15.

What this PR implements

  1. DSH through the existing BYO contract. Runs DeepSeek Harness 0.2.0-rc.2 over ACP behind kagent's private A2A gRPC service. Reads the compiled BYO configuration and agent card, supports OpenAI-compatible Chat Completions, and retains gateway-injected credentials. Adds a pinned container build and an Agent/Harness deployment example. No native harness type, CRD fields or shared runtime/controller behavior are added. The diff consists of the DSH directory, deployment example and a Docker build-context adjustment.
  2. Conversation persistence and process ownership. Preserves the native session, workspace and storage in Actor DATA. Maps text, tool calls/results, native permission decisions and cancellation to kagent. Linux supervisors reap detached/orphaned descendants before releasing a turn; missing cleanup confirmation keeps the task unsettled. Lost-owner cancellation returns an explicit error instead of hanging or claiming cleanup succeeded.
  3. HTTP MCP integration. A local proxy enforces compiled headers, timeout and session-termination policy. Same-origin redirects are allowed; cross-origin redirects are rejected before binding credentials are forwarded. Unsupported configuration is rejected explicitly.
  4. Protected MCP tools in the standard HITL flow. requireApproval holds a call before upstream dispatch. The adapter stops DSH, saves the exact operation and trusted task/context identity, then publishes input-required. Approval executes the saved call; denial and waiting cancellation execute nothing. The result continues the same public A2A task in a new native DSH turn. Per-Actor DATA binds the conversation automatically. Wrong-context, mismatched and late decisions are rejected before task-history mutation. Proven discovery/setup failures remain retryable, and saved results are reused without dispatching the operation again.
  5. An optional external business-approval service. A separate image and PostgreSQL store support durable requests, digest-bound authenticated decisions, expiry, concurrent execution claims and result lookup. An optional notification starts a new A2A task in the same conversation. This service uses one trusted scope per configuration and separate agent/approver credentials. Its migrations affect only its own database. Lossless JSON storage preserves MCP payloads, including escaped NUL characters and large numbers; notifications request immediate A2A acknowledgement.

The protected-binding path provides unified kagent HITL and original-task continuity. The standalone service provides an independent business workflow. Neither changes DSH source or restores an interrupted native execution stack.

Known gaps and limitations

Area Current behavior and remaining work
Public task recovery after adapter replacement Requires the shared contract in #3165. This adapter implements PendingRestorer and passes separate integration tests against that PR, but its shared changes are absent from this branch. Live HITL works on the current base; a replacement adapter rejects the lost-owner continuation.
Native ACP sandbox permissions Still depend on the original live process. DSH session resume does not reconstruct its pending permission promise. The durable MCP path covers externally owned protected calls, not native sandbox escalation. No DSH patch is proposed.
Uncertain side effects A crash during MCP dispatch or native continuation can leave an unresolved operation. The adapter blocks automatic replay; a remote call may outlive HTTP cancellation. Saved results can be reused, but generic exactly-once execution, rollback and automatic reconciliation are not implemented. A later model turn may propose a call again; it must pass a fresh approval gate.
Shared Session recovery Orphaned tasks, unpublished settlement boundaries and abandoned quiescence work can still block the conversation. Local guards do not recover these states. #3010 tracks upstream recovery; #3213 provides an explicit-deletion path for one case, not continuation of the original Session.
Standalone-service notification Ambiguous delivery remains delivery_unknown and requires reconciliation; it is not resent automatically. Acknowledgement confirms acceptance, not successful completion of the follow-up model turn. Repairing notification delivery never repeats the business operation.
Supported surface One conversation per Actor, sequential protected approvals, and text input/output. No parallel approval batches, subagent/memory/Agent Plugin translation, structured output, Responses API, SSE/stdio MCP or per-server tool subsets. The MCP proxy does not forward resources, prompts, elicitation or mid-turn catalog notifications. ACP usage updates do not provide per-model-call token totals. The README lists the remaining rejected configuration fields.
Release acceptance New-path approval recovery through real Kubernetes/controller/Substrate Actor replacement and snapshot restore remains unverified. Fork and live-provider behavior are also unverified. Local fixture tests do not establish those guarantees.

Upstream dependencies and follow-up work

These items have different roles: only #3165 is the direct dependency for the implemented DATA-restored public-task continuation. The others track shared gaps or possible future reuse of temporary DSH-specific code.

Item Status Relationship to this integration
kagent PR #3165 Open, unmerged Required for restoring pending public task ownership after replacing the adapter. Tested separately at 4fe32fdbac8ffbca4b8f66c4d7c0771ad0380ab1. Revalidate against the merged contract before enabling or advertising that recovery capability.
kagent issue #3010 Open Shared orphan-task and unpublished-boundary recovery. DSH must retain its lost-owner/uncertain-cleanup guards until upstream can establish ownership, fencing and settlement safely.
kagent PR #3213 Open, unmerged Separate core fix for explicit deletion after settlement failure, addressing part of #3010. It is not included here and does not recover the original conversation or pending approval.
kagent PR #3011 Open, unmerged Fixes the shared empty cancellation response for a missing owner. Its proposed CANCELED response alone does not prove DSH descendant or remote-effect cleanup, so merging it is insufficient to remove the local guard.
kagent PR #3131, built on #3006 Both open, unmerged Related process-lifetime work. Replace the local supervisor only when a reusable owner supports native harnesses, reaps descendants that escape their process group, and confirms cleanup after supervisor death. These PRs are not prerequisites for the current local supervisor.
kagent PR #3177 Open, unmerged Related egress/origin/credential policy. Reuse a shared client policy when it enforces the same redirect and credential boundary. Gateway destination grants alone do not replace the proxy's client-side checks.
Giantswarm issue #175 and PR #216 Issue closed; PR merged in the downstream fork Related quiescence takeover and fencing work. Downstream closure/merge does not establish that the equivalent recovery is available in upstream kagent or the deployed Substrate version. No downstream patches are imported here.
DSH discussion #6989 Open discussion; no accepted answer Background on pending approvals and transcript recovery. It is not a committed upstream roadmap or a dependency of the MCP composition implemented here.

The relevant supervisor, MCP, executor and pending-turn code comments record the conditions for adopting shared capabilities. An issue being closed or a PR being merged is not, by itself, sufficient to delete a guard that enforces a stronger cleanup or ownership requirement.

Validation

  • BYO/shared-runtime race tests, Linux bridge race tests, repository Go lint, Linux-specific DSH lint and production Docker build passed locally. Focused tests were rerun after the final cancellation refinements.
  • Eleven concurrent real-DSH scenarios against the isolated feat(harness): migrate runtime suspension to DATA snapshots #3165 checkout passed: live and DATA-reconstructed allow/deny/cancel, cancellation during uncertain dispatch, cancellation during subsequent native continuation, and reconstruction after the tool result was committed. They verify stable public task/context IDs, isolated Actor state, rejection before history mutation and one execution across saved-result reuse. Current-base tests explicitly skip the shared-dependent reconstruction cases.
  • Those tests use real DSH, HTTP MCP and private A2A gRPC with the production TaskStore client/settlement wrapper. The model endpoint and controller RPC server are fixtures. No shared-core patch was copied into this branch.
  • The standalone service has PostgreSQL/MCP race coverage for authorization, immutable requests, execution claims, restart, unknown outcomes, notification boundaries and migration Up/Down. Separate real-DSH testing verified submission and result lookup across service/Runner reconstruction.
  • Earlier clean-Kind acceptance verified ordinary conversation and file continuity across automatic suspension and explicit suspend/resume. That run predates the new protected-MCP path and does not validate its Actor-replacement recovery.

Keep this PR in draft pending the community-repository move, shared dependency integration and remaining release acceptance. Migration should preserve the tests and these limits; it should not imply that outstanding shared recovery work has been completed.

AI assistance: OpenAI Codex assisted with implementation, testing and this description.

Run pinned DSH over ACP using the existing BYO payload and A2A executor.
Preserve native conversation state, cancellation and one-shot permissions.
Proxy HTTP MCP bindings to honor headers, timeouts and session termination.

Include the runtime image, dependency lock, deployment example and tests.
AI-assisted development with Codex; human review is required before upstream submission.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
Close the ACP input stream when a blocked write is canceled and bound cancellation messages by a deadline. Cover blocked prompt, setup and permission writes, plus real DSH tool errors, permission decisions and resumed MCP calls.

AI-assisted development with Codex; human review is required before upstream submission.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
@github-actions github-actions Bot added the enhancement New feature or request label Oct 14, 2026
Handle invalid remote tool schemas as startup errors and reject repeated pagination cursors. Verify remote session and DSH process cleanup.

AI assistance: implementation and validation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
AI assistance: audit and documentation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
Use a per-turn Linux subreaper and a lifetime pipe to clean up detached and orphaned tools before returning. Preserve non-object ACP input in JSON-compatible tool events so DSH can return validation errors to the model.

Validate forced and normal teardown, adapter death, unrelated process survival, non-object arguments, and the existing runtime suite under the race detector. Runtime execution now requires Linux.

AI assistance: implementation, regression tests, and validation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
Pin MCP requests and binding headers to the configured origin. Preserve
same-origin redirects with a bounded chain and reject cross-origin hops.

Use nested Linux subreapers and private cleanup confirmation to recover
when either supervisor dies during payload execution. Avoid inherited
stderr copy hangs. Keep the task unsettled if cleanup cannot be confirmed.

Verify redirect isolation, forced supervisor death, detached tool cleanup,
unrelated process survival, and missing confirmation. Run host runtime
race tests, the Linux DSH race suite, Go and Linux lint, and container checks.

AI assistance: implementation, regression tests, and validation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
Exercise the production TaskStore wrapper over gRPC, require native process cleanup before settlement, and verify file and conversation recovery with the pinned DSH runtime. Document the completed clean-cluster lifecycle acceptance and remaining coverage limits.

AI assistance: implementation and validation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
Document upstream dependencies and the guarantees needed to replace local process supervision, pending approvals and MCP origin checks. Clarify that replacing an Actor does not reconcile an orphaned controller task.

AI assistance: implementation and validation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
Return an explicit cancellation error when the shared executor emits no result. Reject lost task continuations before SDK history writes can mutate or settle the waiting task. Keep unknown cleanup fail-closed and document that these DSH-only mitigations do not provide automatic task or approval recovery.

AI assistance: implementation and validation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
@EItanya

EItanya commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Hey there! Thanks so much for the PR. I don't think we plan to add more harnesses in core, but would definitely be open to starting a community harness repo, would you be interested in contributing there?

Report a specific failed outcome when process cleanup is already confirmed before an approval decision. Verify with real DSH SIGKILL fault injection that allow, reject and cancel settle the old task and a new task continues in the same session without replaying the pending tool. Document the surviving-adapter requirement.

AI assistance: implementation and validation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
Verify with pinned DSH that session resume records an interrupted tool outcome without restoring its pending approval or running the command. Document the difference between this safety regression and durable approval continuation, and clarify adoption conditions for kagent kagent-dev#3010, kagent-dev#3011 and kagent-dev#3165.

AI assistance: implementation and validation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
@Jacob953

Copy link
Copy Markdown
Author

Thanks for the guidance, @EItanya. I'd be happy to contribute the DeepSeek Harness BYO integration to a community harness repository and help build it together with the community.

Could you share the next steps for getting involved? In particular, is a repository already planned, and are there any guidelines for its structure, testing, or contribution process? I'd appreciate a pointer to the right place to coordinate the initial setup and moving this integration over.

Record that Go ADK reproduces the shared unpublished-boundary failure and that a deletion escape does not establish pending-call recovery or safe missing-owner cancellation.

AI assistance: documentation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 15, 2026
…omptly

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 15, 2026
Bind protected calls to the runtime task and conversation, persist execution phases and results, and continue the original public task through a new DSH turn. Consume the optional shared pending-restoration contract without changing core. Cover concurrent conversations, immutable decisions, recovery, and cancellation with real DSH/MCP integration tests.

AI assistance: implementation, tests and documentation assisted by OpenAI Codex.

Signed-off-by: Junfeng Yu <64075563+Jacob953@users.noreply.github.com>
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants