@warlock.js/ai-deepseek 4.6.0
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/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +125 -0
- package/cjs/index.cjs +255 -0
- package/cjs/index.cjs.map +1 -0
- package/esm/config.type.d.mts +146 -0
- package/esm/config.type.d.mts.map +1 -0
- package/esm/index.d.mts +4 -0
- package/esm/index.mjs +4 -0
- package/esm/known-models.d.mts +62 -0
- package/esm/known-models.d.mts.map +1 -0
- package/esm/known-models.mjs +101 -0
- package/esm/known-models.mjs.map +1 -0
- package/esm/sdk.d.mts +94 -0
- package/esm/sdk.d.mts.map +1 -0
- package/esm/sdk.mjs +153 -0
- package/esm/sdk.mjs.map +1 -0
- package/llms-full.txt +116 -0
- package/llms.txt +9 -0
- package/package.json +38 -0
- package/skills/setup-deepseek/SKILL.md +106 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog — @warlock.js/ai-deepseek
|
|
2
|
+
|
|
3
|
+
All notable changes to `@warlock.js/ai-deepseek` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
|
|
6
|
+
|
|
7
|
+
## 4.6.0
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **First release.** DeepSeek adapter for `@warlock.js/ai` — a thin wrapper over `@warlock.js/ai-openai`'s `OpenAISDK` pinned to `https://api.deepseek.com` (`provider: "deepseek"`), so all wire behavior (streaming, tool calls, structured output, error wrapping) is inherited unchanged.
|
|
12
|
+
- **`DeepSeekSDK`** — `.model()` / `.embedder()` / `.image()` / `.count()` delegated to the wrapped client. `baseURL` and `provider` are optional (default to DeepSeek's endpoint / label); every other `openai` `ClientOptions` value is forwarded verbatim.
|
|
13
|
+
- **DeepSeek-specific capability inference** (`inferReasoningCapability` / `inferVisionCapability`) — `reasoning` is auto-`true` for `deepseek-reasoner` and the `*-pro` tier, auto-`false` for `deepseek-chat` / `*-flash`; `vision` is `false` for every id (no documented vision surface). An explicit `reasoning` / `vision` per model always wins.
|
|
14
|
+
- **Built-in DeepSeek pricing defaults** (USD per 1M tokens) for `deepseek-chat`, `deepseek-reasoner`, `deepseek-v4-flash`, `deepseek-v4-pro`, so `usage.cost` is computed out of the box; overridable per model or per SDK.
|
|
15
|
+
- **`DEEPSEEK_CHAT_MODELS`** — informational list of the documented chat model ids.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Hassan Zohdy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# @warlock.js/ai-deepseek
|
|
2
|
+
|
|
3
|
+
DeepSeek adapter for [`@warlock.js/ai`](../ai). DeepSeek's API is **OpenAI-compatible** on the wire, so this package is a **thin wrapper** over [`@warlock.js/ai-openai`](../ai-openai)'s `OpenAISDK`: it constructs one internal `OpenAISDK` pinned to `https://api.deepseek.com` with `provider: "deepseek"` and delegates `model()` / `embedder()` / `image()` / `count()` to it — while injecting DeepSeek's own capability inference and built-in pricing so the right flags are set even though the model names aren't OpenAI names.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @warlock.js/ai @warlock.js/ai-deepseek @warlock.js/seal openai
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
> `@warlock.js/seal` is the recommended Standard Schema library for tool inputs and structured output. Any Standard Schema V1 library works (Zod, Valibot, …). `openai` is required because this adapter wraps `@warlock.js/ai-openai`.
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { DeepSeekSDK } from "@warlock.js/ai-deepseek";
|
|
15
|
+
import { ai } from "@warlock.js/ai";
|
|
16
|
+
|
|
17
|
+
const deepseek = new DeepSeekSDK({ apiKey: process.env.DEEPSEEK_API_KEY! });
|
|
18
|
+
|
|
19
|
+
const myAgent = ai.agent({
|
|
20
|
+
model: deepseek.model({ name: "deepseek-chat" }),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const result = await myAgent.execute("Hello!");
|
|
24
|
+
console.log(result.text);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`apiKey` is the only required field — `baseURL` defaults to `https://api.deepseek.com` (DeepSeek's OpenAI-compatible endpoint) and `provider` defaults to `"deepseek"`. `DeepSeekSDK` is a class holding one long-lived wrapped client; construct one per account and reuse it.
|
|
28
|
+
|
|
29
|
+
## API surface
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
new DeepSeekSDK(config: DeepSeekSDKConfig) // Omit<OpenAISDKConfig, "baseURL" | "provider"> + optional baseURL/provider
|
|
33
|
+
.model(config: DeepSeekModelConfig) // → ModelContract
|
|
34
|
+
.embedder(config: DeepSeekEmbedderConfig) // → EmbedderContract
|
|
35
|
+
.image(config: DeepSeekImageConfig) // → ImageModelContract
|
|
36
|
+
.count(text, model?) // approximate token count
|
|
37
|
+
|
|
38
|
+
DeepSeekModelConfig {
|
|
39
|
+
name: string; // e.g. "deepseek-chat", "deepseek-reasoner"
|
|
40
|
+
temperature?: number;
|
|
41
|
+
maxTokens?: number;
|
|
42
|
+
vision?: boolean; // override auto-inference (always false today)
|
|
43
|
+
reasoning?: boolean; // override auto-inference
|
|
44
|
+
structuredOutput?: boolean; // override; defaults true
|
|
45
|
+
responseFormat?: "json_schema" | "json_object" | "text";
|
|
46
|
+
pdf?: boolean; // opt into PDF input
|
|
47
|
+
audio?: boolean; // opt into audio input
|
|
48
|
+
// ...any other ModelConfig field forwarded to the wrapped OpenAI model
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Models
|
|
53
|
+
|
|
54
|
+
| Model | Notes |
|
|
55
|
+
| ------------------- | --------------------------------------------------------------------- |
|
|
56
|
+
| `deepseek-chat` | Non-thinking surface (V3 lineage). Fast, cheap. Reasoning **off**. |
|
|
57
|
+
| `deepseek-reasoner` | Thinking surface (R1 lineage). Emits a reasoning channel. Reasoning **on**. |
|
|
58
|
+
| `deepseek-v4-flash` | Newer flash tier. Reasoning **off** by default. |
|
|
59
|
+
| `deepseek-v4-pro` | Newer quality tier. Reasoning **on** by default. |
|
|
60
|
+
|
|
61
|
+
DeepSeek announced the legacy `deepseek-chat` / `deepseek-reasoner` names retire 2026/07/24 in favor of the `deepseek-v4-*` family; both name sets are understood by the capability inference. `deepseek.model({ name })` accepts any id the upstream serves. `DEEPSEEK_CHAT_MODELS` exports the informational list.
|
|
62
|
+
|
|
63
|
+
## Capabilities
|
|
64
|
+
|
|
65
|
+
Capabilities are inferred from the DeepSeek model **name** (via `inferReasoningCapability` / `inferVisionCapability`) and injected as explicit flags before delegating — an explicit value always wins.
|
|
66
|
+
|
|
67
|
+
| Capability | Default |
|
|
68
|
+
| ------------------ | --------------------------------------------------------------------------------------- |
|
|
69
|
+
| `reasoning` | `true` for `deepseek-reasoner` and the `*-pro` tier; `false` for `deepseek-chat` / `*-flash`. |
|
|
70
|
+
| `vision` | `false` for every DeepSeek model — no chat model documents image input (mid-2026). |
|
|
71
|
+
| `structuredOutput` | `true` (inherited from the wrapped OpenAI model), unless `responseFormat` forces a loose mode. |
|
|
72
|
+
| `promptCaching` | `true` (inherited). DeepSeek reports cache hits via `usage.cachedTokens`. |
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
deepseek.model({ name: "deepseek-chat", reasoning: true }); // force the thinking flag
|
|
76
|
+
deepseek.model({ name: "deepseek-reasoner", reasoning: false }); // suppress it
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Reasoning effort
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
const model = deepseek.model({ name: "deepseek-reasoner" }); // reasoning auto-true
|
|
83
|
+
await model.complete(messages, { reasoning: { effort: "high" } }); // → reasoning_effort: "high"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`reasoning.effort` maps to the OpenAI-compatible `reasoning_effort` param and is dropped for a non-reasoning model.
|
|
87
|
+
|
|
88
|
+
## Pricing
|
|
89
|
+
|
|
90
|
+
The adapter ships **built-in DeepSeek pricing defaults** (USD per 1M tokens, from DeepSeek's published table), so `usage.cost` is computed out of the box. Resolution at `model()` time: per-model `pricing` > SDK `pricing` registry > built-in DeepSeek default > `undefined`.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
new DeepSeekSDK({
|
|
94
|
+
apiKey,
|
|
95
|
+
pricing: { "deepseek-reasoner": { input: 0.55, output: 2.19 } },
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Embeddings & images
|
|
100
|
+
|
|
101
|
+
`deepseek.embedder({...})` and `deepseek.image({...})` delegate to the wrapped `OpenAISDK`. **DeepSeek does not officially document an OpenAI-compatible embeddings endpoint or an image-generation endpoint (mid-2026)** — these delegates exist for adapter parity and work against a compatible gateway you point `baseURL` at, but may fail against the stock DeepSeek endpoint. Use a dedicated embeddings provider (e.g. `@warlock.js/ai-openai` / `@warlock.js/ai-google`) for RAG.
|
|
102
|
+
|
|
103
|
+
## OpenAI-compatible endpoints
|
|
104
|
+
|
|
105
|
+
Override `baseURL` (proxy / gateway) or `provider` (relabel the upstream):
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
new DeepSeekSDK({
|
|
109
|
+
apiKey,
|
|
110
|
+
baseURL: "https://my-gateway.example.com/deepseek",
|
|
111
|
+
provider: "deepseek-proxy",
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Tests
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npm test
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Covers DeepSeek capability inference and the thin-wrapper delegation to `OpenAISDK`.
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
MIT
|
package/cjs/index.cjs
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
let _warlock_js_ai_openai = require("@warlock.js/ai-openai");
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai-deepseek/src/known-models.ts
|
|
5
|
+
/**
|
|
6
|
+
* Capability inference for DeepSeek chat model ids.
|
|
7
|
+
*
|
|
8
|
+
* DeepSeek's API is OpenAI-compatible on the wire (`@warlock.js/ai-deepseek`
|
|
9
|
+
* wraps {@link OpenAISDK}), but its model **names** are not OpenAI names —
|
|
10
|
+
* so OpenAI's own prefix lists (`gpt-4o`, `o3`, …) never match them. This
|
|
11
|
+
* module supplies DeepSeek's OWN name-based inference, which the
|
|
12
|
+
* {@link DeepSeekSDK} injects as explicit capability booleans into the
|
|
13
|
+
* wrapped `openai.model(...)` call (explicit config wins over OpenAI's
|
|
14
|
+
* inference inside `OpenAIModel`).
|
|
15
|
+
*
|
|
16
|
+
* Verified against the official DeepSeek API docs (api-docs.deepseek.com,
|
|
17
|
+
* mid-2026): base URL `https://api.deepseek.com`, OpenAI-compatible Chat
|
|
18
|
+
* Completions. Two reasoning-capable surfaces exist — the legacy
|
|
19
|
+
* `deepseek-reasoner` (thinking mode) and the `*-pro` tier — while
|
|
20
|
+
* `deepseek-chat` is the non-thinking surface. No DeepSeek chat model
|
|
21
|
+
* documents image (vision) input, so vision inference is conservatively
|
|
22
|
+
* `false` for every id.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Default DeepSeek chat model ids, surfaced for discovery and docs.
|
|
26
|
+
*
|
|
27
|
+
* - `deepseek-chat` — the non-thinking surface (V3 lineage). Fast, cheap,
|
|
28
|
+
* broad production coverage. Not reasoning-capable.
|
|
29
|
+
* - `deepseek-reasoner` — the thinking surface (R1 lineage). Emits a
|
|
30
|
+
* reasoning channel and accepts the reasoning-effort knob.
|
|
31
|
+
*
|
|
32
|
+
* Both legacy names are scheduled for retirement (2026/07/24 per DeepSeek's
|
|
33
|
+
* deprecation notice) in favor of the `deepseek-v4-*` family
|
|
34
|
+
* (`deepseek-v4-flash`, `deepseek-v4-pro`), which this inference also
|
|
35
|
+
* understands. The list is informational only — `deepseek.model({ name })`
|
|
36
|
+
* accepts any id the upstream serves.
|
|
37
|
+
*/
|
|
38
|
+
const DEEPSEEK_CHAT_MODELS = [
|
|
39
|
+
"deepseek-chat",
|
|
40
|
+
"deepseek-reasoner",
|
|
41
|
+
"deepseek-v4-flash",
|
|
42
|
+
"deepseek-v4-pro"
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Substrings identifying DeepSeek model ids that expose a reasoning /
|
|
46
|
+
* thinking channel and accept the reasoning-effort knob.
|
|
47
|
+
*
|
|
48
|
+
* - `deepseek-reasoner` — the dedicated thinking surface (R1 lineage).
|
|
49
|
+
* - `-pro` — the V4 quality tier (`deepseek-v4-pro`), which thinks by
|
|
50
|
+
* default per DeepSeek's docs.
|
|
51
|
+
*
|
|
52
|
+
* `deepseek-chat` (the V3 non-thinking surface) and `deepseek-v4-flash`
|
|
53
|
+
* stay `false`. A substring match tolerates date/preview suffixes the
|
|
54
|
+
* provider may append. Override per-model via
|
|
55
|
+
* `deepseek.model({ name, reasoning: true | false })`.
|
|
56
|
+
*/
|
|
57
|
+
const REASONING_CAPABLE_SUBSTRINGS = ["deepseek-reasoner", "-pro"];
|
|
58
|
+
/**
|
|
59
|
+
* Infer whether a DeepSeek model id is reasoning-capable based on the
|
|
60
|
+
* known substrings. Unknown ids default to `false` so the adapter never
|
|
61
|
+
* forwards an unsupported reasoning param to a non-thinking model.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* inferReasoningCapability("deepseek-reasoner"); // → true
|
|
65
|
+
* inferReasoningCapability("deepseek-v4-pro"); // → true
|
|
66
|
+
* inferReasoningCapability("deepseek-chat"); // → false
|
|
67
|
+
* inferReasoningCapability("deepseek-v4-flash"); // → false
|
|
68
|
+
*/
|
|
69
|
+
function inferReasoningCapability(modelId) {
|
|
70
|
+
const normalized = modelId.toLowerCase();
|
|
71
|
+
return REASONING_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Substrings identifying DeepSeek model ids that accept image (vision)
|
|
75
|
+
* input.
|
|
76
|
+
*
|
|
77
|
+
* Currently **empty**: as of mid-2026, no DeepSeek chat model documents
|
|
78
|
+
* vision input on the OpenAI-compatible Chat Completions endpoint, so
|
|
79
|
+
* inference returns `false` for every id and passing an image attachment
|
|
80
|
+
* surfaces a clear, agent-side capability error instead of an opaque 400.
|
|
81
|
+
* Append a fragment here (and a paired spec case) the day DeepSeek ships a
|
|
82
|
+
* multimodal chat model. Devs can always opt in per-model via
|
|
83
|
+
* `deepseek.model({ name, vision: true })`.
|
|
84
|
+
*/
|
|
85
|
+
const VISION_CAPABLE_SUBSTRINGS = [];
|
|
86
|
+
/**
|
|
87
|
+
* Infer whether a DeepSeek model id supports vision based on the known
|
|
88
|
+
* substrings. Today this is always `false` (see
|
|
89
|
+
* {@link VISION_CAPABLE_SUBSTRINGS}); kept as a function so the
|
|
90
|
+
* {@link DeepSeekSDK} call site and the override semantics stay identical
|
|
91
|
+
* to the other adapters, ready for a future multimodal id.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* inferVisionCapability("deepseek-chat"); // → false
|
|
95
|
+
* inferVisionCapability("deepseek-reasoner"); // → false
|
|
96
|
+
*/
|
|
97
|
+
function inferVisionCapability(modelId) {
|
|
98
|
+
const normalized = modelId.toLowerCase();
|
|
99
|
+
return VISION_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region ../@warlock.js/ai-deepseek/src/sdk.ts
|
|
104
|
+
/**
|
|
105
|
+
* DeepSeek's OpenAI-compatible Chat Completions endpoint. Verified against
|
|
106
|
+
* the official API docs (api-docs.deepseek.com, mid-2026).
|
|
107
|
+
*/
|
|
108
|
+
const DEEPSEEK_BASE_URL = "https://api.deepseek.com";
|
|
109
|
+
/** Default upstream label for models produced by this SDK. */
|
|
110
|
+
const DEEPSEEK_PROVIDER = "deepseek";
|
|
111
|
+
/**
|
|
112
|
+
* Built-in DeepSeek pricing defaults, in USD per 1,000,000 tokens, keyed
|
|
113
|
+
* by model name. Sourced from DeepSeek's official pricing table
|
|
114
|
+
* (mid-2026); `cachedInput` is the cache-hit input rate. A caller-supplied
|
|
115
|
+
* SDK `pricing` registry, or a per-model `pricing`, overrides any entry
|
|
116
|
+
* here. Update when DeepSeek revises its published rates.
|
|
117
|
+
*/
|
|
118
|
+
const DEEPSEEK_DEFAULT_PRICING = {
|
|
119
|
+
"deepseek-chat": {
|
|
120
|
+
input: .14,
|
|
121
|
+
output: .28,
|
|
122
|
+
cachedInput: .0028
|
|
123
|
+
},
|
|
124
|
+
"deepseek-reasoner": {
|
|
125
|
+
input: .14,
|
|
126
|
+
output: .28,
|
|
127
|
+
cachedInput: .0028
|
|
128
|
+
},
|
|
129
|
+
"deepseek-v4-flash": {
|
|
130
|
+
input: .14,
|
|
131
|
+
output: .28,
|
|
132
|
+
cachedInput: .0028
|
|
133
|
+
},
|
|
134
|
+
"deepseek-v4-pro": {
|
|
135
|
+
input: .435,
|
|
136
|
+
output: .87,
|
|
137
|
+
cachedInput: .003625
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* DeepSeek-backed implementation of `SDKAdapterContract`.
|
|
142
|
+
*
|
|
143
|
+
* **Role.** The package entry point for DeepSeek models. DeepSeek's API is
|
|
144
|
+
* OpenAI-compatible on the wire, so rather than reimplementing the
|
|
145
|
+
* battle-tested Chat Completions translation, this is a **thin wrapper**
|
|
146
|
+
* over {@link OpenAISDK} from `@warlock.js/ai-openai`: it constructs one
|
|
147
|
+
* internal `OpenAISDK` pinned to DeepSeek's `baseURL` and the `"deepseek"`
|
|
148
|
+
* provider label, and delegates `model()` / `embedder()` / `image()` /
|
|
149
|
+
* `count()` straight to it. Construct one `DeepSeekSDK` per account and
|
|
150
|
+
* reuse it everywhere.
|
|
151
|
+
*
|
|
152
|
+
* **What the wrapper adds over a bare `OpenAISDK`.** DeepSeek's model
|
|
153
|
+
* **names** are not OpenAI names, so OpenAI's own vision/reasoning prefix
|
|
154
|
+
* lists never match them. This wrapper injects DeepSeek's OWN capability
|
|
155
|
+
* inference (see `known-models.ts`) and built-in DeepSeek pricing defaults
|
|
156
|
+
* as explicit values on every `model()` call — so `deepseek-reasoner` is
|
|
157
|
+
* correctly flagged reasoning-capable and `deepseek-chat` is not, even
|
|
158
|
+
* though neither matches an OpenAI prefix. An explicit `vision` /
|
|
159
|
+
* `reasoning` / `pricing` you pass per model always wins over these
|
|
160
|
+
* injected defaults.
|
|
161
|
+
*
|
|
162
|
+
* **Responsibility.**
|
|
163
|
+
* - Owns: one long-lived internal `OpenAISDK` (auth, DeepSeek base URL)
|
|
164
|
+
* and DeepSeek's capability + pricing defaults.
|
|
165
|
+
* - Does NOT own: the wire protocol, streaming loop, message/tool
|
|
166
|
+
* translation, or error wrapping — all inherited unchanged from
|
|
167
|
+
* `OpenAISDK` / `OpenAIModel`.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* const deepseek = new DeepSeekSDK({ apiKey: process.env.DEEPSEEK_API_KEY! });
|
|
171
|
+
* const chat = deepseek.model({ name: "deepseek-chat" }); // reasoning=false
|
|
172
|
+
* const reasoner = deepseek.model({ name: "deepseek-reasoner" }); // reasoning=true
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* // Compose into an `ai.deepseek` namespace for ergonomic agent wiring
|
|
176
|
+
* const ai = { agent, tool, deepseek: new DeepSeekSDK({ apiKey }) };
|
|
177
|
+
* const myAgent = ai.agent({ model: ai.deepseek.model({ name: "deepseek-reasoner" }) });
|
|
178
|
+
*/
|
|
179
|
+
var DeepSeekSDK = class {
|
|
180
|
+
constructor(config) {
|
|
181
|
+
const { provider, pricing, baseURL, ...clientOptions } = config;
|
|
182
|
+
this.provider = provider ?? DEEPSEEK_PROVIDER;
|
|
183
|
+
this.pricing = {
|
|
184
|
+
...DEEPSEEK_DEFAULT_PRICING,
|
|
185
|
+
...pricing
|
|
186
|
+
};
|
|
187
|
+
this.openai = new _warlock_js_ai_openai.OpenAISDK({
|
|
188
|
+
...clientOptions,
|
|
189
|
+
baseURL: baseURL ?? DEEPSEEK_BASE_URL,
|
|
190
|
+
provider: this.provider
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Build a `ModelContract` for a DeepSeek model. Delegates to the wrapped
|
|
195
|
+
* `OpenAISDK.model()`, but first injects this provider's defaults:
|
|
196
|
+
* - `vision` / `reasoning` inferred from DeepSeek's model-name lists
|
|
197
|
+
* (`known-models.ts`) — so the right capabilities are set even though
|
|
198
|
+
* the names aren't OpenAI names.
|
|
199
|
+
* - `pricing` resolved from the built-in DeepSeek table merged with any
|
|
200
|
+
* caller-supplied SDK registry.
|
|
201
|
+
*
|
|
202
|
+
* An explicit `vision` / `reasoning` / `pricing` on `config` always wins
|
|
203
|
+
* over the injected default. Everything else (sampling, structured
|
|
204
|
+
* output, streaming, error wrapping) is inherited unchanged from
|
|
205
|
+
* `OpenAIModel`.
|
|
206
|
+
*/
|
|
207
|
+
model(config) {
|
|
208
|
+
const resolved = {
|
|
209
|
+
...config,
|
|
210
|
+
vision: config.vision ?? inferVisionCapability(config.name),
|
|
211
|
+
reasoning: config.reasoning ?? inferReasoningCapability(config.name),
|
|
212
|
+
pricing: config.pricing ?? this.pricing[config.name]
|
|
213
|
+
};
|
|
214
|
+
return this.openai.model(resolved);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Rough offline token-count estimate. Delegated to the wrapped
|
|
218
|
+
* `OpenAISDK.count()` (the core character-heuristic) — good for
|
|
219
|
+
* budgeting/quota guards, not billing.
|
|
220
|
+
*/
|
|
221
|
+
async count(text, model) {
|
|
222
|
+
return this.openai.count(text, model);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Build an `EmbedderContract`. Delegated verbatim to
|
|
226
|
+
* `OpenAISDK.embedder()`.
|
|
227
|
+
*
|
|
228
|
+
* NOTE: DeepSeek does not officially document an OpenAI-compatible
|
|
229
|
+
* embeddings endpoint (mid-2026); this delegate works against a
|
|
230
|
+
* compatible gateway you point `baseURL` at, but may fail against the
|
|
231
|
+
* stock DeepSeek endpoint. Prefer a dedicated embeddings provider for
|
|
232
|
+
* RAG.
|
|
233
|
+
*/
|
|
234
|
+
embedder(config) {
|
|
235
|
+
return this.openai.embedder(config);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Build an `ImageModelContract`. Delegated verbatim to
|
|
239
|
+
* `OpenAISDK.image()`.
|
|
240
|
+
*
|
|
241
|
+
* NOTE: DeepSeek does not document an image-generation endpoint
|
|
242
|
+
* (mid-2026); provided for adapter parity. A non-image model id is
|
|
243
|
+
* rejected at construction by the wrapped OpenAI image model.
|
|
244
|
+
*/
|
|
245
|
+
image(config) {
|
|
246
|
+
return this.openai.image(config);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
//#endregion
|
|
251
|
+
exports.DEEPSEEK_CHAT_MODELS = DEEPSEEK_CHAT_MODELS;
|
|
252
|
+
exports.DeepSeekSDK = DeepSeekSDK;
|
|
253
|
+
exports.inferReasoningCapability = inferReasoningCapability;
|
|
254
|
+
exports.inferVisionCapability = inferVisionCapability;
|
|
255
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["OpenAISDK"],"sources":["../../../../../../@warlock.js/ai-deepseek/src/known-models.ts","../../../../../../@warlock.js/ai-deepseek/src/sdk.ts"],"sourcesContent":["/**\n * Capability inference for DeepSeek chat model ids.\n *\n * DeepSeek's API is OpenAI-compatible on the wire (`@warlock.js/ai-deepseek`\n * wraps {@link OpenAISDK}), but its model **names** are not OpenAI names —\n * so OpenAI's own prefix lists (`gpt-4o`, `o3`, …) never match them. This\n * module supplies DeepSeek's OWN name-based inference, which the\n * {@link DeepSeekSDK} injects as explicit capability booleans into the\n * wrapped `openai.model(...)` call (explicit config wins over OpenAI's\n * inference inside `OpenAIModel`).\n *\n * Verified against the official DeepSeek API docs (api-docs.deepseek.com,\n * mid-2026): base URL `https://api.deepseek.com`, OpenAI-compatible Chat\n * Completions. Two reasoning-capable surfaces exist — the legacy\n * `deepseek-reasoner` (thinking mode) and the `*-pro` tier — while\n * `deepseek-chat` is the non-thinking surface. No DeepSeek chat model\n * documents image (vision) input, so vision inference is conservatively\n * `false` for every id.\n */\n\n/**\n * Default DeepSeek chat model ids, surfaced for discovery and docs.\n *\n * - `deepseek-chat` — the non-thinking surface (V3 lineage). Fast, cheap,\n * broad production coverage. Not reasoning-capable.\n * - `deepseek-reasoner` — the thinking surface (R1 lineage). Emits a\n * reasoning channel and accepts the reasoning-effort knob.\n *\n * Both legacy names are scheduled for retirement (2026/07/24 per DeepSeek's\n * deprecation notice) in favor of the `deepseek-v4-*` family\n * (`deepseek-v4-flash`, `deepseek-v4-pro`), which this inference also\n * understands. The list is informational only — `deepseek.model({ name })`\n * accepts any id the upstream serves.\n */\nexport const DEEPSEEK_CHAT_MODELS = [\n \"deepseek-chat\",\n \"deepseek-reasoner\",\n \"deepseek-v4-flash\",\n \"deepseek-v4-pro\",\n] as const;\n\n/**\n * Substrings identifying DeepSeek model ids that expose a reasoning /\n * thinking channel and accept the reasoning-effort knob.\n *\n * - `deepseek-reasoner` — the dedicated thinking surface (R1 lineage).\n * - `-pro` — the V4 quality tier (`deepseek-v4-pro`), which thinks by\n * default per DeepSeek's docs.\n *\n * `deepseek-chat` (the V3 non-thinking surface) and `deepseek-v4-flash`\n * stay `false`. A substring match tolerates date/preview suffixes the\n * provider may append. Override per-model via\n * `deepseek.model({ name, reasoning: true | false })`.\n */\nconst REASONING_CAPABLE_SUBSTRINGS = [\"deepseek-reasoner\", \"-pro\"];\n\n/**\n * Infer whether a DeepSeek model id is reasoning-capable based on the\n * known substrings. Unknown ids default to `false` so the adapter never\n * forwards an unsupported reasoning param to a non-thinking model.\n *\n * @example\n * inferReasoningCapability(\"deepseek-reasoner\"); // → true\n * inferReasoningCapability(\"deepseek-v4-pro\"); // → true\n * inferReasoningCapability(\"deepseek-chat\"); // → false\n * inferReasoningCapability(\"deepseek-v4-flash\"); // → false\n */\nexport function inferReasoningCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return REASONING_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));\n}\n\n/**\n * Substrings identifying DeepSeek model ids that accept image (vision)\n * input.\n *\n * Currently **empty**: as of mid-2026, no DeepSeek chat model documents\n * vision input on the OpenAI-compatible Chat Completions endpoint, so\n * inference returns `false` for every id and passing an image attachment\n * surfaces a clear, agent-side capability error instead of an opaque 400.\n * Append a fragment here (and a paired spec case) the day DeepSeek ships a\n * multimodal chat model. Devs can always opt in per-model via\n * `deepseek.model({ name, vision: true })`.\n */\nconst VISION_CAPABLE_SUBSTRINGS: readonly string[] = [];\n\n/**\n * Infer whether a DeepSeek model id supports vision based on the known\n * substrings. Today this is always `false` (see\n * {@link VISION_CAPABLE_SUBSTRINGS}); kept as a function so the\n * {@link DeepSeekSDK} call site and the override semantics stay identical\n * to the other adapters, ready for a future multimodal id.\n *\n * @example\n * inferVisionCapability(\"deepseek-chat\"); // → false\n * inferVisionCapability(\"deepseek-reasoner\"); // → false\n */\nexport function inferVisionCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return VISION_CAPABLE_SUBSTRINGS.some((fragment) => normalized.includes(fragment));\n}\n","import type {\n EmbedderContract,\n ImageModelContract,\n ModelContract,\n ModelPricing,\n SDKAdapterContract,\n} from \"@warlock.js/ai\";\nimport { OpenAISDK } from \"@warlock.js/ai-openai\";\nimport type {\n DeepSeekEmbedderConfig,\n DeepSeekImageConfig,\n DeepSeekModelConfig,\n DeepSeekSDKConfig,\n} from \"./config.type\";\nimport { inferReasoningCapability, inferVisionCapability } from \"./known-models\";\n\n/**\n * DeepSeek's OpenAI-compatible Chat Completions endpoint. Verified against\n * the official API docs (api-docs.deepseek.com, mid-2026).\n */\nconst DEEPSEEK_BASE_URL = \"https://api.deepseek.com\";\n\n/** Default upstream label for models produced by this SDK. */\nconst DEEPSEEK_PROVIDER = \"deepseek\";\n\n/**\n * Built-in DeepSeek pricing defaults, in USD per 1,000,000 tokens, keyed\n * by model name. Sourced from DeepSeek's official pricing table\n * (mid-2026); `cachedInput` is the cache-hit input rate. A caller-supplied\n * SDK `pricing` registry, or a per-model `pricing`, overrides any entry\n * here. Update when DeepSeek revises its published rates.\n */\nconst DEEPSEEK_DEFAULT_PRICING: Record<string, ModelPricing> = {\n \"deepseek-chat\": { input: 0.14, output: 0.28, cachedInput: 0.0028 },\n \"deepseek-reasoner\": { input: 0.14, output: 0.28, cachedInput: 0.0028 },\n \"deepseek-v4-flash\": { input: 0.14, output: 0.28, cachedInput: 0.0028 },\n \"deepseek-v4-pro\": { input: 0.435, output: 0.87, cachedInput: 0.003625 },\n};\n\n/**\n * DeepSeek-backed implementation of `SDKAdapterContract`.\n *\n * **Role.** The package entry point for DeepSeek models. DeepSeek's API is\n * OpenAI-compatible on the wire, so rather than reimplementing the\n * battle-tested Chat Completions translation, this is a **thin wrapper**\n * over {@link OpenAISDK} from `@warlock.js/ai-openai`: it constructs one\n * internal `OpenAISDK` pinned to DeepSeek's `baseURL` and the `\"deepseek\"`\n * provider label, and delegates `model()` / `embedder()` / `image()` /\n * `count()` straight to it. Construct one `DeepSeekSDK` per account and\n * reuse it everywhere.\n *\n * **What the wrapper adds over a bare `OpenAISDK`.** DeepSeek's model\n * **names** are not OpenAI names, so OpenAI's own vision/reasoning prefix\n * lists never match them. This wrapper injects DeepSeek's OWN capability\n * inference (see `known-models.ts`) and built-in DeepSeek pricing defaults\n * as explicit values on every `model()` call — so `deepseek-reasoner` is\n * correctly flagged reasoning-capable and `deepseek-chat` is not, even\n * though neither matches an OpenAI prefix. An explicit `vision` /\n * `reasoning` / `pricing` you pass per model always wins over these\n * injected defaults.\n *\n * **Responsibility.**\n * - Owns: one long-lived internal `OpenAISDK` (auth, DeepSeek base URL)\n * and DeepSeek's capability + pricing defaults.\n * - Does NOT own: the wire protocol, streaming loop, message/tool\n * translation, or error wrapping — all inherited unchanged from\n * `OpenAISDK` / `OpenAIModel`.\n *\n * @example\n * const deepseek = new DeepSeekSDK({ apiKey: process.env.DEEPSEEK_API_KEY! });\n * const chat = deepseek.model({ name: \"deepseek-chat\" }); // reasoning=false\n * const reasoner = deepseek.model({ name: \"deepseek-reasoner\" }); // reasoning=true\n *\n * @example\n * // Compose into an `ai.deepseek` namespace for ergonomic agent wiring\n * const ai = { agent, tool, deepseek: new DeepSeekSDK({ apiKey }) };\n * const myAgent = ai.agent({ model: ai.deepseek.model({ name: \"deepseek-reasoner\" }) });\n */\nexport class DeepSeekSDK implements SDKAdapterContract {\n /** The wrapped OpenAI-compatible client, pinned to DeepSeek. */\n private readonly openai: OpenAISDK;\n private readonly provider: string;\n private readonly pricing: Record<string, ModelPricing>;\n\n public constructor(config: DeepSeekSDKConfig) {\n const { provider, pricing, baseURL, ...clientOptions } = config;\n\n this.provider = provider ?? DEEPSEEK_PROVIDER;\n // Caller pricing overrides the built-in DeepSeek defaults entry-by-entry.\n this.pricing = { ...DEEPSEEK_DEFAULT_PRICING, ...pricing };\n\n // The internal OpenAISDK carries the DeepSeek base URL + provider label;\n // pricing stays on THIS wrapper so it can be merged with the built-in\n // defaults before each per-model resolution below.\n this.openai = new OpenAISDK({\n ...clientOptions,\n baseURL: baseURL ?? DEEPSEEK_BASE_URL,\n provider: this.provider,\n });\n }\n\n /**\n * Build a `ModelContract` for a DeepSeek model. Delegates to the wrapped\n * `OpenAISDK.model()`, but first injects this provider's defaults:\n * - `vision` / `reasoning` inferred from DeepSeek's model-name lists\n * (`known-models.ts`) — so the right capabilities are set even though\n * the names aren't OpenAI names.\n * - `pricing` resolved from the built-in DeepSeek table merged with any\n * caller-supplied SDK registry.\n *\n * An explicit `vision` / `reasoning` / `pricing` on `config` always wins\n * over the injected default. Everything else (sampling, structured\n * output, streaming, error wrapping) is inherited unchanged from\n * `OpenAIModel`.\n */\n public model(config: DeepSeekModelConfig): ModelContract {\n const resolved: DeepSeekModelConfig = {\n ...config,\n vision: config.vision ?? inferVisionCapability(config.name),\n reasoning: config.reasoning ?? inferReasoningCapability(config.name),\n pricing: config.pricing ?? this.pricing[config.name],\n };\n\n return this.openai.model(resolved);\n }\n\n /**\n * Rough offline token-count estimate. Delegated to the wrapped\n * `OpenAISDK.count()` (the core character-heuristic) — good for\n * budgeting/quota guards, not billing.\n */\n public async count(text: string, model?: string): Promise<number> {\n return this.openai.count(text, model);\n }\n\n /**\n * Build an `EmbedderContract`. Delegated verbatim to\n * `OpenAISDK.embedder()`.\n *\n * NOTE: DeepSeek does not officially document an OpenAI-compatible\n * embeddings endpoint (mid-2026); this delegate works against a\n * compatible gateway you point `baseURL` at, but may fail against the\n * stock DeepSeek endpoint. Prefer a dedicated embeddings provider for\n * RAG.\n */\n public embedder(config: DeepSeekEmbedderConfig): EmbedderContract {\n return this.openai.embedder(config);\n }\n\n /**\n * Build an `ImageModelContract`. Delegated verbatim to\n * `OpenAISDK.image()`.\n *\n * NOTE: DeepSeek does not document an image-generation endpoint\n * (mid-2026); provided for adapter parity. A non-image model id is\n * rejected at construction by the wrapped OpenAI image model.\n */\n public image(config: DeepSeekImageConfig): ImageModelContract {\n return this.openai.image(config);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAa,uBAAuB;CAClC;CACA;CACA;CACA;AACF;;;;;;;;;;;;;;AAeA,MAAM,+BAA+B,CAAC,qBAAqB,MAAM;;;;;;;;;;;;AAajE,SAAgB,yBAAyB,SAA0B;CACjE,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,6BAA6B,MAAM,aAAa,WAAW,SAAS,QAAQ,CAAC;AACtF;;;;;;;;;;;;;AAcA,MAAM,4BAA+C,CAAC;;;;;;;;;;;;AAatD,SAAgB,sBAAsB,SAA0B;CAC9D,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,0BAA0B,MAAM,aAAa,WAAW,SAAS,QAAQ,CAAC;AACnF;;;;;;;;AClFA,MAAM,oBAAoB;;AAG1B,MAAM,oBAAoB;;;;;;;;AAS1B,MAAM,2BAAyD;CAC7D,iBAAiB;EAAE,OAAO;EAAM,QAAQ;EAAM,aAAa;CAAO;CAClE,qBAAqB;EAAE,OAAO;EAAM,QAAQ;EAAM,aAAa;CAAO;CACtE,qBAAqB;EAAE,OAAO;EAAM,QAAQ;EAAM,aAAa;CAAO;CACtE,mBAAmB;EAAE,OAAO;EAAO,QAAQ;EAAM,aAAa;CAAS;AACzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,IAAa,cAAb,MAAuD;CAMrD,AAAO,YAAY,QAA2B;EAC5C,MAAM,EAAE,UAAU,SAAS,SAAS,GAAG,kBAAkB;EAEzD,KAAK,WAAW,YAAY;EAE5B,KAAK,UAAU;GAAE,GAAG;GAA0B,GAAG;EAAQ;EAKzD,KAAK,SAAS,IAAIA,gCAAU;GAC1B,GAAG;GACH,SAAS,WAAW;GACpB,UAAU,KAAK;EACjB,CAAC;CACH;;;;;;;;;;;;;;;CAgBA,AAAO,MAAM,QAA4C;EACvD,MAAM,WAAgC;GACpC,GAAG;GACH,QAAQ,OAAO,UAAU,sBAAsB,OAAO,IAAI;GAC1D,WAAW,OAAO,aAAa,yBAAyB,OAAO,IAAI;GACnE,SAAS,OAAO,WAAW,KAAK,QAAQ,OAAO;EACjD;EAEA,OAAO,KAAK,OAAO,MAAM,QAAQ;CACnC;;;;;;CAOA,MAAa,MAAM,MAAc,OAAiC;EAChE,OAAO,KAAK,OAAO,MAAM,MAAM,KAAK;CACtC;;;;;;;;;;;CAYA,AAAO,SAAS,QAAkD;EAChE,OAAO,KAAK,OAAO,SAAS,MAAM;CACpC;;;;;;;;;CAUA,AAAO,MAAM,QAAiD;EAC5D,OAAO,KAAK,OAAO,MAAM,MAAM;CACjC;AACF"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { OpenAISDKConfig } from "@warlock.js/ai-openai";
|
|
2
|
+
import { EmbedderConfig, ImageModelConfig, ModelConfig } from "@warlock.js/ai";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai-deepseek/src/config.type.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Per-model `response_format` override forwarded to the wrapped OpenAI
|
|
7
|
+
* model. Mirrors the OpenAI adapter's union (DeepSeek speaks the same
|
|
8
|
+
* OpenAI-compatible Chat Completions protocol):
|
|
9
|
+
*
|
|
10
|
+
* - `"json_schema"` — strict token-level shape enforcement.
|
|
11
|
+
* - `"json_object"` — guarantees valid JSON, NOT shape; the agent
|
|
12
|
+
* re-injects the schema as a soft prompt hint.
|
|
13
|
+
* - `"text"` — no `response_format` on the wire; relies on the prompt hint.
|
|
14
|
+
*/
|
|
15
|
+
type DeepSeekResponseFormat = "json_schema" | "json_object" | "text";
|
|
16
|
+
/**
|
|
17
|
+
* Configuration for the DeepSeek SDK adapter.
|
|
18
|
+
*
|
|
19
|
+
* DeepSeek's API is OpenAI-compatible on the wire, so this config is the
|
|
20
|
+
* {@link OpenAISDKConfig} shape with one ergonomic change: `baseURL` and
|
|
21
|
+
* `provider` are **optional** because the adapter defaults them to
|
|
22
|
+
* DeepSeek's endpoint (`https://api.deepseek.com`) and the `"deepseek"`
|
|
23
|
+
* label. Pass only your `apiKey` for the common path; every other upstream
|
|
24
|
+
* `openai` `ClientOptions` value (`timeout`, `maxRetries`,
|
|
25
|
+
* `defaultHeaders`, `fetch`, …) is forwarded verbatim to the wrapped
|
|
26
|
+
* `OpenAISDK`.
|
|
27
|
+
*
|
|
28
|
+
* `provider` flows through to `ModelContract.provider`, `AgentReport.model`,
|
|
29
|
+
* logs, and any provider-aware middleware. Defaults to `"deepseek"`.
|
|
30
|
+
*
|
|
31
|
+
* `pricing` is an optional SDK-level registry keyed by model name —
|
|
32
|
+
* resolution at `model()` time is per-model `pricing` > this SDK registry >
|
|
33
|
+
* the adapter's built-in DeepSeek defaults > `undefined`.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* new DeepSeekSDK({ apiKey: process.env.DEEPSEEK_API_KEY! });
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Override the default endpoint (e.g. a proxy) or the provider label:
|
|
40
|
+
* new DeepSeekSDK({
|
|
41
|
+
* apiKey,
|
|
42
|
+
* baseURL: "https://my-gateway.example.com/deepseek",
|
|
43
|
+
* provider: "deepseek-proxy",
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* new DeepSeekSDK({
|
|
48
|
+
* apiKey,
|
|
49
|
+
* pricing: { "deepseek-chat": { input: 0.14, output: 0.28, cachedInput: 0.0028 } },
|
|
50
|
+
* });
|
|
51
|
+
*/
|
|
52
|
+
type DeepSeekSDKConfig = Omit<OpenAISDKConfig, "baseURL" | "provider"> & {
|
|
53
|
+
/**
|
|
54
|
+
* Override the DeepSeek base URL. Defaults to
|
|
55
|
+
* `https://api.deepseek.com` (the OpenAI-compatible endpoint). Set this
|
|
56
|
+
* only to route through a proxy or a self-hosted gateway.
|
|
57
|
+
*/
|
|
58
|
+
baseURL?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Override the upstream label. Defaults to `"deepseek"`. Flows through
|
|
61
|
+
* to `ModelContract.provider`, `AgentReport.model`, and logs.
|
|
62
|
+
*/
|
|
63
|
+
provider?: string;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Per-model configuration for `DeepSeekSDK.model()`. `name` is a DeepSeek
|
|
67
|
+
* chat model id (e.g. `"deepseek-chat"`, `"deepseek-reasoner"`).
|
|
68
|
+
*
|
|
69
|
+
* Mirrors the OpenAI adapter's per-model overrides field-for-field —
|
|
70
|
+
* DeepSeek runs on the same OpenAI-compatible wire. The difference from
|
|
71
|
+
* using `OpenAISDK` directly is the **default** capability inference:
|
|
72
|
+
* `DeepSeekSDK` derives `vision` and `reasoning` from DeepSeek's own
|
|
73
|
+
* model-name lists (see `known-models.ts`) rather than OpenAI's prefix
|
|
74
|
+
* lists, then injects them as explicit booleans. An explicit value you
|
|
75
|
+
* pass here always wins over that inference.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* deepseek.model({ name: "deepseek-chat" }); // reasoning auto-false
|
|
79
|
+
* deepseek.model({ name: "deepseek-reasoner" }); // reasoning auto-true
|
|
80
|
+
* deepseek.model({ name: "deepseek-chat", reasoning: true }); // explicit override
|
|
81
|
+
*/
|
|
82
|
+
type DeepSeekModelConfig = ModelConfig & {
|
|
83
|
+
/**
|
|
84
|
+
* Override the auto-inferred vision capability. When omitted, the
|
|
85
|
+
* adapter infers from the DeepSeek model name (always `false` today —
|
|
86
|
+
* no DeepSeek chat model documents image input). Explicit `true`/`false`
|
|
87
|
+
* always wins.
|
|
88
|
+
*/
|
|
89
|
+
vision?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Override the auto-inferred reasoning capability. When omitted, the
|
|
92
|
+
* adapter infers from the DeepSeek model name — `true` for
|
|
93
|
+
* `deepseek-reasoner` and the `*-pro` tier, `false` for `deepseek-chat`
|
|
94
|
+
* / `*-flash`. Drives whether the reasoning-effort knob is forwarded.
|
|
95
|
+
* Explicit `true`/`false` always wins.
|
|
96
|
+
*/
|
|
97
|
+
reasoning?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Override the inferred `structuredOutput` capability. Forwarded to the
|
|
100
|
+
* wrapped OpenAI model, where it defaults to `true` unless
|
|
101
|
+
* `responseFormat` forces a loose mode.
|
|
102
|
+
*/
|
|
103
|
+
structuredOutput?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Override the wire-level `response_format` the adapter emits for a
|
|
106
|
+
* response schema. Use a loose mode (`"json_object"` / `"text"`) for a
|
|
107
|
+
* route that rejects strict `json_schema`. Forwarded to the wrapped
|
|
108
|
+
* OpenAI model unchanged.
|
|
109
|
+
*/
|
|
110
|
+
responseFormat?: DeepSeekResponseFormat;
|
|
111
|
+
/**
|
|
112
|
+
* Opt into PDF / document **input**. Forwarded to the wrapped OpenAI
|
|
113
|
+
* model; off by default.
|
|
114
|
+
*/
|
|
115
|
+
pdf?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Opt into audio **input**. Forwarded to the wrapped OpenAI model; off
|
|
118
|
+
* by default.
|
|
119
|
+
*/
|
|
120
|
+
audio?: boolean;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Per-embedder configuration for `DeepSeekSDK.embedder()`. Mirrors the
|
|
124
|
+
* neutral {@link EmbedderConfig}.
|
|
125
|
+
*
|
|
126
|
+
* NOTE: DeepSeek does not officially document an OpenAI-compatible
|
|
127
|
+
* embeddings endpoint (mid-2026). `embedder()` is delegated to the wrapped
|
|
128
|
+
* `OpenAISDK` for completeness, so it works against any compatible gateway
|
|
129
|
+
* you point `baseURL` at — but calling `.embed()` against the stock
|
|
130
|
+
* `https://api.deepseek.com` endpoint may fail upstream. Prefer a
|
|
131
|
+
* dedicated embeddings provider for RAG.
|
|
132
|
+
*/
|
|
133
|
+
type DeepSeekEmbedderConfig = EmbedderConfig;
|
|
134
|
+
/**
|
|
135
|
+
* Per-model configuration for `DeepSeekSDK.image()`. Mirrors the neutral
|
|
136
|
+
* {@link ImageModelConfig}.
|
|
137
|
+
*
|
|
138
|
+
* NOTE: DeepSeek does not document an image-generation endpoint
|
|
139
|
+
* (mid-2026). `image()` is delegated to the wrapped `OpenAISDK` for
|
|
140
|
+
* parity; a non-image model id is rejected by the wrapped OpenAI image
|
|
141
|
+
* model at construction exactly as it would be there.
|
|
142
|
+
*/
|
|
143
|
+
type DeepSeekImageConfig = ImageModelConfig;
|
|
144
|
+
//#endregion
|
|
145
|
+
export { DeepSeekEmbedderConfig, DeepSeekImageConfig, DeepSeekModelConfig, DeepSeekSDKConfig };
|
|
146
|
+
//# sourceMappingURL=config.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.type.d.mts","names":[],"sources":["../../../../../../@warlock.js/ai-deepseek/src/config.type.ts"],"mappings":";;;;;;AAaA;;;;AAAkC;AAsClC;;;KAtCY,sBAAA;;;;;;AAiDF;AAoBV;;;;;;;;;;;;;AAsCO;AAcP;;;;AAAmD;AAWnD;;;;AAAkD;;;;;;;KA9FtC,iBAAA,GAAoB,IAAI,CAAC,eAAA;;;;;;EAMnC,OAAA;;;;;EAKA,QAAA;AAAA;;;;;;;;;;;;;;;;;;KAoBU,mBAAA,GAAsB,WAAA;;;;;;;EAOhC,MAAA;;;;;;;;EAQA,SAAA;;;;;;EAMA,gBAAA;;;;;;;EAOA,cAAA,GAAiB,sBAAsB;;;;;EAKvC,GAAA;;;;;EAKA,KAAA;AAAA;;;;;;;;;;;;KAcU,sBAAA,GAAyB,cAAc;;;;;;;;;;KAWvC,mBAAA,GAAsB,gBAAgB"}
|
package/esm/index.d.mts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DeepSeekEmbedderConfig, DeepSeekImageConfig, DeepSeekModelConfig, DeepSeekSDKConfig } from "./config.type.mjs";
|
|
2
|
+
import { DeepSeekSDK } from "./sdk.mjs";
|
|
3
|
+
import { DEEPSEEK_CHAT_MODELS, inferReasoningCapability, inferVisionCapability } from "./known-models.mjs";
|
|
4
|
+
export { DEEPSEEK_CHAT_MODELS, type DeepSeekEmbedderConfig, type DeepSeekImageConfig, type DeepSeekModelConfig, DeepSeekSDK, type DeepSeekSDKConfig, inferReasoningCapability, inferVisionCapability };
|
package/esm/index.mjs
ADDED