Musaab Khan

Merging conflicts, resolving states.

DeepSeek subagents in Claude Code on a Max plan, without a proxy

Sunday, August 9, 2026
2,438 words
13 minute read

# github.com/bxff/claude-code-subagent-models
npm i -g claude-code-subagent-models
ccr --ds-key sk-... # once: saves your DeepSeek key, then patches and runs; never needed again

I've been running Claude Code on a Max plan, and I've wanted the subagents to run on DeepSeek, except there's no supported way to do that. The closest thing to an official path is DeepSeek's own docs: set ANTHROPIC_BASE_URL to their Anthropic-compatible endpoint, set a token, and CC runs on DeepSeek. It does, and the setting applies to the whole session, so the main agent switches over too and all Anthropic models are gone. I wanted the main loop on Opus/Fable and the subagents on deepseek-v4-flash (GA/0731, released July 31, ranks the same as Sonnet 5 on DeepSWE). It also turned out I wasn't the only one asking for this split. The tracker has a running list of requests for it,1,2,3,4 and as of August 2026 none of it is officially supported.

DeepSeek V4 Flash GA benchmark ranking: same as Sonnet 5 and Grok 4.
DeepSeek's own numbers, not yet verified on DeepSWE. Sources: DeepSeek on X, DeepSWE.

People land on two compromised workarounds. The first is running a second session pointed at DeepSeek, which works until you need both models in the same conversation.5 The second is a router, a local relay like claude-code-router or subswitch that sits between CC and the API and decides per request where to send it.6 It gives you the split, and it is also the setup Anthropic has been enforcing against, with account bans in documented cases,7 which I'll get to.

I patched the local bundle. The patch is small: DeepSeek goes through the same model resolution CC already uses for its own aliases, so it shows up in the model picker and in the subagent list like any other model. The routing patch and launcher live in one repo, and the QoL fixes I'd wanted for a while, pinning, detaching, completed subagents staying in the list instead of vanishing after 30 seconds, live in another.

Why not just use Pi or OpenCode?

In OC, a running subagent cannot be steered, cancelled, or aborted individually. By default, the main agent cannot continue until all subagents have finished, and running them in the background exists but is behind an experimental env flag. I didn't know background agents were supported until I went looking while writing this post. And even with the flag, you still cannot abort or steer a single subagent, or intervene with it in any other way. The task tool tells the model to launch subagents concurrently whenever possible, with no cap, no worker pool, and no env var to change it, which is how sessions end up with 50 to 100 subagents or 207 stuck out of 775. A HN thread on why someone stopped using OC tells the same story: it burns tokens uncontrollably.

Pi doesn't have subagents baked in; minimal is the point. There are community extensions for them, but they're lackluster. The best one, which I use, @tintinweb/pi-subagents, seems to fail half the time. And the view is not the same. In CC, a subagent feels like a proper session, as if you'd started a new CC session. In Pi it looks like a secondary view, not like a native session. There are other extensions that may be slightly better, but this is one of the most popular.

Codex got there late. Subagents went GA in March 2026, and the original implementation was rough. I remember using it before the rewrite. You had a hard limit of six subagent sessions, a cap that was deliberately halved to six at one point, and a finished subagent kept its slot until you closed it explicitly, so managing them meant constant closing and reopening. Subagent work happened in separate threads. One issue cataloged the lifecycle findings, and the maintainer's reply shows most of it was deliberate: keeping a finished subagent's slot until you closed it was on purpose, so was letting children run after the parent was cancelled, and wait returning on the first completion was by design. The outcome is the orphaned subagent family, still open with several independent reproductions: the parent loses track of them, they keep running and keep counting against the limit, and once enough accumulate the session freezes.

The rewrite, MultiAgentV2, landed in June 2026, and it was meant to fix the mess above: the slot leaks, the missing cancellation, the orphans. The tool surface changed with it: close_agent became interrupt_agent. In V1 you could only close a subagent that had already finished; the V2 version interrupts a subagent's current turn, so a running subagent could finally be stopped on its own. It encrypted the messages between parent and child, so what you told a subagent is ciphertext in your own history, and the request to restore the audit trail was closed as not planned. Sol forces V2 server-side; the workaround is a custom model catalog, a bypass at the end of the day that hides the custom-agent controls. Per-spawn model selection is gone: the child inherits the parent's model, so no more cheap children from an expensive parent. And custom providers like DeepSeek can't read the encrypted task at all, so every delegated run inside Codex is a no-op. Plain user messages to the same endpoint work fine; it's the encrypted item type Codex wraps the task in that DeepSeek can't read. The rework stabilized in v0.145.0 in July 2026 and they're still trying to prove it works. When Codex started encrypting sub-agent prompts, the top comment called the CLI "a remarkably unremarkable harness". It's further away, not closer.

CC is also the only one with what comes after subagents: dynamic workflows. It's the natural progression: one agent runs one loop, subagents fan out, and a workflow runs the whole flow. Shipped in May 2026, a workflow is a JavaScript script that orchestrates agents, runs in the background while the session stays responsive, and can fan out to sixteen concurrent agents and up to a thousand per run, with the plan living in the script instead of the context window. No other major coding agent has figured this out.

Anthropic polices the client

The router workaround does its own OAuth login to claude.ai, which means the subscription token is being used by a process that is not the official client. That is the pattern Anthropic has been enforcing against since early 2026, with harnesses like OpenClaw and OC losing subscription access and some of the people behind them banned.8

The patch avoids that pattern: no separate login, and the token stays in the official client's hands. The only trace is the extra entry in the subagent tool's model list. I didn't have to add it; remapping an existing alias like sonnet would have been trivial, and with the list identical to stock, detection becomes much harder, almost impossible. As it is, the entry looks like ordinary configuration: Anthropic's official custom model support is an environment variable, and a model added that way looks exactly like this one.

My read on what Anthropic actually cares about comes from watching CC itself. It has no problem with third-party models: DeepSeek's integration is documented and one environment variable away, and they haven't made it harder. If third-party models were the concern, they would have done something by now. The enforcement targets something else, the Max subscription running inside other harnesses. A patched CC is still arguably a CC instance, which makes this a bit risky, but a lot less risky than a router.

Reading the bundle

Anthropic accidentally shipped Claude Code's source map in an npm release a while back. The map is the original source, unminified: real function names, real comments, the whole app as it was written. The bundle is the same code compiled and minified into one file of single-letter identifiers. I gave the agent both and asked it to figure out how routing works. Every anchor in this post came from the map. Without it I'd still be staring at single-letter names.

Every request passes through buildRequest, and its opening destructure pulls the destination URL into a variable. buildRequest is a method name on the SDK's class, and minifiers rename local variables but not property names, so it ships literal. The locals around it get renamed every build, which is why the regex wildcards them but not the method itself. Here is the real line from the bundle and the regex that finds it:

// the line as it ships:
async buildRequest(e,{retryCount:t=0}={}){let r={...e},{method:n,path:o,query:c,defaultBaseURL:s}=r

// the regex, names as wildcards:
/async buildRequest\((\w+),\{retryCount:\w+=0\}=\{\}\}\)\{let (\w+)=\{\.\.\.\1\},\{method:\w+,path:\w+,query:\w+,defaultBaseURL:(\w+)\}=\2/

The captures are the three parts the patch needs: the request parameter, e in this build, the options object, r, and the base URL variable, s. The routing block is spliced right after the statement, and it reassigns s when the model name matches a provider prefix:

const $m = typeof req.body?.model === "string" ? req.body.model : "";
if ($m) {
  const $p = JSON.parse(process.env.CC_PROVIDERS || DEFAULT_PROVIDERS);
  for (const $x of $p) {
    if ($m.indexOf($x.prefix) === 0) {
      req.defaultBaseURL = $x.baseUrl;
      req.headers.Authorization = "Bearer " + (process.env[$x.apiKeyEnv] || "");
      break;
    }
  }
}

The names change between versions, but the skeleton holds, so the same regex keeps matching, and every anchor is validated before anything is written. A version that renames the shape fails loudly instead of producing a broken build.

Each provider has a prefix, a base URL, and the env var holding its key; the default, DeepSeek, is baked in at patch time, and CC_PROVIDERS overrides it at runtime, so adding another provider is config, not a re-patch. The splice also stamps the auth headers, so the DeepSeek key never touches an Anthropic-bound request and the subscription token never touches a DeepSeek-bound one. A separate splice adds the model to the subagent tool's enum, so it is pickable per subagent.

Running the patched bundle under plain Bun needed two more fixes, the embedded native addons and the execPath splice, both asserted on every patch.

The model list is the one concrete tell, and telemetry would be the bigger one, so it is off: CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 in settings.json is the official switch. Enforcement is minimal as of now: patched clients are rare, and the effort has been aimed at relays and third-party harnesses, not local modifications. clawgod, which this approach borrows from, has been patching the official binary since April and is still going; as of August 2026 there is no documented case of Anthropic moving against it.

The task list

Completed subagents used to vanish after 30 seconds. Each task carries an evictAfter timestamp, and a sweep drops any task whose time has passed; completed subagents got theirs set to now plus 30 seconds. The grace period lives in two constants in the task registry, Qse=30000,Tdd=30000, and a third, dMf=30000, covers teammates and in-process tasks the same way. The patch moves all three to an hour:

// before: 30 seconds
Qse = 30000, Tdd = 30000, dMf = 30000;

// after: one hour
Qse = 3600000, Tdd = 3600000, dMf = 3600000;

Pinning keeps a subagent in the list for good. Select a task and press p: the task gets retain set with evictAfter cleared, which the sweep reads as never, and the row shows a [p] marker. Press it again to unpin, which restores the one-hour eviction.

Detach converts the transcript into a session you can resume. A subagent transcript is a sidechain of the parent session, and the resume list filters sidechains out, which is why the conversion is a copy rather than a move. The action re-stamps the conversation: fresh UUIDs, the new session id, the parentUuid chain rebuilt, isSidechain cleared, and drops claude --resume <uuid> into the input.

The extension is on GitHub and npm; the launcher and QoL config are in my-cc-config.

6

The router category is broad: claude-code-router is the best known; claude-code-proxy covers ChatGPT, Kimi, Cursor and Grok subscriptions; CC-Router and subrouter balance multiple subscriptions; subswitch splits per subagent by model name.

7

Mainstream coverage of the enforcement: Anthropic cuts Claude subscribers off from OpenClaw in a cost crackdown (TNW, April 2026); the Financial Times on the June 2026 purge of relay and VPN users, banned without warning.