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

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 (51) hide show
  1. package/.changeset/grumpy-dolphins-think.md +17 -0
  2. package/.changeset/old-teachers-tap.md +5 -0
  3. package/.changeset/pink-eagles-deliver.md +13 -0
  4. package/.changeset/pre.json +9 -1
  5. package/.changeset/quiet-turtles-do.md +7 -0
  6. package/.changeset/smart-yaks-pull.md +23 -0
  7. package/.changeset/sweet-clouds-mix.md +16 -0
  8. package/.changeset/swift-mangos-rush.md +5 -0
  9. package/.changeset/tough-ways-rhyme.md +5 -0
  10. package/CHANGELOG.md +79 -0
  11. package/dist/index.d.mts +116 -100
  12. package/dist/index.d.ts +116 -100
  13. package/dist/index.js +102 -72
  14. package/dist/index.mjs +105 -75
  15. package/examples/chatbot.ts +2 -2
  16. package/examples/cot.ts +21 -73
  17. package/examples/customer-service-sim.ts +3 -3
  18. package/examples/email.ts +3 -5
  19. package/examples/example.ts +2 -2
  20. package/examples/goal.ts +2 -2
  21. package/examples/joke.ts +12 -12
  22. package/examples/jugs.ts +4 -7
  23. package/examples/learn-from-feedback.ts +123 -0
  24. package/examples/number.ts +2 -2
  25. package/examples/raffle.ts +2 -2
  26. package/examples/river-crossing.ts +4 -7
  27. package/examples/simple.ts +13 -10
  28. package/examples/summary.ts +2 -5
  29. package/examples/support.ts +38 -38
  30. package/examples/ticTacToe.ts +46 -4
  31. package/examples/todo.ts +3 -3
  32. package/examples/tutor.ts +2 -2
  33. package/examples/verify.ts +2 -2
  34. package/examples/weather-agent.ts +139 -0
  35. package/examples/weather.ts +26 -23
  36. package/examples/word.ts +8 -6
  37. package/package.json +2 -1
  38. package/src/agent.test.ts +37 -52
  39. package/src/agent.ts +93 -60
  40. package/src/decide.test.ts +56 -8
  41. package/src/decide.ts +42 -32
  42. package/src/strategies/chainOfThought.ts +50 -0
  43. package/src/{planners → strategies}/shortestPath.test.ts +4 -7
  44. package/src/strategies/shortestPath.ts +178 -0
  45. package/src/{planners → strategies}/simple.ts +25 -26
  46. package/src/templates/defaultText.ts +3 -0
  47. package/src/text.ts +13 -13
  48. package/src/types.ts +124 -83
  49. package/src/utils.ts +13 -1
  50. package/src/planners/shortestPath.ts +0 -177
  51. 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,12 +83,19 @@ 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 = [
98
+ data.stateValue ? wrapInXml("stateValue", JSON.stringify(data.stateValue)) : void 0,
83
99
  data.context ? wrapInXml("context", JSON.stringify(data.context)) : void 0
84
100
  ].filter(Boolean).join("\n");
85
101
  return `
@@ -90,10 +106,6 @@ ${data.goal}
90
106
  };
91
107
 
92
108
  // src/text.ts
93
- import {
94
- generateText,
95
- streamText
96
- } from "ai";
97
109
  import {
98
110
  fromObservable,
99
111
  fromPromise,
@@ -186,35 +198,46 @@ async function agentDecide(agent, options) {
186
198
  ...options
187
199
  };
188
200
  const {
189
- planner = simplePlanner,
201
+ strategy = agent.strategy,
190
202
  goal,
203
+ allowedEvents,
191
204
  events = agent.events,
192
205
  state,
193
206
  machine,
194
207
  model = agent.model,
195
208
  messages,
196
- ...otherPlanInput
209
+ ...otherDecideInput
197
210
  } = resolvedOptions;
211
+ const filteredEventSchemas = allowedEvents ? Object.fromEntries(
212
+ Object.entries(events).filter(([key]) => {
213
+ return allowedEvents.includes(key);
214
+ })
215
+ ) : events;
198
216
  let attempts = 0;
199
217
  const maxAttempts = resolvedOptions.maxAttempts ?? 2;
200
- let plan;
218
+ let decision;
219
+ const minimalState = {
220
+ value: state.value,
221
+ context: state.context
222
+ };
201
223
  while (attempts++ < maxAttempts) {
202
- plan = await planner(agent, {
224
+ decision = await strategy(agent, {
203
225
  model,
204
226
  goal,
205
- events,
206
- state,
227
+ events: filteredEventSchemas,
228
+ state: minimalState,
207
229
  machine,
208
230
  messages,
209
231
  // TODO: fix UIMessage thing
210
- ...otherPlanInput
232
+ ...otherDecideInput
211
233
  });
212
- if (plan?.nextEvent) {
213
- agent.addPlan(plan);
214
- await resolvedOptions.execute?.(plan.nextEvent);
234
+ if (decision?.nextEvent) {
235
+ agent.addDecision(decision);
236
+ await resolvedOptions.execute?.(decision.nextEvent);
237
+ break;
215
238
  }
216
239
  }
217
- return plan;
240
+ return decision;
218
241
  }
219
242
  function fromDecision(agent, defaultInput) {
220
243
  return fromPromise2(async ({ input, self }) => {
@@ -228,19 +251,17 @@ function fromDecision(agent, defaultInput) {
228
251
  ...defaultInput,
229
252
  ...inputObject
230
253
  };
231
- const state = {
232
- value: snapshot.value,
233
- context: resolvedInput.context
234
- };
235
- const plan = await agentDecide(agent, {
254
+ const decision = await agentDecide(agent, {
236
255
  machine: parentRef.logic,
237
- state,
256
+ state: snapshot,
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,30 @@ 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
+ stateValue: input.state.value,
325
+ context: input.context ?? input.state.context,
304
326
  goal: input.goal
305
327
  });
306
328
  const messages = await getMessages(agent, prompt, input);
307
329
  const model = input.model ? agent.wrap(input.model) : agent.model;
308
- const {
309
- state,
310
- machine,
311
- previousPlan,
312
- events,
313
- goal,
314
- model: _,
315
- ...rest
316
- } = input;
317
- const machineState = input.machine ? input.machine.resolveState({
330
+ const { state, machine, events, goal, model: _, ...rest } = input;
331
+ const machineState = input.machine && input.state ? input.machine.resolveState({
318
332
  ...input.state,
319
- context: input.state.context
333
+ context: input.state.context ?? {}
320
334
  }) : void 0;
321
335
  const result = await generateText2({
322
336
  ...rest,
@@ -340,7 +354,8 @@ async function simplePlanner(agent, input) {
340
354
  return void 0;
341
355
  }
342
356
  return {
343
- planner: "simple",
357
+ id: randomId(),
358
+ strategy: "simple",
344
359
  goal: input.goal,
345
360
  goalState: input.state,
346
361
  nextEvent: singleResult.result,
@@ -459,12 +474,11 @@ var agentLogic = fromTransition(
459
474
  });
460
475
  break;
461
476
  }
462
- case "agent.plan": {
463
- state.plans.push(event.plan);
477
+ case "agent.decision": {
478
+ state.decisions.push(event.decision);
464
479
  emit({
465
- type: "plan",
466
- // @ts-ignore TODO: fix types in XState
467
- plan: event.plan
480
+ type: "decision",
481
+ decision: event.decision
468
482
  });
469
483
  break;
470
484
  }
@@ -479,7 +493,7 @@ var agentLogic = fromTransition(
479
493
  feedback: [],
480
494
  messages: [],
481
495
  observations: [],
482
- plans: []
496
+ decisions: []
483
497
  })
484
498
  );
485
499
  function createAgent({
@@ -488,7 +502,8 @@ function createAgent({
488
502
  model,
489
503
  events,
490
504
  context,
491
- planner = simplePlanner,
505
+ episodeId,
506
+ strategy = simpleStrategy,
492
507
  logic = agentLogic
493
508
  }) {
494
509
  return new Agent({
@@ -496,9 +511,10 @@ function createAgent({
496
511
  context,
497
512
  events,
498
513
  description,
499
- planner,
514
+ strategy,
500
515
  model,
501
- logic
516
+ logic,
517
+ episodeId
502
518
  });
503
519
  }
504
520
  var Agent = class extends Actor {
@@ -511,17 +527,18 @@ var Agent = class extends Actor {
511
527
  model,
512
528
  events,
513
529
  context,
514
- planner = simplePlanner
530
+ episodeId,
531
+ strategy = simpleStrategy
515
532
  }) {
516
533
  super(logic);
517
534
  this.model = model;
518
- this.episodeId = id ?? randomId();
535
+ this.episodeId = episodeId ?? randomId("episode-");
519
536
  this.name = name;
520
537
  this.description = description;
521
538
  this.events = events;
522
539
  this.context = context;
523
- this.planner = planner;
524
- this.types = {};
540
+ this.strategy = strategy;
541
+ this.id = id ?? randomId();
525
542
  this.start();
526
543
  }
527
544
  /**
@@ -530,6 +547,12 @@ var Agent = class extends Actor {
530
547
  onMessage(fn) {
531
548
  return this.on("message", (ev) => fn(ev.message));
532
549
  }
550
+ /**
551
+ * Called whenever the agent (LLM assistant) receives some feedback.
552
+ */
553
+ onFeedback(fn) {
554
+ return this.on("feedback", (ev) => fn(ev.feedback));
555
+ }
533
556
  /**
534
557
  * Retrieves messages from the agent's short-term (local) memory.
535
558
  */
@@ -552,8 +575,8 @@ var Agent = class extends Actor {
552
575
  addFeedback(feedbackInput) {
553
576
  const feedback = {
554
577
  ...feedbackInput,
578
+ comment: feedbackInput.comment ?? void 0,
555
579
  attributes: { ...feedbackInput.attributes },
556
- reward: feedbackInput.reward ?? 0,
557
580
  timestamp: feedbackInput.timestamp ?? Date.now(),
558
581
  episodeId: this.episodeId
559
582
  };
@@ -592,17 +615,17 @@ var Agent = class extends Actor {
592
615
  getObservations() {
593
616
  return this.getSnapshot().context.observations;
594
617
  }
595
- addPlan(plan) {
618
+ addDecision(decision) {
596
619
  this.send({
597
- type: "agent.plan",
598
- plan
620
+ type: "agent.decision",
621
+ decision
599
622
  });
600
623
  }
601
624
  /**
602
625
  * Retrieves strategies from the agent's short-term (local) memory.
603
626
  */
604
- getPlans() {
605
- return this.getSnapshot().context.plans;
627
+ getDecisions() {
628
+ return this.getSnapshot().context.decisions;
606
629
  }
607
630
  interact(actorRef, getInput) {
608
631
  const actorRefCheck = isActorRef(actorRef) && actorRef.src;
@@ -612,15 +635,16 @@ var Agent = class extends Actor {
612
635
  const agent = this;
613
636
  async function handleObservation(observationInput) {
614
637
  const observation = agent.addObservation(observationInput);
615
- const input = getInput?.(observation);
616
- if (input) {
617
- const res = await agentDecide(agent, {
638
+ const interactInput = getInput?.(observation);
639
+ if (interactInput) {
640
+ const decision = await agentDecide(agent, {
618
641
  machine,
619
642
  state: observation.state,
620
- ...input
643
+ ...interactInput
621
644
  });
622
- if (res?.nextEvent) {
623
- actorRef.send(res.nextEvent);
645
+ if (decision?.nextEvent) {
646
+ decision.nextEvent["_decision"] = decision.id;
647
+ actorRef.send(decision.nextEvent);
624
648
  }
625
649
  }
626
650
  prevState = observationInput.state;
@@ -630,11 +654,14 @@ var Agent = class extends Actor {
630
654
  if (!subscribed || inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
631
655
  return;
632
656
  }
657
+ const decisionId = inspEvent.event["_decision"];
658
+ const decision = decisionId ? agent.getDecisions().find((d) => d.id === decisionId) : void 0;
633
659
  const observationInput = {
634
660
  event: inspEvent.event,
635
661
  prevState,
636
662
  state: inspEvent.snapshot,
637
- machine: actorRef.src
663
+ machine: actorRef.src,
664
+ goal: decision?.goal
638
665
  };
639
666
  await handleObservation(observationInput);
640
667
  }
@@ -642,10 +669,10 @@ var Agent = class extends Actor {
642
669
  if (actorRef._processingStatus === 1) {
643
670
  handleObservation({
644
671
  prevState: void 0,
645
- event: { type: "" },
646
- // TODO: unknown events?
672
+ event: void 0,
647
673
  state: actorRef.getSnapshot(),
648
- machine: actorRef.src
674
+ machine: actorRef.src,
675
+ goal: void 0
649
676
  });
650
677
  }
651
678
  return {
@@ -663,11 +690,14 @@ var Agent = class extends Actor {
663
690
  if (inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
664
691
  return;
665
692
  }
693
+ const decisionId = inspEvent.event["_decision"];
694
+ const decision = decisionId ? this.getDecisions().find((d) => d.id === decisionId) : void 0;
666
695
  const observationInput = {
667
696
  event: inspEvent.event,
668
697
  prevState,
669
698
  state: inspEvent.snapshot,
670
- machine: actorRef.src
699
+ machine: actorRef.src,
700
+ goal: decision?.goal
671
701
  };
672
702
  prevState = observationInput.state;
673
703
  this.addObservation(observationInput);
@@ -683,14 +713,14 @@ var Agent = class extends Actor {
683
713
  });
684
714
  }
685
715
  /**
686
- * Resolves with an `AgentPlan` based on the information provided in the `options`, including:
716
+ * Resolves with an `AgentDecision` based on the information provided in the `options`, including:
687
717
  *
688
718
  * - The `goal` for the agent to achieve
689
719
  * - The observed current `state`
690
720
  * - The `machine` (e.g. a state machine) that specifies what can happen next
691
721
  * - Additional `context`
692
722
  */
693
- decide(opts) {
723
+ async decide(opts) {
694
724
  return agentDecide(this, opts);
695
725
  }
696
726
  };
@@ -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,92 +1,40 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision } from '../src';
2
+ import { createAgent } from '../src';
3
3
  import { openai } from '@ai-sdk/openai';
4
- import { assign, createActor, log, setup } from 'xstate';
5
- import { fromTerminal } from './helpers/helpers';
4
+ import { getFromTerminal } from './helpers/helpers';
5
+ import { chainOfThoughtStrategy } from '../src/strategies/chainOfThought';
6
6
 
7
7
  const agent = createAgent({
8
8
  id: 'chain-of-thought',
9
- model: openai('gpt-4o-mini'),
9
+ model: openai('gpt-4o'),
10
10
  events: {
11
- 'agent.think': z.object({
12
- thought: z
13
- .string()
14
- .describe('The thought process to answering the question'),
15
- }),
16
11
  'agent.answer': z.object({
17
12
  answer: z.string().describe('The answer to the question'),
18
13
  }),
19
14
  },
20
15
  context: {
21
16
  question: z.string().nullable(),
22
- thought: z.string().nullable(),
23
17
  },
18
+ strategy: chainOfThoughtStrategy,
24
19
  });
25
20
 
26
- const machine = setup({
27
- types: agent.types,
28
- actors: { getFromTerminal: fromTerminal },
29
- }).createMachine({
30
- initial: 'asking',
31
- context: {
32
- question: null,
33
- thought: null,
34
- },
35
- states: {
36
- asking: {
37
- invoke: {
38
- src: 'getFromTerminal',
39
- input: 'What would you like to ask?',
40
- onDone: {
41
- actions: assign({
42
- question: ({ event }) => event.output,
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
- target: 'answering',
58
- },
59
- },
60
- },
61
- answering: {
62
- on: {
63
- 'agent.answer': {
64
- actions: log(({ event }) => `Answer: ${event.answer}`),
65
- target: 'answered',
66
- },
21
+ // agent.onMessage((msg) => console.log(msg.content));
22
+
23
+ async function main() {
24
+ const msg = await getFromTerminal('what?');
25
+
26
+ const decision = await agent.decide({
27
+ messages: agent.getMessages(),
28
+ goal: 'Answer the question.',
29
+ state: {
30
+ value: 'thinking',
31
+ context: {
32
+ question: msg,
67
33
  },
68
34
  },
69
- answered: {
70
- type: 'final',
71
- },
72
- },
73
- });
35
+ });
74
36
 
75
- const actor = createActor(machine).start();
37
+ console.log(decision?.nextEvent?.answer);
38
+ }
76
39
 
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
- });
40
+ main();
@@ -1,4 +1,4 @@
1
- import { createAgent, fromDecision } from '../src';
1
+ import { createAgent, EventFromAgent, 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
+ | EventFromAgent<typeof customerServiceAgent>
42
+ | EventFromAgent<typeof customerAgent>,
43
43
  },
44
44
  actors: {
45
45
  customerService: fromDecision(customerServiceAgent),
package/examples/email.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision } from '../src';
2
+ import { ContextFromAgent, createAgent, EventFromAgent } from '../src';
3
3
  import { openai } from '@ai-sdk/openai';
4
4
  import { assign, createActor, setup } from 'xstate';
5
5
  import { fromTerminal } from './helpers/helpers';
@@ -27,12 +27,12 @@ const agent = createAgent({
27
27
 
28
28
  const machine = setup({
29
29
  types: {
30
- events: agent.types.events,
30
+ events: {} as EventFromAgent<typeof agent>,
31
31
  input: {} as {
32
32
  email: string;
33
33
  instructions: string;
34
34
  },
35
- context: agent.types.context,
35
+ context: {} as ContextFromAgent<typeof agent>,
36
36
  },
37
37
  actors: { getFromTerminal: fromTerminal },
38
38
  }).createMachine({
@@ -101,14 +101,12 @@ agent.interact(actor, ({ state }) => {
101
101
  if (state.matches('checking')) {
102
102
  return {
103
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
104
  };
106
105
  }
107
106
 
108
107
  if (state.matches('submitting')) {
109
108
  return {
110
109
  goal: 'Create and submit an email based on the instructions.',
111
- context: state.context,
112
110
  };
113
111
  }
114
112
  });
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { createAgent, fromDecision, fromText } from '../src';
2
+ import { createAgent, EventFromAgent, 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 EventFromAgent<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, EventFromAgent, 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 EventFromAgent<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,
@@ -186,40 +186,40 @@ const jokeMachine = setup({
186
186
 
187
187
  const actor = createActor(jokeMachine);
188
188
 
189
- agent.interact(actor, (observed) => {
190
- if (observed.state.matches('tellingJoke')) {
189
+ agent.interact(actor, ({ state }) => {
190
+ if (state.matches('tellingJoke')) {
191
191
  return {
192
192
  goal: 'Tell me a joke about the topic. Do not make any joke that is not relevant to the topic.',
193
193
  context: {
194
- topic: observed.state.context.topic,
194
+ topic: state.context.topic,
195
195
  },
196
196
  };
197
197
  }
198
198
 
199
- if (observed.state.matches('relevance')) {
199
+ if (state.matches('relevance')) {
200
200
  return {
201
201
  goal: 'An irrelevant joke has no reference to the topic. If the last joke is completely irrelevant to the topic, ask for a new joke topic. Otherwise, continue.',
202
202
  context: {
203
- topic: observed.state.context.topic,
204
- lastJoke: observed.state.context.jokes.at(-1),
203
+ topic: state.context.topic,
204
+ lastJoke: state.context.jokes.at(-1),
205
205
  },
206
206
  };
207
207
  }
208
208
 
209
- if (observed.state.matches('rateJoke')) {
209
+ if (state.matches('rateJoke')) {
210
210
  return {
211
211
  goal: 'Rate the last joke on a scale of 1 to 10.',
212
212
  context: {
213
- lastJoke: observed.state.context.jokes.at(-1),
213
+ lastJoke: state.context.jokes.at(-1),
214
214
  },
215
215
  };
216
216
  }
217
217
 
218
- if (observed.state.matches('decide')) {
218
+ if (state.matches('decide')) {
219
219
  return {
220
220
  goal: 'Choose what to do next, given the previous rating of the joke.',
221
221
  context: {
222
- lastRating: observed.state.context.lastRating,
222
+ lastRating: state.context.lastRating,
223
223
  },
224
224
  };
225
225
  }