import { useCallback, useEffect, useState } from 'react' import type { TreeNode, WalkSession } from '@/types/l1' import { l1Api } from '@/api/l1' import { WalkModals } from './WalkModals' interface Props { session: WalkSession } /** * L1WalkTreeVariant — renders a decision-tree walk. * * For `ai_build` sessions it drives real, node-by-node generation via * POST /l1/sessions/{id}/next-node: fetch the first node on mount, then on each * answer/acknowledge POST the current node id (+ its text, so the walked path and * captured tree stay legible) and render the returned node. Terminal nodes * (resolved / escalate / needs_review) hand off to the existing Resolve/Escalate * modals. Published `flow` / `proposal` walks keep the Phase-1 stub for now. */ export function L1WalkTreeVariant({ session }: Props) { const isAiBuild = session.session_kind === 'ai_build' const [showResolve, setShowResolve] = useState(false) const [showEscalate, setShowEscalate] = useState(false) const [node, setNode] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) // Fetch the first node on mount (ai_build only). useEffect(() => { if (!isAiBuild) return let cancelled = false setLoading(true) l1Api .nextNode(session.id, {}) .then((r) => { if (!cancelled) setNode(r.node) }) .catch(() => { if (!cancelled) setError('Could not generate the next step.') }) .finally(() => { if (!cancelled) setLoading(false) }) return () => { cancelled = true } }, [isAiBuild, session.id]) const advance = useCallback( async (body: { answer?: 'yes' | 'no'; acknowledged?: boolean }) => { if (!node) return setLoading(true) setError(null) try { const r = await l1Api.nextNode(session.id, { node_id: node.id, node_text: node.text, ...body, }) setNode(r.node) } catch { setError('Could not generate the next step.') } finally { setLoading(false) } }, [node, session.id], ) const isTerminal = node?.node_type === 'resolved' || node?.node_type === 'escalate' || node?.node_type === 'needs_review' return (
{isAiBuild && (
These are high-confidence troubleshooting steps, but they come from outside your organization’s knowledge base — review them before acting. When in doubt, escalate early.
)} {!isAiBuild && (

Walking flow {session.flow_id}

Synthetic step rendering (Phase 1 stub).

)} {isAiBuild && (
{loading && (

Thinking through the next step…

)} {error &&

{error}

} {!loading && node?.node_type === 'question' && ( <>

{node.text}

)} {!loading && node?.node_type === 'instruction' && ( <>

{node.text}

)} {!loading && isTerminal && node && ( <>

{node.text}

{node.node_type === 'resolved' ? ( ) : ( )}
)}
)} {/* Resolve / Escalate are always reachable during a walk. */}
setShowResolve(false)} onCloseEscalate={() => setShowEscalate(false)} />
) }