unique_toolkit 2026.34.2__tar.gz → 2026.36.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.
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/PKG-INFO +2 -2
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/pyproject.toml +2 -2
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/pydantic/rjsf_tags.py +23 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +3 -1
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +51 -6
- unique_toolkit-2026.36.0/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/artifacts.py +213 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +10 -0
- unique_toolkit-2026.36.0/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/office_preview.py +154 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic_table/__init__.py +8 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic_table/schemas.py +102 -2
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic_table/service.py +75 -31
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/responses_api.py +3 -1
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/content/functions.py +34 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/__init__.py +6 -3
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/content_tree/__init__.py +14 -18
- unique_toolkit-2026.36.0/unique_toolkit/experimental/components/content_tree/functions.py +380 -0
- unique_toolkit-2026.36.0/unique_toolkit/experimental/components/content_tree/schemas.py +261 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/content_tree/service.py +244 -83
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/content_tree/__init__.py +4 -10
- unique_toolkit-2026.36.0/unique_toolkit/experimental/integrations/openai/streaming/event_routing/_model_params.py +133 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/chat_completions/complete_with_references.py +7 -4
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/complete_with_references.py +12 -8
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/functions.py +11 -2
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/infos.py +61 -0
- unique_toolkit-2026.36.0/unique_toolkit/language_model/invocation_stats.py +173 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/service.py +15 -1
- unique_toolkit-2026.34.2/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/artifacts.py +0 -103
- unique_toolkit-2026.34.2/unique_toolkit/experimental/components/content_tree/functions.py +0 -247
- unique_toolkit-2026.34.2/unique_toolkit/experimental/components/content_tree/schemas.py +0 -106
- unique_toolkit-2026.34.2/unique_toolkit/language_model/invocation_stats.py +0 -77
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/README.md +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/_base_service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/_time_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/README.md +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/__main__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/cli.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/differ.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/exporter.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/models.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/registry.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/config_checker/validator.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/default_language_model.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/docx_generator/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/docx_generator/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/endpoint_builder.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/endpoint_requestor.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/event_bus.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/exception.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/execution.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/feature_flags/schema.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/metadata_filter_scope.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/pydantic_helpers.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/referencing.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/string_utilities.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/tests/test_referencing.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/token/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/token/image_token_counting.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/token/token_counting.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/files.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/image/encode.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/jinja/render.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/utils/write_configuration.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/validate_required_values.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/validators.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/exception.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/tests/test_hallucination_external_context.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/evaluation/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/history_manager/settings.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/history_manager/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/base.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/message_log_order.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/reference_manager/tests/test_external_context.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_references.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/ask_user_tool/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/ask_user_tool/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/ask_user_tool/tool.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/open_file_tool/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/open_file_tool/tool.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/retrieve_search_scope_tool/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/retrieve_search_scope_tool/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/retrieve_search_scope_tool/tool.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/prompts/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/prompts/execution_reminder.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/prompts/tool_description.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/prompts/verification_nudge.j2 +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/experimental/todo/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/factory.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/names.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/activator/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/activator/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/activator/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/builder/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/builder/_container.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/builder/_files.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/builder/_memory.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/builder/builder.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/tool/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/tool/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/tool/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/run_context.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/tool.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic_table/synthetic_chat_event.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/chat_event_filter_options_settings.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/dev_util.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/fast_api_factory.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/feature_flags.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/find_env_file.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/init_logging.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/init_sdk.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/performance/async_tasks.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/performance/async_wrapper.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/unique_settings.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/verification.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/app/webhook.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/cancellation.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/constants.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/deprecated/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/deprecated/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/functions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/rendering.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/state.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/chat/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/content/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/content/constants.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/content/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/content/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/content/smart_rules.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/content/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/README.md +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/augmented/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/base.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/basic/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/data_extraction/basic/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/elicitation/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/elicitation/constants.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/elicitation/exceptions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/elicitation/functions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/elicitation/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/elicitation/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/embedding/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/embedding/constants.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/embedding/functions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/embedding/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/embedding/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/embedding/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/README.md +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/_internal/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/_internal/streaming/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/_internal/streaming/common.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/_internal/streaming/pattern_replacer.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/_base.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/base/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/base/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/base/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/base/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/base/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/chat/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/chat/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/chat/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/chat/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/knowledge_base/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/knowledge_base/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/knowledge_base/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/knowledge_base/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/post_processing/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/post_processing/config.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/components/internal_search/post_processing/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/identity/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/_async_bridge.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/chat_completions/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/chat_completions/stream_event_router.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/chat_completions/text_event_handler.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/chat_completions/tool_call_event_handler.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/events.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/protocols/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/protocols/chat_completions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/protocols/responses.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/code_interpreter_event_handler.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/completed_event_handler.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/stream_event_router.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/text_delta_event_handler.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/tool_call_event_handler.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/subscribers/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/subscribers/message_persister.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/integrations/openai/streaming/event_routing/subscribers/progress_log_persister.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/content_folder/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/content_folder/functions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/content_folder/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/content_folder/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/facades/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/facades/identity/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/facades/identity/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/feature_flags/README.md +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/feature_flags/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/feature_flags/_graphql_client.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/feature_flags/_ttl_cache.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/feature_flags/client.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/feature_flags/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/feature_flags/settings.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/group/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/group/functions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/group/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/group/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/scheduled_task/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/scheduled_task/cron.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/scheduled_task/functions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/scheduled_task/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/scheduled_task/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/user/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/user/functions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/user/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/resources/user/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/experimental/testing/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/framework_utilities/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/framework_utilities/openai/client.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/framework_utilities/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/builder.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/constants.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/default_language_model.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/model_costs.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/prompt.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/reference.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/settings.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/stream_transform.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/language_model/utils.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/monitoring/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/monitoring/gunicorn.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/monitoring/middleware.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/monitoring/registry.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/monitoring/tracing.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/protocols/support.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/services/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/services/chat_service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/services/factory.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/services/knowledge_base.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/short_term_memory/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/short_term_memory/constants.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/short_term_memory/functions.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/short_term_memory/schemas.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/short_term_memory/service.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/smart_rules/__init__.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/smart_rules/compile.py +0 -0
- {unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/test_utilities/events.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-toolkit
|
|
3
|
-
Version: 2026.
|
|
3
|
+
Version: 2026.36.0
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Cedric Klinkert, Martin Fadler, Sadique Sheik, Fabian Schläpfer, Pascal Hauri, Ejiroghene Oki-Peter, Rami Azouz, Ricardo Visini, Sanzio Monti
|
|
6
6
|
Author-email: Cedric Klinkert <cedric.klinkert@unique.ch>, Martin Fadler <martin.fadler@unique.ch>, Sadique Sheik <sadique@unique.ch>, Fabian Schläpfer <fabian@unique.ch>, Pascal Hauri <pascal@unique.ch>, Ejiroghene Oki-Peter <oki-peter.ejiroghene@unique.ai>, Rami Azouz <rami.ext@unique.ch>, Ricardo Visini <ricardo.visini@unique.ch>, Sanzio Monti <sanzio.monti@unique.ai>
|
|
@@ -16,7 +16,7 @@ Requires-Dist: sseclient>=0.0.27,<0.0.28
|
|
|
16
16
|
Requires-Dist: openai>=1.105.0,<3
|
|
17
17
|
Requires-Dist: platformdirs>=4.0.0,<5
|
|
18
18
|
Requires-Dist: pillow>=12.1.1
|
|
19
|
-
Requires-Dist: unique-sdk>=2026.
|
|
19
|
+
Requires-Dist: unique-sdk>=2026.36.0
|
|
20
20
|
Requires-Dist: jambo>=0.1.2,<0.2
|
|
21
21
|
Requires-Dist: jinja2>=3.1.6,<4
|
|
22
22
|
Requires-Dist: docxtpl>=0.20.1,<0.21
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "unique_toolkit"
|
|
3
|
-
version = "2026.
|
|
3
|
+
version = "2026.36.0"
|
|
4
4
|
description = ""
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -28,7 +28,7 @@ dependencies = [
|
|
|
28
28
|
"openai>=1.105.0,<3",
|
|
29
29
|
"platformdirs>=4.0.0,<5",
|
|
30
30
|
"pillow>=12.1.1",
|
|
31
|
-
"unique-sdk>=2026.
|
|
31
|
+
"unique-sdk>=2026.36.0",
|
|
32
32
|
"jambo>=0.1.2,<0.2",
|
|
33
33
|
"jinja2>=3.1.6,<4",
|
|
34
34
|
"docxtpl>=0.20.1,<0.21",
|
{unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/_common/pydantic/rjsf_tags.py
RENAMED
|
@@ -739,6 +739,20 @@ class RJSFMetaTag:
|
|
|
739
739
|
return RJSFMetaTag({**union_attrs, "anyOf": any_of_branches})
|
|
740
740
|
|
|
741
741
|
|
|
742
|
+
class DynamicRJSFTag:
|
|
743
|
+
"""Defer RJSF metadata until ``ui_schema_for_model`` runs.
|
|
744
|
+
|
|
745
|
+
Use for env-driven admin locks (``ui:disabled``) that must reflect the
|
|
746
|
+
deployment environment at schema-generation time, not at module import.
|
|
747
|
+
"""
|
|
748
|
+
|
|
749
|
+
def __init__(self, factory: Callable[[], RJSFMetaTag]) -> None:
|
|
750
|
+
self._factory = factory
|
|
751
|
+
|
|
752
|
+
def resolve_rjsf_tag(self) -> RJSFMetaTag:
|
|
753
|
+
return self._factory()
|
|
754
|
+
|
|
755
|
+
|
|
742
756
|
# --------- Helpers ----------
|
|
743
757
|
_NONE_TYPES = {type(None)}
|
|
744
758
|
"""
|
|
@@ -785,6 +799,12 @@ def _collect_metatags(extras: list[Any]) -> dict[str, Any]:
|
|
|
785
799
|
"""
|
|
786
800
|
out: dict[str, Any] = {}
|
|
787
801
|
for x in extras:
|
|
802
|
+
resolve = getattr(x, "resolve_rjsf_tag", None)
|
|
803
|
+
if callable(resolve):
|
|
804
|
+
tag = resolve()
|
|
805
|
+
if isinstance(tag, RJSFMetaTag):
|
|
806
|
+
out.update(tag.attrs)
|
|
807
|
+
continue
|
|
788
808
|
if isinstance(x, RJSFMetaTag):
|
|
789
809
|
out.update(x.attrs)
|
|
790
810
|
return out
|
|
@@ -938,6 +958,9 @@ def ui_schema_for_model(
|
|
|
938
958
|
# Re-process the unwrapped type to extract metadata from the Annotated branch.
|
|
939
959
|
if not meta and get_origin(base) is Annotated:
|
|
940
960
|
base, meta = _walk_annotated_chain(base)
|
|
961
|
+
field_meta = _collect_metatags(list(field_info.metadata))
|
|
962
|
+
if field_meta:
|
|
963
|
+
meta = {**meta, **field_meta}
|
|
941
964
|
# Start with field-level metadata (flat dict)
|
|
942
965
|
if meta:
|
|
943
966
|
node.update(meta)
|
|
@@ -196,7 +196,9 @@ async def download_encoded_images_async(
|
|
|
196
196
|
image_string = f"data:{mime_type};base64," + encoded_string
|
|
197
197
|
base64_encoded_images.append(image_string)
|
|
198
198
|
except Exception as e:
|
|
199
|
-
_LOGGER.warning(
|
|
199
|
+
_LOGGER.warning(
|
|
200
|
+
"Failed to download image %s: %s", im.key, e, exc_info=True
|
|
201
|
+
)
|
|
200
202
|
return base64_encoded_images
|
|
201
203
|
|
|
202
204
|
|
|
@@ -4,9 +4,10 @@ import json
|
|
|
4
4
|
import logging
|
|
5
5
|
import mimetypes
|
|
6
6
|
import uuid
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
import unique_sdk
|
|
10
|
+
from pydantic import ValidationError
|
|
10
11
|
|
|
11
12
|
from unique_toolkit.agentic.evaluation.schemas import EvaluationMetricName
|
|
12
13
|
from unique_toolkit.agentic.tools.mcp.models import MCPToolConfig
|
|
@@ -17,6 +18,7 @@ from unique_toolkit.app.schemas import ChatEvent, McpServer, McpTool
|
|
|
17
18
|
from unique_toolkit.chat.schemas import MessageLog, MessageLogStatus
|
|
18
19
|
from unique_toolkit.chat.service import ChatService
|
|
19
20
|
from unique_toolkit.content.functions import upload_content_from_bytes
|
|
21
|
+
from unique_toolkit.content.schemas import ContentChunk, ContentReference
|
|
20
22
|
from unique_toolkit.language_model import LanguageModelService
|
|
21
23
|
from unique_toolkit.language_model.schemas import (
|
|
22
24
|
LanguageModelFunction,
|
|
@@ -25,6 +27,8 @@ from unique_toolkit.language_model.schemas import (
|
|
|
25
27
|
|
|
26
28
|
logger = logging.getLogger(__name__)
|
|
27
29
|
|
|
30
|
+
REFERENCE_META_KEY = "unique.app/reference"
|
|
31
|
+
|
|
28
32
|
|
|
29
33
|
class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
30
34
|
"""Wrapper class for MCP tools that implements the Tool interface"""
|
|
@@ -67,7 +71,7 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
67
71
|
parameters=self._mcp_tool.input_schema,
|
|
68
72
|
)
|
|
69
73
|
|
|
70
|
-
def _json_schema_to_python_type(self, schema:
|
|
74
|
+
def _json_schema_to_python_type(self, schema: dict[str, Any]) -> type:
|
|
71
75
|
"""Convert JSON schema type to Python type"""
|
|
72
76
|
json_type = schema.get("type", "string")
|
|
73
77
|
|
|
@@ -135,9 +139,14 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
135
139
|
# Use SDK to call the public API
|
|
136
140
|
result = await self._call_mcp_tool_via_sdk(arguments)
|
|
137
141
|
|
|
142
|
+
content_chunks, references = self._extract_structured_references(result)
|
|
138
143
|
content_str, image_data_urls = await asyncio.to_thread(
|
|
139
144
|
self._process_mcp_result, result
|
|
140
145
|
)
|
|
146
|
+
if content_chunks:
|
|
147
|
+
# Structured references already carry the text; keep any
|
|
148
|
+
# extracted images but drop the redundant flat text.
|
|
149
|
+
content_str = ""
|
|
141
150
|
|
|
142
151
|
# TODO: Why result here not applied directly to the body of the tool_response? like so how does it know the results in the history?
|
|
143
152
|
tool_response = ToolCallResponse(
|
|
@@ -150,6 +159,7 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
150
159
|
},
|
|
151
160
|
error_message="",
|
|
152
161
|
content=content_str,
|
|
162
|
+
content_chunks=content_chunks or None,
|
|
153
163
|
image_data_urls=image_data_urls,
|
|
154
164
|
)
|
|
155
165
|
|
|
@@ -158,6 +168,7 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
158
168
|
progress_message="_Completed MCP tool_",
|
|
159
169
|
status=MessageLogStatus.COMPLETED,
|
|
160
170
|
active_message_log=active_message_log,
|
|
171
|
+
references=references,
|
|
161
172
|
)
|
|
162
173
|
|
|
163
174
|
return tool_response
|
|
@@ -189,17 +200,19 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
189
200
|
progress_message: str | None = None,
|
|
190
201
|
status: MessageLogStatus = MessageLogStatus.RUNNING,
|
|
191
202
|
active_message_log: MessageLog | None = None,
|
|
203
|
+
references: list[ContentReference] | None = None,
|
|
192
204
|
) -> MessageLog | None:
|
|
193
205
|
return self._message_step_logger.create_or_update_message_log(
|
|
194
206
|
active_message_log=active_message_log,
|
|
195
207
|
header=self.display_name(),
|
|
196
208
|
progress_message=progress_message,
|
|
197
209
|
status=status,
|
|
210
|
+
references=references or [],
|
|
198
211
|
)
|
|
199
212
|
|
|
200
213
|
def _extract_and_validate_arguments(
|
|
201
214
|
self, tool_call: LanguageModelFunction
|
|
202
|
-
) ->
|
|
215
|
+
) -> dict[str, Any]:
|
|
203
216
|
"""
|
|
204
217
|
Extract and validate arguments from tool call, handling various formats robustly.
|
|
205
218
|
|
|
@@ -246,7 +259,39 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
246
259
|
f"Unexpected arguments type for MCP tool {self.name}: {type(raw_arguments)}"
|
|
247
260
|
)
|
|
248
261
|
|
|
249
|
-
def
|
|
262
|
+
def _extract_structured_references(
|
|
263
|
+
self, result: dict[str, Any]
|
|
264
|
+
) -> tuple[list[ContentChunk], list[ContentReference]]:
|
|
265
|
+
"""Opt-in: content items with valid ``unique.app/reference`` + chunk ``_meta``."""
|
|
266
|
+
chunks: list[ContentChunk] = []
|
|
267
|
+
references: list[ContentReference] = []
|
|
268
|
+
content_items = self._extract_content_items(result)
|
|
269
|
+
for item in content_items:
|
|
270
|
+
if not isinstance(item, dict) or item.get("type") != "text":
|
|
271
|
+
continue
|
|
272
|
+
meta = item.get("_meta")
|
|
273
|
+
if not isinstance(meta, dict):
|
|
274
|
+
continue
|
|
275
|
+
ref_payload = meta.get(REFERENCE_META_KEY)
|
|
276
|
+
if not isinstance(ref_payload, dict):
|
|
277
|
+
continue
|
|
278
|
+
try:
|
|
279
|
+
reference = ContentReference.model_validate(ref_payload)
|
|
280
|
+
chunk = ContentChunk.model_validate(
|
|
281
|
+
{k: v for k, v in meta.items() if k != REFERENCE_META_KEY}
|
|
282
|
+
)
|
|
283
|
+
except ValidationError:
|
|
284
|
+
self.logger.warning(
|
|
285
|
+
"MCP tool %s: ignoring invalid %s metadata",
|
|
286
|
+
self.name,
|
|
287
|
+
REFERENCE_META_KEY,
|
|
288
|
+
)
|
|
289
|
+
continue
|
|
290
|
+
references.append(reference)
|
|
291
|
+
chunks.append(chunk)
|
|
292
|
+
return chunks, references
|
|
293
|
+
|
|
294
|
+
def _process_mcp_result(self, result: dict[str, Any]) -> tuple[str, list[str]]:
|
|
250
295
|
"""Parse MCP result content array, upload images, return content string and data URLs."""
|
|
251
296
|
content_items = self._extract_content_items(result)
|
|
252
297
|
if not content_items:
|
|
@@ -286,7 +331,7 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
286
331
|
content_str = json.dumps(result)
|
|
287
332
|
return content_str, image_data_urls
|
|
288
333
|
|
|
289
|
-
def _extract_content_items(self, result:
|
|
334
|
+
def _extract_content_items(self, result: dict[str, Any]) -> list[Any]:
|
|
290
335
|
"""Extract content array from MCP result (handles various response shapes)."""
|
|
291
336
|
if "content" in result and isinstance(result["content"], list):
|
|
292
337
|
return result["content"]
|
|
@@ -337,7 +382,7 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
337
382
|
|
|
338
383
|
return data_url, content_id
|
|
339
384
|
|
|
340
|
-
async def _call_mcp_tool_via_sdk(self, arguments:
|
|
385
|
+
async def _call_mcp_tool_via_sdk(self, arguments: dict[str, Any]) -> dict[str, Any]:
|
|
341
386
|
"""Call MCP tool via SDK to public API"""
|
|
342
387
|
try:
|
|
343
388
|
self.logger.info(
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
import tempfile
|
|
4
|
+
from mimetypes import guess_type
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import unique_sdk.utils.file_io as file_io
|
|
9
|
+
from openai.types.responses.response_output_text import AnnotationContainerFileCitation
|
|
10
|
+
from pydantic import BaseModel
|
|
11
|
+
|
|
12
|
+
from unique_toolkit import ChatService
|
|
13
|
+
from unique_toolkit._common.utils.files import FileMimeType, ImageMimeType
|
|
14
|
+
from unique_toolkit.agentic.tools.openai_builtin.code_interpreter.postprocessors.office_preview import (
|
|
15
|
+
OFFICE_PREVIEW_MIME_TYPES,
|
|
16
|
+
convert_office_bytes_to_preview_pdf,
|
|
17
|
+
office_extension,
|
|
18
|
+
)
|
|
19
|
+
from unique_toolkit.content.schemas import Content
|
|
20
|
+
|
|
21
|
+
_CODE_EXECUTION_ARTIFACT_METADATA_KEY: str = "codeExecutionArtifactMetadata"
|
|
22
|
+
|
|
23
|
+
_LOGGER = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CodeExecutionArtifactMetadata(BaseModel):
|
|
27
|
+
container_id: str
|
|
28
|
+
file_id: str
|
|
29
|
+
filepath: str
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _kb_safe_mime(mime: str) -> str:
|
|
33
|
+
"""Return a MIME type the Unique KB will accept.
|
|
34
|
+
|
|
35
|
+
Membership is defined by ``FileMimeType`` and ``ImageMimeType`` in
|
|
36
|
+
``unique_toolkit._common.utils.files`` (same catalog as path-based helpers
|
|
37
|
+
like ``FileMimeType.is_valid_mime``, but here we already have a resolved
|
|
38
|
+
MIME string from ``mimetypes.guess_type``, so we use StrEnum value lookup
|
|
39
|
+
instead of re-parsing a path).
|
|
40
|
+
|
|
41
|
+
The KB GraphQL API rejects many code-file MIME types (e.g. ``text/x-python``
|
|
42
|
+
for ``.py`` files). Anything not in those enums is coerced to
|
|
43
|
+
``text/plain`` so the file can be stored and downloaded without changing
|
|
44
|
+
its bytes.
|
|
45
|
+
|
|
46
|
+
Other ``image/*`` subtypes (e.g. ``image/jpg``) still pass through unchanged.
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
FileMimeType(mime)
|
|
50
|
+
return mime
|
|
51
|
+
except ValueError:
|
|
52
|
+
pass
|
|
53
|
+
try:
|
|
54
|
+
ImageMimeType(mime)
|
|
55
|
+
return mime
|
|
56
|
+
except ValueError:
|
|
57
|
+
pass
|
|
58
|
+
if mime.startswith("image/"):
|
|
59
|
+
return mime
|
|
60
|
+
return "text/plain"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _artifact_metadata(
|
|
64
|
+
file: AnnotationContainerFileCitation,
|
|
65
|
+
) -> dict[str, Any]:
|
|
66
|
+
return {
|
|
67
|
+
_CODE_EXECUTION_ARTIFACT_METADATA_KEY: CodeExecutionArtifactMetadata(
|
|
68
|
+
container_id=file.container_id,
|
|
69
|
+
file_id=file.file_id,
|
|
70
|
+
filepath=f"/mnt/data/{file.filename}",
|
|
71
|
+
).model_dump()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
async def _upload_artifact_bytes(
|
|
76
|
+
chat_service: ChatService,
|
|
77
|
+
file: AnnotationContainerFileCitation,
|
|
78
|
+
file_bytes: bytes,
|
|
79
|
+
mime: str,
|
|
80
|
+
) -> Content:
|
|
81
|
+
_LOGGER.info(
|
|
82
|
+
"Uploading '%s' to knowledge base (%d bytes, mime type %s)",
|
|
83
|
+
file.filename,
|
|
84
|
+
len(file_bytes),
|
|
85
|
+
mime,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
return await chat_service.upload_to_chat_from_bytes_async(
|
|
89
|
+
content=file_bytes,
|
|
90
|
+
content_name=file.filename,
|
|
91
|
+
mime_type=mime,
|
|
92
|
+
skip_ingestion=True,
|
|
93
|
+
hide_in_chat=True,
|
|
94
|
+
metadata=_artifact_metadata(file),
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
async def _upload_office_artifact_with_preview(
|
|
99
|
+
chat_service: ChatService,
|
|
100
|
+
file: AnnotationContainerFileCitation,
|
|
101
|
+
file_bytes: bytes,
|
|
102
|
+
mime: str,
|
|
103
|
+
) -> Content | None:
|
|
104
|
+
"""Upload an Office artifact with a PDF preview, or ``None`` to fall back."""
|
|
105
|
+
with tempfile.TemporaryDirectory(prefix="code-interpreter-preview-") as tmp:
|
|
106
|
+
output_dir = Path(tmp)
|
|
107
|
+
preview_path = await convert_office_bytes_to_preview_pdf(
|
|
108
|
+
filename=file.filename,
|
|
109
|
+
file_bytes=file_bytes,
|
|
110
|
+
tmp_dir=output_dir,
|
|
111
|
+
logger=_LOGGER,
|
|
112
|
+
)
|
|
113
|
+
if preview_path is None:
|
|
114
|
+
_LOGGER.warning(
|
|
115
|
+
"Code interpreter Office artifact '%s' could not be converted "
|
|
116
|
+
"to PDF; uploading without preview.",
|
|
117
|
+
file.filename,
|
|
118
|
+
)
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
source_path = output_dir / Path(file.filename).name
|
|
122
|
+
_LOGGER.info(
|
|
123
|
+
"Uploading code interpreter Office artifact '%s' with PDF preview '%s'",
|
|
124
|
+
file.filename,
|
|
125
|
+
preview_path.name,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
uploaded = await asyncio.to_thread(
|
|
129
|
+
file_io.upload_file,
|
|
130
|
+
chat_service._user_id,
|
|
131
|
+
chat_service._company_id,
|
|
132
|
+
str(source_path),
|
|
133
|
+
file.filename,
|
|
134
|
+
mime,
|
|
135
|
+
chat_id=chat_service._chat_id,
|
|
136
|
+
ingestion_config={
|
|
137
|
+
"uniqueIngestionMode": "SKIP_INGESTION",
|
|
138
|
+
"hideInChat": True,
|
|
139
|
+
},
|
|
140
|
+
metadata=_artifact_metadata(file),
|
|
141
|
+
preview_pdf_path=str(preview_path),
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
return Content.model_validate(uploaded, by_alias=True, by_name=True)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
async def save_code_execution_artifact(
|
|
148
|
+
chat_service: ChatService,
|
|
149
|
+
file: AnnotationContainerFileCitation,
|
|
150
|
+
file_bytes: bytes,
|
|
151
|
+
*,
|
|
152
|
+
attach_office_preview: bool = False,
|
|
153
|
+
) -> Content:
|
|
154
|
+
"""Upload a code-interpreter artifact to the chat knowledge base.
|
|
155
|
+
|
|
156
|
+
``attach_office_preview`` is opt-in (default ``False``) so existing
|
|
157
|
+
Unique AI callers keep the historical bytes-only upload. When ``True``,
|
|
158
|
+
Word / PowerPoint / Excel files are converted to a sibling PDF and
|
|
159
|
+
uploaded with ``preview_pdf_path``. Conversion is best-effort: if
|
|
160
|
+
LibreOffice is missing or conversion fails, the original bytes are
|
|
161
|
+
uploaded instead. Upload failures are not retried via the bytes path,
|
|
162
|
+
because ``file_io.upload_file`` may already have created a content row.
|
|
163
|
+
"""
|
|
164
|
+
if attach_office_preview:
|
|
165
|
+
extension = office_extension(file.filename)
|
|
166
|
+
if extension is not None:
|
|
167
|
+
mime = _kb_safe_mime(OFFICE_PREVIEW_MIME_TYPES[extension])
|
|
168
|
+
content = await _upload_office_artifact_with_preview(
|
|
169
|
+
chat_service=chat_service,
|
|
170
|
+
file=file,
|
|
171
|
+
file_bytes=file_bytes,
|
|
172
|
+
mime=mime,
|
|
173
|
+
)
|
|
174
|
+
if content is not None:
|
|
175
|
+
return content
|
|
176
|
+
return await _upload_artifact_bytes(
|
|
177
|
+
chat_service=chat_service,
|
|
178
|
+
file=file,
|
|
179
|
+
file_bytes=file_bytes,
|
|
180
|
+
mime=mime,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
raw_mime = guess_type(file.filename)[0] or "text/plain"
|
|
184
|
+
mime = _kb_safe_mime(raw_mime)
|
|
185
|
+
|
|
186
|
+
if mime != raw_mime:
|
|
187
|
+
_LOGGER.info(
|
|
188
|
+
"MIME type '%s' is not supported by the Unique KB; "
|
|
189
|
+
"uploading '%s' as 'text/plain' so the file can be stored and downloaded.",
|
|
190
|
+
raw_mime,
|
|
191
|
+
file.filename,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
return await _upload_artifact_bytes(
|
|
195
|
+
chat_service=chat_service,
|
|
196
|
+
file=file,
|
|
197
|
+
file_bytes=file_bytes,
|
|
198
|
+
mime=mime,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def load_code_execution_metadata(
|
|
203
|
+
content: Content,
|
|
204
|
+
) -> CodeExecutionArtifactMetadata | None:
|
|
205
|
+
if (
|
|
206
|
+
content.metadata is None
|
|
207
|
+
or _CODE_EXECUTION_ARTIFACT_METADATA_KEY not in content.metadata
|
|
208
|
+
):
|
|
209
|
+
return None
|
|
210
|
+
|
|
211
|
+
return CodeExecutionArtifactMetadata.model_validate(
|
|
212
|
+
content.metadata[_CODE_EXECUTION_ARTIFACT_METADATA_KEY]
|
|
213
|
+
)
|
|
@@ -117,6 +117,15 @@ class DisplayCodeInterpreterFilesPostProcessorConfig(BaseModel):
|
|
|
117
117
|
"Applies per SDK attempt. The OpenAI SDK default of 600s is too generous "
|
|
118
118
|
"for small generated files; a shorter timeout lets us retry sooner.",
|
|
119
119
|
)
|
|
120
|
+
attach_office_preview: SkipJsonSchema[bool] = Field(
|
|
121
|
+
default=False,
|
|
122
|
+
description=(
|
|
123
|
+
"When True, convert Word/PowerPoint/Excel artifacts to a sibling "
|
|
124
|
+
"PDF and attach it as the chat side-panel preview. Default False "
|
|
125
|
+
"keeps the historical bytes-only upload. Conversion is best-effort "
|
|
126
|
+
"and falls back to the original file."
|
|
127
|
+
),
|
|
128
|
+
)
|
|
120
129
|
|
|
121
130
|
|
|
122
131
|
class _ContentInfo(NamedTuple):
|
|
@@ -762,6 +771,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
762
771
|
chat_service=self._chat_service,
|
|
763
772
|
file=container_file,
|
|
764
773
|
file_bytes=file_bytes,
|
|
774
|
+
attach_office_preview=self._config.attach_office_preview,
|
|
765
775
|
)
|
|
766
776
|
upload_ms = (time.monotonic() - upload_t0) * 1000
|
|
767
777
|
if upload_ms > 2000:
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"""LibreOffice PDF previews for code-interpreter Office artifacts.
|
|
2
|
+
|
|
3
|
+
When the OpenAI code interpreter emits a Word, PowerPoint, or Excel file,
|
|
4
|
+
the chat UI can render a sibling PDF in the side panel far more reliably
|
|
5
|
+
than the Office binary. Conversion is best-effort: if ``soffice`` is
|
|
6
|
+
missing, times out, or rejects the file, callers upload the original
|
|
7
|
+
without a preview.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
import logging
|
|
14
|
+
import shutil
|
|
15
|
+
import subprocess
|
|
16
|
+
import tempfile
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
_SOFFICE_TIMEOUT_SECONDS = 180
|
|
20
|
+
|
|
21
|
+
# Canonical MIME types so slim containers without ``/etc/mime.types`` still
|
|
22
|
+
# upload Office files with a KB-accepted type instead of falling back to
|
|
23
|
+
# ``text/plain`` via ``mimetypes.guess_type``.
|
|
24
|
+
OFFICE_PREVIEW_MIME_TYPES: dict[str, str] = {
|
|
25
|
+
".doc": "application/msword",
|
|
26
|
+
".docx": (
|
|
27
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
28
|
+
),
|
|
29
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
30
|
+
".pptx": (
|
|
31
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
32
|
+
),
|
|
33
|
+
".xls": "application/vnd.ms-excel",
|
|
34
|
+
".xlsx": ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def office_extension(filename: str) -> str | None:
|
|
39
|
+
"""Return the lowercased Office suffix, or ``None`` if not previewable."""
|
|
40
|
+
suffix = Path(filename).suffix.lower()
|
|
41
|
+
return suffix if suffix in OFFICE_PREVIEW_MIME_TYPES else None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _resolve_soffice_binary() -> str | None:
|
|
45
|
+
return shutil.which("soffice") or shutil.which("libreoffice")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _run_soffice(
|
|
49
|
+
soffice: str,
|
|
50
|
+
source: Path,
|
|
51
|
+
output_dir: Path,
|
|
52
|
+
logger: logging.Logger,
|
|
53
|
+
) -> None:
|
|
54
|
+
"""Invoke headless ``soffice`` to convert *source* into *output_dir*.
|
|
55
|
+
|
|
56
|
+
Uses an isolated ``UserInstallation`` profile so concurrent LibreOffice
|
|
57
|
+
invocations do not collide on ``$HOME/.config/libreoffice``.
|
|
58
|
+
"""
|
|
59
|
+
with tempfile.TemporaryDirectory(
|
|
60
|
+
prefix=".libreoffice-profile-",
|
|
61
|
+
dir=output_dir,
|
|
62
|
+
) as profile_dir:
|
|
63
|
+
proc = subprocess.run(
|
|
64
|
+
[
|
|
65
|
+
soffice,
|
|
66
|
+
f"-env:UserInstallation={Path(profile_dir).resolve().as_uri()}",
|
|
67
|
+
"--headless",
|
|
68
|
+
"--convert-to",
|
|
69
|
+
"pdf",
|
|
70
|
+
"--outdir",
|
|
71
|
+
str(output_dir),
|
|
72
|
+
str(source),
|
|
73
|
+
],
|
|
74
|
+
capture_output=True,
|
|
75
|
+
text=True,
|
|
76
|
+
timeout=_SOFFICE_TIMEOUT_SECONDS,
|
|
77
|
+
)
|
|
78
|
+
if proc.returncode != 0:
|
|
79
|
+
logger.warning(
|
|
80
|
+
"office_preview: soffice exited %d for '%s' "
|
|
81
|
+
"(stdout=%d bytes, stderr=%d bytes)",
|
|
82
|
+
proc.returncode,
|
|
83
|
+
source.name,
|
|
84
|
+
len((proc.stdout or "").strip()),
|
|
85
|
+
len((proc.stderr or "").strip()),
|
|
86
|
+
)
|
|
87
|
+
raise subprocess.CalledProcessError(
|
|
88
|
+
proc.returncode, proc.args, proc.stdout, proc.stderr
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
async def convert_office_bytes_to_preview_pdf(
|
|
93
|
+
filename: str,
|
|
94
|
+
file_bytes: bytes,
|
|
95
|
+
tmp_dir: Path,
|
|
96
|
+
logger: logging.Logger,
|
|
97
|
+
) -> Path | None:
|
|
98
|
+
"""Write *file_bytes* into *tmp_dir* and convert to a sibling preview PDF.
|
|
99
|
+
|
|
100
|
+
The original file is written as ``tmp_dir / Path(filename).name`` so the
|
|
101
|
+
caller can pass that path to the SDK uploader. The preview is rendered
|
|
102
|
+
into ``tmp_dir / .previews / <stem>.pdf`` so it cannot collide with a
|
|
103
|
+
same-named PDF the interpreter also produced.
|
|
104
|
+
|
|
105
|
+
Returns the preview path, or ``None`` when conversion is unavailable or
|
|
106
|
+
fails. Never raises for expected conversion problems.
|
|
107
|
+
"""
|
|
108
|
+
safe_filename = Path(filename).name
|
|
109
|
+
source_path = tmp_dir / safe_filename
|
|
110
|
+
source_path.write_bytes(file_bytes)
|
|
111
|
+
|
|
112
|
+
soffice = _resolve_soffice_binary()
|
|
113
|
+
if soffice is None:
|
|
114
|
+
logger.warning(
|
|
115
|
+
"office_preview: soffice/libreoffice not found on PATH — "
|
|
116
|
+
"uploading '%s' without a PDF preview.",
|
|
117
|
+
safe_filename,
|
|
118
|
+
)
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
previews_dir = tmp_dir / ".previews"
|
|
122
|
+
previews_dir.mkdir(exist_ok=True)
|
|
123
|
+
target = previews_dir / f"{source_path.stem}.pdf"
|
|
124
|
+
|
|
125
|
+
try:
|
|
126
|
+
await asyncio.to_thread(
|
|
127
|
+
_run_soffice, soffice, source_path, previews_dir, logger
|
|
128
|
+
)
|
|
129
|
+
except subprocess.TimeoutExpired:
|
|
130
|
+
logger.warning(
|
|
131
|
+
"office_preview: soffice timed out after %ds for '%s' — "
|
|
132
|
+
"uploading original only",
|
|
133
|
+
_SOFFICE_TIMEOUT_SECONDS,
|
|
134
|
+
safe_filename,
|
|
135
|
+
)
|
|
136
|
+
return None
|
|
137
|
+
except subprocess.CalledProcessError:
|
|
138
|
+
return None
|
|
139
|
+
except Exception:
|
|
140
|
+
logger.exception(
|
|
141
|
+
"office_preview: unexpected error for '%s' — uploading original only",
|
|
142
|
+
safe_filename,
|
|
143
|
+
)
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
if target.is_file():
|
|
147
|
+
return target
|
|
148
|
+
|
|
149
|
+
logger.warning(
|
|
150
|
+
"office_preview: soffice returned 0 but '%s' is missing for '%s'",
|
|
151
|
+
target.name,
|
|
152
|
+
safe_filename,
|
|
153
|
+
)
|
|
154
|
+
return None
|
{unique_toolkit-2026.34.2 → unique_toolkit-2026.36.0}/unique_toolkit/agentic_table/__init__.py
RENAMED
|
@@ -14,6 +14,8 @@ from .schemas import (
|
|
|
14
14
|
AgreementStatus,
|
|
15
15
|
ArtifactType,
|
|
16
16
|
CreatedMagicTableSheet,
|
|
17
|
+
LibrarySheetRowVerifiedMetadata,
|
|
18
|
+
LibrarySheetRowVerifiedRow,
|
|
17
19
|
LogEntry,
|
|
18
20
|
MagicTableAction,
|
|
19
21
|
MagicTableAddMetadataPayload,
|
|
@@ -26,11 +28,13 @@ from .schemas import (
|
|
|
26
28
|
MagicTableGenerateArtifactPayload,
|
|
27
29
|
MagicTableLibrarySheetRowVerifiedPayload,
|
|
28
30
|
MagicTableRerunRowPayload,
|
|
31
|
+
MagicTableRerunRowsPayload,
|
|
29
32
|
MagicTableSheet,
|
|
30
33
|
MagicTableSheetCompletedPayload,
|
|
31
34
|
MagicTableSheetCreatedPayload,
|
|
32
35
|
MagicTableUpdateCellPayload,
|
|
33
36
|
RerunRowMetadata,
|
|
37
|
+
RerunRowsMetadata,
|
|
34
38
|
RowMetadataEntry,
|
|
35
39
|
RowMetadataEntryInput,
|
|
36
40
|
SelectionMethod,
|
|
@@ -74,11 +78,15 @@ __all__ = [
|
|
|
74
78
|
"MagicTableGenerateArtifactPayload",
|
|
75
79
|
"MagicTableLibrarySheetRowVerifiedPayload",
|
|
76
80
|
"MagicTableRerunRowPayload",
|
|
81
|
+
"MagicTableRerunRowsPayload",
|
|
77
82
|
"MagicTableSheet",
|
|
78
83
|
"MagicTableSheetCompletedPayload",
|
|
79
84
|
"MagicTableSheetCreatedPayload",
|
|
80
85
|
"MagicTableUpdateCellPayload",
|
|
86
|
+
"LibrarySheetRowVerifiedMetadata",
|
|
87
|
+
"LibrarySheetRowVerifiedRow",
|
|
81
88
|
"RerunRowMetadata",
|
|
89
|
+
"RerunRowsMetadata",
|
|
82
90
|
"RowMetadataEntry",
|
|
83
91
|
"RowMetadataEntryInput",
|
|
84
92
|
"RowVerificationStatus",
|