UNPKG

@statelyai/agent

Version:

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

121 lines (115 loc) 3.01 kB
import { assign, createActor, setup, log } from 'xstate'; import { getFromTerminal } from './helpers/helpers'; import { createAgent, fromDecision } from '../src'; import { z } from 'zod'; import { openai } from '@ai-sdk/openai'; const agent = createAgent({ name: 'verifier', model: openai('gpt-3.5-turbo-16k-0613'), events: { 'agent.validateAnswer': z.object({ isValid: z.boolean(), feedback: z.string(), }), 'agent.answerQuestion': z.object({ answer: z.string().describe('The answer from the agent'), }), 'agent.validateQuestion': z.object({ isValid: z .boolean() .describe( 'Whether the question is a valid question; that is, is it possible to even answer this question in a verifiably correct way?' ), explanation: z .string() .describe('An explanation for why the question is or is not valid'), }), }, }); const machine = setup({ types: { context: {} as { question: string | null; answer: string | null; validation: string | null; }, events: agent.types.events, }, actors: { getFromTerminal, agent: fromDecision(agent), }, }).createMachine({ initial: 'askQuestion', context: { question: null, answer: null, validation: null }, states: { askQuestion: { invoke: { src: 'getFromTerminal', input: 'Ask a (potentially silly) question', onDone: { actions: assign({ question: ({ event }) => event.output, }), target: 'validateQuestion', }, }, }, validateQuestion: { invoke: { src: 'agent', input: ({ context }) => ({ goal: `Validate this question: ${context.question!}`, }), }, on: { 'agent.validateQuestion': [ { target: 'askQuestion', guard: ({ event }) => !event.isValid, actions: log(({ event }) => event.explanation), }, { target: 'answerQuestion', }, ], }, }, answerQuestion: { invoke: { src: 'agent', input: ({ context }) => ({ goal: `Answer this question: ${context.question}`, }), }, on: { 'agent.answerQuestion': { actions: assign({ answer: ({ event }) => event.answer, }), target: 'validateAnswer', }, }, }, validateAnswer: { invoke: { src: 'agent', input: ({ context }) => ({ goal: `Validate if this is a good answer to the question: ${context.question}\nAnswer provided: ${context.answer}`, }), }, on: { 'agent.validateAnswer': { actions: assign({ validation: ({ event }) => event.feedback, }), }, }, }, }, }); const actor = createActor(machine, {}); actor.subscribe((s) => { console.log(s.value, s.context); }); actor.start();