@statelyai/agent 2.0.0-next.0 → 2.0.0-next.2
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/grumpy-dolphins-think.md +17 -0
- package/.changeset/old-jobs-check.md +5 -0
- package/.changeset/old-teachers-tap.md +5 -0
- package/.changeset/pre.json +7 -1
- package/.changeset/smart-yaks-pull.md +23 -0
- package/CHANGELOG.md +52 -0
- package/dist/index.d.mts +69 -66
- package/dist/index.d.ts +69 -66
- package/dist/index.js +111 -79
- package/dist/index.mjs +114 -82
- package/examples/chatbot-alt.ts +1 -1
- package/examples/chatbot.ts +3 -3
- package/examples/cot.ts +7 -25
- package/examples/customer-service-sim.ts +7 -7
- package/examples/email.ts +37 -35
- package/examples/example.ts +3 -3
- package/examples/goal.ts +3 -3
- package/examples/joke.ts +3 -3
- package/examples/jugs.ts +5 -8
- package/examples/learn-from-feedback.ts +100 -0
- package/examples/multi.ts +1 -1
- package/examples/number.ts +3 -3
- package/examples/raffle.ts +3 -3
- package/examples/river-crossing.ts +5 -8
- package/examples/simple.ts +14 -11
- package/examples/summary.ts +3 -6
- package/examples/support.ts +43 -39
- package/examples/ticTacToe.ts +48 -6
- package/examples/todo.ts +3 -3
- package/examples/tutor.ts +4 -4
- package/examples/verify.ts +3 -3
- package/examples/weather-agent.ts +141 -0
- package/examples/weather.ts +24 -24
- package/examples/wiki.ts +1 -1
- package/examples/word.ts +9 -7
- package/package.json +6 -3
- package/src/agent.test.ts +161 -19
- package/src/agent.ts +66 -250
- package/src/decide.test.ts +172 -3
- package/src/decide.ts +50 -30
- package/src/middleware.ts +2 -14
- package/src/strategies/chainOfThought.ts +48 -0
- package/src/strategies/shortestPath.test.ts +91 -0
- package/src/{planners/shortestPathPlanner.ts → strategies/shortestPath.ts} +32 -19
- package/src/{planners/simplePlanner.ts → strategies/simple.ts} +28 -24
- package/src/types.ts +75 -34
- package/src/utils.ts +23 -0
- package/vitest.config.ts +9 -3
- package/src/strategies/chain-of-note.ts +0 -106
package/src/types.ts
CHANGED
|
@@ -31,8 +31,8 @@ export type CostFunction<TEvent extends EventObject> = (
|
|
|
31
31
|
path: AgentPath<TEvent>
|
|
32
32
|
) => number;
|
|
33
33
|
|
|
34
|
-
export type
|
|
35
|
-
|
|
34
|
+
export type AgentDecideInput<TEvent extends EventObject> = Omit<
|
|
35
|
+
AgentGenerateTextOptions,
|
|
36
36
|
'prompt' | 'tools'
|
|
37
37
|
> & {
|
|
38
38
|
/**
|
|
@@ -41,7 +41,7 @@ export type AgentPlanInput<TEvent extends EventObject> = Omit<
|
|
|
41
41
|
state: ObservedState;
|
|
42
42
|
/**
|
|
43
43
|
* The goal for the agent to accomplish.
|
|
44
|
-
* The agent will
|
|
44
|
+
* The agent will make a decision based on this goal.
|
|
45
45
|
*/
|
|
46
46
|
goal: string;
|
|
47
47
|
/**
|
|
@@ -55,14 +55,20 @@ export type AgentPlanInput<TEvent extends EventObject> = Omit<
|
|
|
55
55
|
*/
|
|
56
56
|
machine?: AnyStateMachine;
|
|
57
57
|
/**
|
|
58
|
-
* The previous
|
|
58
|
+
* The previous decision made by the agent.
|
|
59
59
|
*/
|
|
60
|
-
|
|
60
|
+
prevDecision?: AgentDecision<TEvent>;
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* The total cost of the path to the goal state.
|
|
64
64
|
*/
|
|
65
65
|
costFunction?: CostFunction<TEvent>;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The maximum number of attempts to make a decision.
|
|
69
|
+
* Defaults to 2.
|
|
70
|
+
*/
|
|
71
|
+
maxAttempts?: number;
|
|
66
72
|
};
|
|
67
73
|
|
|
68
74
|
export type AgentStep<TEvent extends EventObject> = {
|
|
@@ -80,14 +86,14 @@ export type AgentPath<TEvent extends EventObject> = {
|
|
|
80
86
|
weight?: number;
|
|
81
87
|
};
|
|
82
88
|
|
|
83
|
-
export type
|
|
89
|
+
export type AgentDecision<TEvent extends EventObject> = {
|
|
84
90
|
/**
|
|
85
|
-
* The
|
|
91
|
+
* The strategy used to generate the decision
|
|
86
92
|
*/
|
|
87
|
-
|
|
93
|
+
strategy: string;
|
|
88
94
|
goal: string;
|
|
89
95
|
/**
|
|
90
|
-
* The ending state of the
|
|
96
|
+
* The ending state of the decision.
|
|
91
97
|
*/
|
|
92
98
|
goalState: ObservedState | undefined;
|
|
93
99
|
/**
|
|
@@ -138,44 +144,52 @@ export type PromptTemplate<TEvents extends EventObject> = (data: {
|
|
|
138
144
|
observations?: AgentObservation<any>[]; // TODO
|
|
139
145
|
feedback?: AgentFeedback[];
|
|
140
146
|
messages?: AgentMessage[];
|
|
141
|
-
|
|
147
|
+
decisions?: AgentDecision<TEvents>[];
|
|
142
148
|
}) => string;
|
|
143
149
|
|
|
144
|
-
export type
|
|
150
|
+
export type AgentStrategy<T extends AnyAgent> = (
|
|
145
151
|
agent: T,
|
|
146
|
-
input:
|
|
147
|
-
) => Promise<
|
|
152
|
+
input: AgentDecideInput<EventsFromAgent<T>>
|
|
153
|
+
) => Promise<AgentDecision<EventsFromAgent<T>> | undefined>;
|
|
148
154
|
|
|
149
|
-
export type
|
|
155
|
+
export type AgentInteractInput<T extends AnyAgent> = Omit<
|
|
156
|
+
AgentDecideOptions<T>,
|
|
157
|
+
'state'
|
|
158
|
+
>;
|
|
159
|
+
|
|
160
|
+
export type AgentDecideOptions<T extends AnyAgent> = {
|
|
150
161
|
goal: string;
|
|
151
|
-
model?: LanguageModel;
|
|
152
162
|
state: ObservedState;
|
|
163
|
+
context?: Record<string, any>;
|
|
153
164
|
machine?: AnyStateMachine;
|
|
165
|
+
model?: LanguageModel;
|
|
154
166
|
execute?: (event: AnyEventObject) => Promise<void>;
|
|
155
|
-
|
|
167
|
+
strategy?: AgentStrategy<T>;
|
|
156
168
|
events?: ZodEventMapping;
|
|
169
|
+
allowedEvents?: Array<EventsFromAgent<T>['type']>;
|
|
170
|
+
/**
|
|
171
|
+
* The maximum number of times the agent will attempt to make a decision.
|
|
172
|
+
* Defaults to 2.
|
|
173
|
+
*/
|
|
174
|
+
maxAttempts?: number;
|
|
157
175
|
} & Omit<Parameters<typeof generateText>[0], 'model' | 'tools' | 'prompt'>;
|
|
158
176
|
|
|
159
177
|
export interface AgentFeedback {
|
|
160
|
-
goal
|
|
161
|
-
observationId
|
|
178
|
+
goal: string;
|
|
179
|
+
observationId: string;
|
|
162
180
|
/**
|
|
163
181
|
* The message correlation that the feedback is relevant for
|
|
164
182
|
*/
|
|
165
|
-
correlationId?: string;
|
|
166
183
|
attributes: Record<string, any>;
|
|
167
|
-
reward: number;
|
|
168
184
|
timestamp: number;
|
|
169
185
|
episodeId: string;
|
|
170
186
|
}
|
|
171
187
|
|
|
172
188
|
export interface AgentFeedbackInput {
|
|
173
|
-
goal
|
|
174
|
-
observationId
|
|
175
|
-
|
|
176
|
-
attributes?: Record<string, any>;
|
|
189
|
+
goal: string;
|
|
190
|
+
observationId: string;
|
|
191
|
+
attributes: Record<string, any>;
|
|
177
192
|
timestamp?: number;
|
|
178
|
-
reward?: number;
|
|
179
193
|
}
|
|
180
194
|
|
|
181
195
|
export type AgentMessage = CoreMessage & {
|
|
@@ -313,13 +327,12 @@ export type AgentMessageInput = CoreMessage & {
|
|
|
313
327
|
* which message this message is responding to, if any.
|
|
314
328
|
*/
|
|
315
329
|
responseId?: string;
|
|
316
|
-
correlationId?: string;
|
|
317
|
-
parentCorrelationId?: string;
|
|
318
330
|
result?: GenerateTextResult<any>;
|
|
319
331
|
};
|
|
320
332
|
|
|
321
333
|
export interface AgentObservation<TActor extends ActorRefLike> {
|
|
322
334
|
id: string;
|
|
335
|
+
// TODO: goal
|
|
323
336
|
prevState: SnapshotFrom<TActor> | undefined;
|
|
324
337
|
event: EventFrom<TActor> | undefined;
|
|
325
338
|
state: SnapshotFrom<TActor>;
|
|
@@ -344,7 +357,7 @@ export type AgentDecisionInput = {
|
|
|
344
357
|
} & Omit<Parameters<typeof generateText>[0], 'model' | 'tools' | 'prompt'>;
|
|
345
358
|
|
|
346
359
|
export type AgentDecisionLogic<TEvents extends EventObject> = PromiseActorLogic<
|
|
347
|
-
|
|
360
|
+
AgentDecision<TEvents> | undefined,
|
|
348
361
|
AgentDecisionInput | string
|
|
349
362
|
>;
|
|
350
363
|
|
|
@@ -362,8 +375,8 @@ export type AgentEmitted<TEvents extends EventObject> =
|
|
|
362
375
|
message: AgentMessage;
|
|
363
376
|
}
|
|
364
377
|
| {
|
|
365
|
-
type: '
|
|
366
|
-
|
|
378
|
+
type: 'decision';
|
|
379
|
+
decision: AgentDecision<TEvents>;
|
|
367
380
|
};
|
|
368
381
|
|
|
369
382
|
export type AgentLogic<TEvents extends EventObject> = ActorLogic<
|
|
@@ -381,8 +394,8 @@ export type AgentLogic<TEvents extends EventObject> = ActorLogic<
|
|
|
381
394
|
message: AgentMessage;
|
|
382
395
|
}
|
|
383
396
|
| {
|
|
384
|
-
type: 'agent.
|
|
385
|
-
|
|
397
|
+
type: 'agent.decision';
|
|
398
|
+
decision: AgentDecision<TEvents>;
|
|
386
399
|
},
|
|
387
400
|
any, // TODO: input
|
|
388
401
|
any,
|
|
@@ -402,7 +415,7 @@ export type ContextFromZodContextMapping<
|
|
|
402
415
|
[K in keyof TContextSchema & string]: TypeOf<TContextSchema[K]>;
|
|
403
416
|
};
|
|
404
417
|
|
|
405
|
-
export type AnyAgent = Agent<any, any>;
|
|
418
|
+
export type AnyAgent = Agent<any, any, any, any>;
|
|
406
419
|
|
|
407
420
|
export type FromAgent<T> = T | ((agent: AnyAgent) => T | Promise<T>);
|
|
408
421
|
|
|
@@ -446,7 +459,7 @@ export type ObservedStateFrom<TActor extends ActorRefLike> = Pick<
|
|
|
446
459
|
export type AgentMemoryContext = {
|
|
447
460
|
observations: AgentObservation<any>[]; // TODO
|
|
448
461
|
messages: AgentMessage[];
|
|
449
|
-
|
|
462
|
+
decisions: AgentDecision<any>[];
|
|
450
463
|
feedback: AgentFeedback[];
|
|
451
464
|
};
|
|
452
465
|
|
|
@@ -465,3 +478,31 @@ export interface AgentLongTermMemory {
|
|
|
465
478
|
}
|
|
466
479
|
|
|
467
480
|
export type Compute<A extends any> = { [K in keyof A]: A[K] } & unknown;
|
|
481
|
+
|
|
482
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
483
|
+
|
|
484
|
+
export type EventsFromAgent<T extends AnyAgent> = T extends Agent<
|
|
485
|
+
infer _,
|
|
486
|
+
infer __,
|
|
487
|
+
infer TEvents,
|
|
488
|
+
infer ___
|
|
489
|
+
>
|
|
490
|
+
? TEvents
|
|
491
|
+
: never;
|
|
492
|
+
|
|
493
|
+
export type TypesFromAgent<T extends AnyAgent> = T extends Agent<
|
|
494
|
+
infer TContextSchema,
|
|
495
|
+
infer TEventSchema
|
|
496
|
+
>
|
|
497
|
+
? {
|
|
498
|
+
context: ContextFromZodContextMapping<TContextSchema>;
|
|
499
|
+
events: EventsFromZodEventMapping<TEventSchema>;
|
|
500
|
+
}
|
|
501
|
+
: never;
|
|
502
|
+
|
|
503
|
+
export type ContextFromAgent<T extends AnyAgent> = T extends Agent<
|
|
504
|
+
infer TContextSchema,
|
|
505
|
+
infer _TEventSchema
|
|
506
|
+
>
|
|
507
|
+
? ContextFromZodContextMapping<TContextSchema>
|
|
508
|
+
: never;
|
package/src/utils.ts
CHANGED
|
@@ -59,6 +59,18 @@ export function wrapInXml(tagName: string, content: string): string {
|
|
|
59
59
|
return `<${tagName}>${content}</${tagName}>`;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
export function convertToXml(obj: Record<string, any>): string {
|
|
63
|
+
return Object.entries(obj)
|
|
64
|
+
.map(([key, value]) => {
|
|
65
|
+
if (typeof value === 'object' && value !== null) {
|
|
66
|
+
return wrapInXml(key, convertToXml(value));
|
|
67
|
+
} else {
|
|
68
|
+
return wrapInXml(key, value);
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
.join('');
|
|
72
|
+
}
|
|
73
|
+
|
|
62
74
|
export function randomId(prefix?: string): string {
|
|
63
75
|
const timestamp = Date.now().toString(36);
|
|
64
76
|
const random = Math.random().toString(36).substring(2, 9);
|
|
@@ -103,3 +115,14 @@ export function getTransitions(
|
|
|
103
115
|
});
|
|
104
116
|
return getAllTransitions(resolvedState);
|
|
105
117
|
}
|
|
118
|
+
|
|
119
|
+
export function isMachineActor(
|
|
120
|
+
actor: ActorRefLike
|
|
121
|
+
): actor is typeof actor & { src: AnyStateMachine } {
|
|
122
|
+
return (
|
|
123
|
+
'src' in actor &&
|
|
124
|
+
typeof actor.src === 'object' &&
|
|
125
|
+
actor.src !== null &&
|
|
126
|
+
'definition' in actor.src
|
|
127
|
+
);
|
|
128
|
+
}
|
package/vitest.config.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
2
|
import dotenv from 'dotenv';
|
|
3
3
|
dotenv.config();
|
|
4
4
|
|
|
5
|
-
export default {
|
|
5
|
+
export default defineConfig({
|
|
6
6
|
test: {
|
|
7
7
|
testTimeout: 10000, // Global timeout of 10000ms for all tests
|
|
8
|
+
coverage: {
|
|
9
|
+
provider: 'v8',
|
|
10
|
+
reporter: ['text', 'json', 'html'],
|
|
11
|
+
exclude: ['**.test.ts'],
|
|
12
|
+
include: ['src'],
|
|
13
|
+
},
|
|
8
14
|
},
|
|
9
|
-
};
|
|
15
|
+
});
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { GenerateTextResult, LanguageModel } from 'ai';
|
|
2
|
-
import wiki, { wikiSearchResult, wikiSummary } from 'wikipedia';
|
|
3
|
-
import { assign, fromPromise, setup } from 'xstate';
|
|
4
|
-
import { AnyAgent } from '../types';
|
|
5
|
-
|
|
6
|
-
const searchWiki = fromPromise(
|
|
7
|
-
async ({
|
|
8
|
-
input,
|
|
9
|
-
}: {
|
|
10
|
-
input: {
|
|
11
|
-
query: string;
|
|
12
|
-
limit?: number;
|
|
13
|
-
};
|
|
14
|
-
}) => {
|
|
15
|
-
const passages = await wiki.search(input.query, {
|
|
16
|
-
limit: input.limit ?? 5,
|
|
17
|
-
});
|
|
18
|
-
return passages;
|
|
19
|
-
}
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
const extractSummaries = fromPromise(
|
|
23
|
-
async ({
|
|
24
|
-
input,
|
|
25
|
-
}: {
|
|
26
|
-
input: {
|
|
27
|
-
searchResult: wikiSearchResult;
|
|
28
|
-
};
|
|
29
|
-
}) => {
|
|
30
|
-
const summaries = await Promise.all(
|
|
31
|
-
input.searchResult.results.map(async (result) => {
|
|
32
|
-
const summary = await wiki.summary(result.title);
|
|
33
|
-
return {
|
|
34
|
-
title: result.title,
|
|
35
|
-
summary,
|
|
36
|
-
};
|
|
37
|
-
})
|
|
38
|
-
);
|
|
39
|
-
return summaries;
|
|
40
|
-
}
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
export const chainOfNote = setup({
|
|
44
|
-
types: {
|
|
45
|
-
input: {} as {
|
|
46
|
-
model: LanguageModel;
|
|
47
|
-
agent: AnyAgent;
|
|
48
|
-
prompt: string;
|
|
49
|
-
},
|
|
50
|
-
context: {} as {
|
|
51
|
-
searchResults: wikiSearchResult | null;
|
|
52
|
-
summaries:
|
|
53
|
-
| {
|
|
54
|
-
title: any;
|
|
55
|
-
summary: wikiSummary;
|
|
56
|
-
}[]
|
|
57
|
-
| null;
|
|
58
|
-
model: LanguageModel;
|
|
59
|
-
agent: AnyAgent;
|
|
60
|
-
prompt: string;
|
|
61
|
-
},
|
|
62
|
-
output: {} as GenerateTextResult<any>,
|
|
63
|
-
},
|
|
64
|
-
actors: {
|
|
65
|
-
searchWiki,
|
|
66
|
-
extractSummaries,
|
|
67
|
-
},
|
|
68
|
-
}).createMachine({
|
|
69
|
-
initial: 'searching',
|
|
70
|
-
context: ({ input }) => ({
|
|
71
|
-
...input,
|
|
72
|
-
searchResults: null,
|
|
73
|
-
summaries: null,
|
|
74
|
-
}),
|
|
75
|
-
states: {
|
|
76
|
-
searching: {
|
|
77
|
-
invoke: {
|
|
78
|
-
src: 'searchWiki',
|
|
79
|
-
input: ({ context }) => ({
|
|
80
|
-
query: context.prompt,
|
|
81
|
-
}),
|
|
82
|
-
onDone: {
|
|
83
|
-
actions: assign({
|
|
84
|
-
searchResults: ({ event }) => event.output,
|
|
85
|
-
}),
|
|
86
|
-
target: 'extracting',
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
extracting: {
|
|
91
|
-
invoke: {
|
|
92
|
-
src: 'extractSummaries',
|
|
93
|
-
input: ({ context }) => ({
|
|
94
|
-
searchResult: context.searchResults!,
|
|
95
|
-
}),
|
|
96
|
-
onDone: {
|
|
97
|
-
actions: assign({
|
|
98
|
-
summaries: ({ event }) => event.output,
|
|
99
|
-
}),
|
|
100
|
-
target: 'generating',
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
generating: {},
|
|
105
|
-
},
|
|
106
|
-
});
|