UI Refactor Assessment — server.py / service.py¶
Date: May 2026 Status: In progress — Phase 1 implemented
1. Current-state inventory¶
| File | Lines | Role |
|---|---|---|
ui/service.py |
compatibility shim | Legacy import surface that re-exports focused modules from ui/services/ |
ui/server.py |
app assembly | FastAPI app, middleware, router mounting, logging |
ui/prefab_dashboard.py |
Prefab UI definition | Client-side dashboard layout and fetch wiring |
ui/services/*.py |
focused services | Session, model, preview, LLM, checkpoint, docs, shared utils |
ui/routers/*.py |
route slices | Route handlers grouped by domain |
2. What works vs what is broken¶
Working ✅¶
- 3D preview — GLB/STL export via Three.js embedded viewer; PNG multi-orientation captures
- Feature tree table — loads from snapshot, component selection highlights in SolidWorks
- Model connect/attach — opens
.sldprt/.sldasmvia COM adapter, inspects feature tree - Session persistence — SQLite via
history_db - Context save/load — JSON snapshots in
.solidworks_mcp/ui_context/ - Engineering notes — free-text persisted in session metadata
- Docs context — HTML scrape of
/docsendpoint filtered by query term
Broken / mocked ❌¶
| Component | Reason |
|---|---|
| Clarification (Refresh Clarifications) | Requires GH_TOKEN / OPENAI_API_KEY with models:read scope; model name routing fragile |
| Family inspect (Inspect More) | Same LLM dependency; also fails if no active model attached |
| GO orchestration | Wraps clarify + inspect; fails if either fails |
| Checkpoint execution (Execute Next) | create_sketch, add_line, create_extrusion partially wired; check_interference MOCKED; others MOCKED |
| Engineering Signals | Confidence badge depends on LLM result; always shows "unknown" |
| Design spec / model settings | Provider selection fragile; local model probe works but model name normalisation has edge cases |
| MCP Bridge | McpError: -32601 Method not found — Prefab renderer sends initialize to an MCP server that is not present in this deployment mode |
| Plan Next Steps | Button triggers unimplemented planning sub-flow |
Mitigations now available (May 2026)¶
- Local inference path is validated with local provider settings (
local:*model names) and Ollama endpoint routing. - Preview refresh now enforces successful target-model reopen before image export, preventing captures from the wrong active SolidWorks document.
- Adapter export resolution now prefers the tracked
currentModelunlessActiveDocmatches the same file, which fixes wrong-window preview/export captures when SolidWorks focus drifts. - Tested operator runbook for the U-Joint sample bracket workflow:
docs/getting-started/prefab-ui-u-joint-bracket-runbook.md
Live verification notes (May 4, 2026)¶
- The default dashboard now hides
Plan Next Stepsand the clarification/acceptance action card unlessSOLIDWORKS_UI_EXPERIMENTAL_ORCHESTRATION=1is set. - The Prefab renderer still logs
McpError: -32601 Method not foundon page load, confirming the MCP bridge remains unresolved even though Fetch-based routes work.
3. Is FastAPI the right backend?¶
Yes. The Prefab UI uses Fetch.get/post to call HTTP endpoints — it needs a REST server.
FastAPI is appropriate: async, type-annotated, OpenAPI docs out of the box, and already integrated.
Rejected alternatives:
- Streamlit — server-side re-render model does not fit the client-reactive Prefab component tree; no embedded 3D viewer support
- Gradio — similar limitations; geared toward ML model demos
- FastMCP native Prefab tools — correct long-term direction for a full MCP client, but requires a working MCP client bridge (see broken MCP Bridge above); the FastAPI layer remains necessary until the bridge is fixed
4. FastMCP Prefab / Generative UI findings¶
From https://gofastmcp.com/apps/prefab and https://gofastmcp.com/apps/generative:
- Prefab components (
Column,Row,Fetch,If, etc.) are the current approach and already in use — no migration needed GenerativeUI(FastMCP ≥ 3.2.0) lets the LLM write Prefab Python code at runtime inside a Pyodide sandbox — useful for dynamic report panels but not for the CAD-control flow that requires real adapter calls- The MCP Bridge error (
-32601 Method not found) occurs because the Prefab renderer tries to calltools/list/initializeon a connected MCP server, but the current deployment has no MCP server wired into the Prefab host. This is non-fatal (the Fetch-based API calls still work) but should be resolved by either mounting the MCP server at the same host origin or disabling bridge mode in the Prefab config
5. SOLID violations in the current code¶
Single Responsibility (remaining offender)¶
The old service.py monolith has been split, but the service layer as a whole still handles:
- Session CRUD and state serialisation
- LLM prompting and structured agent execution
- Adapter orchestration (open model, feature tree, preview export)
- RAG ingestion and docs scraping
- Checkpoint plan execution
- Context snapshot save/load
Open/Closed¶
- Tool routing in
_run_checkpoint_toolsis a giantif/elifchain — adding a new tool requires modifying the function - Model name normalisation is a chain of
if model_name.startswith(...)checks
Dependency Inversion¶
- Service functions directly call
create_adapter(load_config())— the adapter is not injected, making unit tests require mocking at import-time _build_agent_modelcreates pydantic-ai model objects inline — no abstraction layer
6. Target architecture¶
ui/
server.py # Thin FastAPI app assembly: middleware, mount routers (~100 lines)
service.py # Backwards-compat re-export shim (import from services/)
prefab_dashboard.py # UI with broken sections commented out
schemas.py # DashboardUIState, DashboardCheckpoint, etc. (unchanged)
local_llm.py # Ollama probe/pull/query (unchanged for now)
services/
__init__.py # Public re-exports (all names that server.py currently imports)
_utils.py # Shared utilities: _sanitize_*, _parse_json_blob,
# _merge_metadata, _persist_ui_action, _trace_*
session_service.py # Session CRUD, state assembly (build_dashboard_state)
model_service.py # connect_target_model, open_target_model
preview_service.py # refresh_preview, highlight_feature
llm_service.py # request_clarifications, inspect_family, run_go_orchestration
checkpoint_service.py # execute_next_checkpoint, _run_checkpoint_tools
docs_service.py # fetch_docs_context, ingest_reference_source
routers/
__init__.py
session.py # GET /api/ui/state, POST /api/ui/brief/approve, etc.
model.py # POST /api/ui/model/connect, /model/open
preview.py # POST /api/ui/preview/refresh, /feature/select, /manual-sync/reconcile
llm.py # POST /api/ui/clarify, /family/inspect, /family/accept, /orchestrate/go
checkpoint.py # POST /api/ui/checkpoints/execute-next
docs.py # POST /api/ui/docs/context, /rag/ingest
local_model.py # GET/POST /api/ui/local-model/*
viewer.py # GET /api/ui/viewer/{session_id}
context.py # POST /api/ui/context/save, /context/load, /notes/update
7. Broken UI sections to comment out (Phase 1)¶
Status update (May 2026): these controls are now gated behind
SOLIDWORKS_UI_EXPERIMENTAL_ORCHESTRATION=1 in prefab_dashboard.py.
Default behavior keeps them hidden so the primary attach/preview/feature workflows stay stable.
Comment out in prefab_dashboard.py — these sections call LLM endpoints that reliably
fail without credentials, obscure working sections, and confuse users:
| Section | Reason to disable |
|---|---|
| Clarification & Engineering Review column (column 2 of 3-column layout) | LLM-dependent; always shows errors |
| GO button + GO status bar | Wraps LLM calls; fails when clarify/inspect fail |
| Checkpoint Plan + Execute Next (model output column) | Mostly MOCKED; checkpoint execution not reliable |
| Engineering Signals badges | Confidence always "unknown" without successful LLM |
| Plan Next Steps button | Calls unimplemented planning sub-flow |
Keep active (working):
- Workflow selector (Edit Existing / New Design / Attach Local Path)
- Model path input + Attach button
- 3D Preview (multi-view images + Three.js viewer)
- Feature tree table + feature select
- Session notes
- Docs context
- Operator Trace (read-only)
- Context save/load
8. Implementation phases¶
| Phase | Scope | Risk |
|---|---|---|
| 1 (done) | Create services/ + routers/, slim server.py, comment out broken UI |
Low — backwards compat shim in service.py |
| 2 | Fix MCP Bridge: mount FastMCP server at same origin or configure Prefab host to not bridge | Medium |
| 3 | Wire real LLM flows with proper credential UX (env var checklist, error toasts with actionable messages) | Medium |
| 4 | Wire checkpoint execution properly: replace if/elif chain with a strategy registry |
Low |
| 5 | Replace on_event("startup") (deprecated) with FastAPI lifespan context manager |
Low |