Improve MemFuse recall via hybrid ranking and candidate generation.
Add RRF fusion with English word-level lexical scoring, tiered keyword fetch, and vector margin expansion (0.15/200) to fix pre-rank truncation; wire DashScope embedding bench path and update baseline to 28.8% recall@20. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { createDbPool } from '../db.mjs';
|
||||
import { decryptSecret } from '../llm-providers.mjs';
|
||||
|
||||
function isDashScopeProviderRow(row) {
|
||||
if (!row) return false;
|
||||
const providerId = String(row.provider_id ?? '').trim();
|
||||
const apiUrl = String(row.api_url ?? '').trim().toLowerCase();
|
||||
if (providerId === 'custom_qwen') return true;
|
||||
return apiUrl.includes('dashscope.aliyuncs.com');
|
||||
}
|
||||
|
||||
function normalizeBaseUrl(apiUrl) {
|
||||
const raw = String(apiUrl ?? '').trim().replace(/\/$/, '');
|
||||
if (!raw) return 'https://dashscope.aliyuncs.com/compatible-mode/v1';
|
||||
if (raw.endsWith('/embeddings')) return raw.slice(0, -'/embeddings'.length);
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve DashScope / Qwen embedding credentials from memind_adm-managed
|
||||
* `h5_llm_provider_keys`, the same store used by Providers in memind_adm.
|
||||
*/
|
||||
export async function resolveLlmEmbeddingCredentials({
|
||||
pool = null,
|
||||
keyId = null,
|
||||
env = process.env,
|
||||
} = {}) {
|
||||
const ownsPool = !pool;
|
||||
const db = pool ?? createDbPool();
|
||||
try {
|
||||
const explicitKeyId = String(keyId ?? env.MEMIND_EMBEDDING_LLM_KEY_ID ?? '').trim();
|
||||
let row = null;
|
||||
if (explicitKeyId) {
|
||||
const [rows] = await db.query(
|
||||
'SELECT * FROM h5_llm_provider_keys WHERE id = ? AND status = ? LIMIT 1',
|
||||
[explicitKeyId, 'active'],
|
||||
);
|
||||
row = rows[0] ?? null;
|
||||
} else {
|
||||
const [selectedRows] = await db.query(
|
||||
'SELECT * FROM h5_llm_provider_keys WHERE is_selected = 1 AND status = ? LIMIT 1',
|
||||
['active'],
|
||||
);
|
||||
if (isDashScopeProviderRow(selectedRows[0])) {
|
||||
row = selectedRows[0];
|
||||
}
|
||||
if (!row) {
|
||||
const [dashRows] = await db.query(
|
||||
`SELECT * FROM h5_llm_provider_keys
|
||||
WHERE status = ?
|
||||
AND (
|
||||
provider_id = 'custom_qwen'
|
||||
OR api_url LIKE '%dashscope.aliyuncs.com%'
|
||||
)
|
||||
ORDER BY is_selected DESC, updated_at DESC
|
||||
LIMIT 1`,
|
||||
['active'],
|
||||
);
|
||||
row = dashRows[0] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!row) {
|
||||
return { available: false, reason: 'dashscope_llm_key_not_found' };
|
||||
}
|
||||
if (!isDashScopeProviderRow(row)) {
|
||||
return { available: false, reason: 'llm_key_not_dashscope', providerId: row.provider_id };
|
||||
}
|
||||
|
||||
const apiKey = decryptSecret(
|
||||
{
|
||||
ciphertext: row.api_key_ciphertext,
|
||||
iv: row.api_key_iv,
|
||||
tag: row.api_key_tag,
|
||||
},
|
||||
env.H5_SETTINGS_ENCRYPTION_KEY ?? env.TKMIND_SERVER__SECRET_KEY,
|
||||
);
|
||||
if (!apiKey) {
|
||||
return { available: false, reason: 'dashscope_api_key_decrypt_failed', keyName: row.name };
|
||||
}
|
||||
|
||||
return {
|
||||
available: true,
|
||||
provider: 'dashscope',
|
||||
keyId: row.id,
|
||||
keyName: row.name,
|
||||
providerId: row.provider_id,
|
||||
apiKey,
|
||||
baseUrl: normalizeBaseUrl(row.api_url),
|
||||
chatModel: row.default_model,
|
||||
model: String(env.MEMIND_EMBEDDING_MODEL ?? 'text-embedding-v3').trim(),
|
||||
};
|
||||
} finally {
|
||||
if (ownsPool) await db.end();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user