{"id":"5af589bc-6904-4701-8023-d83b0a3af529","entityType":"agent","slug":"clawhub-paudyyin-memory-tencentdb","name":"memory-tencentdb","canonicalUrl":"https://www.xpersona.co/agent/clawhub-paudyyin-memory-tencentdb","canonicalPath":"/agent/clawhub-paudyyin-memory-tencentdb","generatedAt":"2026-10-12T18:00:42.201Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T22:45:43.255Z","emptyReason":null},"description":"四层记忆系统插件 — 自动捕获对话、提取结构化记忆、归纳场景、生成用户画像。支持 L0→L1→L2→L3 渐进式管线，本地 SQLite + 腾讯云向量数据库双后端。","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 982 downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s172x1s50dh0bgmm3yc9516nr586kk4b:memory-tencentdb","sourceUrl":"https://clawhub.ai/paudyyin/memory-tencentdb","homepage":"https://clawhub.ai/paudyyin/skills/memory-tencentdb","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/paudyyin/memory-tencentdb","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/paudyyin/skills/memory-tencentdb","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"memory-tencentdb technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T22:45:43.255Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T22:45:43.255Z","emptyReason":null},"stars":null,"forks":null,"downloads":982,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"0.3.7","tractionLabel":"982 downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T22:45:43.239Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T22:45:43.255Z","lastCrawledAt":"2026-10-11T22:45:43.239Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T22:45:43.239Z","lastVerifiedAt":null,"highlights":[{"version":"0.3.7","createdAt":"2026-06-08T03:09:03.780Z","changelog":"Remove standalone LLM mode use Gateway built-in model","fileCount":152,"zipByteSize":768852},{"version":"0.3.6","createdAt":"2026-05-31T03:17:38.331Z","changelog":"Four-layer memory system plugin for OpenClaw - L0/L1/L2/L3 pipeline, SQLite + TencentDB backends","fileCount":5,"zipByteSize":11429},{"version":"0.3.5","createdAt":"2026-05-31T03:02:02.520Z","changelog":"Four-layer memory system: L0 conversation capture → L1 memory extraction → L2 scene induction → L3 persona generation. Supports local SQLite and Tencent Cloud VectorDB backends.","fileCount":152,"zipByteSize":768811}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s172x1s50dh0bgmm3yc9516nr586kk4b:memory-tencentdb","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s172x1s50dh0bgmm3yc9516nr586kk4b:memory-tencentdb` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/paudyyin/memory-tencentdb before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-12T18:00:42.198Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-paudyyin-memory-tencentdb/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T22:45:43.255Z","emptyReason":null},"readme":"Skill: memory-tencentdb\n\nOwner: paudyyin\n\nSummary: 四层记忆系统插件 — 自动捕获对话、提取结构化记忆、归纳场景、生成用户画像。支持 L0→L1→L2→L3 渐进式管线，本地 SQLite + 腾讯云向量数据库双后端。\n\nTags: latest:0.3.7, llm-extraction:0.3.5, long-term-memory:0.3.5, memory:0.3.5, persona:0.3.5, sqlite:0.3.5, vector-search:0.3.5\n\nVersion history:\n\nv0.3.7 | 2026-06-08T03:09:03.780Z | user\n\nRemove standalone LLM mode use Gateway built-in model\n\nv0.3.6 | 2026-05-31T03:17:38.331Z | user\n\nFour-layer memory system plugin for OpenClaw - L0/L1/L2/L3 pipeline, SQLite + TencentDB backends\n\nv0.3.5 | 2026-05-31T03:02:02.520Z | user\n\nFour-layer memory system: L0 conversation capture → L1 memory extraction → L2 scene induction → L3 persona generation. Supports local SQLite and Tencent Cloud VectorDB backends.\n\nArchive index:\n\nArchive v0.3.7: 152 files, 768852 bytes\n\nFiles: bin/export-tencent-vdb.mjs (690b), bin/migrate-sqlite-to-tcvdb.mjs (460b), bin/read-local-memory.mjs (716b), CHANGELOG.md (15460b), dist/index.mjs (703826b), dist/l1-reader-B6GBuxTv.mjs (3670b), hermes-plugin/memory/memory_tencentdb/__init__.py (48007b), hermes-plugin/memory/memory_tencentdb/client.py (5812b), hermes-plugin/memory/memory_tencentdb/plugin.yaml (458b), hermes-plugin/memory/memory_tencentdb/README.md (14846b), hermes-plugin/memory/memory_tencentdb/supervisor.py (12058b), hermes-plugin/memory/memory_tencentdb/tests/__init__.py (0b), hermes-plugin/memory/memory_tencentdb/tests/test_gateway_shutdown_leak.py (33628b), hermes-plugin/memory/memory_tencentdb/tests/test_memory_tencentdb_recovery.py (15674b), index.ts (34874b), openclaw.plugin.json (11198b), package.json (3662b), README.md (16439b), scripts/export-tencent-vdb/dist/export-tencent-vdb.js (19330b), scripts/install_hermes_memory_tencentdb.sh (12348b), scripts/memory-tencentdb-ctl.sh (38742b), scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/cli-entry.js (400b), scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/config-write.js (2371b), scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/manifest-write.js (1353b), scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/sqlite-to-tcvdb.js (27095b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/profile/profile-sync.js (8136b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/record/l1-writer.js (6490b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/scene/scene-format.js (1686b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/scene/scene-index.js (2842b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/scene/scene-navigation.js (2400b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/bm25-local.js (2264b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/embedding.js (19027b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/sqlite.js (80300b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/tcvdb-client.js (9517b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/tcvdb.js (43647b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/types.js (850b), scripts/migrate-sqlite-to-tcvdb/dist/src/profile/profile-sync.js (6894b), scripts/migrate-sqlite-to-tcvdb/dist/src/record/l1-writer.js (6490b), scripts/migrate-sqlite-to-tcvdb/dist/src/scene/scene-format.js (1686b), scripts/migrate-sqlite-to-tcvdb/dist/src/scene/scene-index.js (2842b), scripts/migrate-sqlite-to-tcvdb/dist/src/scene/scene-navigation.js (2084b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/bm25-local.js (2264b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/embedding.js (18904b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/sqlite.js (80297b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/tcvdb-client.js (8766b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/tcvdb.js (43647b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/types.js (850b), scripts/migrate-sqlite-to-tcvdb/dist/src/utils/manifest.js (3264b), scripts/migrate-sqlite-to-tcvdb/README.md (8293b), scripts/openclaw-after-tool-call-messages.patch.sh (15460b), scripts/read-local-memory/dist/read-local-memory.js (34263b), scripts/README.memory-tencentdb-ctl.md (17355b), scripts/setup-offload.sh (14013b), skill-card.md (2943b), SKILL.md (2922b), src/adapters/index.ts (931b), src/adapters/openclaw/host-adapter.ts (3443b), src/adapters/openclaw/index.ts (325b), src/adapters/openclaw/llm-runner.ts (3201b), src/adapters/standalone/host-adapter.ts (2598b), src/adapters/standalone/index.ts (358b), src/adapters/standalone/llm-runner.ts (10869b), src/cli/commands/seed.ts (10485b), src/cli/index.ts (1883b), src/cli/README.md (4674b), src/config.ts (24295b), src/core/conversation/l0-recorder.ts (22156b), src/core/hooks/auto-capture.ts (14826b), src/core/hooks/auto-recall.ts (32080b), src/core/index.ts (613b), src/core/persona/persona-generator.ts (9108b), src/core/persona/persona-trigger.ts (4368b), src/core/profile/profile-sync.ts (8222b), src/core/prompts/l1-dedup.ts (7120b), src/core/prompts/l1-extraction.ts (6275b), src/core/prompts/persona-generation.ts (8053b), src/core/prompts/scene-extraction.ts (14452b), src/core/record/l1-dedup.ts (14909b), src/core/record/l1-extractor.ts (18264b), src/core/record/l1-reader.ts (6512b)\n\nFile v0.3.7:SKILL.md\n\n---\nname: memory-tencentdb\ndescription: 四层记忆系统插件 — 自动捕获对话、提取结构化记忆、归纳场景、生成用户画像。支持 L0→L1→L2→L3 渐进式管线，本地 SQLite + 腾讯云向量数据库双后端。\nversion: 0.3.6\ntags: [\"memory\", \"long-term-memory\", \"persona\", \"sqlite\", \"vector-search\"]\nauthor: paudyyin\n---\n\n# memory-tencentdb — 四层记忆系统\n\n为 OpenClaw AI Agent 提供 L0→L1→L2→L3 长期记忆能力。\n\n## v0.3.6 变更（2026-06-08）\n\n- **移除独立 LLM 模式**：删除 `llm.enabled` 配置和 StandaloneLLMRunner，L1/L2/L3 提取统一走 Gateway 内置模型（runEmbeddedPiAgent）\n- **简化配置**：不再需要单独配置 LLM API 端点和 Key，复用 Gateway 已有的模型认证\n- **修复 L1 提取静默失败**：之前独立 LLM 因 apiKey 为空返回 401，导致提取管线完全停止\n\n## 架构\n\n```\n对话开始\n  → Auto-Recall: 向量/混合搜索相关记忆 + 加载 Persona → 注入系统上下文\n\n对话结束\n  → L0: 录制对话消息 → SQLite + JSONL 双写\n  → Pipeline Scheduler: 达到 N 轮后触发\n     ├── L1: LLM 提取结构化记忆 + 向量去重 → JSONL + SQLite\n     ├── L2: LLM 归纳场景块 → Markdown 文件\n     └── L3: LLM 生成/更新用户画像 → persona.md\n```\n\n## 四层记忆\n\n| 层级 | 名称 | 说明 |\n|------|------|------|\n| L0 | 对话录制 | 原始对话消息捕获 |\n| L1 | 记忆提取 | 结构化记忆（persona/episodic/instruction） |\n| L2 | 场景归纳 | 场景块（Scene Block） |\n| L3 | 用户画像 | 用户人格画像（Persona） |\n\n## 记忆类型\n\n- **persona**：用户的稳定属性、偏好、技能、价值观\n- **episodic**：客观发生的动作、决定、计划或结果\n- **instruction**：用户对 AI 的长期行为规则\n\n## 安装\n\n```bash\nclawhub install memory-tencentdb\n```\n\n## 配置\n\n在 openclaw.json 中添加：\n\n```json\n{\n  \"plugins\": {\n    \"allow\": [\"mx\", \"memory-tencentdb\"],\n    \"load\": {\n      \"paths\": [\"<插件路径>\"]\n    },\n    \"entries\": {\n      \"memory-tencentdb\": {\n        \"enabled\": true,\n        \"config\": {\n          \"pipeline\": {\n            \"everyNConversations\": 3,\n            \"enableWarmup\": true,\n            \"l1IdleTimeoutSeconds\": 10\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n> **注意**：v0.3.6 起不再需要 `llm` 配置段，L1/L2/L3 提取自动使用 Gateway 内置模型。\n\n## 存储后端\n\n- `sqlite`（默认）：本地 SQLite + sqlite-vec\n- `tcvdb`：腾讯云向量数据库\n\n## CLI 命令\n\n```bash\nopenclaw memory-tdai seed --input conversations.json\n```\n\n## 故障排查\n\n如果 L1 提取为空：\n1. 检查 `plugins.allow` 包含 `\"memory-tencentdb\"`\n2. 检查 `plugins.load.paths` 包含插件路径\n3. 检查 Gateway 模型配置正常（`models.providers` 和 `agents.defaults.model`）\n4. 检查 vectors.db 中 l1_fts 与 l1_records 行数一致\n\nFile v0.3.7:hermes-plugin/memory/memory_tencentdb/README.md\n\n# memory-tencentdb Memory Provider (Hermes)\n\nHermes-side [`MemoryProvider`](../../../../../hermes-agent/agent/memory_provider.py)\nadapter for the **memory-tencentdb** four-layer memory system\n(L0 conversation capture → L1 episodic extraction → L2 scene blocks → L3 persona synthesis).\n\nThe heavy lifting — capture, extraction, storage, recall, pipeline scheduling —\nruns in a Node.js **Gateway** sidecar (shipped by the same package as the\nOpenClaw plugin). This Python provider is a thin HTTP client + process\nsupervisor that plugs the Gateway into Hermes's lifecycle.\n\n## Architecture\n\n```\nHermes Agent (Python)\n  └─ MemoryManager\n       └─ MemoryTencentdbProvider        (this directory)\n            ├─ GatewaySupervisor          — starts / health-checks the sidecar\n            └─ MemoryTencentdbSdkClient   — POST /recall, /capture, /search/*, /session/end\n                    │\n                    ▼  HTTP (127.0.0.1:8420 by default)\n            memory-tencentdb Gateway (Node.js)\n               └─ memory-tencentdb Core\n                    ├─ L0  Conversation store      (SQLite / TCVDB + JSONL)\n                    ├─ L1  Episodic extraction     (LLM + vector dedup)\n                    ├─ L2  Scene blocks            (Markdown under data dir)\n                    ├─ L3  Persona synthesis       (persona.md)\n                    └─ Storage backends: SQLite + sqlite-vec  OR  Tencent VectorDB\n```\n\nHermes lifecycle → Gateway mapping:\n\n| Hermes hook / call          | Gateway endpoint | Behavior                                                   |\n|-----------------------------|------------------|------------------------------------------------------------|\n| `prefetch(query)`           | `POST /recall`   | Synchronous. Returns `<memory-context>` text for injection |\n| `sync_turn(user, assistant)`| `POST /capture`  | Fire-and-forget on a background daemon thread (max 4 in-flight) |\n| `shutdown()` / `on_session_end` | `POST /session/end` | Flush pending pipeline work                             |\n| `get_tool_schemas()`        | —                | Advertises two LLM tools (see below)                       |\n\nReliability features baked into the provider:\n\n- **Circuit breaker** — 5 consecutive Gateway failures → pause all calls for 60 s.\n- **Back-pressure on capture** — at most 4 in-flight `sync_turn` threads; a 5th\n  waits up to 5 s for the oldest one before starting (Gateway hangs can't grow\n  threads unboundedly).\n- **Supervised startup** — if `MEMORY_TENCENTDB_GATEWAY_CMD` is set (or the\n  provider auto-discovers `src/gateway/server.ts`, see below), it starts the\n  sidecar, polls `/health` for up to 30 s, and tails `gateway.stderr.log` on\n  crash for diagnostics.\n- **Zero-config auto-discovery** — when `MEMORY_TENCENTDB_GATEWAY_CMD` is\n  unset, the provider looks for `src/gateway/server.ts` next to the plugin\n  checkout (in-tree) and, as a last resort, under\n  `~/.memory-tencentdb/tdai-memory-openclaw-plugin/` (preferred),\n  `~/tdai-memory-openclaw-plugin/` (legacy), and\n  `~/.hermes/plugins/tdai-memory-openclaw-plugin/`.\n  A fresh `git clone` therefore usually works without any extra env wiring —\n  override with the env var when you need a non-standard layout.\n\n## Installation Location\n\nThis directory (`hermes-plugin/memory/memory_tencentdb/`) is the **source of\ntruth** for the provider; Hermes does **not** load it from here. At startup\nHermes scans two locations for memory providers, in precedence order (see\n`hermes-agent/plugins/memory/__init__.py`):\n\n1. **Bundled** — `<hermes-agent-checkout>/plugins/memory/<name>/`\n   **This is the path memory_tencentdb ships under.** It sits alongside the\n   other in-tree providers (`byterover/`, `honcho/`, `mem0/`, `hindsight/`,\n   …). Bundled entries take precedence over user-installed ones on name\n   collision.\n2. **User-installed** — `$HERMES_HOME/plugins/<name>/`, where\n   `$HERMES_HOME` defaults to `~/.hermes` (see\n   `hermes_constants.get_hermes_home()`). This path is for third-party\n   providers; we don't use it for memory_tencentdb.\n\n**The trailing directory name must be exactly `memory_tencentdb`** — Hermes\nuses that directory name as the provider key; it must match\n`plugin.yaml::name` and the value of `memory.provider` in `config.yaml`.\n(The hyphenated form `memory-tencentdb` is a *config-side alias*, not a\nvalid directory name.)\n\nPick one of the two installation styles:\n\n**Install A — symlink (recommended for developers working on both repos\nsimultaneously):** keeps this repo as the single source of truth so\n`git pull` in the plugin repo is immediately visible to Hermes.\n\n```bash\n# from the tdai-memory-openclaw-plugin checkout:\nln -s \"$(pwd)/hermes-plugin/memory/memory_tencentdb\" \\\n      <hermes-agent-checkout>/plugins/memory/memory_tencentdb\n```\n\n**Install B — copy (shipped alongside hermes-agent):** freezes a specific\nversion of the provider inside the hermes-agent tree. This is how\nmemory_tencentdb is currently vendored in this repo pair — the two copies\nunder `tdai-memory-openclaw-plugin/hermes-plugin/memory/memory_tencentdb/`\nand `hermes-agent/plugins/memory/memory_tencentdb/` are kept in sync\nmanually.\n\n```bash\ncp -r tdai-memory-openclaw-plugin/hermes-plugin/memory/memory_tencentdb \\\n      hermes-agent/plugins/memory/memory_tencentdb\n```\n\nVerify Hermes sees the provider:\n\n```bash\n$ cd <hermes-agent-checkout>\n$ python -c 'from plugins.memory import discover_memory_providers; \\\n             [print(n, a) for n, _, a in discover_memory_providers()]'\nmemory_tencentdb True\n...\n```\n\nIf the provider does not appear:\n- confirm the target path is `hermes-agent/plugins/memory/memory_tencentdb/`\n  (underscore, not hyphen);\n- confirm `__init__.py` and `plugin.yaml` sit directly inside that dir;\n- the discovery scan requires `__init__.py` to contain the literal string\n  `MemoryProvider` or `register_memory_provider` — both are present in\n  this provider, so this is a non-issue as long as the file is the one\n  from this repo.\n\n> The **Gateway source code** (Node.js sidecar under `src/gateway/`) stays\n> in the `tdai-memory-openclaw-plugin` checkout and does NOT need to be\n> copied into hermes-agent — the Python provider auto-discovers it via\n> the paths listed in Option A below, or via `MEMORY_TENCENTDB_GATEWAY_CMD`.\n\n## Setup\n\n### 1. Activate in Hermes (`~/.hermes/config.yaml`)\n\n```yaml\nmemory:\n  provider: memory_tencentdb   # canonical name\n  # Aliases accepted for backward compatibility: `memory-tencentdb`, `tdai`\n```\n\n### 2. Provide Gateway runtime + LLM credentials\n\nAt minimum the Gateway needs an OpenAI-compatible endpoint for L1/L2/L3\nextraction. Set these in the Hermes process environment:\n\n```bash\nexport MEMORY_TENCENTDB_LLM_API_KEY=\"sk-...\"\nexport MEMORY_TENCENTDB_LLM_BASE_URL=\"https://api.openai.com/v1\"   # optional\nexport MEMORY_TENCENTDB_LLM_MODEL=\"gpt-4o\"                         # optional\n```\n\n### 3. Start the Gateway\n\nYou have three options; pick whichever fits your deployment.\n\n**Option A — Auto-discovery (zero-config).** If the plugin checkout sits at\none of the well-known paths, the provider will find `src/gateway/server.ts`\non its own and `Popen()` it as `node --import tsx <path>`. Searched paths, in\norder:\n\n1. In-tree: `<plugin-root>/src/gateway/server.ts` (when Hermes loads this\n   provider from a checkout of this repo).\n2. `~/.memory-tencentdb/tdai-memory-openclaw-plugin/src/gateway/server.ts` (preferred install location)\n3. `~/tdai-memory-openclaw-plugin/src/gateway/server.ts` (legacy)\n4. `~/.hermes/plugins/tdai-memory-openclaw-plugin/src/gateway/server.ts`\n\nNo environment variables required beyond the LLM credentials above. A line\nlike\n\n```\nINFO plugins.memory.memory_tencentdb: memory-tencentdb Gateway command auto-discovered: /…/src/gateway/server.ts\n```\n\nwill appear in `~/.hermes/logs/agent.log` on startup.\n\n**Option B — Explicit auto-start.** Override or disable discovery by setting\nthe command yourself:\n\n```bash\nexport MEMORY_TENCENTDB_GATEWAY_CMD=\"node --import tsx /abs/path/to/tdai-memory-openclaw-plugin/src/gateway/server.ts\"\n```\n\nThe provider will `Popen()` this command on `initialize()`, wait for\n`GET /health` to report `ok`/`degraded`, and tail stderr on crash.\n\n**Option C — Run it yourself.** Start the Gateway separately on the default\nport (`127.0.0.1:8420`) before launching Hermes; the provider will detect it\nvia `/health` and skip the subprocess-launch path.\n\n```bash\ncd tdai-memory-openclaw-plugin\nnode --import tsx src/gateway/server.ts\n```\n\n> Storage backend (SQLite vs Tencent VectorDB), embedding config, pipeline\n> cadence, recall strategy, etc. are all **Gateway-side** settings. For\n> OpenClaw installs they live in `~/.openclaw/openclaw.json`; for standalone\n> Hermes deployments configure the Gateway via its own config file or env.\n> See the plugin's top-level [README](../../../README.md) for the full\n> configuration schema.\n\n## Environment Variables\n\n### Gateway location\n\n| Variable                          | Default             | Description                                               |\n|-----------------------------------|---------------------|-----------------------------------------------------------|\n| `MEMORY_TENCENTDB_GATEWAY_HOST`   | `127.0.0.1`         | Gateway host                                              |\n| `MEMORY_TENCENTDB_GATEWAY_PORT`   | `8420`              | Gateway port (must be 1..65535; invalid values fall back) |\n| `MEMORY_TENCENTDB_GATEWAY_CMD`    | —                   | If set, the provider auto-starts the Gateway with this command. If unset, the provider auto-discovers `src/gateway/server.ts` next to the checkout or under `$HOME` (see Option A above) |\n| `MEMORY_TENCENTDB_LOG_DIR`        | `~/.hermes/logs/memory_tencentdb` | Where the supervisor writes `gateway.stdout.log` / `gateway.stderr.log` |\n\n### Gateway data directory (owned by the Gateway, not this provider)\n\nThe L0~L3 data directory is resolved **inside the Gateway** (`src/gateway/config.ts`),\nnot here. Priority:\n\n1. `TDAI_DATA_DIR` env var\n2. `data.baseDir` from a `tdai-gateway.yaml` / `tdai-gateway.json` config file\n3. Default: `~/.memory-tencentdb/memory-tdai`\n   (Override the parent dir with `MEMORY_TENCENTDB_ROOT` if needed.)\n4. Legacy fallback: if `~/.memory-tencentdb/memory-tdai` does not exist but the\n   pre-0.4 location `~/memory-tdai` does, the Gateway keeps using the legacy\n   dir and prints a one-line deprecation warning to stderr. Run\n   `install_hermes_memory_tencentdb.sh` to migrate it automatically.\n\nHermes forwards the inherited environment to the Gateway subprocess, so\nsetting `TDAI_DATA_DIR` before launching Hermes is enough to override it.\nThe old `MEMORY_TENCENTDB_DATA_DIR` env var is no longer read — it was never\nconsumed by the Gateway anyway (names did not match), so removing it just\neliminates a silent no-op.\n\n### Gateway LLM (consumed by the Node sidecar, not by this provider)\n\n| Variable                          | Default                      | Description                         |\n|-----------------------------------|------------------------------|-------------------------------------|\n| `MEMORY_TENCENTDB_LLM_API_KEY`    | —                            | LLM API key (required for L1/L2/L3) |\n| `MEMORY_TENCENTDB_LLM_BASE_URL`   | `https://api.openai.com/v1`  | OpenAI-compatible API base URL      |\n| `MEMORY_TENCENTDB_LLM_MODEL`      | `gpt-4o`                     | Model name                          |\n\n> ⚠️ Only `MEMORY_TENCENTDB_*` env vars are honored by this provider for the\n> Gateway location and LLM credentials. Data-directory resolution is\n> deliberately delegated to the Gateway via `TDAI_DATA_DIR` (see above) so\n> the provider and the Gateway can never disagree about where L0~L3 live.\n\n## LLM Tools\n\nThis provider exposes two tools to the model via `get_tool_schemas()`:\n\n| Tool                                   | Purpose                                           | Args                                            |\n|----------------------------------------|---------------------------------------------------|-------------------------------------------------|\n| `memory_tencentdb_memory_search`       | Search L1 structured long-term memories           | `query` (required), `limit` (1..20, default 5), `type` (`persona`/`episodic`/`instruction`) |\n| `memory_tencentdb_conversation_search` | Search L0 raw conversation history                | `query` (required), `limit` (1..20, default 5)  |\n\nTool-call arguments are defensively coerced: `limit` accepts ints, numeric\nstrings, and floats, rejects bools, and is clamped to `[1, 20]` with a\nwarning on garbage input.\n\n> These are the **only** tool names registered with the LLM. The old\n> `tdai_memory_search` / `tdai_conversation_search` names are not served by\n> this provider — if older transcripts reference them, `handle_tool_call`\n> will return an \"Unknown tool\" error.\n\n## Plugin Metadata (`plugin.yaml`)\n\n```yaml\nname: memory_tencentdb            # canonical provider name\ndisplay_name: memory-tencentdb\nhooks:\n  - on_memory_write               # reserved; not yet mirrored to the Gateway\n  - on_session_end                # triggers POST /session/end\naliases:\n  - tdai                          # legacy config value still resolves here\n  - memory-tencentdb              # hyphenated form resolves here too\n```\n\n## Troubleshooting\n\n- **\"memory-tencentdb Gateway not available\"** on startup: either\n  `MEMORY_TENCENTDB_GATEWAY_CMD` is unset *and* auto-discovery did not find\n  `src/gateway/server.ts` *and* nothing is listening on `8420`, or the\n  sidecar crashed. Check `~/.hermes/logs/memory_tencentdb/gateway.stderr.log`\n  (override with `MEMORY_TENCENTDB_LOG_DIR`). To confirm auto-discovery was\n  attempted, enable `DEBUG` logging and look for\n  `memory-tencentdb Gateway auto-discovery found no server.ts under: …`;\n  that log line enumerates every path that was searched.\n- **Gateway starts from the wrong checkout**: auto-discovery walks a fixed\n  preference list (in-tree first, then `$HOME`). If you want to pin a\n  specific path, set `MEMORY_TENCENTDB_GATEWAY_CMD` explicitly — it always\n  wins over discovery.\n- **Search tools silently missing from the LLM**: `get_tool_schemas()`\n  returns `[]` until either the Gateway is reachable or one of\n  `MEMORY_TENCENTDB_GATEWAY_CMD` / `MEMORY_TENCENTDB_GATEWAY_PORT` is set\n  in the environment. Set the env var so the tools are advertised\n  optimistically at registration time.\n- **\"circuit breaker tripped\"** warnings: five consecutive Gateway errors\n  were observed. Calls are paused for 60 s; check Gateway health and logs.\n- **Capture backlog warnings**: Gateway is slow or hung — `sync_turn` is\n  tracking ≥ 4 in-flight threads. Inspect Gateway logs for stuck L1\n  extractions or LLM timeouts.\n\nFile v0.3.7:README.md\n\n# @tencentdb-agent-memory/memory-tencentdb\n\n**Four-layer memory system plugin for [OpenClaw](https://github.com/openclaw/openclaw).**\n\n为 AI Agent 提供长期记忆能力。通过 L0→L1→L2→L3 四层渐进式管线，自动将对话内容提炼为结构化记忆、场景块和用户画像。支持纯本地 SQLite 和远端腾讯云向量数据库（TCVDB）两种存储后端。\n\n## ✨ 核心功能\n\n- **L0 — 对话录制**：自动捕获每轮对话原始消息，IMemoryStore + JSONL 双写\n- **L1 — 记忆提取**：由 LLM 从对话中提取结构化记忆，支持向量去重与冲突检测\n- **L2 — 场景归纳**：基于 L1 记忆自动归纳场景块（Scene Block），由 LLM 增量提取\n- **L3 — 用户画像**：基于场景块自动生成/更新用户画像（Persona）\n- **自动召回（Auto-Recall）**：对话开始前自动注入相关记忆和用户画像到上下文\n- **多后端存储**：支持 `sqlite`（本地 SQLite + sqlite-vec）和 `tcvdb`（腾讯云向量数据库，服务端 embedding + hybridSearch）\n- **BM25 稀疏向量**：内置 BM25 编码器（tcvdb-text），支持中英文混合搜索\n- **关键词+向量混合搜索**：hybrid（关键词 + 向量 RRF 融合）搜索策略\n- **语义搜索工具**：Agent 可调用 `tdai_memory_search`（L1 记忆搜索）和 `tdai_conversation_search`（L0 对话搜索）\n- **Seed CLI**：`openclaw memory-tdai seed` 命令，支持导入历史对话数据（详见 [CLI 文档](src/cli/README.md)）\n- **Session 隔离**：不同渠道/Agent 的对话独立调度、独立提取\n- **本地数据清理**：可配置 L0/L1 数据保留天数，定时自动清理过期文件\n- **Manifest 元数据**：数据目录自动生成 `.metadata/manifest.json`，记录 store 绑定信息和 seed 运行记录\n- **支持零配置**：支持零配置工作，简单易用\n\n## 🏗️ 关键原理\n\n```\n对话开始\n  → Auto-Recall: 向量/混合搜索相关记忆 + 加载 Persona → 注入系统上下文\n\n对话结束\n  → Auto-Capture (L0): 录制对话消息 → IMemoryStore (SQLite/TCVDB) + JSONL 双写\n  → Pipeline Scheduler: 达到 N 轮后按序触发 L1 → L2 → L3\n     ├── L1: LLM 提取结构化记忆 + 向量去重 → 写入 JSONL + IMemoryStore\n     ├── L2: LLM 归纳场景块 → Markdown 文件\n     └── L3: LLM 生成/更新用户画像 → persona.md\n```\n\n### 数据目录结构\n\n```\n<pluginDataDir>/\n├── conversations/     — L0 每日 JSONL 分片（每行一条消息）\n├── records/           — L1 每日 JSONL 分片（提取的记忆）\n├── scene_blocks/      — L2 场景块 .md 文件\n├── vectors.db         — SQLite + vec0 向量数据库（仅 storeBackend=sqlite）\n├── .metadata/\n│   ├── manifest.json  — 数据目录元数据（store 绑定、seed 信息）\n│   └── checkpoint.json\n└── .backup/           — 滚动备份（persona, scene_blocks）\n```\n\n## 🚀 Quick Start（Docker）\n\n使用预构建的 Docker 镜像，一行命令即可启动带记忆能力的 Hermes Agent：\n\n```bash\ndocker run -d \\\n  --name hermes-memory \\\n  --restart unless-stopped \\\n  -p 8420:8420 \\\n  -e MODEL_API_KEY=\"your-api-key\" \\\n  -e MODEL_BASE_URL=\"https://api.lkeap.cloud.tencent.com/v1\" \\\n  -e MODEL_NAME=\"deepseek-v3.2\" \\\n  -e MODEL_PROVIDER=\"custom\" \\\n  -v hermes_data:/opt/data \\\n  agentmemory/hermes-memory:latest\n```\n\n镜像支持 `linux/amd64` 和 `linux/arm64` 架构。内置腾讯云 DeepSeek-V3.2 默认值，如使用该模型可省略 `MODEL_BASE_URL`/`MODEL_NAME`/`MODEL_PROVIDER`，只传 `MODEL_API_KEY` 即可。\n\n### 环境变量\n\n#### 统一模型配置（Hermes + TDAI 共用）\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `MODEL_API_KEY` | - | LLM API Key（**必填**） |\n| `MODEL_BASE_URL` | `https://api.lkeap.cloud.tencent.com/v1` | LLM API 地址 |\n| `MODEL_NAME` | `deepseek-v3.2` | 模型名称 |\n| `MODEL_PROVIDER` | `custom` | 模型 provider：`custom` / `openrouter` / `anthropic` / `openai` / `gemini` |\n\n#### 服务配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `TDAI_GATEWAY_PORT` | `8420` | Gateway 端口 |\n| `TDAI_GATEWAY_HOST` | `0.0.0.0` | Gateway 绑定地址 |\n| `TDAI_DATA_DIR` | `/opt/data/tdai-memory` | 记忆数据目录 |\n| `HERMES_HOME` | `/opt/data` | Hermes 数据目录 |\n\n### 验证运行\n\n```bash\n# 验证 Gateway 健康状态\ncurl http://localhost:8420/health\n\n# 进入 Hermes 对话\ndocker exec -it hermes-memory hermes\n\n# 查看容器日志\ndocker logs -f hermes-memory\n```\n\n> 更多配置选项和集成说明请参考下文。\n\n---\n\n## 📋 前置依赖\n\n| 依赖 | 版本要求 | 说明 |\n|------|---------|------|\n| [OpenClaw](https://github.com/nicepkg/openclaw) | `>= 2026.3.13` | 宿主框架，提供插件 SDK 及 Gateway 运行环境 |\n| [Node.js](https://nodejs.org/) | `>= 22.16.0` | 运行时环境 |\n| [`node-llama-cpp`](https://github.com/withcatai/node-llama-cpp) | `^3.16.2` | 本地 embedding 模型（GGUF 格式），提供离线向量化能力（仅 sqlite 后端需要） |\n| [`sqlite-vec`](https://github.com/asg017/sqlite-vec) | `0.1.7-alpha.2` | SQLite 向量搜索扩展（仅 sqlite 后端需要） |\n| [`tcvdb-text`](../../../packages/tcvdb-text) | `workspace:*` | BM25 稀疏向量编码器，支持中英文分词（仅 tcvdb 后端需要） |\n\n> 默认场景下无需安装 `node-llama-cpp`。如需启用本地 embedding，再在宿主环境手动安装该包。\n\n## 📦 安装\n\n```bash\n# 安装插件\nopenclaw plugins install @tencentdb-agent-memory/memory-tencentdb\n\n# 更新插件\nopenclaw plugins update memory-tencentdb\n\n# 卸载插件\nopenclaw plugins uninstall memory-tencentdb\n```\n\n安装完成后，**重启 Gateway** 使插件生效：\n\n```bash\nopenclaw gateway restart\n```\n\n## ⚙️ 配置\n\n插件配置位于 `~/.openclaw/openclaw.json` 中 `memory-tencentdb` 字段下。**所有字段均有合理默认值，零配置即可使用。**\n\n### 最小配置\n\n安装启用后即为该状态（默认使用本地 SQLite 后端）：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"enabled\": true\n  }\n}\n```\n\n> **⚠️ 重要：`allowPromptInjection` 必须为 `true`**\n>\n> 本插件通过 `before_prompt_build` hook 在对话开始前将召回的记忆注入系统上下文。\n> OpenClaw v2026.4.5+ 新增了 `allowPromptInjection` 安全控制，当该选项设为 `false` 时，\n> `before_prompt_build` hook 将被**完全阻止注册**，导致记忆召回静默失效（不会报错，仅有 warn 日志）。\n>\n> 请确保 `openclaw.json` 中**不要**将该插件的 `allowPromptInjection` 设为 `false`：\n>\n> ```jsonc\n> // ❌ 错误配置 — 会导致记忆召回完全失效\n> {\n>   \"plugins\": {\n>     \"entries\": {\n>       \"memory-tencentdb\": {\n>         \"hooks\": { \"allowPromptInjection\": false }\n>       }\n>     }\n>   }\n> }\n>\n> ```\n\n### TCVDB 后端配置\n\n使用腾讯云向量数据库作为存储后端：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"storeBackend\": \"tcvdb\",\n    \"tcvdb\": {\n      \"url\": \"http://your-vdb-instance:8100\",\n      \"apiKey\": \"your-api-key\",\n      \"database\": \"my_memory_db\",\n      \"alias\": \"生产环境\"\n    }\n  }\n}\n```\n\n### 完整配置\n\n用户可按需配置，提升使用体验：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"storeBackend\": \"sqlite\",\n    \"capture\": {\n      \"enabled\": true,\n      \"excludeAgents\": [\"bench-judge-*\"],\n      \"l0l1RetentionDays\": 90,\n      \"allowAggressiveCleanup\": false,\n      \"cleanTime\": \"03:00\"\n    },\n    \"extraction\": {\n      \"enabled\": true,\n      \"enableDedup\": true,\n      \"maxMemoriesPerSession\": 20,\n      \"model\": \"provider/model-name\"\n    },\n    \"persona\": {\n      \"triggerEveryN\": 50,\n      \"maxScenes\": 15,\n      \"backupCount\": 3,\n      \"sceneBackupCount\": 10,\n      \"model\": \"provider/model-name\"\n    },\n    \"pipeline\": {\n      \"everyNConversations\": 5,\n      \"enableWarmup\": true,\n      \"l1IdleTimeoutSeconds\": 600,\n      \"l2DelayAfterL1Seconds\": 10,\n      \"l2MinIntervalSeconds\": 900,\n      \"l2MaxIntervalSeconds\": 3600,\n      \"sessionActiveWindowHours\": 24\n    },\n    \"recall\": {\n      \"enabled\": true,\n      \"maxResults\": 5,\n      \"scoreThreshold\": 0.3,\n      \"strategy\": \"hybrid\",\n      \"timeoutMs\": 5000\n    },\n    \"embedding\": {\n      \"enabled\": true,\n      \"provider\": \"none\",\n      \"baseUrl\": \"https://your-embedding-endpoint/v1\",\n      \"apiKey\": \"your-api-key\",\n      \"model\": \"text-embedding-3-small\",\n      \"dimensions\": 1536,\n      \"conflictRecallTopK\": 5,\n      \"maxInputChars\": 5000,\n      \"timeoutMs\": 10000\n    },\n    \"tcvdb\": {\n      \"url\": \"http://your-vdb-instance:8100\",\n      \"username\": \"root\",\n      \"apiKey\": \"your-api-key\",\n      \"database\": \"my_memory_db\",\n      \"alias\": \"生产环境\",\n      \"embeddingModel\": \"bge-large-zh\",\n      \"timeout\": 10000\n    },\n    \"bm25\": {\n      \"enabled\": true,\n      \"language\": \"zh\"\n    }\n  }\n}\n```\n\n### 配置说明\n\n#### storeBackend — 存储后端\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `storeBackend` | string | `\"sqlite\"` | 存储后端：`sqlite`（本地 SQLite + sqlite-vec）或 `tcvdb`（腾讯云向量数据库） |\n\n#### capture — 对话捕获 (L0)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用自动对话捕获 |\n| `excludeAgents` | string[] | `[]` | Agent 排除 glob 模式列表，匹配的 agent 不参与捕获/召回/调度 |\n| `l0l1RetentionDays` | number | `0` | L0/L1 本地文件保留天数。`0` = 不清理；非 0 时需 >= 3（除非开启 `allowAggressiveCleanup`） |\n| `allowAggressiveCleanup` | boolean | `false` | 是否允许 1-2 天的高风险清理配置 |\n| `cleanTime` | string | `\"03:00\"` | 每日清理执行时间（HH:mm 格式） |\n\n#### extraction — 记忆提取 (L1)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用后台记忆提取 |\n| `enableDedup` | boolean | `true` | 启用 L1 智能去重（基于向量相似度或关键词进行冲突检测） |\n| `maxMemoriesPerSession` | number | `20` | 单次 L1 提取每 session 最大记忆条数 |\n| `model` | string | *(OpenClaw 默认模型)* | 提取使用模型（格式：`provider/model`），未填写时使用 OpenClaw 默认模型 |\n\n#### pipeline — 管线调度 (L1→L2→L3)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `everyNConversations` | number | `5` | 每 N 轮对话触发一次 L1 批处理 |\n| `enableWarmup` | boolean | `true` | Warm-up 模式：新 session 从 1 轮触发开始，每次 L1 后翻倍（1→2→4→...→N） |\n| `l1IdleTimeoutSeconds` | number | `600` | 用户停止对话后多久触发 L1（秒） |\n| `l2DelayAfterL1Seconds` | number | `10` | L1 完成后延迟多久触发 L2（秒） |\n| `l2MinIntervalSeconds` | number | `900` | 同一 session 两次 L2 的最小间隔（秒） |\n| `l2MaxIntervalSeconds` | number | `3600` | 活跃 session 的 L2 最大轮询间隔（秒） |\n| `sessionActiveWindowHours` | number | `24` | 超过此时间不活跃的 session 停止 L2 轮询 |\n\n#### recall — 记忆召回\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用对话前自动召回 |\n| `maxResults` | number | `5` | 召回最大结果数 |\n| `scoreThreshold` | number | `0.3` | 最低分数阈值 |\n| `strategy` | string | `\"hybrid\"` | 搜索策略：`keyword`（关键词）、`embedding`（向量）、`hybrid`（混合 RRF 融合，推荐） |\n| `timeoutMs` | number | `5000` | 整体召回超时（毫秒）。超时后跳过记忆注入并输出 warn 日志，避免阻塞用户对话 |\n\n#### embedding — 向量搜索（仅 sqlite 后端）\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用向量搜索（若 `provider=\"none\"`，则实际会被禁用） |\n| `provider` | string | `\"none\"` | Embedding 服务提供者：`none` 表示禁用向量；其他值（如 `openai`、`deepseek`）按 OpenAI 兼容远端服务处理 |\n| `baseUrl` | string | — | API Base URL（远端模式必填） |\n| `apiKey` | string | — | API Key（远端模式必填） |\n| `model` | string | — | 模型名称（远端模式必填） |\n| `dimensions` | number | — | 向量维度（远端模式必填，需与模型匹配） |\n| `conflictRecallTopK` | number | `5` | 冲突检测时召回 Top-K 数 |\n| `maxInputChars` | number | `5000` | Embedding 输入文本最大字符数，超出时截断并打印警告日志（适合大多数模型的 token 上限） |\n| `timeoutMs` | number | `10000` | 单次 embedding API 调用超时（毫秒）。超时后该次 embedding 请求中止，不重试 |\n\n#### tcvdb — 腾讯云向量数据库（仅 storeBackend=tcvdb）\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `url` | string | — | 实例 URL（必填，如 `http://10.0.1.1:8100`） |\n| `username` | string | `\"root\"` | 账户名 |\n| `apiKey` | string | — | API Key（必填） |\n| `database` | string | — | 数据库名（必填，需唯一） |\n| `alias` | string | — | 用户友好别名（可选，记录在 manifest 中便于识别） |\n| `embeddingModel` | string | `\"bge-large-zh\"` | 服务端 embedding 模型 |\n| `timeout` | number | `10000` | 请求超时（毫秒） |\n\n#### bm25 — BM25 稀疏向量编码\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用 BM25 稀疏向量编码 |\n| `language` | string | `\"zh\"` | 分词语言：`zh`（中文 jieba）或 `en`（英文） |\n| `maxInputChars` | number | `5000` | Embedding 输入文本最大字符数，超出时截断并打印警告日志（适合大多数模型的 token 上限） |\n| `timeoutMs` | number | `10000` | 单次 embedding API 调用超时（毫秒）。超时后该次 embedding 请求中止，不重试 |\n\n#### persona — 场景归纳与用户画像 (L2/L3)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `triggerEveryN` | number | `50` | 每 N 条新记忆触发一次画像生成 |\n| `maxScenes` | number | `15` | 最大场景块数量 |\n| `backupCount` | number | `3` | 画像备份保留数量 |\n| `sceneBackupCount` | number | `10` | 场景块备份保留数量 |\n| `model` | string | *(OpenClaw 默认模型)* | L2/L3 使用模型（格式：`provider/model`），未填写时使用 OpenClaw 默认模型 |\n\n#### report — 指标上报\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `false` | 是否启用指标上报（通过 Gateway 日志输出结构化 METRIC JSON） |\n| `type` | string | `\"local\"` | 上报方式：`local` 表示通过 logger 输出结构化 JSON 日志 |\n\n## 🖥️ CLI 命令\n\n插件提供 `openclaw memory-tdai` 命令空间，支持以下子命令：\n\n### `seed` — 导入历史对话数据\n\n将历史对话 JSON 文件导入到记忆管线中，完整执行 L0→L1→L2→L3 流程。\n\n```bash\nopenclaw memory-tdai seed --input conversations.json [--output-dir ./output] [--config seed-config.json] [--yes]\n```\n\n详细用法、输入格式和配置覆盖机制请参阅 [CLI 文档](src/cli/README.md)。\n\n## 🔧 Agent 工具\n\n插件注册了两个 Agent 可调用的工具：\n\n### `tdai_memory_search`\n\n搜索用户的 L1 结构化长期记忆。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `query` | string | ✅ | 搜索查询 |\n| `limit` | number | — | 返回结果上限（默认 5，最大 20） |\n| `type` | string | — | 按记忆类型过滤：`persona` / `episodic` / `instruction` |\n| `scene` | string | — | 按场景名过滤 |\n\n### `tdai_conversation_search`\n\n搜索 L0 原始对话历史。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `query` | string | ✅ | 搜索查询 |\n| `limit` | number | — | 返回结果上限（默认 5，最大 20） |\n| `session_key` | string | — | 按 session 过滤 |\n\n## 📁 数据与日志\n\n- **数据目录**：`~/.openclaw/memory-tdai/`（自动创建）\n- **元数据**：`.metadata/manifest.json`（store 绑定、seed 运行记录）\n- **Gateway 日志**：插件运行日志通过 `[memory-tdai]` 前缀标记，可在 Gateway 日志中搜索查看\n- **配置文件**：`~/.openclaw/openclaw.json`\n\n## 📄 License\n\n[MIT](LICENSE)\n\nFile v0.3.7:scripts/migrate-sqlite-to-tcvdb/README.md\n\n# SQLite → 腾讯云向量数据库迁移工具\n\n离线迁移工具，用于将 memory-tdai 的数据从本地 SQLite 存储迁移到腾讯云向量数据库（TCVDB）。\n\n## 前置条件\n\n- Node.js >= 22.16.0\n- 插件已通过 `openclaw plugins install` 安装\n- 迁移脚本已编译（见下方）\n\n## 编译\n\n迁移脚本使用 TypeScript 编写，运行前需要先编译：\n\n```bash\nnpm run build:migrate-sqlite-to-vdb\n```\n\n编译产物输出到 `scripts/migrate-sqlite-to-tcvdb/dist/`，可直接用 Node 运行。\n\n## 使用方法\n\n```bash\n# 预检模式（仅查看源数据，不执行写入）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --dry-run\n\n# 正式迁移\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n### 更多示例\n\n```bash\n# 直接传入 API Key（不通过环境变量）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key 'your-api-key-here' \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n```bash\n# 指定自定义 SQLite 路径（数据库不在默认 vectors.db 位置时）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --sqlite-path /backup/2026-04/vectors-snapshot.db \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n```bash\n# 只迁移 L1 记忆层（跳过 L0 原始消息和 Profile）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --layers l1 \\\n  --yes\n```\n\n```bash\n# 只迁移 L0 和 L1（不迁移 Profile）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --layers l0,l1 \\\n  --yes\n```\n\n```bash\n# 英文语料场景：使用英文 BM25 分词\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-en-v1.5 \\\n  --bm25-language en \\\n  --yes\n```\n\n```bash\n# 禁用 BM25 稀疏向量（仅使用密集向量检索）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --no-bm25-enabled \\\n  --yes\n```\n\n```bash\n# 仅迁移数据，不自动更新 openclaw.json 和 manifest（手动管理配置）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --no-apply-config \\\n  --no-rewrite-manifest \\\n  --yes\n```\n\n```bash\n# 追加迁移：允许目标库已有数据，跳过非空检查\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --no-fail-if-target-nonempty \\\n  --no-verify-counts \\\n  --yes\n```\n\n```bash\n# 输出迁移摘要到 JSON 文件（适合 CI/自动化流水线）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --summary-json-path ./migration-report.json \\\n  --job-id \"migrate-2026-04-13\" \\\n  --yes\n```\n\n```bash\n# 设置自定义超时和别名\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://10.0.1.50:80 \\\n  --tcvdb-username admin \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --tcvdb-alias \"生产环境-主库\" \\\n  --tcvdb-timeout-ms 30000 \\\n  --yes\n```\n\n## 参数说明\n\n| 参数 | 必填 | 默认值 | 说明 |\n|---|---|---|---|\n| `--plugin-data-dir` | 是 | — | 插件数据目录路径 |\n| `--openclaw-config-path` | 是 | — | `openclaw.json` 配置文件路径 |\n| `--sqlite-path` | 否 | `<plugin-data-dir>/vectors.db` | SQLite 数据库文件路径（默认取数据目录下的 `vectors.db`） |\n| `--plugin-id` | 否 | `memory-tencentdb` | 写入配置时使用的插件 ID |\n| `--tcvdb-url` | 是 | — | TCVDB 服务地址 |\n| `--tcvdb-username` | 是 | — | TCVDB 用户名 |\n| `--tcvdb-api-key` | * | — | TCVDB API 密钥（明文） |\n| `--tcvdb-api-key-env` | * | — | 包含 API 密钥的环境变量名 |\n| `--tcvdb-database` | 是 | — | TCVDB 数据库名 |\n| `--tcvdb-embedding-model` | 是 | — | Embedding 模型名称 |\n| `--tcvdb-alias` | 否 | `\"\"` | 用户自定义别名 |\n| `--tcvdb-timeout-ms` | 否 | `10000` | 请求超时时间（毫秒） |\n| `--layers` | 否 | `l0,l1,l2,l3` | 要迁移的层（逗号分隔） |\n| `--dry-run` | 否 | `false` | 仅预览，不执行写入 |\n| `--yes` | 否 | `false` | 跳过交互确认 |\n| `--apply-config` | 否 | `true` | 迁移后更新 openclaw.json |\n| `--config-backup` | 否 | `true` | 写入配置前先备份原配置文件 |\n| `--rewrite-manifest` | 否 | `true` | 将 manifest.json 更新为 tcvdb |\n| `--fail-if-target-nonempty` | 否 | `true` | 目标库非空时中止 |\n| `--verify-counts` | 否 | `true` | 迁移后校验记录数 |\n| `--summary-json-path` | 否 | — | 将迁移摘要写入此文件 |\n| `--job-id` | 否 | — | 迁移任务 ID（用于追踪） |\n| `--bm25-enabled` | 否 | `true` | 启用 BM25 稀疏向量 |\n| `--bm25-language` | 否 | `zh` | BM25 语言（`zh` 或 `en`） |\n\n\\* `--tcvdb-api-key` 和 `--tcvdb-api-key-env` 二选一，必须提供其中一个。\n\n## 目录结构\n\n```\nscripts/migrate-sqlite-to-tcvdb/\n├── cli-entry.ts          # CLI 入口\n├── sqlite-to-tcvdb.ts    # 迁移核心逻辑（参数解析、预检、数据迁移）\n├── config-write.ts       # OpenClaw 配置更新（JSON5，自包含）\n├── manifest-write.ts     # Manifest 重写\n├── *.test.ts             # 就近放置的测试文件\n├── tsconfig.json         # 迁移脚本编译配置\n├── dist/                 # 编译产物（已 gitignore）\n└── README.md             # 本文件\n\nbin/migrate-sqlite-to-tcvdb.mjs     # 极薄 bin 包装 → dist/\n```\n\n迁移脚本通过 `../../src/` 引用存储实现（VectorStore、TcvdbMemoryStore 等），但**不依赖 `openclaw/plugin-sdk`**。配置写回直接使用 `json5`。\n\nFile v0.3.7:src/cli/README.md\n\n# memory-tdai CLI\n\n`openclaw memory-tdai` 命令空间，提供离线数据管理工具。\n\n## seed — 导入历史对话数据\n\n将历史对话 JSON 文件导入到记忆管线中，完整执行 L0→L1→L2→L3 流程。适用于：\n\n- 将已有对话数据灌入记忆系统\n- 批量测试记忆提取效果\n- 迁移/恢复记忆数据\n\n### 用法\n\n```bash\nopenclaw memory-tdai seed --input <file> [options]\n```\n\n### 参数\n\n| 参数 | 必填 | 说明 |\n|------|------|------|\n| `--input <file>` | ✅ | 输入 JSON 文件路径 |\n| `--output-dir <dir>` | — | 输出目录（默认自动生成带时间戳的目录） |\n| `--session-key <key>` | — | 回退 session key（当输入数据缺少时使用） |\n| `--config <file>` | — | 配置覆盖文件（JSON，与 openclaw.json 插件配置深度合并） |\n| `--strict-round-role` | — | 严格校验每轮对话必须包含 user 和 assistant 消息 |\n| `--yes` | — | 跳过交互确认（如时间戳自动填充确认） |\n\n### 示例\n\n```bash\n# 基本用法\nopenclaw memory-tdai seed --input conversations.json\n\n# 指定输出目录\nopenclaw memory-tdai seed --input data.json --output-dir ./seed-output\n\n# 使用自定义配置覆盖（如调整 pipeline 参数）\nopenclaw memory-tdai seed --input data.json --config seed-config.json\n\n# 跳过所有确认\nopenclaw memory-tdai seed --input data.json --yes\n\n# 严格模式 + 自定义配置\nopenclaw memory-tdai seed --input data.json --config seed-config.json --strict-round-role --yes\n```\n\n### 输入文件格式\n\n支持两种 JSON 格式：\n\n#### Format A：对象包装\n\n```json\n{\n  \"sessions\": [\n    {\n      \"sessionKey\": \"user-alice\",\n      \"sessionId\": \"conv-001\",\n      \"conversations\": [\n        [\n          { \"role\": \"user\", \"content\": \"你好\", \"timestamp\": 1711929600000 },\n          { \"role\": \"assistant\", \"content\": \"你好！有什么可以帮你？\", \"timestamp\": 1711929601000 }\n        ],\n        [\n          { \"role\": \"user\", \"content\": \"今天天气怎么样？\" },\n          { \"role\": \"assistant\", \"content\": \"今天晴天，适合出门。\" }\n        ]\n      ]\n    }\n  ]\n}\n```\n\n#### Format B：顶层数组\n\n```json\n[\n  {\n    \"sessionKey\": \"user-alice\",\n    \"conversations\": [\n      [\n        { \"role\": \"user\", \"content\": \"你好\" },\n        { \"role\": \"assistant\", \"content\": \"你好！\" }\n      ]\n    ]\n  }\n]\n```\n\n#### 字段说明\n\n| 字段 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `sessionKey` | string | ✅ | Session 标识（如用户 ID、频道名） |\n| `sessionId` | string | — | 会话实例 ID（同一 sessionKey 下可有多个 sessionId） |\n| `conversations` | message[][] | ✅ | 对话轮次数组，每个轮次是一组消息 |\n| `role` | string | ✅ | 消息角色：`user` 或 `assistant` |\n| `content` | string | ✅ | 消息内容 |\n| `timestamp` | number \\| string | — | 时间戳：epoch 毫秒或 ISO 8601 字符串。缺失时 seed 会提示自动填充 |\n\n### 配置覆盖\n\n`--config` 接受一个 JSON 文件，与 `openclaw.json` 中的插件配置**两级深度合并**：\n\n- 顶层 key 如果两边都是对象 → 浅合并（保留 base 中未覆盖的字段）\n- 其他类型 → 直接覆盖\n\n常见场景：seed 时使用更激进的 pipeline 参数以加速处理：\n\n```json\n{\n  \"pipeline\": {\n    \"everyNConversations\": 3,\n    \"enableWarmup\": false,\n    \"l1IdleTimeoutSeconds\": 2,\n    \"l2DelayAfterL1Seconds\": 1,\n    \"l2MinIntervalSeconds\": 1,\n    \"l2MaxIntervalSeconds\": 10\n  }\n}\n```\n\n如果需要 seed 到独立的 TCVDB 数据库：\n\n```json\n{\n  \"storeBackend\": \"tcvdb\",\n  \"tcvdb\": {\n    \"database\": \"my_seed_test_db\"\n  },\n  \"pipeline\": {\n    \"everyNConversations\": 3,\n    \"enableWarmup\": false,\n    \"l1IdleTimeoutSeconds\": 2\n  }\n}\n```\n\n### 输出目录结构\n\n```\n<output-dir>/\n├── conversations/          — L0 JSONL 文件\n├── records/                — L1 JSONL 文件\n├── scene_blocks/           — L2 场景块\n├── vectors.db              — SQLite 向量数据库（仅 sqlite 后端）\n├── .metadata/\n│   ├── manifest.json       — 元数据（store 绑定 + seed 运行记录）\n│   └── checkpoint.json     — 管线进度\n└── .backup/                — 滚动备份\n```\n\nSeed 完成后，`manifest.json` 会记录本次运行信息：\n\n```json\n{\n  \"version\": 1,\n  \"createdAt\": \"2026-04-01T22:00:00.000Z\",\n  \"store\": {\n    \"type\": \"sqlite\",\n    \"sqlite\": { \"path\": \"vectors.db\" }\n  },\n  \"seed\": {\n    \"inputFile\": \"conversations.json\",\n    \"sessions\": 3,\n    \"rounds\": 42,\n    \"messages\": 128,\n    \"startedAt\": \"2026-04-01T22:00:00.000Z\",\n    \"completedAt\": \"2026-04-01T22:05:30.000Z\"\n  }\n}\n```\n\nFile v0.3.7:_meta.json\n\n{\n  \"ownerId\": \"kn73z7zhz92tv6skpnmpy5pdfh86j68x\",\n  \"slug\": \"memory-tencentdb\",\n  \"version\": \"0.3.7\",\n  \"publishedAt\": 1780888143780\n}\n\nFile v0.3.7:scripts/README.memory-tencentdb-ctl.md\n\n# memory-tencentdb-ctl.sh — memory_tencentdb (TDAI) 运维脚本\n\n> 配合 [`install_hermes_memory_tencentdb.sh`](./install_hermes_memory_tencentdb.sh) 使用。\n> 先跑安装脚本部署好插件 + Node 依赖，之后日常的启停 / 配置全部通过 `memory-tencentdb-ctl.sh` 完成。\n\n## 1. 运行模式\n\n脚本有两种模式，**默认是独立模式**，完全不触碰 `~/.hermes`：\n\n| 模式 | 激活方式 | 做什么 | 不做什么 |\n|---|---|---|---|\n| `standalone`（默认） | 无需任何参数 | 启停 Gateway；写 `$TDAI_DATA_DIR/tdai-gateway.json`；日志落 `$TDAI_DATA_DIR/logs/` | 不写 `$HERMES_HOME/env.d/`，不改 `$HERMES_HOME/config.yaml`，不读 hermes 相关 env |\n| `hermes` | 命令行追加 `--hermes`，或环境 `MEMORY_TENCENTDB_MODE=hermes` | standalone 的全部 + `config llm` 同步写 `$HERMES_HOME/env.d/memory-tencentdb-llm.sh`；日志落 `$HERMES_HOME/logs/memory_tencentdb/`；开放 `enable-hermes-memory` 子命令 | — |\n\n> **为什么 hermes 模式要多写 env 文件？**\n> 因为 hermes 进程会托管式地把 Gateway 以子进程拉起来（supervisor 用 `os.environ.copy()` 传环境），此时 Gateway 读不到 `tdai-gateway.json` 所在的 shell 环境，必须通过 `$HERMES_HOME/env.d/*.sh` 让 hermes 自身 `source` 才能把凭据传进去。独立模式下 Gateway 自己读 JSON，无此需要。\n\n## 2. 路径\n\n> **路径变量约定**：本节及后续示例统一用 `$HERMES_HOME` 指代 hermes 的家目录，**默认 `~/.hermes`**，但你可以通过环境变量覆盖（例如 `export HERMES_HOME=/srv/hermes`），脚本和 hermes 自身都遵守这个变量。\n>\n> 自 0.4.x 起，所有 tdai 相关数据/代码默认收纳到统一根目录 `$MEMORY_TENCENTDB_ROOT`（默认 `~/.memory-tencentdb`）之下：\n>\n> - `$TDAI_INSTALL_DIR` 默认 `$MEMORY_TENCENTDB_ROOT/tdai-memory-openclaw-plugin`（即 `~/.memory-tencentdb/tdai-memory-openclaw-plugin`）\n> - `$TDAI_DATA_DIR` 默认 `$MEMORY_TENCENTDB_ROOT/memory-tdai`（即 `~/.memory-tencentdb/memory-tdai`）\n>\n> 下文出现这些变量时**先 `export` 一份覆盖**，再跑命令即可全局生效。\n> 旧版本使用 `~/tdai-memory-openclaw-plugin` 与 `~/memory-tdai`；`install_hermes_memory_tencentdb.sh` 在升级时会自动迁移这两个旧目录到新位置。\n\n| 路径 | standalone | hermes | 作用 |\n|---|---|---|---|\n| `$TDAI_INSTALL_DIR` | ✅ | ✅ | 插件源码 + `node_modules` + `src/gateway/server.ts` |\n| `$TDAI_DATA_DIR/tdai-gateway.json` | ✅ | ✅ | Gateway 主配置：`llm` / `memory.embedding` / `memory.tcvdb` / `memory.storeBackend`，权限 `0600` |\n| `$TDAI_DATA_DIR/logs/` | ✅ 日志 | — | `gateway.stdout.log` / `gateway.stderr.log` / `gateway.pid` |\n| `$HERMES_HOME/logs/memory_tencentdb/` | — | ✅ 日志 | 同上，换目录 |\n| `$HERMES_HOME/env.d/memory-tencentdb-llm.sh` | — | ✅ | hermes 启动前 `source`，给 supervisor 托管的 Gateway 子进程注入 LLM 凭据 |\n| `$HERMES_HOME/config.yaml` | — | ✅ | `enable-hermes-memory` 修改其 `memory.provider` |\n| Gateway 监听 | `127.0.0.1:8420` | `127.0.0.1:8420` | 可被 `MEMORY_TENCENTDB_GATEWAY_HOST/PORT` 覆盖 |\n\n所有路径都能用同名环境变量覆盖（再次列出便于对照）：`MEMORY_TENCENTDB_ROOT`（默认 `~/.memory-tencentdb`）、`TDAI_INSTALL_DIR`（默认 `$MEMORY_TENCENTDB_ROOT/tdai-memory-openclaw-plugin`）、`TDAI_DATA_DIR`（默认 `$MEMORY_TENCENTDB_ROOT/memory-tdai`）、`HERMES_HOME`（默认 `~/.hermes`）、`MEMORY_TENCENTDB_LOG_DIR`、`MEMORY_TENCENTDB_GATEWAY_HOST/PORT`。\n\n依赖：`bash`、`python3`、`node >= 22`、`npx`、`lsof` 或 `ss`。\n\n## 3. 安装 & 调用\n\n脚本随 npm 包发布到 `node_modules/.../scripts/` 下，但**没有**注册为 `bin` 命令。要用全局命令名调用，必须自己做一次软链。\n\n### 3.1 从 npm 包里直接运行（无需任何配置）\n\n```bash\nnpm install @tencentdb-agent-memory/memory-tencentdb\n\n# 项目内安装，路径可由 npm root 动态算出\n\"$(npm root)/@tencentdb-agent-memory/memory-tencentdb/scripts/memory-tencentdb-ctl.sh\" --help\n\n# 全局安装则用 npm root -g\n\"$(npm root -g)/@tencentdb-agent-memory/memory-tencentdb/scripts/memory-tencentdb-ctl.sh\" --help\n```\n\n`npm root` / `npm root -g` 会在所有包管理器（npm / pnpm / yarn）和不同的 prefix 配置下返回正确目录，避免硬编码 `node_modules/` 路径。适合一次性、临时使用的场景。\n\n### 3.2 软链到 PATH（推荐给运维 / 长期使用）\n\n不论脚本来源（git clone 出来的仓库 / `npm install` 装的包 / 自定义部署目录），先把脚本路径**算出来存到一个变量里**，再统一做软链。这样无需关心你把仓库放在 `~/code/`、`/opt/`、还是别的什么地方。\n\n```bash\n# 第一步：定位 memory-tencentdb-ctl.sh 的真实路径（任选一种来源）\n\n# (a) 从 git 仓库（在仓库根目录或任意子目录里执行）\nSCRIPT=\"$(git -C \"$(git rev-parse --show-toplevel)\" ls-files | \\\n          grep -E 'scripts/memory-tencentdb-ctl\\.sh$' | head -1)\"\nSCRIPT=\"$(git rev-parse --show-toplevel)/$SCRIPT\"\n\n# (b) 从已 npm 全局安装的包\nSCRIPT=\"$(npm root -g)/@tencentdb-agent-memory/memory-tencentdb/scripts/memory-tencentdb-ctl.sh\"\n\n# (c) 从项目本地的 node_modules\nSCRIPT=\"$(npm root)/@tencentdb-agent-memory/memory-tencentdb/scripts/memory-tencentdb-ctl.sh\"\n\n# (d) 完全手写绝对路径（如部署到非标准位置）\nSCRIPT=\"/opt/tdai/scripts/memory-tencentdb-ctl.sh\"\n\n# 第二步：验证路径正确，然后软链\ntest -f \"$SCRIPT\" && echo \"ok: $SCRIPT\" || { echo \"not found\"; exit 1; }\nchmod +x \"$SCRIPT\"\nsudo ln -sf \"$SCRIPT\" /usr/local/bin/memory-tencentdb-ctl\n\n# 同样的办法把 install_hermes_memory_tencentdb.sh 链接成 install-memory-tencentdb（可选）\nINSTALL_SCRIPT=\"$(dirname \"$SCRIPT\")/install_hermes_memory_tencentdb.sh\"\ntest -f \"$INSTALL_SCRIPT\" && {\n  chmod +x \"$INSTALL_SCRIPT\"\n  sudo ln -sf \"$INSTALL_SCRIPT\" /usr/local/bin/install-memory-tencentdb\n}\n```\n\n之后直接 `memory-tencentdb-ctl …` / `install-memory-tencentdb …`。\n\n> **为什么不直接用 `npm bin` 注册？** 这两个脚本是运维工具而不是包的核心 API，主仓库希望用户**显式**完成 PATH 注册（避免无意中污染全局命令空间，并避免 npm 卸载时静默移除运维入口）。\n\n## 4. 生命周期管理（两种模式通用）\n\n```bash\nmemory-tencentdb-ctl start        # 若 :8420 已占用会直接返回；否则后台 spawn，等待 /health 通过\nmemory-tencentdb-ctl stop         # 先 SIGTERM，5s 内未退则 SIGKILL\nmemory-tencentdb-ctl restart\nmemory-tencentdb-ctl status       # 打印模式、端口、data/log 路径、进程状态\nmemory-tencentdb-ctl health       # GET /health，纯 python3 实现，不要求 curl\nmemory-tencentdb-ctl logs         # tail -f stdout + stderr\nmemory-tencentdb-ctl logs err 500 # 只看 stderr 最近 500 行\n```\n\n启动命令解析顺序：\n\n1. 环境变量 `MEMORY_TENCENTDB_GATEWAY_CMD`（`install_hermes_memory_tencentdb.sh` 写入 `/etc/profile.d/memory-tencentdb-env.sh` 的那条）。\n2. 回退到 `sh -c 'cd $TDAI_INSTALL_DIR && exec npx tsx src/gateway/server.ts'`。\n\n启动时会自动 `source` 的环境文件：\n\n- 两种模式：`/etc/profile.d/memory-tencentdb-env.sh`\n- 仅 hermes 模式：`/etc/profile.d/hermes-env.sh` 以及 `$HERMES_HOME/env.d/*.sh`\n\n## 5. 配置 LLM / Embedding / VDB\n\n三类凭据统一落到 `$TDAI_DATA_DIR/tdai-gateway.json`（`0600`，原子写）。**`config llm` 在 `--hermes` 模式下会额外写一份 env 文件**；Embedding / VDB 从不写 env。\n\n### 5.1 LLM\n\n```bash\n# standalone 模式：只写 tdai-gateway.json\nmemory-tencentdb-ctl config llm \\\n  --api-key   \"sk-xxxxxxxxxxxx\" \\\n  --base-url  \"https://api.openai.com/v1\" \\\n  --model     \"gpt-4o\" \\\n  --restart\n\n# hermes 模式：tdai-gateway.json + $HERMES_HOME/env.d/memory-tencentdb-llm.sh\nmemory-tencentdb-ctl --hermes config llm \\\n  --api-key   \"sk-xxxxxxxxxxxx\" \\\n  --base-url  \"https://api.openai.com/v1\" \\\n  --model     \"gpt-4o\" \\\n  --restart\n```\n\n- JSON 写入点：`$.llm.{baseUrl, apiKey, model}`。\n- env 文件写入（仅 `--hermes`）：`TDAI_LLM_*` 及 `MEMORY_TENCENTDB_LLM_*` 别名（Python provider 的 `get_config_schema()` 会读后者）。\n\n### 5.2 Embedding\n\n默认关闭（`provider=none`）。启用远端 OpenAI 兼容服务：\n\n```bash\nmemory-tencentdb-ctl config embedding \\\n  --provider   openai \\\n  --api-key    \"sk-xxxx\" \\\n  --base-url   \"https://api.openai.com/v1\" \\\n  --model      \"text-embedding-3-small\" \\\n  --dimensions 1536 \\\n  --restart\n\n# 关闭 embedding（退化为 BM25/关键词召回）\nmemory-tencentdb-ctl config embedding --provider none --restart\n```\n\n- JSON 写入点：`$.memory.embedding.{provider, baseUrl, apiKey, model, dimensions, enabled, proxyUrl?}`。\n- `qclaw` provider 额外要求 `--proxy-url`。\n- 校验规则与 `src/config.ts` 的 `parseConfig()` 对齐：`dimensions` 为正整数，非 `none` 必须带 `apiKey/baseUrl/model/dimensions`；缺项直接报错不写半残 JSON。\n\n### 5.3 VectorDB（Tencent Cloud VDB / tcvdb）\n\n```bash\nmemory-tencentdb-ctl config vdb \\\n  --url       \"http://xxx-vdb.tencentclb.com:8100\" \\\n  --username  root \\\n  --api-key   \"YOUR-VDB-API-KEY\" \\\n  --database  \"openclaw_memory\" \\\n  --alias     \"primary\" \\\n  --embedding-model \"bge-large-zh\" \\\n  --ca-pem    \"/etc/ssl/vdb-ca.pem\" \\\n  --restart\n```\n\n- JSON 写入点：`$.memory.tcvdb.{url, username, apiKey, database, alias?, caPemPath?, embeddingModel?}`。\n- 默认同时把 `$.memory.storeBackend` 切到 `\"tcvdb\"`；只想预埋配置先不切，加 `--no-set-backend`。\n- `--ca-pem` 只写路径不复制文件；脚本会校验可读性。\n\n### 5.4 退回本地 SQLite（关闭 VDB 后端）\n\n```bash\n# 默认：保留 memory.tcvdb 凭据（方便随时再切回去），仅把 storeBackend 改回 sqlite\nmemory-tencentdb-ctl config vdb-off --restart\n\n# 同时把腾讯云 VDB 的 url / apiKey / database 等凭据从 JSON 中清掉\nmemory-tencentdb-ctl config vdb-off --purge-creds --restart\n```\n\n- JSON 写入点：把 `$.memory.storeBackend` 设为 `\"sqlite\"`；`--purge-creds` 时额外删除整段 `$.memory.tcvdb`。\n- `$.llm` / `$.memory.embedding` 等其它顶级段**完全保留**，hermes 侧 `memory.provider` **不动**（仍是 `memory_tencentdb`，只是它内部存储退回 sqlite）。\n- 配置文件不存在时给出 `warn` 并写入仅含 `{\"memory\":{\"storeBackend\":\"sqlite\"}}` 的最小配置。\n- 与 `config vdb` 完全镜像：可与 `--dry-run` / `--restart` 组合使用。\n\n### 5.5 查看当前配置\n\n```bash\nmemory-tencentdb-ctl config show\n```\n\n- 打印 `tdai-gateway.json`，`apiKey`/`password`/`token` 字段自动脱敏为 `<redacted:NN chars>`。\n- hermes 模式下额外打印 `$HERMES_HOME/env.d/memory-tencentdb-*.sh`（API key 也会脱敏），可直接贴工单。\n\n## 6. 打通 hermes（仅 `--hermes` 模式）\n\n```bash\nmemory-tencentdb-ctl --hermes enable-hermes-memory\n```\n\n幂等：把 `$HERMES_HOME/config.yaml` 的 `memory:` 段的 `provider:` 改成 `memory_tencentdb`（不存在则新增整段）。改完后重启 hermes：\n\n```bash\nsource \"$HERMES_HOME/env.d/memory-tencentdb-llm.sh\"\npkill -f hermes-agent || true\nhermes\n```\n\n> **关于写入策略**：脚本采用\"格式保真\"双路径，**永不重写整个 YAML**：\n>\n> 1. **首选**：检测到 [`ruamel.yaml`](https://yaml.readthedocs.io/) 时走 round-trip，完整保留注释、键序、引号、缩进风格（推荐 `pip install --user ruamel.yaml` 享受最佳保真度，**非必装**）；\n> 2. **降级**：未安装 ruamel 时走最小化原位行编辑——只重写 `provider:` 那一行，缩进直接从同段已有兄弟键的前缀**逐字符拷贝**（零猜测、零格式破坏）；\n> 3. 若 `memory:` 段不存在，则在文件末尾追加最小段，缩进从文档其它顶级段的子键拓印。\n>\n> 实测对真实 `~/.hermes/config.yaml` 做 byte-for-byte diff，除 `provider` 值本身外其余字节完全一致。\n\n非 hermes 模式下调用该命令会直接报错退出。\n\n> 想反过来\"保留 hermes provider 不变，仅让 TDAI 内部存储退回 sqlite\"，用 §5.4 的 `config vdb-off` 即可（不需要也**不要**改 hermes 的 `memory.provider`）。\n\n## 7. 典型使用流程\n\n### 场景 A：Gateway 独立部署（不使用 hermes）\n\n```bash\n# 1) 安装\n#    INSTALL_SCRIPT 的取值方式见上文 3.2 节（git rev-parse / npm root / 手填均可）\n#    例如从 git 仓库根：INSTALL_SCRIPT=\"$(git rev-parse --show-toplevel)/scripts/install_hermes_memory_tencentdb.sh\"\n#         从 npm 全局：  INSTALL_SCRIPT=\"$(npm root -g)/@tencentdb-agent-memory/memory-tencentdb/scripts/install_hermes_memory_tencentdb.sh\"\nbash \"$INSTALL_SCRIPT\"\n\n# 2) 只配 Gateway 所需凭据\nmemory-tencentdb-ctl config llm       --api-key \"sk-...\" --base-url \"https://api.openai.com/v1\" --model gpt-4o\nmemory-tencentdb-ctl config embedding --provider openai --api-key \"sk-...\" --base-url \"https://api.openai.com/v1\" \\\n                                      --model text-embedding-3-small --dimensions 1536\nmemory-tencentdb-ctl config vdb       --url \"http://xxx:8100\" --api-key \"...\" --database openclaw_memory\n\n# 3) 启动 + 自检\nmemory-tencentdb-ctl start\nmemory-tencentdb-ctl status\nmemory-tencentdb-ctl health      # 预期: {\"status\":\"ok\",...}\n```\n\n### 场景 B：集成 hermes\n\n```bash\n# 1) 安装（与场景 A 相同；INSTALL_SCRIPT 由上文 3.2 节算出）\nbash \"$INSTALL_SCRIPT\"\n\n# 2) 全程加 --hermes（或 export MEMORY_TENCENTDB_MODE=hermes 一次）\nmemory-tencentdb-ctl --hermes config llm --api-key \"sk-...\" --base-url \"https://api.openai.com/v1\" --model gpt-4o\nmemory-tencentdb-ctl --hermes config embedding --provider openai --api-key \"sk-...\" \\\n                                               --base-url \"https://api.openai.com/v1\" \\\n                                               --model text-embedding-3-small --dimensions 1536\nmemory-tencentdb-ctl --hermes config vdb --url \"http://xxx:8100\" --api-key \"...\" --database openclaw_memory\n\n# 3) 启动 Gateway（通常由 hermes supervisor 托管，这里是手动兜底）\nmemory-tencentdb-ctl --hermes start\nmemory-tencentdb-ctl --hermes status\n\n# 4) 在 hermes config 里启用 provider，并重启 hermes\nmemory-tencentdb-ctl --hermes enable-hermes-memory\nsource \"$HERMES_HOME/env.d/memory-tencentdb-llm.sh\"\npkill -f hermes-agent ; hermes\n```\n\n如果嫌 `--hermes` 每次都要带，可以：\n\n```bash\nexport MEMORY_TENCENTDB_MODE=hermes\n```\n\n之后所有调用自动切到 hermes 模式，命令行无需再加 `--hermes`。\n\n### 场景 C：临时把 TDAI 的存储退回 sqlite（保留 hermes 集成）\n\n适用于 VDB 不可达 / 排障 / 离线开发等场景：希望 hermes 端 `memory.provider` 仍是 `memory_tencentdb`，但让 Gateway 改用本地 SQLite 落盘。\n\n```bash\n# (A) 默认：保留 memory.tcvdb 凭据，仅把 storeBackend 切回 sqlite\nmemory-tencentdb-ctl config vdb-off --restart\n\n# (B) 排障结束想切回 vdb：当前需要重新跑一次 config vdb（必填项需重新提供，\n#     即使 JSON 里凭据还在；脚本是基于必填校验的\"重新声明\"语义，不是 toggle）\nmemory-tencentdb-ctl config vdb \\\n  --url \"http://xxx-vdb.tencentclb.com:8100\" \\\n  --api-key \"<你的 KEY>\" \\\n  --database \"openclaw_memory\" \\\n  --restart\n\n# (C) 彻底放弃 vdb：清掉凭据\nmemory-tencentdb-ctl config vdb-off --purge-creds --restart\n```\n\n> 之所以 (B) 不提供\"零参数 vdb-on\"，是因为原 `config vdb` 子命令把 `--url/--api-key/--database` 设为强校验，避免用户拼装出半残配置；如果你希望把\"已存的凭据重新激活\"也做成单命令，告诉维护者补一个 `config vdb-on` 即可（实现方式与 `vdb-off` 完全镜像）。\n\n> **不要**为了\"切回 sqlite\"去改 `~/.hermes/config.yaml` 的 `memory.provider`！hermes 看到的依然是 `memory_tencentdb` provider，存储后端切换是 Gateway 内部的事，对 hermes 完全透明。\n\n## 8. 全局选项 & 调试技巧\n\n- 所有写操作支持 `--dry-run`（放在命令最前），会打印将要写入的内容但不落盘：\n  ```bash\n  memory-tencentdb-ctl --dry-run config llm --api-key k --base-url https://x --model m\n  ```\n- 敏感文件权限一律 `0600`；`env.d/memory-tencentdb-llm.sh` 含明文 API key，**不要** commit。\n- 启动失败：`memory-tencentdb-ctl logs err 200` 查看 stderr；手动前台跑一遍更容易看到报错：\n  ```bash\n  cd \"$TDAI_INSTALL_DIR\" && npx tsx src/gateway/server.ts\n  ```\n- 端口冲突：`MEMORY_TENCENTDB_GATEWAY_PORT=18420 memory-tencentdb-ctl restart`。\n- 验证 hermes 有没有吃到新 env（hermes 模式）：\n  ```bash\n  tr '\\0' '\\n' < /proc/$(pgrep -n hermes-agent)/environ | grep -E 'TDAI_|MEMORY_TENCENTDB_'\n  ```\n\n## 9. 退出码\n\n| 码 | 含义 |\n|---|---|\n| 0 | 成功 |\n| 1 | 参数错误 / 业务校验失败（如 `--base-url` 非 http(s)；在 standalone 下调 hermes 专属命令） |\n| 2 | 写盘失败（磁盘满、权限不足等） |\n| 127 | 依赖缺失（`python3` / `node` / `npx`） |\n\n---\n\n要封装成 systemd unit，基于 `memory-tencentdb-ctl start` / `memory-tencentdb-ctl stop` 写 `Type=forking` 的 service 即可（Gateway 是无状态 HTTP sidecar，不依赖 systemd readiness 协议）。\n\nFile v0.3.7:CHANGELOG.md\n\n# Changelog\n\n本文件记录 `@tencentdb-agent-memory/memory-tencentdb` 插件的所有显著变更，格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)，版本号遵循 [Semantic Versioning](https://semver.org/)。\n\n---\n\n## [0.3.5] - 2026-05-15\n\n### 🐛 修复\n\n- **兼容 OpenClaw v2026.5.7 zod v4 子路径**：显式声明 `zod@^4.4.3` 依赖，解决 `@ai-sdk/provider-utils@4.x` 需要 `zod/v4` 子路径导出但宿主环境可能 hoist zod@3.x 引发 `Cannot find module zod/v4` 的运行时错误。\n\n### ✨ 改进\n\n- **L1→L2 延迟从 90s 降至 10s**：`l2DelayAfterL1Seconds` 默认值 90→10，冷启动用户不再需要等待 ~90s 才能看到 L2 场景提取结果，体感更及时。\n\n### 📖 文档\n\n- README 新增 Docker Quick Start 章节，说明模型 URL/Name 环境变量配置方式。\n\n---\n\n## [0.3.4] - 2026-05-12\n\n### 🐛 修复\n\n- **兼容 OpenClaw v2026.4.7 以下版本 L1 抽取空输出**：旧宿主不支持 `systemPromptOverride`，通过 `extraSystemPrompt` 回退注入系统提示，确保 LLM 按数据提取助手身份工作。\n- **TCVDB hybrid 召回冗余双重 HTTP 调用**：`auto-recall` 对 TCVDB 发两次相同的 `hybridSearch` 请求（且 keyword 路径将 FTS5 OR 表达式错误传入 BM25 编码器）。新增 `nativeHybridSearch` 短路，TCVDB 单次调用即可完成 dense + sparse + RRF，recall 耗时减半（~50-120ms）。\n- **L2 parser 对齐 Go 后端**：增加 mermaid fallback，修复 `first{...last}` JSON 提取逻辑。\n\n### ✨ 改进\n\n- **VDB HTTP 请求级计时**：`tcvdb-client` 每次请求打一条 info 计时日志（`/document/hybridSearch 85ms`），retry/失败细节保持 debug 级别。\n- **启动路径误导性日志降级为 DEBUG**：store manifest 不一致、sqlite schema migration、profile-sync MD5 mismatch 等正常场景不再打 warn/info，避免 AI 误判。\n- **L1 提取调试日志**：新增 `[l1-debug]` 系列（RESOLVE / INVOKE / RESULT / EMPTY_DUMP / ENTRY / NO_JSON），方便定位 LLM 调用链问题。\n\n### 🔧 兼容性适配\n\n- **OC 2026.4.23 Zod schema 兼容 patch 脚本**（`scripts/bugfix-20260423/`）：一键修复 `allowConversationAccess` 被 `.strict()` 拒绝的问题，含轻量版脚本、全自动脚本、手动 SOP 文档。\n- Offload 日志去掉 `Backend` 前缀，默认超时为 120s。\n\n### 📦 新功能\n\n- **Offload Local Mode**：支持本地模式运行 offload（不依赖远端后端）。\n- **Docker 一体化镜像**（`Dockerfile.hermes`）：单容器捆绑 Hermes Agent + memory_tencentdb 插件 + TDAI Memory Gateway，统一 `MODEL_*` 环境变量驱动。\n\n### ✅ 测试\n\n- 修复 `fault-injection` FI-05 mock config 缺 `embedding` 字段\n- 修复 `cli.test` dependencies 断言适配新增依赖\n- 跳过 `patch-effectiveness` 已删除的 `install-plugin.sh` 测试\n\n---\n\n## [0.3.3] - 2026-05-08\n\n### 🐛 修复\n\n- **加固 hook-policy 版本决策逻辑**：仅当宿主版本为严格 `x.y.z` 语义化版本、且 `>= 2026.4.24` 时才自动写入 `hooks.allowConversationAccess`；无法解析（如 `unknown`、beta、snapshot 等非标准版本）时一律跳过，避免对旧版本或非预期版本误写配置导致启动失败。\n- hook-policy 关键路径补充 debug 日志（原始版本串、解析后版本、最小要求版本、是否 patch 的决策），方便线上排查。\n\n### ✅ 测试\n\n- 新增 `src/utils/ensure-hook-policy.test.ts`，覆盖标准版本、预发布、`unknown`、边界值等决策 case。\n\n## [0.3.2] - 2026-05-08\n\n### 🐛 修复\n\n- 兼容 OpenClaw v2026.4.23 前的版本，防止写入的 hook 配置导致无法启动\n- 修改 allowConversationAccess 到 2026.4.24+ 添加。\n\n## [0.3.1-beta.1] - 2026-05-07\n\n### 🐛 修复\n\n- **兼容 OpenClaw v2026.4.23+ hook 权限策略**：该版本引入 `allowConversationAccess` 安全门控（[openclaw#70786](https://github.com/openclaw/openclaw/pull/70786)），导致非 bundled 插件的 `agent_end` hook 被静默拦截，整个 capture pipeline 失效。新增 `ensurePluginHookPolicy()` 自动检测并补全配置，优先通过 SDK 触发 gateway 自动重启，fallback 手动写入配置文件。\n- **兼容 OpenClaw 2026.5.3+ 安装校验**：新增 tsdown 构建配置生成 `dist/index.mjs`，满足新版安装时对编译产物的强制校验（不再允许纯 TypeScript 入口）。\n- **声明 `activation.onStartup`**：确保 gateway 在启动时加载本插件。\n- **声明 `contracts.tools`**：注册 `tdai_memory_search`、`tdai_conversation_search` 工具名，满足 tool registration contract 要求。\n\n---\n\n## [0.3.0] - 2026-05-06\n\n### 🚀 新功能\n\n**运维管理工具（CTL）**\n\n- 新增 `memory-tencentdb-ctl` 命令行管理工具，支持 standalone 与 hermes 两种运行模式\n- 新增 `install-memory-tencentdb` 一键安装脚本\n- CTL 新增 `config vdb-off` 命令，支持将 Gateway 存储从 VDB 回退到 SQLite\n- Gateway 安装脚本支持将环境变量写入 `~/.hermes/.env`（systemd 场景）\n\n**Offload 增强**\n\n- Offload 启动时自动应用 `after_tool_call` patch，patch 失败时自动禁用 offload\n- 新增 `setup-offload.sh` 一键启用/禁用 offload 脚本，支持 `--backend-api-key` 参数\n- L0 捕获过滤：排除 offload 注入的 MMD 上下文块，避免将压缩中间产物误存为记忆\n\n**Gateway 自愈与稳定性**\n\n- Hermes 插件新增 watchdog + lazy probe 机制，Gateway 异常时自动恢复\n- Gateway YAML 配置解析支持任意深度嵌套\n\n### ✨ 改进\n\n- 数据目录与安装目录统一整合至 `~/.memory-tencentdb/`\n- 引入 `$HERMES_HOME` 环境变量约定，移除硬编码 `~/.hermes` 路径\n- CTL hermes 配置编辑改为缩进感知，保持原始文件格式\n- 运维脚本保留在 tarball 中但不再注册为 bin 命令（减少全局命令污染）\n- init/destroy 生命周期日志降级为 debug 级别\n- patch 脚本兼容 pnpm 安装环境，使用 Node.js 动态解析 openclaw 安装路径\n\n### 🐛 修复\n\n**Core 稳定性**\n\n- 修复 `ensureSchedulerStarted` 并发调用下的竞态问题\n- 修复 `/session/end` 错误销毁全局 scheduler 的问题（改为按 session_key 作用域）\n- 修复关闭 store 时未等待后台 fire-and-forget 任务完成的问题\n- 修复 `disable_offload` 未正确删除 `slots.contextEngine` 配置的问题\n\n**Offload**\n\n- 修复 slot 占用检测逻辑：仅在 `ok=false`（slot 被占用）时拒绝，API 异常不再误判为冲突\n- 修复 `registerContextEngine` 抛异常时未禁用 offload 的问题\n- 修复 slot 被占用时未完全禁用所有 offload 功能的问题\n\n**L3 压缩**\n\n- 修复 aggressive/emergency 压缩在用户消息位于队首时卡死的问题\n- 修复消息被大量 offload 后压缩停滞的问题\n\n**迁移工具**\n\n- 修复源数据目录或 SQLite 不存在时迁移脚本崩溃的问题（改为优雅跳过）\n- 修复源数据为空时 config/manifest 未写入的问题\n\n**脚本与运维**\n\n- 修复 `set -e` 环境下 `((VAR++))` 在 VAR=0 时导致脚本退出的问题\n- 修复 patch 脚本误报 FAILED 计数的问题（跳过无 after_tool_call 上下文的候选项）\n- 修复 Hermes 退出时未终止 Gateway 子进程的问题\n\n### ♻️ 重构\n\n- 统一 patch 检测逻辑：始终委托给 patch 脚本并通过退出码判定结果\n\n---\n\n## [0.3.0-beta.1] - 2026-04-23\n\n### 🚀 新功能\n\n**短期记忆压缩（Context Offload）**\n\n- 新增 Offload 模块，支持长对话场景下的上下文压缩与记忆卸载\n\n**架构重构：Core + Gateway 多框架支持**\n\n- 重构为 `TdaiCore` 宿主无关的核心层 + 适配器模式，解耦 OpenClaw 框架依赖\n- 新增 `HostAdapter` / `LLMRunner` / `LLMRunnerFactory` 抽象接口，支持不同宿主的 LLM 调用\n- 新增 Hermes Gateway 适配器（`memory_tencentdb` Hermes Plugin），支持通过 Hermes 框架独立运行\n- `TdaiCore` 提供统一的 `handleBeforeRecall()` / `handleTurnCommitted()` / `searchMemories()` 等 API\n- Gateway 零配置自动发现：Hermes 插件自动检测配置和数据目录\n- 数据目录所有权从插件移至 Gateway 层管理\n\n**Recall 注入优化（Cache 友好）**\n\n- L1 召回记忆从 `appendSystemContext` 移到 `prependContext`（用户消息前缀），避免每轮系统提示词变化导致 prompt cache bust\n- Persona / Scene Navigation / Tools Guide 保持在 `appendSystemContext`（稳定内容，连续多轮 cache 命中）\n- 注册 `before_message_write` 钩子，在 user message 持久化到 JSONL 前 strip `<relevant-memories>` 标签，防止历史消息中累积旧的召回内容\n\n**分场景 Embedding 超时**\n\n- 新增 `embedding.recallTimeoutMs`（recall 路径）和 `embedding.captureTimeoutMs`（capture 路径）配置\n- recall 超时时 hybrid 策略自动降级为纯关键词搜索；capture 超时时 L1 dedup 降级为 FTS\n- 向前兼容：不配置时 fallback 到全局 `embedding.timeoutMs`\n\n### ✨ 改进\n\n- CleanContextRunner 通过 `systemPromptOverride` 替换 OpenClaw 默认系统提示词，每次 L1/L2/L3 调用节省 ~4500 input tokens\n- L2（场景提取）和 L3（画像生成）prompt 拆分为 `systemPrompt` + `userPrompt`，角色划分更清晰\n- Pipeline 默认参数调整：`l1IdleTimeoutSeconds` 60→600s，`l2MinIntervalSeconds` 300→900s，`l2MaxIntervalSeconds` 1800→3600s\n\n### 🐛 修复\n\n- 修复 `pullProfilesToLocal` 并发竞争导致 `ENOTEMPTY` 错误（乐观无锁修法：rename 竞争失败时静默使用对方结果）\n- 修复 `originalUserMessageCount` 数据链路断裂导致 L0 recorder 无法定位被污染的 user message\n- 修复 `RecallResult` 类型定义缺少 `prependContext` 字段（`types.ts` 与 `auto-recall.ts` 不一致）\n\n---\n\n## [0.2.2] - 2026-04-17\n\n### 🐛 修复\n\n- 修复因未声明 `undici` 依赖导致 TCVDB 客户端加载失败的问题（开发环境之前依赖 monorepo 根 `node_modules` 的传递解析）\n- 将插件注册阶段的大量 INFO 日志降级为 DEBUG，避免 CLI 模式下输出过多无关日志\n\n## [0.2.1] - 2026-04-16 (deprecated)\n\n> NOTE: 此版本由于存在 undici 依赖导致插件启动失败的问题，已废弃\n> 相关问题在 0.2.2 及以后版本中已修复\n\n### 🚀 新功能\n\n- TCVDB 新增 HTTPS 连接支持，可通过插件配置 `caPemPath` 或迁移脚本参数 `--tcvdb-ca-pem` 指定自定义 CA 证书 PEM 文件\n- `read-local-memory` 脚本新增 L2 单文件查询，并将 L0 / L1 查询切换为直接从 `vectors.db` 读取，支持 SQL 层过滤、排序与分页\n\n### ✨ 改进\n\n- TCVDB 的 L0 / L1 向量索引默认调整为 `DISK_FLAT`，并在不支持该索引类型的实例上自动回退到 `HNSW`\n- 默认服务端 embedding 模型调整为 `bge-large-zh`\n- TCVDB 所有读接口统一启用 `readConsistency: \"strongConsistency\"`，消除 read-after-write 不一致\n- 健康检测脚本 VDB 连接支持 HTTPS 自签证书\n\n### 🐛 修复\n\n- 修复 L3 persona sync 因未拉取远端 baseline 导致版本冲突跳过写入的问题\n- 修复 `memories_since_last_persona` 被 L0 和 L1 双重计数导致 persona 触发阈值膨胀的问题\n- 移除 `CheckpointManager` 中已被 `captureAtomically()` 替代的废弃方法\n\n---\n\n## [0.2.0] - 2026-04-15\n\n### 🚀 新功能\n\n**腾讯云向量数据库（TCVDB）存储后端**\n\n- 新增腾讯云向量数据库存储后端，支持向量 + BM25 混合召回\n- 支持 SQLite 与 TCVDB 之间的索引结构同步\n- L2 场景 / L3 画像支持在本地缓存与向量数据库之间双向同步\n- 插件配置（manifest）暴露 `storeBackend`、`tcvdb`、`bm25`、`embedding.timeoutMs` 等配置项\n\n**本地 BM25 关键字检索**\n\n- 使用本地 tcvdb-text 编码器替代原有的 BM25 HTTP sidecar 服务，消除外部依赖\n\n**Seed 数据导入工具**\n\n- 新增 CLI `seed` 命令，支持从外部数据批量导入记忆\n- 提取共享的 pipeline-factory，供 seed 和正常运行时复用\n- 支持 ISO 8601 时间戳格式（移除 JSONL 支持）\n\n**数据迁移与运维工具**\n\n- 新增 SQLite → 腾讯云向量数据库迁移脚本，支持 `--help` / `-h` 展示完整参数说明和使用示例\n- 新增 VDB 数据导出脚本（含预编译 JS 和 CLI 启动器）\n- 新增本地 Memory 数据查询脚本\n- 注册全部 CLI bin 入口：`migrate-sqlite-to-tcvdb`、`export-tencent-vdb`、`read-local-memory`\n\n**记忆搜索工具调用限制**\n\n- `tdai_memory_search` + `tdai_conversation_search` 增加每轮合计最多 3 次的调用次数限制，通过 tool description 和召回引导提示词约束模型行为，防止陷入无效重复搜索\n\n### 🐛 修复\n\n- 修复 L2 场景合并（MERGE）无法删除旧文件的问题：OpenClaw 4.1+ 的 write 工具拒绝空白内容，改用 `[DELETED]` 标记实现软删除，SceneExtractor cleanup 阶段同步识别并清理\n- 修复 L2 抽取产生孤立 BATCH/ARCHIVE 文件的问题，统一 maxScenes 上限为 15\n- 修复 L3 启动时重复拉取 profile 的问题\n- 过滤 skill wrapper 噪声标记（`¥¥[...]¥¥`）\n- 处理 `createCollection` 并发竞态（错误码 15202）\n\n### ♻️ 重构\n\n- Pipeline checkpoint 游标语义从 timestamp 改为 update_at\n- Runner 改用 `api.runtime.agent.runEmbeddedPiAgent`，避免跨环境导入失败\n- 统一脚本构建流程：新增 `build:scripts` 一键编译命令，`prepack` 钩子确保 `npm pack` 前自动编译全部脚本产物\n\n### 📚 文档\n\n- 新增 AI Agent 长期记忆插件设计与实现技术文档\n- 新增项目指南、研发系统分层架构文档\n- 新增 VDB 存储设计文档及迁移指南\n\n---\n\n<details>\n<summary>预发布版本</summary>\n\n## [0.2.0-beta.1] - 2026-04-14\n\n*此版本的内容已合并至 [0.2.0] 正式版。*\n\n</details>\n\n## [0.1.4] - 2026-04-10\n\n### 🚀 Features\n\n- *(auto-recall)* Add recall hint text before memories\n\n## [0.1.3] - 2026-04-09\n\n### 🚀 功能\n\n- *(memory-tdai)* 用 reporter 抽象替换 emitMetric\n- *(L3)* L3 使用读写工具，防止模型输出 CoT\n- *(memory)* 添加 embedding 截断、召回超时，以及从 L0 捕获中剔除代码块\n- *(config)* Embedding 超时支持配置\n- *(report)* 在 schema 中暴露 report 配置项，默认值改为 false\n\n### 🐛 修复\n\n- *(capture)* 跳过心跳/定时任务/自动化/调度类消息\n- *(recall)* 召回完成时清除超时定时器，避免误报超时警告\n\n### 💼 Other\n\n- 重命名包名为 memory-tencentdb\n- *(deps)* 将 node-llama-cpp 改为可选依赖\n\n### ⚡ 性能\n\n- *(auto-capture)* 将 L0 向量嵌入移至后台以降低延迟\n\n### 📚 文档\n\n- 添加 allowPromptInjection 配置警告说明\n\n## [0.1.2] — 2026-03-26\n\n### 更新内容\n\n1. 优化对话捕获与记忆抽取过滤机制\n\n## [0.1.1] — 2026-03-25\n\n### 更新内容\n\n1. 兼容 openclaw 2026.3.23 更新\n\n## [0.1.0] — 2026-03-25\n\n> 首个正式发布版本。本地优先的四层记忆系统（L0→L1→L2→L3），基于 SQLite + LLM 实现对话捕获、记忆提取、场景归纳与用户画像。\n\n### 更新内容\n\n1. 关键字检索增加 FTS5 全文索引，采用 jieba 分词\n2. 未配置远程 embedding 服务时，默认不开启 embedding 能力（不自动使用本地 embedding，且封禁主动使用本地 embedding 的配置入口）\n3. 优化 L2、L3 生成 prompt 以控制生成内容大小（减少 token 开销）\n4. Pipeline 调度器优化文件锁用法\n5. 避免全量读取 L0、L1 数据\n\nFile v0.3.7:skill-card.md\n\n## Description: <br>\nFour-layer memory system plugin for OpenClaw that captures conversations, extracts structured memories, summarizes scenes, and builds a user persona with local SQLite and Tencent Cloud VectorDB storage options. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[paudyyin](https://clawhub.ai/user/paudyyin) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agent operators use this skill to add long-term conversational memory to OpenClaw or Hermes agents, including automatic recall, structured memory extraction, scene summaries, persona generation, and migration or export tooling for memory stores. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill can modify OpenClaw behavior through high-impact host patching. <br>\nMitigation: Review or disable the postinstall patch path before installing in production environments. <br>\nRisk: The skill captures and stores long-term conversation memory, which may include sensitive user or tool content. <br>\nMitigation: Deploy only where long-term memory capture is intended, configure retention carefully, and restrict access to local and remote memory stores. <br>\nRisk: Optional backend offload and tracing can send conversations or tool payloads to external services. <br>\nMitigation: Use backend/offload and Opik or full-content tracing only with trusted endpoints and explicit operator approval. <br>\nRisk: Insecure HTTPS settings or implicit user identification can weaken privacy controls. <br>\nMitigation: Do not use insecure HTTPS settings for sensitive data and set an explicit userId instead of relying on IP fallback. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill listing](https://clawhub.ai/paudyyin/memory-tencentdb) <br>\n- [OpenClaw](https://github.com/openclaw/openclaw) <br>\n- [OpenClaw host framework](https://github.com/nicepkg/openclaw) <br>\n- [SQLite vector extension](https://github.com/asg017/sqlite-vec) <br>\n- [node-llama-cpp](https://github.com/withcatai/node-llama-cpp) <br>\n- [Tencent model API endpoint](https://api.lkeap.cloud.tencent.com/v1) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown and configuration snippets with command-line examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Produces agent memory records, scene Markdown, persona Markdown, search tool responses, and operational commands or configuration guidance.] <br>\n\n## Skill Version(s): <br>\n0.3.7 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.3.7:openclaw.plugin.json\n\n{\n  \"id\": \"memory-tencentdb\",\n  \"name\": \"Memory (TencentDB)\",\n  \"description\": \"Four-layer memory system — auto-captures, structures, and profiles conversational knowledge\",\n  \"activation\": {\n    \"onStartup\": true\n  },\n  \"contracts\": {\n    \"tools\": [\"tdai_memory_search\", \"tdai_conversation_search\"]\n  },\n  \"configSchema\": {\n    \"type\": \"object\",\n    \"additionalProperties\": true,\n    \"properties\": {\n      \"storeBackend\": {\n        \"type\": \"string\",\n        \"enum\": [\"sqlite\", \"tcvdb\"],\n        \"default\": \"sqlite\",\n        \"description\": \"存储后端：sqlite（本地 SQLite + sqlite-vec）或 tcvdb（腾讯云向量数据库）\"\n      },\n      \"capture\": {\n        \"type\": \"object\",\n        \"description\": \"对话自动捕获设置 (L0)\",\n        \"properties\": {\n          \"enabled\": { \"type\": \"boolean\", \"default\": true, \"description\": \"是否启用自动对话捕获\" },\n          \"excludeAgents\": { \"type\": \"array\", \"items\": { \"type\": \"string\" }, \"default\": [], \"description\": \"排除的 Agent glob 模式列表（如 bench-judge-*），匹配的 agent 不会被捕获、召回或参与 pipeline 调度\" },\n          \"l0l1RetentionDays\": { \"type\": \"number\", \"default\": 0, \"description\": \"L0/L1 本地文件保留天数（单位天）。0=不清理；非0时默认必须>=3。若为1或2，需显式开启 allowAggressiveCleanup\" },\n          \"allowAggressiveCleanup\": { \"type\": \"boolean\", \"default\": false, \"description\": \"是否允许高风险清理配置（l0l1RetentionDays=1或2）\" },\n          \"cleanTime\": { \"type\": \"string\", \"default\": \"03:00\", \"description\": \"每日清理执行时间（HH:mm）\" }\n        }\n      },\n      \"extraction\": {\n        \"type\": \"object\",\n        \"description\": \"记忆提取设置 (L1)\",\n        \"properties\": {\n          \"enabled\": { \"type\": \"boolean\", \"default\": true, \"description\": \"是否启用后台提取\" },\n          \"enableDedup\": { \"type\": \"boolean\", \"default\": true, \"description\": \"L1 智能去重（基于向量相似度或关键词进行冲突检测）\" },\n          \"maxMemoriesPerSession\": { \"type\": \"number\", \"default\": 20, \"description\": \"单次 L1 提取每 session 最大记忆条数\" },\n          \"model\": { \"type\": \"string\", \"description\": \"提取使用模型 (格式: provider/model)，未填写时使用openclaw默认模型\" }\n        }\n      },\n      \"persona\": {\n        \"type\": \"object\",\n        \"description\": \"场景归纳与用户画像设置 (L2/L3)\",\n        \"properties\": {\n          \"triggerEveryN\": { \"type\": \"number\", \"default\": 50, \"description\": \"每 N 条新记忆触发画像生成\" },\n          \"maxScenes\": { \"type\": \"number\", \"default\": 15, \"description\": \"最大场景数\" },\n          \"backupCount\": { \"type\": \"number\", \"default\": 3, \"description\": \"画像备份保留数量\" },\n          \"sceneBackupCount\": { \"type\": \"number\", \"default\": 10, \"description\": \"场景块备份保留数量\" },\n          \"model\": { \"type\": \"string\", \"description\": \"画像生成模型 (格式: provider/model)，未填写时使用openclaw默认模型\" }\n        }\n      },\n      \"pipeline\": {\n        \"type\": \"object\",\n        \"description\": \"L1→L2→L3 管线调度设置\",\n        \"properties\": {\n          \"everyNConversations\": { \"type\": \"number\", \"default\": 5, \"description\": \"每 N 轮对话触发 L1 批处理\" },\n          \"enableWarmup\": { \"type\": \"boolean\", \"default\": true, \"description\": \"Warm-up 模式：新 session 从 1 轮触发开始，每次 L1 后翻倍（1→2→4→...→everyN），加速早期记忆提取\" },\n          \"l1IdleTimeoutSeconds\": { \"type\": \"number\", \"default\": 600, \"description\": \"L1 空闲超时（秒）：用户停止对话后多久触发 L1 批处理\" },\n          \"l2DelayAfterL1Seconds\": { \"type\": \"number\", \"default\": 10, \"description\": \"L1 完成后延迟多久触发 L2（秒）\" },\n          \"l2MinIntervalSeconds\": { \"type\": \"number\", \"default\": 900, \"description\": \"同一 session 两次 L2 抽取的最小间隔（秒）\" },\n          \"l2MaxIntervalSeconds\": { \"type\": \"number\", \"default\": 3600, \"description\": \"同一活跃 session 的 L2 最大轮询间隔（秒）\" },\n          \"sessionActiveWindowHours\": { \"type\": \"number\", \"default\": 24, \"description\": \"session 活跃窗口（小时），超过此时间不活跃的 session 停止 L2 轮询\" }\n        }\n      },\n      \"recall\": {\n        \"type\": \"object\",\n        \"description\": \"记忆召回设置\",\n        \"properties\": {\n          \"enabled\": { \"type\": \"boolean\", \"default\": true, \"description\": \"是否启用自动召回\" },\n          \"maxResults\": { \"type\": \"number\", \"default\": 5, \"description\": \"召回最大结果数\" },\n          \"scoreThreshold\": { \"type\": \"number\", \"default\": 0.3, \"description\": \"最低分数阈值\" },\n          \"strategy\": { \"type\": \"string\", \"enum\": [\"embedding\", \"keyword\", \"hybrid\"], \"default\": \"hybrid\", \"description\": \"搜索策略：keyword(关键词)、embedding(向量)、hybrid(混合RRF融合，推荐)\" },\n          \"timeoutMs\": { \"type\": \"number\", \"default\": 5000, \"description\": \"召回整体超时（毫秒），超时后跳过记忆注入并打印警告日志\" }\n        }\n      },\n      \"embedding\": {\n        \"type\": \"object\",\n        \"description\": \"向量搜索 (Embedding) 配置\",\n        \"properties\": {\n          \"enabled\": { \"type\": \"boolean\", \"default\": true, \"description\": \"是否启用向量搜索（若 provider=none，则实际会被禁用）\" },\n          \"provider\": { \"type\": \"string\", \"default\": \"none\", \"description\": \"Embedding 服务提供者：填写兼容 OpenAI API 的远端服务名称（如 openai、deepseek 等）；不填或填 none 则禁用向量搜索\" },\n          \"proxyUrl\": { \"type\": \"string\", \"description\": \"本地代理地址（仅 provider=qclaw 时必填）。配置后 embedding 请求将通过该代理转发，原始 baseUrl 作为 Remote-URL 头传递\" },\n          \"baseUrl\": { \"type\": \"string\", \"description\": \"API Base URL（必填）：填写对应 provider 的 API 地址\" },\n          \"apiKey\": { \"type\": \"string\", \"description\": \"API Key（必填）\" },\n          \"model\": { \"type\": \"string\", \"description\": \"模型名称（必填）\" },\n          \"dimensions\": { \"type\": \"number\", \"description\": \"向量维度（必填，需与所选模型匹配）\" },\n          \"conflictRecallTopK\": { \"type\": \"number\", \"default\": 5, \"description\": \"冲突检测时召回 Top-K 数\" },\n          \"maxInputChars\": { \"type\": \"number\", \"default\": 5000, \"description\": \"Embedding 输入文本最大字符数，超出时截断并打印警告日志（默认 5000，适合大多数模型的 token 上限）\" },\n          \"timeoutMs\": { \"type\": \"number\", \"default\": 10000, \"description\": \"单次 embedding API 调用超时（毫秒），超时后该次请求中止且不重试\" },\n          \"recallTimeoutMs\": { \"type\": \"number\", \"description\": \"recall 路径 embedding 超时（毫秒），覆盖 timeoutMs。用户等待中，建议设短一些（如 3000）\" },\n          \"captureTimeoutMs\": { \"type\": \"number\", \"description\": \"capture 路径 embedding 超时（毫秒），覆盖 timeoutMs。后台运行，可设长一些（如 15000）\" }\n        }\n      },\n      \"tcvdb\": {\n        \"type\": \"object\",\n        \"description\": \"腾讯云向量数据库配置（仅 storeBackend=tcvdb 时生效）\",\n        \"properties\": {\n          \"url\": { \"type\": \"string\", \"description\": \"实例 URL（必填，如 http://10.0.1.1:8100）\" },\n          \"username\": { \"type\": \"string\", \"default\": \"root\", \"description\": \"账户名\" },\n          \"apiKey\": { \"type\": \"string\", \"description\": \"API Key（必填）\" },\n          \"database\": { \"type\": \"string\", \"description\": \"数据库名（未填写时默认根据实例 ID 自动生成）\" },\n          \"alias\": { \"type\": \"string\", \"description\": \"用户友好别名（可选，用于 database.json 中识别）\" },\n          \"embeddingModel\": { \"type\": \"string\", \"default\": \"bge-large-zh\", \"description\": \"服务端 embedding 模型\" },\n          \"timeout\": { \"type\": \"number\", \"default\": 10000, \"description\": \"请求超时（毫秒）\" },\n          \"caPemPath\": { \"type\": \"string\", \"description\": \"CA 证书 PEM 文件路径（HTTPS 连接时使用）\" }\n        }\n      },\n      \"bm25\": {\n        \"type\": \"object\",\n        \"description\": \"BM25 稀疏向量编码设置（主要用于 tcvdb 后端）\",\n        \"properties\": {\n          \"enabled\": { \"type\": \"boolean\", \"default\": true, \"description\": \"是否启用 BM25 稀疏向量编码\" },\n          \"language\": { \"type\": \"string\", \"enum\": [\"zh\", \"en\"], \"default\": \"zh\", \"description\": \"分词语言：zh（中文）或 en（英文）\" }\n        }\n      },\n      \"report\": {\n        \"type\": \"object\",\n        \"description\": \"指标上报设置\",\n        \"properties\": {\n          \"enabled\": { \"type\": \"boolean\", \"default\": false, \"description\": \"是否启用指标上报（通过 Gateway 日志输出结构化 METRIC JSON）\" },\n          \"type\": { \"type\": \"string\", \"default\": \"local\", \"description\": \"上报方式：local 表示通过 logger 输出结构化 JSON 日志\" }\n        }\n      },\n      \"offload\": {\n        \"type\": \"object\",\n        \"description\": \"Context Offload 设置 — 多层上下文压缩系统（独立开关，默认关闭）\",\n        \"properties\": {\n          \"enabled\": { \"type\": \"boolean\", \"default\": false, \"description\": \"是否启用 Context Offload（默认关闭，不影响 Memory 功能）\" },\n          \"model\": { \"type\": \"string\", \"description\": \"Offload 使用的 LLM 模型（格式: provider/model），未填写时使用 openclaw 默认模型\" },\n          \"temperature\": { \"type\": \"number\", \"default\": 0.2, \"description\": \"LLM 温度参数\" },\n          \"forceTriggerThreshold\": { \"type\": \"number\", \"default\": 4, \"description\": \"累积多少个 tool pair 后强制触发 L1\" },\n          \"dataDir\": { \"type\": \"string\", \"description\": \"自定义数据目录（绝对路径），默认 ~/.openclaw/context-offload\" },\n          \"defaultContextWindow\": { \"type\": \"number\", \"default\": 200000, \"description\": \"默认上下文窗口大小\" },\n          \"maxPairsPerBatch\": { \"type\": \"number\", \"default\": 20, \"description\": \"L1 每批最大 tool pair 数\" },\n          \"l2NullThreshold\": { \"type\": \"number\", \"default\": 4, \"description\": \"offload.jsonl 中 node_id=null 数量达到此阈值时触发 L2\" },\n          \"l2TimeoutSeconds\": { \"type\": \"number\", \"default\": 300, \"description\": \"距上次 L2 超过此秒数时触发 L2\" },\n          \"mildOffloadRatio\": { \"type\": \"number\", \"default\": 0.5, \"description\": \"温和压缩触发比例（占 context window）\" },\n          \"aggressiveCompressRatio\": { \"type\": \"number\", \"default\": 0.85, \"description\": \"激进压缩触发比例\" },\n          \"mmdMaxTokenRatio\": { \"type\": \"number\", \"default\": 0.2, \"description\": \"MMD 注入 token 预算比例\" },\n          \"backendUrl\": { \"type\": \"string\", \"description\": \"后端服务 URL（如 https://offload-api.example.com），配置后 L1/L1.5/L2/L4 走后端\" },\n          \"backendApiKey\": { \"type\": \"string\", \"description\": \"后端 API 认证 token\" },\n          \"backendTimeoutMs\": { \"type\": \"number\", \"default\": 10000, \"description\": \"后端调用超时（毫秒）\" }\n        }\n      }\n    }\n  }\n}\n\nFile v0.3.7:package.json\n\n{\n  \"name\": \"@tencentdb-agent-memory/memory-tencentdb\",\n  \"version\": \"0.3.6\",\n  \"description\": \"Four-layer local memory system plugin for OpenClaw — auto-captures, structures, and profiles conversational knowledge using local LLM + SQLite vector search (L0→L1→L2→L3 pipeline)\",\n  \"type\": \"module\",\n  \"main\": \"./dist/index.mjs\",\n  \"bin\": {\n    \"migrate-sqlite-to-tcvdb\": \"./bin/migrate-sqlite-to-tcvdb.mjs\",\n    \"export-tencent-vdb\": \"./bin/export-tencent-vdb.mjs\",\n    \"read-local-memory\": \"./bin/read-local-memory.mjs\"\n  },\n  \"exports\": {\n    \".\": {\n      \"import\": \"./dist/index.mjs\",\n      \"default\": \"./dist/index.mjs\"\n    }\n  },\n  \"scripts\": {\n    \"build\": \"npm run build:plugin && npm run build:scripts\",\n    \"build:plugin\": \"tsdown\",\n    \"build:scripts\": \"npm run build:migrate-sqlite-to-vdb && npm run build:export-tencent-vdb && npm run build:read-local-memory\",\n    \"prepack\": \"npm run build\",\n    \"build:migrate-sqlite-to-vdb\": \"tsc -p scripts/migrate-sqlite-to-tcvdb/tsconfig.json --noEmitOnError false\",\n    \"migrate-sqlite-to-tcvdb\": \"node ./bin/migrate-sqlite-to-tcvdb.mjs\",\n    \"build:export-tencent-vdb\": \"tsc --project scripts/export-tencent-vdb/tsconfig.json\",\n    \"export-tencent-vdb\": \"node ./bin/export-tencent-vdb.mjs\",\n    \"build:read-local-memory\": \"tsc --project scripts/read-local-memory/tsconfig.json\",\n    \"read-local-memory\": \"node ./bin/read-local-memory.mjs\",\n    \"test\": \"vitest run\",\n    \"test:watch\": \"vitest\",\n    \"test:coverage\": \"vitest run --coverage\",\n    \"postinstall\": \"bash scripts/openclaw-after-tool-call-messages.patch.sh 2>/dev/null || true\"\n  },\n  \"files\": [\n    \"dist/\",\n    \"bin/\",\n    \"index.ts\",\n    \"scripts/migrate-sqlite-to-tcvdb/dist/\",\n    \"scripts/export-tencent-vdb/dist/\",\n    \"scripts/read-local-memory/dist/\",\n    \"scripts/memory-tencentdb-ctl.sh\",\n    \"scripts/install_hermes_memory_tencentdb.sh\",\n    \"scripts/README.memory-tencentdb-ctl.md\",\n    \"src/\",\n    \"scripts/openclaw-after-tool-call-messages.patch.sh\",\n    \"scripts/setup-offload.sh\",\n    \"hermes-plugin/\",\n    \"openclaw.plugin.json\",\n    \"README.md\",\n    \"CHANGELOG.md\",\n    \"LICENSE\",\n    \"!src/**/*.test.ts\",\n    \"!src/**/*.spec.ts\",\n    \"!src/**/__tests__/\"\n  ],\n  \"keywords\": [\n    \"openclaw\",\n    \"openclaw-plugin\",\n    \"memory\",\n    \"ai-memory\",\n    \"long-term-memory\",\n    \"vector-search\",\n    \"sqlite-vec\",\n    \"llm\",\n    \"conversation\",\n    \"persona\",\n    \"scene-extraction\",\n    \"embedding\"\n  ],\n  \"author\": \"TencentDB Agent Memory Team\",\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=22.16.0\"\n  },\n  \"dependencies\": {\n    \"@ai-sdk/openai\": \"^3.0.53\",\n    \"@node-rs/jieba\": \"^2.0.1\",\n    \"@tencentdb-agent-memory/tcvdb-text\": \"^0.1.1\",\n    \"ai\": \"^6.0.164\",\n    \"js-tiktoken\": \"^1.0.18\",\n    \"json5\": \"^2.2.3\",\n    \"sqlite-vec\": \"0.1.7-alpha.2\",\n    \"tsx\": \"^4.21.0\",\n    \"undici\": \"^8.1.0\",\n    \"yaml\": \"^2.8.3\",\n    \"zod\": \"^4.4.3\"\n  },\n  \"optionalDependencies\": {\n    \"opik\": \"^1.0.0\"\n  },\n  \"peerDependencies\": {\n    \"node-llama-cpp\": \"^3.16.2\",\n    \"openclaw\": \">=2026.3.7\"\n  },\n  \"peerDependenciesMeta\": {\n    \"openclaw\": {\n      \"optional\": true\n    },\n    \"node-llama-cpp\": {\n      \"optional\": true\n    }\n  },\n  \"openclaw\": {\n    \"extensions\": [\n      \"./index.ts\"\n    ],\n    \"compat\": {\n      \"pluginApi\": \">=2026.3.13\",\n      \"minGatewayVersion\": \">=2026.3.13\"\n    },\n    \"build\": {\n      \"openclawVersion\": \"2026.3.13\",\n      \"pluginSdkVersion\": \"2026.3.13\"\n    },\n    \"bundle\": {\n      \"stageRuntimeDependencies\": true\n    }\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^25.5.2\",\n    \"@vitest/coverage-v8\": \"^4.1.2\",\n    \"tsdown\": \"^0.21.10\",\n    \"typescript\": \"^6.0.2\",\n    \"vitest\": \"^4.1.2\"\n  }\n}\n\nFile v0.3.7:hermes-plugin/memory/memory_tencentdb/plugin.yaml\n\nname: memory_tencentdb\ndisplay_name: memory-tencentdb\nversion: 1.0.0\ndescription: \"memory-tencentdb four-layer memory — L0 conversation recording, L1 episodic extraction, L2 scene blocks, L3 persona synthesis via local Node.js Gateway.\"\nhooks:\n  - on_memory_write\n  - on_session_end\n# Legacy provider name — kept so that users whose config still says\n# `memory.provider: tdai` continue to resolve to this provider.\naliases:\n  - tdai\n  - memory-tencentdb\n\nArchive v0.3.6: 5 files, 11429 bytes\n\nFiles: package.json (6033b), README.md (16439b), skill-card.md (3082b), SKILL.md (2905b), _meta.json (135b)\n\nFile v0.3.6:SKILL.md\n\n---\nname: memory-tencentdb\ndescription: 鍥涘眰璁板繂绯荤粺鎻掍欢 鈥?鑷姩鎹曡幏瀵硅瘽銆佹彁鍙栫粨鏋勫寲璁板繂銆佸綊绾冲満鏅€佺敓鎴愮敤鎴风敾鍍忋€傛敮鎸?L0鈫扡1鈫扡2鈫扡3 娓愯繘寮忕绾匡紝鏈湴 SQLite + 鑵捐浜戝悜閲忔暟鎹簱鍙屽悗绔€?version: 0.3.6\ntags: [\"memory\", \"long-term-memory\", \"llm\", \"persona\", \"sqlite\", \"vector-search\"]\nauthor: paudyyin\n---\n\n# memory-tencentdb 鈥?鍥涘眰璁板繂绯荤粺\n\n涓?OpenClaw AI Agent 鎻愪緵 L0鈫扡1鈫扡2鈫扡3 闀挎湡璁板繂鑳藉姏銆?\n## 鏋舵瀯\n\n```\n瀵硅瘽寮€濮?  鈫?Auto-Recall: 鍚戦噺/娣峰悎鎼滅储鐩稿叧璁板繂 + 鍔犺浇 Persona 鈫?娉ㄥ叆绯荤粺涓婁笅鏂?\n瀵硅瘽缁撴潫\n  鈫?L0: 褰曞埗瀵硅瘽娑堟伅 鈫?SQLite + JSONL 鍙屽啓\n  鈫?Pipeline Scheduler: 杈惧埌 N 杞悗瑙﹀彂\n     鈹溾攢鈹€ L1: LLM 鎻愬彇缁撴瀯鍖栬蹇?+ 鍚戦噺鍘婚噸 鈫?JSONL + SQLite\n     鈹溾攢鈹€ L2: LLM 褰掔撼鍦烘櫙鍧?鈫?Markdown 鏂囦欢\n     鈹斺攢鈹€ L3: LLM 鐢熸垚/鏇存柊鐢ㄦ埛鐢诲儚 鈫?persona.md\n```\n\n## 鍥涘眰璁板繂\n\n| 灞傜骇 | 鍚嶇О | 璇存槑 |\n|------|------|------|\n| L0 | 瀵硅瘽褰曞埗 | 鍘熷瀵硅瘽娑堟伅鎹曡幏 |\n| L1 | 璁板繂鎻愬彇 | 缁撴瀯鍖栬蹇嗭紙persona/episodic/instruction锛?|\n| L2 | 鍦烘櫙褰掔撼 | 鍦烘櫙鍧楋紙Scene Block锛?|\n| L3 | 鐢ㄦ埛鐢诲儚 | 鐢ㄦ埛浜烘牸鐢诲儚锛圥ersona锛?|\n\n## 璁板繂绫诲瀷\n\n- **persona**锛氱敤鎴风殑绋冲畾灞炴€с€佸亸濂姐€佹妧鑳姐€佷环鍊艰\n- **episodic**锛氬瑙傚彂鐢熺殑鍔ㄤ綔銆佸喅瀹氥€佽鍒掓垨缁撴灉\n- **instruction**锛氱敤鎴峰 AI 鐨勯暱鏈熻涓鸿鍒?\n## 瀹夎\n\n```bash\nclawhub install memory-tencentdb\n```\n\n## 閰嶇疆\n\n鍦?openclaw.json 涓坊鍔狅細\n\n```json\n{\n  \"plugins\": {\n    \"allow\": [\"mx\", \"memory-tencentdb\"],\n    \"load\": {\n      \"paths\": [\"<鎻掍欢璺緞>\"]\n    },\n    \"entries\": {\n      \"memory-tencentdb\": {\n        \"enabled\": true,\n        \"config\": {\n          \"llm\": {\n            \"enabled\": true,\n            \"baseUrl\": \"https://浣犵殑LLM绔偣/v1\",\n            \"model\": \"浣犵殑妯″瀷ID\"\n          },\n          \"pipeline\": {\n            \"everyNConversations\": 3\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n## 瀛樺偍鍚庣\n\n- `sqlite`锛堥粯璁わ級锛氭湰鍦?SQLite + sqlite-vec\n- `tcvdb`锛氳吘璁簯鍚戦噺鏁版嵁搴?\n## CLI 鍛戒护\n\n```bash\nopenclaw memory-tdai seed --input conversations.json\n```\n\n## 鏁呴殰鎺掓煡\n\n濡傛灉 L1 鎻愬彇涓虹┖锛?1. 妫€鏌?`plugins.allow` 鍖呭惈 `\"memory-tencentdb\"`\n2. 妫€鏌?`plugins.load.paths` 鍖呭惈鎻掍欢璺緞\n3. 妫€鏌?`llm.enabled` 涓?`true`\n4. 妫€鏌?LLM 绔偣鍙闂?\n\nFile v0.3.6:README.md\n\n# @tencentdb-agent-memory/memory-tencentdb\n\n**Four-layer memory system plugin for [OpenClaw](https://github.com/openclaw/openclaw).**\n\n为 AI Agent 提供长期记忆能力。通过 L0→L1→L2→L3 四层渐进式管线，自动将对话内容提炼为结构化记忆、场景块和用户画像。支持纯本地 SQLite 和远端腾讯云向量数据库（TCVDB）两种存储后端。\n\n## ✨ 核心功能\n\n- **L0 — 对话录制**：自动捕获每轮对话原始消息，IMemoryStore + JSONL 双写\n- **L1 — 记忆提取**：由 LLM 从对话中提取结构化记忆，支持向量去重与冲突检测\n- **L2 — 场景归纳**：基于 L1 记忆自动归纳场景块（Scene Block），由 LLM 增量提取\n- **L3 — 用户画像**：基于场景块自动生成/更新用户画像（Persona）\n- **自动召回（Auto-Recall）**：对话开始前自动注入相关记忆和用户画像到上下文\n- **多后端存储**：支持 `sqlite`（本地 SQLite + sqlite-vec）和 `tcvdb`（腾讯云向量数据库，服务端 embedding + hybridSearch）\n- **BM25 稀疏向量**：内置 BM25 编码器（tcvdb-text），支持中英文混合搜索\n- **关键词+向量混合搜索**：hybrid（关键词 + 向量 RRF 融合）搜索策略\n- **语义搜索工具**：Agent 可调用 `tdai_memory_search`（L1 记忆搜索）和 `tdai_conversation_search`（L0 对话搜索）\n- **Seed CLI**：`openclaw memory-tdai seed` 命令，支持导入历史对话数据（详见 [CLI 文档](src/cli/README.md)）\n- **Session 隔离**：不同渠道/Agent 的对话独立调度、独立提取\n- **本地数据清理**：可配置 L0/L1 数据保留天数，定时自动清理过期文件\n- **Manifest 元数据**：数据目录自动生成 `.metadata/manifest.json`，记录 store 绑定信息和 seed 运行记录\n- **支持零配置**：支持零配置工作，简单易用\n\n## 🏗️ 关键原理\n\n```\n对话开始\n  → Auto-Recall: 向量/混合搜索相关记忆 + 加载 Persona → 注入系统上下文\n\n对话结束\n  → Auto-Capture (L0): 录制对话消息 → IMemoryStore (SQLite/TCVDB) + JSONL 双写\n  → Pipeline Scheduler: 达到 N 轮后按序触发 L1 → L2 → L3\n     ├── L1: LLM 提取结构化记忆 + 向量去重 → 写入 JSONL + IMemoryStore\n     ├── L2: LLM 归纳场景块 → Markdown 文件\n     └── L3: LLM 生成/更新用户画像 → persona.md\n```\n\n### 数据目录结构\n\n```\n<pluginDataDir>/\n├── conversations/     — L0 每日 JSONL 分片（每行一条消息）\n├── records/           — L1 每日 JSONL 分片（提取的记忆）\n├── scene_blocks/      — L2 场景块 .md 文件\n├── vectors.db         — SQLite + vec0 向量数据库（仅 storeBackend=sqlite）\n├── .metadata/\n│   ├── manifest.json  — 数据目录元数据（store 绑定、seed 信息）\n│   └── checkpoint.json\n└── .backup/           — 滚动备份（persona, scene_blocks）\n```\n\n## 🚀 Quick Start（Docker）\n\n使用预构建的 Docker 镜像，一行命令即可启动带记忆能力的 Hermes Agent：\n\n```bash\ndocker run -d \\\n  --name hermes-memory \\\n  --restart unless-stopped \\\n  -p 8420:8420 \\\n  -e MODEL_API_KEY=\"your-api-key\" \\\n  -e MODEL_BASE_URL=\"https://api.lkeap.cloud.tencent.com/v1\" \\\n  -e MODEL_NAME=\"deepseek-v3.2\" \\\n  -e MODEL_PROVIDER=\"custom\" \\\n  -v hermes_data:/opt/data \\\n  agentmemory/hermes-memory:latest\n```\n\n镜像支持 `linux/amd64` 和 `linux/arm64` 架构。内置腾讯云 DeepSeek-V3.2 默认值，如使用该模型可省略 `MODEL_BASE_URL`/`MODEL_NAME`/`MODEL_PROVIDER`，只传 `MODEL_API_KEY` 即可。\n\n### 环境变量\n\n#### 统一模型配置（Hermes + TDAI 共用）\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `MODEL_API_KEY` | - | LLM API Key（**必填**） |\n| `MODEL_BASE_URL` | `https://api.lkeap.cloud.tencent.com/v1` | LLM API 地址 |\n| `MODEL_NAME` | `deepseek-v3.2` | 模型名称 |\n| `MODEL_PROVIDER` | `custom` | 模型 provider：`custom` / `openrouter` / `anthropic` / `openai` / `gemini` |\n\n#### 服务配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `TDAI_GATEWAY_PORT` | `8420` | Gateway 端口 |\n| `TDAI_GATEWAY_HOST` | `0.0.0.0` | Gateway 绑定地址 |\n| `TDAI_DATA_DIR` | `/opt/data/tdai-memory` | 记忆数据目录 |\n| `HERMES_HOME` | `/opt/data` | Hermes 数据目录 |\n\n### 验证运行\n\n```bash\n# 验证 Gateway 健康状态\ncurl http://localhost:8420/health\n\n# 进入 Hermes 对话\ndocker exec -it hermes-memory hermes\n\n# 查看容器日志\ndocker logs -f hermes-memory\n```\n\n> 更多配置选项和集成说明请参考下文。\n\n---\n\n## 📋 前置依赖\n\n| 依赖 | 版本要求 | 说明 |\n|------|---------|------|\n| [OpenClaw](https://github.com/nicepkg/openclaw) | `>= 2026.3.13` | 宿主框架，提供插件 SDK 及 Gateway 运行环境 |\n| [Node.js](https://nodejs.org/) | `>= 22.16.0` | 运行时环境 |\n| [`node-llama-cpp`](https://github.com/withcatai/node-llama-cpp) | `^3.16.2` | 本地 embedding 模型（GGUF 格式），提供离线向量化能力（仅 sqlite 后端需要） |\n| [`sqlite-vec`](https://github.com/asg017/sqlite-vec) | `0.1.7-alpha.2` | SQLite 向量搜索扩展（仅 sqlite 后端需要） |\n| [`tcvdb-text`](../../../packages/tcvdb-text) | `workspace:*` | BM25 稀疏向量编码器，支持中英文分词（仅 tcvdb 后端需要） |\n\n> 默认场景下无需安装 `node-llama-cpp`。如需启用本地 embedding，再在宿主环境手动安装该包。\n\n## 📦 安装\n\n```bash\n# 安装插件\nopenclaw plugins install @tencentdb-agent-memory/memory-tencentdb\n\n# 更新插件\nopenclaw plugins update memory-tencentdb\n\n# 卸载插件\nopenclaw plugins uninstall memory-tencentdb\n```\n\n安装完成后，**重启 Gateway** 使插件生效：\n\n```bash\nopenclaw gateway restart\n```\n\n## ⚙️ 配置\n\n插件配置位于 `~/.openclaw/openclaw.json` 中 `memory-tencentdb` 字段下。**所有字段均有合理默认值，零配置即可使用。**\n\n### 最小配置\n\n安装启用后即为该状态（默认使用本地 SQLite 后端）：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"enabled\": true\n  }\n}\n```\n\n> **⚠️ 重要：`allowPromptInjection` 必须为 `true`**\n>\n> 本插件通过 `before_prompt_build` hook 在对话开始前将召回的记忆注入系统上下文。\n> OpenClaw v2026.4.5+ 新增了 `allowPromptInjection` 安全控制，当该选项设为 `false` 时，\n> `before_prompt_build` hook 将被**完全阻止注册**，导致记忆召回静默失效（不会报错，仅有 warn 日志）。\n>\n> 请确保 `openclaw.json` 中**不要**将该插件的 `allowPromptInjection` 设为 `false`：\n>\n> ```jsonc\n> // ❌ 错误配置 — 会导致记忆召回完全失效\n> {\n>   \"plugins\": {\n>     \"entries\": {\n>       \"memory-tencentdb\": {\n>         \"hooks\": { \"allowPromptInjection\": false }\n>       }\n>     }\n>   }\n> }\n>\n> ```\n\n### TCVDB 后端配置\n\n使用腾讯云向量数据库作为存储后端：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"storeBackend\": \"tcvdb\",\n    \"tcvdb\": {\n      \"url\": \"http://your-vdb-instance:8100\",\n      \"apiKey\": \"your-api-key\",\n      \"database\": \"my_memory_db\",\n      \"alias\": \"生产环境\"\n    }\n  }\n}\n```\n\n### 完整配置\n\n用户可按需配置，提升使用体验：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"storeBackend\": \"sqlite\",\n    \"capture\": {\n      \"enabled\": true,\n      \"excludeAgents\": [\"bench-judge-*\"],\n      \"l0l1RetentionDays\": 90,\n      \"allowAggressiveCleanup\": false,\n      \"cleanTime\": \"03:00\"\n    },\n    \"extraction\": {\n      \"enabled\": true,\n      \"enableDedup\": true,\n      \"maxMemoriesPerSession\": 20,\n      \"model\": \"provider/model-name\"\n    },\n    \"persona\": {\n      \"triggerEveryN\": 50,\n      \"maxScenes\": 15,\n      \"backupCount\": 3,\n      \"sceneBackupCount\": 10,\n      \"model\": \"provider/model-name\"\n    },\n    \"pipeline\": {\n      \"everyNConversations\": 5,\n      \"enableWarmup\": true,\n      \"l1IdleTimeoutSeconds\": 600,\n      \"l2DelayAfterL1Seconds\": 10,\n      \"l2MinIntervalSeconds\": 900,\n      \"l2MaxIntervalSeconds\": 3600,\n      \"sessionActiveWindowHours\": 24\n    },\n    \"recall\": {\n      \"enabled\": true,\n      \"maxResults\": 5,\n      \"scoreThreshold\": 0.3,\n      \"strategy\": \"hybrid\",\n      \"timeoutMs\": 5000\n    },\n    \"embedding\": {\n      \"enabled\": true,\n      \"provider\": \"none\",\n      \"baseUrl\": \"https://your-embedding-endpoint/v1\",\n      \"apiKey\": \"your-api-key\",\n      \"model\": \"text-embedding-3-small\",\n      \"dimensions\": 1536,\n      \"conflictRecallTopK\": 5,\n      \"maxInputChars\": 5000,\n      \"timeoutMs\": 10000\n    },\n    \"tcvdb\": {\n      \"url\": \"http://your-vdb-instance:8100\",\n      \"username\": \"root\",\n      \"apiKey\": \"your-api-key\",\n      \"database\": \"my_memory_db\",\n      \"alias\": \"生产环境\",\n      \"embeddingModel\": \"bge-large-zh\",\n      \"timeout\": 10000\n    },\n    \"bm25\": {\n      \"enabled\": true,\n      \"language\": \"zh\"\n    }\n  }\n}\n```\n\n### 配置说明\n\n#### storeBackend — 存储后端\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `storeBackend` | string | `\"sqlite\"` | 存储后端：`sqlite`（本地 SQLite + sqlite-vec）或 `tcvdb`（腾讯云向量数据库） |\n\n#### capture — 对话捕获 (L0)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用自动对话捕获 |\n| `excludeAgents` | string[] | `[]` | Agent 排除 glob 模式列表，匹配的 agent 不参与捕获/召回/调度 |\n| `l0l1RetentionDays` | number | `0` | L0/L1 本地文件保留天数。`0` = 不清理；非 0 时需 >= 3（除非开启 `allowAggressiveCleanup`） |\n| `allowAggressiveCleanup` | boolean | `false` | 是否允许 1-2 天的高风险清理配置 |\n| `cleanTime` | string | `\"03:00\"` | 每日清理执行时间（HH:mm 格式） |\n\n#### extraction — 记忆提取 (L1)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用后台记忆提取 |\n| `enableDedup` | boolean | `true` | 启用 L1 智能去重（基于向量相似度或关键词进行冲突检测） |\n| `maxMemoriesPerSession` | number | `20` | 单次 L1 提取每 session 最大记忆条数 |\n| `model` | string | *(OpenClaw 默认模型)* | 提取使用模型（格式：`provider/model`），未填写时使用 OpenClaw 默认模型 |\n\n#### pipeline — 管线调度 (L1→L2→L3)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `everyNConversations` | number | `5` | 每 N 轮对话触发一次 L1 批处理 |\n| `enableWarmup` | boolean | `true` | Warm-up 模式：新 session 从 1 轮触发开始，每次 L1 后翻倍（1→2→4→...→N） |\n| `l1IdleTimeoutSeconds` | number | `600` | 用户停止对话后多久触发 L1（秒） |\n| `l2DelayAfterL1Seconds` | number | `10` | L1 完成后延迟多久触发 L2（秒） |\n| `l2MinIntervalSeconds` | number | `900` | 同一 session 两次 L2 的最小间隔（秒） |\n| `l2MaxIntervalSeconds` | number | `3600` | 活跃 session 的 L2 最大轮询间隔（秒） |\n| `sessionActiveWindowHours` | number | `24` | 超过此时间不活跃的 session 停止 L2 轮询 |\n\n#### recall — 记忆召回\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用对话前自动召回 |\n| `maxResults` | number | `5` | 召回最大结果数 |\n| `scoreThreshold` | number | `0.3` | 最低分数阈值 |\n| `strategy` | string | `\"hybrid\"` | 搜索策略：`keyword`（关键词）、`embedding`（向量）、`hybrid`（混合 RRF 融合，推荐） |\n| `timeoutMs` | number | `5000` | 整体召回超时（毫秒）。超时后跳过记忆注入并输出 warn 日志，避免阻塞用户对话 |\n\n#### embedding — 向量搜索（仅 sqlite 后端）\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用向量搜索（若 `provider=\"none\"`，则实际会被禁用） |\n| `provider` | string | `\"none\"` | Embedding 服务提供者：`none` 表示禁用向量；其他值（如 `openai`、`deepseek`）按 OpenAI 兼容远端服务处理 |\n| `baseUrl` | string | — | API Base URL（远端模式必填） |\n| `apiKey` | string | — | API Key（远端模式必填） |\n| `model` | string | — | 模型名称（远端模式必填） |\n| `dimensions` | number | — | 向量维度（远端模式必填，需与模型匹配） |\n| `conflictRecallTopK` | number | `5` | 冲突检测时召回 Top-K 数 |\n| `maxInputChars` | number | `5000` | Embedding 输入文本最大字符数，超出时截断并打印警告日志（适合大多数模型的 token 上限） |\n| `timeoutMs` | number | `10000` | 单次 embedding API 调用超时（毫秒）。超时后该次 embedding 请求中止，不重试 |\n\n#### tcvdb — 腾讯云向量数据库（仅 storeBackend=tcvdb）\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `url` | string | — | 实例 URL（必填，如 `http://10.0.1.1:8100`） |\n| `username` | string | `\"root\"` | 账户名 |\n| `apiKey` | string | — | API Key（必填） |\n| `database` | string | — | 数据库名（必填，需唯一） |\n| `alias` | string | — | 用户友好别名（可选，记录在 manifest 中便于识别） |\n| `embeddingModel` | string | `\"bge-large-zh\"` | 服务端 embedding 模型 |\n| `timeout` | number | `10000` | 请求超时（毫秒） |\n\n#### bm25 — BM25 稀疏向量编码\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用 BM25 稀疏向量编码 |\n| `language` | string | `\"zh\"` | 分词语言：`zh`（中文 jieba）或 `en`（英文） |\n| `maxInputChars` | number | `5000` | Embedding 输入文本最大字符数，超出时截断并打印警告日志（适合大多数模型的 token 上限） |\n| `timeoutMs` | number | `10000` | 单次 embedding API 调用超时（毫秒）。超时后该次 embedding 请求中止，不重试 |\n\n#### persona — 场景归纳与用户画像 (L2/L3)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `triggerEveryN` | number | `50` | 每 N 条新记忆触发一次画像生成 |\n| `maxScenes` | number | `15` | 最大场景块数量 |\n| `backupCount` | number | `3` | 画像备份保留数量 |\n| `sceneBackupCount` | number | `10` | 场景块备份保留数量 |\n| `model` | string | *(OpenClaw 默认模型)* | L2/L3 使用模型（格式：`provider/model`），未填写时使用 OpenClaw 默认模型 |\n\n#### report — 指标上报\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `false` | 是否启用指标上报（通过 Gateway 日志输出结构化 METRIC JSON） |\n| `type` | string | `\"local\"` | 上报方式：`local` 表示通过 logger 输出结构化 JSON 日志 |\n\n## 🖥️ CLI 命令\n\n插件提供 `openclaw memory-tdai` 命令空间，支持以下子命令：\n\n### `seed` — 导入历史对话数据\n\n将历史对话 JSON 文件导入到记忆管线中，完整执行 L0→L1→L2→L3 流程。\n\n```bash\nopenclaw memory-tdai seed --input conversations.json [--output-dir ./output] [--config seed-config.json] [--yes]\n```\n\n详细用法、输入格式和配置覆盖机制请参阅 [CLI 文档](src/cli/README.md)。\n\n## 🔧 Agent 工具\n\n插件注册了两个 Agent 可调用的工具：\n\n### `tdai_memory_search`\n\n搜索用户的 L1 结构化长期记忆。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `query` | string | ✅ | 搜索查询 |\n| `limit` | number | — | 返回结果上限（默认 5，最大 20） |\n| `type` | string | — | 按记忆类型过滤：`persona` / `episodic` / `instruction` |\n| `scene` | string | — | 按场景名过滤 |\n\n### `tdai_conversation_search`\n\n搜索 L0 原始对话历史。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `query` | string | ✅ | 搜索查询 |\n| `limit` | number | — | 返回结果上限（默认 5，最大 20） |\n| `session_key` | string | — | 按 session 过滤 |\n\n## 📁 数据与日志\n\n- **数据目录**：`~/.openclaw/memory-tdai/`（自动创建）\n- **元数据**：`.metadata/manifest.json`（store 绑定、seed 运行记录）\n- **Gateway 日志**：插件运行日志通过 `[memory-tdai]` 前缀标记，可在 Gateway 日志中搜索查看\n- **配置文件**：`~/.openclaw/openclaw.json`\n\n## 📄 License\n\n[MIT](LICENSE)\n\nFile v0.3.6:_meta.json\n\n{\n  \"ownerId\": \"kn73z7zhz92tv6skpnmpy5pdfh86j68x\",\n  \"slug\": \"memory-tencentdb\",\n  \"version\": \"0.3.6\",\n  \"publishedAt\": 1780197458331\n}\n\nFile v0.3.6:skill-card.md\n\n## Description: <br>\nMemory (TencentDB) gives OpenClaw agents long-term memory by capturing conversations, extracting structured memories, summarizing scenes, and maintaining a user persona across an L0-L3 pipeline with SQLite and TencentDB vector database backends. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[paudyyin](https://clawhub.ai/user/paudyyin) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agent operators use this skill to add persistent memory, automatic recall, semantic memory search, scene summaries, and persona updates to OpenClaw-based agents. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: The skill stores and recalls sensitive conversation history by default. <br>\nMitigation: Confirm who can trigger memory search, set a finite retention period, and disable or restrict raw conversation search where private or regulated conversations are involved. <br>\nRisk: Conversation content may be sent to third-party model or storage services depending on configuration. <br>\nMitigation: Use local-only model and storage settings when data must remain local, and review TencentDB and LLM endpoint configuration before deployment. <br>\nRisk: The package includes an install-time postinstall patch script noted by the security guidance. <br>\nMitigation: Inspect the published package contents before allowing install-time scripts to run, or install in a controlled environment that blocks scripts until reviewed. <br>\nRisk: The release is marked suspicious by the authoritative security evidence because high-impact memory behavior is under-documented. <br>\nMitigation: Review the security guidance before installing and validate the capture, recall, retention, and access-control settings against the deployment environment. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/paudyyin/memory-tencentdb) <br>\n- [Publisher profile](https://clawhub.ai/user/paudyyin) <br>\n- [OpenClaw](https://github.com/openclaw/openclaw) <br>\n- [OpenClaw package source referenced by artifact](https://github.com/nicepkg/openclaw) <br>\n- [node-llama-cpp](https://github.com/withcatai/node-llama-cpp) <br>\n- [sqlite-vec](https://github.com/asg017/sqlite-vec) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown, JSON configuration, CLI commands, and agent memory search results] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May capture and recall sensitive conversation history; supports local SQLite and TencentDB vector database storage.] <br>\n\n## Skill Version(s): <br>\n0.3.6 (source: server release evidence and package.json) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v0.3.6:package.json\n\n{\r\n    \"name\":  \"memory-tencentdb\",\r\n    \"version\":  \"0.3.6\",\r\n    \"description\":  \"Four-layer local memory system plugin for OpenClaw 鈥?auto-captures, structures, and profiles conversational knowledge using local LLM + SQLite vector search (L0鈫扡1鈫扡2鈫扡3 pipeline)\",\r\n    \"type\":  \"module\",\r\n    \"main\":  \"./dist/index.mjs\",\r\n    \"bin\":  {\r\n                \"migrate-sqlite-to-tcvdb\":  \"./bin/migrate-sqlite-to-tcvdb.mjs\",\r\n                \"export-tencent-vdb\":  \"./bin/export-tencent-vdb.mjs\",\r\n                \"read-local-memory\":  \"./bin/read-local-memory.mjs\"\r\n            },\r\n    \"exports\":  {\r\n                    \".\":  {\r\n                              \"import\":  \"./dist/index.mjs\",\r\n                              \"default\":  \"./dist/index.mjs\"\r\n                          }\r\n                },\r\n    \"scripts\":  {\r\n                    \"build\":  \"npm run build:plugin \\u0026\\u0026 npm run build:scripts\",\r\n                    \"build:plugin\":  \"tsdown\",\r\n                    \"build:scripts\":  \"npm run build:migrate-sqlite-to-vdb \\u0026\\u0026 npm run build:export-tencent-vdb \\u0026\\u0026 npm run build:read-local-memory\",\r\n                    \"prepack\":  \"npm run build\",\r\n                    \"build:migrate-sqlite-to-vdb\":  \"tsc -p scripts/migrate-sqlite-to-tcvdb/tsconfig.json --noEmitOnError false\",\r\n                    \"migrate-sqlite-to-tcvdb\":  \"node ./bin/migrate-sqlite-to-tcvdb.mjs\",\r\n                    \"build:export-tencent-vdb\":  \"tsc --project scripts/export-tencent-vdb/tsconfig.json\",\r\n                    \"export-tencent-vdb\":  \"node ./bin/export-tencent-vdb.mjs\",\r\n                    \"build:read-local-memory\":  \"tsc --project scripts/read-local-memory/tsconfig.json\",\r\n                    \"read-local-memory\":  \"node ./bin/read-local-memory.mjs\",\r\n                    \"test\":  \"vitest run\",\r\n                    \"test:watch\":  \"vitest\",\r\n                    \"test:coverage\":  \"vitest run --coverage\",\r\n                    \"postinstall\":  \"bash scripts/openclaw-after-tool-call-messages.patch.sh 2\\u003e/dev/null || true\"\r\n                },\r\n    \"files\":  [\r\n                  \"dist/\",\r\n                  \"bin/\",\r\n                  \"index.ts\",\r\n                  \"scripts/migrate-sqlite-to-tcvdb/dist/\",\r\n                  \"scripts/export-tencent-vdb/dist/\",\r\n                  \"scripts/read-local-memory/dist/\",\r\n                  \"scripts/memory-tencentdb-ctl.sh\",\r\n                  \"scripts/install_hermes_memory_tencentdb.sh\",\r\n                  \"scripts/README.memory-tencentdb-ctl.md\",\r\n                  \"src/\",\r\n                  \"scripts/openclaw-after-tool-call-messages.patch.sh\",\r\n                  \"scripts/setup-offload.sh\",\r\n                  \"hermes-plugin/\",\r\n                  \"openclaw.plugin.json\",\r\n                  \"README.md\",\r\n                  \"CHANGELOG.md\",\r\n                  \"LICENSE\",\r\n                  \"!src/**/*.test.ts\",\r\n                  \"!src/**/*.spec.ts\",\r\n                  \"!src/**/__tests__/\"\r\n              ],\r\n    \"keywords\":  [\r\n                     \"openclaw\",\r\n                     \"openclaw-plugin\",\r\n                     \"memory\",\r\n                     \"ai-memory\",\r\n                     \"long-term-memory\",\r\n                     \"vector-search\",\r\n                     \"sqlite-vec\",\r\n                     \"llm\",\r\n                     \"conversation\",\r\n                     \"persona\",\r\n                     \"scene-extraction\",\r\n                     \"embedding\"\r\n                 ],\r\n    \"author\":  \"TencentDB Agent Memory Team\",\r\n    \"license\":  \"MIT\",\r\n    \"engines\":  {\r\n                    \"node\":  \"\\u003e=22.16.0\"\r\n                },\r\n    \"dependencies\":  {\r\n                         \"@ai-sdk/openai\":  \"^3.0.53\",\r\n                         \"@node-rs/jieba\":  \"^2.0.1\",\r\n                         \"@tencentdb-agent-memory/tcvdb-text\":  \"^0.1.1\",\r\n                         \"ai\":  \"^6.0.164\",\r\n                         \"js-tiktoken\":  \"^1.0.18\",\r\n                         \"json5\":  \"^2.2.3\",\r\n                         \"sqlite-vec\":  \"0.1.7-alpha.2\",\r\n                         \"tsx\":  \"^4.21.0\",\r\n                         \"undici\":  \"^8.1.0\",\r\n                         \"yaml\":  \"^2.8.3\",\r\n                         \"zod\":  \"^4.4.3\"\r\n                     },\r\n    \"optionalDependencies\":  {\r\n                                 \"opik\":  \"^1.0.0\"\r\n                             },\r\n    \"peerDependencies\":  {\r\n                             \"node-llama-cpp\":  \"^3.16.2\",\r\n                             \"openclaw\":  \"\\u003e=2026.3.7\"\r\n                         },\r\n    \"peerDependenciesMeta\":  {\r\n                                 \"openclaw\":  {\r\n                                                  \"optional\":  true\r\n                                              },\r\n                                 \"node-llama-cpp\":  {\r\n                                                        \"optional\":  true\r\n                                                    }\r\n                             },\r\n    \"openclaw\":  {\r\n                     \"extensions\":  [\r\n                                        \"./index.ts\"\r\n                                    ],\r\n                     \"compat\":  {\r\n                                    \"pluginApi\":  \"\\u003e=2026.3.13\",\r\n                                    \"minGatewayVersion\":  \"\\u003e=2026.3.13\"\r\n                                },\r\n                     \"build\":  {\r\n                                   \"openclawVersion\":  \"2026.3.13\",\r\n                                   \"pluginSdkVersion\":  \"2026.3.13\"\r\n                               },\r\n                     \"bundle\":  {\r\n                                    \"stageRuntimeDependencies\":  true\r\n                                }\r\n                 },\r\n    \"devDependencies\":  {\r\n                            \"@types/node\":  \"^25.5.2\",\r\n                            \"@vitest/coverage-v8\":  \"^4.1.2\",\r\n                            \"tsdown\":  \"^0.21.10\",\r\n                            \"typescript\":  \"^6.0.2\",\r\n                            \"vitest\":  \"^4.1.2\"\r\n                        }\r\n}\n\nArchive v0.3.5: 152 files, 768811 bytes\n\nFiles: bin/export-tencent-vdb.mjs (690b), bin/migrate-sqlite-to-tcvdb.mjs (460b), bin/read-local-memory.mjs (716b), CHANGELOG.md (15460b), dist/index.mjs (703826b), dist/l1-reader-B6GBuxTv.mjs (3670b), hermes-plugin/memory/memory_tencentdb/__init__.py (48007b), hermes-plugin/memory/memory_tencentdb/client.py (5812b), hermes-plugin/memory/memory_tencentdb/plugin.yaml (458b), hermes-plugin/memory/memory_tencentdb/README.md (14846b), hermes-plugin/memory/memory_tencentdb/supervisor.py (12058b), hermes-plugin/memory/memory_tencentdb/tests/__init__.py (0b), hermes-plugin/memory/memory_tencentdb/tests/test_gateway_shutdown_leak.py (33628b), hermes-plugin/memory/memory_tencentdb/tests/test_memory_tencentdb_recovery.py (15674b), index.ts (34874b), openclaw.plugin.json (12193b), package.json (3662b), README.md (16439b), scripts/export-tencent-vdb/dist/export-tencent-vdb.js (19330b), scripts/install_hermes_memory_tencentdb.sh (12348b), scripts/memory-tencentdb-ctl.sh (38742b), scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/cli-entry.js (400b), scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/config-write.js (2371b), scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/manifest-write.js (1353b), scripts/migrate-sqlite-to-tcvdb/dist/scripts/migrate-sqlite-to-tcvdb/sqlite-to-tcvdb.js (27095b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/profile/profile-sync.js (8136b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/record/l1-writer.js (6490b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/scene/scene-format.js (1686b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/scene/scene-index.js (2842b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/scene/scene-navigation.js (2400b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/bm25-local.js (2264b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/embedding.js (19027b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/sqlite.js (80300b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/tcvdb-client.js (9517b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/tcvdb.js (43647b), scripts/migrate-sqlite-to-tcvdb/dist/src/core/store/types.js (850b), scripts/migrate-sqlite-to-tcvdb/dist/src/profile/profile-sync.js (6894b), scripts/migrate-sqlite-to-tcvdb/dist/src/record/l1-writer.js (6490b), scripts/migrate-sqlite-to-tcvdb/dist/src/scene/scene-format.js (1686b), scripts/migrate-sqlite-to-tcvdb/dist/src/scene/scene-index.js (2842b), scripts/migrate-sqlite-to-tcvdb/dist/src/scene/scene-navigation.js (2084b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/bm25-local.js (2264b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/embedding.js (18904b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/sqlite.js (80297b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/tcvdb-client.js (8766b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/tcvdb.js (43647b), scripts/migrate-sqlite-to-tcvdb/dist/src/store/types.js (850b), scripts/migrate-sqlite-to-tcvdb/dist/src/utils/manifest.js (3264b), scripts/migrate-sqlite-to-tcvdb/README.md (8293b), scripts/openclaw-after-tool-call-messages.patch.sh (15460b), scripts/read-local-memory/dist/read-local-memory.js (34263b), scripts/README.memory-tencentdb-ctl.md (17355b), scripts/setup-offload.sh (14013b), skill-card.md (2889b), SKILL.md (2402b), src/adapters/index.ts (931b), src/adapters/openclaw/host-adapter.ts (3443b), src/adapters/openclaw/index.ts (325b), src/adapters/openclaw/llm-runner.ts (3201b), src/adapters/standalone/host-adapter.ts (2598b), src/adapters/standalone/index.ts (358b), src/adapters/standalone/llm-runner.ts (10869b), src/cli/commands/seed.ts (10485b), src/cli/index.ts (1883b), src/cli/README.md (4674b), src/config.ts (25914b), src/core/conversation/l0-recorder.ts (22156b), src/core/hooks/auto-capture.ts (14826b), src/core/hooks/auto-recall.ts (32080b), src/core/index.ts (613b), src/core/persona/persona-generator.ts (9108b), src/core/persona/persona-trigger.ts (4368b), src/core/profile/profile-sync.ts (8222b), src/core/prompts/l1-dedup.ts (7120b), src/core/prompts/l1-extraction.ts (6275b), src/core/prompts/persona-generation.ts (8053b), src/core/prompts/scene-extraction.ts (14452b), src/core/record/l1-dedup.ts (14909b), src/core/record/l1-extractor.ts (18264b), src/core/record/l1-reader.ts (6512b)\n\nFile v0.3.5:SKILL.md\n\n---\nname: memory-tencentdb\ndescription: 四层记忆系统插件 — 自动捕获对话、提取结构化记忆、归纳场景、生成用户画像。支持 L0→L1→L2→L3 渐进式管线，本地 SQLite + 腾讯云向量数据库双后端。\nversion: 0.3.5\ntags: [\"memory\", \"long-term-memory\", \"llm\", \"persona\", \"sqlite\", \"vector-search\"]\nauthor: paudyyin\n---\n\n# memory-tencentdb — 四层记忆系统\n\n为 OpenClaw AI Agent 提供 L0→L1→L2→L3 长期记忆能力。\n\n## 架构\n\n```\n对话开始\n  → Auto-Recall: 向量/混合搜索相关记忆 + 加载 Persona → 注入系统上下文\n\n对话结束\n  → L0: 录制对话消息 → SQLite + JSONL 双写\n  → Pipeline Scheduler: 达到 N 轮后触发\n     ├── L1: LLM 提取结构化记忆 + 向量去重 → JSONL + SQLite\n     ├── L2: LLM 归纳场景块 → Markdown 文件\n     └── L3: LLM 生成/更新用户画像 → persona.md\n```\n\n## 四层记忆\n\n| 层级 | 名称 | 说明 |\n|------|------|------|\n| L0 | 对话录制 | 原始对话消息捕获 |\n| L1 | 记忆提取 | 结构化记忆（persona/episodic/instruction） |\n| L2 | 场景归纳 | 场景块（Scene Block） |\n| L3 | 用户画像 | 用户人格画像（Persona） |\n\n## 记忆类型\n\n- **persona**：用户的稳定属性、偏好、技能、价值观\n- **episodic**：客观发生的动作、决定、计划或结果\n- **instruction**：用户对 AI 的长期行为规则\n\n## 安装\n\n```bash\nclawhub install memory-tencentdb\n```\n\n## 配置\n\n在 openclaw.json 中添加：\n\n```json\n{\n  \"plugins\": {\n    \"allow\": [\"mx\", \"memory-tencentdb\"],\n    \"load\": {\n      \"paths\": [\"<插件路径>\"]\n    },\n    \"entries\": {\n      \"memory-tencentdb\": {\n        \"enabled\": true,\n        \"config\": {\n          \"llm\": {\n            \"enabled\": true,\n            \"baseUrl\": \"https://你的LLM端点/v1\",\n            \"model\": \"你的模型ID\"\n          },\n          \"pipeline\": {\n            \"everyNConversations\": 3\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n## 存储后端\n\n- `sqlite`（默认）：本地 SQLite + sqlite-vec\n- `tcvdb`：腾讯云向量数据库\n\n## CLI 命令\n\n```bash\nopenclaw memory-tdai seed --input conversations.json\n```\n\n## 故障排查\n\n如果 L1 提取为空：\n1. 检查 `plugins.allow` 包含 `\"memory-tencentdb\"`\n2. 检查 `plugins.load.paths` 包含插件路径\n3. 检查 `llm.enabled` 为 `true`\n4. 检查 LLM 端点可访问\n\nFile v0.3.5:hermes-plugin/memory/memory_tencentdb/README.md\n\n# memory-tencentdb Memory Provider (Hermes)\n\nHermes-side [`MemoryProvider`](../../../../../hermes-agent/agent/memory_provider.py)\nadapter for the **memory-tencentdb** four-layer memory system\n(L0 conversation capture → L1 episodic extraction → L2 scene blocks → L3 persona synthesis).\n\nThe heavy lifting — capture, extraction, storage, recall, pipeline scheduling —\nruns in a Node.js **Gateway** sidecar (shipped by the same package as the\nOpenClaw plugin). This Python provider is a thin HTTP client + process\nsupervisor that plugs the Gateway into Hermes's lifecycle.\n\n## Architecture\n\n```\nHermes Agent (Python)\n  └─ MemoryManager\n       └─ MemoryTencentdbProvider        (this directory)\n            ├─ GatewaySupervisor          — starts / health-checks the sidecar\n            └─ MemoryTencentdbSdkClient   — POST /recall, /capture, /search/*, /session/end\n                    │\n                    ▼  HTTP (127.0.0.1:8420 by default)\n            memory-tencentdb Gateway (Node.js)\n               └─ memory-tencentdb Core\n                    ├─ L0  Conversation store      (SQLite / TCVDB + JSONL)\n                    ├─ L1  Episodic extraction     (LLM + vector dedup)\n                    ├─ L2  Scene blocks            (Markdown under data dir)\n                    ├─ L3  Persona synthesis       (persona.md)\n                    └─ Storage backends: SQLite + sqlite-vec  OR  Tencent VectorDB\n```\n\nHermes lifecycle → Gateway mapping:\n\n| Hermes hook / call          | Gateway endpoint | Behavior                                                   |\n|-----------------------------|------------------|------------------------------------------------------------|\n| `prefetch(query)`           | `POST /recall`   | Synchronous. Returns `<memory-context>` text for injection |\n| `sync_turn(user, assistant)`| `POST /capture`  | Fire-and-forget on a background daemon thread (max 4 in-flight) |\n| `shutdown()` / `on_session_end` | `POST /session/end` | Flush pending pipeline work                             |\n| `get_tool_schemas()`        | —                | Advertises two LLM tools (see below)                       |\n\nReliability features baked into the provider:\n\n- **Circuit breaker** — 5 consecutive Gateway failures → pause all calls for 60 s.\n- **Back-pressure on capture** — at most 4 in-flight `sync_turn` threads; a 5th\n  waits up to 5 s for the oldest one before starting (Gateway hangs can't grow\n  threads unboundedly).\n- **Supervised startup** — if `MEMORY_TENCENTDB_GATEWAY_CMD` is set (or the\n  provider auto-discovers `src/gateway/server.ts`, see below), it starts the\n  sidecar, polls `/health` for up to 30 s, and tails `gateway.stderr.log` on\n  crash for diagnostics.\n- **Zero-config auto-discovery** — when `MEMORY_TENCENTDB_GATEWAY_CMD` is\n  unset, the provider looks for `src/gateway/server.ts` next to the plugin\n  checkout (in-tree) and, as a last resort, under\n  `~/.memory-tencentdb/tdai-memory-openclaw-plugin/` (preferred),\n  `~/tdai-memory-openclaw-plugin/` (legacy), and\n  `~/.hermes/plugins/tdai-memory-openclaw-plugin/`.\n  A fresh `git clone` therefore usually works without any extra env wiring —\n  override with the env var when you need a non-standard layout.\n\n## Installation Location\n\nThis directory (`hermes-plugin/memory/memory_tencentdb/`) is the **source of\ntruth** for the provider; Hermes does **not** load it from here. At startup\nHermes scans two locations for memory providers, in precedence order (see\n`hermes-agent/plugins/memory/__init__.py`):\n\n1. **Bundled** — `<hermes-agent-checkout>/plugins/memory/<name>/`\n   **This is the path memory_tencentdb ships under.** It sits alongside the\n   other in-tree providers (`byterover/`, `honcho/`, `mem0/`, `hindsight/`,\n   …). Bundled entries take precedence over user-installed ones on name\n   collision.\n2. **User-installed** — `$HERMES_HOME/plugins/<name>/`, where\n   `$HERMES_HOME` defaults to `~/.hermes` (see\n   `hermes_constants.get_hermes_home()`). This path is for third-party\n   providers; we don't use it for memory_tencentdb.\n\n**The trailing directory name must be exactly `memory_tencentdb`** — Hermes\nuses that directory name as the provider key; it must match\n`plugin.yaml::name` and the value of `memory.provider` in `config.yaml`.\n(The hyphenated form `memory-tencentdb` is a *config-side alias*, not a\nvalid directory name.)\n\nPick one of the two installation styles:\n\n**Install A — symlink (recommended for developers working on both repos\nsimultaneously):** keeps this repo as the single source of truth so\n`git pull` in the plugin repo is immediately visible to Hermes.\n\n```bash\n# from the tdai-memory-openclaw-plugin checkout:\nln -s \"$(pwd)/hermes-plugin/memory/memory_tencentdb\" \\\n      <hermes-agent-checkout>/plugins/memory/memory_tencentdb\n```\n\n**Install B — copy (shipped alongside hermes-agent):** freezes a specific\nversion of the provider inside the hermes-agent tree. This is how\nmemory_tencentdb is currently vendored in this repo pair — the two copies\nunder `tdai-memory-openclaw-plugin/hermes-plugin/memory/memory_tencentdb/`\nand `hermes-agent/plugins/memory/memory_tencentdb/` are kept in sync\nmanually.\n\n```bash\ncp -r tdai-memory-openclaw-plugin/hermes-plugin/memory/memory_tencentdb \\\n      hermes-agent/plugins/memory/memory_tencentdb\n```\n\nVerify Hermes sees the provider:\n\n```bash\n$ cd <hermes-agent-checkout>\n$ python -c 'from plugins.memory import discover_memory_providers; \\\n             [print(n, a) for n, _, a in discover_memory_providers()]'\nmemory_tencentdb True\n...\n```\n\nIf the provider does not appear:\n- confirm the target path is `hermes-agent/plugins/memory/memory_tencentdb/`\n  (underscore, not hyphen);\n- confirm `__init__.py` and `plugin.yaml` sit directly inside that dir;\n- the discovery scan requires `__init__.py` to contain the literal string\n  `MemoryProvider` or `register_memory_provider` — both are present in\n  this provider, so this is a non-issue as long as the file is the one\n  from this repo.\n\n> The **Gateway source code** (Node.js sidecar under `src/gateway/`) stays\n> in the `tdai-memory-openclaw-plugin` checkout and does NOT need to be\n> copied into hermes-agent — the Python provider auto-discovers it via\n> the paths listed in Option A below, or via `MEMORY_TENCENTDB_GATEWAY_CMD`.\n\n## Setup\n\n### 1. Activate in Hermes (`~/.hermes/config.yaml`)\n\n```yaml\nmemory:\n  provider: memory_tencentdb   # canonical name\n  # Aliases accepted for backward compatibility: `memory-tencentdb`, `tdai`\n```\n\n### 2. Provide Gateway runtime + LLM credentials\n\nAt minimum the Gateway needs an OpenAI-compatible endpoint for L1/L2/L3\nextraction. Set these in the Hermes process environment:\n\n```bash\nexport MEMORY_TENCENTDB_LLM_API_KEY=\"sk-...\"\nexport MEMORY_TENCENTDB_LLM_BASE_URL=\"https://api.openai.com/v1\"   # optional\nexport MEMORY_TENCENTDB_LLM_MODEL=\"gpt-4o\"                         # optional\n```\n\n### 3. Start the Gateway\n\nYou have three options; pick whichever fits your deployment.\n\n**Option A — Auto-discovery (zero-config).** If the plugin checkout sits at\none of the well-known paths, the provider will find `src/gateway/server.ts`\non its own and `Popen()` it as `node --import tsx <path>`. Searched paths, in\norder:\n\n1. In-tree: `<plugin-root>/src/gateway/server.ts` (when Hermes loads this\n   provider from a checkout of this repo).\n2. `~/.memory-tencentdb/tdai-memory-openclaw-plugin/src/gateway/server.ts` (preferred install location)\n3. `~/tdai-memory-openclaw-plugin/src/gateway/server.ts` (legacy)\n4. `~/.hermes/plugins/tdai-memory-openclaw-plugin/src/gateway/server.ts`\n\nNo environment variables required beyond the LLM credentials above. A line\nlike\n\n```\nINFO plugins.memory.memory_tencentdb: memory-tencentdb Gateway command auto-discovered: /…/src/gateway/server.ts\n```\n\nwill appear in `~/.hermes/logs/agent.log` on startup.\n\n**Option B — Explicit auto-start.** Override or disable discovery by setting\nthe command yourself:\n\n```bash\nexport MEMORY_TENCENTDB_GATEWAY_CMD=\"node --import tsx /abs/path/to/tdai-memory-openclaw-plugin/src/gateway/server.ts\"\n```\n\nThe provider will `Popen()` this command on `initialize()`, wait for\n`GET /health` to report `ok`/`degraded`, and tail stderr on crash.\n\n**Option C — Run it yourself.** Start the Gateway separately on the default\nport (`127.0.0.1:8420`) before launching Hermes; the provider will detect it\nvia `/health` and skip the subprocess-launch path.\n\n```bash\ncd tdai-memory-openclaw-plugin\nnode --import tsx src/gateway/server.ts\n```\n\n> Storage backend (SQLite vs Tencent VectorDB), embedding config, pipeline\n> cadence, recall strategy, etc. are all **Gateway-side** settings. For\n> OpenClaw installs they live in `~/.openclaw/openclaw.json`; for standalone\n> Hermes deployments configure the Gateway via its own config file or env.\n> See the plugin's top-level [README](../../../README.md) for the full\n> configuration schema.\n\n## Environment Variables\n\n### Gateway location\n\n| Variable                          | Default             | Description                                               |\n|-----------------------------------|---------------------|-----------------------------------------------------------|\n| `MEMORY_TENCENTDB_GATEWAY_HOST`   | `127.0.0.1`         | Gateway host                                              |\n| `MEMORY_TENCENTDB_GATEWAY_PORT`   | `8420`              | Gateway port (must be 1..65535; invalid values fall back) |\n| `MEMORY_TENCENTDB_GATEWAY_CMD`    | —                   | If set, the provider auto-starts the Gateway with this command. If unset, the provider auto-discovers `src/gateway/server.ts` next to the checkout or under `$HOME` (see Option A above) |\n| `MEMORY_TENCENTDB_LOG_DIR`        | `~/.hermes/logs/memory_tencentdb` | Where the supervisor writes `gateway.stdout.log` / `gateway.stderr.log` |\n\n### Gateway data directory (owned by the Gateway, not this provider)\n\nThe L0~L3 data directory is resolved **inside the Gateway** (`src/gateway/config.ts`),\nnot here. Priority:\n\n1. `TDAI_DATA_DIR` env var\n2. `data.baseDir` from a `tdai-gateway.yaml` / `tdai-gateway.json` config file\n3. Default: `~/.memory-tencentdb/memory-tdai`\n   (Override the parent dir with `MEMORY_TENCENTDB_ROOT` if needed.)\n4. Legacy fallback: if `~/.memory-tencentdb/memory-tdai` does not exist but the\n   pre-0.4 location `~/memory-tdai` does, the Gateway keeps using the legacy\n   dir and prints a one-line deprecation warning to stderr. Run\n   `install_hermes_memory_tencentdb.sh` to migrate it automatically.\n\nHermes forwards the inherited environment to the Gateway subprocess, so\nsetting `TDAI_DATA_DIR` before launching Hermes is enough to override it.\nThe old `MEMORY_TENCENTDB_DATA_DIR` env var is no longer read — it was never\nconsumed by the Gateway anyway (names did not match), so removing it just\neliminates a silent no-op.\n\n### Gateway LLM (consumed by the Node sidecar, not by this provider)\n\n| Variable                          | Default                      | Description                         |\n|-----------------------------------|------------------------------|-------------------------------------|\n| `MEMORY_TENCENTDB_LLM_API_KEY`    | —                            | LLM API key (required for L1/L2/L3) |\n| `MEMORY_TENCENTDB_LLM_BASE_URL`   | `https://api.openai.com/v1`  | OpenAI-compatible API base URL      |\n| `MEMORY_TENCENTDB_LLM_MODEL`      | `gpt-4o`                     | Model name                          |\n\n> ⚠️ Only `MEMORY_TENCENTDB_*` env vars are honored by this provider for the\n> Gateway location and LLM credentials. Data-directory resolution is\n> deliberately delegated to the Gateway via `TDAI_DATA_DIR` (see above) so\n> the provider and the Gateway can never disagree about where L0~L3 live.\n\n## LLM Tools\n\nThis provider exposes two tools to the model via `get_tool_schemas()`:\n\n| Tool                                   | Purpose                                           | Args                                            |\n|----------------------------------------|---------------------------------------------------|-------------------------------------------------|\n| `memory_tencentdb_memory_search`       | Search L1 structured long-term memories           | `query` (required), `limit` (1..20, default 5), `type` (`persona`/`episodic`/`instruction`) |\n| `memory_tencentdb_conversation_search` | Search L0 raw conversation history                | `query` (required), `limit` (1..20, default 5)  |\n\nTool-call arguments are defensively coerced: `limit` accepts ints, numeric\nstrings, and floats, rejects bools, and is clamped to `[1, 20]` with a\nwarning on garbage input.\n\n> These are the **only** tool names registered with the LLM. The old\n> `tdai_memory_search` / `tdai_conversation_search` names are not served by\n> this provider — if older transcripts reference them, `handle_tool_call`\n> will return an \"Unknown tool\" error.\n\n## Plugin Metadata (`plugin.yaml`)\n\n```yaml\nname: memory_tencentdb            # canonical provider name\ndisplay_name: memory-tencentdb\nhooks:\n  - on_memory_write               # reserved; not yet mirrored to the Gateway\n  - on_session_end                # triggers POST /session/end\naliases:\n  - tdai                          # legacy config value still resolves here\n  - memory-tencentdb              # hyphenated form resolves here too\n```\n\n## Troubleshooting\n\n- **\"memory-tencentdb Gateway not available\"** on startup: either\n  `MEMORY_TENCENTDB_GATEWAY_CMD` is unset *and* auto-discovery did not find\n  `src/gateway/server.ts` *and* nothing is listening on `8420`, or the\n  sidecar crashed. Check `~/.hermes/logs/memory_tencentdb/gateway.stderr.log`\n  (override with `MEMORY_TENCENTDB_LOG_DIR`). To confirm auto-discovery was\n  attempted, enable `DEBUG` logging and look for\n  `memory-tencentdb Gateway auto-discovery found no server.ts under: …`;\n  that log line enumerates every path that was searched.\n- **Gateway starts from the wrong checkout**: auto-discovery walks a fixed\n  preference list (in-tree first, then `$HOME`). If you want to pin a\n  specific path, set `MEMORY_TENCENTDB_GATEWAY_CMD` explicitly — it always\n  wins over discovery.\n- **Search tools silently missing from the LLM**: `get_tool_schemas()`\n  returns `[]` until either the Gateway is reachable or one of\n  `MEMORY_TENCENTDB_GATEWAY_CMD` / `MEMORY_TENCENTDB_GATEWAY_PORT` is set\n  in the environment. Set the env var so the tools are advertised\n  optimistically at registration time.\n- **\"circuit breaker tripped\"** warnings: five consecutive Gateway errors\n  were observed. Calls are paused for 60 s; check Gateway health and logs.\n- **Capture backlog warnings**: Gateway is slow or hung — `sync_turn` is\n  tracking ≥ 4 in-flight threads. Inspect Gateway logs for stuck L1\n  extractions or LLM timeouts.\n\nFile v0.3.5:README.md\n\n# @tencentdb-agent-memory/memory-tencentdb\n\n**Four-layer memory system plugin for [OpenClaw](https://github.com/openclaw/openclaw).**\n\n为 AI Agent 提供长期记忆能力。通过 L0→L1→L2→L3 四层渐进式管线，自动将对话内容提炼为结构化记忆、场景块和用户画像。支持纯本地 SQLite 和远端腾讯云向量数据库（TCVDB）两种存储后端。\n\n## ✨ 核心功能\n\n- **L0 — 对话录制**：自动捕获每轮对话原始消息，IMemoryStore + JSONL 双写\n- **L1 — 记忆提取**：由 LLM 从对话中提取结构化记忆，支持向量去重与冲突检测\n- **L2 — 场景归纳**：基于 L1 记忆自动归纳场景块（Scene Block），由 LLM 增量提取\n- **L3 — 用户画像**：基于场景块自动生成/更新用户画像（Persona）\n- **自动召回（Auto-Recall）**：对话开始前自动注入相关记忆和用户画像到上下文\n- **多后端存储**：支持 `sqlite`（本地 SQLite + sqlite-vec）和 `tcvdb`（腾讯云向量数据库，服务端 embedding + hybridSearch）\n- **BM25 稀疏向量**：内置 BM25 编码器（tcvdb-text），支持中英文混合搜索\n- **关键词+向量混合搜索**：hybrid（关键词 + 向量 RRF 融合）搜索策略\n- **语义搜索工具**：Agent 可调用 `tdai_memory_search`（L1 记忆搜索）和 `tdai_conversation_search`（L0 对话搜索）\n- **Seed CLI**：`openclaw memory-tdai seed` 命令，支持导入历史对话数据（详见 [CLI 文档](src/cli/README.md)）\n- **Session 隔离**：不同渠道/Agent 的对话独立调度、独立提取\n- **本地数据清理**：可配置 L0/L1 数据保留天数，定时自动清理过期文件\n- **Manifest 元数据**：数据目录自动生成 `.metadata/manifest.json`，记录 store 绑定信息和 seed 运行记录\n- **支持零配置**：支持零配置工作，简单易用\n\n## 🏗️ 关键原理\n\n```\n对话开始\n  → Auto-Recall: 向量/混合搜索相关记忆 + 加载 Persona → 注入系统上下文\n\n对话结束\n  → Auto-Capture (L0): 录制对话消息 → IMemoryStore (SQLite/TCVDB) + JSONL 双写\n  → Pipeline Scheduler: 达到 N 轮后按序触发 L1 → L2 → L3\n     ├── L1: LLM 提取结构化记忆 + 向量去重 → 写入 JSONL + IMemoryStore\n     ├── L2: LLM 归纳场景块 → Markdown 文件\n     └── L3: LLM 生成/更新用户画像 → persona.md\n```\n\n### 数据目录结构\n\n```\n<pluginDataDir>/\n├── conversations/     — L0 每日 JSONL 分片（每行一条消息）\n├── records/           — L1 每日 JSONL 分片（提取的记忆）\n├── scene_blocks/      — L2 场景块 .md 文件\n├── vectors.db         — SQLite + vec0 向量数据库（仅 storeBackend=sqlite）\n├── .metadata/\n│   ├── manifest.json  — 数据目录元数据（store 绑定、seed 信息）\n│   └── checkpoint.json\n└── .backup/           — 滚动备份（persona, scene_blocks）\n```\n\n## 🚀 Quick Start（Docker）\n\n使用预构建的 Docker 镜像，一行命令即可启动带记忆能力的 Hermes Agent：\n\n```bash\ndocker run -d \\\n  --name hermes-memory \\\n  --restart unless-stopped \\\n  -p 8420:8420 \\\n  -e MODEL_API_KEY=\"your-api-key\" \\\n  -e MODEL_BASE_URL=\"https://api.lkeap.cloud.tencent.com/v1\" \\\n  -e MODEL_NAME=\"deepseek-v3.2\" \\\n  -e MODEL_PROVIDER=\"custom\" \\\n  -v hermes_data:/opt/data \\\n  agentmemory/hermes-memory:latest\n```\n\n镜像支持 `linux/amd64` 和 `linux/arm64` 架构。内置腾讯云 DeepSeek-V3.2 默认值，如使用该模型可省略 `MODEL_BASE_URL`/`MODEL_NAME`/`MODEL_PROVIDER`，只传 `MODEL_API_KEY` 即可。\n\n### 环境变量\n\n#### 统一模型配置（Hermes + TDAI 共用）\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `MODEL_API_KEY` | - | LLM API Key（**必填**） |\n| `MODEL_BASE_URL` | `https://api.lkeap.cloud.tencent.com/v1` | LLM API 地址 |\n| `MODEL_NAME` | `deepseek-v3.2` | 模型名称 |\n| `MODEL_PROVIDER` | `custom` | 模型 provider：`custom` / `openrouter` / `anthropic` / `openai` / `gemini` |\n\n#### 服务配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `TDAI_GATEWAY_PORT` | `8420` | Gateway 端口 |\n| `TDAI_GATEWAY_HOST` | `0.0.0.0` | Gateway 绑定地址 |\n| `TDAI_DATA_DIR` | `/opt/data/tdai-memory` | 记忆数据目录 |\n| `HERMES_HOME` | `/opt/data` | Hermes 数据目录 |\n\n### 验证运行\n\n```bash\n# 验证 Gateway 健康状态\ncurl http://localhost:8420/health\n\n# 进入 Hermes 对话\ndocker exec -it hermes-memory hermes\n\n# 查看容器日志\ndocker logs -f hermes-memory\n```\n\n> 更多配置选项和集成说明请参考下文。\n\n---\n\n## 📋 前置依赖\n\n| 依赖 | 版本要求 | 说明 |\n|------|---------|------|\n| [OpenClaw](https://github.com/nicepkg/openclaw) | `>= 2026.3.13` | 宿主框架，提供插件 SDK 及 Gateway 运行环境 |\n| [Node.js](https://nodejs.org/) | `>= 22.16.0` | 运行时环境 |\n| [`node-llama-cpp`](https://github.com/withcatai/node-llama-cpp) | `^3.16.2` | 本地 embedding 模型（GGUF 格式），提供离线向量化能力（仅 sqlite 后端需要） |\n| [`sqlite-vec`](https://github.com/asg017/sqlite-vec) | `0.1.7-alpha.2` | SQLite 向量搜索扩展（仅 sqlite 后端需要） |\n| [`tcvdb-text`](../../../packages/tcvdb-text) | `workspace:*` | BM25 稀疏向量编码器，支持中英文分词（仅 tcvdb 后端需要） |\n\n> 默认场景下无需安装 `node-llama-cpp`。如需启用本地 embedding，再在宿主环境手动安装该包。\n\n## 📦 安装\n\n```bash\n# 安装插件\nopenclaw plugins install @tencentdb-agent-memory/memory-tencentdb\n\n# 更新插件\nopenclaw plugins update memory-tencentdb\n\n# 卸载插件\nopenclaw plugins uninstall memory-tencentdb\n```\n\n安装完成后，**重启 Gateway** 使插件生效：\n\n```bash\nopenclaw gateway restart\n```\n\n## ⚙️ 配置\n\n插件配置位于 `~/.openclaw/openclaw.json` 中 `memory-tencentdb` 字段下。**所有字段均有合理默认值，零配置即可使用。**\n\n### 最小配置\n\n安装启用后即为该状态（默认使用本地 SQLite 后端）：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"enabled\": true\n  }\n}\n```\n\n> **⚠️ 重要：`allowPromptInjection` 必须为 `true`**\n>\n> 本插件通过 `before_prompt_build` hook 在对话开始前将召回的记忆注入系统上下文。\n> OpenClaw v2026.4.5+ 新增了 `allowPromptInjection` 安全控制，当该选项设为 `false` 时，\n> `before_prompt_build` hook 将被**完全阻止注册**，导致记忆召回静默失效（不会报错，仅有 warn 日志）。\n>\n> 请确保 `openclaw.json` 中**不要**将该插件的 `allowPromptInjection` 设为 `false`：\n>\n> ```jsonc\n> // ❌ 错误配置 — 会导致记忆召回完全失效\n> {\n>   \"plugins\": {\n>     \"entries\": {\n>       \"memory-tencentdb\": {\n>         \"hooks\": { \"allowPromptInjection\": false }\n>       }\n>     }\n>   }\n> }\n>\n> ```\n\n### TCVDB 后端配置\n\n使用腾讯云向量数据库作为存储后端：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"storeBackend\": \"tcvdb\",\n    \"tcvdb\": {\n      \"url\": \"http://your-vdb-instance:8100\",\n      \"apiKey\": \"your-api-key\",\n      \"database\": \"my_memory_db\",\n      \"alias\": \"生产环境\"\n    }\n  }\n}\n```\n\n### 完整配置\n\n用户可按需配置，提升使用体验：\n\n```json\n{\n  \"memory-tencentdb\": {\n    \"storeBackend\": \"sqlite\",\n    \"capture\": {\n      \"enabled\": true,\n      \"excludeAgents\": [\"bench-judge-*\"],\n      \"l0l1RetentionDays\": 90,\n      \"allowAggressiveCleanup\": false,\n      \"cleanTime\": \"03:00\"\n    },\n    \"extraction\": {\n      \"enabled\": true,\n      \"enableDedup\": true,\n      \"maxMemoriesPerSession\": 20,\n      \"model\": \"provider/model-name\"\n    },\n    \"persona\": {\n      \"triggerEveryN\": 50,\n      \"maxScenes\": 15,\n      \"backupCount\": 3,\n      \"sceneBackupCount\": 10,\n      \"model\": \"provider/model-name\"\n    },\n    \"pipeline\": {\n      \"everyNConversations\": 5,\n      \"enableWarmup\": true,\n      \"l1IdleTimeoutSeconds\": 600,\n      \"l2DelayAfterL1Seconds\": 10,\n      \"l2MinIntervalSeconds\": 900,\n      \"l2MaxIntervalSeconds\": 3600,\n      \"sessionActiveWindowHours\": 24\n    },\n    \"recall\": {\n      \"enabled\": true,\n      \"maxResults\": 5,\n      \"scoreThreshold\": 0.3,\n      \"strategy\": \"hybrid\",\n      \"timeoutMs\": 5000\n    },\n    \"embedding\": {\n      \"enabled\": true,\n      \"provider\": \"none\",\n      \"baseUrl\": \"https://your-embedding-endpoint/v1\",\n      \"apiKey\": \"your-api-key\",\n      \"model\": \"text-embedding-3-small\",\n      \"dimensions\": 1536,\n      \"conflictRecallTopK\": 5,\n      \"maxInputChars\": 5000,\n      \"timeoutMs\": 10000\n    },\n    \"tcvdb\": {\n      \"url\": \"http://your-vdb-instance:8100\",\n      \"username\": \"root\",\n      \"apiKey\": \"your-api-key\",\n      \"database\": \"my_memory_db\",\n      \"alias\": \"生产环境\",\n      \"embeddingModel\": \"bge-large-zh\",\n      \"timeout\": 10000\n    },\n    \"bm25\": {\n      \"enabled\": true,\n      \"language\": \"zh\"\n    }\n  }\n}\n```\n\n### 配置说明\n\n#### storeBackend — 存储后端\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `storeBackend` | string | `\"sqlite\"` | 存储后端：`sqlite`（本地 SQLite + sqlite-vec）或 `tcvdb`（腾讯云向量数据库） |\n\n#### capture — 对话捕获 (L0)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用自动对话捕获 |\n| `excludeAgents` | string[] | `[]` | Agent 排除 glob 模式列表，匹配的 agent 不参与捕获/召回/调度 |\n| `l0l1RetentionDays` | number | `0` | L0/L1 本地文件保留天数。`0` = 不清理；非 0 时需 >= 3（除非开启 `allowAggressiveCleanup`） |\n| `allowAggressiveCleanup` | boolean | `false` | 是否允许 1-2 天的高风险清理配置 |\n| `cleanTime` | string | `\"03:00\"` | 每日清理执行时间（HH:mm 格式） |\n\n#### extraction — 记忆提取 (L1)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用后台记忆提取 |\n| `enableDedup` | boolean | `true` | 启用 L1 智能去重（基于向量相似度或关键词进行冲突检测） |\n| `maxMemoriesPerSession` | number | `20` | 单次 L1 提取每 session 最大记忆条数 |\n| `model` | string | *(OpenClaw 默认模型)* | 提取使用模型（格式：`provider/model`），未填写时使用 OpenClaw 默认模型 |\n\n#### pipeline — 管线调度 (L1→L2→L3)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `everyNConversations` | number | `5` | 每 N 轮对话触发一次 L1 批处理 |\n| `enableWarmup` | boolean | `true` | Warm-up 模式：新 session 从 1 轮触发开始，每次 L1 后翻倍（1→2→4→...→N） |\n| `l1IdleTimeoutSeconds` | number | `600` | 用户停止对话后多久触发 L1（秒） |\n| `l2DelayAfterL1Seconds` | number | `10` | L1 完成后延迟多久触发 L2（秒） |\n| `l2MinIntervalSeconds` | number | `900` | 同一 session 两次 L2 的最小间隔（秒） |\n| `l2MaxIntervalSeconds` | number | `3600` | 活跃 session 的 L2 最大轮询间隔（秒） |\n| `sessionActiveWindowHours` | number | `24` | 超过此时间不活跃的 session 停止 L2 轮询 |\n\n#### recall — 记忆召回\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用对话前自动召回 |\n| `maxResults` | number | `5` | 召回最大结果数 |\n| `scoreThreshold` | number | `0.3` | 最低分数阈值 |\n| `strategy` | string | `\"hybrid\"` | 搜索策略：`keyword`（关键词）、`embedding`（向量）、`hybrid`（混合 RRF 融合，推荐） |\n| `timeoutMs` | number | `5000` | 整体召回超时（毫秒）。超时后跳过记忆注入并输出 warn 日志，避免阻塞用户对话 |\n\n#### embedding — 向量搜索（仅 sqlite 后端）\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用向量搜索（若 `provider=\"none\"`，则实际会被禁用） |\n| `provider` | string | `\"none\"` | Embedding 服务提供者：`none` 表示禁用向量；其他值（如 `openai`、`deepseek`）按 OpenAI 兼容远端服务处理 |\n| `baseUrl` | string | — | API Base URL（远端模式必填） |\n| `apiKey` | string | — | API Key（远端模式必填） |\n| `model` | string | — | 模型名称（远端模式必填） |\n| `dimensions` | number | — | 向量维度（远端模式必填，需与模型匹配） |\n| `conflictRecallTopK` | number | `5` | 冲突检测时召回 Top-K 数 |\n| `maxInputChars` | number | `5000` | Embedding 输入文本最大字符数，超出时截断并打印警告日志（适合大多数模型的 token 上限） |\n| `timeoutMs` | number | `10000` | 单次 embedding API 调用超时（毫秒）。超时后该次 embedding 请求中止，不重试 |\n\n#### tcvdb — 腾讯云向量数据库（仅 storeBackend=tcvdb）\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `url` | string | — | 实例 URL（必填，如 `http://10.0.1.1:8100`） |\n| `username` | string | `\"root\"` | 账户名 |\n| `apiKey` | string | — | API Key（必填） |\n| `database` | string | — | 数据库名（必填，需唯一） |\n| `alias` | string | — | 用户友好别名（可选，记录在 manifest 中便于识别） |\n| `embeddingModel` | string | `\"bge-large-zh\"` | 服务端 embedding 模型 |\n| `timeout` | number | `10000` | 请求超时（毫秒） |\n\n#### bm25 — BM25 稀疏向量编码\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `true` | 是否启用 BM25 稀疏向量编码 |\n| `language` | string | `\"zh\"` | 分词语言：`zh`（中文 jieba）或 `en`（英文） |\n| `maxInputChars` | number | `5000` | Embedding 输入文本最大字符数，超出时截断并打印警告日志（适合大多数模型的 token 上限） |\n| `timeoutMs` | number | `10000` | 单次 embedding API 调用超时（毫秒）。超时后该次 embedding 请求中止，不重试 |\n\n#### persona — 场景归纳与用户画像 (L2/L3)\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `triggerEveryN` | number | `50` | 每 N 条新记忆触发一次画像生成 |\n| `maxScenes` | number | `15` | 最大场景块数量 |\n| `backupCount` | number | `3` | 画像备份保留数量 |\n| `sceneBackupCount` | number | `10` | 场景块备份保留数量 |\n| `model` | string | *(OpenClaw 默认模型)* | L2/L3 使用模型（格式：`provider/model`），未填写时使用 OpenClaw 默认模型 |\n\n#### report — 指标上报\n\n| 字段 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `enabled` | boolean | `false` | 是否启用指标上报（通过 Gateway 日志输出结构化 METRIC JSON） |\n| `type` | string | `\"local\"` | 上报方式：`local` 表示通过 logger 输出结构化 JSON 日志 |\n\n## 🖥️ CLI 命令\n\n插件提供 `openclaw memory-tdai` 命令空间，支持以下子命令：\n\n### `seed` — 导入历史对话数据\n\n将历史对话 JSON 文件导入到记忆管线中，完整执行 L0→L1→L2→L3 流程。\n\n```bash\nopenclaw memory-tdai seed --input conversations.json [--output-dir ./output] [--config seed-config.json] [--yes]\n```\n\n详细用法、输入格式和配置覆盖机制请参阅 [CLI 文档](src/cli/README.md)。\n\n## 🔧 Agent 工具\n\n插件注册了两个 Agent 可调用的工具：\n\n### `tdai_memory_search`\n\n搜索用户的 L1 结构化长期记忆。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `query` | string | ✅ | 搜索查询 |\n| `limit` | number | — | 返回结果上限（默认 5，最大 20） |\n| `type` | string | — | 按记忆类型过滤：`persona` / `episodic` / `instruction` |\n| `scene` | string | — | 按场景名过滤 |\n\n### `tdai_conversation_search`\n\n搜索 L0 原始对话历史。\n\n| 参数 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `query` | string | ✅ | 搜索查询 |\n| `limit` | number | — | 返回结果上限（默认 5，最大 20） |\n| `session_key` | string | — | 按 session 过滤 |\n\n## 📁 数据与日志\n\n- **数据目录**：`~/.openclaw/memory-tdai/`（自动创建）\n- **元数据**：`.metadata/manifest.json`（store 绑定、seed 运行记录）\n- **Gateway 日志**：插件运行日志通过 `[memory-tdai]` 前缀标记，可在 Gateway 日志中搜索查看\n- **配置文件**：`~/.openclaw/openclaw.json`\n\n## 📄 License\n\n[MIT](LICENSE)\n\nFile v0.3.5:scripts/migrate-sqlite-to-tcvdb/README.md\n\n# SQLite → 腾讯云向量数据库迁移工具\n\n离线迁移工具，用于将 memory-tdai 的数据从本地 SQLite 存储迁移到腾讯云向量数据库（TCVDB）。\n\n## 前置条件\n\n- Node.js >= 22.16.0\n- 插件已通过 `openclaw plugins install` 安装\n- 迁移脚本已编译（见下方）\n\n## 编译\n\n迁移脚本使用 TypeScript 编写，运行前需要先编译：\n\n```bash\nnpm run build:migrate-sqlite-to-vdb\n```\n\n编译产物输出到 `scripts/migrate-sqlite-to-tcvdb/dist/`，可直接用 Node 运行。\n\n## 使用方法\n\n```bash\n# 预检模式（仅查看源数据，不执行写入）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --dry-run\n\n# 正式迁移\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n### 更多示例\n\n```bash\n# 直接传入 API Key（不通过环境变量）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key 'your-api-key-here' \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n```bash\n# 指定自定义 SQLite 路径（数据库不在默认 vectors.db 位置时）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --sqlite-path /backup/2026-04/vectors-snapshot.db \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n```bash\n# 只迁移 L1 记忆层（跳过 L0 原始消息和 Profile）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --layers l1 \\\n  --yes\n```\n\n```bash\n# 只迁移 L0 和 L1（不迁移 Profile）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --layers l0,l1 \\\n  --yes\n```\n\n```bash\n# 英文语料场景：使用英文 BM25 分词\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-en-v1.5 \\\n  --bm25-language en \\\n  --yes\n```\n\n```bash\n# 禁用 BM25 稀疏向量（仅使用密集向量检索）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --no-bm25-enabled \\\n  --yes\n```\n\n```bash\n# 仅迁移数据，不自动更新 openclaw.json 和 manifest（手动管理配置）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --no-apply-config \\\n  --no-rewrite-manifest \\\n  --yes\n```\n\n```bash\n# 追加迁移：允许目标库已有数据，跳过非空检查\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --no-fail-if-target-nonempty \\\n  --no-verify-counts \\\n  --yes\n```\n\n```bash\n# 输出迁移摘要到 JSON 文件（适合 CI/自动化流水线）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --summary-json-path ./migration-report.json \\\n  --job-id \"migrate-2026-04-13\" \\\n  --yes\n```\n\n```bash\n# 设置自定义超时和别名\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://10.0.1.50:80 \\\n  --tcvdb-username admin \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --tcvdb-alias \"生产环境-主库\" \\\n  --tcvdb-timeout-ms 30000 \\\n  --yes\n```\n\n## 参数说明\n\n| 参数 | 必填 | 默认值 | 说明 |\n|---|---|---|---|\n| `--plugin-data-dir` | 是 | — | 插件数据目录路径 |\n| `--openclaw-config-path` | 是 | — | `openclaw.json` 配置文件路径 |\n| `--sqlite-path` | 否 | `<plugin-data-dir>/vectors.db` | SQLite 数据库文件路径（默认取数据目录下的 `vectors.db`） |\n| `--plugin-id` | 否 | `memory-tencentdb` | 写入配置时使用的插件 ID |\n| `--tcvdb-url` | 是 | — | TCVDB 服务地址 |\n| `--tcvdb-username` | 是 | — | TCVDB 用户名 |\n| `--tcvdb-api-key` | * | — | TCVDB API 密钥（明文） |\n| `--tcvdb-api-key-env` | * | — | 包含 API 密钥的环境变量名 |\n| `--tcvdb-database` | 是 | — | TCVDB 数据库名 |\n| `--tcvdb-embedding-model` | 是 | — | Embedding 模型名称 |\n| `--tcvdb-alias` | 否 | `\"\"` | 用户自定义别名 |\n| `--tcvdb-timeout-ms` | 否 | `10000` | 请求超时时间（毫秒） |\n| `--layers` | 否 | `l0,l1,l2,l3` | 要迁移的层（逗号分隔） |\n| `--dry-run` | 否 | `false` | 仅预览，不执行写入 |\n| `--yes` | 否 | `false` | 跳过交互确认 |\n| `--apply-config` | 否 | `true` | 迁移后更新 openclaw.json |\n| `--config-backup` | 否 | `true` | 写入配置前先备份原配置文件 |\n| `--rewrite-manifest` | 否 | `true` | 将 manifest.json 更新为 tcvdb |\n| `--fail-if-target-nonempty` | 否 | `true` | 目标库非空时中止 |\n| `--verify-counts` | 否 | `true` | 迁移后校验记录数 |\n| `--summary-json-path` | 否 | — | 将迁移摘要写入此文件 |\n| `--job-id` | 否 | — | 迁移任务 ID（用于追踪） |\n| `--bm25-enabled` | 否 | `true` | 启用 BM25 稀疏向量 |\n| `--bm25-language` | 否 | `zh` | BM25 语言（`zh` 或 `en`） |\n\n\\* `--tcvdb-api-key` 和 `--tcvdb-api-key-env` 二选一，必须提供其中一个。\n\n## 目录结构\n\n```\nscripts/migrate-sqlite-to-tcvdb/\n├── cli-entry.ts          # CLI 入口\n├── sqlite-to-tcvdb.ts    # 迁移核心逻辑（参数解析、预检、数据迁移）\n├── config-write.ts       # OpenClaw 配置更新（JSON5，自包含）\n├── manifest-write.ts     # Manifest 重写\n├── *.test.ts             # 就近放置的测试文件\n├── tsconfig.json         # 迁移脚本编译配置\n├── dist/                 # 编译产物（已 gitignore）\n└── README.md             # 本文件\n\nbin/migrate-sqlite-to-tcvdb.mjs     # 极薄 bin 包装 → dist/\n```\n\n迁移脚本通过 `../../src/` 引用存储实现（VectorStore、TcvdbMemoryStore 等），但**不依赖 `openclaw/plugin-sdk`**。配置写回直接使用 `json5`。\n\nFile v0.3.5:src/cli/README.md\n\n# memory-tdai CLI\n\n`openclaw memory-tdai` 命令空间，提供离线数据管理工具。\n\n## seed — 导入历史对话数据\n\n将历史对话 JSON 文件导入到记忆管线中，完整执行 L0→L1→L2→L3 流程。适用于：\n\n- 将已有对话数据灌入记忆系统\n- 批量测试记忆提取效果\n- 迁移/恢复记忆数据\n\n### 用法\n\n```bash\nopenclaw memory-tdai seed --input <file> [options]\n```\n\n### 参数\n\n| 参数 | 必填 | 说明 |\n|------|------|------|\n| `--input <file>` | ✅ | 输入 JSON 文件路径 |\n| `--output-dir <dir>` | — | 输出目录（默认自动生成带时间戳的目录） |\n| `--session-key <key>` | — | 回退 session key（当输入数据缺少时使用） |\n| `--config <file>` | — | 配置覆盖文件（JSON，与 openclaw.json 插件配置深度合并） |\n| `--strict-round-role` | — | 严格校验每轮对话必须包含 user 和 assistant 消息 |\n| `--yes` | — | 跳过交互确认（如时间戳自动填充确认） |\n\n### 示例\n\n```bash\n# 基本用法\nopenclaw memory-tdai seed --input conversations.json\n\n# 指定输出目录\nopenclaw memory-tdai seed --input data.json --output-dir ./seed-output\n\n# 使用自定义配置覆盖（如调整 pipeline 参数）\nopenclaw memory-tdai seed --input data.json --config seed-config.json\n\n# 跳过所有确认\nopenclaw memory-tdai seed --input data.json --yes\n\n# 严格模式 + 自定义配置\nopenclaw memory-tdai seed --input data.json --config seed-config.json --strict-round-role --yes\n```\n\n### 输入文件格式\n\n支持两种 JSON 格式：\n\n#### Format A：对象包装\n\n```json\n{\n  \"sessions\": [\n    {\n      \"sessionKey\": \"user-alice\",\n      \"sessionId\": \"conv-001\",\n      \"conversations\": [\n        [\n          { \"role\": \"user\", \"content\": \"你好\", \"timestamp\": 1711929600000 },\n          { \"role\": \"assistant\", \"content\": \"你好！有什么可以帮你？\", \"timestamp\": 1711929601000 }\n        ],\n        [\n          { \"role\": \"user\", \"content\": \"今天天气怎么样？\" },\n          { \"role\": \"assistant\", \"content\": \"今天晴天，适合出门。\" }\n        ]\n      ]\n    }\n  ]\n}\n```\n\n#### Format B：顶层数组\n\n```json\n[\n  {\n    \"sessionKey\": \"user-alice\",\n    \"conversations\": [\n      [\n        { \"role\": \"user\", \"content\": \"你好\" },\n        { \"role\": \"assistant\", \"content\": \"你好！\" }\n      ]\n    ]\n  }\n]\n```\n\n#### 字段说明\n\n| 字段 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `sessionKey` | string | ✅ | Session 标识（如用户 ID、频道名） |\n| `sessionId` | string | — | 会话实例 ID（同一 sessionKey 下可有多个 sessionId） |\n| `conversations` | message[][] | ✅ | 对话轮次数组，每个轮次是一组消息 |\n| `role` | string | ✅ | 消息角色：`user` 或 `assistant` |\n| `content` | string | ✅ | 消息内容 |\n| `timestamp` | number \\| string | — | 时间戳：epoch 毫秒或 ISO 8601 字符串。缺失时 seed 会提示自动填充 |\n\n### 配置覆盖\n\n`--config` 接受一个 JSON 文件，与 `openclaw.json` 中的插件配置**两级深度合并**：\n\n- 顶层 key 如果两边都是对象 → 浅合并（保留 base 中未覆盖的字段）\n- 其他类型 → 直接覆盖\n\n常见场景：seed 时使用更激进的 pipeline 参数以加速处理：\n\n```json\n{\n  \"pipeline\": {\n    \"everyNConversations\": 3,\n    \"enableWarmup\": false,\n    \"l1IdleTimeoutSeconds\": 2,\n    \"l2DelayAfterL1Seconds\": 1,\n    \"l2MinIntervalSeconds\": 1,\n    \"l2MaxIntervalSeconds\": 10\n  }\n}\n```\n\n如果需要 seed 到独立的 TCVDB 数据库：\n\n```json\n{\n  \"storeBackend\": \"tcvdb\",\n  \"tcvdb\": {\n    \"database\": \"my_seed_test_db\"\n  },\n  \"pipeline\": {\n    \"everyNConversations\": 3,\n    \"enableWarmup\": false,\n    \"l1IdleTimeoutSeconds\": 2\n  }\n}\n```\n\n### 输出目录结构\n\n```\n<output-dir>/\n├── conversations/          — L0 JSONL 文件\n├── records/                — L1 JSONL 文件\n├── scene_blocks/           — L2 场景块\n├── vectors.db              — SQLite 向量数据库（仅 sqlite 后端）\n├── .metadata/\n│   ├── manifest.json       — 元数据（store 绑定 + seed 运行记录）\n│   └── checkpoint.json     — 管线进度\n└── .backup/                — 滚动备份\n```\n\nSeed 完成后，`manifest.json` 会记录本次运行信息：\n\n```json\n{\n  \"version\": 1,\n  \"createdAt\": \"2026-04-01T22:00:00.000Z\",\n  \"store\": {\n    \"type\": \"sqlite\",\n    \"sqlite\": { \"path\": \"vectors.db\" }\n  },\n  \"seed\": {\n    \"inputFile\": \"conversations.json\",\n    \"sessions\": 3,\n    \"rounds\": 42,\n    \"messages\": 128,\n    \"startedAt\": \"2026-04-01T22:00:00.000Z\",\n    \"completedAt\": \"2026-04-01T22:05:30.000Z\"\n  }\n}\n```\n\nFile v0.3.5:_meta.json\n\n{\n  \"ownerId\": \"kn73z7zhz92tv6skpnmpy5pdfh86j68x\",\n  \"slug\": \"memory-tencentdb\",\n  \"version\": \"0.3.5\",\n  \"publishedAt\": 1780196522520\n}\n\nFile v0.3.5:scripts/README.memory-tencentdb-ctl.md\n\n# memory-tencentdb-ctl.sh — memory_tencentdb (TDAI) 运维脚本\n\n> 配合 [`install_hermes_m","readmeExcerpt":"Skill: memory-tencentdb Owner: paudyyin Summary: 四层记忆系统插件 — 自动捕获对话、提取结构化记忆、归纳场景、生成用户画像。支持 L0→L1→L2→L3 渐进式管线，本地 SQLite + 腾讯云向量数据库双后端。 Tags: latest:0.3.7, llm-extraction:0.3.5, long-term-memory:0.3.5, memory:0.3.5, persona:0.3.5, sqlite:0.3.5, vector-search:0.3.5 Version history: v0.3.7 | 2026-06-08T03:09:03.780Z | user Remove standalone LLM mode use Gateway built-in model v0.3.6 | 2026-05-31T03:17:38.331Z | user Four-","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"对话开始\n  → Auto-Recall: 向量/混合搜索相关记忆 + 加载 Persona → 注入系统上下文\n\n对话结束\n  → L0: 录制对话消息 → SQLite + JSONL 双写\n  → Pipeline Scheduler: 达到 N 轮后触发\n     ├── L1: LLM 提取结构化记忆 + 向量去重 → JSONL + SQLite\n     ├── L2: LLM 归纳场景块 → Markdown 文件\n     └── L3: LLM 生成/更新用户画像 → persona.md"},{"language":"bash","snippet":"clawhub install memory-tencentdb"},{"language":"json","snippet":"{\n  \"plugins\": {\n    \"allow\": [\"mx\", \"memory-tencentdb\"],\n    \"load\": {\n      \"paths\": [\"<插件路径>\"]\n    },\n    \"entries\": {\n      \"memory-tencentdb\": {\n        \"enabled\": true,\n        \"config\": {\n          \"pipeline\": {\n            \"everyNConversations\": 3,\n            \"enableWarmup\": true,\n            \"l1IdleTimeoutSeconds\": 10\n          }\n        }\n      }\n    }\n  }\n}"},{"language":"bash","snippet":"openclaw memory-tdai seed --input conversations.json"},{"language":"text","snippet":"Hermes Agent (Python)\n  └─ MemoryManager\n       └─ MemoryTencentdbProvider        (this directory)\n            ├─ GatewaySupervisor          — starts / health-checks the sidecar\n            └─ MemoryTencentdbSdkClient   — POST /recall, /capture, /search/*, /session/end\n                    │\n                    ▼  HTTP (127.0.0.1:8420 by default)\n            memory-tencentdb Gateway (Node.js)\n               └─ memory-tencentdb Core\n                    ├─ L0  Conversation store      (SQLite / TCVDB + JSONL)\n                    ├─ L1  Episodic extraction     (LLM + vector dedup)\n                    ├─ L2  Scene blocks            (Markdown under data dir)\n                    ├─ L3  Persona synthesis       (persona.md)\n                    └─ Storage backends: SQLite + sqlite-vec  OR  Tencent VectorDB"},{"language":"bash","snippet":"# from the tdai-memory-openclaw-plugin checkout:\nln -s \"$(pwd)/hermes-plugin/memory/memory_tencentdb\" \\\n      <hermes-agent-checkout>/plugins/memory/memory_tencentdb"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: memory-tencentdb\ndescription: 四层记忆系统插件 — 自动捕获对话、提取结构化记忆、归纳场景、生成用户画像。支持 L0→L1→L2→L3 渐进式管线，本地 SQLite + 腾讯云向量数据库双后端。\nversion: 0.3.6\ntags: [\"memory\", \"long-term-memory\", \"persona\", \"sqlite\", \"vector-search\"]\nauthor: paudyyin\n---\n\n# memory-tencentdb — 四层记忆系统\n\n为 OpenClaw AI Agent 提供 L0→L1→L2→L3 长期记忆能力。\n\n## v0.3.6 变更（2026-06-08）\n\n- **移除独立 LLM 模式**：删除 `llm.enabled` 配置和 StandaloneLLMRunner，L1/L2/L3 提取统一走 Gateway 内置模型（runEmbeddedPiAgent）\n- **简化配置**：不再需要单独配置 LLM API 端点和 Key，复用 Gateway 已有的模型认证\n- **修复 L1 提取静默失败**：之前独立 LLM 因 apiKey 为空返回 401，导致提取管线完全停止\n\n## 架构\n\n```\n对话开始\n  → Auto-Recall: 向量/混合搜索相关记忆 + 加载 Persona → 注入系统上下文\n\n对话结束\n  → L0: 录制对话消息 → SQLite + JSONL 双写\n  → Pipeline Scheduler: 达到 N 轮后触发\n     ├── L1: LLM 提取结构化记忆 + 向量去重 → JSONL + SQLite\n     ├── L2: LLM 归纳场景块 → Markdown 文件\n     └── L3: LLM 生成/更新用户画像 → persona.md\n```\n\n## 四层记忆\n\n| 层级 | 名称 | 说明 |\n|------|------|------|\n| L0 | 对话录制 | 原始对话消息捕获 |\n| L1 | 记忆提取 | 结构化记忆（persona/episodic/instruction） |\n| L2 | 场景归纳 | 场景块（Scene Block） |\n| L3 | 用户画像 | 用户人格画像（Persona） |\n\n## 记忆类型\n\n- **persona**：用户的稳定属性、偏好、技能、价值观\n- **episodic**：客观发生的动作、决定、计划或结果\n- **instruction**：用户对 AI 的长期行为规则\n\n## 安装\n\n```bash\nclawhub install memory-tencentdb\n```\n\n## 配置\n\n在 openclaw.json 中添加：\n\n```json\n{\n  \"plugins\": {\n    \"allow\": [\"mx\", \"memory-tencentdb\"],\n    \"load\": {\n      \"paths\": [\"<插件路径>\"]\n    },\n    \"entries\": {\n      \"memory-tencentdb\": {\n        \"enabled\": true,\n        \"config\": {\n          \"pipeline\": {\n            \"everyNConversations\": 3,\n            \"enableWarmup\": true,\n            \"l1IdleTimeoutSeconds\": 10\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n> **注意**：v0.3.6 起不再需要 `llm` 配置段，L1/L2/L3 提取自动使用 Gateway 内置模型。\n\n## 存储后端\n\n- `sqlite`（默认）：本地 SQLite + sqlite-vec\n- `tcvdb`：腾讯云向量数据库\n\n## CLI 命令\n\n```bash\nopenclaw memory-tdai seed --input conversations.json\n```\n\n## 故障排查\n\n如果 L1 提取为空：\n1. 检查 `plugins.allow` 包含 `\"memory-tencentdb\"`\n2. 检查 `plugins.load.paths` 包含插件路径\n3. 检查 Gateway 模型配置正常（`models.providers` 和 `agents.defaults.model`）\n4. 检查 vectors.db 中 l1_fts 与 l1_records 行数一致"},{"path":"hermes-plugin/memory/memory_tencentdb/README.md","content":"# memory-tencentdb Memory Provider (Hermes)\n\nHermes-side [`MemoryProvider`](../../../../../hermes-agent/agent/memory_provider.py)\nadapter for the **memory-tencentdb** four-layer memory system\n(L0 conversation capture → L1 episodic extraction → L2 scene blocks → L3 persona synthesis).\n\nThe heavy lifting — capture, extraction, storage, recall, pipeline scheduling —\nruns in a Node.js **Gateway** sidecar (shipped by the same package as the\nOpenClaw plugin). This Python provider is a thin HTTP client + process\nsupervisor that plugs the Gateway into Hermes's lifecycle.\n\n## Architecture\n\n```\nHermes Agent (Python)\n  └─ MemoryManager\n       └─ MemoryTencentdbProvider        (this directory)\n            ├─ GatewaySupervisor          — starts / health-checks the sidecar\n            └─ MemoryTencentdbSdkClient   — POST /recall, /capture, /search/*, /session/end\n                    │\n                    ▼  HTTP (127.0.0.1:8420 by default)\n            memory-tencentdb Gateway (Node.js)\n               └─ memory-tencentdb Core\n                    ├─ L0  Conversation store      (SQLite / TCVDB + JSONL)\n                    ├─ L1  Episodic extraction     (LLM + vector dedup)\n                    ├─ L2  Scene blocks            (Markdown under data dir)\n                    ├─ L3  Persona synthesis       (persona.md)\n                    └─ Storage backends: SQLite + sqlite-vec  OR  Tencent VectorDB\n```\n\nHermes lifecycle → Gateway mapping:\n\n| Hermes hook / call          | Gateway endpoint | Behavior                                                   |\n|-----------------------------|------------------|------------------------------------------------------------|\n| `prefetch(query)`           | `POST /recall`   | Synchronous. Returns `<memory-context>` text for injection |\n| `sync_turn(user, assistant)`| `POST /capture`  | Fire-and-forget on a background daemon thread (max 4 in-flight) |\n| `shutdown()` / `on_session_end` | `POST /session/end` | Flush pending pipeline work                             |\n| `get_tool_schemas()`        | —                | Advertises two LLM tools (see below)                       |\n\nReliability features baked into the provider:\n\n- **Circuit breaker** — 5 consecutive Gateway failures → pause all calls for 60 s.\n- **Back-pressure on capture** — at most 4 in-flight `sync_turn` threads; a 5th\n  waits up to 5 s for the oldest one before starting (Gateway hangs can't grow\n  threads unboundedly).\n- **Supervised startup** — if `MEMORY_TENCENTDB_GATEWAY_CMD` is set (or the\n  provider auto-discovers `src/gateway/server.ts`, see below), it starts the\n  sidecar, polls `/health` for up to 30 s, and tails `gateway.stderr.log` on\n  crash for diagnostics.\n- **Zero-config auto-discovery** — when `MEMORY_TENCENTDB_GATEWAY_CMD` is\n  unset, the provider looks for `src/gateway/server.ts` next to the plugin\n  checkout (in-tree) and, as a last resort, under\n  `~/.memory-tencentdb/tdai-memory-openclaw-plugin/` (preferred),\n  `~/tdai-memory-openclaw-plugin/` (legacy),"},{"path":"README.md","content":"# @tencentdb-agent-memory/memory-tencentdb\n\n**Four-layer memory system plugin for [OpenClaw](https://github.com/openclaw/openclaw).**\n\n为 AI Agent 提供长期记忆能力。通过 L0→L1→L2→L3 四层渐进式管线，自动将对话内容提炼为结构化记忆、场景块和用户画像。支持纯本地 SQLite 和远端腾讯云向量数据库（TCVDB）两种存储后端。\n\n## ✨ 核心功能\n\n- **L0 — 对话录制**：自动捕获每轮对话原始消息，IMemoryStore + JSONL 双写\n- **L1 — 记忆提取**：由 LLM 从对话中提取结构化记忆，支持向量去重与冲突检测\n- **L2 — 场景归纳**：基于 L1 记忆自动归纳场景块（Scene Block），由 LLM 增量提取\n- **L3 — 用户画像**：基于场景块自动生成/更新用户画像（Persona）\n- **自动召回（Auto-Recall）**：对话开始前自动注入相关记忆和用户画像到上下文\n- **多后端存储**：支持 `sqlite`（本地 SQLite + sqlite-vec）和 `tcvdb`（腾讯云向量数据库，服务端 embedding + hybridSearch）\n- **BM25 稀疏向量**：内置 BM25 编码器（tcvdb-text），支持中英文混合搜索\n- **关键词+向量混合搜索**：hybrid（关键词 + 向量 RRF 融合）搜索策略\n- **语义搜索工具**：Agent 可调用 `tdai_memory_search`（L1 记忆搜索）和 `tdai_conversation_search`（L0 对话搜索）\n- **Seed CLI**：`openclaw memory-tdai seed` 命令，支持导入历史对话数据（详见 [CLI 文档](src/cli/README.md)）\n- **Session 隔离**：不同渠道/Agent 的对话独立调度、独立提取\n- **本地数据清理**：可配置 L0/L1 数据保留天数，定时自动清理过期文件\n- **Manifest 元数据**：数据目录自动生成 `.metadata/manifest.json`，记录 store 绑定信息和 seed 运行记录\n- **支持零配置**：支持零配置工作，简单易用\n\n## 🏗️ 关键原理\n\n```\n对话开始\n  → Auto-Recall: 向量/混合搜索相关记忆 + 加载 Persona → 注入系统上下文\n\n对话结束\n  → Auto-Capture (L0): 录制对话消息 → IMemoryStore (SQLite/TCVDB) + JSONL 双写\n  → Pipeline Scheduler: 达到 N 轮后按序触发 L1 → L2 → L3\n     ├── L1: LLM 提取结构化记忆 + 向量去重 → 写入 JSONL + IMemoryStore\n     ├── L2: LLM 归纳场景块 → Markdown 文件\n     └── L3: LLM 生成/更新用户画像 → persona.md\n```\n\n### 数据目录结构\n\n```\n<pluginDataDir>/\n├── conversations/     — L0 每日 JSONL 分片（每行一条消息）\n├── records/           — L1 每日 JSONL 分片（提取的记忆）\n├── scene_blocks/      — L2 场景块 .md 文件\n├── vectors.db         — SQLite + vec0 向量数据库（仅 storeBackend=sqlite）\n├── .metadata/\n│   ├── manifest.json  — 数据目录元数据（store 绑定、seed 信息）\n│   └── checkpoint.json\n└── .backup/           — 滚动备份（persona, scene_blocks）\n```\n\n## 🚀 Quick Start（Docker）\n\n使用预构建的 Docker 镜像，一行命令即可启动带记忆能力的 Hermes Agent：\n\n```bash\ndocker run -d \\\n  --name hermes-memory \\\n  --restart unless-stopped \\\n  -p 8420:8420 \\\n  -e MODEL_API_KEY=\"your-api-key\" \\\n  -e MODEL_BASE_URL=\"https://api.lkeap.cloud.tencent.com/v1\" \\\n  -e MODEL_NAME=\"deepseek-v3.2\" \\\n  -e MODEL_PROVIDER=\"custom\" \\\n  -v hermes_data:/opt/data \\\n  agentmemory/hermes-memory:latest\n```\n\n镜像支持 `linux/amd64` 和 `linux/arm64` 架构。内置腾讯云 DeepSeek-V3.2 默认值，如使用该模型可省略 `MODEL_BASE_URL`/`MODEL_NAME`/`MODEL_PROVIDER`，只传 `MODEL_API_KEY` 即可。\n\n### 环境变量\n\n#### 统一模型配置（Hermes + TDAI 共用）\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `MODEL_API_KEY` | - | LLM API Key（**必填**） |\n| `MODEL_BASE_URL` | `https://api.lkeap.cloud.tencent.com/v1` | LLM API 地址 |\n| `MODEL_NAME` | `deepseek-v3.2` | 模型名称 |\n| `MODEL_PROVIDER` | `custom` | 模型 provider：`custom` / `openrouter` / `anthropic` / `openai` / `gemini` |\n\n#### 服务配置\n\n| 变量 | 默认值 | 说明 |\n|------|--------|------|\n| `TDAI_GATEWAY_PORT` | `8420` | Gateway 端口 |\n| `TDAI_GATEWAY_HOST` | `0.0.0.0` | Gateway 绑定地址 |\n| `TDAI_DATA_DIR` | `/opt/data/tdai-memory` | 记忆数据目录 |\n| `HERMES_HOME` | `/opt/data` | Hermes 数据目录 |\n\n### 验证运行\n\n```bash\n# 验证 Gateway 健康状态\ncurl http://localhost:8420/healt"},{"path":"scripts/migrate-sqlite-to-tcvdb/README.md","content":"# SQLite → 腾讯云向量数据库迁移工具\n\n离线迁移工具，用于将 memory-tdai 的数据从本地 SQLite 存储迁移到腾讯云向量数据库（TCVDB）。\n\n## 前置条件\n\n- Node.js >= 22.16.0\n- 插件已通过 `openclaw plugins install` 安装\n- 迁移脚本已编译（见下方）\n\n## 编译\n\n迁移脚本使用 TypeScript 编写，运行前需要先编译：\n\n```bash\nnpm run build:migrate-sqlite-to-vdb\n```\n\n编译产物输出到 `scripts/migrate-sqlite-to-tcvdb/dist/`，可直接用 Node 运行。\n\n## 使用方法\n\n```bash\n# 预检模式（仅查看源数据，不执行写入）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --dry-run\n\n# 正式迁移\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n### 更多示例\n\n```bash\n# 直接传入 API Key（不通过环境变量）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key 'your-api-key-here' \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n```bash\n# 指定自定义 SQLite 路径（数据库不在默认 vectors.db 位置时）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --sqlite-path /backup/2026-04/vectors-snapshot.db \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --yes\n```\n\n```bash\n# 只迁移 L1 记忆层（跳过 L0 原始消息和 Profile）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --layers l1 \\\n  --yes\n```\n\n```bash\n# 只迁移 L0 和 L1（不迁移 Profile）\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-zh \\\n  --layers l0,l1 \\\n  --yes\n```\n\n```bash\n# 英文语料场景：使用英文 BM25 分词\nnpm run migrate:sqlite-to-tcvdb -- \\\n  --plugin-data-dir ~/.openclaw/memory-tdai \\\n  --openclaw-config-path ~/.openclaw/openclaw.json \\\n  --tcvdb-url http://127.0.0.1:80 \\\n  --tcvdb-username root \\\n  --tcvdb-api-key-env TCVDB_API_KEY \\\n  --tcvdb-database agent_memory_prod \\\n  --tcvdb-embedding-model bge-large-en-v1.5 \\\n  --bm25-language en \\\n  --yes\n```\n\n```bash\n# 禁用 B"},{"path":"src/cli/README.md","content":"# memory-tdai CLI\n\n`openclaw memory-tdai` 命令空间，提供离线数据管理工具。\n\n## seed — 导入历史对话数据\n\n将历史对话 JSON 文件导入到记忆管线中，完整执行 L0→L1→L2→L3 流程。适用于：\n\n- 将已有对话数据灌入记忆系统\n- 批量测试记忆提取效果\n- 迁移/恢复记忆数据\n\n### 用法\n\n```bash\nopenclaw memory-tdai seed --input <file> [options]\n```\n\n### 参数\n\n| 参数 | 必填 | 说明 |\n|------|------|------|\n| `--input <file>` | ✅ | 输入 JSON 文件路径 |\n| `--output-dir <dir>` | — | 输出目录（默认自动生成带时间戳的目录） |\n| `--session-key <key>` | — | 回退 session key（当输入数据缺少时使用） |\n| `--config <file>` | — | 配置覆盖文件（JSON，与 openclaw.json 插件配置深度合并） |\n| `--strict-round-role` | — | 严格校验每轮对话必须包含 user 和 assistant 消息 |\n| `--yes` | — | 跳过交互确认（如时间戳自动填充确认） |\n\n### 示例\n\n```bash\n# 基本用法\nopenclaw memory-tdai seed --input conversations.json\n\n# 指定输出目录\nopenclaw memory-tdai seed --input data.json --output-dir ./seed-output\n\n# 使用自定义配置覆盖（如调整 pipeline 参数）\nopenclaw memory-tdai seed --input data.json --config seed-config.json\n\n# 跳过所有确认\nopenclaw memory-tdai seed --input data.json --yes\n\n# 严格模式 + 自定义配置\nopenclaw memory-tdai seed --input data.json --config seed-config.json --strict-round-role --yes\n```\n\n### 输入文件格式\n\n支持两种 JSON 格式：\n\n#### Format A：对象包装\n\n```json\n{\n  \"sessions\": [\n    {\n      \"sessionKey\": \"user-alice\",\n      \"sessionId\": \"conv-001\",\n      \"conversations\": [\n        [\n          { \"role\": \"user\", \"content\": \"你好\", \"timestamp\": 1711929600000 },\n          { \"role\": \"assistant\", \"content\": \"你好！有什么可以帮你？\", \"timestamp\": 1711929601000 }\n        ],\n        [\n          { \"role\": \"user\", \"content\": \"今天天气怎么样？\" },\n          { \"role\": \"assistant\", \"content\": \"今天晴天，适合出门。\" }\n        ]\n      ]\n    }\n  ]\n}\n```\n\n#### Format B：顶层数组\n\n```json\n[\n  {\n    \"sessionKey\": \"user-alice\",\n    \"conversations\": [\n      [\n        { \"role\": \"user\", \"content\": \"你好\" },\n        { \"role\": \"assistant\", \"content\": \"你好！\" }\n      ]\n    ]\n  }\n]\n```\n\n#### 字段说明\n\n| 字段 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `sessionKey` | string | ✅ | Session 标识（如用户 ID、频道名） |\n| `sessionId` | string | — | 会话实例 ID（同一 sessionKey 下可有多个 sessionId） |\n| `conversations` | message[][] | ✅ | 对话轮次数组，每个轮次是一组消息 |\n| `role` | string | ✅ | 消息角色：`user` 或 `assistant` |\n| `content` | string | ✅ | 消息内容 |\n| `timestamp` | number \\| string | — | 时间戳：epoch 毫秒或 ISO 8601 字符串。缺失时 seed 会提示自动填充 |\n\n### 配置覆盖\n\n`--config` 接受一个 JSON 文件，与 `openclaw.json` 中的插件配置**两级深度合并**：\n\n- 顶层 key 如果两边都是对象 → 浅合并（保留 base 中未覆盖的字段）\n- 其他类型 → 直接覆盖\n\n常见场景：seed 时使用更激进的 pipeline 参数以加速处理：\n\n```json\n{\n  \"pipeline\": {\n    \"everyNConversations\": 3,\n    \"enableWarmup\": false,\n    \"l1IdleTimeoutSeconds\": 2,\n    \"l2DelayAfterL1Seconds\": 1,\n    \"l2MinIntervalSeconds\": 1,\n    \"l2MaxIntervalSeconds\": 10\n  }\n}\n```\n\n如果需要 seed 到独立的 TCVDB 数据库：\n\n```json\n{\n  \"storeBackend\": \"tcvdb\",\n  \"tcvdb\": {\n    \"database\": \"my_seed_test_db\"\n  },\n  \"pipeline\": {\n    \"everyNConversations\": 3,\n    \"enableWarmup\": false,\n    \"l1IdleTimeoutSeconds\": 2\n  }\n}\n```\n\n### 输出目录结构\n\n```\n<output-dir>/\n├── conversations/          — L0 JSONL 文件\n├── records/                — L1 JSONL 文件\n├── scene_blocks/           — L2 场景块\n├── vectors.db              — SQLite 向量数据库（仅 sqli"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1354,"uniquenessScore":40,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T22:45:43.255Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T22:45:43.255Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-12T18:00:42.201Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}