agentbyte 0.42.4__tar.gz → 0.44.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 (373) hide show
  1. {agentbyte-0.42.4 → agentbyte-0.44.0}/CHANGELOG.md +53 -0
  2. {agentbyte-0.42.4 → agentbyte-0.44.0}/PKG-INFO +2 -2
  3. {agentbyte-0.42.4 → agentbyte-0.44.0}/README.md +1 -1
  4. agentbyte-0.44.0/src/agentbyte/__about__.py +2 -0
  5. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/agents/agent.py +16 -1
  6. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/agents/base.py +18 -0
  7. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/compaction/grouping.py +11 -2
  8. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/__init__.py +2 -0
  9. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/__init__.py +2 -0
  10. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/conformance.py +2 -2
  11. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/models.py +49 -12
  12. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/recorder.py +2 -2
  13. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/transitions.py +13 -8
  14. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/judges/pairwise.py +10 -5
  15. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/splitting.py +3 -3
  16. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/targets/model.py +3 -2
  17. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/targets/runtime.py +4 -3
  18. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/types.py +18 -5
  19. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/workbench/smoke.py +3 -3
  20. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/workbench/verdict.py +27 -16
  21. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/execution_trace/collector.py +24 -21
  22. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/execution_trace/models.py +13 -5
  23. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/_retry_observability.py +10 -2
  24. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/retry_policy.py +7 -3
  25. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/types.py +10 -3
  26. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/middleware/base.py +25 -14
  27. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/spec.py +3 -3
  28. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/orchestration/__init__.py +15 -1
  29. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/orchestration/ai.py +5 -3
  30. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/orchestration/base.py +72 -14
  31. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/orchestration/handoff.py +18 -6
  32. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/orchestration/policies.py +61 -9
  33. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/__init__.py +2 -0
  34. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/orchestration.py +42 -25
  35. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/__init__.py +2 -1
  36. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/composite.py +15 -5
  37. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/tools/research_tools.py +42 -12
  38. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/types.py +23 -4
  39. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/models.py +20 -3
  40. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/__init__.py +4 -0
  41. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/agent.py +9 -8
  42. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/core/checkpoint.py +20 -4
  43. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/core/models.py +18 -10
  44. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/core/runner.py +10 -5
  45. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/core/workflow.py +2 -1
  46. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/schema.py +2 -2
  47. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/steps/step.py +2 -1
  48. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/visualizer.py +20 -9
  49. agentbyte-0.44.0/tests/agents/test_agent_stop_at_tools.py +170 -0
  50. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_orchestrator_synthesis.py +90 -1
  51. agentbyte-0.44.0/tests/test_option_enums.py +206 -0
  52. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/tools/test_research_tools.py +17 -0
  53. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_workflow_reliability.py +2 -1
  54. agentbyte-0.42.4/src/agentbyte/__about__.py +0 -2
  55. {agentbyte-0.42.4 → agentbyte-0.44.0}/.gitignore +0 -0
  56. {agentbyte-0.42.4 → agentbyte-0.44.0}/LICENSE +0 -0
  57. {agentbyte-0.42.4 → agentbyte-0.44.0}/pyproject.toml +0 -0
  58. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/__init__.py +0 -0
  59. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/_optional.py +0 -0
  60. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/agents/__init__.py +0 -0
  61. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/agents/agent_as_tool.py +0 -0
  62. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/agents/embedding_agent.py +0 -0
  63. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/agents/types.py +0 -0
  64. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/cancellation_token.py +0 -0
  65. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/catalog.py +0 -0
  66. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/cli/__init__.py +0 -0
  67. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/cli/__main__.py +0 -0
  68. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/cli/eval_commands.py +0 -0
  69. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/cli/loading.py +0 -0
  70. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/cli/main.py +0 -0
  71. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/compaction/__init__.py +0 -0
  72. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/compaction/counters.py +0 -0
  73. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/compaction/errors.py +0 -0
  74. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/compaction/strategies.py +0 -0
  75. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/component.py +0 -0
  76. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/context.py +0 -0
  77. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/context_providers/__init__.py +0 -0
  78. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/context_providers/base.py +0 -0
  79. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/context_providers/skill_tools.py +0 -0
  80. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/context_providers/skills.py +0 -0
  81. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/__init__.py +0 -0
  82. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/_aiosqlite.py +0 -0
  83. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/base.py +0 -0
  84. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/config.py +0 -0
  85. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/importer.py +0 -0
  86. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/json.py +0 -0
  87. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/loader.py +0 -0
  88. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/publish.py +0 -0
  89. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/publish_config.py +0 -0
  90. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/publishers.py +0 -0
  91. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/s3.py +0 -0
  92. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/sources.py +0 -0
  93. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/sqlite.py +0 -0
  94. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/sqlite_db.py +0 -0
  95. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/write_config.py +0 -0
  96. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/dataset/writers.py +0 -0
  97. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/entity.py +0 -0
  98. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/base.py +0 -0
  99. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/checks/__init__.py +0 -0
  100. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/checks/decorator.py +0 -0
  101. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/checks/keyword.py +0 -0
  102. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/checks/local.py +0 -0
  103. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/checks/process.py +0 -0
  104. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/checks/tool.py +0 -0
  105. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/checks/types.py +0 -0
  106. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/comparison.py +0 -0
  107. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/eval_dataset.py +0 -0
  108. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/errors.py +0 -0
  109. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/sql.py +0 -0
  110. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/sqlite.py +0 -0
  111. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/history/store.py +0 -0
  112. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/judges/__init__.py +0 -0
  113. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/judges/base.py +0 -0
  114. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/judges/composite.py +0 -0
  115. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/judges/llm.py +0 -0
  116. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/judges/reference.py +0 -0
  117. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/judges/trajectory.py +0 -0
  118. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/judges/validation.py +0 -0
  119. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/pairwise.py +0 -0
  120. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/report.py +0 -0
  121. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/runner.py +0 -0
  122. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/targets/__init__.py +0 -0
  123. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/targets/agent.py +0 -0
  124. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/targets/multi_turn.py +0 -0
  125. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/targets/orchestrator.py +0 -0
  126. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/targets/workflow.py +0 -0
  127. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/workbench/__init__.py +0 -0
  128. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/workbench/coordinator.py +0 -0
  129. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/workbench/jobs.py +0 -0
  130. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/workbench/smoke_tasks.json +0 -0
  131. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/eval/workbench/suite.py +0 -0
  132. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/execution_trace/__init__.py +0 -0
  133. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/__init__.py +0 -0
  134. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/auth.py +0 -0
  135. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/azure/__init__.py +0 -0
  136. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/azure/auth.py +0 -0
  137. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/azure/chat.py +0 -0
  138. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/azure/embedding.py +0 -0
  139. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/azure/settings.py +0 -0
  140. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/azure_openai.py +0 -0
  141. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/azure_openai_embedding.py +0 -0
  142. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/base.py +0 -0
  143. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/embeddings_base.py +0 -0
  144. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/openai/__init__.py +0 -0
  145. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/openai/chat.py +0 -0
  146. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/openai/embedding.py +0 -0
  147. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/openai/settings.py +0 -0
  148. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/openai_embedding.py +0 -0
  149. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/pricing.py +0 -0
  150. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/llm/settings.py +0 -0
  151. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/logger.py +0 -0
  152. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/memory/__init__.py +0 -0
  153. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/memory/base.py +0 -0
  154. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/messages.py +0 -0
  155. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/middleware/__init__.py +0 -0
  156. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/middleware/otel.py +0 -0
  157. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/middleware/retry.py +0 -0
  158. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/middleware/sql_usage.py +0 -0
  159. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/middleware/usage_logger.py +0 -0
  160. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/notebook.py +0 -0
  161. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/__init__.py +0 -0
  162. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/base.py +0 -0
  163. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/config.py +0 -0
  164. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/gepa.py +0 -0
  165. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/mipro.py +0 -0
  166. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/pareto.py +0 -0
  167. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/reflective.py +0 -0
  168. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/optim/trace.py +0 -0
  169. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/orchestration/plan.py +0 -0
  170. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/orchestration/round_robin.py +0 -0
  171. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/agents.py +0 -0
  172. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/clients.py +0 -0
  173. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/instruction_registry.py +0 -0
  174. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/instructions/orchestrator.yaml +0 -0
  175. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/instructions/query_rewriter.yaml +0 -0
  176. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/instructions/researcher.yaml +0 -0
  177. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/instructions/reviewer.yaml +0 -0
  178. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/instructions/writer.yaml +0 -0
  179. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/skills/contracts-analyst/SKILL.md +0 -0
  180. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/skills/hr-analyst/SKILL.md +0 -0
  181. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/skills/hr-analyst/resources/departments.md +0 -0
  182. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/skills/hr-analyst/resources/employees.md +0 -0
  183. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/skills/hr-analyst/resources/payroll.md +0 -0
  184. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/streaming.py +0 -0
  185. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/presets/workflow.py +0 -0
  186. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/session_store.py +0 -0
  187. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/skills/__init__.py +0 -0
  188. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/skills/base.py +0 -0
  189. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/skills/resources.py +0 -0
  190. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/skills/scripts.py +0 -0
  191. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/skills/sources.py +0 -0
  192. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/skills/validation.py +0 -0
  193. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/base.py +0 -0
  194. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/cancellation.py +0 -0
  195. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/consecutive_agent.py +0 -0
  196. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/external.py +0 -0
  197. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/function_call.py +0 -0
  198. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/handoff.py +0 -0
  199. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/max_message.py +0 -0
  200. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/predicate.py +0 -0
  201. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/source.py +0 -0
  202. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/text_mention.py +0 -0
  203. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/timeout.py +0 -0
  204. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/termination/token_usage.py +0 -0
  205. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/tools/__init__.py +0 -0
  206. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/tools/base.py +0 -0
  207. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/tools/coding_tools.py +0 -0
  208. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/tools/core_tools.py +0 -0
  209. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/tools/decorator.py +0 -0
  210. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/tools/memory_tool.py +0 -0
  211. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/__init__.py +0 -0
  212. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/discovery.py +0 -0
  213. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/eval_routes.py +0 -0
  214. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/execution.py +0 -0
  215. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/registry.py +0 -0
  216. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/server.py +0 -0
  217. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/session_store.py +0 -0
  218. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/sessions.py +0 -0
  219. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/ui/assets/index-BsS4WYZu.css +0 -0
  220. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/ui/assets/index-tGvO1yue.js +0 -0
  221. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/ui/index.html +0 -0
  222. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/webui/ui/vite.svg +0 -0
  223. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/core/__init__.py +0 -0
  224. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/core/_structure_hash.py +0 -0
  225. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/defaults.py +0 -0
  226. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/errors.py +0 -0
  227. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/loader.py +0 -0
  228. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/schema_utils.py +0 -0
  229. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/sqlite_checkpoint.py +0 -0
  230. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/steps/__init__.py +0 -0
  231. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/steps/agent.py +0 -0
  232. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/steps/echo.py +0 -0
  233. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/steps/function.py +0 -0
  234. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/steps/http.py +0 -0
  235. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/steps/subworkflow.py +0 -0
  236. {agentbyte-0.42.4 → agentbyte-0.44.0}/src/agentbyte/workflow/steps/transform.py +0 -0
  237. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_as_tool.py +0 -0
  238. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_basic.py +0 -0
  239. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_context_providers.py +0 -0
  240. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_error_response.py +0 -0
  241. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_event_types.py +0 -0
  242. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_memory_integration.py +0 -0
  243. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_middleware_integration.py +0 -0
  244. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_response_accessors.py +0 -0
  245. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_retry_middleware.py +0 -0
  246. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_agent_stream_events.py +0 -0
  247. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_embedding_agent.py +0 -0
  248. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_tool_approval.py +0 -0
  249. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_tool_batch_resolution.py +0 -0
  250. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/agents/test_tool_metadata.py +0 -0
  251. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/cli/test_loading.py +0 -0
  252. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/cli/test_registry_check.py +0 -0
  253. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/compaction/test_compaction.py +0 -0
  254. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/context_providers/__init__.py +0 -0
  255. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/context_providers/test_skill_tools.py +0 -0
  256. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/context_providers/test_skills_provider.py +0 -0
  257. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/dataset/fake_s3.py +0 -0
  258. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/dataset/test_dataset_exit.py +0 -0
  259. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/dataset/test_loader.py +0 -0
  260. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/dataset/test_multi_table.py +0 -0
  261. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/dataset/test_publish.py +0 -0
  262. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/dataset/test_sqlite_db.py +0 -0
  263. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_eval_dataset.py +0 -0
  264. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_eval_history.py +0 -0
  265. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_eval_history_backends.py +0 -0
  266. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_eval_jobs.py +0 -0
  267. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_eval_workbench.py +0 -0
  268. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_execution_trajectories.py +0 -0
  269. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_multi_turn.py +0 -0
  270. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_pairwise.py +0 -0
  271. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_phase1_runner_and_targets.py +0 -0
  272. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_phase2_checks_and_reports.py +0 -0
  273. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_score_integrity.py +0 -0
  274. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_splitting.py +0 -0
  275. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/eval/test_types_and_judges.py +0 -0
  276. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/examples/test_compaction_webapp.py +0 -0
  277. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_azure_client.py +0 -0
  278. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_azure_embedding_client.py +0 -0
  279. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_llm_types.py +0 -0
  280. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_openai_client.py +0 -0
  281. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_openai_embedding_client.py +0 -0
  282. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_pricing.py +0 -0
  283. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_retry_observability.py +0 -0
  284. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_retry_policy_api.py +0 -0
  285. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/llm/test_retryable_error_substrings.py +0 -0
  286. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/memory/test_memory.py +0 -0
  287. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/middleware/test_context_compaction.py +0 -0
  288. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/middleware/test_deduplicate_tool_result.py +0 -0
  289. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/middleware/test_middleware_chain.py +0 -0
  290. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/middleware/test_otel.py +0 -0
  291. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/middleware/test_retry_middleware.py +0 -0
  292. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/middleware/test_sql_usage.py +0 -0
  293. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/middleware/test_usage_logger.py +0 -0
  294. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/__init__.py +0 -0
  295. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_base.py +0 -0
  296. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_base_integration.py +0 -0
  297. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_config.py +0 -0
  298. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_description_tunable.py +0 -0
  299. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_gepa.py +0 -0
  300. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_mipro.py +0 -0
  301. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_orchestrator_optim.py +0 -0
  302. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_pareto.py +0 -0
  303. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_reflective.py +0 -0
  304. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_score_integrity.py +0 -0
  305. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_spec.py +0 -0
  306. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/optim/test_trace.py +0 -0
  307. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_ai_orchestrator.py +0 -0
  308. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_base_orchestrator.py +0 -0
  309. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_handoff_orchestrator.py +0 -0
  310. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_history_tool_call_pairing.py +0 -0
  311. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_orchestration_usage_breakdown.py +0 -0
  312. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_orchestrator_agent_contract.py +0 -0
  313. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_orchestrator_finalization.py +0 -0
  314. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_orchestrator_member_events.py +0 -0
  315. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_orchestrator_otel.py +0 -0
  316. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_plan_orchestrator.py +0 -0
  317. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/orchestration/test_round_robin.py +0 -0
  318. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/presets/test_agents.py +0 -0
  319. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/presets/test_clients.py +0 -0
  320. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/presets/test_instruction_registry.py +0 -0
  321. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/presets/test_orchestration.py +0 -0
  322. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/presets/test_streaming.py +0 -0
  323. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/presets/test_workflow.py +0 -0
  324. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/skills/__init__.py +0 -0
  325. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/skills/test_base.py +0 -0
  326. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/skills/test_resources.py +0 -0
  327. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/skills/test_scripts.py +0 -0
  328. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/skills/test_sources.py +0 -0
  329. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_base.py +0 -0
  330. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_cancellation.py +0 -0
  331. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_composite.py +0 -0
  332. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_consecutive_agent.py +0 -0
  333. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_external.py +0 -0
  334. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_function_call.py +0 -0
  335. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_handoff.py +0 -0
  336. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_max_message.py +0 -0
  337. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_predicate.py +0 -0
  338. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_source.py +0 -0
  339. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_text_mention.py +0 -0
  340. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_timeout.py +0 -0
  341. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/termination/test_token_usage.py +0 -0
  342. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_cancellation_token.py +0 -0
  343. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_context.py +0 -0
  344. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_logger.py +0 -0
  345. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_messages.py +0 -0
  346. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_optional_extras.py +0 -0
  347. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_package_api.py +0 -0
  348. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_session_store.py +0 -0
  349. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_types.py +0 -0
  350. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/test_vanilla_chunker.py +0 -0
  351. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/tools/test_coding_tools.py +0 -0
  352. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/tools/test_memory_tool.py +0 -0
  353. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/tools/test_tools.py +0 -0
  354. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/__init__.py +0 -0
  355. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/helpers.py +0 -0
  356. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/test_eval_routes.py +0 -0
  357. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/test_execution.py +0 -0
  358. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/test_package_api.py +0 -0
  359. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/test_registry.py +0 -0
  360. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/test_server.py +0 -0
  361. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/test_sessions.py +0 -0
  362. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/webui/test_workflow_streaming.py +0 -0
  363. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/recovery_worker.py +0 -0
  364. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_agent_step_imports.py +0 -0
  365. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_checkpoint.py +0 -0
  366. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_subworkflow_step.py +0 -0
  367. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_workflow_agent.py +0 -0
  368. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_workflow_class.py +0 -0
  369. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_workflow_models.py +0 -0
  370. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_workflow_runner.py +0 -0
  371. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_workflow_schema.py +0 -0
  372. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_workflow_steps.py +0 -0
  373. {agentbyte-0.42.4 → agentbyte-0.44.0}/tests/workflow/test_workflow_visualizer.py +0 -0
@@ -6,6 +6,59 @@ The format follows Keep a Changelog principles and semantic versioning.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.44.0] - 2026-10-05
10
+
11
+ ### Changed
12
+
13
+ - Fixed string option sets are `StrEnum`s (spec 0067). Plain strings are still accepted
14
+ everywhere (`AgentHistoryPolicy(window="run")` keeps working) and serialize to the same values.
15
+ New enums: `HistoryWindow`, `HistoryFormat`, `SelectorWindow`, `SelectorFormat`, `StripMode`,
16
+ `FallbackStrategy`, `TurnKind` (`agentbyte.orchestration`); `OrchestratorPattern`
17
+ (`agentbyte.presets`); `CompositeMode` (`agentbyte.termination`); `PairwiseWinner`
18
+ (`agentbyte.eval`); `TaskType` (`agentbyte.eval.history`); `CheckpointType`, `WorkflowMemoryMode`
19
+ (`agentbyte.workflow`); `GraphView`, `EntitySource`, `EntityType`, `SafeSearch`, `PageFormat`,
20
+ `RetrySequenceOutcome`, `RetryAttemptOutcome`. The literal aliases `ScoringStatus`, `RunStatus`,
21
+ `ItemState`, `EvidenceStatus`, `ItemOutcome`, `ExecutionStatus`, `PricingStatus`, `GroupKind`
22
+ are now `StrEnum` classes with the same names (iterate them instead of `typing.get_args`).
23
+ - The 16 `class X(str, Enum)` classes (workflow statuses and modes, `OperationType`, optim
24
+ `Operation`/`ProposalMode`, eval splitting) are `StrEnum`: `str(member)` and f-strings print the
25
+ value (`"completed"`) instead of `"StepStatus.COMPLETED"`.
26
+ - Unknown values for `HandoffOrchestrator(fallback_strategy=...)`, `CompositeTermination(mode=...)`,
27
+ `WorkflowAgent(memory_mode=...)`, `WorkflowVisualizer` `view` and the research tools'
28
+ `default_safe_search` raise `ValueError` instead of silently using a default branch.
29
+ - `WebFetchTool` / `ExtractTextTool` return a failed `ToolResult` listing the valid values for an
30
+ unknown model-supplied `output_format` (previously silently plain text).
31
+ - `SuiteItemVerdict.state/scoring_status/execution_status/evidence_status`,
32
+ `EvalItemRecord.execution_status` and `WorkflowCheckpoint.checkpoint_type` are typed with their
33
+ enums instead of bare `str`.
34
+
35
+ ### Fixed
36
+
37
+ - OTel span-name fallback rendered `"OperationType.MEMORY_ACCESS <agent>"`, and the logger printed
38
+ workflow event types as `"WorkflowEventType.…"`; both print the value now.
39
+ - `copy_tool_metadata` accepts `StrEnum` members (stored as their plain value).
40
+
41
+ ## [0.43.0] - 2026-10-05
42
+
43
+ ### Added
44
+
45
+ - Agents: `stop_at_tools=[...]` ends the run with `finish_reason="tool_executed"`, without a
46
+ final model call, once a call to a named tool succeeds. Multi-step tool discovery and retries
47
+ after a failed call still run; a failed stop tool does not stop the run; the budget-exhaustion
48
+ finalization still applies. Names are validated against the agent's tools at construction.
49
+ Meant for team specialists whose raw tool results a synthesizer turns into the answer.
50
+ - Orchestration: `AgentHistoryPolicy(window="run")` sends this run's messages in full and
51
+ condenses earlier session turns to each user message plus the answer that closed it (no prior
52
+ tool calls, tool results, or worker notes). Use it as `FinalResultPolicy.synthesis_history` so a
53
+ synthesizer's input stays bounded across follow-up turns without losing their context.
54
+ - Orchestration: workers that end with `max_iterations` / `max_iterations_finalized` are reported to
55
+ the synthesizer as a separate completion fact (partial findings), next to error turns.
56
+
57
+ ### Fixed
58
+
59
+ - Design guide: `summarize_tool_result` was documented as a summarization knob; it actually ends
60
+ the run after the first tool batch. The agent topic now describes it and `stop_at_tools`.
61
+
9
62
  ## [0.42.4] - 2026-10-05
10
63
 
11
64
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentbyte
3
- Version: 0.42.4
3
+ Version: 0.44.0
4
4
  Summary: A toolkit for designing multiagent systems
5
5
  Author-email: MrDataPsycho <mr.data.psycho@gmail.com>
6
6
  License-Expression: LicenseRef-Proprietary
@@ -77,7 +77,7 @@ Description-Content-Type: text/markdown
77
77
 
78
78
  Agentbyte is an observability-first agentic AI framework for building and studying multiagent systems with a learning-first, implementation-oriented workflow.
79
79
 
80
- Current release: **0.42.4**
80
+ Current release: **0.44.0**
81
81
 
82
82
  ## Building an Agent
83
83
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Agentbyte is an observability-first agentic AI framework for building and studying multiagent systems with a learning-first, implementation-oriented workflow.
4
4
 
5
- Current release: **0.42.4**
5
+ Current release: **0.44.0**
6
6
 
7
7
  ## Building an Agent
8
8
 
@@ -0,0 +1,2 @@
1
+ __version__ = "0.44.0"
2
+ VERSION = __version__
@@ -372,6 +372,14 @@ class Agent(BaseAgent):
372
372
  and working_context.get_approval_response(tool_call.call_id) is None
373
373
  )
374
374
 
375
+ def _is_stop_tool_success(self, item: object) -> bool:
376
+ """Whether *item* is a successful result of a ``stop_at_tools`` tool."""
377
+ return (
378
+ isinstance(item, ToolMessage)
379
+ and item.success
380
+ and item.tool_name in self.stop_at_tools
381
+ )
382
+
375
383
  async def _resolve_tool_batch(
376
384
  self,
377
385
  working_context: AgentContext,
@@ -560,6 +568,7 @@ class Agent(BaseAgent):
560
568
  # not-yet-run siblings, in order) before asking the model again.
561
569
  if self._unresolved_tail_calls(working_context):
562
570
  outcome: dict[str, int | bool] = {"executed": 0, "paused": False}
571
+ stop_tool_succeeded = False
563
572
  async for item in self._resolve_tool_batch(
564
573
  working_context,
565
574
  cancellation_token,
@@ -567,11 +576,15 @@ class Agent(BaseAgent):
567
576
  provider_tools,
568
577
  outcome,
569
578
  ):
579
+ stop_tool_succeeded |= self._is_stop_tool_success(item)
570
580
  yield item
571
581
  tool_calls += int(outcome["executed"])
572
582
  if outcome["paused"]:
573
583
  finish_reason = "approval_needed"
574
584
  break
585
+ if stop_tool_succeeded:
586
+ finish_reason = "tool_executed"
587
+ break
575
588
 
576
589
  llm_messages = await self._prepare_llm_messages([], working_context, extra_instructions=extra_instructions)
577
590
  if self.memory is not None:
@@ -773,6 +786,7 @@ class Agent(BaseAgent):
773
786
  break
774
787
 
775
788
  outcome = {"executed": 0, "paused": False}
789
+ stop_tool_succeeded = False
776
790
  async for item in self._resolve_tool_batch(
777
791
  working_context,
778
792
  cancellation_token,
@@ -780,13 +794,14 @@ class Agent(BaseAgent):
780
794
  provider_tools,
781
795
  outcome,
782
796
  ):
797
+ stop_tool_succeeded |= self._is_stop_tool_success(item)
783
798
  yield item
784
799
  tool_calls += int(outcome["executed"])
785
800
  if outcome["paused"]:
786
801
  finish_reason = "approval_needed"
787
802
  break
788
803
 
789
- if not self.summarize_tool_result:
804
+ if stop_tool_succeeded or not self.summarize_tool_result:
790
805
  finish_reason = "tool_executed"
791
806
  break
792
807
 
@@ -59,6 +59,7 @@ class BaseAgent(ABC):
59
59
  required_tools: Optional[List[str]] = None,
60
60
  example_tasks: Optional[List[str]] = None,
61
61
  context_providers: Optional[List[ContextProvider]] = None,
62
+ stop_at_tools: Optional[List[str]] = None,
62
63
  **kwargs: Any,
63
64
  ) -> None:
64
65
  """Initialize the agent.
@@ -69,6 +70,15 @@ class BaseAgent(ABC):
69
70
  ``max_iterations >= 2``: with ``max_iterations=1`` the only turn keeps
70
71
  its tools, so a run that calls a tool ends with
71
72
  ``finish_reason="max_iterations"`` and no final answer.
73
+
74
+ ``summarize_tool_result=False`` ends the run right after the first tool
75
+ batch executes, with no further model call
76
+ (``finish_reason="tool_executed"``). ``stop_at_tools`` is the selective
77
+ form: the agent keeps its tool loop (multi-step discovery, retries after a
78
+ failed call) and ends the same way once a call to one of the named tools
79
+ succeeds. The names must be the agent's own tools. Use either when another
80
+ component, such as an orchestrator's synthesizer, writes the answer from
81
+ the raw tool results.
72
82
  """
73
83
  self.name = name
74
84
  self.description = description
@@ -84,6 +94,7 @@ class BaseAgent(ABC):
84
94
  self.required_tools = required_tools or []
85
95
  self.example_tasks = example_tasks or []
86
96
  self.context_providers: List[ContextProvider] = list(context_providers) if context_providers else []
97
+ self.stop_at_tools: List[str] = list(stop_at_tools) if stop_at_tools else []
87
98
  self.extra_config = kwargs
88
99
 
89
100
  self._validate_configuration()
@@ -100,6 +111,13 @@ class BaseAgent(ABC):
100
111
  raise AgentConfigurationError("Model client is required")
101
112
  if self.max_iterations <= 0:
102
113
  raise AgentConfigurationError("max_iterations must be > 0")
114
+ tool_names = {tool.name for tool in self.tools}
115
+ unknown = [name for name in self.stop_at_tools if name not in tool_names]
116
+ if unknown:
117
+ raise AgentConfigurationError(
118
+ f"stop_at_tools names unknown tools {unknown}; "
119
+ f"available: {sorted(tool_names)}"
120
+ )
103
121
 
104
122
  def _process_tools(self, tools: List[Union[BaseTool, Callable]]) -> List[BaseTool]:
105
123
  """Normalize mixed tool list into BaseTool instances."""
@@ -3,7 +3,8 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from dataclasses import dataclass
6
- from typing import Any, Literal
6
+ from enum import StrEnum
7
+ from typing import Any
7
8
 
8
9
  from agentbyte.compaction.errors import PendingToolExchangeError, ToolExchangeError
9
10
  from agentbyte.messages import (
@@ -14,7 +15,15 @@ from agentbyte.messages import (
14
15
  UserMessage,
15
16
  )
16
17
 
17
- GroupKind = Literal["system", "user", "assistant", "tool_exchange", "opaque"]
18
+
19
+ class GroupKind(StrEnum):
20
+ """What an indivisible message group contains."""
21
+
22
+ SYSTEM = "system"
23
+ USER = "user"
24
+ ASSISTANT = "assistant"
25
+ TOOL_EXCHANGE = "tool_exchange"
26
+ OPAQUE = "opaque"
18
27
 
19
28
 
20
29
  @dataclass(frozen=True)
@@ -58,6 +58,7 @@ from .types import (
58
58
  MultiTurnEvalTask,
59
59
  WorkflowEvalTask,
60
60
  PairwiseResult,
61
+ PairwiseWinner,
61
62
  )
62
63
 
63
64
  __all__ = [
@@ -76,6 +77,7 @@ __all__ = [
76
77
  "BaseEvalRunner",
77
78
  "JudgeScoringError",
78
79
  "ScoringStatus",
80
+ "PairwiseWinner",
79
81
  "ExactMatchJudge",
80
82
  "ContainsJudge",
81
83
  "FuzzyMatchJudge",
@@ -30,6 +30,7 @@ from .models import (
30
30
  Redactor,
31
31
  RunStatus,
32
32
  StructuredPayload,
33
+ TaskType,
33
34
  )
34
35
  from .recorder import EvalRunRecorder
35
36
  from .sqlite import SQLiteEvalRunStore
@@ -71,5 +72,6 @@ __all__ = [
71
72
  "SQLiteEvalRunStore",
72
73
  "SqlEvalRunStore",
73
74
  "StructuredPayload",
75
+ "TaskType",
74
76
  "history_metadata",
75
77
  ]
@@ -22,7 +22,7 @@ from pydantic import BaseModel
22
22
 
23
23
  from agentbyte.eval.base import BaseEvalJudge, BaseEvalTarget, JudgeScoringError
24
24
  from agentbyte.eval.runner import EvalRunner
25
- from agentbyte.eval.types import EvalScore, EvalTask, EvalTrajectory, WorkflowEvalTask
25
+ from agentbyte.eval.types import EvalScore, EvalTask, EvalTrajectory, ScoringStatus, WorkflowEvalTask
26
26
  from agentbyte.execution_trace.models import ExecutionEvent, ExecutionSpan, ExecutionTrace
27
27
  from agentbyte.messages import AssistantMessage, UserMessage, Usage
28
28
 
@@ -152,7 +152,7 @@ async def check_lifecycle_updates_counters_and_revisions(store: EvalRunStore) ->
152
152
  assert (saved.state, saved.revision, saved.overall) == ("finished", 4, 6.0)
153
153
  assert saved.started_at == running.started_at and saved.finished_at is not None
154
154
  failed = await store.save_item(_outcome(run, 1).model_copy(update={
155
- "scoring_status": "failed", "overall": None, "failure_reason": "target_error",
155
+ "scoring_status": ScoringStatus.FAILED, "overall": None, "failure_reason": "target_error",
156
156
  }))
157
157
  assert failed.revision == 5
158
158
 
@@ -13,12 +13,13 @@ import re
13
13
  from collections.abc import Callable
14
14
  from datetime import date, datetime, timezone
15
15
  from enum import StrEnum
16
- from typing import Any, Literal
16
+ from typing import Any
17
17
  from uuid import uuid4
18
18
 
19
19
  from pydantic import BaseModel, ConfigDict, Field
20
20
 
21
21
  from agentbyte.eval.types import EvalScore, EvalTask, MultiTurnEvalTask, ScoringStatus, WorkflowEvalTask
22
+ from agentbyte.execution_trace.models import ExecutionStatus
22
23
  from agentbyte.messages import Usage
23
24
 
24
25
  from .errors import EvalSchemaVersionError, EvalSerializationError
@@ -29,8 +30,26 @@ SCHEMA_VERSION = 1
29
30
  EVIDENCE_VERSION = 1
30
31
  """Version of the serialized full-capture evidence envelope."""
31
32
 
32
- RunStatus = Literal["queued", "running", "completed", "failed", "cancelled", "interrupted"]
33
- ItemState = Literal["pending", "running", "finished", "cancelled", "not_started"]
33
+
34
+ class RunStatus(StrEnum):
35
+ """Lifecycle status of a recorded evaluation run."""
36
+
37
+ QUEUED = "queued"
38
+ RUNNING = "running"
39
+ COMPLETED = "completed"
40
+ FAILED = "failed"
41
+ CANCELLED = "cancelled"
42
+ INTERRUPTED = "interrupted"
43
+
44
+
45
+ class ItemState(StrEnum):
46
+ """Lifecycle state of one recorded evaluation item."""
47
+
48
+ PENDING = "pending"
49
+ RUNNING = "running"
50
+ FINISHED = "finished"
51
+ CANCELLED = "cancelled"
52
+ NOT_STARTED = "not_started"
34
53
 
35
54
 
36
55
  class CaptureMode(StrEnum):
@@ -45,11 +64,29 @@ class CaptureMode(StrEnum):
45
64
  FULL = "full"
46
65
 
47
66
 
48
- EvidenceStatus = Literal["not_captured", "captured", "redacted", "unavailable"]
49
- TaskType = Literal["task", "workflow", "multi_turn"]
67
+ class EvidenceStatus(StrEnum):
68
+ """Whether an item's full evidence is stored."""
69
+
70
+ NOT_CAPTURED = "not_captured"
71
+ CAPTURED = "captured"
72
+ REDACTED = "redacted"
73
+ UNAVAILABLE = "unavailable"
74
+
75
+
76
+ class TaskType(StrEnum):
77
+ """Kind of evaluation task an item ran."""
78
+
79
+ TASK = "task"
80
+ WORKFLOW = "workflow"
81
+ MULTI_TURN = "multi_turn"
82
+
50
83
 
51
- ACTIVE_RUN_STATUSES: tuple[RunStatus, ...] = ("queued", "running")
52
- TERMINAL_ITEM_STATES: tuple[ItemState, ...] = ("finished", "cancelled", "not_started")
84
+ ACTIVE_RUN_STATUSES: tuple[RunStatus, ...] = (RunStatus.QUEUED, RunStatus.RUNNING)
85
+ TERMINAL_ITEM_STATES: tuple[ItemState, ...] = (
86
+ ItemState.FINISHED,
87
+ ItemState.CANCELLED,
88
+ ItemState.NOT_STARTED,
89
+ )
53
90
 
54
91
  Redactor = Callable[[EvalScore], EvalScore]
55
92
 
@@ -83,7 +120,7 @@ class EvalRunRecord(BaseModel):
83
120
 
84
121
  id: str = Field(default_factory=lambda: str(uuid4()))
85
122
  schema_version: int = SCHEMA_VERSION
86
- status: RunStatus = "queued"
123
+ status: RunStatus = RunStatus.QUEUED
87
124
  revision: int = 0
88
125
  capture: CaptureMode = CaptureMode.SUMMARY
89
126
  dataset_id: str
@@ -134,8 +171,8 @@ class EvalItemRecord(BaseModel):
134
171
  run_id: str
135
172
  item_index: int
136
173
  task_name: str
137
- task_type: TaskType = "task"
138
- state: ItemState = "pending"
174
+ task_type: TaskType = TaskType.TASK
175
+ state: ItemState = ItemState.PENDING
139
176
  revision: int = 0
140
177
  started_at: datetime | None = None
141
178
  finished_at: datetime | None = None
@@ -145,10 +182,10 @@ class EvalItemRecord(BaseModel):
145
182
  failure_reason: str | None = None
146
183
  error_type: str | None = None
147
184
  success: bool | None = None
148
- execution_status: str | None = None
185
+ execution_status: ExecutionStatus | None = None
149
186
  usage: Usage | None = None
150
187
  trace_id: str | None = None
151
- evidence_status: EvidenceStatus = "not_captured"
188
+ evidence_status: EvidenceStatus = EvidenceStatus.NOT_CAPTURED
152
189
  evidence: EvalScore | None = None
153
190
 
154
191
  @property
@@ -318,9 +318,9 @@ class EvalRunRecorder:
318
318
 
319
319
  def _outcome(self, run_id: str, index: int, task: EvalTask, score: EvalScore) -> EvalItemRecord:
320
320
  evidence: EvalScore | None = None
321
- evidence_status: EvidenceStatus = "not_captured"
321
+ evidence_status: EvidenceStatus = EvidenceStatus.NOT_CAPTURED
322
322
  if self.capture == CaptureMode.FULL:
323
- evidence, evidence_status = score, "captured"
323
+ evidence, evidence_status = score, EvidenceStatus.CAPTURED
324
324
  if self.redact is not None:
325
325
  try:
326
326
  evidence = self.redact(score)
@@ -10,9 +10,14 @@ from __future__ import annotations
10
10
  from typing import Any
11
11
 
12
12
  from .errors import EvalHistoryConflictError, EvalQueueFullError
13
- from .models import EvalItemRecord, EvalRunRecord, RunStatus, utc_now
13
+ from .models import EvalItemRecord, EvalRunRecord, ItemState, RunStatus, utc_now
14
14
 
15
- FINAL_RUN_STATUSES: tuple[RunStatus, ...] = ("completed", "failed", "cancelled", "interrupted")
15
+ FINAL_RUN_STATUSES: tuple[RunStatus, ...] = (
16
+ RunStatus.COMPLETED,
17
+ RunStatus.FAILED,
18
+ RunStatus.CANCELLED,
19
+ RunStatus.INTERRUPTED,
20
+ )
16
21
 
17
22
  def admitted_duplicate(existing: EvalRunRecord, run: EvalRunRecord, planned: int) -> EvalRunRecord:
18
23
  same = (
@@ -44,7 +49,7 @@ def admit(run: EvalRunRecord, items: list[EvalItemRecord]) -> tuple[EvalRunRecor
44
49
  raise ValueError("items must be indexed 0..n-1 in order")
45
50
  if any(item.run_id != run.id or item.state != "pending" for item in items):
46
51
  raise ValueError("items must be pending and belong to the run")
47
- admitted = run.model_copy(update={"status": "queued", "revision": 1, "planned_count": len(items)})
52
+ admitted = run.model_copy(update={"status": RunStatus.QUEUED, "revision": 1, "planned_count": len(items)})
48
53
  return admitted, [item.model_copy(update={"revision": 1}) for item in items]
49
54
 
50
55
 
@@ -52,7 +57,7 @@ def start(run: EvalRunRecord, worker_id: str | None) -> EvalRunRecord:
52
57
  if run.status != "queued":
53
58
  raise EvalHistoryConflictError(f"Run {run.id} is {run.status}, not queued")
54
59
  return run.model_copy(update={
55
- "status": "running", "revision": run.revision + 1,
60
+ "status": RunStatus.RUNNING, "revision": run.revision + 1,
56
61
  "started_at": utc_now(), "worker_id": worker_id,
57
62
  })
58
63
 
@@ -65,7 +70,7 @@ def item_running(run: EvalRunRecord, item: EvalItemRecord) -> tuple[EvalRunRecor
65
70
  revision = run.revision + 1
66
71
  return (
67
72
  run.model_copy(update={"revision": revision}),
68
- item.model_copy(update={"state": "running", "revision": revision, "started_at": utc_now()}),
73
+ item.model_copy(update={"state": ItemState.RUNNING, "revision": revision, "started_at": utc_now()}),
69
74
  )
70
75
 
71
76
 
@@ -125,14 +130,14 @@ def finish(
125
130
  closed: list[EvalItemRecord] = []
126
131
  for item in open_items:
127
132
  if item.state == "pending":
128
- update: dict[str, Any] = {"state": "not_started"}
133
+ update: dict[str, Any] = {"state": ItemState.NOT_STARTED}
129
134
  else:
130
- update = {"state": "cancelled", "failure_reason": "cancelled", "finished_at": now}
135
+ update = {"state": ItemState.CANCELLED, "failure_reason": "cancelled", "finished_at": now}
131
136
  closed.append(item.model_copy(update={**update, "revision": revision}))
132
137
  updated = run.model_copy(update={"revision": revision})
133
138
  for item in closed:
134
139
  updated = updated.model_copy(update=_count(updated, item))
135
- return updated.model_copy(update={"status": status, "finished_at": now, "error": error}), closed
140
+ return updated.model_copy(update={"status": RunStatus(status), "finished_at": now, "error": error}), closed
136
141
 
137
142
 
138
143
  def check_same_evidence(item: EvalItemRecord, stored: str | None, new: str | None) -> None:
@@ -21,6 +21,7 @@ from agentbyte.eval.types import (
21
21
  EvalScore,
22
22
  EvalTrajectory,
23
23
  PairwiseResult,
24
+ PairwiseWinner,
24
25
  )
25
26
 
26
27
 
@@ -129,16 +130,20 @@ class PairwiseJudge(BaseEvalJudge):
129
130
  parsed = self._parse_response(result.structured_output, result.message.content)
130
131
  except (ValidationError, json.JSONDecodeError, TypeError) as exc:
131
132
  raise JudgeScoringError("invalid_response", "Malformed pairwise response") from exc
132
- winner = parsed.winner.strip().lower()
133
- if winner not in ("a", "b", "tie"):
134
- raise JudgeScoringError("invalid_response", f"Unknown winner: {parsed.winner!r}")
133
+ # The model's raw label stays a str until normalized and validated here.
134
+ try:
135
+ winner = PairwiseWinner(parsed.winner.strip().lower())
136
+ except ValueError:
137
+ raise JudgeScoringError(
138
+ "invalid_response", f"Unknown winner: {parsed.winner!r}"
139
+ ) from None
135
140
  margin = float(parsed.margin)
136
141
  if not math.isfinite(margin) or not 0.0 <= margin <= 1.0:
137
142
  raise JudgeScoringError("invalid_score", f"Margin outside 0-1: {parsed.margin!r}")
138
143
  return PairwiseResult(
139
144
  task=trajectory_a.task,
140
- winner=winner, # type: ignore[arg-type]
141
- margin=0.0 if winner == "tie" else margin,
145
+ winner=winner,
146
+ margin=0.0 if winner == PairwiseWinner.TIE else margin,
142
147
  reasoning=parsed.reasoning,
143
148
  trajectory_a=trajectory_a,
144
149
  trajectory_b=trajectory_b,
@@ -8,7 +8,7 @@ import math
8
8
  from abc import ABC, abstractmethod
9
9
  from collections import Counter
10
10
  from collections.abc import Sequence
11
- from enum import Enum
11
+ from enum import StrEnum
12
12
  from typing import Any
13
13
 
14
14
  from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
@@ -16,14 +16,14 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_valida
16
16
  from agentbyte.eval.types import EvalTask
17
17
 
18
18
 
19
- class EvalSplitStrategy(str, Enum):
19
+ class EvalSplitStrategy(StrEnum):
20
20
  """Supported holdout partition layouts."""
21
21
 
22
22
  TRAIN_TEST = "train_test"
23
23
  TRAIN_VALIDATION_TEST = "train_validation_test"
24
24
 
25
25
 
26
- class EvalPartition(str, Enum):
26
+ class EvalPartition(StrEnum):
27
27
  """Named partitions produced by an eval split."""
28
28
 
29
29
  TRAIN = "train"
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import time
6
6
 
7
7
  from agentbyte.cancellation_token import CancellationToken
8
+ from agentbyte.execution_trace import ExecutionStatus
8
9
  from agentbyte.llm import BaseChatCompletionClient
9
10
  from agentbyte.messages import SystemMessage, Usage, UserMessage
10
11
 
@@ -36,7 +37,7 @@ class ModelEvalTarget(BaseEvalTarget):
36
37
  task,
37
38
  start_time,
38
39
  error="Execution cancelled before model call",
39
- status="cancelled",
40
+ status=ExecutionStatus.CANCELLED,
40
41
  )
41
42
 
42
43
  messages = []
@@ -70,7 +71,7 @@ class ModelEvalTarget(BaseEvalTarget):
70
71
  start_time: float,
71
72
  *,
72
73
  error: str,
73
- status: str = "failed",
74
+ status: ExecutionStatus = ExecutionStatus.FAILED,
74
75
  ) -> EvalTrajectory:
75
76
  elapsed_ms = int((time.perf_counter() - start_time) * 1000)
76
77
  return EvalTrajectory(
@@ -9,7 +9,7 @@ from collections.abc import AsyncIterator
9
9
  from typing import Any
10
10
  from weakref import WeakKeyDictionary
11
11
 
12
- from agentbyte.execution_trace import TraceCollector
12
+ from agentbyte.execution_trace import ExecutionStatus, TraceCollector
13
13
  from agentbyte.messages import Usage
14
14
  from agentbyte.eval.types import EvalTask, EvalTrajectory
15
15
 
@@ -34,18 +34,19 @@ def build_trajectory(
34
34
  started: float,
35
35
  *,
36
36
  messages: list,
37
- status: str,
37
+ status: ExecutionStatus | str,
38
38
  error: str | None = None,
39
39
  usage: Usage | None = None,
40
40
  **metadata: Any,
41
41
  ) -> EvalTrajectory:
42
+ status = ExecutionStatus(status)
42
43
  elapsed = int((time.perf_counter() - started) * 1000)
43
44
  total = usage if usage is not None else collector.trace.aggregate_usage()
44
45
  total = total.model_copy(update={"duration_ms": elapsed})
45
46
  return EvalTrajectory(
46
47
  task=task,
47
48
  messages=messages,
48
- success=status == "completed",
49
+ success=status == ExecutionStatus.COMPLETED,
49
50
  error=error,
50
51
  usage=total,
51
52
  trace=collector.trace,
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import math
6
6
  from enum import StrEnum
7
- from typing import Any, Literal
7
+ from typing import Any
8
8
 
9
9
  from pydantic import (
10
10
  BaseModel,
@@ -130,7 +130,20 @@ class EvalTrajectory(BaseModel):
130
130
  return value
131
131
 
132
132
 
133
- ScoringStatus = Literal["scored", "failed", "cancelled"]
133
+ class ScoringStatus(StrEnum):
134
+ """Whether a score (or comparison) is valid measured evidence."""
135
+
136
+ SCORED = "scored"
137
+ FAILED = "failed"
138
+ CANCELLED = "cancelled"
139
+
140
+
141
+ class PairwiseWinner(StrEnum):
142
+ """Which trajectory a pairwise comparison preferred."""
143
+
144
+ A = "a"
145
+ B = "b"
146
+ TIE = "tie"
134
147
 
135
148
 
136
149
  # Markers written by pre-0055 judges on placeholder scores. Such records are
@@ -158,7 +171,7 @@ class EvalScore(BaseModel):
158
171
  description="Overall score on a 0-10 scale; None when not scored",
159
172
  )
160
173
  scoring_status: ScoringStatus = Field(
161
- default="scored",
174
+ default=ScoringStatus.SCORED,
162
175
  description="Whether this outcome is a valid measurement",
163
176
  )
164
177
  failure_reason: str | None = Field(
@@ -251,14 +264,14 @@ class PairwiseResult(BaseModel):
251
264
 
252
265
  task: EvalTask = Field(..., description="Task both trajectories were evaluated on")
253
266
  comparison_status: ScoringStatus = Field(
254
- default="scored",
267
+ default=ScoringStatus.SCORED,
255
268
  description="Whether this comparison is a valid measured preference",
256
269
  )
257
270
  failure_reason: str | None = Field(
258
271
  default=None,
259
272
  description="Safe reason code for failed or cancelled comparisons",
260
273
  )
261
- winner: Literal["a", "b", "tie"] | None = Field(
274
+ winner: PairwiseWinner | None = Field(
262
275
  default=None,
263
276
  description="Which trajectory was better, or tie; None when not compared",
264
277
  )
@@ -18,7 +18,7 @@ from agentbyte.cancellation_token import CancellationToken
18
18
  from agentbyte.eval.base import BaseEvalTarget
19
19
  from agentbyte.eval.judges import ContainsJudge
20
20
  from agentbyte.eval.types import EvalTask, EvalTrajectory
21
- from agentbyte.execution_trace.models import ExecutionSpan, ExecutionTrace
21
+ from agentbyte.execution_trace.models import ExecutionSpan, ExecutionStatus, ExecutionTrace
22
22
  from agentbyte.messages import AssistantMessage, UserMessage
23
23
 
24
24
  from .suite import EvalSuite, EvalSuiteRegistry
@@ -40,11 +40,11 @@ class ArithmeticTarget(BaseEvalTarget):
40
40
  span = ExecutionSpan(kind="agent", name=self.name, input=task.input)
41
41
  match = _QUESTION.search(task.input)
42
42
  if match is None:
43
- answer, status, error = None, "failed", "unsupported_question"
43
+ answer, status, error = None, ExecutionStatus.FAILED, "unsupported_question"
44
44
  else:
45
45
  left, symbol, right = match.groups()
46
46
  answer = str(_OPERATORS[symbol](int(left), int(right)))
47
- status, error = "completed", None
47
+ status, error = ExecutionStatus.COMPLETED, None
48
48
  span = span.model_copy(update={"status": status, "output": answer})
49
49
  messages = [UserMessage(content=task.input, source="user")]
50
50
  if answer is not None: