@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/.env.template +0 -3
- package/.github/actions/ci-setup/action.yml +11 -11
- package/.github/workflows/release.yml +19 -7
- package/CHANGELOG.md +85 -0
- package/dist/index.d.mts +164 -54
- package/dist/index.d.ts +164 -54
- package/dist/index.js +190 -117
- package/dist/index.mjs +181 -117
- package/examples/chatbot.ts +9 -17
- package/examples/cot.ts +5 -7
- package/examples/email.ts +2 -2
- package/examples/example.ts +7 -7
- package/examples/goal.ts +1 -1
- package/examples/joke.ts +8 -10
- package/examples/number.ts +1 -1
- package/examples/raffle.ts +1 -1
- package/examples/sandbox.ts +28 -0
- package/examples/support.ts +1 -1
- package/examples/ticTacToe.ts +18 -21
- package/examples/todo.ts +3 -1
- package/examples/tutor.ts +1 -1
- package/examples/verify.ts +1 -1
- package/examples/weather.ts +1 -1
- package/examples/wiki.ts +1 -1
- package/examples/word.ts +1 -1
- package/package.json +22 -22
- package/readme.md +1 -4
- package/src/agent.test.ts +324 -5
- package/src/agent.ts +64 -26
- package/src/decision.ts +6 -5
- package/src/index.ts +2 -2
- package/src/planners/shortestPathPlanner.ts +2 -2
- package/src/planners/simplePlanner.ts +22 -12
- package/src/schemas.ts +4 -8
- package/src/strategies/chain-of-note.ts +3 -3
- package/src/text.ts +42 -37
- package/src/types.ts +146 -42
- package/src/utils.ts +53 -9
- package/.changeset/shaggy-buttons-itch.md +0 -5
- package/src/templates/defaultToolCall.ts +0 -10
package/src/agent.ts
CHANGED
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
Observer,
|
|
8
8
|
toObserver,
|
|
9
9
|
} from 'xstate';
|
|
10
|
-
import { ZodEventMapping } from './schemas';
|
|
10
|
+
import { ZodContextMapping, ZodEventMapping } from './schemas';
|
|
11
11
|
import {
|
|
12
12
|
Agent,
|
|
13
13
|
AgentLogic,
|
|
14
|
-
|
|
14
|
+
AgentMessage,
|
|
15
15
|
AgentPlanner,
|
|
16
16
|
EventsFromZodEventMapping,
|
|
17
17
|
GenerateTextOptions,
|
|
@@ -20,12 +20,15 @@ import {
|
|
|
20
20
|
ObservedState,
|
|
21
21
|
AgentObservationInput,
|
|
22
22
|
AgentMemoryContext,
|
|
23
|
+
AgentObservation,
|
|
24
|
+
ContextFromZodContextMapping,
|
|
25
|
+
AgentFeedback,
|
|
23
26
|
} from './types';
|
|
24
27
|
import { simplePlanner } from './planners/simplePlanner';
|
|
25
28
|
import { agentGenerateText, agentStreamText } from './text';
|
|
26
29
|
import { agentDecide } from './decision';
|
|
27
30
|
import { vercelAdapter } from './adapters/vercel';
|
|
28
|
-
import { randomId } from './utils';
|
|
31
|
+
import { getMachineHash, randomId } from './utils';
|
|
29
32
|
|
|
30
33
|
export const agentLogic: AgentLogic<AnyEventObject> = fromTransition(
|
|
31
34
|
(state, event, { emit }) => {
|
|
@@ -71,33 +74,52 @@ export const agentLogic: AgentLogic<AnyEventObject> = fromTransition(
|
|
|
71
74
|
}
|
|
72
75
|
return state;
|
|
73
76
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
() =>
|
|
78
|
+
({
|
|
79
|
+
feedback: [],
|
|
80
|
+
messages: [],
|
|
81
|
+
observations: [],
|
|
82
|
+
plans: [],
|
|
83
|
+
} as AgentMemoryContext)
|
|
80
84
|
);
|
|
81
85
|
|
|
82
86
|
export function createAgent<
|
|
87
|
+
const TContextSchema extends ZodContextMapping,
|
|
83
88
|
const TEventSchemas extends ZodEventMapping,
|
|
84
|
-
TEvents extends EventObject = EventsFromZodEventMapping<TEventSchemas
|
|
89
|
+
TEvents extends EventObject = EventsFromZodEventMapping<TEventSchemas>,
|
|
90
|
+
TContext = ContextFromZodContextMapping<TContextSchema>
|
|
85
91
|
>({
|
|
86
92
|
name,
|
|
87
93
|
description,
|
|
88
94
|
model,
|
|
89
95
|
events,
|
|
90
|
-
|
|
96
|
+
context,
|
|
97
|
+
planner = simplePlanner as AgentPlanner<Agent<TContext, TEvents>>,
|
|
91
98
|
stringify = JSON.stringify,
|
|
92
99
|
getMemory,
|
|
93
100
|
logic = agentLogic as AgentLogic<TEvents>,
|
|
94
101
|
adapter = vercelAdapter,
|
|
95
102
|
...generateTextOptions
|
|
96
103
|
}: {
|
|
104
|
+
/**
|
|
105
|
+
* The unique identifier for the agent.
|
|
106
|
+
*
|
|
107
|
+
* This should be the same across all sessions of a specific agent, as it can be
|
|
108
|
+
* used to retrieve memory for this agent.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* const agent = createAgent({
|
|
113
|
+
* id: 'recipe-assistant',
|
|
114
|
+
* // ...
|
|
115
|
+
* });
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
id?: string;
|
|
97
119
|
/**
|
|
98
120
|
* The name of the agent
|
|
99
121
|
*/
|
|
100
|
-
name
|
|
122
|
+
name?: string;
|
|
101
123
|
/**
|
|
102
124
|
* A description of the role of the agent
|
|
103
125
|
*/
|
|
@@ -107,21 +129,20 @@ export function createAgent<
|
|
|
107
129
|
* that the agent knows about.
|
|
108
130
|
*/
|
|
109
131
|
events: TEventSchemas;
|
|
110
|
-
|
|
132
|
+
context?: TContextSchema;
|
|
133
|
+
planner?: AgentPlanner<Agent<TContext, TEvents>>;
|
|
111
134
|
stringify?: typeof JSON.stringify;
|
|
112
135
|
/**
|
|
113
136
|
* A function that retrieves the agent's long term memory
|
|
114
137
|
*/
|
|
115
|
-
getMemory?: (agent: Agent<
|
|
138
|
+
getMemory?: (agent: Agent<TContext, TEvents>) => AgentLongTermMemory;
|
|
116
139
|
/**
|
|
117
140
|
* Agent logic
|
|
118
141
|
*/
|
|
119
142
|
logic?: AgentLogic<TEvents>;
|
|
120
143
|
adapter?: AIAdapter;
|
|
121
|
-
} & GenerateTextOptions): Agent<TEvents> {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
const agent = createActor(logic) as unknown as Agent<TEvents>;
|
|
144
|
+
} & GenerateTextOptions): Agent<TContext, TEvents> {
|
|
145
|
+
const agent = createActor(logic) as unknown as Agent<TContext, TEvents>;
|
|
125
146
|
agent.events = events;
|
|
126
147
|
agent.model = model;
|
|
127
148
|
agent.name = name;
|
|
@@ -134,7 +155,7 @@ export function createAgent<
|
|
|
134
155
|
agent.memory = getMemory ? getMemory(agent) : undefined;
|
|
135
156
|
|
|
136
157
|
agent.onMessage = (callback) => {
|
|
137
|
-
|
|
158
|
+
agent.on('message', (ev) => callback(ev.message));
|
|
138
159
|
};
|
|
139
160
|
|
|
140
161
|
agent.decide = (opts) => {
|
|
@@ -147,7 +168,8 @@ export function createAgent<
|
|
|
147
168
|
id: messageInput.id ?? randomId(),
|
|
148
169
|
timestamp: messageInput.timestamp ?? Date.now(),
|
|
149
170
|
sessionId: agent.sessionId,
|
|
150
|
-
|
|
171
|
+
correlationId: messageInput.correlationId ?? randomId(),
|
|
172
|
+
} satisfies AgentMessage;
|
|
151
173
|
agent.send({
|
|
152
174
|
type: 'agent.message',
|
|
153
175
|
message,
|
|
@@ -155,6 +177,7 @@ export function createAgent<
|
|
|
155
177
|
|
|
156
178
|
return message;
|
|
157
179
|
};
|
|
180
|
+
agent.getMessages = () => agent.getSnapshot().context.messages;
|
|
158
181
|
|
|
159
182
|
agent.generateText = (opts) => agentGenerateText(agent, opts);
|
|
160
183
|
|
|
@@ -163,23 +186,32 @@ export function createAgent<
|
|
|
163
186
|
agent.addFeedback = (feedbackInput) => {
|
|
164
187
|
const feedback = {
|
|
165
188
|
...feedbackInput,
|
|
189
|
+
attributes: { ...feedbackInput.attributes },
|
|
190
|
+
reward: feedbackInput.reward ?? 0,
|
|
166
191
|
timestamp: feedbackInput.timestamp ?? Date.now(),
|
|
167
192
|
sessionId: agent.sessionId,
|
|
168
|
-
};
|
|
193
|
+
} satisfies AgentFeedback;
|
|
169
194
|
agent.send({
|
|
170
195
|
type: 'agent.feedback',
|
|
171
196
|
feedback,
|
|
172
197
|
});
|
|
173
198
|
return feedback;
|
|
174
199
|
};
|
|
200
|
+
agent.getFeedback = () => agent.getSnapshot().context.feedback;
|
|
175
201
|
|
|
176
202
|
agent.addObservation = (observationInput) => {
|
|
203
|
+
const { prevState, event, state } = observationInput;
|
|
177
204
|
const observation = {
|
|
178
|
-
|
|
205
|
+
prevState,
|
|
206
|
+
event,
|
|
207
|
+
state,
|
|
179
208
|
id: observationInput.id ?? randomId(),
|
|
180
209
|
sessionId: agent.sessionId,
|
|
181
210
|
timestamp: observationInput.timestamp ?? Date.now(),
|
|
182
|
-
|
|
211
|
+
machineHash: observationInput.machine
|
|
212
|
+
? getMachineHash(observationInput.machine)
|
|
213
|
+
: undefined,
|
|
214
|
+
} satisfies AgentObservation<any>;
|
|
183
215
|
|
|
184
216
|
agent.send({
|
|
185
217
|
type: 'agent.observe',
|
|
@@ -188,6 +220,7 @@ export function createAgent<
|
|
|
188
220
|
|
|
189
221
|
return observation;
|
|
190
222
|
};
|
|
223
|
+
agent.getObservations = () => agent.getSnapshot().context.observations;
|
|
191
224
|
|
|
192
225
|
agent.addPlan = (plan) => {
|
|
193
226
|
agent.send({
|
|
@@ -195,8 +228,9 @@ export function createAgent<
|
|
|
195
228
|
plan,
|
|
196
229
|
});
|
|
197
230
|
};
|
|
231
|
+
agent.getPlans = () => agent.getSnapshot().context.plans;
|
|
198
232
|
|
|
199
|
-
agent.interact = (actorRef, getInput) => {
|
|
233
|
+
agent.interact = ((actorRef, getInput) => {
|
|
200
234
|
let prevState: ObservedState | undefined = undefined;
|
|
201
235
|
let subscribed = true;
|
|
202
236
|
|
|
@@ -234,7 +268,8 @@ export function createAgent<
|
|
|
234
268
|
event: inspEvent.event,
|
|
235
269
|
prevState,
|
|
236
270
|
state: inspEvent.snapshot as any,
|
|
237
|
-
|
|
271
|
+
machine: (actorRef as any).src,
|
|
272
|
+
} satisfies AgentObservationInput;
|
|
238
273
|
|
|
239
274
|
await handleObservation(observationInput);
|
|
240
275
|
},
|
|
@@ -246,6 +281,7 @@ export function createAgent<
|
|
|
246
281
|
prevState: undefined,
|
|
247
282
|
event: { type: '' }, // TODO: unknown events?
|
|
248
283
|
state: actorRef.getSnapshot(),
|
|
284
|
+
machine: (actorRef as any).src,
|
|
249
285
|
});
|
|
250
286
|
}
|
|
251
287
|
|
|
@@ -254,7 +290,9 @@ export function createAgent<
|
|
|
254
290
|
subscribed = false;
|
|
255
291
|
}, // TODO: make this actually unsubscribe
|
|
256
292
|
};
|
|
257
|
-
};
|
|
293
|
+
}) as typeof agent.interact;
|
|
294
|
+
|
|
295
|
+
agent.types = {} as any;
|
|
258
296
|
|
|
259
297
|
agent.start();
|
|
260
298
|
|
package/src/decision.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { AnyMachineSnapshot, fromPromise } from 'xstate';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
AnyAgent,
|
|
4
4
|
AgentDecideOptions,
|
|
5
5
|
AgentDecisionLogic,
|
|
6
6
|
AgentDecisionInput,
|
|
7
7
|
AgentPlanner,
|
|
8
|
+
AgentPlan,
|
|
8
9
|
} from './types';
|
|
9
10
|
import { simplePlanner } from './planners/simplePlanner';
|
|
10
11
|
|
|
11
|
-
export async function agentDecide<T extends
|
|
12
|
+
export async function agentDecide<T extends AnyAgent>(
|
|
12
13
|
agent: T,
|
|
13
14
|
options: AgentDecideOptions
|
|
14
|
-
) {
|
|
15
|
+
): Promise<AgentPlan<any> | undefined> {
|
|
15
16
|
const resolvedOptions = {
|
|
16
17
|
...agent.defaultOptions,
|
|
17
18
|
...options,
|
|
@@ -44,9 +45,9 @@ export async function agentDecide<T extends Agent<any>>(
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
export function fromDecision(
|
|
47
|
-
agent:
|
|
48
|
+
agent: AnyAgent,
|
|
48
49
|
defaultInput?: AgentDecisionInput
|
|
49
|
-
) {
|
|
50
|
+
): AgentDecisionLogic<any> {
|
|
50
51
|
return fromPromise(async ({ input, self }) => {
|
|
51
52
|
const parentRef = self._parent;
|
|
52
53
|
if (!parentRef) {
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { createAgent } from './agent';
|
|
2
|
-
export { fromText, fromTextStream
|
|
3
|
-
export { fromDecision
|
|
2
|
+
export { fromText, fromTextStream } from './text';
|
|
3
|
+
export { fromDecision } from './decision';
|
|
4
4
|
export * from './types';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Agent, AgentPlan, AgentPlanInput } from '../types';
|
|
1
|
+
import { Agent, AgentPlan, AgentPlanInput, AnyAgent } from '../types';
|
|
2
2
|
import { getShortestPaths } from '@xstate/graph';
|
|
3
3
|
|
|
4
|
-
export async function simplePlanner<T extends
|
|
4
|
+
export async function simplePlanner<T extends AnyAgent>(
|
|
5
5
|
agent: T,
|
|
6
6
|
input: AgentPlanInput<any>
|
|
7
7
|
): Promise<AgentPlan<any> | undefined> {
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { CoreTool, tool } from 'ai';
|
|
1
|
+
import { type CoreTool, tool } from 'ai';
|
|
2
2
|
import {
|
|
3
|
-
Agent,
|
|
4
3
|
AgentPlan,
|
|
5
4
|
AgentPlanInput,
|
|
6
5
|
ObservedState,
|
|
7
6
|
PromptTemplate,
|
|
8
7
|
TransitionData,
|
|
8
|
+
AnyAgent,
|
|
9
9
|
} from '../types';
|
|
10
10
|
import { getAllTransitions } from '../utils';
|
|
11
11
|
import { AnyStateMachine } from 'xstate';
|
|
12
12
|
import { defaultTextTemplate } from '../templates/defaultText';
|
|
13
|
+
import { getMessages } from '../text';
|
|
13
14
|
|
|
14
15
|
function getTransitions(
|
|
15
16
|
state: ObservedState,
|
|
@@ -27,11 +28,11 @@ const simplePlannerPromptTemplate: PromptTemplate<any> = (data) => {
|
|
|
27
28
|
return `
|
|
28
29
|
${defaultTextTemplate(data)}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
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.
|
|
31
32
|
`.trim();
|
|
32
33
|
};
|
|
33
34
|
|
|
34
|
-
export async function simplePlanner<T extends
|
|
35
|
+
export async function simplePlanner<T extends AnyAgent>(
|
|
35
36
|
agent: T,
|
|
36
37
|
input: AgentPlanInput<any>
|
|
37
38
|
): Promise<AgentPlan<any> | undefined> {
|
|
@@ -81,7 +82,7 @@ export async function simplePlanner<T extends Agent<any>>(
|
|
|
81
82
|
toolMap[toolTransitionData.name] = tool({
|
|
82
83
|
description: toolZodType?.description ?? toolTransitionData.description,
|
|
83
84
|
parameters: toolZodType,
|
|
84
|
-
execute: async (params) => {
|
|
85
|
+
execute: async (params: Record<string, any>) => {
|
|
85
86
|
const event = {
|
|
86
87
|
type: toolTransitionData.eventType,
|
|
87
88
|
...params,
|
|
@@ -92,18 +93,26 @@ export async function simplePlanner<T extends Agent<any>>(
|
|
|
92
93
|
});
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
if (!Object.keys(toolMap).length) {
|
|
97
|
+
// No valid transitions for the specified tools
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
95
101
|
// Create a prompt with the given context and goal.
|
|
96
|
-
// The template is used to ensure that a single tool call is made.
|
|
102
|
+
// The template is used to ensure that a single tool call at most is made.
|
|
97
103
|
const prompt = simplePlannerPromptTemplate({
|
|
98
104
|
context: input.state.context,
|
|
99
105
|
goal: input.goal,
|
|
100
106
|
});
|
|
101
107
|
|
|
108
|
+
const messages = await getMessages(agent, prompt, input);
|
|
109
|
+
|
|
102
110
|
const result = await agent.generateText({
|
|
111
|
+
toolChoice: 'required',
|
|
103
112
|
...input,
|
|
104
113
|
prompt,
|
|
114
|
+
messages,
|
|
105
115
|
tools: toolMap,
|
|
106
|
-
toolChoice: 'required',
|
|
107
116
|
});
|
|
108
117
|
|
|
109
118
|
const singleResult = result.toolResults[0];
|
|
@@ -117,11 +126,12 @@ export async function simplePlanner<T extends Agent<any>>(
|
|
|
117
126
|
return {
|
|
118
127
|
goal: input.goal,
|
|
119
128
|
state: input.state,
|
|
120
|
-
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
129
|
+
execute: async (state) => {
|
|
130
|
+
if (JSON.stringify(state) === JSON.stringify(input.state)) {
|
|
131
|
+
return singleResult.result;
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
},
|
|
125
135
|
nextEvent: singleResult.result,
|
|
126
136
|
sessionId: agent.sessionId,
|
|
127
137
|
timestamp: Date.now(),
|
package/src/schemas.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { AnyEventObject } from 'xstate';
|
|
3
|
-
import { ObservedState } from './types';
|
|
1
|
+
import { ZodType, type SomeZodObject } from 'zod';
|
|
4
2
|
|
|
5
3
|
export type ZodEventMapping = {
|
|
6
4
|
// map event types to Zod types
|
|
7
5
|
[eventType: string]: SomeZodObject;
|
|
8
6
|
};
|
|
9
7
|
|
|
10
|
-
export type
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
action: (state: ObservedState, event: AnyEventObject) => Promise<void>;
|
|
14
|
-
};
|
|
8
|
+
export type ZodContextMapping = {
|
|
9
|
+
// map context keys to Zod types
|
|
10
|
+
[contextKey: string]: ZodType;
|
|
15
11
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GenerateTextResult, LanguageModel } from 'ai';
|
|
2
2
|
import wiki, { wikiSearchResult, wikiSummary } from 'wikipedia';
|
|
3
3
|
import { assign, fromPromise, setup } from 'xstate';
|
|
4
|
-
import {
|
|
4
|
+
import { AnyAgent } from '../types';
|
|
5
5
|
|
|
6
6
|
const searchWiki = fromPromise(
|
|
7
7
|
async ({
|
|
@@ -44,7 +44,7 @@ export const chainOfNote = setup({
|
|
|
44
44
|
types: {
|
|
45
45
|
input: {} as {
|
|
46
46
|
model: LanguageModel;
|
|
47
|
-
agent:
|
|
47
|
+
agent: AnyAgent;
|
|
48
48
|
prompt: string;
|
|
49
49
|
},
|
|
50
50
|
context: {} as {
|
|
@@ -56,7 +56,7 @@ export const chainOfNote = setup({
|
|
|
56
56
|
}[]
|
|
57
57
|
| null;
|
|
58
58
|
model: LanguageModel;
|
|
59
|
-
agent:
|
|
59
|
+
agent: AnyAgent;
|
|
60
60
|
prompt: string;
|
|
61
61
|
},
|
|
62
62
|
output: {} as GenerateTextResult<any>,
|
package/src/text.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
CoreMessage,
|
|
3
|
-
CoreTool,
|
|
4
|
-
GenerateTextResult,
|
|
5
|
-
StreamTextResult,
|
|
6
|
-
} from 'ai';
|
|
1
|
+
import type { CoreMessage, CoreTool, GenerateTextResult } from 'ai';
|
|
7
2
|
import {
|
|
8
|
-
Agent,
|
|
9
3
|
AgentGenerateTextOptions,
|
|
4
|
+
AgentGenerateTextResult,
|
|
10
5
|
AgentStreamTextOptions,
|
|
6
|
+
AgentStreamTextResult,
|
|
7
|
+
AnyAgent,
|
|
11
8
|
} from './types';
|
|
12
9
|
import { defaultTextTemplate } from './templates/defaultText';
|
|
13
10
|
import {
|
|
14
|
-
AnyMachineSnapshot,
|
|
15
11
|
ObservableActorLogic,
|
|
16
12
|
Observer,
|
|
17
13
|
PromiseActorLogic,
|
|
@@ -29,15 +25,13 @@ import { randomId } from './utils';
|
|
|
29
25
|
* @param options
|
|
30
26
|
* @returns
|
|
31
27
|
*/
|
|
32
|
-
async function getMessages(
|
|
33
|
-
agent:
|
|
28
|
+
export async function getMessages(
|
|
29
|
+
agent: AnyAgent,
|
|
34
30
|
prompt: string,
|
|
35
|
-
options:
|
|
31
|
+
options: Omit<AgentGenerateTextOptions, 'prompt'>
|
|
36
32
|
): Promise<CoreMessage[]> {
|
|
37
33
|
let messages: CoreMessage[] = [];
|
|
38
|
-
if (options.messages ===
|
|
39
|
-
messages = agent.select((s) => s.messages);
|
|
40
|
-
} else if (typeof options.messages === 'function') {
|
|
34
|
+
if (typeof options.messages === 'function') {
|
|
41
35
|
messages = await options.messages(agent);
|
|
42
36
|
} else if (options.messages) {
|
|
43
37
|
messages = options.messages;
|
|
@@ -51,14 +45,16 @@ async function getMessages(
|
|
|
51
45
|
return messages;
|
|
52
46
|
}
|
|
53
47
|
|
|
54
|
-
export async function agentGenerateText<T extends
|
|
48
|
+
export async function agentGenerateText<T extends AnyAgent>(
|
|
55
49
|
agent: T,
|
|
56
50
|
options: AgentGenerateTextOptions
|
|
57
|
-
) {
|
|
51
|
+
): Promise<AgentGenerateTextResult> {
|
|
58
52
|
const resolvedOptions = {
|
|
59
53
|
...agent.defaultOptions,
|
|
60
54
|
...options,
|
|
55
|
+
correlationId: options.correlationId ?? randomId(),
|
|
61
56
|
};
|
|
57
|
+
// Generate a correlation ID if one is not provided
|
|
62
58
|
const template = resolvedOptions.template ?? defaultTextTemplate;
|
|
63
59
|
// TODO: check if messages was provided instead
|
|
64
60
|
const id = randomId();
|
|
@@ -79,6 +75,8 @@ export async function agentGenerateText<T extends Agent<any>>(
|
|
|
79
75
|
role: 'user',
|
|
80
76
|
content: promptWithContext,
|
|
81
77
|
timestamp: Date.now(),
|
|
78
|
+
correlationId: resolvedOptions.correlationId,
|
|
79
|
+
parentCorrelationId: resolvedOptions.parentCorrelationId,
|
|
82
80
|
});
|
|
83
81
|
|
|
84
82
|
const result = await agent.adapter.generateText({
|
|
@@ -94,18 +92,25 @@ export async function agentGenerateText<T extends Agent<any>>(
|
|
|
94
92
|
timestamp: Date.now(),
|
|
95
93
|
responseId: id,
|
|
96
94
|
result,
|
|
95
|
+
correlationId: resolvedOptions.correlationId,
|
|
96
|
+
parentCorrelationId: resolvedOptions.parentCorrelationId,
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
return
|
|
99
|
+
return {
|
|
100
|
+
...result,
|
|
101
|
+
parentCorrelationId: resolvedOptions.parentCorrelationId,
|
|
102
|
+
correlationId: resolvedOptions.correlationId,
|
|
103
|
+
};
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
export async function agentStreamText(
|
|
103
|
-
agent:
|
|
107
|
+
agent: AnyAgent,
|
|
104
108
|
options: AgentStreamTextOptions
|
|
105
|
-
): Promise<
|
|
109
|
+
): Promise<AgentStreamTextResult> {
|
|
106
110
|
const resolvedOptions = {
|
|
107
111
|
...agent.defaultOptions,
|
|
108
112
|
...options,
|
|
113
|
+
correlationId: options.correlationId ?? randomId(),
|
|
109
114
|
};
|
|
110
115
|
const template = resolvedOptions.template ?? defaultTextTemplate;
|
|
111
116
|
|
|
@@ -127,6 +132,8 @@ export async function agentStreamText(
|
|
|
127
132
|
content: promptWithContext,
|
|
128
133
|
id,
|
|
129
134
|
timestamp: Date.now(),
|
|
135
|
+
correlationId: resolvedOptions.correlationId,
|
|
136
|
+
parentCorrelationId: resolvedOptions.parentCorrelationId,
|
|
130
137
|
});
|
|
131
138
|
|
|
132
139
|
const result = await agent.adapter.streamText({
|
|
@@ -146,33 +153,35 @@ export async function agentStreamText(
|
|
|
146
153
|
usage: res.usage,
|
|
147
154
|
warnings: res.warnings,
|
|
148
155
|
rawResponse: res.rawResponse,
|
|
156
|
+
roundtrips: [], // TODO: how do we get this information?
|
|
149
157
|
},
|
|
150
158
|
content: res.text,
|
|
151
159
|
id: randomId(),
|
|
152
160
|
timestamp: Date.now(),
|
|
153
161
|
responseId: id,
|
|
162
|
+
correlationId: resolvedOptions.correlationId,
|
|
163
|
+
parentCorrelationId: resolvedOptions.parentCorrelationId,
|
|
154
164
|
});
|
|
155
165
|
},
|
|
156
166
|
});
|
|
157
167
|
|
|
158
|
-
return
|
|
168
|
+
return {
|
|
169
|
+
...result,
|
|
170
|
+
parentCorrelationId: resolvedOptions.parentCorrelationId,
|
|
171
|
+
correlationId: resolvedOptions.correlationId,
|
|
172
|
+
} as unknown as AgentStreamTextResult; // TODO: fix
|
|
159
173
|
}
|
|
160
174
|
|
|
161
|
-
export function fromTextStream<T extends
|
|
175
|
+
export function fromTextStream<T extends AnyAgent>(
|
|
162
176
|
agent: T,
|
|
163
177
|
defaultOptions?: AgentStreamTextOptions
|
|
164
178
|
): ObservableActorLogic<
|
|
165
179
|
{ textDelta: string },
|
|
166
180
|
Omit<AgentStreamTextOptions, 'context'> & {
|
|
167
|
-
context?: AgentStreamTextOptions['context']
|
|
181
|
+
context?: AgentStreamTextOptions['context'];
|
|
168
182
|
}
|
|
169
183
|
> {
|
|
170
|
-
return fromObservable(({ input
|
|
171
|
-
const context =
|
|
172
|
-
input.context === true
|
|
173
|
-
? (self._parent?.getSnapshot() as AnyMachineSnapshot).context
|
|
174
|
-
: input.context;
|
|
175
|
-
|
|
184
|
+
return fromObservable(({ input }) => {
|
|
176
185
|
const observers = new Set<Observer<{ textDelta: string }>>();
|
|
177
186
|
|
|
178
187
|
// TODO: check if messages was provided instead
|
|
@@ -181,7 +190,7 @@ export function fromTextStream<T extends Agent<any>>(
|
|
|
181
190
|
const result = await agentStreamText(agent, {
|
|
182
191
|
...defaultOptions,
|
|
183
192
|
...input,
|
|
184
|
-
context,
|
|
193
|
+
context: input.context,
|
|
185
194
|
});
|
|
186
195
|
|
|
187
196
|
for await (const part of result.fullStream) {
|
|
@@ -208,24 +217,20 @@ export function fromTextStream<T extends Agent<any>>(
|
|
|
208
217
|
});
|
|
209
218
|
}
|
|
210
219
|
|
|
211
|
-
export function fromText<T extends
|
|
220
|
+
export function fromText<T extends AnyAgent>(
|
|
212
221
|
agent: T,
|
|
213
222
|
defaultOptions?: AgentGenerateTextOptions
|
|
214
223
|
): PromiseActorLogic<
|
|
215
224
|
GenerateTextResult<Record<string, CoreTool<any, any>>>,
|
|
216
225
|
Omit<AgentGenerateTextOptions, 'context'> & {
|
|
217
|
-
context?: AgentGenerateTextOptions['context']
|
|
226
|
+
context?: AgentGenerateTextOptions['context'];
|
|
218
227
|
}
|
|
219
228
|
> {
|
|
220
|
-
return fromPromise(async ({ input
|
|
221
|
-
const context =
|
|
222
|
-
input.context === true
|
|
223
|
-
? (self._parent?.getSnapshot() as AnyMachineSnapshot).context
|
|
224
|
-
: input.context;
|
|
229
|
+
return fromPromise(async ({ input }) => {
|
|
225
230
|
return await agentGenerateText(agent, {
|
|
226
231
|
...input,
|
|
227
232
|
...defaultOptions,
|
|
228
|
-
context,
|
|
233
|
+
context: input.context,
|
|
229
234
|
});
|
|
230
235
|
});
|
|
231
236
|
}
|