/** * Shared types for the workflows extension (Davis-style). * * Workflows are authored as inline JS: * export const meta = { name, description, phases }; * phase("title"); * await agent("prompt", { label, phase, schema, model, provider, effort }); * await parallel([() => agent(...), ...], { concurrency }); * * The JS executes in a sandbox child process (Node --permission + vm). * The parent receives IPC messages (phase/agent) and runs AgentSession in-process. */ import type { ThinkingLevel } from "@earendil-works/pi-agent-core"; import type { AgentToolResult } from "@earendil-works/pi-coding-agent"; // ── Workflow Meta ────────────────────────────────────────────────────────────── export interface WorkflowMeta { name: string; description?: string; phases?: string[]; } // ── Agent Options (passed from script) ───────────────────────────────────────── export interface AgentOptions { /** Human-readable label for this step */ label?: string; /** Phase grouping */ phase?: string; /** JSON Schema for structured output */ schema?: Record; /** Override model ID */ model?: string; /** Override provider */ provider?: string; /** Override thinking/effort level */ effort?: string; } // ── IPC Messages ─────────────────────────────────────────────────────────────── /** Message from child (sandbox) to parent. */ export type ChildMessage = | { type: "phase"; name: string } | { type: "agent"; id: string; prompt: string; options: AgentOptions } | { type: "complete"; meta?: WorkflowMeta; output?: string } | { type: "error"; message: string }; /** Message from parent to child (sandbox). */ export interface ParentMessage { type: "agent_result"; id: string; success: boolean; output?: string; error?: string; usage?: UsageStats; model?: string; structuredResult?: unknown; } // ── Usage Stats ──────────────────────────────────────────────────────────────── export interface UsageStats { input: number; output: number; cacheRead: number; cacheWrite: number; cost: number; turns: number; totalTokens: number; } // ── Step Progress ────────────────────────────────────────────────────────────── export type StepStatus = "pending" | "running" | "completed" | "failed" | "cancelled"; export interface StepProgress { stepId: string; label: string; phase: string; status: StepStatus; startedAt: number | null; finishedAt: number | null; prompt: string; output: string | null; error: string | null; usage: UsageStats; model?: string; modelId?: string; provider?: string; structuredResult?: unknown; } // ── Workflow Progress ────────────────────────────────────────────────────────── export type WorkflowStatus = "pending" | "running" | "completed" | "failed" | "cancelled"; export interface WorkflowProgress { runId: string; workflowName: string; status: WorkflowStatus; startedAt: number; finishedAt: number | null; phases: string[]; steps: StepProgress[]; totalAgentCalls: number; maxAgentCalls: number; error: string | null; output: string | null; } // ── Tool Parameters ──────────────────────────────────────────────────────────── export interface WorkflowToolParams { /** Workflow script content (inline JS) */ script: string; /** Optional args passed to workflow (JSON object) */ args?: string; /** Run in background */ background?: boolean; } // ── Run Options ──────────────────────────────────────────────────────────────── export interface WorkflowRunOptions { script: string; /** JSON-compatible arguments exposed to the script as global `args`. */ args?: Record; cwd: string; signal?: AbortSignal; onProgress?: (progress: WorkflowProgress) => void; /** Model registry from context */ modelRegistry: any; /** Default model from context */ defaultModel?: string; /** Default provider from context */ defaultProvider?: string; /** Thinking level from pi config */ thinking?: ThinkingLevel; /** Extension API for follow-up messages */ pi?: any; /** Whether this is a background run */ background?: boolean; /** Caller-provided run ID (optional). When provided, used instead of generating a new one. */ runId?: string; } // ── IPC Types (generic, for auth helpers) ────────────────────────────────────── export interface IpcMessage { type: "exec" | "result" | "error" | "ping" | "pong" | "progress"; requestId: string; payload?: unknown; token?: string; } // ── IPC Auth Types ───────────────────────────────────────────────────────────── export interface IpcAuthContext { token: string; createdAt: number; } // ── Dashboard Types ──────────────────────────────────────────────────────────── export interface DashboardState { runs: { runId: string; progress: WorkflowProgress | null }[]; selectedIndex: number; expanded: boolean; autoRefresh: boolean; refreshInterval: ReturnType | null; onClose: () => void; } // ── Constants ────────────────────────────────────────────────────────────────── export const DEFAULT_MAX_AGENT_CALLS = 32; export const DEFAULT_PARALLEL_CONCURRENCY = 4; export const DEFAULT_STEP_TIMEOUT_MS = 300_000; // 5 min export const DEFAULT_WORKFLOW_TIMEOUT_MS = 600_000; // 10 min export const MAX_SOURCE_BYTES = 64 * 1024; // 64 KiB export const MAX_RESULT_BYTES = 128 * 1024; // 128 KiB export const IPC_TOKEN_BYTES = 32; export const WORKFLOWS_DIR_NAME = "workflows"; export const IPC_DELIMITER = "__END_SCRIPT__"; // ── Tool Result ──────────────────────────────────────────────────────────────── export interface WorkflowToolResult { content: AgentToolResult["content"]; details: { runId: string; workflowName: string; status: WorkflowStatus; steps: StepProgress[]; totalAgentCalls: number; output?: string; }; }