From 82c0b0dfd90c8ec883241b625d808d7c7f3181e6 Mon Sep 17 00:00:00 2001 From: Lifei Zhou Date: Wed, 1 Jul 2026 12:44:08 +1000 Subject: [PATCH] UI acp migratoin: Decouple desktop UI types from generated OpenAPI types (Part 2) (#10149) --- ui/desktop/src/acp/providers.ts | 3 +- ui/desktop/src/components/ConfigContext.tsx | 8 ++-- .../components/ModelAndProviderContext.tsx | 2 +- .../onboarding/ProviderConfigForm.tsx | 2 +- .../onboarding/ProviderSelector.tsx | 3 +- .../settings/dictation/DictationSettings.tsx | 2 +- .../settings/models/modelInterface.ts | 2 +- .../models/subcomponents/SwitchModelModal.tsx | 6 +-- .../settings/providers/ProviderGrid.tsx | 3 +- .../providers/ProviderSettingsPage.tsx | 2 +- .../modal/ProviderConfigurationModal.tsx | 2 +- .../subcomponents/ProviderSetupActions.tsx | 2 +- .../forms/DefaultProviderSetupForm.tsx | 2 +- .../providers/subcomponents/ProviderCard.tsx | 2 +- .../buttons/DefaultCardButtons.tsx | 2 +- ui/desktop/src/hooks/useAudioRecorder.ts | 2 +- ui/desktop/src/types/dictation.ts | 1 + ui/desktop/src/types/providers.ts | 46 +++++++++++++++++++ ui/desktop/src/vite-env.d.ts | 2 +- 19 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 ui/desktop/src/types/dictation.ts diff --git a/ui/desktop/src/acp/providers.ts b/ui/desktop/src/acp/providers.ts index c7be5b885c..e9e967f405 100644 --- a/ui/desktop/src/acp/providers.ts +++ b/ui/desktop/src/acp/providers.ts @@ -6,8 +6,7 @@ import type { ProviderTemplateCatalogEntryDto, ProviderTemplateDto, } from '@aaif/goose-sdk'; -import type { ProviderDetails, ThinkingEffort } from '../api'; -import type { UpdateCustomProviderRequest } from '../types/providers'; +import type { ProviderDetails, ThinkingEffort, UpdateCustomProviderRequest } from '../types/providers'; import { getAcpClient } from './acpConnection'; export type { CanonicalModelInfoDto, ProviderSecretDto }; diff --git a/ui/desktop/src/components/ConfigContext.tsx b/ui/desktop/src/components/ConfigContext.tsx index adf0bb36c3..4cb6236b1b 100644 --- a/ui/desktop/src/components/ConfigContext.tsx +++ b/ui/desktop/src/components/ConfigContext.tsx @@ -9,8 +9,8 @@ import { } from '../acp/extensions'; import { pruneDeprecatedBundledExtensions, syncBundledExtensions } from './settings/extensions'; import { nameToKey } from './settings/extensions/utils'; -import type { ConfigResponse, ProviderDetails } from '../api'; import type { ExtensionConfig } from '../types/extensions'; +import type { ProviderDetails } from '../types/providers'; export type { ExtensionConfig } from '../types/extensions'; @@ -20,8 +20,10 @@ export type FixedExtensionEntry = ExtensionConfig & { configKey?: string; }; +type ConfigMap = Record; + interface ConfigContextType { - config: ConfigResponse['config']; + config: ConfigMap; providersList: ProviderDetails[]; extensionsList: FixedExtensionEntry[]; extensionWarnings: string[]; @@ -42,7 +44,7 @@ interface ConfigProviderProps { const ConfigContext = createContext(undefined); export const ConfigProvider: React.FC = ({ children }) => { - const [config, setConfig] = useState({}); + const [config, setConfig] = useState({}); const [providersList, setProvidersList] = useState([]); const [extensionsList, setExtensionsList] = useState([]); const [extensionWarnings, setExtensionWarnings] = useState([]); diff --git a/ui/desktop/src/components/ModelAndProviderContext.tsx b/ui/desktop/src/components/ModelAndProviderContext.tsx index 81b41baa48..5bd3f9226a 100644 --- a/ui/desktop/src/components/ModelAndProviderContext.tsx +++ b/ui/desktop/src/components/ModelAndProviderContext.tsx @@ -1,7 +1,7 @@ import React, { createContext, useContext, useState, useEffect, useMemo, useCallback } from 'react'; import { toastError, toastSuccess } from '../toasts'; import Model, { getProviderMetadata } from './settings/models/modelInterface'; -import { ProviderMetadata } from '../api'; +import type { ProviderMetadata } from '../types/providers'; import { acpChatSessionActions, acpChatSessionStore } from '../acp/chatSessionStore'; import { acpReadDefaults, diff --git a/ui/desktop/src/components/onboarding/ProviderConfigForm.tsx b/ui/desktop/src/components/onboarding/ProviderConfigForm.tsx index dde92a8a50..a926c45f23 100644 --- a/ui/desktop/src/components/onboarding/ProviderConfigForm.tsx +++ b/ui/desktop/src/components/onboarding/ProviderConfigForm.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; -import { ProviderDetails } from '../../api'; import { acpAuthenticateProvider } from '../../acp/providers'; +import type { ProviderDetails } from '../../types/providers'; import DefaultProviderSetupForm, { ConfigInput, } from '../settings/providers/modal/subcomponents/forms/DefaultProviderSetupForm'; diff --git a/ui/desktop/src/components/onboarding/ProviderSelector.tsx b/ui/desktop/src/components/onboarding/ProviderSelector.tsx index ec202cde08..449a24b244 100644 --- a/ui/desktop/src/components/onboarding/ProviderSelector.tsx +++ b/ui/desktop/src/components/onboarding/ProviderSelector.tsx @@ -1,7 +1,6 @@ import { useState, useEffect, useMemo } from 'react'; -import type { ProviderDetails } from '../../api'; import { acpCreateCustomProviderFromRequest, acpListProviderDetails } from '../../acp/providers'; -import type { UpdateCustomProviderRequest } from '../../types/providers'; +import type { ProviderDetails, UpdateCustomProviderRequest } from '../../types/providers'; import { Select } from '../ui/Select'; import ProviderConfigForm from './ProviderConfigForm'; import LocalModelPicker from './LocalModelPicker'; diff --git a/ui/desktop/src/components/settings/dictation/DictationSettings.tsx b/ui/desktop/src/components/settings/dictation/DictationSettings.tsx index 31025ca3da..9b317ef46e 100644 --- a/ui/desktop/src/components/settings/dictation/DictationSettings.tsx +++ b/ui/desktop/src/components/settings/dictation/DictationSettings.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from 'react'; import { ChevronDown } from 'lucide-react'; -import { DictationProvider } from '../../../api'; import { getDictationConfig, DictationProviderStatusEntry } from '../../../acp/dictation'; import { useConfig } from '../../ConfigContext'; import { Input } from '../../ui/input'; @@ -10,6 +9,7 @@ import { LocalModelManager } from './LocalModelManager'; import { MicrophoneSelector } from './MicrophoneSelector'; import { DICTATION_ALLOWED_PROVIDERS } from '../../../updates'; import { useFeatures } from '../../../contexts/FeaturesContext'; +import type { DictationProvider } from '../../../types/dictation'; import { DropdownMenu, DropdownMenuContent, diff --git a/ui/desktop/src/components/settings/models/modelInterface.ts b/ui/desktop/src/components/settings/models/modelInterface.ts index a97b5d2d2a..b16f82ea85 100644 --- a/ui/desktop/src/components/settings/models/modelInterface.ts +++ b/ui/desktop/src/components/settings/models/modelInterface.ts @@ -1,6 +1,6 @@ -import { ProviderDetails, ThinkingEffort } from '../../../api'; import { listLocalModels } from '../../../acp/local-inference'; import { acpListProviderDetails, acpListProviderModels } from '../../../acp/providers'; +import type { ProviderDetails, ThinkingEffort } from '../../../types/providers'; import { errorMessage as getErrorMessage } from '../../../utils/conversionUtils'; export default interface Model { diff --git a/ui/desktop/src/components/settings/models/subcomponents/SwitchModelModal.tsx b/ui/desktop/src/components/settings/models/subcomponents/SwitchModelModal.tsx index f45d124e0c..326ca8e21b 100644 --- a/ui/desktop/src/components/settings/models/subcomponents/SwitchModelModal.tsx +++ b/ui/desktop/src/components/settings/models/subcomponents/SwitchModelModal.tsx @@ -27,7 +27,7 @@ import Model, { getProviderMetadata, } from '../modelInterface'; import { getPredefinedModelsFromEnv, shouldShowPredefinedModels } from '../predefinedModelsUtils'; -import type { ProviderType, ThinkingEffort } from '../../../../api'; +import type { ProviderDetails, ProviderType, ThinkingEffort } from '../../../../types/providers'; import { trackModelChanged } from '../../../../utils/analytics'; const i18n = defineMessages({ @@ -305,9 +305,7 @@ export const SwitchModelModal = ({ const [userClearedModel, setUserClearedModel] = useState(false); const [providerErrors, setProviderErrors] = useState>({}); const [providerWarnings, setProviderWarnings] = useState>({}); - const [activeProvidersList, setActiveProvidersList] = useState< - import('../../../../api').ProviderDetails[] - >([]); + const [activeProvidersList, setActiveProvidersList] = useState([]); const fetchedProviders = useRef>(new Set()); const reasoningRequestId = useRef(0); const [thinkingEffort, setThinkingEffort] = useState(null); diff --git a/ui/desktop/src/components/settings/providers/ProviderGrid.tsx b/ui/desktop/src/components/settings/providers/ProviderGrid.tsx index 4175b375d3..6efe13bbc8 100644 --- a/ui/desktop/src/components/settings/providers/ProviderGrid.tsx +++ b/ui/desktop/src/components/settings/providers/ProviderGrid.tsx @@ -2,9 +2,8 @@ import React, { memo, useMemo, useCallback, useState } from 'react'; import { ProviderCard } from './subcomponents/ProviderCard'; import CardContainer from './subcomponents/CardContainer'; import ProviderConfigurationModal from './modal/ProviderConfigurationModal'; -import type { ProviderDetails } from '../../../api'; import type { CustomProviderConfigDto } from '@aaif/goose-sdk'; -import type { UpdateCustomProviderRequest } from '../../../types/providers'; +import type { ProviderDetails, UpdateCustomProviderRequest } from '../../../types/providers'; import { acpCreateCustomProviderFromRequest, acpGetCustomProvider, diff --git a/ui/desktop/src/components/settings/providers/ProviderSettingsPage.tsx b/ui/desktop/src/components/settings/providers/ProviderSettingsPage.tsx index 3049ea5021..b15dff19bc 100644 --- a/ui/desktop/src/components/settings/providers/ProviderSettingsPage.tsx +++ b/ui/desktop/src/components/settings/providers/ProviderSettingsPage.tsx @@ -4,7 +4,7 @@ import { ScrollArea } from '../../ui/scroll-area'; import BackButton from '../../ui/BackButton'; import ProviderGrid from './ProviderGrid'; import { acpListProviderDetails } from '../../../acp/providers'; -import { ProviderDetails } from '../../../api'; +import type { ProviderDetails } from '../../../types/providers'; import { createNavigationHandler } from '../../../utils/navigationUtils'; import { defineMessages, useIntl } from '../../../i18n'; diff --git a/ui/desktop/src/components/settings/providers/modal/ProviderConfigurationModal.tsx b/ui/desktop/src/components/settings/providers/modal/ProviderConfigurationModal.tsx index aa3d4cb50b..4269a9c176 100644 --- a/ui/desktop/src/components/settings/providers/modal/ProviderConfigurationModal.tsx +++ b/ui/desktop/src/components/settings/providers/modal/ProviderConfigurationModal.tsx @@ -22,7 +22,7 @@ import { } from '../../../../acp/providers'; import { useModelAndProvider } from '../../../ModelAndProviderContext'; import { AlertTriangle, LogIn } from 'lucide-react'; -import { ProviderDetails } from '../../../../api'; +import type { ProviderDetails } from '../../../../types/providers'; import { Button } from '../../../../components/ui/button'; import { errorMessage } from '../../../../utils/conversionUtils'; import { defineMessages, useIntl } from '../../../../i18n'; diff --git a/ui/desktop/src/components/settings/providers/modal/subcomponents/ProviderSetupActions.tsx b/ui/desktop/src/components/settings/providers/modal/subcomponents/ProviderSetupActions.tsx index ae3816c3fe..62bfe75663 100644 --- a/ui/desktop/src/components/settings/providers/modal/subcomponents/ProviderSetupActions.tsx +++ b/ui/desktop/src/components/settings/providers/modal/subcomponents/ProviderSetupActions.tsx @@ -1,7 +1,7 @@ import { SyntheticEvent } from 'react'; import { Button } from '../../../../ui/button'; import { Trash2, AlertTriangle } from 'lucide-react'; -import { ConfigKey } from '../../../../../api'; +import type { ConfigKey } from '../../../../../types/providers'; import { defineMessages, useIntl } from '../../../../../i18n'; const i18n = defineMessages({ diff --git a/ui/desktop/src/components/settings/providers/modal/subcomponents/forms/DefaultProviderSetupForm.tsx b/ui/desktop/src/components/settings/providers/modal/subcomponents/forms/DefaultProviderSetupForm.tsx index 9ebb333f3e..dd6a155c7d 100644 --- a/ui/desktop/src/components/settings/providers/modal/subcomponents/forms/DefaultProviderSetupForm.tsx +++ b/ui/desktop/src/components/settings/providers/modal/subcomponents/forms/DefaultProviderSetupForm.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useMemo, useState, useCallback } from 'react'; import { Input } from '../../../../../ui/input'; import { acpReadProviderConfig } from '../../../../../../acp/providers'; -import { ProviderDetails, ConfigKey } from '../../../../../../api'; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../../../../../ui/collapsible'; +import type { ConfigKey, ProviderDetails } from '../../../../../../types/providers'; import { configLabels, configPlaceholders } from '../../../../../../utils/configUtils'; import { defineMessages, useIntl } from '../../../../../../i18n'; diff --git a/ui/desktop/src/components/settings/providers/subcomponents/ProviderCard.tsx b/ui/desktop/src/components/settings/providers/subcomponents/ProviderCard.tsx index 4b9baf5edb..66d374344f 100644 --- a/ui/desktop/src/components/settings/providers/subcomponents/ProviderCard.tsx +++ b/ui/desktop/src/components/settings/providers/subcomponents/ProviderCard.tsx @@ -3,7 +3,7 @@ import CardContainer from './CardContainer'; import CardHeader from './CardHeader'; import CardBody from './CardBody'; import DefaultCardButtons from './buttons/DefaultCardButtons'; -import { ProviderDetails, ProviderMetadata } from '../../../../api'; +import type { ProviderDetails, ProviderMetadata } from '../../../../types/providers'; import { defineMessages, useIntl } from '../../../../i18n'; const i18n = defineMessages({ diff --git a/ui/desktop/src/components/settings/providers/subcomponents/buttons/DefaultCardButtons.tsx b/ui/desktop/src/components/settings/providers/subcomponents/buttons/DefaultCardButtons.tsx index 7bd7033fe0..d101701fbf 100644 --- a/ui/desktop/src/components/settings/providers/subcomponents/buttons/DefaultCardButtons.tsx +++ b/ui/desktop/src/components/settings/providers/subcomponents/buttons/DefaultCardButtons.tsx @@ -1,5 +1,5 @@ import { ConfigureSettingsButton, RocketButton } from './CardButtons'; -import { ProviderDetails } from '../../../../../api'; +import type { ProviderDetails } from '../../../../../types/providers'; import { defineMessages, useIntl } from '../../../../../i18n'; const i18n = defineMessages({ diff --git a/ui/desktop/src/hooks/useAudioRecorder.ts b/ui/desktop/src/hooks/useAudioRecorder.ts index 4886529b7d..4e4fe68c29 100644 --- a/ui/desktop/src/hooks/useAudioRecorder.ts +++ b/ui/desktop/src/hooks/useAudioRecorder.ts @@ -1,7 +1,7 @@ import { useState, useRef, useCallback, useEffect } from 'react'; -import { DictationProvider } from '../api'; import { getDictationConfig, transcribeDictation } from '../acp/dictation'; import { useConfig } from '../components/ConfigContext'; +import type { DictationProvider } from '../types/dictation'; import { errorMessage } from '../utils/conversionUtils'; interface UseAudioRecorderOptions { diff --git a/ui/desktop/src/types/dictation.ts b/ui/desktop/src/types/dictation.ts new file mode 100644 index 0000000000..35efe3fcef --- /dev/null +++ b/ui/desktop/src/types/dictation.ts @@ -0,0 +1 @@ +export type DictationProvider = 'openai' | 'elevenlabs' | 'groq' | 'local'; diff --git a/ui/desktop/src/types/providers.ts b/ui/desktop/src/types/providers.ts index 904191e031..ca38d7ba70 100644 --- a/ui/desktop/src/types/providers.ts +++ b/ui/desktop/src/types/providers.ts @@ -1,3 +1,49 @@ +export type ProviderType = 'Preferred' | 'Builtin' | 'Declarative' | 'Custom'; + +export type ThinkingEffort = 'off' | 'low' | 'medium' | 'high' | 'max'; + +export type ConfigKey = { + default?: string | null; + device_code_flow?: boolean; + name: string; + oauth_flow: boolean; + primary?: boolean; + required: boolean; + secret: boolean; +}; + +export type ModelInfo = { + context_limit: number; + currency?: string | null; + input_token_cost?: number | null; + name: string; + output_token_cost?: number | null; + reasoning?: boolean; + resolved_model?: string | null; + supports_cache_control?: boolean | null; +}; + +export type ProviderMetadata = { + config_keys: ConfigKey[]; + default_model: string; + description: string; + display_name: string; + fast_model?: string | null; + known_models: ModelInfo[]; + model_doc_link: string; + model_selection_hint?: string | null; + name: string; + setup_steps?: string[]; +}; + +export type ProviderDetails = { + is_configured: boolean; + metadata: ProviderMetadata; + name: string; + provider_type: ProviderType; + saved_model?: string | null; +}; + export type UpdateCustomProviderRequest = { api_key: string; api_url: string; diff --git a/ui/desktop/src/vite-env.d.ts b/ui/desktop/src/vite-env.d.ts index d7c35b6a52..574828ce86 100644 --- a/ui/desktop/src/vite-env.d.ts +++ b/ui/desktop/src/vite-env.d.ts @@ -59,7 +59,7 @@ declare global { sessionId: string; }>; responseStyleChanged: CustomEvent; - 'session-created': CustomEvent<{ session?: import('./api').Session }>; + 'session-created': CustomEvent<{ session?: import('./types/session').Session }>; 'session-deleted': CustomEvent<{ sessionId: string }>; 'session-renamed': CustomEvent<{ sessionId: string;