msgflux 0.1.1__tar.gz → 0.2.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 (454) hide show
  1. {msgflux-0.1.1 → msgflux-0.2.0}/.github/workflows/release-drafter.yml +7 -1
  2. msgflux-0.2.0/CHANGELOG.md +17 -0
  3. {msgflux-0.1.1 → msgflux-0.2.0}/PKG-INFO +1 -1
  4. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/inline.md +42 -0
  5. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/quickstart.md +24 -0
  6. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/tools.md +247 -0
  7. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/speaker.md +19 -0
  8. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/transcriber.md +20 -0
  9. {msgflux-0.1.1 → msgflux-0.2.0}/scripts/release.sh +16 -15
  10. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/__init__.py +3 -0
  11. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/core/__init__.py +2 -1
  12. msgflux-0.2.0/src/msgflux/core/registry.py +126 -0
  13. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/agent.py +337 -24
  14. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/speaker.py +14 -3
  15. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/transcriber.py +14 -3
  16. msgflux-0.2.0/src/msgflux/version.py +1 -0
  17. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_agent.py +49 -2
  18. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_speaker.py +30 -1
  19. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_transcriber.py +30 -1
  20. msgflux-0.2.0/tests/test_registry.py +231 -0
  21. msgflux-0.2.0/tests/test_tool_control.py +319 -0
  22. msgflux-0.1.1/CHANGELOG.md +0 -11
  23. msgflux-0.1.1/src/msgflux/version.py +0 -1
  24. {msgflux-0.1.1 → msgflux-0.2.0}/.github/CODEOWNERS +0 -0
  25. {msgflux-0.1.1 → msgflux-0.2.0}/.github/SECURITY.md +0 -0
  26. {msgflux-0.1.1 → msgflux-0.2.0}/.github/dependabot.yml +0 -0
  27. {msgflux-0.1.1 → msgflux-0.2.0}/.github/labeler.yml +0 -0
  28. {msgflux-0.1.1 → msgflux-0.2.0}/.github/pull_request_template.md +0 -0
  29. {msgflux-0.1.1 → msgflux-0.2.0}/.github/release-drafter.yml +0 -0
  30. {msgflux-0.1.1 → msgflux-0.2.0}/.github/workflows/ci.yml +0 -0
  31. {msgflux-0.1.1 → msgflux-0.2.0}/.github/workflows/docs.yml +0 -0
  32. {msgflux-0.1.1 → msgflux-0.2.0}/.github/workflows/labeler.yml +0 -0
  33. {msgflux-0.1.1 → msgflux-0.2.0}/.github/workflows/merge-bot.yml +0 -0
  34. {msgflux-0.1.1 → msgflux-0.2.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
  35. {msgflux-0.1.1 → msgflux-0.2.0}/.github/workflows/publish.yml +0 -0
  36. {msgflux-0.1.1 → msgflux-0.2.0}/.github/workflows/validate-release.yml +0 -0
  37. {msgflux-0.1.1 → msgflux-0.2.0}/.gitignore +0 -0
  38. {msgflux-0.1.1 → msgflux-0.2.0}/.pre-commit-config.yaml +0 -0
  39. {msgflux-0.1.1 → msgflux-0.2.0}/.python-version +0 -0
  40. {msgflux-0.1.1 → msgflux-0.2.0}/.readthedocs.yaml +0 -0
  41. {msgflux-0.1.1 → msgflux-0.2.0}/CONTRIBUTING.md +0 -0
  42. {msgflux-0.1.1 → msgflux-0.2.0}/LICENSE +0 -0
  43. {msgflux-0.1.1 → msgflux-0.2.0}/README.md +0 -0
  44. {msgflux-0.1.1 → msgflux-0.2.0}/docs/CHANGELOG.md +0 -0
  45. {msgflux-0.1.1 → msgflux-0.2.0}/docs/CNAME +0 -0
  46. {msgflux-0.1.1 → msgflux-0.2.0}/docs/_includes/init_chat_completion_model.md +0 -0
  47. {msgflux-0.1.1 → msgflux-0.2.0}/docs/_includes/install.md +0 -0
  48. {msgflux-0.1.1 → msgflux-0.2.0}/docs/_includes/install_openai.md +0 -0
  49. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/agent.md +0 -0
  50. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/chat-schema-utils.md +0 -0
  51. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/dict-lowering-and-restoration.md +0 -0
  52. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/index.md +0 -0
  53. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/logical-vs-provider-schema.md +0 -0
  54. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/msgspec-transport-lowering.md +0 -0
  55. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/openai-chat-completion.md +0 -0
  56. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/react-provider-schemas.md +0 -0
  57. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/signatures.md +0 -0
  58. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/tool-flow-control.md +0 -0
  59. {msgflux-0.1.1 → msgflux-0.2.0}/docs/anatomy/tool-library.md +0 -0
  60. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/databases/database.md +0 -0
  61. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/databases/types/kv.md +0 -0
  62. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/databases/types/vector.md +0 -0
  63. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/model.md +0 -0
  64. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/model_gateway.md +0 -0
  65. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/chat_completion.md +0 -0
  66. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/image_classifier.md +0 -0
  67. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/image_embedder.md +0 -0
  68. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/image_text_to_image.md +0 -0
  69. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/moderation.md +0 -0
  70. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/speech_to_text.md +0 -0
  71. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/text_classifier.md +0 -0
  72. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/text_embedder.md +0 -0
  73. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/text_reranker.md +0 -0
  74. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/text_to_image.md +0 -0
  75. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/models/types/text_to_speech.md +0 -0
  76. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/functional.md +0 -0
  77. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/agent.md +0 -0
  78. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/module.md +0 -0
  79. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/module_dict.md +0 -0
  80. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/module_list.md +0 -0
  81. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/predictor.md +0 -0
  82. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/searcher.md +0 -0
  83. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/sequential.md +0 -0
  84. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/speaker.md +0 -0
  85. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/tool.md +0 -0
  86. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference/nn/modules/transcriber.md +0 -0
  87. {msgflux-0.1.1 → msgflux-0.2.0}/docs/api-reference.md +0 -0
  88. {msgflux-0.1.1 → msgflux-0.2.0}/docs/assets/logo-msgflux-horizon.png +0 -0
  89. {msgflux-0.1.1 → msgflux-0.2.0}/docs/assets/logo.png +0 -0
  90. {msgflux-0.1.1 → msgflux-0.2.0}/docs/assets/msgflux-wordmark.png +0 -0
  91. {msgflux-0.1.1 → msgflux-0.2.0}/docs/assets/msgflux.png +0 -0
  92. {msgflux-0.1.1 → msgflux-0.2.0}/docs/assets/tmd-mascot.png +0 -0
  93. {msgflux-0.1.1 → msgflux-0.2.0}/docs/blog/.authors.yml +0 -0
  94. {msgflux-0.1.1 → msgflux-0.2.0}/docs/blog/index.md +0 -0
  95. {msgflux-0.1.1 → msgflux-0.2.0}/docs/blog/posts/.meta.yml +0 -0
  96. {msgflux-0.1.1 → msgflux-0.2.0}/docs/blog/posts/26-04/why-msgflux-exists.md +0 -0
  97. {msgflux-0.1.1 → msgflux-0.2.0}/docs/changelog.md +0 -0
  98. {msgflux-0.1.1 → msgflux-0.2.0}/docs/dependency-management.md +0 -0
  99. {msgflux-0.1.1 → msgflux-0.2.0}/docs/hooks/copy_markdown.py +0 -0
  100. {msgflux-0.1.1 → msgflux-0.2.0}/docs/index.md +0 -0
  101. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/dotdict.md +0 -0
  102. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/chat_completion.md +0 -0
  103. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/image_text_to_image.md +0 -0
  104. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/model.md +0 -0
  105. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/model_gateway.md +0 -0
  106. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/moderation.md +0 -0
  107. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/speech_to_text.md +0 -0
  108. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/text_classifier.md +0 -0
  109. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/text_embedder.md +0 -0
  110. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/text_reranker.md +0 -0
  111. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/text_to_image.md +0 -0
  112. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/models/text_to_speech.md +0 -0
  113. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/async.md +0 -0
  114. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/debug.md +0 -0
  115. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/generation-schemas.md +0 -0
  116. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/hooks.md +0 -0
  117. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/index.md +0 -0
  118. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/model-gateway.md +0 -0
  119. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/prefilling.md +0 -0
  120. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/reasoning.md +0 -0
  121. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/signatures.md +0 -0
  122. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/streaming.md +0 -0
  123. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/system-prompt.md +0 -0
  124. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/task-and-context.md +0 -0
  125. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/agent/vars.md +0 -0
  126. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/functional.md +0 -0
  127. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/mediamaker.md +0 -0
  128. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/message.md +0 -0
  129. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/module/composing.md +0 -0
  130. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/module/core-concepts.md +0 -0
  131. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/module/forward-and-async.md +0 -0
  132. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/module/index.md +0 -0
  133. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/module/module-dict.md +0 -0
  134. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/module/module-list.md +0 -0
  135. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/module/sequential.md +0 -0
  136. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/module/visualization.md +0 -0
  137. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/predictor.md +0 -0
  138. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/nn/searcher.md +0 -0
  139. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/parsers.md +0 -0
  140. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/retrievers/fuzzy.md +0 -0
  141. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/retrievers/lexical.md +0 -0
  142. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/retrievers/retriever.md +0 -0
  143. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/retrievers/web.md +0 -0
  144. {msgflux-0.1.1 → msgflux-0.2.0}/docs/learn/telemetry.md +0 -0
  145. {msgflux-0.1.1 → msgflux-0.2.0}/docs/stylesheets/extra.css +0 -0
  146. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/ad-focus-group.md +0 -0
  147. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/advisor-specialist-tool.md +0 -0
  148. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/call-transcript-analysis.md +0 -0
  149. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/deal-briefing-generator.md +0 -0
  150. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/email-auto-responder.md +0 -0
  151. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/food-delivery-assistant.md +0 -0
  152. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/index.md +0 -0
  153. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/intent-router.md +0 -0
  154. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/lead-scoring.md +0 -0
  155. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/meeting-action-items.md +0 -0
  156. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/meeting-assistant.md +0 -0
  157. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/pix-assistant.md +0 -0
  158. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/plan-tool-with-root-context.md +0 -0
  159. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/product-poster.md +0 -0
  160. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/restaurant-supply-assistant.md +0 -0
  161. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/signature-router.md +0 -0
  162. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/streaming-support-triage.md +0 -0
  163. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/support-ticket-router.md +0 -0
  164. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/visit-report.md +0 -0
  165. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/workplace-incident-reporter.md +0 -0
  166. {msgflux-0.1.1 → msgflux-0.2.0}/docs/tutorials/youtube-cut-detector.md +0 -0
  167. {msgflux-0.1.1 → msgflux-0.2.0}/examples/ad_focus_group.py +0 -0
  168. {msgflux-0.1.1 → msgflux-0.2.0}/examples/advisor_specialist_tool.py +0 -0
  169. {msgflux-0.1.1 → msgflux-0.2.0}/examples/call_transcript_analysis.py +0 -0
  170. {msgflux-0.1.1 → msgflux-0.2.0}/examples/deal_briefing_generator.py +0 -0
  171. {msgflux-0.1.1 → msgflux-0.2.0}/examples/food_delivery_assistant.py +0 -0
  172. {msgflux-0.1.1 → msgflux-0.2.0}/examples/intent-router.py +0 -0
  173. {msgflux-0.1.1 → msgflux-0.2.0}/examples/lead_scoring.py +0 -0
  174. {msgflux-0.1.1 → msgflux-0.2.0}/examples/meeting_action_items.py +0 -0
  175. {msgflux-0.1.1 → msgflux-0.2.0}/examples/meeting_assistant.py +0 -0
  176. {msgflux-0.1.1 → msgflux-0.2.0}/examples/pix_assistant.py +0 -0
  177. {msgflux-0.1.1 → msgflux-0.2.0}/examples/plan_tool_with_root_history.py +0 -0
  178. {msgflux-0.1.1 → msgflux-0.2.0}/examples/restaurant-supply-assistant.py +0 -0
  179. {msgflux-0.1.1 → msgflux-0.2.0}/examples/streaming_support_triage.py +0 -0
  180. {msgflux-0.1.1 → msgflux-0.2.0}/examples/visit_report.py +0 -0
  181. {msgflux-0.1.1 → msgflux-0.2.0}/examples/youtube_cut_detector.py +0 -0
  182. {msgflux-0.1.1 → msgflux-0.2.0}/mkdocs.yml +0 -0
  183. {msgflux-0.1.1 → msgflux-0.2.0}/pyproject.toml +0 -0
  184. {msgflux-0.1.1 → msgflux-0.2.0}/scripts/setup-branch-protection.sh +0 -0
  185. {msgflux-0.1.1 → msgflux-0.2.0}/scripts/setup-labels.sh +0 -0
  186. {msgflux-0.1.1 → msgflux-0.2.0}/scripts/svg_render.py +0 -0
  187. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/_private/__init__.py +0 -0
  188. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/_private/client.py +0 -0
  189. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/_private/core.py +0 -0
  190. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/_private/executor.py +0 -0
  191. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/_private/response.py +0 -0
  192. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/auto/__init__.py +0 -0
  193. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/auto/params.py +0 -0
  194. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/cache.py +0 -0
  195. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/core/dotdict.py +0 -0
  196. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/core/examples.py +0 -0
  197. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/core/message.py +0 -0
  198. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/__init__.py +0 -0
  199. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/audio.py +0 -0
  200. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/__init__.py +0 -0
  201. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/base.py +0 -0
  202. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/db.py +0 -0
  203. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/providers/__init__.py +0 -0
  204. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/providers/cachetools.py +0 -0
  205. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/providers/diskcache.py +0 -0
  206. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/providers/faiss.py +0 -0
  207. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/registry.py +0 -0
  208. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/response.py +0 -0
  209. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/dbs/types.py +0 -0
  210. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/__init__.py +0 -0
  211. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/base.py +0 -0
  212. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/parser.py +0 -0
  213. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/providers/__init__.py +0 -0
  214. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/providers/csv_parser.py +0 -0
  215. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/providers/email_parser.py +0 -0
  216. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/providers/html_parser.py +0 -0
  217. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/providers/openpyxl.py +0 -0
  218. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/providers/pypdf.py +0 -0
  219. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/providers/python_docx.py +0 -0
  220. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/providers/python_pptx.py +0 -0
  221. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/registry.py +0 -0
  222. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/response.py +0 -0
  223. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/parsers/types.py +0 -0
  224. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/__init__.py +0 -0
  225. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/base.py +0 -0
  226. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/providers/__init__.py +0 -0
  227. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/providers/bm25.py +0 -0
  228. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/providers/bm25s.py +0 -0
  229. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/providers/rank_bm25.py +0 -0
  230. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/providers/rapidfuzz.py +0 -0
  231. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/providers/wikipedia.py +0 -0
  232. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/registry.py +0 -0
  233. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/retriever.py +0 -0
  234. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/retrievers/types.py +0 -0
  235. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/types/__init__.py +0 -0
  236. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/types/audio.py +0 -0
  237. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/types/base.py +0 -0
  238. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/types/file.py +0 -0
  239. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/types/image.py +0 -0
  240. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/data/types/video.py +0 -0
  241. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/dsl/__init__.py +0 -0
  242. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/dsl/inline.py +0 -0
  243. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/dsl/signature.py +0 -0
  244. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/dsl/typed_parsers/__init__.py +0 -0
  245. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/dsl/typed_parsers/base.py +0 -0
  246. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/dsl/typed_parsers/providers/__init__.py +0 -0
  247. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/dsl/typed_parsers/providers/xml.py +0 -0
  248. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/dsl/typed_parsers/registry.py +0 -0
  249. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/envs.py +0 -0
  250. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/exceptions.py +0 -0
  251. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/generation/__init__.py +0 -0
  252. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/generation/control_flow.py +0 -0
  253. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/generation/reasoning/__init__.py +0 -0
  254. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/generation/reasoning/cot.py +0 -0
  255. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/generation/reasoning/react.py +0 -0
  256. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/generation/reasoning/self_consistency.py +0 -0
  257. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/generation/templates.py +0 -0
  258. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/logger.py +0 -0
  259. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/__init__.py +0 -0
  260. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/base.py +0 -0
  261. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/cache.py +0 -0
  262. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/gateway.py +0 -0
  263. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/httpx.py +0 -0
  264. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/model.py +0 -0
  265. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/profiles/__init__.py +0 -0
  266. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/profiles/base.py +0 -0
  267. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/profiles/loader.py +0 -0
  268. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/profiles/registry.py +0 -0
  269. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/__init__.py +0 -0
  270. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/cerebras.py +0 -0
  271. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/groq.py +0 -0
  272. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/imagerouter.py +0 -0
  273. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/jinaai.py +0 -0
  274. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/ollama.py +0 -0
  275. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/openai.py +0 -0
  276. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/openrouter.py +0 -0
  277. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/replicate.py +0 -0
  278. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/sambanova.py +0 -0
  279. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/together.py +0 -0
  280. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/providers/vllm.py +0 -0
  281. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/registry.py +0 -0
  282. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/response.py +0 -0
  283. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/tool_call_agg.py +0 -0
  284. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/models/types.py +0 -0
  285. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/__init__.py +0 -0
  286. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/functional.py +0 -0
  287. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/hooks/__init__.py +0 -0
  288. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/hooks/guard.py +0 -0
  289. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/hooks/hook.py +0 -0
  290. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/__init__.py +0 -0
  291. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/container.py +0 -0
  292. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/embedder.py +0 -0
  293. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/generator.py +0 -0
  294. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/mediamaker.py +0 -0
  295. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/module.py +0 -0
  296. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/predictor.py +0 -0
  297. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/searcher.py +0 -0
  298. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/modules/tool.py +0 -0
  299. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/nn/parameter.py +0 -0
  300. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/__init__.py +0 -0
  301. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/__init__.py +0 -0
  302. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/auth/__init__.py +0 -0
  303. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/auth/apikey.py +0 -0
  304. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/auth/base.py +0 -0
  305. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/auth/basic.py +0 -0
  306. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/auth/bearer.py +0 -0
  307. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/auth/custom.py +0 -0
  308. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/auth/oauth2.py +0 -0
  309. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/client.py +0 -0
  310. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/exceptions.py +0 -0
  311. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/integration.py +0 -0
  312. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/loglevels.py +0 -0
  313. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/transports.py +0 -0
  314. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/protocols/mcp/types.py +0 -0
  315. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/py.typed +0 -0
  316. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/telemetry/__init__.py +0 -0
  317. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/telemetry/config.py +0 -0
  318. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/telemetry/span.py +0 -0
  319. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/tools/__init__.py +0 -0
  320. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/tools/builtin/__init__.py +0 -0
  321. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/tools/builtin/web_fetch.py +0 -0
  322. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/tools/config.py +0 -0
  323. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/tools/definitions.py +0 -0
  324. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/__init__.py +0 -0
  325. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/chat.py +0 -0
  326. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/common.py +0 -0
  327. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/console.py +0 -0
  328. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/convert.py +0 -0
  329. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/encode.py +0 -0
  330. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/html.py +0 -0
  331. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/imports.py +0 -0
  332. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/inspect.py +0 -0
  333. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/logging.py +0 -0
  334. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/mermaid.py +0 -0
  335. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/msgspec.py +0 -0
  336. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/pooling.py +0 -0
  337. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/templates.py +0 -0
  338. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/tenacity.py +0 -0
  339. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/torch.py +0 -0
  340. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/validation.py +0 -0
  341. {msgflux-0.1.1 → msgflux-0.2.0}/src/msgflux/utils/xml.py +0 -0
  342. {msgflux-0.1.1 → msgflux-0.2.0}/tests/__init__.py +0 -0
  343. {msgflux-0.1.1 → msgflux-0.2.0}/tests/auto/__init__.py +0 -0
  344. {msgflux-0.1.1 → msgflux-0.2.0}/tests/auto/test_params.py +0 -0
  345. {msgflux-0.1.1 → msgflux-0.2.0}/tests/conftest.py +0 -0
  346. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/__init__.py +0 -0
  347. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/parsers/__init__.py +0 -0
  348. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/parsers/test_parsers.py +0 -0
  349. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/retrievers/__init__.py +0 -0
  350. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/retrievers/providers/__init__.py +0 -0
  351. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/retrievers/providers/test_bm25.py +0 -0
  352. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/retrievers/providers/test_bm25s.py +0 -0
  353. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/retrievers/providers/test_rank_bm25.py +0 -0
  354. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/retrievers/providers/test_rapidfuzz.py +0 -0
  355. {msgflux-0.1.1 → msgflux-0.2.0}/tests/data/retrievers/providers/test_wikipedia.py +0 -0
  356. {msgflux-0.1.1 → msgflux-0.2.0}/tests/dsl/test_inline.py +0 -0
  357. {msgflux-0.1.1 → msgflux-0.2.0}/tests/dsl/test_signature.py +0 -0
  358. {msgflux-0.1.1 → msgflux-0.2.0}/tests/dsl/test_typed_parsers.py +0 -0
  359. {msgflux-0.1.1 → msgflux-0.2.0}/tests/generation/__init__.py +0 -0
  360. {msgflux-0.1.1 → msgflux-0.2.0}/tests/generation/test_control_flow.py +0 -0
  361. {msgflux-0.1.1 → msgflux-0.2.0}/tests/generation/test_reasoning.py +0 -0
  362. {msgflux-0.1.1 → msgflux-0.2.0}/tests/generation/test_templates.py +0 -0
  363. {msgflux-0.1.1 → msgflux-0.2.0}/tests/integration/test_agent_reasoning.py +0 -0
  364. {msgflux-0.1.1 → msgflux-0.2.0}/tests/integration/test_guard_moderation.py +0 -0
  365. {msgflux-0.1.1 → msgflux-0.2.0}/tests/integration/test_reasoning.py +0 -0
  366. {msgflux-0.1.1 → msgflux-0.2.0}/tests/integration/test_tool_dict_e2e.py +0 -0
  367. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/__init__.py +0 -0
  368. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/providers/__init__.py +0 -0
  369. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/providers/test_openai.py +0 -0
  370. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/providers/test_vllm.py +0 -0
  371. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_base.py +0 -0
  372. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_cache.py +0 -0
  373. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_gateway.py +0 -0
  374. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_httpx.py +0 -0
  375. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_model.py +0 -0
  376. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_profiles.py +0 -0
  377. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_registry.py +0 -0
  378. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_response.py +0 -0
  379. {msgflux-0.1.1 → msgflux-0.2.0}/tests/models/test_tool_call_agg.py +0 -0
  380. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/__init__.py +0 -0
  381. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/__init__.py +0 -0
  382. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_container.py +0 -0
  383. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_embedder.py +0 -0
  384. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_lm.py +0 -0
  385. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_mediamaker.py +0 -0
  386. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_module.py +0 -0
  387. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_predictor.py +0 -0
  388. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_searcher.py +0 -0
  389. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_tool.py +0 -0
  390. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/modules/test_tool_transport_params.py +0 -0
  391. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/test_functional.py +0 -0
  392. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/test_guard.py +0 -0
  393. {msgflux-0.1.1 → msgflux-0.2.0}/tests/nn/test_parameter.py +0 -0
  394. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/__init__.py +0 -0
  395. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/__init__.py +0 -0
  396. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/auth/test_auth_providers.py +0 -0
  397. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/conftest.py +0 -0
  398. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/mcp_simple_server.py +0 -0
  399. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/test_client.py +0 -0
  400. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/test_exceptions.py +0 -0
  401. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/test_integration.py +0 -0
  402. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/test_loglevels.py +0 -0
  403. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/test_mcp_live.py +0 -0
  404. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/test_toollibrary_mcp.py +0 -0
  405. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/test_transports.py +0 -0
  406. {msgflux-0.1.1 → msgflux-0.2.0}/tests/protocols/mcp/test_types.py +0 -0
  407. {msgflux-0.1.1 → msgflux-0.2.0}/tests/telemetry/__init__.py +0 -0
  408. {msgflux-0.1.1 → msgflux-0.2.0}/tests/telemetry/test_config.py +0 -0
  409. {msgflux-0.1.1 → msgflux-0.2.0}/tests/telemetry/test_span_agent_decorators.py +0 -0
  410. {msgflux-0.1.1 → msgflux-0.2.0}/tests/telemetry/test_span_tool_decorators.py +0 -0
  411. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_agent_as_tool_with_signature.py +0 -0
  412. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_agent_generation_schema.py +0 -0
  413. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_agent_image_detail.py +0 -0
  414. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_agent_include_date.py +0 -0
  415. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_agent_named_kwargs.py +0 -0
  416. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_agent_signature_annotations.py +0 -0
  417. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_agent_templates_fix.py +0 -0
  418. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_async_hooks.py +0 -0
  419. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_autoparams.py +0 -0
  420. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_data_types.py +0 -0
  421. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_dotdict.py +0 -0
  422. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_embedder.py +0 -0
  423. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_examples.py +0 -0
  424. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_image_block_kwargs_refactor.py +0 -0
  425. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_inject_message.py +0 -0
  426. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_mcp_fastmcp.py +0 -0
  427. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_tool_config_decorator.py +0 -0
  428. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_tools_visualization.py +0 -0
  429. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_type_inheritance_struct.py +0 -0
  430. {msgflux-0.1.1 → msgflux-0.2.0}/tests/test_video_block_kwargs.py +0 -0
  431. {msgflux-0.1.1 → msgflux-0.2.0}/tests/tools/__init__.py +0 -0
  432. {msgflux-0.1.1 → msgflux-0.2.0}/tests/tools/builtin/__init__.py +0 -0
  433. {msgflux-0.1.1 → msgflux-0.2.0}/tests/tools/builtin/test_web_fetch.py +0 -0
  434. {msgflux-0.1.1 → msgflux-0.2.0}/tests/tools/test_config.py +0 -0
  435. {msgflux-0.1.1 → msgflux-0.2.0}/tests/tools/test_toolflowcontrol.py +0 -0
  436. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_chat.py +0 -0
  437. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_common.py +0 -0
  438. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_console.py +0 -0
  439. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_convert.py +0 -0
  440. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_encode.py +0 -0
  441. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_hint_to_schema_dict.py +0 -0
  442. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_hooks.py +0 -0
  443. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_imports.py +0 -0
  444. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_inspect.py +0 -0
  445. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_logging.py +0 -0
  446. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_mermaid.py +0 -0
  447. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_msgspec.py +0 -0
  448. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_pooling.py +0 -0
  449. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_templates.py +0 -0
  450. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_tenacity.py +0 -0
  451. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_torch.py +0 -0
  452. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_validation.py +0 -0
  453. {msgflux-0.1.1 → msgflux-0.2.0}/tests/utils/test_xml.py +0 -0
  454. {msgflux-0.1.1 → msgflux-0.2.0}/uv.lock +0 -0
@@ -13,9 +13,15 @@ permissions:
13
13
 
14
14
  jobs:
15
15
  update_release_draft:
16
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
17
+ permissions:
18
+ contents: write
19
+ pull-requests: write
16
20
  runs-on: ubuntu-latest
17
21
  steps:
18
22
  - name: Update Release Draft
19
- uses: release-drafter/release-drafter@v6
23
+ uses: release-drafter/release-drafter@v7
24
+ with:
25
+ commitish: ${{ github.event.pull_request.base.ref || github.ref_name }}
20
26
  env:
21
27
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ ## [0.2.0] - 2026-04-17
4
+
5
+ - Features: added `provider/model-id` string shorthand support to `Agent`, `Speaker`, and `Transcriber` (#26, #27, #28), plus runtime tool controls for `Agent` (#30).
6
+ - Fixes: fixed registry naming for generic callables (#29).
7
+ - Maintenance: updated release automation and cleaned up the release script (#36, #49).
8
+
9
+ ## [0.1.1] - 2026-04-15
10
+
11
+ - Fixed message copying in the OpenAI provider (#47).
12
+ - Fixed isolation of injected messages for agent tools (#46).
13
+ - Updated CI and dependency tooling to keep release checks passing (#45, #44, #38, #37, #35, #34, #33, #32).
14
+
15
+ ## [0.1.0] - 2026-04-09
16
+
17
+ ## [0.1.0a31] - 2026-04-09
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: msgflux
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: Messages and Dynamic AI Systems in Python powered by pretrained models
5
5
  Project-URL: Homepage, https://github.com/msgflux/msgflux
6
6
  Project-URL: Documentation, https://github.com/msgflux/msgflux
@@ -78,6 +78,48 @@ flux = mf.Inline(
78
78
  )
79
79
  ```
80
80
 
81
+ ### Registry
82
+
83
+ Instead of building the modules dict by hand, use `mf.Registry` to collect
84
+ functions with a decorator and pass them as a `{name: callable}` mapping:
85
+
86
+ ```python
87
+ import msgflux as mf
88
+
89
+ modules = mf.Registry()
90
+
91
+ @modules
92
+ def prep(msg):
93
+ msg.ready = True
94
+
95
+ @modules
96
+ def feat_a(msg):
97
+ msg.score_a = 1
98
+
99
+ @modules
100
+ def feat_b(msg):
101
+ msg.score_b = 2
102
+
103
+ @modules
104
+ def combine(msg):
105
+ msg.total = msg.score_a + msg.score_b
106
+
107
+ flux = mf.Inline(
108
+ "prep -> [feat_a, feat_b] -> combine",
109
+ modules.to_items(), # {"prep": prep, "feat_a": feat_a, ...}
110
+ )
111
+
112
+ msg = mf.dotdict()
113
+ msg = flux(msg)
114
+
115
+ print(msg.ready) # True
116
+ print(msg.total) # 3
117
+ ```
118
+
119
+ The decorator captures each function's `__name__` automatically. Use
120
+ `@modules(name="custom")` to override the registered name when the
121
+ expression uses a different identifier.
122
+
81
123
  ---
82
124
 
83
125
  ## 3. **Execution**
@@ -68,6 +68,30 @@ Any `__init__` parameter can be set as a class attribute: `model`, `system_messa
68
68
 
69
69
  The `description` is especially useful when using an [agent as a tool](tools.md#agent-as-tool) — the calling agent uses it to understand what the tool-agent does.
70
70
 
71
+ ## String shorthand
72
+
73
+ When you do not need to configure extra model parameters, you can pass a
74
+ `"provider/model-id"` string directly as the `model` argument. msgFlux will
75
+ call `Model.chat_completion` internally.
76
+
77
+ ???+ example
78
+
79
+ ```python
80
+ import msgflux.nn as nn
81
+
82
+ agent = nn.Agent("assistant", "openai/gpt-4.1-mini")
83
+
84
+ response = agent("What is the capital of France?")
85
+ print(response) # "The capital of France is Paris."
86
+ ```
87
+
88
+ The string shorthand also works when reassigning `agent.model` after
89
+ construction:
90
+
91
+ ```python
92
+ agent.model = "groq/llama-3.1-8b-instant"
93
+ ```
94
+
71
95
  ## Adding Tools
72
96
 
73
97
  Agents can call functions to interact with external systems. Any callable with type annotations and a docstring can be used as a tool:
@@ -241,6 +241,86 @@ When the model decides to use a tool, the Agent intercepts the response, execute
241
241
  response = agent("Tell me about the history of the Python programming language")
242
242
  ```
243
243
 
244
+ ### Registry
245
+
246
+ Use `mf.Registry` to collect tools with a decorator instead of building a list by hand.
247
+ This is especially useful when tools are spread across multiple files or when you want
248
+ to keep them decoupled from the agent definition.
249
+
250
+ ```python
251
+ import msgflux as mf
252
+
253
+ tools = mf.Registry()
254
+
255
+ @tools
256
+ def add(a: float, b: float) -> str:
257
+ """Sum two numbers.
258
+
259
+ Args:
260
+ a: First number.
261
+ b: Second number.
262
+
263
+ Returns:
264
+ The result of the addition.
265
+ """
266
+ return f"{a} + {b} = {a + b}"
267
+
268
+ @tools(name="multiply")
269
+ def mul(a: float, b: float) -> str:
270
+ """Multiply two numbers.
271
+
272
+ Args:
273
+ a: First number.
274
+ b: Second number.
275
+
276
+ Returns:
277
+ The result of the multiplication.
278
+ """
279
+ return f"{a} * {b} = {a * b}"
280
+
281
+ print(tools.to_list()) # [<function add ...>, <function mul ...>]
282
+ print(tools.to_items()) # {"add": <function add ...>, "multiply": <function mul ...>}
283
+ ```
284
+
285
+ The decorator captures the callable's name automatically (`.__name__` for functions,
286
+ `.name` attribute if available). Pass `name=` to override:
287
+
288
+ | Usage | Captured name |
289
+ |-------|---------------|
290
+ | `@tools` | `add` (from `__name__`) |
291
+ | `@tools("custom")` | `custom` |
292
+ | `@tools(name="custom")` | `custom` |
293
+
294
+ Pass the registry directly to an Agent:
295
+
296
+ ```python
297
+ import msgflux.nn as nn
298
+
299
+ class Calculator(nn.Agent):
300
+ model = mf.Model.chat_completion("openai/gpt-4.1-mini")
301
+ tools = tools.to_list()
302
+ ```
303
+
304
+ You can have multiple independent registries — each is an isolated instance:
305
+
306
+ ```python
307
+ read_tools = mf.Registry()
308
+ write_tools = mf.Registry()
309
+
310
+ @read_tools
311
+ def get_data(key: str) -> str:
312
+ """Retrieve data by key."""
313
+ return f"value_for_{key}"
314
+
315
+ @write_tools
316
+ def save_data(key: str, value: str) -> str:
317
+ """Persist a key-value pair."""
318
+ return f"saved {key}={value}"
319
+
320
+ print(len(read_tools)) # 1
321
+ print(len(write_tools)) # 1
322
+ ```
323
+
244
324
  ### Writing Good Tools
245
325
 
246
326
  #### Tool Names
@@ -492,6 +572,173 @@ Control how the model selects tools.
492
572
  response = router("How do I handle errors in Rust?")
493
573
  ```
494
574
 
575
+ !!! note "Interaction with `tool_filter`"
576
+
577
+ `tool_choice` is resolved after runtime filtering.
578
+
579
+ - If `tool_filter` removes a specific tool configured in `tool_choice`, the Agent falls back to `"auto"` for that request
580
+ - If `tool_filter` removes all tools, tool usage is disabled for that request
581
+
582
+ ### Runtime Tool Filtering
583
+
584
+ Use `tool_filter` when you need to change which tools are exposed on a **per-request** basis, without rebuilding the agent.
585
+
586
+ **Rules:**
587
+
588
+ - `tool_filter` must contain exactly one key: `"allow"` or `"block"`
589
+ - The value can be a single tool name or a list of tool names
590
+ - `{"block": "*"}` disables all tools for that request
591
+ - Runtime `tool_filter=...` overrides the value loaded from `message_fields`
592
+
593
+ ???+ example
594
+
595
+ === "Allow Only Specific Tools"
596
+
597
+ ```python
598
+ # pip install msgflux[openai]
599
+ import msgflux as mf
600
+ import msgflux.nn as nn
601
+
602
+ # mf.set_envs(OPENAI_API_KEY="...")
603
+
604
+ def web_search(query: str) -> str:
605
+ """Search the web."""
606
+ return f"Search results for: {query}"
607
+
608
+ def calculator(expression: str) -> str:
609
+ """Evaluate a math expression."""
610
+ return f"Computed: {expression}"
611
+
612
+ def browser(url: str) -> str:
613
+ """Open a web page."""
614
+ return f"Fetched: {url}"
615
+
616
+ class Assistant(nn.Agent):
617
+ model = mf.Model.chat_completion("openai/gpt-4.1-mini")
618
+ tools = [web_search, calculator, browser]
619
+ config = {"verbose": True}
620
+
621
+ agent = Assistant()
622
+
623
+ response = agent(
624
+ "Search for the latest Python release and calculate 2 + 2",
625
+ tool_filter={"allow": ["web_search", "calculator"]},
626
+ )
627
+ ```
628
+
629
+ === "Block Specific Tools"
630
+
631
+ ```python
632
+ response = agent(
633
+ "Answer this without opening pages",
634
+ tool_filter={"block": "browser"},
635
+ )
636
+ ```
637
+
638
+ === "Disable All Tools Temporarily"
639
+
640
+ ```python
641
+ response = agent(
642
+ "Answer only from model knowledge",
643
+ tool_filter={"block": "*"},
644
+ )
645
+ ```
646
+
647
+ ### Tool Filter from Message
648
+
649
+ You can also load `tool_filter` from the input `Message` using `message_fields`.
650
+
651
+ This is useful when another module or router decides which tools should be available before the Agent runs.
652
+
653
+ ???+ example
654
+
655
+ ```python
656
+ # pip install msgflux[openai]
657
+ import msgflux as mf
658
+ import msgflux.nn as nn
659
+
660
+ # mf.set_envs(OPENAI_API_KEY="...")
661
+
662
+ def web_search(query: str) -> str:
663
+ """Search the web."""
664
+ return f"Search results for: {query}"
665
+
666
+ def calculator(expression: str) -> str:
667
+ """Evaluate a math expression."""
668
+ return f"Computed: {expression}"
669
+
670
+ class ControlledAgent(nn.Agent):
671
+ model = mf.Model.chat_completion("openai/gpt-4.1-mini")
672
+ tools = [web_search, calculator]
673
+ message_fields = {
674
+ "task": "content",
675
+ "tool_filter": "control.tool_filter",
676
+ }
677
+
678
+ agent = ControlledAgent()
679
+
680
+ msg = mf.Message(content="What is 25 * 17?")
681
+ msg.set("control.tool_filter", {"allow": "calculator"})
682
+
683
+ response = agent(msg)
684
+ ```
685
+
686
+ !!! tip
687
+
688
+ Runtime kwargs still take precedence:
689
+
690
+ ```python
691
+ response = agent(
692
+ msg,
693
+ tool_filter={"block": "*"}, # overrides msg.control.tool_filter
694
+ )
695
+ ```
696
+
697
+ ### Limiting Tool Loops
698
+
699
+ Use `config["max_tool_turns"]` to cap how many **completed tool rounds** an Agent can execute in a single request.
700
+
701
+ When the limit is reached:
702
+
703
+ - The next attempted tool round is not executed
704
+ - The Agent makes one more model call with tools disabled
705
+ - The model gets a final chance to produce a plain answer
706
+
707
+ This is useful to avoid runaway tool loops while still allowing a graceful final response.
708
+
709
+ ???+ example
710
+
711
+ ```python
712
+ # pip install msgflux[openai] wikipedia
713
+ import msgflux as mf
714
+ import msgflux.nn as nn
715
+
716
+ # mf.set_envs(OPENAI_API_KEY="...")
717
+
718
+ wikipedia = mf.Retriever.web_search("wikipedia")
719
+
720
+ class Researcher(nn.Agent):
721
+ model = mf.Model.chat_completion("openai/gpt-4.1-mini")
722
+ system_message = "Use tools when needed, but finish with a concise answer."
723
+ tools = [wikipedia]
724
+ config = {
725
+ "tool_choice": "auto",
726
+ "max_tool_turns": 2,
727
+ "verbose": True,
728
+ }
729
+
730
+ agent = Researcher()
731
+
732
+ response = agent("Compare Python and Ruby and keep the answer short")
733
+ ```
734
+
735
+ !!! note
736
+
737
+ `max_tool_turns` is different from `tool_choice="none"`:
738
+
739
+ - `tool_choice="none"` disables tools from the start
740
+ - `max_tool_turns` allows some tool usage first, then forces a final no-tools round if the loop keeps going
741
+
495
742
  ### Async Tools
496
743
 
497
744
  When your agent runs asynchronously with `acall()`, prefer writing async tools as well. This ensures non-blocking execution and better performance when tools perform I/O operations.
@@ -41,6 +41,25 @@ The `nn.Speaker` module converts text into natural-sounding speech using text-to
41
41
  audio_path = speaker("Hello world")
42
42
  ```
43
43
 
44
+ ## String shorthand
45
+
46
+ When you do not need to configure extra model parameters, you can pass a
47
+ `"provider/model-id"` string directly as the `model` argument. msgFlux will
48
+ call `Model.text_to_speech` internally.
49
+
50
+ ```python
51
+ import msgflux.nn as nn
52
+
53
+ speaker = nn.Speaker("openai/gpt-4o-mini-tts")
54
+ audio_path = speaker("Hello world")
55
+ ```
56
+
57
+ The shorthand also works when reassigning `speaker.model` after construction:
58
+
59
+ ```python
60
+ speaker.model = "openai/gpt-4o-mini-tts"
61
+ ```
62
+
44
63
  ---
45
64
 
46
65
  ## 2. **Audio Formats**
@@ -38,6 +38,26 @@ The `nn.Transcriber` module wraps speech-to-text models to **transcribe audio**
38
38
  result = transcriber("/path/to/audio.mp3")
39
39
  ```
40
40
 
41
+ ## String shorthand
42
+
43
+ When you do not need to configure extra model parameters, you can pass a
44
+ `"provider/model-id"` string directly as the `model` argument. msgFlux will
45
+ call `Model.speech_to_text` internally.
46
+
47
+ ```python
48
+ import msgflux.nn as nn
49
+
50
+ transcriber = nn.Transcriber("openai/whisper-1")
51
+ result = transcriber("/path/to/audio.mp3")
52
+ ```
53
+
54
+ The shorthand also works when reassigning `transcriber.model` after
55
+ construction:
56
+
57
+ ```python
58
+ transcriber.model = "openai/whisper-1"
59
+ ```
60
+
41
61
  ---
42
62
 
43
63
  ## 2. **Input Types**
@@ -198,7 +198,8 @@ git checkout -b "$BRANCH_NAME"
198
198
  # Commit changes
199
199
  echo -e "${BLUE}💾 Committing changes...${NC}"
200
200
  git add src/msgflux/version.py CHANGELOG.md
201
- git commit -m "RELEASE: v$NEW_VERSION
201
+ COMMIT_MSG=$(cat <<EOF
202
+ RELEASE: v$NEW_VERSION
202
203
 
203
204
  This release updates:
204
205
  - version.py: $CURRENT_VERSION → $NEW_VERSION
@@ -208,10 +209,9 @@ After merging this PR:
208
209
  - publish.yml workflow will trigger automatically
209
210
  - Package will be built and published to PyPI
210
211
  - GitHub release will be created with tag v$NEW_VERSION
211
-
212
- 🤖 Generated with [Claude Code](https://claude.com/claude-code)
213
-
214
- Co-Authored-By: Claude <noreply@anthropic.com>"
212
+ EOF
213
+ )
214
+ git commit -m "$COMMIT_MSG"
215
215
 
216
216
  # Push release branch
217
217
  echo -e "${BLUE}📤 Pushing release branch...${NC}"
@@ -226,12 +226,8 @@ if [ "$ORIGIN_REPO" != "$BASE_REPO" ]; then
226
226
  PR_HEAD="${ORIGIN_OWNER}:${BRANCH_NAME}"
227
227
  fi
228
228
 
229
- PR_URL=$(gh pr create \
230
- --repo "$BASE_REPO" \
231
- --base main \
232
- --head "$PR_HEAD" \
233
- --title "$PR_TITLE" \
234
- --body "## 🚀 Release v$NEW_VERSION
229
+ PR_BODY=$(cat <<EOF
230
+ ## 🚀 Release v$NEW_VERSION
235
231
 
236
232
  ### Changes
237
233
  - **Version**: $CURRENT_VERSION → $NEW_VERSION
@@ -252,11 +248,16 @@ PR_URL=$(gh pr create \
252
248
  ### Merge Instructions
253
249
  After CI passes, merge this PR using one of:
254
250
  - Merge bot: Comment \`@mergebot merge\`
255
- - GitHub UI: Use \"Squash and merge\"
256
-
257
- ---
251
+ - GitHub UI: Use "Squash and merge"
252
+ EOF
253
+ )
258
254
 
259
- 🤖 Generated with [Claude Code](https://claude.com/claude-code)" \
255
+ PR_URL=$(gh pr create \
256
+ --repo "$BASE_REPO" \
257
+ --base main \
258
+ --head "$PR_HEAD" \
259
+ --title "$PR_TITLE" \
260
+ --body "$PR_BODY" \
260
261
  --label "release" \
261
262
  --label "automerge")
262
263
 
@@ -8,6 +8,7 @@ if TYPE_CHECKING:
8
8
  from msgflux.core.dotdict import dotdict
9
9
  from msgflux.core.examples import Example
10
10
  from msgflux.core.message import Message
11
+ from msgflux.core.registry import Registry
11
12
  from msgflux.data.dbs import DB
12
13
  from msgflux.data.parsers import Parser
13
14
  from msgflux.data.retrievers import Retriever
@@ -40,6 +41,7 @@ __all__ = [
40
41
  "ModelGateway",
41
42
  "OutputField",
42
43
  "Parser",
44
+ "Registry",
43
45
  "Retriever",
44
46
  "Signature",
45
47
  "Spans",
@@ -72,6 +74,7 @@ _LAZY_IMPORTS = {
72
74
  "ModelGateway": ("msgflux.models.gateway", "ModelGateway"),
73
75
  "OutputField": ("msgflux.dsl.signature", "OutputField"),
74
76
  "Parser": ("msgflux.data.parsers", "Parser"),
77
+ "Registry": ("msgflux.core.registry", "Registry"),
75
78
  "Retriever": ("msgflux.data.retrievers", "Retriever"),
76
79
  "Signature": ("msgflux.dsl.signature", "Signature"),
77
80
  "Spans": ("msgflux.telemetry", "Spans"),
@@ -1,5 +1,6 @@
1
1
  from msgflux.core.dotdict import dotdict
2
2
  from msgflux.core.examples import Example, ExampleCollection
3
3
  from msgflux.core.message import Message
4
+ from msgflux.core.registry import Registry
4
5
 
5
- __all__ = ["Example", "ExampleCollection", "Message", "dotdict"]
6
+ __all__ = ["Example", "ExampleCollection", "Message", "Registry", "dotdict"]
@@ -0,0 +1,126 @@
1
+ from typing import Any, Callable, TypeVar, overload
2
+
3
+ T = TypeVar("T", bound=Callable[..., Any])
4
+
5
+
6
+ class Registry:
7
+ """Instance-based callable registry.
8
+
9
+ A decorator-based registry that collects callables (tools, modules, functions)
10
+ and exposes them as a list or a name-to-callable dict.
11
+
12
+ Examples
13
+ --------
14
+ Register tools for an Agent::
15
+
16
+ tools = Registry()
17
+
18
+ @tools
19
+ def search(query: str) -> str: ...
20
+
21
+ @tools(name="web_fetch")
22
+ def fetch(url: str) -> str: ...
23
+
24
+ agent = Agent(tools=tools.to_list())
25
+
26
+ Register modules for Inline::
27
+
28
+ modules = Registry()
29
+
30
+ @modules(name="summarizer")
31
+ class Summarizer(Module): ...
32
+
33
+ pipeline = Inline(modules=modules.to_items())
34
+ """
35
+
36
+ def __init__(self) -> None:
37
+ self._entries: dict[str, Any] = {}
38
+
39
+ def _resolve_name(self, obj: Any) -> str:
40
+ """Extract a registration name from a callable-like object."""
41
+ if hasattr(obj, "name"):
42
+ name = obj.name
43
+ if callable(name) and not isinstance(name, str):
44
+ name = name()
45
+ if isinstance(name, str) and name:
46
+ return name
47
+
48
+ dunder_name = getattr(obj, "__name__", None)
49
+ if isinstance(dunder_name, str) and dunder_name:
50
+ return dunder_name
51
+ raise TypeError(
52
+ "Unable to resolve a registry name. Provide `name=` or define `.name` "
53
+ "or `.__name__` on the registered object."
54
+ )
55
+
56
+ @overload
57
+ def __call__(self, obj: T) -> T: ...
58
+
59
+ @overload
60
+ def __call__(self, *, name: str) -> Callable[[T], T]: ...
61
+
62
+ @overload
63
+ def __call__(self, name: str) -> Callable[[T], T]: ...
64
+
65
+ def __call__(
66
+ self,
67
+ obj: T | str | None = None,
68
+ *,
69
+ name: str | None = None,
70
+ ) -> T | Callable[[T], T]:
71
+ # @registry
72
+ if obj is not None and callable(obj) and not isinstance(obj, str):
73
+ resolved = self._resolve_name(obj)
74
+ self._entries[resolved] = obj
75
+ return obj
76
+
77
+ # @registry("custom_name") or @registry(name="custom_name")
78
+ explicit_name = obj if isinstance(obj, str) else name
79
+
80
+ def decorator(fn: T) -> T:
81
+ key = explicit_name if explicit_name else self._resolve_name(fn)
82
+ self._entries[key] = fn
83
+ return fn
84
+
85
+ return decorator
86
+
87
+ def to_list(self) -> list[Any]:
88
+ """Return registered callables as a list."""
89
+ return list(self._entries.values())
90
+
91
+ def to_items(self) -> dict[str, Any]:
92
+ """Return registered callables as a ``{name: callable}`` dict."""
93
+ return dict(self._entries)
94
+
95
+ def update(self, other: "Registry") -> "Registry":
96
+ """Merge entries from *other* into this registry.
97
+
98
+ Returns ``self`` for chaining.
99
+ """
100
+ self._entries.update(other._entries)
101
+ return self
102
+
103
+ def get(self, name: str) -> Any:
104
+ """Return a single registered callable by name."""
105
+ return self._entries[name]
106
+
107
+ def pop(self, name: str) -> Any:
108
+ """Remove and return the callable registered under *name*."""
109
+ return self._entries.pop(name)
110
+
111
+ def clear(self) -> None:
112
+ """Remove all entries."""
113
+ self._entries.clear()
114
+
115
+ def __contains__(self, name: str) -> bool:
116
+ return name in self._entries
117
+
118
+ def __len__(self) -> int:
119
+ return len(self._entries)
120
+
121
+ def __iter__(self):
122
+ return iter(self._entries.values())
123
+
124
+ def __repr__(self) -> str:
125
+ names = list(self._entries.keys())
126
+ return f"Registry({names})"