mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
* fix(native-chat): keep a Claude chat's effort changeable after its first turn After its first turn a Claude chat saves the model id Claude reports it ran (claude-opus-5-5), while the model list names that model only by its alias (opus). Every capability lookup matched on the row id, so the chat's model had no effort choices and effort turned into display-only text on desktop and phone. A listed row now describes a model id by its own id or by the model it resolves to. The match supplies capabilities only; the chat keeps showing and sending the exact model it ran, so it never drifts when the alias moves. The host applies the same rule to the row it adds for the chat's model, for clients that read the answer's models. * test(native-chat): cover exact-row precedence for a described model id * fix(native-chat): remember an after-reply effort without changing the new-chat model An effort pick in a chat on the resolved id it ran is remembered under the listed row that runs that model and leaves the new-chat model untouched, as the common pattern keeps the sticky model and updates only its options. The resolved id is never stored as a default. * refactor(native-chat): move the remembered-pick model choice into its own module * fix(native-chat): keep a held effort pick from adopting a new-chat model * test(native-chat): run the held-effort case as a Claude launch * revert(native-chat): drop the host-side capability copy no live answer can use Claude's live session listing carries no resolvedModel, so the host never matched there, and phones draw the host-served chat bundle, so every client already runs the shared lookup. * Key Claude's model rows by the model each one runs Claude's listing named rows by alias (opus), while a chat saves the model it ran (claude-opus-5-5) after its first turn, so equivalent chats held two kinds of model value and a chat's effort could go read-only. Rows are now keyed by the versioned model they run, the common pattern: a pick saves the same id the CLI reports. Aliases stay as their own rows with their own effort levels; the picker lists one only while the chat is on it or a search matches it, and the phone list leaves them out. A saved alias is kept as the user picked it. A configured alias default marks the versioned row it runs, and an effort picked in an existing or resumed chat no longer changes the model new chats start on, whatever ids the chat and listing use. * test: give the delayed-report alias test's timeout its reason * Remember a new chat's picks by its first turn, and keep aliases reachable everywhere - A chat counts as existing once it has a turn or a send, or when it was opened rather than launched here, not once its launch published: an empty new chat's effort pick adopts its model for new chats again, and every agent's existing chat keeps the remembered new-chat model. - Only a row that names itself as the model it runs covers an alias, so an older host's alias rows stay listed beside a chat's stand-in row. - The phone lists an alias of a listed model behind a More models toggle. - The terminal-chat and commit-message model lists carry each row's resolvedModel, so they list aliases the same way; an older remote that omits it keeps its full list. * fix(mobile): keep the More models toggle's state without an effect reset * Keep commit-message aliases selectable and their resolved model out of saved settings The Source Control model Select has no search, so it lists alias rows after the versioned ones instead of hiding them. Discovered models are saved without an alias row's resolvedModel, and the refresh compares that same saved shape, so the settings cache gains no field. * Drop an unrelated audit-tools lockfile change; reset the phone's More models toggle when its drawer closes * test: build the saved-models test's settings without a cast
13 lines
551 B
TypeScript
13 lines
551 B
TypeScript
type ListedRow = { id: string; resolvedModel?: string | null }
|
|
|
|
/** An alias row whose versioned row the same list holds: reachable by search, not listed beside it.
|
|
* Only a row naming itself as the model it runs counts; a chat's stand-in row for its own id does not. */
|
|
export function isCoveredModelAlias(model: ListedRow, models: readonly ListedRow[]): boolean {
|
|
const resolved = model.resolvedModel
|
|
return (
|
|
!!resolved &&
|
|
resolved !== model.id &&
|
|
models.some((row) => row.id === resolved && row.resolvedModel === resolved)
|
|
)
|
|
}
|