unique_toolkit 1.38.3__tar.gz → 1.39.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/CHANGELOG.md +6 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/PKG-INFO +28 -20
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/README.md +22 -20
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/pyproject.toml +1 -1
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/loop_runner/__init__.py +15 -5
- unique_toolkit-1.39.0/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +95 -0
- unique_toolkit-1.39.0/unique_toolkit/agentic/loop_runner/middleware/__init__.py +11 -0
- unique_toolkit-1.39.0/unique_toolkit/agentic/loop_runner/runners/__init__.py +19 -0
- unique_toolkit-1.39.0/unique_toolkit/agentic/loop_runner/runners/basic.py +46 -0
- unique_toolkit-1.39.0/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +15 -0
- {unique_toolkit-1.38.3/unique_toolkit/agentic/loop_runner/middleware/qwen_forced_tool_call → unique_toolkit-1.39.0/unique_toolkit/agentic/loop_runner/runners/qwen}/helpers.py +15 -0
- unique_toolkit-1.39.0/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +118 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/schemas.py +15 -7
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/services/chat_service.py +409 -1
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/short_term_memory/functions.py +126 -4
- unique_toolkit-1.39.0/unique_toolkit/short_term_memory/schemas.py +54 -0
- unique_toolkit-1.38.3/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -19
- unique_toolkit-1.38.3/unique_toolkit/agentic/loop_runner/middleware/qwen_forced_tool_call/__init__.py +0 -13
- unique_toolkit-1.38.3/unique_toolkit/agentic/loop_runner/middleware/qwen_forced_tool_call/qwen_forced_tool_call.py +0 -50
- unique_toolkit-1.38.3/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -6
- unique_toolkit-1.38.3/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -96
- unique_toolkit-1.38.3/unique_toolkit/short_term_memory/schemas.py +0 -49
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/LICENSE +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/_base_service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/_time_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/default_language_model.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/docx_generator/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/docx_generator/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/endpoint_builder.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/endpoint_requestor.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/exception.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/execution.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/feature_flags/schema.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/pydantic_helpers.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/referencing.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/string_utilities.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/tests/test_referencing.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/token/image_token_counting.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/token/token_counting.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/files.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/image/encode.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/jinja/render.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/utils/write_configuration.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/validate_required_values.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/_common/validators.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/context_relevancy/prompts.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/exception.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/hallucination/prompts.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/history_manager/utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/loop_runner/base.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/factory.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/schemas.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/tool.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/dev_util.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/fast_api_factory.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/init_logging.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/init_sdk.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/performance/async_tasks.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/performance/async_wrapper.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/unique_settings.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/verification.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/app/webhook.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/constants.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/deprecated/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/functions.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/rendering.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/responses_api.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/schemas.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/state.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/chat/utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/content/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/content/constants.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/content/functions.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/content/schemas.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/content/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/content/smart_rules.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/content/utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/README.md +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/augmented/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/base.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/basic/config.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/data_extraction/basic/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/embedding/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/embedding/constants.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/embedding/functions.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/embedding/schemas.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/embedding/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/embedding/utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/framework_utilities/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/framework_utilities/openai/client.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/framework_utilities/utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/builder.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/constants.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/default_language_model.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/functions.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/infos.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/prompt.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/reference.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/schemas.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/language_model/utils.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/protocols/support.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/services/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/services/knowledge_base.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/short_term_memory/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/short_term_memory/constants.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/short_term_memory/service.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/smart_rules/__init__.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/smart_rules/compile.py +0 -0
- {unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/test_utilities/events.py +0 -0
|
@@ -5,6 +5,12 @@ 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.39.0] - 2025-12-17
|
|
9
|
+
- Adding simpler shortterm message abilities to chat service
|
|
10
|
+
|
|
11
|
+
## [1.38.4] - 2025-12-17
|
|
12
|
+
- Improving handling of tool calls with Qwen models
|
|
13
|
+
|
|
8
14
|
## [1.38.3] - 2025-12-17
|
|
9
15
|
- Move the failsafe exception to root folder of unique_toolkit from agentic tools
|
|
10
16
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: unique_toolkit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.39.0
|
|
4
4
|
Summary:
|
|
5
5
|
License: Proprietary
|
|
6
6
|
Author: Cedric Klinkert
|
|
@@ -41,9 +41,25 @@ The Toolkit is structured along the following domains:
|
|
|
41
41
|
- `unique_toolkit.language_model`
|
|
42
42
|
- `unique_toolkit.short_term_memory`
|
|
43
43
|
|
|
44
|
-
Each domain comprises a set of
|
|
44
|
+
Each domain comprises a set of schemas (in `schemas.py`) are used in functions (in `functions.py`) which encapsulates the basic functionalities to interact with the plattform.
|
|
45
|
+
The above domains represent the internal structure of the Unique platform.
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
For the `developers` we expose interfaces via `services` classes that correspond directly to an frontend or an entity the `user` interacts with.
|
|
48
|
+
|
|
49
|
+
The following services are currently available:
|
|
50
|
+
|
|
51
|
+
| Service | Responsability |
|
|
52
|
+
|--|--|
|
|
53
|
+
| ChatService | All interactions with the chat interface |
|
|
54
|
+
| KnowledgeBaseService | All interaction with the knowledgebase |
|
|
55
|
+
|
|
56
|
+
The services can be directly import as
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
from unique_toolkit import ChatService, KnowledgeBaseService
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
In addition, the `unique_toolkit.app` module provides functions to initialize apps and dev utilities to interact with the Unique platform.
|
|
47
63
|
|
|
48
64
|
## Changelog
|
|
49
65
|
|
|
@@ -65,7 +81,6 @@ The `unique_toolkit.app` module encompasses functions for initializing and secur
|
|
|
65
81
|
The `unique_toolkit.chat` module encompasses all chat related functionality.
|
|
66
82
|
|
|
67
83
|
- `functions.py` comprises the functions to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message.
|
|
68
|
-
- `service.py` comprises the ChatService and provides an interface to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message and stream complete.
|
|
69
84
|
- `schemas.py` comprises all relevant schemas, e.g., ChatMessage, used in the ChatService.
|
|
70
85
|
- `utils.py` comprises utility functions to use and convert ChatMessage objects in assistants, e.g., convert_chat_history_to_injectable_string converts the chat history to a string that can be injected into a prompt.
|
|
71
86
|
|
|
@@ -74,11 +89,10 @@ The `unique_toolkit.chat` module encompasses all chat related functionality.
|
|
|
74
89
|
The `unique_toolkit.content` module encompasses all content related functionality. Content can be any type of textual data that is stored in the Knowledgebase on the Unique platform. During the ingestion of the content, the content is parsed, split in chunks, indexed, and stored in the database.
|
|
75
90
|
|
|
76
91
|
- `functions.py` comprises the functions to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message.
|
|
77
|
-
- `service.py` comprises the ContentService and provides an interface to interact with the content, e.g., search content, search content chunks, upload and download content.
|
|
78
92
|
- `schemas.py` comprises all relevant schemas, e.g., Content and ContentChunk, used in the ContentService.
|
|
79
93
|
- `utils.py` comprise utility functions to manipulate Content and ContentChunk objects, e.g., sort_content_chunks and merge_content_chunks.
|
|
80
94
|
|
|
81
|
-
## Embedding
|
|
95
|
+
## Embedding (To be Deprecated)
|
|
82
96
|
|
|
83
97
|
The `unique_toolkit.embedding` module encompasses all embedding related functionality. Embeddings are used to represent textual data in a high-dimensional space. The embeddings can be used to calculate the similarity between two texts, for instance.
|
|
84
98
|
|
|
@@ -86,34 +100,22 @@ The `unique_toolkit.embedding` module encompasses all embedding related function
|
|
|
86
100
|
- `service.py` encompasses the EmbeddingService and provides an interface to interact with the embeddings, e.g., embed text and calculate the similarity between two texts.
|
|
87
101
|
- `schemas.py` comprises all relevant schemas, e.g., Embeddings, used in the EmbeddingService.
|
|
88
102
|
|
|
89
|
-
## Language Model
|
|
103
|
+
## Language Model
|
|
90
104
|
|
|
91
105
|
The `unique_toolkit.language_model` module encompasses all language model related functionality and information on the different language models deployed through the
|
|
92
106
|
Unique platform.
|
|
93
107
|
|
|
94
108
|
- `infos.py` comprises the information on all language models deployed through the Unique platform. We recommend to use the LanguageModel class, initialized with the LanguageModelName, e.g., LanguageModel(LanguageModelName.AZURE_GPT_4o_2024_1120) to get the information on the specific language model like the name, version, token limits or retirement date.
|
|
95
109
|
- `functions.py` comprises the functions to complete and stream complete to chat.
|
|
96
|
-
- `service.py` comprises the LanguageModelService and provides an interface to interact with the language models, e.g., complete.
|
|
97
110
|
- `schemas.py` comprises all relevant schemas, e.g., LanguageModelResponse, used in the LanguageModelService.
|
|
98
111
|
- `utils.py` comprises utility functions to parse the output of the language model, e.g., convert_string_to_json finds and parses the last json object in a string.
|
|
99
112
|
|
|
100
|
-
## Short Term Memory
|
|
113
|
+
## Short Term Memory
|
|
101
114
|
|
|
102
115
|
The `unique_toolkit.short_term_memory` module encompasses all short term memory related functionality.
|
|
103
116
|
|
|
104
117
|
- `functions.py` comprises the functions to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message.
|
|
105
|
-
- `service.py` comprises the ShortTermMemoryService and provides an interface to interact with the short term memory, e.g., create memory.
|
|
106
118
|
- `schemas.py` comprises all relevant schemas, e.g., ShortTermMemory, used in the ShortTermMemoryService.
|
|
107
|
-
|
|
108
|
-
# Development instructions
|
|
109
|
-
|
|
110
|
-
1. Install poetry on your system (through `brew` or `pipx`).
|
|
111
|
-
|
|
112
|
-
2. Install `pyenv` and install python 3.11. `pyenv` is recommended as otherwise poetry uses the python version used to install itself and not the user preferred python version.
|
|
113
|
-
|
|
114
|
-
3. If you then run `python --version` in your terminal, you should be able to see python version as specified in `.python-version`.
|
|
115
|
-
|
|
116
|
-
4. Then finally run `poetry install` to install the package and all dependencies.
|
|
117
119
|
# Changelog
|
|
118
120
|
|
|
119
121
|
All notable changes to this project will be documented in this file.
|
|
@@ -121,6 +123,12 @@ All notable changes to this project will be documented in this file.
|
|
|
121
123
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
122
124
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
123
125
|
|
|
126
|
+
## [1.39.0] - 2025-12-17
|
|
127
|
+
- Adding simpler shortterm message abilities to chat service
|
|
128
|
+
|
|
129
|
+
## [1.38.4] - 2025-12-17
|
|
130
|
+
- Improving handling of tool calls with Qwen models
|
|
131
|
+
|
|
124
132
|
## [1.38.3] - 2025-12-17
|
|
125
133
|
- Move the failsafe exception to root folder of unique_toolkit from agentic tools
|
|
126
134
|
|
|
@@ -9,9 +9,25 @@ The Toolkit is structured along the following domains:
|
|
|
9
9
|
- `unique_toolkit.language_model`
|
|
10
10
|
- `unique_toolkit.short_term_memory`
|
|
11
11
|
|
|
12
|
-
Each domain comprises a set of
|
|
12
|
+
Each domain comprises a set of schemas (in `schemas.py`) are used in functions (in `functions.py`) which encapsulates the basic functionalities to interact with the plattform.
|
|
13
|
+
The above domains represent the internal structure of the Unique platform.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
For the `developers` we expose interfaces via `services` classes that correspond directly to an frontend or an entity the `user` interacts with.
|
|
16
|
+
|
|
17
|
+
The following services are currently available:
|
|
18
|
+
|
|
19
|
+
| Service | Responsability |
|
|
20
|
+
|--|--|
|
|
21
|
+
| ChatService | All interactions with the chat interface |
|
|
22
|
+
| KnowledgeBaseService | All interaction with the knowledgebase |
|
|
23
|
+
|
|
24
|
+
The services can be directly import as
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
from unique_toolkit import ChatService, KnowledgeBaseService
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
In addition, the `unique_toolkit.app` module provides functions to initialize apps and dev utilities to interact with the Unique platform.
|
|
15
31
|
|
|
16
32
|
## Changelog
|
|
17
33
|
|
|
@@ -33,7 +49,6 @@ The `unique_toolkit.app` module encompasses functions for initializing and secur
|
|
|
33
49
|
The `unique_toolkit.chat` module encompasses all chat related functionality.
|
|
34
50
|
|
|
35
51
|
- `functions.py` comprises the functions to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message.
|
|
36
|
-
- `service.py` comprises the ChatService and provides an interface to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message and stream complete.
|
|
37
52
|
- `schemas.py` comprises all relevant schemas, e.g., ChatMessage, used in the ChatService.
|
|
38
53
|
- `utils.py` comprises utility functions to use and convert ChatMessage objects in assistants, e.g., convert_chat_history_to_injectable_string converts the chat history to a string that can be injected into a prompt.
|
|
39
54
|
|
|
@@ -42,11 +57,10 @@ The `unique_toolkit.chat` module encompasses all chat related functionality.
|
|
|
42
57
|
The `unique_toolkit.content` module encompasses all content related functionality. Content can be any type of textual data that is stored in the Knowledgebase on the Unique platform. During the ingestion of the content, the content is parsed, split in chunks, indexed, and stored in the database.
|
|
43
58
|
|
|
44
59
|
- `functions.py` comprises the functions to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message.
|
|
45
|
-
- `service.py` comprises the ContentService and provides an interface to interact with the content, e.g., search content, search content chunks, upload and download content.
|
|
46
60
|
- `schemas.py` comprises all relevant schemas, e.g., Content and ContentChunk, used in the ContentService.
|
|
47
61
|
- `utils.py` comprise utility functions to manipulate Content and ContentChunk objects, e.g., sort_content_chunks and merge_content_chunks.
|
|
48
62
|
|
|
49
|
-
## Embedding
|
|
63
|
+
## Embedding (To be Deprecated)
|
|
50
64
|
|
|
51
65
|
The `unique_toolkit.embedding` module encompasses all embedding related functionality. Embeddings are used to represent textual data in a high-dimensional space. The embeddings can be used to calculate the similarity between two texts, for instance.
|
|
52
66
|
|
|
@@ -54,31 +68,19 @@ The `unique_toolkit.embedding` module encompasses all embedding related function
|
|
|
54
68
|
- `service.py` encompasses the EmbeddingService and provides an interface to interact with the embeddings, e.g., embed text and calculate the similarity between two texts.
|
|
55
69
|
- `schemas.py` comprises all relevant schemas, e.g., Embeddings, used in the EmbeddingService.
|
|
56
70
|
|
|
57
|
-
## Language Model
|
|
71
|
+
## Language Model
|
|
58
72
|
|
|
59
73
|
The `unique_toolkit.language_model` module encompasses all language model related functionality and information on the different language models deployed through the
|
|
60
74
|
Unique platform.
|
|
61
75
|
|
|
62
76
|
- `infos.py` comprises the information on all language models deployed through the Unique platform. We recommend to use the LanguageModel class, initialized with the LanguageModelName, e.g., LanguageModel(LanguageModelName.AZURE_GPT_4o_2024_1120) to get the information on the specific language model like the name, version, token limits or retirement date.
|
|
63
77
|
- `functions.py` comprises the functions to complete and stream complete to chat.
|
|
64
|
-
- `service.py` comprises the LanguageModelService and provides an interface to interact with the language models, e.g., complete.
|
|
65
78
|
- `schemas.py` comprises all relevant schemas, e.g., LanguageModelResponse, used in the LanguageModelService.
|
|
66
79
|
- `utils.py` comprises utility functions to parse the output of the language model, e.g., convert_string_to_json finds and parses the last json object in a string.
|
|
67
80
|
|
|
68
|
-
## Short Term Memory
|
|
81
|
+
## Short Term Memory
|
|
69
82
|
|
|
70
83
|
The `unique_toolkit.short_term_memory` module encompasses all short term memory related functionality.
|
|
71
84
|
|
|
72
85
|
- `functions.py` comprises the functions to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message.
|
|
73
|
-
- `
|
|
74
|
-
- `schemas.py` comprises all relevant schemas, e.g., ShortTermMemory, used in the ShortTermMemoryService.
|
|
75
|
-
|
|
76
|
-
# Development instructions
|
|
77
|
-
|
|
78
|
-
1. Install poetry on your system (through `brew` or `pipx`).
|
|
79
|
-
|
|
80
|
-
2. Install `pyenv` and install python 3.11. `pyenv` is recommended as otherwise poetry uses the python version used to install itself and not the user preferred python version.
|
|
81
|
-
|
|
82
|
-
3. If you then run `python --version` in your terminal, you should be able to see python version as specified in `.python-version`.
|
|
83
|
-
|
|
84
|
-
4. Then finally run `poetry install` to install the package and all dependencies.
|
|
86
|
+
- `schemas.py` comprises all relevant schemas, e.g., ShortTermMemory, used in the ShortTermMemoryService.
|
{unique_toolkit-1.38.3 → unique_toolkit-1.39.0}/unique_toolkit/agentic/loop_runner/__init__.py
RENAMED
|
@@ -1,25 +1,35 @@
|
|
|
1
|
+
from unique_toolkit.agentic.loop_runner._iteration_handler_utils import (
|
|
2
|
+
handle_forced_tools_iteration,
|
|
3
|
+
handle_last_iteration,
|
|
4
|
+
handle_normal_iteration,
|
|
5
|
+
)
|
|
1
6
|
from unique_toolkit.agentic.loop_runner.base import LoopIterationRunner
|
|
2
7
|
from unique_toolkit.agentic.loop_runner.middleware import (
|
|
3
|
-
QWEN_FORCED_TOOL_CALL_PROMPT_INSTRUCTION,
|
|
4
8
|
PlanningConfig,
|
|
5
9
|
PlanningMiddleware,
|
|
6
10
|
PlanningSchemaConfig,
|
|
7
|
-
QwenForcedToolCallMiddleware,
|
|
8
|
-
is_qwen_model,
|
|
9
11
|
)
|
|
10
12
|
from unique_toolkit.agentic.loop_runner.runners import (
|
|
13
|
+
QWEN_FORCED_TOOL_CALL_INSTRUCTION,
|
|
14
|
+
QWEN_LAST_ITERATION_INSTRUCTION,
|
|
11
15
|
BasicLoopIterationRunner,
|
|
12
16
|
BasicLoopIterationRunnerConfig,
|
|
17
|
+
QwenLoopIterationRunner,
|
|
18
|
+
is_qwen_model,
|
|
13
19
|
)
|
|
14
20
|
|
|
15
21
|
__all__ = [
|
|
16
22
|
"LoopIterationRunner",
|
|
17
|
-
"QWEN_FORCED_TOOL_CALL_PROMPT_INSTRUCTION",
|
|
18
23
|
"PlanningConfig",
|
|
19
24
|
"PlanningMiddleware",
|
|
20
25
|
"PlanningSchemaConfig",
|
|
21
|
-
"
|
|
26
|
+
"QwenLoopIterationRunner",
|
|
22
27
|
"is_qwen_model",
|
|
23
28
|
"BasicLoopIterationRunnerConfig",
|
|
24
29
|
"BasicLoopIterationRunner",
|
|
30
|
+
"handle_forced_tools_iteration",
|
|
31
|
+
"handle_last_iteration",
|
|
32
|
+
"handle_normal_iteration",
|
|
33
|
+
"QWEN_FORCED_TOOL_CALL_INSTRUCTION",
|
|
34
|
+
"QWEN_LAST_ITERATION_INSTRUCTION",
|
|
25
35
|
]
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Protocol, Unpack, cast
|
|
3
|
+
|
|
4
|
+
from unique_toolkit.agentic.loop_runner._stream_handler_utils import stream_response
|
|
5
|
+
from unique_toolkit.agentic.loop_runner.base import (
|
|
6
|
+
_LoopIterationRunnerKwargs,
|
|
7
|
+
)
|
|
8
|
+
from unique_toolkit.chat.functions import LanguageModelStreamResponse
|
|
9
|
+
|
|
10
|
+
_LOGGER = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PrepareForcedToolIterationKwargs(Protocol):
|
|
14
|
+
def __call__(
|
|
15
|
+
self,
|
|
16
|
+
func_name: str | None,
|
|
17
|
+
per_choice_kwargs: _LoopIterationRunnerKwargs,
|
|
18
|
+
) -> _LoopIterationRunnerKwargs: ...
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def handle_last_iteration(
|
|
22
|
+
**kwargs: Unpack[_LoopIterationRunnerKwargs],
|
|
23
|
+
) -> LanguageModelStreamResponse:
|
|
24
|
+
_LOGGER.info("Reached last iteration, removing tools and producing final response")
|
|
25
|
+
|
|
26
|
+
return await stream_response(
|
|
27
|
+
loop_runner_kwargs=kwargs,
|
|
28
|
+
tools=None,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def handle_normal_iteration(
|
|
33
|
+
**kwargs: Unpack[_LoopIterationRunnerKwargs],
|
|
34
|
+
) -> LanguageModelStreamResponse:
|
|
35
|
+
_LOGGER.info("Running loop iteration %d", kwargs["iteration_index"])
|
|
36
|
+
|
|
37
|
+
return await stream_response(loop_runner_kwargs=kwargs)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
async def handle_forced_tools_iteration(
|
|
41
|
+
**kwargs: Unpack[_LoopIterationRunnerKwargs],
|
|
42
|
+
) -> LanguageModelStreamResponse:
|
|
43
|
+
return await run_forced_tools_iteration(loop_runner_kwargs=kwargs)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
async def run_forced_tools_iteration(
|
|
47
|
+
*,
|
|
48
|
+
loop_runner_kwargs: _LoopIterationRunnerKwargs,
|
|
49
|
+
prepare_loop_runner_kwargs: PrepareForcedToolIterationKwargs | None = None,
|
|
50
|
+
) -> LanguageModelStreamResponse:
|
|
51
|
+
"""
|
|
52
|
+
Execute a "forced tools" iteration by running one stream_response per tool choice,
|
|
53
|
+
then merging tool calls and references into a single response.
|
|
54
|
+
|
|
55
|
+
Some models (e.g. Qwen) need per-tool-choice message rewriting; this can be done
|
|
56
|
+
via prepare_loop_runner_kwargs (called once per tool choice, on a copy of kwargs).
|
|
57
|
+
"""
|
|
58
|
+
assert "tool_choices" in loop_runner_kwargs
|
|
59
|
+
|
|
60
|
+
tool_choices = loop_runner_kwargs["tool_choices"]
|
|
61
|
+
assert len(tool_choices) > 0, (
|
|
62
|
+
"run_forced_tools_iteration requires at least one tool choice"
|
|
63
|
+
)
|
|
64
|
+
_LOGGER.info("Forcing tools calls: %s", tool_choices)
|
|
65
|
+
|
|
66
|
+
responses: list[LanguageModelStreamResponse] = []
|
|
67
|
+
|
|
68
|
+
available_tools = {t.name: t for t in loop_runner_kwargs.get("tools") or []}
|
|
69
|
+
|
|
70
|
+
for opt in tool_choices:
|
|
71
|
+
func_name = opt.get("function", {}).get("name")
|
|
72
|
+
|
|
73
|
+
per_choice_kwargs = cast(_LoopIterationRunnerKwargs, dict(loop_runner_kwargs))
|
|
74
|
+
if prepare_loop_runner_kwargs:
|
|
75
|
+
per_choice_kwargs = prepare_loop_runner_kwargs(func_name, per_choice_kwargs)
|
|
76
|
+
|
|
77
|
+
limited_tool = available_tools.get(func_name) if func_name else None
|
|
78
|
+
stream_kwargs = {"loop_runner_kwargs": per_choice_kwargs, "tool_choice": opt}
|
|
79
|
+
if limited_tool:
|
|
80
|
+
stream_kwargs["tools"] = [limited_tool]
|
|
81
|
+
responses.append(await stream_response(**stream_kwargs))
|
|
82
|
+
|
|
83
|
+
# Merge responses and refs:
|
|
84
|
+
tool_calls = []
|
|
85
|
+
references = []
|
|
86
|
+
for r in responses:
|
|
87
|
+
if r.tool_calls:
|
|
88
|
+
tool_calls.extend(r.tool_calls)
|
|
89
|
+
references.extend(r.message.references)
|
|
90
|
+
|
|
91
|
+
response = responses[0]
|
|
92
|
+
response.tool_calls = tool_calls if len(tool_calls) > 0 else None
|
|
93
|
+
response.message.references = references
|
|
94
|
+
|
|
95
|
+
return response
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from unique_toolkit.agentic.loop_runner.runners.basic import (
|
|
2
|
+
BasicLoopIterationRunner,
|
|
3
|
+
BasicLoopIterationRunnerConfig,
|
|
4
|
+
)
|
|
5
|
+
from unique_toolkit.agentic.loop_runner.runners.qwen import (
|
|
6
|
+
QWEN_FORCED_TOOL_CALL_INSTRUCTION,
|
|
7
|
+
QWEN_LAST_ITERATION_INSTRUCTION,
|
|
8
|
+
QwenLoopIterationRunner,
|
|
9
|
+
is_qwen_model,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"BasicLoopIterationRunnerConfig",
|
|
14
|
+
"BasicLoopIterationRunner",
|
|
15
|
+
"QwenLoopIterationRunner",
|
|
16
|
+
"QWEN_FORCED_TOOL_CALL_INSTRUCTION",
|
|
17
|
+
"QWEN_LAST_ITERATION_INSTRUCTION",
|
|
18
|
+
"is_qwen_model",
|
|
19
|
+
]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Unpack, override
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
from unique_toolkit._common.pydantic_helpers import get_configuration_dict
|
|
7
|
+
from unique_toolkit.agentic.loop_runner._iteration_handler_utils import (
|
|
8
|
+
handle_forced_tools_iteration,
|
|
9
|
+
handle_last_iteration,
|
|
10
|
+
handle_normal_iteration,
|
|
11
|
+
)
|
|
12
|
+
from unique_toolkit.agentic.loop_runner.base import (
|
|
13
|
+
LoopIterationRunner,
|
|
14
|
+
_LoopIterationRunnerKwargs,
|
|
15
|
+
)
|
|
16
|
+
from unique_toolkit.chat.functions import LanguageModelStreamResponse
|
|
17
|
+
from unique_toolkit.protocols.support import (
|
|
18
|
+
ResponsesLanguageModelStreamResponse,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
_LOGGER = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BasicLoopIterationRunnerConfig(BaseModel):
|
|
25
|
+
model_config = get_configuration_dict()
|
|
26
|
+
max_loop_iterations: int
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class BasicLoopIterationRunner(LoopIterationRunner):
|
|
30
|
+
def __init__(self, config: BasicLoopIterationRunnerConfig) -> None:
|
|
31
|
+
self._config = config
|
|
32
|
+
|
|
33
|
+
@override
|
|
34
|
+
async def __call__(
|
|
35
|
+
self,
|
|
36
|
+
**kwargs: Unpack[_LoopIterationRunnerKwargs],
|
|
37
|
+
) -> LanguageModelStreamResponse | ResponsesLanguageModelStreamResponse:
|
|
38
|
+
tool_choices = kwargs.get("tool_choices", [])
|
|
39
|
+
iteration_index = kwargs["iteration_index"]
|
|
40
|
+
|
|
41
|
+
if len(tool_choices) > 0 and iteration_index == 0:
|
|
42
|
+
return await handle_forced_tools_iteration(**kwargs)
|
|
43
|
+
elif iteration_index == self._config.max_loop_iterations - 1:
|
|
44
|
+
return await handle_last_iteration(**kwargs)
|
|
45
|
+
else:
|
|
46
|
+
return await handle_normal_iteration(**kwargs)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from unique_toolkit.agentic.loop_runner.runners.qwen.helpers import (
|
|
2
|
+
is_qwen_model,
|
|
3
|
+
)
|
|
4
|
+
from unique_toolkit.agentic.loop_runner.runners.qwen.qwen_runner import (
|
|
5
|
+
QWEN_FORCED_TOOL_CALL_INSTRUCTION,
|
|
6
|
+
QWEN_LAST_ITERATION_INSTRUCTION,
|
|
7
|
+
QwenLoopIterationRunner,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"QwenLoopIterationRunner",
|
|
12
|
+
"is_qwen_model",
|
|
13
|
+
"QWEN_FORCED_TOOL_CALL_INSTRUCTION",
|
|
14
|
+
"QWEN_LAST_ITERATION_INSTRUCTION",
|
|
15
|
+
]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from unique_toolkit.language_model.infos import LanguageModelInfo
|
|
2
2
|
from unique_toolkit.language_model.schemas import (
|
|
3
|
+
LanguageModelAssistantMessage,
|
|
3
4
|
LanguageModelMessageRole,
|
|
4
5
|
LanguageModelMessages,
|
|
5
6
|
)
|
|
@@ -31,3 +32,17 @@ def append_qwen_forced_tool_call_instruction(
|
|
|
31
32
|
)
|
|
32
33
|
break
|
|
33
34
|
return LanguageModelMessages(root=messages_list)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def append_qwen_last_iteration_assistant_message(
|
|
38
|
+
*,
|
|
39
|
+
messages: LanguageModelMessages,
|
|
40
|
+
last_iteration_instruction: str,
|
|
41
|
+
) -> LanguageModelMessages:
|
|
42
|
+
"""Append an assistant message at the end to indicate no further tool calls are allowed."""
|
|
43
|
+
messages_list = list(messages)
|
|
44
|
+
assistant_message = LanguageModelAssistantMessage(
|
|
45
|
+
content=last_iteration_instruction,
|
|
46
|
+
)
|
|
47
|
+
messages_list.append(assistant_message)
|
|
48
|
+
return LanguageModelMessages(root=messages_list)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Unpack
|
|
3
|
+
|
|
4
|
+
from unique_toolkit.agentic.loop_runner._iteration_handler_utils import (
|
|
5
|
+
handle_last_iteration,
|
|
6
|
+
handle_normal_iteration,
|
|
7
|
+
run_forced_tools_iteration,
|
|
8
|
+
)
|
|
9
|
+
from unique_toolkit.agentic.loop_runner.base import (
|
|
10
|
+
LoopIterationRunner,
|
|
11
|
+
_LoopIterationRunnerKwargs,
|
|
12
|
+
)
|
|
13
|
+
from unique_toolkit.agentic.loop_runner.runners.qwen.helpers import (
|
|
14
|
+
append_qwen_forced_tool_call_instruction,
|
|
15
|
+
append_qwen_last_iteration_assistant_message,
|
|
16
|
+
)
|
|
17
|
+
from unique_toolkit.chat.service import ChatService, LanguageModelStreamResponse
|
|
18
|
+
|
|
19
|
+
_LOGGER = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
QWEN_FORCED_TOOL_CALL_INSTRUCTION = (
|
|
22
|
+
"**Tool Call Instruction:** \nYou MUST call the tool {TOOL_NAME}. "
|
|
23
|
+
"You must start the response with <tool_call>. "
|
|
24
|
+
"Do NOT provide natural language explanations, summaries, or any text outside the <tool_call> block."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
QWEN_LAST_ITERATION_INSTRUCTION = "The maximum number of loop iteration have been reached. Not further tool calls are allowed. Based on the found information, an answer should be generated"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class QwenLoopIterationRunner(LoopIterationRunner):
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
*,
|
|
34
|
+
qwen_forced_tool_call_instruction: str,
|
|
35
|
+
qwen_last_iteration_instruction: str,
|
|
36
|
+
max_loop_iterations: int,
|
|
37
|
+
chat_service: ChatService,
|
|
38
|
+
) -> None:
|
|
39
|
+
self._qwen_forced_tool_call_instruction = qwen_forced_tool_call_instruction
|
|
40
|
+
self._qwen_last_iteration_instruction = qwen_last_iteration_instruction
|
|
41
|
+
self._max_loop_iterations = max_loop_iterations
|
|
42
|
+
self._chat_service = chat_service
|
|
43
|
+
|
|
44
|
+
async def __call__(
|
|
45
|
+
self, **kwargs: Unpack[_LoopIterationRunnerKwargs]
|
|
46
|
+
) -> LanguageModelStreamResponse:
|
|
47
|
+
tool_choices = kwargs.get("tool_choices") or []
|
|
48
|
+
iteration_index = kwargs["iteration_index"]
|
|
49
|
+
|
|
50
|
+
if len(tool_choices) > 0 and iteration_index == 0:
|
|
51
|
+
return await self._qwen_handle_forced_tools_iteration(**kwargs)
|
|
52
|
+
elif iteration_index == self._max_loop_iterations - 1:
|
|
53
|
+
return await self._qwen_handle_last_iteration(**kwargs)
|
|
54
|
+
else:
|
|
55
|
+
return await self._qwen_handle_normal_iteration(**kwargs)
|
|
56
|
+
|
|
57
|
+
async def _qwen_handle_forced_tools_iteration(
|
|
58
|
+
self, **kwargs: Unpack[_LoopIterationRunnerKwargs]
|
|
59
|
+
) -> LanguageModelStreamResponse:
|
|
60
|
+
# For Qwen models, append tool call instruction to the last user message. These models ignore the parameter tool_choice.
|
|
61
|
+
# As the message has to be modified for each tool call instruction, the function from the basic runner cant be used.
|
|
62
|
+
original_messages = kwargs["messages"].model_copy(deep=True)
|
|
63
|
+
|
|
64
|
+
def _prepare(
|
|
65
|
+
func_name: str | None,
|
|
66
|
+
per_choice_kwargs: _LoopIterationRunnerKwargs,
|
|
67
|
+
) -> _LoopIterationRunnerKwargs:
|
|
68
|
+
prompt_instruction = self._qwen_forced_tool_call_instruction.format(
|
|
69
|
+
TOOL_NAME=func_name or ""
|
|
70
|
+
)
|
|
71
|
+
per_choice_kwargs["messages"] = append_qwen_forced_tool_call_instruction(
|
|
72
|
+
messages=original_messages,
|
|
73
|
+
forced_tool_call_instruction=prompt_instruction,
|
|
74
|
+
)
|
|
75
|
+
return per_choice_kwargs
|
|
76
|
+
|
|
77
|
+
response = await run_forced_tools_iteration(
|
|
78
|
+
loop_runner_kwargs=kwargs,
|
|
79
|
+
prepare_loop_runner_kwargs=_prepare,
|
|
80
|
+
)
|
|
81
|
+
return self._process_response(response)
|
|
82
|
+
|
|
83
|
+
async def _qwen_handle_last_iteration(
|
|
84
|
+
self, **kwargs: Unpack[_LoopIterationRunnerKwargs]
|
|
85
|
+
) -> LanguageModelStreamResponse:
|
|
86
|
+
# For Qwen models, append an assistant message with instructions to not call any tool in this iteration.
|
|
87
|
+
_LOGGER.info(
|
|
88
|
+
"Reached last iteration, removing tools. Appending assistant message with instructions to not call any tool in this iteration."
|
|
89
|
+
)
|
|
90
|
+
kwargs["messages"] = append_qwen_last_iteration_assistant_message(
|
|
91
|
+
messages=kwargs["messages"],
|
|
92
|
+
last_iteration_instruction=self._qwen_last_iteration_instruction,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
response = await handle_last_iteration(
|
|
96
|
+
**kwargs,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return self._process_response(response)
|
|
100
|
+
|
|
101
|
+
async def _qwen_handle_normal_iteration(
|
|
102
|
+
self, **kwargs: Unpack[_LoopIterationRunnerKwargs]
|
|
103
|
+
) -> LanguageModelStreamResponse:
|
|
104
|
+
response = await handle_normal_iteration(**kwargs)
|
|
105
|
+
return self._process_response(response)
|
|
106
|
+
|
|
107
|
+
def _process_response(
|
|
108
|
+
self, response: LanguageModelStreamResponse
|
|
109
|
+
) -> LanguageModelStreamResponse:
|
|
110
|
+
# Check if content of response is </tool_call>
|
|
111
|
+
if "</tool_call>" == response.message.text.strip():
|
|
112
|
+
_LOGGER.warning(
|
|
113
|
+
"Response contains only <tool_call>. This is not allowed. Returning empty response."
|
|
114
|
+
)
|
|
115
|
+
self._chat_service.modify_assistant_message(content="")
|
|
116
|
+
response.message.text = ""
|
|
117
|
+
|
|
118
|
+
return response
|
|
@@ -120,11 +120,15 @@ class McpServer(BaseModel):
|
|
|
120
120
|
class ChatEventUserMessage(BaseModel):
|
|
121
121
|
model_config = model_config
|
|
122
122
|
|
|
123
|
-
id: str
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
123
|
+
id: str = Field(
|
|
124
|
+
description="The id of the user message. On an event this corresponds to the user message that created the event."
|
|
125
|
+
)
|
|
126
|
+
text: str = Field(description="The text of the user message.")
|
|
127
|
+
original_text: str = Field(description="The original text of the user message.")
|
|
128
|
+
created_at: str = Field(
|
|
129
|
+
description="The creation date and time of the user message."
|
|
130
|
+
)
|
|
131
|
+
language: str = Field(description="The language of the user message.")
|
|
128
132
|
|
|
129
133
|
|
|
130
134
|
@deprecated(
|
|
@@ -140,8 +144,12 @@ class EventUserMessage(ChatEventUserMessage):
|
|
|
140
144
|
class ChatEventAssistantMessage(BaseModel):
|
|
141
145
|
model_config = model_config
|
|
142
146
|
|
|
143
|
-
id: str
|
|
144
|
-
|
|
147
|
+
id: str = Field(
|
|
148
|
+
description="The id of the assistant message. On an event this corresponds to the assistant message that will be returned by the process handling the event."
|
|
149
|
+
)
|
|
150
|
+
created_at: str = Field(
|
|
151
|
+
description="The creation date and time of the assistant message."
|
|
152
|
+
)
|
|
145
153
|
|
|
146
154
|
|
|
147
155
|
@deprecated(
|