import { findScenarioOutcome, statusDotClass } from "./ui-render-scenario.js"; import { badgeHtml, esc, formatIso } from "./ui-render-utils.js"; import type { RunnerModelOption, RunnerSelection, TabId, UiState } from "./ui-types.js"; const MOCK_MODELS: RunnerModelOption[] = [ { key: "mock-openai/gpt-5.6-luna", name: "GPT-5.6 Luna (mock)", provider: "mock-openai", input: "text", preferred: true, }, { key: "mock-openai/gpt-5.6-luna-alt", name: "GPT-5.6 Luna Alt (mock)", provider: "mock-openai", input: "text", preferred: false, }, ]; function deriveSelection(state: UiState): RunnerSelection | null { return state.runnerDraft ?? state.bootstrap?.runner.selection ?? null; } /* ===== Render: Header ===== */ export function renderHeader(state: UiState): string { const runner = state.bootstrap?.runner ?? null; const run = state.scenarioRun; const controlUrl = state.bootstrap?.controlUiUrl; return `
QA Lab
${runner ? badgeHtml(runner.status) : ""} ${run ? `${run.counts.passed}/${run.counts.total} pass` : ""} ${state.error ? `${esc(state.error)}` : ""}
${controlUrl ? `Control UI` : ""}
`; } /* ===== Render: Sidebar ===== */ function renderModelSelect(params: { id: string; label: string; value: string; options: RunnerModelOption[]; disabled: boolean; }): string { const values = new Set(params.options.map((o) => o.key)); const options = [...params.options]; if (!values.has(params.value) && params.value.trim()) { options.unshift({ key: params.value, name: params.value, provider: params.value.split("/")[0] ?? "custom", input: "text", preferred: false, }); } return `
${esc(params.label)}
`; } export function renderSidebar(state: UiState): string { const scenarios = state.bootstrap?.scenarios ?? []; const selection = deriveSelection(state); const runner = state.bootstrap?.runner ?? null; const run = state.scenarioRun; const isRunning = runner?.status === "running"; const realModels = state.bootstrap?.runnerCatalog.real ?? []; const modelOptions = selection?.providerMode === "live-frontier" && realModels.length > 0 ? realModels : MOCK_MODELS; const plan = state.runnerPlanOverride ?? state.bootstrap?.runner.plan ?? null; const resolvedIds = plan?.selectedScenarios.map((scenario) => scenario.id) ?? []; const selectedIds = new Set( selection?.scenarioIds ?? (state.runnerDraftDirty ? [] : resolvedIds), ); const profiles = state.bootstrap?.runnerCatalog.profiles ?? []; const channels = state.bootstrap?.runnerCatalog.channels ?? []; const hasRunnableSelection = selection?.scenarioIds === null ? Boolean(selection.profile) : Boolean(selection?.scenarioIds.length); return ` `; } function renderRunStatus(state: UiState): string { const run = state.scenarioRun; const runner = state.bootstrap?.runner ?? null; const plan = state.runnerPlanOverride ?? (state.runnerDraftDirty ? null : (runner?.plan ?? null)); if (!run && !runner) { return ""; } return ` `; } /* ===== Render: Tab bar ===== */ export function renderTabBar(state: UiState): string { const tabs: Array<{ id: TabId; label: string }> = [ { id: "chat", label: "Chat" }, { id: "results", label: "Results" }, { id: "evidence", label: "Evidence Archive" }, { id: "report", label: "Report" }, { id: "events", label: "Events" }, { id: "capture", label: "Capture" }, ]; return ` `; } /* ===== Render: Chat tab ===== */