Spaces:
Sleeping
Sleeping
Commit ·
e43a92b
1
Parent(s): df36551
feat: add notes field to DesignPlan and field_agents config
Browse filesCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- agents/design_state.py +3 -0
- config.yaml +8 -0
- config/settings.py +9 -0
- tests/test_design_state.py +24 -0
- tests/test_settings.py +10 -0
agents/design_state.py
CHANGED
|
@@ -50,6 +50,7 @@ class DesignPlan(BaseModel):
|
|
| 50 |
axis_recommendation: str = ""
|
| 51 |
machining_notes: list[str] = Field(default_factory=list)
|
| 52 |
confidence_score: float = 0.0
|
|
|
|
| 53 |
|
| 54 |
@classmethod
|
| 55 |
def from_state(cls, state: "DesignState", confidence_score: float) -> "DesignPlan":
|
|
@@ -86,6 +87,8 @@ class DesignPlan(BaseModel):
|
|
| 86 |
lines.append(f"Axis: {self.axis_recommendation}")
|
| 87 |
if self.machining_notes:
|
| 88 |
lines.append(f"Machining Notes: {'; '.join(self.machining_notes)}")
|
|
|
|
|
|
|
| 89 |
lines.append("")
|
| 90 |
lines.append("This plan has been reviewed and approved by the user.")
|
| 91 |
lines.append("Generate the model according to these specifications.")
|
|
|
|
| 50 |
axis_recommendation: str = ""
|
| 51 |
machining_notes: list[str] = Field(default_factory=list)
|
| 52 |
confidence_score: float = 0.0
|
| 53 |
+
notes: str = ""
|
| 54 |
|
| 55 |
@classmethod
|
| 56 |
def from_state(cls, state: "DesignState", confidence_score: float) -> "DesignPlan":
|
|
|
|
| 87 |
lines.append(f"Axis: {self.axis_recommendation}")
|
| 88 |
if self.machining_notes:
|
| 89 |
lines.append(f"Machining Notes: {'; '.join(self.machining_notes)}")
|
| 90 |
+
if self.notes:
|
| 91 |
+
lines.append(f"User Notes: {self.notes}")
|
| 92 |
lines.append("")
|
| 93 |
lines.append("This plan has been reviewed and approved by the user.")
|
| 94 |
lines.append("Generate the model according to these specifications.")
|
config.yaml
CHANGED
|
@@ -95,6 +95,14 @@ planning:
|
|
| 95 |
approved_agents:
|
| 96 |
- "cad"
|
| 97 |
- "cnc"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
gap_analysis:
|
| 100 |
category_keywords:
|
|
|
|
| 95 |
approved_agents:
|
| 96 |
- "cad"
|
| 97 |
- "cnc"
|
| 98 |
+
field_agents:
|
| 99 |
+
material: engineering
|
| 100 |
+
dimensions: engineering
|
| 101 |
+
features: design
|
| 102 |
+
constraints: cnc
|
| 103 |
+
axis_recommendation: cnc
|
| 104 |
+
machining_notes: cnc
|
| 105 |
+
part_name: design
|
| 106 |
|
| 107 |
gap_analysis:
|
| 108 |
category_keywords:
|
config/settings.py
CHANGED
|
@@ -109,6 +109,15 @@ class PlanningConfig(BaseModel):
|
|
| 109 |
"plan", "review", "ready", "show plan", "summarize", "what do we have",
|
| 110 |
])
|
| 111 |
approved_agents: list[str] = Field(default_factory=lambda: ["cad", "cnc"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
|
| 114 |
class GapAnalysisConfig(BaseModel):
|
|
|
|
| 109 |
"plan", "review", "ready", "show plan", "summarize", "what do we have",
|
| 110 |
])
|
| 111 |
approved_agents: list[str] = Field(default_factory=lambda: ["cad", "cnc"])
|
| 112 |
+
field_agents: dict[str, str] = Field(default_factory=lambda: {
|
| 113 |
+
"material": "engineering",
|
| 114 |
+
"dimensions": "engineering",
|
| 115 |
+
"features": "design",
|
| 116 |
+
"constraints": "cnc",
|
| 117 |
+
"axis_recommendation": "cnc",
|
| 118 |
+
"machining_notes": "cnc",
|
| 119 |
+
"part_name": "design",
|
| 120 |
+
})
|
| 121 |
|
| 122 |
|
| 123 |
class GapAnalysisConfig(BaseModel):
|
tests/test_design_state.py
CHANGED
|
@@ -126,6 +126,30 @@ class TestDesignPlan:
|
|
| 126 |
assert "aluminum 6061" in rendered
|
| 127 |
assert "No undercuts" in rendered
|
| 128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
class TestComputeScore:
|
| 131 |
def test_empty_state_scores_zero(self):
|
|
|
|
| 126 |
assert "aluminum 6061" in rendered
|
| 127 |
assert "No undercuts" in rendered
|
| 128 |
|
| 129 |
+
def test_plan_notes_default_empty(self):
|
| 130 |
+
plan = DesignPlan(part_name="test")
|
| 131 |
+
assert plan.notes == ""
|
| 132 |
+
|
| 133 |
+
def test_plan_notes_in_render(self):
|
| 134 |
+
plan = DesignPlan(
|
| 135 |
+
part_name="bracket",
|
| 136 |
+
material="aluminum",
|
| 137 |
+
notes="Check if 304 is overkill",
|
| 138 |
+
)
|
| 139 |
+
rendered = plan.render_approved()
|
| 140 |
+
assert "User Notes" in rendered
|
| 141 |
+
assert "Check if 304 is overkill" in rendered
|
| 142 |
+
|
| 143 |
+
def test_plan_notes_empty_not_in_render(self):
|
| 144 |
+
plan = DesignPlan(part_name="bracket", material="aluminum", notes="")
|
| 145 |
+
rendered = plan.render_approved()
|
| 146 |
+
assert "User Notes" not in rendered
|
| 147 |
+
|
| 148 |
+
def test_plan_from_state_no_notes(self):
|
| 149 |
+
state = DesignState(part_name="bracket", material="steel")
|
| 150 |
+
plan = DesignPlan.from_state(state, confidence_score=5.0)
|
| 151 |
+
assert plan.notes == ""
|
| 152 |
+
|
| 153 |
|
| 154 |
class TestComputeScore:
|
| 155 |
def test_empty_state_scores_zero(self):
|
tests/test_settings.py
CHANGED
|
@@ -65,6 +65,16 @@ class TestPlanningConfig:
|
|
| 65 |
assert settings.planning.threshold == 8.0
|
| 66 |
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
class TestGapAnalysisConfig:
|
| 69 |
def test_gap_analysis_defaults(self):
|
| 70 |
from config.settings import Settings
|
|
|
|
| 65 |
assert settings.planning.threshold == 8.0
|
| 66 |
|
| 67 |
|
| 68 |
+
def test_planning_field_agents_defaults():
|
| 69 |
+
from config.settings import PlanningConfig
|
| 70 |
+
cfg = PlanningConfig()
|
| 71 |
+
assert cfg.field_agents["material"] == "engineering"
|
| 72 |
+
assert cfg.field_agents["features"] == "design"
|
| 73 |
+
assert cfg.field_agents["constraints"] == "cnc"
|
| 74 |
+
assert cfg.field_agents["axis_recommendation"] == "cnc"
|
| 75 |
+
assert cfg.field_agents["part_name"] == "design"
|
| 76 |
+
|
| 77 |
+
|
| 78 |
class TestGapAnalysisConfig:
|
| 79 |
def test_gap_analysis_defaults(self):
|
| 80 |
from config.settings import Settings
|