@mofeng2223/dsh-claude-provider 0.4.3 → 0.4.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.
Files changed (2) hide show
  1. package/lib/client.js +55 -26
  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,
@@ -2087,7 +2103,8 @@ window.__ModuleLoader__.load({
2087
2103
  };
2088
2104
  const anyUsable = state.rows.some(providerUsable);
2089
2105
  const configured = state.rows.filter((row) => row.configured);
2090
- const addable = state.rows.filter((row) => !row.configured && row.entry.settingsNs !== "");
2106
+ const configurable = state.rows.filter((row) => state.namespaces.has(row.entry.settingsNs));
2107
+ const addable = configurable.filter((row) => !row.configured);
2091
2108
  const addTarget = adding ? editing : void 0;
2092
2109
  const addNamespace = addTarget === void 0 ? void 0 : state.namespaces.get(addTarget.settingsNs);
2093
2110
  const addRow = addTarget === void 0 ? void 0 : state.rows.find((row) => row.entry.provider === addTarget.provider);
@@ -2120,24 +2137,33 @@ window.__ModuleLoader__.load({
2120
2137
  const namespace = state.namespaces.get(target.settingsNs);
2121
2138
  /* v8 ignore next -- the join marks a row configured only when its namespace resolved */
2122
2139
  if (namespace === void 0) return null;
2140
+ const error = row.entry.error === void 0 ? null : (0, react_jsx_runtime.jsx)("p", {
2141
+ role: "alert",
2142
+ className: ModelsSection_module_css_default["error"],
2143
+ children: row.entry.error
2144
+ });
2123
2145
  if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) return (0, react_jsx_runtime.jsxs)("li", {
2124
2146
  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 })]
2147
+ children: [
2148
+ error,
2149
+ renderProviderEditor({
2150
+ target,
2151
+ namespace,
2152
+ schema,
2153
+ thinkingPresets: isClaudeProvider(row, state),
2154
+ operations,
2155
+ t,
2156
+ readOnly: !state.writable,
2157
+ onClose: (changed) => {
2158
+ closeSetup(changed, target);
2159
+ }
2160
+ }),
2161
+ renderSlot("settings.models.provider-card", {
2162
+ provider: row.entry,
2163
+ configured: row.configured,
2164
+ keyConfigured: keyConfiguredOf(row)
2165
+ }, { entryKey: row.entry.settingsNs })
2166
+ ]
2141
2167
  }, row.entry.provider);
2142
2168
  const open = !adding && editing?.provider === row.entry.provider;
2143
2169
  const adaptiveClaude = isClaudeProvider(row, state);
@@ -2202,6 +2228,7 @@ window.__ModuleLoader__.load({
2202
2228
  }) : null]
2203
2229
  })]
2204
2230
  }),
2231
+ error,
2205
2232
  renderSlot("settings.models.provider-card", {
2206
2233
  provider: row.entry,
2207
2234
  configured: row.configured,
@@ -2287,7 +2314,7 @@ window.__ModuleLoader__.load({
2287
2314
  })
2288
2315
  }) : (0, react_jsx_runtime.jsxs)("div", {
2289
2316
  className: ModelsSection_module_css_default["addActions"],
2290
- children: [(0, react_jsx_runtime.jsxs)("button", {
2317
+ children: [configurable.length > 0 && (0, react_jsx_runtime.jsxs)("button", {
2291
2318
  type: "button",
2292
2319
  className: ModelsSection_module_css_default["addButton"],
2293
2320
  disabled: addable.length === 0 || !state.writable,
@@ -2301,7 +2328,7 @@ window.__ModuleLoader__.load({
2301
2328
  setEditing(targetOf(first));
2302
2329
  },
2303
2330
  children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 }), t("add")]
2304
- }), (0, react_jsx_runtime.jsxs)("button", {
2331
+ }), state.namespaces.has("llm-pi-ai") && (0, react_jsx_runtime.jsxs)("button", {
2305
2332
  type: "button",
2306
2333
  className: ModelsSection_module_css_default["addButton"],
2307
2334
  disabled: protocols.length === 0 || !state.writable,
@@ -2315,7 +2342,7 @@ window.__ModuleLoader__.load({
2315
2342
  }), (0, react_jsx_runtime.jsxs)("button", {
2316
2343
  type: "button",
2317
2344
  className: ModelsSection_module_css_default["addButton"],
2318
- disabled: !state.namespaces.has(CLAUDE_PROVIDER_SETTINGS_NS) || !state.writable,
2345
+ disabled: !state.namespaces.has("llm-pi-ai") || !state.namespaces.has(CLAUDE_PROVIDER_SETTINGS_NS) || !state.writable,
2319
2346
  onClick: () => {
2320
2347
  setSavedTarget(void 0);
2321
2348
  setAdding(false);
@@ -2894,6 +2921,7 @@ window.__ModuleLoader__.load({
2894
2921
  customApi: "API protocol",
2895
2922
  customApiUnset: "Not selected",
2896
2923
  customNeedsBaseUrl: "A custom provider needs a base URL.",
2924
+ customBaseUrlInvalid: "Enter a valid HTTP or HTTPS URL.",
2897
2925
  customNeedsModels: "A custom provider needs at least one model.",
2898
2926
  customBaseUrlPlaceholder: "https://gateway.example/v1",
2899
2927
  settingsPathUnresolvable: "unresolvable settings path",
@@ -3009,6 +3037,7 @@ window.__ModuleLoader__.load({
3009
3037
  customApi: "API 协议",
3010
3038
  customApiUnset: "未选择",
3011
3039
  customNeedsBaseUrl: "自定义提供方需要填写 API 地址。",
3040
+ customBaseUrlInvalid: "请输入有效的 HTTP 或 HTTPS 地址。",
3012
3041
  customNeedsModels: "自定义提供方至少需要一个模型。",
3013
3042
  customBaseUrlPlaceholder: "https://gateway.example/v1",
3014
3043
  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.4",
4
+ "description": "Custom Claude provider support for DeepSeek Harness 0.1.5-rc.2",
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.5-rc.2"
64
64
  }
65
65
  }