@bivy/bivy 0.10.1-staging.367 → 0.10.1-staging.369
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.
|
@@ -72,6 +72,21 @@ const FALLBACK_MODELS = [
|
|
|
72
72
|
{ provider: "anthropic", id: "claude-sonnet-5", name: "Claude Sonnet 5", reasoning: true },
|
|
73
73
|
{ provider: "anthropic", id: "claude-haiku-4-5-20251001", name: "Claude Haiku 4.5", reasoning: true },
|
|
74
74
|
];
|
|
75
|
+
// The SDK's supportedModels() labels each row with a bare family+version
|
|
76
|
+
// ("Opus 4.8") or a family alias ("Sonnet", "Haiku") — while a not-yet-started
|
|
77
|
+
// session's picker uses FALLBACK_MODELS' product names ("Claude Opus 4.8"). That
|
|
78
|
+
// left a running session's picker showing a differently-named catalog than a
|
|
79
|
+
// fresh one. Brand the live rows to match by prefixing "Claude " to any known
|
|
80
|
+
// family label, so the catalog reads the same before and after a session starts.
|
|
81
|
+
// The family list is data — a new lineup means adding a row here, not an `if` —
|
|
82
|
+
// and branding derives from the SDK's own labels so the list never goes stale.
|
|
83
|
+
const CLAUDE_MODEL_FAMILIES = ["Opus", "Sonnet", "Haiku", "Fable", "Mythos"];
|
|
84
|
+
function brandClaudeModel(model) {
|
|
85
|
+
if (model.name.startsWith("Claude "))
|
|
86
|
+
return model;
|
|
87
|
+
const family = CLAUDE_MODEL_FAMILIES.find((f) => model.name === f || model.name.startsWith(`${f} `));
|
|
88
|
+
return family ? { ...model, name: `Claude ${model.name}` } : model;
|
|
89
|
+
}
|
|
75
90
|
/**
|
|
76
91
|
* Appended to the Claude Code system prompt so the agent DISCOVERS the outbound
|
|
77
92
|
* attachment capability. `bivy attach` is just a shell command — without this the
|
|
@@ -874,13 +889,42 @@ class ClaudeSession {
|
|
|
874
889
|
const q = sdk.query({ prompt: this.input, options });
|
|
875
890
|
this.query = q;
|
|
876
891
|
void this.consume(q);
|
|
877
|
-
// Best-effort:
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
892
|
+
// Best-effort: warm the model picker once the agent is up. getModels()
|
|
893
|
+
// re-queries on every call too, so a long-running session's list never
|
|
894
|
+
// freezes on whatever the query reported at spawn.
|
|
895
|
+
void this.refreshSupportedModels();
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Re-read the live query's authoritative model list and brand each row to the
|
|
899
|
+
* product's naming. Called from getModels() (and once at spawn) so the picker
|
|
900
|
+
* reflects the current lineup rather than the set captured when the query
|
|
901
|
+
* first spawned — a long session used to keep a stale catalog. Best-effort:
|
|
902
|
+
* on any failure (query torn down mid-reload, or an SDK build without the
|
|
903
|
+
* call) it leaves the last-known list in place.
|
|
904
|
+
*/
|
|
905
|
+
async refreshSupportedModels() {
|
|
906
|
+
const q = this.query;
|
|
907
|
+
if (!q || typeof q.supportedModels !== "function")
|
|
908
|
+
return;
|
|
909
|
+
// Bound the wait: supportedModels() resolves instantly once the query has
|
|
910
|
+
// initialized, but getModels() is on the models.list request path, so a
|
|
911
|
+
// hung subprocess must not freeze the picker — fall back to the last-known
|
|
912
|
+
// list (or FALLBACK_MODELS) instead of blocking.
|
|
913
|
+
let timer;
|
|
914
|
+
try {
|
|
915
|
+
const models = await Promise.race([
|
|
916
|
+
q.supportedModels(),
|
|
917
|
+
new Promise((resolve) => { timer = setTimeout(() => resolve(undefined), 1500); }),
|
|
918
|
+
]);
|
|
919
|
+
if (Array.isArray(models) && models.length)
|
|
920
|
+
this.models = models.map((m) => brandClaudeModel(toModelInfo(m)));
|
|
921
|
+
}
|
|
922
|
+
catch {
|
|
923
|
+
// Keep the last-known list (getModels() falls back to FALLBACK_MODELS if empty).
|
|
924
|
+
}
|
|
925
|
+
finally {
|
|
926
|
+
if (timer)
|
|
927
|
+
clearTimeout(timer);
|
|
884
928
|
}
|
|
885
929
|
}
|
|
886
930
|
/**
|
|
@@ -1281,9 +1325,12 @@ class ClaudeSession {
|
|
|
1281
1325
|
}
|
|
1282
1326
|
this.emitter.removeAllListeners();
|
|
1283
1327
|
}
|
|
1284
|
-
getModels() {
|
|
1285
|
-
//
|
|
1286
|
-
//
|
|
1328
|
+
async getModels() {
|
|
1329
|
+
// Re-query the live agent so the picker reflects the current lineup instead
|
|
1330
|
+
// of the set captured when the query first spawned. Before the query is up
|
|
1331
|
+
// (or if supportedModels() failed/returned nothing) fall back to the known
|
|
1332
|
+
// lineup so the picker is never empty.
|
|
1333
|
+
await this.refreshSupportedModels();
|
|
1287
1334
|
return this.models.length ? this.models : FALLBACK_MODELS;
|
|
1288
1335
|
}
|
|
1289
1336
|
getCurrentModel() {
|
package/package.json
CHANGED