import { type AutomationId, type AutomationRecord, type AutomationTask, type ShapeType, type When } from "@vendoai/core"; import type { LanguageModel } from "ai"; import { type HostToolInfo } from "../generation/engine.js"; /** * The automation door's authoring: ONE structured model call turns a * plain-language ask into the `when` and the `task` of an automation RECORD, * plus the results collection the app's tree binds. No new automation machinery * — the record is created through the one create operation the engine exposes, * and setup completes in seconds because no machine is involved. */ export interface AutomationPlanInput { appId: string; appName: string; instruction: string; /** How the automation runs: deterministic `steps`, or a `goal` when each * firing needs a model's judgment. It IS the task kind the plan must answer * with — one vocabulary, no translation. */ mode: AutomationTask["kind"]; /** The tools steps may name / the goal's prompt may reference — the SAME * guard-bound surface the automations engine executes through. */ tools: readonly HostToolInfo[]; /** The tools' DECLARED result shapes, keyed by tool name: without them the * model guesses output fields and the jsonata reads nothing (the live-gate * "steps.unpaid.items" class). */ toolShapes?: Readonly>; /** * The automations this app's own list ALREADY names, resolved. * * An app's list holds many, so "check every morning too" adds one while "move * the digest to 9am" changes one, and only something reading the request * against the list can tell those apart. This is what lets the plan answer * with {@link AutomationPlan.replaces}; without it every re-plan of an * existing automation would land beside itself as a duplicate. */ existing?: readonly AutomationRecord[]; } export interface AutomationPlan { /** WHEN it fires, in the SAME authoring vocabulary `.on()` and the chat tool * speak — core's `toTriggerSource` is the one thing that normalizes it. */ when: When; /** WHAT it does. */ task: AutomationTask; /** The automation's own name, the way the person would say it out loud. */ name?: string; /** The app records collection the automation writes displayable results * into — a table in the app's own database, read back by the board. */ resultsCollection?: string; /** The id of the EXISTING automation this plan is a new version of — set only * when the instruction changed one of {@link AutomationPlanInput.existing} * rather than asking for another. Absent means a new record beside them. */ replaces?: AutomationId; } export type AutomationPlanResult = { kind: "plan"; plan: AutomationPlan; } | { kind: "failure"; issues: string[]; }; /** The one statement the publish step runs. The row's id and its payload are * both PARAMETERS, so the jsonata the planner writes never has to nest a * quote inside a quote inside JSON. */ export declare const resultsStatement: (table: string) => string; export declare const resultsPublishArgs: (appId: string, table: string) => string; export declare const toolLine: ({ name, description, risk, inputSchema }: HostToolInfo, shape: ShapeType | undefined) => string; /** Author one automation: up to 3 model attempts, each repair fed the * accumulated issues (the engine's create/edit loop shape). */ export declare const planAutomation: (input: AutomationPlanInput, model: LanguageModel) => Promise; //# sourceMappingURL=plan.d.ts.map