agentbyte 0.4.7__tar.gz → 0.5.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 (281) hide show
  1. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-ai-driven-orchestration/SKILL.md +113 -20
  2. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-dataset/SKILL.md +69 -10
  3. agentbyte-0.5.0/.github/skills/agentbyte-handoff-orchestration/SKILL.md +246 -0
  4. agentbyte-0.5.0/.github/skills/agentbyte-multi-turn-context/SKILL.md +135 -0
  5. agentbyte-0.5.0/.github/skills/agentbyte-otel-tracing/SKILL.md +109 -0
  6. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-plan-based-orchestration/SKILL.md +58 -11
  7. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-round-robin-orchestration/SKILL.md +71 -16
  8. agentbyte-0.5.0/.github/skills/agentbyte-workflow/SKILL.md +157 -0
  9. {agentbyte-0.4.7 → agentbyte-0.5.0}/.gitignore +5 -0
  10. {agentbyte-0.4.7 → agentbyte-0.5.0}/CHANGELOG.md +36 -0
  11. agentbyte-0.4.7/README.md → agentbyte-0.5.0/PKG-INFO +80 -2
  12. agentbyte-0.4.7/PKG-INFO → agentbyte-0.5.0/README.md +24 -39
  13. {agentbyte-0.4.7 → agentbyte-0.5.0}/pyproject.toml +30 -0
  14. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/__about__.py +1 -1
  15. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/__init__.py +33 -10
  16. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/context.py +16 -0
  17. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/dataset/__init__.py +48 -41
  18. agentbyte-0.5.0/src/agentbyte/dataset/config.py +116 -0
  19. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/dataset/json.py +10 -12
  20. agentbyte-0.5.0/src/agentbyte/dataset/loader.py +83 -0
  21. agentbyte-0.5.0/src/agentbyte/dataset/sources.py +205 -0
  22. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/dataset/sqlite.py +18 -18
  23. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/__init__.py +3 -0
  24. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/azure/chat.py +36 -90
  25. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/azure/embedding.py +35 -49
  26. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/base.py +4 -2
  27. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/openai/chat.py +30 -90
  28. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/openai/embedding.py +29 -49
  29. agentbyte-0.5.0/src/agentbyte/llm/retry_policy.py +130 -0
  30. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/orchestration/__init__.py +12 -0
  31. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/orchestration/ai.py +83 -32
  32. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/orchestration/base.py +153 -7
  33. agentbyte-0.5.0/src/agentbyte/orchestration/handoff.py +341 -0
  34. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/orchestration/plan.py +183 -31
  35. agentbyte-0.5.0/src/agentbyte/orchestration/policies.py +81 -0
  36. agentbyte-0.5.0/src/agentbyte/orchestration/round_robin.py +84 -0
  37. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/presets/agents.py +12 -2
  38. agentbyte-0.5.0/src/agentbyte/presets/orchestration.py +216 -0
  39. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/presets/workflow.py +4 -4
  40. agentbyte-0.5.0/src/agentbyte/session_store.py +195 -0
  41. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/__init__.py +12 -6
  42. agentbyte-0.5.0/src/agentbyte/termination/consecutive_agent.py +89 -0
  43. agentbyte-0.5.0/src/agentbyte/termination/predicate.py +58 -0
  44. agentbyte-0.5.0/src/agentbyte/termination/source.py +54 -0
  45. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/__init__.py +8 -1
  46. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/execution.py +12 -7
  47. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/models.py +1 -0
  48. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/server.py +3 -2
  49. agentbyte-0.5.0/src/agentbyte/webui/session_store.py +15 -0
  50. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/sessions.py +3 -20
  51. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/__init__.py +57 -6
  52. agentbyte-0.5.0/src/agentbyte/workflow/agent.py +440 -0
  53. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/core/__init__.py +10 -4
  54. agentbyte-0.5.0/src/agentbyte/workflow/core/_structure_hash.py +55 -0
  55. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/core/checkpoint.py +9 -39
  56. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/core/models.py +311 -12
  57. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/core/runner.py +588 -55
  58. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/core/workflow.py +44 -27
  59. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/defaults.py +2 -2
  60. agentbyte-0.5.0/src/agentbyte/workflow/loader.py +276 -0
  61. agentbyte-0.5.0/src/agentbyte/workflow/schema.py +340 -0
  62. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/steps/__init__.py +4 -2
  63. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/steps/agentbyte_agent.py +12 -7
  64. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/steps/echo.py +2 -2
  65. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/steps/function.py +2 -2
  66. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/steps/http.py +2 -2
  67. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/steps/step.py +48 -6
  68. agentbyte-0.5.0/src/agentbyte/workflow/steps/subworkflow.py +309 -0
  69. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/steps/transform.py +2 -2
  70. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/cli/test_create_skills.py +2 -0
  71. agentbyte-0.5.0/tests/dataset/test_loader.py +200 -0
  72. agentbyte-0.5.0/tests/llm/test_retry_policy_api.py +120 -0
  73. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/orchestration/test_ai_orchestrator.py +119 -25
  74. agentbyte-0.5.0/tests/orchestration/test_handoff_orchestrator.py +444 -0
  75. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/orchestration/test_plan_orchestrator.py +242 -14
  76. agentbyte-0.5.0/tests/orchestration/test_round_robin.py +234 -0
  77. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/presets/test_agents.py +15 -1
  78. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/presets/test_orchestration.py +22 -44
  79. agentbyte-0.5.0/tests/termination/test_consecutive_agent.py +96 -0
  80. agentbyte-0.5.0/tests/termination/test_predicate.py +63 -0
  81. agentbyte-0.5.0/tests/termination/test_source.py +65 -0
  82. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/test_context.py +52 -0
  83. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/test_package_api.py +85 -10
  84. agentbyte-0.5.0/tests/test_session_store.py +131 -0
  85. agentbyte-0.5.0/tests/webui/test_sessions.py +104 -0
  86. agentbyte-0.5.0/tests/workflow/test_checkpoint.py +461 -0
  87. agentbyte-0.5.0/tests/workflow/test_subworkflow_step.py +438 -0
  88. agentbyte-0.5.0/tests/workflow/test_workflow_agent.py +305 -0
  89. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/workflow/test_workflow_class.py +22 -1
  90. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/workflow/test_workflow_models.py +44 -5
  91. agentbyte-0.5.0/tests/workflow/test_workflow_runner.py +1376 -0
  92. agentbyte-0.5.0/tests/workflow/test_workflow_schema.py +468 -0
  93. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/workflow/test_workflow_steps.py +7 -7
  94. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/workflow/test_workflow_visualizer.py +3 -3
  95. agentbyte-0.4.7/.github/skills/agentbyte-multi-turn-context/SKILL.md +0 -34
  96. agentbyte-0.4.7/.github/skills/agentbyte-otel-tracing/SKILL.md +0 -42
  97. agentbyte-0.4.7/src/agentbyte/dataset/loader.py +0 -101
  98. agentbyte-0.4.7/src/agentbyte/orchestration/round_robin.py +0 -137
  99. agentbyte-0.4.7/src/agentbyte/presets/orchestration.py +0 -304
  100. agentbyte-0.4.7/src/agentbyte/session.py +0 -121
  101. agentbyte-0.4.7/src/agentbyte/webui/session_store.py +0 -63
  102. agentbyte-0.4.7/tests/orchestration/test_round_robin.py +0 -156
  103. agentbyte-0.4.7/tests/test_session.py +0 -156
  104. agentbyte-0.4.7/tests/workflow/test_checkpoint.py +0 -184
  105. agentbyte-0.4.7/tests/workflow/test_workflow_runner.py +0 -518
  106. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-agent-as-tool/SKILL.md +0 -0
  107. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-function-tools/SKILL.md +0 -0
  108. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-list-memory/SKILL.md +0 -0
  109. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-llm-client/SKILL.md +0 -0
  110. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-memory-tool/SKILL.md +0 -0
  111. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-middleware/SKILL.md +0 -0
  112. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-simple-agent/SKILL.md +0 -0
  113. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/agentbyte-tool-approval/SKILL.md +0 -0
  114. {agentbyte-0.4.7 → agentbyte-0.5.0}/.github/skills/skill-authoring/SKILL.md +0 -0
  115. {agentbyte-0.4.7 → agentbyte-0.5.0}/LICENSE +0 -0
  116. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/agents/__init__.py +0 -0
  117. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/agents/agent.py +0 -0
  118. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/agents/agent_as_tool.py +0 -0
  119. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/agents/base.py +0 -0
  120. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/agents/types.py +0 -0
  121. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/cancellation_token.py +0 -0
  122. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/cli/__init__.py +0 -0
  123. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/cli/main.py +0 -0
  124. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/component.py +0 -0
  125. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/dataset/base.py +0 -0
  126. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/dataset/loaders.py +0 -0
  127. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/entity.py +0 -0
  128. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/_retry_observability.py +0 -0
  129. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/auth.py +0 -0
  130. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/azure/__init__.py +0 -0
  131. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/azure/auth.py +0 -0
  132. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/azure/settings.py +0 -0
  133. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/azure_openai.py +0 -0
  134. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/azure_openai_embedding.py +0 -0
  135. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/embeddings_base.py +0 -0
  136. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/openai/__init__.py +0 -0
  137. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/openai/settings.py +0 -0
  138. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/openai.py +0 -0
  139. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/openai_embedding.py +0 -0
  140. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/pricing.py +0 -0
  141. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/settings.py +0 -0
  142. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/llm/types.py +0 -0
  143. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/memory/__init__.py +0 -0
  144. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/memory/base.py +0 -0
  145. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/messages.py +0 -0
  146. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/middleware/__init__.py +0 -0
  147. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/middleware/base.py +0 -0
  148. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/middleware/otel.py +0 -0
  149. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/middleware/retry.py +0 -0
  150. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/notebook.py +0 -0
  151. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/presets/__init__.py +0 -0
  152. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/presets/clients.py +0 -0
  153. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/base.py +0 -0
  154. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/cancellation.py +0 -0
  155. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/composite.py +0 -0
  156. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/external.py +0 -0
  157. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/function_call.py +0 -0
  158. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/handoff.py +0 -0
  159. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/max_message.py +0 -0
  160. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/text_mention.py +0 -0
  161. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/timeout.py +0 -0
  162. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/termination/token_usage.py +0 -0
  163. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/tools/__init__.py +0 -0
  164. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/tools/base.py +0 -0
  165. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/tools/core_tools.py +0 -0
  166. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/tools/decorator.py +0 -0
  167. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/tools/memory_tool.py +0 -0
  168. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/types.py +0 -0
  169. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/agent_framework_devui/ui/assets/index-BzhEszHZ.css +0 -0
  170. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/agent_framework_devui/ui/assets/index-DByFJNGD.js +0 -0
  171. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/agent_framework_devui/ui/index.html +0 -0
  172. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/agent_framework_devui/ui/vite.svg +0 -0
  173. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/discovery.py +0 -0
  174. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/.gitignore +0 -0
  175. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/README.md +0 -0
  176. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/components.json +0 -0
  177. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/eslint.config.js +0 -0
  178. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/index.html +0 -0
  179. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/package.json +0 -0
  180. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/plan.md +0 -0
  181. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/public/vite.svg +0 -0
  182. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/App.css +0 -0
  183. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/App.tsx +0 -0
  184. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/assets/react.svg +0 -0
  185. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/agent/agent-view.tsx +0 -0
  186. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/message_renderer/ContentRenderer.tsx +0 -0
  187. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/message_renderer/MessageRenderer.tsx +0 -0
  188. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/message_renderer/index.ts +0 -0
  189. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/message_renderer/types.ts +0 -0
  190. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/mode-toggle.tsx +0 -0
  191. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/orchestrator/orchestrator-view.tsx +0 -0
  192. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/app-header.tsx +0 -0
  193. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/chat-base.tsx +0 -0
  194. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/context-inspector.tsx +0 -0
  195. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/debug-panel.tsx +0 -0
  196. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/entity-selector.tsx +0 -0
  197. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/example-tasks-display.tsx +0 -0
  198. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/examples-gallery.tsx +0 -0
  199. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/session-switcher.tsx +0 -0
  200. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/shared/tool-approval-banner.tsx +0 -0
  201. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/theme-provider.tsx +0 -0
  202. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/attachment-gallery.tsx +0 -0
  203. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/badge.tsx +0 -0
  204. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/button.tsx +0 -0
  205. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/card.tsx +0 -0
  206. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/dialog.tsx +0 -0
  207. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/dropdown-menu.tsx +0 -0
  208. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/file-upload.tsx +0 -0
  209. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/input.tsx +0 -0
  210. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/label.tsx +0 -0
  211. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/loading-spinner.tsx +0 -0
  212. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/loading-state.tsx +0 -0
  213. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/message-input.tsx +0 -0
  214. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/scroll-area.tsx +0 -0
  215. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/slider.tsx +0 -0
  216. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/tabs.tsx +0 -0
  217. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/ui/textarea.tsx +0 -0
  218. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/components/workflow/workflow-view.tsx +0 -0
  219. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/hooks/messageHandlers.ts +0 -0
  220. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/hooks/useEntityExecution.ts +0 -0
  221. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/index.css +0 -0
  222. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/main.tsx +0 -0
  223. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/services/api.ts +0 -0
  224. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/types/index.ts +0 -0
  225. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/types/picoagents.ts +0 -0
  226. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/utils/message-utils.ts +0 -0
  227. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/src/vite-env.d.ts +0 -0
  228. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/tsconfig.app.json +0 -0
  229. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/tsconfig.json +0 -0
  230. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/tsconfig.node.json +0 -0
  231. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/vite.config.ts +0 -0
  232. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/frontend/yarn.lock +0 -0
  233. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/registry.py +0 -0
  234. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/ui/assets/index-CWk64UM3.js +0 -0
  235. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/ui/assets/index-vt1cujlT.css +0 -0
  236. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/ui/index.html +0 -0
  237. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/webui/ui/vite.svg +0 -0
  238. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/schema_utils.py +0 -0
  239. {agentbyte-0.4.7 → agentbyte-0.5.0}/src/agentbyte/workflow/visualizer.py +0 -0
  240. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/agents/test_agent_as_tool.py +0 -0
  241. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/agents/test_agent_basic.py +0 -0
  242. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/agents/test_agent_event_types.py +0 -0
  243. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/agents/test_agent_memory_integration.py +0 -0
  244. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/agents/test_agent_middleware_integration.py +0 -0
  245. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/agents/test_agent_retry_middleware.py +0 -0
  246. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/agents/test_agent_stream_events.py +0 -0
  247. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/agents/test_tool_approval.py +0 -0
  248. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/llm/test_azure_client.py +0 -0
  249. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/llm/test_azure_embedding_client.py +0 -0
  250. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/llm/test_llm_types.py +0 -0
  251. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/llm/test_openai_client.py +0 -0
  252. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/llm/test_openai_embedding_client.py +0 -0
  253. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/llm/test_retry_observability.py +0 -0
  254. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/memory/test_memory.py +0 -0
  255. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/middleware/test_middleware_chain.py +0 -0
  256. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/middleware/test_otel.py +0 -0
  257. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/middleware/test_retry_middleware.py +0 -0
  258. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/orchestration/test_base_orchestrator.py +0 -0
  259. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/presets/test_clients.py +0 -0
  260. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/presets/test_workflow.py +0 -0
  261. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_base.py +0 -0
  262. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_cancellation.py +0 -0
  263. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_composite.py +0 -0
  264. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_external.py +0 -0
  265. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_function_call.py +0 -0
  266. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_handoff.py +0 -0
  267. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_max_message.py +0 -0
  268. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_text_mention.py +0 -0
  269. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_timeout.py +0 -0
  270. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/termination/test_token_usage.py +0 -0
  271. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/test_cancellation_token.py +0 -0
  272. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/test_messages.py +0 -0
  273. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/test_types.py +0 -0
  274. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/tools/test_memory_tool.py +0 -0
  275. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/tools/test_tools.py +0 -0
  276. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/webui/__init__.py +0 -0
  277. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/webui/helpers.py +0 -0
  278. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/webui/test_execution.py +0 -0
  279. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/webui/test_package_api.py +0 -0
  280. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/webui/test_registry.py +0 -0
  281. {agentbyte-0.4.7 → agentbyte-0.5.0}/tests/webui/test_server.py +0 -0
@@ -6,13 +6,32 @@ license: MIT
6
6
 
7
7
  Use this skill when implementing multi-agent collaboration where an LLM intelligently selects which agent should respond next based on conversation context and agent capabilities.
8
8
 
9
+ ## Inputs to confirm
10
+ - Which agents are available and how clearly their descriptions express specialization
11
+ - What should stop the orchestration
12
+ - Whether the selector should see a compact summary or a richer selector context
13
+ - Whether worker agents should receive full history or a narrower execution history
14
+
9
15
  ## Pattern: Basic AI-Driven Orchestration
10
16
 
11
17
  ```python
12
18
  import asyncio
13
- from agentbyte import AIOrchestrator, Agent, UserMessage
19
+ from agentbyte import (
20
+ AIOrchestrator,
21
+ Agent,
22
+ AgentHistoryPolicy,
23
+ HistoryContextPolicy,
24
+ SelectorContextPolicy,
25
+ UserMessage,
26
+ )
14
27
  from agentbyte.llm import OpenAIChatCompletionClient
15
- from agentbyte.termination import MaxMessageTermination, TextMentionTermination
28
+ from agentbyte.termination import (
29
+ ConsecutiveAgentTermination,
30
+ MaxMessageTermination,
31
+ PredicateTermination,
32
+ SourceTermination,
33
+ TextMentionTermination,
34
+ )
16
35
 
17
36
  async def main():
18
37
  # 1. Create model client
@@ -40,14 +59,28 @@ async def main():
40
59
  )
41
60
 
42
61
  # 3. Define termination conditions
43
- termination = MaxMessageTermination(8) | TextMentionTermination("TERMINATE")
62
+ # ConsecutiveAgentTermination guards against the selector routing to the same
63
+ # agent repeatedly — the most common failure mode in AI-driven orchestration
64
+ termination = (
65
+ ConsecutiveAgentTermination(max_consecutive=3)
66
+ | TextMentionTermination("TERMINATE")
67
+ | MaxMessageTermination(8)
68
+ )
44
69
 
45
70
  # 4. Initialize AI orchestrator (requires model_client for selection)
46
71
  orchestrator = AIOrchestrator(
47
72
  agents=[researcher, writer],
48
73
  termination=termination,
49
74
  model_client=client, # Required: LLM for agent selection
50
- max_iterations=6
75
+ max_iterations=6,
76
+ history_policy=HistoryContextPolicy(
77
+ default=AgentHistoryPolicy(window="full", format="text")
78
+ ),
79
+ selector_policy=SelectorContextPolicy(
80
+ window="recent",
81
+ message_limit=12,
82
+ format="summary",
83
+ ),
51
84
  )
52
85
 
53
86
  # 5. Run the collaboration
@@ -87,25 +120,47 @@ async for item in orchestrator.run_stream(task, verbose=True):
87
120
  3. **Reasoning Included:** Selection events include the LLM's reasoning for why it chose that agent
88
121
  4. **Fallback Safety:** If LLM selection fails or returns invalid agent name, falls back to round-robin
89
122
 
90
- ## Configuration Options
123
+ ## Policy Surface
91
124
 
92
125
  ```python
93
126
  orchestrator = AIOrchestrator(
94
- agents=[agent1, agent2, agent3], # Required: List of agents
95
- termination=termination_condition, # Required: When to stop
96
- model_client=selection_model_client, # Required: LLM for agent selection
97
- max_iterations=10, # Optional: Safety limit (default: 10)
98
- verbose=False # Optional: Enable event logging
127
+ agents=[agent1, agent2, agent3],
128
+ termination=termination_condition,
129
+ model_client=selection_model_client,
130
+ max_iterations=10,
131
+ history_policy=HistoryContextPolicy(
132
+ default=AgentHistoryPolicy(window="full", format="text")
133
+ ),
134
+ selector_policy=SelectorContextPolicy(
135
+ window="recent",
136
+ message_limit=12,
137
+ format="summary",
138
+ ),
99
139
  )
100
140
  ```
101
141
 
142
+ Use the two policies for different jobs:
143
+ - `HistoryContextPolicy`: contains a default `AgentHistoryPolicy` plus optional per-agent `AgentHistoryPolicy` overrides for worker execution
144
+ - `SelectorContextPolicy`: controls what the selector model sees when deciding which agent should go next
145
+
146
+ `AgentHistoryPolicy` is the per-agent rule that actually defines:
147
+ - `window`
148
+ - `message_limit`
149
+ - `format`
150
+ - `include_turn_prompt`
151
+
152
+ Selector formatting affects routing quality:
153
+ - `summary` is compact and best for many coordination tasks
154
+ - `markdown` can help readability on long transcripts
155
+ - `json` can help when explicit role/source/content structure matters
156
+
102
157
  ## Pattern Metadata
103
158
 
104
159
  After completion, `result.pattern_metadata` contains:
105
160
  - `iterations_completed`: Total agent executions
106
161
  - `selector_calls`: Number of LLM selection calls made
107
- - `fallback_count`: How many times round-robin fallback was used
108
- - `final_reason`: Why orchestration stopped
162
+ - `selector_model`: Model used for routing
163
+ - `selector_policy`: Serialized selector-context configuration
109
164
 
110
165
  ## Usage Tracking
111
166
 
@@ -132,12 +187,56 @@ description="A helpful agent" # Too vague
132
187
  description="Agent 1" # No capability info
133
188
  ```
134
189
 
190
+ ## Termination Conditions
191
+
192
+ | Termination Type | Purpose | AI-Driven relevance |
193
+ |-----------------|---------|---------------------|
194
+ | `ConsecutiveAgentTermination(n)` | Stop when same agent selected n times in a row | **Primary loop guard** — always include |
195
+ | `MaxMessageTermination(n)` | Stop after n messages | Hard safety cap |
196
+ | `TextMentionTermination("X")` | Stop when any agent says X | Semantic completion signal |
197
+ | `SourceTermination("name")` | Stop when a specific agent speaks | Phase-transition stop (e.g. reviewer responded) |
198
+ | `PredicateTermination(fn)` | Stop on any custom callable condition | Custom quality or content checks |
199
+ | `TimeoutTermination(sec)` | Stop after elapsed time | Latency-sensitive systems |
200
+ | `TokenUsageTermination(n)` | Stop after n tokens | Cost control |
201
+
202
+ ### Recommended baseline for AI-driven orchestration
203
+
204
+ ```python
205
+ termination = (
206
+ ConsecutiveAgentTermination(max_consecutive=3) # loop guard
207
+ | TextMentionTermination("TERMINATE") # semantic stop
208
+ | MaxMessageTermination(12) # hard cap
209
+ )
210
+ ```
211
+
212
+ ### When the workflow ends when a specific agent has responded
213
+
214
+ ```python
215
+ # Stop as soon as the reviewer speaks
216
+ termination = SourceTermination("reviewer") | MaxMessageTermination(10)
217
+
218
+ # Stop only when the reviewer approves in the same message
219
+ termination = (
220
+ PredicateTermination(
221
+ lambda msgs: any(
222
+ getattr(m, "source", None) == "reviewer"
223
+ and "APPROVED" in str(getattr(m, "content", ""))
224
+ for m in msgs
225
+ ),
226
+ reason="Reviewer approved",
227
+ )
228
+ | ConsecutiveAgentTermination(max_consecutive=3)
229
+ | MaxMessageTermination(12)
230
+ )
231
+ ```
232
+
135
233
  ## Guardrails
136
234
 
137
235
  - **Model Client Required:** `AIOrchestrator` needs a `model_client` parameter for agent selection (unlike `RoundRobinOrchestrator`).
138
236
  - **Clear Descriptions:** Write specific agent descriptions—the LLM uses these to decide who should respond.
139
- - **Termination Required:** Always provide termination conditions to prevent infinite loops.
140
- - **Safety Fallback:** If LLM selection fails, orchestrator falls back to round-robin (check `fallback_count` in metadata).
237
+ - **Two Context Surfaces:** Do not confuse `history_policy` with `selector_policy`; one shapes execution, the other shapes routing.
238
+ - **Termination Required:** Always provide termination conditions to prevent infinite loops. Include `ConsecutiveAgentTermination` repeated same-agent selection is the most common AI-driven failure mode.
239
+ - **Safety Fallback:** If LLM selection fails, the orchestrator falls back to round-robin selection to preserve forward progress.
141
240
  - **Usage Accounting:** Final usage includes both agent tokens AND selector tokens.
142
241
  - **Case Insensitive:** Agent name matching is case-insensitive for robustness.
143
242
  - **Event Observability:** Use `verbose=True` with `run_stream()` to see AI selection reasoning.
@@ -160,12 +259,6 @@ description="Agent 1" # No capability info
160
259
  4. **Dynamic Collaboration:** Agents with overlapping capabilities—LLM picks best fit
161
260
  5. **Question Routing:** Route user questions to the most appropriate agent based on content
162
261
 
163
- ## Examples
164
-
165
- - Basic: `examples/orchestration/ai_driven_basic.py`
166
- - Streaming: `examples/orchestration/ai_driven_stream.py`
167
- - With OTel: `examples/orchestration/ai_driven_with_otel.py`
168
-
169
262
  ## OpenTelemetry Integration
170
263
 
171
264
  For observability with Jaeger:
@@ -6,13 +6,16 @@ description: Guide for creating and using Agentbyte datasets with SQLite or JSON
6
6
  Use this skill when you need to:
7
7
  - **Load** an existing dataset using `load_dataset()`
8
8
  - **Create** a new dataset with config.json, schema.json, and data.json
9
+ - **Load** the same dataset structure from local disk or S3
9
10
  - **Query** SQLite datasets with SQL or iterate JSON datasets
10
11
  - **Display** dataset schemas in pretty or raw format
11
12
  - **Work with** multiple data engines (SQLite for structured, JSON for semi-structured)
12
13
 
13
14
  ## Dataset Architecture
14
15
 
15
- Agentbyte datasets are file-based and engine-agnostic. Each dataset lives in `data/samples/{category}/{name}/` with three files:
16
+ Agentbyte datasets are file-based and engine-agnostic. The dataset contract stays the same whether the files live on local disk or in S3.
17
+
18
+ Local layout:
16
19
 
17
20
  ### File Structure
18
21
  ```
@@ -22,6 +25,14 @@ data/samples/{category}/{name}/
22
25
  └── data.json # Records only ({"records": [...]})
23
26
  ```
24
27
 
28
+ Equivalent S3 layout:
29
+ ```
30
+ s3://<bucket>/<optional-prefix>/{category}/{name}/
31
+ ├── config.json
32
+ ├── schema.json
33
+ └── data.json
34
+ ```
35
+
25
36
  ### Supported Engines
26
37
  - **sqlite** (default): Structured data with SQL queries, strict schema, constraints
27
38
  - **json**: Semi-structured data, flexible JSON format, inferred schema
@@ -92,11 +103,23 @@ with open(dataset_dir / "data.json", "w") as f:
92
103
 
93
104
  ### Load a Dataset
94
105
  ```python
95
- from agentbyte.dataset import load_dataset
106
+ from pathlib import Path
96
107
 
97
- ds = load_dataset("category/name") # Returns SQLiteDataset or JSONDataset
108
+ from agentbyte.dataset import LocalDatasetConfig, S3DatasetConfig, load_dataset
109
+
110
+ # Local source
111
+ local_config = LocalDatasetConfig(local_root=Path("data/samples"))
112
+ ds = load_dataset("category/name", local_config) # Returns SQLiteDataset or JSONDataset
98
113
  print(ds.engine) # "sqlite" or "json"
99
114
  print(ds.table_name) # Table/collection name
115
+
116
+ # S3 source
117
+ s3_config = S3DatasetConfig(
118
+ s3_bucket="datapsycho-datasets",
119
+ s3_region="eu-west-1",
120
+ s3_prefix="datasets",
121
+ )
122
+ ds_s3 = load_dataset("category/name", s3_config)
100
123
  ```
101
124
 
102
125
  ### Connect & Get Data
@@ -134,9 +157,11 @@ ds.schema.show(format=SchemaFormat.RAW)
134
157
 
135
158
  ### Example 1: Load & Query Existing SQLite Dataset
136
159
  ```python
137
- from agentbyte.dataset import load_dataset
160
+ from pathlib import Path
138
161
 
139
- ds = load_dataset("contracts/asmd")
162
+ from agentbyte.dataset import LocalDatasetConfig, load_dataset
163
+
164
+ ds = load_dataset("contracts/asmd", LocalDatasetConfig(local_root=Path("data/samples")))
140
165
  conn = ds.connect()
141
166
 
142
167
  # Display schema
@@ -153,7 +178,11 @@ for row in active:
153
178
 
154
179
  ### Example 2: Load & Iterate JSON Dataset
155
180
  ```python
156
- ds = load_dataset("documents/wiki") # engine="json" in config
181
+ from pathlib import Path
182
+
183
+ from agentbyte.dataset import LocalDatasetConfig, load_dataset
184
+
185
+ ds = load_dataset("documents/wiki", LocalDatasetConfig(local_root=Path("data/samples")))
157
186
  data = ds.connect() # dict with {"records": [...]}
158
187
 
159
188
  for i, record in enumerate(data["records"], 1):
@@ -163,13 +192,31 @@ for i, record in enumerate(data["records"], 1):
163
192
  ### Example 3: Create Dataset Programmatically
164
193
  See "Creating a Dataset" section above for step-by-step code.
165
194
 
195
+ ### Example 4: Load From S3
196
+ ```python
197
+ from agentbyte.dataset import S3DatasetConfig, load_dataset
198
+
199
+ s3_config = S3DatasetConfig(
200
+ s3_bucket="datapsycho-datasets",
201
+ s3_region="eu-west-1",
202
+ s3_prefix="datasets",
203
+ )
204
+
205
+ ds = load_dataset("contracts10/asmd", s3_config)
206
+ conn = ds.connect()
207
+ rows = conn.execute("SELECT * FROM contracts_asmd").fetchall()
208
+ ```
209
+
166
210
  ## Guardrails
167
211
 
168
- - **Do** use relative paths from project root in `load_dataset()` (e.g., `"contracts/asmd"`, not full file paths).
212
+ - **Do** use canonical dataset IDs in `load_dataset()` (e.g., `"contracts/asmd"`, not full file paths).
213
+ - **Do** pass a source config object to `load_dataset()` (`LocalDatasetConfig` or `S3DatasetConfig`).
214
+ - **Do** keep `dataset_id` logical (`"category/name"`) and configure S3 location through `S3DatasetConfig`.
169
215
  - **Do** keep schema.json separate from data.json for clarity and reusability.
170
216
  - **Do** use `dict(row)` to convert sqlite3.Row objects to dicts for JSON serialization.
171
217
  - **Do** call `ds.connect()` only once; it caches the connection and schema on first call.
172
218
  - **Don't** hard-code values in datasets (use config.json for metadata).
219
+ - **Don't** store bucket names or S3 prefixes inside `config.json`.
173
220
  - **Don't** forget `.json` extensions for all three files.
174
221
  - **Don't** put schema definitions inside data.json (separate files for clarity).
175
222
  - **Don't** assume JSON datasets support SQL—use dict iteration instead.
@@ -178,9 +225,19 @@ See "Creating a Dataset" section above for step-by-step code.
178
225
 
179
226
  ### Factory Function
180
227
  ```python
181
- load_dataset(dataset_id: str) -> BaseDataset
228
+ load_dataset(
229
+ dataset_id: str,
230
+ config: DatasetSourceConfig,
231
+ ) -> BaseDataset
182
232
  ```
183
- Loads dataset from `data/samples/{category}/{name}/`. Returns `SQLiteDataset` or `JSONDataset` based on config.engine.
233
+ Loads dataset using the provided source config (`LocalDatasetConfig` or
234
+ `S3DatasetConfig`). Returns `SQLiteDataset` or `JSONDataset` based on
235
+ `config.engine`.
236
+
237
+ ### Source Config Types
238
+ - **DatasetSourceConfig**: Abstract config contract
239
+ - **LocalDatasetConfig**: Local source config with `local_root`
240
+ - **S3DatasetConfig**: S3 source config with `s3_bucket`, `s3_region`, `s3_prefix`
184
241
 
185
242
  ### Classes (Generic)
186
243
  - **Column**: name (str), type (str)
@@ -203,6 +260,8 @@ Loads dataset from `data/samples/{category}/{name}/`. Returns `SQLiteDataset` or
203
260
  |-------|-----|
204
261
  | `FileNotFoundError: Schema file not found` | Ensure `schema.json` exists in dataset directory |
205
262
  | `FileNotFoundError: Data file not found` | Ensure `data.json` exists in dataset directory |
263
+ | `FileNotFoundError: Dataset object not found: s3://...` | Ensure the bucket, prefix, dataset_id, and object names are correct |
264
+ | `ValidationError: s3_bucket field required` | Set `AGENTBYTE_DATASET_S3_BUCKET` or pass `S3DatasetConfig(s3_bucket=...)` |
206
265
  | `KeyError: 'records'` | data.json must have `{"records": [...]}` structure |
207
266
  | `sqlite3.Row has no .dict() method` | Use `dict(row)` instead of `row.dict()` |
208
- | Notebook paths fail in `load_dataset()` | Use relative paths from project root; notebook working directory is handled by loader |
267
+ | Notebook paths fail in `load_dataset()` | Pass an explicit `LocalDatasetConfig(local_root=Path("data/samples"))` |
@@ -0,0 +1,246 @@
1
+ ---
2
+ name: agentbyte-handoff-orchestration
3
+ description: Guide for creating Handoff multi-agent orchestration in Agentbyte (Chapter 7.6). Use this when agents should explicitly transfer control to named colleagues with `HANDOFF: <agent_name>` instead of the orchestrator centrally selecting every next turn.
4
+ license: MIT
5
+ ---
6
+
7
+ Use this skill when implementing multi-agent collaboration where the currently speaking agent should decide which specialist goes next.
8
+
9
+ ## Inputs to confirm
10
+ - Which agent should start first
11
+ - What exact handoff signal agents should emit
12
+ - What should happen when no valid handoff signal is present
13
+ - What termination condition should actually stop the run
14
+ - Whether colleagues should be injected into agent context automatically
15
+
16
+ ## Pattern: Basic Handoff Orchestration
17
+
18
+ ```python
19
+ import asyncio
20
+
21
+ from agentbyte import Agent, HandoffOrchestrator, UserMessage
22
+ from agentbyte.llm import OpenAIChatCompletionClient
23
+ from agentbyte.termination import MaxMessageTermination, TextMentionTermination
24
+
25
+
26
+ async def main() -> None:
27
+ client = OpenAIChatCompletionClient.from_api_key(model="gpt-4o-mini")
28
+
29
+ researcher = Agent(
30
+ name="researcher",
31
+ description="Research specialist for concise factual context",
32
+ instructions=(
33
+ "Research the topic and gather the key facts. "
34
+ "When the writer should continue, write exactly: HANDOFF: writer"
35
+ ),
36
+ model_client=client,
37
+ )
38
+
39
+ writer = Agent(
40
+ name="writer",
41
+ description="Writing specialist for clear user-facing drafts",
42
+ instructions=(
43
+ "Write a concise draft using the available context. "
44
+ "When the reviewer should inspect it, write exactly: HANDOFF: reviewer"
45
+ ),
46
+ model_client=client,
47
+ )
48
+
49
+ reviewer = Agent(
50
+ name="reviewer",
51
+ description="Review specialist for clarity and correctness",
52
+ instructions=(
53
+ "Review the draft. If it is ready, say APPROVED. "
54
+ "If it needs revision, give concise feedback and write exactly: HANDOFF: writer"
55
+ ),
56
+ model_client=client,
57
+ )
58
+
59
+ termination = TextMentionTermination("APPROVED") | MaxMessageTermination(12)
60
+
61
+ orchestrator = HandoffOrchestrator(
62
+ agents=[researcher, writer, reviewer],
63
+ termination=termination,
64
+ entry_agent_name="researcher",
65
+ fallback_strategy="round_robin",
66
+ handoff_signal_prefix="HANDOFF:",
67
+ inject_colleagues_context=True,
68
+ max_iterations=10,
69
+ )
70
+
71
+ task = UserMessage(
72
+ content="Write a short note about solar energy benefits.",
73
+ source="user",
74
+ )
75
+ result = await orchestrator.run(task)
76
+
77
+ print(f"Stop reason: {result.stop_message.content}")
78
+ print(f"Handoffs: {result.pattern_metadata['handoff_counts']}")
79
+ print(f"Last target: {result.pattern_metadata['last_handoff_target']}")
80
+
81
+
82
+ asyncio.run(main())
83
+ ```
84
+
85
+ ## Pattern: Streaming Handoff Orchestration
86
+
87
+ ```python
88
+ from agentbyte.messages import Message
89
+ from agentbyte.types import OrchestrationEvent, OrchestrationResponse
90
+
91
+ async for item in orchestrator.run_stream(task, verbose=True):
92
+ if isinstance(item, Message):
93
+ print(f"[{item.source}] {item.content}")
94
+ elif isinstance(item, OrchestrationEvent):
95
+ print(f"[EVENT] {item}")
96
+ elif isinstance(item, OrchestrationResponse):
97
+ print(f"Complete: {item.stop_message.content}")
98
+ ```
99
+
100
+ ## How Handoff Routing Works
101
+
102
+ 1. The first turn goes to the entry agent.
103
+ 2. The current agent may emit `HANDOFF: <agent_name>` in its response.
104
+ 3. The orchestrator parses the latest assistant response for that signal.
105
+ 4. If the target agent exists, control transfers there.
106
+ 5. If no valid signal is present, the configured fallback strategy is used.
107
+
108
+ This means:
109
+ - agents own the routing intent
110
+ - the orchestrator still owns validation, execution safety, and shared state
111
+
112
+ ## Constructor Surface
113
+
114
+ ```python
115
+ orchestrator = HandoffOrchestrator(
116
+ agents=[agent1, agent2, agent3],
117
+ termination=termination_condition,
118
+ entry_agent_name="agent1",
119
+ fallback_strategy="round_robin", # or "entry"
120
+ handoff_signal_prefix="HANDOFF:",
121
+ inject_colleagues_context=True,
122
+ max_iterations=50,
123
+ history_policy=...,
124
+ )
125
+ ```
126
+
127
+ ## Fallback Strategies
128
+
129
+ Use `fallback_strategy="round_robin"` when:
130
+ - you want forward progress even if an agent forgets to hand off
131
+ - multiple specialists can still contribute usefully
132
+
133
+ Use `fallback_strategy="entry"` when:
134
+ - one lead agent should always re-triage the task
135
+ - the entry agent acts like a hub/router
136
+
137
+ ## Colleagues Context Injection
138
+
139
+ When `inject_colleagues_context=True`, each agent receives a short block listing:
140
+ - the other agents it can hand off to
141
+ - their descriptions
142
+ - the reminder to use `HANDOFF: <name>`
143
+
144
+ Keep this enabled unless you already embed the routing protocol clearly in agent instructions and need tighter context control.
145
+
146
+ ## History Policy
147
+
148
+ `HandoffOrchestrator` still uses `HistoryContextPolicy` for execution context:
149
+
150
+ ```python
151
+ from agentbyte import AgentHistoryPolicy, HistoryContextPolicy
152
+
153
+ history_policy = HistoryContextPolicy(
154
+ default=AgentHistoryPolicy(window="full", format="text"),
155
+ per_agent={
156
+ "reviewer": AgentHistoryPolicy(
157
+ window="recent",
158
+ message_limit=4,
159
+ format="markdown",
160
+ )
161
+ },
162
+ )
163
+ ```
164
+
165
+ Important mental model:
166
+ - handoff chooses who acts next
167
+ - history policy chooses what that agent sees
168
+
169
+ ## Recommended Termination Patterns
170
+
171
+ ### Basic reviewer approval flow
172
+
173
+ ```python
174
+ termination = TextMentionTermination("APPROVED") | MaxMessageTermination(12)
175
+ ```
176
+
177
+ ### Reviewer-specific approval in the same message
178
+
179
+ ```python
180
+ from agentbyte.termination import MaxMessageTermination, PredicateTermination
181
+
182
+ termination = (
183
+ PredicateTermination(
184
+ lambda msgs: any(
185
+ getattr(m, "source", None) == "reviewer"
186
+ and "APPROVED" in str(getattr(m, "content", ""))
187
+ for m in msgs
188
+ ),
189
+ reason="Reviewer approved",
190
+ )
191
+ | MaxMessageTermination(12)
192
+ )
193
+ ```
194
+
195
+ ### Production-oriented safety bundle
196
+
197
+ ```python
198
+ from agentbyte.termination import (
199
+ MaxMessageTermination,
200
+ PredicateTermination,
201
+ TimeoutTermination,
202
+ TokenUsageTermination,
203
+ )
204
+
205
+ termination = (
206
+ PredicateTermination(...)
207
+ | TimeoutTermination(120)
208
+ | TokenUsageTermination(8_000)
209
+ | MaxMessageTermination(12)
210
+ )
211
+ ```
212
+
213
+ ## Pattern Metadata
214
+
215
+ After completion, `result.pattern_metadata` includes:
216
+ - `entry_agent`
217
+ - `fallback_strategy`
218
+ - `handoff_signal_prefix`
219
+ - `handoff_counts`
220
+ - `last_handoff_target`
221
+ - inherited base metrics like `iterations_completed` and `message_count`
222
+
223
+ ## Guardrails
224
+
225
+ - **Termination Still Required:** Handoff decides who goes next, not when to stop.
226
+ - **Stable Agent Names:** Keep agent names short and unambiguous because routing depends on matching text.
227
+ - **Explicit Protocol:** Tell agents to emit the exact signal, e.g. `HANDOFF: reviewer`.
228
+ - **Fallback Is Important:** Missing or malformed handoff text should not end the run or crash the orchestrator.
229
+ - **Colleague Descriptions Matter:** The injected colleagues block is more useful when agent descriptions clearly explain specialization.
230
+ - **Text-Based Routing:** This pattern is lighter than AI-driven selection, but also less strict than structured-output routing.
231
+
232
+ ## When to Use Handoff vs Other Patterns
233
+
234
+ | Use Handoff When | Use AI-Driven When | Use Round-Robin When | Use Plan-Based When |
235
+ |------------------|--------------------|----------------------|---------------------|
236
+ | The current agent usually knows the best next specialist | A central selector model should reason over the whole state | All agents should contribute in fixed order | The task has explicit sequential phases |
237
+ | You want decentralized routing | You want selector reasoning as a separate coordination call | Deterministic sequencing matters most | You need evaluator-driven retries and explicit step structure |
238
+ | You want specialist chaining like research -> write -> review -> revise | You want more robust routing than a text signal | You want the simplest possible coordination | You want decomposition before execution |
239
+
240
+ ## Common Use Cases
241
+
242
+ 1. Research -> write -> review workflows
243
+ 2. Reviewer -> writer revision loops
244
+ 3. Support triage -> billing specialist -> support resolution flows
245
+ 4. Specialist chains where the current agent can naturally identify the next specialist
246
+ 5. Lower-cost adaptive routing without a separate selector model