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

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 (41) hide show
  1. package/.changeset/nice-pants-rule.md +10 -0
  2. package/.changeset/pink-eagles-deliver.md +13 -0
  3. package/.changeset/pre.json +7 -1
  4. package/.changeset/quiet-turtles-do.md +7 -0
  5. package/.changeset/sweet-clouds-mix.md +16 -0
  6. package/.changeset/swift-mangos-rush.md +5 -0
  7. package/.changeset/tough-ways-rhyme.md +5 -0
  8. package/CHANGELOG.md +50 -0
  9. package/architecture.tldr +175 -0
  10. package/dist/index.d.mts +116 -102
  11. package/dist/index.d.ts +116 -102
  12. package/dist/index.js +51 -74
  13. package/dist/index.mjs +51 -74
  14. package/examples/cot.ts +19 -53
  15. package/examples/customer-service-sim.ts +3 -3
  16. package/examples/email.ts +2 -10
  17. package/examples/example.ts +2 -2
  18. package/examples/goal.ts +2 -2
  19. package/examples/joke.ts +10 -10
  20. package/examples/learn-from-feedback.ts +47 -24
  21. package/examples/number.ts +2 -2
  22. package/examples/raffle.ts +2 -2
  23. package/examples/support.ts +7 -11
  24. package/examples/ticTacToe.ts +2 -2
  25. package/examples/todo.ts +3 -3
  26. package/examples/tutor.ts +2 -2
  27. package/examples/verify.ts +2 -2
  28. package/examples/weather-agent.ts +3 -5
  29. package/examples/weather.ts +10 -7
  30. package/package.json +1 -1
  31. package/src/agent.test.ts +124 -43
  32. package/src/agent.ts +61 -42
  33. package/src/decide.test.ts +22 -0
  34. package/src/decide.ts +27 -29
  35. package/src/strategies/chainOfThought.ts +5 -3
  36. package/src/strategies/shortestPath.ts +7 -2
  37. package/src/strategies/{simple.ts → simpleStrategy.ts} +5 -16
  38. package/src/templates/defaultText.ts +3 -0
  39. package/src/text.ts +13 -14
  40. package/src/types.ts +103 -104
  41. package/src/utils.ts +1 -1
package/dist/index.js CHANGED
@@ -40,7 +40,7 @@ module.exports = __toCommonJS(src_exports);
40
40
  // src/agent.ts
41
41
  var import_xstate4 = require("xstate");
42
42
 
43
- // src/strategies/simple.ts
43
+ // src/strategies/simpleStrategy.ts
44
44
  var import_ai3 = require("ai");
45
45
 
46
46
  // src/utils.ts
@@ -60,22 +60,6 @@ function getAllTransitions(state) {
60
60
  }).flat(2);
61
61
  return transitions;
62
62
  }
63
- function getAllMachineTransitions(stateNode) {
64
- const transitions = [...stateNode.transitions.values()].map((nodeTransitions) => {
65
- return nodeTransitions.map((transition) => {
66
- return {
67
- ...transition,
68
- guard: typeof transition.guard === "string" ? { type: transition.guard } : transition.guard
69
- // TODO: fix
70
- };
71
- });
72
- }).flat(2);
73
- for (const s of Object.values(stateNode.states)) {
74
- const stateTransitions = getAllMachineTransitions(s);
75
- transitions.push(...stateTransitions);
76
- }
77
- return transitions;
78
- }
79
63
  function wrapInXml(tagName, content) {
80
64
  return `<${tagName}>${content}</${tagName}>`;
81
65
  }
@@ -93,14 +77,6 @@ function randomId(prefix) {
93
77
  const random = Math.random().toString(36).substring(2, 9);
94
78
  return `${prefix || ""}${timestamp}${random}`;
95
79
  }
96
- var machineHashes = /* @__PURE__ */ new WeakMap();
97
- function getMachineHash(machine) {
98
- if (machineHashes.has(machine)) return machineHashes.get(machine);
99
- const transitions = getAllMachineTransitions(machine.root);
100
- const machineHash = (0, import_object_hash.default)(transitions);
101
- machineHashes.set(machine, machineHash);
102
- return machineHash;
103
- }
104
80
  function isActorRef(actorRefLike) {
105
81
  return "src" in actorRefLike && "system" in actorRefLike && "sessionId" in actorRefLike;
106
82
  }
@@ -119,7 +95,7 @@ function isMachineActor(actor) {
119
95
  return "src" in actor && typeof actor.src === "object" && actor.src !== null && "definition" in actor.src;
120
96
  }
121
97
 
122
- // src/strategies/simple.ts
98
+ // src/strategies/simpleStrategy.ts
123
99
  var import_xstate3 = require("xstate");
124
100
 
125
101
  // src/text.ts
@@ -128,6 +104,7 @@ var import_ai = require("ai");
128
104
  // src/templates/defaultText.ts
129
105
  var defaultTextTemplate = (data) => {
130
106
  const preamble = [
107
+ data.stateValue ? wrapInXml("stateValue", JSON.stringify(data.stateValue)) : void 0,
131
108
  data.context ? wrapInXml("context", JSON.stringify(data.context)) : void 0
132
109
  ].filter(Boolean).join("\n");
133
110
  return `
@@ -195,7 +172,6 @@ function fromTextStream(agent, options) {
195
172
  }
196
173
  function fromText(agent, options) {
197
174
  const resolvedOptions = {
198
- ...agent.defaultOptions,
199
175
  ...options
200
176
  };
201
177
  const template = resolvedOptions.template ?? defaultTextTemplate;
@@ -221,10 +197,7 @@ function fromText(agent, options) {
221
197
  var import_xstate2 = require("xstate");
222
198
  var import_ai2 = require("ai");
223
199
  async function agentDecide(agent, options) {
224
- const resolvedOptions = {
225
- ...agent.defaultOptions,
226
- ...options
227
- };
200
+ const resolvedOptions = options;
228
201
  const {
229
202
  strategy = agent.strategy,
230
203
  goal,
@@ -234,6 +207,8 @@ async function agentDecide(agent, options) {
234
207
  machine,
235
208
  model = agent.model,
236
209
  messages,
210
+ episodeId = agent.episodeId,
211
+ maxAttempts = 2,
237
212
  ...otherDecideInput
238
213
  } = resolvedOptions;
239
214
  const filteredEventSchemas = allowedEvents ? Object.fromEntries(
@@ -242,14 +217,18 @@ async function agentDecide(agent, options) {
242
217
  })
243
218
  ) : events;
244
219
  let attempts = 0;
245
- const maxAttempts = resolvedOptions.maxAttempts ?? 2;
246
220
  let decision;
221
+ const minimalState = {
222
+ value: state.value,
223
+ context: state.context
224
+ };
247
225
  while (attempts++ < maxAttempts) {
248
226
  decision = await strategy(agent, {
227
+ episodeId,
249
228
  model,
250
229
  goal,
251
230
  events: filteredEventSchemas,
252
- state,
231
+ state: minimalState,
253
232
  machine,
254
233
  messages,
255
234
  // TODO: fix UIMessage thing
@@ -257,7 +236,6 @@ async function agentDecide(agent, options) {
257
236
  });
258
237
  if (decision?.nextEvent) {
259
238
  agent.addDecision(decision);
260
- await resolvedOptions.execute?.(decision.nextEvent);
261
239
  break;
262
240
  }
263
241
  }
@@ -275,30 +253,26 @@ function fromDecision(agent, defaultInput) {
275
253
  ...defaultInput,
276
254
  ...inputObject
277
255
  };
278
- const state = {
279
- value: snapshot.value,
280
- context: resolvedInput.context
281
- };
282
256
  const decision = await agentDecide(agent, {
283
257
  machine: parentRef.logic,
284
258
  state: snapshot,
285
- context: resolvedInput.context,
286
- execute: async (event) => {
287
- parentRef.send(event);
288
- },
289
259
  ...resolvedInput,
290
260
  // @ts-ignore
291
261
  messages: resolvedInput.messages
292
262
  });
263
+ if (decision?.nextEvent) {
264
+ parentRef.send(decision.nextEvent);
265
+ }
293
266
  return decision;
294
267
  });
295
268
  }
296
- function getToolMap(_agent, input) {
297
- const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(input.events).map(([eventType, { description }]) => ({
269
+ function getToolMap(agent, input) {
270
+ const events = input.events ?? agent.events;
271
+ const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(events).map(([eventType, { description }]) => ({
298
272
  eventType,
299
273
  description
300
274
  }));
301
- const filter = (eventType) => Object.keys(input.events).includes(eventType);
275
+ const filter = (eventType) => Object.keys(events).includes(eventType);
302
276
  const functionNameMapping = {};
303
277
  const toolTransitions = transitions.filter((t) => {
304
278
  return filter(t.eventType);
@@ -336,7 +310,7 @@ function getToolMap(_agent, input) {
336
310
  return toolMap;
337
311
  }
338
312
 
339
- // src/strategies/simple.ts
313
+ // src/strategies/simpleStrategy.ts
340
314
  var simpleStrategyPromptTemplate = (data) => {
341
315
  return `
342
316
  ${convertToXml(data)}
@@ -350,21 +324,13 @@ async function simpleStrategy(agent, input) {
350
324
  return void 0;
351
325
  }
352
326
  const prompt = simpleStrategyPromptTemplate({
353
- context: input.context,
327
+ stateValue: input.state.value,
328
+ context: input.context ?? input.state.context,
354
329
  goal: input.goal
355
330
  });
356
331
  const messages = await getMessages(agent, prompt, input);
357
332
  const model = input.model ? agent.wrap(input.model) : agent.model;
358
- const {
359
- state,
360
- context,
361
- machine,
362
- prevDecision,
363
- events,
364
- goal,
365
- model: _,
366
- ...rest
367
- } = input;
333
+ const { state, machine, events, goal, model: _, ...rest } = input;
368
334
  const machineState = input.machine && input.state ? input.machine.resolveState({
369
335
  ...input.state,
370
336
  context: input.state.context ?? {}
@@ -391,11 +357,12 @@ async function simpleStrategy(agent, input) {
391
357
  return void 0;
392
358
  }
393
359
  return {
360
+ id: randomId(),
394
361
  strategy: "simple",
395
362
  goal: input.goal,
396
363
  goalState: input.state,
397
364
  nextEvent: singleResult.result,
398
- episodeId: agent.episodeId,
365
+ episodeId: input.episodeId ?? agent.episodeId,
399
366
  timestamp: Date.now(),
400
367
  paths: [
401
368
  {
@@ -552,7 +519,6 @@ function createAgent({
552
519
  });
553
520
  }
554
521
  var Agent = class extends import_xstate4.Actor {
555
- // todo
556
522
  constructor({
557
523
  logic = agentLogic,
558
524
  id,
@@ -609,9 +575,10 @@ var Agent = class extends import_xstate4.Actor {
609
575
  addFeedback(feedbackInput) {
610
576
  const feedback = {
611
577
  ...feedbackInput,
578
+ comment: feedbackInput.comment ?? void 0,
612
579
  attributes: { ...feedbackInput.attributes },
613
580
  timestamp: feedbackInput.timestamp ?? Date.now(),
614
- episodeId: this.episodeId
581
+ episodeId: feedbackInput.episodeId ?? this.episodeId
615
582
  };
616
583
  this.send({
617
584
  type: "agent.feedback",
@@ -632,9 +599,12 @@ var Agent = class extends import_xstate4.Actor {
632
599
  event,
633
600
  state,
634
601
  id: observationInput.id ?? randomId(),
635
- episodeId: this.episodeId,
602
+ episodeId: observationInput.episodeId ?? this.episodeId,
636
603
  timestamp: observationInput.timestamp ?? Date.now(),
637
- machineHash: observationInput.machine ? getMachineHash(observationInput.machine) : void 0
604
+ decisionId: observationInput.decisionId
605
+ // machineHash: observationInput.machine
606
+ // ? getMachineHash(observationInput.machine)
607
+ // : undefined,
638
608
  };
639
609
  this.send({
640
610
  type: "agent.observe",
@@ -668,15 +638,16 @@ var Agent = class extends import_xstate4.Actor {
668
638
  const agent = this;
669
639
  async function handleObservation(observationInput) {
670
640
  const observation = agent.addObservation(observationInput);
671
- const input = getInput?.(observation);
672
- if (input) {
673
- const res = await agentDecide(agent, {
641
+ const interactInput = getInput?.(observation);
642
+ if (interactInput) {
643
+ const decision = await agentDecide(agent, {
674
644
  machine,
675
645
  state: observation.state,
676
- ...input
646
+ ...interactInput
677
647
  });
678
- if (res?.nextEvent) {
679
- actorRef.send(res.nextEvent);
648
+ if (decision?.nextEvent) {
649
+ decision.nextEvent["_decision"] = decision.id;
650
+ actorRef.send(decision.nextEvent);
680
651
  }
681
652
  }
682
653
  prevState = observationInput.state;
@@ -686,21 +657,24 @@ var Agent = class extends import_xstate4.Actor {
686
657
  if (!subscribed || inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
687
658
  return;
688
659
  }
660
+ const decisionId = inspEvent.event["_decision"];
661
+ const decision = decisionId ? agent.getDecisions().find((d) => d.id === decisionId) : void 0;
689
662
  const observationInput = {
690
663
  event: inspEvent.event,
691
664
  prevState,
692
665
  state: inspEvent.snapshot,
693
- machine: actorRef.src
666
+ goal: decision?.goal,
667
+ decisionId
694
668
  };
695
669
  await handleObservation(observationInput);
696
670
  }
697
671
  }) : void 0;
698
672
  if (actorRef._processingStatus === 1) {
699
673
  handleObservation({
674
+ decisionId: void 0,
700
675
  prevState: void 0,
701
676
  event: void 0,
702
- state: actorRef.getSnapshot(),
703
- machine: actorRef.src
677
+ state: actorRef.getSnapshot()
704
678
  });
705
679
  }
706
680
  return {
@@ -718,11 +692,14 @@ var Agent = class extends import_xstate4.Actor {
718
692
  if (inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
719
693
  return;
720
694
  }
695
+ const decisionId = inspEvent.event["_decision"];
696
+ const decision = decisionId ? this.getDecisions().find((d) => d.id === decisionId) : void 0;
721
697
  const observationInput = {
698
+ decisionId,
722
699
  event: inspEvent.event,
723
700
  prevState,
724
701
  state: inspEvent.snapshot,
725
- machine: actorRef.src
702
+ goal: decision?.goal
726
703
  };
727
704
  prevState = observationInput.state;
728
705
  this.addObservation(observationInput);
@@ -745,8 +722,8 @@ var Agent = class extends import_xstate4.Actor {
745
722
  * - The `machine` (e.g. a state machine) that specifies what can happen next
746
723
  * - Additional `context`
747
724
  */
748
- async decide(opts) {
749
- return agentDecide(this, opts);
725
+ async decide(input) {
726
+ return agentDecide(this, input);
750
727
  }
751
728
  };
752
729
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  fromTransition
5
5
  } from "xstate";
6
6
 
7
- // src/strategies/simple.ts
7
+ // src/strategies/simpleStrategy.ts
8
8
  import { generateText as generateText2 } from "ai";
9
9
 
10
10
  // src/utils.ts
@@ -24,22 +24,6 @@ function getAllTransitions(state) {
24
24
  }).flat(2);
25
25
  return transitions;
26
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
- }
41
- return transitions;
42
- }
43
27
  function wrapInXml(tagName, content) {
44
28
  return `<${tagName}>${content}</${tagName}>`;
45
29
  }
@@ -57,14 +41,6 @@ function randomId(prefix) {
57
41
  const random = Math.random().toString(36).substring(2, 9);
58
42
  return `${prefix || ""}${timestamp}${random}`;
59
43
  }
60
- var machineHashes = /* @__PURE__ */ new WeakMap();
61
- function getMachineHash(machine) {
62
- if (machineHashes.has(machine)) return machineHashes.get(machine);
63
- const transitions = getAllMachineTransitions(machine.root);
64
- const machineHash = hash(transitions);
65
- machineHashes.set(machine, machineHash);
66
- return machineHash;
67
- }
68
44
  function isActorRef(actorRefLike) {
69
45
  return "src" in actorRefLike && "system" in actorRefLike && "sessionId" in actorRefLike;
70
46
  }
@@ -83,7 +59,7 @@ function isMachineActor(actor) {
83
59
  return "src" in actor && typeof actor.src === "object" && actor.src !== null && "definition" in actor.src;
84
60
  }
85
61
 
86
- // src/strategies/simple.ts
62
+ // src/strategies/simpleStrategy.ts
87
63
  import { getNextSnapshot } from "xstate";
88
64
 
89
65
  // src/text.ts
@@ -95,6 +71,7 @@ import {
95
71
  // src/templates/defaultText.ts
96
72
  var defaultTextTemplate = (data) => {
97
73
  const preamble = [
74
+ data.stateValue ? wrapInXml("stateValue", JSON.stringify(data.stateValue)) : void 0,
98
75
  data.context ? wrapInXml("context", JSON.stringify(data.context)) : void 0
99
76
  ].filter(Boolean).join("\n");
100
77
  return `
@@ -166,7 +143,6 @@ function fromTextStream(agent, options) {
166
143
  }
167
144
  function fromText(agent, options) {
168
145
  const resolvedOptions = {
169
- ...agent.defaultOptions,
170
146
  ...options
171
147
  };
172
148
  const template = resolvedOptions.template ?? defaultTextTemplate;
@@ -192,10 +168,7 @@ function fromText(agent, options) {
192
168
  import { fromPromise as fromPromise2 } from "xstate";
193
169
  import { tool } from "ai";
194
170
  async function agentDecide(agent, options) {
195
- const resolvedOptions = {
196
- ...agent.defaultOptions,
197
- ...options
198
- };
171
+ const resolvedOptions = options;
199
172
  const {
200
173
  strategy = agent.strategy,
201
174
  goal,
@@ -205,6 +178,8 @@ async function agentDecide(agent, options) {
205
178
  machine,
206
179
  model = agent.model,
207
180
  messages,
181
+ episodeId = agent.episodeId,
182
+ maxAttempts = 2,
208
183
  ...otherDecideInput
209
184
  } = resolvedOptions;
210
185
  const filteredEventSchemas = allowedEvents ? Object.fromEntries(
@@ -213,14 +188,18 @@ async function agentDecide(agent, options) {
213
188
  })
214
189
  ) : events;
215
190
  let attempts = 0;
216
- const maxAttempts = resolvedOptions.maxAttempts ?? 2;
217
191
  let decision;
192
+ const minimalState = {
193
+ value: state.value,
194
+ context: state.context
195
+ };
218
196
  while (attempts++ < maxAttempts) {
219
197
  decision = await strategy(agent, {
198
+ episodeId,
220
199
  model,
221
200
  goal,
222
201
  events: filteredEventSchemas,
223
- state,
202
+ state: minimalState,
224
203
  machine,
225
204
  messages,
226
205
  // TODO: fix UIMessage thing
@@ -228,7 +207,6 @@ async function agentDecide(agent, options) {
228
207
  });
229
208
  if (decision?.nextEvent) {
230
209
  agent.addDecision(decision);
231
- await resolvedOptions.execute?.(decision.nextEvent);
232
210
  break;
233
211
  }
234
212
  }
@@ -246,30 +224,26 @@ function fromDecision(agent, defaultInput) {
246
224
  ...defaultInput,
247
225
  ...inputObject
248
226
  };
249
- const state = {
250
- value: snapshot.value,
251
- context: resolvedInput.context
252
- };
253
227
  const decision = await agentDecide(agent, {
254
228
  machine: parentRef.logic,
255
229
  state: snapshot,
256
- context: resolvedInput.context,
257
- execute: async (event) => {
258
- parentRef.send(event);
259
- },
260
230
  ...resolvedInput,
261
231
  // @ts-ignore
262
232
  messages: resolvedInput.messages
263
233
  });
234
+ if (decision?.nextEvent) {
235
+ parentRef.send(decision.nextEvent);
236
+ }
264
237
  return decision;
265
238
  });
266
239
  }
267
- function getToolMap(_agent, input) {
268
- const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(input.events).map(([eventType, { description }]) => ({
240
+ function getToolMap(agent, input) {
241
+ const events = input.events ?? agent.events;
242
+ const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(events).map(([eventType, { description }]) => ({
269
243
  eventType,
270
244
  description
271
245
  }));
272
- const filter = (eventType) => Object.keys(input.events).includes(eventType);
246
+ const filter = (eventType) => Object.keys(events).includes(eventType);
273
247
  const functionNameMapping = {};
274
248
  const toolTransitions = transitions.filter((t) => {
275
249
  return filter(t.eventType);
@@ -307,7 +281,7 @@ function getToolMap(_agent, input) {
307
281
  return toolMap;
308
282
  }
309
283
 
310
- // src/strategies/simple.ts
284
+ // src/strategies/simpleStrategy.ts
311
285
  var simpleStrategyPromptTemplate = (data) => {
312
286
  return `
313
287
  ${convertToXml(data)}
@@ -321,21 +295,13 @@ async function simpleStrategy(agent, input) {
321
295
  return void 0;
322
296
  }
323
297
  const prompt = simpleStrategyPromptTemplate({
324
- context: input.context,
298
+ stateValue: input.state.value,
299
+ context: input.context ?? input.state.context,
325
300
  goal: input.goal
326
301
  });
327
302
  const messages = await getMessages(agent, prompt, input);
328
303
  const model = input.model ? agent.wrap(input.model) : agent.model;
329
- const {
330
- state,
331
- context,
332
- machine,
333
- prevDecision,
334
- events,
335
- goal,
336
- model: _,
337
- ...rest
338
- } = input;
304
+ const { state, machine, events, goal, model: _, ...rest } = input;
339
305
  const machineState = input.machine && input.state ? input.machine.resolveState({
340
306
  ...input.state,
341
307
  context: input.state.context ?? {}
@@ -362,11 +328,12 @@ async function simpleStrategy(agent, input) {
362
328
  return void 0;
363
329
  }
364
330
  return {
331
+ id: randomId(),
365
332
  strategy: "simple",
366
333
  goal: input.goal,
367
334
  goalState: input.state,
368
335
  nextEvent: singleResult.result,
369
- episodeId: agent.episodeId,
336
+ episodeId: input.episodeId ?? agent.episodeId,
370
337
  timestamp: Date.now(),
371
338
  paths: [
372
339
  {
@@ -525,7 +492,6 @@ function createAgent({
525
492
  });
526
493
  }
527
494
  var Agent = class extends Actor {
528
- // todo
529
495
  constructor({
530
496
  logic = agentLogic,
531
497
  id,
@@ -582,9 +548,10 @@ var Agent = class extends Actor {
582
548
  addFeedback(feedbackInput) {
583
549
  const feedback = {
584
550
  ...feedbackInput,
551
+ comment: feedbackInput.comment ?? void 0,
585
552
  attributes: { ...feedbackInput.attributes },
586
553
  timestamp: feedbackInput.timestamp ?? Date.now(),
587
- episodeId: this.episodeId
554
+ episodeId: feedbackInput.episodeId ?? this.episodeId
588
555
  };
589
556
  this.send({
590
557
  type: "agent.feedback",
@@ -605,9 +572,12 @@ var Agent = class extends Actor {
605
572
  event,
606
573
  state,
607
574
  id: observationInput.id ?? randomId(),
608
- episodeId: this.episodeId,
575
+ episodeId: observationInput.episodeId ?? this.episodeId,
609
576
  timestamp: observationInput.timestamp ?? Date.now(),
610
- machineHash: observationInput.machine ? getMachineHash(observationInput.machine) : void 0
577
+ decisionId: observationInput.decisionId
578
+ // machineHash: observationInput.machine
579
+ // ? getMachineHash(observationInput.machine)
580
+ // : undefined,
611
581
  };
612
582
  this.send({
613
583
  type: "agent.observe",
@@ -641,15 +611,16 @@ var Agent = class extends Actor {
641
611
  const agent = this;
642
612
  async function handleObservation(observationInput) {
643
613
  const observation = agent.addObservation(observationInput);
644
- const input = getInput?.(observation);
645
- if (input) {
646
- const res = await agentDecide(agent, {
614
+ const interactInput = getInput?.(observation);
615
+ if (interactInput) {
616
+ const decision = await agentDecide(agent, {
647
617
  machine,
648
618
  state: observation.state,
649
- ...input
619
+ ...interactInput
650
620
  });
651
- if (res?.nextEvent) {
652
- actorRef.send(res.nextEvent);
621
+ if (decision?.nextEvent) {
622
+ decision.nextEvent["_decision"] = decision.id;
623
+ actorRef.send(decision.nextEvent);
653
624
  }
654
625
  }
655
626
  prevState = observationInput.state;
@@ -659,21 +630,24 @@ var Agent = class extends Actor {
659
630
  if (!subscribed || inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
660
631
  return;
661
632
  }
633
+ const decisionId = inspEvent.event["_decision"];
634
+ const decision = decisionId ? agent.getDecisions().find((d) => d.id === decisionId) : void 0;
662
635
  const observationInput = {
663
636
  event: inspEvent.event,
664
637
  prevState,
665
638
  state: inspEvent.snapshot,
666
- machine: actorRef.src
639
+ goal: decision?.goal,
640
+ decisionId
667
641
  };
668
642
  await handleObservation(observationInput);
669
643
  }
670
644
  }) : void 0;
671
645
  if (actorRef._processingStatus === 1) {
672
646
  handleObservation({
647
+ decisionId: void 0,
673
648
  prevState: void 0,
674
649
  event: void 0,
675
- state: actorRef.getSnapshot(),
676
- machine: actorRef.src
650
+ state: actorRef.getSnapshot()
677
651
  });
678
652
  }
679
653
  return {
@@ -691,11 +665,14 @@ var Agent = class extends Actor {
691
665
  if (inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
692
666
  return;
693
667
  }
668
+ const decisionId = inspEvent.event["_decision"];
669
+ const decision = decisionId ? this.getDecisions().find((d) => d.id === decisionId) : void 0;
694
670
  const observationInput = {
671
+ decisionId,
695
672
  event: inspEvent.event,
696
673
  prevState,
697
674
  state: inspEvent.snapshot,
698
- machine: actorRef.src
675
+ goal: decision?.goal
699
676
  };
700
677
  prevState = observationInput.state;
701
678
  this.addObservation(observationInput);
@@ -718,8 +695,8 @@ var Agent = class extends Actor {
718
695
  * - The `machine` (e.g. a state machine) that specifies what can happen next
719
696
  * - Additional `context`
720
697
  */
721
- async decide(opts) {
722
- return agentDecide(this, opts);
698
+ async decide(input) {
699
+ return agentDecide(this, input);
723
700
  }
724
701
  };
725
702
  export {