dsh-gateway-provider 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -97,7 +97,7 @@ the same keys). The frequently used ones:
97
97
  | `gateways` | — | Array of extra gateways: `{ id, baseURL, apiKeyEnv, label, … }`, each becoming a `gateway:<id>` route. |
98
98
  | `models` | — | Per-model overrides: `{ id, name, disabled, protocol, contextWindow, maxTokens, reasoningLevels }`. |
99
99
  | `useModelsDev` / `modelsUrl` | `true` / models.dev | Parameter enrichment source (supports `file:` URLs for offline). |
100
- | `excludePatterns` | image/speech/… | Regex list of model ids to keep out of the picker. |
100
+ | `excludePatterns` | image/speech/… | Regex list of model ids to keep out of the picker (matched case-insensitively). |
101
101
  | `sortModelsByRelease` | `true` | Newest models first. |
102
102
  | `catalogMode` | `auto` | `v1` (`/v1/models` only) / `management` (newapi user API) / `auto`. |
103
103
  | `endpointPriority` | responses → anthropic → openai → gemini | Which protocol to prefer when a model supports several. |
package/docs/README.zh.md CHANGED
@@ -63,7 +63,7 @@ dsh --profile web
63
63
  | `gateways` | — | 额外网关数组:`{ id, baseURL, apiKeyEnv, label, … }`,每个成为一条 `gateway:<id>` 路由。 |
64
64
  | `models` | — | 按模型覆盖:`{ id, name, disabled, protocol, contextWindow, maxTokens, reasoningLevels }`。 |
65
65
  | `useModelsDev` / `modelsUrl` | `true` / models.dev | 参数增补来源(支持 `file:` URL 离线用)。 |
66
- | `excludePatterns` | 图像/语音/…… | 要从选择器排除的模型 id 正则列表。 |
66
+ | `excludePatterns` | 图像/语音/…… | 要从选择器排除的模型 id 正则列表(不区分大小写)。 |
67
67
  | `sortModelsByRelease` | `true` | 最新模型排前面。 |
68
68
  | `catalogMode` | `auto` | `v1`(只用 `/v1/models`)/ `management`(newapi 用户 API)/ `auto`。 |
69
69
  | `endpointPriority` | responses → anthropic → openai → gemini | 模型支持多种协议时的优先序。 |
package/index.js CHANGED
@@ -31,7 +31,6 @@ import z from "@deepseek-ai/schemastery";
31
31
  import { LlmError, RetryPolicySchema, assertUsableApiKey, resolveRetryPolicy } from "@deepseek-ai/dsh-llm";
32
32
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
33
33
  import { launchEnvironmentOf } from "@deepseek-ai/dsh-launch-environment";
34
- import { deepEqualJson, installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
35
34
  import { MAX_TIMER_DELAY_MS } from "@deepseek-ai/dsh-timeout";
36
35
  import { NewapiAdapter } from "./lib/adapter.js";
37
36
  import { DEFAULT_EXCLUDE_PATTERNS, DEFAULT_MAX_TOKENS, DEFAULT_CONTEXT_WINDOW } from "./lib/catalog.js";
@@ -41,7 +40,7 @@ export const name = "llm-newapi";
41
40
  export const inject = ["llm"];
42
41
 
43
42
  /** User-settings namespace whose section overrides this entry. */
44
- const NS = settingsNamespace("llm-newapi");
43
+ const NS = "llm-newapi";
45
44
  /** The legacy single provider route (kept for backwards compatibility). */
46
45
  export const PROVIDER = "newapi";
47
46
  /** Prefix for additional gateway routes. */
@@ -373,7 +372,7 @@ export function apply(ctx, config) {
373
372
  // Include the per-protocol bases: URL-addressed (custom) gateways may
374
373
  // share an empty plain baseURL, and URL-only edits must re-register.
375
374
  const facts = gateways.map((g) => `${g.provider}:${g.connection.baseURL}:${g.label}:${g.connection.apiBases ? JSON.stringify(g.connection.apiBases) : ""}`);
376
- if (deepEqualJson(facts, directoryFacts)) return;
375
+ if (directoryFacts !== undefined && JSON.stringify(facts) === JSON.stringify(directoryFacts)) return;
377
376
  const entries = gateways.map((g, i) => ({
378
377
  provider: g.provider,
379
378
  displayName: g.label,
@@ -413,10 +412,12 @@ export function apply(ctx, config) {
413
412
  }
414
413
  });
415
414
 
416
- installSettingsSection(ctx, NS, Config, config, {
417
- setSource: (source) => {
418
- current = source;
419
- },
420
- onChange: ensureRegistration,
415
+ ctx.inject(["settings"], (settingsCtx) => {
416
+ settingsCtx.settings.installSection(ctx, NS, Config, config, {
417
+ setSource: (source) => {
418
+ current = source;
419
+ },
420
+ onChange: ensureRegistration,
421
+ });
421
422
  });
422
423
  }
package/lib/catalog.js CHANGED
@@ -154,11 +154,11 @@ async function fetchNewapiModels(connection, apiKey, signal) {
154
154
  return fetchManagementModels(base, apiKey, connection.userId, signal);
155
155
  }
156
156
 
157
- /** Apply the picker filter (chat-only + exclude patterns). */
157
+ /** Apply the picker filter (chat-only + exclude patterns, matched case-insensitively). */
158
158
  function filterEntries(entries, connection) {
159
159
  const patterns = (connection.excludePatterns ?? DEFAULT_EXCLUDE_PATTERNS).map((p) => {
160
160
  try {
161
- return new RegExp(p);
161
+ return new RegExp(p, "i");
162
162
  } catch {
163
163
  return undefined;
164
164
  }
package/lib/client.js CHANGED
@@ -918,7 +918,7 @@ window.__ModuleLoader__.load({
918
918
  // Keep the stored list aligned with what the picker will show:
919
919
  // drop entries matched by the configured exclude patterns.
920
920
  var patterns = (snap.excludePatterns || []).map(function (p) {
921
- try { return new RegExp(p); } catch (e) { return null; }
921
+ try { return new RegExp(p, "i"); } catch (e) { return null; }
922
922
  }).filter(Boolean);
923
923
  var discovered = found
924
924
  .filter(function (m) { return !patterns.some(function (re) { return re.test(m.id); }); })
package/lib/pi-bridge.js CHANGED
@@ -17,10 +17,10 @@
17
17
 
18
18
  import {
19
19
  CONTEXT_WINDOW_EXCEEDED_CODE,
20
- CallId,
21
20
  EMPTY_RESPONSE_CODE,
22
21
  LlmError,
23
22
  QUOTA_EXCEEDED_CODE,
23
+ ToolCallId,
24
24
  attributionHeaders,
25
25
  contentHasImage,
26
26
  isContextWindowExceededError,
@@ -275,7 +275,7 @@ function textOnlyContext(options) {
275
275
  }
276
276
  if (message.role === "assistant") {
277
277
  const assistant = toPiAssistant(message);
278
- for (const block of assistant.content) if (block.type === "toolCall") toolNames.set(CallId(block.id), block.name);
278
+ for (const block of assistant.content) if (block.type === "toolCall") toolNames.set(ToolCallId(block.id), block.name);
279
279
  messages.push(assistant);
280
280
  continue;
281
281
  }
@@ -306,7 +306,7 @@ async function toPiContextWithImages(options, attachments) {
306
306
  }
307
307
  if (message.role === "assistant") {
308
308
  const assistant = toPiAssistant(message);
309
- for (const block of assistant.content) if (block.type === "toolCall") toolNames.set(CallId(block.id), block.name);
309
+ for (const block of assistant.content) if (block.type === "toolCall") toolNames.set(ToolCallId(block.id), block.name);
310
310
  messages.push(assistant);
311
311
  continue;
312
312
  }
@@ -455,7 +455,7 @@ export async function* toStreamChunks(events, contextWindow) {
455
455
  yield {
456
456
  type: "tool-call-delta",
457
457
  index: event.contentIndex,
458
- id: CallId(known?.id ?? ""),
458
+ id: ToolCallId(known?.id ?? ""),
459
459
  ...known?.name !== void 0 && known.name.length > 0 ? { name: known.name } : {},
460
460
  argumentsDelta: event.delta,
461
461
  };
@@ -467,7 +467,7 @@ export async function* toStreamChunks(events, contextWindow) {
467
467
  index: event.contentIndex,
468
468
  block: {
469
469
  type: "tool-call",
470
- id: CallId(event.toolCall.id),
470
+ id: ToolCallId(event.toolCall.id),
471
471
  name: event.toolCall.name,
472
472
  arguments: JSON.stringify(event.toolCall.arguments),
473
473
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-gateway-provider",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Generic LLM gateway model provider plugin for DeepSeek Harness: mounts newapi / LiteLLM / Higress / any OpenAI-compatible gateway as provider routes, auto-discovers the model list, enriches every model with models.dev parameters, and dispatches each model over its native wire protocol (OpenAI / Anthropic / Gemini) via the pi-ai SDK",
5
5
  "repository": {
6
6
  "type": "git",
@@ -66,12 +66,11 @@
66
66
  "@earendil-works/pi-ai": "0.84.4"
67
67
  },
68
68
  "peerDependencies": {
69
- "@deepseek-ai/cordis": "^4.0.1",
70
- "@deepseek-ai/dsh-credentials": "^0.1.0-rc.7",
71
- "@deepseek-ai/dsh-launch-environment": "^0.1.0-rc.7",
72
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.7",
73
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.7",
74
- "@deepseek-ai/dsh-timeout": "^0.1.0-rc.7",
69
+ "@deepseek-ai/cordis": "^4.0.2",
70
+ "@deepseek-ai/dsh-credentials": "^0.1.2-rc.1",
71
+ "@deepseek-ai/dsh-launch-environment": "^0.1.2-rc.1",
72
+ "@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
73
+ "@deepseek-ai/dsh-timeout": "^0.1.2-rc.1",
75
74
  "@deepseek-ai/schemastery": "^3.18.1"
76
75
  }
77
76
  }