UNPKG

@statelyai/agent

Version:

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

85 lines (76 loc) 1.92 kB
import { AnyActor, AnyMachineSnapshot, fromPromise } from 'xstate'; import { AnyAgent, AgentDecideOptions, AgentDecisionLogic, AgentDecisionInput, AgentPlanner, AgentPlan, } from './types'; import { simplePlanner } from './planners/simplePlanner'; export async function agentDecide<T extends AnyAgent>( agent: T, options: AgentDecideOptions ): Promise<AgentPlan<any> | undefined> { const resolvedOptions = { ...agent.defaultOptions, ...options, }; const { planner = simplePlanner as AgentPlanner<any>, goal, events = agent.events, state, machine, model = agent.model, ...otherPlanInput } = resolvedOptions; const plan = await planner(agent, { model, goal, events, state, machine, ...otherPlanInput, }); if (plan?.nextEvent) { agent.addPlan(plan); await resolvedOptions.execute?.(plan.nextEvent); } return plan; } export function fromDecision( agent: AnyAgent, defaultInput?: AgentDecisionInput ): AgentDecisionLogic<any> { return fromPromise(async ({ input, self }) => { const parentRef = self._parent; if (!parentRef) { return; } const snapshot = parentRef.getSnapshot() as AnyMachineSnapshot; const inputObject = typeof input === 'string' ? { goal: input } : input; const resolvedInput = { ...defaultInput, ...inputObject, }; const contextToInclude = resolvedInput.context === true ? // include entire context parentRef.getSnapshot().context : resolvedInput.context; const state = { value: snapshot.value, context: contextToInclude, }; const plan = await agentDecide(agent, { machine: (parentRef as AnyActor).logic, state, execute: async (event) => { parentRef.send(event); }, ...resolvedInput, }); return plan; }) as AgentDecisionLogic<any>; }