Skip to content

@agentaily/agent-store

Agent 的状态 / 持久化层。可插拔的 seam + 对浏览器友好的默认实现,这样循环 (@agentaily/agent)与状态住在哪里保持解耦。

只依赖 @agentaily/llm(用它的 Message 线缆类型)。永不拉进 db 或 React —— 以保证它能安全地打进浏览器包。D1/fetch 后端的 store 是住在本包之外的适配器 (如 apps/web)。见 REFACTOR.md §8 / §8.1。

这里装着什么

SeamInterface默认实现内置工具
SkillSkilluseSkillTool(skills)use_skill
MemoryMemoryStore (MemoryEntry)InMemoryStoreLocalStorageStorerememberTool(memory)remember
ConversationConversationStore (Conversation, ConversationRecord)InMemoryConversationStoreLocalStorageConversationStore

还导出内置工具返回时共用的 Tool / ToolResult 形状。

ConversationStore 对标 LangGraph 的 checkpointer / Agents SDK 的 SessionABC (list / create / load / append / remove),它的存在是为了给会话跨会话的持久化 —— 今天循环把 messages[] 攥在一个私有字段里,所以一刷新就丢了对话记录。

状态: conversation seam 在这里已经定义 + 实现 + 测试,但循环还没消费它 —— 把 messages 挪到 store 背后(+ 重新水合)是下一个 PR。

用法

ts
import {
  InMemoryStore, LocalStorageStore, rememberTool,
  useSkillTool, type Skill,
  InMemoryConversationStore, LocalStorageConversationStore, type ConversationStore,
} from '@agentaily/agent-store';

const memory = new LocalStorageStore();            // persists notes across browser sessions
const skills: Skill[] = [{ name: 'market', description: '…', instructions: '…' }];

const sessions: ConversationStore = new LocalStorageConversationStore();
const conv = await sessions.create({ title: 'New chat' });
await sessions.append(conv.id, [{ role: 'user', content: [{ type: 'text', text: 'hi' }] }]);
const { messages } = (await sessions.load(conv.id))!;

向后兼容

Skill / useSkillTool / MemoryStore / MemoryEntry / InMemoryStore / rememberTool 以及 Tool / ToolResult 类型都@agentaily/agent re-export;LocalStorageStore@agentaily/agent-ui re-export。从那些包来的现有 import 保持原样可用。

测试

sh
pnpm --filter @agentaily/agent-store test       # vitest (node)
pnpm --filter @agentaily/agent-store typecheck