首页
/ mem0 TypeScript SDK 工程实践:从双入口构建到 ts-v 标签发布的完整工作流

mem0 TypeScript SDK 工程实践:从双入口构建到 ts-v 标签发布的完整工作流

2026-09-06 20:57:03作者:邬祺芯Juliet

本篇基于 mem0 仓库中的 TypeScript SDK 说明文档(mem0-ts/CLAUDE.md),系统讲解 mem0ai npm 包的工程组织方式:pnpm 命令体系、tsup 双入口(CJS + ESM)构建、jest 测试分层、TypeScript 严格模式约定,以及 ts-v* 标签触发 OIDC 发布到 npm 的完整链路。读完本文,你可以直接参与该 SDK 的二次开发、本地构建与版本发布流程。

定位:一个包,两种记忆入口

mem0-ts 目录承载的就是发布到 npm 的 mem0ai 包(见 mem0-ts/package.json),当前版本为 3.1.7,声明 node >= 18 运行环境(engines 字段),并通过 packageManager 字段锁定 pnpm@10.5.2。该包同时提供两条能力线:

  • 托管平台客户端MemoryClient,对接 Mem0 托管服务;
  • 自托管 OSS 记忆Memory,以及全部 OSS 构建块(Provider)。

对应的公共 API 导出如下(继承自原文档,并与 mem0-ts/package.jsonexports/typesVersions 字段相互印证):

导出 用途 导入方式
MemoryClient 托管平台客户端 import { MemoryClient } from 'mem0ai'
Memory 自托管 OSS 记忆 import { Memory } from 'mem0ai/oss'
Providers OSS 构建块 import { OpenAIEmbedding } from 'mem0ai/oss'

包的两个入口点在构建配置中一一对应:. 映射到 src/client/index.ts 的产物,./oss 映射到 src/oss/src/index.ts 的产物(下节详述)。

目录结构:client 与 oss 的二元划分

原文档给出的源码布局如下:

mem0-ts/src/
├── client/          MemoryClient (hosted platform)
└── oss/             Memory (self-hosted)
    ├── llms/
    ├── embeddings/
    ├── vector_stores/
    └── graphs/

OSS 入口文件 的实际导出看,mem0ai/oss 以桶导出(barrel export)方式暴露了 Memorymemory.types、通用 types,以及 embeddings(OpenAI、Ollama、Google、Azure、AWS Bedrock、HuggingFace、Together、FastEmbed、VertexAI、LangChain、LM Studio 等)与 llms(OpenAI、Anthropic、Groq、Google、Ollama、LM Studio、Mistral、LangChain、LiteLLM、vLLM、AWS Bedrock 等)目录下的全部 Provider 实现,vector_stores 基类与实现同样经由该入口统一导出。这种"单一入口 + 全量桶导出"的结构,使得业务侧只需 import { ... } from 'mem0ai/oss' 即可完成组装,无需深入子路径。

构建体系:tsup 双入口、CJS + ESM 双格式

pnpm run build 背后是 tsup(构建工具),而真正的构建配置写在 mem0-ts/tsup.config.ts 中。该配置以"多入口"方式定义了两个独立的构建任务:

  1. client 入口entry: ["src/client/index.ts"],输出 format: ["cjs", "esm"],开启 dts: true 生成类型声明;
  2. oss 入口entry: ["src/oss/src/index.ts"]outDir: "dist/oss",同样 CJS + ESM 双格式并生成类型。

几个对使用者有实际影响的细节:

  • external 列表显式列出了 openai@anthropic-ai/sdkpgredisbetter-sqlite3chromadb@pinecone-database/pinecone@qdrant/js-client-rest 等几十个 Provider SDK。它们与 package.json 中的 peerDependencies 一致,且绝大部分在 peerDependenciesMeta 中标记为 optional: true——即 SDK 本体只强制依赖 axiosopenaiuuidzod 四个包,其余向量库/LLM 驱动按需安装,避免不必要的依赖膨胀。
  • define 注入版本号:构建时把 __MEM0_SDK_VERSION__ 全局常量替换为 package.jsonversion,供运行时(如遥测、User-Agent)读取。
  • 产物结构package.jsonmain./dist/index.js)、module./dist/index.mjs)、types./dist/index.d.ts)及 exports 子路径映射严格对应,typesVersions 同时为 mem0ai/oss 提供类型解析。
  • pnpm run build 实际展开为 npm run clean && npx prettier --check . && npx tsup:先清理 dist,再做 Prettier 格式检查,最后执行 tsup。也就是说格式检查是构建前置门禁,与 CI 中的 Lint 步骤(ts-sdk-ci.yml 中的 npx prettier --check .)保持一致。

开发命令速查(pnpm only)

原文档约定:只使用 pnpm,绝不用 npm 或 yarn。以下是完整命令表,括号内为 package.json 中的实际脚本定义:

pnpm install
pnpm run build              # tsup (CJS + ESM)
pnpm run test               # jest, all tests
pnpm run test:unit          # jest --coverage
pnpm run test:integration   # jest, needs MEM0_API_KEY
pnpm run test:ci            # jest --coverage --ci
pnpm run test:watch
pnpm run typecheck          # tsc --noEmit

对照 scripts 字段可以补充几点实操细节:

  • test:unit 的真实定义是 jest --coverage --ci --testPathIgnorePatterns='/node_modules/' '/dist/' 'integration',即排除集成测试后跑全量单测并生成覆盖率;
  • test:integration 使用独立的 jest.integration.config.js 并附加 --forceExit,运行前必须配置 MEM0_API_KEY(CI 中通过 secrets.MEM0_API_KEY 注入);
  • test 是裸 jesttest:ts 显式指定 jest.config.js;CI 的"验证包导出"步骤会用 node -e 分别 require dist/index.jsdist/oss/index.js,确认两个入口都能正常加载并统计导出数量;
  • 另有 pnpm run dev(nodemon 热重载)与 pnpm start(运行 OSS 向量库示例脚本 src/oss/examples/vector-stores/index.ts)可用于本地快速验证。

每一次改动之后都应运行 pnpm run typechecktsc --noEmit),这是文档强调的硬性纪律。

约定与工具链:与仓库其他子项目互不干扰

原文档列出的一系列约定,均可在仓库中逐条验证:

约定 仓库证据
Node 20 和 22 为 CI 测试版本 ts-sdk-ci.ymlmatrix.node-version: [20, 22]
构建:tsup,CJS + ESM 双输出 tsup.config.ts 中两个 entry 均为 format: ["cjs", "esm"]
格式化:Prettier,本包未配置 linter package.json devDependencies 仅有 prettier;CI 的 Lint 步骤即 prettier --check
测试:jest jest.config.js 使用 ts-jest preset
TypeScript strict 模式 tsconfig.json"strict": true
仅使用 ESM import 语法,禁止 require() 源码入口文件均为 export 形式(见 OSS 入口
源码文件 snake_case.ts,测试 <module>.test.ts src/oss/src/ 下的 memory.types.ts 等命名

需要特别留意的是文档中的提醒:不要假设全仓库共享同一套 lint 配置mem0-ts 用 Prettier + jest,而 cli/node/ 使用 Biome + vitest,integrations/vercel-ai-sdk/ 使用 ESLint,integrations/openclaw/ 使用 vitest。跨目录迁移代码或复制配置时,必须先确认目标子项目的工具链。

测试体系:ts-jest、路径映射与集成测试隔离

jest.config.js 的关键配置:

  • preset: "ts-jest",测试通过 tsconfig.test.json 转译(主 tsconfig.jsonexclude 明确排除了 **/*.test.ts,测试与构建两套编译配置分离);
  • roots: ["<rootDir>/src", "<rootDir>/tests"],即测试既可与源码同目录(*.test.ts),也可集中放在 tests/ 目录,对应原文档"<module>.test.ts"的命名约定;
  • moduleNameMapper^@/(.*)$ 映射到 <rootDir>/src/$1,与 tsconfig 的 paths: { "@/*": ["./src/*"] } 保持一致,源码中可用 @/... 别名导入;
  • setupFiles 加载 dotenv/configjest.setup.ts,意味着单测中可直接读取 .env 中的环境变量;
  • testPathIgnorePatterns 排除 /node_modules//dist/

CI 流程(ts-sdk-ci.yml)对测试的编排是:仅在 mem0-ts/** 路径变化时触发,依次执行 Prettier 检查、构建、pnpm run test:unit、包导出验证,随后在 Node 20/22 双矩阵上运行 pnpm run test:integrationmax-parallel: 1),覆盖率产物在 Node 20 节点上传为 coverage-report

公共 API 面与文档同步纪律

原文档指出,Memory 的方法面与 Python SDK 保持一致:addsearchgetgetAllupdatedeletedeleteAllhistory。并明确了一条跨仓库的硬性规则:

任何公共签名的变更,必须在同一个 PR 中更新 docs/

这条约定被 CI 强制执行:ts-sdk-ci.ymlchangelog_check 任务会在 PR 中比对 base 与 head 两个 SHA 的 mem0-ts/package.json 版本号,一旦发现版本 bump 而 docs/changelog/sdk.mdx 未变更,就会以错误信息终止流水线,要求"在 TypeScript tab 下为 v<新版本> 添加一条新的 <Update> 条目"。因此,改签名/升版本与更新 SDK 变更日志是不可拆分的原子操作。

发布流程:ts-v* 标签 + OIDC 发布 npm

原文档"Releasing"一节的完整描述为:

Tag 前缀 ts-v* 触发 ts-sdk-cd.yml,通过 OIDC 发布到 npm。先 bump package.json 中的版本号。

对照 .github/workflows/ts-sdk-cd.yml 可以看到完整链路:

  1. 触发方式:该工作流由 release 路由器在 ts-v* 标签发布后以 workflow_call 派发,也支持 workflow_dispatch 手动重发(输入 tag,如 ts-v2.1.0,并可选 prerelease 布尔值);作业入口有 if: startsWith(inputs.tag, 'ts-v') 的前缀校验。
  2. 环境:pnpm 10 + Node 22,pnpm install --frozen-lockfilecache-dependency-path 指向 mem0-ts/pnpm-lock.yaml),工作目录固定为 mem0-ts
  3. 构建pnpm run build(含 Prettier 门禁)。
  4. 发布npx npm@latest publish --provenance --access public,依赖 permissions.id-token: write 启用 GitHub OIDC 短期凭证,无长期 npm token 入库;--provenance 保证包可溯源到具体构建。
  5. 预发布处理:当 prerelease=true 时,脚本从 package.json 版本号的 preid(例如 x.y.z-beta 中的 beta)提取 dist-tag,改为 --tag "$PREID" 发布,避免预发布版本抢占 latest

因此发布顺序是:先改 package.jsonversion(并按需更新 docs/changelog/sdk.mdx)→ 打 ts-v<版本> 标签 → CI 自动构建并经 OIDC 发布,本地不需要执行 npm publish

小结:参与该 SDK 开发前的检查清单

  • 工具链:pnpm(勿用 npm/yarn)、Node 20 或 22、Prettier、jest、TypeScript 5.5(strict 开启);
  • 每次改动后:pnpm run typecheck,必要时 pnpm run buildpnpm run test
  • 集成测试前:配置 MEM0_API_KEY,然后 pnpm run test:integration
  • 改公共签名:同 PR 内更新 docs/
  • 升版本:bump mem0-ts/package.jsonversion + 更新 docs/changelog/sdk.mdx,打 ts-v* 标签交由 ts-sdk-cd.yml 完成 OIDC 发布。
登录后查看全文
热门项目推荐
相关项目推荐