@statelyai/agent 1.0.0-beta.0 → 1.0.0
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/heavy-moons-bake.md +12 -0
- package/.changeset/silly-berries-drop.md +5 -0
- package/.changeset/wild-bobcats-care.md +26 -0
- package/.env.template +0 -3
- package/.github/workflows/release.yml +3 -3
- package/dist/index.d.mts +152 -47
- package/dist/index.d.ts +152 -47
- package/dist/index.js +165 -110
- package/dist/index.mjs +155 -108
- package/examples/chatbot.ts +9 -17
- package/examples/cot.ts +5 -7
- package/examples/email.ts +2 -2
- package/examples/example.ts +7 -7
- package/examples/goal.ts +1 -1
- package/examples/joke.ts +8 -10
- package/examples/number.ts +1 -1
- package/examples/raffle.ts +1 -1
- package/examples/sandbox.ts +28 -0
- package/examples/support.ts +1 -1
- package/examples/ticTacToe.ts +18 -22
- package/examples/todo.ts +3 -1
- package/examples/tutor.ts +1 -1
- package/examples/verify.ts +1 -1
- package/examples/weather.ts +1 -1
- package/examples/wiki.ts +1 -1
- package/examples/word.ts +6 -3
- package/package.json +18 -10
- package/src/agent.test.ts +176 -4
- package/src/agent.ts +53 -18
- package/src/decision.ts +6 -5
- package/src/index.ts +2 -2
- package/src/planners/shortestPathPlanner.ts +2 -2
- package/src/planners/simplePlanner.ts +23 -12
- package/src/schemas.ts +4 -8
- package/src/strategies/chain-of-note.ts +3 -3
- package/src/text.ts +19 -31
- package/src/types.ts +134 -35
- package/src/utils.ts +59 -9
- package/src/templates/defaultToolCall.ts +0 -10
package/dist/index.mjs
CHANGED
|
@@ -9,18 +9,54 @@ import {
|
|
|
9
9
|
import { tool } from "ai";
|
|
10
10
|
|
|
11
11
|
// src/utils.ts
|
|
12
|
+
import hash from "object-hash";
|
|
12
13
|
function getAllTransitions(state) {
|
|
13
14
|
const nodes = state._nodes;
|
|
14
|
-
const transitions = nodes.map((node) => [...node.transitions.values()]).
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const transitions = nodes.map((node) => [...node.transitions.values()]).map((nodeTransitions) => {
|
|
16
|
+
return nodeTransitions.map((nodeEventTransitions) => {
|
|
17
|
+
return nodeEventTransitions.map((transition) => {
|
|
18
|
+
return {
|
|
19
|
+
...transition,
|
|
20
|
+
guard: typeof transition.guard === "string" ? { type: transition.guard } : transition.guard
|
|
21
|
+
// TODO: fix
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}).flat(2);
|
|
26
|
+
return transitions;
|
|
27
|
+
}
|
|
28
|
+
function getAllMachineTransitions(stateNode) {
|
|
29
|
+
const transitions = [...stateNode.transitions.values()].map((nodeTransitions) => {
|
|
30
|
+
return nodeTransitions.map((transition) => {
|
|
31
|
+
return {
|
|
32
|
+
...transition,
|
|
33
|
+
guard: typeof transition.guard === "string" ? { type: transition.guard } : transition.guard
|
|
34
|
+
// TODO: fix
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}).flat(2);
|
|
38
|
+
for (const s of Object.values(stateNode.states)) {
|
|
39
|
+
const stateTransitions = getAllMachineTransitions(s);
|
|
40
|
+
transitions.push(...stateTransitions);
|
|
41
|
+
}
|
|
19
42
|
return transitions;
|
|
20
43
|
}
|
|
21
44
|
function wrapInXml(tagName, content) {
|
|
22
45
|
return `<${tagName}>${content}</${tagName}>`;
|
|
23
46
|
}
|
|
47
|
+
function randomId() {
|
|
48
|
+
const timestamp = Date.now().toString(36);
|
|
49
|
+
const random = Math.random().toString(36).substring(2, 9);
|
|
50
|
+
return timestamp + random;
|
|
51
|
+
}
|
|
52
|
+
var machineHashes = /* @__PURE__ */ new WeakMap();
|
|
53
|
+
function getMachineHash(machine) {
|
|
54
|
+
if (machineHashes.has(machine)) return machineHashes.get(machine);
|
|
55
|
+
const transitions = getAllMachineTransitions(machine.root);
|
|
56
|
+
const machineHash = hash(transitions);
|
|
57
|
+
machineHashes.set(machine, machineHash);
|
|
58
|
+
return machineHash;
|
|
59
|
+
}
|
|
24
60
|
|
|
25
61
|
// src/templates/defaultText.ts
|
|
26
62
|
var defaultTextTemplate = (data) => {
|
|
@@ -34,99 +70,15 @@ ${data.goal}
|
|
|
34
70
|
`.trim();
|
|
35
71
|
};
|
|
36
72
|
|
|
37
|
-
// src/planners/simplePlanner.ts
|
|
38
|
-
function getTransitions(state, machine) {
|
|
39
|
-
if (!machine) {
|
|
40
|
-
return [];
|
|
41
|
-
}
|
|
42
|
-
const resolvedState = machine.resolveState(state);
|
|
43
|
-
return getAllTransitions(resolvedState);
|
|
44
|
-
}
|
|
45
|
-
var simplePlannerPromptTemplate = (data) => {
|
|
46
|
-
return `
|
|
47
|
-
${defaultTextTemplate(data)}
|
|
48
|
-
|
|
49
|
-
Only make a single tool call to achieve the above goal.
|
|
50
|
-
`.trim();
|
|
51
|
-
};
|
|
52
|
-
async function simplePlanner(agent, input) {
|
|
53
|
-
const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(input.events).map(([eventType, { description }]) => ({
|
|
54
|
-
eventType,
|
|
55
|
-
description
|
|
56
|
-
}));
|
|
57
|
-
const filter = (eventType) => Object.keys(input.events).includes(eventType);
|
|
58
|
-
const functionNameMapping = {};
|
|
59
|
-
const toolTransitions = transitions.filter((t) => {
|
|
60
|
-
return filter(t.eventType);
|
|
61
|
-
}).map((t) => {
|
|
62
|
-
const name = t.eventType.replace(/\./g, "_");
|
|
63
|
-
functionNameMapping[name] = t.eventType;
|
|
64
|
-
return {
|
|
65
|
-
type: "function",
|
|
66
|
-
eventType: t.eventType,
|
|
67
|
-
description: t.description,
|
|
68
|
-
name
|
|
69
|
-
};
|
|
70
|
-
});
|
|
71
|
-
const toolMap = {};
|
|
72
|
-
for (const toolTransitionData of toolTransitions) {
|
|
73
|
-
const toolZodType = input.events?.[toolTransitionData.eventType];
|
|
74
|
-
if (!toolZodType) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
toolMap[toolTransitionData.name] = tool({
|
|
78
|
-
description: toolZodType?.description ?? toolTransitionData.description,
|
|
79
|
-
parameters: toolZodType,
|
|
80
|
-
execute: async (params) => {
|
|
81
|
-
const event = {
|
|
82
|
-
type: toolTransitionData.eventType,
|
|
83
|
-
...params
|
|
84
|
-
};
|
|
85
|
-
return event;
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
const prompt = simplePlannerPromptTemplate({
|
|
90
|
-
context: input.state.context,
|
|
91
|
-
goal: input.goal
|
|
92
|
-
});
|
|
93
|
-
const result = await agent.generateText({
|
|
94
|
-
prompt,
|
|
95
|
-
tools: toolMap,
|
|
96
|
-
toolChoice: "required",
|
|
97
|
-
...input
|
|
98
|
-
});
|
|
99
|
-
const singleResult = result.toolResults[0];
|
|
100
|
-
if (!singleResult) {
|
|
101
|
-
console.warn("No tool call results returned");
|
|
102
|
-
return void 0;
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
goal: input.goal,
|
|
106
|
-
state: input.state,
|
|
107
|
-
steps: [
|
|
108
|
-
{
|
|
109
|
-
event: singleResult.result
|
|
110
|
-
}
|
|
111
|
-
],
|
|
112
|
-
nextEvent: singleResult.result,
|
|
113
|
-
sessionId: agent.sessionId,
|
|
114
|
-
timestamp: Date.now()
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
73
|
// src/text.ts
|
|
119
74
|
import {
|
|
120
75
|
fromObservable,
|
|
121
76
|
fromPromise,
|
|
122
77
|
toObserver
|
|
123
78
|
} from "xstate";
|
|
124
|
-
import { nanoid } from "nanoid";
|
|
125
79
|
async function getMessages(agent, prompt, options) {
|
|
126
80
|
let messages = [];
|
|
127
|
-
if (options.messages ===
|
|
128
|
-
messages = agent.select((s) => s.messages);
|
|
129
|
-
} else if (typeof options.messages === "function") {
|
|
81
|
+
if (typeof options.messages === "function") {
|
|
130
82
|
messages = await options.messages(agent);
|
|
131
83
|
} else if (options.messages) {
|
|
132
84
|
messages = options.messages;
|
|
@@ -143,7 +95,7 @@ async function agentGenerateText(agent, options) {
|
|
|
143
95
|
...options
|
|
144
96
|
};
|
|
145
97
|
const template = resolvedOptions.template ?? defaultTextTemplate;
|
|
146
|
-
const id =
|
|
98
|
+
const id = randomId();
|
|
147
99
|
const goal = typeof resolvedOptions.prompt === "string" ? resolvedOptions.prompt : await resolvedOptions.prompt(agent);
|
|
148
100
|
const promptWithContext = template({
|
|
149
101
|
goal,
|
|
@@ -177,7 +129,7 @@ async function agentStreamText(agent, options) {
|
|
|
177
129
|
...options
|
|
178
130
|
};
|
|
179
131
|
const template = resolvedOptions.template ?? defaultTextTemplate;
|
|
180
|
-
const id =
|
|
132
|
+
const id = randomId();
|
|
181
133
|
const goal = typeof resolvedOptions.prompt === "string" ? resolvedOptions.prompt : await resolvedOptions.prompt(agent);
|
|
182
134
|
const promptWithContext = template({
|
|
183
135
|
goal,
|
|
@@ -209,7 +161,7 @@ async function agentStreamText(agent, options) {
|
|
|
209
161
|
rawResponse: res.rawResponse
|
|
210
162
|
},
|
|
211
163
|
content: res.text,
|
|
212
|
-
id:
|
|
164
|
+
id: randomId(),
|
|
213
165
|
timestamp: Date.now(),
|
|
214
166
|
responseId: id
|
|
215
167
|
});
|
|
@@ -218,14 +170,13 @@ async function agentStreamText(agent, options) {
|
|
|
218
170
|
return result;
|
|
219
171
|
}
|
|
220
172
|
function fromTextStream(agent, defaultOptions) {
|
|
221
|
-
return fromObservable(({ input
|
|
222
|
-
const context = input.context === true ? (self._parent?.getSnapshot()).context : input.context;
|
|
173
|
+
return fromObservable(({ input }) => {
|
|
223
174
|
const observers = /* @__PURE__ */ new Set();
|
|
224
175
|
(async () => {
|
|
225
176
|
const result = await agentStreamText(agent, {
|
|
226
177
|
...defaultOptions,
|
|
227
178
|
...input,
|
|
228
|
-
context
|
|
179
|
+
context: input.context
|
|
229
180
|
});
|
|
230
181
|
for await (const part of result.fullStream) {
|
|
231
182
|
if (part.type === "text-delta") {
|
|
@@ -249,16 +200,103 @@ function fromTextStream(agent, defaultOptions) {
|
|
|
249
200
|
});
|
|
250
201
|
}
|
|
251
202
|
function fromText(agent, defaultOptions) {
|
|
252
|
-
return fromPromise(async ({ input
|
|
253
|
-
const context = input.context === true ? (self._parent?.getSnapshot()).context : input.context;
|
|
203
|
+
return fromPromise(async ({ input }) => {
|
|
254
204
|
return await agentGenerateText(agent, {
|
|
255
205
|
...input,
|
|
256
206
|
...defaultOptions,
|
|
257
|
-
context
|
|
207
|
+
context: input.context
|
|
258
208
|
});
|
|
259
209
|
});
|
|
260
210
|
}
|
|
261
211
|
|
|
212
|
+
// src/planners/simplePlanner.ts
|
|
213
|
+
function getTransitions(state, machine) {
|
|
214
|
+
if (!machine) {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
const resolvedState = machine.resolveState(state);
|
|
218
|
+
return getAllTransitions(resolvedState);
|
|
219
|
+
}
|
|
220
|
+
var simplePlannerPromptTemplate = (data) => {
|
|
221
|
+
return `
|
|
222
|
+
${defaultTextTemplate(data)}
|
|
223
|
+
|
|
224
|
+
Make at most one tool call to achieve the above goal. If the goal cannot be achieved with any tool calls, do not make any tool call.
|
|
225
|
+
`.trim();
|
|
226
|
+
};
|
|
227
|
+
async function simplePlanner(agent, input) {
|
|
228
|
+
const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(input.events).map(([eventType, { description }]) => ({
|
|
229
|
+
eventType,
|
|
230
|
+
description
|
|
231
|
+
}));
|
|
232
|
+
const filter = (eventType) => Object.keys(input.events).includes(eventType);
|
|
233
|
+
const functionNameMapping = {};
|
|
234
|
+
const toolTransitions = transitions.filter((t) => {
|
|
235
|
+
return filter(t.eventType);
|
|
236
|
+
}).map((t) => {
|
|
237
|
+
const name = t.eventType.replace(/\./g, "_");
|
|
238
|
+
functionNameMapping[name] = t.eventType;
|
|
239
|
+
return {
|
|
240
|
+
type: "function",
|
|
241
|
+
eventType: t.eventType,
|
|
242
|
+
description: t.description,
|
|
243
|
+
name
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
const toolMap = {};
|
|
247
|
+
for (const toolTransitionData of toolTransitions) {
|
|
248
|
+
const toolZodType = input.events?.[toolTransitionData.eventType];
|
|
249
|
+
if (!toolZodType) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
toolMap[toolTransitionData.name] = tool({
|
|
253
|
+
description: toolZodType?.description ?? toolTransitionData.description,
|
|
254
|
+
parameters: toolZodType,
|
|
255
|
+
execute: async (params) => {
|
|
256
|
+
const event = {
|
|
257
|
+
type: toolTransitionData.eventType,
|
|
258
|
+
...params
|
|
259
|
+
};
|
|
260
|
+
return event;
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
if (!Object.keys(toolMap).length) {
|
|
265
|
+
return void 0;
|
|
266
|
+
}
|
|
267
|
+
const prompt = simplePlannerPromptTemplate({
|
|
268
|
+
context: input.state.context,
|
|
269
|
+
goal: input.goal
|
|
270
|
+
});
|
|
271
|
+
const messages = await getMessages(agent, prompt, input);
|
|
272
|
+
const result = await agent.generateText({
|
|
273
|
+
toolChoice: "required",
|
|
274
|
+
...input,
|
|
275
|
+
prompt,
|
|
276
|
+
messages,
|
|
277
|
+
tools: toolMap
|
|
278
|
+
});
|
|
279
|
+
const singleResult = result.toolResults[0];
|
|
280
|
+
if (!singleResult) {
|
|
281
|
+
console.log(toolMap);
|
|
282
|
+
console.warn("No tool call results returned");
|
|
283
|
+
return void 0;
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
goal: input.goal,
|
|
287
|
+
state: input.state,
|
|
288
|
+
execute: async (state) => {
|
|
289
|
+
if (JSON.stringify(state) === JSON.stringify(input.state)) {
|
|
290
|
+
return singleResult.result;
|
|
291
|
+
}
|
|
292
|
+
return void 0;
|
|
293
|
+
},
|
|
294
|
+
nextEvent: singleResult.result,
|
|
295
|
+
sessionId: agent.sessionId,
|
|
296
|
+
timestamp: Date.now()
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
|
|
262
300
|
// src/decision.ts
|
|
263
301
|
import { fromPromise as fromPromise2 } from "xstate";
|
|
264
302
|
async function agentDecide(agent, options) {
|
|
@@ -329,7 +367,6 @@ var vercelAdapter = {
|
|
|
329
367
|
};
|
|
330
368
|
|
|
331
369
|
// src/agent.ts
|
|
332
|
-
import { nanoid as nanoid2 } from "nanoid";
|
|
333
370
|
var agentLogic = fromTransition(
|
|
334
371
|
(state, event, { emit }) => {
|
|
335
372
|
switch (event.type) {
|
|
@@ -386,6 +423,7 @@ function createAgent({
|
|
|
386
423
|
description,
|
|
387
424
|
model,
|
|
388
425
|
events,
|
|
426
|
+
context,
|
|
389
427
|
planner = simplePlanner,
|
|
390
428
|
stringify = JSON.stringify,
|
|
391
429
|
getMemory,
|
|
@@ -414,7 +452,7 @@ function createAgent({
|
|
|
414
452
|
agent.addMessage = (messageInput) => {
|
|
415
453
|
const message = {
|
|
416
454
|
...messageInput,
|
|
417
|
-
id: messageInput.id ??
|
|
455
|
+
id: messageInput.id ?? randomId(),
|
|
418
456
|
timestamp: messageInput.timestamp ?? Date.now(),
|
|
419
457
|
sessionId: agent.sessionId
|
|
420
458
|
};
|
|
@@ -424,6 +462,7 @@ function createAgent({
|
|
|
424
462
|
});
|
|
425
463
|
return message;
|
|
426
464
|
};
|
|
465
|
+
agent.getMessages = () => agent.getSnapshot().context.messages;
|
|
427
466
|
agent.generateText = (opts) => agentGenerateText(agent, opts);
|
|
428
467
|
agent.streamText = (opts) => agentStreamText(agent, opts);
|
|
429
468
|
agent.addFeedback = (feedbackInput) => {
|
|
@@ -438,12 +477,17 @@ function createAgent({
|
|
|
438
477
|
});
|
|
439
478
|
return feedback;
|
|
440
479
|
};
|
|
480
|
+
agent.getFeedback = () => agent.getSnapshot().context.feedback;
|
|
441
481
|
agent.addObservation = (observationInput) => {
|
|
482
|
+
const { prevState, event, state } = observationInput;
|
|
442
483
|
const observation = {
|
|
443
|
-
|
|
444
|
-
|
|
484
|
+
prevState,
|
|
485
|
+
event,
|
|
486
|
+
state,
|
|
487
|
+
id: observationInput.id ?? randomId(),
|
|
445
488
|
sessionId: agent.sessionId,
|
|
446
|
-
timestamp: observationInput.timestamp ?? Date.now()
|
|
489
|
+
timestamp: observationInput.timestamp ?? Date.now(),
|
|
490
|
+
machineHash: observationInput.machine ? getMachineHash(observationInput.machine) : void 0
|
|
447
491
|
};
|
|
448
492
|
agent.send({
|
|
449
493
|
type: "agent.observe",
|
|
@@ -451,12 +495,14 @@ function createAgent({
|
|
|
451
495
|
});
|
|
452
496
|
return observation;
|
|
453
497
|
};
|
|
498
|
+
agent.getObservations = () => agent.getSnapshot().context.observations;
|
|
454
499
|
agent.addPlan = (plan) => {
|
|
455
500
|
agent.send({
|
|
456
501
|
type: "agent.plan",
|
|
457
502
|
plan
|
|
458
503
|
});
|
|
459
504
|
};
|
|
505
|
+
agent.getPlans = () => agent.getSnapshot().context.plans;
|
|
460
506
|
agent.interact = (actorRef, getInput) => {
|
|
461
507
|
let prevState = void 0;
|
|
462
508
|
let subscribed = true;
|
|
@@ -483,7 +529,8 @@ function createAgent({
|
|
|
483
529
|
const observationInput = {
|
|
484
530
|
event: inspEvent.event,
|
|
485
531
|
prevState,
|
|
486
|
-
state: inspEvent.snapshot
|
|
532
|
+
state: inspEvent.snapshot,
|
|
533
|
+
machine: actorRef.src
|
|
487
534
|
};
|
|
488
535
|
await handleObservation(observationInput);
|
|
489
536
|
}
|
|
@@ -493,7 +540,8 @@ function createAgent({
|
|
|
493
540
|
prevState: void 0,
|
|
494
541
|
event: { type: "" },
|
|
495
542
|
// TODO: unknown events?
|
|
496
|
-
state: actorRef.getSnapshot()
|
|
543
|
+
state: actorRef.getSnapshot(),
|
|
544
|
+
machine: actorRef.src
|
|
497
545
|
});
|
|
498
546
|
}
|
|
499
547
|
return {
|
|
@@ -503,12 +551,11 @@ function createAgent({
|
|
|
503
551
|
// TODO: make this actually unsubscribe
|
|
504
552
|
};
|
|
505
553
|
};
|
|
554
|
+
agent.types = {};
|
|
506
555
|
agent.start();
|
|
507
556
|
return agent;
|
|
508
557
|
}
|
|
509
558
|
export {
|
|
510
|
-
agentDecide,
|
|
511
|
-
agentGenerateText,
|
|
512
559
|
createAgent,
|
|
513
560
|
fromDecision,
|
|
514
561
|
fromText,
|
package/examples/chatbot.ts
CHANGED
|
@@ -13,20 +13,18 @@ const agent = createAgent({
|
|
|
13
13
|
}),
|
|
14
14
|
'agent.endConversation': z.object({}).describe('Stop the conversation'),
|
|
15
15
|
},
|
|
16
|
+
context: {
|
|
17
|
+
userMessage: z.string(),
|
|
18
|
+
},
|
|
16
19
|
});
|
|
17
20
|
|
|
18
21
|
const machine = setup({
|
|
19
|
-
types:
|
|
20
|
-
context: {} as {
|
|
21
|
-
conversation: string[];
|
|
22
|
-
},
|
|
23
|
-
events: agent.eventTypes,
|
|
24
|
-
},
|
|
22
|
+
types: agent.types,
|
|
25
23
|
actors: { agent: fromDecision(agent), getFromTerminal },
|
|
26
24
|
}).createMachine({
|
|
27
25
|
initial: 'listening',
|
|
28
26
|
context: {
|
|
29
|
-
|
|
27
|
+
userMessage: '',
|
|
30
28
|
},
|
|
31
29
|
states: {
|
|
32
30
|
listening: {
|
|
@@ -35,8 +33,7 @@ const machine = setup({
|
|
|
35
33
|
input: 'User:',
|
|
36
34
|
onDone: {
|
|
37
35
|
actions: assign({
|
|
38
|
-
|
|
39
|
-
x.context.conversation.concat('User: ' + x.event.output),
|
|
36
|
+
userMessage: (x) => x.event.output,
|
|
40
37
|
}),
|
|
41
38
|
target: 'responding',
|
|
42
39
|
},
|
|
@@ -47,20 +44,15 @@ const machine = setup({
|
|
|
47
44
|
src: 'agent',
|
|
48
45
|
input: (x) => ({
|
|
49
46
|
context: {
|
|
50
|
-
|
|
47
|
+
userMessage: 'User says: ' + x.context.userMessage,
|
|
51
48
|
},
|
|
49
|
+
messages: agent.getMessages(),
|
|
52
50
|
goal: 'Respond to the user, unless they want to end the conversation.',
|
|
53
51
|
}),
|
|
54
52
|
},
|
|
55
53
|
on: {
|
|
56
54
|
'agent.respond': {
|
|
57
|
-
actions: [
|
|
58
|
-
assign({
|
|
59
|
-
conversation: (x) =>
|
|
60
|
-
x.context.conversation.concat('Assistant: ' + x.event.response),
|
|
61
|
-
}),
|
|
62
|
-
log((x) => `Agent: ${x.event.response}`),
|
|
63
|
-
],
|
|
55
|
+
actions: [log((x) => `Agent: ${x.event.response}`)],
|
|
64
56
|
target: 'listening',
|
|
65
57
|
},
|
|
66
58
|
'agent.endConversation': 'finished',
|
package/examples/cot.ts
CHANGED
|
@@ -17,16 +17,14 @@ const agent = createAgent({
|
|
|
17
17
|
answer: z.string().describe('The answer to the question'),
|
|
18
18
|
}),
|
|
19
19
|
},
|
|
20
|
+
context: {
|
|
21
|
+
question: z.string().nullable(),
|
|
22
|
+
thought: z.string().nullable(),
|
|
23
|
+
},
|
|
20
24
|
});
|
|
21
25
|
|
|
22
26
|
const machine = setup({
|
|
23
|
-
types:
|
|
24
|
-
context: {} as {
|
|
25
|
-
question: string | null;
|
|
26
|
-
thought: string | null;
|
|
27
|
-
},
|
|
28
|
-
events: agent.eventTypes,
|
|
29
|
-
},
|
|
27
|
+
types: agent.types,
|
|
30
28
|
actors: { agent: fromDecision(agent), getFromTerminal },
|
|
31
29
|
}).createMachine({
|
|
32
30
|
initial: 'asking',
|
package/examples/email.ts
CHANGED
|
@@ -19,7 +19,7 @@ const agent = createAgent({
|
|
|
19
19
|
|
|
20
20
|
const machine = setup({
|
|
21
21
|
types: {
|
|
22
|
-
events: agent.
|
|
22
|
+
events: agent.types.events,
|
|
23
23
|
input: {} as {
|
|
24
24
|
email: string;
|
|
25
25
|
instructions: string;
|
|
@@ -50,7 +50,7 @@ const machine = setup({
|
|
|
50
50
|
instructions: x.context.instructions,
|
|
51
51
|
clarifications: x.context.clarifications,
|
|
52
52
|
},
|
|
53
|
-
messages: agent.
|
|
53
|
+
messages: agent.getMessages(),
|
|
54
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
55
|
}),
|
|
56
56
|
},
|
package/examples/example.ts
CHANGED
|
@@ -18,7 +18,7 @@ const agent = createAgent({
|
|
|
18
18
|
|
|
19
19
|
const machine = setup({
|
|
20
20
|
types: {
|
|
21
|
-
events: agent.
|
|
21
|
+
events: agent.types.events,
|
|
22
22
|
},
|
|
23
23
|
actors: { agent: fromDecision(agent), summarizer: fromText(agent) },
|
|
24
24
|
}).createMachine({
|
|
@@ -32,11 +32,11 @@ const machine = setup({
|
|
|
32
32
|
invoke: [
|
|
33
33
|
{
|
|
34
34
|
src: 'summarizer',
|
|
35
|
-
input: {
|
|
36
|
-
context:
|
|
35
|
+
input: (x) => ({
|
|
36
|
+
context: x.context,
|
|
37
37
|
prompt:
|
|
38
38
|
'Summarize the patient visit in a single sentence. The summary should be in English.',
|
|
39
|
-
},
|
|
39
|
+
}),
|
|
40
40
|
onDone: {
|
|
41
41
|
actions: assign({
|
|
42
42
|
englishSummary: ({ event }) => event.output.text,
|
|
@@ -45,11 +45,11 @@ const machine = setup({
|
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
src: 'summarizer',
|
|
48
|
-
input: {
|
|
49
|
-
context:
|
|
48
|
+
input: (x) => ({
|
|
49
|
+
context: x.context,
|
|
50
50
|
prompt:
|
|
51
51
|
'Summarize the patient visit in a single sentence. The summary should be in Spanish.',
|
|
52
|
-
},
|
|
52
|
+
}),
|
|
53
53
|
onDone: {
|
|
54
54
|
actions: assign({
|
|
55
55
|
spanishSummary: ({ event }) => event.output.text,
|
package/examples/goal.ts
CHANGED
package/examples/joke.ts
CHANGED
|
@@ -67,19 +67,17 @@ const agent = createAgent({
|
|
|
67
67
|
.describe('Explains why the joke was irrelevant'),
|
|
68
68
|
'agent.markAsRelevant': z.object({}).describe('The joke was relevant'),
|
|
69
69
|
},
|
|
70
|
+
context: {
|
|
71
|
+
topic: z.string().describe('The topic for the joke'),
|
|
72
|
+
jokes: z.array(z.string()).describe('The jokes told so far'),
|
|
73
|
+
desire: z.string().nullable().describe('The user desire'),
|
|
74
|
+
lastRating: z.number().nullable().describe('The last joke rating'),
|
|
75
|
+
loader: z.string().nullable().describe('The loader text'),
|
|
76
|
+
},
|
|
70
77
|
});
|
|
71
78
|
|
|
72
79
|
const jokeMachine = setup({
|
|
73
|
-
types:
|
|
74
|
-
context: {} as {
|
|
75
|
-
topic: string;
|
|
76
|
-
jokes: string[];
|
|
77
|
-
desire: string | null;
|
|
78
|
-
lastRating: number | null;
|
|
79
|
-
loader: string | null;
|
|
80
|
-
},
|
|
81
|
-
events: agent.eventTypes,
|
|
82
|
-
},
|
|
80
|
+
types: agent.types,
|
|
83
81
|
actors: {
|
|
84
82
|
agent: fromDecision(agent),
|
|
85
83
|
loader,
|
package/examples/number.ts
CHANGED
package/examples/raffle.ts
CHANGED
|
@@ -27,7 +27,7 @@ const machine = setup({
|
|
|
27
27
|
lastInput: string | null;
|
|
28
28
|
entries: string[];
|
|
29
29
|
},
|
|
30
|
-
events: {} as typeof agent.
|
|
30
|
+
events: {} as typeof agent.types.events | { type: 'draw' },
|
|
31
31
|
},
|
|
32
32
|
actors: { agent: fromDecision(agent), getFromTerminal },
|
|
33
33
|
}).createMachine({
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createAgent } from '../src';
|
|
3
|
+
import { openai } from '@ai-sdk/openai';
|
|
4
|
+
import { createMachine } from 'xstate';
|
|
5
|
+
|
|
6
|
+
const agent = createAgent({
|
|
7
|
+
model: openai('gpt-4o'),
|
|
8
|
+
events: {
|
|
9
|
+
doSomething: z.object({}).describe('Do something'),
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
async function main() {
|
|
14
|
+
const machine = createMachine({
|
|
15
|
+
on: {
|
|
16
|
+
doSomething: {},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
const result = await agent.decide({
|
|
20
|
+
goal: 'Do not do anything',
|
|
21
|
+
state: { value: {}, context: {} },
|
|
22
|
+
machine,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log(result);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
main();
|