docs: Major documentation overhaul - restructure folders, update tagline, add Getting Started guide
- Restructure docs/ folder (remove numeric prefixes): - 04_USER_GUIDES -> guides/ - 05_API_REFERENCE -> api/ - 06_PHYSICS -> physics/ - 07_DEVELOPMENT -> development/ - 08_ARCHIVE -> archive/ - 09_DIAGRAMS -> diagrams/ - Replace tagline 'Talk, don't click' with 'LLM-driven optimization framework' in 9 files - Create comprehensive docs/GETTING_STARTED.md: - Prerequisites and quick setup - Project structure overview - First study tutorial (Claude or manual) - Dashboard usage guide - Neural acceleration introduction - Rewrite docs/00_INDEX.md with correct paths and modern structure - Archive obsolete files: - 01_PROTOCOLS.md -> archive/historical/01_PROTOCOLS_legacy.md - 03_GETTING_STARTED.md -> archive/historical/ - ATOMIZER_PODCAST_BRIEFING.md -> archive/marketing/ - Update timestamps to 2026-01-20 across all key files - Update .gitignore to exclude docs/generated/ - Version bump: ATOMIZER_CONTEXT v1.8 -> v2.0
This commit is contained in:
730
docs/reviews/ARCHITECTURE_REVIEW.md
Normal file
730
docs/reviews/ARCHITECTURE_REVIEW.md
Normal file
@@ -0,0 +1,730 @@
|
||||
# Atomizer Architecture Review
|
||||
|
||||
**Date**: January 2026
|
||||
**Version**: 2.0 (AtomizerSpec unified configuration)
|
||||
**Author**: Architecture Review
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Atomizer is a structural optimization platform that enables engineers to optimize FEA (Finite Element Analysis) designs through a visual canvas interface and AI-powered assistance. The architecture follows a **single source of truth** pattern where all configuration flows through `atomizer_spec.json`.
|
||||
|
||||
### Key Strengths
|
||||
- **Unified Configuration**: One JSON file defines the entire optimization study
|
||||
- **Type Safety**: Pydantic validation at every modification point
|
||||
- **Real-time Collaboration**: WebSocket-based sync between all clients
|
||||
- **Responsive UI**: Optimistic updates with background synchronization
|
||||
- **AI Integration**: Claude can modify configurations in Power Mode
|
||||
|
||||
### Architecture Quality Score: **8.5/10**
|
||||
|
||||
| Aspect | Score | Notes |
|
||||
|--------|-------|-------|
|
||||
| Data Integrity | 9/10 | Single source of truth, hash-based conflict detection |
|
||||
| Type Safety | 9/10 | Pydantic models throughout backend |
|
||||
| Extensibility | 8/10 | Custom extractors, algorithms supported |
|
||||
| Performance | 8/10 | Optimistic updates, WebSocket streaming |
|
||||
| Maintainability | 8/10 | Clear separation of concerns |
|
||||
| Documentation | 7/10 | Good inline docs, needs more high-level guides |
|
||||
|
||||
---
|
||||
|
||||
## 1. Configuration Layer
|
||||
|
||||
### 1.1 AtomizerSpec v2.0 - The Single Source of Truth
|
||||
|
||||
**Location**: `studies/{study_name}/atomizer_spec.json`
|
||||
|
||||
The AtomizerSpec is the heart of Atomizer's configuration. Every component reads from and writes to this single file.
|
||||
|
||||
```
|
||||
atomizer_spec.json
|
||||
├── meta # Study metadata
|
||||
│ ├── version: "2.0"
|
||||
│ ├── study_name
|
||||
│ ├── created_by # canvas | claude | api | migration
|
||||
│ └── modified_at
|
||||
├── model # NX model files
|
||||
│ ├── sim: { path, solver }
|
||||
│ ├── nx_part: { path }
|
||||
│ └── fem: { path }
|
||||
├── design_variables[] # Parameters to optimize
|
||||
│ ├── id: "dv_001"
|
||||
│ ├── name, expression_name
|
||||
│ ├── type: continuous | discrete
|
||||
│ ├── bounds: { min, max }
|
||||
│ └── canvas_position
|
||||
├── extractors[] # Physics result extractors
|
||||
│ ├── id: "ext_001"
|
||||
│ ├── type: mass | displacement | stress | zernike | custom
|
||||
│ ├── config: {}
|
||||
│ └── outputs: [{ name, metric }]
|
||||
├── objectives[] # Optimization goals
|
||||
│ ├── id: "obj_001"
|
||||
│ ├── direction: minimize | maximize
|
||||
│ ├── weight
|
||||
│ └── source: { extractor_id, output_key }
|
||||
├── constraints[] # Hard/soft constraints
|
||||
│ ├── id: "con_001"
|
||||
│ ├── operator: <= | >= | ==
|
||||
│ ├── threshold
|
||||
│ └── source: { extractor_id, output_key }
|
||||
├── optimization # Algorithm settings
|
||||
│ ├── algorithm: { type, config }
|
||||
│ ├── budget: { max_trials }
|
||||
│ └── surrogate: { enabled, type }
|
||||
└── canvas # UI layout state
|
||||
└── edges[]
|
||||
```
|
||||
|
||||
### 1.2 Node ID Convention
|
||||
|
||||
All configurable elements use unique IDs with prefixes:
|
||||
|
||||
| Prefix | Element Type | Example |
|
||||
|--------|--------------|---------|
|
||||
| `dv_` | Design Variable | `dv_001`, `dv_002` |
|
||||
| `ext_` | Extractor | `ext_001`, `ext_002` |
|
||||
| `obj_` | Objective | `obj_001`, `obj_002` |
|
||||
| `con_` | Constraint | `con_001`, `con_002` |
|
||||
|
||||
IDs are auto-generated: `{prefix}{max_existing + 1:03d}`
|
||||
|
||||
### 1.3 Legacy Configuration
|
||||
|
||||
**File**: `optimization_config.json` (deprecated)
|
||||
|
||||
Legacy studies may have this file. The `SpecMigrator` automatically converts them to AtomizerSpec v2.0 on load.
|
||||
|
||||
```python
|
||||
from optimization_engine.config.migrator import SpecMigrator
|
||||
migrator = SpecMigrator(study_dir)
|
||||
spec = migrator.migrate_file(legacy_path, spec_path)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Frontend Architecture
|
||||
|
||||
### 2.1 Technology Stack
|
||||
|
||||
| Layer | Technology | Purpose |
|
||||
|-------|------------|---------|
|
||||
| Build | Vite + TypeScript | Fast bundling, type safety |
|
||||
| UI | React 18 + TailwindCSS | Component framework |
|
||||
| State | Zustand | Lightweight global state |
|
||||
| Canvas | ReactFlow | Graph visualization |
|
||||
| Communication | Fetch + WebSocket | API + real-time sync |
|
||||
|
||||
### 2.2 Directory Structure
|
||||
|
||||
```
|
||||
atomizer-dashboard/frontend/src/
|
||||
├── components/
|
||||
│ ├── canvas/ # Canvas components
|
||||
│ │ ├── AtomizerCanvas # Main wrapper
|
||||
│ │ ├── SpecRenderer # Spec → ReactFlow
|
||||
│ │ ├── nodes/ # Node type components
|
||||
│ │ └── panels/ # Side panels
|
||||
│ └── chat/ # Claude chat UI
|
||||
├── hooks/
|
||||
│ ├── useSpecStore.ts # Central state (Zustand)
|
||||
│ ├── useChat.ts # Claude integration
|
||||
│ ├── useCanvasStore.ts # Local canvas state
|
||||
│ └── useSpecWebSocket.ts # Real-time sync
|
||||
├── lib/
|
||||
│ └── spec/converter.ts # Spec ↔ ReactFlow
|
||||
├── types/
|
||||
│ └── atomizer-spec.ts # TypeScript definitions
|
||||
└── pages/
|
||||
├── CanvasView.tsx # Main canvas page
|
||||
├── Home.tsx # Study selection
|
||||
└── Setup.tsx # Study wizard
|
||||
```
|
||||
|
||||
### 2.3 State Management Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ useSpecStore (Zustand) │
|
||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌───────────────┐ │
|
||||
│ │ spec │ │ hash │ │ isDirty │ │ selectedNode │ │
|
||||
│ └────┬────┘ └────┬────┘ └────┬────┘ └───────┬───────┘ │
|
||||
└───────┼────────────┼────────────┼───────────────┼──────────┘
|
||||
│ │ │ │
|
||||
▼ ▼ ▼ ▼
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐
|
||||
│Canvas │ │Conflict │ │ Save │ │ NodeConfig │
|
||||
│ Render │ │Detection│ │ Button │ │ Panel │
|
||||
└─────────┘ └─────────┘ └─────────┘ └─────────────┘
|
||||
```
|
||||
|
||||
**Key Actions**:
|
||||
- `loadSpec(studyId)` - Fetch spec from backend
|
||||
- `patchSpec(path, value)` - Update with conflict check
|
||||
- `patchSpecOptimistic(path, value)` - Fire-and-forget update
|
||||
- `addNode(type, data)` - Add design var/extractor/etc.
|
||||
- `removeNode(nodeId)` - Delete with edge cleanup
|
||||
|
||||
### 2.4 Canvas Rendering Pipeline
|
||||
|
||||
```
|
||||
AtomizerSpec JSON
|
||||
│
|
||||
▼
|
||||
specToNodes() [converter.ts]
|
||||
│
|
||||
├──► Model Node (synthetic)
|
||||
├──► Solver Node (synthetic)
|
||||
├──► DesignVar Nodes × N
|
||||
├──► Extractor Nodes × N
|
||||
├──► Objective Nodes × N
|
||||
├──► Constraint Nodes × N
|
||||
├──► Algorithm Node (synthetic)
|
||||
└──► Surrogate Node (optional)
|
||||
│
|
||||
▼
|
||||
ReactFlow Component
|
||||
│
|
||||
▼
|
||||
Interactive Canvas
|
||||
```
|
||||
|
||||
**Layout Constants**:
|
||||
```
|
||||
Design Variables: x = 50
|
||||
Model: x = 280
|
||||
Solver: x = 510
|
||||
Extractors: x = 740
|
||||
Objectives: x = 1020
|
||||
Constraints: x = 1020 (offset y)
|
||||
Algorithm: x = 1300
|
||||
Surrogate: x = 1530
|
||||
Row Height: 100px
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Backend Architecture
|
||||
|
||||
### 3.1 Technology Stack
|
||||
|
||||
| Layer | Technology | Purpose |
|
||||
|-------|------------|---------|
|
||||
| Framework | FastAPI | Async REST + WebSocket |
|
||||
| Validation | Pydantic | Schema enforcement |
|
||||
| Database | SQLite | Trial storage (Optuna schema) |
|
||||
| LLM | Anthropic Claude | AI assistance |
|
||||
|
||||
### 3.2 Directory Structure
|
||||
|
||||
```
|
||||
atomizer-dashboard/backend/api/
|
||||
├── main.py # FastAPI app
|
||||
├── routes/
|
||||
│ ├── spec.py # Spec CRUD + WebSocket
|
||||
│ ├── optimization.py # Run management
|
||||
│ ├── claude.py # Chat sessions
|
||||
│ └── files.py # File operations
|
||||
└── services/
|
||||
├── spec_manager.py # Central spec management
|
||||
├── claude_agent.py # Claude with tools
|
||||
├── context_builder.py # System prompts
|
||||
└── session_manager.py # WebSocket sessions
|
||||
```
|
||||
|
||||
### 3.3 SpecManager Service
|
||||
|
||||
**The SpecManager is the gatekeeper for all spec modifications.**
|
||||
|
||||
```python
|
||||
class SpecManager:
|
||||
def __init__(self, study_path: Path):
|
||||
self.study_path = study_path
|
||||
self.spec_file = study_path / "atomizer_spec.json"
|
||||
self.subscribers: List[WebSocket] = []
|
||||
|
||||
# Loading
|
||||
def load_spec(self) -> AtomizerSpec
|
||||
def load_raw(self) -> dict
|
||||
|
||||
# Validation
|
||||
def validate(self, spec) -> ValidationReport
|
||||
def validate_semantic(self, spec) -> ValidationReport
|
||||
|
||||
# Modifications
|
||||
def patch_spec(self, path, value) -> dict
|
||||
def add_node(self, type, data) -> str
|
||||
def update_node(self, id, updates) -> None
|
||||
def remove_node(self, id) -> None
|
||||
|
||||
# Persistence
|
||||
def save_spec(self, spec) -> dict # Atomic write + hash
|
||||
def compute_hash(self, spec) -> str
|
||||
|
||||
# Real-time sync
|
||||
def subscribe(self, ws: WebSocket)
|
||||
def broadcast(self, message: dict)
|
||||
```
|
||||
|
||||
**Modification Flow**:
|
||||
1. Load current spec
|
||||
2. Apply modification
|
||||
3. Validate with Pydantic
|
||||
4. Atomic write to disk
|
||||
5. Compute new hash
|
||||
6. Broadcast to all WebSocket subscribers
|
||||
7. Return hash + timestamp
|
||||
|
||||
### 3.4 REST API Endpoints
|
||||
|
||||
| Method | Endpoint | Purpose |
|
||||
|--------|----------|---------|
|
||||
| GET | `/api/studies/{id}/spec` | Load full spec |
|
||||
| GET | `/api/studies/{id}/spec/hash` | Get current hash |
|
||||
| PUT | `/api/studies/{id}/spec` | Replace entire spec |
|
||||
| PATCH | `/api/studies/{id}/spec` | JSONPath patch |
|
||||
| POST | `/api/studies/{id}/spec/nodes` | Add node |
|
||||
| PATCH | `/api/studies/{id}/spec/nodes/{nid}` | Update node |
|
||||
| DELETE | `/api/studies/{id}/spec/nodes/{nid}` | Remove node |
|
||||
| POST | `/api/studies/{id}/spec/validate` | Validate spec |
|
||||
| WS | `/api/studies/{id}/spec/sync` | Real-time sync |
|
||||
|
||||
### 3.5 Conflict Detection
|
||||
|
||||
Uses SHA256 hash of spec content:
|
||||
|
||||
```
|
||||
Client A loads spec (hash: abc123)
|
||||
Client B loads spec (hash: abc123)
|
||||
|
||||
Client A modifies → sends with hash abc123
|
||||
Server: hash matches → apply → new hash: def456
|
||||
Server: broadcast to all clients
|
||||
|
||||
Client B modifies → sends with hash abc123
|
||||
Server: hash mismatch (expected def456)
|
||||
Server: return 409 Conflict
|
||||
Client B: reload latest spec
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Optimization Engine
|
||||
|
||||
### 4.1 Directory Structure
|
||||
|
||||
```
|
||||
optimization_engine/
|
||||
├── config/ # Configuration management
|
||||
│ ├── spec_models.py # Pydantic models
|
||||
│ ├── spec_validator.py # Semantic validation
|
||||
│ └── migrator.py # Legacy migration
|
||||
├── extractors/ # Physics extractors
|
||||
│ ├── extract_displacement.py
|
||||
│ ├── extract_stress.py
|
||||
│ ├── extract_mass_*.py
|
||||
│ ├── extract_zernike*.py
|
||||
│ └── custom_extractor_loader.py
|
||||
├── core/ # Optimization algorithms
|
||||
│ ├── runner.py # Main loop
|
||||
│ ├── method_selector.py # Algorithm selection
|
||||
│ └── intelligent_optimizer.py # IMSO
|
||||
├── nx/ # NX integration
|
||||
│ ├── solver.py # Nastran execution
|
||||
│ └── updater.py # Parameter updates
|
||||
├── study/ # Study management
|
||||
│ ├── creator.py
|
||||
│ └── state.py
|
||||
└── utils/
|
||||
├── dashboard_db.py # Optuna schema
|
||||
└── trial_manager.py # Trial CRUD
|
||||
```
|
||||
|
||||
### 4.2 Extractor Library
|
||||
|
||||
| ID | Type | Function | Inputs |
|
||||
|----|------|----------|--------|
|
||||
| E1 | Displacement | Max/RMS displacement | OP2, subcase |
|
||||
| E2 | Frequency | Eigenvalue | OP2, mode |
|
||||
| E3 | Stress | Von Mises, principal | OP2, element set |
|
||||
| E4 | Mass (BDF) | Total mass | BDF file |
|
||||
| E5 | Mass (Expr) | NX expression | NX session |
|
||||
| E8-10 | Zernike | OPD polynomial fit | OP2, grid config |
|
||||
|
||||
**Custom Extractor Pattern**:
|
||||
```python
|
||||
def extract_volume(op2_path: str) -> Dict[str, float]:
|
||||
from pyNastran.op2.op2 import OP2
|
||||
op2 = OP2()
|
||||
op2.read_op2(op2_path)
|
||||
# ... calculation
|
||||
return {"volume_mm3": calculated_volume}
|
||||
```
|
||||
|
||||
### 4.3 Trial Storage
|
||||
|
||||
**Folder Structure**:
|
||||
```
|
||||
studies/{study}/2_iterations/
|
||||
├── trial_0001/
|
||||
│ ├── params.json # Input parameters
|
||||
│ ├── results.json # Objectives/constraints
|
||||
│ ├── _meta.json # Metadata
|
||||
│ └── *.op2, *.fem # FEA outputs
|
||||
├── trial_0002/
|
||||
└── ...
|
||||
```
|
||||
|
||||
**Database Schema** (Optuna-compatible SQLite):
|
||||
```sql
|
||||
trials (trial_id, study_id, number, state, created_at)
|
||||
trial_params (trial_id, param_name, param_value)
|
||||
trial_values (trial_id, objective_id, value)
|
||||
trial_user_attributes (trial_id, key, value_json)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Claude Integration
|
||||
|
||||
### 5.1 Two Operation Modes
|
||||
|
||||
| Mode | Endpoint | Capabilities | Use Case |
|
||||
|------|----------|--------------|----------|
|
||||
| **User** | `/ws` | Read-only, MCP tools | Safe exploration |
|
||||
| **Power** | `/ws/power` | Full write access | Canvas modification |
|
||||
|
||||
### 5.2 Power Mode Tools
|
||||
|
||||
```python
|
||||
# claude_agent.py - Direct API tools
|
||||
add_design_variable(name, min, max, baseline, units)
|
||||
add_extractor(name, type, config, custom_code)
|
||||
add_objective(name, direction, weight, extractor_id)
|
||||
add_constraint(name, operator, threshold, extractor_id)
|
||||
update_spec_field(path, value) # JSONPath update
|
||||
remove_node(node_id)
|
||||
```
|
||||
|
||||
### 5.3 Context Building
|
||||
|
||||
The `ContextBuilder` assembles rich system prompts:
|
||||
|
||||
```
|
||||
# Atomizer Assistant
|
||||
|
||||
## Current Mode: POWER (full write access)
|
||||
|
||||
## Current Study: bracket_optimization
|
||||
- Design Variables: 3 (thickness, angle, radius)
|
||||
- Extractors: 2 (Displacement, Mass)
|
||||
- Objectives: 2 (Min mass, Max stiffness)
|
||||
- Constraints: 1 (mass <= 0.2 kg)
|
||||
- Status: 47/100 trials complete
|
||||
|
||||
## Canvas State
|
||||
8 nodes, 11 edges
|
||||
[Node list with IDs and types...]
|
||||
|
||||
## Available Tools
|
||||
- add_design_variable: Add a new design variable
|
||||
- add_extractor: Add physics extractor
|
||||
- add_objective: Add optimization objective
|
||||
- add_constraint: Add constraint
|
||||
- update_spec_field: Update any field by JSONPath
|
||||
- remove_node: Remove element by ID
|
||||
|
||||
**ACT IMMEDIATELY** when asked to modify things.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Data Flow Diagrams
|
||||
|
||||
### 6.1 Canvas Edit Flow
|
||||
|
||||
```
|
||||
User edits node property
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ useSpecStore.patchSpec() │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 1. Optimistic UI update │ │
|
||||
│ └───────────┬─────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────▼─────────────┐ │
|
||||
│ │ 2. Async PATCH request │ │
|
||||
│ └───────────┬─────────────┘ │
|
||||
└─────────────┼───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ Backend: SpecManager │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 3. JSONPath parse │ │
|
||||
│ │ 4. Apply modification │ │
|
||||
│ │ 5. Pydantic validate │ │
|
||||
│ │ 6. Atomic file write │ │
|
||||
│ │ 7. Compute new hash │ │
|
||||
│ │ 8. Broadcast to clients │ │
|
||||
│ └───────────┬─────────────┘ │
|
||||
└─────────────┼───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ All WebSocket Clients │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 9. Receive spec_updated │ │
|
||||
│ │ 10. Update local hash │ │
|
||||
│ │ 11. Re-render if needed │ │
|
||||
│ └─────────────────────────┘ │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
### 6.2 Optimization Run Flow
|
||||
|
||||
```
|
||||
User clicks "Run"
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ POST /api/optimization/start│
|
||||
│ { study_id, trials, method }│
|
||||
└─────────────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ Backend: Spawn runner │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 1. Load spec │ │
|
||||
│ │ 2. Initialize Optuna │ │
|
||||
│ │ 3. Create trial folders │ │
|
||||
│ └───────────┬─────────────┘ │
|
||||
└─────────────┼───────────────┘
|
||||
│
|
||||
┌─────────┼─────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────────────────────────────────────────────┐
|
||||
│ For each trial (1 to N): │
|
||||
│ ┌───────────────────────────────────────────────────┐ │
|
||||
│ │ 4. Optuna suggests parameters │ │
|
||||
│ │ 5. Update NX expressions │ │
|
||||
│ │ 6. Run Nastran simulation │ │
|
||||
│ │ 7. Extract physics results │ │
|
||||
│ │ 8. Compute objectives/constraints │ │
|
||||
│ │ 9. Save to trial folder + database │ │
|
||||
│ │ 10. Send WebSocket update │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
└───────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ Frontend: Real-time updates │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ Update convergence plot │ │
|
||||
│ │ Update trial table │ │
|
||||
│ │ Show best design │ │
|
||||
│ └─────────────────────────┘ │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
### 6.3 Claude Canvas Modification Flow
|
||||
|
||||
```
|
||||
User: "Add volume extractor with constraint <= 1000"
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ WebSocket: /ws/power │
|
||||
│ { type: 'message', │
|
||||
│ content: '...', │
|
||||
│ canvas_state: {...} } │
|
||||
└─────────────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ AtomizerClaudeAgent │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ 1. Build context prompt │ │
|
||||
│ │ 2. Send to Claude API │ │
|
||||
│ │ 3. Claude decides tools │ │
|
||||
│ └───────────┬─────────────┘ │
|
||||
└─────────────┼───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ Claude Tool Calls: │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ add_extractor( │ │
|
||||
│ │ name="Volume", │ │
|
||||
│ │ type="custom", │ │
|
||||
│ │ code="..." ) │ │
|
||||
│ │ │ │
|
||||
│ │ add_constraint( │ │
|
||||
│ │ name="Max Volume", │ │
|
||||
│ │ operator="<=", │ │
|
||||
│ │ threshold=1000 ) │ │
|
||||
│ └───────────┬─────────────┘ │
|
||||
└─────────────┼───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ Each tool modifies spec: │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ Load → Modify → Save │ │
|
||||
│ │ Send spec_modified │ │
|
||||
│ └───────────┬─────────────┘ │
|
||||
└─────────────┼───────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────┐
|
||||
│ Frontend receives events: │
|
||||
│ ┌─────────────────────────┐ │
|
||||
│ │ spec_modified → reload │ │
|
||||
│ │ Canvas shows new nodes │ │
|
||||
│ └─────────────────────────┘ │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Component Relationships
|
||||
|
||||
### 7.1 Frontend Component Hierarchy
|
||||
|
||||
```
|
||||
<App>
|
||||
├── <CanvasView>
|
||||
│ ├── <AtomizerCanvas>
|
||||
│ │ ├── <ReactFlow>
|
||||
│ │ │ ├── <DesignVarNode> × N
|
||||
│ │ │ ├── <ExtractorNode> × N
|
||||
│ │ │ ├── <ObjectiveNode> × N
|
||||
│ │ │ ├── <ConstraintNode> × N
|
||||
│ │ │ ├── <ModelNode>
|
||||
│ │ │ ├── <SolverNode>
|
||||
│ │ │ └── <AlgorithmNode>
|
||||
│ │ ├── <NodePalette>
|
||||
│ │ ├── <NodeConfigPanel>
|
||||
│ │ ├── <ValidationPanel>
|
||||
│ │ └── <ExecuteDialog>
|
||||
│ └── <ChatPanel>
|
||||
│ ├── <ChatMessage> × N
|
||||
│ └── <ToolCallCard> × M
|
||||
├── <Home>
|
||||
│ └── <StudyList>
|
||||
└── <Setup>
|
||||
└── <StudyWizard>
|
||||
```
|
||||
|
||||
### 7.2 Backend Service Dependencies
|
||||
|
||||
```
|
||||
FastAPI App
|
||||
│
|
||||
├── spec.py ─────────► SpecManager
|
||||
│ ├── Pydantic Models
|
||||
│ └── File I/O + Hash
|
||||
│
|
||||
├── claude.py ───────► AtomizerClaudeAgent
|
||||
│ ├── ContextBuilder
|
||||
│ ├── Anthropic Client
|
||||
│ └── Write Tools
|
||||
│
|
||||
├── optimization.py ─► Runner Process
|
||||
│ ├── TrialManager
|
||||
│ ├── NX Solver
|
||||
│ └── Extractors
|
||||
│
|
||||
└── WebSocket Hub ◄─── All routes broadcast
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Critical Patterns
|
||||
|
||||
### 8.1 Modification Pattern
|
||||
|
||||
**Always use SpecManager for modifications:**
|
||||
|
||||
```python
|
||||
# ❌ WRONG: Direct file write
|
||||
with open("atomizer_spec.json", "w") as f:
|
||||
json.dump(spec, f)
|
||||
|
||||
# ✅ CORRECT: Use SpecManager
|
||||
manager = SpecManager(study_path)
|
||||
spec = manager.load_spec()
|
||||
spec.objectives[0].weight = 2.0
|
||||
manager.save_spec(spec)
|
||||
```
|
||||
|
||||
### 8.2 Optimistic Update Pattern
|
||||
|
||||
```typescript
|
||||
// 1. Update UI immediately
|
||||
setSpec(modifiedSpec);
|
||||
|
||||
// 2. Async sync to backend
|
||||
patchSpec(path, value)
|
||||
.then(({ hash }) => setHash(hash))
|
||||
.catch(() => setSpec(originalSpec)); // Rollback on failure
|
||||
```
|
||||
|
||||
### 8.3 WebSocket Sync Pattern
|
||||
|
||||
```
|
||||
Client A ─────► Server ─────► Client B
|
||||
│ │ │
|
||||
│ PATCH │ │
|
||||
├─────────────►│ │
|
||||
│ │ broadcast │
|
||||
│ ├─────────────►│
|
||||
│ │ │
|
||||
│◄─────────────┤◄─────────────┤
|
||||
│ ack + hash │ │
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Potential Improvements
|
||||
|
||||
### 9.1 Current Limitations
|
||||
|
||||
1. **No Undo/Redo**: Canvas modifications are immediate
|
||||
2. **Single File Lock**: No distributed locking for multi-user
|
||||
3. **Memory-only Sessions**: Session state lost on restart
|
||||
4. **Limited Offline**: Requires backend connection
|
||||
|
||||
### 9.2 Recommended Enhancements
|
||||
|
||||
| Priority | Enhancement | Benefit |
|
||||
|----------|-------------|---------|
|
||||
| High | Operation history with undo | Better UX |
|
||||
| High | Persistent sessions (Redis) | Scalability |
|
||||
| Medium | Spec versioning/branching | Experimentation |
|
||||
| Medium | Batch operations API | Performance |
|
||||
| Low | Offline canvas editing | Flexibility |
|
||||
|
||||
---
|
||||
|
||||
## 10. Conclusion
|
||||
|
||||
Atomizer's architecture is **well-designed for its purpose**: enabling engineers to configure and run FEA optimizations through a visual interface with AI assistance.
|
||||
|
||||
**Strongest Points**:
|
||||
- Single source of truth eliminates sync issues
|
||||
- Pydantic ensures data integrity
|
||||
- WebSocket enables real-time collaboration
|
||||
- Optimistic updates provide responsive UX
|
||||
|
||||
**Areas for Attention**:
|
||||
- Add undo/redo for canvas operations
|
||||
- Consider persistent session storage for production
|
||||
- Expand test coverage for spec migrations
|
||||
|
||||
The architecture is **production-ready** for single-user/small-team scenarios and can be enhanced for enterprise deployment.
|
||||
519
docs/reviews/ATOMIZER_ARCHITECTURE.svg
Normal file
519
docs/reviews/ATOMIZER_ARCHITECTURE.svg
Normal file
@@ -0,0 +1,519 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 1200" width="1400" height="1200">
|
||||
<defs>
|
||||
<!-- Gradients -->
|
||||
<linearGradient id="headerGrad" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" style="stop-color:#1a1a2e"/>
|
||||
<stop offset="100%" style="stop-color:#16213e"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="frontendGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#0f3460"/>
|
||||
<stop offset="100%" style="stop-color:#0d2847"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="backendGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#1a472a"/>
|
||||
<stop offset="100%" style="stop-color:#143d20"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="engineGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#4a1942"/>
|
||||
<stop offset="100%" style="stop-color:#3d1536"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="specGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#e94560"/>
|
||||
<stop offset="100%" style="stop-color:#c73659"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="claudeGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#d4a373"/>
|
||||
<stop offset="100%" style="stop-color:#bc8f5f"/>
|
||||
</linearGradient>
|
||||
|
||||
<!-- Arrow marker -->
|
||||
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#6b7280"/>
|
||||
</marker>
|
||||
<marker id="arrowheadBlue" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#3b82f6"/>
|
||||
</marker>
|
||||
<marker id="arrowheadGreen" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#22c55e"/>
|
||||
</marker>
|
||||
<marker id="arrowheadOrange" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="#f97316"/>
|
||||
</marker>
|
||||
|
||||
<!-- Drop shadow -->
|
||||
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="2" dy="2" stdDeviation="3" flood-opacity="0.3"/>
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<!-- Background -->
|
||||
<rect width="1400" height="1200" fill="#0f0f1a"/>
|
||||
|
||||
<!-- Title -->
|
||||
<rect x="0" y="0" width="1400" height="60" fill="url(#headerGrad)"/>
|
||||
<text x="700" y="40" text-anchor="middle" font-family="Arial, sans-serif" font-size="24" font-weight="bold" fill="#ffffff">
|
||||
ATOMIZER ARCHITECTURE - Intelligence Layout
|
||||
</text>
|
||||
<text x="700" y="55" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="#9ca3af">
|
||||
AtomizerSpec v2.0 | Single Source of Truth Pattern | January 2026
|
||||
</text>
|
||||
|
||||
<!-- ==================== FRONTEND SECTION ==================== -->
|
||||
<g id="frontend">
|
||||
<!-- Frontend Container -->
|
||||
<rect x="30" y="80" width="420" height="350" rx="10" fill="url(#frontendGrad)" filter="url(#shadow)" stroke="#3b82f6" stroke-width="2"/>
|
||||
<text x="240" y="105" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#3b82f6">FRONTEND (React + TypeScript)</text>
|
||||
|
||||
<!-- Canvas View -->
|
||||
<rect x="50" y="120" width="180" height="80" rx="6" fill="#1e3a5f" stroke="#60a5fa" stroke-width="1"/>
|
||||
<text x="140" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#60a5fa">CanvasView</text>
|
||||
<text x="140" y="162" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#93c5fd">ReactFlow Canvas</text>
|
||||
<text x="140" y="175" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#93c5fd">Node Rendering</text>
|
||||
<text x="140" y="188" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#93c5fd">Edge Connections</text>
|
||||
|
||||
<!-- Chat Panel -->
|
||||
<rect x="250" y="120" width="180" height="80" rx="6" fill="#1e3a5f" stroke="#60a5fa" stroke-width="1"/>
|
||||
<text x="340" y="145" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#60a5fa">ChatPanel</text>
|
||||
<text x="340" y="162" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#93c5fd">Claude Integration</text>
|
||||
<text x="340" y="175" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#93c5fd">User/Power Mode</text>
|
||||
<text x="340" y="188" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#93c5fd">Tool Call Display</text>
|
||||
|
||||
<!-- useSpecStore -->
|
||||
<rect x="50" y="215" width="180" height="90" rx="6" fill="#0d47a1" stroke="#2196f3" stroke-width="2"/>
|
||||
<text x="140" y="240" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#ffffff">useSpecStore</text>
|
||||
<text x="140" y="257" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#bbdefb">Zustand Store</text>
|
||||
<text x="140" y="272" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#90caf9">spec | hash | isDirty</text>
|
||||
<text x="140" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#90caf9">selectedNode | validation</text>
|
||||
<text x="140" y="298" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#64b5f6">patchSpec() | addNode()</text>
|
||||
|
||||
<!-- useChat -->
|
||||
<rect x="250" y="215" width="180" height="90" rx="6" fill="#0d47a1" stroke="#2196f3" stroke-width="2"/>
|
||||
<text x="340" y="240" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#ffffff">useChat</text>
|
||||
<text x="340" y="257" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#bbdefb">WebSocket Hook</text>
|
||||
<text x="340" y="272" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#90caf9">messages | isThinking</text>
|
||||
<text x="340" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#90caf9">mode: user | power</text>
|
||||
<text x="340" y="298" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#64b5f6">sendMessage() | switchMode()</text>
|
||||
|
||||
<!-- Converter -->
|
||||
<rect x="50" y="320" width="380" height="45" rx="6" fill="#1565c0" stroke="#42a5f5" stroke-width="1"/>
|
||||
<text x="240" y="342" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#ffffff">spec/converter.ts</text>
|
||||
<text x="240" y="358" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#bbdefb">specToNodes() | nodesToSpec() | Auto-layout: DVs→Model→Solver→Extractors→Objectives→Algorithm</text>
|
||||
|
||||
<!-- Types -->
|
||||
<rect x="50" y="375" width="180" height="40" rx="4" fill="#1976d2" stroke="#64b5f6" stroke-width="1"/>
|
||||
<text x="140" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="#ffffff">types/atomizer-spec.ts</text>
|
||||
<text x="140" y="408" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbdefb">TypeScript Definitions</text>
|
||||
|
||||
<!-- Panels -->
|
||||
<rect x="250" y="375" width="180" height="40" rx="4" fill="#1976d2" stroke="#64b5f6" stroke-width="1"/>
|
||||
<text x="340" y="395" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="#ffffff">panels/*.tsx</text>
|
||||
<text x="340" y="408" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbdefb">NodeConfig | Validation | Execute</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== BACKEND SECTION ==================== -->
|
||||
<g id="backend">
|
||||
<!-- Backend Container -->
|
||||
<rect x="490" y="80" width="420" height="350" rx="10" fill="url(#backendGrad)" filter="url(#shadow)" stroke="#22c55e" stroke-width="2"/>
|
||||
<text x="700" y="105" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#22c55e">BACKEND (FastAPI + Python)</text>
|
||||
|
||||
<!-- Routes -->
|
||||
<rect x="510" y="120" width="180" height="100" rx="6" fill="#14532d" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="600" y="140" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#4ade80">routes/</text>
|
||||
<text x="600" y="158" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">spec.py - CRUD + WS sync</text>
|
||||
<text x="600" y="173" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">claude.py - Chat sessions</text>
|
||||
<text x="600" y="188" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">optimization.py - Run control</text>
|
||||
<text x="600" y="203" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">files.py - Upload/download</text>
|
||||
|
||||
<!-- Services -->
|
||||
<rect x="710" y="120" width="180" height="100" rx="6" fill="#14532d" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="800" y="140" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#4ade80">services/</text>
|
||||
<text x="800" y="158" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">spec_manager.py</text>
|
||||
<text x="800" y="173" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">claude_agent.py</text>
|
||||
<text x="800" y="188" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">context_builder.py</text>
|
||||
<text x="800" y="203" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">session_manager.py</text>
|
||||
|
||||
<!-- SpecManager Detail -->
|
||||
<rect x="510" y="235" width="380" height="100" rx="6" fill="#166534" stroke="#22c55e" stroke-width="2"/>
|
||||
<text x="700" y="258" text-anchor="middle" font-family="Arial, sans-serif" font-size="12" font-weight="bold" fill="#ffffff">SpecManager (Central Gatekeeper)</text>
|
||||
<text x="700" y="278" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#bbf7d0">load_spec() → validate() → patch_spec() → save_spec()</text>
|
||||
<text x="700" y="295" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">Pydantic Validation | Atomic Writes | SHA256 Hashing</text>
|
||||
<text x="700" y="312" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#86efac">WebSocket Broadcast | Conflict Detection</text>
|
||||
<text x="700" y="328" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#4ade80">All modifications must go through SpecManager</text>
|
||||
|
||||
<!-- REST Endpoints -->
|
||||
<rect x="510" y="350" width="180" height="65" rx="4" fill="#15803d" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="600" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">REST API</text>
|
||||
<text x="600" y="385" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">GET/PUT/PATCH /spec</text>
|
||||
<text x="600" y="398" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">POST/PATCH/DELETE /nodes</text>
|
||||
<text x="600" y="411" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">POST /validate</text>
|
||||
|
||||
<!-- WebSocket -->
|
||||
<rect x="710" y="350" width="180" height="65" rx="4" fill="#15803d" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="800" y="370" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">WebSocket</text>
|
||||
<text x="800" y="385" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">/spec/sync - Real-time sync</text>
|
||||
<text x="800" y="398" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">/ws - User mode chat</text>
|
||||
<text x="800" y="411" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">/ws/power - Power mode</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== ATOMIZER SPEC (CENTER) ==================== -->
|
||||
<g id="spec">
|
||||
<rect x="520" y="470" width="360" height="200" rx="12" fill="url(#specGrad)" filter="url(#shadow)" stroke="#ff6b6b" stroke-width="3"/>
|
||||
<text x="700" y="500" text-anchor="middle" font-family="Arial, sans-serif" font-size="18" font-weight="bold" fill="#ffffff">atomizer_spec.json</text>
|
||||
<text x="700" y="520" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" fill="#fecaca">SINGLE SOURCE OF TRUTH</text>
|
||||
|
||||
<!-- Spec Structure -->
|
||||
<rect x="540" y="535" width="150" height="120" rx="4" fill="#991b1b" stroke="#fca5a5" stroke-width="1"/>
|
||||
<text x="615" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#fecaca">Structure</text>
|
||||
<text x="615" y="572" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fecaca">meta: { version, name }</text>
|
||||
<text x="615" y="586" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fecaca">model: { sim, fem }</text>
|
||||
<text x="615" y="600" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fecaca">design_variables[]</text>
|
||||
<text x="615" y="614" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fecaca">extractors[]</text>
|
||||
<text x="615" y="628" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fecaca">objectives[]</text>
|
||||
<text x="615" y="642" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fecaca">constraints[]</text>
|
||||
|
||||
<!-- Node IDs -->
|
||||
<rect x="710" y="535" width="150" height="120" rx="4" fill="#991b1b" stroke="#fca5a5" stroke-width="1"/>
|
||||
<text x="785" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#fecaca">Node IDs</text>
|
||||
<text x="785" y="575" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#fecaca">dv_001, dv_002...</text>
|
||||
<text x="785" y="592" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#fecaca">ext_001, ext_002...</text>
|
||||
<text x="785" y="609" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#fecaca">obj_001, obj_002...</text>
|
||||
<text x="785" y="626" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#fecaca">con_001, con_002...</text>
|
||||
<text x="785" y="648" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#f87171">+ canvas_position</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== OPTIMIZATION ENGINE ==================== -->
|
||||
<g id="engine">
|
||||
<rect x="950" y="80" width="420" height="350" rx="10" fill="url(#engineGrad)" filter="url(#shadow)" stroke="#c026d3" stroke-width="2"/>
|
||||
<text x="1160" y="105" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#c026d3">OPTIMIZATION ENGINE</text>
|
||||
|
||||
<!-- Core -->
|
||||
<rect x="970" y="120" width="180" height="95" rx="6" fill="#581c87" stroke="#d946ef" stroke-width="1"/>
|
||||
<text x="1060" y="140" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#d946ef">core/</text>
|
||||
<text x="1060" y="158" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">runner.py - Main loop</text>
|
||||
<text x="1060" y="173" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">method_selector.py</text>
|
||||
<text x="1060" y="188" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">intelligent_optimizer.py</text>
|
||||
<text x="1060" y="203" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">gradient_optimizer.py</text>
|
||||
|
||||
<!-- Extractors -->
|
||||
<rect x="1170" y="120" width="180" height="95" rx="6" fill="#581c87" stroke="#d946ef" stroke-width="1"/>
|
||||
<text x="1260" y="140" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#d946ef">extractors/</text>
|
||||
<text x="1260" y="158" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">displacement, stress</text>
|
||||
<text x="1260" y="173" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">frequency, mass</text>
|
||||
<text x="1260" y="188" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">zernike_opd</text>
|
||||
<text x="1260" y="203" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">custom_extractor_loader</text>
|
||||
|
||||
<!-- Config -->
|
||||
<rect x="970" y="230" width="180" height="80" rx="6" fill="#6b21a8" stroke="#a855f7" stroke-width="2"/>
|
||||
<text x="1060" y="252" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#ffffff">config/</text>
|
||||
<text x="1060" y="270" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">spec_models.py (Pydantic)</text>
|
||||
<text x="1060" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">spec_validator.py</text>
|
||||
<text x="1060" y="300" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">migrator.py (legacy→v2)</text>
|
||||
|
||||
<!-- NX Integration -->
|
||||
<rect x="1170" y="230" width="180" height="80" rx="6" fill="#581c87" stroke="#d946ef" stroke-width="1"/>
|
||||
<text x="1260" y="252" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#d946ef">nx/</text>
|
||||
<text x="1260" y="270" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">solver.py - Nastran exec</text>
|
||||
<text x="1260" y="285" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">updater.py - Param update</text>
|
||||
<text x="1260" y="300" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#e9d5ff">session_manager.py</text>
|
||||
|
||||
<!-- Utils -->
|
||||
<rect x="970" y="325" width="180" height="55" rx="4" fill="#7c3aed" stroke="#a78bfa" stroke-width="1"/>
|
||||
<text x="1060" y="345" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">utils/</text>
|
||||
<text x="1060" y="362" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#ddd6fe">dashboard_db.py (Optuna)</text>
|
||||
<text x="1060" y="375" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#ddd6fe">trial_manager.py</text>
|
||||
|
||||
<!-- Study -->
|
||||
<rect x="1170" y="325" width="180" height="55" rx="4" fill="#7c3aed" stroke="#a78bfa" stroke-width="1"/>
|
||||
<text x="1260" y="345" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">study/</text>
|
||||
<text x="1260" y="362" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#ddd6fe">creator.py, state.py</text>
|
||||
<text x="1260" y="375" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#ddd6fe">reset.py</text>
|
||||
|
||||
<!-- Algorithms Box -->
|
||||
<rect x="970" y="390" width="380" height="35" rx="4" fill="#4c1d95" stroke="#8b5cf6" stroke-width="1"/>
|
||||
<text x="1160" y="412" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="#c4b5fd">Algorithms: TPE | CMA-ES | NSGA-II | IMSO | SAT_v3 | RandomSearch</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== CLAUDE INTEGRATION ==================== -->
|
||||
<g id="claude">
|
||||
<rect x="950" y="470" width="420" height="200" rx="10" fill="url(#claudeGrad)" filter="url(#shadow)" stroke="#d97706" stroke-width="2"/>
|
||||
<text x="1160" y="495" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#451a03">CLAUDE INTEGRATION</text>
|
||||
|
||||
<!-- AtomizerClaudeAgent -->
|
||||
<rect x="970" y="510" width="180" height="145" rx="6" fill="#92400e" stroke="#fbbf24" stroke-width="1"/>
|
||||
<text x="1060" y="532" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#fef3c7">AtomizerClaudeAgent</text>
|
||||
<text x="1060" y="550" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#fde68a">Direct Anthropic API</text>
|
||||
<text x="1060" y="570" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fef3c7">Tools (Power Mode):</text>
|
||||
<text x="1060" y="585" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">add_design_variable()</text>
|
||||
<text x="1060" y="598" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">add_extractor()</text>
|
||||
<text x="1060" y="611" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">add_objective()</text>
|
||||
<text x="1060" y="624" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">add_constraint()</text>
|
||||
<text x="1060" y="637" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">update_spec_field()</text>
|
||||
<text x="1060" y="650" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">remove_node()</text>
|
||||
|
||||
<!-- Context Builder -->
|
||||
<rect x="1170" y="510" width="180" height="75" rx="6" fill="#92400e" stroke="#fbbf24" stroke-width="1"/>
|
||||
<text x="1260" y="532" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#fef3c7">ContextBuilder</text>
|
||||
<text x="1260" y="552" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#fde68a">System prompt assembly</text>
|
||||
<text x="1260" y="568" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">Study context injection</text>
|
||||
<text x="1260" y="581" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">Canvas state embedding</text>
|
||||
|
||||
<!-- Modes -->
|
||||
<rect x="1170" y="595" width="85" height="55" rx="4" fill="#78350f" stroke="#f59e0b" stroke-width="1"/>
|
||||
<text x="1212" y="615" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#fef3c7">User</text>
|
||||
<text x="1212" y="630" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">Read-only</text>
|
||||
<text x="1212" y="643" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fde68a">MCP tools</text>
|
||||
|
||||
<rect x="1265" y="595" width="85" height="55" rx="4" fill="#b45309" stroke="#fbbf24" stroke-width="2"/>
|
||||
<text x="1307" y="615" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">Power</text>
|
||||
<text x="1307" y="630" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fef3c7">Full write</text>
|
||||
<text x="1307" y="643" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#fef3c7">Direct API</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== FILE SYSTEM ==================== -->
|
||||
<g id="filesystem">
|
||||
<rect x="30" y="470" width="450" height="200" rx="10" fill="#1f2937" filter="url(#shadow)" stroke="#6b7280" stroke-width="2"/>
|
||||
<text x="255" y="495" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#9ca3af">FILE SYSTEM</text>
|
||||
|
||||
<!-- Study Structure -->
|
||||
<rect x="50" y="510" width="200" height="145" rx="6" fill="#374151" stroke="#6b7280" stroke-width="1"/>
|
||||
<text x="150" y="530" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#d1d5db">studies/{name}/</text>
|
||||
<text x="150" y="550" text-anchor="middle" font-family="monospace" font-size="9" fill="#9ca3af">atomizer_spec.json</text>
|
||||
<text x="150" y="566" text-anchor="middle" font-family="monospace" font-size="9" fill="#6b7280">1_setup/model/</text>
|
||||
<text x="150" y="582" text-anchor="middle" font-family="monospace" font-size="9" fill="#6b7280"> *.prt, *.sim, *.fem</text>
|
||||
<text x="150" y="598" text-anchor="middle" font-family="monospace" font-size="9" fill="#6b7280">2_iterations/</text>
|
||||
<text x="150" y="614" text-anchor="middle" font-family="monospace" font-size="9" fill="#6b7280"> trial_NNNN/</text>
|
||||
<text x="150" y="630" text-anchor="middle" font-family="monospace" font-size="9" fill="#6b7280">3_results/</text>
|
||||
<text x="150" y="646" text-anchor="middle" font-family="monospace" font-size="9" fill="#9ca3af"> study.db</text>
|
||||
|
||||
<!-- Database -->
|
||||
<rect x="270" y="510" width="190" height="145" rx="6" fill="#374151" stroke="#6b7280" stroke-width="1"/>
|
||||
<text x="365" y="530" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#d1d5db">study.db (Optuna)</text>
|
||||
<text x="365" y="555" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#9ca3af">trials</text>
|
||||
<text x="365" y="570" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#6b7280">trial_id | state | created</text>
|
||||
<text x="365" y="590" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#9ca3af">trial_params</text>
|
||||
<text x="365" y="605" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#6b7280">param_name | param_value</text>
|
||||
<text x="365" y="625" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#9ca3af">trial_values</text>
|
||||
<text x="365" y="640" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#6b7280">objective_id | value</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== DATA FLOW ARROWS ==================== -->
|
||||
|
||||
<!-- Frontend to Backend (REST) -->
|
||||
<path d="M 450 285 L 510 285" stroke="#3b82f6" stroke-width="2" marker-end="url(#arrowheadBlue)" fill="none"/>
|
||||
<text x="480" y="278" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#60a5fa">REST</text>
|
||||
|
||||
<!-- Frontend to Backend (WebSocket) -->
|
||||
<path d="M 450 315 L 510 315" stroke="#22c55e" stroke-width="2" marker-end="url(#arrowheadGreen)" fill="none" stroke-dasharray="5,3"/>
|
||||
<text x="480" y="330" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#4ade80">WS</text>
|
||||
|
||||
<!-- Backend to Spec -->
|
||||
<path d="M 700 420 L 700 470" stroke="#e94560" stroke-width="3" marker-end="url(#arrowhead)" fill="none"/>
|
||||
<text x="715" y="445" font-family="Arial, sans-serif" font-size="8" fill="#f87171">Read/Write</text>
|
||||
|
||||
<!-- Spec to Engine -->
|
||||
<path d="M 880 570 L 950 570" stroke="#c026d3" stroke-width="2" marker-end="url(#arrowhead)" fill="none"/>
|
||||
<text x="915" y="563" font-family="Arial, sans-serif" font-size="8" fill="#d946ef">Load</text>
|
||||
|
||||
<!-- Claude to Spec -->
|
||||
<path d="M 950 570 L 880 570" stroke="#d97706" stroke-width="2" marker-end="url(#arrowheadOrange)" fill="none" stroke-dasharray="5,3"/>
|
||||
<text x="915" y="585" font-family="Arial, sans-serif" font-size="8" fill="#fbbf24">Modify</text>
|
||||
|
||||
<!-- Spec to FileSystem -->
|
||||
<path d="M 520 570 L 480 570" stroke="#6b7280" stroke-width="2" marker-end="url(#arrowhead)" fill="none"/>
|
||||
<text x="500" y="563" font-family="Arial, sans-serif" font-size="8" fill="#9ca3af">File</text>
|
||||
|
||||
<!-- Engine to FileSystem (DB) -->
|
||||
<path d="M 950 400 L 480 590" stroke="#c026d3" stroke-width="1.5" marker-end="url(#arrowhead)" fill="none" stroke-dasharray="3,2"/>
|
||||
<text x="720" y="485" font-family="Arial, sans-serif" font-size="8" fill="#d946ef">Trials</text>
|
||||
|
||||
<!-- Frontend to Claude (Chat) -->
|
||||
<path d="M 430 155 L 1050 475" stroke="#d97706" stroke-width="1.5" marker-end="url(#arrowheadOrange)" fill="none" stroke-dasharray="5,3"/>
|
||||
<text x="740" y="300" font-family="Arial, sans-serif" font-size="8" fill="#fbbf24">Chat WS</text>
|
||||
|
||||
<!-- ==================== LEGEND ==================== -->
|
||||
<g id="legend">
|
||||
<rect x="30" y="700" width="1340" height="80" rx="8" fill="#1a1a2e" stroke="#374151" stroke-width="1"/>
|
||||
<text x="700" y="725" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="#ffffff">DATA FLOW LEGEND</text>
|
||||
|
||||
<!-- REST -->
|
||||
<line x1="80" y1="750" x2="130" y2="750" stroke="#3b82f6" stroke-width="2"/>
|
||||
<text x="145" y="754" font-family="Arial, sans-serif" font-size="10" fill="#60a5fa">REST API</text>
|
||||
|
||||
<!-- WebSocket -->
|
||||
<line x1="230" y1="750" x2="280" y2="750" stroke="#22c55e" stroke-width="2" stroke-dasharray="5,3"/>
|
||||
<text x="295" y="754" font-family="Arial, sans-serif" font-size="10" fill="#4ade80">WebSocket</text>
|
||||
|
||||
<!-- Read/Write -->
|
||||
<line x1="400" y1="750" x2="450" y2="750" stroke="#e94560" stroke-width="3"/>
|
||||
<text x="465" y="754" font-family="Arial, sans-serif" font-size="10" fill="#f87171">Spec I/O</text>
|
||||
|
||||
<!-- Claude -->
|
||||
<line x1="560" y1="750" x2="610" y2="750" stroke="#d97706" stroke-width="2" stroke-dasharray="5,3"/>
|
||||
<text x="625" y="754" font-family="Arial, sans-serif" font-size="10" fill="#fbbf24">Claude</text>
|
||||
|
||||
<!-- Engine -->
|
||||
<line x1="700" y1="750" x2="750" y2="750" stroke="#c026d3" stroke-width="2"/>
|
||||
<text x="765" y="754" font-family="Arial, sans-serif" font-size="10" fill="#d946ef">Engine</text>
|
||||
|
||||
<!-- Key Principle -->
|
||||
<rect x="900" y="740" width="430" height="25" rx="4" fill="#991b1b"/>
|
||||
<text x="1115" y="757" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#ffffff">
|
||||
All modifications flow through atomizer_spec.json (Single Source of Truth)
|
||||
</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== CANVAS NODES DETAIL ==================== -->
|
||||
<g id="canvas-nodes">
|
||||
<rect x="30" y="800" width="650" height="180" rx="8" fill="#0d2847" stroke="#3b82f6" stroke-width="1"/>
|
||||
<text x="355" y="825" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="#3b82f6">CANVAS NODE TYPES (ReactFlow)</text>
|
||||
|
||||
<!-- Node types in columns -->
|
||||
<g transform="translate(50, 845)">
|
||||
<!-- Design Variables -->
|
||||
<rect x="0" y="0" width="90" height="50" rx="4" fill="#1e40af" stroke="#60a5fa" stroke-width="1"/>
|
||||
<text x="45" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" font-weight="bold" fill="#ffffff">DesignVar</text>
|
||||
<text x="45" y="35" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#93c5fd">dv_001</text>
|
||||
<text x="45" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#93c5fd">bounds, baseline</text>
|
||||
|
||||
<!-- Model -->
|
||||
<rect x="105" y="0" width="90" height="50" rx="4" fill="#065f46" stroke="#34d399" stroke-width="1"/>
|
||||
<text x="150" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" font-weight="bold" fill="#ffffff">Model</text>
|
||||
<text x="150" y="35" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#a7f3d0">synthetic</text>
|
||||
<text x="150" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#a7f3d0">.sim path</text>
|
||||
|
||||
<!-- Solver -->
|
||||
<rect x="210" y="0" width="90" height="50" rx="4" fill="#065f46" stroke="#34d399" stroke-width="1"/>
|
||||
<text x="255" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" font-weight="bold" fill="#ffffff">Solver</text>
|
||||
<text x="255" y="35" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#a7f3d0">synthetic</text>
|
||||
<text x="255" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#a7f3d0">SOL 101/103</text>
|
||||
|
||||
<!-- Extractor -->
|
||||
<rect x="315" y="0" width="90" height="50" rx="4" fill="#7c2d12" stroke="#fb923c" stroke-width="1"/>
|
||||
<text x="360" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" font-weight="bold" fill="#ffffff">Extractor</text>
|
||||
<text x="360" y="35" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#fed7aa">ext_001</text>
|
||||
<text x="360" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#fed7aa">type, outputs</text>
|
||||
|
||||
<!-- Objective -->
|
||||
<rect x="420" y="0" width="90" height="50" rx="4" fill="#7f1d1d" stroke="#f87171" stroke-width="1"/>
|
||||
<text x="465" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" font-weight="bold" fill="#ffffff">Objective</text>
|
||||
<text x="465" y="35" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#fecaca">obj_001</text>
|
||||
<text x="465" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#fecaca">direction, weight</text>
|
||||
|
||||
<!-- Constraint -->
|
||||
<rect x="525" y="0" width="90" height="50" rx="4" fill="#713f12" stroke="#facc15" stroke-width="1"/>
|
||||
<text x="570" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" font-weight="bold" fill="#ffffff">Constraint</text>
|
||||
<text x="570" y="35" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#fef08a">con_001</text>
|
||||
<text x="570" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#fef08a">operator, threshold</text>
|
||||
</g>
|
||||
|
||||
<!-- Second row -->
|
||||
<g transform="translate(50, 910)">
|
||||
<!-- Algorithm -->
|
||||
<rect x="0" y="0" width="90" height="50" rx="4" fill="#581c87" stroke="#a855f7" stroke-width="1"/>
|
||||
<text x="45" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" font-weight="bold" fill="#ffffff">Algorithm</text>
|
||||
<text x="45" y="35" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#e9d5ff">synthetic</text>
|
||||
<text x="45" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#e9d5ff">TPE/CMA-ES</text>
|
||||
|
||||
<!-- Surrogate -->
|
||||
<rect x="105" y="0" width="90" height="50" rx="4" fill="#312e81" stroke="#818cf8" stroke-width="1"/>
|
||||
<text x="150" y="20" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" font-weight="bold" fill="#ffffff">Surrogate</text>
|
||||
<text x="150" y="35" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#c7d2fe">optional</text>
|
||||
<text x="150" y="45" text-anchor="middle" font-family="Arial, sans-serif" font-size="7" fill="#c7d2fe">MLP/GNN</text>
|
||||
|
||||
<!-- Flow -->
|
||||
<text x="330" y="25" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="#9ca3af">
|
||||
Layout: DVs → Model → Solver → Extractors → Objectives/Constraints → Algorithm
|
||||
</text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- ==================== KEY PATTERNS ==================== -->
|
||||
<g id="patterns">
|
||||
<rect x="700" y="800" width="670" height="180" rx="8" fill="#14532d" stroke="#22c55e" stroke-width="1"/>
|
||||
<text x="1035" y="825" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="#22c55e">KEY ARCHITECTURAL PATTERNS</text>
|
||||
|
||||
<!-- Optimistic Updates -->
|
||||
<rect x="720" y="840" width="200" height="60" rx="4" fill="#166534" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="820" y="860" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">Optimistic Updates</text>
|
||||
<text x="820" y="877" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">1. Update UI immediately</text>
|
||||
<text x="820" y="890" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">2. Async sync to backend</text>
|
||||
|
||||
<!-- Conflict Detection -->
|
||||
<rect x="935" y="840" width="200" height="60" rx="4" fill="#166534" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="1035" y="860" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">Conflict Detection</text>
|
||||
<text x="1035" y="877" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">SHA256 hash comparison</text>
|
||||
<text x="1035" y="890" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">409 Conflict → reload</text>
|
||||
|
||||
<!-- WebSocket Broadcast -->
|
||||
<rect x="1150" y="840" width="200" height="60" rx="4" fill="#166534" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="1250" y="860" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">WS Broadcast</text>
|
||||
<text x="1250" y="877" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">All clients synced</text>
|
||||
<text x="1250" y="890" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">Real-time updates</text>
|
||||
|
||||
<!-- Pydantic Validation -->
|
||||
<rect x="720" y="910" width="200" height="60" rx="4" fill="#166534" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="820" y="930" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">Pydantic Validation</text>
|
||||
<text x="820" y="947" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">Every modification validated</text>
|
||||
<text x="820" y="960" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">Schema + semantic checks</text>
|
||||
|
||||
<!-- Atomic Writes -->
|
||||
<rect x="935" y="910" width="200" height="60" rx="4" fill="#166534" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="1035" y="930" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">Atomic Writes</text>
|
||||
<text x="1035" y="947" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">No partial updates</text>
|
||||
<text x="1035" y="960" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">Write → hash → broadcast</text>
|
||||
|
||||
<!-- Node ID Convention -->
|
||||
<rect x="1150" y="910" width="200" height="60" rx="4" fill="#166534" stroke="#4ade80" stroke-width="1"/>
|
||||
<text x="1250" y="930" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" font-weight="bold" fill="#ffffff">Node ID Convention</text>
|
||||
<text x="1250" y="947" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">dv_, ext_, obj_, con_</text>
|
||||
<text x="1250" y="960" text-anchor="middle" font-family="Arial, sans-serif" font-size="8" fill="#bbf7d0">Auto-increment: {prefix}{N:03d}</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== VERSION INFO ==================== -->
|
||||
<g id="version">
|
||||
<rect x="30" y="1000" width="1340" height="50" rx="8" fill="#1a1a2e" stroke="#374151" stroke-width="1"/>
|
||||
<text x="700" y="1020" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="#6b7280">
|
||||
AtomizerSpec v2.0 | React 18 + Vite + Zustand | FastAPI + Pydantic | SQLite (Optuna) | Anthropic Claude API
|
||||
</text>
|
||||
<text x="700" y="1038" text-anchor="middle" font-family="Arial, sans-serif" font-size="10" fill="#6b7280">
|
||||
Optimization Algorithms: TPE | CMA-ES | NSGA-II | IMSO | SAT_v3 | GNN Surrogates | Extractors: displacement, stress, frequency, mass, zernike
|
||||
</text>
|
||||
</g>
|
||||
|
||||
<!-- ==================== INTELLIGENCE INDICATORS ==================== -->
|
||||
<g id="intelligence">
|
||||
<rect x="30" y="1060" width="1340" height="120" rx="8" fill="#1f1f3a" stroke="#8b5cf6" stroke-width="2"/>
|
||||
<text x="700" y="1085" text-anchor="middle" font-family="Arial, sans-serif" font-size="14" font-weight="bold" fill="#a78bfa">INTELLIGENCE LAYER</text>
|
||||
|
||||
<!-- Claude Power Mode -->
|
||||
<rect x="60" y="1100" width="250" height="60" rx="4" fill="#3730a3" stroke="#818cf8" stroke-width="1"/>
|
||||
<text x="185" y="1120" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#ffffff">Claude Power Mode</text>
|
||||
<text x="185" y="1138" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">Direct spec modifications via tools</text>
|
||||
<text x="185" y="1152" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">No permission prompts</text>
|
||||
|
||||
<!-- IMSO -->
|
||||
<rect x="330" y="1100" width="250" height="60" rx="4" fill="#3730a3" stroke="#818cf8" stroke-width="1"/>
|
||||
<text x="455" y="1120" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#ffffff">IMSO (Intelligent Multi-Stage)</text>
|
||||
<text x="455" y="1138" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">Adaptive algorithm selection</text>
|
||||
<text x="455" y="1152" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">Surrogate-assisted optimization</text>
|
||||
|
||||
<!-- GNN Surrogates -->
|
||||
<rect x="600" y="1100" width="250" height="60" rx="4" fill="#3730a3" stroke="#818cf8" stroke-width="1"/>
|
||||
<text x="725" y="1120" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#ffffff">GNN Surrogates</text>
|
||||
<text x="725" y="1138" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">Neural network FEA predictions</text>
|
||||
<text x="725" y="1152" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">10x speedup via Zernike GNN</text>
|
||||
|
||||
<!-- SAT v3 -->
|
||||
<rect x="870" y="1100" width="250" height="60" rx="4" fill="#3730a3" stroke="#818cf8" stroke-width="1"/>
|
||||
<text x="995" y="1120" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#ffffff">Self-Aware Turbo (SAT v3)</text>
|
||||
<text x="995" y="1138" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">Uncertainty-aware exploration</text>
|
||||
<text x="995" y="1152" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">Adaptive FEA validation</text>
|
||||
|
||||
<!-- Context Learning -->
|
||||
<rect x="1140" y="1100" width="210" height="60" rx="4" fill="#3730a3" stroke="#818cf8" stroke-width="1"/>
|
||||
<text x="1245" y="1120" text-anchor="middle" font-family="Arial, sans-serif" font-size="11" font-weight="bold" fill="#ffffff">LAC (Learning Core)</text>
|
||||
<text x="1245" y="1138" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">Session insights persistence</text>
|
||||
<text x="1245" y="1152" text-anchor="middle" font-family="Arial, sans-serif" font-size="9" fill="#c7d2fe">Cross-study knowledge</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 41 KiB |
529
docs/reviews/COMPONENT_RELATIONSHIPS.md
Normal file
529
docs/reviews/COMPONENT_RELATIONSHIPS.md
Normal file
@@ -0,0 +1,529 @@
|
||||
# Atomizer Component Relationships
|
||||
|
||||
**Date**: January 2026
|
||||
**Version**: 2.0
|
||||
|
||||
This document details how Atomizer's components interact with each other.
|
||||
|
||||
---
|
||||
|
||||
## 1. Configuration Files Hierarchy
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ atomizer_spec.json (v2.0) │
|
||||
│ SINGLE SOURCE OF TRUTH │
|
||||
└───────────────────────────┬─────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│ Canvas UI │ │ Backend API │ │ Opt Engine │
|
||||
│ (ReactFlow) │ │ (FastAPI) │ │ (Python) │
|
||||
└───────────────┘ └───────────────┘ └───────────────┘
|
||||
```
|
||||
|
||||
### Relationship Table
|
||||
|
||||
| Component | Reads From | Writes To | Frequency |
|
||||
|-----------|------------|-----------|-----------|
|
||||
| Canvas (React) | atomizer_spec.json | atomizer_spec.json | Real-time |
|
||||
| Backend (FastAPI) | atomizer_spec.json | atomizer_spec.json | Per request |
|
||||
| Engine (Python) | atomizer_spec.json | study.db | Per trial |
|
||||
| Claude Agent | atomizer_spec.json | atomizer_spec.json | Per command |
|
||||
|
||||
---
|
||||
|
||||
## 2. Frontend Store Dependencies
|
||||
|
||||
```
|
||||
┌─────────────────────┐
|
||||
│ useSpecStore │
|
||||
│ (Zustand) │
|
||||
│ │
|
||||
│ spec: AtomizerSpec │
|
||||
│ hash: string │
|
||||
│ isDirty: boolean │
|
||||
│ selectedNodeId │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
┌───────────────────┼───────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ CanvasView │ │ NodeConfig │ │ Validation │
|
||||
│ │ │ Panel │ │ Panel │
|
||||
│ Subscribes: │ │ │ │ │
|
||||
│ - spec │ │ Subscribes: │ │ Subscribes: │
|
||||
│ - hash │ │ - spec │ │ - validation │
|
||||
│ - isDirty │ │ - selected │ │ │
|
||||
└──────────────┘ └──────────────┘ └──────────────┘
|
||||
|
||||
┌─────────────────────┐
|
||||
│ useChat │
|
||||
│ (Hook) │
|
||||
│ │
|
||||
│ messages: Message[] │
|
||||
│ isThinking: bool │
|
||||
│ mode: user|power │
|
||||
│ sessionId: string │
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ ChatPanel │
|
||||
│ │
|
||||
│ Displays messages │
|
||||
│ Tool call cards │
|
||||
│ Mode toggle │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
### State Flow
|
||||
|
||||
1. **User edits node** → `useSpecStore.patchSpec(path, value)`
|
||||
2. **Optimistic update** → UI immediately reflects change
|
||||
3. **Async PATCH** → Backend validates and saves
|
||||
4. **WebSocket broadcast** → All clients receive `spec_updated`
|
||||
5. **Hash comparison** → Check for conflicts
|
||||
|
||||
---
|
||||
|
||||
## 3. Backend Service Dependencies
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FastAPI App │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌──────────────────────┼──────────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│ spec.py │ │ claude.py │ │optimization.py│
|
||||
│ (Routes) │ │ (Routes) │ │ (Routes) │
|
||||
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│ SpecManager │◄─────│ClaudeAgent │ │ Runner │
|
||||
│ │ │ │ │ (subprocess) │
|
||||
│ - load_spec() │ │ - tools │ │ │
|
||||
│ - save_spec() │ │ - chat() │ │ - run() │
|
||||
│ - patch_spec()│ │ │ │ - stream() │
|
||||
│ - broadcast() │ │ │ │ │
|
||||
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
|
||||
│ │ │
|
||||
└──────────────────────┼──────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ atomizer_spec.json │
|
||||
│ (Disk) │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
### Service Responsibilities
|
||||
|
||||
| Service | Responsibility | Dependencies |
|
||||
|---------|---------------|--------------|
|
||||
| SpecManager | All spec CRUD, validation, broadcasting | Pydantic models |
|
||||
| ClaudeAgent | AI chat with tools, context building | Anthropic API, SpecManager |
|
||||
| ContextBuilder | System prompt assembly | Study data, canvas state |
|
||||
| SessionManager | WebSocket lifecycle | In-memory store |
|
||||
| Runner | Optimization loop | NX solver, extractors |
|
||||
|
||||
---
|
||||
|
||||
## 4. Optimization Engine Module Dependencies
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ optimization_engine/ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ config/ │ │ core/ │ │ nx/ │
|
||||
│ │ │ │ │ │
|
||||
│spec_models │◄─────│ runner │─────►│ solver │
|
||||
│spec_validator│ │ IMSO │ │ updater │
|
||||
│ migrator │ │ gradient │ │ session │
|
||||
└──────┬──────┘ └──────┬──────┘ └─────────────┘
|
||||
│ │
|
||||
│ ┌──────┴──────┐
|
||||
│ │ │
|
||||
│ ▼ ▼
|
||||
│ ┌─────────────┐ ┌─────────────┐
|
||||
│ │ extractors/ │ │ surrogates │
|
||||
│ │ │ │ │
|
||||
│ │displacement │ │ MLP │
|
||||
│ │ stress │ │ GNN │
|
||||
│ │ zernike │ │ ensemble │
|
||||
│ │ custom │ │ │
|
||||
│ └─────────────┘ └─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────┐ ┌─────────────┐
|
||||
│ study/ │ │ utils/ │
|
||||
│ │ │ │
|
||||
│ creator │ │dashboard_db │
|
||||
│ state │ │trial_manager│
|
||||
│ reset │ │ archiver │
|
||||
└─────────────┘ └─────────────┘
|
||||
```
|
||||
|
||||
### Module Interaction Flow
|
||||
|
||||
```
|
||||
atomizer_spec.json
|
||||
│
|
||||
▼
|
||||
┌───────────────┐
|
||||
│ spec_models │ ← Pydantic validation
|
||||
└───────┬───────┘
|
||||
│
|
||||
▼
|
||||
┌───────────────┐
|
||||
│ runner │ ← Main optimization loop
|
||||
└───────┬───────┘
|
||||
│
|
||||
┌───────┴───────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────┐ ┌─────────┐
|
||||
│ nx/ │ │extract/ │
|
||||
│ solver │ │ors │
|
||||
└────┬────┘ └────┬────┘
|
||||
│ │
|
||||
└─────┬─────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────┐
|
||||
│ study.db │ ← Trial persistence
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. WebSocket Event Flow
|
||||
|
||||
### 5.1 Spec Sync WebSocket
|
||||
|
||||
```
|
||||
Frontend Backend File System
|
||||
│ │ │
|
||||
│ ── PATCH /spec ──────► │ │
|
||||
│ │ ── write ──────────────► │
|
||||
│ │ ◄── confirm ──────────── │
|
||||
│ │ │
|
||||
│ ◄── spec_updated ───── │ ← broadcast to all │
|
||||
│ │ │
|
||||
│ (update local hash) │ │
|
||||
```
|
||||
|
||||
### 5.2 Claude Chat WebSocket
|
||||
|
||||
```
|
||||
Frontend Backend Claude API
|
||||
│ │ │
|
||||
│ ── message + state ──► │ │
|
||||
│ │ ── prompt ─────────────► │
|
||||
│ │ ◄── tool_call ────────── │
|
||||
│ ◄── tool_call ──────── │ │
|
||||
│ │ (execute tool) │
|
||||
│ │ ── tool_result ────────► │
|
||||
│ ◄── tool_result ────── │ ◄── response ─────────── │
|
||||
│ ◄── text ───────────── │ │
|
||||
│ ◄── done ───────────── │ │
|
||||
│ │ │
|
||||
│ (if spec_modified) │ │
|
||||
│ ◄── spec_modified ──── │ │
|
||||
│ (reload spec) │ │
|
||||
```
|
||||
|
||||
### 5.3 Optimization Stream WebSocket
|
||||
|
||||
```
|
||||
Frontend Backend Runner Process
|
||||
│ │ │
|
||||
│ ── start_opt ────────► │ ── spawn ──────────────► │
|
||||
│ │ │
|
||||
│ │ ◄── trial_start ──────── │
|
||||
│ ◄── trial_start ────── │ │
|
||||
│ │ │
|
||||
│ │ ◄── trial_complete ───── │
|
||||
│ ◄── trial_complete ─── │ │
|
||||
│ │ │
|
||||
│ (repeat for N trials) │ │
|
||||
│ │ │
|
||||
│ ◄── optimization_done ─ │ ◄── done ─────────────── │
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Data Transformation Pipeline
|
||||
|
||||
### 6.1 Canvas → Spec → ReactFlow
|
||||
|
||||
```
|
||||
User interacts with Canvas
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ ReactFlow onChange │
|
||||
│ (nodes, edges) │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ useSpecStore.patch() │
|
||||
│ JSONPath modification │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Backend SpecManager │
|
||||
│ Pydantic validation │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ atomizer_spec.json │
|
||||
│ (persisted) │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ spec/converter.ts │
|
||||
│ specToNodes() │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ ReactFlow renders │
|
||||
│ updated canvas │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
### 6.2 Spec → Optimization → Results
|
||||
|
||||
```
|
||||
atomizer_spec.json
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Runner.load_config() │
|
||||
│ Parse spec structure │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Optuna.create_study() │
|
||||
│ Initialize sampler │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
┌────────┴────────┐
|
||||
│ Trial Loop │
|
||||
│ (1 to N) │
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ NX solver.solve() │
|
||||
│ Update expressions │
|
||||
│ Run Nastran │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ extractors.extract() │
|
||||
│ Read OP2 results │
|
||||
└───────────┬─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ TrialManager.save() │
|
||||
│ - params.json │
|
||||
│ - results.json │
|
||||
│ - study.db INSERT │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Error Handling Chain
|
||||
|
||||
```
|
||||
Frontend Error
|
||||
│
|
||||
├──► Validation Error (UI shows inline)
|
||||
│
|
||||
├──► Network Error (retry with exponential backoff)
|
||||
│
|
||||
└──► Conflict Error (409) → reload spec → show diff
|
||||
|
||||
Backend Error
|
||||
│
|
||||
├──► Pydantic ValidationError → 422 with field details
|
||||
│
|
||||
├──► SpecNotFoundError → 404
|
||||
│
|
||||
├──► SpecConflictError → 409 with current hash
|
||||
│
|
||||
└──► Internal Error → 500 with traceback (dev mode)
|
||||
|
||||
Engine Error
|
||||
│
|
||||
├──► NX Connection Error → retry with backoff
|
||||
│
|
||||
├──► Solver Error → mark trial FAILED, continue
|
||||
│
|
||||
├──► Extractor Error → log warning, use fallback
|
||||
│
|
||||
└──► Database Error → rollback transaction
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Security Boundaries
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ User Browser │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ React Application │ │
|
||||
│ │ - No direct file access │ │
|
||||
│ │ - All data via REST/WebSocket │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
(HTTP/WS)
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ FastAPI Backend │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ Input Validation │ │
|
||||
│ │ - Pydantic schema validation │ │
|
||||
│ │ - Path sanitization │ │
|
||||
│ │ - Rate limiting (optional) │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ File System Access │ │
|
||||
│ │ - Restricted to studies/ directory │ │
|
||||
│ │ - No path traversal (../) │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Optimization Engine │
|
||||
│ │
|
||||
│ - Runs as separate process │
|
||||
│ - Limited to study directory │
|
||||
│ - NX subprocess sandboxed │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Deployment Topology
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Development Environment │
|
||||
│ │
|
||||
│ Frontend: npm run dev → localhost:5173 │
|
||||
│ Backend: uvicorn --reload → localhost:8001 │
|
||||
│ NX: Local NX installation │
|
||||
│ Claude: Anthropic API (cloud) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Production Environment │
|
||||
│ │
|
||||
│ Frontend: Static files served by Nginx │
|
||||
│ Backend: Gunicorn + Uvicorn workers │
|
||||
│ NX: Licensed NX server │
|
||||
│ Database: SQLite (can upgrade to PostgreSQL) │
|
||||
│ Claude: Anthropic API (cloud) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Version Compatibility Matrix
|
||||
|
||||
| Component | Required Version | Notes |
|
||||
|-----------|-----------------|-------|
|
||||
| Python | 3.10+ | Type hints, async |
|
||||
| Node.js | 18+ | ES modules |
|
||||
| React | 18+ | Concurrent features |
|
||||
| FastAPI | 0.100+ | Pydantic v2 |
|
||||
| Pydantic | 2.0+ | New validation API |
|
||||
| ReactFlow | 11+ | Custom nodes |
|
||||
| Optuna | 3.0+ | Trial management |
|
||||
| NX | 12+ (tested 2306) | NX Open API |
|
||||
| Claude | claude-3-5-sonnet | Tool use |
|
||||
|
||||
---
|
||||
|
||||
## 11. Testing Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Test Pyramid │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────┐
|
||||
│ E2E │ ← Playwright/Cypress
|
||||
│ (few) │ Full user flows
|
||||
└──────┬──────┘
|
||||
│
|
||||
┌────────────┴────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────┐ ┌─────────────┐
|
||||
│ Integration │ │ Integration │
|
||||
│ (frontend) │ │ (backend) │
|
||||
└──────┬──────┘ └──────┬──────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────┐ ┌─────────────┐
|
||||
│ Unit │ │ Unit │
|
||||
│ (React) │ │ (Python) │
|
||||
│ Jest/Vitest│ │ pytest │
|
||||
└─────────────┘ └─────────────┘
|
||||
```
|
||||
|
||||
### Test Coverage Goals
|
||||
|
||||
| Layer | Target | Current |
|
||||
|-------|--------|---------|
|
||||
| Unit (Python) | 80% | ~70% |
|
||||
| Unit (React) | 70% | ~50% |
|
||||
| Integration | 60% | ~40% |
|
||||
| E2E | Key flows | Manual |
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Atomizer's architecture is built on these core principles:
|
||||
|
||||
1. **Single Source of Truth**: All configuration in `atomizer_spec.json`
|
||||
2. **Type Safety**: Pydantic on backend, TypeScript on frontend
|
||||
3. **Real-time Sync**: WebSocket broadcast for multi-client coordination
|
||||
4. **Optimistic Updates**: Responsive UI with async persistence
|
||||
5. **Modular Engine**: Pluggable extractors, algorithms, surrogates
|
||||
|
||||
The architecture is robust for its intended use case (engineering optimization) and can scale horizontally by:
|
||||
- Adding more backend workers
|
||||
- Sharding studies across directories
|
||||
- Upgrading to distributed database (PostgreSQL)
|
||||
- Adding Redis for session state
|
||||
Reference in New Issue
Block a user