chore: CRM-NEW baseline

This commit is contained in:
wangliang
2026-10-23 10:35:28 +08:00
commit aa499f6dbf
111 changed files with 15126 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
'use strict';
const { Pool } = require('pg');
const cache = new Map();
const CACHE_MAX = 200;
function createEmbeddingClient(cfg, opts = {}) {
const pool = new Pool({ connectionString: opts.pgUrl || cfg.ragPgUrl, max: 2, connectionTimeoutMillis: 5000 });
const model = cfg.embModel || 'text-embedding-v4';
const dim = cfg.embDim || 1024;
const baseUrl = String(cfg.embBaseUrl || '').replace(/\/+$/, '');
const apiKey = cfg.embApiKey;
const translateModel = cfg.embTranslateModel || 'qwen-turbo';
async function embedQuery(text) {
const key = String(text || '').slice(0, 200);
if (cache.has(key)) return cache.get(key);
if (!baseUrl || !apiKey) throw new Error('Embedding provider is not configured');
const res = await fetch(`${baseUrl}/embeddings`, {
method: 'POST',
headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ model, input: text, encoding_format: 'float', dimensions: dim }),
signal: AbortSignal.timeout(15000),
});
const json = await res.json();
if (!res.ok || !json.data || !json.data[0] || !json.data[0].embedding) {
throw new Error('embedQuery failed: ' + JSON.stringify(json).slice(0, 200));
}
const vec = json.data[0].embedding;
if (cache.size >= CACHE_MAX) cache.delete(cache.keys().next().value);
cache.set(key, vec);
return vec;
}
function vecStr(v) {
return '[' + v.join(',') + ']';
}
async function translateQueryToEnglish(query) {
try {
const res = await fetch(`${baseUrl}/chat/completions`, {
method: 'POST',
headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
model: translateModel,
max_tokens: 80,
messages: [
{ role: 'system', content: 'Translate the user message into a concise English search query for a B2B jewelry wholesaler FAQ. Output ONLY the English translation, no explanation, no quotes.' },
{ role: 'user', content: query },
],
}),
signal: AbortSignal.timeout(15000),
});
const json = await res.json();
const out = (((json.choices || [])[0] || {}).message || {}).content || '';
return String(out).trim().replace(/^["']|["']$/g, '');
} catch (err) {
console.error(JSON.stringify({ ts: new Date().toISOString(), warn: `kb translate failed: ${err.message}` }));
return null;
}
}
return { pool, embedQuery, vecStr, translateQueryToEnglish, model, dim };
}
module.exports = { createEmbeddingClient };