msgflux 0.3.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (502) hide show
  1. {msgflux-0.3.0 → msgflux-0.5.0}/.pre-commit-config.yaml +2 -2
  2. msgflux-0.5.0/CHANGELOG.md +66 -0
  3. {msgflux-0.3.0 → msgflux-0.5.0}/PKG-INFO +2 -1
  4. {msgflux-0.3.0 → msgflux-0.5.0}/docs/dependency-management.md +23 -13
  5. {msgflux-0.3.0 → msgflux-0.5.0}/docs/index.md +2 -0
  6. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/chat_completion.md +132 -0
  7. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/hooks.md +101 -11
  8. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/index.md +2 -0
  9. msgflux-0.5.0/docs/learn/nn/agent/prompt-cache.md +159 -0
  10. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/signatures.md +95 -0
  11. msgflux-0.5.0/docs/learn/nn/agent/skills.md +324 -0
  12. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/tools.md +395 -1
  13. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/module/forward-and-async.md +35 -0
  14. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/retrievers/retriever.md +31 -4
  15. msgflux-0.5.0/docs/learn/retrievers/weather.md +182 -0
  16. msgflux-0.5.0/docs/learn/retrievers/web.md +891 -0
  17. msgflux-0.5.0/examples/agent_skills_demo.py +126 -0
  18. {msgflux-0.3.0 → msgflux-0.5.0}/mkdocs.yml +3 -13
  19. {msgflux-0.3.0 → msgflux-0.5.0}/pyproject.toml +1 -0
  20. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/__init__.py +17 -0
  21. msgflux-0.5.0/src/msgflux/data/retrievers/providers/arxiv.py +229 -0
  22. msgflux-0.5.0/src/msgflux/data/retrievers/providers/brave.py +149 -0
  23. msgflux-0.5.0/src/msgflux/data/retrievers/providers/ceramic.py +143 -0
  24. msgflux-0.5.0/src/msgflux/data/retrievers/providers/exa.py +196 -0
  25. msgflux-0.5.0/src/msgflux/data/retrievers/providers/linkup.py +162 -0
  26. msgflux-0.5.0/src/msgflux/data/retrievers/providers/open_meteo.py +650 -0
  27. msgflux-0.5.0/src/msgflux/data/retrievers/providers/searxng.py +198 -0
  28. msgflux-0.5.0/src/msgflux/data/retrievers/providers/serpapi.py +225 -0
  29. msgflux-0.5.0/src/msgflux/data/retrievers/providers/tavily.py +180 -0
  30. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/retriever.py +10 -0
  31. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/types.py +6 -0
  32. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/dsl/signature.py +49 -2
  33. msgflux-0.5.0/src/msgflux/generation/templates.py +86 -0
  34. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/gateway.py +116 -0
  35. msgflux-0.5.0/src/msgflux/models/providers/brave.py +27 -0
  36. msgflux-0.5.0/src/msgflux/models/providers/exa.py +57 -0
  37. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/groq.py +1 -1
  38. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/ollama.py +1 -1
  39. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/openai.py +115 -0
  40. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/openrouter.py +1 -1
  41. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/vllm.py +1 -1
  42. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/types.py +24 -0
  43. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/hooks/guard.py +33 -8
  44. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/hooks/hook.py +15 -2
  45. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/agent.py +234 -20
  46. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/module.py +220 -2
  47. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/tool.py +57 -0
  48. msgflux-0.5.0/src/msgflux/runtime/__init__.py +19 -0
  49. msgflux-0.5.0/src/msgflux/runtime/skills.py +544 -0
  50. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/tools/__init__.py +7 -1
  51. msgflux-0.5.0/src/msgflux/tools/builtin/__init__.py +8 -0
  52. msgflux-0.5.0/src/msgflux/tools/builtin/agent_skills.py +48 -0
  53. msgflux-0.5.0/src/msgflux/tools/builtin/weather.py +30 -0
  54. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/tools/builtin/web_fetch.py +1 -0
  55. msgflux-0.5.0/src/msgflux/tools/builtin/web_search.py +260 -0
  56. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/tools/config.py +9 -0
  57. msgflux-0.5.0/src/msgflux/tools/guidance.py +58 -0
  58. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/chat.py +15 -0
  59. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/msgspec.py +18 -3
  60. msgflux-0.5.0/src/msgflux/version.py +1 -0
  61. msgflux-0.5.0/tests/data/retrievers/providers/test_arxiv.py +173 -0
  62. msgflux-0.5.0/tests/data/retrievers/providers/test_brave.py +114 -0
  63. msgflux-0.5.0/tests/data/retrievers/providers/test_ceramic.py +200 -0
  64. msgflux-0.5.0/tests/data/retrievers/providers/test_exa.py +174 -0
  65. msgflux-0.5.0/tests/data/retrievers/providers/test_linkup.py +149 -0
  66. msgflux-0.5.0/tests/data/retrievers/providers/test_searxng.py +255 -0
  67. msgflux-0.5.0/tests/data/retrievers/providers/test_serpapi.py +275 -0
  68. msgflux-0.5.0/tests/data/retrievers/providers/test_tavily.py +146 -0
  69. msgflux-0.5.0/tests/integration/test_tool_msgspec_struct_e2e.py +70 -0
  70. msgflux-0.5.0/tests/models/providers/test_brave.py +35 -0
  71. msgflux-0.5.0/tests/models/providers/test_exa.py +49 -0
  72. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/providers/test_openai.py +227 -0
  73. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/providers/test_vllm.py +24 -0
  74. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_agent.py +130 -0
  75. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_module.py +131 -0
  76. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_tool.py +134 -0
  77. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_tool_transport_params.py +55 -0
  78. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/test_guard.py +65 -0
  79. msgflux-0.5.0/tests/test_agent_input_validation.py +114 -0
  80. msgflux-0.5.0/tests/test_agent_prompt_warmup.py +96 -0
  81. msgflux-0.5.0/tests/test_agent_skills.py +726 -0
  82. msgflux-0.5.0/tests/tools/builtin/test_weather.py +290 -0
  83. {msgflux-0.3.0 → msgflux-0.5.0}/tests/tools/builtin/test_web_fetch.py +8 -1
  84. msgflux-0.5.0/tests/tools/builtin/test_web_search.py +312 -0
  85. {msgflux-0.3.0 → msgflux-0.5.0}/tests/tools/test_config.py +18 -0
  86. msgflux-0.5.0/tests/tools/test_guidance.py +53 -0
  87. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_chat.py +31 -0
  88. {msgflux-0.3.0 → msgflux-0.5.0}/uv.lock +72 -172
  89. msgflux-0.3.0/CHANGELOG.md +0 -24
  90. msgflux-0.3.0/docs/learn/retrievers/web.md +0 -196
  91. msgflux-0.3.0/src/msgflux/generation/templates.py +0 -53
  92. msgflux-0.3.0/src/msgflux/tools/builtin/__init__.py +0 -5
  93. msgflux-0.3.0/src/msgflux/version.py +0 -1
  94. {msgflux-0.3.0 → msgflux-0.5.0}/.github/CODEOWNERS +0 -0
  95. {msgflux-0.3.0 → msgflux-0.5.0}/.github/SECURITY.md +0 -0
  96. {msgflux-0.3.0 → msgflux-0.5.0}/.github/dependabot.yml +0 -0
  97. {msgflux-0.3.0 → msgflux-0.5.0}/.github/labeler.yml +0 -0
  98. {msgflux-0.3.0 → msgflux-0.5.0}/.github/pull_request_template.md +0 -0
  99. {msgflux-0.3.0 → msgflux-0.5.0}/.github/release-drafter.yml +0 -0
  100. {msgflux-0.3.0 → msgflux-0.5.0}/.github/workflows/ci.yml +0 -0
  101. {msgflux-0.3.0 → msgflux-0.5.0}/.github/workflows/docs.yml +0 -0
  102. {msgflux-0.3.0 → msgflux-0.5.0}/.github/workflows/labeler.yml +0 -0
  103. {msgflux-0.3.0 → msgflux-0.5.0}/.github/workflows/merge-bot.yml +0 -0
  104. {msgflux-0.3.0 → msgflux-0.5.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
  105. {msgflux-0.3.0 → msgflux-0.5.0}/.github/workflows/publish.yml +0 -0
  106. {msgflux-0.3.0 → msgflux-0.5.0}/.github/workflows/release-drafter.yml +0 -0
  107. {msgflux-0.3.0 → msgflux-0.5.0}/.github/workflows/validate-release.yml +0 -0
  108. {msgflux-0.3.0 → msgflux-0.5.0}/.gitignore +0 -0
  109. {msgflux-0.3.0 → msgflux-0.5.0}/.python-version +0 -0
  110. {msgflux-0.3.0 → msgflux-0.5.0}/.readthedocs.yaml +0 -0
  111. {msgflux-0.3.0 → msgflux-0.5.0}/CONTRIBUTING.md +0 -0
  112. {msgflux-0.3.0 → msgflux-0.5.0}/LICENSE +0 -0
  113. {msgflux-0.3.0 → msgflux-0.5.0}/README.md +0 -0
  114. {msgflux-0.3.0 → msgflux-0.5.0}/docs/CHANGELOG.md +0 -0
  115. {msgflux-0.3.0 → msgflux-0.5.0}/docs/CNAME +0 -0
  116. {msgflux-0.3.0 → msgflux-0.5.0}/docs/_includes/init_chat_completion_model.md +0 -0
  117. {msgflux-0.3.0 → msgflux-0.5.0}/docs/_includes/install.md +0 -0
  118. {msgflux-0.3.0 → msgflux-0.5.0}/docs/_includes/install_openai.md +0 -0
  119. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/agent.md +0 -0
  120. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/chat-schema-utils.md +0 -0
  121. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/dict-lowering-and-restoration.md +0 -0
  122. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/index.md +0 -0
  123. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/llm-as-a-verifier.md +0 -0
  124. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/logical-vs-provider-schema.md +0 -0
  125. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/msgspec-transport-lowering.md +0 -0
  126. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/openai-chat-completion.md +0 -0
  127. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/react-provider-schemas.md +0 -0
  128. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/signatures.md +0 -0
  129. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/tool-flow-control.md +0 -0
  130. {msgflux-0.3.0 → msgflux-0.5.0}/docs/anatomy/tool-library.md +0 -0
  131. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/databases/database.md +0 -0
  132. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/databases/types/kv.md +0 -0
  133. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/databases/types/vector.md +0 -0
  134. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/model.md +0 -0
  135. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/model_gateway.md +0 -0
  136. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/chat_completion.md +0 -0
  137. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/image_classifier.md +0 -0
  138. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/image_embedder.md +0 -0
  139. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/image_text_to_image.md +0 -0
  140. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/moderation.md +0 -0
  141. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/speech_to_text.md +0 -0
  142. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/text_classifier.md +0 -0
  143. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/text_embedder.md +0 -0
  144. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/text_reranker.md +0 -0
  145. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/text_to_image.md +0 -0
  146. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/models/types/text_to_speech.md +0 -0
  147. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/functional.md +0 -0
  148. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/agent.md +0 -0
  149. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/module.md +0 -0
  150. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/module_dict.md +0 -0
  151. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/module_list.md +0 -0
  152. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/predictor.md +0 -0
  153. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/searcher.md +0 -0
  154. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/sequential.md +0 -0
  155. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/speaker.md +0 -0
  156. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/tool.md +0 -0
  157. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference/nn/modules/transcriber.md +0 -0
  158. {msgflux-0.3.0 → msgflux-0.5.0}/docs/api-reference.md +0 -0
  159. {msgflux-0.3.0 → msgflux-0.5.0}/docs/assets/logo-msgflux-horizon.png +0 -0
  160. {msgflux-0.3.0 → msgflux-0.5.0}/docs/assets/logo.png +0 -0
  161. {msgflux-0.3.0 → msgflux-0.5.0}/docs/assets/msgflux-wordmark.png +0 -0
  162. {msgflux-0.3.0 → msgflux-0.5.0}/docs/assets/msgflux.png +0 -0
  163. {msgflux-0.3.0 → msgflux-0.5.0}/docs/assets/tmd-mascot.png +0 -0
  164. {msgflux-0.3.0 → msgflux-0.5.0}/docs/blog/.authors.yml +0 -0
  165. {msgflux-0.3.0 → msgflux-0.5.0}/docs/blog/index.md +0 -0
  166. {msgflux-0.3.0 → msgflux-0.5.0}/docs/blog/posts/.meta.yml +0 -0
  167. {msgflux-0.3.0 → msgflux-0.5.0}/docs/blog/posts/26-04/why-msgflux-exists.md +0 -0
  168. {msgflux-0.3.0 → msgflux-0.5.0}/docs/changelog.md +0 -0
  169. {msgflux-0.3.0 → msgflux-0.5.0}/docs/hooks/copy_markdown.py +0 -0
  170. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/dotdict.md +0 -0
  171. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/inline.md +0 -0
  172. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/image_text_to_image.md +0 -0
  173. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/model.md +0 -0
  174. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/model_gateway.md +0 -0
  175. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/moderation.md +0 -0
  176. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/speech_to_text.md +0 -0
  177. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/text_classifier.md +0 -0
  178. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/text_embedder.md +0 -0
  179. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/text_reranker.md +0 -0
  180. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/text_to_image.md +0 -0
  181. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/models/text_to_speech.md +0 -0
  182. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/async.md +0 -0
  183. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/debug.md +0 -0
  184. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/generation-schemas.md +0 -0
  185. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/model-gateway.md +0 -0
  186. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/prefilling.md +0 -0
  187. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/quickstart.md +0 -0
  188. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/reasoning.md +0 -0
  189. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/streaming.md +0 -0
  190. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/system-prompt.md +0 -0
  191. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/task-and-context.md +0 -0
  192. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/agent/vars.md +0 -0
  193. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/functional.md +0 -0
  194. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/mediamaker.md +0 -0
  195. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/message.md +0 -0
  196. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/module/composing.md +0 -0
  197. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/module/core-concepts.md +0 -0
  198. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/module/index.md +0 -0
  199. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/module/module-dict.md +0 -0
  200. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/module/module-list.md +0 -0
  201. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/module/sequential.md +0 -0
  202. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/module/visualization.md +0 -0
  203. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/predictor.md +0 -0
  204. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/searcher.md +0 -0
  205. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/speaker.md +0 -0
  206. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/nn/transcriber.md +0 -0
  207. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/parsers.md +0 -0
  208. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/retrievers/fuzzy.md +0 -0
  209. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/retrievers/lexical.md +0 -0
  210. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/telemetry.md +0 -0
  211. {msgflux-0.3.0 → msgflux-0.5.0}/docs/learn/verifiers.md +0 -0
  212. {msgflux-0.3.0 → msgflux-0.5.0}/docs/stylesheets/extra.css +0 -0
  213. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/ad-focus-group.md +0 -0
  214. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/advisor-specialist-tool.md +0 -0
  215. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/call-transcript-analysis.md +0 -0
  216. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/deal-briefing-generator.md +0 -0
  217. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/email-auto-responder.md +0 -0
  218. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/food-delivery-assistant.md +0 -0
  219. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/index.md +0 -0
  220. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/intent-router.md +0 -0
  221. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/lead-scoring.md +0 -0
  222. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/meeting-action-items.md +0 -0
  223. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/meeting-assistant.md +0 -0
  224. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/pix-assistant.md +0 -0
  225. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/plan-tool-with-root-context.md +0 -0
  226. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/product-poster.md +0 -0
  227. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/restaurant-supply-assistant.md +0 -0
  228. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/signature-router.md +0 -0
  229. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/streaming-support-triage.md +0 -0
  230. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/support-ticket-router.md +0 -0
  231. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/visit-report.md +0 -0
  232. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/workplace-incident-reporter.md +0 -0
  233. {msgflux-0.3.0 → msgflux-0.5.0}/docs/tutorials/youtube-cut-detector.md +0 -0
  234. {msgflux-0.3.0 → msgflux-0.5.0}/examples/ad_focus_group.py +0 -0
  235. {msgflux-0.3.0 → msgflux-0.5.0}/examples/advisor_specialist_tool.py +0 -0
  236. {msgflux-0.3.0 → msgflux-0.5.0}/examples/call_transcript_analysis.py +0 -0
  237. {msgflux-0.3.0 → msgflux-0.5.0}/examples/deal_briefing_generator.py +0 -0
  238. {msgflux-0.3.0 → msgflux-0.5.0}/examples/food_delivery_assistant.py +0 -0
  239. {msgflux-0.3.0 → msgflux-0.5.0}/examples/intent-router.py +0 -0
  240. {msgflux-0.3.0 → msgflux-0.5.0}/examples/lead_scoring.py +0 -0
  241. {msgflux-0.3.0 → msgflux-0.5.0}/examples/meeting_action_items.py +0 -0
  242. {msgflux-0.3.0 → msgflux-0.5.0}/examples/meeting_assistant.py +0 -0
  243. {msgflux-0.3.0 → msgflux-0.5.0}/examples/pix_assistant.py +0 -0
  244. {msgflux-0.3.0 → msgflux-0.5.0}/examples/plan_tool_with_root_history.py +0 -0
  245. {msgflux-0.3.0 → msgflux-0.5.0}/examples/restaurant-supply-assistant.py +0 -0
  246. {msgflux-0.3.0 → msgflux-0.5.0}/examples/streaming_support_triage.py +0 -0
  247. {msgflux-0.3.0 → msgflux-0.5.0}/examples/visit_report.py +0 -0
  248. {msgflux-0.3.0 → msgflux-0.5.0}/examples/youtube_cut_detector.py +0 -0
  249. {msgflux-0.3.0 → msgflux-0.5.0}/scripts/release.sh +0 -0
  250. {msgflux-0.3.0 → msgflux-0.5.0}/scripts/setup-branch-protection.sh +0 -0
  251. {msgflux-0.3.0 → msgflux-0.5.0}/scripts/setup-labels.sh +0 -0
  252. {msgflux-0.3.0 → msgflux-0.5.0}/scripts/svg_render.py +0 -0
  253. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/_private/__init__.py +0 -0
  254. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/_private/client.py +0 -0
  255. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/_private/core.py +0 -0
  256. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/_private/executor.py +0 -0
  257. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/_private/response.py +0 -0
  258. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/auto/__init__.py +0 -0
  259. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/auto/params.py +0 -0
  260. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/cache.py +0 -0
  261. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/core/__init__.py +0 -0
  262. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/core/dotdict.py +0 -0
  263. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/core/examples.py +0 -0
  264. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/core/message.py +0 -0
  265. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/core/registry.py +0 -0
  266. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/__init__.py +0 -0
  267. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/audio.py +0 -0
  268. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/__init__.py +0 -0
  269. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/base.py +0 -0
  270. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/db.py +0 -0
  271. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/providers/__init__.py +0 -0
  272. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/providers/cachetools.py +0 -0
  273. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/providers/diskcache.py +0 -0
  274. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/providers/faiss.py +0 -0
  275. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/registry.py +0 -0
  276. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/response.py +0 -0
  277. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/dbs/types.py +0 -0
  278. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/__init__.py +0 -0
  279. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/base.py +0 -0
  280. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/parser.py +0 -0
  281. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/providers/__init__.py +0 -0
  282. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/providers/csv_parser.py +0 -0
  283. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/providers/email_parser.py +0 -0
  284. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/providers/html_parser.py +0 -0
  285. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/providers/openpyxl.py +0 -0
  286. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/providers/pypdf.py +0 -0
  287. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/providers/python_docx.py +0 -0
  288. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/providers/python_pptx.py +0 -0
  289. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/registry.py +0 -0
  290. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/response.py +0 -0
  291. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/parsers/types.py +0 -0
  292. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/__init__.py +0 -0
  293. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/base.py +0 -0
  294. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/providers/__init__.py +0 -0
  295. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/providers/bm25.py +0 -0
  296. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/providers/bm25s.py +0 -0
  297. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/providers/rank_bm25.py +0 -0
  298. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/providers/rapidfuzz.py +0 -0
  299. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/providers/wikipedia.py +0 -0
  300. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/retrievers/registry.py +0 -0
  301. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/types/__init__.py +0 -0
  302. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/types/audio.py +0 -0
  303. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/types/base.py +0 -0
  304. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/types/file.py +0 -0
  305. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/types/image.py +0 -0
  306. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/data/types/video.py +0 -0
  307. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/dsl/__init__.py +0 -0
  308. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/dsl/inline.py +0 -0
  309. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/dsl/typed_parsers/__init__.py +0 -0
  310. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/dsl/typed_parsers/base.py +0 -0
  311. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/dsl/typed_parsers/providers/__init__.py +0 -0
  312. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/dsl/typed_parsers/providers/xml.py +0 -0
  313. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/dsl/typed_parsers/registry.py +0 -0
  314. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/envs.py +0 -0
  315. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/exceptions.py +0 -0
  316. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/__init__.py +0 -0
  317. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/control_flow.py +0 -0
  318. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/reasoning/__init__.py +0 -0
  319. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/reasoning/cot.py +0 -0
  320. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/reasoning/react.py +0 -0
  321. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/reasoning/self_consistency.py +0 -0
  322. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/verifiers/__init__.py +0 -0
  323. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/verifiers/formatters.py +0 -0
  324. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/generation/verifiers/llm_as_a_verifier.py +0 -0
  325. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/logger.py +0 -0
  326. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/__init__.py +0 -0
  327. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/base.py +0 -0
  328. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/cache.py +0 -0
  329. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/httpx.py +0 -0
  330. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/model.py +0 -0
  331. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/profiles/__init__.py +0 -0
  332. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/profiles/base.py +0 -0
  333. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/profiles/loader.py +0 -0
  334. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/profiles/registry.py +0 -0
  335. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/__init__.py +0 -0
  336. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/cerebras.py +0 -0
  337. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/imagerouter.py +0 -0
  338. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/jinaai.py +0 -0
  339. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/replicate.py +0 -0
  340. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/sambanova.py +0 -0
  341. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/providers/together.py +0 -0
  342. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/registry.py +0 -0
  343. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/response.py +0 -0
  344. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/models/tool_call_agg.py +0 -0
  345. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/__init__.py +0 -0
  346. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/functional.py +0 -0
  347. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/hooks/__init__.py +0 -0
  348. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/__init__.py +0 -0
  349. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/container.py +0 -0
  350. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/embedder.py +0 -0
  351. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/generator.py +0 -0
  352. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/mediamaker.py +0 -0
  353. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/predictor.py +0 -0
  354. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/searcher.py +0 -0
  355. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/speaker.py +0 -0
  356. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/modules/transcriber.py +0 -0
  357. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/nn/parameter.py +0 -0
  358. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/__init__.py +0 -0
  359. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/__init__.py +0 -0
  360. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/auth/__init__.py +0 -0
  361. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/auth/apikey.py +0 -0
  362. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/auth/base.py +0 -0
  363. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/auth/basic.py +0 -0
  364. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/auth/bearer.py +0 -0
  365. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/auth/custom.py +0 -0
  366. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/auth/oauth2.py +0 -0
  367. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/client.py +0 -0
  368. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/exceptions.py +0 -0
  369. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/integration.py +0 -0
  370. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/loglevels.py +0 -0
  371. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/transports.py +0 -0
  372. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/protocols/mcp/types.py +0 -0
  373. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/py.typed +0 -0
  374. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/telemetry/__init__.py +0 -0
  375. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/telemetry/config.py +0 -0
  376. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/telemetry/span.py +0 -0
  377. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/tools/definitions.py +0 -0
  378. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/__init__.py +0 -0
  379. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/common.py +0 -0
  380. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/console.py +0 -0
  381. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/convert.py +0 -0
  382. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/encode.py +0 -0
  383. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/html.py +0 -0
  384. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/imports.py +0 -0
  385. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/inspect.py +0 -0
  386. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/logging.py +0 -0
  387. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/mermaid.py +0 -0
  388. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/pooling.py +0 -0
  389. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/templates.py +0 -0
  390. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/tenacity.py +0 -0
  391. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/torch.py +0 -0
  392. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/validation.py +0 -0
  393. {msgflux-0.3.0 → msgflux-0.5.0}/src/msgflux/utils/xml.py +0 -0
  394. {msgflux-0.3.0 → msgflux-0.5.0}/tests/__init__.py +0 -0
  395. {msgflux-0.3.0 → msgflux-0.5.0}/tests/auto/__init__.py +0 -0
  396. {msgflux-0.3.0 → msgflux-0.5.0}/tests/auto/test_params.py +0 -0
  397. {msgflux-0.3.0 → msgflux-0.5.0}/tests/conftest.py +0 -0
  398. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/__init__.py +0 -0
  399. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/parsers/__init__.py +0 -0
  400. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/parsers/test_parsers.py +0 -0
  401. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/retrievers/__init__.py +0 -0
  402. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/retrievers/providers/__init__.py +0 -0
  403. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/retrievers/providers/test_bm25.py +0 -0
  404. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/retrievers/providers/test_bm25s.py +0 -0
  405. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/retrievers/providers/test_rank_bm25.py +0 -0
  406. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/retrievers/providers/test_rapidfuzz.py +0 -0
  407. {msgflux-0.3.0 → msgflux-0.5.0}/tests/data/retrievers/providers/test_wikipedia.py +0 -0
  408. {msgflux-0.3.0 → msgflux-0.5.0}/tests/dsl/test_inline.py +0 -0
  409. {msgflux-0.3.0 → msgflux-0.5.0}/tests/dsl/test_signature.py +0 -0
  410. {msgflux-0.3.0 → msgflux-0.5.0}/tests/dsl/test_typed_parsers.py +0 -0
  411. {msgflux-0.3.0 → msgflux-0.5.0}/tests/generation/__init__.py +0 -0
  412. {msgflux-0.3.0 → msgflux-0.5.0}/tests/generation/test_control_flow.py +0 -0
  413. {msgflux-0.3.0 → msgflux-0.5.0}/tests/generation/test_reasoning.py +0 -0
  414. {msgflux-0.3.0 → msgflux-0.5.0}/tests/generation/test_templates.py +0 -0
  415. {msgflux-0.3.0 → msgflux-0.5.0}/tests/generation/test_verifiers.py +0 -0
  416. {msgflux-0.3.0 → msgflux-0.5.0}/tests/integration/test_agent_reasoning.py +0 -0
  417. {msgflux-0.3.0 → msgflux-0.5.0}/tests/integration/test_guard_moderation.py +0 -0
  418. {msgflux-0.3.0 → msgflux-0.5.0}/tests/integration/test_reasoning.py +0 -0
  419. {msgflux-0.3.0 → msgflux-0.5.0}/tests/integration/test_tool_dict_e2e.py +0 -0
  420. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/__init__.py +0 -0
  421. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/providers/__init__.py +0 -0
  422. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/providers/test_openrouter.py +0 -0
  423. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_base.py +0 -0
  424. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_cache.py +0 -0
  425. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_gateway.py +0 -0
  426. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_httpx.py +0 -0
  427. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_model.py +0 -0
  428. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_profiles.py +0 -0
  429. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_registry.py +0 -0
  430. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_response.py +0 -0
  431. {msgflux-0.3.0 → msgflux-0.5.0}/tests/models/test_tool_call_agg.py +0 -0
  432. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/__init__.py +0 -0
  433. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/__init__.py +0 -0
  434. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_container.py +0 -0
  435. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_embedder.py +0 -0
  436. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_lm.py +0 -0
  437. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_mediamaker.py +0 -0
  438. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_predictor.py +0 -0
  439. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_searcher.py +0 -0
  440. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_speaker.py +0 -0
  441. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/modules/test_transcriber.py +0 -0
  442. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/test_functional.py +0 -0
  443. {msgflux-0.3.0 → msgflux-0.5.0}/tests/nn/test_parameter.py +0 -0
  444. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/__init__.py +0 -0
  445. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/__init__.py +0 -0
  446. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/auth/test_auth_providers.py +0 -0
  447. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/conftest.py +0 -0
  448. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/mcp_simple_server.py +0 -0
  449. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/test_client.py +0 -0
  450. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/test_exceptions.py +0 -0
  451. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/test_integration.py +0 -0
  452. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/test_loglevels.py +0 -0
  453. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/test_mcp_live.py +0 -0
  454. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/test_toollibrary_mcp.py +0 -0
  455. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/test_transports.py +0 -0
  456. {msgflux-0.3.0 → msgflux-0.5.0}/tests/protocols/mcp/test_types.py +0 -0
  457. {msgflux-0.3.0 → msgflux-0.5.0}/tests/telemetry/__init__.py +0 -0
  458. {msgflux-0.3.0 → msgflux-0.5.0}/tests/telemetry/test_config.py +0 -0
  459. {msgflux-0.3.0 → msgflux-0.5.0}/tests/telemetry/test_span_agent_decorators.py +0 -0
  460. {msgflux-0.3.0 → msgflux-0.5.0}/tests/telemetry/test_span_tool_decorators.py +0 -0
  461. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_agent_as_tool_with_signature.py +0 -0
  462. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_agent_generation_schema.py +0 -0
  463. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_agent_image_detail.py +0 -0
  464. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_agent_include_date.py +0 -0
  465. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_agent_named_kwargs.py +0 -0
  466. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_agent_signature_annotations.py +0 -0
  467. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_agent_templates_fix.py +0 -0
  468. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_async_hooks.py +0 -0
  469. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_autoparams.py +0 -0
  470. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_data_types.py +0 -0
  471. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_dotdict.py +0 -0
  472. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_embedder.py +0 -0
  473. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_examples.py +0 -0
  474. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_image_block_kwargs_refactor.py +0 -0
  475. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_inject_message.py +0 -0
  476. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_mcp_fastmcp.py +0 -0
  477. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_registry.py +0 -0
  478. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_tool_config_decorator.py +0 -0
  479. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_tool_control.py +0 -0
  480. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_tools_visualization.py +0 -0
  481. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_type_inheritance_struct.py +0 -0
  482. {msgflux-0.3.0 → msgflux-0.5.0}/tests/test_video_block_kwargs.py +0 -0
  483. {msgflux-0.3.0 → msgflux-0.5.0}/tests/tools/__init__.py +0 -0
  484. {msgflux-0.3.0 → msgflux-0.5.0}/tests/tools/builtin/__init__.py +0 -0
  485. {msgflux-0.3.0 → msgflux-0.5.0}/tests/tools/test_toolflowcontrol.py +0 -0
  486. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_common.py +0 -0
  487. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_console.py +0 -0
  488. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_convert.py +0 -0
  489. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_encode.py +0 -0
  490. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_hint_to_schema_dict.py +0 -0
  491. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_hooks.py +0 -0
  492. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_imports.py +0 -0
  493. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_inspect.py +0 -0
  494. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_logging.py +0 -0
  495. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_mermaid.py +0 -0
  496. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_msgspec.py +0 -0
  497. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_pooling.py +0 -0
  498. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_templates.py +0 -0
  499. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_tenacity.py +0 -0
  500. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_torch.py +0 -0
  501. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_validation.py +0 -0
  502. {msgflux-0.3.0 → msgflux-0.5.0}/tests/utils/test_xml.py +0 -0
@@ -7,12 +7,12 @@ repos:
7
7
  - id: gitleaks
8
8
 
9
9
  - repo: https://github.com/astral-sh/uv-pre-commit
10
- rev: 0.11.7 # uv version.
10
+ rev: 0.11.16 # uv version.
11
11
  hooks:
12
12
  - id: uv-lock
13
13
 
14
14
  - repo: https://github.com/astral-sh/ruff-pre-commit
15
- rev: v0.15.11
15
+ rev: v0.15.14
16
16
  hooks:
17
17
  - id: ruff
18
18
  args: [--fix]
@@ -0,0 +1,66 @@
1
+ # Changelog
2
+
3
+ ## [0.5.0] - 2026-05-29
4
+
5
+ ### Feat
6
+ - Added opt-in input validation for signatures (#82).
7
+ - Added method hooks beyond `forward` (#87).
8
+ - Added `extra_body` passthrough extensions for OpenAI-compatible chat completions (#88).
9
+ - Added Open-Meteo weather retriever support and the builtin `Weather` tool (#97).
10
+ - Added tool display names and usage guidance metadata (#98).
11
+ - Added the Ceramic web retriever (#99).
12
+ - Added the SearXNG web retriever (#101).
13
+ - Added agent prompt warmup (#105).
14
+ - Added `msgspec.Struct` tool parameter support (#110).
15
+ - Added Agent Skills runtime support (#111).
16
+
17
+ ### Docs
18
+ - Corrected retriever section numbering in `docs/learn/nn/agent/tools.md` (#80).
19
+ - Added the Builtin Tools section to `tools.md` (#81).
20
+
21
+ ### Refactor
22
+ - Renamed the WebSearch steering parameter to `goal` (#100).
23
+ - Clarified tool display-name and usage-guidance examples and aligned `ToolLibrary.get_tool_display_names()` with a fallback to the registered tool name (#114).
24
+
25
+ ### CI / Maintenance
26
+ - Updated pre-commit hooks (#86).
27
+ - Bumped `packaging` from 25.0 to 26.2 (#92).
28
+ - Bumped `openai` from 2.32.0 to 2.38.0 (#106).
29
+ - Bumped `bm25s` from 0.3.4 to 0.3.9 (#107).
30
+ - Bumped `ruff` from 0.15.11 to 0.15.14 (#108).
31
+ - Bumped `pymdown-extensions` from 10.21.2 to 10.21.3 (#109).
32
+ - Bumped `pytest-asyncio` from 1.3.0 to 1.4.0 (#113).
33
+
34
+ ## [0.4.1] - 2026-04-22
35
+
36
+ - Fixes: restored uv.lock file for CI compatibility (#78).
37
+
38
+ ## [0.4.0] - 2026-04-22
39
+
40
+ - Features: added new web retrievers (Arxiv, Brave, Exa, LinkUp, SerpAPI, Tavily) and model integrations (Brave, Exa), plus configurable WebSearch tool (#71).
41
+ - Web Retriever: added support for Wikipedia highlighting in web retriever section (#73).
42
+ - Providers: added OpenAI-compatible `extra_body` support for chat completions (#72).
43
+ - Maintenance: removed uv.lock file (#74).
44
+
45
+ ## [0.3.0] - 2026-04-20
46
+
47
+ - Features: added OpenAI prompt cache retention support (#52), token logprobs metadata for chat completions (#53), and the `LLMAsVerifier` workflow with docs and examples (#54).
48
+ - Fixes: mapped OpenRouter `reasoning_max_tokens` to `extra_body.reasoning.max_tokens` and enforced the `reasoning_effort` conflict rule (#57).
49
+ - Docs: updated chat completion and agent reasoning docs to reflect the OpenRouter-only reasoning budget behavior (#56, #57).
50
+ - Maintenance: updated pre-commit hooks (#55).
51
+
52
+ ## [0.2.0] - 2026-04-17
53
+
54
+ - Features: added `provider/model-id` string shorthand support to `Agent`, `Speaker`, and `Transcriber` (#26, #27, #28), plus runtime tool controls for `Agent` (#30).
55
+ - Fixes: fixed registry naming for generic callables (#29).
56
+ - Maintenance: updated release automation and cleaned up the release script (#36, #49).
57
+
58
+ ## [0.1.1] - 2026-04-15
59
+
60
+ - Fixed message copying in the OpenAI provider (#47).
61
+ - Fixed isolation of injected messages for agent tools (#46).
62
+ - Updated CI and dependency tooling to keep release checks passing (#45, #44, #38, #37, #35, #34, #33, #32).
63
+
64
+ ## [0.1.0] - 2026-04-09
65
+
66
+ ## [0.1.0a31] - 2026-04-09
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: msgflux
3
- Version: 0.3.0
3
+ Version: 0.5.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
@@ -26,6 +26,7 @@ Requires-Python: >=3.10
26
26
  Requires-Dist: jinja2>=3.1.6
27
27
  Requires-Dist: msgspec-ext>=0.5.1
28
28
  Requires-Dist: msgtrace-sdk>=1.1.0
29
+ Requires-Dist: pyyaml>=6.0.3
29
30
  Requires-Dist: tenacity>=8.2.3
30
31
  Requires-Dist: typing-extensions>=4.14.1
31
32
  Requires-Dist: uvloop>=0.21.0; sys_platform != 'win32'
@@ -10,16 +10,17 @@ hide:
10
10
 
11
11
  ### Chat Completion
12
12
 
13
- | Provider | Dependency | Auth Env |
14
- |-------------|-------------------|----------------------|
15
- | Cerebras | `msgflux[openai]` | `CEREBRAS_API_KEY` |
16
- | Groq | `msgflux[openai]` | `GROQ_API_KEY` |
17
- | Ollama | `msgflux[openai]` | |
18
- | OpenAI | `msgflux[openai]` | `OPENAI_API_KEY` |
19
- | OpenRouter | `msgflux[openai]` | `OPENROUTER_API_KEY` |
20
- | SambaNova | `msgflux[openai]` | `SAMBANOVA_API_KEY` |
21
- | Together | `msgflux[openai]` | `TOGETHER_API_KEY` |
22
- | vLLM | `msgflux[openai]` | |
13
+ | Provider | Dependency | Auth Env |
14
+ |-------------|-------------------|------------------------|
15
+ | Brave | `msgflux[openai]` | `BRAVE_SEARCH_API_KEY` |
16
+ | Cerebras | `msgflux[openai]` | `CEREBRAS_API_KEY` |
17
+ | Groq | `msgflux[openai]` | `GROQ_API_KEY` |
18
+ | Ollama | `msgflux[openai]` | |
19
+ | OpenAI | `msgflux[openai]` | `OPENAI_API_KEY` |
20
+ | OpenRouter | `msgflux[openai]` | `OPENROUTER_API_KEY` |
21
+ | SambaNova | `msgflux[openai]` | `SAMBANOVA_API_KEY` |
22
+ | Together | `msgflux[openai]` | `TOGETHER_API_KEY` |
23
+ | vLLM | `msgflux[openai]` | |
23
24
 
24
25
  ### Image Embedder
25
26
 
@@ -144,6 +145,15 @@ hide:
144
145
 
145
146
  ### Web Search
146
147
 
147
- | Provider | Dependency |
148
- |-------------|---------------|
149
- | Wikipedia | `wikipedia` |
148
+ | Provider | Installation | Auth Env |
149
+ |-------------|----------------------------------|-----------------------------------|
150
+ | Trafilatura | `httpx`, `trafilatura` | |
151
+ | SearXNG | `httpx` | |
152
+ | SerpApi | `httpx` | `SERPAPI_KEY` |
153
+ | Ceramic | `httpx` | `CERAMIC_API_KEY` |
154
+ | Linkup | `linkup-sdk` | `LINKUP_API_KEY` |
155
+ | Tavily | `tavily-python` | `TAVILY_API_KEY` |
156
+ | Exa | `exa-py` | `EXA_API_KEY` |
157
+ | Brave | `brave-search-python-client` | `BRAVE_SEARCH_API_KEY` |
158
+ | arXiv | `arxiv` | |
159
+ | Wikipedia | `wikipedia` | |
@@ -34,6 +34,8 @@ hide:
34
34
 
35
35
  msgFlux is an open-source framework for building dynamic AI systems with **composable modules**. It treats prompts, signatures, tools, and message flow as explicit program structure instead of ad-hoc glue. Architecture, data flow, and prompting remain separate layers, so systems can evolve by changing contracts, modules, or routes without forcing everything to change together.
36
36
 
37
+ For web search, msgFlux includes both retriever-backed and model-backed options. The built-in `WebSearch` tool can be pointed at a retriever backend like `retriever/wikipedia` or a model backend like `model/openai/gpt-4o-search-preview`, returns `data` plus `annotations` when the backend supplies citations, and can read its engine plus JSON params from `MSGFLUX_TOOL_WEB_SEARCH_*` environment variables.
38
+
37
39
  ## **AI Systems *not* ML Systems**
38
40
 
39
41
  **ML systems** are systems *for* AI - they train, evaluate, and deploy models. **AI systems** are systems *with* AI - software where pretrained models operate as components inside a broader application. In that setting, the model is not the whole product; it is one building block among many. You are not optimizing weights - you are designing behavior, interfaces, and flow around a model. This is the space msgFlux occupies.
@@ -72,6 +72,7 @@ Chat completion models are stateless - they don't maintain conversation history
72
72
  verbose=False, # Print raw output before transformation
73
73
  # --- Search ---
74
74
  web_search_options={}, # Web search config (OpenAI / OpenRouter only)
75
+ extra_body={}, # Provider-specific OpenAI-compatible extensions
75
76
  prompt_cache_retention="24h", # OpenAI only: "in_memory" or "24h"
76
77
  # --- Infrastructure ---
77
78
  base_url="https://api.openai.com/v1", # Override provider API endpoint
@@ -82,6 +83,32 @@ Chat completion models are stateless - they don't maintain conversation history
82
83
  )
83
84
  ```
84
85
 
86
+ Use `extra_body` for provider-specific request body fields supported by
87
+ OpenAI-compatible APIs but not modeled directly by msgFlux. The dict is
88
+ forwarded to the underlying OpenAI SDK client.
89
+
90
+ You can also pass provider-specific fields directly as keyword arguments
91
+ in the model constructor, or per request with `model(...)` / `model.acall(...)`.
92
+ msgFlux merges these kwargs into `extra_body`.
93
+
94
+ ```python
95
+ import msgflux as mf
96
+
97
+ model = mf.Model.chat_completion(
98
+ "brave/brave",
99
+ extra_body={"enable_citations": True},
100
+ enable_entities=True, # merged into extra_body
101
+ enable_research=False, # merged into extra_body
102
+ )
103
+
104
+ # Per-request extensions are merged with constructor defaults.
105
+ response = model(
106
+ "Search the latest release notes.",
107
+ extra_body={"country": "US"},
108
+ enable_citations=True,
109
+ )
110
+ ```
111
+
85
112
  ## 2. **System Prompt**
86
113
 
87
114
  The `system_prompt` parameter sets the model's overarching behavior and role before any user messages. It is a convenience shorthand: when provided, msgFlux automatically inserts a `system` message at the beginning of the conversation, so you don't have to do it manually in the messages list.
@@ -217,6 +244,23 @@ The cache is sensitive to:
217
244
 
218
245
  Changing any of these creates a new cache entry.
219
246
 
247
+ ### 3.2 **Prompt Cache Warmup**
248
+
249
+ Some providers cache long prompt prefixes server-side. For agent-level warmup, use `Agent.warmup_system_prompt()`. It sends the rendered system prompt and tool schemas without task messages, chat history, or checkpointer state.
250
+
251
+ See [Agent — Prompt Cache Warmup](../nn/agent/prompt-cache.md) for the recommended usage.
252
+
253
+ OpenAI-compatible chat providers use `warmup_max_tokens=1` by default:
254
+
255
+ ```python
256
+ model = mf.Model.chat_completion(
257
+ "openai/gpt-4.1-mini",
258
+ warmup_max_tokens=1,
259
+ )
260
+ ```
261
+
262
+ This is separate from `enable_cache`: response caching is local/in-process, while prompt cache warmup targets the provider's prompt cache.
263
+
220
264
  ## 4. **Message Formats**
221
265
 
222
266
  ???+ example
@@ -736,6 +780,8 @@ Force the model to start its response with specific text. msgFlux appends the va
736
780
 
737
781
  The `web_search_options` parameter enables real-time web search, letting the model ground its answers in up-to-date information retrieved from the internet. It is currently supported by OpenAI search models (`gpt-4o-search-preview`, `gpt-4o-mini-search-preview`) and OpenRouter.
738
782
 
783
+ OpenAI-compatible search providers can also expose chat completion models that search the web before answering. Brave uses `BRAVE_SEARCH_API_KEY` with the `brave/brave` model id, and Exa uses `EXA_API_KEY` with the `exa/exa` model id.
784
+
739
785
  !!! info "Dependencies"
740
786
  Install the OpenAI extra if you haven't already:
741
787
 
@@ -794,6 +840,92 @@ The `web_search_options` parameter enables real-time web search, letting the mod
794
840
  print(response.consume())
795
841
  ```
796
842
 
843
+ === "Brave Search"
844
+
845
+ Brave Answers uses an OpenAI-compatible endpoint. Set
846
+ `BRAVE_SEARCH_API_KEY` and use the `brave/brave` model id:
847
+
848
+ ```python
849
+ import msgflux as mf
850
+
851
+ mf.set_envs(BRAVE_SEARCH_API_KEY="...")
852
+
853
+ model = mf.Model.chat_completion("brave/brave")
854
+ response = model("What are the latest Python packaging updates?")
855
+
856
+ print(response.consume())
857
+ ```
858
+
859
+ Brave-specific request fields are passed through `extra_body`:
860
+
861
+ ```python
862
+ import msgflux as mf
863
+
864
+ mf.set_envs(BRAVE_SEARCH_API_KEY="...")
865
+
866
+ model = mf.Model.chat_completion(
867
+ "brave/brave",
868
+ extra_body={
869
+ "country": "BR", # target country for search results
870
+ "language": "pt", # answer language
871
+ },
872
+ )
873
+
874
+ response = model("Quais foram as principais novidades do Python este mês?")
875
+ print(response.consume())
876
+ ```
877
+
878
+ Brave's richer answer fields require streaming mode:
879
+
880
+ ```python
881
+ import msgflux as mf
882
+
883
+ mf.set_envs(BRAVE_SEARCH_API_KEY="...")
884
+
885
+ model = mf.Model.chat_completion(
886
+ "brave/brave",
887
+ extra_body={
888
+ "country": "US",
889
+ "language": "en",
890
+ "enable_citations": True,
891
+ "enable_entities": True,
892
+ "enable_research": False,
893
+ },
894
+ )
895
+
896
+ response = model("Summarize the latest Python packaging updates.", stream=True)
897
+
898
+ async for chunk in response.consume():
899
+ print(chunk, end="", flush=True)
900
+ ```
901
+
902
+ Supported Brave Answers parameters include:
903
+
904
+ | Parameter | Description | Default |
905
+ |---|---|---|
906
+ | `country` | Target country for search results | `"us"` |
907
+ | `language` | Response language | `"en"` |
908
+ | `enable_citations` | Include inline citation tags in streamed responses | `False` |
909
+ | `enable_entities` | Include entity tags in streamed responses | `False` |
910
+ | `enable_research` | Enable multi-search research mode for more thorough answers | `False` |
911
+
912
+ `enable_citations`, `enable_entities`, and `enable_research` require
913
+ `stream=True`. Research mode can be slower and more expensive because
914
+ Brave may run multiple searches before answering.
915
+
916
+ === "Exa Answer"
917
+
918
+ ```python
919
+ import msgflux as mf
920
+
921
+ mf.set_envs(EXA_API_KEY="...")
922
+
923
+ model = mf.Model.chat_completion("exa/exa")
924
+ response = model("What are the latest changes in Python packaging?")
925
+
926
+ print(response.consume())
927
+ ```
928
+
797
929
  ### 11.1 **search_context_size**
798
930
 
799
931
  Controls how much web content is retrieved and included in the model's context window:
@@ -1,19 +1,21 @@
1
1
  # Hooks & Guards
2
2
 
3
- Hooks are the primary mechanism for intercepting and validating data flowing through Modules. The `Hook` base class provides the interface, and `Guard` is a built-in hook for input/output validation.
3
+ Hooks are the primary mechanism for intercepting and validating data flowing through Modules. The `Hook` base class provides the interface, and `Guard` is a built-in hook for input/output validation. Hooks can target either the module execution boundary (`forward`) or a specific method on the module.
4
4
 
5
5
  ## Guard
6
6
 
7
7
  A `Guard` validates inputs and/or outputs of a Module. Each Guard wraps a **validator** callable and defines:
8
8
 
9
- - **`on`** — when to run: `"pre"` (before forward) or `"post"` (after forward).
9
+ - **`on`** — when to run: `"pre"` (before execution) or `"post"` (after execution).
10
10
  - **`message`** — controls the reaction when `safe=False`:
11
11
  - **With `message`** — short-circuits the pipeline and returns the message as the response (the model is never called).
12
12
  - **Without `message`** (default) — raises `UnsafeUserInputError` (pre) or `UnsafeModelResponseError` (post).
13
- - **`target`** — submodule to register on. Defaults to `"generator"`.
13
+ - **`target`** — submodule to register on. Defaults to `"generator"` for forward hooks and `None` for method hooks.
14
+ - **`method`** — optional method name. When omitted, the guard runs around `forward`. When set, it runs around that method instead.
14
15
  - **`include_data`** — if `True`, attaches the data that triggered the guard to the raised exception via `exc.data`. Defaults to `False` for security (the data may contain unsafe content).
15
16
 
16
17
  The validator receives `data` as a positional argument and must return either a dict with `"safe"` (bool) or a `ModelResponse` (auto-consumed by Guard).
18
+ For `Guard(..., on="pre", method=...)`, `data` is the method `kwargs` payload. If a method is intended to be guarded in pre-mode, prefer a keyword-oriented signature.
17
19
 
18
20
  ```python
19
21
  from msgflux.nn.hooks import Guard
@@ -27,8 +29,26 @@ guard = Guard(validator=my_validator, on="pre", message="Not allowed.")
27
29
 
28
30
  # Raises exception when safe=False
29
31
  guard = Guard(validator=my_validator, on="pre")
32
+
33
+ # Guard a specific method on the module itself
34
+ guard = Guard(validator=my_validator, on="post", method="_prepare_response")
30
35
  ```
31
36
 
37
+ !!! note "Method Guard Input Shape"
38
+ `Guard` on a specific method is best suited for keyword-oriented extension points.
39
+ In `on="pre"` mode, the validator sees the method `kwargs`, not positional args.
40
+
41
+ ```python
42
+ class MyModule(nn.Module):
43
+ def forward(self, text):
44
+ return self.validate(data=text)
45
+
46
+ def validate(self, *, data):
47
+ return data
48
+
49
+ guard = Guard(validator=my_validator, on="pre", method="validate")
50
+ ```
51
+
32
52
  ???+ note "Guard Examples"
33
53
 
34
54
  === "With message (short-circuit)"
@@ -200,23 +220,24 @@ The `Hook` base class allows creating custom hooks beyond guards. Implement `__c
200
220
 
201
221
  | Attribute | Description |
202
222
  |---|---|
203
- | `on` | `"pre"` (before forward) or `"post"` (after forward) |
223
+ | `on` | `"pre"` (before execution) or `"post"` (after execution) |
204
224
  | `target` | Submodule name to register on. `None` = the module itself |
225
+ | `method` | Method name to register on. `None` = the module execution boundary (`forward`) |
205
226
  | `processor_key` | Key for processor matching in `_set_hooks`. `None` = no processor |
206
- | `__call__` | Sync hook — called by `_call_impl` |
207
- | `acall` | Async hook — called by `_acall_impl` |
227
+ | `__call__` | Sync hook — called by the sync hook dispatcher |
228
+ | `acall` | Async hook — called by the async hook dispatcher |
208
229
 
209
230
  ### Hook Signatures
210
231
 
211
232
  ```python
212
- # Pre hook — receives module, args and kwargs before forward
233
+ # Pre hook — receives module, args and kwargs before execution
213
234
  def __call__(self, module, args, kwargs, output=None): ...
214
235
 
215
- # Post hook — receives module, args, kwargs and the forward output
236
+ # Post hook — receives module, args, kwargs and the output
216
237
  def __call__(self, module, args, kwargs, output=None): ...
217
238
  ```
218
239
 
219
- Both pre and post hooks share the same signature. For pre hooks, `output` is always `None`.
240
+ Both pre and post hooks share the same signature. For pre hooks, `output` is always `None`. The same signature is used for forward hooks and method hooks.
220
241
 
221
242
  ???+ note "Custom Hook Examples"
222
243
 
@@ -253,6 +274,22 @@ Both pre and post hooks share the same signature. For pre hooks, `output` is alw
253
274
  print(f"Generator took {elapsed:.2f}s")
254
275
  ```
255
276
 
277
+ === "Hooking an Internal Method"
278
+
279
+ ```python
280
+ from msgflux.nn.hooks import Hook
281
+
282
+ class PrepareResponseHook(Hook):
283
+ """Intercept Agent._prepare_response."""
284
+
285
+ def __init__(self):
286
+ super().__init__(on="post", method="_prepare_response")
287
+
288
+ def __call__(self, module, args, kwargs, output=None):
289
+ print("response_type:", kwargs["response_type"])
290
+ return output
291
+ ```
292
+
256
293
  === "Token Counter Hook"
257
294
 
258
295
  ```python
@@ -293,10 +330,11 @@ Both pre and post hooks share the same signature. For pre hooks, `output` is alw
293
330
 
294
331
  ### Hook Registration
295
332
 
296
- All `nn.Module` subclasses support the `hooks` class attribute. Each hook declares its own `target` — the submodule name where it registers:
333
+ All `nn.Module` subclasses support the `hooks` class attribute. Each hook declares where it registers:
297
334
 
298
335
  - `target="generator"` (default for Guard) — registers on the internal `Generator` wrapper
299
336
  - `target=None` — registers on the module itself
337
+ - `method="_prepare_response"` — registers on that specific method instead of `forward`
300
338
 
301
339
  ```python
302
340
  import msgflux.nn as nn
@@ -328,9 +366,27 @@ handle = guard.register(agent.generator) # returns RemovableHandle
328
366
  handle.remove() # unregister when done
329
367
  ```
330
368
 
369
+ You can also register declarative hooks for a specific method via `hooks=`:
370
+
371
+ ```python
372
+ from msgflux.nn.hooks import Hook
373
+
374
+ class PrepareResponseHook(Hook):
375
+ def __init__(self):
376
+ super().__init__(on="post", method="_prepare_response")
377
+
378
+ def __call__(self, module, args, kwargs, output=None):
379
+ print("prepared response")
380
+ return output
381
+
382
+ class Bot(nn.Agent):
383
+ model = model
384
+ hooks = [PrepareResponseHook()]
385
+ ```
386
+
331
387
  ### Using Hooks with `nn.Module` Directly
332
388
 
333
- The hook system is built into `nn.Module`. You can register hooks on any module via PyTorch-style methods:
389
+ The hook system is built into `nn.Module`. You can register hooks on any module via PyTorch-style methods for `forward`, or via method hooks for other methods:
334
390
 
335
391
  ```python
336
392
  import msgflux.nn as nn
@@ -353,5 +409,39 @@ def my_post_hook(module, args, kwargs, output):
353
409
  handle = module.register_forward_hook(my_post_hook)
354
410
  ```
355
411
 
412
+ ### Registering Hooks on Arbitrary Methods
413
+
414
+ Use `register_method_pre_hook()` and `register_method_hook()` when the extension point is an internal method rather than `forward`:
415
+
416
+ ```python
417
+ import msgflux.nn as nn
418
+
419
+ class MyModule(nn.Module):
420
+ def __init__(self):
421
+ super().__init__()
422
+
423
+ def forward(self, text):
424
+ return self._normalize(text)
425
+
426
+ def _normalize(self, text):
427
+ return text.strip().lower()
428
+
429
+ module = MyModule()
430
+
431
+ def normalize_pre_hook(module, args, kwargs):
432
+ return (args[0] + " ",), kwargs
433
+
434
+ def normalize_post_hook(module, args, kwargs, output):
435
+ return f"[{output}]"
436
+
437
+ pre_handle = module.register_method_pre_hook("_normalize", normalize_pre_hook)
438
+ post_handle = module.register_method_hook("_normalize", normalize_post_hook)
439
+
440
+ result = module(" Hello ")
441
+ print(result) # "[hello]"
442
+ ```
443
+
444
+ This is useful for methods such as `Agent._prepare_response`, `Agent._prepare_inputs`, or other internal extension points that do not warrant being promoted to standalone `Module` instances.
445
+
356
446
  !!! warning "Streaming Limitation"
357
447
  Guards with `on="post"` are **not compatible** with `stream=True`, since the full response is needed for validation. Using both raises a `ValueError` at initialization.
@@ -25,6 +25,7 @@ An `Agent` combines a language model with instructions and tools to accomplish t
25
25
  | [Quick Start](quickstart.md) | Get started with a minimal agent, class-based definition (AutoParams) |
26
26
  | [Async](async.md) | Asynchronous agent execution |
27
27
  | [Streaming](streaming.md) | Real-time response streaming |
28
+ | [Prompt Cache Warmup](prompt-cache.md) | Warm provider prompt caches with the system prompt and tool schemas |
28
29
  | [Reasoning](reasoning.md) | Model-level reasoning, `reasoning_in_response`, dual-queue streaming |
29
30
  | [How to Debug an Agent](debug.md) | Inspection and debugging tools |
30
31
  | [System Prompt Components](system-prompt.md) | Compose system prompts from components |
@@ -32,6 +33,7 @@ An `Agent` combines a language model with instructions and tools to accomplish t
32
33
  | [Task and Context](task-and-context.md) | Input handling, templates, multimodal, chat history |
33
34
  | [Vars](vars.md) | Unified execution variable space |
34
35
  | [Tools](tools.md) | Tool calling, configuration, MCP, agent-as-tool |
36
+ | [Agent Skills](skills.md) | Reusable `SKILL.md` workflows loaded through progressive disclosure |
35
37
  | [Signatures](signatures.md) | Declarative input/output specifications |
36
38
  | [Hooks & Guards](hooks.md) | Input and output safety checks with configurable policy |
37
39
  | [Model Gateway](model-gateway.md) | Multi-model routing |
@@ -0,0 +1,159 @@
1
+ # Prompt Cache Warmup
2
+
3
+ Prompt warmup sends the agent's stable prompt prefix to the model provider before the first real task. Providers with prompt caching can prefill the system prompt and tool schemas, so the next request with the same prefix can start faster or report cached input tokens.
4
+
5
+ Use warmup when your agent has a large static system prompt, many tools, or loaded skills. It is not a replacement for response caching: no task message is sent, no checkpoint is written, and no conversation history is updated.
6
+
7
+ ## Basic Usage
8
+
9
+ ```python
10
+ # pip install msgflux[openai]
11
+ import msgflux as mf
12
+ import msgflux.nn as nn
13
+
14
+
15
+ def lookup_ticket(ticket_id: str) -> str:
16
+ return f"{ticket_id}: open"
17
+
18
+
19
+ class SupportAgent(nn.Agent):
20
+ model = mf.Model.chat_completion("openai/gpt-4.1-mini")
21
+ system_message = """
22
+ You are a support agent.
23
+ Follow the escalation policy and use tools when needed.
24
+ """
25
+ tools = [lookup_ticket]
26
+
27
+
28
+ agent = SupportAgent()
29
+
30
+ # Sends only the rendered system prompt and tool schemas.
31
+ agent.warmup_system_prompt()
32
+
33
+ response = agent("Check ticket MSGFLUX-42")
34
+ print(response)
35
+ ```
36
+
37
+ ## Async Usage
38
+
39
+ ```python
40
+ agent = SupportAgent()
41
+
42
+ await agent.awarmup_system_prompt()
43
+ response = await agent.acall("Check ticket MSGFLUX-42")
44
+ ```
45
+
46
+ ## Fire And Forget
47
+
48
+ Warmup can run in the background while the process continues initializing:
49
+
50
+ ```python
51
+ agent = SupportAgent()
52
+
53
+ agent.warmup_system_prompt(background=True)
54
+
55
+ # Continue booting your CLI, server, or worker.
56
+ ```
57
+
58
+ For async applications:
59
+
60
+ ```python
61
+ await agent.awarmup_system_prompt(background=True)
62
+ ```
63
+
64
+ Background warmup does not return the provider response. Errors are logged by the background task runner.
65
+
66
+ ## What Is Sent
67
+
68
+ Warmup intentionally bypasses runtime state. It sends:
69
+
70
+ - The rendered `system_prompt`
71
+ - Tool schemas from the agent's `ToolLibrary`
72
+ - The provider's configured warmup token limit
73
+
74
+ It does not send:
75
+
76
+ - User task messages
77
+ - Chat history
78
+ - Checkpointer state
79
+ - Agent inbox notifications
80
+ - Typed parsers or generation schemas
81
+ - Response templates
82
+
83
+ This keeps warmup focused on the stable prefix that providers can cache.
84
+
85
+ ## Runtime Vars
86
+
87
+ If the system prompt uses runtime variables, pass the same `vars` you expect to use for the real request:
88
+
89
+ ```python
90
+ agent.warmup_system_prompt(vars={"tenant": "acme"})
91
+
92
+ response = agent(
93
+ "Summarize the ticket",
94
+ vars={"tenant": "acme"},
95
+ )
96
+ ```
97
+
98
+ Cache hits depend on the provider seeing the same prompt prefix. If the rendered system prompt changes between warmup and the real call, the provider may miss the cache.
99
+
100
+ ## Tool Filtering
101
+
102
+ Warmup accepts the same `tool_filter` shape used by agent execution:
103
+
104
+ ```python
105
+ agent.warmup_system_prompt(tool_filter={"allow": ["lookup_ticket"]})
106
+ ```
107
+
108
+ Use this when the real request will also restrict tools. A different tool schema list changes the prompt prefix and can reduce cache hits.
109
+
110
+ ## Model Gateway
111
+
112
+ When the agent uses a `ModelGateway`, warmup routes through the gateway and accepts `model_preference`:
113
+
114
+ ```python
115
+ agent.warmup_system_prompt(model_preference="fast")
116
+ ```
117
+
118
+ The selected model must support `warmup_system_prompt`.
119
+
120
+ ## Provider Token Limit
121
+
122
+ OpenAI-compatible chat providers default to one generated token for warmup. This keeps the request cheap while still forcing the provider to process the prompt.
123
+
124
+ Override it on the model if a provider needs a different minimum:
125
+
126
+ ```python
127
+ model = mf.Model.chat_completion(
128
+ "openai/gpt-4.1-mini",
129
+ warmup_max_tokens=1,
130
+ )
131
+ ```
132
+
133
+ OpenAI Chat Completions and Groq reject zero completion tokens, so `0` is not a portable warmup value.
134
+
135
+ ## Reading Cache Usage
136
+
137
+ The provider response is returned in foreground mode:
138
+
139
+ ```python
140
+ raw_response = agent.warmup_system_prompt()
141
+ print(raw_response.usage)
142
+ ```
143
+
144
+ OpenAI reports prompt cache hits in usage metadata:
145
+
146
+ - Chat Completions: `usage.prompt_tokens_details.cached_tokens`
147
+ - Responses API: `usage.input_tokens_details.cached_tokens`
148
+
149
+ msgflux currently implements this warmup path for chat completions.
150
+
151
+ ## Practical Guidance
152
+
153
+ - Keep the warmup prefix stable.
154
+ - Put large static instructions, tools, and skills before dynamic user content.
155
+ - Warmup is most useful above the provider's prompt-cache threshold.
156
+ - Do not expect warmup to persist conversation state.
157
+ - Use foreground warmup during tests so failures are visible.
158
+ - Use background warmup during app startup when failures should not block serving.
159
+