( baseUrl = "http://localhost:11434", apiKey?: string, )
| 60 | } |
| 61 | |
| 62 | export async function getOllamaModels( |
| 63 | baseUrl = "http://localhost:11434", |
| 64 | apiKey?: string, |
| 65 | ): Promise<Record<string, ModelInfo>> { |
| 66 | const models: Record<string, ModelInfo> = {} |
| 67 | |
| 68 | // clearing the input can leave an empty string; use the default in that case |
| 69 | baseUrl = baseUrl === "" ? "http://localhost:11434" : baseUrl |
| 70 | |
| 71 | try { |
| 72 | if (!URL.canParse(baseUrl)) { |
| 73 | return models |
| 74 | } |
| 75 | |
| 76 | // Prepare headers with optional API key |
| 77 | const headers: Record<string, string> = {} |
| 78 | if (apiKey) { |
| 79 | headers["Authorization"] = `Bearer ${apiKey}` |
| 80 | } |
| 81 | |
| 82 | const response = await axios.get<OllamaModelsResponse>(`${baseUrl}/api/tags`, { headers }) |
| 83 | const parsedResponse = OllamaModelsResponseSchema.safeParse(response.data) |
| 84 | const modelInfoPromises = [] |
| 85 | |
| 86 | if (parsedResponse.success) { |
| 87 | for (const ollamaModel of parsedResponse.data.models) { |
| 88 | modelInfoPromises.push( |
| 89 | axios |
| 90 | .post<OllamaModelInfoResponse>( |
| 91 | `${baseUrl}/api/show`, |
| 92 | { |
| 93 | model: ollamaModel.model, |
| 94 | }, |
| 95 | { headers }, |
| 96 | ) |
| 97 | .then((ollamaModelInfo) => { |
| 98 | const modelInfo = parseOllamaModel(ollamaModelInfo.data) |
| 99 | // Only include models that support native tools |
| 100 | if (modelInfo) { |
| 101 | models[ollamaModel.name] = modelInfo |
| 102 | } |
| 103 | }), |
| 104 | ) |
| 105 | } |
| 106 | |
| 107 | await Promise.all(modelInfoPromises) |
| 108 | } else { |
| 109 | console.error(`Error parsing Ollama models response: ${JSON.stringify(parsedResponse.error, null, 2)}`) |
| 110 | } |
| 111 | } catch (error) { |
| 112 | if (error.code === "ECONNREFUSED") { |
| 113 | console.warn(`Failed connecting to Ollama at ${baseUrl}`) |
| 114 | } else { |
| 115 | console.error( |
| 116 | `Error fetching Ollama models: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, |
| 117 | ) |
| 118 | } |
| 119 | } |
no test coverage detected