跳到主要内容

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

浏览文件
main

分支

cli.js

29 行 · 1.7 KB历史下载
1#!/usr/bin/env node
2import { readFileSync } from 'node:fs';
3import { RetrievalMemory } from './store.js';
4const args = process.argv.slice(2);
5const value = name => { const i = args.indexOf(name); return i >= 0 ? args[i + 1] : undefined; };
6const dir = value('--dir');
7if (!dir || !args[0]) {
8 console.error('用法:companion-memory <import|search|stats|export> --dir 目录 [--namespace dsh] [--scope owner|group:号|private:号] [--user local-user]');
9 process.exit(2);
10}
11const memory = new RetrievalMemory({ dir });
12try {
13 const command = args[0];
14 const access = { namespace: value('--namespace') || 'dsh', scope: value('--scope') || 'owner', userId: value('--user') || 'local-user' };
15 if (command === 'import') {
16 const file = value('--file'); if (!file) throw new Error('import 需要 --file JSONL');
17 let count = 0;
18 for (const line of readFileSync(file, 'utf8').split(/\r?\n/).filter(Boolean)) {
19 const { sourceKey, createdAt, content, source } = JSON.parse(line);
20 memory.put({ ...access, sourceKey, createdAt, content, source }); count++;
21 }
22 console.log(JSON.stringify({ imported: count }));
23 } else if (command === 'search') console.log(JSON.stringify(await memory.search(value('--query') || '', { ...access, topK: Number(value('--top-k') || 8) }), null, 2));
24 else if (command === 'stats') console.log(JSON.stringify(memory.stats(), null, 2));
25 // JSONL, one record per line — the same shape `import` reads, so an export can be re-imported.
26 else if (command === 'export') for (const row of memory.export(access))
27 console.log(JSON.stringify({ sourceKey: row.source_key, createdAt: row.created_at, content: row.content, source: row.source }));
28 else throw new Error('未知命令');
29} finally { memory.close(); }