mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
status: compact fallback model presentation
This commit is contained in:
committed by
joshavant
parent
848511fda7
commit
9baae38704
@@ -15,30 +15,30 @@ const baseAttempt = {
|
||||
describe("fallback-state", () => {
|
||||
it("treats fallback as active only when state matches selected and active refs", () => {
|
||||
const state: FallbackNoticeState = {
|
||||
fallbackNoticeSelectedModel: "fireworks/fireworks/minimax-m2p5",
|
||||
fallbackNoticeSelectedModel: "fireworks/minimax-m2p5",
|
||||
fallbackNoticeActiveModel: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
fallbackNoticeReason: "fireworks/fireworks/minimax-m2p5 rate limit",
|
||||
fallbackNoticeReason: "rate limit",
|
||||
};
|
||||
|
||||
const resolved = resolveActiveFallbackState({
|
||||
selectedModelRef: "fireworks/fireworks/minimax-m2p5",
|
||||
selectedModelRef: "fireworks/minimax-m2p5",
|
||||
activeModelRef: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
state,
|
||||
});
|
||||
|
||||
expect(resolved.active).toBe(true);
|
||||
expect(resolved.reason).toBe("fireworks/fireworks/minimax-m2p5 rate limit");
|
||||
expect(resolved.reason).toBe("rate limit");
|
||||
});
|
||||
|
||||
it("does not treat runtime drift as fallback when persisted state does not match", () => {
|
||||
const state: FallbackNoticeState = {
|
||||
fallbackNoticeSelectedModel: "anthropic/claude",
|
||||
fallbackNoticeActiveModel: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
fallbackNoticeReason: "anthropic/claude rate limit",
|
||||
fallbackNoticeReason: "rate limit",
|
||||
};
|
||||
|
||||
const resolved = resolveActiveFallbackState({
|
||||
selectedModelRef: "fireworks/fireworks/minimax-m2p5",
|
||||
selectedModelRef: "fireworks/minimax-m2p5",
|
||||
activeModelRef: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
state,
|
||||
});
|
||||
@@ -61,8 +61,8 @@ describe("fallback-state", () => {
|
||||
expect(resolved.fallbackTransitioned).toBe(true);
|
||||
expect(resolved.fallbackCleared).toBe(false);
|
||||
expect(resolved.stateChanged).toBe(true);
|
||||
expect(resolved.reasonSummary).toBe("fireworks/fireworks/minimax-m2p5 rate limit");
|
||||
expect(resolved.nextState.selectedModel).toBe("fireworks/fireworks/minimax-m2p5");
|
||||
expect(resolved.reasonSummary).toBe("rate limit");
|
||||
expect(resolved.nextState.selectedModel).toBe("fireworks/minimax-m2p5");
|
||||
expect(resolved.nextState.activeModel).toBe("deepinfra/moonshotai/Kimi-K2.5");
|
||||
});
|
||||
|
||||
@@ -74,15 +74,15 @@ describe("fallback-state", () => {
|
||||
activeModel: "moonshotai/Kimi-K2.5",
|
||||
attempts: [{ ...baseAttempt, reason: "timeout" }],
|
||||
state: {
|
||||
fallbackNoticeSelectedModel: "fireworks/fireworks/minimax-m2p5",
|
||||
fallbackNoticeSelectedModel: "fireworks/minimax-m2p5",
|
||||
fallbackNoticeActiveModel: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
fallbackNoticeReason: "fireworks/fireworks/minimax-m2p5 rate limit",
|
||||
fallbackNoticeReason: "rate limit",
|
||||
},
|
||||
});
|
||||
|
||||
expect(resolved.fallbackTransitioned).toBe(false);
|
||||
expect(resolved.stateChanged).toBe(true);
|
||||
expect(resolved.nextState.reason).toBe("fireworks/fireworks/minimax-m2p5 timeout");
|
||||
expect(resolved.nextState.reason).toBe("timeout");
|
||||
});
|
||||
|
||||
it("marks fallback as cleared when runtime returns to selected model", () => {
|
||||
@@ -93,9 +93,9 @@ describe("fallback-state", () => {
|
||||
activeModel: "fireworks/minimax-m2p5",
|
||||
attempts: [],
|
||||
state: {
|
||||
fallbackNoticeSelectedModel: "fireworks/fireworks/minimax-m2p5",
|
||||
fallbackNoticeSelectedModel: "fireworks/minimax-m2p5",
|
||||
fallbackNoticeActiveModel: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
fallbackNoticeReason: "fireworks/fireworks/minimax-m2p5 rate limit",
|
||||
fallbackNoticeReason: "rate limit",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { SessionEntry } from "../config/sessions.js";
|
||||
import { formatProviderModelRef } from "./model-runtime.js";
|
||||
import type { RuntimeFallbackAttempt } from "./reply/agent-runner-execution.js";
|
||||
|
||||
const FALLBACK_REASON_PART_MAX = 80;
|
||||
@@ -37,13 +38,13 @@ export function formatFallbackAttemptReason(attempt: RuntimeFallbackAttempt): st
|
||||
}
|
||||
|
||||
function formatFallbackAttemptSummary(attempt: RuntimeFallbackAttempt): string {
|
||||
return `${attempt.provider}/${attempt.model} ${formatFallbackAttemptReason(attempt)}`;
|
||||
return `${formatProviderModelRef(attempt.provider, attempt.model)} ${formatFallbackAttemptReason(attempt)}`;
|
||||
}
|
||||
|
||||
export function buildFallbackReasonSummary(attempts: RuntimeFallbackAttempt[]): string {
|
||||
const firstAttempt = attempts[0];
|
||||
const firstReason = firstAttempt
|
||||
? formatFallbackAttemptSummary(firstAttempt)
|
||||
? formatFallbackAttemptReason(firstAttempt)
|
||||
: "selected model unavailable";
|
||||
const moreAttempts = attempts.length > 1 ? ` (+${attempts.length - 1} more attempts)` : "";
|
||||
return `${truncateFallbackReasonPart(firstReason)}${moreAttempts}`;
|
||||
@@ -62,8 +63,8 @@ export function buildFallbackNotice(params: {
|
||||
activeModel: string;
|
||||
attempts: RuntimeFallbackAttempt[];
|
||||
}): string | null {
|
||||
const selected = `${params.selectedProvider}/${params.selectedModel}`;
|
||||
const active = `${params.activeProvider}/${params.activeModel}`;
|
||||
const selected = formatProviderModelRef(params.selectedProvider, params.selectedModel);
|
||||
const active = formatProviderModelRef(params.activeProvider, params.activeModel);
|
||||
if (selected === active) {
|
||||
return null;
|
||||
}
|
||||
@@ -76,7 +77,7 @@ export function buildFallbackClearedNotice(params: {
|
||||
selectedModel: string;
|
||||
previousActiveModel?: string;
|
||||
}): string {
|
||||
const selected = `${params.selectedProvider}/${params.selectedModel}`;
|
||||
const selected = formatProviderModelRef(params.selectedProvider, params.selectedModel);
|
||||
const previous = normalizeFallbackModelRef(params.previousActiveModel);
|
||||
if (previous && previous !== selected) {
|
||||
return `↪️ Model Fallback cleared: ${selected} (was ${previous})`;
|
||||
@@ -131,8 +132,8 @@ export function resolveFallbackTransition(params: {
|
||||
attempts: RuntimeFallbackAttempt[];
|
||||
state?: FallbackNoticeState;
|
||||
}): ResolvedFallbackTransition {
|
||||
const selectedModelRef = `${params.selectedProvider}/${params.selectedModel}`;
|
||||
const activeModelRef = `${params.activeProvider}/${params.activeModel}`;
|
||||
const selectedModelRef = formatProviderModelRef(params.selectedProvider, params.selectedModel);
|
||||
const activeModelRef = formatProviderModelRef(params.activeProvider, params.activeModel);
|
||||
const previousState = {
|
||||
selectedModel: normalizeFallbackModelRef(params.state?.fallbackNoticeSelectedModel),
|
||||
activeModel: normalizeFallbackModelRef(params.state?.fallbackNoticeActiveModel),
|
||||
|
||||
@@ -1,11 +1,45 @@
|
||||
import type { SessionEntry } from "../config/sessions.js";
|
||||
|
||||
export function formatProviderModelRef(providerRaw: string, modelRaw: string): string {
|
||||
const provider = String(providerRaw ?? "").trim();
|
||||
const model = String(modelRaw ?? "").trim();
|
||||
if (!provider) {
|
||||
return model;
|
||||
}
|
||||
if (!model) {
|
||||
return provider;
|
||||
}
|
||||
const prefix = `${provider}/`;
|
||||
if (model.toLowerCase().startsWith(prefix.toLowerCase())) {
|
||||
const normalizedModel = model.slice(prefix.length).trim();
|
||||
if (normalizedModel) {
|
||||
return `${provider}/${normalizedModel}`;
|
||||
}
|
||||
}
|
||||
return `${provider}/${model}`;
|
||||
}
|
||||
|
||||
type ModelRef = {
|
||||
provider: string;
|
||||
model: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
function normalizeModelWithinProvider(provider: string, modelRaw: string): string {
|
||||
const model = String(modelRaw ?? "").trim();
|
||||
if (!provider || !model) {
|
||||
return model;
|
||||
}
|
||||
const prefix = `${provider}/`;
|
||||
if (model.toLowerCase().startsWith(prefix.toLowerCase())) {
|
||||
const withoutPrefix = model.slice(prefix.length).trim();
|
||||
if (withoutPrefix) {
|
||||
return withoutPrefix;
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
function normalizeModelRef(
|
||||
rawModel: string,
|
||||
fallbackProvider: string,
|
||||
@@ -25,10 +59,11 @@ function normalizeModelRef(
|
||||
}
|
||||
}
|
||||
const provider = String(fallbackProvider ?? "").trim();
|
||||
const dedupedModel = normalizeModelWithinProvider(provider, trimmed);
|
||||
return {
|
||||
provider,
|
||||
model: trimmed,
|
||||
label: provider ? `${provider}/${trimmed}` : trimmed,
|
||||
model: dedupedModel || trimmed,
|
||||
label: provider ? formatProviderModelRef(provider, dedupedModel || trimmed) : trimmed,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
const payloads = res as { text?: string }[];
|
||||
expect(payloads[0]?.text).toContain("Model Fallback:");
|
||||
expect(payloads[0]?.text).toContain("deepinfra/moonshotai/Kimi-K2.5");
|
||||
expect(sessionEntry.fallbackNoticeReason).toBe("fireworks/fireworks/minimax-m2p5 rate limit");
|
||||
expect(sessionEntry.fallbackNoticeReason).toBe("rate limit");
|
||||
});
|
||||
|
||||
it("does not announce model fallback when verbose is off", async () => {
|
||||
@@ -946,7 +946,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
const res = await run();
|
||||
const firstText = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
expect(firstText).not.toContain("Model Fallback:");
|
||||
expect(sessionEntry.fallbackNoticeReason).toBe("anthropic/claude rate limit");
|
||||
expect(sessionEntry.fallbackNoticeReason).toBe("rate limit");
|
||||
} finally {
|
||||
fallbackSpy.mockRestore();
|
||||
}
|
||||
@@ -958,7 +958,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
updatedAt: Date.now(),
|
||||
fallbackNoticeSelectedModel: "anthropic/claude",
|
||||
fallbackNoticeActiveModel: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
fallbackNoticeReason: "anthropic/claude rate limit",
|
||||
fallbackNoticeReason: "rate limit",
|
||||
modelProvider: "deepinfra",
|
||||
model: "moonshotai/Kimi-K2.5",
|
||||
};
|
||||
@@ -996,7 +996,7 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
const res = await run();
|
||||
const firstText = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||
expect(firstText).not.toContain("Model Fallback:");
|
||||
expect(sessionEntry.fallbackNoticeReason).toBe("anthropic/claude timeout");
|
||||
expect(sessionEntry.fallbackNoticeReason).toBe("timeout");
|
||||
} finally {
|
||||
fallbackSpy.mockRestore();
|
||||
}
|
||||
@@ -1011,9 +1011,9 @@ describe("runReplyAgent typing (heartbeat)", () => {
|
||||
sessionId,
|
||||
updatedAt: Date.now(),
|
||||
sessionFile: transcriptPath,
|
||||
fallbackNoticeSelectedModel: "fireworks/fireworks/minimax-m2p5",
|
||||
fallbackNoticeSelectedModel: "fireworks/minimax-m2p5",
|
||||
fallbackNoticeActiveModel: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
fallbackNoticeReason: "fireworks/fireworks/minimax-m2p5 rate limit",
|
||||
fallbackNoticeReason: "rate limit",
|
||||
};
|
||||
const sessionStore = { main: sessionEntry };
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ describe("/model chat UX", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(reply?.text).toContain("Current: fireworks/fireworks/minimax-m2p5 (selected)");
|
||||
expect(reply?.text).toContain("Current: fireworks/minimax-m2p5 (selected)");
|
||||
expect(reply?.text).toContain("Active: deepinfra/moonshotai/Kimi-K2.5 (runtime)");
|
||||
});
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ describe("buildStatusMessage", () => {
|
||||
model: "claude-haiku-4-5",
|
||||
fallbackNoticeSelectedModel: "openai/gpt-4.1-mini",
|
||||
fallbackNoticeActiveModel: "anthropic/claude-haiku-4-5",
|
||||
fallbackNoticeReason: "fireworks/fireworks/minimax-m2p5 rate limit",
|
||||
fallbackNoticeReason: "rate limit",
|
||||
contextTokens: 32_000,
|
||||
},
|
||||
sessionKey: "agent:main:main",
|
||||
@@ -217,11 +217,10 @@ describe("buildStatusMessage", () => {
|
||||
|
||||
const normalized = normalizeTestText(text);
|
||||
expect(normalized).toContain("Model: openai/gpt-4.1-mini");
|
||||
expect(normalized).toContain("(selected)");
|
||||
expect(normalized).toContain("Active: anthropic/claude-haiku-4-5");
|
||||
expect(normalized).toContain("(Reason: fireworks/fireworks/minimax-m2p5 rate limit)");
|
||||
expect(normalized).toContain("Fallback: anthropic/claude-haiku-4-5");
|
||||
expect(normalized).toContain("(rate limit)");
|
||||
expect(normalized).not.toContain(" - Reason:");
|
||||
expect(normalized).not.toContain("Active Reason:");
|
||||
expect(normalized).not.toContain("Active:");
|
||||
expect(normalized).toContain("di_123...abc");
|
||||
});
|
||||
|
||||
@@ -236,9 +235,9 @@ describe("buildStatusMessage", () => {
|
||||
updatedAt: 0,
|
||||
modelProvider: "anthropic",
|
||||
model: "claude-haiku-4-5",
|
||||
fallbackNoticeSelectedModel: "fireworks/fireworks/minimax-m2p5",
|
||||
fallbackNoticeSelectedModel: "fireworks/minimax-m2p5",
|
||||
fallbackNoticeActiveModel: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
fallbackNoticeReason: "fireworks/fireworks/minimax-m2p5 rate limit",
|
||||
fallbackNoticeReason: "rate limit",
|
||||
},
|
||||
sessionKey: "agent:main:main",
|
||||
sessionScope: "per-sender",
|
||||
@@ -249,9 +248,8 @@ describe("buildStatusMessage", () => {
|
||||
|
||||
const normalized = normalizeTestText(text);
|
||||
expect(normalized).toContain("Model: openai/gpt-4.1-mini");
|
||||
expect(normalized).not.toContain("(selected)");
|
||||
expect(normalized).not.toContain("Active:");
|
||||
expect(normalized).not.toContain("Reason:");
|
||||
expect(normalized).not.toContain("Fallback:");
|
||||
expect(normalized).not.toContain("(rate limit)");
|
||||
});
|
||||
|
||||
it("omits active lines when runtime matches selected model", () => {
|
||||
@@ -265,7 +263,7 @@ describe("buildStatusMessage", () => {
|
||||
updatedAt: 0,
|
||||
modelProvider: "openai",
|
||||
model: "gpt-4.1-mini",
|
||||
fallbackNoticeReason: "openai/gpt-4.1-mini unknown",
|
||||
fallbackNoticeReason: "unknown",
|
||||
},
|
||||
sessionKey: "agent:main:main",
|
||||
sessionScope: "per-sender",
|
||||
@@ -274,8 +272,7 @@ describe("buildStatusMessage", () => {
|
||||
});
|
||||
|
||||
const normalized = normalizeTestText(text);
|
||||
expect(normalized).not.toContain("Active:");
|
||||
expect(normalized).not.toContain("Active Reason:");
|
||||
expect(normalized).not.toContain("Fallback:");
|
||||
});
|
||||
|
||||
it("keeps provider prefix from configured model", () => {
|
||||
|
||||
@@ -41,7 +41,7 @@ import {
|
||||
} from "./commands-registry.js";
|
||||
import type { CommandCategory } from "./commands-registry.types.js";
|
||||
import { resolveActiveFallbackState } from "./fallback-state.js";
|
||||
import { resolveSelectedAndActiveModel } from "./model-runtime.js";
|
||||
import { formatProviderModelRef, resolveSelectedAndActiveModel } from "./model-runtime.js";
|
||||
import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "./thinking.js";
|
||||
|
||||
type AgentDefaults = NonNullable<NonNullable<OpenClawConfig["agents"]>["defaults"]>;
|
||||
@@ -492,19 +492,19 @@ export function buildStatusMessage(args: StatusArgs): string {
|
||||
const costLabel = showCost && hasUsage ? formatUsd(cost) : undefined;
|
||||
|
||||
const selectedModelLabel = modelRefs.selected.label || "unknown";
|
||||
const activeModelLabel = formatProviderModelRef(activeProvider, activeModel) || "unknown";
|
||||
const fallbackState = resolveActiveFallbackState({
|
||||
selectedModelRef: `${selectedProvider}/${selectedModel}`,
|
||||
activeModelRef: `${activeProvider}/${activeModel}`,
|
||||
selectedModelRef: selectedModelLabel,
|
||||
activeModelRef: activeModelLabel,
|
||||
state: entry,
|
||||
});
|
||||
const selectedAuthLabel = selectedAuthLabelValue ? ` · 🔑 ${selectedAuthLabelValue}` : "";
|
||||
const modelLine = `🧠 Model: ${selectedModelLabel}${selectedAuthLabel}${
|
||||
fallbackState.active ? " (selected)" : ""
|
||||
}`;
|
||||
const activeModelLine = fallbackState.active
|
||||
? `🧠 Active: ${activeProvider}/${activeModel}${
|
||||
activeAuthLabelValue ? ` · 🔑 ${activeAuthLabelValue}` : ""
|
||||
} (Reason: ${fallbackState.reason ?? "selected model unavailable"})`
|
||||
const modelLine = `🧠 Model: ${selectedModelLabel}${selectedAuthLabel}`;
|
||||
const showFallbackAuth = activeAuthLabelValue && activeAuthLabelValue !== selectedAuthLabelValue;
|
||||
const fallbackLine = fallbackState.active
|
||||
? `↪️ Fallback: ${activeModelLabel}${
|
||||
showFallbackAuth ? ` · 🔑 ${activeAuthLabelValue}` : ""
|
||||
} (${fallbackState.reason ?? "selected model unavailable"})`
|
||||
: null;
|
||||
const commit = resolveCommitHash();
|
||||
const versionLine = `🦞 OpenClaw ${VERSION}${commit ? ` (${commit})` : ""}`;
|
||||
@@ -519,7 +519,7 @@ export function buildStatusMessage(args: StatusArgs): string {
|
||||
versionLine,
|
||||
args.timeLine,
|
||||
modelLine,
|
||||
activeModelLine,
|
||||
fallbackLine,
|
||||
usageCostLine,
|
||||
`📚 ${contextLine}`,
|
||||
mediaLine,
|
||||
|
||||
@@ -51,13 +51,13 @@ describe("app-tool-stream fallback lifecycle handling", () => {
|
||||
selectedModel: "fireworks/minimax-m2p5",
|
||||
activeProvider: "deepinfra",
|
||||
activeModel: "moonshotai/Kimi-K2.5",
|
||||
reasonSummary: "fireworks/fireworks/minimax-m2p5 rate limit",
|
||||
reasonSummary: "rate limit",
|
||||
},
|
||||
});
|
||||
|
||||
expect(host.fallbackStatus?.selected).toBe("fireworks/fireworks/minimax-m2p5");
|
||||
expect(host.fallbackStatus?.selected).toBe("fireworks/minimax-m2p5");
|
||||
expect(host.fallbackStatus?.active).toBe("deepinfra/moonshotai/Kimi-K2.5");
|
||||
expect(host.fallbackStatus?.reason).toBe("fireworks/fireworks/minimax-m2p5 rate limit");
|
||||
expect(host.fallbackStatus?.reason).toBe("rate limit");
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
|
||||
@@ -49,6 +49,13 @@ function resolveModelLabel(provider: unknown, model: unknown): string | null {
|
||||
}
|
||||
const providerValue = toTrimmedString(provider);
|
||||
if (providerValue) {
|
||||
const prefix = `${providerValue}/`;
|
||||
if (modelValue.toLowerCase().startsWith(prefix.toLowerCase())) {
|
||||
const trimmedModel = modelValue.slice(prefix.length).trim();
|
||||
if (trimmedModel) {
|
||||
return `${providerValue}/${trimmedModel}`;
|
||||
}
|
||||
}
|
||||
return `${providerValue}/${modelValue}`;
|
||||
}
|
||||
const slashIndex = modelValue.indexOf("/");
|
||||
@@ -347,9 +354,10 @@ function handleLifecycleFallbackEvent(host: CompactionHost, payload: AgentEventP
|
||||
if (summaries.length > 0) {
|
||||
return summaries;
|
||||
}
|
||||
return parseFallbackAttempts(data.attempts).map(
|
||||
(attempt) => `${attempt.provider}/${attempt.model}: ${attempt.reason}`,
|
||||
);
|
||||
return parseFallbackAttempts(data.attempts).map((attempt) => {
|
||||
const modelRef = resolveModelLabel(attempt.provider, attempt.model);
|
||||
return `${modelRef ?? `${attempt.provider}/${attempt.model}`}: ${attempt.reason}`;
|
||||
});
|
||||
})();
|
||||
|
||||
if (host.fallbackClearTimer != null) {
|
||||
|
||||
@@ -119,9 +119,9 @@ describe("chat view", () => {
|
||||
renderChat(
|
||||
createProps({
|
||||
fallbackStatus: {
|
||||
selected: "fireworks/fireworks/minimax-m2p5",
|
||||
selected: "fireworks/minimax-m2p5",
|
||||
active: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
attempts: ["fireworks/fireworks/minimax-m2p5: rate limit"],
|
||||
attempts: ["fireworks/minimax-m2p5: rate limit"],
|
||||
occurredAt: 900,
|
||||
},
|
||||
}),
|
||||
@@ -142,7 +142,7 @@ describe("chat view", () => {
|
||||
renderChat(
|
||||
createProps({
|
||||
fallbackStatus: {
|
||||
selected: "fireworks/fireworks/minimax-m2p5",
|
||||
selected: "fireworks/minimax-m2p5",
|
||||
active: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
attempts: [],
|
||||
occurredAt: 0,
|
||||
@@ -164,8 +164,8 @@ describe("chat view", () => {
|
||||
createProps({
|
||||
fallbackStatus: {
|
||||
phase: "cleared",
|
||||
selected: "fireworks/fireworks/minimax-m2p5",
|
||||
active: "fireworks/fireworks/minimax-m2p5",
|
||||
selected: "fireworks/minimax-m2p5",
|
||||
active: "fireworks/minimax-m2p5",
|
||||
previous: "deepinfra/moonshotai/Kimi-K2.5",
|
||||
attempts: [],
|
||||
occurredAt: 900,
|
||||
@@ -177,7 +177,7 @@ describe("chat view", () => {
|
||||
|
||||
const indicator = container.querySelector(".compaction-indicator--fallback-cleared");
|
||||
expect(indicator).not.toBeNull();
|
||||
expect(indicator?.textContent).toContain("Fallback cleared: fireworks/fireworks/minimax-m2p5");
|
||||
expect(indicator?.textContent).toContain("Fallback cleared: fireworks/minimax-m2p5");
|
||||
nowSpy.mockRestore();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user