@deepseek-ai/dsh-deepseek-llm-api-extensions 0.2.1-alpha.1 → 0.2.1-alpha.3

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 CHANGED
@@ -15,8 +15,8 @@
15
15
  en: 6b7f62c318c9aad6
16
16
  zh: 5e22d58884e60c87
17
17
  /deepseek-ai-dsh-deepseek-llm-api-extensions/service:
18
- en: 5a7d0d78328568d0
19
- zh: c9180f610039e688
18
+ en: d9782207ffab7c50
19
+ zh: 22c2a10a5f0de61f
20
20
  /deepseek-ai-dsh-deepseek-llm-api-extensions/model-experience:
21
21
  en: 88a785350ced5c14
22
22
  zh: 755349be023a3f5c
package/README.md CHANGED
@@ -24,7 +24,7 @@ Provider-specific registry for additive top-level fields on official DeepSeek LL
24
24
  ## Service
25
25
 
26
26
  - `register(field, provider)` reserves one field for the calling fiber. Duplicate or malformed names fail synchronously; disposing the registration releases it for a later provider.
27
- - `prepare(request)` snapshots the registered providers, prepares them concurrently, clones and freezes returned JSON values, and returns `{ fields, accept }`. A preparation failure rejects before HTTP dispatch; request cancellation stops awaiting providers even when one ignores its signal.
27
+ - `prepare(request)` snapshots the registered providers, prepares them concurrently, clones and freezes returned JSON values, and returns `{ fields, accept }`. A provider whose preparation throws is omitted while the other fields are returned, and only its first failure is logged; request cancellation rejects and stops awaiting providers even when one ignores its signal.
28
28
  - `accept()` runs every captured post-2xx callback once. Concurrent calls join the same settlement, every callback settles before failures are reported, and several failures become one `AggregateError`.
29
29
 
30
30
  Each provider sees the exact serialized Messages body, the request `AbortSignal`, plus optional `sessionId` and auxiliary-call `purpose`. It must stop its own work promptly after cancellation and returns `undefined` when its field does not apply to that request. A prepared operation retains the providers it captured even if HMR removes their registrations before HTTP acceptance.
package/README.zh.md CHANGED
@@ -24,7 +24,7 @@ kind: "package-reference"
24
24
  ## 服务
25
25
 
26
26
  - `register(field, provider)` 为调用 fiber 保留一个字段。重复或格式错误的名称会同步失败;dispose(资源释放)该注册后,后续提供方可以再次认领。
27
- - `prepare(request)` 对已注册提供方取快照,并发准备贡献,克隆并冻结返回的 JSON 值,然后返回 `{ fields, accept }`。准备失败会在 HTTP 分发前拒绝请求;请求取消后,即使某个提供方忽略信号,注册表也会停止等待。
27
+ - `prepare(request)` 对已注册提供方取快照,并发准备贡献,克隆并冻结返回的 JSON 值,然后返回 `{ fields, accept }`。某个提供方准备时抛错,注册表会省略其字段,其余字段照常返回,且只记录该字段的首次失败;请求取消会使 `prepare` 拒绝,即使某个提供方忽略信号,注册表也会停止等待。
28
28
  - `accept()` 对每个捕获的 2xx 后回调只运行一次。并发调用会等待同一次结算,所有回调都在报告失败前完成,多个失败会合并为一个 `AggregateError`。
29
29
 
30
30
  每个提供方都会看到确切的已序列化 Messages 请求体、请求 `AbortSignal`,以及可选的 `sessionId` 与辅助调用 `purpose`。提供方必须在取消后迅速停止自身工作;字段不适用于当前请求时返回 `undefined`。即使 HMR(热模块替换)在 HTTP 接受前移除了注册,已准备的操作仍会保留其捕获的提供方。
package/lib/index.js CHANGED
@@ -38,6 +38,8 @@ async function abortable(work, signal) {
38
38
  /** Registry of independently owned top-level fields for official DeepSeek requests. */
39
39
  var DeepSeekLlmApiExtensionRegistry = class extends Service {
40
40
  providers = /* @__PURE__ */ new Map();
41
+ /** Fields whose preparation failure was already logged; later failures stay silent. */
42
+ warnedFields = /* @__PURE__ */ new Set();
41
43
  constructor(ctx) {
42
44
  super(ctx, "deepseekLlmApiExtensions");
43
45
  }
@@ -62,23 +64,37 @@ var DeepSeekLlmApiExtensionRegistry = class extends Service {
62
64
  }
63
65
  /**
64
66
  * Prepare every currently registered field from one immutable base request.
65
- * Preparation failures reject before HTTP dispatch. Field values are cloned and frozen;
66
- * providers retain no mutable alias to the outgoing request.
67
+ * A provider whose preparation throws, or whose value cannot be cloned, is omitted
68
+ * from this request; the first such failure per field is logged. Only cancellation rejects. Field values are cloned
69
+ * and frozen; providers retain no mutable alias to the outgoing request.
67
70
  * @param request - exact serialized request facts before extension fields.
68
71
  * @returns detached fields and their idempotent joint acceptance transaction.
69
72
  */
70
73
  async prepare(request) {
71
74
  request.signal.throwIfAborted();
72
75
  const entries = [...this.providers.entries()];
73
- const prepared = await abortable(Promise.all(entries.map(async ([field, provider]) => ({
74
- field,
75
- result: await provider.prepare(request)
76
- }))), request.signal);
76
+ const prepared = await abortable(Promise.all(entries.map(async ([field, provider]) => {
77
+ try {
78
+ const result = await provider.prepare(request);
79
+ return result === void 0 ? void 0 : {
80
+ field,
81
+ value: freezeJson(structuredClone(result.value)),
82
+ result
83
+ };
84
+ } catch (error) {
85
+ if (!request.signal.aborted && !this.warnedFields.has(field)) {
86
+ this.warnedFields.add(field);
87
+ this.ctx.logger.warn(`deepseek-llm-api-extensions: omitting field ${JSON.stringify(field)} from this request because its preparation failed: %o`, error);
88
+ }
89
+ return;
90
+ }
91
+ })), request.signal);
77
92
  const fields = Object.create(null);
78
93
  const callbacks = [];
79
- for (const { field, result } of prepared) {
80
- if (result === void 0) continue;
81
- fields[field] = freezeJson(structuredClone(result.value));
94
+ for (const item of prepared) {
95
+ if (item === void 0) continue;
96
+ const { field, value, result } = item;
97
+ fields[field] = value;
82
98
  const accept = result.accept;
83
99
  if (accept !== void 0) callbacks.push(accept.bind(result));
84
100
  }
@@ -14,6 +14,8 @@ declare module '@deepseek-ai/cordis' {
14
14
  /** Registry of independently owned top-level fields for official DeepSeek requests. */
15
15
  export declare class DeepSeekLlmApiExtensionRegistry extends Service {
16
16
  private readonly providers;
17
+ /** Fields whose preparation failure was already logged; later failures stay silent. */
18
+ private readonly warnedFields;
17
19
  constructor(ctx: Context);
18
20
  /**
19
21
  * Register the sole provider of one top-level request field. Registration is effect-scoped.
@@ -24,8 +26,9 @@ export declare class DeepSeekLlmApiExtensionRegistry extends Service {
24
26
  register<K extends keyof DeepSeekLlmApiExtensionMap>(field: K, provider: DeepSeekLlmApiExtensionProvider<DeepSeekLlmApiExtensionMap[K]>): () => Promise<void>;
25
27
  /**
26
28
  * Prepare every currently registered field from one immutable base request.
27
- * Preparation failures reject before HTTP dispatch. Field values are cloned and frozen;
28
- * providers retain no mutable alias to the outgoing request.
29
+ * A provider whose preparation throws, or whose value cannot be cloned, is omitted
30
+ * from this request; the first such failure per field is logged. Only cancellation rejects. Field values are cloned
31
+ * and frozen; providers retain no mutable alias to the outgoing request.
29
32
  * @param request - exact serialized request facts before extension fields.
30
33
  * @returns detached fields and their idempotent joint acceptance transaction.
31
34
  */
@@ -42,6 +42,8 @@ async function abortable(work, signal) {
42
42
  /** Registry of independently owned top-level fields for official DeepSeek requests. */
43
43
  export class DeepSeekLlmApiExtensionRegistry extends Service {
44
44
  providers = new Map();
45
+ /** Fields whose preparation failure was already logged; later failures stay silent. */
46
+ warnedFields = new Set();
45
47
  constructor(ctx) {
46
48
  super(ctx, 'deepseekLlmApiExtensions');
47
49
  }
@@ -71,24 +73,35 @@ export class DeepSeekLlmApiExtensionRegistry extends Service {
71
73
  }
72
74
  /**
73
75
  * Prepare every currently registered field from one immutable base request.
74
- * Preparation failures reject before HTTP dispatch. Field values are cloned and frozen;
75
- * providers retain no mutable alias to the outgoing request.
76
+ * A provider whose preparation throws, or whose value cannot be cloned, is omitted
77
+ * from this request; the first such failure per field is logged. Only cancellation rejects. Field values are cloned
78
+ * and frozen; providers retain no mutable alias to the outgoing request.
76
79
  * @param request - exact serialized request facts before extension fields.
77
80
  * @returns detached fields and their idempotent joint acceptance transaction.
78
81
  */
79
82
  async prepare(request) {
80
83
  request.signal.throwIfAborted();
81
84
  const entries = [...this.providers.entries()];
82
- const prepared = await abortable(Promise.all(entries.map(async ([field, provider]) => ({
83
- field,
84
- result: await provider.prepare(request),
85
- }))), request.signal);
85
+ const prepared = await abortable(Promise.all(entries.map(async ([field, provider]) => {
86
+ try {
87
+ const result = await provider.prepare(request);
88
+ return result === undefined ? undefined : { field, value: freezeJson(structuredClone(result.value)), result };
89
+ }
90
+ catch (error) {
91
+ if (!request.signal.aborted && !this.warnedFields.has(field)) {
92
+ this.warnedFields.add(field);
93
+ this.ctx.logger.warn(`deepseek-llm-api-extensions: omitting field ${JSON.stringify(field)} from this request because its preparation failed: %o`, error);
94
+ }
95
+ return undefined;
96
+ }
97
+ })), request.signal);
86
98
  const fields = Object.create(null);
87
99
  const callbacks = [];
88
- for (const { field, result } of prepared) {
89
- if (result === undefined)
100
+ for (const item of prepared) {
101
+ if (item === undefined)
90
102
  continue;
91
- fields[field] = freezeJson(structuredClone(result.value));
103
+ const { field, value, result } = item;
104
+ fields[field] = value;
92
105
  const accept = result.accept;
93
106
  if (accept !== undefined)
94
107
  callbacks.push(accept.bind(result));
package/locale/en.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "deepseek-llm-api-extensions"
4
+ }
5
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "DeepSeek API 扩展",
4
+ "description": "允许其他插件向 DeepSeek 模型请求添加扩展字段。"
5
+ }
6
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-deepseek-llm-api-extensions",
3
3
  "description": "Additive request-field registry for the official DeepSeek LLM API adapter",
4
- "version": "0.2.1-alpha.1",
4
+ "version": "0.2.1-alpha.3",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -23,18 +23,20 @@
23
23
  "default": "./lib/types/types.js"
24
24
  },
25
25
  "./src/*": "./src/*",
26
- "./package.json": "./package.json"
26
+ "./package.json": "./package.json",
27
+ "./locale/*.json": "./locale/*.json"
27
28
  },
28
29
  "files": [
30
+ "locale/*.json",
29
31
  "lib/index.js",
30
32
  "lib/types/**/*.js",
31
33
  "lib/types/**/*.d.ts"
32
34
  ],
33
35
  "license": "MIT",
34
36
  "peerDependencies": {
35
- "@deepseek-ai/cordis": "~4.0.5-alpha.1"
37
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2"
36
38
  },
37
39
  "devDependencies": {
38
- "@deepseek-ai/cordis": "~4.0.5-alpha.1"
40
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2"
39
41
  }
40
42
  }