@statelyai/agent 1.1.6 → 2.0.0-alpha.6
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/LICENSE +21 -0
- package/dist/ai-sdk.cjs +249 -0
- package/dist/ai-sdk.d.cts +168 -0
- package/dist/ai-sdk.d.mts +168 -0
- package/dist/ai-sdk.mjs +241 -0
- package/dist/cli.cjs +63 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +64 -0
- package/dist/decision-CX3YdwrO.cjs +1239 -0
- package/dist/decision-D1654JdD.mjs +940 -0
- package/dist/index.cjs +54 -0
- package/dist/index.d.cts +1217 -0
- package/dist/index.d.mts +1194 -405
- package/dist/index.mjs +3 -588
- package/dist/openai-compat.cjs +319 -0
- package/dist/openai-compat.d.cts +98 -0
- package/dist/openai-compat.d.mts +98 -0
- package/dist/openai-compat.mjs +312 -0
- package/dist/src-CEa947Dm.mjs +2449 -0
- package/dist/src-wBfi-kTA.cjs +2568 -0
- package/dist/text-logic-1ZQkO3zr.d.cts +682 -0
- package/dist/text-logic-2EMJIS-n.d.mts +682 -0
- package/dist/types-BHjeDdch.d.cts +208 -0
- package/dist/types-Cq1YlAQ6.d.mts +208 -0
- package/dist/utils-CWUCa3pF.d.mts +108 -0
- package/dist/utils-lK1wnL2i.d.cts +108 -0
- package/dist/zod.cjs +31 -0
- package/dist/zod.d.cts +30 -0
- package/dist/zod.d.mts +30 -0
- package/dist/zod.mjs +30 -0
- package/package.json +109 -28
- package/readme.md +144 -6
- package/schemas/agent-workflow.json +527 -0
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -11
- package/.env.template +0 -3
- package/.github/actions/ci-setup/action.yml +0 -24
- package/.github/workflows/release.yml +0 -46
- package/.vscode/launch.json +0 -28
- package/CHANGELOG.md +0 -222
- package/dist/index.d.ts +0 -428
- package/dist/index.js +0 -621
- package/examples/chatbot.ts +0 -71
- package/examples/cot.ts +0 -89
- package/examples/email.ts +0 -118
- package/examples/example.ts +0 -81
- package/examples/goal.ts +0 -94
- package/examples/helpers/helpers.ts +0 -17
- package/examples/helpers/loader.ts +0 -32
- package/examples/helpers/runner.ts +0 -27
- package/examples/joke.ts +0 -225
- package/examples/multi.ts +0 -103
- package/examples/newspaper.ts +0 -324
- package/examples/number.ts +0 -102
- package/examples/raffle.ts +0 -105
- package/examples/sandbox.ts +0 -28
- package/examples/simple.ts +0 -39
- package/examples/support.ts +0 -147
- package/examples/ticTacToe.ts +0 -224
- package/examples/todo.ts +0 -137
- package/examples/tutor.ts +0 -100
- package/examples/verify.ts +0 -120
- package/examples/weather.ts +0 -178
- package/examples/wiki.ts +0 -30
- package/examples/word.ts +0 -171
- package/src/adapters/vercel.ts +0 -7
- package/src/agent-experimental.ts +0 -221
- package/src/agent.test.ts +0 -506
- package/src/agent.ts +0 -300
- package/src/decision.test.ts +0 -179
- package/src/decision.ts +0 -84
- package/src/index.ts +0 -4
- package/src/memory.ts +0 -25
- package/src/planners/shortestPathPlanner.ts +0 -22
- package/src/planners/simplePlanner.ts +0 -139
- package/src/schemas.ts +0 -11
- package/src/strategies/chain-of-note.ts +0 -155
- package/src/templates/defaultText.ts +0 -18
- package/src/text.ts +0 -241
- package/src/types.ts +0 -499
- package/src/utils.ts +0 -72
- package/tsconfig.json +0 -109
- package/vitest.config.ts +0 -9
package/examples/support.ts
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { openai } from '@ai-sdk/openai';
|
|
2
|
-
import { createAgent, fromDecision } from '../src';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
import { createActor, log, setup } from 'xstate';
|
|
5
|
-
|
|
6
|
-
const agent = createAgent({
|
|
7
|
-
name: 'support-agent',
|
|
8
|
-
model: openai('gpt-4-1106-preview'),
|
|
9
|
-
events: {
|
|
10
|
-
'agent.respond': z.object({
|
|
11
|
-
response: z.string().describe('The response from the agent'),
|
|
12
|
-
}),
|
|
13
|
-
'agent.frontline.classify': z.object({
|
|
14
|
-
category: z
|
|
15
|
-
.enum(['billing', 'technical', 'other'])
|
|
16
|
-
.describe('The category of the customer issue'),
|
|
17
|
-
}),
|
|
18
|
-
'agent.refund': z
|
|
19
|
-
.object({
|
|
20
|
-
response: z.string().describe('The response from the agent'),
|
|
21
|
-
})
|
|
22
|
-
.describe('The agent wants to refund the user'),
|
|
23
|
-
'agent.technical.solve': z.object({
|
|
24
|
-
solution: z
|
|
25
|
-
.string()
|
|
26
|
-
.describe('The solution provided by the technical agent'),
|
|
27
|
-
}),
|
|
28
|
-
'agent.endConversation': z
|
|
29
|
-
.object({
|
|
30
|
-
response: z.string().describe('The response from the agent'),
|
|
31
|
-
})
|
|
32
|
-
.describe('The agent ends the conversation'),
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const machine = setup({
|
|
37
|
-
types: {
|
|
38
|
-
events: agent.types.events,
|
|
39
|
-
input: {} as string,
|
|
40
|
-
context: {} as {
|
|
41
|
-
customerIssue: string;
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
actors: { agent: fromDecision(agent) },
|
|
45
|
-
}).createMachine({
|
|
46
|
-
initial: 'frontline',
|
|
47
|
-
context: ({ input }) => ({
|
|
48
|
-
customerIssue: input,
|
|
49
|
-
}),
|
|
50
|
-
states: {
|
|
51
|
-
frontline: {
|
|
52
|
-
invoke: {
|
|
53
|
-
src: 'agent',
|
|
54
|
-
input: ({ context }) => ({
|
|
55
|
-
context,
|
|
56
|
-
system: `You are frontline support staff for LangCorp, a company that sells computers.
|
|
57
|
-
Be concise in your responses.
|
|
58
|
-
You can chat with customers and help them with basic questions, but if the customer is having a billing or technical problem,
|
|
59
|
-
do not try to answer the question directly or gather information.
|
|
60
|
-
Instead, immediately transfer them to the billing or technical team by asking the user to hold for a moment.
|
|
61
|
-
Otherwise, just respond conversationally.`,
|
|
62
|
-
goal: `The previous conversation is an interaction between a customer support representative and a user.
|
|
63
|
-
Classify whether the representative is routing the user to a billing or technical team, or whether they are just responding conversationally.`,
|
|
64
|
-
}),
|
|
65
|
-
},
|
|
66
|
-
on: {
|
|
67
|
-
'agent.frontline.classify': [
|
|
68
|
-
{
|
|
69
|
-
actions: log(({ event }) => event),
|
|
70
|
-
guard: ({ event }) => event.category === 'billing',
|
|
71
|
-
target: 'billing',
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
actions: log(({ event }) => event),
|
|
75
|
-
guard: ({ event }) => event.category === 'technical',
|
|
76
|
-
target: 'technical',
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
actions: log(({ event }) => event),
|
|
80
|
-
target: 'conversational',
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
billing: {
|
|
86
|
-
invoke: {
|
|
87
|
-
src: 'agent',
|
|
88
|
-
input: {
|
|
89
|
-
system:
|
|
90
|
-
'Your job is to detect whether a billing support representative wants to refund the user.',
|
|
91
|
-
goal: `The following text is a response from a customer support representative. Extract whether they want to refund the user or not.`,
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
on: {
|
|
95
|
-
'agent.refund': {
|
|
96
|
-
actions: log(({ event }) => event),
|
|
97
|
-
target: 'refund',
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
technical: {
|
|
102
|
-
invoke: {
|
|
103
|
-
src: 'agent',
|
|
104
|
-
input: {
|
|
105
|
-
context: true,
|
|
106
|
-
system: `You are an expert at diagnosing technical computer issues. You work for a company called LangCorp that sells computers. Help the user to the best of your ability, but be concise in your responses.`,
|
|
107
|
-
goal: 'Solve the customer issue.',
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
on: {
|
|
111
|
-
'agent.technical.solve': {
|
|
112
|
-
actions: log(({ event }) => event),
|
|
113
|
-
target: 'conversational',
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
conversational: {
|
|
118
|
-
invoke: {
|
|
119
|
-
src: 'agent',
|
|
120
|
-
input: {
|
|
121
|
-
goal: 'You are a customer support agent that is ending the conversation with the customer. Respond politely and thank them for their time.',
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
on: {
|
|
125
|
-
'agent.endConversation': {
|
|
126
|
-
actions: log((x) => x.event),
|
|
127
|
-
target: 'end',
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
refund: {
|
|
132
|
-
entry: () => console.log('Refunding...'),
|
|
133
|
-
after: {
|
|
134
|
-
1000: { target: 'conversational' },
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
end: {
|
|
138
|
-
type: 'final',
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
const actor = createActor(machine, {
|
|
144
|
-
input: `I've changed my mind and I want a refund for order #182818!`,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
actor.start();
|
package/examples/ticTacToe.ts
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { assign, setup, assertEvent, createActor } from 'xstate';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { createAgent, fromDecision, fromTextStream } from '../src';
|
|
4
|
-
import { openai } from '@ai-sdk/openai';
|
|
5
|
-
|
|
6
|
-
const agent = createAgent({
|
|
7
|
-
name: 'tic-tac-toe-bot',
|
|
8
|
-
model: openai('gpt-4-0125-preview'),
|
|
9
|
-
events: {
|
|
10
|
-
'agent.x.play': z.object({
|
|
11
|
-
index: z
|
|
12
|
-
.number()
|
|
13
|
-
.min(0)
|
|
14
|
-
.max(8)
|
|
15
|
-
.describe('The index of the cell to play on'),
|
|
16
|
-
}),
|
|
17
|
-
'agent.o.play': z.object({
|
|
18
|
-
index: z
|
|
19
|
-
.number()
|
|
20
|
-
.min(0)
|
|
21
|
-
.max(8)
|
|
22
|
-
.describe('The index of the cell to play on'),
|
|
23
|
-
}),
|
|
24
|
-
reset: z.object({}).describe('Reset the game to the initial state'),
|
|
25
|
-
},
|
|
26
|
-
context: {
|
|
27
|
-
board: z
|
|
28
|
-
.array(z.union([z.literal(null), z.literal('x'), z.literal('o')]))
|
|
29
|
-
.describe('The 3x3 board represented as a 9-element array.'),
|
|
30
|
-
moves: z
|
|
31
|
-
.number()
|
|
32
|
-
.min(0)
|
|
33
|
-
.max(9)
|
|
34
|
-
.describe('The number of moves made in the game.'),
|
|
35
|
-
player: z
|
|
36
|
-
.union([z.literal('x'), z.literal('o')])
|
|
37
|
-
.describe('The current player (x or o)'),
|
|
38
|
-
gameReport: z.string(),
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
type Player = 'x' | 'o';
|
|
43
|
-
|
|
44
|
-
const initialContext = {
|
|
45
|
-
board: Array(9).fill(null) as Array<Player | null>,
|
|
46
|
-
moves: 0,
|
|
47
|
-
player: 'x' as Player,
|
|
48
|
-
gameReport: '',
|
|
49
|
-
} satisfies typeof agent.types.context;
|
|
50
|
-
|
|
51
|
-
function getWinner(board: typeof initialContext.board): Player | null {
|
|
52
|
-
const lines = [
|
|
53
|
-
[0, 1, 2],
|
|
54
|
-
[3, 4, 5],
|
|
55
|
-
[6, 7, 8],
|
|
56
|
-
[0, 3, 6],
|
|
57
|
-
[1, 4, 7],
|
|
58
|
-
[2, 5, 8],
|
|
59
|
-
[0, 4, 8],
|
|
60
|
-
[2, 4, 6],
|
|
61
|
-
] as const;
|
|
62
|
-
for (const [a, b, c] of lines) {
|
|
63
|
-
if (board[a] !== null && board[a] === board[b] && board[a] === board[c]) {
|
|
64
|
-
return board[a]!;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export const ticTacToeMachine = setup({
|
|
71
|
-
types: {
|
|
72
|
-
context: agent.types.context,
|
|
73
|
-
events: agent.types.events,
|
|
74
|
-
},
|
|
75
|
-
actors: {
|
|
76
|
-
agent: fromDecision(agent),
|
|
77
|
-
gameReporter: fromTextStream(agent),
|
|
78
|
-
},
|
|
79
|
-
actions: {
|
|
80
|
-
updateBoard: assign({
|
|
81
|
-
board: ({ context, event }) => {
|
|
82
|
-
assertEvent(event, ['agent.x.play', 'agent.o.play']);
|
|
83
|
-
const updatedBoard = [...context.board];
|
|
84
|
-
updatedBoard[event.index] = context.player;
|
|
85
|
-
return updatedBoard;
|
|
86
|
-
},
|
|
87
|
-
moves: ({ context }) => context.moves + 1,
|
|
88
|
-
player: ({ context }) => (context.player === 'x' ? 'o' : 'x'),
|
|
89
|
-
}),
|
|
90
|
-
resetGame: assign(initialContext),
|
|
91
|
-
printBoard: ({ context }) => {
|
|
92
|
-
// Print the context.board in a 3 x 3 grid format
|
|
93
|
-
let boardString = '';
|
|
94
|
-
for (let i = 0; i < context.board.length; i++) {
|
|
95
|
-
if ([0, 3, 6].includes(i)) {
|
|
96
|
-
boardString += context.board[i] ?? ' ';
|
|
97
|
-
} else {
|
|
98
|
-
boardString += ' | ' + (context.board[i] ?? ' ');
|
|
99
|
-
if ([2, 5].includes(i)) {
|
|
100
|
-
boardString += '\n--+---+--\n';
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
console.log(boardString);
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
guards: {
|
|
109
|
-
checkWin: ({ context }) => {
|
|
110
|
-
const winner = getWinner(context.board);
|
|
111
|
-
|
|
112
|
-
return !!winner;
|
|
113
|
-
},
|
|
114
|
-
checkDraw: ({ context }) => {
|
|
115
|
-
return context.moves === 9;
|
|
116
|
-
},
|
|
117
|
-
isValidMove: ({ context, event }) => {
|
|
118
|
-
try {
|
|
119
|
-
assertEvent(event, ['agent.o.play', 'agent.x.play']);
|
|
120
|
-
} catch {
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return context.board[event.index] === null;
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
}).createMachine({
|
|
128
|
-
initial: 'playing',
|
|
129
|
-
context: initialContext,
|
|
130
|
-
states: {
|
|
131
|
-
playing: {
|
|
132
|
-
always: [
|
|
133
|
-
{ target: 'gameOver.winner', guard: 'checkWin' },
|
|
134
|
-
{ target: 'gameOver.draw', guard: 'checkDraw' },
|
|
135
|
-
],
|
|
136
|
-
initial: 'x',
|
|
137
|
-
states: {
|
|
138
|
-
x: {
|
|
139
|
-
entry: 'printBoard',
|
|
140
|
-
on: {
|
|
141
|
-
'agent.x.play': [
|
|
142
|
-
{
|
|
143
|
-
target: 'o',
|
|
144
|
-
guard: 'isValidMove',
|
|
145
|
-
actions: 'updateBoard',
|
|
146
|
-
},
|
|
147
|
-
{ target: 'x', reenter: true },
|
|
148
|
-
],
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
o: {
|
|
152
|
-
entry: 'printBoard',
|
|
153
|
-
on: {
|
|
154
|
-
'agent.o.play': [
|
|
155
|
-
{
|
|
156
|
-
target: 'x',
|
|
157
|
-
guard: 'isValidMove',
|
|
158
|
-
actions: 'updateBoard',
|
|
159
|
-
},
|
|
160
|
-
{ target: 'o', reenter: true },
|
|
161
|
-
],
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
gameOver: {
|
|
167
|
-
initial: 'winner',
|
|
168
|
-
invoke: {
|
|
169
|
-
src: 'gameReporter',
|
|
170
|
-
input: ({ context }) => ({
|
|
171
|
-
context: {
|
|
172
|
-
events: agent.getObservations().map((o) => o.event),
|
|
173
|
-
board: context.board,
|
|
174
|
-
},
|
|
175
|
-
prompt: 'Provide a short game report analyzing the game.',
|
|
176
|
-
}),
|
|
177
|
-
onSnapshot: {
|
|
178
|
-
actions: assign({
|
|
179
|
-
gameReport: ({ context, event }) => {
|
|
180
|
-
console.log(
|
|
181
|
-
context.gameReport + (event.snapshot.context?.textDelta ?? '')
|
|
182
|
-
);
|
|
183
|
-
return (
|
|
184
|
-
context.gameReport + (event.snapshot.context?.textDelta ?? '')
|
|
185
|
-
);
|
|
186
|
-
},
|
|
187
|
-
}),
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
states: {
|
|
191
|
-
winner: {
|
|
192
|
-
tags: 'winner',
|
|
193
|
-
},
|
|
194
|
-
draw: {
|
|
195
|
-
tags: 'draw',
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
on: {
|
|
199
|
-
reset: {
|
|
200
|
-
target: 'playing',
|
|
201
|
-
actions: 'resetGame',
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
const actor = createActor(ticTacToeMachine);
|
|
209
|
-
|
|
210
|
-
agent.interact(actor, (observed) => {
|
|
211
|
-
if (observed.state.matches('playing')) {
|
|
212
|
-
return {
|
|
213
|
-
goal: `You are playing a game of tic tac toe. This is the current game state. The 3x3 board is represented by a 9-element array. The first element is the top-left cell, the second element is the top-middle cell, the third element is the top-right cell, the fourth element is the middle-left cell, and so on. The value of each cell is either null, x, or o. The value of null means that the cell is empty. The value of x means that the cell is occupied by an x. The value of o means that the cell is occupied by an o.
|
|
214
|
-
|
|
215
|
-
${JSON.stringify(observed.state.context, null, 2)}
|
|
216
|
-
|
|
217
|
-
Execute the single best next move to try to win the game. Do not play on an existing cell.`,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return;
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
actor.start();
|
package/examples/todo.ts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { assign, setup, assertEvent, createActor, createMachine } from 'xstate';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { createAgent, fromDecision } from '../src';
|
|
4
|
-
import { openai } from '@ai-sdk/openai';
|
|
5
|
-
import { getFromTerminal } from './helpers/helpers';
|
|
6
|
-
|
|
7
|
-
const agent = createAgent({
|
|
8
|
-
name: 'todo',
|
|
9
|
-
model: openai('gpt-4o'),
|
|
10
|
-
events: {
|
|
11
|
-
addTodo: z.object({
|
|
12
|
-
title: z.string().min(1).max(100).describe('The title of the todo'),
|
|
13
|
-
content: z.string().min(1).max(100).describe('The content of the todo'),
|
|
14
|
-
}),
|
|
15
|
-
deleteTodo: z.object({
|
|
16
|
-
index: z.number().describe('The index of the todo to delete'),
|
|
17
|
-
}),
|
|
18
|
-
toggleTodo: z
|
|
19
|
-
.object({
|
|
20
|
-
index: z.number().describe('The index of the todo to toggle'),
|
|
21
|
-
})
|
|
22
|
-
.describe('Toggle whether the todo item is done or not'),
|
|
23
|
-
doNothing: z.object({}).describe('Do nothing'),
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
interface Todo {
|
|
28
|
-
title: string;
|
|
29
|
-
content: string;
|
|
30
|
-
done: boolean;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const machine = setup({
|
|
34
|
-
types: {
|
|
35
|
-
context: {} as {
|
|
36
|
-
todos: Todo[];
|
|
37
|
-
command: string | null;
|
|
38
|
-
},
|
|
39
|
-
events: {} as
|
|
40
|
-
| typeof agent.types.events
|
|
41
|
-
| { type: 'assist'; command: string },
|
|
42
|
-
},
|
|
43
|
-
actors: { agent: fromDecision(agent), getFromTerminal },
|
|
44
|
-
}).createMachine({
|
|
45
|
-
context: {
|
|
46
|
-
command: null,
|
|
47
|
-
todos: [],
|
|
48
|
-
},
|
|
49
|
-
on: {
|
|
50
|
-
addTodo: {
|
|
51
|
-
actions: assign({
|
|
52
|
-
todos: ({ context, event }) => [
|
|
53
|
-
...context.todos,
|
|
54
|
-
{
|
|
55
|
-
title: event.title,
|
|
56
|
-
content: event.content,
|
|
57
|
-
done: false,
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
command: null,
|
|
61
|
-
}),
|
|
62
|
-
target: '.idle',
|
|
63
|
-
},
|
|
64
|
-
deleteTodo: {
|
|
65
|
-
actions: assign({
|
|
66
|
-
todos: ({ context, event }) => {
|
|
67
|
-
const todos = [...context.todos];
|
|
68
|
-
todos.splice(event.index, 1);
|
|
69
|
-
return todos;
|
|
70
|
-
},
|
|
71
|
-
command: null,
|
|
72
|
-
}),
|
|
73
|
-
target: '.idle',
|
|
74
|
-
},
|
|
75
|
-
toggleTodo: {
|
|
76
|
-
actions: assign({
|
|
77
|
-
todos: ({ context, event }) => {
|
|
78
|
-
const todos = context.todos.map((todo, i) => {
|
|
79
|
-
if (i === event.index) {
|
|
80
|
-
return {
|
|
81
|
-
...todo,
|
|
82
|
-
done: !todo.done,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
return todo;
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
return todos;
|
|
89
|
-
},
|
|
90
|
-
command: null,
|
|
91
|
-
}),
|
|
92
|
-
target: '.idle',
|
|
93
|
-
},
|
|
94
|
-
doNothing: { target: '.idle' },
|
|
95
|
-
},
|
|
96
|
-
initial: 'idle',
|
|
97
|
-
states: {
|
|
98
|
-
idle: {
|
|
99
|
-
invoke: {
|
|
100
|
-
src: 'getFromTerminal',
|
|
101
|
-
input: '\nEnter a command:',
|
|
102
|
-
onDone: {
|
|
103
|
-
actions: assign({
|
|
104
|
-
command: ({ event }) => event.output,
|
|
105
|
-
}),
|
|
106
|
-
target: 'assisting',
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
on: {
|
|
110
|
-
assist: {
|
|
111
|
-
target: 'assisting',
|
|
112
|
-
actions: assign({
|
|
113
|
-
command: ({ event }) => event.command,
|
|
114
|
-
}),
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
assisting: {
|
|
119
|
-
invoke: {
|
|
120
|
-
src: 'agent',
|
|
121
|
-
input: (x) => ({
|
|
122
|
-
context: {
|
|
123
|
-
command: x.context.command,
|
|
124
|
-
todos: x.context.todos,
|
|
125
|
-
},
|
|
126
|
-
goal: 'Interpret the command as an action for this todo list; for example, "I need donuts" would add a todo item with the message "Get donuts".',
|
|
127
|
-
}),
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const actor = createActor(machine);
|
|
134
|
-
actor.subscribe((s) => {
|
|
135
|
-
console.log(s.context.todos);
|
|
136
|
-
});
|
|
137
|
-
actor.start();
|
package/examples/tutor.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { assign, createActor, log, setup } from 'xstate';
|
|
2
|
-
import { getFromTerminal } from './helpers/helpers';
|
|
3
|
-
import { createAgent, fromDecision } from '../src';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
import { openai } from '@ai-sdk/openai';
|
|
6
|
-
|
|
7
|
-
const agent = createAgent({
|
|
8
|
-
name: 'tutor',
|
|
9
|
-
model: openai('gpt-4-1106-preview'),
|
|
10
|
-
events: {
|
|
11
|
-
teach: z.object({
|
|
12
|
-
instruction: z
|
|
13
|
-
.string()
|
|
14
|
-
.describe(
|
|
15
|
-
'The feedback to give the human, correcting any grammatical errors, misspellings, etc.'
|
|
16
|
-
),
|
|
17
|
-
}),
|
|
18
|
-
respond: z.object({
|
|
19
|
-
response: z.string().describe('The response to the human in Spanish'),
|
|
20
|
-
}),
|
|
21
|
-
},
|
|
22
|
-
system:
|
|
23
|
-
'You are an expert Spanish tutor. You will respond to the human in Spanish.',
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const machine = setup({
|
|
27
|
-
types: {
|
|
28
|
-
context: {} as {
|
|
29
|
-
conversation: string[];
|
|
30
|
-
},
|
|
31
|
-
events: agent.types.events,
|
|
32
|
-
},
|
|
33
|
-
actors: { agent: fromDecision(agent), getFromTerminal },
|
|
34
|
-
}).createMachine({
|
|
35
|
-
initial: 'human',
|
|
36
|
-
context: {
|
|
37
|
-
conversation: [],
|
|
38
|
-
},
|
|
39
|
-
states: {
|
|
40
|
-
human: {
|
|
41
|
-
invoke: {
|
|
42
|
-
src: 'getFromTerminal',
|
|
43
|
-
input: 'Say something in Spanish:',
|
|
44
|
-
onDone: {
|
|
45
|
-
actions: assign({
|
|
46
|
-
conversation: (x) =>
|
|
47
|
-
x.context.conversation.concat(`User: ` + x.event.output),
|
|
48
|
-
}),
|
|
49
|
-
target: 'ai',
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
ai: {
|
|
54
|
-
initial: 'teaching',
|
|
55
|
-
states: {
|
|
56
|
-
teaching: {
|
|
57
|
-
invoke: {
|
|
58
|
-
src: 'agent',
|
|
59
|
-
input: (x) => ({
|
|
60
|
-
context: true,
|
|
61
|
-
goal: 'Give brief feedback to the human based on the most recent response of the conversation',
|
|
62
|
-
maxTokens: 100,
|
|
63
|
-
}),
|
|
64
|
-
},
|
|
65
|
-
on: {
|
|
66
|
-
teach: {
|
|
67
|
-
actions: (x) => console.log(x.event.instruction),
|
|
68
|
-
target: 'responding',
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
responding: {
|
|
73
|
-
invoke: {
|
|
74
|
-
src: 'agent',
|
|
75
|
-
input: (x) => ({
|
|
76
|
-
context: true,
|
|
77
|
-
goal: 'Respond to the last message of the conversation in Spanish',
|
|
78
|
-
}),
|
|
79
|
-
},
|
|
80
|
-
on: {
|
|
81
|
-
respond: {
|
|
82
|
-
actions: [
|
|
83
|
-
assign({
|
|
84
|
-
conversation: (x) =>
|
|
85
|
-
x.context.conversation.concat(`Agent: ` + x.event.response),
|
|
86
|
-
}),
|
|
87
|
-
log((x) => x.event.response),
|
|
88
|
-
],
|
|
89
|
-
target: 'done',
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
done: { type: 'final' },
|
|
94
|
-
},
|
|
95
|
-
onDone: { target: 'human' },
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
createActor(machine).start();
|