UNPKG

@statelyai/agent

Version:

Stateful agents that make decisions based on finite-state machine models

103 lines (98 loc) 2.42 kB
import { createAgent, fromDecision } from '../src'; import { assign, createActor, log, setup } from 'xstate'; import { z } from 'zod'; import { openai } from '@ai-sdk/openai'; import { getFromTerminal } from './helpers/helpers'; const agent = createAgent({ name: 'number-guesser', model: openai('gpt-3.5-turbo-1106'), events: { 'agent.guess': z.object({ number: z.number().min(1).max(10).describe('The number guessed'), }), }, }); const machine = setup({ types: { context: {} as { previousGuesses: number[]; answer: number | null; }, events: agent.types.events, }, actors: { agent: fromDecision(agent), getFromTerminal, }, }).createMachine({ context: { answer: null, previousGuesses: [], }, initial: 'providing', states: { providing: { invoke: { src: 'getFromTerminal', input: 'Enter a number between 1 and 10', onDone: { actions: assign({ answer: (x) => +x.event.output, }), target: 'guessing', }, }, }, guessing: { always: { guard: ({ context }) => context.answer === context.previousGuesses.at(-1), target: 'winner', }, invoke: { src: 'agent', input: ({ context }) => ({ goal: ` Guess the number between 1 and 10. The previous guesses were ${ context.previousGuesses.length ? context.previousGuesses.join(', ') : 'not made yet' } and the last result was ${ context.previousGuesses.length === 0 ? 'not given yet' : context.previousGuesses.at(-1)! - context.answer! > 0 ? 'too high' : 'too low' }. `, }), }, on: { 'agent.guess': { actions: [ assign({ previousGuesses: ({ context, event }) => [ ...context.previousGuesses, event.number, ], }), log((x) => x.event.number), ], target: 'guessing', reenter: true, }, }, }, winner: { entry: log('You guessed the correct number!'), type: 'final', }, }, exit: () => { process.exit(); }, }); const actor = createActor(machine, { input: { answer: 4 }, }); actor.start();