@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.
@@ -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
- setup,
9
+ isMachineSnapshot,
11
10
  toObserver,
12
11
  } from 'xstate';
13
- import { getAllTransitions } from './utils';
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: 'gpt-3.5-turbo-1106',
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 fromChatCompletionStream<TInput>(
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: 'gpt-3.5-turbo-1106',
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
- machineTypes: { schemas: { context: ContextSchema; events: EventSchemas } },
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: 'gpt-4-1106-preview',
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
- return toolCalls.map((tc) => {
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 CreateAgentOutput<
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
- schemas: T;
204
- types: {
205
- context: FromSchema<ConvertContextToJSONSchema<T['context']>>;
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
- ) => PromiseActorLogic<
211
- FromSchema<Values<ConvertToJSONSchemas<T['events']>>>[] | undefined,
212
- TInput
213
- >;
214
- fromChatCompletion: <TInput>(
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
- fromChatCompletionStream: <TInput>(
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 createAgent<
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): CreateAgentOutput<T> {
232
- const obj: CreateAgentOutput<T> = {
249
+ >(openai: OpenAI, settings: T): OpenAIAdapterOutput<T> {
250
+ const agentSettings: OpenAIAdapterOutput<T> = {
233
251
  model: settings.model,
234
- schemas: {
235
- context: {
236
- type: 'object',
237
- properties: settings.context,
238
- additionalProperties: false,
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 obj as any;
259
+ return agentSettings;
250
260
  }
package/src/agent.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { ActorOptions, AnyStateMachine, createActor } from 'xstate';
2
+
3
+ export function createAgent<T extends AnyStateMachine>(
4
+ ...args: Parameters<typeof createActor<T>>
5
+ ) {
6
+ const [machine, options] = args;
7
+ return createActor(machine, options);
8
+ }
package/src/index.ts CHANGED
@@ -1,6 +1,3 @@
1
- export {
2
- fromChatCompletion,
3
- fromChatCompletionStream,
4
- fromEventChoice,
5
- createAgent,
6
- } from './openai';
1
+ export { createSchemas } from './schemas';
2
+ export { createAgent } from './agent';
3
+ export { createOpenAIAdapter } from './adapters/openai';
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
@@ -1,3 +0,0 @@
1
- declare function helloWorld(): string;
2
-
3
- export { helloWorld };
package/dist/index.mjs DELETED
@@ -1,7 +0,0 @@
1
- // src/index.ts
2
- function helloWorld() {
3
- return "Hello World!";
4
- }
5
- export {
6
- helloWorld
7
- };