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