@statelyai/agent 2.0.0-next.3 → 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.
- package/.changeset/calm-beans-talk.md +5 -0
- package/.changeset/long-guests-explode.md +5 -0
- package/.changeset/nice-pants-rule.md +10 -0
- package/.changeset/odd-kiwis-compare.md +5 -0
- package/.changeset/pre.json +4 -0
- package/CHANGELOG.md +23 -0
- package/architecture.tldr +797 -0
- package/dist/index.d.mts +198 -140
- package/dist/index.d.ts +198 -140
- package/dist/index.js +4397 -148
- package/dist/index.mjs +4397 -149
- package/examples/chatbot.ts +9 -5
- package/examples/cot.ts +2 -4
- package/examples/jugs.ts +2 -2
- package/examples/learn-from-feedback.ts +7 -7
- package/examples/newspaper.ts +1 -1
- package/examples/rewoo.ts +62 -0
- package/examples/river-crossing.ts +2 -2
- package/examples/serverless.ts +71 -0
- package/examples/simple.ts +1 -1
- package/examples/ticTacToe.ts +6 -2
- package/examples/wiki.ts +2 -2
- package/package.json +14 -12
- package/readme.md +57 -0
- package/src/agent.test.ts +387 -30
- package/src/agent.ts +177 -64
- package/src/decide.test.ts +24 -2
- package/src/decide.ts +34 -78
- package/src/index.ts +1 -0
- package/src/{strategies/chainOfThought.ts → policies/chainOfThoughtPolicy.ts} +7 -9
- package/src/policies/index.ts +3 -0
- package/src/{strategies/shortestPath.test.ts → policies/shortestPathPolicy.test.ts} +2 -2
- package/src/{strategies/shortestPath.ts → policies/shortestPathPolicy.ts} +8 -8
- package/src/{strategies/simple.ts → policies/toolPolicy.ts} +27 -26
- package/src/text.ts +17 -22
- package/src/types.ts +162 -166
- package/src/agent-experimental.ts +0 -221
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
AgentDecision,
|
|
6
6
|
PromptTemplate,
|
|
7
7
|
} from '../types';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { combinePromptAndMessages } from '../text';
|
|
9
|
+
import { toolPolicy } from './toolPolicy';
|
|
10
10
|
import { convertToXml } from '../utils';
|
|
11
11
|
|
|
12
12
|
const chainOfThoughtPromptTemplate: PromptTemplate<any> = ({
|
|
@@ -14,14 +14,12 @@ const chainOfThoughtPromptTemplate: PromptTemplate<any> = ({
|
|
|
14
14
|
context,
|
|
15
15
|
goal,
|
|
16
16
|
}) => {
|
|
17
|
-
return
|
|
18
|
-
${convertToXml({ stateValue, context, goal })}
|
|
17
|
+
return `${convertToXml({ stateValue, context, goal })}
|
|
19
18
|
|
|
20
|
-
How would you achieve the goal? Think step-by-step
|
|
21
|
-
`.trim();
|
|
19
|
+
How would you achieve the goal? Think step-by-step.`;
|
|
22
20
|
};
|
|
23
21
|
|
|
24
|
-
export async function
|
|
22
|
+
export async function chainOfThoughtPolicy<T extends AnyAgent>(
|
|
25
23
|
agent: T,
|
|
26
24
|
input: AgentDecideInput<any>
|
|
27
25
|
): Promise<AgentDecision<any> | undefined> {
|
|
@@ -31,7 +29,7 @@ export async function chainOfThoughtStrategy<T extends AnyAgent>(
|
|
|
31
29
|
goal: input.goal,
|
|
32
30
|
});
|
|
33
31
|
|
|
34
|
-
const messages =
|
|
32
|
+
const messages = combinePromptAndMessages(prompt, input.messages);
|
|
35
33
|
|
|
36
34
|
const model = input.model ? agent.wrap(input.model) : agent.model;
|
|
37
35
|
|
|
@@ -41,7 +39,7 @@ export async function chainOfThoughtStrategy<T extends AnyAgent>(
|
|
|
41
39
|
messages,
|
|
42
40
|
});
|
|
43
41
|
|
|
44
|
-
const decision = await
|
|
42
|
+
const decision = await toolPolicy(agent, {
|
|
45
43
|
...input,
|
|
46
44
|
messages: messages.concat(result.response.messages),
|
|
47
45
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createAgent, TypesFromAgent } from '..';
|
|
2
2
|
import { assign, createActor, setup } from 'xstate';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import {
|
|
4
|
+
import { experimental_shortestPathPolicy } from './shortestPathPolicy';
|
|
5
5
|
import { test, expect } from 'vitest';
|
|
6
6
|
import { dummyResponseValues, MockLanguageModelV1 } from '../mockModel';
|
|
7
7
|
|
|
@@ -84,7 +84,7 @@ test.skip('should find shortest path to goal', async () => {
|
|
|
84
84
|
}),
|
|
85
85
|
goal: 'Get the counter to exactly 3',
|
|
86
86
|
state: counterActor.getSnapshot(),
|
|
87
|
-
|
|
87
|
+
policy: experimental_shortestPathPolicy,
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
expect(decision?.nextEvent?.type).toBe('increment');
|
|
@@ -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
|
|
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 =
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
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 {
|
|
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 {
|
|
10
|
-
import {
|
|
9
|
+
import { transition } from 'xstate';
|
|
10
|
+
import { combinePromptAndMessages } from '../text';
|
|
11
11
|
import { getToolMap } from '../decide';
|
|
12
12
|
|
|
13
|
-
const
|
|
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
|
|
22
|
-
agent:
|
|
23
|
-
input: AgentDecideInput<
|
|
24
|
-
): Promise<AgentDecision<
|
|
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 =
|
|
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 =
|
|
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
|
|
59
|
+
tools: toolMap,
|
|
60
60
|
toolChoice: input.toolChoice ?? 'required',
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
result.response.messages.forEach((m) => {
|
|
64
|
-
|
|
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
|
-
|
|
83
|
+
decisionId: input.decisionId ?? null,
|
|
84
|
+
policy: 'simple',
|
|
84
85
|
goal: input.goal,
|
|
85
86
|
goalState: input.state,
|
|
86
|
-
nextEvent
|
|
87
|
-
episodeId: agent.episodeId,
|
|
87
|
+
nextEvent,
|
|
88
|
+
episodeId: input.episodeId ?? agent.episodeId,
|
|
88
89
|
timestamp: Date.now(),
|
|
89
90
|
paths: [
|
|
90
91
|
{
|
|
91
|
-
state:
|
|
92
|
+
state: null,
|
|
92
93
|
steps: [
|
|
93
94
|
{
|
|
94
|
-
event:
|
|
95
|
+
event: nextEvent,
|
|
95
96
|
state:
|
|
96
97
|
machine && machineState
|
|
97
|
-
?
|
|
98
|
-
:
|
|
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
|
|
32
|
-
agent: TAgent,
|
|
31
|
+
export function combinePromptAndMessages(
|
|
33
32
|
prompt: string,
|
|
34
|
-
|
|
35
|
-
):
|
|
36
|
-
|
|
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
|
|
43
|
+
options?: AgentStreamTextOptions
|
|
54
44
|
): ObservableActorLogic<
|
|
55
45
|
{ textDelta: string },
|
|
56
|
-
Omit<AgentStreamTextOptions
|
|
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 =
|
|
66
|
+
const messages = combinePromptAndMessages(
|
|
67
|
+
promptWithContext,
|
|
68
|
+
input.messages
|
|
69
|
+
);
|
|
77
70
|
const result = await streamText({
|
|
78
71
|
...options,
|
|
79
72
|
...input,
|
|
@@ -108,15 +101,14 @@ export function fromTextStream<TAgent extends AnyAgent>(
|
|
|
108
101
|
|
|
109
102
|
export function fromText<TAgent extends AnyAgent>(
|
|
110
103
|
agent: TAgent,
|
|
111
|
-
options?: AgentGenerateTextOptions
|
|
104
|
+
options?: AgentGenerateTextOptions
|
|
112
105
|
): PromiseActorLogic<
|
|
113
|
-
GenerateTextResult<Record<string, CoreTool<any, any
|
|
114
|
-
Omit<AgentGenerateTextOptions
|
|
106
|
+
GenerateTextResult<Record<string, CoreTool<any, any>>, any>,
|
|
107
|
+
Omit<AgentGenerateTextOptions, 'context'> & {
|
|
115
108
|
context?: Record<string, any>;
|
|
116
109
|
}
|
|
117
110
|
> {
|
|
118
111
|
const resolvedOptions = {
|
|
119
|
-
...agent.defaultOptions,
|
|
120
112
|
...options,
|
|
121
113
|
};
|
|
122
114
|
|
|
@@ -133,7 +125,10 @@ export function fromText<TAgent extends AnyAgent>(
|
|
|
133
125
|
context: input.context,
|
|
134
126
|
});
|
|
135
127
|
|
|
136
|
-
const messages =
|
|
128
|
+
const messages = combinePromptAndMessages(
|
|
129
|
+
promptWithContext,
|
|
130
|
+
input.messages
|
|
131
|
+
);
|
|
137
132
|
|
|
138
133
|
const model = input.model ? agent.wrap(input.model) : agent.model;
|
|
139
134
|
|