unique_toolkit 1.68.10__tar.gz → 1.68.12__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.10 → unique_toolkit-1.68.12}/PKG-INFO +1 -1
  2. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/pyproject.toml +1 -1
  3. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +22 -2
  4. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +393 -15
  5. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/README.md +0 -0
  6. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/__init__.py +0 -0
  7. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/__init__.py +0 -0
  8. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/_base_service.py +0 -0
  9. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/_time_utils.py +0 -0
  10. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
  11. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
  12. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
  13. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
  14. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
  15. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
  16. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
  17. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/README.md +0 -0
  18. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/__init__.py +0 -0
  19. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/__main__.py +0 -0
  20. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/cli.py +0 -0
  21. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/differ.py +0 -0
  22. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/exporter.py +0 -0
  23. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/models.py +0 -0
  24. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/registry.py +0 -0
  25. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/config_checker/validator.py +0 -0
  26. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/default_language_model.py +0 -0
  27. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
  28. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/docx_generator/config.py +0 -0
  29. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
  30. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
  31. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/docx_generator/service.py +0 -0
  32. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  33. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/endpoint_builder.py +0 -0
  34. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/endpoint_requestor.py +0 -0
  35. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/event_bus.py +0 -0
  36. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/exception.py +0 -0
  37. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/execution.py +0 -0
  38. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
  39. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
  40. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
  41. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
  42. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
  43. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
  44. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
  45. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
  46. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
  47. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
  48. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
  49. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
  50. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
  51. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
  52. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
  53. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
  54. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
  55. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
  56. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
  57. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
  58. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
  59. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
  60. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
  61. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
  62. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
  63. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
  64. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
  65. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/feature_flags/schema.py +0 -0
  66. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
  67. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/pydantic_helpers.py +0 -0
  68. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/referencing.py +0 -0
  69. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/string_utilities.py +0 -0
  70. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/tests/test_referencing.py +0 -0
  71. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
  72. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/token/__init__.py +0 -0
  73. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/token/image_token_counting.py +0 -0
  74. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/token/token_counting.py +0 -0
  75. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
  76. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
  77. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/__init__.py +0 -0
  78. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/files.py +0 -0
  79. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/image/encode.py +0 -0
  80. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
  81. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/jinja/render.py +0 -0
  82. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
  83. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
  84. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
  85. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
  86. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/utils/write_configuration.py +0 -0
  87. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/validate_required_values.py +0 -0
  88. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/_common/validators.py +0 -0
  89. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/__init__.py +0 -0
  90. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
  91. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
  92. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/config.py +0 -0
  93. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
  94. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
  95. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
  96. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
  97. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
  98. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
  99. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/exception.py +0 -0
  100. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
  101. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
  102. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
  103. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
  104. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
  105. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
  106. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
  107. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
  108. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
  109. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
  110. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
  111. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
  112. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
  113. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
  114. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
  115. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
  116. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/evaluation/utils.py +0 -0
  117. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
  118. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
  119. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
  120. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
  121. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
  122. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/history_manager/utils.py +0 -0
  123. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
  124. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
  125. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
  126. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
  127. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
  128. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/base.py +0 -0
  129. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
  130. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
  131. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
  132. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
  133. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
  134. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
  135. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
  136. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
  137. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
  138. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
  139. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
  140. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
  141. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
  142. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
  143. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
  144. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
  145. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
  146. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
  147. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
  148. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
  149. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/__init__.py +0 -0
  150. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
  151. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
  152. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
  153. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
  154. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
  155. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
  156. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
  157. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
  158. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
  159. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
  160. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
  161. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
  162. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
  163. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
  164. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
  165. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
  166. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
  167. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
  168. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
  169. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
  170. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
  171. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
  172. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
  173. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
  174. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
  175. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
  176. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
  177. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/config.py +0 -0
  178. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/experimental/__init__.py +0 -0
  179. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py +0 -0
  180. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/experimental/open_file_tool/config.py +0 -0
  181. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py +0 -0
  182. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/experimental/open_file_tool/tool.py +0 -0
  183. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/factory.py +0 -0
  184. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
  185. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
  186. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
  187. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
  188. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
  189. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
  190. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
  191. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
  192. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
  193. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
  194. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
  195. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
  196. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
  197. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/schemas.py +0 -0
  198. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
  199. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
  200. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/tool.py +0 -0
  201. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
  202. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
  203. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
  204. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  205. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
  206. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
  207. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
  208. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic_table/__init__.py +0 -0
  209. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic_table/schemas.py +0 -0
  210. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/agentic_table/service.py +0 -0
  211. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/__init__.py +0 -0
  212. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/dev_util.py +0 -0
  213. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/fast_api_factory.py +0 -0
  214. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/init_logging.py +0 -0
  215. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/init_sdk.py +0 -0
  216. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/performance/async_tasks.py +0 -0
  217. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/performance/async_wrapper.py +0 -0
  218. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/schemas.py +0 -0
  219. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/unique_settings.py +0 -0
  220. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/verification.py +0 -0
  221. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/app/webhook.py +0 -0
  222. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/__init__.py +0 -0
  223. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/cancellation.py +0 -0
  224. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/constants.py +0 -0
  225. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/deprecated/service.py +0 -0
  226. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/functions.py +0 -0
  227. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/rendering.py +0 -0
  228. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/responses_api.py +0 -0
  229. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/schemas.py +0 -0
  230. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/service.py +0 -0
  231. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/state.py +0 -0
  232. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/chat/utils.py +0 -0
  233. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/content/__init__.py +0 -0
  234. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/content/constants.py +0 -0
  235. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/content/functions.py +0 -0
  236. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/content/schemas.py +0 -0
  237. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/content/service.py +0 -0
  238. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/content/smart_rules.py +0 -0
  239. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/content/utils.py +0 -0
  240. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/README.md +0 -0
  241. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/__init__.py +0 -0
  242. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
  243. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/augmented/service.py +0 -0
  244. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/base.py +0 -0
  245. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
  246. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/basic/config.py +0 -0
  247. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
  248. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/data_extraction/basic/service.py +0 -0
  249. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/elicitation/__init__.py +0 -0
  250. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/elicitation/constants.py +0 -0
  251. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/elicitation/exceptions.py +0 -0
  252. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/elicitation/functions.py +0 -0
  253. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/elicitation/schemas.py +0 -0
  254. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/elicitation/service.py +0 -0
  255. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/embedding/__init__.py +0 -0
  256. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/embedding/constants.py +0 -0
  257. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/embedding/functions.py +0 -0
  258. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/embedding/schemas.py +0 -0
  259. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/embedding/service.py +0 -0
  260. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/embedding/utils.py +0 -0
  261. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/framework_utilities/__init__.py +0 -0
  262. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
  263. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
  264. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
  265. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
  266. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/framework_utilities/openai/client.py +0 -0
  267. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
  268. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/framework_utilities/utils.py +0 -0
  269. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/__init__.py +0 -0
  270. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
  271. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/builder.py +0 -0
  272. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/constants.py +0 -0
  273. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/default_language_model.py +0 -0
  274. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/functions.py +0 -0
  275. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/infos.py +0 -0
  276. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/prompt.py +0 -0
  277. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/reference.py +0 -0
  278. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/schemas.py +0 -0
  279. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/service.py +0 -0
  280. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/stream_transform.py +0 -0
  281. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/language_model/utils.py +0 -0
  282. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/protocols/support.py +0 -0
  283. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/services/__init__.py +0 -0
  284. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/services/chat_service.py +0 -0
  285. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/services/factory.py +0 -0
  286. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/services/knowledge_base.py +0 -0
  287. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/short_term_memory/__init__.py +0 -0
  288. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/short_term_memory/constants.py +0 -0
  289. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/short_term_memory/functions.py +0 -0
  290. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/short_term_memory/schemas.py +0 -0
  291. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/short_term_memory/service.py +0 -0
  292. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/smart_rules/__init__.py +0 -0
  293. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/unique_toolkit/smart_rules/compile.py +0 -0
  294. {unique_toolkit-1.68.10 → unique_toolkit-1.68.12}/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.10
3
+ Version: 1.68.12
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.10"
3
+ version = "1.68.12"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -85,7 +85,17 @@ class PersistentShortMemoryManager(Generic[TSchema]):
85
85
  self._short_term_memory_name,
86
86
  )
87
87
 
88
- self._log_not_found() if not result.success else self._log_found()
88
+ if not result.success:
89
+ self._log_not_found()
90
+ if result.exception is not None:
91
+ logger.warning(
92
+ "Short term memory lookup failed with %s: %s",
93
+ type(result.exception).__name__,
94
+ result.exception,
95
+ exc_info=result.exception,
96
+ )
97
+ else:
98
+ self._log_found()
89
99
 
90
100
  return result.unpack(default=None)
91
101
 
@@ -95,7 +105,17 @@ class PersistentShortMemoryManager(Generic[TSchema]):
95
105
  self._short_term_memory_name,
96
106
  )
97
107
 
98
- self._log_not_found() if not result.success else self._log_found()
108
+ if not result.success:
109
+ self._log_not_found()
110
+ if result.exception is not None:
111
+ logger.warning(
112
+ "Short term memory lookup failed with %s: %s",
113
+ type(result.exception).__name__,
114
+ result.exception,
115
+ exc_info=result.exception,
116
+ )
117
+ else:
118
+ self._log_found()
99
119
 
100
120
  return result.unpack(default=None)
101
121
 
@@ -2,9 +2,12 @@ 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
 
10
+ import httpx
8
11
  from openai import AsyncOpenAI
9
12
  from openai.types.responses import ResponseCodeInterpreterToolCall
10
13
  from openai.types.responses.response_output_text import AnnotationContainerFileCitation
@@ -76,6 +79,20 @@ class DisplayCodeInterpreterFilesPostProcessorConfig(BaseModel):
76
79
  default=0.5,
77
80
  description="Base delay in seconds for exponential backoff between download/upload retries.",
78
81
  )
82
+ progress_update_interval: float = Field(
83
+ default=3.0,
84
+ description="Minimum seconds between progress message updates sent to the user.",
85
+ )
86
+ download_chunk_size: int = Field(
87
+ default=8192,
88
+ description="Chunk size in bytes for streaming container file downloads.",
89
+ )
90
+ download_read_timeout: float = Field(
91
+ default=120.0,
92
+ description="HTTP read timeout in seconds for container file downloads. "
93
+ "Applies per SDK attempt. The OpenAI SDK default of 600s is too generous "
94
+ "for small generated files; a shorter timeout lets us retry sooner.",
95
+ )
79
96
 
80
97
 
81
98
  class _ContentInfo(NamedTuple):
@@ -103,6 +120,157 @@ def _init_short_term_memory_manager(
103
120
  )
104
121
 
105
122
 
123
+ @dataclass
124
+ class _FileState:
125
+ phase: str = "pending"
126
+ percent: int | None = None
127
+ elapsed_seconds: float = 0.0
128
+ retry_attempt: int = 0
129
+ max_retries: int = 0
130
+
131
+
132
+ class _FileProgressTracker:
133
+ """Concurrency-safe coordinator that publishes file download/upload progress
134
+ to the user-visible assistant message in real time.
135
+
136
+ Replaces sandbox links inline with progress text and appends a summary block.
137
+ Throttles ``modify_assistant_message_async`` calls to avoid API spam.
138
+ """
139
+
140
+ def __init__(
141
+ self,
142
+ filenames: list[str],
143
+ original_text: str,
144
+ chat_service: ChatService,
145
+ log: logging.LoggerAdapter[logging.Logger],
146
+ min_publish_interval: float = 3.0,
147
+ ) -> None:
148
+ self._states: dict[str, _FileState] = {f: _FileState() for f in filenames}
149
+ self._original_text = original_text
150
+ self._chat_service = chat_service
151
+ self._log = log
152
+ self._lock = asyncio.Lock()
153
+ self._last_publish_time = 0.0
154
+ self._min_interval = min_publish_interval
155
+
156
+ async def update(
157
+ self,
158
+ filename: str,
159
+ phase: str,
160
+ *,
161
+ percent: int | None = None,
162
+ elapsed_seconds: float = 0.0,
163
+ retry_attempt: int = 0,
164
+ max_retries: int = 0,
165
+ force_publish: bool = False,
166
+ ) -> None:
167
+ async with self._lock:
168
+ state = self._states.get(filename)
169
+ if state is None:
170
+ return
171
+ state.phase = phase
172
+ state.percent = percent
173
+ state.elapsed_seconds = elapsed_seconds
174
+ state.retry_attempt = retry_attempt
175
+ state.max_retries = max_retries
176
+
177
+ now = time.monotonic()
178
+ should_publish = (
179
+ force_publish
180
+ or phase in ("done", "failed", "uploading")
181
+ or now - self._last_publish_time >= self._min_interval
182
+ )
183
+ if should_publish:
184
+ await self._publish()
185
+ self._last_publish_time = now
186
+
187
+ async def tick_elapsed(self, filename: str, elapsed_seconds: float) -> None:
188
+ """Publish an elapsed-time update without changing percent or retry state.
189
+
190
+ Used by the background ticker to show time-based progress while the
191
+ OpenAI API hasn't started returning bytes yet.
192
+ """
193
+ async with self._lock:
194
+ state = self._states.get(filename)
195
+ if state is None or state.phase != "downloading":
196
+ return
197
+ state.elapsed_seconds = elapsed_seconds
198
+ now = time.monotonic()
199
+ if now - self._last_publish_time >= self._min_interval:
200
+ await self._publish()
201
+ self._last_publish_time = now
202
+
203
+ async def publish_initial(self) -> None:
204
+ """Send the first progress update (marks all files as pending)."""
205
+ async with self._lock:
206
+ for state in self._states.values():
207
+ state.phase = "downloading"
208
+ await self._publish()
209
+ self._last_publish_time = time.monotonic()
210
+
211
+ async def _publish(self) -> None:
212
+ text = self._build_progress_text()
213
+ try:
214
+ await self._chat_service.modify_assistant_message_async(content=text)
215
+ except Exception:
216
+ self._log.debug("Failed to publish progress update", exc_info=True)
217
+
218
+ def _build_progress_text(self) -> str:
219
+ text = self._original_text
220
+
221
+ for filename, state in self._states.items():
222
+ if state.phase == "pending":
223
+ continue
224
+ progress = self._format_inline(filename, state)
225
+ pattern = rf"!?\[.*?\]\(sandbox:/mnt/data/{re.escape(filename)}\)"
226
+ text = re.sub(pattern, progress, text)
227
+
228
+ active = {
229
+ f: s for f, s in self._states.items() if s.phase not in ("done", "pending")
230
+ }
231
+ if active:
232
+ lines = ["---", "Preparing files:"]
233
+ for filename, state in active.items():
234
+ lines.append(f"- {filename} — {self._format_summary(state)}")
235
+ text = text.rstrip() + "\n\n" + "\n".join(lines)
236
+
237
+ return text
238
+
239
+ @staticmethod
240
+ def _format_inline(filename: str, state: _FileState) -> str:
241
+ if state.phase == "downloading":
242
+ base = f"Downloading {filename}..."
243
+ if state.retry_attempt > 0:
244
+ base += f" retry {state.retry_attempt}/{state.max_retries}"
245
+ if state.percent is not None:
246
+ return f"{base} {state.percent}%"
247
+ if state.elapsed_seconds > 0:
248
+ return f"{base} ({int(state.elapsed_seconds)}s)"
249
+ return base
250
+ if state.phase == "uploading":
251
+ return f"Uploading {filename}..."
252
+ if state.phase == "failed":
253
+ return "File could not be generated. Please try again."
254
+ return filename
255
+
256
+ @staticmethod
257
+ def _format_summary(state: _FileState) -> str:
258
+ if state.phase == "downloading":
259
+ base = "Downloading"
260
+ if state.retry_attempt > 0:
261
+ base += f" (retry {state.retry_attempt}/{state.max_retries})"
262
+ if state.percent is not None:
263
+ return f"{base} {state.percent}%"
264
+ if state.elapsed_seconds > 0:
265
+ return f"{base} ({int(state.elapsed_seconds)}s)"
266
+ return f"{base}..."
267
+ if state.phase == "uploading":
268
+ return "Uploading..."
269
+ if state.phase == "failed":
270
+ return "Failed"
271
+ return "Pending"
272
+
273
+
106
274
  class DisplayCodeInterpreterFilesPostProcessor(
107
275
  ResponsesApiPostprocessor,
108
276
  ):
@@ -158,6 +326,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
158
326
 
159
327
  @override
160
328
  async def run(self, loop_response: ResponsesLanguageModelStreamResponse) -> None:
329
+ run_t0 = time.monotonic()
161
330
  self._log.info("run() started — fetching and uploading code interpreter files")
162
331
 
163
332
  container_files = loop_response.container_files
@@ -167,6 +336,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
167
336
  [cf.filename for cf in container_files],
168
337
  )
169
338
 
339
+ phase_t0 = time.monotonic()
170
340
  try:
171
341
  self._content_map: dict[str, str | None] = await self._load_previous_files() # type: ignore
172
342
  if self._content_map:
@@ -181,20 +351,36 @@ class DisplayCodeInterpreterFilesPostProcessor(
181
351
  "proceeding without previous file context."
182
352
  )
183
353
  self._content_map = {}
354
+ load_ms = (time.monotonic() - phase_t0) * 1000
355
+
356
+ tracker: _FileProgressTracker | None = None
357
+ if container_files and self._chat_service is not None:
358
+ tracker = _FileProgressTracker(
359
+ filenames=[cf.filename for cf in container_files],
360
+ original_text=loop_response.message.text or "",
361
+ chat_service=self._chat_service,
362
+ log=self._log,
363
+ min_publish_interval=self._config.progress_update_interval,
364
+ )
365
+ await tracker.publish_initial()
184
366
 
367
+ phase_t0 = time.monotonic()
185
368
  semaphore = asyncio.Semaphore(self._config.max_concurrent_file_downloads)
186
369
  tasks = [
187
370
  self._download_and_upload_container_files_to_knowledge_base(
188
- citation, semaphore
371
+ citation, semaphore, tracker
189
372
  )
190
373
  for citation in container_files
191
374
  ]
192
375
  results = await asyncio.gather(*tasks)
376
+ download_upload_ms = (time.monotonic() - phase_t0) * 1000
193
377
 
194
378
  for citation, result in zip(container_files, results):
195
379
  self._content_map[citation.filename] = (
196
380
  result.content_id if result is not None else None
197
381
  )
382
+ if result is None and tracker:
383
+ await tracker.update(citation.filename, "failed", force_publish=True)
198
384
 
199
385
  succeeded = {f: cid for f, cid in self._content_map.items() if cid is not None}
200
386
  failed = [f for f, cid in self._content_map.items() if cid is None]
@@ -207,6 +393,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
207
393
  failed,
208
394
  )
209
395
 
396
+ phase_t0 = time.monotonic()
210
397
  try:
211
398
  await self._save_generated_files(
212
399
  [
@@ -220,7 +407,9 @@ class DisplayCodeInterpreterFilesPostProcessor(
220
407
  "run() failed to save generated files to short-term memory; "
221
408
  "file replacement will still proceed."
222
409
  )
410
+ save_ms = (time.monotonic() - phase_t0) * 1000
223
411
 
412
+ phase_t0 = time.monotonic()
224
413
  try:
225
414
  if feature_flags.enable_code_execution_fence_un_17972.is_enabled(
226
415
  self._company_id
@@ -241,18 +430,28 @@ class DisplayCodeInterpreterFilesPostProcessor(
241
430
  "file replacement will still proceed."
242
431
  )
243
432
  self._orphan_code_blocks = []
433
+ orphan_ms = (time.monotonic() - phase_t0) * 1000
244
434
 
435
+ total_ms = (time.monotonic() - run_t0) * 1000
245
436
  self._log.info(
246
- "run() finished — content_map has %d entries (%d with content_id, %d failed)",
437
+ "run() finished — content_map has %d entries (%d ok, %d failed). "
438
+ "Timing: total=%.0fms, load_stm=%.0fms, download_upload=%.0fms, "
439
+ "save_stm=%.0fms, orphan=%.0fms",
247
440
  len(self._content_map),
248
441
  len(succeeded),
249
442
  len(failed),
443
+ total_ms,
444
+ load_ms,
445
+ download_upload_ms,
446
+ save_ms,
447
+ orphan_ms,
250
448
  )
251
449
 
252
450
  @override
253
451
  def apply_postprocessing_to_response(
254
452
  self, loop_response: ResponsesLanguageModelStreamResponse
255
453
  ) -> bool:
454
+ apply_t0 = time.monotonic()
256
455
  self._log.info(
257
456
  "apply_postprocessing started — %d file(s) in content_map, fence_ff=%s",
258
457
  len(self._content_map),
@@ -390,14 +589,16 @@ class DisplayCodeInterpreterFilesPostProcessor(
390
589
  "apply_postprocessing found and replaced dangling sandbox links"
391
590
  )
392
591
 
592
+ apply_ms = (time.monotonic() - apply_t0) * 1000
393
593
  self._log.info(
394
594
  "apply_postprocessing finished — changed=%s, replaced=%d, missed=%d, "
395
- "error=%d, dangling_cleaned=%s",
595
+ "error=%d, dangling_cleaned=%s (%.0fms)",
396
596
  changed,
397
597
  len(replaced_files),
398
598
  len(missed_files),
399
599
  len(error_files),
400
600
  dangling_replaced,
601
+ apply_ms,
401
602
  )
402
603
 
403
604
  return changed
@@ -411,50 +612,215 @@ class DisplayCodeInterpreterFilesPostProcessor(
411
612
  self,
412
613
  container_file: AnnotationContainerFileCitation,
413
614
  semaphore: asyncio.Semaphore,
615
+ tracker: _FileProgressTracker | None = None,
414
616
  ) -> _ContentInfo | None:
415
617
  async with semaphore:
618
+ pipeline_t0 = time.monotonic()
416
619
  self._log.info(
417
620
  "Downloading container file '%s' (container=%s, file_id=%s)",
418
621
  container_file.filename,
419
622
  container_file.container_id,
420
623
  container_file.file_id,
421
624
  )
422
- retry = self._build_retry()
423
- file_content = await retry(
424
- self._client.containers.files.content.retrieve,
425
- container_id=container_file.container_id,
426
- file_id=container_file.file_id,
625
+
626
+ download_t0 = time.monotonic()
627
+ file_bytes = await self._download_file_bytes_with_progress(
628
+ container_file, tracker
427
629
  )
630
+ download_ms = (time.monotonic() - download_t0) * 1000
631
+
428
632
  self._log.info(
429
- "Downloaded container file '%s' (%d bytes)",
633
+ "Downloaded container file '%s' (%d bytes, %.0fms)",
430
634
  container_file.filename,
431
- len(file_content.content),
635
+ len(file_bytes),
636
+ download_ms,
432
637
  )
433
638
 
639
+ if tracker:
640
+ await tracker.update(
641
+ container_file.filename, "uploading", force_publish=True
642
+ )
643
+
434
644
  mime = guess_type(container_file.filename)[0] or "text/plain"
435
645
  self._log.info(
436
- "Uploading '%s' to knowledge base (mime=%s)",
646
+ "Uploading '%s' to knowledge base (mime=%s, %d bytes)",
437
647
  container_file.filename,
438
648
  mime,
649
+ len(file_bytes),
439
650
  )
440
651
 
441
652
  assert self._chat_service is not None # Checked in __init__
653
+ upload_t0 = time.monotonic()
442
654
  content = await self._build_retry()(
443
655
  self._chat_service.upload_to_chat_from_bytes_async,
444
- content=file_content.content,
656
+ content=file_bytes,
445
657
  content_name=container_file.filename,
446
658
  mime_type=mime,
447
659
  skip_ingestion=True,
448
660
  hide_in_chat=True,
449
661
  )
662
+ upload_ms = (time.monotonic() - upload_t0) * 1000
663
+
664
+ if tracker:
665
+ await tracker.update(
666
+ container_file.filename, "done", force_publish=True
667
+ )
450
668
 
669
+ pipeline_ms = (time.monotonic() - pipeline_t0) * 1000
451
670
  self._log.info(
452
- "Uploaded '%s' — content_id=%s",
671
+ "Uploaded '%s' — content_id=%s. "
672
+ "Timing: download=%.0fms, upload=%.0fms, pipeline=%.0fms",
453
673
  container_file.filename,
454
674
  content.id,
675
+ download_ms,
676
+ upload_ms,
677
+ pipeline_ms,
455
678
  )
456
679
  return _ContentInfo(filename=container_file.filename, content_id=content.id)
457
680
 
681
+ async def _download_file_bytes_with_progress(
682
+ self,
683
+ container_file: AnnotationContainerFileCitation,
684
+ tracker: _FileProgressTracker | None,
685
+ ) -> bytes:
686
+ """Download container file with streaming progress and manual retry loop.
687
+
688
+ Uses ``with_streaming_response`` so we can read ``content-length``
689
+ and report download percentage. Falls back to elapsed-time display
690
+ when the header is absent.
691
+
692
+ A background ticker task publishes elapsed-time updates at regular
693
+ intervals even when the OpenAI API is slow to return the first byte.
694
+ """
695
+ max_attempts = 1 + self._config.max_download_retries
696
+ download_start = time.monotonic()
697
+ last_exception: Exception | None = None
698
+
699
+ ticker_task: asyncio.Task[None] | None = None
700
+ if tracker:
701
+
702
+ async def _ticker() -> None:
703
+ while True:
704
+ await asyncio.sleep(self._config.progress_update_interval)
705
+ elapsed = time.monotonic() - download_start
706
+ self._log.info(
707
+ "Still downloading '%s' (%.0fs elapsed)",
708
+ container_file.filename,
709
+ elapsed,
710
+ )
711
+ await tracker.tick_elapsed(container_file.filename, elapsed)
712
+
713
+ ticker_task = asyncio.create_task(_ticker())
714
+
715
+ try:
716
+ for attempt_num in range(1, max_attempts + 1):
717
+ retry_num = attempt_num - 1
718
+ try:
719
+ if retry_num > 0:
720
+ delay = self._config.download_retry_base_delay * (
721
+ 2 ** (retry_num - 1)
722
+ )
723
+ self._log.warning(
724
+ "Retrying download of '%s' (attempt %d/%d) after %.1fs",
725
+ container_file.filename,
726
+ attempt_num,
727
+ max_attempts,
728
+ delay,
729
+ )
730
+ if tracker:
731
+ await tracker.update(
732
+ container_file.filename,
733
+ "downloading",
734
+ elapsed_seconds=time.monotonic() - download_start,
735
+ retry_attempt=retry_num,
736
+ max_retries=self._config.max_download_retries,
737
+ force_publish=True,
738
+ )
739
+ await asyncio.sleep(delay)
740
+
741
+ return await self._stream_download_bytes(
742
+ container_file, tracker, retry_num, download_start
743
+ )
744
+ except Exception as exc:
745
+ last_exception = exc
746
+ self._log.warning(
747
+ "Download attempt %d/%d failed for '%s': %s",
748
+ attempt_num,
749
+ max_attempts,
750
+ container_file.filename,
751
+ exc,
752
+ )
753
+
754
+ assert last_exception is not None
755
+ raise last_exception
756
+ finally:
757
+ if ticker_task is not None:
758
+ ticker_task.cancel()
759
+ try:
760
+ await ticker_task
761
+ except BaseException:
762
+ pass
763
+
764
+ async def _stream_download_bytes(
765
+ self,
766
+ container_file: AnnotationContainerFileCitation,
767
+ tracker: _FileProgressTracker | None,
768
+ retry_attempt: int,
769
+ download_start: float,
770
+ ) -> bytes:
771
+ """Stream-download a single container file, reporting chunk-level progress.
772
+
773
+ SDK-level retries are disabled (``max_retries=0``) so that only our
774
+ manual retry loop retries, with full visibility in logs and progress
775
+ tracker. A shorter read timeout avoids waiting 10 minutes on a
776
+ stalled connection.
777
+ """
778
+ t0 = time.monotonic()
779
+ async with self._client.with_options(
780
+ max_retries=0,
781
+ timeout=httpx.Timeout(5.0, read=self._config.download_read_timeout),
782
+ ).containers.files.content.with_streaming_response.retrieve(
783
+ file_id=container_file.file_id,
784
+ container_id=container_file.container_id,
785
+ ) as response:
786
+ first_byte_ms = (time.monotonic() - t0) * 1000
787
+ self._log.info(
788
+ "Stream opened for '%s' — first-byte latency=%.0fms, "
789
+ "content-length=%s, status=%s",
790
+ container_file.filename,
791
+ first_byte_ms,
792
+ response.headers.get("content-length", "unknown"),
793
+ response.status_code,
794
+ )
795
+ content_length = response.headers.get("content-length")
796
+ total = int(content_length) if content_length else None
797
+ chunks: list[bytes] = []
798
+ downloaded = 0
799
+ async for chunk in response.iter_bytes(
800
+ chunk_size=self._config.download_chunk_size
801
+ ):
802
+ chunks.append(chunk)
803
+ downloaded += len(chunk)
804
+ if tracker:
805
+ pct = (downloaded * 100 // total) if total else None
806
+ elapsed = time.monotonic() - download_start
807
+ await tracker.update(
808
+ container_file.filename,
809
+ "downloading",
810
+ percent=pct,
811
+ elapsed_seconds=elapsed,
812
+ retry_attempt=retry_attempt,
813
+ max_retries=self._config.max_download_retries,
814
+ )
815
+ transfer_ms = (time.monotonic() - t0) * 1000 - first_byte_ms
816
+ self._log.info(
817
+ "Stream complete for '%s' — transfer=%.0fms, total=%d bytes",
818
+ container_file.filename,
819
+ transfer_ms,
820
+ downloaded,
821
+ )
822
+ return b"".join(chunks)
823
+
458
824
  async def _load_previous_files(self) -> dict[str, str]:
459
825
  if self._short_term_memory_manager is None:
460
826
  return {}
@@ -462,16 +828,22 @@ class DisplayCodeInterpreterFilesPostProcessor(
462
828
  self._log.info(
463
829
  "Loading previously generated code interpreter files from short term memory"
464
830
  )
831
+ t0 = time.monotonic()
465
832
  memory = await self._short_term_memory_manager.load_async()
833
+ elapsed_ms = (time.monotonic() - t0) * 1000
466
834
 
467
835
  if memory is None:
468
836
  self._log.info(
469
- "No previously generated code interpreter files found in short term memory"
837
+ "No previously generated code interpreter files found "
838
+ "in short term memory (%.0fms)",
839
+ elapsed_ms,
470
840
  )
471
841
  return {}
472
842
 
473
843
  self._log.info(
474
- "Found %s previously generated code interpreter files", len(memory.root)
844
+ "Found %s previously generated code interpreter files (%.0fms)",
845
+ len(memory.root),
846
+ elapsed_ms,
475
847
  )
476
848
 
477
849
  return {content.filename: content.content_id for content in memory.root}
@@ -480,9 +852,15 @@ class DisplayCodeInterpreterFilesPostProcessor(
480
852
  if self._short_term_memory_manager is None or len(content_infos) == 0:
481
853
  return
482
854
 
855
+ t0 = time.monotonic()
483
856
  await self._short_term_memory_manager.save_async(
484
857
  _DisplayedFilesShortTermMemorySchema(root=content_infos)
485
858
  )
859
+ self._log.info(
860
+ "Saved %d generated file(s) to short term memory (%.0fms)",
861
+ len(content_infos),
862
+ (time.monotonic() - t0) * 1000,
863
+ )
486
864
 
487
865
  async def _upload_orphan_code_as_txt(
488
866
  self, loop_response: ResponsesLanguageModelStreamResponse