# PhysiX-Live frontend React + TypeScript + Tailwind UI for the PhysiX-Live demo. Two tabs: - **Run with LLM** — drives a live episode via `POST /interactive/sessions/:id/llm-step`. Server calls a local Ollama daemon, parses the reply, scores it, returns the turn. The UI streams turn cards as they arrive. - **Manual** — `/interactive/sessions/:id/step`: you submit equations yourself. ## Stack - React 18 with strict TypeScript (`exactOptionalPropertyTypes: true`). - Tailwind CSS 3 (warm dark palette, custom tokens in `tailwind.config.js`). - Vite 5 dev server / bundler. - KaTeX for live equation rendering. - Plain HTML5 canvas for trajectory plots — no chart library. ## Layout ``` src/ ├── App.tsx # tab switch ├── main.tsx # ReactDOM root ├── components/ │ ├── HeroIntro.tsx # 3-step "Observe / Hypothesise / Verify" │ ├── RunWithLlmPane.tsx # LLM-driven episode + turn-by-turn stream │ ├── InteractivePane.tsx # manual equation submission │ ├── EquationInput.tsx # textarea + KaTeX preview + starter chips │ ├── EquationDisplay.tsx # KaTeX render of one equation │ ├── TrajectoryCanvas.tsx # observed (cyan) + predicted (coral) │ ├── RewardGauge.tsx # 4-bar breakdown with tooltips │ └── Skeleton.tsx # loading shimmer ├── hooks/ │ ├── useInteractiveSession.ts # manual-mode session lifecycle │ └── useLlmEpisodeRunner.ts # LLM run / pause / step-once orchestration ├── lib/ │ ├── interactiveClient.ts # typed fetch over /interactive/* │ ├── trajectory.ts # canvas projection helpers │ ├── format.ts # SymPy -> KaTeX │ └── cn.ts # classnames joiner └── types/physix.ts # mirrors the Pydantic wire schema ``` ## Scripts ```bash pnpm install # install deps pnpm dev # vite dev server on http://localhost:5173 pnpm typecheck # strict tsc --noEmit pnpm build # production build into dist/ pnpm preview # serve the production build locally ``` The UI expects `VITE_PHYSIX_API_URL` (default `http://localhost:8000`) to point at a running env server (`python -m physix.server.app`). For the LLM tab you also need `ollama serve` and the model tag pulled.