Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,37 @@ Debugging no longer means probing an opaque database — it becomes a determinis
| Hybrid retrieval | BM25 + vector + RRF — supports both keyword and semantic recall |
| Agent tools | `tdai_memory_search` / `tdai_conversation_search` |

### Library Mode for Non-OpenClaw Hosts

OpenClaw remains the default plugin entry point, but host-neutral embedders can
use the same core without depending on OpenClaw runtime APIs:

```ts
import { TdaiCore, parseConfig } from "@tencentdb-agent-memory/memory-tencentdb/core"
import type {
CompletedTurn,
HostAdapter,
} from "@tencentdb-agent-memory/memory-tencentdb/core"

const config = parseConfig({
capture: { enabled: true },
extraction: { enabled: false },
})

const core = new TdaiCore({
hostAdapter,
config,
})
await core.initialize()
```

`TdaiCore` obtains model execution through
`HostAdapter.getLLMRunnerFactory()`, so the constructor only needs the adapter
and parsed config.

For configuration-only integrations, import the parser from
`@tencentdb-agent-memory/memory-tencentdb/config`.

---

## Documentation
Expand Down
30 changes: 30 additions & 0 deletions README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,36 @@ docker exec -it hermes-memory hermes
| 混合检索 | BM25 + 向量 + RRF,兼顾关键词和语义召回 |
| Agent 工具 | `tdai_memory_search` / `tdai_conversation_search` |

### 非 OpenClaw 宿主的 Library Mode

OpenClaw 仍然是默认插件入口,但其他宿主可以复用同一套
host-neutral core,而不需要依赖 OpenClaw runtime API:

```ts
import { TdaiCore, parseConfig } from "@tencentdb-agent-memory/memory-tencentdb/core"
import type {
CompletedTurn,
HostAdapter,
} from "@tencentdb-agent-memory/memory-tencentdb/core"

const config = parseConfig({
capture: { enabled: true },
extraction: { enabled: false },
})

const core = new TdaiCore({
hostAdapter,
config,
})
await core.initialize()
```

`TdaiCore` 通过 `HostAdapter.getLLMRunnerFactory()` 获取模型执行器,
所以构造函数只需要 adapter 和解析后的 config。

如果只需要配置解析,可以从
`@tencentdb-agent-memory/memory-tencentdb/config` 导入 `parseConfig`。

---

## 文档
Expand Down
34 changes: 15 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,43 @@
"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)",
"type": "module",
"main": "./dist/index.mjs",
"bin": {
"migrate-sqlite-to-tcvdb": "./bin/migrate-sqlite-to-tcvdb.mjs",
"export-tencent-vdb": "./bin/export-tencent-vdb.mjs",
"read-local-memory": "./bin/read-local-memory.mjs"
},
"types": "./dist/index.d.mts",
"exports": {
".": {
"types": "./dist/index.d.mts",
"import": "./dist/index.mjs",
"default": "./dist/index.mjs"
},
"./core": {
"types": "./dist/core/index.d.mts",
"import": "./dist/core/index.mjs",
"default": "./dist/core/index.mjs"
},
"./config": {
"types": "./dist/config.d.mts",
"import": "./dist/config.mjs",
"default": "./dist/config.mjs"
}
},
"scripts": {
"build": "npm run build:plugin && npm run build:scripts",
"build": "npm run build:plugin",
"build:plugin": "tsdown",
"build:scripts": "npm run build:migrate-sqlite-to-vdb && npm run build:export-tencent-vdb && npm run build:read-local-memory",
"prepack": "npm run build",
"build:migrate-sqlite-to-vdb": "tsc -p scripts/migrate-sqlite-to-tcvdb/tsconfig.json --noEmitOnError false",
"migrate-sqlite-to-tcvdb": "node ./bin/migrate-sqlite-to-tcvdb.mjs",
"build:export-tencent-vdb": "tsc --project scripts/export-tencent-vdb/tsconfig.json",
"export-tencent-vdb": "node ./bin/export-tencent-vdb.mjs",
"build:read-local-memory": "tsc --project scripts/read-local-memory/tsconfig.json",
"read-local-memory": "node ./bin/read-local-memory.mjs",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"postinstall": "bash scripts/openclaw-after-tool-call-messages.patch.sh 2>/dev/null || true"
},
"files": [
"dist/",
"bin/",
"index.ts",
"scripts/migrate-sqlite-to-tcvdb/dist/",
"scripts/export-tencent-vdb/dist/",
"scripts/read-local-memory/dist/",
"scripts/memory-tencentdb-ctl.sh",
"scripts/install_hermes_memory_tencentdb.sh",
"scripts/README.memory-tencentdb-ctl.md",
"src/",
"scripts/openclaw-after-tool-call-messages.patch.sh",
"scripts/setup-offload.sh",
"hermes-plugin/",
"!hermes-plugin/**/tests/",
"openclaw.plugin.json",
"README.md",
"CHANGELOG.md",
Expand Down Expand Up @@ -101,7 +97,7 @@
},
"openclaw": {
"extensions": [
"./index.ts"
"./dist/index.mjs"
],
"compat": {
"pluginApi": ">=2026.3.13",
Expand Down
18 changes: 18 additions & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,21 @@ export type {
// TdaiCore service facade
export { TdaiCore } from "./tdai-core.js";
export type { TdaiCoreOptions } from "./tdai-core.js";

// Configuration parser used by host-neutral embedders.
export { parseConfig } from "../config.js";
export type {
CaptureConfig,
EmbeddingConfig,
ExtractionConfig,
MemoryTdaiConfig,
BM25Config,
MemoryCleanupConfig,
OffloadConfig,
PersonaConfig,
PipelineTriggerConfig,
RecallConfig,
ReportConfig,
StandaloneLLMOverrideConfig,
TcvdbConfig,
} from "../config.js";
25 changes: 25 additions & 0 deletions src/core/package-metadata.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { existsSync } from "node:fs";
import { resolve } from "node:path";
import { describe, expect, it } from "vitest";
import packageJson from "../../package.json" with { type: "json" };

const repoRoot = resolve(import.meta.dirname, "../..");

describe("npm package metadata", () => {
it("does not reference missing command-line binaries", () => {
for (const target of Object.values(packageJson.bin ?? {})) {
expect(existsSync(resolve(repoRoot, target))).toBe(true);
}
});

it("builds the publishable runtime without missing script tsconfigs", () => {
expect(packageJson.scripts.build).toBe("npm run build:plugin");
expect(packageJson.scripts["build:scripts"]).toBeUndefined();
});

it("publishes compiled runtime artifacts instead of duplicating source", () => {
expect(packageJson.files).toContain("dist/");
expect(packageJson.files).not.toContain("src/");
expect(packageJson.openclaw.extensions).toEqual(["./dist/index.mjs"]);
});
});
38 changes: 38 additions & 0 deletions src/core/public-exports.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { describe, expect, it } from "vitest";
import packageJson from "../../package.json" with { type: "json" };
import { parseConfig, TdaiCore } from "./index.js";

const repoRoot = resolve(import.meta.dirname, "../..");

describe("library mode public exports", () => {
it("exposes host-neutral core and config subpaths", () => {
expect(packageJson.exports).toMatchObject({
"./core": {
import: "./dist/core/index.mjs",
types: "./dist/core/index.d.mts",
},
"./config": {
import: "./dist/config.mjs",
types: "./dist/config.d.mts",
},
});
});

it("keeps TdaiCore and parseConfig available from the core barrel", () => {
expect(typeof TdaiCore).toBe("function");
expect(typeof parseConfig).toBe("function");
expect(parseConfig({ extraction: { enabled: false } }).extraction.enabled).toBe(false);
});

it("documents TdaiCore construction through the HostAdapter contract", () => {
const readme = readFileSync(resolve(repoRoot, "README.md"), "utf8");
const readmeCn = readFileSync(resolve(repoRoot, "README_CN.md"), "utf8");

expect(readme).not.toContain("llmRunnerFactory,");
expect(readmeCn).not.toContain("llmRunnerFactory,");
expect(readme).toContain("HostAdapter.getLLMRunnerFactory()");
expect(readmeCn).toContain("HostAdapter.getLLMRunnerFactory()");
});
});
8 changes: 6 additions & 2 deletions tsdown.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ function collectExternalDependencies(): string[] {
}

export default defineConfig({
entry: ["./index.ts"],
entry: {
index: "./index.ts",
"core/index": "./src/core/index.ts",
config: "./src/config.ts",
},
outDir: "./dist",
format: "esm",
platform: "node",
clean: true,
fixedExtension: true,
dts: false,
dts: true,
sourcemap: false,
deps: {
neverBundle: (id) => {
Expand Down