agentbyte 0.42.4__tar.gz → 0.43.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 (372) hide show
  1. {agentbyte-0.42.4 → agentbyte-0.43.0}/CHANGELOG.md +21 -0
  2. {agentbyte-0.42.4 → agentbyte-0.43.0}/PKG-INFO +2 -2
  3. {agentbyte-0.42.4 → agentbyte-0.43.0}/README.md +1 -1
  4. agentbyte-0.43.0/src/agentbyte/__about__.py +2 -0
  5. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/agents/agent.py +16 -1
  6. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/agents/base.py +18 -0
  7. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/orchestration/base.py +50 -0
  8. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/orchestration/policies.py +5 -1
  9. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/agent.py +1 -0
  10. agentbyte-0.43.0/tests/agents/test_agent_stop_at_tools.py +170 -0
  11. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_orchestrator_synthesis.py +90 -1
  12. agentbyte-0.42.4/src/agentbyte/__about__.py +0 -2
  13. {agentbyte-0.42.4 → agentbyte-0.43.0}/.gitignore +0 -0
  14. {agentbyte-0.42.4 → agentbyte-0.43.0}/LICENSE +0 -0
  15. {agentbyte-0.42.4 → agentbyte-0.43.0}/pyproject.toml +0 -0
  16. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/__init__.py +0 -0
  17. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/_optional.py +0 -0
  18. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/agents/__init__.py +0 -0
  19. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/agents/agent_as_tool.py +0 -0
  20. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/agents/embedding_agent.py +0 -0
  21. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/agents/types.py +0 -0
  22. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/cancellation_token.py +0 -0
  23. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/catalog.py +0 -0
  24. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/cli/__init__.py +0 -0
  25. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/cli/__main__.py +0 -0
  26. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/cli/eval_commands.py +0 -0
  27. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/cli/loading.py +0 -0
  28. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/cli/main.py +0 -0
  29. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/compaction/__init__.py +0 -0
  30. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/compaction/counters.py +0 -0
  31. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/compaction/errors.py +0 -0
  32. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/compaction/grouping.py +0 -0
  33. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/compaction/strategies.py +0 -0
  34. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/component.py +0 -0
  35. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/context.py +0 -0
  36. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/context_providers/__init__.py +0 -0
  37. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/context_providers/base.py +0 -0
  38. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/context_providers/skill_tools.py +0 -0
  39. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/context_providers/skills.py +0 -0
  40. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/__init__.py +0 -0
  41. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/_aiosqlite.py +0 -0
  42. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/base.py +0 -0
  43. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/config.py +0 -0
  44. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/importer.py +0 -0
  45. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/json.py +0 -0
  46. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/loader.py +0 -0
  47. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/publish.py +0 -0
  48. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/publish_config.py +0 -0
  49. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/publishers.py +0 -0
  50. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/s3.py +0 -0
  51. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/sources.py +0 -0
  52. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/sqlite.py +0 -0
  53. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/sqlite_db.py +0 -0
  54. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/write_config.py +0 -0
  55. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/dataset/writers.py +0 -0
  56. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/entity.py +0 -0
  57. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/__init__.py +0 -0
  58. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/base.py +0 -0
  59. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/checks/__init__.py +0 -0
  60. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/checks/decorator.py +0 -0
  61. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/checks/keyword.py +0 -0
  62. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/checks/local.py +0 -0
  63. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/checks/process.py +0 -0
  64. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/checks/tool.py +0 -0
  65. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/checks/types.py +0 -0
  66. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/comparison.py +0 -0
  67. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/eval_dataset.py +0 -0
  68. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/__init__.py +0 -0
  69. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/conformance.py +0 -0
  70. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/errors.py +0 -0
  71. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/models.py +0 -0
  72. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/recorder.py +0 -0
  73. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/sql.py +0 -0
  74. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/sqlite.py +0 -0
  75. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/store.py +0 -0
  76. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/history/transitions.py +0 -0
  77. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/judges/__init__.py +0 -0
  78. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/judges/base.py +0 -0
  79. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/judges/composite.py +0 -0
  80. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/judges/llm.py +0 -0
  81. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/judges/pairwise.py +0 -0
  82. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/judges/reference.py +0 -0
  83. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/judges/trajectory.py +0 -0
  84. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/judges/validation.py +0 -0
  85. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/pairwise.py +0 -0
  86. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/report.py +0 -0
  87. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/runner.py +0 -0
  88. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/splitting.py +0 -0
  89. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/targets/__init__.py +0 -0
  90. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/targets/agent.py +0 -0
  91. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/targets/model.py +0 -0
  92. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/targets/multi_turn.py +0 -0
  93. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/targets/orchestrator.py +0 -0
  94. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/targets/runtime.py +0 -0
  95. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/targets/workflow.py +0 -0
  96. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/types.py +0 -0
  97. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/workbench/__init__.py +0 -0
  98. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/workbench/coordinator.py +0 -0
  99. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/workbench/jobs.py +0 -0
  100. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/workbench/smoke.py +0 -0
  101. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/workbench/smoke_tasks.json +0 -0
  102. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/workbench/suite.py +0 -0
  103. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/eval/workbench/verdict.py +0 -0
  104. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/execution_trace/__init__.py +0 -0
  105. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/execution_trace/collector.py +0 -0
  106. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/execution_trace/models.py +0 -0
  107. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/__init__.py +0 -0
  108. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/_retry_observability.py +0 -0
  109. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/auth.py +0 -0
  110. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/azure/__init__.py +0 -0
  111. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/azure/auth.py +0 -0
  112. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/azure/chat.py +0 -0
  113. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/azure/embedding.py +0 -0
  114. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/azure/settings.py +0 -0
  115. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/azure_openai.py +0 -0
  116. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/azure_openai_embedding.py +0 -0
  117. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/base.py +0 -0
  118. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/embeddings_base.py +0 -0
  119. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/openai/__init__.py +0 -0
  120. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/openai/chat.py +0 -0
  121. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/openai/embedding.py +0 -0
  122. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/openai/settings.py +0 -0
  123. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/openai_embedding.py +0 -0
  124. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/pricing.py +0 -0
  125. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/retry_policy.py +0 -0
  126. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/settings.py +0 -0
  127. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/llm/types.py +0 -0
  128. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/logger.py +0 -0
  129. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/memory/__init__.py +0 -0
  130. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/memory/base.py +0 -0
  131. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/messages.py +0 -0
  132. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/middleware/__init__.py +0 -0
  133. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/middleware/base.py +0 -0
  134. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/middleware/otel.py +0 -0
  135. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/middleware/retry.py +0 -0
  136. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/middleware/sql_usage.py +0 -0
  137. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/middleware/usage_logger.py +0 -0
  138. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/notebook.py +0 -0
  139. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/__init__.py +0 -0
  140. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/base.py +0 -0
  141. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/config.py +0 -0
  142. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/gepa.py +0 -0
  143. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/mipro.py +0 -0
  144. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/pareto.py +0 -0
  145. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/reflective.py +0 -0
  146. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/spec.py +0 -0
  147. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/optim/trace.py +0 -0
  148. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/orchestration/__init__.py +0 -0
  149. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/orchestration/ai.py +0 -0
  150. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/orchestration/handoff.py +0 -0
  151. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/orchestration/plan.py +0 -0
  152. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/orchestration/round_robin.py +0 -0
  153. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/__init__.py +0 -0
  154. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/agents.py +0 -0
  155. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/clients.py +0 -0
  156. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/instruction_registry.py +0 -0
  157. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/instructions/orchestrator.yaml +0 -0
  158. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/instructions/query_rewriter.yaml +0 -0
  159. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/instructions/researcher.yaml +0 -0
  160. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/instructions/reviewer.yaml +0 -0
  161. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/instructions/writer.yaml +0 -0
  162. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/orchestration.py +0 -0
  163. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/skills/contracts-analyst/SKILL.md +0 -0
  164. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/skills/hr-analyst/SKILL.md +0 -0
  165. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/skills/hr-analyst/resources/departments.md +0 -0
  166. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/skills/hr-analyst/resources/employees.md +0 -0
  167. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/skills/hr-analyst/resources/payroll.md +0 -0
  168. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/streaming.py +0 -0
  169. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/presets/workflow.py +0 -0
  170. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/session_store.py +0 -0
  171. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/skills/__init__.py +0 -0
  172. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/skills/base.py +0 -0
  173. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/skills/resources.py +0 -0
  174. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/skills/scripts.py +0 -0
  175. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/skills/sources.py +0 -0
  176. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/skills/validation.py +0 -0
  177. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/__init__.py +0 -0
  178. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/base.py +0 -0
  179. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/cancellation.py +0 -0
  180. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/composite.py +0 -0
  181. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/consecutive_agent.py +0 -0
  182. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/external.py +0 -0
  183. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/function_call.py +0 -0
  184. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/handoff.py +0 -0
  185. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/max_message.py +0 -0
  186. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/predicate.py +0 -0
  187. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/source.py +0 -0
  188. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/text_mention.py +0 -0
  189. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/timeout.py +0 -0
  190. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/termination/token_usage.py +0 -0
  191. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/tools/__init__.py +0 -0
  192. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/tools/base.py +0 -0
  193. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/tools/coding_tools.py +0 -0
  194. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/tools/core_tools.py +0 -0
  195. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/tools/decorator.py +0 -0
  196. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/tools/memory_tool.py +0 -0
  197. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/tools/research_tools.py +0 -0
  198. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/types.py +0 -0
  199. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/__init__.py +0 -0
  200. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/discovery.py +0 -0
  201. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/eval_routes.py +0 -0
  202. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/execution.py +0 -0
  203. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/models.py +0 -0
  204. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/registry.py +0 -0
  205. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/server.py +0 -0
  206. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/session_store.py +0 -0
  207. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/sessions.py +0 -0
  208. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/ui/assets/index-BsS4WYZu.css +0 -0
  209. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/ui/assets/index-tGvO1yue.js +0 -0
  210. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/ui/index.html +0 -0
  211. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/webui/ui/vite.svg +0 -0
  212. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/__init__.py +0 -0
  213. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/core/__init__.py +0 -0
  214. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/core/_structure_hash.py +0 -0
  215. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/core/checkpoint.py +0 -0
  216. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/core/models.py +0 -0
  217. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/core/runner.py +0 -0
  218. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/core/workflow.py +0 -0
  219. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/defaults.py +0 -0
  220. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/errors.py +0 -0
  221. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/loader.py +0 -0
  222. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/schema.py +0 -0
  223. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/schema_utils.py +0 -0
  224. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/sqlite_checkpoint.py +0 -0
  225. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/steps/__init__.py +0 -0
  226. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/steps/agent.py +0 -0
  227. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/steps/echo.py +0 -0
  228. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/steps/function.py +0 -0
  229. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/steps/http.py +0 -0
  230. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/steps/step.py +0 -0
  231. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/steps/subworkflow.py +0 -0
  232. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/steps/transform.py +0 -0
  233. {agentbyte-0.42.4 → agentbyte-0.43.0}/src/agentbyte/workflow/visualizer.py +0 -0
  234. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_as_tool.py +0 -0
  235. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_basic.py +0 -0
  236. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_context_providers.py +0 -0
  237. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_error_response.py +0 -0
  238. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_event_types.py +0 -0
  239. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_memory_integration.py +0 -0
  240. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_middleware_integration.py +0 -0
  241. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_response_accessors.py +0 -0
  242. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_retry_middleware.py +0 -0
  243. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_agent_stream_events.py +0 -0
  244. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_embedding_agent.py +0 -0
  245. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_tool_approval.py +0 -0
  246. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_tool_batch_resolution.py +0 -0
  247. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/agents/test_tool_metadata.py +0 -0
  248. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/cli/test_loading.py +0 -0
  249. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/cli/test_registry_check.py +0 -0
  250. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/compaction/test_compaction.py +0 -0
  251. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/context_providers/__init__.py +0 -0
  252. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/context_providers/test_skill_tools.py +0 -0
  253. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/context_providers/test_skills_provider.py +0 -0
  254. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/dataset/fake_s3.py +0 -0
  255. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/dataset/test_dataset_exit.py +0 -0
  256. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/dataset/test_loader.py +0 -0
  257. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/dataset/test_multi_table.py +0 -0
  258. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/dataset/test_publish.py +0 -0
  259. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/dataset/test_sqlite_db.py +0 -0
  260. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_eval_dataset.py +0 -0
  261. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_eval_history.py +0 -0
  262. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_eval_history_backends.py +0 -0
  263. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_eval_jobs.py +0 -0
  264. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_eval_workbench.py +0 -0
  265. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_execution_trajectories.py +0 -0
  266. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_multi_turn.py +0 -0
  267. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_pairwise.py +0 -0
  268. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_phase1_runner_and_targets.py +0 -0
  269. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_phase2_checks_and_reports.py +0 -0
  270. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_score_integrity.py +0 -0
  271. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_splitting.py +0 -0
  272. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/eval/test_types_and_judges.py +0 -0
  273. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/examples/test_compaction_webapp.py +0 -0
  274. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_azure_client.py +0 -0
  275. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_azure_embedding_client.py +0 -0
  276. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_llm_types.py +0 -0
  277. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_openai_client.py +0 -0
  278. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_openai_embedding_client.py +0 -0
  279. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_pricing.py +0 -0
  280. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_retry_observability.py +0 -0
  281. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_retry_policy_api.py +0 -0
  282. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/llm/test_retryable_error_substrings.py +0 -0
  283. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/memory/test_memory.py +0 -0
  284. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/middleware/test_context_compaction.py +0 -0
  285. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/middleware/test_deduplicate_tool_result.py +0 -0
  286. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/middleware/test_middleware_chain.py +0 -0
  287. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/middleware/test_otel.py +0 -0
  288. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/middleware/test_retry_middleware.py +0 -0
  289. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/middleware/test_sql_usage.py +0 -0
  290. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/middleware/test_usage_logger.py +0 -0
  291. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/__init__.py +0 -0
  292. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_base.py +0 -0
  293. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_base_integration.py +0 -0
  294. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_config.py +0 -0
  295. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_description_tunable.py +0 -0
  296. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_gepa.py +0 -0
  297. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_mipro.py +0 -0
  298. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_orchestrator_optim.py +0 -0
  299. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_pareto.py +0 -0
  300. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_reflective.py +0 -0
  301. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_score_integrity.py +0 -0
  302. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_spec.py +0 -0
  303. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/optim/test_trace.py +0 -0
  304. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_ai_orchestrator.py +0 -0
  305. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_base_orchestrator.py +0 -0
  306. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_handoff_orchestrator.py +0 -0
  307. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_history_tool_call_pairing.py +0 -0
  308. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_orchestration_usage_breakdown.py +0 -0
  309. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_orchestrator_agent_contract.py +0 -0
  310. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_orchestrator_finalization.py +0 -0
  311. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_orchestrator_member_events.py +0 -0
  312. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_orchestrator_otel.py +0 -0
  313. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_plan_orchestrator.py +0 -0
  314. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/orchestration/test_round_robin.py +0 -0
  315. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/presets/test_agents.py +0 -0
  316. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/presets/test_clients.py +0 -0
  317. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/presets/test_instruction_registry.py +0 -0
  318. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/presets/test_orchestration.py +0 -0
  319. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/presets/test_streaming.py +0 -0
  320. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/presets/test_workflow.py +0 -0
  321. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/skills/__init__.py +0 -0
  322. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/skills/test_base.py +0 -0
  323. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/skills/test_resources.py +0 -0
  324. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/skills/test_scripts.py +0 -0
  325. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/skills/test_sources.py +0 -0
  326. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_base.py +0 -0
  327. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_cancellation.py +0 -0
  328. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_composite.py +0 -0
  329. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_consecutive_agent.py +0 -0
  330. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_external.py +0 -0
  331. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_function_call.py +0 -0
  332. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_handoff.py +0 -0
  333. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_max_message.py +0 -0
  334. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_predicate.py +0 -0
  335. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_source.py +0 -0
  336. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_text_mention.py +0 -0
  337. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_timeout.py +0 -0
  338. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/termination/test_token_usage.py +0 -0
  339. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_cancellation_token.py +0 -0
  340. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_context.py +0 -0
  341. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_logger.py +0 -0
  342. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_messages.py +0 -0
  343. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_optional_extras.py +0 -0
  344. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_package_api.py +0 -0
  345. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_session_store.py +0 -0
  346. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_types.py +0 -0
  347. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/test_vanilla_chunker.py +0 -0
  348. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/tools/test_coding_tools.py +0 -0
  349. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/tools/test_memory_tool.py +0 -0
  350. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/tools/test_research_tools.py +0 -0
  351. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/tools/test_tools.py +0 -0
  352. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/__init__.py +0 -0
  353. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/helpers.py +0 -0
  354. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/test_eval_routes.py +0 -0
  355. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/test_execution.py +0 -0
  356. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/test_package_api.py +0 -0
  357. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/test_registry.py +0 -0
  358. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/test_server.py +0 -0
  359. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/test_sessions.py +0 -0
  360. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/webui/test_workflow_streaming.py +0 -0
  361. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/recovery_worker.py +0 -0
  362. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_agent_step_imports.py +0 -0
  363. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_checkpoint.py +0 -0
  364. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_subworkflow_step.py +0 -0
  365. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_workflow_agent.py +0 -0
  366. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_workflow_class.py +0 -0
  367. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_workflow_models.py +0 -0
  368. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_workflow_reliability.py +0 -0
  369. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_workflow_runner.py +0 -0
  370. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_workflow_schema.py +0 -0
  371. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_workflow_steps.py +0 -0
  372. {agentbyte-0.42.4 → agentbyte-0.43.0}/tests/workflow/test_workflow_visualizer.py +0 -0
@@ -6,6 +6,27 @@ The format follows Keep a Changelog principles and semantic versioning.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.43.0] - 2026-10-05
10
+
11
+ ### Added
12
+
13
+ - Agents: `stop_at_tools=[...]` ends the run with `finish_reason="tool_executed"`, without a
14
+ final model call, once a call to a named tool succeeds. Multi-step tool discovery and retries
15
+ after a failed call still run; a failed stop tool does not stop the run; the budget-exhaustion
16
+ finalization still applies. Names are validated against the agent's tools at construction.
17
+ Meant for team specialists whose raw tool results a synthesizer turns into the answer.
18
+ - Orchestration: `AgentHistoryPolicy(window="run")` sends this run's messages in full and
19
+ condenses earlier session turns to each user message plus the answer that closed it (no prior
20
+ tool calls, tool results, or worker notes). Use it as `FinalResultPolicy.synthesis_history` so a
21
+ synthesizer's input stays bounded across follow-up turns without losing their context.
22
+ - Orchestration: workers that end with `max_iterations` / `max_iterations_finalized` are reported to
23
+ the synthesizer as a separate completion fact (partial findings), next to error turns.
24
+
25
+ ### Fixed
26
+
27
+ - Design guide: `summarize_tool_result` was documented as a summarization knob; it actually ends
28
+ the run after the first tool batch. The agent topic now describes it and `stop_at_tools`.
29
+
9
30
  ## [0.42.4] - 2026-10-05
10
31
 
11
32
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentbyte
3
- Version: 0.42.4
3
+ Version: 0.43.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.43.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.43.0**
6
6
 
7
7
  ## Building an Agent
8
8
 
@@ -0,0 +1,2 @@
1
+ __version__ = "0.43.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."""
@@ -51,6 +51,8 @@ _SYNTHESIS_INSTRUCTION = (
51
51
  )
52
52
  _SYNTHESIS_SELECTION_REASON = "Synthesis"
53
53
  _SYNTHESIS_FAILED_FINISH_REASONS = frozenset({"error", "approval_needed", "cancelled"})
54
+ # A worker that hit its iteration budget returned at most a partial result.
55
+ _EXHAUSTED_FINISH_REASONS = frozenset({"max_iterations", "max_iterations_finalized"})
54
56
 
55
57
  # Stop source -> agent finish_reason (spec 0066); every other source, termination
56
58
  # conditions included, maps to "stop".
@@ -128,6 +130,7 @@ class BaseOrchestrator(ABC):
128
130
 
129
131
  # Runtime state
130
132
  self.shared_messages: List[Message] = []
133
+ self._run_start_index = 0
131
134
  self.iteration_count = 0
132
135
  self.start_time: Optional[float] = None
133
136
  self._last_termination_check_count = 0
@@ -154,6 +157,7 @@ class BaseOrchestrator(ABC):
154
157
  self._turn_usage: list[tuple[str, Usage]] = []
155
158
  self._run_task_messages: list[Message] = []
156
159
  self._worker_error_agents: list[str] = []
160
+ self._worker_exhausted_agents: list[str] = []
157
161
  self._synthesis_usage: Usage | None = None
158
162
  self._synthesis_message: Message | None = None
159
163
  self._synthesis_meta: dict[str, Any] | None = None
@@ -307,6 +311,10 @@ class BaseOrchestrator(ABC):
307
311
  # Seed shared_messages from prior session history when context is provided
308
312
  if context is not None and context.messages:
309
313
  self.shared_messages.extend(list(context.messages))
314
+ # Where this run's messages begin; earlier ones are prior session turns.
315
+ self._run_start_index = len(self.shared_messages) - (
316
+ len(initial_messages) if task_in_context else 0
317
+ )
310
318
 
311
319
  # Initialize stop_message
312
320
  stop_message: Optional[StopMessage] = None
@@ -419,6 +427,8 @@ class BaseOrchestrator(ABC):
419
427
  if self._synthesizer is not None:
420
428
  if result.finish_reason == "error":
421
429
  self._worker_error_agents.append(next_agent.name)
430
+ elif result.finish_reason in _EXHAUSTED_FINISH_REASONS:
431
+ self._worker_exhausted_agents.append(next_agent.name)
422
432
  approval_stop = self._get_approval_stop_message(next_agent, result)
423
433
  if approval_stop is not None:
424
434
  # Synthesis cannot resolve a pending approval; stop here.
@@ -888,6 +898,12 @@ class BaseOrchestrator(ABC):
888
898
  "- Worker turns that ended in an error: "
889
899
  + ", ".join(dict.fromkeys(self._worker_error_agents))
890
900
  )
901
+ if self._worker_exhausted_agents:
902
+ facts.append(
903
+ "- Worker turns that ran out of iterations before completing (treat their "
904
+ "findings as partial): "
905
+ + ", ".join(dict.fromkeys(self._worker_exhausted_agents))
906
+ )
891
907
  facts.extend(f"- {fact}" for fact in self._get_synthesis_facts())
892
908
  return (
893
909
  f"Original request:\n{request}\n\n"
@@ -1057,7 +1073,9 @@ class BaseOrchestrator(ABC):
1057
1073
  self._last_context_was_text = False
1058
1074
  self._turn_usage = []
1059
1075
  self._run_task_messages = []
1076
+ self._run_start_index = 0
1060
1077
  self._worker_error_agents = []
1078
+ self._worker_exhausted_agents = []
1061
1079
  self._synthesis_usage = None
1062
1080
  self._synthesis_message = None
1063
1081
  self._synthesis_meta = None
@@ -1260,8 +1278,40 @@ class BaseOrchestrator(ABC):
1260
1278
  """Return the relevant shared-message slice for a history policy."""
1261
1279
  if policy.window == "recent" and policy.message_limit is not None:
1262
1280
  return self._select_recent_messages(policy.message_limit)
1281
+ if policy.window == "run":
1282
+ prior = self.shared_messages[: self._run_start_index]
1283
+ return [
1284
+ *self._condense_prior_turns(prior),
1285
+ *self.shared_messages[self._run_start_index :],
1286
+ ]
1263
1287
  return list(self.shared_messages)
1264
1288
 
1289
+ @staticmethod
1290
+ def _condense_prior_turns(messages: list[Message]) -> list[Message]:
1291
+ """Each earlier turn as its user message(s) plus the answer that closed it.
1292
+
1293
+ The closing answer is the turn's last assistant message with content and
1294
+ no tool calls (for a team with a synthesizer, the synthesized answer).
1295
+ Tool calls, tool results, and intermediate replies are dropped.
1296
+ """
1297
+ condensed: list[Message] = []
1298
+ answer: Message | None = None
1299
+ for message in messages:
1300
+ if isinstance(message, UserMessage):
1301
+ if answer is not None:
1302
+ condensed.append(answer)
1303
+ answer = None
1304
+ condensed.append(message)
1305
+ elif (
1306
+ isinstance(message, AssistantMessage)
1307
+ and message.content
1308
+ and not message.tool_calls
1309
+ ):
1310
+ answer = message
1311
+ if answer is not None:
1312
+ condensed.append(answer)
1313
+ return condensed
1314
+
1265
1315
  def _select_recent_messages(self, message_limit: int) -> list[Message]:
1266
1316
  """Last `message_limit` messages, never splitting a tool-call exchange.
1267
1317
 
@@ -12,7 +12,11 @@ class AgentHistoryPolicy(BaseModel):
12
12
 
13
13
  model_config = ConfigDict(extra="forbid")
14
14
 
15
- window: Literal["full", "recent"]
15
+ window: Literal["full", "recent", "run"]
16
+ """``full``: the whole shared conversation. ``recent``: the last
17
+ ``message_limit`` messages. ``run``: this run's messages in full, with earlier
18
+ turns of the session condensed to each user message and the answer that
19
+ closed its turn (no tool calls, tool results, or intermediate replies)."""
16
20
  message_limit: int | None = None
17
21
  format: Literal["messages", "text", "markdown", "json"]
18
22
  include_turn_prompt: bool = True
@@ -79,6 +79,7 @@ class WorkflowAgent(BaseAgent):
79
79
  self.max_iterations = 1
80
80
  self.output_format = None
81
81
  self.summarize_tool_result = False
82
+ self.stop_at_tools = []
82
83
  self.required_tools = []
83
84
  self.example_tasks = list(workflow.config.metadata.get("example_tasks", []))
84
85
  self.extra_config = {}
@@ -0,0 +1,170 @@
1
+ """``stop_at_tools``: end the run, without a final model call, once a named tool succeeds."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import AsyncGenerator
6
+ from typing import Any
7
+
8
+ import pytest
9
+
10
+ from agentbyte.agents import Agent
11
+ from agentbyte.agents.base import AgentConfigurationError
12
+ from agentbyte.llm.base import BaseChatCompletionClient, BaseChatCompletionClientConfig
13
+ from agentbyte.llm.types import ChatCompletionChunk, ChatCompletionResult
14
+ from agentbyte.messages import AssistantMessage, ToolMessage, Usage, UserMessage
15
+
16
+
17
+ class _Config(BaseChatCompletionClientConfig):
18
+ pass
19
+
20
+
21
+ class FakeModelClient(BaseChatCompletionClient):
22
+ """Returns scripted completions in order."""
23
+
24
+ def __init__(self, responses: list[ChatCompletionResult]) -> None:
25
+ super().__init__(model="fake", client=object())
26
+ self._responses = list(responses)
27
+
28
+ async def create(self, messages, tools=None, output_format=None, **kwargs: Any) -> ChatCompletionResult:
29
+ return self._responses.pop(0)
30
+
31
+ async def create_stream(self, *args: Any, **kwargs: Any) -> AsyncGenerator[ChatCompletionChunk, None]:
32
+ yield ChatCompletionChunk(content="", model="fake", is_complete=True)
33
+
34
+ def _to_config(self) -> BaseChatCompletionClientConfig:
35
+ return _Config(model=self.model, config=self.config)
36
+
37
+ @classmethod
38
+ def _from_config(cls, config: BaseChatCompletionClientConfig) -> FakeModelClient:
39
+ return cls([])
40
+
41
+
42
+ def discover_schema() -> str:
43
+ """Return the table schema."""
44
+ return "orders(id, amount)"
45
+
46
+
47
+ def run_query(sql: str) -> str:
48
+ """Run a read-only SQL query."""
49
+ if sql == "bad":
50
+ raise ValueError("unknown column")
51
+ return "rows: 3"
52
+
53
+
54
+ def _calls(*calls: tuple[str, dict]) -> ChatCompletionResult:
55
+ return ChatCompletionResult(
56
+ message=AssistantMessage(
57
+ content="",
58
+ source="fake",
59
+ tool_calls=[
60
+ {"tool_name": name, "parameters": params, "call_id": f"c-{name}-{i}"}
61
+ for i, (name, params) in enumerate(calls)
62
+ ],
63
+ ),
64
+ usage=Usage(tokens_input=1, tokens_output=1),
65
+ model="fake",
66
+ )
67
+
68
+
69
+ def _answer(text: str) -> ChatCompletionResult:
70
+ return ChatCompletionResult(
71
+ message=AssistantMessage(content=text, source="fake"),
72
+ usage=Usage(tokens_input=1, tokens_output=1),
73
+ model="fake",
74
+ )
75
+
76
+
77
+ def _agent(client: FakeModelClient, **kwargs) -> Agent:
78
+ return Agent(
79
+ name="analyst",
80
+ description="desc",
81
+ instructions="help",
82
+ model_client=client,
83
+ tools=[discover_schema, run_query],
84
+ **kwargs,
85
+ )
86
+
87
+
88
+ @pytest.mark.asyncio
89
+ async def test_stops_after_multi_step_discovery_without_final_answer() -> None:
90
+ client = FakeModelClient(
91
+ [_calls(("discover_schema", {})), _calls(("run_query", {"sql": "ok"}))]
92
+ )
93
+ agent = _agent(client, stop_at_tools=["run_query"])
94
+
95
+ response = await agent.run(UserMessage(content="how many orders?", source="user"))
96
+
97
+ assert response.finish_reason == "tool_executed"
98
+ assert response.usage.llm_calls == 2
99
+ assert response.usage.tool_calls == 2
100
+ last = response.messages[-1]
101
+ assert isinstance(last, ToolMessage)
102
+ assert (last.tool_name, last.success, last.content) == ("run_query", True, "rows: 3")
103
+
104
+
105
+ @pytest.mark.asyncio
106
+ async def test_failed_stop_tool_does_not_stop_so_the_agent_can_retry() -> None:
107
+ client = FakeModelClient(
108
+ [_calls(("run_query", {"sql": "bad"})), _calls(("run_query", {"sql": "ok"}))]
109
+ )
110
+ agent = _agent(client, stop_at_tools=["run_query"])
111
+
112
+ response = await agent.run(UserMessage(content="how many orders?", source="user"))
113
+
114
+ assert response.finish_reason == "tool_executed"
115
+ results = [m for m in response.messages if isinstance(m, ToolMessage)]
116
+ assert [m.success for m in results] == [False, True]
117
+ assert response.usage.llm_calls == 2
118
+
119
+
120
+ @pytest.mark.asyncio
121
+ async def test_stop_tool_in_a_parallel_batch_runs_the_whole_batch() -> None:
122
+ client = FakeModelClient(
123
+ [_calls(("run_query", {"sql": "ok"}), ("discover_schema", {}))]
124
+ )
125
+ agent = _agent(client, stop_at_tools=["run_query"])
126
+
127
+ response = await agent.run(UserMessage(content="q", source="user"))
128
+
129
+ assert response.finish_reason == "tool_executed"
130
+ assert [m.tool_name for m in response.messages if isinstance(m, ToolMessage)] == [
131
+ "run_query",
132
+ "discover_schema",
133
+ ]
134
+
135
+
136
+ @pytest.mark.asyncio
137
+ async def test_without_a_stop_tool_call_the_agent_answers_normally() -> None:
138
+ client = FakeModelClient([_calls(("discover_schema", {})), _answer("no query needed")])
139
+ agent = _agent(client, stop_at_tools=["run_query"])
140
+
141
+ response = await agent.run(UserMessage(content="what tables exist?", source="user"))
142
+
143
+ assert response.finish_reason == "stop"
144
+ assert response.final_content == "no query needed"
145
+
146
+
147
+ @pytest.mark.asyncio
148
+ async def test_stop_tool_never_succeeding_finalizes_on_exhaustion() -> None:
149
+ client = FakeModelClient(
150
+ [
151
+ _calls(("run_query", {"sql": "bad"})),
152
+ _calls(("run_query", {"sql": "bad"})),
153
+ _answer("The query failed: unknown column."),
154
+ ]
155
+ )
156
+ agent = _agent(client, stop_at_tools=["run_query"], max_iterations=3)
157
+
158
+ response = await agent.run(UserMessage(content="q", source="user"))
159
+
160
+ assert response.finish_reason == "max_iterations_finalized"
161
+ assert response.final_content == "The query failed: unknown column."
162
+
163
+
164
+ def test_unknown_stop_tool_is_rejected() -> None:
165
+ with pytest.raises(AgentConfigurationError, match="run_qeury"):
166
+ _agent(FakeModelClient([]), stop_at_tools=["run_qeury"])
167
+
168
+
169
+ def test_stop_at_tools_defaults_to_empty() -> None:
170
+ assert _agent(FakeModelClient([])).stop_at_tools == []
@@ -15,7 +15,13 @@ from agentbyte.context import AgentContext
15
15
  from agentbyte.execution_trace.collector import TraceCollector
16
16
  from agentbyte.llm.base import BaseChatCompletionClient, BaseChatCompletionClientConfig
17
17
  from agentbyte.llm.types import ChatCompletionChunk, ChatCompletionResult
18
- from agentbyte.messages import AssistantMessage, Message, ToolCallRequest, UserMessage
18
+ from agentbyte.messages import (
19
+ AssistantMessage,
20
+ Message,
21
+ ToolCallRequest,
22
+ ToolMessage,
23
+ UserMessage,
24
+ )
19
25
  from agentbyte.orchestration import (
20
26
  AgentHistoryPolicy,
21
27
  AIOrchestrator,
@@ -504,6 +510,89 @@ class TestSynthesisContext:
504
510
  assert "Failed step 1 (hardware): do hardware" in facts
505
511
  assert response.final_content == "final"
506
512
 
513
+ @pytest.mark.parametrize("finish_reason", ["max_iterations", "max_iterations_finalized"])
514
+ async def test_exhausted_worker_is_reported_as_partial(self, finish_reason: str) -> None:
515
+ hardware = ScriptAgent("hardware", "gave up: query kept failing", finish_reason=finish_reason)
516
+ synthesizer = ScriptAgent("synthesizer", "final")
517
+ orchestrator = RoundRobinOrchestrator(
518
+ [hardware, synthesizer], _never(), max_iterations=1, final_result_policy=_policy()
519
+ )
520
+
521
+ await orchestrator.run("task")
522
+
523
+ facts = _text(synthesizer.received_tasks[0])
524
+ assert "ran out of iterations before completing" in facts
525
+ assert "(treat their findings as partial): hardware" in facts
526
+ assert "ended in an error" not in facts
527
+
528
+
529
+ def _prior_turn() -> list[Message]:
530
+ """One completed team turn: question, tool exchange, worker note, answer."""
531
+ return [
532
+ UserMessage(content="old question", source="user"),
533
+ AssistantMessage(
534
+ content="",
535
+ source="hardware",
536
+ tool_calls=[ToolCallRequest(tool_name="scan", parameters={}, call_id="old-1")],
537
+ ),
538
+ ToolMessage(
539
+ content="OLD TOOL PAYLOAD",
540
+ tool_call_id="old-1",
541
+ tool_name="scan",
542
+ success=True,
543
+ source="system",
544
+ ),
545
+ AssistantMessage(content="old intermediate note", source="hardware"),
546
+ AssistantMessage(content="old answer", source="synthesizer"),
547
+ ]
548
+
549
+
550
+ @pytest.mark.asyncio
551
+ class TestRunHistoryWindow:
552
+ async def _synthesis_input(self, window: str, *, task_in_context: bool = False) -> str:
553
+ hardware = ScriptAgent("hardware", "current finding")
554
+ synthesizer = ScriptAgent("synthesizer", "final")
555
+ orchestrator = RoundRobinOrchestrator(
556
+ [hardware, synthesizer],
557
+ _never(),
558
+ max_iterations=1,
559
+ final_result_policy=_policy(
560
+ synthesis_history=AgentHistoryPolicy(window=window, format="text")
561
+ ),
562
+ )
563
+ context = AgentContext(messages=_prior_turn())
564
+ if task_in_context:
565
+ context.messages.append(UserMessage(content="new question", source="user"))
566
+ await orchestrator.run(context=context)
567
+ else:
568
+ await orchestrator.run("new question", context=context)
569
+ return _text(synthesizer.received_tasks[0])
570
+
571
+ @pytest.mark.parametrize("task_in_context", [False, True])
572
+ async def test_run_window_keeps_this_run_and_condenses_prior_turns(
573
+ self, task_in_context: bool
574
+ ) -> None:
575
+ seen = await self._synthesis_input("run", task_in_context=task_in_context)
576
+
577
+ assert "old question" in seen
578
+ assert "old answer" in seen
579
+ assert "new question" in seen
580
+ assert "current finding" in seen
581
+ assert "OLD TOOL PAYLOAD" not in seen
582
+ assert "old intermediate note" not in seen
583
+ assert seen.index("old answer") < seen.index("current finding")
584
+
585
+ async def test_full_window_still_sends_prior_tool_results(self) -> None:
586
+ seen = await self._synthesis_input("full")
587
+
588
+ assert "OLD TOOL PAYLOAD" in seen
589
+ assert "old intermediate note" in seen
590
+
591
+ async def test_run_window_needs_no_message_limit(self) -> None:
592
+ policy = AgentHistoryPolicy(window="run", message_limit=3, format="text")
593
+
594
+ assert policy.message_limit is None
595
+
507
596
 
508
597
  @pytest.mark.asyncio
509
598
  class TestTerminalOutcomes:
@@ -1,2 +0,0 @@
1
- __version__ = "0.42.4"
2
- VERSION = __version__
File without changes
File without changes
File without changes