Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

DeepSeek Provider

DeepSeek as an alternative session provider: how to switch it on and add a key, which V4 models you can pick and what each is good for, the two readiness gaps and their click-to-fix, and where DeepSeek's spend and context-window limits show up.

What it is

Omniscio supports spawning Claude-Code-style sessions backed by DeepSeek's Anthropic-compatible API as an additional provider, alongside claude (the default), codex, gemini, antigravity, the Anthropic-compatible kimi / glm / minimax / meta, cursor, hermes, grok, pi, opencode, and openclaw (the registry defines 26 session-provider keys, 20 of them user-selectable/pickable; the non-pickable ones include opencode, terminal — the managed inbuilt PTY engine — and openclaw).

What the user sees

A DeepSeek session looks identical in the sidebar and main pane to a Claude session — same status dots, same streaming bubbles, same Ctrl+Enter to send, same Plan / Auto-Accept / Bypass Permissions modes, same tool-call approval UI. The provider is invisible in normal chat. The only user-visible difference is the DeepSeek icon (a non-Claude provider mark, no text label) in the session header.

The harness is identical to Claude — same claude CLI binary, same streaming, same tool-call approval flow (there is no yolo / auto-approve mode like Gemini or Anti-Gravity). But the model is not: DeepSeek is a cheaper, weaker autonomous coding agent than Claude. Omniscio offers DeepSeek's V4.1 and V4 models — all unified dual-mode models that drive the Claude-Code tool protocol (DeepSeek's own Claude Code integration uses them). Omniscio defaults a DeepSeek session to DeepSeek V4.1 Flash (deepseek-v4.1-flash) when you haven't picked a model: DeepSeek bills it below V4 Pro while rating it above, and it reads images natively. Also selectable: deepseek-v4-flash (previous generation, fast and general), deepseek-v4-pro (high-capability), and the experimental DeepSeek V4 Flash Vision (deepseek-v4-flash-vision-exp, 2026-08), which adds image input to the old Flash tier; images are converted to tokens and billed as input either way.

V4.1 Flash stalled for two days, and it was our routing (fixed 2026-09-11). V4.1 was added to the picker and made the default on 2026-09-09, and from then until 2026-09-11 a DeepSeek session that didn't name a model silently stalled — it never errored, it just sat there looking like it was waiting for you. The cause was not DeepSeek. An Omniscio-funded DeepSeek session doesn't call DeepSeek directly; it goes through Omniscio's own gateway, which forwards to a partner whose catalog only carried the older V4 models. V4.1 wasn't in it, so the request came back empty. The commit that added V4.1 updated the picker, the pricing and the docs — but not the gateway's routing file, so nothing knew where to send it. The fix adds that route (V4.1 now goes to a provider that serves it) and keeps the default on V4.1. The gateway change needs to be deployed for this to take effect.

Also removed: a second, pre-launch id (deepseek-v4.1-flash-expires-on-0910) and the launch-date switch that chose between the two. Picking a model by a vendor's announced date, rather than by whether it actually answers, is what let a broken default go unnoticed — a session pinned to that retired id now says "pick another model" instead of stalling.

The older deepseek-chat (V3) / deepseek-reasoner (R1) aliases are gone from the picker too — DeepSeek hard-retired those ids on 2026-07-24 15:59 UTC and the endpoint rejects them after, which is why the picker moved to the V4 ids.

Where to find it

How to enable

Master toggle required first. DeepSeek is an alternative provider — by default Omniscio ships as a Claude-only product, and the entire DeepSeek setup section below is hidden in Settings → Accounts. Flip Settings → Accounts → Show alternative AI providers to ON and the DeepSeek panel appears alongside Gemini, Codex, Anti-Gravity, and Kimi. With the master off, the per-project "Default provider" radio collapses to a single Claude row and the session header's provider switcher (ChangeProviderButton) hides DeepSeek — DeepSeek effectively does not exist in the UI even if every gate below is configured. Your saved API key and "Allow DeepSeek sessions" toggle are preserved across master-toggle flips.

You need two of these in place (note: no binary check — same claude binary as Claude). The opt-in toggle leads and gates the key field — the API key input appears only once DeepSeek is turned on, so a key can't be entered into a disabled provider (when off, a hint keeps the deepseek-api-key Settings-search anchor landable and a saved key is preserved):

  1. Settings → Account → Allow DeepSeek sessions in any project — opt-in toggle, off by default; same security stance as the Codex/Gemini spawn guards. Turning it on reveals the key field below.
  2. Settings → Account → DeepSeek → API key — paste a DeepSeek API key from platform.deepseek.com (encrypted at rest via Electron safeStorage). Or skip the key entirely: who pays for a DeepSeek session is DeepSeek's supply list in Settings → Accounts → Who pays & who serves, which for a new user starts as your own DeepSeek key first and Omniscio credits second (an earlier choice you made carries over). With no key saved, sessions run on Omniscio's key and draw down your prepaid credit balance (signed-in only). Reorder the list to put credits first, or add a reseller row (DeepInfra, RunInfra or InferX) to have one of them serve the model on your own account there. See model-vendors.md.

Once both are green, you can launch a DeepSeek session in three ways:

  • Per-launch override — on a fresh (zero-message) session, the ChangeProviderButton in the new session's main panel (the launch-config pickers on a fresh session) lets you pick a one-off provider before sending the first message. Non-ready providers appear aria-disabled with an "Add key…" / "Enable in Settings…" suffix and deep-link to the right Settings panel.
  • Per-project default — Edit Project dialog (three-dot menu → Edit) has a "Default provider" section listing every enabled provider. Pick DeepSeek and the project's sidebar "+ New Session" button spawns DeepSeek automatically.
  • Programmatically — anything that creates a session with provider: 'deepseek' (recipes, agent-driven sessions, the CLI control HTTP API). Same readiness gates apply on the backend.

How it behaves

Choosing the model

A fresh DeepSeek session lets you pick the model in the launch-config pickers (next to the provider chooser): DeepSeek V4.1 Flash (deepseek-v4.1-flash, newest, reads images), DeepSeek V4 Flash (deepseek-v4-flash, previous generation), DeepSeek V4 Pro (deepseek-v4-pro, high-capability), or the experimental DeepSeek V4 Flash Vision (deepseek-v4-flash-vision-exp, old Flash + image/vision input). All are unified dual-mode models that drive the Claude-Code tool protocol. The pick is staged locally and applied when you send your first message. Use default spawns V4.1 Flash rather than omitting the model flag — DeepSeek requires a real DeepSeek model id (the shared claude binary's built-in default is a Claude id its endpoint would reject), so the registry pins one via getProviderDefaultModel (in provider-models.ts). On an Omniscio-funded session the id must ALSO have a route in the gateway's own config — that mismatch is what stalled V4.1 for two days (see the note above), and it is now covered by a test that fails if a model is offered here without one. The legacy deepseek-chat / deepseek-reasoner aliases retire 2026-07-24 15:59 UTC, which is why the picker now offers the V4 ids directly. DeepSeek has no separate "reasoning effort" knob. The model list is DeepSeek's own — a DeepSeek session never inherits your Claude default model (those are Claude ids its endpoint would reject). See start-a-new-session.md.

Per-project default

Each project remembers a default provider in the projectDefaultProviders setting (a Record<projectId, ProviderId>). Empty by default — every project falls back to Claude. Change it from the project's three-dot menu → Edit → Default provider radios; the change persists immediately.

When you set a project's default to DeepSeek but DeepSeek isn't ready (toggle off or key missing), an amber "!" badge appears on that project's sidebar row. Hover the badge for a tooltip explaining the gap; click it to deep-link straight to the right Settings panel. The badge re-checks on every render, so fixing the gap clears it without a refresh. Claude defaults never show the badge — Claude is always considered ready.

Error states and fixes

Two gap codes — fewer than Gemini/Codex because there is no separate binary to check:

Gap What it means Click-to-fix lands you at…
toggle-off "Allow DeepSeek sessions" is OFF in Settings Settings → Account → Allow DeepSeek sessions toggle
key-missing No row of DeepSeek's supply list can serve right now — no DeepSeek API key, and no other row ready (Omniscio credits need you signed in; a reseller row needs its own key and switch) Settings → Account → DeepSeek API key field, or Settings → Accounts → Who pays & who serves

The real reason, not a blanket "model unavailable." When DeepSeek's endpoint rejects a request mid-session for a reason other than the model — the account is out of balance, the conversation outgrew the context window, the key became invalid, or you're rate-limited — Omniscio reads DeepSeek's actual error (carried on the zero-output synthetic placeholder, the same spot the Consumer-Terms gate reads) and shows the specific cause + fix (recharge / start fresh or pick a larger-context model / check the key in Settings / wait a moment) instead of the generic "this model may be unavailable — choose another," which now applies only to a genuinely unknown/retired model. Message-only — the session still parks as needs_you / recovery_failed. Out of balance is the exception when another row can pay: if DeepSeek's supply list has another row that can serve, the session moves to it and resends your message instead of parking (see model-vendors.md). See provider-spawn-model-availability-contract.md vendor-error-is-classified-and-named.

Context window — 1M real, but compaction runs at ~167K on the installed Claude (2026-08-22). DeepSeek V4 runs a real 1,048,576-token window (1M), far above the claude binary's ~200K assumption for a model it has no vendor row for. In practice a DeepSeek session auto-compacts at ~167K — the binary's own default point (its ~200K working window minus a ~33K reserve). An earlier attempt to push that to 400K via a setting turned out to be a no-op on the Claude version this app runs, so it was removed (see "The 400K story" below). If an overflow ever does slip through, the session auto-recovers on its own (rebuilds from its transcript and continues, bounded) instead of parking on the first hit; only if it genuinely can't recover does it fall back to the "conversation got too long" park. See context-limit-400-surfacing-contract.md.

Why not just use the whole 1M. Bigger is not better past a point: DeepSeek V4's measured recall is ~94% up to 128K and ~82% at 512K, but falls to ~66% at 1M, and the published sweet spot is 128K–512K. This is the industry-wide "context rot" effect — one study found all 18 frontier models tested degraded well before their stated limits. So a smaller working window is actually good for quality here, and the ~167K compaction point sits inside the high-quality band. (Omniscio also still nudges you toward a fresh session around 400K on this same quality basis — a separate suggestion from where the conversation compacts.)

The 400K story (2026-08-06 → corrected 2026-08-22). On 2026-08-06 DeepSeek sessions briefly compacted constantly — one live session compacted 10 times in 31 minutes before the CLI's own anti-thrash guard stopped the turn mid-work — because DeepSeek's window had been recorded as a stale 128K. That was corrected the same day to the real 1M, and a setting (CLAUDE_CODE_AUTO_COMPACT_WINDOW=433000) was added intending to place compaction at 400K. On 2026-08-22, live testing showed that setting is a no-op on the Claude version this app runs — DeepSeek had actually been compacting at ~167K all along (confirmed across 404 of 404 real compactions), so the dead setting was removed and DeepSeek now runs at the binary's ~167K default. A true 400K point would require a newer Claude binary. Full history: deepseek-compaction-thrash-postmortem.md. That ending was itself corrected on 2026-09-13 — the dial was not dead, it was half-set. See the compaction bullet under How it works under the hood: the binary resolves the dial as Math.min(believedWindow, dial), so the dial alone could never move a window the binary believed was ~200K. Paired with CLAUDE_CODE_MAX_CONTEXT_TOKENS, it works, and DeepSeek now compacts at 750K rather than ~167K.

Sub-agents on a DeepSeek session (fixed 2026-09-15)

What you saw. A sub-agent — anything a session hands a chunk of work to — died the instant it started, with "There's an issue with the selected model (claude-sonnet-5). It may not exist or you may not have access to it." The session itself kept working; only the helper it spawned failed.

Why. The --model flag pins only the session's MAIN loop. Every other model path the claude binary takes — the background model it uses for topic detection and compaction summaries, and a sub-agent that asks for a model by name — fell back to the binary's own built-in Claude names (claude-sonnet-5, claude-haiku-4-5-…). DeepSeek has never heard of those, so the request was rejected. It was invisible until a sub-agent asked for a model explicitly: a sub-agent with no model preference simply inherited the working session model and was fine, which is why this looked intermittent.

The fix. Omniscio now pins every model name the binary can fall back to — the opus / sonnet / haiku / fable aliases plus the background model — onto the model your session actually runs. Any sub-agent asking for "sonnet" now gets the DeepSeek model instead of a Claude one it could never reach. The same fix covers Kimi, GLM, MiniMax and Meta, and the aside panel.

For agents

How it works under the hood

Spawn-env redirect, no alternate manager. DeepSeek publishes an Anthropic-compatible API — same request/response shape as Anthropic's Messages API, just at a different base URL. So Omniscio reuses the existing claude CLI binary (the same one Claude sessions use) and redirects every HTTP call at spawn time by setting a handful of environment variables on the child process:

  • ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic — sends every HTTP request to DeepSeek's compat endpoint instead of api.anthropic.com.
  • ANTHROPIC_AUTH_TOKEN=<your DeepSeek API key> — supersedes the Claude OAuth/API-key for this child only. That is the shape when the row of DeepSeek's supply list that serves is your own DeepSeek key; an Omniscio credits or developer-lane row points ANTHROPIC_BASE_URL at Omniscio's gateway with a gateway credential instead, and a reseller row goes through the local model proxy on the reseller's own model id.
  • Model-alias pins — ANTHROPIC_DEFAULT_OPUS_MODEL / _SONNET_ / _HAIKU_ / _FABLE_ and ANTHROPIC_SMALL_FAST_MODEL, all set to the id this lane actually sends on --model. --model alone covers only the main loop, so without these a sub-agent (or the background small-fast model) reaches for a Claude id the vendor cannot serve. The alias vars are the ones that matter for a sub-agent: asking for model: "sonnet" requests the sonnet ALIAS, which ANTHROPIC_MODEL does not override. The id is read back from the finished argv, never re-resolved, because a model id is lane-specific (the gateway routes by the picker id, the vendor's own endpoint by its own name). See a-vendor-endpoint-pins-every-model-alias in provider-registry-contract.md.
  • Two compaction settings, always together — applyGlmAutoCompactEnv → usesDeepSeekContextWindow sets CLAUDE_CODE_MAX_CONTEXT_TOKENS=1048576 (DeepSeek's real window) and CLAUDE_CODE_AUTO_COMPACT_WINDOW=783000 (the dial), which together derive a 750K compaction point. Neither works alone: the dial is capped at whatever window the binary believes the model has, so setting it by itself leaves the point at ~167K and looks exactly like setting nothing — that is the trap that made this look unfixable from 2026-08-22 to 2026-09-13. DISABLE_COMPACT is deliberately NOT set (it would switch compaction off entirely, which is the GLM/GPT lane, not this one). Never re-clamp the window to 128K, never raise the compaction point above ~900K (past the real wall once the reply size is counted), and never set CLAUDE_CODE_MAX_OUTPUT_TOKENS for DeepSeek — V4 supports 384K output.

The child process never knows it isn't talking to Anthropic. Streaming, tool calls, --resume for multi-turn, --output-format stream-json parsing all "just work" because they're handled by the standard claude binary against an upstream that speaks the same protocol.

No alternate session manager exists for DeepSeek — session-handlers.ts gates readiness, fires the spawn_non_claude_session feature event, then falls through to the same createSessionWithPrompt() path Claude sessions use. The provider: 'deepseek' value is stored on the session row in the database; process-manager.ts reads that column and injects the right spawn-env on every CLI invocation (initial spawn, resume, aside-runner).

Compared to:

  • Codex / Anti-Gravity — separate CLI binaries (codex, agy) with their own JSON-RPC / stream protocols; need dedicated *-session-manager.ts files. DeepSeek does not — that's the entire point of the Anthropic-compat protocol.
  • Gemini — long-lived gemini --acp (ACP / JSON-RPC) resident child, like Codex/Pi. DeepSeek instead keeps the long-lived claude child process; resume is via claude --resume <uuid> exactly as for Claude.
  • OpenClaw — remote WebSocket gateway with a custom JSON-RPC envelope. DeepSeek is plain HTTP to a vendor-hosted compat endpoint.

Cost tracking

Spend hits the standard api_cost_log table because the claude CLI emits per-turn cost events in its stream-json output and process-manager.ts already plumbs those into trackApiCostRaw(). The source field on the cost row carries the provider ID (deepseek), so the Settings → Usage dashboard breaks down DeepSeek spend separately from Claude/Codex/Gemini.

Cost is re-priced, not taken verbatim. The claude binary has no DeepSeek price table, so its total_cost_usd bills DeepSeek models at Claude rates. DeepSeek is therefore costReporting: 'estimated', and Omniscio recomputes each turn from the token counts × DeepSeek's real rate (MODEL_PRICING) via applyAnthropicCompatReprice — the path shared by all four anthropic-compat vendors (DeepSeek/Kimi/GLM/MiniMax). See central-ai-spend-contract.md anthropic-compat-cost-is-repriced.

Telemetry: every successful DeepSeek spawn fires the spawn_non_claude_session feature event, recording { provider: 'deepseek' } only — no session ID, project ID, or prompt content.

Running out of credit. Spend tracking is backward-looking — it tells you what you already spent. To be warned before the account hits zero, switch on the DeepSeek balance forecast (Settings → Notifications, off by default): it reads the account balance every 15 minutes, measures the real drain, and raises one inbox card with a Recharge button when the account is projected to empty inside your warning window. See deepseek-balance-forecast.md. Note this reads the account behind your own API key; running on Omniscio's DeepSeek credits draws a different balance it cannot see.

Files

  • src/main/services/provider-setup/provider-readiness.ts — single source of truth for the 2-gate readiness check (used by ChangeProviderButton, Edit Project radios, project-row cue, spawn guard)
  • src/main/process/process-manager.ts — injects ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN per session row's provider column
  • src/main/services/providers/supply-connect.ts — walks DeepSeek's supply list at each connection and builds the first row that can serve: your key, a reseller through the proxy, Omniscio credits or the developer lane
  • src/main/ipc/session-handlers.ts — DeepSeek/Kimi spawn branch that gates readiness, fires the analytics event, and falls through to the claude path
  • src/shared/types.ts — ProviderId union, deepseekApiKey, allowDeepseekSessionSpawn setting fields
  • src/renderer/src/features/settings/sections/accounts/AccountSettings.tsx — DeepSeek section under "Show alternative AI providers"

Related

Last verified 2026-10-06