Spaces:
Sleeping
Sleeping
Commit ·
dacf755
1
Parent(s): 7d49731
docs: add generation pipeline, 3MF export, and download panel to planning spec
Browse files
docs/superpowers/specs/2026-04-12-planning-review-gate-design.md
CHANGED
|
@@ -374,35 +374,203 @@ When the scoring threshold triggers in chat mode, an interactive plan card appea
|
|
| 374 |
- Only one plan card active at a time
|
| 375 |
- All labels go through `I18N` / `t()` for i18n support
|
| 376 |
|
| 377 |
-
##
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
|
| 379 |
| File | Change |
|
| 380 |
|------|--------|
|
| 381 |
| `agents/design_state.py` | Add `phase`, `plan` fields to `DesignState`; add `DesignPlan` model; add `compute_score()` function |
|
| 382 |
| `agents/crew_orchestrator.py` | Add phase branching, plan generation, plan trigger keyword detection, approved-phase context injection, routing override |
|
| 383 |
-
| `agents/base.py` | No changes (interface unchanged) |
|
| 384 |
| `config/settings.py` | Add `PlanningConfig` model, add `planning` field to `Settings` |
|
| 385 |
| `config/config.yaml` | Add `planning` section with threshold, weights, caps, keywords, approved_agents |
|
| 386 |
-
| `server/routes.py` | Add `POST /api/plan/approve` and `POST /api/plan/reject` endpoints
|
| 387 |
-
| `
|
|
|
|
|
|
|
| 388 |
|
| 389 |
## Files Not Changed
|
| 390 |
|
| 391 |
| File | Reason |
|
| 392 |
|------|--------|
|
| 393 |
| `agents/orchestrator.py` (MockChatBackend) | Mock backend does not need planning — it's for testing only |
|
|
|
|
| 394 |
| `agents/routing.py` | Routing logic unchanged; override happens in orchestrator |
|
| 395 |
| `agents/definitions.py` | No new agents |
|
| 396 |
| `agents/tools.py` | No new tools |
|
| 397 |
-
| `core/executor.py` | Execution pipeline unchanged |
|
| 398 |
| `core/validator.py` | Validation unchanged |
|
| 399 |
-
| `core/cam.py` | CAM pipeline unchanged |
|
| 400 |
|
| 401 |
## Testing Strategy
|
| 402 |
|
| 403 |
- **Unit tests for `compute_score()`** — verify scoring with various `DesignState` configurations, cap behavior, threshold edge cases
|
| 404 |
- **Unit tests for plan generation** — verify `DesignPlan` is correctly synthesized from `DesignState`
|
| 405 |
- **Unit tests for phase transitions** — verify all state machine transitions (exploring->planning->approved, approved->exploring on NOT READY, etc.)
|
|
|
|
| 406 |
- **Integration test for `chat_turn` with planning** — verify auto-trigger when score crosses threshold, verify manual trigger via keywords, verify approved phase routes to CAD+CNC
|
| 407 |
-
- **
|
| 408 |
-
- **
|
|
|
|
|
|
| 374 |
- Only one plan card active at a time
|
| 375 |
- All labels go through `I18N` / `t()` for i18n support
|
| 376 |
|
| 377 |
+
## Generation Pipeline (Post-Approval)
|
| 378 |
+
|
| 379 |
+
When `phase == "approved"` and the chat turn runs with CAD + CNC agents, the orchestrator executes a full generation pipeline. This is not a new pipeline — it's the existing flow, but now it only runs after explicit user approval.
|
| 380 |
+
|
| 381 |
+
### Generation Steps
|
| 382 |
+
|
| 383 |
+
```
|
| 384 |
+
Plan approved (phase = "approved")
|
| 385 |
+
|
|
| 386 |
+
v
|
| 387 |
+
1. CAD GENERATION
|
| 388 |
+
- CAD agent receives approved plan in context
|
| 389 |
+
- Generates CadQuery code
|
| 390 |
+
- Executor runs code -> cq.Workplane result
|
| 391 |
+
- Geometry metadata extracted (volume, bbox, faces, edges)
|
| 392 |
+
|
|
| 393 |
+
v
|
| 394 |
+
2. EXPORT 3D FILES
|
| 395 |
+
- STEP export: output/{part_name}.step (precision CAD format)
|
| 396 |
+
- STL export: output/{part_name}.stl (mesh for 3D preview)
|
| 397 |
+
- 3MF export: output/{part_name}.3mf (slicer-ready format)
|
| 398 |
+
|
|
| 399 |
+
v
|
| 400 |
+
3. CNC VALIDATION
|
| 401 |
+
- Manufacturability check (wall thickness, pocket depth, undercuts)
|
| 402 |
+
- Axis recommendation (3-axis / 3+2 / 5-axis)
|
| 403 |
+
- Issues list (errors + warnings)
|
| 404 |
+
|
|
| 405 |
+
v
|
| 406 |
+
4. CAM / G-CODE GENERATION
|
| 407 |
+
- CAM agent creates machining plan (operations, tool config, post-processor)
|
| 408 |
+
- core/cam.py generates G-code from shape + plan
|
| 409 |
+
- G-code saved to output/{part_name}.gcode
|
| 410 |
+
|
|
| 411 |
+
v
|
| 412 |
+
5. 3D PREVIEW
|
| 413 |
+
- STL loaded into Three.js viewport
|
| 414 |
+
- G-code toolpath rendered as 3D lines (if generated)
|
| 415 |
+
- View toggle: Part / Toolpath / Overlay
|
| 416 |
+
|
|
| 417 |
+
v
|
| 418 |
+
6. DOWNLOADS AVAILABLE
|
| 419 |
+
- All export files served and download buttons shown
|
| 420 |
+
```
|
| 421 |
+
|
| 422 |
+
### 3MF Export (New)
|
| 423 |
+
|
| 424 |
+
CadQuery supports 3MF via OCCT. Add `export_3mf()` to `core/executor.py`:
|
| 425 |
+
|
| 426 |
+
```python
|
| 427 |
+
def export_3mf(result: cq.Workplane, path: str | Path) -> Path:
|
| 428 |
+
"""Export a CadQuery workplane to 3MF format (slicer-ready)."""
|
| 429 |
+
path = Path(path)
|
| 430 |
+
cq.exporters.export(result, str(path), exportType="3MF")
|
| 431 |
+
return path
|
| 432 |
+
```
|
| 433 |
+
|
| 434 |
+
Update `export_all()` to include 3MF:
|
| 435 |
+
|
| 436 |
+
```python
|
| 437 |
+
def export_all(result: cq.Workplane, base_path: str | Path) -> dict[str, Path]:
|
| 438 |
+
"""Export to STEP, STL, and 3MF."""
|
| 439 |
+
base = Path(base_path)
|
| 440 |
+
return {
|
| 441 |
+
"step": export_step(result, base.with_suffix(".step")),
|
| 442 |
+
"stl": export_stl(result, base.with_suffix(".stl")),
|
| 443 |
+
"3mf": export_3mf(result, base.with_suffix(".3mf")),
|
| 444 |
+
}
|
| 445 |
+
```
|
| 446 |
+
|
| 447 |
+
### New Endpoint: GET /api/models/{name}.3mf
|
| 448 |
+
|
| 449 |
+
```python
|
| 450 |
+
@app.get("/api/models/{name}.3mf")
|
| 451 |
+
async def get_3mf(name: str):
|
| 452 |
+
path = OUTPUT_DIR / f"{name}.3mf"
|
| 453 |
+
if not path.exists():
|
| 454 |
+
return JSONResponse({"error": f"3MF not found: {name}"}, status_code=404)
|
| 455 |
+
return FileResponse(path, media_type="model/3mf", filename=f"{name}.3mf")
|
| 456 |
+
```
|
| 457 |
+
|
| 458 |
+
### Updated Preview Response
|
| 459 |
+
|
| 460 |
+
The preview response returned after generation includes all file URLs:
|
| 461 |
+
|
| 462 |
+
```json
|
| 463 |
+
{
|
| 464 |
+
"success": true,
|
| 465 |
+
"part_name": "bracket",
|
| 466 |
+
"stl_url": "/api/models/bracket.stl",
|
| 467 |
+
"step_url": "/api/models/bracket.step",
|
| 468 |
+
"threemf_url": "/api/models/bracket.3mf",
|
| 469 |
+
"gcode_url": "/api/models/bracket.gcode",
|
| 470 |
+
"execution": {
|
| 471 |
+
"success": true,
|
| 472 |
+
"volume_mm3": 48000,
|
| 473 |
+
"bounding_box_mm": [60, 40, 20],
|
| 474 |
+
"face_count": 14,
|
| 475 |
+
"edge_count": 24
|
| 476 |
+
},
|
| 477 |
+
"validation": {
|
| 478 |
+
"machinable": true,
|
| 479 |
+
"axis_recommendation": "3-axis",
|
| 480 |
+
"issues": [],
|
| 481 |
+
"error_count": 0,
|
| 482 |
+
"warning_count": 0
|
| 483 |
+
},
|
| 484 |
+
"cam": {
|
| 485 |
+
"success": true,
|
| 486 |
+
"operations": ["adaptive", "profile"],
|
| 487 |
+
"tool_config": {"diameter": 6, "h_feed": 800, "v_feed": 200, "speed": 18000},
|
| 488 |
+
"post_processor": "grbl"
|
| 489 |
+
}
|
| 490 |
+
}
|
| 491 |
+
```
|
| 492 |
+
|
| 493 |
+
### Download Panel (Updated)
|
| 494 |
+
|
| 495 |
+
The existing download buttons panel gains a 3MF button and is reorganized by purpose:
|
| 496 |
+
|
| 497 |
+
```
|
| 498 |
+
+------------------------------------------+
|
| 499 |
+
| DOWNLOADS |
|
| 500 |
+
| |
|
| 501 |
+
| 3D Files: |
|
| 502 |
+
| [STEP] [STL] [3MF] |
|
| 503 |
+
| |
|
| 504 |
+
| CNC Files: |
|
| 505 |
+
| [G-CODE] |
|
| 506 |
+
| |
|
| 507 |
+
| Documentation: |
|
| 508 |
+
| [REPORT] |
|
| 509 |
+
+------------------------------------------+
|
| 510 |
+
```
|
| 511 |
+
|
| 512 |
+
- **STEP** — precision CAD interchange format (for CAD software)
|
| 513 |
+
- **STL** — triangulated mesh (for 3D printing, basic viewing)
|
| 514 |
+
- **3MF** — slicer-ready format (for Cura, PrusaSlicer, Bambu Studio)
|
| 515 |
+
- **G-CODE** — CNC machining program (only visible when CAM has run)
|
| 516 |
+
- **REPORT** — design report JSON
|
| 517 |
+
|
| 518 |
+
Each button is only visible when its corresponding file exists. The G-CODE button remains hidden until CAM generation succeeds. The 3MF button is always shown alongside STL (both are generated by `export_all`).
|
| 519 |
+
|
| 520 |
+
### Gallery Card Downloads
|
| 521 |
+
|
| 522 |
+
Gallery cards also updated to show all available formats:
|
| 523 |
+
|
| 524 |
+
```html
|
| 525 |
+
<div class="gallery-card-downloads">
|
| 526 |
+
<a href="/api/models/{name}.step" download>STEP</a>
|
| 527 |
+
<a href="/api/models/{name}.stl" download>STL</a>
|
| 528 |
+
<a href="/api/models/{name}.3mf" download>3MF</a>
|
| 529 |
+
<a href="/api/models/{name}.gcode" download>GCODE</a>
|
| 530 |
+
</div>
|
| 531 |
+
```
|
| 532 |
+
|
| 533 |
+
### 3D Preview Behavior
|
| 534 |
+
|
| 535 |
+
After generation, the 3D viewer automatically:
|
| 536 |
+
1. Loads the STL into the Three.js viewport
|
| 537 |
+
2. If G-code exists, parses and renders toolpath lines (existing G-code preview feature)
|
| 538 |
+
3. Shows view toggle buttons: Part / Toolpath / Overlay
|
| 539 |
+
4. Shows geometry stats (volume, bounding box, face count)
|
| 540 |
+
5. Shows CNC validation badge (machinable / warnings / errors)
|
| 541 |
+
|
| 542 |
+
## Files Changed (Updated)
|
| 543 |
|
| 544 |
| File | Change |
|
| 545 |
|------|--------|
|
| 546 |
| `agents/design_state.py` | Add `phase`, `plan` fields to `DesignState`; add `DesignPlan` model; add `compute_score()` function |
|
| 547 |
| `agents/crew_orchestrator.py` | Add phase branching, plan generation, plan trigger keyword detection, approved-phase context injection, routing override |
|
|
|
|
| 548 |
| `config/settings.py` | Add `PlanningConfig` model, add `planning` field to `Settings` |
|
| 549 |
| `config/config.yaml` | Add `planning` section with threshold, weights, caps, keywords, approved_agents |
|
| 550 |
+
| `server/routes.py` | Add `POST /api/plan/approve` and `POST /api/plan/reject` endpoints |
|
| 551 |
+
| `server/web.py` | Add `GET /api/models/{name}.3mf` endpoint |
|
| 552 |
+
| `core/executor.py` | Add `export_3mf()` function; update `export_all()` to include 3MF |
|
| 553 |
+
| `web/index.html` | Add tab switcher, guided wizard UI, plan card component, state sync, download panel with 3MF button, gallery card 3MF download, i18n entries |
|
| 554 |
|
| 555 |
## Files Not Changed
|
| 556 |
|
| 557 |
| File | Reason |
|
| 558 |
|------|--------|
|
| 559 |
| `agents/orchestrator.py` (MockChatBackend) | Mock backend does not need planning — it's for testing only |
|
| 560 |
+
| `agents/base.py` | Interface unchanged |
|
| 561 |
| `agents/routing.py` | Routing logic unchanged; override happens in orchestrator |
|
| 562 |
| `agents/definitions.py` | No new agents |
|
| 563 |
| `agents/tools.py` | No new tools |
|
|
|
|
| 564 |
| `core/validator.py` | Validation unchanged |
|
| 565 |
+
| `core/cam.py` | CAM pipeline unchanged — already generates G-code when CAM agent is active |
|
| 566 |
|
| 567 |
## Testing Strategy
|
| 568 |
|
| 569 |
- **Unit tests for `compute_score()`** — verify scoring with various `DesignState` configurations, cap behavior, threshold edge cases
|
| 570 |
- **Unit tests for plan generation** — verify `DesignPlan` is correctly synthesized from `DesignState`
|
| 571 |
- **Unit tests for phase transitions** — verify all state machine transitions (exploring->planning->approved, approved->exploring on NOT READY, etc.)
|
| 572 |
+
- **Unit tests for `export_3mf()`** — verify 3MF export produces valid file
|
| 573 |
- **Integration test for `chat_turn` with planning** — verify auto-trigger when score crosses threshold, verify manual trigger via keywords, verify approved phase routes to CAD+CNC
|
| 574 |
+
- **Integration test for generation pipeline** — verify that approved phase produces all outputs: STEP, STL, 3MF, G-code (when CAM active), validation results
|
| 575 |
+
- **API tests** — verify `/api/plan/approve`, `/api/plan/reject`, and `/api/models/{name}.3mf` endpoints
|
| 576 |
+
- **Frontend manual testing** — tab switching, wizard step navigation, state sync between tabs, plan card approve/reject, download buttons visibility (STEP/STL/3MF always, G-CODE only after CAM), gallery card downloads, i18n
|