From 0ee82f743095429c4779bea4784ab3718fda1c1f Mon Sep 17 00:00:00 2001 From: keith666666 <14068334+keith666666@users.noreply.github.com> Date: Thu, 2 Apr 2026 10:51:17 +0800 Subject: [PATCH] fix(engine): fix broken URL resolution in Ollama and MLX engines Both OllamaEngine and MLXEngine had two bugs in URL construction: 1. `axios.create({url: ...})` was used instead of `baseURL`, but `url` in axios config sets a default request URL - not a base prefix. This caused the URL to be ignored when `.post()` was called with a path. 2. `this.client.getUri(this.config)` was used to resolve the POST URL, but passing the engine config (which contains non-axios properties like `apiKey`, `model`, etc.) produced malformed URLs. When `apiKey` is null (the default for Ollama), the URL resolved to `http://localhost:11434/null`, returning HTTP 405. Fix: construct the full endpoint URL once in the constructor and pass it directly to `axios.post()`, matching how FlowiseEngine already works. Co-Authored-By: Claude --- src/engine/mlx.ts | 16 +++++++++------- src/engine/ollama.ts | 19 +++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/engine/mlx.ts b/src/engine/mlx.ts index 7068bb43..cb131864 100644 --- a/src/engine/mlx.ts +++ b/src/engine/mlx.ts @@ -6,16 +6,21 @@ import { AiEngine, AiEngineConfig } from './Engine'; interface MLXConfig extends AiEngineConfig {} +const DEFAULT_MLX_URL = 'http://localhost:8080'; +const MLX_CHAT_PATH = '/v1/chat/completions'; + export class MLXEngine implements AiEngine { config: MLXConfig; client: AxiosInstance; + private chatUrl: string; constructor(config) { this.config = config; + + const baseUrl = config.baseURL || DEFAULT_MLX_URL; + this.chatUrl = `${baseUrl}${MLX_CHAT_PATH}`; + this.client = axios.create({ - url: config.baseURL - ? `${config.baseURL}/${config.apiKey}` - : 'http://localhost:8080/v1/chat/completions', headers: { 'Content-Type': 'application/json' } }); } @@ -31,10 +36,7 @@ export class MLXEngine implements AiEngine { stream: false }; try { - const response = await this.client.post( - this.client.getUri(this.config), - params - ); + const response = await this.client.post(this.chatUrl, params); const choices = response.data.choices; const message = choices[0].message; diff --git a/src/engine/ollama.ts b/src/engine/ollama.ts index 1b530737..621bfcc3 100644 --- a/src/engine/ollama.ts +++ b/src/engine/ollama.ts @@ -6,25 +6,27 @@ import { AiEngine, AiEngineConfig } from './Engine'; interface OllamaConfig extends AiEngineConfig {} +const DEFAULT_OLLAMA_URL = 'http://localhost:11434'; +const OLLAMA_CHAT_PATH = '/api/chat'; + export class OllamaEngine implements AiEngine { config: OllamaConfig; client: AxiosInstance; + private chatUrl: string; constructor(config) { this.config = config; + const baseUrl = config.baseURL || DEFAULT_OLLAMA_URL; + this.chatUrl = `${baseUrl}${OLLAMA_CHAT_PATH}`; + // Combine base headers with custom headers const headers = { 'Content-Type': 'application/json', ...config.customHeaders }; - this.client = axios.create({ - url: config.baseURL - ? `${config.baseURL}/${config.apiKey}` - : 'http://localhost:11434/api/chat', - headers - }); + this.client = axios.create({ headers }); } async generateCommitMessage( @@ -37,10 +39,7 @@ export class OllamaEngine implements AiEngine { stream: false }; try { - const response = await this.client.post( - this.client.getUri(this.config), - params - ); + const response = await this.client.post(this.chatUrl, params); const { message } = response.data; let content = message?.content;