# Router / Intelligent Supervisor Layer for blender-ai-mcp

## Goal

- **Primary**: Act as an intelligent supervisor layer ABOVE LLM tool calls
- Intercept, correct, and expand tool calls generated by LLM
- Analyze scene context and geometry patterns to make informed decisions
- Work offline, without the need for an external LLM
- Override incorrect LLM decisions when necessary
- Expand single tool calls into complete workflows
- Ensure geometric consistency and proper sequencing

------------------------------------------------------------

## Key Concept: Router as LLM Supervisor

```
┌─────────────────────────────────────────────────────────────────┐
│                    TRADITIONAL APPROACH                         │
│   User → LLM → tool_call → Blender                             │
│   (LLM decides everything, errors propagate)                    │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                    NEW ARCHITECTURE                             │
│   User → LLM → tool_call → ROUTER → corrected_tools → Blender  │
│                              ↑                                  │
│                    [Scene Context Analyzer]                     │
│                    [Geometry Pattern Detector]                  │
│                    [Tool Correction Engine]                     │
│                    [Workflow Expansion Engine]                  │
└─────────────────────────────────────────────────────────────────┘
```

**Router is NOT just an "intent matcher".**
**Router is an intelligent supervisor that:**
- Intercepts LLM tool calls
- Corrects parameters and adds missing steps
- Expands single tools into complete workflows
- Overrides incorrect decisions
- Analyzes scene state before execution
- Detects geometric patterns and applies rules

Important:
- ~~Router is the source of truth for everything.~~
- Router is the **policy and safety layer**.
- The source of truth for actual Blender state should be inspection tools and addon-returned state.
- FastMCP should own discovery/visibility concerns.
- LaBSE should own semantic retrieval concerns.

See [RESPONSIBILITY_BOUNDARIES.md](./RESPONSIBILITY_BOUNDARIES.md).

------------------------------------------------------------

## System Structure / Components

```
User prompt (string)
        │
        ▼
┌───────────────────────────────────────┐
│            LLM (Claude/GPT)           │
│   Generates initial tool_call(s)      │
└───────────────────────────────────────┘
        │
        ▼
┌═══════════════════════════════════════════════════════════════┐
║                    ROUTER SUPERVISOR LAYER                     ║
╠═══════════════════════════════════════════════════════════════╣
║  ┌─────────────────────────────────────────────────────────┐  ║
║  │  1. TOOL INTERCEPTOR                                     │  ║
║  │     Captures all LLM tool_calls before execution         │  ║
║  └─────────────────────────────────────────────────────────┘  ║
║                          │                                     ║
║                          ▼                                     ║
║  ┌─────────────────────────────────────────────────────────┐  ║
║  │  2. SCENE CONTEXT ANALYZER                               │  ║
║  │     Reads: objects, bbox, topology, relations, names     │  ║
║  └─────────────────────────────────────────────────────────┘  ║
║                          │                                     ║
║                          ▼                                     ║
║  ┌─────────────────────────────────────────────────────────┐  ║
║  │  3. GEOMETRY PATTERN DETECTOR                            │  ║
║  │     Detects: towers, bases, symmetry, tapers, screens    │  ║
║  └─────────────────────────────────────────────────────────┘  ║
║                          │                                     ║
║                          ▼                                     ║
║  ┌─────────────────────────────────────────────────────────┐  ║
║  │  4. TOOL CORRECTION ENGINE                               │  ║
║  │     Fixes: params, mode, selection, missing steps        │  ║
║  └─────────────────────────────────────────────────────────┘  ║
║                          │                                     ║
║                          ▼                                     ║
║  ┌─────────────────────────────────────────────────────────┐  ║
║  │  5. TOOL OVERRIDE ENGINE                                 │  ║
║  │     Can: replace tool, expand to workflow, add steps     │  ║
║  └─────────────────────────────────────────────────────────┘  ║
║                          │                                     ║
║                          ▼                                     ║
║  ┌─────────────────────────────────────────────────────────┐  ║
║  │  6. WORKFLOW EXPANSION ENGINE                            │  ║
║  │     Transforms: 1 tool → N tools (complete sequence)     │  ║
║  └─────────────────────────────────────────────────────────┘  ║
╚═══════════════════════════════════════════════════════════════╝
        │
        ▼
[ MCP Server ] (tool invocation)
        │
        ▼
[ Blender (bpy) ] — operation execution
        │
        ▼
[ Result / Feedback ]
        └─ optionally: user feedback → to logs / training data
```

**Components:**
- Tool Interceptor (LLM tool call capture)
- Scene Context Analyzer
- Geometry Pattern Detector
- Tool Correction Engine
- Tool Override Engine
- Workflow Expansion Engine
- Metadata for all tools
- Intent-Matcher / Classifier (for offline routing)
- Planner / Sequencer
- Error Firewall (blocks invalid operations)
- Feedback / Learning module

------------------------------------------------------------

## Metadata (tools definition)

File: `server/router/infrastructure/tools_metadata/<category>/<tool>.json`

Example:

```json
{
  "tool_name": "mesh_extrude_region",
  "category": "mesh",
  "keywords": ["extrude", "pull", "push", "face", "extend"],
  "description": "Extrudes selected geometry and optionally moves it.",
  "sample_prompts": [
    "extrude face by 0.2",
    "extend the face downward",
    "pull the top face outwards"
  ],
  "parameters": {
    "move": {
      "type": "list[float]",
      "default": [0.0, 0.0, 0.2],
      "description": "Optional [x, y, z] move applied after extrusion."
    }
  }
}
```

------------------------------------------------------------

## Router / Intent-Matcher Implementation Options

--------------------------------
### 1) Rules + classifier (TF-IDF, SVM, LogisticRegression)

Libraries:
- scikit-learn
- regex
- rapidfuzz

Flow:
- prompt → normalization
- tf-idf → vector
- classifier → label (e.g., "extrude_mesh")
- mapping label → tool

Pros: fast, offline, deterministic
Cons: sensitive to keywords

--------------------------------
### 2) Embedding + vector lookup (FAISS)

Libraries:
- sentence-transformers
- faiss

Flow:
- prompt → embedding
- embedding → comparison to sample_prompts/tool embeddings
- closest tool, if distance < threshold

Pros: generalizes semantics better
Cons: depends on embedding quality

------------------------------------------------------------

## Embedding Model

**LaBSE (Language-agnostic BERT Sentence Embedding)**

| Property | Value |
|----------|-------|
| Model | `sentence-transformers/LaBSE` |
| Parameters | 471M |
| Embedding dim | 768D |
| Languages | 109 (including PL, EN, DE, FR, ES, ...) |
| RAM usage | ~1.8 GB |

Why LaBSE:
- Best cross-lingual semantic matching (Google Research)
- Single model for all languages - no translation step needed
- Handles slang, abbreviations, non-standard phrases
- "pull the wall" ≈ "extrude the face" ≈ "extrude face"

Use LaBSE here for:
- semantic workflow matching
- semantic modifier matching
- multilingual prompt generalization

Do not use LaBSE here as the authority for:
- scene truth
- geometry correctness
- safe execution policy
- final validation

Usage:
```python
from sentence_transformers import SentenceTransformer

model = SentenceTransformer('sentence-transformers/LaBSE')
embedding = model.encode("create a 2x2x2 cube")
# → matches "create a 2x2x2 cube" semantically
```

Note: 1.8GB RAM is acceptable for modern desktop/server environments.

------------------------------------------------------------

## Planner / Sequencer (workflow)

You can define workflows in YAML:

intents:
  create_phone:
    - modeling_create_primitive
    - modeling_transform_object
    - mesh_bevel
    - mesh_inset
    - mesh_extrude_region
    - material_assign

Example: prompt "make a phone" → intent "create_phone" → above sequence of tools.

------------------------------------------------------------

## Learning / Feedback

Mechanism:
- After each invocation, save: prompt, tool used, result, optionally user feedback.
- Store data in JSON file or SQLite.
- Every X executed prompts: retrain classifier or rebuild embedding index.

Possible training types:
- Adding new prompt→tool examples
- Hard negatives (incorrect matching cases)
- User correction (if user corrects tool)

------------------------------------------------------------

## Step-by-Step Implementation

1. Prepare tools_metadata.json with full description of 80 tools.
2. Implement Intent-Matcher:
   - Simple version: TF-IDF + SVM (easiest)
   - Advanced: embedding + FAISS
3. Implement Tool Resolver / Planner.
4. Create route(prompt) → list(tool_calls) function.
5. Add logging and feedback-learning mechanism.
6. Create tests for router (unit + integration).
7. (Optionally) Add fallback chain:
   - regex → fuzzy → classifier → embeddings

------------------------------------------------------------

## Router Architecture (text diagram)

prompt
  ↓
preprocess text → normalize, tokenize
  ↓
intent-matcher (classifier + embeddings + fuzzy)
  ↓
intent
  ↓
tool resolver (metadata + mapping)
  ↓
workflow (list of tools)
  ↓
MCP server
  ↓
Blender API
  ↓
result

------------------------------------------------------------

## Recommended Plan

PHASE 1 – create 80 tools
PHASE 2 – prepare tools_metadata.json
PHASE 3 – add Intent-Matcher (TF-IDF → easy and stable)
PHASE 4 – add embeddings (optional, for better quality)
PHASE 5 – add Planner / Sequencer
PHASE 6 – add feedback-learning
PHASE 7 – fine-tune thresholds, tests and fallback logic

------------------------------------------------------------

## NEW: Tool Interceptor Layer

**Purpose**: Capture all LLM tool calls before execution.

```
LLM generates:
  tool_call("mesh_extrude_region", {"move": [0.0, 0.0, 0.5]})

Interceptor captures:
  {
    "source": "llm",
    "tool": "mesh_extrude_region",
    "params": {"move": [0.0, 0.0, 0.5]},
    "timestamp": "...",
    "context": {...}
  }

Then passes to correction/override engines.
```

**Responsibilities:**
- Capture tool name and parameters
- Log original LLM intent
- Pass to Scene Context Analyzer
- Enable post-processing pipeline

------------------------------------------------------------

## NEW: Scene Context Analyzer

**Purpose**: Read current Blender scene state before making decisions.

**Data Collected:**
| Category | Data Points |
|----------|-------------|
| Objects | Names, types, count, active object |
| Bounding Box | Dimensions, center, volume |
| Topology | Vertex/edge/face count, ngons, tris |
| Relations | Parent-child, collections, hierarchy |
| Transform | Location, rotation, scale, pivot |
| Proportions | Height/width ratio, aspect ratio |
| Selection | Current selection state, mode |
| Materials | Assigned materials, slots |

**Example Analysis:**
```python
scene_context = {
    "active_object": "Cube",
    "dimensions": {"x": 1.0, "y": 2.0, "z": 0.1},
    "proportions": {
        "aspect_xy": 0.5,  # wide rectangle
        "is_flat": True,   # z << x,y
        "is_tall": False
    },
    "topology": {
        "vertices": 8,
        "faces": 6,
        "is_manifold": True
    },
    "mode": "OBJECT",
    "selection": ["Cube"]
}
```

**Decision Impact:**
- If `is_flat` → likely phone/tablet → suggest screen cutout workflow
- If `is_tall` → likely tower/pillar → suggest taper workflow
- If `has_legs` pattern → suggest furniture workflow

------------------------------------------------------------

## NEW: Geometry Pattern Detector

**Purpose**: Recognize common 3D modeling patterns and structures.

**Detected Patterns:**

| Pattern | Detection Criteria | Suggested Workflow |
|---------|-------------------|-------------------|
| Tower/Pillar | height >> width, centered | taper, subdivide, detail |
| Phone/Tablet | flat, rectangular, ~0.1 thickness | screen cutout, bevel edges |
| Table/Desk | flat top + 3-4 legs below | leg extrusion, surface detail |
| Tree | trunk + branching structure | organic subdivision |
| Character Base | humanoid proportions | armature suggestion |
| Wheel | circular, flat | spoke pattern, tire tread |
| Building | stacked floors pattern | window array, facade |

**Pattern Recognition Flow:**
```
Object dimensions → Ratio analysis → Pattern matching → Workflow suggestion
     ↓                   ↓                ↓                  ↓
   bbox            height/width      "phone-like"      screen_cutout_workflow
```

**Example Detections:**
```python
patterns = {
    "tower_like": dimensions.z > dimensions.x * 3,
    "phone_like": dimensions.z < 0.15 and 0.4 < dimensions.x/dimensions.y < 0.6,
    "table_like": has_flat_top and count_legs_below() in [3, 4],
    "symmetric": is_symmetric_x() or is_symmetric_y(),
    "needs_taper": is_tower_like and not has_taper(),
    "needs_bevel": has_sharp_edges() and is_product_design()
}
```

------------------------------------------------------------

## NEW: Tool Correction Engine

**Purpose**: Fix incorrect or incomplete LLM tool calls.

**Correction Types:**

### 1. Parameter Correction
```python
# LLM sends:
mesh_extrude_region(move=[0.0, 0.0, -5.0])  # too large magnitude

# Router corrects:
mesh_extrude_region(move=[0.0, 0.0, -0.5])  # clamped to reasonable value
```

### 2. Mode Correction
```python
# LLM sends mesh tool in OBJECT mode
# Router adds:
[
    system_set_mode("EDIT"),
    mesh_extrude_region(move=[0.0, 0.0, 0.5]),
    system_set_mode("OBJECT")  # restore
]
```

### 3. Selection Correction
```python
# LLM sends extrude without selection
# Router adds:
[
    mesh_select(action="all"),
    mesh_extrude_region(move=[0.0, 0.0, 0.5])
]
```

### 4. Missing Steps Insertion
```python
# LLM sends only extrude for screen cutout
# Router expands to:
[
    mesh_select_targeted(action="by_location", axis="Z", min_coord=0.0, max_coord=9999.0, element_type="FACE"),
    mesh_inset(thickness=0.1),
    mesh_extrude_region(move=[0.0, 0.0, -0.05]),
    mesh_bevel(offset=0.01, segments=2)
]
```

### 5. Value Clamping
```python
# Parameter limits based on context
corrections = {
    "bevel_offset": clamp(value, 0.001, bbox.min_dimension * 0.5),
    "extrude_move_z": clamp(value, -bbox.z, bbox.z * 2),
    "subdivisions": clamp(value, 1, 6),
    "inset_thickness": clamp(value, 0.001, face_size * 0.4)
}
```

------------------------------------------------------------

## NEW: Tool Override Engine

**Purpose**: Replace LLM tool calls with better alternatives.

**Override Scenarios:**

### 1. Tool Replacement
```python
# LLM uses wrong tool
llm_call: mesh_subdivide(number_cuts=10)  # too many cuts
override: mesh_subdivide(number_cuts=2)   # reasonable

# Or complete replacement
llm_call: mesh_extrude_region(move=[0.0, 0.0, 0.5])   # for screen
override: screen_cutout_workflow()   # better approach
```

### 2. Workflow Replacement
```python
# LLM: single tool for complex task
llm_call: mesh_bevel(offset=0.1)

# Router detects "phone" pattern, overrides with:
override: [
    mesh_select_targeted(action="loop", edge_index=0),  # requires a valid edge_index
    mesh_bevel(offset=0.02, segments=3),
    mesh_select(action="none"),
    mesh_select_targeted(action="by_location", axis="Z", min_coord=0.0, max_coord=9999.0, element_type="FACE"),
    mesh_inset(thickness=0.05),
    mesh_extrude_region(move=[0.0, 0.0, -0.02])
]
```

### 3. Complete Ignore
```python
# LLM sends invalid tool for current state
llm_call: mesh_extrude_region()  # but object has no faces selected

# Router ignores and generates own sequence
override: [
    mesh_select(action="all"),
    mesh_extrude_region(move=[0.0, 0.0, 0.5])
]
```

------------------------------------------------------------

## NEW: Workflow Expansion Engine

**Purpose**: Transform single tool calls into complete workflows.

**Expansion Examples:**

### Example 1: Simple Extrude → Full Face Operation
```python
# Input (LLM)
mesh_extrude_region(move=[0.0, 0.0, 0.4])

# Output (Router Expanded)
[
    mesh_select(action="all"),
    mesh_inset(thickness=0.05),
    mesh_extrude_region(move=[0.0, 0.0, 0.4]),
    mesh_bevel(offset=0.01, segments=2)
]
```

### Example 2: "Create Phone" Intent → Full Workflow
```python
# Input (LLM or User intent)
"create_phone"

# Output (Router Workflow)
[
    modeling_create_primitive(type="CUBE"),
    modeling_transform(scale=[0.4, 0.8, 0.05]),
    system_set_mode("EDIT"),
    mesh_select(action="all"),
    mesh_bevel(offset=0.02, segments=3),
    mesh_select(action="none"),
    mesh_select_targeted(action="by_location", axis="Z", min_coord=0.0, max_coord=9999.0, element_type="FACE"),
    mesh_inset(thickness=0.03),
    mesh_extrude_region(move=[0.0, 0.0, -0.02]),
    system_set_mode("OBJECT"),
    material_create(name="PhoneBody", color=[0.1, 0.1, 0.1]),
    material_assign(object="Cube", material="PhoneBody")
]
```

### Example 3: Pattern-Based Expansion
```python
# Router detects: object is tower-like (height >> width)
# LLM sends: mesh_subdivide()

# Router expands based on pattern:
[
    mesh_subdivide(number_cuts=2),
    mesh_select_targeted(action="loop", edge_index=1),  # requires a valid edge_index
    mesh_transform_selected(scale=[1.2, 1.2, 1.0]),  # slight bulge
    mesh_select_targeted(action="loop", edge_index=2),  # requires a valid edge_index
    mesh_transform_selected(scale=[0.8, 0.8, 1.0]),  # taper top
]
```

------------------------------------------------------------

## NEW: Router Priority Logic (Decision Hierarchy)

**Execution Order:**

```
┌─────────────────────────────────────────────────────────────┐
│  PRIORITY 1: Safety Checks                                  │
│  - Block destructive operations without confirmation        │
│  - Validate object exists                                   │
│  - Check mode compatibility                                 │
├─────────────────────────────────────────────────────────────┤
│  PRIORITY 2: Scene Context Analysis                         │
│  - Read current state                                       │
│  - Detect patterns                                          │
│  - Analyze proportions                                      │
├─────────────────────────────────────────────────────────────┤
│  PRIORITY 3: LLM Intent Interpretation                      │
│  - Parse tool call                                          │
│  - Extract parameters                                       │
│  - Understand goal                                          │
├─────────────────────────────────────────────────────────────┤
│  PRIORITY 4: Tool Correction                                │
│  - Fix parameters                                           │
│  - Add missing mode switches                                │
│  - Insert selection steps                                   │
├─────────────────────────────────────────────────────────────┤
│  PRIORITY 5: Workflow Expansion                             │
│  - Pattern-based expansion                                  │
│  - Complete workflow generation                             │
│  - Add finishing steps                                      │
├─────────────────────────────────────────────────────────────┤
│  PRIORITY 6: Router Rules Application                       │
│  - Proportion rules                                         │
│  - Symmetry enforcement                                     │
│  - Style consistency                                        │
├─────────────────────────────────────────────────────────────┤
│  PRIORITY 7: Override Decision                              │
│  - Replace if better workflow exists                        │
│  - Ignore if invalid                                        │
│  - Generate alternative                                     │
├─────────────────────────────────────────────────────────────┤
│  PRIORITY 8: Execution                                      │
│  - Execute final tool sequence                              │
│  - Collect results                                          │
│  - Log for learning                                         │
└─────────────────────────────────────────────────────────────┘
```

------------------------------------------------------------

## NEW: Error Firewall

**Purpose**: Block invalid operations before they reach Blender.

**Blocked Operations:**
```python
firewall_rules = {
    # Mode violations
    "mesh_tool_in_object_mode": "Auto-switch to EDIT mode",
    "object_tool_in_edit_mode": "Auto-switch to OBJECT mode",

    # Selection violations
    "extrude_without_selection": "Auto-select or block",
    "bevel_on_no_edges": "Block with message",

    # Parameter violations
    "negative_subdivision": "Clamp to 1",
    "bevel_larger_than_object": "Clamp to max safe value",

    # State violations
    "operation_on_deleted_object": "Block with error",
    "modifier_on_non_mesh": "Block with message"
}
```

------------------------------------------------------------

## Summary

Router as Intelligent Supervisor will:
- **Intercept** all LLM tool calls before execution
- **Analyze** scene context and geometry patterns
- **Correct** incorrect parameters and missing steps
- **Expand** single tools into complete workflows
- **Override** bad decisions with better alternatives
- **Firewall** invalid operations before execution
- Work **100% offline** for core routing
- Provide **deterministic, reliable** tool execution
- Act as **"intelligent supervisor"** not just "matcher"

**Key Difference from Traditional Router:**
```
Traditional: prompt → intent → tool → execute
New:         prompt → LLM → tool → ROUTER → corrected_workflow → execute
                                      ↑
                              [Scene Analysis]
                              [Pattern Detection]
                              [Correction Engine]
                              [Override Engine]
                              [Error Firewall]
```
