mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-20 13:02:15 +00:00
fix: use consistent model comparison including provider
This commit is contained in:
parent
64e7c80c7e
commit
a7efe3d4c1
5 changed files with 25 additions and 17 deletions
|
|
@ -54,3 +54,15 @@ const XHIGH_MODELS = new Set(["gpt-5.1-codex-max", "gpt-5.2", "gpt-5.2-codex"]);
|
||||||
export function supportsXhigh<TApi extends Api>(model: Model<TApi>): boolean {
|
export function supportsXhigh<TApi extends Api>(model: Model<TApi>): boolean {
|
||||||
return XHIGH_MODELS.has(model.id);
|
return XHIGH_MODELS.has(model.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if two models are equal by comparing both their id and provider.
|
||||||
|
* Returns false if either model is null or undefined.
|
||||||
|
*/
|
||||||
|
export function modelsAreEqual<TApi extends Api>(
|
||||||
|
a: Model<TApi> | null | undefined,
|
||||||
|
b: Model<TApi> | null | undefined,
|
||||||
|
): boolean {
|
||||||
|
if (!a || !b) return false;
|
||||||
|
return a.id === b.id && a.provider === b.provider;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
import type { Agent, AgentEvent, AgentState, AppMessage, Attachment, ThinkingLevel } from "@mariozechner/pi-agent-core";
|
import type { Agent, AgentEvent, AgentState, AppMessage, Attachment, ThinkingLevel } from "@mariozechner/pi-agent-core";
|
||||||
import type { AssistantMessage, Message, Model, TextContent } from "@mariozechner/pi-ai";
|
import type { AssistantMessage, Message, Model, TextContent } from "@mariozechner/pi-ai";
|
||||||
import { isContextOverflow, supportsXhigh } from "@mariozechner/pi-ai";
|
import { isContextOverflow, modelsAreEqual, supportsXhigh } from "@mariozechner/pi-ai";
|
||||||
import { getModelsPath } from "../config.js";
|
import { getModelsPath } from "../config.js";
|
||||||
import { type BashResult, executeBash as executeBashCommand } from "./bash-executor.js";
|
import { type BashResult, executeBash as executeBashCommand } from "./bash-executor.js";
|
||||||
import { calculateContextTokens, compact, prepareCompaction, shouldCompact } from "./compaction.js";
|
import { calculateContextTokens, compact, prepareCompaction, shouldCompact } from "./compaction.js";
|
||||||
|
|
@ -596,9 +596,7 @@ export class AgentSession {
|
||||||
if (this._scopedModels.length <= 1) return null;
|
if (this._scopedModels.length <= 1) return null;
|
||||||
|
|
||||||
const currentModel = this.model;
|
const currentModel = this.model;
|
||||||
let currentIndex = this._scopedModels.findIndex(
|
let currentIndex = this._scopedModels.findIndex((sm) => modelsAreEqual(sm.model, currentModel));
|
||||||
(sm) => sm.model.id === currentModel?.id && sm.model.provider === currentModel?.provider,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (currentIndex === -1) currentIndex = 0;
|
if (currentIndex === -1) currentIndex = 0;
|
||||||
const len = this._scopedModels.length;
|
const len = this._scopedModels.length;
|
||||||
|
|
@ -627,9 +625,7 @@ export class AgentSession {
|
||||||
if (availableModels.length <= 1) return null;
|
if (availableModels.length <= 1) return null;
|
||||||
|
|
||||||
const currentModel = this.model;
|
const currentModel = this.model;
|
||||||
let currentIndex = availableModels.findIndex(
|
let currentIndex = availableModels.findIndex((m) => modelsAreEqual(m, currentModel));
|
||||||
(m) => m.id === currentModel?.id && m.provider === currentModel?.provider,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (currentIndex === -1) currentIndex = 0;
|
if (currentIndex === -1) currentIndex = 0;
|
||||||
const len = availableModels.length;
|
const len = availableModels.length;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ThinkingLevel } from "@mariozechner/pi-agent-core";
|
import type { ThinkingLevel } from "@mariozechner/pi-agent-core";
|
||||||
import type { Api, KnownProvider, Model } from "@mariozechner/pi-ai";
|
import { type Api, type KnownProvider, type Model, modelsAreEqual } from "@mariozechner/pi-ai";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { isValidThinkingLevel } from "../cli/args.js";
|
import { isValidThinkingLevel } from "../cli/args.js";
|
||||||
import type { ModelRegistry } from "./model-registry.js";
|
import type { ModelRegistry } from "./model-registry.js";
|
||||||
|
|
@ -184,7 +184,7 @@ export async function resolveModelScope(patterns: string[], modelRegistry: Model
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid duplicates
|
// Avoid duplicates
|
||||||
if (!scopedModels.find((sm) => sm.model.id === model.id && sm.model.provider === model.provider)) {
|
if (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {
|
||||||
scopedModels.push({ model, thinkingLevel });
|
scopedModels.push({ model, thinkingLevel });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import type { Model } from "@mariozechner/pi-ai";
|
import { type Model, modelsAreEqual } from "@mariozechner/pi-ai";
|
||||||
import {
|
import {
|
||||||
Container,
|
Container,
|
||||||
Input,
|
Input,
|
||||||
|
|
@ -143,8 +143,8 @@ export class ModelSelectorComponent extends Container {
|
||||||
|
|
||||||
// Sort: current model first, then by provider
|
// Sort: current model first, then by provider
|
||||||
models.sort((a, b) => {
|
models.sort((a, b) => {
|
||||||
const aIsCurrent = this.currentModel?.id === a.model.id && this.currentModel?.provider === a.provider;
|
const aIsCurrent = modelsAreEqual(this.currentModel, a.model);
|
||||||
const bIsCurrent = this.currentModel?.id === b.model.id && this.currentModel?.provider === b.provider;
|
const bIsCurrent = modelsAreEqual(this.currentModel, b.model);
|
||||||
if (aIsCurrent && !bIsCurrent) return -1;
|
if (aIsCurrent && !bIsCurrent) return -1;
|
||||||
if (!aIsCurrent && bIsCurrent) return 1;
|
if (!aIsCurrent && bIsCurrent) return 1;
|
||||||
return a.provider.localeCompare(b.provider);
|
return a.provider.localeCompare(b.provider);
|
||||||
|
|
@ -176,7 +176,7 @@ export class ModelSelectorComponent extends Container {
|
||||||
if (!item) continue;
|
if (!item) continue;
|
||||||
|
|
||||||
const isSelected = i === this.selectedIndex;
|
const isSelected = i === this.selectedIndex;
|
||||||
const isCurrent = this.currentModel?.id === item.model.id;
|
const isCurrent = modelsAreEqual(this.currentModel, item.model);
|
||||||
|
|
||||||
let line = "";
|
let line = "";
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { Badge } from "@mariozechner/mini-lit/dist/Badge.js";
|
||||||
import { Button } from "@mariozechner/mini-lit/dist/Button.js";
|
import { Button } from "@mariozechner/mini-lit/dist/Button.js";
|
||||||
import { DialogHeader } from "@mariozechner/mini-lit/dist/Dialog.js";
|
import { DialogHeader } from "@mariozechner/mini-lit/dist/Dialog.js";
|
||||||
import { DialogBase } from "@mariozechner/mini-lit/dist/DialogBase.js";
|
import { DialogBase } from "@mariozechner/mini-lit/dist/DialogBase.js";
|
||||||
import { getModels, getProviders, type Model } from "@mariozechner/pi-ai";
|
import { getModels, getProviders, type Model, modelsAreEqual } from "@mariozechner/pi-ai";
|
||||||
import { html, type PropertyValues, type TemplateResult } from "lit";
|
import { html, type PropertyValues, type TemplateResult } from "lit";
|
||||||
import { customElement, state } from "lit/decorators.js";
|
import { customElement, state } from "lit/decorators.js";
|
||||||
import { createRef, ref } from "lit/directives/ref.js";
|
import { createRef, ref } from "lit/directives/ref.js";
|
||||||
|
|
@ -195,8 +195,8 @@ export class ModelSelector extends DialogBase {
|
||||||
|
|
||||||
// Sort: current model first, then by provider
|
// Sort: current model first, then by provider
|
||||||
filteredModels.sort((a, b) => {
|
filteredModels.sort((a, b) => {
|
||||||
const aIsCurrent = this.currentModel?.id === a.model.id;
|
const aIsCurrent = modelsAreEqual(this.currentModel, a.model);
|
||||||
const bIsCurrent = this.currentModel?.id === b.model.id;
|
const bIsCurrent = modelsAreEqual(this.currentModel, b.model);
|
||||||
if (aIsCurrent && !bIsCurrent) return -1;
|
if (aIsCurrent && !bIsCurrent) return -1;
|
||||||
if (!aIsCurrent && bIsCurrent) return 1;
|
if (!aIsCurrent && bIsCurrent) return 1;
|
||||||
return a.provider.localeCompare(b.provider);
|
return a.provider.localeCompare(b.provider);
|
||||||
|
|
@ -270,7 +270,7 @@ export class ModelSelector extends DialogBase {
|
||||||
<!-- Scrollable model list -->
|
<!-- Scrollable model list -->
|
||||||
<div class="flex-1 overflow-y-auto" ${ref(this.scrollContainerRef)}>
|
<div class="flex-1 overflow-y-auto" ${ref(this.scrollContainerRef)}>
|
||||||
${filteredModels.map(({ provider, id, model }, index) => {
|
${filteredModels.map(({ provider, id, model }, index) => {
|
||||||
const isCurrent = this.currentModel?.id === model.id && this.currentModel?.provider === model.provider;
|
const isCurrent = modelsAreEqual(this.currentModel, model);
|
||||||
const isSelected = index === this.selectedIndex;
|
const isSelected = index === this.selectedIndex;
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue