panelController.measure(w)}
id="flow-editor"
class={'relative h-full overflow-hidden transition-colors duration-[400ms] ease-linear border-t'}
use:triggerableByAI={{
id: 'flow-editor',
description: 'Component to edit a flow'
}}
>
{#if graphOverlay}
{@render graphOverlay()}
{/if}
{#if loading}
{#each new Array(6) as _}
{/each}
{:else if flowStore.val.value.modules}
{
// The step is already inserted; the prompt describes what it should
// contain. Hand it to a session opened on that step rather than the
// docked chat, which sessions leave unmounted. Sent on arrival: the
// user already said what they wanted in the description field.
if (
!sessionScopedManager &&
sessionOpen &&
prefersSessionHandoff(actingUser?.operator)
) {
void openSourceInSession(sessionOpen, {
previewParams: { selected: detail.moduleId },
seedPrompt: stepInstructionsPrompt(detail.moduleId, detail.instructions),
autoSend: true
})
return
}
// Already in a session: its chat is on screen, so ask it directly.
// Not `generateStep` — that forces the request into SCRIPT mode, and
// changeMode is persistent, so it would strand the session outside
// GLOBAL. Global mode writes step code through set_flow_module_code.
if (sessionScopedManager) {
sessionScopedManager.sendOrQueue(
stepInstructionsPrompt(detail.moduleId, detail.instructions)
)
return
}
if (!aiChatManager.open) {
aiChatManager.openChat()
}
aiChatManager.generateStep(detail.moduleId, detail.lang, detail.instructions)
}}
{onTestUpTo}
{onEditInput}
{localModuleStates}
{testModuleStates}
{aiChatOpen}
{showFlowAiButton}
{toggleAiChat}
{sessionOpen}
{isOwner}
{onTestFlow}
{isRunning}
{onCancelTestFlow}
{onOpenPreview}
{onHideJobStatus}
{individualStepTests}
flowJob={job}
{suspendStatus}
{onDelete}
{flowHasChanged}
/>
{/if}