devagent-physical-engine 0.12.1__tar.gz → 0.12.2__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 (151) hide show
  1. {devagent_physical_engine-0.12.1/src/devagent_physical_engine.egg-info → devagent_physical_engine-0.12.2}/PKG-INFO +4 -2
  2. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/README.md +3 -1
  3. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/pyproject.toml +1 -1
  4. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/__init__.py +1 -1
  5. devagent_physical_engine-0.12.2/src/devagent_physical_engine/ros2/gazebo_cli.py +77 -0
  6. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/gazebo_pose.py +6 -6
  7. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/gazebo_world.py +2 -7
  8. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2/src/devagent_physical_engine.egg-info}/PKG-INFO +4 -2
  9. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine.egg-info/SOURCES.txt +2 -0
  10. devagent_physical_engine-0.12.2/tests/test_gazebo_cli_v0122.py +88 -0
  11. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/NOTICE +0 -0
  12. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/setup.cfg +0 -0
  13. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/__init__.py +0 -0
  14. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/compiler.py +0 -0
  15. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/contracts.py +0 -0
  16. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/coordinator.py +0 -0
  17. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/critic.py +0 -0
  18. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/evidence.py +0 -0
  19. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/interpreter.py +0 -0
  20. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/planner.py +0 -0
  21. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/recovery.py +0 -0
  22. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/routing.py +0 -0
  23. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/runtime.py +0 -0
  24. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/semantic.py +0 -0
  25. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/agent/structured.py +0 -0
  26. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ai_cli.py +0 -0
  27. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/cli.py +0 -0
  28. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/continuous_clearance.py +0 -0
  29. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/doctor.py +0 -0
  30. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/engineering_agent.py +0 -0
  31. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/engineering_request.py +0 -0
  32. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/execution.py +0 -0
  33. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/models.py +0 -0
  34. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/operating_envelope.py +0 -0
  35. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/__init__.py +0 -0
  36. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/benchmark.py +0 -0
  37. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/candidates.py +0 -0
  38. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/contracts.py +0 -0
  39. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/evaluator.py +0 -0
  40. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/evidence.py +0 -0
  41. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/experience.py +0 -0
  42. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/measured.py +0 -0
  43. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/optimizer.py +0 -0
  44. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/optimization/orchestrator.py +0 -0
  45. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/physical_campaign.py +0 -0
  46. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/physical_evidence.py +0 -0
  47. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/physical_motion.py +0 -0
  48. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/planning.py +0 -0
  49. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/preexecution_contract.py +0 -0
  50. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/provider_adapters/__init__.py +0 -0
  51. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/provider_adapters/anthropic.py +0 -0
  52. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/provider_adapters/common.py +0 -0
  53. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/provider_adapters/factory.py +0 -0
  54. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/provider_adapters/gemini.py +0 -0
  55. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/provider_adapters/openai.py +0 -0
  56. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/provider_qualification.py +0 -0
  57. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/providers.py +0 -0
  58. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/qualification.py +0 -0
  59. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/qualification_cli.py +0 -0
  60. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/qualification_harness.py +0 -0
  61. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/reference_workcell.py +0 -0
  62. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/robot_platform.py +0 -0
  63. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/robots.py +0 -0
  64. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/__init__.py +0 -0
  65. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/acceptance.py +0 -0
  66. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/commands.py +0 -0
  67. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/continuous_clearance_probe.py +0 -0
  68. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/doctor.py +0 -0
  69. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/fk_pose.py +0 -0
  70. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/fk_probe.py +0 -0
  71. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/frame_alignment.py +0 -0
  72. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/joint_state_recorder.py +0 -0
  73. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/measured_motion.py +0 -0
  74. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/moveit_joint_plan_probe.py +0 -0
  75. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/moveit_scene.py +0 -0
  76. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/moveit_task_planner.py +0 -0
  77. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/preexecution.py +0 -0
  78. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/qualification.py +0 -0
  79. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/qualification_v10.py +0 -0
  80. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/qualification_v11.py +0 -0
  81. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/qualification_v12.py +0 -0
  82. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/scene_probe.py +0 -0
  83. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/state_validity_probe.py +0 -0
  84. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/task_adapter.py +0 -0
  85. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/task_visualization.py +0 -0
  86. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/tf_probe.py +0 -0
  87. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/tool_scene.py +0 -0
  88. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/tool_scene_probe.py +0 -0
  89. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/trajectory.py +0 -0
  90. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/ur5e.py +0 -0
  91. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/ur5e_adapter.py +0 -0
  92. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/ur5e_v10_adapter.py +0 -0
  93. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/workpiece_follow.py +0 -0
  94. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/workpiece_gazebo_follower.py +0 -0
  95. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/workpiece_scene.py +0 -0
  96. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/ros2/workpiece_scene_probe.py +0 -0
  97. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/setup_profile.py +0 -0
  98. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/sim_real_qualification.py +0 -0
  99. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/simulation.py +0 -0
  100. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/simulation_platform.py +0 -0
  101. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/tool_collision.py +0 -0
  102. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/trajectory_qualification.py +0 -0
  103. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/twin.py +0 -0
  104. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/twin_builder.py +0 -0
  105. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/twin_materialization.py +0 -0
  106. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/verification.py +0 -0
  107. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine/workpiece_lifecycle.py +0 -0
  108. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine.egg-info/dependency_links.txt +0 -0
  109. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine.egg-info/entry_points.txt +0 -0
  110. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine.egg-info/requires.txt +0 -0
  111. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/src/devagent_physical_engine.egg-info/top_level.txt +0 -0
  112. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_agent_core.py +0 -0
  113. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_agent_semantic_hardening.py +0 -0
  114. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_ai_cli.py +0 -0
  115. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_ai_cli_v07.py +0 -0
  116. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_continuous_clearance_v011.py +0 -0
  117. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_core.py +0 -0
  118. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_engineering_request_v07.py +0 -0
  119. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_interpreter_profiles_v08.py +0 -0
  120. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_live_provider_qualification.py +0 -0
  121. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_measured_motion_v10.py +0 -0
  122. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_natural_language_agent_v07.py +0 -0
  123. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_openai_strict_schema_v0113.py +0 -0
  124. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_optimization_v05.py +0 -0
  125. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_physical_campaign_v09.py +0 -0
  126. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_physical_evidence_v09.py +0 -0
  127. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_physical_motion_v09.py +0 -0
  128. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_planning_fallback_v012.py +0 -0
  129. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_preexecution_contract_v10.py +0 -0
  130. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_provider_and_qualification.py +0 -0
  131. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_qualification_cli_lifecycle_v06.py +0 -0
  132. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_qualification_harness_v06.py +0 -0
  133. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_readme_pypi.py +0 -0
  134. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_real_provider_adapters.py +0 -0
  135. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_reference_workcell_v012.py +0 -0
  136. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_robot_platform_v08.py +0 -0
  137. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_ros2_production_receipts_v011.py +0 -0
  138. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_ros2_simulation.py +0 -0
  139. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_ros_trajectory_v09.py +0 -0
  140. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_setup_profile.py +0 -0
  141. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_sim_real_qualification_v011.py +0 -0
  142. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_simulation_platform_v08.py +0 -0
  143. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_tool_collision_v011.py +0 -0
  144. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_trajectory_qualification_v09.py +0 -0
  145. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_twin_materialization_v10.py +0 -0
  146. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_twin_v08.py +0 -0
  147. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_ur5e_adapter_scopes_v09.py +0 -0
  148. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_ur5e_v10_adapter_scopes.py +0 -0
  149. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_v052_stabilization.py +0 -0
  150. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/tests/test_v08_catalog_mapping_regression.py +0 -0
  151. {devagent_physical_engine-0.12.1 → devagent_physical_engine-0.12.2}/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.1
3
+ Version: 0.12.2
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
@@ -191,6 +191,8 @@ On a successful run, Gazebo / MoveIt remains open by default so the engineer can
191
191
 
192
192
  v0.12.1 hardens the initial ROS joint-state snapshot by parsing `ros2 topic echo --once` output as a YAML document stream. This accepts the normal ROS 2 trailing `---` message separator instead of incorrectly classifying an otherwise valid `/joint_states` sample as `joint_state_snapshot_invalid`.
193
193
 
194
+ v0.12.2 additionally hardens Gazebo model-pose read-back across Harmonic CLI renderings. One shared parser now accepts both pipe-delimited and whitespace-delimited finite XYZ/RPY vectors and is used by initial world verification and dynamic workpiece pose read-back, so task simulation does not depend on a single human-readable `gz model --pose` delimiter style.
195
+
194
196
  The packaged reference workcell is **not customer-site geometry**. Arbitrary plant layouts require an imported or user-declared physical Twin with trusted poses, collision geometry, tool/TCP information, and workpiece properties. DevAgent does not invent those site facts from a natural-language prompt.
195
197
 
196
198
  The v0.12 implementation remains evidence-gated: source/CI success does not prove the ROS target campaign has passed on a particular workstation. Use the executable qualification below before treating the task-specific path as qualified on that target.
@@ -418,7 +420,7 @@ Detailed engineering documentation lives in the repository:
418
420
 
419
421
  ## Project status
420
422
 
421
- **v0.12.1 — Beta software / evidence-gated task-specific physical simulation.**
423
+ **v0.12.2 — Beta software / evidence-gated task-specific physical simulation.**
422
424
 
423
425
  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.
424
426
 
@@ -150,6 +150,8 @@ On a successful run, Gazebo / MoveIt remains open by default so the engineer can
150
150
 
151
151
  v0.12.1 hardens the initial ROS joint-state snapshot by parsing `ros2 topic echo --once` output as a YAML document stream. This accepts the normal ROS 2 trailing `---` message separator instead of incorrectly classifying an otherwise valid `/joint_states` sample as `joint_state_snapshot_invalid`.
152
152
 
153
+ v0.12.2 additionally hardens Gazebo model-pose read-back across Harmonic CLI renderings. One shared parser now accepts both pipe-delimited and whitespace-delimited finite XYZ/RPY vectors and is used by initial world verification and dynamic workpiece pose read-back, so task simulation does not depend on a single human-readable `gz model --pose` delimiter style.
154
+
153
155
  The packaged reference workcell is **not customer-site geometry**. Arbitrary plant layouts require an imported or user-declared physical Twin with trusted poses, collision geometry, tool/TCP information, and workpiece properties. DevAgent does not invent those site facts from a natural-language prompt.
154
156
 
155
157
  The v0.12 implementation remains evidence-gated: source/CI success does not prove the ROS target campaign has passed on a particular workstation. Use the executable qualification below before treating the task-specific path as qualified on that target.
@@ -377,7 +379,7 @@ Detailed engineering documentation lives in the repository:
377
379
 
378
380
  ## Project status
379
381
 
380
- **v0.12.1 — Beta software / evidence-gated task-specific physical simulation.**
382
+ **v0.12.2 — Beta software / evidence-gated task-specific physical simulation.**
381
383
 
382
384
  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.
383
385
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devagent-physical-engine"
7
- version = "0.12.1"
7
+ version = "0.12.2"
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"
@@ -41,4 +41,4 @@ __all__ = [
41
41
  "TwinValidator",
42
42
  ]
43
43
 
44
- __version__ = "0.12.1"
44
+ __version__ = "0.12.2"
@@ -0,0 +1,77 @@
1
+ from __future__ import annotations
2
+
3
+ from math import isfinite
4
+ import re
5
+
6
+ from ..simulation_platform import SimulationPlatformError
7
+
8
+
9
+ _ANSI_ESCAPE = re.compile(r"\x1b\[[0-?]*[ -/]*[@-~]")
10
+ _BRACKET = re.compile(r"\[([^\[\]\r\n]+)\]")
11
+ _POSE_HEADER = re.compile(r"(?im)^\s*[-*]?\s*Pose\s*\[\s*XYZ(?:\s*\(m\))?\s*\].*$")
12
+
13
+
14
+ def _vector3(payload: str) -> tuple[float, float, float] | None:
15
+ """Parse one Gazebo bracket vector across supported CLI renderings.
16
+
17
+ Gazebo Sim releases have rendered vectors both as ``[x | y | z]`` and
18
+ ``[x y z]``. Some downstream packages also emit comma-separated values.
19
+ Accept those presentation differences while still requiring exactly three
20
+ finite numeric values.
21
+ """
22
+
23
+ parts = payload.replace("|", " ").replace(",", " ").split()
24
+ if len(parts) != 3:
25
+ return None
26
+ try:
27
+ values = tuple(float(value) for value in parts)
28
+ except ValueError:
29
+ return None
30
+ if any(not isfinite(value) for value in values):
31
+ return None
32
+ return values[0], values[1], values[2]
33
+
34
+
35
+ def parse_gz_model_pose(
36
+ text: str,
37
+ ) -> tuple[tuple[float, float, float], tuple[float, float, float]]:
38
+ """Parse ``gz model -m NAME --pose`` output deterministically.
39
+
40
+ The human-readable Gazebo CLI is not stable in its vector delimiter style.
41
+ Anchor on the model Pose header and parse the first two valid 3-vectors
42
+ beneath it as XYZ metres and RPY radians. ANSI terminal escapes are ignored.
43
+ A legacy plain six-number pose line is accepted as a bounded compatibility
44
+ fallback.
45
+ """
46
+
47
+ cleaned = _ANSI_ESCAPE.sub("", text)
48
+ header = _POSE_HEADER.search(cleaned)
49
+ section = cleaned[header.end() :] if header is not None else cleaned
50
+
51
+ vectors: list[tuple[float, float, float]] = []
52
+ for match in _BRACKET.finditer(section):
53
+ vector = _vector3(match.group(1))
54
+ if vector is None:
55
+ continue
56
+ vectors.append(vector)
57
+ if len(vectors) == 2:
58
+ return vectors[0], vectors[1]
59
+
60
+ # Compatibility with older Gazebo model tools that rendered
61
+ # ``x y z roll pitch yaw`` as one line instead of bracket vectors.
62
+ for line in section.splitlines():
63
+ parts = line.replace(",", " ").split()
64
+ if len(parts) != 6:
65
+ continue
66
+ try:
67
+ values = tuple(float(value) for value in parts)
68
+ except ValueError:
69
+ continue
70
+ if any(not isfinite(value) for value in values):
71
+ continue
72
+ return (
73
+ (values[0], values[1], values[2]),
74
+ (values[3], values[4], values[5]),
75
+ )
76
+
77
+ raise SimulationPlatformError("gazebo_model_pose_output_invalid")
@@ -2,10 +2,10 @@ from __future__ import annotations
2
2
 
3
3
  from dataclasses import asdict, dataclass
4
4
  from math import isfinite
5
- import re
6
5
 
7
6
  from ..simulation_platform import SimulationPlatformError
8
7
  from .commands import RosCommandRunner
8
+ from .gazebo_cli import parse_gz_model_pose
9
9
 
10
10
 
11
11
  @dataclass(frozen=True, slots=True)
@@ -21,11 +21,11 @@ class GazeboPoseUpdateReceipt:
21
21
 
22
22
 
23
23
  def _parse_position(text: str) -> tuple[float, float, float]:
24
- pattern = re.compile(r"\[\s*([-+0-9.eE]+)\s*\|\s*([-+0-9.eE]+)\s*\|\s*([-+0-9.eE]+)\s*\]")
25
- match = pattern.search(text)
26
- if match is None:
27
- raise SimulationPlatformError("gazebo_pose_readback_invalid")
28
- return tuple(float(match.group(index)) for index in range(1, 4))
24
+ try:
25
+ position, _orientation = parse_gz_model_pose(text)
26
+ except SimulationPlatformError as exc:
27
+ raise SimulationPlatformError("gazebo_pose_readback_invalid") from exc
28
+ return position
29
29
 
30
30
 
31
31
  class GazeboPoseBridge:
@@ -8,6 +8,7 @@ from typing import Any
8
8
  from ..simulation_platform import SimulationPlatformError
9
9
  from ..twin_materialization import CanonicalTwinMaterialization
10
10
  from .commands import RosCommandRunner
11
+ from .gazebo_cli import parse_gz_model_pose
11
12
 
12
13
 
13
14
  @dataclass(frozen=True, slots=True)
@@ -48,13 +49,7 @@ def _parse_model_names(text: str) -> set[str]:
48
49
 
49
50
 
50
51
  def _parse_pose(text: str):
51
- triples: list[tuple[float, float, float]] = []
52
- pattern = re.compile(r"\[\s*([-+0-9.eE]+)\s*\|\s*([-+0-9.eE]+)\s*\|\s*([-+0-9.eE]+)\s*\]")
53
- for match in pattern.finditer(text):
54
- triples.append(tuple(float(match.group(index)) for index in range(1, 4)))
55
- if len(triples) < 2:
56
- raise SimulationPlatformError("gazebo_model_pose_output_invalid")
57
- return triples[0], triples[1]
52
+ return parse_gz_model_pose(text)
58
53
 
59
54
 
60
55
  class GazeboWorldVerifier:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devagent-physical-engine
3
- Version: 0.12.1
3
+ Version: 0.12.2
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
@@ -191,6 +191,8 @@ On a successful run, Gazebo / MoveIt remains open by default so the engineer can
191
191
 
192
192
  v0.12.1 hardens the initial ROS joint-state snapshot by parsing `ros2 topic echo --once` output as a YAML document stream. This accepts the normal ROS 2 trailing `---` message separator instead of incorrectly classifying an otherwise valid `/joint_states` sample as `joint_state_snapshot_invalid`.
193
193
 
194
+ v0.12.2 additionally hardens Gazebo model-pose read-back across Harmonic CLI renderings. One shared parser now accepts both pipe-delimited and whitespace-delimited finite XYZ/RPY vectors and is used by initial world verification and dynamic workpiece pose read-back, so task simulation does not depend on a single human-readable `gz model --pose` delimiter style.
195
+
194
196
  The packaged reference workcell is **not customer-site geometry**. Arbitrary plant layouts require an imported or user-declared physical Twin with trusted poses, collision geometry, tool/TCP information, and workpiece properties. DevAgent does not invent those site facts from a natural-language prompt.
195
197
 
196
198
  The v0.12 implementation remains evidence-gated: source/CI success does not prove the ROS target campaign has passed on a particular workstation. Use the executable qualification below before treating the task-specific path as qualified on that target.
@@ -418,7 +420,7 @@ Detailed engineering documentation lives in the repository:
418
420
 
419
421
  ## Project status
420
422
 
421
- **v0.12.1 — Beta software / evidence-gated task-specific physical simulation.**
423
+ **v0.12.2 — Beta software / evidence-gated task-specific physical simulation.**
422
424
 
423
425
  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.
424
426
 
@@ -78,6 +78,7 @@ src/devagent_physical_engine/ros2/doctor.py
78
78
  src/devagent_physical_engine/ros2/fk_pose.py
79
79
  src/devagent_physical_engine/ros2/fk_probe.py
80
80
  src/devagent_physical_engine/ros2/frame_alignment.py
81
+ src/devagent_physical_engine/ros2/gazebo_cli.py
81
82
  src/devagent_physical_engine/ros2/gazebo_pose.py
82
83
  src/devagent_physical_engine/ros2/gazebo_world.py
83
84
  src/devagent_physical_engine/ros2/joint_state_recorder.py
@@ -112,6 +113,7 @@ tests/test_ai_cli_v07.py
112
113
  tests/test_continuous_clearance_v011.py
113
114
  tests/test_core.py
114
115
  tests/test_engineering_request_v07.py
116
+ tests/test_gazebo_cli_v0122.py
115
117
  tests/test_interpreter_profiles_v08.py
116
118
  tests/test_live_provider_qualification.py
117
119
  tests/test_measured_motion_v10.py
@@ -0,0 +1,88 @@
1
+ from __future__ import annotations
2
+
3
+ import unittest
4
+
5
+ from devagent_physical_engine.ros2.gazebo_cli import parse_gz_model_pose
6
+ from devagent_physical_engine.ros2.gazebo_pose import _parse_position
7
+ from devagent_physical_engine.ros2.gazebo_world import _parse_pose
8
+ from devagent_physical_engine.simulation_platform import SimulationPlatformError
9
+
10
+
11
+ PIPE_OUTPUT = """Requesting state for world [default]...
12
+
13
+ Model: [8]
14
+
15
+ - Name: BOX_101
16
+
17
+ - Pose [ XYZ (m) ] [ RPY (rad) ]:
18
+
19
+ [0.550000 | -0.350000 | 0.820000]
20
+
21
+ [0.000000 | 0.000000 | 1.570796]
22
+ """
23
+
24
+ HARMONIC_WHITESPACE_OUTPUT = """Requesting state for world [default]...
25
+
26
+ * Model [8]
27
+ * Name: BOX_101
28
+ * Pose [ XYZ (m) ] [ RPY (rad) ]:
29
+ [0.550000 -0.350000 0.820000]
30
+ [0.000000 -0.000000 1.570796]
31
+ """
32
+
33
+
34
+ class GazeboCliPoseV0122Tests(unittest.TestCase):
35
+ def test_accepts_documented_pipe_delimited_pose(self):
36
+ position, orientation = parse_gz_model_pose(PIPE_OUTPUT)
37
+ self.assertEqual(position, (0.55, -0.35, 0.82))
38
+ self.assertEqual(orientation, (0.0, 0.0, 1.570796))
39
+
40
+ def test_accepts_harmonic_whitespace_delimited_pose(self):
41
+ position, orientation = parse_gz_model_pose(HARMONIC_WHITESPACE_OUTPUT)
42
+ self.assertEqual(position, (0.55, -0.35, 0.82))
43
+ self.assertEqual(orientation, (0.0, -0.0, 1.570796))
44
+
45
+ def test_world_verifier_parser_uses_harmonic_compatible_parser(self):
46
+ self.assertEqual(
47
+ _parse_pose(HARMONIC_WHITESPACE_OUTPUT),
48
+ ((0.55, -0.35, 0.82), (0.0, -0.0, 1.570796)),
49
+ )
50
+
51
+ def test_dynamic_workpiece_readback_uses_same_parser(self):
52
+ self.assertEqual(
53
+ _parse_position(HARMONIC_WHITESPACE_OUTPUT),
54
+ (0.55, -0.35, 0.82),
55
+ )
56
+
57
+ def test_ansi_terminal_escape_does_not_break_pose(self):
58
+ payload = "\x1b[32m" + HARMONIC_WHITESPACE_OUTPUT + "\x1b[0m"
59
+ self.assertEqual(parse_gz_model_pose(payload)[0], (0.55, -0.35, 0.82))
60
+
61
+ def test_legacy_plain_six_number_pose_is_supported(self):
62
+ self.assertEqual(
63
+ parse_gz_model_pose("0.55 -0.35 0.82 0.0 0.0 1.570796\n"),
64
+ ((0.55, -0.35, 0.82), (0.0, 0.0, 1.570796)),
65
+ )
66
+
67
+ def test_incomplete_pose_fails_closed(self):
68
+ with self.assertRaisesRegex(
69
+ SimulationPlatformError,
70
+ "gazebo_model_pose_output_invalid",
71
+ ):
72
+ parse_gz_model_pose(
73
+ "- Pose [ XYZ (m) ] [ RPY (rad) ]:\n[0.55 -0.35 0.82]\n"
74
+ )
75
+
76
+ def test_non_finite_pose_fails_closed(self):
77
+ with self.assertRaisesRegex(
78
+ SimulationPlatformError,
79
+ "gazebo_model_pose_output_invalid",
80
+ ):
81
+ parse_gz_model_pose(
82
+ "- Pose [ XYZ (m) ] [ RPY (rad) ]:\n"
83
+ "[0.55 -0.35 nan]\n[0.0 0.0 0.0]\n"
84
+ )
85
+
86
+
87
+ if __name__ == "__main__":
88
+ unittest.main()