Skip to content

Latest commit

 

History

History
342 lines (254 loc) · 16.9 KB

File metadata and controls

342 lines (254 loc) · 16.9 KB

memory-tencentdb-ctl.sh — memory_tencentdb运维脚本

配合 install_hermes_memory_tencentdb.sh 使用。 先跑安装脚本部署好插件 + Node 依赖,之后日常的启停 / 配置全部通过 memory-tencentdb-ctl.sh 完成。

1. 运行模式

脚本有两种模式,默认是独立模式,完全不触碰 ~/.hermes

模式 激活方式 做什么 不做什么
standalone(默认) 无需任何参数 启停 Gateway;写 $TDAI_DATA_DIR/tdai-gateway.json;日志落 $TDAI_DATA_DIR/logs/ 不写 $HERMES_HOME/env.d/,不改 $HERMES_HOME/config.yaml,不读 hermes 相关 env
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 子命令

为什么 hermes 模式要多写 env 文件? 因为 hermes 进程会托管式地把 Gateway 以子进程拉起来(supervisor 用 os.environ.copy() 传环境),此时 Gateway 读不到 tdai-gateway.json 所在的 shell 环境,必须通过 $HERMES_HOME/env.d/*.sh 让 hermes 自身 source 才能把凭据传进去。独立模式下 Gateway 自己读 JSON,无此需要。

2. 路径

路径变量约定:本节及后续示例统一用 $HERMES_HOME 指代 hermes 的家目录,默认 ~/.hermes,但你可以通过环境变量覆盖(例如 export HERMES_HOME=/srv/hermes),脚本和 hermes 自身都遵守这个变量。

自 0.4.x 起,所有 tdai 相关数据/代码默认收纳到统一根目录 $MEMORY_TENCENTDB_ROOT(默认 ~/.memory-tencentdb)之下:

  • $TDAI_INSTALL_DIR 默认 $MEMORY_TENCENTDB_ROOT/tdai-memory-openclaw-plugin(即 ~/.memory-tencentdb/tdai-memory-openclaw-plugin
  • $TDAI_DATA_DIR 默认 $MEMORY_TENCENTDB_ROOT/memory-tdai(即 ~/.memory-tencentdb/memory-tdai

下文出现这些变量时export 一份覆盖,再跑命令即可全局生效。 旧版本使用 ~/tdai-memory-openclaw-plugin~/memory-tdaiinstall_hermes_memory_tencentdb.sh 在升级时会自动迁移这两个旧目录到新位置。

路径 standalone hermes 作用
$TDAI_INSTALL_DIR 插件源码 + node_modules + src/gateway/server.ts
$TDAI_DATA_DIR/tdai-gateway.json Gateway 主配置:llm / memory.embedding / memory.tcvdb / memory.storeBackend,权限 0600
$TDAI_DATA_DIR/logs/ ✅ 日志 gateway.stdout.log / gateway.stderr.log / gateway.pid
$HERMES_HOME/logs/memory_tencentdb/ ✅ 日志 同上,换目录
$HERMES_HOME/env.d/memory-tencentdb-llm.sh hermes 启动前 source,给 supervisor 托管的 Gateway 子进程注入 LLM 凭据
$HERMES_HOME/config.yaml enable-hermes-memory 修改其 memory.provider
Gateway 监听 127.0.0.1:8420 127.0.0.1:8420 可被 MEMORY_TENCENTDB_GATEWAY_HOST/PORT 覆盖

所有路径都能用同名环境变量覆盖(再次列出便于对照):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_DIRMEMORY_TENCENTDB_GATEWAY_HOST/PORT

依赖:bashpython3node >= 22npxlsofss

3. 安装 & 调用

脚本随 npm 包发布到 node_modules/.../scripts/ 下,但没有注册为 bin 命令。要用全局命令名调用,必须自己做一次软链。

3.1 从 npm 包里直接运行(无需任何配置)

npm install @tencentdb-agent-memory/memory-tencentdb

# 项目内安装,路径可由 npm root 动态算出
"$(npm root)/@tencentdb-agent-memory/memory-tencentdb/scripts/memory-tencentdb-ctl.sh" --help

# 全局安装则用 npm root -g
"$(npm root -g)/@tencentdb-agent-memory/memory-tencentdb/scripts/memory-tencentdb-ctl.sh" --help

npm root / npm root -g 会在所有包管理器(npm / pnpm / yarn)和不同的 prefix 配置下返回正确目录,避免硬编码 node_modules/ 路径。适合一次性、临时使用的场景。

3.2 软链到 PATH(推荐给运维 / 长期使用)

不论脚本来源(git clone 出来的仓库 / npm install 装的包 / 自定义部署目录),先把脚本路径算出来存到一个变量里,再统一做软链。这样无需关心你把仓库放在 ~/code//opt/、还是别的什么地方。

# 第一步:定位 memory-tencentdb-ctl.sh 的真实路径(任选一种来源)

# (a) 从 git 仓库(在仓库根目录或任意子目录里执行)
SCRIPT="$(git -C "$(git rev-parse --show-toplevel)" ls-files | \
          grep -E 'scripts/memory-tencentdb-ctl\.sh$' | head -1)"
SCRIPT="$(git rev-parse --show-toplevel)/$SCRIPT"

# (b) 从已 npm 全局安装的包
SCRIPT="$(npm root -g)/@tencentdb-agent-memory/memory-tencentdb/scripts/memory-tencentdb-ctl.sh"

# (c) 从项目本地的 node_modules
SCRIPT="$(npm root)/@tencentdb-agent-memory/memory-tencentdb/scripts/memory-tencentdb-ctl.sh"

# (d) 完全手写绝对路径(如部署到非标准位置)
SCRIPT="/opt/tdai/scripts/memory-tencentdb-ctl.sh"

# 第二步:验证路径正确,然后软链
test -f "$SCRIPT" && echo "ok: $SCRIPT" || { echo "not found"; exit 1; }
chmod +x "$SCRIPT"
sudo ln -sf "$SCRIPT" /usr/local/bin/memory-tencentdb-ctl

# 同样的办法把 install_hermes_memory_tencentdb.sh 链接成 install-memory-tencentdb(可选)
INSTALL_SCRIPT="$(dirname "$SCRIPT")/install_hermes_memory_tencentdb.sh"
test -f "$INSTALL_SCRIPT" && {
  chmod +x "$INSTALL_SCRIPT"
  sudo ln -sf "$INSTALL_SCRIPT" /usr/local/bin/install-memory-tencentdb
}

之后直接 memory-tencentdb-ctl … / install-memory-tencentdb …

为什么不直接用 npm bin 注册? 这两个脚本是运维工具而不是包的核心 API,主仓库希望用户显式完成 PATH 注册(避免无意中污染全局命令空间,并避免 npm 卸载时静默移除运维入口)。

4. 生命周期管理(两种模式通用)

memory-tencentdb-ctl start        # 若 :8420 已占用会直接返回;否则后台 spawn,等待 /health 通过
memory-tencentdb-ctl stop         # 先 SIGTERM,5s 内未退则 SIGKILL
memory-tencentdb-ctl restart
memory-tencentdb-ctl status       # 打印模式、端口、data/log 路径、进程状态
memory-tencentdb-ctl health       # GET /health,纯 python3 实现,不要求 curl
memory-tencentdb-ctl logs         # tail -f stdout + stderr
memory-tencentdb-ctl logs err 500 # 只看 stderr 最近 500 行

启动命令解析顺序:

  1. 环境变量 MEMORY_TENCENTDB_GATEWAY_CMDinstall_hermes_memory_tencentdb.sh 写入 /etc/profile.d/memory-tencentdb-env.sh 的那条)。
  2. 回退到 sh -c 'cd $TDAI_INSTALL_DIR && exec npx tsx src/gateway/server.ts'

启动时会自动 source 的环境文件:

  • 两种模式:/etc/profile.d/memory-tencentdb-env.sh
  • 仅 hermes 模式:/etc/profile.d/hermes-env.sh 以及 $HERMES_HOME/env.d/*.sh

5. 配置 LLM / Embedding / VDB

三类凭据统一落到 $TDAI_DATA_DIR/tdai-gateway.json0600,原子写)。config llm--hermes 模式下会额外写一份 env 文件;Embedding / VDB 从不写 env。

5.1 LLM

# standalone 模式:只写 tdai-gateway.json
memory-tencentdb-ctl config llm \
  --api-key   "sk-xxxxxxxxxxxx" \
  --base-url  "https://api.openai.com/v1" \
  --model     "gpt-4o" \
  --restart

# hermes 模式:tdai-gateway.json + $HERMES_HOME/env.d/memory-tencentdb-llm.sh
memory-tencentdb-ctl --hermes config llm \
  --api-key   "sk-xxxxxxxxxxxx" \
  --base-url  "https://api.openai.com/v1" \
  --model     "gpt-4o" \
  --restart
  • JSON 写入点:$.llm.{baseUrl, apiKey, model}
  • env 文件写入(仅 --hermes):TDAI_LLM_*MEMORY_TENCENTDB_LLM_* 别名(Python provider 的 get_config_schema() 会读后者)。

5.2 Embedding

默认关闭(provider=none)。启用远端 OpenAI 兼容服务:

memory-tencentdb-ctl config embedding \
  --provider   openai \
  --api-key    "sk-xxxx" \
  --base-url   "https://api.openai.com/v1" \
  --model      "text-embedding-3-small" \
  --dimensions 1536 \
  --restart

# 关闭 embedding(退化为 BM25/关键词召回)
memory-tencentdb-ctl config embedding --provider none --restart
  • JSON 写入点:$.memory.embedding.{provider, baseUrl, apiKey, model, dimensions, enabled, proxyUrl?}
  • qclaw provider 额外要求 --proxy-url
  • 校验规则与 src/config.tsparseConfig() 对齐:dimensions 为正整数,非 none 必须带 apiKey/baseUrl/model/dimensions;缺项直接报错不写半残 JSON。

5.3 VectorDB(Tencent Cloud VDB / tcvdb)

memory-tencentdb-ctl config vdb \
  --url       "http://xxx-vdb.tencentclb.com:8100" \
  --username  root \
  --api-key   "YOUR-VDB-API-KEY" \
  --database  "openclaw_memory" \
  --alias     "primary" \
  --embedding-model "bge-large-zh" \
  --ca-pem    "/etc/ssl/vdb-ca.pem" \
  --restart
  • JSON 写入点:$.memory.tcvdb.{url, username, apiKey, database, alias?, caPemPath?, embeddingModel?}
  • 默认同时把 $.memory.storeBackend 切到 "tcvdb";只想预埋配置先不切,加 --no-set-backend
  • --ca-pem 只写路径不复制文件;脚本会校验可读性。

5.4 退回本地 SQLite(关闭 VDB 后端)

# 默认:保留 memory.tcvdb 凭据(方便随时再切回去),仅把 storeBackend 改回 sqlite
memory-tencentdb-ctl config vdb-off --restart

# 同时把腾讯云 VDB 的 url / apiKey / database 等凭据从 JSON 中清掉
memory-tencentdb-ctl config vdb-off --purge-creds --restart
  • JSON 写入点:把 $.memory.storeBackend 设为 "sqlite"--purge-creds 时额外删除整段 $.memory.tcvdb
  • $.llm / $.memory.embedding 等其它顶级段完全保留,hermes 侧 memory.provider 不动(仍是 memory_tencentdb,只是它内部存储退回 sqlite)。
  • 配置文件不存在时给出 warn 并写入仅含 {"memory":{"storeBackend":"sqlite"}} 的最小配置。
  • config vdb 完全镜像:可与 --dry-run / --restart 组合使用。

5.5 查看当前配置

memory-tencentdb-ctl config show
  • 打印 tdai-gateway.jsonapiKey/password/token 字段自动脱敏为 <redacted:NN chars>
  • hermes 模式下额外打印 $HERMES_HOME/env.d/memory-tencentdb-*.sh(API key 也会脱敏),可直接贴工单。

6. 打通 hermes(仅 --hermes 模式)

memory-tencentdb-ctl --hermes enable-hermes-memory

幂等:把 $HERMES_HOME/config.yamlmemory: 段的 provider: 改成 memory_tencentdb(不存在则新增整段)。改完后重启 hermes:

source "$HERMES_HOME/env.d/memory-tencentdb-llm.sh"
pkill -f hermes-agent || true
hermes

关于写入策略:脚本采用"格式保真"双路径,永不重写整个 YAML

  1. 首选:检测到 ruamel.yaml 时走 round-trip,完整保留注释、键序、引号、缩进风格(推荐 pip install --user ruamel.yaml 享受最佳保真度,非必装);
  2. 降级:未安装 ruamel 时走最小化原位行编辑——只重写 provider: 那一行,缩进直接从同段已有兄弟键的前缀逐字符拷贝(零猜测、零格式破坏);
  3. memory: 段不存在,则在文件末尾追加最小段,缩进从文档其它顶级段的子键拓印。

实测对真实 ~/.hermes/config.yaml 做 byte-for-byte diff,除 provider 值本身外其余字节完全一致。

非 hermes 模式下调用该命令会直接报错退出。

想反过来"保留 hermes provider 不变,仅让 TDAI 内部存储退回 sqlite",用 §5.4 的 config vdb-off 即可(不需要也不要改 hermes 的 memory.provider)。

7. 典型使用流程

场景 A:Gateway 独立部署(不使用 hermes)

# 1) 安装
#    INSTALL_SCRIPT 的取值方式见上文 3.2 节(git rev-parse / npm root / 手填均可)
#    例如从 git 仓库根:INSTALL_SCRIPT="$(git rev-parse --show-toplevel)/scripts/install_hermes_memory_tencentdb.sh"
#         从 npm 全局:  INSTALL_SCRIPT="$(npm root -g)/@tencentdb-agent-memory/memory-tencentdb/scripts/install_hermes_memory_tencentdb.sh"
bash "$INSTALL_SCRIPT"

# 2) 只配 Gateway 所需凭据
memory-tencentdb-ctl config llm       --api-key "sk-..." --base-url "https://api.openai.com/v1" --model gpt-4o
memory-tencentdb-ctl config embedding --provider openai --api-key "sk-..." --base-url "https://api.openai.com/v1" \
                                      --model text-embedding-3-small --dimensions 1536
memory-tencentdb-ctl config vdb       --url "http://xxx:8100" --api-key "..." --database openclaw_memory

# 3) 启动 + 自检
memory-tencentdb-ctl start
memory-tencentdb-ctl status
memory-tencentdb-ctl health      # 预期: {"status":"ok",...}

场景 B:集成 hermes

# 1) 安装(与场景 A 相同;INSTALL_SCRIPT 由上文 3.2 节算出)
bash "$INSTALL_SCRIPT"

# 2) 全程加 --hermes(或 export MEMORY_TENCENTDB_MODE=hermes 一次)
memory-tencentdb-ctl --hermes config llm --api-key "sk-..." --base-url "https://api.openai.com/v1" --model gpt-4o
memory-tencentdb-ctl --hermes config embedding --provider openai --api-key "sk-..." \
                                               --base-url "https://api.openai.com/v1" \
                                               --model text-embedding-3-small --dimensions 1536
memory-tencentdb-ctl --hermes config vdb --url "http://xxx:8100" --api-key "..." --database openclaw_memory

# 3) 启动 Gateway(通常由 hermes supervisor 托管,这里是手动兜底)
memory-tencentdb-ctl --hermes start
memory-tencentdb-ctl --hermes status

# 4) 在 hermes config 里启用 provider,并重启 hermes
memory-tencentdb-ctl --hermes enable-hermes-memory
source "$HERMES_HOME/env.d/memory-tencentdb-llm.sh"
pkill -f hermes-agent ; hermes

如果嫌 --hermes 每次都要带,可以:

export MEMORY_TENCENTDB_MODE=hermes

之后所有调用自动切到 hermes 模式,命令行无需再加 --hermes

场景 C:临时把 TDAI 的存储退回 sqlite(保留 hermes 集成)

适用于 VDB 不可达 / 排障 / 离线开发等场景:希望 hermes 端 memory.provider 仍是 memory_tencentdb,但让 Gateway 改用本地 SQLite 落盘。

# (A) 默认:保留 memory.tcvdb 凭据,仅把 storeBackend 切回 sqlite
memory-tencentdb-ctl config vdb-off --restart

# (B) 排障结束想切回 vdb:当前需要重新跑一次 config vdb(必填项需重新提供,
#     即使 JSON 里凭据还在;脚本是基于必填校验的"重新声明"语义,不是 toggle)
memory-tencentdb-ctl config vdb \
  --url "http://xxx-vdb.tencentclb.com:8100" \
  --api-key "<你的 KEY>" \
  --database "openclaw_memory" \
  --restart

# (C) 彻底放弃 vdb:清掉凭据
memory-tencentdb-ctl config vdb-off --purge-creds --restart

之所以 (B) 不提供"零参数 vdb-on",是因为原 config vdb 子命令把 --url/--api-key/--database 设为强校验,避免用户拼装出半残配置;如果你希望把"已存的凭据重新激活"也做成单命令,告诉维护者补一个 config vdb-on 即可(实现方式与 vdb-off 完全镜像)。

不要为了"切回 sqlite"去改 ~/.hermes/config.yamlmemory.provider!hermes 看到的依然是 memory_tencentdb provider,存储后端切换是 Gateway 内部的事,对 hermes 完全透明。

8. 全局选项 & 调试技巧

  • 所有写操作支持 --dry-run(放在命令最前),会打印将要写入的内容但不落盘:
    memory-tencentdb-ctl --dry-run config llm --api-key k --base-url https://x --model m
  • 敏感文件权限一律 0600env.d/memory-tencentdb-llm.sh 含明文 API key,不要 commit。
  • 启动失败:memory-tencentdb-ctl logs err 200 查看 stderr;手动前台跑一遍更容易看到报错:
    cd "$TDAI_INSTALL_DIR" && npx tsx src/gateway/server.ts
  • 端口冲突:MEMORY_TENCENTDB_GATEWAY_PORT=18420 memory-tencentdb-ctl restart
  • 验证 hermes 有没有吃到新 env(hermes 模式):
    tr '\0' '\n' < /proc/$(pgrep -n hermes-agent)/environ | grep -E 'TDAI_|MEMORY_TENCENTDB_'

9. 退出码

含义
0 成功
1 参数错误 / 业务校验失败(如 --base-url 非 http(s);在 standalone 下调 hermes 专属命令)
2 写盘失败(磁盘满、权限不足等)
127 依赖缺失(python3 / node / npx

要封装成 systemd unit,基于 memory-tencentdb-ctl start / memory-tencentdb-ctl stopType=forking 的 service 即可(Gateway 是无状态 HTTP sidecar,不依赖 systemd readiness 协议)。