Wired embedding service into memory write path

This commit is contained in:
Storme-bit
2026-04-04 23:25:48 -07:00
parent 770d123419
commit ed18022d1f
3 changed files with 42 additions and 6 deletions

View File

@@ -1,5 +1,6 @@
const {getDB} = require('../db');
const { EPISODIC } = require('@nexusai/shared');
const { EPISODIC, getEnv, SERVICES } = require('@nexusai/shared');
const semantic = require('../semantic');
// --Sessions --------------------------------------------------
@@ -43,7 +44,7 @@ function deleteSession(id) {
// --Episodes --------------------------------------------------
// Creates a new episode linked to a session, with user message, AI response, optional token count, and metadata
function createEpisode(sessionId, userMessage, aiResponse, tokenCount = null, metadata = null) {
async function createEpisode(sessionId, userMessage, aiResponse, tokenCount = null, metadata = null) {
const db = getDB();
// Wrap insert + session touch in a transaction — both succeed or neither does
@@ -63,7 +64,17 @@ function createEpisode(sessionId, userMessage, aiResponse, tokenCount = null, me
return getEpisode(result.lastInsertRowid);
});
return insert();
const episode= insert();
//embed ascynchronously after SQLite completes, non-blocking. If embedding fail, the episode still saved.
getEpisodeEmbedding(userMessage, aiResponse)
.then(vector => semantic.upsertEpisode(episode.id, vector, {
sessionId: episode.session_id,
createdAt: episode.created_at
}))
.catch(err => console.error(`Failed to embed episode ${episode.id}:`, err.message));
return episode;
}
// Retrieves an episode by its ID
@@ -138,6 +149,26 @@ function parseEpisode(row) {
};
}
/******** Embedding Helper ********/
async function getEpisodeEmbedding(userMessage, aiResponse){
const url = getEnv('EMBEDDING_SERVICE_URL', SERVICES.EMBEDDING_URL);
//Combine user message and AI response for embedding
const text = `User: ${userMessage}\nAssistant: ${aiResponse}`;
const res = await fetch(`${url}/embed`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text })
})
if (!res.ok) {
throw new Error(`Embedding service error: ${res.status} ${res.statusText}`);
}
const data = await res.json();
return data.embedding;
}
module.exports = {
createSession,
getSession,

View File

@@ -19,8 +19,13 @@ const EPISODIC = {
DEFAULT_SEARCH_LIMIT: 10, // Default number of search results to return
};
const SERVICES = {
EMBEDDING_URL: 'http://localhost:3003'
};
module.exports = {
QDRANT,
COLLECTIONS,
EPISODIC
EPISODIC,
SERVICES
};

View File

@@ -1,4 +1,4 @@
const {getEnv} = require('./config/env');
const {QDRANT, COLLECTIONS, EPISODIC } = require('./config/constants');
const {QDRANT, COLLECTIONS, EPISODIC, SERVICES } = require('./config/constants');
module.exports = {getEnv, QDRANT, COLLECTIONS, EPISODIC};
module.exports = {getEnv, QDRANT, COLLECTIONS, EPISODIC, SERVICES};