require ('dotenv').config(); const express = require('express'); const {getEnv, OLLAMA, PORTS, logger} = require('@nexusai/shared'); const app = express(); app.use(express.json()); const PORT = getEnv('PORT', PORTS.EMBEDDING); const OLLAMA_URL = getEnv('OLLAMA_URL', OLLAMA.DEFAULT_URL); const EMBED_MODEL = getEnv('EMBEDDING_MODEL', OLLAMA.EMBED_MODEL); //OLLAMA embedding helper function async function embedText(text) { const res = await fetch(`${OLLAMA_URL}/api/embed`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: EMBED_MODEL, input: text }) }); if (!res.ok) { throw new Error(`Ollama error: ${res.status} ${res.statusText}`); } const data = await res.json(); return data.embeddings[0]; } /**** ROUTES ***** */ // Health check endpoint app.get('/health', (req,res) => { res.json({ service: 'Embedding Service', status: 'healthy' }); }) // Single text embedding app.post('/embed', async (req, res) => { const { text } = req.body; if (!text || typeof text !== 'string' || text.trim() === '') { return res.status(400).json({ error: 'text is required and must be empty' }); } try { const embedding = await embedText(text.trim()); res.json({ embedding, model: EMBED_MODEL, dimensions: embedding.length }); } catch (err) { res.status(502).json({ error: 'Embedding failed', detail: err.message }); } }); // Batch embedding endpoint app.post('/embed/batch', async (req, res) => { const { texts } = req.body; if (!Array.isArray(texts) || texts.length ===0 ) { return res.status(400).json({ error: 'texts array must not be empty' }); } try { //sequential embedding for now, Ollama doesn't natively parallize embeddings const embeddings = []; for (const text of texts) { embeddings.push(await embedText(text.trim())); } res.json ({ embeddings, model: EMBED_MODEL, dimensions: embeddings[0].length, count: embeddings.length }) } catch (err) { res.status(502).json({ error: 'Batch embedding failed', detail: err.message }); } }) /******* Start Server ********/ app.listen(PORT, () => { logger.info(`Embedding Service listening on port ${PORT}`); });