unique_toolkit 1.77.3__tar.gz → 1.78.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/PKG-INFO +1 -1
  2. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/pyproject.toml +1 -1
  3. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/feature_flags/feature_flags.py +11 -0
  4. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/unique_settings.py +16 -0
  5. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/__init__.py +5 -0
  6. unique_toolkit-1.78.1/unique_toolkit/experimental/identity/__init__.py +48 -0
  7. unique_toolkit-1.78.1/unique_toolkit/experimental/identity/functions.py +579 -0
  8. unique_toolkit-1.78.1/unique_toolkit/experimental/identity/schemas.py +200 -0
  9. unique_toolkit-1.78.1/unique_toolkit/experimental/identity/service.py +715 -0
  10. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/services/factory.py +9 -2
  11. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/README.md +0 -0
  12. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/__init__.py +0 -0
  13. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/__init__.py +0 -0
  14. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/_base_service.py +0 -0
  15. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/_time_utils.py +0 -0
  16. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
  17. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
  18. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
  19. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
  20. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
  21. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
  22. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
  23. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/README.md +0 -0
  24. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/__init__.py +0 -0
  25. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/__main__.py +0 -0
  26. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/cli.py +0 -0
  27. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/differ.py +0 -0
  28. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/exporter.py +0 -0
  29. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/models.py +0 -0
  30. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/registry.py +0 -0
  31. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/validator.py +0 -0
  32. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/default_language_model.py +0 -0
  33. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
  34. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/config.py +0 -0
  35. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
  36. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
  37. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/service.py +0 -0
  38. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  39. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/endpoint_builder.py +0 -0
  40. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/endpoint_requestor.py +0 -0
  41. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/event_bus.py +0 -0
  42. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/exception.py +0 -0
  43. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/execution.py +0 -0
  44. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
  45. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
  46. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
  47. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
  48. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
  49. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
  50. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
  51. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
  52. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
  53. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
  54. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
  55. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
  56. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
  57. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
  58. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
  59. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
  60. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
  61. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
  62. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
  63. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
  64. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
  65. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
  66. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
  67. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
  68. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
  69. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
  70. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
  71. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/feature_flags/schema.py +0 -0
  72. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
  73. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/pydantic_helpers.py +0 -0
  74. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/referencing.py +0 -0
  75. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/string_utilities.py +0 -0
  76. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/tests/test_referencing.py +0 -0
  77. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
  78. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/__init__.py +0 -0
  79. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/image_token_counting.py +0 -0
  80. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/token_counting.py +0 -0
  81. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
  82. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
  83. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/__init__.py +0 -0
  84. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/files.py +0 -0
  85. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/image/encode.py +0 -0
  86. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
  87. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/jinja/render.py +0 -0
  88. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
  89. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
  90. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
  91. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
  92. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/write_configuration.py +0 -0
  93. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/validate_required_values.py +0 -0
  94. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/validators.py +0 -0
  95. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/__init__.py +0 -0
  96. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
  97. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
  98. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/config.py +0 -0
  99. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
  100. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
  101. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
  102. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
  103. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
  104. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
  105. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/exception.py +0 -0
  106. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
  107. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
  108. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
  109. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
  110. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
  111. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
  112. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
  113. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
  114. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
  115. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
  116. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
  117. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
  118. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
  119. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
  120. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
  121. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
  122. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/utils.py +0 -0
  123. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
  124. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
  125. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
  126. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
  127. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/history_manager/utils.py +0 -0
  128. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
  129. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
  130. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
  131. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
  132. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
  133. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/base.py +0 -0
  134. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
  135. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
  136. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
  137. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
  138. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
  139. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
  140. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
  141. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
  142. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
  143. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
  144. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
  145. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
  146. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
  147. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
  148. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
  149. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
  150. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
  151. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
  152. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
  153. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
  154. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
  155. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/__init__.py +0 -0
  156. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
  157. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
  158. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
  159. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
  160. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
  161. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
  162. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
  163. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
  164. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
  165. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
  166. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
  167. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
  168. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
  169. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
  170. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
  171. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
  172. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
  173. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
  174. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
  175. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
  176. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
  177. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
  178. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
  179. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
  180. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
  181. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
  182. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
  183. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/config.py +0 -0
  184. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/__init__.py +0 -0
  185. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py +0 -0
  186. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/config.py +0 -0
  187. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py +0 -0
  188. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/tool.py +0 -0
  189. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/__init__.py +0 -0
  190. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/config.py +0 -0
  191. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/__init__.py +0 -0
  192. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/execution_reminder.j2 +0 -0
  193. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/system_prompt.j2 +0 -0
  194. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/tool_description.j2 +0 -0
  195. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/verification_nudge.j2 +0 -0
  196. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/schemas.py +0 -0
  197. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/service.py +0 -0
  198. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/factory.py +0 -0
  199. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
  200. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
  201. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
  202. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
  203. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
  204. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
  205. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
  206. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
  207. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
  208. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
  209. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +0 -0
  210. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
  211. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
  212. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
  213. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/schemas.py +0 -0
  214. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
  215. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
  216. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/tool.py +0 -0
  217. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
  218. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
  219. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
  220. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  221. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
  222. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
  223. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
  224. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic_table/__init__.py +0 -0
  225. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic_table/schemas.py +0 -0
  226. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic_table/service.py +0 -0
  227. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/__init__.py +0 -0
  228. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/chat_event_filter_options_settings.py +0 -0
  229. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/dev_util.py +0 -0
  230. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/fast_api_factory.py +0 -0
  231. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/feature_flags.py +0 -0
  232. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/find_env_file.py +0 -0
  233. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/init_logging.py +0 -0
  234. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/init_sdk.py +0 -0
  235. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/performance/async_tasks.py +0 -0
  236. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/performance/async_wrapper.py +0 -0
  237. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/schemas.py +0 -0
  238. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/verification.py +0 -0
  239. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/webhook.py +0 -0
  240. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/__init__.py +0 -0
  241. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/cancellation.py +0 -0
  242. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/constants.py +0 -0
  243. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/deprecated/service.py +0 -0
  244. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/functions.py +0 -0
  245. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/rendering.py +0 -0
  246. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/responses_api.py +0 -0
  247. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/schemas.py +0 -0
  248. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/service.py +0 -0
  249. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/state.py +0 -0
  250. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/utils.py +0 -0
  251. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/__init__.py +0 -0
  252. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/constants.py +0 -0
  253. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/functions.py +0 -0
  254. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/schemas.py +0 -0
  255. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/service.py +0 -0
  256. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/smart_rules.py +0 -0
  257. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/utils.py +0 -0
  258. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/README.md +0 -0
  259. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/__init__.py +0 -0
  260. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
  261. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/augmented/service.py +0 -0
  262. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/base.py +0 -0
  263. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
  264. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/basic/config.py +0 -0
  265. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
  266. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/basic/service.py +0 -0
  267. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/__init__.py +0 -0
  268. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/constants.py +0 -0
  269. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/exceptions.py +0 -0
  270. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/functions.py +0 -0
  271. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/schemas.py +0 -0
  272. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/service.py +0 -0
  273. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/__init__.py +0 -0
  274. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/constants.py +0 -0
  275. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/functions.py +0 -0
  276. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/schemas.py +0 -0
  277. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/service.py +0 -0
  278. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/utils.py +0 -0
  279. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/__init__.py +0 -0
  280. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/cron.py +0 -0
  281. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/functions.py +0 -0
  282. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/schemas.py +0 -0
  283. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/service.py +0 -0
  284. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/__init__.py +0 -0
  285. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
  286. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
  287. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
  288. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
  289. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/openai/client.py +0 -0
  290. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
  291. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/utils.py +0 -0
  292. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/__init__.py +0 -0
  293. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
  294. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/builder.py +0 -0
  295. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/constants.py +0 -0
  296. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/default_language_model.py +0 -0
  297. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/functions.py +0 -0
  298. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/infos.py +0 -0
  299. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/prompt.py +0 -0
  300. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/reference.py +0 -0
  301. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/schemas.py +0 -0
  302. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/service.py +0 -0
  303. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/stream_transform.py +0 -0
  304. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/utils.py +0 -0
  305. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/monitoring/__init__.py +0 -0
  306. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/monitoring/middleware.py +0 -0
  307. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/monitoring/registry.py +0 -0
  308. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/protocols/support.py +0 -0
  309. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/services/__init__.py +0 -0
  310. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/services/chat_service.py +0 -0
  311. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/services/knowledge_base.py +0 -0
  312. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/__init__.py +0 -0
  313. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/constants.py +0 -0
  314. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/functions.py +0 -0
  315. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/schemas.py +0 -0
  316. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/service.py +0 -0
  317. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/smart_rules/__init__.py +0 -0
  318. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/smart_rules/compile.py +0 -0
  319. {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/test_utilities/events.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-toolkit
3
- Version: 1.77.3
3
+ Version: 1.78.1
4
4
  Summary:
5
5
  Author: Cedric Klinkert, Martin Fadler, Sadique Sheik, Fabian Schläpfer, Pascal Hauri, Ejiroghene Oki-Peter, Rami Azouz, Ricardo Visini, Sanzio Monti
6
6
  Author-email: Cedric Klinkert <cedric.klinkert@unique.ch>, Martin Fadler <martin.fadler@unique.ch>, Sadique Sheik <sadique@unique.ch>, Fabian Schläpfer <fabian@unique.ch>, Pascal Hauri <pascal@unique.ch>, Ejiroghene Oki-Peter <oki-peter.ejiroghene@unique.ai>, Rami Azouz <rami.ext@unique.ch>, Ricardo Visini <ricardo.visini@unique.ch>, Sanzio Monti <sanzio.monti@unique.ai>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique_toolkit"
3
- version = "1.77.3"
3
+ version = "1.78.1"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -91,6 +91,17 @@ class FeatureFlags(BaseSettings):
91
91
  description="Use selected_uploaded_files from event payload instead of querying uploaded files from the backend. Can be 'true' or comma-separated company IDs.",
92
92
  )
93
93
 
94
+ enable_mcp_metadata_fallback_un_19145: FeatureFlag = Field(
95
+ default=FeatureFlag(True),
96
+ description=(
97
+ "When namespaced MCP `_meta` keys (`unique.app/auth/user-id`, "
98
+ "`unique.app/chat/chat-id`, ...) are absent, fall back to the flat camelCase "
99
+ "keys (`userId`, `companyId`, `chatId`, `messageId`) still emitted "
100
+ "by pre-#22513 monorepo builds. Flip to `False` once the monorepo "
101
+ "rollout of namespaced keys is complete."
102
+ ),
103
+ )
104
+
94
105
  model_config = SettingsConfigDict(
95
106
  extra="ignore",
96
107
  env_prefix="FEATURE_FLAG_",
@@ -623,6 +623,22 @@ class UniqueSettings:
623
623
  env_file=self._env_file,
624
624
  )
625
625
 
626
+ def with_chat(self, chat: ChatContextProtocol | None) -> Self:
627
+ """Return a copy of the settings with the new chat context.
628
+
629
+ Passing ``None`` clears any existing chat context; this mirrors the
630
+ semantics of :meth:`with_auth` and is how MCP request handlers opt out
631
+ of chat scoping when the request does not carry chat identifiers.
632
+ """
633
+ return self.__class__(
634
+ auth=self._context.auth,
635
+ app=self.app,
636
+ api=self.api,
637
+ chat_event_filter_options=self.chat_event_filter_options,
638
+ chat=chat,
639
+ env_file=self._env_file,
640
+ )
641
+
626
642
  @property
627
643
  def api(self) -> UniqueApi:
628
644
  return self._env.api
@@ -12,12 +12,17 @@ Currently exposes:
12
12
  - :class:`unique_toolkit.experimental.scheduled_task.ScheduledTasks` — cron-based
13
13
  scheduled tasks that trigger assistants on a recurring schedule (wrapper over
14
14
  :class:`unique_sdk.ScheduledTask`).
15
+ - :class:`unique_toolkit.experimental.identity.Identity` — users + groups
16
+ management (Linux-inspired wrapper over :mod:`unique_sdk.User` and
17
+ :mod:`unique_sdk.Group`).
15
18
  """
16
19
 
20
+ from unique_toolkit.experimental.identity import Identity as Identity
17
21
  from unique_toolkit.experimental.scheduled_task import (
18
22
  ScheduledTasks as ScheduledTasks,
19
23
  )
20
24
 
21
25
  __all__ = [
26
+ "Identity",
22
27
  "ScheduledTasks",
23
28
  ]
@@ -0,0 +1,48 @@
1
+ """``unique_toolkit.experimental.identity`` — user and group directory management.
2
+
3
+ .. warning::
4
+
5
+ **Experimental.** This subpackage is exposed under
6
+ :mod:`unique_toolkit.experimental` and its public API may change without
7
+ notice. It is not covered by the toolkit's normal stability guarantees.
8
+
9
+ A thin, Linux-inspired wrapper around :mod:`unique_sdk.User` and
10
+ :mod:`unique_sdk.Group`. The package exposes:
11
+
12
+ - :class:`Identity` — facade that bundles both sub-services behind
13
+ ``.users`` and ``.groups``.
14
+ - :class:`Users` — CRUD-style API for users (``list``, ``get``,
15
+ ``update_configuration``) plus ``groups_of`` / ``is_member``.
16
+ - :class:`Groups` — CRUD-style API for groups (``list``, ``create``,
17
+ ``delete``, ``rename``, ``update_configuration``) plus
18
+ ``add_members`` / ``remove_members``.
19
+
20
+ The Pydantic response schemas (``UserInfo``, ``GroupInfo``, ...) are also
21
+ re-exported here for convenience.
22
+ """
23
+
24
+ from unique_toolkit.experimental.identity.schemas import (
25
+ GroupDeleted,
26
+ GroupInfo,
27
+ GroupMember,
28
+ GroupMembership,
29
+ GroupWithConfiguration,
30
+ UserGroupMembership,
31
+ UserInfo,
32
+ UserWithConfiguration,
33
+ )
34
+ from unique_toolkit.experimental.identity.service import Groups, Identity, Users
35
+
36
+ __all__ = [
37
+ "GroupDeleted",
38
+ "GroupInfo",
39
+ "GroupMember",
40
+ "GroupMembership",
41
+ "GroupWithConfiguration",
42
+ "Groups",
43
+ "Identity",
44
+ "UserGroupMembership",
45
+ "UserInfo",
46
+ "UserWithConfiguration",
47
+ "Users",
48
+ ]
@@ -0,0 +1,579 @@
1
+ """Low-level function wrappers around :mod:`User` and :mod:`Group`.
2
+
3
+ Each SDK operation gets a ``<verb>`` and ``<verb>_async`` pair. The functions take
4
+ ``user_id`` and ``company_id`` as the first two positional arguments (the acting
5
+ user's credentials) and return toolkit Pydantic models — SDK ``TypedDict``s never
6
+ leak out of this module.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from typing import Any
12
+
13
+ from unique_sdk import Group, User
14
+
15
+ from unique_toolkit.experimental.identity.schemas import (
16
+ GroupDeleted,
17
+ GroupInfo,
18
+ GroupMembership,
19
+ GroupWithConfiguration,
20
+ UserGroupMembership,
21
+ UserInfo,
22
+ UserWithConfiguration,
23
+ )
24
+
25
+ # Default pagination window for list endpoints. Small enough to keep latency
26
+ # predictable, large enough to avoid round-tripping for typical directories.
27
+ DEFAULT_LIST_SKIP = 0
28
+ DEFAULT_LIST_TAKE = 100
29
+
30
+ # ``find_user`` asks for two rows so we can detect ambiguity (zero, one, or
31
+ # "more than one") without paging through the entire result set.
32
+ FIND_USER_TAKE = 2
33
+
34
+ # ── User read operations ──────────────────────────────────────────────────────
35
+
36
+
37
+ def list_users(
38
+ user_id: str,
39
+ company_id: str,
40
+ *,
41
+ skip: int = DEFAULT_LIST_SKIP,
42
+ take: int = DEFAULT_LIST_TAKE,
43
+ email: str | None = None,
44
+ display_name: str | None = None,
45
+ user_name: str | None = None,
46
+ ) -> list[UserInfo]:
47
+ """Page through users in the company.
48
+
49
+ ``skip``/``take`` default to a 0/:data:`DEFAULT_LIST_TAKE` window; all other
50
+ filters are optional and omitted from the request when ``None``.
51
+ """
52
+ params = _build_list_users_params(
53
+ skip=skip,
54
+ take=take,
55
+ email=email,
56
+ display_name=display_name,
57
+ user_name=user_name,
58
+ )
59
+ result = User.get_users(user_id=user_id, company_id=company_id, **params)
60
+ return [
61
+ UserInfo.model_validate(u, by_alias=True, by_name=True) for u in result["users"]
62
+ ]
63
+
64
+
65
+ async def list_users_async(
66
+ user_id: str,
67
+ company_id: str,
68
+ *,
69
+ skip: int = DEFAULT_LIST_SKIP,
70
+ take: int = DEFAULT_LIST_TAKE,
71
+ email: str | None = None,
72
+ display_name: str | None = None,
73
+ user_name: str | None = None,
74
+ ) -> list[UserInfo]:
75
+ """Async :func:`list_users`."""
76
+ params = _build_list_users_params(
77
+ skip=skip,
78
+ take=take,
79
+ email=email,
80
+ display_name=display_name,
81
+ user_name=user_name,
82
+ )
83
+ result = await User.get_users_async(
84
+ user_id=user_id, company_id=company_id, **params
85
+ )
86
+ return [
87
+ UserInfo.model_validate(u, by_alias=True, by_name=True) for u in result["users"]
88
+ ]
89
+
90
+
91
+ def get_user_by_id(
92
+ user_id: str,
93
+ company_id: str,
94
+ *,
95
+ target_user_id: str,
96
+ ) -> UserInfo:
97
+ """Fetch a single user by canonical id."""
98
+ payload = User.get_by_id(
99
+ user_id=user_id,
100
+ company_id=company_id,
101
+ target_user_id=target_user_id,
102
+ )
103
+ return UserInfo.model_validate(payload, by_alias=True, by_name=True)
104
+
105
+
106
+ async def get_user_by_id_async(
107
+ user_id: str,
108
+ company_id: str,
109
+ *,
110
+ target_user_id: str,
111
+ ) -> UserInfo:
112
+ """Async :func:`get_user_by_id`."""
113
+ payload = await User.get_by_id_async(
114
+ user_id=user_id,
115
+ company_id=company_id,
116
+ target_user_id=target_user_id,
117
+ )
118
+ return UserInfo.model_validate(payload, by_alias=True, by_name=True)
119
+
120
+
121
+ def find_user(
122
+ user_id: str,
123
+ company_id: str,
124
+ *,
125
+ email: str | None = None,
126
+ user_name: str | None = None,
127
+ ) -> UserInfo:
128
+ """Resolve a user by email or username using a filtered :func:`list_users` call.
129
+
130
+ Raises :class:`LookupError` when the filter matches zero or more than one user.
131
+ """
132
+ if (email is None) == (user_name is None):
133
+ raise TypeError("find_user: pass exactly one of email= or user_name=.")
134
+ matches = list_users(
135
+ user_id=user_id,
136
+ company_id=company_id,
137
+ email=email,
138
+ user_name=user_name,
139
+ take=FIND_USER_TAKE,
140
+ )
141
+ return _only_match(matches, email=email, user_name=user_name)
142
+
143
+
144
+ async def find_user_async(
145
+ user_id: str,
146
+ company_id: str,
147
+ *,
148
+ email: str | None = None,
149
+ user_name: str | None = None,
150
+ ) -> UserInfo:
151
+ """Async :func:`find_user`."""
152
+ if (email is None) == (user_name is None):
153
+ raise TypeError("find_user: pass exactly one of email= or user_name=.")
154
+ matches = await list_users_async(
155
+ user_id=user_id,
156
+ company_id=company_id,
157
+ email=email,
158
+ user_name=user_name,
159
+ take=FIND_USER_TAKE,
160
+ )
161
+ return _only_match(matches, email=email, user_name=user_name)
162
+
163
+
164
+ def get_user_groups(
165
+ user_id: str,
166
+ company_id: str,
167
+ *,
168
+ target_user_id: str,
169
+ ) -> list[UserGroupMembership]:
170
+ """List the groups a user belongs to (``groups <user>``)."""
171
+ payload = User.get_user_groups(
172
+ user_id=user_id,
173
+ company_id=company_id,
174
+ target_user_id=target_user_id,
175
+ )
176
+ return [
177
+ UserGroupMembership.model_validate(g, by_alias=True, by_name=True)
178
+ for g in payload["groups"]
179
+ ]
180
+
181
+
182
+ async def get_user_groups_async(
183
+ user_id: str,
184
+ company_id: str,
185
+ *,
186
+ target_user_id: str,
187
+ ) -> list[UserGroupMembership]:
188
+ """Async :func:`get_user_groups`."""
189
+ payload = await User.get_user_groups_async(
190
+ user_id=user_id,
191
+ company_id=company_id,
192
+ target_user_id=target_user_id,
193
+ )
194
+ return [
195
+ UserGroupMembership.model_validate(g, by_alias=True, by_name=True)
196
+ for g in payload["groups"]
197
+ ]
198
+
199
+
200
+ def update_user_configuration(
201
+ user_id: str,
202
+ company_id: str,
203
+ *,
204
+ target_user_id: str,
205
+ configuration: dict[str, Any],
206
+ ) -> UserWithConfiguration:
207
+ """Replace the target user's ``user_configuration`` blob.
208
+
209
+ The SDK only supports this call for ``target_user_id == user_id`` (the acting
210
+ user). Callers that need to mutate other users' config must delegate to a
211
+ service user.
212
+
213
+ :raises ValueError: when ``target_user_id`` differs from the acting
214
+ ``user_id`` — the underlying SDK endpoint only updates the acting
215
+ user's own configuration, so any other target would be silently
216
+ ignored.
217
+ """
218
+ _assert_self_update(user_id=user_id, target_user_id=target_user_id)
219
+ payload = User.update_user_configuration(
220
+ user_id=target_user_id,
221
+ company_id=company_id,
222
+ userConfiguration=configuration,
223
+ )
224
+ return UserWithConfiguration.model_validate(payload, by_alias=True, by_name=True)
225
+
226
+
227
+ async def update_user_configuration_async(
228
+ user_id: str,
229
+ company_id: str,
230
+ *,
231
+ target_user_id: str,
232
+ configuration: dict[str, Any],
233
+ ) -> UserWithConfiguration:
234
+ """Async :func:`update_user_configuration`.
235
+
236
+ :raises ValueError: when ``target_user_id`` differs from the acting
237
+ ``user_id``. See :func:`update_user_configuration` for rationale.
238
+ """
239
+ _assert_self_update(user_id=user_id, target_user_id=target_user_id)
240
+ payload = await User.update_user_configuration_async(
241
+ user_id=target_user_id,
242
+ company_id=company_id,
243
+ userConfiguration=configuration,
244
+ )
245
+ return UserWithConfiguration.model_validate(payload, by_alias=True, by_name=True)
246
+
247
+
248
+ # ── Group CRUD ────────────────────────────────────────────────────────────────
249
+
250
+
251
+ def list_groups(
252
+ user_id: str,
253
+ company_id: str,
254
+ *,
255
+ skip: int = DEFAULT_LIST_SKIP,
256
+ take: int = DEFAULT_LIST_TAKE,
257
+ name: str | None = None,
258
+ ) -> list[GroupInfo]:
259
+ """Page through groups in the company (``getent group``).
260
+
261
+ ``skip``/``take`` default to a 0/:data:`DEFAULT_LIST_TAKE` window.
262
+ """
263
+ params = _build_list_groups_params(skip=skip, take=take, name=name)
264
+ result = Group.get_groups(user_id=user_id, company_id=company_id, **params)
265
+ return [
266
+ GroupInfo.model_validate(g, by_alias=True, by_name=True)
267
+ for g in result["groups"]
268
+ ]
269
+
270
+
271
+ async def list_groups_async(
272
+ user_id: str,
273
+ company_id: str,
274
+ *,
275
+ skip: int = DEFAULT_LIST_SKIP,
276
+ take: int = DEFAULT_LIST_TAKE,
277
+ name: str | None = None,
278
+ ) -> list[GroupInfo]:
279
+ """Async :func:`list_groups`."""
280
+ params = _build_list_groups_params(skip=skip, take=take, name=name)
281
+ result = await Group.get_groups_async(
282
+ user_id=user_id, company_id=company_id, **params
283
+ )
284
+ return [
285
+ GroupInfo.model_validate(g, by_alias=True, by_name=True)
286
+ for g in result["groups"]
287
+ ]
288
+
289
+
290
+ def create_group(
291
+ user_id: str,
292
+ company_id: str,
293
+ *,
294
+ name: str,
295
+ parent_id: str | None = None,
296
+ external_id: str | None = None,
297
+ ) -> GroupInfo:
298
+ """Create a group (``groupadd``)."""
299
+ params = _build_create_group_params(
300
+ name=name, parent_id=parent_id, external_id=external_id
301
+ )
302
+ payload = Group.create_group(user_id=user_id, company_id=company_id, **params)
303
+ return GroupInfo.model_validate(payload, by_alias=True, by_name=True)
304
+
305
+
306
+ async def create_group_async(
307
+ user_id: str,
308
+ company_id: str,
309
+ *,
310
+ name: str,
311
+ parent_id: str | None = None,
312
+ external_id: str | None = None,
313
+ ) -> GroupInfo:
314
+ """Async :func:`create_group`."""
315
+ params = _build_create_group_params(
316
+ name=name, parent_id=parent_id, external_id=external_id
317
+ )
318
+ payload = await Group.create_group_async(
319
+ user_id=user_id, company_id=company_id, **params
320
+ )
321
+ return GroupInfo.model_validate(payload, by_alias=True, by_name=True)
322
+
323
+
324
+ def delete_group(
325
+ user_id: str,
326
+ company_id: str,
327
+ *,
328
+ group_id: str,
329
+ ) -> GroupDeleted:
330
+ """Delete a group (``groupdel``)."""
331
+ payload = Group.delete_group(
332
+ user_id=user_id, company_id=company_id, group_id=group_id
333
+ )
334
+ return GroupDeleted.model_validate(payload, by_alias=True, by_name=True)
335
+
336
+
337
+ async def delete_group_async(
338
+ user_id: str,
339
+ company_id: str,
340
+ *,
341
+ group_id: str,
342
+ ) -> GroupDeleted:
343
+ """Async :func:`delete_group`."""
344
+ payload = await Group.delete_group_async(
345
+ user_id=user_id, company_id=company_id, group_id=group_id
346
+ )
347
+ return GroupDeleted.model_validate(payload, by_alias=True, by_name=True)
348
+
349
+
350
+ def rename_group(
351
+ user_id: str,
352
+ company_id: str,
353
+ *,
354
+ group_id: str,
355
+ new_name: str,
356
+ ) -> GroupInfo:
357
+ """Rename a group (``groupmod -n``). Name is the only renameable top-level field."""
358
+ payload = Group.update_group(
359
+ user_id=user_id,
360
+ company_id=company_id,
361
+ group_id=group_id,
362
+ name=new_name,
363
+ )
364
+ return GroupInfo.model_validate(payload, by_alias=True, by_name=True)
365
+
366
+
367
+ async def rename_group_async(
368
+ user_id: str,
369
+ company_id: str,
370
+ *,
371
+ group_id: str,
372
+ new_name: str,
373
+ ) -> GroupInfo:
374
+ """Async :func:`rename_group`."""
375
+ payload = await Group.update_group_async(
376
+ user_id=user_id,
377
+ company_id=company_id,
378
+ group_id=group_id,
379
+ name=new_name,
380
+ )
381
+ return GroupInfo.model_validate(payload, by_alias=True, by_name=True)
382
+
383
+
384
+ def update_group_configuration(
385
+ user_id: str,
386
+ company_id: str,
387
+ *,
388
+ group_id: str,
389
+ configuration: dict[str, Any],
390
+ ) -> GroupWithConfiguration:
391
+ """Replace a group's free-form configuration blob."""
392
+ payload = Group.update_group_configuration(
393
+ user_id=user_id,
394
+ company_id=company_id,
395
+ group_id=group_id,
396
+ configuration=configuration,
397
+ )
398
+ return GroupWithConfiguration.model_validate(payload, by_alias=True, by_name=True)
399
+
400
+
401
+ async def update_group_configuration_async(
402
+ user_id: str,
403
+ company_id: str,
404
+ *,
405
+ group_id: str,
406
+ configuration: dict[str, Any],
407
+ ) -> GroupWithConfiguration:
408
+ """Async :func:`update_group_configuration`."""
409
+ payload = await Group.update_group_configuration_async(
410
+ user_id=user_id,
411
+ company_id=company_id,
412
+ group_id=group_id,
413
+ configuration=configuration,
414
+ )
415
+ return GroupWithConfiguration.model_validate(payload, by_alias=True, by_name=True)
416
+
417
+
418
+ # ── Group membership ──────────────────────────────────────────────────────────
419
+
420
+
421
+ def add_group_members(
422
+ user_id: str,
423
+ company_id: str,
424
+ *,
425
+ group_id: str,
426
+ user_ids: list[str],
427
+ ) -> list[GroupMembership]:
428
+ """Add users to a group (``gpasswd -a``). Bulk."""
429
+ if not user_ids:
430
+ raise ValueError("add_group_members: user_ids must not be empty.")
431
+ payload = Group.add_users_to_group(
432
+ user_id=user_id,
433
+ company_id=company_id,
434
+ group_id=group_id,
435
+ userIds=user_ids,
436
+ )
437
+ return [
438
+ GroupMembership.model_validate(m, by_alias=True, by_name=True)
439
+ for m in payload["memberships"]
440
+ ]
441
+
442
+
443
+ async def add_group_members_async(
444
+ user_id: str,
445
+ company_id: str,
446
+ *,
447
+ group_id: str,
448
+ user_ids: list[str],
449
+ ) -> list[GroupMembership]:
450
+ """Async :func:`add_group_members`."""
451
+ if not user_ids:
452
+ raise ValueError("add_group_members: user_ids must not be empty.")
453
+ payload = await Group.add_users_to_group_async(
454
+ user_id=user_id,
455
+ company_id=company_id,
456
+ group_id=group_id,
457
+ userIds=user_ids,
458
+ )
459
+ return [
460
+ GroupMembership.model_validate(m, by_alias=True, by_name=True)
461
+ for m in payload["memberships"]
462
+ ]
463
+
464
+
465
+ def remove_group_members(
466
+ user_id: str,
467
+ company_id: str,
468
+ *,
469
+ group_id: str,
470
+ user_ids: list[str],
471
+ ) -> bool:
472
+ """Remove users from a group (``gpasswd -d``). Returns the API success flag."""
473
+ if not user_ids:
474
+ raise ValueError("remove_group_members: user_ids must not be empty.")
475
+ payload = Group.remove_users_from_group(
476
+ user_id=user_id,
477
+ company_id=company_id,
478
+ group_id=group_id,
479
+ userIds=user_ids,
480
+ )
481
+ return bool(payload["success"])
482
+
483
+
484
+ async def remove_group_members_async(
485
+ user_id: str,
486
+ company_id: str,
487
+ *,
488
+ group_id: str,
489
+ user_ids: list[str],
490
+ ) -> bool:
491
+ """Async :func:`remove_group_members`."""
492
+ if not user_ids:
493
+ raise ValueError("remove_group_members: user_ids must not be empty.")
494
+ payload = await Group.remove_users_from_group_async(
495
+ user_id=user_id,
496
+ company_id=company_id,
497
+ group_id=group_id,
498
+ userIds=user_ids,
499
+ )
500
+ return bool(payload["success"])
501
+
502
+
503
+ # ── Private helpers ───────────────────────────────────────────────────────────
504
+
505
+
506
+ def _build_list_users_params(
507
+ *,
508
+ skip: int,
509
+ take: int,
510
+ email: str | None,
511
+ display_name: str | None,
512
+ user_name: str | None,
513
+ ) -> dict[str, Any]:
514
+ params: dict[str, Any] = {"skip": skip, "take": take}
515
+ if email is not None:
516
+ params["email"] = email
517
+ if display_name is not None:
518
+ params["displayName"] = display_name
519
+ if user_name is not None:
520
+ params["userName"] = user_name
521
+ return params
522
+
523
+
524
+ def _build_list_groups_params(
525
+ *,
526
+ skip: int,
527
+ take: int,
528
+ name: str | None,
529
+ ) -> dict[str, Any]:
530
+ params: dict[str, Any] = {"skip": skip, "take": take}
531
+ if name is not None:
532
+ params["name"] = name
533
+ return params
534
+
535
+
536
+ def _build_create_group_params(
537
+ *,
538
+ name: str,
539
+ parent_id: str | None,
540
+ external_id: str | None,
541
+ ) -> dict[str, Any]:
542
+ params: dict[str, Any] = {"name": name}
543
+ if parent_id is not None:
544
+ params["parentId"] = parent_id
545
+ if external_id is not None:
546
+ params["externalId"] = external_id
547
+ return params
548
+
549
+
550
+ def _assert_self_update(*, user_id: str, target_user_id: str) -> None:
551
+ """Fail fast when an update-configuration call targets another user.
552
+
553
+ ``unique_sdk.User.update_user_configuration`` is authenticated as
554
+ ``user_id`` and always writes to that same user's configuration — the
555
+ ``target_user_id`` would otherwise be silently swapped in as the acting
556
+ user. Raising here keeps the intent of the caller honest.
557
+ """
558
+ if target_user_id != user_id:
559
+ raise ValueError(
560
+ "update_user_configuration: target_user_id must equal user_id; the "
561
+ "underlying SDK endpoint only updates the acting user's own "
562
+ f"configuration (got user_id={user_id!r}, target_user_id={target_user_id!r})."
563
+ )
564
+
565
+
566
+ def _only_match(
567
+ matches: list[UserInfo],
568
+ *,
569
+ email: str | None,
570
+ user_name: str | None,
571
+ ) -> UserInfo:
572
+ criterion = f"email={email!r}" if email is not None else f"user_name={user_name!r}"
573
+ if len(matches) == 0:
574
+ raise LookupError(f"find_user: no user matches {criterion}.")
575
+ if len(matches) > 1:
576
+ raise LookupError(
577
+ f"find_user: {len(matches)} users match {criterion}; refine the filter."
578
+ )
579
+ return matches[0]