unique_toolkit 1.53.3__tar.gz → 1.54.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/PKG-INFO +1 -1
  2. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/pyproject.toml +1 -1
  3. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +42 -0
  4. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +185 -18
  5. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +28 -3
  6. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/README.md +0 -0
  7. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/__init__.py +0 -0
  8. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/__init__.py +0 -0
  9. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/_base_service.py +0 -0
  10. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/_time_utils.py +0 -0
  11. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
  12. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
  13. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
  14. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
  15. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
  16. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
  17. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
  18. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/README.md +0 -0
  19. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/__init__.py +0 -0
  20. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/__main__.py +0 -0
  21. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/cli.py +0 -0
  22. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/differ.py +0 -0
  23. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/exporter.py +0 -0
  24. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/models.py +0 -0
  25. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/registry.py +0 -0
  26. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/config_checker/validator.py +0 -0
  27. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/default_language_model.py +0 -0
  28. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
  29. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/docx_generator/config.py +0 -0
  30. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
  31. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
  32. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/docx_generator/service.py +0 -0
  33. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  34. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/endpoint_builder.py +0 -0
  35. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/endpoint_requestor.py +0 -0
  36. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/event_bus.py +0 -0
  37. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/exception.py +0 -0
  38. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/execution.py +0 -0
  39. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
  40. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
  41. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
  42. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
  43. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
  44. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
  45. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
  46. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
  47. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
  48. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
  49. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
  50. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
  51. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
  52. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
  53. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
  54. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
  55. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
  56. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
  57. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
  58. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
  59. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
  60. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
  61. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
  62. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
  63. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
  64. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
  65. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
  66. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/feature_flags/schema.py +0 -0
  67. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
  68. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/pydantic_helpers.py +0 -0
  69. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/referencing.py +0 -0
  70. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/string_utilities.py +0 -0
  71. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/tests/test_referencing.py +0 -0
  72. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
  73. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/token/__init__.py +0 -0
  74. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/token/image_token_counting.py +0 -0
  75. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/token/token_counting.py +0 -0
  76. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
  77. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
  78. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/__init__.py +0 -0
  79. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/files.py +0 -0
  80. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/image/encode.py +0 -0
  81. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
  82. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/jinja/render.py +0 -0
  83. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
  84. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
  85. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
  86. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
  87. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/utils/write_configuration.py +0 -0
  88. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/validate_required_values.py +0 -0
  89. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/_common/validators.py +0 -0
  90. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/__init__.py +0 -0
  91. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
  92. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
  93. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/config.py +0 -0
  94. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
  95. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
  96. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
  97. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
  98. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
  99. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
  100. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/exception.py +0 -0
  101. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
  102. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
  103. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
  104. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
  105. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
  106. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
  107. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
  108. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
  109. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
  110. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
  111. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
  112. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
  113. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
  114. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
  115. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
  116. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
  117. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/evaluation/utils.py +0 -0
  118. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
  119. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
  120. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
  121. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
  122. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
  123. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/history_manager/utils.py +0 -0
  124. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
  125. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
  126. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
  127. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
  128. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
  129. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/base.py +0 -0
  130. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
  131. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
  132. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
  133. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
  134. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
  135. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
  136. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
  137. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
  138. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
  139. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
  140. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
  141. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
  142. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
  143. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
  144. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
  145. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
  146. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
  147. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
  148. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
  149. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
  150. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
  151. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/__init__.py +0 -0
  152. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
  153. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
  154. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
  155. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
  156. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
  157. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
  158. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
  159. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
  160. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
  161. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
  162. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
  163. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
  164. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
  165. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
  166. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
  167. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
  168. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
  169. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
  170. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
  171. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
  172. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
  173. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
  174. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
  175. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
  176. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
  177. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
  178. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
  179. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/config.py +0 -0
  180. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/factory.py +0 -0
  181. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
  182. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
  183. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
  184. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
  185. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
  186. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
  187. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
  188. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
  189. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
  190. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
  191. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
  192. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/schemas.py +0 -0
  193. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
  194. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
  195. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/tool.py +0 -0
  196. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
  197. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
  198. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
  199. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  200. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
  201. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
  202. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
  203. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic_table/__init__.py +0 -0
  204. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic_table/schemas.py +0 -0
  205. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/agentic_table/service.py +0 -0
  206. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/__init__.py +0 -0
  207. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/dev_util.py +0 -0
  208. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/fast_api_factory.py +0 -0
  209. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/init_logging.py +0 -0
  210. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/init_sdk.py +0 -0
  211. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/performance/async_tasks.py +0 -0
  212. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/performance/async_wrapper.py +0 -0
  213. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/schemas.py +0 -0
  214. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/unique_settings.py +0 -0
  215. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/verification.py +0 -0
  216. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/app/webhook.py +0 -0
  217. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/__init__.py +0 -0
  218. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/cancellation.py +0 -0
  219. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/constants.py +0 -0
  220. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/deprecated/service.py +0 -0
  221. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/functions.py +0 -0
  222. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/rendering.py +0 -0
  223. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/responses_api.py +0 -0
  224. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/schemas.py +0 -0
  225. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/service.py +0 -0
  226. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/state.py +0 -0
  227. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/chat/utils.py +0 -0
  228. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/content/__init__.py +0 -0
  229. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/content/constants.py +0 -0
  230. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/content/functions.py +0 -0
  231. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/content/schemas.py +0 -0
  232. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/content/service.py +0 -0
  233. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/content/smart_rules.py +0 -0
  234. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/content/utils.py +0 -0
  235. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/README.md +0 -0
  236. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/__init__.py +0 -0
  237. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
  238. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/augmented/service.py +0 -0
  239. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/base.py +0 -0
  240. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
  241. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/basic/config.py +0 -0
  242. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
  243. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/data_extraction/basic/service.py +0 -0
  244. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/elicitation/__init__.py +0 -0
  245. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/elicitation/constants.py +0 -0
  246. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/elicitation/exceptions.py +0 -0
  247. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/elicitation/functions.py +0 -0
  248. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/elicitation/schemas.py +0 -0
  249. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/elicitation/service.py +0 -0
  250. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/embedding/__init__.py +0 -0
  251. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/embedding/constants.py +0 -0
  252. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/embedding/functions.py +0 -0
  253. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/embedding/schemas.py +0 -0
  254. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/embedding/service.py +0 -0
  255. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/embedding/utils.py +0 -0
  256. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/framework_utilities/__init__.py +0 -0
  257. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
  258. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
  259. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
  260. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
  261. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/framework_utilities/openai/client.py +0 -0
  262. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
  263. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/framework_utilities/utils.py +0 -0
  264. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/__init__.py +0 -0
  265. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
  266. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/builder.py +0 -0
  267. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/constants.py +0 -0
  268. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/default_language_model.py +0 -0
  269. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/functions.py +0 -0
  270. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/infos.py +0 -0
  271. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/prompt.py +0 -0
  272. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/reference.py +0 -0
  273. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/schemas.py +0 -0
  274. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/service.py +0 -0
  275. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/stream_transform.py +0 -0
  276. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/language_model/utils.py +0 -0
  277. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/protocols/support.py +0 -0
  278. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/services/__init__.py +0 -0
  279. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/services/chat_service.py +0 -0
  280. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/services/knowledge_base.py +0 -0
  281. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/short_term_memory/__init__.py +0 -0
  282. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/short_term_memory/constants.py +0 -0
  283. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/short_term_memory/functions.py +0 -0
  284. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/short_term_memory/schemas.py +0 -0
  285. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/short_term_memory/service.py +0 -0
  286. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/smart_rules/__init__.py +0 -0
  287. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/smart_rules/compile.py +0 -0
  288. {unique_toolkit-1.53.3 → unique_toolkit-1.54.0}/unique_toolkit/test_utilities/events.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-toolkit
3
- Version: 1.53.3
3
+ Version: 1.54.0
4
4
  Summary:
5
5
  Author: Cedric Klinkert, Martin Fadler, Sadique Sheik, Fabian Schläpfer, Pascal Hauri, Ejiroghene Oki-Peter, Rami Azouz, Ricardo Visini, Sanzio Monti
6
6
  Author-email: Cedric Klinkert <cedric.klinkert@unique.ch>, Martin Fadler <martin.fadler@unique.ch>, Sadique Sheik <sadique@unique.ch>, Fabian Schläpfer <fabian@unique.ch>, Pascal Hauri <pascal@unique.ch>, Ejiroghene Oki-Peter <oki-peter.ejiroghene@unique.ai>, Rami Azouz <rami.ext@unique.ch>, Ricardo Visini <ricardo.visini@unique.ch>, Sanzio Monti <sanzio.monti@unique.ai>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique_toolkit"
3
- version = "1.53.3"
3
+ version = "1.54.0"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -41,6 +41,48 @@ Always use a line break between the title and the markdown!
41
41
  - Only the following file types are allowed to be uploaded to the platform, anything else will FAIL: PDF, DOCX, XLSX, PPTX, CSV, HTML, MD, TXT, PNG, JPG, JPEG.
42
42
  - You MUST always use this syntax, otherwise the files will not be displayed in the chat.
43
43
 
44
+ # Displaying Dataframes/Tables:
45
+ - Whenever asked to display a dataframe/table, it is CRITICAL to represent it faithfully as a markdown table in your response.
46
+
47
+ Handling User Queries:
48
+ - Whenever the user query requires using the python tool, you must always think first about the steps required.
49
+ - Use the tool multiple times:
50
+ - You MUST NOT guess anything about the structure of the data / files uploaded. Rather, you MUST perform some data exploration first.
51
+ - Example: User uploads an excel files and asks a question about it. First Read the data, explore the columns, columns types, etc. Then use the tool to answer the user's query.
52
+ In this case, you can simply call the tool multiple times.
53
+ - REMEMBER that you can always read the content of text, csv files if needed. In this case, you MUST always limit the amount of data displayed.
54
+ - If a tool step fails, you must recover as much as possible.
55
+ - After exhausting all possible solutions without success, inform the user of what was tried and request clarification/help.
56
+ """.strip()
57
+
58
+ # Used when the code-execution fence feature flag (UN-17972) is enabled.
59
+ # The frontend derives the artifact title from the filename itself, so the
60
+ # LLM no longer needs to produce a markdown heading before the sandbox link.
61
+ DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT_FENCE = """
62
+ Use this tool to run python code, e.g to generate plots, process excel files, perform calculations, etc.
63
+
64
+ Instructions:
65
+
66
+ Uploaded and generated files:
67
+ - All files uploaded to the chat are available at the path `/mnt/data/<filename>`.
68
+ - All files generated through code MUST be saved in the `/mnt/data` folder.
69
+
70
+ CRUCIAL Instructions for displaying images and files in the chat:
71
+ - Once files are generated in the `/mnt/data` folder you MUST reference them in the chat using markdown syntax in order to display them in the chat.
72
+ WHENEVER you reference a generated file, you MUST use the following format:
73
+ ```
74
+
75
+ [*Generating your {Graph/Chart/File}…*](sandbox:/mnt/data/<filename>)
76
+
77
+ ```
78
+ IMPORTANT: Do NOT append a leading `!` even when displaying an image.
79
+ IMPORTANT: ALWAYS place a blank line before AND after each file reference link so it stands on its own paragraph. Never place a file reference inline within a sentence or as part of a list item.
80
+ - Files are displayed as interactive components in the chat — images are shown inline, other files show the filename with an option to view the generating code and download the file.
81
+ - Not using syntax above will FAIL to show files to the user.
82
+ - YOU MUST use the syntax above to display files, otherwise the file will not be displayed in the chat.
83
+ - Only the following file types are allowed to be uploaded to the platform, anything else will FAIL: PDF, DOCX, XLSX, PPTX, CSV, HTML, MD, TXT, PNG, JPG, JPEG.
84
+ - You MUST always use this syntax, otherwise the files will not be displayed in the chat.
85
+
44
86
 
45
87
  # Displaying Dataframes/Tables:
46
88
  - Whenever asked to display a dataframe/table, it is CRITICAL to represent it faithfully as a markdown table in your response.
@@ -194,10 +194,17 @@ class DisplayCodeInterpreterFilesPostProcessor(
194
194
 
195
195
  # Files (including HTML when feature flag is disabled)
196
196
  else:
197
+ fence_ff_on = (
198
+ feature_flags.enable_code_execution_fence_un_17972.is_enabled(
199
+ self._company_id
200
+ )
201
+ )
197
202
  loop_response.message.text, replaced = _replace_container_file_citation(
198
203
  text=loop_response.message.text,
199
204
  filename=filename,
200
205
  content_id=content_id,
206
+ ref_number=ref_number,
207
+ use_content_link=fence_ff_on,
201
208
  )
202
209
  changed |= replaced
203
210
 
@@ -223,6 +230,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
223
230
  self._company_id
224
231
  ):
225
232
  code_blocks = _build_code_blocks(loop_response, self._content_map)
233
+ _warn_unmatched_code_blocks(self._content_map, code_blocks)
226
234
  text_before = loop_response.message.text
227
235
  loop_response.message.text = _inject_code_execution_fences(
228
236
  loop_response.message.text,
@@ -230,6 +238,12 @@ class DisplayCodeInterpreterFilesPostProcessor(
230
238
  )
231
239
  changed |= loop_response.message.text != text_before
232
240
 
241
+ _warn_missing_content_ids(loop_response.message.text, self._content_map)
242
+ loop_response.message.text, dangling_replaced = _replace_dangling_sandbox_links(
243
+ loop_response.message.text, self._config.file_download_failed_message
244
+ )
245
+ changed |= dangling_replaced
246
+
233
247
  return changed
234
248
 
235
249
  @override
@@ -395,6 +409,38 @@ def _inline_ref_pattern(file: CodeInterpreterFile) -> re.Pattern[str]:
395
409
  return re.compile(rf"\[{fname}\]\(unique://content/{cid}\)")
396
410
 
397
411
 
412
+ _FENCE_BLOCK_START = re.compile(
413
+ r"^[^\n`]+?(````(?:imgWithSource|fileWithSource)\()",
414
+ re.MULTILINE,
415
+ )
416
+
417
+ # Matches two consecutive fence blocks and normalises the gap between them to
418
+ # exactly one newline. Two cases are handled:
419
+ # - same line: any non-newline, non-backtick content (e.g. " and ", ", ")
420
+ # - cross-line: 1 or 2 newlines optionally surrounded by horizontal whitespace
421
+ # (list-item linebreak, or blank-line paragraph gap)
422
+ _CONSECUTIVE_FENCES_RE = re.compile(
423
+ r"(````(?:imgWithSource|fileWithSource)\([^\n]*\)````)"
424
+ r"(?:[^\n`]*|[ \t]*\n{1,2}[ \t]*)"
425
+ r"(?=````(?:imgWithSource|fileWithSource)\()"
426
+ )
427
+
428
+
429
+ def _ensure_fences_are_standalone(text: str) -> str:
430
+ """Strip any prefix text on the same line as a fence block.
431
+
432
+ The LLM sometimes puts file references inside list items or labels, e.g.:
433
+ - File: ````fileWithSource(...)````
434
+ After fence injection the label is left over. Strip it so the frontend
435
+ always receives the fence at the start of its own line, which is required
436
+ for correct parsing by the markdown renderer.
437
+
438
+ Only the prefix is removed; any trailing content after the closing `````
439
+ is preserved (it's unusual but not harmful).
440
+ """
441
+ return _FENCE_BLOCK_START.sub(r"\1", text)
442
+
443
+
398
444
  def _inject_code_execution_fences(
399
445
  text: str, code_blocks: list[CodeInterpreterBlock]
400
446
  ) -> str:
@@ -423,10 +469,20 @@ def _inject_code_execution_fences(
423
469
  text = new_text
424
470
  fence_id += 1
425
471
  any_fence_injected = True
472
+ else:
473
+ logger.warning(
474
+ "Fence injection skipped: no inline ref matched for '%s' "
475
+ "(content_id=%s); fence discarded. "
476
+ "The file was uploaded but will not appear in the message.",
477
+ file.filename,
478
+ file.content_id,
479
+ )
426
480
  # Remove duplicate refs (overwrite case)
427
481
  text = re.sub(pattern, "", text)
428
482
  if any_fence_injected:
429
483
  text = strip_executed_code_blocks(text)
484
+ text = _ensure_fences_are_standalone(text)
485
+ text = _CONSECUTIVE_FENCES_RE.sub(r"\1\n", text)
430
486
  return text
431
487
 
432
488
 
@@ -474,11 +530,90 @@ def _build_code_blocks(
474
530
  )
475
531
 
476
532
  # Step 3: build result preserving block execution order.
477
- return [
478
- CodeInterpreterBlock(code=calls[idx].code, files=list(files.values()))
479
- for idx, files in sorted(block_file_map.items())
480
- if calls[idx].code
481
- ]
533
+ result: list[CodeInterpreterBlock] = []
534
+ for idx, files in sorted(block_file_map.items()):
535
+ code = calls[idx].code
536
+ if code is not None:
537
+ result.append(
538
+ CodeInterpreterBlock(code=code or "", files=list(files.values()))
539
+ )
540
+ return result
541
+
542
+
543
+ def _warn_missing_content_ids(text: str, content_map: dict[str, str | None]) -> None:
544
+ """End-of-pipeline validation: warn for any uploaded file whose content_id is absent from text.
545
+
546
+ After all postprocessing stages have run every successfully uploaded file should
547
+ have its content_id referenced somewhere in the message text (either as a
548
+ unique://content/<id> link or embedded in a fence attribute). A missing content_id
549
+ means the file was uploaded but the user will never see it.
550
+ """
551
+ for filename, content_id in content_map.items():
552
+ if content_id is None:
553
+ continue
554
+ if content_id not in text:
555
+ logger.info(
556
+ "End-of-pipeline check: content_id '%s' for file '%s' is not present "
557
+ "in the final message text — the file was uploaded but will not be "
558
+ "visible to the user.",
559
+ content_id,
560
+ filename,
561
+ )
562
+
563
+
564
+ # Matches the full markdown link (including optional leading !) wrapping a sandbox URL,
565
+ # so the entire `[label](sandbox://...)` token can be replaced rather than just the URL.
566
+ _SANDBOX_MARKDOWN_LINK_RE = re.compile(r"!?\[.*?\]\(sandbox:/mnt/data/\S+?\)")
567
+
568
+
569
+ def _replace_dangling_sandbox_links(text: str, error_message: str) -> tuple[str, bool]:
570
+ """Replace any remaining sandbox:/mnt/data/ markdown links with an error message.
571
+
572
+ A dangling link means either the LLM hallucinated a file reference (the sandbox
573
+ link appears in the text but no matching container file annotation was emitted by
574
+ OpenAI), or the link format did not match the expected regex in stage-1. In both
575
+ cases the user would see a broken link; this function replaces each such link with
576
+ the configured error message and logs a warning so the incident is visible in logs.
577
+ """
578
+ matches = _SANDBOX_MARKDOWN_LINK_RE.findall(text)
579
+ if not matches:
580
+ return text, False
581
+ for match in matches:
582
+ logger.warning(
583
+ "Dangling sandbox link found in final text: '%s'. "
584
+ "The file was either never uploaded or the link format did not match "
585
+ "the expected pattern — replacing with error message.",
586
+ match,
587
+ )
588
+ return _SANDBOX_MARKDOWN_LINK_RE.sub(error_message, text), True
589
+
590
+
591
+ def _warn_unmatched_code_blocks(
592
+ content_map: dict[str, str | None],
593
+ code_blocks: list[CodeInterpreterBlock],
594
+ ) -> None:
595
+ """Warn for files that were uploaded but could not be matched to any code block.
596
+
597
+ When the fence feature flag is on, every uploaded file should map to a code block
598
+ via its /mnt/data/<filename> path so it can receive a fence. If a file is not
599
+ matched (e.g. the LLM used a variable for the output path rather than a literal
600
+ string) it falls back to a plain unique://content/ link with no code context.
601
+ The user can still download it, but the frontend artifact UI will not be shown.
602
+ """
603
+ fenced_filenames = {f.filename for block in code_blocks for f in block.files}
604
+ for filename, content_id in content_map.items():
605
+ if content_id is None:
606
+ continue
607
+ if filename not in fenced_filenames:
608
+ logger.warning(
609
+ "File '%s' (content_id=%s) could not be matched to any code block "
610
+ "(literal path '/mnt/data/%s' not found in executed code). "
611
+ "It will appear as a plain download link without code context — "
612
+ "consider re-running the query if the artifact UI is expected.",
613
+ filename,
614
+ content_id,
615
+ filename,
616
+ )
482
617
 
483
618
 
484
619
  def _get_next_ref_number(references: list[ContentReference]) -> int:
@@ -494,10 +629,14 @@ def _replace_container_file_error(
494
629
  image_markdown = rf"!?\[.*?\]\(sandbox:/mnt/data/{re.escape(filename)}\)"
495
630
 
496
631
  if not re.search(image_markdown, text):
497
- logger.info("No image markdown found for %s", filename)
632
+ logger.warning(
633
+ "No sandbox link found for '%s'; file was uploaded but the LLM did not "
634
+ "reference it — it will not be displayed.",
635
+ filename,
636
+ )
498
637
  return text, False
499
638
 
500
- logger.info("Displaying image %s", filename)
639
+ logger.info("Replacing failed download for '%s' with error message", filename)
501
640
  return re.sub(
502
641
  image_markdown,
503
642
  error_message,
@@ -511,10 +650,15 @@ def _replace_container_image_citation(
511
650
  image_markdown = rf"!?\[.*?\]\(sandbox:/mnt/data/{re.escape(filename)}\)"
512
651
 
513
652
  if not re.search(image_markdown, text):
514
- logger.info("No image markdown found for %s", filename)
653
+ logger.warning(
654
+ "No sandbox link found for image '%s' (content_id=%s); "
655
+ "file was uploaded but the LLM did not reference it — it will not be displayed.",
656
+ filename,
657
+ content_id,
658
+ )
515
659
  return text, False
516
660
 
517
- logger.info("Displaying image %s", filename)
661
+ logger.info("Inserting image citation for '%s'", filename)
518
662
  return re.sub(
519
663
  image_markdown,
520
664
  f"![image](unique://content/{content_id})",
@@ -528,10 +672,15 @@ def _replace_container_html_citation(
528
672
  html_markdown = rf"!?\[.*?\]\(sandbox:/mnt/data/{re.escape(filename)}\)"
529
673
 
530
674
  if not re.search(html_markdown, text):
531
- logger.info("No HTML markdown found for %s", filename)
675
+ logger.warning(
676
+ "No sandbox link found for HTML file '%s' (content_id=%s); "
677
+ "file was uploaded but the LLM did not reference it — it will not be displayed.",
678
+ filename,
679
+ content_id,
680
+ )
532
681
  return text, False
533
682
 
534
- logger.info("Displaying HTML %s", filename)
683
+ logger.info("Inserting HTML rendering block for '%s'", filename)
535
684
  html_rendering_block = f"""```HtmlRendering
536
685
  100%
537
686
  500px
@@ -547,17 +696,35 @@ unique://content/{content_id}
547
696
 
548
697
 
549
698
  def _replace_container_file_citation(
550
- text: str, filename: str, content_id: str
699
+ text: str,
700
+ filename: str,
701
+ content_id: str,
702
+ ref_number: int,
703
+ use_content_link: bool,
551
704
  ) -> tuple[str, bool]:
705
+ """Replace a sandbox file link with either an inline content link or a superscript ref.
706
+
707
+ When the fence feature flag is on (use_content_link=True), the sandbox link is
708
+ replaced with [filename](unique://content/{id}) so the subsequent fence injection
709
+ step can locate and wrap it. When the flag is off (use_content_link=False), the
710
+ original pre-fence behaviour is restored: the link is replaced with <sup>N</sup>
711
+ and the file remains accessible via the references panel.
712
+ """
552
713
  file_markdown = rf"\[.*?\]\(sandbox:/mnt/data/{re.escape(filename)}\)"
553
714
 
554
715
  if not re.search(file_markdown, text):
555
- logger.info("No file markdown found for %s", filename)
716
+ logger.warning(
717
+ "No sandbox link found for file '%s' (content_id=%s); "
718
+ "file was uploaded but the LLM did not reference it — it will not be displayed.",
719
+ filename,
720
+ content_id,
721
+ )
556
722
  return text, False
557
723
 
558
724
  logger.info("Displaying file %s", filename)
559
- return re.sub(
560
- file_markdown,
561
- f"[{filename}](unique://content/{content_id})",
562
- text,
563
- ), True
725
+ replacement = (
726
+ f"[{filename}](unique://content/{content_id})"
727
+ if use_content_link
728
+ else f"<sup>{ref_number}</sup>"
729
+ )
730
+ return re.sub(file_markdown, replacement, text), True
@@ -5,6 +5,7 @@ from openai import AsyncOpenAI, BaseModel, NotFoundError
5
5
  from openai.types.responses.tool_param import CodeInterpreter
6
6
 
7
7
  from unique_toolkit import ContentService, ShortTermMemoryService
8
+ from unique_toolkit.agentic.feature_flags.feature_flags import feature_flags
8
9
  from unique_toolkit.agentic.short_term_memory_manager.persistent_short_term_memory_manager import (
9
10
  PersistentShortMemoryManager,
10
11
  )
@@ -13,6 +14,8 @@ from unique_toolkit.agentic.tools.openai_builtin.base import (
13
14
  OpenAIBuiltInToolName,
14
15
  )
15
16
  from unique_toolkit.agentic.tools.openai_builtin.code_interpreter.config import (
17
+ DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT,
18
+ DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT_FENCE,
16
19
  OpenAICodeInterpreterConfig,
17
20
  )
18
21
  from unique_toolkit.agentic.tools.schemas import ToolPrompts
@@ -145,6 +148,7 @@ class OpenAICodeInterpreterTool(OpenAIBuiltInTool[CodeInterpreter]):
145
148
  self,
146
149
  config: OpenAICodeInterpreterConfig,
147
150
  container_id: str | None,
151
+ company_id: str = "",
148
152
  is_exclusive: bool = False,
149
153
  ) -> None:
150
154
  self._config = config
@@ -153,6 +157,7 @@ class OpenAICodeInterpreterTool(OpenAIBuiltInTool[CodeInterpreter]):
153
157
  raise ValueError("`container_id` required when not using `auto` containers")
154
158
 
155
159
  self._container_id = container_id
160
+ self._company_id = company_id
156
161
  self._is_exclusive = is_exclusive
157
162
 
158
163
  @property
@@ -196,7 +201,7 @@ class OpenAICodeInterpreterTool(OpenAIBuiltInTool[CodeInterpreter]):
196
201
  ) -> "OpenAICodeInterpreterTool":
197
202
  if config.use_auto_container:
198
203
  logger.info("Using `auto` container setting")
199
- return cls(config=config, container_id=None)
204
+ return cls(config=config, container_id=None, company_id=company_id)
200
205
 
201
206
  memory_manager = _get_container_code_execution_short_term_memory_manager(
202
207
  company_id=company_id,
@@ -229,16 +234,36 @@ class OpenAICodeInterpreterTool(OpenAIBuiltInTool[CodeInterpreter]):
229
234
  assert memory.container_id is not None
230
235
 
231
236
  return OpenAICodeInterpreterTool(
232
- config=config, container_id=memory.container_id, is_exclusive=is_exclusive
237
+ config=config,
238
+ container_id=memory.container_id,
239
+ company_id=company_id,
240
+ is_exclusive=is_exclusive,
233
241
  )
234
242
 
235
243
  @override
236
244
  def get_tool_prompts(self) -> ToolPrompts:
245
+ # When the fence feature flag is on the frontend derives the artifact title
246
+ # from the filename, so the LLM no longer needs to produce a markdown heading.
247
+ # We only substitute the fence-aware default when the operator has NOT
248
+ # customised the prompt — a custom value is always respected regardless of FF.
249
+ # When FF is off we always use the operator-configured prompt as-is.
250
+ fence_ff_on = feature_flags.enable_code_execution_fence_un_17972.is_enabled(
251
+ self._company_id
252
+ )
253
+ operator_customised = (
254
+ self._config.tool_description_for_system_prompt
255
+ != DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT
256
+ )
257
+ if fence_ff_on and not operator_customised:
258
+ system_prompt = DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT_FENCE
259
+ else:
260
+ system_prompt = self._config.tool_description_for_system_prompt
261
+
237
262
  return ToolPrompts(
238
263
  name="python", # https://platform.openai.com/docs/guides/tools-code-interpreter
239
264
  display_name=self.DISPLAY_NAME,
240
265
  tool_description=self._config.tool_description,
241
- tool_system_prompt=self._config.tool_description_for_system_prompt,
266
+ tool_system_prompt=system_prompt,
242
267
  tool_format_information_for_system_prompt="",
243
268
  tool_user_prompt=self._config.tool_description_for_user_prompt,
244
269
  tool_format_information_for_user_prompt="",