Beyond OpenClaw, TencentDB-Agent-Memory also supports the Hermes agent framework; the Hermes adapter lives in hermes-plugin/ and is named memory_tencentdb.[1] The Hermes Docker image bundles hermes-agent and the memory_tencentdb provider together, exposes the gateway on port :8420, and requires plugin version ≥ 0.3.4.[1] The plugin manifest at hermes-plugin/memory/memory_tencentdb/plugin.yaml describes it as implementing the four-layer memory pipeline (L0 conversation recording, L1 episodic extraction, L2 scene blocks, L3 persona synthesis) via a local Node.js Gateway — see Architecture & memory layers.[2]
src/gateway/server.ts implements the TDAI Gateway HTTP server using Node.js's native http module — no Express or Fastify dependency — and is designed to run as a managed sidecar alongside Hermes.[3] Gateway version "0.1.0" is defined as the module-level constant VERSION in src/gateway/server.ts.[3] The TdaiGateway constructor wires together a StandaloneHostAdapter, a TdaiCore instance, and a SessionFilter; configuration is loaded via loadGatewayConfig() with optional overrides.[3] TdaiGateway.start() initializes data directories via initDataDirectories(), calls this.core.initialize(), then starts the HTTP server; TdaiGateway.stop() closes the HTTP server and calls this.core.destroy().[3]
src/gateway/server.ts exposes these HTTP routes: GET /health, POST /recall, POST /capture, POST /search/memories, POST /search/conversations, POST /session/end, and POST /seed.[3] A v2 API provides 14 standard routes covering memory CRUD, atomic updates, scene indexing, and pipeline status queries.[4] GET /health bypasses the auth gate unconditionally so that orchestrators (Kubernetes liveness probes, Docker health checks) can reach it cheaply.[3] The Gateway enforces a 1 MiB request body size limit to prevent abnormal requests.[4] CORS headers are applied based on a configured allowlist — when corsOrigins is empty, no CORS headers are added; OPTIONS preflight requests always receive a 204 response.[3] Unhandled route errors are caught at the top-level handleRequest try/catch, logged with method and pathname, and returned as HTTP 500 with the error message in the GatewayErrorResponse shape.[3]
When server.apiKey is not configured, all routes except GET /health are open to any caller that can reach the port — the documented legacy default — and a startup warning is emitted via logSecurityPosture() to make this visible.[3] Setting server.apiKey / TDAI_GATEWAY_API_KEY requires every non-/health route to carry an Authorization: Bearer <apiKey> header; requests with a missing, malformed, or incorrect token receive HTTP 401.[5][3] checkAuth() uses crypto.timingSafeEqual for API key comparison to prevent timing-based prefix-match attacks; length mismatches are rejected without comparing bytes.[3] A startup WARN is emitted when the gateway binds to a non-loopback host without apiKey set, to avoid silently exposing an unauthenticated endpoint to the network.[6] When server.corsOrigins contains "*", a startup warning is emitted: every browser origin can reach the gateway, and a concrete allowlist is required for non-local deployments.[3] At startup the gateway logs a one-shot security posture summary covering auth status, bound host, and CORS configuration — and never logs the API key value itself.[3]
src/gateway/config.ts loads gateway configuration from four sources in order: (1) TDAI_GATEWAY_CONFIG env var (explicit path), (2) tdai-gateway.yaml or tdai-gateway.json in CWD, (3) the same filenames under the default data dir, (4) pure environment-variable config with no file.[6] YAML config files are parsed with full YAML support (arbitrary nesting, anchors, lists, multi-line strings); ${VAR} environment-variable interpolation is applied to string leaves as a post-processing step for backward compatibility.[6] A malformed config file is silently swallowed and falls back to environment-variable-only configuration; the config file is treated as optional.[6] loadGatewayConfig defaults the gateway server port to 8420 (overridable via TDAI_GATEWAY_PORT env or server.port yaml) and the host to 127.0.0.1 (overridable via TDAI_GATEWAY_HOST or server.host yaml).[6] server.corsOrigins defaults to an empty list, meaning no Access-Control-Allow-* headers are sent and CORS preflight with an Origin header is rejected with 403; setting it to ["*"] restores permissive behaviour for local development.[6] TDAI_CORS_ORIGINS (comma-separated) or yaml server.corsOrigins (string array or comma-separated string) configures allowed CORS origins; returning [] means no CORS headers are emitted.[6] The default data directory is ~/.memory-tencentdb/memory-tdai/, overridable via TDAI_DATA_DIR or MEMORY_TENCENTDB_ROOT.[6] A leading ~/ in TDAI_DATA_DIR or data.baseDir is expanded to $HOME (or $USERPROFILE on Windows, falling back to /tmp).[6] Backward compatibility is preserved: if the new ~/.memory-tencentdb/memory-tdai/ data directory does not exist but the legacy ~/memory-tdai/ does, the legacy path is used and a deprecation warning is written to stderr.[6] loadGatewayConfig defaults the LLM base URL to https://api.openai.com/v1, model to gpt-4o, max tokens to 4096, and timeout to 120000 ms.[6] Memory configuration parsing is delegated to the shared parseConfig imported from ../config.js, ensuring full compatibility between gateway and plugin configurations.[6] loadGatewayConfig accepts a Partial<GatewayConfig> overrides argument merged one level deep — partial server, data, or llm objects are spread on top of defaults, so sibling fields such as corsOrigins introduced after callers were written are not accidentally dropped.[6]
src/gateway/types.ts defines the HealthResponse shape returned by GET /health: { status: "ok"|"degraded", version, uptime, stores: { vectorStore, embeddingService } }.[7] RecallRequest requires query and session_key; user_id is optional. RecallResponse returns context (string), optional strategy, and optional memory_count.[7] CaptureRequest requires user_content, assistant_content, and session_key; session_id, user_id, and messages are optional. CaptureResponse returns l0_recorded (count) and scheduler_notified (bool).[7] MemorySearchRequest accepts query (required), optional limit, type, and scene filters; MemorySearchResponse returns results (string), total (number), and strategy (string).[7] SessionEndRequest requires session_key and accepts optional user_id; SessionEndResponse returns flushed: boolean.[7] SeedResponse reports sessions_processed, rounds_processed, messages_processed, l0_recorded, duration_ms, and output_dir.[7] GatewayErrorResponse is the common error envelope with a required error string and an optional code string.[7]
StandaloneHostAdapter in src/adapters/standalone/host-adapter.ts is the HostAdapter implementation for the TDAI Gateway (Hermes sidecar); it has no dependency on OpenClaw and constructs context purely from Gateway config and per-request parameters.[8] StandaloneHostAdapter is constructed with { dataDir, llmConfig, logger, defaultUserId?, platform? } and delegates LLM execution to StandaloneLLMRunnerFactory from ./llm-runner.js.[8] StandaloneHostAdapter.getRuntimeContext() returns a RuntimeContext with both workspaceDir and dataDir set to the configured dataDir, empty sessionId/sessionKey, and the configured userId and platform.[8] StandaloneHostAdapter.buildRuntimeContextForRequest() scopes each Gateway request to the correct user/session: sessionKey falls back to sessionId when not explicitly provided, and all per-request params fall back to adapter defaults when omitted.[8]
The plugin manifest registers the legacy aliases tdai and memory-tencentdb so that existing user configs specifying memory.provider: tdai continue to resolve to this provider without changes.[2] The Hermes plugin uses a watchdog + lazy probe mechanism to automatically recover when the Gateway encounters an error.[9]
Sources
README.mdhermes-plugin/memory/memory_tencentdb/plugin.yamlsrc/gateway/server.tsgithub.com…ncentDB-Agent-Memory/releases/tag/v1.0.0github.com…ncentDB-Agent-Memory/releases/tag/v0.3.6src/gateway/config.tssrc/gateway/types.tssrc/adapters/standalone/host-adapter.tsgithub.com…ncentDB-Agent-Memory/releases/tag/v0.3.3