@mofeng2223/dsh-claude-provider 0.4.3 → 0.4.5

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.
Files changed (2) hide show
  1. package/lib/client.js +84 -42
  2. package/package.json +3 -3
package/lib/client.js CHANGED
@@ -911,7 +911,8 @@ window.__ModuleLoader__.load({
911
911
  settingsNs: entry.settingsNs,
912
912
  settingsPath: [...entry.settingsPath],
913
913
  active: active.has(entry.provider),
914
- ...entry.declared === void 0 ? {} : { declared: entry.declared }
914
+ ...entry.declared === void 0 ? {} : { declared: entry.declared },
915
+ ...entry.error === void 0 ? {} : { error: entry.error }
915
916
  }));
916
917
  for (const provider of registered) {
917
918
  if (declared.has(provider.id)) continue;
@@ -1157,6 +1158,14 @@ window.__ModuleLoader__.load({
1157
1158
  * credential seam with a raw regular expression the user cannot act on.
1158
1159
  */
1159
1160
  const ROUTE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
1161
+ function isHttpUrl(value) {
1162
+ try {
1163
+ const protocol = new URL(value).protocol;
1164
+ return protocol === "http:" || protocol === "https:";
1165
+ } catch {
1166
+ return false;
1167
+ }
1168
+ }
1160
1169
  /**
1161
1170
  * Render the custom-provider creation card.
1162
1171
  * @param props - existing routes, protocol choices, wire faces, and copy.
@@ -1186,11 +1195,13 @@ window.__ModuleLoader__.load({
1186
1195
  const profileDisabled = disabled || committed;
1187
1196
  const routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route);
1188
1197
  const routeTaken = taken.includes(route);
1198
+ const normalizedBaseURL = baseURL.trim();
1199
+ const baseUrlInvalid = baseURL.length > 0 && !isHttpUrl(normalizedBaseURL);
1189
1200
  const modelFailure = validateDeepSeekModels(models);
1190
1201
  const keyFailure = apiKeyFailure(keyDraft);
1191
1202
  const keyValue = keyDraft.trim();
1192
- const ready = route.length > 0 && !routeInvalid && !routeTaken && baseURL.length > 0 && models.length > 0 && modelFailure === void 0 && keyFailure === void 0;
1193
- const hint = failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken ? void 0 : baseURL.length === 0 ? t("customNeedsBaseUrl") : modelFailure !== void 0 ? `${t("model")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t("customNeedsModels");
1203
+ const ready = route.length > 0 && !routeInvalid && !routeTaken && normalizedBaseURL.length > 0 && !baseUrlInvalid && models.length > 0 && modelFailure === void 0 && keyFailure === void 0;
1204
+ const hint = failure !== void 0 || ready || keyFailure !== void 0 || route.length === 0 || routeInvalid || routeTaken || baseUrlInvalid ? void 0 : normalizedBaseURL.length === 0 ? t("customNeedsBaseUrl") : modelFailure !== void 0 ? `${t("model")} ${String(modelFailure.index + 1)}: ${t(modelFailure.key)}` : t("customNeedsModels");
1194
1205
  /** Perform the create, returning a failure message or undefined. */
1195
1206
  const createOnce = async () => {
1196
1207
  const keyRef = deriveKeyRef(route);
@@ -1200,7 +1211,7 @@ window.__ModuleLoader__.load({
1200
1211
  ...displayName.length === 0 ? {} : { displayName },
1201
1212
  ...storesKey ? { apiKeyEnv: keyRef } : {},
1202
1213
  api: isAdaptiveClaude ? "anthropic-messages" : protocol,
1203
- baseURL,
1214
+ baseURL: normalizedBaseURL,
1204
1215
  models: models.map((model) => isAdaptiveClaude ? withNativeClaudeModel(model) : { ...model }),
1205
1216
  ...isAdaptiveClaude ? { reasoning: "high" } : {}
1206
1217
  };
@@ -1306,12 +1317,17 @@ window.__ModuleLoader__.load({
1306
1317
  value: baseURL,
1307
1318
  placeholder: t("customBaseUrlPlaceholder"),
1308
1319
  "aria-label": t("baseUrl"),
1320
+ "aria-invalid": baseUrlInvalid,
1309
1321
  disabled: profileDisabled,
1310
1322
  onChange: (event) => {
1311
1323
  setBaseURL(event.target.value);
1312
1324
  }
1313
1325
  })]
1314
1326
  }),
1327
+ baseUrlInvalid ? (0, react_jsx_runtime.jsx)("p", {
1328
+ className: ModelsSection_module_css_default["error"],
1329
+ children: t("customBaseUrlInvalid")
1330
+ }) : null,
1315
1331
  (0, react_jsx_runtime.jsxs)("div", {
1316
1332
  className: ModelsSection_module_css_default["field"],
1317
1333
  children: [(0, react_jsx_runtime.jsx)("span", {
@@ -1361,11 +1377,11 @@ window.__ModuleLoader__.load({
1361
1377
  onChange: setModels,
1362
1378
  probe: {
1363
1379
  settingsNs: NS$1,
1364
- baseURL,
1380
+ baseURL: normalizedBaseURL,
1365
1381
  api: protocol,
1366
1382
  ...keyValue.length === 0 ? {} : { apiKey: keyValue }
1367
1383
  },
1368
- probeBlocked: keyFailure === "keyBlank" ? "keyBlankNew" : keyFailure,
1384
+ probeBlocked: baseUrlInvalid ? "customBaseUrlInvalid" : keyFailure === "keyBlank" ? "keyBlankNew" : keyFailure,
1369
1385
  thinkingPresets: isAdaptiveClaude,
1370
1386
  operations,
1371
1387
  t,
@@ -1419,8 +1435,6 @@ window.__ModuleLoader__.load({
1419
1435
  * path ops against the stored section — the card names only the fields it can
1420
1436
  * see instead of rebuilding the whole subtree from a partial descriptor.
1421
1437
  */
1422
- /** The public DeepSeek endpoint shown as the deepseek base-URL placeholder. */
1423
- const DEEPSEEK_PUBLIC_BASE_URL = "https://api.deepseek.com";
1424
1438
  /** A user-section subtree as a plain draft object (absent → empty). */
1425
1439
  function draftAt(schema, namespace, path) {
1426
1440
  const subtree = schema.getPath(namespace.user, path);
@@ -1679,20 +1693,29 @@ window.__ModuleLoader__.load({
1679
1693
  }) : null,
1680
1694
  (0, react_jsx_runtime.jsxs)("div", {
1681
1695
  className: ModelsSection_module_css_default["field"],
1682
- children: [(0, react_jsx_runtime.jsx)("span", {
1683
- className: ModelsSection_module_css_default["fieldLabel"],
1684
- children: t("baseUrl")
1685
- }), (0, react_jsx_runtime.jsx)("input", {
1686
- className: ModelsSection_module_css_default["input"],
1687
- type: "text",
1688
- value: stringAt(draft, "baseURL") ?? "",
1689
- placeholder: family === "deepseek" ? DEEPSEEK_PUBLIC_BASE_URL : stringAt(fallback, "baseURL") ?? t("baseUrlDefault"),
1690
- "aria-label": t("baseUrl"),
1691
- disabled,
1692
- onChange: (event) => {
1693
- setField("baseURL", event.target.value === "" ? void 0 : event.target.value);
1694
- }
1695
- })]
1696
+ children: [
1697
+ (0, react_jsx_runtime.jsx)("span", {
1698
+ className: ModelsSection_module_css_default["fieldLabel"],
1699
+ children: t("baseUrl")
1700
+ }),
1701
+ (0, react_jsx_runtime.jsx)("input", {
1702
+ className: ModelsSection_module_css_default["input"],
1703
+ type: "text",
1704
+ value: stringAt(draft, "baseURL") ?? "",
1705
+ placeholder: family === "deepseek" ? t(stringAt(fallback, "protocol") === "messages" ? "deepSeekMessagesBaseUrl" : "deepSeekChatBaseUrl") : stringAt(fallback, "baseURL") ?? t("baseUrlDefault"),
1706
+ "aria-describedby": family === "deepseek" ? `${props.provider}-endpoint-hint` : void 0,
1707
+ "aria-label": t("baseUrl"),
1708
+ disabled,
1709
+ onChange: (event) => {
1710
+ setField("baseURL", event.target.value === "" ? void 0 : event.target.value);
1711
+ }
1712
+ }),
1713
+ family === "deepseek" ? (0, react_jsx_runtime.jsx)("span", {
1714
+ id: `${props.provider}-endpoint-hint`,
1715
+ className: ModelsSection_module_css_default["advancedHint"],
1716
+ children: t("deepSeekEndpointHint")
1717
+ }) : null
1718
+ ]
1696
1719
  }),
1697
1720
  ownsIdentity ? (0, react_jsx_runtime.jsxs)("div", {
1698
1721
  className: ModelsSection_module_css_default["field"],
@@ -2087,7 +2110,8 @@ window.__ModuleLoader__.load({
2087
2110
  };
2088
2111
  const anyUsable = state.rows.some(providerUsable);
2089
2112
  const configured = state.rows.filter((row) => row.configured);
2090
- const addable = state.rows.filter((row) => !row.configured && row.entry.settingsNs !== "");
2113
+ const configurable = state.rows.filter((row) => state.namespaces.has(row.entry.settingsNs));
2114
+ const addable = configurable.filter((row) => !row.configured);
2091
2115
  const addTarget = adding ? editing : void 0;
2092
2116
  const addNamespace = addTarget === void 0 ? void 0 : state.namespaces.get(addTarget.settingsNs);
2093
2117
  const addRow = addTarget === void 0 ? void 0 : state.rows.find((row) => row.entry.provider === addTarget.provider);
@@ -2120,24 +2144,33 @@ window.__ModuleLoader__.load({
2120
2144
  const namespace = state.namespaces.get(target.settingsNs);
2121
2145
  /* v8 ignore next -- the join marks a row configured only when its namespace resolved */
2122
2146
  if (namespace === void 0) return null;
2147
+ const error = row.entry.error === void 0 ? null : (0, react_jsx_runtime.jsx)("p", {
2148
+ role: "alert",
2149
+ className: ModelsSection_module_css_default["error"],
2150
+ children: row.entry.error
2151
+ });
2123
2152
  if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) return (0, react_jsx_runtime.jsxs)("li", {
2124
2153
  className: ModelsSection_module_css_default["setupCard"],
2125
- children: [renderProviderEditor({
2126
- target,
2127
- namespace,
2128
- schema,
2129
- thinkingPresets: isClaudeProvider(row, state),
2130
- operations,
2131
- t,
2132
- readOnly: !state.writable,
2133
- onClose: (changed) => {
2134
- closeSetup(changed, target);
2135
- }
2136
- }), renderSlot("settings.models.provider-card", {
2137
- provider: row.entry,
2138
- configured: row.configured,
2139
- keyConfigured: keyConfiguredOf(row)
2140
- }, { entryKey: row.entry.settingsNs })]
2154
+ children: [
2155
+ error,
2156
+ renderProviderEditor({
2157
+ target,
2158
+ namespace,
2159
+ schema,
2160
+ thinkingPresets: isClaudeProvider(row, state),
2161
+ operations,
2162
+ t,
2163
+ readOnly: !state.writable,
2164
+ onClose: (changed) => {
2165
+ closeSetup(changed, target);
2166
+ }
2167
+ }),
2168
+ renderSlot("settings.models.provider-card", {
2169
+ provider: row.entry,
2170
+ configured: row.configured,
2171
+ keyConfigured: keyConfiguredOf(row)
2172
+ }, { entryKey: row.entry.settingsNs })
2173
+ ]
2141
2174
  }, row.entry.provider);
2142
2175
  const open = !adding && editing?.provider === row.entry.provider;
2143
2176
  const adaptiveClaude = isClaudeProvider(row, state);
@@ -2202,6 +2235,7 @@ window.__ModuleLoader__.load({
2202
2235
  }) : null]
2203
2236
  })]
2204
2237
  }),
2238
+ error,
2205
2239
  renderSlot("settings.models.provider-card", {
2206
2240
  provider: row.entry,
2207
2241
  configured: row.configured,
@@ -2287,7 +2321,7 @@ window.__ModuleLoader__.load({
2287
2321
  })
2288
2322
  }) : (0, react_jsx_runtime.jsxs)("div", {
2289
2323
  className: ModelsSection_module_css_default["addActions"],
2290
- children: [(0, react_jsx_runtime.jsxs)("button", {
2324
+ children: [configurable.length > 0 && (0, react_jsx_runtime.jsxs)("button", {
2291
2325
  type: "button",
2292
2326
  className: ModelsSection_module_css_default["addButton"],
2293
2327
  disabled: addable.length === 0 || !state.writable,
@@ -2301,7 +2335,7 @@ window.__ModuleLoader__.load({
2301
2335
  setEditing(targetOf(first));
2302
2336
  },
2303
2337
  children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 }), t("add")]
2304
- }), (0, react_jsx_runtime.jsxs)("button", {
2338
+ }), state.namespaces.has("llm-pi-ai") && (0, react_jsx_runtime.jsxs)("button", {
2305
2339
  type: "button",
2306
2340
  className: ModelsSection_module_css_default["addButton"],
2307
2341
  disabled: protocols.length === 0 || !state.writable,
@@ -2315,7 +2349,7 @@ window.__ModuleLoader__.load({
2315
2349
  }), (0, react_jsx_runtime.jsxs)("button", {
2316
2350
  type: "button",
2317
2351
  className: ModelsSection_module_css_default["addButton"],
2318
- disabled: !state.namespaces.has(CLAUDE_PROVIDER_SETTINGS_NS) || !state.writable,
2352
+ disabled: !state.namespaces.has("llm-pi-ai") || !state.namespaces.has(CLAUDE_PROVIDER_SETTINGS_NS) || !state.writable,
2319
2353
  onClick: () => {
2320
2354
  setSavedTarget(void 0);
2321
2355
  setAdding(false);
@@ -2830,6 +2864,9 @@ window.__ModuleLoader__.load({
2830
2864
  customized: "Customized settings",
2831
2865
  baseUrl: "Base URL",
2832
2866
  baseUrlDefault: "Provider default",
2867
+ deepSeekChatBaseUrl: "https://api.deepseek.com",
2868
+ deepSeekMessagesBaseUrl: "https://api.deepseek.com/anthropic",
2869
+ deepSeekEndpointHint: "Use an endpoint compatible with the configured connection.",
2833
2870
  models: "Models",
2834
2871
  modelsInherited: "Using the adapter defaults",
2835
2872
  modelsCustomized: "Customized model catalog",
@@ -2894,6 +2931,7 @@ window.__ModuleLoader__.load({
2894
2931
  customApi: "API protocol",
2895
2932
  customApiUnset: "Not selected",
2896
2933
  customNeedsBaseUrl: "A custom provider needs a base URL.",
2934
+ customBaseUrlInvalid: "Enter a valid HTTP or HTTPS URL.",
2897
2935
  customNeedsModels: "A custom provider needs at least one model.",
2898
2936
  customBaseUrlPlaceholder: "https://gateway.example/v1",
2899
2937
  settingsPathUnresolvable: "unresolvable settings path",
@@ -2945,6 +2983,9 @@ window.__ModuleLoader__.load({
2945
2983
  customized: "自定义设置",
2946
2984
  baseUrl: "API 地址",
2947
2985
  baseUrlDefault: "提供方默认",
2986
+ deepSeekChatBaseUrl: "https://api.deepseek.com",
2987
+ deepSeekMessagesBaseUrl: "https://api.deepseek.com/anthropic",
2988
+ deepSeekEndpointHint: "请填写与当前连接配置兼容的 API 地址。",
2948
2989
  models: "模型目录",
2949
2990
  modelsInherited: "正在使用适配器默认模型",
2950
2991
  modelsCustomized: "已自定义模型目录",
@@ -3009,6 +3050,7 @@ window.__ModuleLoader__.load({
3009
3050
  customApi: "API 协议",
3010
3051
  customApiUnset: "未选择",
3011
3052
  customNeedsBaseUrl: "自定义提供方需要填写 API 地址。",
3053
+ customBaseUrlInvalid: "请输入有效的 HTTP 或 HTTPS 地址。",
3012
3054
  customNeedsModels: "自定义提供方至少需要一个模型。",
3013
3055
  customBaseUrlPlaceholder: "https://gateway.example/v1",
3014
3056
  settingsPathUnresolvable: "无法解析设置路径",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mofeng2223/dsh-claude-provider",
3
- "version": "0.4.3",
4
- "description": "Custom Claude provider support for DeepSeek Harness 0.1.3-alpha.2",
3
+ "version": "0.4.5",
4
+ "description": "Custom Claude provider support for DeepSeek Harness 0.1.6-alpha.1",
5
5
  "author": "mofeng2223",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -60,6 +60,6 @@
60
60
  }
61
61
  },
62
62
  "devDependencies": {
63
- "@deepseek-ai/dsh-client-ui-settings-models": "0.1.3-alpha.2"
63
+ "@deepseek-ai/dsh-client-ui-settings-models": "0.1.6-alpha.1"
64
64
  }
65
65
  }