@mofeng2223/dsh-claude-provider 0.3.1 → 0.4.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mofeng2223/dsh-claude-provider",
3
- "version": "0.3.1",
4
- "description": "Custom Claude provider support for DeepSeek Harness",
3
+ "version": "0.4.1",
4
+ "description": "Custom Claude provider support for DeepSeek Harness 0.1.2-alpha",
5
5
  "author": "mofeng2223",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "type": "module",
26
26
  "dependencies": {
27
- "@deepseek-ai/schemastery": "3.18.1"
27
+ "@deepseek-ai/schemastery": "^3.18.2"
28
28
  },
29
29
  "exports": {
30
30
  ".": "./src/index.js",
@@ -32,7 +32,7 @@
32
32
  "./package.json": "./package.json"
33
33
  },
34
34
  "files": [
35
- "src",
35
+ "src/index.js",
36
36
  "lib/client.js",
37
37
  "cordis.patch.yml",
38
38
  "README.md",
@@ -46,9 +46,6 @@
46
46
  "engines": {
47
47
  "node": ">=22.19"
48
48
  },
49
- "devDependencies": {
50
- "@deepseek-ai/dsh-client-ui-settings-models": "0.1.1-rc.1"
51
- },
52
49
  "dsh": {
53
50
  "bundle": {
54
51
  "patch": "./cordis.patch.yml"
@@ -56,11 +53,13 @@
56
53
  "client": {
57
54
  "platform": "web",
58
55
  "inject": [
59
- "@deepseek-ai/dsh-client-runtime",
60
56
  "@deepseek-ai/dsh-client-ui-settings",
61
57
  "@deepseek-ai/dsh-client-locale",
62
58
  "@deepseek-ai/dsh-api-remotes"
63
59
  ]
64
60
  }
61
+ },
62
+ "devDependencies": {
63
+ "@deepseek-ai/dsh-client-ui-settings-models": "0.1.2-alpha.5"
65
64
  }
66
65
  }
package/src/index.js CHANGED
@@ -5,7 +5,6 @@ export const inject = ['llm', 'settings']
5
5
 
6
6
  export const CLAUDE_PROVIDER_TYPE = 'claude-adaptive'
7
7
  export const CLAUDE_PROVIDER_SETTINGS_NS = 'dsh-claude-provider'
8
- export const CLAUDE_PROVIDER_DIRECTORY_SENTINEL = 'dsh-claude-provider-type'
9
8
 
10
9
  const ProviderTypeSettings = z.object({
11
10
  providerTypes: z.dict(z.const(CLAUDE_PROVIDER_TYPE)).default({}),
@@ -17,6 +16,19 @@ const PI_AI_SETTINGS_NS = 'llm-pi-ai'
17
16
  const MAX_DISCOVERY_RESPONSE_BYTES = 4 * 1024 * 1024
18
17
  const MAX_DISCOVERY_PAGES = 100
19
18
 
19
+ /** Recorded capacities and thinking presets for known Claude model ids. */
20
+ export const CLAUDE_KNOWN_MODELS = Object.freeze({
21
+ 'claude-fable-5': Object.freeze({ contextWindow: 1000000, maxTokens: 128000, preset: 'five' }),
22
+ 'claude-haiku-4-5-20251001': Object.freeze({ contextWindow: 200000, maxTokens: 64000, preset: 'toggle' }),
23
+ 'claude-haiku-4-5': Object.freeze({ contextWindow: 200000, maxTokens: 64000, preset: 'toggle' }),
24
+ 'claude-opus-4-6': Object.freeze({ contextWindow: 1000000, maxTokens: 128000, preset: 'four' }),
25
+ 'claude-opus-4-7': Object.freeze({ contextWindow: 1000000, maxTokens: 128000, preset: 'five' }),
26
+ 'claude-opus-4-8': Object.freeze({ contextWindow: 1000000, maxTokens: 128000, preset: 'five' }),
27
+ 'claude-opus-5': Object.freeze({ contextWindow: 1000000, maxTokens: 128000, preset: 'five' }),
28
+ 'claude-sonnet-4-6': Object.freeze({ contextWindow: 1000000, maxTokens: 64000, preset: 'four' }),
29
+ 'claude-sonnet-5': Object.freeze({ contextWindow: 1000000, maxTokens: 128000, preset: 'five' }),
30
+ })
31
+
20
32
  function requireNonEmptyString(value, field) {
21
33
  if (typeof value !== 'string' || value.length === 0) {
22
34
  throw new Error(`claude-provider: ${field} must be a non-empty string`)
@@ -117,6 +129,13 @@ export function readAnthropicModelPage(body) {
117
129
  }
118
130
  }
119
131
 
132
+ /** Fill a discovered row's capacities from the recorded Claude model table. */
133
+ export function withKnownModelMetadata(model) {
134
+ const known = CLAUDE_KNOWN_MODELS[model?.id]
135
+ if (known === undefined) return model
136
+ return { ...model, contextWindow: known.contextWindow, maxTokens: known.maxTokens }
137
+ }
138
+
120
139
  function discoveryHeaders(apiKey) {
121
140
  const value = requireNonEmptyString(apiKey, 'apiKey').trim()
122
141
  if (value.length === 0) throw new Error('Claude 模型目录:请先填写 API 密钥')
@@ -174,7 +193,7 @@ export async function discoverAnthropicModels({ baseURL, apiKey, signal, fetchIm
174
193
  for (const model of parsed.models) {
175
194
  if (seen.has(model.id)) continue
176
195
  seen.add(model.id)
177
- models.push(model)
196
+ models.push(withKnownModelMetadata(model))
178
197
  }
179
198
  if (!parsed.hasMore) return models
180
199
  if (parsed.lastId === undefined || parsed.lastId === afterId) {
@@ -204,27 +223,34 @@ async function discoveryApiKey(ctx, request) {
204
223
  return value
205
224
  }
206
225
 
226
+ /** Whether an explicitly registered provider belongs to this plugin's Claude type. */
227
+ export function isClaudeProviderType(settings, provider) {
228
+ if (typeof provider !== 'string' || provider.length === 0) return false
229
+ return settings?.providerTypes?.[provider] === CLAUDE_PROVIDER_TYPE
230
+ }
231
+
207
232
  function installClaudeModelDiscovery(ctx) {
208
233
  const llm = ctx.llm
209
234
  const upstream = llm.discoverModels
210
- const wrapped = async function (settingsNs, request) {
211
- if (settingsNs !== PI_AI_SETTINGS_NS || request.api !== CLAUDE_DISCOVERY_API) {
212
- return upstream.call(this, settingsNs, request)
235
+ // DSH 0.1.2-alpha moved caller cancellation to a third positional
236
+ // parameter; `request.signal` no longer exists. Forward it verbatim.
237
+ // Only the plugin's own Claude surfaces send CLAUDE_DISCOVERY_API, so every
238
+ // other provider — generic anthropic-messages routes included — keeps the
239
+ // stock discovery behavior.
240
+ const wrapped = async function (settingsNs, request, signal) {
241
+ if (settingsNs !== PI_AI_SETTINGS_NS || request?.api !== CLAUDE_DISCOVERY_API) {
242
+ return upstream.call(this, settingsNs, request, signal)
213
243
  }
214
244
  // The built-in Anthropic route already has pi-ai's catalog and should keep
215
245
  // using it. The plugin extension is only for hand-declared Claude routes.
216
246
  if (request.provider === 'anthropic') {
217
- return upstream.call(this, settingsNs, { ...request, api: 'anthropic-messages' })
247
+ return upstream.call(this, settingsNs, { ...request, api: 'anthropic-messages' }, signal)
218
248
  }
219
249
  if (typeof request.baseURL !== 'string' || request.baseURL.length === 0) {
220
250
  throw new Error('Claude 模型目录:请先填写 API 地址')
221
251
  }
222
252
  const apiKey = await discoveryApiKey(ctx, request)
223
- return discoverAnthropicModels({
224
- baseURL: request.baseURL,
225
- apiKey,
226
- signal: request.signal,
227
- })
253
+ return discoverAnthropicModels({ baseURL: request.baseURL, apiKey, signal })
228
254
  }
229
255
  llm.discoverModels = wrapped
230
256
  ctx.effect(() => () => {
@@ -232,23 +258,11 @@ function installClaudeModelDiscovery(ctx) {
232
258
  })
233
259
  }
234
260
 
235
- /** Whether an explicitly registered provider belongs to this plugin's Claude type. */
236
- export function isClaudeProviderType(settings, provider) {
237
- if (typeof provider !== 'string' || provider.length === 0) return false
238
- return settings?.providerTypes?.[provider] === CLAUDE_PROVIDER_TYPE
239
- }
240
-
241
261
  export function apply(ctx) {
242
262
  ctx.settings.register(
243
263
  CLAUDE_PROVIDER_SETTINGS_NS,
244
264
  ProviderTypeSettings,
245
265
  { base: { providerTypes: {} } },
246
266
  )
247
- ctx.llm.registerConfigurableProviders([{
248
- provider: CLAUDE_PROVIDER_DIRECTORY_SENTINEL,
249
- displayName: 'Claude Provider Type',
250
- settingsNs: CLAUDE_PROVIDER_SETTINGS_NS,
251
- settingsPath: ['providerTypes'],
252
- }])
253
267
  installClaudeModelDiscovery(ctx)
254
268
  }