提交env
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
# Environment files
|
||||
.env
|
||||
.env.*
|
||||
!backend/.env
|
||||
!.env.example
|
||||
!.env.*.example
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Default provider. Only providers with an API key are exposed to the UI.
|
||||
CDSL_DEFAULT_PROVIDER=deepseek
|
||||
CDSL_DEFAULT_MODEL=deepseek-chat
|
||||
|
||||
# DeepSeek. Fill in your own API key below.
|
||||
CDSL_LLM_BASE_URL=https://api.deepseek.com/v1
|
||||
CDSL_LLM_API_KEY=sk-d3f8fe84bf9a4100a6563559e5d2fefd
|
||||
CDSL_LLM_MODEL=deepseek-chat
|
||||
CDSL_LLM_TIMEOUT_S=90
|
||||
|
||||
# Optional OpenAI provider. Comma-separate enabled models; list vision models
|
||||
# separately so image attachments can be routed safely.
|
||||
CDSL_OPENAI_BASE_URL=https://api.openai.com/v1
|
||||
CDSL_OPENAI_API_KEY=
|
||||
CDSL_OPENAI_MODELS=gpt-4.1,gpt-4.1-mini
|
||||
CDSL_OPENAI_VISION_MODELS=gpt-4.1,gpt-4.1-mini
|
||||
|
||||
# Optional Kimi provider.
|
||||
CDSL_KIMI_BASE_URL=https://api.moonshot.cn/v1
|
||||
CDSL_KIMI_API_KEY=
|
||||
CDSL_KIMI_MODELS=moonshot-v1-8k
|
||||
CDSL_KIMI_VISION_MODELS=
|
||||
# Enable only after verifying that the selected endpoint supports strict
|
||||
# OpenAI-compatible function schemas. This affects generate_cdsl_model's JSON
|
||||
# arguments only, never ordinary assistant chat text.
|
||||
CDSL_DEEPSEEK_STRICT_TOOL_SCHEMA=false
|
||||
CDSL_OPENAI_STRICT_TOOL_SCHEMA=true
|
||||
CDSL_KIMI_STRICT_TOOL_SCHEMA=true
|
||||
# To enable individual models instead of every model from a provider, keep the
|
||||
# provider-wide switch false and list exact IDs, for example:
|
||||
# CDSL_OPENAI_STRICT_TOOL_MODELS=gpt-4.1
|
||||
@@ -103,6 +103,15 @@
|
||||
"required": ["angle_deg", "axis"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"sphereParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"radius_mm": {"$ref": "#/$defs/positive"},
|
||||
"center_mm": {"$ref": "#/$defs/point3"}
|
||||
},
|
||||
"required": ["radius_mm", "center_mm"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"holeBaseParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -290,7 +299,7 @@
|
||||
"required": ["type", "contours"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"feature_atomic_ids": {"enum": ["extrude_add_blind", "extrude_add_two_sided", "extrude_cut_blind", "revolve_add", "revolve_cut", "hole_blind", "hole_countersink", "hole_counterbore", "fillet", "chamfer", "pattern_linear", "pattern_mirror", "reference_plane", "reference_axis", "hole_wizard"]},
|
||||
"feature_atomic_ids": {"enum": ["extrude_add_blind", "extrude_add_two_sided", "extrude_cut_blind", "revolve_add", "revolve_cut", "hole_blind", "hole_countersink", "hole_counterbore", "sphere_add", "fillet", "chamfer", "pattern_linear", "pattern_mirror", "reference_plane", "reference_axis", "hole_wizard"]},
|
||||
"feature": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -312,6 +321,7 @@
|
||||
{"if": {"properties": {"atomic_id": {"const": "extrude_cut_blind"}}}, "then": {"properties": {"params": {"$ref": "#/$defs/extrudeParams"}}}},
|
||||
{"if": {"properties": {"atomic_id": {"const": "revolve_add"}}}, "then": {"properties": {"params": {"$ref": "#/$defs/revolveParams"}}}},
|
||||
{"if": {"properties": {"atomic_id": {"const": "revolve_cut"}}}, "then": {"properties": {"params": {"$ref": "#/$defs/revolveParams"}}}},
|
||||
{"if": {"properties": {"atomic_id": {"const": "sphere_add"}}}, "then": {"properties": {"params": {"$ref": "#/$defs/sphereParams"}}}},
|
||||
{"if": {"properties": {"atomic_id": {"const": "hole_blind"}}}, "then": {"properties": {"params": {"$ref": "#/$defs/holeBlindParams"}}}},
|
||||
{"if": {"properties": {"atomic_id": {"const": "hole_countersink"}}}, "then": {"properties": {"params": {"$ref": "#/$defs/holeCountersinkParams"}}}},
|
||||
{"if": {"properties": {"atomic_id": {"const": "hole_counterbore"}}}, "then": {"properties": {"params": {"$ref": "#/$defs/holeCounterboreParams"}}}},
|
||||
|
||||
@@ -22,6 +22,7 @@ REQUIRED = {
|
||||
"hole_blind": ["diameter_mm", "depth_mm"],
|
||||
"hole_countersink": ["diameter_mm", "depth_mm"],
|
||||
"hole_counterbore": ["diameter_mm", "depth_mm"],
|
||||
"sphere_add": ["radius_mm", "center_mm"],
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ from build123d import ( # noqa: E402
|
||||
Mode,
|
||||
Plane,
|
||||
Polygon,
|
||||
Sphere,
|
||||
Vector,
|
||||
Wire,
|
||||
export_step,
|
||||
@@ -49,6 +50,7 @@ SUPPORTED_ATOMIC_IDS = frozenset({
|
||||
"hole_blind",
|
||||
"hole_countersink",
|
||||
"hole_counterbore",
|
||||
"sphere_add",
|
||||
})
|
||||
|
||||
|
||||
@@ -265,7 +267,16 @@ def run_engine_plan(
|
||||
sketch = step.get("sketch")
|
||||
sid = step.get("step_id")
|
||||
|
||||
if atomic in ("extrude_add_blind", "extrude_add_two_sided", "extrude_cut_blind"):
|
||||
if atomic == "sphere_add":
|
||||
radius = _f(params.get("radius_mm") or 0)
|
||||
center = params.get("center_mm") or [0, 0, 0]
|
||||
if radius <= 0 or len(center) != 3:
|
||||
raise ValueError(f"{sid}: sphere_add requires a positive radius_mm and center_mm")
|
||||
with Locations((_f(center[0]), _f(center[1]), _f(center[2]))):
|
||||
Sphere(radius, mode=Mode.ADD)
|
||||
log.append(f"{sid}: sphere_add radius={radius}")
|
||||
|
||||
elif atomic in ("extrude_add_blind", "extrude_add_two_sided", "extrude_cut_blind"):
|
||||
if sketch is None:
|
||||
raise ValueError(f"{sid}: missing sketch")
|
||||
plane = _plane_from_workplane(sketch.get("workplane") or {})
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"cdsl_json_schema_file": "cdsl_schema.json",
|
||||
"maintenance_rule": "The semantic CDSL contract is a superset of the current runtime. runtime_supported_atomic_ids and runtime_supported_profiles must stay synchronized with sketch_solver.py, llm_compiler.py and llm_engine.py; deferred entries describe future engine work.",
|
||||
"coordinate_convention": "All profile dimensions use millimetres. Two-dimensional points are [u, v] in the sketch workplane.",
|
||||
"runtime_supported_atomic_ids": ["extrude_add_blind", "extrude_add_two_sided", "extrude_cut_blind", "revolve_add", "revolve_cut", "hole_blind", "hole_countersink", "hole_counterbore"],
|
||||
"runtime_supported_atomic_ids": ["extrude_add_blind", "extrude_add_two_sided", "extrude_cut_blind", "revolve_add", "revolve_cut", "hole_blind", "hole_countersink", "hole_counterbore", "sphere_add"],
|
||||
"runtime_supported_profiles": ["circle", "annulus", "circles", "circle_grid", "rectangle", "rectangle_with_circles", "rectangle_with_fillets", "obround", "polygon", "ibone", "rectangle_with_symmetric_notches", "revolve_chamfer", "revolve_chamfer_slanted", "circle_with_arc_notches", "circular_sector_slot", "circle_with_radial_tabs", "filleted_rect_side_slots", "d_shape", "partial_ring", "partial_ring_with_arc_island", "arc_chain", "radial_slot", "patterned_cutouts", "compound_patterned_cutouts", "complex_arc_shape", "unknown_shape"],
|
||||
"feature_atomic_ids": {
|
||||
"extrude_add_blind": {"summary": "Add the closed profile by one signed extrusion distance.", "required_params": ["distance_mm"], "optional_params": ["reverse"], "requires_sketch": true},
|
||||
@@ -15,6 +15,7 @@
|
||||
"hole_blind": {"summary": "Cut one or more blind cylindrical holes in the current body.", "required_params": ["diameter_mm", "depth_mm", "positions"], "optional_params": ["host_face", "drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid.", "requires_sketch": true},
|
||||
"hole_countersink": {"summary": "Cut one or more blind holes with countersink dimensions.", "required_params": ["diameter_mm", "depth_mm", "positions", "countersink_diameter_mm", "countersink_angle_rad"], "optional_params": ["host_face", "drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid.", "requires_sketch": true},
|
||||
"hole_counterbore": {"summary": "Cut one or more blind holes with counterbore dimensions.", "required_params": ["diameter_mm", "depth_mm", "positions", "counterbore_diameter_mm", "counterbore_depth_mm"], "optional_params": ["host_face", "drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid.", "requires_sketch": true},
|
||||
"sphere_add": {"summary": "Add one spherical solid at an explicit model-space center.", "required_params": ["radius_mm", "center_mm"], "optional_params": [], "requires_sketch": true},
|
||||
"fillet": {"summary": "Apply a radius to selected edges or faces.", "required_params": ["radius_mm"], "optional_params": ["tangent_propagation"], "requires_sketch": false, "execution_status": "deferred"},
|
||||
"chamfer": {"summary": "Apply an equal-distance or angle-distance chamfer to selected edges or faces.", "required_params": ["distance_mm"], "optional_params": ["distance_2_mm", "angle_rad"], "requires_sketch": false, "execution_status": "deferred"},
|
||||
"pattern_linear": {"summary": "Repeat source features along one or two directions.", "required_params": ["source_feature_ids", "direction_1", "spacing_1_mm", "pattern_count_1"], "optional_params": ["direction_2", "spacing_2_mm", "pattern_count_2"], "requires_sketch": false, "execution_status": "deferred"},
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from build123d import import_step
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
sys.path.insert(0, str(ROOT / "backend" / "engine"))
|
||||
|
||||
import cdsl_engine # noqa: E402
|
||||
|
||||
|
||||
class SphereAddTests(unittest.TestCase):
|
||||
def test_cdsl_only_rebuilds_a_sphere_at_the_requested_center(self) -> None:
|
||||
cdsl = {
|
||||
"schema": "cad.cdsl.llm.v1",
|
||||
"schema_version": "1.0.0",
|
||||
"kind": "part",
|
||||
"part_id": "sphere_test",
|
||||
"meta": {"unit": "mm"},
|
||||
"geometry": {
|
||||
"sketches": [{
|
||||
"id": "sphere_locator",
|
||||
"workplane": {
|
||||
"origin_mm": [0, 0, 0],
|
||||
"x_dir": [1, 0, 0],
|
||||
"normal": [0, 0, 1],
|
||||
},
|
||||
"profile": {"type": "circle", "radius_mm": 1.0},
|
||||
}],
|
||||
},
|
||||
"features": [{
|
||||
"id": "sphere",
|
||||
"atomic_id": "sphere_add",
|
||||
"depends_on": [],
|
||||
"name": "Test sphere",
|
||||
"params": {"radius_mm": 2.5, "center_mm": [3.0, -4.0, 5.0]},
|
||||
"sketch_id": "sphere_locator",
|
||||
}],
|
||||
}
|
||||
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
out_step = Path(directory) / "sphere.step"
|
||||
result = cdsl_engine.run_rebuild(cdsl, out_step)
|
||||
shape = import_step(str(out_step))
|
||||
bbox = shape.bounding_box()
|
||||
|
||||
self.assertEqual(result["engine"], "cdsl_only")
|
||||
self.assertAlmostEqual(shape.volume, 4 / 3 * 3.141592653589793 * 2.5 ** 3, places=5)
|
||||
self.assertEqual((bbox.min.X, bbox.min.Y, bbox.min.Z), (0.5, -6.5, 2.5))
|
||||
self.assertEqual((bbox.max.X, bbox.max.Y, bbox.max.Z), (5.5, -1.5, 7.5))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user