@xtraceai/memory
v0.1.0
Published
TypeScript SDK for the xtrace memory API — with a Vercel AI SDK integration at @xtraceai/memory/ai-sdk
Maintainers
Readme
@xtraceai/memory
TypeScript SDK for the xtrace memory API — a hosted memory service for AI agents. Send conversation messages, get back structured facts, artifacts, and episodes; search them with vector + filter queries.
Install
npm install @xtraceai/memoryRequires Node 18+ (uses native fetch). Works in the browser too.
Get credentials
Sign in at app.xtrace.ai and grab two values from Settings → API Keys:
- API key —
xtk_… - Org id — your organization identifier
Both are required on every request. See the full docs for storage best practices.
Quickstart
import { MemoryClient } from "@xtraceai/memory";
const client = new MemoryClient({
apiKey: process.env.XTRACE_API_KEY!, // xtk_...
orgId: process.env.XTRACE_ORG_ID!, // org_...
});
// Ingest — async by default. `conv_id` is currently required.
const job = await client.memories.ingest({
messages: [{ role: "user", content: "I keep a daily log of every dog I see." }],
user_id: "alice",
conv_id: "conv_2026_05_15",
});
// Wait for extraction to finish
const done = await client.memories.jobs.pollUntilDone(job.id);
console.log(done.result?.memories_created);
// Or ingest synchronously (server waits up to 30s; falls back to async otherwise)
const sync = await client.memories.ingest(
{
messages: [{ role: "user", content: "I love Thai food." }],
user_id: "alice",
conv_id: "conv_2026_05_15",
},
{ wait: true },
);
if (sync.status === "succeeded") {
console.log(sync.result?.memories_created);
}
// Search
const results = await client.memories.search({
query: "what does the user like to eat?",
filters: { user_id: "alice" },
});
// List with auto-pagination
for await (const memory of client.memories.list({ user_id: "alice" })) {
console.log(memory.text);
}
// Get one
const memory = await client.memories.get(results.data[0]!.id);
// Update
await client.memories.update(memory.id, { text: "Updated content" });
// Delete (soft — sets details.status to "retracted"; hidden from list/search)
await client.memories.delete(memory.id);Vercel AI SDK integration
A separate subpath, @xtraceai/memory/ai-sdk, ships two ways to use the SDK with the Vercel AI SDK. Peer dependencies (ai, zod) are optional — they're only required if you import from this subpath.
Memory-aware model wrapper (auto-context + auto-ingest)
Wraps any LanguageModel so it searches your memory before each call and ingests the turn after. Set it and forget it:
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
import { createXtraceMemory } from "@xtraceai/memory/ai-sdk";
const xtrace = createXtraceMemory({
apiKey: process.env.XTRACE_API_KEY!,
orgId: process.env.XTRACE_ORG_ID!,
user_id: "alice",
conv_id: "conv_42",
});
const result = streamText({
model: xtrace(openai("gpt-4o-mini")), // memory-aware wrapper
messages,
});Memory as tools (LLM decides when to recall / save)
For agent loops where you want the model in control of memory access:
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
import { MemoryClient } from "@xtraceai/memory";
import { memoryTools } from "@xtraceai/memory/ai-sdk";
const client = new MemoryClient({ apiKey, orgId });
const result = streamText({
model: openai("gpt-4o-mini"),
tools: memoryTools(client, { user_id: "alice", conv_id: "conv_42" }),
messages,
});The model gets two tools: search_memory(query, limit?) and save_memory(fact). Use { includeSave: false } for read-only.
Errors
All errors extend MemoryError. Match on error.code for stable machine-readable handling:
import { MemoryNotFound, RateLimited } from "@xtraceai/memory";
try {
await client.memories.get("fact_does_not_exist");
} catch (err) {
if (err instanceof MemoryNotFound) {
// ...
} else if (err instanceof RateLimited) {
// err.retryAfter is the seconds to wait
}
}License
MIT
