import type { IDriverAction } from "../actions"; import { BaseResponseHandler, type IResponseHandler } from "./base-handler"; export type FnArgs = Record; export interface IFunctionResponseHandler extends IResponseHandler {} export class FunctionResponseHandler extends BaseResponseHandler implements IFunctionResponseHandler { actionId?: string; fn?: any; fnName = ""; fnArgs: FnArgs = {}; chatMsg?: string; public async handle(step: any) { super.handle(step); if (!this.isFunctionCallStep()) { return; } this.setFunctionAttributes(); await this.performAction(); } get contextLengthLimit() { return this.driver.contextLengthLimit; } get context() { return this.driver.context; } protected setFunctionAttributes() { this.fn = this.step.function_call; this.fnName = this.fn.name; this.fnArgs = this.parseArgs(); } protected parseArgs() { const fn = this.fn; try { return JSON.parse(fn.arguments); } catch (_err) { if (this.fnName === "answer_user") { return { answer: fn.arguments, }; } } } protected async performAction() { try { const action = this.findAction(); action.setState({ args: this.fnArgs, context: this.context }); await action.execute(); return true; } catch (err: any) { this.log(err.message || `Action error ${this.actionId}`); return false; } } protected log(msg: string) { this.driver.log(msg); } protected communicateMessage(msg: string) { const message = msg.substring(0, this.contextLengthLimit); this.chatMsg = msg ?? { role: "function", name: this.fnName, content: JSON.stringify({ status: "OK", message: message, }), }; } protected handleAction() { this.performAction() || this.defaultAction(); } protected defaultAction() { this.communicateMessage( "That is an unregistered or invalid action. Please use a valid one", ); } protected findAction(): IDriverAction { if (!this.actionId) { throw new Error("Missing action id"); } const action = this.actions[this.actionId]; if (!action) { throw new Error(`Action ${this.actionId} is not registered`); } return action; } get actions() { return this.driver.actions; } }