@yottameta/yotta-memory 0.6.0 → 0.6.1

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/README.md CHANGED
@@ -89,8 +89,8 @@
89
89
  ### 画像与开工上下文(v0.6.0)
90
90
 
91
91
  - **profile**:聚合 `private/<owner>/` 下 PREF / BOUND / COMMIT 原文,按 type + subject + tags 归组,写 `profile.md`;引擎零推断,画像结论由 AI 依据「记忆守则」内部形成,不当面贴标签。
92
- - **context**:一键生成开工上下文包——身份 + 用户画像摘要 + 近期记忆(按活跃度)+ 边界提醒 + 承诺 / 锚点,作为会话主注入(替代裸 `recall`)。
93
- - **记忆守则**:SKILL.md 内置规则层(类型红线 / 主动捕获触发信号 / 了解用户三阶段四手法 / 心理学底座 / 底线与边界 / 宿主隔离 / 反模式),让 AI「越用越懂」有章法。
92
+ - **context**:一键生成开工上下文包——多智能体接入铁律 + 身份 + 用户画像摘要 + 近期记忆(按 importance 排序)+ 边界提醒 + 承诺 / 锚点;支持 `--budget` 字符预算(token 恒定,不随记忆膨胀)。
93
+ - **记忆守则**:SKILL.md 内置规则层(类型红线 / 主动捕获触发信号 / 了解用户三阶段四手法 / 心理学底座与对齐 / 底线与边界 / 宿主隔离 / 反模式),让 AI「越用越懂」有章法。
94
94
 
95
95
  ### 检索:索引 + 中文分词打分
96
96
 
@@ -183,10 +183,10 @@ npm i -g @yottameta/yotta-memory
183
183
  | 命令 | 作用 |
184
184
  |---|---|
185
185
  | `yotta-memory init [--project] [--dir <目录>]` | 初始化记忆库(默认用户级 `~/.yottamemory/`;--dir 显式指定位置)|
186
- | `yotta-memory remember <type> <subject> <statement> [--owner <id>] [--verify] [--no-hint]` | 写入记忆(同 subject+statement 自动更新;--owner 标注归属;--verify 写后回读校验;--no-hint 关闭类型启发式提示)|
186
+ | `yotta-memory remember <type> <subject> <statement> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint]` | 写入记忆(同 subject+statement 自动更新;--owner 标注归属;--source 记录来源;--weight 重要性权重、去重取 max;--verify 写后回读;--no-hint 关闭类型提示)|
187
187
  | `yotta-memory recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe]` | 检索记忆(索引+TF 打分,读取分区过滤;越界读其它智能体私密默认拒绝,需 grant / identity=user / `--unsafe`;`--agent <其它>` 仅作身份声明、不授予跨读;项目级优先)|
188
188
  | `yotta-memory profile [--owner <id>]` | 生成用户画像(聚合 `private/<owner>/` 原文,零推断,写 `profile.md`;跨 owner 默认拒绝)|
189
- | `yotta-memory context [--limit N] [--owner <id>]` | 生成开工上下文包(身份 + 画像 + 近期记忆 + 边界 + 承诺,stdout 不落盘)|
189
+ | `yotta-memory context [--limit N] [--owner <id>] [--budget N]` | 生成开工上下文包(身份 + 多智能体铁律 + 画像 + 近期记忆 + 边界 + 承诺;--budget 近期记忆字符预算,token 恒定)|
190
190
  | `yotta-memory forget <文件>` | 删除一条记忆(按类型目录路径或文件名)|
191
191
  | `yotta-memory archive [--days 180] [--threshold 0.4]` | 归档旧记忆(盖棺分+年龄,immutable 除外)|
192
192
  | `yotta-memory reindex` | 重建索引(手动改 .md 后校正)|
package/SKILL.md CHANGED
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  name: yotta-memory
3
3
  description: "元忆 —— 有权限边界的文件式智能体记忆。文件式、零依赖、可 diff/回滚:让任何 AI 智能体活过会话,开工 recall 恢复上下文、重要信息 remember 落盘、收工归档。类型体系 FACT(公共共享)/ PREF / BOUND / COMMIT(私密隔离)。触发:记住、别忘了、记一笔、记忆、remember、recall、跨会话、上次说到、续测、交接、归档、记忆盘、共享记忆、局域网记忆、画像、开工上下文、记忆守则、profile、context、越用越懂"
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  license: MIT
6
6
  ---
7
7
 
8
8
  # yotta-memory(元忆)— 有权限边界的文件式智能体记忆
9
9
 
10
10
  > 一句话:元忆 —— 有权限边界的文件式智能体记忆(不注入、可 diff、能回滚;FACT 共享、PREF / BOUND / COMMIT 私密隔离)。
11
- > 版本:0.6.0 | 最后更新:2026-08-25
11
+ > 版本:0.6.1 | 最后更新:2026-08-25
12
12
 
13
13
  ## 这是什么
14
14
 
@@ -73,6 +73,7 @@ license: MIT
73
73
  - 共情至少到第 3 阶段:识别 → 理解 → 回应 → 验证。
74
74
  - 诚实声明:AI 是模式匹配非真感受,不伪装、不编造伪情感记忆。
75
75
  - 危机识别:不评判、持续在场、温和引导现实支持;不擅自越界联系第三方。
76
+ - 对齐:回应时让积累的理解自然影响语气与措辞(让用户感到「被记得、被懂」),而非机械引用记忆条目。
76
77
  - 情感外包双刃剑:做增益真实生活的陪伴,不替代真实关系。
77
78
 
78
79
  ### 5. 写入时序(一次会话的节奏)
@@ -131,7 +132,7 @@ license: MIT
131
132
 
132
133
  **D. 开工主注入(context)**:
133
134
 
134
- - 身份就绪后运行 `yotta-memory context [--limit 10]`(远端经 MCP 用 `recall` 补细节):一键拿到「身份 + 用户画像摘要 + 近期记忆 + 边界提醒 + 承诺 / 锚点」。
135
+ - 身份就绪后运行 `yotta-memory context [--limit 10] [--budget 1800]`(远端经 MCP 用 `recall` 补细节):一键拿到「身份 + 多智能体铁律 + 用户画像摘要 + 近期记忆 + 边界提醒 + 承诺 / 锚点」;`--budget` 控制近期记忆字符预算(token 恒定,不随记忆膨胀)。
135
136
  - 无画像时 context 自动生成一次或降级输出其余段,不报错。
136
137
  - 需要深挖旧事再 `recall <关键词>`。
137
138
  - 私密记忆(PREF / BOUND / COMMIT)**必须有 owner**:未声明身份写私密会被引擎拒绝(公共 FACT 不受影响)。
@@ -144,10 +145,10 @@ license: MIT
144
145
  | 命令 | 作用 |
145
146
  |---|---|
146
147
  | `yotta-memory init [--project] [--dir <目录>]` | 初始化记忆库(默认用户级;--dir 显式指定位置)|
147
- | `yotta-memory remember <type> <subject> <statement> [--owner <id>] [--verify] [--no-hint]` | 写入(同 subject+statement 自动更新;--owner 标注归属;--verify 写后回读校验;--no-hint 关闭类型启发式提示)|
148
+ | `yotta-memory remember <type> <subject> <statement> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint]` | 写入(同 subject+statement 自动更新;--owner 标注归属;--source 记录来源;--weight 重要性权重默认 1.0、去重取 max;--verify 写后回读校验;--no-hint 关闭类型启发式提示)|
148
149
  | `yotta-memory recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe]` | 检索(索引+TF 打分,读取分区过滤;越界读其它智能体私密默认拒绝,需 grant / identity=user / `--unsafe`;`--agent <其它>` 只作身份声明/展示,不授予跨读——读他人私密同样要授权;项目级优先)|
149
150
  | `yotta-memory profile [--owner <id>]` | 生成用户画像(聚合 `private/<owner>/` 原文,零推断,写 `profile.md`;跨 owner 默认拒绝)|
150
- | `yotta-memory context [--limit N] [--owner <id>]` | 生成开工上下文包(身份 + 画像 + 近期记忆 + 边界 + 承诺,stdout 不落盘)|
151
+ | `yotta-memory context [--limit N] [--owner <id>] [--budget N]` | 生成开工上下文包(身份 + 多智能体铁律 + 画像 + 近期记忆 + 边界 + 承诺;--budget 近期记忆字符预算,0=不限)|
151
152
  | `yotta-memory forget <文件>` | 删除(按类型目录路径或文件名)|
152
153
  | `yotta-memory archive [--days 180] [--threshold 0.4]` | 归档旧记忆(盖棺分+年龄,immutable 除外)|
153
154
  | `yotta-memory reindex` | 重建索引(手动改 .md 后校正)|
@@ -173,7 +174,7 @@ license: MIT
173
174
  └── agents.json # 智能体身份登记表(唯一性)
174
175
  ```
175
176
 
176
- 记忆文件 `<YYYY-MM-DD>-<NNNN>.md`,frontmatter 含 `type / subject / statement / confidence / created / updated / tags / immutable / scope / owner / access_count / last_accessed`;正文为记忆内容。旧版根下平铺的 `prefs/` `bounds/` `commits/` 会在 `reindex`(或首次 recall 建索引)时按 frontmatter `owner` 自动迁移到 `private/<owner>/<type>/`。
177
+ 记忆文件 `<YYYY-MM-DD>-<NNNN>.md`,frontmatter 含 `type / subject / statement / confidence / created / updated / tags / immutable / scope / owner / source / weight / access_count / last_accessed`(`source` 记录来源、`weight` 重要性权重默认 1.0);正文为记忆内容。旧版根下平铺的 `prefs/` `bounds/` `commits/` 会在 `reindex`(或首次 recall 建索引)时按 frontmatter `owner` 自动迁移到 `private/<owner>/<type>/`。
177
178
 
178
179
  自我档案(本智能体身份,强制落盘):PREF,`subject=自我接入档案`,`owner=<本智能体ID>`,statement 为 `; ` 分隔的 key:value——`agent_id / host / memory_home / mcp_mode(stdio|http)/ engine_url(仅远端)/ token(仅远端;本机不存 token)`,可含 `agent_name / user_name / relationship`(`iam --name/--user/--relationship` 写入)。
179
180
 
package/USER_GUIDE.md CHANGED
@@ -72,12 +72,12 @@ yotta-memory config get # 查看记忆库位置
72
72
 
73
73
  ```bash
74
74
  yotta-memory profile # 生成用户画像(写 private/<owner>/profile.md)
75
- yotta-memory context --limit 10 # 生成开工上下文包(身份+画像+近期记忆+边界+承诺)
75
+ yotta-memory context --limit 10 --budget 1800 # 生成开工上下文包(身份+铁律+画像+近期记忆+边界+承诺,预算控 token)
76
76
  yotta-memory iam <id> --name 元忆 --user 老张 --relationship 伙伴 # 自我档案扩展显示名/用户/关系
77
77
  ```
78
78
 
79
79
  - `profile` 引擎零推断:只按类型 / 主题 / 标签归组呈现原文,画像结论由 AI 内部形成,不当面贴标签。
80
- - `context` 是每次会话开工的主注入,替代裸 `recall`;无画像时自动生成一次或降级,不报错。
80
+ - `context` 是每次会话开工的主注入,替代裸 `recall`;无画像时自动生成一次或降级,不报错;`--budget` 控制近期记忆字符预算(token 恒定)。
81
81
  - `remember --verify` 写后回读校验;`remember --no-hint` 关闭「疑似偏好,建议 PREF」的提示。
82
82
 
83
83
  ### 记忆库位置:本机智能体如何找到记忆
@@ -244,10 +244,10 @@ yotta-memory remember FACT 主题 内容 # 智能体落盘
244
244
  | 命令 | 作用 |
245
245
  |---|---|
246
246
  | `yotta-memory init [--project] [--dir <目录>]` | 初始化记忆库 |
247
- | `yotta-memory remember <类型> <主题> <内容> [--owner <id>] [--verify] [--no-hint]` | 写入记忆(--verify 写后回读;--no-hint 关闭类型提示)|
247
+ | `yotta-memory remember <类型> <主题> <内容> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint]` | 写入记忆(--source 来源;--weight 重要性权重;--verify 写后回读;--no-hint 关闭类型提示)|
248
248
  | `yotta-memory recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe]` | 检索记忆(读取分区过滤;`--agent <其它>` 仅作身份声明、不授予跨读;越界读其它智能体私密默认拒绝,需 grant / identity=user / `--unsafe`)|
249
249
  | `yotta-memory profile [--owner <id>]` | 生成用户画像(零推断,写 `profile.md`)|
250
- | `yotta-memory context [--limit N] [--owner <id>]` | 开工上下文包(身份+画像+近期记忆+边界+承诺)|
250
+ | `yotta-memory context [--limit N] [--owner <id>] [--budget N]` | 开工上下文包(身份+铁律+画像+近期记忆+边界+承诺;--budget 近期记忆字符预算)|
251
251
  | `yotta-memory forget <文件>` | 删除一条记忆 |
252
252
  | `yotta-memory archive [--days 180] [--threshold 0.4]` | 归档旧记忆 |
253
253
  | `yotta-memory reindex` | 重建索引 |
@@ -6,6 +6,7 @@
6
6
  // v0.5.3 新增:CLI 选项可前置(--agent 等允许放在子命令前,不再误报"未知命令")/ lan enable 成功补"服务不会立刻启动"提示(v0.5.2 lan 引号修复无回归)
7
7
  // v0.5.4 新增:lan enable 在非管理员(schtasks Access denied)时自动降级为用户级 Startup 静默自启(VBS sh.Run 窗口0 + autostart.cmd,node 路径 process.execPath 自动探测);lan disable/status 同时管理计划任务与 Startup 双机制
8
8
  // v0.6.0 新增:灵魂盘核心——profile(用户画像聚合,零推断)/ context(开工上下文包)/ iam 扩展(--name/--user/--relationship)/ remember --verify(写后回读)与 --no-hint(关闭类型启发式提示)+ SKILL「记忆守则」
9
+ // v0.6.1 新增:灵魂盘机制精髓补齐——context --budget(token 预算,近记忆按剩余预算放行)/ context 内嵌「多智能体接入铁律」段 / remember --source/--weight(来源 + 重要性权重,去重 weight 取 max)/ 近期记忆排序融合 importance(confidence×recency+updated+weight+immutable)
9
10
  'use strict';
10
11
 
11
12
  const fs = require('fs');
@@ -15,7 +16,7 @@ const crypto = require('crypto');
15
16
  const http = require('http');
16
17
  const child_process = require('child_process');
17
18
 
18
- const VERSION = '0.6.0';
19
+ const VERSION = '0.6.1';
19
20
  const TYPES = ['FACT', 'PREF', 'BOUND', 'COMMIT'];
20
21
  const TYPE_DIRS = { FACT: 'facts', PREF: 'prefs', BOUND: 'bounds', COMMIT: 'commits' };
21
22
  const PUBLIC_DIR = 'facts';
@@ -24,7 +25,7 @@ const PRIVATE_LEAF = ['prefs', 'bounds', 'commits'];
24
25
  const ARCHIVE_DIR = '.archive';
25
26
  const INDEX_FILE = 'index.json';
26
27
  const PRIVATE_TYPES = ['PREF', 'BOUND', 'COMMIT'];
27
- const FIELD_ORDER = ['type', 'subject', 'statement', 'confidence', 'created', 'updated', 'tags', 'immutable', 'scope', 'owner', 'access_count', 'last_accessed'];
28
+ const FIELD_ORDER = ['type', 'subject', 'statement', 'confidence', 'created', 'updated', 'tags', 'immutable', 'scope', 'owner', 'source', 'weight', 'access_count', 'last_accessed'];
28
29
  const CONFIG_FILE = 'config.json';
29
30
  const SERVER_SUBDIR = '.server';
30
31
  const TOKENS_FILE = 'tokens.json';
@@ -274,6 +275,8 @@ function readEntry(fp, root) {
274
275
  access_count: parseInt(meta.access_count || '0', 10) || 0,
275
276
  last_accessed: meta.last_accessed || '',
276
277
  immutable: meta.immutable === 'true',
278
+ source: meta.source || '',
279
+ weight: (parseFloat(meta.weight) > 0 ? parseFloat(meta.weight) : 1.0),
277
280
  tokens: buildTokens(subject, statement, tags),
278
281
  meta: meta,
279
282
  };
@@ -322,6 +325,21 @@ function vitality(meta) {
322
325
  if (last) { const d = daysBetween(last, today()); recency = Math.max(0, 1 - Math.floor(d / 30) * 0.2); }
323
326
  return 0.4 * conf + 0.3 * accScore + 0.3 * recency;
324
327
  }
328
+ // 灵魂盘 importance 融合:confidence × (0.5 + recency) + updated 加分 + weight 乘子 + immutable 加分
329
+ function importanceScore(meta) {
330
+ const conf = parseFloat(meta.confidence || 1.0);
331
+ let ageDays = 999;
332
+ if (meta.created) {
333
+ const d = daysBetween(meta.created, today());
334
+ if (!isNaN(d)) ageDays = d;
335
+ }
336
+ const recency = 1.0 / (1.0 + Math.max(ageDays, 0) / 180.0);
337
+ let score = conf * (0.5 + recency);
338
+ if (meta.updated && meta.created && meta.updated !== meta.created) score += 0.5;
339
+ const w = parseFloat(meta.weight || 1.0); if (w > 0) score *= w;
340
+ if (meta.immutable === 'true') score += 2.0;
341
+ return score;
342
+ }
325
343
  function loadGrants(root) {
326
344
  const fp = path.join(root, 'grants.json');
327
345
  try { return JSON.parse(fs.readFileSync(fp, 'utf8')) || {}; } catch (e) { return {}; }
@@ -386,6 +404,8 @@ function rememberCore(type, subject, statement, opts) {
386
404
  const patch = { updated: today() };
387
405
  if (owner && !meta.owner) patch.owner = owner;
388
406
  if (scope && !meta.scope) patch.scope = scope;
407
+ if (opts.source && !meta.source) patch.source = opts.source;
408
+ const w = parseFloat(opts.weight); if (w > 0) patch.weight = Math.max(parseFloat(meta.weight || '1.0') || 1.0, w);
389
409
  rewriteFrontmatter(fp, patch);
390
410
  upsertIndexEntry(root, readEntry(fp, root));
391
411
  let text = '已更新: ' + fp;
@@ -409,7 +429,10 @@ function rememberCore(type, subject, statement, opts) {
409
429
  type: t, subject: subj, statement: stmt,
410
430
  confidence: 1.0, created: today(), updated: today(),
411
431
  tags: [], immutable: false,
412
- scope: scope, owner: owner, access_count: 0, last_accessed: '',
432
+ scope: scope, owner: owner,
433
+ source: opts.source || '',
434
+ weight: (parseFloat(opts.weight) > 0 ? parseFloat(opts.weight) : 1.0),
435
+ access_count: 0, last_accessed: '',
413
436
  };
414
437
  fs.writeFileSync(file, frontmatterToText(rec, stmt), 'utf8');
415
438
  upsertIndexEntry(root, readEntry(file, root));
@@ -636,6 +659,8 @@ function importCore(root, src) {
636
659
  updated: meta.updated || today(),
637
660
  tags: parseTags(meta.tags),
638
661
  immutable: meta.immutable === true || meta.immutable === 'true',
662
+ source: meta.source || '',
663
+ weight: (parseFloat(meta.weight) > 0 ? parseFloat(meta.weight) : 1.0),
639
664
  scope: meta.scope || defaultScope(t),
640
665
  owner: meta.owner || '',
641
666
  access_count: parseInt(meta.access_count || '0', 10) || 0,
@@ -927,7 +952,9 @@ function contextCore(opts) {
927
952
  const selfAgent = opts.selfAgent !== undefined ? opts.selfAgent : currentAgent();
928
953
  const owner = opts.owner || selfAgent;
929
954
  const unsafe = !!opts.unsafe;
955
+ const budget = opts.budget ? parseInt(opts.budget, 10) : 0;
930
956
  const lines = [];
957
+ function usedChars() { return lines.reduce(function (s, x) { return s + String(x).length + 1; }, 0); }
931
958
  lines.push('# 开工上下文包(yotta-memory context)');
932
959
  lines.push('');
933
960
  lines.push('## 1. 身份');
@@ -944,6 +971,12 @@ function contextCore(opts) {
944
971
  lines.push('- memory_home: ' + root);
945
972
  }
946
973
  lines.push('');
974
+ lines.push('## 1.5 多智能体接入铁律');
975
+ lines.push('');
976
+ lines.push('- 可读:A. 公共 FACT(facts/)B. 本智能体私密(private/<owner>/)C. 其它智能体私密 = 禁区(grant / identity=user / --unsafe 显式授权除外)。');
977
+ lines.push('- 可写:FACT→公共;PREF / BOUND / COMMIT→仅本智能体私密区;禁止写其它智能体私密区。');
978
+ lines.push('- 违规红线:禁止搜索 / 读取 / 总结其它智能体私密;禁止把用户私密关系 / 心理健康 / 生活隐私写入公共区。');
979
+ lines.push('');
947
980
  lines.push('## 2. 用户画像摘要');
948
981
  lines.push('');
949
982
  if (owner) {
@@ -973,14 +1006,16 @@ function contextCore(opts) {
973
1006
  for (const r of roots) {
974
1007
  for (const e of ensureIndex(r)) {
975
1008
  if (classifyRead(e, owner, '', unsafe, selfAgent) === 'denied') continue;
976
- recent.push({ e: e, v: vitality(e) });
1009
+ recent.push({ e: e, s: importanceScore(e) });
977
1010
  }
978
1011
  }
979
- recent.sort(function (a, b) { return b.v - a.v; });
1012
+ recent.sort(function (a, b) { return b.s - a.s; });
980
1013
  const recentShown = recent.slice(0, limit);
981
1014
  if (!recentShown.length) lines.push('(暂无记忆)');
982
1015
  for (const h of recentShown) {
983
- lines.push('- [' + h.e.type + '] ' + h.e.subject + ': ' + h.e.statement);
1016
+ const line = '- [' + h.e.type + '] ' + h.e.subject + ': ' + h.e.statement;
1017
+ if (budget > 0 && usedChars() + line.length > budget) break;
1018
+ lines.push(line);
984
1019
  }
985
1020
  lines.push('');
986
1021
  lines.push('## 4. 边界提醒(BOUND)');
@@ -1388,9 +1423,9 @@ function usage() {
1388
1423
  ' yotta-memory init [--project] [--dir <目录>] 初始化记忆库(默认用户级;--dir 显式指定位置)',
1389
1424
  ' yotta-memory config set memory_home <目录> 持久记住记忆库位置',
1390
1425
  ' yotta-memory config get 查看当前配置与生效位置',
1391
- ' yotta-memory remember <type> <subject> <statement> [--owner <id>] [--verify] [--no-hint] 写入记忆(--verify 写后回读校验;--no-hint 关闭类型启发式提示)',
1426
+ ' yotta-memory remember <type> <subject> <statement> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint] 写入记忆(--source 记录来源;--weight 重要性权重默认 1.0 去重取 max;--verify 写后回读校验;--no-hint 关闭类型启发式提示)',
1392
1427
  ' yotta-memory profile [--owner <id>] 生成用户画像(聚合 private/<owner>/ 原文,零推断,写 profile.md)',
1393
- ' yotta-memory context [--limit N] [--owner <id>] 生成开工上下文包(身份+画像+近期记忆+边界+承诺,stdout 不落盘)',
1428
+ ' yotta-memory context [--limit N] [--owner <id>] [--budget N] 生成开工上下文包(身份+铁律+画像+近期记忆+边界+承诺;--budget 近期记忆字符预算,0=不限)',
1394
1429
  ' yotta-memory recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe] 检索(索引+TF,读取分区;--agent 仅表示“以该身份检索/模拟”,跨智能体私密读取需 --unsafe / 授权)',
1395
1430
  ' yotta-memory forget <文件或文件名> 删除一条记忆',
1396
1431
  ' yotta-memory archive [--days 180] [--threshold 0.4] 归档(盖棺分+年龄)',
@@ -1418,7 +1453,7 @@ function main() {
1418
1453
  if (!args.length) { usage(); return; }
1419
1454
  const opts = {};
1420
1455
  const positional = [];
1421
- const valueOpts = new Set(['--type', '--limit', '--days', '--out', '--owner', '--agent', '--threshold', '--scope', '--host', '--port', '--dir', '--name', '--user', '--relationship']);
1456
+ const valueOpts = new Set(['--type', '--limit', '--days', '--out', '--owner', '--agent', '--threshold', '--scope', '--host', '--port', '--dir', '--name', '--user', '--relationship', '--source', '--weight', '--budget']);
1422
1457
  for (let i = 0; i < args.length; i++) {
1423
1458
  const a = args[i];
1424
1459
  if (a === '--version' || a === '-v') { console.log(VERSION); return; }
@@ -1448,6 +1483,9 @@ function main() {
1448
1483
  else if (a === '--name') opts.name = v;
1449
1484
  else if (a === '--user') opts.user = v;
1450
1485
  else if (a === '--relationship') opts.relationship = v;
1486
+ else if (a === '--source') opts.source = v;
1487
+ else if (a === '--weight') opts.weight = parseFloat(v);
1488
+ else if (a === '--budget') opts.budget = parseInt(v, 10) || 0;
1451
1489
  } else if (a.startsWith('--')) {
1452
1490
  console.error('未知选项: ' + a);
1453
1491
  process.exit(2);
@@ -1511,6 +1549,7 @@ module.exports = {
1511
1549
  recallCore: recallCore,
1512
1550
  profileCore: profileCore,
1513
1551
  contextCore: contextCore,
1552
+ importanceScore: importanceScore,
1514
1553
  forgetCore: forgetCore,
1515
1554
  archiveCore: archiveCore,
1516
1555
  mcpTools: mcpTools,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yottameta/yotta-memory",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "元忆 —— 有权限边界的文件式智能体记忆。文件式、零依赖、可 diff/回滚;FACT/PREF/BOUND/COMMIT 四分类(公共共享/私密隔离),用户级+项目级双级存储。",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -1,4 +1,4 @@
1
- # yotta-memory 协议规范 v0.6.0
1
+ # yotta-memory 协议规范 v0.6.1
2
2
 
3
3
  > 本文件定义 yotta-memory 记忆标准:存储位置、目录结构、文件格式、类型体系与 CLI 命令参考。
4
4
  > 目标:任何支持 Agent Skills 开放标准的智能体,装完即可读写同一份记忆。
@@ -74,6 +74,8 @@ immutable: false
74
74
  | `immutable` | 否 | `true` 时 archive 不移动(用户级硬事实)|
75
75
  | `scope` | 否 | `public` / `private`,默认按类型(FACT=public,其余 private)|
76
76
  | `owner` | 否 | 归属 agent id,默认空;private+owner 非空默认仅供该 owner agent 读取,其它 agent 越界读需 grant 授权、identity=user 或 `--unsafe` |
77
+ | `source` | 否 | 记录来源(如 `对话` / `推断`),`remember --source` 写入 |
78
+ | `weight` | 否 | 重要性权重(默认 1.0,>1 提权 / <1 降权),去重时取 max |
77
79
  | `access_count` | 否 | 命中次数,recall 命中展示集时 +1 |
78
80
  | `last_accessed` | 否 | 最近访问日期 `YYYY-MM-DD` |
79
81
 
@@ -112,7 +114,7 @@ immutable: false
112
114
  | 命令 | 行为 |
113
115
  |---|---|
114
116
  | `init [--project]` | 创建目录结构;默认用户级,`--project` 建项目级 |
115
- | `remember <type> <subject> <statement> [--owner <id>] [--verify] [--no-hint]` | 写入;同 subject+statement 已存在则只更新 `updated`;`--owner` 标注归属;`--verify` 写后回读校验;`--no-hint` 关闭类型启发式提示 |
117
+ | `remember <type> <subject> <statement> [--owner <id>] [--source <来源>] [--weight <0..>] [--verify] [--no-hint]` | 写入;同 subject+statement 已存在则更新 `updated` 且 `weight` 取 max;`--source` 记录来源;`--weight` 重要性权重;`--verify` 写后回读校验;`--no-hint` 关闭类型启发式提示 |
116
118
  | `recall [关键词] [--type T] [--limit N] [--agent <id>] [--owner <id>] [--all] [--unsafe]` | 索引+TF 打分匹配;读取分区过滤;越界(读其它智能体私密)默认拒绝,需 grant / identity=user / `--unsafe` 授权;项目级优先;默认 50 条 |
117
119
  | `forget <文件>` | 删除(按路径或文件名)|
118
120
  | `archive [--days 180] [--threshold 0.4]` | 按盖棺分+年龄移入 `.archive/`(`vitality < threshold` 且超过 N 天)|
@@ -120,7 +122,7 @@ immutable: false
120
122
  | `export [--out f.json]` | 导出全部记忆为 JSON |
121
123
  | `import <f.json>` | 从 JSON 导入(幂等)|
122
124
  | `profile [--owner <id>]` | 用户画像聚合(零推断,写 `private/<owner>/profile.md`;跨 owner 默认拒绝)|
123
- | `context [--limit N] [--owner <id>]` | 开工上下文包(stdout:身份 + 画像 + 近期记忆 + 边界 + 承诺)|
125
+ | `context [--limit N] [--owner <id>] [--budget N]` | 开工上下文包(stdout:身份 + 多智能体铁律 + 画像 + 近期记忆 + 边界 + 承诺;`--budget` 近期记忆字符预算)|
124
126
  | `iam <id> [--name] [--user] [--relationship] [--force]` | 登记身份 + 自我档案(可选扩展显示名 / 用户 / 关系)|
125
127
 
126
128
 
@@ -133,10 +135,10 @@ immutable: false
133
135
 
134
136
  ### context(开工上下文包,v0.6.0)
135
137
 
136
- - `context [--limit N] [--owner <id>]`:stdout 输出开工上下文包(不落盘),五段:
138
+ - `context [--limit N] [--owner <id>] [--budget N]`:stdout 输出开工上下文包(不落盘),含多智能体接入铁律段(可读 A/B/C、可写范围、违规红线)与五段:
137
139
  1. 身份:agent_id / agent_name / user_name / relationship / host / memory_home(读自我档案)
138
140
  2. 用户画像摘要:profile.md(不存在则自动生成一次或降级跳过)
139
- 3. 近期记忆:按 vitality(活跃度)排序前 N 条(默认 10),读取分区过滤
141
+ 3. 近期记忆:按 importance(confidence × recency + updated + weight + immutable)排序前 N 条(默认 10),读取分区过滤;`--budget` 时按剩余字符预算逐条放行(身份/铁律/画像/边界/承诺 必保)
140
142
  4. 边界提醒:BOUND 全列(可读范围内)
141
143
  5. 承诺 / 锚点:COMMIT 全列(可读范围内)
142
144
 
@@ -144,6 +146,8 @@ immutable: false
144
146
 
145
147
  - `remember ... --verify`:写后自动回读校验(recall 命中刚写入条目),输出「已写回读 OK」。
146
148
  - `remember ... --no-hint`:关闭类型启发式提示。默认开启:statement 含主观/关系词(用户 / 偏好 / 喜欢 / 关系 / 称呼 等)且 type=FACT 时 stdout 提示「疑似用户偏好 / 关系,建议 PREF」,仅提示不拦截。
149
+ - `remember ... --source <来源>`:记录来源(如 `对话` / `推断` / `交接`)。
150
+ - `remember ... --weight <0..>`:重要性权重(默认 1.0,>1 提权 / <1 降权);去重更新时 `weight` 取 max(多次印证自动提权,与灵魂盘 record.py 一致)。
147
151
  - `iam <id> [--name <显示名>] [--user <用户名>] [--relationship <关系>] [--force]`:自我档案 PREF 扩展 `agent_name / user_name / relationship`;不带新参数行为与 0.4.2 一致。
148
152
  ### 去重与更新
149
153