Skip to content

Commit 5892be2

Browse files
authored
Merge pull request #18 from neodon/openai-compatible-configs
add configuration for OpenAI-compatible embeddings providers
2 parents 120135c + 803b12f commit 5892be2

5 files changed

Lines changed: 31 additions & 15 deletions

File tree

.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ OM_ADV_EMBED_PARALLEL=false
5454
# Delay between embeddings in milliseconds
5555
OM_EMBED_DELAY_MS=200
5656

57+
# OpenAI-compatible Embeddings Provider
58+
# OM_OPENAI_BASE_URL=https://api.openai.com/v1
59+
# Model override for all sector embeddings (leave empty to use defaults)
60+
# OM_OPENAI_MODEL=text-embedding-qwen3-embedding-4b
61+
62+
# API Configuration
63+
# Max request body size in bytes (default: 1MB)
64+
OM_MAX_PAYLOAD_SIZE=1000000
65+
5766
# --------------------------------------------
5867
# Embedding Provider API Keys
5968
# --------------------------------------------

backend/src/config/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ export const env = {
1212
adv_embed_parallel: process.env.OM_ADV_EMBED_PARALLEL === 'true',
1313
embed_delay_ms: Number(process.env.OM_EMBED_DELAY_MS) || 200,
1414
openai_key: process.env.OPENAI_API_KEY || process.env.OM_OPENAI_API_KEY || '',
15+
openai_base_url: process.env.OM_OPENAI_BASE_URL || 'https://api.openai.com/v1',
16+
openai_model: process.env.OM_OPENAI_MODEL || undefined,
1517
gemini_key: process.env.GEMINI_API_KEY || process.env.OM_GEMINI_API_KEY || '',
1618
ollama_url: process.env.OLLAMA_URL || process.env.OM_OLLAMA_URL || 'http://localhost:11434',
1719
local_model_path: process.env.LOCAL_MODEL_PATH || process.env.OM_LOCAL_MODEL_PATH || '',
1820
vec_dim: Number(process.env.OM_VEC_DIM) || 768,
1921
min_score: Number(process.env.OM_MIN_SCORE) || 0.3,
2022
decay_lambda: Number(process.env.OM_DECAY_LAMBDA) || 0.02,
23+
max_payload_size: Number(process.env.OM_MAX_PAYLOAD_SIZE) || 1_000_000,
2124
mode: (process.env.OM_MODE || 'standard').toLowerCase(),
2225
lg_namespace: process.env.OM_LG_NAMESPACE || 'default',
2326
lg_max_context: Number(process.env.OM_LG_MAX_CONTEXT) || 50,

backend/src/embedding/index.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,18 @@ export async function embedForSector(text: string, sector: string): Promise<numb
3939
async function embedWithOpenAI(text: string, sector: string): Promise<number[]> {
4040
if (!env.openai_key) throw new Error('OpenAI API key not configured')
4141

42-
const modelMap: Record<string, string> = {
42+
const defaultModelMap: Record<string, string> = {
4343
episodic: 'text-embedding-3-small',
4444
semantic: 'text-embedding-3-small',
4545
procedural: 'text-embedding-3-small',
4646
emotional: 'text-embedding-3-small',
4747
reflective: 'text-embedding-3-large'
4848
}
4949

50-
const model = modelMap[sector] || 'text-embedding-3-small'
50+
const model = env.openai_model || defaultModelMap[sector] || 'text-embedding-3-small'
5151

52-
const response = await fetch('https://api.openai.com/v1/embeddings', {
52+
const baseUrl = env.openai_base_url.replace(/\/$/, '')
53+
const response = await fetch(`${baseUrl}/embeddings`, {
5354
method: 'POST',
5455
headers: {
5556
'content-type': 'application/json',
@@ -58,7 +59,7 @@ async function embedWithOpenAI(text: string, sector: string): Promise<number[]>
5859
body: JSON.stringify({
5960
input: text,
6061
model,
61-
dimensions: env.vec_dim <= 1536 ? env.vec_dim : undefined
62+
dimensions: env.vec_dim
6263
})
6364
})
6465

@@ -73,11 +74,12 @@ async function embedWithOpenAI(text: string, sector: string): Promise<number[]>
7374
async function embedBatchOpenAI(texts: Record<string, string>): Promise<Record<string, number[]>> {
7475
if (!env.openai_key) throw new Error('OpenAI API key not configured')
7576

76-
const model = 'text-embedding-3-small'
77+
const model = env.openai_model || 'text-embedding-3-small'
7778
const inputTexts = Object.values(texts)
7879
const sectors = Object.keys(texts)
7980

80-
const response = await fetch('https://api.openai.com/v1/embeddings', {
81+
const baseUrl = env.openai_base_url.replace(/\/$/, '')
82+
const response = await fetch(`${baseUrl}/embeddings`, {
8183
method: 'POST',
8284
headers: {
8385
'content-type': 'application/json',
@@ -86,7 +88,7 @@ async function embedBatchOpenAI(texts: Record<string, string>): Promise<Record<s
8688
body: JSON.stringify({
8789
input: inputTexts,
8890
model,
89-
dimensions: env.vec_dim <= 1536 ? env.vec_dim : undefined
91+
dimensions: env.vec_dim
9092
})
9193
})
9294

@@ -492,13 +494,15 @@ export function getEmbeddingInfo(): Record<string, any> {
492494
switch (env.emb_kind) {
493495
case 'openai':
494496
info.configured = !!env.openai_key
497+
info.base_url = env.openai_base_url
498+
info.model_override = env.openai_model || null
495499
info.batch_api = env.embed_mode === 'simple'
496500
info.models = {
497-
episodic: 'text-embedding-3-small',
498-
semantic: 'text-embedding-3-small',
499-
procedural: 'text-embedding-3-small',
500-
emotional: 'text-embedding-3-small',
501-
reflective: 'text-embedding-3-large'
501+
episodic: env.openai_model || 'text-embedding-3-small',
502+
semantic: env.openai_model || 'text-embedding-3-small',
503+
procedural: env.openai_model || 'text-embedding-3-small',
504+
emotional: env.openai_model || 'text-embedding-3-small',
505+
reflective: env.openai_model || 'text-embedding-3-large'
502506
}
503507
break
504508
case 'gemini':

backend/src/server/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import type {
2323
ingest_url_req
2424
} from '../types'
2525

26-
const app = server()
26+
const app = server({ max_payload_size: env.max_payload_size })
2727

2828
app.use((req: any, res: any, next: any) => {
2929
res.setHeader('Access-Control-Allow-Origin', '*')

backend/src/server/server.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const path = require('path');
2626
const http = require('http');
2727
const WebSocket = require('ws');
2828
const { parse } = require('url');
29-
function server() {
29+
function server(config = {}) {
3030
const ROUTES = [];
3131
const WARES = [];
3232
const WS_ROUTES = [];
@@ -159,7 +159,7 @@ function server() {
159159
use((req, res, next) => {
160160
if (req.headers['content-type']?.includes('application/json')) {
161161
let d = '';
162-
let max = 1e6;
162+
let max = config.max_payload_size || 1_000_000;
163163
req.on('data', e => {
164164
d += e;
165165
if (d.length > max) {

0 commit comments

Comments
 (0)