@statelyai/agent 1.1.6 → 2.0.0-alpha.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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai-sdk.cjs +249 -0
  3. package/dist/ai-sdk.d.cts +168 -0
  4. package/dist/ai-sdk.d.mts +168 -0
  5. package/dist/ai-sdk.mjs +241 -0
  6. package/dist/cli.cjs +63 -0
  7. package/dist/cli.d.cts +1 -0
  8. package/dist/cli.d.mts +1 -0
  9. package/dist/cli.mjs +64 -0
  10. package/dist/decision-FTmbqSEe.mjs +938 -0
  11. package/dist/decision-pC-bY2DE.cjs +1231 -0
  12. package/dist/index.cjs +54 -0
  13. package/dist/index.d.cts +1217 -0
  14. package/dist/index.d.mts +1194 -405
  15. package/dist/index.mjs +3 -588
  16. package/dist/openai-compat.cjs +319 -0
  17. package/dist/openai-compat.d.cts +98 -0
  18. package/dist/openai-compat.d.mts +98 -0
  19. package/dist/openai-compat.mjs +312 -0
  20. package/dist/src-CjpHDU8F.mjs +2445 -0
  21. package/dist/src-DcRsWPfV.cjs +2564 -0
  22. package/dist/text-logic-1ZQkO3zr.d.cts +682 -0
  23. package/dist/text-logic-2EMJIS-n.d.mts +682 -0
  24. package/dist/types-BHjeDdch.d.cts +208 -0
  25. package/dist/types-Cq1YlAQ6.d.mts +208 -0
  26. package/dist/utils-CWUCa3pF.d.mts +108 -0
  27. package/dist/utils-lK1wnL2i.d.cts +108 -0
  28. package/dist/zod.cjs +31 -0
  29. package/dist/zod.d.cts +30 -0
  30. package/dist/zod.d.mts +30 -0
  31. package/dist/zod.mjs +30 -0
  32. package/package.json +109 -28
  33. package/readme.md +144 -6
  34. package/schemas/agent-workflow.json +527 -0
  35. package/.changeset/README.md +0 -8
  36. package/.changeset/config.json +0 -11
  37. package/.env.template +0 -3
  38. package/.github/actions/ci-setup/action.yml +0 -24
  39. package/.github/workflows/release.yml +0 -46
  40. package/.vscode/launch.json +0 -28
  41. package/CHANGELOG.md +0 -222
  42. package/dist/index.d.ts +0 -428
  43. package/dist/index.js +0 -621
  44. package/examples/chatbot.ts +0 -71
  45. package/examples/cot.ts +0 -89
  46. package/examples/email.ts +0 -118
  47. package/examples/example.ts +0 -81
  48. package/examples/goal.ts +0 -94
  49. package/examples/helpers/helpers.ts +0 -17
  50. package/examples/helpers/loader.ts +0 -32
  51. package/examples/helpers/runner.ts +0 -27
  52. package/examples/joke.ts +0 -225
  53. package/examples/multi.ts +0 -103
  54. package/examples/newspaper.ts +0 -324
  55. package/examples/number.ts +0 -102
  56. package/examples/raffle.ts +0 -105
  57. package/examples/sandbox.ts +0 -28
  58. package/examples/simple.ts +0 -39
  59. package/examples/support.ts +0 -147
  60. package/examples/ticTacToe.ts +0 -224
  61. package/examples/todo.ts +0 -137
  62. package/examples/tutor.ts +0 -100
  63. package/examples/verify.ts +0 -120
  64. package/examples/weather.ts +0 -178
  65. package/examples/wiki.ts +0 -30
  66. package/examples/word.ts +0 -171
  67. package/src/adapters/vercel.ts +0 -7
  68. package/src/agent-experimental.ts +0 -221
  69. package/src/agent.test.ts +0 -506
  70. package/src/agent.ts +0 -300
  71. package/src/decision.test.ts +0 -179
  72. package/src/decision.ts +0 -84
  73. package/src/index.ts +0 -4
  74. package/src/memory.ts +0 -25
  75. package/src/planners/shortestPathPlanner.ts +0 -22
  76. package/src/planners/simplePlanner.ts +0 -139
  77. package/src/schemas.ts +0 -11
  78. package/src/strategies/chain-of-note.ts +0 -155
  79. package/src/templates/defaultText.ts +0 -18
  80. package/src/text.ts +0 -241
  81. package/src/types.ts +0 -499
  82. package/src/utils.ts +0 -72
  83. package/tsconfig.json +0 -109
  84. package/vitest.config.ts +0 -9
@@ -1,221 +0,0 @@
1
- // // type AgentExperiences<TState, TReward> = Record<
2
- // // string, // serialized state
3
- // // Record<
4
- // // string, // serialized event
5
- // // {
6
- // // state: TState;
7
- // // reward: TReward;
8
- // // }
9
- // // >
10
-
11
- // import OpenAI from 'openai';
12
- // import {
13
- // AnyEventObject,
14
- // EventObject,
15
- // AnyActorLogic,
16
- // AnyMachineSnapshot,
17
- // ActorRef,
18
- // AnyActorRef,
19
- // SnapshotFrom,
20
- // EventFrom,
21
- // } from 'xstate';
22
- // import { getToolCalls } from './adapters/openai';
23
- // import { ZodEventMapping } from './schemas';
24
-
25
- // // >;
26
- // interface AgentExperience<TState, TEvent extends AnyEventObject> {
27
- // prevState: TState | undefined;
28
- // event: TEvent;
29
- // nextState: TState;
30
- // }
31
-
32
- // type AgentPlan<TState, TEvent extends EventObject> = Array<{
33
- // /**
34
- // * The current state
35
- // */
36
- // state: TState;
37
- // /**
38
- // * The event to execute
39
- // */
40
- // event: TEvent;
41
- // /**
42
- // * The expected next state
43
- // */
44
- // nextState?: TState;
45
- // }>;
46
-
47
- // interface AgentModel<
48
- // // TLogic extends AnyActorLogic,
49
- // TReward,
50
- // TState,
51
- // TEvent extends EventObject
52
- // > {
53
- // // policy: ({
54
- // // logic,
55
- // // state,
56
- // // goal,
57
- // // }: {
58
- // // logic: TLogic;
59
- // // state: TState;
60
- // // goal: string;
61
- // // }) => Promise<AgentPlan<TState>>;
62
- // getExperiences: () => Promise<Array<AgentExperience<TState, TEvent>>>; // TODO: TLogic instead?
63
- // addExperience: (experience: AgentExperience<TState, TEvent>) => void;
64
- // getLogic: ({
65
- // experiences,
66
- // }: {
67
- // experiences: Array<AgentExperience<TState, TEvent>>; // TODO: TLogic instead?
68
- // }) => Promise<AnyActorLogic>;
69
- // getNextEvents: ({
70
- // logic,
71
- // state,
72
- // }: {
73
- // logic: AnyActorLogic;
74
- // state: TState;
75
- // }) => Promise<AnyEventObject[]>;
76
- // getPlans: ({
77
- // logic,
78
- // state,
79
- // goals,
80
- // }: {
81
- // logic: AnyActorLogic;
82
- // state: TState;
83
- // goals: string[];
84
- // }) => Promise<Array<AgentPlan<TState, TEvent>>>;
85
- // getReward: ({
86
- // logic,
87
- // state,
88
- // goals,
89
- // action,
90
- // }: {
91
- // logic: AnyActorLogic;
92
- // state: TState;
93
- // goals: string[];
94
- // action: EventObject;
95
- // }) => Promise<TReward>;
96
- // }
97
-
98
- // interface AgentLogic<T> {
99
- // /**
100
- // * The next possible actions (represented by events) that the agent can take
101
- // * based on the current state of the environment
102
- // */
103
- // getActions(state: T): Promise<AnyEventObject[]>;
104
- // getPlan(state: T, goal: any): Promise<Array<[T, EventObject]>>;
105
- // }
106
-
107
- // interface Agent<TState extends AnyMachineSnapshot, TEvent extends EventObject> {
108
- // act: (env: ActorRef<TState, TEvent>) => Promise<void>;
109
- // }
110
-
111
- // function createAgent2<TEnvironment extends AnyActorRef>(
112
- // openai: OpenAI,
113
- // // logic: AnyActorLogic,
114
- // // input: InputFrom<TLogic>,
115
- // getGoals: (state: SnapshotFrom<TEnvironment>) => string | string[],
116
- // schemas: ZodEventMapping
117
- // ): Agent<SnapshotFrom<TEnvironment>, EventFrom<TEnvironment>> {
118
- // const experiences: Array<AgentExperience<any, any>> = [];
119
-
120
- // const agentModel: AgentModel<
121
- // any,
122
- // SnapshotFrom<TEnvironment>,
123
- // EventFrom<TEnvironment>
124
- // > = {
125
- // // policy: async ({ logic, state, goal }) => {
126
- // // const toolEvents = await getToolCalls(
127
- // // openai,
128
- // // goal,
129
- // // state,
130
- // // 'gpt-4-1106-preview',
131
- // // (eventType) => eventType.startsWith('agent.'),
132
- // // schemas
133
- // // );
134
- // // console.log(toolEvents);
135
- // // return toolEvents.map((te) => ({
136
- // // state,
137
- // // event: te as EventFromLogic<TLogic>,
138
- // // }));
139
- // // },
140
- // addExperience: (experience) => {
141
- // experiences.push(experience);
142
- // },
143
- // getExperiences: async () => experiences,
144
- // getLogic: async ({ experiences }) => {
145
- // return null as any; // TODO
146
- // },
147
- // getNextEvents: async ({ logic, state }) => {
148
- // return [];
149
- // },
150
- // getReward: async ({ logic, state, goals, action }) => {
151
- // return 0;
152
- // },
153
- // getPlans: async ({ logic, state, goals }) => {
154
- // if (!goals[0]) {
155
- // return [];
156
- // }
157
-
158
- // const toolEvents = await getToolCalls(
159
- // openai,
160
- // goals[0] + '\nOnly make a single tool call.',
161
- // state as any,
162
- // 'gpt-3.5-turbo-16k-0613',
163
- // (eventType) => eventType.startsWith('agent.'),
164
- // schemas
165
- // );
166
-
167
- // console.log(toolEvents);
168
-
169
- // return [
170
- // toolEvents.map((toolEvent) => ({
171
- // state,
172
- // event: toolEvent as EventFrom<TEnvironment>,
173
- // })),
174
- // ];
175
- // },
176
- // };
177
-
178
- // // const actor = createActor(logic, {
179
- // // input,
180
- // // inspect: (inspEv) => {
181
- // // if (inspEv.type === '@xstate.snapshot') {
182
- // // agentModel.addExperience({
183
- // // prevState: experiences[experiences.length - 1]?.nextState,
184
- // // nextState: (inspEv.snapshot as AnyMachineSnapshot).value,
185
- // // event: inspEv.event as EventFromLogic<TLogic>,
186
- // // });
187
- // // }
188
- // // },
189
- // // });
190
-
191
- // return {
192
- // act: async (actorRef) => {
193
- // const state = actorRef.getSnapshot();
194
- // // @ts-ignore
195
- // console.log(state.value, state.context);
196
- // const experiences = await agentModel.getExperiences();
197
- // const goals = toArray(getGoals(state));
198
- // console.log('Goal:', goals);
199
-
200
- // const nextPlans = await agentModel.getPlans({
201
- // logic: await agentModel.getLogic({ experiences }),
202
- // goals,
203
- // state,
204
- // });
205
-
206
- // const nextStep = nextPlans?.[0]?.[0];
207
-
208
- // // TODO: race conditions!
209
- // if (nextStep) {
210
- // console.log('nextStep', nextStep?.event);
211
- // actorRef.send(nextStep.event);
212
- // } else {
213
- // console.log('No next step');
214
- // }
215
- // },
216
- // } satisfies Agent<SnapshotFrom<TEnvironment>, EventFrom<TEnvironment>>; // TODO: fix types
217
- // }
218
-
219
- // function toArray<T>(value: T | T[]): T[] {
220
- // return Array.isArray(value) ? value : [value];
221
- // }
package/src/agent.test.ts DELETED
@@ -1,506 +0,0 @@
1
- import { test, expect, vi } from 'vitest';
2
- import {
3
- AgentGenerateTextResult,
4
- AgentMessage,
5
- createAgent,
6
- type AIAdapter,
7
- } from './';
8
- import { createActor, createMachine } from 'xstate';
9
- import { GenerateTextResult } from 'ai';
10
- import { z } from 'zod';
11
-
12
- test('an agent has the expected interface', () => {
13
- const agent = createAgent({
14
- name: 'test',
15
- events: {},
16
- model: {} as any,
17
- });
18
-
19
- expect(agent.decide).toBeDefined();
20
- expect(agent.generateText).toBeDefined();
21
- expect(agent.streamText).toBeDefined();
22
-
23
- expect(agent.addMessage).toBeDefined();
24
- expect(agent.addObservation).toBeDefined();
25
- expect(agent.addFeedback).toBeDefined();
26
- expect(agent.addPlan).toBeDefined();
27
-
28
- expect(agent.getMessages).toBeDefined();
29
- expect(agent.getObservations).toBeDefined();
30
- expect(agent.getFeedback).toBeDefined();
31
- expect(agent.getPlans).toBeDefined();
32
-
33
- expect(agent.interact).toBeDefined();
34
- });
35
-
36
- test('agent.addMessage() adds to message history', () => {
37
- const agent = createAgent({
38
- name: 'test',
39
- events: {},
40
- model: {} as any,
41
- });
42
-
43
- agent.addMessage({
44
- content: 'msg 1',
45
- role: 'user',
46
- });
47
-
48
- const messageHistory = agent.addMessage({
49
- content: 'response 1',
50
- role: 'assistant',
51
- });
52
-
53
- expect(messageHistory.sessionId).toEqual(agent.sessionId);
54
-
55
- expect(agent.select((c) => c.messages)).toContainEqual(
56
- expect.objectContaining({
57
- content: 'msg 1',
58
- })
59
- );
60
- expect(agent.getMessages()).toContainEqual(
61
- expect.objectContaining({
62
- content: 'msg 1',
63
- })
64
- );
65
-
66
- expect(agent.select((c) => c.messages)).toContainEqual(
67
- expect.objectContaining({
68
- content: 'response 1',
69
- sessionId: expect.any(String),
70
- timestamp: expect.any(Number),
71
- })
72
- );
73
- expect(agent.getMessages()).toContainEqual(
74
- expect.objectContaining({
75
- content: 'response 1',
76
- sessionId: expect.any(String),
77
- timestamp: expect.any(Number),
78
- })
79
- );
80
- });
81
-
82
- test('agent.addFeedback() adds to feedback', () => {
83
- const agent = createAgent({
84
- name: 'test',
85
- events: {},
86
- model: {} as any,
87
- });
88
-
89
- const feedback = agent.addFeedback({
90
- attributes: {
91
- score: -1,
92
- },
93
- goal: 'Win the game',
94
- observationId: 'obs-1',
95
- });
96
-
97
- expect(feedback.sessionId).toEqual(agent.sessionId);
98
-
99
- expect(agent.select((c) => c.feedback)).toContainEqual(
100
- expect.objectContaining({
101
- attributes: {
102
- score: -1,
103
- },
104
- goal: 'Win the game',
105
- observationId: 'obs-1',
106
- sessionId: expect.any(String),
107
- timestamp: expect.any(Number),
108
- })
109
- );
110
- expect(agent.getFeedback()).toContainEqual(
111
- expect.objectContaining({
112
- attributes: {
113
- score: -1,
114
- },
115
- goal: 'Win the game',
116
- observationId: 'obs-1',
117
- sessionId: expect.any(String),
118
- timestamp: expect.any(Number),
119
- })
120
- );
121
- });
122
-
123
- test('agent.addObservation() adds to observations', () => {
124
- const agent = createAgent({
125
- name: 'test',
126
- events: {},
127
- model: {} as any,
128
- });
129
-
130
- const observation = agent.addObservation({
131
- prevState: { value: 'playing', context: {} },
132
- event: { type: 'play', position: 3 },
133
- state: { value: 'lost', context: {} },
134
- });
135
-
136
- expect(observation.sessionId).toEqual(agent.sessionId);
137
-
138
- expect(agent.select((c) => c.observations)).toContainEqual(
139
- expect.objectContaining({
140
- prevState: { value: 'playing', context: {} },
141
- event: { type: 'play', position: 3 },
142
- state: { value: 'lost', context: {} },
143
- sessionId: expect.any(String),
144
- timestamp: expect.any(Number),
145
- })
146
- );
147
- });
148
-
149
- test('agent.addObservation() adds to observations with machine hash', () => {
150
- const agent = createAgent({
151
- name: 'test',
152
- events: {},
153
- model: {} as any,
154
- });
155
-
156
- const machine = createMachine({
157
- initial: 'playing',
158
- states: {
159
- playing: {
160
- on: {
161
- play: 'lost',
162
- },
163
- },
164
- lost: {},
165
- },
166
- });
167
-
168
- const observation = agent.addObservation({
169
- prevState: { value: 'playing', context: {} },
170
- event: { type: 'play', position: 3 },
171
- state: { value: 'lost', context: {} },
172
- machine,
173
- });
174
-
175
- expect(observation.sessionId).toEqual(agent.sessionId);
176
-
177
- expect(agent.select((c) => c.observations)).toContainEqual(
178
- expect.objectContaining({
179
- prevState: { value: 'playing', context: {} },
180
- event: { type: 'play', position: 3 },
181
- state: { value: 'lost', context: {} },
182
- machineHash: expect.any(String),
183
- sessionId: expect.any(String),
184
- timestamp: expect.any(Number),
185
- })
186
- );
187
- });
188
-
189
- test('agent.interact() observes machine actors (no 2nd arg)', () => {
190
- const machine = createMachine({
191
- initial: 'a',
192
- states: {
193
- a: {
194
- on: { NEXT: 'b' },
195
- },
196
- b: {},
197
- },
198
- });
199
-
200
- const agent = createAgent({
201
- name: 'test',
202
- events: {},
203
- model: {} as any,
204
- });
205
-
206
- const actor = createActor(machine);
207
-
208
- agent.interact(actor);
209
-
210
- actor.start();
211
-
212
- expect(agent.select((c) => c.observations)).toContainEqual(
213
- expect.objectContaining({
214
- prevState: undefined,
215
- state: expect.objectContaining({ value: 'a' }),
216
- })
217
- );
218
- expect(agent.getObservations()).toContainEqual(
219
- expect.objectContaining({
220
- prevState: undefined,
221
- state: expect.objectContaining({ value: 'a' }),
222
- })
223
- );
224
-
225
- actor.send({ type: 'NEXT' });
226
-
227
- expect(agent.select((c) => c.observations)).toContainEqual(
228
- expect.objectContaining({
229
- prevState: expect.objectContaining({ value: 'a' }),
230
- event: { type: 'NEXT' },
231
- state: expect.objectContaining({ value: 'b' }),
232
- })
233
- );
234
- });
235
-
236
- test('Agents can use a custom adapter', async () => {
237
- const adapter = {
238
- generateText: async () => {
239
- return {
240
- text: 'Response',
241
- } as any;
242
- },
243
- } as unknown as AIAdapter;
244
-
245
- const agent = createAgent({
246
- name: 'test',
247
- events: {},
248
- adapter,
249
- model: {} as any,
250
- });
251
-
252
- const res = await agent.generateText({
253
- prompt: 'Question?',
254
- });
255
-
256
- expect(res.text).toEqual('Response');
257
- });
258
-
259
- test('You can listen for feedback events', () => {
260
- const fn = vi.fn();
261
- const agent = createAgent({
262
- name: 'test',
263
- events: {},
264
- adapter: {} as any,
265
- model: {} as any,
266
- });
267
-
268
- agent.on('feedback', fn);
269
-
270
- agent.addFeedback({
271
- attributes: {
272
- score: -1,
273
- },
274
- goal: 'Win the game',
275
- observationId: 'obs-1',
276
- });
277
-
278
- expect(fn).toHaveBeenCalled();
279
- });
280
-
281
- test('You can listen for plan events', async () => {
282
- const fn = vi.fn();
283
- const agent = createAgent({
284
- name: 'test',
285
- model: {} as any,
286
- events: {
287
- WIN: z.object({}),
288
- },
289
- adapter: {
290
- generateText: async (arg) => {
291
- const keys = Object.keys(arg.tools!);
292
-
293
- if (keys.length !== 1) {
294
- throw new Error('Expected only 1 choice');
295
- }
296
-
297
- return {
298
- toolResults: [
299
- {
300
- result: {
301
- type: keys[0],
302
- },
303
- },
304
- ],
305
- } as any as AgentGenerateTextResult;
306
- },
307
- streamText: {} as any,
308
- },
309
- });
310
-
311
- agent.on('plan', fn);
312
-
313
- await agent.decide({
314
- goal: 'Win the game',
315
- state: {
316
- value: 'playing',
317
- context: {},
318
- },
319
- machine: createMachine({
320
- initial: 'playing',
321
- states: {
322
- playing: {
323
- on: {
324
- WIN: {
325
- target: 'won',
326
- },
327
- },
328
- },
329
- won: {},
330
- },
331
- }),
332
- });
333
-
334
- expect(fn).toHaveBeenCalledWith(
335
- expect.objectContaining({
336
- plan: expect.objectContaining({
337
- nextEvent: {
338
- type: 'WIN',
339
- },
340
- }),
341
- })
342
- );
343
- });
344
-
345
- test('agent.types provides context and event types', () => {
346
- const agent = createAgent({
347
- model: {} as any,
348
- events: {
349
- setScore: z.object({
350
- score: z.number(),
351
- }),
352
- },
353
- context: {
354
- score: z.number(),
355
- },
356
- });
357
-
358
- agent.types satisfies { context: any; events: any };
359
-
360
- agent.types.context satisfies { score: number };
361
-
362
- // @ts-expect-error
363
- agent.types.context satisfies { score: string };
364
- });
365
-
366
- test.each(['generateText', 'streamText'] as const)(
367
- 'can provide a correlation ID (%s)',
368
- async (method) => {
369
- const agent = createAgent({
370
- model: {} as any,
371
- events: {},
372
- adapter: {
373
- [method]: async (opts: any) => {
374
- const res = {
375
- text: 'response',
376
- };
377
-
378
- opts.onFinish?.(res);
379
-
380
- return res as AgentGenerateTextResult;
381
- },
382
- } as any as AIAdapter,
383
- });
384
-
385
- const promise = new Promise<AgentMessage>((res) => {
386
- agent.onMessage((msg) => {
387
- if (msg.role === 'assistant') {
388
- res(msg);
389
- }
390
- });
391
- });
392
-
393
- await agent[method]({
394
- prompt: 'hi',
395
- correlationId: 'c-1',
396
- });
397
-
398
- const msg = await promise;
399
-
400
- expect(msg.correlationId).toBe('c-1');
401
- expect(msg.parentCorrelationId).toBe(undefined);
402
- }
403
- );
404
-
405
- test.each(['generateText', 'streamText'] as const)(
406
- 'correlation IDs are automatically generated if not provided (%s)',
407
- async (method) => {
408
- const agent = createAgent({
409
- model: {} as any,
410
- events: {},
411
- adapter: {
412
- [method]: async (opts: any) => {
413
- const res = {
414
- text: 'response',
415
- };
416
-
417
- opts.onFinish?.(res);
418
-
419
- return res as AgentGenerateTextResult;
420
- },
421
- } as any as AIAdapter,
422
- });
423
-
424
- await agent[method]({
425
- prompt: 'hi',
426
- });
427
-
428
- const messages = agent.getMessages();
429
-
430
- expect(messages[0]?.correlationId).toEqual(expect.stringMatching(/.+/));
431
- expect(messages[0]?.role).toBe('user');
432
- expect(messages[1]?.correlationId).toEqual(expect.stringMatching(/.+/));
433
- expect(messages[1]?.role).toBe('assistant');
434
-
435
- expect(messages[0]!.correlationId).toEqual(messages[1]!.correlationId);
436
- }
437
- );
438
-
439
- test.each(['generateText', 'streamText'] as const)(
440
- 'can provide a parent correlation ID (%s)',
441
- async (method) => {
442
- const agent = createAgent({
443
- model: {} as any,
444
- events: {},
445
- adapter: {
446
- [method]: async (opts: any) => {
447
- const res = {
448
- text: 'response',
449
- };
450
-
451
- opts.onFinish?.(res);
452
-
453
- return res as AgentGenerateTextResult;
454
- },
455
- } as any as AIAdapter,
456
- });
457
-
458
- await agent[method]({
459
- prompt: 'hi',
460
- correlationId: 'c-1',
461
- parentCorrelationId: 'c-0',
462
- });
463
-
464
- const msg = agent.getMessages().find((msg) => msg.role === 'assistant')!;
465
-
466
- expect(msg.correlationId).toBe('c-1');
467
- expect(msg.parentCorrelationId).toBe('c-0');
468
- }
469
- );
470
-
471
- test.each(['generateText', 'streamText'] as const)(
472
- 'can add feedback to a correlation (%s)',
473
- async (method) => {
474
- const agent = createAgent({
475
- name: 'test',
476
- model: {} as any,
477
- events: {},
478
- adapter: {
479
- [method]: async (opts: any) => {
480
- const res = {
481
- text: 'response',
482
- };
483
-
484
- opts.onFinish?.(res);
485
-
486
- return res as AgentGenerateTextResult;
487
- },
488
- } as any as AIAdapter,
489
- });
490
-
491
- const res = await agent[method]({
492
- prompt: 'test',
493
- });
494
-
495
- agent.addFeedback({
496
- correlationId: res.correlationId,
497
- reward: -1,
498
- });
499
-
500
- const message = agent.getMessages()[0]!;
501
- const feedback = agent.getFeedback()[0]!;
502
-
503
- expect(message.correlationId).toBeDefined();
504
- expect(feedback.correlationId).toEqual(message.correlationId);
505
- }
506
- );