Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/users/configuration/auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ qwen --model "qwen3-coder-plus"

# In another terminal

qwen --model "qwen3-coder-next"
qwen --model "qwen3.5-plus"
```

## Security notes
Expand Down
13 changes: 1 addition & 12 deletions packages/cli/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ export interface CliArgs {
googleSearchEngineId: string | undefined;
webSearchDefault: string | undefined;
screenReader: boolean | undefined;
vlmSwitchMode: string | undefined;
inputFormat?: string | undefined;
outputFormat: string | undefined;
includePartialMessages?: boolean;
Expand Down Expand Up @@ -426,13 +425,6 @@ export async function parseArguments(): Promise<CliArgs> {
type: 'boolean',
description: 'Enable screen reader mode for accessibility.',
})
.option('vlm-switch-mode', {
type: 'string',
choices: ['once', 'session', 'persist'],
description:
'Default behavior when images are detected in input. Values: once (one-time switch), session (switch for entire session), persist (continue with current model). Overrides settings files.',
default: process.env['VLM_SWITCH_MODE'],
})
.option('input-format', {
type: 'string',
choices: ['text', 'stream-json'],
Expand Down Expand Up @@ -903,9 +895,6 @@ export async function loadCliConfig(
? argv.screenReader
: (settings.ui?.accessibility?.screenReader ?? false);

const vlmSwitchMode =
argv.vlmSwitchMode || settings.experimental?.vlmSwitchMode;

let sessionId: string | undefined;
let sessionData: ResumedSessionData | undefined;

Expand Down Expand Up @@ -1002,6 +991,7 @@ export async function loadCliConfig(
modelProvidersConfig,
generationConfigSources: resolvedCliConfig.sources,
generationConfig: resolvedCliConfig.generationConfig,
warnings: resolvedCliConfig.warnings,
cliVersion: await getCliVersion(),
webSearch: buildWebSearchConfig(argv, settings, selectedAuthType),
summarizeToolOutput: settings.model?.summarizeToolOutput,
Expand All @@ -1016,7 +1006,6 @@ export async function loadCliConfig(
skipNextSpeakerCheck: settings.model?.skipNextSpeakerCheck,
skipLoopDetection: settings.model?.skipLoopDetection ?? false,
skipStartupContext: settings.model?.skipStartupContext ?? false,
vlmSwitchMode,
truncateToolOutputThreshold: settings.tools?.truncateToolOutputThreshold,
truncateToolOutputLines: settings.tools?.truncateToolOutputLines,
enableToolOutputTruncation: settings.tools?.enableToolOutputTruncation,
Expand Down
2 changes: 0 additions & 2 deletions packages/cli/src/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ const MIGRATION_MAP: Record<string, string> = {
skipStartupContext: 'model.skipStartupContext',
enableOpenAILogging: 'model.enableOpenAILogging',
tavilyApiKey: 'advanced.tavilyApiKey',
vlmSwitchMode: 'experimental.vlmSwitchMode',
visionModelPreview: 'experimental.visionModelPreview',
};

// Settings that need boolean inversion during migration (V1 -> V3)
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/config/settingsSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('SettingsSchema', () => {
'mcp',
'security',
'advanced',
'experimental',
'webSearch',
];

expectedSettings.forEach((setting) => {
Expand Down
32 changes: 0 additions & 32 deletions packages/cli/src/config/settingsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1176,38 +1176,6 @@ const SETTINGS_SCHEMA = {
description: 'Configuration for web search providers.',
showInDialog: false,
},

experimental: {
type: 'object',
label: 'Experimental',
category: 'Experimental',
requiresRestart: true,
default: {},
description: 'Setting to enable experimental features',
showInDialog: false,
properties: {
visionModelPreview: {
type: 'boolean',
label: 'Vision Model Preview',
category: 'Experimental',
requiresRestart: false,
default: true,
description:
'Enable vision model support and auto-switching functionality. When disabled, vision models like qwen-vl-max-latest will be hidden and auto-switching will not occur.',
showInDialog: false,
},
vlmSwitchMode: {
type: 'string',
label: 'VLM Switch Mode',
category: 'Experimental',
requiresRestart: false,
default: undefined as string | undefined,
description:
'Default behavior when images are detected in input. Values: once (one-time switch), session (switch for entire session), persist (continue with current model). If not set, user will be prompted each time. This is a temporary experimental feature.',
showInDialog: false,
},
},
},
} as const satisfies SettingsSchema;

export type SettingsSchemaType = typeof SETTINGS_SCHEMA;
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/gemini.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ vi.mock('./config/config.js', () => ({
getSandbox: vi.fn(() => false),
getQuestion: vi.fn(() => ''),
isInteractive: () => false,
getWarnings: vi.fn(() => []),
} as unknown as Config),
parseArguments: vi.fn().mockResolvedValue({}),
isDebugMode: vi.fn(() => false),
Expand Down Expand Up @@ -177,6 +178,7 @@ describe('gemini.tsx main function', () => {
getGeminiMdFileCount: () => 0,
getProjectRoot: () => '/',
getOutputFormat: () => OutputFormat.TEXT,
getWarnings: () => [],
} as unknown as Config;
});
vi.mocked(loadSettings).mockReturnValue({
Expand Down Expand Up @@ -341,6 +343,7 @@ describe('gemini.tsx main function', () => {
getProjectRoot: () => '/',
getInputFormat: () => 'stream-json',
getContentGeneratorConfig: () => ({ authType: 'test-auth' }),
getWarnings: () => [],
} as unknown as Config;

vi.mocked(loadCliConfig).mockResolvedValue(configStub);
Expand Down Expand Up @@ -438,6 +441,7 @@ describe('gemini.tsx main function kitty protocol', () => {
getExperimentalZedIntegration: () => false,
getScreenReader: () => false,
getGeminiMdFileCount: () => 0,
getWarnings: () => [],
} as unknown as Config);
vi.mocked(loadSettings).mockReturnValue({
errors: [],
Expand Down Expand Up @@ -483,7 +487,6 @@ describe('gemini.tsx main function kitty protocol', () => {
googleSearchEngineId: undefined,
webSearchDefault: undefined,
screenReader: undefined,
vlmSwitchMode: undefined,
inputFormat: undefined,
outputFormat: undefined,
includePartialMessages: undefined,
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/gemini.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ export async function main() {
useBuiltinRipgrep: settings.merged.tools?.useBuiltinRipgrep ?? true,
})),
...getSettingsWarnings(settings),
...config.getWarnings(),
]),
];

Expand Down
52 changes: 0 additions & 52 deletions packages/cli/src/ui/AppContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ import { t } from '../i18n/index.js';
import { useWelcomeBack } from './hooks/useWelcomeBack.js';
import { useDialogClose } from './hooks/useDialogClose.js';
import { useInitializationAuthError } from './hooks/useInitializationAuthError.js';
import { type VisionSwitchOutcome } from './components/ModelSwitchDialog.js';
import { processVisionSwitchOutcome } from './hooks/useVisionAutoSwitch.js';
import { useSubagentCreateDialog } from './hooks/useSubagentCreateDialog.js';
import { useAgentsManagerDialog } from './hooks/useAgentsManagerDialog.js';
import { useAttentionNotifications } from './hooks/useAttentionNotifications.js';
Expand Down Expand Up @@ -496,18 +494,6 @@ export const AppContainer = (props: AppContainerProps) => {
closeAgentsManagerDialog,
} = useAgentsManagerDialog();

// Vision model auto-switch dialog state (must be before slashCommandActions)
const [isVisionSwitchDialogOpen, setIsVisionSwitchDialogOpen] =
useState(false);
const [visionSwitchResolver, setVisionSwitchResolver] = useState<{
resolve: (result: {
modelOverride?: string;
persistSessionModel?: string;
showGuidance?: boolean;
}) => void;
reject: () => void;
} | null>(null);

const slashCommandActions = useMemo(
() => ({
openAuthDialog,
Expand Down Expand Up @@ -571,32 +557,6 @@ export const AppContainer = (props: AppContainerProps) => {
logger,
);

// Vision switch handlers
const handleVisionSwitchRequired = useCallback(
async (_query: unknown) =>
new Promise<{
modelOverride?: string;
persistSessionModel?: string;
showGuidance?: boolean;
}>((resolve, reject) => {
setVisionSwitchResolver({ resolve, reject });
setIsVisionSwitchDialogOpen(true);
}),
[],
);

const handleVisionSwitchSelect = useCallback(
(outcome: VisionSwitchOutcome) => {
setIsVisionSwitchDialogOpen(false);
if (visionSwitchResolver) {
const result = processVisionSwitchOutcome(outcome);
visionSwitchResolver.resolve(result);
setVisionSwitchResolver(null);
}
},
[visionSwitchResolver],
);

// onDebugMessage should log to debug logfile, not update footer debugMessage
const onDebugMessage = useCallback(
(message: string) => {
Expand Down Expand Up @@ -687,11 +647,9 @@ export const AppContainer = (props: AppContainerProps) => {
setModelSwitchedFromQuotaError,
refreshStatic,
() => cancelHandlerRef.current(),
settings.merged.experimental?.visionModelPreview ?? false, // visionModelPreviewEnabled
setEmbeddedShellFocused,
terminalWidth,
terminalHeight,
handleVisionSwitchRequired, // onVisionSwitchRequired
);

// Track whether suggestions are visible for Tab key handling
Expand Down Expand Up @@ -846,7 +804,6 @@ export const AppContainer = (props: AppContainerProps) => {
!isThemeDialogOpen &&
!isEditorDialogOpen &&
!showWelcomeBackDialog &&
!isVisionSwitchDialogOpen &&
welcomeBackChoice !== 'restart' &&
geminiClient?.isInitialized?.()
) {
Expand All @@ -862,7 +819,6 @@ export const AppContainer = (props: AppContainerProps) => {
isThemeDialogOpen,
isEditorDialogOpen,
showWelcomeBackDialog,
isVisionSwitchDialogOpen,
welcomeBackChoice,
geminiClient,
]);
Expand Down Expand Up @@ -1334,7 +1290,6 @@ export const AppContainer = (props: AppContainerProps) => {
isThemeDialogOpen ||
isSettingsDialogOpen ||
isModelDialogOpen ||
isVisionSwitchDialogOpen ||
isPermissionsDialogOpen ||
isAuthDialogOpen ||
isAuthenticating ||
Expand Down Expand Up @@ -1446,8 +1401,6 @@ export const AppContainer = (props: AppContainerProps) => {
extensionsUpdateState,
activePtyId,
embeddedShellFocused,
// Vision switch dialog
isVisionSwitchDialogOpen,
// Welcome back dialog
showWelcomeBackDialog,
welcomeBackInfo,
Expand Down Expand Up @@ -1538,8 +1491,6 @@ export const AppContainer = (props: AppContainerProps) => {
activePtyId,
historyManager,
embeddedShellFocused,
// Vision switch dialog
isVisionSwitchDialogOpen,
// Welcome back dialog
showWelcomeBackDialog,
welcomeBackInfo,
Expand Down Expand Up @@ -1581,8 +1532,6 @@ export const AppContainer = (props: AppContainerProps) => {
refreshStatic,
handleFinalSubmit,
handleClearScreen,
// Vision switch dialog
handleVisionSwitchSelect,
// Welcome back dialog
handleWelcomeBackSelection,
handleWelcomeBackClose,
Expand Down Expand Up @@ -1626,7 +1575,6 @@ export const AppContainer = (props: AppContainerProps) => {
refreshStatic,
handleFinalSubmit,
handleClearScreen,
handleVisionSwitchSelect,
handleWelcomeBackSelection,
handleWelcomeBackClose,
// Subagent dialogs
Expand Down
5 changes: 0 additions & 5 deletions packages/cli/src/ui/components/DialogManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import process from 'node:process';
import { type UseHistoryManagerReturn } from '../hooks/useHistoryManager.js';
import { IdeTrustChangeDialog } from './IdeTrustChangeDialog.js';
import { WelcomeBackDialog } from './WelcomeBackDialog.js';
import { ModelSwitchDialog } from './ModelSwitchDialog.js';
import { AgentCreationWizard } from './subagents/create/AgentCreationWizard.js';
import { AgentsManagerDialog } from './subagents/manage/AgentsManagerDialog.js';
import { SessionPicker } from './SessionPicker.js';
Expand Down Expand Up @@ -236,10 +235,6 @@ export const DialogManager = ({
if (uiState.isModelDialogOpen) {
return <ModelDialog onClose={uiActions.closeModelDialog} />;
}
if (uiState.isVisionSwitchDialogOpen) {
return <ModelSwitchDialog onSelect={uiActions.handleVisionSwitchSelect} />;
}

if (uiState.isAuthDialogOpen || uiState.authError) {
return (
<Box flexDirection="column">
Expand Down
Loading