@statelyai/agent 2.0.0-next.2 → 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.
- package/.changeset/pink-eagles-deliver.md +13 -0
- package/.changeset/pre.json +6 -1
- package/.changeset/quiet-turtles-do.md +7 -0
- package/.changeset/sweet-clouds-mix.md +16 -0
- package/.changeset/swift-mangos-rush.md +5 -0
- package/.changeset/tough-ways-rhyme.md +5 -0
- package/CHANGELOG.md +39 -0
- package/dist/index.d.mts +85 -78
- package/dist/index.d.ts +85 -78
- package/dist/index.js +28 -26
- package/dist/index.mjs +28 -26
- package/examples/cot.ts +19 -53
- package/examples/customer-service-sim.ts +3 -3
- package/examples/email.ts +2 -10
- package/examples/example.ts +2 -2
- package/examples/goal.ts +2 -2
- package/examples/joke.ts +10 -10
- package/examples/learn-from-feedback.ts +47 -24
- package/examples/number.ts +2 -2
- package/examples/raffle.ts +2 -2
- package/examples/support.ts +7 -11
- package/examples/ticTacToe.ts +2 -2
- package/examples/todo.ts +3 -3
- package/examples/tutor.ts +2 -2
- package/examples/verify.ts +2 -2
- package/examples/weather-agent.ts +3 -5
- package/examples/weather.ts +10 -7
- package/package.json +1 -1
- package/src/agent.test.ts +20 -37
- package/src/agent.ts +48 -28
- package/src/decide.ts +12 -12
- package/src/strategies/chainOfThought.ts +4 -2
- package/src/strategies/shortestPath.ts +7 -2
- package/src/strategies/simple.ts +4 -15
- package/src/templates/defaultText.ts +3 -0
- package/src/text.ts +13 -13
- package/src/types.ts +83 -76
- package/src/utils.ts +1 -1
package/src/agent.test.ts
CHANGED
|
@@ -70,34 +70,24 @@ test('agent.addFeedback() adds to feedback', () => {
|
|
|
70
70
|
model: {} as any,
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
},
|
|
73
|
+
const obs = agent.addObservation({
|
|
74
|
+
prevState: { value: 'playing' },
|
|
75
|
+
state: { value: 'lost' },
|
|
76
|
+
event: { type: 'play', position: 3 },
|
|
77
77
|
goal: 'Win the game',
|
|
78
|
-
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const feedback = agent.addFeedback({
|
|
81
|
+
score: 0,
|
|
82
|
+
observationId: obs.id,
|
|
79
83
|
});
|
|
80
84
|
|
|
81
85
|
expect(feedback.episodeId).toEqual(agent.episodeId);
|
|
82
86
|
|
|
83
87
|
expect(agent.getFeedback()).toContainEqual(
|
|
84
88
|
expect.objectContaining({
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
},
|
|
88
|
-
goal: 'Win the game',
|
|
89
|
-
observationId: 'obs-1',
|
|
90
|
-
episodeId: expect.any(String),
|
|
91
|
-
timestamp: expect.any(Number),
|
|
92
|
-
})
|
|
93
|
-
);
|
|
94
|
-
expect(agent.getFeedback()).toContainEqual(
|
|
95
|
-
expect.objectContaining({
|
|
96
|
-
attributes: {
|
|
97
|
-
score: -1,
|
|
98
|
-
},
|
|
99
|
-
goal: 'Win the game',
|
|
100
|
-
observationId: 'obs-1',
|
|
89
|
+
score: 0,
|
|
90
|
+
observationId: obs.id,
|
|
101
91
|
episodeId: expect.any(String),
|
|
102
92
|
timestamp: expect.any(Number),
|
|
103
93
|
})
|
|
@@ -115,6 +105,7 @@ test('agent.addObservation() adds to observations', () => {
|
|
|
115
105
|
prevState: { value: 'playing', context: {} },
|
|
116
106
|
event: { type: 'play', position: 3 },
|
|
117
107
|
state: { value: 'lost', context: {} },
|
|
108
|
+
goal: 'Win the game',
|
|
118
109
|
});
|
|
119
110
|
|
|
120
111
|
expect(observation.episodeId).toEqual(agent.episodeId);
|
|
@@ -139,6 +130,7 @@ test('agent.addObservation() adds to observations (initial state)', () => {
|
|
|
139
130
|
|
|
140
131
|
const observation = agent.addObservation({
|
|
141
132
|
state: { value: 'lost' },
|
|
133
|
+
goal: 'Win the game',
|
|
142
134
|
});
|
|
143
135
|
|
|
144
136
|
expect(observation.episodeId).toEqual(agent.episodeId);
|
|
@@ -176,6 +168,7 @@ test('agent.addObservation() adds to observations with machine hash', () => {
|
|
|
176
168
|
event: { type: 'play', position: 3 },
|
|
177
169
|
state: { value: 'lost', context: {} },
|
|
178
170
|
machine,
|
|
171
|
+
goal: 'Win the game',
|
|
179
172
|
});
|
|
180
173
|
|
|
181
174
|
expect(observation.episodeId).toEqual(agent.episodeId);
|
|
@@ -203,13 +196,11 @@ test('agent.addFeedback() adds to feedback (with observation)', () => {
|
|
|
203
196
|
state: {
|
|
204
197
|
value: 'playing',
|
|
205
198
|
},
|
|
199
|
+
goal: 'Win the game',
|
|
206
200
|
});
|
|
207
201
|
|
|
208
202
|
const feedback = agent.addFeedback({
|
|
209
|
-
|
|
210
|
-
score: -1,
|
|
211
|
-
},
|
|
212
|
-
goal: 'Win the game',
|
|
203
|
+
score: 0,
|
|
213
204
|
observationId: observation.id,
|
|
214
205
|
});
|
|
215
206
|
|
|
@@ -217,10 +208,7 @@ test('agent.addFeedback() adds to feedback (with observation)', () => {
|
|
|
217
208
|
|
|
218
209
|
expect(agent.getFeedback()).toContainEqual(
|
|
219
210
|
expect.objectContaining({
|
|
220
|
-
|
|
221
|
-
score: -1,
|
|
222
|
-
},
|
|
223
|
-
goal: 'Win the game',
|
|
211
|
+
score: 0,
|
|
224
212
|
observationId: observation.id,
|
|
225
213
|
episodeId: expect.any(String),
|
|
226
214
|
timestamp: expect.any(Number),
|
|
@@ -228,10 +216,7 @@ test('agent.addFeedback() adds to feedback (with observation)', () => {
|
|
|
228
216
|
);
|
|
229
217
|
expect(agent.getFeedback()).toContainEqual(
|
|
230
218
|
expect.objectContaining({
|
|
231
|
-
|
|
232
|
-
score: -1,
|
|
233
|
-
},
|
|
234
|
-
goal: 'Win the game',
|
|
219
|
+
score: 0,
|
|
235
220
|
observationId: observation.id,
|
|
236
221
|
episodeId: expect.any(String),
|
|
237
222
|
timestamp: expect.any(Number),
|
|
@@ -297,10 +282,7 @@ test('You can listen for feedback events', () => {
|
|
|
297
282
|
agent.on('feedback', fn);
|
|
298
283
|
|
|
299
284
|
agent.addFeedback({
|
|
300
|
-
|
|
301
|
-
score: -1,
|
|
302
|
-
},
|
|
303
|
-
goal: 'Win the game',
|
|
285
|
+
score: -1,
|
|
304
286
|
observationId: 'obs-1',
|
|
305
287
|
});
|
|
306
288
|
|
|
@@ -445,6 +427,7 @@ test('agent.getDecisions() returns decisions from context', () => {
|
|
|
445
427
|
model: {} as any,
|
|
446
428
|
strategy: async (agent) => {
|
|
447
429
|
return {
|
|
430
|
+
id: Date.now().toString(),
|
|
448
431
|
episodeId: agent.episodeId,
|
|
449
432
|
strategy: 'test-strategy',
|
|
450
433
|
goal: '',
|
package/src/agent.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Actor,
|
|
3
3
|
ActorRefLike,
|
|
4
|
-
AnyEventObject,
|
|
5
4
|
EventObject,
|
|
6
5
|
fromTransition,
|
|
7
6
|
Subscription,
|
|
@@ -23,11 +22,8 @@ import {
|
|
|
23
22
|
AgentMessageInput,
|
|
24
23
|
AgentFeedbackInput,
|
|
25
24
|
AgentDecision,
|
|
26
|
-
Compute,
|
|
27
|
-
AgentDecisionInput,
|
|
28
25
|
AgentDecideOptions,
|
|
29
26
|
AnyAgent,
|
|
30
|
-
EventsFromAgent,
|
|
31
27
|
AgentInteractInput,
|
|
32
28
|
} from './types';
|
|
33
29
|
import { simpleStrategy } from './strategies/simple';
|
|
@@ -40,7 +36,7 @@ import {
|
|
|
40
36
|
} from 'ai';
|
|
41
37
|
import { createAgentMiddleware } from './middleware';
|
|
42
38
|
|
|
43
|
-
export const agentLogic: AgentLogic<
|
|
39
|
+
export const agentLogic: AgentLogic<any> = fromTransition(
|
|
44
40
|
(state, event, { emit }) => {
|
|
45
41
|
switch (event.type) {
|
|
46
42
|
case 'agent.feedback': {
|
|
@@ -92,14 +88,15 @@ export const agentLogic: AgentLogic<AnyEventObject> = fromTransition(
|
|
|
92
88
|
messages: [],
|
|
93
89
|
observations: [],
|
|
94
90
|
decisions: [],
|
|
95
|
-
} as AgentMemoryContext)
|
|
91
|
+
} as AgentMemoryContext<any>)
|
|
96
92
|
);
|
|
97
93
|
|
|
98
94
|
export function createAgent<
|
|
99
95
|
const TContextSchema extends ZodContextMapping,
|
|
100
96
|
const TEventSchemas extends ZodEventMapping,
|
|
101
97
|
TEvents extends EventObject = EventsFromZodEventMapping<TEventSchemas>,
|
|
102
|
-
TContext = ContextFromZodContextMapping<TContextSchema
|
|
98
|
+
TContext = ContextFromZodContextMapping<TContextSchema>,
|
|
99
|
+
TAgent extends AnyAgent = Agent<TContextSchema, TEventSchemas>
|
|
103
100
|
>({
|
|
104
101
|
id,
|
|
105
102
|
description: description,
|
|
@@ -108,7 +105,7 @@ export function createAgent<
|
|
|
108
105
|
context,
|
|
109
106
|
episodeId,
|
|
110
107
|
strategy = simpleStrategy,
|
|
111
|
-
logic = agentLogic as AgentLogic<
|
|
108
|
+
logic = agentLogic as AgentLogic<any>,
|
|
112
109
|
}: {
|
|
113
110
|
/**
|
|
114
111
|
* The unique identifier for the agent.
|
|
@@ -142,11 +139,11 @@ export function createAgent<
|
|
|
142
139
|
*/
|
|
143
140
|
getMemory?: (
|
|
144
141
|
agent: Agent<TContextSchema, TEventSchemas>
|
|
145
|
-
) => AgentLongTermMemory
|
|
142
|
+
) => AgentLongTermMemory<TAgent>;
|
|
146
143
|
/**
|
|
147
144
|
* Agent logic
|
|
148
145
|
*/
|
|
149
|
-
logic?: AgentLogic<
|
|
146
|
+
logic?: AgentLogic<TAgent>;
|
|
150
147
|
model: LanguageModel;
|
|
151
148
|
episodeId?: string;
|
|
152
149
|
}): Agent<TContextSchema, TEventSchemas> {
|
|
@@ -167,7 +164,7 @@ export class Agent<
|
|
|
167
164
|
const TEventSchemas extends ZodEventMapping,
|
|
168
165
|
TEvents extends EventObject = EventsFromZodEventMapping<TEventSchemas>,
|
|
169
166
|
TContext = ContextFromZodContextMapping<TContextSchema>
|
|
170
|
-
> extends Actor<AgentLogic<
|
|
167
|
+
> extends Actor<AgentLogic<any>> {
|
|
171
168
|
/**
|
|
172
169
|
* The name of the agent. All agents with the same name are related and
|
|
173
170
|
* able to share experiences (observations, feedback) with each other.
|
|
@@ -186,11 +183,11 @@ export class Agent<
|
|
|
186
183
|
// context: Compute<TContext>;
|
|
187
184
|
// };
|
|
188
185
|
public model: LanguageModel;
|
|
189
|
-
public memory: AgentLongTermMemory | undefined;
|
|
186
|
+
public memory: AgentLongTermMemory<this> | undefined;
|
|
190
187
|
public defaultOptions: AgentDecideOptions<AnyAgent> | undefined; // todo
|
|
191
188
|
|
|
192
189
|
constructor({
|
|
193
|
-
logic = agentLogic as AgentLogic<
|
|
190
|
+
logic = agentLogic as AgentLogic<any>,
|
|
194
191
|
id,
|
|
195
192
|
name,
|
|
196
193
|
description,
|
|
@@ -200,7 +197,7 @@ export class Agent<
|
|
|
200
197
|
episodeId,
|
|
201
198
|
strategy = simpleStrategy,
|
|
202
199
|
}: {
|
|
203
|
-
logic: AgentLogic<
|
|
200
|
+
logic: AgentLogic<any>;
|
|
204
201
|
id?: string;
|
|
205
202
|
name?: string;
|
|
206
203
|
description?: string;
|
|
@@ -262,6 +259,7 @@ export class Agent<
|
|
|
262
259
|
public addFeedback(feedbackInput: AgentFeedbackInput) {
|
|
263
260
|
const feedback = {
|
|
264
261
|
...feedbackInput,
|
|
262
|
+
comment: feedbackInput.comment ?? undefined,
|
|
265
263
|
attributes: { ...feedbackInput.attributes },
|
|
266
264
|
timestamp: feedbackInput.timestamp ?? Date.now(),
|
|
267
265
|
episodeId: this.episodeId,
|
|
@@ -281,7 +279,7 @@ export class Agent<
|
|
|
281
279
|
}
|
|
282
280
|
|
|
283
281
|
public addObservation(
|
|
284
|
-
observationInput: AgentObservationInput
|
|
282
|
+
observationInput: AgentObservationInput<this>
|
|
285
283
|
): AgentObservation<any> {
|
|
286
284
|
const { prevState, event, state } = observationInput;
|
|
287
285
|
const observation = {
|
|
@@ -311,7 +309,7 @@ export class Agent<
|
|
|
311
309
|
return this.getSnapshot().context.observations;
|
|
312
310
|
}
|
|
313
311
|
|
|
314
|
-
public addDecision(decision: AgentDecision<
|
|
312
|
+
public addDecision(decision: AgentDecision<this>) {
|
|
315
313
|
this.send({
|
|
316
314
|
type: 'agent.decision',
|
|
317
315
|
decision,
|
|
@@ -383,25 +381,29 @@ export class Agent<
|
|
|
383
381
|
const actorRefCheck = isActorRef(actorRef) && actorRef.src;
|
|
384
382
|
const machine = isMachineActor(actorRef) ? actorRef.src : undefined;
|
|
385
383
|
|
|
386
|
-
let prevState: ObservedState | undefined = undefined;
|
|
384
|
+
let prevState: ObservedState<this> | undefined = undefined;
|
|
387
385
|
let subscribed = true;
|
|
388
386
|
|
|
389
387
|
const agent = this;
|
|
390
388
|
|
|
391
|
-
async function handleObservation(
|
|
389
|
+
async function handleObservation(
|
|
390
|
+
observationInput: AgentObservationInput<any>
|
|
391
|
+
) {
|
|
392
392
|
const observation = agent.addObservation(observationInput);
|
|
393
393
|
|
|
394
|
-
const
|
|
394
|
+
const interactInput = getInput?.(observation);
|
|
395
395
|
|
|
396
|
-
if (
|
|
397
|
-
const
|
|
396
|
+
if (interactInput) {
|
|
397
|
+
const decision = await agentDecide(agent, {
|
|
398
398
|
machine,
|
|
399
399
|
state: observation.state,
|
|
400
|
-
...
|
|
400
|
+
...interactInput,
|
|
401
401
|
});
|
|
402
402
|
|
|
403
|
-
if (
|
|
404
|
-
|
|
403
|
+
if (decision?.nextEvent) {
|
|
404
|
+
// @ts-ignore
|
|
405
|
+
decision.nextEvent['_decision'] = decision.id;
|
|
406
|
+
actorRef.send(decision.nextEvent);
|
|
405
407
|
}
|
|
406
408
|
}
|
|
407
409
|
|
|
@@ -420,12 +422,21 @@ export class Agent<
|
|
|
420
422
|
return;
|
|
421
423
|
}
|
|
422
424
|
|
|
425
|
+
const decisionId = inspEvent.event['_decision'] as
|
|
426
|
+
| string
|
|
427
|
+
| undefined;
|
|
428
|
+
|
|
429
|
+
const decision = decisionId
|
|
430
|
+
? agent.getDecisions().find((d) => d.id === decisionId)
|
|
431
|
+
: undefined;
|
|
432
|
+
|
|
423
433
|
const observationInput = {
|
|
424
434
|
event: inspEvent.event,
|
|
425
435
|
prevState,
|
|
426
436
|
state: inspEvent.snapshot as any,
|
|
427
437
|
machine: (actorRef as any).src,
|
|
428
|
-
|
|
438
|
+
goal: decision?.goal,
|
|
439
|
+
} satisfies AgentObservationInput<any>;
|
|
429
440
|
|
|
430
441
|
await handleObservation(observationInput);
|
|
431
442
|
},
|
|
@@ -439,6 +450,7 @@ export class Agent<
|
|
|
439
450
|
event: undefined,
|
|
440
451
|
state: actorRef.getSnapshot(),
|
|
441
452
|
machine: (actorRef as any).src,
|
|
453
|
+
goal: undefined,
|
|
442
454
|
});
|
|
443
455
|
}
|
|
444
456
|
|
|
@@ -451,7 +463,7 @@ export class Agent<
|
|
|
451
463
|
}
|
|
452
464
|
|
|
453
465
|
public observe<TActor extends ActorRefLike>(actorRef: TActor): Subscription {
|
|
454
|
-
let prevState: ObservedState = actorRef.getSnapshot();
|
|
466
|
+
let prevState: ObservedState<this> = actorRef.getSnapshot();
|
|
455
467
|
const actorRefCheck = isActorRef(actorRef);
|
|
456
468
|
|
|
457
469
|
const sub = actorRefCheck
|
|
@@ -464,12 +476,20 @@ export class Agent<
|
|
|
464
476
|
return;
|
|
465
477
|
}
|
|
466
478
|
|
|
479
|
+
const decisionId = inspEvent.event['_decision'] as
|
|
480
|
+
| string
|
|
481
|
+
| undefined;
|
|
482
|
+
const decision = decisionId
|
|
483
|
+
? this.getDecisions().find((d) => d.id === decisionId)
|
|
484
|
+
: undefined;
|
|
485
|
+
|
|
467
486
|
const observationInput = {
|
|
468
487
|
event: inspEvent.event,
|
|
469
488
|
prevState,
|
|
470
489
|
state: inspEvent.snapshot as any,
|
|
471
490
|
machine: (actorRef as any).src,
|
|
472
|
-
|
|
491
|
+
goal: decision?.goal,
|
|
492
|
+
} satisfies AgentObservationInput<this>;
|
|
473
493
|
|
|
474
494
|
prevState = observationInput.state;
|
|
475
495
|
|
|
@@ -498,7 +518,7 @@ export class Agent<
|
|
|
498
518
|
*/
|
|
499
519
|
public async decide(
|
|
500
520
|
opts: AgentDecideOptions<this>
|
|
501
|
-
): Promise<AgentDecision<
|
|
521
|
+
): Promise<AgentDecision<this> | undefined> {
|
|
502
522
|
return agentDecide(this, opts);
|
|
503
523
|
}
|
|
504
524
|
}
|
package/src/decide.ts
CHANGED
|
@@ -6,15 +6,15 @@ import {
|
|
|
6
6
|
AgentDecision,
|
|
7
7
|
AgentDecideInput,
|
|
8
8
|
TransitionData,
|
|
9
|
-
|
|
9
|
+
EventFromAgent,
|
|
10
10
|
} from './types';
|
|
11
11
|
import { getTransitions } from './utils';
|
|
12
12
|
import { CoreMessage, CoreTool, tool } from 'ai';
|
|
13
13
|
|
|
14
|
-
export async function agentDecide<
|
|
15
|
-
agent:
|
|
16
|
-
options: AgentDecideOptions<
|
|
17
|
-
): Promise<AgentDecision<
|
|
14
|
+
export async function agentDecide<TAgent extends AnyAgent>(
|
|
15
|
+
agent: TAgent,
|
|
16
|
+
options: AgentDecideOptions<TAgent>
|
|
17
|
+
): Promise<AgentDecision<TAgent> | undefined> {
|
|
18
18
|
const resolvedOptions = {
|
|
19
19
|
...agent.defaultOptions,
|
|
20
20
|
...options,
|
|
@@ -45,12 +45,17 @@ export async function agentDecide<T extends AnyAgent>(
|
|
|
45
45
|
|
|
46
46
|
let decision: AgentDecision<any> | undefined;
|
|
47
47
|
|
|
48
|
+
const minimalState = {
|
|
49
|
+
value: state.value,
|
|
50
|
+
context: state.context,
|
|
51
|
+
};
|
|
52
|
+
|
|
48
53
|
while (attempts++ < maxAttempts) {
|
|
49
54
|
decision = await strategy(agent, {
|
|
50
55
|
model,
|
|
51
56
|
goal,
|
|
52
57
|
events: filteredEventSchemas,
|
|
53
|
-
state,
|
|
58
|
+
state: minimalState,
|
|
54
59
|
machine,
|
|
55
60
|
messages: messages as CoreMessage[], // TODO: fix UIMessage thing
|
|
56
61
|
...otherDecideInput,
|
|
@@ -68,7 +73,7 @@ export async function agentDecide<T extends AnyAgent>(
|
|
|
68
73
|
|
|
69
74
|
export function fromDecision<T extends AnyAgent>(
|
|
70
75
|
agent: T,
|
|
71
|
-
defaultInput?: AgentDecideInput<
|
|
76
|
+
defaultInput?: AgentDecideInput<EventFromAgent<T>>
|
|
72
77
|
): AgentDecisionLogic<any> {
|
|
73
78
|
return fromPromise(async ({ input, self }) => {
|
|
74
79
|
const parentRef = self._parent;
|
|
@@ -82,15 +87,10 @@ export function fromDecision<T extends AnyAgent>(
|
|
|
82
87
|
...defaultInput,
|
|
83
88
|
...inputObject,
|
|
84
89
|
};
|
|
85
|
-
const state = {
|
|
86
|
-
value: snapshot.value,
|
|
87
|
-
context: resolvedInput.context,
|
|
88
|
-
};
|
|
89
90
|
|
|
90
91
|
const decision = await agentDecide(agent, {
|
|
91
92
|
machine: (parentRef as AnyActor).logic,
|
|
92
93
|
state: snapshot,
|
|
93
|
-
context: resolvedInput.context,
|
|
94
94
|
execute: async (event) => {
|
|
95
95
|
parentRef.send(event);
|
|
96
96
|
},
|
|
@@ -10,11 +10,12 @@ import { simpleStrategy } from './simple';
|
|
|
10
10
|
import { convertToXml } from '../utils';
|
|
11
11
|
|
|
12
12
|
const chainOfThoughtPromptTemplate: PromptTemplate<any> = ({
|
|
13
|
+
stateValue,
|
|
13
14
|
context,
|
|
14
15
|
goal,
|
|
15
16
|
}) => {
|
|
16
17
|
return `
|
|
17
|
-
${convertToXml({ context, goal })}
|
|
18
|
+
${convertToXml({ stateValue, context, goal })}
|
|
18
19
|
|
|
19
20
|
How would you achieve the goal? Think step-by-step.
|
|
20
21
|
`.trim();
|
|
@@ -25,7 +26,8 @@ export async function chainOfThoughtStrategy<T extends AnyAgent>(
|
|
|
25
26
|
input: AgentDecideInput<any>
|
|
26
27
|
): Promise<AgentDecision<any> | undefined> {
|
|
27
28
|
const prompt = chainOfThoughtPromptTemplate({
|
|
28
|
-
|
|
29
|
+
stateValue: input.state.value,
|
|
30
|
+
context: input.context ?? input.state.context,
|
|
29
31
|
goal: input.goal,
|
|
30
32
|
});
|
|
31
33
|
|
|
@@ -13,10 +13,14 @@ import { z } from 'zod';
|
|
|
13
13
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
14
14
|
import Ajv from 'ajv';
|
|
15
15
|
import { AnyMachineSnapshot } from 'xstate';
|
|
16
|
+
import { randomId } from '../utils';
|
|
16
17
|
|
|
17
18
|
const ajv = new Ajv();
|
|
18
19
|
|
|
19
|
-
function observedStatesEqual(
|
|
20
|
+
function observedStatesEqual(
|
|
21
|
+
state1: ObservedState<any>,
|
|
22
|
+
state2: ObservedState<any>
|
|
23
|
+
) {
|
|
20
24
|
// check state value && state context
|
|
21
25
|
return (
|
|
22
26
|
JSON.stringify(state1.value) === JSON.stringify(state2.value) &&
|
|
@@ -24,7 +28,7 @@ function observedStatesEqual(state1: ObservedState, state2: ObservedState) {
|
|
|
24
28
|
);
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
function trimSteps(steps: AgentStep<any>[], currentState: ObservedState) {
|
|
31
|
+
function trimSteps(steps: AgentStep<any>[], currentState: ObservedState<any>) {
|
|
28
32
|
const index = steps.findIndex(
|
|
29
33
|
(step) => step.state && observedStatesEqual(step.state, currentState)
|
|
30
34
|
);
|
|
@@ -162,6 +166,7 @@ Examples:
|
|
|
162
166
|
const nextStep = leastWeightPath?.steps[0];
|
|
163
167
|
|
|
164
168
|
return {
|
|
169
|
+
id: randomId(),
|
|
165
170
|
strategy: 'shortestPath',
|
|
166
171
|
episodeId: agent.episodeId,
|
|
167
172
|
goal: input.goal,
|
package/src/strategies/simple.ts
CHANGED
|
@@ -32,7 +32,8 @@ export async function simpleStrategy<T extends AnyAgent>(
|
|
|
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
34
|
const prompt = simpleStrategyPromptTemplate({
|
|
35
|
-
|
|
35
|
+
stateValue: input.state.value,
|
|
36
|
+
context: input.context ?? input.state.context,
|
|
36
37
|
goal: input.goal,
|
|
37
38
|
});
|
|
38
39
|
|
|
@@ -40,16 +41,7 @@ export async function simpleStrategy<T extends AnyAgent>(
|
|
|
40
41
|
|
|
41
42
|
const model = input.model ? agent.wrap(input.model) : agent.model;
|
|
42
43
|
|
|
43
|
-
const {
|
|
44
|
-
state,
|
|
45
|
-
context,
|
|
46
|
-
machine,
|
|
47
|
-
prevDecision,
|
|
48
|
-
events,
|
|
49
|
-
goal,
|
|
50
|
-
model: _,
|
|
51
|
-
...rest
|
|
52
|
-
} = input;
|
|
44
|
+
const { state, machine, events, goal, model: _, ...rest } = input;
|
|
53
45
|
|
|
54
46
|
const machineState =
|
|
55
47
|
input.machine && input.state
|
|
@@ -87,6 +79,7 @@ export async function simpleStrategy<T extends AnyAgent>(
|
|
|
87
79
|
}
|
|
88
80
|
|
|
89
81
|
return {
|
|
82
|
+
id: randomId(),
|
|
90
83
|
strategy: 'simple',
|
|
91
84
|
goal: input.goal,
|
|
92
85
|
goalState: input.state,
|
|
@@ -109,7 +102,3 @@ export async function simpleStrategy<T extends AnyAgent>(
|
|
|
109
102
|
],
|
|
110
103
|
};
|
|
111
104
|
}
|
|
112
|
-
|
|
113
|
-
export function createSimpleStrategy<T extends AnyAgent>() {
|
|
114
|
-
return simpleStrategy;
|
|
115
|
-
}
|
|
@@ -3,6 +3,9 @@ import { wrapInXml } from '../utils';
|
|
|
3
3
|
|
|
4
4
|
export const defaultTextTemplate: PromptTemplate<any> = (data) => {
|
|
5
5
|
const preamble = [
|
|
6
|
+
data.stateValue
|
|
7
|
+
? wrapInXml('stateValue', JSON.stringify(data.stateValue))
|
|
8
|
+
: undefined,
|
|
6
9
|
data.context
|
|
7
10
|
? wrapInXml('context', JSON.stringify(data.context))
|
|
8
11
|
: undefined,
|
package/src/text.ts
CHANGED
|
@@ -28,10 +28,10 @@ import {
|
|
|
28
28
|
* @param options
|
|
29
29
|
* @returns
|
|
30
30
|
*/
|
|
31
|
-
export async function getMessages(
|
|
32
|
-
agent:
|
|
31
|
+
export async function getMessages<TAgent extends AnyAgent>(
|
|
32
|
+
agent: TAgent,
|
|
33
33
|
prompt: string,
|
|
34
|
-
options: Omit<AgentGenerateTextOptions
|
|
34
|
+
options: Omit<AgentGenerateTextOptions<TAgent>, 'prompt'>
|
|
35
35
|
): Promise<CoreMessage[]> {
|
|
36
36
|
let messages: CoreMessage[] = [];
|
|
37
37
|
if (typeof options.messages === 'function') {
|
|
@@ -48,13 +48,13 @@ export async function getMessages(
|
|
|
48
48
|
return messages;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
export function fromTextStream<
|
|
52
|
-
agent:
|
|
53
|
-
options?: AgentStreamTextOptions
|
|
51
|
+
export function fromTextStream<TAgent extends AnyAgent>(
|
|
52
|
+
agent: TAgent,
|
|
53
|
+
options?: AgentStreamTextOptions<TAgent>
|
|
54
54
|
): ObservableActorLogic<
|
|
55
55
|
{ textDelta: string },
|
|
56
|
-
Omit<AgentStreamTextOptions
|
|
57
|
-
context?:
|
|
56
|
+
Omit<AgentStreamTextOptions<TAgent>, 'context'> & {
|
|
57
|
+
context?: Record<string, any>;
|
|
58
58
|
}
|
|
59
59
|
> {
|
|
60
60
|
const template = options?.template ?? defaultTextTemplate;
|
|
@@ -106,13 +106,13 @@ export function fromTextStream<T extends AnyAgent>(
|
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
export function fromText<
|
|
110
|
-
agent:
|
|
111
|
-
options?: AgentGenerateTextOptions
|
|
109
|
+
export function fromText<TAgent extends AnyAgent>(
|
|
110
|
+
agent: TAgent,
|
|
111
|
+
options?: AgentGenerateTextOptions<TAgent>
|
|
112
112
|
): PromiseActorLogic<
|
|
113
113
|
GenerateTextResult<Record<string, CoreTool<any, any>>>,
|
|
114
|
-
Omit<AgentGenerateTextOptions
|
|
115
|
-
context?:
|
|
114
|
+
Omit<AgentGenerateTextOptions<TAgent>, 'context'> & {
|
|
115
|
+
context?: Record<string, any>;
|
|
116
116
|
}
|
|
117
117
|
> {
|
|
118
118
|
const resolvedOptions = {
|