import { StringEnum } from "@mariozechner/pi-ai"; import { Type, type Static } from "@sinclair/typebox"; function createTaskModelSchema(availableModels: readonly string[]) { return Type.Optional( StringEnum(availableModels, { description: "Optional child model override. Must be one of the currently available models.", }), ); } export function createTaskItemSchema(availableModels: readonly string[]) { return Type.Object({ preset: Type.String({ description: "Subagent preset name to use for this task" }), task: Type.String({ description: "Task to delegate to the child agent" }), model: createTaskModelSchema(availableModels), cwd: Type.Optional(Type.String({ description: "Optional working directory override" })), }); } export const TaskItemSchema = createTaskItemSchema([]); export function createSubagentParamsSchema(availableModels: readonly string[]) { // Single-mode schema: requires preset + task, exposes optional top-level model const SingleMode = Type.Object({ preset: Type.String({ description: "Subagent preset name to use in single mode" }), task: Type.String({ description: "Single-mode delegated task" }), model: createTaskModelSchema(availableModels), cwd: Type.Optional(Type.String({ description: "Single-mode working directory override" })), }); // Parallel-mode schema: requires tasks array where each item contains its own preset and task const ParallelMode = Type.Object({ tasks: Type.Array(createTaskItemSchema(availableModels), { description: "Parallel tasks" }), }); return Type.Union([SingleMode, ParallelMode], { description: "Either single-mode (preset+task) or parallel-mode (tasks array)" }); } export const SubagentParamsSchema = createSubagentParamsSchema([]); export type TaskItem = Static; export type SubagentParams = Static; export interface SubagentRunResult { runId: string; task: string; requestedModel?: string; resolvedModel?: string; paneId?: string; windowId?: string; sessionPath?: string; exitCode: number; stopReason?: string; finalText: string; stdoutPath?: string; stderrPath?: string; transcriptPath?: string; resultPath?: string; eventsPath?: string; errorMessage?: string; } export interface SubagentToolDetails { mode: "single" | "parallel"; results: SubagentRunResult[]; }