All files / src/components/settings/utils useDynamicProviderModels.ts

9.43% Statements 5/53
100% Branches 0/0
0% Functions 0/1
9.43% Lines 5/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 781x 1x 1x 1x                                 1x                                                                                                                  
import { ModelInfo, openAiModelInfoSaneDefaults } from "@shared/api"
import { OpenAiModelsRequest } from "@shared/proto/cline/models"
import { useCallback, useEffect, useMemo, useState } from "react"
import { ModelsServiceClient } from "@/services/grpc-client"
 
interface UseDynamicProviderModelsParams {
	baseUrl?: string
	apiKey?: string
	fallbackModels: Record<string, ModelInfo>
	selectedModelId?: string
	selectedModelInfo?: ModelInfo
	enabled?: boolean
}
 
interface UseDynamicProviderModelsResult {
	models: Record<string, ModelInfo>
	refresh: () => Promise<void>
	isLoading: boolean
}
 
export function useDynamicProviderModels({
	baseUrl,
	apiKey,
	fallbackModels,
	selectedModelId,
	selectedModelInfo,
	enabled = true,
}: UseDynamicProviderModelsParams): UseDynamicProviderModelsResult {
	const [dynamicModelIds, setDynamicModelIds] = useState<string[]>([])
	const [isLoading, setIsLoading] = useState(false)
 
	const refresh = useCallback(async () => {
		if (!enabled || !baseUrl || !apiKey) {
			setDynamicModelIds([])
			return
		}
 
		setIsLoading(true)
		try {
			const response = await ModelsServiceClient.refreshOpenAiModels(
				OpenAiModelsRequest.create({
					baseUrl,
					apiKey,
				}),
			)
			setDynamicModelIds(response?.values ?? [])
		} catch (error) {
			console.error("Failed to refresh provider models:", error)
			setDynamicModelIds([])
		} finally {
			setIsLoading(false)
		}
	}, [apiKey, baseUrl, enabled])
 
	useEffect(() => {
		refresh()
	}, [refresh])
 
	const models = useMemo(() => {
		if (!dynamicModelIds.length) {
			return fallbackModels
		}
 
		const dynamicModels: Record<string, ModelInfo> = {}
		for (const modelId of dynamicModelIds) {
			dynamicModels[modelId] = fallbackModels[modelId] ||
				(selectedModelId === modelId ? selectedModelInfo : undefined) || {
					...openAiModelInfoSaneDefaults,
					description: "Model metadata unavailable from provider API",
				}
		}
 
		return dynamicModels
	}, [dynamicModelIds, fallbackModels, selectedModelId, selectedModelInfo])
 
	return { models, refresh, isLoading }
}