execweave 0.8.28__tar.gz → 0.8.29__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 (187) hide show
  1. {execweave-0.8.28 → execweave-0.8.29}/PKG-INFO +10 -2
  2. {execweave-0.8.28 → execweave-0.8.29}/README.md +9 -1
  3. {execweave-0.8.28 → execweave-0.8.29}/pyproject.toml +2 -2
  4. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/__init__.py +1 -1
  5. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/framework_adapters/autogen.py +48 -0
  6. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/framework_adapters/base.py +23 -0
  7. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/framework_adapters/camel.py +4 -1
  8. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/framework_adapters/metagpt.py +20 -2
  9. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_core.py +16 -6
  10. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/provider_record.py +1 -0
  11. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel.py +24 -3
  12. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/workflow.py +60 -3
  13. {execweave-0.8.28 → execweave-0.8.29}/.gitignore +0 -0
  14. {execweave-0.8.28 → execweave-0.8.29}/LICENSE +0 -0
  15. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/__main__.py +0 -0
  16. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/_conversation_records_core.py +0 -0
  17. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/_dashboard_shell_base.py +0 -0
  18. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/_http_proxy_base.py +0 -0
  19. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/_http_proxy_bounded.py +0 -0
  20. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/_http_proxy_stage.py +0 -0
  21. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/agent_bootstrap.py +0 -0
  22. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/agent_topology.py +0 -0
  23. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/agent_trace.py +0 -0
  24. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/agy_preview_sanitize.py +0 -0
  25. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/analysis.py +0 -0
  26. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/anthropic.py +0 -0
  27. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/anthropic_cli.py +0 -0
  28. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/anthropic_full_fidelity.py +0 -0
  29. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_adapter.py +0 -0
  30. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_adapter_base.py +0 -0
  31. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_full_fidelity.py +0 -0
  32. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_full_fidelity_base.py +0 -0
  33. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_full_fidelity_collaboration_base.py +0 -0
  34. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_hook_cli.py +0 -0
  35. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_record.py +0 -0
  36. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_subagent_linkage.py +0 -0
  37. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/antigravity_trace_capability.py +0 -0
  38. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/auto_specialized.py +0 -0
  39. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/backends.py +0 -0
  40. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/benchmark.py +0 -0
  41. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/claude_adapter.py +0 -0
  42. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/claude_child_transcript.py +0 -0
  43. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/claude_delegation.py +0 -0
  44. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/claude_full_fidelity.py +0 -0
  45. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/claude_hook_cli.py +0 -0
  46. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/claude_hook_contract.py +0 -0
  47. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/claude_model_observer.py +0 -0
  48. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/claude_record.py +0 -0
  49. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cli.py +0 -0
  50. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_adapter.py +0 -0
  51. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_conversation.py +0 -0
  52. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_full_fidelity.py +0 -0
  53. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_hook_cli.py +0 -0
  54. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_hook_entry.py +0 -0
  55. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_hook_lifecycle.py +0 -0
  56. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_message_diagnostics.py +0 -0
  57. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_message_transport_diagnostics.py +0 -0
  58. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_record.py +0 -0
  59. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_rollout_structures.py +0 -0
  60. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_rollout_trace.py +0 -0
  61. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/codex_rollout_trace_base.py +0 -0
  62. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/collector.py +0 -0
  63. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/command.py +0 -0
  64. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/content_evidence.py +0 -0
  65. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/content_store.py +0 -0
  66. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_archive.py +0 -0
  67. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_message_identity.py +0 -0
  68. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_preview.py +0 -0
  69. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_preview_antigravity.py +0 -0
  70. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_preview_claude.py +0 -0
  71. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_preview_codex.py +0 -0
  72. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_preview_common.py +0 -0
  73. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_preview_generic.py +0 -0
  74. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_preview_lines.py +0 -0
  75. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_preview_transcript.py +0 -0
  76. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_records.py +0 -0
  77. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_records_antigravity.py +0 -0
  78. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_records_codex.py +0 -0
  79. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_records_common.py +0 -0
  80. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/conversation_records_ollama.py +0 -0
  81. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/correlation.py +0 -0
  82. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cursor_adapter.py +0 -0
  83. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cursor_delegation.py +0 -0
  84. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cursor_delegation_base.py +0 -0
  85. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cursor_full_fidelity.py +0 -0
  86. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cursor_hook_cli.py +0 -0
  87. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cursor_hook_contract.py +0 -0
  88. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cursor_lifecycle.py +0 -0
  89. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/cursor_record.py +0 -0
  90. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/dashboard_shell.py +0 -0
  91. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/entry.py +0 -0
  92. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/evidence_availability.py +0 -0
  93. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/evidence_grade.py +0 -0
  94. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/fidelity.py +0 -0
  95. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/filesystem.py +0 -0
  96. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/focus.py +0 -0
  97. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/framework_adapters/__init__.py +0 -0
  98. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/framework_adapters/registry.py +0 -0
  99. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/graph.py +0 -0
  100. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/graph_ops.py +0 -0
  101. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/http_proxy.py +0 -0
  102. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/http_proxy_cli.py +0 -0
  103. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/inference_gateway.py +0 -0
  104. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/inference_gateway_cli.py +0 -0
  105. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/inference_gateway_full_fidelity.py +0 -0
  106. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/inference_identity.py +0 -0
  107. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/inference_identity_cli.py +0 -0
  108. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/integrity.py +0 -0
  109. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/integrity_cli.py +0 -0
  110. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/litellm_callback.py +0 -0
  111. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/litellm_callback_cli.py +0 -0
  112. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live.py +0 -0
  113. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view.py +0 -0
  114. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_extra_style.py +0 -0
  115. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_markup.py +0 -0
  116. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_process_layout.py +0 -0
  117. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_readability.py +0 -0
  118. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_script_a.py +0 -0
  119. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_script_b.py +0 -0
  120. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_script_c.py +0 -0
  121. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_script_d.py +0 -0
  122. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/live_view_style.py +0 -0
  123. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/model_runtime.py +0 -0
  124. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/model_runtime_cli.py +0 -0
  125. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/model_runtime_full_fidelity.py +0 -0
  126. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/openai_compatible.py +0 -0
  127. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/openai_compatible_cli.py +0 -0
  128. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/openai_compatible_full_fidelity.py +0 -0
  129. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/opencode_adapter.py +0 -0
  130. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/opencode_event_contract.py +0 -0
  131. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/opencode_full_fidelity.py +0 -0
  132. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/opencode_hook_cli.py +0 -0
  133. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/opencode_plugin_cli.py +0 -0
  134. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/opencode_record.py +0 -0
  135. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/opencode_task_linkage.py +0 -0
  136. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/overhead_benchmark.py +0 -0
  137. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/provider_capability.py +0 -0
  138. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/provider_lifecycle.py +0 -0
  139. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/rule_pack.py +0 -0
  140. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/rule_pack_cli.py +0 -0
  141. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/runtime_endpoint_availability.py +0 -0
  142. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/scalability_benchmark.py +0 -0
  143. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/schema.py +0 -0
  144. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/scope.py +0 -0
  145. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/semantic.py +0 -0
  146. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/sink.py +0 -0
  147. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/strace_backend.py +0 -0
  148. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/stream_assembly.py +0 -0
  149. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/theme.py +0 -0
  150. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/top.py +0 -0
  151. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/top_cli.py +0 -0
  152. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/validate.py +0 -0
  153. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/vendor/dagre.min.js +0 -0
  154. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/view_cli.py +0 -0
  155. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer.py +0 -0
  156. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel_antigravity.py +0 -0
  157. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel_claude.py +0 -0
  158. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel_codex.py +0 -0
  159. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel_cursor.py +0 -0
  160. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel_default.py +0 -0
  161. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel_ollama.py +0 -0
  162. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel_opencode.py +0 -0
  163. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_agent_panel_registry.py +0 -0
  164. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_content_inspector.py +0 -0
  165. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_dashboard_clean.py +0 -0
  166. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_dashboard_focus.py +0 -0
  167. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_dashboard_hardening.py +0 -0
  168. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_dashboard_hardening_v2.py +0 -0
  169. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_dashboard_pr70.py +0 -0
  170. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_edge_decross.py +0 -0
  171. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_execution_flow.py +0 -0
  172. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_execution_flow_provider_normalization.py +0 -0
  173. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_execution_flow_safety.py +0 -0
  174. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_external_endpoints.py +0 -0
  175. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_flow_canvas.py +0 -0
  176. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_flow_layout.py +0 -0
  177. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_gif.py +0 -0
  178. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_layout_geometry.py +0 -0
  179. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_layout_v2.py +0 -0
  180. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_layout_v2_detached.py +0 -0
  181. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_limits.py +0 -0
  182. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_live_layout.py +0 -0
  183. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_projection.py +0 -0
  184. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_projection_base.py +0 -0
  185. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_projection_bridges.py +0 -0
  186. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_semantic_projection.py +0 -0
  187. {execweave-0.8.28 → execweave-0.8.29}/src/execweave/viewer_tool_mirror_identity.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: execweave
3
- Version: 0.8.28
3
+ Version: 0.8.29
4
4
  Summary: Turn AI-agent runtime behavior into a local interactive execution graph.
5
5
  Project-URL: Homepage, https://github.com/Irish-kw/ExecWeave
6
6
  Project-URL: Repository, https://github.com/Irish-kw/ExecWeave
@@ -388,5 +388,13 @@ Paper context: Li et al., *CAMEL: Communicative Agents for "Mind" Exploration of
388
388
 
389
389
  ```python
390
390
  from execweave.framework_adapters import AdapterContext, CAMELAdapter
391
- adapter = CAMELAdapter(AdapterContext.from_environment("camel"))
391
+ context = AdapterContext.from_environment("camel", capture_mode="prompt_and_response")
392
+ adapter = CAMELAdapter(context)
393
+ task = adapter.task_created("task-1", content="Inspect the endpoint and report completion.")
392
394
  ```
395
+
396
+ When the application is launched by `execweave record` or `execweave live`,
397
+ the adapter automatically joins that run and the finished Dashboard is built
398
+ from the merged runtime plus framework evidence. Task prompts and routed
399
+ messages remain local content references and are visible from their task and
400
+ agent nodes.
@@ -328,5 +328,13 @@ Paper context: Li et al., *CAMEL: Communicative Agents for "Mind" Exploration of
328
328
 
329
329
  ```python
330
330
  from execweave.framework_adapters import AdapterContext, CAMELAdapter
331
- adapter = CAMELAdapter(AdapterContext.from_environment("camel"))
331
+ context = AdapterContext.from_environment("camel", capture_mode="prompt_and_response")
332
+ adapter = CAMELAdapter(context)
333
+ task = adapter.task_created("task-1", content="Inspect the endpoint and report completion.")
332
334
  ```
335
+
336
+ When the application is launched by `execweave record` or `execweave live`,
337
+ the adapter automatically joins that run and the finished Dashboard is built
338
+ from the merged runtime plus framework evidence. Task prompts and routed
339
+ messages remain local content references and are visible from their task and
340
+ agent nodes.
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "execweave"
7
- # ExecWeave v0.8.28 release metadata
8
- version = "0.8.28"
7
+ # ExecWeave v0.8.29 release metadata
8
+ version = "0.8.29"
9
9
  description = "Turn AI-agent runtime behavior into a local interactive execution graph."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """ExecWeave runtime graph package."""
2
2
 
3
- __version__ = "0.8.28"
3
+ __version__ = "0.8.29"
@@ -15,6 +15,7 @@ from .base import (
15
15
  FrameworkCompatibility,
16
16
  MessageRecord,
17
17
  ModelCallRecord,
18
+ TaskRecord,
18
19
  ToolCallRecord,
19
20
  )
20
21
 
@@ -26,6 +27,13 @@ class AutoGenAdapter(FrameworkAdapter):
26
27
  "AGENT_CREATED",
27
28
  "AGENT_STARTED",
28
29
  "AGENT_STOPPED",
30
+ "TASK_CREATED",
31
+ "TASK_ASSIGNED",
32
+ "TASK_STARTED",
33
+ "TASK_UPDATED",
34
+ "TASK_COMPLETED",
35
+ "TASK_FAILED",
36
+ "TASK_CONTENT_RECORDED",
29
37
  "MESSAGE_SENT",
30
38
  "MESSAGE_RECEIVED",
31
39
  "MODEL_REQUEST",
@@ -86,6 +94,46 @@ class AutoGenAdapter(FrameworkAdapter):
86
94
  self.context.record_agent(AgentRecord(agent, role=role, process=process, attributes=attributes))
87
95
  return agent
88
96
 
97
+ def observe_task(
98
+ self,
99
+ task_id: str | int,
100
+ *,
101
+ owner: EntityRef | None = None,
102
+ name: str | None = None,
103
+ content: str | None = None,
104
+ content_kind: str = "task_prompt",
105
+ status: str = "created",
106
+ **attributes: Any,
107
+ ) -> EntityRef:
108
+ """Record an authoritative AutoGen task and its visible task prompt."""
109
+ entity_attributes = dict(attributes)
110
+ if content is not None and self.context.capture_policy.mode in {
111
+ "prompt_only",
112
+ "prompt_and_response",
113
+ }:
114
+ entity_attributes.setdefault("task_prompt", content)
115
+ task = self.task(task_id, name=name, provider="autogen", **entity_attributes)
116
+ event = {
117
+ "created": "TASK_CREATED",
118
+ "started": "TASK_STARTED",
119
+ "updated": "TASK_UPDATED",
120
+ "completed": "TASK_COMPLETED",
121
+ "failed": "TASK_FAILED",
122
+ }.get(status)
123
+ if event is None:
124
+ raise ValueError(f"unsupported AutoGen task status: {status}")
125
+ self.context.record_task(
126
+ TaskRecord(
127
+ task,
128
+ owner=owner,
129
+ content=content,
130
+ content_kind=content_kind,
131
+ attributes=attributes,
132
+ ),
133
+ event_type=event,
134
+ )
135
+ return task
136
+
89
137
  def observe_message(
90
138
  self,
91
139
  message_id: str | int,
@@ -11,6 +11,7 @@ import hashlib
11
11
  import json
12
12
  import os
13
13
  import re
14
+ import sys
14
15
  import threading
15
16
  import time
16
17
  from dataclasses import asdict, dataclass, field
@@ -19,6 +20,8 @@ from pathlib import Path
19
20
  from typing import Any, Literal, Mapping
20
21
  from uuid import uuid4
21
22
 
23
+ import psutil
24
+
22
25
  from ..content_store import ContentReference, FullFidelityContentStore
23
26
  from ..schema import SCHEMA_VERSION
24
27
 
@@ -137,6 +140,20 @@ class ProcessRef:
137
140
  return EntityRef("process_reference", f"process-reference:{identity}", self.executable or f"pid {self.pid}", attributes)
138
141
 
139
142
 
143
+ def _current_process_ref() -> ProcessRef:
144
+ """Return the authoritative identity of the adapter's current process."""
145
+ process = psutil.Process(os.getpid())
146
+ try:
147
+ create_time = process.create_time()
148
+ except (psutil.AccessDenied, psutil.NoSuchProcess, psutil.ZombieProcess):
149
+ create_time = None
150
+ try:
151
+ executable = process.exe()
152
+ except (psutil.AccessDenied, psutil.NoSuchProcess, psutil.ZombieProcess):
153
+ executable = sys.executable
154
+ return ProcessRef(os.getpid(), create_time, executable or sys.executable)
155
+
156
+
140
157
  @dataclass(frozen=True)
141
158
  class AdapterCapabilities:
142
159
  events: tuple[str, ...] = ()
@@ -362,6 +379,12 @@ class AdapterContext:
362
379
 
363
380
  @classmethod
364
381
  def from_environment(cls, framework: str, *, capture_mode: CaptureMode = "metadata_only", content_root: str | Path | None = None, run_id: str | None = None, session_id: str | None = None, conversation_id: str | None = None, process: ProcessRef | None = None) -> "AdapterContext":
382
+ if (
383
+ process is None
384
+ and os.environ.get("EXECWEAVE_SEMANTIC_SIDECAR")
385
+ and os.environ.get("EXECWEAVE_SESSION_ID")
386
+ ):
387
+ process = _current_process_ref()
365
388
  return cls(framework=framework, run_id=run_id, session_id=session_id, conversation_id=conversation_id, content_root=content_root, capture_policy=ContentCapturePolicy(capture_mode), process=process)
366
389
 
367
390
  def entity(self, entity_type: str, native_id: str | int | None, *, name: str | None = None, attributes: Mapping[str, Any] | None = None) -> EntityRef:
@@ -51,7 +51,10 @@ class CAMELAdapter(FrameworkAdapter):
51
51
  task = existing
52
52
  else:
53
53
  entity_attributes = dict(attributes)
54
- if content is not None:
54
+ if content is not None and self.context.capture_policy.mode in {
55
+ "prompt_only",
56
+ "prompt_and_response",
57
+ }:
55
58
  entity_attributes.setdefault("task_prompt", content)
56
59
  task = self.task(native_id, name=name, provider="camel", **entity_attributes)
57
60
  self._tasks[str(native_id)] = task
@@ -30,6 +30,7 @@ class MetaGPTAdapter(FrameworkAdapter):
30
30
  "TASK_COMPLETED",
31
31
  "TASK_FAILED",
32
32
  "TASK_UPDATED",
33
+ "TASK_CONTENT_RECORDED",
33
34
  "MESSAGE_SENT",
34
35
  "MESSAGE_RECEIVED",
35
36
  "MODEL_REQUEST",
@@ -96,10 +97,18 @@ class MetaGPTAdapter(FrameworkAdapter):
96
97
  *,
97
98
  owner: EntityRef | None = None,
98
99
  name: str | None = None,
100
+ content: str | None = None,
101
+ content_kind: str = "task_prompt",
99
102
  status: str = "created",
100
103
  **attributes: Any,
101
104
  ) -> EntityRef:
102
- task = self.task(task_id, name=name, provider="metagpt", **attributes)
105
+ entity_attributes = dict(attributes)
106
+ if content is not None and self.context.capture_policy.mode in {
107
+ "prompt_only",
108
+ "prompt_and_response",
109
+ }:
110
+ entity_attributes.setdefault("task_prompt", content)
111
+ task = self.task(task_id, name=name, provider="metagpt", **entity_attributes)
103
112
  event = {
104
113
  "created": "TASK_CREATED",
105
114
  "started": "TASK_STARTED",
@@ -108,7 +117,16 @@ class MetaGPTAdapter(FrameworkAdapter):
108
117
  }.get(status)
109
118
  if event is None:
110
119
  raise ValueError(f"unsupported MetaGPT task status: {status}")
111
- self.context.record_task(TaskRecord(task, owner=owner, attributes=attributes), event_type=event)
120
+ self.context.record_task(
121
+ TaskRecord(
122
+ task,
123
+ owner=owner,
124
+ content=content,
125
+ content_kind=content_kind,
126
+ attributes=attributes,
127
+ ),
128
+ event_type=event,
129
+ )
112
130
  return task
113
131
 
114
132
  def observe_message(
@@ -37,6 +37,8 @@ from .viewer import (
37
37
  LIVE_DELTA_HISTORY = 256
38
38
  LIVE_DELTA_HISTORY_BYTES = 8 * 1024 * 1024
39
39
  _SEMANTIC_ENV = "EXECWEAVE_SEMANTIC_SIDECAR"
40
+ _RUN_ID_ENV = "EXECWEAVE_RUN_ID"
41
+ _SESSION_ID_ENV = "EXECWEAVE_SESSION_ID"
40
42
  _LIVE_TOKEN_HEADER = "X-ExecWeave-Token"
41
43
 
42
44
  _FINAL_THEME_CSS = """
@@ -737,16 +739,24 @@ def run_live(
737
739
  webbrowser.open(authenticated_live_url)
738
740
 
739
741
  return_code = 1
740
- previous_semantic_sidecar = os.environ.get(_SEMANTIC_ENV)
741
- os.environ[_SEMANTIC_ENV] = str(semantic_path)
742
+ environment_updates = {
743
+ _SEMANTIC_ENV: str(semantic_path),
744
+ _RUN_ID_ENV: session_id,
745
+ _SESSION_ID_ENV: session_id,
746
+ }
747
+ previous_environment = {
748
+ key: os.environ.get(key) for key in environment_updates
749
+ }
750
+ os.environ.update(environment_updates)
742
751
  try:
743
752
  try:
744
753
  return_code = collector.run(command)
745
754
  finally:
746
- if previous_semantic_sidecar is None:
747
- os.environ.pop(_SEMANTIC_ENV, None)
748
- else:
749
- os.environ[_SEMANTIC_ENV] = previous_semantic_sidecar
755
+ for key, value in previous_environment.items():
756
+ if value is None:
757
+ os.environ.pop(key, None)
758
+ else:
759
+ os.environ[key] = value
750
760
 
751
761
  validation = validate_event_stream(event_path)
752
762
  if not validation.valid:
@@ -183,6 +183,7 @@ def record_provider_to_viewer(
183
183
  collect_network=collect_network,
184
184
  keep_raw_trace=keep_raw_trace,
185
185
  open_browser=False,
186
+ integrate_semantic=False,
186
187
  )
187
188
  finally:
188
189
  _restore_environment(previous_environment)
@@ -418,6 +418,26 @@ function toolOccurrenceSection(node){
418
418
  });
419
419
  return section;
420
420
  }
421
+ function execweaveAssignedTaskText(agent){
422
+ if(!agent||String(agent.type||'')!=='agent')return '';
423
+ const graph=rawGraph(),nodes=Array.isArray(graph.nodes)?graph.nodes:[],edges=Array.isArray(graph.edges)?graph.edges:[];
424
+ const nodeMap=new Map(nodes.filter(node=>node&&node.id).map(node=>[String(node.id),node]));
425
+ const exactAssignment=['ASSIGNED','AGENT','TASK'].join('_');
426
+ const direct=edges.filter(edge=>edge&&String(edge.target||'')===String(agent.id||'')&&['ASSIGNED_TO',exactAssignment].includes(String(edge.relation||''))).sort((a,b)=>(Number(a.first_sequence)||0)-(Number(b.first_sequence)||0));
427
+ const owned=edges.filter(edge=>edge&&String(edge.source||'')===String(agent.id||'')&&String(edge.relation||'')==='TASK_CREATED').sort((a,b)=>(Number(a.first_sequence)||0)-(Number(b.first_sequence)||0));
428
+ const started=edges.filter(edge=>edge&&String(edge.source||'')===String(agent.id||'')&&String(edge.relation||'')==='TASK_STARTED').sort((a,b)=>(Number(a.first_sequence)||0)-(Number(b.first_sequence)||0));
429
+ const edge=direct.at(-1)||owned.at(-1)||started.at(-1);if(!edge)return '';
430
+ const taskId=direct.length?edge.source:edge.target,task=nodeMap.get(String(taskId||''));
431
+ if(!task||String(task.type||'')!=='task')return '';
432
+ const a=attrs(task);return commandText(a.task_prompt||a.prompt||a.description||task.name);
433
+ }
434
+ function execweaveFillAssignedTask(round,node,isRoot){
435
+ const task=execweaveAssignedTaskText(node);if(!task)return round;
436
+ const value=round||{cards:[]},cards=Array.isArray(value.cards)?value.cards.map(card=>[card[0],card[1]]):[];
437
+ const label=isRoot?'Prompt':'Task',index=cards.findIndex(card=>String(card[0]||'')===label);
438
+ if(index<0)cards.unshift([label,task]);else if(!commandText(cards[index][1]))cards[index][1]=task;
439
+ return{...value,cards};
440
+ }
421
441
  function renderNode(node){
422
442
  const rows=nodeCards(node);
423
443
  if(!rows.length)return false;
@@ -436,10 +456,11 @@ function render(node){
436
456
  selectedNode=node;selectedConversationSignature=conversationSignature(node);detailsEmpty.hidden=true;details.replaceChildren();
437
457
  const record=recordFor(node),preview=record?.conversation_preview||{},path=String(preview.agent_path||nodePath(node)||'').trim(),messages=Array.isArray(preview.messages)?preview.messages:[];
438
458
  const isRoot=nodeHasRootAuthority(node)||previewUsesRootRenderer(preview);
439
- const rounds=isRoot?rootRounds(messages,path||'/root'):childRounds(messages,path);
459
+ const rounds=(isRoot?rootRounds(messages,path||'/root'):childRounds(messages,path)).map(round=>execweaveFillAssignedTask(round,node,isRoot));
440
460
  const tools=toolCallsFor(String(node.id||''));
441
- const appendTools=()=>{if(tools)details.appendChild(card('Tools',tools))};
442
- if(rounds.length<2){details.appendChild(roundView(rounds[0]||{cards:isRoot?[['Prompt',''],['Final response','']]:[['Task',''],['Thinking',''],['Response','']]}));appendTools();return true}
461
+ const frameworkCommunication=attrs(node).conversation_scope==='framework_agent'?uniqueTexts(messages.filter(message=>isObserved(message)&&!isInjected(message)&&String(message?.kind||'')==='agent_message')).join('\n\n'):'';
462
+ const appendTools=()=>{if(frameworkCommunication)details.appendChild(card('Agent communication',frameworkCommunication));if(tools)details.appendChild(card('Tools',tools))};
463
+ if(rounds.length<2){const fallback={cards:isRoot?[['Prompt',''],['Final response','']]:[['Task',''],['Thinking',''],['Response','']]};details.appendChild(roundView(rounds[0]||execweaveFillAssignedTask(fallback,node,isRoot)));appendTools();return true}
443
464
  // A subagent borrows the moment and the wording of the unique canonical root round
444
465
  // it belongs to. If root identity is ambiguous, the child keeps its own timestamp.
445
466
  const runs=isRoot?rounds:runRounds();
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import os
3
4
  from dataclasses import dataclass
4
5
  from pathlib import Path
5
6
  from uuid import uuid4
@@ -7,11 +8,16 @@ from uuid import uuid4
7
8
  from .backends import BackendName, create_collector, resolve_backend
8
9
  from .fidelity import write_fidelity_report
9
10
  from .graph import build_execution_graph, write_execution_graph
11
+ from .semantic import merge_semantic_sidecar
10
12
  from .sink import JsonlSink
11
13
  from .theme import ensure_viewer_theme
12
14
  from .validate import validate_event_stream
13
15
  from .viewer_projection import strip_internal_hook_execution_graph, write_graph_html
14
16
 
17
+ _SEMANTIC_ENV = "EXECWEAVE_SEMANTIC_SIDECAR"
18
+ _RUN_ID_ENV = "EXECWEAVE_RUN_ID"
19
+ _SESSION_ID_ENV = "EXECWEAVE_SESSION_ID"
20
+
15
21
 
16
22
  @dataclass(frozen=True)
17
23
  class RecordResult:
@@ -26,6 +32,9 @@ class RecordResult:
26
32
  event_count: int
27
33
  node_count: int
28
34
  edge_count: int
35
+ semantic_sidecar: Path | None = None
36
+ materialized_event_stream: Path | None = None
37
+ semantic_event_count: int = 0
29
38
 
30
39
  def to_dict(self) -> dict[str, object]:
31
40
  return {
@@ -40,6 +49,15 @@ class RecordResult:
40
49
  "event_count": self.event_count,
41
50
  "node_count": self.node_count,
42
51
  "edge_count": self.edge_count,
52
+ "semantic_sidecar": (
53
+ str(self.semantic_sidecar) if self.semantic_sidecar is not None else None
54
+ ),
55
+ "materialized_event_stream": (
56
+ str(self.materialized_event_stream)
57
+ if self.materialized_event_stream is not None
58
+ else str(self.event_stream)
59
+ ),
60
+ "semantic_event_count": self.semantic_event_count,
43
61
  }
44
62
 
45
63
 
@@ -61,6 +79,7 @@ def record_to_viewer(
61
79
  collect_network: bool = True,
62
80
  keep_raw_trace: bool = False,
63
81
  open_browser: bool = False,
82
+ integrate_semantic: bool = True,
64
83
  ) -> RecordResult:
65
84
  """Record one command and materialize a local graph/viewer after it exits."""
66
85
  if not command:
@@ -79,7 +98,12 @@ def record_to_viewer(
79
98
  fidelity_path = run_dir / "fidelity.json"
80
99
  graph_path = run_dir / "graph.json"
81
100
  viewer_path = run_dir / "viewer.html"
82
- _preflight_artifacts([event_path, fidelity_path, graph_path, viewer_path])
101
+ semantic_path = run_dir / "semantic.jsonl"
102
+ merged_event_path = run_dir / "events.semantic.jsonl"
103
+ artifacts = [event_path, fidelity_path, graph_path, viewer_path]
104
+ if integrate_semantic:
105
+ artifacts.extend([semantic_path, merged_event_path])
106
+ _preflight_artifacts(artifacts)
83
107
 
84
108
  sink = JsonlSink(event_path)
85
109
  resolved = resolve_backend(backend)
@@ -94,14 +118,44 @@ def record_to_viewer(
94
118
  keep_raw_trace=keep_raw_trace,
95
119
  )
96
120
 
97
- return_code = collector.run(command)
121
+ environment_updates = {
122
+ _RUN_ID_ENV: session_id,
123
+ _SESSION_ID_ENV: session_id,
124
+ }
125
+ if integrate_semantic:
126
+ environment_updates[_SEMANTIC_ENV] = str(semantic_path)
127
+ previous_environment = {
128
+ key: os.environ.get(key) for key in environment_updates
129
+ }
130
+ os.environ.update(environment_updates)
131
+ try:
132
+ return_code = collector.run(command)
133
+ finally:
134
+ for key, value in previous_environment.items():
135
+ if value is None:
136
+ os.environ.pop(key, None)
137
+ else:
138
+ os.environ[key] = value
98
139
 
99
140
  validation = validate_event_stream(event_path)
100
141
  if not validation.valid:
101
142
  details = "; ".join(validation.errors)
102
143
  raise RuntimeError(f"recorded event stream failed validation: {details}")
103
144
 
104
- execution_graph = strip_internal_hook_execution_graph(build_execution_graph(event_path))
145
+ materialized_event_path = event_path
146
+ semantic_event_count = 0
147
+ if integrate_semantic and semantic_path.exists() and semantic_path.stat().st_size > 0:
148
+ semantic_merge = merge_semantic_sidecar(
149
+ event_path,
150
+ semantic_path,
151
+ merged_event_path,
152
+ )
153
+ materialized_event_path = merged_event_path
154
+ semantic_event_count = semantic_merge.semantic_event_count
155
+
156
+ execution_graph = strip_internal_hook_execution_graph(
157
+ build_execution_graph(materialized_event_path)
158
+ )
105
159
  write_fidelity_report(execution_graph.fidelity, fidelity_path)
106
160
  write_execution_graph(execution_graph, graph_path)
107
161
  write_graph_html(execution_graph.to_dict(), viewer_path, open_browser=False)
@@ -123,4 +177,7 @@ def record_to_viewer(
123
177
  event_count=execution_graph.event_count,
124
178
  node_count=len(execution_graph.nodes),
125
179
  edge_count=len(execution_graph.edges),
180
+ semantic_sidecar=semantic_path.resolve() if integrate_semantic else None,
181
+ materialized_event_stream=materialized_event_path.resolve(),
182
+ semantic_event_count=semantic_event_count,
126
183
  )
File without changes
File without changes