@statelyai/agent 1.1.6 → 2.0.0-alpha.6

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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai-sdk.cjs +249 -0
  3. package/dist/ai-sdk.d.cts +168 -0
  4. package/dist/ai-sdk.d.mts +168 -0
  5. package/dist/ai-sdk.mjs +241 -0
  6. package/dist/cli.cjs +63 -0
  7. package/dist/cli.d.cts +1 -0
  8. package/dist/cli.d.mts +1 -0
  9. package/dist/cli.mjs +64 -0
  10. package/dist/decision-CX3YdwrO.cjs +1239 -0
  11. package/dist/decision-D1654JdD.mjs +940 -0
  12. package/dist/index.cjs +54 -0
  13. package/dist/index.d.cts +1217 -0
  14. package/dist/index.d.mts +1194 -405
  15. package/dist/index.mjs +3 -588
  16. package/dist/openai-compat.cjs +319 -0
  17. package/dist/openai-compat.d.cts +98 -0
  18. package/dist/openai-compat.d.mts +98 -0
  19. package/dist/openai-compat.mjs +312 -0
  20. package/dist/src-CEa947Dm.mjs +2449 -0
  21. package/dist/src-wBfi-kTA.cjs +2568 -0
  22. package/dist/text-logic-1ZQkO3zr.d.cts +682 -0
  23. package/dist/text-logic-2EMJIS-n.d.mts +682 -0
  24. package/dist/types-BHjeDdch.d.cts +208 -0
  25. package/dist/types-Cq1YlAQ6.d.mts +208 -0
  26. package/dist/utils-CWUCa3pF.d.mts +108 -0
  27. package/dist/utils-lK1wnL2i.d.cts +108 -0
  28. package/dist/zod.cjs +31 -0
  29. package/dist/zod.d.cts +30 -0
  30. package/dist/zod.d.mts +30 -0
  31. package/dist/zod.mjs +30 -0
  32. package/package.json +109 -28
  33. package/readme.md +144 -6
  34. package/schemas/agent-workflow.json +527 -0
  35. package/.changeset/README.md +0 -8
  36. package/.changeset/config.json +0 -11
  37. package/.env.template +0 -3
  38. package/.github/actions/ci-setup/action.yml +0 -24
  39. package/.github/workflows/release.yml +0 -46
  40. package/.vscode/launch.json +0 -28
  41. package/CHANGELOG.md +0 -222
  42. package/dist/index.d.ts +0 -428
  43. package/dist/index.js +0 -621
  44. package/examples/chatbot.ts +0 -71
  45. package/examples/cot.ts +0 -89
  46. package/examples/email.ts +0 -118
  47. package/examples/example.ts +0 -81
  48. package/examples/goal.ts +0 -94
  49. package/examples/helpers/helpers.ts +0 -17
  50. package/examples/helpers/loader.ts +0 -32
  51. package/examples/helpers/runner.ts +0 -27
  52. package/examples/joke.ts +0 -225
  53. package/examples/multi.ts +0 -103
  54. package/examples/newspaper.ts +0 -324
  55. package/examples/number.ts +0 -102
  56. package/examples/raffle.ts +0 -105
  57. package/examples/sandbox.ts +0 -28
  58. package/examples/simple.ts +0 -39
  59. package/examples/support.ts +0 -147
  60. package/examples/ticTacToe.ts +0 -224
  61. package/examples/todo.ts +0 -137
  62. package/examples/tutor.ts +0 -100
  63. package/examples/verify.ts +0 -120
  64. package/examples/weather.ts +0 -178
  65. package/examples/wiki.ts +0 -30
  66. package/examples/word.ts +0 -171
  67. package/src/adapters/vercel.ts +0 -7
  68. package/src/agent-experimental.ts +0 -221
  69. package/src/agent.test.ts +0 -506
  70. package/src/agent.ts +0 -300
  71. package/src/decision.test.ts +0 -179
  72. package/src/decision.ts +0 -84
  73. package/src/index.ts +0 -4
  74. package/src/memory.ts +0 -25
  75. package/src/planners/shortestPathPlanner.ts +0 -22
  76. package/src/planners/simplePlanner.ts +0 -139
  77. package/src/schemas.ts +0 -11
  78. package/src/strategies/chain-of-note.ts +0 -155
  79. package/src/templates/defaultText.ts +0 -18
  80. package/src/text.ts +0 -241
  81. package/src/types.ts +0 -499
  82. package/src/utils.ts +0 -72
  83. package/tsconfig.json +0 -109
  84. package/vitest.config.ts +0 -9
@@ -1,139 +0,0 @@
1
- import { type CoreTool, tool } from 'ai';
2
- import {
3
- AgentPlan,
4
- AgentPlanInput,
5
- ObservedState,
6
- PromptTemplate,
7
- TransitionData,
8
- AnyAgent,
9
- } from '../types';
10
- import { getAllTransitions } from '../utils';
11
- import { AnyStateMachine } from 'xstate';
12
- import { defaultTextTemplate } from '../templates/defaultText';
13
- import { getMessages } from '../text';
14
-
15
- function getTransitions(
16
- state: ObservedState,
17
- machine: AnyStateMachine
18
- ): TransitionData[] {
19
- if (!machine) {
20
- return [];
21
- }
22
-
23
- const resolvedState = machine.resolveState(state);
24
- return getAllTransitions(resolvedState);
25
- }
26
-
27
- const simplePlannerPromptTemplate: PromptTemplate<any> = (data) => {
28
- return `
29
- ${defaultTextTemplate(data)}
30
-
31
- 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.
32
- `.trim();
33
- };
34
-
35
- export async function simplePlanner<T extends AnyAgent>(
36
- agent: T,
37
- input: AgentPlanInput<any>
38
- ): Promise<AgentPlan<any> | undefined> {
39
- // Get all of the possible next transitions
40
- const transitions: TransitionData[] = input.machine
41
- ? getTransitions(input.state, input.machine)
42
- : Object.entries(input.events).map(([eventType, { description }]) => ({
43
- eventType,
44
- description,
45
- }));
46
-
47
- // Only keep the transitions that match the event types that are in the event mapping
48
- // TODO: allow for custom filters
49
- const filter = (eventType: string) =>
50
- Object.keys(input.events).includes(eventType);
51
-
52
- // Mapping of each event type (e.g. "mouse.click")
53
- // to a valid function name (e.g. "mouse_click")
54
- const functionNameMapping: Record<string, string> = {};
55
-
56
- const toolTransitions = transitions
57
- .filter((t) => {
58
- return filter(t.eventType);
59
- })
60
- .map((t) => {
61
- const name = t.eventType.replace(/\./g, '_');
62
- functionNameMapping[name] = t.eventType;
63
-
64
- return {
65
- type: 'function',
66
- eventType: t.eventType,
67
- description: t.description,
68
- name,
69
- } as const;
70
- });
71
-
72
- // Convert the transition data to a tool map that the
73
- // Vercel AI SDK can use
74
- const toolMap: Record<string, CoreTool<any, any>> = {};
75
- for (const toolTransitionData of toolTransitions) {
76
- const toolZodType = input.events?.[toolTransitionData.eventType];
77
-
78
- if (!toolZodType) {
79
- continue;
80
- }
81
-
82
- toolMap[toolTransitionData.name] = tool({
83
- description: toolZodType?.description ?? toolTransitionData.description,
84
- parameters: toolZodType,
85
- execute: async (params: Record<string, any>) => {
86
- const event = {
87
- type: toolTransitionData.eventType,
88
- ...params,
89
- };
90
-
91
- return event;
92
- },
93
- });
94
- }
95
-
96
- if (!Object.keys(toolMap).length) {
97
- // No valid transitions for the specified tools
98
- return undefined;
99
- }
100
-
101
- // Create a prompt with the given context and goal.
102
- // The template is used to ensure that a single tool call at most is made.
103
- const prompt = simplePlannerPromptTemplate({
104
- context: input.state.context,
105
- goal: input.goal,
106
- });
107
-
108
- const messages = await getMessages(agent, prompt, input);
109
-
110
- const result = await agent.generateText({
111
- toolChoice: 'required',
112
- ...input,
113
- prompt,
114
- messages,
115
- tools: toolMap,
116
- });
117
-
118
- const singleResult = result.toolResults[0];
119
-
120
- if (!singleResult) {
121
- // TODO: retries?
122
- console.warn('No tool call results returned');
123
- return undefined;
124
- }
125
-
126
- return {
127
- goal: input.goal,
128
- state: input.state,
129
- execute: async (state) => {
130
- if (JSON.stringify(state) === JSON.stringify(input.state)) {
131
- return singleResult.result;
132
- }
133
- return undefined;
134
- },
135
- nextEvent: singleResult.result,
136
- sessionId: agent.sessionId,
137
- timestamp: Date.now(),
138
- };
139
- }
package/src/schemas.ts DELETED
@@ -1,11 +0,0 @@
1
- import { ZodType, type SomeZodObject } from 'zod';
2
-
3
- export type ZodEventMapping = {
4
- // map event types to Zod types
5
- [eventType: string]: SomeZodObject;
6
- };
7
-
8
- export type ZodContextMapping = {
9
- // map context keys to Zod types
10
- [contextKey: string]: ZodType;
11
- };
@@ -1,155 +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: (x) => ({
71
- ...x.input,
72
- searchResults: null,
73
- summaries: null,
74
- }),
75
- states: {
76
- searching: {
77
- invoke: {
78
- src: 'searchWiki',
79
- input: (x) => ({
80
- query: x.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: (x) => ({
94
- searchResult: x.context.searchResults!,
95
- }),
96
- onDone: {
97
- actions: assign({
98
- summaries: ({ event }) => event.output,
99
- }),
100
- target: 'generating',
101
- },
102
- },
103
- },
104
- generating: {},
105
- },
106
- });
107
-
108
- // export function chainOfNote() {
109
- // return {
110
- // generateText: async (x) => {
111
- // const passages = await wiki.search(x.prompt!, {
112
- // limit: 5,
113
- // });
114
-
115
- // const extracts = await Promise.all(
116
- // passages.results.map(async (p) => {
117
- // const summary = await wiki.summary(p.title);
118
- // return summary.extract;
119
- // })
120
- // );
121
- // x.agent?.addMessage({
122
- // content: x.prompt!,
123
- // id: Date.now() + '',
124
- // role: 'user',
125
- // timestamp: Date.now(),
126
- // });
127
- // const result = await generateText({
128
- // model: x.model,
129
- // system: `Task Description:
130
-
131
- // 1. Read the given question and five Wikipedia passages to gather relevant information.
132
-
133
- // 2. Write reading notes summarizing the key points from these passages.
134
-
135
- // 3. Discuss the relevance of the given question and Wikipedia passages.
136
-
137
- // 4. If some passages are relevant to the given question, provide a brief answer based on the passages.
138
-
139
- // 5. If no passage is relevant, direcly provide answer without considering the passages.
140
-
141
- // Passages: \n${extracts.join('\n')}`,
142
- // prompt: `${x.prompt!}`,
143
- // });
144
-
145
- // x.agent?.addMessage({
146
- // content: result.text,
147
- // id: Date.now() + '',
148
- // role: 'user',
149
- // timestamp: Date.now(),
150
- // });
151
-
152
- // return result;
153
- // },
154
- // } satisfies AgentStrategy;
155
- // }
@@ -1,18 +0,0 @@
1
- import { PromptTemplate } from '../types';
2
- import { wrapInXml } from '../utils';
3
-
4
- export const defaultTextTemplate: PromptTemplate<any> = (data) => {
5
- const preamble = [
6
- data.context
7
- ? wrapInXml('context', JSON.stringify(data.context))
8
- : undefined,
9
- ]
10
- .filter(Boolean)
11
- .join('\n');
12
-
13
- return `
14
- ${preamble}
15
-
16
- ${data.goal}
17
- `.trim();
18
- };
package/src/text.ts DELETED
@@ -1,241 +0,0 @@
1
- import type { CoreMessage, CoreTool, GenerateTextResult } from 'ai';
2
- import {
3
- AgentGenerateTextOptions,
4
- AgentGenerateTextResult,
5
- AgentStreamTextOptions,
6
- AgentStreamTextResult,
7
- AnyAgent,
8
- } from './types';
9
- import { defaultTextTemplate } from './templates/defaultText';
10
- import {
11
- ObservableActorLogic,
12
- Observer,
13
- PromiseActorLogic,
14
- fromObservable,
15
- fromPromise,
16
- toObserver,
17
- } from 'xstate';
18
- import { randomId } from './utils';
19
-
20
- /**
21
- * Gets an array of messages from the given prompt, based on the agent and options.
22
- *
23
- * @param agent
24
- * @param prompt
25
- * @param options
26
- * @returns
27
- */
28
- export async function getMessages(
29
- agent: AnyAgent,
30
- prompt: string,
31
- options: Omit<AgentGenerateTextOptions, 'prompt'>
32
- ): Promise<CoreMessage[]> {
33
- let messages: CoreMessage[] = [];
34
- if (typeof options.messages === 'function') {
35
- messages = await options.messages(agent);
36
- } else if (options.messages) {
37
- messages = options.messages;
38
- }
39
-
40
- messages = messages.concat({
41
- role: 'user',
42
- content: prompt,
43
- });
44
-
45
- return messages;
46
- }
47
-
48
- export async function agentGenerateText<T extends AnyAgent>(
49
- agent: T,
50
- options: AgentGenerateTextOptions
51
- ): Promise<AgentGenerateTextResult> {
52
- const resolvedOptions = {
53
- ...agent.defaultOptions,
54
- ...options,
55
- correlationId: options.correlationId ?? randomId(),
56
- };
57
- // Generate a correlation ID if one is not provided
58
- const template = resolvedOptions.template ?? defaultTextTemplate;
59
- // TODO: check if messages was provided instead
60
- const id = randomId();
61
- const goal =
62
- typeof resolvedOptions.prompt === 'string'
63
- ? resolvedOptions.prompt
64
- : await resolvedOptions.prompt(agent);
65
-
66
- const promptWithContext = template({
67
- goal,
68
- context: resolvedOptions.context,
69
- });
70
-
71
- const messages = await getMessages(agent, promptWithContext, resolvedOptions);
72
-
73
- agent.addMessage({
74
- id,
75
- role: 'user',
76
- content: promptWithContext,
77
- timestamp: Date.now(),
78
- correlationId: resolvedOptions.correlationId,
79
- parentCorrelationId: resolvedOptions.parentCorrelationId,
80
- });
81
-
82
- const result = await agent.adapter.generateText({
83
- ...resolvedOptions,
84
- prompt: undefined,
85
- messages,
86
- });
87
-
88
- agent.addMessage({
89
- content: result.text,
90
- id,
91
- role: 'assistant',
92
- timestamp: Date.now(),
93
- responseId: id,
94
- result,
95
- correlationId: resolvedOptions.correlationId,
96
- parentCorrelationId: resolvedOptions.parentCorrelationId,
97
- });
98
-
99
- return {
100
- ...result,
101
- parentCorrelationId: resolvedOptions.parentCorrelationId,
102
- correlationId: resolvedOptions.correlationId,
103
- };
104
- }
105
-
106
- export async function agentStreamText(
107
- agent: AnyAgent,
108
- options: AgentStreamTextOptions
109
- ): Promise<AgentStreamTextResult> {
110
- const resolvedOptions = {
111
- ...agent.defaultOptions,
112
- ...options,
113
- correlationId: options.correlationId ?? randomId(),
114
- };
115
- const template = resolvedOptions.template ?? defaultTextTemplate;
116
-
117
- const id = randomId();
118
- const goal =
119
- typeof resolvedOptions.prompt === 'string'
120
- ? resolvedOptions.prompt
121
- : await resolvedOptions.prompt(agent);
122
-
123
- const promptWithContext = template({
124
- goal,
125
- context: resolvedOptions.context,
126
- });
127
-
128
- const messages = await getMessages(agent, promptWithContext, resolvedOptions);
129
-
130
- agent.addMessage({
131
- role: 'user',
132
- content: promptWithContext,
133
- id,
134
- timestamp: Date.now(),
135
- correlationId: resolvedOptions.correlationId,
136
- parentCorrelationId: resolvedOptions.parentCorrelationId,
137
- });
138
-
139
- const result = await agent.adapter.streamText({
140
- ...resolvedOptions,
141
- prompt: undefined,
142
- messages,
143
- onFinish: async (res) => {
144
- agent.addMessage({
145
- role: 'assistant',
146
- result: {
147
- text: res.text,
148
- finishReason: res.finishReason,
149
- logprobs: undefined,
150
- responseMessages: [],
151
- toolCalls: [],
152
- toolResults: [],
153
- usage: res.usage,
154
- warnings: res.warnings,
155
- rawResponse: res.rawResponse,
156
- roundtrips: [], // TODO: how do we get this information?,
157
- steps: res.steps,
158
- response: res.response,
159
- experimental_providerMetadata: res.experimental_providerMetadata,
160
- },
161
- content: res.text,
162
- id: randomId(),
163
- timestamp: Date.now(),
164
- responseId: id,
165
- correlationId: resolvedOptions.correlationId,
166
- parentCorrelationId: resolvedOptions.parentCorrelationId,
167
- });
168
- },
169
- });
170
-
171
- return {
172
- ...result,
173
- textStream: result.textStream,
174
- fullStream: result.fullStream,
175
- parentCorrelationId: resolvedOptions.parentCorrelationId,
176
- correlationId: resolvedOptions.correlationId,
177
- } as unknown as AgentStreamTextResult; // TODO: fix
178
- }
179
-
180
- export function fromTextStream<T extends AnyAgent>(
181
- agent: T,
182
- defaultOptions?: AgentStreamTextOptions
183
- ): ObservableActorLogic<
184
- { textDelta: string },
185
- Omit<AgentStreamTextOptions, 'context'> & {
186
- context?: AgentStreamTextOptions['context'];
187
- }
188
- > {
189
- return fromObservable(({ input }) => {
190
- const observers = new Set<Observer<{ textDelta: string }>>();
191
-
192
- // TODO: check if messages was provided instead
193
-
194
- (async () => {
195
- const result = await agentStreamText(agent, {
196
- ...defaultOptions,
197
- ...input,
198
- context: input.context,
199
- });
200
-
201
- for await (const part of result.fullStream) {
202
- if (part.type === 'text-delta') {
203
- observers.forEach((observer) => {
204
- observer.next?.(part);
205
- });
206
- }
207
- }
208
- })();
209
-
210
- return {
211
- subscribe: (...args: any[]) => {
212
- const observer = toObserver(...args);
213
- observers.add(observer);
214
-
215
- return {
216
- unsubscribe: () => {
217
- observers.delete(observer);
218
- },
219
- };
220
- },
221
- };
222
- });
223
- }
224
-
225
- export function fromText<T extends AnyAgent>(
226
- agent: T,
227
- defaultOptions?: AgentGenerateTextOptions
228
- ): PromiseActorLogic<
229
- GenerateTextResult<Record<string, CoreTool<any, any>>>,
230
- Omit<AgentGenerateTextOptions, 'context'> & {
231
- context?: AgentGenerateTextOptions['context'];
232
- }
233
- > {
234
- return fromPromise(async ({ input }) => {
235
- return await agentGenerateText(agent, {
236
- ...input,
237
- ...defaultOptions,
238
- context: input.context,
239
- });
240
- });
241
- }