@statelyai/agent 1.1.6 → 2.0.0-alpha.11

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 (92) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapter.cjs +15 -0
  3. package/dist/adapter.d.cts +4 -0
  4. package/dist/adapter.d.mts +4 -0
  5. package/dist/adapter.mjs +2 -0
  6. package/dist/ai-sdk.cjs +306 -0
  7. package/dist/ai-sdk.d.cts +96 -0
  8. package/dist/ai-sdk.d.mts +96 -0
  9. package/dist/ai-sdk.mjs +304 -0
  10. package/dist/decision-C3k4ve51.mjs +227 -0
  11. package/dist/decision-D8wJrM8W.cjs +286 -0
  12. package/dist/events-CRQj3VtP.cjs +1010 -0
  13. package/dist/events-JiVPYrct.mjs +759 -0
  14. package/dist/index.cjs +2528 -0
  15. package/dist/index.d.cts +1232 -0
  16. package/dist/index.d.mts +1217 -413
  17. package/dist/index.mjs +2489 -584
  18. package/dist/openai-compat.cjs +309 -0
  19. package/dist/openai-compat.d.cts +59 -0
  20. package/dist/openai-compat.d.mts +59 -0
  21. package/dist/openai-compat.mjs +308 -0
  22. package/dist/steps-BALp1eZo.d.mts +198 -0
  23. package/dist/steps-CVe54GPP.cjs +420 -0
  24. package/dist/steps-CkyyyuHd.mjs +379 -0
  25. package/dist/steps-MjnQI4aB.d.cts +198 -0
  26. package/dist/steps.cjs +12 -0
  27. package/dist/steps.d.cts +3 -0
  28. package/dist/steps.d.mts +3 -0
  29. package/dist/steps.mjs +3 -0
  30. package/dist/text-logic-CaKqgX4Y.d.mts +710 -0
  31. package/dist/text-logic-Ckhr2kKC.d.cts +710 -0
  32. package/dist/types-C9QiMjre.d.cts +219 -0
  33. package/dist/types-qm00QF91.d.mts +219 -0
  34. package/dist/utils-BYqT_Dyv.d.cts +108 -0
  35. package/dist/utils-Do5wIJrh.d.mts +108 -0
  36. package/dist/zod.cjs +31 -0
  37. package/dist/zod.d.cts +30 -0
  38. package/dist/zod.d.mts +30 -0
  39. package/dist/zod.mjs +30 -0
  40. package/package.json +132 -28
  41. package/readme.md +153 -6
  42. package/schemas/agent-workflow.json +526 -0
  43. package/.changeset/README.md +0 -8
  44. package/.changeset/config.json +0 -11
  45. package/.env.template +0 -3
  46. package/.github/actions/ci-setup/action.yml +0 -24
  47. package/.github/workflows/release.yml +0 -46
  48. package/.vscode/launch.json +0 -28
  49. package/CHANGELOG.md +0 -222
  50. package/dist/index.d.ts +0 -428
  51. package/dist/index.js +0 -621
  52. package/examples/chatbot.ts +0 -71
  53. package/examples/cot.ts +0 -89
  54. package/examples/email.ts +0 -118
  55. package/examples/example.ts +0 -81
  56. package/examples/goal.ts +0 -94
  57. package/examples/helpers/helpers.ts +0 -17
  58. package/examples/helpers/loader.ts +0 -32
  59. package/examples/helpers/runner.ts +0 -27
  60. package/examples/joke.ts +0 -225
  61. package/examples/multi.ts +0 -103
  62. package/examples/newspaper.ts +0 -324
  63. package/examples/number.ts +0 -102
  64. package/examples/raffle.ts +0 -105
  65. package/examples/sandbox.ts +0 -28
  66. package/examples/simple.ts +0 -39
  67. package/examples/support.ts +0 -147
  68. package/examples/ticTacToe.ts +0 -224
  69. package/examples/todo.ts +0 -137
  70. package/examples/tutor.ts +0 -100
  71. package/examples/verify.ts +0 -120
  72. package/examples/weather.ts +0 -178
  73. package/examples/wiki.ts +0 -30
  74. package/examples/word.ts +0 -171
  75. package/src/adapters/vercel.ts +0 -7
  76. package/src/agent-experimental.ts +0 -221
  77. package/src/agent.test.ts +0 -506
  78. package/src/agent.ts +0 -300
  79. package/src/decision.test.ts +0 -179
  80. package/src/decision.ts +0 -84
  81. package/src/index.ts +0 -4
  82. package/src/memory.ts +0 -25
  83. package/src/planners/shortestPathPlanner.ts +0 -22
  84. package/src/planners/simplePlanner.ts +0 -139
  85. package/src/schemas.ts +0 -11
  86. package/src/strategies/chain-of-note.ts +0 -155
  87. package/src/templates/defaultText.ts +0 -18
  88. package/src/text.ts +0 -241
  89. package/src/types.ts +0 -499
  90. package/src/utils.ts +0 -72
  91. package/tsconfig.json +0 -109
  92. 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
- }