agentbyte 0.34.0__tar.gz → 0.38.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 (364) hide show
  1. {agentbyte-0.34.0 → agentbyte-0.38.0}/CHANGELOG.md +89 -0
  2. {agentbyte-0.34.0 → agentbyte-0.38.0}/PKG-INFO +3 -3
  3. {agentbyte-0.34.0 → agentbyte-0.38.0}/README.md +2 -2
  4. agentbyte-0.38.0/src/agentbyte/__about__.py +2 -0
  5. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/__init__.py +2 -0
  6. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/base.py +51 -17
  7. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/decorator.py +6 -3
  8. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/keyword.py +8 -3
  9. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/models.py +16 -2
  10. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/recorder.py +9 -5
  11. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/composite.py +2 -2
  12. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/llm.py +4 -2
  13. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/pairwise.py +10 -2
  14. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/reference.py +25 -7
  15. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/trajectory.py +7 -2
  16. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/types.py +27 -6
  17. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/coordinator.py +8 -5
  18. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/verdict.py +2 -2
  19. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/__init__.py +16 -1
  20. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/base.py +31 -14
  21. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/config.py +82 -2
  22. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/reflective.py +3 -3
  23. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/spec.py +59 -1
  24. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/eval_routes.py +3 -3
  25. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_history.py +42 -0
  26. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_types_and_judges.py +148 -0
  27. agentbyte-0.38.0/tests/optim/test_orchestrator_optim.py +288 -0
  28. agentbyte-0.34.0/src/agentbyte/__about__.py +0 -2
  29. {agentbyte-0.34.0 → agentbyte-0.38.0}/.gitignore +0 -0
  30. {agentbyte-0.34.0 → agentbyte-0.38.0}/LICENSE +0 -0
  31. {agentbyte-0.34.0 → agentbyte-0.38.0}/pyproject.toml +0 -0
  32. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/__init__.py +0 -0
  33. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/_optional.py +0 -0
  34. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/__init__.py +0 -0
  35. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/agent.py +0 -0
  36. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/agent_as_tool.py +0 -0
  37. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/base.py +0 -0
  38. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/embedding_agent.py +0 -0
  39. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/types.py +0 -0
  40. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cancellation_token.py +0 -0
  41. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/catalog.py +0 -0
  42. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/__init__.py +0 -0
  43. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/__main__.py +0 -0
  44. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/eval_commands.py +0 -0
  45. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/loading.py +0 -0
  46. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/main.py +0 -0
  47. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/__init__.py +0 -0
  48. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/counters.py +0 -0
  49. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/errors.py +0 -0
  50. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/grouping.py +0 -0
  51. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/strategies.py +0 -0
  52. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/component.py +0 -0
  53. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context.py +0 -0
  54. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context_providers/__init__.py +0 -0
  55. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context_providers/base.py +0 -0
  56. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context_providers/skill_tools.py +0 -0
  57. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context_providers/skills.py +0 -0
  58. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/__init__.py +0 -0
  59. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/_aiosqlite.py +0 -0
  60. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/base.py +0 -0
  61. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/config.py +0 -0
  62. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/importer.py +0 -0
  63. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/json.py +0 -0
  64. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/loader.py +0 -0
  65. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/publish.py +0 -0
  66. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/publish_config.py +0 -0
  67. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/publishers.py +0 -0
  68. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/s3.py +0 -0
  69. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/sources.py +0 -0
  70. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/sqlite.py +0 -0
  71. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/sqlite_db.py +0 -0
  72. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/write_config.py +0 -0
  73. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/writers.py +0 -0
  74. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/entity.py +0 -0
  75. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/__init__.py +0 -0
  76. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/local.py +0 -0
  77. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/process.py +0 -0
  78. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/tool.py +0 -0
  79. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/types.py +0 -0
  80. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/comparison.py +0 -0
  81. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/eval_dataset.py +0 -0
  82. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/__init__.py +0 -0
  83. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/conformance.py +0 -0
  84. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/errors.py +0 -0
  85. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/sql.py +0 -0
  86. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/sqlite.py +0 -0
  87. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/store.py +0 -0
  88. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/transitions.py +0 -0
  89. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/__init__.py +0 -0
  90. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/base.py +0 -0
  91. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/validation.py +0 -0
  92. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/pairwise.py +0 -0
  93. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/report.py +0 -0
  94. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/runner.py +0 -0
  95. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/splitting.py +0 -0
  96. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/__init__.py +0 -0
  97. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/agent.py +0 -0
  98. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/model.py +0 -0
  99. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/multi_turn.py +0 -0
  100. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/orchestrator.py +0 -0
  101. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/runtime.py +0 -0
  102. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/workflow.py +0 -0
  103. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/__init__.py +0 -0
  104. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/jobs.py +0 -0
  105. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/smoke.py +0 -0
  106. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/smoke_tasks.json +0 -0
  107. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/suite.py +0 -0
  108. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/execution_trace/__init__.py +0 -0
  109. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/execution_trace/collector.py +0 -0
  110. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/execution_trace/models.py +0 -0
  111. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/__init__.py +0 -0
  112. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/_retry_observability.py +0 -0
  113. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/auth.py +0 -0
  114. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/__init__.py +0 -0
  115. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/auth.py +0 -0
  116. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/chat.py +0 -0
  117. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/embedding.py +0 -0
  118. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/settings.py +0 -0
  119. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure_openai.py +0 -0
  120. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure_openai_embedding.py +0 -0
  121. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/base.py +0 -0
  122. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/embeddings_base.py +0 -0
  123. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai/__init__.py +0 -0
  124. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai/chat.py +0 -0
  125. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai/embedding.py +0 -0
  126. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai/settings.py +0 -0
  127. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai_embedding.py +0 -0
  128. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/pricing.py +0 -0
  129. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/retry_policy.py +0 -0
  130. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/settings.py +0 -0
  131. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/types.py +0 -0
  132. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/logger.py +0 -0
  133. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/memory/__init__.py +0 -0
  134. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/memory/base.py +0 -0
  135. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/messages.py +0 -0
  136. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/__init__.py +0 -0
  137. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/base.py +0 -0
  138. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/otel.py +0 -0
  139. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/retry.py +0 -0
  140. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/sql_usage.py +0 -0
  141. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/usage_logger.py +0 -0
  142. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/notebook.py +0 -0
  143. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/gepa.py +0 -0
  144. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/mipro.py +0 -0
  145. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/pareto.py +0 -0
  146. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/trace.py +0 -0
  147. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/__init__.py +0 -0
  148. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/ai.py +0 -0
  149. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/base.py +0 -0
  150. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/handoff.py +0 -0
  151. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/plan.py +0 -0
  152. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/policies.py +0 -0
  153. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/round_robin.py +0 -0
  154. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/__init__.py +0 -0
  155. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/agents.py +0 -0
  156. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/clients.py +0 -0
  157. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instruction_registry.py +0 -0
  158. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/orchestrator.yaml +0 -0
  159. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/query_rewriter.yaml +0 -0
  160. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/researcher.yaml +0 -0
  161. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/reviewer.yaml +0 -0
  162. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/writer.yaml +0 -0
  163. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/orchestration.py +0 -0
  164. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/contracts-analyst/SKILL.md +0 -0
  165. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/hr-analyst/SKILL.md +0 -0
  166. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/hr-analyst/resources/departments.md +0 -0
  167. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/hr-analyst/resources/employees.md +0 -0
  168. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/hr-analyst/resources/payroll.md +0 -0
  169. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/streaming.py +0 -0
  170. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/workflow.py +0 -0
  171. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/session_store.py +0 -0
  172. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/__init__.py +0 -0
  173. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/base.py +0 -0
  174. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/resources.py +0 -0
  175. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/scripts.py +0 -0
  176. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/sources.py +0 -0
  177. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/validation.py +0 -0
  178. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/__init__.py +0 -0
  179. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/base.py +0 -0
  180. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/cancellation.py +0 -0
  181. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/composite.py +0 -0
  182. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/consecutive_agent.py +0 -0
  183. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/external.py +0 -0
  184. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/function_call.py +0 -0
  185. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/handoff.py +0 -0
  186. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/max_message.py +0 -0
  187. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/predicate.py +0 -0
  188. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/source.py +0 -0
  189. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/text_mention.py +0 -0
  190. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/timeout.py +0 -0
  191. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/token_usage.py +0 -0
  192. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/__init__.py +0 -0
  193. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/base.py +0 -0
  194. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/coding_tools.py +0 -0
  195. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/core_tools.py +0 -0
  196. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/decorator.py +0 -0
  197. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/memory_tool.py +0 -0
  198. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/research_tools.py +0 -0
  199. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/types.py +0 -0
  200. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/__init__.py +0 -0
  201. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/discovery.py +0 -0
  202. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/execution.py +0 -0
  203. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/models.py +0 -0
  204. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/registry.py +0 -0
  205. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/server.py +0 -0
  206. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/session_store.py +0 -0
  207. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/sessions.py +0 -0
  208. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/ui/assets/index-C-wj-OzO.js +0 -0
  209. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/ui/assets/index-DW8IDODJ.css +0 -0
  210. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/ui/index.html +0 -0
  211. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/ui/vite.svg +0 -0
  212. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/__init__.py +0 -0
  213. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/agent.py +0 -0
  214. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/__init__.py +0 -0
  215. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/_structure_hash.py +0 -0
  216. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/checkpoint.py +0 -0
  217. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/models.py +0 -0
  218. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/runner.py +0 -0
  219. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/workflow.py +0 -0
  220. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/defaults.py +0 -0
  221. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/errors.py +0 -0
  222. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/loader.py +0 -0
  223. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/schema.py +0 -0
  224. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/schema_utils.py +0 -0
  225. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/sqlite_checkpoint.py +0 -0
  226. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/__init__.py +0 -0
  227. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/agent.py +0 -0
  228. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/echo.py +0 -0
  229. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/function.py +0 -0
  230. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/http.py +0 -0
  231. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/step.py +0 -0
  232. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/subworkflow.py +0 -0
  233. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/transform.py +0 -0
  234. {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/visualizer.py +0 -0
  235. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_as_tool.py +0 -0
  236. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_basic.py +0 -0
  237. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_context_providers.py +0 -0
  238. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_error_response.py +0 -0
  239. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_event_types.py +0 -0
  240. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_memory_integration.py +0 -0
  241. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_middleware_integration.py +0 -0
  242. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_response_accessors.py +0 -0
  243. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_retry_middleware.py +0 -0
  244. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_stream_events.py +0 -0
  245. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_embedding_agent.py +0 -0
  246. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_tool_approval.py +0 -0
  247. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_tool_batch_resolution.py +0 -0
  248. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_tool_metadata.py +0 -0
  249. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/cli/test_loading.py +0 -0
  250. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/cli/test_registry_check.py +0 -0
  251. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/compaction/test_compaction.py +0 -0
  252. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/context_providers/__init__.py +0 -0
  253. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/context_providers/test_skill_tools.py +0 -0
  254. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/context_providers/test_skills_provider.py +0 -0
  255. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/fake_s3.py +0 -0
  256. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_dataset_exit.py +0 -0
  257. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_loader.py +0 -0
  258. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_multi_table.py +0 -0
  259. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_publish.py +0 -0
  260. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_sqlite_db.py +0 -0
  261. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_dataset.py +0 -0
  262. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_history_backends.py +0 -0
  263. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_jobs.py +0 -0
  264. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_workbench.py +0 -0
  265. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_execution_trajectories.py +0 -0
  266. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_multi_turn.py +0 -0
  267. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_pairwise.py +0 -0
  268. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_phase1_runner_and_targets.py +0 -0
  269. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_phase2_checks_and_reports.py +0 -0
  270. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_score_integrity.py +0 -0
  271. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_splitting.py +0 -0
  272. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/examples/test_compaction_webapp.py +0 -0
  273. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_azure_client.py +0 -0
  274. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_azure_embedding_client.py +0 -0
  275. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_llm_types.py +0 -0
  276. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_openai_client.py +0 -0
  277. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_openai_embedding_client.py +0 -0
  278. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_pricing.py +0 -0
  279. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_retry_observability.py +0 -0
  280. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_retry_policy_api.py +0 -0
  281. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_retryable_error_substrings.py +0 -0
  282. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/memory/test_memory.py +0 -0
  283. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_context_compaction.py +0 -0
  284. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_deduplicate_tool_result.py +0 -0
  285. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_middleware_chain.py +0 -0
  286. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_otel.py +0 -0
  287. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_retry_middleware.py +0 -0
  288. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_sql_usage.py +0 -0
  289. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_usage_logger.py +0 -0
  290. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/__init__.py +0 -0
  291. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_base.py +0 -0
  292. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_base_integration.py +0 -0
  293. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_config.py +0 -0
  294. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_gepa.py +0 -0
  295. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_mipro.py +0 -0
  296. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_pareto.py +0 -0
  297. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_reflective.py +0 -0
  298. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_score_integrity.py +0 -0
  299. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_spec.py +0 -0
  300. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_trace.py +0 -0
  301. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_ai_orchestrator.py +0 -0
  302. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_base_orchestrator.py +0 -0
  303. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_handoff_orchestrator.py +0 -0
  304. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_orchestrator_finalization.py +0 -0
  305. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_plan_orchestrator.py +0 -0
  306. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_round_robin.py +0 -0
  307. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_agents.py +0 -0
  308. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_clients.py +0 -0
  309. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_instruction_registry.py +0 -0
  310. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_orchestration.py +0 -0
  311. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_streaming.py +0 -0
  312. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_workflow.py +0 -0
  313. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/__init__.py +0 -0
  314. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/test_base.py +0 -0
  315. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/test_resources.py +0 -0
  316. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/test_scripts.py +0 -0
  317. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/test_sources.py +0 -0
  318. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_base.py +0 -0
  319. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_cancellation.py +0 -0
  320. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_composite.py +0 -0
  321. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_consecutive_agent.py +0 -0
  322. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_external.py +0 -0
  323. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_function_call.py +0 -0
  324. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_handoff.py +0 -0
  325. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_max_message.py +0 -0
  326. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_predicate.py +0 -0
  327. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_source.py +0 -0
  328. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_text_mention.py +0 -0
  329. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_timeout.py +0 -0
  330. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_token_usage.py +0 -0
  331. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_cancellation_token.py +0 -0
  332. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_context.py +0 -0
  333. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_logger.py +0 -0
  334. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_messages.py +0 -0
  335. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_optional_extras.py +0 -0
  336. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_package_api.py +0 -0
  337. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_session_store.py +0 -0
  338. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_types.py +0 -0
  339. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_vanilla_chunker.py +0 -0
  340. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/tools/test_coding_tools.py +0 -0
  341. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/tools/test_memory_tool.py +0 -0
  342. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/tools/test_research_tools.py +0 -0
  343. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/tools/test_tools.py +0 -0
  344. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/__init__.py +0 -0
  345. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/helpers.py +0 -0
  346. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_eval_routes.py +0 -0
  347. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_execution.py +0 -0
  348. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_package_api.py +0 -0
  349. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_registry.py +0 -0
  350. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_server.py +0 -0
  351. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_sessions.py +0 -0
  352. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_workflow_streaming.py +0 -0
  353. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/recovery_worker.py +0 -0
  354. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_agent_step_imports.py +0 -0
  355. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_checkpoint.py +0 -0
  356. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_subworkflow_step.py +0 -0
  357. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_agent.py +0 -0
  358. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_class.py +0 -0
  359. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_models.py +0 -0
  360. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_reliability.py +0 -0
  361. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_runner.py +0 -0
  362. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_schema.py +0 -0
  363. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_steps.py +0 -0
  364. {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_visualizer.py +0 -0
@@ -6,6 +6,95 @@ The format follows Keep a Changelog principles and semantic versioning.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.38.0] - 2026-10-02
10
+
11
+ ### Added
12
+
13
+ - Orchestrator optimization (spec 0062). `agentbyte.optim` can now optimize a
14
+ multi-agent orchestrator as a whole, not only a single agent:
15
+ - A pluggable `build_target` seam on `BaseOptimizer` maps a candidate config to a
16
+ `BaseEvalTarget`. Omitting it preserves the single-agent path byte-for-byte
17
+ (`config.to_agent` + `AgentEvalTarget`).
18
+ - `agentbyte.optim.OrchestratorConfig` — a frozen, serializable composite candidate
19
+ (`{member_name: AgentConfig}`). The controller/termination is *not* snapshotted; it
20
+ is reattached by a user-supplied `OrchestratorAssembler`.
21
+ - `orchestrator_build_target(model_client, tool_catalog, assemble)` builds an
22
+ `OrchestratorEvalTarget` in factory form (a fresh orchestrator per eval case).
23
+ - `OptimizationSpec.for_members({...})` (→ `MemberOptimizationSpec`) exposes each
24
+ member's components under a namespaced name (`support.instructions`); edits route
25
+ back to the owning member, and names outside the composite spec become no-ops.
26
+ - Per-member credit assignment reuses `source_filter` (spec 0060/0061): the judge
27
+ scores only one member's messages in the multi-source orchestrated trajectory.
28
+ - New exports: `OrchestratorConfig`, `OptimizableConfig`, `OrchestratorAssembler`,
29
+ `TargetBuilder`, `orchestrator_build_target`, `MemberOptimizationSpec`.
30
+
31
+ ### Notes
32
+
33
+ - Single-agent optimization is unchanged (default `build_target`, `AgentConfig` seed).
34
+ - Workflow-level optimization remains a non-goal: optimize each `AgentStep`'s agent
35
+ standalone and compose. GEPA stays single-agent (it runs the external `gepa` loop).
36
+
37
+ ## [0.37.0] - 2026-10-02
38
+
39
+ ### Changed
40
+
41
+ - `agentbyte.eval.history.CaptureMode` is now an `enum.StrEnum` (`SUMMARY`, `FULL`) instead of a
42
+ `Literal["summary", "full"]` alias (spec 0063). The valid values are importable and
43
+ autocomplete, and the enum is the single source of truth: the duplicated `("summary", "full")`
44
+ checks in `EvalRunRecorder` and `EvalSuiteCoordinator._check_capture`, and the re-declared
45
+ `Literal` on the WebUI request model, are gone. Because `StrEnum` members are `str` subclasses
46
+ with value-equality (`CaptureMode.FULL == "full"`), callers passing the raw strings keep
47
+ working, the WebUI JSON contract (`"capture": "full"`) is unchanged, and stored runs reload
48
+ identically.
49
+
50
+ ### Notes
51
+
52
+ - Breaking only for code that compared `CaptureMode` with `is` against a string literal
53
+ (identity); equality (`==`) is the supported contract and is unchanged.
54
+
55
+ ## [0.36.0] - 2026-10-02
56
+
57
+ ### Added
58
+
59
+ - `agentbyte.eval.ConversationScope` — a `StrEnum` (`FULL`, `LAST_TURN`) that selects which
60
+ part of a multi-turn conversation a judge evaluates (spec 0061). It is applied before
61
+ `source_filter` and `AnswerStrategy`, so the three selection axes compose: scope narrows the
62
+ trajectory to a turn window, `source_filter` keeps matching sources, then `AnswerStrategy`
63
+ picks the message(s). A turn boundary is the last `UserMessage`; `LAST_TURN` scopes from
64
+ there to the end of the trajectory.
65
+ - `conversation_scope` keyword (default `ConversationScope.FULL`) on `BaseEvalJudge` and the
66
+ judges/checks that already accept `answer_strategy` (`LLMEvalJudge`, reference judges,
67
+ `PairwiseJudge`, `LLMTrajectoryJudge`, `keyword_check`, the `evaluator` decorator).
68
+ - `agentbyte.eval.base.scope_messages(messages, scope)` — the pure helper implementing the
69
+ turn-window selection.
70
+
71
+ ### Notes
72
+
73
+ - Additive and non-breaking: the default `FULL` reproduces today's whole-trajectory behaviour
74
+ for every existing single- and multi-turn caller. `LAST_TURN` is strictly opt-in.
75
+
76
+ ## [0.35.0] - 2026-10-02
77
+
78
+ Upgrade notes (breaking):
79
+
80
+ - `agentbyte.eval.AnswerStrategy` is now an `enum.StrEnum` instead of a `Literal[...]` type
81
+ alias (spec 0060). Prefer the members `AnswerStrategy.LAST_NON_EMPTY`,
82
+ `AnswerStrategy.LAST_ASSISTANT`, `AnswerStrategy.LAST_CONTENT` and
83
+ `AnswerStrategy.ALL_ASSISTANT`. Because `StrEnum` members are `str` subclasses with
84
+ value-equality, passing the raw strings (`"last_assistant"`, etc.) keeps working and
85
+ serialization is unchanged; only code that compared the value with `is` against a string
86
+ literal (identity) is affected.
87
+
88
+ ### Changed
89
+
90
+ - `AnswerStrategy` is a single source of truth: the duplicated `_VALID_ANSWER_STRATEGIES`
91
+ tuple in `agentbyte.eval.base` is removed and unknown values are rejected via
92
+ `AnswerStrategy(value)` with a `ValueError` naming the valid members. All judges and checks
93
+ (`LLMEvalJudge`, reference judges, `PairwiseJudge`, `keyword_check`, the `evaluator`
94
+ decorator, composite/trajectory judges) default to the enum members.
95
+ - Eval end-to-end notebook (`notebooks/usecases/eval/06-eval-end-to-end.ipynb`) and the
96
+ example catalog (`examples/eval/acme_support.py`) use the typed `AnswerStrategy` enum.
97
+
9
98
  ## [0.34.0] - 2026-10-01
10
99
 
11
100
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentbyte
3
- Version: 0.34.0
3
+ Version: 0.38.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
@@ -72,7 +72,7 @@ Description-Content-Type: text/markdown
72
72
 
73
73
  Agentbyte is an observability-first agentic AI framework for building and studying multiagent systems with a learning-first, implementation-oriented workflow.
74
74
 
75
- Current release: **0.34.0**
75
+ Current release: **0.38.0**
76
76
 
77
77
  ## Building an Agent
78
78
 
@@ -368,7 +368,7 @@ uv run agentbyte eval ui --catalog examples/eval/workbench_catalog.py # htt
368
368
  - To serve agents and Evaluations together: `agentbyte webui --dir my_entities --eval-catalog myapp/evaluations.py`.
369
369
 
370
370
  Start with the end-to-end guide, `docs/guides/evaluation-end-to-end.md` (dataset → suite → history → UI), and the
371
- notebook `notebooks/usecases/eval/06-eval-end-to-end.ipynb` (real OpenAI/Azure model). Details: `docs/study/05-eval_topics/`.
371
+ notebook `notebooks/usecases/eval/06-eval-end-to-end.ipynb` (real OpenAI/Azure model). Details: `docs/design-guide/05-eval_topics/`.
372
372
 
373
373
  ### Option 3: Scan a project directory
374
374
 
@@ -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.34.0**
5
+ Current release: **0.38.0**
6
6
 
7
7
  ## Building an Agent
8
8
 
@@ -298,7 +298,7 @@ uv run agentbyte eval ui --catalog examples/eval/workbench_catalog.py # htt
298
298
  - To serve agents and Evaluations together: `agentbyte webui --dir my_entities --eval-catalog myapp/evaluations.py`.
299
299
 
300
300
  Start with the end-to-end guide, `docs/guides/evaluation-end-to-end.md` (dataset → suite → history → UI), and the
301
- notebook `notebooks/usecases/eval/06-eval-end-to-end.ipynb` (real OpenAI/Azure model). Details: `docs/study/05-eval_topics/`.
301
+ notebook `notebooks/usecases/eval/06-eval-end-to-end.ipynb` (real OpenAI/Azure model). Details: `docs/design-guide/05-eval_topics/`.
302
302
 
303
303
  ### Option 3: Scan a project directory
304
304
 
@@ -0,0 +1,2 @@
1
+ __version__ = "0.38.0"
2
+ VERSION = __version__
@@ -48,6 +48,7 @@ from .splitting import (
48
48
  from .targets import AgentEvalTarget, ModelEvalTarget, MultiTurnAgentEvalTarget, OrchestratorEvalTarget
49
49
  from .types import (
50
50
  AnswerStrategy,
51
+ ConversationScope,
51
52
  EvalResult,
52
53
  EvalScore,
53
54
  EvalTask,
@@ -63,6 +64,7 @@ __all__ = [
63
64
  "WorkflowEvalTask", "WorkflowEvalTarget", "LLMTrajectoryJudge",
64
65
  "select_span", "terminal_status", "steps_completed", "edge_activated", "usage_limits",
65
66
  "AnswerStrategy",
67
+ "ConversationScope",
66
68
  "ExpectedToolCall",
67
69
  "EvalTask",
68
70
  "MultiTurnEvalTask",
@@ -5,16 +5,29 @@ from __future__ import annotations
5
5
  from abc import ABC, abstractmethod
6
6
 
7
7
  from agentbyte.cancellation_token import CancellationToken
8
- from agentbyte.messages import AssistantMessage
8
+ from agentbyte.messages import AssistantMessage, Message, UserMessage
9
9
 
10
- from .types import AnswerStrategy, EvalScore, EvalTask, EvalTrajectory
10
+ from .types import AnswerStrategy, ConversationScope, EvalScore, EvalTask, EvalTrajectory
11
11
 
12
- _VALID_ANSWER_STRATEGIES: tuple[AnswerStrategy, ...] = (
13
- "last_non_empty",
14
- "last_assistant",
15
- "last_content",
16
- "all_assistant",
17
- )
12
+
13
+ def scope_messages(
14
+ messages: list[Message],
15
+ scope: ConversationScope,
16
+ ) -> list[Message]:
17
+ """Narrow a message list to the chosen conversation scope.
18
+
19
+ ``FULL`` returns the list unchanged. ``LAST_TURN`` returns the messages from
20
+ the last ``UserMessage`` (a turn boundary) to the end, inclusive of that
21
+ user message; if there is no ``UserMessage`` the whole list is returned.
22
+ This runs before ``source_filter`` and ``AnswerStrategy`` so the three
23
+ selection axes compose.
24
+ """
25
+ if scope == ConversationScope.LAST_TURN:
26
+ for index in range(len(messages) - 1, -1, -1):
27
+ if isinstance(messages[index], UserMessage):
28
+ return list(messages[index:])
29
+ return list(messages)
30
+ return list(messages)
18
31
 
19
32
 
20
33
  class JudgeScoringError(Exception):
@@ -51,17 +64,28 @@ class BaseEvalJudge(ABC):
51
64
  def __init__(
52
65
  self,
53
66
  name: str,
54
- answer_strategy: AnswerStrategy = "last_non_empty",
67
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
55
68
  source_filter: str | None = None,
69
+ conversation_scope: ConversationScope = ConversationScope.FULL,
56
70
  ) -> None:
57
- if answer_strategy not in _VALID_ANSWER_STRATEGIES:
71
+ try:
72
+ answer_strategy = AnswerStrategy(answer_strategy)
73
+ except ValueError as exc:
58
74
  raise ValueError(
59
75
  f"Unsupported answer_strategy: {answer_strategy!r}. "
60
- f"Expected one of {list(_VALID_ANSWER_STRATEGIES)}."
61
- )
76
+ f"Expected one of {[s.value for s in AnswerStrategy]}."
77
+ ) from exc
78
+ try:
79
+ conversation_scope = ConversationScope(conversation_scope)
80
+ except ValueError as exc:
81
+ raise ValueError(
82
+ f"Unsupported conversation_scope: {conversation_scope!r}. "
83
+ f"Expected one of {[s.value for s in ConversationScope]}."
84
+ ) from exc
62
85
  self.name = name
63
86
  self.answer_strategy = answer_strategy
64
87
  self.source_filter = source_filter
88
+ self.conversation_scope = conversation_scope
65
89
 
66
90
  def extract_answer(self, trajectory: EvalTrajectory) -> str:
67
91
  """Extract the answer text from a trajectory using the configured strategy.
@@ -71,23 +95,27 @@ class BaseEvalJudge(ABC):
71
95
  lets callers target a specific agent's output in multi-agent trajectories
72
96
  (e.g. extract the Writer's last message from a Researcher→Writer→Reviewer
73
97
  orchestrator run).
98
+
99
+ Selection runs in a fixed order: ``conversation_scope`` narrows the
100
+ trajectory to a turn window, then ``source_filter`` keeps only matching
101
+ sources, then ``answer_strategy`` picks the message(s) that remain.
74
102
  """
75
- messages = list(trajectory.messages)
103
+ messages = scope_messages(trajectory.messages, self.conversation_scope)
76
104
  if self.source_filter:
77
105
  messages = [m for m in messages if m.source == self.source_filter]
78
106
  if not messages:
79
107
  return ""
80
108
 
81
- if self.answer_strategy == "last_content":
109
+ if self.answer_strategy == AnswerStrategy.LAST_CONTENT:
82
110
  return messages[-1].content
83
111
 
84
- if self.answer_strategy == "last_non_empty":
112
+ if self.answer_strategy == AnswerStrategy.LAST_NON_EMPTY:
85
113
  for message in reversed(messages):
86
114
  if message.content and message.content.strip():
87
115
  return message.content
88
116
  return ""
89
117
 
90
- if self.answer_strategy == "last_assistant":
118
+ if self.answer_strategy == AnswerStrategy.LAST_ASSISTANT:
91
119
  for message in reversed(messages):
92
120
  if isinstance(message, AssistantMessage):
93
121
  return message.content
@@ -134,4 +162,10 @@ class BaseEvalRunner(ABC):
134
162
  """Evaluate a target on multiple tasks."""
135
163
 
136
164
 
137
- __all__ = ["BaseEvalTarget", "BaseEvalJudge", "BaseEvalRunner", "JudgeScoringError"]
165
+ __all__ = [
166
+ "BaseEvalTarget",
167
+ "BaseEvalJudge",
168
+ "BaseEvalRunner",
169
+ "JudgeScoringError",
170
+ "scope_messages",
171
+ ]
@@ -7,7 +7,7 @@ from collections.abc import Callable
7
7
  from typing import Any, overload
8
8
 
9
9
  from agentbyte.eval.base import BaseEvalJudge
10
- from agentbyte.eval.types import AnswerStrategy, EvalTrajectory
10
+ from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalTrajectory
11
11
 
12
12
  from .types import CheckResult, EvalCheck
13
13
 
@@ -95,18 +95,20 @@ def evaluator(fn: Callable[..., Any], /) -> EvalCheck: ...
95
95
  @overload
96
96
  def evaluator(
97
97
  *,
98
- answer_strategy: AnswerStrategy = "last_non_empty",
98
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
99
99
  name: str | None = None,
100
100
  source_filter: str | None = None,
101
+ conversation_scope: ConversationScope = ConversationScope.FULL,
101
102
  ) -> Callable[[Callable[..., Any]], EvalCheck]: ...
102
103
 
103
104
 
104
105
  def evaluator(
105
106
  fn: Callable[..., Any] | None = None,
106
107
  *,
107
- answer_strategy: AnswerStrategy = "last_non_empty",
108
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
108
109
  name: str | None = None,
109
110
  source_filter: str | None = None,
111
+ conversation_scope: ConversationScope = ConversationScope.FULL,
110
112
  ) -> EvalCheck | Callable[[Callable[..., Any]], EvalCheck]:
111
113
  """Wrap a plain function as an EvalCheck with parameter injection.
112
114
 
@@ -139,6 +141,7 @@ def evaluator(
139
141
  name="extractor",
140
142
  answer_strategy=answer_strategy,
141
143
  source_filter=source_filter,
144
+ conversation_scope=conversation_scope,
142
145
  )
143
146
  kwargs = _resolve_args(
144
147
  func,
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from agentbyte.eval.judges.reference import ExactMatchJudge
6
- from agentbyte.eval.types import AnswerStrategy, EvalTrajectory
6
+ from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalTrajectory
7
7
 
8
8
  from .types import CheckResult, EvalCheck
9
9
 
@@ -12,7 +12,8 @@ def keyword_check(
12
12
  *keywords: str,
13
13
  case_sensitive: bool = False,
14
14
  source_filter: str | None = None,
15
- answer_strategy: AnswerStrategy = "last_assistant",
15
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_ASSISTANT,
16
+ conversation_scope: ConversationScope = ConversationScope.FULL,
16
17
  ) -> EvalCheck:
17
18
  """Return a check that verifies all keywords appear in the extracted response.
18
19
 
@@ -22,7 +23,11 @@ def keyword_check(
22
23
  Pass ``source_filter`` to target a specific agent in multi-agent trajectories
23
24
  (e.g. ``source_filter="writer"`` in a Researcher→Writer→Reviewer pipeline).
24
25
  """
25
- extractor = ExactMatchJudge(answer_strategy=answer_strategy, source_filter=source_filter)
26
+ extractor = ExactMatchJudge(
27
+ answer_strategy=answer_strategy,
28
+ source_filter=source_filter,
29
+ conversation_scope=conversation_scope,
30
+ )
26
31
 
27
32
  async def _check(trajectory: EvalTrajectory) -> CheckResult:
28
33
  response = extractor.extract_answer(trajectory)
@@ -12,6 +12,7 @@ import math
12
12
  import re
13
13
  from collections.abc import Callable
14
14
  from datetime import date, datetime, timezone
15
+ from enum import StrEnum
15
16
  from typing import Any, Literal
16
17
  from uuid import uuid4
17
18
 
@@ -30,7 +31,20 @@ EVIDENCE_VERSION = 1
30
31
 
31
32
  RunStatus = Literal["queued", "running", "completed", "failed", "cancelled", "interrupted"]
32
33
  ItemState = Literal["pending", "running", "finished", "cancelled", "not_started"]
33
- CaptureMode = Literal["summary", "full"]
34
+
35
+
36
+ class CaptureMode(StrEnum):
37
+ """How much evidence an evaluation run captures.
38
+
39
+ A ``StrEnum``: members compare and serialize as their plain string value
40
+ (``CaptureMode.FULL == "full"``), so callers may pass either the member or
41
+ the raw string.
42
+ """
43
+
44
+ SUMMARY = "summary"
45
+ FULL = "full"
46
+
47
+
34
48
  EvidenceStatus = Literal["not_captured", "captured", "redacted", "unavailable"]
35
49
  TaskType = Literal["task", "workflow", "multi_turn"]
36
50
 
@@ -71,7 +85,7 @@ class EvalRunRecord(BaseModel):
71
85
  schema_version: int = SCHEMA_VERSION
72
86
  status: RunStatus = "queued"
73
87
  revision: int = 0
74
- capture: CaptureMode = "summary"
88
+ capture: CaptureMode = CaptureMode.SUMMARY
75
89
  dataset_id: str
76
90
  dataset_revision: str | None = None
77
91
  target_id: str
@@ -59,17 +59,21 @@ class EvalRunRecorder:
59
59
  def __init__(
60
60
  self,
61
61
  store: EvalRunStore,
62
- capture: CaptureMode = "summary",
62
+ capture: CaptureMode = CaptureMode.SUMMARY,
63
63
  *,
64
64
  concurrency: int = 4,
65
65
  redact: Redactor | None = None,
66
66
  worker_id: str | None = None,
67
67
  ) -> None:
68
- if capture not in ("summary", "full"):
69
- raise ValueError("capture must be 'summary' or 'full'")
68
+ try:
69
+ capture = CaptureMode(capture)
70
+ except ValueError as exc:
71
+ raise ValueError(
72
+ f"capture must be one of {[m.value for m in CaptureMode]}, got {capture!r}"
73
+ ) from exc
70
74
  if concurrency < 1:
71
75
  raise ValueError("concurrency must be at least 1")
72
- if redact is not None and capture != "full":
76
+ if redact is not None and capture != CaptureMode.FULL:
73
77
  raise ValueError("redact applies only to capture='full'")
74
78
  self.store = store
75
79
  self.capture = capture
@@ -315,7 +319,7 @@ class EvalRunRecorder:
315
319
  def _outcome(self, run_id: str, index: int, task: EvalTask, score: EvalScore) -> EvalItemRecord:
316
320
  evidence: EvalScore | None = None
317
321
  evidence_status: EvidenceStatus = "not_captured"
318
- if self.capture == "full":
322
+ if self.capture == CaptureMode.FULL:
319
323
  evidence, evidence_status = score, "captured"
320
324
  if self.redact is not None:
321
325
  try:
@@ -8,7 +8,7 @@ from collections.abc import Sequence
8
8
  from agentbyte.cancellation_token import CancellationToken
9
9
 
10
10
  from agentbyte.eval.base import BaseEvalJudge, JudgeScoringError
11
- from agentbyte.eval.types import EvalScore, EvalTrajectory
11
+ from agentbyte.eval.types import AnswerStrategy, EvalScore, EvalTrajectory
12
12
 
13
13
 
14
14
  class CompositeJudge(BaseEvalJudge):
@@ -36,7 +36,7 @@ class CompositeJudge(BaseEvalJudge):
36
36
  )
37
37
  normalized = list(judges)
38
38
 
39
- super().__init__(name=name, answer_strategy="last_non_empty")
39
+ super().__init__(name=name, answer_strategy=AnswerStrategy.LAST_NON_EMPTY)
40
40
  self.judges = normalized
41
41
 
42
42
  async def score(
@@ -21,7 +21,7 @@ from agentbyte.eval.judges.validation import (
21
21
  resolve_criteria,
22
22
  validate_criterion_scores,
23
23
  )
24
- from agentbyte.eval.types import AnswerStrategy, EvalScore, EvalTrajectory
24
+ from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalScore, EvalTrajectory
25
25
 
26
26
 
27
27
  class _JudgeCriterionScore(BaseModel):
@@ -51,8 +51,9 @@ class LLMEvalJudge(BaseEvalJudge):
51
51
  client: BaseChatCompletionClient,
52
52
  *,
53
53
  name: str | None = None,
54
- answer_strategy: AnswerStrategy = "last_non_empty",
54
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
55
55
  source_filter: str | None = None,
56
+ conversation_scope: ConversationScope = ConversationScope.FULL,
56
57
  default_criteria: list[str] | None = None,
57
58
  custom_instructions: str | None = None,
58
59
  use_structured_output: bool = True,
@@ -61,6 +62,7 @@ class LLMEvalJudge(BaseEvalJudge):
61
62
  name=name or f"LLM-{client.model}",
62
63
  answer_strategy=answer_strategy,
63
64
  source_filter=source_filter,
65
+ conversation_scope=conversation_scope,
64
66
  )
65
67
  require_non_empty_defaults(default_criteria, "default_criteria")
66
68
  self.client = client
@@ -15,7 +15,13 @@ from agentbyte.messages import SystemMessage, UserMessage
15
15
 
16
16
  from agentbyte.eval.base import BaseEvalJudge, JudgeScoringError
17
17
  from agentbyte.eval.judges.validation import loads_judge_json, require_non_empty_defaults
18
- from agentbyte.eval.types import AnswerStrategy, EvalScore, EvalTrajectory, PairwiseResult
18
+ from agentbyte.eval.types import (
19
+ AnswerStrategy,
20
+ ConversationScope,
21
+ EvalScore,
22
+ EvalTrajectory,
23
+ PairwiseResult,
24
+ )
19
25
 
20
26
 
21
27
  class _PairwiseResponse(BaseModel):
@@ -47,14 +53,16 @@ class PairwiseJudge(BaseEvalJudge):
47
53
  *,
48
54
  name: str | None = None,
49
55
  criteria: list[str] | None = None,
50
- answer_strategy: AnswerStrategy = "last_assistant",
56
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_ASSISTANT,
51
57
  source_filter: str | None = None,
58
+ conversation_scope: ConversationScope = ConversationScope.FULL,
52
59
  custom_instructions: str | None = None,
53
60
  ) -> None:
54
61
  super().__init__(
55
62
  name=name or f"Pairwise-{client.model}",
56
63
  answer_strategy=answer_strategy,
57
64
  source_filter=source_filter,
65
+ conversation_scope=conversation_scope,
58
66
  )
59
67
  require_non_empty_defaults(criteria, "criteria")
60
68
  self.client = client
@@ -7,7 +7,7 @@ from difflib import SequenceMatcher
7
7
  from agentbyte.cancellation_token import CancellationToken
8
8
 
9
9
  from agentbyte.eval.base import BaseEvalJudge
10
- from agentbyte.eval.types import AnswerStrategy, EvalScore, EvalTrajectory
10
+ from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalScore, EvalTrajectory
11
11
 
12
12
 
13
13
  def _failed_score(judge_name: str, trajectory: EvalTrajectory) -> EvalScore:
@@ -28,12 +28,18 @@ class ExactMatchJudge(BaseEvalJudge):
28
28
  self,
29
29
  *,
30
30
  name: str = "ExactMatch",
31
- answer_strategy: AnswerStrategy = "last_non_empty",
31
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
32
32
  source_filter: str | None = None,
33
+ conversation_scope: ConversationScope = ConversationScope.FULL,
33
34
  case_sensitive: bool = False,
34
35
  strip_whitespace: bool = True,
35
36
  ) -> None:
36
- super().__init__(name=name, answer_strategy=answer_strategy, source_filter=source_filter)
37
+ super().__init__(
38
+ name=name,
39
+ answer_strategy=answer_strategy,
40
+ source_filter=source_filter,
41
+ conversation_scope=conversation_scope,
42
+ )
37
43
  self.case_sensitive = case_sensitive
38
44
  self.strip_whitespace = strip_whitespace
39
45
 
@@ -76,11 +82,17 @@ class ContainsJudge(BaseEvalJudge):
76
82
  self,
77
83
  *,
78
84
  name: str = "Contains",
79
- answer_strategy: AnswerStrategy = "last_non_empty",
85
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
80
86
  source_filter: str | None = None,
87
+ conversation_scope: ConversationScope = ConversationScope.FULL,
81
88
  case_sensitive: bool = False,
82
89
  ) -> None:
83
- super().__init__(name=name, answer_strategy=answer_strategy, source_filter=source_filter)
90
+ super().__init__(
91
+ name=name,
92
+ answer_strategy=answer_strategy,
93
+ source_filter=source_filter,
94
+ conversation_scope=conversation_scope,
95
+ )
84
96
  self.case_sensitive = case_sensitive
85
97
 
86
98
  async def score(
@@ -123,14 +135,20 @@ class FuzzyMatchJudge(BaseEvalJudge):
123
135
  self,
124
136
  *,
125
137
  name: str = "FuzzyMatch",
126
- answer_strategy: AnswerStrategy = "last_non_empty",
138
+ answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
127
139
  source_filter: str | None = None,
140
+ conversation_scope: ConversationScope = ConversationScope.FULL,
128
141
  case_sensitive: bool = False,
129
142
  threshold: float = 0.8,
130
143
  ) -> None:
131
144
  if not 0 <= threshold <= 1:
132
145
  raise ValueError("threshold must be within [0, 1]")
133
- super().__init__(name=name, answer_strategy=answer_strategy, source_filter=source_filter)
146
+ super().__init__(
147
+ name=name,
148
+ answer_strategy=answer_strategy,
149
+ source_filter=source_filter,
150
+ conversation_scope=conversation_scope,
151
+ )
134
152
  self.case_sensitive = case_sensitive
135
153
  self.threshold = threshold
136
154
 
@@ -18,7 +18,7 @@ from agentbyte.eval.judges.validation import (
18
18
  resolve_criteria,
19
19
  validate_criterion_scores,
20
20
  )
21
- from agentbyte.eval.types import EvalScore, EvalTrajectory
21
+ from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalScore, EvalTrajectory
22
22
 
23
23
 
24
24
  class ProcessCriterionScore(BaseModel):
@@ -49,8 +49,13 @@ class LLMTrajectoryJudge(BaseEvalJudge):
49
49
  default_criteria: list[str] | None = None,
50
50
  custom_instructions: str | None = None,
51
51
  max_payload_chars: int = 100_000,
52
+ conversation_scope: ConversationScope = ConversationScope.FULL,
52
53
  ) -> None:
53
- super().__init__(name, answer_strategy="last_assistant")
54
+ super().__init__(
55
+ name,
56
+ answer_strategy=AnswerStrategy.LAST_ASSISTANT,
57
+ conversation_scope=conversation_scope,
58
+ )
54
59
  if max_payload_chars <= 0:
55
60
  raise ValueError("max_payload_chars must be positive")
56
61
  require_non_empty_defaults(default_criteria, "default_criteria")
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import math
6
+ from enum import StrEnum
6
7
  from typing import Any, Literal
7
8
 
8
9
  from pydantic import (
@@ -17,12 +18,31 @@ from agentbyte.execution_trace import ExecutionTrace
17
18
 
18
19
  from agentbyte.messages import Message, Usage
19
20
 
20
- AnswerStrategy = Literal[
21
- "last_non_empty",
22
- "last_assistant",
23
- "last_content",
24
- "all_assistant",
25
- ]
21
+ class AnswerStrategy(StrEnum):
22
+ """Which message in a trajectory counts as the answer to be judged.
23
+
24
+ A ``StrEnum``: members compare and serialize as their plain string value
25
+ (``AnswerStrategy.LAST_ASSISTANT == "last_assistant"``), so callers may pass
26
+ either the member or the raw string.
27
+ """
28
+
29
+ LAST_NON_EMPTY = "last_non_empty"
30
+ LAST_ASSISTANT = "last_assistant"
31
+ LAST_CONTENT = "last_content"
32
+ ALL_ASSISTANT = "all_assistant"
33
+
34
+
35
+ class ConversationScope(StrEnum):
36
+ """Which part of a multi-turn conversation a judge evaluates.
37
+
38
+ Applied before ``source_filter`` and ``AnswerStrategy``, this narrows the
39
+ trajectory to a turn window first. A ``StrEnum``: members compare and
40
+ serialize as their plain string value (``ConversationScope.LAST_TURN ==
41
+ "last_turn"``), so callers may pass either the member or the raw string.
42
+ """
43
+
44
+ FULL = "full"
45
+ LAST_TURN = "last_turn"
26
46
 
27
47
 
28
48
  class ExpectedToolCall(BaseModel):
@@ -287,6 +307,7 @@ class PairwiseResult(BaseModel):
287
307
  __all__ = [
288
308
  "WorkflowEvalTask",
289
309
  "AnswerStrategy",
310
+ "ConversationScope",
290
311
  "ScoringStatus",
291
312
  "ExpectedToolCall",
292
313
  "EvalTask",