Repository navigation
Conversation
Two independent defects make a `deepseek-acp` sub-agent unusable as a delegation target, and neither is fixable from the agent's own settings. 1. `read_response_limit` gave DeepSeek the 2 MiB `fs/read_text_file` cap. Like Antigravity and Kimi Code — the two agents already exempted here — `deepseek-acp` ships the `read` tool's `offset`/`limit` as its own page arguments and asks the host for the WHOLE file, paging the answer itself, so the "narrow with line/limit" hint never reaches it and every read of a file past 2 MiB fails with `Invalid params` the model cannot act on. Measured twice in 2026-11 on a 2.65 MiB single-line bundle: the child sat in `Prompting` until cancelled by hand, the second time for over eight hours, because `deepseek-acp` carries no retry and codeg's delegation has no timeout. 2. There was no way to keep a child off the permission card. `deepseek-acp` 0.9.0 has no approval MODE at all (`set_mode` / `availableModes` appear nowhere in the package) and hard-codes an allow-once / reject-once pair in its `approval/request` handler, so a write tool call parked forever with its parent delegation waiting on it. `CODEG_AUTO_APPROVE` (inherited by every ACP child codeg spawns) now makes codeg answer `session/request_permission` itself with the request's `allow_once` option, publishing the same `ToolApproval` record a user's click does. Deliberately opt-in and agent-agnostic: the flag IS the policy, and only `allow_once` is used — never `allow_always`, which would write a standing rule into the user's own agent settings. A request offering no `allow_once` option still falls through to the card, unchanged.
There was a problem hiding this comment.
🟡 Changes recommended
When CODEG_AUTO_APPROVE is enabled, the new branch bypasses CLI permission policies and inherited permission ceilings, potentially approving writes the run should deny.
4 open issues
What changed in this PR
Improves DeepSeek delegation in Codeg’s ACP runtime by supporting larger whole-file reads and adding opt-in permission auto-approval.
Changes:
- Gives DeepSeek the existing 16 MiB whole-file read ceiling.
- Adds
CODEG_AUTO_APPROVEto selectallow_once, preserving the card flow when that option is unavailable. - Emits approval records identifying automatic decisions with the
auto_approveorigin.
| File | Description |
|---|---|
src-tauri/src/acp/mod.rs |
Defines the environment flag parser and automatic-approval origin. |
src-tauri/src/acp/file_system_runtime.rs |
Adds DeepSeek to the larger read-response allowance. |
src-tauri/src/acp/connection.rs |
Handles automatic permission responses and emits approval records. |
Review effort: Max
| // rule into the user's own agent settings (see | ||
| // [`PermissionOptionInfo::allow_once_in`]). A request offering no such | ||
| // option falls through to the card exactly as before. | ||
| if crate::acp::auto_approve_enabled() { |
| if crate::acp::auto_approve_enabled() { | ||
| if let Some(option_id) = | ||
| PermissionOptionInfo::allow_once_in(&card.options).map(|o| o.option_id.clone()) |
| if let Some(option_id) = | ||
| PermissionOptionInfo::allow_once_in(&card.options).map(|o| o.option_id.clone()) | ||
| { | ||
| let scope = permission_log_scope(state).await; |
| tool_call_id, | ||
| option_kind: kind, | ||
| option_name: name, | ||
| origin: crate::acp::AUTO_APPROVE_ORIGIN.to_string(), |
|
One more note on why the read fix has to be per-agent rather than a blanket raise. I considered simply raising The two agents already on it are there for the same reason, and |
…is a release `cargo build --release --bin codeg` produced a dev binary: `tauri` was compiled without `custom-protocol`, so `tauri-build` set `DEP_TAURI_DEV=true` and the app asked `devUrl` (http://localhost:3000) for a dev server it never started — the window showed ERR_CONNECTION_REFUSED while the process ran fine. `pnpm tauri build` turns the feature on implicitly, which is why only manual builds hit this. Declaring it here makes `--features custom-protocol` explicit and nameable.


TL;DR
A
deepseek-acp(DeepSeek Harness) sub-agent cannot be used as a delegation target today. Two independent defects, and neither is reachable from the agent's own settings — so users cannot work around either one.This PR fixes both. Together they turn
deepseek-acpfrom "spawns fine, then wedges" into a working delegation target — verified end-to-end against a real task.Promptingforever on any file > 2 MiBread_response_limitgave it the 2 MiB cap; it never narrows a readCODEG_AUTO_APPROVEThe problem, precisely
1. Unreadable files park the child permanently
read_response_limitalready exempts Antigravity and Kimi Code fromFS_MAX_READ_RESPONSE_BYTES, and the comment above it states the reason:deepseek-acp0.9.0 is the third member of exactly that class. It ships thereadtool'soffset/limitas its own page arguments and asks the host for the whole file, paging the answer itself. So:line/limit" hint never reaches it — the model sees onlyInvalid paramsdelegation.agent_defaults'mode_idcannot help; there is no such modedelegate_to_agenthas no timeout, so the parent waits tooResult: one oversized read takes down the child and stalls the parent delegation.
Measured twice in 2026-11 on a 2,650,000-byte single-line bundle (
index.js). Both times the child sat inPromptinguntil cancelled by hand — the second time for over eight hours, across a machine restart.Note that splitting the read does not help, which is the part that makes this look like a mystery bug: the host checks cumulative bytes, not lines, so
limit=500on a single-line file trips the same error.2. Every write parks on a card nobody is looking at
deepseek-acp0.9.0 has no approval mode at all —set_mode,availableModesandcurrentModeIdappear nowhere in the package. Itsapproval/requesthandler hard-codes exactly two options:There is no "always". So
delegation.agent_defaultscannot reach it, and since a delegation child has no tab, nobody sees the card. The firstWrite/Edittool call parks indefinitely and the parent waits on it.This is the deeper of the two problems: even with the read limit fixed,
deepseek-acpcannot edit code as a sub-agent, which is most of what a delegation is for.What this PR changes
read_response_limit— one lineSame 16 MiB ceiling the other two long-read agents already get. No new mechanism — the exemption and its rationale already exist; DeepSeek simply was not listed.
CODEG_AUTO_APPROVE— opt-in auto-approveWhen set, codeg answers
session/request_permissionitself with the request'sallow_onceoption, and publishes the sameToolApprovalrecord a user's click produces — so the transcript chip and the approval history look identical to a manual approval.Design choices, deliberately conservative:
1/true/yeskeeps the ordinary card flow byte-for-byte unchanged.allow_onceonly — neverallow_always. The latter writes a standing rule into the user's own agent settings. This matches the reasoningPermissionOptionInfo::allow_once_inalready documents.allow_onceoption still reaches the card, exactly as today.Verification
Built from
v0.42.0and installed:Before — a delegated
deepseekchild asked to read the 2.65 MiB single-lineindex.jssat inPrompting, loggedfs/read_text_file -32602, and was cancelled by hand after eight hours.After — the same task completes in under two minutes and returns a verified answer (20
PRESALES_*symbols enumerated; the target string absent; cross-checked three ways, including ruling out an encoding artifact).And the write path, which was previously a guaranteed permanent hang:
No card was ever raised; the log shows
[ACP] permission … auto-approved … (option=allow-once, CODEG_AUTO_APPROVE).Why this is worth a release slot
deepseek-acpis the cheapest capable agent in codeg's target list, which makes it the natural choice for the high-token grunt work — reading files, running tests, routine edits — with a stronger model reserved for hard problems. That is a headline use case for a multi-agent aggregator, and right now it fails on first contact.Both defects are invisible from the UI: the child spawns with no error, shows
Prompting, and never moves. There is nothing the user can do from within codeg — no setting, no mode, no retry. That is the signature of a bug the host has to fix.The read-limit fix is a one-line addition to an exemption whose stated rationale already names this exact failure mode; it costs nothing and closes a trap. The flag is opt-in and touches no existing path when unset, so it cannot regress current behaviour.
Not addressed here
delegate_to_agentstill has no timeout. Any adapter that stalls for any other reason can still hold its parent indefinitely. I left it out deliberately: choosing between a wall-clock cap and a no-progress cap is a policy decision that deserves its own discussion, and burying it inside this PR would make both harder to review.I am happy to follow up with that as a separate change if you would like.