feat(app): provider system overhaul with model selector, diagnostics, and UX polish
- Add CombinedModelSelector with two-level drill-down (providers → models), favorites section, search, and single-provider auto-drill mode - Add provider snapshot system (ProviderSnapshotManager) for cached provider/model state - Add provider diagnostics with resolved binary paths and versions across all providers - Add StatusBadge shared component for consistent status visual language - Add ProviderDiagnosticSheet for detailed provider health inspection - Add desktop auto-focus on input after any status bar interaction (model, mode, thinking, features) using focusWithRetries - Fix Combobox flicker on height change by switching to bottom-based CSS positioning once initial floating-ui position resolves - Add dynamic dropdown height: Level 1 fits content, Level 2 calculates from model count - Remove "Other providers" section from model selector (only show available providers)
This commit is contained in:
@@ -75,6 +75,7 @@ export function WorkspaceDraftAgentTab({
|
||||
modeOptions,
|
||||
availableModels,
|
||||
allProviderModels,
|
||||
allProviderEntries,
|
||||
isAllModelsLoading,
|
||||
availableThinkingOptions,
|
||||
isModelLoading,
|
||||
@@ -250,6 +251,60 @@ export function WorkspaceDraftAgentTab({
|
||||
addImagesRef.current = addImages;
|
||||
}, []);
|
||||
|
||||
const focusInputRef = useRef<(() => void) | null>(null);
|
||||
|
||||
const handleFocusInputCallback = useCallback((focus: () => void) => {
|
||||
focusInputRef.current = focus;
|
||||
}, []);
|
||||
|
||||
const handleProviderSelectWithFocus = useCallback(
|
||||
(provider: string) => {
|
||||
setProviderFromUser(provider);
|
||||
focusInputRef.current?.();
|
||||
},
|
||||
[setProviderFromUser],
|
||||
);
|
||||
|
||||
const handleModeSelectWithFocus = useCallback(
|
||||
(modeId: string) => {
|
||||
setModeFromUser(modeId);
|
||||
focusInputRef.current?.();
|
||||
},
|
||||
[setModeFromUser],
|
||||
);
|
||||
|
||||
const handleModelSelectWithFocus = useCallback(
|
||||
(modelId: string) => {
|
||||
setModelFromUser(modelId);
|
||||
focusInputRef.current?.();
|
||||
},
|
||||
[setModelFromUser],
|
||||
);
|
||||
|
||||
const handleProviderAndModelSelectWithFocus = useCallback(
|
||||
(provider: string, modelId: string) => {
|
||||
setProviderAndModelFromUser(provider, modelId);
|
||||
focusInputRef.current?.();
|
||||
},
|
||||
[setProviderAndModelFromUser],
|
||||
);
|
||||
|
||||
const handleThinkingOptionSelectWithFocus = useCallback(
|
||||
(optionId: string) => {
|
||||
setThinkingOptionFromUser(optionId);
|
||||
focusInputRef.current?.();
|
||||
},
|
||||
[setThinkingOptionFromUser],
|
||||
);
|
||||
|
||||
const handleSetFeatureWithFocus = useCallback(
|
||||
(featureId: string, value: unknown) => {
|
||||
setDraftFeatureValue(featureId, value);
|
||||
focusInputRef.current?.();
|
||||
},
|
||||
[setDraftFeatureValue],
|
||||
);
|
||||
|
||||
return (
|
||||
<FileDropZone onFilesDropped={handleFilesDropped}>
|
||||
<View style={styles.container}>
|
||||
@@ -296,26 +351,28 @@ export function WorkspaceDraftAgentTab({
|
||||
clearDraft={draftInput.clear}
|
||||
autoFocus={shouldAutoFocusWorkspaceDraftComposer({ isPaneFocused, isSubmitting })}
|
||||
onAddImages={handleAddImagesCallback}
|
||||
onFocusInput={handleFocusInputCallback}
|
||||
commandDraftConfig={draftCommandConfig}
|
||||
statusControls={{
|
||||
providerDefinitions,
|
||||
selectedProvider,
|
||||
onSelectProvider: setProviderFromUser,
|
||||
onSelectProvider: handleProviderSelectWithFocus,
|
||||
modeOptions,
|
||||
selectedMode,
|
||||
onSelectMode: setModeFromUser,
|
||||
onSelectMode: handleModeSelectWithFocus,
|
||||
models: availableModels,
|
||||
selectedModel,
|
||||
onSelectModel: setModelFromUser,
|
||||
onSelectModel: handleModelSelectWithFocus,
|
||||
isModelLoading,
|
||||
allProviderModels,
|
||||
isAllModelsLoading,
|
||||
onSelectProviderAndModel: setProviderAndModelFromUser,
|
||||
onSelectProviderAndModel: handleProviderAndModelSelectWithFocus,
|
||||
thinkingOptions: availableThinkingOptions,
|
||||
selectedThinkingOptionId,
|
||||
onSelectThinkingOption: setThinkingOptionFromUser,
|
||||
onSelectThinkingOption: handleThinkingOptionSelectWithFocus,
|
||||
features: draftFeatures,
|
||||
onSetFeature: setDraftFeatureValue,
|
||||
onSetFeature: handleSetFeatureWithFocus,
|
||||
onDropdownClose: () => focusInputRef.current?.(),
|
||||
disabled: isSubmitting,
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user