Skip to content

feat(llm): add DeepSeek as first-class cloud provider (#204)#205

Merged
ProfSynapse merged 1 commit into
mainfrom
feat/deepseek-provider
May 8, 2026
Merged

feat(llm): add DeepSeek as first-class cloud provider (#204)#205
ProfSynapse merged 1 commit into
mainfrom
feat/deepseek-provider

Conversation

@ProfSynapse
Copy link
Copy Markdown
Owner

Summary

Adds DeepSeek as a direct cloud provider (alongside OpenAI / Anthropic / Google / Mistral / Groq / OpenRouter / etc.). Resolves #204.

DeepSeek's API is OpenAI-compatible, so the adapter is structurally a Groq-clone that plugs into the existing two-sided thinking abstraction (ThinkingEffortMapper for input, unified StreamChunk.reasoning for output) — the chat UI renders DeepSeek reasoning blocks for free, exactly like Claude / o-series / Gemini / Groq today.

Models

Model Context Max output Pricing (in / out per 1M) Cache hit
deepseek-v4-flash 1M 384K $0.14 / $0.28 $0.0028
deepseek-v4-pro 1M 384K $0.435 / $0.87 (75% off until 2026-05-31) discounted

Each ships with a -thinking variant. Thinking mode uses DeepSeek's proprietary thinking: { type: "enabled", reasoning_effort: "high" \| "max" } request shape (NOT OpenAI's reasoning.effort), and surfaces reasoning via delta.reasoning_content (streaming) or message.reasoning_content (non-streaming). The unified ThinkingEffortMapper.getDeepSeekParams handles request-side translation; the adapter's stream extractor maps reasoning_contentStreamChunk.reasoning.

What changed

  • New: DeepSeekAdapter.ts (375 LoC), DeepSeekModels.ts (111 LoC), DeepSeekAdapter.test.ts (275 LoC, 18 tests)
  • Wired through 13 touchpoints: SupportedProvider union, AdapterRegistry, ProviderTypes defaults, ProviderManager def, ValidationService, ThinkingEffortMapper (incl. ProviderThinkingConfig interface + supportedProviders list), platform.ts mobile-compatible list, ModelDropdownRenderer, ProviderUtils (display name, color, emoji, abbreviation, streaming/functions/JSON lists), ProvidersTab (+cloudIds), VisionMessageFormatter, ingestTool labels
  • frequency_penalty / presence_penalty are stripped from outgoing requests (DeepSeek removed support)
  • Mobile-compatible (uses requestUrl-backed REST transport)

Test plan

  • npx jest tests/services/llm/adapters/deepseek — 18/18 passing
  • npx tsc --noEmit — clean
  • npm run build — clean
  • Manual smoke: enter API key in Settings → Providers → DeepSeek, send a message with deepseek-v4-flash, send a tool-using message with deepseek-v4-flash-thinking, verify reasoning block renders in the chat UI

Follow-ups (not blocking)

  • ProviderManager.ts (659 LoC) and ProvidersTab.ts (645 LoC) crossed the 600-line maintainability threshold from the wiring additions. Both are pre-existing tech-debt watch items — refactor when next touched, not as part of this PR.

🤖 Generated with Claude Code

- New DeepSeekAdapter (OpenAI-compatible REST, Bearer auth, https://api.deepseek.com)
- 4 model entries: deepseek-v4-flash[-thinking], deepseek-v4-pro[-thinking]
- Thinking mode hooked into ThinkingEffortMapper with proprietary
  thinking: {type: 'enabled', reasoning_effort: 'high'|'max'} shape
- delta.reasoning_content / message.reasoning_content surfaced via
  unified StreamChunk.reasoning field — UI renders for free
- frequency_penalty/presence_penalty stripped (DeepSeek removed support)
- Wired through 13 touchpoints (types union, AdapterRegistry,
  ProviderTypes default, ProviderManager def, ValidationService,
  ThinkingEffortMapper, platform mobile list, ModelDropdownRenderer,
  ProviderUtils, ProvidersTab + cloudIds, VisionMessageFormatter,
  ingestTool labels)
- Mobile-compatible (requestUrl REST transport)

Resolves #204

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ProfSynapse ProfSynapse merged commit 3f5062e into main May 8, 2026
@ProfSynapse ProfSynapse deleted the feat/deepseek-provider branch May 8, 2026 13:13
ProfSynapse added a commit that referenced this pull request May 11, 2026
PR #205 (v5.8.14) added the DeepSeek adapter and DEEPSEEK_MODELS array
but missed the two central registries that feed the model dropdown UI,
so DeepSeek models never appeared even with a valid API key:

- StaticModelsService.ts — import, providerModels array in
  getAllModels, switch case in getModelsForProvider, and the
  getAvailableProviders whitelist all lacked 'deepseek'
- ModelRegistry.ts — AI_MODELS record and DEFAULT_MODELS record both
  lacked the deepseek entry

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ProfSynapse
Copy link
Copy Markdown
Owner Author

Follow-up: v5.8.15 (just released — https://github.com/ProfSynapse/nexus/releases/tag/5.8.15) fixes a wiring miss from this PR that prevented the DeepSeek models from appearing in the model dropdown even with a valid API key.

The 13 touchpoints listed above were all real, but two central aggregators were missed:

  • src/services/StaticModelsService.ts — the UI's source of truth (getAllModels, getModelsForProvider, getAvailableProviders whitelist) had no deepseek entries, so getModelsForProvider('deepseek') hit the default: return [] branch.
  • src/services/llm/adapters/ModelRegistry.tsAI_MODELS and DEFAULT_MODELS records were both missing the deepseek key.

Fix in commit 4a35280 (10 lines across the 2 files). Note for the next provider addition: the "13 wiring touchpoints" checklist should include these two aggregators — they're the gate everything else flows through.

cc @surill (#204) — the v5.8.15 release on Obsidian Community Plugins / direct download now actually surfaces the models. Please grab the new build and report back if the dropdown still misbehaves.

@surill
Copy link
Copy Markdown

surill commented May 12, 2026

你好,我更新了v5.9.0,DeepSeek模型已经可以正常获取模型列表,目前对话功能已经可以正常使用,但是调用工具出现了问题,返回错误:❌ Tool execution failed: streaming generation failed with HTTP 400

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

模型支持列表能否增加DeepSeek

2 participants