unique_toolkit 1.62.3__tar.gz → 1.63.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/PKG-INFO +1 -1
  2. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/pyproject.toml +1 -1
  3. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +25 -3
  4. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/history_manager/history_manager.py +58 -39
  5. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +21 -83
  6. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/history_manager/utils.py +73 -1
  7. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/functions.py +5 -14
  8. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/README.md +0 -0
  9. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/__init__.py +0 -0
  10. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/__init__.py +0 -0
  11. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/_base_service.py +0 -0
  12. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/_time_utils.py +0 -0
  13. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
  14. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
  15. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
  16. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
  17. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
  18. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
  19. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
  20. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/README.md +0 -0
  21. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/__init__.py +0 -0
  22. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/__main__.py +0 -0
  23. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/cli.py +0 -0
  24. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/differ.py +0 -0
  25. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/exporter.py +0 -0
  26. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/models.py +0 -0
  27. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/registry.py +0 -0
  28. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/config_checker/validator.py +0 -0
  29. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/default_language_model.py +0 -0
  30. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
  31. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/docx_generator/config.py +0 -0
  32. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
  33. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
  34. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/docx_generator/service.py +0 -0
  35. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  36. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/endpoint_builder.py +0 -0
  37. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/endpoint_requestor.py +0 -0
  38. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/event_bus.py +0 -0
  39. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/exception.py +0 -0
  40. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/execution.py +0 -0
  41. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
  42. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
  43. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
  44. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
  45. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
  46. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
  47. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
  48. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
  49. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
  50. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
  51. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
  52. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
  53. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
  54. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
  55. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
  56. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
  57. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
  58. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
  59. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
  60. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
  61. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
  62. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
  63. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
  64. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
  65. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
  66. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
  67. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
  68. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/feature_flags/schema.py +0 -0
  69. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
  70. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/pydantic_helpers.py +0 -0
  71. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/referencing.py +0 -0
  72. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/string_utilities.py +0 -0
  73. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/tests/test_referencing.py +0 -0
  74. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
  75. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/token/__init__.py +0 -0
  76. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/token/image_token_counting.py +0 -0
  77. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/token/token_counting.py +0 -0
  78. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
  79. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
  80. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/__init__.py +0 -0
  81. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/files.py +0 -0
  82. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/image/encode.py +0 -0
  83. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
  84. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/jinja/render.py +0 -0
  85. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
  86. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
  87. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
  88. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
  89. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/utils/write_configuration.py +0 -0
  90. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/validate_required_values.py +0 -0
  91. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/_common/validators.py +0 -0
  92. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/__init__.py +0 -0
  93. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
  94. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
  95. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/config.py +0 -0
  96. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
  97. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
  98. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
  99. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
  100. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
  101. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
  102. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/exception.py +0 -0
  103. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
  104. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
  105. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
  106. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
  107. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
  108. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
  109. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
  110. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
  111. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
  112. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
  113. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
  114. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
  115. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
  116. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
  117. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
  118. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
  119. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/evaluation/utils.py +0 -0
  120. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
  121. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
  122. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
  123. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
  124. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
  125. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
  126. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
  127. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/base.py +0 -0
  128. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
  129. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
  130. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
  131. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
  132. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
  133. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
  134. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
  135. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
  136. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
  137. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
  138. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
  139. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
  140. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
  141. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
  142. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
  143. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
  144. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
  145. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
  146. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
  147. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
  148. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
  149. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/__init__.py +0 -0
  150. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
  151. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
  152. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
  153. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
  154. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
  155. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
  156. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
  157. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
  158. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
  159. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
  160. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
  161. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
  162. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
  163. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
  164. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
  165. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
  166. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
  167. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
  168. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
  169. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
  170. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
  171. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
  172. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
  173. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
  174. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
  175. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
  176. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
  177. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/config.py +0 -0
  178. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/factory.py +0 -0
  179. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
  180. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
  181. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
  182. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
  183. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
  184. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
  185. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
  186. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
  187. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
  188. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
  189. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +0 -0
  190. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
  191. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
  192. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
  193. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/schemas.py +0 -0
  194. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
  195. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
  196. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/tool.py +0 -0
  197. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
  198. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
  199. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
  200. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  201. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
  202. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
  203. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
  204. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic_table/__init__.py +0 -0
  205. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic_table/schemas.py +0 -0
  206. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/agentic_table/service.py +0 -0
  207. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/__init__.py +0 -0
  208. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/dev_util.py +0 -0
  209. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/fast_api_factory.py +0 -0
  210. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/init_logging.py +0 -0
  211. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/init_sdk.py +0 -0
  212. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/performance/async_tasks.py +0 -0
  213. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/performance/async_wrapper.py +0 -0
  214. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/schemas.py +0 -0
  215. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/unique_settings.py +0 -0
  216. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/verification.py +0 -0
  217. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/app/webhook.py +0 -0
  218. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/__init__.py +0 -0
  219. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/cancellation.py +0 -0
  220. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/constants.py +0 -0
  221. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/deprecated/service.py +0 -0
  222. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/rendering.py +0 -0
  223. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/responses_api.py +0 -0
  224. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/schemas.py +0 -0
  225. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/service.py +0 -0
  226. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/state.py +0 -0
  227. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/chat/utils.py +0 -0
  228. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/content/__init__.py +0 -0
  229. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/content/constants.py +0 -0
  230. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/content/functions.py +0 -0
  231. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/content/schemas.py +0 -0
  232. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/content/service.py +0 -0
  233. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/content/smart_rules.py +0 -0
  234. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/content/utils.py +0 -0
  235. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/README.md +0 -0
  236. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/__init__.py +0 -0
  237. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
  238. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/augmented/service.py +0 -0
  239. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/base.py +0 -0
  240. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
  241. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/basic/config.py +0 -0
  242. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
  243. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/data_extraction/basic/service.py +0 -0
  244. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/elicitation/__init__.py +0 -0
  245. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/elicitation/constants.py +0 -0
  246. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/elicitation/exceptions.py +0 -0
  247. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/elicitation/functions.py +0 -0
  248. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/elicitation/schemas.py +0 -0
  249. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/elicitation/service.py +0 -0
  250. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/embedding/__init__.py +0 -0
  251. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/embedding/constants.py +0 -0
  252. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/embedding/functions.py +0 -0
  253. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/embedding/schemas.py +0 -0
  254. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/embedding/service.py +0 -0
  255. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/embedding/utils.py +0 -0
  256. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/framework_utilities/__init__.py +0 -0
  257. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
  258. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
  259. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
  260. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
  261. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/framework_utilities/openai/client.py +0 -0
  262. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
  263. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/framework_utilities/utils.py +0 -0
  264. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/__init__.py +0 -0
  265. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
  266. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/builder.py +0 -0
  267. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/constants.py +0 -0
  268. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/default_language_model.py +0 -0
  269. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/functions.py +0 -0
  270. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/infos.py +0 -0
  271. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/prompt.py +0 -0
  272. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/reference.py +0 -0
  273. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/schemas.py +0 -0
  274. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/service.py +0 -0
  275. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/stream_transform.py +0 -0
  276. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/language_model/utils.py +0 -0
  277. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/protocols/support.py +0 -0
  278. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/services/__init__.py +0 -0
  279. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/services/chat_service.py +0 -0
  280. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/services/factory.py +0 -0
  281. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/services/knowledge_base.py +0 -0
  282. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/short_term_memory/__init__.py +0 -0
  283. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/short_term_memory/constants.py +0 -0
  284. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/short_term_memory/functions.py +0 -0
  285. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/short_term_memory/schemas.py +0 -0
  286. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/short_term_memory/service.py +0 -0
  287. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/smart_rules/__init__.py +0 -0
  288. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/smart_rules/compile.py +0 -0
  289. {unique_toolkit-1.62.3 → unique_toolkit-1.63.0}/unique_toolkit/test_utilities/events.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-toolkit
3
- Version: 1.62.3
3
+ Version: 1.63.0
4
4
  Summary:
5
5
  Author: Cedric Klinkert, Martin Fadler, Sadique Sheik, Fabian Schläpfer, Pascal Hauri, Ejiroghene Oki-Peter, Rami Azouz, Ricardo Visini, Sanzio Monti
6
6
  Author-email: Cedric Klinkert <cedric.klinkert@unique.ch>, Martin Fadler <martin.fadler@unique.ch>, Sadique Sheik <sadique@unique.ch>, Fabian Schläpfer <fabian@unique.ch>, Pascal Hauri <pascal@unique.ch>, Ejiroghene Oki-Peter <oki-peter.ejiroghene@unique.ai>, Rami Azouz <rami.ext@unique.ch>, Ricardo Visini <ricardo.visini@unique.ch>, Sanzio Monti <sanzio.monti@unique.ai>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique_toolkit"
3
- version = "1.62.3"
3
+ version = "1.63.0"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -9,6 +9,7 @@ from itertools import groupby
9
9
  from typing import TYPE_CHECKING
10
10
 
11
11
  if TYPE_CHECKING:
12
+ from unique_toolkit.content.schemas import ContentChunk
12
13
  from unique_toolkit.language_model.builder import MessagesBuilder
13
14
 
14
15
  import numpy as np
@@ -256,13 +257,30 @@ def get_full_history_with_contents_and_tool_calls(
256
257
  content_service: ContentService,
257
258
  include_images: ImageContentInclusion = ImageContentInclusion.ALL,
258
259
  file_content_serialization_type: FileContentSerialization = FileContentSerialization.FILE_NAME,
259
- ) -> LanguageModelMessages:
260
- """Build the full LLM message history, including persisted tool call rounds."""
260
+ ) -> tuple[LanguageModelMessages, int, dict[int, "ContentChunk"]]:
261
+ """Build the full LLM message history, including persisted tool call rounds.
262
+
263
+ Returns:
264
+ A triple of (messages, max_source_number, source_map) where
265
+ *max_source_number* is the highest ``source_number`` found in any
266
+ persisted tool response (``-1`` when none exist) and *source_map*
267
+ maps each ``source_number`` to a ``ContentChunk`` reconstructed from
268
+ the persisted response content.
269
+ """
270
+ from unique_toolkit.agentic.history_manager.utils import (
271
+ build_source_map_from_tool_calls,
272
+ compute_max_source_number_from_tool_calls,
273
+ )
274
+ from unique_toolkit.content.schemas import (
275
+ ContentChunk as ContentChunk, # noqa: F811
276
+ )
277
+
261
278
  chat_history = chat_service.get_full_history()
262
279
 
263
280
  assistant_message_ids = [
264
281
  msg.id for msg in chat_history if msg.role == ChatRole.ASSISTANT and msg.id
265
282
  ]
283
+ all_tool_calls: list[ChatMessageTool] = []
266
284
  tool_calls_by_message: dict[str, list[ChatMessageTool]] = {}
267
285
  if assistant_message_ids:
268
286
  try:
@@ -276,6 +294,10 @@ def get_full_history_with_contents_and_tool_calls(
276
294
  _LOGGER.warning(
277
295
  "Failed to batch-load tool calls, falling back to empty", exc_info=True
278
296
  )
297
+ max_source_number = compute_max_source_number_from_tool_calls(all_tool_calls)
298
+ source_map: dict[int, ContentChunk] = build_source_map_from_tool_calls(
299
+ all_tool_calls
300
+ )
279
301
 
280
302
  grouped_elements = get_chat_history_with_contents(
281
303
  user_message=user_message,
@@ -366,7 +388,7 @@ def get_full_history_with_contents_and_tool_calls(
366
388
  content_service=content_service,
367
389
  chat_id=chat_id,
368
390
  )
369
- return builder.build()
391
+ return builder.build(), max_source_number, source_map
370
392
 
371
393
 
372
394
  def get_full_history_as_llm_messages(
@@ -10,12 +10,16 @@ from unique_toolkit._common.feature_flags.schema import (
10
10
  )
11
11
  from unique_toolkit._common.validators import LMI
12
12
  from unique_toolkit.agentic.history_manager.loop_token_reducer import LoopTokenReducer
13
- from unique_toolkit.agentic.history_manager.utils import transform_chunks_to_string
13
+ from unique_toolkit.agentic.history_manager.utils import (
14
+ serialize_tool_content_json,
15
+ transform_chunks_to_string,
16
+ )
14
17
  from unique_toolkit.agentic.reference_manager.reference_manager import ReferenceManager
15
18
  from unique_toolkit.agentic.tools.config import get_configuration_dict
16
19
  from unique_toolkit.agentic.tools.schemas import ToolCallResponse
17
20
  from unique_toolkit.app.schemas import ChatEvent
18
21
  from unique_toolkit.chat.schemas import ChatMessageTool, ChatMessageToolResponse
22
+ from unique_toolkit.content.schemas import ContentChunk
19
23
  from unique_toolkit.language_model.default_language_model import DEFAULT_GPT_4o
20
24
  from unique_toolkit.language_model.infos import LanguageModelInfo
21
25
  from unique_toolkit.language_model.schemas import (
@@ -64,13 +68,6 @@ class HistoryManagerConfig(BaseModel):
64
68
  description="The fraction of the max input tokens that will be reserved for the history.",
65
69
  )
66
70
 
67
- percent_for_tool_call_history: float = Field(
68
- default=0.0,
69
- ge=0.0,
70
- lt=1.0,
71
- description="The fraction of the max input tokens reserved for tool call rounds. 0 disables.",
72
- )
73
-
74
71
  language_model: LMI = LanguageModelInfo.from_name(DEFAULT_GPT_4o)
75
72
 
76
73
  @property
@@ -80,13 +77,6 @@ class HistoryManagerConfig(BaseModel):
80
77
  * self.percent_of_max_tokens_for_history,
81
78
  )
82
79
 
83
- @property
84
- def max_tool_call_history_tokens(self) -> int:
85
- return int(
86
- self.language_model.token_limits.token_limit_input
87
- * self.percent_for_tool_call_history,
88
- )
89
-
90
80
  uploaded_content_config: (
91
81
  Annotated[
92
82
  UploadedContentConfig,
@@ -135,12 +125,15 @@ class HistoryManager:
135
125
  has_uploaded_content_config=bool(self._config.uploaded_content_config),
136
126
  language_model=self._language_model,
137
127
  reference_manager=reference_manager,
138
- max_tokens_for_tool_call_history=self._config.max_tool_call_history_tokens,
139
128
  )
129
+ self._reference_manager = reference_manager
140
130
  self._tool_call_result_history: list[ToolCallResponse] = []
141
131
  self._tool_calls: list[LanguageModelFunction] = []
142
132
  self._loop_history: list[LanguageModelMessage] = []
143
133
  self._source_enumerator = 0
134
+ self._initial_source_offset = 0
135
+ self._db_source_map: dict[int, ContentChunk] = {}
136
+ self._source_offset_initialized = False
144
137
  self._collected_tool_response_image_urls: list[tuple[str, str]] = []
145
138
 
146
139
  def add_tool_call(self, tool_call: LanguageModelFunction) -> None:
@@ -193,16 +186,13 @@ class HistoryManager:
193
186
  tool_response.content_chunks or []
194
187
  ) # it can be that the tool response does not have content chunks
195
188
 
196
- # Transform content chunks into sources to be appended to tool result
197
189
  stringified_sources, sources = transform_chunks_to_string(
198
190
  content_chunks,
199
191
  self._source_enumerator,
200
192
  )
201
193
  content = stringified_sources
202
194
 
203
- self._source_enumerator += len(
204
- sources
205
- ) # To make sure all sources have unique source numbers
195
+ self._source_enumerator += len(sources)
206
196
 
207
197
  if tool_response.system_reminder:
208
198
  content += f"\n\n{tool_response.system_reminder}"
@@ -243,6 +233,18 @@ class HistoryManager:
243
233
  image_data_urls_from_tools=image_data_from_tools,
244
234
  )
245
235
  self._collected_tool_response_image_urls = []
236
+
237
+ if not self._source_offset_initialized:
238
+ offset = max(0, self._token_reducer.max_db_source_number + 1)
239
+ self._source_enumerator = offset
240
+ self._initial_source_offset = offset
241
+ self._db_source_map = self._token_reducer.db_source_map
242
+ self._source_offset_initialized = True
243
+
244
+ self._source_enumerator = self._initial_source_offset + len(
245
+ self._reference_manager.get_chunks()
246
+ )
247
+
246
248
  return messages
247
249
 
248
250
  async def get_user_visible_chat_history(
@@ -267,29 +269,47 @@ class HistoryManager:
267
269
  )
268
270
  return LanguageModelMessages(history)
269
271
 
272
+ @staticmethod
273
+ def _placeholder_chunk() -> ContentChunk:
274
+ """An empty but backend-valid placeholder for gap positions."""
275
+ return ContentChunk(key="", chunk_id="")
276
+
277
+ def get_content_chunks_for_backend(self) -> list[ContentChunk]:
278
+ """Build a positional list where ``result[N]`` is the chunk for ``[sourceN]``.
279
+
280
+ Positions ``0..K-1`` are filled from ``_db_source_map`` (prior turns).
281
+ Gaps get placeholder ``ContentChunk`` instances with empty-string
282
+ ``key`` / ``chunk_id`` so the backend doesn't reject the payload.
283
+ Positions ``K..`` are the current turn's chunks from the reference
284
+ manager.
285
+ """
286
+ current_chunks = self._reference_manager.get_chunks()
287
+ total_size = self._initial_source_offset + len(current_chunks)
288
+ result: list[ContentChunk] = [
289
+ self._placeholder_chunk() for _ in range(total_size)
290
+ ]
291
+ for source_number, chunk in self._db_source_map.items():
292
+ if source_number < self._initial_source_offset:
293
+ result[source_number] = chunk
294
+ for i, chunk in enumerate(current_chunks):
295
+ result[self._initial_source_offset + i] = chunk
296
+ return result
297
+
270
298
  def extract_message_tools(self) -> list[ChatMessageTool]:
271
299
  """Convert the in-memory loop history into persistable ChatMessageTool records."""
300
+ # Build a map of tool_call_id -> response_content in O(T) time
301
+ tool_responses: dict[str, str | None] = {}
302
+ for msg in self._loop_history:
303
+ if isinstance(msg, LanguageModelToolMessage):
304
+ response_content = msg.content if isinstance(msg.content, str) else None
305
+ tool_responses[msg.tool_call_id] = response_content
306
+
272
307
  records: list[ChatMessageTool] = []
273
308
  round_index = 0
274
- i = 0
275
- while i < len(self._loop_history):
276
- msg = self._loop_history[i]
309
+ for msg in self._loop_history:
277
310
  if isinstance(msg, LanguageModelAssistantMessage) and msg.tool_calls:
278
311
  for seq_index, tc in enumerate(msg.tool_calls):
279
- response_content = None
280
- for j in range(i + 1, len(self._loop_history)):
281
- candidate = self._loop_history[j]
282
- if (
283
- isinstance(candidate, LanguageModelToolMessage)
284
- and candidate.tool_call_id == tc.id
285
- ):
286
- response_content = (
287
- candidate.content
288
- if isinstance(candidate.content, str)
289
- else None
290
- )
291
- break
292
-
312
+ response_content = tool_responses.get(tc.id) if tc.id else None
293
313
  response = (
294
314
  ChatMessageToolResponse(content=response_content)
295
315
  if response_content is not None
@@ -306,7 +326,6 @@ class HistoryManager:
306
326
  )
307
327
  )
308
328
  round_index += 1
309
- i += 1
310
329
  return records
311
330
 
312
331
  @staticmethod
@@ -366,4 +385,4 @@ def _strip_uncited_sources_from_content(content: str, cited: set[int]) -> str:
366
385
  return content
367
386
 
368
387
  filtered = [item for item in data if item.get("source_number") in cited]
369
- return json.dumps(filtered)
388
+ return serialize_tool_content_json(filtered)
@@ -12,6 +12,7 @@ from unique_toolkit.agentic.history_manager.history_construction_with_contents i
12
12
  FileContentSerialization,
13
13
  get_full_history_with_contents_and_tool_calls,
14
14
  )
15
+ from unique_toolkit.agentic.history_manager.utils import serialize_tool_content_json
15
16
  from unique_toolkit.agentic.reference_manager.reference_manager import ReferenceManager
16
17
  from unique_toolkit.app.schemas import ChatEvent
17
18
  from unique_toolkit.app.unique_settings import UniqueSettings
@@ -53,11 +54,9 @@ class LoopTokenReducer:
53
54
  has_uploaded_content_config: bool,
54
55
  reference_manager: ReferenceManager,
55
56
  language_model: LMI,
56
- max_tokens_for_tool_call_history: int | None = None,
57
57
  ):
58
58
  self._max_history_tokens = max_history_tokens
59
59
  self._has_uploaded_content_config = has_uploaded_content_config
60
- self._max_tokens_for_tool_call_history = max_tokens_for_tool_call_history
61
60
  self._logger = logger
62
61
  self._reference_manager = reference_manager
63
62
  self._language_model = language_model
@@ -72,6 +71,16 @@ class LoopTokenReducer:
72
71
  self._language_model.token_limits.token_limit_input
73
72
  * (1 - MAX_INPUT_TOKENS_SAFETY_PERCENTAGE)
74
73
  )
74
+ self._max_db_source_number: int = -1
75
+ self._db_source_map: dict[int, ContentChunk] = {}
76
+
77
+ @property
78
+ def max_db_source_number(self) -> int:
79
+ return self._max_db_source_number
80
+
81
+ @property
82
+ def db_source_map(self) -> dict[int, ContentChunk]:
83
+ return self._db_source_map
75
84
 
76
85
  def _get_encoder(self, language_model: LMI) -> Callable[[str], list[int]]:
77
86
  return language_model.get_encoder()
@@ -105,7 +114,9 @@ class LoopTokenReducer:
105
114
 
106
115
  while self._exceeds_token_limit(token_count):
107
116
  token_count_before_reduction = token_count
108
- loop_history = self._handle_token_limit_exceeded(loop_history, token_count)
117
+ loop_history[:] = self._handle_token_limit_exceeded(
118
+ loop_history, token_count
119
+ )
109
120
  messages = self._construct_history(
110
121
  history_from_db,
111
122
  loop_history,
@@ -292,7 +303,7 @@ class LoopTokenReducer:
292
303
  Returns:
293
304
  list[LanguageModelMessage]: The history
294
305
  """
295
- full_history = get_full_history_with_contents_and_tool_calls(
306
+ full_history, max_src, src_map = get_full_history_with_contents_and_tool_calls(
296
307
  user_message=self._user_message,
297
308
  chat_id=self._chat_id,
298
309
  chat_service=self._chat_service,
@@ -303,16 +314,14 @@ class LoopTokenReducer:
303
314
  else FileContentSerialization.FILE_NAME
304
315
  ),
305
316
  )
317
+ self._max_db_source_number = max_src
318
+ self._db_source_map = src_map
319
+
306
320
  if remove_from_text is not None:
307
321
  full_history.root = await self._clean_messages(
308
322
  full_history.root, remove_from_text
309
323
  )
310
324
 
311
- if self._max_tokens_for_tool_call_history is not None:
312
- full_history.root = self._limit_tool_call_tokens(
313
- full_history.root, self._max_tokens_for_tool_call_history
314
- )
315
-
316
325
  limited_history_messages = self._limit_to_token_window(
317
326
  full_history.root, self._max_history_tokens
318
327
  )
@@ -383,77 +392,6 @@ class LoopTokenReducer:
383
392
 
384
393
  return [msg for turn in selected_turns[::-1] for msg in turn]
385
394
 
386
- def _limit_tool_call_tokens(
387
- self,
388
- messages: list[LanguageModelMessage],
389
- budget: int,
390
- ) -> list[LanguageModelMessage]:
391
- """Drop older tool-call rounds so the total stays within *budget* tokens.
392
-
393
- A "round" is a contiguous block of one ``LanguageModelAssistantMessage``
394
- (with ``tool_calls``) followed by its ``LanguageModelToolMessage`` replies.
395
- Rounds are kept from the back (most recent first). When *budget* is
396
- positive, at least one round is always preserved even if it alone exceeds
397
- the budget. A *budget* of ``0`` removes **all** tool-call rounds.
398
- """
399
- rounds: list[tuple[int, int]] = []
400
- i = 0
401
- while i < len(messages):
402
- msg = messages[i]
403
- if isinstance(msg, LanguageModelAssistantMessage) and msg.tool_calls:
404
- start = i
405
- i += 1
406
- while i < len(messages) and isinstance(
407
- messages[i], LanguageModelToolMessage
408
- ):
409
- i += 1
410
- rounds.append((start, i))
411
- else:
412
- i += 1
413
-
414
- if not rounds:
415
- return messages
416
-
417
- if budget <= 0:
418
- drop_all: set[int] = set()
419
- for start, end in rounds:
420
- drop_all.update(range(start, end))
421
- self._logger.info(
422
- f"Tool-call budget is 0: dropping all {len(rounds)} tool-call rounds",
423
- )
424
- return [m for i, m in enumerate(messages) if i not in drop_all]
425
-
426
- round_tokens = [
427
- sum(
428
- self._count_message_tokens(LanguageModelMessages(root=[m]))
429
- for m in messages[start:end]
430
- )
431
- for start, end in rounds
432
- ]
433
-
434
- keep: set[int] = set()
435
- cumulative = 0
436
- for idx in range(len(rounds) - 1, -1, -1):
437
- cumulative += round_tokens[idx]
438
- if cumulative > budget and keep:
439
- break
440
- keep.add(idx)
441
-
442
- drop_indices: set[int] = set()
443
- for idx, (start, end) in enumerate(rounds):
444
- if idx not in keep:
445
- drop_indices.update(range(start, end))
446
-
447
- if not drop_indices:
448
- return messages
449
-
450
- self._logger.info(
451
- f"Tool-call budget: dropping {len(rounds) - len(keep)} of {len(rounds)} "
452
- f"rounds ({sum(round_tokens[i] for i in range(len(rounds)) if i not in keep)} tokens freed)",
453
- )
454
-
455
- return [m for i, m in enumerate(messages) if i not in drop_indices]
456
-
457
395
  async def _clean_messages(
458
396
  self,
459
397
  messages: list[
@@ -515,7 +453,7 @@ class LoopTokenReducer:
515
453
  history_reduced: list[LanguageModelMessage] = []
516
454
  content_chunks_reduced: list[ContentChunk] = []
517
455
  chunk_offset = 0
518
- source_offset = 0
456
+ source_offset = max(0, self._max_db_source_number + 1)
519
457
 
520
458
  for message in history:
521
459
  if self._should_reduce_message(message):
@@ -651,7 +589,7 @@ class LoopTokenReducer:
651
589
  else:
652
590
  raise ValueError(f"Unexpected content type: {type(message.content)}")
653
591
 
654
- content = json.dumps(
592
+ content = serialize_tool_content_json(
655
593
  {
656
594
  "source_number": source_offset,
657
595
  "content": content_dict.get("content"),
@@ -692,7 +630,7 @@ class LoopTokenReducer:
692
630
  ]
693
631
 
694
632
  return LanguageModelToolMessage(
695
- content=json.dumps(sources),
633
+ content=serialize_tool_content_json(sources),
696
634
  tool_call_id=message.tool_call_id,
697
635
  name=message.name,
698
636
  )
@@ -14,6 +14,11 @@ from unique_toolkit.language_model.schemas import (
14
14
  logger = logging.getLogger(__name__)
15
15
 
16
16
 
17
+ def serialize_tool_content_json(value: Any) -> str:
18
+ """Serialize tool-role JSON text while preserving readable Unicode."""
19
+ return json.dumps(value, ensure_ascii=False)
20
+
21
+
17
22
  def convert_tool_interactions_to_content_messages(
18
23
  loop_history: list[LanguageModelMessage],
19
24
  ) -> list[LanguageModelMessage]:
@@ -80,7 +85,7 @@ def transform_chunks_to_string(
80
85
  }
81
86
  for i, chunk in enumerate(content_chunks)
82
87
  ]
83
- return json.dumps(sources), sources
88
+ return serialize_tool_content_json(sources), sources
84
89
 
85
90
 
86
91
  def load_sources_from_string(
@@ -95,3 +100,70 @@ def load_sources_from_string(
95
100
  except (json.JSONDecodeError, ValueError):
96
101
  logger.warning("Failed to parse source string")
97
102
  return None
103
+
104
+
105
+ def _parse_sources_from_response(content: str) -> list[dict[str, Any]]:
106
+ """Parse the JSON source array from a persisted tool response content string.
107
+
108
+ Returns an empty list when the content is not valid JSON or not a list.
109
+ """
110
+ try:
111
+ data = json.loads(content)
112
+ if isinstance(data, list):
113
+ return data
114
+ return []
115
+ except (json.JSONDecodeError, ValueError) as exc:
116
+ logger.warning(
117
+ "_parse_sources_from_response: JSON parse failed (content_len=%d): %s",
118
+ len(content),
119
+ exc,
120
+ )
121
+ return []
122
+
123
+
124
+ def compute_max_source_number_from_tool_calls(
125
+ tool_calls: list[Any],
126
+ ) -> int:
127
+ """Find the highest ``source_number`` across all persisted tool-call responses.
128
+
129
+ Returns ``-1`` when no source numbers are found.
130
+ """
131
+ from unique_toolkit.chat.schemas import ChatMessageTool
132
+
133
+ max_num = -1
134
+ for tc in tool_calls:
135
+ if not isinstance(tc, ChatMessageTool):
136
+ continue
137
+ if not tc.response or not tc.response.content:
138
+ continue
139
+ for entry in _parse_sources_from_response(tc.response.content):
140
+ sn = entry.get("source_number")
141
+ if isinstance(sn, int) and sn > max_num:
142
+ max_num = sn
143
+ return max_num
144
+
145
+
146
+ def build_source_map_from_tool_calls(
147
+ tool_calls: list[Any],
148
+ ) -> dict[int, ContentChunk]:
149
+ """Build a mapping ``{source_number: ContentChunk}`` from persisted tool responses.
150
+
151
+ Only entries that have both a valid ``source_number`` and ``content`` are included.
152
+ """
153
+ from unique_toolkit.chat.schemas import ChatMessageTool
154
+
155
+ source_map: dict[int, ContentChunk] = {}
156
+ for tc in tool_calls:
157
+ if not isinstance(tc, ChatMessageTool):
158
+ continue
159
+ if not tc.response or not tc.response.content:
160
+ continue
161
+ for entry in _parse_sources_from_response(tc.response.content):
162
+ sn = entry.get("source_number")
163
+ text = entry.get("content")
164
+ if isinstance(sn, int) and isinstance(text, str):
165
+ content_id = entry.get("content_id") or ""
166
+ source_map[sn] = ContentChunk(
167
+ id=content_id, text=text, key="", chunk_id=""
168
+ )
169
+ return source_map
@@ -1410,9 +1410,6 @@ async def update_message_execution_async(
1410
1410
  raise e
1411
1411
 
1412
1412
 
1413
- _MAX_TOOL_RESPONSE_CONTENT_LEN = 10_000
1414
-
1415
-
1416
1413
  def _build_tool_call_items(
1417
1414
  tool_calls: list[ChatMessageTool],
1418
1415
  ) -> list[dict[str, object]]:
@@ -1423,15 +1420,7 @@ def _build_tool_call_items(
1423
1420
  "arguments": tc.arguments,
1424
1421
  "roundIndex": tc.round_index,
1425
1422
  "sequenceIndex": tc.sequence_index,
1426
- **(
1427
- {
1428
- "response": {
1429
- "content": tc.response.content[:_MAX_TOOL_RESPONSE_CONTENT_LEN]
1430
- }
1431
- }
1432
- if tc.response
1433
- else {}
1434
- ),
1423
+ **({"response": {"content": tc.response.content}} if tc.response else {}),
1435
1424
  }
1436
1425
  for tc in tool_calls
1437
1426
  ]
@@ -1484,7 +1473,8 @@ async def create_message_tools_async(
1484
1473
  messageId=message_id,
1485
1474
  tools=_build_tool_call_items(tool_calls), # type: ignore
1486
1475
  )
1487
- return [ChatMessageTool.model_validate(dict(item)) for item in result.data]
1476
+ tools = [ChatMessageTool.model_validate(dict(item)) for item in result.data]
1477
+ return tools
1488
1478
  except Exception as e:
1489
1479
  _LOGGER.error(f"Failed to create message tools: {e}")
1490
1480
  raise e
@@ -1507,7 +1497,8 @@ def get_message_tools(
1507
1497
  company_id=company_id,
1508
1498
  messageIds=ids,
1509
1499
  )
1510
- return [ChatMessageTool.model_validate(dict(item)) for item in result.data]
1500
+ tools = [ChatMessageTool.model_validate(dict(item)) for item in result.data]
1501
+ return tools
1511
1502
  except Exception as e:
1512
1503
  _LOGGER.error(f"Failed to get message tools: {e}")
1513
1504
  raise e