dsh-plugin-subscription-oauth 0.8.15 → 0.8.17
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/auth/provider-controller.js +14 -8
- package/lib/client/FastModeButton.d.ts +4 -3
- package/lib/client/FastModeButton.js +11 -8
- package/lib/client.js +11 -7
- package/lib/client.js.map +1 -1
- package/lib/providers/grok.js +39 -25
- package/lib/providers/kimi.js +42 -30
- package/package.json +1 -1
|
@@ -300,20 +300,26 @@ export class ProviderController {
|
|
|
300
300
|
// every startup would be noise.
|
|
301
301
|
if (!await this.options.store.hasAny())
|
|
302
302
|
return this.status();
|
|
303
|
-
// Discovery
|
|
304
|
-
//
|
|
305
|
-
//
|
|
306
|
-
// Only an explicit user action (the connect button) opens the consent page.
|
|
303
|
+
// Discovery reads the live catalog on startup so the picker shows what the account
|
|
304
|
+
// actually serves without a manual refresh. A resolve must never open the browser:
|
|
305
|
+
// a refresh failure is recorded as the route's last error, never as a login prompt.
|
|
307
306
|
const discovered = [];
|
|
308
307
|
for (const account of Object.keys(await this.options.store.list())) {
|
|
308
|
+
// An unexpired token is used as-is; a lapsed one is refreshed in memory so the
|
|
309
|
+
// catalog still loads on startup. The refreshed token is not written back to the
|
|
310
|
+
// store here — a durable renewal still happens on the next real request.
|
|
309
311
|
let session = await this.options.store.get(account);
|
|
310
312
|
if (session === undefined)
|
|
311
313
|
continue;
|
|
312
|
-
// A token that is still within its stored expiry is used as-is; a lapsed one
|
|
313
|
-
// is a silent skip (the route works, the catalog is just not refreshed).
|
|
314
314
|
if (session.expiresAt <= Date.now()) {
|
|
315
|
-
|
|
316
|
-
|
|
315
|
+
try {
|
|
316
|
+
const refreshed = await this.options.tokens.resolve(account, true);
|
|
317
|
+
session = { ...session, accessToken: refreshed.accessToken, expiresAt: refreshed.expiresAt };
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
this.options.onWarn?.(`${spec.id} model discovery for ${account} skipped: token refresh failed`);
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
317
323
|
}
|
|
318
324
|
const ids = await spec.discover(session.accessToken);
|
|
319
325
|
if (ids !== undefined) {
|
|
@@ -30,14 +30,15 @@ export interface FastModeButtonInjected {
|
|
|
30
30
|
/**
|
|
31
31
|
* The session's model directory, when the host exposes one.
|
|
32
32
|
*
|
|
33
|
-
* Written when the button switches
|
|
34
|
-
*
|
|
33
|
+
* Written when the button switches the model's `fast` rung. Absent on a host without
|
|
34
|
+
* it, in which case the button renders nothing.
|
|
35
35
|
*/
|
|
36
36
|
modelDirectory?: {
|
|
37
|
-
/** Select one model; resolves when the picker
|
|
37
|
+
/** Select one model and its reasoning rung; resolves when the picker accepted it. */
|
|
38
38
|
select?: (selection: {
|
|
39
39
|
provider: string;
|
|
40
40
|
model: string;
|
|
41
|
+
reasoningEffort?: string;
|
|
41
42
|
}) => Promise<unknown>;
|
|
42
43
|
} | undefined;
|
|
43
44
|
}
|
|
@@ -57,16 +57,16 @@ export function FastModeButton({ call, isOwnProvider, modelDirectory, useProject
|
|
|
57
57
|
}, [provider, model, isOwnProvider, call]);
|
|
58
58
|
// A switch that landed clears the reason, so the marker follows the truth on screen.
|
|
59
59
|
useEffect(() => { setFailure(undefined); }, [model]);
|
|
60
|
-
if (pair === undefined || provider === undefined || modelDirectory?.select === undefined)
|
|
61
|
-
return null;
|
|
62
|
-
const active = pair.wireId === model;
|
|
63
|
-
const target = active ? pair.baseId : pair.wireId;
|
|
64
|
-
// Active without a base to return to would be a control that cannot switch anything off.
|
|
65
|
-
if (target === undefined || target === model)
|
|
60
|
+
if (pair === undefined || provider === undefined || model === undefined || modelDirectory?.select === undefined)
|
|
66
61
|
return null;
|
|
62
|
+
// Fast mode is the row's `fast` reasoning rung, so the model id never changes and the
|
|
63
|
+
// picker always shows the row the user can switch back to.
|
|
64
|
+
const active = (selection?.next ?? selection?.lastUsed)?.reasoningEffort === 'fast';
|
|
65
|
+
// The row the rung belongs to: what the picker selected, or the pair's own base.
|
|
66
|
+
const target = model;
|
|
67
67
|
const base = active
|
|
68
68
|
? 'Fast mode is on; press to go back to the standard model'
|
|
69
|
-
: 'Fast mode: switch to
|
|
69
|
+
: 'Fast mode: switch to this model’s fast variant';
|
|
70
70
|
const title = failure === undefined
|
|
71
71
|
? base
|
|
72
72
|
: `${base}\nThe switch was refused — ${`${failure.code ?? ''} ${failure.message}`.trim()}`;
|
|
@@ -74,7 +74,10 @@ export function FastModeButton({ call, isOwnProvider, modelDirectory, useProject
|
|
|
74
74
|
event.stopPropagation();
|
|
75
75
|
setPending(true);
|
|
76
76
|
setFailure(undefined);
|
|
77
|
-
|
|
77
|
+
// Turning it off drops the rung, which the host then reads as the model's own
|
|
78
|
+
// default. The model id is never swapped, so this cannot strand the selection.
|
|
79
|
+
const next = active ? { provider, model: target } : { provider, model: target, reasoningEffort: 'fast' };
|
|
80
|
+
void Promise.resolve(modelDirectory.select?.(next))
|
|
78
81
|
.then((result) => {
|
|
79
82
|
// The directory reports its own outcome: a refused selection carries why.
|
|
80
83
|
const outcome = result;
|
package/lib/client.js
CHANGED
|
@@ -2815,11 +2815,10 @@ function FastModeButton({ call, isOwnProvider, modelDirectory, useProjection })
|
|
|
2815
2815
|
(0, react.useEffect)(() => {
|
|
2816
2816
|
setFailure(void 0);
|
|
2817
2817
|
}, [model]);
|
|
2818
|
-
if (pair === void 0 || provider === void 0 || modelDirectory?.select === void 0) return null;
|
|
2819
|
-
const active =
|
|
2820
|
-
const target =
|
|
2821
|
-
|
|
2822
|
-
const base = active ? "Fast mode is on; press to go back to the standard model" : "Fast mode: switch to the fast variant of this model";
|
|
2818
|
+
if (pair === void 0 || provider === void 0 || model === void 0 || modelDirectory?.select === void 0) return null;
|
|
2819
|
+
const active = (selection?.next ?? selection?.lastUsed)?.reasoningEffort === "fast";
|
|
2820
|
+
const target = model;
|
|
2821
|
+
const base = active ? "Fast mode is on; press to go back to the standard model" : "Fast mode: switch to this model’s fast variant";
|
|
2823
2822
|
const title = failure === void 0 ? base : `${base}\nThe switch was refused — ${`${failure.code ?? ""} ${failure.message}`.trim()}`;
|
|
2824
2823
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: fastModeCss }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2825
2824
|
type: "button",
|
|
@@ -2835,10 +2834,15 @@ function FastModeButton({ call, isOwnProvider, modelDirectory, useProjection })
|
|
|
2835
2834
|
event.stopPropagation();
|
|
2836
2835
|
setPending(true);
|
|
2837
2836
|
setFailure(void 0);
|
|
2838
|
-
|
|
2837
|
+
const next = active ? {
|
|
2839
2838
|
provider,
|
|
2840
2839
|
model: target
|
|
2841
|
-
}
|
|
2840
|
+
} : {
|
|
2841
|
+
provider,
|
|
2842
|
+
model: target,
|
|
2843
|
+
reasoningEffort: "fast"
|
|
2844
|
+
};
|
|
2845
|
+
Promise.resolve(modelDirectory.select?.(next)).then((result) => {
|
|
2842
2846
|
const outcome = result;
|
|
2843
2847
|
if (outcome?.ok !== false) return;
|
|
2844
2848
|
const code = outcome.error?.code;
|