dsh-qoder-plugin 0.6.0 → 0.6.3
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/lib/bin.js +1 -1
- package/lib/client.js +185 -101
- package/lib/index.js +1 -1
- package/lib/{variants-D6eeKFyY.js → variants-CATiqb4o.js} +1 -1
- package/package.json +1 -1
package/lib/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { B as QoderCredentialStore, D as qoderCatalogPath, E as QoderCatalogStore, H as qoderCredentialIdentity, O as FALLBACK_QODER_MODELS, b as createQoderTransport, f as QODER_CONNECT_VERSION, i as variantFor, l as qoderHostHeartbeatPath, m as QoderUpstreamClient, r as QODER_VARIANTS, s as isHeartbeatProcessAlive, t as CHINA_VARIANT, u as readHostHeartbeat, y as validateApiKey } from "./variants-
|
|
2
|
+
import { B as QoderCredentialStore, D as qoderCatalogPath, E as QoderCatalogStore, H as qoderCredentialIdentity, O as FALLBACK_QODER_MODELS, b as createQoderTransport, f as QODER_CONNECT_VERSION, i as variantFor, l as qoderHostHeartbeatPath, m as QoderUpstreamClient, r as QODER_VARIANTS, s as isHeartbeatProcessAlive, t as CHINA_VARIANT, u as readHostHeartbeat, y as validateApiKey } from "./variants-CATiqb4o.js";
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import { realpathSync } from "node:fs";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
package/lib/client.js
CHANGED
|
@@ -193,21 +193,40 @@ window.__ModuleLoader__.load({
|
|
|
193
193
|
className: cx("qdp-iconButton", className)
|
|
194
194
|
});
|
|
195
195
|
}
|
|
196
|
+
/** Hairline marks under the rail — 33 marks, one every 3.125 % of the field. */
|
|
197
|
+
const SLIDER_RULER_MARKS = 33;
|
|
196
198
|
/**
|
|
197
|
-
* Context-window slider
|
|
198
|
-
*
|
|
199
|
-
* the
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
199
|
+
* Context-window slider, replicating the Qoder model-settings control.
|
|
200
|
+
*
|
|
201
|
+
* Geometry follows the upstream component: a 56 px field whose 18 px rail sits
|
|
202
|
+
* on the vertical centre and whose 12 px label row hangs 40 px below the field's
|
|
203
|
+
* top, 33 hairlines along the rail (every eighth one taller and darker) and a
|
|
204
|
+
* 2×12 px grab tick at the fill's edge. The scale starts at zero — a window's
|
|
205
|
+
* position is `value / max`, so 200K sits at 20 % of a 1M axis exactly as in the
|
|
206
|
+
* official table — and the rail itself stops at the widest offered window. Only
|
|
207
|
+
* the offered windows carry a label (9 px, sitting on the field colour so the
|
|
208
|
+
* hairlines pass behind); the one in force is the dark, medium-weight label.
|
|
209
|
+
*
|
|
210
|
+
* With `snapTo` a pointer drag moves the grab tick one tier at a time (it lands
|
|
211
|
+
* only on the offered windows); without offers it follows the pointer quantized
|
|
212
|
+
* to `step`. Arrows, PageUp/PageDown and Home/End keep it keyboard operable,
|
|
213
|
+
* with arrows walking the offers one by one. The component is fully controlled —
|
|
214
|
+
* it never writes anything by itself.
|
|
204
215
|
*/
|
|
205
216
|
function QdpSlider({ label, value, min, max, step = 1e3, disabled, onChange, valueText, ticks, format, snapTo, testId }) {
|
|
206
217
|
const formatValue = (raw) => format !== void 0 ? format(raw) : raw === value && valueText !== void 0 ? valueText : String(raw);
|
|
207
|
-
|
|
218
|
+
/**
|
|
219
|
+
* Position of a window on the field, in percent.
|
|
220
|
+
*
|
|
221
|
+
* The official control's axis starts at zero (`value / maxValue`), not at the
|
|
222
|
+
* smallest window, so a 200K window covers the first fifth of a 1M axis on
|
|
223
|
+
* every row and equal windows line up across rows.
|
|
224
|
+
*/
|
|
225
|
+
const percentOf = (raw) => max > 0 ? Math.min(100, Math.max(0, raw / max * 100)) : 0;
|
|
226
|
+
/** Label/tick transforms that keep the end marks inside the field. */
|
|
227
|
+
const edgeTransform = (percent) => percent >= 99.5 ? "translate(-100%, -50%)" : percent <= .5 ? "translate(0, -50%)" : "translate(-50%, -50%)";
|
|
208
228
|
const trackRef = (0, react.useRef)(null);
|
|
209
229
|
const span = max > min ? max - min : 0;
|
|
210
|
-
const ratio = span > 0 ? Math.min(1, Math.max(0, (value - min) / span)) : 0;
|
|
211
230
|
/** The offered values that actually fit the shared axis, ascending. */
|
|
212
231
|
const anchors = (0, react.useMemo)(() => {
|
|
213
232
|
if (snapTo === void 0 || snapTo.length === 0) return void 0;
|
|
@@ -218,6 +237,14 @@ window.__ModuleLoader__.load({
|
|
|
218
237
|
min,
|
|
219
238
|
snapTo
|
|
220
239
|
]);
|
|
240
|
+
/** Where the grab tick and the filled rail end. */
|
|
241
|
+
const fillPercent = percentOf(value);
|
|
242
|
+
/**
|
|
243
|
+
* The rail stops at the widest offered window, not at the axis end: a row that
|
|
244
|
+
* offers only 200K / 400K draws a shorter rail instead of empty track beyond
|
|
245
|
+
* its last tier (the official control behaves the same way).
|
|
246
|
+
*/
|
|
247
|
+
const railPercent = percentOf(anchors === void 0 ? max : anchors[anchors.length - 1] ?? max);
|
|
221
248
|
const snap = (0, react.useCallback)((raw) => {
|
|
222
249
|
const clamped = Math.min(max, Math.max(min, raw));
|
|
223
250
|
if (anchors !== void 0) {
|
|
@@ -235,24 +262,28 @@ window.__ModuleLoader__.load({
|
|
|
235
262
|
step
|
|
236
263
|
]);
|
|
237
264
|
/**
|
|
238
|
-
* The value a live drag reports
|
|
265
|
+
* The value a live drag reports.
|
|
239
266
|
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
267
|
+
* With `snapTo` the drag advances tier by tier: every pointer move reports the
|
|
268
|
+
* nearest offered window, so the handle is never parked between two tiers
|
|
269
|
+
* (one slide, one context size) and the number under it is always a window the
|
|
270
|
+
* upstream declares. Without offers the drag is quantized to `step`, keeping
|
|
271
|
+
* the displayed number free of round-off noise.
|
|
244
272
|
*/
|
|
245
273
|
const free = (0, react.useCallback)((raw) => {
|
|
274
|
+
if (anchors !== void 0) return snap(raw);
|
|
246
275
|
const clamped = Math.min(max, Math.max(min, raw));
|
|
247
276
|
if (step <= 0) return clamped;
|
|
248
277
|
const stepped = min + Math.round((clamped - min) / step) * step;
|
|
249
278
|
return Math.min(max, Math.max(min, stepped));
|
|
250
279
|
}, [
|
|
280
|
+
anchors,
|
|
251
281
|
max,
|
|
252
282
|
min,
|
|
283
|
+
snap,
|
|
253
284
|
step
|
|
254
285
|
]);
|
|
255
|
-
/**
|
|
286
|
+
/** Pointer position of the drag in flight, kept for the release settle. */
|
|
256
287
|
const lastRaw = (0, react.useRef)(void 0);
|
|
257
288
|
const fromClientX = (0, react.useCallback)((clientX) => {
|
|
258
289
|
const element = trackRef.current;
|
|
@@ -279,12 +310,12 @@ window.__ModuleLoader__.load({
|
|
|
279
310
|
fromClientX(event.clientX);
|
|
280
311
|
};
|
|
281
312
|
/**
|
|
282
|
-
* End of drag:
|
|
313
|
+
* End of drag: settle on the offer nearest the pointer.
|
|
283
314
|
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
315
|
+
* A drag that has offers already reports one on every move, so this only
|
|
316
|
+
* matters for the last finger position: `lastRaw` is the pointer position the
|
|
317
|
+
* drag ended at, not `value` — the controlled parent may still be rendering
|
|
318
|
+
* the previous tick when the release lands.
|
|
288
319
|
*/
|
|
289
320
|
const release = (event) => {
|
|
290
321
|
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
@@ -316,10 +347,10 @@ window.__ModuleLoader__.load({
|
|
|
316
347
|
event.preventDefault();
|
|
317
348
|
if (next !== value) onChange(next);
|
|
318
349
|
};
|
|
319
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
350
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
320
351
|
className: "qdp-sliderField",
|
|
321
352
|
"data-testid": testId,
|
|
322
|
-
children:
|
|
353
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
323
354
|
className: "qdp-slider",
|
|
324
355
|
role: "slider",
|
|
325
356
|
"aria-label": label,
|
|
@@ -334,25 +365,46 @@ window.__ModuleLoader__.load({
|
|
|
334
365
|
onPointerUp: release,
|
|
335
366
|
onPointerCancel: release,
|
|
336
367
|
onKeyDown,
|
|
337
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
368
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
338
369
|
className: "qdp-sliderTrack",
|
|
339
370
|
ref: trackRef,
|
|
340
|
-
children: [
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
371
|
+
children: [
|
|
372
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
373
|
+
className: "qdp-sliderRail",
|
|
374
|
+
style: { width: `${railPercent.toFixed(2)}%` }
|
|
375
|
+
}),
|
|
376
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
377
|
+
className: "qdp-sliderFill",
|
|
378
|
+
style: { width: `${fillPercent.toFixed(2)}%` }
|
|
379
|
+
}),
|
|
380
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
381
|
+
className: "qdp-sliderThumb",
|
|
382
|
+
style: { left: `calc(${fillPercent.toFixed(2)}% - 5px)` }
|
|
383
|
+
})
|
|
384
|
+
]
|
|
385
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
386
|
+
className: "qdp-windowTicks",
|
|
387
|
+
children: [Array.from({ length: SLIDER_RULER_MARKS }, (_, index) => {
|
|
388
|
+
const percent = index / 32 * 100;
|
|
389
|
+
if (percent > railPercent + .01) return null;
|
|
390
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
391
|
+
"aria-hidden": "true",
|
|
392
|
+
className: cx("qdp-windowTickMark", index % 8 === 0 && "qdp-windowTickMarkMajor"),
|
|
393
|
+
style: { left: `${percent.toFixed(2)}%` }
|
|
394
|
+
}, `mark-${index}`);
|
|
395
|
+
}), (ticks ?? []).map((tick) => {
|
|
396
|
+
const percent = percentOf(tick);
|
|
397
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
398
|
+
className: cx("qdp-windowTick", tick === value && "qdp-windowTickActive"),
|
|
399
|
+
style: {
|
|
400
|
+
left: `${percent.toFixed(2)}%`,
|
|
401
|
+
transform: edgeTransform(percent)
|
|
402
|
+
},
|
|
403
|
+
children: formatValue(tick)
|
|
404
|
+
}, tick);
|
|
346
405
|
})]
|
|
347
|
-
})
|
|
348
|
-
})
|
|
349
|
-
className: "qdp-windowTicks",
|
|
350
|
-
children: ticks.map((tick) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
351
|
-
className: "qdp-windowTick",
|
|
352
|
-
style: { left: `${percentOf(tick).toFixed(2)}%` },
|
|
353
|
-
children: formatValue(tick)
|
|
354
|
-
}, tick))
|
|
355
|
-
})]
|
|
406
|
+
})]
|
|
407
|
+
})
|
|
356
408
|
});
|
|
357
409
|
}
|
|
358
410
|
//#endregion
|
|
@@ -405,19 +457,20 @@ window.__ModuleLoader__.load({
|
|
|
405
457
|
return `${factor.toFixed(1)}x`;
|
|
406
458
|
}
|
|
407
459
|
/**
|
|
408
|
-
* The reasoning-effort tag's text
|
|
409
|
-
*
|
|
460
|
+
* The reasoning-effort tag's text: the levels the model can reason at, plus the
|
|
461
|
+
* upstream default.
|
|
410
462
|
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
463
|
+
* The tag speaks the upstream's English wire vocabulary (`low`, `high`,
|
|
464
|
+
* `xhigh`, `max`, …) in every UI language — the words are model parameters, and
|
|
465
|
+
* the official Qoder app lists them untranslated. A model that advertises no
|
|
466
|
+
* selectable effort says so instead of drawing an empty tag.
|
|
414
467
|
*/
|
|
415
468
|
function effortsTagText(model, t) {
|
|
416
469
|
const efforts = (model.reasoningEfforts ?? []).filter((id) => id !== "");
|
|
417
|
-
if (efforts.length === 0) return
|
|
470
|
+
if (efforts.length === 0) return t("effortsUnsupported");
|
|
418
471
|
const nameOf = (id) => id === "low" ? t("effortLow") : id === "medium" ? t("effortMedium") : id === "high" ? t("effortHigh") : id === "xhigh" ? t("effortXhigh") : id === "max" ? t("effortMax") : id === "minimal" ? t("effortMinimal") : id;
|
|
419
472
|
const levels = efforts.map(nameOf).join(" · ");
|
|
420
|
-
const fallback = model.defaultReasoningEffort !== void 0 && efforts.includes(model.defaultReasoningEffort) ?
|
|
473
|
+
const fallback = model.defaultReasoningEffort !== void 0 && efforts.includes(model.defaultReasoningEffort) ? ` (${t("modelEffortsDefault", { name: nameOf(model.defaultReasoningEffort) })})` : "";
|
|
421
474
|
return t("modelEfforts", { levels }) + fallback;
|
|
422
475
|
}
|
|
423
476
|
/** Round an axis end up to a clean K/M boundary so tick labels stay readable. */
|
|
@@ -446,19 +499,17 @@ window.__ModuleLoader__.load({
|
|
|
446
499
|
const clampWindow = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
447
500
|
const uniqueSorted = (ids) => [...new Set(ids)].sort((a, b) => a.localeCompare(b));
|
|
448
501
|
/**
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
502
|
+
* The windows this row offers as tiers, clipped to the shared axis.
|
|
503
|
+
*
|
|
504
|
+
* These are exactly the values the slider lands on and the marks it draws; the
|
|
505
|
+
* shared axis ENDS are deliberately not added. On a row whose narrowest offer
|
|
506
|
+
* sits close to the global minimum (the international roster's Performance
|
|
507
|
+
* offers 272K while the shared minimum is 200K) the extra minimum label
|
|
508
|
+
* overlapped the row's own first label. The scale is still shared, so a 400K on
|
|
509
|
+
* one row keeps lining up with a 400K on the next.
|
|
453
510
|
*/
|
|
454
|
-
function
|
|
455
|
-
|
|
456
|
-
const marks = declared.length > 0 ? [
|
|
457
|
-
min,
|
|
458
|
-
...declared,
|
|
459
|
-
max
|
|
460
|
-
] : [min, max];
|
|
461
|
-
return [...new Set(marks)].filter((value) => value >= min && value <= max).sort((a, b) => a - b);
|
|
511
|
+
function rowTiers(model, min, max) {
|
|
512
|
+
return declaredWindows(model).filter((value) => value >= min && value <= max);
|
|
462
513
|
}
|
|
463
514
|
/**
|
|
464
515
|
* Signature of everything the draft is based on. When it changes the draft is
|
|
@@ -566,6 +617,7 @@ window.__ModuleLoader__.load({
|
|
|
566
617
|
const value = draft.windows[model.id] ?? baseline;
|
|
567
618
|
const current = value === void 0 ? void 0 : clampWindow(value, minWindow, axisMax);
|
|
568
619
|
const effortsText = effortsTagText(model, t);
|
|
620
|
+
const tiers = rowTiers(model, minWindow, axisMax);
|
|
569
621
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
570
622
|
className: "qdp-modelRow",
|
|
571
623
|
"data-model-id": model.id,
|
|
@@ -593,11 +645,11 @@ window.__ModuleLoader__.load({
|
|
|
593
645
|
})
|
|
594
646
|
}),
|
|
595
647
|
model.priceFactor === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QdpTag, { children: formatRate(model.priceFactor) }),
|
|
596
|
-
effortsText === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QdpTag, { children: effortsText }),
|
|
597
648
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
598
649
|
className: "qdp-modelMeta",
|
|
599
650
|
children: model.id
|
|
600
|
-
})
|
|
651
|
+
}),
|
|
652
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(QdpTag, { children: effortsText })
|
|
601
653
|
]
|
|
602
654
|
}),
|
|
603
655
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -614,8 +666,8 @@ window.__ModuleLoader__.load({
|
|
|
614
666
|
disabled: controlsDisabled,
|
|
615
667
|
onChange: (next) => changeWindow(model, next),
|
|
616
668
|
valueText: formatTokens(current),
|
|
617
|
-
|
|
618
|
-
ticks:
|
|
669
|
+
snapTo: tiers,
|
|
670
|
+
ticks: tiers,
|
|
619
671
|
format: formatTokens,
|
|
620
672
|
testId: `qdp-window-${model.id}`
|
|
621
673
|
})
|
|
@@ -3592,49 +3644,55 @@ window.__ModuleLoader__.load({
|
|
|
3592
3644
|
|
|
3593
3645
|
/* ---------------------------------------------------------------- sliders */
|
|
3594
3646
|
|
|
3647
|
+
/* The official Qoder model-settings slider: a 56 px field, an 18 px rail on the
|
|
3648
|
+
vertical centre, a 2 × 12 px grab tick at the fill's edge and a 12 px label
|
|
3649
|
+
row hanging 40 px below the field's top. The rail is a soft neutral and the
|
|
3650
|
+
fill a 42 % brand tint, so the grab tick reads as the only strong mark. */
|
|
3595
3651
|
.qdp-slider {
|
|
3596
3652
|
position: relative;
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
height:
|
|
3600
|
-
padding: 0 2px;
|
|
3653
|
+
width: 100%;
|
|
3654
|
+
max-width: 252px;
|
|
3655
|
+
height: 56px;
|
|
3601
3656
|
border-radius: var(--dsw-radius-xs);
|
|
3602
3657
|
cursor: pointer;
|
|
3603
3658
|
touch-action: none;
|
|
3604
3659
|
user-select: none;
|
|
3605
3660
|
}
|
|
3606
3661
|
.qdp-slider[aria-disabled='true'] {
|
|
3607
|
-
opacity: 0.
|
|
3662
|
+
opacity: 0.55;
|
|
3608
3663
|
cursor: default;
|
|
3609
3664
|
}
|
|
3610
3665
|
.qdp-sliderTrack {
|
|
3611
|
-
position:
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3666
|
+
position: absolute;
|
|
3667
|
+
top: 50%;
|
|
3668
|
+
right: 0;
|
|
3669
|
+
left: 0;
|
|
3670
|
+
height: 18px;
|
|
3671
|
+
transform: translateY(-50%);
|
|
3617
3672
|
}
|
|
3673
|
+
.qdp-sliderRail,
|
|
3618
3674
|
.qdp-sliderFill {
|
|
3619
3675
|
position: absolute;
|
|
3620
3676
|
top: 0;
|
|
3621
3677
|
left: 0;
|
|
3622
3678
|
height: 100%;
|
|
3623
|
-
border-radius:
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3679
|
+
border-radius: var(--dsw-radius-xs);
|
|
3680
|
+
}
|
|
3681
|
+
.qdp-sliderRail {
|
|
3682
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
3683
|
+
}
|
|
3684
|
+
/* The chosen stretch is a quiet neutral, exactly like the upstream rail: the
|
|
3685
|
+
strong mark on the control is the grab tick, not a saturated fill. */
|
|
3686
|
+
.qdp-sliderFill {
|
|
3687
|
+
background: var(--dsw-alias-border-l3);
|
|
3629
3688
|
}
|
|
3630
3689
|
.qdp-sliderThumb {
|
|
3631
3690
|
position: absolute;
|
|
3632
|
-
top:
|
|
3633
|
-
width:
|
|
3634
|
-
height:
|
|
3635
|
-
border-radius:
|
|
3691
|
+
top: 3px;
|
|
3692
|
+
width: 2px;
|
|
3693
|
+
height: 12px;
|
|
3694
|
+
border-radius: 1px;
|
|
3636
3695
|
background: var(--dsw-alias-state-business-primary);
|
|
3637
|
-
transform: translate(-50%, -50%);
|
|
3638
3696
|
}
|
|
3639
3697
|
|
|
3640
3698
|
/* ----------------------------------------------------------------- models */
|
|
@@ -3713,29 +3771,53 @@ window.__ModuleLoader__.load({
|
|
|
3713
3771
|
}
|
|
3714
3772
|
.qdp-sliderField {
|
|
3715
3773
|
position: relative;
|
|
3716
|
-
display: flex;
|
|
3717
|
-
flex-direction: column;
|
|
3718
|
-
gap: 2px;
|
|
3719
3774
|
min-width: 0;
|
|
3720
3775
|
}
|
|
3721
3776
|
.qdp-windowTicks {
|
|
3722
|
-
position:
|
|
3777
|
+
position: absolute;
|
|
3778
|
+
top: 40px;
|
|
3779
|
+
right: 0;
|
|
3780
|
+
left: 0;
|
|
3723
3781
|
height: 12px;
|
|
3724
|
-
|
|
3782
|
+
pointer-events: none;
|
|
3783
|
+
}
|
|
3784
|
+
/* Hairline ruler under the rail: 33 marks across the field, every eighth one
|
|
3785
|
+
taller and a step darker, matching the official scale. */
|
|
3786
|
+
.qdp-windowTickMark {
|
|
3787
|
+
position: absolute;
|
|
3788
|
+
top: 50%;
|
|
3789
|
+
width: 1px;
|
|
3790
|
+
height: 6px;
|
|
3791
|
+
border-radius: 999px;
|
|
3792
|
+
background: var(--dsw-alias-border-l2);
|
|
3793
|
+
transform: translate(-50%, -50%);
|
|
3725
3794
|
}
|
|
3795
|
+
.qdp-windowTickMarkMajor {
|
|
3796
|
+
height: 8px;
|
|
3797
|
+
background: var(--dsw-alias-border-l3);
|
|
3798
|
+
}
|
|
3799
|
+
/* Tier labels sit on the field colour so the ruler passes behind them. */
|
|
3726
3800
|
.qdp-windowTick {
|
|
3727
3801
|
position: absolute;
|
|
3728
|
-
|
|
3802
|
+
top: 50%;
|
|
3803
|
+
padding: 0 4px;
|
|
3804
|
+
background: var(--dsw-alias-settings-card-fill);
|
|
3729
3805
|
font: var(--dsw-font-xxxs-11);
|
|
3806
|
+
font-size: 9px;
|
|
3807
|
+
line-height: 12px;
|
|
3730
3808
|
color: var(--dsw-alias-label-tertiary);
|
|
3731
3809
|
font-variant-numeric: tabular-nums;
|
|
3732
3810
|
white-space: nowrap;
|
|
3733
3811
|
}
|
|
3734
|
-
|
|
3735
|
-
|
|
3812
|
+
/* The window in force is the only dark number: the other tiers are offers the
|
|
3813
|
+
user has not selected, so they keep the tertiary (grey) tone. */
|
|
3814
|
+
.qdp-windowTickActive {
|
|
3815
|
+
color: var(--dsw-alias-label-primary);
|
|
3816
|
+
font-weight: 500;
|
|
3736
3817
|
}
|
|
3737
|
-
.
|
|
3738
|
-
|
|
3818
|
+
/* A disabled slider greys every label, the active one included. */
|
|
3819
|
+
.qdp-slider[aria-disabled='true'] .qdp-windowTick {
|
|
3820
|
+
color: var(--dsw-alias-label-caption);
|
|
3739
3821
|
}
|
|
3740
3822
|
|
|
3741
3823
|
/* --------------------------------------------------------------- save bar */
|
|
@@ -4223,6 +4305,7 @@ window.__ModuleLoader__.load({
|
|
|
4223
4305
|
effortHigh: "high",
|
|
4224
4306
|
effortXhigh: "xhigh",
|
|
4225
4307
|
effortMax: "max",
|
|
4308
|
+
effortsUnsupported: "not supported",
|
|
4226
4309
|
accountCurrent: "In use",
|
|
4227
4310
|
creditsRemaining: "Remaining credit",
|
|
4228
4311
|
checkInStatus: "Check-in",
|
|
@@ -4426,14 +4509,15 @@ window.__ModuleLoader__.load({
|
|
|
4426
4509
|
quotaReadoutEnabledLabel: "在对话框显示积分",
|
|
4427
4510
|
quotaReadoutEnabledDesc: "在输入框工具条上显示剩余积分标签,点击可展开明细面板。",
|
|
4428
4511
|
checkInTime: "签到时间",
|
|
4429
|
-
modelEfforts: "
|
|
4430
|
-
modelEffortsDefault: "
|
|
4431
|
-
effortMinimal: "
|
|
4432
|
-
effortLow: "
|
|
4433
|
-
effortMedium: "
|
|
4434
|
-
effortHigh: "
|
|
4435
|
-
effortXhigh: "
|
|
4436
|
-
effortMax: "
|
|
4512
|
+
modelEfforts: "Efforts: {levels}",
|
|
4513
|
+
modelEffortsDefault: "default {name}",
|
|
4514
|
+
effortMinimal: "minimal",
|
|
4515
|
+
effortLow: "low",
|
|
4516
|
+
effortMedium: "medium",
|
|
4517
|
+
effortHigh: "high",
|
|
4518
|
+
effortXhigh: "xhigh",
|
|
4519
|
+
effortMax: "max",
|
|
4520
|
+
effortsUnsupported: "not supported",
|
|
4437
4521
|
accountCurrent: "当前使用",
|
|
4438
4522
|
creditsRemaining: "剩余积分",
|
|
4439
4523
|
checkInStatus: "签到状态",
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as QODER_AUTH_PATH, B as QoderCredentialStore, C as PROBE_EFFORT_CANDIDATES, D as qoderCatalogPath, E as QoderCatalogStore, F as QODER_SETTINGS_FACE_PATH, G as QODER_DATA_DIR_NAME, H as qoderCredentialIdentity, I as QODER_STATUS_PATH, J as qoderStateDir, K as qoderMachineIdPath, L as QODER_AUTH_FILENAME, M as QODER_GLOBAL_PROBE_PATH, N as QODER_GLOBAL_STATUS_PATH, O as FALLBACK_QODER_MODELS, P as QODER_PROBE_PATH, R as QODER_PAT_ENV_CN, S as getMachineId, T as randomSentinel, U as qoderOwnAuthPath, V as patTail, W as QODER_DATA_DIR_ENV, _ as modelInfoOf, a as QODER_HOST_HEARTBEAT_FILENAME, b as createQoderTransport, c as processStartTimeMs, d as writeHostHeartbeat, f as QODER_CONNECT_VERSION, g as kindFromQoderFailure, h as classifyUpstreamError, i as variantFor, j as QODER_GLOBAL_AUTH_PATH, k as QoderCatalog, l as qoderHostHeartbeatPath, m as QoderUpstreamClient, n as GLOBAL_VARIANT, o as clearHostHeartbeat, p as KIND_STATUS, q as qoderPluginDataDir, r as QODER_VARIANTS, s as isHeartbeatProcessAlive, t as CHINA_VARIANT, u as readHostHeartbeat, v as normalizeCredits, w as probeModel, x as getClaimWindowDateString, y as validateApiKey, z as QODER_PAT_ENV_GLOBAL } from "./variants-
|
|
1
|
+
import { A as QODER_AUTH_PATH, B as QoderCredentialStore, C as PROBE_EFFORT_CANDIDATES, D as qoderCatalogPath, E as QoderCatalogStore, F as QODER_SETTINGS_FACE_PATH, G as QODER_DATA_DIR_NAME, H as qoderCredentialIdentity, I as QODER_STATUS_PATH, J as qoderStateDir, K as qoderMachineIdPath, L as QODER_AUTH_FILENAME, M as QODER_GLOBAL_PROBE_PATH, N as QODER_GLOBAL_STATUS_PATH, O as FALLBACK_QODER_MODELS, P as QODER_PROBE_PATH, R as QODER_PAT_ENV_CN, S as getMachineId, T as randomSentinel, U as qoderOwnAuthPath, V as patTail, W as QODER_DATA_DIR_ENV, _ as modelInfoOf, a as QODER_HOST_HEARTBEAT_FILENAME, b as createQoderTransport, c as processStartTimeMs, d as writeHostHeartbeat, f as QODER_CONNECT_VERSION, g as kindFromQoderFailure, h as classifyUpstreamError, i as variantFor, j as QODER_GLOBAL_AUTH_PATH, k as QoderCatalog, l as qoderHostHeartbeatPath, m as QoderUpstreamClient, n as GLOBAL_VARIANT, o as clearHostHeartbeat, p as KIND_STATUS, q as qoderPluginDataDir, r as QODER_VARIANTS, s as isHeartbeatProcessAlive, t as CHINA_VARIANT, u as readHostHeartbeat, v as normalizeCredits, w as probeModel, x as getClaimWindowDateString, y as validateApiKey, z as QODER_PAT_ENV_GLOBAL } from "./variants-CATiqb4o.js";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -4767,7 +4767,7 @@ const DEFAULT_MAX_TOKENS = 32768;
|
|
|
4767
4767
|
const DEFAULT_CONTEXT_WINDOW = 18e4;
|
|
4768
4768
|
//#endregion
|
|
4769
4769
|
//#region src/version.ts
|
|
4770
|
-
const QODER_CONNECT_VERSION = "0.6.
|
|
4770
|
+
const QODER_CONNECT_VERSION = "0.6.3";
|
|
4771
4771
|
//#endregion
|
|
4772
4772
|
//#region src/host-heartbeat.ts
|
|
4773
4773
|
/**
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-qoder-plugin",
|
|
3
3
|
"displayName": "dsh-qoder-plugin",
|
|
4
4
|
"description": "把 Qoder 模型接入 DeepSeek Harness:用 PAT 调用与 Qoder CLI 同源的模型服务,支持国内版 / 国际版双区域、模型开关、上下文窗口与每日签到,并提供只读的额度概览。",
|
|
5
|
-
"version": "0.6.
|
|
5
|
+
"version": "0.6.3",
|
|
6
6
|
"author": "corrinehu",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"dsh-plugin",
|