@dsh-libing/memory-manager 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +64 -2
- package/cordis.patch.yml +3 -0
- package/icon.svg +1 -0
- package/lib/client-types/client/Dialogs.d.ts +29 -0
- package/lib/client-types/client/Editor.d.ts +12 -0
- package/lib/client-types/client/MemoryPage.d.ts +31 -0
- package/lib/client-types/client/api.d.ts +9 -0
- package/lib/client-types/client/index.d.ts +9 -0
- package/lib/client-types/client/locales.d.ts +207 -0
- package/lib/client-types/client/navigation.d.ts +6 -0
- package/lib/client-types/client/turnView.d.ts +7 -0
- package/lib/client-types/client/useMemory.d.ts +122 -0
- package/lib/client-types/shared.d.ts +506 -0
- package/lib/client.js +221 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.js +111 -0
- package/lib/models.d.ts +21 -0
- package/lib/models.js +69 -0
- package/lib/recall.d.ts +55 -0
- package/lib/recall.js +34 -0
- package/lib/runtime.d.ts +349 -0
- package/lib/runtime.js +177 -0
- package/lib/scope.d.ts +33 -0
- package/lib/scope.js +82 -0
- package/lib/shared.d.ts +506 -0
- package/lib/shared.js +40 -0
- package/lib/storage-worker.d.ts +1 -0
- package/lib/storage-worker.js +256 -0
- package/lib/store.d.ts +15 -0
- package/lib/store.js +113 -0
- package/package.json +123 -3
package/CHANGELOG.md
ADDED
package/README.md
CHANGED
|
@@ -1,3 +1,65 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @dsh-libing/memory-manager
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
DeepSeek Harness **0.2.0-rc.2** 的记忆插件,TypeScript 开发。管理偏好与约定、项目事实与决策、经验与教训和任务摘要。长文档与原件继续放在知识库,技能和 MCP 继续由对应中心管理。
|
|
4
|
+
|
|
5
|
+
## 安装与入口
|
|
6
|
+
|
|
7
|
+
从 LiBing 市场安装,或在明确的 profile 中运行:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
dsh plugin --profile <profile> add @dsh-libing/memory-manager
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
开发未发布包:在仓库根运行 `pnpm dev:market --port 18786`,在开发市场安装“记忆中心”。开发 profile 和数据与日常 `~/.dsh` 隔离;重启命令更新已安装的未发布 tarball。
|
|
14
|
+
|
|
15
|
+
三个入口共享同一数据:
|
|
16
|
+
|
|
17
|
+
- 侧边栏“记忆中心”:记录、过滤、候选复核、版本、设置、活动、导出和回收站。
|
|
18
|
+
- 会话“记忆”页签:与“对话/轨迹”并列,绑定当前实际会话;先查看本轮实际提供给模型的历史版本,再核对本会话建议;搜索、准备和任务细节放在次级记录中。
|
|
19
|
+
- 对话轮末简短回执:有带入、读取或待确认内容时显示,点击定位该会话的对应轮次。
|
|
20
|
+
|
|
21
|
+
已准备表示检索已完成;已带入以实际 `user/message` 接纳事件为准;工具已读取表示读取成功。它们都不证明模型实际采纳了结论。旧会话没有记录时不能推断未用过记忆。
|
|
22
|
+
|
|
23
|
+
## 使用
|
|
24
|
+
|
|
25
|
+
使用流程为“记录或提炼 → 核对建议 → 在后续对话使用”。手动新建先填标题、内容与范围,分类、标签和召回选项放在高级选项;保存直接成为已确认记忆。模型提交和对已确认条目的编辑均先生成候选,在“待确认”中核对内容与来源后确认生效;确认前仍使用原生效版本。候选及修订不会出现在模型检索结果中。两处同时编辑会拒绝过期版本,请刷新再复核。
|
|
26
|
+
|
|
27
|
+
普通会话示例:
|
|
28
|
+
|
|
29
|
+
> 请记住:本项目新增插件前先写简短提案,作为本工作区约定提交候选。
|
|
30
|
+
>
|
|
31
|
+
> 请检索这个工作区的记忆,说明我们之前的选型理由及来源;没有记录就直接说没有。
|
|
32
|
+
|
|
33
|
+
工具需要出现在该会话实际工具目录中,可以在 MCP 管理中心确认调用开关:
|
|
34
|
+
|
|
35
|
+
| 工具 | 用法 |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| `libing_memory_search` | `{ "query": "提案约定" }`,返回已确认记忆的身份、版本、摘要和来源。中文词片与英文关键词匹配,未命中返回空列表。 |
|
|
38
|
+
| `libing_memory_read` | `{ "id": "搜索返回的身份", "version": 1 }`,读取确切版本,重新校验会话范围与当前召回开关。 |
|
|
39
|
+
| `libing_memory_propose` | `{ "title": "提案约定", "content": "新增插件前先写简短提案", "kind": "agreement", "range": "workspace" }`。修订时补 `target` 和读取时的 `expected` 版本;相同工具调用身份不会重复创建候选。 |
|
|
40
|
+
|
|
41
|
+
模型不能通过这些工具批准、直接覆盖、永久删除或选择个人共享范围。管理 API 和模型工具职责分离不是对拥有终端/文件权限的 Agent 的绝对沙箱。
|
|
42
|
+
|
|
43
|
+
## 范围、召回和设置
|
|
44
|
+
|
|
45
|
+
默认工作区范围来自 Host 对当前会话真实 `cwd` 的 canonical path,不按最近会话、名称或最近 Git 根猜测。当前会话范围仅用于对应 session;个人记忆由用户明确设定,仅在当前 profile 内跨工作区共享。子 Agent 使用自身真实会话范围,不能读取父会话专属记忆;自动提炼跳过子 Agent。
|
|
46
|
+
|
|
47
|
+
本地自动召回默认开启,不额外调用模型。新轮第一步优先固定条目,再取最多 5 个相关条目,固定条目同样受预算限制。默认上限 4,000 字符,超限跳过完整条目并记录原因,原文中的模板符号不会被插值。条目确认或修订不改变已经开始的轮次快照;当前明确指令始终优先。
|
|
48
|
+
|
|
49
|
+
自动候选提炼默认关闭。提炼模型默认跟随所选会话最近实际请求的 provider/model,从官方会话日志解析,冷会话不启动 Agent;该会话尚无调用记录时沿用 DSH 默认模型。设置里展示实际模型及来源,也可在官方模型目录选择固定模型或手动填写已配置身份;固定选择优先,不静默替换已失效的提供方。本插件不新增凭据或模型连接配置。中心“从会话提炼”和会话页签“从这轮提炼”可手动提炼已正常完成的一轮;确认窗口说明来源与模型,提交后结果进入待确认。确认时模型若已改变会拒绝提交,任务入队后固定模型,自动模式只在正常 `turn/end` 后排队。提炼仅读取该轮真实用户文本与助手回答,最多 12,000 字符,不读取 reasoning、原始工具输出或本插件召回消息。疑似凭据的输入跳过提炼,检测不能保证发现所有秘密。
|
|
50
|
+
|
|
51
|
+
任务串行执行,最多 20 个排队/执行任务;每次模型调用 45 秒超时,默认每天 20 次(UTC)持久预约预算,取消和失败也计入已花费预算。同一来源轮次、设置版本及实际模型重复点击不重复调用;需要重试时先核对设置并保存。模型最多生成 4 个候选,每条不超过 1,500 字符。模型失败、取消、重启中断和预算跳过分别显示。关闭自动提炼取消当前 profile 各工作区的自动任务;手动任务可逐项取消。取消后迟到的结果不能提交候选。
|
|
52
|
+
|
|
53
|
+
正常会话会把带入的记忆发送给当前模型;提炼会把上述选定对话发送给配置模型。本地存储不等于数据不出本机。
|
|
54
|
+
|
|
55
|
+
## 数据与生命周期
|
|
56
|
+
|
|
57
|
+
默认数据根为当前 profile 的 `libing/memory-manager`。包含 `memory.sqlite`(WAL)、唯一实例 owner lock,持久保存当前记忆、不可变历史版本、候选、任务、预算和活动。可通过 patch 的 `dataRoot` 指定绝对路径;数据根绑定原 profile,不能供另一个 profile 共用。
|
|
58
|
+
|
|
59
|
+
最多 1,000 条记忆(含回收站)、500 个待确认候选;已结束候选及任务保留最近约 2,000 条,活动保留 2,000 条,页面显示最近 200 条活动与 100 个任务。历史版本窗口显示最近 100 个版本。卸载停止接收操作、取消并等待提炼及 worker 退出后释放 owner;重载读取原数据且不重复注册工具。进程中断后的排队/执行任务标记为中断,不自动续费重试。
|
|
60
|
+
|
|
61
|
+
移入回收站立即阻止新检索/读取,支持恢复;永久删除需要在回收站输入完整标题,删除当前记忆、历史、对应候选并清空活动的相关摘要。**它不会擦除已进入会话日志或已发送给模型的内容。** 不涉及数据库物理取证级擦除。JSON/Markdown 导出当前视图的已确认记忆,仅供阅读与迁移准备,不是完整恢复备份;备份数据库前停止插件并连同 WAL 一起妥善处理。
|
|
62
|
+
|
|
63
|
+
owner lock 只在旧 PID 已不存在时恢复,不抢占活实例。如恢复过程本身崩溃留下 `owner.recover`,先确保该数据根没有运行实例,再人工处理;不要在运行中删除 owner 文件。
|
|
64
|
+
|
|
65
|
+
首版只提供本地关键词检索,没有向量模型、云同步、自动合并/画像或知识图谱。验收以 macOS 的真实 rc.2 Web 与安装 tarball 为准,未声明 Windows 已验证。
|
package/cordis.patch.yml
ADDED
package/icon.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#5684ff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 6c-2-5-7-2-6 1-4 0-4 6-1 7-1 4 4 7 7 3V6Zm0 0c2-5 7-2 6 1 4 0 4 6 1 7 1 4-4 7-7 3"/><path d="M6 7c0 2 1 3 3 3m-4 4c2-1 4 0 4 2m9-9c0 2-1 3-3 3m4 4c-2-1-4 0-4 2"/></svg>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { MemoryApi } from './api.ts';
|
|
2
|
+
import type { Translate } from './Editor.tsx';
|
|
3
|
+
import type { State, Mutation, CaptureModel } from '../shared.ts';
|
|
4
|
+
export declare function ModelLine({ value, t }: {
|
|
5
|
+
value: CaptureModel | null;
|
|
6
|
+
t: Translate;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function SettingsDialog({ state, api, t, busy, save, close, error }: {
|
|
9
|
+
state: State;
|
|
10
|
+
api: MemoryApi;
|
|
11
|
+
t: Translate;
|
|
12
|
+
busy: boolean;
|
|
13
|
+
save: (value: Mutation) => Promise<boolean>;
|
|
14
|
+
close: () => void;
|
|
15
|
+
error: string;
|
|
16
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare function Guide({ t, close }: {
|
|
18
|
+
t: Translate;
|
|
19
|
+
close: () => void;
|
|
20
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export declare function CaptureDialog({ state, turn, t, busy, error, save, close }: {
|
|
22
|
+
state: State;
|
|
23
|
+
turn?: number | undefined;
|
|
24
|
+
t: Translate;
|
|
25
|
+
busy: boolean;
|
|
26
|
+
error: string;
|
|
27
|
+
save: (value: Mutation) => Promise<boolean>;
|
|
28
|
+
close: () => void;
|
|
29
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { Candidate, Entry, Mutation } from '../shared.ts';
|
|
3
|
+
export type Translate = TranslateNS<'libingMemoryManager'>;
|
|
4
|
+
export declare function Editor({ original, candidate, t, busy, save, close, error }: {
|
|
5
|
+
original?: Entry | undefined;
|
|
6
|
+
candidate?: Candidate | undefined;
|
|
7
|
+
t: Translate;
|
|
8
|
+
busy: boolean;
|
|
9
|
+
save: (value: Mutation) => Promise<boolean>;
|
|
10
|
+
close: () => void;
|
|
11
|
+
error?: string | undefined;
|
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Shared management controls; the session view never changes its rendered target's identity. */
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
|
+
import type { MemoryApi } from './api.ts';
|
|
5
|
+
import type { Translate } from './Editor.tsx';
|
|
6
|
+
import type { Selection, Entry } from '../shared.ts';
|
|
7
|
+
export declare function label(t: Translate, code: string): string;
|
|
8
|
+
export interface Navigation {
|
|
9
|
+
center(session?: string, focus?: string): void;
|
|
10
|
+
session(session: string, turn?: number): Promise<void>;
|
|
11
|
+
subscribe(listener: () => void): () => void;
|
|
12
|
+
snapshot(): Selection;
|
|
13
|
+
bind(session: string, open: (view: string, focus: string) => void): () => void;
|
|
14
|
+
}
|
|
15
|
+
type Common = PropsLocale<'libingMemoryManager'> & {
|
|
16
|
+
api: MemoryApi;
|
|
17
|
+
navigation: Navigation;
|
|
18
|
+
};
|
|
19
|
+
export declare function EntryRow({ entry, t, children }: {
|
|
20
|
+
entry: Entry;
|
|
21
|
+
t: Translate;
|
|
22
|
+
children?: React.ReactNode;
|
|
23
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export declare function MemoryPage({ api, navigation, t }: Common): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export declare function MemoryPanel({ api, navigation, t, selection, choose }: Common & {
|
|
26
|
+
selection: Selection;
|
|
27
|
+
choose: (value: Selection) => void;
|
|
28
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export declare function MemoryView(props: Common & PropsRuntime<'conversation.view'>): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare function MemoryReceipt({ sessionId, turn, api, navigation, t }: Common & PropsRuntime<'conversation.chat.turnTail'>): import("react/jsx-runtime").JSX.Element | null;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Entry, State, Selection, Mutation, ModelDirectory } from '../shared.ts';
|
|
2
|
+
export interface MemoryApi {
|
|
3
|
+
models(signal: AbortSignal): Promise<ModelDirectory>;
|
|
4
|
+
history(input: Selection, id: string, signal: AbortSignal): Promise<Entry[]>;
|
|
5
|
+
state(input: Selection, signal: AbortSignal): Promise<State>;
|
|
6
|
+
mutate(input: Selection, mutation: Mutation, signal: AbortSignal): Promise<unknown>;
|
|
7
|
+
read(input: Selection, id: string, version: number, signal: AbortSignal): Promise<Entry>;
|
|
8
|
+
}
|
|
9
|
+
export declare const api: MemoryApi;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { LocaleKey } from './locales.ts';
|
|
3
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
4
|
+
interface LocaleNamespaceMap {
|
|
5
|
+
libingMemoryManager: LocaleKey;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export declare const inject: string[];
|
|
9
|
+
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
export declare const zh: {
|
|
2
|
+
readonly savedMemories: "已保存记忆";
|
|
3
|
+
readonly advanced: "高级选项";
|
|
4
|
+
readonly recordHint: "写下以后还会用到的约定或结论。保存后可在后续对话中作为参考。";
|
|
5
|
+
readonly titleExample: "例如:本项目的开发约定";
|
|
6
|
+
readonly contentExample: "例如:新增插件先写简短提案,验证完成后再移到 implemented。";
|
|
7
|
+
readonly emptyMemories: "还没有保存记忆";
|
|
8
|
+
readonly emptyStart: "你可以直接记录一条约定,或从所选会话中提炼建议;模型生成的建议需要你确认后才生效。";
|
|
9
|
+
readonly flowRecord: "1. 记录或提炼";
|
|
10
|
+
readonly flowReview: "2. 核对建议";
|
|
11
|
+
readonly flowUse: "3. 在对话中使用";
|
|
12
|
+
readonly followModel: "跟随会话模型(推荐)";
|
|
13
|
+
readonly fixedModel: "指定提炼模型";
|
|
14
|
+
readonly modelMode: "提炼模型";
|
|
15
|
+
readonly modelChoice: "选择模型";
|
|
16
|
+
readonly effectiveModel: "实际提炼模型";
|
|
17
|
+
readonly sessionModel: "所选会话最近使用";
|
|
18
|
+
readonly defaultModel: "DSH 默认模型";
|
|
19
|
+
readonly customModel: "手动指定";
|
|
20
|
+
readonly modelUnavailable: "此提供方当前不可用,请在 DSH 设置中检查模型连接,或另选提炼模型。";
|
|
21
|
+
readonly modelChanged: "提炼模型已改变,请关闭窗口并重新确认。";
|
|
22
|
+
readonly modelDirectoryUnavailable: "模型目录暂不可用;可手动填写已配置的模型身份。";
|
|
23
|
+
readonly modelFollowHint: "默认沿用所选会话最近使用的模型;尚无调用记录时沿用 DSH 默认模型。无需额外配置凭据。";
|
|
24
|
+
readonly noCaptureModel: "尚无可用的提炼模型,请先在对话中选择模型,或在这里指定已配置的模型。";
|
|
25
|
+
readonly captureConfirm: "从对话生成记忆建议";
|
|
26
|
+
readonly captureFromSession: "从会话提炼";
|
|
27
|
+
readonly captureFromTurn: "从这轮提炼";
|
|
28
|
+
readonly captureSubmit: "生成待确认建议";
|
|
29
|
+
readonly captureHint: "仅发送选定轮次的用户消息与助手回答,不包含推理和原始工具输出。生成的建议先等你核对,不会直接写入已保存记忆。";
|
|
30
|
+
readonly captureTarget: "提炼来源";
|
|
31
|
+
readonly captureQueued: "提炼任务已提交,完成后可在这里核对建议。";
|
|
32
|
+
readonly noSuggestions: "目前没有待确认建议";
|
|
33
|
+
readonly captureEmpty: "这轮没有发现适合长期保存的内容。你仍可手动记录。";
|
|
34
|
+
readonly sessionTitle: "这段对话的记忆";
|
|
35
|
+
readonly provided: "提供给模型";
|
|
36
|
+
readonly usedTitle: "本轮提供给模型的记忆";
|
|
37
|
+
readonly usedHint: "这些内容曾作为参考交给模型;是否采纳以回答为准。";
|
|
38
|
+
readonly noUsed: "本轮没有已记录的记忆带入或读取。";
|
|
39
|
+
readonly noUsedHint: "保存记忆后,系统会在新轮对话中匹配相关内容;也可以直接让模型检索记忆。";
|
|
40
|
+
readonly suggestTitle: "建议保存";
|
|
41
|
+
readonly availableNext: "可用于后续对话的记忆";
|
|
42
|
+
readonly audit: "使用记录";
|
|
43
|
+
readonly reviewAction: "核对并保存";
|
|
44
|
+
readonly reviewNeeded: "模型生成内容需要你确认;确认前不会参与检索或召回。";
|
|
45
|
+
readonly nextAction: "想留下刚才的结论?可以从本轮提炼,也可以在对话中说“请记住这条约定”。";
|
|
46
|
+
readonly recallHint: "自动匹配已保存记忆,不额外调用模型。";
|
|
47
|
+
readonly autoCaptureHint: "每轮完成后自动生成待确认建议,会调用下方模型并计入每日预算。默认关闭。";
|
|
48
|
+
readonly guideRecord: "新建记忆可以直接保存。也可在对话中说“请记住本项目的约定”,或点击“从会话提炼”生成建议。";
|
|
49
|
+
readonly guideReview: "在“待确认”核对内容、范围和来源,再确认生效。修改已有记忆也先生成修订建议,确认前仍使用原版本。";
|
|
50
|
+
readonly guideUse: "新轮对话会自动匹配相关记忆。你也可明确说“请检索本工作区的记忆”,让模型搜索并读取。当前指令优先。";
|
|
51
|
+
readonly guideScope: "默认仅在当前工作区使用;“当前会话”只用于这一段对话;“个人记忆”在当前 profile 的工作区之间共享。";
|
|
52
|
+
readonly guideTools: "支持的工具";
|
|
53
|
+
readonly guideSearch: "搜索已确认且参与召回的记忆,返回标题、摘要和来源。";
|
|
54
|
+
readonly guideRead: "读取搜索结果中的确切版本;不能读取待确认建议。";
|
|
55
|
+
readonly guidePropose: "提交新建议或修订,等待用户确认;不能替用户批准或删除。";
|
|
56
|
+
readonly guideStatus: "会话“记忆”页签";
|
|
57
|
+
readonly guideStatusBody: "“提供给模型”展示这一轮实际带入或工具读取的历史版本。“建议保存”展示本会话待确认内容;搜索匹配和准备记录放在使用记录中。";
|
|
58
|
+
readonly guideLimits: "范围与数据说明";
|
|
59
|
+
readonly recallLabel: "允许对话使用";
|
|
60
|
+
readonly pinLabel: "每轮优先带入";
|
|
61
|
+
readonly manualModel: "手动填写模型身份";
|
|
62
|
+
readonly sessionRequired: "请先选择一个会话";
|
|
63
|
+
readonly untitled: "未命名会话";
|
|
64
|
+
readonly autoCaptureOff: "自动提炼已关闭";
|
|
65
|
+
readonly versions: "历史版本";
|
|
66
|
+
readonly historyLimit: "显示最近 100 个版本;旧版本仅供复核,不替换当前生效内容。";
|
|
67
|
+
readonly profileMismatch: "数据根属于另一个 profile,不能共用";
|
|
68
|
+
readonly nav: "记忆中心";
|
|
69
|
+
readonly subtitle: "管理已确认的偏好、项目决策与经验。";
|
|
70
|
+
readonly help: "使用说明";
|
|
71
|
+
readonly settings: "设置";
|
|
72
|
+
readonly create: "新建记忆";
|
|
73
|
+
readonly refresh: "刷新";
|
|
74
|
+
readonly workspace: "工作区";
|
|
75
|
+
readonly session: "会话";
|
|
76
|
+
readonly noSession: "暂无会话";
|
|
77
|
+
readonly profile: "当前 profile";
|
|
78
|
+
readonly shared: "个人记忆仅在此 profile 内跨工作区共享。选择会话仅用于查看。";
|
|
79
|
+
readonly memories: "记忆";
|
|
80
|
+
readonly pending: "待确认";
|
|
81
|
+
readonly activity: "活动";
|
|
82
|
+
readonly trash: "回收站";
|
|
83
|
+
readonly search: "搜索标题、内容或标签";
|
|
84
|
+
readonly allKinds: "全部类型";
|
|
85
|
+
readonly allRanges: "全部范围";
|
|
86
|
+
readonly agreement: "偏好与约定";
|
|
87
|
+
readonly decision: "项目事实与决策";
|
|
88
|
+
readonly lesson: "经验与教训";
|
|
89
|
+
readonly handoff: "任务摘要";
|
|
90
|
+
readonly workspaceRange: "当前工作区";
|
|
91
|
+
readonly sessionRange: "当前会话";
|
|
92
|
+
readonly personalRange: "个人记忆";
|
|
93
|
+
readonly title: "标题";
|
|
94
|
+
readonly content: "内容";
|
|
95
|
+
readonly tags: "标签(逗号分隔)";
|
|
96
|
+
readonly kind: "类型";
|
|
97
|
+
readonly range: "使用范围";
|
|
98
|
+
readonly pinned: "固定带入";
|
|
99
|
+
readonly recall: "参与召回";
|
|
100
|
+
readonly source: "来源";
|
|
101
|
+
readonly detail: "详情与来源";
|
|
102
|
+
readonly version: "版本";
|
|
103
|
+
readonly manual: "用户记录";
|
|
104
|
+
readonly model: "模型建议";
|
|
105
|
+
readonly capture: "会话提炼";
|
|
106
|
+
readonly edit: "提出修订";
|
|
107
|
+
readonly approve: "确认生效";
|
|
108
|
+
readonly reject: "拒绝";
|
|
109
|
+
readonly remove: "移入回收站";
|
|
110
|
+
readonly restore: "恢复";
|
|
111
|
+
readonly purge: "永久删除";
|
|
112
|
+
readonly confirmTitle: "输入完整标题以确认永久删除";
|
|
113
|
+
readonly save: "保存";
|
|
114
|
+
readonly cancel: "取消";
|
|
115
|
+
readonly close: "关闭";
|
|
116
|
+
readonly loading: "加载中…";
|
|
117
|
+
readonly empty: "暂无符合条件的内容";
|
|
118
|
+
readonly failure: "操作失败";
|
|
119
|
+
readonly saved: "操作已提交";
|
|
120
|
+
readonly old: "原生效内容";
|
|
121
|
+
readonly proposed: "待确认内容";
|
|
122
|
+
readonly nextTurn: "确认后供下一次检索或新轮召回使用,不修改已开始的轮次快照。";
|
|
123
|
+
readonly guide: "记忆是历史参考,当前明确指令优先。说“记住本项目的约定”会提交候选,确认后生效;说“查一下之前的选型原因”可搜索并读取来源。候选不能被模型检索。参与召回只代表可被选中,不等于模型采纳;超预算会跳过完整条目。删除会阻止后续检索,但不擦除既有会话历史。";
|
|
124
|
+
readonly privacy: "正常会话会向当前模型发送带入的记忆;提炼会向配置模型发送选定轮次的用户消息及助手回答。不会提炼 reasoning 或原始工具输出。本地存储不等于数据不出本机。";
|
|
125
|
+
readonly autoRecall: "本地自动召回";
|
|
126
|
+
readonly autoCapture: "自动候选提炼";
|
|
127
|
+
readonly provider: "提炼 provider";
|
|
128
|
+
readonly modelField: "提炼 model";
|
|
129
|
+
readonly daily: "每日调用上限(UTC)";
|
|
130
|
+
readonly budget: "召回字符上限";
|
|
131
|
+
readonly export: "导出 JSON";
|
|
132
|
+
readonly exportMarkdown: "导出 Markdown";
|
|
133
|
+
readonly exportNote: "导出当前视图的生效记忆,用于阅读或迁移准备;不是完整数据库恢复备份。";
|
|
134
|
+
readonly extract: "提炼最近完成的一轮";
|
|
135
|
+
readonly extractTurn: "提炼所选轮次";
|
|
136
|
+
readonly jobs: "提炼任务";
|
|
137
|
+
readonly queued: "排队";
|
|
138
|
+
readonly running: "执行中";
|
|
139
|
+
readonly done: "完成";
|
|
140
|
+
readonly failed: "失败";
|
|
141
|
+
readonly cancelled: "已取消";
|
|
142
|
+
readonly interrupted: "重启中断";
|
|
143
|
+
readonly skipped: "已跳过";
|
|
144
|
+
readonly stop: "取消任务";
|
|
145
|
+
readonly openCenter: "打开记忆中心";
|
|
146
|
+
readonly openMemory: "查看会话记忆";
|
|
147
|
+
readonly latest: "最近一轮";
|
|
148
|
+
readonly turn: "轮次";
|
|
149
|
+
readonly thisTurn: "本轮记忆";
|
|
150
|
+
readonly available: "本会话可用记忆";
|
|
151
|
+
readonly history: "历史轮次与操作";
|
|
152
|
+
readonly included: "已带入";
|
|
153
|
+
readonly prepared: "已准备";
|
|
154
|
+
readonly read: "工具已读取";
|
|
155
|
+
readonly searchStatus: "搜索返回";
|
|
156
|
+
readonly deleted: "已永久删除";
|
|
157
|
+
readonly notAdmitted: "未接纳";
|
|
158
|
+
readonly captureSkipped: "提炼跳过";
|
|
159
|
+
readonly propose: "候选提交";
|
|
160
|
+
readonly settingsStatus: "设置变更";
|
|
161
|
+
readonly toggle: "召回开关变更";
|
|
162
|
+
readonly settingsRevision: "设置保存时复核版本;两个页面修改冲突时请刷新。";
|
|
163
|
+
readonly turnReceipt: "本轮记忆";
|
|
164
|
+
readonly noRecord: "暂无该轮记录;不能据此推断旧会话未使用过记忆。";
|
|
165
|
+
readonly missing: "内容不可用或已删除";
|
|
166
|
+
readonly personalRequiresUser: "个人共享范围需要用户在复核时明确选择";
|
|
167
|
+
readonly unknownScope: "无法确认当前会话范围";
|
|
168
|
+
readonly revisionConflict: "版本已改变,请刷新并重新复核";
|
|
169
|
+
readonly notFound: "条目不存在";
|
|
170
|
+
readonly outsideScope: "条目不属于所选范围";
|
|
171
|
+
readonly notReadable: "条目不再允许模型读取";
|
|
172
|
+
readonly dataRootBusy: "数据目录被其他实例使用";
|
|
173
|
+
readonly sensitiveInput: "该轮疑似包含凭据,已跳过提炼";
|
|
174
|
+
readonly completedTurnRequired: "请先完成一轮正常对话";
|
|
175
|
+
readonly noUserInput: "该轮没有真实用户输入";
|
|
176
|
+
readonly modelRequired: "尚未解析到提炼模型,请在会话选择模型或到记忆设置指定";
|
|
177
|
+
readonly dailyBudget: "已达到每日调用预算";
|
|
178
|
+
readonly queueFull: "任务队列已满";
|
|
179
|
+
readonly memoryLimit: "已达到记忆容量上限";
|
|
180
|
+
readonly candidateLimit: "待确认候选过多";
|
|
181
|
+
readonly purgeConfirmation: "请在回收站输入完整标题";
|
|
182
|
+
readonly noMatch: "没有相关记忆";
|
|
183
|
+
readonly recallOff: "自动召回已关闭";
|
|
184
|
+
readonly recallBudget: "部分完整条目因预算未带入";
|
|
185
|
+
readonly operationFailed: "服务不可用,请刷新";
|
|
186
|
+
readonly storageFailed: "数据库操作失败";
|
|
187
|
+
readonly extractionFailed: "提炼失败,请检查模型设置后手动重试";
|
|
188
|
+
readonly modelNotCompleted: "模型未正常完成";
|
|
189
|
+
readonly modelOutputTooLarge: "模型输出超限";
|
|
190
|
+
readonly restart: "任务在重启时中断";
|
|
191
|
+
readonly userCancelled: "用户取消";
|
|
192
|
+
readonly invalidRequest: "请求无效";
|
|
193
|
+
readonly absoluteRootRequired: "数据目录需要绝对路径";
|
|
194
|
+
readonly closed: "插件正在退出";
|
|
195
|
+
readonly busy: "服务繁忙";
|
|
196
|
+
readonly cannotNavigate: "目标会话未能打开,请在侧栏打开后重试";
|
|
197
|
+
readonly turnHint: "可以查看该轮的带入/读取记录;这不是模型实际采纳的证明。";
|
|
198
|
+
readonly pinnedHint: "固定记忆仍受完整条目预算限制。";
|
|
199
|
+
readonly pendingCount: "本会话待确认";
|
|
200
|
+
readonly off: "关闭";
|
|
201
|
+
readonly on: "开启";
|
|
202
|
+
readonly copyPrompt: "复制使用示例";
|
|
203
|
+
readonly copied: "已复制";
|
|
204
|
+
readonly guideExample: "请检索这个工作区的记忆,说明我们之前的选型理由及来源;没有记录就直接说没有。";
|
|
205
|
+
};
|
|
206
|
+
export type LocaleKey = keyof typeof zh;
|
|
207
|
+
export declare const en: Record<LocaleKey, string>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Target-addressed links. No DOM tab clicking and no unscoped last-session fallback. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { Navigation } from './MemoryPage.tsx';
|
|
4
|
+
export declare function navigation(ctx: Context): Navigation & {
|
|
5
|
+
close(): void;
|
|
6
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Search/preparation are audit facts, not evidence that memory reached the model. */
|
|
2
|
+
import type { Activity, ActivityItem } from '../shared.ts';
|
|
3
|
+
export declare function providedMemories(rows: Activity[]): {
|
|
4
|
+
item: ActivityItem;
|
|
5
|
+
included: boolean;
|
|
6
|
+
read: boolean;
|
|
7
|
+
}[];
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { MemoryApi } from './api.ts';
|
|
2
|
+
import type { Selection, Mutation } from '../shared.ts';
|
|
3
|
+
export declare function invalidate(): void;
|
|
4
|
+
export declare function useMemory(api: MemoryApi, input: Selection): {
|
|
5
|
+
state: {
|
|
6
|
+
profile: string;
|
|
7
|
+
scope: {
|
|
8
|
+
workspace: string;
|
|
9
|
+
session: string | null;
|
|
10
|
+
};
|
|
11
|
+
selectedSession: string | null;
|
|
12
|
+
workspaces: {
|
|
13
|
+
id: string;
|
|
14
|
+
title: string;
|
|
15
|
+
}[];
|
|
16
|
+
sessions: {
|
|
17
|
+
id: string;
|
|
18
|
+
title: string;
|
|
19
|
+
}[];
|
|
20
|
+
entries: {
|
|
21
|
+
title: string;
|
|
22
|
+
content: string;
|
|
23
|
+
kind: "agreement" | "decision" | "lesson" | "handoff";
|
|
24
|
+
tags: string[];
|
|
25
|
+
pinned: boolean;
|
|
26
|
+
recall: boolean;
|
|
27
|
+
range: "workspace" | "session" | "personal";
|
|
28
|
+
id: string;
|
|
29
|
+
version: number;
|
|
30
|
+
workspace: string;
|
|
31
|
+
session: string | null;
|
|
32
|
+
state: "active" | "trash";
|
|
33
|
+
source: {
|
|
34
|
+
kind: "manual" | "model" | "capture";
|
|
35
|
+
session: string | null;
|
|
36
|
+
turn: number | null;
|
|
37
|
+
evidence: string;
|
|
38
|
+
seqs: number[];
|
|
39
|
+
};
|
|
40
|
+
updated: string;
|
|
41
|
+
}[];
|
|
42
|
+
candidates: {
|
|
43
|
+
id: string;
|
|
44
|
+
revision: string;
|
|
45
|
+
target: string | null;
|
|
46
|
+
expected: number;
|
|
47
|
+
workspace: string;
|
|
48
|
+
session: string | null;
|
|
49
|
+
draft: {
|
|
50
|
+
title: string;
|
|
51
|
+
content: string;
|
|
52
|
+
kind: "agreement" | "decision" | "lesson" | "handoff";
|
|
53
|
+
tags: string[];
|
|
54
|
+
pinned: boolean;
|
|
55
|
+
recall: boolean;
|
|
56
|
+
range: "workspace" | "session" | "personal";
|
|
57
|
+
};
|
|
58
|
+
source: {
|
|
59
|
+
kind: "manual" | "model" | "capture";
|
|
60
|
+
session: string | null;
|
|
61
|
+
turn: number | null;
|
|
62
|
+
evidence: string;
|
|
63
|
+
seqs: number[];
|
|
64
|
+
};
|
|
65
|
+
state: "pending" | "rejected" | "accepted";
|
|
66
|
+
updated: string;
|
|
67
|
+
}[];
|
|
68
|
+
activities: {
|
|
69
|
+
id: string;
|
|
70
|
+
workspace: string;
|
|
71
|
+
session: string | null;
|
|
72
|
+
turn: number | null;
|
|
73
|
+
kind: string;
|
|
74
|
+
reason: string;
|
|
75
|
+
items: {
|
|
76
|
+
id: string;
|
|
77
|
+
version: number;
|
|
78
|
+
title: string;
|
|
79
|
+
summary: string;
|
|
80
|
+
status: "prepared" | "included" | "search" | "read" | "deleted";
|
|
81
|
+
}[];
|
|
82
|
+
updated: string;
|
|
83
|
+
}[];
|
|
84
|
+
jobs: {
|
|
85
|
+
id: string;
|
|
86
|
+
workspace: string;
|
|
87
|
+
session: string;
|
|
88
|
+
turn: number;
|
|
89
|
+
state: "queued" | "running" | "done" | "failed" | "cancelled" | "interrupted" | "skipped";
|
|
90
|
+
reason: string;
|
|
91
|
+
candidateIds: string[];
|
|
92
|
+
updated: string;
|
|
93
|
+
automatic: boolean;
|
|
94
|
+
}[];
|
|
95
|
+
settings: {
|
|
96
|
+
revision: number;
|
|
97
|
+
autoRecall: boolean;
|
|
98
|
+
autoCapture: boolean;
|
|
99
|
+
provider: string;
|
|
100
|
+
model: string;
|
|
101
|
+
maxDailyCalls: number;
|
|
102
|
+
maxRecallChars: number;
|
|
103
|
+
};
|
|
104
|
+
captureModel: {
|
|
105
|
+
provider: string;
|
|
106
|
+
model: string;
|
|
107
|
+
source: "session" | "default" | "custom";
|
|
108
|
+
available: boolean;
|
|
109
|
+
} | null;
|
|
110
|
+
followingModel: {
|
|
111
|
+
provider: string;
|
|
112
|
+
model: string;
|
|
113
|
+
source: "session" | "default" | "custom";
|
|
114
|
+
available: boolean;
|
|
115
|
+
} | null;
|
|
116
|
+
} | undefined;
|
|
117
|
+
error: string;
|
|
118
|
+
busy: boolean;
|
|
119
|
+
execute: (value: Mutation) => Promise<boolean>;
|
|
120
|
+
refresh: () => void;
|
|
121
|
+
signal: () => AbortSignal;
|
|
122
|
+
};
|