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

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.
@@ -2,7 +2,6 @@ import { generateObject } from 'ai';
2
2
  import {
3
3
  AgentDecision,
4
4
  AgentDecideInput,
5
- AgentStrategy,
6
5
  AgentStep,
7
6
  AnyAgent,
8
7
  CostFunction,
@@ -40,15 +39,15 @@ function trimSteps(steps: AgentStep<any>[], currentState: ObservedState<any>) {
40
39
  return steps.slice(index + 1, steps.length);
41
40
  }
42
41
 
43
- export async function experimental_shortestPathStrategy<T extends AnyAgent>(
42
+ export async function experimental_shortestPathPolicy<T extends AnyAgent>(
44
43
  agent: T,
45
44
  input: AgentDecideInput<any>
46
45
  ): Promise<AgentDecision<any> | undefined> {
47
46
  const costFunction: CostFunction<any> =
48
47
  input.costFunction ?? ((path) => path.weight ?? Infinity);
49
- const existingDecision = agent
50
- .getDecisions()
51
- .find((p) => p.strategy === 'shortestPath' && p.goal === input.goal);
48
+ const existingDecision = input.decisions?.find(
49
+ (p) => p.policy === 'shortestPath' && p.goal === input.goal
50
+ );
52
51
 
53
52
  let paths = existingDecision?.paths;
54
53
 
@@ -167,11 +166,12 @@ Examples:
167
166
 
168
167
  return {
169
168
  id: randomId(),
170
- strategy: 'shortestPath',
169
+ decisionId: input.decisionId ?? null,
170
+ policy: 'shortestPath',
171
171
  episodeId: agent.episodeId,
172
172
  goal: input.goal,
173
- goalState: paths[0]?.state,
174
- nextEvent: nextStep?.event,
173
+ goalState: paths[0]?.state ?? null,
174
+ nextEvent: nextStep?.event ?? null,
175
175
  paths,
176
176
  timestamp: Date.now(),
177
177
  };
@@ -1,4 +1,4 @@
1
- import { CoreMessage, generateText } from 'ai';
1
+ import { CoreToolResult, generateText } from 'ai';
2
2
  import {
3
3
  AgentDecision,
4
4
  AgentDecideInput,
@@ -6,11 +6,11 @@ import {
6
6
  AnyAgent,
7
7
  } from '../types';
8
8
  import { convertToXml, randomId } from '../utils';
9
- import { getNextSnapshot } from 'xstate';
10
- import { getMessages } from '../text';
9
+ import { transition } from 'xstate';
10
+ import { combinePromptAndMessages } from '../text';
11
11
  import { getToolMap } from '../decide';
12
12
 
13
- const simpleStrategyPromptTemplate: PromptTemplate<any> = (data) => {
13
+ const toolPolicyPromptTemplate: PromptTemplate<any> = (data) => {
14
14
  return `
15
15
  ${convertToXml(data)}
16
16
 
@@ -18,10 +18,10 @@ Make at most one tool call to achieve the above goal. If the goal cannot be achi
18
18
  `.trim();
19
19
  };
20
20
 
21
- export async function simpleStrategy<T extends AnyAgent>(
22
- agent: T,
23
- input: AgentDecideInput<any>
24
- ): Promise<AgentDecision<any> | undefined> {
21
+ export async function toolPolicy<TAgent extends AnyAgent>(
22
+ agent: TAgent,
23
+ input: AgentDecideInput<TAgent>
24
+ ): Promise<AgentDecision<TAgent> | undefined> {
25
25
  const toolMap = getToolMap(agent, input);
26
26
 
27
27
  if (!toolMap) {
@@ -31,13 +31,13 @@ export async function simpleStrategy<T extends AnyAgent>(
31
31
 
32
32
  // Create a prompt with the given context and goal.
33
33
  // The template is used to ensure that a single tool call at most is made.
34
- const prompt = simpleStrategyPromptTemplate({
34
+ const prompt = toolPolicyPromptTemplate({
35
35
  stateValue: input.state.value,
36
36
  context: input.context ?? input.state.context,
37
37
  goal: input.goal,
38
38
  });
39
39
 
40
- const messages = await getMessages(agent, prompt, input);
40
+ const messages = combinePromptAndMessages(prompt, input.messages);
41
41
 
42
42
  const model = input.model ? agent.wrap(input.model) : agent.model;
43
43
 
@@ -56,21 +56,19 @@ export async function simpleStrategy<T extends AnyAgent>(
56
56
  system: input.system ?? agent.description,
57
57
  model,
58
58
  messages,
59
- tools: toolMap as any,
59
+ tools: toolMap,
60
60
  toolChoice: input.toolChoice ?? 'required',
61
61
  });
62
62
 
63
63
  result.response.messages.forEach((m) => {
64
- const message: CoreMessage = m;
65
-
66
- agent.addMessage({
67
- ...message,
68
- id: randomId(),
69
- timestamp: Date.now(),
70
- });
64
+ agent.addMessage(m);
71
65
  });
72
66
 
73
- const singleResult = result.toolResults[0];
67
+ const singleResult = result.toolResults[0] as unknown as CoreToolResult<
68
+ any,
69
+ any,
70
+ any
71
+ >;
74
72
 
75
73
  if (!singleResult) {
76
74
  // TODO: retries?
@@ -78,24 +76,27 @@ export async function simpleStrategy<T extends AnyAgent>(
78
76
  return undefined;
79
77
  }
80
78
 
79
+ const nextEvent = singleResult.result;
80
+
81
81
  return {
82
82
  id: randomId(),
83
- strategy: 'simple',
83
+ decisionId: input.decisionId ?? null,
84
+ policy: 'simple',
84
85
  goal: input.goal,
85
86
  goalState: input.state,
86
- nextEvent: singleResult.result,
87
+ nextEvent,
87
88
  episodeId: input.episodeId ?? agent.episodeId,
88
89
  timestamp: Date.now(),
89
90
  paths: [
90
91
  {
91
- state: undefined,
92
+ state: null,
92
93
  steps: [
93
94
  {
94
- event: singleResult.result,
95
+ event: nextEvent,
95
96
  state:
96
97
  machine && machineState
97
- ? getNextSnapshot(machine, machineState, singleResult.result)
98
- : undefined,
98
+ ? transition(machine, machineState, nextEvent)[0]
99
+ : null,
99
100
  },
100
101
  ],
101
102
  },
package/src/text.ts CHANGED
@@ -28,32 +28,22 @@ import {
28
28
  * @param options
29
29
  * @returns
30
30
  */
31
- export async function getMessages<TAgent extends AnyAgent>(
32
- agent: TAgent,
31
+ export function combinePromptAndMessages(
33
32
  prompt: string,
34
- options: Omit<AgentGenerateTextOptions<TAgent>, 'prompt'>
35
- ): Promise<CoreMessage[]> {
36
- let messages: CoreMessage[] = [];
37
- if (typeof options.messages === 'function') {
38
- messages = await options.messages(agent);
39
- } else if (options.messages) {
40
- messages = options.messages;
41
- }
42
-
43
- messages = messages.concat({
33
+ messages?: CoreMessage[]
34
+ ): CoreMessage[] {
35
+ return (messages ?? []).concat({
44
36
  role: 'user',
45
37
  content: prompt,
46
38
  });
47
-
48
- return messages;
49
39
  }
50
40
 
51
41
  export function fromTextStream<TAgent extends AnyAgent>(
52
42
  agent: TAgent,
53
- options?: AgentStreamTextOptions<TAgent>
43
+ options?: AgentStreamTextOptions
54
44
  ): ObservableActorLogic<
55
45
  { textDelta: string },
56
- Omit<AgentStreamTextOptions<TAgent>, 'context'> & {
46
+ Omit<AgentStreamTextOptions, 'context'> & {
57
47
  context?: Record<string, any>;
58
48
  }
59
49
  > {
@@ -73,7 +63,10 @@ export function fromTextStream<TAgent extends AnyAgent>(
73
63
  goal,
74
64
  context: input.context,
75
65
  });
76
- const messages = await getMessages(agent, promptWithContext, input);
66
+ const messages = combinePromptAndMessages(
67
+ promptWithContext,
68
+ input.messages
69
+ );
77
70
  const result = await streamText({
78
71
  ...options,
79
72
  ...input,
@@ -108,10 +101,10 @@ export function fromTextStream<TAgent extends AnyAgent>(
108
101
 
109
102
  export function fromText<TAgent extends AnyAgent>(
110
103
  agent: TAgent,
111
- options?: AgentGenerateTextOptions<TAgent>
104
+ options?: AgentGenerateTextOptions
112
105
  ): PromiseActorLogic<
113
- GenerateTextResult<Record<string, CoreTool<any, any>>>,
114
- Omit<AgentGenerateTextOptions<TAgent>, 'context'> & {
106
+ GenerateTextResult<Record<string, CoreTool<any, any>>, any>,
107
+ Omit<AgentGenerateTextOptions, 'context'> & {
115
108
  context?: Record<string, any>;
116
109
  }
117
110
  > {
@@ -132,7 +125,10 @@ export function fromText<TAgent extends AnyAgent>(
132
125
  context: input.context,
133
126
  });
134
127
 
135
- const messages = await getMessages(agent, promptWithContext, input);
128
+ const messages = combinePromptAndMessages(
129
+ promptWithContext,
130
+ input.messages
131
+ );
136
132
 
137
133
  const model = input.model ? agent.wrap(input.model) : agent.model;
138
134