Files
Atomizer/docs/plans/CANVAS_DEEP_FIX_INVESTIGATION.md
Anto01 ac5e9b4054 docs: Comprehensive documentation update for Dashboard V3 and Canvas
## Documentation Updates
- DASHBOARD.md: Updated to V3.0 with Canvas V3 features, file browser, introspection
- DASHBOARD_IMPLEMENTATION_STATUS.md: Marked Canvas V3 features as COMPLETE
- CANVAS.md: New comprehensive guide for Canvas Builder V3 with all features
- CLAUDE.md: Added dashboard quick reference and Canvas V3 features

## Canvas V3 Features Documented
- File Browser: Browse studies directory for model files
- Model Introspection: Auto-discover expressions, solver type, dependencies
- One-Click Add: Add expressions as design variables instantly
- Claude Bug Fixes: WebSocket reconnection, SQL errors resolved
- Health Check: /api/health endpoint for monitoring

## Backend Services
- NX introspection service with expression discovery
- File browser API with type filtering
- Claude session management improvements
- Context builder enhancements

## Frontend Components
- FileBrowser: Modal for file selection with search
- IntrospectionPanel: View discovered model information
- ExpressionSelector: Dropdown for design variable configuration
- Improved chat hooks with reconnection logic

## Plan Documents
- Added RALPH_LOOP_CANVAS_V2/V3 implementation records
- Added ATOMIZER_DASHBOARD_V2_MASTER_PLAN
- Added investigation and sync documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 20:48:58 -05:00

9.6 KiB

Canvas Deep Fix Investigation

Date: January 16, 2026 Status: IMPLEMENTATION COMPLETE


Executive Summary

Four critical issues have been identified that are blocking Canvas functionality:

# Issue Root Cause Severity
1 Claude Chat Not Working asyncio.create_subprocess_exec fails on Windows CRITICAL
2 Expressions Can't Connect to Model ModelNode has inputs={0} - no input handle CRITICAL
3 File Browser Only Shows Studies Web API can't access OS file system HIGH
4 Introspection is Fake Only reads config files, not actual NX models HIGH

Issue 1: Claude Chat NotImplementedError

Root Cause

# session_manager.py line 138
process = await asyncio.create_subprocess_exec(...)

On Windows, asyncio.create_subprocess_exec raises NotImplementedError because Windows doesn't support the ProactorEventLoop subprocess methods the same way Unix does.

Evidence

Traceback:
  File "session_manager.py", line 138, in create_session
    process = await asyncio.create_subprocess_exec(
  File "asyncio\subprocess.py", line 218, in create_subprocess_exec
  File "asyncio\base_events.py", line 498, in _make_subprocess_transport
    raise NotImplementedError
NotImplementedError

Solution

Replace async subprocess with synchronous subprocess + ThreadPoolExecutor:

import subprocess
from concurrent.futures import ThreadPoolExecutor

executor = ThreadPoolExecutor(max_workers=4)

async def create_session(...):
    # Instead of asyncio.create_subprocess_exec
    loop = asyncio.get_event_loop()
    process = await loop.run_in_executor(
        executor,
        lambda: subprocess.Popen(
            ["claude", "--print", ...],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=str(ATOMIZER_ROOT),
        )
    )

OR - Simpler approach: Skip session-based subprocess entirely, use HTTP streaming for chat:

The /api/claude/chat/stream endpoint already works (it uses claude_cli_agent.py which runs Claude one-shot). The WebSocket session approach is over-engineered for the use case.

Fix Strategy

  1. Make create_session return a "virtual" session (no subprocess)
  2. Route all messages through HTTP streaming endpoint
  3. Keep conversation history in ConversationStore database
  4. WebSocket just wraps the HTTP streaming calls

Issue 2: Expressions Can't Connect to Model

Root Cause

ModelNode.tsx:

<BaseNode {...props} icon={...} iconColor="text-blue-400" inputs={0}>

inputs={0} means Model has NO input handle - nothing can connect TO it!

DesignVarNode.tsx:

<BaseNode {...props} icon={...} iconColor="text-emerald-400">

Uses defaults (inputs=1, outputs=1) but DesignVar should have:

  • inputs=0 (it's a source node)
  • outputs=1 (connects to Model)

Visual Problem

Current (WRONG):
  DesignVar ←─ Model ──→ Solver
     ↑           ↓
  (has input) (has output only)

Should be:
  DesignVar ──→ Model ──→ Solver
     ↓           ↑↓
  (output)   (input & output)

Fix Required

ModelNode.tsx - Add input handle:

<BaseNode {...props} icon={...} iconColor="text-blue-400" inputs={1} outputs={1}>

DesignVarNode.tsx - Remove input handle:

<BaseNode {...props} icon={...} iconColor="text-emerald-400" inputs={0} outputs={1}>

SurrogateNode.tsx - Should be terminal (no output):

<BaseNode {...props} icon={...} iconColor="text-pink-400" inputs={1} outputs={0}>

Issue 3: File Browser Only Shows Studies Folder

Root Cause

The current FileBrowser.tsx uses fetch to /api/files/list which only lists files within the studies/ directory. The user wants:

  1. Native OS file picker to select files from ANYWHERE
  2. Import selected files into the study folder
  3. Copy all related files (.prt, .sim, .fem, _i.prt, etc.)

Web Browser Limitation

Browsers can't access the local file system directly for security. Options:

Option A: File System Access API (Chrome/Edge only)

const handle = await window.showOpenFilePicker({
  types: [{ description: 'NX Files', accept: { '*/*': ['.sim', '.prt', '.fem'] } }]
});
const file = await handle.getFile();
// Upload to backend

Option B: Traditional File Input

<input type="file" accept=".sim,.prt,.fem,.afem" onChange={handleFileUpload} />

Then upload to backend which saves to study folder.

Option C: Backend Path Input + Validation User enters full Windows path (e.g., C:\NX_Models\bracket.prt), backend validates and copies.

Combine B + C:

  1. File input for direct upload (drag & drop)
  2. Path input for network drives/existing paths
  3. Backend endpoint to copy/import files

Issue 4: Introspection is Fake

Root Cause

Current nx_introspection.py does NOT actually read NX files. It only:

  • Reads optimization_config.json for existing design variables
  • Infers expressions based on folder names ("mirror" → suggest mirror expressions)
  • Guesses solver type from file names

What Real Introspection Needs

For .prt files (NX Part):

  • Use NX Open API to read expressions
  • Get expression names, values, units, formulas
  • Requires NX to be installed and licensed

For .sim files (Simulation):

  • Parse XML-like structure or use NX Open
  • Get solver type, boundary conditions, loads
  • Identify linked .fem and .prt files

For .fem files (FEM):

  • Get mesh statistics (nodes, elements)
  • Material properties
  • Element types used

For .op2 files (Results):

  • Use PyNastran to read binary results
  • Extract displacement, stress, frequency data
  • Get node/element IDs for specific extractions

Implementation Approach

Phase 1: File Discovery (no NX needed)

def discover_related_files(sim_path: Path) -> List[Dict]:
    """Find all related files by naming convention"""
    # model_sim1.sim → model.prt, model_fem1.fem, model_fem1_i.prt

Phase 2: Config-based Expression Discovery

def discover_expressions_from_config(study_dir: Path) -> List[Dict]:
    """Read optimization_config.json for design variables"""

Phase 3: NX Open Integration (requires NX)

def introspect_with_nx_open(prt_path: Path) -> Dict:
    """Use NX Open API to read actual expressions"""
    # This requires NX to be running
    # Use the existing nx_journals/ infrastructure

Phase 4: OP2 Result Analysis (PyNastran)

def analyze_op2_results(op2_path: Path) -> Dict:
    """Read OP2 file to discover available result types"""
    from pyNastran.op2.op2 import OP2
    op2 = OP2()
    op2.read_op2(str(op2_path))
    # Return available subcases, result types, etc.

Implementation Plan

Phase 1: Fix Claude Chat (CRITICAL - 30 min)

  1. Modify create_session to not spawn subprocess
  2. Keep session metadata in database only
  3. Route all messages through HTTP streaming
  4. WebSocket wraps HTTP calls

Phase 2: Fix Node Handles (CRITICAL - 15 min)

  1. Update ModelNode.tsx: inputs={1}
  2. Update DesignVarNode.tsx: inputs={0}, outputs={1}
  3. Update SurrogateNode.tsx: outputs={0}
  4. Test connections work correctly

Phase 3: Native File Import (HIGH - 45 min)

  1. Add file upload input to FileBrowser
  2. Create backend /api/files/upload endpoint
  3. Add path input with validation
  4. Create /api/files/import for path-based import
  5. Copy all related files to study folder

Phase 4: Real Introspection Service (HIGH - 2 hours)

  1. File discovery by naming convention
  2. OP2 analysis with PyNastran
  3. NX Open integration (optional, requires NX running)
  4. Return comprehensive file metadata

Phase 5: Integration Testing (30 min)

  1. Test complete workflow: Select model → Introspect → Add Design Vars → Connect → Execute
  2. Fix any remaining issues

Files to Modify

Backend

  • session_manager.py - Fix Windows subprocess issue
  • files.py - Add upload/import endpoints
  • nx_introspection.py - Real introspection logic

Frontend

  • ModelNode.tsx - Add input handle
  • DesignVarNode.tsx - Remove input, keep output
  • SurrogateNode.tsx - Remove output
  • FileBrowser.tsx - Add file upload, path input
  • IntrospectionPanel.tsx - Display real introspection data

Estimated Total Time: 4-5 hours


Implementation Summary (Completed)

Phase 1: Claude Chat Windows Fix

File: atomizer-dashboard/backend/api/services/session_manager.py

  • Replaced asyncio.create_subprocess_exec with subprocess.Popen
  • Used ThreadPoolExecutor with run_in_executor() for async compatibility
  • Made sessions stateless (no persistent subprocess)
  • Each message handled via one-shot CLI call with 5-minute timeout

Phase 2: Node Handles

Files:

  • ModelNode.tsx: Changed inputs={0} to inputs={1} (now accepts connections)
  • DesignVarNode.tsx: Added inputs={0} outputs={1} (source node)

Phase 3: Native File Import

Files:

  • files.py: Added /validate-path, /import-from-path, /upload endpoints
  • FileBrowser.tsx: Complete rewrite with 3 tabs:
    • Browse Studies (existing)
    • Import Path (paste Windows path, validate, import related files)
    • Upload Files (drag & drop)

Phase 4: Real NX Introspection

File: atomizer-dashboard/backend/api/services/nx_introspection.py

  • Added PyNastran OP2 parsing (displacements, eigenvectors, stress)
  • BDF/DAT file analysis (mass, grid count, element counts, solver type)
  • Study database queries for expression discovery
  • Related file discovery by naming convention
  • Result file discovery with trial folder detection