unique_toolkit 1.47.9__tar.gz → 1.47.11__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.47.9 → unique_toolkit-1.47.11}/CHANGELOG.md +7 -0
  2. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/PKG-INFO +8 -1
  3. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/pyproject.toml +1 -1
  4. unique_toolkit-1.47.11/unique_toolkit/_common/docx_generator/__init__.py +21 -0
  5. unique_toolkit-1.47.11/unique_toolkit/_common/docx_generator/config.py +75 -0
  6. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/docx_generator/schemas.py +6 -0
  7. unique_toolkit-1.47.11/unique_toolkit/_common/docx_generator/service.py +444 -0
  8. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +7 -2
  9. unique_toolkit-1.47.9/unique_toolkit/_common/docx_generator/__init__.py +0 -7
  10. unique_toolkit-1.47.9/unique_toolkit/_common/docx_generator/config.py +0 -12
  11. unique_toolkit-1.47.9/unique_toolkit/_common/docx_generator/service.py +0 -216
  12. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/LICENSE +0 -0
  13. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/README.md +0 -0
  14. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/__init__.py +0 -0
  15. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/__init__.py +0 -0
  16. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/_base_service.py +0 -0
  17. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/_time_utils.py +0 -0
  18. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
  19. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
  20. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
  21. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
  22. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
  23. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
  24. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
  25. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/README.md +0 -0
  26. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/__init__.py +0 -0
  27. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/__main__.py +0 -0
  28. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/cli.py +0 -0
  29. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/differ.py +0 -0
  30. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/exporter.py +0 -0
  31. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/models.py +0 -0
  32. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/registry.py +0 -0
  33. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/config_checker/validator.py +0 -0
  34. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/default_language_model.py +0 -0
  35. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  36. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/endpoint_builder.py +0 -0
  37. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/endpoint_requestor.py +0 -0
  38. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/event_bus.py +0 -0
  39. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/exception.py +0 -0
  40. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/execution.py +0 -0
  41. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
  42. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
  43. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
  44. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
  45. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
  46. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
  47. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
  48. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
  49. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
  50. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
  51. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
  52. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
  53. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
  54. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
  55. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
  56. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
  57. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
  58. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
  59. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
  60. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
  61. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
  62. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
  63. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
  64. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
  65. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
  66. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
  67. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
  68. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/feature_flags/schema.py +0 -0
  69. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
  70. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/pydantic_helpers.py +0 -0
  71. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/referencing.py +0 -0
  72. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/string_utilities.py +0 -0
  73. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/tests/test_referencing.py +0 -0
  74. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
  75. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/token/__init__.py +0 -0
  76. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/token/image_token_counting.py +0 -0
  77. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/token/token_counting.py +0 -0
  78. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
  79. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
  80. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/__init__.py +0 -0
  81. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/files.py +0 -0
  82. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/image/encode.py +0 -0
  83. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
  84. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/jinja/render.py +0 -0
  85. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
  86. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
  87. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
  88. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
  89. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/utils/write_configuration.py +0 -0
  90. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/validate_required_values.py +0 -0
  91. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/_common/validators.py +0 -0
  92. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/__init__.py +0 -0
  93. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
  94. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
  95. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/config.py +0 -0
  96. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
  97. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
  98. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
  99. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
  100. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
  101. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
  102. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/exception.py +0 -0
  103. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
  104. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
  105. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
  106. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
  107. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
  108. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
  109. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
  110. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
  111. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
  112. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
  113. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
  114. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
  115. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
  116. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
  117. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
  118. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
  119. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/evaluation/utils.py +0 -0
  120. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
  121. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
  122. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
  123. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
  124. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
  125. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/history_manager/utils.py +0 -0
  126. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
  127. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
  128. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
  129. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
  130. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
  131. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/base.py +0 -0
  132. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
  133. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
  134. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
  135. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
  136. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
  137. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
  138. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
  139. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
  140. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
  141. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
  142. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
  143. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
  144. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
  145. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
  146. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
  147. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
  148. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
  149. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
  150. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
  151. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/__init__.py +0 -0
  152. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
  153. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
  154. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
  155. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
  156. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
  157. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
  158. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
  159. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
  160. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
  161. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
  162. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
  163. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
  164. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
  165. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
  166. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
  167. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
  168. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
  169. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
  170. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
  171. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
  172. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
  173. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
  174. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
  175. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
  176. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
  177. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
  178. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
  179. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/config.py +0 -0
  180. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/factory.py +0 -0
  181. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
  182. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
  183. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
  184. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
  185. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
  186. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
  187. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
  188. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
  189. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
  190. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +0 -0
  191. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
  192. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
  193. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/schemas.py +0 -0
  194. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
  195. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
  196. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/tool.py +0 -0
  197. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
  198. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
  199. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
  200. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  201. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
  202. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
  203. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
  204. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic_table/__init__.py +0 -0
  205. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic_table/schemas.py +0 -0
  206. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/agentic_table/service.py +0 -0
  207. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/__init__.py +0 -0
  208. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/dev_util.py +0 -0
  209. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/fast_api_factory.py +0 -0
  210. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/init_logging.py +0 -0
  211. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/init_sdk.py +0 -0
  212. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/performance/async_tasks.py +0 -0
  213. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/performance/async_wrapper.py +0 -0
  214. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/schemas.py +0 -0
  215. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/unique_settings.py +0 -0
  216. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/verification.py +0 -0
  217. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/app/webhook.py +0 -0
  218. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/__init__.py +0 -0
  219. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/cancellation.py +0 -0
  220. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/constants.py +0 -0
  221. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/deprecated/service.py +0 -0
  222. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/functions.py +0 -0
  223. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/rendering.py +0 -0
  224. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/responses_api.py +0 -0
  225. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/schemas.py +0 -0
  226. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/service.py +0 -0
  227. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/state.py +0 -0
  228. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/chat/utils.py +0 -0
  229. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/content/__init__.py +0 -0
  230. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/content/constants.py +0 -0
  231. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/content/functions.py +0 -0
  232. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/content/schemas.py +0 -0
  233. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/content/service.py +0 -0
  234. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/content/smart_rules.py +0 -0
  235. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/content/utils.py +0 -0
  236. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/README.md +0 -0
  237. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/__init__.py +0 -0
  238. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
  239. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/augmented/service.py +0 -0
  240. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/base.py +0 -0
  241. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
  242. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/basic/config.py +0 -0
  243. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
  244. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/data_extraction/basic/service.py +0 -0
  245. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/elicitation/__init__.py +0 -0
  246. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/elicitation/constants.py +0 -0
  247. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/elicitation/exceptions.py +0 -0
  248. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/elicitation/functions.py +0 -0
  249. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/elicitation/schemas.py +0 -0
  250. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/elicitation/service.py +0 -0
  251. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/embedding/__init__.py +0 -0
  252. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/embedding/constants.py +0 -0
  253. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/embedding/functions.py +0 -0
  254. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/embedding/schemas.py +0 -0
  255. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/embedding/service.py +0 -0
  256. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/embedding/utils.py +0 -0
  257. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/framework_utilities/__init__.py +0 -0
  258. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
  259. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
  260. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
  261. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
  262. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/framework_utilities/openai/client.py +0 -0
  263. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
  264. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/framework_utilities/utils.py +0 -0
  265. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/__init__.py +0 -0
  266. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
  267. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/builder.py +0 -0
  268. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/constants.py +0 -0
  269. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/default_language_model.py +0 -0
  270. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/functions.py +0 -0
  271. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/infos.py +0 -0
  272. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/prompt.py +0 -0
  273. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/reference.py +0 -0
  274. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/schemas.py +0 -0
  275. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/service.py +0 -0
  276. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/stream_transform.py +0 -0
  277. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/language_model/utils.py +0 -0
  278. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/protocols/support.py +0 -0
  279. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/services/__init__.py +0 -0
  280. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/services/chat_service.py +0 -0
  281. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/services/knowledge_base.py +0 -0
  282. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/short_term_memory/__init__.py +0 -0
  283. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/short_term_memory/constants.py +0 -0
  284. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/short_term_memory/functions.py +0 -0
  285. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/short_term_memory/schemas.py +0 -0
  286. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/short_term_memory/service.py +0 -0
  287. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/smart_rules/__init__.py +0 -0
  288. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/smart_rules/compile.py +0 -0
  289. {unique_toolkit-1.47.9 → unique_toolkit-1.47.11}/unique_toolkit/test_utilities/events.py +0 -0
@@ -5,6 +5,13 @@ 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.47.11] - 2026-02-26
9
+ - Add `DocxGeneratorService` migration surface: `DocxGeneratorResult`, `generate_from_template_with_result()`, `upload_and_create_reference()`, `resolve_template()`, `normalize_heading_levels()`
10
+ - Fix error handling in `DocxGeneratorService`; tighten `DocxGeneratorConfig.template_fields` to `dict[str, str]`
11
+
12
+ ## [1.47.10] - 2026-02-26
13
+ - Code interpreter: bound `expires_after_minutes` to 1–20 (OpenAI API max), add RJSF `NumberWidget.updown` for UI
14
+
8
15
  ## [1.47.9] - 2026-02-26
9
16
  - Fixing bug with chunk relevancy sorter
10
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique_toolkit
3
- Version: 1.47.9
3
+ Version: 1.47.11
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Cedric Klinkert
@@ -128,6 +128,13 @@ All notable changes to this project will be documented in this file.
128
128
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
129
129
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
130
130
 
131
+ ## [1.47.11] - 2026-02-26
132
+ - Add `DocxGeneratorService` migration surface: `DocxGeneratorResult`, `generate_from_template_with_result()`, `upload_and_create_reference()`, `resolve_template()`, `normalize_heading_levels()`
133
+ - Fix error handling in `DocxGeneratorService`; tighten `DocxGeneratorConfig.template_fields` to `dict[str, str]`
134
+
135
+ ## [1.47.10] - 2026-02-26
136
+ - Code interpreter: bound `expires_after_minutes` to 1–20 (OpenAI API max), add RJSF `NumberWidget.updown` for UI
137
+
131
138
  ## [1.47.9] - 2026-02-26
132
139
  - Fixing bug with chunk relevancy sorter
133
140
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "unique_toolkit"
3
- version = "1.47.9"
3
+ version = "1.47.11"
4
4
  description = ""
5
5
  authors = [
6
6
  "Cedric Klinkert <cedric.klinkert@unique.ch>",
@@ -0,0 +1,21 @@
1
+ from unique_toolkit._common.docx_generator.config import DocxGeneratorConfig
2
+ from unique_toolkit._common.docx_generator.schemas import (
3
+ ContentField,
4
+ DocxGeneratorResult,
5
+ HeadingField,
6
+ ParagraphField,
7
+ RunField,
8
+ RunsField,
9
+ )
10
+ from unique_toolkit._common.docx_generator.service import DocxGeneratorService
11
+
12
+ __all__ = [
13
+ "DocxGeneratorConfig",
14
+ "DocxGeneratorResult",
15
+ "DocxGeneratorService",
16
+ "ContentField",
17
+ "HeadingField",
18
+ "ParagraphField",
19
+ "RunField",
20
+ "RunsField",
21
+ ]
@@ -0,0 +1,75 @@
1
+ from datetime import datetime
2
+
3
+ from pydantic import BaseModel, Field, field_validator, model_validator
4
+ from pydantic.json_schema import SkipJsonSchema
5
+ from typing_extensions import Self
6
+
7
+ from unique_toolkit._common.pydantic_helpers import get_configuration_dict
8
+
9
+
10
+ class DocxGeneratorConfig(BaseModel):
11
+ model_config = get_configuration_dict()
12
+
13
+ enabled: bool = Field(
14
+ default=True,
15
+ description="Whether to enable the docx generator.",
16
+ )
17
+ upload_suffix: str = Field(
18
+ default="_report_output.docx",
19
+ description="The suffix of the uploaded file.",
20
+ )
21
+ upload_scope_id: str | SkipJsonSchema[None] = Field(
22
+ default=None,
23
+ description="The scope ID where the generated DOCX file will be uploaded. If not provided and upload_to_chat is False, an error will be raised.",
24
+ )
25
+ upload_to_chat: bool = Field(
26
+ default=True,
27
+ description="Whether to upload the file to the chat.",
28
+ )
29
+
30
+ template_content_id: str | SkipJsonSchema[None] = Field(
31
+ default=None,
32
+ description="The content ID of the template file to be found in the templateScopeId. If not provided, the default template will be used.",
33
+ )
34
+
35
+ template_name: str = Field(
36
+ default="template.docx",
37
+ description="The name of the template file to be found in the templateScopeId. If not provided, or match no file, the default template will be used.",
38
+ deprecated="Please use content_id instead",
39
+ )
40
+ template_scope_id: str | SkipJsonSchema[None] = Field(
41
+ default=None,
42
+ description="The scope ID where the template file is stored. If not provided, the default template will be used.",
43
+ deprecated="Please use content_id instead",
44
+ )
45
+
46
+ template_fields: dict[str, str] = Field(
47
+ default_factory=lambda: {
48
+ "date": datetime.now().strftime("%d/%m/%Y"),
49
+ "document_title": "Template Document",
50
+ },
51
+ description="The fields to be replaced in the template.",
52
+ )
53
+
54
+ skip_ingestion: bool = Field(
55
+ default=True,
56
+ description="Whether to skip the ingestion of the file.",
57
+ )
58
+
59
+ @field_validator("template_fields", mode="after", check_fields=True)
60
+ def validate_template_fields(cls, v: dict[str, str]) -> dict[str, str]:
61
+ for key, value in v.items():
62
+ if value == "CURRENT_DATE":
63
+ v[key] = datetime.now().strftime("%d/%m/%Y")
64
+ else:
65
+ v[key] = value
66
+ return v
67
+
68
+ @model_validator(mode="after")
69
+ def validate_upload_to_chat(self) -> Self:
70
+ if not self.enabled:
71
+ return self
72
+
73
+ if not self.upload_to_chat and not self.upload_scope_id:
74
+ raise ValueError("Either upload_to_chat or upload_scope_id must be set")
75
+ return self
@@ -71,3 +71,9 @@ class ContentField(BaseModel):
71
71
 
72
72
  def __str__(self):
73
73
  return f"ContentField(contents={self.contents})"
74
+
75
+
76
+ class DocxGeneratorResult(BaseModel):
77
+ user_message: str
78
+ docx_object: bytes | None = None
79
+ success: bool = False
@@ -0,0 +1,444 @@
1
+ import io
2
+ import logging
3
+ import re
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ from docxtpl import DocxTemplate
8
+ from markdown_it import MarkdownIt
9
+ from unique_sdk._unique_ql import UQLOperator
10
+
11
+ from unique_toolkit._common.docx_generator.config import DocxGeneratorConfig
12
+ from unique_toolkit._common.docx_generator.schemas import (
13
+ ContentField,
14
+ DocxGeneratorResult,
15
+ HeadingField,
16
+ ParagraphField,
17
+ RunField,
18
+ RunsField,
19
+ )
20
+ from unique_toolkit._common.utils.files import FileMimeType
21
+ from unique_toolkit.chat.service import ChatService
22
+ from unique_toolkit.content.schemas import ContentReference
23
+ from unique_toolkit.services.knowledge_base import KnowledgeBaseService
24
+
25
+ generator_dir_path = Path(__file__).resolve().parent
26
+
27
+ _CHAT_FILE_PREFIX_PATTERN = r"Chat_\d{4}-\d{2}-\d{2}_\d{2}:\d{2}_"
28
+
29
+ _LOGGER = logging.getLogger(__name__)
30
+
31
+
32
+ class DocxGeneratorService:
33
+ def __init__(self, config: DocxGeneratorConfig, *, template: bytes | None = None):
34
+ self._config = config
35
+ self._template = template
36
+
37
+ @staticmethod
38
+ def normalize_heading_levels(markdown: str) -> str:
39
+ """Demote H2 and H3 headings by two levels (## → ####, ### → #####).
40
+
41
+ H1 headings are left unchanged. This replicates the heading normalization
42
+ that was baked into the monorepo's parse_markdown_to_list_content_fields()
43
+ and is useful when migrating callers that relied on that behaviour.
44
+
45
+ Content-specific substitutions (e.g. removing "# Relevant sources" or
46
+ renaming "# Proposed answer") are caller concerns and should be applied
47
+ separately before calling this method.
48
+ """
49
+ markdown = re.sub(r"(?m)^[ \t]*## ", "#### ", markdown)
50
+ markdown = re.sub(r"(?m)^[ \t]*### ", "##### ", markdown)
51
+ return markdown
52
+
53
+ @staticmethod
54
+ def parse_markdown_to_list_content_fields(
55
+ markdown: str,
56
+ offset_header_lvl: int = 0,
57
+ normalize_heading_levels: bool = False,
58
+ ) -> list[HeadingField | ParagraphField | RunsField]:
59
+ if normalize_heading_levels:
60
+ markdown = DocxGeneratorService.normalize_heading_levels(markdown)
61
+
62
+ # Initialize markdown-it parser
63
+ md = MarkdownIt()
64
+
65
+ tokens = md.parse(markdown)
66
+
67
+ elements = []
68
+ current_section = {}
69
+ in_list = False
70
+ bullet_list_indent_level = 0
71
+ list_item_open = False
72
+
73
+ for token in tokens:
74
+ if token.type == "bullet_list_open":
75
+ in_list = True
76
+ bullet_list_indent_level = int(token.level / 2)
77
+
78
+ elif token.type == "bullet_list_close":
79
+ in_list = False
80
+ bullet_list_indent_level = 0
81
+
82
+ elif token.type == "list_item_open":
83
+ if list_item_open:
84
+ elements.append(current_section)
85
+ list_item_open = True
86
+ list_level = token.level - bullet_list_indent_level
87
+ current_section = {
88
+ "type": RunsField,
89
+ "runs": [],
90
+ "is_list_item": True,
91
+ "level": list_level,
92
+ }
93
+
94
+ elif token.type == "list_item_close":
95
+ if current_section and current_section.get("runs"):
96
+ elements.append(current_section)
97
+ current_section = {}
98
+ list_item_open = False
99
+
100
+ if token.type == "heading_open":
101
+ # Heading start, token.tag gives the level (e.g., 'h1', 'h2', etc.)
102
+ header_lvl = int(token.tag[1]) # Extract the level number from tag
103
+ current_section = {
104
+ "type": HeadingField,
105
+ "text": "",
106
+ "level": header_lvl + offset_header_lvl,
107
+ }
108
+
109
+ elif token.type == "heading_close":
110
+ if current_section:
111
+ elements.append(current_section)
112
+ current_section = {}
113
+
114
+ elif token.type == "paragraph_open":
115
+ if not in_list: # Only create new paragraph if not in a list
116
+ current_section = {"type": RunsField, "runs": []}
117
+
118
+ elif token.type == "paragraph_close":
119
+ if not in_list and current_section: # Only append if not in a list
120
+ elements.append(current_section)
121
+ current_section = {}
122
+
123
+ elif token.type == "inline":
124
+ if current_section.get("type") == HeadingField:
125
+ content = token.content
126
+ if content.startswith("_page"):
127
+ # replace "_pageXXXX_" with "PageXXXX", where XXXX can be any characters and numbers
128
+ content = re.sub(
129
+ r"^_page([a-zA-Z0-9\s-]+)_(.*?)",
130
+ r"Page\1",
131
+ content,
132
+ )
133
+ bold = True
134
+ current_section["text"] += content
135
+ elif "runs" in current_section:
136
+ bold = False
137
+ italic = False
138
+ runs = []
139
+ if token.children:
140
+ for child in token.children:
141
+ content = child.content
142
+ if child.type == "strong_open":
143
+ bold = True
144
+ elif child.type == "strong_close":
145
+ bold = False
146
+ elif child.type == "em_open":
147
+ italic = True
148
+ elif child.type == "em_close":
149
+ italic = False
150
+ if child.type == "softbreak":
151
+ content += "\n"
152
+ if content: # Only add non-empty content
153
+ runs.append(
154
+ RunField(
155
+ text=content,
156
+ bold=bold,
157
+ italic=italic,
158
+ )
159
+ )
160
+ else:
161
+ runs.append(
162
+ RunField(
163
+ text=token.content,
164
+ bold=bold,
165
+ italic=italic,
166
+ )
167
+ )
168
+
169
+ current_section["runs"].extend(runs)
170
+
171
+ # Process remaining elements
172
+ contents = []
173
+ for element in elements:
174
+ if not element:
175
+ continue
176
+ if element["type"] == HeadingField:
177
+ contents.append(
178
+ HeadingField(
179
+ text=element["text"],
180
+ level=element["level"],
181
+ )
182
+ )
183
+ elif element["type"] == RunsField:
184
+ if element.get("is_list_item", False):
185
+ level: int = min(element.get("level", 1), 5)
186
+ if level > 1:
187
+ style = "List Bullet " + str(level)
188
+ else:
189
+ style = "List Bullet"
190
+ contents.append(RunsField(style=style, runs=element["runs"]))
191
+ else:
192
+ contents.append(RunsField(runs=element["runs"]))
193
+
194
+ return contents
195
+
196
+ def generate_from_template(
197
+ self,
198
+ subdoc_content: list[HeadingField | ParagraphField | RunsField],
199
+ fields: dict | None = None,
200
+ ) -> bytes | None:
201
+ """
202
+ Generate a docx file from a template with the given content.
203
+
204
+ Args:
205
+ subdoc_content: The content to be added to the docx file.
206
+ fields: Other fields to be added to the docx file. Defaults to None.
207
+
208
+ Returns:
209
+ The generated docx file as bytes, or None on error.
210
+ """
211
+ try:
212
+ doc = DocxTemplate(io.BytesIO(self.template))
213
+
214
+ # Seed context with config template_fields (e.g. date, document_title)
215
+ content: dict[str, Any] = dict(self._config.template_fields)
216
+ content["body"] = ContentField(contents=subdoc_content)
217
+
218
+ if fields:
219
+ content.update(fields)
220
+
221
+ for key, value in content.items():
222
+ if isinstance(value, ContentField):
223
+ content[key] = value.add(doc)
224
+
225
+ doc.render(content)
226
+ docx_rendered_object = io.BytesIO()
227
+
228
+ doc.save(docx_rendered_object)
229
+ docx_rendered_object.seek(0)
230
+
231
+ return docx_rendered_object.getvalue()
232
+
233
+ except Exception:
234
+ _LOGGER.exception("Error generating docx")
235
+ return None
236
+
237
+ def generate_from_template_with_result(
238
+ self,
239
+ subdoc_content: list[HeadingField | ParagraphField | RunsField],
240
+ fields: dict | None = None,
241
+ ) -> DocxGeneratorResult:
242
+ """
243
+ Generate a docx file and return a DocxGeneratorResult wrapper.
244
+
245
+ This is a convenience method for callers that previously used the monorepo
246
+ DocxGeneratorService which returned DocxGeneratorResult directly.
247
+
248
+ Args:
249
+ subdoc_content: The content to be added to the docx file.
250
+ fields: Other fields to be added to the docx file. Defaults to None.
251
+
252
+ Returns:
253
+ DocxGeneratorResult with success flag and docx bytes.
254
+ """
255
+ result = self.generate_from_template(subdoc_content, fields)
256
+ if result is not None:
257
+ return DocxGeneratorResult(
258
+ user_message="ℹ️ Template generated successfully!",
259
+ docx_object=result,
260
+ success=True,
261
+ )
262
+ return DocxGeneratorResult(
263
+ user_message="❌ Error generating docx!",
264
+ docx_object=None,
265
+ success=False,
266
+ )
267
+
268
+ def upload_and_create_reference(
269
+ self,
270
+ *,
271
+ docx_object: bytes,
272
+ sequence_number: int,
273
+ file_name: str,
274
+ chat_service: ChatService,
275
+ knowledge_base_service: KnowledgeBaseService | None = None,
276
+ ) -> ContentReference | None:
277
+ """
278
+ Upload a generated DOCX and create a ContentReference for use in chat.
279
+
280
+ Uploads to chat if config.upload_to_chat is True (via chat_service), and
281
+ additionally to a scope if config.upload_scope_id is set (via
282
+ knowledge_base_service). At least one must be configured.
283
+
284
+ Args:
285
+ docx_object: The generated DOCX bytes to upload.
286
+ sequence_number: The sequence number for the ContentReference.
287
+ file_name: The original file name (chat prefix will be stripped).
288
+ chat_service: Used for chat uploads and to resolve the message ID.
289
+ knowledge_base_service: Required when config.upload_scope_id is set.
290
+
291
+ Returns:
292
+ A ContentReference, or None if an error occurs.
293
+ """
294
+ content_id: str | None = None
295
+ try:
296
+ mime_type = FileMimeType.DOCX.value
297
+
298
+ content_name = (
299
+ re.sub(_CHAT_FILE_PREFIX_PATTERN, "", Path(file_name).stem)
300
+ + self._config.upload_suffix
301
+ )
302
+
303
+ if self._config.upload_to_chat:
304
+ created = chat_service.upload_to_chat_from_bytes(
305
+ content=docx_object,
306
+ content_name=content_name,
307
+ mime_type=mime_type,
308
+ skip_ingestion=self._config.skip_ingestion,
309
+ )
310
+ content_id = created.id
311
+
312
+ if self._config.upload_scope_id:
313
+ if knowledge_base_service is None:
314
+ raise ValueError(
315
+ "knowledge_base_service is required when upload_scope_id is set."
316
+ )
317
+ created = knowledge_base_service.upload_content_from_bytes(
318
+ content=docx_object,
319
+ content_name=content_name,
320
+ scope_id=self._config.upload_scope_id,
321
+ mime_type=mime_type,
322
+ skip_ingestion=self._config.skip_ingestion,
323
+ )
324
+ content_id = created.id
325
+
326
+ if content_id is None:
327
+ raise ValueError(
328
+ "No upload destination configured: set upload_to_chat=True or upload_scope_id."
329
+ )
330
+
331
+ return ContentReference(
332
+ id=content_id,
333
+ sequence_number=sequence_number,
334
+ message_id=chat_service._assistant_message_id,
335
+ name=content_name,
336
+ source=content_name,
337
+ source_id=content_id,
338
+ url=f"unique://content/{content_id}",
339
+ )
340
+
341
+ except Exception:
342
+ if content_id is not None:
343
+ _LOGGER.exception(
344
+ "Scope upload failed after chat upload succeeded "
345
+ "(chat content_id=%s); chat content was not rolled back",
346
+ content_id,
347
+ )
348
+ else:
349
+ _LOGGER.exception("Error uploading content")
350
+ return None
351
+
352
+ @staticmethod
353
+ def resolve_template(
354
+ config: DocxGeneratorConfig,
355
+ knowledge_base_service: KnowledgeBaseService,
356
+ ) -> bytes | None:
357
+ """
358
+ Fetch template bytes using config's template_content_id or
359
+ template_name + template_scope_id.
360
+
361
+ Returns None if neither is set (the service will fall back to the
362
+ default bundled template automatically).
363
+
364
+ Args:
365
+ config: The DocxGeneratorConfig with template resolution settings.
366
+ knowledge_base_service: The KnowledgeBaseService to use for downloading.
367
+
368
+ Returns:
369
+ Template bytes, or None to use the default template.
370
+ """
371
+ try:
372
+ if config.template_content_id:
373
+ return DocxGeneratorService._fetch_template_by_content_id(
374
+ config.template_content_id, knowledge_base_service
375
+ )
376
+ elif config.template_name and config.template_scope_id:
377
+ return DocxGeneratorService._fetch_template_by_name(
378
+ config.template_name,
379
+ config.template_scope_id,
380
+ knowledge_base_service,
381
+ )
382
+ except Exception:
383
+ _LOGGER.exception("Error resolving template, falling back to default")
384
+
385
+ return None
386
+
387
+ @staticmethod
388
+ def _fetch_template_by_content_id(
389
+ content_id: str, knowledge_base_service: KnowledgeBaseService
390
+ ) -> bytes:
391
+ content = knowledge_base_service.download_content_to_bytes(
392
+ content_id=content_id
393
+ )
394
+ _LOGGER.info(f"Template downloaded from content ID: {content_id}")
395
+ return content
396
+
397
+ @staticmethod
398
+ def _fetch_template_by_name(
399
+ template_name: str,
400
+ template_scope_id: str,
401
+ knowledge_base_service: KnowledgeBaseService,
402
+ ) -> bytes:
403
+ where_clause: dict = {
404
+ "OR": [
405
+ {
406
+ "title": {UQLOperator.EQUALS: template_name},
407
+ "ownerId": {UQLOperator.EQUALS: template_scope_id},
408
+ },
409
+ {
410
+ "key": {UQLOperator.EQUALS: template_name},
411
+ "ownerId": {UQLOperator.EQUALS: template_scope_id},
412
+ },
413
+ ]
414
+ }
415
+
416
+ contents = knowledge_base_service.search_contents(where=where_clause)
417
+ if len(contents) == 0:
418
+ raise ValueError(
419
+ f"No template found with the name `{template_name}` in knowledge base."
420
+ )
421
+ if len(contents) > 1:
422
+ raise ValueError(
423
+ f"Multiple templates found with the name `{template_name}` in knowledge base."
424
+ )
425
+
426
+ result = DocxGeneratorService._fetch_template_by_content_id(
427
+ contents[0].id, knowledge_base_service
428
+ )
429
+ _LOGGER.info(f"Template downloaded from template name: {template_name}")
430
+ return result
431
+
432
+ def _get_default_template(self) -> bytes:
433
+ generator_dir_path = Path(__file__).resolve().parent
434
+ path = generator_dir_path / "template" / "Doc Template.docx"
435
+
436
+ file_content = path.read_bytes()
437
+
438
+ _LOGGER.info("Template downloaded from default template")
439
+
440
+ return file_content
441
+
442
+ @property
443
+ def template(self) -> bytes:
444
+ return self._template or self._get_default_template()
@@ -91,9 +91,14 @@ class OpenAICodeInterpreterConfig(BaseToolConfig):
91
91
  description="The description of the tool that will be included in the user prompt.",
92
92
  )
93
93
  )
94
- expires_after_minutes: int = Field(
94
+ expires_after_minutes: Annotated[
95
+ int,
96
+ RJSFMetaTag.NumberWidget.updown(min=1, max=20),
97
+ ] = Field(
95
98
  default=20,
96
- description="The number of minutes after which the container will be deleted.",
99
+ ge=1,
100
+ le=20,
101
+ description="Minutes of inactivity after which the container is deleted. Maximum allowed by OpenAI is 20.",
97
102
  )
98
103
  use_auto_container: bool = Field(
99
104
  default=False,
@@ -1,7 +0,0 @@
1
- from unique_toolkit._common.docx_generator.config import DocxGeneratorConfig
2
- from unique_toolkit._common.docx_generator.service import DocxGeneratorService
3
-
4
- __all__ = [
5
- "DocxGeneratorService",
6
- "DocxGeneratorConfig",
7
- ]
@@ -1,12 +0,0 @@
1
- from pydantic import BaseModel, Field
2
-
3
- from unique_toolkit._common.pydantic_helpers import get_configuration_dict
4
-
5
-
6
- class DocxGeneratorConfig(BaseModel):
7
- model_config = get_configuration_dict()
8
-
9
- template_content_id: str = Field(
10
- default="",
11
- description="The content id of the template file uploaded to the knowledge base.",
12
- )