@statelyai/agent 1.0.0-beta.0 → 1.0.0

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/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { createAgent } from './agent';
2
- export { fromText, fromTextStream, agentGenerateText } from './text';
3
- export { fromDecision, agentDecide } from './decision';
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 Agent<any>>(
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
1
  import { 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
- Only make a single tool call to achieve the above goal.
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 Agent<any>>(
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,23 +93,32 @@ 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({
103
- prompt,
104
- tools: toolMap,
105
111
  toolChoice: 'required',
106
112
  ...input,
113
+ prompt,
114
+ messages,
115
+ tools: toolMap,
107
116
  });
108
117
 
109
118
  const singleResult = result.toolResults[0];
110
119
 
111
120
  if (!singleResult) {
121
+ console.log(toolMap);
112
122
  // TODO: retries?
113
123
  console.warn('No tool call results returned');
114
124
  return undefined;
@@ -117,11 +127,12 @@ export async function simplePlanner<T extends Agent<any>>(
117
127
  return {
118
128
  goal: input.goal,
119
129
  state: input.state,
120
- steps: [
121
- {
122
- event: singleResult.result,
123
- },
124
- ],
130
+ execute: async (state) => {
131
+ if (JSON.stringify(state) === JSON.stringify(input.state)) {
132
+ return singleResult.result;
133
+ }
134
+ return undefined;
135
+ },
125
136
  nextEvent: singleResult.result,
126
137
  sessionId: agent.sessionId,
127
138
  timestamp: Date.now(),
package/src/schemas.ts CHANGED
@@ -1,15 +1,11 @@
1
- import type { SomeZodObject } from 'zod';
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 ZodActionMapping = {
11
- [eventType: string]: {
12
- schema: SomeZodObject;
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 { Agent } from '../types';
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: Agent<any>;
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: Agent<any>;
59
+ agent: AnyAgent;
60
60
  prompt: string;
61
61
  },
62
62
  output: {} as GenerateTextResult<any>,
package/src/text.ts CHANGED
@@ -5,13 +5,12 @@ import type {
5
5
  StreamTextResult,
6
6
  } from 'ai';
7
7
  import {
8
- Agent,
9
8
  AgentGenerateTextOptions,
10
9
  AgentStreamTextOptions,
10
+ AnyAgent,
11
11
  } from './types';
12
12
  import { defaultTextTemplate } from './templates/defaultText';
13
13
  import {
14
- AnyMachineSnapshot,
15
14
  ObservableActorLogic,
16
15
  Observer,
17
16
  PromiseActorLogic,
@@ -19,7 +18,7 @@ import {
19
18
  fromPromise,
20
19
  toObserver,
21
20
  } from 'xstate';
22
- import { nanoid } from 'nanoid';
21
+ import { randomId } from './utils';
23
22
 
24
23
  /**
25
24
  * Gets an array of messages from the given prompt, based on the agent and options.
@@ -29,15 +28,13 @@ import { nanoid } from 'nanoid';
29
28
  * @param options
30
29
  * @returns
31
30
  */
32
- async function getMessages(
33
- agent: Agent<any>,
31
+ export async function getMessages(
32
+ agent: AnyAgent,
34
33
  prompt: string,
35
- options: AgentStreamTextOptions
34
+ options: Omit<AgentGenerateTextOptions, 'prompt'>
36
35
  ): Promise<CoreMessage[]> {
37
36
  let messages: CoreMessage[] = [];
38
- if (options.messages === true) {
39
- messages = agent.select((s) => s.messages);
40
- } else if (typeof options.messages === 'function') {
37
+ if (typeof options.messages === 'function') {
41
38
  messages = await options.messages(agent);
42
39
  } else if (options.messages) {
43
40
  messages = options.messages;
@@ -51,7 +48,7 @@ async function getMessages(
51
48
  return messages;
52
49
  }
53
50
 
54
- export async function agentGenerateText<T extends Agent<any>>(
51
+ export async function agentGenerateText<T extends AnyAgent>(
55
52
  agent: T,
56
53
  options: AgentGenerateTextOptions
57
54
  ) {
@@ -61,7 +58,7 @@ export async function agentGenerateText<T extends Agent<any>>(
61
58
  };
62
59
  const template = resolvedOptions.template ?? defaultTextTemplate;
63
60
  // TODO: check if messages was provided instead
64
- const id = nanoid();
61
+ const id = randomId();
65
62
  const goal =
66
63
  typeof resolvedOptions.prompt === 'string'
67
64
  ? resolvedOptions.prompt
@@ -100,7 +97,7 @@ export async function agentGenerateText<T extends Agent<any>>(
100
97
  }
101
98
 
102
99
  export async function agentStreamText(
103
- agent: Agent<any>,
100
+ agent: AnyAgent,
104
101
  options: AgentStreamTextOptions
105
102
  ): Promise<StreamTextResult<any>> {
106
103
  const resolvedOptions = {
@@ -109,7 +106,7 @@ export async function agentStreamText(
109
106
  };
110
107
  const template = resolvedOptions.template ?? defaultTextTemplate;
111
108
 
112
- const id = nanoid();
109
+ const id = randomId();
113
110
  const goal =
114
111
  typeof resolvedOptions.prompt === 'string'
115
112
  ? resolvedOptions.prompt
@@ -148,7 +145,7 @@ export async function agentStreamText(
148
145
  rawResponse: res.rawResponse,
149
146
  },
150
147
  content: res.text,
151
- id: nanoid(),
148
+ id: randomId(),
152
149
  timestamp: Date.now(),
153
150
  responseId: id,
154
151
  });
@@ -158,21 +155,16 @@ export async function agentStreamText(
158
155
  return result;
159
156
  }
160
157
 
161
- export function fromTextStream<T extends Agent<any>>(
158
+ export function fromTextStream<T extends AnyAgent>(
162
159
  agent: T,
163
160
  defaultOptions?: AgentStreamTextOptions
164
161
  ): ObservableActorLogic<
165
162
  { textDelta: string },
166
163
  Omit<AgentStreamTextOptions, 'context'> & {
167
- context?: AgentStreamTextOptions['context'] | boolean;
164
+ context?: AgentStreamTextOptions['context'];
168
165
  }
169
166
  > {
170
- return fromObservable(({ input, self }) => {
171
- const context =
172
- input.context === true
173
- ? (self._parent?.getSnapshot() as AnyMachineSnapshot).context
174
- : input.context;
175
-
167
+ return fromObservable(({ input }) => {
176
168
  const observers = new Set<Observer<{ textDelta: string }>>();
177
169
 
178
170
  // TODO: check if messages was provided instead
@@ -181,7 +173,7 @@ export function fromTextStream<T extends Agent<any>>(
181
173
  const result = await agentStreamText(agent, {
182
174
  ...defaultOptions,
183
175
  ...input,
184
- context,
176
+ context: input.context,
185
177
  });
186
178
 
187
179
  for await (const part of result.fullStream) {
@@ -208,24 +200,20 @@ export function fromTextStream<T extends Agent<any>>(
208
200
  });
209
201
  }
210
202
 
211
- export function fromText<T extends Agent<any>>(
203
+ export function fromText<T extends AnyAgent>(
212
204
  agent: T,
213
205
  defaultOptions?: AgentGenerateTextOptions
214
206
  ): PromiseActorLogic<
215
207
  GenerateTextResult<Record<string, CoreTool<any, any>>>,
216
208
  Omit<AgentGenerateTextOptions, 'context'> & {
217
- context?: AgentGenerateTextOptions['context'] | boolean;
209
+ context?: AgentGenerateTextOptions['context'];
218
210
  }
219
211
  > {
220
- return fromPromise(async ({ input, self }) => {
221
- const context =
222
- input.context === true
223
- ? (self._parent?.getSnapshot() as AnyMachineSnapshot).context
224
- : input.context;
212
+ return fromPromise(async ({ input }) => {
225
213
  return await agentGenerateText(agent, {
226
214
  ...input,
227
215
  ...defaultOptions,
228
- context,
216
+ context: input.context,
229
217
  });
230
218
  });
231
219
  }
package/src/types.ts CHANGED
@@ -22,21 +22,38 @@ import {
22
22
  streamText,
23
23
  StreamTextResult,
24
24
  } from 'ai';
25
- import { ZodEventMapping } from './schemas';
25
+ import { ZodContextMapping, ZodEventMapping } from './schemas';
26
26
  import { TypeOf } from 'zod';
27
27
 
28
28
  export type GenerateTextOptions = Parameters<typeof generateText>[0];
29
29
 
30
30
  export type StreamTextOptions = Parameters<typeof streamText>[0];
31
31
 
32
- export type AgentPlanInput<TEvent extends EventObject> = {
33
- model: LanguageModel;
32
+ export type AgentPlanInput<TEvent extends EventObject> = Omit<
33
+ GenerateTextOptions,
34
+ 'prompt' | 'messages' | 'tools'
35
+ > & {
36
+ /**
37
+ * The currently observed state.
38
+ */
34
39
  state: ObservedState;
40
+ /**
41
+ * The goal for the agent to accomplish.
42
+ * The agent will create a plan based on this goal.
43
+ */
35
44
  goal: string;
45
+ /**
46
+ * The events that the agent can trigger. This is a mapping of
47
+ * event types to Zod event schemas.
48
+ */
36
49
  events: ZodEventMapping;
50
+ /**
51
+ * The state machine that represents the environment the agent
52
+ * is interacting with.
53
+ */
37
54
  machine?: AnyStateMachine;
38
55
  /**
39
- * The previous plan
56
+ * The previous plan.
40
57
  */
41
58
  previousPlan?: AgentPlan<TEvent>;
42
59
  };
@@ -45,10 +62,11 @@ export type AgentPlan<TEvent extends EventObject> = {
45
62
  goal: string;
46
63
  state: ObservedState;
47
64
  content?: string;
48
- steps?: Array<{
49
- event: TEvent;
50
- state?: ObservedState;
51
- }>;
65
+ /**
66
+ * Executes the plan based on the given `state` and resolves with
67
+ * a potential next `event` to trigger to achieve the `goal`.
68
+ */
69
+ execute: (state: ObservedState) => Promise<TEvent | undefined>;
52
70
  nextEvent: TEvent | undefined;
53
71
  sessionId: string;
54
72
  timestamp: number;
@@ -86,14 +104,14 @@ export type PromptTemplate<TEvents extends EventObject> = (data: {
86
104
  */
87
105
  observations?: AgentObservation<any>[]; // TODO
88
106
  feedback?: AgentFeedback[];
89
- messages?: AgentMessageHistory[];
107
+ messages?: AgentMessage[];
90
108
  plans?: AgentPlan<TEvents>[];
91
109
  }) => string;
92
110
 
93
- export type AgentPlanner<T extends Agent<any>> = (
94
- agent: T['eventTypes'],
95
- options: AgentPlanInput<T['eventTypes']>
96
- ) => Promise<AgentPlan<T['eventTypes']> | undefined>;
111
+ export type AgentPlanner<T extends AnyAgent> = (
112
+ agent: T,
113
+ input: AgentPlanInput<T['types']['events']>
114
+ ) => Promise<AgentPlan<T['types']['events']> | undefined>;
97
115
 
98
116
  export type AgentDecideOptions = {
99
117
  goal: string;
@@ -124,7 +142,7 @@ export interface AgentFeedbackInput {
124
142
  timestamp?: number;
125
143
  }
126
144
 
127
- export type AgentMessageHistory = CoreMessage & {
145
+ export type AgentMessage = CoreMessage & {
128
146
  timestamp: number;
129
147
  id: string;
130
148
  /**
@@ -136,7 +154,7 @@ export type AgentMessageHistory = CoreMessage & {
136
154
  sessionId: string;
137
155
  };
138
156
 
139
- export type AgentMessageHistoryInput = CoreMessage & {
157
+ export type AgentMessageInput = CoreMessage & {
140
158
  timestamp?: number;
141
159
  id?: string;
142
160
  /**
@@ -152,6 +170,7 @@ export interface AgentObservation<TActor extends AnyActorRef> {
152
170
  prevState: SnapshotFrom<TActor> | undefined;
153
171
  event: EventFrom<TActor>;
154
172
  state: SnapshotFrom<TActor>;
173
+ machineHash: string | undefined;
155
174
  sessionId: string;
156
175
  timestamp: number;
157
176
  }
@@ -161,6 +180,7 @@ export interface AgentObservationInput {
161
180
  prevState: ObservedState | undefined;
162
181
  event: AnyEventObject;
163
182
  state: ObservedState;
183
+ machine?: AnyStateMachine;
164
184
  timestamp?: number;
165
185
  }
166
186
 
@@ -186,7 +206,7 @@ export type AgentEmitted<TEvents extends EventObject> =
186
206
  }
187
207
  | {
188
208
  type: 'message';
189
- message: AgentMessageHistory;
209
+ message: AgentMessage;
190
210
  }
191
211
  | {
192
212
  type: 'plan';
@@ -205,7 +225,7 @@ export type AgentLogic<TEvents extends EventObject> = ActorLogic<
205
225
  }
206
226
  | {
207
227
  type: 'agent.message';
208
- message: AgentMessageHistory;
228
+ message: AgentMessage;
209
229
  }
210
230
  | {
211
231
  type: 'agent.plan';
@@ -223,21 +243,30 @@ export type EventsFromZodEventMapping<TEventSchemas extends ZodEventMapping> =
223
243
  } & TypeOf<TEventSchemas[K]>;
224
244
  }>;
225
245
 
226
- export type Agent<TEvents extends EventObject> = ActorRefFrom<
246
+ export type ContextFromZodContextMapping<
247
+ TContextSchema extends ZodContextMapping
248
+ > = {
249
+ [K in keyof TContextSchema & string]: TypeOf<TContextSchema[K]>;
250
+ };
251
+
252
+ export type Agent<TContext, TEvents extends EventObject> = ActorRefFrom<
227
253
  AgentLogic<TEvents>
228
254
  > & {
229
255
  /**
230
- * The general name of the agent. All agents with the same name are related and
256
+ * The name of the agent. All agents with the same name are related and
231
257
  * able to share experiences (observations, feedback) with each other.
232
258
  */
233
- name: string;
259
+ name?: string;
234
260
  /**
235
- * The unique id of the agent. This is used to partition message history.
261
+ * The unique identifier for the agent.
236
262
  */
237
263
  id?: string;
238
264
  description?: string;
239
265
  events: ZodEventMapping;
240
- eventTypes: TEvents;
266
+ types: {
267
+ events: TEvents;
268
+ context: Compute<TContext>;
269
+ };
241
270
  model: LanguageModel;
242
271
  defaultOptions: GenerateTextOptions;
243
272
  memory: AgentLongTermMemory | undefined;
@@ -254,7 +283,7 @@ export type Agent<TEvents extends EventObject> = ActorRefFrom<
254
283
  *
255
284
  * - The `goal` for the agent to achieve
256
285
  * - The observed current `state`
257
- * - The `logic` (e.g. a state machine) that specifies what can happen next
286
+ * - The `machine` (e.g. a state machine) that specifies what can happen next
258
287
  * - Additional `context`
259
288
  */
260
289
  decide: (
@@ -271,32 +300,100 @@ export type Agent<TEvents extends EventObject> = ActorRefFrom<
271
300
  options: AgentStreamTextOptions
272
301
  ) => Promise<StreamTextResult<Record<string, CoreTool<any, any>>>>;
273
302
 
274
- addObservation: (observation: AgentObservationInput) => AgentObservation<any>; // TODO
275
- addMessage: (history: AgentMessageHistoryInput) => AgentMessageHistory;
276
- addFeedback: (feedbackItem: AgentFeedbackInput) => AgentFeedback;
303
+ addObservation: (
304
+ observationInput: AgentObservationInput
305
+ ) => AgentObservation<any>; // TODO
306
+ addMessage: (messageInput: AgentMessageInput) => AgentMessage;
307
+ addFeedback: (feedbackInput: AgentFeedbackInput) => AgentFeedback;
277
308
  addPlan: (plan: AgentPlan<TEvents>) => void;
278
309
  /**
279
310
  * Called whenever the agent (LLM assistant) receives or sends a message.
280
311
  */
281
- onMessage: (callback: (message: AgentMessageHistory) => void) => void;
312
+ onMessage: (callback: (message: AgentMessage) => void) => void;
282
313
  /**
283
314
  * Selects agent data from its context.
315
+ *
316
+ * @deprecated Select from `agent.getSnapshot().context` directly or:
317
+ * - `agent.getMessages()`
318
+ * - `agent.getObservations()`
319
+ * - `agent.getFeedback()`
320
+ * - `agent.getPlans()`
284
321
  */
285
322
  select: <T>(selector: (context: AgentMemoryContext) => T) => T;
286
323
 
287
324
  /**
288
- * Inspects state machine actor transitions and automatically observes
289
- * (prevState, event, state) tuples.
325
+ * Retrieves messages from the agent's short-term (local) memory.
290
326
  */
291
- interact: <TActor extends AnyActorRef>(
327
+ getMessages: () => AgentMessage[];
328
+
329
+ /**
330
+ * Retrieves observations from the agent's short-term (local) memory.
331
+ */
332
+ getObservations: () => AgentObservation<Agent<TContext, TEvents>>[];
333
+
334
+ /**
335
+ * Retrieves feedback from the agent's short-term (local) memory.
336
+ */
337
+ getFeedback: () => AgentFeedback[];
338
+
339
+ /**
340
+ * Retrieves strategies from the agent's short-term (local) memory.
341
+ */
342
+ getPlans: () => AgentPlan<TEvents>[];
343
+
344
+ /**
345
+ * Interacts with this state machine actor by inspecting state transitions and storing them as observations.
346
+ *
347
+ * Observations contain the `prevState`, `event`, and current `state` of this
348
+ * actor, as well as other properties that are useful when recalled.
349
+ * These observations are stored in the `agent`'s short-term (local) memory
350
+ * and can be retrieved via `agent.getObservations()`.
351
+ *
352
+ * @example
353
+ * ```ts
354
+ * // Only observes the actor's state transitions
355
+ * agent.interact(actor);
356
+ *
357
+ * actor.start();
358
+ * ```
359
+ */
360
+ interact<TActor extends AnyActorRef>(actorRef: TActor): Subscription;
361
+ /**
362
+ * Interacts with this state machine actor by:
363
+ * 1. Inspecting state transitions and storing them as observations
364
+ * 2. Deciding what to do next (which event to send the actor) based on
365
+ * the agent input returned from `getInput(observation)`, if `getInput(…)` is provided as the 2nd argument.
366
+ *
367
+ * Observations contain the `prevState`, `event`, and current `state` of this
368
+ * actor, as well as other properties that are useful when recalled.
369
+ * These observations are stored in the `agent`'s short-term (local) memory
370
+ * and can be retrieved via `agent.getObservations()`.
371
+ *
372
+ * @example
373
+ * ```ts
374
+ * // Observes the actor's state transitions and
375
+ * // makes a decision if on the "summarize" state
376
+ * agent.interact(actor, observed => {
377
+ * if (observed.state.matches('summarize')) {
378
+ * return {
379
+ * context: observed.state.context,
380
+ * goal: 'Summarize the message'
381
+ * }
382
+ * }
383
+ * });
384
+ *
385
+ * actor.start();
386
+ * ```
387
+ */
388
+ interact<TActor extends AnyActorRef>(
292
389
  actorRef: TActor,
293
- getInput?: (
390
+ getInput: (
294
391
  observation: AgentObservation<TActor>
295
392
  ) => AgentDecisionInput | undefined
296
- ) => Subscription;
393
+ ): Subscription;
297
394
  };
298
395
 
299
- export type AnyAgent = Agent<any>;
396
+ export type AnyAgent = Agent<any, any>;
300
397
 
301
398
  export type FromAgent<T> = T | ((self: AnyAgent) => T | Promise<T>);
302
399
 
@@ -304,7 +401,7 @@ export interface CommonTextOptions {
304
401
  prompt: FromAgent<string>;
305
402
  model?: LanguageModel;
306
403
  context?: Record<string, any>;
307
- messages?: FromAgent<CoreMessage[]> | true;
404
+ messages?: FromAgent<CoreMessage[]>;
308
405
  template?: PromptTemplate<any>;
309
406
  }
310
407
 
@@ -339,7 +436,7 @@ export type ObservedStateFrom<TActor extends AnyActorRef> = Pick<
339
436
 
340
437
  export type AgentMemoryContext = {
341
438
  observations: AgentObservation<any>[]; // TODO
342
- messages: AgentMessageHistory[];
439
+ messages: AgentMessage[];
343
440
  plans: AgentPlan<any>[];
344
441
  feedback: AgentFeedback[];
345
442
  };
@@ -376,3 +473,5 @@ export interface AIAdapter {
376
473
  generateText: typeof generateText;
377
474
  streamText: typeof streamText;
378
475
  }
476
+
477
+ export type Compute<A extends any> = { [K in keyof A]: A[K] } & unknown;