your agents, in minutes.
build AI agents that remember things, use tools, persist sessions, and work in teams. works with any model. no magic, no black boxes. just agents.
npm install @ridit/ai
# or
bun add @ridit/aii- any model — anthropic, openai, groq, google, ollama, openrouter
- memory — inject context into any session
- sessions — persist to disk or localStorage.
- compaction — context too long? it summarizes itself. automatically.
- tools — files, bash, memory, sub-agents, and more
import { buildProvider, runLLM } from "@ridit/ai";
import { FileWriteTool, ThinkTool } from "@ridit/ai/tools";
const provider = buildProvider({
provider: "anthropic",
model: "claude-sonnet-4-20250514",
apiKey: process.env.ANTHROPIC_API_KEY,
});
const { text, session } = await runLLM({
prompt: "create a hello world python script",
providerr,
tools: { ThinkTool, FileWriteTool },
});
console.log(text);that's it. agent runs, uses tools, returns text and the session.
import { buildProvider } from "@ridit/ai";
buildProvider({
provider: "anthropic",
model: "claude-sonnet-4-20250514",
apiKey: "...",
});
buildProvider({ provider: "openai", model: "gpt-4o", apiKey: "..." });
buildProvider({
provider: "groq",
model: "llama-3.3-70b-versatile",
apiKey: "...",
});
buildProvider({ provider: "google", model: "gemini-2.0-flash", apiKey: "..." });
buildProvider({ provider: "ollama", model: "llama3.2" }); // no key needed
buildProvider({
provider: "openrouter",
model: "meta-llama/llama-3.3-70b-instruct",
apiKey: "...",
});sessions are opt-in. no storage passed = runs in memory, nothing saved. your call.
import { createStore } from "@ridit/ai/utils";
const store = createStore({ ... });
const { session } = await runLLM({ prompt: "hey", provider, store });
// resume later
const { text } = await runLLM({
prompt: "what did i say before?",
providerr,
sessionn,
storagee,
});import { createStore } from "@ridit/ai/utils";
const store = createStore({
async save(session) {
localStorage.setItem(session.id, JSON.stringify(session));
},
async load(id) {
const s = localStorage.getItem(id);
return s ? JSON.parse(s) : null;
},
async list() {
return [];
},
});
const { text, session } = await runLLM({ prompt: "hi", provider, store });import { createStore } from "@ridit/ai/utils";
import { readFile, writeFile, mkdir } from "fs/promises";
import { join } from "path";
const sessionsDir = "./sessions";
await mkdir(sessionsDir, { recursive: true });
const store = createStore({
session: {
async save(session) {
await writeFile(
join(sessionsDir, `${session.id}.json`),
JSON.stringify(session),
"utf-8",
);
},
async load(id) {
try {
const raw = await readFile(join(sessionsDir, `${id}.json`), "utf-8");
return JSON.parse(raw);
} catch {
return null;
}
},
async list() {
return []; // implement if needed
},
},
memory: {
async read(name) {
return null;
},
async write(name, content) {},
async list() {
return [];
},
},
});
const { text, session } = await runLLM({ prompt: "hey", provider, store });
// resume later
const { text: text2 } = await runLLM({
prompt: "what did i say before?",
providerr,
storee,
sessionId: session.id,
});bring your own adapter. redis, supabase, sqlite — whatever you want.
import {
ThinkTool, // internal reasoning step
} from "@ridit/ai/tools";Memory tools need a store to store your memory.
import { createMemoryTools } from "@ridit/ai/tools";
const { MemoryReadTool, MemoryWriteTool, MemoryEditTool } =
createMemoryTools(store); // your storeCreate yours too!
when sessions get long, @ridit/ai summarizes the history and compacts it automatically before the next call. you don't have to think about it.
const { text } = await runLLM({
prompt: "review this PR",
providerr,
system: "you are a senior typescript engineer. be direct. no fluff.",
});create client 1 time, run as many times as your want without configuring multiple times.
const provider = buildProvider({
model: "openai/gpt-oss-120b",
provider: "groq",
apiKey: "...",
});
const client = createClient({ provider, tools: {} }); // tools is to set a global set of tools
const text = await client.run({
prompt: "hey!",
tools: { FileReadTool, FileWriteTool }, // override global tools
});
console.log(text);| field | type | required |
|---|---|---|
provider |
`"anthropic" | "openai" |
model |
string |
✅ |
apiKey |
string |
for hosted providers |
baseURL |
string |
for ollama / custom endpoints |
| field | type | description |
|---|---|---|
prompt |
string |
user message |
provider |
LanguageModel |
from buildProvider() |
system |
string |
system prompt |
tools |
object |
tool map |
session |
Session |
resume a session |
storage |
SessionStorage |
persistence adapter |
memoryContent |
string |
memory to inject |
steps |
number |
max agentic steps (default: 100) |
onToolCall |
function |
intercept before tool runs |
onToolResult |
function |
observe tool output |
abortSignal |
AbortSignal |
cancel in-flight requests |
Vercel AI SDK — model routing, tool calling, streaming
@ridit/ai started as the core of Milo — a terminal AI agent/pet. after building out memory, sessions, compaction, and multi-agent support there, it made sense to pull it out into a proper framework anyone could use.
if you want to see what you can build with it, go look at Milo.
MIT © Ridit Jangra
made with 💕