@statelyai/agent 2.0.0-next.1 → 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/grumpy-dolphins-think.md +17 -0
- package/.changeset/old-teachers-tap.md +5 -0
- package/.changeset/pink-eagles-deliver.md +13 -0
- package/.changeset/pre.json +9 -1
- package/.changeset/quiet-turtles-do.md +7 -0
- package/.changeset/smart-yaks-pull.md +23 -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 +79 -0
- package/dist/index.d.mts +116 -100
- package/dist/index.d.ts +116 -100
- package/dist/index.js +102 -72
- package/dist/index.mjs +105 -75
- package/examples/chatbot.ts +2 -2
- package/examples/cot.ts +21 -73
- package/examples/customer-service-sim.ts +3 -3
- package/examples/email.ts +3 -5
- package/examples/example.ts +2 -2
- package/examples/goal.ts +2 -2
- package/examples/joke.ts +12 -12
- package/examples/jugs.ts +4 -7
- package/examples/learn-from-feedback.ts +123 -0
- package/examples/number.ts +2 -2
- package/examples/raffle.ts +2 -2
- package/examples/river-crossing.ts +4 -7
- package/examples/simple.ts +13 -10
- package/examples/summary.ts +2 -5
- package/examples/support.ts +38 -38
- package/examples/ticTacToe.ts +46 -4
- package/examples/todo.ts +3 -3
- package/examples/tutor.ts +2 -2
- package/examples/verify.ts +2 -2
- package/examples/weather-agent.ts +139 -0
- package/examples/weather.ts +26 -23
- package/examples/word.ts +8 -6
- package/package.json +2 -1
- package/src/agent.test.ts +37 -52
- package/src/agent.ts +93 -60
- package/src/decide.test.ts +56 -8
- package/src/decide.ts +42 -32
- package/src/strategies/chainOfThought.ts +50 -0
- package/src/{planners → strategies}/shortestPath.test.ts +4 -7
- package/src/strategies/shortestPath.ts +178 -0
- package/src/{planners → strategies}/simple.ts +25 -26
- package/src/templates/defaultText.ts +3 -0
- package/src/text.ts +13 -13
- package/src/types.ts +124 -83
- package/src/utils.ts +13 -1
- package/src/planners/shortestPath.ts +0 -177
- package/src/strategies/chain-of-note.ts +0 -106
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
fromTransition
|
|
5
5
|
} from "xstate";
|
|
6
6
|
|
|
7
|
-
// src/
|
|
7
|
+
// src/strategies/simple.ts
|
|
8
8
|
import { generateText as generateText2 } from "ai";
|
|
9
9
|
|
|
10
10
|
// src/utils.ts
|
|
@@ -43,6 +43,15 @@ function getAllMachineTransitions(stateNode) {
|
|
|
43
43
|
function wrapInXml(tagName, content) {
|
|
44
44
|
return `<${tagName}>${content}</${tagName}>`;
|
|
45
45
|
}
|
|
46
|
+
function convertToXml(obj) {
|
|
47
|
+
return Object.entries(obj).map(([key, value]) => {
|
|
48
|
+
if (typeof value === "object" && value !== null) {
|
|
49
|
+
return wrapInXml(key, convertToXml(value));
|
|
50
|
+
} else {
|
|
51
|
+
return wrapInXml(key, value);
|
|
52
|
+
}
|
|
53
|
+
}).join("");
|
|
54
|
+
}
|
|
46
55
|
function randomId(prefix) {
|
|
47
56
|
const timestamp = Date.now().toString(36);
|
|
48
57
|
const random = Math.random().toString(36).substring(2, 9);
|
|
@@ -74,12 +83,19 @@ function isMachineActor(actor) {
|
|
|
74
83
|
return "src" in actor && typeof actor.src === "object" && actor.src !== null && "definition" in actor.src;
|
|
75
84
|
}
|
|
76
85
|
|
|
77
|
-
// src/
|
|
86
|
+
// src/strategies/simple.ts
|
|
78
87
|
import { getNextSnapshot } from "xstate";
|
|
79
88
|
|
|
89
|
+
// src/text.ts
|
|
90
|
+
import {
|
|
91
|
+
generateText,
|
|
92
|
+
streamText
|
|
93
|
+
} from "ai";
|
|
94
|
+
|
|
80
95
|
// src/templates/defaultText.ts
|
|
81
96
|
var defaultTextTemplate = (data) => {
|
|
82
97
|
const preamble = [
|
|
98
|
+
data.stateValue ? wrapInXml("stateValue", JSON.stringify(data.stateValue)) : void 0,
|
|
83
99
|
data.context ? wrapInXml("context", JSON.stringify(data.context)) : void 0
|
|
84
100
|
].filter(Boolean).join("\n");
|
|
85
101
|
return `
|
|
@@ -90,10 +106,6 @@ ${data.goal}
|
|
|
90
106
|
};
|
|
91
107
|
|
|
92
108
|
// src/text.ts
|
|
93
|
-
import {
|
|
94
|
-
generateText,
|
|
95
|
-
streamText
|
|
96
|
-
} from "ai";
|
|
97
109
|
import {
|
|
98
110
|
fromObservable,
|
|
99
111
|
fromPromise,
|
|
@@ -186,35 +198,46 @@ async function agentDecide(agent, options) {
|
|
|
186
198
|
...options
|
|
187
199
|
};
|
|
188
200
|
const {
|
|
189
|
-
|
|
201
|
+
strategy = agent.strategy,
|
|
190
202
|
goal,
|
|
203
|
+
allowedEvents,
|
|
191
204
|
events = agent.events,
|
|
192
205
|
state,
|
|
193
206
|
machine,
|
|
194
207
|
model = agent.model,
|
|
195
208
|
messages,
|
|
196
|
-
...
|
|
209
|
+
...otherDecideInput
|
|
197
210
|
} = resolvedOptions;
|
|
211
|
+
const filteredEventSchemas = allowedEvents ? Object.fromEntries(
|
|
212
|
+
Object.entries(events).filter(([key]) => {
|
|
213
|
+
return allowedEvents.includes(key);
|
|
214
|
+
})
|
|
215
|
+
) : events;
|
|
198
216
|
let attempts = 0;
|
|
199
217
|
const maxAttempts = resolvedOptions.maxAttempts ?? 2;
|
|
200
|
-
let
|
|
218
|
+
let decision;
|
|
219
|
+
const minimalState = {
|
|
220
|
+
value: state.value,
|
|
221
|
+
context: state.context
|
|
222
|
+
};
|
|
201
223
|
while (attempts++ < maxAttempts) {
|
|
202
|
-
|
|
224
|
+
decision = await strategy(agent, {
|
|
203
225
|
model,
|
|
204
226
|
goal,
|
|
205
|
-
events,
|
|
206
|
-
state,
|
|
227
|
+
events: filteredEventSchemas,
|
|
228
|
+
state: minimalState,
|
|
207
229
|
machine,
|
|
208
230
|
messages,
|
|
209
231
|
// TODO: fix UIMessage thing
|
|
210
|
-
...
|
|
232
|
+
...otherDecideInput
|
|
211
233
|
});
|
|
212
|
-
if (
|
|
213
|
-
agent.
|
|
214
|
-
await resolvedOptions.execute?.(
|
|
234
|
+
if (decision?.nextEvent) {
|
|
235
|
+
agent.addDecision(decision);
|
|
236
|
+
await resolvedOptions.execute?.(decision.nextEvent);
|
|
237
|
+
break;
|
|
215
238
|
}
|
|
216
239
|
}
|
|
217
|
-
return
|
|
240
|
+
return decision;
|
|
218
241
|
}
|
|
219
242
|
function fromDecision(agent, defaultInput) {
|
|
220
243
|
return fromPromise2(async ({ input, self }) => {
|
|
@@ -228,19 +251,17 @@ function fromDecision(agent, defaultInput) {
|
|
|
228
251
|
...defaultInput,
|
|
229
252
|
...inputObject
|
|
230
253
|
};
|
|
231
|
-
const
|
|
232
|
-
value: snapshot.value,
|
|
233
|
-
context: resolvedInput.context
|
|
234
|
-
};
|
|
235
|
-
const plan = await agentDecide(agent, {
|
|
254
|
+
const decision = await agentDecide(agent, {
|
|
236
255
|
machine: parentRef.logic,
|
|
237
|
-
state,
|
|
256
|
+
state: snapshot,
|
|
238
257
|
execute: async (event) => {
|
|
239
258
|
parentRef.send(event);
|
|
240
259
|
},
|
|
241
|
-
...resolvedInput
|
|
260
|
+
...resolvedInput,
|
|
261
|
+
// @ts-ignore
|
|
262
|
+
messages: resolvedInput.messages
|
|
242
263
|
});
|
|
243
|
-
return
|
|
264
|
+
return decision;
|
|
244
265
|
});
|
|
245
266
|
}
|
|
246
267
|
function getToolMap(_agent, input) {
|
|
@@ -286,37 +307,30 @@ function getToolMap(_agent, input) {
|
|
|
286
307
|
return toolMap;
|
|
287
308
|
}
|
|
288
309
|
|
|
289
|
-
// src/
|
|
290
|
-
var
|
|
310
|
+
// src/strategies/simple.ts
|
|
311
|
+
var simpleStrategyPromptTemplate = (data) => {
|
|
291
312
|
return `
|
|
292
|
-
${
|
|
313
|
+
${convertToXml(data)}
|
|
293
314
|
|
|
294
315
|
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.
|
|
295
316
|
`.trim();
|
|
296
317
|
};
|
|
297
|
-
async function
|
|
318
|
+
async function simpleStrategy(agent, input) {
|
|
298
319
|
const toolMap = getToolMap(agent, input);
|
|
299
320
|
if (!toolMap) {
|
|
300
321
|
return void 0;
|
|
301
322
|
}
|
|
302
|
-
const prompt =
|
|
303
|
-
|
|
323
|
+
const prompt = simpleStrategyPromptTemplate({
|
|
324
|
+
stateValue: input.state.value,
|
|
325
|
+
context: input.context ?? input.state.context,
|
|
304
326
|
goal: input.goal
|
|
305
327
|
});
|
|
306
328
|
const messages = await getMessages(agent, prompt, input);
|
|
307
329
|
const model = input.model ? agent.wrap(input.model) : agent.model;
|
|
308
|
-
const {
|
|
309
|
-
|
|
310
|
-
machine,
|
|
311
|
-
previousPlan,
|
|
312
|
-
events,
|
|
313
|
-
goal,
|
|
314
|
-
model: _,
|
|
315
|
-
...rest
|
|
316
|
-
} = input;
|
|
317
|
-
const machineState = input.machine ? input.machine.resolveState({
|
|
330
|
+
const { state, machine, events, goal, model: _, ...rest } = input;
|
|
331
|
+
const machineState = input.machine && input.state ? input.machine.resolveState({
|
|
318
332
|
...input.state,
|
|
319
|
-
context: input.state.context
|
|
333
|
+
context: input.state.context ?? {}
|
|
320
334
|
}) : void 0;
|
|
321
335
|
const result = await generateText2({
|
|
322
336
|
...rest,
|
|
@@ -340,7 +354,8 @@ async function simplePlanner(agent, input) {
|
|
|
340
354
|
return void 0;
|
|
341
355
|
}
|
|
342
356
|
return {
|
|
343
|
-
|
|
357
|
+
id: randomId(),
|
|
358
|
+
strategy: "simple",
|
|
344
359
|
goal: input.goal,
|
|
345
360
|
goalState: input.state,
|
|
346
361
|
nextEvent: singleResult.result,
|
|
@@ -459,12 +474,11 @@ var agentLogic = fromTransition(
|
|
|
459
474
|
});
|
|
460
475
|
break;
|
|
461
476
|
}
|
|
462
|
-
case "agent.
|
|
463
|
-
state.
|
|
477
|
+
case "agent.decision": {
|
|
478
|
+
state.decisions.push(event.decision);
|
|
464
479
|
emit({
|
|
465
|
-
type: "
|
|
466
|
-
|
|
467
|
-
plan: event.plan
|
|
480
|
+
type: "decision",
|
|
481
|
+
decision: event.decision
|
|
468
482
|
});
|
|
469
483
|
break;
|
|
470
484
|
}
|
|
@@ -479,7 +493,7 @@ var agentLogic = fromTransition(
|
|
|
479
493
|
feedback: [],
|
|
480
494
|
messages: [],
|
|
481
495
|
observations: [],
|
|
482
|
-
|
|
496
|
+
decisions: []
|
|
483
497
|
})
|
|
484
498
|
);
|
|
485
499
|
function createAgent({
|
|
@@ -488,7 +502,8 @@ function createAgent({
|
|
|
488
502
|
model,
|
|
489
503
|
events,
|
|
490
504
|
context,
|
|
491
|
-
|
|
505
|
+
episodeId,
|
|
506
|
+
strategy = simpleStrategy,
|
|
492
507
|
logic = agentLogic
|
|
493
508
|
}) {
|
|
494
509
|
return new Agent({
|
|
@@ -496,9 +511,10 @@ function createAgent({
|
|
|
496
511
|
context,
|
|
497
512
|
events,
|
|
498
513
|
description,
|
|
499
|
-
|
|
514
|
+
strategy,
|
|
500
515
|
model,
|
|
501
|
-
logic
|
|
516
|
+
logic,
|
|
517
|
+
episodeId
|
|
502
518
|
});
|
|
503
519
|
}
|
|
504
520
|
var Agent = class extends Actor {
|
|
@@ -511,17 +527,18 @@ var Agent = class extends Actor {
|
|
|
511
527
|
model,
|
|
512
528
|
events,
|
|
513
529
|
context,
|
|
514
|
-
|
|
530
|
+
episodeId,
|
|
531
|
+
strategy = simpleStrategy
|
|
515
532
|
}) {
|
|
516
533
|
super(logic);
|
|
517
534
|
this.model = model;
|
|
518
|
-
this.episodeId =
|
|
535
|
+
this.episodeId = episodeId ?? randomId("episode-");
|
|
519
536
|
this.name = name;
|
|
520
537
|
this.description = description;
|
|
521
538
|
this.events = events;
|
|
522
539
|
this.context = context;
|
|
523
|
-
this.
|
|
524
|
-
this.
|
|
540
|
+
this.strategy = strategy;
|
|
541
|
+
this.id = id ?? randomId();
|
|
525
542
|
this.start();
|
|
526
543
|
}
|
|
527
544
|
/**
|
|
@@ -530,6 +547,12 @@ var Agent = class extends Actor {
|
|
|
530
547
|
onMessage(fn) {
|
|
531
548
|
return this.on("message", (ev) => fn(ev.message));
|
|
532
549
|
}
|
|
550
|
+
/**
|
|
551
|
+
* Called whenever the agent (LLM assistant) receives some feedback.
|
|
552
|
+
*/
|
|
553
|
+
onFeedback(fn) {
|
|
554
|
+
return this.on("feedback", (ev) => fn(ev.feedback));
|
|
555
|
+
}
|
|
533
556
|
/**
|
|
534
557
|
* Retrieves messages from the agent's short-term (local) memory.
|
|
535
558
|
*/
|
|
@@ -552,8 +575,8 @@ var Agent = class extends Actor {
|
|
|
552
575
|
addFeedback(feedbackInput) {
|
|
553
576
|
const feedback = {
|
|
554
577
|
...feedbackInput,
|
|
578
|
+
comment: feedbackInput.comment ?? void 0,
|
|
555
579
|
attributes: { ...feedbackInput.attributes },
|
|
556
|
-
reward: feedbackInput.reward ?? 0,
|
|
557
580
|
timestamp: feedbackInput.timestamp ?? Date.now(),
|
|
558
581
|
episodeId: this.episodeId
|
|
559
582
|
};
|
|
@@ -592,17 +615,17 @@ var Agent = class extends Actor {
|
|
|
592
615
|
getObservations() {
|
|
593
616
|
return this.getSnapshot().context.observations;
|
|
594
617
|
}
|
|
595
|
-
|
|
618
|
+
addDecision(decision) {
|
|
596
619
|
this.send({
|
|
597
|
-
type: "agent.
|
|
598
|
-
|
|
620
|
+
type: "agent.decision",
|
|
621
|
+
decision
|
|
599
622
|
});
|
|
600
623
|
}
|
|
601
624
|
/**
|
|
602
625
|
* Retrieves strategies from the agent's short-term (local) memory.
|
|
603
626
|
*/
|
|
604
|
-
|
|
605
|
-
return this.getSnapshot().context.
|
|
627
|
+
getDecisions() {
|
|
628
|
+
return this.getSnapshot().context.decisions;
|
|
606
629
|
}
|
|
607
630
|
interact(actorRef, getInput) {
|
|
608
631
|
const actorRefCheck = isActorRef(actorRef) && actorRef.src;
|
|
@@ -612,15 +635,16 @@ var Agent = class extends Actor {
|
|
|
612
635
|
const agent = this;
|
|
613
636
|
async function handleObservation(observationInput) {
|
|
614
637
|
const observation = agent.addObservation(observationInput);
|
|
615
|
-
const
|
|
616
|
-
if (
|
|
617
|
-
const
|
|
638
|
+
const interactInput = getInput?.(observation);
|
|
639
|
+
if (interactInput) {
|
|
640
|
+
const decision = await agentDecide(agent, {
|
|
618
641
|
machine,
|
|
619
642
|
state: observation.state,
|
|
620
|
-
...
|
|
643
|
+
...interactInput
|
|
621
644
|
});
|
|
622
|
-
if (
|
|
623
|
-
|
|
645
|
+
if (decision?.nextEvent) {
|
|
646
|
+
decision.nextEvent["_decision"] = decision.id;
|
|
647
|
+
actorRef.send(decision.nextEvent);
|
|
624
648
|
}
|
|
625
649
|
}
|
|
626
650
|
prevState = observationInput.state;
|
|
@@ -630,11 +654,14 @@ var Agent = class extends Actor {
|
|
|
630
654
|
if (!subscribed || inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
|
|
631
655
|
return;
|
|
632
656
|
}
|
|
657
|
+
const decisionId = inspEvent.event["_decision"];
|
|
658
|
+
const decision = decisionId ? agent.getDecisions().find((d) => d.id === decisionId) : void 0;
|
|
633
659
|
const observationInput = {
|
|
634
660
|
event: inspEvent.event,
|
|
635
661
|
prevState,
|
|
636
662
|
state: inspEvent.snapshot,
|
|
637
|
-
machine: actorRef.src
|
|
663
|
+
machine: actorRef.src,
|
|
664
|
+
goal: decision?.goal
|
|
638
665
|
};
|
|
639
666
|
await handleObservation(observationInput);
|
|
640
667
|
}
|
|
@@ -642,10 +669,10 @@ var Agent = class extends Actor {
|
|
|
642
669
|
if (actorRef._processingStatus === 1) {
|
|
643
670
|
handleObservation({
|
|
644
671
|
prevState: void 0,
|
|
645
|
-
event:
|
|
646
|
-
// TODO: unknown events?
|
|
672
|
+
event: void 0,
|
|
647
673
|
state: actorRef.getSnapshot(),
|
|
648
|
-
machine: actorRef.src
|
|
674
|
+
machine: actorRef.src,
|
|
675
|
+
goal: void 0
|
|
649
676
|
});
|
|
650
677
|
}
|
|
651
678
|
return {
|
|
@@ -663,11 +690,14 @@ var Agent = class extends Actor {
|
|
|
663
690
|
if (inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
|
|
664
691
|
return;
|
|
665
692
|
}
|
|
693
|
+
const decisionId = inspEvent.event["_decision"];
|
|
694
|
+
const decision = decisionId ? this.getDecisions().find((d) => d.id === decisionId) : void 0;
|
|
666
695
|
const observationInput = {
|
|
667
696
|
event: inspEvent.event,
|
|
668
697
|
prevState,
|
|
669
698
|
state: inspEvent.snapshot,
|
|
670
|
-
machine: actorRef.src
|
|
699
|
+
machine: actorRef.src,
|
|
700
|
+
goal: decision?.goal
|
|
671
701
|
};
|
|
672
702
|
prevState = observationInput.state;
|
|
673
703
|
this.addObservation(observationInput);
|
|
@@ -683,14 +713,14 @@ var Agent = class extends Actor {
|
|
|
683
713
|
});
|
|
684
714
|
}
|
|
685
715
|
/**
|
|
686
|
-
* Resolves with an `
|
|
716
|
+
* Resolves with an `AgentDecision` based on the information provided in the `options`, including:
|
|
687
717
|
*
|
|
688
718
|
* - The `goal` for the agent to achieve
|
|
689
719
|
* - The observed current `state`
|
|
690
720
|
* - The `machine` (e.g. a state machine) that specifies what can happen next
|
|
691
721
|
* - Additional `context`
|
|
692
722
|
*/
|
|
693
|
-
decide(opts) {
|
|
723
|
+
async decide(opts) {
|
|
694
724
|
return agentDecide(this, opts);
|
|
695
725
|
}
|
|
696
726
|
};
|
package/examples/chatbot.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { createAgent, fromDecision } from '../src';
|
|
2
|
+
import { createAgent, fromDecision, TypesFromAgent } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { assign, createActor, log, setup } from 'xstate';
|
|
5
5
|
import { fromTerminal } from './helpers/helpers';
|
|
@@ -19,7 +19,7 @@ const agent = createAgent({
|
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
const machine = setup({
|
|
22
|
-
types: agent
|
|
22
|
+
types: {} as TypesFromAgent<typeof agent>,
|
|
23
23
|
actors: { getFromTerminal: fromTerminal },
|
|
24
24
|
}).createMachine({
|
|
25
25
|
initial: 'listening',
|
package/examples/cot.ts
CHANGED
|
@@ -1,92 +1,40 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { createAgent
|
|
2
|
+
import { createAgent } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { getFromTerminal } from './helpers/helpers';
|
|
5
|
+
import { chainOfThoughtStrategy } from '../src/strategies/chainOfThought';
|
|
6
6
|
|
|
7
7
|
const agent = createAgent({
|
|
8
8
|
id: 'chain-of-thought',
|
|
9
|
-
model: openai('gpt-4o
|
|
9
|
+
model: openai('gpt-4o'),
|
|
10
10
|
events: {
|
|
11
|
-
'agent.think': z.object({
|
|
12
|
-
thought: z
|
|
13
|
-
.string()
|
|
14
|
-
.describe('The thought process to answering the question'),
|
|
15
|
-
}),
|
|
16
11
|
'agent.answer': z.object({
|
|
17
12
|
answer: z.string().describe('The answer to the question'),
|
|
18
13
|
}),
|
|
19
14
|
},
|
|
20
15
|
context: {
|
|
21
16
|
question: z.string().nullable(),
|
|
22
|
-
thought: z.string().nullable(),
|
|
23
17
|
},
|
|
18
|
+
strategy: chainOfThoughtStrategy,
|
|
24
19
|
});
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
src: 'getFromTerminal',
|
|
39
|
-
input: 'What would you like to ask?',
|
|
40
|
-
onDone: {
|
|
41
|
-
actions: assign({
|
|
42
|
-
question: ({ event }) => event.output,
|
|
43
|
-
}),
|
|
44
|
-
target: 'thinking',
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
thinking: {
|
|
49
|
-
on: {
|
|
50
|
-
'agent.think': {
|
|
51
|
-
actions: [
|
|
52
|
-
log(({ event }) => `Thought: ${event.thought}`),
|
|
53
|
-
assign({
|
|
54
|
-
thought: ({ event }) => event.thought,
|
|
55
|
-
}),
|
|
56
|
-
],
|
|
57
|
-
target: 'answering',
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
answering: {
|
|
62
|
-
on: {
|
|
63
|
-
'agent.answer': {
|
|
64
|
-
actions: log(({ event }) => `Answer: ${event.answer}`),
|
|
65
|
-
target: 'answered',
|
|
66
|
-
},
|
|
21
|
+
// agent.onMessage((msg) => console.log(msg.content));
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
const msg = await getFromTerminal('what?');
|
|
25
|
+
|
|
26
|
+
const decision = await agent.decide({
|
|
27
|
+
messages: agent.getMessages(),
|
|
28
|
+
goal: 'Answer the question.',
|
|
29
|
+
state: {
|
|
30
|
+
value: 'thinking',
|
|
31
|
+
context: {
|
|
32
|
+
question: msg,
|
|
67
33
|
},
|
|
68
34
|
},
|
|
69
|
-
|
|
70
|
-
type: 'final',
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
});
|
|
35
|
+
});
|
|
74
36
|
|
|
75
|
-
|
|
37
|
+
console.log(decision?.nextEvent?.answer);
|
|
38
|
+
}
|
|
76
39
|
|
|
77
|
-
|
|
78
|
-
if (obs.state.matches('thinking')) {
|
|
79
|
-
return {
|
|
80
|
-
goal: 'Think step-by-step about how you would answer the question',
|
|
81
|
-
context: obs.state.context,
|
|
82
|
-
messages: agent.getMessages(),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
if (obs.state.matches('answering')) {
|
|
86
|
-
return {
|
|
87
|
-
goal: 'Answer the question',
|
|
88
|
-
context: obs.state.context,
|
|
89
|
-
messages: agent.getMessages(),
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
});
|
|
40
|
+
main();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createAgent, fromDecision } from '../src';
|
|
1
|
+
import { createAgent, EventFromAgent, fromDecision } from '../src';
|
|
2
2
|
import { assign, createActor, setup } from 'xstate';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { z } from 'zod';
|
|
@@ -38,8 +38,8 @@ const machine = setup({
|
|
|
38
38
|
messages: string[];
|
|
39
39
|
},
|
|
40
40
|
events: {} as
|
|
41
|
-
| typeof customerServiceAgent
|
|
42
|
-
| typeof customerAgent
|
|
41
|
+
| EventFromAgent<typeof customerServiceAgent>
|
|
42
|
+
| EventFromAgent<typeof customerAgent>,
|
|
43
43
|
},
|
|
44
44
|
actors: {
|
|
45
45
|
customerService: fromDecision(customerServiceAgent),
|
package/examples/email.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { createAgent,
|
|
2
|
+
import { ContextFromAgent, createAgent, EventFromAgent } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { assign, createActor, setup } from 'xstate';
|
|
5
5
|
import { fromTerminal } from './helpers/helpers';
|
|
@@ -27,12 +27,12 @@ const agent = createAgent({
|
|
|
27
27
|
|
|
28
28
|
const machine = setup({
|
|
29
29
|
types: {
|
|
30
|
-
events: agent
|
|
30
|
+
events: {} as EventFromAgent<typeof agent>,
|
|
31
31
|
input: {} as {
|
|
32
32
|
email: string;
|
|
33
33
|
instructions: string;
|
|
34
34
|
},
|
|
35
|
-
context: agent
|
|
35
|
+
context: {} as ContextFromAgent<typeof agent>,
|
|
36
36
|
},
|
|
37
37
|
actors: { getFromTerminal: fromTerminal },
|
|
38
38
|
}).createMachine({
|
|
@@ -101,14 +101,12 @@ agent.interact(actor, ({ state }) => {
|
|
|
101
101
|
if (state.matches('checking')) {
|
|
102
102
|
return {
|
|
103
103
|
goal: 'Respond to the email given the instructions and the provided clarifications. If not enough information is provided, ask for clarification. Otherwise, if you are absolutely sure that there is no ambiguous or missing information, create and submit a response email.',
|
|
104
|
-
context: state.context,
|
|
105
104
|
};
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
if (state.matches('submitting')) {
|
|
109
108
|
return {
|
|
110
109
|
goal: 'Create and submit an email based on the instructions.',
|
|
111
|
-
context: state.context,
|
|
112
110
|
};
|
|
113
111
|
}
|
|
114
112
|
});
|
package/examples/example.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { createAgent, fromDecision, fromText } from '../src';
|
|
2
|
+
import { createAgent, EventFromAgent, fromDecision, fromText } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { assign, createActor, setup } from 'xstate';
|
|
5
5
|
|
|
@@ -18,7 +18,7 @@ const agent = createAgent({
|
|
|
18
18
|
|
|
19
19
|
const machine = setup({
|
|
20
20
|
types: {
|
|
21
|
-
events: agent
|
|
21
|
+
events: {} as EventFromAgent<typeof agent>,
|
|
22
22
|
},
|
|
23
23
|
actors: { agent: fromDecision(agent), summarizer: fromText(agent) },
|
|
24
24
|
}).createMachine({
|
package/examples/goal.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { createAgent, fromDecision } from '../src';
|
|
2
|
+
import { createAgent, EventFromAgent, fromDecision } from '../src';
|
|
3
3
|
import { openai } from '@ai-sdk/openai';
|
|
4
4
|
import { assign, createActor, log, setup } from 'xstate';
|
|
5
5
|
import { fromTerminal } from './helpers/helpers';
|
|
@@ -25,7 +25,7 @@ const machine = setup({
|
|
|
25
25
|
question: string | null;
|
|
26
26
|
goal: string | null;
|
|
27
27
|
},
|
|
28
|
-
events: agent
|
|
28
|
+
events: {} as EventFromAgent<typeof agent>,
|
|
29
29
|
},
|
|
30
30
|
actors: { decider, getFromTerminal: fromTerminal },
|
|
31
31
|
}).createMachine({
|
package/examples/joke.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assign, createActor, fromCallback, log, setup } from 'xstate';
|
|
2
|
-
import { createAgent, fromDecision } from '../src';
|
|
2
|
+
import { createAgent, fromDecision, TypesFromAgent } from '../src';
|
|
3
3
|
import { loadingAnimation } from './helpers/loader';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { openai } from '@ai-sdk/openai';
|
|
@@ -81,7 +81,7 @@ const agent = createAgent({
|
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
const jokeMachine = setup({
|
|
84
|
-
types: agent
|
|
84
|
+
types: {} as TypesFromAgent<typeof agent>,
|
|
85
85
|
actors: {
|
|
86
86
|
agent: fromDecision(agent),
|
|
87
87
|
loader,
|
|
@@ -186,40 +186,40 @@ const jokeMachine = setup({
|
|
|
186
186
|
|
|
187
187
|
const actor = createActor(jokeMachine);
|
|
188
188
|
|
|
189
|
-
agent.interact(actor, (
|
|
190
|
-
if (
|
|
189
|
+
agent.interact(actor, ({ state }) => {
|
|
190
|
+
if (state.matches('tellingJoke')) {
|
|
191
191
|
return {
|
|
192
192
|
goal: 'Tell me a joke about the topic. Do not make any joke that is not relevant to the topic.',
|
|
193
193
|
context: {
|
|
194
|
-
topic:
|
|
194
|
+
topic: state.context.topic,
|
|
195
195
|
},
|
|
196
196
|
};
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
if (
|
|
199
|
+
if (state.matches('relevance')) {
|
|
200
200
|
return {
|
|
201
201
|
goal: 'An irrelevant joke has no reference to the topic. If the last joke is completely irrelevant to the topic, ask for a new joke topic. Otherwise, continue.',
|
|
202
202
|
context: {
|
|
203
|
-
topic:
|
|
204
|
-
lastJoke:
|
|
203
|
+
topic: state.context.topic,
|
|
204
|
+
lastJoke: state.context.jokes.at(-1),
|
|
205
205
|
},
|
|
206
206
|
};
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
if (
|
|
209
|
+
if (state.matches('rateJoke')) {
|
|
210
210
|
return {
|
|
211
211
|
goal: 'Rate the last joke on a scale of 1 to 10.',
|
|
212
212
|
context: {
|
|
213
|
-
lastJoke:
|
|
213
|
+
lastJoke: state.context.jokes.at(-1),
|
|
214
214
|
},
|
|
215
215
|
};
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
if (
|
|
218
|
+
if (state.matches('decide')) {
|
|
219
219
|
return {
|
|
220
220
|
goal: 'Choose what to do next, given the previous rating of the joke.',
|
|
221
221
|
context: {
|
|
222
|
-
lastRating:
|
|
222
|
+
lastRating: state.context.lastRating,
|
|
223
223
|
},
|
|
224
224
|
};
|
|
225
225
|
}
|