@statelyai/agent 0.0.2 → 0.0.4
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/config.json +1 -1
- package/.env.template +6 -0
- package/.github/actions/ci-setup/action.yml +24 -0
- package/.github/workflows/release.yml +35 -0
- package/CHANGELOG.md +14 -0
- package/dist/index.d.ts +38 -44
- package/dist/index.js +64 -39
- package/examples/helpers/helpers.ts +17 -0
- package/examples/helpers/loader.ts +32 -0
- package/examples/helpers/runner.ts +27 -0
- package/examples/joke.ts +121 -56
- package/examples/multiAgentCollaboration.ts +0 -0
- package/examples/ticTacToe.ts +41 -66
- package/examples/weather.ts +160 -0
- package/package.json +14 -6
- package/readme.md +41 -0
- package/src/{openai.ts → adapters/openai.ts} +68 -58
- package/src/agent.ts +8 -0
- package/src/index.ts +3 -6
- package/src/schemas.ts +38 -0
- package/dist/index.d.mts +0 -3
- package/dist/index.mjs +0 -7
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
import OpenAI from 'openai';
|
|
1
|
+
import type OpenAI from 'openai';
|
|
2
2
|
import {
|
|
3
3
|
AnyEventObject,
|
|
4
4
|
ObservableActorLogic,
|
|
5
5
|
Observer,
|
|
6
6
|
PromiseActorLogic,
|
|
7
|
-
Values,
|
|
8
7
|
fromObservable,
|
|
9
8
|
fromPromise,
|
|
10
|
-
|
|
9
|
+
isMachineSnapshot,
|
|
11
10
|
toObserver,
|
|
12
11
|
} from 'xstate';
|
|
13
|
-
import { getAllTransitions } from '
|
|
14
|
-
import {
|
|
15
|
-
ContextSchema,
|
|
16
|
-
EventSchemas,
|
|
17
|
-
ConvertContextToJSONSchema,
|
|
18
|
-
ConvertToJSONSchemas,
|
|
19
|
-
createEventSchemas,
|
|
20
|
-
} from './utils';
|
|
21
|
-
import { FromSchema } from 'json-schema-to-ts';
|
|
12
|
+
import { getAllTransitions } from '../utils';
|
|
22
13
|
import { ChatCompletionCreateParamsNonStreaming } from 'openai/resources';
|
|
23
14
|
import {
|
|
24
15
|
ChatCompletionCreateParamsBase,
|
|
@@ -34,6 +25,7 @@ import {
|
|
|
34
25
|
*/
|
|
35
26
|
export function fromChatCompletion<TInput>(
|
|
36
27
|
openai: OpenAI,
|
|
28
|
+
agentSettings: OpenAIAdapterOutput<any>,
|
|
37
29
|
inputFn: (
|
|
38
30
|
input: TInput
|
|
39
31
|
) => string | OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming
|
|
@@ -44,7 +36,7 @@ export function fromChatCompletion<TInput>(
|
|
|
44
36
|
const params: ChatCompletionCreateParamsNonStreaming =
|
|
45
37
|
typeof openAiInput === 'string'
|
|
46
38
|
? {
|
|
47
|
-
model:
|
|
39
|
+
model: agentSettings.model,
|
|
48
40
|
messages: [
|
|
49
41
|
{
|
|
50
42
|
role: 'user',
|
|
@@ -66,8 +58,9 @@ export function fromChatCompletion<TInput>(
|
|
|
66
58
|
* @param openai The OpenAI instance to use.
|
|
67
59
|
* @param inputFn A function that maps arbitrary input to OpenAI chat completion input.
|
|
68
60
|
*/
|
|
69
|
-
export function
|
|
61
|
+
export function fromChatStream<TInput>(
|
|
70
62
|
openai: OpenAI,
|
|
63
|
+
agentSettings: OpenAIAdapterOutput<any>,
|
|
71
64
|
inputFn: (
|
|
72
65
|
input: TInput
|
|
73
66
|
) => string | OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming
|
|
@@ -81,7 +74,7 @@ export function fromChatCompletionStream<TInput>(
|
|
|
81
74
|
const resolvedParams: ChatCompletionCreateParamsBase =
|
|
82
75
|
typeof openAiInput === 'string'
|
|
83
76
|
? {
|
|
84
|
-
model:
|
|
77
|
+
model: agentSettings.model,
|
|
85
78
|
messages: [
|
|
86
79
|
{
|
|
87
80
|
role: 'user',
|
|
@@ -126,13 +119,29 @@ export function fromChatCompletionStream<TInput>(
|
|
|
126
119
|
*/
|
|
127
120
|
export function fromEventChoice<TInput>(
|
|
128
121
|
openai: OpenAI,
|
|
129
|
-
|
|
122
|
+
agentSettings: OpenAIAdapterOutput<any>,
|
|
130
123
|
inputFn: (
|
|
131
124
|
input: TInput
|
|
132
|
-
) => string | OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming
|
|
125
|
+
) => string | OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming,
|
|
126
|
+
options?: {
|
|
127
|
+
/**
|
|
128
|
+
* Immediately execute sending the event to the parent actor.
|
|
129
|
+
* @default false
|
|
130
|
+
*/
|
|
131
|
+
execute?: boolean;
|
|
132
|
+
}
|
|
133
133
|
) {
|
|
134
134
|
return fromPromise<AnyEventObject[] | undefined, TInput>(
|
|
135
|
-
async ({ input, self }) => {
|
|
135
|
+
async ({ input, self, system }) => {
|
|
136
|
+
const parentSnapshot = self._parent?.getSnapshot();
|
|
137
|
+
|
|
138
|
+
if (!parentSnapshot || !isMachineSnapshot(parentSnapshot)) {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const schemas = parentSnapshot.machine.schemas as any;
|
|
143
|
+
const eventSchemaMap = schemas.events ?? {};
|
|
144
|
+
|
|
136
145
|
const transitions = getAllTransitions(self._parent!.getSnapshot());
|
|
137
146
|
const functionNameMapping: Record<string, string> = {};
|
|
138
147
|
const tools = transitions
|
|
@@ -147,12 +156,10 @@ export function fromEventChoice<TInput>(
|
|
|
147
156
|
function: {
|
|
148
157
|
name,
|
|
149
158
|
description:
|
|
150
|
-
t.description ??
|
|
151
|
-
machineTypes.schemas.events[t.eventType]?.description,
|
|
159
|
+
t.description ?? eventSchemaMap[t.eventType]?.description,
|
|
152
160
|
parameters: {
|
|
153
161
|
type: 'object',
|
|
154
|
-
properties:
|
|
155
|
-
machineTypes.schemas.events[t.eventType]?.properties ?? {},
|
|
162
|
+
properties: eventSchemaMap[t.eventType]?.properties ?? {},
|
|
156
163
|
},
|
|
157
164
|
},
|
|
158
165
|
} as const;
|
|
@@ -162,7 +169,7 @@ export function fromEventChoice<TInput>(
|
|
|
162
169
|
const completionParams: ChatCompletionCreateParamsNonStreaming =
|
|
163
170
|
typeof openAiInput === 'string'
|
|
164
171
|
? {
|
|
165
|
-
model:
|
|
172
|
+
model: agentSettings.model,
|
|
166
173
|
messages: [
|
|
167
174
|
{
|
|
168
175
|
role: 'user',
|
|
@@ -179,12 +186,19 @@ export function fromEventChoice<TInput>(
|
|
|
179
186
|
const toolCalls = completion.choices[0]?.message.tool_calls;
|
|
180
187
|
|
|
181
188
|
if (toolCalls) {
|
|
182
|
-
|
|
189
|
+
const events = toolCalls.map((tc) => {
|
|
183
190
|
return {
|
|
184
191
|
type: functionNameMapping[tc.function.name],
|
|
185
192
|
...JSON.parse(tc.function.arguments),
|
|
186
193
|
};
|
|
187
194
|
});
|
|
195
|
+
|
|
196
|
+
if (options?.execute) {
|
|
197
|
+
events.forEach((event) => {
|
|
198
|
+
// @ts-ignore
|
|
199
|
+
system._relay(self, self._parent, event);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
188
202
|
}
|
|
189
203
|
|
|
190
204
|
return undefined;
|
|
@@ -192,29 +206,35 @@ export function fromEventChoice<TInput>(
|
|
|
192
206
|
);
|
|
193
207
|
}
|
|
194
208
|
|
|
195
|
-
interface
|
|
209
|
+
interface OpenAIAdapterOutput<
|
|
196
210
|
T extends {
|
|
197
211
|
model: ChatCompletionCreateParamsBase['model'];
|
|
198
|
-
context: ContextSchema;
|
|
199
|
-
events: EventSchemas;
|
|
200
212
|
}
|
|
201
213
|
> {
|
|
202
214
|
model: T['model'];
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
events: FromSchema<Values<ConvertToJSONSchemas<T['events']>>>;
|
|
207
|
-
};
|
|
215
|
+
/**
|
|
216
|
+
* Determines which event to send to the parent state machine actor based on the prompt.
|
|
217
|
+
*/
|
|
208
218
|
fromEventChoice: <TInput>(
|
|
209
|
-
inputFn: (input: TInput) => string | ChatCompletionCreateParamsNonStreaming
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
219
|
+
inputFn: (input: TInput) => string | ChatCompletionCreateParamsNonStreaming,
|
|
220
|
+
options?: {
|
|
221
|
+
/**
|
|
222
|
+
* Immediately execute sending the event to the parent actor.
|
|
223
|
+
* @default true
|
|
224
|
+
*/
|
|
225
|
+
execute?: boolean;
|
|
226
|
+
}
|
|
227
|
+
) => PromiseActorLogic<AnyEventObject[] | undefined, TInput>;
|
|
228
|
+
/**
|
|
229
|
+
* Creates promise actor logic that resolves with a chat completion.
|
|
230
|
+
*/
|
|
231
|
+
fromChat: <TInput>(
|
|
215
232
|
inputFn: (input: TInput) => string | ChatCompletionCreateParamsNonStreaming
|
|
216
233
|
) => PromiseActorLogic<OpenAI.Chat.Completions.ChatCompletion, TInput>;
|
|
217
|
-
|
|
234
|
+
/**
|
|
235
|
+
* Creates observable actor logic that emits a chat completion stream.
|
|
236
|
+
*/
|
|
237
|
+
fromChatStream: <TInput>(
|
|
218
238
|
inputFn: (input: TInput) => string | ChatCompletionCreateParamsStreaming
|
|
219
239
|
) => ObservableActorLogic<
|
|
220
240
|
OpenAI.Chat.Completions.ChatCompletionChunk,
|
|
@@ -222,29 +242,19 @@ interface CreateAgentOutput<
|
|
|
222
242
|
>;
|
|
223
243
|
}
|
|
224
244
|
|
|
225
|
-
export function
|
|
245
|
+
export function createOpenAIAdapter<
|
|
226
246
|
T extends {
|
|
227
247
|
model: ChatCompletionCreateParamsBase['model'];
|
|
228
|
-
context: ContextSchema;
|
|
229
|
-
events: EventSchemas;
|
|
230
248
|
}
|
|
231
|
-
>(openai: OpenAI, settings: T):
|
|
232
|
-
const
|
|
249
|
+
>(openai: OpenAI, settings: T): OpenAIAdapterOutput<T> {
|
|
250
|
+
const agentSettings: OpenAIAdapterOutput<T> = {
|
|
233
251
|
model: settings.model,
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
},
|
|
240
|
-
events: createEventSchemas(settings.events),
|
|
241
|
-
} as any,
|
|
242
|
-
types: {} as any,
|
|
243
|
-
fromEventChoice: (input) => fromEventChoice(openai, obj, input) as any,
|
|
244
|
-
fromChatCompletion: (input) => fromChatCompletion(openai, input),
|
|
245
|
-
fromChatCompletionStream: (input) =>
|
|
246
|
-
fromChatCompletionStream(openai, input),
|
|
252
|
+
fromEventChoice: (input) =>
|
|
253
|
+
// @ts-ignore infinitely deep
|
|
254
|
+
fromEventChoice(openai, agentSettings, input, { execute: true }) as any,
|
|
255
|
+
fromChat: (input) => fromChatCompletion(openai, agentSettings, input),
|
|
256
|
+
fromChatStream: (input) => fromChatStream(openai, agentSettings, input),
|
|
247
257
|
};
|
|
248
258
|
|
|
249
|
-
return
|
|
259
|
+
return agentSettings;
|
|
250
260
|
}
|
package/src/agent.ts
ADDED
package/src/index.ts
CHANGED
package/src/schemas.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Values } from 'xstate';
|
|
2
|
+
import {
|
|
3
|
+
ContextSchema,
|
|
4
|
+
EventSchemas,
|
|
5
|
+
ConvertContextToJSONSchema,
|
|
6
|
+
ConvertToJSONSchemas,
|
|
7
|
+
createEventSchemas,
|
|
8
|
+
} from './utils';
|
|
9
|
+
import { FromSchema } from 'json-schema-to-ts';
|
|
10
|
+
|
|
11
|
+
export function createSchemas<
|
|
12
|
+
TContextSchema extends ContextSchema,
|
|
13
|
+
TEventSchemas extends EventSchemas
|
|
14
|
+
>({
|
|
15
|
+
context,
|
|
16
|
+
events,
|
|
17
|
+
}: {
|
|
18
|
+
context: TContextSchema;
|
|
19
|
+
events: TEventSchemas;
|
|
20
|
+
}): {
|
|
21
|
+
context: ConvertContextToJSONSchema<TContextSchema>;
|
|
22
|
+
events: ConvertToJSONSchemas<TEventSchemas>;
|
|
23
|
+
types: {
|
|
24
|
+
context: FromSchema<ConvertContextToJSONSchema<TContextSchema>>;
|
|
25
|
+
events: FromSchema<Values<ConvertToJSONSchemas<TEventSchemas>>>;
|
|
26
|
+
};
|
|
27
|
+
} {
|
|
28
|
+
return {
|
|
29
|
+
context: {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: context,
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
required: Object.keys(context),
|
|
34
|
+
},
|
|
35
|
+
events: createEventSchemas(events),
|
|
36
|
+
types: {} as any,
|
|
37
|
+
};
|
|
38
|
+
}
|
package/dist/index.d.mts
DELETED