2025-09-18 13:32:00 +08:00
|
|
|
/**
|
|
|
|
|
* @license
|
|
|
|
|
* Copyright 2025 Qwen
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import type React from 'react';
|
|
|
|
|
import { Box, Text } from 'ink';
|
|
|
|
|
import { Colors } from '../colors.js';
|
|
|
|
|
import {
|
|
|
|
|
RadioButtonSelect,
|
|
|
|
|
type RadioSelectItem,
|
|
|
|
|
} from './shared/RadioButtonSelect.js';
|
|
|
|
|
import { useKeypress } from '../hooks/useKeypress.js';
|
|
|
|
|
|
|
|
|
|
export enum VisionSwitchOutcome {
|
2025-09-24 10:21:09 +08:00
|
|
|
SwitchOnce = 'once',
|
|
|
|
|
SwitchSessionToVL = 'session',
|
|
|
|
|
ContinueWithCurrentModel = 'persist',
|
2025-09-18 13:32:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ModelSwitchDialogProps {
|
|
|
|
|
onSelect: (outcome: VisionSwitchOutcome) => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const ModelSwitchDialog: React.FC<ModelSwitchDialogProps> = ({
|
|
|
|
|
onSelect,
|
|
|
|
|
}) => {
|
|
|
|
|
useKeypress(
|
|
|
|
|
(key) => {
|
|
|
|
|
if (key.name === 'escape') {
|
2025-09-24 10:21:09 +08:00
|
|
|
onSelect(VisionSwitchOutcome.ContinueWithCurrentModel);
|
2025-09-18 13:32:00 +08:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ isActive: true },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const options: Array<RadioSelectItem<VisionSwitchOutcome>> = [
|
|
|
|
|
{
|
|
|
|
|
label: 'Switch for this request only',
|
|
|
|
|
value: VisionSwitchOutcome.SwitchOnce,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Switch session to vision model',
|
|
|
|
|
value: VisionSwitchOutcome.SwitchSessionToVL,
|
|
|
|
|
},
|
|
|
|
|
{
|
2025-09-24 10:21:09 +08:00
|
|
|
label: 'Continue with current model',
|
|
|
|
|
value: VisionSwitchOutcome.ContinueWithCurrentModel,
|
2025-09-18 13:32:00 +08:00
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const handleSelect = (outcome: VisionSwitchOutcome) => {
|
|
|
|
|
onSelect(outcome);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Box
|
|
|
|
|
flexDirection="column"
|
|
|
|
|
borderStyle="round"
|
|
|
|
|
borderColor={Colors.AccentYellow}
|
|
|
|
|
padding={1}
|
|
|
|
|
width="100%"
|
|
|
|
|
marginLeft={1}
|
|
|
|
|
>
|
|
|
|
|
<Box flexDirection="column" marginBottom={1}>
|
|
|
|
|
<Text bold>Vision Model Switch Required</Text>
|
|
|
|
|
<Text>
|
|
|
|
|
Your message contains an image, but the current model doesn't
|
|
|
|
|
support vision.
|
|
|
|
|
</Text>
|
|
|
|
|
<Text>How would you like to proceed?</Text>
|
|
|
|
|
</Box>
|
|
|
|
|
|
|
|
|
|
<Box marginBottom={1}>
|
|
|
|
|
<RadioButtonSelect
|
|
|
|
|
items={options}
|
|
|
|
|
initialIndex={0}
|
|
|
|
|
onSelect={handleSelect}
|
|
|
|
|
isFocused
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
|
|
|
|
|
|
|
|
|
<Box>
|
|
|
|
|
<Text color={Colors.Gray}>Press Enter to select, Esc to cancel</Text>
|
|
|
|
|
</Box>
|
|
|
|
|
</Box>
|
|
|
|
|
);
|
|
|
|
|
};
|