agent-framework-lib 0.8.5__tar.gz → 0.8.6__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.
- {agent_framework_lib-0.8.5/agent_framework_lib.egg-info → agent_framework_lib-0.8.6}/PKG-INFO +1 -1
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/__init__.py +2 -2
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/agent_interface.py +32 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/base_agent.py +31 -44
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/execution_controller.py +77 -55
- agent_framework_lib-0.8.6/agent_framework/core/prompt_builder.py +198 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/providers/graphiti_provider.py +27 -21
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/work_patterns.py +104 -4
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/__init__.py +0 -2
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/discovery_prompt.py +0 -14
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/skills_demo_agent.py +1 -6
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/server.py +11 -11
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6/agent_framework_lib.egg-info}/PKG-INFO +1 -1
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework_lib.egg-info/SOURCES.txt +1 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/skills_demo_agent.py +1 -6
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/pyproject.toml +9 -2
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/ARCHITECTURE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/LICENSE +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/MANIFEST.in +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/README.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/base.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/endpoints/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/endpoints/a2a_router.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/endpoints/agent_card_builder.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/endpoints/agent_card_skill_builder.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/endpoints/jsonrpc_dispatcher.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/endpoints/models_jsonrpc.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/endpoints/sse_wrapper.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/endpoints/translation_layer.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/models.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/providers/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/providers/elasticsearch_provider.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/a2a/providers/postgres_provider.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/capabilities/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/capabilities/resolver.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/activity_formatter.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/agent_provider.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/context_budget.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/context_summarizer.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/elasticsearch_config_provider.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/implementation_validator.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/interruption_message.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/knowledge_state.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/loop_detector.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/model_clients.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/model_config.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/model_router.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/models.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/provider_calibration.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/scratchpad_compressor.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/scratchpad_serializer.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/state_manager.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/step_display_config.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/streaming_parts_accumulator.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/implementations/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/implementations/budget_aware_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/implementations/llamaindex_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/implementations/llamaindex_memory_adapter.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/implementations/microsoft_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/agent_mixin.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/base.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/config.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/hypothesis_engine.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/implicit_feedback.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/manager.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/personalization.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/providers/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/providers/memori_provider.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/response_lessons.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/memory/tools.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/api_timing_tracker.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/elasticsearch_circuit_breaker.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/elasticsearch_logging.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/error_handling.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/error_logging.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/llm_auto_instrumentor.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/llm_metrics.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/llm_metrics_collector.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/llm_metrics_extractor.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/metrics_aggregator.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/metrics_config.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/observability_manager.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/otel_instrumentor.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/otel_logging_handler.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/otel_metrics_recorder.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/otel_setup.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/performance_monitor.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/progress_tracker.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/resource_manager.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/resource_metrics_collector.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/streaming_latency_tracer.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/timing_tracker.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/token_counter.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/monitoring/tracing_context.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/notifications/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/notifications/hub.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/notifications/webhook_notifier.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/processing/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/processing/ai_content_management.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/processing/markdown_converter.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/processing/multimodal_integration.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/processing/rich_content_validation.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/py.typed +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/session/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/session/elasticsearch_session_storage.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/session/session_storage.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/agent_mixin.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/base.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/scripts/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/scripts/create_and_register.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/scripts/register_to_storage.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/chart/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/chart/chart_to_image.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/code_format/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/code_format/format_python.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/csv/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/csv/create_csv.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/csv/read_csv.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/csv/transform_csv.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/data_format/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/data_format/json_to_yaml.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/data_format/yaml_to_json.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/drawio/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/drawio/create_drawio.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/email_template/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/excel/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/excel/create_excel.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/file/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/file/create_file.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/file/list_files.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/file/read_file.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/file_access/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/file_access/download_to_local.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/file_access/get_file_path.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/form/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/image_display/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/image_gen/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/image_gen/create_image.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/image_gen/generate_image.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/mermaid/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/mermaid/mermaid_to_image.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/multimodal/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/optionsblock/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/powerpoint/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/powerpoint/create_powerpoint.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/powerpoint/templates/Big Data Infographics.pptx +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/powerpoint/templates/Executive Design Pitch Deck.pptx +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/powerpoint/templates/Management Consulting Toolkit.pptx +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/powerpoint/templates/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/powerpoint/templates/generate_templates.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/skill_creator/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/skill_creator/skill_api.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/table/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/table/table_to_image.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/unified_pdf/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/unified_pdf/create_pdf.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/web_news_search/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/web_news_search/web_news_search.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/word/SKILL.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/builtin/skills/word/create_word.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/custom_skill_manager.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/markdown_loader.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/skills/tools.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/storage/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/storage/file_storages.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/storage/file_system_management.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/storage/storage_optimizer.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/subagents/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/subagents/executor.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/subagents/message_injector.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/subagents/message_queue.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/subagents/retrigger.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/subagents/spawn_tool.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/activity_callback.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/adaptive_pdf_css.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/base.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/html_content_analyzer.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/multimodal_tools.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/pdf_image_scaler.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/shell_tool.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/sizing_config.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/web_fetch_tool.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/tools/web_search_tool.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/utils/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/utils/path_utils.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/utils/post_install.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/utils/session_title_generator.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/utils/source_detector.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/utils/special_blocks.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/admin_auth.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/admin_models.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/admin_router.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/admin_services.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/api_timing_middleware.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/A2A_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/BUILTIN_SKILLS_REFERENCE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/CREATING_AGENTS.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/CUSTOM_SKILLS_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/DOCKER_SETUP.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/Dockerfile +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/GETTING_STARTED.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/GITNEXUS_USER_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/MEMORY_INSTALLATION.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/README.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/TOOLS_AND_MCP_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/WORKSPACE_INTEGRATION.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/api-reference.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/configuration.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/docker-compose.yml +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/agent_example_multi_skills.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/agent_with_file_storage.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/agent_with_mcp.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/agent_with_memory.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/agent_with_memory_graphiti.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/agent_with_memory_hybrid.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/agent_with_memory_simple.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/custom_framework_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/examples/simple_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/docs/installation-guide.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/documentation_generator.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/gitnexus_client.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/helper_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/helper_ui.html +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/modern_ui.html +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/observability/kibana-llm-dashboard-setup.json +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/observability/kibana-resource-metrics-dashboard.json +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/otel_tracing_middleware.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/skills_router.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/web/test_app.html +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/__init__.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/artefacts.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/client.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/config.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/context.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/cursor.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/memory.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/models.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/poller.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/preferences.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/router.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/session.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/workspace/subscription.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework_lib.egg-info/dependency_links.txt +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework_lib.egg-info/entry_points.txt +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework_lib.egg-info/requires.txt +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework_lib.egg-info/top_level.txt +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/A2A_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/ACTIVITY_OUTPUT_PART.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/ARCHITECTURE_DIAGRAM.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/BUILTIN_SKILLS_REFERENCE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/CANCEL_AND_INTERRUPT_FRONTEND.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/CONCURRENCE_VS_PARALLELISME_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/CREATING_AGENTS.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/CUSTOM_SKILLS_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/DEEPEVAL_TEST_REPORT.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/DOCKER_SETUP.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/ELASTICSEARCH_DATA_STRUCTURES.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/FILE_DOWNLOAD_LINKS.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/FILE_STORAGE_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/GETTING_STARTED.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/GITNEXUS_USER_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/HISTORY_MESSAGE_FORMAT.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/IMPLEMENTATION_GUIDE_NEW_AGENT.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/MEMORY_INSTALLATION.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/MODIFICATIONS_CONCURRENCE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/MULTIMODAL_TOOLS_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/OBSERVABILITY_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/PYPI_PUBLISHING.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/QA_STREAMING_LATENCY.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/SCREENSHOTS_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/SPEC_CROSS_MODEL_HISTORY_CONVERSION.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/SSE_NOTIFICATIONS_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/STREAMING_EVENTS_FRONTEND.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/TOOLS_AND_MCP_GUIDE.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/WORKSPACE_INTEGRATION.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/api-reference.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/configuration.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/framework_audit_remarques.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/helper_agent.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/index.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/docs/installation-guide.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/README.md +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_context_budget_test.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_example_multi_skills.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_exemple_test.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_training_with_apo.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_with_custom_tools_file_storage.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_with_file_storage.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_with_mcp.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_with_memory_graphiti.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_with_memory_hybrid.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_with_memory_simple.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/agent_with_personalization.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/biagenttest.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/custom_framework_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/dependencies/docker-compose.yaml +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/pyproject.toml +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/simple_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/test_work_patterns_live.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/examples/workspace_test_agent.py +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/setup.cfg +0 -0
- {agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/setup.py +0 -0
{agent_framework_lib-0.8.5/agent_framework_lib.egg-info → agent_framework_lib-0.8.6}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-framework-lib
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.6
|
|
4
4
|
Summary: A comprehensive Python framework for building and serving conversational AI agents with FastAPI
|
|
5
5
|
Author-email: Sebastian Pavel <sebastian@cinco.ai>, Elliott Girard <elliott.girard@icloud.com>
|
|
6
6
|
Maintainer-email: Sebastian Pavel <sebastian@cinco.ai>
|
|
@@ -32,7 +32,7 @@ Example Usage:
|
|
|
32
32
|
create_basic_agent_server(MyAgent, port=8000)
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Version: 0.8.
|
|
35
|
+
Version: 0.8.6
|
|
36
36
|
Author: Cinco AI Team
|
|
37
37
|
License: MIT
|
|
38
38
|
"""
|
|
@@ -89,7 +89,7 @@ def _auto_setup_dependencies() -> None:
|
|
|
89
89
|
# Track if auto-setup has been done
|
|
90
90
|
_AUTO_SETUP_DONE = False
|
|
91
91
|
|
|
92
|
-
__version__ = "0.8.
|
|
92
|
+
__version__ = "0.8.6"
|
|
93
93
|
__author__ = "Cinco AI Team"
|
|
94
94
|
__license__ = "MIT"
|
|
95
95
|
__email__ = "sebastian@cinco.ai"
|
{agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/agent_interface.py
RENAMED
|
@@ -860,6 +860,38 @@ class AgentInterface(abc.ABC):
|
|
|
860
860
|
"""
|
|
861
861
|
pass
|
|
862
862
|
|
|
863
|
+
def get_cancellation_refs(self) -> dict[str, Any]:
|
|
864
|
+
"""
|
|
865
|
+
Return framework-specific references the server uses to wire up
|
|
866
|
+
graceful cancellation for the in-flight turn.
|
|
867
|
+
|
|
868
|
+
The returned dict may contain any of:
|
|
869
|
+
- ``handler``: the live workflow handler (e.g. LlamaIndex's
|
|
870
|
+
``WorkflowHandler``) that the server will pass to
|
|
871
|
+
``ExecutionController.set_handler`` so an external cancel can call
|
|
872
|
+
``handler.cancel_run()``.
|
|
873
|
+
- ``ctx``: the agent's working context (used for scratchpad commit on
|
|
874
|
+
cancel).
|
|
875
|
+
- ``memory``: the chat memory buffer (used for scratchpad replay).
|
|
876
|
+
- ``memory_adapter``: the memory adapter (used to invalidate caches
|
|
877
|
+
after the scratchpad is committed).
|
|
878
|
+
|
|
879
|
+
The default implementation returns all keys set to ``None``. Agents
|
|
880
|
+
that participate in cancellation (BaseAgent + LlamaIndex-style
|
|
881
|
+
agents) should override this method. The server treats every key as
|
|
882
|
+
optional and only wires what is present.
|
|
883
|
+
|
|
884
|
+
Exposing these refs through a single public method keeps the server
|
|
885
|
+
framework-agnostic — it never has to touch private agent attributes
|
|
886
|
+
like ``_current_handler`` or ``_current_ctx``.
|
|
887
|
+
"""
|
|
888
|
+
return {
|
|
889
|
+
"handler": None,
|
|
890
|
+
"ctx": None,
|
|
891
|
+
"memory": None,
|
|
892
|
+
"memory_adapter": None,
|
|
893
|
+
}
|
|
894
|
+
|
|
863
895
|
def get_custom_tool_display_info(self) -> dict[str, Any]:
|
|
864
896
|
"""
|
|
865
897
|
Returns custom display info for agent-specific tools (e.g., MCP tools).
|
|
@@ -388,6 +388,23 @@ class BaseAgent(SkillsMixin, MemoryMixin, AgentInterface):
|
|
|
388
388
|
else:
|
|
389
389
|
self._message_queue = None
|
|
390
390
|
|
|
391
|
+
def get_cancellation_refs(self) -> dict[str, Any]:
|
|
392
|
+
"""Expose private cancellation hooks through a single public method.
|
|
393
|
+
|
|
394
|
+
Returns the live framework objects (workflow handler, agent context,
|
|
395
|
+
memory, memory adapter) that the FastAPI server registers with the
|
|
396
|
+
``ExecutionController`` so a user-issued cancel can commit the
|
|
397
|
+
scratchpad and abort the in-flight handler. Keeping this behind a
|
|
398
|
+
single interface method lets the server stay framework-agnostic
|
|
399
|
+
instead of poking at private attributes like ``_current_handler``.
|
|
400
|
+
"""
|
|
401
|
+
return {
|
|
402
|
+
"handler": getattr(self, "_current_handler", None),
|
|
403
|
+
"ctx": getattr(self, "_current_ctx", None),
|
|
404
|
+
"memory": getattr(self, "_current_memory", None),
|
|
405
|
+
"memory_adapter": getattr(self, "_memory_adapter", None),
|
|
406
|
+
}
|
|
407
|
+
|
|
391
408
|
def _create_subagent_spawn_tool(self) -> SubagentSpawnTool | None:
|
|
392
409
|
"""Create the SubagentSpawnTool if all conditions are met.
|
|
393
410
|
|
|
@@ -910,51 +927,21 @@ class BaseAgent(SkillsMixin, MemoryMixin, AgentInterface):
|
|
|
910
927
|
except Exception as e:
|
|
911
928
|
logger.warning("Personalization injection skipped: %s", e)
|
|
912
929
|
|
|
913
|
-
|
|
914
|
-
"""
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
If skills are enabled (default), automatically combines the agent's
|
|
918
|
-
custom prompt with skills discovery instructions that teach the agent
|
|
919
|
-
how to discover and load skills on-demand.
|
|
930
|
+
def _has_shell_tool(self) -> bool:
|
|
931
|
+
"""Check whether a shell tool is available."""
|
|
932
|
+
return self._live_shell_tool is not None
|
|
920
933
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
return get_skills_discovery_prompt()
|
|
934
|
-
except ImportError as e:
|
|
935
|
-
logger.error(f"Failed to import skills discovery prompt: {e}")
|
|
936
|
-
logger.warning("Skills discovery capabilities unavailable, using empty prompt")
|
|
937
|
-
return ""
|
|
938
|
-
return ""
|
|
939
|
-
|
|
940
|
-
if not self._enable_skills or not SKILLS_AVAILABLE:
|
|
941
|
-
logger.debug("Skills disabled, returning base prompt only")
|
|
942
|
-
return base_prompt
|
|
943
|
-
|
|
944
|
-
# Import here to avoid circular dependencies
|
|
945
|
-
try:
|
|
946
|
-
from ..skills.discovery_prompt import get_skills_discovery_prompt
|
|
947
|
-
|
|
948
|
-
skills_prompt = get_skills_discovery_prompt()
|
|
949
|
-
combined = f"{base_prompt}\n\n{skills_prompt}"
|
|
950
|
-
logger.debug(
|
|
951
|
-
f"Combined prompt length: {len(combined)} chars (base: {len(base_prompt)}, skills: {len(skills_prompt)})"
|
|
952
|
-
)
|
|
953
|
-
return combined
|
|
954
|
-
except ImportError as e:
|
|
955
|
-
logger.error(f"Failed to import skills discovery prompt: {e}")
|
|
956
|
-
logger.warning("Skills discovery capabilities unavailable, using base prompt only")
|
|
957
|
-
return base_prompt
|
|
934
|
+
async def get_system_prompt(self) -> str | None:
|
|
935
|
+
"""Assemble le system prompt via PromptBuilder."""
|
|
936
|
+
from .prompt_builder import PromptBuilder
|
|
937
|
+
|
|
938
|
+
builder = PromptBuilder(
|
|
939
|
+
agent_prompt=self._session_system_prompt or "",
|
|
940
|
+
has_shell_tool=self._has_shell_tool(),
|
|
941
|
+
has_workspace=self._workspace_context is not None,
|
|
942
|
+
skills_enabled=self._enable_skills and SKILLS_AVAILABLE,
|
|
943
|
+
)
|
|
944
|
+
return builder.build()
|
|
958
945
|
|
|
959
946
|
async def get_current_model(self, session_id: str) -> str | None:
|
|
960
947
|
"""Return the current model name."""
|
{agent_framework_lib-0.8.5 → agent_framework_lib-0.8.6}/agent_framework/core/execution_controller.py
RENAMED
|
@@ -40,6 +40,11 @@ class ExecutionContext:
|
|
|
40
40
|
# MessageData on cancel, so the /cancel endpoint skips its own persist
|
|
41
41
|
# and we don't write duplicate entries.
|
|
42
42
|
stream_persisted_partial: bool = False
|
|
43
|
+
# Serializes concurrent cancel_execution / end_execution calls for this
|
|
44
|
+
# session. Without this, two awaiters can both pass the ``state == RUNNING``
|
|
45
|
+
# check before either sets state=IDLE, and both will commit the scratchpad
|
|
46
|
+
# + return True (cf. test_exactly_one_cancel_succeeds).
|
|
47
|
+
lock: asyncio.Lock = field(default_factory=asyncio.Lock)
|
|
43
48
|
|
|
44
49
|
|
|
45
50
|
class InvalidStateTransitionError(Exception):
|
|
@@ -284,70 +289,82 @@ class ExecutionController:
|
|
|
284
289
|
8. return True
|
|
285
290
|
"""
|
|
286
291
|
ctx = self._sessions.get(session_id)
|
|
287
|
-
if not ctx
|
|
292
|
+
if not ctx:
|
|
288
293
|
return False
|
|
289
294
|
|
|
290
|
-
#
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
)
|
|
302
|
-
except asyncio.TimeoutError:
|
|
303
|
-
logger.warning(
|
|
304
|
-
"[EC] Scratchpad commit timeout (5s) for session %s, proceeding with standard cancel",
|
|
305
|
-
session_id,
|
|
306
|
-
)
|
|
307
|
-
except Exception as exc:
|
|
308
|
-
logger.warning(
|
|
309
|
-
"[EC] Scratchpad commit failed for session %s: %s, proceeding with standard cancel",
|
|
295
|
+
# Serialize concurrent cancel_execution calls for this session. The
|
|
296
|
+
# state check + commit + state mutation must run atomically — without
|
|
297
|
+
# the lock, two awaiters both observe RUNNING and both commit + return
|
|
298
|
+
# True, violating "exactly one cancellation succeeds".
|
|
299
|
+
async with ctx.lock:
|
|
300
|
+
if ctx.state != ExecutionState.RUNNING:
|
|
301
|
+
return False
|
|
302
|
+
|
|
303
|
+
# Phase 1: Commit scratchpad (best-effort, before cancel_event.set)
|
|
304
|
+
logger.info(
|
|
305
|
+
"[EC] cancel_execution starting for session %s (interaction %s)",
|
|
310
306
|
session_id,
|
|
311
|
-
|
|
312
|
-
exc_info=True,
|
|
307
|
+
ctx.interaction_id,
|
|
313
308
|
)
|
|
314
|
-
|
|
315
|
-
# Phase 1b: Invalidate cache after successful commit (Requirement 3.1)
|
|
316
|
-
if commit_succeeded and ctx.memory_adapter is not None:
|
|
309
|
+
commit_succeeded = False
|
|
317
310
|
try:
|
|
318
|
-
|
|
319
|
-
|
|
311
|
+
commit_succeeded = await asyncio.wait_for(
|
|
312
|
+
self._commit_scratchpad(ctx),
|
|
313
|
+
timeout=5.0,
|
|
314
|
+
)
|
|
315
|
+
except asyncio.TimeoutError:
|
|
316
|
+
logger.warning(
|
|
317
|
+
"[EC] Scratchpad commit timeout (5s) for session %s, proceeding with standard cancel",
|
|
318
|
+
session_id,
|
|
319
|
+
)
|
|
320
320
|
except Exception as exc:
|
|
321
|
-
logger.warning(
|
|
321
|
+
logger.warning(
|
|
322
|
+
"[EC] Scratchpad commit failed for session %s: %s, proceeding with standard cancel",
|
|
323
|
+
session_id,
|
|
324
|
+
exc,
|
|
325
|
+
exc_info=True,
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
# Phase 1b: Invalidate cache after successful commit (Requirement 3.1)
|
|
329
|
+
if commit_succeeded and ctx.memory_adapter is not None:
|
|
330
|
+
try:
|
|
331
|
+
ctx.memory_adapter.clear_cache(session_id=session_id, user_id=ctx.user_id)
|
|
332
|
+
logger.info("[EC] Cache invalidated for session %s", session_id)
|
|
333
|
+
except Exception as exc:
|
|
334
|
+
logger.warning(
|
|
335
|
+
"[EC] Cache invalidation failed for session %s: %s", session_id, exc
|
|
336
|
+
)
|
|
322
337
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
338
|
+
# Phase 2: Standard cancellation
|
|
339
|
+
ctx.cancel_event.set()
|
|
340
|
+
ctx.state = ExecutionState.IDLE
|
|
326
341
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
342
|
+
# Cancel the LlamaIndex workflow handler if available
|
|
343
|
+
if ctx.handler is not None:
|
|
344
|
+
try:
|
|
345
|
+
cancel_method = getattr(ctx.handler, "cancel_run", None)
|
|
346
|
+
if cancel_method and asyncio.iscoroutinefunction(cancel_method):
|
|
347
|
+
await cancel_method()
|
|
348
|
+
logger.info("[EC] Called handler.cancel_run() for session %s", session_id)
|
|
349
|
+
elif hasattr(ctx.handler, "cancel"):
|
|
350
|
+
ctx.handler.cancel()
|
|
351
|
+
logger.info("[EC] Called handler.cancel() for session %s", session_id)
|
|
352
|
+
except Exception as exc:
|
|
353
|
+
logger.warning(
|
|
354
|
+
"[EC] Error cancelling handler for session %s: %s", session_id, exc
|
|
355
|
+
)
|
|
356
|
+
ctx.handler = None
|
|
340
357
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
358
|
+
# Phase 3: Clean up agent references (Requirement 2.4)
|
|
359
|
+
# NOTE: keep ``last_scratchpad_activity_parts`` so server.py can read it
|
|
360
|
+
# right after cancel to build the InterruptionMessage.
|
|
361
|
+
ctx.agent_ctx = None
|
|
362
|
+
ctx.memory = None
|
|
363
|
+
ctx.memory_adapter = None
|
|
364
|
+
ctx.session_storage = None
|
|
365
|
+
ctx.user_id = None
|
|
349
366
|
|
|
350
|
-
|
|
367
|
+
return True
|
|
351
368
|
|
|
352
369
|
async def end_execution(self, session_id: str) -> None:
|
|
353
370
|
"""Termine normalement une exécution.
|
|
@@ -357,7 +374,12 @@ class ExecutionController:
|
|
|
357
374
|
CancelledError (client disconnect) rather than a clean cancel.
|
|
358
375
|
"""
|
|
359
376
|
ctx = self._sessions.get(session_id)
|
|
360
|
-
if ctx:
|
|
377
|
+
if not ctx:
|
|
378
|
+
return
|
|
379
|
+
# Use the same per-session lock as ``cancel_execution`` so the two
|
|
380
|
+
# paths cannot race (e.g. cancel mid-stream while the stream is also
|
|
381
|
+
# ending normally).
|
|
382
|
+
async with ctx.lock:
|
|
361
383
|
# Best-effort scratchpad commit before cleanup.
|
|
362
384
|
# This covers the GeneratorExit / CancelledError path where
|
|
363
385
|
# cancel_execution() was never called.
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"""Modular prompt assembly system for enhanced system prompts."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
from agent_framework.skills.discovery_prompt import SKILLS_DISCOVERY_PROMPT
|
|
11
|
+
except ImportError:
|
|
12
|
+
SKILLS_DISCOVERY_PROMPT = ""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class PromptSection:
|
|
17
|
+
"""A named, conditionally-included section of the system prompt."""
|
|
18
|
+
|
|
19
|
+
name: str
|
|
20
|
+
content: str
|
|
21
|
+
order: int
|
|
22
|
+
prerequisite_met: bool = True
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
BASE_PROMPT_SECTION: str = """## Communication & Efficiency
|
|
26
|
+
|
|
27
|
+
- Provide concise responses focused on results, not process descriptions.
|
|
28
|
+
- Use structured formatting (bullet points, code blocks, tables) for technical information.
|
|
29
|
+
- State what was done and what the result is. Do not narrate each intermediate step.
|
|
30
|
+
- Do not repeat information already visible in the conversation context.
|
|
31
|
+
- When encountering an error, report it with a diagnosis and proposed next steps — never forward raw error output without interpretation."""
|
|
32
|
+
|
|
33
|
+
PROACTIVE_SECTION: str = """## Proactive Behavior
|
|
34
|
+
|
|
35
|
+
- Attempt actions before asking clarifying questions. Use available tools to gather information rather than asking the user for details you can discover yourself.
|
|
36
|
+
- Complete multi-step tasks in a single response when all required information is available or discoverable via tools.
|
|
37
|
+
- When a request is ambiguous, attempt the most likely interpretation and state the assumption made. Only ask for clarification when multiple interpretations would lead to fundamentally different outcomes.
|
|
38
|
+
- Report results concisely without repeating the original request or adding unnecessary preamble."""
|
|
39
|
+
|
|
40
|
+
SHELL_SECTION: str = """## Shell Usage & Diagnostics
|
|
41
|
+
|
|
42
|
+
You have access to `shell_exec` for running shell commands. Use it proactively:
|
|
43
|
+
|
|
44
|
+
**Diagnostics first**: Before reporting a problem to the user, use shell_exec to verify connectivity, test commands, and diagnose the issue yourself. Chain diagnostic commands in a logical sequence (check connectivity → verify credentials → test endpoint).
|
|
45
|
+
|
|
46
|
+
**Environment discovery**: Read environment variables via shell_exec (`echo $VAR_NAME` or `env | grep PATTERN`) to discover available service endpoints and credentials. Do not ask the user for values that are available in the environment.
|
|
47
|
+
|
|
48
|
+
**Timeout**: The default timeout is 30 seconds. Use the `timeout` parameter for commands expected to take longer.
|
|
49
|
+
|
|
50
|
+
**Error interpretation**: Interpret non-zero exit codes and stderr output to diagnose failures. Provide the user with a diagnosis, not raw output.
|
|
51
|
+
|
|
52
|
+
**Dependency auto-install**: When shell output shows an ImportError or missing client library:
|
|
53
|
+
1. Detect the missing package name from the error message.
|
|
54
|
+
2. Install it with `uv pip install <package>` (never use `pip` directly — always `uv`).
|
|
55
|
+
3. Retry the failed command.
|
|
56
|
+
4. If installation fails, report the specific error to the user.
|
|
57
|
+
5. Install only the specific missing package, not unrelated packages."""
|
|
58
|
+
|
|
59
|
+
WORKSPACE_SECTION: str = """## Workspace Context
|
|
60
|
+
|
|
61
|
+
You are operating within a shared workspace. Leverage the workspace context:
|
|
62
|
+
|
|
63
|
+
**Secrets as env vars**: Workspace entities marked as secrets are available as environment variables in shell_exec. Access them via `$VARIABLE_NAME` in shell commands. NEVER expose secret values in your text responses.
|
|
64
|
+
|
|
65
|
+
**Service discovery**: Infer available services from entity names (e.g., `ELASTICSEARCH_URL` implies Elasticsearch access, `REDIS_HOST` implies Redis). Test service connectivity via shell_exec using available credentials before reporting access issues.
|
|
66
|
+
|
|
67
|
+
**Collaboration**: Use workspace member information to personalize interactions and understand the collaboration context."""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class PromptBuilder:
|
|
71
|
+
"""Assembles the system prompt from modular, conditional sections."""
|
|
72
|
+
|
|
73
|
+
SECTION_SEPARATOR: str = "\n\n"
|
|
74
|
+
|
|
75
|
+
def __init__(
|
|
76
|
+
self,
|
|
77
|
+
agent_prompt: str,
|
|
78
|
+
has_shell_tool: bool = False,
|
|
79
|
+
has_workspace: bool = False,
|
|
80
|
+
skills_enabled: bool = True,
|
|
81
|
+
) -> None:
|
|
82
|
+
self._agent_prompt = agent_prompt
|
|
83
|
+
self._has_shell_tool = has_shell_tool
|
|
84
|
+
self._has_workspace = has_workspace
|
|
85
|
+
self._skills_enabled = skills_enabled
|
|
86
|
+
|
|
87
|
+
self._sections = self._build_sections()
|
|
88
|
+
|
|
89
|
+
def _build_sections(self) -> list[PromptSection]:
|
|
90
|
+
"""Create all sections with their prerequisite flags."""
|
|
91
|
+
return [
|
|
92
|
+
PromptSection(
|
|
93
|
+
name="Agent_Prompt",
|
|
94
|
+
content=self._agent_prompt,
|
|
95
|
+
order=0,
|
|
96
|
+
prerequisite_met=True,
|
|
97
|
+
),
|
|
98
|
+
PromptSection(
|
|
99
|
+
name="Base_Prompt_Section",
|
|
100
|
+
content=BASE_PROMPT_SECTION,
|
|
101
|
+
order=1,
|
|
102
|
+
prerequisite_met=True,
|
|
103
|
+
),
|
|
104
|
+
PromptSection(
|
|
105
|
+
name="Proactive_Section",
|
|
106
|
+
content=PROACTIVE_SECTION,
|
|
107
|
+
order=2,
|
|
108
|
+
prerequisite_met=True,
|
|
109
|
+
),
|
|
110
|
+
PromptSection(
|
|
111
|
+
name="Shell_Section",
|
|
112
|
+
content=SHELL_SECTION,
|
|
113
|
+
order=3,
|
|
114
|
+
prerequisite_met=self._has_shell_tool,
|
|
115
|
+
),
|
|
116
|
+
PromptSection(
|
|
117
|
+
name="Workspace_Section",
|
|
118
|
+
content=WORKSPACE_SECTION,
|
|
119
|
+
order=4,
|
|
120
|
+
prerequisite_met=self._has_workspace,
|
|
121
|
+
),
|
|
122
|
+
PromptSection(
|
|
123
|
+
name="Skills_Discovery_Section",
|
|
124
|
+
content=SKILLS_DISCOVERY_PROMPT,
|
|
125
|
+
order=5,
|
|
126
|
+
prerequisite_met=self._skills_enabled and bool(SKILLS_DISCOVERY_PROMPT),
|
|
127
|
+
),
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
def build(self) -> str:
|
|
131
|
+
"""Assemble the final prompt from active sections in canonical order."""
|
|
132
|
+
active = sorted(
|
|
133
|
+
[s for s in self._sections if s.prerequisite_met],
|
|
134
|
+
key=lambda s: s.order,
|
|
135
|
+
)
|
|
136
|
+
return self.SECTION_SEPARATOR.join(s.content for s in active)
|
|
137
|
+
|
|
138
|
+
def get_active_sections(self) -> list[str]:
|
|
139
|
+
"""Return the list of active section names in canonical order."""
|
|
140
|
+
return [s.name for s in sorted(self._sections, key=lambda s: s.order) if s.prerequisite_met]
|
|
141
|
+
|
|
142
|
+
def get_sections(self) -> list[PromptSection]:
|
|
143
|
+
"""Return all registered sections (active and inactive)."""
|
|
144
|
+
return list(self._sections)
|
|
145
|
+
|
|
146
|
+
@staticmethod
|
|
147
|
+
def parse_sections(assembled_prompt: str) -> list[PromptSection]:
|
|
148
|
+
"""Parse an assembled prompt back into its constituent sections.
|
|
149
|
+
|
|
150
|
+
Each section is delimited by a markdown header: ## Section Name
|
|
151
|
+
The agent prompt (first section) has no header delimiter.
|
|
152
|
+
"""
|
|
153
|
+
# Split on ## headers while keeping the delimiter
|
|
154
|
+
parts = re.split(r"(?=^## )", assembled_prompt, flags=re.MULTILINE)
|
|
155
|
+
|
|
156
|
+
sections: list[PromptSection] = []
|
|
157
|
+
|
|
158
|
+
for i, part in enumerate(parts):
|
|
159
|
+
if not part:
|
|
160
|
+
continue
|
|
161
|
+
|
|
162
|
+
if i == 0 and not part.startswith("## "):
|
|
163
|
+
# First part is the agent prompt (no ## header)
|
|
164
|
+
sections.append(
|
|
165
|
+
PromptSection(
|
|
166
|
+
name="Agent_Prompt",
|
|
167
|
+
content=part.rstrip("\n"),
|
|
168
|
+
order=0,
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
else:
|
|
172
|
+
# Extract section name from the ## header line
|
|
173
|
+
lines = part.split("\n", 1)
|
|
174
|
+
header = lines[0]
|
|
175
|
+
name = header.lstrip("# ").strip()
|
|
176
|
+
sections.append(
|
|
177
|
+
PromptSection(
|
|
178
|
+
name=name,
|
|
179
|
+
content=part.rstrip("\n"),
|
|
180
|
+
order=len(sections),
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
return sections
|
|
185
|
+
|
|
186
|
+
def get_token_estimate(self) -> int:
|
|
187
|
+
"""Return approximate token count of framework-added sections.
|
|
188
|
+
|
|
189
|
+
Excludes agent prompt and skills discovery section.
|
|
190
|
+
Uses len(text) / 4 as approximation.
|
|
191
|
+
"""
|
|
192
|
+
framework_sections = [
|
|
193
|
+
s
|
|
194
|
+
for s in self._sections
|
|
195
|
+
if s.prerequisite_met and s.name not in ("Agent_Prompt", "Skills_Discovery_Section")
|
|
196
|
+
]
|
|
197
|
+
total_chars = sum(len(s.content) for s in framework_sections)
|
|
198
|
+
return int(total_chars / 4)
|
|
@@ -46,6 +46,7 @@ Version: 0.1.0
|
|
|
46
46
|
|
|
47
47
|
import logging
|
|
48
48
|
import re
|
|
49
|
+
import unicodedata
|
|
49
50
|
from datetime import datetime
|
|
50
51
|
from typing import Any
|
|
51
52
|
|
|
@@ -58,29 +59,34 @@ logger = logging.getLogger(__name__)
|
|
|
58
59
|
|
|
59
60
|
def _sanitize_for_redisearch(text: str) -> str:
|
|
60
61
|
"""
|
|
61
|
-
Sanitize text to avoid RediSearch syntax errors.
|
|
62
|
-
|
|
63
|
-
RediSearch
|
|
64
|
-
|
|
65
|
-
- / (path separator,
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
62
|
+
Sanitize text to avoid RediSearch syntax errors and non-ASCII payloads.
|
|
63
|
+
|
|
64
|
+
RediSearch rejects multi-byte UTF-8 sequences in many query contexts and
|
|
65
|
+
has special syntactic characters that must be removed:
|
|
66
|
+
- | (OR operator), / (path separator), @ (field prefix), : (field separator)
|
|
67
|
+
- ( ) (grouping), [ ] (range), { } (tag), " (phrase), ~ (fuzzy)
|
|
68
|
+
- * (wildcard), - (negation), ' (escape), \\ (escape)
|
|
69
|
+
|
|
70
|
+
Pipeline:
|
|
71
|
+
1. Normalize via NFKD to decompose accented characters
|
|
72
|
+
(e.g. ``é`` → ``e`` + combining acute accent).
|
|
73
|
+
2. Drop every combining mark and any character with ``ord >= 128``,
|
|
74
|
+
producing ASCII-only output (``résumé`` → ``resume``).
|
|
75
|
+
3. Replace RediSearch-special characters with spaces to preserve
|
|
76
|
+
word boundaries, then collapse runs of whitespace.
|
|
77
|
+
|
|
78
|
+
The transliteration step preserves the semantic intent of the search
|
|
79
|
+
text. Falling back to ``encode("ascii", "ignore")`` would have stripped
|
|
80
|
+
the accented characters entirely (``résumé`` → ``rsum``), which is much
|
|
81
|
+
less useful for keyword search.
|
|
78
82
|
"""
|
|
79
|
-
#
|
|
83
|
+
# 1. Decompose accented characters into base + combining marks.
|
|
84
|
+
decomposed = unicodedata.normalize("NFKD", text)
|
|
85
|
+
# 2. Drop combining marks and any residual non-ASCII characters.
|
|
86
|
+
ascii_only = "".join(c for c in decomposed if not unicodedata.combining(c) and ord(c) < 128)
|
|
87
|
+
# 3. Strip RediSearch special characters and collapse whitespace.
|
|
80
88
|
special_chars = r'[|/@:(){}\[\]"~*\-\'\\/]'
|
|
81
|
-
|
|
82
|
-
sanitized = re.sub(special_chars, " ", text)
|
|
83
|
-
# Collapse multiple spaces
|
|
89
|
+
sanitized = re.sub(special_chars, " ", ascii_only)
|
|
84
90
|
sanitized = re.sub(r"\s+", " ", sanitized)
|
|
85
91
|
return sanitized.strip()
|
|
86
92
|
|