unique_toolkit 1.68.13__tar.gz → 1.69.1__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 (297) hide show
  1. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/PKG-INFO +3 -1
  2. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/pyproject.toml +4 -1
  3. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +260 -5
  4. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +13 -11
  5. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +7 -6
  6. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +4 -4
  7. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/fast_api_factory.py +15 -0
  8. unique_toolkit-1.69.1/unique_toolkit/monitoring/__init__.py +39 -0
  9. unique_toolkit-1.69.1/unique_toolkit/monitoring/middleware.py +90 -0
  10. unique_toolkit-1.69.1/unique_toolkit/monitoring/registry.py +107 -0
  11. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/README.md +0 -0
  12. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/__init__.py +0 -0
  13. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/__init__.py +0 -0
  14. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/_base_service.py +0 -0
  15. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/_time_utils.py +0 -0
  16. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
  17. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
  18. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
  19. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
  20. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
  21. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
  22. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
  23. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/README.md +0 -0
  24. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/__init__.py +0 -0
  25. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/__main__.py +0 -0
  26. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/cli.py +0 -0
  27. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/differ.py +0 -0
  28. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/exporter.py +0 -0
  29. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/models.py +0 -0
  30. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/registry.py +0 -0
  31. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/config_checker/validator.py +0 -0
  32. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/default_language_model.py +0 -0
  33. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
  34. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/docx_generator/config.py +0 -0
  35. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
  36. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
  37. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/docx_generator/service.py +0 -0
  38. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  39. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/endpoint_builder.py +0 -0
  40. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/endpoint_requestor.py +0 -0
  41. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/event_bus.py +0 -0
  42. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/exception.py +0 -0
  43. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/execution.py +0 -0
  44. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
  45. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
  46. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
  47. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
  48. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
  49. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
  50. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
  51. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
  52. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
  53. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
  54. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
  55. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
  56. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
  57. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
  58. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
  59. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
  60. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
  61. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
  62. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
  63. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
  64. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
  65. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
  66. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
  67. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
  68. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
  69. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
  70. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
  71. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/feature_flags/schema.py +0 -0
  72. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
  73. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/pydantic_helpers.py +0 -0
  74. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/referencing.py +0 -0
  75. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/string_utilities.py +0 -0
  76. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/tests/test_referencing.py +0 -0
  77. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
  78. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/token/__init__.py +0 -0
  79. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/token/image_token_counting.py +0 -0
  80. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/token/token_counting.py +0 -0
  81. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
  82. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
  83. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/__init__.py +0 -0
  84. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/files.py +0 -0
  85. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/image/encode.py +0 -0
  86. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
  87. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/jinja/render.py +0 -0
  88. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
  89. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
  90. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
  91. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
  92. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/utils/write_configuration.py +0 -0
  93. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/validate_required_values.py +0 -0
  94. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/_common/validators.py +0 -0
  95. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/__init__.py +0 -0
  96. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
  97. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
  98. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/config.py +0 -0
  99. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
  100. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
  101. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
  102. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
  103. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
  104. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
  105. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/exception.py +0 -0
  106. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
  107. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
  108. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
  109. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
  110. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
  111. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
  112. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
  113. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
  114. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
  115. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
  116. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
  117. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
  118. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
  119. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
  120. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
  121. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
  122. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/evaluation/utils.py +0 -0
  123. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
  124. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
  125. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
  126. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/history_manager/utils.py +0 -0
  127. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
  128. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
  129. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
  130. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
  131. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
  132. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/base.py +0 -0
  133. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
  134. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
  135. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
  136. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
  137. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
  138. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
  139. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
  140. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
  141. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
  142. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
  143. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
  144. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
  145. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
  146. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
  147. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
  148. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
  149. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
  150. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
  151. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
  152. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
  153. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/__init__.py +0 -0
  154. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
  155. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
  156. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
  157. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
  158. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
  159. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
  160. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
  161. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
  162. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
  163. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
  164. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
  165. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
  166. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
  167. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
  168. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
  169. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
  170. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
  171. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
  172. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
  173. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
  174. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
  175. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
  176. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
  177. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
  178. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
  179. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
  180. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
  181. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/config.py +0 -0
  182. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/experimental/__init__.py +0 -0
  183. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py +0 -0
  184. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/config.py +0 -0
  185. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py +0 -0
  186. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/tool.py +0 -0
  187. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/factory.py +0 -0
  188. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
  189. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
  190. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
  191. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
  192. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
  193. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
  194. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
  195. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
  196. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
  197. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +0 -0
  198. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
  199. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
  200. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
  201. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/schemas.py +0 -0
  202. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
  203. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
  204. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/tool.py +0 -0
  205. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
  206. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
  207. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
  208. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  209. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
  210. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
  211. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
  212. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic_table/__init__.py +0 -0
  213. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic_table/schemas.py +0 -0
  214. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/agentic_table/service.py +0 -0
  215. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/__init__.py +0 -0
  216. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/dev_util.py +0 -0
  217. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/init_logging.py +0 -0
  218. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/init_sdk.py +0 -0
  219. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/performance/async_tasks.py +0 -0
  220. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/performance/async_wrapper.py +0 -0
  221. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/schemas.py +0 -0
  222. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/unique_settings.py +0 -0
  223. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/verification.py +0 -0
  224. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/app/webhook.py +0 -0
  225. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/__init__.py +0 -0
  226. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/cancellation.py +0 -0
  227. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/constants.py +0 -0
  228. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/deprecated/service.py +0 -0
  229. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/functions.py +0 -0
  230. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/rendering.py +0 -0
  231. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/responses_api.py +0 -0
  232. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/schemas.py +0 -0
  233. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/service.py +0 -0
  234. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/state.py +0 -0
  235. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/chat/utils.py +0 -0
  236. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/content/__init__.py +0 -0
  237. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/content/constants.py +0 -0
  238. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/content/functions.py +0 -0
  239. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/content/schemas.py +0 -0
  240. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/content/service.py +0 -0
  241. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/content/smart_rules.py +0 -0
  242. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/content/utils.py +0 -0
  243. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/README.md +0 -0
  244. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/__init__.py +0 -0
  245. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
  246. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/augmented/service.py +0 -0
  247. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/base.py +0 -0
  248. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
  249. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/basic/config.py +0 -0
  250. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
  251. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/data_extraction/basic/service.py +0 -0
  252. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/elicitation/__init__.py +0 -0
  253. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/elicitation/constants.py +0 -0
  254. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/elicitation/exceptions.py +0 -0
  255. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/elicitation/functions.py +0 -0
  256. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/elicitation/schemas.py +0 -0
  257. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/elicitation/service.py +0 -0
  258. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/embedding/__init__.py +0 -0
  259. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/embedding/constants.py +0 -0
  260. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/embedding/functions.py +0 -0
  261. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/embedding/schemas.py +0 -0
  262. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/embedding/service.py +0 -0
  263. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/embedding/utils.py +0 -0
  264. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/framework_utilities/__init__.py +0 -0
  265. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
  266. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
  267. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
  268. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
  269. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/framework_utilities/openai/client.py +0 -0
  270. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
  271. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/framework_utilities/utils.py +0 -0
  272. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/__init__.py +0 -0
  273. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
  274. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/builder.py +0 -0
  275. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/constants.py +0 -0
  276. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/default_language_model.py +0 -0
  277. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/functions.py +0 -0
  278. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/infos.py +0 -0
  279. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/prompt.py +0 -0
  280. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/reference.py +0 -0
  281. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/schemas.py +0 -0
  282. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/service.py +0 -0
  283. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/stream_transform.py +0 -0
  284. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/language_model/utils.py +0 -0
  285. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/protocols/support.py +0 -0
  286. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/services/__init__.py +0 -0
  287. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/services/chat_service.py +0 -0
  288. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/services/factory.py +0 -0
  289. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/services/knowledge_base.py +0 -0
  290. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/short_term_memory/__init__.py +0 -0
  291. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/short_term_memory/constants.py +0 -0
  292. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/short_term_memory/functions.py +0 -0
  293. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/short_term_memory/schemas.py +0 -0
  294. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/short_term_memory/service.py +0 -0
  295. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/smart_rules/__init__.py +0 -0
  296. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/unique_toolkit/smart_rules/compile.py +0 -0
  297. {unique_toolkit-1.68.13 → unique_toolkit-1.69.1}/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.13
3
+ Version: 1.69.1
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>
@@ -38,9 +38,11 @@ Requires-Dist: openai>=1.105.0,<2 ; extra == 'langchain'
38
38
  Requires-Dist: langchain>=1.0.0,<2 ; extra == 'langchain'
39
39
  Requires-Dist: langchain-openai>=0.3.28 ; extra == 'langchain'
40
40
  Requires-Dist: langchain-core>=1.0.0,<2 ; extra == 'langchain'
41
+ Requires-Dist: prometheus-client>=0.24.1,<1 ; extra == 'monitoring'
41
42
  Requires-Python: >=3.12
42
43
  Provides-Extra: fastapi
43
44
  Provides-Extra: langchain
45
+ Provides-Extra: monitoring
44
46
  Description-Content-Type: text/markdown
45
47
 
46
48
  # Unique Toolkit
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique_toolkit"
3
- version = "1.68.13"
3
+ version = "1.69.1"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -57,6 +57,9 @@ fastapi = [
57
57
  "starlette>=0.49.1",
58
58
  "uvicorn>=0.37.0,<0.38",
59
59
  ]
60
+ monitoring = [
61
+ "prometheus_client>=0.24.1,<1",
62
+ ]
60
63
 
61
64
  [build-system]
62
65
  requires = ["uv_build>=0.8.14,<0.9.0"]
@@ -6,7 +6,7 @@ import mimetypes
6
6
  from datetime import datetime
7
7
  from enum import StrEnum
8
8
  from itertools import groupby
9
- from typing import TYPE_CHECKING
9
+ from typing import TYPE_CHECKING, Iterator
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from unique_toolkit.content.schemas import ContentChunk
@@ -77,7 +77,7 @@ class ChatHistoryWithContent(RootModel):
77
77
 
78
78
  return cls(root=grouped_elements)
79
79
 
80
- def __iter__(self):
80
+ def __iter__(self) -> Iterator[ChatMessageWithContents]:
81
81
  return iter(self.root)
82
82
 
83
83
  def __getitem__(self, item):
@@ -94,7 +94,7 @@ def get_chat_history_with_contents(
94
94
  id=user_message.id,
95
95
  chat_id=chat_id,
96
96
  text=user_message.text,
97
- originalText=user_message.original_text,
97
+ original_text=user_message.original_text,
98
98
  role=ChatRole.USER,
99
99
  gpt_request=None,
100
100
  created_at=datetime.fromisoformat(user_message.created_at),
@@ -118,6 +118,41 @@ def get_chat_history_with_contents(
118
118
  )
119
119
 
120
120
 
121
+ async def get_chat_history_with_contents_async(
122
+ *,
123
+ user_message: ChatEventUserMessage,
124
+ chat_id: str,
125
+ chat_history: list[ChatMessage],
126
+ content_service: ContentService,
127
+ ) -> ChatHistoryWithContent:
128
+ last_user_message = ChatMessage(
129
+ id=user_message.id,
130
+ chat_id=chat_id,
131
+ text=user_message.text,
132
+ original_text=user_message.original_text,
133
+ role=ChatRole.USER,
134
+ gpt_request=None,
135
+ created_at=datetime.fromisoformat(user_message.created_at),
136
+ )
137
+ if len(chat_history) > 0 and last_user_message.id == chat_history[-1].id:
138
+ pass
139
+ else:
140
+ chat_history.append(last_user_message)
141
+
142
+ chat_contents = await content_service.search_contents_async(
143
+ where={
144
+ "ownerId": {
145
+ "equals": chat_id,
146
+ },
147
+ },
148
+ )
149
+
150
+ return ChatHistoryWithContent.from_chat_history_and_contents(
151
+ chat_history,
152
+ chat_contents,
153
+ )
154
+
155
+
121
156
  def download_encoded_images(
122
157
  contents: list[Content],
123
158
  content_service: ContentService,
@@ -141,6 +176,30 @@ def download_encoded_images(
141
176
  return base64_encoded_images
142
177
 
143
178
 
179
+ async def download_encoded_images_async(
180
+ *,
181
+ contents: list[Content],
182
+ content_service: ContentService,
183
+ chat_id: str,
184
+ ) -> list[str]:
185
+ base64_encoded_images = []
186
+ for im in contents:
187
+ if FileUtils.is_image_content(im.key):
188
+ try:
189
+ file_bytes = await content_service.download_content_to_bytes_async(
190
+ content_id=im.id,
191
+ chat_id=chat_id,
192
+ )
193
+
194
+ mime_type, _ = mimetypes.guess_type(im.key)
195
+ encoded_string = base64.b64encode(file_bytes).decode("utf-8")
196
+ image_string = f"data:{mime_type};base64," + encoded_string
197
+ base64_encoded_images.append(image_string)
198
+ except Exception as e:
199
+ _LOGGER.warning("Failed to download image %s: %s", im.key, e)
200
+ return base64_encoded_images
201
+
202
+
144
203
  class FileContentSerialization(StrEnum):
145
204
  NONE = "none"
146
205
  FILE_NAME = "file_name"
@@ -212,6 +271,49 @@ def _append_element_to_builder(
212
271
  )
213
272
 
214
273
 
274
+ async def _append_element_to_builder_async(
275
+ builder: MessagesBuilder,
276
+ *,
277
+ c: ChatMessageWithContents,
278
+ text: str,
279
+ include_images: ImageContentInclusion,
280
+ file_content_serialization_type: FileContentSerialization,
281
+ content_service: ContentService,
282
+ chat_id: str,
283
+ ) -> None:
284
+ if len(c.contents) > 0:
285
+ file_contents = [co for co in c.contents if FileUtils.is_file_content(co.key)]
286
+ image_contents = [co for co in c.contents if FileUtils.is_image_content(co.key)]
287
+ content = (
288
+ text
289
+ + "\n\n"
290
+ + file_content_serialization(
291
+ file_contents,
292
+ file_content_serialization_type,
293
+ )
294
+ ).strip()
295
+ if include_images and len(image_contents) > 0:
296
+ builder.image_message_append(
297
+ content=content,
298
+ images=await download_encoded_images_async(
299
+ contents=image_contents,
300
+ content_service=content_service,
301
+ chat_id=chat_id,
302
+ ),
303
+ role=map_chat_llm_message_role[c.role],
304
+ )
305
+ else:
306
+ builder.message_append(
307
+ role=map_chat_llm_message_role[c.role],
308
+ content=content,
309
+ )
310
+ else:
311
+ builder.message_append(
312
+ role=map_chat_llm_message_role[c.role],
313
+ content=text,
314
+ )
315
+
316
+
215
317
  def get_full_history_with_contents(
216
318
  user_message: ChatEventUserMessage,
217
319
  chat_id: str,
@@ -228,7 +330,7 @@ def get_full_history_with_contents(
228
330
  )
229
331
 
230
332
  builder = LanguageModelMessages([]).builder()
231
- for c in grouped_elements:
333
+ for c in grouped_elements.root:
232
334
  # LanguageModelUserMessage has no field original_text
233
335
  text = c.original_text if c.original_text else c.content
234
336
  if text is None:
@@ -249,6 +351,43 @@ def get_full_history_with_contents(
249
351
  return builder.build()
250
352
 
251
353
 
354
+ async def get_full_history_with_contents_async(
355
+ *,
356
+ user_message: ChatEventUserMessage,
357
+ chat_id: str,
358
+ chat_service: ChatService,
359
+ content_service: ContentService,
360
+ include_images: ImageContentInclusion = ImageContentInclusion.ALL,
361
+ file_content_serialization_type: FileContentSerialization = FileContentSerialization.FILE_NAME,
362
+ ) -> LanguageModelMessages:
363
+ grouped_elements = await get_chat_history_with_contents_async(
364
+ user_message=user_message,
365
+ chat_id=chat_id,
366
+ chat_history=await chat_service.get_full_history_async(),
367
+ content_service=content_service,
368
+ )
369
+
370
+ builder = LanguageModelMessages([]).builder()
371
+ for c in grouped_elements.root:
372
+ text = c.original_text if c.original_text else c.content
373
+ if text is None:
374
+ if c.role == ChatRole.USER:
375
+ raise ValueError(
376
+ "Content or original_text of LanguageModelMessages should exist.",
377
+ )
378
+ text = ""
379
+ await _append_element_to_builder_async(
380
+ builder=builder,
381
+ c=c,
382
+ text=text,
383
+ include_images=include_images,
384
+ file_content_serialization_type=file_content_serialization_type,
385
+ content_service=content_service,
386
+ chat_id=chat_id,
387
+ )
388
+ return builder.build()
389
+
390
+
252
391
  def get_full_history_with_contents_and_tool_calls(
253
392
  *,
254
393
  user_message: ChatEventUserMessage,
@@ -307,7 +446,7 @@ def get_full_history_with_contents_and_tool_calls(
307
446
  )
308
447
 
309
448
  builder = LanguageModelMessages([]).builder()
310
- for c in grouped_elements:
449
+ for c in grouped_elements.root:
311
450
  text = c.original_text if c.original_text else c.content
312
451
  if text is None:
313
452
  if c.role == ChatRole.USER:
@@ -391,6 +530,122 @@ def get_full_history_with_contents_and_tool_calls(
391
530
  return builder.build(), max_source_number, source_map
392
531
 
393
532
 
533
+ async def get_full_history_with_contents_and_tool_calls_async(
534
+ *,
535
+ user_message: ChatEventUserMessage,
536
+ chat_id: str,
537
+ chat_service: ChatService,
538
+ content_service: ContentService,
539
+ include_images: ImageContentInclusion = ImageContentInclusion.ALL,
540
+ file_content_serialization_type: FileContentSerialization = FileContentSerialization.FILE_NAME,
541
+ ) -> tuple[LanguageModelMessages, int, dict[int, "ContentChunk"]]:
542
+ """Async version of get_full_history_with_contents_and_tool_calls."""
543
+ from unique_toolkit.agentic.history_manager.utils import (
544
+ build_source_map_from_tool_calls,
545
+ compute_max_source_number_from_tool_calls,
546
+ )
547
+ from unique_toolkit.content.schemas import (
548
+ ContentChunk as ContentChunk, # noqa: F811
549
+ )
550
+
551
+ chat_history = await chat_service.get_full_history_async()
552
+
553
+ assistant_message_ids = [
554
+ msg.id for msg in chat_history if msg.role == ChatRole.ASSISTANT and msg.id
555
+ ]
556
+ all_tool_calls: list[ChatMessageTool] = []
557
+ tool_calls_by_message: dict[str, list[ChatMessageTool]] = {}
558
+ if assistant_message_ids:
559
+ try:
560
+ all_tool_calls = await chat_service.get_message_tools_async(
561
+ message_ids=assistant_message_ids,
562
+ )
563
+ for tc in all_tool_calls:
564
+ if tc.message_id:
565
+ tool_calls_by_message.setdefault(tc.message_id, []).append(tc)
566
+ except Exception:
567
+ _LOGGER.warning(
568
+ "Failed to batch-load tool calls, falling back to empty", exc_info=True
569
+ )
570
+ max_source_number = compute_max_source_number_from_tool_calls(all_tool_calls)
571
+ source_map: dict[int, ContentChunk] = build_source_map_from_tool_calls(
572
+ all_tool_calls
573
+ )
574
+
575
+ grouped_elements = await get_chat_history_with_contents_async(
576
+ user_message=user_message,
577
+ chat_id=chat_id,
578
+ chat_history=chat_history,
579
+ content_service=content_service,
580
+ )
581
+
582
+ builder = LanguageModelMessages([]).builder()
583
+ for c in grouped_elements.root:
584
+ text = c.original_text if c.original_text else c.content
585
+ if text is None:
586
+ if c.role == ChatRole.USER:
587
+ raise ValueError(
588
+ "Content or original_text of LanguageModelMessages should exist.",
589
+ )
590
+ text = ""
591
+
592
+ if c.role == ChatRole.ASSISTANT and c.id and c.id in tool_calls_by_message:
593
+ tc_records = sorted(
594
+ tool_calls_by_message[c.id],
595
+ key=lambda tc: (tc.round_index, tc.sequence_index),
596
+ )
597
+ if tc_records:
598
+ for _round, round_group in groupby(
599
+ tc_records, key=lambda tc: tc.round_index
600
+ ):
601
+ round_tcs = list(round_group)
602
+ round_tcs_with_response = [
603
+ tc
604
+ for tc in round_tcs
605
+ if tc.response and tc.response.content is not None
606
+ ]
607
+ if not round_tcs_with_response:
608
+ continue
609
+ fns = [
610
+ LanguageModelFunction(
611
+ id=tc.external_tool_call_id,
612
+ name=tc.function_name,
613
+ arguments=tc.arguments,
614
+ )
615
+ for tc in round_tcs_with_response
616
+ ]
617
+ builder.messages.append(
618
+ LanguageModelAssistantMessage.from_functions(tool_calls=fns)
619
+ )
620
+ for fn, tc in zip(fns, round_tcs_with_response):
621
+ builder.messages.append(
622
+ LanguageModelToolMessage(
623
+ tool_call_id=fn.id,
624
+ content=tc.response.content, # type: ignore[union-attr]
625
+ name=tc.function_name,
626
+ )
627
+ )
628
+
629
+ had_tool_calls = (
630
+ c.role == ChatRole.ASSISTANT
631
+ and c.id is not None
632
+ and c.id in tool_calls_by_message
633
+ )
634
+ if had_tool_calls and not text:
635
+ continue
636
+
637
+ await _append_element_to_builder_async(
638
+ builder=builder,
639
+ c=c,
640
+ text=text,
641
+ include_images=include_images,
642
+ file_content_serialization_type=file_content_serialization_type,
643
+ content_service=content_service,
644
+ chat_id=chat_id,
645
+ )
646
+ return builder.build(), max_source_number, source_map
647
+
648
+
394
649
  def get_full_history_as_llm_messages(
395
650
  chat_service: ChatService,
396
651
  ) -> LanguageModelMessages:
@@ -10,8 +10,8 @@ from unique_toolkit._common.token.token_counting import (
10
10
  from unique_toolkit._common.validators import LMI
11
11
  from unique_toolkit.agentic.history_manager.history_construction_with_contents import (
12
12
  FileContentSerialization,
13
- get_full_history_with_contents,
14
- get_full_history_with_contents_and_tool_calls,
13
+ get_full_history_with_contents_and_tool_calls_async,
14
+ get_full_history_with_contents_async,
15
15
  )
16
16
  from unique_toolkit.agentic.history_manager.utils import serialize_tool_content_json
17
17
  from unique_toolkit.agentic.reference_manager.reference_manager import ReferenceManager
@@ -312,19 +312,21 @@ class LoopTokenReducer:
312
312
  else FileContentSerialization.FILE_NAME
313
313
  )
314
314
  if self._enable_tool_call_persistence:
315
- full_history, max_src, src_map = (
316
- get_full_history_with_contents_and_tool_calls(
317
- user_message=self._user_message,
318
- chat_id=self._chat_id,
319
- chat_service=self._chat_service,
320
- content_service=self._content_service,
321
- file_content_serialization_type=file_content_serialization_type,
322
- )
315
+ (
316
+ full_history,
317
+ max_src,
318
+ src_map,
319
+ ) = await get_full_history_with_contents_and_tool_calls_async(
320
+ user_message=self._user_message,
321
+ chat_id=self._chat_id,
322
+ chat_service=self._chat_service,
323
+ content_service=self._content_service,
324
+ file_content_serialization_type=file_content_serialization_type,
323
325
  )
324
326
  self._max_db_source_number = max_src
325
327
  self._db_source_map = src_map
326
328
  else:
327
- full_history = get_full_history_with_contents(
329
+ full_history = await get_full_history_with_contents_async(
328
330
  user_message=self._user_message,
329
331
  chat_id=self._chat_id,
330
332
  chat_service=self._chat_service,
@@ -65,7 +65,7 @@ class QwenLoopIterationRunner(BasicLoopIterationRunner):
65
65
  loop_runner_kwargs=kwargs,
66
66
  prepare_loop_runner_kwargs=_prepare,
67
67
  )
68
- return self._process_response(response)
68
+ return await self._process_response(response)
69
69
 
70
70
  async def _handle_last_iteration(
71
71
  self, **kwargs: Unpack[_LoopIterationRunnerKwargs]
@@ -78,22 +78,23 @@ class QwenLoopIterationRunner(BasicLoopIterationRunner):
78
78
  last_iteration_instruction=self._last_iteration_instruction,
79
79
  )
80
80
  response = await super()._handle_last_iteration(**kwargs)
81
- return self._process_response(response)
81
+ return await self._process_response(response)
82
82
 
83
83
  async def _handle_normal_iteration(
84
84
  self, **kwargs: Unpack[_LoopIterationRunnerKwargs]
85
85
  ) -> LanguageModelStreamResponse:
86
86
  response = await super()._handle_normal_iteration(**kwargs)
87
- return self._process_response(response)
87
+ return await self._process_response(response)
88
88
 
89
- def _process_response(
89
+ async def _process_response(
90
90
  self, response: LanguageModelStreamResponse
91
91
  ) -> LanguageModelStreamResponse:
92
- if "</tool_call>" == response.message.text.strip():
92
+ message_text = response.message.text or ""
93
+ if "</tool_call>" == message_text.strip():
93
94
  _LOGGER.warning(
94
95
  "Response contains only <tool_call>. This is not allowed. Returning empty response."
95
96
  )
96
- self._chat_service.modify_assistant_message(content="")
97
+ await self._chat_service.modify_assistant_message_async(content="")
97
98
  response.message.text = ""
98
99
 
99
100
  return response
@@ -377,7 +377,10 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
377
377
  async def _call_mcp_tool_via_sdk(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
378
378
  """Call MCP tool via SDK to public API"""
379
379
  try:
380
- result = unique_sdk.MCP.call_tool(
380
+ self.logger.info(
381
+ f"Calling MCP tool {self.name} with arguments: {arguments}"
382
+ )
383
+ result = await unique_sdk.MCP.call_tool_async(
381
384
  user_id=self._event.user_id,
382
385
  company_id=self._event.company_id,
383
386
  name=self.name,
@@ -386,9 +389,6 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
386
389
  arguments=arguments,
387
390
  )
388
391
 
389
- self.logger.info(
390
- f"Calling MCP tool {self.name} with arguments: {arguments}"
391
- )
392
392
  self.logger.debug(f"Result: {result}")
393
393
 
394
394
  return result
@@ -63,6 +63,21 @@ def build_unique_custom_app(
63
63
  """Health check endpoint."""
64
64
  return JSONResponse(content={"status": "healthy", "service": title})
65
65
 
66
+ from unique_toolkit.monitoring import _MONITORING_AVAILABLE
67
+
68
+ if _MONITORING_AVAILABLE:
69
+ from starlette.responses import Response as StarletteResponse
70
+
71
+ from unique_toolkit.monitoring import get_metrics
72
+
73
+ @app.get(path="/metrics")
74
+ async def metrics_endpoint() -> StarletteResponse:
75
+ """Prometheus metrics endpoint."""
76
+ return StarletteResponse(
77
+ content=get_metrics(),
78
+ media_type="text/plain; version=0.0.4; charset=utf-8",
79
+ )
80
+
66
81
  @app.post(path=webhook_path)
67
82
  async def webhook_handler(
68
83
  request: Request, background_tasks: BackgroundTasks
@@ -0,0 +1,39 @@
1
+ try:
2
+ from prometheus_client import CollectorRegistry # noqa: F401
3
+
4
+ _MONITORING_AVAILABLE = True
5
+ except ImportError:
6
+ _MONITORING_AVAILABLE = False
7
+
8
+
9
+ def _check_monitoring_available() -> None:
10
+ if not _MONITORING_AVAILABLE:
11
+ raise ImportError(
12
+ "prometheus_client is not installed. "
13
+ "Install it with: pip install unique_toolkit[monitoring]"
14
+ )
15
+
16
+
17
+ if _MONITORING_AVAILABLE:
18
+ from unique_toolkit.monitoring.middleware import MetricsMiddleware
19
+ from unique_toolkit.monitoring.registry import (
20
+ REGISTRY,
21
+ MetricNamespace,
22
+ get_metrics,
23
+ metric_scope,
24
+ track_execution,
25
+ )
26
+
27
+ __all__ = [
28
+ "REGISTRY",
29
+ "MetricNamespace",
30
+ "MetricsMiddleware",
31
+ "get_metrics",
32
+ "metric_scope",
33
+ "track_execution",
34
+ "_MONITORING_AVAILABLE",
35
+ ]
36
+ else:
37
+
38
+ def __getattr__(name: str):
39
+ _check_monitoring_available()
@@ -0,0 +1,90 @@
1
+ from __future__ import annotations
2
+
3
+ import time
4
+
5
+ from prometheus_client import Counter, Gauge, Histogram
6
+
7
+ from .registry import REGISTRY
8
+
9
+ _http_requests_total = Counter(
10
+ "http_requests_total",
11
+ "Total HTTP requests",
12
+ ["method", "path", "status_code"],
13
+ registry=REGISTRY,
14
+ )
15
+ _http_request_duration_seconds = Histogram(
16
+ "http_request_duration_seconds",
17
+ "HTTP request duration",
18
+ ["method", "path"],
19
+ registry=REGISTRY,
20
+ )
21
+ _http_requests_in_progress = Gauge(
22
+ "http_requests_in_progress",
23
+ "In-flight HTTP requests",
24
+ ["method"],
25
+ registry=REGISTRY,
26
+ )
27
+
28
+ _DEFAULT_EXCLUDED_PATHS = frozenset({"/health", "/metrics", "/"})
29
+
30
+
31
+ class MetricsMiddleware:
32
+ """ASGI middleware that tracks HTTP request metrics.
33
+
34
+ Works with any ASGI app (FastAPI, Quart, Starlette).
35
+
36
+ Handles:
37
+ - Non-HTTP scopes (WebSocket, lifespan) — passed through, not tracked
38
+ - Excluded paths (health, metrics) — passed through, not tracked
39
+ - App exceptions — duration + error still recorded, in-progress gauge cleaned up
40
+ - Streaming responses — status captured from first http.response.start message
41
+
42
+ Usage::
43
+
44
+ # FastAPI
45
+ app.add_middleware(MetricsMiddleware)
46
+
47
+ # Quart
48
+ app.asgi_app = MetricsMiddleware(app.asgi_app)
49
+ """
50
+
51
+ def __init__(self, app, excluded_paths: set[str] | None = None):
52
+ self.app = app
53
+ self._excluded_paths = (
54
+ excluded_paths if excluded_paths is not None else _DEFAULT_EXCLUDED_PATHS
55
+ )
56
+
57
+ async def __call__(self, scope, receive, send):
58
+ # Pass through non-HTTP (WebSocket, lifespan)
59
+ if scope["type"] != "http":
60
+ return await self.app(scope, receive, send)
61
+
62
+ path = scope.get("path", "/")
63
+
64
+ # Pass through excluded paths (health checks, metrics endpoint)
65
+ if path in self._excluded_paths:
66
+ return await self.app(scope, receive, send)
67
+
68
+ method = scope.get("method", "UNKNOWN")
69
+ status_code = "500" # Default if app crashes before sending response
70
+
71
+ _http_requests_in_progress.labels(method=method).inc()
72
+ start = time.perf_counter()
73
+
74
+ async def send_wrapper(message):
75
+ nonlocal status_code
76
+ if message["type"] == "http.response.start":
77
+ status_code = str(message["status"])
78
+ await send(message)
79
+
80
+ try:
81
+ await self.app(scope, receive, send_wrapper)
82
+ finally:
83
+ duration = time.perf_counter() - start
84
+ _http_requests_in_progress.labels(method=method).dec()
85
+ _http_request_duration_seconds.labels(method=method, path=path).observe(
86
+ duration
87
+ )
88
+ _http_requests_total.labels(
89
+ method=method, path=path, status_code=status_code
90
+ ).inc()