diff --git a/Dockerfile b/Dockerfile index ffec336..4eb8a3c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,6 +32,12 @@ RUN apt-get update && apt-get install -y \ COPY package*.json ./ RUN npm install --ignore-scripts +# --ignore-scripts skips node-gyp rebuild for native modules +# (security best-practice, blocks malicious postinstall scripts). +# Explicitly rebuild better-sqlite3 so its arm64/amd64 .node binding +# is compiled — otherwise the runtime fails with "Could not locate +# the bindings file" on architectures lacking a prebuild. +RUN npm rebuild better-sqlite3 # Install Chrome via Puppeteer as fallback (system Chromium will be used first) RUN npx puppeteer browsers install chrome || true COPY . . diff --git a/README.md b/README.md index 79ca99e..253fb27 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,16 @@ Configuration is managed through two files: OPENAI_API_KEY="sk-..." OPENAI_MODEL="text-embedding-3-large" # Optional, defaults to text-embedding-3-large + # Optional: Override the OpenAI API base URL. Useful for pointing the + # OpenAI SDK at an OpenAI-compatible endpoint such as Ollama, LM Studio, + # llama.cpp, vLLM, or a proxy gateway. When unset, the SDK uses the + # default OpenAI endpoint. Equivalent to the `embedding.openai.base_url` + # field in config.yaml; the env var wins if both are set. + # Example values: + # OPENAI_BASE_URL="http://localhost:11434/v1" # Ollama + # OPENAI_BASE_URL="https://gateway.example.com/v1" # proxy / gateway + OPENAI_BASE_URL="http://localhost:11434/v1" + # Optional: Embedding dimension size (defaults to 3072) EMBEDDING_DIMENSION="3072" @@ -277,6 +287,7 @@ Configuration is managed through two files: openai: api_key: '${OPENAI_API_KEY}' # Optional, uses env var by default model: 'text-embedding-3-large' # Optional, defaults to text-embedding-3-large + # base_url: 'http://localhost:11434/v1' # Optional, override OpenAI API base URL for Ollama / other OpenAI-compatible endpoints. Falls back to OPENAI_BASE_URL env var. # For Azure OpenAI, use this instead: # azure: # api_key: '${AZURE_OPENAI_KEY}' diff --git a/doc2vec.ts b/doc2vec.ts index fe107b7..13e7352 100644 --- a/doc2vec.ts +++ b/doc2vec.ts @@ -89,15 +89,19 @@ export class Doc2Vec { } else { const openaiApiKey = embeddingConfig.openai?.api_key || process.env.OPENAI_API_KEY; const openaiModel = embeddingConfig.openai?.model || process.env.OPENAI_MODEL || 'text-embedding-3-large'; - + const openaiBaseURL = embeddingConfig.openai?.base_url || process.env.OPENAI_BASE_URL; + if (!openaiApiKey) { this.logger.error('OpenAI requires api_key to be configured'); process.exit(1); } - - this.openai = new OpenAI({ apiKey: openaiApiKey }); + + this.openai = new OpenAI({ + apiKey: openaiApiKey, + ...(openaiBaseURL && { baseURL: openaiBaseURL }), + }); this.embeddingModel = openaiModel; - this.logger.info(`Using OpenAI with model: ${openaiModel} (${this.embeddingDimension} dimensions)`); + this.logger.info(`Using OpenAI with model: ${openaiModel} (${this.embeddingDimension} dimensions)${openaiBaseURL ? ` via ${openaiBaseURL}` : ''}`); } this.contentProcessor = new ContentProcessor(this.logger); diff --git a/mcp/package.json b/mcp/package.json index 1869fc5..253edb2 100644 --- a/mcp/package.json +++ b/mcp/package.json @@ -1,6 +1,6 @@ { "name": "sqlite-vec-mcp-server", - "version": "2.1.0", + "version": "2.1.1", "description": "MCP Server for querying documentation with sqlite-vec", "main": "build/index.js", "type": "module", diff --git a/mcp/src/index.ts b/mcp/src/index.ts index 7f48875..7273cf2 100644 --- a/mcp/src/index.ts +++ b/mcp/src/index.ts @@ -34,6 +34,7 @@ const embeddingProvider = process.env.EMBEDDING_PROVIDER || 'openai'; // OpenAI configuration const openAIApiKey = process.env.OPENAI_API_KEY; const openAIModel = process.env.OPENAI_MODEL || 'text-embedding-3-large'; +const openAIBaseURL = process.env.OPENAI_BASE_URL; // Optional: override API base URL for Ollama / other OpenAI-compatible endpoints // Azure OpenAI configuration const azureApiKey = process.env.AZURE_OPENAI_KEY; @@ -110,6 +111,7 @@ async function createEmbeddings(text: string): Promise { case 'openai': { const openai = new OpenAI({ apiKey: openAIApiKey, + ...(openAIBaseURL && { baseURL: openAIBaseURL }), }); const response = await openai.embeddings.create({ model: openAIModel, diff --git a/package.json b/package.json index 4ba2cd6..ae29d6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "doc2vec", - "version": "2.10.2", + "version": "2.10.3", "type": "commonjs", "description": "", "main": "dist/doc2vec.js", diff --git a/types.ts b/types.ts index 67d359c..995c022 100644 --- a/types.ts +++ b/types.ts @@ -99,8 +99,9 @@ export interface EmbeddingConfig { provider: 'openai' | 'azure'; dimension?: number; openai?: { - api_key?: string; // Can also use OPENAI_API_KEY env var - model?: string; // Default: text-embedding-3-large + api_key?: string; // Can also use OPENAI_API_KEY env var + model?: string; // Default: text-embedding-3-large + base_url?: string; // Override OpenAI API base URL — useful for Ollama or other OpenAI-compatible endpoints. Can also use OPENAI_BASE_URL env var. }; azure?: { api_key?: string; // Can also use AZURE_OPENAI_KEY env var