@ai-agent-forge/plugin-memory 0.88.18 → 0.88.20
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/agent-forge.json +1 -1
- package/dist/capability.d.ts.map +1 -1
- package/dist/capability.js +39 -0
- package/dist/capability.js.map +1 -1
- package/dist/inference-bin.bundle.js +62 -7
- package/dist/memory/command-face.d.ts.map +1 -1
- package/dist/memory/command-face.js +1 -1
- package/dist/memory/command-face.js.map +1 -1
- package/dist/memory/inference-service-main.d.ts.map +1 -1
- package/dist/memory/inference-service-main.js +5 -0
- package/dist/memory/inference-service-main.js.map +1 -1
- package/dist/memory/recall-pipeline.d.ts.map +1 -1
- package/dist/memory/recall-pipeline.js +22 -4
- package/dist/memory/recall-pipeline.js.map +1 -1
- package/dist/memory/vector-channel.d.ts.map +1 -1
- package/dist/memory/vector-channel.js +5 -0
- package/dist/memory/vector-channel.js.map +1 -1
- package/dist/memory/vector-index.d.ts +37 -0
- package/dist/memory/vector-index.d.ts.map +1 -1
- package/dist/memory/vector-index.js +54 -2
- package/dist/memory/vector-index.js.map +1 -1
- package/package.json +2 -2
- package/plugin.json +1 -1
package/dist/capability.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party builtin memory capability (统一修复轮 A, 方案系统设计 §6.1 + §11,\n * 方案实施计划 §11 A 路) — the model-facing write/recall/list/forget surface\n * over the M5 Memory Foundation.\n *\n * Every operation is suite-scoped by construction: the suiteId comes from the\n * session's suite binding entry (SUITE_SESSION_ENTRY_TYPE, written by the sdk\n * at session creation) and is NEVER a tool parameter, so the model cannot\n * widen or switch its memory domain (防越权). Sessions without a binding fall\n * back to the \"legacy\" domain with a diagnostic. Writes go through the\n * scheduler facade (observation → candidate → committed) plus a durable JSONL\n * ledger append (src/memory/ledger.ts, the store's persistent replica); recall\n * runs through the memory-recall-agent with the suiteId passthrough filter and\n * the egress gate; forget goes through the canonical purge gate\n * (user-immediate) and journal, physically rewriting the ledger (forget 后真\n * 物理删除).\n *\n * Domain resolution is LAZY, per tool call (统一修复轮 B1 复审修复): the sdk\n * appends the suite binding entry only after `new AgentSession` returns (the\n * constructor's synchronous runtime build already runs this factory), so a\n * factory-time resolution always saw an empty branch and every new session\n * fell back to the legacy domain. Instead, each tool handler resolves the\n * domain at call time — the binding entry is on the branch by then (creation\n * appends it; resumed sessions carry it in their history) — and the per-domain\n * ledger is created, loaded, and replayed into the store on the first call in\n * that domain (Map<domain, ledger> cache, no memoization of the domain\n * itself). The store stays one per-capability-instance singleton across\n * domains: the atom `suiteId` field carries the read boundary; the ledger is\n * only the per-domain durable replica.\n *\n * Concurrency envelope (统一修复轮 H1, #7 深度修复; WP-F 关洞修复): ledger\n * appends AND the forget path's full-file rewrite serialize competing\n * processes through the ledger's `.lock` sibling file (exclusive create +\n * poll, 5 s timeout, stale-lock stealing — src/memory/ledger.ts), and both\n * write paths run open → write → fsync → close, so a hard crash cannot lose\n * a write that returned to its caller. A lock timeout or IO/fsync failure\n * throws out of the tool handler, so the model sees the error instead of a\n * silently lost write. Remaining boundaries: the lock is atomic only on\n * local filesystems; a rewrite publishes the calling process's in-memory\n * view without merging rows another process appended after its last load\n * (the forget caller owns that reconciliation); fsync does not cover\n * directory entries, so a crash before rewrite's rename leaves the previous\n * file intact; an append whose fsync failed stays unacknowledged though it\n * may already be readable — the loader's duplicate tolerance covers an\n * unacknowledged retry.\n *\n * Global mode gate (2.4d6 S1, 记忆系统语义化重设计 §3): `memory.mode` is\n * `\"off\"` (default) | `\"light\"` | `\"full\"`; off means the whole memory family\n * is NOT registered (the suite membership skips the plugin; the factory\n * itself returns zero registrations for direct callers). light/full run an\n * enabling state machine (local checks → model load/download → smoke →\n * ready; failure → failed with a four-option action list and the effective\n * mode falls back to off for this instance).\n *\n * Semantic recall (2.4d6 S2, 设计 §4): memory_recall has exactly one\n * retrieval path — embed → KNN depth50 + FTS depth50 → RRF k=60 top20 →\n * cross-encoder rerank → store lookup (owner/suite/scope/expiry). The legacy\n * tag-wordform bridge (query-token → tag-facet anchors, recency fallback\n * page) is retired as a retrieval semantic; tags still ride the FTS body and\n * the memory_list management face. Degradation ladder (never thrown at the\n * model): rerank failure → RRF order; vector failure → FTS-only with\n * recency ordering; FTS/index failure → KNN-only; both channels down →\n * recency enumeration over the domain; total failure → degraded packet.\n * `memoryIdEquals`-style primary-key lookup survives as the exact-id fast\n * path (reference semantics, not retrieval).\n *\n * Semantic write merge (2.4d6 S3, 设计 §5 + 实施计划 S3 标定定版): in mode\n * \"full\" every memory_write probes the projection BEFORE the canonical commit\n * (embed + same-owner KNN top-5) because atoms are immutable — the outcome's\n * relations must ride the atom's one commit. Merge condition (calibrated on\n * bge-m3): cos ≥ 0.72, or 0.55 ≤ cos < 0.72 with a case-insensitive tag\n * overlap. A merge commits the NEW atom with a one-way `supersedes` relation\n * to the neighbor (the old entry keeps its memoryId and stays addressable via\n * primary-key lookup) while the projection upserts the new row and removes the\n * superseded one; startup reconciliation never re-adds superseded rows.\n * 0.55 ≤ cos < 0.72 without a tag overlap is the conflict band: both entries\n * stay, and the new atom carries one-way `conflict` relations. Below that (or\n * no neighbor): a plain new entry. bge-small-zh similarity distributions\n * overlap (标定: 余弦不可用作去重信号) → light mode never probes and stays\n * byte-identical to the pre-S3 behavior. Recall filters superseded entries\n * after the store lookup (only while their successor is among the candidates,\n * so forgetting the successor revives the old entry). The Foundation\n * (owner, observationId) idempotency is untouched: replays never consume a\n * probe outcome.\n */\nimport { join } from \"node:path\";\nimport type {\n\tMemoryCapabilityOverrideV1,\n\tMemoryModeV1,\n\tMemoryStorageComponentsV1,\n\tMemoryVectorComponentsOverrideV1,\n\tSessionArchiveHostV1,\n} from \"@agent-forge/plugin-sdk\";\nimport {\n\ttype CapabilityAPI,\n\ttype DisposableRegistration,\n\tEXPERIMENTAL_PUBLIC_API_VERSION,\n} from \"@agent-forge/plugin-sdk\";\n\n// 记忆公共契约的权威定义处已是 plugin-sdk(D-075 S4-4 第一批迁入);此处 re-export\n// 维持宿主历史导出面(宿主第二批收口后由宿主 re-export SDK)。\nexport {\n\tMEMORY_RECALL_TOOL_NAME,\n\ttype MemoryCapabilityOverrideV1,\n\ttype MemoryEnablingOverrideV1,\n\ttype MemoryModeV1,\n\ttype MemoryStorageComponentsV1,\n\ttype MemoryVectorComponentsOverrideV1,\n} from \"@agent-forge/plugin-sdk\";\n// 拆分战役 slice 1/3b: 征询持久化(enabling.ts 征询域)与向量常量/状态类型\n// (vector-channel.ts)随模块迁出,经 re-export 维持 capability.ts 的历史\n// 导出面(index.ts `export *` 与 entry.ts / inference-service-main.ts 的\n// 既有 import 不变;vector-channel.ts 不进 index.ts,slice 2 先例)。\nexport {\n\tMEMORY_AGENT_DIR_CONFIG_RELATIVE_PATH,\n\tMEMORY_CONSENT_DECLINED_VALUE,\n\twriteMemoryConsentDeclined,\n\twriteMemorySettingsMode,\n} from \"./memory/enabling.ts\";\n// 拆分战役 slice 7: auto-recall 注入标记/免责行随钩子面迁入 hooks.ts, 经\n// re-export 维持 capability.ts 的历史导出面 (index.ts `export *` 与既有 import\n// 不变; hooks.ts 本体不进 index.ts, recall-pipeline.ts 先例)。lessons 开关解析\n// 已随实时教训停用一并移除 (记忆归档与整理设计 §14 裁决 1)。\nexport {\n\tMEMORY_AUTO_RECALL_DEADLINE_MS,\n\tMEMORY_AUTO_RECALL_DISCLAIMER,\n\tMEMORY_AUTO_RECALL_MARKER,\n} from \"./memory/hooks.ts\";\n// 拆分战役 slice 4: MEMORY_TOOLS_GUIDE 随召回管线迁入 recall-pipeline.ts, 经\n// re-export 维持 capability.ts 的历史导出面 (宿主与测试的既有 import 不变;\n// recall-pipeline.ts 本体不进 index.ts, vector-channel.ts slice 2 先例)。\nexport { MEMORY_TOOLS_GUIDE } from \"./memory/recall-pipeline.ts\";\nexport {\n\ttype MemoryCapabilityStateV1,\n\ttype MemoryConsentNeededV1,\n\ttype MemoryEnablingFailureV1,\n\tVECTOR_DB_DIRNAME,\n\tVECTOR_MODEL_CACHE_DIRNAME,\n\tVECTOR_RERANKER_MODEL_ID,\n} from \"./memory/vector-channel.ts\";\n// 拆分战役 slice 5: 档位自动升级阈值随写入面迁入 write-face.ts, 经 re-export\n// 维持 capability.ts 的历史导出面。\nexport { MEMORY_TIER_UPGRADE_STORE_THRESHOLD } from \"./memory/write-face.ts\";\n\nimport { createMemoryCandidateMachine } from \"./memory/candidates.ts\";\nimport { createMemoryCommandFace } from \"./memory/command-face.ts\";\nimport { createMemoryCurator } from \"./memory/curator.ts\";\nimport { createMemoryEgressPolicy } from \"./memory/egress-policy.ts\";\nimport type { MemoryAtomV1 } from \"./memory/foundation.ts\";\nimport { createMemoryHooks } from \"./memory/hooks.ts\";\nimport { createDurableMemoryLedger, type DurableMemoryLedgerV1, scanOwnerLedgerMemoryIds } from \"./memory/ledger.ts\";\nimport { createMemoryLifecycleManager } from \"./memory/lifecycle.ts\";\nimport { createMemoryNetwork, createRelationDiffusionAdapter } from \"./memory/memory-network.ts\";\nimport { createPreferenceDisambiguator } from \"./memory/preference-disambiguator.ts\";\nimport { createPreferenceResolver } from \"./memory/preference-resolver.ts\";\nimport { createMemoryPurgeGate, createMemoryReplicaRegistry, type MemoryReplicaV1 } from \"./memory/purge.ts\";\nimport { createMemoryPurgeJournal } from \"./memory/purge-journal.ts\";\nimport { createMemoryRecallAgent } from \"./memory/recall-agent.ts\";\nimport { createMemoryRecallIndex } from \"./memory/recall-index.ts\";\nimport { createMemoryRecallPipeline } from \"./memory/recall-pipeline.ts\";\nimport { sweepExpiredMemories } from \"./memory/retention-sweep.ts\";\nimport { createMemoryScheduler } from \"./memory/scheduler.ts\";\nimport { createMemorySchedulerApi } from \"./memory/scheduler-api.ts\";\nimport { createFirstPartyRetentionRegistry, createMemoryStore } from \"./memory/store.ts\";\nimport { type SuiteMemoryDomainV1, suiteMemoryDomainName } from \"./memory/suite-memory.ts\";\nimport { MEMORY_CONTRACT_VERSION_V2 } from \"./memory/transfer.ts\";\nimport type { MemoryCapabilityStateV1, MemoryEnablingFailureV1 } from \"./memory/vector-channel.ts\";\nimport { createMemoryVectorChannel } from \"./memory/vector-channel.ts\";\nimport { createMemoryVectorProjection } from \"./memory/vector-projection.ts\";\nimport { createMemoryWriteFace, TAG_FACET_NAMESPACE } from \"./memory/write-face.ts\";\n\nexport const capabilityManifest = {\n\tid: \"agent-forge.builtin.memory\",\n\tversion: \"0.1.0\",\n\tapiVersion: EXPERIMENTAL_PUBLIC_API_VERSION,\n\trequiredCapabilities: [\"session\", \"events\", \"tools\"],\n\tprovides: [{ id: \"memory.scheduler\", version: 1, kind: \"service\" }],\n} as const;\n\n/**\n * 解析后的全局模式 (2.4d6 S1)。`invalidEnvValue` 非空 = 配置的环境值非法,\n * 已 fail-closed 回 off, 调用方负责以此输出一次 warn; `invalidSettingsValue`\n * 非空 = settings.json 的 `memory.mode` 非法, 同为 fail-closed off 并输出一次\n * 诊断; `legacyEnvUsed` = 模式由旧别名 `AGENT_FORGE_MEMORY_VECTOR` 决定 (兼容\n * 期: 仅当 `AGENT_FORGE_MEMORY_MODE` 与 settings 均未定档时生效, 一个发布周期\n * 后移除)。\n */\nexport interface MemoryModeResolutionV1 {\n\treadonly mode: MemoryModeV1;\n\treadonly invalidEnvValue?: string;\n\treadonly invalidSettingsValue?: string;\n\treadonly legacyEnvUsed?: boolean;\n}\n\nconst isMemoryModeV1 = (value: string): value is MemoryModeV1 =>\n\tvalue === \"off\" || value === \"light\" || value === \"full\";\n\n/**\n * memory.mode 解析 (2.4d6 S1)。优先级: context 显式值 → 环境变量\n * `AGENT_FORGE_MEMORY_MODE` → settings.json `memory.mode` (settingsMode 参, 持\n * 久配置面) → 旧别名 `AGENT_FORGE_MEMORY_VECTOR` (兼容期) → 默认 light\n * (2026-10-05 用户裁决翻转默认 off→light, 对齐主流编程助手开箱即用方向)。env 是\n * 临时覆盖、settings 是持久配置 (env > 文件, 沿用本仓 suite 解析先例)。任何\n * 非法配置值 fail-closed 为 off 并在结果中携带原值供调用方告警一次, 绝不静默\n * 改档或意外下载。\n */\nexport function resolveMemoryMode(\n\texplicitMode: string | undefined,\n\tenv: Readonly<Record<string, string | undefined>> = process.env,\n\tsettingsMode?: string,\n): MemoryModeResolutionV1 {\n\tif (explicitMode !== undefined) {\n\t\tif (isMemoryModeV1(explicitMode)) return { mode: explicitMode };\n\t\treturn { mode: \"off\", invalidEnvValue: explicitMode };\n\t}\n\tconst configured = env.AGENT_FORGE_MEMORY_MODE?.trim().toLowerCase();\n\tif (configured !== undefined && configured !== \"\") {\n\t\tif (isMemoryModeV1(configured)) return { mode: configured };\n\t\treturn { mode: \"off\", invalidEnvValue: configured };\n\t}\n\t// 持久配置面: settings.json memory.mode。设置但非法同样 fail-closed, 不再\n\t// 回落旧别名 (与非法 env 的先例一致)。\n\tconst fromSettings = settingsMode?.trim().toLowerCase();\n\tif (fromSettings !== undefined && fromSettings !== \"\") {\n\t\tif (isMemoryModeV1(fromSettings)) return { mode: fromSettings };\n\t\treturn { mode: \"off\", invalidSettingsValue: fromSettings };\n\t}\n\t// 兼容期别名: AGENT_FORGE_MEMORY_VECTOR (混合检索工程化的旧开关), 语义并入\n\t// AGENT_FORGE_MEMORY_MODE, 仅当新变量与 settings 均未定档时生效; 一个发布\n\t// 周期后删除。\n\tconst legacy = env.AGENT_FORGE_MEMORY_VECTOR?.trim().toLowerCase();\n\tif (legacy !== undefined && legacy !== \"\") {\n\t\tif (isMemoryModeV1(legacy)) return { mode: legacy, legacyEnvUsed: true };\n\t\treturn { mode: \"off\", invalidEnvValue: legacy, legacyEnvUsed: true };\n\t}\n\treturn { mode: \"light\" };\n}\n\n/** Host-provided factory context; provided by the host session assembly (sdk suite membership). */\nexport interface MemoryCapabilityContext {\n\t/** Agent home directory — roots the durable ledger under `<agentDir>/memory/`. */\n\treadonly agentDir: string;\n\t/**\n\t * 宿主已解析的 onnxruntime-node 入口绝对路径 (D-075 安装店重依赖可见性):\n\t * 安装店副本无 node_modules, 插件内 createRequire 解析不到; 宿主装载器把\n\t * hostDependencyPaths 注入 manifest config, entry 提取后经本字段传入。\n\t * 缺省 (源码/工作区直载) 走插件内双通道自解析。\n\t */\n\treadonly hostOnnxRuntimeEntryPath?: string;\n\t/** 同上——@lancedb/lancedb 入口路径 (向量索引运行时按绝对路径原生 import)。 */\n\treadonly hostLancedbEntryPath?: string;\n\t/** 同上——@huggingface/transformers 入口路径 (embedding/reranker 运行时用)。 */\n\treadonly hostTransformersEntryPath?: string;\n\t/**\n\t * 记忆全局档位 (2.4d6 S1)。缺省解析顺序: 本字段 → 环境变量\n\t * `AGENT_FORGE_MEMORY_MODE` → {@link MemoryCapabilityContext.memory.settingsMode}\n\t * → 旧别名 `AGENT_FORGE_MEMORY_VECTOR` (兼容期) → 默认 off (整个家族不注册)。\n\t * 装配方 (sdk) 可经本字段显式定档。\n\t */\n\treadonly memory?: {\n\t\treadonly mode?: MemoryModeV1;\n\t\t/**\n\t\t * settings.json `memory.mode` 的原样值 (持久配置面, 优先级低于 env);\n\t\t * 类型面只允许合法档位, 手改文件的非法值原样透传并由\n\t\t * {@link resolveMemoryMode} fail-closed 处理。\n\t\t */\n\t\treadonly settingsMode?: string;\n\t};\n\t/**\n\t * 测试专用注入 (架构宪法: deterministic mock AI 门禁)。经装配上下文携带时,\n\t * 装配方原样透传给工厂; 与 {@link createCapabilityWithVectorComponents}\n\t * 的第三参语义一致, 第三参优先。\n\t */\n\treadonly vectorComponents?: MemoryCapabilityOverrideV1;\n\t/**\n\t * 共享推理服务装配缝 (Slice B2, 记忆共享推理服务设计 §3.1/§3.3/§3.6)。\n\t * 缺省 (生产) = 真实路径: 模型在位时装配经 TCP loopback 走常驻服务,\n\t * 连不上则懒 spawn 插件 bin (`agent-forge-memory-inference`), 重连失败按\n\t * enabling failed 呈现 (裁决 A: 不回退本地装配)。测试注入替换对应环节\n\t * (deterministic 门禁): `port` 直连测试服务、`spawnImpl` 替换进程拉起、\n\t * `modelsInPlace` 声明模型在位 (跳过文件检查, 免写假权重文件)。\n\t * loadImpl enabling 缝与 vectorComponents 注入仍走本地装配路径 (既有语义)。\n\t */\n\treadonly inferenceService?: {\n\t\treadonly port?: number;\n\t\treadonly spawnImpl?: (\n\t\t\tagentDir: string,\n\t\t\tmode: \"light\" | \"full\",\n\t\t\tport: number,\n\t\t\t/** spawn 异步失败 (EACCES/ENOMEM 等) 的回调; 缺省实现经 child 'error' 事件馈入。 */\n\t\t\tonError?: (error: Error) => void,\n\t\t) => Promise<void>;\n\t\treadonly modelsInPlace?: boolean;\n\t};\n\t/**\n\t * 记忆底层组件注入 (扩展位盘点 A1/A2 的宿主装配通道): store/ledger 工厂与\n\t * 向量组件公共契约, 缺省成员走内置默认实现。装配方经\n\t * `CreateAgentSessionOptions.memoryCapability.storage` 携带。\n\t */\n\treadonly storage?: MemoryStorageComponentsV1;\n\t/**\n\t * 会话归档协调面 (记忆归档与整理设计 §4/§8): 整理器读归档会话条目与回写\n\t * curation 状态的唯一通道。缺省回落宿主服务 `api.host.sessionArchive`(生产\n\t * 装配路径);两者都缺席 = 宿主不开放归档,整理器的两个触发(归档事件观察与\n\t * 启动 sweep)都不注册,记忆家族其余能力不受影响。本字段同时是测试注入缝\n\t * (deterministic mock AI 门禁:curator 测试经它注入 fake archive)。\n\t */\n\treadonly sessionArchive?: SessionArchiveHostV1;\n}\n\nconst isVectorComponentsOverride = (\n\toverride: MemoryCapabilityOverrideV1,\n): override is MemoryVectorComponentsOverrideV1 => \"embedProvider\" in override && \"vectorIndex\" in override;\n\n/**\n * 默认档判定 (征询拒绝只抑制默认档): 显式值、env、settings、旧别名四层全部\n * 未定档时, 模式来自出厂默认档 (light)。与 resolveMemoryMode 的优先级链同构,\n * 不改 resolver 返回面。\n */\nexport function memoryModeSourceIsDefault(\n\texplicitMode: string | undefined,\n\tenv: Readonly<Record<string, string | undefined>>,\n\tsettingsMode?: string,\n): boolean {\n\treturn (\n\t\texplicitMode === undefined &&\n\t\t(env.AGENT_FORGE_MEMORY_MODE?.trim() ?? \"\") === \"\" &&\n\t\t(env.AGENT_FORGE_MEMORY_VECTOR?.trim() ?? \"\") === \"\" &&\n\t\t(settingsMode?.trim() ?? \"\") === \"\"\n\t);\n}\n\nfunction assertNonEmptyString(value: unknown, label: string): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) throw new Error(`${label} must be a non-empty string`);\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * 双约定工具输入读取(对齐 subagent-delegate 的 objectInput):capability invoke\n * 面单参约定下第一参即输入(第二参是宿主注入的 toolExecutionContext),legacy 5 参\n * 约定(toolCallId 字符串打头)下输入在第二参。生产装配恒向 runtime invoke 面注入\n * toolExecutionContext 作为 execute 第二参(公共契约),因此\"第二参非 undefined 即\n * 输入\"的判定会把 context 误当输入(content/query 等读成 undefined)。改按形状判定:\n * 第一参是普通对象即取第一参,否则看第二参;两者皆非对象时返回空记录,交由各工具\n * 的字段断言报错。\n */\nfunction memoryToolInput(first: unknown, second: unknown): Record<string, unknown> {\n\tconst primary = isPlainRecord(first) ? first : second;\n\treturn isPlainRecord(primary) ? primary : {};\n}\n\n/** FNV-1a 32-bit — deterministic identity from the given value (code-memory 同构). */\nfunction identityHash(value: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\thash ^= value.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(36);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Session protocol key of the suite binding entry (方案设计 §10.1). The value\n * mirrors the authoritative `SUITE_SESSION_ENTRY_TYPE` in\n * src/suites/suite-loader.ts — pinned by a deterministic test in\n * test/capabilities-builtin.test.ts. Declared locally so the capability module\n * graph stays free of the assembler's bundled-loader dependency chain.\n */\nconst SUITE_SESSION_ENTRY_TYPE = \"suite\";\n\n/**\n * Owner (isolation principal) of every atom this capability writes. The\n * Foundation owner is the store/facade isolation identity; this product ships\n * one local user per agentDir, so one stable owner id partitions the ledger\n * directory `<agentDir>/memory/<owner>/ledger-<suiteId|\"legacy\">.jsonl`.\n */\nexport const BUILTIN_MEMORY_OWNER = \"local-user\";\n\n/** Contract version written by this capability (@2 atoms carry suiteId). */\nconst MEMORY_CONTRACT_VERSION = MEMORY_CONTRACT_VERSION_V2;\n\n/**\n * Suite binding entry ids already warned about (统一修复轮终审 minor 3):\n * resolveSessionDomain runs on EVERY memory tool call, so without this\n * module-level set one malformed binding entry would repeat the warning on\n * each call and flood the log.\n */\nconst malformedBindingWarned = new Set<string>();\n\n/**\n * Resolves the session's suite binding domain from the branch entries: the\n * LAST suite entry wins (the sdk appends one at session creation). A binding\n * with a malformed payload counts as unbound — the legacy fallback is\n * fail-safe (its atoms are invisible to every real suite) and a diagnostic is\n * logged when the logger capability is available. Called per tool call —\n * never captured at factory time (统一修复轮 B1: the binding entry is appended\n * after the session constructor ran this factory).\n */\nfunction resolveSessionDomain(api: CapabilityAPI): SuiteMemoryDomainV1 {\n\tconst entries = api.session?.getBranchEntries() ?? [];\n\tfor (let index = entries.length - 1; index >= 0; index -= 1) {\n\t\tconst entry = entries[index];\n\t\tif (entry.type !== \"custom\" || entry.customType !== SUITE_SESSION_ENTRY_TYPE) continue;\n\t\tconst data = entry.data;\n\t\tconst suiteId = isPlainObject(data) ? data.suiteId : undefined;\n\t\tif (typeof suiteId === \"string\" && suiteId.trim() !== \"\") {\n\t\t\treturn { kind: \"suite\", suiteId };\n\t\t}\n\t\tif (!malformedBindingWarned.has(entry.id)) {\n\t\t\tmalformedBindingWarned.add(entry.id);\n\t\t\tapi.logger?.warn(\"suite binding entry has a malformed payload; falling back to the legacy memory domain\", {\n\t\t\t\tentryId: entry.id,\n\t\t\t});\n\t\t}\n\t\treturn { kind: \"legacy\" };\n\t}\n\treturn { kind: \"legacy\" };\n}\n\n/** Recency-first payload projection: unwraps the `{ statement }` payload convention. */\nfunction statementOf(payload: unknown): string {\n\tif (isPlainObject(payload) && typeof payload.statement === \"string\") return payload.statement;\n\treturn JSON.stringify(payload);\n}\n\n/** The egress gate re-derives statements as payload JSON; unwrap for the model face. */\nfunction unwrapEgressStatement(statement: string): string {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(statement);\n\t\tif (isPlainObject(parsed) && typeof parsed.statement === \"string\") return parsed.statement;\n\t} catch {\n\t\t// Not payload JSON — surface it verbatim.\n\t}\n\treturn statement;\n}\n\nfunction tagFacetsOf(atom: MemoryAtomV1): string[] {\n\treturn atom.facets\n\t\t.filter((facet) => facet.namespace === TAG_FACET_NAMESPACE && facet.key === \"tag\")\n\t\t.map((facet) => facet.value);\n}\n\n/**\n * Creates the builtin memory capability: four tools (memory_write,\n * memory_recall, memory_list, memory_forget) over a per-session Foundation\n * stack whose durable replica is the per-domain JSONL ledger under\n * `<agentDir>/memory/<owner>/ledger-<domain>.jsonl`, resolved lazily at each\n * tool call (统一修复轮 B1).\n *\n * `memory.mode` gates the whole family (2.4d6 S1): a resolved mode of \"off\"\n * registers NOTHING (zero tools, zero commands, zero events) — the factory\n * returns an empty registration list and logs the one-line disabled\n * declaration. suite capability membership decides earlier at the assembly\n * level (设计 §3.2 \"禁用 = 不注册\").\n *\n * `override` is the test-only seam (deterministic mock AI 门禁): full vector\n * components skip the real transformers/lancedb assembly entirely; enabling\n * seams keep the real assembly but replace the transformers loader.\n */\nexport function createMemoryCapability(\n\tapi: CapabilityAPI,\n\tcontext: MemoryCapabilityContext,\n\toverride?: MemoryCapabilityOverrideV1,\n): readonly DisposableRegistration[] {\n\tconst harness = createMemoryCapabilityHarness(api, context, override);\n\treturn harness.registrations;\n}\n\n/** Test-only harness over the capability: registration list plus state-work hooks. */\nexport interface MemoryVectorCapabilityHarnessV1 {\n\treadonly registrations: readonly DisposableRegistration[];\n\t/** Resolves after every vector op queued so far (reconcile/upsert/purge) settled. */\n\tsettleVectorWork(): Promise<void>;\n\tvectorState(): \"off\" | MemoryCapabilityStateV1;\n\t/**\n\t * Resolves once the enabling attempt settles (immediately for injected\n\t * components): ready, or the structured failure (reason + action list).\n\t */\n\tenablingOutcome(): Promise<\"ready\" | MemoryEnablingFailureV1>;\n\t/**\n\t * 释放共享推理服务连接 (服务路径) 或本地向量索引 (本地装配路径)。幂等: 引用\n\t * 清空后二次调用为 no-op。同名注册项挂 registrations 首位——宿主反向逐个\n\t * dispose 时它最后执行 (先拆消费者、后关通道)。\n\t */\n\tteardown(): void;\n}\n\n/**\n * Test-only assembly variant: the capability with an injected override (full\n * vector components skip real assembly; enabling seams redirect the model\n * loader on the real path). Public tool names, schemas, and return shapes are\n * identical to {@link createMemoryCapability}.\n */\nexport function createCapabilityWithVectorComponents(\n\tapi: CapabilityAPI,\n\tcontext: MemoryCapabilityContext,\n\toverride: MemoryCapabilityOverrideV1,\n): MemoryVectorCapabilityHarnessV1 {\n\t// Tool-face test stubs hand-write partial CapabilityAPIs that predate the\n\t// D-071 auto-recall hook; default registerLoopHook to a no-op so those\n\t// tests keep exercising just the tool face. Real CapabilityAPIs always\n\t// carry the method (production path never hits this default) — the `in`\n\t// check is runtime-only because the stubs bypass the declared type.\n\tconst apiWithHooks: CapabilityAPI =\n\t\t\"registerLoopHook\" in api\n\t\t\t? api\n\t\t\t: Object.assign(Object.create(null) as CapabilityAPI, api, {\n\t\t\t\t\tregisterLoopHook: (): DisposableRegistration => ({\n\t\t\t\t\t\tid: \"test:noop-loop-hook\",\n\t\t\t\t\t\tkind: \"loop-hook\",\n\t\t\t\t\t\tdispose() {},\n\t\t\t\t\t}),\n\t\t\t\t});\n\treturn createMemoryCapabilityHarness(apiWithHooks, context, override);\n}\n\nfunction createMemoryCapabilityHarness(\n\tapi: CapabilityAPI,\n\tcontext: MemoryCapabilityContext,\n\toverride?: MemoryCapabilityOverrideV1,\n): MemoryVectorCapabilityHarnessV1 {\n\tassertNonEmptyString(context.agentDir, \"MemoryCapabilityContext.agentDir\");\n\tconst now = (): number => Date.now();\n\tconst sessionId = api.session?.getSessionId() ?? \"no-session\";\n\n\t// 全局档位解析 (2.4d6 S1): context 显式 → env → settings.json → 默认 off。\n\t// 非法 env/settings 值 fail-closed 回 off 并各告警一次; off = 家族整体不注册\n\t// (零工具零命令零事件)。\n\tconst modeResolution = resolveMemoryMode(context.memory?.mode, undefined, context.memory?.settingsMode);\n\tif (modeResolution.invalidEnvValue !== undefined) {\n\t\tapi.logger?.warn(\n\t\t\t`invalid AGENT_FORGE_MEMORY_MODE value \"${modeResolution.invalidEnvValue}\"; memory stays off (fail-closed)`,\n\t\t);\n\t}\n\tif (modeResolution.invalidSettingsValue !== undefined) {\n\t\tapi.logger?.warn(\n\t\t\t`invalid memory.mode setting \"${modeResolution.invalidSettingsValue}\"; memory stays off (fail-closed)`,\n\t\t);\n\t}\n\tif (modeResolution.mode === \"off\") {\n\t\tapi.logger?.info(\"memory disabled (mode=off)\");\n\t\treturn {\n\t\t\tregistrations: [],\n\t\t\tsettleVectorWork: async () => {},\n\t\t\tvectorState: () => \"off\",\n\t\t\tenablingOutcome: async () => \"ready\",\n\t\t\tteardown: () => {},\n\t\t};\n\t}\n\tconst memoryMode = modeResolution.mode;\n\tconst vectorComponentsOverride: MemoryCapabilityOverrideV1 | undefined =\n\t\toverride ?? context.vectorComponents ?? context.storage?.vectorComponents;\n\tconst injectedComponents =\n\t\tvectorComponentsOverride !== undefined && isVectorComponentsOverride(vectorComponentsOverride)\n\t\t\t? vectorComponentsOverride\n\t\t\t: undefined;\n\tconst enablingOverride =\n\t\tvectorComponentsOverride !== undefined && !isVectorComponentsOverride(vectorComponentsOverride)\n\t\t\t? vectorComponentsOverride\n\t\t\t: undefined;\n\n\t// Store: one per-capability-instance singleton. Atoms of every domain this\n\t// session touches live here together — the atom `suiteId` field carries the\n\t// read boundary (suite queries filter through it; the ledger is only the\n\t// per-domain durable replica). The injected storeFactory (扩展位 A1) replaces\n\t// the default store wholesale: the implementation owns retention semantics.\n\tconst retentionRegistry = createFirstPartyRetentionRegistry();\n\tconst store =\n\t\tcontext.storage?.storeFactory?.({\n\t\t\tagentDir: context.agentDir,\n\t\t\towner: BUILTIN_MEMORY_OWNER,\n\t\t\tnow,\n\t\t}) ?? createMemoryStore({ retentionRegistry, now });\n\n\t// Durable replica per domain, created and loaded lazily on the first tool\n\t// call in that domain (统一修复轮 B1 复审修复): the sdk appends the suite\n\t// binding entry only after the session constructor ran this factory, so the\n\t// domain (and with it the ledger to replay) is only known at call time.\n\t// Write identity is deterministic: observationId `memory_write:<sessionId>:<n>`\n\t// hashes into the memoryId. The counter is instance-local, so a resumed session\n\t// re-derives its floor from the replayed ledger (resolveDomain): a persisted\n\t// observationId of this session marks its sequence as taken — the store rejects\n\t// a regenerated memoryId (canonical atoms are immutable), which would fail every\n\t// replayed-sequence write after resume (write → dispose → resume → write).\n\tconst domainLedgers = new Map<string, DurableMemoryLedgerV1>();\n\tconst resolveDomain = (): {\n\t\treadonly domain: SuiteMemoryDomainV1;\n\t\treadonly domainName: string;\n\t\treadonly ledger: DurableMemoryLedgerV1;\n\t} => {\n\t\tconst domain = resolveSessionDomain(api);\n\t\tconst domainName = suiteMemoryDomainName(domain);\n\t\tlet ledger = domainLedgers.get(domainName);\n\t\tif (ledger === undefined) {\n\t\t\tledger =\n\t\t\t\tcontext.storage?.ledgerFactory?.({\n\t\t\t\t\tagentDir: context.agentDir,\n\t\t\t\t\towner: BUILTIN_MEMORY_OWNER,\n\t\t\t\t\tdomain: domainName,\n\t\t\t\t\tnow,\n\t\t\t\t}) ??\n\t\t\t\tcreateDurableMemoryLedger({\n\t\t\t\t\tpath: join(context.agentDir, \"memory\", BUILTIN_MEMORY_OWNER, `ledger-${domainName}.jsonl`),\n\t\t\t\t\tnow,\n\t\t\t\t});\n\t\t\tif (domain.kind === \"legacy\") {\n\t\t\t\tapi.logger?.info(\"session has no suite binding; memory falls back to the legacy domain\", {\n\t\t\t\t\tsessionId: api.session?.getSessionId() ?? \"unknown\",\n\t\t\t\t});\n\t\t\t}\n\t\t\t// First load in this domain: replay the durable atoms into the store.\n\t\t\t// Sequences persisted by earlier instances of this session raise the\n\t\t\t// write-sequence floor before any new write can regenerate their ids.\n\t\t\tconst replay = ledger.load();\n\t\t\tfor (const atom of replay.atoms) {\n\t\t\t\tconst persistedSequence = writeFace.writeSequenceOf(atom.observationId);\n\t\t\t\tif (persistedSequence !== undefined) writeFace.advanceWriteSequenceFloor(persistedSequence);\n\t\t\t\ttry {\n\t\t\t\t\tstore.commit(atom);\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// A ledger atom the current store cannot accept (e.g. an unregistered\n\t\t\t\t\t// retention mode) must not fail the session — skip with a diagnostic.\n\t\t\t\t\tapi.logger?.warn(\"memory ledger atom could not be replayed into the store\", {\n\t\t\t\t\t\tmemoryId: atom.memoryId,\n\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (replay.corruptedLines > 0 || replay.duplicateSkipped > 0 || replay.unreadable) {\n\t\t\t\tapi.logger?.warn(\"memory ledger loaded with diagnostics\", {\n\t\t\t\t\tdomain: domainName,\n\t\t\t\t\tcorruptedLines: replay.corruptedLines,\n\t\t\t\t\tduplicateSkipped: replay.duplicateSkipped,\n\t\t\t\t\tunreadable: replay.unreadable,\n\t\t\t\t});\n\t\t\t}\n\t\t\tdomainLedgers.set(domainName, ledger);\n\t\t\t// 启动对账: 首个域的 ledger 重放完成后一次性触发 (fire-and-forget,\n\t\t\t// 不阻塞本工具调用; 失败只影响向量通道, 不影响锚点通道)。\n\t\t\tvectorProjection.reconcileOnce();\n\t\t\t// 机会式保留清扫 (M5, 记忆系统设计 §3.3): 首载重放完成后对本域已过期\n\t\t\t// 原子执行一次受控物理清理 (retention-expiry 授权, 最旧优先 ≤200 条,\n\t\t\t// ledger 重写 + 向量行删除 + store 逐出)。同步调用且 sweep 自吞错——\n\t\t\t// 装载绝不因清扫失败失败; 非干净结果只记一条有界 warn。\n\t\t\tconst sweepLedger = ledger;\n\t\t\tconst sweep = sweepExpiredMemories(\n\t\t\t\t{\n\t\t\t\t\tstore,\n\t\t\t\t\tpurgeGate,\n\t\t\t\t\tpurgeJournal,\n\t\t\t\t\tpurgeIndexReplica: vectorProjection.purgeMemories,\n\t\t\t\t\tpurgeCanonicalReplica: (memoryIds) => {\n\t\t\t\t\t\tconst purged = new Set(memoryIds);\n\t\t\t\t\t\tsweepLedger.rewrite(sweepLedger.atomsSnapshot().filter((atom) => !purged.has(atom.memoryId)));\n\t\t\t\t\t\tfor (const id of memoryIds) store.evict(id);\n\t\t\t\t\t},\n\t\t\t\t\tauthorizedBy: `${capabilityManifest.id}:retention-sweep`,\n\t\t\t\t\tnow,\n\t\t\t\t},\n\t\t\t\t{ owner: BUILTIN_MEMORY_OWNER, domain },\n\t\t\t);\n\t\t\tif (sweep.status === \"failed\" || sweep.status === \"purge_eligible\" || sweep.reason !== undefined) {\n\t\t\t\tapi.logger?.warn(\n\t\t\t\t\t\"memory retention sweep did not finish clean; expired atoms stay purge-eligible and are retried on the next domain load\",\n\t\t\t\t\t{\n\t\t\t\t\t\tdomain: domainName,\n\t\t\t\t\t\tstatus: sweep.status,\n\t\t\t\t\t\t...(sweep.reason === undefined ? {} : { reason: sweep.reason }),\n\t\t\t\t\t\t...(sweep.failedReplicas === undefined ? {} : { failedReplicas: sweep.failedReplicas }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn { domain, domainName, ledger };\n\t};\n\n\tconst machine = createMemoryCandidateMachine({ store, now });\n\tconst lifecycle = createMemoryLifecycleManager({\n\t\tpolicy: {\n\t\t\tpolicyVersion: \"lifecycle@1\",\n\t\t\thalfLifeMs: { session: 86_400_000, cycle: 604_800_000, \"long-term\": 2_592_000_000 },\n\t\t\tstaleAfterMs: { session: 172_800_000, cycle: 1_209_600_000, \"long-term\": 5_184_000_000 },\n\t\t\tarchiveAfterMs: { session: 604_800_000, cycle: 5_184_000_000, \"long-term\": 15_552_000_000 },\n\t\t\tbaselineAttention: 0.5,\n\t\t},\n\t\tnow,\n\t});\n\tconst scheduler = createMemoryScheduler({ now });\n\tscheduler.acquireForInstance({ instanceId: sessionId, owner: BUILTIN_MEMORY_OWNER });\n\t// 非工具召回路径设施 (2.4d6 S4 家族收口取证结论): 生产工具召回 (memory_recall\n\t// 工具与 auto-recall 钩子, 后者直连同一 recallExecute, D-071 自 sdk 迁入)\n\t// 只走 recallSemantically 语义管线; index → recallAgent →\n\t// schedulerApi.recall 这条链在本 capability 内不再被工具面调用 (schedulerApi\n\t// 的生产使用仅剩写入路径的 submitObservation/submitCandidate)。保留原因:\n\t// MemorySchedulerApiV1 facade 契约 (recall + egress 门)、recall-agent 与\n\t// recall-index 是公共 API (src/index.ts 导出) 和 memory-testkit 之上的测试\n\t// 设施 (scheduler-api / memory-suite-scope / coverage-branch-memory-recall\n\t// 等测试的直接消费者) — 有存续消费者, 非死代码。\n\tconst index = createMemoryRecallIndex({ store });\n\tconst recallAgent = createMemoryRecallAgent({\n\t\tscheduler,\n\t\tindex,\n\t\tpolicyDefaults: {\n\t\t\tcandidateBudget: 1000,\n\t\t\tmodelInspectionLimit: 20,\n\t\t\tfinalResultLimit: 20,\n\t\t\tmaxRelationHops: 2,\n\t\t\tmaxModelCalls: 3,\n\t\t\tmaxOutputTokens: 4000,\n\t\t\tmaxOutputBytes: 16_000,\n\t\t\tmaxRounds: 3,\n\t\t},\n\t\thostLimits: {\n\t\t\tcandidateBudget: 5000,\n\t\t\tmodelInspectionLimit: 100,\n\t\t\tfinalResultLimit: 100,\n\t\t\tmaxRelationHops: 5,\n\t\t\tmaxModelCalls: 10,\n\t\t\tmaxOutputTokens: 100_000,\n\t\t\tmaxOutputBytes: 1_000_000,\n\t\t\tmaxRounds: 10,\n\t\t},\n\t\tnow,\n\t});\n\tconst replicaRegistry = createMemoryReplicaRegistry();\n\treplicaRegistry.register({\n\t\treplicaId: \"memory-ledger\",\n\t\tkind: \"canonical\",\n\t\townerScope: BUILTIN_MEMORY_OWNER,\n\t\tcontractVersion: MEMORY_CONTRACT_VERSION,\n\t\thealthy: true,\n\t} satisfies MemoryReplicaV1);\n\t// 向量投影副本 (混合检索工程化, D-035): 恒注册 — purge 批次以向量索引确认为\n\t// 副本契约的一部分; 通道 off/disabled 时 index 分派为 no-op (索引不存在,\n\t// 无行可清), 行为见 vectorProjection.purgeMemories。\n\treplicaRegistry.register({\n\t\treplicaId: \"memory-vector-index\",\n\t\tkind: \"index\",\n\t\tcontractVersion: MEMORY_CONTRACT_VERSION,\n\t\townerScope: BUILTIN_MEMORY_OWNER,\n\t\thealthy: true,\n\t} satisfies MemoryReplicaV1);\n\tconst purgeGate = createMemoryPurgeGate({ registry: replicaRegistry, now });\n\tconst purgeJournal = createMemoryPurgeJournal();\n\tconst egressPolicy = createMemoryEgressPolicy({\n\t\tpolicyVersion: \"egress@1\",\n\t\tallowedSourceKinds: [\"tool\", \"entry\"],\n\t\tredactedPayloadFields: [],\n\t});\n\t// schedulerApi.recall 在生产工具面无调用点 (角色见上方\"非工具召回路径设施\"\n\t// 注释); 本 capability 的生产使用仅 submitObservation/submitCandidate (写入)。\n\tconst schedulerApi = createMemorySchedulerApi({\n\t\trecallAgent,\n\t\tmachine,\n\t\tlifecycle,\n\t\tpurgeGate,\n\t\tegressPolicy,\n\t\tfactInfoLookup: (memoryId) => {\n\t\t\tconst record = store.get(memoryId, { owner: BUILTIN_MEMORY_OWNER });\n\t\t\tif (!record) return undefined;\n\t\t\treturn {\n\t\t\t\tsourceRefs: record.atom.sourceRefs,\n\t\t\t\tpayload: record.atom.payload as Record<string, unknown>,\n\t\t\t};\n\t\t},\n\t});\n\t// Preference resolution/disambiguation over context-scoped recalls (2.4c/2.4d2):\n\t// stateless and deterministic — one instance per capability suffices.\n\tconst preferenceResolver = createPreferenceResolver();\n\tconst preferenceDisambiguator = createPreferenceDisambiguator();\n\t// Relation diffusion over the recall seeds (记忆网络接线, 2.4d4): a factory-\n\t// scoped deterministic network with one enabled one-hop adapter; disabled\n\t// adapters yield an explicit `disabled` result instead of silent degradation.\n\tconst memoryNetwork = createMemoryNetwork({\n\t\tadapters: [createRelationDiffusionAdapter({ maxHops: 1 })],\n\t});\n\n\t// ---- 语义召回通道状态机 (2.4d6 S1/S2; 拆分战役 slice 3b) ----\n\t// vectorEnsure 状态转换、装配分支 (服务/本地/下载/征询门) 与 dispose 闩锁\n\t// 已迁至 memory/vector-channel.ts: 共享闭包状态收拢为 channel 对象, 经 deps\n\t// 显式注入, 降级/投影经下方 vectorProjection (slice 3a) 上报。以下调用点\n\t// 全部薄委托。\n\tconst vectorChannelCtl = createMemoryVectorChannel({\n\t\tagentDir: context.agentDir,\n\t\tmemoryMode,\n\t\tlogger: api.logger,\n\t\thostOnnxRuntimeEntryPath: context.hostOnnxRuntimeEntryPath,\n\t\thostLancedbEntryPath: context.hostLancedbEntryPath,\n\t\thostTransformersEntryPath: context.hostTransformersEntryPath,\n\t\tinferenceServicePort: context.inferenceService?.port,\n\t\tinferenceServiceSpawnImpl: context.inferenceService?.spawnImpl,\n\t\tinferenceServiceModelsInPlace: context.inferenceService?.modelsInPlace,\n\t\tenablingOverride,\n\t\tinjectedComponents,\n\t\t// vectorProjection 声明在本对象之后; 委托箭头只在 download 运行期触达,\n\t\t// 与下方 supersededMemoryIds 依赖同构 (构造期不执行)。\n\t\tresetReconcile: () => vectorProjection.resetReconcile(),\n\t\treconcileOnce: () => vectorProjection.reconcileOnce(),\n\t});\n\n\t// 写入侧向量投影管线 (拆分战役 slice 3a): 串行队列、upsert/purge 埋点与启动\n\t// 对账搬至 memory/vector-projection.ts; 状态机归 memory/vector-channel.ts\n\t// (slice 3b), 投影经只读 deps 使用, degraded 转换经 markDegraded 回调上报。\n\tconst vectorProjection = createMemoryVectorProjection({\n\t\tvectorEnabled: () => vectorChannelCtl.enabled(),\n\t\tensureChannel: () => vectorChannelCtl.ensure(),\n\t\treadyChannel: () => vectorChannelCtl.readyChannel(),\n\t\tisChannelActive: () => {\n\t\t\tconst channelState = vectorChannelCtl.rawState();\n\t\t\treturn channelState === \"ready\" || channelState === \"degraded\";\n\t\t},\n\t\tisDisposed: () => vectorChannelCtl.isDisposed(),\n\t\t// 反向清理的跨进程守卫 (2026-10-07 终审): 只读扫描 owner 全部域账本的\n\t\t// memoryId 并集 (盘面扫描, 不触碰进程内 ledger 快照)。\n\t\trefreshCanonicalMemoryIds: () =>\n\t\t\tscanOwnerLedgerMemoryIds({ agentDir: context.agentDir, owner: BUILTIN_MEMORY_OWNER }),\n\t\tmarkDegraded: () => vectorChannelCtl.markDegraded(),\n\t\tlogger: api.logger,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tstore,\n\t\t// writeFace 声明在本对象之后; 委托箭头只在对账运行期触达 (构造期不执行)。\n\t\tsupersededMemoryIds: () => writeFace.supersededMemoryIds(),\n\t\tstatementOf,\n\t\ttagFacetsOf,\n\t});\n\n\t// ---- 写入面 (拆分战役 slice 5) ----\n\t// memory_write 工具、语义合并探测、写入 atom 构造与写后自动升档旁路已迁至\n\t// memory/write-face.ts: 写序计数/探测降级告警闩/升档闩归 write-face 工厂\n\t// 所有, 经 deps 显式注入; 状态机与写侧投影经对象只读消费。supersededMemoryIds\n\t// 供上方 vectorProjection 的对账 deps 消费 (构造期不执行, 依赖同构)。\n\tconst writeFace = createMemoryWriteFace({\n\t\tlogger: api.logger,\n\t\tregisterTool: (definition) => api.registerTool(definition),\n\t\tpublish: api.publish,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tsessionId,\n\t\tmanifest: capabilityManifest,\n\t\tcontractVersion: MEMORY_CONTRACT_VERSION,\n\t\tmemoryMode,\n\t\tagentDir: context.agentDir,\n\t\tnow,\n\t\tstore,\n\t\tschedulerApi,\n\t\tvectorProjection,\n\t\tvectorChannelCtl,\n\t\tresolveDomain,\n\t\tassertNonEmptyString,\n\t\tmemoryToolInput,\n\t\tidentityHash,\n\t\tstatementOf,\n\t\ttagFacetsOf,\n\t});\n\n\t// ---- 语义召回管线 (拆分战役 slice 4) ----\n\t// 双通道查询、RRF 融合、egress 门、语义召回与召回工具已迁至\n\t// memory/recall-pipeline.ts: 状态机经 vectorChannelCtl 只读面消费\n\t// (warming/ensure/征询/失败/degraded), 写侧投影的读侧等待经 settleProjection,\n\t// capability 模块级纯函数经 deps 注入避免双头定义。recallTool 进 registrations,\n\t// recallExecute 同时被钩子面 (slice 7) 直连。\n\tconst recallPipeline = createMemoryRecallPipeline({\n\t\tlogger: api.logger,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tsessionId,\n\t\tstore,\n\t\tresolveDomain,\n\t\tegressPolicy,\n\t\tpreferenceResolver,\n\t\tpreferenceDisambiguator,\n\t\tmemoryNetwork,\n\t\twarming: () => vectorChannelCtl.warming(),\n\t\tensureChannel: () => vectorChannelCtl.ensure(),\n\t\tdeclined: () => vectorChannelCtl.declined(),\n\t\tconsentAsk: () => vectorChannelCtl.consentAsk(),\n\t\tfailure: () => vectorChannelCtl.failure(),\n\t\trawState: () => vectorChannelCtl.rawState(),\n\t\tmarkDegraded: () => vectorChannelCtl.markDegraded(),\n\t\trecoverDegraded: () => vectorChannelCtl.recoverDegraded(),\n\t\tsettleProjection: () => vectorProjection.settle(),\n\t\tmemoryToolInput,\n\t\tassertNonEmptyString,\n\t\tisPlainObject,\n\t\tidentityHash,\n\t\tstatementOf,\n\t\tunwrapEgressStatement,\n\t\tregisterTool: (definition) => api.registerTool(definition),\n\t});\n\n\t// ---- 命令面 (拆分战役 slice 6) ----\n\t// memory_list/forget 工具、/memory 与 /promote 命令、memory_enable 征询执行\n\t// 面与 memory.scheduler 声明已迁至 memory/command-face.ts: 列表/删除/晋升/\n\t// 征询的命令执行面经 deps 显式注入, decline/download 仍薄委托 vectorChannelCtl\n\t// (slice 3b 先例); 升档声明状态经 writeFace 的只读面消费。\n\tconst commandFace = createMemoryCommandFace({\n\t\tregisterTool: (definition) => api.registerTool(definition),\n\t\tregisterCommand: (definition) => api.registerCommand(definition),\n\t\tpublish: api.publish,\n\t\tcapabilities: api.capabilities,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tsessionId,\n\t\tmanifest: capabilityManifest,\n\t\tagentDir: context.agentDir,\n\t\tmemoryMode,\n\t\tnow,\n\t\tstore,\n\t\tpurgeGate,\n\t\tpurgeJournal,\n\t\tvectorProjection,\n\t\tvectorChannelCtl,\n\t\tresolveDomain,\n\t\tassertNonEmptyString,\n\t\tmemoryToolInput,\n\t\tstatementOf,\n\t\tunwrapEgressStatement,\n\t\ttierUpgradePending: writeFace.tierUpgradePending,\n\t\tclearTierUpgrade: writeFace.clearTierUpgrade,\n\t});\n\n\t// ---- 注入钩子 (拆分战役 slice 7) ----\n\t// auto-recall 与 assistant 偏好卡已迁至 memory/hooks.ts: 钩子经 api 注册面\n\t// 订阅 (loop hook), 召回执行闭包经 deps 注入。bash 失败教训沉淀已停用\n\t// (记忆归档与整理设计 §14 裁决 1), 其职责由归档整理器承担。\n\tconst hooks = createMemoryHooks({\n\t\tlogger: api.logger,\n\t\tregisterLoopHook: api.registerLoopHook,\n\t\tsession: api.session,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tagentDir: context.agentDir,\n\t\tnow,\n\t\tisPlainObject,\n\t\tresolveSessionDomain: () => resolveSessionDomain(api),\n\t\trecallExecute: recallPipeline.recallExecute,\n\t\tvectorChannelCtl,\n\t});\n\n\t// ---- 归档整理器 (记忆归档与整理设计 §5-§7) ----\n\t// 归档即后台整理: session.archived 事件观察 + 启动 sweep 两个触发, 提交、\n\t// 幂等、journal 与暂停/续跑语义归 memory/curator.ts。宿主未开放归档面\n\t// (context 与 api.host 都无 sessionArchive) 时两个触发都不注册。\n\tconst curator = createMemoryCurator({\n\t\tapi,\n\t\tagentDir: context.agentDir,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tnow,\n\t\tmanifest: capabilityManifest,\n\t\tstore,\n\t\tresolveDomain,\n\t\tvectorProjection,\n\t\tidentityHash,\n\t\tsessionArchive: context.sessionArchive ?? api.host?.sessionArchive,\n\t});\n\n\tconst registrations = [\n\t\t// 首位 = 宿主反向 dispose 时的末位: 先拆工具/命令/钩子等消费者, 最后关\n\t\t// 底层通道, 避免消费者在通道已关后仍触发向量操作报错。释放本体\n\t\t// (capabilityTeardown, slice 3b) 在 memory/vector-channel.ts。\n\t\t{\n\t\t\tid: \"memory:capability-teardown\",\n\t\t\tkind: \"capability-teardown\",\n\t\t\tdispose: () => vectorChannelCtl.dispose(),\n\t\t},\n\t\twriteFace.writeTool,\n\t\trecallPipeline.recallTool,\n\t\tcommandFace.listTool,\n\t\tcommandFace.forgetTool,\n\t\tcommandFace.enableTool,\n\t\tcommandFace.memoryCommand,\n\t\tcommandFace.promoteCommand,\n\t\tcommandFace.schedulerCapability,\n\t\thooks.autoRecallHook,\n\t\thooks.preferenceCardHook,\n\t\t...curator.registrations,\n\t];\n\treturn {\n\t\tregistrations,\n\t\tsettleVectorWork: async () => {\n\t\t\tawait vectorProjection.settle();\n\t\t},\n\t\tvectorState: (): \"off\" | MemoryCapabilityStateV1 => vectorChannelCtl.state(),\n\t\t// 触发惰性 enabling (已注入组件时已就绪) 并等待其落定: ready 或结构化失败。\n\t\tenablingOutcome: () => vectorChannelCtl.enablingOutcome(),\n\t\tteardown: () => vectorChannelCtl.dispose(),\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party builtin memory capability (统一修复轮 A, 方案系统设计 §6.1 + §11,\n * 方案实施计划 §11 A 路) — the model-facing write/recall/list/forget surface\n * over the M5 Memory Foundation.\n *\n * Every operation is suite-scoped by construction: the suiteId comes from the\n * session's suite binding entry (SUITE_SESSION_ENTRY_TYPE, written by the sdk\n * at session creation) and is NEVER a tool parameter, so the model cannot\n * widen or switch its memory domain (防越权). Sessions without a binding fall\n * back to the \"legacy\" domain with a diagnostic. Writes go through the\n * scheduler facade (observation → candidate → committed) plus a durable JSONL\n * ledger append (src/memory/ledger.ts, the store's persistent replica); recall\n * runs through the memory-recall-agent with the suiteId passthrough filter and\n * the egress gate; forget goes through the canonical purge gate\n * (user-immediate) and journal, physically rewriting the ledger (forget 后真\n * 物理删除).\n *\n * Domain resolution is LAZY, per tool call (统一修复轮 B1 复审修复): the sdk\n * appends the suite binding entry only after `new AgentSession` returns (the\n * constructor's synchronous runtime build already runs this factory), so a\n * factory-time resolution always saw an empty branch and every new session\n * fell back to the legacy domain. Instead, each tool handler resolves the\n * domain at call time — the binding entry is on the branch by then (creation\n * appends it; resumed sessions carry it in their history) — and the per-domain\n * ledger is created, loaded, and replayed into the store on the first call in\n * that domain (Map<domain, ledger> cache, no memoization of the domain\n * itself). The store stays one per-capability-instance singleton across\n * domains: the atom `suiteId` field carries the read boundary; the ledger is\n * only the per-domain durable replica.\n *\n * Concurrency envelope (统一修复轮 H1, #7 深度修复; WP-F 关洞修复): ledger\n * appends AND the forget path's full-file rewrite serialize competing\n * processes through the ledger's `.lock` sibling file (exclusive create +\n * poll, 5 s timeout, stale-lock stealing — src/memory/ledger.ts), and both\n * write paths run open → write → fsync → close, so a hard crash cannot lose\n * a write that returned to its caller. A lock timeout or IO/fsync failure\n * throws out of the tool handler, so the model sees the error instead of a\n * silently lost write. Remaining boundaries: the lock is atomic only on\n * local filesystems; a rewrite publishes the calling process's in-memory\n * view without merging rows another process appended after its last load\n * (the forget caller owns that reconciliation); fsync does not cover\n * directory entries, so a crash before rewrite's rename leaves the previous\n * file intact; an append whose fsync failed stays unacknowledged though it\n * may already be readable — the loader's duplicate tolerance covers an\n * unacknowledged retry.\n *\n * Global mode gate (2.4d6 S1, 记忆系统语义化重设计 §3): `memory.mode` is\n * `\"off\"` (default) | `\"light\"` | `\"full\"`; off means the whole memory family\n * is NOT registered (the suite membership skips the plugin; the factory\n * itself returns zero registrations for direct callers). light/full run an\n * enabling state machine (local checks → model load/download → smoke →\n * ready; failure → failed with a four-option action list and the effective\n * mode falls back to off for this instance).\n *\n * Semantic recall (2.4d6 S2, 设计 §4): memory_recall has exactly one\n * retrieval path — embed → KNN depth50 + FTS depth50 → RRF k=60 top20 →\n * cross-encoder rerank → store lookup (owner/suite/scope/expiry). The legacy\n * tag-wordform bridge (query-token → tag-facet anchors, recency fallback\n * page) is retired as a retrieval semantic; tags still ride the FTS body and\n * the memory_list management face. Degradation ladder (never thrown at the\n * model): rerank failure → RRF order; vector failure → FTS-only with\n * recency ordering; FTS/index failure → KNN-only; both channels down →\n * recency enumeration over the domain; total failure → degraded packet.\n * `memoryIdEquals`-style primary-key lookup survives as the exact-id fast\n * path (reference semantics, not retrieval).\n *\n * Semantic write merge (2.4d6 S3, 设计 §5 + 实施计划 S3 标定定版): in mode\n * \"full\" every memory_write probes the projection BEFORE the canonical commit\n * (embed + same-owner KNN top-5) because atoms are immutable — the outcome's\n * relations must ride the atom's one commit. Merge condition (calibrated on\n * bge-m3): cos ≥ 0.72, or 0.55 ≤ cos < 0.72 with a case-insensitive tag\n * overlap. A merge commits the NEW atom with a one-way `supersedes` relation\n * to the neighbor (the old entry keeps its memoryId and stays addressable via\n * primary-key lookup) while the projection upserts the new row and removes the\n * superseded one; startup reconciliation never re-adds superseded rows.\n * 0.55 ≤ cos < 0.72 without a tag overlap is the conflict band: both entries\n * stay, and the new atom carries one-way `conflict` relations. Below that (or\n * no neighbor): a plain new entry. bge-small-zh similarity distributions\n * overlap (标定: 余弦不可用作去重信号) → light mode never probes and stays\n * byte-identical to the pre-S3 behavior. Recall filters superseded entries\n * after the store lookup (only while their successor is among the candidates,\n * so forgetting the successor revives the old entry). The Foundation\n * (owner, observationId) idempotency is untouched: replays never consume a\n * probe outcome.\n */\nimport { readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type {\n\tMemoryCapabilityOverrideV1,\n\tMemoryModeV1,\n\tMemoryStorageComponentsV1,\n\tMemoryVectorComponentsOverrideV1,\n\tSessionArchiveHostV1,\n} from \"@agent-forge/plugin-sdk\";\nimport {\n\ttype CapabilityAPI,\n\ttype DisposableRegistration,\n\tEXPERIMENTAL_PUBLIC_API_VERSION,\n} from \"@agent-forge/plugin-sdk\";\n\n// 记忆公共契约的权威定义处已是 plugin-sdk(D-075 S4-4 第一批迁入);此处 re-export\n// 维持宿主历史导出面(宿主第二批收口后由宿主 re-export SDK)。\nexport {\n\tMEMORY_RECALL_TOOL_NAME,\n\ttype MemoryCapabilityOverrideV1,\n\ttype MemoryEnablingOverrideV1,\n\ttype MemoryModeV1,\n\ttype MemoryStorageComponentsV1,\n\ttype MemoryVectorComponentsOverrideV1,\n} from \"@agent-forge/plugin-sdk\";\n// 拆分战役 slice 1/3b: 征询持久化(enabling.ts 征询域)与向量常量/状态类型\n// (vector-channel.ts)随模块迁出,经 re-export 维持 capability.ts 的历史\n// 导出面(index.ts `export *` 与 entry.ts / inference-service-main.ts 的\n// 既有 import 不变;vector-channel.ts 不进 index.ts,slice 2 先例)。\nexport {\n\tMEMORY_AGENT_DIR_CONFIG_RELATIVE_PATH,\n\tMEMORY_CONSENT_DECLINED_VALUE,\n\twriteMemoryConsentDeclined,\n\twriteMemorySettingsMode,\n} from \"./memory/enabling.ts\";\n// 拆分战役 slice 7: auto-recall 注入标记/免责行随钩子面迁入 hooks.ts, 经\n// re-export 维持 capability.ts 的历史导出面 (index.ts `export *` 与既有 import\n// 不变; hooks.ts 本体不进 index.ts, recall-pipeline.ts 先例)。lessons 开关解析\n// 已随实时教训停用一并移除 (记忆归档与整理设计 §14 裁决 1)。\nexport {\n\tMEMORY_AUTO_RECALL_DEADLINE_MS,\n\tMEMORY_AUTO_RECALL_DISCLAIMER,\n\tMEMORY_AUTO_RECALL_MARKER,\n} from \"./memory/hooks.ts\";\n// 拆分战役 slice 4: MEMORY_TOOLS_GUIDE 随召回管线迁入 recall-pipeline.ts, 经\n// re-export 维持 capability.ts 的历史导出面 (宿主与测试的既有 import 不变;\n// recall-pipeline.ts 本体不进 index.ts, vector-channel.ts slice 2 先例)。\nexport { MEMORY_TOOLS_GUIDE } from \"./memory/recall-pipeline.ts\";\nexport {\n\ttype MemoryCapabilityStateV1,\n\ttype MemoryConsentNeededV1,\n\ttype MemoryEnablingFailureV1,\n\tVECTOR_DB_DIRNAME,\n\tVECTOR_MODEL_CACHE_DIRNAME,\n\tVECTOR_RERANKER_MODEL_ID,\n} from \"./memory/vector-channel.ts\";\n// 拆分战役 slice 5: 档位自动升级阈值随写入面迁入 write-face.ts, 经 re-export\n// 维持 capability.ts 的历史导出面。\nexport { MEMORY_TIER_UPGRADE_STORE_THRESHOLD } from \"./memory/write-face.ts\";\n\nimport { createMemoryCandidateMachine } from \"./memory/candidates.ts\";\nimport { createMemoryCommandFace } from \"./memory/command-face.ts\";\nimport { createMemoryCurator } from \"./memory/curator.ts\";\nimport { createMemoryEgressPolicy } from \"./memory/egress-policy.ts\";\nimport type { MemoryAtomV1 } from \"./memory/foundation.ts\";\nimport { createMemoryHooks } from \"./memory/hooks.ts\";\nimport { createDurableMemoryLedger, type DurableMemoryLedgerV1, scanOwnerLedgerMemoryIds } from \"./memory/ledger.ts\";\nimport { createMemoryLifecycleManager } from \"./memory/lifecycle.ts\";\nimport { createMemoryNetwork, createRelationDiffusionAdapter } from \"./memory/memory-network.ts\";\nimport { createPreferenceDisambiguator } from \"./memory/preference-disambiguator.ts\";\nimport { createPreferenceResolver } from \"./memory/preference-resolver.ts\";\nimport { createMemoryPurgeGate, createMemoryReplicaRegistry, type MemoryReplicaV1 } from \"./memory/purge.ts\";\nimport { createMemoryPurgeJournal } from \"./memory/purge-journal.ts\";\nimport { createMemoryRecallAgent } from \"./memory/recall-agent.ts\";\nimport { createMemoryRecallIndex } from \"./memory/recall-index.ts\";\nimport { createMemoryRecallPipeline } from \"./memory/recall-pipeline.ts\";\nimport { sweepExpiredMemories } from \"./memory/retention-sweep.ts\";\nimport { createMemoryScheduler } from \"./memory/scheduler.ts\";\nimport { createMemorySchedulerApi } from \"./memory/scheduler-api.ts\";\nimport { createFirstPartyRetentionRegistry, createMemoryStore } from \"./memory/store.ts\";\nimport { type SuiteMemoryDomainV1, suiteMemoryDomainName } from \"./memory/suite-memory.ts\";\nimport { MEMORY_CONTRACT_VERSION_V2 } from \"./memory/transfer.ts\";\nimport type { MemoryCapabilityStateV1, MemoryEnablingFailureV1 } from \"./memory/vector-channel.ts\";\nimport { createMemoryVectorChannel } from \"./memory/vector-channel.ts\";\nimport { createMemoryVectorProjection } from \"./memory/vector-projection.ts\";\nimport { createMemoryWriteFace, TAG_FACET_NAMESPACE } from \"./memory/write-face.ts\";\n\nexport const capabilityManifest = {\n\tid: \"agent-forge.builtin.memory\",\n\tversion: \"0.1.0\",\n\tapiVersion: EXPERIMENTAL_PUBLIC_API_VERSION,\n\trequiredCapabilities: [\"session\", \"events\", \"tools\"],\n\tprovides: [{ id: \"memory.scheduler\", version: 1, kind: \"service\" }],\n} as const;\n\n/**\n * 解析后的全局模式 (2.4d6 S1)。`invalidEnvValue` 非空 = 配置的环境值非法,\n * 已 fail-closed 回 off, 调用方负责以此输出一次 warn; `invalidSettingsValue`\n * 非空 = settings.json 的 `memory.mode` 非法, 同为 fail-closed off 并输出一次\n * 诊断; `legacyEnvUsed` = 模式由旧别名 `AGENT_FORGE_MEMORY_VECTOR` 决定 (兼容\n * 期: 仅当 `AGENT_FORGE_MEMORY_MODE` 与 settings 均未定档时生效, 一个发布周期\n * 后移除)。\n */\nexport interface MemoryModeResolutionV1 {\n\treadonly mode: MemoryModeV1;\n\treadonly invalidEnvValue?: string;\n\treadonly invalidSettingsValue?: string;\n\treadonly legacyEnvUsed?: boolean;\n}\n\nconst isMemoryModeV1 = (value: string): value is MemoryModeV1 =>\n\tvalue === \"off\" || value === \"light\" || value === \"full\";\n\n/**\n * memory.mode 解析 (2.4d6 S1)。优先级: context 显式值 → 环境变量\n * `AGENT_FORGE_MEMORY_MODE` → settings.json `memory.mode` (settingsMode 参, 持\n * 久配置面) → 旧别名 `AGENT_FORGE_MEMORY_VECTOR` (兼容期) → 默认 light\n * (2026-10-05 用户裁决翻转默认 off→light, 对齐主流编程助手开箱即用方向)。env 是\n * 临时覆盖、settings 是持久配置 (env > 文件, 沿用本仓 suite 解析先例)。任何\n * 非法配置值 fail-closed 为 off 并在结果中携带原值供调用方告警一次, 绝不静默\n * 改档或意外下载。\n */\nexport function resolveMemoryMode(\n\texplicitMode: string | undefined,\n\tenv: Readonly<Record<string, string | undefined>> = process.env,\n\tsettingsMode?: string,\n): MemoryModeResolutionV1 {\n\tif (explicitMode !== undefined) {\n\t\tif (isMemoryModeV1(explicitMode)) return { mode: explicitMode };\n\t\treturn { mode: \"off\", invalidEnvValue: explicitMode };\n\t}\n\tconst configured = env.AGENT_FORGE_MEMORY_MODE?.trim().toLowerCase();\n\tif (configured !== undefined && configured !== \"\") {\n\t\tif (isMemoryModeV1(configured)) return { mode: configured };\n\t\treturn { mode: \"off\", invalidEnvValue: configured };\n\t}\n\t// 持久配置面: settings.json memory.mode。设置但非法同样 fail-closed, 不再\n\t// 回落旧别名 (与非法 env 的先例一致)。\n\tconst fromSettings = settingsMode?.trim().toLowerCase();\n\tif (fromSettings !== undefined && fromSettings !== \"\") {\n\t\tif (isMemoryModeV1(fromSettings)) return { mode: fromSettings };\n\t\treturn { mode: \"off\", invalidSettingsValue: fromSettings };\n\t}\n\t// 兼容期别名: AGENT_FORGE_MEMORY_VECTOR (混合检索工程化的旧开关), 语义并入\n\t// AGENT_FORGE_MEMORY_MODE, 仅当新变量与 settings 均未定档时生效; 一个发布\n\t// 周期后删除。\n\tconst legacy = env.AGENT_FORGE_MEMORY_VECTOR?.trim().toLowerCase();\n\tif (legacy !== undefined && legacy !== \"\") {\n\t\tif (isMemoryModeV1(legacy)) return { mode: legacy, legacyEnvUsed: true };\n\t\treturn { mode: \"off\", invalidEnvValue: legacy, legacyEnvUsed: true };\n\t}\n\treturn { mode: \"light\" };\n}\n\n/** Host-provided factory context; provided by the host session assembly (sdk suite membership). */\nexport interface MemoryCapabilityContext {\n\t/** Agent home directory — roots the durable ledger under `<agentDir>/memory/`. */\n\treadonly agentDir: string;\n\t/**\n\t * 宿主已解析的 onnxruntime-node 入口绝对路径 (D-075 安装店重依赖可见性):\n\t * 安装店副本无 node_modules, 插件内 createRequire 解析不到; 宿主装载器把\n\t * hostDependencyPaths 注入 manifest config, entry 提取后经本字段传入。\n\t * 缺省 (源码/工作区直载) 走插件内双通道自解析。\n\t */\n\treadonly hostOnnxRuntimeEntryPath?: string;\n\t/** 同上——@lancedb/lancedb 入口路径 (向量索引运行时按绝对路径原生 import)。 */\n\treadonly hostLancedbEntryPath?: string;\n\t/** 同上——@huggingface/transformers 入口路径 (embedding/reranker 运行时用)。 */\n\treadonly hostTransformersEntryPath?: string;\n\t/**\n\t * 记忆全局档位 (2.4d6 S1)。缺省解析顺序: 本字段 → 环境变量\n\t * `AGENT_FORGE_MEMORY_MODE` → {@link MemoryCapabilityContext.memory.settingsMode}\n\t * → 旧别名 `AGENT_FORGE_MEMORY_VECTOR` (兼容期) → 默认 off (整个家族不注册)。\n\t * 装配方 (sdk) 可经本字段显式定档。\n\t */\n\treadonly memory?: {\n\t\treadonly mode?: MemoryModeV1;\n\t\t/**\n\t\t * settings.json `memory.mode` 的原样值 (持久配置面, 优先级低于 env);\n\t\t * 类型面只允许合法档位, 手改文件的非法值原样透传并由\n\t\t * {@link resolveMemoryMode} fail-closed 处理。\n\t\t */\n\t\treadonly settingsMode?: string;\n\t};\n\t/**\n\t * 测试专用注入 (架构宪法: deterministic mock AI 门禁)。经装配上下文携带时,\n\t * 装配方原样透传给工厂; 与 {@link createCapabilityWithVectorComponents}\n\t * 的第三参语义一致, 第三参优先。\n\t */\n\treadonly vectorComponents?: MemoryCapabilityOverrideV1;\n\t/**\n\t * 共享推理服务装配缝 (Slice B2, 记忆共享推理服务设计 §3.1/§3.3/§3.6)。\n\t * 缺省 (生产) = 真实路径: 模型在位时装配经 TCP loopback 走常驻服务,\n\t * 连不上则懒 spawn 插件 bin (`agent-forge-memory-inference`), 重连失败按\n\t * enabling failed 呈现 (裁决 A: 不回退本地装配)。测试注入替换对应环节\n\t * (deterministic 门禁): `port` 直连测试服务、`spawnImpl` 替换进程拉起、\n\t * `modelsInPlace` 声明模型在位 (跳过文件检查, 免写假权重文件)。\n\t * loadImpl enabling 缝与 vectorComponents 注入仍走本地装配路径 (既有语义)。\n\t */\n\treadonly inferenceService?: {\n\t\treadonly port?: number;\n\t\treadonly spawnImpl?: (\n\t\t\tagentDir: string,\n\t\t\tmode: \"light\" | \"full\",\n\t\t\tport: number,\n\t\t\t/** spawn 异步失败 (EACCES/ENOMEM 等) 的回调; 缺省实现经 child 'error' 事件馈入。 */\n\t\t\tonError?: (error: Error) => void,\n\t\t) => Promise<void>;\n\t\treadonly modelsInPlace?: boolean;\n\t};\n\t/**\n\t * 记忆底层组件注入 (扩展位盘点 A1/A2 的宿主装配通道): store/ledger 工厂与\n\t * 向量组件公共契约, 缺省成员走内置默认实现。装配方经\n\t * `CreateAgentSessionOptions.memoryCapability.storage` 携带。\n\t */\n\treadonly storage?: MemoryStorageComponentsV1;\n\t/**\n\t * 会话归档协调面 (记忆归档与整理设计 §4/§8): 整理器读归档会话条目与回写\n\t * curation 状态的唯一通道。缺省回落宿主服务 `api.host.sessionArchive`(生产\n\t * 装配路径);两者都缺席 = 宿主不开放归档,整理器的两个触发(归档事件观察与\n\t * 启动 sweep)都不注册,记忆家族其余能力不受影响。本字段同时是测试注入缝\n\t * (deterministic mock AI 门禁:curator 测试经它注入 fake archive)。\n\t */\n\treadonly sessionArchive?: SessionArchiveHostV1;\n}\n\nconst isVectorComponentsOverride = (\n\toverride: MemoryCapabilityOverrideV1,\n): override is MemoryVectorComponentsOverrideV1 => \"embedProvider\" in override && \"vectorIndex\" in override;\n\n/**\n * 默认档判定 (征询拒绝只抑制默认档): 显式值、env、settings、旧别名四层全部\n * 未定档时, 模式来自出厂默认档 (light)。与 resolveMemoryMode 的优先级链同构,\n * 不改 resolver 返回面。\n */\nexport function memoryModeSourceIsDefault(\n\texplicitMode: string | undefined,\n\tenv: Readonly<Record<string, string | undefined>>,\n\tsettingsMode?: string,\n): boolean {\n\treturn (\n\t\texplicitMode === undefined &&\n\t\t(env.AGENT_FORGE_MEMORY_MODE?.trim() ?? \"\") === \"\" &&\n\t\t(env.AGENT_FORGE_MEMORY_VECTOR?.trim() ?? \"\") === \"\" &&\n\t\t(settingsMode?.trim() ?? \"\") === \"\"\n\t);\n}\n\nfunction assertNonEmptyString(value: unknown, label: string): asserts value is string {\n\tif (typeof value !== \"string\" || value.trim().length === 0) throw new Error(`${label} must be a non-empty string`);\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * 双约定工具输入读取(对齐 subagent-delegate 的 objectInput):capability invoke\n * 面单参约定下第一参即输入(第二参是宿主注入的 toolExecutionContext),legacy 5 参\n * 约定(toolCallId 字符串打头)下输入在第二参。生产装配恒向 runtime invoke 面注入\n * toolExecutionContext 作为 execute 第二参(公共契约),因此\"第二参非 undefined 即\n * 输入\"的判定会把 context 误当输入(content/query 等读成 undefined)。改按形状判定:\n * 第一参是普通对象即取第一参,否则看第二参;两者皆非对象时返回空记录,交由各工具\n * 的字段断言报错。\n */\nfunction memoryToolInput(first: unknown, second: unknown): Record<string, unknown> {\n\tconst primary = isPlainRecord(first) ? first : second;\n\treturn isPlainRecord(primary) ? primary : {};\n}\n\n/** FNV-1a 32-bit — deterministic identity from the given value (code-memory 同构). */\nfunction identityHash(value: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (let index = 0; index < value.length; index += 1) {\n\t\thash ^= value.charCodeAt(index);\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(36);\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Session protocol key of the suite binding entry (方案设计 §10.1). The value\n * mirrors the authoritative `SUITE_SESSION_ENTRY_TYPE` in\n * src/suites/suite-loader.ts — pinned by a deterministic test in\n * test/capabilities-builtin.test.ts. Declared locally so the capability module\n * graph stays free of the assembler's bundled-loader dependency chain.\n */\nconst SUITE_SESSION_ENTRY_TYPE = \"suite\";\n\n/**\n * Owner (isolation principal) of every atom this capability writes. The\n * Foundation owner is the store/facade isolation identity; this product ships\n * one local user per agentDir, so one stable owner id partitions the ledger\n * directory `<agentDir>/memory/<owner>/ledger-<suiteId|\"legacy\">.jsonl`.\n */\nexport const BUILTIN_MEMORY_OWNER = \"local-user\";\n\n/** Contract version written by this capability (@2 atoms carry suiteId). */\nconst MEMORY_CONTRACT_VERSION = MEMORY_CONTRACT_VERSION_V2;\n\n/**\n * Suite binding entry ids already warned about (统一修复轮终审 minor 3):\n * resolveSessionDomain runs on EVERY memory tool call, so without this\n * module-level set one malformed binding entry would repeat the warning on\n * each call and flood the log.\n */\nconst malformedBindingWarned = new Set<string>();\n\n/**\n * Resolves the session's suite binding domain from the branch entries: the\n * LAST suite entry wins (the sdk appends one at session creation). A binding\n * with a malformed payload counts as unbound — the legacy fallback is\n * fail-safe (its atoms are invisible to every real suite) and a diagnostic is\n * logged when the logger capability is available. Called per tool call —\n * never captured at factory time (统一修复轮 B1: the binding entry is appended\n * after the session constructor ran this factory).\n */\nfunction resolveSessionDomain(api: CapabilityAPI): SuiteMemoryDomainV1 {\n\tconst entries = api.session?.getBranchEntries() ?? [];\n\tfor (let index = entries.length - 1; index >= 0; index -= 1) {\n\t\tconst entry = entries[index];\n\t\tif (entry.type !== \"custom\" || entry.customType !== SUITE_SESSION_ENTRY_TYPE) continue;\n\t\tconst data = entry.data;\n\t\tconst suiteId = isPlainObject(data) ? data.suiteId : undefined;\n\t\tif (typeof suiteId === \"string\" && suiteId.trim() !== \"\") {\n\t\t\treturn { kind: \"suite\", suiteId };\n\t\t}\n\t\tif (!malformedBindingWarned.has(entry.id)) {\n\t\t\tmalformedBindingWarned.add(entry.id);\n\t\t\tapi.logger?.warn(\"suite binding entry has a malformed payload; falling back to the legacy memory domain\", {\n\t\t\t\tentryId: entry.id,\n\t\t\t});\n\t\t}\n\t\treturn { kind: \"legacy\" };\n\t}\n\treturn { kind: \"legacy\" };\n}\n\n/** Recency-first payload projection: unwraps the `{ statement }` payload convention. */\nfunction statementOf(payload: unknown): string {\n\tif (isPlainObject(payload) && typeof payload.statement === \"string\") return payload.statement;\n\treturn JSON.stringify(payload);\n}\n\n/** The egress gate re-derives statements as payload JSON; unwrap for the model face. */\nfunction unwrapEgressStatement(statement: string): string {\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(statement);\n\t\tif (isPlainObject(parsed) && typeof parsed.statement === \"string\") return parsed.statement;\n\t} catch {\n\t\t// Not payload JSON — surface it verbatim.\n\t}\n\treturn statement;\n}\n\nfunction tagFacetsOf(atom: MemoryAtomV1): string[] {\n\treturn atom.facets\n\t\t.filter((facet) => facet.namespace === TAG_FACET_NAMESPACE && facet.key === \"tag\")\n\t\t.map((facet) => facet.value);\n}\n\n/**\n * Creates the builtin memory capability: four tools (memory_write,\n * memory_recall, memory_list, memory_forget) over a per-session Foundation\n * stack whose durable replica is the per-domain JSONL ledger under\n * `<agentDir>/memory/<owner>/ledger-<domain>.jsonl`, resolved lazily at each\n * tool call (统一修复轮 B1).\n *\n * `memory.mode` gates the whole family (2.4d6 S1): a resolved mode of \"off\"\n * registers NOTHING (zero tools, zero commands, zero events) — the factory\n * returns an empty registration list and logs the one-line disabled\n * declaration. suite capability membership decides earlier at the assembly\n * level (设计 §3.2 \"禁用 = 不注册\").\n *\n * `override` is the test-only seam (deterministic mock AI 门禁): full vector\n * components skip the real transformers/lancedb assembly entirely; enabling\n * seams keep the real assembly but replace the transformers loader.\n */\nexport function createMemoryCapability(\n\tapi: CapabilityAPI,\n\tcontext: MemoryCapabilityContext,\n\toverride?: MemoryCapabilityOverrideV1,\n): readonly DisposableRegistration[] {\n\tconst harness = createMemoryCapabilityHarness(api, context, override);\n\treturn harness.registrations;\n}\n\n/** Test-only harness over the capability: registration list plus state-work hooks. */\nexport interface MemoryVectorCapabilityHarnessV1 {\n\treadonly registrations: readonly DisposableRegistration[];\n\t/** Resolves after every vector op queued so far (reconcile/upsert/purge) settled. */\n\tsettleVectorWork(): Promise<void>;\n\tvectorState(): \"off\" | MemoryCapabilityStateV1;\n\t/**\n\t * Resolves once the enabling attempt settles (immediately for injected\n\t * components): ready, or the structured failure (reason + action list).\n\t */\n\tenablingOutcome(): Promise<\"ready\" | MemoryEnablingFailureV1>;\n\t/**\n\t * 释放共享推理服务连接 (服务路径) 或本地向量索引 (本地装配路径)。幂等: 引用\n\t * 清空后二次调用为 no-op。同名注册项挂 registrations 首位——宿主反向逐个\n\t * dispose 时它最后执行 (先拆消费者、后关通道)。\n\t */\n\tteardown(): void;\n}\n\n/**\n * Test-only assembly variant: the capability with an injected override (full\n * vector components skip real assembly; enabling seams redirect the model\n * loader on the real path). Public tool names, schemas, and return shapes are\n * identical to {@link createMemoryCapability}.\n */\nexport function createCapabilityWithVectorComponents(\n\tapi: CapabilityAPI,\n\tcontext: MemoryCapabilityContext,\n\toverride: MemoryCapabilityOverrideV1,\n): MemoryVectorCapabilityHarnessV1 {\n\t// Tool-face test stubs hand-write partial CapabilityAPIs that predate the\n\t// D-071 auto-recall hook; default registerLoopHook to a no-op so those\n\t// tests keep exercising just the tool face. Real CapabilityAPIs always\n\t// carry the method (production path never hits this default) — the `in`\n\t// check is runtime-only because the stubs bypass the declared type.\n\tconst apiWithHooks: CapabilityAPI =\n\t\t\"registerLoopHook\" in api\n\t\t\t? api\n\t\t\t: Object.assign(Object.create(null) as CapabilityAPI, api, {\n\t\t\t\t\tregisterLoopHook: (): DisposableRegistration => ({\n\t\t\t\t\t\tid: \"test:noop-loop-hook\",\n\t\t\t\t\t\tkind: \"loop-hook\",\n\t\t\t\t\t\tdispose() {},\n\t\t\t\t\t}),\n\t\t\t\t});\n\treturn createMemoryCapabilityHarness(apiWithHooks, context, override);\n}\n\nfunction createMemoryCapabilityHarness(\n\tapi: CapabilityAPI,\n\tcontext: MemoryCapabilityContext,\n\toverride?: MemoryCapabilityOverrideV1,\n): MemoryVectorCapabilityHarnessV1 {\n\tassertNonEmptyString(context.agentDir, \"MemoryCapabilityContext.agentDir\");\n\tconst now = (): number => Date.now();\n\tconst sessionId = api.session?.getSessionId() ?? \"no-session\";\n\n\t// 全局档位解析 (2.4d6 S1): context 显式 → env → settings.json → 默认 off。\n\t// 非法 env/settings 值 fail-closed 回 off 并各告警一次; off = 家族整体不注册\n\t// (零工具零命令零事件)。\n\tconst modeResolution = resolveMemoryMode(context.memory?.mode, undefined, context.memory?.settingsMode);\n\tif (modeResolution.invalidEnvValue !== undefined) {\n\t\tapi.logger?.warn(\n\t\t\t`invalid AGENT_FORGE_MEMORY_MODE value \"${modeResolution.invalidEnvValue}\"; memory stays off (fail-closed)`,\n\t\t);\n\t}\n\tif (modeResolution.invalidSettingsValue !== undefined) {\n\t\tapi.logger?.warn(\n\t\t\t`invalid memory.mode setting \"${modeResolution.invalidSettingsValue}\"; memory stays off (fail-closed)`,\n\t\t);\n\t}\n\tif (modeResolution.mode === \"off\") {\n\t\tapi.logger?.info(\"memory disabled (mode=off)\");\n\t\treturn {\n\t\t\tregistrations: [],\n\t\t\tsettleVectorWork: async () => {},\n\t\t\tvectorState: () => \"off\",\n\t\t\tenablingOutcome: async () => \"ready\",\n\t\t\tteardown: () => {},\n\t\t};\n\t}\n\tconst memoryMode = modeResolution.mode;\n\tconst vectorComponentsOverride: MemoryCapabilityOverrideV1 | undefined =\n\t\toverride ?? context.vectorComponents ?? context.storage?.vectorComponents;\n\tconst injectedComponents =\n\t\tvectorComponentsOverride !== undefined && isVectorComponentsOverride(vectorComponentsOverride)\n\t\t\t? vectorComponentsOverride\n\t\t\t: undefined;\n\tconst enablingOverride =\n\t\tvectorComponentsOverride !== undefined && !isVectorComponentsOverride(vectorComponentsOverride)\n\t\t\t? vectorComponentsOverride\n\t\t\t: undefined;\n\n\t// Store: one per-capability-instance singleton. Atoms of every domain this\n\t// session touches live here together — the atom `suiteId` field carries the\n\t// read boundary (suite queries filter through it; the ledger is only the\n\t// per-domain durable replica). The injected storeFactory (扩展位 A1) replaces\n\t// the default store wholesale: the implementation owns retention semantics.\n\tconst retentionRegistry = createFirstPartyRetentionRegistry();\n\tconst store =\n\t\tcontext.storage?.storeFactory?.({\n\t\t\tagentDir: context.agentDir,\n\t\t\towner: BUILTIN_MEMORY_OWNER,\n\t\t\tnow,\n\t\t}) ?? createMemoryStore({ retentionRegistry, now });\n\n\t// Durable replica per domain, created and loaded lazily on the first tool\n\t// call in that domain (统一修复轮 B1 复审修复): the sdk appends the suite\n\t// binding entry only after the session constructor ran this factory, so the\n\t// domain (and with it the ledger to replay) is only known at call time.\n\t// Write identity is deterministic: observationId `memory_write:<sessionId>:<n>`\n\t// hashes into the memoryId. The counter is instance-local, so a resumed session\n\t// re-derives its floor from the replayed ledger (resolveDomain): a persisted\n\t// observationId of this session marks its sequence as taken — the store rejects\n\t// a regenerated memoryId (canonical atoms are immutable), which would fail every\n\t// replayed-sequence write after resume (write → dispose → resume → write).\n\tconst domainLedgers = new Map<string, DurableMemoryLedgerV1>();\n\t/**\n\t * Seed the write-sequence floor from every domain ledger in this owner\n\t * directory, not just the domain being loaded. The observationId carries no\n\t * domain component, so per-domain floors can collide (legacy fallback after a\n\t * branch cut reused the first coding write's sequence and memoryId, and the\n\t * projection overwrote that coding row).\n\t */\n\tconst seedWriteSequenceFloorFromAllDomains = (): void => {\n\t\tconst dir = join(context.agentDir, \"memory\", BUILTIN_MEMORY_OWNER);\n\t\tlet names: readonly string[];\n\t\ttry {\n\t\t\tnames = readdirSync(dir);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\t\tfor (const name of names) {\n\t\t\tif (!name.startsWith(\"ledger-\") || !name.endsWith(\".jsonl\")) continue;\n\t\t\tconst path = join(dir, name);\n\t\t\ttry {\n\t\t\t\tconst replay = createDurableMemoryLedger({ path, now }).load();\n\t\t\t\tfor (const atom of replay.atoms) {\n\t\t\t\t\tconst sequence = writeFace.writeSequenceOf(atom.observationId);\n\t\t\t\t\tif (sequence !== undefined) writeFace.advanceWriteSequenceFloor(sequence);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tapi.logger?.warn(\"memory ledger sequence floor scan failed; a new write may reuse a sequence\", {\n\t\t\t\t\tpath,\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\tconst resolveDomain = (): {\n\t\treadonly domain: SuiteMemoryDomainV1;\n\t\treadonly domainName: string;\n\t\treadonly ledger: DurableMemoryLedgerV1;\n\t} => {\n\t\tconst domain = resolveSessionDomain(api);\n\t\tconst domainName = suiteMemoryDomainName(domain);\n\t\tlet ledger = domainLedgers.get(domainName);\n\t\tif (ledger === undefined) {\n\t\t\tledger =\n\t\t\t\tcontext.storage?.ledgerFactory?.({\n\t\t\t\t\tagentDir: context.agentDir,\n\t\t\t\t\towner: BUILTIN_MEMORY_OWNER,\n\t\t\t\t\tdomain: domainName,\n\t\t\t\t\tnow,\n\t\t\t\t}) ??\n\t\t\t\tcreateDurableMemoryLedger({\n\t\t\t\t\tpath: join(context.agentDir, \"memory\", BUILTIN_MEMORY_OWNER, `ledger-${domainName}.jsonl`),\n\t\t\t\t\tnow,\n\t\t\t\t});\n\t\t\tif (domain.kind === \"legacy\") {\n\t\t\t\tapi.logger?.info(\"session has no suite binding; memory falls back to the legacy domain\", {\n\t\t\t\t\tsessionId: api.session?.getSessionId() ?? \"unknown\",\n\t\t\t\t});\n\t\t\t}\n\t\t\t// First load in this domain: replay the durable atoms into the store.\n\t\t\t// Sequences persisted by earlier instances of this session raise the\n\t\t\t// write-sequence floor before any new write can regenerate their ids.\n\t\t\t// Scan every domain first: observationIds are shared across domains.\n\t\t\tseedWriteSequenceFloorFromAllDomains();\n\t\t\tconst replay = ledger.load();\n\t\t\tfor (const atom of replay.atoms) {\n\t\t\t\tconst persistedSequence = writeFace.writeSequenceOf(atom.observationId);\n\t\t\t\tif (persistedSequence !== undefined) writeFace.advanceWriteSequenceFloor(persistedSequence);\n\t\t\t\ttry {\n\t\t\t\t\tstore.commit(atom);\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// A ledger atom the current store cannot accept (e.g. an unregistered\n\t\t\t\t\t// retention mode) must not fail the session — skip with a diagnostic.\n\t\t\t\t\tapi.logger?.warn(\"memory ledger atom could not be replayed into the store\", {\n\t\t\t\t\t\tmemoryId: atom.memoryId,\n\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (replay.corruptedLines > 0 || replay.duplicateSkipped > 0 || replay.unreadable) {\n\t\t\t\tapi.logger?.warn(\"memory ledger loaded with diagnostics\", {\n\t\t\t\t\tdomain: domainName,\n\t\t\t\t\tcorruptedLines: replay.corruptedLines,\n\t\t\t\t\tduplicateSkipped: replay.duplicateSkipped,\n\t\t\t\t\tunreadable: replay.unreadable,\n\t\t\t\t});\n\t\t\t}\n\t\t\tdomainLedgers.set(domainName, ledger);\n\t\t\t// 启动对账: 首个域的 ledger 重放完成后一次性触发 (fire-and-forget,\n\t\t\t// 不阻塞本工具调用; 失败只影响向量通道, 不影响锚点通道)。\n\t\t\tvectorProjection.reconcileOnce();\n\t\t\t// 机会式保留清扫 (M5, 记忆系统设计 §3.3): 首载重放完成后对本域已过期\n\t\t\t// 原子执行一次受控物理清理 (retention-expiry 授权, 最旧优先 ≤200 条,\n\t\t\t// ledger 重写 + 向量行删除 + store 逐出)。同步调用且 sweep 自吞错——\n\t\t\t// 装载绝不因清扫失败失败; 非干净结果只记一条有界 warn。\n\t\t\tconst sweepLedger = ledger;\n\t\t\tconst sweep = sweepExpiredMemories(\n\t\t\t\t{\n\t\t\t\t\tstore,\n\t\t\t\t\tpurgeGate,\n\t\t\t\t\tpurgeJournal,\n\t\t\t\t\tpurgeIndexReplica: vectorProjection.purgeMemories,\n\t\t\t\t\tpurgeCanonicalReplica: (memoryIds) => {\n\t\t\t\t\t\tconst purged = new Set(memoryIds);\n\t\t\t\t\t\tsweepLedger.rewrite(sweepLedger.atomsSnapshot().filter((atom) => !purged.has(atom.memoryId)));\n\t\t\t\t\t\tfor (const id of memoryIds) store.evict(id);\n\t\t\t\t\t},\n\t\t\t\t\tauthorizedBy: `${capabilityManifest.id}:retention-sweep`,\n\t\t\t\t\tnow,\n\t\t\t\t},\n\t\t\t\t{ owner: BUILTIN_MEMORY_OWNER, domain },\n\t\t\t);\n\t\t\tif (sweep.status === \"failed\" || sweep.status === \"purge_eligible\" || sweep.reason !== undefined) {\n\t\t\t\tapi.logger?.warn(\n\t\t\t\t\t\"memory retention sweep did not finish clean; expired atoms stay purge-eligible and are retried on the next domain load\",\n\t\t\t\t\t{\n\t\t\t\t\t\tdomain: domainName,\n\t\t\t\t\t\tstatus: sweep.status,\n\t\t\t\t\t\t...(sweep.reason === undefined ? {} : { reason: sweep.reason }),\n\t\t\t\t\t\t...(sweep.failedReplicas === undefined ? {} : { failedReplicas: sweep.failedReplicas }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn { domain, domainName, ledger };\n\t};\n\n\tconst machine = createMemoryCandidateMachine({ store, now });\n\tconst lifecycle = createMemoryLifecycleManager({\n\t\tpolicy: {\n\t\t\tpolicyVersion: \"lifecycle@1\",\n\t\t\thalfLifeMs: { session: 86_400_000, cycle: 604_800_000, \"long-term\": 2_592_000_000 },\n\t\t\tstaleAfterMs: { session: 172_800_000, cycle: 1_209_600_000, \"long-term\": 5_184_000_000 },\n\t\t\tarchiveAfterMs: { session: 604_800_000, cycle: 5_184_000_000, \"long-term\": 15_552_000_000 },\n\t\t\tbaselineAttention: 0.5,\n\t\t},\n\t\tnow,\n\t});\n\tconst scheduler = createMemoryScheduler({ now });\n\tscheduler.acquireForInstance({ instanceId: sessionId, owner: BUILTIN_MEMORY_OWNER });\n\t// 非工具召回路径设施 (2.4d6 S4 家族收口取证结论): 生产工具召回 (memory_recall\n\t// 工具与 auto-recall 钩子, 后者直连同一 recallExecute, D-071 自 sdk 迁入)\n\t// 只走 recallSemantically 语义管线; index → recallAgent →\n\t// schedulerApi.recall 这条链在本 capability 内不再被工具面调用 (schedulerApi\n\t// 的生产使用仅剩写入路径的 submitObservation/submitCandidate)。保留原因:\n\t// MemorySchedulerApiV1 facade 契约 (recall + egress 门)、recall-agent 与\n\t// recall-index 是公共 API (src/index.ts 导出) 和 memory-testkit 之上的测试\n\t// 设施 (scheduler-api / memory-suite-scope / coverage-branch-memory-recall\n\t// 等测试的直接消费者) — 有存续消费者, 非死代码。\n\tconst index = createMemoryRecallIndex({ store });\n\tconst recallAgent = createMemoryRecallAgent({\n\t\tscheduler,\n\t\tindex,\n\t\tpolicyDefaults: {\n\t\t\tcandidateBudget: 1000,\n\t\t\tmodelInspectionLimit: 20,\n\t\t\tfinalResultLimit: 20,\n\t\t\tmaxRelationHops: 2,\n\t\t\tmaxModelCalls: 3,\n\t\t\tmaxOutputTokens: 4000,\n\t\t\tmaxOutputBytes: 16_000,\n\t\t\tmaxRounds: 3,\n\t\t},\n\t\thostLimits: {\n\t\t\tcandidateBudget: 5000,\n\t\t\tmodelInspectionLimit: 100,\n\t\t\tfinalResultLimit: 100,\n\t\t\tmaxRelationHops: 5,\n\t\t\tmaxModelCalls: 10,\n\t\t\tmaxOutputTokens: 100_000,\n\t\t\tmaxOutputBytes: 1_000_000,\n\t\t\tmaxRounds: 10,\n\t\t},\n\t\tnow,\n\t});\n\tconst replicaRegistry = createMemoryReplicaRegistry();\n\treplicaRegistry.register({\n\t\treplicaId: \"memory-ledger\",\n\t\tkind: \"canonical\",\n\t\townerScope: BUILTIN_MEMORY_OWNER,\n\t\tcontractVersion: MEMORY_CONTRACT_VERSION,\n\t\thealthy: true,\n\t} satisfies MemoryReplicaV1);\n\t// 向量投影副本 (混合检索工程化, D-035): 恒注册 — purge 批次以向量索引确认为\n\t// 副本契约的一部分; 通道 off/disabled 时 index 分派为 no-op (索引不存在,\n\t// 无行可清), 行为见 vectorProjection.purgeMemories。\n\treplicaRegistry.register({\n\t\treplicaId: \"memory-vector-index\",\n\t\tkind: \"index\",\n\t\tcontractVersion: MEMORY_CONTRACT_VERSION,\n\t\townerScope: BUILTIN_MEMORY_OWNER,\n\t\thealthy: true,\n\t} satisfies MemoryReplicaV1);\n\tconst purgeGate = createMemoryPurgeGate({ registry: replicaRegistry, now });\n\tconst purgeJournal = createMemoryPurgeJournal();\n\tconst egressPolicy = createMemoryEgressPolicy({\n\t\tpolicyVersion: \"egress@1\",\n\t\tallowedSourceKinds: [\"tool\", \"entry\"],\n\t\tredactedPayloadFields: [],\n\t});\n\t// schedulerApi.recall 在生产工具面无调用点 (角色见上方\"非工具召回路径设施\"\n\t// 注释); 本 capability 的生产使用仅 submitObservation/submitCandidate (写入)。\n\tconst schedulerApi = createMemorySchedulerApi({\n\t\trecallAgent,\n\t\tmachine,\n\t\tlifecycle,\n\t\tpurgeGate,\n\t\tegressPolicy,\n\t\tfactInfoLookup: (memoryId) => {\n\t\t\tconst record = store.get(memoryId, { owner: BUILTIN_MEMORY_OWNER });\n\t\t\tif (!record) return undefined;\n\t\t\treturn {\n\t\t\t\tsourceRefs: record.atom.sourceRefs,\n\t\t\t\tpayload: record.atom.payload as Record<string, unknown>,\n\t\t\t};\n\t\t},\n\t});\n\t// Preference resolution/disambiguation over context-scoped recalls (2.4c/2.4d2):\n\t// stateless and deterministic — one instance per capability suffices.\n\tconst preferenceResolver = createPreferenceResolver();\n\tconst preferenceDisambiguator = createPreferenceDisambiguator();\n\t// Relation diffusion over the recall seeds (记忆网络接线, 2.4d4): a factory-\n\t// scoped deterministic network with one enabled one-hop adapter; disabled\n\t// adapters yield an explicit `disabled` result instead of silent degradation.\n\tconst memoryNetwork = createMemoryNetwork({\n\t\tadapters: [createRelationDiffusionAdapter({ maxHops: 1 })],\n\t});\n\n\t// ---- 语义召回通道状态机 (2.4d6 S1/S2; 拆分战役 slice 3b) ----\n\t// vectorEnsure 状态转换、装配分支 (服务/本地/下载/征询门) 与 dispose 闩锁\n\t// 已迁至 memory/vector-channel.ts: 共享闭包状态收拢为 channel 对象, 经 deps\n\t// 显式注入, 降级/投影经下方 vectorProjection (slice 3a) 上报。以下调用点\n\t// 全部薄委托。\n\tconst vectorChannelCtl = createMemoryVectorChannel({\n\t\tagentDir: context.agentDir,\n\t\tmemoryMode,\n\t\tlogger: api.logger,\n\t\thostOnnxRuntimeEntryPath: context.hostOnnxRuntimeEntryPath,\n\t\thostLancedbEntryPath: context.hostLancedbEntryPath,\n\t\thostTransformersEntryPath: context.hostTransformersEntryPath,\n\t\tinferenceServicePort: context.inferenceService?.port,\n\t\tinferenceServiceSpawnImpl: context.inferenceService?.spawnImpl,\n\t\tinferenceServiceModelsInPlace: context.inferenceService?.modelsInPlace,\n\t\tenablingOverride,\n\t\tinjectedComponents,\n\t\t// vectorProjection 声明在本对象之后; 委托箭头只在 download 运行期触达,\n\t\t// 与下方 supersededMemoryIds 依赖同构 (构造期不执行)。\n\t\tresetReconcile: () => vectorProjection.resetReconcile(),\n\t\treconcileOnce: () => vectorProjection.reconcileOnce(),\n\t});\n\n\t// 写入侧向量投影管线 (拆分战役 slice 3a): 串行队列、upsert/purge 埋点与启动\n\t// 对账搬至 memory/vector-projection.ts; 状态机归 memory/vector-channel.ts\n\t// (slice 3b), 投影经只读 deps 使用, degraded 转换经 markDegraded 回调上报。\n\tconst vectorProjection = createMemoryVectorProjection({\n\t\tvectorEnabled: () => vectorChannelCtl.enabled(),\n\t\tensureChannel: () => vectorChannelCtl.ensure(),\n\t\treadyChannel: () => vectorChannelCtl.readyChannel(),\n\t\tisChannelActive: () => {\n\t\t\tconst channelState = vectorChannelCtl.rawState();\n\t\t\treturn channelState === \"ready\" || channelState === \"degraded\";\n\t\t},\n\t\tisDisposed: () => vectorChannelCtl.isDisposed(),\n\t\t// 反向清理的跨进程守卫 (2026-10-07 终审): 只读扫描 owner 全部域账本的\n\t\t// memoryId 并集 (盘面扫描, 不触碰进程内 ledger 快照)。\n\t\trefreshCanonicalMemoryIds: () =>\n\t\t\tscanOwnerLedgerMemoryIds({ agentDir: context.agentDir, owner: BUILTIN_MEMORY_OWNER }),\n\t\tmarkDegraded: () => vectorChannelCtl.markDegraded(),\n\t\tlogger: api.logger,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tstore,\n\t\t// writeFace 声明在本对象之后; 委托箭头只在对账运行期触达 (构造期不执行)。\n\t\tsupersededMemoryIds: () => writeFace.supersededMemoryIds(),\n\t\tstatementOf,\n\t\ttagFacetsOf,\n\t});\n\n\t// ---- 写入面 (拆分战役 slice 5) ----\n\t// memory_write 工具、语义合并探测、写入 atom 构造与写后自动升档旁路已迁至\n\t// memory/write-face.ts: 写序计数/探测降级告警闩/升档闩归 write-face 工厂\n\t// 所有, 经 deps 显式注入; 状态机与写侧投影经对象只读消费。supersededMemoryIds\n\t// 供上方 vectorProjection 的对账 deps 消费 (构造期不执行, 依赖同构)。\n\tconst writeFace = createMemoryWriteFace({\n\t\tlogger: api.logger,\n\t\tregisterTool: (definition) => api.registerTool(definition),\n\t\tpublish: api.publish,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tsessionId,\n\t\tmanifest: capabilityManifest,\n\t\tcontractVersion: MEMORY_CONTRACT_VERSION,\n\t\tmemoryMode,\n\t\tagentDir: context.agentDir,\n\t\tnow,\n\t\tstore,\n\t\tschedulerApi,\n\t\tvectorProjection,\n\t\tvectorChannelCtl,\n\t\tresolveDomain,\n\t\tassertNonEmptyString,\n\t\tmemoryToolInput,\n\t\tidentityHash,\n\t\tstatementOf,\n\t\ttagFacetsOf,\n\t});\n\n\t// ---- 语义召回管线 (拆分战役 slice 4) ----\n\t// 双通道查询、RRF 融合、egress 门、语义召回与召回工具已迁至\n\t// memory/recall-pipeline.ts: 状态机经 vectorChannelCtl 只读面消费\n\t// (warming/ensure/征询/失败/degraded), 写侧投影的读侧等待经 settleProjection,\n\t// capability 模块级纯函数经 deps 注入避免双头定义。recallTool 进 registrations,\n\t// recallExecute 同时被钩子面 (slice 7) 直连。\n\tconst recallPipeline = createMemoryRecallPipeline({\n\t\tlogger: api.logger,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tsessionId,\n\t\tstore,\n\t\tresolveDomain,\n\t\tegressPolicy,\n\t\tpreferenceResolver,\n\t\tpreferenceDisambiguator,\n\t\tmemoryNetwork,\n\t\twarming: () => vectorChannelCtl.warming(),\n\t\tensureChannel: () => vectorChannelCtl.ensure(),\n\t\tdeclined: () => vectorChannelCtl.declined(),\n\t\tconsentAsk: () => vectorChannelCtl.consentAsk(),\n\t\tfailure: () => vectorChannelCtl.failure(),\n\t\trawState: () => vectorChannelCtl.rawState(),\n\t\tmarkDegraded: () => vectorChannelCtl.markDegraded(),\n\t\trecoverDegraded: () => vectorChannelCtl.recoverDegraded(),\n\t\tsettleProjection: () => vectorProjection.settle(),\n\t\tmemoryToolInput,\n\t\tassertNonEmptyString,\n\t\tisPlainObject,\n\t\tidentityHash,\n\t\tstatementOf,\n\t\tunwrapEgressStatement,\n\t\tregisterTool: (definition) => api.registerTool(definition),\n\t});\n\n\t// ---- 命令面 (拆分战役 slice 6) ----\n\t// memory_list/forget 工具、/memory 与 /promote 命令、memory_enable 征询执行\n\t// 面与 memory.scheduler 声明已迁至 memory/command-face.ts: 列表/删除/晋升/\n\t// 征询的命令执行面经 deps 显式注入, decline/download 仍薄委托 vectorChannelCtl\n\t// (slice 3b 先例); 升档声明状态经 writeFace 的只读面消费。\n\tconst commandFace = createMemoryCommandFace({\n\t\tregisterTool: (definition) => api.registerTool(definition),\n\t\tregisterCommand: (definition) => api.registerCommand(definition),\n\t\tpublish: api.publish,\n\t\tcapabilities: api.capabilities,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tsessionId,\n\t\tmanifest: capabilityManifest,\n\t\tagentDir: context.agentDir,\n\t\tmemoryMode,\n\t\tnow,\n\t\tstore,\n\t\tpurgeGate,\n\t\tpurgeJournal,\n\t\tvectorProjection,\n\t\tvectorChannelCtl,\n\t\tresolveDomain,\n\t\tassertNonEmptyString,\n\t\tmemoryToolInput,\n\t\tstatementOf,\n\t\tunwrapEgressStatement,\n\t\ttierUpgradePending: writeFace.tierUpgradePending,\n\t\tclearTierUpgrade: writeFace.clearTierUpgrade,\n\t});\n\n\t// ---- 注入钩子 (拆分战役 slice 7) ----\n\t// auto-recall 与 assistant 偏好卡已迁至 memory/hooks.ts: 钩子经 api 注册面\n\t// 订阅 (loop hook), 召回执行闭包经 deps 注入。bash 失败教训沉淀已停用\n\t// (记忆归档与整理设计 §14 裁决 1), 其职责由归档整理器承担。\n\tconst hooks = createMemoryHooks({\n\t\tlogger: api.logger,\n\t\tregisterLoopHook: api.registerLoopHook,\n\t\tsession: api.session,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tagentDir: context.agentDir,\n\t\tnow,\n\t\tisPlainObject,\n\t\tresolveSessionDomain: () => resolveSessionDomain(api),\n\t\trecallExecute: recallPipeline.recallExecute,\n\t\tvectorChannelCtl,\n\t});\n\n\t// ---- 归档整理器 (记忆归档与整理设计 §5-§7) ----\n\t// 归档即后台整理: session.archived 事件观察 + 启动 sweep 两个触发, 提交、\n\t// 幂等、journal 与暂停/续跑语义归 memory/curator.ts。宿主未开放归档面\n\t// (context 与 api.host 都无 sessionArchive) 时两个触发都不注册。\n\tconst curator = createMemoryCurator({\n\t\tapi,\n\t\tagentDir: context.agentDir,\n\t\towner: BUILTIN_MEMORY_OWNER,\n\t\tnow,\n\t\tmanifest: capabilityManifest,\n\t\tstore,\n\t\tresolveDomain,\n\t\tvectorProjection,\n\t\tidentityHash,\n\t\tsessionArchive: context.sessionArchive ?? api.host?.sessionArchive,\n\t});\n\n\tconst registrations = [\n\t\t// 首位 = 宿主反向 dispose 时的末位: 先拆工具/命令/钩子等消费者, 最后关\n\t\t// 底层通道, 避免消费者在通道已关后仍触发向量操作报错。释放本体\n\t\t// (capabilityTeardown, slice 3b) 在 memory/vector-channel.ts。\n\t\t{\n\t\t\tid: \"memory:capability-teardown\",\n\t\t\tkind: \"capability-teardown\",\n\t\t\tdispose: () => vectorChannelCtl.dispose(),\n\t\t},\n\t\twriteFace.writeTool,\n\t\trecallPipeline.recallTool,\n\t\tcommandFace.listTool,\n\t\tcommandFace.forgetTool,\n\t\tcommandFace.enableTool,\n\t\tcommandFace.memoryCommand,\n\t\tcommandFace.promoteCommand,\n\t\tcommandFace.schedulerCapability,\n\t\thooks.autoRecallHook,\n\t\thooks.preferenceCardHook,\n\t\t...curator.registrations,\n\t];\n\treturn {\n\t\tregistrations,\n\t\tsettleVectorWork: async () => {\n\t\t\tawait vectorProjection.settle();\n\t\t},\n\t\tvectorState: (): \"off\" | MemoryCapabilityStateV1 => vectorChannelCtl.state(),\n\t\t// 触发惰性 enabling (已注入组件时已就绪) 并等待其落定: ready 或结构化失败。\n\t\tenablingOutcome: () => vectorChannelCtl.enablingOutcome(),\n\t\tteardown: () => vectorChannelCtl.dispose(),\n\t};\n}\n"]}
|
|
@@ -2306,6 +2306,23 @@ var init_embedding_reranker = __esm({
|
|
|
2306
2306
|
function escapeSqlLiteral(value) {
|
|
2307
2307
|
return value.replace(/'/g, "''");
|
|
2308
2308
|
}
|
|
2309
|
+
function partitionIdentitySafeWrites(rows, stored) {
|
|
2310
|
+
const accepted = [];
|
|
2311
|
+
const collisions = [];
|
|
2312
|
+
for (const row of rows) {
|
|
2313
|
+
const storedBody = stored.get(row.memoryId);
|
|
2314
|
+
if (storedBody === void 0) {
|
|
2315
|
+
accepted.push(row);
|
|
2316
|
+
continue;
|
|
2317
|
+
}
|
|
2318
|
+
if (storedBody === row.body) {
|
|
2319
|
+
accepted.push(row);
|
|
2320
|
+
continue;
|
|
2321
|
+
}
|
|
2322
|
+
collisions.push({ memoryId: row.memoryId, storedBody, incomingBody: row.body });
|
|
2323
|
+
}
|
|
2324
|
+
return { accepted, collisions };
|
|
2325
|
+
}
|
|
2309
2326
|
async function createMemoryVectorIndex(options) {
|
|
2310
2327
|
const dimensions = options.dimensions;
|
|
2311
2328
|
const lancedb = await importHostOrBareModule(
|
|
@@ -2343,6 +2360,14 @@ async function createMemoryVectorIndex(options) {
|
|
|
2343
2360
|
} catch {
|
|
2344
2361
|
}
|
|
2345
2362
|
};
|
|
2363
|
+
const storedBodiesFor = async (target, rows) => {
|
|
2364
|
+
const ids = [...new Set(rows.map((row) => row.memoryId))];
|
|
2365
|
+
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
2366
|
+
const predicate = `memoryId IN (${ids.map((id) => `'${escapeSqlLiteral(id)}'`).join(",")})`;
|
|
2367
|
+
const found = await target.query().where(predicate).select(["memoryId", "body"]).toArray();
|
|
2368
|
+
return new Map(found.map((row) => [row.memoryId, row.body]));
|
|
2369
|
+
};
|
|
2370
|
+
const reportedCollisions = /* @__PURE__ */ new Set();
|
|
2346
2371
|
return {
|
|
2347
2372
|
replicaId: "memory-vector-index",
|
|
2348
2373
|
upsert: (entries) => withOpenIndex(async () => {
|
|
@@ -2369,7 +2394,15 @@ async function createMemoryVectorIndex(options) {
|
|
|
2369
2394
|
await createBodyFtsIndex(table);
|
|
2370
2395
|
return;
|
|
2371
2396
|
}
|
|
2372
|
-
await current
|
|
2397
|
+
const { accepted, collisions } = partitionIdentitySafeWrites(rows, await storedBodiesFor(current, rows));
|
|
2398
|
+
for (const collision of collisions) {
|
|
2399
|
+
const key = `${collision.memoryId}\0${collision.storedBody}`;
|
|
2400
|
+
if (reportedCollisions.has(key)) continue;
|
|
2401
|
+
reportedCollisions.add(key);
|
|
2402
|
+
options.onCollision?.(collision);
|
|
2403
|
+
}
|
|
2404
|
+
if (accepted.length === 0) return;
|
|
2405
|
+
await current.mergeInsert("memoryId").whenMatchedUpdateAll().whenNotMatchedInsertAll().execute([...accepted]);
|
|
2373
2406
|
}),
|
|
2374
2407
|
remove: (memoryIds) => withOpenIndex(async () => {
|
|
2375
2408
|
if (memoryIds.length === 0) {
|
|
@@ -7154,14 +7187,30 @@ var recallSchema = typebox_exports.Object({
|
|
|
7154
7187
|
description: "Natural-language query; recall fuses semantic (vector) and full-text (BM25) matching and reranks the result. An exact memoryId retrieves that memory directly"
|
|
7155
7188
|
}),
|
|
7156
7189
|
limit: typebox_exports.Optional(
|
|
7157
|
-
typebox_exports.Integer({
|
|
7190
|
+
typebox_exports.Integer({
|
|
7191
|
+
description: "Maximum number of memories to return (1-100, default 5)",
|
|
7192
|
+
minimum: 1,
|
|
7193
|
+
maximum: 100
|
|
7194
|
+
})
|
|
7158
7195
|
),
|
|
7159
7196
|
context: typebox_exports.Optional(
|
|
7160
7197
|
typebox_exports.Object(
|
|
7161
7198
|
{
|
|
7162
|
-
scenes: typebox_exports.Optional(
|
|
7163
|
-
|
|
7164
|
-
|
|
7199
|
+
scenes: typebox_exports.Optional(
|
|
7200
|
+
typebox_exports.Array(typebox_exports.String(), {
|
|
7201
|
+
description: "Scene tags of the current task, used to resolve preferences by scope"
|
|
7202
|
+
})
|
|
7203
|
+
),
|
|
7204
|
+
projects: typebox_exports.Optional(
|
|
7205
|
+
typebox_exports.Array(typebox_exports.String(), {
|
|
7206
|
+
description: "Project identifiers of the current task, used to resolve preferences by scope"
|
|
7207
|
+
})
|
|
7208
|
+
),
|
|
7209
|
+
tasks: typebox_exports.Optional(
|
|
7210
|
+
typebox_exports.Array(typebox_exports.String(), {
|
|
7211
|
+
description: "Task or goal identifiers of the current task, used to resolve preferences by scope"
|
|
7212
|
+
})
|
|
7213
|
+
)
|
|
7165
7214
|
},
|
|
7166
7215
|
{
|
|
7167
7216
|
description: "Current scope context; when present, recalled preferences are resolved against it (out-of-scope preferences drop, competing values resolve by scope specificity or surface as explicit conflicts)"
|
|
@@ -11519,7 +11568,7 @@ var writeSchema = typebox_exports.Object({
|
|
|
11519
11568
|
// src/memory/command-face.ts
|
|
11520
11569
|
var listSchema = typebox_exports.Object({
|
|
11521
11570
|
limit: typebox_exports.Optional(
|
|
11522
|
-
typebox_exports.Integer({ description: "Maximum number of entries to list (1-100)", minimum: 1, maximum: 100 })
|
|
11571
|
+
typebox_exports.Integer({ description: "Maximum number of entries to list (1-100, default 20)", minimum: 1, maximum: 100 })
|
|
11523
11572
|
)
|
|
11524
11573
|
});
|
|
11525
11574
|
var forgetSchema = typebox_exports.Object({
|
|
@@ -11977,7 +12026,13 @@ async function runMemoryInferenceService(options) {
|
|
|
11977
12026
|
const vectorIndex = await createMemoryVectorIndex({
|
|
11978
12027
|
dbPath: join7(options.agentDir, "memory", VECTOR_DB_DIRNAME),
|
|
11979
12028
|
dimensions: preset.dimensions,
|
|
11980
|
-
...options.moduleEntryPaths?.lancedb === void 0 ? {} : { moduleEntryPath: options.moduleEntryPaths.lancedb }
|
|
12029
|
+
...options.moduleEntryPaths?.lancedb === void 0 ? {} : { moduleEntryPath: options.moduleEntryPaths.lancedb },
|
|
12030
|
+
// P5 残留守卫 (与本地通道同语义): 拒绝覆盖外来同 id 行, 服务进程日志留痕。
|
|
12031
|
+
onCollision: (collision) => {
|
|
12032
|
+
log2(
|
|
12033
|
+
"memory-inference: vector projection refused to overwrite a row whose memoryId belongs to a different atom (cross-domain id collision): " + collision.memoryId
|
|
12034
|
+
);
|
|
12035
|
+
}
|
|
11981
12036
|
});
|
|
11982
12037
|
backend = { embedProvider, reranker, vectorIndex };
|
|
11983
12038
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-face.d.ts","sourceRoot":"","sources":["../../src/memory/command-face.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 命令面(capability 拆分战役 slice 6):memory_list / memory_forget 工具、\n * /memory 与 /promote 命令、memory_enable 征询执行面与 memory.scheduler 能力\n * 声明。物理删除的授权引用构造在本面(用户命令链专用); decline/download 仍\n * 薄委托 vectorChannelCtl(slice 3b 先例, 经 deps 下的 channel 对象调用);\n * 搬移函数体逐字节保留。\n */\nimport type { CapabilityAPI, CapabilityCommandResult, DisposableRegistration } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport { writeMemorySettingsMode } from \"./enabling.ts\";\nimport type { DurableMemoryLedgerV1 } from \"./ledger.ts\";\nimport { promotePreferenceToUserDefault } from \"./preference-promotion.ts\";\nimport type { MemoryPurgeGateV1 } from \"./purge.ts\";\nimport type { MemoryPurgeJournalV1 } from \"./purge-journal.ts\";\nimport type { MemoryStoreV1 } from \"./store.ts\";\nimport {\n\tforgetDomainMemory,\n\tlistDomainMemories,\n\ttype SuiteForgetAuthorizationRefV1,\n\ttype SuiteMemoryDomainV1,\n\ttype SuiteMemoryListEntryV1,\n} from \"./suite-memory.ts\";\nimport type { MemoryVectorChannelV1 } from \"./vector-channel.ts\";\nimport type { MemoryVectorProjectionV1 } from \"./vector-projection.ts\";\nimport { EVENT_TYPE } from \"./write-face.ts\";\n\nconst DEFAULT_LIST_LIMIT = 20;\n\nconst listSchema = Type.Object({\n\tlimit: Type.Optional(\n\t\tType.Integer({ description: \"Maximum number of entries to list (1-100)\", minimum: 1, maximum: 100 }),\n\t),\n});\n\nconst forgetSchema = Type.Object({\n\tmemoryId: Type.String({\n\t\tdescription: \"The memoryId of the memory to forget, as returned by memory_write or memory_list\",\n\t}),\n});\n\nconst enableSchema = Type.Object({\n\taction: Type.Union([Type.Literal(\"download\"), Type.Literal(\"decline\"), Type.Literal(\"retry\")], {\n\t\tdescription:\n\t\t\t'\"download\" / \"retry\" run the one-time model download (retry re-runs after a failure); \"decline\" persists memory off for this machine',\n\t}),\n});\n\n/** Canonical memoryId of the promoted copy of one preference (promotePreferenceToUserDefault suffix). */\nconst userDefaultMemoryId = (memoryId: string): string => `${memoryId}-user-default`;\n\n/**\n * 命令面对 capability 闭包的显式依赖视图 (slice 6): 逐项来自\n * createMemoryCapabilityHarness 的闭包捕获核实。状态机 (vectorChannelCtl)、\n * 写侧投影 (vectorProjection) 与 purge 组件归 capability 装配所有, 本模块经\n * 对象只读消费; capability 模块级纯函数经 deps 注入避免双头定义。\n */\nexport interface MemoryCommandFaceDepsV1 {\n\t/** 工具注册面 (api.registerTool): memory_list/forget/enable 经同一公共通道注册。 */\n\treadonly registerTool: CapabilityAPI[\"registerTool\"];\n\t/** 命令注册面 (api.registerCommand): /memory 与 /promote。 */\n\treadonly registerCommand: CapabilityAPI[\"registerCommand\"];\n\t/** 事件发布面 (api.publish): memory.changed forgotten 事件。 */\n\treadonly publish: CapabilityAPI[\"publish\"];\n\t/** 能力声明面 (api.capabilities): memory.scheduler@1 provide。 */\n\treadonly capabilities: CapabilityAPI[\"capabilities\"];\n\t/** 检索行 owner (capability.BUILTIN_MEMORY_OWNER)。 */\n\treadonly owner: string;\n\t/** 会话 id (harness sessionId): forget 授权引用 confirmationRef 组成。 */\n\treadonly sessionId: string;\n\t/** capability 清单 (capabilityManifest): issuedBy / authorizedBy / 事件 correlationId 来源。 */\n\treadonly manifest: { readonly id: string };\n\t/** agent 根目录 (MemoryCapabilityContext.agentDir): 档位持久化路径域。 */\n\treadonly agentDir: string;\n\t/** 已解析的全局档位 (harness memoryMode, off 已被工厂入口拦截)。 */\n\treadonly memoryMode: \"light\" | \"full\";\n\t/** 时钟 (harness now)。 */\n\treadonly now: () => number;\n\t/** canonical store (per-capability 单例): 列表/成员判定/晋升回查。 */\n\treadonly store: MemoryStoreV1;\n\t/** purge 门 (capability.purgeGate): 物理删除唯一生产入口的授权面。 */\n\treadonly purgeGate: MemoryPurgeGateV1;\n\t/** purge 日志 (capability.purgeJournal)。 */\n\treadonly purgeJournal: MemoryPurgeJournalV1;\n\t/** 写侧投影 (slice 3a 的 vectorProjection): forget 批次的 index 副本分派与晋升埋点。 */\n\treadonly vectorProjection: MemoryVectorProjectionV1;\n\t/** 向量通道 (slice 3b 的 vectorChannelCtl): 状态行与 decline/download 薄委托。 */\n\treadonly vectorChannelCtl: MemoryVectorChannelV1;\n\t/** 域解析 (capability.resolveDomain): 每次调用时惰性解析 (B1 语义)。 */\n\treadonly resolveDomain: () => {\n\t\treadonly domain: SuiteMemoryDomainV1;\n\t\treadonly domainName: string;\n\t\treadonly ledger: DurableMemoryLedgerV1;\n\t};\n\t// ---- capability 模块级纯函数 (留守方, 经 deps 注入避免双头定义) ----\n\treadonly assertNonEmptyString: (value: unknown, label: string) => asserts value is string;\n\treadonly memoryToolInput: (first: unknown, second: unknown) => Record<string, unknown>;\n\treadonly statementOf: (payload: unknown) => string;\n\treadonly unwrapEgressStatement: (statement: string) => string;\n\t// ---- 写入面闭包视图 (slice 5 的 writeFace): 升档声明状态归 write-face 所有 ----\n\t/** 升档声明只读视图 (/memory 状态行 pending 尾巴)。 */\n\treadonly tierUpgradePending: () => boolean;\n\t/** 用户显式档位表达取代本实例升档声明 (/memory light)。 */\n\treadonly clearTierUpgrade: () => void;\n}\n\n/** 命令面工厂产物: 注册项集合 (capability registrations 按既有顺序收集)。 */\nexport interface MemoryCommandFaceV1 {\n\t/** memory_list 工具注册项。 */\n\treadonly listTool: DisposableRegistration;\n\t/** memory_forget 工具注册项 (仅登记请求, 物理删除在 /memory forget)。 */\n\treadonly forgetTool: DisposableRegistration;\n\t/** memory_enable 工具注册项 (征询门执行面)。 */\n\treadonly enableTool: DisposableRegistration;\n\t/** /memory 命令注册项。 */\n\treadonly memoryCommand: DisposableRegistration;\n\t/** /promote 命令注册项。 */\n\treadonly promoteCommand: DisposableRegistration;\n\t/** memory.scheduler@1 plugin capability 声明注册项。 */\n\treadonly schedulerCapability: DisposableRegistration;\n}\n\nexport function createMemoryCommandFace(deps: MemoryCommandFaceDepsV1): MemoryCommandFaceV1 {\n\tconst {\n\t\tregisterTool,\n\t\tregisterCommand,\n\t\tpublish,\n\t\tcapabilities,\n\t\towner,\n\t\tsessionId,\n\t\tagentDir,\n\t\tmemoryMode,\n\t\tnow,\n\t\tstore,\n\t\tpurgeGate,\n\t\tpurgeJournal,\n\t\tvectorProjection,\n\t\tvectorChannelCtl,\n\t\tresolveDomain,\n\t\tmemoryToolInput,\n\t\tstatementOf,\n\t\tunwrapEgressStatement,\n\t\ttierUpgradePending,\n\t\tclearTierUpgrade,\n\t} = deps;\n\tconst { manifest: capabilityManifest } = deps;\n\n\t/** Recency-first payload projection: unwraps the `{ statement }` payload convention. */\n\tfunction entryToToolEntry(entry: SuiteMemoryListEntryV1): Record<string, unknown> {\n\t\treturn {\n\t\t\tmemoryId: entry.memoryId,\n\t\t\tkind: entry.memoryKind,\n\t\t\tstatement: statementOf(entry.payload),\n\t\t\toccurredAt: entry.occurredAt,\n\t\t\t...(entry.preference === undefined\n\t\t\t\t? {}\n\t\t\t\t: {\n\t\t\t\t\t\tpreference: {\n\t\t\t\t\t\t\tsubject: entry.preference.subject,\n\t\t\t\t\t\t\tkey: entry.preference.key,\n\t\t\t\t\t\t\tscopeLevel: entry.preference.scopeLevel,\n\t\t\t\t\t\t\tcrossSuiteVisible: entry.preference.crossSuiteVisible,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t};\n\t}\n\n\tconst listTool = registerTool({\n\t\tname: \"memory_list\",\n\t\tlabel: \"List memories\",\n\t\tdescription: \"List this suite's durable memories (the explicit management surface for personal data)\",\n\t\tparameters: listSchema,\n\t\texecute: async (first: unknown, second?: unknown) => {\n\t\t\tconst input = memoryToolInput(first, second);\n\t\t\tconst rawLimit: unknown = input.limit;\n\t\t\tconst limit =\n\t\t\t\trawLimit === undefined\n\t\t\t\t\t? DEFAULT_LIST_LIMIT\n\t\t\t\t\t: ((): number => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\ttypeof rawLimit !== \"number\" ||\n\t\t\t\t\t\t\t\t!Number.isSafeInteger(rawLimit) ||\n\t\t\t\t\t\t\t\trawLimit < 1 ||\n\t\t\t\t\t\t\t\trawLimit > 100\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthrow new Error(\"limit must be an integer between 1 and 100\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn rawLimit;\n\t\t\t\t\t\t})();\n\t\t\tconst { domain } = resolveDomain();\n\t\t\tconst page = listDomainMemories({ store }, { owner, domain });\n\t\t\treturn {\n\t\t\t\tdomain: page.domain,\n\t\t\t\tentries: page.entries.slice(0, limit).map(entryToToolEntry),\n\t\t\t\ttotal: page.entries.length,\n\t\t\t\tpreferenceCount: page.preferenceCount,\n\t\t\t\tfactCount: page.factCount,\n\t\t\t\tfilter: page.filter,\n\t\t\t};\n\t\t},\n\t});\n\n\t/**\n\t * 物理删除唯一生产入口 (诚实化设计 §2, 2026-10-05 裁决): 用户命令链\n\t * `/memory forget <id> confirm`。授权引用由命令分发构造 (structured\n\t * confirmationRef `memory-forget-command:<session>:<memoryId>:confirmed`),\n\t * 模型工具面不再签发 user-immediate 授权 (记忆系统设计 :997 — 授权不能由\n\t * 模型生成)。\n\t */\n\tconst purgeMemoryViaUserCommand = (memoryId: string) => {\n\t\tconst { domain, ledger } = resolveDomain();\n\t\tconst authorizationRef: SuiteForgetAuthorizationRefV1 = {\n\t\t\tmode: \"user-immediate\",\n\t\t\tissuedAt: now(),\n\t\t\tissuedBy: `${capabilityManifest.id}:/memory-forget-confirm`,\n\t\t\tconfirmationRef: `memory-forget-command:${sessionId}:${memoryId}:confirmed`,\n\t\t};\n\t\treturn forgetDomainMemory(\n\t\t\t{\n\t\t\t\tstore,\n\t\t\t\tpurgeGate,\n\t\t\t\tpurgeJournal,\n\t\t\t\t// index 副本分派 (混合检索工程化): canonical 走下方原回调, 向量投影由\n\t\t\t\t// suite-memory 的 executePurgeBatch 按副本路由到这里。\n\t\t\t\tpurgeIndexReplica: vectorProjection.purgeMemories,\n\t\t\t\tnow,\n\t\t\t},\n\t\t\t{\n\t\t\t\towner,\n\t\t\t\tdomain,\n\t\t\t\tmemoryId,\n\t\t\t\tauthorizedBy: `${capabilityManifest.id}:memory-forget-command`,\n\t\t\t\tauthorizationRef,\n\t\t\t},\n\t\t\t(memoryIds) => {\n\t\t\t\tconst purged = new Set(memoryIds);\n\t\t\t\t// Physical replica purge: rewrite the durable ledger without the\n\t\t\t\t// purged atoms, then evict them from the in-memory store so the\n\t\t\t\t// running process cannot recall them either (both idempotent for\n\t\t\t\t// purge_eligible retries).\n\t\t\t\tledger.rewrite(ledger.atomsSnapshot().filter((atom) => !purged.has(atom.memoryId)));\n\t\t\t\tfor (const id of memoryIds) store.evict(id);\n\t\t\t},\n\t\t);\n\t};\n\n\tconst forgetTool = registerTool({\n\t\tname: \"memory_forget\",\n\t\tlabel: \"File a forget request\",\n\t\tdescription:\n\t\t\t\"File a request to forget one memory of this suite by memoryId. This tool never deletes anything — physical deletion is user-only: the user confirms via /memory forget <memoryId> confirm\",\n\t\tparameters: forgetSchema,\n\t\texecute: async (first: unknown, second?: unknown) => {\n\t\t\tconst input = memoryToolInput(first, second);\n\t\t\tdeps.assertNonEmptyString(input.memoryId, \"memoryId\");\n\t\t\tconst { domain, domainName } = resolveDomain();\n\t\t\tconst unscoped = store.get(input.memoryId, { owner });\n\t\t\tif (unscoped === undefined) {\n\t\t\t\treturn { status: \"not_found\" as const, memoryId: input.memoryId };\n\t\t\t}\n\t\t\t// 域成员判定与 forgetDomainMemory 同判据 (suiteId 匹配 / legacy 为\n\t\t\t// undefined): 请求面同样拒绝外域 id — 模型连\"请求遗忘\"都不能指向别的域。\n\t\t\tconst isMember =\n\t\t\t\tdomain.kind === \"suite\" ? unscoped.atom.suiteId === domain.suiteId : unscoped.atom.suiteId === undefined;\n\t\t\tif (!isMember) {\n\t\t\t\treturn { status: \"foreign_domain\" as const, memoryId: input.memoryId };\n\t\t\t}\n\t\t\t// 请求的登记价值由返回文本承载 (转告用户确认命令); 无进程内状态 —\n\t\t\t// 重复请求幂等 (同一提示再次返回)。\n\t\t\treturn {\n\t\t\t\tstatus: \"requested\" as const,\n\t\t\t\tmemoryId: input.memoryId,\n\t\t\t\trequest:\n\t\t\t\t\t`Forget request filed for \"${unwrapEgressStatement(statementOf(unscoped.atom.payload))}\" in domain ${domainName}. ` +\n\t\t\t\t\t`Nothing is deleted yet — tell the user to confirm the deletion with: /memory forget ${input.memoryId} confirm`,\n\t\t\t};\n\t\t},\n\t});\n\n\t/**\n\t * /promote (偏好晋升触发, B2; 2026-10-05 诚实化裁决起两步确认): the production\n\t * caller of {@link promotePreferenceToUserDefault}. Promotes one of THIS\n\t * session's preferences to the user-default scope: the promoted canonical atom\n\t * is appended to the session domain's durable ledger and committed to the\n\t * store, so every suite's preference-card read (which applies the suite read\n\t * boundary across all of the owner's ledgers) sees it from now on. The\n\t * original atom is never rewritten. Promotion is an irreversible cross-suite\n\t * authorization face, so the first run only shows the target and asks the\n\t * user to re-run with `confirm`. Errors (unknown id, non-preference, already\n\t * promoted) surface as error results, never as thrown failures — a slash\n\t * command must not crash the host.\n\t */\n\tconst promoteCommand = registerCommand({\n\t\tname: \"promote\",\n\t\tdescription:\n\t\t\t\"Promote a memory preference to the user-default scope (visible in every suite; two-step — re-run with confirm)\",\n\t\targumentHint: \"<memoryId> [confirm]\",\n\t\texecute: async (args: string) => {\n\t\t\tconst tokens = args.trim().split(/\\s+/).filter(Boolean);\n\t\t\tconst memoryId = tokens[0] ?? \"\";\n\t\t\tconst confirmed = tokens[1] === \"confirm\";\n\t\t\tif (memoryId === \"\" || tokens.length > 2 || (tokens[1] !== undefined && !confirmed)) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\tmessage: \"Usage: /promote <memoryId> [confirm] — run memory_list for this suite's memory ids\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst record = store.get(memoryId, { owner });\n\t\t\tif (!record) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\tmessage: `No memory found with id ${memoryId}; run memory_list for this suite's memory ids`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst atom = record.atom;\n\t\t\tif (atom.memoryKind !== \"preference\" || atom.preference === undefined) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\tmessage: `${memoryId} is a fact, not a preference; only preferences can be promoted`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (store.get(userDefaultMemoryId(memoryId), { owner }) !== undefined) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\tmessage: `Preference ${memoryId} is already promoted to the user-default scope`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!confirmed) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t`Promotion target: \"${unwrapEgressStatement(statementOf(atom.payload))}\"\\n` +\n\t\t\t\t\t\t\"This makes the preference visible in EVERY suite (user-default scope, permanent). Nothing is promoted yet — re-run to confirm:\\n\" +\n\t\t\t\t\t\t`/promote ${memoryId} confirm`,\n\t\t\t\t};\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst promoted = promotePreferenceToUserDefault({\n\t\t\t\t\tatom,\n\t\t\t\t\tauthorizedBy: \"user:/promote\",\n\t\t\t\t\tconfirmedAt: new Date(now()).toISOString(),\n\t\t\t\t});\n\t\t\t\tconst { domainName, ledger } = resolveDomain();\n\t\t\t\tledger.append(promoted);\n\t\t\t\tstore.commit(promoted);\n\t\t\t\t// 向量投影埋点: 与 memory_write 同一异步旁路 (失败不阻塞命令返回)。\n\t\t\t\tvectorProjection.upsertAtom(promoted);\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\tmessage: `Promoted \"${unwrapEgressStatement(statementOf(promoted.payload))}\" to the user-default scope; it is now visible in every suite`,\n\t\t\t\t\tdata: { memoryId: promoted.memoryId, sourceMemoryId: memoryId, domain: domainName },\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn { status: \"error\" as const, message: error instanceof Error ? error.message : String(error) };\n\t\t\t}\n\t\t},\n\t});\n\n\t// memory.scheduler@1 plugin capability (宪法 §3 显式声明面): a declarative\n\t// marker only — the scheduler enforcement itself (per-instance single\n\t// lease, acquired above) stays carried by the host builtin implementation.\n\t// The declaration anchors \"this suite's memory scheduling is provided by\n\t// this plugin\" so the code Profile assembly check (requiresMemoryScheduler)\n\t// and third-party replacement detection have an explicit surface:\n\t// list()-visible, a same-id double provide fails explicitly (no override\n\t// priority), and after dispose a replacement provider can take the id.\n\tconst schedulerCapability = capabilities.provide({ id: \"memory.scheduler\", version: 1, kind: \"service\" }, () =>\n\t\tObject.freeze({\n\t\t\tid: \"memory.scheduler\",\n\t\t\tversion: 1,\n\t\t\towner: \"agent-forge.builtin.memory\",\n\t\t\tleaseScope: \"per-agent-instance\",\n\t\t}),\n\t);\n\n\t// ---- 征询门执行面 (2026-10-05 用户裁决「首次使用征询、拒绝/失败可跳过」) ----\n\t// memory_enable 是 consent-required / failed 态的唯一下载入口: consentGranted\n\t// 只在这里置位, recall/auto-recall 永不触发下载。decline 同时持久化\n\t// (writeMemoryConsentDeclined), 只抑制默认档——用户显式设置 memory.mode 后\n\t// 下次启用会在首次使用时再次走到征询门。\n\t// ---- 记忆模型下载控制面 (2026-10-05 流程裁决「后台预热、不阻塞提问」) ----\n\t// 生产入口 (交互模式会话绑定后) 经公共工具面调用 memory_enable download\n\t// 触发后台预热; 命令面 /memory off|retry 是用户的直接出口。decline/download\n\t// 核心在 memory/vector-channel.ts (slice 3b), 工具与命令面经\n\t// vectorChannelCtl.decline()/download() 薄委托; decline 持久化只抑制默认档。\n\t/**\n\t * Structured status for host consoles (公共命令结果 data, additive):\n\t * the TUI `/memory` console reads mode/channel/domain without parsing the\n\t * human message. `channel` mirrors the vector state machine; decline is\n\t * reported as \"off\" (the line's existing semantics).\n\t */\n\tconst memoryStatusSnapshot = (): {\n\t\treadonly mode: \"light\" | \"full\";\n\t\treadonly channel: \"off\" | \"consent-required\" | \"enabling\" | \"ready\" | \"degraded\" | \"failed\";\n\t\treadonly declined: boolean;\n\t\treadonly pendingUpgrade: boolean;\n\t\treadonly failureReason?: string;\n\t} => {\n\t\t// pending 尾巴只对仍有效的升档声明 (declined 分支里档位键已被删除, 显示\n\t\t// pending 会失实 — 2026-10-06 复审 P2-1)。\n\t\tconst declined = vectorChannelCtl.declined();\n\t\tconst pendingUpgrade = tierUpgradePending() && !declined;\n\t\tconst failureReason = vectorChannelCtl.failure()?.reason;\n\t\treturn {\n\t\t\tmode: memoryMode,\n\t\t\tchannel: declined ? \"off\" : vectorChannelCtl.rawState(),\n\t\t\tdeclined,\n\t\t\tpendingUpgrade,\n\t\t\t...(failureReason === undefined ? {} : { failureReason }),\n\t\t};\n\t};\n\tconst memoryStatusLine = (status: ReturnType<typeof memoryStatusSnapshot>): string => {\n\t\tconst modeLine = `mode=${status.mode}${status.pendingUpgrade ? \", auto-upgrade to full pending (next session)\" : \"\"}`;\n\t\tif (status.declined) {\n\t\t\treturn `${modeLine}, off (declined on this machine). Set memory.mode (light|full) in settings.json and restart the session to re-enable`;\n\t\t}\n\t\tif (status.channel === \"ready\") return `${modeLine}, ready`;\n\t\tif (status.channel === \"degraded\") return `${modeLine}, ready (degraded)`;\n\t\tif (status.channel === \"failed\") return `${modeLine}, failed: ${status.failureReason ?? \"unknown reason\"}`;\n\t\tif (status.channel === \"consent-required\") {\n\t\t\treturn `${modeLine}, waiting for the model download decision (/memory retry to start it)`;\n\t\t}\n\t\treturn `${modeLine}, loading models in the background`;\n\t};\n\tconst enableTool = registerTool({\n\t\tname: \"memory_enable\",\n\t\tlabel: \"Enable memory\",\n\t\tdescription:\n\t\t\t'Run or decline the one-time memory model download. The host starts it in the background at session start; call it with \"retry\" after a failure, or with \"decline\" when the user chooses to keep memory off',\n\t\tparameters: enableSchema,\n\t\texecute: async (first: unknown, second?: unknown) => {\n\t\t\tconst input = memoryToolInput(first, second);\n\t\t\tconst action: unknown = input.action;\n\t\t\tif (action !== \"download\" && action !== \"decline\" && action !== \"retry\") {\n\t\t\t\tthrow new Error('action must be \"download\", \"decline\", or \"retry\"');\n\t\t\t}\n\t\t\tif (action === \"decline\") return vectorChannelCtl.decline();\n\t\t\treturn vectorChannelCtl.download();\n\t\t},\n\t});\n\tconst memoryCommand = registerCommand({\n\t\tname: \"memory\",\n\t\tdescription:\n\t\t\t\"Memory controls: bare shows status; light|full switches the model preset (persisted, effective next session); off persists disable; retry re-runs the model download; forget <memoryId> [confirm] is the user-only physical delete (two-step)\",\n\t\targumentHint: \"[light|full|off|retry|forget <memoryId> [confirm]]\",\n\t\texecute: async (args: string) => {\n\t\t\tconst tokens = args.trim().split(/\\s+/).filter(Boolean);\n\t\t\tif (tokens[0] === \"forget\") {\n\t\t\t\tconst memoryId = tokens[1] ?? \"\";\n\t\t\t\tconst confirmed = tokens[2] === \"confirm\";\n\t\t\t\tif (memoryId === \"\" || tokens.length > 3 || (tokens[2] !== undefined && !confirmed)) {\n\t\t\t\t\treturn { status: \"error\" as const, message: \"Usage: /memory forget <memoryId> [confirm]\" };\n\t\t\t\t}\n\t\t\t\tconst { domain, domainName } = resolveDomain();\n\t\t\t\tconst unscoped = store.get(memoryId, { owner });\n\t\t\t\tif (unscoped === undefined) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\t\tmessage: `No memory found with id ${memoryId}; run memory_list for this suite's memory ids`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst isMember =\n\t\t\t\t\tdomain.kind === \"suite\" ? unscoped.atom.suiteId === domain.suiteId : unscoped.atom.suiteId === undefined;\n\t\t\t\tif (!isMember) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\t\tmessage: `${memoryId} belongs to another suite; each suite forgets only its own memories`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (!confirmed) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t`Forget target: \"${unwrapEgressStatement(statementOf(unscoped.atom.payload))}\"\\n` +\n\t\t\t\t\t\t\t\"This permanently deletes the memory (irreversible, purge-gated). Nothing is deleted yet — re-run to confirm:\\n\" +\n\t\t\t\t\t\t\t`/memory forget ${memoryId} confirm`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst result = purgeMemoryViaUserCommand(memoryId);\n\t\t\t\tif (result.status === \"completed\") {\n\t\t\t\t\tawait publish({\n\t\t\t\t\t\ttype: EVENT_TYPE,\n\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\tcorrelationId: capabilityManifest.id,\n\t\t\t\t\t\tdata: { action: \"forgotten\", memoryId, domain: domainName, batchId: result.batchId },\n\t\t\t\t\t});\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\t\tmessage: `Forgot ${memoryId} (${domainName}): the memory is physically deleted`,\n\t\t\t\t\t\tdata: { memoryId, domain: domainName, batchId: result.batchId },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn { status: \"error\" as const, message: `forget failed: ${result.status}` };\n\t\t\t}\n\t\t\tconst sub = args.trim().toLowerCase();\n\t\t\tif (sub === \"\" || sub === \"status\") {\n\t\t\t\tconst snapshot = memoryStatusSnapshot();\n\t\t\t\tconst statusResult: CapabilityCommandResult = {\n\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\tmessage: `memory: ${memoryStatusLine(snapshot)}`,\n\t\t\t\t\tdata: { memoryStatus: snapshot },\n\t\t\t\t};\n\t\t\t\treturn statusResult;\n\t\t\t}\n\t\t\tif (sub === \"light\" || sub === \"full\") {\n\t\t\t\t// 无\"已是该档\"早退: 持久化档位与会话内已解析档位是两回事——会话可能\n\t\t\t\t// 因默认档而运行 light, 用户降档仍需把持久化值落盘 (或覆盖旧档)。\n\t\t\t\twriteMemorySettingsMode(agentDir, sub);\n\t\t\t\t// 升/降档清了文件里的拒绝标记, 内存标记同步翻回: 用户最新的显式\n\t\t\t\t// 意图是启用——本会话恢复对当前预置的响应 (retry 可用), 新档与\n\t\t\t\t// 新模型下载在下一会话生效。\n\t\t\t\tvectorChannelCtl.clearDeclined();\n\t\t\t\t// 用户的显式档位表达取代本实例的自动升档声明: 降回 light 后 pending\n\t\t\t\t// 尾巴不再显示, 且显式 light 会让自动升档在后续写入中跳过 (复审 P2-1)。\n\t\t\t\tif (sub === \"light\") clearTierUpgrade();\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t`memory: preset ${sub} persisted (capabilities/builtin.memory.json). It takes effect next session — ` +\n\t\t\t\t\t\t(sub === \"full\"\n\t\t\t\t\t\t\t? \"the larger embedding model (bge-m3, hundreds of MB) downloads in the background at the next start, disk headroom ≥2GB, and write-side semantic dedup turns on. \"\n\t\t\t\t\t\t\t: \"\") +\n\t\t\t\t\t\t\"Existing memories carry over: the projection rebuilds onto the new model automatically.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\t// 命令面结果映射: 工具闭包的 completed/failed 面转 CapabilityCommandResult\n\t\t\t// 的 success/error; 行动清单/next 指引并入 message (命令结果无 actions 字段)。\n\t\t\tconst toCommandResult = (\n\t\t\t\tresult: Awaited<ReturnType<typeof vectorChannelCtl.download>>,\n\t\t\t): { status: \"success\" | \"error\"; message: string } => ({\n\t\t\t\tstatus: result.status === \"completed\" ? \"success\" : \"error\",\n\t\t\t\tmessage:\n\t\t\t\t\tresult.status === \"failed\"\n\t\t\t\t\t\t? [result.message, ...(result.actions ?? []), result.next].filter(Boolean).join(\" — \")\n\t\t\t\t\t\t: result.message,\n\t\t\t});\n\t\t\tif (sub === \"off\") return toCommandResult(vectorChannelCtl.decline());\n\t\t\tif (sub === \"retry\") return toCommandResult(await vectorChannelCtl.download());\n\t\t\treturn {\n\t\t\t\tstatus: \"error\" as const,\n\t\t\t\tmessage: \"Usage: /memory [light|full|off|retry|forget <memoryId> [confirm]]\",\n\t\t\t};\n\t\t},\n\t});\n\n\treturn { listTool, forgetTool, enableTool, memoryCommand, promoteCommand, schedulerCapability };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"command-face.d.ts","sourceRoot":"","sources":["../../src/memory/command-face.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 命令面(capability 拆分战役 slice 6):memory_list / memory_forget 工具、\n * /memory 与 /promote 命令、memory_enable 征询执行面与 memory.scheduler 能力\n * 声明。物理删除的授权引用构造在本面(用户命令链专用); decline/download 仍\n * 薄委托 vectorChannelCtl(slice 3b 先例, 经 deps 下的 channel 对象调用);\n * 搬移函数体逐字节保留。\n */\nimport type { CapabilityAPI, CapabilityCommandResult, DisposableRegistration } from \"@agent-forge/plugin-sdk\";\nimport { Type } from \"typebox\";\nimport { writeMemorySettingsMode } from \"./enabling.ts\";\nimport type { DurableMemoryLedgerV1 } from \"./ledger.ts\";\nimport { promotePreferenceToUserDefault } from \"./preference-promotion.ts\";\nimport type { MemoryPurgeGateV1 } from \"./purge.ts\";\nimport type { MemoryPurgeJournalV1 } from \"./purge-journal.ts\";\nimport type { MemoryStoreV1 } from \"./store.ts\";\nimport {\n\tforgetDomainMemory,\n\tlistDomainMemories,\n\ttype SuiteForgetAuthorizationRefV1,\n\ttype SuiteMemoryDomainV1,\n\ttype SuiteMemoryListEntryV1,\n} from \"./suite-memory.ts\";\nimport type { MemoryVectorChannelV1 } from \"./vector-channel.ts\";\nimport type { MemoryVectorProjectionV1 } from \"./vector-projection.ts\";\nimport { EVENT_TYPE } from \"./write-face.ts\";\n\nconst DEFAULT_LIST_LIMIT = 20;\n\nconst listSchema = Type.Object({\n\tlimit: Type.Optional(\n\t\tType.Integer({ description: \"Maximum number of entries to list (1-100, default 20)\", minimum: 1, maximum: 100 }),\n\t),\n});\n\nconst forgetSchema = Type.Object({\n\tmemoryId: Type.String({\n\t\tdescription: \"The memoryId of the memory to forget, as returned by memory_write or memory_list\",\n\t}),\n});\n\nconst enableSchema = Type.Object({\n\taction: Type.Union([Type.Literal(\"download\"), Type.Literal(\"decline\"), Type.Literal(\"retry\")], {\n\t\tdescription:\n\t\t\t'\"download\" / \"retry\" run the one-time model download (retry re-runs after a failure); \"decline\" persists memory off for this machine',\n\t}),\n});\n\n/** Canonical memoryId of the promoted copy of one preference (promotePreferenceToUserDefault suffix). */\nconst userDefaultMemoryId = (memoryId: string): string => `${memoryId}-user-default`;\n\n/**\n * 命令面对 capability 闭包的显式依赖视图 (slice 6): 逐项来自\n * createMemoryCapabilityHarness 的闭包捕获核实。状态机 (vectorChannelCtl)、\n * 写侧投影 (vectorProjection) 与 purge 组件归 capability 装配所有, 本模块经\n * 对象只读消费; capability 模块级纯函数经 deps 注入避免双头定义。\n */\nexport interface MemoryCommandFaceDepsV1 {\n\t/** 工具注册面 (api.registerTool): memory_list/forget/enable 经同一公共通道注册。 */\n\treadonly registerTool: CapabilityAPI[\"registerTool\"];\n\t/** 命令注册面 (api.registerCommand): /memory 与 /promote。 */\n\treadonly registerCommand: CapabilityAPI[\"registerCommand\"];\n\t/** 事件发布面 (api.publish): memory.changed forgotten 事件。 */\n\treadonly publish: CapabilityAPI[\"publish\"];\n\t/** 能力声明面 (api.capabilities): memory.scheduler@1 provide。 */\n\treadonly capabilities: CapabilityAPI[\"capabilities\"];\n\t/** 检索行 owner (capability.BUILTIN_MEMORY_OWNER)。 */\n\treadonly owner: string;\n\t/** 会话 id (harness sessionId): forget 授权引用 confirmationRef 组成。 */\n\treadonly sessionId: string;\n\t/** capability 清单 (capabilityManifest): issuedBy / authorizedBy / 事件 correlationId 来源。 */\n\treadonly manifest: { readonly id: string };\n\t/** agent 根目录 (MemoryCapabilityContext.agentDir): 档位持久化路径域。 */\n\treadonly agentDir: string;\n\t/** 已解析的全局档位 (harness memoryMode, off 已被工厂入口拦截)。 */\n\treadonly memoryMode: \"light\" | \"full\";\n\t/** 时钟 (harness now)。 */\n\treadonly now: () => number;\n\t/** canonical store (per-capability 单例): 列表/成员判定/晋升回查。 */\n\treadonly store: MemoryStoreV1;\n\t/** purge 门 (capability.purgeGate): 物理删除唯一生产入口的授权面。 */\n\treadonly purgeGate: MemoryPurgeGateV1;\n\t/** purge 日志 (capability.purgeJournal)。 */\n\treadonly purgeJournal: MemoryPurgeJournalV1;\n\t/** 写侧投影 (slice 3a 的 vectorProjection): forget 批次的 index 副本分派与晋升埋点。 */\n\treadonly vectorProjection: MemoryVectorProjectionV1;\n\t/** 向量通道 (slice 3b 的 vectorChannelCtl): 状态行与 decline/download 薄委托。 */\n\treadonly vectorChannelCtl: MemoryVectorChannelV1;\n\t/** 域解析 (capability.resolveDomain): 每次调用时惰性解析 (B1 语义)。 */\n\treadonly resolveDomain: () => {\n\t\treadonly domain: SuiteMemoryDomainV1;\n\t\treadonly domainName: string;\n\t\treadonly ledger: DurableMemoryLedgerV1;\n\t};\n\t// ---- capability 模块级纯函数 (留守方, 经 deps 注入避免双头定义) ----\n\treadonly assertNonEmptyString: (value: unknown, label: string) => asserts value is string;\n\treadonly memoryToolInput: (first: unknown, second: unknown) => Record<string, unknown>;\n\treadonly statementOf: (payload: unknown) => string;\n\treadonly unwrapEgressStatement: (statement: string) => string;\n\t// ---- 写入面闭包视图 (slice 5 的 writeFace): 升档声明状态归 write-face 所有 ----\n\t/** 升档声明只读视图 (/memory 状态行 pending 尾巴)。 */\n\treadonly tierUpgradePending: () => boolean;\n\t/** 用户显式档位表达取代本实例升档声明 (/memory light)。 */\n\treadonly clearTierUpgrade: () => void;\n}\n\n/** 命令面工厂产物: 注册项集合 (capability registrations 按既有顺序收集)。 */\nexport interface MemoryCommandFaceV1 {\n\t/** memory_list 工具注册项。 */\n\treadonly listTool: DisposableRegistration;\n\t/** memory_forget 工具注册项 (仅登记请求, 物理删除在 /memory forget)。 */\n\treadonly forgetTool: DisposableRegistration;\n\t/** memory_enable 工具注册项 (征询门执行面)。 */\n\treadonly enableTool: DisposableRegistration;\n\t/** /memory 命令注册项。 */\n\treadonly memoryCommand: DisposableRegistration;\n\t/** /promote 命令注册项。 */\n\treadonly promoteCommand: DisposableRegistration;\n\t/** memory.scheduler@1 plugin capability 声明注册项。 */\n\treadonly schedulerCapability: DisposableRegistration;\n}\n\nexport function createMemoryCommandFace(deps: MemoryCommandFaceDepsV1): MemoryCommandFaceV1 {\n\tconst {\n\t\tregisterTool,\n\t\tregisterCommand,\n\t\tpublish,\n\t\tcapabilities,\n\t\towner,\n\t\tsessionId,\n\t\tagentDir,\n\t\tmemoryMode,\n\t\tnow,\n\t\tstore,\n\t\tpurgeGate,\n\t\tpurgeJournal,\n\t\tvectorProjection,\n\t\tvectorChannelCtl,\n\t\tresolveDomain,\n\t\tmemoryToolInput,\n\t\tstatementOf,\n\t\tunwrapEgressStatement,\n\t\ttierUpgradePending,\n\t\tclearTierUpgrade,\n\t} = deps;\n\tconst { manifest: capabilityManifest } = deps;\n\n\t/** Recency-first payload projection: unwraps the `{ statement }` payload convention. */\n\tfunction entryToToolEntry(entry: SuiteMemoryListEntryV1): Record<string, unknown> {\n\t\treturn {\n\t\t\tmemoryId: entry.memoryId,\n\t\t\tkind: entry.memoryKind,\n\t\t\tstatement: statementOf(entry.payload),\n\t\t\toccurredAt: entry.occurredAt,\n\t\t\t...(entry.preference === undefined\n\t\t\t\t? {}\n\t\t\t\t: {\n\t\t\t\t\t\tpreference: {\n\t\t\t\t\t\t\tsubject: entry.preference.subject,\n\t\t\t\t\t\t\tkey: entry.preference.key,\n\t\t\t\t\t\t\tscopeLevel: entry.preference.scopeLevel,\n\t\t\t\t\t\t\tcrossSuiteVisible: entry.preference.crossSuiteVisible,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t};\n\t}\n\n\tconst listTool = registerTool({\n\t\tname: \"memory_list\",\n\t\tlabel: \"List memories\",\n\t\tdescription: \"List this suite's durable memories (the explicit management surface for personal data)\",\n\t\tparameters: listSchema,\n\t\texecute: async (first: unknown, second?: unknown) => {\n\t\t\tconst input = memoryToolInput(first, second);\n\t\t\tconst rawLimit: unknown = input.limit;\n\t\t\tconst limit =\n\t\t\t\trawLimit === undefined\n\t\t\t\t\t? DEFAULT_LIST_LIMIT\n\t\t\t\t\t: ((): number => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\ttypeof rawLimit !== \"number\" ||\n\t\t\t\t\t\t\t\t!Number.isSafeInteger(rawLimit) ||\n\t\t\t\t\t\t\t\trawLimit < 1 ||\n\t\t\t\t\t\t\t\trawLimit > 100\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthrow new Error(\"limit must be an integer between 1 and 100\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn rawLimit;\n\t\t\t\t\t\t})();\n\t\t\tconst { domain } = resolveDomain();\n\t\t\tconst page = listDomainMemories({ store }, { owner, domain });\n\t\t\treturn {\n\t\t\t\tdomain: page.domain,\n\t\t\t\tentries: page.entries.slice(0, limit).map(entryToToolEntry),\n\t\t\t\ttotal: page.entries.length,\n\t\t\t\tpreferenceCount: page.preferenceCount,\n\t\t\t\tfactCount: page.factCount,\n\t\t\t\tfilter: page.filter,\n\t\t\t};\n\t\t},\n\t});\n\n\t/**\n\t * 物理删除唯一生产入口 (诚实化设计 §2, 2026-10-05 裁决): 用户命令链\n\t * `/memory forget <id> confirm`。授权引用由命令分发构造 (structured\n\t * confirmationRef `memory-forget-command:<session>:<memoryId>:confirmed`),\n\t * 模型工具面不再签发 user-immediate 授权 (记忆系统设计 :997 — 授权不能由\n\t * 模型生成)。\n\t */\n\tconst purgeMemoryViaUserCommand = (memoryId: string) => {\n\t\tconst { domain, ledger } = resolveDomain();\n\t\tconst authorizationRef: SuiteForgetAuthorizationRefV1 = {\n\t\t\tmode: \"user-immediate\",\n\t\t\tissuedAt: now(),\n\t\t\tissuedBy: `${capabilityManifest.id}:/memory-forget-confirm`,\n\t\t\tconfirmationRef: `memory-forget-command:${sessionId}:${memoryId}:confirmed`,\n\t\t};\n\t\treturn forgetDomainMemory(\n\t\t\t{\n\t\t\t\tstore,\n\t\t\t\tpurgeGate,\n\t\t\t\tpurgeJournal,\n\t\t\t\t// index 副本分派 (混合检索工程化): canonical 走下方原回调, 向量投影由\n\t\t\t\t// suite-memory 的 executePurgeBatch 按副本路由到这里。\n\t\t\t\tpurgeIndexReplica: vectorProjection.purgeMemories,\n\t\t\t\tnow,\n\t\t\t},\n\t\t\t{\n\t\t\t\towner,\n\t\t\t\tdomain,\n\t\t\t\tmemoryId,\n\t\t\t\tauthorizedBy: `${capabilityManifest.id}:memory-forget-command`,\n\t\t\t\tauthorizationRef,\n\t\t\t},\n\t\t\t(memoryIds) => {\n\t\t\t\tconst purged = new Set(memoryIds);\n\t\t\t\t// Physical replica purge: rewrite the durable ledger without the\n\t\t\t\t// purged atoms, then evict them from the in-memory store so the\n\t\t\t\t// running process cannot recall them either (both idempotent for\n\t\t\t\t// purge_eligible retries).\n\t\t\t\tledger.rewrite(ledger.atomsSnapshot().filter((atom) => !purged.has(atom.memoryId)));\n\t\t\t\tfor (const id of memoryIds) store.evict(id);\n\t\t\t},\n\t\t);\n\t};\n\n\tconst forgetTool = registerTool({\n\t\tname: \"memory_forget\",\n\t\tlabel: \"File a forget request\",\n\t\tdescription:\n\t\t\t\"File a request to forget one memory of this suite by memoryId. This tool never deletes anything — physical deletion is user-only: the user confirms via /memory forget <memoryId> confirm\",\n\t\tparameters: forgetSchema,\n\t\texecute: async (first: unknown, second?: unknown) => {\n\t\t\tconst input = memoryToolInput(first, second);\n\t\t\tdeps.assertNonEmptyString(input.memoryId, \"memoryId\");\n\t\t\tconst { domain, domainName } = resolveDomain();\n\t\t\tconst unscoped = store.get(input.memoryId, { owner });\n\t\t\tif (unscoped === undefined) {\n\t\t\t\treturn { status: \"not_found\" as const, memoryId: input.memoryId };\n\t\t\t}\n\t\t\t// 域成员判定与 forgetDomainMemory 同判据 (suiteId 匹配 / legacy 为\n\t\t\t// undefined): 请求面同样拒绝外域 id — 模型连\"请求遗忘\"都不能指向别的域。\n\t\t\tconst isMember =\n\t\t\t\tdomain.kind === \"suite\" ? unscoped.atom.suiteId === domain.suiteId : unscoped.atom.suiteId === undefined;\n\t\t\tif (!isMember) {\n\t\t\t\treturn { status: \"foreign_domain\" as const, memoryId: input.memoryId };\n\t\t\t}\n\t\t\t// 请求的登记价值由返回文本承载 (转告用户确认命令); 无进程内状态 —\n\t\t\t// 重复请求幂等 (同一提示再次返回)。\n\t\t\treturn {\n\t\t\t\tstatus: \"requested\" as const,\n\t\t\t\tmemoryId: input.memoryId,\n\t\t\t\trequest:\n\t\t\t\t\t`Forget request filed for \"${unwrapEgressStatement(statementOf(unscoped.atom.payload))}\" in domain ${domainName}. ` +\n\t\t\t\t\t`Nothing is deleted yet — tell the user to confirm the deletion with: /memory forget ${input.memoryId} confirm`,\n\t\t\t};\n\t\t},\n\t});\n\n\t/**\n\t * /promote (偏好晋升触发, B2; 2026-10-05 诚实化裁决起两步确认): the production\n\t * caller of {@link promotePreferenceToUserDefault}. Promotes one of THIS\n\t * session's preferences to the user-default scope: the promoted canonical atom\n\t * is appended to the session domain's durable ledger and committed to the\n\t * store, so every suite's preference-card read (which applies the suite read\n\t * boundary across all of the owner's ledgers) sees it from now on. The\n\t * original atom is never rewritten. Promotion is an irreversible cross-suite\n\t * authorization face, so the first run only shows the target and asks the\n\t * user to re-run with `confirm`. Errors (unknown id, non-preference, already\n\t * promoted) surface as error results, never as thrown failures — a slash\n\t * command must not crash the host.\n\t */\n\tconst promoteCommand = registerCommand({\n\t\tname: \"promote\",\n\t\tdescription:\n\t\t\t\"Promote a memory preference to the user-default scope (visible in every suite; two-step — re-run with confirm)\",\n\t\targumentHint: \"<memoryId> [confirm]\",\n\t\texecute: async (args: string) => {\n\t\t\tconst tokens = args.trim().split(/\\s+/).filter(Boolean);\n\t\t\tconst memoryId = tokens[0] ?? \"\";\n\t\t\tconst confirmed = tokens[1] === \"confirm\";\n\t\t\tif (memoryId === \"\" || tokens.length > 2 || (tokens[1] !== undefined && !confirmed)) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\tmessage: \"Usage: /promote <memoryId> [confirm] — run memory_list for this suite's memory ids\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst record = store.get(memoryId, { owner });\n\t\t\tif (!record) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\tmessage: `No memory found with id ${memoryId}; run memory_list for this suite's memory ids`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst atom = record.atom;\n\t\t\tif (atom.memoryKind !== \"preference\" || atom.preference === undefined) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\tmessage: `${memoryId} is a fact, not a preference; only preferences can be promoted`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (store.get(userDefaultMemoryId(memoryId), { owner }) !== undefined) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\tmessage: `Preference ${memoryId} is already promoted to the user-default scope`,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!confirmed) {\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t`Promotion target: \"${unwrapEgressStatement(statementOf(atom.payload))}\"\\n` +\n\t\t\t\t\t\t\"This makes the preference visible in EVERY suite (user-default scope, permanent). Nothing is promoted yet — re-run to confirm:\\n\" +\n\t\t\t\t\t\t`/promote ${memoryId} confirm`,\n\t\t\t\t};\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst promoted = promotePreferenceToUserDefault({\n\t\t\t\t\tatom,\n\t\t\t\t\tauthorizedBy: \"user:/promote\",\n\t\t\t\t\tconfirmedAt: new Date(now()).toISOString(),\n\t\t\t\t});\n\t\t\t\tconst { domainName, ledger } = resolveDomain();\n\t\t\t\tledger.append(promoted);\n\t\t\t\tstore.commit(promoted);\n\t\t\t\t// 向量投影埋点: 与 memory_write 同一异步旁路 (失败不阻塞命令返回)。\n\t\t\t\tvectorProjection.upsertAtom(promoted);\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\tmessage: `Promoted \"${unwrapEgressStatement(statementOf(promoted.payload))}\" to the user-default scope; it is now visible in every suite`,\n\t\t\t\t\tdata: { memoryId: promoted.memoryId, sourceMemoryId: memoryId, domain: domainName },\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\treturn { status: \"error\" as const, message: error instanceof Error ? error.message : String(error) };\n\t\t\t}\n\t\t},\n\t});\n\n\t// memory.scheduler@1 plugin capability (宪法 §3 显式声明面): a declarative\n\t// marker only — the scheduler enforcement itself (per-instance single\n\t// lease, acquired above) stays carried by the host builtin implementation.\n\t// The declaration anchors \"this suite's memory scheduling is provided by\n\t// this plugin\" so the code Profile assembly check (requiresMemoryScheduler)\n\t// and third-party replacement detection have an explicit surface:\n\t// list()-visible, a same-id double provide fails explicitly (no override\n\t// priority), and after dispose a replacement provider can take the id.\n\tconst schedulerCapability = capabilities.provide({ id: \"memory.scheduler\", version: 1, kind: \"service\" }, () =>\n\t\tObject.freeze({\n\t\t\tid: \"memory.scheduler\",\n\t\t\tversion: 1,\n\t\t\towner: \"agent-forge.builtin.memory\",\n\t\t\tleaseScope: \"per-agent-instance\",\n\t\t}),\n\t);\n\n\t// ---- 征询门执行面 (2026-10-05 用户裁决「首次使用征询、拒绝/失败可跳过」) ----\n\t// memory_enable 是 consent-required / failed 态的唯一下载入口: consentGranted\n\t// 只在这里置位, recall/auto-recall 永不触发下载。decline 同时持久化\n\t// (writeMemoryConsentDeclined), 只抑制默认档——用户显式设置 memory.mode 后\n\t// 下次启用会在首次使用时再次走到征询门。\n\t// ---- 记忆模型下载控制面 (2026-10-05 流程裁决「后台预热、不阻塞提问」) ----\n\t// 生产入口 (交互模式会话绑定后) 经公共工具面调用 memory_enable download\n\t// 触发后台预热; 命令面 /memory off|retry 是用户的直接出口。decline/download\n\t// 核心在 memory/vector-channel.ts (slice 3b), 工具与命令面经\n\t// vectorChannelCtl.decline()/download() 薄委托; decline 持久化只抑制默认档。\n\t/**\n\t * Structured status for host consoles (公共命令结果 data, additive):\n\t * the TUI `/memory` console reads mode/channel/domain without parsing the\n\t * human message. `channel` mirrors the vector state machine; decline is\n\t * reported as \"off\" (the line's existing semantics).\n\t */\n\tconst memoryStatusSnapshot = (): {\n\t\treadonly mode: \"light\" | \"full\";\n\t\treadonly channel: \"off\" | \"consent-required\" | \"enabling\" | \"ready\" | \"degraded\" | \"failed\";\n\t\treadonly declined: boolean;\n\t\treadonly pendingUpgrade: boolean;\n\t\treadonly failureReason?: string;\n\t} => {\n\t\t// pending 尾巴只对仍有效的升档声明 (declined 分支里档位键已被删除, 显示\n\t\t// pending 会失实 — 2026-10-06 复审 P2-1)。\n\t\tconst declined = vectorChannelCtl.declined();\n\t\tconst pendingUpgrade = tierUpgradePending() && !declined;\n\t\tconst failureReason = vectorChannelCtl.failure()?.reason;\n\t\treturn {\n\t\t\tmode: memoryMode,\n\t\t\tchannel: declined ? \"off\" : vectorChannelCtl.rawState(),\n\t\t\tdeclined,\n\t\t\tpendingUpgrade,\n\t\t\t...(failureReason === undefined ? {} : { failureReason }),\n\t\t};\n\t};\n\tconst memoryStatusLine = (status: ReturnType<typeof memoryStatusSnapshot>): string => {\n\t\tconst modeLine = `mode=${status.mode}${status.pendingUpgrade ? \", auto-upgrade to full pending (next session)\" : \"\"}`;\n\t\tif (status.declined) {\n\t\t\treturn `${modeLine}, off (declined on this machine). Set memory.mode (light|full) in settings.json and restart the session to re-enable`;\n\t\t}\n\t\tif (status.channel === \"ready\") return `${modeLine}, ready`;\n\t\tif (status.channel === \"degraded\") return `${modeLine}, ready (degraded)`;\n\t\tif (status.channel === \"failed\") return `${modeLine}, failed: ${status.failureReason ?? \"unknown reason\"}`;\n\t\tif (status.channel === \"consent-required\") {\n\t\t\treturn `${modeLine}, waiting for the model download decision (/memory retry to start it)`;\n\t\t}\n\t\treturn `${modeLine}, loading models in the background`;\n\t};\n\tconst enableTool = registerTool({\n\t\tname: \"memory_enable\",\n\t\tlabel: \"Enable memory\",\n\t\tdescription:\n\t\t\t'Run or decline the one-time memory model download. The host starts it in the background at session start; call it with \"retry\" after a failure, or with \"decline\" when the user chooses to keep memory off',\n\t\tparameters: enableSchema,\n\t\texecute: async (first: unknown, second?: unknown) => {\n\t\t\tconst input = memoryToolInput(first, second);\n\t\t\tconst action: unknown = input.action;\n\t\t\tif (action !== \"download\" && action !== \"decline\" && action !== \"retry\") {\n\t\t\t\tthrow new Error('action must be \"download\", \"decline\", or \"retry\"');\n\t\t\t}\n\t\t\tif (action === \"decline\") return vectorChannelCtl.decline();\n\t\t\treturn vectorChannelCtl.download();\n\t\t},\n\t});\n\tconst memoryCommand = registerCommand({\n\t\tname: \"memory\",\n\t\tdescription:\n\t\t\t\"Memory controls: bare shows status; light|full switches the model preset (persisted, effective next session); off persists disable; retry re-runs the model download; forget <memoryId> [confirm] is the user-only physical delete (two-step)\",\n\t\targumentHint: \"[light|full|off|retry|forget <memoryId> [confirm]]\",\n\t\texecute: async (args: string) => {\n\t\t\tconst tokens = args.trim().split(/\\s+/).filter(Boolean);\n\t\t\tif (tokens[0] === \"forget\") {\n\t\t\t\tconst memoryId = tokens[1] ?? \"\";\n\t\t\t\tconst confirmed = tokens[2] === \"confirm\";\n\t\t\t\tif (memoryId === \"\" || tokens.length > 3 || (tokens[2] !== undefined && !confirmed)) {\n\t\t\t\t\treturn { status: \"error\" as const, message: \"Usage: /memory forget <memoryId> [confirm]\" };\n\t\t\t\t}\n\t\t\t\tconst { domain, domainName } = resolveDomain();\n\t\t\t\tconst unscoped = store.get(memoryId, { owner });\n\t\t\t\tif (unscoped === undefined) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\t\tmessage: `No memory found with id ${memoryId}; run memory_list for this suite's memory ids`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst isMember =\n\t\t\t\t\tdomain.kind === \"suite\" ? unscoped.atom.suiteId === domain.suiteId : unscoped.atom.suiteId === undefined;\n\t\t\t\tif (!isMember) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"error\" as const,\n\t\t\t\t\t\tmessage: `${memoryId} belongs to another suite; each suite forgets only its own memories`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tif (!confirmed) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t`Forget target: \"${unwrapEgressStatement(statementOf(unscoped.atom.payload))}\"\\n` +\n\t\t\t\t\t\t\t\"This permanently deletes the memory (irreversible, purge-gated). Nothing is deleted yet — re-run to confirm:\\n\" +\n\t\t\t\t\t\t\t`/memory forget ${memoryId} confirm`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst result = purgeMemoryViaUserCommand(memoryId);\n\t\t\t\tif (result.status === \"completed\") {\n\t\t\t\t\tawait publish({\n\t\t\t\t\t\ttype: EVENT_TYPE,\n\t\t\t\t\t\tversion: 1,\n\t\t\t\t\t\tcorrelationId: capabilityManifest.id,\n\t\t\t\t\t\tdata: { action: \"forgotten\", memoryId, domain: domainName, batchId: result.batchId },\n\t\t\t\t\t});\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\t\tmessage: `Forgot ${memoryId} (${domainName}): the memory is physically deleted`,\n\t\t\t\t\t\tdata: { memoryId, domain: domainName, batchId: result.batchId },\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn { status: \"error\" as const, message: `forget failed: ${result.status}` };\n\t\t\t}\n\t\t\tconst sub = args.trim().toLowerCase();\n\t\t\tif (sub === \"\" || sub === \"status\") {\n\t\t\t\tconst snapshot = memoryStatusSnapshot();\n\t\t\t\tconst statusResult: CapabilityCommandResult = {\n\t\t\t\t\tstatus: \"success\",\n\t\t\t\t\tmessage: `memory: ${memoryStatusLine(snapshot)}`,\n\t\t\t\t\tdata: { memoryStatus: snapshot },\n\t\t\t\t};\n\t\t\t\treturn statusResult;\n\t\t\t}\n\t\t\tif (sub === \"light\" || sub === \"full\") {\n\t\t\t\t// 无\"已是该档\"早退: 持久化档位与会话内已解析档位是两回事——会话可能\n\t\t\t\t// 因默认档而运行 light, 用户降档仍需把持久化值落盘 (或覆盖旧档)。\n\t\t\t\twriteMemorySettingsMode(agentDir, sub);\n\t\t\t\t// 升/降档清了文件里的拒绝标记, 内存标记同步翻回: 用户最新的显式\n\t\t\t\t// 意图是启用——本会话恢复对当前预置的响应 (retry 可用), 新档与\n\t\t\t\t// 新模型下载在下一会话生效。\n\t\t\t\tvectorChannelCtl.clearDeclined();\n\t\t\t\t// 用户的显式档位表达取代本实例的自动升档声明: 降回 light 后 pending\n\t\t\t\t// 尾巴不再显示, 且显式 light 会让自动升档在后续写入中跳过 (复审 P2-1)。\n\t\t\t\tif (sub === \"light\") clearTierUpgrade();\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"success\" as const,\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t`memory: preset ${sub} persisted (capabilities/builtin.memory.json). It takes effect next session — ` +\n\t\t\t\t\t\t(sub === \"full\"\n\t\t\t\t\t\t\t? \"the larger embedding model (bge-m3, hundreds of MB) downloads in the background at the next start, disk headroom ≥2GB, and write-side semantic dedup turns on. \"\n\t\t\t\t\t\t\t: \"\") +\n\t\t\t\t\t\t\"Existing memories carry over: the projection rebuilds onto the new model automatically.\",\n\t\t\t\t};\n\t\t\t}\n\t\t\t// 命令面结果映射: 工具闭包的 completed/failed 面转 CapabilityCommandResult\n\t\t\t// 的 success/error; 行动清单/next 指引并入 message (命令结果无 actions 字段)。\n\t\t\tconst toCommandResult = (\n\t\t\t\tresult: Awaited<ReturnType<typeof vectorChannelCtl.download>>,\n\t\t\t): { status: \"success\" | \"error\"; message: string } => ({\n\t\t\t\tstatus: result.status === \"completed\" ? \"success\" : \"error\",\n\t\t\t\tmessage:\n\t\t\t\t\tresult.status === \"failed\"\n\t\t\t\t\t\t? [result.message, ...(result.actions ?? []), result.next].filter(Boolean).join(\" — \")\n\t\t\t\t\t\t: result.message,\n\t\t\t});\n\t\t\tif (sub === \"off\") return toCommandResult(vectorChannelCtl.decline());\n\t\t\tif (sub === \"retry\") return toCommandResult(await vectorChannelCtl.download());\n\t\t\treturn {\n\t\t\t\tstatus: \"error\" as const,\n\t\t\t\tmessage: \"Usage: /memory [light|full|off|retry|forget <memoryId> [confirm]]\",\n\t\t\t};\n\t\t},\n\t});\n\n\treturn { listTool, forgetTool, enableTool, memoryCommand, promoteCommand, schedulerCapability };\n}\n"]}
|