@statelyai/agent 0.1.0 → 0.1.2
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 +303 -2
- package/dist/index.js +4 -3915
- package/dist/index.mjs +515 -4
- package/examples/todo.ts +6 -3
- package/package.json +13 -12
- package/src/planners/simplePlanner.ts +5 -2
- package/src/schemas.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,518 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/agent.ts
|
|
2
|
+
import {
|
|
3
|
+
createActor,
|
|
4
|
+
fromTransition,
|
|
5
|
+
toObserver as toObserver2
|
|
6
|
+
} from "xstate";
|
|
7
|
+
|
|
8
|
+
// src/planners/simplePlanner.ts
|
|
9
|
+
import { tool } from "ai";
|
|
10
|
+
|
|
11
|
+
// src/utils.ts
|
|
12
|
+
function getAllTransitions(state) {
|
|
13
|
+
const nodes = state._nodes;
|
|
14
|
+
const transitions = nodes.map((node) => [...node.transitions.values()]).flat(2).map((transition) => ({
|
|
15
|
+
...transition,
|
|
16
|
+
guard: typeof transition.guard === "string" ? { type: transition.guard } : transition.guard
|
|
17
|
+
// TODO: fix
|
|
18
|
+
}));
|
|
19
|
+
return transitions;
|
|
20
|
+
}
|
|
21
|
+
function wrapInXml(tagName, content) {
|
|
22
|
+
return `<${tagName}>${content}</${tagName}>`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/templates/defaultText.ts
|
|
26
|
+
var defaultTextTemplate = (data) => {
|
|
27
|
+
const preamble = [
|
|
28
|
+
data.context ? wrapInXml("context", JSON.stringify(data.context)) : void 0
|
|
29
|
+
].filter(Boolean).join("\n");
|
|
30
|
+
return `
|
|
31
|
+
${preamble}
|
|
32
|
+
|
|
33
|
+
${data.goal}
|
|
34
|
+
`.trim();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// src/planners/simplePlanner.ts
|
|
38
|
+
function getTransitions(state, machine) {
|
|
39
|
+
if (!machine) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
const resolvedState = machine.resolveState(state);
|
|
43
|
+
return getAllTransitions(resolvedState);
|
|
44
|
+
}
|
|
45
|
+
var simplePlannerPromptTemplate = (data) => {
|
|
46
|
+
return `
|
|
47
|
+
${defaultTextTemplate(data)}
|
|
48
|
+
|
|
49
|
+
Only make a single tool call to achieve the above goal.
|
|
50
|
+
`.trim();
|
|
51
|
+
};
|
|
52
|
+
async function simplePlanner(agent, input) {
|
|
53
|
+
const transitions = input.machine ? getTransitions(input.state, input.machine) : Object.entries(input.events).map(([eventType, { description }]) => ({
|
|
54
|
+
eventType,
|
|
55
|
+
description
|
|
56
|
+
}));
|
|
57
|
+
const filter = (eventType) => Object.keys(input.events).includes(eventType);
|
|
58
|
+
const functionNameMapping = {};
|
|
59
|
+
const toolTransitions = transitions.filter((t) => {
|
|
60
|
+
return filter(t.eventType);
|
|
61
|
+
}).map((t) => {
|
|
62
|
+
const name = t.eventType.replace(/\./g, "_");
|
|
63
|
+
functionNameMapping[name] = t.eventType;
|
|
64
|
+
return {
|
|
65
|
+
type: "function",
|
|
66
|
+
eventType: t.eventType,
|
|
67
|
+
description: t.description,
|
|
68
|
+
name
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
const toolMap = {};
|
|
72
|
+
for (const toolTransitionData of toolTransitions) {
|
|
73
|
+
const toolZodType = input.events?.[toolTransitionData.eventType];
|
|
74
|
+
if (!toolZodType) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
toolMap[toolTransitionData.name] = tool({
|
|
78
|
+
description: toolZodType?.description ?? toolTransitionData.description,
|
|
79
|
+
parameters: toolZodType,
|
|
80
|
+
execute: async (params) => {
|
|
81
|
+
const event = {
|
|
82
|
+
type: toolTransitionData.eventType,
|
|
83
|
+
...params
|
|
84
|
+
};
|
|
85
|
+
return event;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const prompt = simplePlannerPromptTemplate({
|
|
90
|
+
context: input.state.context,
|
|
91
|
+
goal: input.goal
|
|
92
|
+
});
|
|
93
|
+
const result = await agent.generateText({
|
|
94
|
+
prompt,
|
|
95
|
+
tools: toolMap,
|
|
96
|
+
toolChoice: "required",
|
|
97
|
+
...input
|
|
98
|
+
});
|
|
99
|
+
const singleResult = result.toolResults[0];
|
|
100
|
+
if (!singleResult) {
|
|
101
|
+
console.warn("No tool call results returned");
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
goal: input.goal,
|
|
106
|
+
state: input.state,
|
|
107
|
+
steps: [
|
|
108
|
+
{
|
|
109
|
+
event: singleResult.result
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
nextEvent: singleResult.result,
|
|
113
|
+
sessionId: agent.sessionId,
|
|
114
|
+
timestamp: Date.now()
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/agent.ts
|
|
119
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
120
|
+
|
|
121
|
+
// src/text.ts
|
|
122
|
+
import { randomUUID } from "crypto";
|
|
123
|
+
import {
|
|
124
|
+
fromObservable,
|
|
125
|
+
fromPromise,
|
|
126
|
+
toObserver
|
|
127
|
+
} from "xstate";
|
|
128
|
+
async function getMessages(agent, prompt, options) {
|
|
129
|
+
let messages = [];
|
|
130
|
+
if (options.messages === true) {
|
|
131
|
+
messages = agent.select((s) => s.messages);
|
|
132
|
+
} else if (typeof options.messages === "function") {
|
|
133
|
+
messages = await options.messages(agent);
|
|
134
|
+
} else if (options.messages) {
|
|
135
|
+
messages = options.messages;
|
|
136
|
+
}
|
|
137
|
+
messages = messages.concat({
|
|
138
|
+
role: "user",
|
|
139
|
+
content: prompt
|
|
140
|
+
});
|
|
141
|
+
return messages;
|
|
142
|
+
}
|
|
143
|
+
async function agentGenerateText(agent, options) {
|
|
144
|
+
const resolvedOptions = {
|
|
145
|
+
...agent.defaultOptions,
|
|
146
|
+
...options
|
|
147
|
+
};
|
|
148
|
+
const template = resolvedOptions.template ?? defaultTextTemplate;
|
|
149
|
+
const id = randomUUID();
|
|
150
|
+
const goal = typeof resolvedOptions.prompt === "string" ? resolvedOptions.prompt : await resolvedOptions.prompt(agent);
|
|
151
|
+
const promptWithContext = template({
|
|
152
|
+
goal,
|
|
153
|
+
context: resolvedOptions.context
|
|
154
|
+
});
|
|
155
|
+
const messages = await getMessages(agent, promptWithContext, resolvedOptions);
|
|
156
|
+
agent.addMessage({
|
|
157
|
+
id,
|
|
158
|
+
role: "user",
|
|
159
|
+
content: promptWithContext,
|
|
160
|
+
timestamp: Date.now()
|
|
161
|
+
});
|
|
162
|
+
const result = await agent.adapter.generateText({
|
|
163
|
+
...resolvedOptions,
|
|
164
|
+
prompt: void 0,
|
|
165
|
+
messages
|
|
166
|
+
});
|
|
167
|
+
agent.addMessage({
|
|
168
|
+
content: result.text,
|
|
169
|
+
id,
|
|
170
|
+
role: "assistant",
|
|
171
|
+
timestamp: Date.now(),
|
|
172
|
+
responseId: id,
|
|
173
|
+
result
|
|
174
|
+
});
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
async function agentStreamText(agent, options) {
|
|
178
|
+
const resolvedOptions = {
|
|
179
|
+
...agent.defaultOptions,
|
|
180
|
+
...options
|
|
181
|
+
};
|
|
182
|
+
const template = resolvedOptions.template ?? defaultTextTemplate;
|
|
183
|
+
const id = randomUUID();
|
|
184
|
+
const goal = typeof resolvedOptions.prompt === "string" ? resolvedOptions.prompt : await resolvedOptions.prompt(agent);
|
|
185
|
+
const promptWithContext = template({
|
|
186
|
+
goal,
|
|
187
|
+
context: resolvedOptions.context
|
|
188
|
+
});
|
|
189
|
+
const messages = await getMessages(agent, promptWithContext, resolvedOptions);
|
|
190
|
+
agent.addMessage({
|
|
191
|
+
role: "user",
|
|
192
|
+
content: promptWithContext,
|
|
193
|
+
id,
|
|
194
|
+
timestamp: Date.now()
|
|
195
|
+
});
|
|
196
|
+
const result = await agent.adapter.streamText({
|
|
197
|
+
...resolvedOptions,
|
|
198
|
+
prompt: void 0,
|
|
199
|
+
messages,
|
|
200
|
+
onFinish: async (res) => {
|
|
201
|
+
agent.addMessage({
|
|
202
|
+
role: "assistant",
|
|
203
|
+
result: {
|
|
204
|
+
text: res.text,
|
|
205
|
+
finishReason: res.finishReason,
|
|
206
|
+
logprobs: void 0,
|
|
207
|
+
responseMessages: [],
|
|
208
|
+
toolCalls: [],
|
|
209
|
+
toolResults: [],
|
|
210
|
+
usage: res.usage,
|
|
211
|
+
warnings: res.warnings,
|
|
212
|
+
rawResponse: res.rawResponse
|
|
213
|
+
},
|
|
214
|
+
content: res.text,
|
|
215
|
+
id: randomUUID(),
|
|
216
|
+
timestamp: Date.now(),
|
|
217
|
+
responseId: id
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
function fromTextStream(agent, defaultOptions) {
|
|
224
|
+
return fromObservable(({ input, self }) => {
|
|
225
|
+
const context = input.context === true ? (self._parent?.getSnapshot()).context : input.context;
|
|
226
|
+
const observers = /* @__PURE__ */ new Set();
|
|
227
|
+
(async () => {
|
|
228
|
+
const result = await agentStreamText(agent, {
|
|
229
|
+
...defaultOptions,
|
|
230
|
+
...input,
|
|
231
|
+
context
|
|
232
|
+
});
|
|
233
|
+
for await (const part of result.fullStream) {
|
|
234
|
+
if (part.type === "text-delta") {
|
|
235
|
+
observers.forEach((observer) => {
|
|
236
|
+
observer.next?.(part);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
})();
|
|
241
|
+
return {
|
|
242
|
+
subscribe: (...args) => {
|
|
243
|
+
const observer = toObserver(...args);
|
|
244
|
+
observers.add(observer);
|
|
245
|
+
return {
|
|
246
|
+
unsubscribe: () => {
|
|
247
|
+
observers.delete(observer);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function fromText(agent, defaultOptions) {
|
|
255
|
+
return fromPromise(async ({ input, self }) => {
|
|
256
|
+
const context = input.context === true ? (self._parent?.getSnapshot()).context : input.context;
|
|
257
|
+
return await agentGenerateText(agent, {
|
|
258
|
+
...input,
|
|
259
|
+
...defaultOptions,
|
|
260
|
+
context
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// src/decision.ts
|
|
266
|
+
import { fromPromise as fromPromise2 } from "xstate";
|
|
267
|
+
async function agentDecide(agent, options) {
|
|
268
|
+
const resolvedOptions = {
|
|
269
|
+
...agent.defaultOptions,
|
|
270
|
+
...options
|
|
271
|
+
};
|
|
272
|
+
const {
|
|
273
|
+
planner = simplePlanner,
|
|
274
|
+
goal,
|
|
275
|
+
events = agent.events,
|
|
276
|
+
state,
|
|
277
|
+
machine,
|
|
278
|
+
model = agent.model,
|
|
279
|
+
...otherPlanInput
|
|
280
|
+
} = resolvedOptions;
|
|
281
|
+
const plan = await planner(agent, {
|
|
282
|
+
model,
|
|
283
|
+
goal,
|
|
284
|
+
events,
|
|
285
|
+
state,
|
|
286
|
+
machine,
|
|
287
|
+
...otherPlanInput
|
|
288
|
+
});
|
|
289
|
+
if (plan?.nextEvent) {
|
|
290
|
+
agent.addPlan(plan);
|
|
291
|
+
await resolvedOptions.execute?.(plan.nextEvent);
|
|
292
|
+
}
|
|
293
|
+
return plan;
|
|
294
|
+
}
|
|
295
|
+
function fromDecision(agent, defaultInput) {
|
|
296
|
+
return fromPromise2(async ({ input, self }) => {
|
|
297
|
+
const parentRef = self._parent;
|
|
298
|
+
if (!parentRef) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const snapshot = parentRef.getSnapshot();
|
|
302
|
+
const inputObject = typeof input === "string" ? { goal: input } : input;
|
|
303
|
+
const resolvedInput = {
|
|
304
|
+
...defaultInput,
|
|
305
|
+
...inputObject
|
|
306
|
+
};
|
|
307
|
+
const contextToInclude = resolvedInput.context === true ? (
|
|
308
|
+
// include entire context
|
|
309
|
+
parentRef.getSnapshot().context
|
|
310
|
+
) : resolvedInput.context;
|
|
311
|
+
const state = {
|
|
312
|
+
value: snapshot.value,
|
|
313
|
+
context: contextToInclude
|
|
314
|
+
};
|
|
315
|
+
const plan = await agentDecide(agent, {
|
|
316
|
+
machine: parentRef.src,
|
|
317
|
+
state,
|
|
318
|
+
execute: async (event) => {
|
|
319
|
+
parentRef.send(event);
|
|
320
|
+
},
|
|
321
|
+
...resolvedInput
|
|
322
|
+
});
|
|
323
|
+
return plan;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// src/adapters/vercel.ts
|
|
328
|
+
import { generateText, streamText } from "ai";
|
|
329
|
+
var vercelAdapter = {
|
|
330
|
+
generateText,
|
|
331
|
+
streamText
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// src/agent.ts
|
|
335
|
+
var agentLogic = fromTransition(
|
|
336
|
+
(state, event, { emit }) => {
|
|
337
|
+
switch (event.type) {
|
|
338
|
+
case "agent.feedback": {
|
|
339
|
+
state.feedback.push(event.feedback);
|
|
340
|
+
emit({
|
|
341
|
+
type: "feedback",
|
|
342
|
+
// @ts-ignore TODO: fix types in XState
|
|
343
|
+
feedback: event.feedback
|
|
344
|
+
});
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
case "agent.observe": {
|
|
348
|
+
state.observations.push(event.observation);
|
|
349
|
+
emit({
|
|
350
|
+
type: "observation",
|
|
351
|
+
// @ts-ignore TODO: fix types in XState
|
|
352
|
+
observation: event.observation
|
|
353
|
+
});
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
case "agent.message": {
|
|
357
|
+
state.messages.push(event.message);
|
|
358
|
+
emit({
|
|
359
|
+
type: "message",
|
|
360
|
+
// @ts-ignore TODO: fix types in XState
|
|
361
|
+
message: event.message
|
|
362
|
+
});
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
case "agent.plan": {
|
|
366
|
+
state.plans.push(event.plan);
|
|
367
|
+
emit({
|
|
368
|
+
type: "plan",
|
|
369
|
+
// @ts-ignore TODO: fix types in XState
|
|
370
|
+
plan: event.plan
|
|
371
|
+
});
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
default:
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
return state;
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
feedback: [],
|
|
381
|
+
messages: [],
|
|
382
|
+
observations: [],
|
|
383
|
+
plans: []
|
|
384
|
+
}
|
|
385
|
+
);
|
|
386
|
+
function createAgent({
|
|
387
|
+
name,
|
|
388
|
+
description,
|
|
389
|
+
model,
|
|
390
|
+
events,
|
|
391
|
+
planner = simplePlanner,
|
|
392
|
+
stringify = JSON.stringify,
|
|
393
|
+
getMemory,
|
|
394
|
+
logic = agentLogic,
|
|
395
|
+
adapter = vercelAdapter,
|
|
396
|
+
...generateTextOptions
|
|
397
|
+
}) {
|
|
398
|
+
const messageHistoryListeners = [];
|
|
399
|
+
const agent = createActor(logic);
|
|
400
|
+
agent.events = events;
|
|
401
|
+
agent.model = model;
|
|
402
|
+
agent.name = name;
|
|
403
|
+
agent.description = description;
|
|
404
|
+
agent.adapter = adapter;
|
|
405
|
+
agent.defaultOptions = { ...generateTextOptions, model };
|
|
406
|
+
agent.select = (selector) => {
|
|
407
|
+
return selector(agent.getSnapshot().context);
|
|
408
|
+
};
|
|
409
|
+
agent.memory = getMemory ? getMemory(agent) : void 0;
|
|
410
|
+
agent.onMessage = (callback) => {
|
|
411
|
+
messageHistoryListeners.push(toObserver2(callback));
|
|
412
|
+
};
|
|
413
|
+
agent.decide = (opts) => {
|
|
414
|
+
return agentDecide(agent, opts);
|
|
415
|
+
};
|
|
416
|
+
agent.addMessage = (messageInput) => {
|
|
417
|
+
const message = {
|
|
418
|
+
...messageInput,
|
|
419
|
+
id: messageInput.id ?? randomUUID2(),
|
|
420
|
+
timestamp: messageInput.timestamp ?? Date.now(),
|
|
421
|
+
sessionId: agent.sessionId
|
|
422
|
+
};
|
|
423
|
+
agent.send({
|
|
424
|
+
type: "agent.message",
|
|
425
|
+
message
|
|
426
|
+
});
|
|
427
|
+
return message;
|
|
428
|
+
};
|
|
429
|
+
agent.generateText = (opts) => agentGenerateText(agent, opts);
|
|
430
|
+
agent.streamText = (opts) => agentStreamText(agent, opts);
|
|
431
|
+
agent.addFeedback = (feedbackInput) => {
|
|
432
|
+
const feedback = {
|
|
433
|
+
...feedbackInput,
|
|
434
|
+
timestamp: feedbackInput.timestamp ?? Date.now(),
|
|
435
|
+
sessionId: agent.sessionId
|
|
436
|
+
};
|
|
437
|
+
agent.send({
|
|
438
|
+
type: "agent.feedback",
|
|
439
|
+
feedback
|
|
440
|
+
});
|
|
441
|
+
return feedback;
|
|
442
|
+
};
|
|
443
|
+
agent.addObservation = (observationInput) => {
|
|
444
|
+
const observation = {
|
|
445
|
+
...observationInput,
|
|
446
|
+
id: observationInput.id ?? randomUUID2(),
|
|
447
|
+
sessionId: agent.sessionId,
|
|
448
|
+
timestamp: observationInput.timestamp ?? Date.now()
|
|
449
|
+
};
|
|
450
|
+
agent.send({
|
|
451
|
+
type: "agent.observe",
|
|
452
|
+
observation
|
|
453
|
+
});
|
|
454
|
+
return observation;
|
|
455
|
+
};
|
|
456
|
+
agent.addPlan = (plan) => {
|
|
457
|
+
agent.send({
|
|
458
|
+
type: "agent.plan",
|
|
459
|
+
plan
|
|
460
|
+
});
|
|
461
|
+
};
|
|
462
|
+
agent.interact = (actorRef, getInput) => {
|
|
463
|
+
let prevState = void 0;
|
|
464
|
+
let subscribed = true;
|
|
465
|
+
async function handleObservation(observationInput) {
|
|
466
|
+
const observation = agent.addObservation(observationInput);
|
|
467
|
+
const input = getInput?.(observation);
|
|
468
|
+
if (input) {
|
|
469
|
+
await agentDecide(agent, {
|
|
470
|
+
machine: actorRef.src,
|
|
471
|
+
state: observation.state,
|
|
472
|
+
execute: async (event) => {
|
|
473
|
+
actorRef.send(event);
|
|
474
|
+
},
|
|
475
|
+
...input
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
prevState = observationInput.state;
|
|
479
|
+
}
|
|
480
|
+
actorRef.system.inspect({
|
|
481
|
+
next: async (inspEvent) => {
|
|
482
|
+
if (!subscribed || inspEvent.actorRef !== actorRef || inspEvent.type !== "@xstate.snapshot") {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const observationInput = {
|
|
486
|
+
event: inspEvent.event,
|
|
487
|
+
prevState,
|
|
488
|
+
state: inspEvent.snapshot
|
|
489
|
+
};
|
|
490
|
+
await handleObservation(observationInput);
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
if (actorRef._processingStatus === 1) {
|
|
494
|
+
handleObservation({
|
|
495
|
+
prevState: void 0,
|
|
496
|
+
event: { type: "" },
|
|
497
|
+
// TODO: unknown events?
|
|
498
|
+
state: actorRef.getSnapshot()
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
return {
|
|
502
|
+
unsubscribe: () => {
|
|
503
|
+
subscribed = false;
|
|
504
|
+
}
|
|
505
|
+
// TODO: make this actually unsubscribe
|
|
506
|
+
};
|
|
507
|
+
};
|
|
508
|
+
agent.start();
|
|
509
|
+
return agent;
|
|
4
510
|
}
|
|
5
511
|
export {
|
|
6
|
-
|
|
512
|
+
agentDecide,
|
|
513
|
+
agentGenerateText,
|
|
514
|
+
createAgent,
|
|
515
|
+
fromDecision,
|
|
516
|
+
fromText,
|
|
517
|
+
fromTextStream
|
|
7
518
|
};
|
package/examples/todo.ts
CHANGED
|
@@ -9,7 +9,8 @@ const agent = createAgent({
|
|
|
9
9
|
model: openai('gpt-4o'),
|
|
10
10
|
events: {
|
|
11
11
|
addTodo: z.object({
|
|
12
|
-
|
|
12
|
+
title: z.string().min(1).max(100).describe('The title of the todo'),
|
|
13
|
+
content: z.string().min(1).max(100).describe('The content of the todo'),
|
|
13
14
|
}),
|
|
14
15
|
deleteTodo: z.object({
|
|
15
16
|
index: z.number().describe('The index of the todo to delete'),
|
|
@@ -24,7 +25,8 @@ const agent = createAgent({
|
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
interface Todo {
|
|
27
|
-
|
|
28
|
+
title: string;
|
|
29
|
+
content: string;
|
|
28
30
|
done: boolean;
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -48,7 +50,8 @@ const machine = setup({
|
|
|
48
50
|
todos: ({ context, event }) => [
|
|
49
51
|
...context.todos,
|
|
50
52
|
{
|
|
51
|
-
|
|
53
|
+
title: event.title,
|
|
54
|
+
content: event.content,
|
|
52
55
|
done: false,
|
|
53
56
|
},
|
|
54
57
|
],
|
package/package.json
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statelyai/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
10
|
+
"lint": "tsc --noEmit",
|
|
11
|
+
"test": "vitest",
|
|
12
|
+
"example": "ts-node examples/helpers/runner.ts",
|
|
13
|
+
"prepublishOnly": "tsup src/index.ts --format cjs,esm --dts",
|
|
14
|
+
"changeset": "changeset",
|
|
15
|
+
"release": "changeset publish",
|
|
16
|
+
"version": "changeset version"
|
|
17
|
+
},
|
|
8
18
|
"keywords": [],
|
|
9
19
|
"author": "",
|
|
10
20
|
"license": "MIT",
|
|
@@ -33,14 +43,5 @@
|
|
|
33
43
|
"ai": "^3.1.32",
|
|
34
44
|
"xstate": "^5.13.2"
|
|
35
45
|
},
|
|
36
|
-
"packageManager": "pnpm@8.11.0"
|
|
37
|
-
|
|
38
|
-
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
39
|
-
"lint": "tsc --noEmit",
|
|
40
|
-
"test": "vitest",
|
|
41
|
-
"example": "ts-node examples/helpers/runner.ts",
|
|
42
|
-
"changeset": "changeset",
|
|
43
|
-
"release": "changeset publish",
|
|
44
|
-
"version": "changeset version"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
46
|
+
"packageManager": "pnpm@8.11.0"
|
|
47
|
+
}
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
} from '../types';
|
|
10
10
|
import { getAllTransitions } from '../utils';
|
|
11
11
|
import { AnyStateMachine } from 'xstate';
|
|
12
|
-
import { z } from 'zod';
|
|
13
12
|
import { defaultTextTemplate } from '../templates/defaultText';
|
|
14
13
|
|
|
15
14
|
function getTransitions(
|
|
@@ -75,9 +74,13 @@ export async function simplePlanner<T extends Agent<any>>(
|
|
|
75
74
|
for (const toolTransitionData of toolTransitions) {
|
|
76
75
|
const toolZodType = input.events?.[toolTransitionData.eventType];
|
|
77
76
|
|
|
77
|
+
if (!toolZodType) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
78
81
|
toolMap[toolTransitionData.name] = tool({
|
|
79
82
|
description: toolZodType?.description ?? toolTransitionData.description,
|
|
80
|
-
parameters: toolZodType
|
|
83
|
+
parameters: toolZodType,
|
|
81
84
|
execute: async (params) => {
|
|
82
85
|
const event = {
|
|
83
86
|
type: toolTransitionData.eventType,
|
package/src/schemas.ts
CHANGED