@molecule/api-ai-deepseek 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,197 @@
1
+ <!--
2
+ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
+ Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
+ Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
+ To change this document, edit the module-level JSDoc in src/index.ts.
6
+ Generated: 2026-08-04T01:47:29.897Z
7
+ -->
8
+
9
+ # @molecule/api-ai-deepseek
10
+
11
+ > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
12
+ > It is written to be read by coding agents as much as by people, and is generated from this
13
+ > package's source — edit `src/index.ts` JSDoc, not this file.
14
+
15
+ DeepSeek AI provider for molecule.dev.
16
+
17
+ ## Type
18
+
19
+ `provider`
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @molecule/api-ai-deepseek @molecule/api-ai @molecule/api-bond @molecule/api-i18n @molecule/api-secrets
25
+ ```
26
+
27
+ ## API
28
+
29
+ ### Interfaces
30
+
31
+ #### `DeepseekConfig`
32
+
33
+ Configuration for DeepSeek.
34
+
35
+ ```typescript
36
+ interface DeepseekConfig {
37
+ /** API key. Defaults to DEEPSEEK_API_KEY env var. */
38
+ apiKey?: string
39
+ /** Default model. Defaults to 'deepseek-v4-flash'. */
40
+ defaultModel?: string
41
+ /** Maximum tokens for completions. */
42
+ maxTokens?: number
43
+ /** Base URL override (for proxies). Defaults to 'https://api.deepseek.com'. */
44
+ baseUrl?: string
45
+ /**
46
+ * Chat-completions path appended to {@link baseUrl}. Defaults to
47
+ * `/v1/chat/completions` (DeepSeek-direct puts the version in the path). Set
48
+ * this when the same open-weight model is served by a US OpenAI-compatible
49
+ * host whose version prefix lives in the base URL instead — e.g. DeepInfra:
50
+ * `baseUrl='https://api.deepinfra.com/v1/openai'` + `completionsPath='/chat/completions'`.
51
+ */
52
+ completionsPath?: string
53
+ /**
54
+ * Optional catalog-id → upstream-model-id map, applied to the outbound request
55
+ * ONLY. Lets a US OpenAI-compatible host (DeepInfra) receive its namespaced id
56
+ * (`deepseek-ai/DeepSeek-V4-Flash`) while the rest of the platform — pricing,
57
+ * cost ceilings, display — keeps using the canonical catalog id
58
+ * (`deepseek-v4-flash`). An id not in the map passes through unchanged.
59
+ */
60
+ modelMap?: Record<string, string>
61
+ /** Called on each rate-limited/overloaded upstream response, before any retry sleep. */
62
+ onRateLimit?: AiRateLimitCallback
63
+ }
64
+ ```
65
+
66
+ #### `ProcessEnv`
67
+
68
+ Process Env interface.
69
+
70
+ ```typescript
71
+ interface ProcessEnv {
72
+ DEEPSEEK_API_KEY: string
73
+ /** Base URL override (for credential brokers / gateways / US OpenAI-compatible hosts). */
74
+ DEEPSEEK_BASE_URL?: string
75
+ /** Chat-completions path override (see {@link DeepseekConfig.completionsPath}). */
76
+ DEEPSEEK_COMPLETIONS_PATH?: string
77
+ }
78
+ ```
79
+
80
+ ### Functions
81
+
82
+ #### `createProvider(config)`
83
+
84
+ Creates a DeepSeek AI provider instance.
85
+
86
+ ```typescript
87
+ function createProvider(config?: DeepseekConfig): AIProvider
88
+ ```
89
+
90
+ - `config` — DeepSeek-specific configuration (API key, model, max tokens, base URL).
91
+
92
+ **Returns:** An `AIProvider` backed by the DeepSeek Chat Completions API.
93
+
94
+ ### Constants
95
+
96
+ #### `aiDeepseekSecretDefinitions`
97
+
98
+ Secret definitions required by the DeepSeek AI bond.
99
+
100
+ ```typescript
101
+ const aiDeepseekSecretDefinitions: SecretDefinition[]
102
+ ```
103
+
104
+ #### `DeepseekAIProvider`
105
+
106
+ Back-compat alias for the provider class (the scaffold exported this name).
107
+
108
+ ```typescript
109
+ const DeepseekAIProvider: typeof DeepseekAIProviderImpl
110
+ ```
111
+
112
+ #### `provider`
113
+
114
+ The provider implementation.
115
+
116
+ ```typescript
117
+ const provider: AIProvider
118
+ ```
119
+
120
+ ## Core Interface
121
+
122
+ Implements `@molecule/api-ai` interface.
123
+
124
+ ## Bond Wiring
125
+
126
+ Setup function to register this provider with the bond system:
127
+
128
+ ```typescript
129
+ import { bond } from '@molecule/api-bond'
130
+ import { provider } from '@molecule/api-ai-deepseek'
131
+
132
+ export function setupAiDeepseek(): void {
133
+ bond('ai', 'deepseek', provider)
134
+ }
135
+ ```
136
+
137
+ ## Injection Notes
138
+
139
+ ### Requirements
140
+
141
+ Peer dependencies:
142
+
143
+ - `@molecule/api-ai` ^1.0.1
144
+ - `@molecule/api-bond` ^1.0.1
145
+ - `@molecule/api-i18n` ^1.0.1
146
+ - `@molecule/api-secrets` ^1.0.1
147
+
148
+ ### Environment Variables
149
+
150
+ - `DEEPSEEK_API_KEY` _(required)_ — DeepSeek API key
151
+ - Setup: Create an API key on the DeepSeek open platform.
152
+ - Get it here: [https://platform.deepseek.com/api_keys](https://platform.deepseek.com/api_keys)
153
+ - Example: `sk-...`
154
+
155
+ ### Runtime Dependencies
156
+
157
+ - `@molecule/api-ai`
158
+ - `@molecule/api-bond`
159
+ - `@molecule/api-i18n`
160
+ - `@molecule/api-secrets`
161
+
162
+ Config: `DEEPSEEK_API_KEY` (SERVER-side only) plus an optional default model id/base URL.
163
+
164
+ **Missing `DEEPSEEK_API_KEY` fails fast**: the provider throws naming the exact env var on
165
+ first use (the exported `provider` is a lazy proxy, so this fires on the first `chat()` call,
166
+ not at bond/module-load time) — it never silently sends an empty key.
167
+
168
+ **Error message disambiguation**: a plain 400 that ISN'T a context-length error (bad param,
169
+ malformed tool schema) gets its own non-retryable message distinct from the generic
170
+ "AI service error. Please try again." used for retryable failures.
171
+
172
+ ## E2E Tests
173
+
174
+ Integration checklist — drive the real UI (live preview, no mocks), adapt
175
+ each item to this app's actual chat/AI screens, and check every box off one
176
+ by one. A box you can't check is an integration bug to fix — not a skip. The
177
+ sandbox HAS an AI provider bonded, so the flow runs live end-to-end; AI
178
+ output is NON-DETERMINISTIC, so assert on STRUCTURE/behavior, not exact text:
179
+
180
+ - [ ] A message sent through the real chat UI comes back as a RELEVANT AI
181
+ reply — not an echo of the prompt, a hardcoded stub, or an empty bubble.
182
+ Ask something with a checkable answer (e.g. "What is 2 + 2?") and confirm
183
+ the response actually contains it ("4"), proving a live model answered.
184
+ - [ ] If the app streams, tokens render INCREMENTALLY — text grows word by
185
+ word in the UI, not one final blob dumped after a long frozen spinner. (A
186
+ streamed `chat()` yields `text` chunks then a final `done`; a single late
187
+ blob means the reply was awaited whole and streaming is broken.)
188
+ - [ ] Multi-turn CONTEXT is preserved: a follow-up that refers back to the
189
+ previous turn (e.g. after "2 + 2", ask "now double that" -> understood as 8) works — proving the full `messages` history is sent, not just the last
190
+ line.
191
+ - [ ] A provider failure (bad/missing key, rate limit, timeout) surfaces as
192
+ a graceful in-UI error message, NOT a crash, blank screen, a spinner that
193
+ never resolves, or an unhandled 500. Force one and watch the UI recover.
194
+ - [ ] The provider key + the provider call are SERVER-side only: the key
195
+ never reaches the browser (check the network tab, the JS bundle, and page
196
+ globals), and no route proxies arbitrary prompts to the model without auth
197
+ - a token cap — an open AI endpoint is an unbounded bill and abuse vector.
package/dist/provider.js CHANGED
@@ -42,7 +42,7 @@ class DeepseekAIProviderImpl {
42
42
  onRateLimit;
43
43
  constructor(config = {}) {
44
44
  this.apiKey = config.apiKey ?? process.env.DEEPSEEK_API_KEY ?? '';
45
- this.defaultModel = config.defaultModel ?? 'deepseek-v4-flash';
45
+ this.defaultModel = config.defaultModel ?? 'deepseek-flash';
46
46
  this.maxTokens = config.maxTokens ?? 4096;
47
47
  this.baseUrl = config.baseUrl ?? process.env.DEEPSEEK_BASE_URL ?? 'https://api.deepseek.com';
48
48
  this.completionsPath =
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molecule/api-ai-deepseek",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "DeepSeek AI provider for molecule.dev",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -17,7 +17,8 @@
17
17
  }
18
18
  },
19
19
  "files": [
20
- "dist"
20
+ "dist",
21
+ "README.md"
21
22
  ],
22
23
  "keywords": [
23
24
  "molecule",
@@ -25,18 +26,23 @@
25
26
  "deepseek"
26
27
  ],
27
28
  "license": "Apache-2.0",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/molecule-dev/molecule.git",
32
+ "directory": "packages/api/bonds/ai/deepseek"
33
+ },
28
34
  "devDependencies": {
29
- "@molecule/api-ai": "1.0.0",
30
- "@molecule/api-bond": "1.0.0",
35
+ "@molecule/api-ai": "1.2.0",
36
+ "@molecule/api-bond": "1.0.1",
31
37
  "@types/node": "26.1.2",
32
38
  "typescript": "6.0.3",
33
- "vitest": "4.1.10"
39
+ "vitest": "4.1.11"
34
40
  },
35
41
  "peerDependencies": {
36
- "@molecule/api-ai": "^1.0.0",
37
- "@molecule/api-bond": "^1.0.0",
38
- "@molecule/api-i18n": "^1.0.0",
39
- "@molecule/api-secrets": "^1.0.0"
42
+ "@molecule/api-ai": "^1.0.1",
43
+ "@molecule/api-bond": "^1.0.1",
44
+ "@molecule/api-i18n": "^1.0.1",
45
+ "@molecule/api-secrets": "^1.0.1"
40
46
  },
41
47
  "peerDependenciesMeta": {
42
48
  "@molecule/api-ai": {