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 `
`;
}
/* ===== 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 ===== */