diff --git a/ui/src/hooks/use-copilot.ts b/ui/src/hooks/use-copilot.ts index b250be50..66d2b6fa 100644 --- a/ui/src/hooks/use-copilot.ts +++ b/ui/src/hooks/use-copilot.ts @@ -30,6 +30,10 @@ export interface CopilotConfig { rate_limit: number | null; wait_on_limit: boolean; model: string; + // Model mapping for Claude tiers + opus_model?: string; + sonnet_model?: string; + haiku_model?: string; } export interface CopilotModel { @@ -40,6 +44,15 @@ export interface CopilotModel { isCurrent?: boolean; } +export interface CopilotRawSettings { + settings: { + env?: Record; + }; + mtime: number; + path: string; + exists: boolean; +} + // API functions async function fetchCopilotStatus(): Promise { const res = await fetch(`${API_BASE}/copilot/status`); @@ -59,6 +72,12 @@ async function fetchCopilotModels(): Promise<{ models: CopilotModel[]; current: return res.json(); } +async function fetchCopilotRawSettings(): Promise { + const res = await fetch(`${API_BASE}/copilot/settings/raw`); + if (!res.ok) throw new Error('Failed to fetch copilot raw settings'); + return res.json(); +} + async function updateCopilotConfig(config: Partial): Promise<{ success: boolean }> { const res = await fetch(`${API_BASE}/copilot/config`, { method: 'PUT', @@ -69,6 +88,20 @@ async function updateCopilotConfig(config: Partial): Promise<{ su return res.json(); } +async function saveCopilotRawSettings(data: { + settings: CopilotRawSettings['settings']; + expectedMtime?: number; +}): Promise<{ success: boolean; mtime: number }> { + const res = await fetch(`${API_BASE}/copilot/settings/raw`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(data), + }); + if (res.status === 409) throw new Error('CONFLICT'); + if (!res.ok) throw new Error('Failed to save copilot raw settings'); + return res.json(); +} + async function startCopilotAuth(): Promise<{ success: boolean; error?: string }> { const res = await fetch(`${API_BASE}/copilot/auth/start`, { method: 'POST' }); if (!res.ok) throw new Error('Failed to start auth'); @@ -108,12 +141,27 @@ export function useCopilot() { queryFn: fetchCopilotModels, }); + const rawSettingsQuery = useQuery({ + queryKey: ['copilot-raw-settings'], + queryFn: fetchCopilotRawSettings, + }); + // Mutations const updateConfigMutation = useMutation({ mutationFn: updateCopilotConfig, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['copilot-status'] }); queryClient.invalidateQueries({ queryKey: ['copilot-config'] }); + queryClient.invalidateQueries({ queryKey: ['copilot-raw-settings'] }); + }, + }); + + const saveRawSettingsMutation = useMutation({ + mutationFn: saveCopilotRawSettings, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['copilot-status'] }); + queryClient.invalidateQueries({ queryKey: ['copilot-config'] }); + queryClient.invalidateQueries({ queryKey: ['copilot-raw-settings'] }); }, }); @@ -157,11 +205,20 @@ export function useCopilot() { currentModel: modelsQuery.data?.current, modelsLoading: modelsQuery.isLoading, + // Raw Settings + rawSettings: rawSettingsQuery.data, + rawSettingsLoading: rawSettingsQuery.isLoading, + refetchRawSettings: rawSettingsQuery.refetch, + // Mutations updateConfig: updateConfigMutation.mutate, updateConfigAsync: updateConfigMutation.mutateAsync, isUpdating: updateConfigMutation.isPending, + saveRawSettings: saveRawSettingsMutation.mutate, + saveRawSettingsAsync: saveRawSettingsMutation.mutateAsync, + isSavingRawSettings: saveRawSettingsMutation.isPending, + startAuth: startAuthMutation.mutate, isAuthenticating: startAuthMutation.isPending,