@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/src/types.ts CHANGED
@@ -27,21 +27,25 @@ export type GenerateTextOptions = Parameters<typeof generateText>[0];
27
27
 
28
28
  export type StreamTextOptions = Parameters<typeof streamText>[0];
29
29
 
30
- export type CostFunction<TEvent extends EventObject> = (
31
- path: AgentPath<TEvent>
30
+ export type CostFunction<TAgent extends AnyAgent> = (
31
+ path: AgentPath<TAgent>
32
32
  ) => number;
33
33
 
34
- export type AgentPlanInput<TEvent extends EventObject> = Omit<
35
- AgentGenerateTextOptions,
34
+ export type AgentDecideInput<TAgent extends AnyAgent> = Omit<
35
+ AgentGenerateTextOptions<TAgent>,
36
36
  'prompt' | 'tools'
37
37
  > & {
38
38
  /**
39
39
  * The currently observed state.
40
40
  */
41
- state: ObservedState;
41
+ state: ObservedState<TAgent>;
42
+ /**
43
+ * The context to provide in the prompt to the agent. This overrides the `state.context`.
44
+ */
45
+ context?: Record<string, any>;
42
46
  /**
43
47
  * The goal for the agent to accomplish.
44
- * The agent will create a plan based on this goal.
48
+ * The agent will make a decision based on this goal.
45
49
  */
46
50
  goal: string;
47
51
  /**
@@ -54,58 +58,55 @@ export type AgentPlanInput<TEvent extends EventObject> = Omit<
54
58
  * is interacting with.
55
59
  */
56
60
  machine?: AnyStateMachine;
57
- /**
58
- * The previous plan.
59
- */
60
- previousPlan?: AgentPlan<TEvent>;
61
61
 
62
62
  /**
63
63
  * The total cost of the path to the goal state.
64
64
  */
65
- costFunction?: CostFunction<TEvent>;
65
+ costFunction?: CostFunction<TAgent>;
66
66
 
67
67
  /**
68
- * The maximum number of attempts to generate a plan.
68
+ * The maximum number of attempts to make a decision.
69
69
  * Defaults to 2.
70
70
  */
71
71
  maxAttempts?: number;
72
72
  };
73
73
 
74
- export type AgentStep<TEvent extends EventObject> = {
74
+ export type AgentStep<TAgent extends AnyAgent> = {
75
75
  /** The event to take */
76
- event: TEvent;
76
+ event: EventFromAgent<TAgent>;
77
77
  /** The next expected state after taking the event */
78
- state: ObservedState | undefined;
78
+ state: ObservedState<TAgent> | undefined;
79
79
  };
80
80
 
81
- export type AgentPath<TEvent extends EventObject> = {
81
+ export type AgentPath<TAgent extends AnyAgent> = {
82
82
  /** The expected ending state of the path */
83
- state: ObservedState | undefined;
83
+ state: ObservedState<TAgent> | undefined;
84
84
  /** The steps to reach the ending state */
85
- steps: Array<AgentStep<TEvent>>;
85
+ steps: Array<AgentStep<TAgent>>;
86
86
  weight?: number;
87
87
  };
88
88
 
89
- export type AgentPlan<TEvent extends EventObject> = {
89
+ export type AgentDecision<TAgent extends AnyAgent> = {
90
+ id: string;
90
91
  /**
91
- * The planner used to generate the plan
92
+ * The strategy used to generate the decision
92
93
  */
93
- planner: string;
94
+ strategy: string;
94
95
  goal: string;
95
96
  /**
96
- * The ending state of the plan.
97
+ * The ending state of the decision.
97
98
  */
98
- goalState: ObservedState | undefined;
99
+ goalState: ObservedState<TAgent> | undefined;
99
100
  /**
100
101
  * The next event that the agent decided needs to occur to achieve the `goal`.
101
102
  *
102
103
  * This next event is chosen from the
103
104
  */
104
- nextEvent: TEvent | undefined;
105
+ nextEvent: EventFromAgent<TAgent> | undefined;
105
106
  /**
106
107
  * The paths that the agent can take to achieve the goal.
107
108
  */
108
- paths: AgentPath<TEvent>[];
109
+ paths: AgentPath<TAgent>[];
109
110
  episodeId: string;
110
111
  timestamp: number;
111
112
  // result: GenerateObjectResult<any>;
@@ -118,17 +119,13 @@ export interface TransitionData {
118
119
  target?: any;
119
120
  }
120
121
 
121
- export type PromptTemplate<TEvents extends EventObject> = (data: {
122
+ export type PromptTemplate<TAgent extends AnyAgent> = (data: {
122
123
  goal: string;
123
124
  /**
124
125
  * The observed state
125
126
  */
126
- state?: ObservedState;
127
- /**
128
- * The context to provide.
129
- * This overrides the observed state.context, if provided.
130
- */
131
- context?: any;
127
+ stateValue?: any;
128
+ context?: Record<string, any>;
132
129
  /**
133
130
  * The state machine model of the observed environment
134
131
  */
@@ -144,22 +141,34 @@ export type PromptTemplate<TEvents extends EventObject> = (data: {
144
141
  observations?: AgentObservation<any>[]; // TODO
145
142
  feedback?: AgentFeedback[];
146
143
  messages?: AgentMessage[];
147
- plans?: AgentPlan<TEvents>[];
144
+ decisions?: AgentDecision<TAgent>[];
148
145
  }) => string;
149
146
 
150
- export type AgentPlanner<T extends AnyAgent> = (
151
- agent: T,
152
- input: AgentPlanInput<T['types']['events']>
153
- ) => Promise<AgentPlan<T['types']['events']> | undefined>;
147
+ export type AgentStrategy<TAgent extends AnyAgent> = (
148
+ agent: TAgent,
149
+ input: AgentDecideInput<EventFromAgent<TAgent>>
150
+ ) => Promise<AgentDecision<TAgent> | undefined>;
151
+
152
+ export type AgentInteractInput<T extends AnyAgent> = Omit<
153
+ AgentDecideOptions<T>,
154
+ 'state'
155
+ > & {
156
+ state?: never;
157
+ };
154
158
 
155
- export type AgentDecideOptions<T extends AnyAgent> = {
159
+ export type AgentDecideOptions<TAgent extends AnyAgent> = {
156
160
  goal: string;
157
- model?: LanguageModel;
158
- state: ObservedState;
161
+ state: ObservedState<TAgent>;
162
+ /**
163
+ * The context to provide in the prompt to the agent. This overrides the `state.context`.
164
+ */
165
+ context?: Record<string, any>;
159
166
  machine?: AnyStateMachine;
167
+ model?: LanguageModel;
160
168
  execute?: (event: AnyEventObject) => Promise<void>;
161
- planner?: AgentPlanner<T>;
169
+ strategy?: AgentStrategy<TAgent>;
162
170
  events?: ZodEventMapping;
171
+ allowedEvents?: Array<EventFromAgent<TAgent>['type']>;
163
172
  /**
164
173
  * The maximum number of times the agent will attempt to make a decision.
165
174
  * Defaults to 2.
@@ -168,23 +177,23 @@ export type AgentDecideOptions<T extends AnyAgent> = {
168
177
  } & Omit<Parameters<typeof generateText>[0], 'model' | 'tools' | 'prompt'>;
169
178
 
170
179
  export interface AgentFeedback {
171
- goal?: string;
172
- observationId?: string;
180
+ observationId: string;
181
+ score: number;
182
+ comment: string | undefined;
173
183
  /**
174
184
  * The message correlation that the feedback is relevant for
175
185
  */
176
186
  attributes: Record<string, any>;
177
- reward: number;
178
187
  timestamp: number;
179
188
  episodeId: string;
180
189
  }
181
190
 
182
191
  export interface AgentFeedbackInput {
183
- goal?: string;
184
- observationId?: string;
192
+ observationId: string;
193
+ score: number;
194
+ comment?: string;
185
195
  attributes?: Record<string, any>;
186
196
  timestamp?: number;
187
- reward?: number;
188
197
  }
189
198
 
190
199
  export type AgentMessage = CoreMessage & {
@@ -327,6 +336,7 @@ export type AgentMessageInput = CoreMessage & {
327
336
 
328
337
  export interface AgentObservation<TActor extends ActorRefLike> {
329
338
  id: string;
339
+ goal?: string;
330
340
  prevState: SnapshotFrom<TActor> | undefined;
331
341
  event: EventFrom<TActor> | undefined;
332
342
  state: SnapshotFrom<TActor>;
@@ -335,13 +345,14 @@ export interface AgentObservation<TActor extends ActorRefLike> {
335
345
  timestamp: number;
336
346
  }
337
347
 
338
- export interface AgentObservationInput {
348
+ export interface AgentObservationInput<TAgent extends AnyAgent> {
339
349
  id?: string;
340
- prevState?: ObservedState;
350
+ prevState?: ObservedState<TAgent>;
341
351
  event?: AnyEventObject;
342
- state: ObservedState;
352
+ state: ObservedState<TAgent>;
343
353
  machine?: AnyStateMachine;
344
354
  timestamp?: number;
355
+ goal: string | undefined;
345
356
  }
346
357
 
347
358
  export type AgentDecisionInput = {
@@ -350,12 +361,12 @@ export type AgentDecisionInput = {
350
361
  context?: Record<string, any>;
351
362
  } & Omit<Parameters<typeof generateText>[0], 'model' | 'tools' | 'prompt'>;
352
363
 
353
- export type AgentDecisionLogic<TEvents extends EventObject> = PromiseActorLogic<
354
- AgentPlan<TEvents> | undefined,
364
+ export type AgentDecisionLogic<TAgent extends AnyAgent> = PromiseActorLogic<
365
+ AgentDecision<TAgent> | undefined,
355
366
  AgentDecisionInput | string
356
367
  >;
357
368
 
358
- export type AgentEmitted<TEvents extends EventObject> =
369
+ export type AgentEmitted<TAgent extends AnyAgent> =
359
370
  | {
360
371
  type: 'feedback';
361
372
  feedback: AgentFeedback;
@@ -369,12 +380,12 @@ export type AgentEmitted<TEvents extends EventObject> =
369
380
  message: AgentMessage;
370
381
  }
371
382
  | {
372
- type: 'plan';
373
- plan: AgentPlan<TEvents>;
383
+ type: 'decision';
384
+ decision: AgentDecision<TAgent>;
374
385
  };
375
386
 
376
- export type AgentLogic<TEvents extends EventObject> = ActorLogic<
377
- TransitionSnapshot<AgentMemoryContext>,
387
+ export type AgentLogic<TAgent extends AnyAgent> = ActorLogic<
388
+ TransitionSnapshot<AgentMemoryContext<TAgent>>,
378
389
  | {
379
390
  type: 'agent.feedback';
380
391
  feedback: AgentFeedback;
@@ -388,20 +399,22 @@ export type AgentLogic<TEvents extends EventObject> = ActorLogic<
388
399
  message: AgentMessage;
389
400
  }
390
401
  | {
391
- type: 'agent.plan';
392
- plan: AgentPlan<TEvents>;
402
+ type: 'agent.decision';
403
+ decision: AgentDecision<TAgent>;
393
404
  },
394
405
  any, // TODO: input
395
406
  any,
396
- AgentEmitted<TEvents>
407
+ AgentEmitted<TAgent>
397
408
  >;
398
409
 
399
410
  export type EventsFromZodEventMapping<TEventSchemas extends ZodEventMapping> =
400
- Values<{
401
- [K in keyof TEventSchemas & string]: {
402
- type: K;
403
- } & TypeOf<TEventSchemas[K]>;
404
- }>;
411
+ Compute<
412
+ Values<{
413
+ [K in keyof TEventSchemas & string]: {
414
+ type: K;
415
+ } & TypeOf<TEventSchemas[K]>;
416
+ }>
417
+ >;
405
418
 
406
419
  export type ContextFromZodContextMapping<
407
420
  TContextSchema extends ZodContextMapping
@@ -413,27 +426,27 @@ export type AnyAgent = Agent<any, any, any, any>;
413
426
 
414
427
  export type FromAgent<T> = T | ((agent: AnyAgent) => T | Promise<T>);
415
428
 
416
- export type CommonTextOptions = {
429
+ export type CommonTextOptions<TAgent extends AnyAgent> = {
417
430
  prompt: FromAgent<string>;
418
431
  model?: LanguageModel;
419
- context?: Record<string, any>;
420
432
  messages?: FromAgent<CoreMessage[]>;
421
433
  template?: PromptTemplate<any>;
434
+ context?: Record<string, any>;
422
435
  };
423
436
 
424
- export type AgentGenerateTextOptions = Omit<
437
+ export type AgentGenerateTextOptions<TAgent extends AnyAgent> = Omit<
425
438
  GenerateTextOptions,
426
439
  'model' | 'prompt' | 'messages'
427
440
  > &
428
- CommonTextOptions;
441
+ CommonTextOptions<TAgent>;
429
442
 
430
- export type AgentStreamTextOptions = Omit<
443
+ export type AgentStreamTextOptions<TAgent extends AnyAgent> = Omit<
431
444
  StreamTextOptions,
432
445
  'model' | 'prompt' | 'messages'
433
446
  > &
434
- CommonTextOptions;
447
+ CommonTextOptions<TAgent>;
435
448
 
436
- export interface ObservedState {
449
+ export interface ObservedState<TAgent extends AnyAgent> {
437
450
  /**
438
451
  * The current state value of the state machine, e.g.
439
452
  * `"loading"` or `"processing"` or `"ready"`
@@ -442,7 +455,7 @@ export interface ObservedState {
442
455
  /**
443
456
  * Additional contextual data related to the current state
444
457
  */
445
- context?: Record<string, unknown>;
458
+ context?: ContextFromAgent<TAgent>;
446
459
  }
447
460
 
448
461
  export type ObservedStateFrom<TActor extends ActorRefLike> = Pick<
@@ -450,25 +463,53 @@ export type ObservedStateFrom<TActor extends ActorRefLike> = Pick<
450
463
  'value' | 'context'
451
464
  >;
452
465
 
453
- export type AgentMemoryContext = {
454
- observations: AgentObservation<any>[]; // TODO
466
+ export type AgentMemoryContext<TAgent extends AnyAgent> = {
467
+ observations: AgentObservation<TAgent>[]; // TODO
455
468
  messages: AgentMessage[];
456
- plans: AgentPlan<any>[];
469
+ decisions: AgentDecision<TAgent>[];
457
470
  feedback: AgentFeedback[];
458
471
  };
459
472
 
460
- export interface AgentLongTermMemory {
461
- get<K extends keyof AgentMemoryContext>(
473
+ export interface AgentLongTermMemory<TAgent extends AnyAgent> {
474
+ get<K extends keyof AgentMemoryContext<TAgent>>(
462
475
  key: K
463
- ): Promise<AgentMemoryContext[K]>;
464
- append<K extends keyof AgentMemoryContext>(
476
+ ): Promise<AgentMemoryContext<TAgent>[K]>;
477
+ append<K extends keyof AgentMemoryContext<TAgent>>(
465
478
  key: K,
466
- item: AgentMemoryContext[K][0]
479
+ item: AgentMemoryContext<TAgent>[K][0]
467
480
  ): Promise<void>;
468
- set<K extends keyof AgentMemoryContext>(
481
+ set<K extends keyof AgentMemoryContext<TAgent>>(
469
482
  key: K,
470
- items: AgentMemoryContext[K]
483
+ items: AgentMemoryContext<TAgent>[K]
471
484
  ): Promise<void>;
472
485
  }
473
486
 
474
487
  export type Compute<A extends any> = { [K in keyof A]: A[K] } & unknown;
488
+
489
+ export type MaybePromise<T> = T | Promise<T>;
490
+
491
+ export type EventFromAgent<T extends AnyAgent> = T extends Agent<
492
+ infer _,
493
+ infer __,
494
+ infer TEvents,
495
+ infer ___
496
+ >
497
+ ? TEvents
498
+ : never;
499
+
500
+ export type TypesFromAgent<T extends AnyAgent> = T extends Agent<
501
+ infer TContextSchema,
502
+ infer TEventSchema
503
+ >
504
+ ? {
505
+ context: ContextFromZodContextMapping<TContextSchema>;
506
+ events: EventsFromZodEventMapping<TEventSchema>;
507
+ }
508
+ : never;
509
+
510
+ export type ContextFromAgent<T extends AnyAgent> = T extends Agent<
511
+ infer TContextSchema,
512
+ infer _TEventSchema
513
+ >
514
+ ? ContextFromZodContextMapping<TContextSchema>
515
+ : never;
package/src/utils.ts CHANGED
@@ -59,6 +59,18 @@ export function wrapInXml(tagName: string, content: string): string {
59
59
  return `<${tagName}>${content}</${tagName}>`;
60
60
  }
61
61
 
62
+ export function convertToXml(obj: Record<string, any>): string {
63
+ return Object.entries(obj)
64
+ .map(([key, value]) => {
65
+ if (typeof value === 'object' && value !== null) {
66
+ return wrapInXml(key, convertToXml(value));
67
+ } else {
68
+ return wrapInXml(key, value);
69
+ }
70
+ })
71
+ .join('');
72
+ }
73
+
62
74
  export function randomId(prefix?: string): string {
63
75
  const timestamp = Date.now().toString(36);
64
76
  const random = Math.random().toString(36).substring(2, 9);
@@ -89,7 +101,7 @@ export function isActorRef(
89
101
  }
90
102
 
91
103
  export function getTransitions(
92
- state: ObservedState,
104
+ state: ObservedState<any>,
93
105
  machine: AnyStateMachine
94
106
  ): TransitionData[] {
95
107
  if (!machine) {
@@ -1,177 +0,0 @@
1
- import { generateObject } from 'ai';
2
- import {
3
- AgentPlan,
4
- AgentPlanInput,
5
- AgentPlanner,
6
- AgentStep,
7
- AnyAgent,
8
- CostFunction,
9
- ObservedState,
10
- } from '../types';
11
- import { getShortestPaths } from '@xstate/graph';
12
- import { z } from 'zod';
13
- import { zodToJsonSchema } from 'zod-to-json-schema';
14
- import Ajv from 'ajv';
15
- import { AnyMachineSnapshot } from 'xstate';
16
-
17
- const ajv = new Ajv();
18
-
19
- function observedStatesEqual(state1: ObservedState, state2: ObservedState) {
20
- // check state value && state context
21
- return (
22
- JSON.stringify(state1.value) === JSON.stringify(state2.value) &&
23
- JSON.stringify(state1.context) === JSON.stringify(state2.context)
24
- );
25
- }
26
-
27
- function trimSteps(steps: AgentStep<any>[], currentState: ObservedState) {
28
- const index = steps.findIndex(
29
- (step) => step.state && observedStatesEqual(step.state, currentState)
30
- );
31
-
32
- if (index === -1) {
33
- return undefined;
34
- }
35
-
36
- return steps.slice(index + 1, steps.length);
37
- }
38
-
39
- export function experimental_createShortestPathPlanner<
40
- T extends AnyAgent
41
- >(): AgentPlanner<T> {
42
- return async function shortestPathPlanner<T extends AnyAgent>(
43
- agent: T,
44
- input: AgentPlanInput<any>
45
- ): Promise<AgentPlan<any> | undefined> {
46
- const costFunction: CostFunction<any> =
47
- input.costFunction ?? ((path) => path.weight ?? Infinity);
48
- const existingPlan = agent
49
- .getPlans()
50
- .find((p) => p.planner === 'shortestPath' && p.goal === input.goal);
51
-
52
- let paths = existingPlan?.paths;
53
-
54
- if (existingPlan) {
55
- console.log('Existing plan found');
56
- }
57
-
58
- if (!input.machine && !existingPlan) {
59
- return;
60
- }
61
-
62
- if (input.machine && !existingPlan) {
63
- const contextSchema = zodToJsonSchema(z.object(agent.context));
64
- const result = await generateObject({
65
- model: agent.model,
66
- system: input.system ?? agent.description,
67
- prompt: `
68
- <goal>
69
- ${input.goal}
70
- </goal>
71
- <contextSchema>
72
- ${contextSchema}
73
- </contextSchema>
74
-
75
-
76
- Update the context JSON schema so that it validates the context to determine that it reaches the goal. Return the result as a diff.
77
-
78
- The contextSchema properties must not change. Do not add or remove properties, or modify the name of the properties.
79
- Use "const" for exact required values and define ranges/types for flexible conditions.
80
-
81
- Examples:
82
- 1. For "user is logged in with admin role":
83
- {
84
- "contextSchema": "{"type": "object", "properties": {"role": {"const": "admin"}, "lastLogin": {"type": "string"}}, "required": ["role"]}"
85
- }
86
-
87
- 2. For "score is above 100":
88
- {
89
- "contextSchema": "{"type": "object", "properties": {"score": {"type": "number", "minimum": 100}}, "required": ["score"]}"
90
- }
91
-
92
- 3. For "fruits contain apple, orange, banana":
93
- {
94
- "type": "array",
95
- "allOf": [
96
- { "contains": { "const": "apple" } },
97
- { "contains": { "const": "orange" } },
98
- { "contains": { "const": "banana" } }
99
- ]
100
- }
101
- `.trim(),
102
- schema: z.object({
103
- // valueSchema: z
104
- // .string()
105
- // .describe('The JSON Schema representing the goal state value'),
106
- contextSchema: z
107
- .object({
108
- type: z.literal('object'),
109
- properties: z.object(
110
- Object.keys((contextSchema as any).properties).reduce(
111
- (acc, key) => {
112
- acc[key] = z.any();
113
- return acc;
114
- },
115
- {} as any
116
- )
117
- ),
118
- required: z.array(z.string()).optional(),
119
- })
120
- .describe('The JSON Schema representing the goal state context'),
121
- }),
122
- });
123
-
124
- console.log(result.object);
125
- const validateContext = ajv.compile(result.object.contextSchema);
126
-
127
- const stateFilter = (state: AnyMachineSnapshot) => {
128
- return validateContext(state.context);
129
- };
130
-
131
- const resolvedState = input.machine.resolveState({
132
- ...input.state,
133
- context: input.state.context ?? {},
134
- });
135
-
136
- paths = getShortestPaths(input.machine, {
137
- fromState: resolvedState,
138
- toState: stateFilter,
139
- });
140
- }
141
-
142
- if (!paths) {
143
- return undefined;
144
- }
145
-
146
- const trimmedPaths = paths
147
- .map((path) => {
148
- const trimmedSteps = trimSteps(path.steps, input.state);
149
- if (!trimmedSteps) {
150
- return undefined;
151
- }
152
- return {
153
- ...path,
154
- steps: trimmedSteps,
155
- };
156
- })
157
- .filter((p): p is NonNullable<typeof p> => p !== undefined);
158
-
159
- // Sort paths from least weight to most weight
160
- const sortedPaths = trimmedPaths.sort(
161
- (a, b) => costFunction(a) - costFunction(b)
162
- );
163
-
164
- const leastWeightPath = sortedPaths[0];
165
- const nextStep = leastWeightPath?.steps[0];
166
-
167
- return {
168
- planner: 'shortestPath',
169
- episodeId: agent.episodeId,
170
- goal: input.goal,
171
- goalState: paths[0]?.state,
172
- nextEvent: nextStep?.event,
173
- paths,
174
- timestamp: Date.now(),
175
- };
176
- };
177
- }