import { useState } from 'react' // Collapsible "view / edit the exact prompt before it runs" panel. // // `value` is the current prompt text (null = use the backend default). // `fetchPrompt` is an async () => string that assembles the default prompt // (some steps fetch live data to build it, so it may take a moment). // When the user edits the box, value diverges from the default — the run // button sends `value`; if the panel was never opened, value stays null and // the backend assembles the default itself. export default function PromptPanel({ fetchPrompt, value, setValue, disabled, label = 'prompt', open: openProp, setOpen: setOpenProp }) { const [openState, setOpenState] = useState(false) // Controlled when the parent passes open/setOpen (e.g. to auto-reveal prompts // after a bulk generate); otherwise self-managed. const controlled = openProp !== undefined const open = controlled ? openProp : openState const setOpen = controlled ? setOpenProp : setOpenState const [loading, setLoading] = useState(false) const [error, setError] = useState('') const [original, setOriginal] = useState(null) const load = async () => { setLoading(true) setError('') try { const p = await fetchPrompt() setValue(p) setOriginal(p) } catch (e) { setError(e.message) } finally { setLoading(false) } } const toggle = async () => { if (!open && value == null) await load() setOpen(!open) } const edited = value != null && original != null && value !== original return (
{open && (

This is the exact text sent to the model. Edit it to QC the output, then run. Your edits are used as-is.

{loading ? (

Assembling prompt…

) : error ? (
{error}
) : (