@jcy2387/dsh-models-input-modalities 0.1.1 → 0.1.2
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 +47 -10
- package/README.zh.md +49 -14
- package/cordis.patch.yml +4 -3
- package/lib/client.cjs +392 -62
- package/lib/client.cjs.map +1 -1
- package/lib/types/client/ModelCapabilityCard.d.ts +34 -0
- package/lib/types/client/controller.d.ts +7 -7
- package/lib/types/client/index.d.ts +9 -8
- package/lib/types/client/locales.d.ts +13 -3
- package/lib/types/image-input.d.ts +1 -9
- package/lib/types/model-row.d.ts +10 -0
- package/lib/types/reasoning-efforts.d.ts +108 -0
- package/package.json +1 -1
- package/lib/types/client/ImageInputCard.d.ts +0 -32
package/lib/client.cjs
CHANGED
|
@@ -24,7 +24,7 @@ window.__ModuleLoader__.load({
|
|
|
24
24
|
return Array.isArray(value) ? value.map((entry) => typeof entry === "object" && entry !== null && !Array.isArray(entry) ? entry : {}) : [];
|
|
25
25
|
}
|
|
26
26
|
/** Joins the settings Remote's document view and fenced writes for one card. */
|
|
27
|
-
var
|
|
27
|
+
var ModelCapabilityController = class {
|
|
28
28
|
ctx;
|
|
29
29
|
/** The cards waiting to hear that this namespace's stored section changed. */
|
|
30
30
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -148,6 +148,8 @@ window.__ModuleLoader__.load({
|
|
|
148
148
|
function parseImageInputChoice(value) {
|
|
149
149
|
return value === "inherit" || value === "text" || value === "image" ? value : void 0;
|
|
150
150
|
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/model-row.ts
|
|
151
153
|
/**
|
|
152
154
|
* The row's model id for labels.
|
|
153
155
|
* @param row - one stored model row.
|
|
@@ -159,8 +161,197 @@ window.__ModuleLoader__.load({
|
|
|
159
161
|
return typeof id === "string" && id.length > 0 ? id : `#${String(index + 1)}`;
|
|
160
162
|
}
|
|
161
163
|
//#endregion
|
|
164
|
+
//#region src/reasoning-efforts.ts
|
|
165
|
+
/** Every level a row may declare, in escalation order — the adapter's own key set. */
|
|
166
|
+
const THINKING_LEVELS = [
|
|
167
|
+
"off",
|
|
168
|
+
"minimal",
|
|
169
|
+
"low",
|
|
170
|
+
"medium",
|
|
171
|
+
"high",
|
|
172
|
+
"xhigh",
|
|
173
|
+
"max"
|
|
174
|
+
];
|
|
175
|
+
/**
|
|
176
|
+
* The spelling a newly offered level starts from: its own name, except for
|
|
177
|
+
* `off`, whose absence is the spelling most providers read as "do not think".
|
|
178
|
+
* @param level - the level being offered.
|
|
179
|
+
* @returns its default wire spelling.
|
|
180
|
+
*/
|
|
181
|
+
function defaultWire(level) {
|
|
182
|
+
return level === "off" ? "" : level;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* A level set offering exactly `offered`, each at its default spelling.
|
|
186
|
+
* @param offered - the levels to declare.
|
|
187
|
+
* @returns the seven level drafts.
|
|
188
|
+
*/
|
|
189
|
+
function declaring(offered) {
|
|
190
|
+
const drafts = {};
|
|
191
|
+
for (const level of THINKING_LEVELS) {
|
|
192
|
+
const on = offered.includes(level);
|
|
193
|
+
drafts[level] = {
|
|
194
|
+
offered: on,
|
|
195
|
+
wire: on ? defaultWire(level) : ""
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return drafts;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The levels a row with no dict of its own starts from when it is switched to a
|
|
202
|
+
* declared set: the three efforts an OpenAI-compatible gateway is most likely
|
|
203
|
+
* to serve, each spelled as its own name. `off` is deliberately left unticked:
|
|
204
|
+
* on the plain `reasoning_effort` wire an empty `off` is the very same request
|
|
205
|
+
* as naming no effort at all, so pre-offering it would promise a "stop
|
|
206
|
+
* thinking" choice the endpoint may not honour — the author ticks it, and
|
|
207
|
+
* spells it, once their endpoint says how.
|
|
208
|
+
*/
|
|
209
|
+
const DEFAULT_LEVELS = declaring([
|
|
210
|
+
"low",
|
|
211
|
+
"medium",
|
|
212
|
+
"high"
|
|
213
|
+
]);
|
|
214
|
+
/**
|
|
215
|
+
* The choice a row's stored `reasoningEfforts` displays. Anything that is not
|
|
216
|
+
* `false` and not a plain object states no claim this card understands, and
|
|
217
|
+
* reads as the inheritance it leaves in place; an empty object reads as a
|
|
218
|
+
* declared set offering nothing, which the validator then names.
|
|
219
|
+
* @param row - one stored model row.
|
|
220
|
+
* @returns the choice the row's select shows.
|
|
221
|
+
*/
|
|
222
|
+
function reasoningChoice(row) {
|
|
223
|
+
const value = row["reasoningEfforts"];
|
|
224
|
+
if (value === false) return "none";
|
|
225
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) return "custom";
|
|
226
|
+
return "inherit";
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* The row's declared levels as editor state. A level the dict omits is not
|
|
230
|
+
* offered; one it carries is, with its wire spelling — an empty value, which is
|
|
231
|
+
* what a valueless `off:` stores as, and a value of a type the schema refuses
|
|
232
|
+
* both read as no spelling yet. A row declaring nothing shows the defaults a
|
|
233
|
+
* fresh declaration starts from.
|
|
234
|
+
* @param row - one stored model row.
|
|
235
|
+
* @returns the seven level drafts.
|
|
236
|
+
*/
|
|
237
|
+
function reasoningLevels(row) {
|
|
238
|
+
const value = row["reasoningEfforts"];
|
|
239
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return DEFAULT_LEVELS;
|
|
240
|
+
const stored = value;
|
|
241
|
+
const drafts = {};
|
|
242
|
+
for (const level of THINKING_LEVELS) {
|
|
243
|
+
if (!(level in stored)) {
|
|
244
|
+
drafts[level] = {
|
|
245
|
+
offered: false,
|
|
246
|
+
wire: ""
|
|
247
|
+
};
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
const wire = stored[level];
|
|
251
|
+
drafts[level] = {
|
|
252
|
+
offered: true,
|
|
253
|
+
wire: typeof wire === "string" ? wire : ""
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return drafts;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* The row with one reasoning choice applied: `inherit` removes the field,
|
|
260
|
+
* `none` stores `false`, and `custom` stores exactly the levels offered — in
|
|
261
|
+
* escalation order, a valueless `off` as `null`, spellings trimmed so a stray
|
|
262
|
+
* space cannot reach the wire. Every other field, including ones this card
|
|
263
|
+
* never shows, survives.
|
|
264
|
+
* @param row - the row to patch.
|
|
265
|
+
* @param choice - the selected state.
|
|
266
|
+
* @param levels - the editor's level drafts; read only for `custom`.
|
|
267
|
+
* @returns a new row carrying the choice.
|
|
268
|
+
*/
|
|
269
|
+
function withReasoning(row, choice, levels) {
|
|
270
|
+
const next = { ...row };
|
|
271
|
+
delete next["reasoningEfforts"];
|
|
272
|
+
if (choice === "none") {
|
|
273
|
+
next["reasoningEfforts"] = false;
|
|
274
|
+
return next;
|
|
275
|
+
}
|
|
276
|
+
if (choice !== "custom") return next;
|
|
277
|
+
const declared = {};
|
|
278
|
+
for (const level of THINKING_LEVELS) {
|
|
279
|
+
const draft = levels[level];
|
|
280
|
+
if (!draft.offered) continue;
|
|
281
|
+
const wire = draft.wire.trim();
|
|
282
|
+
declared[level] = wire.length === 0 ? null : wire;
|
|
283
|
+
}
|
|
284
|
+
next["reasoningEfforts"] = declared;
|
|
285
|
+
return next;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* The level set with one level offered or withdrawn. Offering a level always
|
|
289
|
+
* starts its spelling from the default, so a tick is never a blank the save
|
|
290
|
+
* then refuses, and what a withdrawn level carried is not what a reticked one
|
|
291
|
+
* silently revives; levels left alone keep theirs.
|
|
292
|
+
* @param levels - the drafts to patch.
|
|
293
|
+
* @param level - the level toggled.
|
|
294
|
+
* @param offered - whether the row should declare it.
|
|
295
|
+
* @returns the patched drafts, or the same object when nothing changes.
|
|
296
|
+
*/
|
|
297
|
+
function toggleLevel(levels, level, offered) {
|
|
298
|
+
if (levels[level].offered === offered) return levels;
|
|
299
|
+
return {
|
|
300
|
+
...levels,
|
|
301
|
+
[level]: {
|
|
302
|
+
offered,
|
|
303
|
+
wire: offered ? defaultWire(level) : ""
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* The level set with one level's wire spelling retyped.
|
|
309
|
+
* @param levels - the drafts to patch.
|
|
310
|
+
* @param level - the level whose spelling changed.
|
|
311
|
+
* @param wire - the text the field now carries.
|
|
312
|
+
* @returns the patched drafts.
|
|
313
|
+
*/
|
|
314
|
+
function setWire(levels, level, wire) {
|
|
315
|
+
return {
|
|
316
|
+
...levels,
|
|
317
|
+
[level]: {
|
|
318
|
+
...levels[level],
|
|
319
|
+
wire
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Why a row's declared levels would be refused, checked before the write so the
|
|
325
|
+
* card can name the row instead of answering a rejected settings mutation. The
|
|
326
|
+
* rules are the adapter's: every declared level but `off` needs a wire spelling,
|
|
327
|
+
* and a set offering no level beyond `off` declares nothing worth declaring.
|
|
328
|
+
* @param row - one stored model row.
|
|
329
|
+
* @returns the failure, or undefined for a row that can be saved.
|
|
330
|
+
*/
|
|
331
|
+
function reasoningFailure(row) {
|
|
332
|
+
if (reasoningChoice(row) !== "custom") return void 0;
|
|
333
|
+
const levels = reasoningLevels(row);
|
|
334
|
+
let thinks = false;
|
|
335
|
+
for (const level of THINKING_LEVELS) {
|
|
336
|
+
const draft = levels[level];
|
|
337
|
+
if (!draft.offered || level === "off") continue;
|
|
338
|
+
if (draft.wire.trim().length === 0) return "needsWire";
|
|
339
|
+
thinks = true;
|
|
340
|
+
}
|
|
341
|
+
return thinks ? void 0 : "needsLevel";
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Read a select's submitted value. The DOM hands over a bare string, so an
|
|
345
|
+
* unrecognized one is refused rather than cast into the union.
|
|
346
|
+
* @param value - the submitted option value.
|
|
347
|
+
* @returns the choice, or undefined for anything else.
|
|
348
|
+
*/
|
|
349
|
+
function parseReasoningChoice(value) {
|
|
350
|
+
return value === "inherit" || value === "none" || value === "custom" ? value : void 0;
|
|
351
|
+
}
|
|
352
|
+
//#endregion
|
|
162
353
|
//#region \0dsh-css:src/client/styles.module.css.mjs
|
|
163
|
-
const css = ".q49TuG_fold{border:1px solid var(--dsw-alias-border-l2,#0000001f);background:var(--dsw-alias-bg-layer-3,transparent);border-radius:10px;margin:8px 0 0}.q49TuG_summary{cursor:pointer;color:var(--dsw-alias-label-primary,inherit);user-select:none;padding:10px 14px;font-size:13px;font-weight:600}.q49TuG_body{flex-direction:column;gap:10px;padding:2px 14px 14px;display:flex}.q49TuG_row{align-items:
|
|
354
|
+
const css = ".q49TuG_fold{border:1px solid var(--dsw-alias-border-l2,#0000001f);background:var(--dsw-alias-bg-layer-3,transparent);border-radius:10px;margin:8px 0 0}.q49TuG_summary{cursor:pointer;color:var(--dsw-alias-label-primary,inherit);user-select:none;padding:10px 14px;font-size:13px;font-weight:600}.q49TuG_body{flex-direction:column;gap:10px;padding:2px 14px 14px;display:flex}.q49TuG_model{flex-direction:column;gap:6px;display:flex}.q49TuG_row{flex-wrap:wrap;align-items:flex-end;gap:10px;display:flex}.q49TuG_rowId{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary,inherit);flex:auto;padding-bottom:6px;font-size:13px;overflow:hidden}.q49TuG_field{flex-direction:column;gap:3px;display:flex}.q49TuG_fieldLabel{color:var(--dsw-alias-label-tertiary,inherit);font-size:11px;line-height:1.2}.q49TuG_select{min-width:9em;color:var(--dsw-alias-label-primary,inherit);border:1px solid var(--dsw-alias-border-l2,#0000001f);border-radius:8px;flex:none;padding:6px 8px;font-size:13px}.q49TuG_levels{border:1px dashed var(--dsw-alias-border-l2,#0000001f);border-radius:8px;flex-direction:column;gap:6px;padding:8px 10px;display:flex}.q49TuG_levelGrid{grid-template-columns:repeat(auto-fill,minmax(15em,1fr));gap:6px 12px;display:grid}.q49TuG_levelRow{align-items:center;gap:8px;min-width:0;display:flex}.q49TuG_levelOffered{color:var(--dsw-alias-label-primary,inherit);cursor:pointer;flex:0 0 6.5em;align-items:center;gap:6px;font-size:12px;display:flex}.q49TuG_wire{min-width:0;color:var(--dsw-alias-label-primary,inherit);border:1px solid var(--dsw-alias-border-l2,#0000001f);background:0 0;border-radius:8px;flex:auto;padding:4px 8px;font-size:12px}.q49TuG_wire:disabled{opacity:.55}.q49TuG_hint,.q49TuG_status{color:var(--dsw-alias-label-tertiary,inherit);margin:0;font-size:12px;line-height:1.5}.q49TuG_error{color:var(--dsw-alias-status-danger,#d64545);margin:0;font-size:12px;line-height:1.5}.q49TuG_footer{align-items:center;gap:10px;display:flex}";
|
|
164
355
|
const tagId = "@jcy2387/dsh-models-input-modalities/styles.module.css";
|
|
165
356
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
166
357
|
const tag = document.createElement("style");
|
|
@@ -170,35 +361,45 @@ window.__ModuleLoader__.load({
|
|
|
170
361
|
document.head.appendChild(tag);
|
|
171
362
|
}
|
|
172
363
|
var styles_module_css_default = {
|
|
173
|
-
"
|
|
174
|
-
"
|
|
364
|
+
"field": "q49TuG_field",
|
|
365
|
+
"status": "q49TuG_status",
|
|
175
366
|
"body": "q49TuG_body",
|
|
367
|
+
"fold": "q49TuG_fold",
|
|
368
|
+
"row": "q49TuG_row",
|
|
369
|
+
"fieldLabel": "q49TuG_fieldLabel",
|
|
370
|
+
"levels": "q49TuG_levels",
|
|
371
|
+
"hint": "q49TuG_hint",
|
|
372
|
+
"levelOffered": "q49TuG_levelOffered",
|
|
373
|
+
"summary": "q49TuG_summary",
|
|
176
374
|
"rowId": "q49TuG_rowId",
|
|
177
|
-
"
|
|
178
|
-
"
|
|
375
|
+
"select": "q49TuG_select",
|
|
376
|
+
"levelRow": "q49TuG_levelRow",
|
|
179
377
|
"footer": "q49TuG_footer",
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"
|
|
378
|
+
"levelGrid": "q49TuG_levelGrid",
|
|
379
|
+
"error": "q49TuG_error",
|
|
380
|
+
"wire": "q49TuG_wire",
|
|
381
|
+
"model": "q49TuG_model"
|
|
183
382
|
};
|
|
184
383
|
//#endregion
|
|
185
|
-
//#region src/client/
|
|
384
|
+
//#region src/client/ModelCapabilityCard.tsx
|
|
186
385
|
/**
|
|
187
|
-
* One pi-ai provider card's
|
|
188
|
-
* Models page's own form does not carry
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
386
|
+
* One pi-ai provider card's model-capability fold: the per-model claims the
|
|
387
|
+
* Models page's own form does not carry — which inputs a model accepts, and
|
|
388
|
+
* which reasoning levels it offers. The fold loads the provider's stored rows
|
|
389
|
+
* when first opened, edits them locally, and writes the whole `models` array
|
|
390
|
+
* back under the revision fence the load answered — the same array semantics
|
|
391
|
+
* the page's own cards use, and the reason both claims live in one fold: two
|
|
392
|
+
* folds would write the same array and fence each other into conflicts. A
|
|
393
|
+
* stored change elsewhere on the page (a model added or removed in the catalog
|
|
394
|
+
* above) reaches the fold through the pushed settings invalidation, so the list
|
|
395
|
+
* it shows never waits for the section to remount.
|
|
195
396
|
*/
|
|
196
397
|
/**
|
|
197
|
-
* Render the
|
|
398
|
+
* Render the model-capability fold of one provider card.
|
|
198
399
|
* @param props - the card's directory row plus the bound face and copy.
|
|
199
400
|
* @returns the fold, or nothing while the provider is still a dormant row.
|
|
200
401
|
*/
|
|
201
|
-
function
|
|
402
|
+
function ModelCapabilityCard(props) {
|
|
202
403
|
const { provider, configured, t, loadModels, saveModels, subscribeChanges } = props;
|
|
203
404
|
const [status, setStatus] = (0, react.useState)("idle");
|
|
204
405
|
const [view, setView] = (0, react.useState)(void 0);
|
|
@@ -286,11 +487,26 @@ window.__ModuleLoader__.load({
|
|
|
286
487
|
reload
|
|
287
488
|
]);
|
|
288
489
|
if (configured !== true) return null;
|
|
289
|
-
const
|
|
490
|
+
const chooseInput = (index, choice) => {
|
|
290
491
|
setRows((current) => current.map((row, at) => at === index ? withImageInput(row, choice) : row));
|
|
291
492
|
};
|
|
493
|
+
const chooseReasoning = (index, choice) => {
|
|
494
|
+
setRows((current) => current.map((row, at) => at === index ? withReasoning(row, choice, reasoningLevels(row)) : row));
|
|
495
|
+
};
|
|
496
|
+
/**
|
|
497
|
+
* Patch one row's declared levels. The edit runs inside the state updater and
|
|
498
|
+
* re-reads the row there, so two controls changed in one batch each see what
|
|
499
|
+
* the previous one wrote.
|
|
500
|
+
* @param index - the row to patch.
|
|
501
|
+
* @param edit - the level-set transformation.
|
|
502
|
+
*/
|
|
503
|
+
const patchLevels = (index, edit) => {
|
|
504
|
+
setRows((current) => current.map((row, at) => at === index ? withReasoning(row, "custom", edit(reasoningLevels(row))) : row));
|
|
505
|
+
};
|
|
506
|
+
const unsavable = rows.some((row) => reasoningFailure(row) !== void 0);
|
|
507
|
+
const locked = view === void 0 || !view.writable || status === "saving";
|
|
292
508
|
const submit = async () => {
|
|
293
|
-
if (view === void 0) return;
|
|
509
|
+
if (view === void 0 || unsavable) return;
|
|
294
510
|
setStatus("saving");
|
|
295
511
|
const outcome = await saveModels(provider, rows, view.revision);
|
|
296
512
|
if (outcome.kind === "written") {
|
|
@@ -350,36 +566,130 @@ window.__ModuleLoader__.load({
|
|
|
350
566
|
className: styles_module_css_default["hint"],
|
|
351
567
|
children: t("inheritsHint")
|
|
352
568
|
}),
|
|
353
|
-
rows.map((row, index) =>
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
className: styles_module_css_default["
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
569
|
+
rows.map((row, index) => {
|
|
570
|
+
const id = rowId(row, index);
|
|
571
|
+
const reasoning = reasoningChoice(row);
|
|
572
|
+
const levels = reasoningLevels(row);
|
|
573
|
+
const invalid = reasoningFailure(row);
|
|
574
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
575
|
+
className: styles_module_css_default["model"],
|
|
576
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
577
|
+
className: styles_module_css_default["row"],
|
|
578
|
+
children: [
|
|
579
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
580
|
+
className: styles_module_css_default["rowId"],
|
|
581
|
+
children: id
|
|
582
|
+
}),
|
|
583
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
584
|
+
className: styles_module_css_default["field"],
|
|
585
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
586
|
+
className: styles_module_css_default["fieldLabel"],
|
|
587
|
+
children: t("inputLabel")
|
|
588
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
589
|
+
className: styles_module_css_default["select"],
|
|
590
|
+
value: imageInputChoice(row),
|
|
591
|
+
"aria-label": `${t("inputLabel")} ${id}`,
|
|
592
|
+
disabled: locked,
|
|
593
|
+
onChange: (event) => {
|
|
594
|
+
const next = parseImageInputChoice(event.target.value);
|
|
595
|
+
if (next !== void 0) chooseInput(index, next);
|
|
596
|
+
},
|
|
597
|
+
children: [
|
|
598
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
599
|
+
value: "inherit",
|
|
600
|
+
children: t("choiceDefault")
|
|
601
|
+
}),
|
|
602
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
603
|
+
value: "text",
|
|
604
|
+
children: t("choiceText")
|
|
605
|
+
}),
|
|
606
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
607
|
+
value: "image",
|
|
608
|
+
children: t("choiceImage")
|
|
609
|
+
})
|
|
610
|
+
]
|
|
611
|
+
})]
|
|
612
|
+
}),
|
|
613
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
614
|
+
className: styles_module_css_default["field"],
|
|
615
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
616
|
+
className: styles_module_css_default["fieldLabel"],
|
|
617
|
+
children: t("reasoningLabel")
|
|
618
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
619
|
+
className: styles_module_css_default["select"],
|
|
620
|
+
value: reasoning,
|
|
621
|
+
"aria-label": `${t("reasoningLabel")} ${id}`,
|
|
622
|
+
disabled: locked,
|
|
623
|
+
onChange: (event) => {
|
|
624
|
+
const next = parseReasoningChoice(event.target.value);
|
|
625
|
+
if (next !== void 0) chooseReasoning(index, next);
|
|
626
|
+
},
|
|
627
|
+
children: [
|
|
628
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
629
|
+
value: "inherit",
|
|
630
|
+
children: t("reasoningInherit")
|
|
631
|
+
}),
|
|
632
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
633
|
+
value: "none",
|
|
634
|
+
children: t("reasoningNone")
|
|
635
|
+
}),
|
|
636
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
637
|
+
value: "custom",
|
|
638
|
+
children: t("reasoningCustom")
|
|
639
|
+
})
|
|
640
|
+
]
|
|
641
|
+
})]
|
|
642
|
+
})
|
|
643
|
+
]
|
|
644
|
+
}), reasoning === "custom" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
645
|
+
className: styles_module_css_default["levels"],
|
|
646
|
+
children: [
|
|
647
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
648
|
+
className: styles_module_css_default["levelGrid"],
|
|
649
|
+
children: THINKING_LEVELS.map((level) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
650
|
+
className: styles_module_css_default["levelRow"],
|
|
651
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
652
|
+
className: styles_module_css_default["levelOffered"],
|
|
653
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
654
|
+
type: "checkbox",
|
|
655
|
+
checked: levels[level].offered,
|
|
656
|
+
disabled: locked,
|
|
657
|
+
onChange: (event) => {
|
|
658
|
+
const offered = event.target.checked;
|
|
659
|
+
patchLevels(index, (current) => toggleLevel(current, level, offered));
|
|
660
|
+
}
|
|
661
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: level })]
|
|
662
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
663
|
+
className: styles_module_css_default["wire"],
|
|
664
|
+
type: "text",
|
|
665
|
+
value: levels[level].wire,
|
|
666
|
+
placeholder: level === "off" ? t("wireNothing") : level,
|
|
667
|
+
"aria-label": `${t("wireLabel")} ${level}`,
|
|
668
|
+
spellCheck: false,
|
|
669
|
+
disabled: locked || !levels[level].offered,
|
|
670
|
+
onChange: (event) => {
|
|
671
|
+
const wire = event.target.value;
|
|
672
|
+
patchLevels(index, (current) => setWire(current, level, wire));
|
|
673
|
+
}
|
|
674
|
+
})]
|
|
675
|
+
}, level))
|
|
676
|
+
}),
|
|
677
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
678
|
+
className: styles_module_css_default["hint"],
|
|
679
|
+
children: t("reasoningHint")
|
|
680
|
+
}),
|
|
681
|
+
invalid === "needsWire" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
682
|
+
className: styles_module_css_default["error"],
|
|
683
|
+
children: `${id}: ${t("needsWire")}`
|
|
684
|
+
}) : null,
|
|
685
|
+
invalid === "needsLevel" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
686
|
+
className: styles_module_css_default["error"],
|
|
687
|
+
children: `${id}: ${t("needsLevel")}`
|
|
688
|
+
}) : null
|
|
689
|
+
]
|
|
690
|
+
}) : null]
|
|
691
|
+
}, index);
|
|
692
|
+
}),
|
|
383
693
|
failure !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
384
694
|
className: styles_module_css_default["error"],
|
|
385
695
|
children: failure
|
|
@@ -390,7 +700,7 @@ window.__ModuleLoader__.load({
|
|
|
390
700
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
391
701
|
variant: "outline",
|
|
392
702
|
size: "sm",
|
|
393
|
-
disabled:
|
|
703
|
+
disabled: locked || !dirty || unsavable,
|
|
394
704
|
onClick: () => {
|
|
395
705
|
submit();
|
|
396
706
|
},
|
|
@@ -422,19 +732,29 @@ window.__ModuleLoader__.load({
|
|
|
422
732
|
}
|
|
423
733
|
//#endregion
|
|
424
734
|
//#region src/client/locales.ts
|
|
425
|
-
/** Copy dictionaries for the
|
|
735
|
+
/** Copy dictionaries for the model-capability card. */
|
|
426
736
|
/** English strings (the key-set source of truth for this pair). */
|
|
427
737
|
const en = {
|
|
428
|
-
title: "
|
|
738
|
+
title: "Model capabilities",
|
|
429
739
|
loading: "Loading the model list…",
|
|
430
740
|
loadFailed: "Loading the model configuration failed.",
|
|
431
741
|
retry: "Retry",
|
|
432
|
-
empty: "No explicit model list yet — add models in the catalog above, then declare
|
|
742
|
+
empty: "No explicit model list yet — add models in the catalog above, then declare what each one accepts and reasons with here.",
|
|
433
743
|
inheritsHint: "Showing the inherited model list; saving copies it into your user settings.",
|
|
434
744
|
readOnly: "The settings document is read-only in this deployment.",
|
|
745
|
+
inputLabel: "Input modalities",
|
|
435
746
|
choiceDefault: "Provider default",
|
|
436
747
|
choiceText: "Text only",
|
|
437
748
|
choiceImage: "Text and image",
|
|
749
|
+
reasoningLabel: "Reasoning levels",
|
|
750
|
+
reasoningInherit: "Catalog default",
|
|
751
|
+
reasoningNone: "Not a reasoning model",
|
|
752
|
+
reasoningCustom: "Declare levels",
|
|
753
|
+
reasoningHint: "A ticked level is one the model picker offers; the value beside it is the spelling sent on the wire, which a gateway may name its own way. Only off may stay empty — offered, and sent as no parameter at all. A level left unticked is not offered.",
|
|
754
|
+
wireLabel: "Wire value for",
|
|
755
|
+
wireNothing: "send nothing",
|
|
756
|
+
needsLevel: "declare at least one level beyond off, or choose “Not a reasoning model”.",
|
|
757
|
+
needsWire: "every level except off needs the wire value to send.",
|
|
438
758
|
save: "Save",
|
|
439
759
|
saving: "Saving…",
|
|
440
760
|
saved: "Saved. The adapter picks it up on its next request.",
|
|
@@ -442,16 +762,26 @@ window.__ModuleLoader__.load({
|
|
|
442
762
|
};
|
|
443
763
|
/** Chinese strings (same keys as {@link en}). */
|
|
444
764
|
const zh = {
|
|
445
|
-
title: "
|
|
765
|
+
title: "模型能力",
|
|
446
766
|
loading: "正在读取模型列表…",
|
|
447
767
|
loadFailed: "读取模型配置失败。",
|
|
448
768
|
retry: "重试",
|
|
449
|
-
empty: "
|
|
769
|
+
empty: "还没有显式模型列表——请先在上方模型目录中添加模型,再回到这里声明每个模型接受的输入与推理等级。",
|
|
450
770
|
inheritsHint: "当前显示的是继承的模型列表;保存会将其复制到你的用户设置层。",
|
|
451
771
|
readOnly: "当前部署的设置文档为只读。",
|
|
772
|
+
inputLabel: "输入模态",
|
|
452
773
|
choiceDefault: "提供方默认",
|
|
453
774
|
choiceText: "仅文本",
|
|
454
775
|
choiceImage: "文本和图片",
|
|
776
|
+
reasoningLabel: "推理等级",
|
|
777
|
+
reasoningInherit: "目录默认",
|
|
778
|
+
reasoningNone: "非推理模型",
|
|
779
|
+
reasoningCustom: "声明等级",
|
|
780
|
+
reasoningHint: "勾选的等级就是模型选择器会提供的选项;旁边的值是实际发到网关的拼写,网关可以有自己的叫法。只有 off 可以留空——表示提供该等级但完全不发送参数。未勾选的等级不会提供。",
|
|
781
|
+
wireLabel: "发送值:",
|
|
782
|
+
wireNothing: "不发送",
|
|
783
|
+
needsLevel: "至少声明一个 off 以外的等级,或选择「非推理模型」。",
|
|
784
|
+
needsWire: "除 off 外,每个勾选的等级都要填写发送值。",
|
|
455
785
|
save: "保存",
|
|
456
786
|
saving: "保存中…",
|
|
457
787
|
saved: "已保存。适配器会在下一次请求时生效。",
|
|
@@ -460,7 +790,7 @@ window.__ModuleLoader__.load({
|
|
|
460
790
|
//#endregion
|
|
461
791
|
//#region src/client/index.ts
|
|
462
792
|
/** Dictionary namespace owned by this plugin. */
|
|
463
|
-
const NS = "settings.models.
|
|
793
|
+
const NS = "settings.models.modelCapabilities";
|
|
464
794
|
/** The effect label prefix. */
|
|
465
795
|
const PKG = "@jcy2387/dsh-models-input-modalities";
|
|
466
796
|
/** Required browser services. */
|
|
@@ -471,7 +801,7 @@ window.__ModuleLoader__.load({
|
|
|
471
801
|
"remote.settings"
|
|
472
802
|
];
|
|
473
803
|
/**
|
|
474
|
-
* Register the
|
|
804
|
+
* Register the model-capability fold on every llm-pi-ai provider card once the
|
|
475
805
|
* Models section has declared the seat.
|
|
476
806
|
* @param ctx - the plugin's client context.
|
|
477
807
|
*/
|
|
@@ -480,7 +810,7 @@ window.__ModuleLoader__.load({
|
|
|
480
810
|
zh,
|
|
481
811
|
en
|
|
482
812
|
}), `${PKG}: dictionaries`);
|
|
483
|
-
const controller = new
|
|
813
|
+
const controller = new ModelCapabilityController(ctx);
|
|
484
814
|
ctx.effect(() => controller.watch(), `${PKG}: settings invalidations`);
|
|
485
815
|
const face = {
|
|
486
816
|
loadModels: (entry) => controller.load(entry),
|
|
@@ -492,7 +822,7 @@ window.__ModuleLoader__.load({
|
|
|
492
822
|
key: "llm-pi-ai",
|
|
493
823
|
locale: NS,
|
|
494
824
|
inject: () => face
|
|
495
|
-
},
|
|
825
|
+
}, ModelCapabilityCard));
|
|
496
826
|
}
|
|
497
827
|
//#endregion
|
|
498
828
|
exports.apply = apply;
|