Clarify Assistant route switching actions

This commit is contained in:
rcourtman
2026-06-08 05:28:17 +01:00
parent fb085763ab
commit 43974e7760
4 changed files with 33 additions and 12 deletions
@@ -374,8 +374,8 @@ export const MessageItem: Component<MessageItemProps> = (props) => {
const alternative = props.modelRouteAlternative;
if (!alternative) return '';
return alternative.kind === 'same-model-route'
? `Retry with ${alternative.providerLabel} route`
: `Retry with ${alternative.providerLabel} model route`;
? `Switch to ${alternative.providerLabel} route and retry`
: `Switch to ${alternative.providerLabel} model route and retry`;
};
const hasPreviousModelRoute = (event: StreamDisplayEvent) => {
const model = event.model?.trim();
@@ -320,8 +320,8 @@ vi.mock('../ChatMessages', () => ({
}
>
{recovery().alternative.kind === 'same-model-route'
? `Retry with ${recovery().alternative.providerLabel} route`
: `Retry with ${recovery().alternative.providerLabel} model route`}
? `Switch to ${recovery().alternative.providerLabel} route and retry`
: `Switch to ${recovery().alternative.providerLabel} model route and retry`}
</button>
)}
</Show>
@@ -1234,6 +1234,27 @@ describe('AIChat', () => {
expect(document.activeElement).toBe(textarea);
});
it('treats provider readiness request failures as recoverable route status', async () => {
const readinessError = new Error('Model provider does not match test provider');
mockAIAPI.testProvider.mockRejectedValueOnce(readinessError);
renderChat();
await screen.findByText('Selected model route issue');
expect(screen.getByLabelText('Assistant selected model route status')).toHaveTextContent(
'Pulse could not verify the selected model route.',
);
expect(logger.warn).toHaveBeenCalledWith(
'[AIChat] Failed to check selected provider readiness:',
readinessError,
);
expect(logger.error).not.toHaveBeenCalledWith(
'[AIChat] Failed to check selected provider readiness:',
readinessError,
);
});
it('offers an equivalent configured-provider route when the selected provider fails', async () => {
mockAIAPI.getSettings.mockResolvedValue({
model: 'deepseek:deepseek-v4-pro',
@@ -1279,9 +1300,9 @@ describe('AIChat', () => {
renderChat();
const switchButton = await screen.findByRole('button', {
name: 'Use OpenRouter route',
name: 'Switch to OpenRouter route',
});
expect(switchButton).toHaveTextContent('Use OpenRouter route');
expect(switchButton).toHaveTextContent('Switch to OpenRouter route');
fireEvent.click(switchButton);
@@ -1330,7 +1351,7 @@ describe('AIChat', () => {
renderChat();
await screen.findByRole('button', {
name: 'Use OpenRouter route',
name: 'Switch to OpenRouter route',
});
const textarea = screen.getByPlaceholderText(
@@ -252,9 +252,9 @@ describe('MessageItem', () => {
expect(alert.textContent).toContain('billing or quota reasons');
const retryViaOpenRouter = screen.getByRole('button', {
name: 'Retry with OpenRouter route',
name: 'Switch to OpenRouter route and retry',
});
expect(retryViaOpenRouter).toHaveTextContent('Retry with OpenRouter route');
expect(retryViaOpenRouter).toHaveTextContent('Switch to OpenRouter route and retry');
fireEvent.click(retryViaOpenRouter);
expect(onUseModelRoute).toHaveBeenCalledWith('openrouter:deepseek/deepseek-v4-pro', 'msg-1');
@@ -1973,7 +1973,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
});
} catch (error) {
if (requestId !== providerReadinessRequestId) return;
logger.error('[AIChat] Failed to check selected provider readiness:', error);
logger.warn('[AIChat] Failed to check selected provider readiness:', error);
setProviderReadiness({
status: 'error',
provider,
@@ -2234,8 +2234,8 @@ export const AIChat: Component<AIChatProps> = (props) => {
const alternative = providerReadinessAlternative();
if (!alternative) return '';
return alternative.kind === 'same-model-route'
? `Use ${alternative.providerLabel} route`
: `Use ${alternative.providerLabel} model route`;
? `Switch to ${alternative.providerLabel} route`
: `Switch to ${alternative.providerLabel} model route`;
};
createEffect(() => {