@statelyai/agent 2.0.0-next.1 → 2.0.0-next.2

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.
Files changed (44) hide show
  1. package/.changeset/grumpy-dolphins-think.md +17 -0
  2. package/.changeset/old-teachers-tap.md +5 -0
  3. package/.changeset/pre.json +4 -1
  4. package/.changeset/smart-yaks-pull.md +23 -0
  5. package/CHANGELOG.md +40 -0
  6. package/dist/index.d.mts +55 -46
  7. package/dist/index.d.ts +55 -46
  8. package/dist/index.js +78 -50
  9. package/dist/index.mjs +81 -53
  10. package/examples/chatbot.ts +2 -2
  11. package/examples/cot.ts +6 -24
  12. package/examples/customer-service-sim.ts +3 -3
  13. package/examples/email.ts +9 -3
  14. package/examples/example.ts +2 -2
  15. package/examples/goal.ts +2 -2
  16. package/examples/joke.ts +2 -2
  17. package/examples/jugs.ts +4 -7
  18. package/examples/learn-from-feedback.ts +100 -0
  19. package/examples/number.ts +2 -2
  20. package/examples/raffle.ts +2 -2
  21. package/examples/river-crossing.ts +4 -7
  22. package/examples/simple.ts +13 -10
  23. package/examples/summary.ts +2 -5
  24. package/examples/support.ts +42 -38
  25. package/examples/ticTacToe.ts +46 -4
  26. package/examples/todo.ts +2 -2
  27. package/examples/tutor.ts +2 -2
  28. package/examples/verify.ts +2 -2
  29. package/examples/weather-agent.ts +141 -0
  30. package/examples/weather.ts +23 -23
  31. package/examples/word.ts +8 -6
  32. package/package.json +2 -1
  33. package/src/agent.test.ts +17 -15
  34. package/src/agent.ts +48 -35
  35. package/src/decide.test.ts +56 -8
  36. package/src/decide.ts +34 -24
  37. package/src/strategies/chainOfThought.ts +48 -0
  38. package/src/{planners → strategies}/shortestPath.test.ts +4 -7
  39. package/src/strategies/shortestPath.ts +173 -0
  40. package/src/{planners → strategies}/simple.ts +28 -18
  41. package/src/types.ts +62 -28
  42. package/src/utils.ts +12 -0
  43. package/src/planners/shortestPath.ts +0 -177
  44. package/src/strategies/chain-of-note.ts +0 -106
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  fromTransition
5
5
  } from "xstate";
6
6
 
7
- // src/planners/simple.ts
7
+ // src/strategies/simple.ts
8
8
  import { generateText as generateText2 } from "ai";
9
9
 
10
10
  // src/utils.ts
@@ -43,6 +43,15 @@ function getAllMachineTransitions(stateNode) {
43
43
  function wrapInXml(tagName, content) {
44
44
  return `<${tagName}>${content}</${tagName}>`;
45
45
  }
46
+ function convertToXml(obj) {
47
+ return Object.entries(obj).map(([key, value]) => {
48
+ if (typeof value === "object" && value !== null) {
49
+ return wrapInXml(key, convertToXml(value));
50
+ } else {
51
+ return wrapInXml(key, value);
52
+ }
53
+ }).join("");
54
+ }
46
55
  function randomId(prefix) {
47
56
  const timestamp = Date.now().toString(36);
48
57
  const random = Math.random().toString(36).substring(2, 9);
@@ -74,9 +83,15 @@ function isMachineActor(actor) {
74
83
  return "src" in actor && typeof actor.src === "object" && actor.src !== null && "definition" in actor.src;
75
84
  }
76
85
 
77
- // src/planners/simple.ts
86
+ // src/strategies/simple.ts
78
87
  import { getNextSnapshot } from "xstate";
79
88
 
89
+ // src/text.ts
90
+ import {
91
+ generateText,
92
+ streamText
93
+ } from "ai";
94
+
80
95
  // src/templates/defaultText.ts
81
96
  var defaultTextTemplate = (data) => {
82
97
  const preamble = [
@@ -90,10 +105,6 @@ ${data.goal}
90
105
  };
91
106
 
92
107
  // src/text.ts
93
- import {
94
- generateText,
95
- streamText
96
- } from "ai";
97
108
  import {
98
109
  fromObservable,
99
110
  fromPromise,
@@ -186,35 +197,42 @@ async function agentDecide(agent, options) {
186
197
  ...options
187
198
  };
188
199
  const {
189
- planner = simplePlanner,
200
+ strategy = agent.strategy,
190
201
  goal,
202
+ allowedEvents,
191
203
  events = agent.events,
192
204
  state,
193
205
  machine,
194
206
  model = agent.model,
195
207
  messages,
196
- ...otherPlanInput
208
+ ...otherDecideInput
197
209
  } = resolvedOptions;
210
+ const filteredEventSchemas = allowedEvents ? Object.fromEntries(
211
+ Object.entries(events).filter(([key]) => {
212
+ return allowedEvents.includes(key);
213
+ })
214
+ ) : events;
198
215
  let attempts = 0;
199
216
  const maxAttempts = resolvedOptions.maxAttempts ?? 2;
200
- let plan;
217
+ let decision;
201
218
  while (attempts++ < maxAttempts) {
202
- plan = await planner(agent, {
219
+ decision = await strategy(agent, {
203
220
  model,
204
221
  goal,
205
- events,
222
+ events: filteredEventSchemas,
206
223
  state,
207
224
  machine,
208
225
  messages,
209
226
  // TODO: fix UIMessage thing
210
- ...otherPlanInput
227
+ ...otherDecideInput
211
228
  });
212
- if (plan?.nextEvent) {
213
- agent.addPlan(plan);
214
- await resolvedOptions.execute?.(plan.nextEvent);
229
+ if (decision?.nextEvent) {
230
+ agent.addDecision(decision);
231
+ await resolvedOptions.execute?.(decision.nextEvent);
232
+ break;
215
233
  }
216
234
  }
217
- return plan;
235
+ return decision;
218
236
  }
219
237
  function fromDecision(agent, defaultInput) {
220
238
  return fromPromise2(async ({ input, self }) => {
@@ -232,15 +250,18 @@ function fromDecision(agent, defaultInput) {
232
250
  value: snapshot.value,
233
251
  context: resolvedInput.context
234
252
  };
235
- const plan = await agentDecide(agent, {
253
+ const decision = await agentDecide(agent, {
236
254
  machine: parentRef.logic,
237
- state,
255
+ state: snapshot,
256
+ context: resolvedInput.context,
238
257
  execute: async (event) => {
239
258
  parentRef.send(event);
240
259
  },
241
- ...resolvedInput
260
+ ...resolvedInput,
261
+ // @ts-ignore
262
+ messages: resolvedInput.messages
242
263
  });
243
- return plan;
264
+ return decision;
244
265
  });
245
266
  }
246
267
  function getToolMap(_agent, input) {
@@ -286,37 +307,38 @@ function getToolMap(_agent, input) {
286
307
  return toolMap;
287
308
  }
288
309
 
289
- // src/planners/simple.ts
290
- var simplePlannerPromptTemplate = (data) => {
310
+ // src/strategies/simple.ts
311
+ var simpleStrategyPromptTemplate = (data) => {
291
312
  return `
292
- ${defaultTextTemplate(data)}
313
+ ${convertToXml(data)}
293
314
 
294
315
  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.
295
316
  `.trim();
296
317
  };
297
- async function simplePlanner(agent, input) {
318
+ async function simpleStrategy(agent, input) {
298
319
  const toolMap = getToolMap(agent, input);
299
320
  if (!toolMap) {
300
321
  return void 0;
301
322
  }
302
- const prompt = simplePlannerPromptTemplate({
303
- context: input.state.context,
323
+ const prompt = simpleStrategyPromptTemplate({
324
+ context: input.context,
304
325
  goal: input.goal
305
326
  });
306
327
  const messages = await getMessages(agent, prompt, input);
307
328
  const model = input.model ? agent.wrap(input.model) : agent.model;
308
329
  const {
309
330
  state,
331
+ context,
310
332
  machine,
311
- previousPlan,
333
+ prevDecision,
312
334
  events,
313
335
  goal,
314
336
  model: _,
315
337
  ...rest
316
338
  } = input;
317
- const machineState = input.machine ? input.machine.resolveState({
339
+ const machineState = input.machine && input.state ? input.machine.resolveState({
318
340
  ...input.state,
319
- context: input.state.context
341
+ context: input.state.context ?? {}
320
342
  }) : void 0;
321
343
  const result = await generateText2({
322
344
  ...rest,
@@ -340,7 +362,7 @@ async function simplePlanner(agent, input) {
340
362
  return void 0;
341
363
  }
342
364
  return {
343
- planner: "simple",
365
+ strategy: "simple",
344
366
  goal: input.goal,
345
367
  goalState: input.state,
346
368
  nextEvent: singleResult.result,
@@ -459,12 +481,11 @@ var agentLogic = fromTransition(
459
481
  });
460
482
  break;
461
483
  }
462
- case "agent.plan": {
463
- state.plans.push(event.plan);
484
+ case "agent.decision": {
485
+ state.decisions.push(event.decision);
464
486
  emit({
465
- type: "plan",
466
- // @ts-ignore TODO: fix types in XState
467
- plan: event.plan
487
+ type: "decision",
488
+ decision: event.decision
468
489
  });
469
490
  break;
470
491
  }
@@ -479,7 +500,7 @@ var agentLogic = fromTransition(
479
500
  feedback: [],
480
501
  messages: [],
481
502
  observations: [],
482
- plans: []
503
+ decisions: []
483
504
  })
484
505
  );
485
506
  function createAgent({
@@ -488,7 +509,8 @@ function createAgent({
488
509
  model,
489
510
  events,
490
511
  context,
491
- planner = simplePlanner,
512
+ episodeId,
513
+ strategy = simpleStrategy,
492
514
  logic = agentLogic
493
515
  }) {
494
516
  return new Agent({
@@ -496,9 +518,10 @@ function createAgent({
496
518
  context,
497
519
  events,
498
520
  description,
499
- planner,
521
+ strategy,
500
522
  model,
501
- logic
523
+ logic,
524
+ episodeId
502
525
  });
503
526
  }
504
527
  var Agent = class extends Actor {
@@ -511,17 +534,18 @@ var Agent = class extends Actor {
511
534
  model,
512
535
  events,
513
536
  context,
514
- planner = simplePlanner
537
+ episodeId,
538
+ strategy = simpleStrategy
515
539
  }) {
516
540
  super(logic);
517
541
  this.model = model;
518
- this.episodeId = id ?? randomId();
542
+ this.episodeId = episodeId ?? randomId("episode-");
519
543
  this.name = name;
520
544
  this.description = description;
521
545
  this.events = events;
522
546
  this.context = context;
523
- this.planner = planner;
524
- this.types = {};
547
+ this.strategy = strategy;
548
+ this.id = id ?? randomId();
525
549
  this.start();
526
550
  }
527
551
  /**
@@ -530,6 +554,12 @@ var Agent = class extends Actor {
530
554
  onMessage(fn) {
531
555
  return this.on("message", (ev) => fn(ev.message));
532
556
  }
557
+ /**
558
+ * Called whenever the agent (LLM assistant) receives some feedback.
559
+ */
560
+ onFeedback(fn) {
561
+ return this.on("feedback", (ev) => fn(ev.feedback));
562
+ }
533
563
  /**
534
564
  * Retrieves messages from the agent's short-term (local) memory.
535
565
  */
@@ -553,7 +583,6 @@ var Agent = class extends Actor {
553
583
  const feedback = {
554
584
  ...feedbackInput,
555
585
  attributes: { ...feedbackInput.attributes },
556
- reward: feedbackInput.reward ?? 0,
557
586
  timestamp: feedbackInput.timestamp ?? Date.now(),
558
587
  episodeId: this.episodeId
559
588
  };
@@ -592,17 +621,17 @@ var Agent = class extends Actor {
592
621
  getObservations() {
593
622
  return this.getSnapshot().context.observations;
594
623
  }
595
- addPlan(plan) {
624
+ addDecision(decision) {
596
625
  this.send({
597
- type: "agent.plan",
598
- plan
626
+ type: "agent.decision",
627
+ decision
599
628
  });
600
629
  }
601
630
  /**
602
631
  * Retrieves strategies from the agent's short-term (local) memory.
603
632
  */
604
- getPlans() {
605
- return this.getSnapshot().context.plans;
633
+ getDecisions() {
634
+ return this.getSnapshot().context.decisions;
606
635
  }
607
636
  interact(actorRef, getInput) {
608
637
  const actorRefCheck = isActorRef(actorRef) && actorRef.src;
@@ -642,8 +671,7 @@ var Agent = class extends Actor {
642
671
  if (actorRef._processingStatus === 1) {
643
672
  handleObservation({
644
673
  prevState: void 0,
645
- event: { type: "" },
646
- // TODO: unknown events?
674
+ event: void 0,
647
675
  state: actorRef.getSnapshot(),
648
676
  machine: actorRef.src
649
677
  });
@@ -683,14 +711,14 @@ var Agent = class extends Actor {
683
711
  });
684
712
  }
685
713
  /**
686
- * Resolves with an `AgentPlan` based on the information provided in the `options`, including:
714
+ * Resolves with an `AgentDecision` based on the information provided in the `options`, including:
687
715
  *
688
716
  * - The `goal` for the agent to achieve
689
717
  * - The observed current `state`
690
718
  * - The `machine` (e.g. a state machine) that specifies what can happen next
691
719
  * - Additional `context`
692
720
  */
693
- decide(opts) {
721
+ async decide(opts) {
694
722
  return agentDecide(this, opts);
695
723
  }
696
724
  };
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision } from '../src';
2
+ import { createAgent, fromDecision, TypesFromAgent } from '../src';
3
3
  import { openai } from '@ai-sdk/openai';
4
4
  import { assign, createActor, log, setup } from 'xstate';
5
5
  import { fromTerminal } from './helpers/helpers';
@@ -19,7 +19,7 @@ const agent = createAgent({
19
19
  });
20
20
 
21
21
  const machine = setup({
22
- types: agent.types,
22
+ types: {} as TypesFromAgent<typeof agent>,
23
23
  actors: { getFromTerminal: fromTerminal },
24
24
  }).createMachine({
25
25
  initial: 'listening',
package/examples/cot.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision } from '../src';
2
+ import { createAgent, fromDecision, TypesFromAgent } from '../src';
3
3
  import { openai } from '@ai-sdk/openai';
4
4
  import { assign, createActor, log, setup } from 'xstate';
5
5
  import { fromTerminal } from './helpers/helpers';
6
+ import { chainOfThoughtStrategy } from '../src/strategies/chainOfThought';
6
7
 
7
8
  const agent = createAgent({
8
9
  id: 'chain-of-thought',
@@ -19,18 +20,17 @@ const agent = createAgent({
19
20
  },
20
21
  context: {
21
22
  question: z.string().nullable(),
22
- thought: z.string().nullable(),
23
23
  },
24
+ strategy: chainOfThoughtStrategy,
24
25
  });
25
26
 
26
27
  const machine = setup({
27
- types: agent.types,
28
+ types: {} as TypesFromAgent<typeof agent>,
28
29
  actors: { getFromTerminal: fromTerminal },
29
30
  }).createMachine({
30
31
  initial: 'asking',
31
32
  context: {
32
33
  question: null,
33
- thought: null,
34
34
  },
35
35
  states: {
36
36
  asking: {
@@ -41,19 +41,6 @@ const machine = setup({
41
41
  actions: assign({
42
42
  question: ({ event }) => event.output,
43
43
  }),
44
- target: 'thinking',
45
- },
46
- },
47
- },
48
- thinking: {
49
- on: {
50
- 'agent.think': {
51
- actions: [
52
- log(({ event }) => `Thought: ${event.thought}`),
53
- assign({
54
- thought: ({ event }) => event.thought,
55
- }),
56
- ],
57
44
  target: 'answering',
58
45
  },
59
46
  },
@@ -74,14 +61,9 @@ const machine = setup({
74
61
 
75
62
  const actor = createActor(machine).start();
76
63
 
64
+ agent.onMessage(console.log);
65
+
77
66
  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
67
  if (obs.state.matches('answering')) {
86
68
  return {
87
69
  goal: 'Answer the question',
@@ -1,4 +1,4 @@
1
- import { createAgent, fromDecision } from '../src';
1
+ import { createAgent, EventsFromAgent, fromDecision } from '../src';
2
2
  import { assign, createActor, setup } from 'xstate';
3
3
  import { openai } from '@ai-sdk/openai';
4
4
  import { z } from 'zod';
@@ -38,8 +38,8 @@ const machine = setup({
38
38
  messages: string[];
39
39
  },
40
40
  events: {} as
41
- | typeof customerServiceAgent.types.events
42
- | typeof customerAgent.types.events,
41
+ | EventsFromAgent<typeof customerServiceAgent>
42
+ | EventsFromAgent<typeof customerAgent>,
43
43
  },
44
44
  actors: {
45
45
  customerService: fromDecision(customerServiceAgent),
package/examples/email.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision } from '../src';
2
+ import {
3
+ ContextFromAgent,
4
+ createAgent,
5
+ EventsFromAgent,
6
+ fromDecision,
7
+ TypesFromAgent,
8
+ } from '../src';
3
9
  import { openai } from '@ai-sdk/openai';
4
10
  import { assign, createActor, setup } from 'xstate';
5
11
  import { fromTerminal } from './helpers/helpers';
@@ -27,12 +33,12 @@ const agent = createAgent({
27
33
 
28
34
  const machine = setup({
29
35
  types: {
30
- events: agent.types.events,
36
+ events: {} as EventsFromAgent<typeof agent>,
31
37
  input: {} as {
32
38
  email: string;
33
39
  instructions: string;
34
40
  },
35
- context: agent.types.context,
41
+ context: {} as ContextFromAgent<typeof agent>,
36
42
  },
37
43
  actors: { getFromTerminal: fromTerminal },
38
44
  }).createMachine({
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision, fromText } from '../src';
2
+ import { createAgent, EventsFromAgent, fromDecision, fromText } from '../src';
3
3
  import { openai } from '@ai-sdk/openai';
4
4
  import { assign, createActor, setup } from 'xstate';
5
5
 
@@ -18,7 +18,7 @@ const agent = createAgent({
18
18
 
19
19
  const machine = setup({
20
20
  types: {
21
- events: agent.types.events,
21
+ events: {} as EventsFromAgent<typeof agent>,
22
22
  },
23
23
  actors: { agent: fromDecision(agent), summarizer: fromText(agent) },
24
24
  }).createMachine({
package/examples/goal.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision } from '../src';
2
+ import { createAgent, EventsFromAgent, fromDecision } from '../src';
3
3
  import { openai } from '@ai-sdk/openai';
4
4
  import { assign, createActor, log, setup } from 'xstate';
5
5
  import { fromTerminal } from './helpers/helpers';
@@ -25,7 +25,7 @@ const machine = setup({
25
25
  question: string | null;
26
26
  goal: string | null;
27
27
  },
28
- events: agent.types.events,
28
+ events: {} as EventsFromAgent<typeof agent>,
29
29
  },
30
30
  actors: { decider, getFromTerminal: fromTerminal },
31
31
  }).createMachine({
package/examples/joke.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { assign, createActor, fromCallback, log, setup } from 'xstate';
2
- import { createAgent, fromDecision } from '../src';
2
+ import { createAgent, fromDecision, TypesFromAgent } from '../src';
3
3
  import { loadingAnimation } from './helpers/loader';
4
4
  import { z } from 'zod';
5
5
  import { openai } from '@ai-sdk/openai';
@@ -81,7 +81,7 @@ const agent = createAgent({
81
81
  });
82
82
 
83
83
  const jokeMachine = setup({
84
- types: agent.types,
84
+ types: {} as TypesFromAgent<typeof agent>,
85
85
  actors: {
86
86
  agent: fromDecision(agent),
87
87
  loader,
package/examples/jugs.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { createAgent } from '../src';
1
+ import { createAgent, TypesFromAgent } from '../src';
2
2
  import { assign, createActor, setup } from 'xstate';
3
3
  import { openai } from '@ai-sdk/openai';
4
4
  import { z } from 'zod';
5
- import { experimental_createShortestPathPlanner } from '../src/planners/shortestPath';
5
+ import { experimental_shortestPathStrategy } from '../src/strategies/shortestPath';
6
6
 
7
7
  const agent = createAgent({
8
8
  id: 'die-hard-solver',
@@ -38,10 +38,7 @@ const agent = createAgent({
38
38
  });
39
39
 
40
40
  const waterJugMachine = setup({
41
- types: {
42
- context: agent.types.context,
43
- events: agent.types.events,
44
- },
41
+ types: {} as TypesFromAgent<typeof agent>,
45
42
  }).createMachine({
46
43
  initial: 'solving',
47
44
  context: { jug3: 0, jug5: 0 },
@@ -106,7 +103,7 @@ async function main() {
106
103
  machine: waterJugMachine,
107
104
  goal: 'Get exactly 4 gallons of water in the 5-gallon jug',
108
105
  state: waterJugActor.getSnapshot(),
109
- planner: experimental_createShortestPathPlanner(),
106
+ strategy: experimental_shortestPathStrategy,
110
107
  });
111
108
 
112
109
  console.log(decision?.nextEvent);
@@ -0,0 +1,100 @@
1
+ import { z } from 'zod';
2
+ import { createAgent } from '../src';
3
+ import { openai } from '@ai-sdk/openai';
4
+
5
+ const agent = createAgent({
6
+ id: 'chatbot',
7
+ model: openai('gpt-4o-mini'),
8
+ events: {
9
+ submit: z.object({}).describe('Submit the form'),
10
+ pressEnter: z.object({}).describe('Press the enter key'),
11
+ },
12
+ context: {
13
+ userMessage: z.string(),
14
+ },
15
+ });
16
+
17
+ agent.onMessage((msg) => {
18
+ console.log(`Message`, msg.content);
19
+ });
20
+
21
+ agent.on('decision', ({ decision }) => {
22
+ console.log(`Decision: ${decision.nextEvent?.type ?? '??'}`);
23
+ });
24
+
25
+ async function main() {
26
+ let status = 'editing';
27
+ let count = 0;
28
+
29
+ while (status !== 'submitted') {
30
+ console.log(`Attempt ${count} - ${status}`);
31
+ if (count++ > 5) {
32
+ break;
33
+ }
34
+ switch (status) {
35
+ case 'editing': {
36
+ const relevantObservations = await agent
37
+ .getObservations()
38
+ .filter((obs) => obs.prevState.value === 'editing');
39
+ const relevantFeedback = await agent
40
+ .getFeedback()
41
+ .filter((f) =>
42
+ relevantObservations.find((o) => o.id === f.observationId)
43
+ );
44
+
45
+ const decision = await agent.decide({
46
+ goal: 'Submit the form. Take the feedback into consideration, and perform the action that will lead to the form being submitted.',
47
+ state: {
48
+ value: 'editing',
49
+ context: {
50
+ feedback: relevantFeedback.map((f) => {
51
+ const observation = relevantObservations.find(
52
+ (o) => o.id === f.observationId
53
+ );
54
+ return {
55
+ prevState: observation?.prevState,
56
+ event: observation?.event,
57
+ state: observation?.state,
58
+ feedback: f.attributes.text,
59
+ };
60
+ }),
61
+ },
62
+ },
63
+ });
64
+
65
+ if (decision?.nextEvent?.type === 'submit') {
66
+ const observation = await agent.addObservation({
67
+ prevState: { value: 'editing' },
68
+ event: { type: 'submit' },
69
+ state: { value: 'editing' },
70
+ });
71
+
72
+ // don't change the status; pretend submit button is broken
73
+ await agent.addFeedback({
74
+ observationId: observation.id,
75
+ goal: 'Submit the form',
76
+ attributes: {
77
+ text: 'Form not submitted',
78
+ },
79
+ });
80
+ } else if (decision?.nextEvent?.type === 'pressEnter') {
81
+ status = 'submitted';
82
+
83
+ await agent.addObservation({
84
+ prevState: { value: 'editing' },
85
+ event: { type: 'pressEnter' },
86
+ state: { value: 'submitted' },
87
+ });
88
+ }
89
+ break;
90
+ }
91
+ case 'submitted':
92
+ break;
93
+ }
94
+ }
95
+
96
+ console.log('End of conversation.');
97
+ process.exit();
98
+ }
99
+
100
+ main().catch(console.error);
@@ -1,4 +1,4 @@
1
- import { createAgent, fromDecision } from '../src';
1
+ import { createAgent, EventsFromAgent, fromDecision } from '../src';
2
2
  import { assign, createActor, log, setup } from 'xstate';
3
3
  import { z } from 'zod';
4
4
  import { openai } from '@ai-sdk/openai';
@@ -21,7 +21,7 @@ const machine = setup({
21
21
  previousGuesses: number[];
22
22
  answer: number | null;
23
23
  },
24
- events: agent.types.events,
24
+ events: {} as EventsFromAgent<typeof agent>,
25
25
  },
26
26
  actors: {
27
27
  agent: fromDecision(agent),
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision } from '../src';
2
+ import { createAgent, EventsFromAgent, fromDecision } from '../src';
3
3
  import { openai } from '@ai-sdk/openai';
4
4
  import { assign, createActor, log, setup } from 'xstate';
5
5
  import { fromTerminal } from './helpers/helpers';
@@ -27,7 +27,7 @@ const machine = setup({
27
27
  lastInput: string | null;
28
28
  entries: string[];
29
29
  },
30
- events: agent.types.events,
30
+ events: {} as EventsFromAgent<typeof agent>,
31
31
  },
32
32
  actors: { agent: fromDecision(agent), getFromTerminal: fromTerminal },
33
33
  }).createMachine({