Skip to content
pastdotdevPublic

About

past dev memory for the Vercel AI SDK

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

@pastdotdev/ai-sdk

past dev is a memory API for AI agents. This package gives an agent built with the Vercel AI SDK long-term memory through two tools, Recall and Ingest, and an optional middleware that recalls before each model call.

  • pastTools() returns the AI SDK tools recall and ingest.
  • pastRecallMiddleware() adds a small, ranked recall to the prompt of each model call.
  • createPastClient() is the small fetch client under both, with deleteDataPoint() for retraction.

It works with AI SDK 7, any model provider, Node 20 or later, and edge runtimes that have fetch.

Install

npm install @pastdotdev/ai-sdk ai zod

Get a project API key (it starts with past_sk_) from the past dev console, and set it:

export PAST_API_KEY=past_sk_...

Tools

import { generateText, isStepCount } from 'ai';
import { pastTools } from '@pastdotdev/ai-sdk';

const { text } = await generateText({
  model: 'openai/gpt-5-mini',
  tools: pastTools({ identity: user.id }),
  stopWhen: isStepCount(5),
  prompt: 'Remember that my favourite editor is Neovim.',
});

With an agent:

import { ToolLoopAgent } from 'ai';
import { pastTools } from '@pastdotdev/ai-sdk';

const agent = new ToolLoopAgent({
  model: 'anthropic/claude-sonnet-5.5',
  instructions: 'You are a helpful assistant with long-term memory.',
  tools: pastTools({ identity: user.id }),
});

const result = await agent.generate({ prompt: 'Which editor do I use?' });
Tool API call What the model fills
recall POST /api/v1/recall query
ingest POST /api/v1/ingest content, and optionally timestamp (ISO 8601) and label

recall gives the model compact text: one numbered line per memory with its date, a mark when a later statement superseded it, and up to two quotations from its sources. Set modelOutput: 'json' to give the model the API's JSON instead. Source metadata is never put in the text.

ingest gives each call a new source id, and uses the same value as the idempotency key, so a retry of the same call never makes a second data point. The result carries sourceId, which deleteDataPoint() takes later. A new memory becomes readable after a short processing time.

The identity is yours to set

Recall needs an identity: the person whose memory it reads. Ingest names the identity as the author, and creates it the first time it sees it. Your code sets the identity, from your own session or user record. The model never chooses it. No tool schema has an identity field, so a prompt cannot make the model read or write another person's memory. Make the tools for each request, with the signed-in user's id.

Options

pastTools({
  identity: user.id,         // required
  apiKey: '...',             // default: PAST_API_KEY
  apiHost: 'https://...',    // default: PAST_API_HOST, then https://api.past.dev
  audience: 'team-a',        // the audience slug of each ingest; omit it for the whole project
  metadata: { app: 'chat' }, // your JSON, stored with each ingest; the model never sees it
  limit: 10,                 // the maximum number of memories in a recall (default 10)
  level: 'low',              // the evidence budget: low, medium, high, extra-high
  maxTokens: 4000,           // or an explicit budget in tokens (not with level)
  modelOutput: 'text',       // or 'json'
  descriptions: { recall: '...', ingest: '...' },
  fetch,                     // a custom fetch
});

apiHost is for a past dev deployment in your own cloud.

Recall middleware

The middleware recalls with the last user message as the query, before each model call, and adds the memories as one system message after your own system messages. It keeps the prompt small:

  • at most limit memories (default 5) from an evidence budget of maxTokens (default 1,000);
  • at most maxChars characters of memory text (default 4,000), dropping the lowest-ranked memories to fit;
  • no superseded memories, unless you set skipSuperseded: false;
  • control characters removed, and the block marked as notes, not instructions.

It adds nothing when the message has no text, when nothing matches, or when the recall fails. A failed recall goes to onError (default: one console warning with the error code), and the model call goes on. Inside a tool loop, the same query within one minute reuses the first answer.

import { gateway, streamText, wrapLanguageModel } from 'ai';
import { pastRecallMiddleware } from '@pastdotdev/ai-sdk';

const model = wrapLanguageModel({
  model: gateway('openai/gpt-5-mini'),
  middleware: pastRecallMiddleware({ identity: user.id }),
});

const result = streamText({ model, prompt: 'What did we decide about the launch date?' });

The middleware only reads. Use the ingest tool, or createPastClient().ingest() in your own code, to write.

Client

import { createPastClient } from '@pastdotdev/ai-sdk';

const past = createPastClient(); // PAST_API_KEY, PAST_API_HOST

await past.listAudiences(); // free: a good connection test
await past.ingest({ content: 'Order 1042 shipped.', identity: user.id, id: 'order-1042' });
await past.recall({ query: 'order 1042', identity: user.id });
await past.deleteDataPoint('order-1042'); // the data point and the memory derived from it
await past.listIdentities({ limit: 100 }); // paged with hasMore and endCursor

Errors and credits

An API error is a PastApiError with code, status, debugMessage and requestId (the X-Request-Id header). Inside a tool, the AI SDK gives the error to the model as a tool error, and the loop goes on. A 429 is tried again at most twice, after the Retry-After time (at most 10 seconds). No other error is tried again: 402 out-of-credits and every 400 fail at once.

Every ingest spends credits, and so does a recall on plans that price one. The middleware recalls once per new user message. See pricing for the figures.

Development

npm ci
npm run check   # typecheck, build, tests

The tests use a fake fetch and the AI SDK mock model, so they spend nothing. One live smoke test (test/live.test.ts) runs only when PAST_API_KEY is set. It makes four calls: a free connection test, one ingest, one recall, and one delete.

Links

Questions: louis@past.dev.

License

MIT

About

past dev memory for the Vercel AI SDK

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages