SPB Git

spb/zyquo-cloud Public MIT

Native macOS AI chat client for 12 cloud providers — your keys, every cloud model, one beautiful chat.

Swift 97.4% Shell 1.7% Makefile 1%
8.4 KB · 115 lines markdown
Rendered Raw Blame History
1<!--2  deepseek.md3  Zyquo Cloud4  Author: Simon-Pierre Boucher5  Mail: contact@spboucher.ai6-->78# DeepSeek — API Research (Phase 0)910Researched 2026-07-30 against official docs (api-docs.deepseek.com) and a **live `/models` probe with a real key** (`/tmp/zyquo-probe/deepseek.json`). Major change vs older integrations: **`deepseek-chat` and `deepseek-reasoner` are RETIRED** — only `deepseek-v4-flash` and `deepseek-v4-pro` exist now.1112---1314## 1. Base URL & Endpoints1516Base: `https://api.deepseek.com` (OpenAI-compatible). An Anthropic-Messages-compatible surface also exists at `https://api.deepseek.com/anthropic` (not needed — Zyquo Cloud uses the OpenAI surface via `OpenAICompatibleClient`).1718| Endpoint | Method | Purpose |19|---|---|---|20| `/chat/completions` (also `/v1/chat/completions`) | POST | Chat (streaming + non-streaming) |21| `/models` | GET | List models |22| `/user/balance` | GET | Account balance (nice-to-have for the usage footer) |2324Docs: https://api-docs.deepseek.com/ and https://api-docs.deepseek.com/api/create-chat-completion2526## 2. Authentication2728`Authorization: Bearer $DEEPSEEK_API_KEY`. Keys from platform.deepseek.com.2930## 3. Chat Model Catalog3132Live probe (2026-07-30) returns exactly two models. Specs from https://api-docs.deepseek.com/quick_start/pricing. Both support **streaming, vision — NO (text-only; unverified whether V4 added image input — docs do not document vision input; treat as text-only), tools/function calling (up to 128 functions), JSON mode (`json_object`), and thinking mode** (default ON).3334| Model ID | Context | Max output | $/1M input (cache hit) | $/1M input (cache miss) | $/1M output | Thinking | Concurrency |35|---|---|---|---|---|---|---|---|36| `deepseek-v4-flash` | 1,000,000 | 384K | $0.0028 | $0.14 | $0.28 | ✅ default on (also non-thinking) | 2,500 |37| `deepseek-v4-pro` | 1,000,000 | 384K | $0.003625 | $0.435 | $0.87 | ✅ default on (also non-thinking) | 500 |3839**Retired legacy IDs (do NOT ship in ModelCatalog):** `deepseek-chat` and `deepseek-reasoner` were routing aliases (chat = non-thinking mode, reasoner = thinking mode of the current generation, latterly resolving to `deepseek-v4-flash`). They stopped resolving on **2026-07-24 15:59 UTC** and now return errors (404-class). V4 launched in preview 2026-04-24, GA 2026-07-20. If migrating user configs: `deepseek-chat``deepseek-v4-flash` with `thinking.type: "disabled"`; `deepseek-reasoner``deepseek-v4-flash` with thinking enabled (note: reasoner mapped to **Flash**, not Pro). Sources: [DeepSeek V4 migration](https://ecorpit.com/deepseek-v4-migration-legacy-api-cutoff-july-2026/), [Developers Digest guide](https://www.developersdigest.tech/blog/deepseek-chat-to-v4-migration-guide), [TheRouter.ai](https://therouter.ai/news/deepseek-chat-reasoner-deprecation-v4-migration-routing/) (third-party corroboration of official release notes).4041Max-output default vs maximum split is not documented beyond "384K max" — default `max_tokens` when omitted: unverified.4243## 4. Request / Response Format4445**OpenAI-compatible** with DeepSeek extensions/deviations (https://api-docs.deepseek.com/api/create-chat-completion):4647- `model`: `"deepseek-v4-flash" | "deepseek-v4-pro"`48- `messages`: roles `system` / `user` / `assistant` / `tool`; optional `name`49- `temperature`: 0–2, **default 1**; `top_p`: 0–1, default 150- `max_tokens`: nullable int (input + output ≤ context)51- **`thinking`**: `{ "type": "enabled" | "disabled" }` — default **enabled**; plus **`reasoning_effort`**: `"high" | "max"` (defaults vary by request type; exact default unverified)52- `stream`, `stream_options: {"include_usage": true}`53- `response_format`: `{"type": "text" | "json_object"}` (no `json_schema` documented)54- `tools` (≤128 functions), `tool_choice`, `logprobs` + `top_logprobs` (0–20), `stop` (≤16 sequences)55- **Deprecated/removed:** `frequency_penalty` and `presence_penalty` — "no longer supported". Do not surface these sliders for DeepSeek in the per-conversation parameters UI.5657```json58POST /chat/completions59{60  "model": "deepseek-v4-flash",61  "messages": [62    { "role": "system", "content": "You are a helpful assistant." },63    { "role": "user", "content": "Reply with exactly: OK" }64  ],65  "thinking": { "type": "enabled" },66  "reasoning_effort": "high",67  "max_tokens": 4096,68  "stream": false69}70```7172Response deviations from vanilla OpenAI:73- `choices[0].message.reasoning_content` (nullable string): "For thinking mode only. The reasoning contents of the assistant message, before the final answer." → this feeds Zyquo Cloud's collapsible "Thinking…" section.74- `finish_reason` values: `stop`, `length`, `content_filter`, `tool_calls`, **`insufficient_system_resource`** (DeepSeek-specific — surface as "DeepSeek servers overloaded").75- `usage`: `prompt_tokens` (= `prompt_cache_hit_tokens` + `prompt_cache_miss_tokens`), `completion_tokens`, `total_tokens`, `prompt_cache_hit_tokens`, `prompt_cache_miss_tokens`, `completion_tokens_details.reasoning_tokens`. Cost calc must use hit/miss split (cache-hit input is ~50× cheaper).7677**Vision:** not documented for V4 — treat DeepSeek as text-only (no `image_url` support; unverified whether it errors or ignores).7879**Legacy V3-era rule** ("do not pass `reasoning_content` back in the next request or the API errors") is **unverified for V4** — the V4 docs no longer state it. Safe client behavior: never send `reasoning_content` back in `messages` (matches OpenAI-compat semantics either way). Whether `temperature`/`top_p` are ignored in thinking mode (as with the old reasoner): unverified for V4 — docs list them without model restrictions.8081## 5. Streaming8283Standard OpenAI SSE: `data: {chunk}` lines, terminated by `data: [DONE]`. DeepSeek specifics:84- Thinking mode streams `choices[0].delta.reasoning_content` first (while reasoning), then `choices[0].delta.content` for the final answer. The parser must watch both fields and switch the UI from the "Thinking…" section to the answer body when `content` starts.85- With `stream_options.include_usage: true`, one extra chunk with full `usage` arrives just before `[DONE]`.86- **Keep-alive under load** (https://api-docs.deepseek.com/quick_start/rate_limit): non-streaming responses may pad with empty lines; streaming sends SSE comments `: keep-alive`. The SSE parser must ignore comment lines and empty lines. If inference hasn't started after **10 minutes**, the server closes the connection — use long read timeouts.8788## 6. Special Parameters & Notes8990- **`thinking: {"type": "enabled"|"disabled"}`** — per-request toggle; default enabled on both models. Map Zyquo Cloud's "reasoning" toggle to this.91- **`reasoning_effort: "high" | "max"`** — extra thinking depth control (thinking mode).92- **Context caching is automatic** (no opt-in): repeated prefixes hit the cache and bill at the cache-hit input rate; observable via `prompt_cache_hit_tokens`/`prompt_cache_miss_tokens`.93- **`user_id`** (optional): scheduling isolation; on expanded-capacity accounts each distinct `user_id` gets its own concurrency budget.94- No `frequency_penalty`/`presence_penalty`; no `json_schema` response format; `n` not documented (unverified).9596## 7. Rate Limits & Errors9798(https://api-docs.deepseek.com/quick_start/rate_limit, https://api-docs.deepseek.com/quick_start/error_codes) DeepSeek uses **concurrency limits, not RPM/TPM**: 2,500 concurrent requests for v4-flash, 500 for v4-pro (a slot is held from send until the response completes). Exceeding → HTTP 429. Free capacity-expansion requests available. Under load, expect keep-alive padding (§5) rather than fast failures.99100| HTTP | Meaning | Handling |101|---|---|---|102| 400 | Invalid request body format | fix request |103| 401 | Wrong API key | "Invalid API key for DeepSeek" |104| 402 | **Insufficient balance** (DeepSeek-specific) | tell user to top up |105| 422 | Invalid parameters | fix params per message |106| 429 | Concurrency limit | backoff + retry |107| 500 | Server error | retry with backoff |108| 503 | Server overloaded | retry after wait |109110Error body: OpenAI-style `{"error": {"message", "type", "code"}}` — exact JSON shape not specified in official docs (unverified; confirm in Phase 7).111112## 8. `/models` Listing113114**Yes.** `GET /models` → minimal OpenAI shape (verified live): `{"object":"list","data":[{"id":"deepseek-v4-flash","object":"model","owned_by":"deepseek"},{"id":"deepseek-v4-pro","object":"model","owned_by":"deepseek"}]}`. IDs only — context/pricing/capabilities must come from the built-in catalog.115