Repository navigation
Expand file tree
/
Copy pathmemory.ts
More file actions
64 lines (59 loc) · 2.37 KB
/
Copy pathmemory.ts
File metadata and controls
64 lines (59 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* An assistant with a memory: the facts it learns about you go into a table
* of its own SQL database, next to its conversation. Its tools write and read
* them through `ctx.db`, and a view of your own serves them, for a profile
* page say.
*
* OPENAI_API_KEY=… node basic/memory.ts
* npx @restatedev/restate-server # Restate, in another terminal
* npx @restatedev/restate deployments register http://localhost:9080
* curl localhost:8080/memory_assistant/alice/chat -d 'I am vegetarian, and I live in Lisbon.'
* curl localhost:8080/memory_assistant/alice/chat -d 'Suggest a restaurant for tonight.'
* curl localhost:8080/memory_assistant/alice/facts
*/
import { sessionObject, serve, tool } from '@restatedev/agents';
import * as pi from '@restatedev/agents/pi';
import { z } from 'zod';
const remember = tool({
name: 'remember',
description: 'Remember a fact about the user, for this conversation and later ones.',
input: z.object({ fact: z.string() }),
run: async ({ fact }, { ctx }) => {
await ctx.db.execute('INSERT OR IGNORE INTO facts (fact) VALUES (?)', [fact]);
return `Remembered: ${fact}`;
},
});
const recall = tool({
name: 'recall',
description: 'Everything remembered about the user.',
input: z.object({}),
run: async (_input, { ctx }) => {
const rows = await ctx.db.query<{ fact: string }>('SELECT fact FROM facts ORDER BY rowid');
return rows.map(({ fact }) => fact);
},
});
// An object of your own: the agent's handler and view, and yours beside them.
const assistant = sessionObject({
name: 'memory_assistant',
// Your own table, in each user's database next to the agent's tables.
schema: ['CREATE TABLE facts (fact TEXT PRIMARY KEY)'],
handlers: {
chat: pi.chat({
system: 'You are a helpful assistant. Remember what you learn about the user, and recall it when it helps.',
tools: [remember, recall],
}),
/** Forget a fact. */
forget: async (ctx, fact: string) => {
await ctx.db.execute('DELETE FROM facts WHERE fact = ?', [fact]);
},
},
views: {
messages: pi.messages(),
/** What the assistant knows about the user. A view, so it answers even while the agent is busy. */
facts: async (ctx) => {
const rows = await ctx.db.query<{ fact: string }>('SELECT fact FROM facts ORDER BY rowid');
return rows.map(({ fact }) => fact);
},
},
});
await serve(assistant);