@statelyai/agent 1.1.6 → 2.0.0-alpha.11

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 (92) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapter.cjs +15 -0
  3. package/dist/adapter.d.cts +4 -0
  4. package/dist/adapter.d.mts +4 -0
  5. package/dist/adapter.mjs +2 -0
  6. package/dist/ai-sdk.cjs +306 -0
  7. package/dist/ai-sdk.d.cts +96 -0
  8. package/dist/ai-sdk.d.mts +96 -0
  9. package/dist/ai-sdk.mjs +304 -0
  10. package/dist/decision-C3k4ve51.mjs +227 -0
  11. package/dist/decision-D8wJrM8W.cjs +286 -0
  12. package/dist/events-CRQj3VtP.cjs +1010 -0
  13. package/dist/events-JiVPYrct.mjs +759 -0
  14. package/dist/index.cjs +2528 -0
  15. package/dist/index.d.cts +1232 -0
  16. package/dist/index.d.mts +1217 -413
  17. package/dist/index.mjs +2489 -584
  18. package/dist/openai-compat.cjs +309 -0
  19. package/dist/openai-compat.d.cts +59 -0
  20. package/dist/openai-compat.d.mts +59 -0
  21. package/dist/openai-compat.mjs +308 -0
  22. package/dist/steps-BALp1eZo.d.mts +198 -0
  23. package/dist/steps-CVe54GPP.cjs +420 -0
  24. package/dist/steps-CkyyyuHd.mjs +379 -0
  25. package/dist/steps-MjnQI4aB.d.cts +198 -0
  26. package/dist/steps.cjs +12 -0
  27. package/dist/steps.d.cts +3 -0
  28. package/dist/steps.d.mts +3 -0
  29. package/dist/steps.mjs +3 -0
  30. package/dist/text-logic-CaKqgX4Y.d.mts +710 -0
  31. package/dist/text-logic-Ckhr2kKC.d.cts +710 -0
  32. package/dist/types-C9QiMjre.d.cts +219 -0
  33. package/dist/types-qm00QF91.d.mts +219 -0
  34. package/dist/utils-BYqT_Dyv.d.cts +108 -0
  35. package/dist/utils-Do5wIJrh.d.mts +108 -0
  36. package/dist/zod.cjs +31 -0
  37. package/dist/zod.d.cts +30 -0
  38. package/dist/zod.d.mts +30 -0
  39. package/dist/zod.mjs +30 -0
  40. package/package.json +132 -28
  41. package/readme.md +153 -6
  42. package/schemas/agent-workflow.json +526 -0
  43. package/.changeset/README.md +0 -8
  44. package/.changeset/config.json +0 -11
  45. package/.env.template +0 -3
  46. package/.github/actions/ci-setup/action.yml +0 -24
  47. package/.github/workflows/release.yml +0 -46
  48. package/.vscode/launch.json +0 -28
  49. package/CHANGELOG.md +0 -222
  50. package/dist/index.d.ts +0 -428
  51. package/dist/index.js +0 -621
  52. package/examples/chatbot.ts +0 -71
  53. package/examples/cot.ts +0 -89
  54. package/examples/email.ts +0 -118
  55. package/examples/example.ts +0 -81
  56. package/examples/goal.ts +0 -94
  57. package/examples/helpers/helpers.ts +0 -17
  58. package/examples/helpers/loader.ts +0 -32
  59. package/examples/helpers/runner.ts +0 -27
  60. package/examples/joke.ts +0 -225
  61. package/examples/multi.ts +0 -103
  62. package/examples/newspaper.ts +0 -324
  63. package/examples/number.ts +0 -102
  64. package/examples/raffle.ts +0 -105
  65. package/examples/sandbox.ts +0 -28
  66. package/examples/simple.ts +0 -39
  67. package/examples/support.ts +0 -147
  68. package/examples/ticTacToe.ts +0 -224
  69. package/examples/todo.ts +0 -137
  70. package/examples/tutor.ts +0 -100
  71. package/examples/verify.ts +0 -120
  72. package/examples/weather.ts +0 -178
  73. package/examples/wiki.ts +0 -30
  74. package/examples/word.ts +0 -171
  75. package/src/adapters/vercel.ts +0 -7
  76. package/src/agent-experimental.ts +0 -221
  77. package/src/agent.test.ts +0 -506
  78. package/src/agent.ts +0 -300
  79. package/src/decision.test.ts +0 -179
  80. package/src/decision.ts +0 -84
  81. package/src/index.ts +0 -4
  82. package/src/memory.ts +0 -25
  83. package/src/planners/shortestPathPlanner.ts +0 -22
  84. package/src/planners/simplePlanner.ts +0 -139
  85. package/src/schemas.ts +0 -11
  86. package/src/strategies/chain-of-note.ts +0 -155
  87. package/src/templates/defaultText.ts +0 -18
  88. package/src/text.ts +0 -241
  89. package/src/types.ts +0 -499
  90. package/src/utils.ts +0 -72
  91. package/tsconfig.json +0 -109
  92. 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
- );