dsh-plugin-subscription-oauth 0.17.2 → 0.17.4

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.
@@ -94,7 +94,11 @@ export function FastModeButton({ call, isOwnProvider, modelDirectory, useProject
94
94
  }, [provider, model, isOwnProvider, call]);
95
95
  // A switch that landed clears the reason, so the marker follows the truth on screen.
96
96
  useEffect(() => { setFailure(undefined); }, [model]);
97
- if (pair === undefined || provider === undefined || model === undefined || modelDirectory?.select === undefined)
97
+ // The button renders on the fast pair alone. The host's model directory can be a moment
98
+ // late (its `remote.session` dependency starts after the composer mounts), so gating
99
+ // rendering on the directory being ready here hid the button for the whole session.
100
+ // `modelDirectory.select` resolves the directory lazily on click instead.
101
+ if (pair === undefined || provider === undefined || model === undefined)
98
102
  return null;
99
103
  // Fast mode is the row's fast reasoning rung, so the model id never changes and the
100
104
  // picker always shows the row the user can switch back to.
@@ -113,7 +117,12 @@ export function FastModeButton({ call, isOwnProvider, modelDirectory, useProject
113
117
  // Turning it off drops the rung, which the host then reads as the model's own
114
118
  // default. The model id is never swapped, so this cannot strand the selection.
115
119
  const next = active ? { provider, model: target } : { provider, model: target, reasoningEffort: pair.rung };
116
- void Promise.resolve(modelDirectory.select?.(next))
120
+ if (modelDirectory?.select === undefined) {
121
+ setFailure({ message: 'the model directory is unavailable on this host' });
122
+ setPending(false);
123
+ return;
124
+ }
125
+ void Promise.resolve(modelDirectory.select(next))
117
126
  .then((result) => {
118
127
  // The directory reports its own outcome: a refused selection carries why.
119
128
  const outcome = result;
@@ -103,29 +103,41 @@ export function apply(ctx) {
103
103
  /**
104
104
  * The session's model directory, in the shape the quick-mode button writes through.
105
105
  *
106
- * Absent when the host exposes no directory for the session, or exposes one that cannot
107
- * select — in which case the button renders nothing rather than a dead control.
106
+ * The lookup is lazy: the returned `select` resolves the host's directory on first use,
107
+ * not at inject time. The host's `directoryFor` throws while its own `remote.session`
108
+ * dependency is still starting (observed on desktop), so resolving eagerly at mount hid
109
+ * the button for the whole session even though the directory became ready a moment later.
108
110
  *
109
111
  * @param modelDirectories - the host's directory resolver, when it has one.
110
112
  * @param sessionId - the session whose directory is wanted.
111
- * @returns the reader/writer pair, or undefined.
113
+ * @returns the writer, or undefined when there is no resolver or session at all.
112
114
  */
113
115
  function modelDirectoryFor(modelDirectories, sessionId) {
114
116
  if (sessionId === undefined || modelDirectories?.directoryFor === undefined)
115
117
  return undefined;
116
- // The host throws when the session has no directory yet (a fresh session, say); that is
117
- // a missing control, not a fault, so the button renders nothing instead of breaking the
118
- // whole composer.
119
- let directory;
120
- try {
121
- directory = modelDirectories.directoryFor(sessionId);
122
- }
123
- catch {
124
- return undefined;
125
- }
126
- if (directory?.select === undefined)
127
- return undefined;
118
+ // A lazily-resolved select: the first call walks the host's directory; a throw there is
119
+ // a transient startup miss, so it is retried once after a short beat before failing.
128
120
  return {
129
- select: (selection) => directory.select?.(selection) ?? Promise.resolve(),
121
+ select: async (selection) => {
122
+ const resolve = () => modelDirectories.directoryFor?.(sessionId);
123
+ let directory = (() => { try {
124
+ return resolve();
125
+ }
126
+ catch {
127
+ return undefined;
128
+ } })();
129
+ if (directory?.select === undefined) {
130
+ await new Promise((resolveWait) => setTimeout(resolveWait, 500));
131
+ try {
132
+ directory = resolve();
133
+ }
134
+ catch {
135
+ directory = undefined;
136
+ }
137
+ }
138
+ if (directory?.select === undefined)
139
+ throw new Error('the model directory is not available yet; try again');
140
+ return directory.select(selection);
141
+ },
130
142
  };
131
143
  }
package/lib/client.js CHANGED
@@ -3123,7 +3123,7 @@ function FastModeButton({ call, isOwnProvider, modelDirectory, useProjection })
3123
3123
  (0, react.useEffect)(() => {
3124
3124
  setFailure(void 0);
3125
3125
  }, [model]);
3126
- if (pair === void 0 || provider === void 0 || model === void 0 || modelDirectory?.select === void 0) return null;
3126
+ if (pair === void 0 || provider === void 0 || model === void 0) return null;
3127
3127
  const active = (selection?.next ?? selection?.lastUsed)?.reasoningEffort === pair.rung;
3128
3128
  const target = model;
3129
3129
  const base = active ? "Fast mode is on; press to go back to the standard model" : "Fast mode: switch to this model’s fast variant";
@@ -3150,7 +3150,12 @@ function FastModeButton({ call, isOwnProvider, modelDirectory, useProjection })
3150
3150
  model: target,
3151
3151
  reasoningEffort: pair.rung
3152
3152
  };
3153
- Promise.resolve(modelDirectory.select?.(next)).then((result) => {
3153
+ if (modelDirectory?.select === void 0) {
3154
+ setFailure({ message: "the model directory is unavailable on this host" });
3155
+ setPending(false);
3156
+ return;
3157
+ }
3158
+ Promise.resolve(modelDirectory.select(next)).then((result) => {
3154
3159
  const outcome = result;
3155
3160
  if (outcome?.ok !== false) return;
3156
3161
  const code = outcome.error?.code;
@@ -3286,23 +3291,37 @@ function apply(ctx) {
3286
3291
  /**
3287
3292
  * The session's model directory, in the shape the quick-mode button writes through.
3288
3293
  *
3289
- * Absent when the host exposes no directory for the session, or exposes one that cannot
3290
- * select — in which case the button renders nothing rather than a dead control.
3294
+ * The lookup is lazy: the returned `select` resolves the host's directory on first use,
3295
+ * not at inject time. The host's `directoryFor` throws while its own `remote.session`
3296
+ * dependency is still starting (observed on desktop), so resolving eagerly at mount hid
3297
+ * the button for the whole session even though the directory became ready a moment later.
3291
3298
  *
3292
3299
  * @param modelDirectories - the host's directory resolver, when it has one.
3293
3300
  * @param sessionId - the session whose directory is wanted.
3294
- * @returns the reader/writer pair, or undefined.
3301
+ * @returns the writer, or undefined when there is no resolver or session at all.
3295
3302
  */
3296
3303
  function modelDirectoryFor(modelDirectories, sessionId) {
3297
3304
  if (sessionId === void 0 || modelDirectories?.directoryFor === void 0) return void 0;
3298
- let directory;
3299
- try {
3300
- directory = modelDirectories.directoryFor(sessionId);
3301
- } catch {
3302
- return;
3303
- }
3304
- if (directory?.select === void 0) return void 0;
3305
- return { select: (selection) => directory.select?.(selection) ?? Promise.resolve() };
3305
+ return { select: async (selection) => {
3306
+ const resolve = () => modelDirectories.directoryFor?.(sessionId);
3307
+ let directory = (() => {
3308
+ try {
3309
+ return resolve();
3310
+ } catch {
3311
+ return;
3312
+ }
3313
+ })();
3314
+ if (directory?.select === void 0) {
3315
+ await new Promise((resolveWait) => setTimeout(resolveWait, 500));
3316
+ try {
3317
+ directory = resolve();
3318
+ } catch {
3319
+ directory = void 0;
3320
+ }
3321
+ }
3322
+ if (directory?.select === void 0) throw new Error("the model directory is not available yet; try again");
3323
+ return directory.select(selection);
3324
+ } };
3306
3325
  }
3307
3326
 
3308
3327
  //#endregion