dsh-plugin-model-tuning 2.1.0 → 3.0.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/README.md +85 -234
- package/client.js +425 -1013
- package/cordis.patch.yml +10 -19
- package/index.js +20 -263
- package/package.json +6 -11
package/cordis.patch.yml
CHANGED
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
# dsh-plugin-model-tuning
|
|
1
|
+
# dsh-plugin-model-tuning v3 self-wiring (dsh.bundle.patch mechanism).
|
|
2
2
|
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# 2. 再 insert 本包(v2 起一个包承担:模型参数页 + 标题路由 + 绘图工具/面板)。
|
|
3
|
+
# v3 keeps only the drawing capability: the `generate_image` /
|
|
4
|
+
# `list_image_models` tools plus the `imageGeneration` Remote service behind the
|
|
5
|
+
# settings page. The per-model compatibility switches on the official Models
|
|
6
|
+
# page and the drawing page need no extra rows.
|
|
8
7
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
disabled: true
|
|
15
|
-
|
|
8
|
+
# The v2 patch disabled the shipped `session-title-llm` row and inserted this
|
|
9
|
+
# bundle as a replacement title provider. That is gone: the shipped row already
|
|
10
|
+
# supports a provider/model route plus budgets in its Config, so title routing
|
|
11
|
+
# is configured again in the profile's cordis.patch.yml (and the official
|
|
12
|
+
# "标题随对话更新" optional bundle can be used normally).
|
|
16
13
|
- insert:
|
|
17
14
|
- id: model-tuning
|
|
18
15
|
name: dsh-plugin-model-tuning
|
|
19
|
-
config:
|
|
20
|
-
targetWords: 5
|
|
21
|
-
targetCjkCharacters: 10
|
|
22
|
-
maxInputBytes: 4096
|
|
23
|
-
maxOutputTokens: 64
|
|
24
|
-
timeoutMs: 60000
|
package/index.js
CHANGED
|
@@ -1,34 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Host half of `dsh-plugin-model-tuning`
|
|
3
|
-
* `dsh-plugin-title-model` and `dsh-plugin-image-generation`).
|
|
2
|
+
* Host half of `dsh-plugin-model-tuning` v3.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* competing generator cannot coexist. Everything except the route is
|
|
13
|
-
* delegated to the public shared policy (`executeSessionTitleLlm`, or
|
|
14
|
-
* `generateSessionTitleWithLlm` before dsh 0.2.1) from
|
|
15
|
-
* `@deepseek-ai/dsh-session-title-llm`, resolved from the RUNNING
|
|
16
|
-
* deployment (see hostRequire) — never from this package's directory, which
|
|
17
|
-
* for a linked workspace package would risk a second copy of the host's
|
|
18
|
-
* shared module graph.
|
|
19
|
-
*
|
|
20
|
-
* 2. Image generation (ex dsh-plugin-image-generation): the `generate_image`
|
|
21
|
-
* and `list_image_models` tools plus the `imageGeneration` Remote service
|
|
22
|
-
* that the 直接绘图 panel drives. Transport lives in `./core.js`.
|
|
23
|
-
*
|
|
24
|
-
* 3. Nothing else: the settings surface (模型参数 / 用途 / 绘图 tabs) lives in
|
|
25
|
-
* the browser implementation exported from `./client`.
|
|
4
|
+
* v3 keeps exactly one capability here: image generation (the former
|
|
5
|
+
* `dsh-plugin-image-generation`). Session-title routing was removed because the
|
|
6
|
+
* host's own `@deepseek-ai/dsh-session-title-first-prompt-llm` row already
|
|
7
|
+
* supports a provider/model route plus budgets in its Config; configure it in
|
|
8
|
+
* the profile's `cordis.patch.yml`. The per-model compatibility switches and
|
|
9
|
+
* the catalog-route reasoning override need no host half: the browser half
|
|
10
|
+
* writes the provider's settings namespace directly.
|
|
26
11
|
*
|
|
27
12
|
* @module dsh-plugin-model-tuning
|
|
28
13
|
*/
|
|
29
14
|
import { randomUUID } from 'node:crypto'
|
|
30
|
-
import { pathToFileURL } from 'node:url'
|
|
31
|
-
import { createRequire } from 'node:module'
|
|
32
15
|
import z from '@deepseek-ai/schemastery'
|
|
33
16
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
34
17
|
import { TypertRemoteService, RemoteError } from '@deepseek-ai/dsh-typert-protocol'
|
|
@@ -37,27 +20,12 @@ import { discoverImageModels, generateImages, resolveRequest, validateConfig } f
|
|
|
37
20
|
export const name = 'dsh-plugin-model-tuning'
|
|
38
21
|
|
|
39
22
|
/** Services this plugin reads. */
|
|
40
|
-
export const inject = ['tools', 'attachments'
|
|
23
|
+
export const inject = ['tools', 'attachments']
|
|
41
24
|
|
|
42
|
-
/** Settings namespace owned by this plugin
|
|
25
|
+
/** Settings namespace owned by this plugin. */
|
|
43
26
|
export const NS = 'model-tuning'
|
|
44
27
|
|
|
45
|
-
/**
|
|
46
|
-
* Provider identity recorded with generated titles. Kept equal to the row this
|
|
47
|
-
* plugin replaces so durable logs and the folded title source stay unchanged.
|
|
48
|
-
*/
|
|
49
|
-
const TITLE_PROVIDER_ID = 'session-title-llm'
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Unified Config: image-generation fields (models / defaultModel) plus the
|
|
53
|
-
* title route fields (titleMode / titleProvider / titleModel), all volatile.
|
|
54
|
-
*
|
|
55
|
-
* The title budget fields mirror the `session-title-llm` config in
|
|
56
|
-
* `@deepseek-ai/dsh-base` so that removing this bundle's `config:` block
|
|
57
|
-
* cannot change title behaviour. Title fields are prefixed `title` so the
|
|
58
|
-
* pre-merge `title-model` section could be migrated mechanically; the former
|
|
59
|
-
* `image-generation` section's `models`/`defaultModel` keys are kept verbatim.
|
|
60
|
-
*/
|
|
28
|
+
/** One drawing model. `source` is legacy provenance kept so old linked entries still parse. */
|
|
61
29
|
const imageModelSchema = z.object({
|
|
62
30
|
id: z.string().required(), name: z.string(), model: z.string().required(),
|
|
63
31
|
api: z.union(['openai-images']).default('openai-images'),
|
|
@@ -72,219 +40,16 @@ const imageModelSchema = z.object({
|
|
|
72
40
|
output_format: z.string(), response_format: z.string(), style: z.string(),
|
|
73
41
|
})
|
|
74
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Config: drawing models only. Removed v2 title fields (`titleMode` etc.) are
|
|
45
|
+
* tolerated by the loader's schema and ignored, so an existing profile keeps
|
|
46
|
+
* loading without a migration step.
|
|
47
|
+
*/
|
|
75
48
|
export const Config = z.object({
|
|
76
|
-
// ── 绘图(ex image-generation;键名原样保留,旧数据可直接搬入) ──
|
|
77
49
|
models: z.array(imageModelSchema).default([]).volatile(),
|
|
78
50
|
defaultModel: z.string().volatile(),
|
|
79
|
-
// ── 标题生成(ex title-model;title 前缀迁移自 mode/provider/model) ──
|
|
80
|
-
titleMode: z.union([z.const('inherit'), z.const('custom')]).default('inherit').volatile(),
|
|
81
|
-
titleProvider: z.string().volatile(),
|
|
82
|
-
titleModel: z.string().volatile(),
|
|
83
|
-
// ── 标题请求预算(用户可在「用途」页改;默认值与 dsh-base 的 session-title-llm 行一致) ──
|
|
84
|
-
targetWords: z.number().step(1).min(1).default(5).volatile(),
|
|
85
|
-
targetCjkCharacters: z.number().step(1).min(1).default(10).volatile(),
|
|
86
|
-
maxInputBytes: z.number().step(1).min(1).default(4096).volatile(),
|
|
87
|
-
maxOutputTokens: z.number().step(1).min(1).default(64).volatile(),
|
|
88
|
-
timeoutMs: z.number().step(1).min(1).default(60000).volatile(),
|
|
89
51
|
})
|
|
90
52
|
|
|
91
|
-
/** Reject a custom title mode that cannot name both halves of a route. */
|
|
92
|
-
export function validateTitleModel(value) {
|
|
93
|
-
const provider = value?.titleProvider
|
|
94
|
-
const model = value?.titleModel
|
|
95
|
-
const hasProvider = provider !== undefined && provider !== null && provider !== ''
|
|
96
|
-
const hasModel = model !== undefined && model !== null && model !== ''
|
|
97
|
-
if (hasProvider !== hasModel) throw new Error('model-tuning: titleProvider 与 titleModel 必须同时填写或同时留空')
|
|
98
|
-
if (value?.titleMode === 'custom' && !hasProvider) throw new Error('model-tuning: titleMode 为 custom 时必须同时选择 provider 与 model')
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Resolve the exact route recorded for one generation request.
|
|
103
|
-
* @param settings - resolved title fields (`titleMode`/`titleProvider`/`titleModel`).
|
|
104
|
-
* @param request - service-owned request carrying the session's logged route.
|
|
105
|
-
* @returns the provider/model pair to dispatch.
|
|
106
|
-
*/
|
|
107
|
-
export function resolveTitleRoute(settings, request) {
|
|
108
|
-
validateTitleModel(settings)
|
|
109
|
-
if (settings?.titleMode === 'custom') {
|
|
110
|
-
return { provider: settings.titleProvider, model: settings.titleModel }
|
|
111
|
-
}
|
|
112
|
-
if (request?.route === undefined) {
|
|
113
|
-
throw new Error('session-title-llm: no logged request route is available; configure provider and model together')
|
|
114
|
-
}
|
|
115
|
-
return { provider: request.route.provider, model: request.route.model }
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** The shared title policy module, loaded once per process. */
|
|
119
|
-
const HELPER_PACKAGE = '@deepseek-ai/dsh-session-title-llm'
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Resolve the shared title policy.
|
|
123
|
-
*
|
|
124
|
-
* A plain `import '@deepseek-ai/dsh-session-title-llm'` would have to be
|
|
125
|
-
* resolvable from THIS package's directory, which for a linked workspace package
|
|
126
|
-
* means risking another installation of the host's shared module graph. The
|
|
127
|
-
* helper therefore resolves from the deployment that loads this plugin.
|
|
128
|
-
*/
|
|
129
|
-
function hostRequire() {
|
|
130
|
-
const anchors = [process.argv[1], process.execPath, import.meta.url]
|
|
131
|
-
for (const anchor of anchors) {
|
|
132
|
-
if (anchor === undefined) continue
|
|
133
|
-
try {
|
|
134
|
-
const require = createRequire(anchor)
|
|
135
|
-
require.resolve(HELPER_PACKAGE)
|
|
136
|
-
return require
|
|
137
|
-
} catch {
|
|
138
|
-
// Try the next anchor: a test or tool process may not sit inside the deployment.
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return undefined
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/** Title-service package that owns `normalizeSessionTitle`; resolved next to the helper. */
|
|
145
|
-
const TITLE_SERVICE_PACKAGE = '@deepseek-ai/dsh-session-title'
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Language-aware system instruction, mirroring the shipped first-prompt
|
|
149
|
-
* provider (dsh ≥ 0.2.1 hands prompt ownership to each provider).
|
|
150
|
-
* @param budget - the live title budget.
|
|
151
|
-
* @returns the system prompt.
|
|
152
|
-
*/
|
|
153
|
-
export function titleSystemPrompt(budget) {
|
|
154
|
-
return [
|
|
155
|
-
'Create a concise title for an AI coding-assistant session from the supplied human messages.',
|
|
156
|
-
'Return only the title on one line, **in plain text of natural language**, with no quotes, prefix, explanation, Markdown, XML, or terminal control codes. No code is allowed.',
|
|
157
|
-
'Use the language of the messages.',
|
|
158
|
-
`Aim for about ${budget.targetWords} words in non-CJK languages or ${budget.targetCjkCharacters} CJK characters.`,
|
|
159
|
-
'If the messages give little to name, still return a short best-effort title, such as Greeting, instead of explaining.',
|
|
160
|
-
].join('\n')
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** Asterisk emphasis wrapping a whole line, such as `**Title**`. */
|
|
164
|
-
const EMPHASIS_WRAPPER = /^(?<marker>\*{1,3})(?<inner>\S(?:.*\S)?)\k<marker>$/u
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Take the title from model output: the first non-empty line, without
|
|
168
|
-
* asterisk emphasis wrapping that whole line (same rule as the shipped provider).
|
|
169
|
-
* @param text - the joined text blocks.
|
|
170
|
-
* @returns the raw title line.
|
|
171
|
-
*/
|
|
172
|
-
export function titleFromOutput(text) {
|
|
173
|
-
const line = text.split(/\r?\n/u).map(item => item.trim()).find(item => item.length > 0) ?? ''
|
|
174
|
-
const groups = EMPHASIS_WRAPPER.exec(line)?.groups
|
|
175
|
-
const marker = groups?.marker
|
|
176
|
-
const inner = groups?.inner
|
|
177
|
-
return marker === undefined || inner === undefined || inner.includes(marker) ? line : inner
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Adapt the prepared-request API (`executeSessionTitleLlm`, dsh ≥ 0.2.1) to the
|
|
182
|
-
* one-call shape this plugin drives.
|
|
183
|
-
* @param execute - the host's `executeSessionTitleLlm`.
|
|
184
|
-
* @param normalize - the host's `normalizeSessionTitle`.
|
|
185
|
-
* @returns `(ctx, budget, request, selected, providerId) => { title, messageSeqs, model }`.
|
|
186
|
-
*/
|
|
187
|
-
export function preparedTitleGenerator(execute, normalize) {
|
|
188
|
-
return async (ctx, budget, request, selected, providerId) => {
|
|
189
|
-
const config = { maxInputBytes: budget.maxInputBytes, maxOutputTokens: budget.maxOutputTokens, timeoutMs: budget.timeoutMs }
|
|
190
|
-
const messageSeqs = selected.map(message => message.seq)
|
|
191
|
-
const response = await execute(ctx, config, request, providerId, {
|
|
192
|
-
system: titleSystemPrompt(budget),
|
|
193
|
-
input: `Generate the session title from this JSON array of human messages:\n${JSON.stringify(selected)}`,
|
|
194
|
-
messageSeqs,
|
|
195
|
-
// A title needs no deliberation: take the route's least effort.
|
|
196
|
-
selectReasoningEffort: model => model.reasoning?.efforts?.[0]?.id,
|
|
197
|
-
})
|
|
198
|
-
if (response.finish.kind === 'tool-calls' || response.blocks.some(block => block.type === 'tool-call')) {
|
|
199
|
-
throw new Error('session-title-llm: title output must contain text only')
|
|
200
|
-
}
|
|
201
|
-
if (response.finish.kind === 'max-tokens') {
|
|
202
|
-
throw new Error('session-title-llm: title output reached maxOutputTokens')
|
|
203
|
-
}
|
|
204
|
-
const text = response.blocks.filter(block => block.type === 'text').map(block => block.text).join(' ')
|
|
205
|
-
const title = normalize(titleFromOutput(text), Number.MAX_SAFE_INTEGER)
|
|
206
|
-
if (title.length === 0) throw new Error('session-title-llm: title model produced no text')
|
|
207
|
-
return { title, messageSeqs, model: response.model }
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
let helperPromise
|
|
212
|
-
/**
|
|
213
|
-
* Load a title generator from the running deployment: the prepared-request
|
|
214
|
-
* API when the host has it (≥ 0.2.1), else the one-call
|
|
215
|
-
* `generateSessionTitleWithLlm` (0.1.7 – 0.2.0).
|
|
216
|
-
*/
|
|
217
|
-
function loadTitleHelper() {
|
|
218
|
-
helperPromise ??= (async () => {
|
|
219
|
-
const require = hostRequire()
|
|
220
|
-
if (require === undefined) {
|
|
221
|
-
throw new Error(
|
|
222
|
-
`model-tuning: 无法从宿主解析 ${HELPER_PACKAGE};本插件必须与提供该包的部署一起运行。`,
|
|
223
|
-
)
|
|
224
|
-
}
|
|
225
|
-
const helperPath = require.resolve(HELPER_PACKAGE)
|
|
226
|
-
const loaded = await import(pathToFileURL(helperPath).href)
|
|
227
|
-
if (typeof loaded.executeSessionTitleLlm === 'function') {
|
|
228
|
-
const service = await import(pathToFileURL(createRequire(helperPath).resolve(TITLE_SERVICE_PACKAGE)).href)
|
|
229
|
-
if (typeof service.normalizeSessionTitle !== 'function') {
|
|
230
|
-
throw new Error(`model-tuning: ${TITLE_SERVICE_PACKAGE} 未导出 normalizeSessionTitle`)
|
|
231
|
-
}
|
|
232
|
-
return preparedTitleGenerator(loaded.executeSessionTitleLlm, service.normalizeSessionTitle)
|
|
233
|
-
}
|
|
234
|
-
if (typeof loaded.generateSessionTitleWithLlm === 'function') return loaded.generateSessionTitleWithLlm
|
|
235
|
-
throw new Error(`model-tuning: ${HELPER_PACKAGE} 既没有 executeSessionTitleLlm 也没有 generateSessionTitleWithLlm`)
|
|
236
|
-
})()
|
|
237
|
-
return helperPromise
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Read the live title budget.
|
|
242
|
-
*
|
|
243
|
-
* Every field is user-editable from the 用途 tab, so each generation re-reads
|
|
244
|
-
* them instead of freezing the apply-time values. A reasoning model that only
|
|
245
|
-
* starts answering after a long think needs a larger `maxOutputTokens` here;
|
|
246
|
-
* that is the user's call, not a constant in this file.
|
|
247
|
-
* @param config - the plugin's live Config.
|
|
248
|
-
* @returns the prompt/byte/token/timeout policy for one title request.
|
|
249
|
-
*/
|
|
250
|
-
export function titleBudgetOf(config) {
|
|
251
|
-
const policy = {
|
|
252
|
-
targetWords: config.targetWords.get(),
|
|
253
|
-
targetCjkCharacters: config.targetCjkCharacters.get(),
|
|
254
|
-
maxInputBytes: config.maxInputBytes.get(),
|
|
255
|
-
maxOutputTokens: config.maxOutputTokens.get(),
|
|
256
|
-
timeoutMs: config.timeoutMs.get(),
|
|
257
|
-
}
|
|
258
|
-
for (const [key, value] of Object.entries(policy)) {
|
|
259
|
-
if (!Number.isInteger(value) || value < 1) throw new Error(`model-tuning: ${key} 必须是正整数`)
|
|
260
|
-
}
|
|
261
|
-
return policy
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Register the settings-owned title provider.
|
|
266
|
-
* @param ctx - context exposing session-title and LLM services.
|
|
267
|
-
* @param config - the live Config (route and budget are re-read per generation).
|
|
268
|
-
*/
|
|
269
|
-
export async function registerTitleProvider(ctx, config) {
|
|
270
|
-
const generateTitle = await loadTitleHelper()
|
|
271
|
-
validateTitleModel({ titleMode: config.titleMode.get(), titleProvider: config.titleProvider.get(), titleModel: config.titleModel.get() })
|
|
272
|
-
titleBudgetOf(config)
|
|
273
|
-
ctx.sessionTitle.register({
|
|
274
|
-
id: TITLE_PROVIDER_ID,
|
|
275
|
-
automatic: 'first-prompt',
|
|
276
|
-
async generate(request) {
|
|
277
|
-
const route = resolveTitleRoute({
|
|
278
|
-
titleMode: config.titleMode.get(), titleProvider: config.titleProvider.get(), titleModel: config.titleModel.get(),
|
|
279
|
-
}, request)
|
|
280
|
-
const selected = request.messages.slice(0, 1)
|
|
281
|
-
return await generateTitle(ctx, titleBudgetOf(config), { ...request, route }, selected, TITLE_PROVIDER_ID)
|
|
282
|
-
},
|
|
283
|
-
})
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// ── 绘图:工具 + Remote 服务(ex dsh-plugin-image-generation/index.js) ──
|
|
287
|
-
|
|
288
53
|
const IMAGE_PARAMETERS = {
|
|
289
54
|
model: { type: 'string', description: 'Configuration ID from list_image_models, not the upstream model ID. Omit to use the configured default.' },
|
|
290
55
|
prompt: { type: 'string', required: true, description: 'Full self-contained description of the image to generate. Chat history is not sent.' },
|
|
@@ -434,18 +199,10 @@ export function registerImageTools(ctx, config) {
|
|
|
434
199
|
}
|
|
435
200
|
|
|
436
201
|
/**
|
|
437
|
-
* Register
|
|
438
|
-
* @param ctx - context exposing tools, attachments
|
|
439
|
-
* @param config - the
|
|
202
|
+
* Register the drawing tools and their Remote service.
|
|
203
|
+
* @param ctx - context exposing tools, attachments and llm.
|
|
204
|
+
* @param config - the drawing Config.
|
|
440
205
|
*/
|
|
441
|
-
export
|
|
442
|
-
// The title route leans on a host helper whose API has changed between
|
|
443
|
-
// releases. If it breaks again, lose only title routing — never the image
|
|
444
|
-
// tools and settings page that ride on the same row.
|
|
445
|
-
try {
|
|
446
|
-
await registerTitleProvider(ctx, config)
|
|
447
|
-
} catch (error) {
|
|
448
|
-
ctx.logger?.warn?.(`model-tuning: 标题路由未启用(${error instanceof Error ? error.message : String(error)});绘图与设置页照常工作`)
|
|
449
|
-
}
|
|
206
|
+
export function apply(ctx, config) {
|
|
450
207
|
registerImageTools(ctx, config)
|
|
451
208
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-model-tuning",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"engines": { "dsh": ">=0.2.0-rc.2 <0.3.0-0" },
|
|
4
5
|
"license": "MIT",
|
|
5
|
-
"keywords": ["dsh-plugin", "deepseek-harness", "dsh", "model", "settings", "reasoning", "
|
|
6
|
+
"keywords": ["dsh-plugin", "deepseek-harness", "dsh", "model", "settings", "reasoning", "compat", "image-generation"],
|
|
6
7
|
"publishConfig": { "registry": "https://registry.npmjs.org" },
|
|
7
8
|
"repository": { "type": "git", "url": "git+https://github.com/tofu-zyc/dsh-plugin-tofu-box.git", "directory": "dsh-plugin-model-tuning" },
|
|
8
9
|
"bugs": { "url": "https://github.com/tofu-zyc/dsh-plugin-tofu-box/issues" },
|
|
9
10
|
"homepage": "https://github.com/tofu-zyc/dsh-plugin-tofu-box/tree/main/dsh-plugin-model-tuning",
|
|
10
|
-
"description": "
|
|
11
|
+
"description": "只补官方没有的两块:①「设置 → 模型」卡片里的兼容开关与内置目录路由推理覆盖(官方 Models 页没有的 compat.supportsDeveloperRole / compat.forceAdaptiveThinking / modelOverrides.reasoningEfforts);②「设置 → 绘图」页(绘图模型配置 + generate_image / list_image_models 工具 + 直接绘图面板)。v3 起标题生成路由交还官方 session-title 行,模型参数页交还官方 Models 页。",
|
|
11
12
|
"type": "module",
|
|
12
13
|
"main": "index.js",
|
|
13
14
|
"exports": {
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
"platform": "web",
|
|
25
26
|
"inject": [
|
|
26
27
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
27
|
-
"@deepseek-ai/dsh-client-ui-
|
|
28
|
+
"@deepseek-ai/dsh-client-ui-settings-models",
|
|
28
29
|
"@deepseek-ai/dsh-api-remotes"
|
|
29
30
|
]
|
|
30
31
|
}
|
|
@@ -32,13 +33,7 @@
|
|
|
32
33
|
"peerDependencies": {
|
|
33
34
|
"@deepseek-ai/dsh-tools": ">=0.1.6-alpha.1",
|
|
34
35
|
"@deepseek-ai/dsh-typert-protocol": ">=0.1.6-alpha.1",
|
|
35
|
-
"@deepseek-ai/schemastery": "^3.18.2"
|
|
36
|
-
"@deepseek-ai/dsh-session-title-llm": ">=0.1.6-alpha.2"
|
|
37
|
-
},
|
|
38
|
-
"peerDependenciesMeta": {
|
|
39
|
-
"@deepseek-ai/dsh-session-title-llm": {
|
|
40
|
-
"optional": true
|
|
41
|
-
}
|
|
36
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
42
37
|
},
|
|
43
38
|
"scripts": {
|
|
44
39
|
"test": "node --test tests/*.test.mjs"
|