mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 12:26:38 -06:00
fix(ui): use session-key equivalence for active-row lookups in model/thinking/fast-mode paths (#124020)
Six sites strict-compared row.key === sessionKey while the sibling locked check already used areUiSessionKeysEquivalent (#104045 upgraded only the model path). In alias/transition windows (pre-hello legacy 'main' vs canonical agent:main:main) the optimistic thinking/fast-mode row patch found no row — the click produced no immediate visible change — and the display resolvers missed the active row, falling back to agent defaults. All lookups now go through the equivalence helper the rest of the flow uses.
This commit is contained in:
committed by
GitHub
parent
ab8d7dbb21
commit
f24bd8a2a2
@@ -122,6 +122,25 @@ describe("chat-model-select-state", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("finds the active row across the legacy main alias window", () => {
|
||||
// Pre-hello (or legacy-alias) states select "main" while the row list
|
||||
// already carries the canonical agent:main:main key; a strict compare
|
||||
// missed the row and the picker fell back to the agent default.
|
||||
const sessionsResult = createSessionsListResult({
|
||||
model: "gpt-5.3-codex",
|
||||
modelProvider: "openai",
|
||||
});
|
||||
const session = expectDefined(sessionsResult.sessions[0], "alias fixture row");
|
||||
sessionsResult.sessions[0] = { ...session, key: "agent:main:main" };
|
||||
const value = resolveChatModelOverrideValue(
|
||||
createChatModelState({
|
||||
chatModelCatalog: DEFAULT_CHAT_MODEL_CATALOG,
|
||||
sessionsResult,
|
||||
}),
|
||||
);
|
||||
expect(value).toBe("openai/gpt-5.3-codex");
|
||||
});
|
||||
|
||||
it("uses the server-qualified value when the active session provider is present", () => {
|
||||
const state = createChatModelState({
|
||||
chatModelCatalog: createModelCatalog(DEEPSEEK_CHAT_MODEL),
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
SessionsListResult,
|
||||
} from "../../api/types.ts";
|
||||
import { t } from "../../i18n/index.ts";
|
||||
import { areUiSessionKeysEquivalent } from "../sessions/session-key.ts";
|
||||
import {
|
||||
buildCatalogDisplayLookup,
|
||||
buildChatModelOptionFromLookup,
|
||||
@@ -72,7 +73,9 @@ type ChatFastModeSelectStateInput = {
|
||||
const FAST_MODE_PROVIDER_IDS = new Set(["anthropic", "minimax", "minimax-portal", "openai", "xai"]);
|
||||
|
||||
function resolveActiveSessionRow(state: ChatModelSelectStateInput) {
|
||||
return state.sessionsResult?.sessions?.find((row) => row.key === state.sessionKey);
|
||||
return state.sessionsResult?.sessions?.find((row) =>
|
||||
areUiSessionKeysEquivalent(row.key, state.sessionKey),
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveChatModelOverrideValue(state: ChatModelSelectStateInput): string {
|
||||
@@ -304,7 +307,9 @@ function hasCatalogProviderMetadata(value: string, catalog: ModelCatalogEntry[])
|
||||
export function resolveChatFastModeSelectState(
|
||||
input: ChatFastModeSelectStateInput,
|
||||
): ChatFastModeSelectState {
|
||||
const activeRow = input.sessionsResult?.sessions?.find((row) => row.key === input.sessionKey);
|
||||
const activeRow = input.sessionsResult?.sessions?.find((row) =>
|
||||
areUiSessionKeysEquivalent(row.key, input.sessionKey),
|
||||
);
|
||||
const activeProvider = normalizeChatModelProviderId(activeRow?.modelProvider ?? "") || null;
|
||||
const defaultProvider =
|
||||
normalizeChatModelProviderId(input.sessionsResult?.defaults?.modelProvider ?? "") || null;
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
normalizeThinkLevel,
|
||||
resolveThinkingDefaultForModelCore,
|
||||
} from "../../../../src/auto-reply/thinking.shared.js";
|
||||
// Control UI module implements thinking behavior.
|
||||
import type {
|
||||
GatewaySessionRow,
|
||||
GatewayThinkingLevelOption,
|
||||
@@ -13,6 +12,8 @@ import type {
|
||||
} from "../../api/types.ts";
|
||||
import { pushUniqueTrimmedSelectOption } from "../select-options.ts";
|
||||
import { sessionModelMatchesDefaults } from "../session-model-defaults.ts";
|
||||
// Control UI module implements thinking behavior.
|
||||
import { areUiSessionKeysEquivalent } from "../sessions/session-key.ts";
|
||||
|
||||
type ThinkingSessionDefaults = SessionsListResult["defaults"] | undefined;
|
||||
|
||||
@@ -216,7 +217,10 @@ export function resolveChatThinkingSelectState(params: {
|
||||
sessionsResult: SessionsListResult | null;
|
||||
}): ChatThinkingSelectState {
|
||||
const session =
|
||||
params.session ?? params.sessionsResult?.sessions?.find((row) => row.key === params.sessionKey);
|
||||
params.session ??
|
||||
params.sessionsResult?.sessions?.find((row) =>
|
||||
areUiSessionKeysEquivalent(row.key, params.sessionKey),
|
||||
);
|
||||
const persisted = session?.thinkingLevel;
|
||||
const currentOverride =
|
||||
typeof persisted === "string" && persisted.trim()
|
||||
|
||||
@@ -331,7 +331,7 @@ function patchSessionRow(
|
||||
host.sessionsResult = {
|
||||
...current,
|
||||
sessions: current.sessions.map((row) =>
|
||||
row.key === sessionKey ? Object.assign({}, row, patch) : row,
|
||||
areUiSessionKeysEquivalent(row.key, sessionKey) ? Object.assign({}, row, patch) : row,
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -344,7 +344,9 @@ export function switchChatFastMode(
|
||||
if (!host.client || !host.connected) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
const activeRow = host.sessionsResult?.sessions?.find((row) => row.key === targetSessionKey);
|
||||
const activeRow = host.sessionsResult?.sessions?.find((row) =>
|
||||
areUiSessionKeysEquivalent(row.key, targetSessionKey),
|
||||
);
|
||||
const previousFastMode = activeRow?.fastMode;
|
||||
const previousEffectiveFastMode = activeRow?.effectiveFastMode;
|
||||
const next: FastMode | undefined =
|
||||
@@ -478,7 +480,9 @@ export function switchChatThinkingLevel(
|
||||
if (!host.client || !host.connected) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
const activeRow = host.sessionsResult?.sessions?.find((row) => row.key === targetSessionKey);
|
||||
const activeRow = host.sessionsResult?.sessions?.find((row) =>
|
||||
areUiSessionKeysEquivalent(row.key, targetSessionKey),
|
||||
);
|
||||
const previousThinkingLevel = activeRow?.thinkingLevel;
|
||||
const normalizedNext =
|
||||
(normalizeThinkLevel(nextThinkingLevel) ?? nextThinkingLevel.trim()) || undefined;
|
||||
|
||||
Reference in New Issue
Block a user