@warlock.js/ai-deepseek 4.8.2 → 4.9.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/cjs/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  let _warlock_js_ai_openai = require("@warlock.js/ai-openai");
3
3
 
4
- //#region ../@warlock.js/ai-deepseek/src/known-models.ts
4
+ //#region ../ai-deepseek/src/known-models.ts
5
5
  /**
6
6
  * Capability inference for DeepSeek chat model ids.
7
7
  *
@@ -100,7 +100,7 @@ function inferVisionCapability(modelId) {
100
100
  }
101
101
 
102
102
  //#endregion
103
- //#region ../@warlock.js/ai-deepseek/src/sdk.ts
103
+ //#region ../ai-deepseek/src/sdk.ts
104
104
  /**
105
105
  * DeepSeek's OpenAI-compatible Chat Completions endpoint. Verified against
106
106
  * the official API docs (api-docs.deepseek.com, mid-2026).
package/cjs/index.cjs.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"index.cjs","names":["OpenAISDK"],"sources":["../../../../../../ai-deepseek/src/known-models.ts","../../../../../../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"}
@@ -1,7 +1,7 @@
1
1
  import { OpenAISDKConfig } from "@warlock.js/ai-openai";
2
2
  import { EmbedderConfig, ImageModelConfig, ModelConfig } from "@warlock.js/ai";
3
3
 
4
- //#region ../@warlock.js/ai-deepseek/src/config.type.d.ts
4
+ //#region ../ai-deepseek/src/config.type.d.ts
5
5
  /**
6
6
  * Per-model `response_format` override forwarded to the wrapped OpenAI
7
7
  * model. Mirrors the OpenAI adapter's union (DeepSeek speaks the same
@@ -1 +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"}
1
+ {"version":3,"file":"config.type.d.mts","names":[],"sources":["../../../../../../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"}
@@ -1,4 +1,4 @@
1
- //#region ../@warlock.js/ai-deepseek/src/known-models.d.ts
1
+ //#region ../ai-deepseek/src/known-models.d.ts
2
2
  /**
3
3
  * Capability inference for DeepSeek chat model ids.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"known-models.d.mts","names":[],"sources":["../../../../../../@warlock.js/ai-deepseek/src/known-models.ts"],"mappings":";;AAkCA;;;;AAKU;AA4BV;;;;AAAwD;AA+BxD;;;;AAAqD;;;;;;;;;;;;;;;;;;cAhExC,oBAAA;;;;;;;;;;;;iBAiCG,wBAAA,CAAyB,OAAe;;;;;;;;;;;;iBA+BxC,qBAAA,CAAsB,OAAe"}
1
+ {"version":3,"file":"known-models.d.mts","names":[],"sources":["../../../../../../ai-deepseek/src/known-models.ts"],"mappings":";;AAkCA;;;;AAKU;AA4BV;;;;AAAwD;AA+BxD;;;;AAAqD;;;;;;;;;;;;;;;;;;cAhExC,oBAAA;;;;;;;;;;;;iBAiCG,wBAAA,CAAyB,OAAe;;;;;;;;;;;;iBA+BxC,qBAAA,CAAsB,OAAe"}
@@ -1,4 +1,4 @@
1
- //#region ../@warlock.js/ai-deepseek/src/known-models.ts
1
+ //#region ../ai-deepseek/src/known-models.ts
2
2
  /**
3
3
  * Capability inference for DeepSeek chat model ids.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"known-models.mjs","names":[],"sources":["../../../../../../@warlock.js/ai-deepseek/src/known-models.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"],"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"}
1
+ {"version":3,"file":"known-models.mjs","names":[],"sources":["../../../../../../ai-deepseek/src/known-models.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"],"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"}
package/esm/sdk.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { DeepSeekEmbedderConfig, DeepSeekImageConfig, DeepSeekModelConfig, DeepSeekSDKConfig } from "./config.type.mjs";
2
2
  import { EmbedderContract, ImageModelContract, ModelContract, SDKAdapterContract } from "@warlock.js/ai";
3
3
 
4
- //#region ../@warlock.js/ai-deepseek/src/sdk.d.ts
4
+ //#region ../ai-deepseek/src/sdk.d.ts
5
5
  /**
6
6
  * DeepSeek-backed implementation of `SDKAdapterContract`.
7
7
  *
package/esm/sdk.d.mts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.mts","names":[],"sources":["../../../../../../@warlock.js/ai-deepseek/src/sdk.ts"],"mappings":";;;;;;AA8EA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,WAAA,YAAuB,kBAAA;EA+E2B;EAAA,iBA7E5C,MAAA;EAAA,iBACA,QAAA;EAAA,iBACA,OAAA;cAEE,MAAA,EAAQ,iBAAA;;;;;;;;;;;;;;;EA+BpB,KAAA,CAAM,MAAA,EAAQ,mBAAA,GAAsB,aAAA;;;;;;EAgB9B,KAAA,CAAM,IAAA,UAAc,KAAA,YAAiB,OAAA;;;;;;;;;;;EAc3C,QAAA,CAAS,MAAA,EAAQ,sBAAA,GAAyB,gBAAA;;;;;;;;;EAY1C,KAAA,CAAM,MAAA,EAAQ,mBAAA,GAAsB,kBAAA;AAAA"}
1
+ {"version":3,"file":"sdk.d.mts","names":[],"sources":["../../../../../../ai-deepseek/src/sdk.ts"],"mappings":";;;;;;AA8EA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,WAAA,YAAuB,kBAAA;EA+E2B;EAAA,iBA7E5C,MAAA;EAAA,iBACA,QAAA;EAAA,iBACA,OAAA;cAEE,MAAA,EAAQ,iBAAA;;;;;;;;;;;;;;;EA+BpB,KAAA,CAAM,MAAA,EAAQ,mBAAA,GAAsB,aAAA;;;;;;EAgB9B,KAAA,CAAM,IAAA,UAAc,KAAA,YAAiB,OAAA;;;;;;;;;;;EAc3C,QAAA,CAAS,MAAA,EAAQ,sBAAA,GAAyB,gBAAA;;;;;;;;;EAY1C,KAAA,CAAM,MAAA,EAAQ,mBAAA,GAAsB,kBAAA;AAAA"}
package/esm/sdk.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { inferReasoningCapability, inferVisionCapability } from "./known-models.mjs";
2
2
  import { OpenAISDK } from "@warlock.js/ai-openai";
3
3
 
4
- //#region ../@warlock.js/ai-deepseek/src/sdk.ts
4
+ //#region ../ai-deepseek/src/sdk.ts
5
5
  /**
6
6
  * DeepSeek's OpenAI-compatible Chat Completions endpoint. Verified against
7
7
  * the official API docs (api-docs.deepseek.com, mid-2026).
package/esm/sdk.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.mjs","names":[],"sources":["../../../../../../@warlock.js/ai-deepseek/src/sdk.ts"],"sourcesContent":["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":";;;;;;;;AAoBA,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,IAAI,UAAU;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"}
1
+ {"version":3,"file":"sdk.mjs","names":[],"sources":["../../../../../../ai-deepseek/src/sdk.ts"],"sourcesContent":["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":";;;;;;;;AAoBA,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,IAAI,UAAU;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"}
package/package.json CHANGED
@@ -13,13 +13,13 @@
13
13
  "url": "https://github.com/warlockjs/ai-deepseek"
14
14
  },
15
15
  "dependencies": {
16
- "@warlock.js/ai-openai": "4.8.2",
17
- "@warlock.js/logger": "4.8.2"
16
+ "@warlock.js/ai-openai": "4.9.0",
17
+ "@warlock.js/logger": "4.9.0"
18
18
  },
19
19
  "peerDependencies": {
20
- "@warlock.js/ai": "4.8.2"
20
+ "@warlock.js/ai": "4.9.0"
21
21
  },
22
- "version": "4.8.2",
22
+ "version": "4.9.0",
23
23
  "main": "./cjs/index.cjs",
24
24
  "module": "./esm/index.mjs",
25
25
  "types": "./esm/index.d.mts",