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.
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/PKG-INFO +1 -1
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/pyproject.toml +1 -1
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/feature_flags/feature_flags.py +11 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/unique_settings.py +16 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/__init__.py +5 -0
- unique_toolkit-1.78.1/unique_toolkit/experimental/identity/__init__.py +48 -0
- unique_toolkit-1.78.1/unique_toolkit/experimental/identity/functions.py +579 -0
- unique_toolkit-1.78.1/unique_toolkit/experimental/identity/schemas.py +200 -0
- unique_toolkit-1.78.1/unique_toolkit/experimental/identity/service.py +715 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/services/factory.py +9 -2
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/README.md +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/_base_service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/_time_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/README.md +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/__main__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/cli.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/differ.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/exporter.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/models.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/registry.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/config_checker/validator.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/default_language_model.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/endpoint_builder.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/endpoint_requestor.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/event_bus.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/exception.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/execution.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
- {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
- {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
- {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
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
- {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
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/feature_flags/schema.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/pydantic_helpers.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/referencing.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/string_utilities.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/tests/test_referencing.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/image_token_counting.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/token_counting.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/files.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/image/encode.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/jinja/render.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/utils/write_configuration.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/validate_required_values.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/_common/validators.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/exception.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/evaluation/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/history_manager/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/base.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
- {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
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/tool.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/execution_reminder.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/tool_description.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/prompts/verification_nudge.j2 +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/experimental/todo/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/factory.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/tool.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic_table/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic_table/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/agentic_table/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/chat_event_filter_options_settings.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/dev_util.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/fast_api_factory.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/feature_flags.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/find_env_file.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/init_logging.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/init_sdk.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/performance/async_tasks.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/performance/async_wrapper.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/verification.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/app/webhook.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/cancellation.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/constants.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/deprecated/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/functions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/rendering.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/responses_api.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/state.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/chat/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/constants.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/functions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/smart_rules.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/content/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/README.md +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/augmented/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/base.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/basic/config.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/data_extraction/basic/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/constants.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/exceptions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/functions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/elicitation/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/constants.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/functions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/embedding/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/cron.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/functions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/experimental/scheduled_task/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/openai/client.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/framework_utilities/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/builder.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/constants.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/default_language_model.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/functions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/infos.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/prompt.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/reference.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/stream_transform.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/language_model/utils.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/monitoring/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/monitoring/middleware.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/monitoring/registry.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/protocols/support.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/services/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/services/chat_service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/services/knowledge_base.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/constants.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/functions.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/schemas.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/short_term_memory/service.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/smart_rules/__init__.py +0 -0
- {unique_toolkit-1.77.3 → unique_toolkit-1.78.1}/unique_toolkit/smart_rules/compile.py +0 -0
- {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.
|
|
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>
|
|
@@ -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]
|