ldcon 0.2.0__py3-none-any.whl

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 (482) hide show
  1. ldcon/__init__.py +302 -0
  2. ldcon/_moved.py +49 -0
  3. ldcon/agent_tools.py +4 -0
  4. ldcon/agents/__init__.py +1 -0
  5. ldcon/agents/adjustment_guidance.py +73 -0
  6. ldcon/agents/adjustment_quality.py +399 -0
  7. ldcon/agents/agent_adapters.py +709 -0
  8. ldcon/agents/agent_background.py +307 -0
  9. ldcon/agents/agent_bundle.py +75 -0
  10. ldcon/agents/agent_cards.py +171 -0
  11. ldcon/agents/agent_config_access.py +22 -0
  12. ldcon/agents/agent_configuration.py +224 -0
  13. ldcon/agents/agent_configuration_policy.py +67 -0
  14. ldcon/agents/agent_connect.py +93 -0
  15. ldcon/agents/agent_device_parameters.py +41 -0
  16. ldcon/agents/agent_execution.py +77 -0
  17. ldcon/agents/agent_history.py +112 -0
  18. ldcon/agents/agent_inbox_watch.py +121 -0
  19. ldcon/agents/agent_interactive.py +386 -0
  20. ldcon/agents/agent_interactive_hooks.py +381 -0
  21. ldcon/agents/agent_language.py +48 -0
  22. ldcon/agents/agent_log_context.py +308 -0
  23. ldcon/agents/agent_log_read.py +250 -0
  24. ldcon/agents/agent_log_watch.py +27 -0
  25. ldcon/agents/agent_metrics.py +111 -0
  26. ldcon/agents/agent_monitor.py +272 -0
  27. ldcon/agents/agent_opencode_http.py +270 -0
  28. ldcon/agents/agent_opencode_mcp.py +64 -0
  29. ldcon/agents/agent_owner_status.py +216 -0
  30. ldcon/agents/agent_profiles.py +186 -0
  31. ldcon/agents/agent_providers.py +53 -0
  32. ldcon/agents/agent_repairs.py +105 -0
  33. ldcon/agents/agent_routing.py +90 -0
  34. ldcon/agents/agent_runtime.py +70 -0
  35. ldcon/agents/agent_sandbox.py +141 -0
  36. ldcon/agents/agent_startup_notice.py +142 -0
  37. ldcon/agents/agent_task.py +336 -0
  38. ldcon/agents/agent_tools.py +488 -0
  39. ldcon/agents/agent_window.py +70 -0
  40. ldcon/agents/agent_workspace.py +340 -0
  41. ldcon/agents/card_fallback.py +284 -0
  42. ldcon/agents/dlc_pi_adjustment.py +250 -0
  43. ldcon/agents/dlc_pi_plan.py +24 -0
  44. ldcon/agents/dlc_pi_response_plan.py +26 -0
  45. ldcon/agents/failure_policy.py +473 -0
  46. ldcon/agents/fallback_service.py +146 -0
  47. ldcon/agents/fallback_targets.py +96 -0
  48. ldcon/agents/gateway_role.py +31 -0
  49. ldcon/agents/manual_adjustment_grant.py +66 -0
  50. ldcon/agents/measurement_grant.py +95 -0
  51. ldcon/agents/monitor_quality_binding.py +33 -0
  52. ldcon/agents/notification_policy.py +346 -0
  53. ldcon/agents/operating_mode_client.py +99 -0
  54. ldcon/agents/report_pdf.py +105 -0
  55. ldcon/agents/resident_adjustment.py +572 -0
  56. ldcon/agents/resident_agent.py +438 -0
  57. ldcon/agents/resident_quality_apply.py +233 -0
  58. ldcon/agents/task_decisions.py +218 -0
  59. ldcon/agents/teams_card.py +100 -0
  60. ldcon/agents/teams_destinations.py +157 -0
  61. ldcon/cld_owner.py +4 -0
  62. ldcon/cli.py +19 -0
  63. ldcon/core/__init__.py +1 -0
  64. ldcon/core/adjustment_plan.py +47 -0
  65. ldcon/core/adjustment_registry.py +100 -0
  66. ldcon/core/agent_authority.py +903 -0
  67. ldcon/core/card_admission.py +15 -0
  68. ldcon/core/card_definition.py +14 -0
  69. ldcon/core/card_reporting.py +238 -0
  70. ldcon/core/configuration.py +357 -0
  71. ldcon/core/configuration_transaction.py +225 -0
  72. ldcon/core/contracts.py +86 -0
  73. ldcon/core/current_settings.py +86 -0
  74. ldcon/core/deck_yaml.py +45 -0
  75. ldcon/core/device_conditions.py +133 -0
  76. ldcon/core/execution_context.py +3 -0
  77. ldcon/core/instrument_client.py +190 -0
  78. ldcon/core/interface_cards.py +520 -0
  79. ldcon/core/interface_schema.py +640 -0
  80. ldcon/core/laser_assets.py +238 -0
  81. ldcon/core/metric_quantities.py +38 -0
  82. ldcon/core/modulation.py +107 -0
  83. ldcon/core/operation_registry.py +195 -0
  84. ldcon/core/paths.py +26 -0
  85. ldcon/core/period_context.py +118 -0
  86. ldcon/core/records.py +4 -0
  87. ldcon/core/result_reservations.py +469 -0
  88. ldcon/core/site_bindings.py +25 -0
  89. ldcon/core/state_layout.py +70 -0
  90. ldcon/core/target_policy.py +79 -0
  91. ldcon/core/telegraf.py +106 -0
  92. ldcon/core/telemetry.py +130 -0
  93. ldcon/core/temperature_settings.py +12 -0
  94. ldcon/dashboard_metrics.py +4 -0
  95. ldcon/device_registry.py +4 -0
  96. ldcon/drivers/__init__.py +1 -0
  97. ldcon/drivers/cld1015.py +296 -0
  98. ldcon/drivers/cld1015_config.py +31 -0
  99. ldcon/drivers/dlcpro.py +177 -0
  100. ldcon/drivers/dlcpro_analog.py +33 -0
  101. ldcon/drivers/dlcpro_console.py +133 -0
  102. ldcon/drivers/dlcpro_priority.py +46 -0
  103. ldcon/drivers/ecdl.py +334 -0
  104. ldcon/drivers/esp32_servo.py +187 -0
  105. ldcon/drivers/fizeau.py +114 -0
  106. ldcon/drivers/frequency_sweep.py +69 -0
  107. ldcon/drivers/influx_wavelength.py +70 -0
  108. ldcon/drivers/metric_sources.py +82 -0
  109. ldcon/drivers/native_dither_telemetry.py +50 -0
  110. ldcon/drivers/rigol_scope.py +126 -0
  111. ldcon/drivers/siglent.py +418 -0
  112. ldcon/drivers/staircase.py +155 -0
  113. ldcon/drivers/wsu_udp.py +164 -0
  114. ldcon/esp32_time_telemetry.py +4 -0
  115. ldcon/example_config.py +41 -0
  116. ldcon/fallback_service.py +4 -0
  117. ldcon/instrument_owner.py +4 -0
  118. ldcon/instrument_service.py +4 -0
  119. ldcon/interface_worker.py +4 -0
  120. ldcon/job_service.py +4 -0
  121. ldcon/jobs/__init__.py +1 -0
  122. ldcon/jobs/adaptive_pid.py +234 -0
  123. ldcon/jobs/adaptive_window_session.py +922 -0
  124. ldcon/jobs/adjustment_continuation.py +284 -0
  125. ldcon/jobs/axis_frequency.py +219 -0
  126. ldcon/jobs/axis_frequency_report.py +86 -0
  127. ldcon/jobs/background_parameter_session.py +142 -0
  128. ldcon/jobs/background_pid_session.py +447 -0
  129. ldcon/jobs/branch_maps.py +71 -0
  130. ldcon/jobs/branch_target_migration.py +33 -0
  131. ldcon/jobs/card_runtime.py +157 -0
  132. ldcon/jobs/change_measure.py +293 -0
  133. ldcon/jobs/change_measure_adapter.py +360 -0
  134. ldcon/jobs/change_measure_dlc.py +94 -0
  135. ldcon/jobs/change_measure_parameters.py +222 -0
  136. ldcon/jobs/change_measure_target.py +135 -0
  137. ldcon/jobs/current_cards.py +159 -0
  138. ldcon/jobs/current_devices.py +71 -0
  139. ldcon/jobs/dashboard_api.py +61 -0
  140. ldcon/jobs/device_parameters.py +426 -0
  141. ldcon/jobs/dlc_pi_measurement.py +151 -0
  142. ldcon/jobs/dlcpro_awg_analysis.py +77 -0
  143. ldcon/jobs/dlcpro_awg_card.py +116 -0
  144. ldcon/jobs/dlcpro_cards.py +240 -0
  145. ldcon/jobs/ecdl_branch_hop.py +175 -0
  146. ldcon/jobs/ecdl_branch_recovery.py +176 -0
  147. ldcon/jobs/ecdl_devices.py +306 -0
  148. ldcon/jobs/ecdl_locked_sweep_proxy.py +526 -0
  149. ldcon/jobs/ecdl_mapped_recovery.py +6 -0
  150. ldcon/jobs/ecdl_mode_map.py +469 -0
  151. ldcon/jobs/ecdl_mode_recovery.py +20 -0
  152. ldcon/jobs/ecdl_online.py +158 -0
  153. ldcon/jobs/ecdl_operating_point.py +403 -0
  154. ldcon/jobs/ecdl_pi_commission.py +161 -0
  155. ldcon/jobs/ecdl_recovery.py +25 -0
  156. ldcon/jobs/ecdl_recovery_plan.py +90 -0
  157. ldcon/jobs/ecdl_recovery_test.py +59 -0
  158. ldcon/jobs/ecdl_relock.py +7 -0
  159. ldcon/jobs/ecdl_response_study.py +369 -0
  160. ldcon/jobs/ecdl_steady.py +343 -0
  161. ldcon/jobs/ecdl_thermal_context.py +242 -0
  162. ldcon/jobs/ecdl_window_center.py +734 -0
  163. ldcon/jobs/emission_card.py +102 -0
  164. ldcon/jobs/fringe_sweep_reference.py +89 -0
  165. ldcon/jobs/interface_devices.py +122 -0
  166. ldcon/jobs/interface_worker.py +471 -0
  167. ldcon/jobs/job_service.py +125 -0
  168. ldcon/jobs/laser_live.py +270 -0
  169. ldcon/jobs/learned_settling.py +450 -0
  170. ldcon/jobs/lock_target.py +461 -0
  171. ldcon/jobs/locked_triangle.py +36 -0
  172. ldcon/jobs/measurement_acquisition.py +51 -0
  173. ldcon/jobs/measurement_analysis.py +59 -0
  174. ldcon/jobs/measurement_execution.py +40 -0
  175. ldcon/jobs/measurement_notice.py +78 -0
  176. ldcon/jobs/measurement_presets.py +52 -0
  177. ldcon/jobs/measurement_report.py +76 -0
  178. ldcon/jobs/measurement_statistics.py +22 -0
  179. ldcon/jobs/metric_cards.py +34 -0
  180. ldcon/jobs/metric_interface.py +100 -0
  181. ldcon/jobs/modulation_sweep.py +274 -0
  182. ldcon/jobs/native_background_session.py +91 -0
  183. ldcon/jobs/native_current_acquire.py +143 -0
  184. ldcon/jobs/native_current_card.py +328 -0
  185. ldcon/jobs/native_current_online.py +129 -0
  186. ldcon/jobs/native_ff_proxy.py +1361 -0
  187. ldcon/jobs/native_ff_sweep.py +802 -0
  188. ldcon/jobs/online_pid.py +178 -0
  189. ldcon/jobs/operating_point.py +1399 -0
  190. ldcon/jobs/operating_point_proxy.py +236 -0
  191. ldcon/jobs/operation_execution.py +126 -0
  192. ldcon/jobs/operation_history.py +419 -0
  193. ldcon/jobs/optical_broker.py +23 -0
  194. ldcon/jobs/pi_algorithms.py +30 -0
  195. ldcon/jobs/pi_response.py +239 -0
  196. ldcon/jobs/progress.py +63 -0
  197. ldcon/jobs/quality_baseline.py +411 -0
  198. ldcon/jobs/recovery_decisions.py +131 -0
  199. ldcon/jobs/recovery_history.py +152 -0
  200. ldcon/jobs/recovery_procedure.py +285 -0
  201. ldcon/jobs/recovery_reference.py +123 -0
  202. ldcon/jobs/recovery_stationary.py +138 -0
  203. ldcon/jobs/response_algorithms.py +47 -0
  204. ldcon/jobs/response_comparison.py +62 -0
  205. ldcon/jobs/response_record.py +90 -0
  206. ldcon/jobs/runtime_parameters.py +434 -0
  207. ldcon/jobs/settling_profile.py +140 -0
  208. ldcon/jobs/shot_analysis.py +1300 -0
  209. ldcon/jobs/simulation.py +127 -0
  210. ldcon/jobs/slow_control.py +208 -0
  211. ldcon/jobs/slow_current.py +88 -0
  212. ldcon/jobs/study_adoption.py +122 -0
  213. ldcon/jobs/study_execution.py +182 -0
  214. ldcon/jobs/sweep_ff_analysis.py +320 -0
  215. ldcon/jobs/sweep_ff_optimization.py +202 -0
  216. ldcon/jobs/sweep_ff_plan.py +166 -0
  217. ldcon/jobs/sweep_ff_report.py +254 -0
  218. ldcon/jobs/sweep_ff_transport.py +326 -0
  219. ldcon/jobs/sweep_tracking.py +424 -0
  220. ldcon/jobs/sweep_verdict.py +288 -0
  221. ldcon/jobs/target_response.py +638 -0
  222. ldcon/jobs/target_response_analysis.py +65 -0
  223. ldcon/jobs/target_response_control.py +215 -0
  224. ldcon/jobs/target_response_decisions.py +152 -0
  225. ldcon/jobs/target_response_experiment.py +110 -0
  226. ldcon/jobs/target_response_feedforward.py +130 -0
  227. ldcon/jobs/target_response_search.py +225 -0
  228. ldcon/jobs/target_response_shift.py +475 -0
  229. ldcon/jobs/target_response_thermal.py +113 -0
  230. ldcon/jobs/target_response_thermal_experiment.py +120 -0
  231. ldcon/jobs/target_sequence.py +166 -0
  232. ldcon/jobs/temperature_identification.py +86 -0
  233. ldcon/jobs/wavelength_history.py +17 -0
  234. ldcon/jobs/window_actions.py +641 -0
  235. ldcon/jobs/window_center.py +784 -0
  236. ldcon/jobs/window_control.py +130 -0
  237. ldcon/jobs/window_decisions.py +105 -0
  238. ldcon/jobs/window_sampling.py +66 -0
  239. ldcon/jobs/workflow_artifacts.py +73 -0
  240. ldcon/migration/__init__.py +810 -0
  241. ldcon/migration/migration_decks.py +239 -0
  242. ldcon/migration/migration_readiness.py +397 -0
  243. ldcon/migration/migration_relocation.py +283 -0
  244. ldcon/monitor_owner.py +4 -0
  245. ldcon/owner_telemetry.py +4 -0
  246. ldcon/owners/__init__.py +1 -0
  247. ldcon/owners/adc_log_threshold.py +209 -0
  248. ldcon/owners/background_grants.py +44 -0
  249. ldcon/owners/cld_instrument_owner.py +96 -0
  250. ldcon/owners/cld_owner.py +706 -0
  251. ldcon/owners/cld_projection.py +194 -0
  252. ldcon/owners/cld_system_owner.py +276 -0
  253. ldcon/owners/current_owner.py +68 -0
  254. ldcon/owners/device_registry.py +229 -0
  255. ldcon/owners/dlcpro_awg_plan.py +115 -0
  256. ldcon/owners/dlcpro_awg_port.py +98 -0
  257. ldcon/owners/dlcpro_awg_protocol.py +190 -0
  258. ldcon/owners/dlcpro_awg_return.py +63 -0
  259. ldcon/owners/dlcpro_awg_sweep.py +437 -0
  260. ldcon/owners/dlcpro_awg_timing.py +35 -0
  261. ldcon/owners/dlcpro_awg_tracking.py +175 -0
  262. ldcon/owners/dlcpro_awg_tracking_guard.py +87 -0
  263. ldcon/owners/dlcpro_awg_tracking_report.py +49 -0
  264. ldcon/owners/dlcpro_awg_zero.py +82 -0
  265. ldcon/owners/dlcpro_deployment.py +66 -0
  266. ldcon/owners/dlcpro_ff.py +64 -0
  267. ldcon/owners/dlcpro_ff_adjustment.py +159 -0
  268. ldcon/owners/dlcpro_ff_delta_adjustment.py +194 -0
  269. ldcon/owners/dlcpro_frequency_window.py +61 -0
  270. ldcon/owners/dlcpro_observation.py +62 -0
  271. ldcon/owners/dlcpro_owner.py +830 -0
  272. ldcon/owners/dlcpro_pi_protocol.py +44 -0
  273. ldcon/owners/dlcpro_pi_trial.py +161 -0
  274. ldcon/owners/dlcpro_readback.py +50 -0
  275. ldcon/owners/dlcpro_service.py +203 -0
  276. ldcon/owners/dlcpro_target_changes.py +330 -0
  277. ldcon/owners/dlcpro_target_step.py +44 -0
  278. ldcon/owners/dlcpro_target_store.py +75 -0
  279. ldcon/owners/dlcpro_telemetry.py +72 -0
  280. ldcon/owners/ecdl_background_parameters.py +248 -0
  281. ldcon/owners/ecdl_background_pid.py +184 -0
  282. ldcon/owners/ecdl_hot_control.py +255 -0
  283. ldcon/owners/ecdl_independent_pid.py +95 -0
  284. ldcon/owners/ecdl_locked_study.py +122 -0
  285. ldcon/owners/ecdl_locked_sweep.py +1875 -0
  286. ldcon/owners/ecdl_native_pid.py +181 -0
  287. ldcon/owners/ecdl_optical.py +37 -0
  288. ldcon/owners/ecdl_owner.py +1058 -0
  289. ldcon/owners/ecdl_policy_reload.py +494 -0
  290. ldcon/owners/ecdl_prelock.py +612 -0
  291. ldcon/owners/ecdl_projection.py +636 -0
  292. ldcon/owners/ecdl_steady_owner.py +1859 -0
  293. ldcon/owners/ecdl_steady_policy.py +212 -0
  294. ldcon/owners/ecdl_target_ff.py +214 -0
  295. ldcon/owners/ecdl_target_settling.py +163 -0
  296. ldcon/owners/ecdl_tec_pair.py +88 -0
  297. ldcon/owners/ecdl_thermal_study.py +251 -0
  298. ldcon/owners/emission.py +365 -0
  299. ldcon/owners/emission_adapters.py +268 -0
  300. ldcon/owners/esp32_native_client.py +335 -0
  301. ldcon/owners/esp32_native_owner.py +2166 -0
  302. ldcon/owners/esp32_time_telemetry.py +253 -0
  303. ldcon/owners/esp32_udp_gate.py +136 -0
  304. ldcon/owners/external_sweep_guard.py +44 -0
  305. ldcon/owners/flexible_native_trial.py +172 -0
  306. ldcon/owners/fringe_peaks.py +92 -0
  307. ldcon/owners/full_data_log.py +133 -0
  308. ldcon/owners/instrument_identity.py +125 -0
  309. ldcon/owners/instrument_owner.py +1041 -0
  310. ldcon/owners/instrument_projection.py +104 -0
  311. ldcon/owners/instrument_service.py +638 -0
  312. ldcon/owners/migration_physical_lock.py +162 -0
  313. ldcon/owners/monitor_owner.py +322 -0
  314. ldcon/owners/native_assembly.py +37 -0
  315. ldcon/owners/native_assembly_host.py +260 -0
  316. ldcon/owners/native_background.py +233 -0
  317. ldcon/owners/native_current_tuning.py +251 -0
  318. ldcon/owners/native_ff_proof.py +433 -0
  319. ldcon/owners/native_instrument_owner.py +161 -0
  320. ldcon/owners/native_modulation_limits.py +45 -0
  321. ldcon/owners/native_policy_reload.py +186 -0
  322. ldcon/owners/native_policy_safety.py +213 -0
  323. ldcon/owners/native_policy_update.py +473 -0
  324. ldcon/owners/native_system_owner.py +420 -0
  325. ldcon/owners/operating_mode_owner.py +128 -0
  326. ldcon/owners/owner_projection.py +530 -0
  327. ldcon/owners/owner_telemetry.py +166 -0
  328. ldcon/owners/pi_handover.py +154 -0
  329. ldcon/owners/projection_transport.py +143 -0
  330. ldcon/owners/remote_instruments.py +323 -0
  331. ldcon/owners/sdg_client.py +122 -0
  332. ldcon/owners/sdg_owner.py +468 -0
  333. ldcon/owners/tec_rate.py +29 -0
  334. ldcon/owners/wsu_udp_monitor.py +113 -0
  335. ldcon/report_pdf.py +4 -0
  336. ldcon/resources/agent-model-options.json +142 -0
  337. ldcon/resources/agent_contract/adjustment.txt +45 -0
  338. ldcon/resources/agent_contract/common.txt +42 -0
  339. ldcon/resources/agent_contract/diagnosis.txt +11 -0
  340. ldcon/resources/agent_contract/research.txt +20 -0
  341. ldcon/resources/agent_contract/response_optimization.txt +13 -0
  342. ldcon/resources/examples/README.html +10 -0
  343. ldcon/resources/examples/assignments/sr1092.yaml +100 -0
  344. ldcon/resources/examples/assignments/sr422.yaml +677 -0
  345. ldcon/resources/examples/assignments/thf685.yaml +7 -0
  346. ldcon/resources/examples/interface-decks/dfb-dbr-ldc-tec.yaml +430 -0
  347. ldcon/resources/examples/interface-decks/ecdl-dlcpro.yaml +288 -0
  348. ldcon/resources/examples/interface-decks/ecdl-pzt-ldc-tec.yaml +698 -0
  349. ldcon/resources/examples/lasers/sr1092.yaml +267 -0
  350. ldcon/resources/examples/lasers/sr422.yaml +403 -0
  351. ldcon/resources/examples/lasers/thf685.yaml +158 -0
  352. ldcon/resources/report_template/ldconreport.cls +42 -0
  353. ldcon/resources/report_template/report.tex +47 -0
  354. ldcon/web/__init__.py +1 -0
  355. ldcon/web/agent_approval_api.py +126 -0
  356. ldcon/web/agent_settings_api.py +54 -0
  357. ldcon/web/agent_task_api.py +211 -0
  358. ldcon/web/control_readback.py +63 -0
  359. ldcon/web/dashboard_activity.py +109 -0
  360. ldcon/web/dashboard_controls_revision.py +29 -0
  361. ldcon/web/dashboard_metrics.py +146 -0
  362. ldcon/web/dashboard_snapshot.py +163 -0
  363. ldcon/web/dashboard_state.py +104 -0
  364. ldcon/web/dashboard_wavelength.py +150 -0
  365. ldcon/web/device_parameters_api.py +52 -0
  366. ldcon/web/dither_quality.py +46 -0
  367. ldcon/web/dlcpro_target_api.py +91 -0
  368. ldcon/web/dlcpro_target_query.py +23 -0
  369. ldcon/web/failure_api.py +62 -0
  370. ldcon/web/gateway_lan.py +208 -0
  371. ldcon/web/grafana_activity.py +84 -0
  372. ldcon/web/grafana_dashboard.py +492 -0
  373. ldcon/web/grafana_dlcpro.py +158 -0
  374. ldcon/web/grafana_quality.py +167 -0
  375. ldcon/web/interface_projection.py +27 -0
  376. ldcon/web/job_registry.py +68 -0
  377. ldcon/web/job_report.py +122 -0
  378. ldcon/web/laser_operations.py +445 -0
  379. ldcon/web/lock_target_api.py +554 -0
  380. ldcon/web/lock_target_queue.py +212 -0
  381. ldcon/web/log_archive.py +191 -0
  382. ldcon/web/metric_query_profiles.py +378 -0
  383. ldcon/web/online_position.py +26 -0
  384. ldcon/web/operating_mode_api.py +72 -0
  385. ldcon/web/operation_api.py +34 -0
  386. ldcon/web/operation_observation.py +57 -0
  387. ldcon/web/operations_settings.py +92 -0
  388. ldcon/web/quality_threshold_metrics.py +64 -0
  389. ldcon/web/shot_analysis_api.py +136 -0
  390. ldcon/web/sweep_api.py +1186 -0
  391. ldcon/web/sweep_guard.py +45 -0
  392. ldcon/web/target_reference_panel.py +38 -0
  393. ldcon/web/teams_destinations_api.py +81 -0
  394. ldcon/web/web_fleet.py +482 -0
  395. ldcon/web/web_runtime.py +811 -0
  396. ldcon/web/web_server.py +402 -0
  397. ldcon/web/window_api.py +28 -0
  398. ldcon/web_assets/agent-settings.css +4 -0
  399. ldcon/web_assets/agent-settings.html +53 -0
  400. ldcon/web_assets/agent-settings.js +270 -0
  401. ldcon/web_assets/app.css +9 -0
  402. ldcon/web_assets/app.js +802 -0
  403. ldcon/web_assets/card-browser.js +160 -0
  404. ldcon/web_assets/card-guide.js +9 -0
  405. ldcon/web_assets/cards/acquire.metrics.html +82 -0
  406. ldcon/web_assets/cards/agent.history_review.html +13 -0
  407. ldcon/web_assets/cards/agent.log_watch.html +1 -0
  408. ldcon/web_assets/cards/agent.monitor.html +13 -0
  409. ldcon/web_assets/cards/agent.request.html +1 -0
  410. ldcon/web_assets/cards/agent.resident.html +1 -0
  411. ldcon/web_assets/cards/agent.task.html +17 -0
  412. ldcon/web_assets/cards/commission.ecdl_pi.html +1 -0
  413. ldcon/web_assets/cards/identify.axis_frequency.html +1 -0
  414. ldcon/web_assets/cards/identify.current_response.html +1 -0
  415. ldcon/web_assets/cards/laser.emission.html +8 -0
  416. ldcon/web_assets/cards/measure.batch.html +1 -0
  417. ldcon/web_assets/cards/measure.change.html +1 -0
  418. ldcon/web_assets/cards/measure.target_response.html +1 -0
  419. ldcon/web_assets/cards/monitor.wavelength.html +1 -0
  420. ldcon/web_assets/cards/notify.teams.html +1 -0
  421. ldcon/web_assets/cards/optimize.settling_criteria.html +1 -0
  422. ldcon/web_assets/cards/optimize.target_feedforward.html +1 -0
  423. ldcon/web_assets/cards/optimize.target_step.html +1 -0
  424. ldcon/web_assets/cards/optimize.target_thermal.html +1 -0
  425. ldcon/web_assets/cards/plan.ecdl_recovery.html +14 -0
  426. ldcon/web_assets/cards/prepare.ecdl_recovery.html +18 -0
  427. ldcon/web_assets/cards/recover.ecdl_mode_hop.html +12 -0
  428. ldcon/web_assets/cards/report.grafana_dashboard.html +22 -0
  429. ldcon/web_assets/cards/servo.current_pid.html +1 -0
  430. ldcon/web_assets/cards/servo.dlcpro_frequency.html +1 -0
  431. ldcon/web_assets/cards/servo.ecdl_steady_lock.html +11 -0
  432. ldcon/web_assets/cards/servo.native_current.html +1 -0
  433. ldcon/web_assets/cards/study.ecdl_current_response.html +1 -0
  434. ldcon/web_assets/cards/study.ecdl_locked_current_map.html +1 -0
  435. ldcon/web_assets/cards/study.ecdl_mode_map.html +6 -0
  436. ldcon/web_assets/cards/study.ecdl_thermal_context.html +5 -0
  437. ldcon/web_assets/cards/study.target_response.html +1 -0
  438. ldcon/web_assets/cards/sweep.current_modulation.html +1 -0
  439. ldcon/web_assets/cards/sweep.dlcpro_frequency.html +1 -0
  440. ldcon/web_assets/cards/sweep.servo_modulation.html +1 -0
  441. ldcon/web_assets/cards/test.ecdl_recovery.html +4 -0
  442. ldcon/web_assets/cards/tune.ecdl_initial_point.html +1 -0
  443. ldcon/web_assets/cards/tune.ecdl_operating_point.html +13 -0
  444. ldcon/web_assets/cards/tune.ecdl_window_center.html +7 -0
  445. ldcon/web_assets/cards/tune.native_current.html +1 -0
  446. ldcon/web_assets/cards/tune.pid_coordinate_search.html +1 -0
  447. ldcon/web_assets/cards/tune.pid_factor_reduction.html +1 -0
  448. ldcon/web_assets/cards/tune.pid_online.html +1 -0
  449. ldcon/web_assets/cards/tune.temperature_once.html +18 -0
  450. ldcon/web_assets/committing-input.js +35 -0
  451. ldcon/web_assets/configuration-editor.js +194 -0
  452. ldcon/web_assets/dashboard-state.js +39 -0
  453. ldcon/web_assets/failures.html +1 -0
  454. ldcon/web_assets/failures.js +19 -0
  455. ldcon/web_assets/fallback.css +3 -0
  456. ldcon/web_assets/fallback.html +1 -0
  457. ldcon/web_assets/fallback.js +21 -0
  458. ldcon/web_assets/fleet-settings.js +20 -0
  459. ldcon/web_assets/fleet.css +9 -0
  460. ldcon/web_assets/fleet.html +8 -0
  461. ldcon/web_assets/fleet.js +130 -0
  462. ldcon/web_assets/gateway-presentation.js +27 -0
  463. ldcon/web_assets/grafana-help.js +31 -0
  464. ldcon/web_assets/help.html +22 -0
  465. ldcon/web_assets/i18n.js +279 -0
  466. ldcon/web_assets/index.html +14 -0
  467. ldcon/web_assets/laser-workspace.js +279 -0
  468. ldcon/web_assets/modulation.html +1 -0
  469. ldcon/web_assets/modulation.js +14 -0
  470. ldcon/web_assets/reservations.html +16 -0
  471. ldcon/web_assets/reservations.js +77 -0
  472. ldcon/web_assets/teams-settings.js +91 -0
  473. ldcon/web_assets/window-actions.js +37 -0
  474. ldcon/web_assets/workspace.css +99 -0
  475. ldcon/web_fleet.py +4 -0
  476. ldcon/web_server.py +4 -0
  477. ldcon-0.2.0.dist-info/METADATA +85 -0
  478. ldcon-0.2.0.dist-info/RECORD +482 -0
  479. ldcon-0.2.0.dist-info/WHEEL +5 -0
  480. ldcon-0.2.0.dist-info/entry_points.txt +5 -0
  481. ldcon-0.2.0.dist-info/licenses/LICENSE +21 -0
  482. ldcon-0.2.0.dist-info/top_level.txt +1 -0
ldcon/__init__.py ADDED
@@ -0,0 +1,302 @@
1
+ """Shared interface cards, instrument ownership and laser dashboard."""
2
+ import importlib as _importlib
3
+ from ldcon._moved import install as _install
4
+
5
+ # Old flat name -> new subpackage path (refactor phase 2). See ldcon/_moved.py; importing ldcon stays lazy.
6
+ MOVED = {
7
+ # G1 (ldcon.migration itself became the package __init__: same name, no alias needed)
8
+ 'ldcon.migration_decks': 'ldcon.migration.migration_decks',
9
+ 'ldcon.migration_readiness': 'ldcon.migration.migration_readiness',
10
+ 'ldcon.migration_relocation': 'ldcon.migration.migration_relocation',
11
+ # G2
12
+ 'ldcon.fizeau': 'ldcon.drivers.fizeau',
13
+ 'ldcon.rigol_scope': 'ldcon.drivers.rigol_scope',
14
+ 'ldcon.esp32_servo': 'ldcon.drivers.esp32_servo',
15
+ # G3 (fallback_service, report_pdf keep an entry stub ldcon/<name>.py)
16
+ 'ldcon.teams_card': 'ldcon.agents.teams_card',
17
+ 'ldcon.teams_destinations': 'ldcon.agents.teams_destinations',
18
+ 'ldcon.notification_policy': 'ldcon.agents.notification_policy',
19
+ 'ldcon.card_fallback': 'ldcon.agents.card_fallback',
20
+ 'ldcon.fallback_targets': 'ldcon.agents.fallback_targets',
21
+ 'ldcon.fallback_service': 'ldcon.agents.fallback_service',
22
+ 'ldcon.failure_policy': 'ldcon.agents.failure_policy',
23
+ 'ldcon.report_pdf': 'ldcon.agents.report_pdf',
24
+ # G4 (dashboard_metrics keeps an entry stub)
25
+ 'ldcon.dashboard_activity': 'ldcon.web.dashboard_activity',
26
+ 'ldcon.dashboard_controls_revision': 'ldcon.web.dashboard_controls_revision',
27
+ 'ldcon.dashboard_metrics': 'ldcon.web.dashboard_metrics',
28
+ 'ldcon.dashboard_snapshot': 'ldcon.web.dashboard_snapshot',
29
+ 'ldcon.dashboard_state': 'ldcon.web.dashboard_state',
30
+ 'ldcon.dashboard_wavelength': 'ldcon.web.dashboard_wavelength',
31
+ 'ldcon.dither_quality': 'ldcon.web.dither_quality',
32
+ 'ldcon.quality_threshold_metrics': 'ldcon.web.quality_threshold_metrics',
33
+ 'ldcon.grafana_activity': 'ldcon.web.grafana_activity',
34
+ 'ldcon.grafana_dashboard': 'ldcon.web.grafana_dashboard',
35
+ 'ldcon.grafana_quality': 'ldcon.web.grafana_quality',
36
+ 'ldcon.metric_query_profiles': 'ldcon.web.metric_query_profiles',
37
+ 'ldcon.target_reference_panel': 'ldcon.web.target_reference_panel',
38
+ 'ldcon.job_report': 'ldcon.web.job_report',
39
+ 'ldcon.log_archive': 'ldcon.web.log_archive',
40
+ 'ldcon.operations_settings': 'ldcon.web.operations_settings',
41
+ 'ldcon.job_registry': 'ldcon.web.job_registry',
42
+ 'ldcon.interface_projection': 'ldcon.web.interface_projection',
43
+ 'ldcon.operation_observation': 'ldcon.web.operation_observation',
44
+ # G5
45
+ 'ldcon.slow_control': 'ldcon.jobs.slow_control',
46
+ 'ldcon.slow_current': 'ldcon.jobs.slow_current',
47
+ 'ldcon.online_pid': 'ldcon.jobs.online_pid',
48
+ 'ldcon.adaptive_pid': 'ldcon.jobs.adaptive_pid',
49
+ 'ldcon.current_cards': 'ldcon.jobs.current_cards',
50
+ 'ldcon.current_devices': 'ldcon.jobs.current_devices',
51
+ 'ldcon.temperature_identification': 'ldcon.jobs.temperature_identification',
52
+ 'ldcon.metric_cards': 'ldcon.jobs.metric_cards',
53
+ 'ldcon.metric_interface': 'ldcon.jobs.metric_interface',
54
+ 'ldcon.optical_broker': 'ldcon.jobs.optical_broker',
55
+ 'ldcon.fringe_sweep_reference': 'ldcon.jobs.fringe_sweep_reference',
56
+ # G6
57
+ 'ldcon.window_actions': 'ldcon.jobs.window_actions',
58
+ 'ldcon.window_center': 'ldcon.jobs.window_center',
59
+ 'ldcon.window_sampling': 'ldcon.jobs.window_sampling',
60
+ 'ldcon.window_control': 'ldcon.jobs.window_control',
61
+ 'ldcon.window_decisions': 'ldcon.jobs.window_decisions',
62
+ 'ldcon.adaptive_window_session': 'ldcon.jobs.adaptive_window_session',
63
+ 'ldcon.adjustment_continuation': 'ldcon.jobs.adjustment_continuation',
64
+ 'ldcon.background_pid_session': 'ldcon.jobs.background_pid_session',
65
+ 'ldcon.background_parameter_session': 'ldcon.jobs.background_parameter_session',
66
+ 'ldcon.simulation': 'ldcon.jobs.simulation',
67
+ # G7
68
+ 'ldcon.ecdl_devices': 'ldcon.jobs.ecdl_devices',
69
+ 'ldcon.ecdl_steady': 'ldcon.jobs.ecdl_steady',
70
+ 'ldcon.ecdl_window_center': 'ldcon.jobs.ecdl_window_center',
71
+ 'ldcon.ecdl_online': 'ldcon.jobs.ecdl_online',
72
+ 'ldcon.ecdl_mode_map': 'ldcon.jobs.ecdl_mode_map',
73
+ 'ldcon.ecdl_mode_recovery': 'ldcon.jobs.ecdl_mode_recovery',
74
+ 'ldcon.ecdl_recovery': 'ldcon.jobs.ecdl_recovery',
75
+ 'ldcon.ecdl_recovery_plan': 'ldcon.jobs.ecdl_recovery_plan',
76
+ 'ldcon.ecdl_recovery_test': 'ldcon.jobs.ecdl_recovery_test',
77
+ 'ldcon.ecdl_relock': 'ldcon.jobs.ecdl_relock',
78
+ 'ldcon.ecdl_response_study': 'ldcon.jobs.ecdl_response_study',
79
+ 'ldcon.ecdl_branch_hop': 'ldcon.jobs.ecdl_branch_hop',
80
+ 'ldcon.ecdl_operating_point': 'ldcon.jobs.ecdl_operating_point',
81
+ 'ldcon.ecdl_thermal_context': 'ldcon.jobs.ecdl_thermal_context',
82
+ 'ldcon.ecdl_pi_commission': 'ldcon.jobs.ecdl_pi_commission',
83
+ 'ldcon.workflow_artifacts': 'ldcon.jobs.workflow_artifacts',
84
+ # G8
85
+ 'ldcon.lock_target': 'ldcon.jobs.lock_target',
86
+ 'ldcon.target_sequence': 'ldcon.jobs.target_sequence',
87
+ 'ldcon.target_response': 'ldcon.jobs.target_response',
88
+ 'ldcon.target_response_analysis': 'ldcon.jobs.target_response_analysis',
89
+ 'ldcon.target_response_control': 'ldcon.jobs.target_response_control',
90
+ 'ldcon.target_response_decisions': 'ldcon.jobs.target_response_decisions',
91
+ 'ldcon.target_response_experiment': 'ldcon.jobs.target_response_experiment',
92
+ 'ldcon.target_response_feedforward': 'ldcon.jobs.target_response_feedforward',
93
+ 'ldcon.target_response_search': 'ldcon.jobs.target_response_search',
94
+ 'ldcon.settling_profile': 'ldcon.jobs.settling_profile',
95
+ 'ldcon.learned_settling': 'ldcon.jobs.learned_settling',
96
+ 'ldcon.pi_response': 'ldcon.jobs.pi_response',
97
+ 'ldcon.wavelength_history': 'ldcon.jobs.wavelength_history',
98
+ 'ldcon.study_execution': 'ldcon.jobs.study_execution',
99
+ 'ldcon.study_adoption': 'ldcon.jobs.study_adoption',
100
+ 'ldcon.quality_baseline': 'ldcon.jobs.quality_baseline',
101
+ 'ldcon.dashboard_api': 'ldcon.jobs.dashboard_api',
102
+ 'ldcon.measurement_notice': 'ldcon.jobs.measurement_notice',
103
+ 'ldcon.operating_point': 'ldcon.jobs.operating_point',
104
+ 'ldcon.device_parameters': 'ldcon.jobs.device_parameters',
105
+ 'ldcon.emission_card': 'ldcon.jobs.emission_card',
106
+ # G9
107
+ 'ldcon.native_ff_proxy': 'ldcon.jobs.native_ff_proxy',
108
+ 'ldcon.native_ff_sweep': 'ldcon.jobs.native_ff_sweep',
109
+ 'ldcon.ecdl_locked_sweep_proxy': 'ldcon.jobs.ecdl_locked_sweep_proxy',
110
+ 'ldcon.modulation_sweep': 'ldcon.jobs.modulation_sweep',
111
+ 'ldcon.shot_analysis': 'ldcon.jobs.shot_analysis',
112
+ 'ldcon.sweep_tracking': 'ldcon.jobs.sweep_tracking',
113
+ 'ldcon.sweep_verdict': 'ldcon.jobs.sweep_verdict',
114
+ 'ldcon.native_current_acquire': 'ldcon.jobs.native_current_acquire',
115
+ 'ldcon.native_current_card': 'ldcon.jobs.native_current_card',
116
+ 'ldcon.native_current_online': 'ldcon.jobs.native_current_online',
117
+ 'ldcon.native_background_session': 'ldcon.jobs.native_background_session',
118
+ 'ldcon.progress': 'ldcon.jobs.progress',
119
+ # G10 (monitor_owner, esp32_time_telemetry keep an entry stub); cld_projection was added after the map (owner-side CLD policy)
120
+ 'ldcon.esp32_native_owner': 'ldcon.owners.esp32_native_owner',
121
+ 'ldcon.esp32_native_client': 'ldcon.owners.esp32_native_client',
122
+ 'ldcon.esp32_udp_gate': 'ldcon.owners.esp32_udp_gate',
123
+ 'ldcon.esp32_time_telemetry': 'ldcon.owners.esp32_time_telemetry',
124
+ 'ldcon.native_assembly': 'ldcon.owners.native_assembly',
125
+ 'ldcon.native_assembly_host': 'ldcon.owners.native_assembly_host',
126
+ 'ldcon.native_background': 'ldcon.owners.native_background',
127
+ 'ldcon.native_current_tuning': 'ldcon.owners.native_current_tuning',
128
+ 'ldcon.native_ff_proof': 'ldcon.owners.native_ff_proof',
129
+ 'ldcon.native_instrument_owner': 'ldcon.owners.native_instrument_owner',
130
+ 'ldcon.native_modulation_limits': 'ldcon.owners.native_modulation_limits',
131
+ 'ldcon.native_policy_reload': 'ldcon.owners.native_policy_reload',
132
+ 'ldcon.native_policy_safety': 'ldcon.owners.native_policy_safety',
133
+ 'ldcon.native_policy_update': 'ldcon.owners.native_policy_update',
134
+ 'ldcon.native_system_owner': 'ldcon.owners.native_system_owner',
135
+ 'ldcon.flexible_native_trial': 'ldcon.owners.flexible_native_trial',
136
+ 'ldcon.adc_log_threshold': 'ldcon.owners.adc_log_threshold',
137
+ 'ldcon.full_data_log': 'ldcon.owners.full_data_log',
138
+ 'ldcon.monitor_owner': 'ldcon.owners.monitor_owner',
139
+ 'ldcon.cld_projection': 'ldcon.owners.cld_projection',
140
+ # G11 (owner_telemetry keeps an entry stub); ecdl_thermal_study, tec_rate were added after the map (owner-only TEC overlay / cadence)
141
+ 'ldcon.ecdl_owner': 'ldcon.owners.ecdl_owner',
142
+ 'ldcon.ecdl_steady_owner': 'ldcon.owners.ecdl_steady_owner',
143
+ 'ldcon.ecdl_steady_policy': 'ldcon.owners.ecdl_steady_policy',
144
+ 'ldcon.ecdl_policy_reload': 'ldcon.owners.ecdl_policy_reload',
145
+ 'ldcon.ecdl_projection': 'ldcon.owners.ecdl_projection',
146
+ 'ldcon.ecdl_native_pid': 'ldcon.owners.ecdl_native_pid',
147
+ 'ldcon.ecdl_background_pid': 'ldcon.owners.ecdl_background_pid',
148
+ 'ldcon.ecdl_background_parameters': 'ldcon.owners.ecdl_background_parameters',
149
+ 'ldcon.background_grants': 'ldcon.owners.background_grants',
150
+ 'ldcon.ecdl_tec_pair': 'ldcon.owners.ecdl_tec_pair',
151
+ 'ldcon.ecdl_target_ff': 'ldcon.owners.ecdl_target_ff',
152
+ 'ldcon.ecdl_target_settling': 'ldcon.owners.ecdl_target_settling',
153
+ 'ldcon.ecdl_hot_control': 'ldcon.owners.ecdl_hot_control',
154
+ 'ldcon.ecdl_locked_sweep': 'ldcon.owners.ecdl_locked_sweep',
155
+ 'ldcon.ecdl_locked_study': 'ldcon.owners.ecdl_locked_study',
156
+ 'ldcon.ecdl_optical': 'ldcon.owners.ecdl_optical',
157
+ 'ldcon.fringe_peaks': 'ldcon.owners.fringe_peaks',
158
+ 'ldcon.external_sweep_guard': 'ldcon.owners.external_sweep_guard',
159
+ 'ldcon.ecdl_prelock': 'ldcon.owners.ecdl_prelock',
160
+ 'ldcon.owner_telemetry': 'ldcon.owners.owner_telemetry',
161
+ 'ldcon.sdg_owner': 'ldcon.owners.sdg_owner',
162
+ 'ldcon.sdg_client': 'ldcon.owners.sdg_client',
163
+ 'ldcon.emission': 'ldcon.owners.emission',
164
+ 'ldcon.emission_adapters': 'ldcon.owners.emission_adapters',
165
+ 'ldcon.operating_mode_owner': 'ldcon.owners.operating_mode_owner',
166
+ 'ldcon.ecdl_thermal_study': 'ldcon.owners.ecdl_thermal_study',
167
+ 'ldcon.tec_rate': 'ldcon.owners.tec_rate',
168
+ # G12 (instrument_owner, instrument_service, cld_owner, device_registry keep an entry stub)
169
+ 'ldcon.instrument_owner': 'ldcon.owners.instrument_owner',
170
+ 'ldcon.instrument_service': 'ldcon.owners.instrument_service',
171
+ 'ldcon.instrument_identity': 'ldcon.owners.instrument_identity',
172
+ 'ldcon.instrument_projection': 'ldcon.owners.instrument_projection',
173
+ 'ldcon.owner_projection': 'ldcon.owners.owner_projection',
174
+ 'ldcon.projection_transport': 'ldcon.owners.projection_transport',
175
+ 'ldcon.device_registry': 'ldcon.owners.device_registry',
176
+ 'ldcon.remote_instruments': 'ldcon.owners.remote_instruments',
177
+ 'ldcon.cld_owner': 'ldcon.owners.cld_owner',
178
+ 'ldcon.cld_instrument_owner': 'ldcon.owners.cld_instrument_owner',
179
+ 'ldcon.cld_system_owner': 'ldcon.owners.cld_system_owner',
180
+ 'ldcon.current_owner': 'ldcon.owners.current_owner',
181
+ 'ldcon.migration_physical_lock': 'ldcon.owners.migration_physical_lock',
182
+ # G13 (agent_tools keeps an entry stub: ENTRY_MODULES and `-m ldcon.agent_tools <context>`)
183
+ 'ldcon.agent_adapters': 'ldcon.agents.agent_adapters',
184
+ 'ldcon.agent_background': 'ldcon.agents.agent_background',
185
+ 'ldcon.agent_bundle': 'ldcon.agents.agent_bundle',
186
+ 'ldcon.agent_cards': 'ldcon.agents.agent_cards',
187
+ 'ldcon.agent_config_access': 'ldcon.agents.agent_config_access',
188
+ 'ldcon.agent_configuration': 'ldcon.agents.agent_configuration',
189
+ 'ldcon.agent_configuration_policy': 'ldcon.agents.agent_configuration_policy',
190
+ 'ldcon.agent_connect': 'ldcon.agents.agent_connect',
191
+ 'ldcon.agent_device_parameters': 'ldcon.agents.agent_device_parameters',
192
+ 'ldcon.agent_execution': 'ldcon.agents.agent_execution',
193
+ 'ldcon.agent_history': 'ldcon.agents.agent_history',
194
+ 'ldcon.agent_inbox_watch': 'ldcon.agents.agent_inbox_watch',
195
+ 'ldcon.agent_interactive': 'ldcon.agents.agent_interactive',
196
+ 'ldcon.agent_interactive_hooks': 'ldcon.agents.agent_interactive_hooks',
197
+ 'ldcon.agent_language': 'ldcon.agents.agent_language',
198
+ 'ldcon.agent_log_context': 'ldcon.agents.agent_log_context',
199
+ 'ldcon.agent_log_read': 'ldcon.agents.agent_log_read',
200
+ 'ldcon.agent_log_watch': 'ldcon.agents.agent_log_watch',
201
+ 'ldcon.agent_metrics': 'ldcon.agents.agent_metrics',
202
+ 'ldcon.agent_monitor': 'ldcon.agents.agent_monitor',
203
+ 'ldcon.agent_opencode_http': 'ldcon.agents.agent_opencode_http',
204
+ 'ldcon.agent_owner_status': 'ldcon.agents.agent_owner_status',
205
+ 'ldcon.agent_profiles': 'ldcon.agents.agent_profiles',
206
+ 'ldcon.agent_providers': 'ldcon.agents.agent_providers',
207
+ 'ldcon.agent_repairs': 'ldcon.agents.agent_repairs',
208
+ 'ldcon.agent_routing': 'ldcon.agents.agent_routing',
209
+ 'ldcon.agent_runtime': 'ldcon.agents.agent_runtime',
210
+ 'ldcon.agent_sandbox': 'ldcon.agents.agent_sandbox',
211
+ 'ldcon.agent_startup_notice': 'ldcon.agents.agent_startup_notice',
212
+ 'ldcon.agent_task': 'ldcon.agents.agent_task',
213
+ 'ldcon.agent_tools': 'ldcon.agents.agent_tools',
214
+ 'ldcon.agent_window': 'ldcon.agents.agent_window',
215
+ 'ldcon.agent_workspace': 'ldcon.agents.agent_workspace',
216
+ 'ldcon.resident_agent': 'ldcon.agents.resident_agent',
217
+ 'ldcon.resident_adjustment': 'ldcon.agents.resident_adjustment',
218
+ 'ldcon.resident_quality_apply': 'ldcon.agents.resident_quality_apply',
219
+ 'ldcon.task_decisions': 'ldcon.agents.task_decisions',
220
+ 'ldcon.gateway_role': 'ldcon.agents.gateway_role',
221
+ 'ldcon.manual_adjustment_grant': 'ldcon.agents.manual_adjustment_grant',
222
+ 'ldcon.monitor_quality_binding': 'ldcon.agents.monitor_quality_binding',
223
+ 'ldcon.adjustment_guidance': 'ldcon.agents.adjustment_guidance',
224
+ 'ldcon.adjustment_quality': 'ldcon.agents.adjustment_quality',
225
+ 'ldcon.operating_mode_client': 'ldcon.agents.operating_mode_client',
226
+ # G14 (job_service, interface_worker keep an entry stub: units, `-m ldcon.interface_worker` spawn + card_fallback cmdline match)
227
+ 'ldcon.job_service': 'ldcon.jobs.job_service',
228
+ 'ldcon.interface_worker': 'ldcon.jobs.interface_worker',
229
+ 'ldcon.interface_devices': 'ldcon.jobs.interface_devices',
230
+ 'ldcon.card_runtime': 'ldcon.jobs.card_runtime',
231
+ 'ldcon.runtime_parameters': 'ldcon.jobs.runtime_parameters',
232
+ 'ldcon.laser_live': 'ldcon.jobs.laser_live',
233
+ 'ldcon.operation_execution': 'ldcon.jobs.operation_execution',
234
+ # G15 (web_server, web_fleet keep an entry stub: units, ldcon.cli:web_main)
235
+ 'ldcon.agent_approval_api': 'ldcon.web.agent_approval_api',
236
+ 'ldcon.agent_settings_api': 'ldcon.web.agent_settings_api',
237
+ 'ldcon.agent_task_api': 'ldcon.web.agent_task_api',
238
+ 'ldcon.device_parameters_api': 'ldcon.web.device_parameters_api',
239
+ 'ldcon.failure_api': 'ldcon.web.failure_api',
240
+ 'ldcon.operating_mode_api': 'ldcon.web.operating_mode_api',
241
+ 'ldcon.operation_api': 'ldcon.web.operation_api',
242
+ 'ldcon.window_api': 'ldcon.web.window_api',
243
+ 'ldcon.teams_destinations_api': 'ldcon.web.teams_destinations_api',
244
+ 'ldcon.lock_target_api': 'ldcon.web.lock_target_api',
245
+ 'ldcon.lock_target_queue': 'ldcon.web.lock_target_queue',
246
+ 'ldcon.sweep_api': 'ldcon.web.sweep_api',
247
+ 'ldcon.sweep_guard': 'ldcon.web.sweep_guard',
248
+ 'ldcon.shot_analysis_api': 'ldcon.web.shot_analysis_api',
249
+ 'ldcon.laser_operations': 'ldcon.web.laser_operations',
250
+ 'ldcon.online_position': 'ldcon.web.online_position',
251
+ 'ldcon.web_fleet': 'ldcon.web.web_fleet',
252
+ 'ldcon.web_server': 'ldcon.web.web_server',
253
+ # G16 (job supervisor hub; still re-exports ConflictError/TERMINAL for core until the split in module-map.md 2b)
254
+ 'ldcon.web_runtime': 'ldcon.web.web_runtime',
255
+ # G17 (core hubs: contracts, records, schema, cards, clients, layout, configuration; no entry)
256
+ 'ldcon.contracts': 'ldcon.core.contracts',
257
+ 'ldcon.records': 'ldcon.core.records',
258
+ 'ldcon.execution_context': 'ldcon.core.execution_context',
259
+ 'ldcon.state_layout': 'ldcon.core.state_layout',
260
+ 'ldcon.deck_yaml': 'ldcon.core.deck_yaml',
261
+ 'ldcon.device_conditions': 'ldcon.core.device_conditions',
262
+ 'ldcon.interface_schema': 'ldcon.core.interface_schema',
263
+ 'ldcon.interface_cards': 'ldcon.core.interface_cards',
264
+ 'ldcon.card_definition': 'ldcon.core.card_definition',
265
+ 'ldcon.instrument_client': 'ldcon.core.instrument_client',
266
+ 'ldcon.current_settings': 'ldcon.core.current_settings',
267
+ 'ldcon.temperature_settings': 'ldcon.core.temperature_settings',
268
+ 'ldcon.site_bindings': 'ldcon.core.site_bindings',
269
+ 'ldcon.result_reservations': 'ldcon.core.result_reservations',
270
+ 'ldcon.configuration': 'ldcon.core.configuration',
271
+ 'ldcon.configuration_transaction': 'ldcon.core.configuration_transaction',
272
+ 'ldcon.metric_quantities': 'ldcon.core.metric_quantities',
273
+ 'ldcon.card_reporting': 'ldcon.core.card_reporting',
274
+ 'ldcon.telegraf': 'ldcon.core.telegraf',
275
+ 'ldcon.telemetry': 'ldcon.core.telemetry',
276
+ 'ldcon.period_context': 'ldcon.core.period_context',
277
+ 'ldcon.adjustment_registry': 'ldcon.core.adjustment_registry',
278
+ 'ldcon.laser_assets': 'ldcon.core.laser_assets',
279
+ 'ldcon.modulation': 'ldcon.core.modulation',
280
+ 'ldcon.agent_authority': 'ldcon.core.agent_authority',
281
+ 'ldcon.operation_registry': 'ldcon.core.operation_registry',
282
+ 'ldcon.card_admission': 'ldcon.core.card_admission',
283
+ # added after the module map (63db3e1), assigned by responsibility (see doc/card-system-current-state.md, phase 2 G10-G13)
284
+ 'ldcon.branch_maps': 'ldcon.jobs.branch_maps',
285
+ 'ldcon.branch_target_migration': 'ldcon.jobs.branch_target_migration',
286
+ 'ldcon.ecdl_branch_recovery': 'ldcon.jobs.ecdl_branch_recovery',
287
+ 'ldcon.locked_triangle': 'ldcon.jobs.locked_triangle',
288
+ 'ldcon.operating_point_proxy': 'ldcon.jobs.operating_point_proxy',
289
+ 'ldcon.target_response_thermal': 'ldcon.jobs.target_response_thermal',
290
+ 'ldcon.target_response_thermal_experiment': 'ldcon.jobs.target_response_thermal_experiment',
291
+ 'ldcon.target_policy': 'ldcon.core.target_policy',
292
+ 'ldcon.control_readback': 'ldcon.web.control_readback',
293
+ }
294
+ _install(MOVED)
295
+
296
+
297
+ def __getattr__(name):
298
+ if 'ldcon.' + name in MOVED: return _importlib.import_module('ldcon.' + name) # the finder binds the attribute
299
+ raise AttributeError(f'module ldcon has no attribute {name!r}')
300
+
301
+
302
+ def __dir__(): return sorted(set(globals()) | {name.split('.')[1] for name in MOVED})
ldcon/_moved.py ADDED
@@ -0,0 +1,49 @@
1
+ """Old import paths of modules moved into subpackages (refactor phase 2, 2026-10-27).
2
+
3
+ `ldcon.MOVED` maps each old name to the new dotted path. A meta-path finder installed by
4
+ `ldcon/__init__.py` resolves `import ldcon.<old>`, `from ldcon.<old> import x`, `from ldcon import <old>`,
5
+ `importlib.import_module('ldcon.<old>')` and `python -m ldcon.<old>` to the *same module object* as the new
6
+ path (an alias in `sys.modules`, not a copy), so a `monkeypatch.setattr` through the old alias reaches the
7
+ globals the real functions read. Entry modules additionally keep a tiny `ldcon/<old>.py` stub for
8
+ `python -m ldcon.<old>` (the units name them). The aliases exist for releases, units, deploy scripts and
9
+ external callers that still use the old names; code inside the package imports the new paths directly.
10
+ """
11
+ import importlib, importlib.abc, importlib.machinery, importlib.util, sys
12
+
13
+
14
+ def alias(old, new=None):
15
+ """Bind sys.modules[old] and the parent attribute to the module at `new` (default: ldcon.MOVED[old])."""
16
+ new = new or sys.modules['ldcon'].MOVED[old]
17
+ module = importlib.import_module(new)
18
+ sys.modules[old] = module
19
+ parent, _, attribute = old.rpartition('.')
20
+ setattr(sys.modules[parent], attribute, module)
21
+ return module
22
+
23
+
24
+ class _Loader(importlib.abc.Loader):
25
+ def __init__(self, new): self.new = new
26
+ def create_module(self, spec):
27
+ module = importlib.import_module(self.new)
28
+ self.spec = module.__spec__
29
+ return module
30
+ def exec_module(self, module):
31
+ module.__spec__ = self.spec # module_from_spec replaced it with the alias spec; the module keeps its own identity
32
+ def get_code(self, name): # runpy (`python -m ldcon.<old>`) without a stub file
33
+ return importlib.import_module(self.new).__spec__.loader.get_code(self.new)
34
+
35
+
36
+ class _Finder(importlib.abc.MetaPathFinder):
37
+ def __init__(self, table): self.table = table
38
+ def find_spec(self, name, path=None, target=None):
39
+ new = self.table.get(name)
40
+ if new is None: return None
41
+ found = importlib.util.find_spec(new)
42
+ if found is None: raise ImportError(f'{name} was moved to {new}, which does not exist')
43
+ return importlib.machinery.ModuleSpec(name, _Loader(new), origin=found.origin)
44
+
45
+
46
+ def install(table):
47
+ """Append the finder once (after the path finder, so real files such as the entry stubs win)."""
48
+ if not any(isinstance(finder, _Finder) for finder in sys.meta_path):
49
+ sys.meta_path.append(_Finder(table))
ldcon/agent_tools.py ADDED
@@ -0,0 +1,4 @@
1
+ """`python -m ldcon.agent_tools <context>` stays valid for ENTRY_MODULES and external callers; the module is ldcon.agents.agent_tools."""
2
+ from ldcon._moved import alias
3
+ _module = alias('ldcon.agent_tools')
4
+ if __name__ == '__main__': _module.main()
@@ -0,0 +1 @@
1
+ """Resident agents, notifications and reports. Importing never contacts a model, an owner or Teams."""
@@ -0,0 +1,73 @@
1
+ """Laser-specific proposal advice, separate from owner safety and trial grants."""
2
+ from ldcon.core.state_layout import asset_parts, root_from_laser_file
3
+
4
+ from experiment_core.adjustment_guidance import validate as validate_document, snapshot
5
+
6
+ # Units describe proposals, not a promise that an owner supports every knob.
7
+ UNITS = dict(current='V', temperature='V', piezo_center_dac='count',
8
+ kp_count_per_nm='count/nm', ki_count_per_nm_s='count/(nm*s)',
9
+ integral_limit_count='count', p_sample='1', g_sample='1',
10
+ tec_gain='1', tec_dt_cap_s='s', supervision_interval_s='s',
11
+ current_per_temperature='V/V', target_ff_scale='1', target_step_hz='Hz')
12
+
13
+
14
+ def validate(value):
15
+ value = validate_document(value)
16
+ for knob, item in value['knobs'].items():
17
+ if knob not in UNITS:
18
+ raise ValueError('Unknown laser adjustment guidance knob: '+knob)
19
+ if item['kind'] == 'absolute' and item['unit'] != UNITS[knob]:
20
+ raise ValueError('Incorrect physical unit for guidance knob: '+knob)
21
+ return value
22
+
23
+
24
+ def location(root, laser_id):
25
+ from pathlib import Path
26
+ from experiment_core.records import safe_id
27
+ path=Path(root).joinpath(*asset_parts(root, safe_id(laser_id)))/'data'/'adjustment-guidance.json'
28
+ if any(p.is_symlink() for p in (path,*path.parents)):
29
+ raise ValueError('Adjustment guidance must not use symlinks')
30
+ return path
31
+
32
+
33
+ def read(root, laser_id):
34
+ import json
35
+ path=location(root,laser_id)
36
+ raw=path.read_bytes() if path.exists() else b'{"schema_version":1,"knobs":{}}'
37
+ if len(raw)>65536:raise ValueError('Adjustment guidance is too large')
38
+ value=validate(json.loads(raw))
39
+ return dict(snapshot(value),laser_id=laser_id,
40
+ availability='configured' if value['knobs'] else 'not_configured')
41
+
42
+
43
+ def current(runtime, laser_id):
44
+ # Establish scope, then read advice independently of the physical policy.
45
+ runtime.interface_repository.read('lasers',laser_id)
46
+ return read(runtime.root,laser_id)
47
+
48
+
49
+ def for_job(directory, laser_id):
50
+ from ldcon.jobs.laser_live import laser_file
51
+ return read(root_from_laser_file(laser_file(directory,laser_id)),laser_id)
52
+
53
+
54
+ def update(runtime, laser_id, data):
55
+ import fcntl
56
+ import os
57
+ from experiment_core.records import atomic_json
58
+ from ldcon.web.web_runtime import ConflictError
59
+ if not isinstance(data,dict) or set(data)!={'expected_revision','document'}:
60
+ raise ValueError('Expected revision and an advisory document')
61
+ document=validate(data['document'])
62
+ if len(__import__('json').dumps(document).encode())>65536:
63
+ raise ValueError('Adjustment guidance is too large')
64
+ with runtime.mutex:
65
+ runtime.interface_repository.read('lasers',laser_id)
66
+ path=location(runtime.root,laser_id);path.parent.mkdir(parents=True,exist_ok=True)
67
+ descriptor=os.open(path.with_suffix('.lock'),os.O_CREAT|os.O_RDWR|os.O_NOFOLLOW,0o600)
68
+ with os.fdopen(descriptor,'a') as stream:
69
+ fcntl.flock(stream,fcntl.LOCK_EX)
70
+ if current(runtime,laser_id)['revision']!=data['expected_revision']:
71
+ raise ConflictError('Adjustment advice changed; read it before saving')
72
+ atomic_json(path,document)
73
+ return current(runtime,laser_id)