unique_toolkit 1.76.0__tar.gz → 1.77.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/PKG-INFO +1 -1
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/pyproject.toml +1 -1
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/history_manager/history_construction_with_contents.py +24 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/history_manager/loop_token_reducer.py +7 -1
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/history_manager/utils.py +23 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/__init__.py +27 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py +7 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/__init__.py +24 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/config.py +94 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/prompts/__init__.py +13 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/prompts/execution_reminder.j2 +11 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/prompts/system_prompt.j2 +41 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/prompts/tool_description.j2 +9 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/prompts/verification_nudge.j2 +1 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/schemas.py +137 -0
- unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/service.py +271 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +1 -0
- unique_toolkit-1.76.0/unique_toolkit/agentic/tools/experimental/__init__.py +0 -11
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/README.md +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/_base_service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/_time_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/api_calling/human_verification_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/base_model_type_attribute.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/chunk_relevancy_sorter/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/chunk_relevancy_sorter/exception.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/chunk_relevancy_sorter/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/README.md +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/__main__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/cli.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/differ.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/exporter.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/models.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/registry.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/config_checker/validator.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/default_language_model.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/docx_generator/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/docx_generator/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/docx_generator/pandoc_converter.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/docx_generator/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/docx_generator/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/endpoint_builder.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/endpoint_requestor.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/event_bus.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/exception.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/execution.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/endpoint_builder.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/endpoint_requestor.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/README.md +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/agent.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/examples/data.csv +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/examples/example_usage.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/exceptions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/dataframe_handler/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/exceptions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/generation_handler/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/default_template.j2 +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/exceptions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/services/template_handler/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/experimental/write_up_agent/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/feature_flags/schema.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/pydantic/rjsf_tags.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/pydantic_helpers.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/referencing.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/string_utilities.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/tests/test_referencing.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/tests/test_string_utilities.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/token/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/token/image_token_counting.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/token/token_counting.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/token/tokenizers/deepseek/tokenizer.json +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/token/tokenizers/qwen/tokenizer.json +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/files.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/image/encode.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/jinja/helpers.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/jinja/render.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/jinja/schema.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/jinja/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/structured_output/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/structured_output/schema.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/utils/write_configuration.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/validate_required_values.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/_common/validators.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/context_relevancy/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/context_relevancy/schema.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/context_relevancy/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/evaluation_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/exception.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/hallucination/constants.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/system_prompt.j2 +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/hallucination/prompts/user_prompt.j2 +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/hallucination/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/hallucination/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/output_parser.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/tests/fixtures.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/tests/test_config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/tests/test_hallucination_constants.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/tests/test_output_parser.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/evaluation/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/feature_flags/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/feature_flags/feature_flags.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/history_manager/history_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/_stream_handler_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/base.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/middleware/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/middleware/planning/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/middleware/planning/planning.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/middleware/planning/schema.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/runners/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/runners/basic.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/runners/mistral/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/runners/mistral/mistral_runner.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/message_log_manager/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/message_log_manager/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/postprocessor/postprocessor_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/reference_manager/reference_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/responses_api/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/responses_api/postprocessors/code_display.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/responses_api/stream_handler.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/thinking_manager/thinking_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/evaluation/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/display.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/references.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/prompts.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/response_watcher/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/tool/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/tool/_memory.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/tool/_schema.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/tool/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/tool/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/agent_chunks_hanlder.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/experimental/open_file_tool/tool.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/factory.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/mcp/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/mcp/manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/mcp/models.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/mcp/tool_wrapper.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/base.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/openai_builtin/manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/test/test_mcp_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/tool.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/tool_manager.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/tool_progress_reporter.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/utils/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/utils/source_handling/schema.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic_table/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic_table/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic_table/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/chat_event_filter_options_settings.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/dev_util.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/fast_api_factory.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/feature_flags.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/find_env_file.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/init_logging.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/init_sdk.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/performance/async_tasks.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/performance/async_wrapper.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/unique_settings.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/verification.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/app/webhook.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/cancellation.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/constants.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/deprecated/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/functions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/rendering.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/responses_api.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/state.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/chat/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/content/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/content/constants.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/content/functions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/content/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/content/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/content/smart_rules.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/content/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/README.md +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/augmented/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/augmented/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/base.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/basic/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/basic/config.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/basic/prompt.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/data_extraction/basic/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/elicitation/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/elicitation/constants.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/elicitation/exceptions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/elicitation/functions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/elicitation/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/elicitation/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/embedding/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/embedding/constants.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/embedding/functions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/embedding/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/embedding/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/embedding/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/framework_utilities/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/framework_utilities/langchain/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/framework_utilities/langchain/client.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/framework_utilities/openai/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/framework_utilities/openai/client.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/framework_utilities/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/_responses_api_utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/builder.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/constants.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/default_language_model.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/functions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/infos.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/prompt.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/reference.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/stream_transform.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/language_model/utils.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/monitoring/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/monitoring/middleware.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/monitoring/registry.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/protocols/support.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/services/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/services/chat_service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/services/factory.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/services/knowledge_base.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/short_term_memory/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/short_term_memory/constants.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/short_term_memory/functions.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/short_term_memory/schemas.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/short_term_memory/service.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/smart_rules/__init__.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/smart_rules/compile.py +0 -0
- {unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/test_utilities/events.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-toolkit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.77.1
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Cedric Klinkert, Martin Fadler, Sadique Sheik, Fabian Schläpfer, Pascal Hauri, Ejiroghene Oki-Peter, Rami Azouz, Ricardo Visini, Sanzio Monti
|
|
6
6
|
Author-email: Cedric Klinkert <cedric.klinkert@unique.ch>, Martin Fadler <martin.fadler@unique.ch>, Sadique Sheik <sadique@unique.ch>, Fabian Schläpfer <fabian@unique.ch>, Pascal Hauri <pascal@unique.ch>, Ejiroghene Oki-Peter <oki-peter.ejiroghene@unique.ai>, Rami Azouz <rami.ext@unique.ch>, Ricardo Visini <ricardo.visini@unique.ch>, Sanzio Monti <sanzio.monti@unique.ai>
|
|
@@ -237,10 +237,18 @@ def _append_element_to_builder(
|
|
|
237
237
|
file_content_serialization_type: FileContentSerialization,
|
|
238
238
|
content_service: ContentService,
|
|
239
239
|
chat_id: str,
|
|
240
|
+
selected_content_ids: set[str] | None = None,
|
|
240
241
|
) -> None:
|
|
241
242
|
if len(c.contents) > 0:
|
|
242
243
|
file_contents = [co for co in c.contents if FileUtils.is_file_content(co.key)]
|
|
243
244
|
image_contents = [co for co in c.contents if FileUtils.is_image_content(co.key)]
|
|
245
|
+
if selected_content_ids is not None:
|
|
246
|
+
file_contents = [
|
|
247
|
+
co for co in file_contents if co.id in selected_content_ids
|
|
248
|
+
]
|
|
249
|
+
image_contents = [
|
|
250
|
+
co for co in image_contents if co.id in selected_content_ids
|
|
251
|
+
]
|
|
244
252
|
content = (
|
|
245
253
|
text
|
|
246
254
|
+ "\n\n"
|
|
@@ -280,10 +288,18 @@ async def _append_element_to_builder_async(
|
|
|
280
288
|
file_content_serialization_type: FileContentSerialization,
|
|
281
289
|
content_service: ContentService,
|
|
282
290
|
chat_id: str,
|
|
291
|
+
selected_content_ids: set[str] | None = None,
|
|
283
292
|
) -> None:
|
|
284
293
|
if len(c.contents) > 0:
|
|
285
294
|
file_contents = [co for co in c.contents if FileUtils.is_file_content(co.key)]
|
|
286
295
|
image_contents = [co for co in c.contents if FileUtils.is_image_content(co.key)]
|
|
296
|
+
if selected_content_ids is not None:
|
|
297
|
+
file_contents = [
|
|
298
|
+
co for co in file_contents if co.id in selected_content_ids
|
|
299
|
+
]
|
|
300
|
+
image_contents = [
|
|
301
|
+
co for co in image_contents if co.id in selected_content_ids
|
|
302
|
+
]
|
|
287
303
|
content = (
|
|
288
304
|
text
|
|
289
305
|
+ "\n\n"
|
|
@@ -321,6 +337,7 @@ def get_full_history_with_contents(
|
|
|
321
337
|
content_service: ContentService,
|
|
322
338
|
include_images: ImageContentInclusion = ImageContentInclusion.ALL,
|
|
323
339
|
file_content_serialization_type: FileContentSerialization = FileContentSerialization.FILE_NAME,
|
|
340
|
+
selected_content_ids: set[str] | None = None,
|
|
324
341
|
) -> LanguageModelMessages:
|
|
325
342
|
grouped_elements = get_chat_history_with_contents(
|
|
326
343
|
user_message=user_message,
|
|
@@ -347,6 +364,7 @@ def get_full_history_with_contents(
|
|
|
347
364
|
file_content_serialization_type=file_content_serialization_type,
|
|
348
365
|
content_service=content_service,
|
|
349
366
|
chat_id=chat_id,
|
|
367
|
+
selected_content_ids=selected_content_ids,
|
|
350
368
|
)
|
|
351
369
|
return builder.build()
|
|
352
370
|
|
|
@@ -359,6 +377,7 @@ async def get_full_history_with_contents_async(
|
|
|
359
377
|
content_service: ContentService,
|
|
360
378
|
include_images: ImageContentInclusion = ImageContentInclusion.ALL,
|
|
361
379
|
file_content_serialization_type: FileContentSerialization = FileContentSerialization.FILE_NAME,
|
|
380
|
+
selected_content_ids: set[str] | None = None,
|
|
362
381
|
) -> LanguageModelMessages:
|
|
363
382
|
grouped_elements = await get_chat_history_with_contents_async(
|
|
364
383
|
user_message=user_message,
|
|
@@ -384,6 +403,7 @@ async def get_full_history_with_contents_async(
|
|
|
384
403
|
file_content_serialization_type=file_content_serialization_type,
|
|
385
404
|
content_service=content_service,
|
|
386
405
|
chat_id=chat_id,
|
|
406
|
+
selected_content_ids=selected_content_ids,
|
|
387
407
|
)
|
|
388
408
|
return builder.build()
|
|
389
409
|
|
|
@@ -396,6 +416,7 @@ def get_full_history_with_contents_and_tool_calls(
|
|
|
396
416
|
content_service: ContentService,
|
|
397
417
|
include_images: ImageContentInclusion = ImageContentInclusion.ALL,
|
|
398
418
|
file_content_serialization_type: FileContentSerialization = FileContentSerialization.FILE_NAME,
|
|
419
|
+
selected_content_ids: set[str] | None = None,
|
|
399
420
|
) -> tuple[LanguageModelMessages, int, dict[int, "ContentChunk"]]:
|
|
400
421
|
"""Build the full LLM message history, including persisted tool call rounds.
|
|
401
422
|
|
|
@@ -526,6 +547,7 @@ def get_full_history_with_contents_and_tool_calls(
|
|
|
526
547
|
file_content_serialization_type=file_content_serialization_type,
|
|
527
548
|
content_service=content_service,
|
|
528
549
|
chat_id=chat_id,
|
|
550
|
+
selected_content_ids=selected_content_ids,
|
|
529
551
|
)
|
|
530
552
|
return builder.build(), max_source_number, source_map
|
|
531
553
|
|
|
@@ -538,6 +560,7 @@ async def get_full_history_with_contents_and_tool_calls_async(
|
|
|
538
560
|
content_service: ContentService,
|
|
539
561
|
include_images: ImageContentInclusion = ImageContentInclusion.ALL,
|
|
540
562
|
file_content_serialization_type: FileContentSerialization = FileContentSerialization.FILE_NAME,
|
|
563
|
+
selected_content_ids: set[str] | None = None,
|
|
541
564
|
) -> tuple[LanguageModelMessages, int, dict[int, "ContentChunk"]]:
|
|
542
565
|
"""Async version of get_full_history_with_contents_and_tool_calls."""
|
|
543
566
|
from unique_toolkit.agentic.history_manager.utils import (
|
|
@@ -642,6 +665,7 @@ async def get_full_history_with_contents_and_tool_calls_async(
|
|
|
642
665
|
file_content_serialization_type=file_content_serialization_type,
|
|
643
666
|
content_service=content_service,
|
|
644
667
|
chat_id=chat_id,
|
|
668
|
+
selected_content_ids=selected_content_ids,
|
|
645
669
|
)
|
|
646
670
|
return builder.build(), max_source_number, source_map
|
|
647
671
|
|
|
@@ -13,7 +13,10 @@ from unique_toolkit.agentic.history_manager.history_construction_with_contents i
|
|
|
13
13
|
get_full_history_with_contents_and_tool_calls_async,
|
|
14
14
|
get_full_history_with_contents_async,
|
|
15
15
|
)
|
|
16
|
-
from unique_toolkit.agentic.history_manager.utils import
|
|
16
|
+
from unique_toolkit.agentic.history_manager.utils import (
|
|
17
|
+
get_selected_uploaded_content_ids,
|
|
18
|
+
serialize_tool_content_json,
|
|
19
|
+
)
|
|
17
20
|
from unique_toolkit.agentic.reference_manager.reference_manager import ReferenceManager
|
|
18
21
|
from unique_toolkit.app.schemas import ChatEvent
|
|
19
22
|
from unique_toolkit.app.unique_settings import UniqueSettings
|
|
@@ -76,6 +79,7 @@ class LoopTokenReducer:
|
|
|
76
79
|
self._max_db_source_number: int = -1
|
|
77
80
|
self._db_source_map: dict[int, ContentChunk] = {}
|
|
78
81
|
self._enable_tool_call_persistence = enable_tool_call_persistence
|
|
82
|
+
self._selected_content_ids = get_selected_uploaded_content_ids(event)
|
|
79
83
|
|
|
80
84
|
@property
|
|
81
85
|
def max_db_source_number(self) -> int:
|
|
@@ -322,6 +326,7 @@ class LoopTokenReducer:
|
|
|
322
326
|
chat_service=self._chat_service,
|
|
323
327
|
content_service=self._content_service,
|
|
324
328
|
file_content_serialization_type=file_content_serialization_type,
|
|
329
|
+
selected_content_ids=self._selected_content_ids,
|
|
325
330
|
)
|
|
326
331
|
self._max_db_source_number = max_src
|
|
327
332
|
self._db_source_map = src_map
|
|
@@ -332,6 +337,7 @@ class LoopTokenReducer:
|
|
|
332
337
|
chat_service=self._chat_service,
|
|
333
338
|
content_service=self._content_service,
|
|
334
339
|
file_content_serialization_type=file_content_serialization_type,
|
|
340
|
+
selected_content_ids=self._selected_content_ids,
|
|
335
341
|
)
|
|
336
342
|
|
|
337
343
|
if remove_from_text is not None:
|
{unique_toolkit-1.76.0 → unique_toolkit-1.77.1}/unique_toolkit/agentic/history_manager/utils.py
RENAMED
|
@@ -3,7 +3,9 @@ import logging
|
|
|
3
3
|
from copy import deepcopy
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
|
+
from unique_toolkit.agentic.feature_flags import feature_flags
|
|
6
7
|
from unique_toolkit.agentic.tools.schemas import Source
|
|
8
|
+
from unique_toolkit.app.schemas import ChatEvent
|
|
7
9
|
from unique_toolkit.content.schemas import ContentChunk
|
|
8
10
|
from unique_toolkit.language_model.schemas import (
|
|
9
11
|
LanguageModelAssistantMessage,
|
|
@@ -14,6 +16,27 @@ from unique_toolkit.language_model.schemas import (
|
|
|
14
16
|
logger = logging.getLogger(__name__)
|
|
15
17
|
|
|
16
18
|
|
|
19
|
+
def get_selected_uploaded_content_ids(event: ChatEvent) -> set[str] | None:
|
|
20
|
+
"""Derive the set of content IDs the user explicitly selected.
|
|
21
|
+
|
|
22
|
+
Returns ``None`` when the feature flag is disabled (meaning *all*
|
|
23
|
+
uploaded images should be included), or a ``set[str]`` of IDs when
|
|
24
|
+
only a subset should be attached.
|
|
25
|
+
"""
|
|
26
|
+
if not feature_flags.enable_selected_uploaded_files_un_18215.is_enabled(
|
|
27
|
+
event.company_id
|
|
28
|
+
):
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
if not (
|
|
32
|
+
hasattr(event.payload, "additional_parameters")
|
|
33
|
+
and event.payload.additional_parameters
|
|
34
|
+
):
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
return set(event.payload.additional_parameters.selected_uploaded_file_ids)
|
|
38
|
+
|
|
39
|
+
|
|
17
40
|
def serialize_tool_content_json(value: Any) -> str:
|
|
18
41
|
"""Serialize tool-role JSON text while preserving readable Unicode."""
|
|
19
42
|
return json.dumps(value, ensure_ascii=False)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from unique_toolkit.agentic.tools.experimental.open_file_tool import (
|
|
2
|
+
OpenFileTool,
|
|
3
|
+
OpenFileToolRuntime,
|
|
4
|
+
OpenFileToolRuntimeConfig,
|
|
5
|
+
)
|
|
6
|
+
from unique_toolkit.agentic.tools.experimental.todo import (
|
|
7
|
+
TodoConfig,
|
|
8
|
+
TodoItem,
|
|
9
|
+
TodoItemInput,
|
|
10
|
+
TodoList,
|
|
11
|
+
TodoStatus,
|
|
12
|
+
TodoWriteInput,
|
|
13
|
+
TodoWriteTool,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"OpenFileTool",
|
|
18
|
+
"OpenFileToolRuntime",
|
|
19
|
+
"OpenFileToolRuntimeConfig",
|
|
20
|
+
"TodoConfig",
|
|
21
|
+
"TodoItem",
|
|
22
|
+
"TodoItemInput",
|
|
23
|
+
"TodoList",
|
|
24
|
+
"TodoStatus",
|
|
25
|
+
"TodoWriteInput",
|
|
26
|
+
"TodoWriteTool",
|
|
27
|
+
]
|
|
@@ -34,6 +34,7 @@ class OpenFileToolRuntimeConfig:
|
|
|
34
34
|
send_files_in_payload: bool = False
|
|
35
35
|
send_uploaded_files_in_payload: bool = False
|
|
36
36
|
use_responses_api: bool = False
|
|
37
|
+
selected_content_ids: frozenset[str] | None = None
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
class OpenFileToolRuntime:
|
|
@@ -256,6 +257,12 @@ class OpenFileToolRuntime:
|
|
|
256
257
|
if (document.expired_at is None or document.expired_at > now)
|
|
257
258
|
and document.key.lower().endswith(".pdf")
|
|
258
259
|
]
|
|
260
|
+
if self._config.selected_content_ids is not None:
|
|
261
|
+
uploaded_documents = [
|
|
262
|
+
doc
|
|
263
|
+
for doc in uploaded_documents
|
|
264
|
+
if doc.id in self._config.selected_content_ids
|
|
265
|
+
]
|
|
259
266
|
self._cached_uploaded_documents = sorted(
|
|
260
267
|
uploaded_documents,
|
|
261
268
|
key=lambda document: (
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from unique_toolkit.agentic.tools.experimental.todo.config import TodoConfig
|
|
2
|
+
from unique_toolkit.agentic.tools.experimental.todo.schemas import (
|
|
3
|
+
TodoItem,
|
|
4
|
+
TodoItemInput,
|
|
5
|
+
TodoList,
|
|
6
|
+
TodoStatus,
|
|
7
|
+
TodoWriteInput,
|
|
8
|
+
)
|
|
9
|
+
from unique_toolkit.agentic.tools.experimental.todo.service import (
|
|
10
|
+
TodoWriteTool,
|
|
11
|
+
)
|
|
12
|
+
from unique_toolkit.agentic.tools.factory import ToolFactory
|
|
13
|
+
|
|
14
|
+
ToolFactory.register_tool(TodoWriteTool, TodoConfig)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"TodoConfig",
|
|
18
|
+
"TodoItem",
|
|
19
|
+
"TodoItemInput",
|
|
20
|
+
"TodoList",
|
|
21
|
+
"TodoStatus",
|
|
22
|
+
"TodoWriteInput",
|
|
23
|
+
"TodoWriteTool",
|
|
24
|
+
]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from unique_toolkit._common.pydantic.rjsf_tags import RJSFMetaTag
|
|
6
|
+
from unique_toolkit.agentic.tools.experimental.todo.prompts import (
|
|
7
|
+
EXECUTION_REMINDER_TEMPLATE,
|
|
8
|
+
SYSTEM_PROMPT_TEMPLATE,
|
|
9
|
+
TOOL_DESCRIPTION_TEMPLATE,
|
|
10
|
+
VERIFICATION_NUDGE_TEMPLATE,
|
|
11
|
+
)
|
|
12
|
+
from unique_toolkit.agentic.tools.schemas import BaseToolConfig
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TodoConfig(BaseToolConfig):
|
|
16
|
+
display_name: str = Field(
|
|
17
|
+
default="Progress",
|
|
18
|
+
description="Human-readable label for task tracking shown in the Steps panel.",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
tool_description: Annotated[
|
|
22
|
+
str,
|
|
23
|
+
RJSFMetaTag.StringWidget.textarea(rows=3),
|
|
24
|
+
] = Field(
|
|
25
|
+
default=TOOL_DESCRIPTION_TEMPLATE,
|
|
26
|
+
description="Edit this Jinja template to customize the tool description passed to the LLM."
|
|
27
|
+
"Available variable: parallel_mode (bool).",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
system_prompt: Annotated[
|
|
31
|
+
str,
|
|
32
|
+
RJSFMetaTag.StringWidget.textarea(rows=15),
|
|
33
|
+
] = Field(
|
|
34
|
+
default=SYSTEM_PROMPT_TEMPLATE,
|
|
35
|
+
description="Edit this Jinja template to customize the system prompt injected for task tracking. "
|
|
36
|
+
"Available variable: parallel_mode (bool).",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
execution_reminder: Annotated[
|
|
40
|
+
str,
|
|
41
|
+
RJSFMetaTag.StringWidget.textarea(rows=5),
|
|
42
|
+
] = Field(
|
|
43
|
+
default=EXECUTION_REMINDER_TEMPLATE,
|
|
44
|
+
description="Edit this Jinja template to customize the reminder appended to tool responses "
|
|
45
|
+
"during execution phase. Available variable: parallel_mode (bool).",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
parallel_mode: Annotated[
|
|
49
|
+
bool,
|
|
50
|
+
RJSFMetaTag.BooleanWidget.checkbox(
|
|
51
|
+
help=(
|
|
52
|
+
"When enabled, the agent may combine task tracking with other "
|
|
53
|
+
"tool calls in the same turn and mark multiple items "
|
|
54
|
+
"in_progress simultaneously. When disabled (default), the "
|
|
55
|
+
"agent works through items one at a time with sequential "
|
|
56
|
+
"status updates."
|
|
57
|
+
),
|
|
58
|
+
),
|
|
59
|
+
] = Field(
|
|
60
|
+
default=False,
|
|
61
|
+
title="Track tasks alongside other tool calls",
|
|
62
|
+
description="Parallel Mode for Task Tracking",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
show_triggered_tool_calls: Annotated[
|
|
66
|
+
bool,
|
|
67
|
+
RJSFMetaTag.BooleanWidget.checkbox(
|
|
68
|
+
help=(
|
|
69
|
+
"Show 'Triggered Tool Calls' entries in the Steps panel "
|
|
70
|
+
"listing which tools the agent called each iteration. "
|
|
71
|
+
),
|
|
72
|
+
),
|
|
73
|
+
] = Field(
|
|
74
|
+
default=True,
|
|
75
|
+
title="Display triggered tool calls in the Steps panel",
|
|
76
|
+
description="Display Triggered Tool Calls",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
verification_threshold: int = Field(
|
|
80
|
+
default=5,
|
|
81
|
+
ge=0,
|
|
82
|
+
title="Verification Nudge Threshold",
|
|
83
|
+
description="After this many task completions, nudge the agent to verify its work "
|
|
84
|
+
"before continuing. Set to 0 to disable.",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
verification_nudge: Annotated[
|
|
88
|
+
str,
|
|
89
|
+
RJSFMetaTag.StringWidget.textarea(rows=2),
|
|
90
|
+
] = Field(
|
|
91
|
+
default=VERIFICATION_NUDGE_TEMPLATE,
|
|
92
|
+
description="Jinja template for the verification nudge message. "
|
|
93
|
+
"Available variable: completed (int).",
|
|
94
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
_PROMPTS_DIR = Path(__file__).parent
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _load(name: str) -> str:
|
|
7
|
+
return (_PROMPTS_DIR / name).read_text().strip()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
TOOL_DESCRIPTION_TEMPLATE = _load("tool_description.j2")
|
|
11
|
+
SYSTEM_PROMPT_TEMPLATE = _load("system_prompt.j2")
|
|
12
|
+
EXECUTION_REMINDER_TEMPLATE = _load("execution_reminder.j2")
|
|
13
|
+
VERIFICATION_NUDGE_TEMPLATE = _load("verification_nudge.j2")
|
unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/prompts/execution_reminder.j2
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
You are in the EXECUTION PHASE.
|
|
2
|
+
Do NOT ask the user any questions or request confirmation.
|
|
3
|
+
You MUST process every pending item — do not skip or summarize.
|
|
4
|
+
{%- if parallel_mode %}
|
|
5
|
+
- Always include a TodoWrite call alongside your work tool calls in the same response — mark items in_progress before executing and completed after.
|
|
6
|
+
- Do not use a separate turn just for status updates.
|
|
7
|
+
{%- else %}
|
|
8
|
+
- Mark exactly one item in_progress, complete it, then move to the next.
|
|
9
|
+
- Do not batch completions.
|
|
10
|
+
{%- endif %}
|
|
11
|
+
- Do NOT write a final text response while items are still pending or in_progress — keep executing until every item reaches a terminal state (completed/cancelled), then call TodoWrite one final time before responding.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
You have access to a task tracking tool (TodoWrite). Use it proactively — the user sees the task list as a live progress indicator.
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
Use for any task with 3+ steps, batch operations, or when the user gives a numbered list. For batch operations (e.g. "process all invoices"), create one task per item so none are skipped. When receiving new instructions mid-conversation, immediately capture them as tasks. Skip for single-step lookups or simple factual questions.
|
|
6
|
+
|
|
7
|
+
Examples:
|
|
8
|
+
- "Research competitor pricing and write a comparison" → create tasks per competitor + comparison + summary
|
|
9
|
+
- "Process all invoices in uploads" → one task per invoice
|
|
10
|
+
- "What's the capital of France?" → do NOT use TodoWrite
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. CLARIFICATION PHASE: Ask ALL clarifying questions in a single message upfront.
|
|
15
|
+
2. EXECUTION PHASE: After creating the task list, execute every step autonomously. Do NOT ask follow-up questions — use sensible defaults and document your assumptions.
|
|
16
|
+
|
|
17
|
+
## Task Design
|
|
18
|
+
|
|
19
|
+
- Break into 3-7 specific, actionable items with clear outcomes
|
|
20
|
+
- Provide active_form for each (e.g. content: "Search pricing data", active_form: "Searching pricing data")
|
|
21
|
+
- For complex tasks, include a final "verify and synthesize" item
|
|
22
|
+
|
|
23
|
+
## Execution Rules
|
|
24
|
+
|
|
25
|
+
- Execute immediately after creating the list. Do NOT ask for confirmation between steps.
|
|
26
|
+
{% if parallel_mode -%}
|
|
27
|
+
- Mark multiple items in_progress simultaneously. Combine TodoWrite with work tool calls in the same response — do not waste a turn on bookkeeping alone.
|
|
28
|
+
{%- else -%}
|
|
29
|
+
- Mark exactly ONE item in_progress at a time. Complete and mark it immediately before starting the next — do not batch completions.
|
|
30
|
+
{%- endif %}
|
|
31
|
+
- After completing a task, check if follow-up tasks need to be added.
|
|
32
|
+
- When unclear, if there is a reasonable default, choose it rather than stopping to ask. Document your assumption.
|
|
33
|
+
- Do NOT summarize remaining items or ask if you should continue. Just keep going.
|
|
34
|
+
- The ONLY reason to stop is a hard blocker: missing credentials, nonexistent resource, or unrecoverable error.
|
|
35
|
+
|
|
36
|
+
## Completion
|
|
37
|
+
|
|
38
|
+
- Never write a final response while items are still pending — if items remain, keep executing.
|
|
39
|
+
- You MUST call TodoWrite to mark every item completed/cancelled before your final response. Zero pending/in_progress items must remain.
|
|
40
|
+
- You have a limited iteration budget. Mark all items terminal BEFORE the final iteration when tools are removed.
|
|
41
|
+
- Items needing only analysis (no tool call) should be marked completed as soon as you have the data.
|
unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/prompts/tool_description.j2
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Create or update a task list to track progress. Use for any task involving multiple steps — the user sees this as a live progress indicator.
|
|
2
|
+
|
|
3
|
+
Provide active_form (present continuous, e.g. "Searching documents") for each task — this is shown to the user as live status text.
|
|
4
|
+
|
|
5
|
+
{% if parallel_mode -%}
|
|
6
|
+
Mark items in_progress when starting, completed when done. You can mark multiple items in_progress if working on them in parallel.
|
|
7
|
+
{%- else -%}
|
|
8
|
+
Mark exactly one item in_progress at a time. Mark it completed immediately when done, then move to the next item. Do not batch completions.
|
|
9
|
+
{%- endif %}
|
unique_toolkit-1.77.1/unique_toolkit/agentic/tools/experimental/todo/prompts/verification_nudge.j2
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[Checkpoint: {{ completed }} tasks completed. Before continuing, briefly verify recent results are correct.]
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections import Counter
|
|
4
|
+
from enum import StrEnum
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TodoStatus(StrEnum):
|
|
10
|
+
PENDING = "pending"
|
|
11
|
+
IN_PROGRESS = "in_progress"
|
|
12
|
+
COMPLETED = "completed"
|
|
13
|
+
CANCELLED = "cancelled"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
_STATUS_ICONS: dict[TodoStatus, str] = {
|
|
17
|
+
TodoStatus.PENDING: "[ ]",
|
|
18
|
+
TodoStatus.IN_PROGRESS: "[>]",
|
|
19
|
+
TodoStatus.COMPLETED: "[x]",
|
|
20
|
+
TodoStatus.CANCELLED: "[-]",
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
_TERMINAL_STATUSES: frozenset[TodoStatus] = frozenset(
|
|
24
|
+
{TodoStatus.COMPLETED, TodoStatus.CANCELLED}
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
model_config = ConfigDict(extra="forbid")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TodoItem(BaseModel):
|
|
32
|
+
"""Stored todo item — always has content."""
|
|
33
|
+
|
|
34
|
+
model_config = model_config
|
|
35
|
+
|
|
36
|
+
id: str = Field(
|
|
37
|
+
description="Unique identifier for this TODO (model-generated, free-form string e.g. 'research-apis', 'step-1')",
|
|
38
|
+
)
|
|
39
|
+
content: str = Field(description="Description of the task")
|
|
40
|
+
status: TodoStatus
|
|
41
|
+
active_form: str | None = Field(
|
|
42
|
+
description="Present-continuous form of the task shown as live status text "
|
|
43
|
+
"(e.g. 'Searching documents', 'Analyzing results'). "
|
|
44
|
+
"Provide when creating or updating an item.",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class TodoItemInput(BaseModel):
|
|
49
|
+
"""Input todo item — content is optional for merge updates (status-only changes)."""
|
|
50
|
+
|
|
51
|
+
model_config = model_config
|
|
52
|
+
id: str = Field(
|
|
53
|
+
description="Unique identifier for this TODO (model-generated, free-form string e.g. 'research-apis', 'step-1')",
|
|
54
|
+
)
|
|
55
|
+
content: str | None = Field(
|
|
56
|
+
description="Description of the task. Required when creating new items, optional when updating existing ones via merge.",
|
|
57
|
+
)
|
|
58
|
+
status: TodoStatus
|
|
59
|
+
active_form: str | None = Field(
|
|
60
|
+
description="Present-continuous form shown as live status text "
|
|
61
|
+
"(e.g. 'Searching documents'). Provide for richer UI display.",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class TodoList(BaseModel):
|
|
66
|
+
"""Full TODO state for a session. Stored in ShortTermMemory."""
|
|
67
|
+
|
|
68
|
+
model_config = model_config
|
|
69
|
+
todos: list[TodoItem] = Field(description="The list of todo items.")
|
|
70
|
+
last_updated_iteration: int = Field(
|
|
71
|
+
description="The iteration number of the last update."
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def update(self, incoming: list[TodoItemInput]) -> TodoList:
|
|
75
|
+
"""Update by ID: overwrite existing, append new, preserve unmentioned.
|
|
76
|
+
|
|
77
|
+
When an incoming item omits content, the existing content is preserved.
|
|
78
|
+
active_form falls back to existing value when not supplied.
|
|
79
|
+
New items without content get an empty string as fallback.
|
|
80
|
+
"""
|
|
81
|
+
existing_by_id = {t.id: t for t in self.todos}
|
|
82
|
+
for item in incoming:
|
|
83
|
+
existing = existing_by_id.get(item.id)
|
|
84
|
+
content = (
|
|
85
|
+
item.content
|
|
86
|
+
if item.content is not None
|
|
87
|
+
else (existing.content if existing else "")
|
|
88
|
+
)
|
|
89
|
+
active_form = (
|
|
90
|
+
item.active_form
|
|
91
|
+
if item.active_form is not None
|
|
92
|
+
else (existing.active_form if existing else None)
|
|
93
|
+
)
|
|
94
|
+
existing_by_id[item.id] = TodoItem(
|
|
95
|
+
id=item.id,
|
|
96
|
+
content=content,
|
|
97
|
+
status=item.status,
|
|
98
|
+
active_form=active_form,
|
|
99
|
+
)
|
|
100
|
+
return TodoList(
|
|
101
|
+
todos=list(existing_by_id.values()),
|
|
102
|
+
last_updated_iteration=self.last_updated_iteration,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def has_active_items(self) -> bool:
|
|
106
|
+
return any(t.status not in _TERMINAL_STATUSES for t in self.todos)
|
|
107
|
+
|
|
108
|
+
def format(self) -> str:
|
|
109
|
+
"""Format as human-readable text for tool responses."""
|
|
110
|
+
if not self.todos:
|
|
111
|
+
return "No tasks tracked."
|
|
112
|
+
summary = self._summarize()
|
|
113
|
+
return f"Task list ({summary}):\n" + "\n".join(self._format_lines())
|
|
114
|
+
|
|
115
|
+
def status_counter(self) -> Counter[str]:
|
|
116
|
+
"""Return a Counter of status values. Missing keys auto-return 0."""
|
|
117
|
+
return Counter(t.status.value for t in self.todos)
|
|
118
|
+
|
|
119
|
+
def _format_lines(self) -> list[str]:
|
|
120
|
+
return [
|
|
121
|
+
f" {_STATUS_ICONS.get(t.status, '[ ]')} {t.content} (id: {t.id})"
|
|
122
|
+
for t in self.todos
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
def _summarize(self) -> str:
|
|
126
|
+
completed = sum(1 for t in self.todos if t.status == TodoStatus.COMPLETED)
|
|
127
|
+
return f"{completed}/{len(self.todos)} completed"
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class TodoWriteInput(BaseModel):
|
|
131
|
+
model_config = model_config
|
|
132
|
+
todos: list[TodoItemInput] = Field(
|
|
133
|
+
min_length=1, description="The list of todo items to update."
|
|
134
|
+
)
|
|
135
|
+
merge: bool = Field(
|
|
136
|
+
description="If true, merge with existing todos by ID. If false, replace entirely.",
|
|
137
|
+
)
|