dsh-cortex-memory 0.1.0 → 0.2.0-rc.13
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/LICENSE +3 -3
- package/README.md +85 -146
- package/bench/ab-engine.mjs +60 -0
- package/bench/ann-bench.mjs +78 -0
- package/bench/hnsw-bench.mjs +79 -0
- package/bench/metrics.js +8 -0
- package/bench/migration-bench.mjs +69 -0
- package/bench/run.js +5 -2
- package/bench/synthetic.js +51 -7
- package/bench/vector-ab.mjs +76 -0
- package/bin/cortex.mjs +2 -3
- package/client.js +286 -4
- package/cordis.patch.yml +1 -1
- package/docs/install-windows.md +115 -27
- package/docs/models.md +165 -30
- package/docs/multimodal.md +112 -0
- package/docs/scopes.md +142 -0
- package/examples/README.md +72 -0
- package/examples/setup-cortex-bge.ps1 +66 -0
- package/examples/uninstall-cortex.ps1 +91 -0
- package/index.js +15 -1
- package/package.json +5 -12
- package/src/adapters/markdown-import.js +20 -1
- package/src/adapters/markdown.js +12 -2
- package/src/adapters/shiori.js +1 -1
- package/src/api/routes.js +148 -4
- package/src/api/validate.js +26 -0
- package/src/core/attachment-reader.js +31 -0
- package/src/core/attachments.js +39 -0
- package/src/core/config.js +36 -1
- package/src/core/model-config.js +3 -1
- package/src/core/profile.js +32 -0
- package/src/engines/develop.js +1 -1
- package/src/engines/encode.js +68 -30
- package/src/engines/extract.js +13 -8
- package/src/engines/growth.js +1 -1
- package/src/engines/reflect.js +1 -1
- package/src/engines/retrieve.js +44 -13
- package/src/host/runtime.js +1 -1
- package/src/memory/query.js +1 -1
- package/src/memory/tokenizer.js +19 -4
- package/src/security/scope-grants.js +73 -0
- package/src/self/appraisal.js +3 -3
- package/src/self/emotion.js +1 -1
- package/src/self/identity.js +1 -1
- package/src/self/relationship.js +2 -2
- package/src/service/cortex.js +191 -3
- package/src/store/database.js +33 -1
- package/src/store/repositories/edges.js +48 -4
- package/src/store/repositories/traces.js +23 -12
- package/src/store/schema.sql +1 -0
- package/src/tools/definitions.js +64 -5
- package/src/vector/external-ann.js +37 -0
- package/src/vector/hnsw.js +246 -0
- package/src/vector/index.js +85 -2
- package/docs/compatibility.md +0 -39
package/docs/install-windows.md
CHANGED
|
@@ -1,56 +1,144 @@
|
|
|
1
|
-
# Windows
|
|
1
|
+
# Windows 安装与回滚
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 目标:和本鲸一样的 Windows DSH 用户,能从 tgz 直接安装,不需要编译、不需要原生依赖。
|
|
4
|
+
> 前提:**Node >= 24**(`node:sqlite` 内置)、DSH `>=0.2.1-rc.2 <0.4.0`、Windows 10/11。
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
- Node.js **>= 24** (DSH ships a compatible runtime on current builds)
|
|
7
|
-
- DSH `>=0.2.1-rc.2 <0.4.0`
|
|
6
|
+
## 1. 先备份
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
```powershell
|
|
9
|
+
$stamp = Get-Date -Format 'yyyyMMdd-HHmm'
|
|
10
|
+
Copy-Item -Recurse "$env:USERPROFILE\.dsh\profiles\desktop" "$env:USERPROFILE\Desktop\dsh-profile-backup-$stamp"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`dsh-cortex` 默认数据在 `~/.dsh/cortex`,**不读写 shiori 的 `D:\shiori-data`**。第一次安装没有旧数据,不需要迁移。
|
|
14
|
+
|
|
15
|
+
## 2. 生成/取得 tgz
|
|
16
|
+
|
|
17
|
+
在 `plugins/dsh-cortex`:
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
npm pack
|
|
21
|
+
# 产出 dsh-cortex-0.2.0-dev.1.tgz
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
如果用本鲸打好的包,直接用 `dist/dsh-cortex-0.2.0-dev.1.tgz`。包是纯 JS + SQL,无 `node_modules` 依赖。
|
|
25
|
+
|
|
26
|
+
## 3. 安装到 desktop profile
|
|
10
27
|
|
|
11
28
|
```powershell
|
|
12
|
-
dsh plugin --profile desktop add "C
|
|
29
|
+
dsh plugin --profile desktop add "C:\完整路径\dsh-cortex-0.2.0-dev.1.tgz"
|
|
13
30
|
```
|
|
14
31
|
|
|
15
|
-
|
|
16
|
-
and select the same tgz.
|
|
32
|
+
路径必须是**绝对路径**。装完重启 DSH。不要用 `link:` 去指向一个会被清理的目录。
|
|
17
33
|
|
|
18
|
-
##
|
|
34
|
+
## 4. 验收
|
|
35
|
+
|
|
36
|
+
重启后:
|
|
37
|
+
|
|
38
|
+
1. 模型工具列表出现 21 个 `cortex_*`(至少 `cortex_write` / `cortex_search` / `cortex_as_of` / `cortex_playbook` / `cortex_consolidate`)。
|
|
39
|
+
2. 侧栏/插件面板能看到 Cortex。
|
|
40
|
+
3. 写一条测试记忆:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
cortex_write({ text: "安装验收:主人喜欢白饭。", explicit: true })
|
|
44
|
+
cortex_search({ query: "白饭" })
|
|
45
|
+
cortex_self({})
|
|
46
|
+
cortex_guard({ action: "check" })
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
4. API(默认只回环):
|
|
19
50
|
|
|
20
51
|
```powershell
|
|
21
|
-
|
|
52
|
+
curl.exe http://127.0.0.1:7430/api/cortex/health
|
|
22
53
|
```
|
|
23
54
|
|
|
24
|
-
|
|
25
|
-
and run **Guardian → check**.
|
|
55
|
+
期望 `{"ok":true,...}` 且没有 shiori 数据被写。
|
|
26
56
|
|
|
27
|
-
##
|
|
57
|
+
## 5. 可选:开 LLM 巩固
|
|
28
58
|
|
|
29
|
-
|
|
59
|
+
默认 `features.llm=false`,巩固会记录 `skipped` 且零改动。可以在面板「设置 → 权限」点按钮,确认后写入:
|
|
30
60
|
|
|
31
61
|
```text
|
|
32
|
-
|
|
62
|
+
<dataRoot>/feature-overrides.json
|
|
33
63
|
```
|
|
34
64
|
|
|
35
|
-
|
|
36
|
-
|
|
65
|
+
**重启 DSH 后生效**;同一页可以回滚上一次权限修改,审计记录在本地 `audit` 表。
|
|
66
|
+
也可以用配置:
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
- id: cortex
|
|
70
|
+
name: dsh-cortex
|
|
71
|
+
config:
|
|
72
|
+
features:
|
|
73
|
+
llm: true
|
|
74
|
+
consolidateOnSleep: true
|
|
75
|
+
```
|
|
37
76
|
|
|
38
|
-
|
|
77
|
+
开之前先确认当前 DSH 的模型路由可用。失败会跳过,不阻塞睡眠。
|
|
78
|
+
|
|
79
|
+
## 6. 回滚
|
|
39
80
|
|
|
40
81
|
```powershell
|
|
41
|
-
dsh plugin --profile desktop
|
|
82
|
+
dsh plugin --profile desktop remove dsh-cortex
|
|
42
83
|
```
|
|
43
84
|
|
|
44
|
-
|
|
85
|
+
重启。`~/.dsh/cortex` 不会被自动删除;确认不要后再手动处理。要恢复 profile,拷回第 1 步的备份。
|
|
86
|
+
|
|
87
|
+
### 卸载后清理手写 patch
|
|
88
|
+
|
|
89
|
+
如果你在 `cordis.patch.yml` 里手写过 cortex 配置,`dsh plugin remove` **不会删这段**。残留块通常不影响 `--dump-config`,但会让 diff 变脏,重装时也可能踩到“entry not found”。
|
|
90
|
+
|
|
91
|
+
可以用脚本:
|
|
92
|
+
|
|
93
|
+
```powershell
|
|
94
|
+
powershell -ExecutionPolicy Bypass -File .\examples\uninstall-cortex.ps1 `
|
|
95
|
+
-Dsh "D:\path\to\dsh.cmd" -Profile <profile>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
脚本只删 `- id: cortex` 段,保留其他 patch,并跑一次 `--dump-config`;不删 dataRoot。已手动移除时也会跳过 remove、继续清 patch。
|
|
99
|
+
|
|
100
|
+
卸载后检查:
|
|
45
101
|
|
|
46
102
|
```powershell
|
|
47
|
-
|
|
103
|
+
notepad "$HOME\.dsh\profiles\<profile>\cordis.patch.yml"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
删除整段:
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
- id: cortex
|
|
110
|
+
name: dsh-cortex
|
|
111
|
+
config:
|
|
112
|
+
...
|
|
48
113
|
```
|
|
49
114
|
|
|
50
|
-
|
|
115
|
+
保留其他条目;如果文件只剩注释,写回:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
[]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
然后再跑一次:
|
|
122
|
+
|
|
123
|
+
```powershell
|
|
124
|
+
dsh --profile <profile> --dump-config > $null
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
不要为了清理 patch 去删整个 profile 目录;dataRoot 可能不在 profile 内。
|
|
128
|
+
|
|
129
|
+
## 7. 常见问题
|
|
130
|
+
|
|
131
|
+
| 现象 | 原因 | 处理 |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| 装完没有工具 | 插件条目没 active / 重启没做 | 看 profile 的 bundles,重启 DSH |
|
|
134
|
+
| `node:sqlite` 报错 | Node < 24 或运行时不带 SQLite | 升级 DSH/Node 到 24+ |
|
|
135
|
+
| 工具名冲突 | 另一个插件也注册同名工具 | 先停用旧插件,或改名后再装 |
|
|
136
|
+
| 数据目录不对 | 改过 `dataRoot` | 用绝对路径,不要指向 profile 内部 |
|
|
137
|
+
| 面板 403 | 非回环 Host / 跨源 | 用 `127.0.0.1`,同源打开 |
|
|
51
138
|
|
|
52
|
-
|
|
53
|
-
2. Re-enable the previous plugin entry if needed.
|
|
54
|
-
3. Restore the profile configuration and data backup.
|
|
139
|
+
## 8. 兼容性说明
|
|
55
140
|
|
|
56
|
-
|
|
141
|
+
- 这是 **bundle 插件**:`dsh.bundle.patch` 指向 `cordis.patch.yml`,装完自动注册 Host 行。
|
|
142
|
+
- 零运行时 npm 依赖;SQLite 用 Node 内置。
|
|
143
|
+
- Windows 路径手写 `C:\...` 即可;包内没有 shell 脚本。
|
|
144
|
+
- 不修改全局 patch,不覆盖系统提示,不碰 shiori。
|
package/docs/models.md
CHANGED
|
@@ -1,48 +1,183 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 可选模型:embedder / rerank
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 结论先说:**安装包不自动下载模型,也不默认联网。**
|
|
4
|
+
> 大模型动辄几百 MB,自动下载会把“装插件”变成“装模型”,还可能带来磁盘、网络、校验和更新问题。
|
|
5
|
+
> 本插件只提供可插拔接口;用户显式配置后才使用。
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
## 0. 当前接线状态(2026-11-11)
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
- HTTP rerank:**已接到 QA**(`cortex_qa`),默认关,失败开放。
|
|
10
|
+
- HTTP embedder:**接口已实现**(`createOpenAIEmbedder`);**异步索引入口** `POST /vector/index` / `POST /vector/rebuild` 已可用,写不会被网络阻塞;**异步混合检索** `GET /search?async=true` 与 QA 已走 `searchAsync`(远程向量可参与);默认同步 `/search` 仍不等待网络。
|
|
11
|
+
- 安装包**不自动下载**任何模型。
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
## 1. 默认路径(零依赖)
|
|
14
|
+
|
|
15
|
+
- `features.vector = false`:不用向量,FTS5 + 图 + recent 融合。
|
|
16
|
+
- `features.vector = true`:使用内置 `hash-256` embedder(词法哈希,**不是语义模型**)。
|
|
17
|
+
- 不下载任何文件;不需要 `node_modules`;Windows 直接可用。
|
|
18
|
+
|
|
19
|
+
## 2. 可选 HTTP embedder
|
|
20
|
+
|
|
21
|
+
代码:`src/vector/providers.js` 的 `createOpenAIEmbedder`。
|
|
22
|
+
|
|
23
|
+
接口是 OpenAI-compatible `/embeddings`:
|
|
24
|
+
|
|
25
|
+
```http
|
|
26
|
+
POST {baseUrl}/embeddings
|
|
27
|
+
Authorization: Bearer <apiKey>
|
|
28
|
+
{"model":"bge-m3","input":["文本"]}
|
|
11
29
|
```
|
|
12
30
|
|
|
13
|
-
|
|
31
|
+
返回:
|
|
14
32
|
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
baseUrl: http://127.0.0.1:11434/v1
|
|
18
|
-
model: bge-m3
|
|
19
|
-
dim: 1024
|
|
20
|
-
key: (blank)
|
|
33
|
+
```json
|
|
34
|
+
{"data":[{"embedding":[0.1,0.2]}]}
|
|
21
35
|
```
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
|
|
37
|
+
它不会在安装时运行。要接本地服务(如 Xinference / Ollama 的 OpenAI 兼容层 / vLLM),由用户自己启动服务并提供 `baseUrl`。
|
|
38
|
+
**不要把 API key 写进仓库或安装包。**
|
|
39
|
+
|
|
40
|
+
## 2.1 本地 bge 可选配置(默认关)
|
|
41
|
+
|
|
42
|
+
本机实测用 Ollama 的 `bge-m3`(1024 维)通过 OpenAI 兼容 `/v1/embeddings` 接入。
|
|
25
43
|
|
|
26
|
-
|
|
44
|
+
### profile 配置
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
- id: cortex
|
|
48
|
+
name: dsh-cortex
|
|
49
|
+
config:
|
|
50
|
+
features:
|
|
51
|
+
vector: true
|
|
52
|
+
# dataRoot / dbFile 按你的 profile 配
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 模型配置
|
|
56
|
+
|
|
57
|
+
在 cortex 的 dataRoot 下放 `model-config.json`(可在面板模型设置里保存,效果相同):
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"embedding": {
|
|
62
|
+
"mode": "local",
|
|
63
|
+
"baseUrl": "http://127.0.0.1:11434/v1",
|
|
64
|
+
"model": "bge-m3",
|
|
65
|
+
"dim": 1024,
|
|
66
|
+
"apiKey": ""
|
|
67
|
+
},
|
|
68
|
+
"rerank": {
|
|
69
|
+
"enabled": false,
|
|
70
|
+
"baseUrl": "",
|
|
71
|
+
"model": "",
|
|
72
|
+
"apiKey": ""
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- `mode: local` 表示本地 keyless 服务;不要把云端 key 写进仓库。
|
|
78
|
+
- 不配模型时,`features.vector=true` 只会用内置 `hash-256` 词法哈希,**不是语义模型**。
|
|
79
|
+
- 向量索引是暴力扫描,适合个人千条级记忆;不是十亿级 ANN。
|
|
80
|
+
|
|
81
|
+
### 实测代价(2026-11-11,300 traces / 50 paraphrase queries)
|
|
27
82
|
|
|
28
83
|
```text
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
84
|
+
FTS: hit 0.96 / MRR 0.694 / nDCG 0.603 / p50 4.5-4.8ms
|
|
85
|
+
bge: hit 1.00 / MRR 0.960 / nDCG 0.883 / p50 51-63ms
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- 语义召回明显提升,但查询延迟约 10 倍。
|
|
89
|
+
- 这是合成 paraphrase,不是 LoCoMo;不能当公开 SOTA。
|
|
90
|
+
- 默认仍关闭;没有本地模型/服务就不要开。
|
|
91
|
+
|
|
92
|
+
## 2.2 可选 ANN(默认关)
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
features:
|
|
96
|
+
vector: true
|
|
97
|
+
vectorAnn: true
|
|
98
|
+
vectorAnnMin: 20000
|
|
99
|
+
vectorAnnEngine: hnsw
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- 复用 `src/vector/ann.js` 的单层 NSW 索引;纯 JS,无原生依赖。
|
|
103
|
+
- 小于 `vectorAnnMin` 时仍走暴力精确扫描。
|
|
104
|
+
- ANN 命中不足 5 条时自动回退暴力扫描,避免 scope/过滤把结果卡空。
|
|
105
|
+
- 首次搜索从 embeddings 懒构建;写入/删除会同步索引。
|
|
106
|
+
- 默认 `vectorAnn: false`;不开启时行为不变。
|
|
107
|
+
- 当前验证是单元/小规模,不是 100k ANN 压测;大库收益和召回还需单独 benchmark。
|
|
108
|
+
- 5000 条 A/B 结论(dim 64):ANN ef=120 recall@10 0.29,ef=400 0.70(p50 0.99ms,暴力 1.11ms),ef=800 0.93(p50 2.73ms,暴力 1.16ms),ef=1600 0.998(p50 11ms)。**小库暴力反而更快**,所以默认阈值放在 20000,且 ANN 默认关。
|
|
109
|
+
- 20k / 100k 复验(ef=800/1600):20k recall 0.591(ANN p50 5.4ms,暴力 9.2ms);100k recall 0.413(ANN p50 10.9ms,暴力 38.9ms,构建约 101s)。
|
|
110
|
+
- HNSW 候选(`src/vector/hnsw.js`,二叉堆版)在 5k/20k 的质量:
|
|
111
|
+
- 5k:recall 0.997,build 5.5s,p50 2.24ms(暴力 1.15ms)
|
|
112
|
+
- 20k:recall 0.956,build 58.4s,p50 4.88ms(暴力 5.78ms)
|
|
113
|
+
- 所以 `vectorAnnEngine: hnsw` 已接到可选路径,但 **`vectorAnn` 仍默认关**;HNSW 冷构建慢,20k 以下没明显查询优势。
|
|
114
|
+
- 旧 NSW 保留为 `vectorAnnEngine: nsw` 的兼容选项,不再是默认引擎。
|
|
115
|
+
- 100k 构建/内存尚未验证;不建议在生产库直接开。
|
|
116
|
+
|
|
117
|
+
### 外置 ANN(默认关)
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
features:
|
|
121
|
+
vector: true
|
|
122
|
+
vectorAnnExternal: true
|
|
123
|
+
vectorAnnEndpoint: 'http://127.0.0.1:8765/search'
|
|
124
|
+
vectorAnnTimeoutMs: 800
|
|
34
125
|
```
|
|
35
126
|
|
|
36
|
-
|
|
37
|
-
|
|
127
|
+
- 只接 `searchAsync` 异步路径;同步 `search` 继续精确扫描。
|
|
128
|
+
- 端点为空或请求失败 → 回退精确扫描,不丢召回。
|
|
129
|
+
- 客户端契约见 `docs/external-ann.md`。
|
|
130
|
+
- **需要你手动启动本地 ANN 服务**;当前没有常驻服务。
|
|
131
|
+
- 20k 端到端验证:recall@10 1.0,p50 20.3-20.8ms(HTTP 客户端 + HNSW 服务)。
|
|
132
|
+
|
|
133
|
+
## 3. 可选 HTTP rerank(已接到 QA)
|
|
134
|
+
|
|
135
|
+
代码:`createHttpReranker`,已在 `cortex_qa` 的检索结果上生效(失败开放,回退融合顺序)。
|
|
136
|
+
|
|
137
|
+
配置:
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
- id: cortex
|
|
141
|
+
name: dsh-cortex
|
|
142
|
+
config:
|
|
143
|
+
rerankEnabled: true
|
|
144
|
+
rerankBaseUrl: "http://127.0.0.1:9000/v1"
|
|
145
|
+
rerankModel: "bge-reranker-base"
|
|
146
|
+
# rerankApiKey: "" # 本机服务通常不需要
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
接口:
|
|
150
|
+
|
|
151
|
+
```http
|
|
152
|
+
POST {baseUrl}/rerank
|
|
153
|
+
{"model":"bge-reranker-base","query":"...","documents":["..."],"top_n":8}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
返回 `results: [{index, relevance_score}]`。
|
|
157
|
+
|
|
158
|
+
默认关;没有配置或请求失败时,QA 保持原来的 RRF 顺序,不阻塞回答。
|
|
159
|
+
|
|
160
|
+
## 4. 本地 ONNX 模型(未内置)
|
|
161
|
+
|
|
162
|
+
本鲸没有把 `onnxruntime-node` 或 `@huggingface/transformers` 放进运行时依赖,原因:
|
|
163
|
+
|
|
164
|
+
- 安装体积大(数百 MB);
|
|
165
|
+
- Windows 上原生二进制/驱动差异;
|
|
166
|
+
- 安装期下载模型不可审计。
|
|
167
|
+
|
|
168
|
+
后续如果要内置,应该是**单独的 optional 包**,并满足:
|
|
38
169
|
|
|
39
|
-
|
|
170
|
+
1. 用户显式点“下载模型”;
|
|
171
|
+
2. 显示 URL、大小、SHA-256;
|
|
172
|
+
3. 下载到 `~/.dsh/cortex/models/`,不写 profile;
|
|
173
|
+
4. 失败开放,不影响 FTS;
|
|
174
|
+
5. 可一键删除。
|
|
40
175
|
|
|
41
|
-
|
|
42
|
-
fails, Cortex keeps the original fusion order.
|
|
176
|
+
## 5. 安装包里有什么
|
|
43
177
|
|
|
44
|
-
|
|
178
|
+
- 没有模型文件;
|
|
179
|
+
- 没有原生 `.node`;
|
|
180
|
+
- 没有 `node_modules`;
|
|
181
|
+
- 只有纯 JS + SQL + 文档。
|
|
45
182
|
|
|
46
|
-
|
|
47
|
-
- Local mode is the safest for private data.
|
|
48
|
-
- Remote mode sends memory text to the configured endpoint.
|
|
183
|
+
所以 Windows 用户装完即可用;要用语义模型时再按上面的配置接服务。
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# 多模态附件:只存引用,不存字节
|
|
2
|
+
|
|
3
|
+
> 当前实现是**元数据边界**,不是视觉/音频理解模型。
|
|
4
|
+
|
|
5
|
+
## 1. 写入
|
|
6
|
+
|
|
7
|
+
`cortex_write` / `POST /api/cortex/write` 支持 `attachments`:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"text": "主人发来一张白饭照片。",
|
|
12
|
+
"explicit": true,
|
|
13
|
+
"attachments": [
|
|
14
|
+
{
|
|
15
|
+
"kind": "image",
|
|
16
|
+
"uri": "https://example.test/rice.png",
|
|
17
|
+
"name": "rice.png",
|
|
18
|
+
"mime": "image/png",
|
|
19
|
+
"bytes": 12345,
|
|
20
|
+
"sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
约束:
|
|
27
|
+
|
|
28
|
+
- 最多 8 个
|
|
29
|
+
- `kind`: image / audio / video / file
|
|
30
|
+
- `uri` 必填,最长 2000
|
|
31
|
+
- `sha256` 必须是 64 位 hex
|
|
32
|
+
- `bytes` 0..1e9
|
|
33
|
+
- **不读取、不下载、不解析 URI**
|
|
34
|
+
- 不把二进制写进 SQLite
|
|
35
|
+
|
|
36
|
+
## 2. 存储
|
|
37
|
+
|
|
38
|
+
落在 `traces.metadata_json.attachments`:
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"attachments": [
|
|
43
|
+
{"kind": "image", "uri": "https://example.test/rice.png", "mime": "image/png", "bytes": 12345}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
没有单独附件表,也没有内容寻址存储。旧库会通过 `ensureTraceColumns` 自动补 `metadata_json` 列,默认 `{}`。
|
|
49
|
+
|
|
50
|
+
## 3. 当前能做什么
|
|
51
|
+
|
|
52
|
+
- 记录“这条记忆关联了哪些附件”的引用
|
|
53
|
+
- 在 trace 读取时返回 metadata
|
|
54
|
+
- 在写入结果里报告附件数量
|
|
55
|
+
- 为未来的视觉/音频模型留出入口
|
|
56
|
+
|
|
57
|
+
## 4. 当前不能做什么
|
|
58
|
+
|
|
59
|
+
- 不能读取图片/音频内容
|
|
60
|
+
- 不能生成缩略图
|
|
61
|
+
- 不能做 OCR / 语音转写
|
|
62
|
+
- 不能校验 URI 指向的内容
|
|
63
|
+
- 不能防止恶意 URI(调用方自己负责)
|
|
64
|
+
- 不能自动下载模型
|
|
65
|
+
|
|
66
|
+
## 5. 安全边界
|
|
67
|
+
|
|
68
|
+
- 附件只是引用,不是可信内容
|
|
69
|
+
- 不要把私密 URL、token、签名参数写进 uri
|
|
70
|
+
- 隐私删除 trace 时,metadata 随 trace 一起离开;外部 URI 上的文件不在 cortex 控制内
|
|
71
|
+
- 导出 Markdown 是否包含附件元数据,后续再定
|
|
72
|
+
|
|
73
|
+
## 5.1 可选本地读取器(默认关)
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
features:
|
|
77
|
+
attachmentReader: true
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```http
|
|
81
|
+
POST /api/cortex/attachments/inspect
|
|
82
|
+
{"uri":"file:///C:/path/rice.txt"}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- **只接受 `file://`**
|
|
86
|
+
- 只返回 name/bytes/mtime/sha256
|
|
87
|
+
- 不返回文件内容
|
|
88
|
+
- 最大 50MB
|
|
89
|
+
- 默认关;未开启 403
|
|
90
|
+
- 写入 audit:`attachment.inspect`
|
|
91
|
+
|
|
92
|
+
这不是 OCR/转写。它只做本地文件元数据与哈希校验,方便把附件引用和实际文件对上。
|
|
93
|
+
|
|
94
|
+
## 5.2 提取器联动(可选)
|
|
95
|
+
|
|
96
|
+
独立包 `dsh-cortex-extractors` 的 `cortex_extract_text` 支持显式 `traceId`:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{"uri":"file:///C:/tmp/frame.png","mode":"ocr","traceId":"trc_target"}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- 主脑写入一条 **派生 trace**(不修改原 trace)
|
|
103
|
+
- metadata 保留 `derivedFrom`、URI、mode、engine
|
|
104
|
+
- 需要提取器与主脑同时启用
|
|
105
|
+
- 不传 `traceId` 时仍只返回文字,不写记忆
|
|
106
|
+
|
|
107
|
+
## 6. 下一步
|
|
108
|
+
|
|
109
|
+
1. 可选附件读取器接口(本地、显式开启)
|
|
110
|
+
2. 图片缩略图/OCR 作为独立可选包
|
|
111
|
+
3. 附件级删除/保留策略
|
|
112
|
+
4. 与 bge 一样:默认关,失败开放,不自动下载模型
|
package/docs/scopes.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Scope 与只读共享
|
|
2
|
+
|
|
3
|
+
> 结论先说:`scope` 是**数据隔离边界**,`readOnlyScopes` 是**写保护**;
|
|
4
|
+
> 它们不是完整的身份认证/授权系统。能读 shared 的调用方仍然能读,只是不能改。
|
|
5
|
+
|
|
6
|
+
## 0. 默认行为
|
|
7
|
+
|
|
8
|
+
- 默认 scope:`global`
|
|
9
|
+
- 默认 `readOnlyScopes: []`
|
|
10
|
+
- 默认 dataRoot:`desktop` profile 仍是历史 `~/.dsh/cortex`;其他 profile 未显式配置时派生到 `~/.dsh/cortex/profiles/<profile>`(避免干净 profile 读到 desktop 库)
|
|
11
|
+
- 显式 `dataRoot` / `dbFile` / `CORTEX_HOME` 优先级更高
|
|
12
|
+
- 不配置 `readOnlyScopes` 时,写权限行为和以前一样
|
|
13
|
+
|
|
14
|
+
## 1. scope 怎么用
|
|
15
|
+
|
|
16
|
+
API 支持:
|
|
17
|
+
|
|
18
|
+
```http
|
|
19
|
+
x-cortex-scope: agent-a
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
或查询参数:
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
?scope=agent-a
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
工具大多只操作当前配置的默认 scope;按 id 的写工具会先查记录所属 scope。
|
|
29
|
+
|
|
30
|
+
## 2. 只读共享示例
|
|
31
|
+
|
|
32
|
+
主配置:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
- id: cortex
|
|
36
|
+
name: dsh-cortex
|
|
37
|
+
config:
|
|
38
|
+
scope: agent-a
|
|
39
|
+
readOnlyScopes:
|
|
40
|
+
- shared
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
含义:
|
|
44
|
+
|
|
45
|
+
- `agent-a` 可写自己的 scope
|
|
46
|
+
- `shared` 只能读
|
|
47
|
+
- 写 `shared` 的记忆、工作项、目标、准则、候选边、日记、情绪都会拒绝
|
|
48
|
+
- `forget` / compress / retention / consolidate / vector rebuild 也不会动 `shared`
|
|
49
|
+
|
|
50
|
+
API 返回:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{"ok":false,"error":"scope-read-only","scopeId":"shared"}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
状态码:**403**。
|
|
57
|
+
|
|
58
|
+
工具返回:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
未执行:该记录属于只读共享 scope。
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 2.1 显式写授权(可选)
|
|
65
|
+
|
|
66
|
+
默认只读 scope 谁都写不了。需要给某个 agent 开写时:
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
- id: cortex
|
|
70
|
+
name: dsh-cortex
|
|
71
|
+
config:
|
|
72
|
+
readOnlyScopes:
|
|
73
|
+
- shared
|
|
74
|
+
scopeWriteGrants:
|
|
75
|
+
- shared:agent-a
|
|
76
|
+
- grant: shared:agent-b
|
|
77
|
+
until: '2026-12-31T00:00:00Z'
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
字符串是永久授权;对象形式到期自动失效。调用时带:
|
|
81
|
+
|
|
82
|
+
```http
|
|
83
|
+
x-cortex-agent: agent-a
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
未带 header / 未授权仍是 403。
|
|
87
|
+
|
|
88
|
+
### 运行时撤销/新增(不重启)
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
GET /api/cortex/security/grants
|
|
92
|
+
POST /api/cortex/security/grants { "action": "add", "grant": "shared:agent-a" }
|
|
93
|
+
POST /api/cortex/security/grants { "action": "revoke", "grant": "shared:agent-a" }
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
覆盖保存在 `<dataRoot>/scope-grants.json`,重启后仍生效。
|
|
97
|
+
撤销会写入 `revoked` 列表,优先于配置文件里的同名 grant。
|
|
98
|
+
这些改动会进 audit:`scope.grant.add` / `scope.grant.revoke`。
|
|
99
|
+
|
|
100
|
+
这不是登录或签名:header 是本地调用方自报的 agent id,只适合本机多 agent 协作。工具路径不带这个 header,因此工具仍按“默认 scope 只读”处理。
|
|
101
|
+
|
|
102
|
+
## 3. 多 agent 的两种隔离
|
|
103
|
+
|
|
104
|
+
### 同一 dataRoot,不同 scope
|
|
105
|
+
|
|
106
|
+
适合“一个进程里多个 agent / 会话共享一份库”。
|
|
107
|
+
|
|
108
|
+
- 各自读写自己的 scope
|
|
109
|
+
- `shared` 设为只读
|
|
110
|
+
- 谁有 API 访问权,谁就能读 `shared`
|
|
111
|
+
|
|
112
|
+
### 不同 dataRoot / profile
|
|
113
|
+
|
|
114
|
+
适合“完全不同的 agent,不共享数据库”。
|
|
115
|
+
|
|
116
|
+
- 每个 profile 独立 `dataRoot`
|
|
117
|
+
- 不会互相看到 traces/facts/graph
|
|
118
|
+
- 需要共享时,走导出/导入或单独的共享库
|
|
119
|
+
|
|
120
|
+
## 4. 这不是什么
|
|
121
|
+
|
|
122
|
+
- 不是多用户登录 / token 身份系统
|
|
123
|
+
- 不是按 agent 的细粒度 ACL
|
|
124
|
+
- 不会阻止能访问本地 API 的人读取 shared
|
|
125
|
+
- 不会自动把 desktop 数据迁到 shared
|
|
126
|
+
- 不会替调用方判断“这个 agent 该不该读”
|
|
127
|
+
|
|
128
|
+
## 5. 已验证的边界
|
|
129
|
+
|
|
130
|
+
- 两个 scope 的 facts / as-of 互不可见
|
|
131
|
+
- 两个 scope 的候选边互不混
|
|
132
|
+
- 只读 scope 的 write / working / goal / playbook / candidate / life / emotion / compress / forget 都会拒绝
|
|
133
|
+
- 候选边仍然要人工 approve 才进图
|
|
134
|
+
|
|
135
|
+
## 6. 还没做
|
|
136
|
+
|
|
137
|
+
- agent 身份与签名
|
|
138
|
+
- 显式 share grant / 到期时间
|
|
139
|
+
- 跨 agent 审计报表
|
|
140
|
+
- 多模态附件的共享边界
|
|
141
|
+
|
|
142
|
+
在这些完成前,文档里不要把它写成“多 agent 安全模型”,只能写“scope 隔离 + 写保护”。
|