unique_toolkit 1.68.9__tar.gz → 1.68.11__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-1.68.9 → unique_toolkit-1.68.11}/PKG-INFO +1 -1
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/pyproject.toml +1 -1
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +410 -33
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/README.md +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/_base_service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/_time_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/README.md +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/__main__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/cli.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/differ.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/exporter.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/models.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/registry.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/validator.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/default_language_model.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/endpoint_builder.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/endpoint_requestor.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/event_bus.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/exception.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/execution.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/feature_flags/schema.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/pydantic_helpers.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/referencing.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/string_utilities.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/tests/test_referencing.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/image_token_counting.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/token_counting.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/files.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/image/encode.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/jinja/render.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/write_configuration.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/validate_required_values.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/validators.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/exception.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/history_manager/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/base.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/open_file_tool/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/open_file_tool/tool.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/factory.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/tool.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic_table/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic_table/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic_table/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/dev_util.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/fast_api_factory.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/init_logging.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/init_sdk.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/performance/async_tasks.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/performance/async_wrapper.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/unique_settings.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/verification.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/webhook.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/cancellation.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/constants.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/deprecated/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/functions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/rendering.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/responses_api.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/state.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/constants.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/functions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/smart_rules.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/README.md +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/augmented/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/base.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/basic/config.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/basic/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/constants.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/exceptions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/functions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/constants.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/functions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/openai/client.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/builder.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/constants.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/default_language_model.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/functions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/infos.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/prompt.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/reference.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/stream_transform.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/utils.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/protocols/support.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/services/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/services/chat_service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/services/factory.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/services/knowledge_base.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/constants.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/functions.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/schemas.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/service.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/smart_rules/__init__.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/smart_rules/compile.py +0 -0
- {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/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: 1.68.
|
|
3
|
+
Version: 1.68.11
|
|
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>
|
|
@@ -2,6 +2,8 @@ import asyncio
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
import re
|
|
5
|
+
import time
|
|
6
|
+
from dataclasses import dataclass
|
|
5
7
|
from mimetypes import guess_type
|
|
6
8
|
from typing import NamedTuple, override
|
|
7
9
|
|
|
@@ -41,6 +43,14 @@ from unique_toolkit.short_term_memory.service import ShortTermMemoryService
|
|
|
41
43
|
logger = logging.getLogger(__name__)
|
|
42
44
|
|
|
43
45
|
|
|
46
|
+
class _ChatLoggerAdapter(logging.LoggerAdapter[logging.Logger]):
|
|
47
|
+
"""LoggerAdapter that prefixes every message with ``[chat_id=…]``."""
|
|
48
|
+
|
|
49
|
+
def process(self, msg: str, kwargs): # type: ignore[override]
|
|
50
|
+
extra = dict(self.extra) if self.extra else {} # type: ignore[arg-type]
|
|
51
|
+
return f"[chat_id={extra.get('chat_id', 'n/a')}] {msg}", kwargs
|
|
52
|
+
|
|
53
|
+
|
|
44
54
|
class DisplayCodeInterpreterFilesPostProcessorConfig(BaseModel):
|
|
45
55
|
model_config = get_configuration_dict()
|
|
46
56
|
upload_to_chat: SkipJsonSchema[bool] = Field(
|
|
@@ -53,8 +63,8 @@ class DisplayCodeInterpreterFilesPostProcessorConfig(BaseModel):
|
|
|
53
63
|
)
|
|
54
64
|
|
|
55
65
|
file_download_failed_message: str = Field(
|
|
56
|
-
default="⚠️ File
|
|
57
|
-
description="The message to display when a file download fails.",
|
|
66
|
+
default="⚠️ File could not be generated. Please try again.",
|
|
67
|
+
description="The message to display when a file download fails after all retry attempts.",
|
|
58
68
|
)
|
|
59
69
|
max_concurrent_file_downloads: int = Field(
|
|
60
70
|
default=10,
|
|
@@ -68,6 +78,14 @@ class DisplayCodeInterpreterFilesPostProcessorConfig(BaseModel):
|
|
|
68
78
|
default=0.5,
|
|
69
79
|
description="Base delay in seconds for exponential backoff between download/upload retries.",
|
|
70
80
|
)
|
|
81
|
+
progress_update_interval: float = Field(
|
|
82
|
+
default=3.0,
|
|
83
|
+
description="Minimum seconds between progress message updates sent to the user.",
|
|
84
|
+
)
|
|
85
|
+
download_chunk_size: int = Field(
|
|
86
|
+
default=8192,
|
|
87
|
+
description="Chunk size in bytes for streaming container file downloads.",
|
|
88
|
+
)
|
|
71
89
|
|
|
72
90
|
|
|
73
91
|
class _ContentInfo(NamedTuple):
|
|
@@ -95,6 +113,141 @@ def _init_short_term_memory_manager(
|
|
|
95
113
|
)
|
|
96
114
|
|
|
97
115
|
|
|
116
|
+
@dataclass
|
|
117
|
+
class _FileState:
|
|
118
|
+
phase: str = "pending"
|
|
119
|
+
percent: int | None = None
|
|
120
|
+
elapsed_seconds: float = 0.0
|
|
121
|
+
retry_attempt: int = 0
|
|
122
|
+
max_retries: int = 0
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class _FileProgressTracker:
|
|
126
|
+
"""Concurrency-safe coordinator that publishes file download/upload progress
|
|
127
|
+
to the user-visible assistant message in real time.
|
|
128
|
+
|
|
129
|
+
Replaces sandbox links inline with progress text and appends a summary block.
|
|
130
|
+
Throttles ``modify_assistant_message_async`` calls to avoid API spam.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
def __init__(
|
|
134
|
+
self,
|
|
135
|
+
filenames: list[str],
|
|
136
|
+
original_text: str,
|
|
137
|
+
chat_service: ChatService,
|
|
138
|
+
log: logging.LoggerAdapter[logging.Logger],
|
|
139
|
+
min_publish_interval: float = 3.0,
|
|
140
|
+
) -> None:
|
|
141
|
+
self._states: dict[str, _FileState] = {f: _FileState() for f in filenames}
|
|
142
|
+
self._original_text = original_text
|
|
143
|
+
self._chat_service = chat_service
|
|
144
|
+
self._log = log
|
|
145
|
+
self._lock = asyncio.Lock()
|
|
146
|
+
self._last_publish_time = 0.0
|
|
147
|
+
self._min_interval = min_publish_interval
|
|
148
|
+
|
|
149
|
+
async def update(
|
|
150
|
+
self,
|
|
151
|
+
filename: str,
|
|
152
|
+
phase: str,
|
|
153
|
+
*,
|
|
154
|
+
percent: int | None = None,
|
|
155
|
+
elapsed_seconds: float = 0.0,
|
|
156
|
+
retry_attempt: int = 0,
|
|
157
|
+
max_retries: int = 0,
|
|
158
|
+
force_publish: bool = False,
|
|
159
|
+
) -> None:
|
|
160
|
+
async with self._lock:
|
|
161
|
+
state = self._states.get(filename)
|
|
162
|
+
if state is None:
|
|
163
|
+
return
|
|
164
|
+
state.phase = phase
|
|
165
|
+
state.percent = percent
|
|
166
|
+
state.elapsed_seconds = elapsed_seconds
|
|
167
|
+
state.retry_attempt = retry_attempt
|
|
168
|
+
state.max_retries = max_retries
|
|
169
|
+
|
|
170
|
+
now = time.monotonic()
|
|
171
|
+
should_publish = (
|
|
172
|
+
force_publish
|
|
173
|
+
or phase in ("done", "failed", "uploading")
|
|
174
|
+
or now - self._last_publish_time >= self._min_interval
|
|
175
|
+
)
|
|
176
|
+
if should_publish:
|
|
177
|
+
await self._publish()
|
|
178
|
+
self._last_publish_time = now
|
|
179
|
+
|
|
180
|
+
async def publish_initial(self) -> None:
|
|
181
|
+
"""Send the first progress update (marks all files as pending)."""
|
|
182
|
+
async with self._lock:
|
|
183
|
+
for state in self._states.values():
|
|
184
|
+
state.phase = "downloading"
|
|
185
|
+
await self._publish()
|
|
186
|
+
self._last_publish_time = time.monotonic()
|
|
187
|
+
|
|
188
|
+
async def _publish(self) -> None:
|
|
189
|
+
text = self._build_progress_text()
|
|
190
|
+
try:
|
|
191
|
+
await self._chat_service.modify_assistant_message_async(content=text)
|
|
192
|
+
except Exception:
|
|
193
|
+
self._log.debug("Failed to publish progress update", exc_info=True)
|
|
194
|
+
|
|
195
|
+
def _build_progress_text(self) -> str:
|
|
196
|
+
text = self._original_text
|
|
197
|
+
|
|
198
|
+
for filename, state in self._states.items():
|
|
199
|
+
if state.phase == "pending":
|
|
200
|
+
continue
|
|
201
|
+
progress = self._format_inline(filename, state)
|
|
202
|
+
pattern = rf"!?\[.*?\]\(sandbox:/mnt/data/{re.escape(filename)}\)"
|
|
203
|
+
text = re.sub(pattern, progress, text)
|
|
204
|
+
|
|
205
|
+
active = {
|
|
206
|
+
f: s for f, s in self._states.items() if s.phase not in ("done", "pending")
|
|
207
|
+
}
|
|
208
|
+
if active:
|
|
209
|
+
lines = ["---", "Preparing files:"]
|
|
210
|
+
for filename, state in active.items():
|
|
211
|
+
lines.append(f"- {filename} — {self._format_summary(state)}")
|
|
212
|
+
text = text.rstrip() + "\n\n" + "\n".join(lines)
|
|
213
|
+
|
|
214
|
+
return text
|
|
215
|
+
|
|
216
|
+
@staticmethod
|
|
217
|
+
def _format_inline(filename: str, state: _FileState) -> str:
|
|
218
|
+
if state.phase == "downloading":
|
|
219
|
+
base = f"Downloading {filename}..."
|
|
220
|
+
if state.retry_attempt > 0:
|
|
221
|
+
base += f" retry {state.retry_attempt}/{state.max_retries}"
|
|
222
|
+
if state.percent is not None:
|
|
223
|
+
return f"{base} {state.percent}%"
|
|
224
|
+
if state.elapsed_seconds > 0:
|
|
225
|
+
return f"{base} ({int(state.elapsed_seconds)}s)"
|
|
226
|
+
return base
|
|
227
|
+
if state.phase == "uploading":
|
|
228
|
+
return f"Uploading {filename}..."
|
|
229
|
+
if state.phase == "failed":
|
|
230
|
+
return "File could not be generated. Please try again."
|
|
231
|
+
return filename
|
|
232
|
+
|
|
233
|
+
@staticmethod
|
|
234
|
+
def _format_summary(state: _FileState) -> str:
|
|
235
|
+
if state.phase == "downloading":
|
|
236
|
+
base = "Downloading"
|
|
237
|
+
if state.retry_attempt > 0:
|
|
238
|
+
base += f" (retry {state.retry_attempt}/{state.max_retries})"
|
|
239
|
+
if state.percent is not None:
|
|
240
|
+
return f"{base} {state.percent}%"
|
|
241
|
+
if state.elapsed_seconds > 0:
|
|
242
|
+
return f"{base} ({int(state.elapsed_seconds)}s)"
|
|
243
|
+
return f"{base}..."
|
|
244
|
+
if state.phase == "uploading":
|
|
245
|
+
return "Uploading..."
|
|
246
|
+
if state.phase == "failed":
|
|
247
|
+
return "Failed"
|
|
248
|
+
return "Pending"
|
|
249
|
+
|
|
250
|
+
|
|
98
251
|
class DisplayCodeInterpreterFilesPostProcessor(
|
|
99
252
|
ResponsesApiPostprocessor,
|
|
100
253
|
):
|
|
@@ -122,6 +275,10 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
122
275
|
if self._chat_service is None:
|
|
123
276
|
raise ValueError("ChatService is required if uploadToChat is True")
|
|
124
277
|
|
|
278
|
+
self._log: logging.LoggerAdapter[logging.Logger] = _ChatLoggerAdapter(
|
|
279
|
+
logger, {"chat_id": chat_id or "n/a"}
|
|
280
|
+
)
|
|
281
|
+
|
|
125
282
|
self._orphan_code_blocks: list[CodeInterpreterBlock] = []
|
|
126
283
|
self._short_term_memory_manager = None
|
|
127
284
|
if chat_id is not None and user_id is not None and company_id is not None:
|
|
@@ -140,40 +297,73 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
140
297
|
return AsyncRetrying(
|
|
141
298
|
stop=stop_after_attempt(1 + self._config.max_download_retries),
|
|
142
299
|
wait=wait_exponential(multiplier=self._config.download_retry_base_delay),
|
|
143
|
-
before_sleep=before_sleep_log(
|
|
300
|
+
before_sleep=before_sleep_log(self._log, logging.WARNING), # type: ignore[arg-type]
|
|
144
301
|
reraise=True,
|
|
145
302
|
)
|
|
146
303
|
|
|
147
304
|
@override
|
|
148
305
|
async def run(self, loop_response: ResponsesLanguageModelStreamResponse) -> None:
|
|
149
|
-
|
|
306
|
+
self._log.info("run() started — fetching and uploading code interpreter files")
|
|
150
307
|
|
|
151
308
|
container_files = loop_response.container_files
|
|
152
|
-
|
|
309
|
+
self._log.info(
|
|
310
|
+
"run() found %d container file annotation(s): %s",
|
|
311
|
+
len(container_files),
|
|
312
|
+
[cf.filename for cf in container_files],
|
|
313
|
+
)
|
|
153
314
|
|
|
154
315
|
try:
|
|
155
316
|
self._content_map: dict[str, str | None] = await self._load_previous_files() # type: ignore
|
|
317
|
+
if self._content_map:
|
|
318
|
+
self._log.info(
|
|
319
|
+
"run() loaded %d previous file(s) from short-term memory: %s",
|
|
320
|
+
len(self._content_map),
|
|
321
|
+
list(self._content_map.keys()),
|
|
322
|
+
)
|
|
156
323
|
except Exception:
|
|
157
|
-
|
|
158
|
-
"
|
|
159
|
-
"
|
|
324
|
+
self._log.exception(
|
|
325
|
+
"run() failed to load previous files from short-term memory; "
|
|
326
|
+
"proceeding without previous file context."
|
|
160
327
|
)
|
|
161
328
|
self._content_map = {}
|
|
162
329
|
|
|
330
|
+
tracker: _FileProgressTracker | None = None
|
|
331
|
+
if container_files and self._chat_service is not None:
|
|
332
|
+
tracker = _FileProgressTracker(
|
|
333
|
+
filenames=[cf.filename for cf in container_files],
|
|
334
|
+
original_text=loop_response.message.text or "",
|
|
335
|
+
chat_service=self._chat_service,
|
|
336
|
+
log=self._log,
|
|
337
|
+
min_publish_interval=self._config.progress_update_interval,
|
|
338
|
+
)
|
|
339
|
+
await tracker.publish_initial()
|
|
340
|
+
|
|
163
341
|
semaphore = asyncio.Semaphore(self._config.max_concurrent_file_downloads)
|
|
164
342
|
tasks = [
|
|
165
343
|
self._download_and_upload_container_files_to_knowledge_base(
|
|
166
|
-
citation, semaphore
|
|
344
|
+
citation, semaphore, tracker
|
|
167
345
|
)
|
|
168
346
|
for citation in container_files
|
|
169
347
|
]
|
|
170
348
|
results = await asyncio.gather(*tasks)
|
|
171
349
|
|
|
172
350
|
for citation, result in zip(container_files, results):
|
|
173
|
-
# Overwrite if file has been re-generated
|
|
174
351
|
self._content_map[citation.filename] = (
|
|
175
352
|
result.content_id if result is not None else None
|
|
176
353
|
)
|
|
354
|
+
if result is None and tracker:
|
|
355
|
+
await tracker.update(citation.filename, "failed", force_publish=True)
|
|
356
|
+
|
|
357
|
+
succeeded = {f: cid for f, cid in self._content_map.items() if cid is not None}
|
|
358
|
+
failed = [f for f, cid in self._content_map.items() if cid is None]
|
|
359
|
+
self._log.info(
|
|
360
|
+
"run() download/upload complete — %d succeeded, %d failed. "
|
|
361
|
+
"succeeded=%s, failed=%s",
|
|
362
|
+
len(succeeded),
|
|
363
|
+
len(failed),
|
|
364
|
+
list(succeeded.keys()),
|
|
365
|
+
failed,
|
|
366
|
+
)
|
|
177
367
|
|
|
178
368
|
try:
|
|
179
369
|
await self._save_generated_files(
|
|
@@ -184,9 +374,9 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
184
374
|
]
|
|
185
375
|
)
|
|
186
376
|
except Exception:
|
|
187
|
-
|
|
188
|
-
"
|
|
189
|
-
"
|
|
377
|
+
self._log.exception(
|
|
378
|
+
"run() failed to save generated files to short-term memory; "
|
|
379
|
+
"file replacement will still proceed."
|
|
190
380
|
)
|
|
191
381
|
|
|
192
382
|
try:
|
|
@@ -196,19 +386,39 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
196
386
|
self._orphan_code_blocks = await self._upload_orphan_code_as_txt(
|
|
197
387
|
loop_response
|
|
198
388
|
)
|
|
389
|
+
if self._orphan_code_blocks:
|
|
390
|
+
self._log.info(
|
|
391
|
+
"run() produced %d orphan code block(s)",
|
|
392
|
+
len(self._orphan_code_blocks),
|
|
393
|
+
)
|
|
199
394
|
else:
|
|
200
395
|
self._orphan_code_blocks = []
|
|
201
396
|
except Exception:
|
|
202
|
-
|
|
203
|
-
"
|
|
397
|
+
self._log.exception(
|
|
398
|
+
"run() failed to process orphan code blocks; "
|
|
204
399
|
"file replacement will still proceed."
|
|
205
400
|
)
|
|
206
401
|
self._orphan_code_blocks = []
|
|
207
402
|
|
|
403
|
+
self._log.info(
|
|
404
|
+
"run() finished — content_map has %d entries (%d with content_id, %d failed)",
|
|
405
|
+
len(self._content_map),
|
|
406
|
+
len(succeeded),
|
|
407
|
+
len(failed),
|
|
408
|
+
)
|
|
409
|
+
|
|
208
410
|
@override
|
|
209
411
|
def apply_postprocessing_to_response(
|
|
210
412
|
self, loop_response: ResponsesLanguageModelStreamResponse
|
|
211
413
|
) -> bool:
|
|
414
|
+
self._log.info(
|
|
415
|
+
"apply_postprocessing started — %d file(s) in content_map, fence_ff=%s",
|
|
416
|
+
len(self._content_map),
|
|
417
|
+
feature_flags.enable_code_execution_fence_un_17972.is_enabled(
|
|
418
|
+
self._company_id
|
|
419
|
+
),
|
|
420
|
+
)
|
|
421
|
+
|
|
212
422
|
if loop_response.message.references is None:
|
|
213
423
|
loop_response.message.references = []
|
|
214
424
|
if loop_response.message.text is None:
|
|
@@ -220,6 +430,10 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
220
430
|
self._company_id
|
|
221
431
|
)
|
|
222
432
|
|
|
433
|
+
replaced_files: list[str] = []
|
|
434
|
+
missed_files: list[str] = []
|
|
435
|
+
error_files: list[str] = []
|
|
436
|
+
|
|
223
437
|
for filename, content_id in self._content_map.items():
|
|
224
438
|
if content_id is None:
|
|
225
439
|
loop_response.message.text, replaced = _replace_container_file_error(
|
|
@@ -228,12 +442,14 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
228
442
|
error_message=self._config.file_download_failed_message,
|
|
229
443
|
)
|
|
230
444
|
changed |= replaced
|
|
445
|
+
error_files.append(filename)
|
|
231
446
|
continue
|
|
232
447
|
|
|
233
|
-
|
|
234
|
-
|
|
448
|
+
mime = guess_type(filename)[0] or ""
|
|
449
|
+
is_image = mime.startswith("image/")
|
|
450
|
+
is_html = mime == "text/html"
|
|
451
|
+
file_type = "image" if is_image else ("html" if is_html else "document")
|
|
235
452
|
|
|
236
|
-
# Images
|
|
237
453
|
if is_image:
|
|
238
454
|
loop_response.message.text, replaced = (
|
|
239
455
|
_replace_container_image_citation(
|
|
@@ -262,6 +478,17 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
262
478
|
)
|
|
263
479
|
changed |= replaced
|
|
264
480
|
|
|
481
|
+
if replaced:
|
|
482
|
+
replaced_files.append(filename)
|
|
483
|
+
self._log.info(
|
|
484
|
+
"Replaced sandbox link for '%s' (type=%s, content_id=%s)",
|
|
485
|
+
filename,
|
|
486
|
+
file_type,
|
|
487
|
+
content_id,
|
|
488
|
+
)
|
|
489
|
+
else:
|
|
490
|
+
missed_files.append(filename)
|
|
491
|
+
|
|
265
492
|
is_html_rendered = is_html
|
|
266
493
|
if replaced and not (is_image or is_html_rendered or fence_ff_on):
|
|
267
494
|
loop_response.message.references.append(
|
|
@@ -275,15 +502,30 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
275
502
|
)
|
|
276
503
|
ref_number += 1
|
|
277
504
|
|
|
505
|
+
self._log.info(
|
|
506
|
+
"Stage-1 replacement summary — replaced=%s, missed=%s, error=%s",
|
|
507
|
+
replaced_files,
|
|
508
|
+
missed_files,
|
|
509
|
+
error_files,
|
|
510
|
+
)
|
|
511
|
+
|
|
278
512
|
if fence_ff_on:
|
|
279
513
|
code_blocks = _build_code_blocks(loop_response, self._content_map)
|
|
514
|
+
self._log.info(
|
|
515
|
+
"Fence injection — %d code block(s), files: %s",
|
|
516
|
+
len(code_blocks),
|
|
517
|
+
[f.filename for b in code_blocks for f in b.files],
|
|
518
|
+
)
|
|
280
519
|
_warn_unmatched_code_blocks(self._content_map, code_blocks)
|
|
281
520
|
text_before = loop_response.message.text
|
|
282
521
|
loop_response.message.text = _inject_code_execution_fences(
|
|
283
522
|
loop_response.message.text,
|
|
284
523
|
code_blocks,
|
|
285
524
|
)
|
|
286
|
-
|
|
525
|
+
fences_changed = loop_response.message.text != text_before
|
|
526
|
+
changed |= fences_changed
|
|
527
|
+
if fences_changed:
|
|
528
|
+
self._log.info("Fence injection modified the message text")
|
|
287
529
|
|
|
288
530
|
if self._orphan_code_blocks:
|
|
289
531
|
fence_id = _get_next_fence_id(loop_response.message.text)
|
|
@@ -292,12 +534,29 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
292
534
|
loop_response.message.text.rstrip() + "\n\n" + orphan_fences
|
|
293
535
|
)
|
|
294
536
|
changed = True
|
|
537
|
+
self._log.info(
|
|
538
|
+
"Appended %d orphan fence(s)", len(self._orphan_code_blocks)
|
|
539
|
+
)
|
|
295
540
|
|
|
296
541
|
_warn_missing_content_ids(loop_response.message.text, self._content_map)
|
|
297
542
|
loop_response.message.text, dangling_replaced = _replace_dangling_sandbox_links(
|
|
298
543
|
loop_response.message.text, self._config.file_download_failed_message
|
|
299
544
|
)
|
|
300
545
|
changed |= dangling_replaced
|
|
546
|
+
if dangling_replaced:
|
|
547
|
+
self._log.warning(
|
|
548
|
+
"apply_postprocessing found and replaced dangling sandbox links"
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
self._log.info(
|
|
552
|
+
"apply_postprocessing finished — changed=%s, replaced=%d, missed=%d, "
|
|
553
|
+
"error=%d, dangling_cleaned=%s",
|
|
554
|
+
changed,
|
|
555
|
+
len(replaced_files),
|
|
556
|
+
len(missed_files),
|
|
557
|
+
len(error_files),
|
|
558
|
+
dangling_replaced,
|
|
559
|
+
)
|
|
301
560
|
|
|
302
561
|
return changed
|
|
303
562
|
|
|
@@ -310,48 +569,166 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
310
569
|
self,
|
|
311
570
|
container_file: AnnotationContainerFileCitation,
|
|
312
571
|
semaphore: asyncio.Semaphore,
|
|
572
|
+
tracker: _FileProgressTracker | None = None,
|
|
313
573
|
) -> _ContentInfo | None:
|
|
314
574
|
async with semaphore:
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
575
|
+
self._log.info(
|
|
576
|
+
"Downloading container file '%s' (container=%s, file_id=%s)",
|
|
577
|
+
container_file.filename,
|
|
578
|
+
container_file.container_id,
|
|
579
|
+
container_file.file_id,
|
|
320
580
|
)
|
|
321
581
|
|
|
322
|
-
|
|
323
|
-
|
|
582
|
+
file_bytes = await self._download_file_bytes_with_progress(
|
|
583
|
+
container_file, tracker
|
|
584
|
+
)
|
|
585
|
+
|
|
586
|
+
self._log.info(
|
|
587
|
+
"Downloaded container file '%s' (%d bytes)",
|
|
324
588
|
container_file.filename,
|
|
589
|
+
len(file_bytes),
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
if tracker:
|
|
593
|
+
await tracker.update(
|
|
594
|
+
container_file.filename, "uploading", force_publish=True
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
mime = guess_type(container_file.filename)[0] or "text/plain"
|
|
598
|
+
self._log.info(
|
|
599
|
+
"Uploading '%s' to knowledge base (mime=%s)",
|
|
600
|
+
container_file.filename,
|
|
601
|
+
mime,
|
|
325
602
|
)
|
|
326
603
|
|
|
327
604
|
assert self._chat_service is not None # Checked in __init__
|
|
328
605
|
content = await self._build_retry()(
|
|
329
606
|
self._chat_service.upload_to_chat_from_bytes_async,
|
|
330
|
-
content=
|
|
607
|
+
content=file_bytes,
|
|
331
608
|
content_name=container_file.filename,
|
|
332
|
-
mime_type=
|
|
609
|
+
mime_type=mime,
|
|
333
610
|
skip_ingestion=True,
|
|
334
611
|
hide_in_chat=True,
|
|
335
612
|
)
|
|
336
613
|
|
|
614
|
+
if tracker:
|
|
615
|
+
await tracker.update(
|
|
616
|
+
container_file.filename, "done", force_publish=True
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
self._log.info(
|
|
620
|
+
"Uploaded '%s' — content_id=%s",
|
|
621
|
+
container_file.filename,
|
|
622
|
+
content.id,
|
|
623
|
+
)
|
|
337
624
|
return _ContentInfo(filename=container_file.filename, content_id=content.id)
|
|
338
625
|
|
|
626
|
+
async def _download_file_bytes_with_progress(
|
|
627
|
+
self,
|
|
628
|
+
container_file: AnnotationContainerFileCitation,
|
|
629
|
+
tracker: _FileProgressTracker | None,
|
|
630
|
+
) -> bytes:
|
|
631
|
+
"""Download container file with streaming progress and manual retry loop.
|
|
632
|
+
|
|
633
|
+
Uses ``with_streaming_response`` so we can read ``content-length``
|
|
634
|
+
and report download percentage. Falls back to elapsed-time display
|
|
635
|
+
when the header is absent.
|
|
636
|
+
"""
|
|
637
|
+
max_attempts = 1 + self._config.max_download_retries
|
|
638
|
+
download_start = time.monotonic()
|
|
639
|
+
last_exception: Exception | None = None
|
|
640
|
+
|
|
641
|
+
for attempt_num in range(1, max_attempts + 1):
|
|
642
|
+
retry_num = attempt_num - 1
|
|
643
|
+
try:
|
|
644
|
+
if retry_num > 0:
|
|
645
|
+
delay = self._config.download_retry_base_delay * (2**retry_num)
|
|
646
|
+
self._log.warning(
|
|
647
|
+
"Retrying download of '%s' (attempt %d/%d) after %.1fs",
|
|
648
|
+
container_file.filename,
|
|
649
|
+
attempt_num,
|
|
650
|
+
max_attempts,
|
|
651
|
+
delay,
|
|
652
|
+
)
|
|
653
|
+
if tracker:
|
|
654
|
+
await tracker.update(
|
|
655
|
+
container_file.filename,
|
|
656
|
+
"downloading",
|
|
657
|
+
elapsed_seconds=time.monotonic() - download_start,
|
|
658
|
+
retry_attempt=retry_num,
|
|
659
|
+
max_retries=self._config.max_download_retries,
|
|
660
|
+
force_publish=True,
|
|
661
|
+
)
|
|
662
|
+
await asyncio.sleep(delay)
|
|
663
|
+
|
|
664
|
+
return await self._stream_download_bytes(
|
|
665
|
+
container_file, tracker, retry_num, download_start
|
|
666
|
+
)
|
|
667
|
+
except Exception as exc:
|
|
668
|
+
last_exception = exc
|
|
669
|
+
self._log.warning(
|
|
670
|
+
"Download attempt %d/%d failed for '%s': %s",
|
|
671
|
+
attempt_num,
|
|
672
|
+
max_attempts,
|
|
673
|
+
container_file.filename,
|
|
674
|
+
exc,
|
|
675
|
+
)
|
|
676
|
+
|
|
677
|
+
assert last_exception is not None
|
|
678
|
+
raise last_exception
|
|
679
|
+
|
|
680
|
+
async def _stream_download_bytes(
|
|
681
|
+
self,
|
|
682
|
+
container_file: AnnotationContainerFileCitation,
|
|
683
|
+
tracker: _FileProgressTracker | None,
|
|
684
|
+
retry_attempt: int,
|
|
685
|
+
download_start: float,
|
|
686
|
+
) -> bytes:
|
|
687
|
+
"""Stream-download a single container file, reporting chunk-level progress."""
|
|
688
|
+
async with (
|
|
689
|
+
self._client.containers.files.content.with_streaming_response.retrieve(
|
|
690
|
+
file_id=container_file.file_id,
|
|
691
|
+
container_id=container_file.container_id,
|
|
692
|
+
) as response
|
|
693
|
+
):
|
|
694
|
+
content_length = response.headers.get("content-length")
|
|
695
|
+
total = int(content_length) if content_length else None
|
|
696
|
+
chunks: list[bytes] = []
|
|
697
|
+
downloaded = 0
|
|
698
|
+
async for chunk in response.iter_bytes(
|
|
699
|
+
chunk_size=self._config.download_chunk_size
|
|
700
|
+
):
|
|
701
|
+
chunks.append(chunk)
|
|
702
|
+
downloaded += len(chunk)
|
|
703
|
+
if tracker:
|
|
704
|
+
pct = (downloaded * 100 // total) if total else None
|
|
705
|
+
elapsed = time.monotonic() - download_start
|
|
706
|
+
await tracker.update(
|
|
707
|
+
container_file.filename,
|
|
708
|
+
"downloading",
|
|
709
|
+
percent=pct,
|
|
710
|
+
elapsed_seconds=elapsed,
|
|
711
|
+
retry_attempt=retry_attempt,
|
|
712
|
+
max_retries=self._config.max_download_retries,
|
|
713
|
+
)
|
|
714
|
+
return b"".join(chunks)
|
|
715
|
+
|
|
339
716
|
async def _load_previous_files(self) -> dict[str, str]:
|
|
340
717
|
if self._short_term_memory_manager is None:
|
|
341
718
|
return {}
|
|
342
719
|
|
|
343
|
-
|
|
720
|
+
self._log.info(
|
|
344
721
|
"Loading previously generated code interpreter files from short term memory"
|
|
345
722
|
)
|
|
346
723
|
memory = await self._short_term_memory_manager.load_async()
|
|
347
724
|
|
|
348
725
|
if memory is None:
|
|
349
|
-
|
|
726
|
+
self._log.info(
|
|
350
727
|
"No previously generated code interpreter files found in short term memory"
|
|
351
728
|
)
|
|
352
729
|
return {}
|
|
353
730
|
|
|
354
|
-
|
|
731
|
+
self._log.info(
|
|
355
732
|
"Found %s previously generated code interpreter files", len(memory.root)
|
|
356
733
|
)
|
|
357
734
|
|
|
@@ -414,7 +791,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
414
791
|
hide_in_chat=True,
|
|
415
792
|
)
|
|
416
793
|
except Exception:
|
|
417
|
-
|
|
794
|
+
self._log.exception(
|
|
418
795
|
"Failed to upload orphan code block as txt for call %d ('%s'); "
|
|
419
796
|
"falling back to legacy code block display.",
|
|
420
797
|
i,
|
|
@@ -430,7 +807,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
430
807
|
orphan_blocks.append(
|
|
431
808
|
CodeInterpreterBlock(code=call.code, files=[orphan_file])
|
|
432
809
|
)
|
|
433
|
-
|
|
810
|
+
self._log.info(
|
|
434
811
|
"Uploaded orphan code block as '%s' (content_id=%s)",
|
|
435
812
|
filename,
|
|
436
813
|
content.id,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/base_model_type_attribute.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|