CallMeDaniel Claude Opus 4.6 (1M context) commited on
Commit
8d2137d
·
1 Parent(s): ae6029b

refactor: use serializers to eliminate duplicated result building

Browse files

Replace all inline dict-building for execution and validation results in
server/mcp.py and agents/orchestrator.py with ExecutionResultSerializer.to_dict()
and ValidationResultSerializer.to_dict() calls from core.serializers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Files changed (2) hide show
  1. agents/orchestrator.py +3 -17
  2. server/mcp.py +9 -53
agents/orchestrator.py CHANGED
@@ -28,6 +28,7 @@ from agents.prompts import (
28
  from agents.design_state import DesignState, extract_decisions
29
  from core.backends import LLMBackend, MockBackend
30
  from core.executor import execute_cadquery, export_all
 
31
  from core.validator import validate_for_cnc
32
 
33
 
@@ -112,23 +113,8 @@ def _execute_cad_code(
112
  "part_name": part_name,
113
  "stl_url": f"/api/models/{part_name}.stl",
114
  "step_url": f"/api/models/{part_name}.step",
115
- "execution": {
116
- "success": True,
117
- "volume_mm3": exec_result.volume,
118
- "bounding_box_mm": list(exec_result.bounding_box),
119
- "face_count": exec_result.face_count,
120
- "edge_count": exec_result.edge_count,
121
- },
122
- "validation": {
123
- "machinable": validation.machinable,
124
- "axis_recommendation": validation.axis_recommendation,
125
- "error_count": validation.error_count,
126
- "warning_count": validation.warning_count,
127
- "issues": [
128
- {"severity": i.severity, "category": i.category, "message": i.message}
129
- for i in validation.issues
130
- ],
131
- },
132
  }
133
 
134
 
 
28
  from agents.design_state import DesignState, extract_decisions
29
  from core.backends import LLMBackend, MockBackend
30
  from core.executor import execute_cadquery, export_all
31
+ from core.serializers import ExecutionResultSerializer, ValidationResultSerializer
32
  from core.validator import validate_for_cnc
33
 
34
 
 
113
  "part_name": part_name,
114
  "stl_url": f"/api/models/{part_name}.stl",
115
  "step_url": f"/api/models/{part_name}.step",
116
+ "execution": ExecutionResultSerializer.to_dict(exec_result),
117
+ "validation": ValidationResultSerializer.to_dict(validation),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  }
119
 
120
 
server/mcp.py CHANGED
@@ -17,14 +17,14 @@ Usage:
17
 
18
  import json
19
  import os
20
- import sys
21
  from pathlib import Path
22
 
23
  from mcp.server.fastmcp import FastMCP
24
 
25
  from core.cadquery_prompts import build_messages, CADQUERY_SYSTEM_PROMPT
26
- from core.executor import ExecutionResult, execute_cadquery, export_all, sanitize_code
27
- from core.validator import validate_for_cnc, CNCValidationResult
 
28
 
29
  # ── Server Setup ──────────────────────────────────────────────────────────
30
 
@@ -117,27 +117,11 @@ def generate_cnc_model(
117
  "part_name": part_name,
118
  "retries": result.retry_count,
119
  "generated_code": result.generated_code,
120
- "execution": {
121
- "success": result.execution.success,
122
- "volume_mm3": result.execution.volume,
123
- "bounding_box_mm": list(result.execution.bounding_box) if result.execution.bounding_box else [],
124
- "face_count": result.execution.face_count,
125
- "edge_count": result.execution.edge_count,
126
- "error": result.execution.error,
127
- },
128
  }
129
 
130
  if result.validation:
131
- response["validation"] = {
132
- "machinable": result.validation.machinable,
133
- "axis_recommendation": result.validation.axis_recommendation,
134
- "error_count": result.validation.error_count,
135
- "warning_count": result.validation.warning_count,
136
- "issues": [
137
- {"severity": i.severity, "category": i.category, "message": i.message}
138
- for i in result.validation.issues
139
- ],
140
- }
141
 
142
  if result.exported_files:
143
  response["exported_files"] = {
@@ -189,14 +173,7 @@ def validate_cnc_model(
189
  }
190
  validation = validate_for_cnc(exec_result.result, part_name=part_name, config=config)
191
  response["validation"] = {
192
- "machinable": validation.machinable,
193
- "axis_recommendation": validation.axis_recommendation,
194
- "error_count": validation.error_count,
195
- "warning_count": validation.warning_count,
196
- "issues": [
197
- {"severity": i.severity, "category": i.category, "message": i.message}
198
- for i in validation.issues
199
- ],
200
  "summary": validation.summary(),
201
  }
202
 
@@ -231,13 +208,8 @@ def execute_cadquery_code(
231
  exec_result = execute_cadquery(code)
232
 
233
  response = {
234
- "success": exec_result.success,
235
- "error": exec_result.error,
236
  "stdout": exec_result.stdout,
237
- "volume_mm3": exec_result.volume,
238
- "bounding_box_mm": list(exec_result.bounding_box) if exec_result.bounding_box else [],
239
- "face_count": exec_result.face_count,
240
- "edge_count": exec_result.edge_count,
241
  }
242
 
243
  if exec_result.success and export_path:
@@ -358,28 +330,12 @@ def generate_from_image(
358
  "backend": backend,
359
  "retries": retry_count,
360
  "generated_code": generated_code,
361
- "execution": {
362
- "success": exec_result.success,
363
- "volume_mm3": exec_result.volume,
364
- "bounding_box_mm": list(exec_result.bounding_box) if exec_result.bounding_box else [],
365
- "face_count": exec_result.face_count,
366
- "edge_count": exec_result.edge_count,
367
- "error": exec_result.error,
368
- },
369
  }
370
 
371
  if exec_result.success:
372
  validation = validate_for_cnc(exec_result.result, part_name=part_name)
373
- response["validation"] = {
374
- "machinable": validation.machinable,
375
- "axis_recommendation": validation.axis_recommendation,
376
- "error_count": validation.error_count,
377
- "warning_count": validation.warning_count,
378
- "issues": [
379
- {"severity": i.severity, "category": i.category, "message": i.message}
380
- for i in validation.issues
381
- ],
382
- }
383
 
384
  base_path = DEFAULT_OUTPUT_DIR / part_name
385
  try:
 
17
 
18
  import json
19
  import os
 
20
  from pathlib import Path
21
 
22
  from mcp.server.fastmcp import FastMCP
23
 
24
  from core.cadquery_prompts import build_messages, CADQUERY_SYSTEM_PROMPT
25
+ from core.executor import execute_cadquery, export_all
26
+ from core.serializers import ExecutionResultSerializer, ValidationResultSerializer
27
+ from core.validator import validate_for_cnc
28
 
29
  # ── Server Setup ──────────────────────────────────────────────────────────
30
 
 
117
  "part_name": part_name,
118
  "retries": result.retry_count,
119
  "generated_code": result.generated_code,
120
+ "execution": ExecutionResultSerializer.to_dict(result.execution),
 
 
 
 
 
 
 
121
  }
122
 
123
  if result.validation:
124
+ response["validation"] = ValidationResultSerializer.to_dict(result.validation)
 
 
 
 
 
 
 
 
 
125
 
126
  if result.exported_files:
127
  response["exported_files"] = {
 
173
  }
174
  validation = validate_for_cnc(exec_result.result, part_name=part_name, config=config)
175
  response["validation"] = {
176
+ **ValidationResultSerializer.to_dict(validation),
 
 
 
 
 
 
 
177
  "summary": validation.summary(),
178
  }
179
 
 
208
  exec_result = execute_cadquery(code)
209
 
210
  response = {
211
+ **ExecutionResultSerializer.to_dict(exec_result),
 
212
  "stdout": exec_result.stdout,
 
 
 
 
213
  }
214
 
215
  if exec_result.success and export_path:
 
330
  "backend": backend,
331
  "retries": retry_count,
332
  "generated_code": generated_code,
333
+ "execution": ExecutionResultSerializer.to_dict(exec_result),
 
 
 
 
 
 
 
334
  }
335
 
336
  if exec_result.success:
337
  validation = validate_for_cnc(exec_result.result, part_name=part_name)
338
+ response["validation"] = ValidationResultSerializer.to_dict(validation)
 
 
 
 
 
 
 
 
 
339
 
340
  base_path = DEFAULT_OUTPUT_DIR / part_name
341
  try: