berry-agent 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +96 -0
- package/dist/.api-emit.stamp +1 -0
- package/dist/.build-meta.json +6 -0
- package/dist/agent/events.js +1 -0
- package/dist/agent/index.js +2 -0
- package/dist/agent/loop.js +139 -0
- package/dist/agent/queue.js +119 -0
- package/dist/agent/stream.js +62 -0
- package/dist/agent/tools-batch.js +221 -0
- package/dist/agent/types.js +8 -0
- package/dist/api/berry-agent-llm.d.ts +18 -0
- package/dist/api/berry-agent.d.ts +9 -0
- package/dist/api/surface.json +1632 -0
- package/dist/api/tsconfig.paths.json +12 -0
- package/dist/api/typebox-compile.d.ts +2 -0
- package/dist/api/typebox-value.d.ts +2 -0
- package/dist/api/typebox.d.ts +2 -0
- package/dist/browser/cdp.js +256 -0
- package/dist/browser/codes.js +31 -0
- package/dist/browser/discover.js +107 -0
- package/dist/browser/engine.js +169 -0
- package/dist/browser/index.js +17 -0
- package/dist/browser/install.js +342 -0
- package/dist/browser/page.js +321 -0
- package/dist/browser/service.js +158 -0
- package/dist/browser/tools.js +198 -0
- package/dist/browser/types.js +81 -0
- package/dist/channels/ask-queue.js +82 -0
- package/dist/channels/commands.js +129 -0
- package/dist/channels/engine/cell.js +143 -0
- package/dist/channels/engine/diff.js +143 -0
- package/dist/channels/engine/engine.js +416 -0
- package/dist/channels/engine/index.js +8 -0
- package/dist/channels/engine/input-keys.js +86 -0
- package/dist/channels/engine/input.js +596 -0
- package/dist/channels/engine/memory-io.js +71 -0
- package/dist/channels/engine/process-io.js +38 -0
- package/dist/channels/engine/types.js +17 -0
- package/dist/channels/engine/width.js +122 -0
- package/dist/channels/index.js +15 -0
- package/dist/channels/registry.js +56 -0
- package/dist/channels/sdk/admit.js +29 -0
- package/dist/channels/sdk/backend.js +102 -0
- package/dist/channels/sdk/cursor.js +56 -0
- package/dist/channels/sdk/index.js +20 -0
- package/dist/channels/sdk/jsonl.js +208 -0
- package/dist/channels/sdk/protocol.js +24 -0
- package/dist/channels/sdk/schema.js +91 -0
- package/dist/channels/sdk/wire-core.js +446 -0
- package/dist/channels/service.js +169 -0
- package/dist/channels/tui/autocomplete/autocomplete.js +42 -0
- package/dist/channels/tui/autocomplete/file-mentions.js +106 -0
- package/dist/channels/tui/autocomplete/popup.js +148 -0
- package/dist/channels/tui/autocomplete/provider.js +7 -0
- package/dist/channels/tui/autocomplete/token.js +68 -0
- package/dist/channels/tui/backend/ansi-rows.js +211 -0
- package/dist/channels/tui/backend/main-screen.js +207 -0
- package/dist/channels/tui/backend/osc.js +91 -0
- package/dist/channels/tui/backend/transcript.js +230 -0
- package/dist/channels/tui/backend/tui-backend.js +915 -0
- package/dist/channels/tui/editor/editor-model.js +543 -0
- package/dist/channels/tui/editor/editor-view.js +140 -0
- package/dist/channels/tui/editor/editor.js +275 -0
- package/dist/channels/tui/editor/undo-stack.js +35 -0
- package/dist/channels/tui/editor/visual-lines.js +126 -0
- package/dist/channels/tui/editor/word-nav.js +106 -0
- package/dist/channels/tui/history/history-viewer.js +403 -0
- package/dist/channels/tui/index.js +3 -0
- package/dist/channels/tui/layout.js +167 -0
- package/dist/channels/tui/markdown/blocks.js +111 -0
- package/dist/channels/tui/markdown/inline.js +75 -0
- package/dist/channels/tui/markdown/markdown.js +182 -0
- package/dist/channels/tui/memory/memory-viewer.js +540 -0
- package/dist/channels/tui/overlay/alt-screen.js +105 -0
- package/dist/channels/tui/overlay/overlay.js +57 -0
- package/dist/channels/tui/overlay/select-confirm.js +156 -0
- package/dist/channels/tui/panels/todo-panel.js +54 -0
- package/dist/channels/tui/panels/tool-progress-panel.js +93 -0
- package/dist/channels/tui/scroll/scroll-view.js +254 -0
- package/dist/channels/tui/status/status-line.js +76 -0
- package/dist/channels/tui/text.js +38 -0
- package/dist/channels/tui/theme.js +41 -0
- package/dist/channels/types.js +11 -0
- package/dist/channels/ui-core.js +209 -0
- package/dist/checkpoint/capture.js +45 -0
- package/dist/checkpoint/codes.js +33 -0
- package/dist/checkpoint/command.js +82 -0
- package/dist/checkpoint/gate.js +48 -0
- package/dist/checkpoint/index.js +20 -0
- package/dist/checkpoint/restore.js +172 -0
- package/dist/checkpoint/store.js +247 -0
- package/dist/checkpoint/types.js +4 -0
- package/dist/checkpoint/walk.js +146 -0
- package/dist/compaction/ccr-tools.js +112 -0
- package/dist/compaction/ccr.js +84 -0
- package/dist/compaction/codes.js +21 -0
- package/dist/compaction/index.js +18 -0
- package/dist/compaction/policy.js +200 -0
- package/dist/compaction/service.js +422 -0
- package/dist/compaction/slots.js +121 -0
- package/dist/compaction/types.js +10 -0
- package/dist/context/codes.js +40 -0
- package/dist/context/events.js +160 -0
- package/dist/context/index.js +13 -0
- package/dist/context/logger.js +136 -0
- package/dist/context/scope.js +182 -0
- package/dist/context/workspace.js +104 -0
- package/dist/contracts/agent-events.d.ts +73 -0
- package/dist/contracts/agent-events.js +16 -0
- package/dist/contracts/api.d.ts +249 -0
- package/dist/contracts/api.js +299 -0
- package/dist/contracts/approval.d.ts +37 -0
- package/dist/contracts/approval.js +9 -0
- package/dist/contracts/env-ref.d.ts +41 -0
- package/dist/contracts/env-ref.js +32 -0
- package/dist/contracts/errors.d.ts +56 -0
- package/dist/contracts/errors.js +266 -0
- package/dist/contracts/events.d.ts +70 -0
- package/dist/contracts/events.js +329 -0
- package/dist/contracts/index.d.ts +32 -0
- package/dist/contracts/index.js +26 -0
- package/dist/contracts/llm.d.ts +275 -0
- package/dist/contracts/llm.js +12 -0
- package/dist/contracts/messages.d.ts +63 -0
- package/dist/contracts/messages.js +65 -0
- package/dist/contracts/redact.d.ts +46 -0
- package/dist/contracts/redact.js +223 -0
- package/dist/contracts/tools.d.ts +197 -0
- package/dist/contracts/tools.js +33 -0
- package/dist/contracts/types.d.ts +302 -0
- package/dist/contracts/types.js +50 -0
- package/dist/contracts/ui.d.ts +122 -0
- package/dist/contracts/ui.js +15 -0
- package/dist/conversation/agent-service.js +61 -0
- package/dist/conversation/approval-wiring.js +82 -0
- package/dist/conversation/backoff.js +38 -0
- package/dist/conversation/codes.js +47 -0
- package/dist/conversation/control-tools.js +102 -0
- package/dist/conversation/control.js +210 -0
- package/dist/conversation/driver.js +922 -0
- package/dist/conversation/index.js +12 -0
- package/dist/conversation/model-visible.js +169 -0
- package/dist/conversation/open-tools.js +126 -0
- package/dist/conversation/reseed.js +132 -0
- package/dist/conversation/sessions.js +215 -0
- package/dist/conversation/todo.js +203 -0
- package/dist/conversation/types.js +35 -0
- package/dist/conversation/wiring.js +204 -0
- package/dist/credentials/codes.js +59 -0
- package/dist/credentials/commands.js +186 -0
- package/dist/credentials/env-ref.js +34 -0
- package/dist/credentials/index.js +28 -0
- package/dist/credentials/migration.js +18 -0
- package/dist/credentials/oauth.js +266 -0
- package/dist/credentials/refresh.js +152 -0
- package/dist/credentials/secrets.js +118 -0
- package/dist/credentials/types.js +30 -0
- package/dist/exec/bash.js +279 -0
- package/dist/exec/codes.js +37 -0
- package/dist/exec/env.js +99 -0
- package/dist/exec/environment.js +39 -0
- package/dist/exec/git-guard.js +623 -0
- package/dist/exec/index.js +24 -0
- package/dist/exec/registry.js +120 -0
- package/dist/exec/spawn.js +281 -0
- package/dist/exec/tail.js +77 -0
- package/dist/exec/types.js +5 -0
- package/dist/goal/codes.js +33 -0
- package/dist/goal/command.js +175 -0
- package/dist/goal/fold.js +121 -0
- package/dist/goal/gates.js +122 -0
- package/dist/goal/index.js +22 -0
- package/dist/goal/migration.js +48 -0
- package/dist/goal/service.js +501 -0
- package/dist/goal/todo-tool.js +174 -0
- package/dist/goal/types.js +1 -0
- package/dist/goal/update-tool.js +46 -0
- package/dist/host/approval-cmd.js +276 -0
- package/dist/host/assembly.js +1146 -0
- package/dist/host/boot-failures.js +104 -0
- package/dist/host/budget-advisory.js +74 -0
- package/dist/host/budget-broadcast.js +50 -0
- package/dist/host/builtins.js +54 -0
- package/dist/host/cli.js +544 -0
- package/dist/host/codes.js +120 -0
- package/dist/host/config-schema.js +195 -0
- package/dist/host/conversation-stack.js +654 -0
- package/dist/host/core-plugins.js +1685 -0
- package/dist/host/credentials-cmd.js +42 -0
- package/dist/host/disclosure.js +30 -0
- package/dist/host/dispatch.js +105 -0
- package/dist/host/doors-cmd.js +154 -0
- package/dist/host/dump-config.js +44 -0
- package/dist/host/hook-dispatch-guard.js +27 -0
- package/dist/host/import-gate.js +153 -0
- package/dist/host/index.js +54 -0
- package/dist/host/issue-session.js +241 -0
- package/dist/host/loader.js +372 -0
- package/dist/host/main.js +161 -0
- package/dist/host/manifest.js +381 -0
- package/dist/host/mcp-entry.js +53 -0
- package/dist/host/plugin-boot.js +952 -0
- package/dist/host/plugin-context.js +672 -0
- package/dist/host/plugin-install.js +480 -0
- package/dist/host/plugin-reload.js +124 -0
- package/dist/host/plugin-store.js +462 -0
- package/dist/host/plugin-tools.js +359 -0
- package/dist/host/plugin-uninstall.js +257 -0
- package/dist/host/plugins-cmd.js +302 -0
- package/dist/host/plugins-command.js +130 -0
- package/dist/host/plugins-config.js +195 -0
- package/dist/host/prompt-sections.js +133 -0
- package/dist/host/run-entry.js +544 -0
- package/dist/host/runtime.js +209 -0
- package/dist/host/scheduler-tick.js +294 -0
- package/dist/host/serve-daemon.js +501 -0
- package/dist/host/serve-entry.js +279 -0
- package/dist/host/session-anchor.js +41 -0
- package/dist/host/sessions-cmd.js +219 -0
- package/dist/host/sessions-face.js +47 -0
- package/dist/host/settings-store.js +112 -0
- package/dist/host/signals.js +69 -0
- package/dist/host/single-instance.js +105 -0
- package/dist/host/subagent-factory.js +291 -0
- package/dist/host/testkit/harness.js +283 -0
- package/dist/host/testkit/index.js +14 -0
- package/dist/host/testkit/matrix.js +302 -0
- package/dist/host/tool-policy-store.js +177 -0
- package/dist/host/triggers.js +212 -0
- package/dist/host/tui-entry.js +216 -0
- package/dist/host/webui-bridge.js +165 -0
- package/dist/issue/codes.js +38 -0
- package/dist/issue/filter.js +146 -0
- package/dist/issue/github.js +116 -0
- package/dist/issue/index.js +17 -0
- package/dist/issue/mount.js +70 -0
- package/dist/issue/poll.js +58 -0
- package/dist/issue/service.js +341 -0
- package/dist/issue/tools.js +70 -0
- package/dist/issue/types.js +34 -0
- package/dist/issue/webhook.js +126 -0
- package/dist/llm/codes.js +77 -0
- package/dist/llm/complete.js +196 -0
- package/dist/llm/events.js +15 -0
- package/dist/llm/index.js +24 -0
- package/dist/llm/inflight.js +65 -0
- package/dist/llm/model-id.js +58 -0
- package/dist/llm/provider-face.d.ts +32 -0
- package/dist/llm/provider-face.js +34 -0
- package/dist/llm/recovery.js +146 -0
- package/dist/llm/runtime.js +46 -0
- package/dist/llm/stream-fn.js +147 -0
- package/dist/lsp/codes.js +31 -0
- package/dist/lsp/connection.js +147 -0
- package/dist/lsp/frame.js +110 -0
- package/dist/lsp/index.js +16 -0
- package/dist/lsp/inject.js +58 -0
- package/dist/lsp/instance.js +264 -0
- package/dist/lsp/service.js +522 -0
- package/dist/lsp/tools.js +53 -0
- package/dist/lsp/types.js +201 -0
- package/dist/mcp/bridge.js +222 -0
- package/dist/mcp/codes.js +21 -0
- package/dist/mcp/index.js +19 -0
- package/dist/mcp/jsonrpc.js +230 -0
- package/dist/mcp/service.js +125 -0
- package/dist/mcp/tools.js +145 -0
- package/dist/mcp/types.js +108 -0
- package/dist/memory/cite.js +131 -0
- package/dist/memory/codes.js +50 -0
- package/dist/memory/command.js +71 -0
- package/dist/memory/consolidate.js +219 -0
- package/dist/memory/cycle.js +109 -0
- package/dist/memory/dao.js +878 -0
- package/dist/memory/diff.js +238 -0
- package/dist/memory/extract.js +181 -0
- package/dist/memory/fts.js +58 -0
- package/dist/memory/index.js +42 -0
- package/dist/memory/inject.js +354 -0
- package/dist/memory/merge.js +178 -0
- package/dist/memory/migration.js +132 -0
- package/dist/memory/pollution.js +59 -0
- package/dist/memory/port.js +385 -0
- package/dist/memory/review.js +201 -0
- package/dist/memory/scan.js +89 -0
- package/dist/memory/tools.js +508 -0
- package/dist/memory/types.js +140 -0
- package/dist/obs/codes.js +38 -0
- package/dist/obs/db.js +115 -0
- package/dist/obs/index.js +20 -0
- package/dist/obs/rollup.js +61 -0
- package/dist/obs/service.js +363 -0
- package/dist/obs/session-tools.js +282 -0
- package/dist/obs/session-view.js +225 -0
- package/dist/obs/tool.js +97 -0
- package/dist/obs/types.js +1 -0
- package/dist/persist/audit.js +63 -0
- package/dist/persist/aux.js +39 -0
- package/dist/persist/codes.js +35 -0
- package/dist/persist/index.js +30 -0
- package/dist/persist/load-history.js +50 -0
- package/dist/persist/migrations.js +37 -0
- package/dist/persist/paths.js +108 -0
- package/dist/persist/persistence.js +229 -0
- package/dist/persist/schema.js +99 -0
- package/dist/persist/secret-box.js +95 -0
- package/dist/persist/store.js +706 -0
- package/dist/persist/write-behind.js +238 -0
- package/dist/safety/approval.js +171 -0
- package/dist/safety/bwrap.js +123 -0
- package/dist/safety/codes.js +57 -0
- package/dist/safety/danger.js +505 -0
- package/dist/safety/gate.js +226 -0
- package/dist/safety/index.js +24 -0
- package/dist/safety/presets.js +73 -0
- package/dist/safety/roots.js +139 -0
- package/dist/safety/sandbox.js +214 -0
- package/dist/safety/seatbelt.js +88 -0
- package/dist/safety/sensitive.js +34 -0
- package/dist/safety/tool-policy.js +203 -0
- package/dist/safety/types.js +13 -0
- package/dist/scheduler/codes.js +54 -0
- package/dist/scheduler/cron-backend.js +135 -0
- package/dist/scheduler/engine.js +280 -0
- package/dist/scheduler/gates.js +60 -0
- package/dist/scheduler/index.js +25 -0
- package/dist/scheduler/migration.js +22 -0
- package/dist/scheduler/runner.js +171 -0
- package/dist/scheduler/schedule.js +193 -0
- package/dist/scheduler/service.js +283 -0
- package/dist/scheduler/tick.js +139 -0
- package/dist/scheduler/types.js +1 -0
- package/dist/sdk/http.js +865 -0
- package/dist/sdk/index.js +22 -0
- package/dist/sdk/mcp.js +289 -0
- package/dist/sdk/plugin-route-registry.js +126 -0
- package/dist/sdk/plugin-routes.js +149 -0
- package/dist/sdk/security.js +116 -0
- package/dist/sdk/types.js +32 -0
- package/dist/session/budget.js +159 -0
- package/dist/session/codes.js +40 -0
- package/dist/session/derive.js +180 -0
- package/dist/session/event-data.js +1 -0
- package/dist/session/fork.js +72 -0
- package/dist/session/import-gates.js +148 -0
- package/dist/session/index.js +18 -0
- package/dist/session/recover.js +103 -0
- package/dist/session/session.js +279 -0
- package/dist/session/snapshot.js +107 -0
- package/dist/skills/agents.js +242 -0
- package/dist/skills/codes.js +51 -0
- package/dist/skills/discovery.js +266 -0
- package/dist/skills/frontmatter.js +215 -0
- package/dist/skills/index.js +28 -0
- package/dist/skills/load.js +118 -0
- package/dist/skills/manage.js +201 -0
- package/dist/skills/registry.js +138 -0
- package/dist/skills/render.js +124 -0
- package/dist/skills/sections.js +171 -0
- package/dist/skills/types.js +21 -0
- package/dist/subagent/codes.js +50 -0
- package/dist/subagent/declarative.js +55 -0
- package/dist/subagent/index.js +19 -0
- package/dist/subagent/notify.js +51 -0
- package/dist/subagent/provide.js +7 -0
- package/dist/subagent/registry.js +149 -0
- package/dist/subagent/service.js +338 -0
- package/dist/subagent/surface.js +44 -0
- package/dist/subagent/tool.js +153 -0
- package/dist/subagent/types.js +25 -0
- package/dist/tools/apply-patch.js +164 -0
- package/dist/tools/codes.js +109 -0
- package/dist/tools/fs.js +501 -0
- package/dist/tools/index.js +17 -0
- package/dist/tools/observed.js +99 -0
- package/dist/tools/pipeline.js +176 -0
- package/dist/tools/protected-read.js +54 -0
- package/dist/tools/registry.js +250 -0
- package/dist/tools/search.js +451 -0
- package/dist/tools/worktree.js +327 -0
- package/dist/web/codes.js +37 -0
- package/dist/web/gate.js +43 -0
- package/dist/web/hygiene.js +195 -0
- package/dist/web/index.js +16 -0
- package/dist/web/service.js +207 -0
- package/dist/web/ssrf-guard.js +44 -0
- package/dist/web/tool.js +76 -0
- package/dist/web/types.js +10 -0
- package/dist/webui/assets/index-B-t2O8gh.js +22 -0
- package/dist/webui/assets/index-DOlgSZ9Q.css +2 -0
- package/dist/webui/index.html +14 -0
- package/dist/webui/index.js +14 -0
- package/dist/webui/server.js +549 -0
- package/dist/webui/types.js +38 -0
- package/examples/README.md +26 -0
- package/examples/minimal-code-plugin/entry.js +43 -0
- package/examples/minimal-code-plugin/package.json +12 -0
- package/examples/pure-skill-pack/package.json +14 -0
- package/examples/pure-skill-pack/skills/markdown-table/SKILL.md +32 -0
- package/package.json +86 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory 简报差分件(06 §6 差分纪律——批 18c-7)。
|
|
3
|
+
*
|
|
4
|
+
* 三件:①基线冻结不动(差分永不触发 systemPrompt 重建——重建时点唯
|
|
5
|
+
* 装配面 materialize);②权威变化落 durable 事件 `memory/diff`(surface
|
|
6
|
+
* 类别——与 todo/write 同族;全量差分 last-wins + 落账时权威面指纹);
|
|
7
|
+
* ③请求尾差分注入 = 派生视图(镜像纯函数于日志——无日志即无视图)。
|
|
8
|
+
*
|
|
9
|
+
* 不变式:`mirror == derive(日志, 基线指纹)`(last-wins 取最后一条指纹
|
|
10
|
+
* 匹配事件)。纪元首请求懒派生(mirror 置 null 未初始化);派生非空而
|
|
11
|
+
* 当面零漂移的不一致即落清账事件 entries=[]——重启撞指纹自愈(上进程
|
|
12
|
+
* 面漂移后回摆、净变化恰归零且未及下一请求即退出,新进程基线指纹与
|
|
13
|
+
* 残留事件相同)。收敛清账:净变化为零 = 空差分,mirror 非空时落
|
|
14
|
+
* entries=[] 清账事件(视图归零)。
|
|
15
|
+
*
|
|
16
|
+
* **词面独立律**:appendEvent / fetchEvents 为装配面注入 seam(结构兼容
|
|
17
|
+
* 宿主会话面子集——memory 席 DAG 无 host 边);appendEvent 缺席 = 降级
|
|
18
|
+
* 只渲染不落账(mirror 不锁步)。`memory/diff` 词汇 meta 随件导出,经
|
|
19
|
+
* `ctx.events.registerSessionEventType` 装配面作用域化注册(件内不静态
|
|
20
|
+
* 注册——注册器挂 effect 栈的回卷语义归装配面)。
|
|
21
|
+
*/
|
|
22
|
+
import { createHash } from 'node:crypto';
|
|
23
|
+
import { getMessageRoleDefinition, registerMessageRole, } from '../contracts/index.js';
|
|
24
|
+
import { shortIdOf } from './inject.js';
|
|
25
|
+
import { MEMORY_DIFF_EPOCHS_LRU } from './types.js';
|
|
26
|
+
/* ---------------- 词汇注册面(装配面消费) ---------------- */
|
|
27
|
+
/** 差分事件类型词(06 §6 唯一 durable 出口——surface 类别) */
|
|
28
|
+
export const MEMORY_DIFF_EVENT_TYPE = 'memory/diff';
|
|
29
|
+
/** 差分事件词汇 meta(经 ctx.events.registerSessionEventType 装配面注册) */
|
|
30
|
+
export const MEMORY_DIFF_EVENT_META = {
|
|
31
|
+
type: MEMORY_DIFF_EVENT_TYPE,
|
|
32
|
+
category: 'surface',
|
|
33
|
+
owner: 'memory',
|
|
34
|
+
tier: 'stable',
|
|
35
|
+
description: '记忆简报权威面自基线的变化(全量差分 last-wins + 基线指纹)',
|
|
36
|
+
ignorable: true,
|
|
37
|
+
};
|
|
38
|
+
/* ---------------- 面与指纹(纯函数) ---------------- */
|
|
39
|
+
/**
|
|
40
|
+
* 简报基线拍平为权威面三元组(frozen + competitive + 晋升候选三流——
|
|
41
|
+
* §9.1「候选行进简报权威面」的物理承载;quoted 呈现层注记不进面;
|
|
42
|
+
* updatedAt/expiresAt 时效数据字段同 quoted 律不进面——06 §6 p-1 指纹
|
|
43
|
+
* 排除律:时间流逝不换纪元、差分不 churn)。
|
|
44
|
+
*/
|
|
45
|
+
export function faceOf(baseline) {
|
|
46
|
+
return [...baseline.frozen, ...baseline.competitive, ...baseline.candidates].map((e) => ({
|
|
47
|
+
id: e.id,
|
|
48
|
+
kind: e.kind,
|
|
49
|
+
summary: e.summary,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 面指纹:sha256 规范序列化前 16 hex,**按 id 排序——次序不敏感**(流的
|
|
54
|
+
* 组内排序变化〔效用分波动〕不是权威面变化)。
|
|
55
|
+
*/
|
|
56
|
+
export function fingerprintOf(face) {
|
|
57
|
+
const canonical = [...face]
|
|
58
|
+
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
|
|
59
|
+
.map((e) => JSON.stringify([e.id, e.kind, e.summary]))
|
|
60
|
+
.join(',');
|
|
61
|
+
return createHash('sha256').update(canonical).digest('hex').slice(0, 16);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 全量差分(baseline → current 三态映射;按 id 字典序确定性输出):
|
|
65
|
+
* '+' 新入 / '-' 退场 / '~' kind 或 summary 变更(quoted 不进面——呈现层
|
|
66
|
+
* 注记变化不触发差分)。条目 id 为**短 id**(注入派生只呈现短面;被引用
|
|
67
|
+
* 经 cite 前缀归责计数——无第二回写路径)。
|
|
68
|
+
*/
|
|
69
|
+
export function diffFace(baseline, current) {
|
|
70
|
+
const baseMap = new Map(baseline.map((e) => [e.id, e]));
|
|
71
|
+
const curMap = new Map(current.map((e) => [e.id, e]));
|
|
72
|
+
const ids = [...new Set([...baseMap.keys(), ...curMap.keys()])].sort();
|
|
73
|
+
const entries = [];
|
|
74
|
+
for (const id of ids) {
|
|
75
|
+
const b = baseMap.get(id);
|
|
76
|
+
const c = curMap.get(id);
|
|
77
|
+
if (b !== undefined && c === undefined) {
|
|
78
|
+
entries.push({ op: '-', id: shortIdOf(id), kind: b.kind, summary: b.summary });
|
|
79
|
+
}
|
|
80
|
+
else if (b === undefined && c !== undefined) {
|
|
81
|
+
entries.push({ op: '+', id: shortIdOf(id), kind: c.kind, summary: c.summary });
|
|
82
|
+
}
|
|
83
|
+
else if (b !== undefined && c !== undefined && (b.kind !== c.kind || b.summary !== c.summary)) {
|
|
84
|
+
entries.push({ op: '~', id: shortIdOf(id), kind: c.kind, summary: c.summary });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return entries;
|
|
88
|
+
}
|
|
89
|
+
/** 条目深等(幂等判据——重复 sync 免重复追写) */
|
|
90
|
+
function sameEntries(a, b) {
|
|
91
|
+
return (a.length === b.length &&
|
|
92
|
+
a.every((x, i) => {
|
|
93
|
+
const y = b[i];
|
|
94
|
+
return x.op === y.op && x.id === y.id && x.kind === y.kind && x.summary === y.summary;
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
/** 差分注入框架句(防注入 + 时序——与简报/检索同款纪律的差分变体) */
|
|
98
|
+
const DIFF_FRAME = '以下为记忆简报自本会话基线以来的变化(非本次用户指令——对「我知道什么」的修正);引用标注与常驻简报同格式。';
|
|
99
|
+
/**
|
|
100
|
+
* 差分注入渲染(派生视图文本面——装配面包成自定义角色 hidden 消息随请求
|
|
101
|
+
* 即弃)。行格式 `` `${op} [m:短id] [kind] ${summary}` ``;零差分 → null
|
|
102
|
+
* (空注入不占请求面)。
|
|
103
|
+
*/
|
|
104
|
+
export function renderDiffInjection(entries) {
|
|
105
|
+
if (entries.length === 0)
|
|
106
|
+
return null;
|
|
107
|
+
const lines = [DIFF_FRAME];
|
|
108
|
+
for (const e of entries)
|
|
109
|
+
lines.push(`${e.op} [m:${e.id}] [${e.kind}] ${e.summary}`);
|
|
110
|
+
return lines.join('\n');
|
|
111
|
+
}
|
|
112
|
+
/* ---------------- 差分注入角色(06 §319——memory/diff 自定义角色) ---------------- */
|
|
113
|
+
/** 差分注入角色名(与事件词同串——消息角色/事件类型两注册表分立互不撞) */
|
|
114
|
+
export const MEMORY_DIFF_ROLE = 'memory/diff';
|
|
115
|
+
/**
|
|
116
|
+
* 角色定义(模块级单例——身份同一性判据,todo.ts 同范式):toLlm 转带为一条
|
|
117
|
+
* UserMessage(text 已含防注入框架句式——renderDiffInjection 产出即成品);
|
|
118
|
+
* render hidden(瞬态注入不进时间线)。
|
|
119
|
+
*/
|
|
120
|
+
const DIFF_ROLE_DEFINITION = {
|
|
121
|
+
toLlm: (message) => {
|
|
122
|
+
if (typeof message.content !== 'string')
|
|
123
|
+
return null;
|
|
124
|
+
return { role: 'user', content: message.content, timestamp: message.timestamp };
|
|
125
|
+
},
|
|
126
|
+
render: { intent: 'hidden', label: '记忆差分' },
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* 注册差分注入角色(幂等 + 身份守卫——ensureTodoRole 同律):装配面多次装配
|
|
130
|
+
* 常态;在册定义另有其身 → 域名窃据 fail-loud。
|
|
131
|
+
*/
|
|
132
|
+
export function ensureDiffRole() {
|
|
133
|
+
const existing = getMessageRoleDefinition(MEMORY_DIFF_ROLE);
|
|
134
|
+
if (existing !== undefined) {
|
|
135
|
+
if (existing !== DIFF_ROLE_DEFINITION) {
|
|
136
|
+
throw new Error(`消息角色 ${MEMORY_DIFF_ROLE} 已被其他定义占用(memory 域名窃据——差分注入拒绝分叉转写)`);
|
|
137
|
+
}
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
registerMessageRole(MEMORY_DIFF_ROLE, DIFF_ROLE_DEFINITION);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 构建差分注入消息(LLM 形——context_transform 载荷消息批已是 LLM 形):
|
|
144
|
+
* 经角色 toLlm 转写(ensureDiffRole 自足)。timestamp 取请求时点。
|
|
145
|
+
*/
|
|
146
|
+
export function diffInjectionMessage(text, timestamp) {
|
|
147
|
+
ensureDiffRole();
|
|
148
|
+
const converted = DIFF_ROLE_DEFINITION.toLlm?.({ role: MEMORY_DIFF_ROLE, content: text, timestamp });
|
|
149
|
+
// 定义体在本模块单源——string content 必产单条 user;运行时窄化防御仅挡未来改动
|
|
150
|
+
if (converted === undefined || converted === null || Array.isArray(converted) || converted.role !== 'user') {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return converted;
|
|
154
|
+
}
|
|
155
|
+
/** 建差分 tracker(epochs per-session Map——LRU 帽 256) */
|
|
156
|
+
export function createDiffTracker(deps) {
|
|
157
|
+
const warn = deps.warn ?? (() => { });
|
|
158
|
+
const epochs = new Map();
|
|
159
|
+
/** LRU 触达(delete + set 复位插入序;超帽逐最旧) */
|
|
160
|
+
function touch(sessionId, epoch) {
|
|
161
|
+
epochs.delete(sessionId);
|
|
162
|
+
epochs.set(sessionId, epoch);
|
|
163
|
+
if (epochs.size > MEMORY_DIFF_EPOCHS_LRU) {
|
|
164
|
+
const oldest = epochs.keys().next().value;
|
|
165
|
+
if (oldest !== undefined)
|
|
166
|
+
epochs.delete(oldest);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/** 懒派生:last-wins 取日志最后一条指纹匹配事件(不变式右半的实现体) */
|
|
170
|
+
function deriveFromLog(sessionId, fingerprint) {
|
|
171
|
+
if (!deps.fetchEvents)
|
|
172
|
+
return [];
|
|
173
|
+
try {
|
|
174
|
+
const events = deps.fetchEvents(sessionId);
|
|
175
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
176
|
+
const e = events[i];
|
|
177
|
+
if (e.type !== MEMORY_DIFF_EVENT_TYPE)
|
|
178
|
+
continue;
|
|
179
|
+
const d = e.data;
|
|
180
|
+
if (typeof d === 'object' && d !== null && d.fingerprint === fingerprint && Array.isArray(d.entries)) {
|
|
181
|
+
return d.entries;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
warn(`[memory] 差分懒派生尽力而为止步:${err instanceof Error ? err.message : String(err)}`);
|
|
187
|
+
}
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
/** 落账 + 锁步(appendEvent 缺席/失败 = 降级:不落账不锁步——派生视图纯函数于日志) */
|
|
191
|
+
function commit(data) {
|
|
192
|
+
if (!deps.appendEvent)
|
|
193
|
+
return false;
|
|
194
|
+
try {
|
|
195
|
+
deps.appendEvent(MEMORY_DIFF_EVENT_TYPE, data);
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
warn(`[memory] 差分落账尽力而为止步:${err instanceof Error ? err.message : String(err)}`);
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
materialize(sessionId) {
|
|
205
|
+
if (sessionId === null)
|
|
206
|
+
return; // 诊断物化——只渲染不立纪元
|
|
207
|
+
const base = deps.face();
|
|
208
|
+
touch(sessionId, { base, fingerprint: fingerprintOf(base), mirror: null });
|
|
209
|
+
},
|
|
210
|
+
sync(sessionId) {
|
|
211
|
+
let epoch = epochs.get(sessionId);
|
|
212
|
+
if (epoch === undefined) {
|
|
213
|
+
// 未立纪元(诊断物化后首请求 / 纪元被逐):以当面懒立——重立基线重派生,语义零变
|
|
214
|
+
const base = deps.face();
|
|
215
|
+
epoch = { base, fingerprint: fingerprintOf(base), mirror: null };
|
|
216
|
+
touch(sessionId, epoch);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
touch(sessionId, epoch); // LRU 触达
|
|
220
|
+
}
|
|
221
|
+
// 懒派生(纪元首请求——重启撞指纹自愈的发现位)
|
|
222
|
+
if (epoch.mirror === null)
|
|
223
|
+
epoch.mirror = deriveFromLog(sessionId, epoch.fingerprint);
|
|
224
|
+
const current = deps.face();
|
|
225
|
+
const diff = diffFace(epoch.base, current);
|
|
226
|
+
if (sameEntries(diff, epoch.mirror))
|
|
227
|
+
return epoch.mirror; // 幂等(重复 sync / 已追写态)
|
|
228
|
+
// 载荷指纹 = 落账时权威面(当前面)——重放 last-wins 与新基线指纹比对的重启自愈判据
|
|
229
|
+
const data = { entries: diff, fingerprint: fingerprintOf(current) };
|
|
230
|
+
if (commit(data))
|
|
231
|
+
epoch.mirror = diff; // 锁步只在落账成功后
|
|
232
|
+
return epoch.mirror;
|
|
233
|
+
},
|
|
234
|
+
renderInjection(entries) {
|
|
235
|
+
return renderDiffInjection(entries);
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory 提取即时路(06 §4——确定性代码零 LLM,fire-and-forget)。
|
|
3
|
+
*
|
|
4
|
+
* **纠正检测**:真用户消息命中纠正触发词表(中英双语保守清单常量,起草值
|
|
5
|
+
* 随实测调)→ 立即提取 correction 候选(置信度 0.7 = 强证据——Mercury/Hermes
|
|
6
|
+
* 纠正即时存先例)。候选经 ingest 单点入库(§5 合并管线 + §8 写前扫描
|
|
7
|
+
* 内置——没有绕过合并的写路径)。
|
|
8
|
+
*
|
|
9
|
+
* **机器源滤除**(06 §4 即时路细则):只对真用户消息入检——source 归因
|
|
10
|
+
* 仅三形参与:缺省(读侧视为 'user')/ 'user' / 'channel:*';压缩摘要载体
|
|
11
|
+
* (compaction)、插件注入(plugin:*)、调度(schedule)、子代理结算
|
|
12
|
+
* (subagent-*)等机器载体一律跳过——机器文本命中纠正触发词会被提取成
|
|
13
|
+
* 「用户亲口纠正」污染记忆库语义。
|
|
14
|
+
*
|
|
15
|
+
* **owner 恒 global**(06 §4 细则:纠正的是模型行为,跨项目成立——不走
|
|
16
|
+
* project 域)。**溯源精确事件位**:sourceRefs = {sessionId, seq}(信封
|
|
17
|
+
* seq——18c-2 工具面 seq:0 会话级位的精确位兑现)。
|
|
18
|
+
*
|
|
19
|
+
* **polluted 资格检查**(§4.1「两路入口同一资格检查」——批 18c-5 兑现):
|
|
20
|
+
* 本件首步(源滤除之前)经 isSessionPolluted seam 检查——polluted 会话跳过
|
|
21
|
+
* 提取(外部源内容不做记忆源);seam 缺席恒 eligible(无污染追踪装配的
|
|
22
|
+
* 装配面——装配根把周期路编排件的 pollution 追踪器接到此位)。
|
|
23
|
+
*
|
|
24
|
+
* **装配位**:本件为纯消费件——host 装配批(批 12 装载面后装配批)把
|
|
25
|
+
* onUserMessage 挂到 durable 事件流消费点;件自身不订阅。
|
|
26
|
+
*
|
|
27
|
+
* **词面独立律**:入检消息结构兼容 session UserMessageData(content
|
|
28
|
+
* string|块数组 + source 可选)——本件不 import session(memory→session
|
|
29
|
+
* 边的 18c-6 跨会话检索消费位仍占位)。
|
|
30
|
+
*/
|
|
31
|
+
import { parseEventSource } from '../contracts/index.js';
|
|
32
|
+
import { recordCorrectedCites } from './cite.js';
|
|
33
|
+
import { MEMORY_CONTENT_MAX_CHARS, MEMORY_SUMMARY_MAX_CHARS } from './types.js';
|
|
34
|
+
/**
|
|
35
|
+
* 纠正触发词表(06 §4 中英双语保守清单——起草值随实测调)。
|
|
36
|
+
* 中文:直接子串匹配;英文:小写归一后子串匹配(含撇形两拼)。
|
|
37
|
+
*/
|
|
38
|
+
const CORRECTION_TRIGGERS_ZH = [
|
|
39
|
+
'不对',
|
|
40
|
+
'不是的',
|
|
41
|
+
'说错了',
|
|
42
|
+
'我说错了',
|
|
43
|
+
'我说的是',
|
|
44
|
+
'搞错了',
|
|
45
|
+
'弄错了',
|
|
46
|
+
'别再',
|
|
47
|
+
'不要再',
|
|
48
|
+
'纠正一下',
|
|
49
|
+
'应该是',
|
|
50
|
+
];
|
|
51
|
+
const CORRECTION_TRIGGERS_EN = [
|
|
52
|
+
"that's wrong",
|
|
53
|
+
'thats wrong',
|
|
54
|
+
"that's not right",
|
|
55
|
+
"that's incorrect",
|
|
56
|
+
"you're wrong",
|
|
57
|
+
'youre wrong',
|
|
58
|
+
'no, i said',
|
|
59
|
+
'i meant',
|
|
60
|
+
'i said,',
|
|
61
|
+
'stop doing',
|
|
62
|
+
"don't do that",
|
|
63
|
+
'dont do that',
|
|
64
|
+
'scratch that',
|
|
65
|
+
];
|
|
66
|
+
/** 纠正候选置信度(06 §4——强证据定值) */
|
|
67
|
+
const CORRECTION_CONFIDENCE = 0.7;
|
|
68
|
+
/** 摘要前缀(落码定形:统一前缀 + 全文截断——同文本恒同摘要,重放经 exact 合并幂等吸收) */
|
|
69
|
+
const CORRECTION_SUMMARY_PREFIX = '用户纠正:';
|
|
70
|
+
/** 摘要正文截长(起草值——总长仍在 MEMORY_SUMMARY_MAX_CHARS 帽内) */
|
|
71
|
+
const CORRECTION_SUMMARY_TEXT_MAX = 100;
|
|
72
|
+
/**
|
|
73
|
+
* 机器源滤除(06 §4 三形白名单):缺省 / 'user' / 'channel:*' 入检;
|
|
74
|
+
* schedule / subagent-* / compaction / plugin:* 跳过。未知字面量按
|
|
75
|
+
* contracts.parseEventSource 归 user 同视(05 §3.1 读侧向前兼容)——
|
|
76
|
+
* 与「缺省(读侧视为 'user')」同形。
|
|
77
|
+
*/
|
|
78
|
+
export function isEligibleUserSource(source) {
|
|
79
|
+
if (source === undefined)
|
|
80
|
+
return true;
|
|
81
|
+
const kind = parseEventSource(source).kind;
|
|
82
|
+
return kind === 'user' || kind === 'channel';
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 消息纯文本面提取:string 直取;块数组拼 text 块(其余块形无关);
|
|
86
|
+
* 无文本(纯图像等)→ null 不入检。
|
|
87
|
+
*/
|
|
88
|
+
export function userTextOf(content) {
|
|
89
|
+
if (typeof content === 'string')
|
|
90
|
+
return content === '' ? null : content;
|
|
91
|
+
const parts = [];
|
|
92
|
+
for (const block of content) {
|
|
93
|
+
if (block.type === 'text' && typeof block.text === 'string')
|
|
94
|
+
parts.push(block.text);
|
|
95
|
+
}
|
|
96
|
+
if (parts.length === 0)
|
|
97
|
+
return null;
|
|
98
|
+
const joined = parts.join('\n');
|
|
99
|
+
return joined === '' ? null : joined;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 纠正触发词检测:中文表子串直配;英文表小写归一子串配。
|
|
103
|
+
* 多命中取首(表序即优先序);未命中 → null。
|
|
104
|
+
*/
|
|
105
|
+
export function detectCorrectionHit(text) {
|
|
106
|
+
for (const trigger of CORRECTION_TRIGGERS_ZH) {
|
|
107
|
+
if (text.includes(trigger))
|
|
108
|
+
return { trigger, text };
|
|
109
|
+
}
|
|
110
|
+
const lower = text.toLowerCase();
|
|
111
|
+
for (const trigger of CORRECTION_TRIGGERS_EN) {
|
|
112
|
+
if (lower.includes(trigger))
|
|
113
|
+
return { trigger, text };
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
/** 摘要形(落码定形:前缀 + 全文截 100 + 省略尾——同文本恒同串,exact 合并幂等键) */
|
|
118
|
+
function correctionSummary(text) {
|
|
119
|
+
const body = text.length > CORRECTION_SUMMARY_TEXT_MAX ? `${text.slice(0, CORRECTION_SUMMARY_TEXT_MAX)}…` : text;
|
|
120
|
+
const summary = `${CORRECTION_SUMMARY_PREFIX}${body}`;
|
|
121
|
+
// 双保险截帽(前缀 + 截长恒在帽内;显式截防起草值未来调大越帽)
|
|
122
|
+
return summary.length > MEMORY_SUMMARY_MAX_CHARS ? summary.slice(0, MEMORY_SUMMARY_MAX_CHARS) : summary;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 纠正候选组装(06 §4 细则全档:kind correction / 置信度 0.7 / owner 恒
|
|
126
|
+
* global / 溯源精确事件位)。content 截至帽内(提取尽力而为——超长纠正
|
|
127
|
+
* 截尾保知识不整条拒写;截断点前文本仍完整过写前扫描)。
|
|
128
|
+
*/
|
|
129
|
+
export function buildCorrectionCandidate(hit, sessionId, seq) {
|
|
130
|
+
return {
|
|
131
|
+
ownerKey: 'global',
|
|
132
|
+
kind: 'correction',
|
|
133
|
+
summary: correctionSummary(hit.text),
|
|
134
|
+
content: hit.text.length > MEMORY_CONTENT_MAX_CHARS ? hit.text.slice(0, MEMORY_CONTENT_MAX_CHARS) : hit.text,
|
|
135
|
+
confidence: CORRECTION_CONFIDENCE,
|
|
136
|
+
sourceRefs: [{ sessionId, seq }],
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* 即时路编排件工厂:资格首步 → 源滤除 → 文本提取 → 触发词检测 →(命中即记
|
|
141
|
+
* 负效用回看 +)候选组装 → ingest 单点。第二动作(负效用回写)与候选 ingest
|
|
142
|
+
* **失败路径分立**:回写件自持 try/catch(cite.ts recordCorrectedCites 尽力而
|
|
143
|
+
* 为),候选走 §5 合并被拒(secret 扫描等)不连带负效用落账。
|
|
144
|
+
*/
|
|
145
|
+
export function createImmediateExtractor(deps) {
|
|
146
|
+
const warn = deps.warn ?? (() => { });
|
|
147
|
+
return {
|
|
148
|
+
onUserMessage(sessionId, seq, data) {
|
|
149
|
+
try {
|
|
150
|
+
// 资格检查首步(§4.1——源滤除之前;polluted 会话两动作同跳:提取与
|
|
151
|
+
// 负效用回写均为派生面,污染可注入——派生面从严)
|
|
152
|
+
if (deps.isSessionPolluted !== undefined && deps.isSessionPolluted(sessionId)) {
|
|
153
|
+
return { extracted: false };
|
|
154
|
+
}
|
|
155
|
+
if (!isEligibleUserSource(data.source))
|
|
156
|
+
return { extracted: false };
|
|
157
|
+
const text = userTextOf(data.content);
|
|
158
|
+
if (text === null)
|
|
159
|
+
return { extracted: false };
|
|
160
|
+
const hit = detectCorrectionHit(text);
|
|
161
|
+
if (hit === null)
|
|
162
|
+
return { extracted: false };
|
|
163
|
+
// —— 第二动作:纠正负效用回看(§4——触发位 = 纠正**命中**即记;回看
|
|
164
|
+
// 紧邻前一条 assistant 文本全复用 §6 解析面;件内自持 try/catch,
|
|
165
|
+
// 候选 ingest 被拒不连带)——
|
|
166
|
+
const previousAssistantText = deps.lastAssistantText?.(sessionId) ?? null;
|
|
167
|
+
if (previousAssistantText !== null && previousAssistantText !== '') {
|
|
168
|
+
recordCorrectedCites(deps.dao, sessionId, previousAssistantText, warn);
|
|
169
|
+
}
|
|
170
|
+
deps.dao.ingest(buildCorrectionCandidate(hit, sessionId, seq));
|
|
171
|
+
return { extracted: true };
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
// 尽力而为(06 §4——提取失败不重试不反噬;写前扫描拒写〔secret 命中〕
|
|
175
|
+
// 等被拒候选在此吞——进程日志是唯一观测面;负效用已在前位独立落账)
|
|
176
|
+
warn(`memory 即时路提取失败(尽力而为跳过):${error instanceof Error ? error.message : String(error)}`);
|
|
177
|
+
return { extracted: false };
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session_fts 消费件(批 18c-6——06 §10 + 05 §9 追记):激活期对账策略位
|
|
3
|
+
* (ensureFtsIndex)+ snippet 切窗纯函数(snippetOf)。
|
|
4
|
+
*
|
|
5
|
+
* **维护归属映射**(05 §9 追记②——结构对账住 persist / 策略位与消费位住
|
|
6
|
+
* core:memory):写入档同批同事务与删除档已是 persist 写路径的结构性组成
|
|
7
|
+
* (「单事件原子」免费成立),本件只持**策略位**——激活期触发抽样审计、
|
|
8
|
+
* 发现缺口即全量重建(派生物不修不补,重建即修复);装配面(host 装配根)
|
|
9
|
+
* 在 memory 装载序激活时调用一次。
|
|
10
|
+
*
|
|
11
|
+
* **词面独立律**:FtsMaintenanceFace / SessionFtsSearchFace 均为结构兼容
|
|
12
|
+
* persist Store 公开面的窄 seam——host 装配批直传 Store 真身,compat 互证
|
|
13
|
+
* 见 fts.test(真 Store 全环)。
|
|
14
|
+
*/
|
|
15
|
+
import { MEMORY_SNIPPET_AFTER, MEMORY_SNIPPET_BEFORE, } from './types.js';
|
|
16
|
+
/* ---------------- snippet 切窗(纯函数) ---------------- */
|
|
17
|
+
/**
|
|
18
|
+
* 命中 body 切 snippet(06 §10 定形注②):命中位前 {@link MEMORY_SNIPPET_BEFORE}
|
|
19
|
+
* 后 {@link MEMORY_SNIPPET_AFTER} 字符、截断端补省略号;命中词大小写不敏感
|
|
20
|
+
* 定位(trigram 分词器大小写不折叠对齐——lowercase 双侧比对);命中词缺席
|
|
21
|
+
* (理论不至——trigram 子串语义下查询必为 body 子串;防御位)退化为 body
|
|
22
|
+
* 头窗。查询词先消毒(剥引号——与检索侧字符串字面量包裹同族的用户输入面)。
|
|
23
|
+
*/
|
|
24
|
+
export function snippetOf(body, query) {
|
|
25
|
+
const sanitized = query.replaceAll('"', ' ').trim();
|
|
26
|
+
const lowerBody = body.toLowerCase();
|
|
27
|
+
const idx = sanitized === '' ? -1 : lowerBody.indexOf(sanitized.toLowerCase());
|
|
28
|
+
if (idx < 0) {
|
|
29
|
+
// 防御位:无命中词可定位——头窗呈现(前 BEFORE+AFTER 字符)
|
|
30
|
+
const head = body.slice(0, MEMORY_SNIPPET_BEFORE + MEMORY_SNIPPET_AFTER);
|
|
31
|
+
return head.length < body.length ? `${head}…` : head;
|
|
32
|
+
}
|
|
33
|
+
const start = Math.max(0, idx - MEMORY_SNIPPET_BEFORE);
|
|
34
|
+
const end = Math.min(body.length, idx + sanitized.length + MEMORY_SNIPPET_AFTER);
|
|
35
|
+
const prefix = start > 0 ? '…' : '';
|
|
36
|
+
const suffix = end < body.length ? '…' : '';
|
|
37
|
+
return `${prefix}${body.slice(start, end)}${suffix}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 激活期对账(memory 装载序调用一次):抽样审计 → 有缺口即全量重建
|
|
41
|
+
* (05 §9 对账三档第三档消费位——派生物不修不补,重建即修复)。
|
|
42
|
+
* 永不抛——对账失败不阻断装载(warn 吞,索引退化可检索面降级不致命)。
|
|
43
|
+
*/
|
|
44
|
+
export function ensureFtsIndex(deps) {
|
|
45
|
+
const warn = deps.warn ?? (() => { });
|
|
46
|
+
try {
|
|
47
|
+
const audit = deps.face.auditFts(deps.sampleCount);
|
|
48
|
+
if (audit.mismatches.length === 0)
|
|
49
|
+
return { audit };
|
|
50
|
+
warn(`session_fts 抽样对账发现缺口(${audit.mismatches.length}/${audit.checked} 会话)——全量重建:` +
|
|
51
|
+
audit.mismatches.map((m) => `${m.sessionId} 期望 ${m.expected} 实有 ${m.actual}`).join(';'));
|
|
52
|
+
return { audit, rebuilt: deps.face.rebuildFts() };
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
warn(`session_fts 激活期对账失败(尽力而为跳过):${error instanceof Error ? error.message : String(error)}`);
|
|
56
|
+
return { audit: { checked: 0, mismatches: [] } };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory 模块公开面(core:memory——06 篇 §1-§10 使用进化机制落码件;批 18c)。
|
|
3
|
+
*
|
|
4
|
+
* 单向 DAG(02 §4.1 memory 席 deps = contracts + context + session + persist)。
|
|
5
|
+
* 批 18c-1 域 = 表族三迁移槽 + 入库单点 DAO(secret 扫描 + 版本链拍照)+
|
|
6
|
+
* 合并三分支纯函数 + 效用综合分;18c-2 域 = 持有面动词 + 检索/访问面 +
|
|
7
|
+
* 工具面九件(createMemoryTools);18c-3 域 = 提取即时路(纠正检测纯函数 +
|
|
8
|
+
* fire-and-forget 编排件——机器源滤除 + owner 恒 global + 精确事件位溯源);
|
|
9
|
+
* 18c-4 域 = 注入两路(常驻简报 memory/core builder + 按需检索 recall 瞬态
|
|
10
|
+
* 注入——读出消毒统一罩工具读面与注入面、流水 op='recall' 分账);
|
|
11
|
+
* 18c-5 域 = 周期路(review 编排 + 审阅窗转录 + JSON 三试)+ consolidation
|
|
12
|
+
* 整理拍(absorb/decay/sweepExpired 物理承载 + 护栏四件)+ polluted 会话
|
|
13
|
+
* 资格(判据通配 + 状态机 + 两路入口挂检);18c-6 域 = 跨会话检索
|
|
14
|
+
* (session_fts 消费件——激活期对账策略位 ensureFtsIndex + snippet 切窗
|
|
15
|
+
* + memory_search 联合检索扩面 [历史会话] 行);18c-7 域 = 晋升桥候选
|
|
16
|
+
* 点名(简报尾行两形 + BriefBaseline.candidates 权威流)+ 效用进化
|
|
17
|
+
* (cite 引用回写件 cite.ts + dao markUsed/resolveShortId)+ 简报差分
|
|
18
|
+
* (memory/diff durable 词汇 + 纪元 tracker epochs LRU + 懒派生自愈);
|
|
19
|
+
* 18c-8 域 = 持有面收口(sweep 双清同拍——TTL 物化 + 访问日志 90 天窗口清扫)
|
|
20
|
+
* + 导入导出件(port.ts JSONL 序列化/解析 + command.ts 两命令处理器;
|
|
21
|
+
* provenance 写入面与 skill_manage 三动作经对账钉死已随 14b 落)。
|
|
22
|
+
* 迁移 export-only(host 装配根机械聚合入
|
|
23
|
+
* 宿主单链——05 §6.4);错误码注册(codes.ts)随本面引入生效。
|
|
24
|
+
*/
|
|
25
|
+
import './codes.js';
|
|
26
|
+
export { MEMORY_KINDS, MEMORY_STATUSES, MEMORY_FUZZY_JACCARD_THRESHOLD, MEMORY_POLARITY_JACCARD_THRESHOLD, MEMORY_SOURCE_REFS_CAP, MEMORY_SUMMARY_MAX_CHARS, MEMORY_CONTENT_MAX_CHARS, MEMORY_SEARCH_DEFAULT_LIMIT, MEMORY_SEARCH_MAX_LIMIT, MEMORY_ACCESS_LOG_DEFAULT_LIMIT, MEMORY_ACCESS_LOG_MAX_LIMIT, MEMORY_ACCESS_AGGREGATE_TOP_N, MEMORY_SKILL_NAME_RE, MEMORY_SKILL_NAME_MAX, MEMORY_RECENT_LIMIT, MEMORY_DAY_MS, MEMORY_BRIEF_MARKER, MEMORY_BRIEF_CHAR_LIMIT, MEMORY_BRIEF_TOP_N, MEMORY_BRIEF_STALE_DAYS, MEMORY_RECALL_QUERY_MAX_CHARS, MEMORY_RECALL_TOP_K, MEMORY_RECALL_POOL_FACTOR, MEMORY_RECALL_ROLE, MEMORY_REVIEW_TURN_THRESHOLD, MEMORY_REVIEW_TOOL_CALL_THRESHOLD, MEMORY_REVIEW_WINDOW_TURNS, MEMORY_REVIEW_CONFIDENCE, MEMORY_CONSOLIDATION_STALE_DAYS, MEMORY_OWNER_CAPACITY, MEMORY_CONSOLIDATION_ANCHOR_MS, MEMORY_DECAY_FACTOR, MEMORY_POLLUTION_DEFAULT_PATTERNS, MEMORY_SNIPPET_BEFORE, MEMORY_SNIPPET_AFTER, MEMORY_PROMOTION_KINDS, MEMORY_PROMOTION_TOP_N, MEMORY_PROMOTION_EVIDENCE_MIN, MEMORY_PROMOTION_USAGE_MIN, MEMORY_PROMOTION_DISTINCT_SESSIONS_MIN, MEMORY_DIFF_EPOCHS_LRU, MEMORY_LAST_ASSISTANT_TEXT_LRU, MEMORY_ACCESS_WINDOW_DAYS, MEMORY_EXPORT_MAGIC, MEMORY_EXPORT_FORMAT_VERSION, REVIEW_KINDS, llmTextOf, } from './types.js';
|
|
27
|
+
export { MEMORY_MIGRATIONS } from './migration.js';
|
|
28
|
+
export { scanForSecrets, sanitizeEntryForReadout } from './scan.js';
|
|
29
|
+
export { tokenizeForMerge, normalizeForMerge, jaccard, detectPolarityConflict, decideMerge, utilityScore, unionSourceRefs, } from './merge.js';
|
|
30
|
+
export { createMemoryDao, uuidv7 } from './dao.js';
|
|
31
|
+
export { createMemoryTools } from './tools.js';
|
|
32
|
+
export { isEligibleUserSource, userTextOf, detectCorrectionHit, buildCorrectionCandidate, createImmediateExtractor, } from './extract.js';
|
|
33
|
+
export { MEMORY_CITE_RE, shortIdOf, freshnessLabel, briefBaseline, renderCoreBrief, buildCoreBrief, recallForQuery, ensureRecallRole, recallInjectionMessage, } from './inject.js';
|
|
34
|
+
export { matchesToolPattern, isPollutingToolName, createPollutionTracker } from './pollution.js';
|
|
35
|
+
export { parseJsonPayload, transcribeForReview, runMemoryReview } from './review.js';
|
|
36
|
+
export { createConsolidator } from './consolidate.js';
|
|
37
|
+
export { sliceReviewWindow, createMemoryCycle } from './cycle.js';
|
|
38
|
+
export { snippetOf, ensureFtsIndex } from './fts.js';
|
|
39
|
+
export { parseCitations, createCiteRecorder, recordCorrectedCites, createLastAssistantTextCache, assistantTextOf, } from './cite.js';
|
|
40
|
+
export { MEMORY_DIFF_EVENT_TYPE, MEMORY_DIFF_EVENT_META, MEMORY_DIFF_ROLE, faceOf, fingerprintOf, diffFace, renderDiffInjection, ensureDiffRole, diffInjectionMessage, createDiffTracker, } from './diff.js';
|
|
41
|
+
export { isWithinRoots, exportRowOf, serializeMemoryExport, parseMemoryImportHeader, parseMemoryImportRow, runMemoryImport, buildMemoryExport, } from './port.js';
|
|
42
|
+
export { MEMORY_EXPORT_USAGE, MEMORY_IMPORT_USAGE, runMemoryExportCommand, runMemoryImportCommand } from './command.js';
|