devagent-physical-engine 0.12.4__tar.gz → 0.13.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 (172) hide show
  1. {devagent_physical_engine-0.12.4/src/devagent_physical_engine.egg-info → devagent_physical_engine-0.13.0}/PKG-INFO +22 -3
  2. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/README.md +22 -3
  3. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/pyproject.toml +1 -1
  4. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/__init__.py +17 -1
  5. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/cli.py +117 -0
  6. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/physical_motion.py +14 -1
  7. devagent_physical_engine-0.13.0/src/devagent_physical_engine/pose_math.py +134 -0
  8. devagent_physical_engine-0.13.0/src/devagent_physical_engine/project.py +601 -0
  9. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/reference_workcell.py +151 -39
  10. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/joint_state_probe.py +139 -0
  11. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/joint_state_recorder.py +35 -9
  12. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/moveit_joint_plan_probe.py +580 -0
  13. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/moveit_task_planner.py +279 -0
  14. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/task_adapter.py +160 -0
  15. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/task_visualization.py +602 -0
  16. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/trajectory.py +376 -0
  17. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/trajectory_action_probe.py +352 -0
  18. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/trajectory_tracking.py +201 -0
  19. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/workpiece_follow.py +79 -5
  20. devagent_physical_engine-0.13.0/src/devagent_physical_engine/ros2/workpiece_gazebo_follower.py +275 -0
  21. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/setup_profile.py +5 -0
  22. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0/src/devagent_physical_engine.egg-info}/PKG-INFO +22 -3
  23. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine.egg-info/SOURCES.txt +12 -0
  24. devagent_physical_engine-0.13.0/tests/test_joint_state_probe_v0125.py +54 -0
  25. devagent_physical_engine-0.13.0/tests/test_moveit_planning_diagnostics_v0125.py +104 -0
  26. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_physical_motion_v09.py +5 -3
  27. devagent_physical_engine-0.13.0/tests/test_pose_math_v0125.py +42 -0
  28. devagent_physical_engine-0.13.0/tests/test_project_spine_v013.py +300 -0
  29. devagent_physical_engine-0.13.0/tests/test_reference_workcell_ros_frames_v0125.py +41 -0
  30. devagent_physical_engine-0.13.0/tests/test_ros_trajectory_v09.py +300 -0
  31. devagent_physical_engine-0.13.0/tests/test_trajectory_action_probe_v0125.py +107 -0
  32. devagent_physical_engine-0.13.0/tests/test_trajectory_tracking_v0125.py +142 -0
  33. devagent_physical_engine-0.12.4/src/devagent_physical_engine/ros2/moveit_joint_plan_probe.py +0 -159
  34. devagent_physical_engine-0.12.4/src/devagent_physical_engine/ros2/moveit_task_planner.py +0 -139
  35. devagent_physical_engine-0.12.4/src/devagent_physical_engine/ros2/task_adapter.py +0 -52
  36. devagent_physical_engine-0.12.4/src/devagent_physical_engine/ros2/task_visualization.py +0 -325
  37. devagent_physical_engine-0.12.4/src/devagent_physical_engine/ros2/trajectory.py +0 -213
  38. devagent_physical_engine-0.12.4/src/devagent_physical_engine/ros2/workpiece_gazebo_follower.py +0 -218
  39. devagent_physical_engine-0.12.4/tests/test_ros_trajectory_v09.py +0 -116
  40. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/NOTICE +0 -0
  41. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/setup.cfg +0 -0
  42. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/__init__.py +0 -0
  43. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/compiler.py +0 -0
  44. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/contracts.py +0 -0
  45. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/coordinator.py +0 -0
  46. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/critic.py +0 -0
  47. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/evidence.py +0 -0
  48. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/interpreter.py +0 -0
  49. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/planner.py +0 -0
  50. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/recovery.py +0 -0
  51. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/routing.py +0 -0
  52. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/runtime.py +0 -0
  53. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/semantic.py +0 -0
  54. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/agent/structured.py +0 -0
  55. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ai_cli.py +0 -0
  56. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/continuous_clearance.py +0 -0
  57. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/doctor.py +0 -0
  58. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/engineering_agent.py +0 -0
  59. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/engineering_request.py +0 -0
  60. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/execution.py +0 -0
  61. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/models.py +0 -0
  62. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/operating_envelope.py +0 -0
  63. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/__init__.py +0 -0
  64. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/benchmark.py +0 -0
  65. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/candidates.py +0 -0
  66. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/contracts.py +0 -0
  67. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/evaluator.py +0 -0
  68. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/evidence.py +0 -0
  69. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/experience.py +0 -0
  70. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/measured.py +0 -0
  71. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/optimizer.py +0 -0
  72. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/optimization/orchestrator.py +0 -0
  73. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/physical_campaign.py +0 -0
  74. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/physical_evidence.py +0 -0
  75. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/planning.py +0 -0
  76. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/preexecution_contract.py +0 -0
  77. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/provider_adapters/__init__.py +0 -0
  78. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/provider_adapters/anthropic.py +0 -0
  79. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/provider_adapters/common.py +0 -0
  80. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/provider_adapters/factory.py +0 -0
  81. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/provider_adapters/gemini.py +0 -0
  82. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/provider_adapters/openai.py +0 -0
  83. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/provider_qualification.py +0 -0
  84. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/providers.py +0 -0
  85. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/qualification.py +0 -0
  86. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/qualification_cli.py +0 -0
  87. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/qualification_harness.py +0 -0
  88. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/robot_platform.py +0 -0
  89. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/robots.py +0 -0
  90. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/__init__.py +0 -0
  91. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/acceptance.py +0 -0
  92. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/commands.py +0 -0
  93. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/continuous_clearance_probe.py +0 -0
  94. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/doctor.py +0 -0
  95. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/fk_pose.py +0 -0
  96. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/fk_probe.py +0 -0
  97. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/frame_alignment.py +0 -0
  98. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/gazebo_cli.py +0 -0
  99. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/gazebo_pose.py +0 -0
  100. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/gazebo_world.py +0 -0
  101. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/measured_motion.py +0 -0
  102. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/moveit_scene.py +0 -0
  103. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/preexecution.py +0 -0
  104. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/qualification.py +0 -0
  105. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/qualification_v10.py +0 -0
  106. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/qualification_v11.py +0 -0
  107. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/qualification_v12.py +0 -0
  108. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/scene_probe.py +0 -0
  109. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/state_validity_probe.py +0 -0
  110. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/tf_probe.py +0 -0
  111. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/tool_scene.py +0 -0
  112. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/tool_scene_probe.py +0 -0
  113. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/ur5e.py +0 -0
  114. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/ur5e_adapter.py +0 -0
  115. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/ur5e_v10_adapter.py +0 -0
  116. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/workpiece_scene.py +0 -0
  117. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/ros2/workpiece_scene_probe.py +0 -0
  118. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/sim_real_qualification.py +0 -0
  119. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/simulation.py +0 -0
  120. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/simulation_platform.py +0 -0
  121. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/tool_collision.py +0 -0
  122. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/trajectory_qualification.py +0 -0
  123. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/twin.py +0 -0
  124. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/twin_builder.py +0 -0
  125. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/twin_materialization.py +0 -0
  126. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/verification.py +0 -0
  127. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine/workpiece_lifecycle.py +0 -0
  128. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine.egg-info/dependency_links.txt +0 -0
  129. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine.egg-info/entry_points.txt +0 -0
  130. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine.egg-info/requires.txt +0 -0
  131. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/src/devagent_physical_engine.egg-info/top_level.txt +0 -0
  132. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_agent_core.py +0 -0
  133. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_agent_semantic_hardening.py +0 -0
  134. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_ai_cli.py +0 -0
  135. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_ai_cli_v07.py +0 -0
  136. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_continuous_clearance_v011.py +0 -0
  137. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_core.py +0 -0
  138. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_engineering_request_v07.py +0 -0
  139. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_gazebo_cli_v0122.py +0 -0
  140. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_interpreter_profiles_v08.py +0 -0
  141. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_live_provider_qualification.py +0 -0
  142. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_measured_motion_v10.py +0 -0
  143. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_moveit_scene_v0123.py +0 -0
  144. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_natural_language_agent_v07.py +0 -0
  145. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_openai_strict_schema_v0113.py +0 -0
  146. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_optimization_v05.py +0 -0
  147. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_physical_campaign_v09.py +0 -0
  148. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_physical_evidence_v09.py +0 -0
  149. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_planning_fallback_v012.py +0 -0
  150. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_preexecution_contract_v10.py +0 -0
  151. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_provider_and_qualification.py +0 -0
  152. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_qualification_cli_lifecycle_v06.py +0 -0
  153. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_qualification_harness_v06.py +0 -0
  154. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_readme_pypi.py +0 -0
  155. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_real_provider_adapters.py +0 -0
  156. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_reference_workcell_v012.py +0 -0
  157. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_robot_platform_v08.py +0 -0
  158. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_ros2_production_receipts_v011.py +0 -0
  159. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_ros2_simulation.py +0 -0
  160. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_setup_profile.py +0 -0
  161. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_sim_real_qualification_v011.py +0 -0
  162. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_simulation_platform_v08.py +0 -0
  163. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_tool_collision_v011.py +0 -0
  164. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_tool_scene_v0124.py +0 -0
  165. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_trajectory_qualification_v09.py +0 -0
  166. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_twin_materialization_v10.py +0 -0
  167. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_twin_v08.py +0 -0
  168. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_ur5e_adapter_scopes_v09.py +0 -0
  169. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_ur5e_v10_adapter_scopes.py +0 -0
  170. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_v052_stabilization.py +0 -0
  171. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_v08_catalog_mapping_regression.py +0 -0
  172. {devagent_physical_engine-0.12.4 → devagent_physical_engine-0.13.0}/tests/test_workpiece_lifecycle_v011.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devagent-physical-engine
3
- Version: 0.12.4
3
+ Version: 0.13.0
4
4
  Summary: Verification-first agentic engineering, simulation, and evidence runtime for robotics and industrial automation.
5
5
  Author: Tom Ha
6
6
  License: All Rights Reserved
@@ -143,6 +143,24 @@ While the command runs, stage-by-stage progress is printed to `stderr` and the f
143
143
 
144
144
  Use `--quiet` when a script or CI job needs JSON without terminal progress.
145
145
 
146
+ ## Commercial project spine
147
+
148
+ v0.13 adds durable customer project, site, and workcell identity around the existing verification engine. Project manifests are fingerprinted, Twin builds can be persisted as immutable revisions, and project evidence is stored locally in SQLite with content hashes.
149
+
150
+ Create and inspect a project:
151
+
152
+ ```bash
153
+ devagent-physical project init warehouse-cnc-04 \
154
+ --name "Warehouse CNC Loading Cell 04" \
155
+ --site atl-01 \
156
+ --workcell cnc-04
157
+
158
+ devagent-physical project show warehouse-cnc-04
159
+ devagent-physical project revisions warehouse-cnc-04
160
+ ```
161
+
162
+ The default store is `~/.devagent/projects.db`. This project spine is the durable boundary for upcoming customer Twin import, requirement traceability, physical test campaigns, regression analysis, and FAT reporting. It does not by itself claim customer geometry import, physical qualification, site qualification, or real execution.
163
+
146
164
  ## Task-specific visual simulation
147
165
 
148
166
  For the supported v0.12 UR5e `load` scope, `--visualize` continues from the verified high-level task into a physical simulation path:
@@ -408,6 +426,7 @@ A green `main` release is tied to the exact CI-tested commit. Release artifacts
408
426
 
409
427
  Detailed engineering documentation lives in the repository:
410
428
 
429
+ - [Commercial project spine](https://github.com/tomha85/devagent-physical-engine/blob/main/docs/COMMERCIAL_PROJECT_SPINE.md)
411
430
  - [Production readiness](https://github.com/tomha85/devagent-physical-engine/blob/main/docs/PRODUCTION_READINESS.md)
412
431
  - [Architecture](https://github.com/tomha85/devagent-physical-engine/blob/main/docs/ARCHITECTURE.md)
413
432
  - [Agent Core](https://github.com/tomha85/devagent-physical-engine/blob/main/docs/AGENT_CORE.md)
@@ -424,9 +443,9 @@ Detailed engineering documentation lives in the repository:
424
443
 
425
444
  ## Project status
426
445
 
427
- **v0.12.4 — Beta software / evidence-gated task-specific physical simulation.**
446
+ **v0.13.0 — Beta software / commercial project spine + evidence-gated task-specific physical simulation.**
428
447
 
429
- The software and release pipeline are production-oriented, but physical readiness is scope-specific and evidence-driven. The UR5e task-specific reference-workcell path must pass the executable v0.12 ROS/Gazebo/MoveIt campaign on the target workstation before that scope is considered simulation-qualified there. Real robot execution remains locked. Functional-safety certification and site qualification are not claimed.
448
+ The software and release pipeline are production-oriented, but physical readiness is scope-specific and evidence-driven. v0.13 adds durable project/site/workcell identity, immutable Twin revisions, and content-addressed local evidence; it does not claim arbitrary customer Twin import or customer-site qualification. The UR5e task-specific reference-workcell path must pass the executable v0.12 ROS/Gazebo/MoveIt campaign on the target workstation before that scope is considered simulation-qualified there. Real robot execution remains locked. Functional-safety certification and site qualification are not claimed.
430
449
 
431
450
  ## Ownership
432
451
 
@@ -102,6 +102,24 @@ While the command runs, stage-by-stage progress is printed to `stderr` and the f
102
102
 
103
103
  Use `--quiet` when a script or CI job needs JSON without terminal progress.
104
104
 
105
+ ## Commercial project spine
106
+
107
+ v0.13 adds durable customer project, site, and workcell identity around the existing verification engine. Project manifests are fingerprinted, Twin builds can be persisted as immutable revisions, and project evidence is stored locally in SQLite with content hashes.
108
+
109
+ Create and inspect a project:
110
+
111
+ ```bash
112
+ devagent-physical project init warehouse-cnc-04 \
113
+ --name "Warehouse CNC Loading Cell 04" \
114
+ --site atl-01 \
115
+ --workcell cnc-04
116
+
117
+ devagent-physical project show warehouse-cnc-04
118
+ devagent-physical project revisions warehouse-cnc-04
119
+ ```
120
+
121
+ The default store is `~/.devagent/projects.db`. This project spine is the durable boundary for upcoming customer Twin import, requirement traceability, physical test campaigns, regression analysis, and FAT reporting. It does not by itself claim customer geometry import, physical qualification, site qualification, or real execution.
122
+
105
123
  ## Task-specific visual simulation
106
124
 
107
125
  For the supported v0.12 UR5e `load` scope, `--visualize` continues from the verified high-level task into a physical simulation path:
@@ -367,6 +385,7 @@ A green `main` release is tied to the exact CI-tested commit. Release artifacts
367
385
 
368
386
  Detailed engineering documentation lives in the repository:
369
387
 
388
+ - [Commercial project spine](https://github.com/tomha85/devagent-physical-engine/blob/main/docs/COMMERCIAL_PROJECT_SPINE.md)
370
389
  - [Production readiness](https://github.com/tomha85/devagent-physical-engine/blob/main/docs/PRODUCTION_READINESS.md)
371
390
  - [Architecture](https://github.com/tomha85/devagent-physical-engine/blob/main/docs/ARCHITECTURE.md)
372
391
  - [Agent Core](https://github.com/tomha85/devagent-physical-engine/blob/main/docs/AGENT_CORE.md)
@@ -383,9 +402,9 @@ Detailed engineering documentation lives in the repository:
383
402
 
384
403
  ## Project status
385
404
 
386
- **v0.12.4 — Beta software / evidence-gated task-specific physical simulation.**
405
+ **v0.13.0 — Beta software / commercial project spine + evidence-gated task-specific physical simulation.**
387
406
 
388
- The software and release pipeline are production-oriented, but physical readiness is scope-specific and evidence-driven. The UR5e task-specific reference-workcell path must pass the executable v0.12 ROS/Gazebo/MoveIt campaign on the target workstation before that scope is considered simulation-qualified there. Real robot execution remains locked. Functional-safety certification and site qualification are not claimed.
407
+ The software and release pipeline are production-oriented, but physical readiness is scope-specific and evidence-driven. v0.13 adds durable project/site/workcell identity, immutable Twin revisions, and content-addressed local evidence; it does not claim arbitrary customer Twin import or customer-site qualification. The UR5e task-specific reference-workcell path must pass the executable v0.12 ROS/Gazebo/MoveIt campaign on the target workstation before that scope is considered simulation-qualified there. Real robot execution remains locked. Functional-safety certification and site qualification are not claimed.
389
408
 
390
409
  ## Ownership
391
410
 
@@ -393,4 +412,4 @@ DevAgent Smart Physical Engine
393
412
  Copyright © 2026 Tom Ha
394
413
  Original creator: Tom Ha
395
414
  Original project: https://github.com/tomha85/devagent-physical-engine
396
- All rights reserved.
415
+ All rights reserved.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devagent-physical-engine"
7
- version = "0.12.4"
7
+ version = "0.13.0"
8
8
  description = "Verification-first agentic engineering, simulation, and evidence runtime for robotics and industrial automation."
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.11"
@@ -10,6 +10,15 @@ from .models import (
10
10
  WorldState,
11
11
  )
12
12
  from .physical_motion import JointTrajectoryPoint, MotionExecutionMetrics, PhysicalMotionPlan
13
+ from .project import (
14
+ EvidenceArtifactRecord,
15
+ ProjectError,
16
+ ProjectManifest,
17
+ ProjectService,
18
+ ProjectTwinBuildOutcome,
19
+ SQLiteProjectRepository,
20
+ TwinRevisionRecord,
21
+ )
13
22
  from .robot_platform import (
14
23
  BUILTIN_ROBOT_PROFILES,
15
24
  QualificationState,
@@ -30,6 +39,13 @@ __all__ = [
30
39
  "JointTrajectoryPoint",
31
40
  "MotionExecutionMetrics",
32
41
  "PhysicalMotionPlan",
42
+ "ProjectError",
43
+ "ProjectManifest",
44
+ "ProjectService",
45
+ "ProjectTwinBuildOutcome",
46
+ "SQLiteProjectRepository",
47
+ "TwinRevisionRecord",
48
+ "EvidenceArtifactRecord",
33
49
  "BUILTIN_ROBOT_PROFILES",
34
50
  "QualificationState",
35
51
  "RobotProfile",
@@ -41,4 +57,4 @@ __all__ = [
41
57
  "TwinValidator",
42
58
  ]
43
59
 
44
- __version__ = "0.12.4"
60
+ __version__ = "0.13.0"
@@ -24,6 +24,34 @@ def _parser() -> argparse.ArgumentParser:
24
24
  sub.add_parser("qualify", help="Run deterministic cross-vendor smoke qualification")
25
25
  add_qualification_parsers(sub)
26
26
 
27
+ project = sub.add_parser(
28
+ "project",
29
+ help="Manage durable customer project/site/workcell context and Twin revisions",
30
+ )
31
+ project.add_argument(
32
+ "--db",
33
+ default="~/.devagent/projects.db",
34
+ help="SQLite project/evidence database path",
35
+ )
36
+ project_sub = project.add_subparsers(dest="project_command", required=True)
37
+
38
+ project_init = project_sub.add_parser("init", help="Create a new customer project")
39
+ project_init.add_argument("project_id")
40
+ project_init.add_argument("--name", required=True)
41
+ project_init.add_argument("--site", required=True)
42
+ project_init.add_argument("--workcell", required=True)
43
+
44
+ project_sub.add_parser("list", help="List known customer projects")
45
+
46
+ project_show = project_sub.add_parser("show", help="Show one project and latest Twin revision")
47
+ project_show.add_argument("project_id")
48
+
49
+ project_revisions = project_sub.add_parser(
50
+ "revisions",
51
+ help="List immutable Twin revisions for a project",
52
+ )
53
+ project_revisions.add_argument("project_id")
54
+
27
55
  setup = sub.add_parser(
28
56
  "setup",
29
57
  help="Configure an explicit system profile; pip installation never changes OS packages",
@@ -92,6 +120,92 @@ def _parser() -> argparse.ArgumentParser:
92
120
  return parser
93
121
 
94
122
 
123
+ def _project_command(args: argparse.Namespace) -> int:
124
+ from .project import ProjectError, ProjectManifest, SQLiteProjectRepository
125
+
126
+ repository = SQLiteProjectRepository(args.db)
127
+ try:
128
+ if args.project_command == "init":
129
+ manifest = repository.create_project(
130
+ ProjectManifest(
131
+ project_id=args.project_id,
132
+ name=args.name,
133
+ site_id=args.site,
134
+ workcell_id=args.workcell,
135
+ )
136
+ )
137
+ print(
138
+ json.dumps(
139
+ {
140
+ **manifest.to_dict(),
141
+ "manifest_hash": manifest.fingerprint,
142
+ "database": str(repository.path),
143
+ },
144
+ indent=2,
145
+ )
146
+ )
147
+ return 0
148
+
149
+ if args.project_command == "list":
150
+ projects = repository.list_projects()
151
+ print(
152
+ json.dumps(
153
+ {
154
+ "database": str(repository.path),
155
+ "projects": [
156
+ {**item.to_dict(), "manifest_hash": item.fingerprint}
157
+ for item in projects
158
+ ],
159
+ },
160
+ indent=2,
161
+ )
162
+ )
163
+ return 0
164
+
165
+ if args.project_command == "show":
166
+ project = repository.get_project(args.project_id)
167
+ latest = repository.latest_twin_revision(project.project_id)
168
+ print(
169
+ json.dumps(
170
+ {
171
+ "project": {**project.to_dict(), "manifest_hash": project.fingerprint},
172
+ "latest_twin_revision": None if latest is None else latest.to_dict(),
173
+ "database": str(repository.path),
174
+ },
175
+ indent=2,
176
+ )
177
+ )
178
+ return 0
179
+
180
+ if args.project_command == "revisions":
181
+ project = repository.get_project(args.project_id)
182
+ revisions = repository.list_twin_revisions(project.project_id)
183
+ print(
184
+ json.dumps(
185
+ {
186
+ "project_id": project.project_id,
187
+ "revisions": [item.to_dict() for item in revisions],
188
+ "database": str(repository.path),
189
+ },
190
+ indent=2,
191
+ )
192
+ )
193
+ return 0
194
+ except ProjectError as exc:
195
+ print(
196
+ json.dumps(
197
+ {
198
+ "passed": False,
199
+ "failure_code": str(exc),
200
+ "database": str(repository.path),
201
+ },
202
+ indent=2,
203
+ )
204
+ )
205
+ return 10
206
+ return 2
207
+
208
+
95
209
  def _setup_profile(args: argparse.Namespace) -> int:
96
210
  from .ros2 import RosDoctor, SubprocessRosRunner
97
211
  from .setup_profile import (
@@ -367,6 +481,9 @@ def main(argv: list[str] | None = None) -> int:
367
481
  if qualification_code is not None:
368
482
  return qualification_code
369
483
 
484
+ if args.command == "project":
485
+ return _project_command(args)
486
+
370
487
  if args.command == "setup":
371
488
  return _setup_profile(args)
372
489
 
@@ -160,6 +160,12 @@ class MotionExecutionMetrics:
160
160
  min_clearance_m: float | None = None
161
161
  final_tcp_error_m: float | None = None
162
162
  energy_proxy: float | None = None
163
+ joint_state_sample_rate_hz: float | None = None
164
+ max_sample_gap_s: float | None = None
165
+ trajectory_duration_error_s: float | None = None
166
+ tracking_sample_count: int | None = None
167
+ tracking_scope: str = "endpoint_only"
168
+ tracking_interpolation: str = "unspecified"
163
169
  planner_retries: int | None = None
164
170
  trajectory_retries: int | None = None
165
171
  failure_codes: tuple[str, ...] = ()
@@ -168,6 +174,10 @@ class MotionExecutionMetrics:
168
174
  def __post_init__(self) -> None:
169
175
  if not self.metrics_origin.strip():
170
176
  raise PhysicalMotionError("metrics_origin_required")
177
+ if not self.tracking_scope.strip():
178
+ raise PhysicalMotionError("tracking_scope_required")
179
+ if not self.tracking_interpolation.strip():
180
+ raise PhysicalMotionError("tracking_interpolation_required")
171
181
  for name in (
172
182
  "observed_duration_s",
173
183
  "planned_duration_s",
@@ -178,6 +188,9 @@ class MotionExecutionMetrics:
178
188
  "min_clearance_m",
179
189
  "final_tcp_error_m",
180
190
  "energy_proxy",
191
+ "joint_state_sample_rate_hz",
192
+ "max_sample_gap_s",
193
+ "trajectory_duration_error_s",
181
194
  ):
182
195
  value = getattr(self, name)
183
196
  if value is None:
@@ -185,7 +198,7 @@ class MotionExecutionMetrics:
185
198
  numeric = float(value)
186
199
  if not isfinite(numeric) or numeric < 0:
187
200
  raise PhysicalMotionError(f"metric_invalid:{name}")
188
- for name in ("planner_retries", "trajectory_retries"):
201
+ for name in ("tracking_sample_count", "planner_retries", "trajectory_retries"):
189
202
  value = getattr(self, name)
190
203
  if value is not None and value < 0:
191
204
  raise PhysicalMotionError(f"metric_invalid:{name}")
@@ -0,0 +1,134 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from math import acos, isfinite, sqrt
5
+
6
+
7
+ class PoseMathError(ValueError):
8
+ pass
9
+
10
+
11
+ def _finite(values: tuple[float, ...], *, code: str) -> tuple[float, ...]:
12
+ converted = tuple(float(value) for value in values)
13
+ if any(not isfinite(value) for value in converted):
14
+ raise PoseMathError(code)
15
+ return converted
16
+
17
+
18
+ def normalize_quaternion(
19
+ quaternion_xyzw: tuple[float, float, float, float],
20
+ ) -> tuple[float, float, float, float]:
21
+ values = _finite(tuple(quaternion_xyzw), code="quaternion_non_finite")
22
+ if len(values) != 4:
23
+ raise PoseMathError("quaternion_size_invalid")
24
+ norm = sqrt(sum(value * value for value in values))
25
+ if norm <= 1e-12:
26
+ raise PoseMathError("quaternion_zero")
27
+ normalized = tuple(value / norm for value in values)
28
+ # q and -q encode the same rotation. Keep one deterministic representation.
29
+ for component in (normalized[3], normalized[0], normalized[1], normalized[2]):
30
+ if abs(component) <= 1e-15:
31
+ continue
32
+ return tuple(-value for value in normalized) if component < 0.0 else normalized
33
+ raise PoseMathError("quaternion_zero")
34
+
35
+
36
+ def quaternion_multiply(
37
+ first: tuple[float, float, float, float],
38
+ second: tuple[float, float, float, float],
39
+ ) -> tuple[float, float, float, float]:
40
+ ax, ay, az, aw = normalize_quaternion(first)
41
+ bx, by, bz, bw = normalize_quaternion(second)
42
+ return normalize_quaternion(
43
+ (
44
+ aw * bx + ax * bw + ay * bz - az * by,
45
+ aw * by - ax * bz + ay * bw + az * bx,
46
+ aw * bz + ax * by - ay * bx + az * bw,
47
+ aw * bw - ax * bx - ay * by - az * bz,
48
+ )
49
+ )
50
+
51
+
52
+ def quaternion_conjugate(
53
+ quaternion_xyzw: tuple[float, float, float, float],
54
+ ) -> tuple[float, float, float, float]:
55
+ x, y, z, w = normalize_quaternion(quaternion_xyzw)
56
+ return (-x, -y, -z, w)
57
+
58
+
59
+ def rotate_vector(
60
+ quaternion_xyzw: tuple[float, float, float, float],
61
+ vector_xyz: tuple[float, float, float],
62
+ ) -> tuple[float, float, float]:
63
+ qx, qy, qz, qw = normalize_quaternion(quaternion_xyzw)
64
+ vx, vy, vz = _finite(tuple(vector_xyz), code="vector_non_finite")
65
+ if len((vx, vy, vz)) != 3:
66
+ raise PoseMathError("vector_size_invalid")
67
+ # Unit-quaternion vector rotation without constructing temporary quaternions.
68
+ tx = 2.0 * (qy * vz - qz * vy)
69
+ ty = 2.0 * (qz * vx - qx * vz)
70
+ tz = 2.0 * (qx * vy - qy * vx)
71
+ return (
72
+ vx + qw * tx + (qy * tz - qz * ty),
73
+ vy + qw * ty + (qz * tx - qx * tz),
74
+ vz + qw * tz + (qx * ty - qy * tx),
75
+ )
76
+
77
+
78
+ @dataclass(frozen=True, slots=True)
79
+ class RigidPose:
80
+ position_m: tuple[float, float, float]
81
+ quaternion_xyzw: tuple[float, float, float, float]
82
+
83
+ def __post_init__(self) -> None:
84
+ position = _finite(tuple(self.position_m), code="pose_position_non_finite")
85
+ if len(position) != 3:
86
+ raise PoseMathError("pose_position_size_invalid")
87
+ object.__setattr__(self, "position_m", position)
88
+ object.__setattr__(
89
+ self,
90
+ "quaternion_xyzw",
91
+ normalize_quaternion(tuple(self.quaternion_xyzw)),
92
+ )
93
+
94
+ @classmethod
95
+ def identity(cls) -> "RigidPose":
96
+ return cls((0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0))
97
+
98
+ def compose(self, child: "RigidPose") -> "RigidPose":
99
+ offset = rotate_vector(self.quaternion_xyzw, child.position_m)
100
+ return RigidPose(
101
+ tuple(self.position_m[index] + offset[index] for index in range(3)),
102
+ quaternion_multiply(self.quaternion_xyzw, child.quaternion_xyzw),
103
+ )
104
+
105
+ def inverse(self) -> "RigidPose":
106
+ inverse_q = quaternion_conjugate(self.quaternion_xyzw)
107
+ inverse_position = rotate_vector(
108
+ inverse_q,
109
+ tuple(-value for value in self.position_m),
110
+ )
111
+ return RigidPose(inverse_position, inverse_q)
112
+
113
+ def relative_to(self, parent: "RigidPose") -> "RigidPose":
114
+ return parent.inverse().compose(self)
115
+
116
+ def position_error_m(self, other: "RigidPose") -> float:
117
+ return sqrt(
118
+ sum(
119
+ (self.position_m[index] - other.position_m[index]) ** 2
120
+ for index in range(3)
121
+ )
122
+ )
123
+
124
+ def orientation_error_rad(self, other: "RigidPose") -> float:
125
+ first = normalize_quaternion(self.quaternion_xyzw)
126
+ second = normalize_quaternion(other.quaternion_xyzw)
127
+ dot = abs(sum(a * b for a, b in zip(first, second)))
128
+ return 2.0 * acos(max(-1.0, min(1.0, dot)))
129
+
130
+ def to_dict(self) -> dict[str, list[float]]:
131
+ return {
132
+ "position_m": list(self.position_m),
133
+ "quaternion_xyzw": list(self.quaternion_xyzw),
134
+ }