mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-06 23:44:36 +00:00
fix(coding-agent): expose unavailable scoped models (#7032)
* fix(coding-agent): expose unavailable scoped models Keep missing configured models editable in the scoped-model selector. This fixes #6949. * fix(coding-agent): reuse model scope diagnostics * fix(coding-agent): classify model scope diagnostics
This commit is contained in:
parent
8eef62ed3e
commit
a3ee1d286e
6 changed files with 244 additions and 37 deletions
|
|
@ -36,7 +36,7 @@ function enableAll(enabledIds: EnabledIds, allIds: string[], targetIds?: string[
|
|||
for (const id of targets) {
|
||||
if (!result.includes(id)) result.push(id);
|
||||
}
|
||||
return result.length === allIds.length ? null : result;
|
||||
return result.length === allIds.length && result.every((id) => allIds.includes(id)) ? null : result;
|
||||
}
|
||||
|
||||
function clearAll(enabledIds: EnabledIds, allIds: string[], targetIds?: string[]): EnabledIds {
|
||||
|
|
@ -67,7 +67,7 @@ function getSortedIds(enabledIds: EnabledIds, allIds: string[]): string[] {
|
|||
|
||||
interface ModelItem {
|
||||
fullId: string;
|
||||
model: Model<any>;
|
||||
model: Model<any> | undefined;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
|
|
@ -152,20 +152,20 @@ export class ScopedModelsSelectorComponent extends Container implements Focusabl
|
|||
}
|
||||
|
||||
private buildItems(): ModelItem[] {
|
||||
// Filter out IDs that no longer have a corresponding model (e.g., after logout)
|
||||
return getSortedIds(this.enabledIds, this.allIds)
|
||||
.filter((id) => this.modelsById.has(id))
|
||||
.map((id) => ({
|
||||
fullId: id,
|
||||
model: this.modelsById.get(id)!,
|
||||
enabled: isEnabled(this.enabledIds, id),
|
||||
}));
|
||||
return getSortedIds(this.enabledIds, this.allIds).map((id) => ({
|
||||
fullId: id,
|
||||
model: this.modelsById.get(id),
|
||||
enabled: isEnabled(this.enabledIds, id),
|
||||
}));
|
||||
}
|
||||
|
||||
private getFooterText(): string {
|
||||
const enabledCount = this.enabledIds?.length ?? this.allIds.length;
|
||||
const enabledCount = this.enabledIds?.filter((id) => this.modelsById.has(id)).length ?? this.allIds.length;
|
||||
const unavailableCount = this.enabledIds?.filter((id) => !this.modelsById.has(id)).length ?? 0;
|
||||
const allEnabled = this.enabledIds === null;
|
||||
const countText = allEnabled ? "all enabled" : `${enabledCount}/${this.allIds.length} enabled`;
|
||||
const countText = allEnabled
|
||||
? "all enabled"
|
||||
: `${enabledCount}/${this.allIds.length} enabled${unavailableCount ? ` · ${unavailableCount} unavailable` : ""}`;
|
||||
const parts = [
|
||||
`${keyText("tui.select.confirm")} toggle`,
|
||||
`${keyText("app.models.enableAll")} all`,
|
||||
|
|
@ -184,8 +184,10 @@ export class ScopedModelsSelectorComponent extends Container implements Focusabl
|
|||
const query = this.searchInput.getValue();
|
||||
const items = this.buildItems();
|
||||
this.filteredItems = query
|
||||
? fuzzyFilter(items, query, (i) =>
|
||||
getModelSearchText({ id: i.model.id, provider: i.model.provider, name: i.model.name }),
|
||||
? fuzzyFilter(items, query, (item) =>
|
||||
item.model
|
||||
? getModelSearchText({ id: item.model.id, provider: item.model.provider, name: item.model.name })
|
||||
: item.fullId,
|
||||
)
|
||||
: items;
|
||||
this.selectedIndex = Math.min(this.selectedIndex, Math.max(0, this.filteredItems.length - 1));
|
||||
|
|
@ -216,9 +218,16 @@ export class ScopedModelsSelectorComponent extends Container implements Focusabl
|
|||
const item = this.filteredItems[i]!;
|
||||
const isSelected = i === this.selectedIndex;
|
||||
const prefix = isSelected ? theme.fg("accent", "→ ") : " ";
|
||||
const modelText = isSelected ? theme.fg("accent", item.model.id) : item.model.id;
|
||||
const providerBadge = theme.fg("muted", ` [${item.model.provider}]`);
|
||||
const status = allEnabled ? "" : item.enabled ? theme.fg("success", " ✓") : theme.fg("dim", " ✗");
|
||||
const id = item.model?.id ?? item.fullId;
|
||||
const modelText = isSelected ? theme.fg("accent", id) : id;
|
||||
const providerBadge = theme.fg("muted", item.model ? ` [${item.model.provider}]` : " [unavailable]");
|
||||
const status = item.model
|
||||
? allEnabled
|
||||
? ""
|
||||
: item.enabled
|
||||
? theme.fg("success", " ✓")
|
||||
: theme.fg("dim", " ✗")
|
||||
: theme.fg("dim", " ✗");
|
||||
this.listContainer.addChild(new Text(`${prefix}${modelText}${providerBadge}${status}`, 0, 0));
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +241,13 @@ export class ScopedModelsSelectorComponent extends Container implements Focusabl
|
|||
if (this.filteredItems.length > 0) {
|
||||
const selected = this.filteredItems[this.selectedIndex];
|
||||
this.listContainer.addChild(new Spacer(1));
|
||||
this.listContainer.addChild(new Text(theme.fg("muted", ` Model Name: ${selected.model.name}`), 0, 0));
|
||||
this.listContainer.addChild(
|
||||
new Text(
|
||||
theme.fg("muted", ` ${selected.model ? `Model Name: ${selected.model.name}` : "Model unavailable"}`),
|
||||
0,
|
||||
0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -310,7 +325,7 @@ export class ScopedModelsSelectorComponent extends Container implements Focusabl
|
|||
// Toggle provider of current item
|
||||
if (kb.matches(data, "app.models.toggleProvider")) {
|
||||
const item = this.filteredItems[this.selectedIndex];
|
||||
if (item) {
|
||||
if (item?.model) {
|
||||
const provider = item.model.provider;
|
||||
const providerIds = this.allIds.filter((id) => this.modelsById.get(id)!.provider === provider);
|
||||
const allEnabled = providerIds.every((id) => isEnabled(this.enabledIds, id));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue