purra-mem0
v1.0.1
Published
Scoped Mem0 OSS memory integration for PurrA
Readme
purra-mem0 · TypeScript
English | 简体中文
使用 mem0ai/oss 的 Memory 提供作用域记忆、检索和生命周期管理。
要求 Node.js 22.13+,不支持托管的 Mem0 Platform 客户端。
安装
按照源码安装说明操作,选择
integrations/mem0/typescript。Mem0 的本地存储需要执行 better-sqlite3 的原生安装脚本。
原生受控模型和向量回调已包含在本包内,无需安装 LangChain。
导入 Mem0 前,设置 MEM0_TELEMETRY=false,并将 MEM0_DIR 指向应用管理的数据目录。
显式配置 LLM、embedder、vectorStore.config.dbPath 和 historyDbPath。
保存与读取
应用提供 mem0Config、已认证的 userId、已授权的 projectId,以及持久化 journalPath:
import { Memory } from "mem0ai/oss";
import { Mem0Memory } from "purra-mem0";
const sdk = new Memory(mem0Config);
const memory = new Mem0Memory({
client: sdk,
scope: { user: userId, project: projectId },
journalPath,
});
async function savePreference() {
const saved = await memory.add("Reply in Chinese.", {
source: { id: "preference:language", revision: "1" },
key: "preference:language:1",
});
return memory.get(saved.ids[0]!);
}add 默认创建已启用记录;需要先审核时设置 state: "pending"。
记录不可用时,get 返回 undefined。更新、状态切换和删除需要当前 version 与稳定的操作 key。
接入 Agent
提供 memoryQuery 函数,从 Core 的 ContextRequest 中选取查询文本:
import { RetrieverTool } from "purra";
import { MemoryContext } from "purra-mem0";
const recall = new RetrieverTool({
retriever: memory,
name: "recallMemory",
description: "Recall saved preferences and facts.",
});
const context = new MemoryContext({ memory, query: memoryQuery });将 recall.definition 加入 Agent 工具,或将 context 与其他上下文提供器组合。
记忆实例已经绑定作用域。需要显式选择记录时,使用 assembleMemoryContext(memory, ids, allowance)。
受控模型调用
调用需要持久化预算时,使用以下配置替代原生 SDK 客户端。 存储路径、向量维度和预算键由应用提供,数值仅用于演示预算配置。
modelTasks 是 PurrA 扩展工厂提供的执行器。
异步回调 embed(texts, signal) 需要返回 EmbeddingResult,包含向量和服务报告的输入 Token 用量。
import { createManagedClient, runModel } from "purra-mem0";
const client = await createManagedClient({
embeddingDims: embeddingDimensions,
config: { vectorStore: vectorStoreConfig, historyDbPath: historyPath },
});
const memory = new Mem0Memory({
client,
scope: { user: userId, project: projectId },
journalPath,
allowInference: true,
providers: {
budget: {
key: budgetKey,
maxLlmCalls: 4,
maxEmbeddingCalls: 64,
maxInputChars: 100_000,
maxOutputTokens: 8192,
resultCapacityTargetTokens: 2048,
},
complete: runModel(modelTasks),
embed,
},
});通过 memory.budgetUsage() 查看已准入调用和报告用量。原生 SDK 模式的内部用量记为未知。
resultCapacityTargetTokens 用于预留单次记忆结果的预期容量,并不是 Provider 生成上限。
runModel() 会保留 Run 的用户生成上限,并把该值记录为工作流容量目标。
提取与审查
配置受控模型调用并设置 allowInference: true 后:
import { MemoryWorkflow, type MemorySource } from "purra-mem0";
const workflow = new MemoryWorkflow(memory);
async function capture(
messages: readonly { role: "user" | "assistant"; content: string }[],
source: MemorySource,
operationKey: string,
) {
return workflow.capture(messages, { source, key: operationKey });
}此配置审查候选并让其保持待处理。需要应用决定时,为 MemoryWorkflow 传入
policy(candidate, review) 和稳定的 policyRevision。
策略返回已授权且保留审查键的 MemoryResolution,或返回 undefined 保持待处理;策略可以是异步函数。
需要在消息到达 Mem0 或 Provider 前强制授权时,绑定宿主签发的准确捕获意图:
import { MemoryWorkflow, memoryCaptureIntent } from "purra-mem0";
const authorization = {
intentDigest: memoryCaptureIntent(messages, { source, metadata }),
policyId: capturePolicyId,
policyRevision: capturePolicyRevision,
principalId: authenticatedUserId,
decisionId: hostDecisionId,
};
const workflow = new MemoryWorkflow(memory, { capturePolicyId, capturePolicyRevision });
await memory.recordCaptureAuthorization(authorization, {
key: `capture-authorization:${hostDecisionId}`,
expiresAt: captureAuthorizationExpiresAt,
});
const result = await workflow.capture(messages, {
source, key: operationKey, metadata, authorization,
});宿主负责认证、内容适用性和决定审计。重试必须沿用相同授权;缺失或不匹配的授权会在
操作日志及 Provider 调用前失败,同一 key 更换已绑定授权会触发幂等冲突。
调用 revokeCaptureAuthorization(policyId, decisionId, { key }) 可持久撤销决定,阻止
新的提取、审查和激活,并隐藏由其产生的记录。到期只阻止新处理;两者均不物理删除
Mem0 内容或历史。
生命周期
关闭前调用 await memory.drain() 和 memory.close(),再关闭 SDK 与模型服务资源。
分页、来源撤回、证据校验和不确定写入的处理见记忆生命周期指南。
原生受控适配
createManagedClient 把 PurrA 的原生模型和向量适配器注入包内、版本固定的 Mem0 私有模块,沿用现有预算、取消与结果校验。向量维度必须一致,受控路径拒绝 LangChain 向量库。不修改宿主安装的官方 SDK,也不启动代理服务。来源、许可证与修改说明见第三方声明。直接传入的原始 SDK 客户端仍由宿主管理,不自动获得受控回调的计费。
宿主选择与关系候选
MemoryContext 支持异步 selectIds(request, signal),与原有 query 二选一。
宿主返回有序记忆 ID;组件重新读取并验证来源、版本和预算,不接受替换文本。
purra-mem0 导出的 proposeMemoryRelations 接受记忆引用、宿主关系词表和异步 extract。
抽取回调返回仅含 from、to、relation、fromQuote、toQuote 字符串的对象数组。
组件校验原文引用与当前记忆版本,只返回候选,不自动写入关系。
关系是否成立、是否采纳和显式调用 memory.link 均由宿主决定。
模型调用的授权、超时和费用预算也由宿主负责。
