seam-studio 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. seam_studio-0.1.0/MANIFEST.in +3 -0
  2. seam_studio-0.1.0/PKG-INFO +100 -0
  3. seam_studio-0.1.0/README.md +56 -0
  4. seam_studio-0.1.0/pyproject.toml +86 -0
  5. seam_studio-0.1.0/seam_studio/__init__.py +0 -0
  6. seam_studio-0.1.0/seam_studio/api/__init__.py +0 -0
  7. seam_studio-0.1.0/seam_studio/api/agent.py +149 -0
  8. seam_studio-0.1.0/seam_studio/api/ai.py +321 -0
  9. seam_studio-0.1.0/seam_studio/api/calibrate.py +345 -0
  10. seam_studio-0.1.0/seam_studio/api/channel.py +161 -0
  11. seam_studio-0.1.0/seam_studio/api/compile.py +34 -0
  12. seam_studio-0.1.0/seam_studio/api/datasets.py +91 -0
  13. seam_studio-0.1.0/seam_studio/api/deps.py +41 -0
  14. seam_studio-0.1.0/seam_studio/api/engines.py +15 -0
  15. seam_studio-0.1.0/seam_studio/api/events.py +38 -0
  16. seam_studio-0.1.0/seam_studio/api/export.py +83 -0
  17. seam_studio-0.1.0/seam_studio/api/health.py +78 -0
  18. seam_studio-0.1.0/seam_studio/api/import_osm.py +78 -0
  19. seam_studio-0.1.0/seam_studio/api/import_results.py +86 -0
  20. seam_studio-0.1.0/seam_studio/api/import_scene.py +537 -0
  21. seam_studio-0.1.0/seam_studio/api/materials.py +319 -0
  22. seam_studio-0.1.0/seam_studio/api/point_import.py +109 -0
  23. seam_studio-0.1.0/seam_studio/api/projects.py +214 -0
  24. seam_studio-0.1.0/seam_studio/api/render.py +53 -0
  25. seam_studio-0.1.0/seam_studio/api/scenario.py +205 -0
  26. seam_studio-0.1.0/seam_studio/api/scene.py +172 -0
  27. seam_studio-0.1.0/seam_studio/api/segmentation.py +249 -0
  28. seam_studio-0.1.0/seam_studio/api/simulate.py +659 -0
  29. seam_studio-0.1.0/seam_studio/cli.py +92 -0
  30. seam_studio-0.1.0/seam_studio/core/__init__.py +0 -0
  31. seam_studio-0.1.0/seam_studio/core/config.py +96 -0
  32. seam_studio-0.1.0/seam_studio/core/paths.py +59 -0
  33. seam_studio-0.1.0/seam_studio/data/default_rf_materials.yaml +316 -0
  34. seam_studio-0.1.0/seam_studio/engine_workers/__init__.py +11 -0
  35. seam_studio-0.1.0/seam_studio/engine_workers/sionna_rt_worker.py +334 -0
  36. seam_studio-0.1.0/seam_studio/main.py +84 -0
  37. seam_studio-0.1.0/seam_studio/schemas/__init__.py +119 -0
  38. seam_studio-0.1.0/seam_studio/schemas/actors.py +90 -0
  39. seam_studio-0.1.0/seam_studio/schemas/ai.py +176 -0
  40. seam_studio-0.1.0/seam_studio/schemas/calibration.py +163 -0
  41. seam_studio-0.1.0/seam_studio/schemas/channel.py +221 -0
  42. seam_studio-0.1.0/seam_studio/schemas/common.py +68 -0
  43. seam_studio-0.1.0/seam_studio/schemas/compile.py +45 -0
  44. seam_studio-0.1.0/seam_studio/schemas/datasets.py +93 -0
  45. seam_studio-0.1.0/seam_studio/schemas/devices.py +53 -0
  46. seam_studio-0.1.0/seam_studio/schemas/engines.py +35 -0
  47. seam_studio-0.1.0/seam_studio/schemas/material_impact.py +55 -0
  48. seam_studio-0.1.0/seam_studio/schemas/materials.py +80 -0
  49. seam_studio-0.1.0/seam_studio/schemas/point_import.py +112 -0
  50. seam_studio-0.1.0/seam_studio/schemas/projects.py +45 -0
  51. seam_studio-0.1.0/seam_studio/schemas/render.py +31 -0
  52. seam_studio-0.1.0/seam_studio/schemas/results.py +200 -0
  53. seam_studio-0.1.0/seam_studio/schemas/scene.py +300 -0
  54. seam_studio-0.1.0/seam_studio/schemas/seam_agent.py +134 -0
  55. seam_studio-0.1.0/seam_studio/schemas/segmentation.py +112 -0
  56. seam_studio-0.1.0/seam_studio/schemas/simulation.py +209 -0
  57. seam_studio-0.1.0/seam_studio/schemas/validation.py +64 -0
  58. seam_studio-0.1.0/seam_studio/services/__init__.py +0 -0
  59. seam_studio-0.1.0/seam_studio/services/ai_provider.py +2138 -0
  60. seam_studio-0.1.0/seam_studio/services/aodt_import.py +311 -0
  61. seam_studio-0.1.0/seam_studio/services/availability.py +32 -0
  62. seam_studio-0.1.0/seam_studio/services/calibration.py +290 -0
  63. seam_studio-0.1.0/seam_studio/services/channel_analysis.py +1011 -0
  64. seam_studio-0.1.0/seam_studio/services/dataset.py +554 -0
  65. seam_studio-0.1.0/seam_studio/services/demo_project.py +395 -0
  66. seam_studio-0.1.0/seam_studio/services/engines.py +200 -0
  67. seam_studio-0.1.0/seam_studio/services/events.py +119 -0
  68. seam_studio-0.1.0/seam_studio/services/import_jobs.py +147 -0
  69. seam_studio-0.1.0/seam_studio/services/live_state.py +100 -0
  70. seam_studio-0.1.0/seam_studio/services/material_assignment.py +142 -0
  71. seam_studio-0.1.0/seam_studio/services/material_impact.py +205 -0
  72. seam_studio-0.1.0/seam_studio/services/material_segmentation.py +756 -0
  73. seam_studio-0.1.0/seam_studio/services/measurement_validation.py +177 -0
  74. seam_studio-0.1.0/seam_studio/services/mesh_radio_map.py +188 -0
  75. seam_studio-0.1.0/seam_studio/services/mesh_tools.py +173 -0
  76. seam_studio-0.1.0/seam_studio/services/mitsuba_import.py +434 -0
  77. seam_studio-0.1.0/seam_studio/services/osm_import.py +495 -0
  78. seam_studio-0.1.0/seam_studio/services/plugins.py +299 -0
  79. seam_studio-0.1.0/seam_studio/services/point_import.py +539 -0
  80. seam_studio-0.1.0/seam_studio/services/project_store.py +451 -0
  81. seam_studio-0.1.0/seam_studio/services/rf_compiler.py +902 -0
  82. seam_studio-0.1.0/seam_studio/services/rfdata_export.py +287 -0
  83. seam_studio-0.1.0/seam_studio/services/scenario.py +388 -0
  84. seam_studio-0.1.0/seam_studio/services/scene_bounds.py +64 -0
  85. seam_studio-0.1.0/seam_studio/services/scene_render.py +287 -0
  86. seam_studio-0.1.0/seam_studio/services/scene_validator.py +588 -0
  87. seam_studio-0.1.0/seam_studio/services/seam_agent.py +1076 -0
  88. seam_studio-0.1.0/seam_studio/services/simulation_backends/__init__.py +63 -0
  89. seam_studio-0.1.0/seam_studio/services/simulation_backends/base.py +143 -0
  90. seam_studio-0.1.0/seam_studio/services/simulation_backends/mock_backend.py +562 -0
  91. seam_studio-0.1.0/seam_studio/services/simulation_backends/sionna_backend.py +1609 -0
  92. seam_studio-0.1.0/seam_studio/services/solve_ctx.py +87 -0
  93. seam_studio-0.1.0/seam_studio/services/terrain.py +130 -0
  94. seam_studio-0.1.0/seam_studio/services/trajectory.py +727 -0
  95. seam_studio-0.1.0/seam_studio/static/assets/index-CTYi_D0u.js +4442 -0
  96. seam_studio-0.1.0/seam_studio/static/assets/index-D0ZVAk6d.css +1 -0
  97. seam_studio-0.1.0/seam_studio/static/index.html +24 -0
  98. seam_studio-0.1.0/seam_studio.egg-info/PKG-INFO +100 -0
  99. seam_studio-0.1.0/seam_studio.egg-info/SOURCES.txt +152 -0
  100. seam_studio-0.1.0/seam_studio.egg-info/dependency_links.txt +1 -0
  101. seam_studio-0.1.0/seam_studio.egg-info/entry_points.txt +2 -0
  102. seam_studio-0.1.0/seam_studio.egg-info/requires.txt +26 -0
  103. seam_studio-0.1.0/seam_studio.egg-info/top_level.txt +1 -0
  104. seam_studio-0.1.0/setup.cfg +4 -0
  105. seam_studio-0.1.0/tests/test_ai_evidence.py +228 -0
  106. seam_studio-0.1.0/tests/test_ai_models.py +372 -0
  107. seam_studio-0.1.0/tests/test_ai_parser.py +1475 -0
  108. seam_studio-0.1.0/tests/test_beamforming.py +162 -0
  109. seam_studio-0.1.0/tests/test_calibration.py +476 -0
  110. seam_studio-0.1.0/tests/test_channel_analysis.py +465 -0
  111. seam_studio-0.1.0/tests/test_channel_pack.py +411 -0
  112. seam_studio-0.1.0/tests/test_channel_persist_positions.py +123 -0
  113. seam_studio-0.1.0/tests/test_dataset_pack.py +323 -0
  114. seam_studio-0.1.0/tests/test_datasets.py +227 -0
  115. seam_studio-0.1.0/tests/test_doppler.py +410 -0
  116. seam_studio-0.1.0/tests/test_engines.py +159 -0
  117. seam_studio-0.1.0/tests/test_events_and_aodt.py +293 -0
  118. seam_studio-0.1.0/tests/test_face_group_split.py +247 -0
  119. seam_studio-0.1.0/tests/test_import_api.py +132 -0
  120. seam_studio-0.1.0/tests/test_import_jobs.py +216 -0
  121. seam_studio-0.1.0/tests/test_live_state.py +101 -0
  122. seam_studio-0.1.0/tests/test_material_assignment.py +396 -0
  123. seam_studio-0.1.0/tests/test_material_impact.py +241 -0
  124. seam_studio-0.1.0/tests/test_material_segmentation.py +248 -0
  125. seam_studio-0.1.0/tests/test_materials_pack.py +192 -0
  126. seam_studio-0.1.0/tests/test_measurements_pack.py +345 -0
  127. seam_studio-0.1.0/tests/test_mitsuba_import.py +250 -0
  128. seam_studio-0.1.0/tests/test_mock_backend.py +360 -0
  129. seam_studio-0.1.0/tests/test_openapi_export.py +131 -0
  130. seam_studio-0.1.0/tests/test_osm_import.py +393 -0
  131. seam_studio-0.1.0/tests/test_packaging.py +67 -0
  132. seam_studio-0.1.0/tests/test_plugins.py +277 -0
  133. seam_studio-0.1.0/tests/test_point_import.py +462 -0
  134. seam_studio-0.1.0/tests/test_project_format.py +175 -0
  135. seam_studio-0.1.0/tests/test_project_mgmt.py +231 -0
  136. seam_studio-0.1.0/tests/test_projects_pack.py +233 -0
  137. seam_studio-0.1.0/tests/test_provenance_race.py +59 -0
  138. seam_studio-0.1.0/tests/test_render.py +129 -0
  139. seam_studio-0.1.0/tests/test_review_regressions.py +251 -0
  140. seam_studio-0.1.0/tests/test_rf_compiler.py +389 -0
  141. seam_studio-0.1.0/tests/test_rfdata_export.py +384 -0
  142. seam_studio-0.1.0/tests/test_scenario.py +555 -0
  143. seam_studio-0.1.0/tests/test_scene_bounds.py +183 -0
  144. seam_studio-0.1.0/tests/test_scene_schema.py +208 -0
  145. seam_studio-0.1.0/tests/test_seam_agent.py +349 -0
  146. seam_studio-0.1.0/tests/test_segmentation_api.py +284 -0
  147. seam_studio-0.1.0/tests/test_sionna_backend.py +178 -0
  148. seam_studio-0.1.0/tests/test_solver_controls.py +369 -0
  149. seam_studio-0.1.0/tests/test_terrain.py +233 -0
  150. seam_studio-0.1.0/tests/test_textured_import.py +336 -0
  151. seam_studio-0.1.0/tests/test_trajectory_routes.py +673 -0
  152. seam_studio-0.1.0/tests/test_validation.py +239 -0
  153. seam_studio-0.1.0/tests/test_validation_checklist.py +214 -0
  154. seam_studio-0.1.0/tests/test_variant_selection.py +62 -0
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ recursive-include seam_studio/data *.yaml
3
+ recursive-include seam_studio/static *
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: seam-studio
3
+ Version: 0.1.0
4
+ Summary: SEAM Studio - unified RF-visual scene authoring, RF material assignment, and Sionna RT digital-twin simulation workbench
5
+ Author-email: Jaewoo Lee <doni04164@gmail.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Repository, https://github.com/jaewoo4200/SEAM
8
+ Project-URL: Issues, https://github.com/jaewoo4200/SEAM/issues
9
+ Project-URL: Documentation, https://jaewoo4200.github.io/SEAM/
10
+ Keywords: sionna,ray-tracing,digital-twin,RF,6G,ISAC,radio-propagation
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Intended Audience :: Telecommunications Industry
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Scientific/Engineering :: Physics
18
+ Classifier: Topic :: Communications
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: fastapi>=0.111
22
+ Requires-Dist: python-multipart>=0.0.9
23
+ Requires-Dist: uvicorn[standard]>=0.30
24
+ Requires-Dist: pydantic>=2.7
25
+ Requires-Dist: numpy>=1.26
26
+ Requires-Dist: trimesh>=4.4
27
+ Requires-Dist: scipy>=1.11
28
+ Requires-Dist: rtree>=1.2
29
+ Requires-Dist: shapely>=2.0
30
+ Requires-Dist: mapbox-earcut>=1.0
31
+ Requires-Dist: pyyaml>=6.0
32
+ Requires-Dist: httpx>=0.27
33
+ Requires-Dist: pillow>=10.3
34
+ Requires-Dist: ddgs>=9.0
35
+ Requires-Dist: sionna-rt>=2.0
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=8.2; extra == "dev"
38
+ Provides-Extra: sionna
39
+ Requires-Dist: sionna-rt>=2.0; extra == "sionna"
40
+ Provides-Extra: results
41
+ Requires-Dist: duckdb>=1.0; extra == "results"
42
+ Requires-Dist: pyarrow>=16; extra == "results"
43
+ Requires-Dist: zarr>=2.18; extra == "results"
44
+
45
+ # SEAM Studio
46
+
47
+ **Unified RF–visual scene authoring, RF material assignment, and
48
+ [Sionna RT](https://github.com/NVlabs/sionna-rt) digital-twin simulation — in one
49
+ local workbench.**
50
+
51
+ SEAM Studio pairs a FastAPI backend with a bundled React/three.js frontend:
52
+ author a 3D scene, bind ITU/custom RF materials to its surfaces (by hand,
53
+ by rules, or with a local-LLM agent), then ray-trace paths, radio maps,
54
+ UE/UAV trajectories, Doppler, beamforming and handover — all persisted as
55
+ reproducible result sets.
56
+
57
+ ## Install
58
+
59
+ ```bash
60
+ pip install seam-studio
61
+ ```
62
+
63
+ This installs the real ray-tracing engine (`sionna-rt`, Dr.Jit/Mitsuba) by
64
+ default — no GPU required (an LLVM CPU backend is used when CUDA is absent),
65
+ and the app falls back to its deterministic Mock engine if the import fails.
66
+
67
+ ## Quickstart
68
+
69
+ ```bash
70
+ seam-studio # starts on http://127.0.0.1:8000 and opens the browser
71
+ ```
72
+
73
+ The first run creates a **Sample Demo** project (toy urban scene with a
74
+ rooftop TX, street RX, car and pedestrian actors) under `~/.seam/projects`,
75
+ so you can press **Simulate paths** immediately.
76
+
77
+ ```
78
+ seam-studio --port 9000 # different port
79
+ seam-studio --project-root D:\twins # keep projects elsewhere
80
+ seam-studio --no-browser
81
+ ```
82
+
83
+ ## Highlights
84
+
85
+ - **Scene → RF binding**: import Mitsuba XML / scene bundles / OpenStreetMap
86
+ extrusions; assign RF materials per surface with validation and provenance.
87
+ - **Simulation**: paths, planar & mesh radio maps, multi-TX SINR/RSRP/RSRQ,
88
+ MIMO beamforming, UE/UAV trajectories with per-step handover (3GPP A3),
89
+ Doppler spectrograms, ML ground-truth dataset export (NPZ).
90
+ - **AI assist**: local LLM/VLM material suggestion agent (Ollama / LM Studio),
91
+ natural-language assignment rules, validation explains.
92
+ - **Reproducibility**: every run persisted with config snapshots + content
93
+ hashes; measurement import and calibration against real logs.
94
+
95
+ ## Links
96
+
97
+ - Repository & docs: <https://github.com/jaewoo4200/SEAM>
98
+ - Website: <https://jaewoo4200.github.io/SEAM/>
99
+
100
+ Apache-2.0 © Jaewoo Lee
@@ -0,0 +1,56 @@
1
+ # SEAM Studio
2
+
3
+ **Unified RF–visual scene authoring, RF material assignment, and
4
+ [Sionna RT](https://github.com/NVlabs/sionna-rt) digital-twin simulation — in one
5
+ local workbench.**
6
+
7
+ SEAM Studio pairs a FastAPI backend with a bundled React/three.js frontend:
8
+ author a 3D scene, bind ITU/custom RF materials to its surfaces (by hand,
9
+ by rules, or with a local-LLM agent), then ray-trace paths, radio maps,
10
+ UE/UAV trajectories, Doppler, beamforming and handover — all persisted as
11
+ reproducible result sets.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ pip install seam-studio
17
+ ```
18
+
19
+ This installs the real ray-tracing engine (`sionna-rt`, Dr.Jit/Mitsuba) by
20
+ default — no GPU required (an LLVM CPU backend is used when CUDA is absent),
21
+ and the app falls back to its deterministic Mock engine if the import fails.
22
+
23
+ ## Quickstart
24
+
25
+ ```bash
26
+ seam-studio # starts on http://127.0.0.1:8000 and opens the browser
27
+ ```
28
+
29
+ The first run creates a **Sample Demo** project (toy urban scene with a
30
+ rooftop TX, street RX, car and pedestrian actors) under `~/.seam/projects`,
31
+ so you can press **Simulate paths** immediately.
32
+
33
+ ```
34
+ seam-studio --port 9000 # different port
35
+ seam-studio --project-root D:\twins # keep projects elsewhere
36
+ seam-studio --no-browser
37
+ ```
38
+
39
+ ## Highlights
40
+
41
+ - **Scene → RF binding**: import Mitsuba XML / scene bundles / OpenStreetMap
42
+ extrusions; assign RF materials per surface with validation and provenance.
43
+ - **Simulation**: paths, planar & mesh radio maps, multi-TX SINR/RSRP/RSRQ,
44
+ MIMO beamforming, UE/UAV trajectories with per-step handover (3GPP A3),
45
+ Doppler spectrograms, ML ground-truth dataset export (NPZ).
46
+ - **AI assist**: local LLM/VLM material suggestion agent (Ollama / LM Studio),
47
+ natural-language assignment rules, validation explains.
48
+ - **Reproducibility**: every run persisted with config snapshots + content
49
+ hashes; measurement import and calibration against real logs.
50
+
51
+ ## Links
52
+
53
+ - Repository & docs: <https://github.com/jaewoo4200/SEAM>
54
+ - Website: <https://jaewoo4200.github.io/SEAM/>
55
+
56
+ Apache-2.0 © Jaewoo Lee
@@ -0,0 +1,86 @@
1
+ [build-system]
2
+ # >=77 for PEP 639 SPDX license expressions (CI installs from a clean env).
3
+ requires = ["setuptools>=77"]
4
+ build-backend = "setuptools.build_meta"
5
+
6
+ [project]
7
+ # The pip-installable app: `pip install seam-studio` → `seam-studio` serves
8
+ # the backend + the bundled frontend. ("seam" itself is taken on PyPI.)
9
+ name = "seam-studio"
10
+ version = "0.1.0"
11
+ description = "SEAM Studio - unified RF-visual scene authoring, RF material assignment, and Sionna RT digital-twin simulation workbench"
12
+ readme = "README.md"
13
+ requires-python = ">=3.11"
14
+ # SPDX expression (the license text lives at the repo root; a ../LICENSE file
15
+ # reference breaks modern setuptools, which forbids paths outside the project).
16
+ license = "Apache-2.0"
17
+ authors = [{ name = "Jaewoo Lee", email = "doni04164@gmail.com" }]
18
+ keywords = ["sionna", "ray-tracing", "digital-twin", "RF", "6G", "ISAC", "radio-propagation"]
19
+ classifiers = [
20
+ "Development Status :: 4 - Beta",
21
+ "Intended Audience :: Science/Research",
22
+ "Intended Audience :: Telecommunications Industry",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.14",
26
+ "Topic :: Scientific/Engineering :: Physics",
27
+ "Topic :: Communications",
28
+ ]
29
+ dependencies = [
30
+ "fastapi>=0.111",
31
+ "python-multipart>=0.0.9",
32
+ "uvicorn[standard]>=0.30",
33
+ "pydantic>=2.7",
34
+ "numpy>=1.26",
35
+ "trimesh>=4.4",
36
+ # Scene import (Mitsuba XML -> GLB) uses trimesh geometry ops that
37
+ # require scipy at runtime.
38
+ "scipy>=1.11",
39
+ # trimesh ray casting (terrain-following trajectories) needs an R-tree.
40
+ "rtree>=1.2",
41
+ # OpenStreetMap import: extrude building footprints (shapely polygons) via
42
+ # trimesh, which needs an FSF-approved triangulation engine at runtime.
43
+ "shapely>=2.0",
44
+ "mapbox-earcut>=1.0",
45
+ "pyyaml>=6.0",
46
+ "httpx>=0.27",
47
+ "pillow>=10.3",
48
+ # SEAM-Agent web/image evidence retrieval (DuckDuckGo, keyless). Only used
49
+ # when the user opts into online evidence; import stays lazy.
50
+ "ddgs>=9.0",
51
+ # The real ray-tracing engine, installed by default so `pip install
52
+ # seam-studio` matches `pip install sionna` expectations (Dr.Jit/Mitsuba
53
+ # ship an LLVM CPU backend, so no GPU is required to install or run).
54
+ # The app still degrades gracefully to the Mock backend if the import
55
+ # fails at runtime (HANDOFF rule: never break when Sionna is missing).
56
+ "sionna-rt>=2.0",
57
+ ]
58
+
59
+ [project.scripts]
60
+ seam-studio = "seam_studio.cli:main"
61
+
62
+ [project.urls]
63
+ Repository = "https://github.com/jaewoo4200/SEAM"
64
+ Issues = "https://github.com/jaewoo4200/SEAM/issues"
65
+ Documentation = "https://jaewoo4200.github.io/SEAM/"
66
+
67
+ [project.optional-dependencies]
68
+ dev = ["pytest>=8.2"]
69
+ # Back-compat alias from when sionna-rt was opt-in; it is a base dependency
70
+ # now, so this extra is a no-op kept so `pip install "seam-studio[sionna]"`
71
+ # instructions keep working.
72
+ sionna = ["sionna-rt>=2.0"]
73
+ # Future columnar result schemas (paths.parquet, radio_map.parquet, cir.zarr).
74
+ results = ["duckdb>=1.0", "pyarrow>=16", "zarr>=2.18"]
75
+
76
+ [tool.setuptools.packages.find]
77
+ include = ["seam_studio*"]
78
+
79
+ [tool.setuptools.package-data]
80
+ # default_rf_materials.yaml + the frontend bundle copied in by
81
+ # scripts/build_wheel.py (seam_studio/static is gitignored; wheels carry it).
82
+ seam_studio = ["data/*.yaml", "static/**/*"]
83
+
84
+ [tool.pytest.ini_options]
85
+ testpaths = ["tests"]
86
+ addopts = "-q"
File without changes
File without changes
@@ -0,0 +1,149 @@
1
+ """SEAM-Agent endpoints (retrieval-augmented RF material authoring).
2
+
3
+ POST /projects/{id}/agent/material-assignment/start spawn a job
4
+ (409 while one is
5
+ already running)
6
+ GET /projects/{id}/agent/material-assignment/{jid}/trace activity trace
7
+ (memory, or disk
8
+ after a restart)
9
+ POST /projects/{id}/agent/material-assignment/{jid}/cancel cooperative stop
10
+ POST /projects/{id}/agent/material-assignment/{jid}/apply bake accepted
11
+ segments (undo
12
+ via segmentation
13
+ /undo)
14
+
15
+ The trace is the user-visible "thinking": bounded steps, search queries,
16
+ evidence cards, live progress/ETA and segment proposals - never raw
17
+ chain-of-thought.
18
+ """
19
+
20
+ from fastapi import APIRouter, HTTPException
21
+
22
+ from seam_studio.api.deps import get_store, load_scene_or_404
23
+ from seam_studio.schemas.seam_agent import (
24
+ AgentApplyRequest,
25
+ AgentApplyResponse,
26
+ AgentCancelResponse,
27
+ AgentStartRequest,
28
+ AgentStartResponse,
29
+ AgentTrace,
30
+ )
31
+ from seam_studio.services import seam_agent
32
+ from seam_studio.services.material_segmentation import SegmentationError
33
+
34
+ router = APIRouter(tags=["agent"])
35
+
36
+
37
+ @router.post(
38
+ "/projects/{project_id}/agent/material-assignment/start",
39
+ response_model=AgentStartResponse,
40
+ )
41
+ def agent_start(project_id: str, request: AgentStartRequest) -> AgentStartResponse:
42
+ store = get_store()
43
+ scene = load_scene_or_404(store, project_id)
44
+ project_dir = store.resolve(project_id)
45
+ if scene.prim_by_id(request.prim_id) is None:
46
+ raise HTTPException(status_code=404, detail=f"prim not found: {request.prim_id}")
47
+ b = request.budget
48
+ budget = seam_agent.AgentBudget(
49
+ max_web_searches=b.max_web_searches if b else 6,
50
+ max_image_searches=b.max_image_searches if b else 4,
51
+ max_vlm_calls=b.max_vlm_calls if b else 40,
52
+ max_refine_calls=b.max_refine_calls if b else 3,
53
+ max_runtime_sec=b.max_runtime_sec if b else 600,
54
+ )
55
+ try:
56
+ job_id = seam_agent.start_job(
57
+ project_dir,
58
+ scene,
59
+ request.prim_id,
60
+ [v.model_dump() for v in request.views],
61
+ request.user_hint,
62
+ request.allow_web,
63
+ request.model,
64
+ budget,
65
+ )
66
+ except seam_agent.AgentBusyError as exc:
67
+ # One job per project (and a small global cap): multi-building runs
68
+ # are sequential by design — the FE queues and retries.
69
+ raise HTTPException(status_code=409, detail=str(exc))
70
+ return AgentStartResponse(job_id=job_id)
71
+
72
+
73
+ @router.get(
74
+ "/projects/{project_id}/agent/material-assignment/{job_id}/trace",
75
+ response_model=AgentTrace,
76
+ )
77
+ def agent_trace(project_id: str, job_id: str) -> AgentTrace:
78
+ store = get_store()
79
+ load_scene_or_404(store, project_id)
80
+ project_dir = store.resolve(project_id)
81
+ # Live jobs from memory; finished jobs rehydrate from ai/agent/<id>/ so
82
+ # traces stay reviewable after a backend restart.
83
+ job = seam_agent.resolve_job(project_dir, job_id)
84
+ if job is None:
85
+ raise HTTPException(status_code=404, detail=f"unknown job: {job_id}")
86
+ return AgentTrace(
87
+ status=job.status, # type: ignore[arg-type]
88
+ detail=job.detail or None,
89
+ steps=job.steps, # type: ignore[arg-type]
90
+ evidence=job.evidence, # type: ignore[arg-type]
91
+ segments=job.segments, # type: ignore[arg-type]
92
+ progress=(job.progress or None), # type: ignore[arg-type]
93
+ views=job.view_assets, # type: ignore[arg-type]
94
+ )
95
+
96
+
97
+ @router.post(
98
+ "/projects/{project_id}/agent/material-assignment/{job_id}/cancel",
99
+ response_model=AgentCancelResponse,
100
+ )
101
+ def agent_cancel(project_id: str, job_id: str) -> AgentCancelResponse:
102
+ store = get_store()
103
+ load_scene_or_404(store, project_id)
104
+ accepted = seam_agent.cancel_job(job_id)
105
+ return AgentCancelResponse(status="accepted" if accepted else "not_running")
106
+
107
+
108
+ @router.post(
109
+ "/projects/{project_id}/agent/material-assignment/{job_id}/apply",
110
+ response_model=AgentApplyResponse,
111
+ )
112
+ def agent_apply(
113
+ project_id: str, job_id: str, request: AgentApplyRequest
114
+ ) -> AgentApplyResponse:
115
+ store = get_store()
116
+ scene = load_scene_or_404(store, project_id)
117
+ project_dir = store.resolve(project_id)
118
+ job = seam_agent.resolve_job(project_dir, job_id)
119
+ if job is None:
120
+ raise HTTPException(status_code=404, detail=f"unknown job: {job_id}")
121
+ # GLB + scene JSON must move together; same per-project write lock as the
122
+ # segmentation apply/undo routes.
123
+ from seam_studio.services.material_segmentation import project_write_lock
124
+
125
+ with project_write_lock(project_dir):
126
+ try:
127
+ scene, info = seam_agent.apply_segments(
128
+ project_dir, scene, job, request.segment_ids
129
+ )
130
+ except SegmentationError as exc:
131
+ raise HTTPException(status_code=400, detail=str(exc))
132
+ store.save_scene(project_id, scene)
133
+ store.append_provenance(
134
+ project_id,
135
+ {
136
+ "type": "seam_agent_apply",
137
+ "job_id": job_id,
138
+ "prim_id": job.prim_id,
139
+ "segment_ids": request.segment_ids,
140
+ "added_prim_ids": info["added_prim_ids"],
141
+ "backup_glb": info["backup_glb"],
142
+ },
143
+ )
144
+ return AgentApplyResponse(
145
+ added_prim_ids=info["added_prim_ids"],
146
+ removed_prim_id=info["removed_prim_id"],
147
+ backup_glb=info["backup_glb"],
148
+ batch_id=info["batch_id"],
149
+ )