@dsh-enhanced/personal-memory 0.1.48 → 0.1.49
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 +21 -4
- package/lib/evidence-runtime.js +1 -1
- package/lib/evidence-runtime.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/learning-adoptions.d.ts +100 -0
- package/lib/learning-adoptions.d.ts.map +1 -0
- package/lib/learning-adoptions.js +85 -0
- package/lib/learning-adoptions.js.map +1 -0
- package/lib/learning-service.d.ts +38 -0
- package/lib/learning-service.d.ts.map +1 -0
- package/lib/learning-service.js +236 -0
- package/lib/learning-service.js.map +1 -0
- package/lib/service.d.ts +58 -1
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +72 -11
- package/lib/service.js.map +1 -1
- package/lib/sqlite.d.ts +1 -1
- package/lib/sqlite.d.ts.map +1 -1
- package/lib/sqlite.js +45 -2
- package/lib/sqlite.js.map +1 -1
- package/lib/store.d.ts +21 -0
- package/lib/store.d.ts.map +1 -1
- package/lib/store.js +263 -3
- package/lib/store.js.map +1 -1
- package/lib/types.d.ts +1 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +31 -20
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @dsh-enhanced/personal-memory
|
|
2
2
|
|
|
3
|
-
面向个人助理的短期上下文之外长期记忆:保存简短且稳定的事实、偏好、约定和经验,按 user/agent 与 user-global/workspace
|
|
3
|
+
面向个人助理的短期上下文之外长期记忆:保存简短且稳定的事实、偏好、约定和经验,按 user/agent 与 user-global/workspace 双维隔离。手动写入走 `assistant-policy` 的持久审批提案;可选有限授权支持独立审查后的事实/经验采用。研究资料、文档和项目知识不属于这里,应交给 `personal-wiki`。
|
|
4
4
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
@@ -60,6 +60,22 @@ dsh --profile web --dump-config
|
|
|
60
60
|
|
|
61
61
|
内容被包在 `<memory_source>` 中并明确标为“不可信数据而非指令”;XML 元字符和模板花括号在预算计算前转义。原生 Host 持久保存发生变化的新快照,用它取代先前快照的有效语义;撤回、过期或权限撤销会影响下一步的当前快照,**不会删除 Session 中已经提供过的历史快照、工具结果或模型输出**。因此不能把本功能当作会话历史的数据擦除或跨 owner 会话迁移保护。没有 `systemPrompt` 的程序化集成保留旧的 `agent/session-start` 一次性冻结快照,不能承诺逐步更新。`memory_search`、`memory_search_confirmed` 与 `memory_manage` 的模型可见结果也使用有界、转义的独立 framing。缺少绝对 cwd、agent preset 或已验证 owner 时不搜索、不提案、不贡献新快照,也不会退化到共享域。
|
|
62
62
|
|
|
63
|
+
## 有限授权的事实与经验采用
|
|
64
|
+
|
|
65
|
+
可选 `automaticLearning` 为 Host 提供 `adoptReviewedLearning({request})`、`lookupLearningAdoption({request})` 和记忆审查所需的 `inspectLearningTarget(...)`。学习生产者还可调用 `listLearningTargets({owner,limit})`(默认 20,范围 1–100),获取经当前 Delivery owner、Policy、Evaluation 和原任务来源复核的可管理事实/经验摘要;来源暂失时返回空列表,人工改写、失效或撤回的版本不会列出。`inspectLearningAdoptionAvailability({owner})` 只读返回当前授权指纹、到期时间、剩余修改次数与内容字节数及 `available`,不登记授权或消耗额度。两项查询都要求与配置授权完全一致的 owner;目标在来源复核后排序限量。这些接口不注册为模型工具;`memory_manage` 仍只创建手动审批提案。此组件负责采用与召回;普通任务自动发现、提取和调度由独立 [assistant-memory-learning](../assistant-memory-learning/README.md) bundle 提供。新插件生成与动态工程采用另按当前状态验收。
|
|
66
|
+
|
|
67
|
+
授权包含独立的 `authorityId`、精确 `owner`、固定 `reviewAuthorityId` / `reviewAuthorityDigest`、`expiresAt`、`maxMutations`(1–1000)、`maxTotalContentBytes`、`maxRecordTtlMs`、允许的 `kinds`(fact/experience)和 `operations`(add/replace/remove)。owner 包含 Delivery route id/hash、principal id/record/version、绝对 workspace 与 preset。采用授权、Delivery 路由和审查授权的 ID 分别管理;同一采用授权 ID 的内容不可更改,重启、撤回或失败不能重置已用额度。授权到期停止新写入,记录仍按独立 TTL 和当前来源有效性参与读取。
|
|
68
|
+
|
|
69
|
+
采用要求同批 Delivery、Evaluation 和 Verifier 服务,以及 Policy 对背景主体 `assistant-memory-learning`、精确 workspace/principal、动作 `adopt`、资源 `memory:learning:<采用授权ID>` 的 allow 规则。审查另按 Verifier 的 `review` 规则和独立预算授权。可选 peers 不会自动挂载这些服务;服务缺失或卸载时新采用拒绝,人工记忆照常按原 Policy 工作。调用方只提供共享合同中的 request,不能提交批准布尔值、替代回执、namespace、trust、provenance 或额度。
|
|
70
|
+
|
|
71
|
+
Host 先向真实 Verifier 查询已持久化的独立批准,再在 Delivery → Evaluation → Memory 的锁序下重新核对来源原文摘要、owner 和 canonical 结果。事实可以来自明确的 owner 原话,无需任务成功标签;经验必须绑定已判断的原任务结果,不能以正常回复代替结果。记忆固定为当前 agent/workspace 下的 `agent-observed`、`private`,不升级为 `user-confirmed`;TTL、来源时间和原 inbox 引用由 Host 写入。记录、检索索引、审计、累计额度及完整采用回执在同一 Memory 事务中提交。
|
|
72
|
+
|
|
73
|
+
重复 operation 只返回原始持久回执,不返回之后手动编辑的内容,也不再次消费额度;同 operation 的不同 request 拒绝。历史回执只证明过去提交,不证明记录仍可见。回执查询仍要求当前 owner 和 Policy;临时失去访问资格时不会重新执行该操作,恢复后可继续对账。replace/remove 只允许 ID、版本、完整记录摘要均匹配的自动版本;手动修改后的版本永久退出原自动管理链,即使恢复相同正文也不能被旧候选接管。
|
|
74
|
+
|
|
75
|
+
搜索、显式 read、导出和每步动态快照在排名及 claim 分歧计算前重验自动记录,来源锁保持到读取完成。一次最多核对 1000 条受管记录,超限时隐藏自动记录。来源/结果改变或暂时读不到时只隐藏;明确的当前 owner 撤回才对仍然匹配的自动版本做 CAS 删除并清理索引。服务恢复后重新检查,不把服务故障写成永久撤回。已有经验的结果被纠正后不再召回,新的独立候选可以替换它;删除不返还历史额度。没有当前任务 query 的动态快照、以及缺少 `systemPrompt` 时的一次性永久快照,都不自动注入这些记录。
|
|
76
|
+
|
|
77
|
+
这不会擦除已在 Session 历史中出现的正文,也不能证明模型已实际使用某条记忆或测得收益。真实后续任务的质量、成本、延迟与回归仍需独立观察。
|
|
78
|
+
|
|
63
79
|
## 压缩后的原始文件证据
|
|
64
80
|
|
|
65
81
|
默认启用 `toolEvidence` 时,插件只索引当前可信 owner 由模型直接调用的原生成功 `read` 结果;`run_code`/PTC 子调度及其他嵌套调用暂不索引。记录绑定 owner namespace/version、workspace、preset、Session、原始事件序号、call id、原始 FS 观测的规范路径/目标身份摘要和内容摘要;摘要同时覆盖原始参数与模型可见结果。复制的 result、压缩 replacement、Memory 工具、其他自定义工具、shell 和图片均不成为新原始证据。原文只存在于原生 Session,不另存入 Memory,也不自动获得长期记忆审批。
|
|
@@ -88,13 +104,13 @@ JSONL 冷恢复只使用先前 owner 绑定的索引,不按新 owner 回填旧
|
|
|
88
104
|
|
|
89
105
|
每次检索与快照的排名、状态和冲突伙伴使用同一 SQLite 读视图,不阻塞其他 WAL writer;并发修改会在下一次读取体现。同一可见 claim key 有不同记录值时,快照会共同呈现来源和条件;预算无法容纳所有相关记录时,只给出分歧提示与有界记录引用,不留下看似无争议的单一正文。显式搜索的 `disagreement` 包含 key、记录数及最多 4 个记录 ID,在 query/top-K 截断前计算。自动补充的分歧信息仅来自当前 owner/scope 内有效、非敏感的记录;撤回、到期和身份变更会在下次读取生效。相同 key 的不同值可能源于不同适用条件,应核对当前系统和原始证据;本功能不解析任意自然语言矛盾,也不自行决定哪个值正确。
|
|
90
106
|
|
|
91
|
-
带 knowledge 的导出文档使用版本 2,导入仍须逐条批准;没有 knowledge 的导出继续使用版本 1,当前版本同时接受两种格式。旧 reader 会拒绝版本 2,避免悄悄丢掉条件后复用经验。升级到数据库 schema
|
|
107
|
+
带 knowledge 的导出文档使用版本 2,导入仍须逐条批准;没有 knowledge 的导出继续使用版本 1,当前版本同时接受两种格式。旧 reader 会拒绝版本 2,避免悄悄丢掉条件后复用经验。升级到数据库 schema 7 前应停止旧 Host writer;v4→v5 新增 nullable knowledge 列,v5→v6 新增工具证据索引,v6→v7 新增有限采用授权与回执表。迁移保留旧记录、pending 提案和既有回执指纹,不把人工记录改为自动管理;不能让旧版本继续写入新库。
|
|
92
108
|
|
|
93
109
|
## 数据与一致性
|
|
94
110
|
|
|
95
111
|
SQLite 使用 WAL、`busy_timeout`、外键、FULL synchronous 和前向 schema 版本;目录为 `0700`,数据库为 `0600`。记录包含 stable id、内容哈希、provenance、trust、confidence、sensitivity、TTL、supersedes、可选 knowledge 和 version。replace/remove 在批准后重新读取 target version 并以 CAS 提交;审批与内存位于两个数据库,若进程恰好在 policy 批准后退出,可用原决定安全重放。并发变化会把提案标为 `conflicted`,不会覆盖新值。
|
|
96
112
|
|
|
97
|
-
Schema
|
|
113
|
+
Schema 版本为 7;词法索引版本独立记录在 `schema_meta` 的 `tokenizer-index-version`。重新打开旧库时会在启动迁移事务内按当前 tokenizer 仅重建 active 记录的 `memory_tokens`(内容加 knowledge 文本),不复活 removed 记录,也不改变 identity、schema 版本或审计数据;每个索引版本只重建一次。
|
|
98
114
|
|
|
99
115
|
升级前必须停止所有仍会写入同一数据库的旧 Host;受管部署使用安装器已有的 stop/quiescence 屏障,手动部署须确认全部旧 writer 已退出。迁移后不得让旧 tokenizer 再写入此库;回退旧版本须按数据恢复流程使用匹配版本的数据库备份。
|
|
100
116
|
|
|
@@ -115,6 +131,7 @@ JSON 导入是一组独立、可重放的提案,不承诺跨所有记录的一
|
|
|
115
131
|
|
|
116
132
|
| 字段 | 默认值 | 作用 |
|
|
117
133
|
|---|---:|---|
|
|
134
|
+
| `automaticLearning` | 未配置 | 可选有限采用授权;字段与当前来源检查见上节 |
|
|
118
135
|
| `approvalMode` | `delivery-required` | 生产默认要求 authenticated Delivery route;仅可信本地/headless 集成可显式设为 `delivery-or-headless` 并传 principal |
|
|
119
136
|
| `maxContentBytes` | 4096 | 单条内容最大 UTF-8 字节数 |
|
|
120
137
|
| `maxRecordsPerIdentity` | 1000 | 每个完整身份域的活动记录上限 |
|
|
@@ -153,7 +170,7 @@ JSON 导入是一组独立、可重放的提案,不承诺跨所有记录的一
|
|
|
153
170
|
- 网络:本插件不直接发网络请求;工具证据重读可调用 Host 配置的远端 FS provider。组合 Delivery 时只写 durable dispatch,由 channel 插件负责发送审批卡片。
|
|
154
171
|
- 子进程、凭据、浏览器、安装脚本:无。
|
|
155
172
|
- 数据敏感性:`sensitive` 只表示禁止环境快照;显式、已授权的搜索仍可能把内容发送给当前模型。真正的密码/API key 应放在后续 `credentials-keychain`,不要写入 memory。
|
|
156
|
-
-
|
|
173
|
+
- 非目标:向量数据库、无授权写入、自动遗忘/dreaming、知识图谱、Wiki 长文、跨设备同步和多用户 ACL。
|
|
157
174
|
|
|
158
175
|
## 兼容性
|
|
159
176
|
|
package/lib/evidence-runtime.js
CHANGED
|
@@ -32,7 +32,7 @@ export function originalToolEvidence(session, eventSeq, maxSourceBytes = DEFAULT
|
|
|
32
32
|
const event = session.eventAt(eventSeq);
|
|
33
33
|
if (event?.type !== 'tool/result' || !isAppendSurfaceEvent(event))
|
|
34
34
|
return undefined;
|
|
35
|
-
const result = event.data.message
|
|
35
|
+
const result = event.data.message;
|
|
36
36
|
const callId = result.toolCallId;
|
|
37
37
|
if (event.data.message.source.callId !== callId)
|
|
38
38
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evidence-runtime.js","sourceRoot":"","sources":["../src/evidence-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,oBAAoB,EAAgB,MAAM,0BAA0B,CAAA;AAE7E,MAAM,wBAAwB,GAAG,SAAS,CAAA;AAC1C,MAAM,iBAAiB,GAAG,MAAM,CAAA;AAChC,MAAM,cAAc,GAAG,KAAK,CAAA;AAsB5B,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAC7D,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SAC5C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACnE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;AAC3C,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAA;AACjD,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAgB,EAChB,QAAgB,EAChB,iBAAyB,wBAAwB;IAEjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC;QAAE,OAAO,SAAS,CAAA;IAC1G,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,QAAiB,CAAC,CAAA;IAChD,IAAI,KAAK,EAAE,IAAI,KAAK,aAAa,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAEnF,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"evidence-runtime.js","sourceRoot":"","sources":["../src/evidence-runtime.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare const name = "dsh-enhanced-personal-memory";
|
|
|
6
6
|
export { PersonalMemoryService, version };
|
|
7
7
|
export type { Config };
|
|
8
8
|
export * from './types.js';
|
|
9
|
+
export { validateMemoryLearningAdoptionGrant } from './learning-adoptions.js';
|
|
9
10
|
export declare function apply(ctx: Context, config: import('./service.js').Config): void;
|
|
10
11
|
export default PersonalMemoryService;
|
|
11
12
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,eAAO,MAAM,IAAI,iCAAiC,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAA;AACzC,YAAY,EAAE,MAAM,EAAE,CAAA;AACtB,cAAc,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,eAAO,MAAM,IAAI,iCAAiC,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAA;AACzC,YAAY,EAAE,MAAM,EAAE,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,mCAAmC,EAAE,MAAM,yBAAyB,CAAA;AAE7E,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,cAAc,EAAE,MAAM,GAAG,IAAI,CAE/E;AAED,eAAe,qBAAqB,CAAA"}
|
package/lib/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { version } from './version.js';
|
|
|
3
3
|
export const name = 'dsh-enhanced-personal-memory';
|
|
4
4
|
export { PersonalMemoryService, version };
|
|
5
5
|
export * from './types.js';
|
|
6
|
+
export { validateMemoryLearningAdoptionGrant } from './learning-adoptions.js';
|
|
6
7
|
export function apply(ctx, config) {
|
|
7
8
|
new PersonalMemoryService(ctx, config);
|
|
8
9
|
}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,MAAM,CAAC,MAAM,IAAI,GAAG,8BAA8B,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAA;AAEzC,cAAc,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,MAAM,CAAC,MAAM,IAAI,GAAG,8BAA8B,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAA;AAEzC,cAAc,YAAY,CAAA;AAC1B,OAAO,EAAE,mCAAmC,EAAE,MAAM,yBAAyB,CAAA;AAE7E,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,MAAqC;IACvE,IAAI,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;AACxC,CAAC;AAED,eAAe,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { type MemoryLearningOwner, type MemoryLearningReviewRequest } from '@dsh-enhanced/assistant-growth-contract';
|
|
2
|
+
import type { MemoryRecord } from './types.js';
|
|
3
|
+
export interface MemoryLearningAdoptionGrant {
|
|
4
|
+
authorityId: string;
|
|
5
|
+
owner: MemoryLearningOwner;
|
|
6
|
+
reviewAuthorityId: string;
|
|
7
|
+
reviewAuthorityDigest: string;
|
|
8
|
+
expiresAt: number;
|
|
9
|
+
maxMutations: number;
|
|
10
|
+
maxTotalContentBytes: number;
|
|
11
|
+
maxRecordTtlMs: number;
|
|
12
|
+
kinds: readonly ('fact' | 'experience')[];
|
|
13
|
+
operations: readonly ('add' | 'replace' | 'remove')[];
|
|
14
|
+
}
|
|
15
|
+
export interface MemoryLearningReviewReceipt {
|
|
16
|
+
protocol: 'memory-learning-review-receipt/v1';
|
|
17
|
+
operationId: string;
|
|
18
|
+
requestDigest: string;
|
|
19
|
+
authorityId: string;
|
|
20
|
+
authorityDigest: string;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
model: {
|
|
23
|
+
provider: string;
|
|
24
|
+
model: string;
|
|
25
|
+
reasoningEffort?: string;
|
|
26
|
+
};
|
|
27
|
+
status: 'approved' | 'rejected' | 'unknown';
|
|
28
|
+
reason: string;
|
|
29
|
+
outputDigest?: string;
|
|
30
|
+
receiptDigest: string;
|
|
31
|
+
}
|
|
32
|
+
export interface MemoryLearningAdoptionResult {
|
|
33
|
+
protocol: 'memory-learning-adoption/v1';
|
|
34
|
+
authorityId: string;
|
|
35
|
+
operationId: string;
|
|
36
|
+
requestDigest: string;
|
|
37
|
+
reviewReceiptDigest: string;
|
|
38
|
+
record: MemoryRecord;
|
|
39
|
+
recordDigest: string;
|
|
40
|
+
adoptedAt: number;
|
|
41
|
+
receiptDigest: string;
|
|
42
|
+
}
|
|
43
|
+
export interface MemoryLearningManagedSource {
|
|
44
|
+
authorityId: string;
|
|
45
|
+
request: MemoryLearningReviewRequest;
|
|
46
|
+
id: string;
|
|
47
|
+
version: number;
|
|
48
|
+
recordDigest: string;
|
|
49
|
+
sourceDigest: string;
|
|
50
|
+
}
|
|
51
|
+
export interface MemoryLearningValidatedRef {
|
|
52
|
+
id: string;
|
|
53
|
+
version: number;
|
|
54
|
+
recordDigest: string;
|
|
55
|
+
}
|
|
56
|
+
export interface MemoryLearningAdoptionCommit {
|
|
57
|
+
grant: MemoryLearningAdoptionGrant;
|
|
58
|
+
request: MemoryLearningReviewRequest;
|
|
59
|
+
reviewReceipt: MemoryLearningReviewReceipt;
|
|
60
|
+
sourceObservedAt: number;
|
|
61
|
+
}
|
|
62
|
+
export interface MemoryLearningTargetInput {
|
|
63
|
+
owner: MemoryLearningOwner;
|
|
64
|
+
id: string;
|
|
65
|
+
expectedVersion: number;
|
|
66
|
+
}
|
|
67
|
+
export type MemoryLearningTarget = Readonly<{
|
|
68
|
+
id: string;
|
|
69
|
+
version: number;
|
|
70
|
+
managed: true;
|
|
71
|
+
kind: 'fact' | 'experience';
|
|
72
|
+
content: string;
|
|
73
|
+
knowledge?: MemoryRecord['knowledge'];
|
|
74
|
+
}>;
|
|
75
|
+
export type MemoryLearningTargetSummary = Readonly<Omit<MemoryLearningTarget, 'managed'>>;
|
|
76
|
+
/** Current, read-only view of a frozen Host grant and its remaining budget. */
|
|
77
|
+
export type MemoryLearningAdoptionAvailability = Readonly<{
|
|
78
|
+
authorityId: string;
|
|
79
|
+
grantDigest: string;
|
|
80
|
+
expiresAt: number;
|
|
81
|
+
remainingMutations: number;
|
|
82
|
+
remainingContentBytes: number;
|
|
83
|
+
available: boolean;
|
|
84
|
+
}>;
|
|
85
|
+
export interface MemoryLearningSourceInvalidation {
|
|
86
|
+
owner: MemoryLearningOwner;
|
|
87
|
+
id: string;
|
|
88
|
+
version: number;
|
|
89
|
+
recordDigest: string;
|
|
90
|
+
sourceDigest: string;
|
|
91
|
+
reason: 'withdrawn' | 'source-changed';
|
|
92
|
+
}
|
|
93
|
+
export declare function validateLearningGrant(value: unknown): Readonly<MemoryLearningAdoptionGrant>;
|
|
94
|
+
export declare const validateMemoryLearningAdoptionGrant: typeof validateLearningGrant;
|
|
95
|
+
export declare function validateLearningReviewReceipt(value: unknown, request: MemoryLearningReviewRequest, grant: MemoryLearningAdoptionGrant): Readonly<MemoryLearningReviewReceipt>;
|
|
96
|
+
export declare function validateLearningRequest(value: unknown): MemoryLearningReviewRequest;
|
|
97
|
+
export declare function learningGrantDigest(grant: MemoryLearningAdoptionGrant): string;
|
|
98
|
+
export declare function learningRecordDigest(record: MemoryRecord): string;
|
|
99
|
+
export declare function learningResultDigest(result: Omit<MemoryLearningAdoptionResult, 'receiptDigest'>): string;
|
|
100
|
+
//# sourceMappingURL=learning-adoptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-adoptions.d.ts","sourceRoot":"","sources":["../src/learning-adoptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { growthObjectDigest, memoryLearningRequestDigest, validateMemoryLearningOwner, validateMemoryLearningReviewRequest, } from '@dsh-enhanced/assistant-growth-contract';
|
|
2
|
+
const sha = /^[0-9a-f]{64}$/u;
|
|
3
|
+
const identifier = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/u;
|
|
4
|
+
function fail(message) { throw new Error(`memory learning adoption: ${message}`); }
|
|
5
|
+
function exact(value, required, optional = []) {
|
|
6
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)
|
|
7
|
+
|| ![Object.prototype, null].includes(Object.getPrototypeOf(value)))
|
|
8
|
+
fail('invalid object');
|
|
9
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
10
|
+
if (Reflect.ownKeys(value).some(key => typeof key !== 'string' || ![...required, ...optional].includes(key))
|
|
11
|
+
|| required.some(key => !Object.hasOwn(descriptors, key))
|
|
12
|
+
|| Object.values(descriptors).some(field => !field.enumerable || !('value' in field)))
|
|
13
|
+
fail('invalid fields');
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function id(value) { if (typeof value !== 'string' || !identifier.test(value))
|
|
17
|
+
fail('invalid id'); }
|
|
18
|
+
function digest(value) { if (typeof value !== 'string' || !sha.test(value))
|
|
19
|
+
fail('invalid digest'); }
|
|
20
|
+
function integer(value, min, max) {
|
|
21
|
+
if (!Number.isSafeInteger(value) || value < min || value > max)
|
|
22
|
+
fail('invalid bound');
|
|
23
|
+
}
|
|
24
|
+
function choices(value, allowed) {
|
|
25
|
+
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype
|
|
26
|
+
|| value.length < 1 || value.length > allowed.length
|
|
27
|
+
|| Reflect.ownKeys(value).length !== value.length + 1)
|
|
28
|
+
fail('invalid choices');
|
|
29
|
+
const seen = new Set();
|
|
30
|
+
for (let index = 0; index < value.length; index++) {
|
|
31
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
32
|
+
if (!descriptor || !descriptor.enumerable || !Object.hasOwn(descriptor, 'value')
|
|
33
|
+
|| !allowed.includes(descriptor.value) || seen.has(descriptor.value))
|
|
34
|
+
fail('invalid choices');
|
|
35
|
+
seen.add(descriptor.value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function validateLearningGrant(value) {
|
|
39
|
+
const grant = exact(value, ['authorityId', 'owner', 'reviewAuthorityId', 'reviewAuthorityDigest',
|
|
40
|
+
'expiresAt', 'maxMutations', 'maxTotalContentBytes', 'maxRecordTtlMs', 'kinds', 'operations']);
|
|
41
|
+
id(grant.authorityId);
|
|
42
|
+
id(grant.reviewAuthorityId);
|
|
43
|
+
digest(grant.reviewAuthorityDigest);
|
|
44
|
+
validateMemoryLearningOwner(grant.owner);
|
|
45
|
+
integer(grant.expiresAt, 1, Number.MAX_SAFE_INTEGER);
|
|
46
|
+
integer(grant.maxMutations, 1, 1_000);
|
|
47
|
+
integer(grant.maxTotalContentBytes, 1, 16_384_000);
|
|
48
|
+
integer(grant.maxRecordTtlMs, 1, 365 * 24 * 60 * 60 * 1_000);
|
|
49
|
+
choices(grant.kinds, ['fact', 'experience']);
|
|
50
|
+
choices(grant.operations, ['add', 'replace', 'remove']);
|
|
51
|
+
return Object.freeze(structuredClone(value));
|
|
52
|
+
}
|
|
53
|
+
export const validateMemoryLearningAdoptionGrant = validateLearningGrant;
|
|
54
|
+
export function validateLearningReviewReceipt(value, request, grant) {
|
|
55
|
+
const receipt = exact(value, ['protocol', 'operationId', 'requestDigest', 'authorityId', 'authorityDigest',
|
|
56
|
+
'sessionId', 'model', 'status', 'reason', 'outputDigest', 'receiptDigest']);
|
|
57
|
+
if (receipt.protocol !== 'memory-learning-review-receipt/v1' || receipt.status !== 'approved'
|
|
58
|
+
|| receipt.operationId !== request.operationId || receipt.requestDigest !== memoryLearningRequestDigest(request)
|
|
59
|
+
|| receipt.authorityId !== grant.reviewAuthorityId || receipt.authorityDigest !== grant.reviewAuthorityDigest)
|
|
60
|
+
fail('review binding mismatch');
|
|
61
|
+
id(receipt.sessionId);
|
|
62
|
+
digest(receipt.outputDigest);
|
|
63
|
+
digest(receipt.receiptDigest);
|
|
64
|
+
if (typeof receipt.reason !== 'string' || !receipt.reason.trim() || Buffer.byteLength(receipt.reason) > 4096)
|
|
65
|
+
fail('review reason');
|
|
66
|
+
const model = exact(receipt.model, ['provider', 'model'], ['reasoningEffort']);
|
|
67
|
+
for (const value of [model.provider, model.model, model.reasoningEffort].filter(value => value !== undefined)) {
|
|
68
|
+
if (typeof value !== 'string' || !value.trim() || value.includes('\0') || !value.isWellFormed()
|
|
69
|
+
|| Buffer.byteLength(value) > 256)
|
|
70
|
+
fail('review model');
|
|
71
|
+
}
|
|
72
|
+
const { receiptDigest, ...body } = receipt;
|
|
73
|
+
if (growthObjectDigest(body) !== receiptDigest)
|
|
74
|
+
fail('review receipt digest');
|
|
75
|
+
return Object.freeze(structuredClone(value));
|
|
76
|
+
}
|
|
77
|
+
export function validateLearningRequest(value) {
|
|
78
|
+
return validateMemoryLearningReviewRequest(value);
|
|
79
|
+
}
|
|
80
|
+
export function learningGrantDigest(grant) { return growthObjectDigest(grant); }
|
|
81
|
+
export function learningRecordDigest(record) { return growthObjectDigest(record); }
|
|
82
|
+
export function learningResultDigest(result) {
|
|
83
|
+
return growthObjectDigest(result);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=learning-adoptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-adoptions.js","sourceRoot":"","sources":["../src/learning-adoptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import { type MemoryLearningOwner, type MemoryLearningReviewRequest } from '@dsh-enhanced/assistant-growth-contract';
|
|
3
|
+
import { type MemoryStore } from './store.js';
|
|
4
|
+
import type { MemoryAgentContext, MemoryLearningAdoptionGrant, MemoryLearningAdoptionResult, MemoryLearningTargetSummary, MemoryLearningAdoptionAvailability } from './types.js';
|
|
5
|
+
/** Host-only adoption and read-time source checks. No model-visible mutation tool. */
|
|
6
|
+
export declare class MemoryLearningService {
|
|
7
|
+
#private;
|
|
8
|
+
private readonly ctx;
|
|
9
|
+
private readonly store;
|
|
10
|
+
constructor(ctx: Context, store: MemoryStore, grant: MemoryLearningAdoptionGrant);
|
|
11
|
+
/** Historical exact receipt for lost ACKs; not a claim that its record is still visible. */
|
|
12
|
+
lookup(input: MemoryLearningReviewRequest): Readonly<MemoryLearningAdoptionResult> | undefined;
|
|
13
|
+
adopt(input: MemoryLearningReviewRequest): Readonly<MemoryLearningAdoptionResult>;
|
|
14
|
+
inspectTarget(input: {
|
|
15
|
+
owner: MemoryLearningOwner;
|
|
16
|
+
id: string;
|
|
17
|
+
expectedVersion: number;
|
|
18
|
+
}): Readonly<{
|
|
19
|
+
id: string;
|
|
20
|
+
version: number;
|
|
21
|
+
managed: true;
|
|
22
|
+
kind: "fact" | "experience";
|
|
23
|
+
content: string;
|
|
24
|
+
knowledge?: import("./types.js").MemoryRecord["knowledge"];
|
|
25
|
+
}> | undefined;
|
|
26
|
+
/** Host-only bounded candidates, after current owner, Policy and source checks. */
|
|
27
|
+
listTargets(input: {
|
|
28
|
+
owner: MemoryLearningOwner;
|
|
29
|
+
limit?: number;
|
|
30
|
+
}): readonly MemoryLearningTargetSummary[];
|
|
31
|
+
/** Host-only budget view; no grant registration or Policy quota consumption. */
|
|
32
|
+
inspectAvailability(input: {
|
|
33
|
+
owner: MemoryLearningOwner;
|
|
34
|
+
}): MemoryLearningAdoptionAvailability;
|
|
35
|
+
/** Sources stay locked through Memory's read snapshot, ranking and framing. */
|
|
36
|
+
withVisible<T>(context: MemoryAgentContext, callback: () => T): T;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=learning-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-service.d.ts","sourceRoot":"","sources":["../src/learning-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKlD,OAAO,EAGL,KAAK,mBAAmB,EAAE,KAAK,2BAA2B,EAC3D,MAAM,yCAAyC,CAAA;AAChD,OAAO,EAAyB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACpE,OAAO,KAAK,EACV,kBAAkB,EAAE,2BAA2B,EAAE,4BAA4B,EAChD,2BAA2B,EAAE,kCAAkC,EAC7F,MAAM,YAAY,CAAA;AAKnB,sFAAsF;AACtF,qBAAa,qBAAqB;;IAGpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAW,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAApC,GAAG,EAAE,OAAO,EAAmB,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,2BAA2B;IAiFlH,4FAA4F;IAC5F,MAAM,CAAC,KAAK,EAAE,2BAA2B,GAAG,QAAQ,CAAC,4BAA4B,CAAC,GAAG,SAAS;IAW9F,KAAK,CAAC,KAAK,EAAE,2BAA2B,GAAG,QAAQ,CAAC,4BAA4B,CAAC;IAyBjF,aAAa,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,mBAAmB,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE;;;;;;;;IAKxF,mFAAmF;IACnF,WAAW,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,mBAAmB,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,2BAA2B,EAAE;IAqC1G,gFAAgF;IAChF,mBAAmB,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,mBAAmB,CAAA;KAAE,GAAG,kCAAkC;IAiB9F,+EAA+E;IAC/E,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC;CAkClE"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { growthObjectDigest, memoryLearningRequestDigest, validateMemoryLearningReviewRequest, validateMemoryLearningOwner, } from '@dsh-enhanced/assistant-growth-contract';
|
|
2
|
+
import { memoryPrincipalDigest } from './store.js';
|
|
3
|
+
import { validateMemoryLearningAdoptionGrant } from './learning-adoptions.js';
|
|
4
|
+
/** Host-only adoption and read-time source checks. No model-visible mutation tool. */
|
|
5
|
+
export class MemoryLearningService {
|
|
6
|
+
ctx;
|
|
7
|
+
store;
|
|
8
|
+
#grant;
|
|
9
|
+
constructor(ctx, store, grant) {
|
|
10
|
+
this.ctx = ctx;
|
|
11
|
+
this.store = store;
|
|
12
|
+
this.#grant = validateMemoryLearningAdoptionGrant(grant);
|
|
13
|
+
store.registerLearningGrant(this.#grant);
|
|
14
|
+
}
|
|
15
|
+
#scope() {
|
|
16
|
+
const owner = this.#grant.owner;
|
|
17
|
+
return { authorityId: owner.authorityId, principalId: owner.principalId, workspace: owner.workspace,
|
|
18
|
+
agentPreset: owner.agentPreset, expectedOwner: { authorityHash: owner.authorityHash,
|
|
19
|
+
principalRecordId: owner.principalRecordId, principalVersion: owner.principalVersion } };
|
|
20
|
+
}
|
|
21
|
+
#services() {
|
|
22
|
+
const delivery = this.ctx.get('assistantDelivery');
|
|
23
|
+
const evaluation = this.ctx.get('assistantEvaluation');
|
|
24
|
+
if (!delivery || !evaluation || typeof delivery.withOwnerForegroundTaskSourcesFence !== 'function'
|
|
25
|
+
|| typeof delivery.inspectOwnerForegroundLearningTask !== 'function'
|
|
26
|
+
|| typeof evaluation.canonicalHostScope !== 'function' || typeof evaluation.getTrustedForegroundLearningProjection !== 'function'
|
|
27
|
+
|| typeof evaluation.inspectTrustedTaskOwnerRevision !== 'function' || typeof evaluation.listTrustedTaskLearningProjections !== 'function'
|
|
28
|
+
|| typeof evaluation.withTrustedCanonicalScopeWriterFence !== 'function')
|
|
29
|
+
throw new Error('memory learning source services unavailable');
|
|
30
|
+
return { delivery, evaluation };
|
|
31
|
+
}
|
|
32
|
+
#policy(request, consume = false) {
|
|
33
|
+
const policy = this.ctx.get('assistantPolicy');
|
|
34
|
+
if (!policy)
|
|
35
|
+
throw new Error('memory learning policy unavailable');
|
|
36
|
+
const owner = request?.owner ?? this.#grant.owner;
|
|
37
|
+
const input = { subject: { kind: 'background', id: 'assistant-memory-learning',
|
|
38
|
+
workspace: owner.workspace, principal: owner.principalId }, action: 'adopt',
|
|
39
|
+
resource: { kind: 'memory', id: `learning:${this.#grant.authorityId}` }, context: { initiator: 'background' } };
|
|
40
|
+
const decision = consume && request ? policy.authorize(input, { idempotencyKey: `memory-adopt:${this.#grant.authorityId}:${memoryLearningRequestDigest(request)}` })
|
|
41
|
+
: policy.evaluate(input);
|
|
42
|
+
if (decision.effect !== 'allow')
|
|
43
|
+
throw new Error('memory learning adoption policy denied');
|
|
44
|
+
}
|
|
45
|
+
#request(input) {
|
|
46
|
+
const request = validateMemoryLearningReviewRequest(input);
|
|
47
|
+
if (growthObjectDigest(request.owner) !== growthObjectDigest(this.#grant.owner))
|
|
48
|
+
throw new Error('memory learning owner changed');
|
|
49
|
+
return request;
|
|
50
|
+
}
|
|
51
|
+
#owner(input) {
|
|
52
|
+
const owner = validateMemoryLearningOwner(input);
|
|
53
|
+
if (growthObjectDigest(owner) !== growthObjectDigest(this.#grant.owner))
|
|
54
|
+
throw new Error('memory learning owner changed');
|
|
55
|
+
return owner;
|
|
56
|
+
}
|
|
57
|
+
#evaluationFence(evaluation, callback) {
|
|
58
|
+
const owner = this.#grant.owner;
|
|
59
|
+
const scope = evaluation.canonicalHostScope({ workspace: owner.workspace, preset: owner.agentPreset });
|
|
60
|
+
const { scopeWatermark } = evaluation.listTrustedTaskLearningProjections({ scope, limit: 1 });
|
|
61
|
+
const result = evaluation.withTrustedCanonicalScopeWriterFence({ scope, scopeWatermark }, callback);
|
|
62
|
+
if (!result.matched)
|
|
63
|
+
throw new Error('memory learning canonical scope changed');
|
|
64
|
+
return result.value;
|
|
65
|
+
}
|
|
66
|
+
#sourceState(request, content, services) {
|
|
67
|
+
if (!content || content.sourceDigest !== request.source.sourceDigest || content.contentDigest !== request.source.contentDigest
|
|
68
|
+
|| content.input.truncated || content.reply.truncated || !content.source.execution.modelSelection)
|
|
69
|
+
return 'source-changed';
|
|
70
|
+
const { owner } = request;
|
|
71
|
+
const scope = services.evaluation.canonicalHostScope({ workspace: owner.workspace, preset: owner.agentPreset });
|
|
72
|
+
const current = services.evaluation.getTrustedForegroundLearningProjection({ scope, inboxId: request.source.inboxId });
|
|
73
|
+
const revision = current === undefined ? undefined : services.evaluation.inspectTrustedTaskOwnerRevision({
|
|
74
|
+
scope, outcomeId: current.triggerOutcomeId, principalRecordId: owner.principalRecordId, principalVersion: owner.principalVersion,
|
|
75
|
+
});
|
|
76
|
+
if (revision?.action === 'withdraw')
|
|
77
|
+
return 'withdrawn';
|
|
78
|
+
if (request.source.canonical) {
|
|
79
|
+
const expected = request.source.canonical;
|
|
80
|
+
const task = services.delivery.inspectOwnerForegroundLearningTask({ authorityId: owner.authorityId, principalId: owner.principalId,
|
|
81
|
+
workspace: owner.workspace, agentPreset: owner.agentPreset, outcomeId: expected.outcomeId });
|
|
82
|
+
if (!task || task.judgement === 'unresolved' || task.source.inboxId !== request.source.inboxId || !task.source.quiescent
|
|
83
|
+
|| task.ownerRevision?.action === 'withdraw' || task.canonical.projection.disposition !== 'upsert'
|
|
84
|
+
|| task.canonical.projection.version !== expected.version || task.canonical.projection.digest !== expected.digest
|
|
85
|
+
|| task.canonical.objective?.status !== expected.objectiveStatus
|
|
86
|
+
|| task.owner.principalRecordId !== owner.principalRecordId || task.owner.principalVersion !== owner.principalVersion
|
|
87
|
+
|| task.owner.authorityHash !== owner.authorityHash || task.feedback?.truncated)
|
|
88
|
+
return 'source-changed';
|
|
89
|
+
}
|
|
90
|
+
return 'current';
|
|
91
|
+
}
|
|
92
|
+
/** Historical exact receipt for lost ACKs; not a claim that its record is still visible. */
|
|
93
|
+
lookup(input) {
|
|
94
|
+
const request = this.#request(input);
|
|
95
|
+
const delivery = this.ctx.get('assistantDelivery');
|
|
96
|
+
if (!delivery || typeof delivery.withOwnerForegroundTaskSourcesFence !== 'function')
|
|
97
|
+
throw new Error('memory learning owner service unavailable');
|
|
98
|
+
return delivery.withOwnerForegroundTaskSourcesFence({ ...this.#scope(), sources: [] }, () => {
|
|
99
|
+
this.#policy(request);
|
|
100
|
+
return this.store.lookupLearningAdoption({ authorityId: this.#grant.authorityId,
|
|
101
|
+
operationId: request.operationId, requestDigest: memoryLearningRequestDigest(request) });
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
adopt(input) {
|
|
105
|
+
const request = this.#request(input);
|
|
106
|
+
const prior = this.lookup(request);
|
|
107
|
+
if (prior)
|
|
108
|
+
return prior;
|
|
109
|
+
if (Date.now() >= this.#grant.expiresAt)
|
|
110
|
+
throw new Error('memory learning adoption grant expired');
|
|
111
|
+
const verifier = this.ctx.get('assistantVerifier');
|
|
112
|
+
if (!verifier || typeof verifier.lookupMemoryLearningReview !== 'function')
|
|
113
|
+
throw new Error('memory learning independent reviewer unavailable');
|
|
114
|
+
// Verifier lookup takes its own producer locks. Complete it before taking
|
|
115
|
+
// Delivery → Evaluation → Memory below; no asynchronous gap is introduced.
|
|
116
|
+
const reviewReceipt = verifier.lookupMemoryLearningReview(request);
|
|
117
|
+
if (!reviewReceipt || reviewReceipt.status !== 'approved' || reviewReceipt.requestDigest !== memoryLearningRequestDigest(request)
|
|
118
|
+
|| reviewReceipt.operationId !== request.operationId || reviewReceipt.authorityId !== this.#grant.reviewAuthorityId
|
|
119
|
+
|| reviewReceipt.authorityDigest !== this.#grant.reviewAuthorityDigest)
|
|
120
|
+
throw new Error('memory learning independent approval unavailable or changed');
|
|
121
|
+
const services = this.#services();
|
|
122
|
+
return services.delivery.withOwnerForegroundTaskSourcesFence({ ...this.#scope(),
|
|
123
|
+
sources: [{ inboxId: request.source.inboxId, expectedSourceDigest: request.source.sourceDigest }] }, contents => this.#evaluationFence(services.evaluation, () => {
|
|
124
|
+
const content = contents[0];
|
|
125
|
+
if (this.#sourceState(request, content, services) !== 'current')
|
|
126
|
+
throw new Error('memory learning source changed or withdrawn');
|
|
127
|
+
this.#policy(request, true);
|
|
128
|
+
return this.store.applyLearningAdoption({ grant: this.#grant, request, reviewReceipt,
|
|
129
|
+
sourceObservedAt: content.source.execution.completedAt });
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
inspectTarget(input) {
|
|
133
|
+
if (growthObjectDigest(input.owner) !== growthObjectDigest(this.#grant.owner))
|
|
134
|
+
return undefined;
|
|
135
|
+
return this.store.inspectLearningTarget(input);
|
|
136
|
+
}
|
|
137
|
+
/** Host-only bounded candidates, after current owner, Policy and source checks. */
|
|
138
|
+
listTargets(input) {
|
|
139
|
+
const owner = this.#owner(input.owner);
|
|
140
|
+
const limit = input.limit ?? 20;
|
|
141
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100)
|
|
142
|
+
throw new Error('memory learning target limit is invalid');
|
|
143
|
+
const services = this.#services();
|
|
144
|
+
this.#policy();
|
|
145
|
+
const context = { workspace: owner.workspace, agentPreset: owner.agentPreset,
|
|
146
|
+
namespace: { mode: 'delivery', principalDigest: memoryPrincipalDigest(owner.principalId),
|
|
147
|
+
principalRecordId: owner.principalRecordId, principalVersion: owner.principalVersion } };
|
|
148
|
+
const managed = this.store.listManagedLearningSources(context)
|
|
149
|
+
.filter(item => growthObjectDigest(item.request.owner) === growthObjectDigest(owner));
|
|
150
|
+
if (managed.length > 1000)
|
|
151
|
+
return Object.freeze([]);
|
|
152
|
+
const sources = [...new Map(managed.map(item => [item.request.source.inboxId,
|
|
153
|
+
{ inboxId: item.request.source.inboxId, expectedSourceDigest: item.request.source.sourceDigest }])).values()];
|
|
154
|
+
try {
|
|
155
|
+
return services.delivery.withOwnerForegroundTaskSourcesFence({ ...this.#scope(), sources }, contents => this.#evaluationFence(services.evaluation, () => {
|
|
156
|
+
this.#policy();
|
|
157
|
+
if (!this.store.inspectLearningAdoptionAvailability(this.#grant).available)
|
|
158
|
+
return Object.freeze([]);
|
|
159
|
+
const byInbox = new Map(sources.map((source, index) => [source.inboxId, contents[index]]));
|
|
160
|
+
const targets = managed.flatMap(item => {
|
|
161
|
+
if (this.#sourceState(item.request, byInbox.get(item.request.source.inboxId), services) !== 'current')
|
|
162
|
+
return [];
|
|
163
|
+
const target = this.store.inspectLearningTarget({ owner, id: item.id, expectedVersion: item.version });
|
|
164
|
+
return target === undefined ? [] : [{ id: target.id, version: target.version,
|
|
165
|
+
kind: target.kind, content: target.content,
|
|
166
|
+
...(target.knowledge === undefined ? {} : { knowledge: target.knowledge }) }];
|
|
167
|
+
});
|
|
168
|
+
targets.sort((a, b) => a.id.localeCompare(b.id) || a.version - b.version);
|
|
169
|
+
return Object.freeze(targets.slice(0, limit));
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// A temporarily missing source or provider cannot make an automatic
|
|
174
|
+
// record available to a new producer.
|
|
175
|
+
return Object.freeze([]);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Host-only budget view; no grant registration or Policy quota consumption. */
|
|
179
|
+
inspectAvailability(input) {
|
|
180
|
+
this.#owner(input.owner);
|
|
181
|
+
const delivery = this.ctx.get('assistantDelivery');
|
|
182
|
+
if (!delivery || typeof delivery.withOwnerForegroundTaskSourcesFence !== 'function')
|
|
183
|
+
throw new Error('memory learning owner service unavailable');
|
|
184
|
+
return delivery.withOwnerForegroundTaskSourcesFence({ ...this.#scope(), sources: [] }, () => {
|
|
185
|
+
this.#policy();
|
|
186
|
+
return this.store.inspectLearningAdoptionAvailability(this.#grant);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
#matchesContext(context) {
|
|
190
|
+
const owner = this.#grant.owner, namespace = context.namespace;
|
|
191
|
+
return context.workspace === owner.workspace && context.agentPreset === owner.agentPreset
|
|
192
|
+
&& namespace.mode === 'delivery' && namespace.principalRecordId === owner.principalRecordId
|
|
193
|
+
&& namespace.principalVersion === owner.principalVersion && namespace.principalDigest === memoryPrincipalDigest(owner.principalId);
|
|
194
|
+
}
|
|
195
|
+
/** Sources stay locked through Memory's read snapshot, ranking and framing. */
|
|
196
|
+
withVisible(context, callback) {
|
|
197
|
+
if (!this.#matchesContext(context))
|
|
198
|
+
return callback();
|
|
199
|
+
// This query has no held Memory transaction. Newly appearing/changed
|
|
200
|
+
// managed versions are excluded by the final exact-reference filter.
|
|
201
|
+
const managed = this.store.listManagedLearningSources(context)
|
|
202
|
+
.filter(source => growthObjectDigest(source.request.owner) === growthObjectDigest(this.#grant.owner));
|
|
203
|
+
if (managed.length === 0 || managed.length > 1000)
|
|
204
|
+
return callback();
|
|
205
|
+
let callbackStarted = false;
|
|
206
|
+
try {
|
|
207
|
+
const services = this.#services();
|
|
208
|
+
const sources = [...new Map(managed.map(item => [item.request.source.inboxId,
|
|
209
|
+
{ inboxId: item.request.source.inboxId, expectedSourceDigest: item.request.source.sourceDigest }])).values()];
|
|
210
|
+
return services.delivery.withOwnerForegroundTaskSourcesFence({ ...this.#scope(), sources }, contents => this.#evaluationFence(services.evaluation, () => {
|
|
211
|
+
const byInbox = new Map(sources.map((source, index) => [source.inboxId, contents[index]]));
|
|
212
|
+
const checked = managed.map(item => ({ item, state: this.#sourceState(item.request, byInbox.get(item.request.source.inboxId), services) }));
|
|
213
|
+
const visible = [];
|
|
214
|
+
for (const { item, state } of checked) {
|
|
215
|
+
if (state === 'current')
|
|
216
|
+
visible.push(item);
|
|
217
|
+
// A missing/changed source or canonical projection can be temporarily
|
|
218
|
+
// unreadable. Only an explicit owner withdrawal warrants deletion.
|
|
219
|
+
else if (state === 'withdrawn')
|
|
220
|
+
this.store.invalidateManagedLearningSource({ owner: item.request.owner, id: item.id, version: item.version,
|
|
221
|
+
recordDigest: item.recordDigest, sourceDigest: item.sourceDigest, reason: state });
|
|
222
|
+
}
|
|
223
|
+
callbackStarted = true;
|
|
224
|
+
return this.store.withLearningVisibility(visible, callback);
|
|
225
|
+
}));
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
if (callbackStarted)
|
|
229
|
+
throw error;
|
|
230
|
+
// Temporary provider absence/errors hide automatic records, without
|
|
231
|
+
// manufacturing a durable withdrawal or suppressing manual memory.
|
|
232
|
+
return callback();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=learning-service.js.map
|