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. */ |
| 2 | import { 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 | */ |
| 12 | export 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 | } |

