msgflux 0.2.0__tar.gz → 0.3.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.
- {msgflux-0.2.0 → msgflux-0.3.0}/.pre-commit-config.yaml +2 -2
- {msgflux-0.2.0 → msgflux-0.3.0}/CHANGELOG.md +7 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/PKG-INFO +1 -1
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/index.md +2 -0
- msgflux-0.3.0/docs/anatomy/llm-as-a-verifier.md +317 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/chat_completion.md +85 -18
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/reasoning.md +5 -6
- msgflux-0.3.0/docs/learn/verifiers.md +583 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/mkdocs.yml +14 -0
- msgflux-0.3.0/src/msgflux/generation/verifiers/__init__.py +62 -0
- msgflux-0.3.0/src/msgflux/generation/verifiers/formatters.py +149 -0
- msgflux-0.3.0/src/msgflux/generation/verifiers/llm_as_a_verifier.py +1633 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/openai.py +154 -35
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/openrouter.py +8 -0
- msgflux-0.3.0/src/msgflux/version.py +1 -0
- msgflux-0.3.0/tests/generation/test_verifiers.py +842 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/providers/test_openai.py +158 -0
- msgflux-0.3.0/tests/models/providers/test_openrouter.py +96 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/providers/test_vllm.py +30 -0
- msgflux-0.2.0/src/msgflux/version.py +0 -1
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/CODEOWNERS +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/SECURITY.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/dependabot.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/labeler.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/pull_request_template.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/release-drafter.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/workflows/ci.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/workflows/docs.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/workflows/labeler.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/workflows/merge-bot.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/workflows/pre-commit-autoupdate.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/workflows/publish.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/workflows/release-drafter.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.github/workflows/validate-release.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.gitignore +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.python-version +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/.readthedocs.yaml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/CONTRIBUTING.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/LICENSE +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/README.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/CHANGELOG.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/CNAME +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/_includes/init_chat_completion_model.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/_includes/install.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/_includes/install_openai.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/agent.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/chat-schema-utils.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/dict-lowering-and-restoration.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/logical-vs-provider-schema.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/msgspec-transport-lowering.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/openai-chat-completion.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/react-provider-schemas.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/signatures.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/tool-flow-control.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/anatomy/tool-library.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/databases/database.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/databases/types/kv.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/databases/types/vector.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/model.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/model_gateway.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/chat_completion.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/image_classifier.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/image_embedder.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/image_text_to_image.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/moderation.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/speech_to_text.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/text_classifier.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/text_embedder.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/text_reranker.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/text_to_image.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/models/types/text_to_speech.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/functional.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/agent.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/module.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/module_dict.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/module_list.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/predictor.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/searcher.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/sequential.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/speaker.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/tool.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference/nn/modules/transcriber.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/api-reference.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/assets/logo-msgflux-horizon.png +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/assets/logo.png +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/assets/msgflux-wordmark.png +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/assets/msgflux.png +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/assets/tmd-mascot.png +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/blog/.authors.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/blog/index.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/blog/posts/.meta.yml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/blog/posts/26-04/why-msgflux-exists.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/changelog.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/dependency-management.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/hooks/copy_markdown.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/index.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/dotdict.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/inline.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/image_text_to_image.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/model.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/model_gateway.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/moderation.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/speech_to_text.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/text_classifier.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/text_embedder.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/text_reranker.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/text_to_image.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/models/text_to_speech.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/async.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/debug.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/generation-schemas.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/hooks.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/index.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/model-gateway.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/prefilling.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/quickstart.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/signatures.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/streaming.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/system-prompt.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/task-and-context.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/tools.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/agent/vars.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/functional.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/mediamaker.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/message.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/module/composing.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/module/core-concepts.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/module/forward-and-async.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/module/index.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/module/module-dict.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/module/module-list.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/module/sequential.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/module/visualization.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/predictor.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/searcher.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/speaker.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/nn/transcriber.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/parsers.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/retrievers/fuzzy.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/retrievers/lexical.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/retrievers/retriever.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/retrievers/web.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/learn/telemetry.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/stylesheets/extra.css +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/ad-focus-group.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/advisor-specialist-tool.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/call-transcript-analysis.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/deal-briefing-generator.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/email-auto-responder.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/food-delivery-assistant.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/index.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/intent-router.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/lead-scoring.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/meeting-action-items.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/meeting-assistant.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/pix-assistant.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/plan-tool-with-root-context.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/product-poster.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/restaurant-supply-assistant.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/signature-router.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/streaming-support-triage.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/support-ticket-router.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/visit-report.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/workplace-incident-reporter.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/docs/tutorials/youtube-cut-detector.md +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/ad_focus_group.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/advisor_specialist_tool.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/call_transcript_analysis.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/deal_briefing_generator.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/food_delivery_assistant.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/intent-router.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/lead_scoring.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/meeting_action_items.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/meeting_assistant.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/pix_assistant.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/plan_tool_with_root_history.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/restaurant-supply-assistant.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/streaming_support_triage.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/visit_report.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/examples/youtube_cut_detector.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/pyproject.toml +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/scripts/release.sh +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/scripts/setup-branch-protection.sh +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/scripts/setup-labels.sh +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/scripts/svg_render.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/_private/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/_private/client.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/_private/core.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/_private/executor.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/_private/response.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/auto/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/auto/params.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/cache.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/core/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/core/dotdict.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/core/examples.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/core/message.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/core/registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/audio.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/db.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/providers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/providers/cachetools.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/providers/diskcache.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/providers/faiss.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/response.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/dbs/types.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/parser.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/providers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/providers/csv_parser.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/providers/email_parser.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/providers/html_parser.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/providers/openpyxl.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/providers/pypdf.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/providers/python_docx.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/providers/python_pptx.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/response.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/parsers/types.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/providers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/providers/bm25.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/providers/bm25s.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/providers/rank_bm25.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/providers/rapidfuzz.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/providers/wikipedia.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/retriever.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/retrievers/types.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/types/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/types/audio.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/types/base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/types/file.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/types/image.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/data/types/video.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/dsl/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/dsl/inline.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/dsl/signature.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/dsl/typed_parsers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/dsl/typed_parsers/base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/dsl/typed_parsers/providers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/dsl/typed_parsers/providers/xml.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/dsl/typed_parsers/registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/envs.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/exceptions.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/generation/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/generation/control_flow.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/generation/reasoning/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/generation/reasoning/cot.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/generation/reasoning/react.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/generation/reasoning/self_consistency.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/generation/templates.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/logger.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/cache.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/gateway.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/httpx.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/model.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/profiles/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/profiles/base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/profiles/loader.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/profiles/registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/cerebras.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/groq.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/imagerouter.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/jinaai.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/ollama.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/replicate.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/sambanova.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/together.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/providers/vllm.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/response.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/tool_call_agg.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/models/types.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/functional.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/hooks/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/hooks/guard.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/hooks/hook.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/agent.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/container.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/embedder.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/generator.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/mediamaker.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/module.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/predictor.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/searcher.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/speaker.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/tool.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/modules/transcriber.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/nn/parameter.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/auth/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/auth/apikey.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/auth/base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/auth/basic.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/auth/bearer.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/auth/custom.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/auth/oauth2.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/client.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/exceptions.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/integration.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/loglevels.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/transports.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/protocols/mcp/types.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/py.typed +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/telemetry/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/telemetry/config.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/telemetry/span.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/tools/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/tools/builtin/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/tools/builtin/web_fetch.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/tools/config.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/tools/definitions.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/chat.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/common.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/console.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/convert.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/encode.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/html.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/imports.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/inspect.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/logging.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/mermaid.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/msgspec.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/pooling.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/templates.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/tenacity.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/torch.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/validation.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/src/msgflux/utils/xml.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/auto/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/auto/test_params.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/conftest.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/parsers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/parsers/test_parsers.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/retrievers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/retrievers/providers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/retrievers/providers/test_bm25.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/retrievers/providers/test_bm25s.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/retrievers/providers/test_rank_bm25.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/retrievers/providers/test_rapidfuzz.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/data/retrievers/providers/test_wikipedia.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/dsl/test_inline.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/dsl/test_signature.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/dsl/test_typed_parsers.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/generation/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/generation/test_control_flow.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/generation/test_reasoning.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/generation/test_templates.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/integration/test_agent_reasoning.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/integration/test_guard_moderation.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/integration/test_reasoning.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/integration/test_tool_dict_e2e.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/providers/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_base.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_cache.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_gateway.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_httpx.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_model.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_profiles.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_response.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/models/test_tool_call_agg.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_agent.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_container.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_embedder.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_lm.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_mediamaker.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_module.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_predictor.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_searcher.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_speaker.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_tool.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_tool_transport_params.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/modules/test_transcriber.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/test_functional.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/test_guard.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/nn/test_parameter.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/auth/test_auth_providers.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/conftest.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/mcp_simple_server.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/test_client.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/test_exceptions.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/test_integration.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/test_loglevels.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/test_mcp_live.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/test_toollibrary_mcp.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/test_transports.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/protocols/mcp/test_types.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/telemetry/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/telemetry/test_config.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/telemetry/test_span_agent_decorators.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/telemetry/test_span_tool_decorators.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_agent_as_tool_with_signature.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_agent_generation_schema.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_agent_image_detail.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_agent_include_date.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_agent_named_kwargs.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_agent_signature_annotations.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_agent_templates_fix.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_async_hooks.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_autoparams.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_data_types.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_dotdict.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_embedder.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_examples.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_image_block_kwargs_refactor.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_inject_message.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_mcp_fastmcp.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_registry.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_tool_config_decorator.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_tool_control.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_tools_visualization.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_type_inheritance_struct.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/test_video_block_kwargs.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/tools/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/tools/builtin/__init__.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/tools/builtin/test_web_fetch.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/tools/test_config.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/tools/test_toolflowcontrol.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_chat.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_common.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_console.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_convert.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_encode.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_hint_to_schema_dict.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_hooks.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_imports.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_inspect.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_logging.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_mermaid.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_msgspec.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_pooling.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_templates.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_tenacity.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_torch.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_validation.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/tests/utils/test_xml.py +0 -0
- {msgflux-0.2.0 → msgflux-0.3.0}/uv.lock +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.
|
|
10
|
+
rev: 0.11.7 # 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.
|
|
15
|
+
rev: v0.15.11
|
|
16
16
|
hooks:
|
|
17
17
|
- id: ruff
|
|
18
18
|
args: [--fix]
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2026-04-20
|
|
4
|
+
|
|
5
|
+
- Features: added OpenAI prompt cache retention support (#52), token logprobs metadata for chat completions (#53), and the `LLMAsVerifier` workflow with docs and examples (#54).
|
|
6
|
+
- Fixes: mapped OpenRouter `reasoning_max_tokens` to `extra_body.reasoning.max_tokens` and enforced the `reasoning_effort` conflict rule (#57).
|
|
7
|
+
- Docs: updated chat completion and agent reasoning docs to reflect the OpenRouter-only reasoning budget behavior (#56, #57).
|
|
8
|
+
- Maintenance: updated pre-commit hooks (#55).
|
|
9
|
+
|
|
3
10
|
## [0.2.0] - 2026-04-17
|
|
4
11
|
|
|
5
12
|
- Features: added `provider/model-id` string shorthand support to `Agent`, `Speaker`, and `Transcriber` (#26, #27, #28), plus runtime tool controls for `Agent` (#30).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: msgflux
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.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
|
|
@@ -41,3 +41,5 @@ Use this section when you need to answer questions like:
|
|
|
41
41
|
`dict[K, V]` is encoded for strict structured outputs and restored at runtime.
|
|
42
42
|
- [ReAct Provider Schemas](react-provider-schemas.md): how ReAct uses tool
|
|
43
43
|
schemas to build a dynamic provider-facing response format.
|
|
44
|
+
- [LLM-as-a-Verifier](llm-as-a-verifier.md): how verifier prompts, concurrent
|
|
45
|
+
execution, score-token parsing, and weighted aggregation fit together.
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# LLM-as-a-Verifier
|
|
2
|
+
|
|
3
|
+
`src/msgflux/generation/verifiers/llm_as_a_verifier.py` is the first verifier
|
|
4
|
+
module in msgFlux.
|
|
5
|
+
|
|
6
|
+
At a high level, it turns a verification task into a reusable runtime with four
|
|
7
|
+
main jobs:
|
|
8
|
+
|
|
9
|
+
- build a verifier prompt from task, criteria, candidates, and context
|
|
10
|
+
- request discrete score tokens from the model
|
|
11
|
+
- estimate a stable score from `logprobs` instead of trusting only the chosen
|
|
12
|
+
token
|
|
13
|
+
- aggregate repeated attempts and multiple criteria into a final verdict
|
|
14
|
+
|
|
15
|
+
It is not tied to `Agent`. It is a callable verification layer that can be used
|
|
16
|
+
from plain generation code, tool workflows, candidate reranking, or future
|
|
17
|
+
optimizers.
|
|
18
|
+
|
|
19
|
+
## Mental Model
|
|
20
|
+
|
|
21
|
+
The verifier pipeline looks like this:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
task + candidates + criteria
|
|
25
|
+
-> prompt builder
|
|
26
|
+
-> request batch
|
|
27
|
+
-> concurrent model calls
|
|
28
|
+
-> per-attempt evidence extraction
|
|
29
|
+
-> text token
|
|
30
|
+
-> logprob distribution
|
|
31
|
+
-> criterion aggregation
|
|
32
|
+
-> final verifier result
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The important part is that the verifier does not ask the model for an open-ended
|
|
36
|
+
score. It asks for a small discrete token from a known scale, then uses the
|
|
37
|
+
token distribution to estimate the final normalized score.
|
|
38
|
+
|
|
39
|
+
## Why The Output Is A Score Token
|
|
40
|
+
|
|
41
|
+
The verifier uses a discrete score scale such as `A..T`.
|
|
42
|
+
|
|
43
|
+
That choice is deliberate:
|
|
44
|
+
|
|
45
|
+
- it keeps the scoring space bounded
|
|
46
|
+
- it makes the provider response easier to parse
|
|
47
|
+
- it makes `logprobs` directly useful
|
|
48
|
+
- it lets the runtime compute an expected score instead of a brittle hard label
|
|
49
|
+
|
|
50
|
+
Letters are preferred over digits for the default scale because they behave
|
|
51
|
+
more like single symbolic labels as granularity grows.
|
|
52
|
+
|
|
53
|
+
That matters for `logprobs` extraction:
|
|
54
|
+
|
|
55
|
+
- `A..T` is a cleaner discrete label set than `1..20`
|
|
56
|
+
- multi-digit numeric scales are more likely to split across tokens
|
|
57
|
+
- numeric labels are more likely to attach to punctuation or formatting noise
|
|
58
|
+
- letter labels are easier to rank, normalize, and recover from imperfect tag
|
|
59
|
+
formatting
|
|
60
|
+
|
|
61
|
+
So the default runtime chooses a letter-based scale not for presentation, but
|
|
62
|
+
for tokenization stability and better score-distribution extraction.
|
|
63
|
+
|
|
64
|
+
So the model is not asked to emit a floating-point score. It is asked to emit a
|
|
65
|
+
single token inside a known tag:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
<score>A</score>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
or, in pairwise mode:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
<score_A>A</score_A>
|
|
75
|
+
<score_B>H</score_B>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`ScoreScale.letter(granularity=20)` is the public way to ask for 20 score
|
|
79
|
+
levels explicitly. That is also the default runtime scale.
|
|
80
|
+
|
|
81
|
+
## Prompt Construction
|
|
82
|
+
|
|
83
|
+
`default_prompt_builder(...)` assembles the verifier prompt from
|
|
84
|
+
`VerificationPromptInput`.
|
|
85
|
+
|
|
86
|
+
That input contains:
|
|
87
|
+
|
|
88
|
+
- `task`
|
|
89
|
+
- `criterion`
|
|
90
|
+
- `candidates`
|
|
91
|
+
- `score_scale`
|
|
92
|
+
- optional `context`
|
|
93
|
+
- optional verifier-level instructions
|
|
94
|
+
|
|
95
|
+
The default builder always explains:
|
|
96
|
+
|
|
97
|
+
- the criterion being judged
|
|
98
|
+
- the valid score-token range
|
|
99
|
+
- the exact tag format expected at the end
|
|
100
|
+
|
|
101
|
+
This is why the verifier can support custom prompting without changing the rest
|
|
102
|
+
of the execution pipeline. The builder is only responsible for prompt text; the
|
|
103
|
+
runtime remains responsible for scoring and aggregation.
|
|
104
|
+
|
|
105
|
+
## Trajectory Formatting Helpers
|
|
106
|
+
|
|
107
|
+
Benchmark-style presets work best when the candidate contains the full execution
|
|
108
|
+
evidence, not only the final answer.
|
|
109
|
+
|
|
110
|
+
The public API therefore exposes:
|
|
111
|
+
|
|
112
|
+
- `format_terminal_trajectory(...)`
|
|
113
|
+
- `format_swe_bench_trajectory(...)`
|
|
114
|
+
|
|
115
|
+
These helpers deliberately format only candidate evidence:
|
|
116
|
+
|
|
117
|
+
- summaries
|
|
118
|
+
- command/output steps
|
|
119
|
+
- metadata such as expected output
|
|
120
|
+
- final patch text for SWE-style runs
|
|
121
|
+
- final answer or final narration
|
|
122
|
+
|
|
123
|
+
The task or issue description stays outside the helper and should still be
|
|
124
|
+
passed through the verifier's `task` argument. That keeps the verifier API
|
|
125
|
+
clean: `task` carries the evaluation target, while the formatted candidate
|
|
126
|
+
string carries the evidence being judged.
|
|
127
|
+
|
|
128
|
+
## Request Batching And Concurrency
|
|
129
|
+
|
|
130
|
+
The verifier builds a `VerificationRequest` for each independent
|
|
131
|
+
criterion/repetition pair.
|
|
132
|
+
|
|
133
|
+
That means the number of model calls in a single verification is:
|
|
134
|
+
|
|
135
|
+
```text
|
|
136
|
+
len(criteria) * n_verifications
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Those requests are independent, so the verifier fans them out concurrently:
|
|
140
|
+
|
|
141
|
+
- `__call__` uses `F.map_gather(...)`
|
|
142
|
+
- `acall` uses `F.amap_gather(...)`
|
|
143
|
+
|
|
144
|
+
This matters because a verifier with multiple criteria and repeated attempts can
|
|
145
|
+
otherwise accumulate latency linearly.
|
|
146
|
+
|
|
147
|
+
The runtime still keeps the final result deterministic:
|
|
148
|
+
|
|
149
|
+
- requests are built in criterion order, then repetition order
|
|
150
|
+
- gather responses preserve input order
|
|
151
|
+
- attempts are regrouped per criterion after execution
|
|
152
|
+
|
|
153
|
+
So the work is concurrent, but the aggregation order remains stable.
|
|
154
|
+
|
|
155
|
+
## Why `select_best(...)` Is Separate
|
|
156
|
+
|
|
157
|
+
`__call__` and `acall` support only one or two candidates.
|
|
158
|
+
|
|
159
|
+
That boundary is intentional:
|
|
160
|
+
|
|
161
|
+
- one candidate -> verification
|
|
162
|
+
- two candidates -> pairwise comparison
|
|
163
|
+
- more than two candidates -> tournament selection
|
|
164
|
+
|
|
165
|
+
`select_best(...)` and `aselect_best(...)` implement the tournament layer on top
|
|
166
|
+
of the base verifier. They run pairwise matches, accumulate wins, and use
|
|
167
|
+
average score as a tiebreaker.
|
|
168
|
+
|
|
169
|
+
The tournament layer can also fan out its pairwise matches concurrently. That
|
|
170
|
+
means a multi-candidate selection now has two concurrency layers:
|
|
171
|
+
|
|
172
|
+
- concurrent attempts inside each verifier call
|
|
173
|
+
- concurrent pairwise matches across the tournament
|
|
174
|
+
|
|
175
|
+
This keeps the core verifier simple instead of making `__call__` return
|
|
176
|
+
different shapes for different candidate counts.
|
|
177
|
+
|
|
178
|
+
## Scoring From Logprobs
|
|
179
|
+
|
|
180
|
+
The central scoring path is:
|
|
181
|
+
|
|
182
|
+
```text
|
|
183
|
+
model response
|
|
184
|
+
-> locate score token
|
|
185
|
+
-> collect chosen token + top_logprobs alternatives
|
|
186
|
+
-> convert logprobs to probabilities
|
|
187
|
+
-> compute expected value on the discrete score scale
|
|
188
|
+
-> normalize to [0, 1]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
This is why `LLMAsVerifier` always requests:
|
|
192
|
+
|
|
193
|
+
- `logprobs=True`
|
|
194
|
+
- `top_logprobs=<scale size or override>`
|
|
195
|
+
|
|
196
|
+
If the provider returns a good token distribution, the verifier uses that
|
|
197
|
+
distribution directly.
|
|
198
|
+
|
|
199
|
+
If not, and `strict_logprobs=False`, it falls back to parsing the score from the
|
|
200
|
+
response text.
|
|
201
|
+
|
|
202
|
+
## Why The Parser Has Heuristics
|
|
203
|
+
|
|
204
|
+
Provider tokenization around XML-like tags is not always clean.
|
|
205
|
+
|
|
206
|
+
The verifier therefore uses a layered extraction strategy:
|
|
207
|
+
|
|
208
|
+
1. parse the text tag if possible
|
|
209
|
+
2. try to find the matching score entry directly in `logprobs`
|
|
210
|
+
3. fall back to finding the expected score token near the closing tag
|
|
211
|
+
4. if strict mode is disabled, fall back to text-only extraction
|
|
212
|
+
|
|
213
|
+
This is also why the parser tolerates malformed openings such as:
|
|
214
|
+
|
|
215
|
+
```text
|
|
216
|
+
<20A</score>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The runtime treats the text and token stream as evidence that must be reconciled,
|
|
220
|
+
not as perfectly formatted output.
|
|
221
|
+
|
|
222
|
+
## Aggregation Model
|
|
223
|
+
|
|
224
|
+
There are two aggregation stages.
|
|
225
|
+
|
|
226
|
+
### Attempt Aggregation
|
|
227
|
+
|
|
228
|
+
Each criterion can run multiple repetitions.
|
|
229
|
+
|
|
230
|
+
Those repeated attempts are averaged into a single score per criterion and
|
|
231
|
+
candidate.
|
|
232
|
+
|
|
233
|
+
### Criterion Aggregation
|
|
234
|
+
|
|
235
|
+
Each criterion carries a weight.
|
|
236
|
+
|
|
237
|
+
The final score per candidate is the weighted average of all criterion scores.
|
|
238
|
+
|
|
239
|
+
That is what makes the verifier reusable across different presets: the
|
|
240
|
+
execution path stays the same while the criteria set changes.
|
|
241
|
+
|
|
242
|
+
## Verdict Semantics
|
|
243
|
+
|
|
244
|
+
The final verdict depends on candidate count.
|
|
245
|
+
|
|
246
|
+
For a single candidate:
|
|
247
|
+
|
|
248
|
+
- `pass`
|
|
249
|
+
- `fail`
|
|
250
|
+
- `uncertain`
|
|
251
|
+
|
|
252
|
+
For two candidates:
|
|
253
|
+
|
|
254
|
+
- winner label
|
|
255
|
+
- `tie`
|
|
256
|
+
|
|
257
|
+
This is why `VerifierResult` exposes both:
|
|
258
|
+
|
|
259
|
+
- `verdict`
|
|
260
|
+
- optional `winner`
|
|
261
|
+
|
|
262
|
+
## Verbose Mode
|
|
263
|
+
|
|
264
|
+
When `verbose=True`, the verifier stores enough information to debug prompt and
|
|
265
|
+
scoring behavior without rerunning the call.
|
|
266
|
+
|
|
267
|
+
Per attempt, it keeps:
|
|
268
|
+
|
|
269
|
+
- final prompt text
|
|
270
|
+
- raw response text
|
|
271
|
+
- per-candidate evidence
|
|
272
|
+
- extracted token probabilities
|
|
273
|
+
|
|
274
|
+
That data is exposed both in:
|
|
275
|
+
|
|
276
|
+
- `criteria_results[*].attempts[*]`
|
|
277
|
+
- `result.metadata["raw_outputs"]`
|
|
278
|
+
|
|
279
|
+
Tournament mode mirrors that same information in each match entry of
|
|
280
|
+
`TournamentResult.metadata["raw_outputs"]`.
|
|
281
|
+
|
|
282
|
+
## Presets
|
|
283
|
+
|
|
284
|
+
The preset constructors are thin wrappers around the same runtime:
|
|
285
|
+
|
|
286
|
+
- `trajectory_analysis`
|
|
287
|
+
- `answer_reranking`
|
|
288
|
+
- `grounded_answer_verification`
|
|
289
|
+
- `patch_selection`
|
|
290
|
+
- `terminal_bench`
|
|
291
|
+
- `swe_bench_verified`
|
|
292
|
+
- `tool_trace_verification`
|
|
293
|
+
- `synthetic_data_filtering`
|
|
294
|
+
|
|
295
|
+
Each preset only supplies:
|
|
296
|
+
|
|
297
|
+
- a default criteria set
|
|
298
|
+
- optional default instructions or ground-truth notes
|
|
299
|
+
|
|
300
|
+
The runtime path stays identical.
|
|
301
|
+
|
|
302
|
+
This is important for maintenance because it means new verifier presets should
|
|
303
|
+
usually be data/config additions, not new execution engines.
|
|
304
|
+
|
|
305
|
+
## Main Design Choices
|
|
306
|
+
|
|
307
|
+
The current design makes a few explicit tradeoffs:
|
|
308
|
+
|
|
309
|
+
- verifier core is independent from `Agent`
|
|
310
|
+
- prompt building is pluggable, scoring is centralized
|
|
311
|
+
- discrete score tokens are preferred over free-form numeric scores
|
|
312
|
+
- `logprobs` are first-class evidence
|
|
313
|
+
- tournament selection is built on top of pairwise verification
|
|
314
|
+
- verbose debugging is part of the runtime, not an external wrapper
|
|
315
|
+
|
|
316
|
+
These choices make the verifier easier to reuse for reranking, trajectory
|
|
317
|
+
selection, patch selection, and future optimizer integrations.
|
|
@@ -59,17 +59,20 @@ Chat completion models are stateless - they don't maintain conversation history
|
|
|
59
59
|
reasoning_effort="medium", # "minimal", "low", "medium", "high"
|
|
60
60
|
enable_thinking=True, # Enable extended model reasoning
|
|
61
61
|
return_reasoning=True, # Include reasoning content in response
|
|
62
|
-
reasoning_max_tokens=4096, #
|
|
62
|
+
reasoning_max_tokens=4096, # OpenRouter only: max tokens reserved for reasoning/thinking
|
|
63
63
|
reasoning_in_tool_call=True, # Preserve reasoning context across tool calls
|
|
64
64
|
# --- Output ---
|
|
65
65
|
modalities=["text"], # ["text"], ["audio"] or ["text", "audio"]
|
|
66
66
|
audio={"voice": "alloy", "format": "mp3"}, # Audio output config
|
|
67
67
|
verbosity="medium", # Response verbosity: "low", "medium", "high"
|
|
68
|
+
logprobs=True, # Include token logprobs in metadata
|
|
69
|
+
top_logprobs=2, # Return 2 alternatives per token
|
|
68
70
|
parallel_tool_calls=True, # Allow model to call multiple tools in parallel
|
|
69
71
|
validate_typed_parser_output=False, # Validate typed parser output with schema
|
|
70
72
|
verbose=False, # Print raw output before transformation
|
|
71
73
|
# --- Search ---
|
|
72
74
|
web_search_options={}, # Web search config (OpenAI / OpenRouter only)
|
|
75
|
+
prompt_cache_retention="24h", # OpenAI only: "in_memory" or "24h"
|
|
73
76
|
# --- Infrastructure ---
|
|
74
77
|
base_url="https://api.openai.com/v1", # Override provider API endpoint
|
|
75
78
|
context_length=128000, # Override maximum context window
|
|
@@ -837,7 +840,7 @@ msgFlux exposes five parameters that control reasoning behaviour at model initia
|
|
|
837
840
|
| Parameter | Description | Default |
|
|
838
841
|
|---|---|---|
|
|
839
842
|
| `reasoning_effort` | How much reasoning to do. One of `"minimal"`, `"low"`, `"medium"`, `"high"`. | — |
|
|
840
|
-
| `reasoning_max_tokens` |
|
|
843
|
+
| `reasoning_max_tokens` | OpenRouter-only hard cap (in tokens) for the internal thinking budget. Maps to `extra_body.reasoning.max_tokens` and cannot be combined with `reasoning_effort`. | — |
|
|
841
844
|
| `return_reasoning` | Store the reasoning trace in `response.reasoning`. When `False`, reasoning is discarded even if the provider returns it. | `True` |
|
|
842
845
|
| `enable_thinking` | Activate extended model reasoning. | `False` |
|
|
843
846
|
| `reasoning_in_tool_call` | Preserve reasoning context across tool calls so the model keeps its chain of thought intact. When enabled, the `ToolCallAggregator` embeds the reasoning in `<think>` tags inside the assistant message history, allowing the model to see its previous reasoning when processing tool results. | `False` |
|
|
@@ -1007,7 +1010,7 @@ Providers that keep reasoning internal (like OpenAI) still report how many token
|
|
|
1007
1010
|
|
|
1008
1011
|
### 12.6 **Controlling the Reasoning Budget**
|
|
1009
1012
|
|
|
1010
|
-
`reasoning_max_tokens`
|
|
1013
|
+
`reasoning_max_tokens` is an OpenRouter-only parameter in msgFlux. It maps to `extra_body={"reasoning": {"max_tokens": ...}}` on the OpenRouter API and cannot be combined with `reasoning_effort`.
|
|
1011
1014
|
|
|
1012
1015
|
???+ example
|
|
1013
1016
|
|
|
@@ -1015,17 +1018,17 @@ Providers that keep reasoning internal (like OpenAI) still report how many token
|
|
|
1015
1018
|
import msgflux as mf
|
|
1016
1019
|
|
|
1017
1020
|
model = mf.Model.chat_completion(
|
|
1018
|
-
"
|
|
1019
|
-
|
|
1020
|
-
reasoning_max_tokens=512, # Cap the thinking budget
|
|
1021
|
+
"openrouter/anthropic/claude-sonnet-4.5",
|
|
1022
|
+
reasoning_max_tokens=2000,
|
|
1021
1023
|
)
|
|
1022
1024
|
|
|
1023
|
-
response = model("
|
|
1024
|
-
print(response.consume_reasoning())
|
|
1025
|
+
response = model("What's the weather like in Boston? Then recommend what to wear.")
|
|
1026
|
+
print(response.consume_reasoning())
|
|
1025
1027
|
print(response.consume())
|
|
1026
|
-
# x = 5
|
|
1027
1028
|
```
|
|
1028
1029
|
|
|
1030
|
+
OpenRouter's own API examples pass the reasoning budget inside `extra_body={"reasoning": {"max_tokens": 2000}}`; msgFlux translates the model-level `reasoning_max_tokens` parameter to that shape for you.
|
|
1031
|
+
|
|
1029
1032
|
### 12.7 **Streaming with Reasoning**
|
|
1030
1033
|
|
|
1031
1034
|
Streaming introduces a dual-queue architecture. Content and reasoning flow through independent queues, allowing consumers to process them in parallel or sequentially.
|
|
@@ -1383,7 +1386,61 @@ if "tool_call" in model_response.response_type:
|
|
|
1383
1386
|
|
|
1384
1387
|
The Agent reads `model_response.reasoning` to pass it downstream. If the Agent's `config["reasoning_in_response"]` is `True`, the final output is wrapped as `dotdict(answer=raw_response, reasoning=reasoning)` — this is an explicit opt-in at the Agent level, not a silent model-level behaviour.
|
|
1385
1388
|
|
|
1386
|
-
## 13. **
|
|
1389
|
+
## 13. **Token Logprobs**
|
|
1390
|
+
|
|
1391
|
+
`logprobs` and `top_logprobs` are forwarded for `openai/...` chat completion models. Providers that inherit from `OpenAIChatCompletion` but are not OpenAI do not receive these fields.
|
|
1392
|
+
|
|
1393
|
+
Use `logprobs=True` to request token log probabilities. Set `top_logprobs` to the number of alternative tokens you want returned for each generated token.
|
|
1394
|
+
|
|
1395
|
+
| Parameter | Description |
|
|
1396
|
+
|---|---|
|
|
1397
|
+
| `logprobs` | Enables token-level logprob data in the response metadata. |
|
|
1398
|
+
| `top_logprobs` | Number of alternative tokens returned per generated token. Use with `logprobs=True`. |
|
|
1399
|
+
|
|
1400
|
+
The returned payload is exposed in `response.metadata.logprobs` and follows OpenAI's native shape. It includes the `content` list with token entries and nested `top_logprobs` alternatives.
|
|
1401
|
+
|
|
1402
|
+
???+ example
|
|
1403
|
+
|
|
1404
|
+
```python
|
|
1405
|
+
import msgflux as mf
|
|
1406
|
+
|
|
1407
|
+
model = mf.Model.chat_completion(
|
|
1408
|
+
"openai/gpt-4.1-mini",
|
|
1409
|
+
logprobs=True,
|
|
1410
|
+
top_logprobs=2,
|
|
1411
|
+
)
|
|
1412
|
+
|
|
1413
|
+
response = model("Hello!")
|
|
1414
|
+
print(response.metadata.logprobs["content"][0]["token"])
|
|
1415
|
+
print(response.metadata.logprobs["content"][0]["top_logprobs"][0]["token"])
|
|
1416
|
+
```
|
|
1417
|
+
|
|
1418
|
+
## 14. **OpenAI Prompt Caching**
|
|
1419
|
+
|
|
1420
|
+
`prompt_cache_retention` is an OpenAI-only initialization parameter. msgFlux forwards it only for `openai/...` chat completion models. OpenAI-compatible providers that inherit from `OpenAIChatCompletion` do not use it.
|
|
1421
|
+
|
|
1422
|
+
Use it when you want OpenAI to keep cached prefixes in memory or retain them for longer:
|
|
1423
|
+
|
|
1424
|
+
| Value | Behaviour |
|
|
1425
|
+
|---|---|
|
|
1426
|
+
| `"in_memory"` | Default. Keeps the cache in volatile memory for short-lived reuse. |
|
|
1427
|
+
| `"24h"` | Extended retention. Keeps cached prefixes available for longer. |
|
|
1428
|
+
|
|
1429
|
+
???+ example
|
|
1430
|
+
|
|
1431
|
+
```python
|
|
1432
|
+
import msgflux as mf
|
|
1433
|
+
|
|
1434
|
+
model = mf.Model.chat_completion(
|
|
1435
|
+
"openai/gpt-5.1",
|
|
1436
|
+
prompt_cache_retention="24h",
|
|
1437
|
+
)
|
|
1438
|
+
|
|
1439
|
+
response = model("Summarize the attached policy.")
|
|
1440
|
+
print(response.consume())
|
|
1441
|
+
```
|
|
1442
|
+
|
|
1443
|
+
## 15. **Response Metadata**
|
|
1387
1444
|
|
|
1388
1445
|
All responses include metadata with usage information:
|
|
1389
1446
|
|
|
@@ -1419,7 +1476,7 @@ All responses include metadata with usage information:
|
|
|
1419
1476
|
print(f"Request cost: ${cost:.4f}")
|
|
1420
1477
|
```
|
|
1421
1478
|
|
|
1422
|
-
##
|
|
1479
|
+
## 16. **Error Handling**
|
|
1423
1480
|
|
|
1424
1481
|
Handle common errors gracefully:
|
|
1425
1482
|
|
|
@@ -1441,7 +1498,7 @@ Handle common errors gracefully:
|
|
|
1441
1498
|
print(f"API error: {e}")
|
|
1442
1499
|
```
|
|
1443
1500
|
|
|
1444
|
-
##
|
|
1501
|
+
## 17. **Model Profiles**
|
|
1445
1502
|
|
|
1446
1503
|
Model profiles provide metadata about capabilities, pricing, and limits from [models.dev](https://models.dev).
|
|
1447
1504
|
|
|
@@ -1507,11 +1564,11 @@ Every initialized model exposes a `.profile` property that returns this metadata
|
|
|
1507
1564
|
print(f"Estimated cost: ${cost:.4f}")
|
|
1508
1565
|
```
|
|
1509
1566
|
|
|
1510
|
-
##
|
|
1567
|
+
## 18. **Adding a Custom Provider**
|
|
1511
1568
|
|
|
1512
1569
|
If the service you want to use exposes an **OpenAI-compatible API**, you can add it as a provider by subclassing `OpenAIChatCompletion`. The process has two stages depending on how compatible the endpoint is.
|
|
1513
1570
|
|
|
1514
|
-
###
|
|
1571
|
+
### 18.1 **Stage 1 — URL and API key only**
|
|
1515
1572
|
|
|
1516
1573
|
When the target API is fully OpenAI-compatible and only requires a different base URL and authentication key, the entire subclass is a small configuration mixin plus the `@register_model` decorator.
|
|
1517
1574
|
|
|
@@ -1555,7 +1612,7 @@ After registering, the model is available through the standard factory. The stri
|
|
|
1555
1612
|
print(response.consume())
|
|
1556
1613
|
```
|
|
1557
1614
|
|
|
1558
|
-
###
|
|
1615
|
+
### 18.2 **Stage 2 — Adapting parameters**
|
|
1559
1616
|
|
|
1560
1617
|
Some providers are mostly OpenAI-compatible but have small differences: renamed fields, required extra headers, or unsupported parameters. Override `_adapt_params` to transform the parameter dict before it reaches the API.
|
|
1561
1618
|
|
|
@@ -1598,12 +1655,22 @@ The built-in OpenRouter provider is a real-world example:
|
|
|
1598
1655
|
if params["tool_choice"] is None:
|
|
1599
1656
|
params["tool_choice"] = "auto" if params["tools"] else "none"
|
|
1600
1657
|
|
|
1601
|
-
# 3. Map
|
|
1658
|
+
# 3. Map reasoning parameters to the provider format
|
|
1602
1659
|
reasoning_effort = params.pop("reasoning_effort", None)
|
|
1660
|
+
reasoning_max_tokens = params.pop("reasoning_max_tokens", None)
|
|
1661
|
+
if reasoning_effort is not None and reasoning_max_tokens is not None:
|
|
1662
|
+
raise ValueError(
|
|
1663
|
+
"`reasoning_max_tokens` cannot be used together with "
|
|
1664
|
+
"`reasoning_effort` for OpenRouter."
|
|
1665
|
+
)
|
|
1603
1666
|
if reasoning_effort is not None:
|
|
1604
1667
|
extra_body = params.get("extra_body", {})
|
|
1605
1668
|
extra_body["reasoning"] = {"effort": reasoning_effort}
|
|
1606
1669
|
params["extra_body"] = extra_body
|
|
1670
|
+
if reasoning_max_tokens is not None:
|
|
1671
|
+
extra_body = params.get("extra_body", {})
|
|
1672
|
+
extra_body["reasoning"] = {"max_tokens": reasoning_max_tokens}
|
|
1673
|
+
params["extra_body"] = extra_body
|
|
1607
1674
|
|
|
1608
1675
|
# 4. Add required headers
|
|
1609
1676
|
params["extra_headers"] = {
|
|
@@ -1619,11 +1686,11 @@ Common adaptations inside `_adapt_params`:
|
|
|
1619
1686
|
|---|---|
|
|
1620
1687
|
| Provider uses `max_completion_tokens` instead of `max_tokens` | `params["max_completion_tokens"] = params.pop("max_tokens")` |
|
|
1621
1688
|
| Provider rejects `tool_choice=None` | Set it explicitly to `"auto"` or `"none"` |
|
|
1622
|
-
| Provider uses a different field for reasoning | `params.pop("reasoning_effort")` and remap into `extra_body` |
|
|
1689
|
+
| Provider uses a different field for reasoning | `params.pop("reasoning_effort")` or `params.pop("reasoning_max_tokens")` and remap into `extra_body` |
|
|
1623
1690
|
| Provider requires extra headers | Add keys to `params["extra_headers"]` |
|
|
1624
1691
|
| Provider accepts non-standard extensions | Add keys to `params["extra_body"]` |
|
|
1625
1692
|
|
|
1626
|
-
###
|
|
1693
|
+
### 18.3 **Stage 3 — Using a different client**
|
|
1627
1694
|
|
|
1628
1695
|
The two previous stages assume the service is reached through the `openai` Python package. If you want to use a completely different HTTP client or SDK — one that is **not** the `openai` package but still exposes a compatible interface — override `_initialize` instead.
|
|
1629
1696
|
|
|
@@ -8,9 +8,9 @@ Modern language models can "think before answering" — generating an internal c
|
|
|
8
8
|
|---|---|---|
|
|
9
9
|
| **What it is** | The model's native thinking capability (e.g. `reasoning_effort="high"`) | A `generation_schema` that forces structured thinking (CoT, ReAct, SelfConsistency) |
|
|
10
10
|
| **Where reasoning lives** | `response.reasoning` — a first-class field on the response object | Inside `response.consume()` — as a field of the structured output (e.g. `result.reasoning`) |
|
|
11
|
-
| **Configured via** | Model params: `reasoning_effort`, `return_reasoning`, `reasoning_max_tokens` | Agent param: `generation_schema=ChainOfThought` |
|
|
11
|
+
| **Configured via** | Model params: `reasoning_effort`, `return_reasoning`, `reasoning_max_tokens` (OpenRouter only) | Agent param: `generation_schema=ChainOfThought` |
|
|
12
12
|
| **Works with any model** | No — requires a reasoning-capable model (Groq gpt-oss, OpenAI o-series, etc.) | Yes — any model that supports structured output |
|
|
13
|
-
| **Controllable budget** | Yes — `reasoning_effort
|
|
13
|
+
| **Controllable budget** | Yes — `reasoning_effort`; OpenRouter also supports `reasoning_max_tokens` | No — the model decides how much to write in the schema field |
|
|
14
14
|
| **Can combine with tools** | Yes — `reasoning_in_tool_call=True` preserves the chain across calls | Yes — ReAct is specifically designed for tool use |
|
|
15
15
|
|
|
16
16
|
!!! tip
|
|
@@ -28,10 +28,9 @@ Model-level reasoning is configured at model initialization through parameters f
|
|
|
28
28
|
import msgflux as mf
|
|
29
29
|
|
|
30
30
|
model = mf.Model.chat_completion(
|
|
31
|
-
"
|
|
32
|
-
reasoning_effort="low", # How much to think: "minimal", "low", "medium", "high"
|
|
31
|
+
"openrouter/anthropic/claude-sonnet-4.5",
|
|
33
32
|
return_reasoning=True, # Store the trace in response.reasoning (default: True)
|
|
34
|
-
reasoning_max_tokens=1024, #
|
|
33
|
+
reasoning_max_tokens=1024, # OpenRouter only: cap the thinking budget in tokens
|
|
35
34
|
reasoning_in_tool_call=True, # Preserve reasoning across tool call rounds
|
|
36
35
|
)
|
|
37
36
|
```
|
|
@@ -600,7 +599,7 @@ This is useful for debugging the relationship between the model's thinking and i
|
|
|
600
599
|
|---|---|---|---|
|
|
601
600
|
| `reasoning_effort` | `str` | — | `"minimal"`, `"low"`, `"medium"`, `"high"` |
|
|
602
601
|
| `return_reasoning` | `bool` | `True` | Store reasoning in `response.reasoning` |
|
|
603
|
-
| `reasoning_max_tokens` | `int` | — |
|
|
602
|
+
| `reasoning_max_tokens` | `int` | — | OpenRouter-only cap on reasoning token budget |
|
|
604
603
|
| `reasoning_in_tool_call` | `bool` | `False` | Embed reasoning in `<think>` tags across tool call rounds |
|
|
605
604
|
| `enable_thinking` | `bool` | `False` | Provider-level switch (e.g. Anthropic) |
|
|
606
605
|
|