agentbyte 0.26.0__tar.gz → 0.26.2__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 (300) hide show
  1. {agentbyte-0.26.0 → agentbyte-0.26.2}/CHANGELOG.md +11 -0
  2. {agentbyte-0.26.0 → agentbyte-0.26.2}/PKG-INFO +10 -2
  3. {agentbyte-0.26.0 → agentbyte-0.26.2}/README.md +9 -1
  4. {agentbyte-0.26.0 → agentbyte-0.26.2}/pyproject.toml +4 -0
  5. agentbyte-0.26.2/src/agentbyte/__about__.py +2 -0
  6. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/middleware/base.py +2 -2
  7. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/middleware/test_middleware_chain.py +53 -0
  8. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_gepa.py +3 -2
  9. agentbyte-0.26.2/tests/test_vanilla_chunker.py +213 -0
  10. agentbyte-0.26.0/src/agentbyte/__about__.py +0 -2
  11. {agentbyte-0.26.0 → agentbyte-0.26.2}/.gitignore +0 -0
  12. {agentbyte-0.26.0 → agentbyte-0.26.2}/LICENSE +0 -0
  13. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/__init__.py +0 -0
  14. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/agents/__init__.py +0 -0
  15. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/agents/agent.py +0 -0
  16. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/agents/agent_as_tool.py +0 -0
  17. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/agents/base.py +0 -0
  18. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/agents/embedding_agent.py +0 -0
  19. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/agents/types.py +0 -0
  20. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/cancellation_token.py +0 -0
  21. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/catalog.py +0 -0
  22. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/cli/__init__.py +0 -0
  23. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/cli/main.py +0 -0
  24. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/component.py +0 -0
  25. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/context.py +0 -0
  26. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/context_providers/__init__.py +0 -0
  27. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/context_providers/base.py +0 -0
  28. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/context_providers/skill_tools.py +0 -0
  29. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/context_providers/skills.py +0 -0
  30. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/__init__.py +0 -0
  31. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/base.py +0 -0
  32. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/config.py +0 -0
  33. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/importer.py +0 -0
  34. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/json.py +0 -0
  35. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/loader.py +0 -0
  36. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/publish.py +0 -0
  37. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/publish_config.py +0 -0
  38. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/publishers.py +0 -0
  39. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/sources.py +0 -0
  40. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/sqlite.py +0 -0
  41. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/sqlite_db.py +0 -0
  42. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/write_config.py +0 -0
  43. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/dataset/writers.py +0 -0
  44. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/entity.py +0 -0
  45. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/__init__.py +0 -0
  46. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/base.py +0 -0
  47. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/checks/__init__.py +0 -0
  48. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/checks/decorator.py +0 -0
  49. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/checks/keyword.py +0 -0
  50. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/checks/local.py +0 -0
  51. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/checks/tool.py +0 -0
  52. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/checks/types.py +0 -0
  53. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/comparison.py +0 -0
  54. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/eval_dataset.py +0 -0
  55. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/judges/__init__.py +0 -0
  56. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/judges/base.py +0 -0
  57. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/judges/composite.py +0 -0
  58. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/judges/llm.py +0 -0
  59. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/judges/pairwise.py +0 -0
  60. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/judges/reference.py +0 -0
  61. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/pairwise.py +0 -0
  62. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/report.py +0 -0
  63. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/runner.py +0 -0
  64. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/splitting.py +0 -0
  65. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/targets/__init__.py +0 -0
  66. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/targets/agent.py +0 -0
  67. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/targets/model.py +0 -0
  68. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/targets/multi_turn.py +0 -0
  69. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/targets/orchestrator.py +0 -0
  70. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/eval/types.py +0 -0
  71. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/__init__.py +0 -0
  72. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/_retry_observability.py +0 -0
  73. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/auth.py +0 -0
  74. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/azure/__init__.py +0 -0
  75. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/azure/auth.py +0 -0
  76. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/azure/chat.py +0 -0
  77. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/azure/embedding.py +0 -0
  78. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/azure/settings.py +0 -0
  79. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/azure_openai.py +0 -0
  80. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/azure_openai_embedding.py +0 -0
  81. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/base.py +0 -0
  82. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/embeddings_base.py +0 -0
  83. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/openai/__init__.py +0 -0
  84. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/openai/chat.py +0 -0
  85. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/openai/embedding.py +0 -0
  86. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/openai/settings.py +0 -0
  87. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/openai_embedding.py +0 -0
  88. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/pricing.py +0 -0
  89. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/retry_policy.py +0 -0
  90. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/settings.py +0 -0
  91. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/llm/types.py +0 -0
  92. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/logger.py +0 -0
  93. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/memory/__init__.py +0 -0
  94. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/memory/base.py +0 -0
  95. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/messages.py +0 -0
  96. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/middleware/__init__.py +0 -0
  97. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/middleware/otel.py +0 -0
  98. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/middleware/retry.py +0 -0
  99. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/middleware/sql_usage.py +0 -0
  100. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/middleware/usage_logger.py +0 -0
  101. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/notebook.py +0 -0
  102. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/__init__.py +0 -0
  103. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/base.py +0 -0
  104. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/config.py +0 -0
  105. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/gepa.py +0 -0
  106. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/mipro.py +0 -0
  107. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/pareto.py +0 -0
  108. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/reflective.py +0 -0
  109. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/spec.py +0 -0
  110. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/optim/trace.py +0 -0
  111. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/orchestration/__init__.py +0 -0
  112. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/orchestration/ai.py +0 -0
  113. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/orchestration/base.py +0 -0
  114. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/orchestration/handoff.py +0 -0
  115. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/orchestration/plan.py +0 -0
  116. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/orchestration/policies.py +0 -0
  117. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/orchestration/round_robin.py +0 -0
  118. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/__init__.py +0 -0
  119. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/agents.py +0 -0
  120. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/clients.py +0 -0
  121. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/instruction_registry.py +0 -0
  122. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/instructions/orchestrator.yaml +0 -0
  123. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/instructions/query_rewriter.yaml +0 -0
  124. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/instructions/researcher.yaml +0 -0
  125. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/instructions/reviewer.yaml +0 -0
  126. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/instructions/writer.yaml +0 -0
  127. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/orchestration.py +0 -0
  128. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/skills/contracts-analyst/SKILL.md +0 -0
  129. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/skills/hr-analyst/SKILL.md +0 -0
  130. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/skills/hr-analyst/resources/departments.md +0 -0
  131. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/skills/hr-analyst/resources/employees.md +0 -0
  132. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/skills/hr-analyst/resources/payroll.md +0 -0
  133. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/streaming.py +0 -0
  134. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/presets/workflow.py +0 -0
  135. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/session_store.py +0 -0
  136. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/skills/__init__.py +0 -0
  137. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/skills/base.py +0 -0
  138. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/skills/resources.py +0 -0
  139. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/skills/scripts.py +0 -0
  140. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/skills/sources.py +0 -0
  141. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/skills/validation.py +0 -0
  142. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/__init__.py +0 -0
  143. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/base.py +0 -0
  144. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/cancellation.py +0 -0
  145. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/composite.py +0 -0
  146. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/consecutive_agent.py +0 -0
  147. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/external.py +0 -0
  148. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/function_call.py +0 -0
  149. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/handoff.py +0 -0
  150. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/max_message.py +0 -0
  151. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/predicate.py +0 -0
  152. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/source.py +0 -0
  153. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/text_mention.py +0 -0
  154. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/timeout.py +0 -0
  155. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/termination/token_usage.py +0 -0
  156. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/tools/__init__.py +0 -0
  157. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/tools/base.py +0 -0
  158. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/tools/coding_tools.py +0 -0
  159. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/tools/core_tools.py +0 -0
  160. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/tools/decorator.py +0 -0
  161. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/tools/memory_tool.py +0 -0
  162. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/tools/research_tools.py +0 -0
  163. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/types.py +0 -0
  164. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/__init__.py +0 -0
  165. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/discovery.py +0 -0
  166. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/execution.py +0 -0
  167. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/models.py +0 -0
  168. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/registry.py +0 -0
  169. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/server.py +0 -0
  170. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/session_store.py +0 -0
  171. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/sessions.py +0 -0
  172. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/ui/assets/index-BF3DwXaF.js +0 -0
  173. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/ui/assets/index-ar5tOeqt.css +0 -0
  174. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/ui/index.html +0 -0
  175. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/webui/ui/vite.svg +0 -0
  176. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/__init__.py +0 -0
  177. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/agent.py +0 -0
  178. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/core/__init__.py +0 -0
  179. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/core/_structure_hash.py +0 -0
  180. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/core/checkpoint.py +0 -0
  181. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/core/models.py +0 -0
  182. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/core/runner.py +0 -0
  183. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/core/workflow.py +0 -0
  184. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/defaults.py +0 -0
  185. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/loader.py +0 -0
  186. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/schema.py +0 -0
  187. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/schema_utils.py +0 -0
  188. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/steps/__init__.py +0 -0
  189. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/steps/agentbyte_agent.py +0 -0
  190. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/steps/echo.py +0 -0
  191. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/steps/function.py +0 -0
  192. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/steps/http.py +0 -0
  193. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/steps/step.py +0 -0
  194. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/steps/subworkflow.py +0 -0
  195. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/steps/transform.py +0 -0
  196. {agentbyte-0.26.0 → agentbyte-0.26.2}/src/agentbyte/workflow/visualizer.py +0 -0
  197. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_as_tool.py +0 -0
  198. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_basic.py +0 -0
  199. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_context_providers.py +0 -0
  200. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_event_types.py +0 -0
  201. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_memory_integration.py +0 -0
  202. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_middleware_integration.py +0 -0
  203. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_response_accessors.py +0 -0
  204. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_retry_middleware.py +0 -0
  205. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_agent_stream_events.py +0 -0
  206. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_embedding_agent.py +0 -0
  207. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/agents/test_tool_approval.py +0 -0
  208. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/cli/test_registry_check.py +0 -0
  209. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/context_providers/__init__.py +0 -0
  210. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/context_providers/test_skill_tools.py +0 -0
  211. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/context_providers/test_skills_provider.py +0 -0
  212. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/dataset/test_loader.py +0 -0
  213. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/dataset/test_multi_table.py +0 -0
  214. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/dataset/test_publish.py +0 -0
  215. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/dataset/test_sqlite_db.py +0 -0
  216. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/eval/test_eval_dataset.py +0 -0
  217. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/eval/test_multi_turn.py +0 -0
  218. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/eval/test_pairwise.py +0 -0
  219. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/eval/test_phase1_runner_and_targets.py +0 -0
  220. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/eval/test_phase2_checks_and_reports.py +0 -0
  221. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/eval/test_splitting.py +0 -0
  222. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/eval/test_types_and_judges.py +0 -0
  223. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/llm/test_azure_client.py +0 -0
  224. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/llm/test_azure_embedding_client.py +0 -0
  225. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/llm/test_llm_types.py +0 -0
  226. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/llm/test_openai_client.py +0 -0
  227. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/llm/test_openai_embedding_client.py +0 -0
  228. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/llm/test_pricing.py +0 -0
  229. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/llm/test_retry_observability.py +0 -0
  230. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/llm/test_retry_policy_api.py +0 -0
  231. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/memory/test_memory.py +0 -0
  232. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/middleware/test_otel.py +0 -0
  233. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/middleware/test_retry_middleware.py +0 -0
  234. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/middleware/test_sql_usage.py +0 -0
  235. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/middleware/test_usage_logger.py +0 -0
  236. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/__init__.py +0 -0
  237. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_base.py +0 -0
  238. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_base_integration.py +0 -0
  239. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_config.py +0 -0
  240. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_mipro.py +0 -0
  241. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_pareto.py +0 -0
  242. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_reflective.py +0 -0
  243. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_spec.py +0 -0
  244. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/optim/test_trace.py +0 -0
  245. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/orchestration/test_ai_orchestrator.py +0 -0
  246. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/orchestration/test_base_orchestrator.py +0 -0
  247. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/orchestration/test_handoff_orchestrator.py +0 -0
  248. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/orchestration/test_plan_orchestrator.py +0 -0
  249. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/orchestration/test_round_robin.py +0 -0
  250. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/presets/test_agents.py +0 -0
  251. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/presets/test_clients.py +0 -0
  252. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/presets/test_instruction_registry.py +0 -0
  253. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/presets/test_orchestration.py +0 -0
  254. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/presets/test_streaming.py +0 -0
  255. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/presets/test_workflow.py +0 -0
  256. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/skills/__init__.py +0 -0
  257. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/skills/test_base.py +0 -0
  258. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/skills/test_resources.py +0 -0
  259. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/skills/test_scripts.py +0 -0
  260. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/skills/test_sources.py +0 -0
  261. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_base.py +0 -0
  262. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_cancellation.py +0 -0
  263. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_composite.py +0 -0
  264. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_consecutive_agent.py +0 -0
  265. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_external.py +0 -0
  266. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_function_call.py +0 -0
  267. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_handoff.py +0 -0
  268. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_max_message.py +0 -0
  269. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_predicate.py +0 -0
  270. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_source.py +0 -0
  271. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_text_mention.py +0 -0
  272. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_timeout.py +0 -0
  273. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/termination/test_token_usage.py +0 -0
  274. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/test_cancellation_token.py +0 -0
  275. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/test_context.py +0 -0
  276. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/test_logger.py +0 -0
  277. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/test_messages.py +0 -0
  278. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/test_package_api.py +0 -0
  279. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/test_session_store.py +0 -0
  280. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/test_types.py +0 -0
  281. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/tools/test_coding_tools.py +0 -0
  282. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/tools/test_memory_tool.py +0 -0
  283. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/tools/test_research_tools.py +0 -0
  284. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/tools/test_tools.py +0 -0
  285. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/webui/__init__.py +0 -0
  286. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/webui/helpers.py +0 -0
  287. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/webui/test_execution.py +0 -0
  288. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/webui/test_package_api.py +0 -0
  289. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/webui/test_registry.py +0 -0
  290. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/webui/test_server.py +0 -0
  291. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/webui/test_sessions.py +0 -0
  292. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_checkpoint.py +0 -0
  293. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_subworkflow_step.py +0 -0
  294. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_workflow_agent.py +0 -0
  295. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_workflow_class.py +0 -0
  296. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_workflow_models.py +0 -0
  297. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_workflow_runner.py +0 -0
  298. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_workflow_schema.py +0 -0
  299. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_workflow_steps.py +0 -0
  300. {agentbyte-0.26.0 → agentbyte-0.26.2}/tests/workflow/test_workflow_visualizer.py +0 -0
@@ -4,6 +4,17 @@ All notable changes to Agentbyte are documented in this file.
4
4
 
5
5
  The format follows Keep a Changelog principles and semantic versioning.
6
6
 
7
+ ## [0.26.2] - 2026-09-09
8
+
9
+ ### Fixed
10
+
11
+ - Fixed `MiddlewareChain.execute_stream()` treating a middleware's `None` return from `process_error()` (meaning "not handled, propagate") as a recovered result, which swallowed the original exception and surfaced a generic "did not yield a final result" error instead.
12
+
13
+ ## [0.26.1] - 2026-09-04
14
+
15
+ - Ensured release CI explicitly installs the optional GEPA optimization dependency and made its availability test independent of the environment's installed extras.
16
+ - Updated the contracting example's skills provider and added chunking-strategy documentation.
17
+
7
18
  ## [0.26.0] - 2026-09-04
8
19
 
9
20
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentbyte
3
- Version: 0.26.0
3
+ Version: 0.26.2
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
@@ -86,7 +86,7 @@ Description-Content-Type: text/markdown
86
86
 
87
87
  Agentbyte is an observability-first agentic AI framework for building and studying multiagent systems with a learning-first, implementation-oriented workflow.
88
88
 
89
- Current release: **0.26.0**
89
+ Current release: **0.26.2**
90
90
 
91
91
  ## Building an Agent
92
92
 
@@ -189,6 +189,14 @@ print(execution.state["route_output"])
189
189
 
190
190
  Steps can also wrap an agent (`AgentStep`), call HTTP endpoints (`HttpStep`), transform data (`TransformStep`), or nest another workflow (`SubWorkflowStep`) — with conditional routing, parallel branches, checkpoint/resume, and human-in-the-loop suspend/resume.
191
191
 
192
+ ### Choosing Agents or Graph-Based Orchestration
193
+
194
+ Graph-based orchestration makes routing deterministic: after one defined step completes, the next defined step runs. It does not make an LLM's interpretation, tool selection, or output deterministic. Use a graph or `Workflow` when the business process is known, stable, and requires explicit control over every transition.
195
+
196
+ Start with an `Agent` when the work requires the system to decide how to solve an open-ended request: researching, interpreting documents, selecting tools, synthesizing results, or handling long-tail exceptions. A single agent can complete many such multi-step tasks without encoding every anticipated reasoning path as graph infrastructure.
197
+
198
+ Keep deterministic controls at operational boundaries. Validate structured output, apply policy checks and approvals, use idempotent writes, and emit audit records before an agent can produce external side effects. This separates deterministic process control from the model's inherently probabilistic reasoning, while allowing a workflow to be introduced where a stable business process truly needs one.
199
+
192
200
  ## Orchestrator Patterns
193
201
 
194
202
  Two different ways to combine multiple agents — pick based on who's in control:
@@ -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.26.0**
5
+ Current release: **0.26.2**
6
6
 
7
7
  ## Building an Agent
8
8
 
@@ -105,6 +105,14 @@ print(execution.state["route_output"])
105
105
 
106
106
  Steps can also wrap an agent (`AgentStep`), call HTTP endpoints (`HttpStep`), transform data (`TransformStep`), or nest another workflow (`SubWorkflowStep`) — with conditional routing, parallel branches, checkpoint/resume, and human-in-the-loop suspend/resume.
107
107
 
108
+ ### Choosing Agents or Graph-Based Orchestration
109
+
110
+ Graph-based orchestration makes routing deterministic: after one defined step completes, the next defined step runs. It does not make an LLM's interpretation, tool selection, or output deterministic. Use a graph or `Workflow` when the business process is known, stable, and requires explicit control over every transition.
111
+
112
+ Start with an `Agent` when the work requires the system to decide how to solve an open-ended request: researching, interpreting documents, selecting tools, synthesizing results, or handling long-tail exceptions. A single agent can complete many such multi-step tasks without encoding every anticipated reasoning path as graph infrastructure.
113
+
114
+ Keep deterministic controls at operational boundaries. Validate structured output, apply policy checks and approvals, use idempotent writes, and emit audit records before an agent can produce external side effects. This separates deterministic process control from the model's inherently probabilistic reasoning, while allowing a workflow to be introduced where a stable business process truly needs one.
115
+
108
116
  ## Orchestrator Patterns
109
117
 
110
118
  Two different ways to combine multiple agents — pick based on who's in control:
@@ -210,6 +210,10 @@ all = [
210
210
  "youtube-transcript-api>=0.6",
211
211
  "gepa>=0.1",
212
212
  ]
213
+ experiment = [
214
+ "tiktoken>=0.9.0",
215
+ "yake>=0.4.8",
216
+ ]
213
217
 
214
218
  [tool.pytest.ini_options]
215
219
  testpaths = ["tests"]
@@ -0,0 +1,2 @@
1
+ __version__ = "0.26.2"
2
+ VERSION = __version__
@@ -391,7 +391,7 @@ class MiddlewareChain:
391
391
  ):
392
392
  if self._is_event_item(item):
393
393
  yield item
394
- else:
394
+ elif item is not None:
395
395
  yield item
396
396
  recovered = True
397
397
  return
@@ -492,7 +492,7 @@ class MiddlewareChain:
492
492
  ):
493
493
  if self._is_event_item(item):
494
494
  yield item
495
- else:
495
+ elif item is not None:
496
496
  yield item
497
497
  recovered = True
498
498
  return
@@ -358,6 +358,59 @@ async def test_middleware_chain_execute_stream_yields_events_and_result() -> Non
358
358
  assert items[2] == {"value": "ok", "stream": True}
359
359
 
360
360
 
361
+ @pytest.mark.asyncio
362
+ async def test_execute_stream_propagates_error_when_request_handler_declines() -> None:
363
+ """A None-returning process_error during process_request must not be treated as recovery."""
364
+ chain = MiddlewareChain([FailingRequestMiddleware()])
365
+
366
+ async def operation() -> str:
367
+ return "should-not-run"
368
+
369
+ with pytest.raises(RuntimeError, match="request middleware failed"):
370
+ async for _ in chain.execute_stream(
371
+ operation="model_call",
372
+ agent_name="assistant",
373
+ agent_context=AgentContext(),
374
+ data={"payload": "x"},
375
+ func=operation,
376
+ ):
377
+ pass
378
+
379
+
380
+ @pytest.mark.asyncio
381
+ async def test_execute_stream_propagates_error_when_response_handler_declines() -> None:
382
+ """A None-returning process_error during process_response must not be treated as recovery."""
383
+
384
+ class FailingResponseMiddleware(BaseMiddleware):
385
+ async def process_request(self, context: MiddlewareContext) -> MiddlewareContext:
386
+ return context
387
+
388
+ async def process_response(self, context: MiddlewareContext, result: Any) -> Any:
389
+ raise RuntimeError("response middleware failed")
390
+
391
+ async def process_error(
392
+ self,
393
+ context: MiddlewareContext,
394
+ error: Exception,
395
+ ) -> Optional[Any]:
396
+ return None
397
+
398
+ chain = MiddlewareChain([FailingResponseMiddleware()])
399
+
400
+ async def operation() -> str:
401
+ return "ok"
402
+
403
+ with pytest.raises(RuntimeError, match="response middleware failed"):
404
+ async for _ in chain.execute_stream(
405
+ operation="model_call",
406
+ agent_name="assistant",
407
+ agent_context=AgentContext(),
408
+ data={"payload": "x"},
409
+ func=operation,
410
+ ):
411
+ pass
412
+
413
+
361
414
  @pytest.mark.asyncio
362
415
  async def test_approval_middleware_emits_event_for_matching_tool() -> None:
363
416
  chain = MiddlewareChain([ApprovalMiddleware(tool_names=["sensitive_tool"])])
@@ -24,6 +24,7 @@ from agentbyte.messages import AssistantMessage, Usage
24
24
  from agentbyte.optim import GEPA_AVAILABLE, AgentConfig, CostLog, OptimizationSpec, InstructionTunable
25
25
  from agentbyte.optim.gepa import (
26
26
  AgentbyteGepaAdapter,
27
+ _gepa,
27
28
  _CostTrackingReflectionLM,
28
29
  _GepaTraceCallback,
29
30
  optimize_with_gepa,
@@ -84,8 +85,8 @@ class ScriptedModelClient(BaseChatCompletionClient):
84
85
 
85
86
 
86
87
  def test_gepa_available_reflects_import_state() -> None:
87
- # gepa is genuinely not installed in this dev environment
88
- assert GEPA_AVAILABLE is False
88
+ """The optional dependency may be present in CI but absent locally."""
89
+ assert GEPA_AVAILABLE is (_gepa is not None)
89
90
 
90
91
 
91
92
  @pytest.mark.asyncio
@@ -0,0 +1,213 @@
1
+ """Regression coverage for the standalone chunking example."""
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ import pytest
7
+
8
+ pytest.importorskip('tiktoken')
9
+ pytest.importorskip('yake')
10
+ SOURCE = Path(__file__).parents[1] / 'examples/chunking/vanilla_chunker.py'
11
+ SPEC = importlib.util.spec_from_file_location('vanilla_chunker', SOURCE)
12
+ module = importlib.util.module_from_spec(SPEC)
13
+ sys.modules[SPEC.name] = module
14
+ SPEC.loader.exec_module(module)
15
+
16
+
17
+ @pytest.fixture(autouse=True)
18
+ def offline_encoding(monkeypatch):
19
+ # Real BPE encoding with a local vocabulary: no tokenizer download in unit tests.
20
+ ranks = {bytes([i]): i for i in range(256)}
21
+ for word in (b'Alpha', b'Beta', b'Gamma', b'word'):
22
+ for end in range(2, len(word) + 1):
23
+ ranks.setdefault(word[:end], len(ranks))
24
+ encoding = module.tiktoken.Encoding(
25
+ name='offline', pat_str=r'\s+|\w+|[^\w\s]+',
26
+ mergeable_ranks=ranks, special_tokens={},
27
+ )
28
+ monkeypatch.setattr(module.tiktoken, 'get_encoding', lambda name: encoding)
29
+
30
+
31
+ def chunker(budget=60, overlap=10):
32
+ return module.VanillaChunker(module.ChunkerConfig(
33
+ project_id='project', doc_id='doc', max_tokens=budget, token_overlap=overlap,
34
+ min_tokens=0, document_type='prose',
35
+ ))
36
+
37
+
38
+ def test_unmarked_paragraphs_overlap_and_schema():
39
+ c = chunker(60, 12)
40
+ paragraphs = [' '.join([word] * 20) + '.' for word in ('Alpha', 'Beta', 'Gamma')]
41
+ docs = c.chunk_text('\n\n'.join(paragraphs), 'plain.md')
42
+ assert len(docs) == 1
43
+ doc = docs[0]
44
+ assert len(doc.chunks) == 3
45
+ for paragraph, chunk in zip(paragraphs, doc.chunks):
46
+ assert paragraph in chunk.content
47
+ assert chunk.page_start == chunk.page_end == 1
48
+ assert chunk.token_count == c._count_tokens(chunk.content) <= 60
49
+ assert 'Alpha' in doc.chunks[1].content.split('\n\n')[0]
50
+
51
+
52
+ def test_long_paragraph_unicode_and_empty_input():
53
+ c = chunker(30, 5)
54
+ docs = c.chunk_text('界' * 100, 'unicode.md')
55
+ assert len(docs) == 1
56
+ assert len(docs[0].chunks) > 1
57
+ assert all(chunk.token_count <= 30 for chunk in docs[0].chunks)
58
+ assert all('\ufffd' not in chunk.content for chunk in docs[0].chunks)
59
+ assert sum(chunk.content.count('界') for chunk in docs[0].chunks) >= 100
60
+ assert c.chunk_text('', 'empty.md') == []
61
+
62
+
63
+ def test_cross_page_table_headers_and_rows():
64
+ c = chunker(70, 0)
65
+ header = '| Item | Value |\n| --- | --- |'
66
+ rows = [f'| item{i} | value{i} |' for i in range(12)]
67
+ raw = '<!-- page: {"page": 4} -->\n## Costs\n' + header + '\n'
68
+ raw += '\n'.join(rows[:6]) + '\n<!-- page: {"page": 5} -->\n'
69
+ raw += '\n'.join(rows[6:])
70
+ docs = c.chunk_text(raw, 'table.md')
71
+ assert len(docs) == 1
72
+ chunks = docs[0].chunks
73
+ assert len(chunks) > 2
74
+ for chunk in chunks:
75
+ assert header in chunk.content
76
+ assert chunk.token_count == c._count_tokens(chunk.content) <= 70
77
+ combined = '\n'.join(chunk.content for chunk in chunks)
78
+ assert all(combined.count(row) == 1 for row in rows)
79
+ assert chunks[0].page_start == 4
80
+ assert chunks[-1].page_end == 5
81
+
82
+
83
+ def test_table_context_cleared_by_heading_and_adjacent_prose():
84
+ c = chunker()
85
+ blocks = c._parse_section_blocks([(1, '| A |\n| --- |\n| one |\nprose\n| two |\n## New\n| three |')])
86
+ assert all(not b['table_header'] for b in blocks if 'two' in b['text'] or 'three' in b['text'])
87
+
88
+
89
+ def test_oversized_table_row_fails_explicitly():
90
+ c = chunker(20, 0)
91
+ with pytest.raises(ValueError, match='one row'):
92
+ c.chunk_text('| A |\n| --- |\n| ' + 'word ' * 100 + '|', 'table.md')
93
+
94
+
95
+ def test_oversized_table_header_fails_explicitly():
96
+ with pytest.raises(ValueError, match='Table header exceeds'):
97
+ chunker(20, 0).chunk_text('| ' + 'word ' * 100 + '|\n| --- |', 'table.md')
98
+
99
+
100
+ def test_preamble_preserved():
101
+ docs = chunker().chunk_text('Introduction\n<!-- page: {"page": 3} -->\nBody', 'doc.md')
102
+ assert len(docs) == 1
103
+ assert 'Introduction' in docs[0].chunks[0].content
104
+ assert docs[0].chunks[0].page_start == 3
105
+
106
+
107
+ def test_skipped_heading_levels_are_siblings_and_preserved():
108
+ c = chunker(500, 0)
109
+ raw = '# Agreement\n#### First\nAlpha\n#### Second\nBeta\n##### Exhibit A\nGamma'
110
+ docs = c.chunk_text(raw, 'doc.md')
111
+ assert len(docs) == 1
112
+ chunks = docs[0].chunks
113
+ assert [chunk.section_title for chunk in chunks] == ['Agreement', 'First', 'Second', 'Exhibit A']
114
+ assert chunks[2].heading_path == ['Agreement', 'Second']
115
+ assert chunks[3].heading_path == ['Agreement', 'Second', 'Exhibit A']
116
+ assert '#### Second' in chunks[2].content
117
+ assert all(chunk.token_count == c._count_tokens(chunk.content) for chunk in chunks)
118
+
119
+
120
+ def test_signature_artifacts_keep_section_and_content():
121
+ c = chunker(500, 0)
122
+ raw = ('# Agreement\n##### Adelphi Values LLC\nby: Docusigned by:\n'
123
+ '**### | | ...**\nBy: By:\n**# FEDIEBAD219E44F.**\n'
124
+ 'D21C3301ADS44AS.\n##### (Exhibit A) BUDGET AND PAYMENT SCHEDULE\nPayment')
125
+ docs = c.chunk_text(raw, 'signature.md')
126
+ assert len(docs) == 1
127
+ chunks = docs[0].chunks
128
+ assert len(chunks) == 3
129
+ signature = chunks[1]
130
+ assert signature.section_title == 'Adelphi Values LLC'
131
+ assert signature.heading_path == ['Agreement', 'Adelphi Values LLC']
132
+ assert '**# FEDIEBAD219E44F.**' in signature.content
133
+ assert 'D21C3301ADS44AS.' in signature.content
134
+ assert '**### | | ...**' in signature.content
135
+ assert chunks[2].heading_path == ['Agreement', '(Exhibit A) BUDGET AND PAYMENT SCHEDULE']
136
+
137
+
138
+ def test_identifier_without_signature_context_remains_heading():
139
+ blocks = chunker()._parse_section_blocks([(1, '# FEDIEBAD219E44F.\nContent')])
140
+ assert blocks[0]['type'] == 'heading'
141
+
142
+
143
+ def test_artifact_does_not_reset_cross_page_table_context():
144
+ c = chunker(500, 0)
145
+ blocks = c._parse_section_blocks([
146
+ (1, '# Signatures\nDocuSigned by:\n| Name |\n| --- |\n| Alice |'),
147
+ (2, '# FEDIEBAD219E44F.\n| Bob |'),
148
+ (3, '#### New section\n| Carol |'),
149
+ ])
150
+ bob = next(b for b in blocks if b['text'] == '| Bob |')
151
+ carol = next(b for b in blocks if b['text'] == '| Carol |')
152
+ assert bob['table_header'] == '| Name |\n| --- |'
153
+ assert bob['heading_path'] == ['Signatures']
154
+ assert carol['table_header'] == ''
155
+ docs = c._build_records(c._accumulate_chunks(blocks), 'doc.md', c._kw)
156
+ assert len(docs) == 1
157
+ assert '| Name |\n| --- |\n| Bob |' in docs[0].chunks[0].content
158
+
159
+
160
+ def test_configured_heading_depth_uses_actual_level():
161
+ c = chunker(500, 0)
162
+ c.cfg.section_split_depth = 2
163
+ docs = c.chunk_text('# Root\n#### Child\nText', 'doc.md')
164
+ assert len(docs) == 1
165
+ assert docs[0].chunks[0].section_title == 'Root'
166
+ assert '#### Child' in docs[0].chunks[0].content
167
+
168
+
169
+ def test_auto_form_labels_pack_but_exhibit_still_splits():
170
+ c = chunker(500, 0)
171
+ c.cfg.document_type = 'auto'
172
+ raw = ('# Form\n##### Name\nAlice\n##### Date\nToday\n'
173
+ '##### Value\n100\n##### Exhibit A\nTerms')
174
+ docs = c.chunk_text(raw, 'form.md')
175
+ assert len(docs) == 1
176
+ chunks = docs[0].chunks
177
+ assert len(chunks) == 2
178
+ assert all(label in chunks[0].content for label in ('Name', 'Date', 'Value'))
179
+ assert chunks[1].section_title == 'Exhibit A'
180
+
181
+
182
+ def test_small_chunks_merge_without_content_loss():
183
+ c = chunker(500, 0)
184
+ c.cfg.min_tokens = 100
185
+ raw = '# Root\n##### Label\nValue\n##### Other\nMore'
186
+ docs = c.chunk_text(raw, 'form.md')
187
+ assert len(docs) == 1
188
+ chunks = docs[0].chunks
189
+ assert len(chunks) == 1
190
+ assert all(line in chunks[0].content for line in raw.splitlines())
191
+ assert chunks[0].heading_path == ['Root']
192
+ assert chunks[0].token_count == c._count_tokens(chunks[0].content)
193
+
194
+
195
+ def test_minimum_does_not_merge_across_pages_or_exceed_maximum():
196
+ c = chunker(60, 0)
197
+ c.cfg.min_tokens = 50
198
+ raw = '<!-- page: {"page":1} -->\n# A\n<!-- page: {"page":2} -->\n# B'
199
+ docs = c.chunk_text(raw, 'pages.md')
200
+ assert len(docs) == 1
201
+ assert len(docs[0].chunks) == 2
202
+ raw = '# A\n' + 'x' * 40 + '\n# B\n' + 'y' * 40
203
+ docs = c.chunk_text(raw, 'budget.md')
204
+ assert len(docs) == 1
205
+ chunks = docs[0].chunks
206
+ assert len(chunks) == 2
207
+ assert all(chunk.token_count <= 60 for chunk in chunks)
208
+
209
+
210
+ @pytest.mark.parametrize('budget,overlap', [(0, 0), (10, -1), (10, 10)])
211
+ def test_invalid_config(budget, overlap):
212
+ with pytest.raises(ValueError):
213
+ chunker(budget, overlap)
@@ -1,2 +0,0 @@
1
- __version__ = "0.26.0"
2
- VERSION = __version__
File without changes
File without changes