@statelyai/agent 1.0.0-beta.1 → 1.1.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.
package/dist/index.mjs CHANGED
@@ -1,21 +1,43 @@
1
1
  // src/agent.ts
2
2
  import {
3
3
  createActor,
4
- fromTransition,
5
- toObserver as toObserver2
4
+ fromTransition
6
5
  } from "xstate";
7
6
 
8
7
  // src/planners/simplePlanner.ts
9
8
  import { tool } from "ai";
10
9
 
11
10
  // src/utils.ts
11
+ import hash from "object-hash";
12
12
  function getAllTransitions(state) {
13
13
  const nodes = state._nodes;
14
- const transitions = nodes.map((node) => [...node.transitions.values()]).flat(2).map((transition) => ({
15
- ...transition,
16
- guard: typeof transition.guard === "string" ? { type: transition.guard } : transition.guard
17
- // TODO: fix
18
- }));
14
+ const transitions = nodes.map((node) => [...node.transitions.values()]).map((nodeTransitions) => {
15
+ return nodeTransitions.map((nodeEventTransitions) => {
16
+ return nodeEventTransitions.map((transition) => {
17
+ return {
18
+ ...transition,
19
+ guard: typeof transition.guard === "string" ? { type: transition.guard } : transition.guard
20
+ // TODO: fix
21
+ };
22
+ });
23
+ });
24
+ }).flat(2);
25
+ return transitions;
26
+ }
27
+ function getAllMachineTransitions(stateNode) {
28
+ const transitions = [...stateNode.transitions.values()].map((nodeTransitions) => {
29
+ return nodeTransitions.map((transition) => {
30
+ return {
31
+ ...transition,
32
+ guard: typeof transition.guard === "string" ? { type: transition.guard } : transition.guard
33
+ // TODO: fix
34
+ };
35
+ });
36
+ }).flat(2);
37
+ for (const s of Object.values(stateNode.states)) {
38
+ const stateTransitions = getAllMachineTransitions(s);
39
+ transitions.push(...stateTransitions);
40
+ }
19
41
  return transitions;
20
42
  }
21
43
  function wrapInXml(tagName, content) {
@@ -26,6 +48,14 @@ function randomId() {
26
48
  const random = Math.random().toString(36).substring(2, 9);
27
49
  return timestamp + random;
28
50
  }
51
+ var machineHashes = /* @__PURE__ */ new WeakMap();
52
+ function getMachineHash(machine) {
53
+ if (machineHashes.has(machine)) return machineHashes.get(machine);
54
+ const transitions = getAllMachineTransitions(machine.root);
55
+ const machineHash = hash(transitions);
56
+ machineHashes.set(machine, machineHash);
57
+ return machineHash;
58
+ }
29
59
 
30
60
  // src/templates/defaultText.ts
31
61
  var defaultTextTemplate = (data) => {
@@ -39,87 +69,6 @@ ${data.goal}
39
69
  `.trim();
40
70
  };
41
71
 
42
- // src/planners/simplePlanner.ts
43
- function getTransitions(state, machine) {
44
- if (!machine) {
45
- return [];
46
- }
47
- const resolvedState = machine.resolveState(state);
48
- return getAllTransitions(resolvedState);
49
- }
50
- var simplePlannerPromptTemplate = (data) => {
51
- return `
52
- ${defaultTextTemplate(data)}
53
-
54
- Only make a single tool call to achieve the above goal.
55
- `.trim();
56
- };
57
- async function simplePlanner(agent, input) {
58
- const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(input.events).map(([eventType, { description }]) => ({
59
- eventType,
60
- description
61
- }));
62
- const filter = (eventType) => Object.keys(input.events).includes(eventType);
63
- const functionNameMapping = {};
64
- const toolTransitions = transitions.filter((t) => {
65
- return filter(t.eventType);
66
- }).map((t) => {
67
- const name = t.eventType.replace(/\./g, "_");
68
- functionNameMapping[name] = t.eventType;
69
- return {
70
- type: "function",
71
- eventType: t.eventType,
72
- description: t.description,
73
- name
74
- };
75
- });
76
- const toolMap = {};
77
- for (const toolTransitionData of toolTransitions) {
78
- const toolZodType = input.events?.[toolTransitionData.eventType];
79
- if (!toolZodType) {
80
- continue;
81
- }
82
- toolMap[toolTransitionData.name] = tool({
83
- description: toolZodType?.description ?? toolTransitionData.description,
84
- parameters: toolZodType,
85
- execute: async (params) => {
86
- const event = {
87
- type: toolTransitionData.eventType,
88
- ...params
89
- };
90
- return event;
91
- }
92
- });
93
- }
94
- const prompt = simplePlannerPromptTemplate({
95
- context: input.state.context,
96
- goal: input.goal
97
- });
98
- const result = await agent.generateText({
99
- ...input,
100
- prompt,
101
- tools: toolMap,
102
- toolChoice: "required"
103
- });
104
- const singleResult = result.toolResults[0];
105
- if (!singleResult) {
106
- console.warn("No tool call results returned");
107
- return void 0;
108
- }
109
- return {
110
- goal: input.goal,
111
- state: input.state,
112
- steps: [
113
- {
114
- event: singleResult.result
115
- }
116
- ],
117
- nextEvent: singleResult.result,
118
- sessionId: agent.sessionId,
119
- timestamp: Date.now()
120
- };
121
- }
122
-
123
72
  // src/text.ts
124
73
  import {
125
74
  fromObservable,
@@ -128,9 +77,7 @@ import {
128
77
  } from "xstate";
129
78
  async function getMessages(agent, prompt, options) {
130
79
  let messages = [];
131
- if (options.messages === true) {
132
- messages = agent.select((s) => s.messages);
133
- } else if (typeof options.messages === "function") {
80
+ if (typeof options.messages === "function") {
134
81
  messages = await options.messages(agent);
135
82
  } else if (options.messages) {
136
83
  messages = options.messages;
@@ -144,7 +91,8 @@ async function getMessages(agent, prompt, options) {
144
91
  async function agentGenerateText(agent, options) {
145
92
  const resolvedOptions = {
146
93
  ...agent.defaultOptions,
147
- ...options
94
+ ...options,
95
+ correlationId: options.correlationId ?? randomId()
148
96
  };
149
97
  const template = resolvedOptions.template ?? defaultTextTemplate;
150
98
  const id = randomId();
@@ -158,7 +106,9 @@ async function agentGenerateText(agent, options) {
158
106
  id,
159
107
  role: "user",
160
108
  content: promptWithContext,
161
- timestamp: Date.now()
109
+ timestamp: Date.now(),
110
+ correlationId: resolvedOptions.correlationId,
111
+ parentCorrelationId: resolvedOptions.parentCorrelationId
162
112
  });
163
113
  const result = await agent.adapter.generateText({
164
114
  ...resolvedOptions,
@@ -171,14 +121,21 @@ async function agentGenerateText(agent, options) {
171
121
  role: "assistant",
172
122
  timestamp: Date.now(),
173
123
  responseId: id,
174
- result
124
+ result,
125
+ correlationId: resolvedOptions.correlationId,
126
+ parentCorrelationId: resolvedOptions.parentCorrelationId
175
127
  });
176
- return result;
128
+ return {
129
+ ...result,
130
+ parentCorrelationId: resolvedOptions.parentCorrelationId,
131
+ correlationId: resolvedOptions.correlationId
132
+ };
177
133
  }
178
134
  async function agentStreamText(agent, options) {
179
135
  const resolvedOptions = {
180
136
  ...agent.defaultOptions,
181
- ...options
137
+ ...options,
138
+ correlationId: options.correlationId ?? randomId()
182
139
  };
183
140
  const template = resolvedOptions.template ?? defaultTextTemplate;
184
141
  const id = randomId();
@@ -192,7 +149,9 @@ async function agentStreamText(agent, options) {
192
149
  role: "user",
193
150
  content: promptWithContext,
194
151
  id,
195
- timestamp: Date.now()
152
+ timestamp: Date.now(),
153
+ correlationId: resolvedOptions.correlationId,
154
+ parentCorrelationId: resolvedOptions.parentCorrelationId
196
155
  });
197
156
  const result = await agent.adapter.streamText({
198
157
  ...resolvedOptions,
@@ -210,26 +169,33 @@ async function agentStreamText(agent, options) {
210
169
  toolResults: [],
211
170
  usage: res.usage,
212
171
  warnings: res.warnings,
213
- rawResponse: res.rawResponse
172
+ rawResponse: res.rawResponse,
173
+ roundtrips: []
174
+ // TODO: how do we get this information?
214
175
  },
215
176
  content: res.text,
216
177
  id: randomId(),
217
178
  timestamp: Date.now(),
218
- responseId: id
179
+ responseId: id,
180
+ correlationId: resolvedOptions.correlationId,
181
+ parentCorrelationId: resolvedOptions.parentCorrelationId
219
182
  });
220
183
  }
221
184
  });
222
- return result;
185
+ return {
186
+ ...result,
187
+ parentCorrelationId: resolvedOptions.parentCorrelationId,
188
+ correlationId: resolvedOptions.correlationId
189
+ };
223
190
  }
224
191
  function fromTextStream(agent, defaultOptions) {
225
- return fromObservable(({ input, self }) => {
226
- const context = input.context === true ? (self._parent?.getSnapshot()).context : input.context;
192
+ return fromObservable(({ input }) => {
227
193
  const observers = /* @__PURE__ */ new Set();
228
194
  (async () => {
229
195
  const result = await agentStreamText(agent, {
230
196
  ...defaultOptions,
231
197
  ...input,
232
- context
198
+ context: input.context
233
199
  });
234
200
  for await (const part of result.fullStream) {
235
201
  if (part.type === "text-delta") {
@@ -253,16 +219,102 @@ function fromTextStream(agent, defaultOptions) {
253
219
  });
254
220
  }
255
221
  function fromText(agent, defaultOptions) {
256
- return fromPromise(async ({ input, self }) => {
257
- const context = input.context === true ? (self._parent?.getSnapshot()).context : input.context;
222
+ return fromPromise(async ({ input }) => {
258
223
  return await agentGenerateText(agent, {
259
224
  ...input,
260
225
  ...defaultOptions,
261
- context
226
+ context: input.context
262
227
  });
263
228
  });
264
229
  }
265
230
 
231
+ // src/planners/simplePlanner.ts
232
+ function getTransitions(state, machine) {
233
+ if (!machine) {
234
+ return [];
235
+ }
236
+ const resolvedState = machine.resolveState(state);
237
+ return getAllTransitions(resolvedState);
238
+ }
239
+ var simplePlannerPromptTemplate = (data) => {
240
+ return `
241
+ ${defaultTextTemplate(data)}
242
+
243
+ 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.
244
+ `.trim();
245
+ };
246
+ async function simplePlanner(agent, input) {
247
+ const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(input.events).map(([eventType, { description }]) => ({
248
+ eventType,
249
+ description
250
+ }));
251
+ const filter = (eventType) => Object.keys(input.events).includes(eventType);
252
+ const functionNameMapping = {};
253
+ const toolTransitions = transitions.filter((t) => {
254
+ return filter(t.eventType);
255
+ }).map((t) => {
256
+ const name = t.eventType.replace(/\./g, "_");
257
+ functionNameMapping[name] = t.eventType;
258
+ return {
259
+ type: "function",
260
+ eventType: t.eventType,
261
+ description: t.description,
262
+ name
263
+ };
264
+ });
265
+ const toolMap = {};
266
+ for (const toolTransitionData of toolTransitions) {
267
+ const toolZodType = input.events?.[toolTransitionData.eventType];
268
+ if (!toolZodType) {
269
+ continue;
270
+ }
271
+ toolMap[toolTransitionData.name] = tool({
272
+ description: toolZodType?.description ?? toolTransitionData.description,
273
+ parameters: toolZodType,
274
+ execute: async (params) => {
275
+ const event = {
276
+ type: toolTransitionData.eventType,
277
+ ...params
278
+ };
279
+ return event;
280
+ }
281
+ });
282
+ }
283
+ if (!Object.keys(toolMap).length) {
284
+ return void 0;
285
+ }
286
+ const prompt = simplePlannerPromptTemplate({
287
+ context: input.state.context,
288
+ goal: input.goal
289
+ });
290
+ const messages = await getMessages(agent, prompt, input);
291
+ const result = await agent.generateText({
292
+ toolChoice: "required",
293
+ ...input,
294
+ prompt,
295
+ messages,
296
+ tools: toolMap
297
+ });
298
+ const singleResult = result.toolResults[0];
299
+ if (!singleResult) {
300
+ console.warn("No tool call results returned");
301
+ return void 0;
302
+ }
303
+ return {
304
+ goal: input.goal,
305
+ state: input.state,
306
+ execute: async (state) => {
307
+ if (JSON.stringify(state) === JSON.stringify(input.state)) {
308
+ return singleResult.result;
309
+ }
310
+ return void 0;
311
+ },
312
+ nextEvent: singleResult.result,
313
+ sessionId: agent.sessionId,
314
+ timestamp: Date.now()
315
+ };
316
+ }
317
+
266
318
  // src/decision.ts
267
319
  import { fromPromise as fromPromise2 } from "xstate";
268
320
  async function agentDecide(agent, options) {
@@ -377,18 +429,19 @@ var agentLogic = fromTransition(
377
429
  }
378
430
  return state;
379
431
  },
380
- {
432
+ () => ({
381
433
  feedback: [],
382
434
  messages: [],
383
435
  observations: [],
384
436
  plans: []
385
- }
437
+ })
386
438
  );
387
439
  function createAgent({
388
440
  name,
389
441
  description,
390
442
  model,
391
443
  events,
444
+ context,
392
445
  planner = simplePlanner,
393
446
  stringify = JSON.stringify,
394
447
  getMemory,
@@ -396,7 +449,6 @@ function createAgent({
396
449
  adapter = vercelAdapter,
397
450
  ...generateTextOptions
398
451
  }) {
399
- const messageHistoryListeners = [];
400
452
  const agent = createActor(logic);
401
453
  agent.events = events;
402
454
  agent.model = model;
@@ -409,7 +461,7 @@ function createAgent({
409
461
  };
410
462
  agent.memory = getMemory ? getMemory(agent) : void 0;
411
463
  agent.onMessage = (callback) => {
412
- messageHistoryListeners.push(toObserver2(callback));
464
+ agent.on("message", (ev) => callback(ev.message));
413
465
  };
414
466
  agent.decide = (opts) => {
415
467
  return agentDecide(agent, opts);
@@ -419,7 +471,8 @@ function createAgent({
419
471
  ...messageInput,
420
472
  id: messageInput.id ?? randomId(),
421
473
  timestamp: messageInput.timestamp ?? Date.now(),
422
- sessionId: agent.sessionId
474
+ sessionId: agent.sessionId,
475
+ correlationId: messageInput.correlationId ?? randomId()
423
476
  };
424
477
  agent.send({
425
478
  type: "agent.message",
@@ -427,11 +480,14 @@ function createAgent({
427
480
  });
428
481
  return message;
429
482
  };
483
+ agent.getMessages = () => agent.getSnapshot().context.messages;
430
484
  agent.generateText = (opts) => agentGenerateText(agent, opts);
431
485
  agent.streamText = (opts) => agentStreamText(agent, opts);
432
486
  agent.addFeedback = (feedbackInput) => {
433
487
  const feedback = {
434
488
  ...feedbackInput,
489
+ attributes: { ...feedbackInput.attributes },
490
+ reward: feedbackInput.reward ?? 0,
435
491
  timestamp: feedbackInput.timestamp ?? Date.now(),
436
492
  sessionId: agent.sessionId
437
493
  };
@@ -441,12 +497,17 @@ function createAgent({
441
497
  });
442
498
  return feedback;
443
499
  };
500
+ agent.getFeedback = () => agent.getSnapshot().context.feedback;
444
501
  agent.addObservation = (observationInput) => {
502
+ const { prevState, event, state } = observationInput;
445
503
  const observation = {
446
- ...observationInput,
504
+ prevState,
505
+ event,
506
+ state,
447
507
  id: observationInput.id ?? randomId(),
448
508
  sessionId: agent.sessionId,
449
- timestamp: observationInput.timestamp ?? Date.now()
509
+ timestamp: observationInput.timestamp ?? Date.now(),
510
+ machineHash: observationInput.machine ? getMachineHash(observationInput.machine) : void 0
450
511
  };
451
512
  agent.send({
452
513
  type: "agent.observe",
@@ -454,12 +515,14 @@ function createAgent({
454
515
  });
455
516
  return observation;
456
517
  };
518
+ agent.getObservations = () => agent.getSnapshot().context.observations;
457
519
  agent.addPlan = (plan) => {
458
520
  agent.send({
459
521
  type: "agent.plan",
460
522
  plan
461
523
  });
462
524
  };
525
+ agent.getPlans = () => agent.getSnapshot().context.plans;
463
526
  agent.interact = (actorRef, getInput) => {
464
527
  let prevState = void 0;
465
528
  let subscribed = true;
@@ -486,7 +549,8 @@ function createAgent({
486
549
  const observationInput = {
487
550
  event: inspEvent.event,
488
551
  prevState,
489
- state: inspEvent.snapshot
552
+ state: inspEvent.snapshot,
553
+ machine: actorRef.src
490
554
  };
491
555
  await handleObservation(observationInput);
492
556
  }
@@ -496,7 +560,8 @@ function createAgent({
496
560
  prevState: void 0,
497
561
  event: { type: "" },
498
562
  // TODO: unknown events?
499
- state: actorRef.getSnapshot()
563
+ state: actorRef.getSnapshot(),
564
+ machine: actorRef.src
500
565
  });
501
566
  }
502
567
  return {
@@ -506,12 +571,11 @@ function createAgent({
506
571
  // TODO: make this actually unsubscribe
507
572
  };
508
573
  };
574
+ agent.types = {};
509
575
  agent.start();
510
576
  return agent;
511
577
  }
512
578
  export {
513
- agentDecide,
514
- agentGenerateText,
515
579
  createAgent,
516
580
  fromDecision,
517
581
  fromText,
@@ -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
- conversation: [],
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
- conversation: (x) =>
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
- conversation: x.context.conversation,
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.eventTypes,
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.select((ctx) => ctx.messages),
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
  },
@@ -18,7 +18,7 @@ const agent = createAgent({
18
18
 
19
19
  const machine = setup({
20
20
  types: {
21
- events: agent.eventTypes,
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: true,
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: true,
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
@@ -25,7 +25,7 @@ const machine = setup({
25
25
  question: string | null;
26
26
  goal: string | null;
27
27
  },
28
- events: agent.eventTypes,
28
+ events: agent.types.events,
29
29
  },
30
30
  actors: { decider, getFromTerminal },
31
31
  }).createMachine({
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,
@@ -20,7 +20,7 @@ const machine = setup({
20
20
  previousGuesses: number[];
21
21
  answer: number | null;
22
22
  },
23
- events: agent.eventTypes,
23
+ events: agent.types.events,
24
24
  },
25
25
  actors: {
26
26
  agent: fromDecision(agent),
@@ -27,7 +27,7 @@ const machine = setup({
27
27
  lastInput: string | null;
28
28
  entries: string[];
29
29
  },
30
- events: {} as typeof agent.eventTypes | { type: 'draw' },
30
+ events: {} as typeof agent.types.events | { type: 'draw' },
31
31
  },
32
32
  actors: { agent: fromDecision(agent), getFromTerminal },
33
33
  }).createMachine({