unique_toolkit 1.46.8__tar.gz → 1.46.10__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 (282) hide show
  1. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/CHANGELOG.md +8 -0
  2. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/PKG-INFO +9 -1
  3. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/pyproject.toml +1 -1
  4. unique_toolkit-1.46.10/unique_toolkit/_common/event_bus.py +102 -0
  5. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/tool.py +1 -1
  6. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/tool_manager.py +1 -0
  7. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/__init__.py +2 -0
  8. unique_toolkit-1.46.10/unique_toolkit/chat/cancellation.py +175 -0
  9. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/schemas.py +1 -0
  10. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/infos.py +21 -0
  11. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/schemas.py +1 -0
  12. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/services/chat_service.py +13 -1
  13. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/LICENSE +0 -0
  14. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/README.md +0 -0
  15. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/__init__.py +0 -0
  16. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/__init__.py +0 -0
  17. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/_base_service.py +0 -0
  18. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/_time_utils.py +0 -0
  19. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
  20. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
  21. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
  22. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
  23. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
  24. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
  25. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
  26. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/README.md +0 -0
  27. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/__init__.py +0 -0
  28. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/__main__.py +0 -0
  29. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/cli.py +0 -0
  30. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/differ.py +0 -0
  31. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/exporter.py +0 -0
  32. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/models.py +0 -0
  33. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/registry.py +0 -0
  34. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/config_checker/validator.py +0 -0
  35. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/default_language_model.py +0 -0
  36. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
  37. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/docx_generator/config.py +0 -0
  38. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
  39. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/docx_generator/service.py +0 -0
  40. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  41. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/endpoint_builder.py +0 -0
  42. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/endpoint_requestor.py +0 -0
  43. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/exception.py +0 -0
  44. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/execution.py +0 -0
  45. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
  46. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
  47. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
  48. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
  49. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
  50. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
  51. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
  52. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
  53. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
  54. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
  55. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
  56. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
  57. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
  58. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
  59. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
  60. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
  61. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
  62. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
  63. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
  64. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
  65. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
  66. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
  67. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
  68. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
  69. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
  70. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
  71. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
  72. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/feature_flags/schema.py +0 -0
  73. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
  74. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/pydantic_helpers.py +0 -0
  75. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/referencing.py +0 -0
  76. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/string_utilities.py +0 -0
  77. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/tests/test_referencing.py +0 -0
  78. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
  79. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/token/__init__.py +0 -0
  80. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/token/image_token_counting.py +0 -0
  81. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/token/token_counting.py +0 -0
  82. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
  83. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
  84. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/__init__.py +0 -0
  85. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/files.py +0 -0
  86. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/image/encode.py +0 -0
  87. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
  88. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/jinja/render.py +0 -0
  89. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
  90. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
  91. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
  92. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
  93. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/utils/write_configuration.py +0 -0
  94. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/validate_required_values.py +0 -0
  95. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/_common/validators.py +0 -0
  96. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/__init__.py +0 -0
  97. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
  98. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
  99. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/config.py +0 -0
  100. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
  101. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
  102. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
  103. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
  104. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
  105. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
  106. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/exception.py +0 -0
  107. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
  108. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
  109. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
  110. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
  111. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
  112. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
  113. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
  114. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
  115. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
  116. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
  117. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
  118. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
  119. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
  120. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
  121. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
  122. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
  123. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/evaluation/utils.py +0 -0
  124. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
  125. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
  126. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
  127. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
  128. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
  129. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/history_manager/utils.py +0 -0
  130. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
  131. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
  132. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
  133. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
  134. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
  135. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/base.py +0 -0
  136. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
  137. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
  138. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
  139. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
  140. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
  141. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
  142. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
  143. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
  144. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
  145. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
  146. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
  147. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
  148. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
  149. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
  150. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
  151. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
  152. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
  153. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
  154. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
  155. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/__init__.py +0 -0
  156. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
  157. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
  158. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
  159. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
  160. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
  161. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
  162. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
  163. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
  164. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
  165. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
  166. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
  167. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
  168. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
  169. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
  170. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
  171. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
  172. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
  173. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
  174. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
  175. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
  176. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
  177. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
  178. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
  179. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
  180. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
  181. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
  182. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
  183. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/config.py +0 -0
  184. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/factory.py +0 -0
  185. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
  186. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
  187. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
  188. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
  189. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
  190. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
  191. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
  192. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
  193. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
  194. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
  195. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/schemas.py +0 -0
  196. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
  197. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
  198. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
  199. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
  200. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  201. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
  202. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
  203. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
  204. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic_table/__init__.py +0 -0
  205. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic_table/schemas.py +0 -0
  206. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/agentic_table/service.py +0 -0
  207. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/__init__.py +0 -0
  208. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/dev_util.py +0 -0
  209. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/fast_api_factory.py +0 -0
  210. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/init_logging.py +0 -0
  211. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/init_sdk.py +0 -0
  212. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/performance/async_tasks.py +0 -0
  213. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/performance/async_wrapper.py +0 -0
  214. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/schemas.py +0 -0
  215. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/unique_settings.py +0 -0
  216. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/verification.py +0 -0
  217. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/app/webhook.py +0 -0
  218. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/constants.py +0 -0
  219. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/deprecated/service.py +0 -0
  220. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/functions.py +0 -0
  221. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/rendering.py +0 -0
  222. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/responses_api.py +0 -0
  223. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/service.py +0 -0
  224. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/state.py +0 -0
  225. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/chat/utils.py +0 -0
  226. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/content/__init__.py +0 -0
  227. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/content/constants.py +0 -0
  228. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/content/functions.py +0 -0
  229. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/content/schemas.py +0 -0
  230. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/content/service.py +0 -0
  231. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/content/smart_rules.py +0 -0
  232. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/content/utils.py +0 -0
  233. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/README.md +0 -0
  234. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/__init__.py +0 -0
  235. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
  236. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/augmented/service.py +0 -0
  237. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/base.py +0 -0
  238. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
  239. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/basic/config.py +0 -0
  240. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
  241. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/data_extraction/basic/service.py +0 -0
  242. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/elicitation/__init__.py +0 -0
  243. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/elicitation/constants.py +0 -0
  244. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/elicitation/exceptions.py +0 -0
  245. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/elicitation/functions.py +0 -0
  246. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/elicitation/schemas.py +0 -0
  247. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/elicitation/service.py +0 -0
  248. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/embedding/__init__.py +0 -0
  249. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/embedding/constants.py +0 -0
  250. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/embedding/functions.py +0 -0
  251. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/embedding/schemas.py +0 -0
  252. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/embedding/service.py +0 -0
  253. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/embedding/utils.py +0 -0
  254. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/framework_utilities/__init__.py +0 -0
  255. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
  256. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
  257. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
  258. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
  259. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/framework_utilities/openai/client.py +0 -0
  260. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
  261. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/framework_utilities/utils.py +0 -0
  262. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/__init__.py +0 -0
  263. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
  264. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/builder.py +0 -0
  265. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/constants.py +0 -0
  266. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/default_language_model.py +0 -0
  267. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/functions.py +0 -0
  268. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/prompt.py +0 -0
  269. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/reference.py +0 -0
  270. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/service.py +0 -0
  271. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/language_model/utils.py +0 -0
  272. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/protocols/support.py +0 -0
  273. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/services/__init__.py +0 -0
  274. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/services/knowledge_base.py +0 -0
  275. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/short_term_memory/__init__.py +0 -0
  276. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/short_term_memory/constants.py +0 -0
  277. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/short_term_memory/functions.py +0 -0
  278. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/short_term_memory/schemas.py +0 -0
  279. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/short_term_memory/service.py +0 -0
  280. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/smart_rules/__init__.py +0 -0
  281. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/smart_rules/compile.py +0 -0
  282. {unique_toolkit-1.46.8 → unique_toolkit-1.46.10}/unique_toolkit/test_utilities/events.py +0 -0
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.46.10] - 2026-02-19
9
+ - Add flag-based cancellation support via `CancellationWatcher` and `TypedEventBus`
10
+ - Expose `ChatService.cancellation` property for polling, event subscription, and `run_with_cancellation` helper
11
+ - Add `CancellationEvent`, `cancelled_at` on `ChatMessage`, and `stopped_by_user` on `LanguageModelStreamResponse`
12
+
13
+ ## [1.46.9] - 2026-02-19
14
+ - Add `litellm:anthropic-claude-sonnet-4-6` to `info.py`
15
+
8
16
  ## [1.46.8] - 2026-02-17
9
17
  - Add Configuration Check utility as class, CLI and CI workflow
10
18
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 1.46.8
3
+ Version: 1.46.10
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Cedric Klinkert
@@ -127,6 +127,14 @@ All notable changes to this project will be documented in this file.
127
127
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
128
128
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
129
129
 
130
+ ## [1.46.10] - 2026-02-19
131
+ - Add flag-based cancellation support via `CancellationWatcher` and `TypedEventBus`
132
+ - Expose `ChatService.cancellation` property for polling, event subscription, and `run_with_cancellation` helper
133
+ - Add `CancellationEvent`, `cancelled_at` on `ChatMessage`, and `stopped_by_user` on `LanguageModelStreamResponse`
134
+
135
+ ## [1.46.9] - 2026-02-19
136
+ - Add `litellm:anthropic-claude-sonnet-4-6` to `info.py`
137
+
130
138
  ## [1.46.8] - 2026-02-17
131
139
  - Add Configuration Check utility as class, CLI and CI workflow
132
140
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "unique_toolkit"
3
- version = "1.46.8"
3
+ version = "1.46.10"
4
4
  description = ""
5
5
  authors = [
6
6
  "Cedric Klinkert <cedric.klinkert@unique.ch>",
@@ -0,0 +1,102 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ from dataclasses import dataclass
6
+ from typing import Any, Awaitable, Callable, Generic, Protocol, TypeVar, Union
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ T = TypeVar("T")
11
+
12
+ AsyncHandler = Callable[[T], Awaitable[None]]
13
+ SyncHandler = Callable[[T], None]
14
+ Handler = Union[AsyncHandler[T], SyncHandler[T]]
15
+
16
+
17
+ class Subscription(Protocol):
18
+ """Handle returned by ``subscribe`` that allows unsubscribing."""
19
+
20
+ def cancel(self) -> None: ...
21
+
22
+
23
+ @dataclass(slots=True)
24
+ class _ListSubscription:
25
+ _cancel: Callable[[], None]
26
+ _active: bool = True
27
+
28
+ def cancel(self) -> None:
29
+ if not self._active:
30
+ return
31
+ self._active = False
32
+ self._cancel()
33
+
34
+
35
+ class TypedEventBus(Generic[T]):
36
+ """In-process, asyncio-friendly, typed pub/sub.
37
+
38
+ * ``subscribe(handler)`` — returns a :class:`Subscription`
39
+ * ``publish_and_wait(event)`` — synchronous: calls handlers directly,
40
+ schedules async handlers as tasks when a loop is running
41
+ * ``publish_and_forget_async(event)`` — fire-and-forget (schedules tasks)
42
+ * ``publish_and_wait_async(event)`` — awaits all handlers
43
+ """
44
+
45
+ __slots__ = ("_handlers",)
46
+
47
+ def __init__(self) -> None:
48
+ self._handlers: list[Handler[T]] = []
49
+
50
+ def subscribe(self, handler: Handler[T]) -> Subscription:
51
+ self._handlers.append(handler)
52
+
53
+ def _remove() -> None:
54
+ try:
55
+ self._handlers.remove(handler)
56
+ except ValueError:
57
+ pass
58
+
59
+ return _ListSubscription(_cancel=_remove)
60
+
61
+ async def _invoke(self, handler: Handler[T], event: T) -> None:
62
+ result: Any = handler(event)
63
+ if asyncio.iscoroutine(result):
64
+ await result
65
+
66
+ def publish_and_wait(self, event: T) -> None:
67
+ """Synchronous publish: call each handler directly.
68
+
69
+ Sync handlers are invoked inline. Async handlers are scheduled
70
+ as fire-and-forget tasks when a running event loop is detected;
71
+ otherwise they are skipped with a warning.
72
+ """
73
+ loop: asyncio.AbstractEventLoop | None = None
74
+ try:
75
+ loop = asyncio.get_running_loop()
76
+ except RuntimeError:
77
+ pass
78
+
79
+ for handler in list(self._handlers):
80
+ result: Any = handler(event)
81
+ if asyncio.iscoroutine(result):
82
+ if loop is not None:
83
+ loop.create_task(result)
84
+ else:
85
+ result.close()
86
+ logger.warning(
87
+ "Skipping async handler %r — no running event loop",
88
+ handler,
89
+ )
90
+
91
+ def publish_and_forget_async(self, event: T) -> list[asyncio.Task[None]]:
92
+ """Fire-and-forget: schedule each handler as a background task."""
93
+ loop = asyncio.get_running_loop()
94
+ return [loop.create_task(self._invoke(h, event)) for h in list(self._handlers)]
95
+
96
+ async def publish_and_wait_async(
97
+ self, event: T, *, return_exceptions: bool = False
98
+ ) -> None:
99
+ """Invoke every handler and await completion."""
100
+ coros = [self._invoke(h, event) for h in list(self._handlers)]
101
+ if coros:
102
+ await asyncio.gather(*coros, return_exceptions=return_exceptions)
@@ -52,7 +52,7 @@ class Tool(ABC, Generic[ConfigType]):
52
52
  """Whether the tool is enabled or not."""
53
53
  return self.settings.is_enabled
54
54
 
55
- def takes_control(self):
55
+ def takes_control(self) -> bool:
56
56
  """
57
57
  Some tools require to take control of the conversation with the user and do not want the orchestrator to intervene.
58
58
  this function indicates whether the tool takes control or not. It yanks the control away from the orchestrator.
@@ -255,6 +255,7 @@ class _ToolManager(Generic[_ApiMode]):
255
255
 
256
256
  # Wait until all tasks are finished
257
257
  tool_call_results = await asyncio.gather(*tasks)
258
+
258
259
  tool_call_results_unpacked: list[ToolCallResponse] = []
259
260
  for i, result in enumerate(tool_call_results):
260
261
  unpacked_tool_call_result = self._create_tool_call_response(
@@ -1,5 +1,7 @@
1
1
  import warnings
2
2
 
3
+ from .cancellation import CancellationEvent as CancellationEvent
4
+ from .cancellation import CancellationWatcher as CancellationWatcher
3
5
  from .constants import DOMAIN_NAME as DOMAIN_NAME
4
6
  from .schemas import ChatMessage as ChatMessage
5
7
  from .schemas import ChatMessageAssessment as ChatMessageAssessment
@@ -0,0 +1,175 @@
1
+ """Cancellation detection and notification for chat agent executions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import logging
7
+ from dataclasses import dataclass
8
+ from typing import Any, Coroutine, TypeVar, overload
9
+
10
+ import unique_sdk
11
+
12
+ from unique_toolkit._common.event_bus import TypedEventBus
13
+
14
+
15
+ @dataclass(frozen=True, slots=True)
16
+ class CancellationEvent:
17
+ """Published on the cancellation event bus when a user abort is detected."""
18
+
19
+ message_id: str
20
+
21
+ T = TypeVar("T")
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class CancellationWatcher:
27
+ """Polls the database for ``cancelledAt`` and publishes to an event bus.
28
+
29
+ The watcher never raises exceptions for cancellation. Instead it:
30
+ - publishes a :class:`CancellationEvent` on the bus
31
+ - sets :attr:`is_cancelled` to ``True``
32
+
33
+ Callers inspect :attr:`is_cancelled` to decide whether to stop.
34
+ """
35
+
36
+ def __init__(
37
+ self,
38
+ *,
39
+ user_id: str,
40
+ company_id: str,
41
+ chat_id: str,
42
+ assistant_message_id: str,
43
+ ) -> None:
44
+ self._bus: TypedEventBus[CancellationEvent] = TypedEventBus()
45
+ self._user_id = user_id
46
+ self._company_id = company_id
47
+ self._chat_id = chat_id
48
+ self._assistant_message_id = assistant_message_id
49
+ self._cancelled = False
50
+
51
+ @property
52
+ def is_cancelled(self) -> bool:
53
+ return self._cancelled
54
+
55
+ @property
56
+ def on_cancellation(self) -> TypedEventBus[CancellationEvent]:
57
+ return self._bus
58
+
59
+ async def check_cancellation_async(self) -> bool:
60
+ """Poll the DB once. Returns ``True`` if the message was cancelled.
61
+
62
+ When cancellation is detected for the first time, all subscribers
63
+ on the bus are notified (awaited) before this method returns.
64
+ """
65
+ if self._cancelled:
66
+ return True
67
+ try:
68
+ raw_msg = await unique_sdk.Message.retrieve_async(
69
+ user_id=self._user_id,
70
+ company_id=self._company_id,
71
+ id=self._assistant_message_id,
72
+ chatId=self._chat_id,
73
+ )
74
+ cancelled_at = getattr(raw_msg, "cancelledAt", None)
75
+ if cancelled_at is not None:
76
+ self._cancelled = True
77
+ event = CancellationEvent(message_id=self._assistant_message_id)
78
+ await self._bus.publish_and_wait_async(event)
79
+ return True
80
+ except Exception as exc:
81
+ logger.warning(
82
+ "Failed to check cancellation: %s: %s", type(exc).__name__, exc
83
+ )
84
+ return False
85
+
86
+ def check_cancellation(self) -> bool:
87
+ """Synchronous single-shot check.
88
+
89
+ Returns ``True`` if the message was cancelled. Subscribers are
90
+ notified via :meth:`TypedEventBus.publish_and_wait` (sync handlers
91
+ are called inline; async handlers are scheduled as tasks when a
92
+ running event loop is detected).
93
+ """
94
+ if self._cancelled:
95
+ return True
96
+ try:
97
+ raw_msg = unique_sdk.Message.retrieve(
98
+ user_id=self._user_id,
99
+ company_id=self._company_id,
100
+ id=self._assistant_message_id,
101
+ chatId=self._chat_id,
102
+ )
103
+ cancelled_at = getattr(raw_msg, "cancelledAt", None)
104
+ if cancelled_at is not None:
105
+ self._cancelled = True
106
+ event = CancellationEvent(message_id=self._assistant_message_id)
107
+ self._bus.publish_and_wait(event)
108
+ return True
109
+ except Exception as exc:
110
+ logger.warning(
111
+ "Failed to check cancellation: %s: %s", type(exc).__name__, exc
112
+ )
113
+ return False
114
+
115
+ @overload
116
+ async def run_with_cancellation(
117
+ self,
118
+ coroutine: Coroutine[Any, Any, T],
119
+ *,
120
+ poll_interval: float = ...,
121
+ cancel_result: T,
122
+ ) -> T: ...
123
+
124
+ @overload
125
+ async def run_with_cancellation(
126
+ self,
127
+ coroutine: Coroutine[Any, Any, T],
128
+ *,
129
+ poll_interval: float = ...,
130
+ ) -> T | None: ...
131
+
132
+ async def run_with_cancellation(
133
+ self,
134
+ coroutine: Coroutine[Any, Any, Any],
135
+ *,
136
+ poll_interval: float = 2.0,
137
+ cancel_result: Any = None,
138
+ ) -> Any:
139
+ """Run *coroutine* while polling for cancellation in the background.
140
+
141
+ When cancelled, subscribers are notified via the bus and
142
+ :attr:`is_cancelled` is set to ``True``.
143
+
144
+ Args:
145
+ coroutine: The async coroutine to execute.
146
+ poll_interval: How often (in seconds) to poll for cancellation.
147
+ cancel_result: Value to return when cancelled. When provided
148
+ the return type matches the coroutine's return type so
149
+ callers don't need a ``None`` check.
150
+
151
+ Returns:
152
+ The coroutine's result on success, or *cancel_result* if
153
+ cancelled (defaults to ``None``).
154
+ """
155
+ task = asyncio.create_task(coroutine)
156
+
157
+ async def _watcher() -> None:
158
+ while not task.done():
159
+ cancelled = await self.check_cancellation_async()
160
+ if cancelled:
161
+ task.cancel()
162
+ return
163
+ await asyncio.sleep(poll_interval)
164
+
165
+ watcher = asyncio.create_task(_watcher())
166
+ try:
167
+ return await task
168
+ except asyncio.CancelledError:
169
+ return cancel_result
170
+ finally:
171
+ watcher.cancel()
172
+ try:
173
+ await watcher
174
+ except asyncio.CancelledError:
175
+ pass
@@ -83,6 +83,7 @@ class ChatMessage(BaseModel):
83
83
  debug_info: dict | None = {}
84
84
  created_at: datetime | None = None
85
85
  completed_at: datetime | None = None
86
+ cancelled_at: datetime | None = None
86
87
  updated_at: datetime | None = None
87
88
  references: list[ContentReference] | None = None
88
89
 
@@ -57,6 +57,7 @@ class LanguageModelName(StrEnum):
57
57
  ANTHROPIC_CLAUDE_HAIKU_4_5 = "litellm:anthropic-claude-haiku-4-5"
58
58
  ANTHROPIC_CLAUDE_SONNET_4 = "litellm:anthropic-claude-sonnet-4"
59
59
  ANTHROPIC_CLAUDE_SONNET_4_5 = "litellm:anthropic-claude-sonnet-4-5"
60
+ ANTHROPIC_CLAUDE_SONNET_4_6 = "litellm:anthropic-claude-sonnet-4-6"
60
61
  ANTHROPIC_CLAUDE_OPUS_4 = "litellm:anthropic-claude-opus-4"
61
62
  ANTHROPIC_CLAUDE_OPUS_4_1 = "litellm:anthropic-claude-opus-4-1"
62
63
  ANTHROPIC_CLAUDE_OPUS_4_5 = "litellm:anthropic-claude-opus-4-5"
@@ -1139,6 +1140,26 @@ class LanguageModelInfo(BaseModel):
1139
1140
  info_cutoff_at=date(2025, 7, 1),
1140
1141
  published_at=date(2025, 9, 29),
1141
1142
  )
1143
+ case LanguageModelName.ANTHROPIC_CLAUDE_SONNET_4_6:
1144
+ return cls(
1145
+ name=model_name,
1146
+ capabilities=[
1147
+ ModelCapabilities.FUNCTION_CALLING,
1148
+ ModelCapabilities.STREAMING,
1149
+ ModelCapabilities.VISION,
1150
+ ModelCapabilities.REASONING,
1151
+ ],
1152
+ provider=LanguageModelProvider.LITELLM,
1153
+ version="claude-sonnet-4-6",
1154
+ encoder_name=EncoderName.O200K_BASE, # TODO: Update encoder with litellm
1155
+ token_limits=LanguageModelTokenLimits(
1156
+ # Input limit is 200_000, we leave 20_000 tokens as buffer due to tokenizer mismatch
1157
+ token_limit_input=180_000,
1158
+ token_limit_output=64_000,
1159
+ ),
1160
+ info_cutoff_at=date(2026, 1, 1),
1161
+ published_at=date(2026, 2, 17),
1162
+ )
1142
1163
  case LanguageModelName.ANTHROPIC_CLAUDE_OPUS_4:
1143
1164
  return cls(
1144
1165
  name=model_name,
@@ -168,6 +168,7 @@ class LanguageModelStreamResponse(BaseModel):
168
168
 
169
169
  message: LanguageModelStreamResponseMessage
170
170
  tool_calls: list[LanguageModelFunction] | None = None
171
+ stopped_by_user: bool = False
171
172
 
172
173
  def is_empty(self) -> bool:
173
174
  """
@@ -17,6 +17,7 @@ from pydantic import BaseModel
17
17
  from typing_extensions import deprecated
18
18
 
19
19
  from unique_toolkit._common.utils.files import is_file_content, is_image_content
20
+ from unique_toolkit.chat.cancellation import CancellationWatcher
20
21
  from unique_toolkit.chat.constants import (
21
22
  DEFAULT_MAX_MESSAGES,
22
23
  DEFAULT_PERCENT_OF_MAX_TOKENS,
@@ -114,13 +115,24 @@ class ChatService(ChatServiceDeprecated):
114
115
  super().__init__(*args, **kwargs)
115
116
  self._elicitation_service: ElicitationService | None = None
116
117
 
118
+ self._cancellation_watcher = CancellationWatcher(
119
+ user_id=self._user_id,
120
+ company_id=self._company_id,
121
+ chat_id=self._chat_id,
122
+ assistant_message_id=self._assistant_message_id,
123
+ )
124
+
125
+ @property
126
+ def cancellation(self) -> CancellationWatcher:
127
+ """Cancellation watcher for this chat session."""
128
+ return self._cancellation_watcher
129
+
117
130
  @property
118
131
  def elicitation(self) -> ElicitationService:
119
132
  """Get the ElicitationService for this chat session."""
120
133
  if self._elicitation_service is not None:
121
134
  return self._elicitation_service
122
135
 
123
- # Create the ElicitationService from the chat event (dynamically selects correlation or chat and message)
124
136
  self._elicitation_service = ElicitationService.from_chat_event(self._event)
125
137
 
126
138
  return self._elicitation_service