@deepseek-ai/dsh-llm-deepseek-api-key 0.2.1-rc.2 → 0.2.1-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +16 -16
- package/README.md +27 -8
- package/README.zh.md +27 -8
- package/lib/index.js +103 -13
- package/lib/types/config.d.ts +15 -7
- package/lib/types/index.d.ts +1 -1
- package/package.json +9 -9
package/README.i18n.yaml
CHANGED
|
@@ -3,26 +3,26 @@
|
|
|
3
3
|
# After editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/llm/llm-deepseek-api-key/README.md
|
|
5
5
|
/:
|
|
6
|
-
en:
|
|
7
|
-
zh:
|
|
6
|
+
en: d0825db7a1a9d8ee
|
|
7
|
+
zh: d0825db7a1a9d8ee
|
|
8
8
|
/deepseek-ai-dsh-llm-deepseek-api-key:
|
|
9
9
|
en: b6871195e386cc64
|
|
10
10
|
zh: 742b05a3ca80883c
|
|
11
11
|
/deepseek-ai-dsh-llm-deepseek-api-key/summary:
|
|
12
|
-
en:
|
|
13
|
-
zh:
|
|
12
|
+
en: f937052cf8ff4812
|
|
13
|
+
zh: 899d61f5021136d6
|
|
14
14
|
/deepseek-ai-dsh-llm-deepseek-api-key/table-of-contents:
|
|
15
15
|
en: 23386452a66b2fbd
|
|
16
16
|
zh: 4cf93c4bf17b3da2
|
|
17
17
|
/deepseek-ai-dsh-llm-deepseek-api-key/use-this-package:
|
|
18
|
-
en:
|
|
19
|
-
zh:
|
|
18
|
+
en: 2aad8a660b90561d
|
|
19
|
+
zh: 3f425b3d1ea023e1
|
|
20
20
|
/deepseek-ai-dsh-llm-deepseek-api-key/understand-the-implementation:
|
|
21
|
-
en:
|
|
22
|
-
zh:
|
|
21
|
+
en: d614c1ea3a9eb382
|
|
22
|
+
zh: 5ca070349bb22d56
|
|
23
23
|
/deepseek-ai-dsh-llm-deepseek-api-key/further-exploration:
|
|
24
|
-
en:
|
|
25
|
-
zh:
|
|
24
|
+
en: 347659458510940c
|
|
25
|
+
zh: ccfb03e18b356a39
|
|
26
26
|
/deepseek-ai-dsh-llm-deepseek-api-key/model-experience:
|
|
27
27
|
en: 215e7ba838619b7b
|
|
28
28
|
zh: a311da3843709f90
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
en: e5624a2c7bb26e90
|
|
34
34
|
zh: 44da0286a548f24a
|
|
35
35
|
/deepseek-ai-dsh-llm-deepseek-api-key/model-experience/authenticated-model-requests/token-effect:
|
|
36
|
-
en:
|
|
37
|
-
zh:
|
|
36
|
+
en: 9dd6430752202069
|
|
37
|
+
zh: 53068bf7f828156f
|
|
38
38
|
/deepseek-ai-dsh-llm-deepseek-api-key/model-experience/authenticated-model-requests/kv-cache-effect:
|
|
39
|
-
en:
|
|
40
|
-
zh:
|
|
39
|
+
en: 8226f9d956013ad9
|
|
40
|
+
zh: bace9524b7acc1fa
|
|
41
41
|
/deepseek-ai-dsh-llm-deepseek-api-key/known-limitations-and-deferred-work:
|
|
42
|
-
en:
|
|
43
|
-
zh:
|
|
42
|
+
en: e0a41598c126c187
|
|
43
|
+
zh: 857ab65c27f41612
|
|
44
44
|
/deepseek-ai-dsh-llm-deepseek-api-key/known-limitations-and-deferred-work/dev-note:
|
|
45
45
|
en: 0525041e573e96b6
|
|
46
46
|
zh: b05ed8d852498e6b
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "DeepSeek
|
|
2
|
+
description: "DeepSeek API-key authentication, model discovery, and the official model listing."
|
|
3
3
|
kind: "package-reference"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
Register authentication and model
|
|
12
|
+
Register authentication, model discovery, and the official model listing for `deepseek-official`. This plugin shares the [Messages transport](../llm-deepseek/README.md) and owns credential resolution, catalog availability, and model admission.
|
|
13
13
|
|
|
14
14
|
Authentication resolution returns the validated API key in `x-api-key` for both Messages and Files requests.
|
|
15
15
|
|
|
@@ -37,17 +37,30 @@ Authentication resolution returns the validated API key in `x-api-key` for both
|
|
|
37
37
|
|
|
38
38
|
The endpoint and credential reference come from one configuration resolution. In-flight requests retain that snapshot; subsequent updates affect subsequent calls. Account login state cannot change this route’s credential.
|
|
39
39
|
|
|
40
|
-
`models` is an independently configurable catalog for this provider; defaults and protocol capabilities come from the shared transport.
|
|
40
|
+
`models` is an independently configurable catalog for this provider; defaults and protocol capabilities come from the shared transport. While `models` equals the built-in catalog and the Messages origin is the official API, `https://api.deepseek.com`, the route serves the official `GET https://api.deepseek.com/models` listing instead. Listing requests carry the API key in `x-api-key` and the harness `User-Agent`, and reject redirects; without an API key the route requests nothing. Any other endpoint, including one named by `baseURL` or `$DEEPSEEK_BASE_URL`, serves `models` and requests no listing. Discovery does not probe inference endpoints.
|
|
41
|
+
|
|
42
|
+
The first access waits for the listing up to `modelsTimeoutMs`. Later accesses use the loaded listing and refresh it in the background once it is older than `modelsMaxAgeMs`; an idle route sends no requests. A failed or empty listing keeps the previous one; before any listing loads, the route serves the built-in catalog of the current version (`deepseek-flash` and `deepseek-v4-pro`). A listing HTTP 401 fails only that load. Each loaded listing, the first failure of a failing streak with the catalog it falls back to, and each listing entry hidden because its declarations are unreadable or unusable are written to stderr with the `[llm-deepseek-api-key]` tag; stdout remains available for protocol messages, and secrets are never logged.
|
|
43
|
+
|
|
44
|
+
Listed models are offered, merged with this build's entries, and refused before network I/O with `CLIENT_UPGRADE_REQUIRED` or `MODEL_UNSUPPORTED` by the [account route's rules](../llm-deepseek-account/README.md#use-this-package); model ids the listing does not name pass through unchanged.
|
|
45
|
+
|
|
46
|
+
A `models` list that differs from the built-in catalog replaces the catalog and stops listing requests; the Models page stores an edited catalog there. Removing that list, as **Restore defaults** on the Models page does, returns the route to the listing, and the next access loads the listing again even when the cached one is still fresh. A list identical to the built-in catalog counts as uncustomized.
|
|
47
|
+
|
|
48
|
+
| Field | Default | Meaning |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `modelsTimeoutMs` | `5,000` | Deadline of one listing request and of a first-access wait |
|
|
51
|
+
| `modelsMaxAgeMs` | `600,000` | Listing age after which the next access refreshes it; a failed load retries after the same age |
|
|
52
|
+
|
|
53
|
+
The settings namespace is the Cordis entry id, or the plugin name without an entry. Product profiles retain the official entry id `llm-deepseek` and use `llm-deepseek-account` for the account route.
|
|
41
54
|
|
|
42
55
|
<a id="understand-the-implementation"></a>
|
|
43
56
|
## Understand the implementation
|
|
44
57
|
|
|
45
|
-
Registrations and listeners dispose with the plugin. Shared Host wiring supplies attachments, request extensions, anonymous identity, and atomic retry-policy updates; this plugin registers only its own route.
|
|
58
|
+
Registrations and listeners dispose with the plugin, and disposal aborts an in-flight listing request. Shared Host wiring supplies attachments, request extensions, anonymous identity, and atomic retry-policy updates; this plugin registers only its own route and uses the transport's `connect` and `admit` hooks for the listed catalog and the gate. The listing request, its cache, and catalog resolution come from the shared transport; the cache lives in memory and is keyed by endpoint and a SHA-256 of the key, so another key loads its own listing. A `loader/volatile-update` listener discards the cached listing whenever the route starts or stops following it.
|
|
46
59
|
|
|
47
60
|
<a id="further-exploration"></a>
|
|
48
61
|
## Further Exploration
|
|
49
62
|
|
|
50
|
-
[LLM streaming](../../../docs/subsystems/llm-streaming.md) · [Messages](../llm-deepseek/README.md)
|
|
63
|
+
[LLM streaming](../../../docs/subsystems/llm-streaming.md) · [Messages](../llm-deepseek/README.md) · [Official listing decision](../../../.agents/notes/implemented/architecture/2026-10-22-deepseek-official-model-listing.md)
|
|
51
64
|
|
|
52
65
|
<a id="model-experience"></a>
|
|
53
66
|
## Model Experience
|
|
@@ -60,17 +73,23 @@ Requests on `deepseek-official` add no model-visible text from this plugin; the
|
|
|
60
73
|
|
|
61
74
|
#### Token effect
|
|
62
75
|
|
|
63
|
-
Authentication and
|
|
76
|
+
Authentication, discovery, and the listing add no input tokens. The followed listing sets each model's context window and default output cap, which each request's logged context and header record.
|
|
64
77
|
|
|
65
78
|
#### KV Cache effect
|
|
66
79
|
|
|
67
|
-
Credentials and catalog availability do not enter model input; the protocol transport owns request-prefix serialization.
|
|
80
|
+
Credentials and catalog availability do not enter model input; the protocol transport owns request-prefix serialization. A listing change to a model's system prompt or tool update mode changes how later system prompt or tool updates are serialized.
|
|
68
81
|
|
|
69
82
|
## Known Limitations and Deferred Work
|
|
70
83
|
|
|
71
84
|
<a id="known-limitations-and-deferred-work"></a>
|
|
72
85
|
|
|
73
|
-
-
|
|
86
|
+
- A configured catalog is configuration metadata, not remote validation that a model is accepted; actual calls can still fail.
|
|
87
|
+
- The Models page shows the built-in catalog while the route follows the listing, so a model only the listing offers appears only in model selectors. Editing that catalog on the page stores the rows the page shows, which drops such a model until **Restore defaults**.
|
|
88
|
+
- A customized catalog does not receive models the listing adds later.
|
|
89
|
+
- Customization is judged against the running version's built-in catalog, so a saved `models` list equal to an earlier version's built-in catalog counts as customized once the built-in catalog changes and stops following the listing until **Restore defaults**.
|
|
90
|
+
- The listing cache lives in memory; a start without network serves the built-in catalog until a listing loads.
|
|
91
|
+
- A listing change during a running process reaches the Web model picker at its next catalog refresh; the plugin does not announce it.
|
|
92
|
+
- When the current version can serve no listed model, the route offers no models.
|
|
74
93
|
|
|
75
94
|
<a id="dev-note"></a>
|
|
76
95
|
### Dev Note
|
package/README.zh.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "DeepSeek API
|
|
2
|
+
description: "DeepSeek API-key authentication, model discovery, and the official model listing."
|
|
3
3
|
kind: "package-reference"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
为 `deepseek-official`
|
|
12
|
+
为 `deepseek-official` 注册鉴权、模型发现和官方模型列表。通过 [llm-deepseek](../llm-deepseek/README.zh.md) 共用 Messages 请求实现;本包拥有凭据解析、目录可用性判断和模型准入。
|
|
13
13
|
|
|
14
14
|
鉴权解析将验证后的 API key 放入 `x-api-key`,供 Messages 和 Files 请求共同使用。
|
|
15
15
|
|
|
@@ -37,17 +37,30 @@ kind: "package-reference"
|
|
|
37
37
|
|
|
38
38
|
端点和凭据引用来自同一次配置解析;进行中的请求保留该快照,后续配置更新仅影响后续请求。账号登录态不影响该路由使用的凭据。
|
|
39
39
|
|
|
40
|
-
`models` 是该 provider
|
|
40
|
+
`models` 是该 provider 独立的可配置目录;默认值和协议能力来自共享传输包。当 `models` 等于内置目录、且 Messages 的 origin 是官方 API `https://api.deepseek.com` 时,路由改为提供官方 `GET https://api.deepseek.com/models` 列表。列表请求用 `x-api-key` 携带 API key,带上 harness 的 `User-Agent`,并拒绝重定向;没有 API key 时不发任何请求。其他端点,包括由 `baseURL` 或 `$DEEPSEEK_BASE_URL` 指定的端点,提供 `models`,不请求列表。目录判断不探测推理端点。
|
|
41
|
+
|
|
42
|
+
第一次访问会等待列表,最长 `modelsTimeoutMs`。之后的访问直接使用已加载的列表,列表超过 `modelsMaxAgeMs` 后在后台刷新;路由空闲时不发请求。获取失败或得到空列表时保留上一份;还没有加载到任何列表时,路由提供当前版本内置的目录(`deepseek-flash` 与 `deepseek-v4-pro`)。列表请求返回 HTTP 401 只让这一次加载失败。每次加载成功、连续失败中的第一次失败及其退回的目录、以及每个因声明无法读取或不可用而被隐藏的列表条目,都会以 `[llm-deepseek-api-key]` 标签写到 stderr;stdout 保留给协议消息,且不记录任何密钥。
|
|
43
|
+
|
|
44
|
+
列出的模型按[账号路由的规则](../llm-deepseek-account/README.zh.md#use-this-package)提供、与本版本的内置条目合并,并在网络请求之前以 `CLIENT_UPGRADE_REQUIRED` 或 `MODEL_UNSUPPORTED` 拒绝;列表没有列出的模型 id 照常透传。
|
|
45
|
+
|
|
46
|
+
与内置目录不同的 `models` 列表会替换整个目录,并停止请求列表;模型页把编辑后的目录存在这里。删除这个列表(即模型页上的**恢复默认模型**)后,路由重新使用列表,即使缓存的列表尚未过期,下一次访问也会重新加载。与内置目录完全相同的列表视为未自定义。
|
|
47
|
+
|
|
48
|
+
| 字段 | 默认值 | 含义 |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| `modelsTimeoutMs` | `5,000` | 单次列表请求以及首次访问等待的上限 |
|
|
51
|
+
| `modelsMaxAgeMs` | `600,000` | 列表超过这个时长后,下一次访问时刷新;获取失败后同样在这个时长后重试 |
|
|
52
|
+
|
|
53
|
+
设置命名空间采用 Cordis entry id,没有 entry 时采用插件名。产品保留 official 的 `llm-deepseek` entry id,账号使用 `llm-deepseek-account`。
|
|
41
54
|
|
|
42
55
|
<a id="understand-the-implementation"></a>
|
|
43
56
|
## 理解实现
|
|
44
57
|
|
|
45
|
-
|
|
58
|
+
注册和监听随插件生命周期释放,释放时会中止进行中的列表请求。共享 Host 绑定提供附件访问、请求扩展、匿名标识和重试策略的原子更新;本包只注册自己的路由,并通过传输层的 `connect` 与 `admit` 钩子接入列表目录和门控。列表请求、缓存和目录解析来自共享传输包;缓存只在内存中,以端点和 API key 的 SHA-256 为键,因此换一个 key 会加载它自己的列表。一个 `loader/volatile-update` 监听器在路由开始或停止使用列表时丢弃缓存的列表。
|
|
46
59
|
|
|
47
60
|
<a id="further-exploration"></a>
|
|
48
61
|
## 进一步探索
|
|
49
62
|
|
|
50
|
-
[LLM streaming](../../../docs/subsystems/llm-streaming.zh.md) · [Messages](../llm-deepseek/README.zh.md)
|
|
63
|
+
[LLM streaming](../../../docs/subsystems/llm-streaming.zh.md) · [Messages](../llm-deepseek/README.zh.md) · [官方列表决策](../../../.agents/notes/implemented/architecture/2026-10-22-deepseek-official-model-listing.zh.md)
|
|
51
64
|
|
|
52
65
|
<a id="model-experience"></a>
|
|
53
66
|
## 模型体验
|
|
@@ -60,17 +73,23 @@ kind: "package-reference"
|
|
|
60
73
|
|
|
61
74
|
#### Token effect
|
|
62
75
|
|
|
63
|
-
|
|
76
|
+
鉴权、目录过滤和列表都不增加输入 token。所使用的列表决定每个模型的上下文窗口和默认输出上限,每次请求记录的上下文和请求头会写明这些值。
|
|
64
77
|
|
|
65
78
|
#### KV Cache effect
|
|
66
79
|
|
|
67
|
-
|
|
80
|
+
凭据与目录可用性不进入模型输入;协议传输拥有请求前缀的序列化。列表改变某个模型的 system prompt 模式或工具更新模式时,之后的 system prompt 更新或工具更新的序列化方式随之改变。
|
|
68
81
|
|
|
69
82
|
## 已知限制与后续工作
|
|
70
83
|
|
|
71
84
|
<a id="known-limitations-and-deferred-work"></a>
|
|
72
85
|
|
|
73
|
-
-
|
|
86
|
+
- 配置的目录是配置元数据,不验证远端是否接受模型;实际调用仍可能失败。
|
|
87
|
+
- 路由使用列表时,模型页显示的仍是内置目录,因此只有列表提供的模型只出现在模型选择器中。在模型页编辑目录会保存页面上显示的行,这类模型会消失,直到点**恢复默认模型**。
|
|
88
|
+
- 自定义的目录收不到列表之后新增的模型。
|
|
89
|
+
- 是否自定义按当前版本的内置目录判断:保存的 `models` 列表若等于旧版本的内置目录,内置目录变化后就算作自定义,不再跟随列表,直到点**恢复默认模型**。
|
|
90
|
+
- 列表缓存只在内存中;没有网络的启动会一直提供内置目录,直到加载到列表。
|
|
91
|
+
- 进程运行期间的列表变化在 Web 模型选择器下一次刷新目录时生效;插件不主动通知。
|
|
92
|
+
- 当前版本不能用任何已列出的模型时,路由不提供模型。
|
|
74
93
|
|
|
75
94
|
<a id="dev-note"></a>
|
|
76
95
|
### 开发备注
|
package/lib/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { LlmError, assertUsableApiKey } from "@deepseek-ai/dsh-llm";
|
|
1
|
+
import { APP_IDENTITY, LlmError, assertUsableApiKey } from "@deepseek-ai/dsh-llm";
|
|
2
2
|
import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
|
|
3
|
-
import { catalogModelInfo, deepSeekConfigFields, plainOptions as plainOptions$1, registerDeepSeekProvider, resolveAdapterOptions as resolveAdapterOptions$1 } from "@deepseek-ai/dsh-llm-deepseek";
|
|
3
|
+
import { ModelListingCache, PUBLIC_BASE_URL, catalogModelInfo, deepSeekConfigFields, isBuiltInCatalog, modelListingConfigFields, modelListingURL, plainOptions as plainOptions$1, refuseListedModel, registerDeepSeekProvider, requestModelListing, resolveAdapterOptions as resolveAdapterOptions$1, resolveListedCatalog, resolveListingTiming } from "@deepseek-ai/dsh-llm-deepseek";
|
|
4
4
|
import z from "@deepseek-ai/schemastery";
|
|
5
5
|
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
6
6
|
//#region lib/types/config.js
|
|
7
|
+
/** Origin of the official API, the only endpoint whose `/models` listing this route follows. */
|
|
8
|
+
const OFFICIAL_ORIGIN = new URL(PUBLIC_BASE_URL).origin;
|
|
7
9
|
const Config = z.object({
|
|
8
10
|
...deepSeekConfigFields,
|
|
11
|
+
...modelListingConfigFields,
|
|
9
12
|
apiKeyEnv: z.string().role("credential-ref").default("DEEPSEEK_API_KEY").volatile()
|
|
10
13
|
});
|
|
11
14
|
/** Read one validated provider configuration.
|
|
@@ -18,15 +21,23 @@ function plainOptions(config) {
|
|
|
18
21
|
apiKeyEnv: config.apiKeyEnv.get()
|
|
19
22
|
};
|
|
20
23
|
}
|
|
21
|
-
/** Resolve API-key and protocol settings together.
|
|
24
|
+
/** Resolve API-key, listing, and protocol settings together.
|
|
22
25
|
* @param config - raw deployment settings.
|
|
23
26
|
* @param environment - application launch environment.
|
|
24
|
-
* @returns validated endpoint facts
|
|
27
|
+
* @returns validated endpoint facts, the matching credential reference, and the listing the catalog follows.
|
|
25
28
|
*/
|
|
26
29
|
function resolveAdapterOptions(config, environment) {
|
|
30
|
+
const { modelsTimeoutMs: _timeout, modelsMaxAgeMs: _maxAge, apiKeyEnv, ...messages } = config;
|
|
31
|
+
const timing = resolveListingTiming(config, "llm-deepseek-api-key");
|
|
32
|
+
const connection = resolveAdapterOptions$1(messages, environment);
|
|
33
|
+
const listed = new URL(connection.baseURL).origin === OFFICIAL_ORIGIN && isBuiltInCatalog(connection.models);
|
|
27
34
|
return {
|
|
28
|
-
...
|
|
29
|
-
apiKeyEnv: credentialRef(
|
|
35
|
+
...connection,
|
|
36
|
+
apiKeyEnv: credentialRef(apiKeyEnv ?? "DEEPSEEK_API_KEY"),
|
|
37
|
+
...listed ? { listing: {
|
|
38
|
+
url: modelListingURL(connection.baseURL),
|
|
39
|
+
...timing
|
|
40
|
+
} } : {}
|
|
30
41
|
};
|
|
31
42
|
}
|
|
32
43
|
//#endregion
|
|
@@ -34,6 +45,8 @@ function resolveAdapterOptions(config, environment) {
|
|
|
34
45
|
const name = "llm-deepseek-api-key";
|
|
35
46
|
const inject = ["llm"];
|
|
36
47
|
const PROVIDER = "deepseek-official";
|
|
48
|
+
/** Console tag of listing diagnostics; product profiles mount no console exporter for `ctx.logger`. */
|
|
49
|
+
const LOG_TAG = "[llm-deepseek-api-key]";
|
|
37
50
|
function apply(ctx, config) {
|
|
38
51
|
const options = () => resolveAdapterOptions(plainOptions(config), launchEnvironmentOf(ctx));
|
|
39
52
|
options();
|
|
@@ -49,6 +62,52 @@ function apply(ctx, config) {
|
|
|
49
62
|
}
|
|
50
63
|
throw new LlmError(`llm-deepseek: no API key for provider route "${PROVIDER}"; store ${ref} through the credentials service (the web Models page writes it), or export ${ref} in the launching environment`, "MISSING_CREDENTIAL");
|
|
51
64
|
};
|
|
65
|
+
/** The API key, or `undefined` when none is configured; other credential failures propagate. */
|
|
66
|
+
const presentApiKey = async (connection) => {
|
|
67
|
+
try {
|
|
68
|
+
return await resolveApiKey(connection);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
if (error instanceof LlmError && error.code === "MISSING_CREDENTIAL") return void 0;
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const listings = new ModelListingCache({
|
|
75
|
+
credential: async () => presentApiKey(options()),
|
|
76
|
+
load: (url, apiKey, signal) => requestModelListing(url, { "x-api-key": apiKey }, signal),
|
|
77
|
+
now: () => Date.now(),
|
|
78
|
+
info: (message) => {
|
|
79
|
+
console.error(LOG_TAG, message);
|
|
80
|
+
},
|
|
81
|
+
warn: (message) => {
|
|
82
|
+
console.warn(LOG_TAG, message);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
let reportedListing;
|
|
86
|
+
/** Resolve the catalog of one operation, reporting each listing's hidden entries once. */
|
|
87
|
+
const connectionOf = (connection, view) => {
|
|
88
|
+
if (view === void 0) return {
|
|
89
|
+
...connection,
|
|
90
|
+
offered: connection.models,
|
|
91
|
+
refusals: /* @__PURE__ */ new Map()
|
|
92
|
+
};
|
|
93
|
+
const catalog = resolveListedCatalog({
|
|
94
|
+
listing: view.listing?.entries,
|
|
95
|
+
supported: connection.models,
|
|
96
|
+
overrides: {},
|
|
97
|
+
routeMaxTokens: connection.maxTokens,
|
|
98
|
+
clientVersion: APP_IDENTITY.version
|
|
99
|
+
});
|
|
100
|
+
if (view.listing !== reportedListing) {
|
|
101
|
+
reportedListing = view.listing;
|
|
102
|
+
for (const problem of catalog.problems) console.warn(LOG_TAG, problem);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
...connection,
|
|
106
|
+
models: catalog.resolution,
|
|
107
|
+
offered: catalog.offered,
|
|
108
|
+
refusals: catalog.refusals
|
|
109
|
+
};
|
|
110
|
+
};
|
|
52
111
|
ctx.llm.registerConfigurableProviders([{
|
|
53
112
|
provider: PROVIDER,
|
|
54
113
|
displayName: "DeepSeek",
|
|
@@ -56,20 +115,51 @@ function apply(ctx, config) {
|
|
|
56
115
|
settingsPath: []
|
|
57
116
|
}]);
|
|
58
117
|
registerDeepSeekProvider(ctx, PROVIDER, {
|
|
59
|
-
options,
|
|
60
118
|
providerName: "DeepSeek",
|
|
61
|
-
|
|
62
|
-
discoverModels: async (provider) => {
|
|
119
|
+
options: () => {
|
|
63
120
|
const connection = options();
|
|
121
|
+
return connectionOf(connection, connection.listing === void 0 ? void 0 : listings.current());
|
|
122
|
+
},
|
|
123
|
+
connect: async (signal) => {
|
|
124
|
+
const connection = options();
|
|
125
|
+
if (connection.listing === void 0) return connectionOf(connection, void 0);
|
|
126
|
+
let view;
|
|
64
127
|
try {
|
|
65
|
-
await
|
|
128
|
+
view = await listings.view(connection.listing, signal);
|
|
66
129
|
} catch (error) {
|
|
67
|
-
if (
|
|
68
|
-
|
|
130
|
+
if (signal?.aborted === true) throw error;
|
|
131
|
+
return connectionOf(connection, void 0);
|
|
69
132
|
}
|
|
70
|
-
return connection
|
|
133
|
+
return connectionOf(connection, view);
|
|
134
|
+
},
|
|
135
|
+
resolveAuth: async (connection) => ({ headers: { "x-api-key": await resolveApiKey(connection) } }),
|
|
136
|
+
admit: (connection, model) => {
|
|
137
|
+
refuseListedModel(model, connection.refusals.get(model));
|
|
138
|
+
},
|
|
139
|
+
discoverModels: async (provider) => {
|
|
140
|
+
const connection = options();
|
|
141
|
+
if (connection.listing === void 0) {
|
|
142
|
+
if (await presentApiKey(connection) === void 0) return [];
|
|
143
|
+
return connection.models.map((model) => catalogModelInfo(provider, model));
|
|
144
|
+
}
|
|
145
|
+
const view = await listings.view(connection.listing);
|
|
146
|
+
return view.authenticated ? connectionOf(connection, view).offered.map((model) => catalogModelInfo(provider, model)) : [];
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
let following = options().listing !== void 0;
|
|
150
|
+
ctx.on("loader/volatile-update", () => {
|
|
151
|
+
let next;
|
|
152
|
+
try {
|
|
153
|
+
next = options().listing !== void 0;
|
|
154
|
+
} catch (_rejectedConfiguration) {
|
|
155
|
+
return;
|
|
71
156
|
}
|
|
157
|
+
if (next !== following) listings.invalidate();
|
|
158
|
+
following = next;
|
|
72
159
|
});
|
|
160
|
+
ctx.effect(() => () => {
|
|
161
|
+
listings.dispose();
|
|
162
|
+
}, "llm-deepseek-api-key: model listing");
|
|
73
163
|
}
|
|
74
164
|
//#endregion
|
|
75
165
|
export { Config, apply, inject, name, plainOptions, resolveAdapterOptions };
|
package/lib/types/config.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
/** API-key configuration resolved together with one Messages endpoint generation. */
|
|
1
|
+
/** API-key configuration resolved together with one Messages endpoint generation and its model listing. */
|
|
2
2
|
import type { Volatile } from '@deepseek-ai/cordis';
|
|
3
3
|
import z from '@deepseek-ai/schemastery';
|
|
4
4
|
import { type CredentialRef } from '@deepseek-ai/dsh-credentials';
|
|
5
5
|
import type { LaunchEnvironmentSnapshot } from '@deepseek-ai/dsh-launch-environment';
|
|
6
|
-
import {
|
|
7
|
-
import type { Options as ProtocolOptions, DeepSeekConnectionOptions } from '@deepseek-ai/dsh-llm-deepseek';
|
|
6
|
+
import type { Config as ProtocolConfig, DeepSeekConnectionOptions, ListingSettings, ModelListingConfig, ModelListingOptions, Options as ProtocolOptions } from '@deepseek-ai/dsh-llm-deepseek';
|
|
8
7
|
/** Messages configuration with a per-request API-key reference. */
|
|
9
|
-
export interface Config extends ProtocolConfig {
|
|
8
|
+
export interface Config extends ProtocolConfig, ModelListingConfig {
|
|
10
9
|
/** Credential reference resolved per request; defaults to DEEPSEEK_API_KEY. */
|
|
11
10
|
apiKeyEnv: Volatile<string>;
|
|
12
11
|
}
|
|
13
12
|
export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
14
13
|
apiKeyEnv: z<string, string, "volatile-defined">;
|
|
14
|
+
modelsTimeoutMs: z<number, number, "volatile-defined">;
|
|
15
|
+
modelsMaxAgeMs: z<number, number, "volatile-defined">;
|
|
15
16
|
baseURL: z<string, string, "volatile">;
|
|
16
17
|
thinking: z<"enabled" | "disabled", "enabled" | "disabled", "volatile">;
|
|
17
18
|
reasoningEffort: z<"low" | "off" | "high" | "max", "low" | "off" | "high" | "max", "volatile">;
|
|
@@ -32,6 +33,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
32
33
|
retryPolicy: z<NoInfer<import("@deepseek-ai/dsh-llm").RetryPolicyConfig>, NoInfer<import("@deepseek-ai/dsh-llm").RetryPolicyConfig>, "volatile">;
|
|
33
34
|
}>>, Schemastery.ObjectT<NoInfer<{
|
|
34
35
|
apiKeyEnv: z<string, string, "volatile-defined">;
|
|
36
|
+
modelsTimeoutMs: z<number, number, "volatile-defined">;
|
|
37
|
+
modelsMaxAgeMs: z<number, number, "volatile-defined">;
|
|
35
38
|
baseURL: z<string, string, "volatile">;
|
|
36
39
|
thinking: z<"enabled" | "disabled", "enabled" | "disabled", "volatile">;
|
|
37
40
|
reasoningEffort: z<"low" | "off" | "high" | "max", "low" | "off" | "high" | "max", "volatile">;
|
|
@@ -52,23 +55,28 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
52
55
|
retryPolicy: z<NoInfer<import("@deepseek-ai/dsh-llm").RetryPolicyConfig>, NoInfer<import("@deepseek-ai/dsh-llm").RetryPolicyConfig>, "volatile">;
|
|
53
56
|
}>>, "plain">;
|
|
54
57
|
/** Plain deployment inputs for the API-key provider. */
|
|
55
|
-
export type Options = ProtocolOptions & {
|
|
58
|
+
export type Options = ProtocolOptions & ModelListingOptions & {
|
|
56
59
|
apiKeyEnv?: string;
|
|
57
60
|
};
|
|
58
61
|
/** Endpoint and credential reference captured from the same configuration generation. */
|
|
59
62
|
export interface ResolvedDeepSeekOptions extends DeepSeekConnectionOptions {
|
|
60
63
|
/** Credential reference used only for this connection snapshot. */
|
|
61
64
|
apiKeyEnv: CredentialRef;
|
|
65
|
+
/**
|
|
66
|
+
* The official `/models` listing this generation follows; absent when `models`
|
|
67
|
+
* differs from the built-in catalog or the endpoint is not the official API.
|
|
68
|
+
*/
|
|
69
|
+
listing?: ListingSettings;
|
|
62
70
|
}
|
|
63
71
|
/** Read one validated provider configuration.
|
|
64
72
|
* @param config - live plugin configuration.
|
|
65
73
|
* @returns detached resolver inputs.
|
|
66
74
|
*/
|
|
67
75
|
export declare function plainOptions(config: Config): Options;
|
|
68
|
-
/** Resolve API-key and protocol settings together.
|
|
76
|
+
/** Resolve API-key, listing, and protocol settings together.
|
|
69
77
|
* @param config - raw deployment settings.
|
|
70
78
|
* @param environment - application launch environment.
|
|
71
|
-
* @returns validated endpoint facts
|
|
79
|
+
* @returns validated endpoint facts, the matching credential reference, and the listing the catalog follows.
|
|
72
80
|
*/
|
|
73
81
|
export declare function resolveAdapterOptions(config: Options, environment?: LaunchEnvironmentSnapshot): ResolvedDeepSeekOptions;
|
|
74
82
|
//# sourceMappingURL=config.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** API-key authentication
|
|
1
|
+
/** API-key authentication, credential-gated discovery, and the official model listing for the official DeepSeek route. */
|
|
2
2
|
import type { Context } from '@deepseek-ai/cordis';
|
|
3
3
|
import { Config } from './config.ts';
|
|
4
4
|
export { Config, plainOptions, resolveAdapterOptions } from './config.ts';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-llm-deepseek-api-key",
|
|
3
3
|
"description": "DeepSeek api-key provider authentication and discovery",
|
|
4
|
-
"version": "0.2.1-rc.
|
|
4
|
+
"version": "0.2.1-rc.4",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -30,18 +30,18 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"@deepseek-ai/cordis": "~4.0.5",
|
|
33
|
-
"@deepseek-ai/dsh-llm": "0.2.1-rc.
|
|
34
|
-
"@deepseek-ai/dsh-llm-deepseek": "0.2.1-rc.
|
|
35
|
-
"@deepseek-ai/dsh-launch-environment": "0.2.1-rc.
|
|
36
|
-
"@deepseek-ai/dsh-credentials": "0.2.1-rc.
|
|
33
|
+
"@deepseek-ai/dsh-llm": "0.2.1-rc.4",
|
|
34
|
+
"@deepseek-ai/dsh-llm-deepseek": "0.2.1-rc.4",
|
|
35
|
+
"@deepseek-ai/dsh-launch-environment": "0.2.1-rc.4",
|
|
36
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-rc.4",
|
|
37
37
|
"@deepseek-ai/cordis-plugin-loader": "~1.0.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@deepseek-ai/cordis": "~4.0.5",
|
|
41
|
-
"@deepseek-ai/dsh-llm": "0.2.1-rc.
|
|
42
|
-
"@deepseek-ai/dsh-llm-deepseek": "0.2.1-rc.
|
|
43
|
-
"@deepseek-ai/dsh-launch-environment": "0.2.1-rc.
|
|
44
|
-
"@deepseek-ai/dsh-credentials": "0.2.1-rc.
|
|
41
|
+
"@deepseek-ai/dsh-llm": "0.2.1-rc.4",
|
|
42
|
+
"@deepseek-ai/dsh-llm-deepseek": "0.2.1-rc.4",
|
|
43
|
+
"@deepseek-ai/dsh-launch-environment": "0.2.1-rc.4",
|
|
44
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-rc.4",
|
|
45
45
|
"@deepseek-ai/cordis-plugin-loader": "~1.0.6"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|