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.
Files changed (294) hide show
  1. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/PKG-INFO +1 -1
  2. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/pyproject.toml +1 -1
  3. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +410 -33
  4. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/README.md +0 -0
  5. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/__init__.py +0 -0
  6. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/__init__.py +0 -0
  7. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/_base_service.py +0 -0
  8. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/_time_utils.py +0 -0
  9. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
  10. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
  11. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
  12. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
  13. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
  14. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
  15. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
  16. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/README.md +0 -0
  17. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/__init__.py +0 -0
  18. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/__main__.py +0 -0
  19. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/cli.py +0 -0
  20. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/differ.py +0 -0
  21. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/exporter.py +0 -0
  22. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/models.py +0 -0
  23. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/registry.py +0 -0
  24. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/config_checker/validator.py +0 -0
  25. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/default_language_model.py +0 -0
  26. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
  27. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/config.py +0 -0
  28. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
  29. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
  30. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/service.py +0 -0
  31. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  32. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/endpoint_builder.py +0 -0
  33. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/endpoint_requestor.py +0 -0
  34. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/event_bus.py +0 -0
  35. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/exception.py +0 -0
  36. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/execution.py +0 -0
  37. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
  38. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
  39. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
  40. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
  41. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
  42. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
  43. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
  44. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
  45. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
  46. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
  47. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
  48. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
  49. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
  50. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
  51. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
  52. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
  53. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
  54. {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
  55. {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
  56. {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
  57. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
  58. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
  59. {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
  60. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
  61. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
  62. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
  63. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
  64. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/feature_flags/schema.py +0 -0
  65. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
  66. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/pydantic_helpers.py +0 -0
  67. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/referencing.py +0 -0
  68. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/string_utilities.py +0 -0
  69. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/tests/test_referencing.py +0 -0
  70. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
  71. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/__init__.py +0 -0
  72. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/image_token_counting.py +0 -0
  73. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/token_counting.py +0 -0
  74. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
  75. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
  76. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/__init__.py +0 -0
  77. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/files.py +0 -0
  78. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/image/encode.py +0 -0
  79. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
  80. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/jinja/render.py +0 -0
  81. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
  82. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
  83. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
  84. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
  85. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/utils/write_configuration.py +0 -0
  86. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/validate_required_values.py +0 -0
  87. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/_common/validators.py +0 -0
  88. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/__init__.py +0 -0
  89. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
  90. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
  91. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/config.py +0 -0
  92. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
  93. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
  94. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
  95. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
  96. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
  97. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
  98. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/exception.py +0 -0
  99. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
  100. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
  101. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
  102. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
  103. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
  104. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
  105. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
  106. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
  107. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
  108. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
  109. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
  110. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
  111. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
  112. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
  113. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
  114. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
  115. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/evaluation/utils.py +0 -0
  116. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
  117. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
  118. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
  119. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
  120. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
  121. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/history_manager/utils.py +0 -0
  122. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
  123. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
  124. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
  125. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
  126. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
  127. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/base.py +0 -0
  128. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
  129. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
  130. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
  131. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
  132. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
  133. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
  134. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
  135. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
  136. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
  137. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
  138. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
  139. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
  140. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
  141. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
  142. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
  143. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
  144. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
  145. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
  146. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
  147. {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
  148. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
  149. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/__init__.py +0 -0
  150. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
  151. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
  152. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
  153. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
  154. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
  155. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
  156. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
  157. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
  158. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
  159. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
  160. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
  161. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
  162. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
  163. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
  164. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
  165. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
  166. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
  167. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
  168. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
  169. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
  170. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
  171. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
  172. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
  173. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
  174. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
  175. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
  176. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
  177. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/config.py +0 -0
  178. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/__init__.py +0 -0
  179. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py +0 -0
  180. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/open_file_tool/config.py +0 -0
  181. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py +0 -0
  182. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/experimental/open_file_tool/tool.py +0 -0
  183. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/factory.py +0 -0
  184. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
  185. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
  186. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
  187. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
  188. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
  189. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
  190. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
  191. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
  192. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
  193. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
  194. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
  195. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
  196. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
  197. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/schemas.py +0 -0
  198. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
  199. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
  200. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/tool.py +0 -0
  201. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
  202. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
  203. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
  204. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  205. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
  206. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
  207. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
  208. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic_table/__init__.py +0 -0
  209. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic_table/schemas.py +0 -0
  210. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/agentic_table/service.py +0 -0
  211. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/__init__.py +0 -0
  212. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/dev_util.py +0 -0
  213. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/fast_api_factory.py +0 -0
  214. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/init_logging.py +0 -0
  215. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/init_sdk.py +0 -0
  216. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/performance/async_tasks.py +0 -0
  217. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/performance/async_wrapper.py +0 -0
  218. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/schemas.py +0 -0
  219. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/unique_settings.py +0 -0
  220. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/verification.py +0 -0
  221. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/app/webhook.py +0 -0
  222. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/__init__.py +0 -0
  223. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/cancellation.py +0 -0
  224. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/constants.py +0 -0
  225. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/deprecated/service.py +0 -0
  226. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/functions.py +0 -0
  227. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/rendering.py +0 -0
  228. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/responses_api.py +0 -0
  229. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/schemas.py +0 -0
  230. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/service.py +0 -0
  231. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/state.py +0 -0
  232. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/chat/utils.py +0 -0
  233. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/__init__.py +0 -0
  234. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/constants.py +0 -0
  235. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/functions.py +0 -0
  236. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/schemas.py +0 -0
  237. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/service.py +0 -0
  238. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/smart_rules.py +0 -0
  239. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/content/utils.py +0 -0
  240. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/README.md +0 -0
  241. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/__init__.py +0 -0
  242. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
  243. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/augmented/service.py +0 -0
  244. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/base.py +0 -0
  245. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
  246. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/basic/config.py +0 -0
  247. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
  248. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/data_extraction/basic/service.py +0 -0
  249. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/__init__.py +0 -0
  250. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/constants.py +0 -0
  251. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/exceptions.py +0 -0
  252. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/functions.py +0 -0
  253. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/schemas.py +0 -0
  254. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/elicitation/service.py +0 -0
  255. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/__init__.py +0 -0
  256. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/constants.py +0 -0
  257. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/functions.py +0 -0
  258. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/schemas.py +0 -0
  259. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/service.py +0 -0
  260. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/embedding/utils.py +0 -0
  261. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/__init__.py +0 -0
  262. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
  263. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
  264. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
  265. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
  266. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/openai/client.py +0 -0
  267. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
  268. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/framework_utilities/utils.py +0 -0
  269. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/__init__.py +0 -0
  270. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
  271. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/builder.py +0 -0
  272. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/constants.py +0 -0
  273. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/default_language_model.py +0 -0
  274. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/functions.py +0 -0
  275. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/infos.py +0 -0
  276. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/prompt.py +0 -0
  277. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/reference.py +0 -0
  278. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/schemas.py +0 -0
  279. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/service.py +0 -0
  280. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/stream_transform.py +0 -0
  281. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/language_model/utils.py +0 -0
  282. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/protocols/support.py +0 -0
  283. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/services/__init__.py +0 -0
  284. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/services/chat_service.py +0 -0
  285. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/services/factory.py +0 -0
  286. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/services/knowledge_base.py +0 -0
  287. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/__init__.py +0 -0
  288. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/constants.py +0 -0
  289. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/functions.py +0 -0
  290. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/schemas.py +0 -0
  291. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/short_term_memory/service.py +0 -0
  292. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/smart_rules/__init__.py +0 -0
  293. {unique_toolkit-1.68.9 → unique_toolkit-1.68.11}/unique_toolkit/smart_rules/compile.py +0 -0
  294. {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.9
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>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique_toolkit"
3
- version = "1.68.9"
3
+ version = "1.68.11"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -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 download failed ...",
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(logger, logging.WARNING),
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
- logger.info("Fetching and adding code interpreter files to the response")
306
+ self._log.info("run() started — fetching and uploading code interpreter files")
150
307
 
151
308
  container_files = loop_response.container_files
152
- logger.info("Found %s container files", len(container_files))
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
- logger.exception(
158
- "Failed to load previous code interpreter files from short-term "
159
- "memory; proceeding without previous file context."
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
- logger.exception(
188
- "Failed to save generated code interpreter files to short-term "
189
- "memory; file replacement will still proceed."
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
- logger.exception(
203
- "Failed to process orphan code blocks; "
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
- is_image = (guess_type(filename)[0] or "").startswith("image/")
234
- is_html = (guess_type(filename)[0] or "") == "text/html"
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
- changed |= loop_response.message.text != text_before
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
- retry = self._build_retry()
316
- file_content = await retry(
317
- self._client.containers.files.content.retrieve,
318
- container_id=container_file.container_id,
319
- file_id=container_file.file_id,
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
- logger.info(
323
- "Uploading file content for %s to knowledge base",
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=file_content.content,
607
+ content=file_bytes,
331
608
  content_name=container_file.filename,
332
- mime_type=guess_type(container_file.filename)[0] or "text/plain",
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
- logger.info(
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
- logger.info(
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
- logger.info(
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
- logger.exception(
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
- logger.info(
810
+ self._log.info(
434
811
  "Uploaded orphan code block as '%s' (content_id=%s)",
435
812
  filename,
436
813
  content.id,