@statelyai/agent 1.1.6 → 2.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/cyan-carpets-perform.md +5 -0
- package/.changeset/fast-donkeys-argue.md +5 -0
- package/.changeset/light-hats-drive.md +9 -0
- package/.changeset/old-jobs-check.md +5 -0
- package/.changeset/pre.json +13 -0
- package/.vscode/launch.json +6 -0
- package/CHANGELOG.md +22 -0
- package/dist/index.d.mts +262 -171
- package/dist/index.d.ts +262 -171
- package/dist/index.js +383 -274
- package/dist/index.mjs +386 -272
- package/examples/chatbot-alt.ts +57 -0
- package/examples/chatbot.ts +12 -17
- package/examples/cot.ts +26 -23
- package/examples/customer-service-sim.ts +107 -0
- package/examples/email.ts +37 -41
- package/examples/example.ts +6 -6
- package/examples/executor.ts +66 -0
- package/examples/goal.ts +12 -12
- package/examples/helpers/helpers.ts +26 -14
- package/examples/joke.ts +79 -76
- package/examples/jugs.ts +125 -0
- package/examples/multi.ts +5 -5
- package/examples/newspaper.ts +98 -104
- package/examples/number.ts +6 -5
- package/examples/raffle.ts +11 -12
- package/examples/river-crossing.ts +140 -0
- package/examples/sandbox.ts +1 -1
- package/examples/simple.ts +5 -3
- package/examples/summary.ts +121 -0
- package/examples/support.ts +6 -6
- package/examples/ticTacToe.ts +86 -45
- package/examples/todo.ts +7 -7
- package/examples/tutor.ts +15 -15
- package/examples/verify.ts +3 -3
- package/examples/weather.ts +6 -9
- package/examples/wiki.ts +27 -8
- package/examples/word.ts +16 -11
- package/package.json +16 -11
- package/readme.md +1 -1
- package/src/agent-experimental.ts +1 -1
- package/src/agent.test.ts +243 -214
- package/src/agent.ts +286 -95
- package/src/decide.test.ts +276 -0
- package/src/decide.ts +163 -0
- package/src/index.ts +1 -1
- package/src/middleware.ts +91 -0
- package/src/mockModel.ts +47 -0
- package/src/planners/shortestPath.test.ts +94 -0
- package/src/planners/shortestPath.ts +177 -0
- package/src/planners/simple.ts +105 -0
- package/src/strategies/chain-of-note.ts +6 -55
- package/src/text.ts +51 -144
- package/src/types.ts +187 -212
- package/src/utils.ts +48 -4
- package/vitest.config.ts +9 -3
- package/src/adapters/vercel.ts +0 -7
- package/src/decision.test.ts +0 -179
- package/src/decision.ts +0 -84
- package/src/memory.ts +0 -25
- package/src/planners/shortestPathPlanner.ts +0 -22
- package/src/planners/simplePlanner.ts +0 -139
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createAgent } from '../src';
|
|
3
|
+
import { openai } from '@ai-sdk/openai';
|
|
4
|
+
import { getFromTerminal } from './helpers/helpers';
|
|
5
|
+
|
|
6
|
+
const agent = createAgent({
|
|
7
|
+
id: 'chatbot',
|
|
8
|
+
model: openai('gpt-4o-mini'),
|
|
9
|
+
events: {
|
|
10
|
+
'agent.respond': z.object({
|
|
11
|
+
response: z.string().describe('The response from the agent'),
|
|
12
|
+
}),
|
|
13
|
+
'agent.endConversation': z.object({}).describe('Stop the conversation'),
|
|
14
|
+
},
|
|
15
|
+
context: {
|
|
16
|
+
userMessage: z.string(),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
async function main() {
|
|
21
|
+
let status = 'listening';
|
|
22
|
+
let userMessage = '';
|
|
23
|
+
|
|
24
|
+
while (status !== 'finished') {
|
|
25
|
+
switch (status) {
|
|
26
|
+
case 'listening':
|
|
27
|
+
userMessage = await getFromTerminal('User:');
|
|
28
|
+
status = 'responding';
|
|
29
|
+
break;
|
|
30
|
+
|
|
31
|
+
case 'responding':
|
|
32
|
+
const decision = await agent.decide({
|
|
33
|
+
messages: agent.getMessages(),
|
|
34
|
+
goal: 'Respond to the user, unless they want to end the conversation.',
|
|
35
|
+
state: {
|
|
36
|
+
value: status,
|
|
37
|
+
context: {
|
|
38
|
+
userMessage: 'User says: ' + userMessage,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (decision?.nextEvent?.type === 'agent.respond') {
|
|
44
|
+
console.log(`Agent: ${decision.nextEvent.response}`);
|
|
45
|
+
status = 'listening';
|
|
46
|
+
} else if (decision?.nextEvent?.type === 'agent.endConversation') {
|
|
47
|
+
status = 'finished';
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log('End of conversation.');
|
|
54
|
+
process.exit();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main().catch(console.error);
|
package/examples/chatbot.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { z } from 'zod';
|
|
|
2
2
|
import { createAgent, fromDecision } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { assign, createActor, log, setup } from 'xstate';
|
|
5
|
-
import {
|
|
5
|
+
import { fromTerminal } from './helpers/helpers';
|
|
6
6
|
|
|
7
7
|
const agent = createAgent({
|
|
8
|
-
|
|
9
|
-
model: openai('gpt-
|
|
8
|
+
id: 'chatbot',
|
|
9
|
+
model: openai('gpt-4o-mini'),
|
|
10
10
|
events: {
|
|
11
11
|
'agent.respond': z.object({
|
|
12
12
|
response: z.string().describe('The response from the agent'),
|
|
@@ -20,7 +20,7 @@ const agent = createAgent({
|
|
|
20
20
|
|
|
21
21
|
const machine = setup({
|
|
22
22
|
types: agent.types,
|
|
23
|
-
actors: {
|
|
23
|
+
actors: { getFromTerminal: fromTerminal },
|
|
24
24
|
}).createMachine({
|
|
25
25
|
initial: 'listening',
|
|
26
26
|
context: {
|
|
@@ -33,26 +33,16 @@ const machine = setup({
|
|
|
33
33
|
input: 'User:',
|
|
34
34
|
onDone: {
|
|
35
35
|
actions: assign({
|
|
36
|
-
userMessage: (
|
|
36
|
+
userMessage: ({ event }) => event.output,
|
|
37
37
|
}),
|
|
38
38
|
target: 'responding',
|
|
39
39
|
},
|
|
40
40
|
},
|
|
41
41
|
},
|
|
42
42
|
responding: {
|
|
43
|
-
invoke: {
|
|
44
|
-
src: 'agent',
|
|
45
|
-
input: (x) => ({
|
|
46
|
-
context: {
|
|
47
|
-
userMessage: 'User says: ' + x.context.userMessage,
|
|
48
|
-
},
|
|
49
|
-
messages: agent.getMessages(),
|
|
50
|
-
goal: 'Respond to the user, unless they want to end the conversation.',
|
|
51
|
-
}),
|
|
52
|
-
},
|
|
53
43
|
on: {
|
|
54
44
|
'agent.respond': {
|
|
55
|
-
actions:
|
|
45
|
+
actions: log(({ event }) => `Agent: ${event.response}`),
|
|
56
46
|
target: 'listening',
|
|
57
47
|
},
|
|
58
48
|
'agent.endConversation': 'finished',
|
|
@@ -68,4 +58,9 @@ const machine = setup({
|
|
|
68
58
|
},
|
|
69
59
|
});
|
|
70
60
|
|
|
71
|
-
createActor(machine).start();
|
|
61
|
+
const actor = createActor(machine).start();
|
|
62
|
+
|
|
63
|
+
agent.interact(actor, () => ({
|
|
64
|
+
goal: 'Respond to the user, unless they want to end the conversation.',
|
|
65
|
+
messages: agent.getMessages(),
|
|
66
|
+
}));
|
package/examples/cot.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { z } from 'zod';
|
|
|
2
2
|
import { createAgent, fromDecision } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { assign, createActor, log, setup } from 'xstate';
|
|
5
|
-
import {
|
|
5
|
+
import { fromTerminal } from './helpers/helpers';
|
|
6
6
|
|
|
7
7
|
const agent = createAgent({
|
|
8
|
-
|
|
9
|
-
model: openai('gpt-4o'),
|
|
8
|
+
id: 'chain-of-thought',
|
|
9
|
+
model: openai('gpt-4o-mini'),
|
|
10
10
|
events: {
|
|
11
11
|
'agent.think': z.object({
|
|
12
12
|
thought: z
|
|
@@ -25,7 +25,7 @@ const agent = createAgent({
|
|
|
25
25
|
|
|
26
26
|
const machine = setup({
|
|
27
27
|
types: agent.types,
|
|
28
|
-
actors: {
|
|
28
|
+
actors: { getFromTerminal: fromTerminal },
|
|
29
29
|
}).createMachine({
|
|
30
30
|
initial: 'asking',
|
|
31
31
|
context: {
|
|
@@ -39,26 +39,19 @@ const machine = setup({
|
|
|
39
39
|
input: 'What would you like to ask?',
|
|
40
40
|
onDone: {
|
|
41
41
|
actions: assign({
|
|
42
|
-
question: (
|
|
42
|
+
question: ({ event }) => event.output,
|
|
43
43
|
}),
|
|
44
44
|
target: 'thinking',
|
|
45
45
|
},
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
thinking: {
|
|
49
|
-
invoke: {
|
|
50
|
-
src: 'agent',
|
|
51
|
-
input: (x) => ({
|
|
52
|
-
context: x.context,
|
|
53
|
-
goal: 'Answer the question. Think step-by-step.',
|
|
54
|
-
}),
|
|
55
|
-
},
|
|
56
49
|
on: {
|
|
57
50
|
'agent.think': {
|
|
58
51
|
actions: [
|
|
59
|
-
log((
|
|
52
|
+
log(({ event }) => `Thought: ${event.thought}`),
|
|
60
53
|
assign({
|
|
61
|
-
thought: (
|
|
54
|
+
thought: ({ event }) => event.thought,
|
|
62
55
|
}),
|
|
63
56
|
],
|
|
64
57
|
target: 'answering',
|
|
@@ -66,16 +59,9 @@ const machine = setup({
|
|
|
66
59
|
},
|
|
67
60
|
},
|
|
68
61
|
answering: {
|
|
69
|
-
invoke: {
|
|
70
|
-
src: 'agent',
|
|
71
|
-
input: (x) => ({
|
|
72
|
-
context: x.context,
|
|
73
|
-
goal: 'Answer the question',
|
|
74
|
-
}),
|
|
75
|
-
},
|
|
76
62
|
on: {
|
|
77
63
|
'agent.answer': {
|
|
78
|
-
actions:
|
|
64
|
+
actions: log(({ event }) => `Answer: ${event.answer}`),
|
|
79
65
|
target: 'answered',
|
|
80
66
|
},
|
|
81
67
|
},
|
|
@@ -86,4 +72,21 @@ const machine = setup({
|
|
|
86
72
|
},
|
|
87
73
|
});
|
|
88
74
|
|
|
89
|
-
createActor(machine).start();
|
|
75
|
+
const actor = createActor(machine).start();
|
|
76
|
+
|
|
77
|
+
agent.interact(actor, (obs) => {
|
|
78
|
+
if (obs.state.matches('thinking')) {
|
|
79
|
+
return {
|
|
80
|
+
goal: 'Think step-by-step about how you would answer the question',
|
|
81
|
+
context: obs.state.context,
|
|
82
|
+
messages: agent.getMessages(),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (obs.state.matches('answering')) {
|
|
86
|
+
return {
|
|
87
|
+
goal: 'Answer the question',
|
|
88
|
+
context: obs.state.context,
|
|
89
|
+
messages: agent.getMessages(),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createAgent, fromDecision } from '../src';
|
|
2
|
+
import { assign, createActor, setup } from 'xstate';
|
|
3
|
+
import { openai } from '@ai-sdk/openai';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
// Create customer service agent
|
|
7
|
+
const customerServiceAgent = createAgent({
|
|
8
|
+
id: 'customer-service',
|
|
9
|
+
model: openai('gpt-4o'),
|
|
10
|
+
events: {
|
|
11
|
+
'agent.respond': z.object({
|
|
12
|
+
response: z
|
|
13
|
+
.string()
|
|
14
|
+
.describe('The response from the customer service agent'),
|
|
15
|
+
}),
|
|
16
|
+
},
|
|
17
|
+
description: 'You are a customer service agent for an airline.',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Create simulated customer agent
|
|
21
|
+
const customerAgent = createAgent({
|
|
22
|
+
id: 'customer',
|
|
23
|
+
model: openai('gpt-4o-mini'),
|
|
24
|
+
events: {
|
|
25
|
+
'agent.respond': z.object({
|
|
26
|
+
response: z.string().describe('The response from the customer'),
|
|
27
|
+
}),
|
|
28
|
+
'agent.finish': z.object({}).describe('End the conversation'),
|
|
29
|
+
},
|
|
30
|
+
description: `You are Harrison, a customer trying to get a refund for a trip to Alaska.
|
|
31
|
+
You want them to give you ALL the money back. Be extremely persistent. This trip happened 5 years ago.
|
|
32
|
+
If you have nothing more to add to the conversation, send agent.finish event.`,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const machine = setup({
|
|
36
|
+
types: {
|
|
37
|
+
context: {} as {
|
|
38
|
+
messages: string[];
|
|
39
|
+
},
|
|
40
|
+
events: {} as
|
|
41
|
+
| typeof customerServiceAgent.types.events
|
|
42
|
+
| typeof customerAgent.types.events,
|
|
43
|
+
},
|
|
44
|
+
actors: {
|
|
45
|
+
customerService: fromDecision(customerServiceAgent),
|
|
46
|
+
customer: fromDecision(customerAgent),
|
|
47
|
+
},
|
|
48
|
+
}).createMachine({
|
|
49
|
+
initial: 'customerService',
|
|
50
|
+
context: {
|
|
51
|
+
messages: [],
|
|
52
|
+
},
|
|
53
|
+
states: {
|
|
54
|
+
customerService: {
|
|
55
|
+
invoke: {
|
|
56
|
+
src: 'customerService',
|
|
57
|
+
input: ({ context }) => ({
|
|
58
|
+
goal: 'Respond to the customer message',
|
|
59
|
+
context,
|
|
60
|
+
}),
|
|
61
|
+
},
|
|
62
|
+
on: {
|
|
63
|
+
'agent.respond': {
|
|
64
|
+
target: 'customer',
|
|
65
|
+
actions: assign({
|
|
66
|
+
messages: ({ context, event }) => [
|
|
67
|
+
...context.messages,
|
|
68
|
+
event.response,
|
|
69
|
+
],
|
|
70
|
+
}),
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
customer: {
|
|
75
|
+
invoke: {
|
|
76
|
+
src: 'customer',
|
|
77
|
+
input: ({ context }) => ({
|
|
78
|
+
goal: 'Respond to the customer service agent, or finish the conversation if you have nothing more to add.',
|
|
79
|
+
context,
|
|
80
|
+
}),
|
|
81
|
+
},
|
|
82
|
+
on: {
|
|
83
|
+
'agent.respond': {
|
|
84
|
+
target: 'customerService',
|
|
85
|
+
actions: assign({
|
|
86
|
+
messages: ({ context, event }) => [
|
|
87
|
+
...context.messages,
|
|
88
|
+
event.response,
|
|
89
|
+
],
|
|
90
|
+
}),
|
|
91
|
+
},
|
|
92
|
+
'agent.finish': 'done',
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
done: {
|
|
96
|
+
type: 'final',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const actor = createActor(machine);
|
|
102
|
+
actor.subscribe((state) => {
|
|
103
|
+
console.log('State:', state.value);
|
|
104
|
+
console.log('Messages:', state.context.messages);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
actor.start();
|
package/examples/email.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { z } from 'zod';
|
|
|
2
2
|
import { createAgent, fromDecision } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { assign, createActor, setup } from 'xstate';
|
|
5
|
-
import {
|
|
5
|
+
import { fromTerminal } from './helpers/helpers';
|
|
6
6
|
|
|
7
7
|
const agent = createAgent({
|
|
8
|
-
|
|
9
|
-
model: openai('gpt-
|
|
8
|
+
id: 'email',
|
|
9
|
+
model: openai('gpt-4o-mini'),
|
|
10
10
|
events: {
|
|
11
11
|
askForClarification: z.object({
|
|
12
12
|
questions: z.array(z.string()).describe('The questions to ask the agent'),
|
|
@@ -15,6 +15,14 @@ const agent = createAgent({
|
|
|
15
15
|
email: z.string().describe('The email to submit'),
|
|
16
16
|
}),
|
|
17
17
|
},
|
|
18
|
+
context: {
|
|
19
|
+
email: z.string().describe('The email to respond to'),
|
|
20
|
+
instructions: z.string().describe('The instructions for the email'),
|
|
21
|
+
clarifications: z
|
|
22
|
+
.array(z.string())
|
|
23
|
+
.describe('The clarifications to the email'),
|
|
24
|
+
replyEmail: z.string().nullable().describe('The email to submit'),
|
|
25
|
+
},
|
|
18
26
|
});
|
|
19
27
|
|
|
20
28
|
const machine = setup({
|
|
@@ -24,39 +32,22 @@ const machine = setup({
|
|
|
24
32
|
email: string;
|
|
25
33
|
instructions: string;
|
|
26
34
|
},
|
|
27
|
-
context:
|
|
28
|
-
email: string;
|
|
29
|
-
instructions: string;
|
|
30
|
-
clarifications: string[];
|
|
31
|
-
replyEmail: string | null;
|
|
32
|
-
},
|
|
35
|
+
context: agent.types.context,
|
|
33
36
|
},
|
|
34
|
-
actors: {
|
|
37
|
+
actors: { getFromTerminal: fromTerminal },
|
|
35
38
|
}).createMachine({
|
|
36
39
|
initial: 'checking',
|
|
37
|
-
context: (
|
|
38
|
-
email:
|
|
39
|
-
instructions:
|
|
40
|
+
context: ({ input }) => ({
|
|
41
|
+
email: input.email,
|
|
42
|
+
instructions: input.instructions,
|
|
40
43
|
clarifications: [],
|
|
41
44
|
replyEmail: null,
|
|
42
45
|
}),
|
|
43
46
|
states: {
|
|
44
47
|
checking: {
|
|
45
|
-
invoke: {
|
|
46
|
-
src: 'agent',
|
|
47
|
-
input: (x) => ({
|
|
48
|
-
context: {
|
|
49
|
-
email: x.context.email,
|
|
50
|
-
instructions: x.context.instructions,
|
|
51
|
-
clarifications: x.context.clarifications,
|
|
52
|
-
},
|
|
53
|
-
messages: agent.getMessages(),
|
|
54
|
-
goal: 'Respond to the email given the instructions and the provided clarifications. If not enough information is provided, ask for clarification. Otherwise, if you are absolutely sure that there is no ambiguous or missing information, create and submit a response email.',
|
|
55
|
-
}),
|
|
56
|
-
},
|
|
57
48
|
on: {
|
|
58
49
|
askForClarification: {
|
|
59
|
-
actions: (
|
|
50
|
+
actions: ({ event }) => console.log(event.questions.join('\n')),
|
|
60
51
|
target: 'clarifying',
|
|
61
52
|
},
|
|
62
53
|
submitEmail: {
|
|
@@ -70,25 +61,14 @@ const machine = setup({
|
|
|
70
61
|
input: `Please provide answers to the questions above`,
|
|
71
62
|
onDone: {
|
|
72
63
|
actions: assign({
|
|
73
|
-
clarifications: (
|
|
74
|
-
|
|
64
|
+
clarifications: ({ context, event }) =>
|
|
65
|
+
context.clarifications.concat(event.output),
|
|
75
66
|
}),
|
|
76
67
|
target: 'checking',
|
|
77
68
|
},
|
|
78
69
|
},
|
|
79
70
|
},
|
|
80
71
|
submitting: {
|
|
81
|
-
invoke: {
|
|
82
|
-
src: 'agent',
|
|
83
|
-
input: ({ context }) => ({
|
|
84
|
-
context: {
|
|
85
|
-
email: context.email,
|
|
86
|
-
instructions: context.instructions,
|
|
87
|
-
clarifications: context.clarifications,
|
|
88
|
-
},
|
|
89
|
-
goal: `Create and submit an email based on the instructions.`,
|
|
90
|
-
}),
|
|
91
|
-
},
|
|
92
72
|
on: {
|
|
93
73
|
submitEmail: {
|
|
94
74
|
actions: assign({
|
|
@@ -100,7 +80,7 @@ const machine = setup({
|
|
|
100
80
|
},
|
|
101
81
|
done: {
|
|
102
82
|
type: 'final',
|
|
103
|
-
entry: (
|
|
83
|
+
entry: ({ context }) => console.log(context.replyEmail),
|
|
104
84
|
},
|
|
105
85
|
},
|
|
106
86
|
exit: () => {
|
|
@@ -109,10 +89,26 @@ const machine = setup({
|
|
|
109
89
|
},
|
|
110
90
|
});
|
|
111
91
|
|
|
112
|
-
createActor(machine, {
|
|
92
|
+
const actor = createActor(machine, {
|
|
113
93
|
input: {
|
|
114
94
|
email: 'That sounds great! When are you available?',
|
|
115
95
|
instructions:
|
|
116
96
|
'Tell them exactly when I am available. Address them by his full (first and last) name.',
|
|
117
97
|
},
|
|
118
98
|
}).start();
|
|
99
|
+
|
|
100
|
+
agent.interact(actor, ({ state }) => {
|
|
101
|
+
if (state.matches('checking')) {
|
|
102
|
+
return {
|
|
103
|
+
goal: 'Respond to the email given the instructions and the provided clarifications. If not enough information is provided, ask for clarification. Otherwise, if you are absolutely sure that there is no ambiguous or missing information, create and submit a response email.',
|
|
104
|
+
context: state.context,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (state.matches('submitting')) {
|
|
109
|
+
return {
|
|
110
|
+
goal: 'Create and submit an email based on the instructions.',
|
|
111
|
+
context: state.context,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
});
|
package/examples/example.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { openai } from '@ai-sdk/openai';
|
|
|
4
4
|
import { assign, createActor, setup } from 'xstate';
|
|
5
5
|
|
|
6
6
|
const agent = createAgent({
|
|
7
|
-
|
|
8
|
-
model: openai('gpt-
|
|
7
|
+
id: 'example',
|
|
8
|
+
model: openai('gpt-4o-mini'),
|
|
9
9
|
events: {
|
|
10
10
|
'agent.englishSummary': z.object({
|
|
11
11
|
text: z.string().describe('The summary in English'),
|
|
@@ -32,8 +32,8 @@ const machine = setup({
|
|
|
32
32
|
invoke: [
|
|
33
33
|
{
|
|
34
34
|
src: 'summarizer',
|
|
35
|
-
input: (
|
|
36
|
-
context
|
|
35
|
+
input: ({ context }) => ({
|
|
36
|
+
context,
|
|
37
37
|
prompt:
|
|
38
38
|
'Summarize the patient visit in a single sentence. The summary should be in English.',
|
|
39
39
|
}),
|
|
@@ -45,8 +45,8 @@ const machine = setup({
|
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
src: 'summarizer',
|
|
48
|
-
input: (
|
|
49
|
-
context
|
|
48
|
+
input: ({ context }) => ({
|
|
49
|
+
context,
|
|
50
50
|
prompt:
|
|
51
51
|
'Summarize the patient visit in a single sentence. The summary should be in Spanish.',
|
|
52
52
|
}),
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { openai } from '@ai-sdk/openai';
|
|
2
|
+
import { createAgent, fromDecision } from '../src';
|
|
3
|
+
import { assign, createActor, createMachine, fromPromise } from 'xstate';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { fromTerminal } from './helpers/helpers';
|
|
6
|
+
|
|
7
|
+
const agent = createAgent({
|
|
8
|
+
model: openai('gpt-4o-mini'),
|
|
9
|
+
events: {
|
|
10
|
+
getTime: z.object({}).describe('Get the current time'),
|
|
11
|
+
other: z.object({}).describe('Do something else'),
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const machine = createMachine({
|
|
16
|
+
initial: 'start',
|
|
17
|
+
context: {
|
|
18
|
+
question: null,
|
|
19
|
+
},
|
|
20
|
+
states: {
|
|
21
|
+
start: {
|
|
22
|
+
invoke: {
|
|
23
|
+
src: fromTerminal,
|
|
24
|
+
input: 'What do you want to do?',
|
|
25
|
+
onDone: {
|
|
26
|
+
actions: assign({
|
|
27
|
+
question: ({ event }) => event.output,
|
|
28
|
+
}),
|
|
29
|
+
target: 'deciding',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
deciding: {
|
|
34
|
+
invoke: {
|
|
35
|
+
src: fromDecision(agent),
|
|
36
|
+
input: ({ context }) => ({
|
|
37
|
+
goal: 'Satisfy the user question',
|
|
38
|
+
context,
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
41
|
+
on: {
|
|
42
|
+
getTime: 'gettingTime',
|
|
43
|
+
other: 'other',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
gettingTime: {
|
|
47
|
+
invoke: {
|
|
48
|
+
src: fromPromise(async () => {
|
|
49
|
+
console.log('Time:', new Date().toLocaleTimeString());
|
|
50
|
+
}),
|
|
51
|
+
onDone: 'start',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
other: {
|
|
55
|
+
entry: () =>
|
|
56
|
+
console.log(
|
|
57
|
+
'You want me to do something else. I can only tell the time.'
|
|
58
|
+
),
|
|
59
|
+
after: {
|
|
60
|
+
1000: 'start',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
createActor(machine).start();
|
package/examples/goal.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { z } from 'zod';
|
|
|
2
2
|
import { createAgent, fromDecision } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { assign, createActor, log, setup } from 'xstate';
|
|
5
|
-
import {
|
|
5
|
+
import { fromTerminal } from './helpers/helpers';
|
|
6
6
|
|
|
7
7
|
const agent = createAgent({
|
|
8
|
-
|
|
9
|
-
model: openai('gpt-
|
|
8
|
+
id: 'goal',
|
|
9
|
+
model: openai('gpt-4o-mini'),
|
|
10
10
|
events: {
|
|
11
11
|
'agent.createGoal': z.object({
|
|
12
12
|
goal: z.string().describe('The goal for the conversation'),
|
|
@@ -27,7 +27,7 @@ const machine = setup({
|
|
|
27
27
|
},
|
|
28
28
|
events: agent.types.events,
|
|
29
29
|
},
|
|
30
|
-
actors: { decider, getFromTerminal },
|
|
30
|
+
actors: { decider, getFromTerminal: fromTerminal },
|
|
31
31
|
}).createMachine({
|
|
32
32
|
initial: 'gettingQuestion',
|
|
33
33
|
context: {
|
|
@@ -50,11 +50,11 @@ const machine = setup({
|
|
|
50
50
|
makingGoal: {
|
|
51
51
|
invoke: {
|
|
52
52
|
src: 'decider',
|
|
53
|
-
input: {
|
|
54
|
-
context
|
|
53
|
+
input: ({ context }) => ({
|
|
54
|
+
context,
|
|
55
55
|
goal: 'Determine what the user wants to accomplish. What is their ideal goal state? ',
|
|
56
56
|
maxRetries: 3,
|
|
57
|
-
},
|
|
57
|
+
}),
|
|
58
58
|
},
|
|
59
59
|
on: {
|
|
60
60
|
'agent.createGoal': {
|
|
@@ -62,7 +62,7 @@ const machine = setup({
|
|
|
62
62
|
assign({
|
|
63
63
|
goal: ({ event }) => event.goal,
|
|
64
64
|
}),
|
|
65
|
-
log((
|
|
65
|
+
log(({ event }) => `Goal: ${event.goal}`),
|
|
66
66
|
],
|
|
67
67
|
target: 'responding',
|
|
68
68
|
},
|
|
@@ -71,15 +71,15 @@ const machine = setup({
|
|
|
71
71
|
responding: {
|
|
72
72
|
invoke: {
|
|
73
73
|
src: 'decider',
|
|
74
|
-
input: {
|
|
75
|
-
context
|
|
74
|
+
input: ({ context }) => ({
|
|
75
|
+
context,
|
|
76
76
|
goal: 'Answer the question to achieve the stated goal, unless the goal is impossible to achieve.',
|
|
77
77
|
maxRetries: 3,
|
|
78
|
-
},
|
|
78
|
+
}),
|
|
79
79
|
},
|
|
80
80
|
on: {
|
|
81
81
|
'agent.respond': {
|
|
82
|
-
actions: log(({ event }) => event),
|
|
82
|
+
actions: log(({ event }) => `Response: ${event.response}`),
|
|
83
83
|
},
|
|
84
84
|
},
|
|
85
85
|
},
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import { fromPromise } from 'xstate';
|
|
2
2
|
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
});
|
|
3
|
+
export const fromTerminal = fromPromise<string, string>(async ({ input }) => {
|
|
4
|
+
const topic = await new Promise<string>((res) => {
|
|
5
|
+
console.log(input + '\n');
|
|
6
|
+
const listener = (data: Buffer) => {
|
|
7
|
+
const result = data.toString().trim();
|
|
8
|
+
process.stdin.off('data', listener);
|
|
9
|
+
res(result);
|
|
10
|
+
};
|
|
11
|
+
process.stdin.on('data', listener);
|
|
12
|
+
});
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
return topic;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export async function getFromTerminal(msg: string) {
|
|
18
|
+
const topic = await new Promise<string>((res) => {
|
|
19
|
+
console.log(msg + '\n');
|
|
20
|
+
const listener = (data: Buffer) => {
|
|
21
|
+
const result = data.toString().trim();
|
|
22
|
+
process.stdin.off('data', listener);
|
|
23
|
+
res(result);
|
|
24
|
+
};
|
|
25
|
+
process.stdin.on('data', listener);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return topic;
|
|
29
|
+
}
|