@statelyai/agent 0.1.4 → 1.0.0-beta.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/dist/index.d.mts CHANGED
@@ -4,14 +4,28 @@ import { generateText, streamText, LanguageModel, CoreMessage, GenerateTextResul
4
4
 
5
5
  type GenerateTextOptions = Parameters<typeof generateText>[0];
6
6
  type StreamTextOptions = Parameters<typeof streamText>[0];
7
- type AgentPlanInput<TEvent extends EventObject> = {
8
- model: LanguageModel;
7
+ type AgentPlanInput<TEvent extends EventObject> = Omit<GenerateTextOptions, 'prompt' | 'messages' | 'tools'> & {
8
+ /**
9
+ * The currently observed state.
10
+ */
9
11
  state: ObservedState;
12
+ /**
13
+ * The goal for the agent to accomplish.
14
+ * The agent will create a plan based on this goal.
15
+ */
10
16
  goal: string;
17
+ /**
18
+ * The events that the agent can trigger. This is a mapping of
19
+ * event types to Zod event schemas.
20
+ */
11
21
  events: ZodEventMapping;
22
+ /**
23
+ * The state machine that represents the environment the agent
24
+ * is interacting with.
25
+ */
12
26
  machine?: AnyStateMachine;
13
27
  /**
14
- * The previous plan
28
+ * The previous plan.
15
29
  */
16
30
  previousPlan?: AgentPlan<TEvent>;
17
31
  };
package/dist/index.d.ts CHANGED
@@ -4,14 +4,28 @@ import { generateText, streamText, LanguageModel, CoreMessage, GenerateTextResul
4
4
 
5
5
  type GenerateTextOptions = Parameters<typeof generateText>[0];
6
6
  type StreamTextOptions = Parameters<typeof streamText>[0];
7
- type AgentPlanInput<TEvent extends EventObject> = {
8
- model: LanguageModel;
7
+ type AgentPlanInput<TEvent extends EventObject> = Omit<GenerateTextOptions, 'prompt' | 'messages' | 'tools'> & {
8
+ /**
9
+ * The currently observed state.
10
+ */
9
11
  state: ObservedState;
12
+ /**
13
+ * The goal for the agent to accomplish.
14
+ * The agent will create a plan based on this goal.
15
+ */
10
16
  goal: string;
17
+ /**
18
+ * The events that the agent can trigger. This is a mapping of
19
+ * event types to Zod event schemas.
20
+ */
11
21
  events: ZodEventMapping;
22
+ /**
23
+ * The state machine that represents the environment the agent
24
+ * is interacting with.
25
+ */
12
26
  machine?: AnyStateMachine;
13
27
  /**
14
- * The previous plan
28
+ * The previous plan.
15
29
  */
16
30
  previousPlan?: AgentPlan<TEvent>;
17
31
  };
package/dist/index.js CHANGED
@@ -48,6 +48,11 @@ function getAllTransitions(state) {
48
48
  function wrapInXml(tagName, content) {
49
49
  return `<${tagName}>${content}</${tagName}>`;
50
50
  }
51
+ function randomId() {
52
+ const timestamp = Date.now().toString(36);
53
+ const random = Math.random().toString(36).substring(2, 9);
54
+ return timestamp + random;
55
+ }
51
56
 
52
57
  // src/templates/defaultText.ts
53
58
  var defaultTextTemplate = (data) => {
@@ -118,10 +123,10 @@ async function simplePlanner(agent, input) {
118
123
  goal: input.goal
119
124
  });
120
125
  const result = await agent.generateText({
126
+ ...input,
121
127
  prompt,
122
128
  tools: toolMap,
123
- toolChoice: "required",
124
- ...input
129
+ toolChoice: "required"
125
130
  });
126
131
  const singleResult = result.toolResults[0];
127
132
  if (!singleResult) {
@@ -144,7 +149,6 @@ async function simplePlanner(agent, input) {
144
149
 
145
150
  // src/text.ts
146
151
  var import_xstate = require("xstate");
147
- var import_nanoid = require("nanoid");
148
152
  async function getMessages(agent, prompt, options) {
149
153
  let messages = [];
150
154
  if (options.messages === true) {
@@ -166,7 +170,7 @@ async function agentGenerateText(agent, options) {
166
170
  ...options
167
171
  };
168
172
  const template = resolvedOptions.template ?? defaultTextTemplate;
169
- const id = (0, import_nanoid.nanoid)();
173
+ const id = randomId();
170
174
  const goal = typeof resolvedOptions.prompt === "string" ? resolvedOptions.prompt : await resolvedOptions.prompt(agent);
171
175
  const promptWithContext = template({
172
176
  goal,
@@ -200,7 +204,7 @@ async function agentStreamText(agent, options) {
200
204
  ...options
201
205
  };
202
206
  const template = resolvedOptions.template ?? defaultTextTemplate;
203
- const id = (0, import_nanoid.nanoid)();
207
+ const id = randomId();
204
208
  const goal = typeof resolvedOptions.prompt === "string" ? resolvedOptions.prompt : await resolvedOptions.prompt(agent);
205
209
  const promptWithContext = template({
206
210
  goal,
@@ -232,7 +236,7 @@ async function agentStreamText(agent, options) {
232
236
  rawResponse: res.rawResponse
233
237
  },
234
238
  content: res.text,
235
- id: (0, import_nanoid.nanoid)(),
239
+ id: randomId(),
236
240
  timestamp: Date.now(),
237
241
  responseId: id
238
242
  });
@@ -352,7 +356,6 @@ var vercelAdapter = {
352
356
  };
353
357
 
354
358
  // src/agent.ts
355
- var import_nanoid2 = require("nanoid");
356
359
  var agentLogic = (0, import_xstate3.fromTransition)(
357
360
  (state, event, { emit }) => {
358
361
  switch (event.type) {
@@ -437,7 +440,7 @@ function createAgent({
437
440
  agent.addMessage = (messageInput) => {
438
441
  const message = {
439
442
  ...messageInput,
440
- id: messageInput.id ?? (0, import_nanoid2.nanoid)(),
443
+ id: messageInput.id ?? randomId(),
441
444
  timestamp: messageInput.timestamp ?? Date.now(),
442
445
  sessionId: agent.sessionId
443
446
  };
@@ -464,7 +467,7 @@ function createAgent({
464
467
  agent.addObservation = (observationInput) => {
465
468
  const observation = {
466
469
  ...observationInput,
467
- id: observationInput.id ?? (0, import_nanoid2.nanoid)(),
470
+ id: observationInput.id ?? randomId(),
468
471
  sessionId: agent.sessionId,
469
472
  timestamp: observationInput.timestamp ?? Date.now()
470
473
  };
package/dist/index.mjs CHANGED
@@ -21,6 +21,11 @@ function getAllTransitions(state) {
21
21
  function wrapInXml(tagName, content) {
22
22
  return `<${tagName}>${content}</${tagName}>`;
23
23
  }
24
+ function randomId() {
25
+ const timestamp = Date.now().toString(36);
26
+ const random = Math.random().toString(36).substring(2, 9);
27
+ return timestamp + random;
28
+ }
24
29
 
25
30
  // src/templates/defaultText.ts
26
31
  var defaultTextTemplate = (data) => {
@@ -91,10 +96,10 @@ async function simplePlanner(agent, input) {
91
96
  goal: input.goal
92
97
  });
93
98
  const result = await agent.generateText({
99
+ ...input,
94
100
  prompt,
95
101
  tools: toolMap,
96
- toolChoice: "required",
97
- ...input
102
+ toolChoice: "required"
98
103
  });
99
104
  const singleResult = result.toolResults[0];
100
105
  if (!singleResult) {
@@ -121,7 +126,6 @@ import {
121
126
  fromPromise,
122
127
  toObserver
123
128
  } from "xstate";
124
- import { nanoid } from "nanoid";
125
129
  async function getMessages(agent, prompt, options) {
126
130
  let messages = [];
127
131
  if (options.messages === true) {
@@ -143,7 +147,7 @@ async function agentGenerateText(agent, options) {
143
147
  ...options
144
148
  };
145
149
  const template = resolvedOptions.template ?? defaultTextTemplate;
146
- const id = nanoid();
150
+ const id = randomId();
147
151
  const goal = typeof resolvedOptions.prompt === "string" ? resolvedOptions.prompt : await resolvedOptions.prompt(agent);
148
152
  const promptWithContext = template({
149
153
  goal,
@@ -177,7 +181,7 @@ async function agentStreamText(agent, options) {
177
181
  ...options
178
182
  };
179
183
  const template = resolvedOptions.template ?? defaultTextTemplate;
180
- const id = nanoid();
184
+ const id = randomId();
181
185
  const goal = typeof resolvedOptions.prompt === "string" ? resolvedOptions.prompt : await resolvedOptions.prompt(agent);
182
186
  const promptWithContext = template({
183
187
  goal,
@@ -209,7 +213,7 @@ async function agentStreamText(agent, options) {
209
213
  rawResponse: res.rawResponse
210
214
  },
211
215
  content: res.text,
212
- id: nanoid(),
216
+ id: randomId(),
213
217
  timestamp: Date.now(),
214
218
  responseId: id
215
219
  });
@@ -329,7 +333,6 @@ var vercelAdapter = {
329
333
  };
330
334
 
331
335
  // src/agent.ts
332
- import { nanoid as nanoid2 } from "nanoid";
333
336
  var agentLogic = fromTransition(
334
337
  (state, event, { emit }) => {
335
338
  switch (event.type) {
@@ -414,7 +417,7 @@ function createAgent({
414
417
  agent.addMessage = (messageInput) => {
415
418
  const message = {
416
419
  ...messageInput,
417
- id: messageInput.id ?? nanoid2(),
420
+ id: messageInput.id ?? randomId(),
418
421
  timestamp: messageInput.timestamp ?? Date.now(),
419
422
  sessionId: agent.sessionId
420
423
  };
@@ -441,7 +444,7 @@ function createAgent({
441
444
  agent.addObservation = (observationInput) => {
442
445
  const observation = {
443
446
  ...observationInput,
444
- id: observationInput.id ?? nanoid2(),
447
+ id: observationInput.id ?? randomId(),
445
448
  sessionId: agent.sessionId,
446
449
  timestamp: observationInput.timestamp ?? Date.now()
447
450
  };
@@ -2,7 +2,6 @@ import { assign, setup, assertEvent, createActor } from 'xstate';
2
2
  import { z } from 'zod';
3
3
  import { createAgent, fromDecision, fromTextStream } from '../src';
4
4
  import { openai } from '@ai-sdk/openai';
5
- import { defaultToolCallTemplate } from '../src/templates/defaultToolCall';
6
5
 
7
6
  const agent = createAgent({
8
7
  name: 'tic-tac-toe-bot',
package/examples/word.ts CHANGED
@@ -12,7 +12,7 @@ const context = {
12
12
 
13
13
  const agent = createAgent({
14
14
  name: 'word',
15
- model: openai('gpt-4-1106-preview'),
15
+ model: openai('gpt-4o'),
16
16
  events: {
17
17
  'agent.guessLetter': z.object({
18
18
  letter: z.string().min(1).max(1).describe('The letter guessed'),
@@ -42,12 +42,15 @@ const wordGuesserMachine = setup({
42
42
  agent: fromDecision(agent),
43
43
  getFromTerminal,
44
44
  },
45
+ actions: {
46
+ resetContext: assign(context),
47
+ },
45
48
  }).createMachine({
46
49
  initial: 'providingWord',
47
50
  context,
48
51
  states: {
49
52
  providingWord: {
50
- entry: assign(context),
53
+ entry: 'resetContext',
51
54
  invoke: {
52
55
  src: 'getFromTerminal',
53
56
  input: 'Enter a word, and an agent will try to guess it.',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@statelyai/agent",
3
- "version": "0.1.4",
4
- "description": "",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "Stateful agents that make decisions based on finite-state machine models",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
@@ -9,13 +9,20 @@
9
9
  "build": "tsup src/index.ts --format cjs,esm --dts",
10
10
  "lint": "tsc --noEmit",
11
11
  "test": "vitest",
12
+ "test:ci": "vitest --run",
12
13
  "example": "ts-node examples/helpers/runner.ts",
13
14
  "prepublishOnly": "tsup src/index.ts --format cjs,esm --dts",
14
15
  "changeset": "changeset",
15
16
  "release": "changeset publish",
16
17
  "version": "changeset version"
17
18
  },
18
- "keywords": [],
19
+ "keywords": [
20
+ "ai",
21
+ "state machine",
22
+ "agent",
23
+ "rl",
24
+ "reinforcement learning"
25
+ ],
19
26
  "author": "",
20
27
  "license": "MIT",
21
28
  "devDependencies": {
@@ -24,7 +31,7 @@
24
31
  "@langchain/community": "^0.0.53",
25
32
  "@langchain/core": "^0.1.63",
26
33
  "@langchain/openai": "^0.0.28",
27
- "@types/node": "^20.14.2",
34
+ "@types/node": "^20.14.6",
28
35
  "dotenv": "^16.4.5",
29
36
  "json-schema-to-ts": "^3.1.0",
30
37
  "ts-node": "^10.9.2",
@@ -38,10 +45,9 @@
38
45
  "access": "public"
39
46
  },
40
47
  "dependencies": {
41
- "@ai-sdk/openai": "^0.0.13",
48
+ "@ai-sdk/openai": "^0.0.31",
42
49
  "@xstate/graph": "^2.0.0",
43
- "ai": "^3.1.32",
44
- "nanoid": "^5.0.7",
50
+ "ai": "^3.2.1",
45
51
  "xstate": "^5.13.2"
46
52
  },
47
53
  "packageManager": "pnpm@8.11.0"
package/src/agent.ts CHANGED
@@ -25,7 +25,7 @@ import { simplePlanner } from './planners/simplePlanner';
25
25
  import { agentGenerateText, agentStreamText } from './text';
26
26
  import { agentDecide } from './decision';
27
27
  import { vercelAdapter } from './adapters/vercel';
28
- import { nanoid } from 'nanoid';
28
+ import { randomId } from './utils';
29
29
 
30
30
  export const agentLogic: AgentLogic<AnyEventObject> = fromTransition(
31
31
  (state, event, { emit }) => {
@@ -144,7 +144,7 @@ export function createAgent<
144
144
  agent.addMessage = (messageInput) => {
145
145
  const message = {
146
146
  ...messageInput,
147
- id: messageInput.id ?? nanoid(),
147
+ id: messageInput.id ?? randomId(),
148
148
  timestamp: messageInput.timestamp ?? Date.now(),
149
149
  sessionId: agent.sessionId,
150
150
  };
@@ -176,7 +176,7 @@ export function createAgent<
176
176
  agent.addObservation = (observationInput) => {
177
177
  const observation = {
178
178
  ...observationInput,
179
- id: observationInput.id ?? nanoid(),
179
+ id: observationInput.id ?? randomId(),
180
180
  sessionId: agent.sessionId,
181
181
  timestamp: observationInput.timestamp ?? Date.now(),
182
182
  };
@@ -100,10 +100,10 @@ export async function simplePlanner<T extends Agent<any>>(
100
100
  });
101
101
 
102
102
  const result = await agent.generateText({
103
+ ...input,
103
104
  prompt,
104
105
  tools: toolMap,
105
106
  toolChoice: 'required',
106
- ...input,
107
107
  });
108
108
 
109
109
  const singleResult = result.toolResults[0];
package/src/text.ts CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  fromPromise,
20
20
  toObserver,
21
21
  } from 'xstate';
22
- import { nanoid } from 'nanoid';
22
+ import { randomId } from './utils';
23
23
 
24
24
  /**
25
25
  * Gets an array of messages from the given prompt, based on the agent and options.
@@ -61,7 +61,7 @@ export async function agentGenerateText<T extends Agent<any>>(
61
61
  };
62
62
  const template = resolvedOptions.template ?? defaultTextTemplate;
63
63
  // TODO: check if messages was provided instead
64
- const id = nanoid();
64
+ const id = randomId();
65
65
  const goal =
66
66
  typeof resolvedOptions.prompt === 'string'
67
67
  ? resolvedOptions.prompt
@@ -109,7 +109,7 @@ export async function agentStreamText(
109
109
  };
110
110
  const template = resolvedOptions.template ?? defaultTextTemplate;
111
111
 
112
- const id = nanoid();
112
+ const id = randomId();
113
113
  const goal =
114
114
  typeof resolvedOptions.prompt === 'string'
115
115
  ? resolvedOptions.prompt
@@ -148,7 +148,7 @@ export async function agentStreamText(
148
148
  rawResponse: res.rawResponse,
149
149
  },
150
150
  content: res.text,
151
- id: nanoid(),
151
+ id: randomId(),
152
152
  timestamp: Date.now(),
153
153
  responseId: id,
154
154
  });
package/src/types.ts CHANGED
@@ -29,14 +29,31 @@ export type GenerateTextOptions = Parameters<typeof generateText>[0];
29
29
 
30
30
  export type StreamTextOptions = Parameters<typeof streamText>[0];
31
31
 
32
- export type AgentPlanInput<TEvent extends EventObject> = {
33
- model: LanguageModel;
32
+ export type AgentPlanInput<TEvent extends EventObject> = Omit<
33
+ GenerateTextOptions,
34
+ 'prompt' | 'messages' | 'tools'
35
+ > & {
36
+ /**
37
+ * The currently observed state.
38
+ */
34
39
  state: ObservedState;
40
+ /**
41
+ * The goal for the agent to accomplish.
42
+ * The agent will create a plan based on this goal.
43
+ */
35
44
  goal: string;
45
+ /**
46
+ * The events that the agent can trigger. This is a mapping of
47
+ * event types to Zod event schemas.
48
+ */
36
49
  events: ZodEventMapping;
50
+ /**
51
+ * The state machine that represents the environment the agent
52
+ * is interacting with.
53
+ */
37
54
  machine?: AnyStateMachine;
38
55
  /**
39
- * The previous plan
56
+ * The previous plan.
40
57
  */
41
58
  previousPlan?: AgentPlan<TEvent>;
42
59
  };
package/src/utils.ts CHANGED
@@ -20,3 +20,9 @@ export function getAllTransitions(state: AnyMachineSnapshot): TransitionData[] {
20
20
  export function wrapInXml(tagName: string, content: string): string {
21
21
  return `<${tagName}>${content}</${tagName}>`;
22
22
  }
23
+
24
+ export function randomId() {
25
+ const timestamp = Date.now().toString(36);
26
+ const random = Math.random().toString(36).substring(2, 9);
27
+ return timestamp + random;
28
+ }