跳到主要内容

DeepSeek Harness 本地聊天记忆:按来源保存聊天原文,关键词 + 向量检索,可选大模型重排与检索摘要。源码公开,仅限非商用

浏览文件
main

分支

recall.js

29 行 · 1.5 KB历史下载
1/** The single retrieval path shared by automatic recall, the model tool and the bridge API. */
2import { renderEvidence } from './store.js';
3
4/**
5 * Search, keep one hit per record, attach each hit's neighbouring turns, render.
6 * @param {import('./store.js').RetrievalMemory} memory
7 * @param {string} query
8 * @param {object} access search access (namespace, userId, scope, groups, owner)
9 * @param {{ topK: number, maxChars: number, signal?: AbortSignal, exclude?: Set<string>, here?: string, context?: boolean }} options
10 * `exclude`: source keys already in the model's context (the session's recent tail).
11 */
12export async function recall(memory, query, access, { topK, maxChars, signal, exclude = new Set(), here, context = true }) {
13 const found = await memory.search(query, { ...access, topK: Math.min(20, topK * 2 + 4), signal });
14 const hits = [], records = new Set();
15 for (const hit of found) {
16 if (exclude.has(hit.source_key) || records.has(hit.record_id)) continue;
17 records.add(hit.record_id); hits.push(hit);
18 if (hits.length === topK) break;
19 }
20 if (context) {
21 const shown = new Set(hits.map(hit => hit.record_id));
22 const keep = row => row && !shown.has(row.id) && !exclude.has(row.source_key) ? row : null;
23 for (const hit of hits) {
24 const { before, after } = memory.neighbors(hit, access);
25 hit.context = { before: keep(before), after: keep(after) };
26 }
27 }
28 return { hits, text: renderEvidence(hits, maxChars, { here }) };
29}