Backend
- /sessions POST opens a long-lived ClaudeSDKClient kept in an
in-process dict; /sessions/{id}/query streams turns against it.
Per-session asyncio.Lock serializes concurrent calls. Idle TTL
10 min, 32-session cap with LRU eviction. Reaper task.
- /query (single-shot) is kept for the demo card path and as a
fallback for non-chat consumers.
Frontend
- store.ts: messages[] + sessionId; sendMessage() appends a user
bubble + streaming agent bubble and pipes SSE into it. Tool calls
continue to drive the canvas via predictFieldsInline. Per-turn
agentFields reset on sendMessage so one turn doesn't ghost-show
another turn's fields.
- ChatThread.tsx: Claude-chat style bubbles — user (serif, accent
soft) vs agent (bordered card with tool chips + final answer).
Auto-scrolls on new messages. "new chat" closes the session.
- QueryInput.tsx: single composer used for first-turn and
follow-ups. Enter sends, Shift+Enter newlines. Label flips…
fix(agent): use claude-opus-4-7 to match hackathon + repo-wide config
Ubuntu+1: Claude Opus 4.7
72309a5
The runtime DEFAULT_MODEL was still pinned to opus-4-6 while every
subagent frontmatter, .claude/settings.json, and JOURNAL/AGENTS docs
use opus-4-7. The API-backed /query path was silently on the weaker
model. Align with the hackathon thesis ("Built with Opus 4.7").
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Day-2 afternoon: field heatmaps, Dockerfile, README
Ubuntu+1: Claude Opus 4.7
3e3d78c
- POST /predict returns solver+surrogate T/P arrays for a scenario
- FieldPanel renders both engines side-by-side via canvas magma cmap
(shared tMin/tMax so disagreement is visible; Δ Tmax chip)
- Dashboard bundle stays at 160 kB JS / 3.5 kB CSS (no plotly)
- Multi-stage Dockerfile: node build → python runtime (CPU-only torch),
FastAPI auto-mounts dashboard/dist when present
- Root README with thesis, architecture diagram, install paths,
honest scope/limitations
- Dry-run of all 3 scenarios recorded in JOURNAL (flagged q1/q3
solver pressure/temperature anomalies for reviewer pre-demo)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- demo/scenarios.yaml: Q1 (drill T), Q2 (sustainable MW / 20 yr, with UQ
distributions), Q3 (well placement, with OAT sensitivity knob).
- tools/monte_carlo.py: ensemble wrapper with uniform/normal/lognormal/
triangular sampling; returns P10/P50/P90 temperature + pressure fields
plus per-draw scalar summaries. Default engine = surrogate (30 samples
in ~0.1 s).
- tools/sensitivity.py: OAT parameter sweep with probe_temperature_C and
reservoir-mean metrics; returns per-parameter curves + |delta| ranking.
- agent/runtime.py: two new MCP tools (monte_carlo, sensitivity_oat)
registered with the SDK MCP server; system prompt updated to describe
all four tools.
- agent/api.py: FastAPI app with /health, /scenarios, and SSE /query
streaming AssistantMessage text + ToolUseBlock events to the UI.
- app/app.py: Streamlit fallback (<200 lines) with sidebar scenario
picker, solver/surrogate side-by-side heatmaps, and an agent-trace
panel backed by ClaudeSDKClient.
All 13 tests s…
Day-1 evening milestone: both engines live, agent answers Q1
Ubuntu+1: Claude Opus 4.6
97f04e4
- tools/predict_solver.py: unified (scenario) -> {T, P, grid, engine} wrapper
around solver.coupled.run_coupled_transient
- tools/predict_surrogate.py: matching schema wrapper around v1.1 CNN surrogate
(handles well-index rescaling from arbitrary grid -> 32x32)
- agent/runtime.py: claude-agent-sdk runtime, in-process SDK MCP server
exposing both tools to claude-opus-4-6. CLI entry point answers
natural-language geothermal questions end-to-end.
Q1 verified: "drill at x=200m, y=100m after 1 yr of 0.5 kg/s reinjection" ->
agent correctly maps coords, calls predict_solver, reports T ~ 123 C, P ~ 15.0 MPa.
Spot-check against direct solver call matches.
Day-1-evening GO/NO-GO: solver GO (Theis 0.38% err, conduction 0.18% err).
13/13 tests green.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>