@statelyai/agent 1.1.6 → 2.0.0-next.1
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/cyan-carpets-perform.md +5 -0
- package/.changeset/fast-donkeys-argue.md +5 -0
- package/.changeset/light-hats-drive.md +9 -0
- package/.changeset/old-jobs-check.md +5 -0
- package/.changeset/pre.json +13 -0
- package/.vscode/launch.json +6 -0
- package/CHANGELOG.md +22 -0
- package/dist/index.d.mts +262 -171
- package/dist/index.d.ts +262 -171
- package/dist/index.js +383 -274
- package/dist/index.mjs +386 -272
- package/examples/chatbot-alt.ts +57 -0
- package/examples/chatbot.ts +12 -17
- package/examples/cot.ts +26 -23
- package/examples/customer-service-sim.ts +107 -0
- package/examples/email.ts +37 -41
- package/examples/example.ts +6 -6
- package/examples/executor.ts +66 -0
- package/examples/goal.ts +12 -12
- package/examples/helpers/helpers.ts +26 -14
- package/examples/joke.ts +79 -76
- package/examples/jugs.ts +125 -0
- package/examples/multi.ts +5 -5
- package/examples/newspaper.ts +98 -104
- package/examples/number.ts +6 -5
- package/examples/raffle.ts +11 -12
- package/examples/river-crossing.ts +140 -0
- package/examples/sandbox.ts +1 -1
- package/examples/simple.ts +5 -3
- package/examples/summary.ts +121 -0
- package/examples/support.ts +6 -6
- package/examples/ticTacToe.ts +86 -45
- package/examples/todo.ts +7 -7
- package/examples/tutor.ts +15 -15
- package/examples/verify.ts +3 -3
- package/examples/weather.ts +6 -9
- package/examples/wiki.ts +27 -8
- package/examples/word.ts +16 -11
- package/package.json +16 -11
- package/readme.md +1 -1
- package/src/agent-experimental.ts +1 -1
- package/src/agent.test.ts +243 -214
- package/src/agent.ts +286 -95
- package/src/decide.test.ts +276 -0
- package/src/decide.ts +163 -0
- package/src/index.ts +1 -1
- package/src/middleware.ts +91 -0
- package/src/mockModel.ts +47 -0
- package/src/planners/shortestPath.test.ts +94 -0
- package/src/planners/shortestPath.ts +177 -0
- package/src/planners/simple.ts +105 -0
- package/src/strategies/chain-of-note.ts +6 -55
- package/src/text.ts +51 -144
- package/src/types.ts +187 -212
- package/src/utils.ts +48 -4
- package/vitest.config.ts +9 -3
- package/src/adapters/vercel.ts +0 -7
- package/src/decision.test.ts +0 -179
- package/src/decision.ts +0 -84
- package/src/memory.ts +0 -25
- package/src/planners/shortestPathPlanner.ts +0 -22
- package/src/planners/simplePlanner.ts +0 -139
package/src/agent.ts
CHANGED
|
@@ -1,34 +1,43 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Actor,
|
|
3
|
+
ActorRefLike,
|
|
2
4
|
AnyEventObject,
|
|
3
5
|
AnyStateMachine,
|
|
4
|
-
createActor,
|
|
5
6
|
EventObject,
|
|
6
7
|
fromTransition,
|
|
7
|
-
|
|
8
|
-
toObserver,
|
|
8
|
+
Subscription,
|
|
9
9
|
} from 'xstate';
|
|
10
10
|
import { ZodContextMapping, ZodEventMapping } from './schemas';
|
|
11
11
|
import {
|
|
12
|
-
Agent,
|
|
13
12
|
AgentLogic,
|
|
14
13
|
AgentMessage,
|
|
15
14
|
AgentPlanner,
|
|
16
15
|
EventsFromZodEventMapping,
|
|
17
16
|
GenerateTextOptions,
|
|
18
17
|
AgentLongTermMemory,
|
|
19
|
-
AIAdapter,
|
|
20
18
|
ObservedState,
|
|
21
19
|
AgentObservationInput,
|
|
22
20
|
AgentMemoryContext,
|
|
23
21
|
AgentObservation,
|
|
24
22
|
ContextFromZodContextMapping,
|
|
25
23
|
AgentFeedback,
|
|
24
|
+
AgentMessageInput,
|
|
25
|
+
AgentFeedbackInput,
|
|
26
|
+
AgentPlan,
|
|
27
|
+
Compute,
|
|
28
|
+
AgentDecisionInput,
|
|
29
|
+
AgentDecideOptions,
|
|
30
|
+
AnyAgent,
|
|
26
31
|
} from './types';
|
|
27
|
-
import { simplePlanner } from './planners/
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
|
|
32
|
+
import { simplePlanner } from './planners/simple';
|
|
33
|
+
import { agentDecide } from './decide';
|
|
34
|
+
import { getMachineHash, isActorRef, isMachineActor, randomId } from './utils';
|
|
35
|
+
import {
|
|
36
|
+
experimental_wrapLanguageModel,
|
|
37
|
+
LanguageModel,
|
|
38
|
+
LanguageModelV1,
|
|
39
|
+
} from 'ai';
|
|
40
|
+
import { createAgentMiddleware } from './middleware';
|
|
32
41
|
|
|
33
42
|
export const agentLogic: AgentLogic<AnyEventObject> = fromTransition(
|
|
34
43
|
(state, event, { emit }) => {
|
|
@@ -69,8 +78,11 @@ export const agentLogic: AgentLogic<AnyEventObject> = fromTransition(
|
|
|
69
78
|
});
|
|
70
79
|
break;
|
|
71
80
|
}
|
|
72
|
-
default:
|
|
81
|
+
default: {
|
|
82
|
+
// unrecognized
|
|
83
|
+
console.warn('Unrecognized event', event);
|
|
73
84
|
break;
|
|
85
|
+
}
|
|
74
86
|
}
|
|
75
87
|
return state;
|
|
76
88
|
},
|
|
@@ -89,23 +101,19 @@ export function createAgent<
|
|
|
89
101
|
TEvents extends EventObject = EventsFromZodEventMapping<TEventSchemas>,
|
|
90
102
|
TContext = ContextFromZodContextMapping<TContextSchema>
|
|
91
103
|
>({
|
|
92
|
-
|
|
93
|
-
description,
|
|
104
|
+
id,
|
|
105
|
+
description: description,
|
|
94
106
|
model,
|
|
95
107
|
events,
|
|
96
108
|
context,
|
|
97
|
-
planner = simplePlanner as AgentPlanner<Agent<
|
|
98
|
-
stringify = JSON.stringify,
|
|
99
|
-
getMemory,
|
|
109
|
+
planner = simplePlanner as AgentPlanner<Agent<TContextSchema, TEventSchemas>>,
|
|
100
110
|
logic = agentLogic as AgentLogic<TEvents>,
|
|
101
|
-
adapter = vercelAdapter,
|
|
102
|
-
...generateTextOptions
|
|
103
111
|
}: {
|
|
104
112
|
/**
|
|
105
113
|
* The unique identifier for the agent.
|
|
106
114
|
*
|
|
107
115
|
* This should be the same across all sessions of a specific agent, as it can be
|
|
108
|
-
* used to retrieve memory for this agent.
|
|
116
|
+
* used to retrieve memory for previous episodes of this agent.
|
|
109
117
|
*
|
|
110
118
|
* @example
|
|
111
119
|
* ```ts
|
|
@@ -116,10 +124,6 @@ export function createAgent<
|
|
|
116
124
|
* ```
|
|
117
125
|
*/
|
|
118
126
|
id?: string;
|
|
119
|
-
/**
|
|
120
|
-
* The name of the agent
|
|
121
|
-
*/
|
|
122
|
-
name?: string;
|
|
123
127
|
/**
|
|
124
128
|
* A description of the role of the agent
|
|
125
129
|
*/
|
|
@@ -130,150 +134,292 @@ export function createAgent<
|
|
|
130
134
|
*/
|
|
131
135
|
events: TEventSchemas;
|
|
132
136
|
context?: TContextSchema;
|
|
133
|
-
planner?: AgentPlanner<Agent<
|
|
137
|
+
planner?: AgentPlanner<Agent<TContextSchema, TEventSchemas>>;
|
|
134
138
|
stringify?: typeof JSON.stringify;
|
|
135
139
|
/**
|
|
136
140
|
* A function that retrieves the agent's long term memory
|
|
137
141
|
*/
|
|
138
|
-
getMemory?: (
|
|
142
|
+
getMemory?: (
|
|
143
|
+
agent: Agent<TContextSchema, TEventSchemas>
|
|
144
|
+
) => AgentLongTermMemory;
|
|
139
145
|
/**
|
|
140
146
|
* Agent logic
|
|
141
147
|
*/
|
|
142
148
|
logic?: AgentLogic<TEvents>;
|
|
143
|
-
|
|
144
|
-
} & GenerateTextOptions): Agent<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
agent.memory = getMemory ? getMemory(agent) : undefined;
|
|
149
|
+
model: LanguageModel;
|
|
150
|
+
} & GenerateTextOptions): Agent<TContextSchema, TEventSchemas> {
|
|
151
|
+
return new Agent({
|
|
152
|
+
id,
|
|
153
|
+
context,
|
|
154
|
+
events,
|
|
155
|
+
description,
|
|
156
|
+
planner,
|
|
157
|
+
model,
|
|
158
|
+
logic,
|
|
159
|
+
}) as any;
|
|
160
|
+
}
|
|
156
161
|
|
|
157
|
-
|
|
158
|
-
|
|
162
|
+
export class Agent<
|
|
163
|
+
const TContextSchema extends ZodContextMapping,
|
|
164
|
+
const TEventSchemas extends ZodEventMapping,
|
|
165
|
+
TEvents extends EventObject = EventsFromZodEventMapping<TEventSchemas>,
|
|
166
|
+
TContext = ContextFromZodContextMapping<TContextSchema>
|
|
167
|
+
> extends Actor<AgentLogic<TEvents>> {
|
|
168
|
+
/**
|
|
169
|
+
* The name of the agent. All agents with the same name are related and
|
|
170
|
+
* able to share experiences (observations, feedback) with each other.
|
|
171
|
+
*/
|
|
172
|
+
public name?: string;
|
|
173
|
+
/**
|
|
174
|
+
* The unique identifier for the agent.
|
|
175
|
+
*/
|
|
176
|
+
public episodeId: string;
|
|
177
|
+
public description?: string;
|
|
178
|
+
public events: TEventSchemas;
|
|
179
|
+
public context?: TContextSchema;
|
|
180
|
+
public planner?: AgentPlanner<Agent<TContextSchema, TEventSchemas>>;
|
|
181
|
+
public types: {
|
|
182
|
+
events: TEvents;
|
|
183
|
+
context: Compute<TContext>;
|
|
159
184
|
};
|
|
185
|
+
public model: LanguageModel;
|
|
186
|
+
public memory: AgentLongTermMemory | undefined;
|
|
187
|
+
public defaultOptions: AgentDecideOptions<AnyAgent> | undefined; // todo
|
|
160
188
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
189
|
+
constructor({
|
|
190
|
+
logic = agentLogic as AgentLogic<TEvents>,
|
|
191
|
+
id,
|
|
192
|
+
name,
|
|
193
|
+
description,
|
|
194
|
+
model,
|
|
195
|
+
events,
|
|
196
|
+
context,
|
|
197
|
+
planner = simplePlanner,
|
|
198
|
+
}: {
|
|
199
|
+
logic: AgentLogic<TEvents>;
|
|
200
|
+
id?: string;
|
|
201
|
+
name?: string;
|
|
202
|
+
description?: string;
|
|
203
|
+
model: GenerateTextOptions['model'];
|
|
204
|
+
events: TEventSchemas;
|
|
205
|
+
context?: TContextSchema;
|
|
206
|
+
planner?: AgentPlanner<Agent<TContextSchema, TEventSchemas>>;
|
|
207
|
+
}) {
|
|
208
|
+
super(logic);
|
|
209
|
+
this.model = model;
|
|
210
|
+
this.episodeId = id ?? randomId();
|
|
211
|
+
this.name = name;
|
|
212
|
+
this.description = description;
|
|
213
|
+
this.events = events;
|
|
214
|
+
this.context = context;
|
|
215
|
+
this.planner = planner;
|
|
216
|
+
this.types = {} as any;
|
|
217
|
+
|
|
218
|
+
this.start();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Called whenever the agent (LLM assistant) receives or sends a message.
|
|
223
|
+
*/
|
|
224
|
+
public onMessage(fn: (message: AgentMessage) => void) {
|
|
225
|
+
return this.on('message', (ev) => fn(ev.message));
|
|
226
|
+
}
|
|
164
227
|
|
|
165
|
-
|
|
228
|
+
/**
|
|
229
|
+
* Retrieves messages from the agent's short-term (local) memory.
|
|
230
|
+
*/
|
|
231
|
+
public addMessage(messageInput: AgentMessageInput) {
|
|
166
232
|
const message = {
|
|
167
233
|
...messageInput,
|
|
168
234
|
id: messageInput.id ?? randomId(),
|
|
169
235
|
timestamp: messageInput.timestamp ?? Date.now(),
|
|
170
|
-
|
|
171
|
-
correlationId: messageInput.correlationId ?? randomId(),
|
|
236
|
+
episodeId: this.episodeId,
|
|
172
237
|
} satisfies AgentMessage;
|
|
173
|
-
|
|
238
|
+
this.send({
|
|
174
239
|
type: 'agent.message',
|
|
175
240
|
message,
|
|
176
241
|
});
|
|
177
242
|
|
|
178
243
|
return message;
|
|
179
|
-
}
|
|
180
|
-
agent.getMessages = () => agent.getSnapshot().context.messages;
|
|
244
|
+
}
|
|
181
245
|
|
|
182
|
-
|
|
246
|
+
public getMessages() {
|
|
247
|
+
return this.getSnapshot().context.messages;
|
|
248
|
+
}
|
|
183
249
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
agent.addFeedback = (feedbackInput) => {
|
|
250
|
+
public addFeedback(feedbackInput: AgentFeedbackInput) {
|
|
187
251
|
const feedback = {
|
|
188
252
|
...feedbackInput,
|
|
189
253
|
attributes: { ...feedbackInput.attributes },
|
|
190
254
|
reward: feedbackInput.reward ?? 0,
|
|
191
255
|
timestamp: feedbackInput.timestamp ?? Date.now(),
|
|
192
|
-
|
|
256
|
+
episodeId: this.episodeId,
|
|
193
257
|
} satisfies AgentFeedback;
|
|
194
|
-
|
|
258
|
+
this.send({
|
|
195
259
|
type: 'agent.feedback',
|
|
196
260
|
feedback,
|
|
197
261
|
});
|
|
198
262
|
return feedback;
|
|
199
|
-
}
|
|
200
|
-
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Retrieves feedback from the agent's short-term (local) memory.
|
|
267
|
+
*/
|
|
268
|
+
public getFeedback() {
|
|
269
|
+
return this.getSnapshot().context.feedback;
|
|
270
|
+
}
|
|
201
271
|
|
|
202
|
-
|
|
272
|
+
public addObservation(
|
|
273
|
+
observationInput: AgentObservationInput
|
|
274
|
+
): AgentObservation<any> {
|
|
203
275
|
const { prevState, event, state } = observationInput;
|
|
204
276
|
const observation = {
|
|
205
277
|
prevState,
|
|
206
278
|
event,
|
|
207
279
|
state,
|
|
208
280
|
id: observationInput.id ?? randomId(),
|
|
209
|
-
|
|
281
|
+
episodeId: this.episodeId,
|
|
210
282
|
timestamp: observationInput.timestamp ?? Date.now(),
|
|
211
283
|
machineHash: observationInput.machine
|
|
212
284
|
? getMachineHash(observationInput.machine)
|
|
213
285
|
: undefined,
|
|
214
286
|
} satisfies AgentObservation<any>;
|
|
215
287
|
|
|
216
|
-
|
|
288
|
+
this.send({
|
|
217
289
|
type: 'agent.observe',
|
|
218
290
|
observation,
|
|
219
291
|
});
|
|
220
292
|
|
|
221
293
|
return observation;
|
|
222
|
-
}
|
|
223
|
-
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Retrieves observations from the agent's short-term (local) memory.
|
|
298
|
+
*/
|
|
299
|
+
public getObservations() {
|
|
300
|
+
return this.getSnapshot().context.observations;
|
|
301
|
+
}
|
|
224
302
|
|
|
225
|
-
|
|
226
|
-
|
|
303
|
+
public addPlan(plan: AgentPlan<TEvents>) {
|
|
304
|
+
this.send({
|
|
227
305
|
type: 'agent.plan',
|
|
228
306
|
plan,
|
|
229
307
|
});
|
|
230
|
-
}
|
|
231
|
-
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Retrieves strategies from the agent's short-term (local) memory.
|
|
311
|
+
*/
|
|
312
|
+
public getPlans() {
|
|
313
|
+
return this.getSnapshot().context.plans;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Interacts with this state machine actor by inspecting state transitions and storing them as observations.
|
|
318
|
+
*
|
|
319
|
+
* Observations contain the `prevState`, `event`, and current `state` of this
|
|
320
|
+
* actor, as well as other properties that are useful when recalled.
|
|
321
|
+
* These observations are stored in the `agent`'s short-term (local) memory
|
|
322
|
+
* and can be retrieved via `agent.getObservations()`.
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* // Only observes the actor's state transitions
|
|
327
|
+
* agent.interact(actor);
|
|
328
|
+
*
|
|
329
|
+
* actor.start();
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
332
|
+
public interact<TActor extends ActorRefLike>(actorRef: TActor): Subscription;
|
|
333
|
+
/**
|
|
334
|
+
* Interacts with this state machine actor by:
|
|
335
|
+
* 1. Inspecting state transitions and storing them as observations
|
|
336
|
+
* 2. Deciding what to do next (which event to send the actor) based on
|
|
337
|
+
* the agent input returned from `getInput(observation)`, if `getInput(…)` is provided as the 2nd argument.
|
|
338
|
+
*
|
|
339
|
+
* Observations contain the `prevState`, `event`, and current `state` of this
|
|
340
|
+
* actor, as well as other properties that are useful when recalled.
|
|
341
|
+
* These observations are stored in the `agent`'s short-term (local) memory
|
|
342
|
+
* and can be retrieved via `agent.getObservations()`.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```ts
|
|
346
|
+
* // Observes the actor's state transitions and
|
|
347
|
+
* // makes a decision if on the "summarize" state
|
|
348
|
+
* agent.interact(actor, observed => {
|
|
349
|
+
* if (observed.state.matches('summarize')) {
|
|
350
|
+
* return {
|
|
351
|
+
* context: observed.state.context,
|
|
352
|
+
* goal: 'Summarize the message'
|
|
353
|
+
* }
|
|
354
|
+
* }
|
|
355
|
+
* });
|
|
356
|
+
*
|
|
357
|
+
* actor.start();
|
|
358
|
+
* ```
|
|
359
|
+
*/
|
|
360
|
+
public interact<TActor extends ActorRefLike>(
|
|
361
|
+
actorRef: TActor,
|
|
362
|
+
getInput: (
|
|
363
|
+
observation: AgentObservation<TActor>
|
|
364
|
+
) => AgentDecisionInput | undefined
|
|
365
|
+
): Subscription;
|
|
366
|
+
public interact<TActor extends ActorRefLike>(
|
|
367
|
+
actorRef: TActor,
|
|
368
|
+
getInput?: (
|
|
369
|
+
observation: AgentObservation<TActor>
|
|
370
|
+
) => AgentDecisionInput | undefined
|
|
371
|
+
): Subscription {
|
|
372
|
+
const actorRefCheck = isActorRef(actorRef) && actorRef.src;
|
|
373
|
+
const machine = isMachineActor(actorRef) ? actorRef.src : undefined;
|
|
232
374
|
|
|
233
|
-
agent.interact = ((actorRef, getInput) => {
|
|
234
375
|
let prevState: ObservedState | undefined = undefined;
|
|
235
376
|
let subscribed = true;
|
|
236
377
|
|
|
378
|
+
const agent = this;
|
|
379
|
+
|
|
237
380
|
async function handleObservation(observationInput: AgentObservationInput) {
|
|
238
381
|
const observation = agent.addObservation(observationInput);
|
|
239
382
|
|
|
240
383
|
const input = getInput?.(observation);
|
|
241
384
|
|
|
242
385
|
if (input) {
|
|
243
|
-
await agentDecide(agent, {
|
|
244
|
-
machine
|
|
386
|
+
const res = await agentDecide(agent, {
|
|
387
|
+
machine,
|
|
245
388
|
state: observation.state,
|
|
246
|
-
execute: async (event) => {
|
|
247
|
-
actorRef.send(event);
|
|
248
|
-
},
|
|
249
389
|
...input,
|
|
250
390
|
});
|
|
391
|
+
|
|
392
|
+
if (res?.nextEvent) {
|
|
393
|
+
actorRef.send(res.nextEvent);
|
|
394
|
+
}
|
|
251
395
|
}
|
|
252
396
|
|
|
253
397
|
prevState = observationInput.state;
|
|
254
398
|
}
|
|
255
399
|
|
|
256
400
|
// Inspect system, but only observe specified actor
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
401
|
+
const sub = actorRefCheck
|
|
402
|
+
? actorRef.system.inspect({
|
|
403
|
+
next: async (inspEvent) => {
|
|
404
|
+
if (
|
|
405
|
+
!subscribed ||
|
|
406
|
+
inspEvent.actorRef !== actorRef ||
|
|
407
|
+
inspEvent.type !== '@xstate.snapshot'
|
|
408
|
+
) {
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
266
411
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
412
|
+
const observationInput = {
|
|
413
|
+
event: inspEvent.event,
|
|
414
|
+
prevState,
|
|
415
|
+
state: inspEvent.snapshot as any,
|
|
416
|
+
machine: (actorRef as any).src,
|
|
417
|
+
} satisfies AgentObservationInput;
|
|
273
418
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
419
|
+
await handleObservation(observationInput);
|
|
420
|
+
},
|
|
421
|
+
})
|
|
422
|
+
: undefined;
|
|
277
423
|
|
|
278
424
|
// If actor already started, interact with current state
|
|
279
425
|
if ((actorRef as any)._processingStatus === 1) {
|
|
@@ -287,14 +433,59 @@ export function createAgent<
|
|
|
287
433
|
|
|
288
434
|
return {
|
|
289
435
|
unsubscribe: () => {
|
|
436
|
+
sub?.unsubscribe();
|
|
290
437
|
subscribed = false;
|
|
291
|
-
},
|
|
438
|
+
},
|
|
292
439
|
};
|
|
293
|
-
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
public observe<TActor extends ActorRefLike>(actorRef: TActor): Subscription {
|
|
443
|
+
let prevState: ObservedState = actorRef.getSnapshot();
|
|
444
|
+
const actorRefCheck = isActorRef(actorRef);
|
|
294
445
|
|
|
295
|
-
|
|
446
|
+
const sub = actorRefCheck
|
|
447
|
+
? actorRef.system.inspect({
|
|
448
|
+
next: async (inspEvent) => {
|
|
449
|
+
if (
|
|
450
|
+
inspEvent.actorRef !== actorRef ||
|
|
451
|
+
inspEvent.type !== '@xstate.snapshot'
|
|
452
|
+
) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
296
455
|
|
|
297
|
-
|
|
456
|
+
const observationInput = {
|
|
457
|
+
event: inspEvent.event,
|
|
458
|
+
prevState,
|
|
459
|
+
state: inspEvent.snapshot as any,
|
|
460
|
+
machine: (actorRef as any).src,
|
|
461
|
+
} satisfies AgentObservationInput;
|
|
298
462
|
|
|
299
|
-
|
|
463
|
+
prevState = observationInput.state;
|
|
464
|
+
|
|
465
|
+
this.addObservation(observationInput);
|
|
466
|
+
},
|
|
467
|
+
})
|
|
468
|
+
: undefined;
|
|
469
|
+
|
|
470
|
+
return sub ?? { unsubscribe: () => {} };
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
public wrap(modelToWrap: LanguageModelV1) {
|
|
474
|
+
return experimental_wrapLanguageModel({
|
|
475
|
+
model: modelToWrap,
|
|
476
|
+
middleware: createAgentMiddleware(this),
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Resolves with an `AgentPlan` based on the information provided in the `options`, including:
|
|
482
|
+
*
|
|
483
|
+
* - The `goal` for the agent to achieve
|
|
484
|
+
* - The observed current `state`
|
|
485
|
+
* - The `machine` (e.g. a state machine) that specifies what can happen next
|
|
486
|
+
* - Additional `context`
|
|
487
|
+
*/
|
|
488
|
+
public decide(opts: AgentDecideOptions<this>) {
|
|
489
|
+
return agentDecide(this, opts);
|
|
490
|
+
}
|
|
300
491
|
}
|