@statelyai/agent 0.0.8 → 0.1.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/.vscode/launch.json +12 -1
- package/CHANGELOG.md +18 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +286 -44
- package/dist/index.js +695 -1225
- package/dist/index.mjs +7 -0
- package/examples/chatbot.ts +79 -0
- package/examples/cot.ts +91 -0
- package/examples/email.ts +118 -0
- package/examples/example.ts +81 -0
- package/examples/goal.ts +94 -0
- package/examples/joke.ts +98 -84
- package/examples/multi.ts +103 -0
- package/examples/newspaper.ts +324 -0
- package/examples/number.ts +102 -0
- package/examples/raffle.ts +105 -0
- package/examples/simple.ts +39 -0
- package/examples/support.ts +147 -0
- package/examples/ticTacToe.ts +77 -77
- package/examples/todo.ts +135 -0
- package/examples/tutor.ts +100 -0
- package/examples/verify.ts +120 -0
- package/examples/weather.ts +42 -45
- package/examples/wiki.ts +30 -0
- package/examples/word.ts +168 -0
- package/package.json +29 -23
- package/readme.md +9 -38
- package/src/adapters/vercel.ts +7 -0
- package/src/agent-experimental.ts +221 -0
- package/src/agent.test.ts +187 -0
- package/src/agent.ts +260 -6
- package/src/decision.test.ts +179 -0
- package/src/decision.ts +83 -0
- package/src/index.ts +3 -2
- package/src/memory.ts +25 -0
- package/src/planners/shortestPathPlanner.ts +22 -0
- package/src/planners/simplePlanner.ts +126 -0
- package/src/schemas.ts +9 -20
- package/src/strategies/chain-of-note.ts +155 -0
- package/src/templates/defaultText.ts +18 -0
- package/src/templates/defaultToolCall.ts +10 -0
- package/src/text.ts +232 -0
- package/src/types.ts +363 -46
- package/src/utils.ts +13 -72
- package/tsconfig.json +1 -1
- package/examples/multiAgentCollaboration.ts +0 -0
- package/examples/numberGuesser.ts +0 -101
- package/examples/wordGuesser.ts +0 -144
- package/src/adapter.test.ts +0 -217
- package/src/adapters/openai.ts +0 -303
package/src/types.ts
CHANGED
|
@@ -1,61 +1,378 @@
|
|
|
1
|
-
import OpenAI from 'openai';
|
|
2
|
-
import {
|
|
3
|
-
ChatCompletionCreateParamsNonStreaming,
|
|
4
|
-
ChatCompletionCreateParamsStreaming,
|
|
5
|
-
} from 'openai/resources';
|
|
6
1
|
import {
|
|
2
|
+
ActorLogic,
|
|
3
|
+
ActorRefFrom,
|
|
4
|
+
AnyActorRef,
|
|
7
5
|
AnyEventObject,
|
|
8
|
-
|
|
6
|
+
AnyStateMachine,
|
|
7
|
+
EventFrom,
|
|
8
|
+
EventObject,
|
|
9
9
|
PromiseActorLogic,
|
|
10
|
+
SnapshotFrom,
|
|
11
|
+
StateValue,
|
|
12
|
+
Subscription,
|
|
13
|
+
TransitionSnapshot,
|
|
14
|
+
Values,
|
|
10
15
|
} from 'xstate';
|
|
16
|
+
import {
|
|
17
|
+
CoreMessage,
|
|
18
|
+
CoreTool,
|
|
19
|
+
generateText,
|
|
20
|
+
GenerateTextResult,
|
|
21
|
+
LanguageModel,
|
|
22
|
+
streamText,
|
|
23
|
+
StreamTextResult,
|
|
24
|
+
} from 'ai';
|
|
25
|
+
import { ZodEventMapping } from './schemas';
|
|
26
|
+
import { TypeOf } from 'zod';
|
|
27
|
+
|
|
28
|
+
export type GenerateTextOptions = Parameters<typeof generateText>[0];
|
|
29
|
+
|
|
30
|
+
export type StreamTextOptions = Parameters<typeof streamText>[0];
|
|
31
|
+
|
|
32
|
+
export type AgentPlanInput<TEvent extends EventObject> = {
|
|
33
|
+
model: LanguageModel;
|
|
34
|
+
state: ObservedState;
|
|
35
|
+
goal: string;
|
|
36
|
+
events: ZodEventMapping;
|
|
37
|
+
machine?: AnyStateMachine;
|
|
38
|
+
/**
|
|
39
|
+
* The previous plan
|
|
40
|
+
*/
|
|
41
|
+
previousPlan?: AgentPlan<TEvent>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type AgentPlan<TEvent extends EventObject> = {
|
|
45
|
+
goal: string;
|
|
46
|
+
state: ObservedState;
|
|
47
|
+
content?: string;
|
|
48
|
+
steps?: Array<{
|
|
49
|
+
event: TEvent;
|
|
50
|
+
state?: ObservedState;
|
|
51
|
+
}>;
|
|
52
|
+
nextEvent: TEvent | undefined;
|
|
53
|
+
sessionId: string;
|
|
54
|
+
timestamp: number;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export interface TransitionData {
|
|
58
|
+
eventType: string;
|
|
59
|
+
description?: string;
|
|
60
|
+
guard?: { type: string };
|
|
61
|
+
target?: any;
|
|
62
|
+
}
|
|
11
63
|
|
|
12
|
-
export
|
|
13
|
-
|
|
64
|
+
export type PromptTemplate<TEvents extends EventObject> = (data: {
|
|
65
|
+
goal: string;
|
|
14
66
|
/**
|
|
15
|
-
*
|
|
16
|
-
* possible next events of the parent state machine
|
|
17
|
-
* and sends it to the parent actor.
|
|
67
|
+
* The observed state
|
|
18
68
|
*/
|
|
19
|
-
|
|
20
|
-
inputFn: (input: TInput) => string | ChatCompletionCreateParamsNonStreaming
|
|
21
|
-
) => PromiseActorLogic<AnyEventObject[] | undefined, TInput>;
|
|
69
|
+
state?: ObservedState;
|
|
22
70
|
/**
|
|
23
|
-
*
|
|
71
|
+
* The context to provide.
|
|
72
|
+
* This overrides the observed state.context, if provided.
|
|
24
73
|
*/
|
|
25
|
-
|
|
26
|
-
inputFn: (input: TInput) => string | ChatCompletionCreateParamsNonStreaming
|
|
27
|
-
) => PromiseActorLogic<OpenAI.Chat.Completions.ChatCompletion, TInput>;
|
|
74
|
+
context?: any;
|
|
28
75
|
/**
|
|
29
|
-
*
|
|
76
|
+
* The state machine model of the observed environment
|
|
30
77
|
*/
|
|
31
|
-
|
|
32
|
-
inputFn: (input: TInput) => string | ChatCompletionCreateParamsStreaming
|
|
33
|
-
) => ObservableActorLogic<
|
|
34
|
-
OpenAI.Chat.Completions.ChatCompletionChunk,
|
|
35
|
-
TInput
|
|
36
|
-
>;
|
|
78
|
+
machine?: unknown;
|
|
37
79
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
80
|
+
* The potential next transitions that can be taken
|
|
81
|
+
* in the state machine
|
|
40
82
|
*/
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
83
|
+
transitions?: TransitionData[];
|
|
84
|
+
/**
|
|
85
|
+
* Past observations
|
|
86
|
+
*/
|
|
87
|
+
observations?: AgentObservation<any>[]; // TODO
|
|
88
|
+
feedback?: AgentFeedback[];
|
|
89
|
+
messages?: AgentMessageHistory[];
|
|
90
|
+
plans?: AgentPlan<TEvents>[];
|
|
91
|
+
}) => string;
|
|
92
|
+
|
|
93
|
+
export type AgentPlanner<T extends Agent<any>> = (
|
|
94
|
+
agent: T['eventTypes'],
|
|
95
|
+
options: AgentPlanInput<T['eventTypes']>
|
|
96
|
+
) => Promise<AgentPlan<T['eventTypes']> | undefined>;
|
|
97
|
+
|
|
98
|
+
export type AgentDecideOptions = {
|
|
99
|
+
goal: string;
|
|
100
|
+
model?: LanguageModel;
|
|
101
|
+
context?: any;
|
|
102
|
+
state: ObservedState;
|
|
103
|
+
machine: AnyStateMachine;
|
|
104
|
+
execute?: (event: AnyEventObject) => Promise<void>;
|
|
105
|
+
planner?: AgentPlanner<any>;
|
|
106
|
+
events?: ZodEventMapping;
|
|
107
|
+
} & Omit<
|
|
108
|
+
Parameters<typeof generateText>[0],
|
|
109
|
+
'model' | 'tools' | 'prompt' | 'messages'
|
|
110
|
+
>;
|
|
111
|
+
|
|
112
|
+
export interface AgentFeedback {
|
|
113
|
+
goal: string;
|
|
114
|
+
observationId: string;
|
|
115
|
+
attributes: Record<string, any>;
|
|
116
|
+
timestamp: number;
|
|
117
|
+
sessionId: string;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface AgentFeedbackInput {
|
|
121
|
+
goal: string;
|
|
122
|
+
observationId: string; // Observation ID;
|
|
123
|
+
attributes: Record<string, any>;
|
|
124
|
+
timestamp?: number;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export type AgentMessageHistory = CoreMessage & {
|
|
128
|
+
timestamp: number;
|
|
129
|
+
id: string;
|
|
130
|
+
/**
|
|
131
|
+
* The response ID of the message, which references
|
|
132
|
+
* which message this message is responding to, if any.
|
|
133
|
+
*/
|
|
134
|
+
responseId?: string;
|
|
135
|
+
result?: GenerateTextResult<any>;
|
|
136
|
+
sessionId: string;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export type AgentMessageHistoryInput = CoreMessage & {
|
|
140
|
+
timestamp?: number;
|
|
141
|
+
id?: string;
|
|
142
|
+
/**
|
|
143
|
+
* The response ID of the message, which references
|
|
144
|
+
* which message this message is responding to, if any.
|
|
145
|
+
*/
|
|
146
|
+
responseId?: string;
|
|
147
|
+
result?: GenerateTextResult<any>;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export interface AgentObservation<TActor extends AnyActorRef> {
|
|
151
|
+
id: string;
|
|
152
|
+
prevState: SnapshotFrom<TActor> | undefined;
|
|
153
|
+
event: EventFrom<TActor>;
|
|
154
|
+
state: SnapshotFrom<TActor>;
|
|
155
|
+
sessionId: string;
|
|
156
|
+
timestamp: number;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface AgentObservationInput {
|
|
160
|
+
id?: string;
|
|
161
|
+
prevState: ObservedState | undefined;
|
|
162
|
+
event: AnyEventObject;
|
|
163
|
+
state: ObservedState;
|
|
164
|
+
timestamp?: number;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export type AgentDecisionInput = {
|
|
168
|
+
goal: string;
|
|
169
|
+
model?: LanguageModel;
|
|
170
|
+
context?: any;
|
|
171
|
+
} & Omit<Parameters<typeof generateText>[0], 'model' | 'tools' | 'prompt'>;
|
|
172
|
+
|
|
173
|
+
export type AgentDecisionLogic<TEvents extends EventObject> = PromiseActorLogic<
|
|
174
|
+
AgentPlan<TEvents> | undefined,
|
|
175
|
+
AgentDecisionInput | string
|
|
176
|
+
>;
|
|
177
|
+
|
|
178
|
+
export type AgentEmitted<TEvents extends EventObject> =
|
|
179
|
+
| {
|
|
180
|
+
type: 'feedback';
|
|
181
|
+
feedback: AgentFeedback;
|
|
182
|
+
}
|
|
183
|
+
| {
|
|
184
|
+
type: 'observation';
|
|
185
|
+
observation: AgentObservation<any>; // TODO
|
|
186
|
+
}
|
|
187
|
+
| {
|
|
188
|
+
type: 'message';
|
|
189
|
+
message: AgentMessageHistory;
|
|
190
|
+
}
|
|
191
|
+
| {
|
|
192
|
+
type: 'plan';
|
|
193
|
+
plan: AgentPlan<TEvents>;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
export type AgentLogic<TEvents extends EventObject> = ActorLogic<
|
|
197
|
+
TransitionSnapshot<AgentMemoryContext>,
|
|
198
|
+
| {
|
|
199
|
+
type: 'agent.feedback';
|
|
200
|
+
feedback: AgentFeedback;
|
|
45
201
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
202
|
+
| {
|
|
203
|
+
type: 'agent.observe';
|
|
204
|
+
observation: AgentObservation<any>; // TODO
|
|
205
|
+
}
|
|
206
|
+
| {
|
|
207
|
+
type: 'agent.message';
|
|
208
|
+
message: AgentMessageHistory;
|
|
209
|
+
}
|
|
210
|
+
| {
|
|
211
|
+
type: 'agent.plan';
|
|
212
|
+
plan: AgentPlan<TEvents>;
|
|
213
|
+
},
|
|
214
|
+
any, // TODO: input
|
|
215
|
+
any,
|
|
216
|
+
AgentEmitted<TEvents>
|
|
217
|
+
>;
|
|
218
|
+
|
|
219
|
+
export type EventsFromZodEventMapping<TEventSchemas extends ZodEventMapping> =
|
|
220
|
+
Values<{
|
|
221
|
+
[K in keyof TEventSchemas & string]: {
|
|
222
|
+
type: K;
|
|
223
|
+
} & TypeOf<TEventSchemas[K]>;
|
|
224
|
+
}>;
|
|
225
|
+
|
|
226
|
+
export type Agent<TEvents extends EventObject> = ActorRefFrom<
|
|
227
|
+
AgentLogic<TEvents>
|
|
228
|
+
> & {
|
|
229
|
+
/**
|
|
230
|
+
* The general name of the agent. All agents with the same name are related and
|
|
231
|
+
* able to share experiences (observations, feedback) with each other.
|
|
232
|
+
*/
|
|
233
|
+
name: string;
|
|
234
|
+
/**
|
|
235
|
+
* The unique id of the agent. This is used to partition message history.
|
|
236
|
+
*/
|
|
237
|
+
id?: string;
|
|
238
|
+
description?: string;
|
|
239
|
+
events: ZodEventMapping;
|
|
240
|
+
eventTypes: TEvents;
|
|
241
|
+
model: LanguageModel;
|
|
242
|
+
defaultOptions: GenerateTextOptions;
|
|
243
|
+
memory: AgentLongTermMemory | undefined;
|
|
244
|
+
/**
|
|
245
|
+
* The adapter used to perform LLM actions such as
|
|
246
|
+
* `.generateText(…)` and `.streamText(…)`.
|
|
247
|
+
*
|
|
248
|
+
* Defaults to the Vercel AI SDK.
|
|
249
|
+
*/
|
|
250
|
+
adapter: AIAdapter;
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Resolves with an `AgentPlan` based on the information provided in the `options`, including:
|
|
254
|
+
*
|
|
255
|
+
* - The `goal` for the agent to achieve
|
|
256
|
+
* - The observed current `state`
|
|
257
|
+
* - The `logic` (e.g. a state machine) that specifies what can happen next
|
|
258
|
+
* - Additional `context`
|
|
259
|
+
*/
|
|
260
|
+
decide: (
|
|
261
|
+
options: AgentDecideOptions
|
|
262
|
+
) => Promise<AgentPlan<TEvents> | undefined>;
|
|
263
|
+
|
|
264
|
+
// Generate text
|
|
265
|
+
generateText: (
|
|
266
|
+
options: AgentGenerateTextOptions
|
|
267
|
+
) => Promise<GenerateTextResult<Record<string, any>>>;
|
|
268
|
+
|
|
269
|
+
// Stream text
|
|
270
|
+
streamText: (
|
|
271
|
+
options: AgentStreamTextOptions
|
|
272
|
+
) => Promise<StreamTextResult<Record<string, CoreTool<any, any>>>>;
|
|
273
|
+
|
|
274
|
+
addObservation: (observation: AgentObservationInput) => AgentObservation<any>; // TODO
|
|
275
|
+
addMessage: (history: AgentMessageHistoryInput) => AgentMessageHistory;
|
|
276
|
+
addFeedback: (feedbackItem: AgentFeedbackInput) => AgentFeedback;
|
|
277
|
+
addPlan: (plan: AgentPlan<TEvents>) => void;
|
|
278
|
+
/**
|
|
279
|
+
* Called whenever the agent (LLM assistant) receives or sends a message.
|
|
280
|
+
*/
|
|
281
|
+
onMessage: (callback: (message: AgentMessageHistory) => void) => void;
|
|
282
|
+
/**
|
|
283
|
+
* Selects agent data from its context.
|
|
284
|
+
*/
|
|
285
|
+
select: <T>(selector: (context: AgentMemoryContext) => T) => T;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Inspects state machine actor transitions and automatically observes
|
|
289
|
+
* (prevState, event, state) tuples.
|
|
290
|
+
*/
|
|
291
|
+
interact: <TActor extends AnyActorRef>(
|
|
292
|
+
actorRef: TActor,
|
|
293
|
+
getInput?: (
|
|
294
|
+
observation: AgentObservation<TActor>
|
|
295
|
+
) => AgentDecisionInput | undefined
|
|
296
|
+
) => Subscription;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
export type AnyAgent = Agent<any>;
|
|
300
|
+
|
|
301
|
+
export type FromAgent<T> = T | ((self: AnyAgent) => T | Promise<T>);
|
|
302
|
+
|
|
303
|
+
export interface CommonTextOptions {
|
|
304
|
+
prompt: FromAgent<string>;
|
|
305
|
+
model?: LanguageModel;
|
|
306
|
+
context?: Record<string, any>;
|
|
307
|
+
messages?: FromAgent<CoreMessage[]> | true;
|
|
308
|
+
template?: PromptTemplate<any>;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export type AgentGenerateTextOptions = Omit<
|
|
312
|
+
GenerateTextOptions,
|
|
313
|
+
'model' | 'prompt' | 'messages'
|
|
314
|
+
> &
|
|
315
|
+
CommonTextOptions;
|
|
316
|
+
|
|
317
|
+
export type AgentStreamTextOptions = Omit<
|
|
318
|
+
StreamTextOptions,
|
|
319
|
+
'model' | 'prompt' | 'messages'
|
|
320
|
+
> &
|
|
321
|
+
CommonTextOptions;
|
|
322
|
+
|
|
323
|
+
export interface ObservedState {
|
|
324
|
+
/**
|
|
325
|
+
* The current state value of the state machine, e.g.
|
|
326
|
+
* `"loading"` or `"processing"` or `"ready"`
|
|
327
|
+
*/
|
|
328
|
+
value: StateValue;
|
|
329
|
+
/**
|
|
330
|
+
* Additional contextual data related to the current state
|
|
331
|
+
*/
|
|
332
|
+
context: Record<string, unknown>;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export type ObservedStateFrom<TActor extends AnyActorRef> = Pick<
|
|
336
|
+
SnapshotFrom<TActor>,
|
|
337
|
+
'value' | 'context'
|
|
338
|
+
>;
|
|
339
|
+
|
|
340
|
+
export type AgentMemoryContext = {
|
|
341
|
+
observations: AgentObservation<any>[]; // TODO
|
|
342
|
+
messages: AgentMessageHistory[];
|
|
343
|
+
plans: AgentPlan<any>[];
|
|
344
|
+
feedback: AgentFeedback[];
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
export type AgentMemory = AppendOnlyStorage<AgentMemoryContext>;
|
|
348
|
+
|
|
349
|
+
export interface AppendOnlyStorage<T extends Record<string, any[]>> {
|
|
350
|
+
append<K extends keyof T>(
|
|
351
|
+
sessionId: string,
|
|
352
|
+
key: K,
|
|
353
|
+
item: T[K][0]
|
|
354
|
+
): Promise<void>;
|
|
355
|
+
getAll<K extends keyof T>(
|
|
356
|
+
sessionId: string,
|
|
357
|
+
key: K
|
|
358
|
+
): Promise<T[K] | undefined>;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export interface AgentLongTermMemory {
|
|
362
|
+
get<K extends keyof AgentMemoryContext>(
|
|
363
|
+
key: K
|
|
364
|
+
): Promise<AgentMemoryContext[K]>;
|
|
365
|
+
append<K extends keyof AgentMemoryContext>(
|
|
366
|
+
key: K,
|
|
367
|
+
item: AgentMemoryContext[K][0]
|
|
368
|
+
): Promise<void>;
|
|
369
|
+
set<K extends keyof AgentMemoryContext>(
|
|
370
|
+
key: K,
|
|
371
|
+
items: AgentMemoryContext[K]
|
|
372
|
+
): Promise<void>;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export interface AIAdapter {
|
|
376
|
+
generateText: typeof generateText;
|
|
377
|
+
streamText: typeof streamText;
|
|
61
378
|
}
|
package/src/utils.ts
CHANGED
|
@@ -1,81 +1,22 @@
|
|
|
1
|
-
import { AnyMachineSnapshot, AnyStateNode
|
|
2
|
-
import {
|
|
3
|
-
import { JSONSchema7 } from 'json-schema-to-ts/lib/types/definitions';
|
|
4
|
-
import zodToJsonSchema, { JsonSchema7Type } from 'zod-to-json-schema';
|
|
5
|
-
import { ZodEventTypes } from './schemas';
|
|
6
|
-
import { z } from 'zod';
|
|
1
|
+
import { AnyMachineSnapshot, AnyStateNode } from 'xstate';
|
|
2
|
+
import { TransitionData } from './types';
|
|
7
3
|
|
|
8
|
-
export function getAllTransitions(state: AnyMachineSnapshot) {
|
|
4
|
+
export function getAllTransitions(state: AnyMachineSnapshot): TransitionData[] {
|
|
9
5
|
const nodes = state._nodes;
|
|
10
6
|
const transitions = (nodes as AnyStateNode[])
|
|
11
7
|
.map((node) => [...(node as AnyStateNode).transitions.values()])
|
|
12
|
-
.flat(2)
|
|
8
|
+
.flat(2)
|
|
9
|
+
.map((transition) => ({
|
|
10
|
+
...transition,
|
|
11
|
+
guard:
|
|
12
|
+
typeof transition.guard === 'string'
|
|
13
|
+
? { type: transition.guard }
|
|
14
|
+
: (transition.guard as any), // TODO: fix
|
|
15
|
+
}));
|
|
13
16
|
|
|
14
17
|
return transitions;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
description?: string;
|
|
20
|
-
properties?: {
|
|
21
|
-
[key: string]: JsonSchema7Type;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export type ContextSchema = JSONSchema7 & { type: 'object' };
|
|
27
|
-
|
|
28
|
-
export type ConvertToJSONSchemas<T> = {
|
|
29
|
-
[K in keyof T]: {
|
|
30
|
-
properties: { type: { const: K } } & Prop<T[K], 'properties'>;
|
|
31
|
-
type: 'object';
|
|
32
|
-
required: Array<(keyof Prop<T[K], 'properties'> & string) | 'type'>;
|
|
33
|
-
additionalProperties: false;
|
|
34
|
-
};
|
|
35
|
-
} & {};
|
|
36
|
-
|
|
37
|
-
export function createEventSchemas<T extends EventSchemas>(
|
|
38
|
-
eventSchemaMap: T
|
|
39
|
-
): ConvertToJSONSchemas<T> {
|
|
40
|
-
const resolvedEventSchemaMap = {};
|
|
41
|
-
|
|
42
|
-
for (const [key, schema] of Object.entries(eventSchemaMap)) {
|
|
43
|
-
// @ts-ignore
|
|
44
|
-
resolvedEventSchemaMap[key] = {
|
|
45
|
-
type: 'object',
|
|
46
|
-
required: ['type'],
|
|
47
|
-
properties: {
|
|
48
|
-
type: {
|
|
49
|
-
const: key,
|
|
50
|
-
},
|
|
51
|
-
...schema.properties,
|
|
52
|
-
},
|
|
53
|
-
additionalProperties: false,
|
|
54
|
-
...schema,
|
|
55
|
-
} as JSONSchema7;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return resolvedEventSchemaMap as ConvertToJSONSchemas<T>;
|
|
20
|
+
export function wrapInXml(tagName: string, content: string): string {
|
|
21
|
+
return `<${tagName}>${content}</${tagName}>`;
|
|
59
22
|
}
|
|
60
|
-
|
|
61
|
-
export function createZodEventSchemas<T extends ZodEventTypes>(
|
|
62
|
-
eventSchemaMap: T
|
|
63
|
-
): {
|
|
64
|
-
[K in keyof T]: unknown;
|
|
65
|
-
} {
|
|
66
|
-
const resolvedEventSchemaMap = {};
|
|
67
|
-
|
|
68
|
-
for (const [eventType, zodType] of Object.entries(eventSchemaMap)) {
|
|
69
|
-
// @ts-ignore
|
|
70
|
-
resolvedEventSchemaMap[eventType] = zodToJsonSchema(
|
|
71
|
-
zodType.extend({
|
|
72
|
-
type: z.literal(eventType),
|
|
73
|
-
})
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return resolvedEventSchemaMap as ConvertToJSONSchemas<T>;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export type InferEventsFromSchemas<T extends ConvertToJSONSchemas<any>> =
|
|
81
|
-
FromSchema<Values<T>>;
|
package/tsconfig.json
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
|
53
53
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
|
54
54
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
|
55
|
-
|
|
55
|
+
"sourceMap": true /* Create source map files for emitted JavaScript files. */,
|
|
56
56
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
|
57
57
|
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
|
58
58
|
// "outDir": "./", /* Specify an output folder for all emitted files. */
|
|
File without changes
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import OpenAI from 'openai';
|
|
2
|
-
import { createAgent, createOpenAIAdapter, defineEvents } from '../src';
|
|
3
|
-
import { assign, setup } from 'xstate';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
const openai = new OpenAI({
|
|
6
|
-
apiKey: process.env.OPENAI_API_KEY,
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
const adapter = createOpenAIAdapter(openai, {
|
|
10
|
-
model: 'gpt-3.5-turbo-1106',
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const guessLogic = adapter.fromEvent(
|
|
14
|
-
({
|
|
15
|
-
previousGuesses,
|
|
16
|
-
lastResult,
|
|
17
|
-
}: {
|
|
18
|
-
previousGuesses: number[];
|
|
19
|
-
lastResult: string;
|
|
20
|
-
}) => `
|
|
21
|
-
Guess the number between 1 and 10. The previous guesses were ${
|
|
22
|
-
previousGuesses.length ? previousGuesses.join(', ') : 'not made yet'
|
|
23
|
-
} and the last result was ${lastResult}.
|
|
24
|
-
`
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
const events = defineEvents({
|
|
28
|
-
guess: z.object({
|
|
29
|
-
number: z.number().min(1).max(10).describe('The number guessed'),
|
|
30
|
-
}),
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const machine = setup({
|
|
34
|
-
types: {
|
|
35
|
-
context: {} as {
|
|
36
|
-
previousGuesses: number[];
|
|
37
|
-
answer: number;
|
|
38
|
-
},
|
|
39
|
-
input: {} as { answer: number },
|
|
40
|
-
events: events.types,
|
|
41
|
-
},
|
|
42
|
-
schemas: {
|
|
43
|
-
events: events.schemas,
|
|
44
|
-
},
|
|
45
|
-
actors: {
|
|
46
|
-
guessLogic,
|
|
47
|
-
},
|
|
48
|
-
}).createMachine({
|
|
49
|
-
context: ({ input }) => ({
|
|
50
|
-
answer: input.answer,
|
|
51
|
-
previousGuesses: [],
|
|
52
|
-
}),
|
|
53
|
-
initial: 'guessing',
|
|
54
|
-
states: {
|
|
55
|
-
guessing: {
|
|
56
|
-
always: {
|
|
57
|
-
guard: ({ context }) =>
|
|
58
|
-
context.answer === context.previousGuesses.at(-1),
|
|
59
|
-
target: 'winner',
|
|
60
|
-
},
|
|
61
|
-
invoke: {
|
|
62
|
-
src: 'guessLogic',
|
|
63
|
-
input: ({ context }) => ({
|
|
64
|
-
previousGuesses: context.previousGuesses,
|
|
65
|
-
lastResult:
|
|
66
|
-
context.previousGuesses.length === 0
|
|
67
|
-
? 'not given yet'
|
|
68
|
-
: context.previousGuesses.at(-1)! - context.answer > 0
|
|
69
|
-
? 'too high'
|
|
70
|
-
: 'too low',
|
|
71
|
-
}),
|
|
72
|
-
},
|
|
73
|
-
on: {
|
|
74
|
-
guess: {
|
|
75
|
-
actions: assign({
|
|
76
|
-
previousGuesses: ({ context, event }) => [
|
|
77
|
-
...context.previousGuesses,
|
|
78
|
-
event.number,
|
|
79
|
-
],
|
|
80
|
-
}),
|
|
81
|
-
target: 'guessing',
|
|
82
|
-
reenter: true,
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
winner: {
|
|
87
|
-
type: 'final',
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
const agent = createAgent(machine, {
|
|
93
|
-
input: { answer: 4 },
|
|
94
|
-
inspect: (ev) => {
|
|
95
|
-
if (ev.type === '@xstate.event') {
|
|
96
|
-
console.log(ev.event);
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
agent.start();
|