Yao provides four memory namespaces, each with a different lifetime. All are accessible via `ctx.memory.*` in any Hook.
## The Four Namespaces
| Namespace | Scope | When it's cleared |
|-----------|-------|------------------|
| `ctx.memory.context` | Current request | When the context is released (default TTL: 30 min) |
| `ctx.memory.chat` | Current chat session | When the chat ends or TTL expires (default: 24 h) |
| `ctx.memory.user` | Per user | Never (persistent) |
| `ctx.memory.team` | Per team | Never (persistent) |
**`context`** — temporary scratchpad for passing data from `Create` to `Next` within a single request.
**`chat`** — accumulates state as the conversation progresses (e.g., current topic, task progress).
**`user`** — long-term per-user preferences, counters, and history.
**`team`** — shared state across all users on a team (shared context, quotas, etc.).
## Basic Operations
All namespaces share the same API:
```typescript
// Write
ctx.memory.chat.Set("topic", "machine learning");
// Read
const topic = ctx.memory.chat.Get("topic") as string;
// Check / Delete
if (ctx.memory.chat.Has("topic")) {
ctx.memory.chat.Del("topic");
}
// Read and delete atomically
const token = ctx.memory.context.GetDel("one_time_token");
// All keys / count
const keys = ctx.memory.user.Keys();
const count = ctx.memory.chat.Len();
// Clear all
ctx.memory.context.Clear();
// Set with TTL (milliseconds)
ctx.memory.context.Set("temp_data", value, 300_000); // 300 000 ms = 5 minutes
```
## Counters
```typescript
const views = ctx.memory.user.Incr("page_views"); // +1, returns new value
const visits = ctx.memory.user.Incr("visits", 5); // +5
const credits = ctx.memory.user.Decr("credits", 10); // -10
```
## Common Patterns
### Pass Data from Create to Next
```typescript
// Create Hook
export function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
ctx.memory.context.Set("start_time", Date.now());
ctx.memory.context.Set("mode", detectMode(ctx));
return { messages };
}
// Next Hook
export function Next(ctx: agent.Context, payload: agent.Payload): agent.Next | null {
const startTime = ctx.memory.context.Get("start_time") as number;
const mode = ctx.memory.context.Get("mode") as string;
const duration = Date.now() - startTime;
ctx.Send(`Done in ${duration}ms (mode: ${mode})`);
return null;
}
```
### Accumulate Conversation State
```typescript
// Create Hook — load chat context
export function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
const taskCount = ctx.memory.chat.Get("task_count") as number || 0;
const topic = ctx.memory.chat.Get("current_topic") as string;
const enriched = [
{
role: "system" as const,
content: `Tasks completed this session: ${taskCount}. Topic: ${topic || "not set"}.`,
},
...messages,
];
return { messages: enriched };
}
// Next Hook — update state
export function Next(ctx: agent.Context, payload: agent.Payload): agent.Next | null {
const taskCount = ctx.memory.chat.Get("task_count") as number || 0;
ctx.memory.chat.Set("task_count", taskCount + 1);
return null;
}
```
### Track User Preferences
```typescript
// Next Hook — detect language preference from LLM response
export function Next(ctx: agent.Context, payload: agent.Payload): agent.Next | null {
const content = payload.completion?.content;
const text = typeof content === "string" ? content : "";
if (text.startsWith("以") || text.startsWith("您")) {
ctx.memory.user.Set("preferred_language", "zh");
}
return null;
}
// Create Hook — apply preference
export function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
const lang = ctx.memory.user.Get("preferred_language") as string;
if (lang === "zh") {
return { messages, locale: "zh-cn" };
}
return { messages };
}
```
### Rate Limiting
Use a connector-less assistant (no `prompts.yml`) so only the Create Hook runs. The LLM is never called when there are no prompts or MCP servers configured.
```typescript
export function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
const calls = ctx.memory.user.Incr("api_calls_today") as number;
if (calls > 100) {
ctx.Send("Daily limit reached. Try again tomorrow.");
return { messages };
}
return { messages };
}
```
## What's Next
With state management covered, you're ready to coordinate multiple agents.
→ **[Multi-Agent](./multi-agent)**