mirror of
https://github.com/vercel/eve.git
synced 2026-09-20 05:35:39 +08:00
e6ecaf6fb3
Signed-off-by: Andrew Barba <barba@hey.com>
73 lines
2.7 KiB
Plaintext
73 lines
2.7 KiB
Plaintext
---
|
|
title: "Remember Definitions"
|
|
description: "Part 5 of the Build an Agent tutorial. Use defineState to remember the team's metric glossary across turns."
|
|
---
|
|
|
|
Every team has house definitions for the analytics assistant. "Active" means a purchase in the last 30 days, revenue is net of refunds, a "week" starts Monday. Re-explaining all of that on every turn is a waste. State gives the agent a place to keep them.
|
|
|
|
`defineState(name, initial)` creates a typed, named slot that survives across step and turn boundaries within a session. You read it with `get()` and change it with `update()`.
|
|
|
|
## Define the glossary slot
|
|
|
|
```ts title="agent/lib/glossary.ts"
|
|
import { defineState } from "eve/context";
|
|
|
|
export interface Glossary {
|
|
readonly terms: Readonly<Record<string, string>>;
|
|
}
|
|
|
|
export const glossary = defineState<Glossary>("analytics.glossary", () => ({
|
|
terms: {},
|
|
}));
|
|
```
|
|
|
|
## Tools to read and write it
|
|
|
|
```ts title="agent/tools/define_metric.ts"
|
|
import { defineTool } from "eve/tools";
|
|
import { z } from "zod";
|
|
import { glossary } from "../lib/glossary";
|
|
|
|
export default defineTool({
|
|
description: "Record the team's definition of a metric so it persists across turns.",
|
|
inputSchema: z.object({ term: z.string(), meaning: z.string() }),
|
|
async execute({ term, meaning }) {
|
|
glossary.update((g) => ({ terms: { ...g.terms, [term]: meaning } }));
|
|
return glossary.get();
|
|
},
|
|
});
|
|
```
|
|
|
|
```ts title="agent/tools/recall_metrics.ts"
|
|
import { defineTool } from "eve/tools";
|
|
import { z } from "zod";
|
|
import { glossary } from "../lib/glossary";
|
|
|
|
export default defineTool({
|
|
description: "Read the team's recorded metric definitions.",
|
|
inputSchema: z.object({}),
|
|
async execute() {
|
|
return glossary.get();
|
|
},
|
|
});
|
|
```
|
|
|
|
## See it persist
|
|
|
|
```text
|
|
> For this dataset, a high-value customer has at least $50 in total orders.
|
|
Remember that.
|
|
→ calls define_metric("high-value customer", "at least $50 in total orders")
|
|
|
|
> How many high-value customers do we have?
|
|
→ recalls the definition, writes the matching SQL, answers
|
|
```
|
|
|
|
The sample data has two high-value customers: Acme ($57) and Globex ($99). This definition works with the same fixed dataset whenever you run the tutorial. The second turn is a separate turn in the same session, yet the definition is still there. State checkpoints at step boundaries, so it's the same durability from [Step 2](./how-it-runs), now applied to your own data.
|
|
|
|
State is scoped to a session and isolated per agent, so a subagent starts with fresh state and never sees the parent's. Need to reset something each turn? Call `update(() => fresh)` in a lifecycle hook. More in [State](../concepts/state).
|
|
|
|
→ Next: [Team playbooks](./team-playbooks)
|
|
|
|
Learn more: [State](../concepts/state)
|