import * as plugins from './plugins.js'; import { AgentProxy } from './classes.agentproxy.js'; import { DeviceProxy } from './classes.deviceproxy.js'; export type TAutomationEvent = { triggerId: string; kind: plugins.shxInterfaces.data.TAutomationTriggerKind; payload: Record; }; export type TAutomationHandler = ( eventArg: TAutomationEvent, contextArg: ShxAutomationContext ) => Promise | void; export type TToolPlanExecutor = ( planArg: plugins.shxInterfaces.data.IToolPlan ) => Promise; export interface IShxAutomationContextOptions { callerId: string; executePlan?: TToolPlanExecutor; } export interface IAutomationRegistration { trigger: plugins.shxInterfaces.data.IAutomationTrigger; handler: TAutomationHandler; } export class ShxAutomationContext { public devices = new DeviceProxy(this); public agents = new AgentProxy(this); private registrations: IAutomationRegistration[] = []; constructor(public options: IShxAutomationContextOptions) {} public on( triggerArg: plugins.shxInterfaces.data.IAutomationTrigger, handlerArg: TAutomationHandler ) { this.registrations.push({ trigger: triggerArg, handler: handlerArg, }); return triggerArg; } public getRegistrations() { return [...this.registrations]; } public async runTrigger(eventArg: TAutomationEvent) { const matchingRegistrations = this.registrations.filter((registrationArg) => { return registrationArg.trigger.id === eventArg.triggerId || registrationArg.trigger.kind === eventArg.kind; }); for (const registration of matchingRegistrations) { await registration.handler(eventArg, this); } } public async executePlan(planArg: plugins.shxInterfaces.data.IToolPlan) { if (this.options.executePlan) { return this.options.executePlan(planArg); } return { planId: planArg.id, results: planArg.calls.map((callArg: plugins.shxInterfaces.data.IToolCall) => ({ callId: callArg.id, status: 'suggested' as const, output: { message: 'No hub executor attached. Plan was recorded as a suggestion.', }, })), }; } }