From 5af3500e539caad1d1e6b6c9c85db5a4b6e309c9 Mon Sep 17 00:00:00 2001 From: xxsc0529 Date: Wed, 11 Mar 2026 10:45:17 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9Aadd=20oceanbase=20vector=20backend?= =?UTF-8?q?=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Made-with: Cursor --- .github/workflows/_build.yml | 38 +- .github/workflows/build-docker-image.yml | 4 +- .github/workflows/release-vikingbot-first.yml | 4 +- .github/workflows/release.yml | 8 +- .gitignore | 2 +- Cargo.lock | 3232 +++++++++++++++++ Dockerfile | 20 +- Makefile | 25 +- README.md | 8 +- README_CN.md | 4 +- bot/vikingbot/agent/context.py | 8 +- bot/vikingbot/agent/loop.py | 29 +- bot/vikingbot/agent/memory.py | 32 +- bot/vikingbot/channels/chat.py | 5 +- bot/vikingbot/channels/feishu.py | 57 +- bot/vikingbot/channels/single_turn.py | 5 +- bot/vikingbot/cli/commands.py | 41 +- bot/vikingbot/config/loader.py | 15 +- bot/vikingbot/config/schema.py | 17 +- bot/vikingbot/integrations/langfuse.py | 114 +- bot/vikingbot/openviking_mount/ov_server.py | 2 +- bot/vikingbot/providers/litellm_provider.py | 141 +- bot/vikingbot/sandbox/manager.py | 4 +- bot/vikingbot/session/manager.py | 4 +- build_support/__init__.py | 1 + build_support/x86_profiles.py | 64 + crates/ov_cli/Cargo.toml | 2 +- crates/ov_cli/src/client.rs | 102 + crates/ov_cli/src/commands/chat.rs | 20 +- crates/ov_cli/src/commands/content.rs | 33 + crates/ov_cli/src/commands/observer.rs | 20 + crates/ov_cli/src/commands/resources.rs | 2 + crates/ov_cli/src/commands/system.rs | 30 +- crates/ov_cli/src/main.rs | 67 +- crates/ov_cli/src/tui/app.rs | 144 + crates/ov_cli/src/tui/event.rs | 51 +- crates/ov_cli/src/tui/mod.rs | 4 + crates/ov_cli/src/tui/tree.rs | 37 +- crates/ov_cli/src/tui/ui.rs | 239 +- docs/design/multi-tenant-design.md | 2 +- docs/design/openclaw-integration.md | 354 ++ docs/design/operation_telemetry.md | 520 +++ docs/en/api/02-resources.md | 43 + docs/en/api/05-sessions.md | 73 +- docs/en/concepts/05-storage.md | 1 + docs/en/concepts/07-retrieval.md | 1 + docs/en/concepts/09-transaction.md | 363 ++ docs/en/faq/faq.md | 1 + docs/en/guides/01-configuration.md | 125 +- docs/en/guides/06-mcp-integration.md | 230 ++ docs/en/guides/06-oceanbase-integration.md | 274 ++ docs/images/wechat-group-qrcode.png | Bin 1886580 -> 1068829 bytes docs/zh/api/02-resources.md | 43 + docs/zh/api/05-sessions.md | 73 +- docs/zh/concepts/05-storage.md | 1 + docs/zh/concepts/07-retrieval.md | 1 + docs/zh/concepts/09-transaction.md | 405 ++- docs/zh/faq/faq.md | 1 + docs/zh/guides/01-configuration.md | 87 +- docs/zh/guides/06-mcp-integration.md | 230 ++ docs/zh/guides/06-oceanbase-integration.md | 274 ++ examples/mcp-query/server.py | 40 +- examples/{ => misc}/memory_demo.py | 0 .../openclaw-memory-plugin/INSTALL-AGENT.md | 30 +- examples/openclaw-memory-plugin/INSTALL-ZH.md | 124 +- examples/openclaw-memory-plugin/INSTALL.md | 720 +--- examples/openclaw-memory-plugin/README.md | 456 ++- examples/openclaw-memory-plugin/client.ts | 39 +- examples/openclaw-memory-plugin/index.ts | 237 +- examples/openclaw-memory-plugin/install.ps1 | 97 +- examples/openclaw-memory-plugin/install.sh | 39 +- .../setup-helper/cli.js | 970 ----- .../setup-helper/install.js | 810 +++++ .../setup-helper/package.json | 21 +- examples/opencode-memory-plugin/.gitignore | 5 + examples/opencode-memory-plugin/INSTALL-ZH.md | 236 ++ examples/opencode-memory-plugin/README.md | 196 + .../openviking-config.example.json | 10 + .../openviking-memory.ts | 1878 ++++++++++ examples/opencode/plugin/README.md | 4 +- examples/opencode/plugin/index.mjs | 64 +- .../opencode/plugin/openviking-context.ts | 60 - examples/opencode/plugin/package.json | 2 +- .../plugin/skills/openviking/SKILL.md | 55 +- examples/ov.conf.example | 10 + examples/watch_resource_example.py | 151 + openviking/agfs_manager.py | 15 + openviking/async_client.py | 28 +- openviking/client/local.py | 138 +- openviking/client/session.py | 5 +- openviking/console/app.py | 73 + openviking/console/bootstrap.py | 2 +- openviking/core/building_tree.py | 1 + openviking/core/context.py | 4 + openviking/core/directories.py | 2 +- openviking/eval/ragas/__init__.py | 17 +- openviking/models/embedder/__init__.py | 4 + openviking/models/embedder/base.py | 279 +- openviking/models/embedder/jina_embedders.py | 61 +- .../models/embedder/openai_embedders.py | 266 +- .../models/embedder/vikingdb_embedders.py | 12 +- .../models/embedder/volcengine_embedders.py | 150 +- .../models/embedder/voyage_embedders.py | 118 + openviking/models/vlm/backends/litellm_vlm.py | 10 +- openviking/models/vlm/backends/openai_vlm.py | 26 +- .../models/vlm/backends/volcengine_vlm.py | 16 +- openviking/models/vlm/base.py | 17 + openviking/parse/directory_scan.py | 6 +- openviking/parse/parsers/constants.py | 1 + openviking/parse/parsers/excel.py | 95 +- openviking/parse/parsers/html.py | 100 +- openviking/parse/parsers/legacy_doc.py | 355 ++ openviking/parse/parsers/upload_utils.py | 1 + openviking/parse/registry.py | 2 + openviking/parse/tree_builder.py | 192 +- openviking/resource/__init__.py | 7 + openviking/resource/watch_manager.py | 717 ++++ openviking/resource/watch_scheduler.py | 350 ++ openviking/retrieve/hierarchical_retriever.py | 177 +- openviking/retrieve/retrieval_stats.py | 165 + openviking/server/app.py | 5 +- openviking/server/auth.py | 46 +- openviking/server/models.py | 13 +- openviking/server/routers/content.py | 155 +- openviking/server/routers/debug.py | 80 +- openviking/server/routers/observer.py | 18 +- openviking/server/routers/resources.py | 95 +- openviking/server/routers/search.py | 73 +- openviking/server/routers/sessions.py | 56 +- openviking/server/routers/system.py | 42 +- openviking/server/telemetry.py | 33 + openviking/service/core.py | 86 +- openviking/service/debug_service.py | 36 +- openviking/service/fs_service.py | 5 + openviking/service/resource_service.py | 326 +- openviking/service/search_service.py | 6 +- openviking/session/__init__.py | 9 + openviking/session/compressor.py | 417 ++- openviking/session/memory_archiver.py | 328 ++ openviking/session/memory_deduplicator.py | 64 +- openviking/session/memory_extractor.py | 63 +- openviking/session/session.py | 140 +- openviking/storage/__init__.py | 3 +- openviking/storage/collection_schemas.py | 253 +- openviking/storage/errors.py | 12 + openviking/storage/local_fs.py | 8 +- openviking/storage/observers/__init__.py | 6 +- openviking/storage/observers/lock_observer.py | 71 + .../storage/observers/retrieval_observer.py | 99 + .../storage/observers/transaction_observer.py | 222 -- openviking/storage/queuefs/__init__.py | 2 + openviking/storage/queuefs/embedding_msg.py | 16 +- .../queuefs/embedding_msg_converter.py | 2 + openviking/storage/queuefs/embedding_queue.py | 1 + .../storage/queuefs/embedding_tracker.py | 129 + openviking/storage/queuefs/named_queue.py | 32 +- openviking/storage/queuefs/queue_manager.py | 43 +- openviking/storage/queuefs/semantic_dag.py | 416 ++- openviking/storage/queuefs/semantic_msg.py | 24 +- .../storage/queuefs/semantic_processor.py | 878 ++++- openviking/storage/transaction/__init__.py | 35 +- .../storage/transaction/lock_context.py | 68 + openviking/storage/transaction/lock_handle.py | 37 + .../storage/transaction/lock_manager.py | 263 ++ openviking/storage/transaction/path_lock.py | 591 +-- openviking/storage/transaction/redo_log.py | 76 + .../transaction/transaction_manager.py | 374 -- .../storage/transaction/transaction_record.py | 122 - .../storage/vectordb/engine/__init__.py | 176 + .../vectordb/service/server_fastapi.py | 98 +- .../storage/vectordb/store/bytes_row.py | 3 + .../storage/vectordb_adapters/__init__.py | 2 + .../storage/vectordb_adapters/factory.py | 2 + .../vectordb_adapters/oceanbase_adapter.py | 556 +++ openviking/storage/viking_fs.py | 244 +- .../storage/viking_vector_index_backend.py | 652 +++- openviking/storage/vikingdb_manager.py | 348 +- openviking/sync_client.py | 32 +- openviking/telemetry/__init__.py | 24 + openviking/telemetry/backends/__init__.py | 7 + openviking/telemetry/backends/memory.py | 12 + openviking/telemetry/context.py | 35 + openviking/telemetry/execution.py | 115 + openviking/telemetry/operation.py | 244 ++ openviking/telemetry/registry.py | 36 + openviking/telemetry/request.py | 49 + openviking/telemetry/resource_summary.py | 132 + openviking/telemetry/runtime.py | 79 + openviking/telemetry/snapshot.py | 7 + openviking/utils/agfs_utils.py | 4 + openviking/utils/embedding_utils.py | 147 +- openviking/utils/process_lock.py | 102 + openviking/utils/resource_processor.py | 106 +- openviking/utils/skill_processor.py | 21 +- openviking/utils/summarizer.py | 32 +- openviking_cli/client/base.py | 11 +- openviking_cli/client/http.py | 75 +- openviking_cli/client/sync_http.py | 29 +- openviking_cli/exceptions.py | 8 + openviking_cli/session/user_id.py | 2 +- .../utils/config/embedding_config.py | 143 +- .../utils/config/open_viking_config.py | 8 +- openviking_cli/utils/config/parser_config.py | 26 + openviking_cli/utils/config/storage_config.py | 12 +- .../utils/config/transaction_config.py | 32 + .../utils/config/vectordb_config.py | 31 +- openviking_cli/utils/config/vlm_config.py | 17 +- openviking_cli/utils/rerank.py | 18 +- pyproject.toml | 25 +- setup.py | 29 +- src/CMakeLists.txt | 369 +- src/cpu_feature_probe.cpp | 118 + src/pybind11_interface.cpp | 8 +- tests/agfs/test_fs_binding.py | 9 +- tests/agfs/test_fs_binding_s3.py | 6 +- tests/agfs/test_fs_local.py | 5 +- tests/agfs/test_fs_s3.py | 8 +- tests/cli/test_user_identifier.py | 32 + tests/client/test_file_operations.py | 6 +- tests/client/test_import_export.py | 2 + tests/client/test_resource_management.py | 95 +- tests/client/test_windows_path_handling.py | 162 + tests/engine/CMakeLists.txt | 4 + tests/integration/test_add_resource_index.py | 34 +- tests/integration/test_full_workflow.py | 18 +- tests/integration/test_watch_e2e.py | 495 +++ tests/misc/test_config_validation.py | 44 + tests/misc/test_embedding_input_type.py | 283 ++ tests/misc/test_process_lock.py | 61 + tests/misc/test_resource_processor_mv.py | 85 + tests/misc/test_semantic_config.py | 82 + tests/misc/test_vectordb_engine_loader.py | 120 + tests/misc/test_vikingdb_observer.py | 16 +- tests/misc/test_vikingfs_uri_guard.py | 106 + tests/misc/test_x86_profiles.py | 17 + .../models/test_embedding_telemetry_usage.py | 104 + tests/models/test_vlm_strip_think_tags.py | 85 + tests/parse/test_url_filename_preservation.py | 120 + tests/resource/__init__.py | 3 + tests/resource/test_watch_manager.py | 689 ++++ tests/resource/test_watch_scheduler.py | 27 + .../test_hierarchical_retriever_rerank.py | 268 ++ tests/server/conftest.py | 52 +- tests/server/test_api_content.py | 42 + tests/server/test_api_filesystem.py | 45 +- tests/server/test_api_resources.py | 104 +- tests/server/test_api_search.py | 88 + tests/server/test_api_sessions.py | 50 +- tests/server/test_auth.py | 277 +- tests/server/test_http_client_sdk.py | 34 + tests/service/test_resource_service_watch.py | 482 +++ tests/service/test_watch_recovery.py | 612 ++++ tests/session/test_memory_dedup_actions.py | 259 +- .../session/test_memory_extractor_language.py | 28 + .../test_memory_extractor_response_types.py | 77 + tests/session/test_session_commit.py | 6 +- .../test_session_compressor_vikingdb.py | 6 +- tests/storage/test_collection_schemas.py | 4 +- tests/storage/test_semantic_dag_skip_files.py | 154 + tests/storage/test_semantic_dag_stats.py | 43 +- tests/telemetry/test_execution.py | 98 + tests/telemetry/test_layering_rules.py | 30 + tests/telemetry/test_resource_summary.py | 58 + tests/test_session_task_tracking.py | 91 + tests/test_telemetry_runtime.py | 307 ++ tests/transaction/__init__.py | 0 tests/transaction/conftest.py | 139 + tests/transaction/test_concurrent_lock.py | 103 + tests/transaction/test_e2e.py | 125 + tests/transaction/test_lock_context.py | 85 + tests/transaction/test_lock_manager.py | 88 + tests/transaction/test_path_lock.py | 336 ++ tests/transaction/test_redo_log.py | 78 + tests/unit/retrieve/test_retrieval_stats.py | 175 + tests/unit/session/test_deduplicator_uri.py | 125 + tests/unit/session/test_memory_archiver.py | 423 +++ tests/unit/test_embedding_config_voyage.py | 52 + tests/unit/test_extra_headers_embedding.py | 146 + tests/unit/test_extra_headers_vlm.py | 221 ++ tests/unit/test_jina_embedder.py | 25 +- tests/unit/test_ollama_embedding_factory.py | 174 + tests/unit/test_openai_embedder.py | 299 ++ tests/unit/test_openai_embedder_chunking.py | 532 +++ tests/unit/test_skill_processor_none.py | 18 + tests/unit/test_voyage_embedder.py | 152 + .../tool_skill/test_tool_skill_calibration.py | 2 +- .../test_tool_skill_memory_guardrails.py | 4 - tests/utils/mock_context.py | 29 + tests/vectordb/test_oceanbase_live.py | 542 +++ third_party/agfs/agfs-server/Makefile | 48 +- .../pkg/plugins/queuefs/backend.go | 31 +- .../pkg/plugins/queuefs/db_backend.go | 6 + .../pkg/plugins/queuefs/queuefs.go | 22 +- .../pkg/plugins/queuefs/sqlite_backend.go | 321 ++ uv.lock | 217 +- 295 files changed, 32878 insertions(+), 5081 deletions(-) create mode 100644 Cargo.lock create mode 100644 build_support/__init__.py create mode 100644 build_support/x86_profiles.py create mode 100644 docs/design/openclaw-integration.md create mode 100644 docs/design/operation_telemetry.md create mode 100644 docs/en/concepts/09-transaction.md create mode 100644 docs/en/guides/06-mcp-integration.md create mode 100644 docs/en/guides/06-oceanbase-integration.md create mode 100644 docs/zh/guides/06-mcp-integration.md create mode 100644 docs/zh/guides/06-oceanbase-integration.md rename examples/{ => misc}/memory_demo.py (100%) mode change 100644 => 100755 examples/openclaw-memory-plugin/install.sh delete mode 100755 examples/openclaw-memory-plugin/setup-helper/cli.js create mode 100644 examples/openclaw-memory-plugin/setup-helper/install.js create mode 100644 examples/opencode-memory-plugin/.gitignore create mode 100644 examples/opencode-memory-plugin/INSTALL-ZH.md create mode 100644 examples/opencode-memory-plugin/README.md create mode 100644 examples/opencode-memory-plugin/openviking-config.example.json create mode 100644 examples/opencode-memory-plugin/openviking-memory.ts delete mode 100644 examples/opencode/plugin/openviking-context.ts create mode 100644 examples/watch_resource_example.py create mode 100644 openviking/models/embedder/voyage_embedders.py create mode 100644 openviking/parse/parsers/legacy_doc.py create mode 100644 openviking/resource/__init__.py create mode 100644 openviking/resource/watch_manager.py create mode 100644 openviking/resource/watch_scheduler.py create mode 100644 openviking/retrieve/retrieval_stats.py create mode 100644 openviking/server/telemetry.py create mode 100644 openviking/session/memory_archiver.py create mode 100644 openviking/storage/observers/lock_observer.py create mode 100644 openviking/storage/observers/retrieval_observer.py delete mode 100644 openviking/storage/observers/transaction_observer.py create mode 100644 openviking/storage/queuefs/embedding_tracker.py create mode 100644 openviking/storage/transaction/lock_context.py create mode 100644 openviking/storage/transaction/lock_handle.py create mode 100644 openviking/storage/transaction/lock_manager.py create mode 100644 openviking/storage/transaction/redo_log.py delete mode 100644 openviking/storage/transaction/transaction_manager.py delete mode 100644 openviking/storage/transaction/transaction_record.py create mode 100644 openviking/storage/vectordb/engine/__init__.py create mode 100644 openviking/storage/vectordb_adapters/oceanbase_adapter.py create mode 100644 openviking/telemetry/__init__.py create mode 100644 openviking/telemetry/backends/__init__.py create mode 100644 openviking/telemetry/backends/memory.py create mode 100644 openviking/telemetry/context.py create mode 100644 openviking/telemetry/execution.py create mode 100644 openviking/telemetry/operation.py create mode 100644 openviking/telemetry/registry.py create mode 100644 openviking/telemetry/request.py create mode 100644 openviking/telemetry/resource_summary.py create mode 100644 openviking/telemetry/runtime.py create mode 100644 openviking/telemetry/snapshot.py create mode 100644 openviking/utils/process_lock.py create mode 100644 openviking_cli/utils/config/transaction_config.py create mode 100644 src/cpu_feature_probe.cpp create mode 100644 tests/cli/test_user_identifier.py create mode 100644 tests/client/test_windows_path_handling.py create mode 100644 tests/integration/test_watch_e2e.py create mode 100644 tests/misc/test_embedding_input_type.py create mode 100644 tests/misc/test_process_lock.py create mode 100644 tests/misc/test_resource_processor_mv.py create mode 100644 tests/misc/test_semantic_config.py create mode 100644 tests/misc/test_vectordb_engine_loader.py create mode 100644 tests/misc/test_vikingfs_uri_guard.py create mode 100644 tests/misc/test_x86_profiles.py create mode 100644 tests/models/test_embedding_telemetry_usage.py create mode 100644 tests/models/test_vlm_strip_think_tags.py create mode 100644 tests/parse/test_url_filename_preservation.py create mode 100644 tests/resource/__init__.py create mode 100644 tests/resource/test_watch_manager.py create mode 100644 tests/resource/test_watch_scheduler.py create mode 100644 tests/retrieve/test_hierarchical_retriever_rerank.py create mode 100644 tests/service/test_resource_service_watch.py create mode 100644 tests/service/test_watch_recovery.py create mode 100644 tests/session/test_memory_extractor_response_types.py create mode 100644 tests/storage/test_semantic_dag_skip_files.py create mode 100644 tests/telemetry/test_execution.py create mode 100644 tests/telemetry/test_layering_rules.py create mode 100644 tests/telemetry/test_resource_summary.py create mode 100644 tests/test_telemetry_runtime.py create mode 100644 tests/transaction/__init__.py create mode 100644 tests/transaction/conftest.py create mode 100644 tests/transaction/test_concurrent_lock.py create mode 100644 tests/transaction/test_e2e.py create mode 100644 tests/transaction/test_lock_context.py create mode 100644 tests/transaction/test_lock_manager.py create mode 100644 tests/transaction/test_path_lock.py create mode 100644 tests/transaction/test_redo_log.py create mode 100644 tests/unit/retrieve/test_retrieval_stats.py create mode 100644 tests/unit/session/test_deduplicator_uri.py create mode 100644 tests/unit/session/test_memory_archiver.py create mode 100644 tests/unit/test_embedding_config_voyage.py create mode 100644 tests/unit/test_extra_headers_embedding.py create mode 100644 tests/unit/test_extra_headers_vlm.py create mode 100644 tests/unit/test_ollama_embedding_factory.py create mode 100644 tests/unit/test_openai_embedder.py create mode 100644 tests/unit/test_openai_embedder_chunking.py create mode 100644 tests/unit/test_voyage_embedder.py create mode 100644 tests/utils/mock_context.py create mode 100644 tests/vectordb/test_oceanbase_live.py create mode 100644 third_party/agfs/agfs-server/pkg/plugins/queuefs/sqlite_backend.go diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml index fc09bb90..89a69ef4 100644 --- a/.github/workflows/_build.yml +++ b/.github/workflows/_build.yml @@ -12,7 +12,7 @@ on: description: 'JSON string of Python versions' required: false type: string - default: '["3.10", "3.11", "3.12", "3.13"]' + default: '["3.10", "3.11", "3.12", "3.13", "3.14"]' build_sdist: description: 'Whether to build source distribution' required: false @@ -42,7 +42,7 @@ on: python_json: description: 'JSON string of Python versions' required: false - default: '["3.10", "3.11", "3.12", "3.13"]' + default: '["3.10", "3.11", "3.12", "3.13", "3.14"]' jobs: build-sdist: @@ -170,6 +170,7 @@ jobs: "3.11") PYTHON_FULL="3.11.8" ;; "3.12") PYTHON_FULL="3.12.2" ;; "3.13") PYTHON_FULL="3.13.2" ;; + "3.14") PYTHON_FULL="3.14.3" ;; *) echo "Error: Unknown python version $PYTHON_VERSION" exit 1 @@ -454,21 +455,22 @@ jobs: shell: bash run: | python - <<'PY' + import importlib import importlib.util - import pathlib - import site - - candidates = [] - for base in site.getsitepackages(): - candidates.extend(pathlib.Path(base).glob("openviking/storage/vectordb/engine*.so")) - - if not candidates: - raise SystemExit("openviking storage engine extension was not installed") - - engine_path = candidates[0] - spec = importlib.util.spec_from_file_location("engine", engine_path) - module = importlib.util.module_from_spec(spec) - assert spec.loader is not None - spec.loader.exec_module(module) - print(f"Loaded native extension from {engine_path}") + + import openviking.storage.vectordb.engine as engine + + native_spec = importlib.util.find_spec("openviking.storage.vectordb.engine._native") + if native_spec is None or native_spec.origin is None: + raise SystemExit("openviking storage native backend extension was not installed") + + native_module = importlib.import_module("openviking.storage.vectordb.engine._native") + if engine.ENGINE_VARIANT != "native": + raise SystemExit( + f"expected native engine variant on macOS arm64 wheel, got {engine.ENGINE_VARIANT}" + ) + + print(f"Loaded runtime engine variant {engine.ENGINE_VARIANT}") + print(f"Loaded native extension from {native_spec.origin}") + print(f"Imported backend module {native_module.__name__}") PY diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index b8677984..c36802d7 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -38,7 +38,7 @@ jobs: - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} @@ -50,7 +50,7 @@ jobs: - name: Build and push Docker image id: push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/release-vikingbot-first.yml b/.github/workflows/release-vikingbot-first.yml index fd917dcc..9f78c202 100644 --- a/.github/workflows/release-vikingbot-first.yml +++ b/.github/workflows/release-vikingbot-first.yml @@ -10,9 +10,9 @@ jobs: run: working-directory: bot steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.11' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9d842916..89b5f800 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ on: description: 'JSON string of Python versions (Manual only)' required: false type: string - default: '["3.10", "3.11", "3.12", "3.13"]' + default: '["3.10", "3.11", "3.12", "3.13", "3.14"]' permissions: contents: write @@ -48,7 +48,7 @@ jobs: uses: ./.github/workflows/_build.yml with: os_json: ${{ inputs.os_json || '["ubuntu-24.04", "ubuntu-24.04-arm", "macos-14", "macos-15-intel", "windows-latest"]' }} - python_json: ${{ inputs.python_json || '["3.10", "3.11", "3.12", "3.13"]' }} + python_json: ${{ inputs.python_json || '["3.10", "3.11", "3.12", "3.13", "3.14"]' }} build_sdist: ${{ github.event_name == 'release' || inputs.build_sdist != false }} build_wheels: ${{ github.event_name == 'release' || inputs.build_wheels != false }} @@ -182,7 +182,7 @@ jobs: - name: Extract metadata (tags, labels) for Docker id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: ghcr.io/${{ github.repository }} @@ -193,7 +193,7 @@ jobs: uses: docker/setup-buildx-action@v4 - name: Build and push Docker image - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.gitignore b/.gitignore index e4953a7a..e050e2c8 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,6 @@ openviking.egg-info/ data/ # Rust -Cargo.lock target/ **/*.rs.bk *.pdb @@ -142,6 +141,7 @@ celerybeat-schedule # mkdocs documentation /site +docs/superpowers/ # mypy .mypy_cache/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..7593e6ae --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3232 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "bzip2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" +dependencies = [ + "bzip2-sys", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.13+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "castaway" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +dependencies = [ + "rustversion", +] + +[[package]] +name = "cc" +version = "1.2.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" + +[[package]] +name = "clipboard-win" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + +[[package]] +name = "compact_str" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "coolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980c2afde4af43d6a05c5be738f9eae595cff86dce1f38f88b95058a98c027f3" +dependencies = [ + "crossterm 0.29.0", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crokey" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04a63daf06a168535c74ab97cdba3ed4fa5d4f32cb36e437dcceb83d66854b7c" +dependencies = [ + "crokey-proc_macros", + "crossterm 0.29.0", + "once_cell", + "serde", + "strict", +] + +[[package]] +name = "crokey-proc_macros" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "847f11a14855fc490bd5d059821895c53e77eeb3c2b73ee3dded7ce77c93b231" +dependencies = [ + "crossterm 0.29.0", + "proc-macro2", + "quote", + "strict", + "syn", +] + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix 0.38.44", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +dependencies = [ + "bitflags", + "crossterm_winapi", + "derive_more", + "document-features", + "mio", + "parking_lot", + "rustix 1.1.4", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deflate64" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2" + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "error-code" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fd-lock" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" +dependencies = [ + "cfg-if", + "rustix 1.1.4", + "windows-sys 0.59.0", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "indoc" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instability" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357b7205c6cd18dd2c86ed312d1e70add149aea98e7ef72b9fdf0270e555c11d" +dependencies = [ + "darling", + "indoc", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy-regex" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bae91019476d3ec7147de9aa291cadb6d870abf2f3015d2da73a90325ac1496" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de9c1e1439d8b7b3061b2d209809f447ca33241733d9a3c01eabf2dc8d94358" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" + +[[package]] +name = "libredox" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +dependencies = [ + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "machine-uid" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d7217d573cdb141d6da43113b098172e057d39915d79c4bdedbc3aacd46bd96" +dependencies = [ + "libc", + "windows-registry", + "windows-sys 0.61.2", +] + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimad" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8b688969b16915f3ecadc7829d5b7779dee4977e503f767f34136803d5c06f" +dependencies = [ + "once_cell", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases 0.1.1", + "libc", +] + +[[package]] +name = "num-conv" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ov_cli" +version = "0.2.6" +dependencies = [ + "anyhow", + "clap", + "colored", + "crossterm 0.28.1", + "dirs", + "futures", + "machine-uid", + "mime_guess", + "ratatui", + "reqwest", + "rustyline", + "serde", + "serde_json", + "tempfile", + "termimad", + "thiserror 1.0.69", + "tokio", + "unicode-width 0.1.14", + "url", + "uuid", + "walkdir", + "zip", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases 0.2.1", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases 0.2.1", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "ratatui" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" +dependencies = [ + "bitflags", + "cassowary", + "compact_str", + "crossterm 0.28.1", + "indoc", + "instability", + "itertools", + "lru", + "paste", + "strum", + "unicode-segmentation", + "unicode-truncate", + "unicode-width 0.2.0", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.12.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rustyline" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63" +dependencies = [ + "bitflags", + "cfg-if", + "clipboard-win", + "fd-lock", + "home", + "libc", + "log", + "memchr", + "nix", + "radix_trie", + "unicode-segmentation", + "unicode-width 0.1.14", + "utf8parse", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strict" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f42444fea5b87a39db4218d9422087e66a85d0e7a0963a439b07bcdf91804006" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tempfile" +version = "3.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" +dependencies = [ + "fastrand", + "getrandom 0.4.2", + "once_cell", + "rustix 1.1.4", + "windows-sys 0.61.2", +] + +[[package]] +name = "termimad" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "889a9370996b74cf46016ce35b96c248a9ac36d69aab1d112b3e09bc33affa49" +dependencies = [ + "coolor", + "crokey", + "crossbeam", + "lazy-regex", + "minimad", + "serde", + "thiserror 2.0.18", + "unicode-width 0.1.14", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-truncate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +dependencies = [ + "itertools", + "unicode-segmentation", + "unicode-width 0.1.14", +] + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" +dependencies = [ + "getrandom 0.4.2", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] +name = "web-sys" +version = "0.3.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zip" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "getrandom 0.3.4", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "sha1", + "thiserror 2.0.18", + "time", + "xz2", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zopfli" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" +dependencies = [ + "bumpalo", + "crc32fast", + "log", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Dockerfile b/Dockerfile index b69f865e..4c4c48b7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,13 +3,22 @@ # Stage 1: provide Go toolchain (required by setup.py -> build_agfs_artifacts -> make build) FROM golang:1.26-trixie AS go-toolchain -# Stage 2: build Python environment with uv (builds AGFS + C++ extension from source) +# Stage 2: provide Rust toolchain (required by setup.py -> build_ov_cli_artifact -> cargo build) +FROM rust:1.88-trixie AS rust-toolchain + +# Stage 3: build Python environment with uv (builds AGFS + Rust CLI + C++ extension from source) FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim AS py-builder # Reuse Go toolchain from stage 1 so setup.py can compile agfs-server in-place. COPY --from=go-toolchain /usr/local/go /usr/local/go -ENV PATH="/usr/local/go/bin:${PATH}" +# Reuse Rust toolchain from stage 2 so setup.py can compile ov CLI in-place. +COPY --from=rust-toolchain /usr/local/cargo /usr/local/cargo +COPY --from=rust-toolchain /usr/local/rustup /usr/local/rustup +ENV CARGO_HOME=/usr/local/cargo +ENV RUSTUP_HOME=/usr/local/rustup +ENV PATH="/usr/local/cargo/bin:/usr/local/go/bin:${PATH}" ARG OPENVIKING_VERSION=0.0.0 +ARG TARGETPLATFORM ENV SETUPTOOLS_SCM_PRETEND_VERSION_FOR_OPENVIKING=${OPENVIKING_VERSION} RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -24,17 +33,20 @@ ENV UV_NO_DEV=1 WORKDIR /app # Copy source required for setup.py artifact builds and native extension build. +COPY Cargo.toml Cargo.lock ./ COPY pyproject.toml uv.lock setup.py README.md ./ +COPY build_support/ build_support/ +COPY crates/ crates/ COPY openviking/ openviking/ COPY openviking_cli/ openviking_cli/ COPY src/ src/ COPY third_party/ third_party/ # Install project and dependencies (triggers setup.py artifact builds + build_extension). -RUN --mount=type=cache,target=/root/.cache/uv \ +RUN --mount=type=cache,target=/root/.cache/uv,id=uv-${TARGETPLATFORM} \ uv sync --no-editable -# Stage 3: runtime +# Stage 4: runtime FROM python:3.13-slim-trixie RUN apt-get update && apt-get install -y --no-install-recommends \ diff --git a/Makefile b/Makefile index 6f0ae1c4..55db0860 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ # Variables PYTHON ?= python3 -PIP ?= $(PYTHON) -m pip SETUP_PY := setup.py AGFS_SERVER_DIR := third_party/agfs/agfs-server OV_CLI_DIR := crates/ov_cli @@ -42,12 +41,18 @@ help: @echo " help - Show this help message" check-pip: - @$(PYTHON) -m pip --version > /dev/null 2>&1 || ( \ - echo "Error: pip not found for $(PYTHON)."; \ - echo "Try fixing your virtual environment by running:"; \ + @if command -v uv > /dev/null 2>&1 && uv pip --help > /dev/null 2>&1; then \ + echo " [OK] uv pip found"; \ + elif $(PYTHON) -m pip --version > /dev/null 2>&1; then \ + echo " [OK] pip found"; \ + else \ + echo "Error: Neither uv pip nor pip found for $(PYTHON)."; \ + echo "Try fixing your environment by running:"; \ + echo " uv sync # if using uv"; \ + echo " or"; \ echo " $(PYTHON) -m ensurepip --upgrade"; \ - exit 1 \ - ) + exit 1; \ + fi check-deps: @echo "Checking dependencies..." @@ -87,7 +92,13 @@ check-deps: build: check-deps check-pip @echo "Starting build process via setup.py..." $(PYTHON) $(SETUP_PY) build_ext --inplace - $(PIP) install -e . + @if command -v uv > /dev/null 2>&1 && uv pip --help > /dev/null 2>&1; then \ + echo " [OK] uv pip found, use uv pip to install..."; \ + uv pip install -e .; \ + else \ + echo " [OK] pip found, use pip to install..."; \ + $(PYTHON) -m pip install -e .; \ + fi @echo "Build completed successfully." clean: diff --git a/README.md b/README.md index 70addef2..3841d60b 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ English / [中文](README_CN.md) 📱 Lark Group · WeChat · Discord · X +volcengine%2FOpenViking | Trendshift + --- @@ -97,7 +99,7 @@ OpenViking supports three VLM providers: | Provider | Description | Get API Key | |----------|-------------|-------------| -| `volcengine` | Volcengine Doubao Models | [Volcengine Console](https://console.volcengine.com/ark) | +| `volcengine` | Volcengine Doubao Models | [Volcengine Console](https://console.volcengine.com/ark/region:ark+cn-beijing/overview?briefPage=0&briefType=introduce&type=new&utm_content=OpenViking&utm_medium=devrel&utm_source=OWO&utm_term=OpenViking) | | `openai` | OpenAI Official API | [OpenAI Platform](https://platform.openai.com) | | `litellm` | Unified access to various third-party models (Anthropic, DeepSeek, Gemini, vLLM, Ollama, etc.) | See [LiteLLM Providers](https://docs.litellm.ai/docs/providers) | @@ -123,7 +125,7 @@ Volcengine supports both model names and endpoint IDs. Using model names is reco } ``` -You can also use endpoint IDs (found in [Volcengine ARK Console](https://console.volcengine.com/ark)): +You can also use endpoint IDs (found in [Volcengine ARK Console](https://console.volcengine.com/ark/region:ark+cn-beijing/overview?briefPage=0&briefType=introduce&type=new&utm_content=OpenViking&utm_medium=devrel&utm_source=OWO&utm_term=OpenViking): ```json { @@ -489,6 +491,8 @@ After integrating OpenViking: 👉 **[View: OpenClaw Memory Plugin](examples/openclaw-memory-plugin/README.md)** +👉 **[View: OpenCode Memory Plugin Example](examples/opencode-memory-plugin/README.md)** + -- ## Core Concepts diff --git a/README_CN.md b/README_CN.md index 11670859..8f33242d 100644 --- a/README_CN.md +++ b/README_CN.md @@ -97,7 +97,7 @@ OpenViking 支持三种 VLM 提供商: | 提供商 | 描述 | 获取 API Key | |----------|-------------|-------------| -| `volcengine` | 火山引擎豆包模型 | [Volcengine 控制台](https://console.volcengine.com/ark) | +| `volcengine` | 火山引擎豆包模型 | [Volcengine 控制台](https://console.volcengine.com/ark/region:ark+cn-beijing/overview?briefPage=0&briefType=introduce&type=new&utm_content=OpenViking&utm_medium=devrel&utm_source=OWO&utm_term=OpenViking) | | `openai` | OpenAI 官方 API | [OpenAI 平台](https://platform.openai.com) | | `litellm` | 统一调用多种第三方模型 (Anthropic, DeepSeek, Gemini, vLLM, Ollama 等) | 参见 [LiteLLM 提供商](https://docs.litellm.ai/docs/providers) | @@ -487,6 +487,8 @@ ov chat 👉 **[查看:OpenClaw 记忆插件](examples/openclaw-memory-plugin/README.md)** +👉 **[查看:OpenCode 记忆插件示例](examples/opencode-memory-plugin/README.md)** + ## VikingBot 部署详情 OpenViking 有一个类似 nanobot 的机器人用于交互工作,现已可用。 diff --git a/bot/vikingbot/agent/context.py b/bot/vikingbot/agent/context.py index 0af9b0aa..9fb01691 100644 --- a/bot/vikingbot/agent/context.py +++ b/bot/vikingbot/agent/context.py @@ -272,14 +272,14 @@ async def build_messages( if not self._eval: messages.extend(history) + # User + user_info = await self._build_user_memory(session_key, current_message, history) + messages.append({"role": "user", "content": user_info}) + # Current message (with optional image attachments) user_content = self._build_user_content(current_message, media) messages.append({"role": "user", "content": user_content}) - # User - user_info = await self._build_user_memory(session_key, current_message, history) - messages.append({"role": "system", "content": user_info}) - return messages def _build_user_content(self, text: str, media: list[str] | None) -> str | list[dict[str, Any]]: diff --git a/bot/vikingbot/agent/loop.py b/bot/vikingbot/agent/loop.py index b72dd98f..87d29d39 100644 --- a/bot/vikingbot/agent/loop.py +++ b/bot/vikingbot/agent/loop.py @@ -129,11 +129,6 @@ def __init__( self._running = False self._register_default_tools() - self._token_usage = { - "prompt_tokens": 0, - "completion_tokens": 0, - "total_tokens": 0, - } async def _publish_thinking_event( self, session_key: SessionKey, event_type: OutboundEventType, content: str @@ -221,7 +216,7 @@ async def _run_agent_loop( session_key: SessionKey, publish_events: bool = True, sender_id: str | None = None, - ) -> tuple[str | None, list[dict]]: + ) -> tuple[str | None, list[dict], dict[str, int]]: """ Run the core agent loop: call LLM, execute tools, repeat until done. @@ -236,6 +231,11 @@ async def _run_agent_loop( iteration = 0 final_content = None tools_used: list[dict] = [] + token_usage = { + "prompt_tokens": 0, + "completion_tokens": 0, + "total_tokens": 0, + } while iteration < self.max_iterations: iteration += 1 @@ -257,9 +257,9 @@ async def _run_agent_loop( ) if response.usage: cur_token = response.usage - self._token_usage["prompt_tokens"] += cur_token["prompt_tokens"] - self._token_usage["completion_tokens"] += cur_token["completion_tokens"] - self._token_usage["total_tokens"] += cur_token["total_tokens"] + token_usage["prompt_tokens"] += cur_token["prompt_tokens"] + token_usage["completion_tokens"] += cur_token["completion_tokens"] + token_usage["total_tokens"] += cur_token["total_tokens"] if publish_events and response.reasoning_content: await self.bus.publish_outbound( @@ -362,7 +362,7 @@ async def execute_single_tool(idx: int, tool_call): else: final_content = "I've completed processing but have no response to give." - return final_content, tools_used + return final_content, tools_used, token_usage @trace( name="process_message", @@ -489,7 +489,7 @@ async def check_long_running(): # logger.info(f"New messages: {messages}") # Run agent loop - final_content, tools_used = await self._run_agent_loop( + final_content, tools_used, token_usage = await self._run_agent_loop( messages=messages, session_key=session_key, publish_events=True, @@ -503,7 +503,8 @@ async def check_long_running(): # Save to session (include tool names so consolidation sees what happened) session.add_message("user", msg.content, sender_id=msg.sender_id) session.add_message( - "assistant", final_content, tools_used=tools_used if tools_used else None + "assistant", final_content, tools_used=tools_used if tools_used else None, token_usage=token_usage, + sender_id=msg.sender_id, ) await self.sessions.save(session) @@ -512,7 +513,7 @@ async def check_long_running(): session_key=msg.session_key, content=final_content, metadata=msg.metadata, - token_usage=self._token_usage, + token_usage=token_usage, time_cost=time_cost or {}, # Pass through for channel-specific needs (e.g. Slack thread_ts) ) @@ -541,7 +542,7 @@ async def _process_system_message(self, msg: InboundMessage) -> OutboundMessage ) # Run agent loop (no events published) - final_content, tools_used = await self._run_agent_loop( + final_content, tools_used, token_usage = await self._run_agent_loop( messages=messages, session_key=msg.session_key, publish_events=False, diff --git a/bot/vikingbot/agent/memory.py b/bot/vikingbot/agent/memory.py index e7817839..8e47adcd 100644 --- a/bot/vikingbot/agent/memory.py +++ b/bot/vikingbot/agent/memory.py @@ -48,21 +48,25 @@ def get_memory_context(self) -> str: return f"## Long-term Memory\n{long_term}" if long_term else "" async def get_viking_memory_context(self, current_message: str, workspace_id: str) -> str: - client = await VikingClient.create(agent_id=workspace_id) - admin_user_id = load_config().ov_server.admin_user_id - start = time.time() - result = await client.search_memory(current_message, user_id=admin_user_id, limit=3) - cost = round(time.time() - start, 2) - if not result: - logger.info(f"[USER_MEMORY]: search failed. cost {cost}") + try: + client = await VikingClient.create(agent_id=workspace_id) + admin_user_id = load_config().ov_server.admin_user_id + start = time.time() + result = await client.search_memory(current_message, user_id=admin_user_id, limit=3) + cost = round(time.time() - start, 2) + if not result: + logger.info(f"[USER_MEMORY]: search failed. cost {cost}") + return "" + user_memory = self._parse_viking_memory(result["user_memory"]) + agent_memory = self._parse_viking_memory(result["agent_memory"]) + logger.info(f"[USER_MEMORY]: search success. res: {user_memory[:100]}. cost {cost}") + return ( + f"### user memories:\n{user_memory}\n" + f"### agent memories:\n{agent_memory}" + ) + except Exception as e: + logger.error(f"[USER_MEMORY]: search failed. {e}") return "" - user_memory = self._parse_viking_memory(result["user_memory"]) - agent_memory = self._parse_viking_memory(result["agent_memory"]) - logger.info(f"[USER_MEMORY]: search success. res: {user_memory[:100]}. cost {cost}") - return ( - f"### user memories:\n{user_memory}\n" - f"### agent memories:\n{agent_memory}" - ) async def get_viking_user_profile(self, workspace_id: str, user_id: str) -> str: client = await VikingClient.create(agent_id=workspace_id) diff --git a/bot/vikingbot/channels/chat.py b/bot/vikingbot/channels/chat.py index 03ff0f70..fe7dc65c 100644 --- a/bot/vikingbot/channels/chat.py +++ b/bot/vikingbot/channels/chat.py @@ -48,11 +48,13 @@ def __init__( session_id: str = "default", markdown: bool = True, logs: bool = False, + sender: str | None = None, ): super().__init__(config, bus, workspace_path) self.session_id = session_id self.markdown = markdown self.logs = logs + self.sender = sender self._response_received = asyncio.Event() self._last_response: str | None = None @@ -149,13 +151,14 @@ def _exit_on_sigint(signum, frame): self._response_received.clear() self._last_response = None + sender_id = self.sender or "user" msg = InboundMessage( session_key=SessionKey( type="cli", channel_id=self.config.channel_id(), chat_id=self.session_id, ), - sender_id="user", + sender_id=sender_id, content=user_input, ) await self.bus.publish_inbound(msg) diff --git a/bot/vikingbot/channels/feishu.py b/bot/vikingbot/channels/feishu.py index 5c93c1b1..1a92fcec 100644 --- a/bot/vikingbot/channels/feishu.py +++ b/bot/vikingbot/channels/feishu.py @@ -45,7 +45,7 @@ GetMessageResourceRequest, P2ImMessageReceiveV1, ReplyMessageRequest, - ReplyMessageRequestBody, + ReplyMessageRequestBody ) FEISHU_AVAILABLE = True @@ -172,8 +172,9 @@ async def _download_feishu_image(self, image_key: str, message_id: str | None = # Handle failed response if not response.success(): + raw_detail = getattr(getattr(response, 'raw', None), 'content', response.msg) raise Exception( - f"Failed to download image: code={response.code}, msg={response.msg}, log_id={response.get_log_id()}" + f"Failed to download image: code={response.code}, msg={raw_detail}, log_id={response.get_log_id()}" ) # Read the image bytes from the response file @@ -658,10 +659,7 @@ async def _on_message(self, data: "P2ImMessageReceiveV1") -> None: chat_type = message.chat_type # "p2p" or "group" msg_type = message.message_type - # Add reaction to indicate "seen" - await self._add_reaction(message_id, "MeMeMe") - - # Parse message content and media + # Parse message content and media first to check mentions content = "" media = [] @@ -746,7 +744,54 @@ async def _on_message(self, data: "P2ImMessageReceiveV1") -> None: import re + # 检查是否@了机器人 + is_mentioned = False mention_pattern = re.compile(r"@_user_\d+") + bot_open_id = self.config.open_id + bot_app_id = self.config.app_id + + # 优先从message的mentions字段提取@信息(text和post类型都适用) + if hasattr(message, 'mentions') and message.mentions and bot_open_id: + for mention in message.mentions: + if hasattr(mention, 'id') and hasattr(mention.id, 'open_id'): + at_id = mention.id.open_id + if at_id == bot_open_id: + is_mentioned = True + break + continue + # 兼容其他可能的ID格式 + at_id = getattr(mention, 'id', '') or getattr(mention, 'user_id', '') + if at_id == f"app_{bot_app_id}" or at_id == bot_app_id: + is_mentioned = True + break + + # 话题群@检查逻辑 + should_process = True + if chat_type == "group": + chat_mode = await self._get_chat_mode(chat_id) + if chat_mode == "thread": + # 判断是否是话题的首条消息(root_id等于message_id说明是话题发起消息) + is_topic_starter = message.root_id == message.message_id or not message.root_id + + if self.config.thread_require_mention: + # 模式1:默认True,所有消息都需要@才处理 + if not is_mentioned: + logger.info(f"Skipping thread message: thread_require_mention is True and not mentioned") + should_process = False + else: + # 模式2:False,仅话题首条消息不需要@,后续回复需要@ + if not is_topic_starter and not is_mentioned: + logger.info(f"Skipping thread message: not topic starter and not mentioned") + should_process = False + + # 不需要处理的消息直接跳过 + if not should_process: + return + + # 确认需要处理后再添加"已读"表情 + await self._add_reaction(message_id, "MeMeMe") + + # 替换所有@占位符 content = mention_pattern.sub(f"@{sender_id}", content) # Forward to message bus diff --git a/bot/vikingbot/channels/single_turn.py b/bot/vikingbot/channels/single_turn.py index 333ccc33..7c1673b8 100644 --- a/bot/vikingbot/channels/single_turn.py +++ b/bot/vikingbot/channels/single_turn.py @@ -45,11 +45,13 @@ def __init__( session_id: str = "default", markdown: bool = True, eval: bool = False, + sender: str | None = None, ): super().__init__(config, bus, workspace_path) self.message = message self.session_id = session_id self.markdown = markdown + self.sender = sender self._response_received = asyncio.Event() self._last_response: str | None = None self._eval = eval @@ -59,13 +61,14 @@ async def start(self) -> None: self._running = True # Send the message + sender_id = self.sender or "user" msg = InboundMessage( session_key=SessionKey( type="cli", channel_id=self.config.channel_id(), chat_id=self.session_id, ), - sender_id="default", + sender_id=sender_id, content=self.message, ) await self.bus.publish_inbound(msg) diff --git a/bot/vikingbot/cli/commands.py b/bot/vikingbot/cli/commands.py index d380069d..119db4f4 100644 --- a/bot/vikingbot/cli/commands.py +++ b/bot/vikingbot/cli/commands.py @@ -234,6 +234,7 @@ def gateway( True, "--agent/--no-agent", help="Enable agent loop for OpenAPI/chat" ), verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"), + config_path: str = typer.Option(None, "--config", "-c", help="ov.conf path"), ): """Start the vikingbot gateway with OpenAPI chat enabled by default.""" @@ -243,7 +244,8 @@ def gateway( logging.basicConfig(level=logging.DEBUG) bus = MessageBus() - config = ensure_config() + path = Path(config_path).expanduser() if config_path is not None else None + config = ensure_config(path) _init_bot_data(config) session_manager = SessionManager(config.bot_data_path) @@ -507,6 +509,7 @@ def prepare_agent_channel( markdown: bool, logs: bool, eval: bool = False, + sender: str | None = None, ): """Prepare channel for agent command.""" from vikingbot.channels.chat import ChatChannel, ChatChannelConfig @@ -524,6 +527,7 @@ def prepare_agent_channel( session_id=session_id, markdown=markdown, eval=eval, + sender=sender, ) channels.add_channel(channel) else: @@ -536,6 +540,7 @@ def prepare_agent_channel( session_id=session_id, markdown=markdown, logs=logs, + sender=sender, ) channels.add_channel(channel) @@ -557,18 +562,12 @@ def chat( ), config_path: str = typer.Option( None, "--config", "-c", help="Path to ov.conf, default .openviking/ov.conf" - ) + ), + sender: str = typer.Option( + None, "--sender", help="Sender ID, same usage as feishu channel sender" + ), ): """Interact with the agent directly.""" - if message is not None: - # Single-turn mode: only show error logs - logger.remove() - logger.add(sys.stderr, level="ERROR") - elif logs: - logger.enable("vikingbot") - else: - logger.disable("vikingbot") - path = Path(config_path).expanduser() if config_path is not None else None bus = MessageBus() @@ -581,11 +580,29 @@ def chat( if session_id is None: session_id = get_or_create_machine_id() cron = prepare_cron(bus, quiet=is_single_turn) - channels = prepare_agent_channel(config, bus, message, session_id, markdown, logs, eval) + channels = prepare_agent_channel(config, bus, message, session_id, markdown, logs, eval, sender) agent_loop = prepare_agent_loop( config, bus, session_manager, cron, quiet=is_single_turn, eval=eval ) + logger.remove() + + log_file = get_data_dir() / f"vikingbot.debug.{os.getpid()}.log" + logger.add( + log_file, + level="DEBUG", + rotation="10 MB", + retention="7 days", + encoding="utf-8", + backtrace=True, + diagnose=True, + ) + + if logs: + logger.add(sys.stderr, level="DEBUG") + else: + logger.add(sys.stderr, level="ERROR") + async def run(): if is_single_turn: # Single-turn mode: run channels and agent, exit after response diff --git a/bot/vikingbot/config/loader.py b/bot/vikingbot/config/loader.py index f1bad266..e57c3879 100644 --- a/bot/vikingbot/config/loader.py +++ b/bot/vikingbot/config/loader.py @@ -53,7 +53,7 @@ def ensure_config(config_path: Path | None = None) -> Config: # Create default config with empty bot section default_config = Config() - save_config(default_config, config_path) + save_config(default_config, config_path, include_defaults=True) logger.info(f"[green]✓[/green] Created default config at {config_path}") config = load_config() @@ -131,6 +131,8 @@ def _merge_vlm_model_config(bot_data: dict, vlm_data: dict) -> None: bot_data["agents"]["provider"] = provider if provider else "" bot_data["agents"]["api_base"] = vlm_data.get("api_base", "") bot_data["agents"]["api_key"] = vlm_data.get("api_key", "") + if "extra_headers" in vlm_data and vlm_data["extra_headers"] is not None: + bot_data["agents"]["extra_headers"] = vlm_data["extra_headers"] def _merge_ov_server_config(bot_data: dict, ov_data: dict) -> None: @@ -143,19 +145,22 @@ def _merge_ov_server_config(bot_data: dict, ov_data: dict) -> None: bot_data["server_url"] = f"http://{host}:{port}" if "root_api_key" not in bot_data or not bot_data["root_api_key"]: bot_data["root_api_key"] = ov_data.get("root_api_key", "") - if "root_api_key" in ov_data and ov_data["root_api_key"]: + if "root_api_key" in bot_data and bot_data["root_api_key"]: bot_data["mode"] = "remote" else: bot_data["mode"] = "local" -def save_config(config: Config, config_path: Path | None = None) -> None: +def save_config( + config: Config, config_path: Path | None = None, include_defaults: bool = False +) -> None: """ Save configuration to ov.conf's bot field, preserving other sections. Args: config: Configuration to save. config_path: Optional path to ov.conf file. Uses default if not provided. + include_defaults: Whether to include default values in the saved config. """ path = config_path or get_config_path() path.parent.mkdir(parents=True, exist_ok=True) @@ -170,7 +175,7 @@ def save_config(config: Config, config_path: Path | None = None) -> None: pass # Update bot section - only save fields that were explicitly set - bot_data = config.model_dump(exclude_unset=True) + bot_data = config.model_dump(exclude_unset=not include_defaults) if bot_data: full_data["bot"] = convert_to_camel(bot_data) else: @@ -212,4 +217,4 @@ def camel_to_snake(name: str) -> str: def snake_to_camel(name: str) -> str: """Convert snake_case to camelCase.""" components = name.split("_") - return components[0] + "".join(x.title() for x in components[1:]) + return components[0] + "".join(x.title() for x in components[1:]) \ No newline at end of file diff --git a/bot/vikingbot/config/schema.py b/bot/vikingbot/config/schema.py index b4c30b56..90a2b10c 100644 --- a/bot/vikingbot/config/schema.py +++ b/bot/vikingbot/config/schema.py @@ -38,11 +38,13 @@ class SandboxMode(str, Enum): PER_SESSION = "per-session" SHARED = "shared" + PER_CHANNEL = "per-channel" class AgentMemoryMode(str, Enum): """Agent memory mode enumeration.""" PER_SESSION = "per-session" SHARED = "shared" + PER_CHANNEL = "per-channel" class BaseChannelConfig(BaseModel): @@ -102,10 +104,12 @@ class FeishuChannelConfig(BaseChannelConfig): type: ChannelType = ChannelType.FEISHU app_id: str = "" + open_id: str = "" app_secret: str = "" encrypt_key: str = "" verification_token: str = "" allow_from: list[str] = Field(default_factory=list) ## 允许更新Agent对话的Feishu用户ID列表 + thread_require_mention: bool = Field(default=True, description="话题群模式下是否需要@才响应:默认True=所有消息必须@才响应;False=新话题首条消息无需@,后续回复必须@") def channel_id(self) -> str: # Use app_id directly as the ID @@ -384,15 +388,15 @@ class AgentsConfig(BaseModel): provider: str = "" api_key: str = "" api_base: str = "" - extra_headers: dict[str, str] = None + extra_headers: Optional[dict[str, str]] = Field(default_factory=dict) class ProviderConfig(BaseModel): """LLM provider configuration.""" api_key: str = "" - api_base: str | None = None - extra_headers: dict[str, str] | None = None # Custom headers (e.g. APP-Code for AiHubMix) + api_base: Optional[str] = None + extra_headers: Optional[dict[str, str]] = Field(default_factory=dict) # Custom headers (e.g. APP-Code for AiHubMix) class ProvidersConfig(BaseModel): @@ -609,7 +613,7 @@ class Config(BaseSettings): "summarize", ] ) - storage_workspace: str | None = None # From ov.conf root level storage.workspace + storage_workspace: Optional[str] = None # From ov.conf root level storage.workspace use_local_memory: bool = False read_only: bool = False @@ -623,7 +627,8 @@ def channels_config(self) -> ChannelsConfig: @property def bot_data_path(self) -> Path: """Get expanded bot data path: {storage_workspace}/bot.""" - return Path(self.storage_workspace).expanduser() / "bot" + workspace = self.storage_workspace or "~/.openviking/data" + return Path(workspace).expanduser() / "bot" @property def workspace_path(self) -> Path: @@ -729,4 +734,4 @@ def from_safe_name(safe_name: str): file_name_split = safe_name.split("__") return SessionKey( type=file_name_split[0], channel_id=file_name_split[1], chat_id=file_name_split[2] - ) + ) \ No newline at end of file diff --git a/bot/vikingbot/integrations/langfuse.py b/bot/vikingbot/integrations/langfuse.py index 506cf2be..713bd577 100644 --- a/bot/vikingbot/integrations/langfuse.py +++ b/bot/vikingbot/integrations/langfuse.py @@ -104,31 +104,47 @@ def propagate_attributes( yield return + propagate_kwargs = {} + if session_id: + propagate_kwargs["session_id"] = session_id + if user_id: + propagate_kwargs["user_id"] = user_id + + if not propagate_kwargs: + yield + return + + # Use module-level propagate_attributes from langfuse SDK v3 + # Store in a local variable to avoid shadowing issues with the method name + global propagate_attributes + _propagate = propagate_attributes + + if _propagate is None: + logger.warning( + "[LANGFUSE] propagate_attributes not available (SDK version may not support it)" + ) + yield + return + + # Only catch exceptions when ENTERING the context manager + # Don't wrap the yield - let exceptions from the inner block propagate normally + logger.info(f"[LANGFUSE] Propagating attributes: {list(propagate_kwargs.keys())}") try: - propagate_kwargs = {} - if session_id: - propagate_kwargs["session_id"] = session_id - if user_id: - propagate_kwargs["user_id"] = user_id - - if not propagate_kwargs: - yield - return - - # Use module-level propagate_attributes from langfuse SDK v3 - global propagate_attributes - if propagate_attributes is not None: - logger.info(f"[LANGFUSE] Propagating attributes: {list(propagate_kwargs.keys())}") - with propagate_attributes(**propagate_kwargs): - yield - else: - logger.warning( - "[LANGFUSE] propagate_attributes not available (SDK version may not support it)" - ) - yield + cm = _propagate(**propagate_kwargs) + cm.__enter__() except Exception as e: - logger.debug(f"[LANGFUSE] propagate_attributes error: {e}") + logger.debug(f"[LANGFUSE] Failed to enter propagate_attributes: {e}") + yield + return + + try: yield + finally: + # Always exit the context manager + try: + cm.__exit__(None, None, None) + except Exception as e: + logger.debug(f"[LANGFUSE] Failed to exit propagate_attributes: {e}") @contextmanager def trace( @@ -207,23 +223,47 @@ def generation( yield None return + observation = None try: - with self._client.start_as_current_generation( - name=name, - model=model, - input=prompt, - metadata=metadata or {}, - ) as generation: - yield generation + # Use start_observation for the current SDK version + if hasattr(self._client, "start_as_current_observation"): + with self._client.start_as_current_observation( + name=name, + as_type="generation", + model=model, + input=prompt, + metadata=metadata or {}, + ) as obs: + yield obs + elif hasattr(self._client, "start_observation"): + observation = self._client.start_observation( + name=name, + as_type="generation", + model=model, + input=prompt, + metadata=metadata or {}, + ) + yield observation + else: + logger.debug("[LANGFUSE] No supported observation method found on client") + yield None except Exception as e: logger.debug(f"Langfuse generation error: {e}") yield None + finally: + # If we used start_observation, we need to end it manually + if observation and hasattr(observation, "end"): + try: + observation.end() + except Exception as e: + logger.debug(f"Langfuse observation.end() error: {e}") def update_generation( self, generation: Any, output: str | None = None, usage: dict[str, int] | None = None, + usage_details: dict[str, int] | None = None, metadata: dict[str, Any] | None = None, ) -> None: """Update a generation with output and usage.""" @@ -234,12 +274,18 @@ def update_generation( update_kwargs: dict[str, Any] = {} if output is not None: update_kwargs["output"] = output - if usage: - update_kwargs["usage"] = { - "prompt_tokens": usage.get("prompt_tokens", 0), - "completion_tokens": usage.get("completion_tokens", 0), - "total_tokens": usage.get("total_tokens", 0), + if usage_details: + update_kwargs["usage_details"] = usage_details + elif usage: + # Support both usage and usage_details formats + usage_details = { + "input": usage.get("prompt_tokens", 0), + "output": usage.get("completion_tokens", 0), } + # Pass through total_tokens if available + if "total_tokens" in usage: + usage_details["total"] = usage["total_tokens"] + update_kwargs["usage_details"] = usage_details if metadata: if hasattr(generation, "metadata") and generation.metadata: update_kwargs["metadata"] = {**generation.metadata, **metadata} diff --git a/bot/vikingbot/openviking_mount/ov_server.py b/bot/vikingbot/openviking_mount/ov_server.py index 935ce162..d3f6383c 100644 --- a/bot/vikingbot/openviking_mount/ov_server.py +++ b/bot/vikingbot/openviking_mount/ov_server.py @@ -91,7 +91,7 @@ def _relation_to_dict(self, relation: Any) -> Dict[str, Any]: } def get_agent_space_name(self, user_id: str) -> str: - return hashlib.md5((user_id + self.agent_id).encode()).hexdigest()[:12] + return hashlib.md5(f"{user_id}:{self.agent_id}".encode()).hexdigest()[:12] async def find(self, query: str, target_uri: Optional[str] = None): """搜索资源""" diff --git a/bot/vikingbot/providers/litellm_provider.py b/bot/vikingbot/providers/litellm_provider.py index 646a6779..5bca3627 100644 --- a/bot/vikingbot/providers/litellm_provider.py +++ b/bot/vikingbot/providers/litellm_provider.py @@ -4,9 +4,9 @@ import os from typing import Any -from loguru import logger import litellm from litellm import acompletion +from loguru import logger from vikingbot.integrations.langfuse import LangfuseClient from vikingbot.providers.base import LLMProvider, LLMResponse, ToolCallRequest @@ -104,6 +104,64 @@ def _apply_model_overrides(self, model: str, kwargs: dict[str, Any]) -> None: kwargs.update(overrides) return + def _handle_system_message( + self, model: str, messages: list[dict[str, Any]] + ) -> list[dict[str, Any]]: + """ + Handle system message for providers that don't support it (e.g. MiniMax). + Merges system message into the first user message or converts to user role. + """ + # Check for MiniMax + if model.startswith("minimax/") or "/minimax/" in model: + # Create a copy to avoid modifying the original list + new_messages = [] + + # Helper to merge content + def merge_content(base_content, new_content): + if isinstance(base_content, str) and isinstance(new_content, str): + return f"{new_content}\n\n{base_content}" + if isinstance(base_content, list): + base_content = list(base_content) + base_content.insert(0, {"type": "text", "text": f"{new_content}\n\n"}) + return base_content + return f"{new_content}\n\n{str(base_content)}" + + # First pass: identify system messages + system_contents = [] + cleaned_messages = [] + + for msg in messages: + if msg.get("role") == "system": + system_contents.append(msg.get("content", "")) + else: + cleaned_messages.append(msg) + + # If no system messages, return as is + if not system_contents: + return messages + + # Combine all system prompts + full_system_prompt = "\n\n".join([str(c) for c in system_contents]) + + # Merge into the first user message if available + merged = False + for msg in cleaned_messages: + if not merged and msg.get("role") == "user": + msg = msg.copy() + msg["content"] = merge_content(msg.get("content", ""), full_system_prompt) + new_messages.append(msg) + merged = True + else: + new_messages.append(msg) + + # If no user message found, create one at the beginning + if not merged: + new_messages.insert(0, {"role": "user", "content": full_system_prompt}) + + return new_messages + + return messages + async def chat( self, messages: list[dict[str, Any]], @@ -129,6 +187,9 @@ async def chat( """ model = self._resolve_model(model or self.default_model) + # Handle system message for MiniMax and others that don't support it + messages = self._handle_system_message(model, messages) + kwargs: dict[str, Any] = { "model": model, "messages": messages, @@ -155,24 +216,28 @@ async def chat( kwargs["tools"] = tools kwargs["tool_choice"] = "auto" - # Direct Langfuse v3 SDK usage + # Langfuse integration # Note: session_id is set via propagate_attributes in loop.py, not here - langfuse_generation = None + langfuse_observation = None try: if self.langfuse.enabled and self.langfuse._client: metadata = {"has_tools": tools is not None} - langfuse_generation = self.langfuse._client.start_generation( - name="llm-chat", - model=model, - input=messages, - metadata=metadata, - ) + client = self.langfuse._client + # Use start_observation with generation type + if hasattr(client, "start_observation"): + langfuse_observation = client.start_observation( + name="llm-chat", + as_type="generation", + model=model, + input=messages, + metadata=metadata, + ) response = await acompletion(**kwargs) llm_response = self._parse_response(response) - # Update and end Langfuse generation - if langfuse_generation: + # Update and end Langfuse observation + if langfuse_observation: output_text = llm_response.content or "" if llm_response.tool_calls: output_text = ( @@ -180,21 +245,20 @@ async def chat( or f"[Tool calls: {[tc.name for tc in llm_response.tool_calls]}]" ) - # Update generation with output and usage + # Update observation with output and usage update_kwargs: dict[str, Any] = { "output": output_text, "metadata": {"finish_reason": llm_response.finish_reason}, } if llm_response.usage: - # Langfuse v3 SDK expects "usage_details" with "input" and "output" keys + # Add usage data using usage_details format usage_details: dict[str, Any] = { "input": llm_response.usage.get("prompt_tokens", 0), "output": llm_response.usage.get("completion_tokens", 0), } - # Add cache read tokens if available (OpenAI/Anthropic prompt caching) - # Try multiple possible field names for cached tokens + # Add cache read tokens if available cache_read_tokens = llm_response.usage.get( "cache_read_input_tokens" ) or llm_response.usage.get("prompt_tokens_details", {}).get("cached_tokens") @@ -202,23 +266,44 @@ async def chat( usage_details["cache_read_input_tokens"] = cache_read_tokens update_kwargs["usage_details"] = usage_details - # Log the usage details being sent to Langfuse - # logger.info(f"[LANGFUSE] Updating generation with usage_details: {usage_details}") - langfuse_generation.update(**update_kwargs) - langfuse_generation.end() - self.langfuse.flush() + # Update the observation + if hasattr(langfuse_observation, "update"): + try: + langfuse_observation.update(**update_kwargs) + except Exception as e: + logger.debug(f"[LANGFUSE] Failed to update observation: {e}") + + # End the observation + if hasattr(langfuse_observation, "end"): + try: + langfuse_observation.end() + except Exception as e: + logger.debug(f"[LANGFUSE] Failed to end observation: {e}") + + try: + self.langfuse.flush() + except Exception as e: + logger.debug(f"[LANGFUSE] Failed to flush: {e}") return llm_response except Exception as e: - # End Langfuse generation with error - if langfuse_generation: - langfuse_generation.update( - output=f"Error: {str(e)}", - metadata={"error": str(e)}, - ) - langfuse_generation.end() - self.langfuse.flush() + # End Langfuse observation with error + if langfuse_observation: + try: + if hasattr(langfuse_observation, "update"): + langfuse_observation.update( + output=f"Error: {str(e)}", + metadata={"error": str(e)}, + ) + if hasattr(langfuse_observation, "end"): + langfuse_observation.end() + try: + self.langfuse.flush() + except Exception: + pass + except Exception: + pass # Return error as content for graceful handling return LLMResponse( content=f"Error calling LLM: {str(e)}", diff --git a/bot/vikingbot/sandbox/manager.py b/bot/vikingbot/sandbox/manager.py index 82e2947b..595fd6bc 100644 --- a/bot/vikingbot/sandbox/manager.py +++ b/bot/vikingbot/sandbox/manager.py @@ -107,7 +107,9 @@ def get_workspace_path(self, session_key: SessionKey) -> Path: def to_workspace_id(self, session_key: SessionKey): if self.config.sandbox.mode == "shared": return "shared" - else: + elif self.config.sandbox.mode == "per-channel": + return session_key.channel_key() + else: # per-session return session_key.safe_name() async def get_sandbox_cwd(self, session_key: SessionKey) -> str: diff --git a/bot/vikingbot/session/manager.py b/bot/vikingbot/session/manager.py index 32087f68..971f39f4 100644 --- a/bot/vikingbot/session/manager.py +++ b/bot/vikingbot/session/manager.py @@ -29,12 +29,14 @@ class Session: metadata: dict[str, Any] = field(default_factory=dict) def add_message( - self, role: str, content: str, sender_id: str | None = None, **kwargs: Any + self, role: str, content: str, sender_id: str | None = None, token_usage: dict[str, Any] = None, **kwargs: Any ) -> None: """Add a message to the session.""" msg = {"role": role, "content": content, "timestamp": datetime.now().isoformat(), **kwargs} if sender_id is not None: msg["sender_id"] = sender_id + if token_usage is not None: + msg["token_usage"] = token_usage self.messages.append(msg) self.updated_at = datetime.now() diff --git a/build_support/__init__.py b/build_support/__init__.py new file mode 100644 index 00000000..b9c0eff1 --- /dev/null +++ b/build_support/__init__.py @@ -0,0 +1 @@ +"""Build helpers for OpenViking native artifacts.""" diff --git a/build_support/x86_profiles.py b/build_support/x86_profiles.py new file mode 100644 index 00000000..cb0f1904 --- /dev/null +++ b/build_support/x86_profiles.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +import os +from dataclasses import dataclass +from typing import Iterable + +DEFAULT_X86_VARIANTS = ("sse3", "avx2", "avx512") +KNOWN_X86_VARIANTS = frozenset(DEFAULT_X86_VARIANTS) +X86_ARCHITECTURES = ("x86_64", "amd64", "x64", "i386", "i686") + + +@dataclass(frozen=True) +class EngineBuildConfig: + is_x86: bool + primary_extension: str + cmake_variants: tuple[str, ...] + + +def _normalize_machine(machine: str | None) -> str: + return (machine or "").strip().lower() + + +def is_x86_machine(machine: str | None) -> bool: + normalized = _normalize_machine(machine) + return any(token in normalized for token in X86_ARCHITECTURES) + + +def _normalize_x86_variants(raw_variants: Iterable[str]) -> tuple[str, ...]: + requested = [] + for variant in raw_variants: + normalized = variant.strip().lower() + if not normalized or normalized not in KNOWN_X86_VARIANTS or normalized in requested: + continue + requested.append(normalized) + + if "sse3" not in requested: + requested.insert(0, "sse3") + + return tuple(requested or DEFAULT_X86_VARIANTS) + + +def get_requested_x86_build_variants(raw_value: str | None = None) -> tuple[str, ...]: + if raw_value is None: + raw_value = os.environ.get("OV_X86_BUILD_VARIANTS", "") + + if not raw_value.strip(): + return DEFAULT_X86_VARIANTS + + return _normalize_x86_variants(raw_value.replace(";", ",").split(",")) + + +def get_host_engine_build_config(machine: str | None) -> EngineBuildConfig: + if is_x86_machine(machine): + return EngineBuildConfig( + is_x86=True, + primary_extension="openviking.storage.vectordb.engine._x86_sse3", + cmake_variants=get_requested_x86_build_variants(), + ) + + return EngineBuildConfig( + is_x86=False, + primary_extension="openviking.storage.vectordb.engine._native", + cmake_variants=(), + ) diff --git a/crates/ov_cli/Cargo.toml b/crates/ov_cli/Cargo.toml index a7bb8a5a..ea7bcd14 100644 --- a/crates/ov_cli/Cargo.toml +++ b/crates/ov_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ov_cli" -version = "0.2.1" +version = "0.2.6" edition = "2024" authors = ["OpenViking Contributors"] description = "Rust CLI client for OpenViking" diff --git a/crates/ov_cli/src/client.rs b/crates/ov_cli/src/client.rs index ce3cf8a9..46166e66 100644 --- a/crates/ov_cli/src/client.rs +++ b/crates/ov_cli/src/client.rs @@ -307,6 +307,51 @@ impl HttpClient { self.get("/api/v1/content/overview", ¶ms).await } + /// Download file as raw bytes + pub async fn get_bytes(&self, uri: &str) -> Result> { + let url = format!("{}/api/v1/content/download", self.base_url); + let params = vec![("uri".to_string(), uri.to_string())]; + + let response = self + .http + .get(&url) + .headers(self.build_headers()) + .query(¶ms) + .send() + .await + .map_err(|e| Error::Network(format!("HTTP request failed: {}", e)))?; + + let status = response.status(); + if !status.is_success() { + // Try to parse error message as JSON + let json_result: Result = response + .json() + .await + .map_err(|e| Error::Network(format!("Failed to parse error response: {}", e))); + + let error_msg = match json_result { + Ok(json) => { + json + .get("error") + .and_then(|e| e.get("message")) + .and_then(|m| m.as_str()) + .map(|s| s.to_string()) + .or_else(|| json.get("detail").and_then(|d| d.as_str()).map(|s| s.to_string())) + .unwrap_or_else(|| format!("HTTP error {}", status)) + } + Err(_) => format!("HTTP error {}", status), + }; + + return Err(Error::Api(error_msg)); + } + + response + .bytes() + .await + .map(|b| b.to_vec()) + .map_err(|e| Error::Network(format!("Failed to read response bytes: {}", e))) + } + // ============ Filesystem Methods ============ pub async fn ls(&self, uri: &str, simple: bool, recursive: bool, output: &str, abs_limit: i32, show_all_hidden: bool, node_limit: i32) -> Result { @@ -435,6 +480,7 @@ impl HttpClient { include: Option, exclude: Option, directly_upload_media: bool, + watch_interval: f64, ) -> Result { let path_obj = Path::new(path); @@ -456,6 +502,7 @@ impl HttpClient { "include": include, "exclude": exclude, "directly_upload_media": directly_upload_media, + "watch_interval": watch_interval, }); self.post("/api/v1/resources", &body).await @@ -475,6 +522,7 @@ impl HttpClient { "include": include, "exclude": exclude, "directly_upload_media": directly_upload_media, + "watch_interval": watch_interval, }); self.post("/api/v1/resources", &body).await @@ -492,6 +540,7 @@ impl HttpClient { "include": include, "exclude": exclude, "directly_upload_media": directly_upload_media, + "watch_interval": watch_interval, }); self.post("/api/v1/resources", &body).await @@ -510,6 +559,7 @@ impl HttpClient { "include": include, "exclude": exclude, "directly_upload_media": directly_upload_media, + "watch_interval": watch_interval, }); self.post("/api/v1/resources", &body).await @@ -689,4 +739,56 @@ impl HttpClient { ); self.post(&path, &serde_json::json!({})).await } + + // ============ Debug Vector Methods ============ + + /// Get paginated vector records + pub async fn debug_vector_scroll( + &self, + limit: Option, + cursor: Option, + uri_prefix: Option, + ) -> Result<(Vec, Option)> { + let mut params = Vec::new(); + if let Some(l) = limit { + params.push(("limit".to_string(), l.to_string())); + } + if let Some(c) = cursor { + params.push(("cursor".to_string(), c)); + } + if let Some(u) = uri_prefix { + params.push(("uri".to_string(), u)); + } + + let result: serde_json::Value = self.get("/api/v1/debug/vector/scroll", ¶ms).await?; + let records = result["records"] + .as_array() + .ok_or_else(|| Error::Parse("Missing records in response".to_string()))? + .clone(); + let next_cursor = result["next_cursor"].as_str().map(|s| s.to_string()); + + Ok((records, next_cursor)) + } + + /// Get count of vector records + pub async fn debug_vector_count( + &self, + filter: Option<&serde_json::Value>, + uri_prefix: Option, + ) -> Result { + let mut params = Vec::new(); + if let Some(f) = filter { + params.push(("filter".to_string(), serde_json::to_string(f)?)); + } + if let Some(u) = uri_prefix { + params.push(("uri".to_string(), u)); + } + + let result: serde_json::Value = self.get("/api/v1/debug/vector/count", ¶ms).await?; + let count = result["count"] + .as_u64() + .ok_or_else(|| Error::Parse("Missing count in response".to_string()))?; + + Ok(count) + } } diff --git a/crates/ov_cli/src/commands/chat.rs b/crates/ov_cli/src/commands/chat.rs index 6f78e3e2..6c15f1b4 100644 --- a/crates/ov_cli/src/commands/chat.rs +++ b/crates/ov_cli/src/commands/chat.rs @@ -37,9 +37,9 @@ pub struct ChatCommand { #[arg(short, long)] pub session: Option, - /// User ID - #[arg(short, long, default_value = "cli_user")] - pub user: String, + /// Sender ID + #[arg(short, long, default_value = "user")] + pub sender: String, /// Non-interactive mode (single message) #[arg(short = 'M', long)] @@ -128,7 +128,7 @@ impl ChatCommand { let request = ChatRequest { message: message.to_string(), session_id: self.session.clone(), - user_id: Some(self.user.clone()), + user_id: Some(self.sender.clone()), stream: false, context: None, }; @@ -171,7 +171,7 @@ impl ChatCommand { let request = ChatRequest { message: message.to_string(), session_id: self.session.clone(), - user_id: Some(self.user.clone()), + user_id: Some(self.sender.clone()), stream: true, context: None, }; @@ -244,10 +244,10 @@ impl ChatCommand { async fn run_interactive(&self, client: &Client) -> Result<()> { println!("Vikingbot Chat - Interactive Mode"); println!("Endpoint: {}", self.endpoint); - println!("Streaming: {}", if self.stream { "enabled" } else { "disabled" }); if let Some(session) = &self.session { println!("Session: {}", session); } + println!("Sender: {}", self.sender); println!("Type 'exit', 'quit', or press Ctrl+C to exit"); println!("----------------------------------------\n"); @@ -348,7 +348,7 @@ impl ChatCommand { let request = ChatRequest { message: input.to_string(), session_id: session_id.clone(), - user_id: Some(self.user.clone()), + user_id: Some(self.sender.clone()), stream: false, context: None, }; @@ -403,7 +403,7 @@ impl ChatCommand { let request = ChatRequest { message: input.to_string(), session_id: session_id.clone(), - user_id: Some(self.user.clone()), + user_id: Some(self.sender.clone()), stream: true, context: None, }; @@ -617,7 +617,7 @@ impl ChatCommand { endpoint: String, api_key: Option, session: Option, - user: String, + sender: String, message: Option, stream: bool, no_format: bool, @@ -627,7 +627,7 @@ impl ChatCommand { endpoint, api_key, session, - user, + sender, message, stream, no_format, diff --git a/crates/ov_cli/src/commands/content.rs b/crates/ov_cli/src/commands/content.rs index 7c51f6de..c1673f10 100644 --- a/crates/ov_cli/src/commands/content.rs +++ b/crates/ov_cli/src/commands/content.rs @@ -1,6 +1,9 @@ use crate::client::HttpClient; use crate::error::Result; use crate::output::OutputFormat; +use std::fs::File; +use std::io::Write; +use std::path::Path; pub async fn read( client: &HttpClient, @@ -34,3 +37,33 @@ pub async fn overview( println!("{}", content); Ok(()) } + +pub async fn get( + client: &HttpClient, + uri: &str, + local_path: &str, +) -> Result<()> { + // Check if target path already exists + let path = Path::new(local_path); + if path.exists() { + return Err(crate::error::Error::Client( + format!("File already exists: {}", local_path) + )); + } + + // Ensure parent directory exists + if let Some(parent) = path.parent() { + std::fs::create_dir_all(parent)?; + } + + // Download file + let bytes = client.get_bytes(uri).await?; + + // Write to local file + let mut file = File::create(path)?; + file.write_all(&bytes)?; + file.flush()?; + + println!("Downloaded {} bytes to {}", bytes.len(), local_path); + Ok(()) +} diff --git a/crates/ov_cli/src/commands/observer.rs b/crates/ov_cli/src/commands/observer.rs index 3b68c208..8a617804 100644 --- a/crates/ov_cli/src/commands/observer.rs +++ b/crates/ov_cli/src/commands/observer.rs @@ -32,6 +32,26 @@ pub async fn vlm( Ok(()) } +pub async fn transaction( + client: &HttpClient, + output_format: OutputFormat, + compact: bool, +) -> Result<()> { + let response: serde_json::Value = client.get("/api/v1/observer/transaction", &[]).await?; + output_success(&response, output_format, compact); + Ok(()) +} + +pub async fn retrieval( + client: &HttpClient, + output_format: OutputFormat, + compact: bool, +) -> Result<()> { + let response: serde_json::Value = client.get("/api/v1/observer/retrieval", &[]).await?; + output_success(&response, output_format, compact); + Ok(()) +} + pub async fn system( client: &HttpClient, output_format: OutputFormat, diff --git a/crates/ov_cli/src/commands/resources.rs b/crates/ov_cli/src/commands/resources.rs index bc816bcf..78ff6c63 100644 --- a/crates/ov_cli/src/commands/resources.rs +++ b/crates/ov_cli/src/commands/resources.rs @@ -16,6 +16,7 @@ pub async fn add_resource( include: Option, exclude: Option, directly_upload_media: bool, + watch_interval: f64, format: OutputFormat, compact: bool, ) -> Result<()> { @@ -33,6 +34,7 @@ pub async fn add_resource( include, exclude, directly_upload_media, + watch_interval, ) .await?; output_success(&result, format, compact); diff --git a/crates/ov_cli/src/commands/system.rs b/crates/ov_cli/src/commands/system.rs index 6f4b74c5..eae7b35d 100644 --- a/crates/ov_cli/src/commands/system.rs +++ b/crates/ov_cli/src/commands/system.rs @@ -34,19 +34,29 @@ pub async fn health( client: &HttpClient, output_format: OutputFormat, compact: bool, -) -> Result<()> { +) -> Result { let response: serde_json::Value = client.get("/health", &[]).await?; - // For health check, if it's a simple status, just print it - if let Some(status) = response.get("status").and_then(|v| v.as_str()) { - if matches!(output_format, OutputFormat::Json) { - output_success(&response, output_format, compact); - } else { - println!("{}", status); - } - } else { + // Extract the key fields + let healthy = response.get("healthy").and_then(|v| v.as_bool()).unwrap_or(false); + let _status = response.get("status").and_then(|v| v.as_str()); + let version = response.get("version").and_then(|v| v.as_str()); + let user_id = response.get("user_id").and_then(|v| v.as_str()); + + // For table output, print in a readable format + if matches!(output_format, OutputFormat::Table) || matches!(output_format, OutputFormat::Json) { output_success(&response, output_format, compact); + } else { + // Simple text output + print!("healthy {}", if healthy { "true" } else { "false" }); + if let Some(v) = version { + print!(" version {}", v); + } + if let Some(u) = user_id { + print!(" user_id {}", u); + } + println!(); } - Ok(()) + Ok(healthy) } diff --git a/crates/ov_cli/src/main.rs b/crates/ov_cli/src/main.rs index eb98c45c..cf444d75 100644 --- a/crates/ov_cli/src/main.rs +++ b/crates/ov_cli/src/main.rs @@ -96,6 +96,9 @@ enum Commands { /// Do not directly upload media files #[arg(long = "no-directly-upload-media", default_value_t = false)] no_directly_upload_media: bool, + /// Watch interval in minutes for automatic resource monitoring (0 = no monitoring) + #[arg(long, default_value = "0")] + watch_interval: f64, }, /// Add a skill into OpenViking AddSkill { @@ -261,6 +264,13 @@ enum Commands { /// Viking URI uri: String, }, + /// Download file to local path (supports binaries/images) + Get { + /// Viking URI + uri: String, + /// Local path (must not exist yet) + local_path: String, + }, /// Run semantic retrieval Find { /// Search query @@ -326,8 +336,8 @@ enum Commands { }, /// Interactive TUI file explorer Tui { - /// Viking URI to start browsing (default: viking://) - #[arg(default_value = "viking://")] + /// Viking URI to start browsing (default: /) + #[arg(default_value = "/")] uri: String, }, /// Chat with vikingbot agent @@ -338,6 +348,9 @@ enum Commands { /// Session ID (defaults to machine unique ID) #[arg(short, long)] session: Option, + /// Sender ID + #[arg(short, long, default_value = "user")] + sender: String, /// Stream the response (default: true) #[arg(long, default_value_t = true)] stream: bool, @@ -379,6 +392,10 @@ enum ObserverCommands { Vikingdb, /// Get VLM status Vlm, + /// Get transaction system status + Transaction, + /// Get retrieval quality metrics + Retrieval, /// Get overall system status System, } @@ -511,6 +528,7 @@ async fn main() { include, exclude, no_directly_upload_media, + watch_interval, } => { handle_add_resource( path, @@ -525,6 +543,7 @@ async fn main() { include, exclude, no_directly_upload_media, + watch_interval, ctx, ) .await @@ -584,13 +603,13 @@ async fn main() { Commands::Tui { uri } => { handle_tui(uri, ctx).await } - Commands::Chat { message, session, stream, no_format, no_history } => { + Commands::Chat { message, session, sender, stream, no_format, no_history } => { let session_id = session.or_else(|| config::get_or_create_machine_id().ok()); let cmd = commands::chat::ChatCommand { endpoint: std::env::var("VIKINGBOT_ENDPOINT").unwrap_or_else(|_| "http://localhost:1933/bot/v1".to_string()), api_key: std::env::var("VIKINGBOT_API_KEY").ok(), session: session_id, - user: "cli_user".to_string(), + sender, message, stream, no_format, @@ -606,6 +625,7 @@ async fn main() { Commands::Read { uri } => handle_read(uri, ctx).await, Commands::Abstract { uri } => handle_abstract(uri, ctx).await, Commands::Overview { uri } => handle_overview(uri, ctx).await, + Commands::Get { uri, local_path } => handle_get(uri, local_path, ctx).await, Commands::Find { query, uri, node_limit, threshold } => { handle_find(query, uri, node_limit, threshold, ctx).await } @@ -640,6 +660,7 @@ async fn handle_add_resource( include: Option, exclude: Option, no_directly_upload_media: bool, + watch_interval: f64, ctx: CliContext, ) -> Result<()> { let is_url = path.starts_with("http://") @@ -682,7 +703,17 @@ async fn handle_add_resource( let strict = !no_strict; let directly_upload_media = !no_directly_upload_media; - let client = ctx.get_client(); + let effective_timeout = if wait { + timeout.unwrap_or(60.0).max(ctx.config.timeout) + } else { + ctx.config.timeout + }; + let client = client::HttpClient::new( + &ctx.config.url, + ctx.config.api_key.clone(), + ctx.config.agent_id.clone(), + effective_timeout, + ); commands::resources::add_resource( &client, &path, @@ -697,6 +728,7 @@ async fn handle_add_resource( include, exclude, directly_upload_media, + watch_interval, ctx.output_format, ctx.compact, ).await @@ -772,7 +804,9 @@ async fn handle_system(cmd: SystemCommands, ctx: CliContext) -> Result<()> { commands::system::status(&client, ctx.output_format, ctx.compact).await } SystemCommands::Health => { - commands::system::health(&client, ctx.output_format, ctx.compact).await + let _ = + commands::system::health(&client, ctx.output_format, ctx.compact).await?; + Ok(()) } } } @@ -789,6 +823,12 @@ async fn handle_observer(cmd: ObserverCommands, ctx: CliContext) -> Result<()> { ObserverCommands::Vlm => { commands::observer::vlm(&client, ctx.output_format, ctx.compact).await } + ObserverCommands::Transaction => { + commands::observer::transaction(&client, ctx.output_format, ctx.compact).await + } + ObserverCommands::Retrieval => { + commands::observer::retrieval(&client, ctx.output_format, ctx.compact).await + } ObserverCommands::System => { commands::observer::system(&client, ctx.output_format, ctx.compact).await } @@ -913,6 +953,11 @@ async fn handle_overview(uri: String, ctx: CliContext) -> Result<()> { commands::content::overview(&client, &uri, ctx.output_format, ctx.compact).await } +async fn handle_get(uri: String, local_path: String, ctx: CliContext) -> Result<()> { + let client = ctx.get_client(); + commands::content::get(&client, &uri, &local_path).await +} + async fn handle_find( query: String, uri: String, @@ -1028,12 +1073,10 @@ async fn handle_glob(pattern: String, uri: String, node_limit: i32, ctx: CliCont async fn handle_health(ctx: CliContext) -> Result<()> { let client = ctx.get_client(); - let system_status: serde_json::Value = client.get("/api/v1/observer/system", &[]).await?; - let is_healthy = system_status.get("is_healthy").and_then(|v| v.as_bool()).unwrap_or(false); - output::output_success(&serde_json::json!({ "healthy": is_healthy }), ctx.output_format, ctx.compact); - if !is_healthy { - std::process::exit(1); - } + + // Reuse the system health command + let _ = commands::system::health(&client, ctx.output_format, ctx.compact).await?; + Ok(()) } diff --git a/crates/ov_cli/src/tui/app.rs b/crates/ov_cli/src/tui/app.rs index 1039f5a0..8e7517d4 100644 --- a/crates/ov_cli/src/tui/app.rs +++ b/crates/ov_cli/src/tui/app.rs @@ -8,6 +8,41 @@ pub enum Panel { Content, } +#[derive(Debug, Clone)] +pub struct VectorRecordsState { + pub records: Vec, + pub cursor: usize, + pub scroll_offset: usize, + pub next_page_cursor: Option, + pub has_more: bool, + pub total_count: Option, +} + +impl VectorRecordsState { + pub fn new() -> Self { + Self { + records: Vec::new(), + cursor: 0, + scroll_offset: 0, + next_page_cursor: None, + has_more: false, + total_count: None, + } + } + + /// Adjust scroll_offset so cursor is visible in the given viewport height + pub fn adjust_scroll(&mut self, viewport_height: usize) { + if viewport_height == 0 { + return; + } + if self.cursor < self.scroll_offset { + self.scroll_offset = self.cursor; + } else if self.cursor >= self.scroll_offset + viewport_height { + self.scroll_offset = self.cursor - viewport_height + 1; + } + } +} + pub struct App { pub client: HttpClient, pub tree: TreeState, @@ -18,6 +53,9 @@ pub struct App { pub content_line_count: u16, pub should_quit: bool, pub status_message: String, + pub vector_state: VectorRecordsState, + pub showing_vector_records: bool, + pub current_uri: String, } impl App { @@ -32,6 +70,9 @@ impl App { content_line_count: 0, should_quit: false, status_message: String::new(), + vector_state: VectorRecordsState::new(), + showing_vector_records: false, + current_uri: "/".to_string(), } } @@ -54,6 +95,7 @@ impl App { } }; + self.current_uri = uri.clone(); self.content_title = uri.clone(); self.content_scroll = 0; @@ -75,6 +117,11 @@ impl App { } self.content_line_count = self.content.lines().count() as u16; + + // If in vector mode, reload records with new current_uri + if self.showing_vector_records { + self.load_vector_records(Some(self.current_uri.clone())).await; + } } async fn load_directory_content(&mut self, uri: &str) { @@ -157,4 +204,101 @@ impl App { Panel::Content => Panel::Tree, }; } + + pub async fn load_vector_records(&mut self, uri_prefix: Option) { + self.status_message = "Loading vector records...".to_string(); + match self + .client + .debug_vector_scroll(Some(100), None, uri_prefix.clone()) + .await + { + Ok((records, next_cursor)) => { + self.vector_state.records = records; + self.vector_state.has_more = next_cursor.is_some(); + self.vector_state.next_page_cursor = next_cursor; + self.vector_state.cursor = 0; + self.vector_state.scroll_offset = 0; + self.status_message = format!("Loaded {} vector records", self.vector_state.records.len()); + } + Err(e) => { + self.status_message = format!("Failed to load vector records: {}", e); + } + } + } + + pub async fn load_next_vector_page(&mut self) { + if !self.vector_state.has_more { + self.status_message = "No more pages".to_string(); + return; + } + + self.status_message = "Loading next page...".to_string(); + match self + .client + .debug_vector_scroll( + Some(100), + self.vector_state.next_page_cursor.clone(), + Some(self.current_uri.clone()), + ) + .await + { + Ok((mut new_records, next_cursor)) => { + self.vector_state.records.append(&mut new_records); + self.vector_state.has_more = next_cursor.is_some(); + self.vector_state.next_page_cursor = next_cursor; + self.status_message = format!("Loaded {} total vector records", self.vector_state.records.len()); + } + Err(e) => { + self.status_message = format!("Failed to load next page: {}", e); + } + } + } + + pub async fn toggle_vector_records_mode(&mut self) { + self.showing_vector_records = !self.showing_vector_records; + if self.showing_vector_records && self.vector_state.records.is_empty() { + self.load_vector_records(Some(self.current_uri.clone())).await; + } + } + + pub async fn load_vector_count(&mut self) { + self.status_message = "Loading vector count...".to_string(); + match self + .client + .debug_vector_count(None, Some(self.current_uri.clone())) + .await + { + Ok(count) => { + self.vector_state.total_count = Some(count); + self.status_message = format!("Total vector records: {}", count); + } + Err(e) => { + self.status_message = format!("Failed to load count: {}", e); + } + } + } + + pub fn move_vector_cursor_up(&mut self) { + if self.vector_state.cursor > 0 { + self.vector_state.cursor -= 1; + } + } + + pub fn move_vector_cursor_down(&mut self) { + if !self.vector_state.records.is_empty() + && self.vector_state.cursor < self.vector_state.records.len() - 1 + { + self.vector_state.cursor += 1; + } + } + + pub fn scroll_vector_top(&mut self) { + self.vector_state.cursor = 0; + } + + pub fn scroll_vector_bottom(&mut self) { + if !self.vector_state.records.is_empty() { + self.vector_state.cursor = self.vector_state.records.len() - 1; + } + } } diff --git a/crates/ov_cli/src/tui/event.rs b/crates/ov_cli/src/tui/event.rs index 4a382abc..10a914ef 100644 --- a/crates/ov_cli/src/tui/event.rs +++ b/crates/ov_cli/src/tui/event.rs @@ -10,6 +10,15 @@ pub async fn handle_key(app: &mut App, key: KeyEvent) { KeyCode::Tab => { app.toggle_focus(); } + KeyCode::Char('v') => { + app.toggle_vector_records_mode().await; + } + KeyCode::Char('n') if app.showing_vector_records => { + app.load_next_vector_page().await; + } + KeyCode::Char('c') if app.showing_vector_records => { + app.load_vector_count().await; + } _ => match app.focus { Panel::Tree => handle_tree_key(app, key).await, Panel::Content => handle_content_key(app, key), @@ -37,19 +46,37 @@ async fn handle_tree_key(app: &mut App, key: KeyEvent) { } fn handle_content_key(app: &mut App, key: KeyEvent) { - match key.code { - KeyCode::Char('j') | KeyCode::Down => { - app.scroll_content_down(); + if app.showing_vector_records { + match key.code { + KeyCode::Char('j') | KeyCode::Down => { + app.move_vector_cursor_down(); + } + KeyCode::Char('k') | KeyCode::Up => { + app.move_vector_cursor_up(); + } + KeyCode::Char('g') => { + app.scroll_vector_top(); + } + KeyCode::Char('G') => { + app.scroll_vector_bottom(); + } + _ => {} } - KeyCode::Char('k') | KeyCode::Up => { - app.scroll_content_up(); - } - KeyCode::Char('g') => { - app.scroll_content_top(); + } else { + match key.code { + KeyCode::Char('j') | KeyCode::Down => { + app.scroll_content_down(); + } + KeyCode::Char('k') | KeyCode::Up => { + app.scroll_content_up(); + } + KeyCode::Char('g') => { + app.scroll_content_top(); + } + KeyCode::Char('G') => { + app.scroll_content_bottom(); + } + _ => {} } - KeyCode::Char('G') => { - app.scroll_content_bottom(); - } - _ => {} } } diff --git a/crates/ov_cli/src/tui/mod.rs b/crates/ov_cli/src/tui/mod.rs index 0079a112..6c9e9d28 100644 --- a/crates/ov_cli/src/tui/mod.rs +++ b/crates/ov_cli/src/tui/mod.rs @@ -55,6 +55,10 @@ async fn run_loop(client: HttpClient, uri: &str) -> Result<()> { area.height.saturating_sub(3) as usize }; app.tree.adjust_scroll(tree_height); + // Adjust vector scroll before rendering + if app.showing_vector_records { + app.vector_state.adjust_scroll(tree_height); + } terminal.draw(|frame| ui::render(frame, &app))?; diff --git a/crates/ov_cli/src/tui/tree.rs b/crates/ov_cli/src/tui/tree.rs index 076fdd08..bc90a0a5 100644 --- a/crates/ov_cli/src/tui/tree.rs +++ b/crates/ov_cli/src/tui/tree.rs @@ -62,11 +62,25 @@ impl TreeState { const ROOT_SCOPES: &'static [&'static str] = &["agent", "resources", "session", "user"]; pub async fn load_root(&mut self, client: &HttpClient, uri: &str) { - let is_root = uri == "viking://" || uri == "viking:///"; + let is_root = uri == "viking://" || uri == "viking:///" || uri == "/"; if is_root { - // Synthesize root scope folders and eagerly load their children - let mut root_nodes = Vec::new(); + // Create a single "/" root directory node, which when expanded will show the scopes + let mut root_node = TreeNode { + entry: FsEntry { + uri: "/".to_string(), + size: None, + is_dir: true, + mod_time: None, + }, + depth: 0, + expanded: true, + children_loaded: false, + children: Vec::new(), + }; + + // Preload the children (root scopes) so they're ready when expanding + let mut scope_nodes = Vec::new(); for scope in Self::ROOT_SCOPES { let scope_uri = format!("viking://{}", scope); let mut node = TreeNode { @@ -76,28 +90,27 @@ impl TreeState { is_dir: true, mod_time: None, }, - depth: 0, + depth: 1, expanded: false, children_loaded: false, children: Vec::new(), }; - // Try to load children eagerly to show first level + // Try to load children eagerly for scopes if let Ok(mut children) = Self::fetch_children(client, &scope_uri).await { for child in &mut children { - child.depth = 1; + child.depth = 2; } node.children = children; node.children_loaded = true; - if !node.children.is_empty() { - node.expanded = true; - } } - // Always show all scopes - root_nodes.push(node); + scope_nodes.push(node); } - self.nodes = root_nodes; + root_node.children = scope_nodes; + root_node.children_loaded = true; + + self.nodes = vec![root_node]; self.rebuild_visible(); } else { match Self::fetch_children(client, uri).await { diff --git a/crates/ov_cli/src/tui/ui.rs b/crates/ov_cli/src/tui/ui.rs index a67591ac..d3d0630f 100644 --- a/crates/ov_cli/src/tui/ui.rs +++ b/crates/ov_cli/src/tui/ui.rs @@ -71,7 +71,9 @@ fn render_tree(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) { }; let style = if row.is_dir { - Style::default().fg(Color::Blue).add_modifier(Modifier::BOLD) + Style::default() + .fg(Color::Blue) + .add_modifier(Modifier::BOLD) } else { Style::default() }; @@ -91,7 +93,11 @@ fn render_tree(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) { let list = List::new(items).highlight_style( Style::default() - .bg(if focused { Color::DarkGray } else { Color::Reset }) + .bg(if focused { + Color::DarkGray + } else { + Color::Reset + }) .fg(Color::White) .add_modifier(Modifier::BOLD), ); @@ -100,6 +106,11 @@ fn render_tree(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) { } fn render_content(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) { + if app.showing_vector_records { + render_vector_records(frame, app, area); + return; + } + let focused = app.focus == Panel::Content; let border_color = if focused { Color::Cyan @@ -126,20 +137,218 @@ fn render_content(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) { frame.render_widget(paragraph, area); } -fn render_status_bar(frame: &mut Frame, _app: &App, area: ratatui::layout::Rect) { - let hints = Line::from(vec![ - Span::styled(" q", Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)), +fn render_vector_records(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) { + let focused = app.focus == Panel::Content; + let border_color = if focused { + Color::Cyan + } else { + Color::DarkGray + }; + + let title = if let Some(total) = app.vector_state.total_count { + format!( + " Vector Records for {} ({}/{}, total: {}) ", + app.current_uri, + app.vector_state.cursor + 1, + app.vector_state.records.len(), + total + ) + } else { + format!( + " Vector Records for {} ({}/{}) ", + app.current_uri, + app.vector_state.cursor + 1, + app.vector_state.records.len() + ) + }; + + let block = Block::default() + .title(title) + .borders(Borders::ALL) + .border_style(Style::default().fg(border_color)); + + let inner = block.inner(area); + frame.render_widget(block, area); + + if app.vector_state.records.is_empty() { + let empty = + Paragraph::new("(no vector records)").style(Style::default().fg(Color::DarkGray)); + frame.render_widget(empty, inner); + return; + } + + let viewport_height = inner.height as usize; + + let items: Vec = app + .vector_state + .records + .iter() + .skip(app.vector_state.scroll_offset) + .take(viewport_height) + .map(|record| { + let context_type = record + .get("context_type") + .and_then(|v| v.as_str()) + .unwrap_or("(no type)"); + let level_str = record + .get("level") + .and_then(|v| v.as_i64()) + .map(|l| l.to_string()) + .unwrap_or("(no level)".to_string()); + let id = record + .get("id") + .and_then(|v| v.as_str()) + .unwrap_or("(no id)"); + let uri = record + .get("uri") + .and_then(|v| v.as_str()) + .unwrap_or("(no uri)"); + let line = Line::from(vec![ + Span::styled( + context_type, + Style::default() + .fg(Color::Green) + .add_modifier(Modifier::BOLD), + ), + Span::raw(" "), + Span::styled( + level_str, + Style::default() + .fg(Color::Magenta) + .add_modifier(Modifier::BOLD), + ), + Span::raw(" "), + Span::styled( + id, + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(" "), + Span::raw(uri), + ]); + ListItem::new(line) + }) + .collect(); + + let adjusted_cursor = app + .vector_state + .cursor + .saturating_sub(app.vector_state.scroll_offset); + let mut list_state = ListState::default().with_selected(Some(adjusted_cursor)); + + let list = List::new(items).highlight_style( + Style::default() + .bg(if focused { + Color::DarkGray + } else { + Color::Reset + }) + .fg(Color::White) + .add_modifier(Modifier::BOLD), + ); + + frame.render_stateful_widget(list, inner, &mut list_state); +} + +fn render_status_bar(frame: &mut Frame, app: &App, area: ratatui::layout::Rect) { + let mut hints = vec![ + Span::styled( + " q", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), Span::raw(":quit "), - Span::styled("TAB", Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)), + Span::styled( + "TAB", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), Span::raw(":switch "), - Span::styled("j/k", Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)), - Span::raw(":navigate "), - Span::styled(".", Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)), - Span::raw(":toggle folder "), - Span::styled("g/G", Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)), - Span::raw(":top/bottom"), - ]); - - let bar = Paragraph::new(hints).style(Style::default().bg(Color::DarkGray).fg(Color::White)); + ]; + + if app.showing_vector_records { + hints.extend_from_slice(&[ + Span::styled( + "v", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":files "), + Span::styled( + "j/k", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":navigate "), + Span::styled( + "n", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":next page "), + Span::styled( + "c", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":count "), + Span::styled( + "g/G", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":top/bottom"), + ]); + } else { + hints.extend_from_slice(&[ + Span::styled( + "v", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":vectors "), + Span::styled( + "j/k", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":navigate "), + Span::styled( + ".", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":toggle folder "), + Span::styled( + "g/G", + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ), + Span::raw(":top/bottom"), + ]); + } + + if !app.status_message.is_empty() { + hints.push(Span::raw(" | ")); + hints.push(Span::styled( + &app.status_message, + Style::default().fg(Color::Cyan), + )); + } + + let bar = Paragraph::new(Line::from(hints)) + .style(Style::default().bg(Color::DarkGray).fg(Color::White)); frame.render_widget(bar, area); } diff --git a/docs/design/multi-tenant-design.md b/docs/design/multi-tenant-design.md index 6c5ad43d..9a131ac2 100644 --- a/docs/design/multi-tenant-design.md +++ b/docs/design/multi-tenant-design.md @@ -283,7 +283,7 @@ def agent_space_name(self) -> str: | `agent/instructions` | `/{account_id}/agent/{agent_space}/instructions/` | account + user + agent | agent 的行为规则,每用户独立 | | `resources/` | `/{account_id}/resources/` | account | account 内共享的知识资源 | | `session/` | `/{account_id}/session/{user_space}/{session_id}/` | account + user | 用户的对话记录 | -| `transactions/` | `/{account_id}/transactions/` | account | 账户级事务记录 | +| `redo/` | `/{account_id}/_system/redo/` | account | 崩溃恢复 redo 标记 | | `_system/`(全局) | `/_system/` | 系统级 | 全局工作区列表 | | `_system/`(per-account) | `/{account_id}/_system/` | account | 用户注册表 | diff --git a/docs/design/openclaw-integration.md b/docs/design/openclaw-integration.md new file mode 100644 index 00000000..9725f7ee --- /dev/null +++ b/docs/design/openclaw-integration.md @@ -0,0 +1,354 @@ +# OpenClaw Context Engine Integration Design / OpenClaw 上下文引擎集成方案设计 + +## Context / 背景 + +本方案讨论在 OpenViking 中集成 OpenClaw Context Engine 的扩展机制,以及围绕新引擎的记忆管理、查询、注入等完整设计。 + +This proposal discusses the extension mechanism for integrating OpenClaw Context Engine into OpenViking, along with the complete design for memory management, retrieval, and injection around the new engine. + +--- + +## Component 1: Memory Write Mechanism / 组件 1:记忆写入机制 + +### Compact-Triggered Automatic Write / compact 触发的自动写入 + +1. 当 compact 时一次性把对话上传到 ov。 + + Upload conversation to OpenViking in one batch when compact is triggered. + +2. 可选项:compact 时,可以把一些工作记忆(比如 TODO,摘要),留在压缩后的上下文里面(如果有的话),避免断档。 + + Optional: During compact, keep some working memories (e.g., TODOs, summaries) in the compressed context (if available) to avoid discontinuity. + +3. 由于涉及 agent 记忆的提取,建议把 system prompt 和工具调用也一起上传。 + + Since agent memory extraction is involved, it is recommended to also upload the system prompt and tool calls together. + +4. 相比于之前模式(每条消息都写入),一次性的写入可以减少记忆提取阶段的 token 消耗,带来的缺点是跨 session 的记忆同步会变慢(不敏感)。 + + Compared to the previous mode (writing every message), one-time writing reduces token consumption during memory extraction. The downside is that cross-session memory synchronization will be slower (not sensitive). + +5. compact 一般在 /new 或消息达到一定长度时触发,消息未达长度的部分不会触发记忆提取。这部分未来可以加入 timeout 触发提取的机制(当前可以不要)。 + + Compact is typically triggered by /new or when messages reach a certain length. Messages that don't reach the length threshold won't trigger memory extraction. A timeout-based extraction mechanism can be added in the future (not needed currently). + +--- + +### Active Memory (Tool-based) / 主动记忆(基于工具)(可选) + +这允许 agent 通过 `commit_memory` 工具(或ov cli)主动记录记忆,支持用户请求如: + +This allows the agent to actively record memories via a `commit_memory` tool (or ov cli), supporting user requests like: + +- "Remember that I like dark mode" / "记住我喜欢深色模式" +- "Don't ask me for confirmation again" / "下次不要再让我确认了" +- "Note that project X is on hold" / "记下项目 X 暂停了" + +**commit_memory Tool / 工具**: +- **Purpose / 用途**: Actively commit a memory to long-term storage / 主动将记忆提交到长期存储 +- **When to use / 何时使用**: User asks to remember, strong preference, important decision, etc. / 用户要求记住、强烈偏好、重要决定等 +- **Parameters / 参数**: `memory_content`, `memory_type`, `priority`, `category` +- **Behavior / 行为**: Immediate extraction and write (no compact delay) / 立即提取和写入(无 compact 延迟) + +--- + +## Component 2: Memory Retrieval / 组件 2:记忆查询/召回 + +记忆查询分为三部分: + +Memory retrieval has three parts: + +1. **用户画像注入** - 在会话开始时注入到 system prompt / User Profile Injection - Injected into system prompt at session start +2. **每轮记忆召回** - 为每条用户消息召回相关记忆 / Per-turn Memory Retrieval - Retrieve relevant memories for each user message +3. **Agent主动通过工具调用召回记忆**(TODO) / Agent-initiated memory retrieval via tool calls (TODO) + +--- + +### Part 1: User Profile Injection / 第一部分:用户画像注入 + +在会话开始时一次性注入到 system prompt。 + +Injected once at session start into the system prompt. + +**Profile Sources / 画像来源**: +- `profile.md` - User's main profile file (always included) / 用户主画像文件(总是包含) +- High-quality memory abstracts (only if quality score >= threshold) / 高质量记忆摘要(TODO:是否加入取决于摘要机制的质量是否ok / TODO: inclusion depends on whether the quality of the abstraction mechanism is acceptable) + +--- + +### Part 2: Per-turn Memory Retrieval / 第二部分:每轮记忆召回 + +为每条用户消息召回,仅用于该次 LLM 调用。 + +Retrieved for each user message, only used for that single LLM call. + +**Query Construction / 查询构建**: Use last N user messages (default: 5) concatenated as the search query / 使用最近 N 条用户消息(默认:5条)拼接作为搜索查询 + +**Lightweight Intent Detection / 轻量级意图检测(TODO 可选模块,可基于轻量模型实现 / TODO optional module, can be implemented with lightweight models)**: +- Skip retrieval for greetings ("你好", "在吗", "hi", "hello") / 跳过问候语的召回 +- Skip very short messages (<= 3 chars) / 跳过很短的消息(<= 3 字符) + +--- + +**将自动召回的记忆作为模拟的 function call 结果注入,而不是直接注入到 prompt 中** + +Inject auto-retrieved memories as simulated function call results instead of directly injecting into the prompt. This is a continuation of Part 2. + +**Benefits / 好处**: +1. **Agent Awareness / Agent 感知**: The agent sees that a search was performed, so it knows this pattern exists and can use it itself later / Agent 看到执行了搜索,因此知道这种模式存在,以后可以自己使用 +2. **Query Transparency / 查询透明**: The agent sees exactly what query was used, so it can choose different keywords if it searches again / Agent 看到具体使用了什么查询,因此如果再次搜索可以选择不同的关键词 + +**Example Flow / 示例流程**: +``` +User: How do I optimize the database? + +Assistant: [Function Call] search_memories({"query": "database optimization...", "max_results": 5}) + +System: [Function Result] {"success": true, "memories": [...]} + +Assistant: Based on... +``` + +**Retrieval Flow / 召回流程**: +1. Get current user message / 获取当前用户消息 +2. Check if should skip retrieval / 检查是否应该跳过召回 +3. Build search query from last N user messages / 从最近 N 条用户消息构建搜索查询 +4. Search in OpenViking / 在 OpenViking 中搜索 +5. Apply relevance threshold filter / 应用相关性阈值过滤 +6. Format memories (L0/L1/L2 based on config) / 格式化记忆(根据配置使用 L0/L1/L2) +7. Inject into THIS LLM call only (not persisted) / 仅注入到本次 LLM 调用(不持久化) + +--- + +## Component 3: Agentic Memory Query / 组件 3:Agent 通过工具主动记忆查询 + +除了每轮自动注入之外,还提供 Agent 发起的查询机制,以满足更复杂的检索需求。这是一种"测试时计算"的方法,用于解决单轮回召可能遗漏的多跳和多背景检索问题。 + +In addition to per-turn auto-injection, provide an agent-initiated query mechanism to meet more complex retrieval needs. This is a "test-time compute" approach to solve multi-hop and multi-context retrieval problems that single-round retrieval may miss. + +### Pre-inject Directory Structure / 预先注入目录结构 + +为了让主动记忆的路径尽可能短,可以默认把 `ov ls viking://` 的结果预先注入到 system prompt 里面,让 agent 预先知道 ov 里有哪些数据可以用。如果能模拟成是 agent 主动调用的,效果可能更好。 + +To make the path to active memory as short as possible, pre-inject the results of `ov ls viking://` into the system prompt by default, so the agent knows in advance what data is available in OpenViking. Effect may be better if simulated as an agent-initiated call. + +**Design / 设计**: +- At session start / 在会话开始时 +- Run `ov ls viking://` (or equivalent) / 运行 `ov ls viking://`(或等效操作) +- Format results as directory tree / 将结果格式化为目录树 +- Inject into system prompt, optionally simulate as function call / 注入到 system prompt,可选模拟为 function call + +**Example / 示例**: +``` +Assistant: [Function Call] ov_ls({"path": "viking://"}) + +System: [Function Result] { + "directories": [ + "viking://docs/", + "viking://user/memories/", + "viking://agent/skills/", + "viking://assets/" + ] +} +``` + +### When to Use / 何时使用 + +| Scenario / 场景 | Example / 示例 | +|----------------|---------------| +| **Multi-hop reasoning / 多跳推理** | "What did I say about project X last week, and how does that relate to the Y file we discussed?" | +| **Need for comprehensive context / 需要全面上下文** | "Tell me everything I've said about database optimization" | +| **Temporal queries / 时间查询** | "What decisions did we make in the last month about authentication?" | +| **Cross-session retrieval / 跨会话检索** | "Find my previous conversation about API design patterns" | +| **Directory semantic exploration / 目录语义探索** | "What's in the /docs folder that's relevant to my current task?" | + +--- + +## Component 4: Skill Memory Injection / 组件 4:Skill 记忆注入 + +Skill 记忆是Agent记忆的一种,区别点在于他锚定一个确定性的Skill + +因此可以通过拦截工具调用中的 `read skills/xxx/SKILL.md` 文件调用,在返回结果中添加 skill 记忆的方式注入。 + +Skill memories are a type of agent memory, with the key distinction that they are anchored to a specific skill. + +Therefore, they can be injected by intercepting `read skills/xxx/SKILL.md` file calls in tool calls, and adding skill memories to the returned results. + +**Design / 设计**: + +1. **Intercept skill file reads / 拦截 skill 文件读取** + - When agent reads `skills//SKILL.md` / 当 agent 读取 `skills//SKILL.md` 时 + - Intercept the read operation / 拦截读取操作 + - Look up skill memories from memory store / 从记忆存储中查找 skill 记忆 + +2. **Augment skill content / 增强 skill 内容** + - Prepend/append skill memories to the SKILL.md content / 在 SKILL.md 内容前后添加 skill 记忆 + - Include usage patterns, success tips, common pitfalls, etc. / 包含使用模式、成功技巧、常见陷阱等 + - Keep the original SKILL.md intact / 保持原始 SKILL.md 不变 + +3. **Skill memory structure / Skill 记忆结构** + - Usage statistics (how often used, success rate) / 使用统计(使用频率、成功率) + - Past examples (successful invocations) / 过去的示例(成功调用) + - Tips and tricks (learned from experience) / 技巧和窍门(从经验中学习) + - Known issues and workarounds / 已知问题和解决方法 + +**Example / 示例**: +``` +Original SKILL.md: +## Create Presentation +Create a PowerPoint presentation... + +Augmented with skill memory: +## Create Presentation (Used 15 times, 93% success) + +Create a PowerPoint presentation... + +--- +## Past Examples +- Successfully created Q3 financial report (2024-03-01) +- Created project kickoff deck (2024-02-15) + +## Tips +- User prefers dark theme templates +- Always include executive summary slide +- Use company logo from /assets/logo.png + +## Known Issues +- Large images (>10MB) sometimes fail - compress first +``` + +--- + +## Component 5: Tool Memory Injection / 组件 5:工具记忆注入 + +工具记忆可以通过 system prompt 方式注入。 + +Tool memories can be injected via system prompt. + +**Design / 设计**: + +1. **Inject into system prompt / 注入到 system prompt** + - At the start of each session or turn / 在每个会话或轮次开始时 + - Include tool usage memories / 包含工具使用记忆 + - Keep it concise to avoid token bloat / 保持简洁以避免 token 膨胀 + +2. **Tool memory content / 工具记忆内容** + - Tool usage statistics (call count, success rate, average time) / 工具使用统计(调用次数、成功率、平均时间) + - Common parameter patterns / 常见参数模式 + - Error patterns and how to avoid them / 错误模式和如何避免 + - Best practices learned / 学到的最佳实践 + +3. **Format / 格式** + - Structured, easy to parse / 结构化,易于解析 + - Priority-based (most important first) / 基于优先级(最重要的在前) + - Include only high-value insights / 仅包含高价值洞察 + +**Example / 示例**: +``` +## Tool Usage Memories + +### run_shell +- Called 42 times, 88% success rate +- Average time: 2.3s +- Common issues: + - Forgetting to use `cd` before relative paths + - Long-running commands need `--async` flag +- Best practice: Always use `&&` for chained commands + +### edit_file +- Called 156 times, 95% success rate +- Best practice: Use `search_replace` instead of full rewrite when possible +``` + +--- + +## Appendix: OpenViking Tool Injection / 附录:OpenViking 工具注入 + +本节讨论如何将 OpenViking 能力注入到 Agent 中。提出了两种方案,都避免了基于 skill 的注入模式。 + +This section discusses how to inject OpenViking capabilities into the agent. Two options are proposed, both avoiding the skill-based injection pattern. + +### Problem with Skill-based Injection / 基于 Skill 注入的问题 + +- **Unstable triggering / 触发不稳定** +- **Competition with other skills / 需要和其他 skill 竞争** +- **Hard to predict when it will be used / 难以预测何时会被使用** + +--- + +### Option 1: System Prompt + Bash CLI (Recommended if CLI is LLM-friendly) / 方案 1:System Prompt + Bash CLI(如果 CLI 对 LLM 友好,推荐此方案) + +直接将 OpenViking CLI 用法说明注入到 system prompt 中。Agent 使用内置的 bash 工具调用 `ov` 命令。 + +Inject OpenViking CLI usage instructions directly into the system prompt. The agent uses the built-in bash tool to call `ov` commands. + +**Advantages / 优势**: +- No tool definition needed / 不需要定义 tool +- Uses agent's existing bash capabilities / 使用 Agent 已有的 bash 能力 +- More flexible (agent can compose commands) / 更灵活(Agent 可以组合命令) +- Works well if CLI is simple and intuitive / 如果 CLI 简单直观,效果很好 + +**Requirements / 要求**: +- CLI must be LLM-friendly (simple commands, good help text) / CLI 必须对 LLM 友好(命令简单、帮助文本完善) +- Predictable output format (JSON by default) / 可预测的输出格式(默认 JSON) +- Clear, self-documenting commands / 清晰、自解释的命令 + +**Example Commands / 示例命令**: +```bash +ov search --query "your query" [--category ] [--limit N] +ov ls memories [--category ] +ov search-docs --query "your query" [--path ] +ov history [--limit N] +ov remember --content "what to remember" [--type ] [--priority N] +``` + +--- + +### Option 2: Tool Definition Injection / 方案 2:工具定义注入 + +将 OpenViking 能力定义为显式的工具定义(function calling)。 + +Define OpenViking capabilities as explicit tool definitions (function calling). + +**Advantages / 优势**: +- More predictable triggering / 触发更可预测 +- Structured input validation / 结构化输入验证 +- Clear separation from bash usage / 与 bash 用法清晰分离 +- Works even if agent doesn't have bash access / 即使 Agent 没有 bash 访问权限也能工作 + +**Disadvantages / 劣势**: +- Need to maintain tool definitions / 需要维护工具定义 +- Less flexible than free-form bash / 不如自由形式的 bash 灵活 +- More verbose for complex operations / 复杂操作更冗长 + +--- + +### Comparison / 对比 + +| Aspect / 方面 | Option 1: System Prompt + Bash / 方案 1:System Prompt + Bash | Option 2: Tool Definition / 方案 2:工具定义 | +|--------------|----------------------------------------------------------------|----------------------------------------------| +| **Trigger Stability / 触发稳定性** | Depends on bash tool reliability / 取决于 bash 工具可靠性 | More predictable / 更可预测 | +| **Flexibility / 灵活性** | High - can compose commands / 高 - 可以组合命令 | Lower - fixed schema / 较低 - 固定 schema | +| **Maintenance / 维护成本** | Maintain CLI help text / 维护 CLI 帮助文本 | Maintain tool definitions / 维护工具定义 | +| **LLM Friendliness / LLM 友好度** | Requires good CLI design / 需要好的 CLI 设计 | Explicit schema helps / 显式 schema 有帮助 | +| **Bash Required / 需要 Bash** | Yes / 是 | No / 否 | + +--- + +### Recommendation / 建议 + +**Primary Recommendation: Option 1 (CLI + Bash) if CLI can be made LLM-friendly** + +**主要建议:如果 CLI 能做到对 LLM 友好,选择方案 1(CLI + Bash)** + +Why / 为什么: +1. More flexible for power users / 对高级用户更灵活 +2. Single source of truth (CLI works for humans and agents) / 单一事实来源(CLI 对人类和 Agent 都有效) +3. Less code to maintain (no duplicate tool definitions) / 维护代码更少(没有重复的工具定义) +4. Agents can discover and experiment with commands / Agent 可以发现和实验命令 + +**Fallback: Option 2 (Tool Definition) if CLI can't be simplified enough** + +**备选方案:如果 CLI 无法足够简化,选择方案 2(工具定义)** + +--- diff --git a/docs/design/operation_telemetry.md b/docs/design/operation_telemetry.md new file mode 100644 index 00000000..d20fd00e --- /dev/null +++ b/docs/design/operation_telemetry.md @@ -0,0 +1,520 @@ +# 操作级 Telemetry 设计 + +## 1. 背景与目标 + +OpenViking 需要一套统一的 telemetry 机制,用来描述一次操作在执行过程中的关键观测信息。当前已经落地的是操作级 telemetry,主要覆盖: + +- 请求耗时统计 +- token 消耗统计 +- 检索、队列、内存提取等阶段的摘要指标 + +这里统一使用 `telemetry`,而不是 `trace`,原因是这套抽象未来不只服务于“单次操作链路”,还要能承载非操作级数据,例如: + +- 服务整体 token 消耗 +- 各类后端能力的延迟与错误率 +- 存储、向量库、队列等组件级指标 +- 基于 OpenTelemetry 的 exporter / backend 对接 + +当前实现只对“操作级 telemetry”提供正式接口,但抽象命名和结构已经为后续扩展预留空间。 + +## 2. 设计原则 + +### 2.1 详细信息显式按需返回 + +详细 telemetry 由调用方通过 `telemetry` 参数显式请求,当前对外协议只返回结构化 summary,不返回事件流。 + +### 2.3 字段名直接面向用户 + +内部打点名与对外 summary 字段名保持一致,避免额外的“内部名 -> 外部名”转换层。 + +### 2.4 缺失分组不返回 + +如果某类操作天然不会产出某个 summary 分组,则该分组直接省略,不返回空对象或全 `null` 字段。 + +例如: + +- `resources.add_resource` 不一定有 `memory` +- `session.commit` 一般没有 `semantic_nodes` +- 某些操作没有向量检索,就不返回 `vector` + +## 3. 当前支持范围 + +### 3.1 HTTP 接口 + +当前已接入 operation telemetry 的接口: + +- `POST /api/v1/search/find` +- `POST /api/v1/search/search` +- `POST /api/v1/resources` +- `POST /api/v1/skills` +- `POST /api/v1/sessions/{session_id}/commit` + +说明: + +- `session.commit` 仅在 `wait=true` 的同步模式下支持返回 telemetry +- `wait=false` 的异步任务模式当前不支持 telemetry,请求时会返回 `INVALID_ARGUMENT` + +### 3.2 SDK 接口 + +当前已接入 operation telemetry 的 SDK 方法: + +- `add_resource` +- `add_skill` +- `find` +- `search` +- `commit_session` + +本地嵌入式 client 和 HTTP client 都遵循同一套 telemetry 请求语义。 + +## 4. 响应模型 + +服务端仍使用统一响应包裹结构: + +```json +{ + "status": "ok", + "result": { "...": "..." }, + "time": 0.031, + "telemetry": { + "id": "tm_9f6f4d6b0d0c4f4d93ce5adf82e71c18", + "summary": { + "operation": "search.find", + "status": "ok", + "duration_ms": 31.224, + "tokens": { + "total": 24, + "llm": { + "input": 12, + "output": 6, + "total": 18 + }, + "embedding": { + "total": 6 + } + }, + "vector": { + "searches": 3, + "scored": 26, + "passed": 8, + "returned": 5, + "scanned": 26, + "scan_reason": "" + } + } + } +} +``` + +说明: + +- `telemetry` 只在调用方显式请求时返回 +- `telemetry.id` 是不透明标识,只用于关联,不要求调用方解析语义 + +## 5. telemetry 请求语义 + +`telemetry` 字段支持两种形态: + +### 5.1 布尔形态 + +```json +{ + "telemetry": true +} +``` + +语义: + +- 返回 `telemetry.id + telemetry.summary` + +### 5.2 对象形态 + +```json +{ + "telemetry": { + "summary": true + } +} +``` + +语义: + +- `summary` 默认值为 `true` +- 适合只看结构化摘要 + +当前支持的合法组合如下: + +| 请求值 | 语义 | +| --- | --- | +| `false` | 不返回 `telemetry` | +| `true` | 返回 `id + summary` | +| `{"summary": true}` | 返回 `id + summary` | +| `{"summary": false}` | 不返回 `telemetry` | + +以下请求非法: + +```json +{ + "telemetry": { + "events": true + } +} +``` + +原因是当前对外 telemetry 已收敛为 summary-only,不再接受事件流选择参数。 + +## 6. telemetry 的职责划分 + +### 6.1 `telemetry.summary` + +`summary` 是结构化的操作摘要,用于: + +- 调试 +- 排障 +- 离线分析 +- 上报到外部观测系统 + +当前 summary 的核心字段包括: + +- `operation` +- `status` +- `duration_ms` +- `tokens` +- `queue` +- `vector` +- `semantic_nodes` +- `memory` +- `errors` + +其中: + +- `tokens` 始终存在 +- 其余分组按是否有产出决定是否返回 + +### 6.3 `telemetry.id` + +`telemetry.id` 是请求级关联标识,用于把一次操作的 summary 与内部异步链路统计关联起来。 + +## 7. summary 字段约定 + +### 7.1 顶层公共字段 + +所有 summary 至少包含: + +- `operation` +- `status` +- `duration_ms` +- `tokens` + +### 7.2 tokens + +示例: + +```json +{ + "tokens": { + "total": 19, + "llm": { + "input": 11, + "output": 7, + "total": 18 + }, + "embedding": { + "total": 1 + } + } +} +``` + +说明: + +- `llm` 统计输入、输出与总量 +- `embedding` 当前只统计总量 + +### 7.3 queue + +队列相关摘要示例: + +```json +{ + "queue": { + "semantic": { + "processed": 1, + "error_count": 0 + }, + "embedding": { + "processed": 1, + "error_count": 0 + } + } +} +``` + +### 7.4 vector + +向量检索摘要示例: + +```json +{ + "vector": { + "searches": 2, + "scored": 5, + "passed": 3, + "returned": 2, + "scanned": 5, + "scan_reason": "" + } +} +``` + +### 7.5 semantic_nodes + +语义检索 DAG / 节点级摘要示例: + +```json +{ + "semantic_nodes": { + "total": 4, + "done": 3, + "pending": 1, + "running": 0 + } +} +``` + +### 7.6 memory + +会话提交等内存提取类操作示例: + +```json +{ + "memory": { + "extracted": 4 + } +} +``` + +### 7.7 errors + +发生错误时可返回: + +```json +{ + "errors": { + "stage": "resource_processor.parse", + "error_code": "PROCESSING_ERROR", + "message": "..." + } +} +``` + +无错误时,该分组可以省略。 + +## 8. 缺失字段裁剪策略 + +summary 采用“按分组裁剪”的策略,而不是固定返回整套字段。 + +这样做有几个直接收益: + +- 避免返回大量与当前操作无关的空字段 +- 降低调用方理解成本 +- 更适合未来扩展新的 telemetry 分组 + +示例: + +### 8.1 `resources.add_resource` + +可能返回: + +```json +{ + "operation": "resources.add_resource", + "status": "ok", + "duration_ms": 152.3, + "tokens": { "...": "..." }, + "semantic_nodes": { "...": "..." }, + "queue": { "...": "..." } +} +``` + +这里不应强行返回 `memory`。 + +### 8.2 `session.commit` + +可能返回: + +```json +{ + "operation": "session.commit", + "status": "ok", + "duration_ms": 48.1, + "tokens": { "...": "..." }, + "memory": { + "extracted": 4 + } +} +``` + +这里不应强行返回 `semantic_nodes`。 + +## 9. 成本模型 + +当前 collector 只采集 summary 所需的数据: + +- 采集 counters / gauges +- 记录 error 状态 +- 构造最终 summary +- 不保留事件列表 + +## 10. 实现结构 + +### 10.1 核心类型 + +核心实现位于: + +- `openviking/telemetry/operation.py` +- `openviking/telemetry/request.py` +- `openviking/telemetry/context.py` +- `openviking/telemetry/registry.py` + +主要对象包括: + +- `OperationTelemetry` +- `TelemetrySnapshot` +- `TelemetrySelection` + +### 10.2 请求解析 + +`openviking/telemetry/request.py` 负责统一解析 `telemetry` 请求参数: + +- 支持 `bool | object` +- 归一化为 `TelemetrySelection` +- 校验非法字段,例如 `events` + +这样 server、local client、HTTP client 都共享同一套语义。 + +### 10.3 服务端集成 + +`openviking/server/telemetry.py` 负责: + +- 根据请求创建 collector +- 根据 selection 决定是否附带 `summary` + +router 层的职责是: + +1. 创建 collector +2. 绑定 operation 上下文 +3. 执行实际业务逻辑 +4. 按请求返回 `telemetry` + +### 10.4 本地与 HTTP client + +本地 client 和 HTTP client 都暴露同样的 `telemetry` 参数语义: + +```python +await client.find("memory dedup", telemetry=True) +await client.find("memory dedup", telemetry={"summary": True}) +``` + +其中: + +- local client 在本地生成 telemetry 并拼回结果 +- HTTP client 负责参数校验并透传给服务端 + +## 11. 异步链路与跨组件聚合 + +当前 operation telemetry 不只覆盖同步请求栈,也支持部分异步处理链路的数据回流。 + +典型场景包括: + +- 请求线程触发语义队列处理 +- 请求线程触发 embedding 处理 +- 后台处理线程继续向同一个 operation collector 记录指标 + +实现方式是: + +- collector 生成 `telemetry.id` +- 后续消息携带该 `id` +- 后台组件通过 registry 找回原 collector +- 在新的执行上下文中重新绑定 collector + +这样一次操作的最终 summary 可以覆盖: + +- 请求入口逻辑 +- 检索过程 +- embedding 处理 +- semantic queue 处理 +- memory 提取结果 + +## 12. 与 OpenTelemetry 的关系 + +当前方案不是直接把 OpenTelemetry 暴露为业务接口,而是先定义 OpenViking 自己的 telemetry 抽象。 + +这样做的好处是: + +- 对调用方暴露稳定、简单的产品接口 +- 不把业务接口和具体观测框架强绑定 +- 后续可以新增 OpenTelemetry backend,而不影响现有 SDK / HTTP 语义 + +可以把 OpenTelemetry 看作未来的一种底层实现或导出方式,而不是当前对外协议本身。 + +## 13. 未来扩展方向 + +当前文档描述的是 operation telemetry,但未来需要兼容更广义的 telemetry 数据源。 + +推荐的扩展方向: + +- 服务级 token 消耗聚合 +- 存储、向量库、模型服务的接口耗时 +- 队列吞吐、失败率、积压长度 +- 与 OpenTelemetry exporter 的桥接 +- 更长期的指标聚合、采样和导出 + +这些扩展不要求沿用完全相同的 summary schema,但应复用统一的 telemetry 抽象和运行时。 + +## 14. 使用示例 + +### 14.1 返回 telemetry summary + +```bash +curl -X POST http://localhost:8080/api/v1/search/find \ + -H 'Content-Type: application/json' \ + -d '{ + "query": "memory dedup", + "limit": 5, + "telemetry": true + }' +``` + +### 14.2 只返回 summary + +```bash +curl -X POST http://localhost:8080/api/v1/search/find \ + -H 'Content-Type: application/json' \ + -d '{ + "query": "memory dedup", + "limit": 5, + "telemetry": { + "summary": true + } + }' +``` + +### 14.4 Python SDK + +```python +result = await client.find("memory dedup", telemetry={"summary": True}) + +print(result.telemetry["summary"]["tokens"]["total"]) +``` + +## 15. 新接口接入规范 + +新接口如果需要接入 operation telemetry,建议遵循以下规则: + +1. 为该操作创建 `OperationTelemetry` collector。 +2. 用上下文绑定覆盖整个操作生命周期。 +3. 在内部关键阶段记录 counters、gauges 和错误状态。 +4. 仅在调用方请求时返回 `telemetry`。 +5. summary 只返回本次操作真实产出的分组。 + +这样可以保持默认低成本,同时为调用方提供稳定、可分析的结构化摘要。 diff --git a/docs/en/api/02-resources.md b/docs/en/api/02-resources.md index eff4d56f..e7db2931 100644 --- a/docs/en/api/02-resources.md +++ b/docs/en/api/02-resources.md @@ -45,6 +45,7 @@ Add a resource to the knowledge base. | instruction | str | No | "" | Special processing instructions | | wait | bool | No | False | Wait for semantic processing to complete | | timeout | float | No | None | Timeout in seconds (only used when wait=True) | +| watch_interval | float | No | 0 | Watch interval (minutes). >0 enables/updates watch; <=0 disables watch. Only takes effect when target is provided | **Python SDK (Embedded / HTTP)** @@ -168,6 +169,48 @@ curl -X POST http://localhost:1933/api/v1/system/wait \ openviking add-resource ./documents/guide.md --wait ``` +**Example: Watch for Updates (watch_interval)** + +`watch_interval` is in minutes and periodically triggers re-processing for the specified target URI: + +- `watch_interval > 0`: create (or reactivate and update) a watch task for the `target` +- `watch_interval <= 0`: disable (deactivate) the watch task for the `target` +- watch tasks are only managed when `target` / CLI `--to` is provided + +If there is already an active watch task for the same `target`, submitting another request with `watch_interval > 0` returns a conflict error. Disable it first (`watch_interval = 0`) and then set a new interval. + +**Python SDK (Embedded / HTTP)** + +```python +client.add_resource( + "./documents/guide.md", + target="viking://resources/documents/guide.md", + watch_interval=60, +) +``` + +**HTTP API** + +```bash +curl -X POST http://localhost:1933/api/v1/resources \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-key" \ + -d '{ + "path": "./documents/guide.md", + "target": "viking://resources/documents/guide.md", + "watch_interval": 60 + }' +``` + +**CLI** + +```bash +openviking add-resource ./documents/guide.md --to viking://resources/documents/guide.md --watch-interval 60 + +# Disable watch +openviking add-resource ./documents/guide.md --to viking://resources/documents/guide.md --watch-interval 0 +``` + --- ### export_ovpack() diff --git a/docs/en/api/05-sessions.md b/docs/en/api/05-sessions.md index b0df222e..1e9bd423 100644 --- a/docs/en/api/05-sessions.md +++ b/docs/en/api/05-sessions.md @@ -328,6 +328,71 @@ openviking session add-message a1b2c3d4 --role user --content "How do I authenti --- +### used() + +Record actually used contexts and skills in the session. When `commit()` is called, `active_count` is updated based on this usage data. + +**Parameters** + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| contexts | List[str] | No | None | List of context URIs that were actually used | +| skill | Dict[str, Any] | No | None | Skill usage record with keys: `uri`, `input`, `output`, `success` | + +**Python SDK (Embedded / HTTP)** + +```python +session = client.session(session_id="a1b2c3d4") +session.load() + +# Record used contexts +session.used(contexts=["viking://resources/docs/auth/"]) + +# Record used skill +session.used(skill={ + "uri": "viking://skills/search-web/", + "input": {"query": "OAuth"}, + "output": "Results...", + "success": True +}) +``` + +**HTTP API** + +``` +POST /api/v1/sessions/{session_id}/used +``` + +```bash +# Record used contexts +curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/used \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-key" \ + -d '{"contexts": ["viking://resources/docs/auth/"]}' + +# Record used skill +curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/used \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-key" \ + -d '{"skill": {"uri": "viking://skills/search-web/", "input": {"query": "OAuth"}, "output": "Results...", "success": true}}' +``` + +**Response** + +```json +{ + "status": "ok", + "result": { + "session_id": "a1b2c3d4", + "contexts_used": 1, + "skills_used": 0 + }, + "time": 0.1 +} +``` + +--- + ### commit() Commit a session by archiving messages and extracting memories. @@ -501,7 +566,13 @@ curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/messages \ -H "X-API-Key: your-key" \ -d '{"role": "assistant", "content": "Based on the documentation, you can configure embedding..."}' -# Step 5: Commit session +# Step 5: Record used contexts +curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/used \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-key" \ + -d '{"contexts": ["viking://resources/docs/embedding/"]}' + +# Step 6: Commit session curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/commit \ -H "Content-Type: application/json" \ -H "X-API-Key: your-key" diff --git a/docs/en/concepts/05-storage.md b/docs/en/concepts/05-storage.md index 0c14986b..74ada850 100644 --- a/docs/en/concepts/05-storage.md +++ b/docs/en/concepts/05-storage.md @@ -137,6 +137,7 @@ index_meta = { | `local` | Local persistence | | `http` | HTTP remote service | | `volcengine` | Volcengine VikingDB | +| `oceanbase` | OceanBase vector database | ## Vector Synchronization diff --git a/docs/en/concepts/07-retrieval.md b/docs/en/concepts/07-retrieval.md index 7fb73c91..4dd5f87e 100644 --- a/docs/en/concepts/07-retrieval.md +++ b/docs/en/concepts/07-retrieval.md @@ -137,6 +137,7 @@ Rerank refines candidate results in THINKING mode. - Rerank AK/SK configured - Using THINKING mode (default for search()) +- If rerank returns an invalid result or the API call fails, retrieval falls back to vector scores ### Scoring Method diff --git a/docs/en/concepts/09-transaction.md b/docs/en/concepts/09-transaction.md new file mode 100644 index 00000000..edbda724 --- /dev/null +++ b/docs/en/concepts/09-transaction.md @@ -0,0 +1,363 @@ +# Path Locks and Crash Recovery + +OpenViking uses two simple primitives — **path locks** and **redo log** — to protect the consistency of core write operations (`rm`, `mv`, `add_resource`, `session.commit`), ensuring that VikingFS, VectorDB, and QueueManager remain consistent even when failures occur. + +## Design Philosophy + +OpenViking is a context database where FS is the source of truth and VectorDB is a derived index. A lost index can be rebuilt from source data, but lost source data is unrecoverable. Therefore: + +> **Better to miss a search result than to return a bad one.** + +## Design Principles + +1. **Write-exclusive**: Path locks ensure only one write operation can operate on a path at a time +2. **On by default**: All data operations automatically acquire locks; no extra configuration needed +3. **Lock as protection**: LockContext acquires locks on entry, releases on exit — no undo/journal/commit semantics +4. **Only session_memory needs crash recovery**: RedoLog re-executes memory extraction after a process crash +5. **Queue operations run outside locks**: SemanticQueue/EmbeddingQueue enqueue operations are idempotent and retriable + +## Architecture + +``` +Service Layer (rm / mv / add_resource / session.commit) + | + v ++--[LockContext async context manager]--+ +| | +| 1. Create LockHandle | +| 2. Acquire path lock (poll+timeout) | +| 3. Execute operations (FS+VectorDB) | +| 4. Release lock | +| | +| On exception: auto-release lock, | +| exception propagates unchanged | ++---------------------------------------+ + | + v +Storage Layer (VikingFS, VectorDB, QueueManager) +``` + +## Two Core Components + +### Component 1: PathLock + LockManager + LockContext (Path Lock System) + +**PathLock** implements file-based distributed locks with two lock types — POINT and SUBTREE — using fencing tokens to prevent TOCTOU races and automatic stale lock detection and cleanup. + +**LockHandle** is a lightweight lock holder token: + +```python +@dataclass +class LockHandle: + id: str # Unique ID used to generate fencing tokens + locks: list[str] # Acquired lock file paths + created_at: float # Creation time +``` + +**LockManager** is a global singleton managing lock lifecycle: +- Creates/releases LockHandles +- Background cleanup of leaked locks (in-process safety net) +- Executes RedoLog recovery on startup + +**LockContext** is an async context manager encapsulating the lock/unlock lifecycle: + +```python +from openviking.storage.transaction import LockContext, get_lock_manager + +async with LockContext(get_lock_manager(), [path], lock_mode="point") as handle: + # Perform operations under lock protection + ... +# Lock automatically released on exit (including exceptions) +``` + +### Component 2: RedoLog (Crash Recovery) + +Used only for the memory extraction phase of `session.commit`. Writes a marker before the operation, deletes it after success, and scans for leftover markers on startup to redo. + +``` +/local/_system/redo/{task_id}/redo.json +``` + +Memory extraction is idempotent — re-extracting from the same archive produces the same result. + +## Consistency Issues and Solutions + +### rm(uri) + +| Problem | Solution | +|---------|----------| +| Delete file first, then index -> file gone but index remains -> search returns non-existent file | **Reverse order**: delete index first, then file. Index deletion failure -> both file and index intact | + +**Locking strategy** (depends on target type): +- Deleting a **directory**: `lock_mode="subtree"`, locks the directory itself +- Deleting a **file**: `lock_mode="point"`, locks the file's parent directory + +Operation flow: + +``` +1. Check whether target is a directory or file, choose lock mode +2. Acquire lock +3. Delete VectorDB index -> immediately invisible to search +4. Delete FS file +5. Release lock +``` + +VectorDB deletion fails -> exception thrown, lock auto-released, file and index both intact. FS deletion fails -> VectorDB already deleted but file remains, retry is safe. + +### mv(old_uri, new_uri) + +| Problem | Solution | +|---------|----------| +| File moved to new path but index points to old path -> search returns old path (doesn't exist) | Copy first then update index; clean up copy on failure | + +**Locking strategy** (handled automatically via `lock_mode="mv"`): +- Moving a **directory**: SUBTREE lock on both source path and destination parent +- Moving a **file**: POINT lock on both source's parent and destination parent + +Operation flow: + +``` +1. Check whether source is a directory or file, set src_is_dir +2. Acquire mv lock (internally chooses SUBTREE or POINT based on src_is_dir) +3. Copy to new location (source still intact, safe) +4. If directory, remove the lock file carried over by cp into the copy +5. Update VectorDB URIs + - Failure -> clean up copy, source and old index intact, consistent state +6. Delete source +7. Release lock +``` + +### add_resource + +| Problem | Solution | +|---------|----------| +| File moved from temp to final directory, then crash -> file exists but never searchable | Two separate paths for first-time add vs incremental update | +| Resource already on disk but rm deletes it while semantic processing / vectorization is still running -> wasted work | Lifecycle SUBTREE lock held from finalization through processing completion | + +**First-time add** (target does not exist) — handled in `ResourceProcessor.process_resource` Phase 3.5: + +``` +1. Acquire POINT lock on parent of final_uri +2. agfs.mv temp directory -> final location +3. Acquire SUBTREE lock on final_uri (inside POINT lock, eliminating race window) +4. Release POINT lock +5. Clean up temp directory +6. Enqueue SemanticMsg(lifecycle_lock_handle_id=...) -> DAG runs on final +7. DAG starts lock refresh loop (refreshes timestamp every lock_expire/2 seconds) +8. DAG complete + all embeddings done -> release SUBTREE lock +``` + +During this period, `rm` attempting to acquire a SUBTREE lock on the same path will fail with `ResourceBusyError`. + +**Incremental update** (target already exists) — temp stays in place: + +``` +1. Acquire SUBTREE lock on target_uri (protect existing resource) +2. Enqueue SemanticMsg(uri=temp, target_uri=final, lifecycle_lock_handle_id=...) +3. DAG runs on temp, lock refresh loop active +4. DAG completion triggers sync_diff_callback or move_temp_to_target_callback +5. Callback completes -> release SUBTREE lock +``` + +Note: DAG callbacks do NOT wrap operations in an outer lock. Each `VikingFS.rm` and `VikingFS.mv` has its own lock internally. An outer lock would conflict with these inner locks causing deadlock. + +**Server restart recovery**: SemanticMsg is persisted in QueueFS. On restart, `SemanticProcessor` detects that the `lifecycle_lock_handle_id` handle is missing from the in-memory LockManager and re-acquires a SUBTREE lock. + +### session.commit() + +| Problem | Solution | +|---------|----------| +| Messages cleared but archive not written -> conversation data lost | Phase 1 without lock (incomplete archive has no side effects) + Phase 2 with RedoLog | + +LLM calls have unpredictable latency (5s~60s+) and cannot be inside a lock-holding operation. The design splits into two phases: + +``` +Phase 1 — Archive (no lock): + 1. Generate archive summary (LLM) + 2. Write archive (history/archive_N/messages.jsonl + summaries) + 3. Clear messages.jsonl + 4. Clear in-memory message list + +Phase 2 — Memory extraction + write (RedoLog): + 1. Write redo marker (archive_uri, session_uri, user identity) + 2. Extract memories from archived messages (LLM) + 3. Write current message state + 4. Write relations + 5. Directly enqueue SemanticQueue + 6. Delete redo marker +``` + +**Crash recovery analysis**: + +| Crash point | State | Recovery action | +|------------|-------|----------------| +| During Phase 1 archive write | No marker | Incomplete archive; next commit scans history/ for index, unaffected | +| Phase 1 archive complete but messages not cleared | No marker | Archive complete + messages still present = redundant but safe | +| During Phase 2 memory extraction/write | Redo marker exists | On startup: redo extraction + write + enqueue from archive | +| Phase 2 complete | Redo marker deleted | No recovery needed | + +## LockContext + +`LockContext` is an **async** context manager that encapsulates lock acquisition and release: + +```python +from openviking.storage.transaction import LockContext, get_lock_manager + +lock_manager = get_lock_manager() + +# Point lock (write operations, semantic processing) +async with LockContext(lock_manager, [path], lock_mode="point"): + # Perform operations... + pass + +# Subtree lock (delete operations) +async with LockContext(lock_manager, [path], lock_mode="subtree"): + # Perform operations... + pass + +# MV lock (move operations) +async with LockContext(lock_manager, [src], lock_mode="mv", mv_dst_parent_path=dst): + # Perform operations... + pass +``` + +**Lock modes**: + +| lock_mode | Use case | Behavior | +|-----------|----------|----------| +| `point` | Write operations, semantic processing | Lock the specified path; conflicts with any lock on the same path and any SUBTREE lock on ancestors | +| `subtree` | Delete operations | Lock the subtree root; conflicts with any lock on the same path, any lock on descendants, and any SUBTREE lock on ancestors | +| `mv` | Move operations | Directory move: SUBTREE lock on both source and destination; File move: POINT lock on source parent and destination (controlled by `src_is_dir`) | + +**Exception handling**: `__aexit__` always releases locks and does not swallow exceptions. Lock acquisition failure raises `LockAcquisitionError`. + +## Lock Types (POINT vs SUBTREE) + +The lock mechanism uses two lock types to handle different conflict patterns: + +| | POINT on same path | SUBTREE on same path | POINT on descendant | SUBTREE on ancestor | +|---|---|---|---|---| +| **POINT** | Conflict | Conflict | — | Conflict | +| **SUBTREE** | Conflict | Conflict | Conflict | Conflict | + +- **POINT (P)**: Used for write and semantic-processing operations. Only locks a single directory. Blocks if any ancestor holds a SUBTREE lock. +- **SUBTREE (S)**: Used for rm and mv operations. Logically covers the entire subtree but only writes **one lock file** at the root. Before acquiring, scans all descendants and ancestor directories for conflicting locks. + +## Lock Mechanism + +### Lock Protocol + +Lock file path: `{path}/.path.ovlock` + +Lock file content (Fencing Token): +``` +{handle_id}:{time_ns}:{lock_type} +``` + +Where `lock_type` is `P` (POINT) or `S` (SUBTREE). + +### Lock Acquisition (POINT mode) + +``` +loop until timeout (poll interval: 200ms): + 1. Check target directory exists + 2. Check if target directory is locked by another operation + - Stale lock? -> remove and retry + - Active lock? -> wait + 3. Check all ancestor directories for SUBTREE locks + - Stale lock? -> remove and retry + - Active lock? -> wait + 4. Write POINT (P) lock file + 5. TOCTOU double-check: re-scan ancestors for SUBTREE locks + - Conflict found: compare (timestamp, handle_id) + - Later one (larger timestamp/handle_id) backs off (removes own lock) to prevent livelock + - Wait and retry + 6. Verify lock file ownership (fencing token matches) + 7. Success + +Timeout (default 0 = no-wait) raises LockAcquisitionError +``` + +### Lock Acquisition (SUBTREE mode) + +``` +loop until timeout (poll interval: 200ms): + 1. Check target directory exists + 2. Check if target directory is locked by another operation + - Stale lock? -> remove and retry + - Active lock? -> wait + 3. Check all ancestor directories for SUBTREE locks + - Stale lock? -> remove and retry + - Active lock? -> wait + 4. Scan all descendant directories for any locks by other operations + - Stale lock? -> remove and retry + - Active lock? -> wait + 5. Write SUBTREE (S) lock file (only one file, at the root path) + 6. TOCTOU double-check: re-scan descendants and ancestors + - Conflict found: compare (timestamp, handle_id) + - Later one (larger timestamp/handle_id) backs off (removes own lock) to prevent livelock + - Wait and retry + 7. Verify lock file ownership (fencing token matches) + 8. Success + +Timeout (default 0 = no-wait) raises LockAcquisitionError +``` + +### Lock Expiry Cleanup + +**Stale lock detection**: PathLock checks the fencing token timestamp. Locks older than `lock_expire` (default 300s) are considered stale and are removed automatically during acquisition. + +**In-process cleanup**: LockManager checks active LockHandles every 60 seconds. Handles created more than 3600 seconds ago are force-released. + +**Orphan locks**: Lock files left behind after a process crash are automatically removed via stale lock detection when any operation next attempts to acquire a lock on the same path. + +## Crash Recovery + +`LockManager.start()` automatically scans for leftover markers in `/local/_system/redo/` on startup: + +| Scenario | Recovery action | +|----------|----------------| +| session_memory extraction crash | Redo memory extraction + write + enqueue from archive | +| Crash while holding lock | Lock file remains in AGFS; stale detection auto-cleans on next acquisition (default 300s expiry) | +| Crash after enqueue, before worker processes | QueueFS SQLite persistence; worker auto-pulls after restart | +| Orphan index | Cleaned on L2 on-demand load | + +### Defense Summary + +| Failure scenario | Defense | Recovery timing | +|-----------------|--------|-----------------| +| Crash during operation | Lock auto-expires + stale detection | Next acquisition of same path lock | +| Crash during add_resource semantic processing | Lifecycle lock expires + SemanticProcessor re-acquires on restart | Worker restart | +| Crash during session.commit Phase 2 | RedoLog marker + redo | On restart | +| Crash after enqueue, before worker | QueueFS SQLite persistence | Worker restart | +| Orphan index | L2 on-demand load cleanup | When user accesses | + +## Configuration + +Path locks are enabled by default with no extra configuration needed. **The default behavior is no-wait**: if the path is locked, `LockAcquisitionError` is raised immediately. To allow wait/retry, configure the `storage.transaction` section: + +```json +{ + "storage": { + "transaction": { + "lock_timeout": 5.0, + "lock_expire": 300.0 + } + } +} +``` + +| Parameter | Type | Description | Default | +|-----------|------|-------------|---------| +| `lock_timeout` | float | Lock acquisition timeout (seconds). `0` = fail immediately if locked (default). `> 0` = wait/retry up to this many seconds. | `0.0` | +| `lock_expire` | float | Stale lock expiry threshold (seconds). Locks held longer than this by a crashed process are force-released. | `300.0` | + +### QueueFS Persistence + +The lock mechanism relies on QueueFS using the SQLite backend to ensure enqueued tasks survive process restarts. This is the default configuration and requires no manual setup. + +## Related Documentation + +- [Architecture](./01-architecture.md) - System architecture overview +- [Storage](./05-storage.md) - AGFS and vector store +- [Session Management](./08-session.md) - Session and memory management +- [Configuration](../guides/01-configuration.md) - Configuration reference diff --git a/docs/en/faq/faq.md b/docs/en/faq/faq.md index 4992480e..24a42dfe 100644 --- a/docs/en/faq/faq.md +++ b/docs/en/faq/faq.md @@ -126,6 +126,7 @@ Config files at the default path `~/.openviking/ov.conf` are loaded automaticall | `openai` | OpenAI Embedding API | | `vikingdb` | VikingDB Embedding API | | `jina` | Jina AI Embedding API | +| `ollama` | Ollama (local OpenAI-compatible server, no API key required) | Supports Dense, Sparse, and Hybrid embedding modes. diff --git a/docs/en/guides/01-configuration.md b/docs/en/guides/01-configuration.md index 568e3930..46ddabec 100644 --- a/docs/en/guides/01-configuration.md +++ b/docs/en/guides/01-configuration.md @@ -115,10 +115,10 @@ Embedding model configuration for vector search, supporting dense, sparse, and h | Parameter | Type | Description | |-----------|------|-------------| | `max_concurrent` | int | Maximum concurrent embedding requests (`embedding.max_concurrent`, default: `10`) | -| `provider` | str | `"volcengine"`, `"openai"`, `"vikingdb"`, or `"jina"` | +| `provider` | str | `"volcengine"`, `"openai"`, `"vikingdb"`, `"jina"`, or `"voyage"` | | `api_key` | str | API key | | `model` | str | Model name | -| `dimension` | int | Vector dimension | +| `dimension` | int | Vector dimension. For Voyage, this maps to `output_dimension` | | `input` | str | Input type: `"text"` or `"multimodal"` | | `batch_size` | int | Batch size for embedding requests | @@ -136,6 +136,7 @@ With `input: "multimodal"`, OpenViking can embed text, images (PNG, JPG, etc.), - `volcengine`: Volcengine Embedding API - `vikingdb`: VikingDB Embedding API - `jina`: Jina AI Embedding API +- `voyage`: Voyage AI Embedding API **vikingdb provider example:** @@ -175,6 +176,39 @@ Available Jina models: Get your API key at https://jina.ai +**voyage provider example:** + +```json +{ + "embedding": { + "dense": { + "provider": "voyage", + "api_key": "pa-xxx", + "api_base": "https://api.voyageai.com/v1", + "model": "voyage-4-lite", + "dimension": 1024 + } + } +} +``` + +Supported Voyage text embedding models include: +- `voyage-4-lite` +- `voyage-4` +- `voyage-4-large` +- `voyage-code-3` +- `voyage-context-3` +- `voyage-3` +- `voyage-3.5` +- `voyage-3.5-lite` +- `voyage-finance-2` +- `voyage-law-2` + +If `dimension` is omitted, OpenViking uses the model's default output dimension when creating the vector schema. + +OpenViking currently configures a single dense embedder for both indexing and query-time retrieval, so provider-specific query/document modes are not exposed in config yet. +OpenViking also expects dense float vectors throughout storage and retrieval, so Voyage quantized output dtypes are not exposed in config. + **Local deployment (GGUF/MLX):** Jina embedding models are open-weight and available in GGUF and MLX formats on [Hugging Face](https://huggingface.co/jinaai). You can run them locally with any OpenAI-compatible server (e.g. llama.cpp, MLX, vLLM) and point the `api_base` to your local endpoint: ```json @@ -193,13 +227,15 @@ Get your API key at https://jina.ai #### Sparse Embedding +> **Note:** Volcengine sparse embedding is supported starting from model `doubao-embedding-vision-250615`. + ```json { "embedding": { "sparse": { "provider": "volcengine", "api_key": "your-api-key", - "model": "bm25-sparse-v1" + "model": "doubao-embedding-vision-250615" } } } @@ -238,7 +274,7 @@ Two approaches are supported: "sparse": { "provider": "volcengine", "api_key": "your-api-key", - "model": "bm25-sparse-v1" + "model": "doubao-embedding-vision-250615" } } } @@ -267,6 +303,7 @@ Vision Language Model for semantic extraction (L0/L1 generation). | `api_base` | str | API endpoint (optional) | | `thinking` | bool | Enable thinking mode for VolcEngine models (default: `false`) | | `max_concurrent` | int | Maximum concurrent semantic LLM calls (default: `100`) | +| `extra_headers` | object | Custom HTTP headers (for OpenAI-compatible providers, optional) | **Available Models** @@ -282,6 +319,30 @@ When resources are added, VLM generates: If VLM is not configured, L0/L1 will be generated from content directly (less semantic), and multimodal resources may have limited descriptions. +**Custom HTTP Headers** + +For OpenAI-compatible providers (e.g., OpenRouter), you can add custom HTTP headers via `extra_headers`: + +```json +{ + "vlm": { + "provider": "openai", + "api_key": "your-api-key", + "model": "gpt-4o", + "api_base": "https://openrouter.ai/api/v1", + "extra_headers": { + "HTTP-Referer": "https://your-site.com", + "X-Title": "Your App Name" + } + } +} +``` + +Common use cases: +- **OpenRouter**: Requires `HTTP-Referer` and `X-Title` to identify your application +- **Custom proxies**: Add authentication or tracing headers +- **API gateways**: Add version or routing identifiers + ### code Controls how code files are summarized via `code_summary_mode`. Both config formats are equivalent: @@ -479,14 +540,13 @@ Supports S3 storage in VirtualHostStyle mode, such as TOS. - #### vectordb Vector database storage configuration | Parameter | Type | Description | Default | |-----------|------|-------------|---------| -| `backend` | str | VectorDB backend type: 'local' (file-based), 'http' (remote service), 'volcengine' (cloud VikingDB), or 'vikingdb' (private deployment) | "local" | +| `backend` | str | VectorDB backend: 'local', 'http', 'volcengine', 'vikingdb', or 'oceanbase' (OceanBase) | "local" | | `name` | str | VectorDB collection name | "context" | | `url` | str | Remote service URL for 'http' type (e.g., 'http://localhost:5000') | null | | `project_name` | str | Project name (alias project) | "default" | @@ -495,6 +555,7 @@ Vector database storage configuration | `sparse_weight` | float | Sparse weight for hybrid vector search, only effective when using hybrid index | 0.0 | | `volcengine` | object | 'volcengine' type VikingDB configuration | - | | `vikingdb` | object | 'vikingdb' type private deployment configuration | - | +| `oceanbase` | object | OceanBase config when backend is 'oceanbase' | - | Default local mode ``` @@ -528,6 +589,29 @@ Supports cloud-deployed VikingDB on Volcengine ``` +
+OceanBase (oceanbase) +Use [OceanBase](https://www.oceanbase.com/) as the vector backend. See [OceanBase integration guide](./06-oceanbase-integration.md) for installation and configuration. + +```json +{ + "storage": { + "vectordb": { + "name": "context", + "backend": "oceanbase", + "distance_metric": "cosine", + "oceanbase": { + "uri": "127.0.0.1:2881", + "user": "root@test", + "password": "your-password", + "db_name": "test" + } + } + } +} +``` +
+ ## Config Files @@ -603,6 +687,28 @@ When `root_api_key` is configured, the server enables multi-tenant authenticatio For startup and deployment details see [Deployment](./03-deployment.md), for authentication see [Authentication](./04-authentication.md). +## storage.transaction Section + +Path locks are enabled by default and usually require no configuration. **The default behavior is no-wait**: if the target path is already locked by another operation, the operation fails immediately with `LockAcquisitionError`. Set `lock_timeout` to a positive value to allow polling/retry. + +```json +{ + "storage": { + "transaction": { + "lock_timeout": 5.0, + "lock_expire": 300.0 + } + } +} +``` + +| Parameter | Type | Description | Default | +|-----------|------|-------------|---------| +| `lock_timeout` | float | Path lock acquisition timeout (seconds). `0` = fail immediately if locked (default). `> 0` = wait/retry up to this many seconds, then raise `LockAcquisitionError`. | `0.0` | +| `lock_expire` | float | Stale lock expiry threshold (seconds). Locks held longer than this by a crashed process are force-released. | `300.0` | + +For details on the lock mechanism, see [Path Locks and Crash Recovery](../concepts/09-transaction.md). + ## Full Schema ```json @@ -623,7 +729,8 @@ For startup and deployment details see [Deployment](./03-deployment.md), for aut "model": "string", "api_base": "string", "thinking": false, - "max_concurrent": 100 + "max_concurrent": 100, + "extra_headers": {} }, "rerank": { "provider": "volcengine", @@ -637,6 +744,10 @@ For startup and deployment details see [Deployment](./03-deployment.md), for aut "url": "string", "timeout": 10 }, + "transaction": { + "lock_timeout": 0.0, + "lock_expire": 300.0 + }, "vectordb": { "backend": "local|remote", "url": "string", diff --git a/docs/en/guides/06-mcp-integration.md b/docs/en/guides/06-mcp-integration.md new file mode 100644 index 00000000..e8516101 --- /dev/null +++ b/docs/en/guides/06-mcp-integration.md @@ -0,0 +1,230 @@ +# MCP Integration Guide + +OpenViking can be used as an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server, allowing any MCP-compatible client to access its memory and resource capabilities. + +## Transport Modes + +OpenViking supports two MCP transport modes: + +| | HTTP (SSE) | stdio | +|---|---|---| +| **How it works** | Single long-running server process; clients connect via HTTP | Host spawns a new OpenViking process per session | +| **Multi-session safe** | ✅ Yes — single process, no lock contention | ⚠️ **No** — multiple processes contend for the same data directory | +| **Recommended for** | Production, multi-agent, multi-session | Single-session local development only | +| **Setup complexity** | Requires running `openviking-server` separately | Zero setup — host manages the process | + +### Choosing the Right Transport + +- **Use HTTP** if your host opens multiple sessions, runs multiple agents, or needs concurrent access. +- **Use stdio** only for single-session, single-agent local setups where simplicity is the priority. + +> ⚠️ **Important:** When an MCP host spawns multiple stdio OpenViking processes (e.g., one per chat session), all instances compete for the same underlying data directory. This causes **lock/resource contention** in the storage layer (AGFS and VectorDB). +> +> Symptoms include misleading errors such as: +> - `Collection 'context' does not exist` +> - `Transport closed` +> - Intermittent search failures +> +> **The root cause is not a broken index** — it is multiple processes contending for the same storage files. Switch to HTTP mode to resolve this. See [Troubleshooting](#troubleshooting) for details. + +## Setup + +### Prerequisites + +1. OpenViking installed (`pip install openviking` or from source) +2. A valid configuration file (see [Configuration Guide](01-configuration.md)) +3. For HTTP mode: `openviking-server` running (see [Deployment Guide](03-deployment.md)) + +### HTTP Mode (Recommended) + +Start the OpenViking server first: + +```bash +openviking-server --config /path/to/config.yaml +# Default: http://localhost:1933 +``` + +Then configure your MCP client to connect via HTTP. + +### stdio Mode + +No separate server needed — the MCP host spawns OpenViking directly. + +## Client Configuration + +### Claude Code (CLI) + +**HTTP mode:** + +```bash +claude mcp add openviking \ + --transport sse \ + "http://localhost:1933/mcp" +``` + +**stdio mode:** + +```bash +claude mcp add openviking \ + --transport stdio \ + -- python -m openviking.server --transport stdio \ + --config /path/to/config.yaml +``` + +### Claude Desktop + +Edit `claude_desktop_config.json`: + +**HTTP mode:** + +```json +{ + "mcpServers": { + "openviking": { + "url": "http://localhost:1933/mcp" + } + } +} +``` + +**stdio mode:** + +```json +{ + "mcpServers": { + "openviking": { + "command": "python", + "args": [ + "-m", "openviking.server", + "--transport", "stdio", + "--config", "/path/to/config.yaml" + ] + } + } +} +``` + +### Cursor + +In Cursor Settings → MCP: + +**HTTP mode:** + +```json +{ + "mcpServers": { + "openviking": { + "url": "http://localhost:1933/mcp" + } + } +} +``` + +**stdio mode:** + +```json +{ + "mcpServers": { + "openviking": { + "command": "python", + "args": [ + "-m", "openviking.server", + "--transport", "stdio", + "--config", "/path/to/config.yaml" + ] + } + } +} +``` + +### OpenClaw + +In your OpenClaw configuration (`openclaw.json` or `openclaw.yaml`): + +**HTTP mode (recommended):** + +```json +{ + "mcp": { + "servers": { + "openviking": { + "url": "http://localhost:1933/mcp" + } + } + } +} +``` + +**stdio mode:** + +```json +{ + "mcp": { + "servers": { + "openviking": { + "command": "python", + "args": [ + "-m", "openviking.server", + "--transport", "stdio", + "--config", "/path/to/config.yaml" + ] + } + } + } +} +``` + +## Available MCP Tools + +Once connected, OpenViking exposes the following MCP tools: + +| Tool | Description | +|------|-------------| +| `search` | Semantic search across memories and resources | +| `add_memory` | Store a new memory | +| `add_resource` | Add a resource (file, text, URL) | +| `get_status` | Check system health and component status | +| `list_memories` | Browse stored memories | +| `list_resources` | Browse stored resources | + +Refer to OpenViking's tool documentation for full parameter details. + +## Troubleshooting + +### `Collection 'context' does not exist` + +**Likely cause:** Multiple stdio MCP instances contending for the same data directory. + +**Fix:** Switch to HTTP mode. If you must use stdio, ensure only one OpenViking process accesses a given data directory at a time. + +### `Transport closed` + +**Likely cause:** The MCP stdio process crashed or was killed due to resource contention. Can also occur when a client holds a stale connection after the backend was restarted. + +**Fix:** +1. Switch to HTTP mode to avoid contention. +2. If using HTTP: reload the MCP connection in your client (restart the session or reconnect). + +### Connection refused on HTTP endpoint + +**Likely cause:** `openviking-server` is not running, or is running on a different port. + +**Fix:** Verify the server is running: + +```bash +curl http://localhost:1933/health +# Expected: {"status": "ok"} +``` + +### Authentication errors + +**Likely cause:** API key mismatch between client config and server config. + +**Fix:** Ensure the API key in your MCP client configuration matches the one in your OpenViking server configuration. See [Authentication Guide](04-authentication.md). + +## References + +- [MCP Specification](https://modelcontextprotocol.io/) +- [OpenViking Configuration](01-configuration.md) +- [OpenViking Deployment](03-deployment.md) +- [Related issue: stdio contention (#473)](https://github.com/volcengine/OpenViking/issues/473) diff --git a/docs/en/guides/06-oceanbase-integration.md b/docs/en/guides/06-oceanbase-integration.md new file mode 100644 index 00000000..5c181575 --- /dev/null +++ b/docs/en/guides/06-oceanbase-integration.md @@ -0,0 +1,274 @@ +# OpenViking and OceanBase Integration + +This guide describes how to use [OceanBase](https://www.oceanbase.com/) as the vector store backend for OpenViking, with **official step-by-step tutorials** you can run from scratch. + +--- + +## Overview + +- Connection is via [pyobvector](https://github.com/oceanbase/pyobvector) and OceanBase’s vector tables and HNSW index. +- Set `storage.vectordb.backend` to `"oceanbase"` and fill in the `oceanbase` connection block in config. +- Suitable when you want context indexes in a relational/HTAP database or to reuse an existing OceanBase deployment. + +**Prerequisites**: OceanBase 4.3.3.0+ (with vector type and index support); install `pyobvector` or `openviking[oceanbase]`. + +--- + +## Installation and configuration + +### Install + +```bash +# Option 1: pyobvector only (if openviking is already installed) +pip install pyobvector + +# Option 2: openviking with oceanbase extra (recommended) +pip install openviking[oceanbase] +``` + +### Configuration example (ov.conf) + +In `~/.openviking/ov.conf`, set `storage.vectordb` and the `oceanbase` block: + +```json +{ + "storage": { + "vectordb": { + "name": "context", + "backend": "oceanbase", + "distance_metric": "l2", + "oceanbase": { + "uri": "127.0.0.1:2881", + "user": "root@test", + "password": "", + "db_name": "openviking" + } + } + } +} +``` + +> **Note**: When using Docker OceanBase (slim mode), set `distance_metric` to `"l2"`. For OceanBase versions that support cosine, you can use `"cosine"`. See [Configuration](./01-configuration.md#vectordb) for full options. + +OpenViking creates the collection and index on first write or server start; no manual table creation is required. + +--- + +## Tutorial 1: Run OpenViking + OceanBase in 5 minutes + +This tutorial mirrors the [Quick Start](../getting-started/02-quickstart.md): from starting OceanBase to performing one semantic search, with runnable steps and expected output. + +### Step 1: Start OceanBase (Docker) + +If you don’t have OceanBase installed, start a single-node instance with Docker (first run may pull the image; boot can take a few minutes): + +```bash +# Start container (port 2881) +docker run -d -p 2881:2881 --name oceanbase-ce -e MODE=slim oceanbase/oceanbase-ce + +# Wait until boot completes (look for "boot success!" in logs) +docker logs oceanbase-ce 2>&1 | tail -5 + +# Create database (root@test tenant) +docker exec -it oceanbase-ce mysql -h127.0.0.1 -P2881 -uroot@test -e "CREATE DATABASE IF NOT EXISTS openviking;" +``` + +If you use an existing OceanBase instance, ensure the database in `oceanbase.db_name` exists and that the host can connect with the given user and password. + +### Step 2: Prepare configuration + +Ensure `~/.openviking/ov.conf` includes **embedding** (same as [Quick Start](../getting-started/02-quickstart.md)) and **storage.vectordb (OceanBase)**. Minimal example (replace embedding api_key, model, etc. with your values): + +```json +{ + "embedding": { + "dense": { + "api_base": "", + "api_key": "", + "provider": "", + "dimension": 1024, + "model": "" + } + }, + "storage": { + "vectordb": { + "name": "context", + "backend": "oceanbase", + "distance_metric": "l2", + "oceanbase": { + "uri": "127.0.0.1:2881", + "user": "root@test", + "password": "", + "db_name": "openviking" + } + } + } +} +``` + +Full examples per provider are in [Configuration guide - Examples](./01-configuration.md#configuration-examples). + +### Step 3: Create the example script + +Create `example_oceanbase.py` (same flow as Quick Start, with vector store set to OceanBase): + +```python +import openviking as ov + +# Uses default config ~/.openviking/ov.conf (vectordb backend = oceanbase) +client = ov.OpenViking(path="./data") + +try: + client.initialize() + + # Add resource (URL, file, or directory) + add_result = client.add_resource( + path="https://raw.githubusercontent.com/volcengine/OpenViking/refs/heads/main/README.md" + ) + root_uri = add_result["root_uri"] + + # List resource structure + ls_result = client.ls(root_uri) + print(f"Directory structure:\n{ls_result}\n") + + # Wait for semantic processing (vectors written to OceanBase) + print("Waiting for semantic processing...") + client.wait_processed() + + # Get abstract and overview + abstract = client.abstract(root_uri) + overview = client.overview(root_uri) + print(f"Abstract:\n{abstract}\n\nOverview:\n{overview}\n") + + # Semantic search (vector search is performed against OceanBase) + results = client.find("what is openviking", target_uri=root_uri) + print("Search results:") + for r in results.resources: + print(f" {r.uri} (score: {r.score:.4f})") + + client.close() + +except Exception as e: + print(f"Error: {e}") +``` + +### Step 4: Run + +```bash +python example_oceanbase.py +``` + +### Step 5: Expected output + +``` +Directory structure: +... + +Waiting for semantic processing... +Abstract: +... + +Overview: +... + +Search results: + viking://resources/... (score: 0.xxxx) + ... +``` + +You have now run OpenViking with OceanBase as the vector store. Content is still stored in local AGFS (`path="./data"`); vectors and metadata are stored in OceanBase. + +--- + +## Tutorial 2: Enterprise knowledge base (batch import + scoped search) + +This tutorial shows: importing multiple resources, then searching by natural language within a URI prefix—suitable for internal docs, Wiki, or knowledge bases. + +### Step 1: Prepare content and config + +- OceanBase is running and the database exists (same as Tutorial 1). +- `ov.conf` has `storage.vectordb.backend` set to `oceanbase` and valid embedding and oceanbase connection settings. + +### Step 2: Batch import and search + +Create `example_knowledge_base.py`: + +```python +import openviking as ov + +client = ov.OpenViking(path="./data") +client.initialize() + +# Batch add resources (local directory or URL) +client.add_resource("/path/to/your/wiki") # local directory +client.add_resource("https://example.com/doc.md") # or URL +client.wait_processed() + +# Semantic search within a URI prefix (useful for multi-tenant or per-project scope) +results = client.find( + "user login and authentication flow", + target_uri="viking://resources/", + limit=5 +) + +print(f"Total: {results.total} result(s)") +for ctx in results.resources: + print(f" {ctx.uri}") + print(f" score={ctx.score:.3f} abstract={ctx.abstract[:80]}...") + print() + +client.close() +``` + +Replace `/path/to/your/wiki` with your doc root or remove that line to use only the URL. Then run: + +```bash +python example_knowledge_base.py +``` + +Using `target_uri="viking://resources/"` limits search to the resource tree; different tenants can use different prefixes (e.g. `viking://resources/tenant-a/`) for logical isolation. + +--- + +## Docker quick reference + +| Step | Command | +|------|---------| +| Start OceanBase | `docker run -d -p 2881:2881 --name oceanbase-ce -e MODE=slim oceanbase/oceanbase-ce` | +| Wait for ready | `docker logs oceanbase-ce 2>&1 \| tail -1` until you see `boot success!` | +| Create DB | `docker exec -it oceanbase-ce mysql -h127.0.0.1 -P2881 -uroot@test -e "CREATE DATABASE IF NOT EXISTS openviking;"` | + +Set `oceanbase.uri: "127.0.0.1:2881"` and `oceanbase.db_name: "openviking"` in config. + +--- + +## Distance metrics and versions + +| distance_metric | Description | +|----------------|-------------| +| `cosine` | Mapped to neg_ip where supported by your OceanBase version | +| `l2` / `ip` | Map directly to OceanBase L2 / IP distance | + +If you see "this type of vector index distance algorithm is not supported", set `distance_metric` to `"l2"` (recommended for Docker slim mode). + +--- + +## Running integration tests + +OceanBase tests in this repo start OceanBase via Docker by default; no local OceanBase installation is required: + +```bash +# Requires Docker; will pull and start oceanbase/oceanbase-ce +pytest tests/vectordb/test_oceanbase_live.py -v -s +# or +python -m unittest tests.vectordb.test_oceanbase_live -v +``` + +--- + +## See also + +- [Configuration](./01-configuration.md) — `storage.vectordb` and common options for all backends +- [Storage architecture](../concepts/05-storage.md) — role of the vector store in OpenViking +- [Quick Start](../getting-started/02-quickstart.md) — get started with OpenViking (default local vector store) +- [OceanBase integration (Chinese)](../../zh/guides/06-oceanbase-integration.md) — 中文版本文档 diff --git a/docs/images/wechat-group-qrcode.png b/docs/images/wechat-group-qrcode.png index 5c0945e408a88beec91b27c9c3c2d9615e5bc000..f04aca2ebafa8f958d6e90229d6e8354f5386c56 100644 GIT binary patch literal 1068829 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

|%N)Y8UZ8 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

ot3LxpBf4$!M*_pV(I&A(iUcTFlU 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∓fqsulUuy$g@a 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

C8PmpKXt=%BJbcG0Yr8r4+z` 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�wCZt?aP@UKQ{`;R_#&L@g^XHJfkq>40hTBLX2{h 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

9MdS^akF+xFHbOe3oVXTez8H+ zk-0#idPdJ&ySeGPhdV_jB@be5MoPeJo+PZ-pR)oi4}J@)Xcvi&1{3uwRz17Y^Z}sE z*_Fxy1Q$K1+Cx_u93X1xod1~u`Rku2VOP2>lVBcV$K}K@l&k4rDPo3s4R18+=t|BH3EYNbL;F>{bXFxo3qG; z>@MWbfh&JCDCL}MH0tEwhpA&4V;=a+T0fcWEobFteoVyWz9MjK{?y^;IunnNL5`7_ z!G!GWZQ?SLab(#H#f<2`jDA~p!99YK96|QJbhd7A112pPjNE}d&& zy64|S(FO(H9kb}JWJF(YJ?{))xi;p%t9uPfZUc*G&3tmGx|k^q&)14lnpIy}u~+>e zHM;7uvPmTlnMc1^j*TilYPE6&Z)b0&%^WQfb82dDJUL4yU`}?$^sbHx3h3u=k^rHP zaVkvDL10%5EuEgN?a%%RDr$4&FWDvdb_q|JYt%lU&1Z7Hi@ULZDBB{YzTY9#8x}VF zt}p&)WzVX!N0$+CR`~l$ckT^#F^Tz_Sv+UtX-We6sC{YsFaL&B<=%iEtZ8rH!<8fe z`_2B@u#BDS)!?1a5CiZLh6SZK-7X@|GqGrJ({_#tV`SLc-;BIZ(vifM;Zo zuR+RAaqXt<-{_A>6jAxj@JK$I@8!b4>kh^Fj3Cc@ZAW0RbYqgcQ&PdOjIDc|YBe5Z zr4~RM7W||&1Uza0O8Bg@^3;{o)kaiTEZg*IzS43&7Vzx2xt+KqbXlF){%NnOeHby& zYU~D2S9LDCL+<+cdCSkB>{U=sZL)E?^e8bRSAsx@Hr{v(TEX0pcW&f~M zSUBEX-P#lTp?`n+Q^#HbU%{g{B9i+B^GTXe=F1Gn!h2RNCd2Jp`B3y_VR5wKGVZ~Q zPN|kabj0R<=4NX3(E

kgAk)wdwXH=2Pe>uV2kdUdzozQ6X<-8^z+zIjyw&8O^=Y zRkoN&XYUb|CDNO9CP&>M5>79v04x7)iYnxko+}Se5`i$!K!WGu#ZZ-6a!_!`*B<0_ zKY?wEE9BzPMGZj6>_>@d`u>lJkrG_6IS%v{hkV~g;?i$Vv6wnpiG1pfI|G_$BQi^y~hsrbgooDtt57*lW;D~c{Q_6f&( zea==vFSA?fg$7Z=C3SvyN{Kld|KoWB@RGfNVsoYG?GF~YESC;*2GFvIBIa<1$^5M; z@%R80z9(<0lMtQ8$PX@^LaGk>Z(}(7MJvhG?#`h~uNB_b5|Fl-FfT23 z$_=I#Df`~u$x2*R6md82zd2M~$^tgAt$uZjHexOZM>=$(*U%P|i>t{GcL3_dL ziouMM@!KWS0FKhqQqh?`*oRNx80`eav;v0ic_m>4YTS3%vcM{f37gKXz41ru63M$a)j6&-D-&_nPw0 zmsR?@PLV@7tFw61F(14RzLIZ?jebU!)vUWN;GavVDjZnO>!mKFc~)7)EKVSZs~j13 zrG0Dkk2}J)G(OM?1ksHr?|x3_&)oJ+RdkLq9v%R6c`mc5z2~&---u|?o#-A-I644N z;|Kjkc@d2RoTK!BP^n?E7sI?`JPn} zoZPWI5RTMXwC^9b~*kGCcW6&*o6^ zCcVN4*&NwPd$DW8EIiU6;O5?Y%Qm#A-UAvcO>(Sfd~FhdSZjmlsiro$|Aju&fll+QVgguNSJ3tJGrE9tt}15~aT1xiFsFGkrL{ zmm*ffYu2aEaBWg<<+im`;=?zJZ!`C*m;MUt6?`ey70R8FQ>geNSv>MVtQ|gotD&pU zq`Gn;30)qphx}ORMuE#zbGu%Y@xD{DaIiKeHzn8`;mOo|XQw%F9{xgTu^4sFM zwmVKU!58#r*lX|%6R>K6K zvH>;{9^P}w(UQjpBXzaa%4{`&H#^^KAT_y$B7LekYn?n|p9*fbf;A_hAA~ z#mwuov>F?8t*PD_MFq2Y_r(jir!1EPxujU?Pu{<@b;`PCthwyuh9oLrEBboZAg~7K zapQZk^7oYx_SUvsi{-)3Ep0Pq0Ly2vW)EUn>5pL_cl>u$P2TKB&>Td~0i1)TD=w=$ zUjM+K_pN(qTLcndoO18^2TJ!Y&$GM4FINM0kCT5aPHoCtjIy*|Jv;@LTmE&A%cWR^ zrRx$ZFB@hn3}sw6aRQhT>N76M*F01nDdrHpK?)U5A2J<}btlMcOVy|;QA@@2E81&AJ01#p!Nf8*q{z}b8fjbL51V9T3zMYZq<-E;f^_Ab=;S6$yvb)iC0FVPNUzPnzYw44oxk%Jzh}3u@rZ$R^vOF4 z+}n37u>O{Z>rjNVqdUda@A>XinQQIFDO{hy*(ZR}_ekb>viBulP|LFYizFE%uFZh? zF2!!XZJEbI9Kl1`VV6B~1jQVvBz&;SbKzO;K*>FO06mh|mMm$`mV6m#RZ)9%$7EP>&qsoc7p-c|8~#2~w?oun^y zx=BID5-UPp55Q_l`;NR>ep9)x4T6J5I&}~^!S-)h@NXC=)3Se>E1>yTGG}-3p;`jL z{XFVFF>7>?@wXG*d~0l&MU6Nq;&s$3XnNwbe85=snM~{)OP`1r$C$$HpRRW-EJ!9R z1IEYV^Q@!}U|ekEEt}zo$ic^{)jNW&kIY|MX2l;2CdU3BTYE?`L%aYl9 zH>k6kQ8;bn-jL*ztt9}pdZhRkibsRhU`+!xKFid?95lH?LuEA08t(+cFZ~n;`#j-u zgx`g>`Uj^n7PBC^T7#&oy3SP&=0iJ@ILC-tg$gB1y1gB!pUJ5bvK*V0wQXo$*j)3P zYgpK-h9NO;>yA~4m3JS|OPX2Bxh}6OC*<_f?7T2=|EUQOeGP4+sMGX1X3)H|)jICu z=)hksn_c=~0!JMWVs4MwOd4Vw$`*Gt8&Z5VDh&!ZzA&~VvyRdk1g z-{Yzl$+pn4YD7vYKp5kcZU0IvbF)jJR@yFj$L3SbsmggyV9m-Atyc9xYKLRRPDdM+ zIChG%d_m`-Wn8i{p?N@Z!O)*{u^s;TGBM(``mxx7cG)H1n~w%LbzCU?i=@c-W--?c z$Xt#VR>a`UQ_AhgdTNH(diaR?BO>UT$toV7(R?hPD^sgBMWuJ);Eyw?|^rty;M zaFN`wL+-HGPE1F$m;Bt<&0jWY+Wcrktm{}0M&3PmEe*-5oBONq3hs32R~aMKev{*k zNMz;qad73QjTwLE8^XItyvv<=)QC`WDM)P$5;Wd4^@ix9ZH=R!*Xz`(tsd>5y6pBx z#lLD+P_mNmn?!TZxOGA$kW1BsK?|Gi<>%ce<0?+L4V22cDsJR&24CvowOJDzc~V+# zR={{7kK6Tmnsr_R{*GPTUC5%PSCa4JpOkF%gKVJ@6LwzKGdkmfW6`gOUY!X6s;+{g zulS}SB62jTOGnn1!-0eG>Fp_XN6E}r9eLBM_uuoYCa=z((B%=!SM*W)`56q}e#i2< z%(uIVsh~qRAmznr%6{yXWY6Zp7QWlyl4=Xw%s~aCk*!?}am9yP(a=uoB;5r0M#)!& z2{=Cs5?jj{72O_W_|O1?4VyU81tiBK5U zZaqCr;HQW622C5cN;N=uQKj$FrRH@XDH-7lmQ>%g6Z`II+SLhx-Oyeu%Tr_g||wCGK69VMv=_=x#O$LS!Y zwqKVy5~7|RbAJSQNCdjTmEYKwe}P6u=YCTA-0|YFj&esq*V~9>->~M6G~B#UU9kuf z5#xY9vJFp!v{mLOnc&vpG4#ge*<^o#0yn*ty3e3>L6~;NQ{jX6yNyfR%E5C3R_&NX zptZFL!s4RBs=DgI>GzOr&qBcbB%+3e0mW(P-NN|h6=$D1 zU+AQ~*qbhra`~NuDWZC(`@tn*-cge~Xub2rpH zjL5L7DlI@@^+>I`S3WVwqddehIk6Y|fzMkw0F%^8qI|78__`3A6?3>|^qq}=r@26W zn)(a&*NQQDcDzzU=(g{o32}f$l-`ue$Y^1P>C$)C6;?hy2F4>XNtlq9`P&r3vS%S1=aU!3f*XVv`{araBG~!bllQ~)7gws z!{vKWMNZW+QRhFZhX}X`W+#vsIi07T%nZD75qb2a9NIjmujbJ;0RG zn==sf9VK;4K`ii2jnH2IwKUn>^EtsC(H5{Pht8yM`Ag!b=8O3NUrVXW1Z)Mzuo4l^ zbsJ`(?Ctipzk2E4NQbFuk$eh+EM=NyxnJt++)BW;w{{77DsjB<=cp*hn!MRK{<>42 z6!o{tkpg_{B2o;&)owo@eKP6%+5J0BzwkLTEY#OiC_2I0HQkO$;KrpS7OdHo1YDH$ zLBE*FEk}kh2*Xh$=;&rcgqw%IG8BdFXn??pNiF!l;qp>MKM)LN0NwBV^yT0G3t$2N zFm^`iG0D{@`UNk2U$km~%yN5H;q?Y?{zgK>3;q2&Nk^fIVCFaN36V`YfXB@;qLg0B zetyS?9wWPOl@r8dcDsy(ztu^v(jxR$t;sL$CLFD}C3T&em}7KXJxOjP1iUreSNr^# zpUw1YQc!TGHX_-RpiG#v(9>aL$P(KmV8SHdKcS?gkC!b7b<0Zh zaH8Aw>$EqbdxwVOa`(qjh47uPU36B;OlQ^AA)~!Fm}Cu?vw2g$RSi6eJ#Bw$`hCe2 zwbTQ&O!#p|m;g)k8BTOCX?w?9L7D0A$@eNQo+_jE77qdbr{z4-EB#pQ!9~MAo`iFc zJg~#asB@(u_ECrmmq%$y?J_J+>HMdh8H4RJ2}WtL?pv|)#{J)*9~vN$B?SR3X_~{9 z)9mu`7}Ml?VEAI%^53FrICqcKy`Mk&rz+(w>p<_rwqJli-@8A&m_kcCGz&wV>EF=m zWuzUt3;mc6Vn?&~U|)geCs8in6BWtYGU=UT0j#%>M#T1-;8l2?{pI9wECF8>N%p)UB|biDFxAFnw$H{6T8)?n2#<)hDwwo{|6eqndpwhW{QfIy z3Y$_6nR85^Voo{5M$(eQDjy-|QxbC4Fq7kw!)Sys=cI(3&*z-a=R?kOm{ZI!bNcS{ z`+dLv@3BAb-Fx4!*L6Lw>t@rX-i*8v&{K96nqNxK<$AD|95Y`?RAr&&>j<>Jr|X9A z``AuNsi!12ftGP5XHjO-c55Z40WvMDi}9AO;TGObG+Vn}l*e-KQeoIsFfsaf0Bexw zj?{CYL?e^&Hclu)>(P0ZZ;ZhTNg z(Hxf__YP1-dBAG^cS5@SajbETtf%7ikhzfpn#!$Rm+O#j7t^Vbi6@8U#B07x@Re39 zB6b+`DjY^bdAY$D(yom*N*F@s#u5TC>&9p1iWR>SCf0yC;7hi85=j=soaD&}bgZUA z$^sW!(f~(z=_b&oP&${6lQz10`|S5y!E??&7ahn7OAng#Bw)|Wh!8>)bxCkm+1n%c z2P7$E;GQ&zSF!02B=2FwYAV^i(R5(MIr)f!sA!&4BS7w!vh(BtS-Er8VzefQjn|?< zD@08KI)*k}M{T;xSHj72PcDD)E+HgGe6%P$E#x$Enu+iKt+(r-drL6uL1lBUoU=q^ z_Z`~TI&2GxhxX}E(yz<-(@bvHe#>LC9U0xILxnCggXhPoultuEdR?p?@?qkNYv{7knqquY?gxe!Jv^Zdw9lpbE zn>itxf2ecQbs!OG&Lg)0K&ISh60&>!y(_LL|60A$S^6(7=hNo$X4_v#|67m~T`rz# zjPN&@+0Yhan^^LJ}K>gOj@l{rLwUV}bt>b%%0HK_Wcl^LY4 zuUy-*!^`OT<5*}h?M&8KT2HsG$c>E9^J`C?ywyY(h=2Mu>rD4wHD9|!efiFR!1ddA5%O(;*|YuTMI8XXng$%|QyE4`U?WhS|l=Q!JLc6+*c`kq_QMTRAv zM0NtL6)BJP9SxYQQ;;}(eX!P37v#si6eEv#J9=ir8=C=Aq-=|pBl~yhYGn%o>isz0 zEqpOlAi)7nk^0;(wKw+?ys>JxRrJmZ)W`4}_;jdzXW=s6v+%E3{8=GN;Ns;h< zhhRvbpyX?BU}S^iAD)+Zoo;&M!pZ6JCsA)`*%%mDvU_|yhRs=>x%4eK`m`;2D{4%yxPhKm3`u^5pHhe%$$xP zyk?!N1KH;FfSS=NlO6ffBc+2TJ%Edh)Rb~L+b;_Xg^two=Xk# zxF#R(@q~wh8SM>{S@kU=jGT1g+B}hef{tWTfP{U8tp8Q7PI5$+V1Bv#reg=oG5jY3 z{Nezu?BEGTKJRpTUBM#5NZ40&rz8t@2%r2yzVQFFCxVmGKG$W={(c{n{Y|m%8ls<8n@#KjA zo*5!U-q~|z`~|mW<^e_U9?Je{gP-n@6)jJ0*qXTLyyczgL!5?RGaBTPj}SDT4*hvA z5Xz@;{Te^Q4&53vd)zY%K2dwR#=E};(9MOoZbcqA>bnO3{*$Jad9$WSbF@(Tn)HZ~ z!E|EGq56@VlbOackHf$*M@nT|RWCSH-lspL=M8?cX6b#i8ungn>44Bf(B}1#O~Te> z)qcy1KA$KF%5w1y3(u9_jc_1fBp~@_{7qk1!LdC**hr3_vGZVv-vwcm&~A;q{ZEpk z$=Lb}G+AV5FGE)6=-(r#^dcTwFxRt^r=F)Zyq@te|6VoLVEi9oFdu2(emF^m>%`RT zacz^`OXs2E`3u5;NxqHYud6|0FLiv!_TA~ng2r-k_IW)jZ?@xQa0c_?B<_S8L|!!~F9vrZ&K@UH$+2}3Q$k92@t3?jvXE={P7*OL zR#P9x9*rOESCd`vFo`I2G^rv&uM-JmX}1b5I)ne`AeVjeG5QJ?-xL)toYKx5 z=?-a2^(xyu#P!P{Sy6?5ktpwl2um)^&S27A?Fi9Vm$KBEllJ9&xE+Ap+fVGSz3Xo{ z*MaxoF#G@xjt7&tJ57KvqV8x&+3(_NrAs=YJh3n+(w@9bGMZrJ08V<_M94VHxUz$#p8a!XumYXd5ace@+QpF8XZ<_I64DXa%i4RRyW&}Kl#OEwmPfF z8OR(qG5+xX+eDNY*;E?rMC9ZjnAw>3!gR$?8*Nv~nT^-%O`Y$wtdl}wA-h%bf$hcTt$K5p7;r-_>iI<9kkq<$xx$02c%hz?Wh@j$=|jE6%08pl!L_37g}}R!8TTXKxfv*2MLO) z2!@=^F!oxEQSRL_aw@Fgq?KbJ-$}Nfk_}yN4X}%odT;6&F^tU~fbyQMCCM$@K* zr-;X%in7$XqydP-pq95E+7rF&TpBz5AvX>8Wtmudq)KC8VlX^IOA za;AZOJA=NixnKQ+mA->7%Q#!#os8N4J~JmMu?VbwsB{1}MSq<38M{<3=U9KvYf=>x z)c)7d9#8EUdPMv|h;{h*JMTJKwTa!}s1m5#8RHaM zo1xT=apzW#TgehAX=qm7ppehQ_-lnt{vAmeN5lc`@*p(24BD%dTzi z;lE|>mbK!zFWJxm0q}Fn{ngQiv9_gU02C9MG9iaz>>@!Qv{PU0WN~6z%Up`M$0CFQ z`gA>4fLZUwA-?S?=07`ME}To#NbHhKYtHZa96HDHTo<4v`M`r12(O*zzJ`szJ4U|e z3IVxpTYi%{zRPD}5rl*T~%`;Qi?Kby# zl(TO8u*l*xHw(;|Wz)As-zwsB13M0x?Hi)z)Gqc$#e`h`s!4_2 zTh(rhxaPlKuHFH`jKT~!NZh~dK?~M@2Ac5_EDs(jZ4g=gV`*-@m0|2OE85 zq;d~s39I{he#m_*o>98k=eJc~&AQojAGMQHlYjK@`bwMCGjo61Wjyps)Sims)=uS2 z-o~2JxAg>FzbD)o@6hywoO#X*?v-y+a;NZz{K*H9Z%tdc%`UJ4&I`=2qBSv-aOfXD?IRzb{pe z*0l$N95>XJ2Y;5A=%H5ZOs8!3T&h30tTX{F)ExvWuXX~hK#JOF@VD-TQdkGiL!|Nb(5Kc(;7oyljm!Pwk%(PrOLjwt*HFP{LAxwOXeBZ_Kr;k8>h5of`E)A zs;c9wHaK%IG!n%gruoq5=9K@MgN8dLkw!_^8nalE#2G)r-3`=t3ff6({kI8NnGj<3D7YWq-V zB*bymj=ilBkfMO@{6uce$z0#wiIKFA)lx!p;2W{?D`wtT&04SXI{K{Wo7oCzaR(}9 z>K@L|X+GfDmpT_41_r#GiEx{{#3N1gTx>11x^=qIcj}m%IhW5nz$;-h5nOJO9gh}5kqW#Suvc+;<3beg1X$d*k`_Ztl7kDlg^yF z)yMU0hq>&QTkfTV$R~^OGXr-u# zmYrwjeRSx@f*^TtkFRibF^0w}x-eqYD!!Ldi&uZ!s&Dxiqn9|e&!a-~)_6otEKM>p z7Ofx6v3Yuem%DyQWRiysNy(1bkHP{qw?E)!(U!{H5NF4m(bzT2Uo(sxp!?m;A1jbUP0Z+#8i(5tTpB{DlFhWI-8n_gE`8vZ0PfXk>!wxKaiq4T(?L4o=Cg2m1?hREERg{8dq2z9syl%CGi0q#X@lD(rT>?=GKt{UdHj2J*7< z9Q+V*HY{^>K;6(K29%QmVTA?ff#kb}m;tGjjJIZIKu z1tD`xBE01n+^G<=WPs6+2Wf`uL8{uLIZyIp@{-1@9RI``_zkMp4or>b%#NI#roC)G z+M4b@1NMF8so=KmK;D1C^NHUy($mEN(q8JK6k5(Nu_dXAA#3FF?Oe9opB)!d7&C%tZk%fxYFX5AB`FpRm5WiRJyo-Tw$a$C)S4f>lIRjdIp9 zE6}{DaP-%Uf%2A2${kY2%2R&zgN5ziifO~4;}_{{)~0|oh7KDUs^ z1Bis8M|}}EjY{9MHI)61Sdy}PKYj-Q{bC^DdP2JeU5XPuKuzPrS0UO2s@|g|#ALzt zRC&%4h@RqITFl)QhA&ylP_HM_G7;1c)uuJC>weeT;-Rq3&Qhs{n_4{dfnpN&ugz2= zFe-+-b~w__h%?c*SR%uYuW3ZIG;CPPgv4&Twyz1YZRAl7ia(0gJ7t1B&YRAUo43Z%dL)iLR#ucwu0^d0E$Lx=?@bI9Ij;zO8yLUZehl{lbKLo_+JU9~ z^BUV#Nh;5Vj>oR(H6z==HoPxB=(4(@O@e|+k|b9z3n0`6XjHV*%Vt^f<>}pHmBeLD z>!S8-kRrIb8SfO~Og}rXAgH|Kk|vH%{N@<=6HL~Cj#eniyRl(vs*s0rDlw8tkAcq} z+Z{b0;d{82N_Q6Q6#)!#VdBY-=eANWOT9G-&}daqn{x^f#Ji| zKB2`*Mg89X2lfIAeU!vlpVP|Jqsr$tamakf!QAOWs0AgB;W*IpXZ`wWJLoq2`CB5) za!c>s;4ryGq`v(|=x|b5KsT>F1Mw?N&z#$!=IX;J7y5>eX(Cf$H@&l*hdDnm+D#5?cYvltu{5P(=Lby`Saj?yXWq#}`nU`vDSz3WZXf#hl$; zj?u%B9v=vus-W=Y_}UFyTNaso?&@HCoODvN#X%yW@&6q2oFr5meM1d1&Y?mL+qDvgnZJ2v)Icx50eGXMkFr}c0$wfI@SATV(mR1 zbGyYtw8ND$kH_`ehTB@z`1~k*D0`~(L$ATAf`Vy?>Dp5?@sZhr#aHmcZ~9ja?%Cq~ zp9%>VWyj?l2OsRRo0Y2{d-{w~G-#@Y>;w-Ah~Jy{`&7d4cm+p66v=W%oyKf5S>;kx zVXKLG{e39U?<>n>4q7j2xLS5_6ulKUbYAjkMu}eH=%H&inX99>pCKPuV!Z?QMnB9c zv8yNwcWVICn~($i3x(CqTAx@erJjnNNFPw10_66rg2X@8dvvzO!@XN!35A*Sg66dO zpxWbU9z^z4QNJ}|>CAV$b?20QMbiO?MZ3r62N1)a8rLYvj`VPG3iHx`kx~a+v7)Yj?(p4hXF)hyZ?)xIB%Z z=XZnHHZJU@VpJub`%{p$3QSL?AIT|#zjv)*K2FG*nGi)-EAw|meipejJ%^LpnuOT> zC-sOL&hwO(AYxGP2oXlkKu}vk{6Ay9D4~MoeI9Lt-G4=1nW_}k}FA6b_^sxCQrefEhT3E67x-23|4x@H5jQ0#CXF#8D}T zg{uVcd(_KU4h}!GljXu4OBASuJJ~hK9#R*w+`nx=nKLiFON# zIgZ7%pixCnGwfij2D^>@mPs{tAC_W`%ejrpq z#_U)_mIiLel-VrC+;!4Cd%7aWU&=k!%D!pJ=Yi*|_xJ{Dk12pW5T5l*mTii}=aW{< z&OUTgaND0*zWdW{D;z|Z?_L=8BByB+ePKp9tj&(O9#s=Yx=yL@+&bV&!{gZzVaUp? z{H}i&@f6Q5CI~Z>8{TG?7Ktc9DCH{?)3Z};DjbNnxObzOA%BC zd-i^bwAc;>r&tiAFba&)W88PP+wULZBi;VqoKfdv98jygdXkZOgh4F?=DN`pKNK)9 zHPVAR@stVUC`#oPRy=tKn^d1nJpKgd9|gmdQN;s-5zPLbiR9>!oR+cdUu_JKIw#A(`_1{f3s=v`E z2;*{czwHBi~%AM=5MAMQ^laWTz>nDDjN+INl=KC+0;>kgGY11$0tX z<{iSoKJNzDOew20tet+Mecvr`&Bn2M?HBb-tp0mVd>e|&>83^0uoH?#6tetpNz?#( z%m_BY;|jDAz{NcF2&@=+r)jEIX%6D&A&MXJqEd8C#D6fEkyDR5z6N>yQ(wpXzKu4b z7VX{ovP=2>_MJKk#ZzEWejyJbbK0M(XLgG}_Rzd)7yxt7+WmqqxsR1xUbPTRk)_2b zcGHZGx@y?9cNmQ=!Q9E~H_z-9zwU{d+#j1E%?S)Q+P2P9;-7!mnw_rJtNx&E=q8qs z1<&I9-34{az{!#={F(G%w*8=N4Vx#}3^?C$%({~F5iK@&y8flXm<>_w=j3S&zY%&V z4dHaA^^Q#RsNqDsAmhyFy(tQACFc+Ap)l5*dPWfae)Xns@Np_0w->k~D~fD%mgPYs znOI8RLADmJrbFZ-c`O{rHKDmLTH?8`0ID4YXbyzo+VKT$ncj;}J0;9&zc*)Tp0R)S z(ehio3S@U}>e0K5G@{065`4M(FLuB|a~g2z_C?CnfBDjEv+aMhOmQ~R9T%M~)t`Cf zgu4yhv7P_nd-QLs_z@p)Z(9JSJaYg0ir+ye687Y#7xxj1?w;CH>J|4Rd1=O1yJziJ zFk-)*0BYC^*6c+r7ZM-0OU4MWzYnOF`*-KEOr@mZHD{rYThSt2g7&zz`?+s-XyYlb=xJ3jI@Po)^Uu&^lLnUv5K^#dG>?W=LA z5*6;BEFA6;ZAy&5`fq?DX7`&v+jT{`e!BBy zk4#Z|7V!{1>hy~kCYNvQx98Or5!XCvS=2J%- zDUb*i=d}=o));-DQE;qZV+~H=gHFr0Q!k?A_STL|Ql)qq8+B9~B{zF&T@JwLKkH+p zq$Uc_&Kgr0?IB0ugo3B)O?4TPFx)#@#D6|nxt*9b065G=cy}U|Hbc+{#LGjRhg&(D z?q%PEnqOUflIpo?&GPG8S+2GAApcUBkkk>tB$G+aXPQUBke*seoXlK;j*7zP%sq!T`+z0gvb?%v~*fuI@c_E-(285`WTsgH5BaqECqvTueI7u$98 z8oK>4H!)`m%xL63yvPP7{>IIaSz>geD%#t^gTq&1abUTKAn<0Gb3rreF3{YDC?IdX zB}p*qyRYn%WqiN**P2qS|IeV~4)wKeLxd;KEj9(m?;e#V2setA5570ov0d3k()SaFS`6;{%W&Pjq=@(${Jm4 zG?#-bMUm&`$)5n;qPN+NV5}>*mE5+2x!4Z*N+bQlrIj@Mq|B5DY^=Z3dEAm;A||PF zi^!qagr~B;nJ~fQi$1#dsak2rBxzQRnwu3qf6)ps5yIWIX`a9b6GBU4h!&6QC>j2e zVT8d3$WFvvTlaIj{}J+BDDqV#g4!_JI(AfztTK}PpiUG%;Hc!NUh9HfzN<_Oij6$I z*Bf8Oz)q^T|L$!ZYo$T$ntpaZSIR^*dx7%W?|{@I>7rQnWyzBE=LH;murV*1th&w1 z{o#U0A7=g{E*VN}YER|d!&$D_)KiMN2O#M01jZ_bPjZ%SyO?Zn$W30eHmqFV&oHr8 zW_nHs-AI48M*OA=O2s|XoN}#|X+b_E?JfFF}UTpanbdg+Fe#C&5X7b{}Zi1){AyEbePVrqjZ z(B1uHetP-u`fc&VQWK}^9p>mxesdFY@{))L%amx^oo}a;`8ZF{=3>A-LuQ`NlBiVdGQNd9goeLT804Gtkt?o-jB>E9H}lvEmKeZ zdK}F3TEQoX#Ncqq9m8*WeiNbL&Sc*U2B}E%C=+k7%o4$aZOMX>q{h| z&D7XLmU;B`+EqA_M=cjX8y>IZjHj9$_}M;d9mXC7&E)_sF2UW)mA-Fs`lJ!pl`Jn~ ze^6JicGL3)nl+M2Zw%~>7X~r(0uS_XUp(59yZmU+_?qV#&6Dr2G52$lEMO-SAudk} z$@cGnE-iP-TcWyisPj-|Y6x^M5Meyu|I>JAhnapkAPf>j-|YuAO32eKJaQ1+@^=N| zWKO8bkePb#R5TL#&U@&Aaz>W%A8m7ft37(mO0nFF7k z0DZE|Kifwz3;-yrnw>0s_N{v|vLXW8h=5Tv z&qDkuOIks+F@oO@n11^7i*Nqyxlj8g!_X%I-Vwy#8yBpv`(5w;Dy_i&9je!( z|AW`&HRnUe_vU4KZOo16&NY%<=Vnm*olVEaiT9O3rvD&}{omu?PIkyVCGZycdymB6 z2uhu+{}5!AGuJh)J2e5ba0L8rdk_k? zcStF9G^6y9^+{ycw!1FL*sX*Gq{eiYM!%laVo1A=c>e{VvT>si0lym_FtvyS<=jO5 znPIORH(8nOu|?o>*rsGdK*<{8jG0djZ&jZ&kEuplH%I3miq z#^Y-6CB*LsREPR~2dyZMeK5?etYQcUdu`0N)QrdBsxCm9UV&WlW4n?BSmk|qf$72z z*`e|9|5{;+i3f65+QLmpV!f`3Ze573`Pc&A>bvVg-y-FXCK4){7HlfTiZ6>8D{0JL zI&@LE3mHIeq8OB>8dh$(4Jv5jT0^cSbDB}f-`6AEbYB6jr58d9m^pYJCUM3)(U=bv zv*m7r_2QL>Vu%TcFFw%o>RT2vJKpI4X*il+IlR<#o{vyX#Ul632?5`V&u!5cB4 z4|^TeURSeH-rVupW*JvEAHgZF$3Nf^-W=oFSc&*uYXf>FFtvZL< z`+mp#WP$jPsgW$_f)W49{Xo3D_o}dj7?QuQgV2+e#BVpf`r@5Fn4grNzaP6bCwTt> zqS!0!MG4-n`DJW&b4>d5mBG#{)Y}ZS(kk+{7D(z_Zx(BLVRUPoy&vs*S}r1o^88hb z-)_=u&9a8Wt98$sMUhKAE2B3Y@?F2f12^84^!2(As*Y6z>YcqHu&N+%@C)#%50NT> z>&vd3w?`XXx>?uo3@X&g@jq54u2*eT!U}xma{(Va#xG5v1LZ1XAr7<*JyYdO5D56v z>Zzjfk*K&zw^0WWq4GXHD6F9EjOmFSngWo3>lD5N_OxrN4h&~ym0FM(! z9a|g5k=&FY%n+kN28?u^f!{CX&CW|}8TY32t7xy!@6C4=TCP9BDrh7_7H!OTvev_5V5>Awo?w3GEnGVkx4q36Du(Ngs4+?GZ00db7X^iPrNXx5YXV~pA3ph0HcLIA-`XcceXs7f)bFV^3y!chc+EyK zq1C*ivoC-sz~D1TyC1!5Jn6peT+Q_4-7M32ViBA?#9ukhS~U-Y)o07a{drJ@D=I_CSw3H=y)e!o8Tw4`caTug%2 zT729J`hv>9!D$|xT8o*wUTj0A{1^6Ltr=I3s2S95gpCDL?9HBi&L@npemy4aB%Z36 z5ub&Y+noyDw0T%g-gFJ{P|he&C8UAVQg}-iGo9emP=kk@Z+)_YxTaBet&p&$m@F;j z-`OK0UuoCso4ud-T98+@(2DWpfweOAQKqX~8WS`z-f=Z>mM~_U!s)99*A#uk@EV!M zt1@Lhzv3^a^h1@iCHzd^*Cab$S(==xJO!PcN*^**M{>7^W)~}BdhstI9y?)l&R$6O+i5PAbD`_|?>-uJv9zV6~M@vY$XyFj4nzO%z0 z^Qagy#}(!ezXz=DA`=-fz+!bwI9twJ2`(T;u>|vx^k2o>q%u(~rn&f{gV}Y|{muZW zl1-?!;9_3dqW_%o43Hexwes}Syy;(`u}K%BmQVWA+!+Y}@QjP@N>-gik$%Iah99%t zMYna4dn$b)v2RsjMhd)gpqZ^}U}`YV3q@Ut{su`^25wX_k(U#Gryh5f0&>2E3&2xW z&LL|(Ao7U#p!PbswpAClxbz@-WBSKLKQN1U0gsFOn@3wu%cFG|xE*h`=SnDo3my0Y zu4_s}gIDT*G*X$>0f*ZiZ9u2AiS~41MUzXP+|3vp?VO!9tk~X~n|=*Cx4OiGB$jmK zntz2%Yz=BWby9H3GG!FVFF=h#CGG}SSTt2vs|7E z4!iT)s@3++QY)0hm6L}(bsZ*gWjLD6rcrhIv-y@cdVc-O&6h^Go<%_vZz2XSd|7QD ztMArIJ^JHcaj-go7|YIfi{98}yY|X2{qH4|y3-oTKEnYnDV6_|L^Ps4oomcvNO&n4&!d_u5p{-?blBOzeLM9lxq2F8Qohzvv5SR6NTGL$UD!Q%V0%ntre_Kl{3JAoM@`M@1aVg*Q(fU!Y8r0$aou$p>kz( z_WVG(C$rzW^bD0G)B3SAJhC$hH#*js+TP(98}qalTd!@`vU~={iIb(yU3@iLe3F3%KH5p(N}yfwvAus zaA8eDy~?Lk&35W;<={yCx4Mcy6@)Mj&<%y)v+&@a4!MB@l^AUFRADL4l-Ak4f zyMBS>&L-Ta0GXQ$Z6OiG*Xuqhc5(G{4zu@PBo?HMS3kW!!3i5jOULU_6^si(K`R@G zDet!hZ|hbei=0853{YA$e>6iDXu8{$;;Q=)U>WY769D{fvV2zZ+6Ao01GI9gGhr!tnrp2#-(Dq9$YvD19Qc64 zp81o8PNC{N4)*k|r91WS_Go%6!#`++^D{3Lz`%ofe7sWH;H1RPTyx+X_`fUMiVwmlDUCin{pgqUbgi*1B{cSn=uR+3$XNNFH@ zyV-F!wziJ$oe}xtJl;d6qV@uQ5o1nUFbEI@q$v0iDPNfZc<^>97W4b-HZPULFmaUt zBe9AcD|`pv+SlRqna&OuDC>ajRfCQF7z&*NQYiI~U&Tu*_vbv`)URo9*3q2iD89P4 zvCr!Z&krE7doI&LF~&)<1<@L2HCo{vc_%yl2kis$Jzy6eNN0~d@dEK7QX6LbdWva0 zb`=hM+x{Ked~rgXce{!Ce&ni1xtrT%LNP)q3nATs161uADOIX4ETJ9&a2+zoE=_d! zY=!*p`wE)ymq}Es%BGnd9)}%rmwRkgF+T)NGnb3bQ5moCezk^^6VoLOcJ{XdHg;m- zYr=e6c1q%J`hn;emF++D_-Gu!{S`cOz z#bdWP!R4f~3Nc!5BV8>Za?Zw zii@PhX3;5XcUZ|GKka_<1==37>~P$Rx4Lg6^pKBX6{s!-at?16B#n7it=q|rF(#~6 zz&j_e^OfO;DTHT}etaa+ybZH9Qs7Cc-6ML7ud9{y?H`s-E{!u^=rC zBUax~up|EPG+42n&>61XQ@q`K-fhf`qz!aWQcN)+Y69$STcgxpyJz{VklX0(31IvD zr6KRezPh|{)|#EfveqeT9P+D2z*NNx^Au9Oh%+tK`o8D39d!9%@Yyj*c1-1@W%4yY z$;H=<@zCCaN-W17HN%gaOGn4U)5g$`U#NPWcRmM*ZkDODvR5hxlp9Dzfj!=R3m1L4 zadAw>=v7i0E0Ql^Qy_(P;1ab-FtyGK6jkO{p|@p+qMv8;b+zJg4pA zz9GA9H#1iS@Mo4)1#6f5hal>}6aT#)sFm$|Gu1CDs^~a-=pJ&XU(8vbb_p}5^@#il z=ht&IdSgW@CAUA$X+By$F{MDkz}2kv^KxnPD@6VGXZH*FX=|$m`=rrA`U^^fe$=-^ znlEmBzt}r_Hme`5Qw!x(8@d_4VqDx{LSeG}RoLJXbr+ay(Hj`V34F-zA3hr~P!#>W zE1*Qos8IZ=c$3RriRAOT0ck*RNt1)6Iu^ftjVbDwL$q&|i9^ZbJfKx$wxmxeMT*spjv(X&`f_ha7hVEiZs;LZZzcTz4{DQi8oHy21rlYnO*7#33 z@mjpj%dg!x)i`yT+PVYMX>!Nt?K+%iF-|qU00)so9Dl3#dr%2KT4USh~Ml zWiU_8gsz0v@gKG$%<7n);Oedhr)p(M1h!vT+2O5W`kuOOr+Tw6?6gs0k3`EX@wx{+ z9>*Pqj?^2USwE?EVDK!(R;`Zmm&TQi0ZhtP5xbi*ew>)iXVscrNIt(a4{+C=63zaZ zR#=;1y)2IFU?=T|YanQ5PXzl1Q#4RfqF9vv6u?)zI;233WOLJuZ^KMzr(CGnxB~E( zW^f<7i|4FcSq)o+5S}Vwiu3GjUk7LE?lo1Kp=A);vG7XOUn^nwV~=kU(~M6Qt9?Ef zn7(oM-pD`GzB!Rrv$hKDeDlKy)Jx|8oeksc4BUo4uZiNh+Vvz%kC14E;wU@M?-1DU znEYguRUI%nz-6tEx;_-xe4dki#z!u6)!O8JtENMF<@gs{^;Nt313D7ap(v8vo({00 zc&j8G?G`u+FEKf$E`Mh*-K~hcGwC4<&6RH}R&3>2Gh>r%^G#1Xygl)?b~p!O1O|p> zPuytOi-2ILqmPLC9QjowM##2f&)$$1MN(db9V~qg1vFSuYIjE6RL!@6IG26+OO)yw zB$d?o6pUh4wT~9m%+pW*K{CajS8m$XKDC!AX~x6576gILqXy38#(MIa4TA@y_P58; zhn0v-9#;Djybi6(r4wE`@a*%~&p{^t*9CC0AZ42!v{R6GDCPSvymkp$*)=PRG9tPx zqzjy`E;1mdM*k8;rn-XjcizX-hN3!d*B=HE_MthP?JkX3f(3`7DvNqAQ>gtRW;^WI zzlmpa7J~s0ILCJJ=FhiR^g@AKJy^88{W@pjd7l0*!Se9iZaRK%{|Q$tk8fS=^6x9K z=VT+FapBPsq@Nzby+C zs_^g7O9RYN%B~)znKcua2=$v&b9_tRQieq!gtdY5;!DuF)!!eX5+@t$oAQTXn-zEC z+2IigxxQaLXlBiSC;aGQy7GHa0(tRHe|R2Y-EQ@~cdcQDX@Khh^+W4Fbf=+5rE*BI z)Q-9o9#FLhExH9dY-famQ35yPy0j#ujP3bRhxQwny3eb^8=0frxs|504#)%*oYwWK z=8+dR7l;X)P=4O`@?tn;P?=vk=e^Qg&WI9MCs6#~51eN^1N%d$eZx}olP|{;q9@@g zS|pi$4{Wogsq9`6|HQ!J-^8F~^#t{PC>wy4{V@gV>XZ&-s#m(R%X6$I zQPm$FwXE$PD|6#i>WB-p{b@+1y6K(nzJdRqfrHAbbR_c4=2K+KWD4(ifAZ->A7+0B z0NW0*H9xeeXfQ2p=oy`@ep5=RGhwt1(?UCNNDeS_0GN~Q!atT=o)N-~bG*dn)-5>v zDojhF&R?i#Xc}J-n|?4QbhTi?C40Uk?XmGUw{z|Su?C{LGhl+ztU=`2D(>_(X~Cjv z;d9hLhty*j8PyvTOkaZLxC>)0UP}YKlQQ8~k8~QXjcvtbKtL{(y^rx5SC_?SO+0FJ0 zP8j`)1W25DdX>l>;MlZ)B1t(lDHu2GrdmHiR>@1 zp^ItzPoY!)6rXpwY=h74D=wGU8%aF5hNKD@{bTTo{-O*q2k>Hcp1@CY{AQ%{allX9 z$@U~gwr*fleo8?DQP)!jbKr9oBql~svkexvPft!D%vq!>0B7_dzfQCSA#Ui|)4qzH z7i*W<;k8YDe1r2%2!>mTl2ahkOEIzA~MZ42Xu>HxKSK5#aO>OLOS7pew5r-cNZ$@3n{ju_1qI3NYK41BNXgc?J zru+Ym6PltecV%f~N>Mqi&=@l$>BQ=Gm*iB)A#*Wp*ZX>1*YnbnoID4v^NAeheyV$X#J|I0yp&-Nak1;H z5+F{kXsuRyBA*yIr6&g|81D+~+PCN;-@h$73H(Cz$qGzN`P;QWB<}KRQy#i?ElFwJ z@7|n7R~NDckue#;6&`c2t~t4C>Y$pH2d&>W2ylJ3GIgP+a$5FBttiX(=l`ZcMGFPH zN?Dhh*K=YOk%6q964)u=YpQo>LRYWq&@allgX_pdcy$y-{q$~s9V;8IJSp_7hx_l- zF4+1ZT`tY=l!^Z!CXQ>fSqL#Q`(Y0jdTI&`m}2K2nWTbpk{tQ|0fm6(-ZAIZok(_S zT`%8mCD~YnT3FMW5ME0T{WEYoBo(Z`r8fQ_AxV58virW*XF$zju?Xs}_I0>6W%V&_ zcjJHb$TawRWS1jaiR660ehOes?}AQyB$1ZVsJj++Z+?3Sv(}r?+Z2rJ#IL=cyma*Z zfm8u2e6yxsFMGRZf4Hk>Ul$%{GZ(6)19p7w%GR0K7)zVjDzaYhIIx&PSf}s&_8hzG zr}9f9<#SAVntBSSlKbYd`>$^MiJf83y|TY+F{WD?JV9Qcy`dTY@)t{M-l3I@y*)`? zk_B?-rz7aGas=4;Y3AON`Ti2*9}j&FaZq9!4lJ5y5N-}{@OE}^@%!|;7?q6Nx^~v+ zw%E|h>Q4Qt1-hmJih-}wa_M0ICuE|aH1|5h+Qo25XHNiF-RJz&4aU|}2suc+{g112 z-AFB6R|sx>GS6DpGweEGQ*fN-{}i=-{q9`Qc*F91q5@d!z+J@rSo`FVNi*wWQN8LD z_c&e}a#@V|3cW*x$yhJbA{A42&s0|S2y!7P-xmxCl(0{z>SmahO0uPZ4vyooQnCS= z5>($bnwQ?%+%ju9qL*OF93)K}nDsCNBwqFW3Q_Gz8D6-l;vf9vCu(VWtPEiv$GsGk zdA~8J(3?ZBsLiy{;q)yi;~{!7VM=tP{mq6ze)yx2P&D=~BPOsUX=3jy2LFuaFrm=k znbG{vVC3Lf%ZXZub}m?-HjiL8tl^X&PU0q}Dr9-C9Uj%9H7k-;Yaz4)l83}zL>5Gn zuTGv}Hu*7s-Yjd>T$|TxA^}4KmEW|7`b2%I3s)^ymi6%JR8qGO9scgM}tJ<(0@ z9boo?T!YZX{o{{nNJkBhWoj%?0T0(^vmwe)$4lFgZ;Q|hPqZF6d4F6ZvJ;F^+qntf zZ7pNjE22O#OTi*%K&2qfiheq|17h+vra&Ye%k+*$Wjh~hoMNqHLZNJt$JyDg6&2*h z@!|*9C2Kr~G~HBuG}|}{tG8{q(>1c}`?D(HBl*Fd3T?U% zy^c7e3wRlemunjh2vy>E*iw)U66HrLK|b?_cOi4j6v^4TDBUAQ&$k3^SK3urF@Q_0 z1iwCq3h7pqQJtTeMvaryyvjKwN#(EbN)*X!lWkl#*#9{^_`ocH_5Q1cbdRYun|%mB z>d=4Eb9?fP-qEg8US9fQy|47pDuD759WXo02Z({8TmP5= z0r3%C&5svjh)1R8j+v#3w>KZS3n?}sdOdjmCBgA7-cz%EvQcFAf09PC}P22(x(IfC$ zOzqZS&dJW7pHDbv(P01E*<%L)eqAB^oHOI-M8bb^5kiHG^+3Z7Yx%K6^ zqpm$u0l>+@Vfp>`B1pEUR`=&_Vn4v0_0+8H7TIN731$^9v)~sU=lVdpJkPAQvDKnB z5Zz5`4G6icwIQ_f^DC6K(EOYoBU^u4_o;<6_if&mi8YIiRE~fbE8=;jg3u*lYg&{v zR4GldD*-s3Bc1v)Y9IM5Veq?L$ys181W=1Yir!Kw&#d{Lf0o>z^qUI zpL&TLB2G)&zp|mXXHEeYXzK8^k3|W!_F+bRP-P`sScI&p&tF-c7Me9`2)+Pw1uF)J zccAa;R8c;g2-eqBeDcwg%v8$QVq5F--aR?(4pW1pN!vYJ$IbARm+EgH;mc)lj(8qqKYsF=S8>PZ7B-| zIz4sYms=c=pORECSg`MS(Cz{%7n@5k3&jw^%LBQeN~UQtDLwpas?^_2#(zNPmCFl5 z8VoTn&N)S7s1GZ^Ap|TDobt>1b{bvb8EB3&OWWor64qZ=6xmvUgE@T`)ss?io(z?c zzpGQuE3!$F_CFa!yN2CeH`)%WU!OKavktWjKB5UV_;hy93ihqND{yqa3$uJ}!I9OL z8lmiMRnHSGymQr{ey8D3F149E`?hjiQ)6=@uSyGE zYb{gt`K4zrSOh&9D>Zqk{7bpV>p_X{N2BK6l7C9JxlDO^EEzvFdAoo5@skl@toyTvnKwu1Jy z_iI(cgQpdOZ8wjBZ;fC34+Qh~!LgaWTxXeBw9fi`9rwW@X?m4P77^#6r8xtYggE&P zec)@6Yo55ZFS;eVNaX6cz!V9MdtpX1SF}1C#UdUWbzBrXXo3VAF_>D zd#rtStKma=+V``xdqE~z8`XO=wuTmOcqAa+bad)9$@6}LbNZ{^Z$}c;xN{o8Q$lR& z0UrBwK*f&^S%`jB%O%=E9-l!@~VBrxrzv_eAakBPlJ8fci*MI?a@(@^?K~Zs2zC<#@p4 z!9{CB8&Yp@uKK_UzaM`M;(Uxr9@7#NeYTptAFlV*h^}o`mQ@d)Ecu-5(u*=}h#SJKsO>J~!2OPCiOL;hX`&Y8 z1z;a@N@o&j8Q}Dvyp6zIl68tBE;B~K{Fk0Z-;BC_6#H{+;Pj%r8NvvzgK~ri)LQSL zUMXaP9<9BfIdrQ`5xOTV!@2+bG;!VY{nMg!<6dwnKzFZ+QM(4&-rPNqiB7jyXmCUe zLhG-pn$$MF?QZA=bNZHLGM`%W-R>G$+vvp>GaPU-BY!a=(G9n-H|&TSk;2S$;y8TF z&~xd^VdDIn5&Q;Wdig&sd;))qVM7d_{**zUDrP+2LDYW=w0FlX6*&PGTe9oSAdb46 z*(L&%IdvPcCCEy|XkS!#qly>S*~`YcoUn|~c+*>SCxamofH&xC{-_$5jX~>MafT3= zK+9!MYtARl|Jw|=A8A;xp36G4CTk|huUs}xf{!m*>X5!ALD$-pdN|L&I;_tB?87{i zN@y|ODuY!LG_3P!TX-kuC`QZ>M7`{EO0-UZkMN?PYGXo?>)PKlStVx}OKZy1r*bt$=%FH7OQ4g}DhKa_-dZ7#Hbuy-`50&cHtWGFKY z7&#t^OLmLj$6Ek#oW@?0wbJh>uaD3#Nk!)0Y>8pMC(rM!fm)|>tNQx&MPbV2pAtHzo2PgYx}1o)YhE`r6*od8 znobPNy~>>Uxq#e5+z-CkYGL3Z!d{;_?^&gp53F=$YuXGF#6~^^w)Y)7qGfK0Ois7z z8FUsT2u*e@nWwsK95Dg}up&8)^Px1{v|NLpikOZCy9JV~7Z7^}3j7bOKQ54)r?o~5 zV0`i|9&ZjMfoAjHRy3a8xPA)o)7$S%1OJ=H^8N#)E_5#xzrGh|kW1`<1EVy4R$#X7 z#s%X$+TDGVnt3eh$&Gn)*WeDAdoR=myrt?~A`C6W(SA=(w3K3frX ziMaECy1Z}yF9GF*Z0uElrhBBj-kpk^@_2C%fk)WOttU{d*RGERpaLXu*VySu z6`bBnhT;OSEk=9hq_PjwA^6ycdAymp0NS}r&a|Jmf2%Qi8aa3Yrd;|g$^JnhD5_Vf*oYPAC&AwO-hf}Q z`z@cQS|`9A(uZH8lADfe>l!ykSk8(pEST3m^3)BKdTfV2we+xtg>JA$;GVU_t!cGMAKH=RFMN|>lV1o%8~K+7 zT5-=v&sG#qMzt6Ro-)O`^Ti1KR`l#ONCq=oA^uaqSD&r4B~w-3)2IfdkwVq%CxBG+ zeY7sD6;t)s6~0@3ERYx1maTJ_OOMx~EJZ0B7rczRf)6Z(NbQm=fJ7T_%{34$+9I#{e@g9Kn^~q} zZCM8Q$HTebO9!5h9hhI;U#*#A@=w$ncDTj&(8xOik};CsS%C%}4s8$zgrxFI@ul+l!%+_x+s?&tU=*li((Pu`eRN@@Yi)rL}AIkrQWLRf=>?zgDq~ zg49TM+eZ=<1XN9@hd)>WeCf52=@ws)V zZQ`7HBeH+Iar=M3z0I=2Whkx_mDJ^(OpV8==)p?AL?BwD3Nxc*yVJxzw2n?`>iB7+ zy;qA}$2CKtYPu_r4U(XXwVKoZ#r-p_`^B!w`}5OXQ`GM@qW?ap6Z)qFI$IJmkba9J zOh5f3SEgM=M)vg2H`%Hyx%=-DerQr>qe)zLjmv~+A6i!Xna17Gp1r&{ruXvdnQn`U zO)v-B6^nh;fT%AwSm}`(29K^?9ESIP?KvxiZ1X)eE9CEgA+Eu38*zrEStFnera`TF z1J|$a5N!61Fgi264p&Ki?mzB1+qKKYNc(DBc<^ZaeS~sb6A*y~UV&~6!6?Eur!u2* zH9%s0Ob3uA`>K)l$iM~f5y!&MAf5GVNmjJ)jelBH(?oraMQ?6Q;f&%777T&`!t7MA zE;~W8C+2)De}`ZXPMwj)mXfN&V?AgG;FbTB)@qJ^Zb0e71h8L^(;WjzGWOR9K=xPI zZJ_{ceo-py2hG_Oxkipf$oy5l~()y*Sw<#y3Co2lW+!CiT&mAJJ)AQ<(UroL&{ z!#OY3CR7SDM?n;T`fWY@wxtt_1cixY{vBR|eGi{ut!MEuD?XgF)#lxW2n*O@v!LX-u4BtrO+s~F?cK86up7$QD&W!l=-}0%G{!@(7jWW6 zl2F&S?orxh^cs^qF$?BQT=L1$P2~z%?oKW$E-TqQO7S?B8Fy3{&uL-|Yf||zr|fX& zzbXeiqZVM}$n~!>{!gFtp0bi%8B%VQR7cRL^~WeBZ}*knhlvM!i~bQM6%Ex6^W&UL#JuABOP2}9!z8`=$J zTld=AKIp_?Hrs?uRs_JH%Z*WY!oY%Mi8bx|tY)M7%ky4?8d}Rc?E7F*mIA&sp`(hs z!EgVq0Pvd>I=>d7ezj_hFUE`6c-jBOMxrfFl83~D1cHG!;WoWBf*@&j`Ri@odL^9Q zKfA?Ifk)4=r}v+hVgE&~{72NZh+4l5@cDSILACNWnw!!e<2w@}v+SIomef_T^{}Oq z@196NTJP(}6$nZ*Us*qC7c>gkd}K#CO}fJ@aRxJJ{f5G03ujD%y|!;^?tQF&XX!z` zjCqqM*Nv_Kr1VV$6G9d(+s~cUZK)}+T2qs0`(wTnAkiiw8uYNXOo134$Qf{7Ya&5q z>$cM^r<8uVPXf}MF-ym_*A!Od%1_{*VZ09eXn>0wl6%^LDh{=xsw%zlJ$?%>i6zvi z%5F0@+z0NFr0lV`x36NMJjUODn@|5Ukt%X$+L*13Gd&5>aVG~P)JK4$#GC}BB@Cs>_90a~ zC_-z3905&im|GP8@&2!q*SdRJiSH_UGk(1E%VEh!KG|V@Y>EWFCQuU4d)!Pn?Ul$j z_DBx0SS4JuOeGwOP&9i9qXOBd&D4K=n)-ziZ~K5Bm{a!(m3|e%A;YYJdcKv@K?L&D zxc8`gztzOaG%hyx2{dH<8UN1EbT7QLg}sX%*!9VdN!u2WSswLI9Gbw7SyRE% zZEp{`ZbmEeY$go*{TDLhWY(yr3PJ2U;2E+YiPZ74qiVKu#v7f!DoXz~;zK1nT+0uU zO2Qh!Sp8ppU+|Om4TJNyMkiAuTvc7Qy3B#e73Z{i-&{w$Bd$Ce{izU9zWGL+o_U11 zXZy>Od;%TNnKA@$rL>GIor9t2;?i29zg}-1g1tdCEo z;Q5tm_J1xF=I3EuuorTZwB|=ZFs?b|l)_Ln+X&J~7HXiU{NBq=G$=OR^O!9u3((s+ z88thsF+$(9>s&CyK7k%)z&4kH*004uol-&NKU6owMkno{HKFRQi|!t!bN|}!+yFTT zes-BFLUfO}Na}QEFwUZrg&ug{to(R8%$RSLZc*IsBd5@qQaCX3dLI;Mh~l8;|mROp*C=K6=*+pGDG2*jJGlqVNN@9^1y zq(|N{QE=}pRW=PPQ={cHuopAMFkMRCpV^3nL*bf(3USHePDG)_w`ofBUZ~dy&a(cX z?r>G3T)=u`503M{s-X_pa3PIhDK$XO)~wEYB{2sN95>URB$G@few}fYhlLpO9 zFnZQh&UNkayvb8Af6N~9tQ~*36wadGuG3uwU#3Hd!P$kX99HiD=obxA=!2VVw*&b0 z!+CRpnvaJ}bAzKmj~EJ>JuHg}-k;}1QJGeZnN%@_44v#x=y;nOq}dDmG{?Wlx5UM_ z+K~AB4KG~qm*MNm%jQ3*O@9r{+8jJ6nZzF?(wSkKuA*IO)Z`bTwPZvS45-~VmkDM^%befJ#~!RHISt*$ zcFVA6CDr3i4K{t3y619h176n+F=sysrKNA>*{ARhVfc{aQkC%1IFxFsLI|f?VLz<} zUN;KkPMi7YnZ=W*%)j&api-huz8%t#)2U_P#|yt#KZJh*FCYA zY1&^@mA7Qfne|^8>n+Wlnqd8nxsCW?%yaMf1FrA?-^i?rspjyVb5DI zci?FSVNfi@=tG88x8`Gk#S5#UuY?wI33d88n5I>TKJBJ703O7Lz4YzrhWAAh39bp) zh?^$()c)g{29@3_;h)7Ra23*#&9UKzas4?(xY4Gz>*=BEgIRI1V``~vfrS%$?R5-7 z&4EYsv9i5KuqLyVhs5eoa@QWz$ki&KYEwTXn1h5{WI64$-qur(yHyqXD=OrJ%xoYZC3IQs1{n0t&86=|*PomF|Le%M zarqb#iamGT$cpz1H*Ngy2GKZSo02;8bo@ygKb}l~l@i6~Ps1jvubKvIQjf5uv}$KP zG{Xqh)g7X$3J_fRM+KO%zRV*J<`)tdhGMHTHqEsJ5nojxef^xR>BxXbx~gbun3#h0 zw>V6tp^<=nW5`w9PtQx7wJCCvjppNy*`GzBxm)sa-~-TSOFPS+CtxVbN&lhPmKAq? z>05qPsX3{R12JM~>{>dUwAqAfGC#R&Ib`R0O1%G_TbZ`t@hcqdu#435czYFS*Jr8G zDwr`pke;^Zc3#eDqh@2OXb&Y;YKqK`)auM%AV zE_s{ryTSBWlG;+>b+DEVg2|?Y7U@p}^{E*3#n2 z`!A@ZP$TjtzLo!LXDRpY<@AZEci}EXJ;{xR3Oy^-WZ+B1;%Z)4HI=Tgc3~N_bNwhyaJzJ@{UnTXCaPP{ z+P6JV=T|%PXT81Za9IXESxqX*9H;J&wI$uOUb;fMJGyab`}~j#H;dp`N6D)9K~a7J zJ?56o+CNKoX$+lGW!p+i@iT5_k2UZ;^)FFFw|J_73mM|3K%e(w3udEhPx7BHPl}xO zChg@0*Aumtr?73Q4k4dxXmU>dY`M5Vk7ob(Eu(7N?-IM(;5MAV#+<0X!gUqeqhdqn z_d34Ha3e0aFzAg@buGtqp20S8a<3XzQHRF9I^yEy6_cVev0ktL1}xhWHk9~A1Fasn zq(_+E1CmLSHewD@kG3TtVy_Lt$JLAPhD+XxqU40dc5RaR3~N)EwU|mEf)Yo>iYt$V zHy<`BA1IT}I_)u{secSxjEn}_U|XQ)Gke2i=UU1SBs6=bwtO&%|`tl`N zg;ZXcmn(n}y?ms+h|4^G4EhHNeQakl=(y_fXCh?m2Vm4NKEk*AmB9hLp-!m_2>3PP zWNfCRiH^s^tk}jwo}xmfB0;5jf#b7NRb3GeV{t2=WBukQ-)B2VNhuNXQ$DN6r##>6rc0nsekcUM;QrnCGSO5i<7b ztv9q$^0iU?hwXl^LNGZnTaZmt5seW_d&A*6$NT8PCXI{`mn27)3f%Ea^x{mAE}ckr zgad9dj-im_3~Rgg(MJd^hMs=NzlhCWwGqOlPDX-wuJdgUaY_n~h(^5LNV`G5sjHpw zy)6~bRH)-j*WVM@_>m(N;GdVbsy(?rR2o1|F3u|NwTFA6+6q+aTf|a{>#lnj;g(P7 zsVkjoz$NU9A15l~i@wPEA-OaZ_pnbc;8E`rSow6s^~waJgJ~`h zgFw1HWZqxEt5hh}X(}#>FKL*ST{aK*@A3OLZiVtfW{)fP+gVqAK(YAmC|}TfTFbpz z(|B4p)qb$30Ag)P{l2dBMQC;4Acvwz+H2TOYp7n%yptgi6OL>$JQ!>x++>P=!pdm~ zo`mQRq3tq_ck}aNH>bYwlgYQ`E7Nv!^fhe*ONz)4LIDmC%%9e|88y%vg!+YYj(PTU|LVuef8ds?gg?*i+C+>v1o5GwROpqo2|78@+m*mAcC*F);0V*Ev+CP6{MsKj5EFT zH#vefrkjM&$bw)vW`o+FHU|58+vPnv(l%!kLr%DP9Vb_;a%dzTZLlZ5ntRV>M?m7WN_ASQQ&haN99gm)F%6wN*Ee*kF?tsLakr94}7R_0&L5&eXdC zt@gvL7yWxu(xv~Y5JO+05B5!zY0cWsSgU&#=V8bOM%7&Xp4=IuYSgAckeONimOf_U zeVm3>G~{k=MK^`K^uF6OLyHyRxIECpX*94Ae?N8T*Wxc2dPme=sQqx?AmKJlFlM)Y z`5TJ6dvn6+JGz4qS05^KY9Y_$DW?g34I}QiSBq~G2T6OfsH4r1TjjwUPYN_z{`s+X z6)t1D6vZQg@8oN@NYzg3`*Hlu2ueCpg6Yf;l8Or1+r20U5T*69Lnmn)Um)23z^6~Q z^L6lIV1qb!^>*cu+tz;y*3GpAu`Y)nh2r0TJqCAXU$m3srVUHe%jEVucYkU0Gb*z8 zj!bUM(7Nk?Lc2f2eb*`E)oC%y09>rtY*JE2Gqb}iw`MD1FA2Ou>lhs^RfPI3C*-d% z@c5%4JKpmMdMJ_kQ-moNwu?Okw%QzdDej-5wzhiaaI6;FOc&2|)G3pP02nUwhJ1-? zvAtiTX_=&GxAP?*?t` z7-P!)>Y|GkXIgB1SpRI`MT0M5=q!E)xahO*>Va-g<9abV+Etn_!C*!|f&(4R8_&A; zxlifmyl#lh^;&=?OFk6485M_$dK*a*Bt#6YDRCNqI^SdIYACfyV%3!goCHf7)4(FY ztF`At4J2b@4et0r2fV!2PRDt9SzOZhx|kOAdp4!)^g%1(*AdPNK)$+>{y@ylx8Lkh zTS=pCkm1Jfst5rwf88+xn2TLZ*|=c@@lx%IIg0Xfmh&f0In*xy>ISO1GV$k37!8v@_xRN()4QYItVX+7hnxJJk!mX;jM=3KhxD( zNMI-PbfrFe_iI{APNhI+e_EtkGb9L^T%wS&vu68(;0Wx^uT)ipHG7dLIF_z^6*JqL>L+2UJSAlK!*Oy(o*I9vvVZe$BFf$lmk78|y{WlQ-M=6?+Vchs8&8p5@_Q5TDJ`t!K$Bk3z6JU-5ThtBB$&|clq z(^*P1MhE1ZE#IwmFyai}C)`#(&an+Stzb>rx!-hyjFyG;`R@A=ozqkWjwnM}ciVr23qaFfimyL! z8^?^9;Ik7u7t9-y=ekHNexXfCP49&+nHY?BplVi+%4|sS52&s6q6cz94~bq3ZHe^p zy7>1_i8w+i=dbzFXb;EtPd7wb^;EBI-!M zETT2M<#OtY1`@9+7CV@CCCHGJ7^&rw6>%al)<;2}h(*-VR>s`@AF=U?> zIE)EfsO6r7ZlV&@ET-%lrvG7F+$W~@{=MVw!_fRhsJ}>Z<*aWUV652_FIT3@t^7@o zoBS%>ToA^geyR_5<5?0N1Ns?k+heS$el;zXQw2uYY!hy=U|maQ@U??0EfbHA1^5WD zJ7XzwFlqg2oB$}^R1@rA#a zFaM>*nfG+n?(TE44OPMl@&k4kb$7~mV6$19NfnDpFA1N7p$1Fgv0s5nHJGsj$~TO; z#%s#gB@YH5FL`I3jaC&?H)_BBOaI4rF{PhQ58oe_oYvi&(X~#q2MWz!2#rc=d|j@2 z$V%9F8>`As%U-B^+u3{0hW+uJ+vQfkN_sr|buMeMmy99vTOg-F1cQ-%(K8W-szy&# ze&_mr8ifBBJeF+Q)v|1Ndj4p$u2CdW(!;M*&{-}A8nQxuJ$d)dU=pUshxs@rHm)+_ z89``0VBr&ZNW<{YwBcR6e(i!TmQug$U_dsXDfcd{`$3*s>~im`naHxb->FIAL$5O9@bk_@=N+}aB!{;RVK)^{^jDGJAiWG>Os+ZC&M)VJ+bh~Fy}YnHGqtkXxUso5y?cT0Rl%vgaMsFHkD(_hH5r;n=w zi$DRf`TgsZgMEwkw-NEg?Fn(P{_Lk?+F=YqZs_t^2B!CQ&tsF4DUCuJ_aZf^^CrXH zrQu5ZLsc8*1lBA>vo+Yibh{d?54>tA{-(>wsYIxHB=U~*3(YSYf3{WGZq~k;Pn8@L zRKNCoUL4lF*eVD0Two2Hj#wYB=?>=o=Q(peAkC%%a$}GF0_vX})TSrHdhTSWQXt(` z<|D}b)&bND3V3O7ed%_Dx&D?6gTrX{=%cz5BnP5(y;B2Evig@|2n>fC-1&N~Jx0s{uSD*bPWF-^2hQr-*l zfAB>StR8SF3;l+)t&gVls_p0X<0Ral`VWT;N-%}nLl`L`0T;4Wes3Gg;(LQn=+1G3 zw!)%{Hd~-}6PfP(KXQ%zHY^HUn@51-6TBsm8)PUJW*Sl^zX-5Dr@+LW3AV*2<`0n@ zc%%E}TL)Dr(#47Ztj4H`%(hscto9cpxN{Fp+hU5c)dHC4{C#_z?;qK{!f9Ftu?DZ0 zneV5YC6}=e@g#H+C)S=G({uM>lkC^9`}FU?6#(U?Y?kZsd83DxIoRyeUY0D;#mxDc~sBg!2yC%*+;;;%=#5ptnd*r-F+>Au95R|XP8>b zeogpKB7PH$#DJuMyoyHtXM>Lx!~gnL=tV_~WL=W#ZoW}1a$Q^rbs*mH$^3sv>>B0+ z@}hF8WEJ9r*>lOfQb_Sc>&+EOL+t)MLNNp(Agg=(9t%~aN$Y1m?& zG}Q%kYYwHufR*ICtWSB##B|ki%@m*@QeSX;J`$om+U8`&kI&m!10tXE&b-PPd7(@j z32w(9rHb`71$YTUbJOx%!M|MO1bu|kKvx(0gYlOxr&b)+ikI359#kk-N zY&LX1)Rj;cx&vN+3ZmHGD6-c^h)`Vn~@CayIW~r z1^m%Mq9wOGVkNXa@=JC5^?xDfjgI}G7jkXmf%c+iKM>)jfVmc{ngB*DvxAFonN6HJeuLO87;%>6=oC`jp;);f0j8 zB&(ToHe>8t0Gv*OVBwy;t4z6k^<9lvMwpe4iL=vaeU_cdIT)X#H#T^pl=pr$ZSKsg zU9QeZ>#X81cqxGJYgag!hH|tL|zYVPEoMH%j|Ff@OT~CiR-0d!b1#=K8o21rZ z&h>cTL5#>Egc}uXfKc7SqD~U(C753S1Q%(#ZkUk3efZ{@t5zK)rV?m zYq3`#H~TzT$Jp*w%jdfbH_c`QUFR5g0G^D0H(vS8x~Exu6a>^qC~9S9cWMrNPmBnV zATGCec~Y{_vSrB5)XA$+*1(T1V7pDcBeuT!-0YiR--@O0(;DF%O$K-`1paCO^NVIB zKI?3Ru!UT%9W0XUyP`{#q^h=b4Gt-QIl%I;$}jlx3jrZ~bgX;x;-TJ~L)>4-b4zW# zjLe8y3uBzOaJclGLL91Y(|AU&zWNsI1a*AjWIx-(vl!+h@9ia@z!smyw1REQTmG;n zvx{6nh_Y_Jh$>-s@W|$xyK!Pq(!HXsnf*w|&V^O>v<>S7Gc!FHr{MB-JCx*Z-L8Ta zn4D2-E#L|idX@H??R_2ZOU!!WCJVNS6=z6q^G$ey(sP3B^{Yn2DwMDOcA76(W%uWE zJb0gL0}s;r;xMt5NRcdBCKHDs4aH69xbME9y3dFQx{}tYjf&bzFVxU$LwghJ(i8Q) z`+w#fcP4TfS5{j6XeV{`+;D?~A42{<---HX%WYRCD3bfKM#Q)Gv2F>MP5oo*EC8Fl z*LciWb6F2zH(DQxag|ovs(9*WeBGBiu(g%U$lDE?2Xk{uhf)|J0eYvbDw%zEg1GYE zZf9D{J~cwE&$}$TbH8^exDY(`F*88rrm|2p`s&j}Fxk2Dr=8I*^QEI-N8w!4=`=1U zf!qwTX^hMcNK0os+RX?w78Ovx8P6Rm`$5$Kw}CSaKqZ-XzN}8&e!k+$oB!)1wsIAn zX(`R6CQLY>q|92tytP;I=&Hv0%KA>7YUUueH;pDzNs9jn|+l=`trswVR z4^hhwt3{prV#&*C%&57Hm&xt!>xskR(=_=(3q8r>?m0Rmh6azOLPdz&3L|}U^ zxwC2gV0naLY^E4kz4w-*udtX}qgnDCrTA#!`qa_JC!#?Ky;DFsbIMVu@xn~>=Jku_ zdfeOIXQ8o9@U+vh0zC4RfX6BR4d1Q_a;0^vrWUNf{E#&F%GosbvZEE&U~2k>@o4B^ z!+@PlY#L(H9|A(W0!~0xi-Um5(3Ojm31l;*d3P9h{66n(G@T}&?YW|np(ZCT$2oqM5Qk{&INA4y@s_V7OrC=Wwj^rsnK$DeGiwQ5bp*+6<|`XW z!dDFgJb& z`_q?zOxp}uh^(pl;41RRFBUU#mzEgo^T7JywN|5TCx{)e%vE528op<1Ro9!M3`zPn zol@{AI}1*2wOkUQ8&dfx%Cy}@vfZ)E=F%Q%&tvQ$&sUsdhbnzUlYr|O_owy`7%4o; z*$;8`s+pEw3UOO~u`1#D7(`f^bZ;mI*n_=m!Bk_wC!p&`^zfHbW^MvE*FTXesGPM1 z8Wx?{^eM@|-R#F#7;+>A>LD$BabB%Bg~V2m&A$h{%Gd>9q%TW%X3tK7*EGs^mK)aE z1W;lX(sfQhhWOd#_&UCS$|Scj&;(4l4g_L%H|==Z!|!hWKMUY%u=WbsLHZ=}+9iPI zCDjLuaurkggy*cu{fgzJx_N8ilm@&SMz5o%5mRsFUPq5hG#qIzJibb%;w`wfPXJZBcz*3q(1SkDT_d9g5@%Axgn zVvyU9qrZq1;FNqTY+q`c= z4VUHl<;Q>^(}b6crYM2TA$85r(bpHv2QvmNfpp|&R(Onj16%fgOH$)80-yR(DEZs7F zvwMb3C4hBYug8W5{1&^#C2h8iU)RBfYHGFI^m_to;s$6g@5@P|(KG-Yopw2*aGTUs z4o(?S6m(O2xbJ}eR+bENg(Qznn6{MvpS9t~`#L=YdI z+LvTWcCtQ4U(gejFGHtfZ0Z1Pf%%$lSgb)7{(Tr%?9rzCQ;h|K z!Geaqr>x#?_LR@5;qhyw<{uSrRQ4@uAMG`Z7Q+{L3c_5g)}xY2mwx7V$TJVKVl+y2 z`KzxFtB(i5>ixXVJ0+;jA1W^gQQhcs_|>3^zOMo8hSYNXz!ITRd_|P3m#6^TZt!$W zK-Y+0Jhi#$eUzFzcJ#OgDa!!J?Hz8BTvf4}mTSo?u?qIf2bu9(&AiM1z~r7(A4TKr~ArvD4R!{6CTZ`5H-J~n!`HNuTf-+g2uFSIS< zzetVip5`9-&3QwPsjR5bo_4G4y|oFPB@bIB+z)JHaA zD=VU8ZweIRFMVmikNNQsRhepRHOCrxkSZ-;HJ9zWw@j)`i)s_Jspc+zDl-tp4`KeL zPv((asTn+Dd}eT9!tHw0#!nYsi10Z+L_-_ThVTYYvOkw0f7hLX?>H;eWY3s~sH3Ap z02V`MXM~I^yT`qwo8!bOa;q-1xRpWV-!r24eYrN&c-{ZebngF5KJFiPY$RLp&LM{> z$8svaXihoD9AX$YhFQaRpC7*e!Tq=& zkNdh`*LA(F=PSM?2b#lAcUO5zMCr6MI!}1hg#F?$_ivfJ$SZ8&Baex=M4?)5svcH+ zz1pd*F((oOJoRI}FM@%%S17u^3jw?y({!gU15$`zv(SZ0;S)2G@eM8VHHRbTuO~_}5}8pvAAl zhWEB#`LS(`w_tEBtc2v1@kW%kIDBuUe{xqg^kIXC$xhz!A2-h=ld)Dmch5BD{+3>% zMt1*)5ZpJF(A6JsKvN%$JMmO@(V}Rm^8zCdEoH}(pu}+vkkX}xK3IDI3mz^}I_?PG z3@a`bzWWRAztA8Q%jbBvMZTugy@n=7So940dsC8_vxl$7d^4&BIur~Pk&(8P#f&KG z)#CEHU_X_2g-rK3Oa0Yvl4xcJB~SH{id(~W`_K5{W!=9+4*;bJ+boz;zlufw541!G zcZk#uqWMX{wW6b2VT)aj3(wk6NiKq|k{s~05758Y_r-6?Gs=>6J`!fkkThb5_IOV` znY$-pYljf#+yrrs59D==-(QG$QBcPQ-WH~eNUre>ljToP6m3MOqy5>0kI6q^0X_w= ziom@gIEsCDX`Qg7;aaA5oZUDn6cz!YWGS+kq;$%!rnSIS2@kI-v2 zZS6${U%e9fU1roX$#-p=oP;WN$m$<@$K%<;f-53|2H~w}Nw4}r!=^f5U(7M0#wn=k zO4BgEy#`fa+-3OMRAc-2{C;ii75gDUe%4-hZ#bJ_-kK8K4hNq529&tG^DlYFyn;o18$N+jS@r8~+r@B9xwr^Ok( z;)c;_%B-q2J;PoT#}hqi(?^X0baTXg)+ikA4tqa8|6$&ZV}Lq=vT}vk!CqI0@%Fmt_S7i8wra2U5bJ43I1G!u*di|F5x)EIg#0A z{3dZtJ#QqZG7-Ok|LCTQ(Why0dOAcmlRH^P7g9|%Z)7$(y#uaf?vQZt0cR?wH)fmK zs}KH%6DS;5Qzt+04kvsR*DUj4QymoM3PLD+T+Z>EjRnp1l-4DJ+IC_S&}H?>)!XZA z=Nzg7EC2e4#CbR-8fXp-OX)!5qv{iC_^I|sf9;EXo?0#u6?Br*4X){mKI*y(UC=Aa zbn&orjH4FB6?fE^a$j4yAYlL{=*1t3p?HR2)o(m>B$#JjSIXu10 zGhC+!FRC9CR|Xz9PR-=Cq*-FkNTzV?W3lTy1wR3cHj=uYi4zx&p0$2-OKkt#(>SCB zNvUwHoqUn^iR5gv2ucV=JdiX%*D_-Ht7^t6Y5r@%q#>-q^10}C75DzHaH+em1J$0x zG(X{jwpb8}g*yJwozO$6Yy?T_5x9z-j7{2}&xtWPbh=m*nwYRL_}d;Vn zHI3#X1)nGECV2H`GM_oNb(ZM#)5mcX_N8`!1bed)w-{{ENN@Oz-RaP>U=AtJk>}w0 z&tV!TaBJl_@}A~F9&Zh1edUSWt;ej>YfumBVZ$S1Ir=k=svVDm3vL&yLY>Uq39IR0 zIUAqDyq^o!m%sO!zx)#)QHG2kdd;}6X(-l;3)(IyafJGhvdU-Alck#y!sSk*)g)PL z8iXme^9|D{x6FTNGBxw54bm_`LgRZKtqQJ_qcPWtH##JjG(%Q7Li<;iAMUV+Ql(k< z?$1C0SH>&7-soAsH2S!FiQsfRyLG5l1P{2D0C93KYHWF^8c9n9p7|k-z;0G?iluhT zg)3JCc`z^4E(3xY>%RS|q~+vhV{Uj`|Q%j8Xe0%~n3ZB!}JxsWg(g2@x&FXWYGL7cyUb z2qlVkGm4wyeRc@P%$91*k=?q~nDvABZl=4#Q7)2^vmqb7Ar^NLg^>AJ?Yhe+ghtZ_ zxR;)3HCFiSVe9il_8xvb`km+TBJU#TONlw#n$V-Jy(_CP{rUi56mmtwkNyOZCb*w3 zXIb9QWCw8=Z8z~BsR*rGP1LeRPPC=<%}HAYbg5>oI&I#IcL{xZrnxIRcx^=3qA`PW zV2klmXB?B(h~n7oi9BY-cy4%PS9pmWqk)UJ?Q_ib9)S$>7RGCfJU{SW3#$JJojzlM z7dKK7eu#ER<+3~73OIP>KLVux4Ph9cYG_Cs1&*2SQoQulva|S^{RC$JcJz0^Sl-h0 zk)2V&xpd>??^F|5~qqc_1{q%DLrh}4=N1ItGL9(s0b zPRV6GccuMShvvKjiqG5LO+~N1yt6%aG-9x43Fn$ml>~MpoxTFV#d{0;9+sHeor|7D zI1|AZC*gIy)EKEpjjg-Nr6uj-C4pb@94s@I8MO8VU!}vi2bNV0Z-NkC>^BpSzKiI?_aj%O!KBy4q+J7NB-CQ3u3komSldp7!~?kqBO(^D}T1oYRL(b1vwm6ttL%(@K7uwc@g$k)iU&j%Dg8^gXTE$FpynzHqZkI8@~vTO5Htw{YXRAIlPyCELO_W~ zYxa=rcSpQYt(@KkdJwHSV)}PfI#j}K%G-BSFGZRU!k8>2x^Gq)<|iK&!rn>Ha``D9 zm{hqIj4^m8vfT`@rdg$FLGOtkk06+-Hf;|WJNw`J^;t7f;!Wk_c3}xN*tyUh`9sq3 zU59b%&NQ>)_{N30HLbNuNgbwIn9fA5bk-^ihFW_c6NgwLMd0`w_;UiPK9+J%&L@GI z8N=ixIB-laeDlJWU}_$gF%{Q8#g*^sIdL;lM^mgQI{RvmF;2zbm&d~7aO~-S8T9wl zjYfBLV+yFB6%TC(MN%2#v&e+{_sFTUVH&&O^_VC%r1qjR*i9=O^lzkFI(RaLw5uQo{z3q@bO;x z^v7D`Xr6#^6VG7%%)4?9jKNU}!VR2`=ArHc5*8_bbS_$Dr#D}GHicko6cGB*&e7g} z3AY<(tNRr&EEpCcaRd$tJbv!sdluE0>?N4T?nxCEO`Ej3aapb_BK(#JV-Rl`WoYyroOBbduFWRW1JAUd$+B%`RKkJX|SNPsWo{reRt z*^+Jw6PTjkH|a*9q`_RGic34tUb?^T^Wq#n#&E)cqVwc`$Ct)5Rrd24b~YLl^Ms@C zIP$+h4};NEhsY6C^6P=H9qjQ7tVc`5)NgxAZK~`>68AB}OyUVb-sZB`#0MWvct!vl z!F-4_3P)_OJJxO9VLtt&o41e#OO)n?v!s9IZLT85 z+KaMmZ>O$)YQ{3|?L{%n8c-4Hk_()Y`_O~rEo%cKgoEdxAy?2S;pNIR&dda^Lh44nIOpV|O?*^$=e;ZJ=l%z7A%#HFQ` z-5(+!kEM6amxgE00(~>(8o#C{O+LJDVj`gb?!EZ4sY375E5z4?M?j%d>9iM>tAZuK z@>Mt(^(fx{$j)Ya%}TYS+|{7dmK|8^4yEIzgQ*#(oRr$lwu*@=YDP6h5X$*@O*8q2`18CC9ZG*94+sY&QN<=7AU1!Ml|9S0D|$UhN>RK(Ao~@m`56 zlw}EshQsV$c(a>wB$p82TuLwZQUg;>5Q$*yA-4*XG_c!*!fhzv8gtJZYZ!09Y>!L^ z>zWRYU$tcW&3+LuxKqapm`$*35S~f+&i*SqS?g`R7P|(of)@4aQ@)p6HzV1d3#P39 z<122eBhJbw;T5sBxPHrB64R8(43FS!lJic^Z!EurE=pOfyh|E-T6Hp@dTDZDlf?!bE>G3`9f?y);>&6>{YUxS?fn(YYYX|* z+Z+ex(?492`VhtgYYYm25rFp(mr{HjX3hzFa^;-O3<=FAOqDjSO7Yk>S~u33nCS6| z(P`>X!$S1uC;_}SxNWSJICOpVp-p;AWIIRX)>7(jR_BGf-yYL#CseaX-iL@8Yq}j+ zmG7|Axr|h_;b7X)rLQ<2XrQM%T*nc`vRycDPd^jjL z`QbeXsBxeyc6C5h$jq(BVb!Dojpfe4J(B_BUMDOAE~_xM-!tJug9)0|6Q?s*)iFbZ%{py{i8yoTnm($+tMM0d=#hjQD{J%d%~1-pT@TL+ zdvB^!u^*4j^cy@V#0UrRtsS}z-0#zmdhu$!0D7qJ1ltk$Hx#dwO`b{M{*n^f&D-(}R@RZ^yUR570~Nw#3fM)?~2 z(_&@!r0Qpc#PRu8{w$dy-#?Kp?u0ItSU&iCvL2nFcICN&c$g)u>l?MLu+5d67pg7( zan5}f)-r{>pjtPAq_upo-eg_mWQZ1p z2uS300_p4o#DB_u;E+~Mcx!G96q4>Z$(dc5EL+>xM@+2Z7E=yz-4sYjBQ%EontMb5 z{(&_PMYt|p7YY{WmM5xST-b52TUO zBr?FXS0Xt<7em`aCzvhBU#pJI?~wOkLbdg6(2a)@S>gQl5Sh7@_vlsV4%iOVszT}8unkmA4==d5BtvIO)=G7Es^RKS^iMx=1P^z#(1s-054>A^v}aj$sQr~ zV~WhRiA<3wC>0tFvI$EWO{Ly~l7FeT)_zvs9xMowIA**$wW$g)bl>sSx91Gh0{$vI zT&k%R=h8n2rN4gP$~DxXEx#c5R4|Tr=yf)~WpWa4{&%?A({z9C0gltj%N-uuW%Mdh z=ks0y$m{&ky{F)O=VD|dWYKb$FLSVYQlv@cZwCz%d2R2jwsQhuv-uE&;1{VAUJ<+p zMDshI$-PzA2G3@G7iS`nNwTnHWyrjRfpd~;MDDe+I6K|RQ!KVKvYx=6bf`td;6TFQJUBA@3f;5%Hx$0`pd_FFinumP? zFvFJBagWC}FANKcpyzJ3*|YjST~m9i*3Y3X`QvAnhfQ0%anbhni+~n~LI?>JaO-?) z_0V@@YzZsARzWKh{|dJ?ug67!lB9T)aNQ;D$n&v6&D>NWjjkWu6`k*H^3~H*=#MY9 zShtuTJE3hll74@VHmH36_L2J<08E;el2bpX#v##;aUuSsOla2%3mJv>tH2Po=r(go zOR&KuKjkUbWalFhFZ~2P${LS^O>6!>3La92wi>BA07@DPlgJM3RVn;&rxpMR3u7S2x4{)r5tt zerziEN&6~si0z)>3uU}6u6wM5x{S}WxetGILhhi~g`E)3EV&vG1HEi%OkupsB>xwR zCdy+fQn4gsK`=rW9ySV!92Ue(g7hwb?qnyoi{wC$GG=9hlZQpYj+SY^8YTM2DOc8H zDMPvPm1_iArBxWEy=-6V)-fGyxFiE^KG#AezkBWbwh^chXCwwi*A0-DFJ2Z*SXr{n zj*sIL%W1yX*PU)Q@kF;Teo%F!B2LcV6SG~iR(a7PtBqYgY_U+`;3^B5hz>le6{#A~ zS9>eV)QGK3Lr)p=#hdbh@1u(xwW0^QOV1k=P8iIA;7oaUdD(AV(7=jAa>8cL4N28^L}ukeVy9g=E?X32YCU#r=Z>aOEU%&CZdwN zYS7KcS!KpTn6`<(T8($-;S!CL8JYr;GPRV2OA*mKzn9nma-zwwAm`0RVWp#dy0OU# zFX`wsKd zx~QlB!9$Idoe&`N!2Zgc_VbIk8o~}z7aMP@3gBFAt-)``2UJ1TwJ*V=-4wHmIa1*^ z>d7?_G-W7?Z1Cr~{Ka;&^rk9!MK57LA9|Tsmu%mfsv1Pylkb$*7i;L+_$y{;b~QC28pE{#>#HfZpd7~wxl_(UVM2|-lU$r~D)?BXbVSNyVr`q1W^R9Lw~W{Q zE9oCvbA-Vp?8_!QF5Ju1DFs0;>!pk|v~*9Xc1G=dDepTZ>(jnz@tPF=!4_}kbkn9y zUAM1QAy749|2w?ZK|n55ty~7Ck&^c{i=RCrmHWSJZsm|9?zaYI#M57RCuB5+K7kE2 z59wbs0XB)LGj{m(3SeY$aq(CiH;$5MWY3H66yjw=l$$zD9cAkx*vGI`F~cQS5c&Sy z+x8r0VrfDk4n=mI!|=SHWF@`aZid-4uSH|2!V<1L;_gFlhpMba)5&a&jg(WvOFz|T z5JtyO$OmJw4jGwK9xGEKSA>+_Ko3`8C9S%%ttlz8BT6Mlnd=Bp3HlqjlJd0}b9d}@ zII*7d?%|hs%)C#+>k!A^VxJDlQQUJjbHOuGcy(>MEREC?IYejaQw0p(qdT>SkqNuJ zjOd?IV1XDkOi`a!P?oO)(3g;g5wBnAVJj6XgL++g=>J~l?@?Ie^jT%wRSs2V3KBJM zlyw8@9eDaBa)avNIM!9r$!E{^h@(Vb#F_by-%RYnl5|nKD5jEIq`7bEqKRUNhv7@j zCqhlkrYIk^z1Nqf1jNht4z4z**&Bf~bwf=O98z-mpof)LJS^SBuJ9r0`b63E`5cq# zHl!}G%CJ>c@h7si#E#LKx3ZKks2!(&=(dxHUe*v(BMuE4*eQ&JEsOadoDFq%Q)jXIF-ddk|)w~!~9#ns@fphJemL8Z!vBdoovx`{yTNMPlm8L?}~#%%H9CP1^5z`Z^Y8hp z+sQiM5xV+`3Hg@xvCon;v*2N1aaV(H{d8Un%!Jdc^^= zJ;1$l`A8PS17+AhTUq)^Ai*$Q;uqqj@-U0gN)O9&pZMmNV9`0J(~eWj|8}r?%f>{X zOz{;?ZCP}(p#)~O2VjUkh0B9YCYOy)l)|5Zy7GL!sx}cFvemn2oMDVyP^cSA280%R zFiJpFsa3v1(xnLZ?0b)XHCO15Q`)$<$a9E}nOgwO#4V)iISTl9-R-HiS0LVO)I*@k z(P&_TSEbz|Z~v0~!D#zWmp@u1=ZdDH6k~YN?SC4dk*6lcPQZ5zv;#ac87FG5$nKpT z?~jsdM4eH9A5-6%9zy);@mp7yk!(doz|Amvs{i z7Rd520Uph!Ie^B9%jeW&K`27+qE1k&4R0Nu`d8a37F&-vEpC-&$T%gx^i3}2eOM|}N+$xKwUJK+A0#_%Sh#T*c&>Da z*Q`~sBe%T-IKlePYx-JG-RG9JzRk!yc5q+Vkuw1p${BcjhYPaN-9^RpIJA>h(nz(D zsV>*PLohSlpvI~0XkEi7HML6sY56=g?r_e33^|d}ZuJ&EQ(9{aOjUxLuznFvY*TRzH^lzDQGt;xL zH86fc)5)&3p2VjxbsHK}n#+*1+@v@~$mbX0Ql ztPCY`f~^A*!d~(i;)uT|B#3T^y?S$#O%mv|= zS|%&=yX3}CSbNzOcNj4+TljGn&O@$9FT58~a_U1@cDPJ7=qEl~@N*z@JY z-CM`O?BC3@UhzvJDyavWDm}vBNtRt>K3c+mzP;jx5M3;aZngI-Pn0lRyxe+6Q|2a0SS669jze!D>Z5;t?I}R>?r;@_~m+R$Y{<-zqi znz<&Woa@nJ+Rz75&kV7qcXbps|Fbm$mb%${J&YA0R-xEDpB8#T6?L(m8WHHMR^R;C zh20#!XQSsi^jg@W+9|uDtPB2O{tEL?lt~^JF4kb;A|Zicc)Gc_GjQTfULH`^_Cpp! zU2RQ%vB5~nv83IULUBo0jc)#&?GpBD+m8m2$LvXRm4yMw%T|!qPA}>pim10{1Gu2M zJW=37?2MsVVwdvAeQWVOlZpJYn(sh!))fa`Ev5`E5W+sB7yXnKfhyiV9MVpZs6&p>13X+^{+F6H`z|X5hh^p!K@Fqsu%+w=Y|-_ z!S~Jq_j*(cnAVG2;xnYV>4of-?1rglQGq2quSQ3v|II%!X9mIRVTqPh;yR1O0u z|7VFQ8nJM`-)OA^x*)Z4iyEdj)IueAwdyG;9N}9I#7b7r8FWn?lmkG*`$<&Yad#N4BI7tv;vIqW426ZR`!m1= zXxa%~5GYGUMkd82e2ziMNjLRcX0NSxJIG1+PuA#aS3Gs51#63sX${kb8;5sdizcsv zUqb`j>=Ind1drDB{+)Vu+3&qDJL#wPh`ig0mEaM-L(<8TvaegaHLi_{M#3h${U6_kQkxc#4OE>I}` zt3AcY>o3it@$EcmHYUwKVK(1%MNMDS3hpN8I4B{}&{oKg_1)4vT=*;H2HUcm62JPt zQW_`A5~^N#O=i=2L*cx585a(<$@)vlf3W%HmmRpuIiBz#4K2k|i87ui%^}##HrMS4 z6E*gzji5WviTE+Es}ly0#e!`T&l9BpZZhVbi==-}0+7k!i+nI8^51BhQ~S6~d@)yz z+G9~jvG>DGN!28^{Z&wtcQ_V>&r{^t`)!AA5cVgVI-M7*)8&Z-TUaru%8{(yl6>~4 z8R{%zf;iGL3n?r6BB>O_<;o#zD4@TX-rvm}jto=BNWVEM-t|Vu%yQfjxN))+F?#Zv zr^t{WyY&X`1Cb#2{$^5?6nov?+Jx0t&Foz)m+?V%ewg#dZjDE^n6ef77k<9I^V(N2 z6R+~&!@sQ0$JD%s?$;51421q2VjD;GLQ#)e7PID|H+=hib2WMwIRwD`XNYlS!8LEn|kKpWF|okUejR1#7w~OT}sN z-D(`*H!h`*2r1KSG;&L9?IX&(bERVpV=gStbit3j*8q?i>T81rjic%BZ{}Dt1)iU9 z&)DSzrg8It5ksN<=hmX2y--)P&UKv7F+%>Z9b^E#VZc{HMO?s6WPaSUKWx;{FJ4;zrZ4d`5H>L zZyR4c`aZf2q?$>Mm|IeplyEqQn@R>`zO*uJnHVfxb&8t6;t-0u{)K<~`+D+XRg{>! zg*Pj2ezo9!L8M6It>j9CPfWzbo#q>+RfN}oHq3_hPRT!}Y+*eJ&|~IQc&X159G3}{ zv~Hu>7te6H48KhYxkIpYxxBWj9rUemE&Y7forKqDtU#XS;xu#~(|K~1zT9cr5si9S45C||I_xoura z21u%XgWYNDlhs{-O}^DSp7aO~2apjS;??h6DCj8>J_nh@J}upeGQ&HrU8u)k52M$t{DyTTTX|GMDB1C+ z(5OT;YMAdoW`oYCh}th1+F+TSqY*heOaMIip$@pUD~#S1)>kM28aVgj8kdHO84M#) z>;oJw^N=&)l)Omen~)Aaf0s}aJeGAIBpDVgd`BnSc4$$LuCKNo>U$;s%C$nK_@Bfk z*DmauJ|kY$c_wjW57sl?!K&9jac;q1dGJ{`}S# z(K!r|b=*e{NK&MN9wiw3`y12Aw>;9NZyhS_q8_kY);!-$z3dJ5{*xNf>j&6~H z$`$q=imREF3+}5_42i!ZSfYk+(c+1=PA$eKkZ~GrjKq2IPH|{;s~_!HOKIY zuv!}hUXhWwU=&xorZ9ycbZ&dU<#<`2=aaN-Kv(VR5sE_{K$QbS^G)9g5kT4F9IZ385VN# z#pujQm8E?a+@&mXla;9SBudt{*;<4Rvm0;@r-5t9mR@*`j-W&U0@ z+hLzob9phtB3&cMr$kwY_&!$DfLG-&eNZT~Og2gucYOXCGrha#w_#$L{Hk>G#?ju0 zCix>WN>2>O9M0lDvo~y*cm%U2nN3wXwDaj4I-SDy8uVVBet-Uu6tyH59kQ_|rtO(Y zQHFbadqxRwOm&&es=tv`WdxzGjyf7=zNi$VlYuo8j z_97s1h~-cH+ef>YA+)*VXjTOPCsb9TSlDjbNQS2N;5SLH#-L(*Y7r!DE!k8;@93TZ z&ocmd@_Mtyxw3GdFJZkY@YSgPF8An2&CgDY>5`R0a{~HTXNmU!T_WDf@W!~K!J(sS zfFb#%O3!o7zN-ekf^+CqKGnw3uK6XLSD&RMst1#CY5atQYB0+1BshEW?nb#ysV0Ih zjA_N!ht$gW|j(HIAr`JEM*BH^WiUVAXk}_5+*wzp%fNxe99X{<$pEBB{rNW^u$XaF$kT!`Ca!HVf+u;&b7IBii3jV=NiUt{txR}ON#>6$H4aKY6Oy_XXh{Y5~}pa!9e?}Ep{qt zQ7&lM;{{RnuiLsjidLk?lKZ(T_SQk0uQzw@d9Q{u&H) zm{din^>xJ;sqGifo2eH2^W1533{6M$tu(ESJZMt1BM#};C%O6(@97^6JRXyGI&J^% z>_qyDnzC+H4;+(X@o(ol&;Z?#baOJB3#Wva#RF=ZICpr$q>Bdw`+7L#THXZ!f)Nj5 z9mRhKI>-`s>Ln#HB81eaoUiYH9_D#C;5MMTM_QUof2Bxqe_CKK{pA43rM*2JszyEsq*&EyuE~x&P!&b4 z1Yy}E{L@Cws-zR*@>$@-x!?n-FAktsCH%T%$>xZe;8$1P1mXfKI(bI1~`W4Lcd`iK=ua6JSxcb?RrCJGLY z@SPLlh*lm%|4+R#|1u!|G*nKKl*CC^QimhZL$c<_c<7d_+tz@3j4U50)TLkIMM$OS zKE>4gcJ>F8z_Zy05mutvU2uB2p91$M@DU|CHA|G>Q2D<8k~GMsI@fEl+r}Hsb}p`n zX}owLm~S#2OdT**eklWaDQ5Sg_st^$ts5j_#7vKpih03^vxmT%C|8?2J^g-0#9h6n z`$p2B^40op)-d3=5K?~xTSB*i=y6@J4E_m(cq9YQC9GNoF>6cU>HIhG(7F=V;F#kr zJpV2Dd-ZIFv=#I$<8W^g!($G%G80^0faM0c^=gcVqH zOZ`zzROh5k&G8vlVzons5v9DjqHG?^BZMUqrH$xSQPPl+Wfy2siNt}D+vE?7Q@2xx zbS?UgD;7wz=%Vq1v>~+%y`i+8l75JVoIyX6$nU!NQU%|}S$w6izqT|tD%-&8>A4?E z*P_UMW)x9%bivKiplOa~6#I8`46i5lD*BG2pg!tn;dT%ZjG4y<@1A-M4@&_>B2K04 zOx7W?uzhHO!&I`-2wb7pi#102d0ng{U;`5G!A1Iw& z6N-m1_=&Haj~U3BFR6I5zBuF@Y5~^iwmiE!x9}c!Mvr3ORl{!*oCB(q-CooWv5F2O zEUl=@ROdnHy&y?MzF6wQ4Q#t=lYdGDReOU2*qjYUNlS9AN(X<8lYYCEw9`qOsdWrv z*qM9jcjAKaU66A5p}M1y5`T;R$&QN#e~D}0UB=^&E;cD4VnWg;@E2V zs@>ECnWT$u83;=ru zb)3|OEj(-4tO|p=j$?p-P|p8nE=p<-3#O z)YpA7e5^Ty+4}I2@b~)rzI)8)Zf|(bfXN4G?_$fsp+432Uf!L0={;89n^=pfW3^+OFfsL|M<7>b*KtaW#M|?% zy}zE`mc<;IB{{_eSxf&v#v!TIfuADePV|@qlT3R%?y+5b!!Dn=w;ZcAVQ$`+f#N%D zizWWXj;7!}eJ_=ANNeHiKdvklH05vtMepp&Ap~no3C8ur16rYGTV4~t!11YB?8vN> zz*3iDA|fJ;O&c1ig1e_@8IG)4(>xzQkh88n_^kswI4@QKk$z3 zz9M=ZY1pDjwxt(I6%iin-|Xe@>~r`aOC+it?t%FRqb%pJ-y@#}R})9V1gd7Hg-!w^ zxkiNyBA;zg4DE?cU!NOE1+BJO;XD_tPbag3hJHT^fBiX5kWrp97AExQFyFZRx$Aku z8qM#=WLB0S_lD)87$}rCBKy^woNBI3eD(Q_I14mpzhQ22=_r~tmj|X%f>hdlEQ6dm z^w2*!Abcm7=WNJUQYs-Xep9l-`a@3{E-`Cj(8&kBnSQV2pNtgGlP2{;5Am!s^EGK^ zXL5ZyWotlegCoqI!)TXF@@V3$;{{hUzDeGN<`b`O*z-u1TqsHD04z1NzYA~yl(Mh&> z9IAWJ5y)%aiyk``@-)EiWl0tm7e(hWG$RI7e^^rR-FBWw8>N#8`LRd4RY9)_arU)+ z3$_N~KZ>jjy7fep@-$;w_wEG|e#=KO+{zuXpXs;kr@p#|EtT)7l_Z+kUc>N0y`w%< z2F@|3AwN{IKm9Pb@mw%#@GrXaZxuTsXI<}eRVx>8CoArO!LaUNZMpG1U@BMOx;UmS zxKsN+GV9r?Z7tv_QU~hpJ}a5Xv1(j+OriOp2*+yNqKbn?P=?W)G{5aP(EeU@BQll} zy^PrAHu{Wug)JT}fH^8>MOlJlt7*ibuA08~5({tIiC<5CS!=aur~DEcO+I#GIkwh^ za`}#y@XN{H_4H=S_s-~1#~IfeBUR8e!xQyvs$Q32>3OuTT)>v%LWVV)7CQ0qb@?VY z)tGegQ}4n+(;`mN0yE`Y@q{r|a$BRjN<=CKvoVed-7T?>MUJkZ%yATwNjY_7*#Y1v z;h(j)gNVi)F2Xa^P+q5qmJ)|%BPtVOla!v&sixR~fhWZNh+(1LWVp?zl9C)H*@tD>SE)C(nXN$!CQ_?YnU-Yh&F{+ODC4E+C6kRtggN=Z>sgJ zs#@8_#SVNG=Xq3L^43(nF-$*$JYjem>}p%?=ps{rnQBJuY{XJ=UR}%S-J)r;`)hZ-k7L%Nr*J;2T(LZWlRS_AfW< z*{&sq!y=5CLSJe%gL1#dDQ5O1D^8}!3&UONbm_95At&S~YP@~57e!|>A@b0vaZPQ4 z9Kuj{axIls$S=VoL@ZR?pJJ_7h_oNX9yz(tpa5YllxHJYI*;)3o)sEXxEhu(O!cxUdFymJ8ouw>f_OWdnqOO*PUe7hb&DFKoS4D#*($6 zpUqzME}aXlclBWMO^2jJNjdf`2Wa+=HJ;J`cirBMGIBP|2&qX!@W`mbfA&?jH{6sv zJY2;ctv>l);HV*&MaeH8sqb4ktA8;VUG38mR{18Yo)ZQ%7@tr-akzxLDf4Ikpi{U6 z^i0XNF?Z`W;V%uRH1k#Y!vC`X&^S(E-|{mt>8O}Fhmg%D2QLG|EvRoPD z>58L=CsJKsY_117yFq_NNrk#J<~VK+)O^Ot68G?$yLOmpug)jUyiU^Vv(>o>$aaKU z9qHXE?{s8S?0MsD3#ol_gbF?dewVUTCgrlR_?Z0XyqVLBGLhZ0UNt z$nWw&Q0tQql};6EzXes)$-k%i&+eK7{hc&dCTrigdVavi37hH>mer5`@I76wsA)N5 zh{1@%ijwmhNaBVM3m_!X*mwWXSaW+&C!2C-jHw=!0@!-u3z{`dMAjx*&6oyk{LU>r z+^gC2$oti#+glM74${C#EWL|})2BDaDes*ixU%xkl)y#5YF`_%w)7r;@9h8c9>5I7 z%KNV{@9X`g39u4AzDX*ZPBsmcXcHlbW`h}06kbtJz2xoN{>24p-(0|ntos^+sXdmD zFBeyREiT$FR}%$_Du*imE?N69Vx)T&Ic;5F&$8?PK5MVJ`p@2(5i@spR<{$qR5%NX z5go)#Psh)7Tn3fxz===)k;J;AEy9-FF}HC~U~SlVQc6}vs%L5aHo@uroqsSJh*@F1 z^{Yi`?Z(?x8=|13l|GX3ae0{Pud*<|%X$O$#QmPRD#8W8v7Cwv*8i3~nd1*r2E8ZH zF*_um7Yo=pP+NTEx!cBJ(3{7P7Rc~V%(PSF3-iwIy=H*}gwQMJ6Ds%B1kzUxz2F|1^N%y=A0ER0xF0^JmHzo& z1a8aS)bQZD^UIi=C9WBUhYcx*8AAO(>04U`JH?DS`6Db`G866R!Y_74t@OF3ho)jK ziCg$(1((vSTZTU9i#krlDD7=0sn5_KJj%?nm&4`5w_}a>N>8eSVL2ye$pFLSfEIG* zoknr4th^t5WXGXv$?Va{XG^WzDoJmxgRtDlN?`sTs2um`tG;Sr7pR8;0*{LC9 zxyQ5NM~Mskmy^r#5iaa0uZpFN5^t&0;`689+NYbIBcN2V4!!(Bv3ryrs$dB|d|j&N z)6n(yE{9$3+HUC#iiwfkcKx_8H+r`v=XO?edm&p+l++=Qu%zaTlALD#>(x@%9;xE_ zXOF$hO%1L5Pt

P){jvk;!mJv6i-)$^>C7a%00!u~7w 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

}t4D@w5pdw4K=^sNo@$BmLAwOV2aSGx8v%cQA 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�B)H5nWOE_IzD2ZwvCw$`V#3fPV}EH7CuC$KSH@hqbZ(lofgX?F@eK?dp>)Ej#_4`KHe^ zR+*!@G#@Os|x@_0Ru^Phy!$A?{&OM7aQ-Jw#W zwIlBD##mLvGvWRJZ30`~7!O9AOZcv}f^}FTHJ1BP zxIz2Q@RL+J{^P?5KF|NtuvXK4-|gov)Y5EV$(kOgK3qR9#-&cb*a3ZTuskR3_9un> zGf~h{@9@#9zOUm?Ppb2haPEipUqYo0xLs}6;B^n@*Jg}u{JrBI2nQ)lJ2IF%Eatww z1$!Y;P3yOc)66Eemhk#Ox^%(8X4_;`b3kkxkQM$(uExV!>HBhlTUdIY`Kn%TK{rZyXS=J6@b$|G3&Erh!cw`i}ZrzWg+j*k>%U z-#G&U_8a$7n zWNH|{Af5P3s;9OlsIKzKwyafeKI8q7UcY#F`Ax=Ztq(h8cg-waClyeEh)a^Y+p5+M z2cE3}5iUE6QlAj3nHvJLZ3b7NeeJvdEU&TF4Nbn)@9TRz)t|khj9+giMoZx4#2Q`| ze*PJD!pgmpZa?IE&8LZnW1IeczaLOG#}w?ILxulEG>|elQtQ`+0#zz^V_bFcb6+t< zC4f%J3NVIrn@(Is{TFbw?6wyTfz;17Nv>as8O_3d*P`x=9K;a33K$mn@6;$itJz+Pei~@scN<0ykuDv4ryT=Ex?4b}-iF}@U z+gVseJgFVFy6C2TqHRMkgqqDd=irhzMS2<|F%=))o82iY=$}w?7#3Ec2HnM#_GmdK zjTMaaYFHuMh0FH?yba)a23DE_Ni^y@=V-uY2V|-n=X1RC`)Jg^qkcW86qyXphOmGP zz+oT54*k}1;!+enfS1)$d+B1`0Fz_JOAV4t>=#$#2kUe!PLz{ME&R4dLGyb zgLoCkVi&gCujI;h;~aMTW#?u5+}5dxBOpf#3Kx^%4D=d!uQ!8z@Pi*GD(L=OmNnnB zOJt2#603H!?{BXBaryK=HxTzQcO&z^PFsT(Vj{R)_^S$9XrOhT4EV=ii|~6M+qexK z|H^AHlMGl32P7p=M(3@h{>VJZ&^Z@dDRmfW??<*AXaez8j#~hT@jBoAiMtane=2?e zLsejz;gpTFkcGbD9Q$i^Aqp%SV@9Nw$r8AD*gj9I7DJS<7&FY zgU(ACZlTN(AUCJm4ZD>uPpr1Z4Xtk55v$A;<1jN%LB*x-D)S6g#LTJ*+{eVZTaqz} zIq7t%x*FNg6^<0qNnl%vSuL>g{vcGk^RV-?U}HO$DHC+5F?R~+S001=*@ARxKi%;1 z!pqP(uw`;kcS!C+|9*bMdj9B%d;Ot1jRLj${4P(HidQHJtE)aCF+?6$9v#MG zlCgEgO%B&vI<9J*zt%z$15_1|PVowj^K7HA0_CXDi@wXy_6goB^R0V{E=E4;&UFD} z#^ag+5})YjF1jZ6x$C$}bCU=1(f9IiK1>QtGOeGt>jtQ6m7IitC&Z>9amYaH6RjI- zzB00ec+MgR8u9tWn#ZUm@_jZdPgMJSdob|UE9_T6#Q{7*wnU>g(D?jvAzM3V%NfU5 z&cYsS@#&vKu}76{@2j~k>ol3~BU%|N+5av-3%?_{-793s@j) zN;RvT;mBo4cvDF>L?kjr(0IJZK%XOB(7yafv+4VcU>RC}l6R|3-=1#^xQMM9*%mEm zz3;OXQMq5}H)7muc4%)*A;tdGS3VHz*Vjl1h|ak!EXlz@67h+`q=LiEebPb-pe1;c z`1XmcH{NJ&%_kiGaAc4*$gPUEkr0MFM3kf zwtW0)Kc_X{qVIlO8(UMido&ZaJZvh7_9?b2ECPQAb<9h3yqv0S^2ciq^UG15fm&qM zx525clZ_S6I0ACPo(~1QcEi=j+ z5Z&g}rS#cNW7{WStu0ARD@oy~`9y{6NEvtCN<`I>)cv|S15wSRR<tABI8u zk5TL|-z==f{YNRjk7rQdH^TZ+ zM{cNEBxv+PTr0_9_MUEhja!KO%&eB|zp@rX(_eLfmqp5%9p#I=pM~fdEN54`D+T+P zJ?Cqi>lq5ZzXL51eC3~vuQ$x9b5V(U+Ps52Xi=&C*B?^Cn_UEA0tEX zpgW>3HYK8z+m!9rOHd$5^4v9%M#N#=3|9H8=#FwAUF`1p^vf$39^qG&y{q+yym*V*Q%aVO4`*;3&w-ty zrP!Ow2Z_GJR=#!`{I4=1ijBMeSS4ncUd0_C70QFX=D4ant5OSW(N-`mP`Zs4xumE4RK*Cz?Ya(*RZ>ipR9aF zY9W!HrY);;PmuhO*8dx)((sFiWunm74B`HWq9xAMq~K=C8H0bH1X6dW?@4KtaUZX( zH6Uv1#2LI#OENP)X-^w}`{i@6u2y#&smJf?5iM2nZsSL|q{VS#*{*>fv{SXco8$dz zGfXJ zjEgEd{KG=Okhc1!K?6;Zp;GK?GqkiBGj;Ru9?XRvA1nV@{cjIE4pbP+N@k>1W1NG= zo;Wh({^SmnDX+XV`2v#fYyD zHBki(}LU8ZgvY2D~U&F_ZLJYA8LDXkx((13R zl=i?^xoA9SaW+=}WXHnE$su`b59b?usxug{YQJ=ZTJNMyngdpLmT0WzfLmQi+Uhq2 zV+2DwqQP}*9)gyHAv=ZFP@54z1fdVt&~!6=3e`b%gIMG$`Z-*WGho{X0{7Bx7OFok zt<^zROK$&x4y6xcaHYnsi2oLq+aMU#$Td@9AG&+t2<(wwk^;H9py3|uziMHjx`qas zhBseAZ(+1(VmJ>Rz>qpDBX&8CK+bFn@m|4+|CsMA3S~d=l%DzSyZbnYvF@j^LzcRd zKix%njbXWEUl#lU$dNohjikqVMgLDO-Eqm~@d@rXDc=Rsx8<)-;GUEI?Ly0RG7jtpl`wn@?DSvTOk(5c3yJ!3GY&7x}O8Ukzp#(-!LqIlbN^ z08=gk{|q%vWDD2(qC#?M_c=Kc8wUW1kOR2l;DeUY* zV*dmiifOS6Eqo+z1`F1VB=+$OUIFs#8K3Q85^gS~Io25&8Qdh5;|smDq47o2Qt0<__Vb)db%iUiHBkjO|RJc)Ek+OKR*) z^$a@*e)>Kg%vxYs250MfsoHDR+R1rmsiZvEfD)cH7)G#VGTThK{^c&@vaSqz8*Atc zsqc5dnPS&}SkCTPcDwbU1s^2rLXb{Fmtu)53lZCaUjr?f0h-QZK%;@V1c%z{U)DE$ z_PRf#>m3YYs!o63x{Fs(ABkp+TG$qx$sOb=m#910(#%c##V@gC)$lakTS>wDN}163 zHVc=eSZ_hR&sMa129sZ>_T?1uHgR?E$8ezfeeR{mM2wLe- z^S}M-IU^aDk|PG@E5Iq45U`u#F3;XI?PbYuo#l%#l=cG!N~FYgz*>ma+8K0;VP}bS z#p=%mKXU24oA+KqzWa!u>Kp>E_(q`pJuiUOa-!)LJZ~sNLgORdm)MZ5IfWEAp4HJS zRv#N78394?SxMvfe3fDm+&8c!nc3}?1BxE`M^22`(c1E#p)!U`urfi1UYoe`FI21G z9OYeoWG^{#!uAe6IK+!j<9svq-wfz^&o`RZJX_~n89@$;o-gjB5kslbU=0V97d65A zg6_gYddCF(DAa`N5XSiScJ$JL;6eEyGDJ0b(Wf=BFMZFF76k;KvE1r!S;>XtwYLfU zD8H4^Kyw+MA+r)rE2dyFh(fUJe+5;iYSk_ygBZwTXekE6B z@2qQI{bhg0g$Lo(f8>gvG4pYMx`{fBl9+)ll+e_ELf356H)rx7VSnUgnIS=n^(qmu z8m-Rza@{Kl_Z0kE@s{ym`>Hdw&@WO~k4aR0N8i|T)KojJb;)c}j2;opM+E{SME{mh zF*FN3#!BKJHohWeQ6Qhm9o?N+l@6UTU3M4#ngFpw_^+@M2Tx86s*7{EI@ib*O)`N@ z|9Pogql)h}URhq0LHV!O#UB~Ki`)}|S_j_{V$`iR<~&q&6{Pm^rwke1*tJ5{AE#= z4UX}VT1J{Le^OauO39U~|D(OCWNMv4!_gjnJXva&5 z%x<@9t98`N(`8e0eaI&S>JO)_Hpp6AdWecbR{Uj@d#`9`TD{{>*&r_#__Hh{yrEVv z#rSUn35(pSW$Q)Z`Kw0CF3a?>!}DW3b>(X6M8xt2eTtx5;Zt52rdOG*u=m+d``7e% zf?+^zGa~|ZaPPPv#rfa_!`nX5+GK$3v|DriXe=yB0&MMsEso5{ojIMO-&A|s#TY~}(gZiu5Uf3A(WPo1JuU(fu=^7ov1lpv&`@Z00?FF9$D`^IZj-tk8zC z3w98sTVSqdmx-JjB@&MB+N})N2`2tqpN_S5-@LX9v150HbsZ=_7}uw9(5ZJtz}3oT z*VE)Aol`GtYf$crm@SNHOF@sTmY&Ng{1VkWmsdvE$>P@`kX>R2@E?N=IZ}jKG$>ep zGk&4GWdx@>lj*#Fv2VtnwRkjEl-{>28|9%SPsfZIYWC0V+}UcZ=7U@D@G1Y>G0y~s z#m^D@J~H8o6T;a1sY+Ldz;8eRfO%V?TOTDhH_v!t$wLmuFAxAd}C@j@38(y{xWm1!d>+GRZE!#t=3 zxi;;RD0io}8pLTs7p^=Wl?_+$Hv61Ls}t{r@bvoI zR(woFR)|rwt1kq1DyrfpPcA8R!vyQ%oW2csRTfD6ZBvn5lQs*Th^b$VD^!-AskV`h zlXsSN&lh5>W=Bo%I&_;s$2PgXie&Yw4t9J*E4QaF>r>}4ap7)A?qLb&nt-UEV-Fdx zIq=GdT{3C+k1m$4jd1QOEJmJQFBm``*c9N|@%@2$_?~21O`@=tulOc~4sbUx=xU{W zgTb1IU7VGTc!n`uIY`ED;8tHrVO3&=TQ+KEts7*GFNPjrFrA=8L+~ zO76fYWVn#2LuX#k+K0^jwY9G(mArk_`j;8L^;F0xq(&Jv2w4rML=fN7_HWnSFQLv2 z@(c@-A&1!#f+5}|*F+H48q;5gwWmF|qu0X%lGGItw%#czsvjQ>Vy?cvTJt zvm@55V~{N)Esq*BB^v&I`n=#FWl3*lf9=EZ2&-Ys?gnndGEw%DrD@_ifeXASE6~^THhpPQ%18W>i$bd_RydBvjS56bw(?O^Z5*7+MNPQUVK zyjZJz9&e^yf4w8QL*7rHU+7k5#B;H0)GMZ_Aaw6jRnh`Gq@mM*N0Cnob*+#RS2Krm zELPG0${!y-XTaXajZ`3(n8!1T&B|W0=@Rme`(ciMvH_>ufMr2_z2%~@AbHO4xw5Qu zKt%o%hJ3&4ohuGEPrz$Uuva0m5?^y7J^jrhhdA*X-2k^0M7ORY;Kx5}t@4+bvFPxM zD!V5p=U~YFB=o1Sb39l)^0}qFnCW)#_o$JuC~>=&xAHZ%1m$VAQZ}BgRJom(R>*J# z^jWHGecOuJ@`aW*))qLaL~gX z905b~(poX~t?+L(M$F6d$?LuLg$-vc5mYpTVUSkauAkzP`W0>x&AO|CgP<*_eGGfE zxfQuiS!iH)e$N9NvZwH^DiLy@cS~92ef`?lzdAU#hh+VRH2hr(rb=?&4<^7c2M-1P z=mwe&YO{D@u+v86GePk2WdbR8r_n=lX3ciG5k9C(qdZr(dhN%dPUTqYFw*zy)LriS zl)V>65eqYAb#O;b#>1=qZR0wW+MPc8VtpgrES3 z_{)G+4gY!+ymrNdyF3!*m=P1RtKU$+`o$nfTA;z-D=NqHCY`9mF0iy%Bl@<+F3D}s zP$L7q!DzXyW1v?0Y4__1A*kKdUZ|%#x@WaI`mOQ@-RS(kek&<+Z?gY}ul;uft;^|A zPZfE6+i^^oe`8FKL#qyU#dt2Yfx5nr%`W=(?nkZZ%=$A8(<-72JQw`j z&1}oM0kY*T?5ST~G^D}8Nf(q{?QMqj{}Qcxy?dx4yy-7o{%}ztRdqOTG;V#E-NH$I zM6KZC-c735WD3`&Vy6s@dSI)iZZdqdFo47qs?KBfccAOV8>p5*sZT| zF_?`-6QktfS^4)*Syb+>k-luu?7XQJl^P};4bik?YalK16;*{f&W?msgvn?RK77r7 zyn7P=tM}qi>G$BBbm&j>8o$to{t;693DFZ>#_47#Mt;ubCvVlVbW(?O)Mlp~Rw^cS z?K&38%$1C0xSMMom??<$4^+@?AUwRU>4Rd8C9j$k2ItCB0xCgS>~>{^&g>mRDhygW z#=+<2bXRfJjWKTjkx*yPFJ9Y1{RP;O<^B_$8gBszI6Pf-4as-X&Y7MMD)B!(-h_=Z zuTAWWcDXUZDN#Kjos4kWYR36x@4a!M>G}mf0)mLh~DiBB=yf)!=^X1yJKvTC? zrQ_}ZEQ>z#d}cErxfja#sh;L!kUu@lH-Y(bB7?mP?`Dq*!B|vN@d%3rh=fADd;X!C z5R~dp7P`d&^lX7@EXUk#Gq1=6ny-Gg_UyQqPOTn;|0@Q#8TceMo<*OE!V&X4X@ti} z`cG4dVu9MStu9^8!WyWo^ZR-I=&r7244I&GObUUk9d^yfn34@35QbwTXY1gC+($Tb z6TEl_p3Esi*^{;FkAHs7X-O!giu^VDIRXe5zCPIhBjtsO4C~bsr#i%W1-kE#w1<>N z(+r^u9(M?o5O1dKzl`@>%@8c2Fs>exILKkH)>rEg$3ajIM)nF1;cCNT_87w5ESXGk zH(s{&fY;tC?|^)h6)=<%xUXwdnHb>Pm8&0XnH9XcGNWXvncc2C4MNV{iD7oV+3|f2 zPcSt?G8Xmq={c{?^_1L)2f^{1U6!sohnxC`jAU%-fJC712e*9_%h|1D&CV-D z)A3Q8IbucA$KZWh4PIiubtF^0km-!s4|OMx&3AnsNS%AlJe|(ai_T;^|5DlmkZJEX z?9(y*ynDhyZ;H7+u7qG*)_)C zCwC?F!G_fW!UOS0^;f8Ul->Bo>Stl{E%x4+-wtaTM>W&N>p}zKAD*+QMclnWkPGd{ ziy8txJ5IND!;($l#?X(6`q?;$A@4QWUN8PUHqDQ#^&G zWN^J{q6cNnMZ+S&JK0xdCA92d{0>g;lbp2dY*xoOX{G?h$j*~4DQAPeGV-xZb}r2o zYtm99aP+%suRiV*`BB$_cA03Qo?N^n?H6>UcHbu4eJWgT>bBO}%4a<%WnxzTAze_p zA~>{)8t~U z>$R9fSMUOQ2Hm%c^`iI0)~iSS;d zE{p8JOf&~_k@mDT&d@{j{QiV5NnG^oJ=e1IZh(x}=Tk{_goInj@I^ll7XkqNSmY4*hSX zj@b}#>bgjln_?%3#71~ES-`X_W7HuDzLyKhtJfw@)KqaK+{R}(D`w{RoU-NXO0gMh zF`v%{yNd5Wh4#aL4yE|hFt^?phi~}RTi|jyE$lM&XWAZ9$;$^SF?Ei39;##SR!l14 zViEAZbsxH0(+3 z--U=qt(PIrYXm*BTcv*f8oWf&etjO>Ix{1`P2Q*`KivP%0*KM%rgm;7M*}q^P#&6j z<#*cbX|P=-x1Gd?pV`n)I8}`jbbxZ0K93VkTGPqBWyB7tuk19Jtxp-04#;?7qMTkd zmmwDwNODHzJQRi=k`vemHx6fq7K(f<1zp7JA1ox=rtSl&Ka?+`)iO^IodkA8(IujE0BO56YEh zD26khu)wYf%jhtkmm9@JZe-i$DL;(IWc%?TW;=AR!H-vNDBD`kSbF8A(#=b6S-4*^t~ zv=kf-5#C*(PB>vH@jC6bpBK_2y<82uUQ<}k?Xbo>f4ZSQVgO>SxljiUEXL7siY{K| z_oZX#1x96Uc^<9cZc&yOmR_nHd;Q@0@Hg)H*ZK$hHTeKIoGLyV;P~5Bv;Xl&!9Yb> zrsF~mbMEqRj>wr6@YNu$zP@~?@#S0{~}jyUWWvH>QpFHR6a8i`32W~FP2=# zmbPY~to_xBSHNp&mUnR&&*{u$X zT*3PGncJEX6P+nP(VN?yTS#X49nb#1#)A<-0<-uv$048>`Q$7=Y4Ivfo^n^p45nTz zd(IyB57?<}isE`at>=AT$a8jsXRQ0OQZ0ErD7q+KFEy&5**JmRen@jaYSxePflC4P`in+L90Ulz2`eHt%oY_h*myF)>2={ zHyQ?uSHnuL*V9U)=-KE*S*$Viyvp7KPb$YtYEv_RwYK0tfbn5)s?JE}eJ1>T+T?+0InC8+&X^c1C%KSx;LDoz2Ebn z`8C@6GOl!fYSz)hB1gB%43{*9z*=p4PPsvSv@QK5A%!$(^^3q|&JEheVfz!@*3$-T zc}XVnIx2#RU`-!395P`2lUB`G*SDZnP zlV?@Oo^&BHV$k2W8El2%k6Z1d$1mLDZ&nv| zez>=k?IS;PI04=LY#a&R*E4O@Rr8;hD0Iw}#T}V7tP079F$|1u`maY=iIz!l^^_Jr zqCZ2+{2Ao-vYA_L|ChDB!+eWq*TSx-BG<|y7>;*STsAwN15uUVG{x2PRG^X%@x)MW zX{IfYy!R3(o!?RQDOtAxdAH7u6d--^+`Zs#YD~kXktwutyS>S>imxNFQ*hOEs#pC% z_uKWY%zQA;P`JTU|&0ZV*Kr|743k3*R1#MWAk*$!}sJ;c53jD&WmZ2 zh{2C_4J|PbCnAG*pxDZ|z^fj^#{HpD;~&7mj88peiXCY(Uv}#uDhdAOT$XfT_Ol{- zhy6S;mHx!XwQ^Qp|A+r?!QCtPedXc~cS=7yfoqM?`yvB(cJ;ogCcC&l-{3Hh$=f24 z_Y>kn@ZZqdfgj%L8%n$`B)2%0W9B5b;cr9#OZmP&jDL&MKpnk3@DqaY?4nsL<&Z0Mve6oInay4B;V}H-|;3$c7 zBP7RiWnOBrd<&fBi}x?SUH4}Qnky^x_nJZEQq*oIXx zCBRWl$Sk*f?Z(A^i<{D!;xafH9}j;C@_g}y>28nvVgz66&xdB!G2!snlD|;F(wqF6 zye+alSN9X67Hm&cuqc^w$6rscpxs9%+M&$d0d%ebOj|6-pwOXG7Ye=*@Af2JwIc)HPmS#Qhtqxi$*|b}qv_n^nePApPh`1-N*C3fO11hpEYh5fbU7qemr8P2 z<(x6+<7^Ic@fsN2TuMv2V3k%1yyG-3|ild3#esliYwjCUB+p*sYGZy;&ef z{kD1Nb4vA+{mp;5ahd%G#Jmg}FcVl&kT15ylm_qvE70|o)qnA$wOnRS_}LHjv|fQt zKe$Im)ZFNcQJ#bE&N^M@A*$tp`FJ^d)wANXN zQdmw1uc1=2ATBrm4S8W-NDUXoOm`7EWMUeSKVf$kzDqJokdg}9En9zN5Omuh50jh!6>NYFBdX(ADDy)*Kt%3&U5kb0JV(% zbbv0+;4A@_*|iLXO8zhbjl~cO)&C_dYcr@fB=(;{Jg}mV6IO}VftiT1dCwLlLuPY? zU~eU-Lm7=Sy4yg1Vw3?Q+8;dBUQn}2?hWYYMbby4)5yfC^7H-$Arq@zmY8PCR3PBQ z{5X@Pc&wc-PS@o@lo3nHJ#4G>H2l}Gstwhwy%A`s3d12WNJS) z_u-~jT*zDh^DUUOQ5~xt6aZ1 z%$qvyz#~rp$m7fpP9;C}$fabXiY^j#7qapi+xKcWL!EW$nW8a#=LwB#QR21#D~@5W zWlFCGWW6l&Rk(N-`p`01L6Y8X25lBoJo0J;C>Us0Zt3rRDnZJ% zsBzZHG|??N5?EcYAX8atF!!-=n!86jNI49pO1Z~-csd7(Pj>RYC~8kllRV<;gZX!2 z%Yu~|If=@3_tO)S+G&NcRFqlF^P{6$)A&&`pENaWhCu(F8-~)4^Q(Rz<=>#reP3SV z{#I~QQrgE#<#$0h_FGNJ&uFRTAKH%t)r|Uy+Q3Uu5=-g3rD+UOaSCyz$fZe@YKVHX z4?(dXEY3;LGpU+wouW>mphRKrRa2~QsXUhNH=)~!!no~h6m_wMXU+y|VyD{oNyug) zAv)c*II*r#-CV8C^}EmXOOiMFsMN5-J#0QSkb-6xbP0SD{XKswE0a{>Y6cIzOu7iF zb&{H}^j~b>+qt^3%Gtynq#T-TW$e@V#CG%IEU`nx>vXQYna?n16!=xnBR@Wc`mUgO6&DaqpWQI;M3hLj1!(HsgypQHwk*D$aSm+s9zs_&nLQ}`E{7> z2x&Bbidwdue}|F1&~DxZBYTej0wUyVBez%AEq*F;)HZZxJikP6{Wo9ZA$O-2$bW2B zK1nYj9LTKTh&#B^AQ@mr2@y`m<8V^p-33H0g{V6x<|WK(`Up|?iTaY53i-EVO(g0~ z{RT|C`?P-njyuYejyPA7qjpa*9mHjm>;Es7dYrzxz<^(=r44+d1cUVmHJ2yEFN^CT zcOD>bh=;%~XiGWkLuGK$;=D*k#!(~iao?i52h$*U;Nszb!CrR145$Cm$nNR0Oreg= zPkcG0*>F`%Gl!)|9N>vW(Ue@&jFh zq1_Gph7CpRJSqGmcX-+db*iY;5%HolGc%A4%o2kbTl~V)KoFt*_l?(s`#C>#6N^Cp*+_cu>W*G; zN%IE9$>$|P6I1%=Us(7yq!~~K9@iJ&!@4%w zR_`YQu;P0G>Hm9g6ySfd?`d2X3r-t08#0Ol&g)3jvbdzAdc`3A%&Pm5ff(ffEQ1z) zJ64&1Hu^WrlnDKs!Nb+Bup*J#J9R=CQ~Fml9XgcACg+yzbcxxmp!>&9*dgSku}MQP6qsnSXpjp<4iPP$3uZq*{1#u-s@Oi*@Ac?Q#In- z)mnNTYwm%~o~qcN*wkIT0#tKMsbDN{?MU7l*(#qZ_8JrxOQM*Ov|#9%Am2u$o$hy? ztOsM!uR`=TFhLhlRMCk_J4Vj#;KN@p>hUc;1^q<=F1|S}w#ck&}> z1N=3b>T0nB+?yTzz#i{t2SDw?Y54dr;DP_{2R6*b;n*P6P)Z~EC=En6h7XgG-@CsS z04IFh!x_=mhBsK#+E1XVKpwh#$Ik%2vvG+n%iTLKj4&lf-TTJLe7uXje~wA3&fd?K7P*p&gA=N2#v^IL}qKOt)JhIuw&E1WM;zufury!9Y0* z$t}U#u-*;kH}BGrXLpcIt%ynDmFK|32{d*GhU84$MVqEuy=_ zCqJnEA89gB&L!QGa+)yRMHvtQ>ElPYb}bL^j}zCIZ9l%L*H*saxkM6PZZ&%Zp4K|1 zQg3SD7V3%qbb>hg&)(Q_zJf+*eq%(#<)%n!dPd>alEo2@v}vL*W1cVPh8Oz0VC%C9 zi;v>V;)bx#?)7`wS`!Mt!UWA#jeZFnP*3$WPTdH4vDRx2i$+OW-R;O8& zyy(0x-wpgML#@V{HnIQo$EZ!J!!BwrfBUZD(!E30k@R+K>_DB%(nlkn>&~8xI}@cR z9t^WxzAV$L;jk(fif@*-2@($#4@|EpJ-Ky=Yp~~SOQ*>r{`ijH-=Ge!pRWxrzE;}c ze9wb-HRBelvAMynED{kbUgVNNsL5Yw%mtHtc^vrKBX$jBScC6Ak1q%iKDOu))WZ{1sIYdWixbMf{bq=CLJXlZ$Q-OdmD$kCZ1%@~n!GkvR_ zBh+Txg!s(-K6^l59{@O%$M^>Tjl^z@9L)LZ%ciPXgqmk{&-6F027v8FOc|Hp|A4x7 za*to}m$DruL==$;Ym<8F)z6(<)WJ9yk9*nna9|I^babHC0q&cf^#l9X2R7k;(e-rgqlK-s4+g0`{uI4SDSX+o1Np*_m z6yX(%1OQimUdjn<*U0Jyb|4)%>`MPY$eaE?IP2R>FPpJJ+&4tc7{fAdN3i2dmfYF* z!Hoz_o!@`gE;}nNHiQL923+a5yrN@^xUi`ii{Q&LD6>)u6p{Z9bTn}Pok+9Yfvyxs zz73R*6FGO2yP(PPwFuZ|(-hG`o$A-D@T=bAgL42YjFyaCfgUVTO+^dTQODYp!tyEi zC*I`bt%_Wg`as&NC6PWxg?iG{bc~N$hVri8KS-!GoE1Mv0=WqC+OhkBd(=HPP(3%* z{Bo3%E(Q4IqB!RsQ{=nZ3DS!;Emep8=eFJVxX%_6JJD^;0fQfoGvayUt7T(|tE&Kw z4d+Ye?Cep}-V$g!zu-mWd!s|Xej^9u0Qc<$4Ju`)?7P{ANS*DJUP)2cKbwsc!Xi5) z0w;fC05A_|nQ?#%*9XyvkAc_R(mt(fOuTSNH@*=RR<0v?`N-JVM$cXEauyMiZPl2e zgZQ$fAKDVtN|fR`J1tD_XmAaS8mt|utr4$SXbnkJ=ZfEgu~9|Z>={uRp$kH_m7$jq z^!5bpfkprS@?RQ)%V85!%$|T)zN12amE55wXX48K+clYEWQgg|w+zK(gp|-W+O&6Z zl2Q8UzkToC^zRevFP2Kq>lwJ7GH+rq)v{=6M@zVe6E_i$SXS`G3qJOhx2$8yD~=Lc ze7Em^KFSg!GMc_#0CG(YPmc>9ug2Deece(zVH#t>Le1GrhDzdChIH=i;ld9QU_6to}G@^d+jPyK3cj>Bih@oox3F&PekjQ7s&R zJez{ctJ_Fa8`c54KsbT?hn8S@wo3iZPyMYlAXH$Vc>UlThI3tW<==_Em(suPAkVIM zESYZZF2Ye;!DXKG39 z#_;OdA1IyGH=j?a-@R+OiQTL2Jw#ue1D7v6sN1J^+pRKZ(k?#q|1+rnrrZDUoEb_3 zq*NDGXcCSBaX#o0St*KCvafh@XF8YhSFzM5+(6)ax&6gC7t`oEH_FW-63GcXy1a^F&GnS(>V2aA78t?Au<@C@|oI4fV@Wg zVsI+=KUc}ixV!pP!IpS>)i?T@z-Q@B7Q9{SW@JX2b$%S{xa*i6C#Nx^IM2&wf|tI; zO;8x%56%Hs&Od;(90|=*s{-PAYHyWiEQqXq<=8xUh0gK0x~eI|-5sD=i5Hu_c@3gW zQpN2~M{1;KJPMw+N;{3WJPw(#Q6v2ZD0vG|nc&-`@t=$ZwYUDQYEr4Hr0=zZCK=J{ zK*eTLPUBO!Jz~^--aK8leolI?q8}N2rYF-*y_I>%_IANU z7i;T=eOja==S}5pQD2l?h)Q(v`O5Y$!W9o?SU>=O(Ry``{QbaRWvz@m6}yyt|M?zw z^Y(y~kJYaA0VY(0S$w986JLp+IyR8&f=?c^S*mQxV$! z`FFtjeqowweW6}ylU~f~vjHT&29F}-e*?g_#`HXAL$$2n0F!W>`PGdg@VxI=Ln%Gz zlSu3QXvEARr1a6x&H@FDn2(q5eC6(o^Xb=hr3rf8qk6Qa4==w*$`Zwerl%vFRoW8m zWE0)urJB;c_f)gqbatyvY3nK)AQ{_Y30c#C{_s@B+wX+K`S&r|iH+xn?WMOrWD=Xx zA@|~7|GtlD3i_4v_T`DTI!2iITE07~Zp{%2W-)Ev#Ne0j>w+5s%*vLdiwSJAhR?dT zlG7Y209IkFNmU>5H>{4i;2pkF_%c0)CrFWJrZ@(2*GwBpjgWX7;|d<2CdpqsDAT-x zlzJEAPCXH+8-zz{HZ@vfvGbFkUta5+J2&~=(lzwI&hTG^N#E^21D9(xT?ZwV5bYVk zMrf(NpT?M+SCNpGCGHtTyekaa7gxs~(0_w%zWkzjACpn<#8dmrc!Vl*b|g)5*%^om zzukn>4dAMekyv}f^rAJMl15Cz_>L)E=}IEo6E&)7^AL>=85?_r{1dwhl}L#b4|iER zqAQF)zMQdiEgU)Oxp%tI%!t-spt+%UkK9q&gI(QyF*n_#|Atj;^_kR!ww6k=H^sDH zirvJB8rf3M0|c<7x`TZZ4(O6r%~0{-^w6@AURD2v`?~iHvgpAZK18jSEk>_ye171i zfZfMm+_`Y8p}0nVqV57deHvapn$#jQ%}4DvlzX~k-@t^}c8D5jU@3~FQwO1-CA170 zIo~T3v(8PFA~LG;iBBwGr>D1Y;DMDGU>|bz*kV=6rFK}(OUt*LD`-0YknY^7pB}l$ zPS6INLAg62+JBf$o4e206eCf-k9-ZS(Ofq+P&-K?|FF9$yY2hmX%++DA#SzqQh;mjZZzW!lp>ThrZW z>~>0AzV256gx&5l=kxn-e}TE3$R?L};qZ&)h4sAudD-Z!SeNe6+LPEFgI|L$K(y(7 zmf}~?v9mk~4zt4`wByyRsIPVr-@ZD7cQG`Kq>;VCB7Kza&hiT4QokS z^__LEObUeU{LaCCP+&kfFXk9xY}RBF7Qgf|w`N6I<6)^^I98EIu}Oi>R=;#mB6~|h zxTw6LGMe2kXD+R66TKgEmZgzFzomXRfMO&Pey5{*hu<OQE;TUgiey}8|~%c&+QPM zvkC7)tIAy63AXiQ`!YYGEEg_5QXiso1$U78Ataaa{a)ZpKh2InItbvwC9cAR5FqLmPG8WTn zwu`94&N$$YwtZjsqwGCR^uI3TMt&k%SFLgWd|`c@+4UdqWOzjPd(S(6*$`gO z@yRIq&X@A|kk)U>YQoOfxX*N-BH9(|J%1XB7CX(Fx%7S2GQC1u=t2}6HXb_rOCX`< zh>fO)JY2K=mB3?`ph|hhPu>jzJuY<3-UvPzXPVpSMSLZPXM2uAiqEuJr+eadRx;*m z?fKd*V%IK1tA7l>aq`~$gadEDxZ27~KzH#8Ta1$|&i}FJd)8g06mp+H&C4ptc<8tP z#;MLEJ$a6kG^956GRFHaRzMg~iAE1uHjvR|t6*t>oRm|RQKwIMQCu^_j1eLXh!?3% zGOB8&`GXRpv7@rYqh!ag#O95B%D0I;$gr&BF!`6jfGLtS&|fg3FxcCL6@>0z4Y(>h zi9&7ls8Jjvzei^H)h3xp_<_F34O2~{ma6zV4h1o0joOuD@@dUuuQyQ$HsA2XeyEUU z|K@n5k8{2)C$Nkr8*}NJH+t=dU0dgN zXV>1=J&_xH^%=qlk^3Udr#&K9`8*&`dLAQX2(>9xovWx6Bw+>#ld3IS%l8*|9dwjP zMU1ZP{f&iQnwD%oa`Z%rzPrJ-bFKZPTA)Aly8Ymvmd`=|!Ccllb(f)moq>%#?NQjk z^48S~Oi9wPrKVm6-fR4+iSJzZq{EC_yR2fhBLtK5u5}po<=m2X-&4t6JD2P+ucEYz zijTJ}E?3G!d#y*<_o@fck5`*zq$SUPpuC4D)v9baFu_xdmckj4sN+Yz;NmwlL!`)F zX9EOiuMQGgYx2~@H8XDA#`@(D8{y372km&Bc|O*t=P)w(gb~hF(vr9$-b7N7^NPd; ze!q3@#KGDf-OwDsdT9zug3Zqz746y^ND$V!Hg~CjJCOOFJAYf_n0K4wcR94*O*`zo zo%IobYx6slm8*vFQSx)vraBc&6(scT(fAzu+c!1>c)hc7WMsushKAWDr49wsREwTa z&8wir-8nnmFe1|KzsL-iB2nq~Wof84gZ>HOGz!rS@n_OMX_>}lnD6WW-ZVE$@D&(C;l!P$;0sY2ejeNWj2T^83kWQHhh-2k6ihV@)o5u#|i3 zH}1ClEuXOuv2+;jVL&>6`Bpv&CHZk7)06|0ExOddGx7i~rND`V02&*ZY09ykpyaWK z{@VI~0W9-^v7k-x?27%G}o%(%;@_rnjSQX7QIDBpTapgce zKJ*jFSxnEgw!i;#HOR~3QSBCxoy#LVD*i2*3}V!)+ePHK)9AD*2zPRz1F0hp!X@CWxf@q@^Gj>X)E z-ESWH6?0BIqIG?IQh$zO8&|UOK$;AxbH0|bxE|e8F=o$v6ZGGvE5{xW><8L9pgIon z=tZj_2IYR}O9^vjCL@QLv(>{+KzaxTMlM%NEbe9=P!~&gzH%Gc@?S7}gjNaG!6Kl? zzL{W=2J<=31&Y=FrppuI(o%0M2z|uB#-B{QpZ>Z-zybXC!MkQrOTy!6pa|=0bN(YX z$B$p!Ctdf(y)FA`U5@>y93KMY;+-YC)++@j3ma*&9sA&8o>TC{{6&G5pnu+hz^aDf z(5;We_mf9V&UvE4segtNrvw5C9|bVFKfe3(JPzwx=<_Az9b_4ZAbx4Q-f=xeoG#M) zR$D5o9&71Jd348vrg3J=Rh?+FHTOw|OO5I+w^dILs1@#Ff4bD|=S^@SOKy)Hp%=gY zS?_LO?sxxvmrw1xuiDC^Ls=nct)N6Vj;wJd?7}bNs{F@x=%fH@MP2*n`StE-*!b3I z>b%jc19~%eN8?t@WIgW_zmHfjm$SZ(+dO0@9;qA=q;8{z~}_9CsBpLK)^(YAk5)mkC#WC9se{NLn!no zx%6++IsLu0z=ZzF0>?Uymj7bmJDIar0Br>f1Vu4$sZj)2Bf566g0R zf6N7m?KF}3I?4Y0vCg7WV_N2xQH^lMf~;}S&XKl)I+Uzyz+{cAHLF<+J6!CZfJk4Z zzbfdio&CGu%z8e;^`SqQxun7c%J8plr4?z1)|4reg8p3j+ENYh8tkAeSL!ZH_^m@L$d{RwT>T@SvG*ou(QaouR& zh)+NU%K_18e?4fFtxH9(+9y9?`6;YeuS>>%kMJ5ZRN}l1lGYx;N5XRZk0k$tkaepP zelY}B-R@ivvx!Cq$A8lf=3VI5m-{#nx8k+07BPT?dpCZA_ZO%in=O{LZ8}Qncqimg z;9}w}l!`U%e>lVwp_d z0+!r4ZT$(PAevv}NgyEEXtM{#$%NXT`t4Fhd*70+Y zJ$+Qmov;1wTY>#5XM4^6tEo;wbN-;E=IlZ#T|yq350JF>4;!l#Ht?6@XsQ!kJ-lN; zDO>h(oWE0w;#Buh`n2WgVLWrno9_%%DxM)|6KFIpmdn?h4MMyj0)yiATty zwc2Fh+=%nfrD@(VQ)QgZn&+2;W|63aF+dMLQ4%wh-=+fWBk!oXhcRvHv!r*vDEHG# zu+e{~eG(MEcJ}MsZdbDJ@0!Yo{^$OT76CtkVKp!(q&(-JJ&jm<|l&90Z`m6taS#W zvB9)pK0069GqwADYT^MBHhxg>pf=;~G>dVmHngMHnd9W;&WH2$QAmHiO6-ZIbZQdc2HEDE@gJ8esLdPTdsR#E zOF0kHKUwcwQH0AQtw8z(fz9%kh*P8hOz?pIT~6EEf;+qu?tqZ)ganJE>kSdLgLVX! zLZgEt^3n%Hxi*tGCYmDH^Z&>QgFmoL0qQULR6g76>D7>nja|^HXR@Mz3o`cQvWZq-HtrH%@7f2#zY4ymlWa#s2`e zVtyC;>~1CVqm571elzqCUJ>nhVq^vg(hQ@95{FqDx{wjiJ%JoyYXntG)hfobygf~% z0b_eEeI*`w4#dcb^kIkjTRwq;r(~HQApV-qX1O}W#n&+~;yaAnNgFOI7uusJ~G(oNiBY6;54&T|v^CSac z*(Dj^sU)L&V9*%KY664`MP5aWbLB)9daf)|)<@ZX0>hJk+)AHjbiKAOL15Z#7}oTA zf~MEnJr^#bPTK}AB9=^FfAjyAt-Py_8f?93K_Ey=^UnasI5b1f}4V187Cw8nA zTm+YuXwY3t4~s|hRaDt4leEXg!A>^W<~X7#f#}XVPWL3D@{5794ah5BWYYl8;p8M% z&iDY}u~%Eek9CO5i`*9L)%|CR9smrJ!687so66*U3q!jymC5R1c(0#KL1L4Oc;Aus zSNWmIMAlcL=5_{1$EB;aBqeYmF8NJQFqZz!ZJ|Vi_+?bA5<#D=QwPrw>J-yViN*q_23r=~m5lVY2z-bBTkLx!Jh)(M)36-?wk z#hd#EZ0zR(@scUh#>J6CljxIEimH`=&B#lC7P_fqB9u|^9G{S<4$HddrQ!5+V0cJW4d!Fi>zwn!y)@iSDpy?Aa<2&SJ~(8CwLBAdmo?O4ZHXbT z^cD$TM;muS%43w_<`gxZ0kFHOlg`|EwAkJJqV@-z%toj?cc*2UTH=q2Pe7qO{av&-EmhiC4f{QOBMOt*(cQtjWDMQroL9y~{BUs9#Hb346@t zZXS4)R&e2Ra7;x^L9$E}j4dIhI)X<%L-^24f%(1-2=mdNWvvBkcP8K*MT1;M^zNgX z3pP$C#;2#A6~9y(bs3UT3^F~qpmPwuF5S!pZP(YE zdvhmkx!zHY~4u37KxLRXfR0<1(j62ns^B6qYgPMo(sy@4&)4RLP-(j%&h zGXmT#qQA2rkx@a)>E+4Nq24nM(2&RhJ}Dsbw)4tv_hiAXvor^iZz`wD`Xx+`4$-w@ z6vl<3lJxViO*{E|#Ccik-DGoYmBtliY4wcXNT)z zE_)!Q2Ie+K9u(-y)&*@Ch)`IHw*%x);a0RmiD zi-7l8rK8baZ11`hrG2-u*By64mEVRlhu_wZuZjj<%k9doE?w&Vz!HCY0qC>sL*RgD z2UIIVjM(8WjjZ6lk>-x#gWhKWhR-T90Mue4VNLhA_m?f+nX%t!&*lai@g z8RHc>mkfHrQcL#1}xbLJZ4^qg3JW<>VYP+EXGjdH2N-(~O6IUV68nU3-2#ed=^ z97U|_r>@O!|Lj0;=Mk|WO`1trl;y!q@u~z+wt<&+lb#hQNjLl(vR@!Tnd!(Yu}qHQ%`$g>=|?&119|)seDQe7lhr zILFNQF(YgL{w6l38vK~7`FZz(obf{y9xr`qrg&;jo#wIU4aT}$ipevvdrS)KSU&eE zbnUP9*Wy|bLUVf69KIzASZ${}Co5jMZh3DC z-ilxVshQS41SFu3vgCgDKs4oi8gcWLrB*hwafS5_m8|O$#WTNCQOfRU5<;ND8{Q|H4Ye+T<=6+?P#_2M8aK!!!j)_Sz8#rtmLV8`|{3L zHmbmnRUS})@(WM*vau$>b4+ym7!PbO7PE{Dc-rT638OCnjVF$XW6#ORRQSgB0GcY2 z{&%B9Z3=YM-R7It&O+Eg;1m0wG4&}u3P*yEToJKUFxv)vs&I8|^gpBl{XQH2w9iHD zLCQ6iUGBE>2vLwVePDyG2!j(kFK#z4XWY}N5cwSn(m$+f?^Qo`Q^j2}#5m0<$5lsW95`#g zeQtx0sfxE&Hz%@nFkYEzS3)xE0kI++^br+igsuC*bt&}OH3Zq}TW^D7fWngm4BPNd z?5GE$M)>5;9cPs2@nKP zMF!#9;y{)>O|99LG=em`3vwxL$Zmd-13@hbLWKxtJ|va6xc(}t-r0knSj%rzIt}1g21 z!Nia0CAL!|s097@K@IWPE%eO`uZ(n~`J;WnIFTBg+@?&W5rGVwwk}pMSI{S3)Y*l(;&`JBj9ghK%EZuHfJ z%r3S9_HP26hY}$86yu@9G6YdGcsk>&%fcYs zeq(_W_nU!Q;YiJ6D`V5`gs$0vCYNK^E1ZQisleVg8d>MT7Vmr;QkhR#jFAPOgq_ET zM5dyYhsUav$fl`vYss;&aR6vK{2dlQsYCbGv$Af74p}=6Q;7F*C5#(Sh8@ZZ$!MX# z?TGZPj|=xjV$QZ5QF}}?ZEPIOg^h;(+md@~dO_=YTB1$Xs;pj6i9XnN;2TIKDVA9E zDbYWGvm$&OYqIEjt6bLo)lNu|XSmwXTOo0*NRPX$qYOqO2p@TVZwn9r8Bx2o8$}E- zr{97o5+QxSXcZ-?!UCgTDh>$BR}2go)n0aEF8ED>lh^~F-XlM2rMf?<#i(3zQ!yEK zCTkB&2FopfbbHT-t#J-QToA%Ed`>rejQvWYzX$=HVY&1P_+d{MxTLrrHlam?LvQYiiE&i?9d+_1^BlJ;gbVc2LU|U2g8e9W)Ysxdvnmz zKtjWZAa&aTa7^EQufDSdEd4KE&>f!H=7p)$zMHo2y8Ju+vD*>Hn*+D*Kps88`j$m; zMES=$u~%;caVO|YdiCJQ4=(uib_2U8d{kC+eC%2g&x+z%#IK;)#?>7~DkH@4xy-W# zCN9uS(xYy7;{SI6%vS%9O4^kDBajf8;bw{E|FIg*)qd*QACJ0Tr%EGx?nN$%V*p3s zYOf4`!%MlfBMv`34RT+4?V*GfWEBA3Wq8 z@((hU-hNYvJWS%2?**Tjw=iP=3r5)|rk0|23}x-Ik?*p7c9WBAF^v3dJOo6d(1r8cltPp&&3S ztrhu-JY4?8-OqPaAe(xlRHP&M1J3`1s!VFDP`>}K0^Z7!AJQ-41#JiveH%12KhqG=4`1$F&JJ|Rgi0s419x`X) zMmgI*vXT~_OQCx#Kl?9#L_W7?1#?Isml&_nlv2^hH*1<~dwmhu&@TsxV=G~m9^pg! zeL5Z?0(Ew?|J9O4!N0iwGX#AWQ)P_tU;jz)WtIJafX%vAZY@=;UYz2)jWKiY zMGMg{det;#9F0&3eSGVjF?zV&A0SVaj2!ocd%)Ou48uyjqTIy`t#VZ16iPO96R4#= z3eu-dTOI4u54r~B&l_IuAny2`pm$g*feEm2MUSDZdg=C@x2tpFn(bpP$0akHB`RO6 z{T&K)<-oGhk7`dk7#xY05Wd!#cib2{Oq~YhGqWJ$TE}R$+o-1eeCMD=TEB)#YC0;? z*$<%IkG;r9e7Uxh7nAK~DYQoqkKF76OL=!wHga;S-GGNAOC{B8_>oG7BW0&1hc}i- z^-r7~-swvBHAQ&sxvNrvg<{K43fNv4%bUZY5ab}c2N^Qm;b zWtg?CJaVG`9o}wZi)R2;VSOA>qxI7Ta);OAuGeYvPAhN!>oik*$9|%7xWJ@5{C_b( zhLoq$y<+Tb-^QZahe3lNOmo;B+8@V6hz^F6(|rg1zGf>1Es1?Y#ITzupN ze8rNh3k$jBb+^vayK7mB;`Wik4S`o9&BM)YJ59}fs}bTtV*uGAIZp&jc`9{YD|7T8%e`!apG5PEsSpOOs95JOI@7*3%TI8ec;lZ(-OpVJe%O;g5|9Q2K z!dH&p+5Fcg%Z$r1jSAFFYXolaG0uU7$*iM3n)^vTP7V^;fNEJ<&c_0iSvI)&aX(D2hwa41>Lbgo_78)aoqaq zROQ0hTZv*n)#Rz8PF9Jc?%3sejP9}9Jwf9Ud6JbhBiCX?kG3Q~U@hww3UyvsPO<$& zvD5q*s8ABib^uTGUo)zFdgDMvI`B*Xs}Oeo9hnNUmaUu2bzSWp=f>Kp`#u$Y1c`;{ ztVCT#zeSb$735jUb#r?5C8BpNd3E{*>G$N!Rg17Z$#{X;ld&I;A0cH&b7@R~UP|q} zx2$qt&8Ah|Lyx9vJlb`@#Y?qM)T&-vg`IkMu>6B`Kj1L#*CNKz={sK#oZeYADbSXw ztG6084*?7dxiekR9pyha!z3GiJWoU04^U#IEBgvKTMsyb6KsK;ttY@S@(Gt}+b*jU z($Hv$n|d0rJkD_c@mwKHYxSjJn0Q)KzgYoO|20)~tKkTwuzt-4C z-DCeI!2fvG1yW-JYV5np>3CWRZ-!1q0q)$JC>%)0#_6!tLaDf6vukbTgw79&+W9+A z6wYB9ht(#4Y8;Rzaw=uryKlXtT(8b8Lhu{|oH0>;&%xr)`S|It{)x+>d`x%LsNTS$ zG$1g>`9o}tWeVR!2_6Fy8^27Ke2Zo_erBsh0HXuwiqBP9&GsjmIZC5XeliN%wzCyE z+A+`X`QAqwfxpjNA-|M*x@1~w1ow4Ev_$~6&xjubVs-WY10liPIw}2sZ=ak_KYk=5 z>gb4qk^e(b`s*ybjQobIu|`dVm2^$tsYt)t@udPOezGS7lrre}9=G^+Z(>tN4z8sA zK^2I1Q4M-H!-h*yjpH0-WuC|dE&CHE7?+Uu(SV{(nFLXRExGuL&WyQ;cW-dgWgXIO zbdcweDEQIzfHT&jd+aaF>mTkL^={{9-Y{%=exQisz@GJ4EyDAq+$;RSeaJ$mkIod{ z&EXb zp?AHCvNT!hEnDSqWbM@Eg6#6&Sra<~3wL}@k4#T>NyIr^l|pmPVM4C{%6}H{fE7Cr z6>ry^BZ0S5(AnQMg=0N<<8n{f`FENZ*Yr<3o+>G8#m6ef)=zJ-d)j1%!%; z=|kTlBMR&?AXD63E`LOqp^;Dj3 z?5ex5FTn1IA0j*l+~6Sgzhj4putvUB@7@vtAg$N;OlG~4(7_%+%bt~3ta{V>9YHHj zUY);?8{%8)cj&$V9R0|$vo`Q+gX4Pi?Jwj~mg&ZcHt+So?b)aH>A&D1a>gm-I!aM~ z@10^dN8pK1!UBpxHLY_&_Vr}PQe*q2hwqWym_@Z`2|oUi`AWpA6^Qx+bzP!Y~>@wKlkcA=0wVb1_4A(S@8}Dp@D>kQt$Rw_$RWut_=SW z@wj0gZtIQ*J$yf~RU*HBkJXgNO+aq&_2jc!qjc$2$_KN6$fT!|Kp^$Wkvj5=YbXlB zfTi<~j@lGv`^;cxp0+gEQ3*a+Tk8fh6upS_Yb{vI(q4B(fLRp#-->n)+TRMA;j=gJ zL@(2F*fbunK~B0xvO51CSMUDMbmPbWJ0`8H-nyt9rc0(8J&KUUMIUiq8e zlOc^l50>zbZ1>W`hyK@5v6o$c6Ww~aqk1x@hS;TLvAvL&2c_Uo)WP~theoyg}IzRH$t3}EYA&MgcA0%G`QlY3a&nhTz z(zkdZ6+p;L0Ce3=y6kwxZBvjoQ&nsUSPXD%S8X+I-aLh}p4NzI#}|mq3l7n73lk>a zqU8V)BL?=TUqmg<<@tk;g;}#X;;MjCsU*&^CvU6)JRoC6p3ZvT7Db`qXEc- zey_C-iT+B9Y+T73p6NDBM9RFXJIimXeRXEez)31oO1t-Rqp`;Q8QG(jJ`?}e1eIq2 z=JV56odw#W6lo3b1tWJ+Phz;Rg8KA>Rv7tvJP6G?z>G`kz2wMxpN^a zi86EL#lL-2y%v9H{h*8pCHZ8Pvx?#_NrA=AyOOVIap&%JUm2O}GIZRs*7fs=o~I%s zIKv-Itk6|_>2ANWZQvX}-v1gnXh=-N5HWifMV z$n_YqShLXVGhUxkl&58rRr4Wv+Mx@fZLcLVyppdMZA2F7)sKp_CVX;HnlCr1q5&sJ zInHS*Cf+wv{l`)2(_B7DNFw=W>F2H7)Ho`DJIpO_yW+?e=J;QitX~?nF#{8>!v zYhizSZDRuNBZ(VL`B?ow51nvWu4#JDmSH_Nv+F;XoDG5Y0y1>(jz}_CTI9%3(L|;m z06(BOz~RhuU|%HGFnmE{PWcxtk3_ABObs?t81gJWh!J#hAQg6Jv`KEP?EIj1_y z4*b8A9DIGBjcXbK& zMj4vu{vK!1mcx@tCRm?Y9Q7q`eTD;@f1SgMuq`Jf zI|kT(61U~zIh*;8^|;9xoEqzTtWxz<3B(fWoIC-1Lkf|;Z>7GCO6v3-ar^1Na26qz z47N_yQ_n0I=bwG$;q&0L7M9A-Z^{18y;q`#I`~|ZpE8)6hh>ZaP=~8mA*b=|$?{qA z@|A7~5D|K9fz6ld@F~aczdof1XCuCr=5O%l*t&ehhzhec?+UX3+ zk>uqbfFaRwPU%k${5?-=zoUqf>AzOUJC1Z}JP^xfO#;#ub%MdRoS6ZfAI0`ZD8$|3 zm<7&vx%k`;4f#Oq>y=IwE6s4j*;&d?RS!>XE%UWTM+-YDw!$_P0h~7En8a|5Fzeg%JpPeuww?w=LGt!OLgP5$uMFm;DWHrj8dx|Q zhH2z)&!LDfJR1K9w1%@h)47EsS;9sjQFmt9hjO{leuCN`gD>Mh2<};xqUU4pfz%l$ zR;18gyx#Kdgfkqr1lfF0;tUW~+8WI1GPK4NxWWsL%A;V>+_?W zktfG>7a%0sbT{L?$W3c-n}I87NnYmsa9YK%Q4H!SOu}BNa)o>4zUemWX|JU2&(g;K zqC3R_!}V0Ab%W`dGh>k@bDs$H=>XLx0=A10Ps74hXCu}3e}Emgv%pK(Z4`C0?pFZ` zXc(7XnTO!Tfm5_S0F-d}-TjF02*-_n(|4rrofCL3&io~OoDR6V^6!qT692M{|Mt#F ziC!r6Fl3gn|JfAYYO41Q-E>Ur4YKYFq&7YNqpVvj*l@Y3A{esGV=OyWJU#GcMN&dmFV{;)r=KpCfZBV*R zYP8I1M>?RTF__R^Ntz_OuS8xuHO9;d@!i~QQ(|r13$Tb?{n_!zZMsN0lr}$4q)Q62 z`6dPG=L*DfhGd&=ciYfDwCFt=APVXer<24M|AQrK3Dyc!3;QR-bEuJbAXd8X5=?if z@-pdx9F3x}8WVhanHTBQ;=%qmLFW@<)blBrM@`|b3#;EHm!@%!fX`~%V1XrM7*E`u z{u2Q>Ds2-w5)f#b$Y6~Jb#?C5p8sNZT<9!u;_!^!KRS&ark}C|ODb(bgM5p?(|Fl` z>6hY-^fq64zQ;sUzU|LQ7I_rfj`H64_j!~JQ(n{n_Q;zei_X^zryMm zOF3l1%{ri4N>I!+sD}EPU94VZEIN&R zs%Vx4=@XNvNbi8^AXzvh%tV@hb(mYEL)` z=EfW_l}ab6in)H<2v*=Ge|IfCY4# z-6pLR>iPp9D-TbL#P7l<>~(GmG6%4(=TRil8uP!zr5ZnGA*ZioW$A{x`3TajWK~PH znQw&OVuiW^;X@CgI~re>Tas#y!vFflRFL)(%6x0Vh{u7%#yx?mi1wT8*M->+=+=Cg zDlaZ6&Yksy2H4sBvQp{P>u{3Ne3U}Fbh<3cS$?KB0m}@LZ#8*Vuc==Gy>Fl+`<(S2 zny#jpv%H#1@IHgPBPAH}5wFr)u==355iy?>qxN9CQueTKrtcnb>vW0~mgBYmsw4#< zO%mTsQ_M0dTA(uCBiBNKn}7HO)U>gK)ibkoA|d4GFrQuxqZjtJwSFB+y$&YzfS3XE z5fec(c%P6asb;B{65;_S39666RN%#Bi(Uiw>PZyE)?rpBfTP*lUma(cDwy4+?U~3D zl?48Al$VY0{fBd;`^f7Vm5RfM|9*V+*^Ce`lWQJ->fz_lSEB_({t^~CdED2)ck0Ng ztcNda&v2TQeJA(w$0y+hD;euy+wi;^>iYc?<)s(>=TrS$9=Q~L8HKmGeeXsB`FRcD+dndZ}f2JpQRn58#9xz7!4&>h zOln|jMQmz8qZYX8(icLPpSF#aGklY$Z)hPm`g=aO8;PDrb(Eg8-!n7~kIY-)7?OUI z=afa-AMNHB>@hX=;;>Jbxc@sJd=AOTo_-n3o|eMZsRH{0-fpYli2#ikiXA_u8i)Z_ zagKBU6d7sPIg}E=51YKD-{C{v)Y?h))os;(*luH+ukPb_8VY!R0h9WDuDWivXc_pA z=l}MW0>ZDqb}X58k{t>fT{~Dh_!UAL+91P%J#+ou%k3cKMM&bhC1=yE`9ZaIhWO(24?<+n_C-h`{Z3>@bFR6Cm(u=mgPLg65tB2}a)NfFk-!3p zszq~9(#7_k*T43{chE)3sZ%_ICR)Qsk%aQwfCJpj!cT~`CZt*WEFkqX%VX$wim%lG z?^f+}-aDiNMO(tc!;~rG{C8!h43W9;#=x@CW$$))$mVDBUbhUV{pNrwX8)pRS$|J+ zP1uUISSHQ~xi^4_+WZEgQx-b~WtV(6zOME0Ll)!b-kVB#$t7gOO)}Uy$AV_(lu_(< zg)3NwSyjM)37Eg_vfp{*BJ^@q+UYIGaJ}qf#Bnx}?NcwwJRIQ%Dylg)Q zo8`M^A!23IU$T!qZgG=M{Wxn7vl>EEnw>ugXH`gSF=Z>%io)a0L&JMNd(CHCrF?IC zQBDV>IsvO461at|Mb=fC3)m8o8_T64+MLs!;tY_pueGBx7%Vlr%ovl%o-N;!_$qir z&8P}(Nurhbh}er-*1$j^-QdC7-U+RB$xY!g?62W}qu0c*Sm1Ke|1rV>E@-{!5~yqz zu#;Q*J-k)_@$sbqBj=>xX!izxqtOS8x>Md?Wx%TwM;Jfj^$0gcxo^fv#w zp%0c5r_g*HG+KWGEcwZrK>-und$aBKcjiRhqu^deM}2q?dWC3~k`A1YB1(1h+P^W= zw|0YOt+5pvJTzlW>3>VZ{~Si?39y!PMNZ>{sn-}+tbxbU4Wv%J{ub? zy`)pg>fTV>VA2(>!@EtMl`!Rucpu;nxW6dKluUjE6K&2JaXw-5yU@3da>Ai3Et;0r zAuoa!27EC`Gv$%!km**9iYhSu-toOMqB#`~dUgoQ2MrV`Gc36ohljPik%#@M(|_E3 zDdBTZ1;?e9s^HW2x<2`9X?kh3x?g_Gy%-O6;dCm<^Xpa5iEW9T%Pw9${Y+ep7zxu8 z(grP;*<&JNA2M(VP^YA0LOVu=55VjCG$)z%J$M-!D$Foz>ztXD8JepB2TBVbArUrKk1CKV@}<&^m)oa zS3x#S*PF$$H<01+JxS54U14lvj)_*N10?lJLhiOkLfG+`c$gMD=evov-LqIzOhT_}_mAk2=x4hHdYiWYwRGZQ% zHk(%=gOcSQdum~MF&w$Q_pt?t-e6Hg$|t(3t0t+r#U>}NY^XE{eCQNZc&jXLJ2P4* zo@K#dBuP4iw^j9kcmH|16-8%QM2hHS0RA2|exaT7%z^g{^i?wvok6mFo^nch9yv@^ ziu7B@Ct_DOXonK*Mn`&0;|nw4ePS9)5p-`}OGAREhC=45AjFWo{8DJ%{^P5ckGtuKc#Md_V59 z#5M35?5b+wlwcKY81$8TQE>CnZCS^@fYfGg)6AHm+t(pWwC zD_2a~rjwT`Vr@b6KmJ=fO4jOC7V&-UVmAikDo%c#9}I$hDkpTAgX#c1sZO zDw}SBZs~iagpUYnt`9^6kCmDh#KCqyzOyfvflJIXFTZDP0(ZiW=_KMROou86DSJCj z3MxCVp3!%Myg6V`Ja;x)FrY9a+MeoeFGn!4WvthFwE<}QLEQ_J{dd8il(pGe^gCqS zk^7I4fqCh@w<_8M&DT6OKOY-wHY23E(M|;20S9E%GLq1Y6viV#AQu?jYxyGYNmDdm zdAgDp^q@v6phvI&0Dm4*%+cdWMZ~?5D2Fu*CF>jBLVB4dINQ9GX5$=afteSOVP+nt zi|?d%q^xQm{#SbrY@aV!s3R6sfYtoed=lFRp}N|CFJ3J2yefJX+$IFK$)%Hd@98nt>ZO*m zekLA_L~E>`*bQpI9(~TN*@W{!q*G*~xgT6EO8gJJ$j%Fm!^LHD&Q5-eWsmL4R!jQF ziJS?zTC~b^mQ;7fxg`~`6;Zu~>rmkfUZk*MBgid@dO>^BqLcce*}tGnZIbq~{{muD zj$q<34qF<0uLRSZt~~790KV_s=N)j_kzuxz0$!Dc`JsNZ;#4r(cmcn@*tFHpK4_bp z$6NI*v>I=aqL!Ni3uVLmHNsR|Yal~1^NoR1afjH`nf-6~7|>9fG09zbvkE?>R7Hs* z*oSV#y0W4xP9!9pRH#>811X4`@!vn#=m|3>n>|5K4xIjMKrwRgyh;Oz6z zU_!Jvu@9uGr6qxm->F?3ulYq0k<`tPy|;IUhvr8`<~Ch{dpEqf;9VFg{50+`$+lHT zJr+V|lC9_3h<7rL7T|Mpo8s=caL+=J*l8Up###ix`u?)o` zZS$HDUmu);ZrSn7*zBO|HX+;|8zpFIwl~XI<$!XJN0OQ0SLS} zH|Ux+>mIdE1$b9?{Hri)*I@M^rsR~4cCP`xsITQkE;jGjV6f0KU!ZiMjI;kSt%#>F zJF>0`MPEZl%*L0myXrIF;4!@m-^|ZN$zfl?bR${6xUY_K&kMFhy|=w@F)%y(+g~YoLZ1sfD|Kox`u=;&xXfm1+a-K*Qb+ z9Xf9igF2(sHT!e{=4S{q5L5-ad{n(U;E>NO^kcVKzBbuhEz2g++FBeZLe(YR5czSB zH4QGnGc{%VLZqN|qUSOns1=_`5Yb+)966%8MKT%UN67k$@rP2C+|CsAswWW00Gylr zU*4Fj>WWOs`Iw5;n z*!}Zi_cH8mLKl^&X9Z`weY7HKNS?Cp6c&!6EMv{W%XF4L|KWd(!qe@6zRfU}=iE>3 zoW=C%?KG?da5PPLyVAct%c=?cr*|QvUHnfK?u5r5%f7w;OVYXW#w0p4k8qNVp3+{t zpr=FmRSKjLHYcj%3!*o8R_t&X>GFv5$K5xQ+Uh|>%)XVT(ss8IV zZxj}4o)&o;VlR*dnvJ*ml+$z8)4OKZ0qal2Gw^_QjCl^H;G}BHH=d^ldJg88 z);YTiEwGVF8{Rv|r<{fZG?a`QH-wfezv8iieT>`yu&dfVT3FLO_^D|L2&EJ)P7))@BkD<200I5qDL zXu&BzOl+?`4c3AV_nwHMMz}E?TnxxBdy>BIc}i3XN(>7a1~)A2oas>X7W~pE*4cP> zqL%Kr>Ad;tnfKWZlYcYXBBFswYfM1#KXC-&%H}ykd)soFqjM?ca?o({B`m9SibgrBqR<1K>Tp8ycCBFT#LS5>bTS=5UDQa~gRd#NnNg~wiNWtRu7q(EM z<4YNq5xl|>uTOdHsFM_XOm*E8J}flg&1h;2QiYI~I!wjkdy<8=cQ@g!6laPPI+I zg7x2}0BB>VOqsqO^o!8CYqXGp3OOW+O zhmPx4A9K2yz|?VBJ88D0~?;7J~y?rTJAP>IktT|Hs_(ik{|{2Pa4eoO0U4|61!>Hj)C-e zM5^cKH;!T@H5u%Hes9d(YC$y}L-m{dgytBT(GUPs9o{`lmK+-}q2Zvm!-MFcW`Bm& z;#bR>0?4u2^iAW?)7DG*byKtHUDLhRjzOXclT=q2v@G4<>1Lpk>f%V3wt;wngU*_* zeu&k&JH+X%_B(59V(P35?CypMMj4kI&90%}(d|186&bmit~=0SG5@Y_+VZ6=d^8ry zw`XD5n3kvC`W4!kt((!7Wl{3|giNx#vX^WBEAR1+#x{u%ZG?nHzdm8`9zB|X>{A|Z zEx0B1d;cRL{L@@Ac*#kP1z@%#f?IfT|Cfq8txlK)BG-)n$@jFCopBZ=O=nHFn3pqAieYQl zT+vI7R#3gG)bsmaGrM_L(eftaOD<5&>35S?Qs!!M!DxeRBHJy$$YN_C2N&ACrB#8G z^a)%lkOs?v8=B-J1wYZ>lYowXvG?BZvpre%VUeu-#Xlyei`#@vGj!a{*io7pbN>$U zi!^*U6pTqvPM7S{a-iU1f?Pa}CxFxa6}d{kkP%e9UzONmJnOTSdb7{cP4g zWu*;O?-5x<689Ou*XscMMJa^DqkZUG(t#Iotyfqj371xb{36 zk8{zC%zU4xho-$T^{dWU%j-Uv$ghUJRHd~}FojvA{(b}4JLpn}`L`mUah(CF*i6|! zOdH@W*>{KpjI8+2klSSp8KiZ4nXCQXjMSoZW&g>-cyy#5_oCeocle`OR^eJvM$o;9 zJ*m`S35&VGLtRMD{6G=b#5=V2`GgGfffAv1R0tm0F34VL_ejsQ@H#b-bpgJLJjD18 z)y1KFkA$xQ<1bsXc7Kn&L!?w(HiynH6yI1##`y-XE3{UE#sM7n9MO1OF+jcPa9(f^H4)Jg9gtXm2 z5oCUr4ciZL-2cGSUrE2aaLlK)!TA0IkdVWtD;xgz4>c-2&b`!dnyX_UO*?aP{`o8h zcmxOc39$1tAwhzCx29y;Z_(IW>F-l&<0CyKu5s>xK5~>&bdz=ShU_C-iJId9b`LTi zKAchfES1)##d9^EjY3HYF(^J+BTplbvU-GJBYUQa+<+Te0Xk3xNr!3ONcAd4Z>CbQ zucE0|WN)P4#}g37h1mC`HigL(Mb8`7Tdr_uOMr&|SeY-vOYm?4>mH(}EOXTaRz0my zLkhXsVfR6n6@5tGkT)gmzz(T=5DfyN4PEdG{yX9sT<6#X&AQ%+rVQ_`jcYe^=WY_6 zRT0(pP3}(r>_6*JYbV9WhmOX})TrV5RRsd=iPB{+QO%#nQ>o1?g>gmA+A< z)LI58vDI2j-(I-|0%=KhIq`T$W0Q7G*D;K@`&^pjyCqohM9ey(wSta2)U7mLIM^tX zzWS}ZGr@x43=L6LNf)8@E9tirE`-uAMEo||&?+q7ZHZnvJz;MVKM6s{v0eyr)JD-`|LSL;Dov7eiXjN^|u8 zI#@-lD`MPa_o3!j0dG;^>Tb{w#Kdwr?1A$rll2nK+(Ii&TyN<(lqh# zyR?m$l^9Oa*}b;6U)%VK{4ZFFG{hySGuyMn_C9jm3N#X~>^)}<5^tD>S1~997E78L zni=M!tqsDfAkqs{JY%J35S6$=>6uUr)BT>k!j#uI%}+=qm_Ih%9L-DwSiQ zbkM5LGM^Zgw|6()Dv`e*Z<}Gyn9`;+g8>uj?(P(=BA~RvRy7eyR}z_uhzn*1)vMe! z#qKE*(|AR2Y4pNI`<&JU>L=^TJ$Z2xge`j*|E-6%+O?Cg1ra6|JWyLVWzH8|CCv#^);ON{IBn*iP?jQvzC7 z{2K*}Lffap%u!fm=Uqf<%W@%HW>n5MU9Y?CC0Q^aTEXD&jR>AAd8!b*CjV`3!Q8q` zwdzMozTM_8irkJn3(&>PZ@?yf?^zwONV&=5)$$&m&#U&)`wWn3SeTVf07_+<-Q`m9U{95j9ef07gdTlHs zKY$RC^!Ao>axQs01wALs80c7_8Ehq6Be5h#)M%>L7=`A3JTQSD1B3&jrRfF$g+PXb zXK-wFvZEr{qium}@$t0*AHkMnK_XXPmTBzzTRw&%3O~kp0%?J4OFier)l&`~sUB#O zMAUw2i+btk*)Ht60t`6MT z7^8Aa0irKQECe7uJaXi)%Jn?YXCl?D@;!^wt+=n$yn4M7Q==4}FzjxO=$W0~=P_Eg zZQAY%J+@YQe5rK&;(6q2>v`6^h%+8q6zY+Rvv9c+xQS~vXVd+=AKlp#suzR?y*$Kq zdeEMO4VW)2^1voRs=LKX>po`d)g(&BM|a9;x7F=)AdOH=g%-X-t8;PtvY@H&)p;`)Xq_Y@K60zt4jX$U*_H27$-VEt0| ztep7hE;1JVW&bB?>NJry>$5dKcMiWDG>+S)MTQ2nE9SV#f_g0>J@Ko?8KWInpGKgW z{uZc~!skKMj6R-hQ^&!{uCg0*@K9x(R)p5fhvE64c zoEec-^~zsk*l}DU{Ev(@WNgSH{?r}YcA@ek!oT1gSpr-1Cs(c4ud9_kb*r)n!o>YG zUSxru_CUD%Kljs_Q9@{^WxvYspXZl3v(fe*J9um(C~pqa>9jp-Sbwe39iiUnWXD)Q z6!xQM1`hRc|E+7*-J%vrLpQl)gJ)q6`n8L`c)$gg`l8p`Y-<#D)K)I8?ja&Ro3|>0 z!J$`stpB|Rc0dolnz8M7OVS|ABT}L;K{x@{$RG3&;}INv5ic;GlU{>mP2;vWPm6&W z^=h^-%VkfWI1|SCDP1{DoxLMMe1<1}i50Uff-9g9|K5|CU(U+bt9Lz#HX2j$%{mxq zB_DV1;%&ssqmEUryJh0uS2p`xs*6yqa>wSWG)NMX7vsJX!g1Qfic7>;kk)U-O-zmG zp2gDCp=eL%^6!5Ku5E(rmBw=gPE(b>?Z2%g9EU9}7*`wT#2xn8zy5BlxUuNDC8%w4 zIc_pp6q@Le_a@~2a9>BB&9=^(B*jay{J3E$?BY99WGr+)!dc^QPCLyRVSv>13ZXb) zwZdrkxq(d|YL^10a?9ku)B&AY+wwsHqpYD=i@|yeF6MW|wHyXiiy;(6A z)D64i0z6Uu8M==J*OI!Dfe_8hFK;q*O2p4}>!0|tdg|r-ljoFpn7;;wFc-TQu9f6M zrO`~Q1W0C{Y-l(2X-1_L=CMTtA2qqoeq|_xO;*svo$#6;2|HU%8Qx7)zsfxd4Yyw= z1zC#di?mKOC-eMO_I}`g;5J%`BSgogjor$P7yCOuaMH9XLCrbs)_+VRp8Z)Iy{P;v zA;Um6lZYu}YVF7UE!>OO5eQ^S!g+QEgveJLXU4?>lW`g-7qk7g9IsMAOz}dsvn)+x z{;pU1v<_izqrL5VytA=9`sSdp77l8El^G{V8ZClZ79NfFk0f)nvdMB2bEbP@Zf#b7 z&6e!<^={BwVm)bns4tx%^53M_v9kM=Lg?zE>^xgRZ^(BkzlRPE=a2UjF#vf-DoOjb z1{cTeKIf|2vLSkFBDD4(RyDFw{Ik^;icw0=^h_74x)=&Xq()D6&02RK?Iz3)x$Z5t_7r$ay?9+H}m{R3uGQ0HAe zs#fSi@K)&*2vbDnM&)b-vGaST}cxley!jgjuX7F%fG=uXNu^7iUivX`12 zx#tkjCMt;l3r(3K*uBBBQ}6bu$%xEpgE9MVC0qfiQunXJhnFtR=h|@^Q?@(R7#FiU z24W_d##%Lxk(zYdo&r#oAeI%gpERS~mU1*CDUO_29{3VA5L8awfBA2Wo*PZXotM(h zoKoTiAGN@U9pCx)U*JkCnTq*XpZO1Fs`o;5>rx`bF~644VI|p0u3vAfEtB&EZgFB| ze2{sR*dlwF*>ok|13UZyRXuRx79!q}2U5zI_5m8{G509d;{m$g!V@-0y;DPSSNnaX zR2I7$^u2S<>k=-5XlA^{g@J!g*}SZ<(YR65m>%mqzbwS|AF9+)AQ}sxRV>r&me@`^ z9e5}-R)kS?yV5sP>Cc7z!Cjj1Y7AroZ~K9zF$~Z!1o1pNWdDin=i(@ir-|!gA7}e} zs5PSc6SIB6>K@@PZ*}`1=&DGVRC~fuLg!;nxJu|5)JNjirI7(HkSI9ja^lhLg1Y%U z$@^|4^RCzhS4YtMVrb}`e}gsB5i@*t!ux-{EeWdo^C+H+Xj~TKdh$VCHbXq$XmOl9hB(Hgupss(3s5!ew%K<00EX0WieQP2QeSdAr1{c@r!aEjP=Q>5ucMICu8yTnJDKx=D!d!XWTXXx2x(b$WiyU z1iIBiZOT2A)|;@t%dVC9iFMn_>j{}j?;80WbT+R`zCsg1q0ML>66K|49!*$!CE z4pXC=Dhrgmmx4KYIoU*cwB?gk!qUfVh@0;0rXX0an02&z>YPSI$g0y0uNB_jmTLY9 z(^Q*1$rcZgN{G{1`kXgOzrpK4az{c9K_%y`FOYzhPQ=?DVy(7o#;j7vi0`!;w3s7j zCI}T`XA8At-@f{@HB5>v(}-I4n?tT{&vc-1vJ{# zysc&^!Y9J1GVCNN#d;i3%x~BKWd9I_H}R8Y@P0XraLCOnR1*v2C~nw!rg+CG)8PeQ z^QPS+_6Wz$6s4C+V&@h>cbtw&N8P}p*^GIY+H1i+P3uiV}&uW1loIW_jdi6cUYkvB#DJmZh@4@zL+8DQ94wh}t64&lDq#F)R zKaA|*t@b#w{<_{8Zw0A+44#)^i7HZ74nD%iJeY-v-?&A?kW}Mbj#i3HX3$fOd4D*4 z`X1bBQH+$`wLdURYtjvEHSYBz-b_>+@cp!KI`x12q z#kw>5#o#!lemOJCyhJ30YT#|SN#3m?*T51sJ2nL}oV{y*#jMR2fxV2@o&Q!EiPSS) zQ$mJYrud_m=Yl5=Th%u{iZTM`hxuTCu0a8VYbl#X8=7ahlC3g`UkJo*?$U+H2c->b z6$f*}xCB{*eR^1WCF)yaV!NW(ykYc1L1)d2lLx!DegQTL+h(2DlW{Kt(_hq4Gw!aQ z*grD|s-FU>g#)*q-W(`932G}L7I1svk;9kCDDSHNa;g6fNhnCX2kd?kXsWqSXn)D) zyU_c-cE!IF5(ag5za-Qf3vnbQ8vgrL{tN$$VjVtc?ZBz+*{yY%ZU5+&*Y?pmR*B`= z7s!DrUMLl%lZNWn`+yuulnTMw>!fllKJF@^{DA#jt&*You`RJKNeb&{=AcU}J#R!% z1>pYsn31xQ?@m^KejF3~d@S8`2%V{?+hP=MfC^kF=Q8i+)`z-XRZ$VHs%OQLS$#v8 zt|676yNi}?+4KXtDzpx;Z`#8|JWox(m8DyFgC3({j%8Q0W#&*F%c;cgt^ou5)00%6 zXSlcC|F1{6 zm*;JJLVx#xTcay=a8MnC2^|!o_=ZdWcB2TSmYK0r>pJrJhtqF*Kv~>(DE9}{z8PwG zbo(XDUftR?B7A0yl|S?9^8aN4B$@A*oQRnuOmY`;_D33K@Lo2>IrKY_OO868t$@56 z`+mPIZ__i+)A|8BeFL+o?l?Mp`-K>0n|ZRLYa2+^%8%7YEc(M;M?MfLNRCA~tTH5S zwC&Ir_|8GHL&vE{(MmOxx1G%w!?_-SzaJV7)J9%;S69dYb_AwPdLa@c^Trln$wX9i ziU?T3bP6CSR*XP~nC6lQWi1gY>)!J7Nnu9G9Q3Zld666sX*R3a0p7L~<-uY%CROjg zGSTcnXx@c>pWRFTXu3a2lQPYJELrjPwOVMC?QDt zfc?v^`DT8FAZ_IIxiKbaK5lkSH4=|H;yj?n*4Can;`VtXRVKXy+`TC$WJ@=eJOw4w zrN~d{X8ch9v-*9a7QAz0BY1VIcj0X8K}3oKnc46*tYP)bAL;h@oSk>d*6*iq=vQ&A z(cYT9!XA!{UiG4pKfwqO$6p1RpLLc}!Ae?L@eaz|ee`|GaQiX8|YuLE`o_ zK3Jf2k(ZER1>t3-Co2=y@ZN1wVtSTn_mJLR_`;JFfwdObKS+pR^Xx&0Zyoc1QxzMD=u8EQ?tkS4;gV+kDc0M+!(IarJ)-rEKFg;pE9QsxIo{-2%y1CQbWaZgKs!3V`F3!!3(T0ih)px)^|jH2RLNFbpl zkL`1{ePixge5I62tiIuisMv#iVMkb?=ed!k)knH1HNQ>gb5KKWqh(v?zCR~Dk3MD^ z8whIjbZ!(N-A1X2aT^iU|NbKAG49*gG}y2X3yeI-f{g3EdmL5cc=)ZzsfZHf(D<|7 zE`im9Xtt6EmA&rtKPG1UR|qmF-aM*aWkB_ltK4C8zmKmHNX|Z795Sfl8c|g^df|oi znFn4mOY3Gxn6s;$tz~1A;H|K?rn`y4VhafvZbro4IWLkt0HlIHcMlA9n4$&w_Gx%d35veFzv->d%{VT0r=@p~z?Lx`$e0C8}w`-@=p3ADA@E9N5)z4$2-1rr(-f z7a1CF5FS(83sRw#X5SxE#$Gt3Z15?3X^F<%c{gs72Dg0hg6sTRc4FkZ3G8-W+IR~+Y9aT51VYzm!gRLj)mxf(ZwxG7(RR%w+ z-E}wd?EU4dA`GONGW2;&y~p;u!Xmbt`bW{0C$f8z(?JMoQ(mV=#;6v2MPxw-e71qV z)L~9Ra3ndW6ticBDD7o&hR9g76q3?644TxBhBqT<;z#RhH>I$z#Lm#od-@sEbYZN! z#%L|41rX1~q9iOEkcdk@1c1le|Ls_?W~8RfOf?`pzb#uBsqDx}k49}P-r3W@T-bFp zT^vpE?tg^qIlJg~DtI`_yIGvyCOktdpeUSTj$JH&h^CDsjSn*b0>h4kOdKkpLouYA z)A1_`(fdORsX21&uzG8M&zmj`eW>K-s%T%(R=9=~>6<+5X_ z*+58Akux%YeQ~racto_Tj=Njkx|NmqmFsY6AcVc@iU>nfu4hy~J!-Ja&xKrQ!giih z0`!|*+L(Sp_4WPa?|IS0rLlEY_Ny>E&Xwjw<(ES`NI2vX1nZOGgfz7AC#naXOdDA2 z%zIi#C-7ccGkd#~aA$Q>oG20>n32YtU$$$-4St_K{I@G(F~KttaZfBS`VVyxv#bWW z)*l+J8i!lBn_u~K8~jQ2v&ddm@FSxNP56rVmhQ7RalZqQ;miF&vzyi`i~5Ns6?K^1 zCy{UF6@o9Mv(ou;wqm~br9I%T)=$ed7X9riiT6A@ECc)+f$K;XCM1r`NV3uyyO}N) zV8F_$k+5S_61xOq?#mG`e#6!)2)DDd0%jO@v0}fmBP%6M*bZgu zLY3G6LX_(A^f`|beA4%lIj^V-5B_U>AV?t?7OqrEB)Q!h9Yny4i-e5>=ry%tX`$Wz z88sk#%t*;8#=mJ@qOptP|8stbhf_=5cLiRR=z;xINsZVEjtI6ju$vlvlZij}1;_!| zun|xQ`R?NL&oxNDTf4`!ZAS7cEWWq=vM2v`0hv?KF;gULqyA2<-9Bd=UGbsT?$V&_ zpwC&DmKx>ux~MhihLkK|McBlf7r~D&ze~>^wSUu7swiMW@xXlle2VS4W4o% zOCi%BRF&ub5oYO$e=?REh_&;&b9AE%+Bq0wNHKse-d!Q{Ryq#J>5o15-q;HDx_DS;bB7;) z4Va?l+mUwDa*qAWW$H`)T=n3-ZXWQ+C;(4sw~&<@y)x@LgGG+4UUNQ)489?MAl}^! zMgMEJOWtYtsHKV3nf<_tPA$jBx;`)eKjTL8q}5xLv~LVUw#35;i2T@-xw0gcb?w8spLVIO*=`oBilqR$4I6s40Yfko5*Ax^t=v<2>i( z>aFrpHtbV^X7QsIH12`*Msi%pMVLg{l4}SK9|~6G3OyJ4A0@Ansgfu?+V)5O@Ct9m z8ar?O{>f;XGuDuRN^R-VU*BianJMm?IUd^f9$6UW{=6*^x{SJ+K5RwHv!aVw&9(DygDw(0%e+b!4!@-HAK22MgJ?X|<(nxUwzrWFs!1?jS>jfT9+)I0{;v_CgU?eggn7g*=&A2kki$_F) z3-_BV;k-&E4PNatqJ@MAOP?++RYM`r0OkEYj-5~0v=su^C`M(Qq=@R}tO za6MsenWUcoe4+zD9Xy9P!nzgHm(rEupy)==V1gEGm-Q;{Fmc#y!YO3NWj0z3HqLH4 z2t9*>?7XUfdpRl-E3{wi*LUyLAJ-e<({6q-YEUyE%QZH*R{T@(z^Dp_5+Yr<#6#Q` zg4t1e1S^=lrzh_xlKZpd?Kw!%!77Sdzo|?17j^D8KD{r{YpYhsJMSa!)}ANEL@Y+l4TyLyAAoU2y`GUn(V$m`K2nr_Oxu0O2*%Y!+2<1)`3$tgl?WF?9nS(jJFDK#5CW{hJ>5jdX)c z4c2~i!zEox$H%m-3+<}|&_ha(wA&pvp9I?LE@84HEANDLqR*CHnHAvP$5=YKtb;R+n{QXdn3NjSb$B&>d?gHPf*Oiw& z-zaH0M0(VwN|qA2n@?lzoPnYkNq7|^GPW@JXh<|;R(sy+o;GGS$Nb^u@&SleZ3kTH z_3_CGcfTNF6MUp~EOsJtN%e|PkNq?0=12T;oV`W}xAA|c{%-LEM76LiSIl%P0x9Q) z+MiaiWEcUdiydRB+&f{-rP~)&$(ra#Qs%3)opu>G+wf0jq8sBOO zZI2Zh$L?%+e)>IeSAru*1NquQ#o#>AXoRb8%te%J`xUp^GBux=i&3UIvxunt>66mz z))}B-(pqeWoBv&`3AKj;V@Xi?l~#A)-T?XpzFK~o(q*wO)`>$_$WugTz-5#lp%RUj z@ndLd&zHG(v5W*EW29kVDVp|XGV|klvb%Ez9^iJw4K0K$qG?-^<69cw6JoL9FYE8Q zD*I1hc&jbwWWtF2jqMP?{aoCNzdsa`I50{aeUDBq=9ZzQAr^@%!VG&X1vInad223C zC`%D3s4ne-uYZe{t^pV}cUkFJ36U`23()q+8g#PmbgfldVO$5KKDfpX`p}u3>wYET zOLsQQjo3X_n&?l03SQx6L{Wg;IacmjAfV8$J^HKn)F=E08Z`_ZyL2bUAdHyv+Y2F z@(KG<7ivjRZ6-TVL#b7U+{$WDTDoTsHP2d)mJA`^R+la#s5~T$8@npI2ock68{-y##S)-q5j~znhzTO4LFg}{)9^LhW%sLSHJbu?+GdAg7HA> z>j#fSFXKeQShOiu-(%P2ewB&lw{&eMK(%pf)8vwPF@U$a3b=TdFbTM0Q5-$J(^o3Y zct$k(SD$LR==qWO`<#kuTGP*si^SuJBb?Dw($~T~ORBrAyQ!e99UgHv;ZL8h4dr0s zVIKQk?wDB3TXgc?vH3nfosT@-`w0c{yV?pyv}LRF{D=e5wF$RuhGIu_S9Z(B^1ClK zb_p5pGXVmmG*pxw3XTCR*L8a^Fp~r&1#F9J0?SbA_S--EalE-wSvj$(J&)H!R{l^% zVdU{d(`eLgOq0BDcjUsUD;R#*sTA^enMwplS3)FmKPjC`U$NURdOEN0QZ)mej6p4c z-1*v>_pJHrLUnaB_i{1KuTVY}v--uQ_{bGID>;KUV?LYb3Kc zawq$!n8E#l1iv|X<9+4qBGGPls5y{>h66% z^lINBd-cwzR<3RnK=W&?CG8Ru%7+;D6=6y*)F(-K-1)l>DXBXyR#JQq zFcXeAz%j|&PJ#l~kc??ITC}6q(9p@1ZU-}|nC31t4Zj|ZXloh=+#C70*xlL@A>%gt z&CPx<-gHsr>Hmy03-~2p-dKBy+U^d0yX%As9(`ra8awr%6TYvfK$ADt8Icg_LVYsZ zI%Zy2dLX)eB-90eb+0yRmX`$GYq>3~J4lP`yJt@b%UeiZzoRA{IMbmrE_Pxr3?1bU z5gTeaOqaZ@BjEEr12V+RuKgtwDm{;g0{Bm~AkXEc_(?f+3IpTvuMLHbXO+p9yrg|ci=8#bMh%ipT& z=H|Za-4RYMOpsXmo2-#V$^ixM9X_cSaQM%0v6mz$c;Xm_<4Vd=TXmiV9QR?L&prDA zc;Az|{pZQcIr*#m7ho$B@Z`Qh(DrC5?4kNi-xhh}<1IpQnm#|inb`p>k00?1?FEyK z1X3{1v~gKXqWid5bOwH>;tOH@ z0(a7{J|U`^8~L%nDu|Rb2ArZ@L_fjqmDkLz?JtWu*CxVL=7CJGA+6C8C&Hux{_`B6 z3w;IfK;3BCI#3*UHEEMK2GGK9p(PBD=B&D%q#Odhvy52)pnj7$<&p;--=gh|Aj9_OY>a(lulv>{M?|xy92bCs+LgE z2*1F;aU#WiheX7Gend%zq@l0W^tgYL8GV-91@HP$_bzR$5@j?F1m^UmQFy_grD$~h zhC@S8SWF3~+39|LoJh3W-mgk3P?>nB^ULG^02QHhzf>`9kM9fFhg=ceLPv#x_jQ-4 zH7-_@MS>>$NC|VX14W0ch>eBm2mu}g$M_{yj3zQHu;I%IIY$@&3(qkvbjK@A83U>0 zO;g&&vu@&%ah*W>Up4jDNjb=`LBOl?Nb~MqFMa{r^V1tQZJgvGf8HH=iB5)H82|z~ ze$?4%K$peeh!w4s15Vj;4ol9S!Jn&7e8Dycse znnI>t>kAvh!zdOm$U@xfvnjS;gsfUQ!O%Q*ZC^v%-kW zaeGrO)=8V5Rq~?I?b$rW`Squ7OCr>ypZT)860iE4^O@iQPrP<6sezSR{L_$YvUZXOgF{9YdVLjFL% zzG@4|C~jTn?oU$AeiGH$TGmxECf2lCOUeNlMvrs~ecTf(5da{N{YThhHctL9Ok$5U z5Xyi_v$as`S_6RnES*pe?@OHjQhx+MSJo0DS+fv|X|@iE-i3FK`?{Ywj+-7EULP1T zX;?(Tf8s5)QO);eHoeKt%(v{Z!Z+(P-~)N5r1u4i&4Z(t^g&S9tS2&2<2{ z@mCaUD$6G-PG~ol5+1UqvzdzDIB+$^u>}vm;XiP;iab){R7s6DM*}YizJ#u_LcTVNo|4f4qBSNZuGJIXCvSiz*!I*#N-m9xZc%nqqG* zZ=*as6^K`(yPkUCJ^gwYP}mcva6=cJfqQ*XmT4+YNCdoPH;eoc=oy1#!+`Vnw8L1j z4uAFc@W)}F1!)v+l6$}OUW-wDW!b88)%fb(>R8(F$?^Rpt9ySud(>_RH=_F=yz}#w zsOo936*7L@^SVkD%*QWy9EhGJld(YJ5Zz7`>C%n#l*Tn$?qI0Fd8EKcV z14NMrA--l+m!aWahBfu`=quqssIto90{`7o3W70bzw22cG548Gz>1B%1Y)nsTTHWO zdf$)@Vc9N&Dp|)8c_JFkbEh5>VRm+YvBJsU1G4S$Y7vX6@_ZFyQ!|)cdsy2w00|f+ zk=vP`pdSPf2HPBJa7XP7&TS{5rhfW71+Qta>XP5H03y zd_hXajeC-ywQC{Y9PG1Mtb$CP5z+3A_5Jaf&SOWj4dfMkNlR_rZNL`@glx)O4NL%H z!UpgJ>!|43@_g#RSU`PBdS+f|J9zxOpN4>eurb#a`0l3F3($x7E{hd-zH>*S;O0$G z^yBnFRi!nBLfA9g-EUX`p`jWMhTrq7RB> zxfKEB)9o63?P?zS3KE)kXZo+{yTLgjBq#vq&&2}6;Q>HhZnc{I-nMQ5xMl!0+JqQ$ zmy7o#l;X35jMv4tj^N_%gDDY1apMzT-PdP(JS?DTh)JoUwh1Jm3KJuwS~}y(qtg2T&pprzi##{IZUU zb-)MK6@609clETRE(7+K+_g4#O$J)5yxezF=Wo#~Q!-s9y&UpJ0{ud8s-x<1O7d8V+;RzWhqyrApnbV#0K&`KK{IY6b7IsXOQM5F6C15Y8hm^Cc z@>bvv{k4x-y`@|=rxfOE;GZZ#Cv)NTDcH^A8`g>EPX&Aja)+Y;bS>i&NzjZPMooUe zPp|s#zGGtB#gLt1i+v978ct$mLU<04WYU~Ei7%C8;8_#mA}<`cGo!l@V>Tn_4nL=M z@WB4#PT!f~5gPXPZhFR9CH{A)KrTnh`SPhnC+vS_|G6Yev~&5O2=_jz%Ta==<7a=R z@SDNDOdNtJI7rt@#{_-Tb1}4AE{!F zs_h4`h6sOu)vbI_%z(NN?#nh+aPRr+sJ->6bS-Hhx6SCyE;FJQOy;k$+~vn~@BBwC-CMA22xo)-)r*R?V2%5?B-q zRc?rZ^t12jWrFUH7`n=Cama-V>LdHVRLZrGw_R?3lHx?6F1y7}BLO$|% zA%I$ca%v-wui%$a!y$(I9)2IiyX>QQRQYE9;(sXqji~y;l}&VVY_WhBsjvJ;wEKZ* z?=-Hqqx|W)FqQVLDzLc76L+Dol-z6CcO*ON4zo+r>%0d!RX|u^*V;i(eK9w*g~@jz zxN*%utgn5Jz9Ro-`xU@?S}r6DALMhZ6H3I(?cS9P*_>{WtdpCUzOZ>TQ-vgC!}uC$pShbLYNClOR(bVjOfN%o1 zS;dI;*SgW(-oE76jO?A_kZzO!$^Zj|?eE*nC1TyX8&Hq>!zZP+_ttO!R2gQkde*Tz zKV%yKcjwbXAhP=WhErYZ+=uLrLZ<@o4}U7F=_iVdxE3uD#i)M$K?=W#yXO@@O z+9N)B4rgTLUc%zyX4BmzMK0>v{bW%JhI!hVAR-5-hH&8>@th=RBxXl(+q250z``fX zInVEBC?INj8khiyCGPaCkMGTZ*e+(C{96@^0LWZx6z(+Y4P$pz05J$3G`TMpcyxFB zDhg=|8S@VBT&_Uy~X!Od@v|;+#|1Q9FiJNanK9O>ck~JFN z{tzli5Fe;KC(Zt^`Dgmg1Z-4Rn|DXhgS6Y5ULR=p87M^ceb+cdIcN{9c%G7vag~_r zhXA!1Z~XT?v43a3p*9irO9%25aX|hTS~lr>rx8em(fM`lKLjC}Zn=?^R}K61)ozh! zR;m4m&1a{*noppjY@u)Wy~KAEb;p#()|hkgfl4ZW z!juFhPuBpS_nwy!k;Aw_=Or4}B;fza43yk+n7}Vora8!QF`enQT)@(A|0}`&C#11E z~*{^c2YNfIqC0FpV@T(`G8D1Cm1`?`b4sBPckrENtqcZ=&Fh65ipHPzSzNxFv zS^8LNJR|VffKf$FB5*~|Ifu93_N{`g{#ZRW*nf#oR)cwKRHB&K2_$s@xk_Jjr>x*Q zs^1MNwmL-7H^(rW{0T^4{a~(`9NcrX58KT$y+Sy;ig$khaW|smA7(p{+&woE zB>YXvap|Z$C?eMou3|oTNW`hyf2Mb4G{5_7)Hq#Dnyz6YPXsF8qp{-v07TRFA=>9j zU*UdEKe708C6g6VKNnG$ke&pnq7^+!!g0-jZuflf<%sOQbVu}7E2UMt72${$m>z z6#H3Sb3NtJFgG_ZG(5UzmYhHu=XH(Oo&*?>%fD*RJkGDBTgLTuy#L_6P*qgA_XbM5 zFN>-w#LX5kGeZ|hcKL{hM25P=T=KQZGPgZ-u;LukT$S6s zb4kOFbLsmMQx$7~n!r8P8X2r}MW$e!A0%Nbp+h1wBI*s$-0y#05=%KV_$G_WYPDEj z_^;<3-jt!|wav}rJsJqxj0=-e5911D0giP2Y@q}Vp_T%KSWR^SQgfu#&7 zRRaHnQY!qRE%9`21}5j_xHI!#TlK97rQiOHWgWpm!#+Q1c)s(!a^VKC_aso7R@{1m zJpVlrwNr}vg77<;w0AyKI_R|waeD^~-ICzFVV-Lk88BE%PhyGV z1nd5zA^pbh07MO5wGb21mFCy5vHPOR;S{4^OO+9Fn6ZZri%+E(ee#3R>-%gswVZfB zh3Fvd=h#A+jg>vhUOE`n2evLPLTohI5PS7noo$i=5tIC$2eNyjDFaW7w;vrv&^8V( zTc$7EXds+hm)3u>PFLs#hGF^^DBvlrjiQeTy^ZOmzL)3+2e|Q3E@(Q@>Q-I8a2n0nA-nvqz<;QodjPGpzj#q|hYHY{2iJ z$g}h@8-lB#ooZEK;g5}HvPRs{>o@cb2G1%@s;S^+3J0TV8@t|@cogEydjfInBs zIEoF7x~4P)3~qANBnH9)Gh;4M&pWf)1!$NGkJA=OF648XN0K;?(nOH zK!fNlj81Ia#fr;CE}2V|{74_o@RHG1AF}!_T+olz=Rsh7GuR%LynXF}oWhc4-~0Sw()_sf%5 z9dYmEVh1zcQ!t-1gDoU^NqqUQ*r8gi`=R#yEoN#rrS=*?_JSD1G#JNuLwD#Qg^^9I zs#UOC{IEJ*5JK>aRG@2tT8DkBHyVYr8N5{{=&RMFO4=1Y7~DVJe)tmwr06QeWvB)@ z83oNTC&7C}2~BKV9M&ht*Z&$;>0!EdtzGN^WclJ%#@#wjXNJN3fS+YGq2j2-TT$Hvhl*7Woc+T~tbf|zLECls`jn+j&(-%j>-KrzWvEHrgTrwqQaw*?4PTWL}Us>;mD<<4Qmt0vR2D^ndG*$Ea#m9kuwzKXamz;lr0^l$E7>>wB-8lMYh?pD*>WooYU+* zKx!)z0ee&AKUbR7^D}t%9!c&i6nS?YoHcf`m5SeL^c~ZZ&3PaNEIej)^@vckikRn$ zUXFV&4T}*ywkX#F&d}O??y@W*C-+sCpAvsUSb=YCa_(by$AF2Wa}^U9sa?}qx&^2r zKVsc=JL`JvBeSFI@+Z^_jOnq=o-Iu*k{kGY?NEY(i#eFvO~TIzI8CP_eGf&feFdfG z=-@;9h(D6tmS@8wb0S|7r$DmHycGUKNm9fmAJ^L7^?uho8{0&wU!y%w9_wYt=B|d$ z$HMFP2Z~qX5s2H5jp6vRUfpfr(yl#8TJo6-AF|$QN-cQ&alV@%Z?)AeLB4WnC~41RCaD!7XhL`Z*{xxE$Rww&!-UUZJb z1>2Fl5U=x`gJkcICY{rZ(5uEiwk?~yV39?CWIbRb72ZMi&#^$_ylZTw8w0T4(hABQ z*bt5LZ8zoTr&r{|BTA~Tll#UWcMWydX4mxw>6%~%(o*M!2gU1|PqE=QTWUa9!iyv? zuRAcufWyZ-UcXSJ3zwz#-(Y1npQ(CRe>U&l9}(9Jo^=^BfPTJNws4_J{Z+8gD^DL` z7@_9{d*+Fi^YoiVKNz(%(;dvNLG?7`s*xkx2Pf^T^-V52hYmhaFPyY6_BTwQdmao% z8Rlek4e%?sJxGPQPw=CaDJI!53Jh7o#?}w1y^EzL%S-nQ@dl~bY_GYztT=dT+)r=! zU}J#d@(p^-GAs9NQpaR09JkNl@nOIBFgoO)F_QEdEn^%*6bqOr`hNewY{FCHQ4v9R zP3Vu1DE-4VQmcrRzk--fn46>ClU^kUD|zfE2Iw#s-=-U~lI))OSZC*rv<_S1j|ZS< z7zB4v*lEV88Dlz^nhtT|Ds~8Dl{Cn!%oNTTuKk1aELrwi(S2_{ZQ*<61%S-5+|349 zu)=j#TJ#6h0?FfjeA1%tpLg3nTu-~d!btLM`=&pO*!7LpSW)Njn5DY*hzGuctY4?!H^Omd~HcFme)JPF?BNSX26?am%N5@K^ESuOTJrKLmUG zxX=DZ=43qh2z{jsop-lsG!=8`Npd1R5Urs<1=AkMZY!o5+3N!}jyFoguemiF7MrHT zF0f?S;Je@_Ne3cs0JlWZb?$-7$)ft1m)MkQrqo`jE5wr(InuVQn@lJ9J^jQh%st{8 zI1gTHNokO1{WU^|ZIcAl9Zpf5xpp-RB_emX)7>p>PTpl%J8Li8*XTjRUum1e67FriDXFlLIC>) z$mc6WzE?*e!8Op$B5+MPM0&4qI-}4>J3JhMT7H;bVFD~gYt!E?zRj#tSQB!c?3MX3 zRya9}@)jQm^7(!F(rQ^iSjy`5%gjJ!h@s$g8lEMcSj^45Q%m%)%ma?ly_bgWfLTV zQ;;Nadog4*Mh&|oW6#Q)zvKl$I0@Ix#<7bMa>e0a-eTZ!)o4RGGw-OrF2_cAE=dQi zLU76@?|I1IN!2ykTPWJS8`hVJWu-*_QHng?pFRa@7Zr(~C@|4um?Z_0V34^l!WQiF=6zOCC`<%cbsn$QU;VG33i19{Gf&1x{;GRHhSwm4Bw=Aj7{mR zX%s%X^7muUE;&Z%&mW-_!jgyL)Ti+E#OCLAeuD_jWAucRTX8OyzA3S}D%f50n>p}Zr)I!MH z#JwLcG&@qhoU78Jp6A1m+;(xWr0b%;9#rlP6seWk(3(;StT27~uPx*2Q*E{4b@Wg3 z3_VK$)l)Hnx2^Yx!zTs5)qW6B!1@Q)xY>?QGcjqz4Xl9^r!Jq_GQ`qy;;Pnf2k8b|~-5B<>?f~s})gsXg{yFK6 ztbFyglt03Cr-`}ew3+TQ@phP_2L2o4 zJme@5Z>Mj+@WZ43>c?mWtUym_r?^PUpi)4zk7*c;lWwYxSG3Gng=6nkA!bXD~Dp*fS6>jkxP z)_(eKHzpRpE0~VD!4t#MM`?6tg4)uaU=<3`Fk?@}7HyB$6Rv8tsd6d>KT z`a-8J5i+Xq1;xM~psiW-g@P6zB$dcQ7P$=tBbUjPAMzQ*_uV7^yJeVXX9U zCcnhqfWyi}9q+_-*^tgp%MygT7jkn)d-_ABYz%vCs`1kllP{I(z=Tod%JwK$b6P8s zl0o%=e0AC^<+>~M1-Du(mu+Q45FuWw^5jpBOe{64eYkACcn|8H3wp6Kx z`?cO@bK0S7Dn5xN#iiTY+JWp87QAd{HrmcZN^;gcqQ;KXnuIN@Cu@KmVpcnipC8W2 zAO7b4#p6dk_kzLY9-3@ah1Njm+SgehvS_r7h9{!mSQslnHJ;svyz)`m2XLiXm|(G6 zRahEzL$KcFMc@#E+!(JwNh(CPnSBR^E`Zi3|Hd*ea61m7@q z{;KZd&hv-3jRcZ!%McRlJm{E|O*Uvo3aLyUk6vKP$DNB(m9rmjockgrcxc(}kj&b- z?CY|`;Px%rUs`s*AegNuU7|jh*HebB4Ut;ktR9cNQon=Z^ilH@Wa*>e%qaE23`>t7 z;ycJO@~D{?m1E^Zd%@)h>d3rV-7Tq(>K=R$*%j7$I~f17A8oW#Qm%qcC@j14Pub2Z zFwp~OGXgRPQ*ajN_U=U#@=oDds`#x?mFr5*foAeXK?;F?nD8hoeyi&9Z$?FcS?Ml` zKph<&pu-kb5>T7BemN=^^Y81@A8fOedW>P^zDpIt#n=I zr>o5nWU-=MLEYxe&V*D$BPPmu$J4BSi1U1GP(%JkVclySEE{&O@$n=VJAfzA7`(gyGhtmkSVX_k zc6L$E-JRPb28oP27dS($xMCZ&Omf$Ls*>GNB5|CVYP%PuGXA%b8j#rc&E+jTVcbOb zoeeVpKkETO&{XeNhd%c0GrU<1^xPj-hG<-IE_-j-cV1~^Uh_f)uo)KeVjuB3{k)Y? zl~jh7dG@G1;S*`_!dcwZ%QuI9bvWt%`T!m%msi%a^0Rt2Pa(@V%M|f^^C4=ZxpQyF zMdBg)j-BL*p(nf!Ri&(_VC(RnE_V(B%$!z7=+ z(0a9c+vEM*L&%V?I>l7eht_nB5Y%Id+z@;T<)#CY1|3i3keQDlpX^|R7H0wy4n$@a z;odZxXd&hT{U<(*g$Wqxm{@!%P9WSmyl5kIRJ~jVx#s20kaPovR0@aBARf#kjTmjcLbzq|s*SKMHtq7gF=Vy-#2peV7>dxVyv&K3#m(p?iS zWE`ZnmPrcYk_UMaS_k|e)`>XOaoev0#xh@XWqKja?Dxh|JP|(Qnj!c%xu36A) zw@kzT*|2#br1O5{ zk%dDfzSSbF$jqN@BQ2e}NLJTDB8FamV;*unr16={NK z)Oufj>t4zvjUIS^D_K&S1m(`UhBlrzG%rV?Evf|$HI(%z|H+URdGE9c@nar6)I`mf zGTOKon6Z@=Go-J`1?{{x(VfoA(I3-k5$2RVaq;h~6Sjjha)TN!XBZbUI>G1BWA&`{85Ex$5*ri$yia29C+rARGyEph{wO}}0h9w`pHEBv z9h&=BTqRoM$gyLu4<0*v>v)TID)F)YiGSaU9W$4DXmDBT^=$#+C9&U8w>(qJ7wu2| zL;XOF9G}y|W*Y{O11=31k>4Zv%PW|b5x&u!m<VaTHYw!u zB{%|h4L0Qy+GaRb9Z|~f?*wYL)-G$3j-EAw1`}D3nU>*o%Sr$9yo-t*8O z5kqN8w~=&QP8Oq2)9kU+tnK32bQ5+0w|UC9AX6FF7cfq}x<-9j&a?L-t-t(0Qa)g+#NHG8vWQ!R z!No4@P+sK2nsp!7d+U1oOD{J}-4JJrtW#&euB;waTjz7k^6aZ=4P0?>XjCEPjL~9F zeT=MKv_Crnxl?R)+&cVJr>5&to(bYx$8_m4{W;Lk(!Y>w7Z}#y#o)h%n-{Q*pOtIQwqGzfEAGmvX7gE3|m$#%r9@p#JqMCWZPP;1xB z`qWRVP{%qiqmlR=b@TDimL!F;o`;oGKey)y*zOPg%sY5?WBC+m`Xa6Ts*RZud{Gb( z@i}#frg|+!`OjYxYaLpHUsK#~dtCL*O?0-C36!B`-ej7BFje+BDs^iov6(BX2((n4 zMX8}8y%`W1TuK1HTq^Y57PgXzRt*k?zTl)#AX92!Vql|?(09>K+Q`rwzA8=myx|if zMcx>tQCd?m^oli+y~gZDW%p^k;CzeGWP&kDyFy5z=d}~oVqjcopfDh6;w~}5Dg{6o zo07pRqRWAK?QJl=M*Wv6a|~}{O`f-47FID0!^*SsUp0f|#R4a%g&Q8+-c2VuH^L&z zK;bhmDw~2?`_-WXx+HayZ72VVXNC#C)R*oHl{cF1RNd?nc5r1(zi{L!62zqL4OART$n^>)2m zhEgNUxZIk z2^9uaLC_w(WGqd1TY%kfRa+(=ml16thir{oH73Mi(&~Q-F3`!{3>cpT&QxMgU4$?9 z{K_LPF7|r{uKiNA0K}qIK0!DK zv0N9Cotm*EE&6%FbufJc?Y~@d_D+h6gDcy)t7fN z3h+6OJ3=0LeHrQq(#;w)Y!?d3lJ?!6JmTXz9IEWd6KgsWtJ z!JG$R@WfXz=hY<0SRcWeJk@4)yuL0tR=5x6IZ0S8MIUYH2 z_GF|33R+Zs3=%pRn^u3jMmFu$7jTJ!RHg5gMBDJDW{a1*e^pG1|7$xnW#;ep@okJ> zBmy-h3Ex3XQ;4^`l1fTlH0g#Mw3#M~Riqtpyn(H|-S`UhoK<2*&|}-AbBdGT+|)zM zug{Aqu*=U79;hT67v3cJw?~25XQ~9o*C=sdS)(WzHhbHH7yJj8p(4@$<^2l>5;kNKID?8zl{%4VGpzJ*se6QB) z%+7h?-a4y-xg+?mupyWFS6DYY)!M+J;WeGoIoQwvgM> zN|_6ya34zrR29?A1a}r0m{`A=Y>7BM++kASn>xPiyAz(ZVVS)tUbJ}tYfzspsMMq^ z?Q=GpyX{|_B08|XRKz7G4t-#8tRjs{K?Ln35nhya#y1u09GFFa)m$JAnL%fO`iQ-O zCSY2tyKCmUaOARpTKxm>f=c&0X?k@Fh2_T$7b5aOhkhPdSN*JdAODneX|&2|<@Vn7I2(#DnqCR5_g81pR* zTRDT0o|_7}xhN08C*zESY*f$p2NoQcH%SPcDKn)p%HM8(wSmSL{<2RlG@4MJcy$Oe zqt#yEAV~c4o>7d;@0~Vj#1dKJcCWB+Z~?Bi*J8Ui`7viel|DWeouRN>poOLe2bMao z*|Z`n8n-Oxc-XPqf!*M96sYaa;Q?golj}yauJyTJRyk>={sy8H z3J9knO^U{7i>TYv;K+92(#XkpGV240-2#)(uf>}kcp-=f2?`|LrfOvoB6yJw>_c(O zoKg$t`qK?e{3eVuD2ZEm=2-Jh0?Xsxc-%@N`7@RzP=xuXDLx(TS7Ln$DyIfn{Y5vk z{|swAv)fUAR*!|I(q-w4hTF9dZcX8s6>OKaGuvvi&da#%3=Q4|sy<;-1>^9wz#t}x zSf8aAz`H~|>lg**bxd7?vwo!^7_+27=NXIUBj_?_=kBAv0Bzn`ZmuZX!b~qv11ArU zW*UP98~?C4w076Aoty&E_q$JNE=43KmO47`l4K!z*{MOFZNGdvgjAfL9^`=7kT3yB zRPjaR{9i2p;I~v>8hHLJllcIa4>o#l%LueYc`iT9&Mvi3*C1ACg?H$h$tmw1c{LU{i37+!)NDP!S1{qj=eSr#XSGBFT2?!;ArEkbbqS%;V53m zvxwMI$;pSt2pY|nu<=|erR~H}^b7Y8NEQ42tw}OSjf(%UeH5L$ivAgE8NWdpgOjC`(5|5PM9sa;A4(sU26)l z=2SrOBi-z^)F*1KAL0#WxSG3p%(ycLv?M`3JS0K(dW_v@i>0gI z55T{X-GyeP`~e>u)LEzXuK?SG*^CE;QAf@D$XVHwKZ{<<{=if;ec0jMcjb!0jB=oi{zJ<8RmIb0#^97RB@{d2SQ|||NL9~ z(f3Qn&b1RQ$L(|R7fc8#Q!k)vvRCo-27FrN~_a75DzW1V$g@Zs&0QB|a zahe-QAKK8U)?VO+WY`h>zeQPxHY(#5Fh_UjeYWagO^7*GG6w_Ut^JW?o#W4?U$z|& z)Vwc&QF1;S-COsluPJ=!y`$dmykVqv{GJEz#17c2-vz4aD>GpBT-2Rm({z zICknxS~}_*ey;1HUaKHdJj7@T*?v+&(`iZ>(k{$JMfN239LUoJk8joULlab;*1jJI z)M~fQ2DDz(i01O}wZ(~Y$-g%&l^zC@4aVIork{)kCi^z0S>1M}+tzPU-dS?BGSikK zO~wxSF$Fkhgjwu1qrJ%8XW*pzd00LBo6UhDgJ(AqR~2Mu{s7}VH&Bs^NlO;C<6^>i z74Yg3D>K^$K0}W)>|7HBltqta1xqwAYr|ikQD9AcPpC$!p0aJd@ej)w^nPy;wPvkk z5S}ACFT(XGxApIZC>b(M3JxjlMRT4A_U5uU@jW--*)!!ms%FoFVj;B)B=zv*ar{$! zSX81AI=&$EFaMc!iJ|##{a*Oj53tDvnRr1-q?FRHw~rOJZPuG$4Lm}#-RtFu0oN^WaxzQv(?GjG=p^|&tG9UD z7CF^1nwhqNTcA2g#2T+)VHDG&Uh&EgYimGLFF!V_?^){p9-;^^( zd@!W_1NK$hhfN?6ks6+u2EmbBQ$l$Ax`MO81Dl=X#QNvB1bD~y^`XlK-@uxR>qVP3 zS*L6u9f;hEx~@Mrdx88CcB&KXc)+YN#X8C{lrA`(z^cyvYHFpoYd+_rv0%K5>ixZvKf*!1t5*Ww8G@i$h!Y`=*PDyl=E z=5{C#p48B?E+A{QgPv9=FhC&-HW?)0-qOG@O(9N4i;_|w)h|`BB-INSl}%SmhlFb8 zc=E1D4TL5Xontq>iaH93(#>GB{d9iTLwE`!4jE%)U$J^YMV!|k>U+;ew#);5G5Ad9 zI2RTk+Hssr>no0|zy}?C_6nYsF3Bja{09!tqKQF=OTh5SYXg1fu?D9z!lz>nBn>%) zUlg9JO_p*n;L<0v#-`ZOaHki6+f9OuKeDA0jx}PWUM&3O9IPrs3@wjXwtTUTE@(Kt zdhzL|QF(K#ryfNHt3gv%9K3)c?Xn!k)p83q)ul>a5l(-?|HL6J#=RR=8rpEJp;o_o z&x}u5@}}2&gdwX+dd?z|wF9)j8w}Y|q%iA;s^=vz@rPw%N~&|TjoV{jIk*$^gZDjH zp09yDSNu1D$dc77J)KZ(&&lyAaiV96vbm;X1^1Dx>oDbWVDKv+03A6Dw&`$K&B`_c zeP%9`YH4swLg?vA0nkxt2q&sJjz7@McM+6lsZ@*Bu3g6pA#ET4mgUi_!^J?D42gz2 zRt4|CO89h1`dZ}`!*_}k!tG5C?eLBX@oaAKgN_qJc)D(t4|F~X!Y@_Zm1h}RzQ)L& zTl)v>V0g;5JJy@b5y|;~WSx6F)BPX!9b%Otxw6V(I#Cz4M2Im`sl+N*QasPGy?eXxB`Rwy~z2C3rQ?gfN z6@ZNe2O@4TNrcynA}(4kg0jSD@s$(t?j?y)bH^qb&TQ6?$+4y4!EB&y(H`yj7-mz$ zIKY&`ZPsr*x2f(k$6n|)k*|eez3Bf?2fsjv>ENk*xcK)UDFw8BVP^Ds8~lp8OcMBR zRDroY$17~J5ZHd2)|Ie6j-FJ^-E7U_nG^~UhtFYM`e*(aryfMeAeR^=rUTIKc%$dU z^B&hgOmqH;;vm4f=M0ymiV$L0jiA+x_**Q$Jrvu}gT_PyPv==dolARLjMY&cQ2eB1 zTI!K|q0`G>ab=PfwEZ~2<60ackBx-a4hm@=LU3LqJ6KWXKa^bjkvMu|`q4OO1icPc zgFawyRXJ4`wQwtduNk;<+P3#t+I$c8i(^n`W^P)?R7#CmaB%B?qLwk@>1z7QX<#i( zL%aBb6B!3*9vmyahmygpr|CFk2K3_2``;LJueX%f=Sc02%~uz%uw?A~!ZUB}UOpuO zxj-SH=(N7fvRZxOhXAH&xO>2h9y5bTtrWAFT1xpjHcK+?YBVvd5be(gWTGT@b+h6# z6MwGJ5~{Xx%ZlwK8clAY0)ih&RMyxv#r7HP=Pb83xxaiJ%I-y8dbw`NL;551j*hfx zL1kcWgkT%w+&A|uh^#l3lF#2$V!(OIY!$_{NYRcYyN9P>6~-ppz_l#zAj@|i)3le_rH~Lq-5zj`xEFoD z<@-4=c%orhz}*p~){KAzKSHaSuwWGQ8$uMI%}MaSOZZG#c1de=4!Y0;HJV_|?tKfh zh?9&PXzkQev_ifeYxf!Msu{7*cyh^62*-Tt^iuG>kTu*e;3idSVjy@!FJS86WD9bR zeUmIu=%-CVsX(#@Su$fof-Q+<`qW5Q8(_kEp#F|oTpK4Q#Oa(^p*DQ8%>J1PF=)>~ z>`W^%ibl^dSWE2_)5H1gXq^Alvfk&>?;VtLDu^dw%i%=ZdPt^4_-t6%q=Txa-rV_$ z0#ki~u3X6MuO0HgeX&r^Q(I=Ma4#;0&wl^fg{SdZqs5HuH~O4~RvH$<5%(~MOvJ0^ zh2cuZ2S5jpF`lJ}v+4fpYzH64DcKSi`eVIltzo~U)D@#+wZc0f{n~dm`7V#DB7`?F zIZOXx*)62wFJSUc&X!ygw^IWLgml@Dr;&1uXf*M8^mDuA_U2OW8Cqj`<(;lV#y^q6 zi@%Kv3%Vbp+jvjYHJ^jzS{oaDb*Sa0?Ya`_N{~>dOr)C)tJW}*y=TfVHO_to zT`>1{szJZ()AaJlpFg^xZ=<9;j&@1Ic>n(eOHo29xsI}DDzIxO{M)X?!em3b=jVL~ zM(HUo*(uje%QO#&@A5>!q>lPx|@jC{mG&nsC zBTU!&HqA2aJm$#gvZK<6Uz6?9#FF!;=2%(@TOc&+^x&0Osj|@`Vsd2W`Y#iO&|4Je zLpo*Mb_y^^Zn&jHAa$pWe{Y~5toPJshU#<+cSn<} z#~Pv0b$Ey8<8-?4@Lt|xkaH^VP9}QZvDhh!1$tQrwRV3R{@UFeVY8hHB(?0$c=!y4 z8ouQY8~&l0<;ga>zw@N5mG|1BMv-(?g~+=mO2N-fKpGZ7PJ$)NZR5U`Pcky&qPXeC zJFu!=n-Ap4hEtZ?^ya!I)1X$^p+mc=jcw6#@*FC9GeMcIcZsra?4Vu?L#c}A+8`K( z5{iEgq9>$@r?##u4Rh^06~=c~x5dt2T-@RPYR9RoKpl3NBcm;l@gwd8K&e$!~GROXFL_t>aX>g~bk5lo9`2eNK6k6X~^c0`WQA1jKz2OW>Q_ zOglw5;4HA~VPMZ;#bKimtyeQ|3AoUDj1X)VFqSo0I>F(YSMSw?%!@6yXph0u^7Ty&|uXQ^|-{hUDHm}cl4%PpC8+TbK0X7?P%euHOzX}5xmW)UQ{0$ z16F3hcRtEvB9}Y#XL>TJrxXf#Z@pi~ol6__t92MqhC2%(5(&KDb&|ax=vn&%UkXxN z`{iNF{9EH6El0klDMgLq)R%7m()<=WA~U~L8??70;H@}Qsn8>6I@@z2?|=vXE1rfe zg9^kZvVOo^CZyJA!IDDpnJU4#VjOM?_H_uYo~p#mnyT-c+qgu{CW=RWWKXNsUJQ6K z^3-^qwbbHv0Z`Fyiw$7@Wfx<67>tt1A{~=p|sgY!%W}=NXPsN9{Bd zb8O=aRrd}YTrReMg3l7GWG{r~n|Fx#C4e9WKRu`4q`~q3(C18;e@;L=IlOJs?#Smp zGgc&Wy98np`i4i+6X`)FQtWw4V|#)RaGn4bvAQ zdi{B;vqTbUAkVq9+=X-zVX_Jjh4TJE+|9klcXCxJyT}6451$ zTowE45Fxg6TJjESO3RTDq>gu0YGX=Sx%5TJFGLKe?;cGh`XQ`CB?8 zwV}*Z%{C+igZly*4O+_2h5RSMlKdXGoLns)Vg@4SlHO{~Xr$7=adRX-?CUL+@@P~~ zFE0uDW*77vu_HlPR()!2%dx6>D@V-)QUpD(>b+b{VMZoCa6Vl6uxgTuqCUXQo~zs* zozo{sS4v+OT@vLfK2MeznyD-H4iI!&=lv~qxP=eYA{J=-Of90!M0=?HSr#bfyoXPq zz(YyT2K31!2o$lmmnpX3a=}AzEv)ghr{Lq0CHEDoo@Kopx*VYrr7~#0hAi3g1X-O< zzP&IY6t03*e8g-yOsAUQPp<=u=45ML;+gbTQL$`*o=&b>C2rNMSwC$OBe`q0>-(QY zV5P%>{)J3I@LyiF-xU)JjDwGdG?5N;?RuwU>~NOXp*wJ4XQ!XaSm|G(3~=brVKIAV zw8+^?)>YUM@u^PJbZ##c0M>+X#Ag3zJ9 z)sb)T%{rsZ821$#AlL)mnC6}f*AN=R;UX0!K~a$)>y>c%Hd_>rlD0#6tVEv?cCOEe zFJOH}ptxrs-G-IKE0zIo2WOWAB`~!`=KKSG^`!XMUSUJefy>PrOGHL3MY@P7^1cZj z_1|!Iq-j)RKUl9-0M{n%s()E5YwFS=g~Iet+~WI{|Doq);T5&&&;7%mO2B!7a*Vf1 zU0RDUd{ZHy#vs|Hpi^A@KiDhDbBzS-N}To^$X`m|{I?Um*vWg8>id4DH4R5LA;u83 z#~n8J=|y`$Cs<#!^0~R4EpswEqw4Qtw^?<pt8Qg41B!!-ae)*Q)CEF#l?0pCYAo?b1~0xh zR_QOx{}+HkJQGqR2bBRZQoCivOT;Sds)-eE}d*vZ8(ED*U*e{yWphJ08(3mKeAq1honFY>v>SHUnZi8Pj7)x~&L#!nY8O za(7H@P+RG(evFDY#MZBN@U z1Q{SOY$cmC_2&1@v5rlT!#t})PMtIWlf3BtbAOkqRJP$V=6}R++-|F3ecE4~3IUcRa(!IF{Bj z@0!R#Yk#TXgSHQ#mlGks7Y%jKzfPX}-EX>cVRy=u=u;B*5$7zAOjXO~rdGK0%Ux=M zg^XboA^NDrc-h-kwUKtriS6-Fd!qUvHtX$6y=;fsT zysDQ0q-hpSjd8q_m(sGQAXD? z!D-R8m8W}~>&d?XCi7O{(&f6@ufnx-)3b?4^1Or~tNvs1g1b-A+2XHy6w_64xXL^C z7b@_Sus2AAU_Lx(e>hI6TKI()iPJe)^A}AVZRgYT{*Y<`yZ7@mcr>|qyrMI7x|r2W z{ycEGJG{$&r{6wbq|i_7ablH`X|!$B2Z`XJhIjDI-c!j%w0m(B)i@7DY;-n2Mns^P zv(Gi?{*3)?>*a}jeU{_1^0WhE0kQnP zK0}`mv-Gbcag6a|-8dvt2Xji?bi@B0iju8zjNusVbK*zXoGul(l8^q-EcW=?@LoTj zz~{VCsbmsFHr(vDhx=Xh=pO*{i`Q5d8*$p?bIrf6PMb)P9NZ7kZnu7%-#j6S?$ zKq`K3x;9OlLo!s>;SwUKt;)fC@4ge-DYL-F;Bi9hQmr1}?;~yoO+f2^ua2!W+6z9a zc@1b2Z>Q0wjr_kuv=3nDk&x=yJpsqfBQVYc9JyZ*J9Es4C75DTr`RD|SMJn5D_s{3 zSuli!<0`+xyf>BIpzObN(V6zdv1+fKjV+=E>e0x5XZRRwm&H#;J7(d0gvan1c`wS| zmO&yjS~LIF0n6>_D3?DqJQsN4JzauycM_~KjdHW#!U-<(x55NzcP9s-cN)1ZooH+v zbVDYvJ#M_NhX9*dtL*e2O10?~8>u!Wuc@Nq~Vd&1{8dvoAjzHWz z<8tB?%qo$GN$MI%*)b!@Bd^*4XInP$0*!cBq;#$V0&OJ=RULCXi8ZHDyMn5Ys@ueB4G+XpZ&@nZdM z{=b`sORAxtV(fVfUcT}zbvebtHbr|Jzxcr!!i!hsk53*;2jN;hajrX!`a}&xt+UM8 zPpRzBpO|zN&X^aE^#A8`T&Q6a4sa;mQ zwX+hT)rOj9j8wvS3euCap{@!N_zISAlcmo7T5SX9wrn~cxYRJLbM9~5XlMY*D;OV- z7041%Ab~>;A}?y9SS%Ig`>Rf!rDC``L-t$LSd{+WmMs5WvJ&7 zTV8y#c-@(LnF)5&nP^+kYs!8(GdNv0dafhN#=!mz?dSOb)eWrNfkCrMOuZCssh3HAC%x4X*JN@bhA``0B!i$EW_nng4C+&+1*_v;aUfs7@tByw;g>GuyFPyXv^^$_ug)A7+G(L#MK^Q35Uak%N9Vx zHT*|olX)2-NItc&IGsmxHJ-h@N(63~+F#!RE+b|myH^{VK&P|IpB6JBgol@}Wi$TCb;-h?>eD-<{m zIRDRNe9_PQX}xB7RV6o8vc&A+EuXkQ)P|>* z#S2+#`azS{tXjs&dF#B=%&u}q*vrX8{RPsR^rI~skdAbu^grVJKI9#sr@yQVgOamE zvr?YQ9l&hYJ9O85X|xjKNLNmM*xUU?=|v-JKjJge624&JRXcsVFQQNI>C5ivdP9G) zIBC4gLbBbm>EIuR=FaT1>QQXg>(EiE=$R)8SF z;(ple{bIvmok}TaTMZiA5%eqrCU+bweVoVZJoYi&?_f?pu-4ey_)OE4nrAoc*Q8F$ z(MrW+2@@~l?82-uk5kG=ecG*Y(@_P&hpM~8Xg$wVf~d`a>348->ZinO&4&%?5EmuQ zCCyM5L+{FT)w8*_d7c!nOGhy?%D_PMqi6R~^blIz$#L#bb5n0d|Ff|XZ@Kx&gu*ZI zO0hOK`_$4KDOM}Yi-p+E$}A3G<*+xA*KaZj`DhA2K7MEdn=rzsEe|BQLeh1fj|h@} zUO{Mq=c(N0Kg#;ib@y;T1ns#lb3nk_q%3m+?<8XbJhyflIWvA=SIg8c#>Ndh8CI4V zX)0*RWxZX$w_~63S$&8rX~&tGEBDYRDMhQY8a)?ll2`PTz_?RqKha!$*}wv!>yE)M z9C=n_eK9eWmDMky!!{A6&~rR6pW4RC&tS#xR%!VCoMqm&*8Qe8WgIuFxsw28hWQA_ zzl2gKN@h`Q#r@i!ZxJtz)TI#wJ3!p32BD(24UuVPn2w;%C%Pry&{lz)U@^I96pzpGkRgU>k7x&2@#Q{o=}DX^)jLd;6_6T2k44;r4wmRaPQk z6ZGd=tHZ4+gVuf8kwoCs`ldzH*wUumfll75i8m)6%_7{dTE5-PHL217_nZpVTD?IH z4-_N~Kfv}|1~|J_I=cm3i6RtzgUQY?!hBKJQEFV;r0!Cr`-**4pH^!sbr9>E*(~-4 z(s!!rRk`MKCDF#z@*RgwQ(nsjAP*}X?!PDya~l= zvs@V{^0WnoZ;HK0aS z>)>g}Rsa|Ru?t*Uy_)W|0Ha9-Oe(2Po~U^%v*wftOSja-zR6Y@O|%=KUrxLTky(jb zYG#C+5Y;3*xCs_dOh21yU-!S`fGaC-hMgy|gz8VpGhSSTBnPuEgwWp$%I&O2T~M$< zG{M|%F6nIya^K*GXG2ztL-+j&BIAhmQY-dJzZ2~vXz$Dla4SR4-d&7u@Pys8Mjwa8 zW~Pf7EfqGyXVu&eej&RmMTPDB)JLyj+Mn1zK>dIoVu98xF7;Puu9^jGTnDWm4i(x> zxENv?>>%^iV=|{RSgqD}D+;g^x~<;H@nZKmpB-sAjfA*&{z$f?&HV~GscXfYe|syW ztJ2CwGH*;!uC-6|Nj0O%1fZelGO~R(p2y9(zbzPh=eg5t516TX8$VR`1q{VP$6gUm zT5`e(wIJT!j?7s%>RYj6)R(2))`HdHxJ*G#>-smn9I9W?me9VGygMbxvZD8%B~s{% z+yL-%ZpB52yuy2BHT|}zW^sNmv{Wi&`(9yCf8~Q>Q4LT$p`b@RU@qti?6i#cim_hs zz`)8>$&GNthW9$eK6B7w-ZXUKo1=b`y>3r)r{M6*8sw5*g?cw=EXLAdOK@$kv4ri? z-_fDn(nZXlP*c&GW89}o@Q12|u(()UzA)m&dcT zL41zvt`XJm0~gph9ZtWW{GO-cC%3=j+2Qxghil(O!8L`n6-}b8#mvBl(nq8}i$76i z2lag`zo~LyCbKcefFv$X?}}3$r&--k)PnuvF3Wx=?iC_6F9UeO22Y4tNpJcls4eYB z#;>iX+?SVAp{d@N#qjuRyZqs=_i@($*@o`y4sif&A<$zD8Dq{_$<)+5-9Z<%x0g54 zN)4#ZglgIux5WBK9xb2u6^Ou66k7_%&W*Hvs0d`m49wQno7aSF01CLuLq)ew>h5+& zk1p8j+?TEUIeE7U%0JBR`eKOqp->X`%AV^c!xRr6jy)>Dv>9!c5}N5{F+URVr%?JK z-(@riedlD=#!AggG(XYYBB6g$*}s)gl^^}iOCq%e^c0L=taW69Np51paC?3e;3%`;0|ZN(4W2R+c(bFAszR^KxL5c4nSqDdy$UZB|CV>qn?w7S2^^MTT;IJ7(Wurzvm;n&`K;v*0iA!Of8tuWes@Wd8bd?JDKOSz+$EK}7?$6!H>W z0BKd3D_kvrPekEQg!Hz`)U_S=bhDugz#r=C=Jf(Gi2cSr`_kDA;LVBlkG8Blm-q$t zK*A;_6RIN1cTEw`cR$ZLtQtJ|M!1`5BwFj(7H{A3+^NAxS%AZ+vqTijFW#;-G}Pu? zl(!jY#6aMh^B{3i{C0V0Fhwyxwx~6{gz*$%*LxI}J9thhcpkoj1Xb|5;ayRvD?c7; zH3=-~hHU?Z;~lrmnv?1EqKnP?VkyaRw|}CpH6;Rsg9+;;(1xqKUu``Uw918y9EbIg z0}KZ82%HWGy|hnUtF_qdmw({xjySu?pX9oHF~72NMq+Sk)h9AX+APEp5!NieUZzQb zKS34BbstkDrZUc^r>&&pf?6hql_4##D=-KNgAt{Rhu<)MerWewIl5x`2n*rSfh%04 znaYtf#l{mub$&{Ede885{r?M1-#7t}hx)0&@NJA9(flph7(G5C&VK0#c2-9xJvx+X zT}`LQC@I7h3}*|6YzwYjA*rWk6y~S9eyl%5YU}GtYRJiq_e?YvujyVen&u@zd1?}T zmY(Cr$L6VN3E8KS3nQ*FaxLczDSb5n*}BT_m;27^u5b;64sX-_mZ4=Wge+8(V?UFa zfE;o;p#J0-@;A>sOsqvw7@_~sA1d)r;qTQ`pMKLigRUV9aQvcyA}ueh$JhgyYs`D< z8Gfq)L7d~u%n=^TKUQ*Zspci8TQsApw_=0PuIiK5Q2q2VqDx{nB?mrpF4s=8a5klHv%FmCeIJzECqY4@ zLRNj#s<`2$DsZ0I z4f@V~h}0e-?xd343q(q%<#2{(tNzk0Lej7>ANAsd$%H!o!|q##Sn`gkj$X@IyHtI& zDNW}3UplO1)t?DFc+bHJ_6_6mqo1h45D&qxo&jItE@%!Fmq7+mA736bPZFET6zLTS zdP^qt((YG1R>rwbP)CrIJ0DFMFld?zdB)^_8Bgc`GM@aV*IfJy(5=1FD$?Q7|0o_v z%-{F9mDKv#uxg*>a5^OQWxnBWqmlrFm!Z~6lUv%zVNY3PUuinaPoT? zrR5`=UPL}k9(V}?hZyRF^m>>*WoFsA1JFeq3&4b$wkmGL$9jmf$#qAu;DBh9*!DSc zaTrqU&V_ce7A_kur*c+hj~woP2OUPTQ2{g|Arm@39%m%MON7ooO7Z%2p~UaUB#^N3 zIyWo`K_y3-vjYtfK7A>b&&nwjalwD!5q>bdgSFeN&s!zyZBxi7kP}ly^Y;V!TVEzh zer{_2Mlnty=%psA1kCWO*vN)lrxJnhPu@gXq;{UODJfsn2-U?E-(UocM%(iM7uanp z#u4RU(UZR};~$FY&7XzIObV!ddOOmw%GgYaTsFB?((Cuk24Z1BQbK-!OuDR#Lx?jr zL}$BX?FVl+=g~!w=AyVB`=LzBz(6C-Rjg?*xoJHA$vDyXf!lgN z^6{VXFOYdG>P4zM*<1W#NW@b{PwmxVf| zAZ$2x1LV(E)-pGgiCzLD*mQhEF#Vxc4lf;Uy*$dvz$K zCK{MO_HT;wl`u@}K#e%&FJU}&0AGz;(5ZL^I}5wshh5ZLf24n0LE;vi{LEELcRo30 zeo}rvCSwlKt(}Tz_KJv;($!EJin9MAh)#PbnjWSI9jwIw`_A?p*m-JF`1eRq&0tNz zL??C2CRhl>6OUm`EzvRsfs82a0NGD~^Ac8K;+Px~w^1DMk{CbU^Tm@pWg>w$d$O6n zPvVo>W!n(!wOl-Oc~gF1aX=iZ#^SJ$0YUZ}j*K>_cUh0HXWf~>XcX(Sa~c|y(zd|> zjIW;emy(*=DHGjqlz;1P{~K8tgAxf@9Sq$W9ITk0?5V5Z|7uK}O=(4tRE+{4UM;V* zILsKku!(M&=HEOwRkwoTK&Lc<&v!_5*ip#C2#rsVbUO*$*X;`1#!I5GajWQ~Fu9wF zbDzh>gjm@UdW{Q(u}+RFm$4pEC`xa7E#Ik%h z&w;WVTiYJNq~4%$tBs1d5-AvTQ(15Txa)kG<2}$KVScrQS8<|Xo&Jk`b>$nWoZ9NP z=H-*>yDLHTY;L>a=x(oDyTef}Ieu zx!3RPl_>CtL0SIqO9&tfUJ<=S?DELF!|p@ftvb-XXP!A&0!wSq%b!~s7;?`qn7Bmp zzSN+#xecY~0pn?CQC*3yKIYA@4eBk+0*Rq58**j(pE()u`b5czssfGFjdWt4p?+0~ z)HV(V#gCMSj4VowfE}4O_zsc-k1f!ldF7p2j2%EAMwFx8gxe%*n&R1~b1HnCjkSSr zXZ?TSPVUc4B4k>S08+FPd-d0T?3OXG=fRIH_Y0DQGKKxk4_1$9uu~3Hmrm!)ioHUw zia(JHn-o?Vy#-ZFcd-OAVMc9nYvXCRo<*?{0RxOq2ux;!bAe+z0o_YML6 z2f!vHNaFGAsxYlz)6DMCgi)vQJGa1fpRIw{Hz)-hAmh4m#Z1hAJQbW8{)FCVX(J@3 zV1)^4XmdCOtsYME^Ps$dT)lCRK4RTEBR75>k zEWgmjF$6PvPY|>F-ln;~z)ynk4@yn=33KG4sXd7WaBuBK<{P)nRe@0)dNp^YgR8yb z860}g(>!%r5pR1Ftt8ujDAg~ht1QlV{V2&w-EVSL z$=xg_DjfK)*f;q1aN95wriFq%fz^|mx3Z` zCRBUfR;V^pthdx;=e0@&YTj#-@t2F(-o<)~5KJo;;P1iU&?<^^Xu!Tru=QW@>Znsh zRB8wQXnpNo7d1iuZLA-96KxrE8vJ@Au6#6>Fy1k1$*f*^YvZ;A$nU)ZGF${uQ2#5Sa&!7WW9CGc~|FM3^th1CklBrd=F&&2;)mrKa%ZKI2 zI!`%Q`50QQ^a@shQ}RYujJj)K@ltjdsQL0?K`!p$DQSyaO%FN6WA&2U*0bvs{`vk_ zs9$^zt?5o+Lu*Zm=QknlK#XI83{1*wrB@s4dJ+Zu*5w+zh<4vpR1i6*FxGh6Gzn}Of z1x4>}CFH1n7>rTc)DzEfBh*y8Ko)N6$o2FnkL&eawOSE^oZpzzg2CRP`3#@q3QIk4 z#D}p2;=VcyoS0LOO(pjM4)i(!!9jCll+vCQBxpKiYYjy9-g4!V3#2 z%EM>2`BM-cjKPlp%1=Om7xqij?Tp`$xJ~JowflY34SnV5`S2Z(Uq6y)PEb8Gpz5 z8>F0xQ@KEIf9+H!(t6_>cAD1H&~&B7>b~ye)G4tTU?5QNWnwxG8NckHJ$1z9{$oqp z{dw#2rh4?BA2G{tnLVd_mIf>7{m_|OE%aq^vx@2Z%2BjF|izXA5vU1?$WqRIN zT~wx>c9uh0w1SMQ=Gj6B!?3z5Q`Z*9LKZzndpOZQ@*Rx1nJZSlWJR9h_&d}ko%92r zO49Qt z+D|eo|KAjTYao-Vj%}ri@ssQk?+_fI*0RigIfJa4xfjY@Q26bOEFMIc$>6eD4-Qrz zw6DP?4%xKx7CKF%cKY-&E{*A!#kpS>W_qD#OC@A(t>-pebK6(lB4V?9*2F@yK9PW6 z()eH6&W{8h?{FGfGHl7H$R1vP>6jxpQU;V1aRPaD)g7Tj?Chrr^&Q6zpo3h%-( zKW@5nGbECSSc)SvgModGDBus~Pkj}z&oXU*L|UpMx=~&l`%6lA;~tG~9uuGFG1W_0 z|10M*DZs|(5&K>2oKzga$1f}-^D&GwsJ1_W&a^fYdD5k@Q$W!ET4a_1jo@C3=Q&}= z2P|oCIbgYWdsp>uFkpxy1a; z#e(aW2(OlRTH9lJ1iz=js0SbvhOYICb7H&YlTKZsN4(`FSzLE92t{U2y`0g#qDSeZ za>LVf2B6_Sg22F}4NNGHhvJiR?6_7cU_)Z-XMmbevK$Q>3)6`2(!?}H`!yj#f2i|l zH_7OwJupAuODhF@|8q2QWg8lJDdeXBMCW((lb+Uc{KoUDkWWTke8&buRylsDyuiDo zJs_6Az6VMzzSnUrJ}))LzC(no6$dA&Ln^RVqF$Adi zGIf@({lOuKnp+^SYbH}iWdt@E?F@xb;tf3tiAb$MqnJIAwuqxjVS6=CNOnrXIEIYIig8P(@$ zUAM3MXQz%~)pA%`K6Hcq8@_t=hBq%0mI`lZC3%%?oLf0LuY{jgvIw5?B&c^%QSn*$P0~53F<3^HAKW4vS#qVu!_foE)VtrWZ8OxKxmmSPCT5IVYB@(pki;O_g4F! zCiF@X7&FzsRvz$&`~_LA^J_2jax0~v zovlVF4XA{Bs>h#DATRbeCBB^+i)d5Fo0diW2a@+K%8*hZKW|B4DPlk=(vg%b*>u=- zB&yc{E2b)@5dC-;TcV4Lx7f6cp-ZTp3i!)HdKmShZ_ECW;fqMry=l^Dxd%7{cwj>PKN)s5$D z&%JK~JLPCY79E#=CisUr6<_|sXiNSaD$^W;cKO^OA%8Y*RUsIzBqJUSymMa#aHfGB zv(h{4rWX9kx-VlkNr^Ch4}tbVQk$h2vFKc1M!6Qf#rOSOZ5mu)>+uO2#syUT*z<%M zf!F+%lP%is46!ury-0|wK@>0PBQMKVe)mjqkr(xZ zD6{;K>5P;TF>$slP`{?-o#!d5l<$yR@?O>O=`(v)iiEdXgBQghNnqFow&U!QFe<2< zG^YhyjPmNSH5;(vFw&gS3z@Q>b#-6TY`x+FUWNVSRZtKhx=CC=2n_Z8^M`lZ@2%tFo-`yR1! zG37Bz;DSYBR6&r5C7a1XKw6|)z_g`8U_>R27=TixR#+4(Y%woyPW7OkVu!{k9nJqu z>YbbC9K9}<7>aGn6(d`UQ6zWIX@&fWL5Rcb( zr9TDXPVI%@{~3f#p4PQ?v)T>Gg0L=wK8TNYf(BIV_FP45oB|~gmRawqAN=Dt;<5eV zRrolibTsh|bV5C~e$UL*3uW;7MGhuFlIAc{Ops^)wC{LPwjq2haVyCVud!hC?jrD( z{Oj3ptEPcBXg2CiCSdI1Pi~86Hq}mdO6+#f;*`KJt|1Pk;qwxWBmUTKqMefexw{YQ z7C@cbb7A3?63}K#ln8Bm<0(I=Um~@eojW!;C6h554vkmme+xt{ zc-eoruy5vujlGW79I|NWOB%y*V(-nhV)m5aWQnvh1T(R{Ij6HI?TN6z)>X)BE6m%G z9v0#*1JNY{TIm3ZGWdFw(!Wj%Gp0R-4W#wWKp z{G~6xGML!n)*O>?amu`v{xJhQ6Zqx^V<@N2MoLWA9IlFcZ%;`&HvYe*62|{>hi~69 zQwbZj)q8#DJy#D23HwL-3zK-#x0(ByDGH|lh|8(O1EDX?l<389JL&xZefYdHUYm2wJ$joB^JtFG1k(gq~E`< zJG96B=ZPZVr$fE4tWIO?lx33}(FEXwT%10yFgPXiL)(M#p`h;z6RM^+CmaMe)GQW% zrD_1P<=uF%y0)O@ki|JDPuiE7i$H{D6IGH`_Ns~+vQv8|64E9^Xp?lJ*3O+>up96j zOWKLwnr2_xe<%#|Gt^0=pM$u9hqD=15R*0@=-zbQJ#+<7R%Ws-_grypnKy813EoAF zsX2ey>R7+kq-pltNRV)pBxdr^8s+O@l{}mkB!@>K9z5c z;0rR9T41RQdE<@6_?iq?@$--hZPE`JSh4UEK?%-VSLISL@zA8uPyNZ0*LA%o=Y`Zh zUV=<(Ije|*aFd1*Uda-B(N{cvXz*&cyCvsjO^#h#7@W6|wnLPpDVQO)It6`mePDim zl7B?yAkK`t62mbHq@a_+Sygj5brMAv7QtG}S%XHz^hx#l&Thz(j}@zZ`rYL03Efsa zyc5)57wUW7L+`n$#%oNMsG5FjI+EY6?=1eb24^(RD|T4dPWdzP_jPj7B3H`*Qmq)u z>31%(B+y#S3+#?3mbOD97QsDJ{!ilyKz|arcR`C5U&rCf=DQBA9%e4`T7?0U|LJ{( z{kXBAeWJeoefUA4Ce75Kn?XMYa=CfJo5c7t@Gi;?i85#vS>AKm#U6Yu5YQ?zV~ zy08S=(U7&q)hCMfG8bIsw>krMYE3S2pIz`=*?tt^?Tp%!fh@<+NbEKxx7URWwV?yS zO(xqncI2P%qqQzs3S*cuc;AVKD~l&v@Lgi~&1SEuPKGjtwSV%z@)2BFQ6qbXWDl&q zX%UXpu&K{J0yWVN&(bP38Rv6z&d3#>7+($+J4 z0_qab2e+5UkO+WiW)kvPd6u!pUtL4NT1)s15_BzV{UZjvH>%<-%J=Pq?%XA#qZKyX@)kudj|%lZ$cWXoZzt_C;7k_kI`hWANK`|D`#A z)8j%Q8s13NpL^rMl{AC*0@b>bksyzl+s(tTHa%-{5ViLT@^rF5hl)ieFdaB@=|jF3 zD$}kjI(=A9KK7qq(A9U{qo9%n|TvzHI0r*-BwmIMVaJ3^|&NBbbV=Q4TA-)(`F zRP;(~J=vi+S|Pe_xd%0A9QtAvBL870{P&6K`Lu(J&sLTfJGI4b%eY}5jF3Oy(@f*+ zDS+>E7I(gjy#bt;!J1bsh1ulzQOr%Z%rJRwSfrqgD8iriV6xg^e9r~jJ;#jP|J1n7 zcT2hunw;<@YE0kb+#Onvy8dNX7Vp|F^DTA&y8Xp^VsHJR^RH-yo!WJ*?%e|$@P;Tp z+03~#!TqkH3m9tBp{v;~E*~qmC?WR(34cZPzy6UojbFTu2%L0KAFJq0%{T2oL(v20 z6efE>p)6le6EuQdC3f>CE6H0LS*I{k^Pd zzCbS&PcPq{Jw}hcm?kVS5mP+w7^UTw4+HF{QOo0dc0c&H+(ZSm&`AW-q&4IsO#ncjy@?{yt%=Q*46Q_oxKH z^0j@23cl4v^UWrk7Y_e|Z~968Hro{1bkFeoZShXOZ_}l8n@GteQ>cu{U$t6NF@zlr zTl`I9wbW<4H;`VEMi4)Rn%$l_sj_PsknLUhPhSGANN$xLp>-FbyU*fOZLGi4%l?`f)Hhxgl#(d z2r`|snOB!&H)OX*Z`C_)tTlMv8vS9A`Zfl5a>ykI<;9FeT?oLa-QE7NTaGM4-!YH_Lu|o@D3)9Gtu)N^&wgROp+ynPD&F7t{GKO(E(8aab!}u-8->dX zvSQM>7Uqd?fCb+%qo$RDz~4QISW+JY>k`=yc6hr;Xx02E4?G@N~8vc;3p zb2VOAIWhgJW^mD5)`nP35&}i@o`l z7oBcN8ot_1f`+IJt4^j7v5DH_lrx`r?!V3P-ejIzL;uzIp>jBl98_N@V!3fTB)d$t zj=-rks`_!XiUnv?TY+ zpERUeVb7oR|B4BR?OQ{7eL&CDybHXiZz{?|R7qW1j)3<^mY}9)8Z-x*Y7Sv>rQ1Ui z2>}ab-^_LECeKVXUqO$oI;(gzLT{ko@CU)R(%lW5wRSi?nOe>1Wn!pkh2XP$Er4&< ze59Z);k)NXvMx6xW|Yg-R>A8m<1$y%oqAfYf-Ozj3iTWM8WX5MRs{L=RQ{-UwBgf^ zlZPhFolxHS?ftUZVK-KOD_eBf^}=;58gxFe?z&FLN!u$?@r1+mr~gFCOI~B0g9jW< zV0eS9lcRcBeVQQGOMi{ss;LojTyn!B0ovL^y9zABQmD`?Gft#UNs4!tZa@&y3k$zr zDab*Ei0R;LE})yCjs;aDe9Z6YoOFVk*nn+qyLszTOgPbx+ig2r)MDb=8rRRzPJ*IF z4~KQ8CL$~Yt@yO%eeCAzp5it2rIZ8BOrQn0US1g3^jz%kVgqeinUmjIWXaXj!UdDE z0&Lvla1`oxjduCf(z5_ii8&7^`o%%pRRgtq$70{GHc}owTq)?^W|mql@?$4(z0}K; zmCd4&XTQ~i_zg09!*WAA7a@zYT+PLLu?21&&rb^)# z>Xnii^|}p4L%fay*wO-RrwvM;du6-b29303kU2|gsNF*xiP;EN?`z-%sQ%I&*fSy`{jppu zWAkPli(`3zLNTais6^j+0NeH&09LotI2l?$jLUn5Ei5^>-aJV6m;{NwL*UnJG_gM|M_MSl)6;%p!}L8O@>b`NmEZ(*wa4ZpLRYvf>mtOkgA)a!nR5-FVjALL;8JpL@ydTO>ApIUW0ksXf~j641Gkqc1bUajE*R#KdTb2GFk zVWs_!)~ZRMhV#PRny+!5zscdfgwcz|k$GgOk4NP&>{Z9G}C= z5UenlsNP=i8`L0_5_u~b>Xs<$O3U$S#dwJ39Vjwp0M?W{K<77Mb}<-miC6WJ97Jy4 zoVw?f_OSPl@8~M6G7E0hF+-rQ!B~1snBI5^sBplG$t!~XoM*jY9L_^HPIIr_Rdl%* z>{7i7%U(p>G2-5sBN)s5GjCSed{G;jHWB4jejVjKEi09SO$131{|fu9f_=Kp1L)DW zX6Kh~?U%$5e`WlXL^%fgIJ4edO0yo6oKen}_TT!H{{`2)nZdcL1-rB2QkTz-?~0Lu z)_mU<7jDMADY>>KO&oEaA9}5JJf5D%&BiSw_~nUM$TWgDQb`8 zCK&H-=1emS@U4wro2oV;V1rcT65%76Jj&h6ig)%l2uLhf*!CRSjo%&*XD$Ia{mfh1bgxTqTC|$}Vl=76)UEJu z+-}#{IGWF*z0!`0LW}h=Wp_34BmNAH-6ReQ9nRvP{R8J)@?|D(sqS*DQ4ufp$AWc{ zEG0d^Eo|Ey|88h1eG1REpB)@8xJ22I0nEtm`^~Pt2-xHzExj7U&1U&M-ze^r#CLxU zw*?pW6<6n_E(l64ZpYT%aZMH=7~@|&N1|x)IM!)NLo>}ctzz*#NUau-Pa4PJ;OSa# z7Ffz{mKwVgofd9A0&Icl8WIKGFl46yMWS6L516GZ?bsn>Bbw~;-m4RPzfb?pSu$Qo zH}C`8n}%%Kfhxr)o=f>713BmZ6(sRzBpu)|HSevOS;9Hz`!~ z@(j;zcrG~}xm@;nr(;|*BG08UH)duO@wFoi(IpD`s{#r52^-OwCP)K|U6e&F9WQJf z2En3)>KKo(R;OlpM9?su171wKU3jxrb@5NM}=}I2_}Bz zi{93J)Es{P$)bV!>_ZdRCbAVr%c{v^4N7be|I|N7aD`xzXW?^hwZH$U(*MAy`1di( zkB=nuz+}#04Ns+9)K@)MDfkdXGh|U7f>wh>7lO-K*Mmfs2Nnj1&QG82-4TGFZ7wdA zPtk9EsC14)$w*7H3m>dwC2NmPpZUSefmSVxQd#7daCigFcH7vu@Tc{*z-OQHbuOn1 z_BX9(TUWzb9h&_5pN9CeP*bWc5;dd#6%T>m#mOdL7wJFUBd5tkup+ZQeDll)Rk!{< zXRS)D;gWBEgLa-Qx4J`SH7lJo>(phN?Y6H&=!!3yFmR=Juf)~{re<~FYBt$dM4&oi zSy{eDadFKiC^n7#Ia0EgmS6%6i+xfnjER(|{Zqu*P-b{{#BM*)p~N}@`n>JSN^hFZ zW}$5Mu<#qj%1~2l3U709M=__|C9S=gnYyDN$gsGVQ|w?;8B5sYG%5$gZ>0C+98{C{ zqbCQC4o1Qn0sD1Wjvh+#!+^d1F-b}y_aw>GMVG^U8?wkbx*Y+3%jiLowWy@A>&UP{ zgmAxckxt8S>JQ0z1U$E*`TXlMvjx1l^8rZp^`AwMp7 z6I61rabZgcuk-9*OKfZ<;8)JFxgO6}hWo%#ne@`BGh|MdDaxg0Cm{#&a$m;0+-X+Z zxpaPd3K-4n3ut6wg={5H)g`7w)11d(l630Re~Sz|^%_c%8iAt<{QCA&8t`fRayZun zU9@5YeNday5}sBiAPdXJDnyDy~j4iUrjDizJf5EsV_C!_gr%Yp1-} zZA-T2${Jkl3!YrP%>(XYr0homl)9M z$cT#YzX4O0!!+j_i6?SgAOAzI|J!7h`dyOIR<>mTz$#h6>-^Qf^MAh6#Mg6n;9d7M z5?`NPOzvW@gt(F(yrcZS2S)>ejktAbNh9K>ujSghR+#>NQU~R;5mAUUz=RFUB3C7k zPpl_tEU8Y=&g=b6E9T$Ht19dJFXHw$F3cVq%0pvp{DcKA>o_gtZp6!V`PA1AC?kuw zs$@P`+<%Jj_puX@ab>m@gr=y4B>l@3r5os<4@ovGx5#xA~!N-#9lN#6yL8$x17v~2r)PwD&M7Qc-Y}s^8NmpVftFO zTc6UnaGU&n{y_b`ipjlvovn#qd$ncD6aKo6ibN8zIQ;6`-yxfTjm2aIF8UW+p=W_V z$26b1KHUNuZdow%p&1X*2$6$?$J(iUK|B$=CuR{pQ!066cb9qVJ+yw|51UdysV(rV zasX;;ph(EI2wYkKBnUya@PiX9v@8uQ3(4r0(KyPx9cE68;gW^ZEN-=zr+32O1#Zs! ze8$FVcQLpR*KJ+CjD7evaIZ^xakcl_$P6dCeS(wu>8RysOVCBhzJHeRG^q1Huwj-D zkuOp5_l`?OqZY-CXO#~qfdLD2Z;E3k60qB00?*8hmdy2bsSkCFb_Fs_oc)n~*ivC% zpF?=f2w5Eq84_PXAdQ~fv2;N$6Y&Gyq2S;p_ED~qtP-BHgp-jRLbfd=~^}QOnA2MuyPqjS4A<08aP}RH|c^U5ypB2e9T#j7vf& z#y#YuUGMr>p3So(ZL;@Ax;deVEp;nmuiao^uQluBv)T|lDqB%PGZQD%3LCzq4V12-EO>&oSHukFj< z3ZjcvA5D~q5(&U6didM|bqLSiYFC?W6_Aw*6t}ANnZ{`pZ0n~^U7IYX!jt{dBaj3j zP(Z21-U5st*i10CaT^=$IF6$bStX3GHnM!*5y~N-*XP=^f}f$((DD9H=n{*zb0ySh03Fn zpwrkb*@Ks|-#2K+Bisz`N~#FjGmPC5zzOU)%ACc^-2VvbDb`0#Y^E01zFlv|aZ=bl zF`~vL*pde2l#*P{6`f4wc)u2qqt?43w&nsWCvCS&&+=QjQgm+3(8POP-OKA7|H2x; zY$t>rUxmA(Ik{x?=Q*?AeWiU?@=;GeoEC4a=SDV{8}ABDdqF};b!ky(5|HIVc+a?# zT+88kBS}%FI#g+rNF;{Jzlk$~tb~cY3GqIk2c1gVT|OT#n)t;L*?p=?BR1gA9UuYi zvq}mp@D|SxqZ|SDU>eqfKBt@n5R$J-mTOL8@%j;Czs)Nkfms{K;+;9Z|=weOJvzG;cB`;tQArCG`H z-H8s^8d#%6frxqS5F%@z-J(#%s=)14TwNcIjntp+ky!2fbp$oF%LNclHW!u=3F&en z$}(zy2m6W5NgIk>+2(DNsl25fu%ncyB-Diz-~~_L^OsnzWv&-GxZnR_8OTr;E{E~% ziMJxRUq#^Zj|%#?4-u438L-UphjJr+N4%ze&pYHP$LA+KU>J9WJ52Zmca(`B{Oeg| zq*EtXL69|j?z*&hP=uve5B%j0ry0e{O`N?2KadyH*H9LATUOtx&olz@7)Y=4G>C-A z?URWlRn9)+{!Sz=H;L8I=cVO{ZY7*QbpQ?7UNaqa7FSK`&A4)D%RQ93h-NRE+pW3zS5`k6pXL>r?FihTMYX+yN;gQf zgX>gfE~d_Ujz@{E6-c=DKKsEr5dK?(K;ZjS%^Pk<-f8M>MMM`uam}yhy~9^4!%} z6Da&N{Xa)07lmuGTYItc#54{4?Buo!pvU^6A;XF`2{}UNpXoKGjM3bWr>#jFBAQ_k zqGv>zgX-T)J80w8-uG2y=awpHy}}2t&>n3@fDUTS6(6ANeHsSt*KYZBBNGPxA&XUu z=|;_nwmA3EW6K!Z62C%^(fk@~qC1x#fu2p1D;}ZV%uEupLxns)X-4P@zD{=!?La&* zxAa~pzW`!o(Hj>GW^F7t5m4&u_-CmVrVu&}gGag*ITeFqAwj7wA(aCKW67)X9}fJR z*QKY(Ge#^0kz+UtW~TknUrbpnW}-5|&HkF$P~Ny{rg4Ypaz-qqwj2z+@wUO-JdSw(KStt4V6{g#gI;rjafeOiRzGpnBi& zEtv>gJ>^T#1s2;DIBpSnMrPA%Jz^az`_0`bSW(xzxp?$iSxZZaQJ`>1C{{17*)T%# zHp6(U<_DQSdGIv2DM!ymsO6oLQHCF4yNvPh$gS8_T4pH6ZLQiJ)!d$NG@oMrUhM;} zjY^ikeeZ_;W_hg_;&d&tejPu`aI)|6hv=AP_l>y_CGujUt3*Op4YlN{eM<{KA7}UG z9B_;0^uor{DGgW?ulAQy`1LPXI8xyQQkIWoe0f3!qAmD6oMhW-@eF@+sQfW-b)_m) zp5|iRTcO`LyVZSl%ilJe&d$)CF^mUFVK@=;F@07$R4DBf(9FDS zL*$$-{X2YgYg8Qrr_MZhbC%biwy-&uer3MrImU)8W?Q@43AX|LI6n*8yVc#(QzIIp zWLs=IS2e>cCuv~zZL2m^p2^}Y)oYA}gUW)9_f@EPG3#a{t%eNf*op#%>RN3PYdmjK zyHd4OFsB%LTo{oRjow{-!}k4BJBG>K9`R{i`Rp4MD$tcHAObL4{JSWEv>gnZY9?ey za{~-R?sJPes$H6R?E~ZDkZe>l`a3+nE3vWZy2liVSzR9ExyM>Ih0Z_i$=V& zEOZF*6+3GnjySx`|6#=9cN|PNEqd=1<)@@K=)@!ZRvz4%I}A=l*gvYZduDJtuI$kB z*+eyi;E6l&&#QC8m9I>RPxbNKvv6m z3QalohBr1e)gSTS_W|jXd+Os&4BQNY>rueeceW{HV?CiueB~1tkEV47WxVnJ$IX{X zD~9gm7aRDCJzCNAUxkMBDvT{(l~9`eavlRy-YPR7J^yi2a#x0L$q3P!C^M}mbRcSq zb%6?=!Lx5m_$*=VSDUpSl};Mb@7wGfgfD68y*HDMGzKI{*nvMRQJ&fL-UOsYmKn%G z?zp**xRw+qPYV88ckUy|TF6Kh9sK9%Rl|C(TUCO{ZgIwtr*bqPB#vc!%DuJ=1tj7w4@m)wC|CTwQs>~OSp%u-bk1_4>)8Nb8D-%kWWc zMMC~5;q*odKPPGaORUvlggDwhss1ID0H9gD5C_c+b9syLH5srlxQ;*1`HjrivUd5PjFoC)ImvU42(v0`AIU`rN#}3} zKAN0)5!1)KmBLI)=?s;h6ui>%E7xW_5ftQwuYoY;s<^6U?m zZ(h9S{ZX`>nya_>_7B`8<$t@R>~_OA$-AaWK+T7iGIAE>4Jup7L~;DKZPvPM-1iOn z575iNv}VU1QEh65o)xXvk`CeZwi+-MO-U z-L&sV{YCD{BnPcwB|%Sp&TL-?)~PQo%?>tq!nUMQb(upDc9$>nP(IX(3e+tm(9EKc zB_|uK&I0p_c`9~i*`c3ZS0C2;jd5rBjafCRar@JYdd3Ic=6Y_Ws>rr0;5pLql#}2p z?{Wi85#i>gLA^m}TIqU@b!QO)?%$pL=6sS(96egzlNWj>dmW!EbN>}4cREXS%}PFb zecn%L!$)?sMqi`syMlY6sDb2ix^#gQQ>Z7GhPiapFiHi7p*rLB%T0njlq$H-}N*yu= zt<7-DxdDo&wqK5*ZqH; z_vOzK9h_(D-|c<;bJ_09{ro(a8EerTR-*XfF~+6S^{SV|$C#qL!D-E@b!OcH3%7nc zy8U}n=kh(=R_+7*Cr*cUE23`XRb;e@I662#s2f{IHwL8zz2M}4P=vk*!!PYpqF{#a zCVg&gTn92Ys`wZ2`36n5x>9^6DtPXf@R^wq9+t-|_%kMlEGw_WD!94{*+Jc}P9Qq$ zW%%^G+@6y7_$WVs_o``AYYn3Jp>pJ}dBcoN6Vat3CH*iE9Z*yp_$-%_0Gt+cTGriP zFu5yqw)*YQ9NQVa!1JQvSBP6>{ATcD(tv%XKRVu@k|_EX54v2?~Vp&7$P5K%c8aMN9VdDZGWL?zoX2M zaV=p$|98r#sPSu$T5eV0ratq`b83=UazC!^yP|Oa&AwYP!m|60>Tx3fFsYeNou#di z&4z%Q-sl6jiFDrTd$KbMr`nanF-B3ILW{cV<@ThHr2_+9UPaEv%JR~mb83zC=x*|) zeoawCPs6nl!?SxgCHwRBBMBEE^MDZ#-u*8kuJRBa~N>2Q65lnbq4f#Z@Wf6nI|T$u=W>J74~lXK z#kB&=AE;lc@PBj@OMv0(!&6p&!(nn-=b@GzsD4M~+D~@XyFV{rdp&-r?*ozvnu*?= z3rU}HX{q=*rV&UD@f;HJh(}eDZo6%2TgiW$C92C=uTH=oVHa8W_mU~yzGB`SqbUnV zZNZtonOv%XuYW?rXmQb!d4eBUvid)dOs0nB$#|x6YQxbDN;3a4kU=qhqP6?Ng~Rua zd6+|!ma}1N%0Do;JNipjz`Z3?YN-E$ROvsowqTLS&%i4#8y`_WX=E2ObTQy^Yx8)! z){LHX-|EAIiP}i24QobHb@w;A8&{N`anS8#eUF2Oc$W_AZ$TnAI0qDZsN)IcmDwaL zr`Y&U9^)8#B$>Y##A02ka!_9o*v#Jg!x5}QNTMHhy#HoNuhBomwvFe+wo!FN&&l#d zJdlz4oEw_P{NZ^ccBDbprresAFmTIni=O4zg8oBM89cnr*JQ_T-+T!QAn6ExbY#2+ ziV!(hLCHqNqL!MydfxQ~G~dtMBcPF4b&DzCoioUfqKN5t1zO>?F)=ZNLe&IrEHyr2 znR}bZ-*o+p-;zRVLURuDMLx$CI?zSt18Dd4JRuqWei>S_dkN_T-ItWf8>I$wGGL0l zLADi)0gi|sI7u>$t0crTxAqhVVPDQVp08vyYmTiq+p)|+>>uiH7vvJ&yWo!Q{`GKqK$bl6C|=L}6Asj-xZ7{~tT5lgfXBZ-L#O5E3Y&}_68@A$O}6c>t5 zYsg#|_J#lY)cGDi)nS;Vxx;@v1Obn)=l<^d`QM&*|4-SZ{Tm?$-9xKx@1|N_B^yZU z)eFgO@9~ZY-X5emO7BQ0@fZeQeYPxg?jpVVlyaS#M5Ztxno5@AV1z<=|q+A zS@@vPujzY3JR)yjKgK*23$Hyf$m9+jQC8>O0Qy@;31qj!OwYX>(+0N=8U}R8^NQ;;5axgV7j^_WQ36AE4o6#_YVzBBZ$xkkfI%CP|B}2J5 z$Bc1Yc9AibXY>qwWpU&Q9-K8&#k2MABbxo$nr1H%z28oR<#H^k*>cm*GCHVlvF!y`GkUUj z4Y5vjo=<+Pl{m871tLACES12YUhU4E8lUq4!q$U})HcfxoCEbSR4uR?%QmurU%C|aP#y8>m>6Ybz<*n^u2uG-XEZ)bom?)RaW26L&=wsamsdi zDSlu0?CuP(^tnQVblJMJ=qeX<`Z2n9`$z&&XT4_Hoj1mcPBIijD}qnsB!d|3BjE~F z>wXz;?n#R}bS(_P<%~A+$2A9rvvih}WWwo87X#>W@v1qFi`X`dtzIU>e3oviuJC~L z6IX^6eoQuE^sHLlGYV2ek79clv;j(khdOyFl~bPx;;4nE&+b{x1CrDr_mG5di28Eu ziky=pc5Rno*_axytM|lqd30^=ipW3beBS+pg{U3M@pp}z9lkKhG|vh-wZKFn9l>Mj zl;_2$K!|78wz*fV=GvAJa)!r`l~X=oWfbdHKI=tGaa~ePnog;HJoE}R$%P)swfSq~ zaV^%`N6f*#68_6sGL5%Q2u*C8>tx$wM2fbsp{D?bFOG-PIgVPJ82p@O=i8Cqus2$H z=X;Xa(1_bn646;IDkm(yU#zOUB)^$oDb&MgF_QM|^f*{H}{tO=GrP#cY_Rao?_ zQNhcXU9fHhq*^hujX@qCR5;6aZLMlK5bq3qy{xLauNPpk4{3W6r5O7tUg~_fK0SS4 zLd#{6kb2bej%`mugNkjETtJM^o0HcG$p?=%J5RZ!iG=hk=9DtR_nvXpB3}4%p}^D4 zK$HdYd{;vFE7q;5N26_H8=?M$7ko?r0C7D!C4dnbdH89*p zhl0RM71p2bK2grNBQGt_^8>t;UEKAY2>It&d#CQ5ywgr;SVV*LQ68ewy|wz}OHT-= z^t*2no8CKiORuK#S1K9O4jp!zkw|l1`G}iKa;&YOpzib}%}0M#w7T^Z>EvruT)#Ht+^|hNSMXO=WHQhwwfm@@)vd@ztR zkO6&DpAwx_z*9uQDMb%Wh$#+j;tp6_5{lLmk5b-=A6U030~wMZcCULFe)gnnm*E3t zXVQPVZ%Iok_mu1ViFO%^1+2dL@hbGcMo=p=`AQ%6ZFCl`H&TbT)SGCpA`&tj5xpZ4 zvV7f*c$j<-t+5|*`2%2HB0!>0;wvGTKe0K>B-3F82K=C0qH3l3mGnU~VqDsC;@zxS zx0eB@l)it=nmI9bbWNK*KW$s<tdKGcR-#RtB?OPCBJ-^O*>mL z<(s~E<(8ZO97y%U#TeIn8ZDWl@f5xL6PcP@X|lRJORdGiDu9H!VrN(O3N)nQ@keyr zMLiV&#V4pmZcBR4A%}osJ(^UP%cMOMe6=C8^p-vBpr;>aXd`DqI@%q+bYCB(njkCn z3PT9MUSz6&8+hyYRg^ZXrxK2v#QC&3`agNER^!~5I`?u>Xz3KRAremlf@hItb+_8r zsv7yim8r7l-K_1}%-I(eu#H0SW1}Z8ZM(|<0ltYiQG2k5NADVA@P+E{k88-(=DhC%i!k39yQFjM6{0~xbL3*X!GEC6nG$_%X<)DCxP6)RCXg*M9} zK0k?ng>VUO$Kgem2qmYCvBU|RLPq>}BozJ(s+WKZF{_!0h?v~BFwm_&o6}!>UF~2~ znSCWTvVME_iEpS0jD#+F93zmrD_Uf+!)cd%2{k?}=)p^yHDx>vGo9rtHWAGcD}BG* zlA>R{UifnZBi4OA(zem~P3mKK&)@_%eplwEK$v*{U^UrxndG z&dm|lJ#7piywnackCCf(`WCYRJymQt;U5TuzFHMx?o968=pkAH7L4O%wN)o?s5zL6PyP^8u>GN2GyNuD*@Q}fH8 zdz`OkO|xKj+`Kg@*1Jw7J2eXtWU-eu=gN9QL2`P$#GYRexqk*2R+eqdWeK(Q+E0#d zg$4K#*Qc-@i_y7(vR%*$WM@WCXAVECT$S1G?A59e=AvH^K5j(oRh+yiATCt1{kOn+ z4@_GcJ7JsUk(`-J%K~sPHspU8TP|R&ZnH*1zMC@!oo#GV={|8J33BhaQl3)&{-GBK z-}*rJi-Kn<*SKa?eTfu}U8m6-`QsMpL0l8yHItx_;|RB@;Uky059_y{4?0$I;@l0} zkwDf|PiDRvTlGe@>~h^q{x~+>;rPA8lV3*9f|m~S@t^QMAE$X*8AR&&#=I@!?O4kn z%HcXcO_rSK&~*^+uk$Ps;y|0%hASo#MThi-1g5Y$J4dpA_YiQc<4Pqc1)Q)%QT^!; z+v?)0@1n>SXAdP(WL8%$>3*AcI-KhEqdUE>Ls}<95qS<5R4e4pm>~u37PFn#r~8d0 z3IkRC5xB;s0DG6_JtsHkt{)74$S|I)>_)r3UrRHx^-7nC34AuRxI4nBj4HJF$hAKK zlS$8&`3DI(ML%;$vGgMJRd#h20ZgX4!2?E%jD@bS1x(huc(#E0R+K5&WI31Z!*5(k z_>vEA?HUT={_%Oau&M>O%Pb|!5~^DTS#R(Rdw?^HPY z&)`RX)7);^Z_G4{<~Lu2Izlq)al<#R5cY1FvsHGx56{$l(Gyk_?3359fa>XX++X>J zfZAf7XN-`RGf$;(ocQgDZqFZsIHxLK1p9}Pn{+c3bqqv3sfOrDH=gu(ow{if49@M1 z2mfuc^=Uq+H>-&!>-YO%AuZC!mbh@M{0;}S&l!@phd**^v8#w`XYP{I)rmkS09ojr zxt@HMy7YyKBn<&qMB++^QQP#CE*C0@O@OiTI?PaKb5LTMx2cQ#$HEO3Jg@ls2#(!q zKN}kEFsNVgIeu(`haG7}NV%*=%#HygKlqIi!YhnqJ{8?KvDA!0?4t7| zaf3c{e1GFp`AhnsRQ>|Ul_j%E2jv+(Ks$$OmAd=@soai?k$h=QD-!n%J!EuaQFm-APXLnw7W~KbNaSR-XwON9qXqGg(Mpn5T*8G1$croBors&y zVkL{71_8>sSRS7(Ar0HjHm+d@GkqPiT;r?Ox>^(^6Vvl7wc5r+ zbzeNkD0V#W`a~J>Zaw%$!~{)$M;?vq^XdLpGvGA<};}aIV>I)(bVj`_-{v+aZ&tU zNxFhoF*o^AI=mxMCh4MF)FC^X!!`OvE{*fk?SzE1@wr92TT^F$h+VpgKjdPo+eSTX z?(KRlZgGF(06Tt`F)=Fc#fjep7?(ln*Dlzh3P#oJO&ZA{9zd9zJxk%wsAi%Gq8<^=GX*SZTE#!_ExW0cWa)(6N`@ zsdiCi=VkG|#a#ZRAXIR;+T5Kled+zhs56-87y7Pyz_K-{u+j!1*acVM(WgD?fB}El zHTGA8?;q9I`o57Wd}r1ZN3fuKsJiLzk@n>HrX$9uu#n!?vVhHClgrqPgkZmc(f1?V zl{~G!pYEO9lUw^ z!Ys!R`MF1+E=-cii4u1lGQEoVL91y&% z*QZ0wlI@B=s*#kei_Etec14s-2%+9_a8=nG&(X_?3~uCVw_%Wg<{AwI~OR^iMwk=OYbT6(xs110@!tg%D+Ar{8 zdqq@>ua{5x{J~OG0JI>Q4MME3NZeT#BRS3DBnHu z=j&y{cB>H>P)H!mjn;(9$NgR}W6f5KDZLKgL~4*2uCqZlj6e;Bais<*4c5~7b$uWl zsOPt2S)<1O2>QluXUwVm5}#<*oPhBbt0EbnXCC0EVqxjJ>?TE&NB6+3UtoD{|F1)V zh~2yF*_rjYNSNoJZ{SSQJN;v!)Oha*IkcYVG*;Mn0|q2VeA&co$p#DzT6wJG;R2?e z7D1g}$P&)F^CzH*_vh$)25cEok5>B)*U-GNzq;oxgUFiY{UCQc7o|5PiVO~aM{Rm}zc{{mRBy!+NeoT9qxX%n_98%5=Ua<4c&F!qsSz{6bwPHY zfS(G^>xKoMNI}F2EK@89Um3kx2F8<1#zh0ZFOCDOn4M3JY;iOEH72#QT2JK8y+!w# z;HXuuj{?%iTUzBs57#Y?c;eW3r#vMOpQX>;60*R8Th-l$+ z_mn>=em_xutljJhCm!J+<{xa^QTEZA4gx`F z_h#mfCLU^&c_E1Wl5TiwYpL_rpF5JB87XRRH%dH$Mzc&LWyBNu;!Omhl3}U5U_(dN zFIYJFkf57<`jB*CTVtfDcRNgTPNUxP_Od3O@2*p;S+;7W)1gfMp^1_gppbKc0moGR zw$%NdPRu=v66~t}`Cd-<^k#`TvhnnQM4bZca6-z7DNp_opTHK=C|;o}Z;aISe%b0) za#K&Ac(kG(2?@4?iw)I2s-l$RFLSi?6%x$W0{qr#T!R|_;Ob`^lBthVbqAOLu!9Fp zK3Cy!60)$p?x?(aiyhi?5ZS%1pnEP4JuHLjIU{bD;h^4ik$Le_s|EDEeRl5jA)v%L za7}BA?K3ASubz%|f3yDjd%+Ov3vlEu;Hfq0Pf)+vE6AwEiR$8Z31u9cUV17I+F#Z^ zTM*-eYM<$SDxd3_Cesa@y{tXIX3NT=y4iPpC!M*byA{&v>t~K_h|i}*&c&IdY9ms| z%36ug$y(h<0b{dr=mKFCE$WRjYeulBdno`Di7w^N7j6C8^%n;H``DJ9j7c!DM$}GB z$qU+A&+$35NPkN((c@Uy*dWPM-CCE73gZc7r5@R_%tJ8_Wgew|O^!+8QGPG~=Gs7J zK>CiUtiEgISq|>0?}vCsl!SJ5$iGm`rEeV$8Ypf^n=83c9D1`i8&^H@)3|KmfsnWK zZKqRS1oy4a;?|e8ewuFn>V(o6#+wxRe^Wk{JI1>vujtYPVOl z_oYTqWF&iZy*ZJS^~K0J+GrGG!!e_fSwjjj8S(%Y6})#s@1<+Rk<}2OVQfvwQOv!q zR=2Y8%D(xYWzGG?v`Fg<;kNs9vW=V+t)G{E2#Rh+zr;{aO^yJk2u||4{eWHUDrRlT zeD;Cg%E_$~`+$YV;m{fJ%?k%F-G`n?Z*u{=MG!Hmj)-R81-Q>lkzq7gx~HqgxQg=q zlPbrU@g1*h^*p-A%Ru4QpHItI3TE#})9dwiTxxxlOn|VX$(jrG(uA5WaZ*e!sFO`tgNfQhTB0Fg~qg8-d=3Lehkdd+M|xc zDD#v5z&0=H2kN;WN#$=U z^rj#T$2>}~<~@s}3GuwJ*0303i+SBgE^E>68Sm7#?0rID)s|2vOBt;-5q2?`+!Tl8 zZ~YR(6!_*jbqNN2lAW(Ynp!%Ht0Zt&!S&oPl68yTsj!!dLX`s@J95;|`!gOvcO^d? zb3%151YDod^LcUPS#gnQ+QAIT3t0{o>bE((!HF~U?ht6QTC7HeXk;IF9p-R`p^AEvn#4&dy-YNUj626h|A(X7S^GytdeB(2~{9;PN z-A%w)mCXboLoMyv zDveRfhi+M7bwZq_#niZkA&hHAHOp#qv%G3rQ{rRKE_Ewv2k}d$a?9|5h4kxtd(^~A z7+2~W#m~kbKNl&2>OOd8mU=u^uW_D-7Ua)0?qse6{pJ#mp$+U<)n#r}M?2PE6CKGc z7)e(qdU0&^Tfm1pFt$>SPqNwbMfx0lBriXk2|V~#l~y1*QG?q7l|E`(^gSy`u&Gq zFIKR6=ko5M{1g05%ciMTHOse*YuTcc`Y0mvs0cDZDIDTP;@hKbX9~-DHYP7Ngkx5p zNi(M6L@#!@F;6Y7cRDX{Z}s1iVDRj;s^|$d;YvNolC0@Yo}sY?j|C2Km9?-%z9kO- z`*u>`Fk~4uBYsedVV8 zbmpx7mt{*eF7@VvYm^KL5bKJm+pRF>WE|RBT7@(9Fx~uJ=`E(l^u-+%?K-Yc11Q}8 z)z0;Ysra-OR#y2xg3MUkN+{y%d(kf1c>Bf$Td5A8`OY^b{Sh0>Rwh#G5d}W#uo`;j z_LqStBQ>RMuPt>(hf2Z4wc9jDo2|Q!7F$^~NyZ= zjas7V4unTKXTR%shi3cJJ8Wr+WZ5<3LM=XO z2eEAxptbbqV~plb))sCT5K9-O%=1wA%_|G6KB|2X-C-o&$IspgtenIDF7EL4lFe4D z?QayXrdiP-eN~JY*kvNgdl5f;$K`g>il$o=W`P?(VtF&DKOi+Gx(SQdjG+-AlET4F z%!^BqpP|_SppZHfxj@Ipal~!SB`u5Y34C`Wfb=g+ZiFdfW1yzh^HSOM6H@km{@omw z7}~E#P>(iqRW|OBp1x&N$Y4*G5(kRmUpQjQ@-P2lD*!8+?HzbVxDaE?(iR_gbk049 zwZ36wZGc|Au`2JA&HJ(sOy;grfifRLHqSHjw=VB5^Ok42@=x_m2>3g2W?+!|EGsED zw*)@{&J3*YnNT83_V*ugpI_FqCf57PiXddP@fJm$n{8lCoWC>QY&ILIKgHwC|9>={ zi$Bx-8~+^}3H4QpVY(G{%M_Z^4y34Cta8_q!#WT`&ZpUiR4T_vlEcU;74Dpmn?pIq zoMq1E&2gJyo0;GG{T{!6z+(@O_vdHYUQPPkINIS4uQ`m*Xj&nVq5izbb$6`#kHu;`L|c!Yq)XW0$@5~7a*&T8G9a_ zQ$733ph>++DIdE7&azi2=u!CCKHn{QI8(`Q&B}Vc!pADAZf43mZQAO&Zi0z^8&HNl zn>ZlPeYQ^gqFneor{4Q)+TJBd zQ+d{Blh5HvJW94DgvEN>g<}pEY`JqSks{I|ojFUrx#1!z(9`;y`L|!qQiH8k&Q4lC zb9w=gj+Wa4AU@YuW_Fyq`cPY3C3z%&iDd_`>HVb5604s-RVKBu+*?xVdW~@ko#8!u zB@@Cu?rM?3Oa@RsqrxRXD&ahCTN(co`S>QqTxugzN&?oFQYnOM(&H>wb(9%(2wdAX zqgyYcdiMKnVsZys|Ix7=kivy?yURjr^(KG6hNpRskASw&Yk8{m6$2ypDOaIqqAdc& zqPD>Sz5PA9W9KK^+st=N_W&Y#iesZ{@FtH9_(uq;w^ic?38MLE-VFt-2f9FP_SdH3 zric@6t{0`E%6$@JxM1baP&aFM%S~mLl7WI~>piZ$80dLC`-87FLdk2{S)TbjFC=ci zKWP58qw=>xi^tCE4xO~`g0W`}{!sHtaY_!Mqz^=I7Iq=84|RbnlB-H~UKc?6{v9!( zkKaA%&ibP7gWUbV{T6rhvgTf*l;cRc>^$lKy0%|NhIb8yG7n?tAt7oY$E{D%K^#9` zwwi24Su@YA{+g^~?E^K3VA(B>1q>a)8H#+@-s!Os4LGgxU!!MR^5c6=j= z^oJr97rG(`em?HKuhx<8h%)GP-r>dytV_X*$M}>p1K{1uUR-V8$7Pf+1^8|KtuJf8 zP)I{X?=wNN@j8V|9nnUDAl&-Eb%zLyDQB1Vqo{Z(WJX%~d>a~T83CaNyg-HS#T4rl zLQQ0oEUL@h(?0{1w~}m>oxws;^~@F$fzaSq0LI?h>WU=ed_Cu;E4%z6c%AgoJZZbc zW=+sjXmyNeT3o9=UVn0ENG7bY3?lb#PR?_OQIg5cV&XVMK|^#7d>T^A?*P+aJg|hO>tx^r``o!d82w)I%B`NhuG&-v%x%l=> zzXdPYpFo7VBNkGYY?XO44Ii2|a|usZ3OY3EolZ-QwWBeD_=~-4nNd^RW4MVvJW1X& zctBQZre7t)|8=HMQSmnAOC5tmGYu_gyEremg!MyDAq;0;3AQ^&mE}`Ez19xs>qJyd zWv!N*pdk4jfZmg84v8;%s6tl0RAYctXT@z0h(^LcvsCUixP2fcLIKt>w}Icn!*idJ&#P{+S67<7Uo^>@Z#Ug~AnIkYjNBh(RwneF&vdd+Yo{n`YQ0 zxV+=^2)-b@%X3DZKr|iD#V!|ajEYmWQ+stDQ$_LH+2rwpf?%x|YMCx7O1fdoruYTQ zNHLe)NWgB@z7zEwtvabz4_tqQ`;t?mf^6A9^ z0L|!ZSlC~#pG?ef{vKkTWS_1vuL8IU!r~jOJ!0u|OU^m_4h`~ip@Wwz#@Kg9m)0L` zD=fm2G)D87tQ5V8J1NBZ)cX+_|9f?vG&`8Vrz3GgbR~SQ8Z)6R+A3F8IF&b#d>j&P zJ?@f1$)BT_ys4ALI0uC*zqG+e)L_>t#Dhg=-b@nrhP9V_Ae8P>!>9Bj=sk*KShWv- zw--kuRM?`VEFNZpSOrl`~S@0 z&ZjgViT}zhM8x453)A3-6nk&(eL{Y0qrNE8Bjh0imeZ^VX@Zks^U;+?EXTTSb$tcR zTHv=)wt+TNEk1WXK!56EnT%;TX4OjN)rRZFND6wQBMn0r+J5sGdbR1tXc-jcpS#c` z+^b2#EbA3hHSI=T+IM!PmDi?-u>YALTf*&Ildx%bz12aAeKsiD`j@B-_RY%ubL5Mr z8SGa?U%cf6>sH1no&X9Ev_=0c%n3l|3eQ24oeL;1IZr7wxF4jtp9gmsrQb&E73zjO zQ%mn`UU9Ttu-RC?Yyn%-EXg?P3c75eqU6xYnEyf&sLSs(1mBc}^|B*?mqk_9eylLr zpx&2Xw<`(>Gb3d0zctau!S4!;cN{uRJ#$?*%(h(a8GF`trqS?eo%EbTutJwM$+IZfiZ#dlJzLIAGR z4kUVc&ShI|yf4GI8F5l2SNNV#EOW-YDU~pUj4foRJh7?s&OE&aWRz*uCuy^0^*^%x zkyGn)LCd%C!A~@jL1%WZlZR4JaEGj-bC`bmnIOcjg#$U*=0NkDqhlcRm4(u-i*tc+ z@T@L>p_|A4Dm!PEforUiQrZlvkGt_w2A7+YL|>hQK|y--8*bBY0Hz8|Pr?pIetpt# zFCOQy8%d9P^Hy}yeW(#9+Ts2)xMIz)Oi2aM(UE$?KtE1b!_GG8Ekp^oK&?T+l}mVr zrr*0o0_0Zj5F5149uAk6NvU;Mo)J9T|8-cf5@P5ODq7+(%XRJIVn>-RRXXHR3vN~k z>w5f_xKFKywnJ}3APu7Yi~kO=y%l2}!X@K^QIUS^x8LrPx7#m@Dg^vKmavgZEDHz` zK}~zgJA3!x<|KNGDHaw7NstI5=1NKGhNGcG!O`nV)H!K_h{yeG4Q<<&vV&gjZLynS zBY%S@YWmCIpEnjp^gA6);1eT(lmy?vEV9<~q0Rh^`s1fM%ex(?i#93{Vcs5_BauP1 zqO#`Le+A&W3*wKbI`#QOD<;VOfWngfib7C@WQiVj`R{={4rc}Ee__wx2aNp*`=)Jv zhn3eD>(ZA(*#2&^?|uS5X3nHCT?IYZI_5X-a#=Zc>&w?~O!gc6<`&;??(tLAcAGHf zb+~~;))Gs6sIla)O6>$qHFTgu z3Tv~t{kVhz^57MDZAw=f@EX&kdJu*BD7`*M{OIC23gE5&MR6*SWtEn&Q2@{FRk%WF z8JqR(y2JT}cO^=VIp0LXy@7;z_g{}UIvGcCo=Ku`PkYtOiKs5<^9{(V`c#ExhQYLN z_A$q;Y2O!9)gpcwS=a6J9DOgVVLP&mbbMc;QUe`2`{VJqWbxPv;WdT-a$LX2JMNe$ zU|5B)y{v+9zXfW<>Mh(F6*)0~dVh6yc4a=fxlqL@)4|(cn}mP6(OiY)MXX*_nbYMA z-X!_NqUFb~Sr@t_G|UPAu-jTekzK1RF=@&pG9bE0Kr=GaHlL{D+rIPCfG#b&mRKh3 zwZ^zh45V1dTgel1kY39X)V9dLAynMs+DwBP(dEvdLJccYXX3?>ovqhk35(!FVKDTu zJhM+YxkeW8(fdhGW~3DK)Y2obhP7swzy$*P$F_}6pRAWoW2!*gH1soSse@2zX#H-= zx2uw`p`EIz(UC2!Dk{jF!z|~BM!7iOA~)i=0VN<9aOytZ#++|^5<`vbNGiqgKM5ks zacj9?XB+bJ?fkHJ$o(PRd#iRvTU5inEIB-fb+wIy!o}Gj}7f?pDE8^7~Eb0R3 zE}-N>#M+~6#7Eb{fr}ifVZkT*Ds3VN!lcjxZ`jZO#RU)EL2 zjY-}8hRQiNNrj@zIUQbmc}mJ;p?x+(P6QIvHz;FG8~-gqV6`?0N{H%=obGF5ZOs#gJia%(T{h5(NW=Z#= zVl{9%9@|w$+;m)Zj3wNk1ZpWFh*qpH`|c(q8AssN-9!EK z?4~gWG0&`kShiEC}kQyCkp z?0bX4-5O8mX|{m)4_yoD{89kBN0Y-t&!9jKTOI4E4uNlJ=Y&uQH%Q1e(9Cm?7A6-> z4)%`l7Y7*ros?Ju&oP@*1%1d-+q%GHkUc&W;R=CnA9% z9Tzz73ect3_BK?komVg6){=nh-rfIBZGm3KdacpacONCu$45$(cmKymiUymA#>bw8 z=9mUD+31Up1b50$0PM*M5wcz(+!`*Gx!&==T=!syKWaL2*J(Jwv}#p7#R9>d4C}`m zNYoy2@VocXCGE1cn2>?R^ytGT!aS!1+4HV!;rh_Xd(m#g&Y)C@c^oT; zk6N7TdduCM-XZPpt;lv5+HFmX5V(U3;5DkUvU1Ut-#o1#R(T7sAbqn<4U;K#@A_3L zN6z2$qY+qdrm>2vE|S&2+mv9plJMsr49P>{_p(1DqIqvh=u7Xav_giyZcxL)(^nCl z(^Ha@Sfp2u$_yUa!^51c}_OiM2WeN1zGS-jnP%#_5}HMFk3FJ`+Sf@NL=bFvYXZ#vBpfe= zC(dj0XSMHqboeeCnCH3XLBS89a6_L)>N}Cs(ys3O!Iz{yN0qd%zrys`1MAW9+Qs|s zHy|N_vS|1(0ssie%n>JHI&{Y7BCk_zb9dTmsg*T3#1}e7)Hz+u|1%G>=0QE!0xrEJ z8#i}V;0q^QA8-Lk4UHVgaO!nbfNNTgP%~6|O7_))N(=0`J|TBnCuw7_h6U|W=x!Kg zfEd{Q)qngVBQuxWxs{AS4}0-lKTc5Pv%(mCt&tER+4Yruw!;e-wuE+w1HH`jk+onU z740$>V^Svlikh$CIsJD}B6<7gcfQG({r#By9RDwwzsJYT2z>8}>}Q;-%Iw;~WO*6Z zvL+TdwGleCdmP3f=wRJ!U|932gbtQ!- z$)Vi1xV~ZreS72=l;iy>jCu>Y5}!YC8e$O+Sp|$m*5v>FgCUO zrwdKr=flO zZjW7buEti!OMqWm$k2%_n-x`^NY8OkqXy369D&LmEGSLuZXFu%`je1TvHD^yJZZK2 z1pA{P7tuMzv+uA5IXOo8X z;*Xq6G!yep?HYYU%moCqkI_4jPor}E3#Zs}d`rW$EUCaObnh7ix9>Keyw4-ME1g(! zEfkH4#@A{@^K;1>2u?>ASYEe)cRz(=85mD?BlQgg&Cij37hI5dHzz*${^>ljJ*@8} z4s-1gj9D0;zwN)^81_~Q=BpURmDBRHAG#9tl%;7Lk&ZO!3wZB%OPgQh0* zA5xIJgUkB-XwZOlDAU~{Gj<);g~V6jy=DhyWEmb_nAEYK|K`v8L3|1^a9b8j1938ku@F&7J5mK z4fB;4Z#Pd7ulA>vn*3ElycMNVAx!gLZapOl+S^+|^B4LHrri#Vh(A|v^@a)6$<{r@ zcnf2)(pW9#zX|u7XIIjQv@|gE58aykc$bxIH5{iRW^~JWrre-Pm?67Qmt8UWx3LS{ z7p_q^jD&cs=MHxS=h<2$m^tReLN7P_RnTNY1`)T|yZVE4oE6&wBAt&Ooe zVJ^vbpx&?3iTktK;+dvcoVEb{cxR{n_E}n}9 zL)Pd_uj-voJ9?$ihb~=$qWfez`%OFx)GND-`RSy#Eyusc=Npn|*S9BT=Klo$mb{BMjaPO~n)zwQE3NTJ zmcEx|cbK7xO^vVob8mGCY<#moGsE#(NphK`ls_X=+K`{PKj`K9xy^jk%9AeKD*`Kt zvcWf|dbo;I_MgyCG0rMK+4eM9A;&))OzgJ-O3~YGo~l$eZ6qXmQiKG}PpK!%lLy-> zL^^zL=>y+cvS|j$8_oRGP59JzntXsk;B^q}*>$Adx{K;RLOBu()ILp&K(zDIe7@m- z&-Zix4Qtq2^FlLeRju~rF*kibAb+BH`4{2=&K43)kcTze9tv{8pjCG3J6y?-eA$HBzI#;$^Ny;3bG3 z2sUE@bHi9xKGbBt8yNeU;jpY+&WZMj*p1{2HsJ%?YIh9 zRNQuLctX^TFGFoPa1*+dqQKo>TO%)ogQ{mP0oPrN{YUtV4z?lw9q4;eJPu)>^ASaR zAp>{W`QLX;a6#4D;a!AdaA%(A3nz0q*C@#64QN+eJYPS56Md_k_CKn2HGGe@CZuir z_EQFS-USdW#ttWa4~Nut{*;6?dj3stf_Ag zab@t2c-sz2>J?R{BU?ZUTWm`Wx*V>_(SBsLH(#>x+nJx3*^y4%lD*d-oMl%390041 z6%Bm&>-&JSMv6dLdm6O=VsZq(HsT1M@3(MmjMngHJ%B_GD`~9$IMH6v>&(d8Ual*( z`$j@%8n>iDL;y;TU^-&zkMg~q~mA2{7PkP_W}LP|zZwEe1UqKfod zJ8l{4P0ZCuY56HTP&8&y)c-a3>y5dmC@lumkNc7HR|cp>wStSnOL&sje&SJz07J1j zf5k?jmi^(8YAWrvA&mZWQ7PraD+gvarKv#0Fe%`||F6(Y(}X5Ebpn+wy?!Y1g6_ZG z28U|n8hq7n=?AKXcmH=XZW89Ab)z)ft!&v&5O9BI+HLj@`MIW+>VUcu(=Se`toGSN zbY1wY@<#B|(^7WyvE0=8iY4rxUb^ZCQ019U+O&v<>4D7r$S6=)go`|PIrZH%q-N}D zMU7hH;VcE&R*8?xX%f@T+Dc1DwimpbRB!Zq(fa2t5bEdUvjC-{!Tn~n|Dva@qrx`z z!^&jND;-Kz+H&7RMp4o&uHIo5#IKLOdGXEXe&4Feztit}EC1_!WUC zWb8d$+;#O>rbrnC+FKTUTtZPa%SWEDi_ws>=iUU3ejD;?jbPlj&nnm-GPS9V*Dx$b zW1yKOpl(3a|1#>%{Y_#3Nj{#7|H%tZNFSqIbk7F3ljXa!dKtv9h0MpmqSbJK^1gi& z#1mj(B`jeCJ0$)>~o@zQ#vG*WjXh& zJ|_;pRi@#&C?MREZGoa%^@Ebj1GhMxGYfXLlvmWlEh4DZ0(-l(HOTb2?Q`i3_uo#v zL@Gm(^lvewx0sg$BJI$pkAz@AV+bm_rDM`FILAdr-uQ$(>zQ@nq~Hk|x^OGt=OK^D z*_9#zA^DTbW*^(t-mMEw`R_Er>UflWtgMkxlB56jW}i+E)}2GopM{P@GWuSk7T{OIe$ zlhqziE~+%gYFAFz9)Bet+Ju-J zEp21-1(bGfu+GoeJLis2aB1b392IAX0Lt$m+bk1${H1TtrKvypN;QN3Yw+d^j0|ci>TXBQseLO-m)=hYR$Jm!mUiu}0=B#{>7JID{uqQ_&cE!@cB>;5c-M)CfFP}6c^sVZ}^CcLn! z_6gc}iwwLD{DdeKHGOlxBR{+`$yz{sP;4BmTPiGD{YROz`hHUU*rZA6{rf5YPi~5x zyR2j+neXXwa9#kFa3~i8(~rGstJ~hpRC1N1NPQD$LI57er;#KeDb{VxODTQo!qpLO zWCnJu3O9D|=qU7|1~!d9yH7<;&`6I-&IsO*KAulTlAsp6I6$vWu&(s2-$d#wIfSt8W7%mYHMVtSc5TTrys(Q@^Pi%Nq zkBX$}WX8JtDI0%hJZK5;{%)CeTRXT(Y8cv6MZb_0(g-8w%qSqdUA#K`%C8F20Yp9i zm)7QaztHQ5+h(iCu(?v$*_YIARJA?zvTSTfwnGT3eQw%*{66&VI|URkPg+x|A*Fu) zw7aQ$WP$YY@@av>Ceroql~20SsM=hMawYIxIt{TE)8!PL1&kR}Xr7TK@(3+r6=iUpx85!;RQ>x&B$q%|cG5S7{-4`Ck zbvp{?vQN1mcvRqA___zRenHF2wy>sM{ePJhcA2endfLhx(G4V;8lGBPrJ$icOZt%l zxxFxxafm*Ub9eZF!MVe)Yrv35O@~@1-BWYXW5Jd_KQdqCfL!f+_B*%4+d#>zD4ogpY~E zt4xut1>`=Wdr=kLq>UbQ+O9m2?1%mQ=(?e6>4j}T7#+|B9*u?8|7YqK(T($Y%Wgk; zSc#P^^dC6O`~2=b1wf zB6*~0L(Jkmh?w@iGwzq5n;UkBby;)RJuJJ+$)w2?&B6rZbH^MP<=M5sNA~F9pk-k_ z#5Q9s?Xu=0?3o;L==vz%k`}fm!|0tu{wmtvX#v?{=5@X5w!T~DFTpqLQZlfkDKLI> z%Ie~s^Ufc1Ad`dH0B11wlV#;AnUCATF=qE;1v4UE+ZE*X`TP0ObgmjUHp<&_s3SAR z56D~ei5gw>Vf8MW4SB`>w2m*S z*aiBJc*dkn;}HYZH2!!i>-eMQiQoa5H5}JzAPO8vMtSe%;1C6lAdAvO&*BFBFKcDL;>P;2fDt zYoKdClzgOA6nqneFo7G;Ql&qlMjrwG+iv{*HIUoM>vpM>>6mI(fC;iQO|fSp>6kk0-@ug0!#Y}~XM#N)-L;XJZsK`7kMxpFAGrCVYXudD2T#E6F zQx}y>kfZ_d(}4GC#|EVw2i+gu4zvE|x^&s_-vGmYrugbJMALN1KDVSqC^oX<1gBIx zboQVuB0_TZ|vtP&sv#l_5U0u{XJ)h5IO`#a@>3?9p@r z^m{~tl^XAU7{eZ>-un+I?_W6nlV2`O0m^22PM$%bGIg?uCX?oI_jiKuOF?&3zx-;7 z5Ldw*KXbgNHG} zIzT^ha$FqBEM`~LGN>unceL3Ri#}Z{tUolPok3VqA0+-HD?pSFC!ZZu)j4o6ONaQjn3GCtD$2G?cI>E}FAMDsKaag*# zncf!2haHS$vL!CEX2Ccb?#1mLAt|# zN8~>~w5ybN3|NG5=~nQ;zSb8i4fJkoo=+PXCJJ1YN%weCTXoVZ#r1j6ZF|rdMnK%_ zm#yu~L6-l5$z1jf9}AYZD6@1Ph9OvHh;kW*2eIm;v_)-%{11Sl5VB)V0pyLzP5>8$ zdRz|`;GG00?S@rnZM)5CD{~y6H;sm=WgrV6Gt1Ni83U!8D=a2+93VnM6#FUu9%8 zzWFtt@f4ap8hoki*yYgW#BZ(o`>qo$F5H*tAxhROUjz;MT*(Yle}+hT2WG#MIT~XO zoZSYoAIyD3T##Wu!O0h~sD`8cjCX}x|7&o5=K+NAgOt^m#Xl1Lt3exYooB70nB!4l zOfyvHRt65}@3>1D0f(Kn{tIZ!mYeI*_kXkVDKBisMT2g2qu?u+%**p>Mc>=`Pi~E4 zS=o#*me83TeND6s%A+@3K@W`lu&6(yTcYSUuX~(bGWwKx0)O^~Y$Iy2(_pL3W!T;X z%`O=@%ko537Qoqp#{gE}V-fuZJW$T1b)>!~xAPdS?*ogRl? z4UH~r?DIFY_dUR~+U|%Iq@wrZ~UzT`^-l-ia60$PU{$1>7RKgGWXH?oyXg8=Y zvazh{z32ErXoqCKOW;|wO2ZTF8wW&ghm>VZ|FXLy;t=R2DkkBG0k)eaTru-@j(e^H{Q_F^M|OZ&yQ9dW&kQGy)DSxqtGo$HQ^daezsDgTLz~ zJW!#3e*3Q&QIP5e8qS=#;Ru(&oS9YI%ahHeE+UqbxbM6wzq>^+=Melk&5G24PvFN% z1?9ZePvtyU%8A`Sqkd=YP1W{G8yaCujTEoKB8Z1}no|jrDtCRiC>9&=TNU)Uj~7j1 zM|XjfZ9PJ|1UAF?%@qHH*sm>*9XOiRU(^V3Ov{eb=F=^`p$nSmn&ThX<=tPZcC=CnzkaVf3@I5?gdtVlb#r5MjbKAo1g?{XaOa z=yO)D;w$s7Luc~wP!7$67;hS!-fz#bT6jT$r2adD2(XkQ9I9;>DkX-=7C51cc4PofNte`5IL@oqXZoJ6ldPl5l^ zRAHtdxH*VgUY?5%Qek`!n9&-r{qiM`XB#joUi0hgA}Z}R{Y?rd3B-8|vh}?Kg71L! z6nB^r&>gzS0&{Q#AalN#lZWQ!ZNg1)k&J4856mZ3hy&{kB+ucJuME ztIj~8^o+?nZPBU?;#vB$34OCz<44x@snPZ_X*!}irE`Hv4Vf(lCn{cJuFtm*!wdKaaVFeNB_=~^%UmGb*9vQiceW(9xDm{ zSt=hGiSo-}Ja)th#@e-IC67p1FsMKXH^!dmPVQiBJY`sIO;&5{f)6xYMyA=Rglyhx zQSd6kY<&$%`?3EYYtt~E!ry7VDf~10VA~LmXeS{)LD_XVrcG4)imUS3mNy>43WKwB_g;@U5`)y!d^~^79gr zjXY5O^k3Mf#GBAFk*BA-PgsWk$n#9955L-XD(7lVLU}^7({q4yW=J;?~X2o#X_9TM#Y!bxn4Kp0xe>O15ysFN<0m^Xg&?yuTA4U7P0gB zYP=+IG*u&o$4r#>@>AT~>)GJ-oRIavyiGkvu|m*Qn=9AH!83m5pjGGn<*PgSlt1(S zY~=T2xW+}W;JE_+5mstwX-PD7;uIjO6kNvCAL9*tfmh*M<+C^tgs~LT4 zon13$DoW6jv2(zqZ0AiE_x)BMV3#1M0HM2@XtgLelNN9Qkhd^U3$cSoB3>Ip-ZmsL$5GWKeE4dg@eUL2w9)AX#K8m*uX~W-Jg@I z7-1zEqa$t78L=Dyp0NFxBmBv9K#VU)ubcnS-c=@m`A_i{XR5^yc!*uhx)>qhrB$7$ zKb4b1{P{lo80I)O^Us^-z`qN#-~HG~O2{ICU!U45a((&*yuAUnd+}Pr(% zV+yA$tIgcSTj#IcIHp`BBq*8Is|SB^Gsa5lDG!elc}W6pA;14Xt*^(keP2&C328Ui z^rOE!L#OuYO4gDhph(14#kF+1p7E-4F<(aP$TksggQoUm?XP|8svq7|!~O(LawJ_m zTL4s&%%iU_zP+fGJ{b}>y6>c!A$gR~NzY0yJ94VmwSMkVuM0@z&T%Xxb#q`Q)vcvK zru}Ks*)iW9u+}R9s)HOS6yZNt-FQ$iK)}@Xoj4aiJ|ADKi?|5D^u|2JcQ>eddbMs{ zhN)ndWgFl(Z||j|nOPcIoObDHQ_ET%ZfSvHYydZ-F|IM3SMxM_aoIxP&>SRpY=!-> z;g~ige#;v@0sS`S>ye;iDt0CmCQr;i7Ci<5rb!8B0P~hNN^LL z#nMF*KP^dn3zuB>AY9XB7u+$v;WYUEOZheDoag&G>ym#J3MkoHzuYzh z7WyNn3mfyd2LOzR_zpA^y=cy`lBuSjm6kcoU(dNvU_my|j`a}MOzZX@HMySxSr&&Z zaU9EM4o-bT2D>Awh4z>}bb1$6p)GGzLZ@J!R8Q+O?~MWVtUFkEm2Agoq%Bh7_L;3h zXmzrAjkF&NdK=*-_5xKyHOP_M>shEP5CA{cj9I0YOeuP(O_D?DP2js_k*z_1E4sFP zm!?kZ`@s3~EjCLK1&dJNdZ@jc6dy-aLh1J>zQ|H_W3_ijujyQon+T2p;Cj*yulAcC zsME7f=rT{hpYPIreh=TAl%7Xk>O55d4WyY~vGv0Nb% zIjT1&II_CMaZf0d>b%r3w090+_|3K=4G`A;S`f2=cZ0Iu3a;|+J|aQk`~F9#=FQ!^ zQc9H}fB(+I_on?=cmZ^D6Dponp|)ERJ3*|~0dH;vzi2P;J>O!ICy$|dEEbhFus&E9 z?ZJfpfqUKSE5f_M8pE<(tnZ|?)p6|_IxO4RzxxZkfTqNw(-Fro6~|wP1x(-W30OG= zG>sa1;A_-!cG5XA(f+3#?Z~tmMQuhAG4BCI$vzGKy-)z(DiqN4&b&(wJ6ND-AR}!* zDnW^_j>FU*DJKLvB55V@CPJYX3@@C&d)PMIc2JRSa4+(OPP${9wgt4H2HX&#=Hm8= z1r#jQTHZGQ^g;0G%hfR3hnFrGKXq=55$HpzLJYm-4n`&j_x_+FLCVGn(`C2jG)#7-^Cmc_2VsDpe} zUec+Ee=%9YUoMde8+C#i4-zZ#m?fyjxkH;TyFU`QlRA5+bdiXmwN&GjDx4Tv2t6F8 z>Uh?hBQojQ*T%ckTlp;%w_^S)z8}YLVdr_(j64n|qYf(Jcyl0-)IGOOgT=t-+UX3f zu+VlJnIev4P=u8m_1)H(@0$9_X!D|sQVh>IOoviU%YAp z$0viJ@8z5#J}&s-GjaKi`9g`|>4uTrhx96$jq?1~w^Yq|{N6Fbqy%&EE#76_MeS9l zhnS=X^HJu#;Y@nofNd1xKN#6L(XJ6GBngYK@_elwK@unq2q4yUAr!-`@?Y2xq_f#r z+#fK9U|g?l(vfophD(7-=)E;V;y-QjS!e_5#jw}K{%OaaO;frH^p;{(17^~l1&;7* z1cv5{qtW@PO@(uNS^CfBJ@ubKFG_10ka05~<3rT0 zf_mS3WZDn6ahtxW8C0@!G`)z$=P*MLK>J%u`=fNU_ztJ5Dr{$r%xgzDh)%OBMr|_W z9qr+Jm25;c!*?WO#lDc|3g2AyyBg>FXcfbml~@hE(I0uLGp!3=TMugmH-s?q^$|L} z8$eTkNpy9Fal0^GLo0Le`#M7?oAWIo-bbl~+qgTm-;|9c9A35Y?2Cw>xGcL)Pl1oc zGTCKrZ3QRV_Nt`o{v{V^E$N@3ZJURO*9kV98rTB-D;N9^QCXIo?!Qy**zUz4w z^>34&(vl9fiV6pL{YoI`CmDk7rwIHN8m$UMk53TG_;qCyMMW96V6k=KkBcF#w;4d} z2hr5Xw_RA|_~X{mip@LVwPRLncLXaY#3{RNid!_LNHBWu_3Z*tK^FUQ5Cc{8ey(kp z+ov^|EcH$_BTaByLa?-p^+R93>0;?3<()vuD7LLz5zrLk$SKLli1ZR`N>W+EQ*Az~ zWPL);iPZhrsXub+KtXp^X>J|Mq<;0h!@I@n+MYKsW`hMY?DK&#DC`g)dl)@B3x3y1WGpA#3A>-hO^a3CJ84MO9c>Q4z=s;U`x|NI zz1{sRck3m#h_DjKqBYxhK3%2F^U}%i!K7g6ga5uw@-LbkKG|$rtFt~dbKmL|)b?Ss zlt$a$bfj#&qVZ@+|OJyx?)9nu_QDJF~xvocnP#FURVJ|NKZ&;i$>u$iZq9z1)TT}Tv9(74za zy1|r`jsCto(;X1FPBg=;y-`tgYEEHg9=>=)kRU)ZfV?Q*kJ(_4ZLoP$uK%g=?jDwe zerQDS*>iJ}jg)J4t{Mpq)%l@2GzYtDHg{@U8vFxiZ~OCoE44!+N=sa-_anTj)kC$x z5iw;hBUO)&V)3>TL{@+8>uEl(VI}EvaTBkS{IPTws8vatdU-RCw)+`qT9E`9C`qq~ zg-hgC_%tGBuYOwT;gkqIv)(H>Hb)MK#739Xzf@HWtZJuO z9SA(wK6Gi~(r08v(<8MrVKh@Qz7DVmj#Zw2?O1wMH27b6$5M$#$=rjgwx7Rh{P*er zjH~M#(dO+QTFoRCyNuQ$`D_!L`!{b`kmS7OgVRHvS#aW*{VQj%(}bjz{l^XYQfpb= zu?7C!k4wefp2Z4UqJ;3vgabE^`^)TL!RXXZ!xg*C^@~%R<_UnXUs{apjM2-Ux%KXD zCaK=B&qaBSW{z810e;1hGurmm=T+3t3P#lA@>vbv^%j7Okxd)+E5K-R|F^5!XQBRW z$sGkWwr5kUd{if4YDO~1AJeRi<4JhHi7|c@a=zS@`L;W4<6a1(03B*$LMmgpXPzP( z{g7Ly&HzjLT_g~bU1OQaDf#Dc_hf&!L$pipB=kgOZ+>5hknxlNy;A46DAL3Gr*Bk3 z%#o@w4*hCjv~H<|zW@E6CoLlX4^8jl&*cCAk2{aVDn%Nmx1w??G-o5_keH5=n94DR zoR4!V>XlPb%W;lLLOGvD%Gu_S!yG5aInK;sv)T9RbNl`NhwFMi9*_GG+~dNv9Of1(tKJn47P+JGq~^WcIm3tRWv^@XSqDTDc#+ zQNwV{c#RHzfe2qap&LA$75XWnQoRMmGh8+|Q0GSb`=mKRZXqjdgD&sAZ3DZWNrrd^ zC_%LU>4IW2`D+hur4!nIFKsJ-^Q0Ca(yuS%$V^2(@Z@b>_vERx;S6wee=w#n-~qeU zOgHzG3Y`pI9fT_#49%PJEjg63^80psl)_F-7$vE*m+wP}{PkY5O@>(a7~A(jrP_Pi zl}kFlPUu`X+v=mxO}7U@F0^b1$dZ=?Z@(wdoHo+UJl}A6^SR7xKu|&COIvZ8+xJOP zLRhCcSbeD6PHhUb-bl#{lEuOTES>9=H|mW&PURW%r1fV z=E3D{h`26Q!g(tX5TbCX-)DRrIVq3|8aI z8N%Kbn!GL~;UdG2R8~er=rkyNL(J}cj+_(Z@$%BVB1|AXe=%y*&-|6_-OcR`>i8-} zdbs2pB)M{CAILOs;ei#rsGgyjdrEMV5?N!3wmYu166zV<_=I$kc6p}64;8-7m4}n5 z(&9;>6C+&TIDPbr)#oImGP1EWtc2(h+J(#ZcTk4WjWlC~eU^UF5{Iu?77$q@Tay*2 za_mvufMQb@0-Hw?ILHx;h7-*_h)HU#mmt9@PrpOtlefIKKo_)(Myn8co&ycmovp zoDQzALN-;~4){O}RwSIzFR|lKH^M8Bu4nV%k0OAjXR+EWai0iYR9RVJ1J4xOlRFgm zDvK8z5t6NUNSRw}mcjkitD}OuAAOt1_;GxG=v-6;C3~UBhx0XE1V%ZBWt8TbB7K_O zvX72a9;Li9hVL)+gufos=twNQ9ma+QxVpU5)0_p|rM2_1494u2GwMxFs1p4C#L?3<8y`7oCDZz(*?4YxK8Hk1-X6Q$cn1yiXSXy9L z;=N|oV3;ruq-ugGH{>F)|E?$6C@Q0i1KMeqACR4n8?+cq2Wl;ucaCMS%X9kM>3BT; zyD_bE#ORoomu%sIVsB{OgO72`M>d8E{5~S81-|~B(7J9v6#4*qjK@m(vCG<^Evl)J zwMbYQ`{az7caz~)b{O;+FN+9K%b2w&BbNpFuyVYseuQuaZ2LlFn_o(kl*T%hph#F2 z&vb>E+Rp*M;B|#?tBr*mjH5{5VW}>PBWzX>r|P>R!NSicyj;=n*jwx9E5uc65UO2&PXu-I8dd z(gj`?o}p4UZV?#&3?KfcWmKpwOkjq!v3E4=$awYfm(IrkNu!K%>fa}y6Qvr|tok<( znFMxd+}t3FhyIg0oZcyu7^ep<@se0{pPMYKL0zCYGSAb;Kmh;62=y^g>*UFW9~>t; zq%TCbVbls<(Ghac3{VG&7^4*N}l~qx!8Xdm{agdI^0d`!>;}Dx! zxsgiF=1lZKiLt%p-O!-rqJuz#j`rjr*~>G}p!4N=)sbK9>hI2Q_WRZvi{JxIJe(c( zoqTlGo!Ukxl^a!YU03)O;5NYpP}EdbIQyG(ZAy_8{I8JV9Osmie0T49wjGMHQtTGy8XLKP z8{^qL5^i-dx>SpH-68@W{5$U|h$4O4=ix$1jquhDnO%YRA&XBOG7f?MHd$BFst3<( z^nlo!#;xo**)Hl{M(;-MrjvXWw}Xs?t;NCNLD-6mkaSS)ja2GZ$CC%n{t<&IA3jFk zo7T^5?)oosO8?2zCwEY1>54Pdk~xvbVQvp3ImGypqh4Ln>cN9tt|*=tW9&Yv^QSpT zXOF(tXeQ`S9XinBXR60hOW!B`D%Q`h&8F8!DUq*;SBaREQMF0We?GZ(Zi?g*MJrGa zb3F<`G>xuQC|5prxdWn9_k2Z#LYCsbj<_@DK=K{3^9G2v$Wbt)%Jc~`_|yD>_0OpC zY#`fKp`|kO4H2YAiTt7ewdt?CUClbNDRgw;cVeM;*5l?x)c;&$Ivp%SE)C^guX7RN z^k5J?W}3+Pi6%+HiWHuQQb^HI*|G6#!}Ri zV}9a_;1L{!$ta3*d+Z*y@^!M$L6bWS`| z@nJ+zc@6LB#;lD61WzZA*VaouyNs!};j4B_p+TyO8pLzZcBS|^SaxOI?|l7AkTFjZ z&zEh?zVcuMBXMvzy}Q4hQ6RI&vb;`6}m|e%-qTIs9cEN zu#L5`PhMXQK(bb>j4A&~=v^E!>d!N?ybr(SJREOSZRUYWwpgON%ptsbAyUiq$+u|E z#N8FRa<8>}wIpx9(NNF|XKT$1WJ9mn=U+oqhz}mUnlLDZz(+G(VHN(d-s>_f8N*1Llm+vK=MC zhIJ^E8AVzzbS(RYL=%)%HlmJd+KQHvl8lh>iU#bN+WE5vK?``LbS)<6U{j=wA^2!K zL8=N{y&9iqWmo6Bh`&*mrzg>4@VO3~a|%IILLLzLspolUjLl0rbl=60>Fu%aW?^^$ zkg#u8J@FB`f72LFUkr8JH$%V8)YGT2ue>+w+izwb=Q(0haT<3C8j^Ol4$S$~Yb~OjIvo)-fvn8WBh)^SG9cg5&6r4>* ztPK=`EQv>&4g9kt20P1j^XHC-3y*HMYa-hpbhdfwHh;5<4{+If0@PY9=Nu0kC3BSM zYw0K32G1pCX8(?j1e(|%FPCUNUee7Y9S`pu4CfK=_Hqyn?Glsz*PT__Y)_#*R+lC zr4mk17V+#&EXc{xJhw@}AwvDE8p&pIeT`{sh2m))CjA`v$?M%MbWUPVD{0MQ@&o1p zhkztPI@KOBHe6zt02k+bC$by8=a6g0jg{LvN|8Mo^@r>&iYgxMKFvcGIN3RrAZwDP zaOGGUElt0#K6W#oi#P{wdUz|%{fK_xsVT0X*KLTz(u%XFq-ok&a`#PaPx|$czr(+V zL`<@t^Ms&yuAWVmt0teudU01)?+q?YeBVy_{3aEydIOAI>BZs&Fv0531Oi*~{)4bz z^Fu$0T)jULxG$a#h-H)X30I{;sGBE!aLP@N^BgDI`R%#tbBKe~M(tv`^{SUlL$&dJ zaWsNB zcuI(^iMXr{-K55$e97MfcmLE;17C8#goForB|1^-J}N=Kcy4tYQwc139kqM*25}Wt z7D=l|+f6iw*eXbrACnx6t;pN;`HW!vt(hl_g`T$=@Mu7s*c|_bc5e}D;mx&zn980{ieu5uueU}=vbr6pR(Myh5Kh-DsP)YqoxrGoc9>CWA{1FLAv#36)vNOR)b+t z)oQsPzELOmRS;((Gp_Cnh`3_>c;aR*W+le$ajJDJ%~iukrIIJfsD))5 z?i;%Dg}ynd=MpP7?xQ{2OdZ2jR~HQ%C8@Gq(WaOY>xmX8no}bsNANwaLd~ypSgv-z zj0KDOMt0}v<4~7ST`$qCPjp(KJAvQ)Fl8HDq?mZNM?v=^p{E%%8X98ImEXMk!fDql z7J0_<<1JsHsS)__E_#YYW`2q#_Ff)=WnEQj0TKKqiw|!B5pw$?Iy)R6;-x*qPIHr% zaPAJ9HOK$3w_X;j+BN=AUFF0&w598LNQ{DMoMHFj2Zx*C9jW2%( zZK0YFEpD=}=_5UOjR)7ToCj`wvL75m%YFw^ThQGnsVliKi)V${w}^f_G}Y+=r)~w9qh3*&p-1(kF0M^YL52_ zp6|$d42zntFk5}bnv_lX!B23J;QO0A72@?0N0WW8{&ou?>$&{h3~ca8q$t{0Ewe30 zrzMeAl0m(+n!~{vz{0ne!6*^0{BSRZjVur40Z~wF9&P`%SnYhF$f&N%b?jf*JjpOl zyPX>wa~Cd^*`O?xrP*{an6d<+pA0^S{Q<%T2FiKLc>n{WjspOU7_@Hh)t!D0#!-rLu z==Y)Q6(kGMlm49TKgNp#WXHv8m3;^5Ccsmz(#aZ+BUj=&Ty3HW=d2!SHIH<>FQ8oIhSooYf?juoeod77V!z^ zL=MGg8(vu7v0m_c+YdP}*wI0L@i8O6>m6s8dXl-rywAt&mtfRFfp$u&WNu@f4pX#L zHp<*rF-hUv4E1BCJj6gEAlf2fJc1t{E4;|*EmeEds+8l7$dSnM{VQ)wKWDJ?L%G5! z2(|-kYc=_(Y`yGB*;ohOt`)s0*>W|IB%a$T+67`Dds6gzRD4y3sFeodr)J&OO<{kx zh#IdQhYWy=DvZxwlhvNc?EDs%Bj792K|3m!t!w}iIVTbbNs+bC?|)$5a(%RTQ(Ifx zYRzxMDvv@{UDeT2MN+q($#h;HjVj~)g#MDyT+05^5t9H;NZuXDA6as*eqNJkd+5n| zy2k(h8C}9|wnUO0xAF#h|==-;Y@5iY2IQ4KJJaxL;TJQ?@ zR&11@m*T&^UE<8}gnF;-k!x5lCd=IyC)Is(d+#D`*k1zJ)CNsj;GcMDR5s3443JDu zx|M};A#xs;U>+p6wM&qAT>Ctg$#k>gfC{(J55;YXp$rZgA>wu^a z+*suFKgX+TqLP6Zc{Z*zBv7JjqDl32Gs9QT#PRH^$aOBA!C};4w&HL+A#&aXE;q{V ztM@fWknd^_-ENL#*?dV){)7cC{M|cGP-;tku0(K}OZq0=7j)oIJXndn@+YUXeC2nU ziZN%P#4`VQTJ$>t0JffDO1fyLcs@=vIiX&NLDVsr*;t;?s9tMTMTO78kk{;; z(W^n*h&8c%EGm2+#50Kl)N+ZS>R=fYU7r*nTV6(nGzKx)f+tB)jj`MIap-BIV2|lW|~$Q(3KB=i;2+>Cyt*J{St%C)M?ha z?Rm5w2qMMIP3{9_b~XA^sHDd=ilg1!uFJj~eQ$A0Gq&x{Pf}t@Bj7wc<5~U?iUmmf z+j`n&0b7~PfEcnyi7iyA_bXx~GhkAWW{>`f96xr$%DSAWaHX{R_3rW90K0#4)vm8RPCMKS_o8w8lg*JyK<_u{8n|;+VT$vTnQ*$y;`Me; zPZ;&$UDV03XYXqx}2@`wP#X#JyY`$2}1BKs&p zC%53SCr^%Zw7Io^lm#TkWuUJ*j1*%isTDo(4qXtv@!<({?N{UL#K?&@4JJk?E=cB! z|ECE)y+-Z%o^;3e%JJrui@Ggt&9ULDTho<0_OjSJnfn<#Agc%`%ivH7Yg*q?uIc#o znZQ4A4(q(LQ#t6`pJAU=f%o6tn^>ETm^)@ethUjCULMLc=Ppf32T<4G-+=5UMopB6t)o>}sR)`av6 zLo;{pbU^q?JU+e|`EoqBQf_@S$7=*SddGeE@R1w!zuBW2U9u=wV zpKUA^)Z;a&C*=GcT^t;a^){=FZNI#fgdpN(YMp4ddacqTNiZBeq|kf zEn820uP&)kSTp}wY~86P#W|O=&<$b$l$eXf>X|FKUsltHNyjXm%Nn{(O}{5t-aq%x zQjqWpC8F$aB-d5uv8yztYugPPyeY;*sZ4wGQqEc7^}K+zb#Lz8*t5h;A|U!;fl8Mz z)rh@>BD+VO80r4hl@N%5X!V4E6Lsy?!D7B-8C(0mI4+az!i3P=>l51gsJZ$|BEnTU zTLQw>?J859JJl#~)@!&u%DcO=-v@_99et@zT4FZs+5TASzxu;Jyb1fXcq6oVXANZ* zvEM9j3Sy~E($Ck1?yjAAnDaK;{oJsuaVpfctu7O?8F#m;NUsPg=n{ObvgLC*{rHiw zV#$hkC-0@=sk+P3{THO2lcgT&?CFDMR3GGd0}kzv*`V_~1k=~zrNO>|$MECVwTYLn15dmEOUS*MtIUG7 zx>pX#N>IhfSwQ9UK?=YSqo!FK0pPIR#ouveQ2d-RCmMNk^}5orLUEmW9+mCDWPuPU2mF`7bPo>IJ4tptZ(iL0p_OaS_x zxV+n1HpSo(V+Ff82?7;_+8)RmJzt@4waGkFK3d=QhhuO7=1fd16gyqIQ>psYdVXZ02frYSs0YivaRC!B*6(M!fQ`4O_1BYFeN% z;cC{+iN%`Z`BR}>gZ0L^v>E>AG8ZJs1+XqOiEmKSV08Zb@n<5fjjiEUKgRHCKzb z8q}jY+m+}J{>1R*_B{n4QzwAWiy&>A7QI>XRUN9GUj2}0 z_AL6nZCY7K!&F+ifBM0x@o}NPL1%RThgjs&q0H+{%FtoM%?Yv_>?qyYzYRGe$!&MaR zhxI#Ocz;ajR@Z-i*;SK(ACy>03-!+CGLaQ+St^>Q#O&O+5IG`pRph!KrCjV#B2Wap zw_F$C@A<>=+LN3;`gwh)D{drCStN5N!;7euz=z{~2^G1xY5DxZ#?{%MXv@R$1M_ zM}}k0hRi-o5%Ejyv9Bq&@+|G;i~;J6UKyW>o6A1TwH7KS%UdTOfrDy zW68hv<6&-(G=9z|xZBL9*UvfR z5>!%Wg?sV)Vg&#RGy-E?L|-NGOBuerwNO%@t_tn`So$qO`@k4%3obJe^BVQwdf>3o z_Wp@9oP^L>_ThTLsMGs0lUEoX{#OKhn(+&X`aB&fZ6jsfnZ{NDo5A#ckGB9CfnVPY zc|OkzQu6lx87&O)i_!a^c9M1T#PV11E7`x5x_&B^7{<*}E0gQ${kIq6{J*hgGyJ|b z9?Z+*cH_W~X~^B|+lSuHTZz*d=diHJLoqWN1&oY6p#FXKG1c~YgC@zsbAD@HkKTAn zE=kaeVH$I4uaxbBeN4;IsTU?oU8^{L9XoO^jBhxmT4jvCQhEP7A9nV~*zu{7RZGw5?6-?Y$xrl> zC9u&qiIc{zIhG63x6UTo9=Vyfl#E(4vfe%cX<}l4!>A~9zuLEXI*ck%%N_u{vi*fZ zH^Di7J3h{BW{5Es9pU8HQb05|KbQDW{g3qKhD_sL~hr$BQu$x`&hdatk%@QKI;D;2Ok&b`y zPVIb-yTZ^jUK&8|4d?u)prpiVHHg7tAnfKi|MTdmjP83Qx{p;m1!pqQO`|IzGIwx? zlvub9vp}!)!B6d>*wL^KJKw+7;z-XezAW@cTH{*O%wODcg`Y|7A8ew_tXwuIwvl#= zy?6w6VPFUpS5hIdq6WPi&}TDoaT2820YO)Rt$WRAo>+xSqc4(MZ|q?I&5ZlVgQS)P zzJMno0T${}F3|2mT}X{lZ9S zRS?M~!iD2Y7H7+~O;tb)dwO}`k>nnvgX2QdbA5MCbx^hwvveR9J{jl*rZ_)!pt|Z) zyE0%=DcG&zXe3$g_;YP$^2FU3*dLuDnTJld?`hwIX(rcI>{_-rwU%*Orrp5A3oKeq|jF%m~*!-xPP-&%l@bT zu8_-;0{(ZW$*R-}nsnNR8+deZ%k`b~muIb{c%|gl{jXEy;GG0e!YEtv#v-s{Eq_8w zjvJ&e7!M5TQS(PVh_BW3Znk9NPM)Ty1+sonDC z_tsM1V$@egC*9c7K7@^M!2xVd05G7Svh!OUc=swEhC%=}~dT z-O0a~#uXG;;uSA0XjLdshPacko9{~DJR4gr$RpRbF`_H&XLl5K$N5hHtL3l&WuAW} zwmSs`);CTI@zmolrx_(la}tLO6YJbj@}8e1`&Qwb-C-<0JLvf?+Xh#&JtAO~bR`?7 zX+j$^)T5}b`Cr%UPHbR0lz26D>;VDV5UENNT{&@dTs!SxHlt@Vpu~e(ft|i5gY?&2 zDwNrw+|Tm$7ex#%$b-tV|Ev2cF?KFGqCuU~3-R|KQIARigPT8all8OIY9%Yody-|p zli|qz)jmNcf32H3_In*L?w416^n?mooh#c{m|y)mm05$zLb#|U2Xe;Id9zZ7Q!Oco zGV;fx05*)|if2^Shkk1LEX3>WvGe8Vr-|M$o!;OSDaCYEX1O0fT*y5x(Cs~rCQu5C zdT%B^>P4V+V-m7-Tnp53e>`XxNfx`AzhR5<(*9c9p&U}){x8+_G9*8wb8j>S8FkV)V|Z>jUEhM zNq_f$iMDu8fb;lp3Q5WSZ|BN5EWGV%k_1JLF>?RV5X1hfjj|ksqyl;fDE~%?$+KSpwU-C@&Nuu@|IvOXLn`b_G@@&I_Kp!eLRs5HIB38C zS+9E8InX=E24DojUD29zC0RaPfImt9HM z*|ydU4Wiu5Fqkxgb|R@ZOfmRktAq+cqhEk| z+l2V0lr=3fyX8Ba6yk1unb5F;h4{tnL7KN(U!WIL3ki+hb-JKI2y@6rod9P~wlD{O zPQ*uTFJWp#F{T<}67v-v%QH>xJXNoQf{ALB2mJ<-Qs9Q;`F#{2kY2==;6nv7>;y6J zIj2*r9F~x}{y)fR{*Tb0(Wq{l%OOJ_n*xs@bUCja=0{k|vReQDEP&zO*x-pnWt83} z0=z{ov8=Mz(AYj(?#<XZE9qj6@;C^aJP5GD3E>%k7-ytD3gfhvjl_{?A3aZ^o=V ze!UrnpB1X9_tMtp08*x$S-p=rPs`KITJIhX)(oR^mzHX3-8{8S+as4-;Gh~JH=y*D z&mVQyJrMie?VnT#2a@WZ=Vakd@_#XJmP#M^nh_FMVYc1F^*ImJz)9ixU?Ose?} zIV=l!02XGh_C!@jDXiTg*;>j?cAs-rs|i||)16*UvOUw#=gcd?D-{{hAophA-zmd06 z|NOQxq%W-Z0%df(qOHaUA0D#7nMS4~_6rRE^LH%pg4V!9|D-;_g=j#^J~+?$D%m2x z7dbX}z?YP(k_jHJ>TK&=$q$?Q#k&!zDxWkv5WFG3v5Qq&1p`k`2Y@pt|(LqsPEq z^Kr3jR^t0jvj$k0tNY|!-z1Umd{{28x)$v6pPJ9Q4gI$~GiQ0aR^!0Vj*LIY>2Zeb z57yt}CA>C=Tx({U@thtw9kJI5+aK{JwYO~af`~YT&3gp2|Fb80TgJILM4;9tmYKK7 z%93Bt4LwHKQk<$1y0mL9c9`A?G4uNBHmRDh3Tl8DfNce8!c*#Fh#Ul@vlfjB%@wm{xZ{*t9 z`P2g#vQMlRN7K|>yAV+tjjPlfL5~Cg{peH-)JE?I!ERs7hfj}lrj#r#{$7SSD6boE zVZz7~!1lP^dG!u^3f1U+l=iteD?9q~Pxt|M5UnV|&D%QmyV-6&xL>mF7o_oczPleO zt{v^{m}0E0Kw7tc=3^nQ#I{{M?Bb?WxbU7bt`R@c7T)i}Y%%r> z<*#cb_7wIDy#BnJy17!=K+Pa?;DkqM`#nGvlYE2!AC+PiH#ODNtB*g^eGj8$_of5zi`g6+2vP> zs3?B)mTXqm%YHQ9FIZHk9J0 zo&(FO7pS2sc&BbbWu5Rv>GbP|69DeH+UP*iYk?R5L3n$q6JjiGhzaq~M1w@Qy<|LY z1pk9>m&(Qs3E65^oI+Thu~PgqC4cvzxPfd{(*i@vVH(z=ZsThC>TzP|$^5NLnuyt$rcoii#^SN@7X_cuP7 zRDe^-3hA$qX)@o*^FmJ#TDSv{f~E?Jl>)LE@FvkXFj+ILARue| zAmwv>;o)5&J&3{l|7P-fWbZ)?XeXy&4#*%!+tDJBx^C~nUohN#AV#FYK^2haAS82) zYrM8W+eZB*f*TINXH}7ae5@DgPtXkj4{QONaBlu~=v-2r*d*+P-r-ha;)})?eNF<0 zO~+p@eK3NR_olapA7RG?!f1l8sk@;el3H15@hC(1;cz5^?ZjU_kb5b5_`H zUF5;^_MWtA>4N59p)ZqTpQB+dGC`A6DuLbk$GX${ua?SzGbAa!O*VULjlwEeL6_BX-hA&EB|>CiKnWm)l>;1p1$O{~gb z-|Zu{$sbBuoFzJyJ_s(|%G-Shu-Di!t{rvPNV+4$V22a65Xo^kXmpHKtU6cH*Uz!7 zS?|-ZmD8>T4b^UJrobwb6P_k7l%y^(9y^rb{fA; z?Cz^9-3$I5nKoZY>dsd9c9Kr+K~}r2uDhcD_$mhHM91+ngNfrm@6%Q!@Iq zz{@wK2uaO`8kh3p4%eQ@yq*(AE_oS?cyM^)wdw~8QZ4!am&$+SVUW3m;=<8S4lW#T zt^5#Y^0`%9WRhL6i&vhU_@sLI5_ji@RvmNVFFsJB+0WnLdds!ACDhala>>u@B^30X*eEL83^g_He zqWeBPloF7wS%aaCpF(aezA;C|X31T|KF-=GL2dCS26yS5ZYIM!me>iGz6#WvHoPfB zxKc5`@aPc6Lcp>P%PhGtGgH1$mx>Yn2rFlSZlQWTxj4-|S1z!t%2-ob5ChcoFK`+` zA>9b{%CBv4`nGwPT8Np;+qav#olA50nS+*of$7q{_-t)aq>>5OGOg&wq4-8~h|q(S z-A9DP%1r;?X6wDMNjI~gwO`4BS=nmM)GOOuw}^@kVm`qO8It4I`tuOo-@!Yf)JV2U zg3bQI=ksvKo6wBFSa2siDljPqTdE< z1jM~GWUW=V=6r=dEAWlx9reYdIl^wH@3hH=ydMiCd<-~E0& zVk|T<%&CKU&R)HHHC7)!u)FUN68maD#?UM77DKXOl1Qw(38sn6kU_R&#=FMBHhFW) zSGH$5*fa#&m*?Pv$k@s6R}Xs;waIU1BCYC#b$$vK>LjggH)X%0bA=t*;Fsp)#Qh`U z^RUVHLw@?*(>JtF4h0ClxI(B63=e1oU~<>MQ^G2mot6!RLkqgK$L`thrh0Rykj~L3 zBoQYBNz^_XU#_Z$(#)tG`JU7npUn0btC<94U`Ui|X4m}f9i}T|N#m;mdk+77R@Gbd zzhtg;EMl=@dFvlRS=z{X__3zZ(f!t$fXZ2>fD*G93%wo?j<2vt&zNqgMeF7Cc z$37qkR-*6@&MWU*gPQDSjt%m4lMI`=o5m${!B-tIi&gHtNZ5uHa{As7+V?FekdaT6 z>{;wBDA3af+3jPkVd~G}jkS8=gsD8G@K&Xep=ZLikPznH+X}w|&{MmIYy8t8A8Qgx zk&qT`Y!^_h*0uzT2B$gCjrR_yp2#lbxFsQnb${f6wwk1|s^Ibr#Ib4+^|I=P2u z?YjMV`nNoxZt%uwqwi9kPohaRXu)A$khhRTsSlEmW`(_oQG-^Xv%}su|E%&)P3F0O{kq4 z{U`i>k{8&b9ZJFb&Zdz)%7)M4KHc$%wJ)mo7$U3K1!fJf7hY5A3@eQi!~J82J&=_7UJJ?_5D1;m?Jup2I|cqQitmQp zUH*Y+8(!?zw3xle-H{V%)66QFdGVWZ^sjQ0@0{MKw*(i9RS*;!8Br`rt-k=vA?cfc zy5%dhpQSYIH)#b*&@^okk5QI$jkx@dGXF~MtHvD>gXHrfw)mZ#*k;%Mt#!M%Co6A7 zeenbK|6MSYu4#rp{SZ>r#ov&&qu&pw9_(qh>}{QFlzX_gP| zk5oR){}flA<9nBgCx1e7HhysQq`5^(cjiJLW`Fu}5nNNasUV>Q2v$TDc>k+-;rn;A z3eCId@0%$5DC!Gr-Ti+q>dAp&$BC*0E} z^jf++%x&WlqqWXw^*ZBG6{`PnPxbQOEI{5vsynamzx8(|y7bjuyL8K0G~FBdMGEa4 zsJLY8qn%rXyg77;XVmC*$?~w7g|V;xi+8GipLwpQw`Mne;=2l7*x-f%m^A?jXR2Wp z!Mby`fFv)e&&hz2n&s_&BzsN@hacyg>6QoRBHy@Tu5{5)SsHT6jZtrz7orc$p>C6n4;Fi(9SoY9$;xBso4hiN87gnWkdr9#Vr*sCt& zkpzKI3TArxUbP{MZsLiLjRh3?gM!4G;DL|&+78dgO(wQ5T%`8VSSY&fL!bEmF899k zYpF?=`hOhn=~;3i#Pgww`{^^EY`As{JpA?Mnx|K-(Y3T6K@wv3u43#l9E9$o4yB=Y zl?>b6uSdnl7XIa)#OW2z{4i^UhYFq%kRpS8SK`mHr0l5p%J(AEz8DMb;%6R(*r4}W z$m5~v*awL^O_2_zrqhhIofUVbLZNR$?%vj7*|DO~7^!eF{0#56UPpQgO?Bc_M%RtR zh(_|K(7|-V87tm9eeuhm;#*K61itp?7%*}RLn+8Bbt|(*kM3s&1jf%TJ|18H7XtZk zj}&P>rlI`ZbuM47VmPtA_8~g|6=qUex3>LlwPDZcmhiBhVx;8ZEnS3Za-W9uh4^Z; z{)V`+crvHmp0J~nZSHxO9;Iyz!*07LGc!|l6TR2a5oj;@)V+VNN?@vm+-O&Z816BY zYpS=XX_xYU+DNZ}A5<6&)n?BW%e9nEEpNXwmJ-)9V!Tz}!Ck6}2RXXqug8W;2W`!7 zy9yGojO-A#=Mp#ye<0FVdd7P+N@srbXk!48M~_>?z~{H>FO+N_v9uZuMjg0eFF9<> zL)I4~K`eur>RXG{%7j$1c~L4<|U|5 z!=I&o7$yl5MiLVWtO(lM|8lgRN)rOsWBu`4xPyP#&)H&?&8X zj%MvlM26BMCvL-wOL9M$yJ|m+yei+|{`iKOO-mnktmX3VJnm;9>L*dNe#5yr}-Sj^(Wa)7Vx0-~$-Rd!4_t#n#kTCe6(QFTV*mkunaFN+&mwqrd_SdZU zE|5EroTV^tj7{Y9flI5K=mmwU(rLW@S1R?I<%*+$c|(b@qUgp)idrc@=nvV*ptX*61URTymI*-zSRL-`FySC z{Dgdgn9tGEpQalc1)e;OtS&Ut^sKE89N^I0eNn+QF(yQ{I{f76zuy0{KVM1-kGr8M z2i@?BScv+C-$%w^S!=Sa@TW$LEotu0Q#rQdwij)4pF~ zx`KM^4zml1pQ>i_dgd+rZ$Vm%bO8@x-dx;BuQ7ro@Y+>d7?GgRra%CkwQwG}W&@Qsc?;1Ku z^A^N_QaK>yGkW`7bUUnx6#CFw*5DyF_~WkN9`_8#D>;> z@H=hA3mton_IO;?SrX>dFmGej|NIC?3?b-qw3WBXoZysTAmyy6ArtdEivz5!_W20U zSkf#`;gpc^=)g8LJ}7m z?YdY}Z6Mb$tK8Ktx0KF%mWuI8x@&7}d0>=Bi_Q$#lKeKknx{r2Yc}=2iS{UPvkC^e z8)PR=je`C~1_$u)EI{uiuKgNY@p;IIh)CFdhS|E8-UiM+jx&~IlcL{-CB;h~;Rv2E zv@aDxmRpHJRc#x!B2>0Y3FM)*JMhbx9ch7vmjtGM#BoVl{|zMamxvCf4|HZAFMZqy zHvrc0)yE*|-B#_Bgg}SKcRJdxEM5y03rIccEPD8W}L0*}h_i`0wFs#7@Za+3V% z{0LGz%HBFN(*^4(@Sq3!^jWyy`y}{7WR-hPp{|lQyhRC>l06JiYRKw1zF<|wy(*j= zZ7izgUA2lQEJ08sZL=$&#m(a4_pb2uwQuY#HG-iVj*)UO-@TV@j^xd6y3&q30~r&@ zT8=9@DJ^3I{&pQqi1_9ez1(_MGTRsimQFIwerGXo!sR6MSvV6O+|KCh-lrLx~8Ua?=ibluqO?*9&Yb7k7}kF!hQ(S$6|d^UXU*zRSiCD5wiI z8sLj(pBj9yHZ%5BxprwnXUx!fy?2ptj`FVJQ6R#?rO$Kt)pMf}TV z-VLN}gdZT;m?stO_apDst6_&ncLZARdB+NF4tRgI*)^=G5T-eXO`f3wAwoFh_-6QN zwJOQFZ$EVSpHJ&2t_^0qDlrnobCfK5Oo-U-T6tkJza!GG4bI9;;0Fo85&7{--cUZ8 zbG62S8Kb~C^tqh>PvmKRYN1SfJiU87)BpefkA+IC@{Tl2DJrKz&fCbV)Jv>h9hB4R$cyI%Q}+?7W}mpW0H zk$}h8cvOg)k$Iju@3=VcKNLd%=aSyC;uQTA99nA#mbaJL-Q3Xg_;S$WMtk2ge_Km_ zLFMC86~0|J$)aX_?sT96sEY4Tf_(yK<;m@YFSpQ+7pwzf)8gEMCM=1R^jJUcrNaw$ zHePF18nx5GZWQA|+e3Xqe;9l+E&gmsN2}$pm?C8P)@rVXKjTmPV#B%j1pdwCjvqD& zyY{f_B8C6Rn)wKzdmA9SAD;y>W&W?*Ehn5Je#9Fqt4O7ObkI6ga>sQ5>FbF4vOx8knxn;Wi!417uM z)%3@hW2_drDktAQ4j1jvwijIAW>|IZ=RMgY*%lX1Fhxv~Op?eVPW$H4t6n=-V*660 zUtMb$$`J^^Tif}{KgUMM_uKy^V@aqjJ`lpoc71X3wz1{O&V^^hA*uant&l;_GAq>5-Jx;_qa87E zZTR(i+owpoZ-;c<+82+OY(~b*iHB=JjL4mhxn@sp%Os}GkKfWK9jB8HE~b-ew#LOz zFwc{r+o;C{21FaFz&%wb{Ey*8Y^~Rk>3~UQz~HAzw??-zMoI2nQHcXHLxF=wHh2Ao zmnWWt^*p^gcYe;Lu~__blP=)5K(3qLSf9`%1doX~10$99^(G`ZLV9fv!~e#%E~LpV z*C0s+15G9S>r(W9?_xs=rUKcd|Eahkk%k4gV) zRou_{6M3u%BD~;Gu_i)d{AiZOM$+^cc+oY4vy3-1pX>Or9~Ve+W4(PAzg-qQ8R8lS zamo8(r!(7Zh1HaG7p&Ymdn}3@uE-fL&^2e{!lkw~1PSZKbvK6M!9k3p#AaC&?-;v} zQM9dPeqz_v84rz)nZqA{{C|aEP$EOKK(ya^OK#SMpvR!^^aAtHR^Je zJ&~lbkRL=2E={Mhquc)1`x0YDj(Nhn!_#+i&7sMJBxPPdDl?9DN5-kM!|K@m8^jxJ zgHHY#v{|lmaH2Jo z-+wv@?rZ~BY@XsPAR_FYb_|Qh(F+=7iZ&?{IP^d`$isEqjP+SYEO?E7#6>vEJ3TuQ zOGp`M_vrZb;RXKXaGL@9eS1}`0!wx=wJ*Loha@`K6Zz}y^PD0}ebSs2?78$hBXcWw zFX3VT>{IE>VzBo}FS~;wkBT1-<(i%O8y&CX0<=VA!2N)gX<(-#QvS z5Brt0>>BX(7l-~UznH*@lragw@36|oTmy#a%)&>;_8&EH5b9b7-hq^fljRJrKNoHj6a;B zPD00E1Fpzrc@>Q7c}5Uwe;q0IY>Th<{s3oobEPwxF9w@$oV0IyYgv2=Y&$p~Nvt2< zT1oyf=!Z44i!zX-M~T^G#rZ}F^N$(*xcG9dg27y9AL2C#=n|MLZ$~rM4`{+Mlu@0y ze+p4RjcMAfd}%+p6a@W81^pgu&vrB26M$}fCysj$ZvBcWA6D}22YQ3!>3`yJiaIYp z0qT9eLXommD|X3Z*Au$@*DYwKvlj+h^ITcSeh1(HCZ3k}m&^11H+<|SzRlT z-4q+MB9@~y>}4A-Xsb$D>w&)ahbd3V-oR`!!sKNI`HzA{0wuLf1b2>~yx~puwL1Kq z*=Y$})KUQW2A`h1;EqHh?-h$P%aSx#M^eSHC~-VLFNY(v=p6ezHX#w$HRw>Cj2#r% z8dsa49{b+!$>i48ox<> zNYV22>?e%mhsq*JIh!P%qMvlpy?BhX%> zZE)7IpT}3Z(s1bNiO>4Xya}R4c~;qnGUMxgj5Arm6z6S4AYuQ9)}g9GL*7r2PPS}~ z_gM$w#9z6$z=y3^_EFKJ#9(%J-8tR)uxOwO{~kL@33e>1TH>JLLJUw6rTrxdID?U{ z?&{m&uSsE2I9Gl~=c(iImL)4j4#^jFSBaU;|3@&Xt4qGO1KeB9PC>LrJ^#?~(7MFp_wSE^Yx&vP3jkM0mxwdZx*?2vv!aB0f8M0tPL%l|31b! z7l+yi7O8vO-*~niu?id?cZY|R!MUB2D!4Btv;LTW;i3Zeg8HGPB2w?^rEyT^AG2jB zgT&=?>a=BB$01RI?aWgxuQ!OLT5ir$C28h3BdbUsg}8dG%dSQs!s;|1%CX^KArj4J<@hrd{LX4 zOfH`{gFlN3Dek~;+ShB%DoWyLcgjcq9MF>bVDpczc9~+@5`~;5+nEpL8XF|ENo@D7 zzxPsy!2}A8i*{r`uD|-eXsoR7e&j)p=+l+XC(4Dr0ff5Q}JEJS@>K;P05U#mL_ICsCvmr6F>+dr&Y~=4Z>JmKdjyA|* zclw{kUpgp;*pVuYE?4#Bl*$G7xkts{-{tX-V}LygJ0rJXD`gVdTkbbQa>sH56?In) zDJFKv%5f37PkAs$#raQw;-Xs{yDNj_?JF){6nAVXd@`AGiPm(QR#v;^ky*E>^`#{| zLMHU1#V7uz{cZqU$0JAHdi8E}90?sZTP>>QhXhG?^@&2~^UPVxv3~moM}JCE;>3f4 zmmKJCXMXY}-)8PbJ9?8nhy~DLr`eaqBvBxiR;`~1HO}K|)%+p)Q^u)`uUULPN}bCx zN6)v%11wI8I|=Z1UX*K2I;Cr3G>mQJcpvV0I3|gMcVwLSaDgMRgk|VB|J}wyRz`rs zBcg0`2N0)#RU-_PDHhf16!j|4hH{n?W7RqLf)}l9^MIJfNH}^pQCgjpr-kIiHHQV` z)qj9ySD5(y^azhZwd%5CbW6{!bh+km^^dFnQtx;b)>ZH4hqJ<9o&ST)e^#u{F$Fd- z$Sz1xex4uG^q|_!m44al#2ES4XY?nZJ9e7-#=$bWc`!aDJN(@9__?X7Nhw_U9&#J5 z`_eP3DPDSnAuQyZQNkTOt6=u)LhE>FpEfnm9iT3&|A;1X)KXGCBJtQqlcumam*;h8 zpTP4mah>LHzec>nYcP~GhaWpH2kFb)))6dw>XT{I)#ha>Ysnp%pCVrTnn}N><2w)$ ze&4&{NZs61P31x+>j}tJ(qOP{Fj-eW#5e7c8*IsBr@a>^0Hb-A1DO#_Yvc5Oa`2zj zt|Fv?gI{0QK(3Lil%4zFkugW@+H`bda{%MHP(<9_kNiUE{5Rr=#Gow0?)RtY+tHCq z&Qh&iSMeC{$Sw9qCZARKz^Q=PpD+Ajm(NJLUn5cTROfaELQbb_x60kzpkHKS=^fAp ziu_xs%X6;aN6OA}55JBg+Lucxp+q_r*JJZ}OD{sap=DemIc#bFt2dc*M0BZZq?Wr`%6!$F|wMD2KH$AvJBX!lG$erPo z;h-BEIX^zCQoFyRH<95=xrt>NmdNp17Sh1o$e$`kZ6zhzB!TjyQQ96IQn3K3HL1ao zC{z92wdz|RTBWPG5+9e8Rk*pgq~)=3hYKnk_0oPqdnmjAPpJco=c2VjXM``#7ho{e z#3gOS$?vxw(%+Cq9!h=A+stjG>Ye*sBvAH7P{$W8579N1m{BDd8p9?0dl%lx2n!`{WrC zpY?xz3IcFsdpDB1cQeL~5HBUFH=Cv9Le)rvAKP0h0tRM}W0OpSoaDM1Ul4>U%H85R zqvS+bhTG<-ZDH?rN%?-oq^!6qRoq`ckM}PArChc0hh0!Z+4HloD<4b?QCIAqC2UR) zQTWjaz3wEDdQFD(roJ4slA%hp)w%cin`pA&CPS=(VJv{Dd2!jxQ+bd6>B@BI#;Ax6 zcTl$LDu7-fF`bro7MGD5E~8Ob3bAD!DMp}ary$Hk3p+IZj0I}^{JHUW0rzm;IX+Z7 zx96N(C(HH5M0fSj>~>3*mj`uXvU9>^*{=S=WN5TH*m@L#dPki&gH6ARj){7yvaHSC zeEPd_R<)FHj+<}^V$eLVknYpYDOlQ&3pO-FRg@=cn&^oTE=}|ISGRG8d-c4@B97yC zz-nSE_i{BE!2=R?h8LC74O}7~w=GEqn$I1T-=Pg>tAX0fz`-T4Q$cWzvLyqeYol;7}*q=3_v} zKf1nym$)h7K--C45mn9<#S9S!Ea>`lo-7!T+BjYj%+WZIQ(IzCzsE2K`4|@`o=oP1 zm_2*sfz$ze6HC}iOe%aL0qkml9n1kCUPb-NBsr#F-TNU3_Lty&Fr@mkS!kGQR}Z@1 z5^B^F<(mS&1LOdxDuv%S=B+_8?Q+ZH*nD<_VwPAKEWxwAcL}`V?DsyVEXh~yUE?=k z|M?J;?og~ePhu(GJRl*iOzZcS;43x6;wO~=fkkt%_*jKKv+&vpaU9D9Fe=067_s$r zZmN@tfE=d5ue*L4$Z}Iym_6f1LGb^#FAWvJ)oXm=Cn##AtYK0a?b1i*I%H*uT2anf zfy+NL_3JX^^7N_H;SsA*K6KSm@-lf|=W?3DTV57=qZCsLt*IV(fwFH4yyH-pP?XjWj7 zYjAFjyYcv{p-TM-?d~9g^!}3f##h7&KzJ`Ht*+BDD#Z^DXPwWq2t>j0gU&`PIxikd zZ|;W$eDfIeBR!TnShsstdhhSgjnNwHWc(LQ<$Dgh@BcCoT9CmTnL}Hd-IIndWsu~L zvIS!6zwxbS(YvmK%R6t8)$qfzOGc~qq)H6o`LWX-cw|KTjdSa5%W=g#(4CLEo|_0I z<{T{#FFe_ll;=3o2&TV2X{#%?Os=S9FEC*y(I;#g6l-j6hZR*lzVB?axr2olmc1}g z!k7CL9#(mp{&9$h{zi^v?H829>)X}oZ1l*_nMPPV0*6A6T&7G^uG-23x#%@f*X={2 zLeTTXc=T7Ot%A|w2soy;K!qB-EJirsb4)FeX4(UdHUEJ*3PS@|9#{B=jJ`qAula!9EOtsq5N)D~?ri;4fy6C9_pG%ULEwJ<~5u|hzXNcCjMvh8FXz}g83d(n@Js3#)vn~Zq_g7dQltB)9J zL1&l5iYD%~x@I$tKw_VVAAr0DqJRY`vnQnn^e_>bx#$9v>try!sgti2kJ-#s0r58H z?^tT*QuGbbm*D;*_(EH50=djW9W|dJIHNXqR}P)bpMV~LD9B~48EYlzf^$`d9!!{! zRc6irs~DZ?otHGG7p8B_bZmW(%@xEXbU%Z*eapk|C~=%aJJz7JjS(|)fm3xWE;~bA zxnjsHf~ma0;Cw#;O`No_-y89J0_Vse4saLc>B?2}Uvkn!43+S`o%_(4+;3yAD~y6K zM(;Bjg-{uKw|%k|Jcv)H5~W_@)BkR}7*E|f;ljAnU9_LYN2`Fc$0frl|52%JMDtP= zdj^(Pz7>V%H7c8Zc&GozPR0nu$Sz$rEa>KGZ0YY3Z%gSv%n zqvSnpl!hDHM)q}vM~?6@@V+chTD+t4ya_^zBVx$ehS5Aw^?4aEL!exuaqc~lH9EQo^2yw`)5pZbh0TV62#++Gk7(Es` z5=XOu-7(|$8Y|RB%P+hxWr1h*}&1LOLA8{{X5@T@!5OjKb z;}tbXgD4)g(?pf;;r(OdrP6)RP(FEFo>^>IniD}5K&)O_Gr+D`S?^Cp$7z@M&&#X( z|BL6Y^m1?2m*_t35u4*90xCCccwX&g;ve}*%Hg>)b7Pa&#&yT(if=T$X}FV1uDWPe zpdZoS_9@$zDUVs14_`Y(Zb7-BhFv!gz4XpUUbw}0S?afVA?tsq5-!*aNv&T{c&Tu^ z=m86UD)(~0=U;+}Gl?^*VZygaiTS_mVP}qAJRdn5Og12vC`X6BUzfYM?g*oPhqze; zO&Doy-+Q+98^J#i#0x_>oMB>l`mSQgOcYQ)zva@o*=2snvl-Sr`0gS3&=zX$Kj@6)Q})Iwx5RLMwOyc1^xHt!bqlNynu_c)lXpd3_9(Yv zvyzxs0q~9c*4!#M(4_~j9sE)k^gseq{+D5bM7y}>PiDB%8!y&;=HzwWyr4ILywFU2 zrmx-F98nPaWKYih;+T64U>th*8TexVsgw1j6UjuSP7Gm_`M9q1nS|@2|6>i75I=Ds z_!Y+aWOp#Sb=MR?4iCX=FXiTe(E`_3rQdx!6f+JlO_I3*c$V?V%{tPG2z;J$yT>HC?(GgTp&>Ok)@2&ymg_<1e{Y~ zc@{{26u&v*#hW3?1C$|GqhQAI?Dmr4MFCd4mCwxpWkfI@OelD;vO-Q2k@zae6F5BD zgD@O-Q@lKDJi||~xy%~~j&0ryi*tXyVVu=G)HwEH^}wDHik=3sW@%vc_5AJbWW;^1zf zL~Zy(h;~B0RYEB1yZxwScD}=Lv!J;j5-I*$x)H3_^XA{NYUDR@aQ9eyoHU z>5V8|?`{nN`ixT0htL#?R*`zXD}+gb+X%9!nhGeC*eo$i3wk-H?gKF&ypwCWqMt?! zCuFJu_D^xn!BT{~DwnDHb=67o5Og>3M~_p>2!FCkLQ5(+QHHe6?HKyOP9vI_m-8^? zahvw{WzK&!;+QNkl+~aeucgo5NnQMI1a0j_GcL^t!|tea76Us)f#+J!XsAzgb*re= zCacRgg!ImNvv47ucSLFb?w@>@gP^t6Xuv}M0XO7@51)c~7OM4nzX=2m)>G+CV=wP+ zc)B48jAxv1cOuRiy8!tgBPkO(#83lc$01PFdl{BM#$|+WKasi6B(5C1kYbWw>fM9s z%EK;>s|$E`lbKl&e6LAmgn*IDJfN=1z9lga{enxG_Os%qDnsUu#Xf^GpJ@1Dg9h?| zyU}e%Tj7dOWNp`&u$fVl8u7jX{lwfU+D@WhNJL}k>8#_103ir3sJD_F?{OIE2*Rsq=xHajxNoC3p;$L-c zj@G<8aQH|Pm5wKCWhhv8y~~-cWnT^L)|F*YvV`I*yc z-8BnqOklj#9_uJswH_^fU!nsr7!~5WB$=vf%@lC$66*$%V^p|)e9)~5>LjTcKojIW z!Y%_ovfJYK-`82yE+p0&hx)EXbopN)+Bd7MV-@uF{XU07v>SBwruP%q4@9(VG7oY_ zGbx4>M?Xcb9a%T18+)xMlaf$0l1PahS~z1%yzBj`Eh`V8TX|%``1NskB`V9{ zN%X3{>t>ll5J-Xh^fR}_L8v|-GZ?PPd>apRMSl>zPuso}&-dBNnxHYo%~w1M@2|0d zLf%1=Z%gi4GQWVd`)^5lxp?2E`F_E>+w6B;O4qKWk>4u4h#N1E4}`yJg6sG%6V?YB ziN9G(gn~IU$)gZ{qYQ8GKhge-wM@y6v6WGV!Si6@J$6I@Yvnp;;a1}6AY_8|b*96t z9GxhC8PLD=Qfu;pIjiFe%!rLA-+ZrE+Cj0$1W5B%Wz>9H%}Q7cNJ5Jfm6_B0;5^=I z?_Wdhnx;e^B+2yIQcH7QU8yd!cSkConUu1b+-?7AA=k`YW-bU+@#Q-)iJtk~AP3BC zI#t;Y3TBz-tq&di?UA=?hIK+3Y^rP#NRIzb=fc>zRx^IS19^4dgJTMZA_rcj8?C6> zo=~1z5JDOe7OFaH;RN=P<6+9SiVKTiG0+Go)bQA(mfYj`&cBZ0hl*Lt8yCbR233oX zY&+lgak;EJ_Ex)i{8d$TL)r@s_T2ZQ$g@N#J=cc|I}buUgzh$PSHB2oWdJO9_=w3> zjhwquR^-Uem9&Er^BuD%J}A&x^VH<^YzGPsuNL^;)T3$e zg}7G2Xd$|w?>7xf#(oWJa5^b!uyZt0DjhX~YmFy0Y@bLuLzEw2WFAh0v)SXRL?62m zh;^rxT%!sU(nM5mO+w7rL1z9g)eovpPUHL~akOSH1CnTNI5s-hDk*19mg;x6J<|k+ z&ff!i-nZraI!#)U!IcUJHC^I=LnpOE><1rf-f1UN*L5+GY>9fNBdcdOS(^Ii>veex z#&|sy{jd(nW~2iDz%9IgX1%xImPc;_69Mzk!^=Qe-JCGNZe9uQ5FS8<@`D}Yion_L zy6lx7vq%4mqWA6JQT9%ZJ@`{s{!aSFGkI=R7>eD0f|{Ysdo_)RkFx}5MI1hRU4hrWk2*{^2I-q}Du~q+%x%1~41os%(81hYP z%)|5d8B;u0G5s1nJhCM#!a4Zo^Os8d>O}Z9NW27h#Va_<>|kyOH@#eLTJF#;1$x@` zzI$GVBvkhV;>=3!j(Q&-n$>Eb(U(%Vf9_5y%w@=@zA(IR9n1(x_RA%66@$a$32bAR z8(VjQI-{RQRRvVF1=x?yEyq55rn4bV<8i@UCg4zq_m&NBK)q+oUX-I&(vaS#| z`^{ks0=5Ma0$eQw<9HxyAx(ldL zE`c|F!@3%%7t%Es1_TMyC65D4;vIX+&Au$fGtsxqKS0w#9ToW6W+45987sfSW$><% z`VAxWpTv=F)ji{CZg?T4E5b#|YroAeA{-80)fGbp9FU*sy@tcbzUTYq0lUopv(|I}Ak_{X)S)Di;5nhFIzbOY+9MOL{ zIlUQR2*k_*+JV5;`~IoVb$UF^o}SAPF^18DcpT~$h8_Wyg|Ww9l}H4g*EbmQpq`td z->N{80^Yg_{P0Uv!Ui_jWkwooWA8Hrf#`+=zoX^+dis9hVfA)4Fw}*6jTrtiqW7EN zwsFr31_g(0VC2{D=STU)>RMG3?^0?7yPn@xvTWhAd0?CT-vj)M6NO_(UDwOLf!F<+ zNM4?{3LUZ9nBw#W&QuL$ZfZ-(&A(Fq$Xb$r1IG_Ii(&=%SW*@|5V~6wA1ino-W4uG z>}-N;`ow2SDqEf~8&f!kaCwC|+S1Edye5znK>%M=7ComxnEPxM5Jdbvh3xnuKc1@{ zb{kJ!jYUf8Wq5t*{chr{-^PdvMZL;6Ch0Mo*I<+waEWaD$cJVVIi%N3e2AB+hXF? z*~-O^$`cX$e?%BHty*9MzSX)0VrA1v-mkQHuUuHFnQ?QPCLF$HB8ciG75dNC3WxNj z!XxACjmzD$#~v;jXO})dkf^)$#ea}w1;t#>w{;TBe9rH~2Unvx?zXPA>LfmcEURR$ zmR2nD2ew*}Z;(6S9E70{H2!}U0AKqUv>g1;P~LKetsD{gY%@gb3T9iSueJBQ{_j}+ zxKZw3W!PV&4UNvL;JE}9je7Hs)b+TGiM`+axA_9E)Zb~@-i7{RmR>M^ta?9L7K^qU z_^@#VywaF6UDUl-e|Qk#8E^#xo#&fJ2zw-I0=f1sik({+JZ^VZTDpEBRcv-~XtNYx z6t*8ppO?0y(fX zr5G<{*lFj&6jy(?kqrB*|N(GDf(~lhXGe#7P{Xwa=t9-r8H0sQvG6 z6hUB|mZLHGc`l>Y$o7|E4AvHJbL;i&-hWp}4x~}?QCrDxLQ)PUa;0T0HNJ|kDE9;7 z7L1*8bT8mxXkfYPyj3~&1}P;`N}Q7$;ep}oNq(_HuX&|NBMvXdBA8`}-(`l%miu^2 zDLd2Y{%FbmhspH1XNO+$%>NwY&Gp~wlLJ%rtLP^S(5FR~wq=2lAxl>Z?$5|L%i#kI z&Mh#kWVkggGJ(muR0R-(Cdx8(pF#WKm!d{#4~eJa(!Ts2|H7bE@m_&h1Myf?3`_!g ztr4V76M%XRWt8;&w8@9rL{mS?zS?tf44qGchq0X{XyI3?IgY5Pv%$P z>upzf^_e&u$5u&>X#6Y4F;+XgzFBVb+OjyyeAA(QRR464I^+uZrXwTe2|_>~f9rhc z8*qRwaG)X~$6P)j2JVCTB?@CV8n#P^{)=#JRE^f-O694_^uR~()mrjdKgd63b4B-W z<5k--y|`^&vdp(pX6Hze1J6O5lw*+ez||PczDpg-DUf5crl3D3>@trO>oR-zF+>4( z(u=?l=gVSuk%})kl5vDW&o|DffqVD`=3xs%qqlG+DU_)JAD{lD%*saw1862t5Bzlc zo}1`|>9*`rzZULQl*YIEMcs_2`{sU54qy^${-qYzWk4Ki;xY9!Z>C=hTzC)DN1kZ> zPndK*J@!uzS$Rxnl!o>viVQ4wGT9NVuE~6`?8|;952evTb@QOxXJ<#Wc>RKOGJ`M@ zedCJ3B5+Bvwfk}<*M$5LUmi$%J_ zyT?+VWA+NQJ|F+2bOkkG}s92zWem%7;lNVIOe^Zr}f?$C{@Zu4=q;IbmsLE$U%Bbj6^y zDUH4C#alk*tF-#ZQt$n>dypE*foyz7!U369?xYSnmO%30^ zV~E(kfzXmwinAv5yN4a*ztJr^SZ&EX3dyNK>goA1^9XX~y!D=of$ z5oqKca0_mf(B3LCcjIW?hKCo3nV9lWu@J?5_UKi5lH1J|d%Z|^q>2@5AhCS(;9d8e z$Ac(|Sw>voI(G+gxbxwUEM2@7Xa3R9CA0p&Gm>^PuIfcB(!a~Um!5S8+KU0CQ2lNR z%370A(HKYZ!eU6Y3iPAsvH1p2gI3KWgc42Zxop~?^L|%?*qf-R%tjM@hK0_}f_hGR zy$tBAl&K!oQ9&`Y$h7*AmsFGfy@h$cxzALT_k1)`*fn@qYNhlTk<|55(z5LCF$0%s zRg~|mfd)xqX|=G|%-ou>x_gd0$`jM=d|R>kl(4C2S7M^%7@wbBx49;wRy`bb$!g#H zOXToNhXgqsKUL@Au+D_=Q6LK^v5wT2tpWUt31{hXJP^0-+&b`0T<^Ez8@+U6Q9q6))d(JR8p`x-Yq`-dsC2wuR3-|kJsZ)+p#cB=L`{$YR?8Cp4lrTyq zI{;=X*p3N6_ix82A4pH)sD`up>w|y4*SjB7%Cd3{>5q`tp2*bsiinQ8MvC;#GE)jo z)=~dsOU)~&J1ehOM$x$P>Xv?Oq8OQ$P0E?up#$Xv=bymcugFy+@fZv(JR*k8v$H=qsCd7O8mdc!IS z8a2ZbECffq4Jy!nBOC<~of$BbzGE)G=T5X;U|;5n1atY9|L8o-CEAWAM;Nz+M68?> zQ(d7;vv0Kt7rTO(D47uUA1khb%BjM|(~%#hTd!7jp2U(BYOS*t0ta#eJO}=?xj1xc z9RXl{++>-r)&?{OY=dND=C^3XGJSu%-J|xeH5#wr^5qS)Lwi&NGdgCijnNhJGKx-C z#WCOID9%r9ZNF8$y;kFX*+tSA(vv0ePx~q|_eIasSy>8#SzBs|?-dTN$=~ifomSOTN#c@eJ$!+dfCG$%gQ4nZvH`AEBr~IME-}v5}Bpu zOxY%vKli=^Mc4bL5a|vo%OWmG79U9}-zlw~QKn}uh6HDu`Y(*@Z4oqFN!Rlp;<)Ax zM3OONsMQv+Fa)$+HG>Q++05>bX2aJmqmIq>emZ_a zpk^2cS$_cp`7N>gzN{ivgf|x$i_dC*c5ma${^#cq;Og06HO3RnU~c!832vX%9Q;xK z23OsHWAUfKMs5{@wD(35Jo;XTOT_;qXn4EwzD~2owIyOi#o=Sz+S#nSmE_P8N&j}s z?>R2G)kk){oMch={N1ni;iNVhXfCf?5VrF*vxt8<(w);kKwSGF(x(?uUu8JDmHP&y zj%~Mq7sUQKhOiyl$;pY$s?`p?ObL*-s_$Q4>sjsh6*=)-%IIEo2J>1&`n8p_OIPX} zC0L}5laRG*;y(@U14s|=s4I7!(=P0ME5JflZ?5$x{Sf?U+VFrWawMv?^L_-$;)LYq zh%l4JSA$2E)P`Q#T1IxB43>QxWwdzS;rvTa{rfacNWU`A4lS*554tCNG#a;Zz~Q@+ zD|Hj+w6Bn9?w^n^k}@3KvaicDkC%9xleMN+yKUgIUu3oWl2OG)r-Dn3+d9jh-r^JH zZNQypfs2~xk~5P0z;O1G=KSK3ZZT!E6KdM})jCoq)@c$Dc9Tq~QNwwHTvqO8hl7cP znxu8#PB}MqmTv^4x(Tg(Bl6em6OM~5(cL~~z#on#S~GKRzznI5mAIk1{JxF~(q1O+ z^c3HidO7N?-N$?6xEmxwO89KaZyBQs<1exG^Wt7-1KxV!HT9j{7pMHla>YgbkLQ#~ ziRq6MCzS#ZV)q^Jj)NlZN1r7;B(8MoYW%|Xj!ijG;{vNGzM4Bv%zwi|eo0Q{XVe^w zA*BofQkVM-+(I2*Z}=>ZUjhwC>1`9)TkyDtg@*^7w}|F41}h`8wU!>qqs#pPT3?eC z@ET$lq!A?bWuUVquZZIiereikw)9jzF*ZwP&t!8XrS}Ir&1apuhaKKR!fI+h+&^sH z9sewBEcq;5+2sc(uw4~JOPVJT z3`Xnj-0kR07qRufY#hzjdl&xz^|z_fZKlQwi^l24Oi*+2BJ#gr81;bh%6A35!IEhc zf+YIoJTjn+x)R&5MkAukxkEHlqmZ9>`;-@e$6{|SQ1_3+(YXVV4ogUhIYrNq4ETl8U*idk4JvekaR%sz z69?A}d97@h0n#-mn)nOSVYUsY#+jEAS)($2e2rM91u|&^)V&M1qh1>0I&lLRKAW}4 zRvQR|y?ISt>G5Th{A)z!qnXB?z5EHg`P+9 z_O7($;-ui6R55VmW@%Z4>b5*q37i1@!u63IM){)||8Xrqp$?gu+ZGRuXHS{Y-jt=Sxp-V)G%?{j6U59ZNBZe>| zA}4VjAF|}0p2d@mKF5j$EG$S5EX9b%rg@SV=)&}z`bY59zMEIAT`1=Bd{m<~!g(1asNotpRiA9tGyOP_i7_}7f5t(Iu(Tx?H6{rnZ5XIg2U$1QJBHgH6<|kur z;gyfliPKbdvB8W>#Xg!6LM~0+;Y9+LP_cL^u@e`({f_8MN=>P)d`OllH8$`iLOYLq zZiE@?DOt<9Nkk@XDoKc3v5fVVg()BO`@NqD>!6(oM9)hkZ{L&H6KPh#-txoHR;nc?YtrejzC@)VH~a06*S|U8 z7j zjrW9y@UrW(er(rz^z`FS0Z3eCI;MUiyLS8TN;toY z%B62{-43chzdFc{;TYf+S8(T*Ev#VZ5(N+%hBf+Z8dNH{(am1ISQ`-7ZYU2HQ)MPi zpOLRjUSpp4j5qt}(|hD#nh!;A5#?U@2qR}%teLaLZ$>+{8DPR!dk<3MDvhCa;Rb(M zS-$-zkbA8f!e68nY99Y(GcgJwu1xZ$gYAFU+%m(8f&QkfB0`t)oxH{!$S$a|qXjeU zk~X2}mmaq_5HH;-TBanNLkc|lh0|~J{S4js5$ohLAu4B2|29IbAGlll{!csG${3px zXe%SW)ORBc>^PMT_b3p5aFE+-O{rvXB?2oceX)JEy4XI_z(myJS*e>0I!$a0a1E)( z>3hmYt}8_a55o`m_`tQVg@Ltxq1#i-UfYC_nY9^;1&p^nEmgl8P+>FcZY6c7{=E6v z55K-=SY7|(^RDC3A!xPYZE5?%{jqrLN8lYi#+O&@Go^GARHo3YRD!@Df@yzlzwTC= zyva-!pLo+0A=c5YKK{wnm49dAg!ldkqMu>mS+47+@b_GVcEFb8)@ak_lJer|j0d=7 z2%VPRd!9Cc8JQ~MX->_XHbXK-B+o5Lnju#EF4X9!_Ns565`DTbd;31ADd_2oRKrj( zf@>Z;ygZy;7I$$7Q@Fg>Sceegs36WX(ozwxuX9IRD6YmM9G`x=$bq0Vsc<-NX*hxX7aPEk;JfLY#hvhi%kZW-VJuMihCxo<0nTZL4)V8nAP zYj5g}!=GvFZ_3!rl>vQ7BbqW&)a0|UnoHATWUI9n8exf8o}Jg zr&-iga>GzjG#JN{d!%w~`NnCRjuXouHaA9O4ie~=_1X}iSVqMI4^ z^E%Q!HR>_bC{wXN%=WpqB#h&8X~z&wHv+08p(MVVq}5@GofE}AFG~6yCz%3`l;W+c zjnDbNt?!H-13!(c80>J)>AtxN=FNlSI^P{TE58t3l9e%}U>WJ2-78z4PkHsW5htRl ze@T<56uy!pOBlOiT*S*7_$f3w-eIutlWz+9Syma!h3(? zeplc^SY#>6O2Y>Wjh$2Dq394LH=j=b(Bnh=?95GwkU`I~YTWpT0R%JF{b`q(SBd=m zzlWcHqg0@_<6Z|#Yly>%>%3pzwc`Mxi+k9uy*S=q2#G)=>=GI_)U{Yrjymh>J(I9&4&3TIcydNUMtdb<9tXsvK(m zsImX$BatcEaff_?E!`z>Rg?JD*ZuDTGX?|+_jWRsI%LIjyJvsb&VoQc_t)BDR^-22 z`~AQ7L7Vte{bHF()jMnT*0NeqTP$Zn!;TbH|5thzd1A)G%eNJb^m_0SM{}%2hQ|AF z|GN$2eZM|>!PBeb*CK)!Twm`HbIBL zHbd0*n3j4KPrHu)aX6?^JMs;BEyS2Fx16IUYSf&hrpc?@%yiYQ7cXtML~pW>YlPCw z+bjRMejoPlp)r*akK;ZSAa0x{C`>s5nl^KDAEL%{>*_g05f|70LTu7MT{pwIo+km0 za^#pj=$!i4?HKjY6^&kTw&^lN=YMlrV-+hu>K6+qe~vBpzd@dF(3MG!FsxC51P}Jg z$U)J2HM1q`7d0R_oqgdBDH!T*Y|jmBg&p+I2J+F+@d13`A*E7t+=)`{yMU}YX$56Z zZSVD%vJm`5`TRuXZjU;V-J&cJQWVtG-ij}#RbC7B{**4uprqLqpF!EPo227{;`Pw{ zp0Ok?uS61!G}hoYsm+Neq{Est7~>;U*dZt9;I0;8Q8Eo|Ggsl6Bi9#@MrgUDk+BfT z_Fe+L9s1Jyune&Mm)x2Aow=3!{k9>O8Mc}Ez0c?O{SVA|zMjv=HPv=etbUivlEeC^&arID zg7NF+zk*b%%CcoKjjiDVp4RC52FE~`PIWQ<$L|xp7Zh%4xQ~w>Z1-5@91w z@8|ER+q9IfT6@1!bhdKcJYO33#d0oL7|R@9OXD-mt5f45%e)GY5yWRG)HG)velgT} zseVJ$G(ZHhqQ`2#e=Vt?+nX0t%hF@%T@{Yqdtq-5iC^P89^{LQ(FeVDj3C_Vy#gUZ zXzjhAr{j!Y0I#)>nZnN!pU*Pe5|-$*`Pa7IN>z2pN7D>iHg~*Y9pgU|Y9aHdzmWGb@EaBX;Sd z$RL=^r%Yh*t29`$&v{4?oz$r6V)r7)t{ThMsQ(rMg%WH&8!HK(ANbiGnwZoSGw3e| z7C$w)7+yUgJ`x$|?C=_?ngwZ4koh4vprutamTexGaCYYkho}&nwxLD!pRw#H<`I@X zR~S#dqGgh2Wj4&4#I>Emtyo~t^!FUq5(>M1&V+eCV-YDI$i0&udO-hO@fEihCl&Ev;iNM^qI0g$FMj;ciclnO5)M=v;iA6xK0%8`i z7Kb{k82X?x(nVO#AKcKpCzR{vPB$Wp#1b=^Z)fKd`8ah7Oc@_5+e2;8`O!+6X3;-S zHs7E`i94^en6dp&$BV2rA7|+NFmm&D63i&KppIzNAzMMVY8^hQDnfmuu}m_TDZGV< z8~S|IyPm5V>$NZ1Pi`+5RQF98kW(XefXllUngt})TY#;K= zXrU$YAr(vCY2}G|gU5jvB(bq*Gd>jLo$UE8!uBPEg)wgY|peGVGyzkYY zhugvq$Y9ST#yIA9{Ha_%toASG+Qn?ev&%8@@WT#Jpc_hIwBV~L$as~VVF}VB%R{G* zAD;9O@A;J?nDWrjEik|(JX6>Y!0Hk7*!I{enr!`DAgc#YnDB)}^>_N1lHgy32096d z_J+bbJtF^cGd?zL{Vng4lqaDYj)&EqI$jl#t2)VFnIq5WijbKo*zd1u{dPMM!q&}m z4%o>lQ|7WMZ(R|R>a6K^QR}Vjt{>E@p0*2&Q}Edk`vM?U4g;k|Le+T%KUS^BX1KW3 z?KiCI78d%4o~j$eX&+4x#P@vR#Q3>9F`(2Vf64Eo!$-e-Mablk{HC#6AStu3Rh?|5 zMas-oUCUfnh(1cGJW}lMNZPzDvS;rOTHZ7GMk5b_^f+KA{uy`^z$1u6tM794@*XMMQdjt8#(tr4(%b1EFE&YqMBDQ02}24nkVv4AtIYU*E5B%L3VJ zzu+Xs;i%P91MQ*@0nFf}4rQS`W#{K*!*nUu)ln<|>+{SuQ%2iUZ=BXJ`L7K&Wripx zEud2L%wR-Ae3JgI5uRcsT_KQL6x9@YTKwgmov|2U37ig4H`3%9;nu7ZovpW+i3DP{ zGk;w7Y>AMuYRGaJ;W|!{C68d$SuZlXr5aj^9p^d86o^GWghq*uyb+7pH$l{nN6WbQf2UY|wo94_XeCp5yRhRCYVz{=Jf& zEKJA2IlIq{t=%?D`idQMMM?satUr(Q8Rel^p+DoakbpNYp;Qa!j-dw-@39ew(vl<@HSNy&Q9qxPp z{Q%brl*F%_4oAZSX=T{&+^mjE<8w$$hCbnT4nMDO^@Q=*+)qo=RtEoFHBA>9rThNp zp0?m7PlzWY=?T0XTtmA$TZQNTH>07Y zr}USp&CdO|s{!wdOsYh+Dw)^oIAIrTe7m=xd~G& zW8%)i)8hw;eBx5?^Jn0K0|s(+6&Ji%xIbA>cB#&iQX2v|=QDO=xeJa&fd9&gSe_ob z5$qcYJi!QLahoc3sUH%K?huWSCK2id96wk+lhP9P(4}oYwGIX#C|Uop)G2>G=){Nj zsP#h{xMNG`Og($=ll20MA?f{}UHADs*uH$f-!Z}mKqN{+X12n4L3%yUbm<=?Xdi~` zoUz_v@V^7^>py#%R^MLNS#WnsHA3ORIOiqz>Xj+5oYBV)L*(e0C0WSlFI57|JCSOq zS?ghX6H0C&-G)^io*+HdJNpDU(Y&cc4E2HORIFC*Jgv-JS8N!zt046oTtpLYmm1eg zkK@k}pN2e-?B^iXsOH&uNpl9$Y<{KsDw)l2hKQ^6;%ee&%K7&AmzwS8IA7o-XE^nC zc@xqAaG+kG4c6G(%_>BBlH$J_CqciDJuZ%~UtFMo)aa@RDz?KMl-+2yb8_5CPZjUP zNX#L|Yxsa=HjzQUjtl1IVAjV~3{UKjw0HJuxRl@`<0R@eHyxUvXsx;1*48&j&xF@? zqD~yn=zwJDmyXq*8+jdVY#>0sJ7ST(I@ z^JEO@UFhu45MKxP>wB<~z{wVsOmIWKIg;T2Hkwb)eI$m@d5Hv6cCHM%`%(<3pO3tc zuY}O;Iez_w3!e<1$)Im=3*|kAWz5t~7hwG@kp82QyQ_D>!9%V=lah7I1(|yl1v;L6 zy$hrWqlW5AAd$I^)v4_+#(I-%NeKS^LwMJtj6Db_Co5ju<=e5A*wRS5?Y3+7RI^Tn z_kx9|HmP7iuXpP4@?QQ$^g|I{nL%a7UUK8g#5%TQ^SdZTbbdu5T+j&Z)*3U{Wax8G z;ao*}RY{h_dabF#CSOG4eEqx6;MFihK^uyEBCE8-&O7t~e|m6y)$)g}n_Tq&y8QGAmn2;V zbvvc}$iE_T;v`dpy|0=wcXGy>h_(!C41C>KG_sKEf?-VStI8;T)*mr>TyJAo>zYf- zyqmjamZ!+z{wt_T5CNz@dzrn(BL;K^_^{!~Nd;$X7o9)h7JS%;cW$le3BPf`5)cD^ zuOTkSM!oSQ?t8+}-djL(5(l4uhmv~jdR)Ue=WUKJYKR05PmA|V=k(Y_ykP3=zwXla zKHm+*4L`@qtk2ee+CcxFdkBj+w6i*pk8{|Fll&8AW95+x6&#lZ!!BgINZ+$L?Ia|O zdbPD{hStY-D?&ow$Y(4u-&!=je0V{jI(7Oq?A-+X_E<|4JCAQ`ir1peCu>4)!WfC~yEHe%NychTvTK#k&)%^C4MwxT%edhz$i-9jQNww+cJ=vq za9@V)UJBBUj)}+@i99Z`&n(Z7S4=6v@m_@6i18dCuw=sj+xPiGW}(_rTTL0E!FzyO z(tGH?mK{k?qDY_bl%ZfzIeI4^zTHn&QP-w&M*QvYHlG=;h~in=*%Cy5;cKYl-r()< zyJCS~@hVvXpELfjC8vAJXuJxitWW5mDAchyzW% z%CN5VyC6jyaqu09>3vFZs$!CTTGEvoq(aA>#IsLMlcyLY;}j2wO_LO#ZtwOw@XA&4 zAR4YXJhIY)Z#-`-vynE1v0SdI4G##^$!Rp}icjur%%DHfD-k6f`*TkbZMK>NQiILO`x2 zL{;s#fsq+t%SlznVz+_qN}G)@$!ST~5O0F zDbY{moD=Oc$&6#66`O{xv0s zXIP{cdEVAeTU^f>jqJDJ;P+_Ke4ojuTyS&Xr$DaB@QvyH)LqU3e+$xL(#AQ=8c^n& zr=m*Qxl~snu39-I(v3E~oM3@=5*>@Cz0d_EdFQb5 ziP|i-+Q@mWw)z2ZY!^7&qCV%B0l!_5n%u(as3m(^q>`L?Ivqz*Y+#nfN$w>8x`bcQ zT-@>L&_XnQ3_`{JZV*)==S4RF6^R#n>b`;DqZR?HDKn>!KL;O80GiSpv;6_K4TNgU z7M^-5Gvj+?Uz3ot_xnn1+L=5xnFHj|Fdy1^*RL#YG3vKNyrODbye^{tvA^+e44~kC zty#j2E_Q|6xyG!TytAKkOu0aP6=v~HgDj%ZxUTLZZiHQJWWh5orgpSHqI}ea1$)~r z>i}fzZOGCz;rJnx=?s~6M~YsQH9E^HiU8>~2&im4hgS5u+kfzL&)oTL$sN9|gj zj;meo2U@an+-p;4LC_%8VHd;b#@uI=)%wiNn$_pt10HPqslsROBwnhR7swYz65>Cv zrC`okGl+Pl zx;w&6EB{oI7jvF9JZQxhBFU$G6eYPd&U<%Y{o%fg8im6;*v>t@%-T|QXZ_bX?vbx; zvbhJ}gGHh;CMc>9NYaNb<6D*YFrIA9-5(BC1wvo)5edQJ!f#qR>KCndrHhSh_d8UP z5wYSLzl3_n<);o;*@GwNfj$DeT|=udOw*aXm^~bWgp0e&68f1Et5oZ)@u;?f)Gp%; zJfF!Zg3AD2$LD52jf-Cz7q6kVW^#7%uFiiNw1VO}p%y34?Pw#~W-slVfdu~+? zdHYVh`knexCQW92vWit`Gg0vx#=@f7dE$XlvBvi@*D8TKkmD;8Z9zkNu+>F#?Ps|JLRk})dMO2_BFL546Qsj#2;Z7SlIt6>1qvbyPk4u8vcVa2&3{Dhl zoqyA9w3~A4c(Jt#w`nx6^sH}F%x8H$rHMrXdkglUlajTwVM1wn{&Lx%SocGH7FBfeu6;Wr& zAYGmu2KII681$$D=feq=FSfyZN~$}eiD9B7wRCtTD*NOnld2gFQ9QolOh^`lF6E%B zss4+kvHH%`hIIl+k=KYUFo;+;$7!y1Qg}z%r}x+i$ost+--PXVfny-674l12gLvrq%{f3NQ|Ec~*V-d^wTkx=2)yypD3z}g z7qV9q8Y<`dP^l!~lgMgh_2PuU)MSeWw=u+PK6C3u0EZP+bCUBxY&4|)0O*Z0!8EUL zPI4|bJ@qDh3V2KIbNVvtH>kUb5D!cJGR5iZJE04^`CYjoA6OmYOQ=y(Q7$|wdy9_I zQ83=SbDzIk!w&>ojGbX@mZLY!>JNUFh^5|^;gK~-yMTMGd>ygWdWq8}^Zr=C^&S5# z=!T}Di8kWwLlX-h8RF0{gZJz~B^1BqD8*3mPG4kwbWEMqt4d8=n%RiR_M&D zbwh2&!fV6Om?|^b44o{gfjvDIvB06iZO9ekopbf4JgF|sC=iDo;X?$_=Q)kyX z*e6^;TID%q$4F~8a)^^gjmu}%1cvP(qhm0Q2@Rc#G23?>ssvV1e&DCSq94!#(OZh6 z03iczth1cM7VEv^d4aIznLAJL5g&OT&U>#z|Z-ZYI%4aOZSR5)d>Dc9eeyfid4F2aA5kEHI&$D6u0=b>_XVk88 zUP%dOaxBL>9Z8!AMaBBAU`#-In=990Y#(B6WF$Z`RY2Z31^yx>n&MVnQoAu@aFT3W zkuJh`&8PEAe85umUiL!b%l23hUXP|GA-*JvHo%-27^(( zuM?}jC)X|hoSKD{)@P|7+L8O8&+c`o)uSkOLY_mN?jXHGTJ2Fh`^)2pAT8C}^^x|W z`>GDo_YnS!GXiqP^~S|>$2$1^!+~^+Vnsh`eiaPYk4As>0CvjuzgvXg$TzBIq1*d4q>+Fdy#k0HN=A5xe3jog)sO_E9TS*Q~4z%ZU6} z^^=SB(1k8jrhsr)DsnNmhSIKTMCk?E5M#g<9&*pdel#|76!yIn9+(Wi>4@=zsO0UT zHGy04jZF_snz+D+rtXaN+ms9#m@V;W!cB0lER?QQbLM0^YvO;HOwEd?qE9F-q<<1R z^EK#?z8&c>y{JlO^#(?S!z{0khz6Sh$U{>oyq&}`aY8trCIG5V7w>_k`%aja*23@x z$e}9WA4!FV(me-YIxgTTEf>oItFy3Nn+gxM|GVygA7nM!$@Y%D<~$=WCZd1qeGMV2 zYv^x_Xt}v*w}HcjL8;iP!Mr^-O=H0T-YAKJ(JZTZ?BQqRMP9L+r?gM|z;_k=yB)%+ z!W^Cl-2|XV_FebWq^KNs`zwZHm)UK2xjUnz;ebG>^tu26{x%5VHyUdsPUyKTZ1b6) zrXm{Med!+&C@wzD)~(KHyer4H${+De-GzfzW%4fH*SK?h2$E_5P;;qhpGKZ&$3Xluhvq$lPjm0imb1%OX3ruQBWzy!$-pEDM(ls~1NC{M!ore1;X-fR;?yMY{jz*d-&Js+=O@=loWZ1H%qQvpQM8 z%sworrY5dl!kBtDph*_YKXc4bg~6{uf`Tx~6!nn6IJ#92RbXDkgV_ev3^jimitg_B z(p*lk`^@uT?q3(|WLW*~&81D$ELA{u`|Ppne2R-w=*n%rxDih_fPdO5nDsdQ%L~ag zzBrD;RZ<}Wha^+<%e90&h;!3O(VWH~Zl5^={<@z)TeAk)L#3{5?xP{0r@AW>^~(>j z!QD2IxjEu3gB6+%XAhc7_-&`jQ^@BKeJZ2Is}-C6K(IiE<=|`^aA(cbs4b|7f9|3? zW(}Se1I3CXIarXDdNCQQCH+ytCeD<_V&`PHZCbVBJCCvP!JZSlz{F8B!;aJ;5% zfUAxl2VB{<4a^ej8mYcM6^nQi31vW-)}hqqE7gGy5@Hy-&m>FK?f-n3nMIKB;`Bkk z&W@;q9~LKfO${VrcP+$cXFsQq-W>MLUC;QRn`e)8sYun!I(Oj++7NLem-nYTjG;kwKoww0GfSW;_=ma@ zJ$=`qh9&-PLz&oNQ0LrX<00=X@f+|aZPAS+Po}{`;p#VQ!-9qR9tdU^;sHuS^a89J z{70__FdXy>&CzBZ#9v5vF`lB_;^bQ~5KD`le(KOvVfs4wNKpt@R?&oCpMM(+;^ga= zAP*}a4}LYX4i0)gr0zBA!2D*)N`8#qOcM`&4g1ymGKch3ls~v|ISPziaODttIov^& z>;2P@(IOtZ zaDzhnp7k+Stx;4QU|GWLD==bH{St8-7S#ujI6kDH+|ir=fYgDrmxz0b-GlIz zs;3?odC7cgMtdll?cd zw^&vbZ%=Vvnmg#c?m}CR6VGt2nO@@FCc_7YR;numE@Rkl;Cf2uw=!(r;+*0?s%rzJ zgWpqeKpl{4$_wtq#!msAz^?rOKyeW|0z859@>VNXM+X!cq2&gPrYv7cpgT7jrMp3ITeI&F7GHpPf@SN zdxi0UQg0D6yrjQWh40)zpEjX^rkkp~#t6ET#L@-9Y3~KXHlGdA_=C|$l8|G|0`o_VrDgc10e)Ey$lZj)o}$Zsn;rds)sfjq*lHU z{!d20K7Dryr|(tROX&8#dFi+;DA--J$~(^{+li&S+CjR@KzV%qYv3gw0Mvi|Nc~j{eHKJ71U_|7fo2w!l59;7aEoW=0XfHy{i~tM_JvQk+(Uz-4HfgOo?jT2)i3_Am=$`Sa0z zpi&Rqzs9JHi_4_;o+KXrV3`;W4cw^dJ(I_yz3;M=3yI$vts|Gu-D6q;8EAil`KHj! zJsfm0ylQd&X2I}mu%E&#QG~ekO`5Qfu@@7`{qKPC(YO~||DF#B-*cMUBK=T!(MFP1 zE`=D(X@yu41xq@723c&$v|Kd6KKA>s%nW1l>-}m&n0(MLagwMyx~ue?xlFJ=R1-*3 z?ewdjNo2p{qWuuPyfC-#Ry~_pA#gt9>d`*&!0$Nk>dduMr*u!35Ur zMtw)4b~okh5f@;QdR^W`?y+d}RoJ-@miC1Vz@5WFsv75w9}YE3eA>@XgIC+E+!yi@ zdOyiorvB%0DV+NrCS-c4Ll*$ca<6E+o+6*#RiQF3VnnZc#jpQI=tnHC^>EjKlHzqM$%C)g z0v&F)2&ES-KCKISTjpDCz4Nc#)=HLgg|=Zq2q+1tQkV5)>n122sZ4u%`K8)plT*|p zoN3cJ*w)7=DgK21jzV?~-Ub4O+Lv;0u)N}!7T8$sk?^C}!~Q(PQas*Y;ds+2Tr!v( zW4^766ub@`&>kx?Y7G-zeiN70*oBMm<*cv*jq$M+?042}H{UGB=s8dNRMgPTr%<)I1Bi=l_VaGGZ5;{E>E zFGR&X>}1-!r+A=1xzaY9P885ub_f0T?ImZ2b>n_DpFfBw$&?vPGge zBWJ{KAN(JIr2pPi>LdtG-n=_0Df1uR^zm zBKK;nUC1iz(b#@oPcx7zwgj?+Znn9+nN+X(@gi-6mwHxJuK8h3i2sAwj5W*nWoxwv z+sb!-+Zuq;_%DeaK5=VDy{Ti5pb0Db4*^HLch;(R#!SU*e5_j^lzDFJ$ZjJ|JL!u6 z0VKK5dDX+=YjDW2w1mbw?-qq6x>jkx&rDQX7lJJlD)e9zvG8OQYY<5KeIPvS6xa&R z-|M({oD&>EAHhKw=Rf6f^whQmBzJ64#WDjWO#^!%lbqx;wkq=IPc0NlN8Hqb;p$Q+ z2E#tep*)ah`fV;h|gl}hE&dH&F*?G$s#QcDC6)~heXGq~ReTjM~P%-aCx3wxD z4#5Hq%PKwY6Rj1xO;E3_R1Emr#%*iYHK*g5*6cMz=hU3)WDWac%C5U8n!yLL2Sz8l zrhRw|J8X6qva59>lt5?#(t^d(0?5X4Dv5;GQE}Yd?R&7&r;@;iaiS3_&ykegx_loq zylyld%SXRliF$~Zv4gSgUwO4dpuCNAcRyTE!mlBuT>8a=` z@0-O3B>w~Rnh9o$;7LZTzA&X|s~-cTyR5|rcJfmC`#Zak#ubalO#qQ}sIvHcWS_FL7hQG(}a zoWlZ5&DtB!M4l@~mSh6b&$!I2gcZWtK*@ueZ)Tx|;96C}s_cIkp!XeCpH zxmC#Fv|lHex4*`D8D4l=_`nW^Fv4R^`Zq&p+W0~x_m-$Kt3CJD&?8jG2h;;xD_Lj& zr02LtR~1R~aFG?233N#KA$%F9LcR*xYJiu`&w}*QWD)9-5GUvGzSF~fC-2;2O&c|~ z`y|rK^+CFdXFr8C54GG8EL?vm!aqywhnH;Wh*ECg;OkX|EqXzxLdTwb{Jxp7@}WvF zRi^AeeOusw-R$@ck%fCxnHASPhrJRaOcY(;?xjLm>V?7h z{m4$Z+@J9>^&5>?{2g`0YkVmljs%ciI{yv5m*wm@PqxsP6Kp>;0v>xmPSx{d8#+1Y zzf`SpW7)Ap*bdn~hAnw}@H4q_9r@inuuZAq>sKhLKX(1fQ4%;cm6q>^c!?uB>U*@_ z{#&awZ1nz%SaG`1k_|{NIh^~IOa6+uUHDB&x=cuDL~lfCsj1e@Eei0r;^@?B!D;6f zwb+!_sa!|7ufRP5D4RGLVLF$&wU-~E;-?lR*h@Ij#H?6e>p1+@NFw_UZimfRab)S? z3DMe;v@#DLaVT+?ortpumcEC6(Wm_TDnY4%_D#$Y+w*EphoNiD-@lmGzdr-gW4xZ_ z{I;p5uQC`=}OaN4^ZUB*g*O@UjjHIRkuaTftRze0G}0c_7-% z9K*;|%ROjdZs<5s4WumQwgTQn|U7V!-k~+#}L9q6%Y5d~u zBTYycq7-mV=S3N7Q@Dy}ITK84M1l<*wn_#+v4DXuG2)1ECQtRb_8sYB=z)64R9A>5NX|AxQ36o(B7rw!>M>Dd3=nY^(FK|1 zG#mcL4z%j#IX)nOE>@q=uC!(kuC7Ty^+Bxyg}wH8IvwcO$ghDU)x=y$voy_QpNH+|7nXU*Sw0LJ)% zFUQW&-3H7>Dt(8@bwjA23DDife-b^D3$6!m9!mayKNEQ{dTiEUut+mqTsCNy(|7oq zVJ`2Ga!#>%y4F8bZKIMjgT>ibu>d#HvG8lC7{LqS&$M9GuL^H&h`)%!y0E^!n~Va^ z8nZdw*K3ktm9fgJDrxuMszppMwZH0Wk>Q9l_f%$;(5nv##GTEsm?;9u4*RwxSG^gL ztyYf`n%1yA(+I>ZYXTU9iLfY-_l{at212d`sVU<|{;>9+h4TWZ2Kd+u6W0Rx>s~;; z`}l3tS(q!Nn)+R-?}DbP*NIPT2Qp)vN*XP^c$3q2``q?I5yYgl&0)5OT_WshHdJjF z{S2GT>(o$c&~(f@}ClpYFw~6d?%gh z=Rf42Oq4Z*uewxcw-21E`=Yda&vY}v+;j2y2-fDBVI}an*;-z47Tx^rtKy@J{%DTC z*6aC*2ElBR^N|u4VYZ*Xw0@r>yPflgH7aOp##qrTKN?{h7nFMq_>pSX5H6QeN!p0C zNchN)DYXbCE1~;djS9Y}U0 zfrP@eRfQ9l0>-IU{~mcM@ykWCBx7A|p(qW~%cUJi>gNXTla!`P0HZX%+yct*Kt6%P z+p}`s6~a~0uB-U$ROUzVKVRDaY8tx!zJxt@(|Drz18o_%6Y@@trb|1@eHZ8jXf%f* zc^I`}ATvD(SP->N2CN$cRoGO&{eTLZNnCG8p-IeeQFxiCu(dQ2#PNA%Bf z(tbZMU_-qOIvK9^dkoTZh0)&HX8Eg3Xq^m4{PD}!ODnzcz-89|=k@ufw{eouJ_#0_ zrhl|&T|SdUz$8nN;0-l!g&%jSq4#y3Tv+WH%H}^3o6BydA(QIw^YQ08U+21<^!yvN z4z#=hwj|dS?oS}9qRCLz1 z77XqE-yl6Bllx;1)h}?R5_kU{TaVYV?5?th`YM=I0g$D+B|JGNab4NaJh;A# zqmtJ3yCA+kZh5pud$aY`8)SpPD--y9L|yHUb+CW$RJpdOuHbdv&)qUMl=~^NU>t*N zFeo(7HJ0|#Bc#1FZbC^TbMMtt5dxKC0WA7K_T-L>iF|R{@Pp`bf0J7-pT&W797%p} z10j%urRxYYEUaF}IwblLpCo@N+AQAynx#MiK9ag^a(DrCGjDBpB0o-2cBcYXfK2Zj@d9vk`j3>15csRz zG*ObM@M- zlD zy+0{u41g`EAMqb(FPZnBOe~PHwU)yDkKJM+TgJcRSjC9yGq;~3ThkS03@yY}Ch8jJ znm+)DoKtOimrwEZJ1HB(24=w~1%;Hlz>&R^J8vqv|4ib8 zGu>5l8fbBnpbP6yFM@`nyGumFa_C7w^u|Z_HV&?J}br=_=Nln zb9Z-AQH+ghdbpTuyq%FpvS5LDuYagxlxYL@v3qOUmyh(;WFT>Jf=Y&tO7?P!f$>KO zzO_2AFSMD`DiO&fo(I0Pq;elQBzJx|P(NS;g!fCMUW=fea)az>sZ6i=E4RDD(8ys9F54+LCNnvNRU-y}1j zr9hlqOcgZ+@d0d`yM!K))v=bgrwe9WUH=Q=Qok@hTsfO99bHjljo7yXl@Z9CFZy6|I=>z){*K2HPv|-!|Hc>vN0w={KGQ) z@X)^|>U-Q6M!Sz~+RprSOK*z7;Pe+4jp6|vMw7vyA%y(F=h8123DBp+WkRk-{)(QPythY zM^uJ;OGcpSRo9)FmU#Ljj-G#&tQSn4RM)LmlT$uXFS7>Aq;6)K_EhMJY_&L&H0q-k zs}S=mcSdpm7T+{o6;g@lX2af8HrbV&*;g=W^e!D!+8y#CC>alGTo)3Zc;F;2F-vqj zp|VWieUkw$duXKzu$;MBoa`JvQwY6S9C+KSBAWxSL)v9*?dEFNsXQ{oC~x~++yR(P z`%Xu5iNx=HxYyi#Rzs35^_jw5z%6C=4O*db(4#{IiQiPsc-ZDutH7!B0f=I+Q9^`* zXO(q=i*b*j5YXD?LVv)!&r@(xwj&qsAURXmWP)MyUUBThMW?Ev2PaQkPsL?=W)Rkt zAtZ~?K|J%eTqCz>yOT?X4T~tbcjK>?1r2SBzVeUe1dk6kFF8DtzHk1riweolK~nO7 zf*ycxFbW0un&%2c;7gdfaqc6uTX`wG*Kb~s6x%)pa`TM%v8XnvfM?>+A2?J@yM z?O22JXllC{%-iZz8FlBs_y`5$jtB+o9YHm(+PNcpQ5i}G0#nP4I3AD3_%u@`8_LMr z!b!&Bhtxd}J;Sc;CTZqOh*31!ceYHoQk?j-lb|@W%nzNznp)QbefECduh3s{;vAw`Ldo`Lcic1fHZp)u3Nc7Do)$js+(1v-0Z5O!fEgDZ znk`Zr&z$Bqgge*obQ=jVstfcF7PBS(%v+#VEIKC7h)(*4e&TtsL=_4Oj#92yo*@&E zR-K=qJY#28Vpe`&_NC|*`HLIZNT?1HgcCZc=X2W^-3aC3fT;||@zVGGR1V3{sQ-myj7;6*u=!6_`uQi~%XX0PNaNrO$MLiOMi(f<0FCBZ^_z?9=X;|G zHIZ{Xr8&0 z$sR=0*b;@aN=46dam9n?IeQWteNVMTSrE?&YI2X7!|u(h5ChbgRaWf-zu<|u=oc_gSI zt~e}`L+JNHo@}GOH9_5e`gnJraY?A!sbG<=B6pvINg)JHvARt zpGGJC=32W4`KU))(vd~W3+!#X!W`WRfz{M}?i1;Ib(Ayb2iF*{P91gqgN>6%NsG*< z;K|(9%qUjUiY0C%VpuAi^{}uwxNCL~dve7oGCLhPBurc1(yKE)bjPY$ZwSIy4Dm4% z+Wu}MV+#IcinQwSdI@vA_QtT+yzv2YXK3Zz%iVwOT7=Yc0@u5vNwwbugKhnQepklo z1ir%zTYnsSsw~Q~gwz~F`+qc@i$Bx-|Nk9gxfZL-6-hRwsAQ|iaR*XVPF<-aY!V^I zkmGC)mAV{rNWw-=m7LF~Avp}0vykJ=ak9;5n~k5(_jddJ1KaI=yKS%c>-l&-9`{Ex zpRdDAu`=I1l%kiVqdlu`^fZ-M=N#2BiOc`B(4Y*(=9;j&uFhOfz|EfO3Y0wYbr>4^ zL+VFFU~&iWbesD0N&$ML0(dnQwa?9xAA8pRb0y+V`q*x4s#M}}5XbC2EAhIKBA(~T zYwZ!jO$-V*i`I7>)aa0-Ra4sy_VipT$hx=STX&!~`Nb|>#2`ypB{r47J0gJHP0P)uI+)?~U}Mvk78X&uL86B4v}>L6iv^x&fIW}MgS zV1wC{`_{$S7$Q;)N*PQ4H>m5oF02b&gsvcOr)Cs{Qz{spLXLhrCo*R1zU* zMCF9FKqF&+(^VRDJUo`}U@3@EV5qmyfRsOCHV+$rOD4Ae=@5IK^FuG;cgvK)S-XL- z)yJdG{#~7-y*Q;AxF_UeruHoT)LC6DuzNGwXXPwRXKsjg$NyuY-P{|f9D!`F^$BlL zx342hnN(QornQr=<{Ux=x7k5{zN9&2IHAq{Oi{i~)$t^tO?(t_^gM&SiWeUkqYUF_ zMK>^GE6@l}8&X*g!S=v7=5uo=>JdJ()616Ke~2T8s^|J|4^r=^kq=wgJk?>BcZ5(` z(j}`K8@tD4Q(*>G4rU~dR@)#5lY6h1vj+>zst!$*N&r))o1h$XyJE^ zas-#GIe8V@(+;;Uc)ePFDo=k3u8Esf@{MIChN5lfnpd0aZ*8Bae>1Li)K{^AT-??| zPk6l@3H&_GBR+Ku^NTU&w>vIqv0b<}gl&7fX)RdeYkP2FNk(**5CSnDYq9<^zQRg} zwi(ItX62*@XN!8f^vfhx{e6Nd8b99GCBERQ3O(C&_Vcc7IkP>NSdLKDn*8jy^G9db zHFdjlRC2W3rP5F^$-C1V&n^U4ucN_-mt`)25>*i65`X7rQK9xMs!G8ee_9 z->RXhN{nNsiyW&K7gqb&VFaq<~SA91H>3BY}sdS%X5EbojYsNbBYW?nC0uhq37Goc&P zBMP(wx&eXduE1kJ1BGuQHgeIzkyYWx&=+Fgxz{oV)nbOk)Ea#vB<@Tc7*9VV^G}oY z$6q(Y`li{X+Ul)4GYFX`$KM+p8&lXhqLl8hvMhbj!?RcB@(rbr!ogNuV?milDJn~^BN3)aT`KWDuB&D~rYi!}0b3TbcyE=Zw&7|#R9mTxDOD)f9zC+1QT2} z0*&J>8h2c^gDUKF*$j(^)N^sLpo+}4LWqXr(b<)?Q=j%eFM4!OpZ4djrps!s;)1^! z9GoWqEm|uw%~)`H%*%30jaH=QF~@0zk}9Egrn{WWIGtIQ=n{iQ1T_=usz|hbrkfYZ zY;WY@)lkek4Y{ItBSVYBn8p~JdHMs1IObb(b_>L!yh@g$SjR1_EFWlfa(0>>v_NxH zN)GX#8CVAoK!%M}EM`PluRcAG)S);TQG?kIPRsw83djjF;Znyvs3Rr2Ia~U_n>GXm zH2Y1I)$tjr5h&UB?IW{ykmRoFN!=z|?O%$$hIuwJU$HeL!2oDL$wZYybOELtQXF&Fe(W52EfM zH08P>jKWR2pq;I2NK{~j`u4p47Ecl`ZYCPp2ZU;bj01h?Cyj-#y?bUCpJv z&CJ+e9SWhFxDwFy_FW;teM$%DGUHQITV&e(QG*;&Bd=k3t)e};&cls!hWn93cQTr* z*y!w675^D9e$}Z$c7vT`iMuBQMuZ->oa;Th@LiR79wIE0(7>G@K8-#xG2n|xec zu|3WVP%NvECT7y7v~sc0oxD#(muQvr0l^q6>D&eydW0K9tVTbM&+*e;5 z$}T5WiBo|jar$_ZpD#tQaV0udIGvZD@NDycgy6xMUHeR{^)k94=X>A^KI&&w=}6#B z6e&%Y+5_>nA3bTir4O|$I?4xKTr-hv9=#^Two9(v4-WX3>X69kjRjv>bIU*BA~QgR z#b;ZTCvHyubqC9%azz!B*1OHR#I-4oLX|5n>rWdUQ;D;hu%8WYo%TChh#G$qAFKzv zQ7R*w%OhhJ*!1#m!nMqC-Co#}(#KZK4MFa#oQlS)yb1%M@ptI%5a^AZBG2=Y`#+-o z%zqNwrx%hQhpxPg8%>?)OU~r`+1L03mL=msEt3^YlLo(MbKkBZo~kb1mrdHHu9h(W zMq!7Q@VS`FR*OARenBhQ=3=mx@jpNJlHyY<#Hi(>0kUNiPoEoF(Dc_keffwnBV{z+ zpOlpu*cy?^`QM2z>k|VTar0joa|KKb^KaGFerE{7hqspb&U)nNi-Lq~%DE%8Gw=l{O3qeJEnj9>46L_nm}hCp9zcu7B6Xpi|1Akk>i^|@`1$({)mlw-&2;cuJ%e6T*K}m!+N+va5uD%2AxFooYN1xx zuVmp8Q(*|D`@=y$Q_-6C;-2?1^_queobCM11^m-8WHk7~lj(VK!{ctWoUR_*JMBsM zlg-lR3m2DLUMb)4*N_`ZQyUzQg6^2Iq!1S#@GA^ho;Ff5c3;Xyyuxk#5}k!}eqT7a z`KXc67eD0e?sZrx=|c1w;APbF)7wun>g^kPfGAoeiCcpeCBN*jO_(+C54UBBP$mHS zk+2zSZ{AYu!hmpT+gK%8ePFWpO9R{P4V3xTl=shUaK+exjr248hc*|PLu$LrRX2g2 z+QCefj7nz>0?={pq*SN*Ve`oiGdOT{bBR(Se=+^Cht?;=S-`xCatPG4pOJ^`Ow~Lj zL&Tb30Cde1UN})ryTH-{dX|C zz5Zmyo^<7LpH`XjaZ?QH-n{n#wH@~ih263qanlA3bFSuX5_fohWBrU2LGAC~^=__! zfX}Is(ZmJJ=l4xjHoBkif|%*m|MPc!R&oJBeS>2qMq%nZEYda5uBp5D*OEnsuW^3^_tI0NgQ;(NZVA3|V*ap! zQ}ZiznrR;N@Fn?l>nQMI9qFiZvEf=eE=oYD4WvfagdyLva*iZ9`F_T0q07^LGc)+X z_W`j(tAX9O7HQwvA9h<%c5aaItFII#&!-axrHREArrdc>AW|a1q~oiX?iHD*Rug&K zF6iglO?o%37}2GKDzddF89$l{G}Xug%{igpqc)g^;^>%>*ikQ(s{sLxG9;`HGv8P+RU-KZn4w%qUUq*Ow8yB6kYPpkxg`Swqz zq^+;S<$D1IN4~)7D|ABUY7EfAMM6(E-R56I$g+_|Gev(+LPh$cy;NCy{am$?4Udo0X56EwV zx}Avo`RBdWmZ+dLyxC{(u_vqs2zw+vJ zNgXX;t*HM5p^7Ey4H3jhR>Z(b^)Fh27GO5-q)nB{I`f^4r}fe^0Ata{Cyb@vU>Lvg zRX%t?I3WsVO;XE;G`ez~BsR4tf3~J>i}A_ktS1dIR+^^P3lv_qd=MIZ+GNs?d)iEv zdT$MJIW#9x%Kfc{(e77;d5l7L2{`2><)NUO_EkB^;c@qsu@lSHy42SY$F~DIsk>%i zMC(^)$_RxGs^`lzX{W=Db8Lmti1USn*_4w?d;Ln*0~RlRmdtdyA9Mbgh5?=;;MxEZyKJAAD0t6T&7cpgY*^Ze+h%ES1~pWROs+t z)fl>lT@ZrXEFk(CmPn4i%MJGuQPYu~9RBYY_AFH;ST*F=W==(PR_tR7FV<|!(r&eZ zlE&*Rvv0lblqCe*aL<9(+Fxv`mNO_26@owEiW_m2&qP1>^3r)-eXufcC6;c-jjXvl z?|RYmRQS*(GtY&6ymOYJQ$^?Z16~m?+H%O>40?d?i19w3sF%As=Cu1e25rF8e&x3# zD(W=;Wu%Hli*0e8goi$Ub3ld;WqOEd>jKqhp0tWgf9n-~L3~%{I_J!Cztg9deo8vq z@H9|a{^)aK^yTsYv}R=keG=1~_3TelURfZ@&Fsz&<+n!M4w~T%{G}m zXQfPqTQ@etcT+sn<~<&C)&1tJrB>spU&bCaAC2zV_#uMY>QDil&Vt~rQn_gacbFOx z^?k(Pc{(C6djS2>a7f$$Z6NpfVD0wAR4XWm7hd+WmKJfRL4%+JSFXvj)eR{w3Q`tr zS)pjYoA?ixWp~^%CUt+E-)G@+oajLykC=P#%0r#1v8ABbn+7ZNePK#zu}r#Q*dE96-b7f5&+Im%Ary8k%6N#Uf{FL2B<$|!Xxw0gwXwG2pefph)yBb$wfH@4-{SU5`*f z6A?Z(HYzjpj52KbvJL(euw>MXkYkuW&FNBYe)iG-wM5Sa zqXwQdxnme#opI~aySux(eOZ5EA)!t^>eIMWso+8E);|5$-Qy2`IbGlG)7vu-_SUEr z+wC|?=TtVw>U23t*S7!d-@RGGOKOqPj0gZrgfwquL2tifJ*-{G_-2 zGm25LbxZb`OPAROXXsHxrM<16gyUZJ^w(IcbmFyA^^;)ab_7%-GZ_Rh*vz>zgde8=>SQ?1uIL>2MPj zFqcB)Av9Nzoya)F73Szx*rB(cIMY??{{#bjewOlXg<@SoW5P0*y)2fzXZY*;1aVN; zSm(+Z?%t$I4>G6;j@bq(5<6`k>i8gruG>gQj)ttp!D3Ta6TvEV2XBFV76UN~t($hi zS%4H9=^lXI3yJZF>f1PW%8{fa$lbv21#mwx{_pxV`>7*)J+VV38B!A|{(Ju;Ua$Lh zxKdNMUTS6$&KsKt2fa!K4HK&iG9PGZdsUQF5Qjn4g6C>}+s~dNF2Vwk_1K}HtFX;i zLr;|HP@L37G_UD|H*P`XR)gN}{~JDNfxNr@C-6sn?ra{1U-_%D6DYiI*3z&DVv)r{oi8=bVLz z{0|42(4VIt+<2g2-K)2tBc&~*b+h)D&#|T3ilNcW=VebG84=oySStO%rj}xMFVP`L z1|+kwV13udUIPl;ew;-e^OtCkcvU`gX$nuv;^xych}#xvre+X>8Gk6 zoF3PB@F~r2j%sI@m~(-|8n$u0RIhnW#?*1dyz5S1#ArnSw_b~__X~5wL9F|cP^_b+ zwoj!=W2^$1%`0Z!xo=|- zg{}`Sf@ct4iEM`5XsCQv9j*z`S^igi7~1tJ{iK|?by~RvT3@;qJZqPqXUh8jL zypL)D{-f%9>~!?*M4nmwrJ)St`@2sswAtYG@Voq{=`|xCauQQAicD7)$|&vp^mke+ zv8lWafAXF_@)M33hXQlG&gixR2qUVR%np>Cx8g%x7I3!4@4Bo9d`QlW%PLowQ>{?K znc_y0cBOh%9c@xy=eenLxcJ7`fk3*)3WSi@;@R;TFv9PZ2`50tFrBDZvq>{AiX-v=kBe#Hiz z)0yM`z&P6u*J_U%zf;G`g#n%_4J5V(bgyZ#KmGVv_R8DZ zt7+EWSmB}i-I{LMY7|{W%-0AawP)vVWI!}#4(X&n$tf>-`hLM1@NGa&pkZW8w=i- zD$I8iZs2U}#@|IfsqIQVo2MSn?bK1Gn*Pk}b?#OCDX9r{$qcY1?NVs=bYEF_x5m2x z7S=fHZ_zI>O>`iEojY|>n>5}hW@Yz$g&FPHLRwYWU|b#YR=xU-T@DH^7 zIL;Z5fOsMP@yKD&tYud5!q7~htC|~DGk(%}#GL!qBQU*l=iCzC%2x2T7l!>cv^{mK z2p40seR81=eyMms8Wfy3LfBfQrRy%e+j2)bPJYE}o>rM`_vY!RKHa8n+wcrL{`=s< zP4rmQd7NKXzx(FZp_f)|BhoMFCz0{72 zzM0zxpP)+dl^X+)-cX)#81b-a=w{lsJ^_&%J-yxOJzfZ({QB=i$p@=Ulm;^Ar0UFF zi1%uEJbW_5O}@if@VlDkGpKt5^Ff#TZwOa-yL=4EEa*wov?Hr6+ zq*?6CfdkIS3cBm>2a7AT-eumJ*8{xr?>@bapCLbEF_rKQl2dW-m7WJnF)l#Tk=*sn z1^zPql*`(PW%}+6AYb*-f968R|4{>9cxcL2wwIo~GWNi4UED9zFs)%@+U#u8^%;9T zt%u4;pe%4z89*~ro<0~=apR~~OW&KL3ZctSvXsX*!=)M|Wo+fMl&@)s@zoBP{-q2A z%FZ-;*Lj~P%_?=hIM7g=pm`*muMeIgZ_1RlD+aCfy}L^4Y&(76XQV7cSp=oarotM9 zd9JWsDUEUGzbiipJBr|Djr+eHi=%An*Vj+*n6zHqqbp2&9>Jo!$LC@&Zq2 zJq#f;s@ZR6I~xf_`i($ONFAJz2vW0ObFKmfQ-z7{+O5KAl8~S(>GBqLfTjf5=TWWR z@VG};RgnV59xOV^b>dV zUvtCN+@Jn(RDZwzqDVydaY22Gc&u6X+)I`EHW8j9xNF=FzAtr}jG`fjn$* zVpI)J=84@mlc*sX1^;7KCrX!l*!P`zCiO{6>G~77nr%jn`p@8PXWS-!aZIOA5Uq@Q z0L^bdn-OfJe7hdogi2A`7S7o8KEeGRgX!pj{-9CM6r`2MUBBzXw@!?(kX#lPEnWsJTk!;k&bomE09 zf1|)@bxoC`Rwh|n&|yvI@!vr{6%bgsxe!5Np@JC7zM9m`W$wHBJ9LTEd$VhV=uNLn zaueE^a<@JN_wOPW@4(DwJwfr7dwq`TEHM8BTqtPqzF?=?$?n>=E1;TL)3UhwZ^L`! zXYhBva-b0^^tspW&%tvgY6(tYzz>+WU!vEPJ-8noljicYM!kcGu7Z?l92XeiD?D8q zb3;PK&4h{c(~vAR%<+u~cIA)FLxFkH4;xp3v;n0l+M4k~xCZ`vTDh zNOQRP8hcZIL(+f1>d$>WB^Kb*%9T6Dffemg!X|FEE zAb>7d+T-J46W5fRxysd~?K3^cw)X+_{&tve6|J?`3mP`Ihx{6tPSnyH*_`q8$ogthv{o`RUN`he3ozdEu+w^J zT(;74)>4=C`53B2Ginff-eOjDZEV%~j4g6-zkeHsc^W^uHaft5^q5*-O)y>iDV59p z@4}bRYff7|gTs_DJUsYlD-a(bUI~sxAIZL^p>9p@D#?csI z5}e;~XwdxY6>h46OTGu$v7%a-160VU>uk)i3%*}a)k8n*w$mq9Nf{MmRQ=0u>DvRW zRj~*DR9;^nH9p!u+HG3#UyKLh>Qj z+nv1dOO{jRq9qiZ|DU9%Ozo$p;`ZuIg*g*1k0qyKl6x!&0}@FXoYnNE>87k;=bpGEYTJzbrV(sUVIio6p=tYb8X@iDHbBU-IBxC}7_`_Uh`$(H4wfRc4{ z!+NKj;7wvPgoFwX2-Gxr6c{mJjj(K44p7*^m7{#yb= zrjci`6{S_j2`M&ZB%@KqHd0sMYcuo^&Y)il30!6D4UuHQrH}5s-c(D}{L*8|fTT{<$tdL!cHR zp`=ll=DTi)x`>mDPHyY0c!01#cRR;Fc&K*?=Smc6^692*zbw%F>^ZJt5%g%4FzroG z%vVp)gi>%q@#3Kd9}ew5kw7zu{3Sy>A$8YXF*UTKXYnuHg~E=qz$Ba7=ui=Mw}LFg z6jr8h@d0g9&G}iK69gi>Y%T?Fmvt-|vQ*m)$ z>9P>Oa=z!!`%`ZbYi1-r93uujKGj&UBcW2uVBLxqbrMt56knUVOiM84dnv8s zAdY4k=%ElNH7K(8O-@~b@u_q5L(EN8yU^$r%O=;oiRfBfBuv-;pbPoegoLc594m=h zcbQ;-ylaGBza|&7vLP1-c1e!1G{2xg;oMSHXChQAbaiR7DXzbR*giM-rNF&o)<^|G z#e$zc@Xs3yEH-p#iEd`xFMzPe>wRv(Zo$ap9AfE+$yaNJ>9^; zj~NG`+O6@q(dB`n&x=U5@XrnW)A7aZ*3O4k6WNtz<3A%bA>E>Uq2wMT-l7(JLA%sr zrY$~jWU(UNbGy@V?o5Kx0=`lRb9=&xK|aXkyoIN3X;tWJP zgG7mUt9eExaa+v3D}!%m2CrBzGZXSHkt4|AN%vI0TLd5B(5iU4l053U8q9`jwm}9G z`bNum3TdoDl+Tl-q_4Oc|NK~^ky$#_(6 z8Cg*&@5*iI(I7chiotxs8a9x%_A`UOta$WO%OtqpQ&xP9#2)s&bH93mYpG;{gS|s| z&0(Em98>KEqrz6VrBJ1_p~p=nyEv+$(dX-K|_BBX4(GHOY&dG;LE9i!GRA8|T ziVPQh=5)aA-rc983G76WbGFFxO)vQiJ_GkO@lR6AM~>E!jfhf#i8g5tPNF{U z4_IfAZ2dM*8Wombqi@9juAkPnQ1Nfq%yQn)kBagUB0n(uW)1e;FL(WPEG2I)8T8Ex z{lQ)E3Z{l^U&toMbM>e1Lo}9O@~`w{cLMt%H#YOc`o2D{&rSDXS_ADkS?X|W852Ka zd6Moei^_%5z;p`sNzGi8W!!H^QQEi!CX~E+!7=*1)ba&h*IU@TCxs<@;?sPF%)#2n z+`l$5O|0uxH(CrO&*Qi5#5G!=e_jmike-SZ{@DulfBq>4ylS~>2JTv1wVFDsswVX8 z`6&y10EHMxjv5=C-7iS8Yc5_VtC%!(ie{Eeg8==eQ%@tisqN59yZSiIyqTD!v`~kv z-eDzphCaY!Y%#G&ND?oyo&@&ho9tTvj`p{M)Dlu-9XRYPX=|U~tUB zq|HSv@w_}G!jMs*uI$24QR#@sJS}f+H~>lAHwq*jf`5Uy>Qatb=sKtJc{kxty_g0$ z1Tk7=Lr1l1r(J+TIYNbR4nTlF4TgU z`egHf%7P<5+h6fBo7}@GL@W#~~x{L!dRhEKO><^F%%F!(hMkW_M6(QZB!%&PWDJo64PsFKD5-f+G&!F%gm zyKTnk?(kB>&PAT!(?_c_%AL1-HHZ<)x?K-PTK!12lyMj-2*7201RJGc1|T zL_h0!5J^BT){i=M7hz@U73hl)YBC~hkx%YHoMUaF4X<`%DGNaN0J)qDL&vhV zAETAso#{w|d}{uoK>l};hU&E}wv3w+hf!h};8O|nZj&VaC{M~m^OWz@FH~T|WXDGu zG!qHkzr5RitJI9g$0>-6FS8`Zmp6ClDg$qr#_F_|p#r#5I*jp;xd^8KB&UBo!36Sr zB`tO?2?#qOKF3V~xuv?0+r8FgN$Tc_g@?cmxJox?u65mKl_@c84Xg&Obx3s9Oo~Jh z;}4$G%P}+oaV8)SY3(Dv@TbO(=TuHZO3;VfEVym-I*Rk2nSkmwaN zW4M8a+dQ3Wuo1o+l@R=Ak03Z6<3DsgVY~WUgpF<|Z~5}U6aEsFPq1KQA2b39GRNAN zYX20Pn&G)L9@o71;JD%y&)Wp7wy0vp8xhaJHZK6DJKGW*8_1d=|5Rgiz4LTPi?$Oj zfB6Y3Ee&4rm=|?95FDoboum1w$0S~^4RX|OkqnBSRao@V%6SRcwNezWy#wb z)cM85Yb4zF0 z?9~Ed_0Q%^ktryb`7UTNTeI_H>Oa3?0Ck^R~VTa9fqE@)ih z&s?|NCHPZc5-tEOZ#Ult6WMR0;xH>xuvx3=cj$*%IW5K`VsPYm-Q_w)_(pCtj3;AG z&QpOOuiek(Z*Pr@gGrJGx}$_m!`*ZiS<|!shmjnSUrRy+wf&ZyCkd2h+7liu$KHpN zbCkL;9Kf;x(xKB;thzMC%Wk2J9D$pl0Nh_lFGYLkHfI4`<_=&-+@2pS5PanJI{O0* zC&=zL-LoSd*N$IP$~>eEUl|RQ#cKzx-jfrYIngN8^`8ofDU%v+WUbBHx8{*p%ZMH# z)vDI9IHog-FG5g6l$T+Hg&JpBYW0JxVHGexLdCW*xl_e@&{(W-=wJBO=AkD@YrlIX ztQAXrW36W=!R^c>P}EGXjTm|nP*;VQ4GjFTO+^1Z~RatL1dFbS2GOlol3FO_rqtqz22&vM{ckqYVII z&n`1=c?F3Dp9X^1lRkgm#cPK4=Sh<$AUc8bYVlxlT98Yw0en!FNbi=?&_}PagA}7? zl1(VQH|2g=85vt%Jy<9^wMch%V-L#fh-allcFKP@CX_Q4O0U-^V4b=m zF-9>XP-?1A;6Z&;6rcG`U6+F`Isq{iBug;J@h<%xDu~&Xn`7PP@^k&!trlRUpJnyM zo{w(;*x)xqKrm>_M$m;>dy>|iQbRbCP8zq5k5JYgw$2<7vG3t8#%LQeTjocR*>ts^iRHOfL3v@9H4 z&XHEoVMmG*fP*ew76GoT$+N9v(BvG;Y@b2CawaLz(YK6WMC?+X6&(aMIVYG_B8H-8 z`V-#HBpUA*9Sgouje{+g1w%feS9ia>v@k6e{Ks{tJxuVVX*t)C80c?-%FA@&H;j3 zHl-mg6(j0h8!lmRMLWSQ>Y3R1+lY@dFC$;-@*Kb8$Bd+;E;3->F>>oy(>|B@tsj6; zc%aPHjX_TK%T8d+k8+#ziL;KAaP3yW486T!HwGz~TZx@kPrxL+lKuF39}GF$I_l{f z)_l1`;!^NQyqUFIxDqZmpnXsszPmy!=HF`mY@xwL9T!L`d?FP5X5QTW*Wt2Q`4A5A zZ;lH#k?nu`7M~X{LcaIP&JtC7&I(+&JZqC`8@jb$bkg%D26Q|B_HmSlFkz1+o3Z<< zvob!DFSOih<xmWJ_egwdq8H=l8&Gdza^&P0xPOuL|Q6$EsmqQ4h}l28sn({fV*?<$>6q| z7XNipCKjPt%ofn_?{D{D^e!Wxamg+x$a~Hzg|fi=tffo;RxbVk8qQL$TdRqXQQ%j; zA)>;iyDHE^9VWUX_%Ai9%6l~Fa(F@W-jTbASy5P@^TN3#fnztZ46A7F$#o&C-spri zXXgcI3^K2Z4yx{QdQ1O~1<|ON`rYJw^1*|vkkHMD;N(TCO9IYS9U<8kGt^uGJadjK zJA>8j3F;`Uz8Y8QA7-&th!BR;s0D{U$PIe&T-9o^XH~LvTvQsWW1Ab<%7D8Yj-_Yx zR-(Y*{=DkyQ|~}4^i%2xT2E46Ns7*`7%jy2mCI{KO14Lq%U?q2CIL=jx+BvZVLRgx>{l5v45jP*waKWpYOVB+g4K0%?F6Zd9)= z=Pkx!9NBT5rADyS6RaCroAo_;Dhu;bF&6kH@enWknHVf53yAQGB5~&uSOr((eAsd!H>SbZ9 z$X;6~??x!VPCV1@0PSrB=KxsS<$;R5&)1KV%YVtAFq0B*+~?T2`pJke#7#1@%f-z^ zPu4TMeIvfx)G3RKx&olkh*>7%`I9~G{*52ONf1uxy+#^E!X!<^uFG(#=8qt*c&0Yx z{;Ni1Xz&ADV9R&dMs15qcM|BK{#(&5t?^Pb#yx!X64CuIH3>N=sq3(tU&Go-^F2{Ve^RvU&=Q3Mhd-I|Nzjrric*Pap?jEc7z*1oI&_Q-FsO+U3U2J~P zoo%N2*r&Pf>sQ`u($fAFM*%ruCQz+jajJww29IJkW3X zwS^$nOeA=&R{zOXr;KjfTM1(Gu-5pZgyt6%#YIff2-CH}8oneLIA+18fVUPElQ)Lr z8|g!ys{wr1-n%t{v&~i3)D?>sQMlqnK4@Ivp_SL}0rWLCO!HeU^$HnFz9 zCgMjZgD0I`8($FGm&XrLFb>+f3v2Y3&Z>3GtfTmFo(bs()Gwl5Xkk`*Ruz6M><3qM zuQa{+sRe!5NWS^&o5~*SesVvX|ELxI8(;f|OtZQKUifd0f!XVv83eKGCbS=7RZa3Q zua^2BEa+o9`>=&6-re_R=#MK%Ka^Q)opOe$49=iDmj(z-$|K4X5pI}edBCz-EJ{b9 z6r|f_g3{RcG`)RO!o1wjTQ*348&7O8FYi*>kl0ze-<&9hY_i=JTJftuvW75H2H^7L zaFAjT>Y=k${i@aKc?GgkPvAu0_^;D2bVsw}w-L%yFILwj+-EIKiK>))*|bR8O4j#5 zF^##dFhHONIKiYu5zPla1u$M>k2hOu9_N|f7H@h$2o}eRK@g!`PxSbGQM*g+zwr~E zTV?^8Wp7Jz!l?}rK?PUZh9mn%fa9z$6?{ch^FRuwf8bKXPbC<{{W1I}@OSNFm8j5( zysf+?zCkgI+1K|5Bc}$L!0pN3n<=zVO_w4tJrQnrds7`LMmBENdFQEdVA2^$PJHi# z`iY%F`5u%HWz2!$>Y{%m@Tp5Ka=Dqt_AUI?& zlZ0KyJKao*HpX>Ihf@EMpZ$qR&w?N;4uQwN!Vmws03otvlCmK}n{n9Sc?++ELo^`6 z^nyA{#^> zg9_{Q-z{Nao%XI8Z@09ga3dSZb(i5gfw%Wp`4K(u<9EmQR+$d`*Ljo+h!9t$o?zD1 zkoxyQC`3l6(lXA6EsO3&$o_{34BBfr5SbqSBTG}|nrpOBWLEe;fpOqI-!PJ}dd9I> zMaVxJgn%fBGDjc~G?nb}O7>~n(!@Zf5vjfTW}(t09BEuqzS=lArk+V= z+RCl0HZ18p`Y75hq`?XEZfBY!Kb(t#X0Zml`}ezxrx<4y1jEu8r;UGzdv=GD6&xu*HhXG8_9ud{U?gP8dKbpM^v0@&W&FJpE>@ITq* zTsH;?!@@loRUuf~*l&ch6|MiQG?=&wk<9Yam?tDf8*y2=DS4m|=W5EyhHdEn#s4tL zN@I%)|7%{Hw!&{&l_0l3+FrGfY7Q4R6+po5Ma1Q1M;mw6-2dR`BSfi~l)Ol6Ie7QA zaq;v2BXAVer1!0t@EA_JacH>~nS@vZ*BtS=L93bjqtLc?Rmg0;W7G8jZq^q!2P9=| zlPk{pAK~4@Y~2g_AKqZpnQ9vPZ(aAS)#T?;7g^0iQUcG0_3EZS&3l414*kxgmWa^t zY+g%2>6Y8&*#X&GJpjLg94u9Jmo-}@Mp>0cHw|f}51z5!KZ|z_P@O?sj_~f?cl3#W zf&^HTWzi6O)CH&-350kHL3HO}rAvkoUjH<4k4r3BAIi7GrPoFBDu31B0u1E#+*`3}kG z3n2M!><8**eEQ29>^)By0J}ysN!xDC{_6odJ3F#t*SHdr_yn3V2mJZ3EaZ|_I;7yBJ3!6ts zE1!^vHdPo1k2UcBSO*Io69F;eT}5pw(n7C#011%Td%SS2KBhE(#GI;5T{XczxQJ`o zZ;^S}2@{w#eDzq3ax4T;yG-_7;m@b+1^0+bCO5p;-Jh*CH8ZzBkMknWKPF@N?HIaX zr+IJZLno5EIy@a7I(l{+GJ0;QFVhBd`eccJl0~J858L@t9Sfe+uDK@e_B^V+=+A12 zU)z}Q2~_pQvx~9fm|$wBkv6aFUu)doNh{@VE^M9;TD(VNMX}gg;-T$U*!F2l0wDg0MmV{^QVE6W$~X-E7+HC(Lyc{}RNc-kJo& z2@6-w@i`|o;r+}st^`S$(wEZOdYN}2ke{smxCxKlaF)7|`NnRK7l`nF^=b-a1I!}n zsrH9fmwrQtV{yFLGM~E&R&aWLl4nv&LB0vY(+d%|b^X4(96D;nVWcjL^0A4ka%ZTi zr)QxCANI-cC1q+4jS~WEocSXwmM|55$cjc!T<`}3gnBd3*8cT1$(eT|W^ykiJ5x6gp72(sr*)Glgp_OE8*w^QF zOq{UZz2cE-dZH_sSVxb}caQAtv-$bX?hsr>JtJW3vVQcT27Jfga~jdYvn?9+>GOd2 z%1PY8fEm2EP$JBGH)h6+R=U?KXvKm(LBR0|gW4ty7aw z0roK^Np|axu&1v@^tRNV%uX7{o-lMRB(%>nz|$C18OS>RY7&{4^nHw%IXHgu7~Fl zp6#7SY!=aeC8#YRsEZ%S^)K;aEQP6x7WR-#iOA~rogsW(+!ZA#hW! zu2^PleEZkRz3!ppdr|N=e$oyvDFU|@f~(Me<9+w+1Gc82;f)=tWR|R>;MtSN3`8+L z3efz2vP92-_BAVNPu>sfn`tT!Z6|Vn*HRii*^Rp|dX(U^nYkleEQ~!14&iJA^DruJ zN(hOrX9!(~3V7`!XgIGCvL^avFPqu@WfA-z{giPyKWe-1_A3d=JeOv=@};rO*4ML6qihmRHpJTpZ<37c(bB>#56^MKktM^K;7|OAp_$ zXPGo<43voRihNoVx^rOvAapMOtiv)v5LVt{sxxR-X74rw9OQ(0*lKc<<3@}k`JN8} zw#+?P>hLCf7Fph)>VvA$gAQuid|OQtfvm&sWWbLhsqV}P+9Qv7pL}rX`rc%il8}H1o zHwSaEmmq@Pc*Ji!81@J*8vhy$3yHn8?z{+c`z&kRtqZnQSy~ElzV_$Sp5VBhVXW~i zUc-n-xe5ytE?<&YRdIMS7aic8YbO2&u|b!YGil1!iChaL=s57TEH6f87i(7??Rx^}=;fB^OywAj%TjaVAB%EPM$;ijmjAq2 z4_bOaR)3uoc`{R2+dGqWy+#k42K}Pg`@wAPz2qMv#yEhcM&KZOsFhAY>U9l4qWg*z zH}=-J9yau1S13Je^l&z%SV^U7Q+e~4_9HT{=~|RE@eSh&apYF&0BP)r^khlXpHYd% zD?y63PSO`($zH1(O`-HX=VAx6hn6h$U5*`Dee6PF`3?WEnq#Jj9DWU+Z(GZGo^Sb{ARy1gw~J9JePnk9%~eqjx)$9#ITl z{tx=KzSN>pkba(dU3&fmtwg`Jd6#OGgfEdG8q&E-fkZ7OD56RS)*YqCpewEI*MKH3 z=Ef~!{<6z@_(;vB7|`x{D7V@AiZ&NnRsS4C{UdBxGXcec|5hmz-svz|yy@>Q7Zvf; zn%aE}N1j=7>H>2(*_z2H(&H3JY8vCZ^Z8VL7`1R24Xg;qYg31LPlgSzeL(@H^z-lP z_18kL(=Gsh<<-vm*rO|@7R9WH;C>yGh}VFyc=^Ey?JG)AMUj+cQf7;;f#LTQ$U~^d z=*h?K`MXm0bi5x@pQq#6aKI^VM3utyaJRkCAXP((^T_K66P8W{v_UPP>P>e$PfB=!RJuCV=+DVtU%gFDB+l_ zEgdCUhCeiQ_}kvVC67n1tvg(GR2880*+1xtsPI{HMTO55qD<}=_ph=%bw~I;#Gmi_ z@lK(Aa^Bp_F8y4Eo3P@^E5-Xuco&$~xS12XXpj5-Oekc|bq#tn*jbs;)$}=>Y3VMJ zWk&QCzk!u!S@=fwo^ogYHmEVJ+l$l;C+qAPt4we|60m_ZtzX4>ELvF+?Lp z?@V!bkCF0symgk_T8icHP3wGxXC6<4YQqm$j2}&Dl7krucu7qWAm=IUy&JL&sx_Rq z6W@H$qltMe36OndUYyJ_3*(KO(l%;Pkt45(fHG<^z2vaXes1kpZ)s1**cEK<%P02| z--3_vUZN8&2%MuUTGo$!rSe1WuX%Xhs z>ifq&PL3Xsv82Mq)#SWb&KF2jx=Iw#*;#efscE;u87Iny_CgRW`ngslpNi+koojwn ziZ@`#@ZXi~4*#I-7^wyw=+w`q!st}N%{^e9O*N&iz-&|Q1n|;r(9sCM)uYSK1Tf=yM8CL zJm2Z9EJspNaoeJ%w8f{Z%NtHi#?5MI893@Cc@Y+Ff(C?|8=tFM;!m_3SOKv^!&{&> zS=v%T2^E3^l<<;U!7|pF@lVEIbKhVKpEm_>MmFh3Ha#SnhQzvgr;yghZoTym$f5Nm zd3y!K-gm89D!z3Ll?lJ^JJgC2^b-n1=|0*vZwnvVhuVl&CC04uVTbJ;S$82pGb_dM zIz#)%ztlSmXB7(r(2nzn`$cIzmm^cmu2E?DvHl%zfE9Kt)AFjw7}Eh+i82Mn%i51P z%^d5=`+Kh|a@Ax{5}~CEh+NNl(@fJ4FZb{tAQVLid1#u+{{Z_9<c_TI&T+F)qFq{( z)LaXDog@!pUE0I7G+MuwWB6&E>8tw10|dDxDcUCxpA&6HA@#Q`I+1ET8E9}$f>z7n zm1n$DDe#WH_httM#J7!#ZuuPsy=q=7a|3ma0ALf{$3VP`tH5+qh8;}Lc(01e@ zGU(>$@8GA&FT%-C0@s8h`4;A7+zG@Mfkci9HR(l*`IUzq+#I6$j}m0GOyGR zv<@jz$2L=6NOv5{p{GywW26VHg&d18X0t-q;VEhftM80GzvHA`+A|9ZC;6HkzvGn+ zJbjlLd>S3**H>^v5&r!Zf^q2|v3cG8188BM(}wr^z&ZN}7oVTxPmlw`%a1nyE5}B> z$p~Gb2;Z%x7lzRrjkBh>0eP^;8h5kKhS$m9Mx2bC>|;(~T@hH$>w+jtT&fK`qxS_= zuE{xQtMtJe4p!NSpJ!5WiYu`620Z~J9_DMum0&t zf^zV53XXXTB=qp#Y|*b{&QdyWF9q*PN#M;Poyi-T^Q|0nFx>T>sa-9!1@^tG4HY>O!e;qm_4U zrvf^)Rsac&E5y2isnOY2t3v6*ea7i~QY?&P%c;3ff=Y$>*aWCbDOCL5B1gqBIP4l! z1bL;4}_j=ikZCm^ja%QmiNnj|Z2Q`BZLfnl#pa0)@O6NcWOw1Nbt)QO(9`b_4$mgEfCdXnlCYWXHO=@g&Phcp z38;ZQl%etsVhx{cN2@;3v8fRjtP2XtoD6w$ont*Erpmn^KNyhpqD zB&2m*ux>U&^qY&#qg7Ye8R*y#ixd(Ha*S+_?ov-$oqusULv@uA7POSws zc#@xM*DPfT{iC(p|3TT=MAC{HTdFL)r+WQQr>?)$%J9L^FN*R+kq=aLlcvH~yhiv9 zGp{O2R9-I!>R_4t+zjK0DE!pnLpFxZ#8s*fPnZFpXQeSMjQDs256|7z`^4L;_!a*g z{3Q|+kPCSHxYZl0$t{l%0{7n-vuKX&MaBy52hM?UXEdCMDTjK2b({gYL=*av3F=>KnK;B*1SCd_r0 zke^%rL;upY1l6v(GOn*M0p)}#vQqkkvWLLUCEWaSvFtSLk*668Q0qE>YnBFt&W)ex zf=#Z{Kmx&aEVlASATvi*W9M|zmyb=iz<2dlFC^92mSi4`l$5Mx_C4Z|8|GZ<{t4~? zoUDT9TK)~V^__-4%bnl7R0fE22rh%iS}cNl?HjViU6hhUYU}JCQbIHDR3Uij1DQNr z)vpE*o&OwpdhN(p7Ly=Ni|^cW{HfHsLDP(oV1Edv6B*Rp>OsYPpAMV)zhyl*Cv0m@ z4!mv5y!|r`(q%fZ^GfHIbm8uwc|a3tk4XxsEmk45vtCdY)lfnbrI+~}wF3l|?1`_e z&~E*55W~2c$GZxG`}cg|hBIDbwg2wXSy3QdS_t&|7TUUa>YU0D!E^&5Y(h9vlzbhu z31v5fu7ntVBz{~kZ7PX=nn({sh4LjxN9{@#RxCt4qu!QjKqFlE$x>`;XVNXsPIUZU z{ipEfl;~$rR68sv%Q$KPkRm_S+qNiK1avSngWq@C@a8q$q7Q>raC4?ua)||bPi2Qq zU0uiLy3Zm505p@8Uyosg zQcW}UYQ8*a#&i^{Hh>^%5Y>%yb^QyH!01ExABNio?1qCI4Sv_E+cKZ~hC_z0gJ;Ti{6Trg0c7rV3PDD&D_UnX zYiLnn^q--@VWlM8nQF8sgA!33xo=0(dd`6Q&M<%~rnW z!>CS$_su9-F>*;Q#nwz%F5U&pPB^o2jAfYIvk>~1&1Bi!SV8uX^=K;&h*k9!`Y!_3aZ*_f(A!-zHGeKYw&U+4NOSKyebgAQuHbQ;Wxt$p?72q z8yFSGt3)3E_OlXIgGn~jd60NNFd%iTtkY;%(GUx?Rw5XS!^PU>TqCaq=ynm*q1D0* zsKTbNN8Lm)eT+4058a0M-qAIfz}Rv%>sgwePre%w;2Y0|U{O@#{Hcq!j9s#%b}vnI zUN&A~bjIQNu!gf*Un_mOIW@4;?YUSqB_7utX8vQ8QD=i@=3?IHW!6gFv-EG+`DM^q zYcQkXQX;EO7}b8fYFb`xZKOW6p+JDQ$it4*3sA=w5C~8DY)q8s;zd8&JDBh;t$5i50XZ#QdW$edwyG=oK$-Cy6t>g=owlYd_4 z|6CcwAHKIRw9e05uNu`JJ5QgzK+B!Gg=TRj2*_my0ZS(g8$M1-a{qH6RB^fj8+RyS zG0nQL!+c=s$qYcw_m^cX1+tZJLnyL(Jw`S*SbD``O1ght*>YSbJE&;&iQU`?Aj8p& zQhi2w$N@TaO;@Q`+)y)VK|s` zm48n&9$V%UW@p3cAKo|oQhRVU!tuP(L@bG$g#8>604dr2Q*avL+}t;JrzWY;V7%7{ z=^S~cB=?2&R1@orj*baiWg@rZ*4jV(j!dbIgKgJI(YTi&8ynA1%EC>>4#b8e;#*Hh zi=q#RF&M&&LM4-w|{_lTJI_EatdQ z_1D#nS1ARK0p)Hz{bt;TS0+0KpUO!%0iJLqv1uD1e+`_CG}+Ot=q&mwsz^*lWG<2qlz-r!wiodU26?$`%TOa1Tabh#Pae||p8PUF+3k1r|Wn2PpcqH@8lsqFkh z?`_ILq#k2a;UsKHNVmE_wfa`xrwDKo4ms>xC#f832>t?Cyp4RJq^x^}J&>*U+y?Wa zH^C%PW_DmN?-v#G8BsO>Gu0@wuMzTr))>(3+wz&D?|BPNaT}1<$RY3yl6~qfF2vXy z`TMUmD|qaydgX~hO{aK%*R|IsVl#7uM$@E6 zYQ4VFniVLvyzX=s^n+>nLqweqvkAzm;|$W@#8!`5Z=mX2XBGzalk%QZhf3&neay4`xvg&W%t+6O^w&Q(`?^mA3eeMDB>-ccSm;SfnDrmMUYjyAq)|(FiW8 z_FgtAY}=uZ=AbREKR0z|Ot4~5>=aPtxLI;tOo(H4@o3GYbzb87ZH7^WV`$iQwR%fj zn05xqLeYkNVRFTJt2#({eB^GmaBc~g+xe|euUlH2R^G;bpCkLXhylWFfJV@X7Yb}} z?+>OX#p<16TucxC`1K74yXlS#_93v=(W7OZJApnLn=(|lWUblN&K8gV`sNX0|8}>6 z0f?irU{k^Gg-A5DBl?VBn5H8R>##h9iANne1=nD>@QVq;$c&wme>;tgDtMh%nuU}j zI$!Ib6PzF8UF=yYC-UOSn3G=p=AC$5YXg@*u|<^7JdvvnE%hRPdqgr)=R^EL%Yy$~ z?-hHh<4F8Vs)bHY#uYZ_8+_~XTTx}_ZFXqX=irytxi-hQzO3RKCG9tba~%;Iz;)~x zX-t#0ACz>G8jG%y37DRg^8dIuTiB%jrsGYt_wSZ}fhQKP%H#WdI-w)`+izt09?J1k zpU{p0%tkIR5`WmK3fl9Hh2=`HO6{1@#a+M{+Nq=r<6-TGgk_(I{WrFWfQW{(@rtf- z_d~*=!O6dZ_Ln*`GaTufZO0JbO1cj_DxEDVrz8pKJ~xycISwc*-B~05ad)D&A`%t} ziy&0Xyf+OBI6Q?(6NE~qV4bC242>`Q*MN6NQg5Ok#z?b-M!yV_2bX>UbW@^Qwy~R z35=H5!Rut1|Ih)wVVQK#2;RrorZY+%+A+cd^Ak(&GmIaMbw*_d%)QF&7cP9=)Q*WX zYC9H6>%FlS;C9Wui`7!hv`{g;%{aaki(QHxX7<0G`9~4SGzS^poEjIH0XqZO#p8cD zv?qpUH1F&%8@%aJ9fv$VQ5=a083Ee@{;qMKS%ntpDD?;q5USYJ8rvD{uj4LWCH zQZmrE@UJ4$`LC7Zr&M1lE*7#jILcXR;a!0ADR+KNJ4UrE@w9MB3E4uJ+nv@vL~@d% zPhlTY_9%&Zvni3Lx*k|?Q5`h<`70!$Iq6!q%D{uQzYOtoX$NKB;n~E7^lC*0<=9$agu5``r4pACG$y~2bt&JY9-6C{;?L%A~;5>pupbwMxEUJ zq%RQipWlMQ+5K0zv3+qGo&&L!; z#i8{C51hAC8yDJ=oTOg3J9$M#9CjV=vRHg()KS86lBzP$cNRR5R~`q}?<;-kb!;5# zU=PU4$J-3MuF5+y{uGq;j=-8`{xOJpHq4a1$hkr)Yh75 z<0e@dK_gk_z3fq2=&2~>G

uOV!HaMX3E`iiXjS(e}08SA~tba@I={DanQSt%NMb zRa=EPa~GpW%CEuhMg3QMh077k@4b!8f@jP!0ri`wQ|fO-qc2hq5x5U`#zPNaHS!oHP|I^ zj!NbD;j&|&tif|eD<2}GAgP-ZSLMT8gZArr_NvGgIBrvX1!(-E&@fo&(qt zJ{m_$%}iZ;;Y`1lM^0&LZMvF_mO7#%LTige-!>n=uDhqHPbO#9$egE$fZpkXp>u~O z0zNy}Fn@K59xFhQNrubEKadQMqrIB02l;)YYrJ}{ft^HSPk1;>UG$?YU?%crX7VOE z9}8$uVD9`z24x9qtolLp@Yk&X`HgSRYq&W|(E+$gqQt8qW>zmZ?#T^$*+~JzoU+h5 zF-y|RkdmJxipB4arUb`@eFV%{VtMMSMsq}EfAN1isq06&2brl=`NiNBABVD@8HzE%|Ie7J+Il6goj zeXxP^jfo_nDi~JqIA6g)D4l4=K7LBTBbA3n>`yhhuVcy2dn;a0LTbktPLSpdsU5Tt zzy29k0{2n*cffHXi1BI{gS9|Jl~eO6LHn<4eeIbk-*gQr5>j)q(@GVa(i^~p+A~ol z$pVACvu*TD1iZSH@sE&6AW|=WD_-qiTnP2d2piS!$zNa64LW19Z{E|Tr8A^<#mURa zf4{5u+VQ0wm-QZ!Pv@u06qG6@PLX^0;}%isz5Z#XABoqldMcbsJ@Di4mm4Sc?b-Ks z=dXl6^)4Or_`d6a=aok}3i1bhp5kE1#M@dK1{e&f#N~hzB_Zn8`Dg+rQr{;*@qMt9)V-d zc9DytsK{RJJ;bHAwhyTHoAdsAa*s6qAIR|Co-7tK?g7aF7*KLK{!~|@021T<#rjUk zDml?!n6voU5cs>A3M3}f12;Vt1Pm~_o5&n53XiuJs>8dLZNu+&%Z(b#{0FPONU z&r98bnfX|fKM1)RAn!U*By1nx9*edYk@+{HERE|XcUJ>q@~@el$mH%S_Mk&Gb(Hg? zn3=O97*O~AFGxNI5`NyehCOB|hv4Qx-zZ78SSbAvjwvCT7Wpp1US@PPs)G2;p+ZBc zZ}QE#q!4+Gc(WwxgvSUnnHf;GfAGP`U7ZWJ5Cy3BX^%2J3}uQX*6JTTKL`7#c18~p zvy5Q2_0XXKO*M%yVI=!KUQN^|U3xATuckD(C=tB3MJ&emSGP4CTHPpL(9L8%cbhEQ zJBoXixA?Aj+%F`0@zOZqH(s&+DU;-;9w!j8y$csv@w5!Fh)gc(x?3%{O{g`dGa?-j|0b@$caC7G3ki!-3kBG;J%5(4WSwN~o zvZo`LzeDb6MF`3wefkeC0B(c!AY{w8<&Ocf19KEfAko;HEf;fF9M^L#G5yQkxb+}; zS8YR%+K1|V{GX7R)%vkm3!Tz?_B9UY6A_T>5XT8|>(`l$Ib`qG>ku<7?Jmg`yc#L_ zuFc`toN>R3nLcE1dbA@^9w~$beV>mf?A`xnmyt~Ii-)FVcr{E%cQN~Jm|hA>Rwpde zk9AFc`~S|i8?LRj1kS6%tLg7!CuBKshKR=URy@DiF>TZ~b;LR1gh&7T8q4ILV`|#p zOvT1B%PIS|++BpeSM(t<6RTq~{&w@`vwXm$Q{=8Vwfy`GYo)cHwskETJMy$f*fH_f z$N*d0_t=ku)h>izw3Uj~ST7SQS>fZGSrXL$jxb4!U;3{-?3=0-(^Mbs+cuhxYWD2~ z-kVj46TE5hY;?UJ6=}N*M9z`AWnNxwMk~?9f&p{0<$P=Wl z3=k49-5q!hytF;VGjJ~ahA#*SE>3V!kveihCEZJ71)nwGYK1T>*<3Vbs(k>?-Qrs9 z{u?!2?tq}n5>NLo(^!V}>>c!%K-&TnH6`Ub{)^z?>OQk_;=K$~<%MAyx zJ@r@#r&Xl*kF)UXNtuTk4pltWIZ%(}z*cv{&yWxG%ZGoaLyct4!-?^w8K!FdP}x>| zmMNKMs}tzI4Xt>(m;^#rTr*KFtNas!k)Llj*x6sYqULdCo^_c#SdjD{ut7#<( z$JW?l-@?~H z%@g{)tNW0)w34XTvLSaTkjYqI1>k;8lKs@?74`~d$^MP#j*r$F*yWp8wA5EfjP<~} zH!t2n#!b;AK}W5IzjzIVlw~exAbJ8)Y%tABKTmx&!bXk&w^?bHuz&RUw_3R^>K%R8 z{)C^f86c_^jUju(yftcoz!d;f1zuilZ&MjOxu7EzRhwZJOB8ulVwiXSASO`TS5P~G zl}VYucRV1^#wO)hU-CEj^itr7y7ruBtF>8`UXV5M=8f@)Aml4zkPHF(-Q7lX=dDVA z4LD{t;yIM6+IuZJ_=dwioTsYu57zBAU9k%Qa35HtQMESg+{8cvgDNCu%^A=-%Yu_9>)G| zU=_Q=M2IQfruV0++kni)uG^mq94jU?3>@SA_dpY1GzZu*U2J>0-M!1}4%#zVe*RzO zI#(OgQwOM2-@*A3PFu)K^VpMXQC;{f@d*ItIF^Tw6p zgKq^VFu;#9os#)Ziey~zmfHr*2Yu1!M$f3Uv5rK*1&1d;soYYm)L_b}_ zg!?M7MUDU*23O#!7>C|YuYa|GVst31O*+!m+K?>;f;YdrV|~;zX?LzTsCg3Va=m6a zuL{#A8Z5B{{@YsJ4U+!niRf;?y3${Ox?5Fp8H5zlKO%_Q0w=UH5Q#iGs6!NW@K+27 zIsbz8R3P;8mwo3w&-Ohz9Rs`}wXX=d*gV5T8=7@|wmvN4?wEAHn>Z;evH{EfeLL94 z5@rt^dc*XK-6;3Q6rU5V3X8yV;e6M)Gj!1D5$Bz4)KMKDSa{%SGtf;7*l=(b=B8LV z^V>5qe*NqOH4t)~8DJD!*xBk%3SG8Su`;1qY(bGNI>dBX!VE<=>S&K~4@?xJI;k2g z|AQpfZ^T`-+_9`3I8nPOh{NjEuBe@=TP&m97B|j3qS`Uum)@>fRr{bH)8oP|S3yH! z$oq4kKx9`Uf@8YoVwI)(w2T~AWMLhV%WXt?==P|YK4eiiUi@NN_c~iGuJ-%cB(utm zzIIu~4DO?#7@IQ}Ws0#``224sCm%SQtRv;q+JoddRg@@S<{WWKxUd3_$rN+)by!~# z$op@keMHo5JqnYbN5mLs4I_Kmq#a>12^=#@B+s@uu%^EcfL2*0OjgEvQMX7*Mars#J)*qsE+%IJh(ZoP6d3OEkloG+kLB?opBw|>b3PE6s%(PM zyViewMov8uFcf@;@b)+>Bg!Hljwxk3%2n+gLY5Nar*@5z|&KGuW*O0c<;y`VsPs<8t;5qoL zAfs$agReie(ppKe$^QqC{aF7$K$ZX@VNZWXbFcM!cIc&DXwQH(o?2I1`rqWdkxWcd zYx?82Z|0%9nQsM^!GQF`7&3VW5x`a!iQ2VrinaJGxSacbbbl?`Z^cq7vS7`4roai# zZ%1Gl30Xpis4oL6f-}%MVd4}#e_-kAiF-46*|uc$sedUubJXD zm*WKXC=RS{x53;H;I#!BSLl`ULi~mI_~A6Zv8ffLzYmxKuPNY_wz$PE#k50mD9Y#5T$7g>>k)SeB4`0}|Hl)>&-+xQE-tZvI7wkSvAb8@={M>Q_dKm> zI->Le82a;i&BYrN(Q9%%rZEU<2Z`jm6DJpj#3$lZ;f*vz%ySfQPH`7*O&9%2(TJEy zZb66^2pMX!S(H>;J~N4w4+~uNb^elZaB*w)*_QMl7h5b`(t;ifJvRG9x84QGO94w` zJ)6LFlw=S1MT*@hjSfDy{=#BE8Kc zjo0zA+=h1`WNKaC#{l!67nS?RF@2l)SxGQ|RM8xe7!x zt<1+kffnU*TlVDHgFwM`)t3ksRu<@R=sGy+jcQ?-{FT=UncmkT4m)~pyE|~N?sz{L z2OfRBY^vmn0j?(iQjX8^eo()u?PL11JLR3-etM#D&`XGvem_M}YlO!0zFhBvDN)tSiy&8m55A#n32Hp67w6xLw#-riU( za7?7CMg6^cJUa>;lZQw!YZ#R+2BAQUu!#i1B)Rui4+5)oKM_Ibl`KI#)Zx}{^iy%6 zAS8mVizx9n`1K6{@}k8o_E4tZ)&pD6BE}q{ZBqej$gf*D(>L5V#+$6$&ncq4D+0%G z)`9cR`4s^yaBR2T#DNCgeYxIMFoSq8Pp;r8|kHqArs%pbr3TDT5?>K=E8+ap_FGat+q0O@Q^txc4@^E~iU zyL$qo?;!iC=w9cxYajymK1hE4-DzxTBd!nlqEllF?_&3^RA&IRGm6NnIzL@EE|FXJ zz?eC8Qy@hK-Eii8SJY+$#W(sBE&p`L)Cy2((*JJVyG6(>-3rMN30_t_4N;LATI9*} zT5Nl!Tauix9%PPmZt(kBWk}3g;Vsol;qsT;PKGl7pl23tOXN>3=FhA)W&km}*|l&= zrvFx(Mn(Cup@25aW6N(f02_*qWHtb+6;U8FIqgA7AfaCFZD}pok$L#;^7Rodj6++4 zepRJ3@b6E}KuD`=>gEzUl|f@#u_ZfsD22?ITBXLwoiFYtUU#yJy1N58?b;bXN|u6z zdXAHZIOCOi!#-``Yn6~8Q=%Qmt;gG`9|}tU=#7yrFib$57Yx1#=HD}vxxce&&o_l0 z^ld@f!kdl0_06=8z+gWoSX>1X?}wXYdrPTY4ooFA-X_Sd+92}$_ju@YfM!UCmFN;j zNKbV$-~HTEk}eGW5%IcYhSA= zQIQH;x>U=(mRu%P&)Ds@4Dw+8>+j}UrXS;rkspj~dAfS)0fg9B+A{+MJqGHAo!Gmv z7i9u2wUa7*z%gGO)C+|r=*Vn*R(pKGZncm+jh}Z4H4AmR0RZBURWpr{&vW!?s>}q_ zOE$00(SWB^GTbIodAZdNKb*n*~mGQXPBu!TZDEN9Ap!1n!0z$m3Mab54Pkn zb8J-lMj{6QIL6+%w>!%&Tq|xH3w+Q)T$zb{ZRC0HN+NC{e`d`k@VV-J)m~VsqK}L3 zKI=%O|NMr(0dY5w;HmaTt^=_zS!l;_NPG+G(Sf+C>~ zV6RaFNK9njC-@)EO?REi&3*AeiD{WCUU;OZB!KY&g!VB))5p2fi?G*F_66s%{+Pe#!Ypbge;(7w}3Q2dQ z?_!o0!;O00v-f?wFQY@f)YN{(g3+&p9R7Fm2DVYw`CD5cdMzP~y<25{UF}p<-){=T z^t2G%2y;OFi^f;YTBIlWOUB^h%M_@R#t84U-5roDkOMFG8a7YkRFa)MLCCtOE_h1elXcpY_zam~ zewF^vpaXE09Bf4&iDRm?rh~mh)->|69Zem=gk%vHqR};%nt`izAEmo;53xC(Dc4 zlLS>ZYh^`8GI-+Xo#A`BS#mkRZX=EiBu%;NN^3qX1AoBjvF==&VPxff?k@@@U;C#m z394N#DoN_5eq5pI)+``<14-KxG@M*-%>5C5+l4n_PT3N(nI|WG)oR@@jyj*$nXw5j zDrtxX7)#7As!hqrccQGbL;1epMc+Xm@49gI)Xhvk{jEk?h|)<{V$vn916BY%UVmOi zs;D!6#yE^f<`vSuG7`ZyBb;AApa)ReeoCVU@~O+p_U?E1vEK*%1?@Y#MWacg(ev1` zc@AjOO9XjASNniKg#0y!lS6`#3#1kc)@a&S`r8TC01+2mdY)xuFtQG?2XAeJiA?;I zB=yPWJGrg|lgbOKUqOcCw0o+koe*F_;ybWXzT-k4>7J|IKbSugEHdl8JN%kbD_bqs z<1xQC+N#A(i3n?0R6@dja4O((iX?&AIXG`-&$4^_8{iWgCqIx3`UUM%Lw*Kr6(ei^ zG+IomNFs}}a67-cU94fPC{@vt87geqj#S-cq?&jxZ?!)J#RSt$;vSgHBP`n0DWUvq zgdlq)fe@N1SwhQJye^`?0w&UdXGYhP1lGm1o{b=5r;W4LI7-}mSOp8koCMjS6#w}@ zbi&%t!;L(Gbpm9j^~1*Fmk}`&b73VRo9^d_8D}%VFK}ns_cs0y4S^^XJ0Zq0)x4v| z5B;nmyn?SyFTgR%uiqTDJoGc}!u5s=borXhd()P|hfc$iC!)tLu|9p;dj`9-3(K6i z58lZjw}JdB67*w??@W>Y%`B6*@K!`7ld4hRE$EX?6k;koF|8^gXXgmr zCq=t!{ZyCC?2~>8TX|h1g|6skqrfKXzMOw{k`x?@mquwg< z5g8~SJPqdlxWnrKY9_Z9fSlV5Is~Rgv~4$l;NO(B=eFLo8ZZ0@GHWZ{ z)OG%@5nn)8sl)gie$X|*{J(fiHBMaI><&;!i9likA-#Jv_&4_1*MDVLR8zU7?}YgO)^gvf5>@|Fv zk)^s6w^(;>ED~rhIxOfE*zq8n>`IxnJ6R32Mw-0sjvPK=3Vudg4L^{Rf>3(1@&DFE77l`;(LL< z+gRoe5R&s3Wo&q9FYa+{F-SXjXKvO6R~OOtzk+xAIzBMG0hvt61&|aJU~;3|@7FfO z>U!$=|5d1QFy)1kiPB%{?*VjfIO~4-pS;j+wtQfo>O9fAdE-}=#!6o_cE1z)Hqzwk zMeZd9SBFh2vX`Nxf(U35DeSda$Q4#yP~RPNh|_+VQH;+TQyp^PUav~K6F{NBB@A z(AbJhosT@@RQp=P8jNCPR~PfA_cleW@f%q5L~~qP!PqT_4xQE2ugdyMk-HZ^0u6 zWA?#;JAXR&=%1>Xqctf`a@{e^=OcGqXlFVRc4q9elNgryk6+9zT`@)cg*A+UC3ue> zt#>q%d2fT3V&+=`8NBQThgRc#QRKtbKPY%bofdRMgUTbXn#V7R< zb-{1x>sGRXiQHbhOjauG-*ilOo$0)iY1?^h)GuGn0-*ETP zdU-Rg46ghC&~)zMO!xmErMy{dv8fkH>Q*`{#kNeYcU~pkBcX zI$53YXUNSP)pyp0Zrhp>W_J8W>1CtJ?x!p&zbjFcEo+_ualYAvbu)^?i_EiXUcGH9 zA0g-{S5lh1gsB^eee4`Llzr_Eu6H;*+zd`mf$`l(cyUS|f?;Kwc}QZjCHInUbETi} zMlFBlm7#7ja8CMi@o90+TU?Pa80-6!WH#mOwWrc99Fw!8Z|1JqDBMA>`E&^}(S6Mg z0=vrwh@!y&q({bh$bpyFDPGi#PCb&~tsLmV!U7uJBv1ktQkHSO#+B5Daj@b4Xqu6W z#49BFnVPnIZm-oJ1Aco7_h&PQ8AQ&zWXb)|2Z$k|dtV0kC!(9mJz)OPwtElj!qf0y zmMjin^Zkh;?zBP9&;64p$+9A$ixz~k=s~VMt*vnPZ4F-yq-^y3?wjCm;QU|_N$XX~|F7xd3h%HL!Ow(v^to2loaVha%_@v;s_aNOVPg$l#% z@x!x+kcxVt*|qC0y%1dzeZqv5dM66k8nu=IEbAfgRJfC-IpDNe=9oy)*Z27+p+ono zogqAIqo!Sx1f)QtmldwtWNGKGT=x2rW~XsfMS9Q(M|;xPHz6FeTj!LGu1ab42qQN$ zrq?EZK96N4csc70ol!z{+amSWr%WlLGwA6LXn_#GL%J^$PeJu+B1<1vDVq5WVRTbo zl7JXxv`xj!%Ikv*l+nIB0W+vgz>MU-D($r&+9M0?+M~uVRdKI*E`&~Th?aWtacT>0 zod;*X=UNu3EuESsncZILHPWPAM0g%t(0RDAC|S#iGu88@R$G6-~0v4v; z)#SJn1Guf|J*Jc0C_bg!x3$p5m6`Pt_3p+#dGolP%&+=WnLZDS?>Z%>T%=ZMhuE2yQsphEoJ6i@G%im74Pw%?XELS`by zYdP`)oUr4XJe_x5vN4UW$Q; z31-{eR%NO)Q6n9DZJBG7EK1>I&R5;k7?n{mLTpJBHW9%0CS_;ROi<4LTq=%1a>q zb7+`@`-F$H=1;jZQb(?4)qcaN@5qiYA(3gq;B$yUbbj*T!u_qw+x&Af;W3^lJFdiv$@M)zrxiW_B<%%7EkL9i)j|?Q>XZjIb>WyHU+Zxmk7H% zr4>(8xtD&#jiyiJc1!^{Z}H5)U*{mQ?}~5?Y7wJ;3C#Ffv3H?4=~GwMZRAi}tA%)X z1e%!z(C^9II2KlJ$`-Ea2fBMNLWE@v)yEE`gOD6z14%rrq(l7A1Y7P@tMmN;3H*At z#q@_D8%*(WpPiL*j88)=ns0!-hZmmA#;?2ln5I9k@krCO>-35>v9xj>xND}(i_#=7^0J!~iQ=WXv3PZ zypC1ZVUw~c4Odrgga{~bH1N`_HNt?|e@1qid~}2JTL-|XKS}1#M)D0HE2)U3S!cww zR68&HyhqWN-tN_aa2zWvLiFLQop6Ccq=D?iKo{VgHVCi*M}AZ+#v|<>`6MOgJ}*7S z^&wVw+C-$n;snlK;VwkeQ|DmswoFPL*tF%=0G9hy$sO|7#<>2#RTeXC`ng}c*@q?= zl^Z9sOFlpC2(0EeiFn!EmH65bnjG{_&b?23{X`3SB|LgLsS5_uJUnn;JUtOU7Jn`6 zYmbd{-e18N4Y)ItWGJf;XMo@R&T)yA$OE@bL%2!SM{J8I9y>!kg!P;FxF1($4|sIz zhJ&hm9>}GDMAD(xB_}Y|_3*-b&7a{*KsV==1U~kMZ^5K6M%24_Eb;cXgKKR}(BdC< zQb87y{9l4<$elrGXjRbd{fA5MB3ms_OdOg@^7N*^EZ^+NT_u)EfDGSM&VK}H#SI@E zl;r%WW8@(|(11sVMk8ek_!B`#er}-iz_vLte+ARh%LVd5GK$d#6mKn%qo2dQFQe&;G_HAWl4{3ZKl&+Q$7Hi zT9gg^Z5lph)0e;-TgC+(@ymg_6g};Nva*J5?K~l_#r$zG%FjMS-iudXit{~>m?^h^ zTVsJtZA|Cq=dHXyjHJ%|;I~nSZUu^8a1V1M(a#Mrn?#jCkG2_69v3-z&w?LkzL#rF z+Gaq#;8jDwoa)bR>hig|#%OZ^x4MXt3+6XkODO>jakA#`YNEb8<~yK5S*kMDE!`CT z*Ul2xP=gT8mT`JoQghe$>vXeM;J+w?ZV`9M6G|*<*~_dN-9P>bkvnKs$rWC61)wGw z#ueq?`ZK8g#*9JpL<>8*;#Gfe7iTt*yL^0qj^GK`>OOFhdbl7Qffrhck-Q2VoE#YJ zB^GGa#B>$!_P~d*TMN*KBvk6wzDVmUFLhi{Yke1|g+y~U#QciI49DEk>O*5EtWeES z1vt>`^LuhsgQh0F2HSv4!E?WK* zKbE4ce>QIA%4p`PW|0Ijv!%bhbb>UW*sy6b>8XA~xv3*%Lx};!a$dfoZKZo*4|5HY zBhtIvVbvb*A3@XZmRbGe7~KgzCkjp56*eQga(WHF9iMosHlMZ86Vqm!jo3Q8e5epj{d z5IiOr`!)_3kI8%~JAjLc44&2luh2{*(F69apUj9xcAQ1@Xyt%c^lMnwkju(oxU}?c zfyR)p)q{W#g%^8VDe=0mT|C1Zf>eKm{F3vAk$+V3{!`U1)wm$lE_%{_UM;7u>feHH z#BHffu_+Zb)okmMwk6YE`kK4mV;k%8>HJZQ6;Foje$|aUaM|4`P6Wd;C{qL%xUDpX zh8soA{&Xmc6XSf_S2U^A%Kou)tSX?sq}FYhm)1ej3BLHFidtY&vH;B{++VCQowf4j zNOEd+7_ z`5tYGwp_+F^dOhEd0d=XCkQefE4)36J(j2x%dD5X@S@|TSZ1%t^$3Rrksl&AI3hlP zOkqhgZWGh{VHoZ5{VxUQ-(CCueZcHZYb&wO+o9y6yAT?p!4w&~-@SD@>PpnF4!NtS zL9uynIDjRJXWQr8O-WsT+%V@VD|#bCY=NI7hx=~FSxzEBRkb{_1>M_e)%;WY@8x%h znCc=-Jg6D!{#a~HB+d&~TKv~D$zPe*!Afm2=%)q5vz>5JBA9<&chD_e0=Hr|T5-pc zo*BF$CG3B#t777Yxo&8qdpmw}#%ahYlI#~cktORTseR%X=i@eA49Pu>syi&NQ_x4g zo-Tv$aUPe36n^LyMzz{Q?RpRB$cO%FCwczIehkO-_GFk@4zBkO!+ak=#^=X9UAPv~ z^Mmuwl{Yb-Pg|B~I-wkuA@-rR_DE7(xfyV`qwg6{Muy5aLoq%yF?lZ41vA8xCsJzJUyB zxCV~%X!(S?uZN_RSg@oi)Ai%6MMdN=@<4M5oRgcPae@AlW%&d*ZnDdzciX$MSq5Fz!=VV&7(l z`WREG>trG2YvG=)-UEO^p=VJA?;K?{hD3kSac(0`!{G}gKL9g&4iHBYdIaeU`~lZQc78b>T{`^lrb#mHlvJM_zeh-mcAPvx`}?u54ANk~T?Flt639ug z@$hCf6G3%}&{SE@Pjj}u$ForE*|mG}7Sw<-tQL3rZCBDY@zfUJkSav(uj#Hxm)^i$ z)ke~CBwE1EFHfPq`XP^RDADN_T<`RY8_Z+hrwz?rzxvhWk090MER6Y&K&*aA-HYLJ zvmP6twetf$t(aF+vrQ3AZBCIT0omz*%fjs46B{Dja|RQGnvpg8kI0ei*> zgf~|Bfw#Z@8b17RD`E0Wl;A=+Mw6sYzYQHaeWFbuTt@GE;*tvmMFxZHzxK=bw+QEb z5!GHu13=fHpkhfZVMSNBEZ(uIzquoq)!mzF8|MBPt}_~0Hwd+Lc6NM}!@1)8qe!mE z>PHT}j42bt3bR>xvd?*qvW9TF5 z+jEkrAZw}N$lzaDslVa}oMxIpam%R;W;zkaFC})li#rE{&8?%+uvewB(=Y9h5@~bB z@oJg_&HDWrwz%V$0KGtLSr3Nnk~9;veTcr4OzY;z>t2l0n) z|Kn!gK}2_$tGt^K{4M~lX+SslWj~hw>q%X@a-rd0NS??|#6*t(Seg*B9r^es`e;#l zINe{uBqAsRY9;vNm;x~BBKrZhWb|X^nM#%@QJ=7`s{HSry$148{HX{J2l5|t2Q?Tf zloc~~PUh>u%l%pYcDvhJ+qo^pw%1Vxmaf!S!Xe~~j6S`czl=z#Tr{!;;%*#ii6pM- zRjC_na!e11!{}vc{r_MyEHMJ~BvX_JSiP-W(L5@qplHvB)kA{d!Dw( z(wt!)uP^{swm!QD(rCzQ#9S}%P2VG~&Wp~F;%caMMsm6VmD$sc0>@6dE@k9h-3L)_ zFV{#qjvk>^U1CCh>t_Hxh!qxu6{TZw{COpFn9eh7<6~6?eu^3&=@Z=Z%!3}{@t@tM zL9$l-__tQMAe{03vIW}Ry&zQ zNd;k08C+-Y#vO18+;Kv8%6`2Q+DJTL3QhtM=|>*5HN-8`rBULPy09M-r z{r3(T)5SXwS{x_mw(~3BhHARx^#t~Ml+lpUlf140il4lHD2S;f(IVPns8Gn~wD$#o zC3{V|Pc+znsz}Q1w-rmJM@9Ov9h8++$N3-gY7WJfvyY2!*8LK?nAr3|EwFbCq&_Xk zs=OGCbu8Ej3;$u@e!(qF^Xy6X(dhKn`mm9(LHV=e6L;n8=6fcc*G=3m#GoTQB8u(? zu@W`EG=#TR&_reNLS}>Pwd~7wSVpl|NCfr)2tSh%V>c9VLvCj0jE^wN??5p!d-s#p$_u3A-H4T3mo%XMt(1jR*JldzW0ONANMkMx z6EJd*(Q`(BD$W^iA!jx%URA{DC}JM#a~^DPRxbJJQho47_&gNymdAI-4UMqE>^JfUF{^w}9F zlrk^bD2!s(5ykDx+;~J4N+-J&xoNd?L#^5d$RycecC^mjFqf-&;EHQK#I>ZtUYb`L zSywVFUH1|T$I;{UfR)Owhh}Fy;${eV*)j-+*MKeG*+LIUL$KLJ(W6u?s2m8Cu6c0gOrWPqC;AXfb@vM zv6ky7+~>ksFUKOwie)o`ddsSVT8rsc@z32EgH-6V#b;ey;5w-Gno2Vs`S-*|9Abf^ ztb#^;5@*20GYidVmQ*IL)0EldrH}d#U21_4!UeU7_9|_b%Yt$T>BOR*6MbIvFp)ZE zRK+~^P&)8KA4m<7Ejr?AAo7OE2EXNWL&WxbS~vSCxP?U%JOWJ&l}6Ug9N~N+MPq08 zama=B)D4Lcr@Dxv6ZhgFURZ9=Rg9v&D50k|=!bR{{tkIYb0sI>Xjik4`P&7^MfOj1 zeDVI|ATO}28AuOgKM)P=h+;pHc$Bjo23+Si4Y;et0Ciyzbfio$KS80^pT7*{G#iEf zC%K@-_|ACD?>^#?WsOxg0A_f{($^!>TLNsc zA5Z-z2K58a2X+7+hiTrt7HHIcVDx!peUV{#eRtSWu=rCEpAwN$Ua`i7?(c5Li@1il=R@kMPTj`D$iGoos1G&oKY4p0LKI z|2-j`nk3BlJJTm7`=v&jX}BmaW369LJ9~HWu00@_m)o#&-Imp#5qv=PdJ($ffR$<% z2QVXu54H&0(HbCMLRk`dgadfe0TWz&q$U5QinW1 z<%p!MwiW$!R-18~^LCh!jCsRfCI#M;2YE1gx)=vgkf3W_0$n?$Aokg0uua)IEXo8K zqlmir$0beIo)!wy>JJ!d;fg1t#Ym+S-OHcfIDs3-W?t8Q(E}KC|4euvMHqY#kZ#*I zY4OnpH@P5al^k&}0YbyDPgTq%9c@ie?dOleP)V;U32+IF|7eK6CFTc49`**JyPD)^7wA(GZ{n0$QK_3^yvQ=p&(IslHTEbb} zo3{v6U4w|qmq?yO{&YAq44-1dD?Zt4uE zCG)XsuqAM&6;Kc{-`Y85MQJl_Cr=NRxF!4Nqxw7sziD&*Ay*}-&6*Gx{%g7JRg5}S zYC`UM`fh~l!!4%Q<`1v1wfeG^cU4x_ddEqEvChR%gBx-M0cX8<{o1;l?~%b4sukWn zPfY_kt%X|DnRC#rVOqkO!XQW?Yf41~tE8E7wm}<#`3maaZf%T2^;8%KR;!u5PDQna zN%bk=XPm&)<(GDNwnHEKJW86e^=$bCBxK<~+v!yFVu&{z;P)I&TKw$G1$yvEIX@gl zw$>%|I8aQT+df|zG{$K}yHif>Y+R{n9mK`O`NVhGHf)BaYXwOP`{iQ>FrNwP`jbNk z1~vCk%KiEOzoT`01o7TP(T; zK0Kih+!N^(xfFDXzb=G5$qprtrJIY}L|l;Odj4uz82-61@U+)H_D+z*v%C1JM0LaN z(HuzFVN0vv3{x1gm)-jOL!BI|ts@Mx)i7sqe&H-Sy`k!OCOnj7g|Ik;F|4_Z--ANw zKn-(rz-K-6KhVu54h%t^2p)@LA!wwfy}JC2QJH^!v@XS$Rd`oka^0flmU(;}1m&in z`a?0bXeQ&QXP8nwGnG*6qpL7awiV9w841WYie2BLhx zsl7c3QFaD^7GvUhSMCr6^&woV8g$5Unj-GaNe~NQv`cii&WWnqAeiJ`WZL|r{Q{z; z&c!g&mLe^xJPPC?XooQkW(9ou)0oGa%vsB}5+5l!FiSzxM){Aq2(n+7Jv z0ar}`6g$5;=w|;#69TR`4(E6%-qvCu;VZXZQf|2|CoZ1Ud*x+RgZOek*<3BQ5$6jp!@P6oe*ce6DAWGVLfS4erk?4eTSRCkH5cfZs%K~bp z>ZGy}%D}5k?^{dqnTP!N!--`4lZU_w)9Gvb){f`1oI?+oF(&&C?P(m?9jb@$HFqks zpW^M8CowgyHg{3;w?-4YDD)$kN8|%@GppH%?=nYRLl2Ap$vJ|H%rd9AL{zKAR1H5n=VG0_fWEX}> zu##HfA2K2FW$+RA);Z}npR2`y=aYye+#uZo`65lORFknjrO9pkYkdGV3E&Aa>IBIk zmmcL@GY;wn{j|=yyxvsx07Pzg1`Xx7VqlWfs)XO$AGLt2d)8pBMy_}Ft5Aa3T+Tp!Y zk2u*|9)oZWxb_J9RAd!>mB57#a|O(3r2E@Vve^*1X5CP$@`08^f>Gdx%+8}Y<{OR4 z0lrdf$ADgp6?<02$1kb5T=%(=#ONhlU00cTA*4KKw=$>a6vFdkP_ z@F55J4|I4QBjvNj(B!%#xv93|i`Y5{=OA|5ce5b65`lT#t}S9{ty{S-qIkYl1AcaT z@9p(4!d4pq8*W7reXwDq#Ao()C7lth;`OWhLmWxb(_LwDzs4+z6c<9AaYV;Tfp z?oROX)&1LYF81&`Z6Spx@IR#40)bqOBiE=xQ5P_s6)1c1Bm;i z;{_#r$f+|B*Bp4B;HwPDHydW+f?dPbvW_9BTi!osHE@lV)eX_ zqe|_psS=B^am6rr@#j;b*ZNDiewJu2t}jc3aMJ)7a4~DWnJg|gYG3A(Fc(ZOtVwhW zU;hC0pd|K~UoY4%;ch(sN{&2nW++eWZk-!xql-GpmB!S?;X2^lYe<9+cKF!3QY8JA zS*}&=*r)(dtr_;L^cd3_;{${Nw{8*B!;WS7F zviZ?OwTvYk`YR@FZ^#&VtoQY|{KDh#5hgb8jDEwZHg z_O#>*TBP4%UD>QAhom@XM(-&dVvPp&wihlcu1cQjJtOFy@I$&bWA4$L9}3uSN0|mq z*=|wqR?%|Td{J4e#cRWsfi$S-jg=cZEC1fur@s_4CWz#w&VwxGT+y(260(T{hVJ(G zO`i$oZ=Qv1&#_?g3wBog?(Z)*9{XmCdvm?+f8oBaeYO-DXFlFr+W~aJCs zMx`NeQ7iRV`pWNasmm|H$q=^&oq{aSOYn}K#&R1DNq~IHbzQgoPnRW40 z-?q)R(^b=01M$_2%(D}e@pcN6Ck?$()rryA=3I;8g_r1d%k6S?2<9n^(PN8ItGHA7 zGB>=|#ltvXQ7Q$Vf=UFHT-!%VG-uzRfP1inNQ_1zF*ygCK{Oc<1g@IgHq3XU?N~iZ zn4omzBqP_9!@i^<6m$tUuiB^=GB0aa!5=8Sc;ik>8n(~m*CEDP$rx4}i+I;MbVdPE z(Qmzf|B4cOLGvMpeL?)a_O_sivLa;T9MwG+5oD0&{q_`!^(?smMBcM#+c-QslN2Cm z9{8ZYuC2Rrdi=$qIuy;hrXO_B(am{g-FgqvNLa{sUnwny^LYFTA-nY{+yecbo7qfF-M0sM zilSyKU$us2e|qhdd0EqncprE~=dpj#))Mnbe?vjC@MJc~JX8?sJ=H|79CKR!O#aU6s(_-VjuezXUUjS z-;A$Kj$F;F+gd)2w)a9r4f5w3O%8Fn(9ou~W(%tB6BE$Hxng;>9`x2tot>g9X#w|F zzsCNYi%v~y#qV`NO0|)n#9rk?H+6QzRy;_3&%=QFAL+tn`M2Y@2}?92r6*St5?jFpn5|Or7flikdv0zmFIPq2$0T?&*7jD{ zlEahUDgG3(1gDI1Q^$iCK>P%-;8(x;gtR^RuJkvtPQ`<)*0Yp75ob|NmcT!Nw&U{W zP_^!zJr&pFt()u@)5M%(iXXFDA&i&pIe}d6OSzuQmNF~f?KdLC^{vlIbh*g2+?D-k zLY772rX&h+0x|K9uZP6J?wj^NeNp!tC-8CycYoVVlLXNmqxRYSD`nur>Fw`OYqOiO@}E_^16>A=)2Q$+uu}v zw<9KZbkM7D@zKlfr%s7Ao{*p;g9yAF0(InarH{dqvGQn(Z|1iC_=dh^jiBs^Ff>CV zokw=>)sMU(87omj#or-!7tm1F9t*nfd#(6w0Xq&;b8D|EOj0=;q-^&m8NyvOJYN`0 z#Ox?T%<;mZTJC~-Xnq7=$_Y8fN?_bWj{lXF`O;j*Hi&j5%6w)2w`4Loz}4cO>=_~= ztlT$g(^y7&nhaZzpX{UT<*NMlZ4}OfV79ZIXLl&YZ}xsW|5dtz2Z{?2v+8jb*%s7% zMndYy1NayEOW1qcdp6+Wqz@?D58RZP#Z&uH!YQ^zGiP!xQm67M$Mqv@lvkAs!wP+)zzXr)no73cVHHa9ca)+8oOf$2t;z@qe&vCD+~; zj#xdw6`AZf=29)3e}9M+gh2I4q-WOpepj;{xd2w#=XdS%+aUW)h~TC?y6&$)EBD+h z3EiDIjK+S~*zPxHc1Sv?Ku2v}kI!dy3H-{tJ-56F``d(C_k>RtY@T%JrXlb9OYq!K zW=BT=38Aap4x|^lUE~Vx5yuFF4(W&7_Uqa~sG!-dwy0<68olf63zYS@W~j)(@$Jy@ z@@Nd~6&H^B3dPU7Q4!`o!A+AY=6*MXCU25-x=sQL&!<@Jv)}5f9)jolc;$}X-@&<584IrXE)v=|5*8LC5O+>!gZEtR`1I^R!^Sr zXiU0BlS?ftX~kFz6GkVyg&GkCn@1zxfJR7l45%Ob-))_-tU~{+n2Retq2XVLP6FaU zR|BbkCr9tFvMG!{xUM6k(Di*oPSsiGDAdB5-&?%B1!LmbGA)FaL<{La2||N8an_iW zwUNidT77G+FKbW6s?iIL9zQJhk4TRzyq`}g@}}RW(gNF*OlnRp_o|@ITGm>>fDUz) zd6t1_(OdidI46n7?*lnfoTQ%00 z6!k-p^ynS2?c|OGCqVNp*oWMbwNJ;X+FQC;&*3)(U`BEu(x5-*vY-Nwao1+eNGbKpOW2>iJv4v&hhbnVJh}& zb}$1N)>*ohz1q;!gDe_X4lT}GLUor2R#U4Pm3;Z0yuZP%p%G4~7Yg{W{r?>a3 z>rMQsw;L4vDukp4 z;BKgRY{&8xh+o%FSPV^eb7VevC|b^$-DoAOK(v+tiyw-J=0RFqTf3TLra2}WeX@2h zC?~I1@Jm;tSP@obZU}JYM0AYjIS*ciPub9eqaG4cg$^pB^EI18trCul&6fnu?)69% z&ZDo*@V)PeBG_=LDfuC7ZVoZ0V_KO=*)0%_`obiNJ=irJ?lwm$;4S*aLgUXbhR1WmMGqI3lO>AlSikFPdZ_Czo_Q7i~aV zKn?mmEIg^2GII_9sikWLm$Y^9u7DHajC}4j%Nkfwb{qs;VjI~;gW~@S^h}qHU4)bl zW6zm(eIf*j<5EJ{mEu<>6Ag1b=Q9z*=6$NNUW_;Ti*X+GS8mg@KRaj+n1@({>weBPfbr?_Sj_V#CE$b#uWM?I_`Tssf13TAD@@G=SRdZek;p| zwL^>dHpj8**R;UCF_ZHVEwu*0(bd1#$7Y}sz4R9VY8PJ zb?hlL^y)jbfO*d3Trq-CX`)>37zOrg&;a5)^sV5u=7iCk623X0mfK)>q2*rKW}$#( z*rC6y=|-g0X7BPdLR}vViOC6#Ro5WXWA0*t>$;>ZF(!J$O}FNS`EQZ(Fhbt2*@_V| z^rxP^=Dn@=KHX8qgv)@zk?FBIYMgWE zH|PzoC%b=br1?w9GBY4jm*S6ddnR%V`cpSak#hZK^s{%l=k1!Y5YW5+dgKQ=M2XVl z@26k_iR}LnFn_rV$D|F!97JG%56=VwA>rXm-PzgCZbi&zQ6ikcQYQ?stwwG|#TBlG zE*CaMo`Zo!W+&2a6`u^*DyCGQ|8aCmQ5=yXqiojv#4kwf`%F*0{7P#8@iP3J$ePt1 zu1JW4Ibvd47%`uL2$`~w7AI)&|9Qh<^d%7l{WTa^I~nJc;^~rPHQ0a*9zTCiA`kxO z0NKR7^|?c8+L(FEGV}6na=E~mrI)M}B~U}Skpf42nl&mab-uoFi7>+(44hXg#9{pf zutr2%Hl-u{_vv9v|4?*7*|X;S-4at#Lsp3?BRp8St_MyoL-*#s6_6Ml|oi1s{(xe+Ty1dUi3 zT6vuKg1K6YlUQ3s;T|5W@`aTrb`XXR?AtvzCG{A4m41c8Dp0mSCq8{tDdM7*lQr3;>P2((Wz;; ze@ylK083$G9WMhiZO@^h>Vi9TE`@KQ=VS0dV#ET?d(squpMb=V{ZuC(ambh>E-3jP zSx`vz5@Z74i<}haU$nStsn3wIYfnsIP7UuzVj)~{=O2gkPud%L-Cwg$uE7l%J~2`P zO17G=&BWWL6EOWv1nQzr_XC@Lbzf< zv3j5|xUu}gf(@XmzMo)c3EMp})q!SYwJL(T2c0UJ?PkSaqXi9&*mNUE-Q<~gl`icn zx0Ml*bbR*e*mljf>NLqm42rx_z_hzJ)c(g%hg{hLfOhQR8>Q`Gho{a8RJu{X+%QgF zwln)*FA0Hs3Svcf0JZcdum2?;-X>TZ-z3cR0Xwlts|$+e*$9SGqGSPo>ZRo-#}&kK z3#19v^s99of_*P-r=cCYl`zt$A7c+sZ_x!Z(ck2otijt|9OAOU35D+OZ++MeCiitpObyom!T}PkkX{ztr1H@-t9;9SSX)0~PDNJWS_97BaXZa*;A#Ey!YiQ8F$$Z# z@C1Gj|7OL^IwD6@pJ|p{ek@Na51PO8BV?dc_QaWo#{jGb-A#vM>}Nw{Pnjxc4#@QX&1g7$PFjV^u!=zB-e$+LF&lOQEw)^rlnAJHFqQ5 zfMT}XomSNR%ViZ72ZpYMZwg()8|necVCJjrnv%aR?#WDq6GNf^M^Jyf zdiUc)>`Wev5z{h3S3x1udWrKS4#L^>skL4SIjbZ$DKqac~13 zVLfg851%cW9m3Bt!EFH36b}o>Tx)xu3qD1RZZ*+yoQWa}O_R@Y>aS#06>;^bK#j7G zd%v4X91{YGW6y!IEZ2amkz`%^A3*o}#Ft}FcLX%?lIgOstb9?z%g_Nn%{^%ztY=rsm6pj&Qvtn0WM0~#;ZBd z?F0MVBlZPJ_Faa^vVa0-32q6x6+OjYT_; zQhx~t2_4*_Ijo~Ts^*yJwnSvAgjqhg@AQva z3xq(9RVC`H@pi-Oer!>@^(T(??UOXeaJ8h(bG#$jS+|7)v}H zhfJp&vy%x`AJP2}DeW`J5Zw5~1r5(jBGV+iJ>c4Syb18e^|AiklC6V_5SK?JSpE2K zZQ|w&8ZDbz{C0YxmF6^UT(z;rCKmBifB1by#*kp2*?^TMkvm#knYiUx&}b>pb<l~Jln$KJg1V-7<}>MeYrXG#y3H=^!f|5#-nog%jC{= zn(uGaSD-6}Ly_8D32(gyc9pM{wjY7t)cDo)`QRmQq||`S9SX=}u6yVgThxclH*z!I6s>g(L~JLmAuJ2sjC{G`!=3ucH6HpZTQrl+f8k*{ z$G#;;!sFAnzK4W0N`KJKW=h1rLE}n)seJme1*$pE!sGwHr6l83> zUBeMGksuqG0u-@4hcR`vhYd~=`z_9vHV0*O<@KcaIg49sS;>I z=UcaVo@)$+>p*X--7MtOKoVV;QsMwNDNmd+l`nOn`5jOPAwW>d780`mnz}F~K z27Ycn<1-FQ_0p=*IqHjA%>eF@R!=cAF!xz{c5BntF*zxr60@)h2V5WyZRGI;gw zY6?)gh5YgQlM@k&^^~0oiuKsj3$L~RfODe6!o&w9Mq_TFzRc zYrUyl&|IMZDhZ!a)U{H*o~R^9&ftAp-*KMVZ}iozWOHM@aMP?uO80`(Db(h|qMb%& z-ch?lL6>;U%=oqI2=;3=G!^`f{rRZwMOVKQ=~Jw}$?#~^1Uu#{%kwKuPrbe$>VpoM zS_(Tf!`5buEoy?xrMBH_x7^xe{vEf4Wegv~a@#RA=Q~-Na+l)Ao6`BVT8qyiqb++= z(7mam_?!qaAh~-+AU4R3hNd}`uQynZ<;^+NJ8QmciUJ>Exw{81O%wLl_V1>xFBL!N z8bb&#UDMt?lGq%19r2WZ8j^~`=Xzw8u5UY(fiLXViJcsJTpvNwSa>mxG$=SW0be>K z=cOSHdY=Km$6)lCrd^pTsrGddzITE9Ef&r8=A1+&nt>QSiU8<>cMP0sQGv~P25jrQ zU0G7`po-mS@qaX(cU02-`~Ou`EK}^Z^iEu5Y26OW+ygZ$GY6KHnIh#jckTt6m6>uG-jxOfH zppXfCZX=4zq4-)9FogDNjH7id#D5!0NZAoNO_#XfV=3^jyH5^ZooHcarmiWRnB zt?)3HKbUm#1li7yaQ&+icAlE()l8GSbfKde&y%{o3X!>|m;_Mq>rUufD3>7|b~_(2 zl)96nk>+*tK6_fOd!8&QMCSN6FM+M+yS5kv79z8|mmrsuy!Hc@!b)a>(E5|wQ2Rek zr0Ky7&x{J%`p0_N$XLRH9J(1a9~No?dHNOe(az1Yed)*A!5wQ@hpoh@~J;)VYwe12GXEPu?4=JufW0>&zUPEbE+DzTf;>HQV4 z9;HC>gk41)zcUubj4sY*I@u^(=A8PT?n;%@xQZw*V}9maJVUx4<+ui?4X}(V$WD%x z>WT}^$TLT?1XA2?a=C^QUnGLw3X7&Ie%oYg84M$zkIQmZXjNrwvsCYX;J>nY95VS9 zD_6nT@1TCJ8)0)Ih_G!;r~d{{2!yqfgjK<92_tWlGhx{3t0<9ew+}llL0^;+eh`l% zse+xZ1b*|;&B#+}JL;69Rx?KRCO{as&{6eURwY&mCJ#jm9~5pRKdQ+i4(P=2%}1DQ z{1;d(85UJXLTbbul;?tV$ZtmyJmHf4pzg0~5P_mD>UcU&0EnXb?ZV2__Xqt-LB(d( z6sRF|R&jJYP`2xG#qJ<(W$zlzBpS7h1%E!#Y+D~lrDW{94>D2QD~HXkfR{wqdM2Q# z|0J%0Ax$+)1>wskBw^NJNNvaNw;ujm+n<2mw|59Psi}P8UJ)%n0*V>KIc?}et&(=S zlK1vBPWHN#6pkrzZFat=DJIF?3%Z$)QNnVv(Q7`!sV$RQF^rA+-k^5>+Qj{HTc)T; zXbHm{dUGm_)&!$96}teH9#}PF%&iKTZ?bTK_GZ%e4}nIJiZJWOT9FtX0KABfG}tvM z-YW;{z<^(}>W4gs0!IP3J{-&YKBSE8DX6FvT8N@%p`P)jx!4N|`>OQ3iwc?4;>l4< zCG#Ro2YE`F3{;e?U#1_gn&AEYG8iXzTho}oA|7G_-->Sja;iwJvOhQc$&ah`^Pso? zc79H~d!|LZ|49G3eMS?;^5X+C_%=v`<7J@e`vEA&rMC&01OGm_y{+}&@f%hIS)!+- z=tK41;4))#_#me&_aKq;<>;?O>D&VN-L1Te5r05c#1OFRw!dr=+9Rb%n(mbUw#~0o z@RYJEk+)!<=8n2hD#hBu^^~jBzG2GHJT4xs+Q32|E3Xuf=H7-hP(nrp}+TH@bv z+#=DdII?(ctwc>B=1gtsX`CdYsfgFxVgB@V&-0`N^an{D;e+R)V@xoG#=?uW8fmmI zDaiUj=So+JmNG=`hn=hUlDrg5i)Nz`P=J3}9KI^r&bo95AWcs2L<^fP%THDHq5pvP zW5n;>yjD!HHJ*6AB?Qzi{BIi4HF*_|Ix1ylc3dUF^=v9J(cZ5fL;SXzP9YM17gWkx z8fh3Ij@-U4;>(YAn;XLf-*$E(*cXwg@BAdU_&&^x-jni-DKuFJ<0&mL!=m;xA%JxA z9w>SpEv5SBs8Bv^T)eUXLth(hiN%xSR**HL>#9nJe5N)7A1c<&LKd3!G^`T1d!0A+ z1ETYv*2Q;4t+owh==ie?gAIKN&0ZUWN}3m3Rs9Ba>9sqv6$vahrwO00S?tb9Y)%6d zBWMm4fE5zd9gej%$l8vLILNcotKk0-F4s4VOnF=m$HU-@ z%8p1aB~bJb4+Ow!RoycC8k`;xdf0*;2SQ0n$y#8B1}WzuRc~qGlSLxJ(9>-*)^?iX z^i0EV%$G)-=O`_|T31s2TeXhIL6~(sH@}5VxgW{6zSaSor7KZzyujt7ifxLO`MVJ3 z9pqvp!`@Ne`R+azuWA91-b^&>S3Km2(R%MPY_kzO^OgPSHtyk&{JJtr7fZFmPuARL z+rit&!EZ(aDFX(+SrOw|eGmZVm-LQy!JG;6#WXzO2q!h&DqHNJ<18{|Sv*%&78da| zD|Rm?4=Yk4e{kQWf4IiLP#I~s<#HMpSxW^^IU}^o4<|bX@B&g6{?iDDn*`@ z1Z`jBRT=lA4W388^-VA8(ZL0hzcSTYf0Xf?OM=gQG7+{Q%qDPSX+XA;n8Xu!<>Xhv zp*U-5+L-+K>CMnPp@d_04yw>^@+l(8)D%xoP~aQ_;e1&S zAs4RpQB{B5Atx!n2VZ$6}Vq=8i0xFZ7t>;{?3Q z8byLWh8}B1%K8rM_mm9e1dKdlEFBbNrE8U3xXn!g$eWkck&~!$W8aPo=`t9XCl&L= z4Te<49V!TK@3jCv*#$9}D84v$y0daYLoGI4>7QMh)7vX-Gh6lk2+GV=NL$0{mzkRt zYWxIVa&*em9O%k8BJ}FP0{a4p^kV8GhVNDyH8&Sf&Tza+!x?C-l`smXSkV}sg&&i; zeO~_WiO=0DE0;`rk7mXw_I z(D(-~J^*n@eoFqmovY2TC0yy#hHOBV7Giak)dXz;);jwY%(b42fC6V(y^j|GLm}id zOzJ91mxD%!@0crlJAAUtSmU~!6tx?xqdpc{s&EEZpD9!~=Nk``F{s5)A8R>3ci)T@ z<@F0Q=eFxVJt}XiS**)j9I$bUP;*e~{&LnPeHu3#w?hgRVa$qH(0eWWd@l=~o4>gg zixqTRKnT8C@qm*64Kzpb*?$<9yf;Lib!KFmD-lY1r11-%Whx;!CBMbKT`BOjFPIbNjZ!E_}A?yoPWKK9~uG$kfpOYQ2WNJCkmX zxh=!Cs+LpBW(~RJ`g!BPmZVN+KRr7Mw{|;FTWdCYCftBgyyM#$J^JVQLt$rkE79sK z2R+hJdP4F-sLr&4+hRKGDi+<(ZEn)G8k2l6K|3(0(s4Pik2(Lhl-J zi!jGHu5zjGzP7Jfs;G6y6)6l|%?~WKt&3Au$Pr%ck%?q(1-Y^Uvxx1|yk2n|Ik$RI)d$OIsG+qQ&|RB5T5QsF(Th<61m{ zF;e**JeL!W$%^jF%vUfD+O@K?kGZ*CJ;u>~9J@*Cu~Vh);q0mlf+SHF$kANwn_5cy zdGLIaZqWGGW}Cf>kY8U5+6#J(u@guOCUCc0b*6SH8+ttS8#UB>SDpvnRk=F2&7T)A z6S7i}G==X7Ge2T_Wg2lTz>G#855Lg$t}XfXm`^xy;iq}|P0}K!7^DC!YxY;$HnsL3 z^oe8wuAXAIPrk6+rRgQ}HRHIlE!&Z-^_X$Cvf|R_nr`{JQ`PodPJdM9_{*`37zP`0u=B$(?7V87USp0{G7c+S zw#I*!>Lum@PfIY<4sRPurGDMmeN%tH~lui zN^0`$sJdW!SVAcMJnX3BA6V&P3CMlp9rsmlX)NRWPP};P`oo(2YdyLmXx{EB(c7Fc z$AG0!tym8nSFbJ;iKJSmqi2E%%hK6_1LiFS16$A3+-tqLJn!0>dC8j8O$4QQ-s z?F2ip*3mVQ7%wvk8#Z6-uS$e{WdPHWQgOfb8<_BTKRTbRYpf!q6Y#~L-1G_h@b}JX z4M9q*%YF>TG|dC5G7&B_o)xMVwlcxIpI>c`vv;kb0p8wz-rnAIDkO6j+7B2I z#ccrXO(*d?i~6Ny65Whl2uL>A4#IDPb#5)ysm#&qGGhNtf%I%Eo_enNTQK)~3%{Rc z7u3j#)#QU*#s<(ai#3>&-~Ze_@DJ*dh}zEk=>0IT)X{k>?EWn}4juL7)ykEUe=)mW z*E5sJ}y;YAe}_?2X+RFz;=gZsvL4K)6;*iV>rP3pk1aX zMM#E;!klWBBSXk-YayNT@edp=BcgQ`WSNRVrJseQUq#Hm<C72rS#F$F?Azk+9%D|mYv$0U@!|BbMa%c{z!+o|}E8(SF*b9k*nnzn&qEqH->ObLfibYFCi8xEK(l=u112MJPEHjEZ4A1fTU&mey=S;y;2MVDZ?QOcsd zFZgt71Bx0OUq^t-8n;eehNcKsL>h3${q@W`T9q&}I~#rp1&cp2pl1KsxyF@`qp3|f z&QbodyX(%rc@p|wcGcL_CjT`5z$N4B1zB%lQ~R}8N`7uqrT5jkSDRS-Le0aL><|;P zm#VS?a%{yms>X(XWos!usR-K+NFQ^!;%i!3h5^q}s>-1sCoyq9{LMtMiljv0r;c1& zgr)4$tN+dfHNC65S5l>+VQSCJY&+G?x*dTFd^K#?5vR8PFvv-cN={K627doq--$k! zZUBv+_b%$yy2UyiZAsfX+wdhJAgDnxm$dU2fnCkL73+MW_uld3^R+75^=jJOZmfa- zz9h_V@swLAp-K7+_lMD*O_a^NM4fk%!))JIbGLS@jJ0d`HGyW9Ki^i@=CQQup@Ba*UHDAl#aZJkM??5HG3~{{3o84NqqG1UzzeFGrNemx z`gGzBcF<*_?*+Sv0yBNp)PMhc?42_Zk>G-@*<;qzK`Md!Mz^3W@gccR{a)nk)bh&s zs(7Vpw+gwep1{KdX0Ni~xuo$7uH3)DVT+A>BC9HjmfvSh8Y1*N7KMAPi?!CSo7H?% z^wnfCU=U{6&~UCcRC&zgLCH#+$HZH?L$`Lo{YD!aaDtV`XxM6WBE~yJT40RvEB?GQ zAr5x&(lDCu9b^B>f%u9n`L*i~Ih-PQ69A3pvJh*dc1`iXI((YUqmsPQ zwa3G1mgf3mjXz#h;ojkD-=;uYj~%KqAmb>1>fJxc;Bm(GAWltb+?ZtF%-emT_D3sr zOmoh7<)7Xm)n^H8a!l~F;{{~6n0oE%6@00i2rR0t{*Q%*Q--Hk@u^2L0MM9ZpGoY!Z zN4k>tmMa!?jo%49eo{Zf9D#=Ze!-&3wz#!e`5@o7-9ueVSuHX%P`0M_a5`Z0ol;GU zhM=#gKS68f`&3!&g_+E%JpSa)24w{!5eUnVwm)C{bP~6e3$GK`A}&yaRrU%j53pQm zH?~su894L|%ya>`SA?6;dn7!1 z8rvbGTK1JI^NaPOTxp=D4Plf`KZtx!V!PiiI)B5tkPeXl->Goi_sQLsW<>bNs(d}1 zdG95pF$L9X|K!@K|3t0KO7_0$xqeXuGyatE6VjA~$>B}c?8j~Py|siW`6mfKjy)YV z8d1;qJ$d5LGfvDYf0aNex{xzEZC?wmpwe-J{-yNR zt3uvD^yV_!gdMND}Cm984(yO zhW7Q=R0bRgwR_)26=MV&{Qv1_6&LQbus*c^-RH%GXGjpme;SBElm0d)M!oj$WLsy^N7!|@AO;_z}pE=rm|CzU$$C&cs_{xbHAqDD?+=Cy6_G& zH=8S6P3Rsl^3HDb!O~WyD~=yLf##4&;XMF={fv_a7eCV7OPXuyNY?|U@teOt766DB zQ2oGK>H{fTJRow^c|wWzY6V+hC^5E$l*#t5DuJ)_oGpD&oB9bjj3yT`0SZHNqmjF| zuB<(PN6>aHI@7FMrr!c*vL}^|g)+a-IgK*~pZU2XMY0-Y4zar}`4>g~G z;|Q}2DgJlb=y$F=b8^@D@$|TEU4RH0m4^pDpdf-KW}(ah^o_P&&ott|K&hhlN^JAe zwe{E(!@Ao#$av}QYCX;w(0oo<`N{x5m3LoLQApL`sMy^Z<|A}Q9}Hg02Ck(cG|?by z+{h#P5e3MxALfBgc6%tupp5eRdp;8x2e+a5#Y=$`J-ETTsvi)t4U6|&kA+qB!9(;~ zMTRLfqvp3*bhRA5rO!1}MQQ-DD1TCO@1RZ3SY$Un7VbpOhR7xuB7~ppH2k1s5&tO~ z)xw$-X?fWmE^)5fF=l4qb(!jTlV#WI8 z*8(%iuQyjlX@KuJJvUnZP>$GR;_QH6#G-sBdH`Pj@=eSaRV3;Oh`(=AMsLw~$F=mh zYh)g{f|*99Y>Q+u8xmNfw`tusPAy@R9?@^;OyF*d z)lpFRE&f`(TG^$b-t2oC&b%>*Ia1Ic!ARpWNqs7G=Crt#;NjmUl10FtB|-<@AOfF| zP|^pj&$pr1+eR8M*4$`k_vBnLne11zzvPyRZ}UJUig;ESjiUL^62?D-UI1&sT?cOa zpPiyN<9038v>eJx4t%5wO*u^tR*WxNa$c&fJ!@^%&AXZUISFbVYa5u~ zhqjn!zvp<(;nDFz61)K{k)W&y2wUlxMoLbBL_$#W)R7f$6Eo-@pL^gMq=fyu z&iMal0c?`1MoH*U0U6=LjsJNF6`t&r-gw>^jFsp(Dm=CG+N|bE*Ap3%8(EU-vHg=s z!qk6qHGiYMxl+|nca{}20=`CU&C-vN_ z0~P=rfe`E8lys1rS~6`G6lVwM$pLovx^^tGK`}blIm*D**usn1vlR#o14@)}7eV4G z1Z@+iXOb^rjau0?nXcW|3?p(_CbSCMP@w*5cSSM4o{Lk-jrR1mOx`og0=SlXuES-1 z3+28Ff)I2qTEL_dozzwY0MuSYGm++(iIfwR>ULJK2%OQzOkbZi#Um_zDw1+4E;QDnl zc)t?fi~EZ8^%$Q#WsJ!$L%2Ptao+!>?>e#DHFB}e!LfevBKN!&*4J50bp8upJ)s`} zEPy|E)hTB5z;^b`FizsW3!j=tMRv}&@gom|o!AanZKs{;(dBzR9_VW)#laH9*$UP= zzy$2e(GI$@OW^X$)<244UuLa9fF?rnmQIf3QOFsXI!_Pk8FUDJdDwQ`%-ezs7}Ge| z?cXm<3H!EwQ%R{p=96%qy`WyQ@QOHHSMp!b`l$gcyt1%`*Bj1^E2-or-a%vPYsKXR z;gyCiZEjkYS4#OHyi>kaF*;?>PsuvPdENhuSjB!aut^|zeL8)s>wmHT--g|y0Z3Jy zlk*`2O^|4q9rMz(cxCu!B6_DaOwACHs??@_p=maaIqVczz33Io^#|0qsH3-wM)5mK zcfeW}i>2?`JAX^m6O^}7r{~FwZzaXC&j%Z=e}!){c+HPhE^{*C?;Nuxj5gQ+E@F`V zi&_7I6CGDepv?O{@nG-r4Yi0%oTkvt_0K88U+me+95&2UYM91j0~8!*J7ws;g2J0hwr|lm?h!BSrBDOJf1NLQI^Nn4ewHcg6Hu zKAas3qV2{y{6efG9ebC>KLnL2qB$tAANbTIQ*k50Y%1U~qKkjcCOvoR2q^b9k%oP| zPZ72H$6c6nMFRT{1N*2qi0ktzpFlD|4QF6w(2Z}^`SPbb8W*7!9mt8t>)<-TMaLDU z0iT+!r~(dhs9}%QA~o4=Cftq=c0Y*fQ@@weg&iXo&O+LJfo_-k3Lp&?Ab!sDuK{m% zXrsu>yjN+XK{dZqBYFHmZrkj}OYv^NHkg72EV)X6bLewIt@XGK8a?uO|0jl;+d0KA zxy;lfVM7k(zPjVsoPsZXj(0q438=meON|{ZH6v+l%%KB#T3m)e_MUIYU=qvgEdN1KW!JY3^1Z87R$Uz3L*pABL8AmjU{LAofrfa>Lrya zz}5O^-QuSD!K$4jaX*sPjLZS4abXvrmV3Aq0v3J>ZS54S0Tl5q(K$GkKEF%q^?%jI z&_T}@^q4;NkxWpQhA*L5nzY@SFbb4OoRWv{RzP|ccVUvvzXH4-A*zQ^q%N&dKnpxl zT*S?7u9S9c|ADzWM9!wgb4j$lwStlbx(}TrEH0nejob5ehB0!Om_ljL*6<#mx=0K3C6$& zZ|~3QzY+EB$$heTa%&ak!J-eJw_9u*$d$QZ-F4|jgGf#^r6aIEhbnmKO?Adv-j*Ma z_0$ztLcaR;CyVJSVeU^ekCtN7nVoMg`?WgH`v7$=ewK}_jpDrtuk6tS!fx(*i&jki z!6Oxp490LcM>K#8Cmq( zz+;KrzQu2_5d!d&RPlL&Xw7=}O<>Ei%NJoapzsq&L}mdcRD_Vx(KVxm?H$A-0<48# z=B=E1++OtRje@-L!^XRr2sGfv{4C#A>-AcB+0s|}sg1G)_ayJ8;D6xBcQxVTf6c}D zJ=;g`ciuz%S*Qeo%ZW$wZtad4KztzdZD(eZxm(ATE#Q4+I({y}?(gi-kLa5?)i3{b zNzfqxAcMA2GAx17%DlniL9P;Fj020*(aI zUv~DKUBFtJ7buqLD(^dFxGM4OGS1$I*%MIWQR}{Ee=|g*nESO{@JBWANe7i@>CHJRUGIXGWd{P}h)HCEiB+J0knd?92*(++4!!cr4)pers?Nn1L zrWm572g5Qf$FndY)^LCZvgBaFAmDEKhsp|vwNBR--Wz}f-XC0+)(7A{uOodF+8H5o zMwq9HVA|eod#{6*Y@l&1GR^&JJ3b}5??>~GL9&E2{gbJ>(=A^X1YN30P^O{8X#2Z# zkjlp_qA1*+Nv`op6rq`Sa>aKqi5N&1T>&QRQ6}SzMqSt8f?BJO^mg+2I3xJsu{xlV zHue7*)Iu_#-^Y#;R@f|@J7mh@z4z|MgnB$L8hsbQkX6s%O{>UK-a{fL%R_EzaM@WI z`x#Yj+SMfR5v{^W=AJquSP{ zTd>>qkBLu_M3}SpzmWQUGrX5jluFJgJC`Bb<~v@QAcZ@`?I}*$8!jKnO%fRHJ}zO? z9}@7ZuwaXVD*{>!w@j8$+*f}S7EFj6LDlV$$}kAz9_+|Eos#9%egh*AB~wnl7iPIH zk5`|hECIy_R~JQv*(Xu?86<&9L;(p|4Z08ihMeF~9DUPfOF6&8>bHOF%ZI4Nb;%?B z#kl)9>A@3C+TWJ0(83X8i3P#H&~CP94aVytqwcgd%p8fk+dzM~?3 zkLxjjY~b~=+nhwJj&h^GW~K;zWo}tZOu<8DITA6~Hvhy@Ztf0xlwwB9I%S;}3Rt-c zz>zL*`+D5wTvPjTvw+Xp*ToAfMTke}D9*dzKN)gJJ7^9`VWRh&@C&|q#_zjlF5)B{ zhio49z8NKK?zylGUZe;;34k7C2_^^JTmL$VT_;7VBT$*sOKKYu)TS6%RYQ6N`3rn- zv2%>RR*$}|2QP|t8vf~&|P4w#QNIiAwr ze0)US`bR)Xh!uIuH2Rjh5UcwAE4VjZFN2L0+~&}~|1Q&7ri3ia1=srml zrBgory^Ax>X)$6aWpvi?0vC@fQ8ZZXBNVpIm-!=xJHYTxRo`WIvy9ui)1|P zHgrBS=G0PvaLCA`UDV{JIlb!vb<&ew`sAyjp}nQ9i*FX-aVPcp%MpGIB5sx(3M4_i zc;0wx3B@y$A_PUhjr44as5xv0-tPbmbDAQ6nJxRPgfnSyu#h{c!m|b&m~ z6-CsqF8cnFq^e{hL>X4E3)hpxACs`PTrYRJ zH2@R%36%;UMvKQva!QRbvw*m@BqeW%d!P}DU00ai@hCXsKkLO~9opR*#g)1}02&x? zJ^nLKMJO%-0z05knxqx@(cPRrq+aK;WlzPAys)Slbsw~v(wm`!QXE8)JR@+FEX9i-!Q4rt-Gj!+z4@;8qG6EGx&8+x zd+%ymU0MB}zCF>$Y)g2e1fyvUrIUUQ{Pw$Izi>(igfRn|-hLC{|J}-8zmKFam1!!h#taF&*{Y1XwHs(uhI(#QqpwB(F^OmH;Wf7a4%$M5ljP{X1&T>h z=(wY|{G`6B?IB?bK_l!YP(u_0f)uF0Yi=+YM%~p}mCA_)cd^X}1Crnu9^Uh31697g zI2e2;TSwScYO~_Q`jQLM!%dVX@x9-)w%e~tlGcS}1c2(h zR`r_Gpcgdh|H7@r0sq#YNzLLkpq~G}sqZe5)4F#vHdAefRdyi7z=8K)&VBLJ?U&J} zOP)c>T!oE*@RAp)dB{J0+s`S}J87}bT$)Ic*ewgG9-8@!= z_5UfS_Yl4#8oII@$O#JVWQ`cLm9`ERwK6Tyc;ZIzi=ih&H2P(PU02Zb!m za$!_A|i>-BiQ6hGm%ZYbaRo*SIDj zRY7+AJzI7khsvAk_ZFoC=U4pSeJfD205a&)wf&nnuR;`|s!IpPV0xEYpM(kNkw{L# zAcA@yOp*%fDo~fGcZ7aa5OA(c;`h!ugTk^?Z%(vvto9n_LTbpYMd*H46B`M)nPSxQ z*f-pRuKNgVC-b4RC<)A6s{UtoTUg!syo+4amF(Chj8j8UP_EZK*Po9ON^Vf_f!qPz ztS(bqVpntHHYz_4oO&9pHEfWwsy%L2p4Hp>@Sq*#|MYjFdLcY)cSp5Jssy`zujYb=Nt8?G&xltZ8S%s<2V5;3}PpYO2lthM0L z-bEe(0HK&5{R5voG()hc7 zMLhQsTHW{b*8ZWiod)!@_QK1FXcbn%7Fp4i^_v~x?JE*bz0or{(ruMMQT3Q8Y!Gy> zOE|7&a5mrX7XqCWaR-sav=MV=;0(_DRe{j&?Hw`L$>N~fL;=N-(&7C9mK!pke2gmp zqS%H{+ybuAQ|2YOWIg-fSdgI5a;v+?cfkr!dh&N#vf}dStzRJzx<4gavluEbbB@}I zwE;8uPFhZbv!(!pMBu6lN0W%itMmOH248mdzyDFZ(P|c~^N#zqznJ|}^8;|Ou!=-w zE&G{uAy#K1$1UkeUE-Y6iuv+!ICG$PlZ+burPy$Tul+^~LkZTh@u`=sN#p0EKXD|L5kUUU3f?3o>1^x?|z)|^<-+^?i5jY@^upw;%qScw=l-7^cHppVc~ z$qeLu(4J_H;xJE|*#_&8g!7$c&E%O>gB+@wsa4QuXY-QVU zXr9W>2J_UOZ+X%WBK>=EYNbotL~!fq128{oujp#=G)JOBcJ*TZwB=#b4HnA2^j@vP zpMZv2NYdrHUWG>{q+!g6dJrKT#=CD8~&A107 zw5p5HL{6?Oj;?HHRO=uvP$ok~8T!Puu9XILg|W#_O65Itbq2qGrVdJ+#{{8*<89ne zZKY@#IoMa`pEPkU0j~hBz+flFavn+_x>!3HUc9fjA1|{V4S#IUSbq_}q18Whh0ZU| zrKD*=>xKoL);rl8bmJrmq^@<|(F+J(&~J@Dk~_w2*1y+Oq-gI!8>aJqlmh}@c8#z8 zcOdsTU9;ocrYVq(R*fW7)83UgB_(vN{=ZTDvdwVr#EH)kkCfU8e+x z5Jk)1|6@j^j+BW%Kqz4k9Ku9cXCF5#U!rV>Sefr-7lULNE%nV3d!j3UZ>3-0%UVW3 zZ=FbQT~?fG;K3fRC7yuRuN>Rs?@s^^tN?ylE2ezt-P|ccDGt6^?S2{vO4mO}cc5GV zkARS5Oc48in%Lfb_-pt|5xu4Drv&}{OqPZ_HDN0izA>rPUXHNlib$xa*!JLA;DKC@ zc3k{C8boW+tX~^Rp3Mx2#`5q;fCIF)Si@eMh*rRUC0vAy_og5L9KqPwdJ?~ zPJx*}`ZG$ZoR50@vZH$94Y!rmdJUPB+cy_ELp%?aT}TA|K%mS0h(qTCR`IpeL#Gwr z&y`%4qlTHJT`mdWb@`oZ+ljGX*g=2yZ@*^fbfLoKIFm25{2i0t=U3>!y*rrevUdjE zKQVO^`Y-A6afo<*8P+@0?&4)2T-~FDWqI}7a`$_kT9NBspR2#`&j+d*=L-XZxRFg%-PM%}KTrrVj z_jZsgtAh`(@pXt)*>b6fchRw#LudP7uch<%DPZ7pRI29D2yYU6w9&A*>wC(E#l-yY zqqMFidg{4jA5BtZT3&L8O`}+J%Dk?j9CujV)*U_U+Mp0MxcM8^m5ej*_22prT$1lH*N}D-IEYvb&w3!q5B;~AB8j5Q+e-+5CrR0DrZar|M{&IL$-!Jk$ILM zeYV|Idl3lwj%R^Y)cnlqh8|C`#lXAprYZ3yx@)2a8r#o<5h^4T?i5;7Tt8H6XTZf? z5njnh@bms0S($*4fhKY90MCfEF%Hzaa91MHI(oBbb;sJUV0s--v`klY9u9d6e?UyI zz~95K>V!FG_eJtRH}SiY_~KSo=WuZW<1pg{ge?+zc`^=J2b_(Pw)>_V>;=QXGyU<@ zK@m4D@u;=)x z2e>c1rP?ZKqdz8{$^$pzdM@awKW&sDQhI$XG?eV-JAr4yp!DrpYnK~N4FO;{w(s`C zr(L~Y7QEgsQs%)BaI;MY(PeLsPkBl?PcT;#%C2C3O&!_MwG!R`2zLATYQ;Dn@s|E5 zCB%XaNpsht6|FZX>B1i<{eQd1up|fi25@Xo40KskLC@N{t~%7QO{6KBD8eXz$y@To zy^$~qIlXrNN9xikpgykgRWFuVU;UA7HY)z)yI*yEGW%ErBRz6eXQEkPZ4ytPG|_PT z`aDSZs&P_NUP@Nz${R?&raa$|w?)0z_y*SMlu!K^yizDj z{$x1gAW|e(owCP@?m}k-T>?*1D?t`(ET|~=ZPl)fv)H8UKeDydVO88CCZ*@{gl*=D(+$ zS@9SVV!ak^0=)->7dP+t*_=`9EWLIET=;v2y!A!?`GXF_Gi1KAoXhLO3j9V(D-tS7HTs6Mq}M|%Ir6_owv=lQtt(g>Rf9vu!pp>V&ps1`pbZJr5ZUuo@={}#-+6r)|et8hi1-N1bMs8vy>=8uE5vnXXf zlnUIx&KkJxhbq5#cEb&wNQ-SgY>12 zStoE`53IH#xFLnw)Ae^vaBVL<2G>(L?&wU>?&U^8T-*IPufsiA+aJEqDNd`Tkteib zfDczZTY#)ROa40-vagzCHO=~nFJ)YK!kWrMv3HaxlBMDt;cppg7hlfK3<3=^7^MX% z8SpDc*ePd>yo48Aa8L!ac=AO(MLPDGVn+AiL8T$zr_hH!7#|@*zbiJqWTwWhqS3E> za)q@le2sP`^_H3de><~nP3deeim?Mw*7mu4YzA_>|EoOa@3Dr_pIZ74+?`$r*3^T& zbJeBX#ZbFpU3DCTkSDis2~`t8(Lf|ZmyckaUP@%7rUw;v*v3k35g!^AOu)aY?8el& z9p3Fn*7QmBP#bxfrb0GHdnyaIwzUJ__kAns0>&QI*L>Qtr=A>)S$gk@oVd^9c84Mi z$AxO-h#ovGGNgwWs&g@jlqV;idOqVo1%tFnSyVJn+NuikIiC3dWgcC>H^mAtZ6gOg zZ3ibqs{HP|vJSZ0lpoo1XinFs96;34aK8c_rNZi{hks|3rE1=&YH#qW%f;(}8-CA| zP7ARPgdC(Lc-rs|gWRT{?+wH3a`X(N^h9QxG96 ztNDH>b_`mSeLHpvIxVf9^O3Pr6dmN0r}1lz92yv~9SU&Hl>LviHyHjtY69 z?x*j+Nx2se>MmVP>TaJu2Nlg)7R?&x*t0HW-tKWl?@jdI2$8)vHdGX{+IEerTD+c} zQ;ykUhpz_Kj`c%MGF4m{4PJ|Vy1>-I#-HZ(x>@e|K!c$mtErR9nMCK%msA5H!Mudu z%^6G+ZEuFV1jcn_Ep=tjJ|;^F6D@GSi2Z7LIfnPT=x6E61~QTs}KzD zzL?782GsHNC!8>><4kpSVmC;N|E%(Ml0XVs<5{jh4=1m#B(4!ISWk#HnXN43?8q=IvJDZal&rzERN@2kZRC7HUwI@l)JAdg*84); z9f@|O#Ok6BS}NXFE2^!;%BUBG=SN2I*R9-%z=om_C-*81GRq$bG-9r}yHlu|~!APYu>Z+<{du&kYz;6auRG##)2%XY2)hyT@U@prI zghmFwny&<@SHe%8i?y)~#wO9SytN$(DYX74PwIV_X7e_VbRyKCziEpgh?-ka<3vb) zF%XeQQHxqUHHn@Mf)&9B@5(`TD&PEnPW_zhj=ftznoft*;B*l815Q6d{eom}2-ufM zZ^XN^p0wwmqL+7CWoP*KboDsv}~bB({fIIFU zv7PE$Id``~9&>+l{T(+HJ2YubSP~!ca2hn967-4MAu+*`BNBrbRY5nSk^T+u;S>jN znqq@EtS^eFdd6%p3tHtCTpVLk6u#;cADU*W zvk&sEPTgbnZ3ra%YZr>TK4K7HaSxcKb6N7{#*jgbalyCfVdu^;sVdg$8+NQ@?n72Y zEqkf9Rf+d=)rm{0MX;LTIt@pv11m2JDo?7tUh#D&6a^Tg9km0?8kehfO;`-Xb zJuD0tVBjhJP>{VRT-rPsW%TUOlJ{m(j(8QjS<=kWt2t}qyQ27z=baj)nn}Fh3&`t!=C~U_Yga5#W>JE|+7^e(p`rjdYXY%CxLL7#Ww9>1^y0({&wwt4W>55auWw?i(y8TXfushPWugyd#2or2Eo8Kw$Wj-RU)--jBF=V#K1$j+ zg*ae7_a)Xk#Xo+e&XKMO9mwhtgX^Pav`GUQwS5lM4bG%3UtL%3P?5xiOe?x$Icm4P zq)_f)`x7*&E4tWgKG8iMF$>h4 z9vjwlmn%P^XFrM~xV_Qt?9gJnzljXAVoR8}7o8cv}x! zKTRzE>yfjQq;8g=-0(Sy98^kUvH(@X^0|t~0(ORnF`(@t<_a;JE(7ml;zCD`(Z`li|Gz z>g@~6oD5SD#pxzC<5WMqtPYx{hXMNdSZ;CvbtCw8qVnkgpR{%63y!~(^9hg9q4ZJj zmEZ{gG7cDrq_>vdhv>+!hX?E)7{9e7^%_%43qNrgCW#5k zeTfYgdKn$Wr)4fJ7UjeVLth^d=XkvGI23txZ-nf~ZnML5Dk;~o{$x2T2j|2|Yd=C9d04F$37h?AHy9 zzCfDgI>A2UqPd>Aj;?`Ybg}w#4O4+1>;bc4Y-Zq*>nhjJdXSf?2(PYzw+hCd?=M#W zbQ`{IV93`h4r&*3U0TMYN0KeL9}3#>@J4(nXz)9Dq^z@?g{O#KU3;d@Bh2lvxylxO zH0;Li>^UX1?vNc=eFh`DG59(LRwR+~L(J2K1pC+=+;9St!2xCqqx`w4a;Oi?vAxBu z@-VpKZo5-Q^5I6etg=XoVa(?I^V(_GUSr7BuXof16Qt-{i@7@D;G14z>0nh>k2eiN zO&mIiJCfU)sxaTi0z$QHvrTwu>)x)Tv2^^TC5SjK7)*4gJbCY>D(Y2X-+S-FFhB1Tvlz1UI@bjjT z4rOeI(c=l$kf=sW+<3Fg zxBD8zy>w>H0wq<|)T0vdtG%SSo~pT9ePNV`B2RR^_PZlD9<Imd7_-mQBugant`E zuXKS_CI2+DGZ8Qv=u_QHDI56?G|iuMJmEJg7%_ab!Q)vy44Q^+6FetuLiSzT7GsrC zu$LkzX_z$;rTYHhLkr+l=vkeg*cDm$thBmB72jr7^N&QKTzV9EbQ?G31jSu}OivlK zV6%ItywGNIL}#-Mz{P5US2zqF%7$&Fo5ETGLh~$H>w{HmK9n^?yd!j@1bjmwj6Gld`A0J=BM@EfxOYR=UB!1%pYjfyAK+Mv z_?Q(u%mI0>lXmEH2;278x&+w=mZ24rjE`t18>&U@A^73}5PFV#%Qu~1!+L_?~abaTlT2zm01?L2zHEy-% zx&OC=e_hHk4QD|+b)Zsb09Bv9?n0 zNy2kNMZ)LV32V14kN<{*jz(JJ0i0$0<9hK%#Z&>F0>=Z)l1bRXJo7>HRa=6fh3pj0 zC?jg^-1GzTi7H;B^5aSX?GbdpDZGgv#~mJP*Zy>|aqeiVCMp&dJpPMgieupEOZr=L zw$G<~N;DepOA3ft!edeU&D-Tc8J)lfI!YHj9^m&;$D;`LwHEVByQ*#&fZ3zrVd!V^ zTsZR45YgOPr763wR-|;BAl!fAV6dU6j>4K;x=A7PN@>5UW?qgiB?A|S4z6#uE3ct+ zUF8~FwsDqKuBK{cS3UQ3sqam$Xmfd0L_RddQ-GdU?9Ex0O$wFiG=4f3-uH+ay8k z)L9e34WdyZwRDrp85;1T2>8P`*yEIBP9pEteBUbS@TF|ySl|}HbAccXmZRN*(r}mj zJ)=+mh!F~MT@T_AA>Ym39ur_(gTI9x|HEJV0sg84#Ml2ty`lFs7SyOVSxLSN`9XO6 zJ!6v_%7!xxF%Y#U@PwZ{oZLQ8jSbQ=g{`?6Z%R!Fxr)mqHPe@1W3Tu>3zFerOYM^{ zhUDJR0FShxCuu820nfyH0mE`f@?qcUmWebs#oa#1t^k8Hs*9cz0)2Cp z-C557dBVeoeoF0tL+mDlm-#1Jg|4RibTqb2@OV4iA<$-msQiO>mz&DENlH>iS;Vr%RYt z%hQxZNy$*xZ86*Rr>%q&2|A14YIpFRSg)31_$?HDq6c^S7Ak}apLSC}%HelAh>yi( zZEA=U2Ba4MeMpz1myu=j15e;=w4`{n;ujA-xrmD4ODu=IZv-MgrQ3I3gQW8(v!lY_ zxz{hL1%cJw5QO=BLww6jCf1vmG9s`xApcEl=49|Yw2{!RoLG|etTY4aTvo)snWI}B zMSk$R#oZ8aQLQz=$JH!`v-)!1Y>ND?Q4~I1cqdKZ?17p8MSr%4(@ICGh*&)93 z@bsZdwCyqFdM@TcwL7*ws2we9r;vz}%8E~V<%y48{iAk6?qUBa z;&_I|mI1h`xqOSlRcR~rK#^sa2z%(^U9$0D_FA^D9{J8h&sX}0O9qqNser{4Ruj3P zEm}m*7xbSjs0}R}iSu=4jddS#29ys(){Z%3BPt`Wig>C>L5D5+Ptt1a(awk1!gTve z;Xq4~&EkPV`SPK8#~1P50adMAE``G!-E_9YD{I2ox5q->)&J%<9X={b3oIc!^z6vJ z9|zfvuX@-Kcmhl$55Q8SOWIl1b57=n5PHqP$rv^2M}Rc&p-(~X_Epxo`Lfzl{>*jk zzj8fLeNIl2^SL4aZ;^{ZLS zCxCyshi9p{cKh5x-V9}EBnhx4a%-+%!Tgb_$BoAMb;Juljy7A7tD~@v_ec3qz1vw- zK!aM@vsMO73kKUQ1GpK7^b1YZ>a#A$kGzTe4tsFs7ybmZ=cab7lwgk6_^W{t;NdEY z_G~vRm~h?p;it*tLOIV5=D0fxsOZ@K)F3-@2=boX^J1|;lh%z_Lv zaw=UT(Uhi&z>uoG+N@;TMt&qFO6 z7#^|UV0t(dNQ_1twdrOITad4{e%FmZtB<_Ljclr}x`6sGu)`XsKaM23O8AXKJKq~M zSG7-MIAuJ)2z(T@bYH!lUF?$pduTv$chK{+HNG7IgcQn`P3of>pVLm zwoM0t)DzhCBze^Z&JeF*mhwO@%Xm1~3S#*$Ki-m)g6{7PXRq5Iv13h?xR4ne4$78`%sF(GQzR zvQJw%U8oKy9QO2nipzmGmh;*4MIATOI}7D#v`V(j;KM zxdi)s`*o2OgvTJYF1FAyv7yfDqW}|FS*3aj^LL^i4wLE|zhzyHSu+2#!B$3PWI|;s zjgPno`a5`t?7&+kGo7Z&v~jl{Otj5VS@%fyucAVV5ZQH+6WMeo z2xUr={^QxEN9lyRjtnLg=9+A6XwLR014{!=sEhQY0!GSP(Lsr|?g1QX!*R;ue!0%= zax)hTDwM+2zD-XcjSsCCh-_(bOM(kBfsn^V<_r_}1^9}nuHP3(V=h3f4x^Y!xc^zp z9XiaAIIM?`uS1@gWs$;bA@B3%Jd*wJd*a`g+LdNP$g8zbSY1FfU6;ab@Nx zH&Qq!QR?R~EN!cM%U~IQa>h8n8lzAw5KK0tI$N5CZ>8<&;Ky!K2xrZM3AF(_1-V&} z#xFA|P!vub+o$NwS7_ek^YmeG_jFSToYotgf7x13bc<`3jhH(-|7N)u5(+X4*U%UD z^aTqI^uGq8tPV~w^MrXB`h;$DkzN^={g(3Ne0_`6)noHEfO&Wy=Cz8hX&T6^xx zpJS43gIcoAK6*E9*x=swk)4it8ba{lx+5}4`lG-jE3r@MjDlfj-@Nj-x}~ggjF#!K z4W*yuTY6=ST+ZLMVOR4GicbjCmy1Y~)YVukocx;DAFHt45IG^V6h&N_-EErtsJVo| z7-@fcs?|W`U4WkkoMVAfAhh`u>!wMpq|2V1mf&!nX#+-p6z`AIr#p`7B1uYi%QfYG zYj53$4u(Q_87w)2%Fx|GX{n!mZ+jHe><$*9!FIu5=TuD~b7<~#p|FmD+QdLTwDsED zbxF!+(1Na~12Sf^flt}N>8(qX*Y%qay*1vos80zk4ZqS_Qje@@_AiA?4`K^>$C3S) z`R}i86|$bNE%!+*eBO&)`Ie-w8>Vq~#Zc%Z?=%H=d>2LwwFinrJ`2F)xaf*(4) zunbvVl7og9c23iU_t)-AZVQU%MKwdT3YIMMe+;;Vk|y|@+~A$x`#Om-@{dAi$ZcVKoz%3&a9(pNO9HXHT%Q`0DCwGqCUY|Wt@FoBlP%aWb_!(mi2>#S& zs{Y=fH}ceHeeY#CzB^Cc4F#h^;@Yi!d^{FQD}dMU(*v6YSn#EIqHc- zRMJNX3`sB_c8SQp=8UC$kn>d755K6UDJ!6BPIo#n{~i{|Ng16kfFH+^Il9YIK}o#uT1k*wd_KWkGe`U(h7T>H zcOoUj?~5&B%;3V$g7c&yMA2~p465dmPMy!OLM(TUryVa3>FoFCa^Z`v?PJiKJSh;G zi9Z0=)~kEe8+N{B38K~)BdImonk1(eFGee;rvKiMr+HZ;^S-KI)nlVXQ>}Gj3tPa? zTmhrf2rk0fWmD(*+m?E|movg>R0oMg8Sd!^*tXr%sace?^0Vu^0nimjCB(2!=`c*&U3!9|STmW~`c?P`u#&dmzn7_IR= z-$ItoXtcOr>csKLAB%4^Co6jl(}^e;RjLS%$3{ z;Nfl5SW?xb2}pBz5QIkUWq5RBLE=da!a@aUL9Xo2MZY#kc;tmCreEuXgZS}^&-t#3g{+-V%C zq{@AnW76k?0b);v{{gej(IpZYl@@Usz8jC+C&+~FqvO1ST~Cd~A_=iHb|&deTfy_Y z4UA6+wnnjcIaa!BMl+SLKr=ZaC=1mCIeZG2I(%WNKdSRjLIiMG>ma(SG$xE7^{ETv z!a_u9C8cF0n>ti?Z51}Iz({vct~qj0jdTB+7G)TOMj65*vr|j|d>k|bKp#pwY>hwx zbOSf?EA3rD5MiW9San43Xo?khk>l=wCmFPQT0w7g+|EB*~bz& zEY_X)9g_S#C-1}<>y`f>?AE9WoA*%X}dOBr^4Lx z;KKIAgs4cJe$z#KyP_eOKoWiPr_)X9eGE)&)745i7=3?6IGK|<5PHd*y3DRaP6H(w z>#juJlbG+6&QMdclWT1sF6j=w;5y=C9|@>abuAq7A#geHjZyWc*|(kA1QXcuwnZi8 zpZOeeb38W#33Y4{tRyltUKu9V%nNu%eJg>8KMtyMuiN3}(W>zjt0onW6tDk0>yTah zLpo7T6yxp~NB&nrVzU2MjB()R_sz)g%6u6>ed24XPE&2T6@!*z3WreqK^RMH*$;pI<$IV8S+HR7ZbLA})WMBx*SCnGaG_m= zKJY@>bL6w^7S{e1yiu+ZDk%5oSJ&D+RER;|TY?`e{2Wf<{$}VLTR1AMg)6Pi57Mx- z-v6)mUY2mQJG0M9cO=mMQ^4z(koX4@1*?!hFiCV-zW>=FG_#^C8L0F;a3~>JA*4|A zLGtW@uKI7%ErDvbhv;t(12G-3;3h)@8!DTw`De_GyRp6l1qSt$y=BVnyI*DsKhe`l zOmEJ$(Uu2vdVrWj1MY^{(2$O-ED&Hl7i_|4FXhb{%&JG zE7FP4Z7UD0w@640K_ka)<63eO7SO%AH2tGVU91>DmX%+s-CrJQXCBWTB6xUocX_C0 zLRu$kj8)6KW+2O6HzAq5?^2B{f%&G3lG(Ga_a||02Mrh>qJN_fPP7Ic7l}9F_$3>t zg#x4zt>U13sO6q@l%ngRugpNRMZqFZqSD*>udKtN68idX>G5IcKnT%ch1iK2jt^UI z97LcmlQ}UQ8p&|*gJU_F1fFKRy|zi(&8Gyc!E-5fajg{aw3Q~C z3%46tkQ2}`Z^8^_s~+wSs*P186l-Xe;LjfKh#3(7gU0()P2@1e$K%(JhW3&MCkoD2 zHh%?92E=atMrrgG{I`21QtPA#RDx@tQY9BWZu@Y5;Vm>~Ltt$PR}=xH8^azp)l6^9 zVcda~b3*Mi5N89`#@_N4xkMdI73UGV9!&w_R}-!AIAdz z3svOzd8hd#;at6XwKH%k(zEW*-$>2=;kJ?yJe-`V01{xta8Z=wf~!RU-vNO>@|pR@U>y&Io@xbp2ME z`EXvHDu5p3C;_K2y7T_L|R5lo!)!0 z23|R8to0Zbu%RACjmF(NJfD&u6F_`uI}#KBPw?6rC&E8Yk6@}L&RG0(IxTU34=Az8 zxex_?{%w<#TIRsG9Hx0n>VLyd8bSW_7 zdRZ-0MD#5zHL)!EWq46-a*S7~e9J9JF#GOK#u-K-BB#mMOoU2;fu2{Bi&2Y8Z6-rc zq|Dj+IqJ*C`G7~6-bo3-uzyOTEA5Lr8C6s%L^o!c4;$&uSn;lC6DH*XCr8Y;`eO}( z*H=C;hwp=Q)kgPa<4R^ z11e04qAoo-#PP#-^pifR{?WHG?kGLudasDtAp=Aad zxpZx2Ln-Ux}ko^;!nvW72f}^Fh5y{bm9qkJpCK9 zP%Px&-??xu@5%6Yci^y~1M+hv^N>mOOF8-hZvZh{>5{keVhNC>5MHPj8AuDZE~4F_ zbc{Q!40u=`rKF=4r*3-p7Xe{^(&9xE zxks5%o}^!hM5Ch;xuX(wyNb|gT*O3HqAJRBODgeb*>Wad;l6aXv0Ac|A)qwQ-D5~w4)vo z(ZXMXDd#!dma;;slrd1BMm3))93jx;5WU)1w{A#aHNFJK|9t)PoZsi8=9D-hA$1WP z!X&aFDB61a{*WMk{ZU`Bq!g7iJ_X#DsG^Md2C&K@%i9>(`&TPh-u^ZGp#Rg!w(BIC z^luhr7-Szl0z$QMpLGkq)!T@7xSB31#fV&t2C%}*Px#fIJXd`ruPztUFL{df#?l=& z2XGtGRY_{sFL${ZXH2o6%ec=EeNqD(xxaG;58nFw9|9C3ic+ zJ*9GE0yob^EJp<Ue*n6mNlf;e+} zl%Yzq-p;3SCPQj#P`f$gxfc_l>m);9SOslT$%)ADT~1Gzi=7|$8)m03BXAuj9FUH3 z;P(aZ-^RV#c-i0%t1f7)GbtS6Jxc#tNy)cr)lFN>=?S}c?wbT}{^m32@p?%MvE-xP zc*Z6lQM`?ZV4+<6b(JoW|z5oUZ*m9%9m} z0>QMo?So3tVdac0ndzT&lDX#%UKrfOaEJoWcvl#`Fp`YGNwF@Y*WNcRSpcY&> z^-)p}o;7aRi}>X^`ck^#jP73+iXBwVfTwR{8N`g!8|?K^jBR|2v z2_qLC&h*^?tC6f=4U4TUB)(Rbv-IeL&CEy~%H5f-Fj?8G2OAyyWdE1!Y?+5q1c!{6!gQ{P({4bI(8d3OQLzqZw1Wn&SqLYg?|6=c9nS zB<0(4v!-=6yX^qPqjBgo!PMVDp!nF>+w}|5?^o-o8^sqq!R;2=JDIDBjZ5W`dr>aO z`veqXE2A(KnurC4d+xRDAB_*{L0Xoqg{dj;0m#W@7|rn5{3qH1GLkCC4~xo0*{^ zz45y9Nj#tkhmZ!#n=><$&}Z9Lq`u?L%}30zcN;GuXMZ!7Mr5+S)rF}vvo%=m2k@n} zs=@oL58OjBuh-g^9rJXj34QnLx-PQGrzzvp-b^hpx3pd)}2Ek@JhJw99wC#akS?YRIgOj(cB`k9@J5geX6nBv+;ay=Y~ zpPe3hR$7uIzW(|5Wpa>eGAlQBST>YZqpR5`WInla15UXNuiO~bF`P+8V#+%Wg{e zx+wmfX2jr+s8{}ALiMc!mRX#l-Lg5|vY7y)=YbmZ(*67T<&*OR%QLHGFOW{3a(VrLNMHO@PvUguicU?#<`yQo=NWziZ-$^s9(f&ILIXk@mBzN>n2d+T9i zt1V}_&a#X4B2wc|OH|IDC32UA2jaA6Ofrd5RCjC05Ax#|Mc!&5`8)CXhKIRgybW|CtDn2V6(MG4?R8_(9k zUuFGud9|M()i-CGDI;(8RJze+$An1pj3q=jEWDcn7m~-B<+udX&PS*nj(Z(~v8^=j z;?5JtU5}G^!4SisM-*K%@36zWLIWF#W=_9QY84X**)e*JVHwLJAF@tAGb?a<*Z1hK zc{^g8GKzi6CE2(r?7@f_m<%5Xy%HHwX_>RNG{#NnjM!u=)}dt+ozo7E{w|_K!R(Wz zgT!Z5{XHY<;hpN=_o{sEz|TOctK-8wPxbK<6dTU9OH5CaU+DC8N$MaRAVE9PAh?#EB zPRq=~`fS*?{qt&--r`}C(A#<{B5ax|!uYSoA$;?ZNY{~Aes-|UkFyrNYso;!rp#*) zKXOticxyRB-BsIBBH}Y-%4dv+>Pe+q9+PQ9$m4~eN&BEu-&B^oR+1W|Q}A9e{@~;5 z+Log_o;F4;FFpUxuZLrf;gFDb0^zFpna;~cqa1}&}T@Q{Lg~z^!xLr z)ObmWwM8&&4ReqWOpm@?Md@cXXukk4JP$EXv;IUc1(ZwDMNob$Fu;3`K*BDWQj%U}|K2A(Njq>eem*fV@3rgy{*St;<;T;(xqMUF z$3(6;PML^>`V6JXx6xIU0r7BYyv}pNme` zL*GR8_sJOQU~F^}bA~S?Af^ws`Pp$ zXs&pc&Vl#;0nrM7zHFeG?5{k*J_v(bAxQ?G)abGJ^M{s=Zi0(tn%T6sKi{c*REqXkw$VlW?!mp~kF&fN;_)|D znZEyaay+e4uJJPrH&-P&ukCb2Sx!vMdzvp^-gq(ddZlJ;{Y|-G;(~M5XhZLXmvHxd zSEam02wH1rnec1Vb4l)Ccfne6iD@me5I(hb^AiGwafGFD-*<4?LlJt&}wM z`Q0OVsZ+1bmAO3mxTD{9C%tMg(P@%xAc{zdUdroCUt_C3e7lAG+539@uOPS-{b}sx zOD&(%I2_&bm^*dEm8Ebhx$K! zla*t+_-v9@#hh?wkbZ2{eP#}V^20Cd10BWipOmmkN)kF)*2Sb5jQYXfN{cu&BX)8s zkC!jP-osEX@MlFvTr;(Bt|H?;v)sM11U_|gz6y7uOl#weglrNDgl~T;R3#)2{(~Ls ziQ&ZwJg4QE03joD9uElqU_AOgaupPe=Y5*(LIX>Pzrj%t|2jTXaeo5XO5pF`hNqDu znzq1W+)Fvhv89TLDa_-Jfedw+cK_r}y27waq|0uem0tM1#K&rpV&D(wmV4TYPmGVS z-mXc~t?%;`5`R0%@WIb$9~5%-BX_(VsspOOhMp#wR;0rbEIYLQ(VvCHL0RIHCDz|3 zem^tw&jT?@PvQ@d2y3bi3Xu&;Lf%%AMg8dp#av_cg9bqeU*>L{pN@pAt2WPN@Vj_^ zp|foEf$g@ZIdD+P<9mA?*@UNxKU~{}UUXk*|45?#1PA<;(I~cnd;1I|sYS{)iHxu6 z2#Qv4<=356C1y-<=FpJ>9@q5R^As1r}{m3V)y*Q4fSQT zM48L;XL6Lmb;WF9w4tEqW*ev*6l;?a?|~k~o@!mXEikkd@93J_Y0c8JJR!JP#=zgX zdst;mM;>Hv)3UpV>U*J;&WjnV2UT2$co~4VYEAnPXxE$1)iH~!NH1nCCBuFUCag56 zl5|v}Q1m1E*jc9c^6TB&(h43>XuZDQ?(f;<5v$*m0P!}_-d+EF3N~UvuGeVPDc2Z$ zQ_yMJL*`Xy_R1xR{me&wrk9;2y053dp296h_#*9uXw@;J*z7ao4B9 zD%=t}MVTYnj75cIB%|ZOBZ1ejnAaZW>Ylxzf&DetQBFwU&DMG&Jx1LQkB0K5yaWAW z23)ka+s*UqW+dHSVX+MoFv;>V{3O*8IQAUd90HF_fpzR#_&+@YGhM%S*h+Wwo9F=M zyf>`Tt?}=x0F~uc%(Q!`tD5&7{=P2Is%(R0{?6o~-V`4AdA4{?BrJ}fvdfHYHqbF0 zVPoiL0GFD^kwYW~x`0i+18oSzFz+TH4CF1!{gw+{ zidm3>8XmgP59nU*1+osHJbGAMBxG%r{`uJR_vosp^|wUU!9`D^ASz6?t!`@saL^~% z81J_DLi1gvNJdH6$T%x~7d?bS53n z{DmnMzD0e$^CtWxT=mD-P~sK7yy+dQ+q92k(5nJM|3By%S-j|Ir4(=;xgG|SE47H?ao(Q4w zhWb#_4$NBRS!C-d^4Y^H%4AjKO$CNi>ZFwowG*CN#{9#@x6wP-*mj`VK~d9_lo{SN z7*?@vEc4IcI<@g4mlY8!HqZPYmc8J@(uC8+KNyY@Hl18Q`On-Qd{Sbg-0%L@_}nj+ zXSerCJ;qSp!J3}%M+(VN%+CzJfwG5j`-CK;OkT4Oi8;zf2?@-mgU^Vn&6mKlls3Qi z8g1os1_?L?Uq~_kz4nx?I=Azq@XUc>7>A8{hhn7SOYsvUyiNQQ!{ zM{O@YqMm8j-UqaVl8X8B&g=3C)Lwr}cx2v)#aDl&j#Rb@1!)(o-sq+X6UBUgM zEFQ>N1KqRQIyE(V?U2aBm|Z~~T&`V^Q zn@(9tV;;{T5#-`xbE61zMx|8cqpLz+Vy*Xl;5sl+wx#6WC{LU&*b8z*fR=L=#oLnk z%wtN0Wa$zuLY0Kqdg(`;1M)ExifGud5C|ByQ8B){HhnP;u16go;V-t|bA-d>(~zgXBqpl#Trv6aCDd~DO2sBOIOLScLlA6YPPz(fs#5D9--Mf*1Ka)7Da%~^q$*x z32|b!)6dxp|0FGl&5oUGUAqYbudH{M5^qI?x-7TXnUnw@sKvs2IQX6+Y_fj!l`3mF zeVKEDYyIqNe+quL_P>>5e{$S*fib~osU3P)t@-FX>uh&e_55m=^+KMWti#_P@%}UDG%B<2bXN2l6{y*6Yf&pg1h**3A-LchR?vNN%> zRm;MyYpbKji*&!9l~m40T8sSefKD9fk|y`_;^dfPWqP^ISNJ^Y~Jy2Way?qN(diMh&&n*WGR$P-CxUGM=$# zp2GTh?oHdkG;^xuiy_nwiB^(oWJvU{+&e6dNxuC$r>zKy6YagVaYhKRn2B(ys^ULh z(g6=32q1Hdy%RXT3+fVI-pWlp^!S?Sl8<>6J_yuc8z|1kF~_n)Ocv{Zrt9S}JI7^d zk83Xi-%NzoKSBPshg0*Ip4~3~Ey?!bXUny3LO6E)o+}(OF#xDxD&LiyZEndAimo==f3VfZFeJ)v?K;=c6w}a2@&%Co1TmKdCQjV z!xryd-=?nNm0wsfr8amY2~$pF_NcmZu8%tWp%mr@yGc$xO#NNuKsPPFIE-qJyS|Ba z)h1&yqsp)zwYH(7Klh>)fY~AT>yn_0t`K)+cg|z{<;aO%2Q#oyL{{nR+GaUp4&q zwoPo;={BXdP@x<4M6i^|6uys>TU$`Aefq`P-{pHUaztumzWcA6y{7&I*=gX#m6c?Ah$LnvzU+Zqf~Zo($OGnIyGGgA%1aaZ{3K8n*hY7|U;BgCD>>_b%l|kZ>1eJOod1x!G91+d zGbBm&OCLBW?I;>$stD0N6zRgJm!Y+=Bd1pZ3C@d-77>f5N2&DLc8w&kKtB1WlZ^C^ zm(j488O5hZHxd!}JGUU05``sMkX@Ma(UcYB#1i-^`<@X*f9@4bSTEc_4_HmxH%3y8 zO(7LFr(bn~fFVoo3sJ8E7N1oQ-6p4>LCVi4(iPhf+xrM_rMS2VC$uE7qZ@u(osN&+ zb7sII!hfIjV3n45?7?*HHbdYX!=PK^tF6bNW;4{Hh3T#IcYV!v>-e26KNpR=GPWYnvbl|XN$W+G~Or`LtE4DadmMHbbc z?91G~l&FXAK6TXgu&b(J8~{C{-si@co?2>LMK*_6w8{m-i5kD}%srsDaRL+(6Vh~} zBc%qXgzRdUU4!t(Nl+7;%dDbaoxoiX*1DVXxB$7ATnX2@jgD>!ba9Vy0jnVoVvxaD zOw>c3W|xYVWRJtjh-oryB@OH~fS%F_p=b}~Xc!cEgbFcN{jzDZ0~uiul_9k`g~9CW z2|r-4(84fz?YGjUVeitg3d|QV6IQiAvEdA8`jBS8(R(26eT~=ojQEl&_(%}W%6@r1 zcu>zr48{V%Muo_>zI3#A7H z&1KT+)doJ+d*{IpcNqV|Wo_qP>`j6)7XjjFugeo8@U-dslNm?7EYt(wVzERRS?lxK zgai2wI3&wzYj~GsMGKm6i1vjtDhKD~yhBGbCg_pS6~_@}bFb>?tzx9e`oTNeBx|ef zU0RP$B#w?`$m8s3@%Lx1|1sywtlgbSS=b`$Wf@A!bpGFdvxw_d+l%Tp&q&sS8Fyln z!zJ2)lj8~TR2%<<=hXq1U~Vq4`0emj?a7W?k#$q5v>ofc|79iVS7%6dRY^JEl`o^h zs8Q^lVy9%!O~;#8qj^x_!8edrdL)3Bt>$N+51lXi*u15x-|T^JF#0;UEw}prk)e}B z&kzomwvv7o*U$cQeSUXE8o>e+Cv^|y3Lbt-i@P@zJQQ^uu`zO^;;kr6vCX4PBv`^> z>ZDsonMI}1>JRD`|A~#OM=_GPwuQl)JlcPs^zBf~l$QP?rI}G+7S6&UP}!=iC7wOj zMerKWDOnfR=uy3NK;<}hF2r(mY00U^Fz|9deeKf;le$e|FF#jKL{to-4X&7tF46lG zd02AF2_-y(eJe4?SWz#Jf3wl0SEJsfuP0jd$DeF!c0X}O@y+Z`_WpN7j?(;nNN7v} z5kdQPSf`gEwV0~o`u@E4rZU)8?M)hZN!;o8p5Du#`d}N6PxY~K0_POlNYzqjElE2? z(zAkNT=!smsV|xlb>0Q-{u&n(@cR{sx-E#o=tLIs$@vSySe*yEa8@g_4Cjx#WfMMs z4q0s9WeV4tcTrg{^$+mSn@Y+i|HH2q8%<6IU{WI@{qQy-x*qkdf0gS;gA2ccUl#Ef zplF{^Hpgz{Zdg@ngJAz$5jibS{yI0wl#V^Ks^IFv8LX^&dl{DfCwX6be@Vds=SqG3 zMSUI14&sq#!M2G>>{mF^L_G;ltqZ;J+Cchn%tw2|#AA-Xr5!`w9IM8h$(mC^$l>nB zU;gxDSkuzs0nOwbkAY$pqAg2;0ox0US7KC-RDztz2 z^1>ow%2_IxKcX>;Me{|D0RkqAUj?)d`bI$?&H^@XvcLjAuZZ26z4BVnA$+`5(6z3u zS>rdXdYa|C^DaApJ_sySpP{mEuEa|D zpFFT%gR;7{!4;!RUs3O*1=8Xd7t*6WcT|H}T>P8+7nAIKV*N+DU?Gl~V86ayN64Nd zO99Q3IYz2K%5=^1JGyDKN8UaRx zItl_Za@i7UGr|{jmoH|xRF@2aSmnN;@=l%Ve}h^_AECs_!T{k=2EbL_?;}(a5xlc9 zFz$uB!|<4qo*i~1p0}rtq4oxmsUp3!!n8OK4Z4joHEu@2$(BA9(`Uz)omt zwbJR|+u_z&Nn^d-&pMKvp!#|m*qGUDmoUXH1?s9(-Czi*Jq;B0+2tY7g~>>6sfhxA zLP$f7c7njyYOyKG4ivH4Z_S^s(1|5sR#6W0GZ2-%boe_*O3K?gYSlKo4(HIk6D+t2 zQd#(mq1t*bgZxZ9DCbej3s|6{eOwPvL;vS5|IM7N?uRO`n6@$LCBn#6o!3nx7naJG zl*EF`y`h6mYdu@b?-!iGsn2-ifrEkPvLg&b+RD2feX$MtnL?nN@@VbFdX1IK`2v+A zTx;i;mHy5nsAWpZPV(GA{M-XZ7sy|PK?+&7ooirR)1tC3LFJr-p}P1>iGKCjwD^#X zaz=mo_vp@r4jVrsM+_^()L%aDWrN>hg{_q0y;s8+3_#X;bk1~X$WcH6*QwVWU)rbU zqh4+Nby1hbm%MN>cyQ`zON05<&-HsA9gpw4@P4w#*Gl4Z&oSmK7a|H=^>{5eBz_>e zu@H;m^GX)sS#C#tf~6tTbY64f-@ z)ma`bwfU`y{Xy0up0!FYxo`%ekxQT6VC`7iFYngXn)0LL-H!?3NxF?Lz$BnNz*wY# zNE8eJ{WkHTfOxhRF6KASk4uz3bDcSN$~N+SP03}Rtwf= zYwG4Uc~q|*TNi__kVjt!EHlA*Vb{unzgp05=@yq9_Sc1mSQj<3AesQsp4EyAQ0wFZ ztb59Jfk!88Ff7EUp(A&c1+XqJC+C1(yaS9&1H)KGawT|ujJ}_1vA`9H6C&%8wLg+# z)DO?Lj85juptcLDIB#cYZMf#A+mBEwZ_ELFEY~OEw#?C*2EkaNS$C)joABhCB)u-$ zA7R=2gpKYr)iZCnA*B4d3h5#T!fRYP+snB0)%^eQ^yPs}KmPwAruSlcD?Xa5i^{P= zBiBe$Io7Rmta9hfIoDi8l5=Tkm=uzb`!;f)b0p?IHutq*w%Pc--rqld|NG-*=J|R) zA7?_VJd=FB=G>XO4|aY*iuAH8Rdqnu@D=usXyLZ`!Q;2;_3K~Nsm=Jh_Dljxv+>63 zeLt~3x(>-5czU%sv}Fz$q~D9f&`ye14pfK~+)$c!r$S4FZs@9Phz|)?=YvT{%?|6| z!Q@J(k700<=(!X14l2_t9>XK9b4>@fuShb}<}zFZ9tbDf(s5QxU6}muh#o!sf81?< zjK4&~u0LsSdD+YQ{i}?Ig3+W&D|A9va@x1hpKYVhNFfIYFS}WbJOA;i#z;Gt@f&BS z&LLHrwGgL}49oDf{RTsWki9GvJ8KBDSu-8Hleb69){M%gysy}E#1#hbgjwJGFO(7) z0vJxyw(k`hR|TnAX1p?#nyVDLfwCI$@Yc($Q;vtu~>GJ$V+8S-#l`ui|1{C1(q9umv=QxMXcP<&X zwsu?WRae-T%1lVY7tDyp=h`vavw^ycyTB+P(>!3Q2{ABkAD`u`iGHNaSHJr?r$5L50OKtJF2$L z=QD2Pb*w%-WF%DC`VMUt63Dn;)j4ok`y$=^PB)&kN$IjdVqnT8IjELbBCoSq)Fud` zmeYc>VYQyF-HV6=Uk}lFk4VP7aa$4LFmKg6=4$vL1gP2I;pwU9X-T6g&U8Q{=j7 zQY}^915vzp1d7;sp?53@{QX{Id4o%WGV;zF1=km0a+@wM7;%2JHvArFfm3`_4AU3e z<@#xo9ic?Vx$h;75S2C^CQ_4 zIWnUj2UUcG)j1Q|jngivz4_{kO znQBnY_4UAbdKSYQTwQwA$Kz)Tg-7Mqg5Fr`u8G5FjK72)1lR<6OWhaj=b4K|W}b?l z7-_F7hVSd}1sw9(;knF@KnM*(@v~V6{eAig=qFmX_(lI4dHX}WsL8{m#W9fv(hY>w zP{pw|dF#z4=Y1q}XTbO!GGIuK_K&!!o%h!LlkBvESckb!I?OC_#c$~>JKqj?N8Cs7 zhezeqE?8YrGz#>gL^z0Ulvg~kDE-+U2h=onZ;M(wn#Uo=crckJfgQ%>v!8?DVK%AH z5kQNm)8O5dro*l|6ZW;&QFY2B@@?t!N+EWWoeMZuS+d9WjdN1dH&k_ciycapKM%aA zcU+3N=MTImZ@&kP!C*-;Zk{d36t=C~F>A!@uHA!a$o?}{G#|X)Q$kM^76e7MUvYi3 znhYdIA`|<%aN?s0I)fLUl#{5qS!jlW@L)@8C?T@s6*UWt--BlXwK?{np5;d}1ai79 z2|-q}h{Rb2ANxkUnn6*eh`@q(jEEp#nD=oQ_955NWegddpiTa$%^A=zBeLuYHJAR4 zHyFrQYL|;Yy1kof`fdLFXb*bY*%a^P^1&=>GqR>|H~9*L&Kr(d4;^Uq_wGni8ZfUz zf0XWoV!XGEF_}{mTeHUQ(^su2=LsPS;J%~V`bASbxY!3!{HE15A8MbTi+Hq=dBIxQ z)2@*Itpn&Jp&(gFav4=|A&Q3k8_`ET8(r$(;$SV?iX~CYH(0 zgQfik@E5)<0qr%k8C_Jq+2JF-QG(XR(an6l$iN@?4*T?ZE~A`mjF+Lrc$7vwkbVZ5 zCU>dN|Fg%U%KzmcB{=zYnYo-FylKqn%5fgM>c03%&hbrX1BU!QzeL?~`iT{@Rf-ma zI_caJya%7n;yb#MkdL^bMQo9A6(8N%B}>m{y^@qcef(eB%nxT`W1VO1VqQTlaCG^R zQNPkfVO*CS@yEqo{*2ojqY8+RylV>9>E-IrQ?hJZ2Vn4v9ixy!lK%!h&7$ zGf;zerqE|D(09dVEhnv1{_1LoDe-~3wfA?We7*t08j`P>9F-$aEG4zcTMikP#MBNY zrzaE4hL=iQ!|I5-W0nLhj@d$7Tf29#i1+)Uf|a0H{=+Td-&zRz*3%f~OcY_?loVdt zIYSDo)d#2fH$IfpfF3`3bMn1v1DFmU7Yc&6&Lcf?&40DEmGJ0Gg|<;plNZOiMKkLQ zT}MSG)wXL61djOF>v&tW@lG7|rZ^okK-TBM!d)KkAOhux9yF5Mw!mT}Ua51}-V&rQ zfP(USC{?>O&$Jc5uZ_G{T;xM{C`^28dNcPMXDw#+f9eqdG~NcjSZbuvZ+%pF-)mQZ z*V8XcmCMSCP!n}VNL_)1k9>pQlMlQLRkEXYfyL8%>M`M6ku`?fTj>>3Bfzvn^fSb$ zKgH8*cYaQ6lG!BzGfRA83+yz8m&oynZNrs|d^&oXH5C#-!Cmv{Omt;7fOAwlkPa;F z8BZv1r2>eyA2fC~7h=hfbv)utnnW>na{{J~l(|RWqU6>v^DVppyD)7)m|x{f)IP`QG>{QHt|j<6s9a?Rujp7k zti0S;s14HJH;={uVYG5P-vYmLmw`r(+ zX)yFS52@wyFRU)%Oub8(tDfgDa(Q7Jytwp29r4^gVyf};r|>wSy6N+_7mxxhFVo(e zUX!`vKdO+@{$jEl)^a>Rr)UqQ2uE+@Tx8O^zTKDO#E3d3#VWE>eN_wI^@!^T-rg;t zYUv2h;)3;$R0P;|El{yAVv47N*5S+*yJJx&MuDe_(G9?YQnb~P?PhejhQXZR9zz() zdOHhsJ~%_7e7VRgh^(a$^O>HF zVEy+5g3iB9dOH=RI>V&JSzbC2A^UhaXU0X1ao@=ChTlWYY0}S{OaX0xzj^pRohi z)Ph?%aUqL-t*>as+Ly%Y~k(i-n3>?ZX@I5gghu zW^MS<#q4O@i?^?QFvpHtmB;GJ2#_sxYw0_AXh5DiHebXJi}2DzYzew%rCRnVlzSHb zW4;Js<(NfaDL(_7jbC{!Us-XsA@w+qlPXuPW}G>=JQX-xGg)?TXXLzAzk~I% z-aHo3H6iNhvS*yA%k!6Mt^PB9_bNrK_L@*>_sn*yf*#z8k`w5kDutQPvg z8^l_%-_3cZ;0UD%iC_i?UyIkP|ElA+&G;2&+cfd|#*+v_^_)kt;K}*SzaMFs@;U}S21wAvqn3Z3LNU$x;C=Zl8!`E4=!+g{kAD7$o-)Wf7LkT-iL)y$a=--ziz_kUAzCQ zUi<4i+9Q4p{_{tU^5;>o$pQW6QDy6ya|X~{Ig|QD6^Wx!$lM&Rv-5VrzX`;B6G-{< z-O2BM8Ec!@t@m}gJ{E-aRo=`6Y3Z6JXZX0%C0FgI$E^gI&G~NS=xNcyQT(dy$3ny| zF;7vl`GW(mi>5{f1-C)2>$kgx42jXf`q5VAd+^Q%(UQ-`WGLqjtPATlN-XvtS26o> zFXMF>iDh?ka+>Jy1j)lYa<8`gj)D4}Qs25SJ<|1YJ*=Tokx}O4EIR(b8QJ#6_x$;< zNH=^gKU)@GqbxqT=)U)pz(Ogm-a>Nw!rvmEibN~SYCu69Ru>Tx)wo{IU1dz}gkr{) zarwQ-$UqEGsjVrt(XTC*M4I1^op}D9xzlF=$?pMNYrB+FVA+TTcGiM2b(5J@WLnch zK<^kPR2|Wp1R72Og;8pdY0Z}~T^;@6YNNo`SX(DPrw~1VwqalMLXKmH!9lTzkQ1%T zehtFygXH_)J?K_vHMLb}?^1Z^)0N{S^g>tizIY5_dR75DdD>%|z@&7oE?pxo=G2eS^>()b}gl~?~FO1syB`2DhbWSv{TuO z=CkM0wj(&j0cFOdjxa(k+ku9m{{=N44`7|XX|g2mIW52PFEbQj`=bDU2INoKg4!wj zvvaTB2IXUoWcS4jvpB~f&^gh`K=UQ& z&bU2TWD@>xUEY@a?_1`$z6kyVkr{J2s31$MpKsqbkQ2+lF~xO%05I8VDY5ySez4!) zBy>-`-=s!@;NomzJ*UiJ>(pK}CkgfI{(i<}?VqJ<7UV11;)))-jDvLW=!U%}?%z3f zOonmFMzso9@I5fq{>Sf%^#zlGy~`t1;_Zysg9?_8IZT?jjAscK!om&XV;zBZH&)5B zUqIuSLBw^R{@c2Ip`387>P{>A{A-}wQ1l;BXOR936y4{vc^^eC3RRcrH1N%vMajCxy{R!A*-j)$ekKm^d#jf7e?NhDU zdGEl;7ozxxeB+KE+}9NBoODUxN*ykmia~K)E4VN*s{Yy>SqHjc>n@M#=-}mq1hvLZRKGRZa+Z%kvf%&ViRQ?02JOBXFC*ql} z5d_zxdlyu>;}!$#Q-O3NcbAt4@DqPgIV)EGy7fuIJ^%k+1*}*f=uN#~cF7mRa)&4@ zY7yB^mNn9AF}+QAVZ+GE3 zjdweSXNLsNX!Q~zBUVlmn7r>wI%-uQ997pwQv0l@9*aFp#IRzD8fz7GmsGjMwH?;! znpT~3V>WAGIYm?Ov@!h`7XE|qQXEHL;|$DCsq)NTvSLOHDWH1W0RU?AH>a!erS3<9 z?Vgi-v2E9?DbD*|fi4j5Bn;A@)Ey?&X=ko6seCnrNG)=Uu@6sx{dH7SOfO{s(*H)C6%~@G#$DBw{cL~7)=x{u2!qOMOW3G41?**U5sU4kRpI(i|jGXSLVHfSi(Omq3LDp8w?c2dAR zsogf_=d?a;1M@KbU%heVdCKyo-M2RP&Z6~9E^h^b^f}Fzf3fLe0cq>O@Z{+1#qg?C?k=K|^9_Ja z)y`77d;FC3Pzfw`id}z3$@|B z!a+yUJy~RwZXXh$SL10p5wf%?@C$AsLQOBIe3z`HJCg|6wAp%8BqPJo6nyvhr|MV< z$8hnV{bMlHe|;-~>8mfw05IeaJXU=65Wa{0ATsa0PHAC825Zm*^RIu*#?0p6N96@naR!|AO{DAmCI^hxK zecZ55x)a#aO^9t`ytO)5qbnG|aK-e{;NatD`Jd{KQ3kT(LZ0rnuMgf03j_~c$PmlG zYozW-7KCzRfa&O*5d~mMV#~Uh%O%Xjw0rRxY9dKsH>TMR43yJr-mQH1U*}rn|shlU9YXvtz0-Fp9gpq#s1b9&zQAJq$JtDKC1_=rHq)=PtR(bJ|e+ za&u&ydWq|LhI7-zJV6L@z~R_d-0b+cTs2GJ((~92PduL_jI=jy00vIx==9yG8~LzV z#Y;P&m>%}SpuPw#0yQy9jjW9|=mrjp&9a&J0@K+wq=(Y!8pI%E6Fi`bN$zm~pZ2B5 zdzYbakiy#!3TAPui=P9oe^ndJvi<(^K?;sXF?Gi)*t$DfmpCK`|M;iq`JDq~o41yl zAwHtqqj~Yfhce*#m{H z))V{i2i=X#XueL4ivJ(K#JgJ61V*w<-0_B{yjSDmk5(@d#WkB94r>0{Sj~{UE?;vV zCk`WZh{lb$2rHyBk0{$zzdGW!R{vIp3F4v?cyz?i!>i0&l}Eb-Gy>@z@Pter@u0c| zoktT&$?1$h_s&5r`wUfOJM_e8ivbfaR+J7x^1FH?K*!^aV`$D6K9&O z0;srUzqOUr*7_31pt{-;Ce}PPGvaE_f!|Wju_dF5eR1&U5;nw*mG<`1i&?_qZj(XJT0~*K z+r+$qu(hSzM&*V17YP?q*$**Jy0&LH9TT{hUXx9cEs0&tK&FS=_#iHr8L691yejy@ zxSo%xP($@wJsjYRvSyKsR4_ow$}1D?W3V3M_jC0b+jIlQuzmkWp!~;yRS>jO`%|s$ z)rwMvV({W;*aH{_%=(A>9O`P5Z-dF?ZXa=VTFn@Kk6TJH&0W^jLfb=0tJ;v>p1a*y zVLO)*jS$$J#vOP1;}k!pDs5>7cUICCUpSZ5(=Gbb?|mLawB@0S+1t1W7K6Dosq|V- zb~PK|2Z19xSVS$~e`tMUe}8JCY~&o!<`eSQH)UeDCU5V`?!s&S!|q`ZGhDaY?QKN= z3A4B(kacAJiH^7Qd zLq=-p^(MtmT-(G2SQJFavYWmap;|Y+GVH&sFL)iLlkNV-J8-mXcuS{;-NdZo0h!Wl zRE5x4&qErE*A-5Vd0SvQ-8T?AMhcvKm&M2xz=I+B`$E2Ab$XtKv}FMK_$KKRkl#K= z&=u6|!e9lo4l&Z<3+@>}?55o{9Z0xK91XHIKkc!vCYjPMe!vkx*je2NaXtjv49HdT zClY?BTs|9Bf7NHhx^A&5K07eu=xdnJ!B3USyn#2B=U2I$+<8pu5bGt^jtygB* zq^|_C5~+!mw#BD+fU4WCBXT~jfnq)RYrk(z-UI2=EA)^;0`kfoIWs;GE^_lVdnfikx%B*1h3)Y$x z%@x`6npw+X_gL$JkLFG7K>DpR;M1HAnDt3NprXiP?ygT3?XBF?bs$yZ`EE`SNf;g6 zcv^SPPCJ|w$Bop|s$M4bhxr{7grES*@_rgBfN$b)oH9EIwYmuAjX|?IPyxr%EhK&V zeMQdNOSDx0+?$Cs=l52se8QDf&O2-P-936H-|d|q31*gW;IrNAz1Rs2E!K5#tkV>I z<|AUOG`T2F%2hTRC;BI4OR)Hc!>rYIdXUv(!W*FTnTqqCV4q`?i(Y-%j}*`oKM#xF z*t=(n*oeshn$M4g{2@gy-MdJLy+{D*LlB(JL6o&gxp<;{@Q=1B0M8G>Z!AHWpS$Qn zm=|9SO`byI2F6!uWpZ#@u%kt zhi|HGh?0sGKI7g{@SGe(3-Hz#R~#u3I;$e!(Bb*Wnz^^FpkVzO(vJ*rKxq&42zZn| zv2n8r@O^-ptSf$|5U=^-H0l^pnp}5iA;Et|X4!p(QES@oomd8-aU9|E3Rqr*5GcS` zrjD+lfO;yOs)xax$%^QC7i(d*D$Ma&}MuJzsgN-w;1z1%HZ>v+)L?hEgxA z4QUY#6cP^qohxib?e9OK<8;X`aTwquwg)}xJO8!~4W}0@#bY0-6<)jTUj0~g#6#Vk zG1xR)iZO)kce>|TQFkpb!nAf-jNnhwrL5zoRa%Yxm#F%F-?u^8wX2I zc87$&pUZ%IA?9=?tYmf9`#r;QaSQZ`DOXu&74UCQk}%iOaBwIdz~%G$FP-J5XG>B1 z8NBYO!~TuA5wgLtgtw#@sxlqQS^YP_ABZ8Eu@F__!Le^sDJ6?FjC+d!>MggnUUoU9 zA3HoMh+rwRR;kji7}mNUF)(ZOoI4v;oSxk3*GX&v=WwFOxMK3-E8Cf3BfC>EFAfHq zwA@yEg@+MBxN`-AUzKFvUXcYCtebvPv~~S9TA3uz6l1=4bSRY-{_EM%(Z1su)QCyN zV+}(kjn7N^^?Lm=k6H(7+p!MNqndzBe# z7;68qX`C5-{@U%d&UP#OcXKjjK{qI9PUt}7PQ2pck~ociV;n!ZoqeLM)UN2fZpXcM z4xZf@IRv-A{1VMDK}Z3r%@(|~tN4_bCmE+;QN2sbB**CJU?2MXd_@Xl0k$7Y#Z6Y0 z6-j&tGt`h{-UBI>n|;lA<)Al&O=H@sAznI_O_DXKl!g1N`Ih}0Y# z3;za#>CzM1{tEmX6g>S9P%}U6V*}yL|7!>RK#ZMX(+BQbFm}yHm~-ILi&OYt+<#X(p{?r+6pAViropG<`WU58^FCsTgwAj*O4n8%>!2 zD$lkdx4ybK8gS@ymlS=1mMXaPYiW*>rvtUI zX9C+D&b(3#{zkbxHK))zgt>P^;w093SHWuwgu$H-AnPpy{kn-4&ALPp0gbbO-*E3|%`}+B#^_7?0*TJ1nU{zVHbDz^If+$5Xo}drh z!{!HDFKj-3m69sQ#1#JFP*2&rEpwtUyFeqq!9q+RN=-&amjp4fKZ@T7Gh1kl`q6T-Co;xuWl=vMxr)UaYQ3abVd2**P@d3s&(ko5+Wms3f4ur};3LO9@4#LxzN&et}Uhv<< zKIQvyq~ORK^%W8n{R2P3Z`JreK_>lk&RQDaqPw1U%8AX{%4}UuT8w}8{1y(!k|AtGhR4sk(Mus?mxBH zr2b{m^aa#Qtb&X$kky(E%jR@a8ViMk>^3z8GZpk4X6+*$R_=W@sf&)USGbvj-j=kc zfB5ZuI=Y@u?LemGa4T|q#KS#Ig?r4+_aZ_oV~LmMCt@o)+T1P92Oke3e3+3L?ZM;4 z)@60_kdsW)n)WvFX^C_~bb#kBKTgO4ipM;S=w6bl_a41cMKu&BdM6d4zTTg7i60f2 zSZ-XqC(puy)-Q+J``&gFoiOrsXDs`T-Wv;NIv|%`=fa*Q<3^vYc7gGK*e~r=W06Y~ z9@yx*)Zt&|`$N}L6lK%;il5khk+lwp=$2bZZ(W*IzB;Qkan0w$jHx*O;%s!RDJGiO zqYKh^t(+QhWf;M99sLRw4@``_KPm>3|4ERuytZpx@MeU}=+0J1h42fh!!&(pv(#a7 z&~a5?rJtQr&zA*WEiaJ&H{GMbwIr6F_e{K6^%6v~TDC{*wjFw+DfllD!1cU>HXSWj zWN)(mD5OpE`mlg?3Xn@%kBsv;a1RfE6bqo2vpY7fIsY950o`0Pllmejm3PWtSx?%9 z6)Ywh?n$(@z%U)%*LKLO?{rQ8IvXYRcr^T!*)=g_&2s+#93K1!$BSH zOkxCzk@Xa$Pj>6{cx!@Ub>iH#G&Vwh*sUm8t^F|Jd`N<&%+;9o-|QW@C9YJTNz~zN zuAzQ>NtXK4uj_IwzGPHCB?h%@6P)`ODYf*K?Z4gE-s`=5jjuqhYOb!w93*T>uO9Cr z7C|dyMuM*bU6AuV5waSxI^#x7!QK;~yuY-d_S&6J-@y{cJxXjj98IzCJx8M1a z?kiV2`k^HM&zQ{E{x=!(N+QF8VH;9B!@roQlQn9Uo(JG>ncp-!R&{R@(zEDh&xrzA zz_Gz;c^Y<*5S==k6VOxBA(W&ZP%)^y>pVzFO2Y4FFh2G&M&}m_hfYDBQf|rl6x*=M z5S%*Hq$OsF3cAcMt+}dW_lbVaSkr|{5$6olh7teQhQ(?3KP371&8(0Pda*Drc>wLa zZx=Dej|O4{}q21;-)zD{DU z(pNPu2G@}zyeV0C&yEd5$gO9JUZvDT!DPO?37Z z8ON0;8cJ(|@tA?B(J3T5;&0pEM5)910Dj{b&wW{X zm!T13?s?OpYLC(v>F6iY4C_&C>5~l!Q@4XjHySgRZ_1NWHgq*RPC@q5mK&-fwVpiN zsPOw;sjM}{3rO-7#^$Rjhrog_!?O=LUAoeazccdd-%9ASlP09oIuXyA{A2;^ZT@wD z5$h|zl>uK-FL!_Sw|r7uz|w#=MC zX2U1@e8NVJPr_KV1T%k=^FeoCd>y$qVe2~JiHvvr(lvSCT%*&N#_nrvHr%uvKj<}s! z=hhtf&xHP)t{z>dG&em&IqA+#5E_bw>oR$`*L17&IP-vdGe%Z)h1Du2>74{l^Zvw0 z8cA)9$bAEfUMz?i%(2L;8se1D!hCrC}WZ&4eYVA>k&hNZ|oqx4C= zYpB{%y~|?L1fm1qj=tu0t%^If1m)W{4E++1*k>;LwerG_Y=ZIS_1CXVM)wGZ%OPBO z>;owkwB+i6`%=(#;XfmT*{@Bdymwv^d-CH~ruKZbLe9ua;Y1cVVK#h#f-$IEcEFdJ zs4(?Fs=yc%@X=40Rfx~8H+>K_yiFhU5T?-~YXT!8CWr)_d6kI7lFzlWSZ>#mZKS0`B? z5Rrr`Rzle+*tG=H^mRDSHalN$iTPO4%OZM;#Fp7LrZ4SqJekFv82X8`kl!jt{xO!H)Hn-AT>*>M+a* zO+vkdU~<=*0aDA;lU~YomM^WIRWOyOR}#3PC=fa3tU5U+`x5~fu44VTLn#E#jRcM zqt3UWo?O}(GB;QBef(u&F-J(BI+UCVPC8SsV_rVImU{wl;~o^9GQ*A;%J{S++eV?> z0>_!V>4BA_RPDOCFS?_c`H{wNXs4s}B+*ahk0tz=5#l#PcCBBkL~+L#_9xtexXh=x z%_A$)`-M|ac1MnO>sqkLrvlG=HKuX22dg4vw-x}u-9cr{@ImFWSxUQ);8}CE;-#QS z1Lb1C2S0VdRwZeJrv)Z(okT8XqiuUmCYbDO)~ep#s5^V%>Pf%8%~TGSpt5sY0UL=r zndY?N9n}<)ZF&)_?v%l|cudK&WccU(kVyC5&3ERj+-75}aQI?JFQ5cTuhB+I)4Q5b zwc9Hob{gSuIc5meccNk%3Y$)fPi?yf*C^jFFp{#m68H-ywe7wl9h|yx-knRdOR6ij zDV;8g@ju%q-FhFk`8n!Kj6H4OU_{aSw~_i&M-s!#4Ba{1836&>;$d?(!7kkqs&?m~ z8SX)SedUJ`8Z#Z{!hIKr)pS7E8|DJ+@-zCD$MD>D{8y7{NOXG1n}uz8t+WQizxNmI1gk5hb?p1C3YCvLqA2P-Zk>|9QX1##$!7Kp0b zk9<19gx}VCm&enU3Rh)`KJl1dRKFb3GgF7EfO>~h5eLGuRD46SEvY@;F^H~$4cN=D zIxg&8aI9Yqe*q-it)gvbFi}io^{^UW43GXaToxco?>@?KnO=I5c0~1=c;AeeNwQYy zFIkmDbr14`q9p)&{GsqYLhfaMiuMGS&rMW3Ml&MA)FUY97^NqPl3bl>zW;IEFkR?2 zx=6^X&s*f|j?33_fXTMP$C|#MsVtU1>2jE2S3`LiDWl_h__3PSW1IVUyXC+!67C`V zo#~(UXAKYGtS?UjlVzp^mgQvA7x3rc52cE8#Vh44sxx98%o&k5>l~k5(V9im;2fRy znRlSt#VGNfl;7alnW{h^EI4?L+?q`&-^`9v_th(Iv#<_Ozy~ySAo}FE_f4!mX%r+t^2rjYO=V=|9K5g$17IN|aCGLb+^52&g8ZNJ z9srqji%S3^r}5&QkP7O@)$di<;66iG@c5RD9>^!G#TtMI*{r4sJ7y8I(K8B7kor&5o;wKYHzC?EQSmLOls|+P`L*cG!JXj~6Wb&7!qgDH zfDw<~7Q+8rX;eLfD*oya71!qvEdTENh3Bp`;{z&W2QV*8f_ZxXoC#iZbS#Jq&7zxRL+D%r#@21Z< z@s&@LMtj1(>lTDW<6uEEV4Rd|>85dI2Ku!?wes$&z(`(ga?ze>dW0+{T83CE;ifo^ zYxUTAvQ-aYHij^Q?N=o$HT~L62ueB#vvdghpWzp-TebH)@#ogl>v7BofvOR{sa7dc zh6Cd`QF>Bpnr00B5%h3k6w@WWwxuV5L9qu8D(Cb?_B}e9#6%f8yZaBv&c>J4KFJAG z!-h$-Q2)Z6$6@Vic4b+$!f??nLjR7^OH}lDEDxfsv z{InW`S-T`n-V5*+X-@y^JwLFWR-8o33>Am|fLZsumPgPj`hb2pl(0?Q|IkJ}zFxa4 z`2qEkgA_(F*r#pzrEf#zU=hfsAC-)ta{!dcnbKRvQ7s zpQDPt>h|gP0V1S_Bivicr8&fT3-mCCdaLey?ppV5?M*vNA#sdP9}=cL2NFl1(Om?L zsFKen-+u!bIW~g2a_n1(O@~C z;g+fzhd-0cSKRUux8U+VXHV9jLW+>xdo~)**$&vkPt~@jbM*IeRh`-@YSAqam@9bE zeZt0ah{RIRY6wGFm1g3Emx1#2h0VE#bt%7NZsgWFSHAym6~j64vf$HLYbc%) zfzw{XNiN^OS#N%Df~s}6o|%U2&%!=R2}N?%Qq_%vfHV3bHYRRQ-Q8uW&b zB!>T~33kMdwHx~d!r|)xiRC9+x?v%Dr80x@-I{(*s|ss6nabQ`$yH;Fhp*$TCtsK7 z4R5UfS50kZX6801GsSEsMjw~H-*&%7*WLA+a}ANxMYKeDr~L2pcH-s0Y;(H2R=UR~ z)_!Z-SgzKJjKWlQBuULi3xqtfP7jFUtuN8VzeTa}g!1jy>^IVB({do)QJB>SJ9B?Z zr}VmldWsmb`9#zgG3CtXXoKB~<#W9;D;Q$Tojg;e`tCft**` z!D6#vAuq+%N}(x1Eh|D6zQ@}ZM~&sk(Qy<3@|Bt_yaReDk!}nU-wyOtkNWi(7xF~! z%+>C#*%&v^3*z{eOWX#5e*qn8X9nidM$XT5vJj$NilO8i zK(3#@gITmpE2|0fXg&%V6%AQC-2xI0O!>-m(qNQU73xH+KD>yKYFc_S%I!69V^Q}* zenbzkbtYyUVXk_S1&gW6&>75|=E?M)NTarT1@YkA;uV zy!1m!Ki(Lb22NjO-&u2ZB{F?|<^u>a!G2fFe&TO?Pd%l@FJt1Tf#fGVB)SJa4vnYj z6{0ii!N_f1w4QWO{ma;M0Axz`5Qint%z(95G>gd0Lw%ph-+?~UI@1BYituJ%8DrB> z5;K2ZIFlkj_QJD)K+zBBb*8vG1=x!-DDu`HY)MXe-XrgRW#Q`gID`I4Lc6;g^{++R znm@HJE}O^0-ku`A5t`?hc@2TR{o8yuTQ?Ly+RYd{mJ+p#mF5D!0SJ(hLM(?GAtky^x``QJkG4_RJvtx<8~>c^XrQ7^T3t|<|1)q@Rd)uvRX z(N7e$ZelO!qO0`Q6eiojIF94WAm9p<7-m0K^!Sp7baMB>in{LVL}`tgTYG*7QzlGh zqsrpYOK*Vi9?1(;ACOO$aBg&RlNZf%)Z9f3*JAAD0E5v(V0oWHXyQ?3E)p3hHt4e( zWNtIfvPxGTlak|TIEb8PM!{9XKGH#18~{YuK99bRWwx999vZxKn(|*J=VLUka46t{1x=r zzWO^JoBBjez85D!HfyLeIsOZ-`lXyPfiXIK96x{phYmEGeo?+Z#tAkeP?oY{r zh2@cHAoqzwd9B|k%hM;2K6DpBHg60I`GK$RcR)gU;0)7llaG?UrN2_>-}p{iEhdp( zchq&@9_WAz))1y|R(|Ck6g~HRUM$e}0Lc}&$!t(vlrSTC--+k$Q;_?%rhP$I8|r5U z&C>)J7Z95L7T4W%y0psn>L)h!ONuW5$wUvOCzKGR>DmW%%Soqn0hnR#P!CU*?-us4 z@QBGLlShN9b^X8dIE&{D)O5zCH|5G>O&O(^a|%pP;HTy6ndD#B2thpB#a}?PC{}5_ zHoE?J$t}AVt*GrIn%^yIzG@W$;VygE*LXqa2^#btQ#yDPZ7R93PQ|kUE91HY;nBn* zgV~D~vpDqt*KaQo?oMNiw*;87dr5{*pr<;{k@%Z0>bie%1H#tYOWp*avo`Z^Qs1`1 z`KE&b$^?p7qTT}>ag_N8&cKak1Bgzk@cHBgFzxXPH*Sh&vP`;4kW1*8?F^7KV{lRy z^R}av2alfx@6G0h#`muCqO>EetrLuKvUhJP% zkY=chlHJ$M_evh6{n#2)_b3&y>tYc2qq361I2RF%?<37?(~=Xb$Q&h@owD8rdJgHp zeR|M}45`SCkkJZgyte0LT&*F<>*(zt=U!W(!5le!xtz`WTm0rdcDeuORL6wDWSyBW zcWb_c98E}>VAI1<#R_|a&l&35I(ed~;;gwpQ+0ez!uFha)j8?U?9xv^L$<_$t@X2a zy7zQoFJuV@X|Us?hN4#06Bq{;dbJeX;_p*6j}M(}bKpMoXpr&Dh!r5(fw*1J%vPSc zu)?(W5Ra1ko;F#!pL`=hpvoLAwy@|(zxGd9_y;4uhZ?gG^2mv4Lqh08pL~u+_lDFg zYv6BWjYGLfQR2gcJ%;MX?Ha%mU&L=9jf&d^pUL2w~4}V8Ypeea4ILAz0n10 zF=kM3!btiN_Cgm{{3$IaNBhpx{m$B*oZ^(1qERO}1Deg^{_Iq^AVg`mgm7vpW#U7T zyv41sN_Sy<$xH5wT}42VyWdRV?Ha_6`-N(>5sGfWyujJcEDsR8F&QaHq|LWE<4o< zM%#iqJ_;}8nONf-rk}|4nf*Pr?}ull@1$MH+s~@&CcdAWH=4ht&p02e>p#wCH_G>` za3`{;muWA#0O-E~y=(2KXw;mrM1M49P0im#ccx=-q377*(824o2D-d{ofcNPY-QgM zy((;z)aaa}=Lw}VmQ8kw9w(z<22_Ic1h8<26et}WT~_*j1r5$zSHc`MaczI1@u?l0 z`V6W8eodb_KD}^#DC60`&qE2|CmI5$phlC2)f>w{eN>NFdmur0Ch(H!eaXLE?{Z4{ zGsjot27aUtUsNg2`Oi_`1~I1IeIQ2*lanJ#4Q`XQRdD9g4R@++uyzT`^Yh|)Jle$> zke_rRc+|*c{&pgdNEvQteus{Yq00)Z54r1wJiCWm)2@+^@)Xs_s^ZJx38i0z#97Ql zr9IQD69k`r5LcN~U%cng=r|*xLtR|&+KoxQh1w6gp|17lQB`T6-OTJMnJFbS-`JQF zXCN}}NO>#-nl6fXy4)sz^)|JHyKOA`N!}Oy6fZq0VTDCNTlRNjbd4h627R}qm|L?*J7Hwxpw&qe-F5kfy#XA< zcVaXzU^Pd`WcB}XbT0l(zW*Pmg-WbXiX5jD$zhQkXHzQ4VU>zwaJF>-~B@J3pZ90Auh{7Dzay^cx}r zD{*9~!TN%f8%5(kC-Cxg!YK|EwLc%UVIEczPsLikTG-WF-%-5jp51APfT%l^C*G((3tz0ha=pdi_EDM`7Hc*HaJ3o%p>dMVnO99wuEUhP7= z6#?y1gY{eH{!xA5bGW`M;adj@-?4S{nRkDt)!q3)Sxol!nlWZWkDv0dOnJ~^yYD1J zS4UV?xtn_3?@Q7;9(8A2(71^zZqYk(I9zH@B4{Avxngs7ORM?8{tC2|LDY)f96^Ja zlijEQZ5nR)dOWHV?qC~d01{{sku=d7DdSPBH`dXNhSK?Oq8}Rf&Na2Rf$+oL1Mtq< zN^35%S*1{okDK6@@UOj{JfZjKLEiUkny&=L$<4sExYCo>Es=ai(Eoux4S=8ap-Fj7?<!lQ;TQ)vcG|SCcsECQ3Uy3wMgrDet&4x2 zX+&B2Z-&E`E(n@Ufqh1!(EFMIR5|8I9J0oLD;U(W{z}W1zGUmvUAYnecq+wc(GxNGlO)@ zQny78F35?p5Z?S?Iceqncsz?kT-Kyco*Zn_J2~w$9==j8N=dCr>sz!bzLV*z(E3*p ztWc@E0Jk0WDro89sw#U?=fQ=h2f3OxI;4LsLDK(KuuCk2qdytb+W{_SW2PyCWDJru z?0dL5U0Yn&VM?CxtTH7V`V-p*)+{Y-B3ln5iWZmuN-3_^*KIhDLl>1!*y*+ttoF)` zh`5*$Yxumb-Xl-#3;OdXwPe>Sfiy$UJqh<5$|PXOiZCMz3<)7!to3?G;iK3A2z)BFkicez+Zb732 z*=O4*zEk|*R&YFtvocL<*X7z@4FSH9SDon#RoSPn8^eJ?@y49a(~l&@7{ z4EVQF(7UlY-q}lYmG`~1+*N;&|uEo!QXa21pvcedNQ8uWaRJmnqxHTgdL|1J4cn|dJ zpPL9x|JHj+rJ5ajc3{ptoqGL~gwDZ=>JcuA+EUy`4DJ$IKeEZl;6ZL zWnJVfv>GLkQFV=r1t{)I{)UYNaF?bc(VebpUYYc;o+H_HC#{7R@TR&Xpfe6Neej~o z(EEv8dMDr3O8M22S^g+_thwJeAn>Ftt62{;FQeiq{11Qm`vO|9t4IqaFfEhnxquNN zEG8+_-fRy4LIw?_FRmF=sPog5%#k2@_QK280s1>kLy2B;7HDx5JD#10|Th3kP1Kd404d)^9+&QyLa(o%{PyuIt#R$}2zQTSh$>^SyIeK0hE>sb+~&ZIox8 zgRUh!zgSU=XSdiR(Oo@wb=Q6x^yCk+BiS|B21)auj~KBQbhQ>GC`nK2pd`U{19&`& z`R-TEfHT*aZ_N+bjo(`4AMZc@_}C&x5Ph@$erqy_&)4H|ka11AQ#$B~bY2&5)?Y(Q3nKrJbOio$_ z^UT;V+dsNG3#a4wcBGS8qscppSSQ z>^6s2hblr{Emh|3z}f~E+>VsJe*h`)L0Y)q)82zF7t5KrhEj(J05wJ1^p3q$`3>iC zI~|u-Or12t-KPQ|>FBx3GcQT9%(gV>3YP`stZNxNiW} z&C7Fy2MDIK9=@Od*ZSry8|Ocyi`&}AY^(;$i4UDC`IvSutL+2qo?n}gtV2(V*_CLH zeaSt}_xovDXFl_YosMzFy?v^vn*8)J&$hw*n8H7IZoh_@<_Vua6tX75i(spzq`@^L5PBDaS#X)xk5XVXLKIEFf&NtlStNtZ2yclkt^hp#EUT1 zP14Uf`p1l8!$eVo)Jfdw$a_;v3Zsd)6Tv$Rvf#bj_{7Fc0HO*bK5VA$IlInp?uNKU_9|X5tx& z4t5K7T#1@KGuOPH#-`u80jrlxk({8LA`*!Nz&RqJg}_xM!zzV15jD}3VU~dJJizUuNbm2F25e}sC%(4a z`vQ1`-4IoNRc$fBX;HwRg~B|E%7|nhPB9A7lwZO@ued%Z@eg!?EP-=vh1`aXJ;OIx z#6Q?l1V>E7neeN}v(#KOCcnnexCLEB6hUnds6r{GQrUd-Sa`hQi$`Yf%b6+S1@jZh zxnhl0kz(p`uV^?+@svE`7sSdrM#sk}^L-7=iz$l+^5mc?12y%jZjrXdSoqYXA?9Q( zV!Z{$Qxajf`y4hQKpIh5424=a>@zF8RtKxCUk2@fAAV~Yt*{8W{NQs)dSy4~Wxt1y zZ$Es-&fdv+`GwH1I29iM^t9j8*5-Sgcb~oJXnuG}k4N$J*XK*S77v9?*V%b1c3;StBh@fNd3PLLlu>UlbfSQ(5V z4sWjUOW~*E5wfK28T#qh@qJ2MA!tR4etXMsrV1aF6v%6;{&sveb?}3Z$GOsza6?=N z%Qa7Ild5!ezs-erI16UBhda@Wrh*D9_HD>H8FO;&4H#5Q9e7XQLKR?mPp22Fm zj7p$)A9PotV~QyrrE}MS4fQL*Ha0f)nFHXlj7rY7#XvK#@{rZMcrnf>A3X{=HeUCmhOo!Tq-mau6G0 zj)tHIQC5<{2bn*IBVW;%*ntD_bqqpwcsWf$V?gP|No1mM2;TC(I4+VCAK&&{la9SM z?i~A4cs_J0_2jkbFWzULPP#O#Sy<1B?XPF2#NWInyJ3pgF7ukEx(ga{Y_&pi$ixMI z*%$oGQ*Us&TW_9n(O)<^PY0AW99%WzvK~4wX`tG*!4iiYy5}fAGZp@&k{&2)`#pI5 zu~-V5nX1tW1?$|w*Q0IWs*05{_*`P|BG;%pv7hKg8@?R3??1bmZ7*L0UXbcKU2UzW zN)2nk&~vb>WDa-n<9yeF^m~|`mjASY$ZGlx8?vZSu8-PeO{k@9bcSY6mKZIc1~h$h zm~10-L_zd>?Xg>%Rb==^11SK;a}8zViGZ@g6Fqg)Qw&PPloFcGXPN04^~&v~Gc5w? z)(z4Ot)KF?2OJmFOK@k9ewe8@aM4!l@yA&*r>XpT2?&ikhvV+m$twZM&*5ES8!~?H z`VR?bM*`Ng(9urBU->7jIcwA_gwKRiGtP`(eyE1Tx4+EB4|BJBC#Kc53bJ*+ibmzA zB<|kfzXBK&Rf_;4mt+{j&GEb4BDymF=xgWs9&3^yO&JuWFMfXg6Q zAP|w-rl8K5DS1iqqOvg0lQrDiFQ3RfE?Al4r&>B}YqH9LWxy#;v*0Y%V~52Lhjq_B z@zxQB`Q$v=C>3nENe`0^3;^Q7-(=|D;V5Aw59NQ~crdSFdG8zTXX5iSyi=2MCD0 zp@5?mj?Hr~|H_DX5qF)T|7*;AE7FikmQpZ}t@4e@TX z50A9%Ph}EgwHt<`HaE6lJCeyqgDu2v>TSR47{6*`LzD_?Sfem*s!o@yocza;TsH{DN@Yp(U$+P-7A3+f0pS!Dx!vFN2g3M~FiA-n&Cj!U z_T5#!8`>eUI+P4K4UUSq0H60%6U;&hU_>Qgk{WohC`tJYS$@MO6q>JV+UL0 zh4|TH1y|4E6^C9Q~V@72tM z68|`Wxt4O{*KjQ{!E!)7FZzF^Gk8yHvr9Rgx;^{|a1*vwcM(X%N+PvGEp}Iuc20x^M)tbzi5K}+FbCHS*q^!VBbr9ePBX9qOo6s78b$I)mO#i z-OG*rhEkR{Fq?B|Ud`r08`Zt{K1Fw!1c){tHM)7zX?o z$_sko#jE=jwlYlPPHW{hbKXzj9Q;(%?|gg%G=_)`*2nwkf$LR-azi9B?mrD~$kdtj zjlg63Ote%yysCu*sFE$Gd%4ZSNAAL;6HA!%{yD~eK4NM2R^w5S6r0;GdpBv}nGlyl z_!?Hh@+Nr+w1vaRZ1a+fy(m%)oQalABS-noqKuqE{bq@Xs9y;iD;w(rO>Qp3Y}+Fm z{ymU=4=`Lb`WYKG*5E@us&e=$sI|N5gzRAK3}Wu`uJ?x@IJ>i$FY|Y4HeO}W_`#7- z_z#${dv8v#)C{&A)}IkkNEPgM6pCX99&0J$$~GL%hC=A?x3q*OV5ZuOF(;(R5C$M( z(>V1?j|>m5aP36E>p|Kjm4K^W&Cw3nyLP`EgT#10{t0t%8t)qO@C-41J^_fmr%0D`n0`_{O{9K`FAKlCd(9e#o4vGqX`J>^+r(F~n@OFnrL{)1g@> zz(dDL3$*;f|B1G?>5zc1*B_fPj9Rez%SUJC?cG_f0)_ogEknuCX85Og+h4Db??7h> z&jZ$tqLb1cA`(yLP(AhCLZ1;i5^#MTbn@W*v}#b|2~K2Cb$$pt8HadPx~8(Bl+vdM zT%)lI#^#ojZJx@D?B-QC8Nzf--a2rp=6t7yYgZl2EtUdNH@6aSi;8N zTDBK0M`H8|x+>n{c(cKKXwTn<(4;lhYv=WNCI z1L5|v8)q-Ed0&~H#S_ZosAVE9jR89?e*$)_sVoPBt@<=)E%tB(y;8BfrHPL>r^x$` zv+d%3%i)JFN)HZkv1ujz?@$k0S|uqG8Xz~Iz|Lk*;>Ui&#(8Tn13zq zn5JQ!qT9Q8F;Q{QFARqyYyrV0N89FbTVTmXih0XdZy`J2iu`frT9{&o$FKueAR*?g zvxgo?F*~LuWWz%Ems)Ek@@8xIhT;Vtl-ZK0XpB+)(UeME{z6}3KRj0Vt6{X}Up)-F z=y9TNZrX-z?r+K6mjMo)nGB;pPB^^633XoDAPbPZbq)qJCM^V-k#<9iqFy+Ae{Vp^ zw}ix%B)B7*V!{#Qum(v1*0oOgLn$@hh>E*{LtMDYNQk&bpAG!pku9pfYxtH$h!?Ea z{L<(|!(3B<-W}7M+F;L%GNH4t2Cc&7Y1|3Vcr7Xm%@(pY-n?dXP!#9-bmD^nqY{2Z zzl9%B>#yp4B^nynpUT4DDAsaP0f)O@@DD!2iN?`U1C_cy#K)^T>qB>asKtu3mWUR* zs&$o~D@tmM@D5N(&G9KtcIwSfBL_BHsdU+`o@!V;JKChUwkp&iPB6xl5JK*JJJnSAdi#wX9w0A7V@vJ5KG^8RGhZPALHsulpnc(r zBqqYzb+}=T@qm3eE-*Q2T4Y?g@NY?l45YmLhFV@Ov$bv6dqgUOs3mZ4XIshnt&FOJ zj`P9fl=Jw+EST9XWE26TrMum)wQV2c6`?ME7h50zu}PSh<4usjPbXSUXV=BVzA^q+ z@bcU;HS=8_0=GUJ3<=X7u$65;Tmq_1hNnB|Lyz743!sKj2zw^IQi|p+kufrZiYSKt26Fj7J*iha7I_!cBpP+o`&M~H z>zX)`z{9HQ3juh-LO^tva+*$3yf#Q>atrGX5BtG}R@fE5^-Und1T36wphwtT|~ zaMLut07WGa-|ornenf8fkjt1Ea*^x5cEik0(u`W|9lDX}ztF%t@4T!Vx|ukO8_^LF z^=+3=vQ0| z9gM&Gy1i3d=rb?qsg|idySQX$W=({$Vlq68cIyhwlR}m8Q)M{^{nHgHQxq z3@UfE;PqMOXBX*F(g1aGg0Z1^#Sx?b?(`e)T9&uyxJAx)SIh6Kw1h>%7!f|Vm z1=OtqmQRbrEaZ3>&f!H3=Ea~Er?hm?lzGA&Av-D1A`QL0fEY&`ahA_3WHa6~NS$+c zQS@&%S{AjNF_|t^HtJ5t@5t&DArPb|2;6F1@B5>q=Nr1y>M9qCm7q0T#vwAJBjOCu z-iv3cFQZ7K5tsO7~ zL5;gFlaeef+$s!~sjm;tBJ>TBr+p3T_?M23SO3a)mltp~Y0>jcw_-rt4jsIB9l`3S z7WD_;WSQXwM{NFAr^gZ1gE{)tMO!$X> zHw~+9H;b6C>W^HJB3wnN=SBGi@zi*`1VU6d9~F{@FiHyxfCB&d2YR$HmE~krygY;Y z`yFCl2(*8OD$v;bB$zK?jkN34)EO+3#XkSC`AAv=!fr^(scQ-ablfTK*fpvP(@++KV*}JiqKVcC|TH~kvQD&fXwsAln?#s7TDti(& zg_0Abqv5Z;iP1iW#q<4P7wBut>Q9?5h%OJYs&AC_E?`sMK=bn|8&4t9BfIhFRQ<>R zF+a{eP~dTil}l+O+bV|XGl)rN1Fn(s?q0PLP(N#1c1Q3)>A*wO99fOZZ_77jH}s5F z-oakwF}S^zEKjtyDZh!aNJuDfIC!Whcyh{EjlJJHOAq1dGn~LFpcxpYM8hpK3`9A2 z*X^8rb@DmN4IlS)s-b*1KC}daS$VI_UX`zxkDEN4-(Vs%i+}Ul=f3ZQ-%T5oR1|NWVWeGv-8ME9nt^@zXi3A* zD%3khr|FNc4nWRl&6t&b(UGvgRrn}P=GDi6MG2+2f{1pw0A;=vqa5cc>#+ZXzkaMV zHuxuD;YQTvN5AqwJDA-2=dL1Z5`JPD)W}yY(vOf?;J(oIW40#P0&H zzZ4QEpkMd5qOjaF6PpIh;R8Yzx`i{y=3H2*C`_v}^vWC_lvT=tsj0!a_b2s09@1mOy%gg;DivDb3g^z>>Ly#pLwt?>_dix{ZB16cr@RW~@ zxQ0aI*JVe@_FQ}F@Yz9s}>|3$x!@ViLV9)x3SWEiC$t^Z@-$s+(q zo{p9^FXR$(30eQgkSh}>DbFB2>4wW{zIkt#@Y_`Af>ijGtfccLyM)5`^x@ag`3YMq zu7kEhl=YBpGdrlK8|*V9HNwJ3N%!*yuA`85!6O~LuH7|1;fD!0!e-_JeD zv2TImdkPg`b|T{hy#*XX1Oj8T8I0>K*vP6P`m(zke@buw(OYe@FF-b8{l@ej$j&|U zKhG1nsD2^_h)p|@glQOPJkmyQ`AlKtD!eGWucU_4JS2exzJQZY9I2wN^2KxL-LWb{N12&VE zg25tJ8$x9gCD|Ye+JzKqNE}alSj*9Ci@KChC-o5SP|?#9 z2IivW`!@sig}1tO_Jm77W}Tz9|C-`4WAcsv3P>@N*Ujg z6E45wEG+o^8*lM7m%CrP$djQcsI|QN%FqT}vb6o?wJKlF(0}iF9fo59&d&$8kR@+! zPX{Wox)az37LAUTLg}Q;EQjj*chn6~^EpBC=JQT=^F~cstLi6XKy_kYu#x{Q?xFbc zw^LPq?9Qsa02Tnnyu6R;u7xh zb-!p7C{b;D*4acKTT+?mZd~(*qzRW`=%(HqHRFW?+MLM^6)d21G4TKUQtfY~KzUq|g zMb$t82g(9DeY4azp|e z&B~v+BgCUBzlS#N(N*W32J1;t_t_U>*m->3;vPmhkk_u20)En$X?fDG7k&e5bAUs! z7SWQh=0z8hHpofXiHtSmRa(>LV#KGR4k{0~hCJAIe4nD-uFLq4G9m5v20h4LTNbLE z@xS@xd`~rU?|%H9)Ptu=$u)QO#(*@BuP~7Bw7o~b1VH6HRv<5~P(4xk*ho;7dOh^$ zK8xapthA?&G?Vkrb_cRVd1Px9H>H!Mq)pP~y(|oQO)jdj3QxHBd%|!;FNN`Js!Yoe zIn*kU2NWZ;!62?~A$n0MAl}qdLSw-u&~3EJ>LOk0CYZAK%{XfLK!l#ekouAds%b&Tz;E0kK@&V@6EsS zHJ}yfSgCZY&##0a%N>st4>l zYh*+Q4%LX=xP6h=cU&q1|dR&T++Qug)nN$Hg5Hu-$` zCQ6A-LmY2StC)AbA7zqLl+73lp>DG#YG#tQ-4E61R0XNpLvcAZ+a99PJ9-d8LP&N7_= zY)c$(3|%u0{kgPPCl&x92HZ@&(2KENM|wwP93*%7O+ByJKnKvds|3i=i1SzvG4u@71_EMs+>R`vaaV%n z>xj7y)HMkMJmJwuKms)v;_BOlP!ksgd#ncVF($rZDQ2o=XPd>FdtVCJo`p`V4%T-P z*j)(L#>@KO{6QuzTEVP#4_tKe)K7x{px*)DXIS{oKg@sd;Q!Cd0beBnuu?zP!o zQ>7zGS9F-Muf88kWe9d_w{sDw$YmP#fET!Jd%QGN+(rep!1Xi6yu21xvC2Mr#=P^- z0{NONnN$#SPzH4H4%AHHRym$$IcMSO>zNiOsBtg9B^?YY{w33)XqzfwS}mBZ?>jF5 zFMpAQl(tN&=M|`bfz<*HyLyMq@RrPBhE(b?BecX5!hc(&jBP>1?*_ z$mLz_N<#R)Ye|)gCxN+0@7n|#`?TF{UCjp0I3sH(I4KF6-+1?Z@ER!VbKYz44$7_g zQvJp+`Ru9=d59G$>f%EuBt@XtDs+9YsT^+&-%5wm3kt6^Ba!U&xEa4|e?7RhD8FCw zI+cg-CX_&9b5Y2iFel+N>pDNF`r{N@s&Ch7lK>8Td(zIKgnEDEM4?_ zk+`q%jah#q3xzjh;g#Fw_5p-w$?FxY1<#tQ;AMo#3*m8hEjHKQFt3$}l>~dU>2*7ku*EA6p2Tp~C5sreysLY>|ivnSD7gJc#jrg4FZHg1!RpI;*70=E%VA zjU?!QQCC*~WN%C-MD3_GX`1^G%LHHx!l*e;aZC@mQbXx0%zI!LF6wZ6Rj}}+*O*Do z`5l$NaoF>SYi+y8bd9oiVSo!g|9e8@59Gd3UGDdEC93T?!UerMOfu-xF@|gIH&--( z_YE;xTTONSc`D;AE^?TBUdH@5(|uKxAA<<-UmDDFQ;a~bIlGZ>bNn-;}-Q0uw1Ikq6B9r z`J+oO9L>5M|0HFQ?2&CoX`f!vi$d?_=^VWNfOG8+s017dIs9wZUpS;!Vk;x@cy*4E zL;INAL`fo(c*^02h193q>C@z)SSg12(O;got8#l*F>xG`zqB&42a3-I85)M#1}dab zC!>xh_qzwxpYweQGu9D-{v(t%r1Uv0y=gCFr;$8f)9hhzi)8@|y!%~CTTqD`hnyvh z{u93OXX)oxHeMgWCE|p6{o~z%a~_H> zp&9z|C-hRLuYspQx_*f;BjMSr+t29HKpIO8{7B)%Js6vJ6FThlHiLZhyA5_c0y7VV zOB&d+S>qEnQSER2sz-iev)F5~Zz*ff@dV_~h>P5F5y_#Q|BpKV*#miUFwVi_JOdt_ zJOk}N>nlJ88<}_5O#QAxs+Zq+^PchlIWJMpVFNVZBUOUKg5CS4q7VJLO0aBP1YrJ1 z$oVySUJ$S8;zLk)6P)@V+~nYeBxE8^3W_^tTmH}7(5#41>ZKnV^cUU87tWGtHVwW@ zX&@3i)6Qo47!#WtB*p6Dmgps|3iW%n95H8i>ojn}b5vWt;_1gv?d-GMCr6IDwdW_fyxcC7ZMB23gM zT9l=$2AK-@^v40Tnt-F4Lx{rzXMZqbGYpz)T2H`ok{3k>*9x&lB2b@pBi^P>R>i%{ zwNRVH)vMz^8z-D~R_AE}z37;wUI-`B@@`)#mTN9p zYpTN2@#nt~@5$d{o>8(^Q`2^HD$+nAZ!DLby(qBNj!V<~NdUW;$kub=I|!8%6R9J_ zqUAgb#{(*DT$T%{rrHG~2O{y;>MPLYd(DvtTk?&TOQ=^zyDpvGs6XAs`x5>Umlx@$ zs-LcIUNgX3wIjs*zZM0YtOhiXUnTF|Smr>E34>^#qo|*&c!vuOU}2tgIF$BHEwhRj zL}Lv+r!D7_Cd)ksGHF;m9*=_ugh926=FxpXG2itb`U~dH)u*g6s{3NcIjcg~m+I?| zYzhqgB?lBH9PH97PHH5*S|4Rn!)9!RA(Ic)eYhRI&-&UX5A=Q$Q2wtFjen)_g-iWT z7Ho^CE_e&TrCCW>JtPGx(HI;(Tycqhs`J-Qa7$7kr~QzDKVCEGK|K4?Kf8rZV|kq1 z^y{cC=ok#~_oR{O{GB~5Q<`qy@mb!g*5+BDoJaed={)iRlKlVY`okW$a2 zifgi5xy@uj%&wsQTgA6m9)AdZE%n0;a49u^gE4%kmf7XZ=yJkQ67NbYU45vhrn+F% z)aaM$kI&l`3J|H4cD!@ccK!or!t{6D35Pv6S+pK_YRE+0M>CH{_p&A|^rTP%%8$TM!!Wgyby2>fx#RCSGDsZ>8OVJ5 zB-}i!eubgQel3T7hmB(or5Y#yw8vr~Yr60^=p1>2ti0Tif(u!i*^n}hWB?=-&gi)R zhY%M*gSDo?Zv>DZ+2Ejrdh(il;-@6<17l)=j_a}%+~*Expjzw)LjBES_4(zbDRxl5 z^S@lA;lJdK5f?Hoxqbw3GO)uKC@(zw%`;2Z{Iui1eK4B$Eg0vxPEem+D~NQ6Z2F&a zdCRa^-tpA}fOT2=ljq9Ti+U82C@>=(T$z&DR2~GG(7A4GV_ zRsj>Hfdcwd`C+*luHYw_DaV;^R(b~hqW_qPWmPN8lQWVp5pDg8OoQ5Un}EoG|E z0B03&&+D)N^m1pflGCy?$p%l-+kiIWq%b85=UmR^FL1@0qJ0ut#I{_vQgw$7PM2*_XrPyBbT`&&Oo)L6q zyRFLVf!>_$rq4*)Y$aU}=w(tYyc&-=enKH;W)N&fsNe!G=DaAgHwm^YWidf6wO*C$ z7p}t~E9^bt1=>q;bG>@-x%WQ!^=nNzmm};u<1%TW=q}h-u&uE3A8W@I(&arH`-|@Q zsop%0v$eU6z#*ffE0Q%A80PWVxn8BE7_$b|#3nQj8_cH2!?kqk)e>uuRyw*~X~BfQ zt@u&y1pF$)tLlAF97^C7SPN->E23h|{GZ~ZYM@-u2@oz92hfb(`d5JXNCztVMNa^J zMkkdle%!z>qq1j{xpB7Fd3Q&BUjotx%n-{*G2? zVknxJy5m1p=s%T;DA#T-%QyFNMMv<@RixOV?aZ_0DhnzX@Qsnoy*@bW*MV@?cO1wL zqsiJbz6Epw^kL79Nkc65wQ0+~X*dF{>)A|0?;Jumw7MGcSBF@en!3nCP(N`=p>(eZ zZ`hwvWxqA8j(eoqGRQfV6@0FmG0GC1cMiUbt{POx>i2nyQ|E@ed#K0h!d^~G)F`=q z9q(VHiwi11L&2|4|<*-`qpHyd~l@Jn!|_L!Nm3c`ho1TGxMKpL~*`V zTzA$qHym-VO6tXpTEVoC{ZLm%>B)NOxPRKVt%;5hx5$4ucxwPIDzg%&$5#>Ks--2| zqOsHH-Z_4PdX>ShEDkm&SFw0QDHI$3#DHAagZZTO0bfQ1OXZh@5aOP^=&!|zN;q4s z-pg01X2~{J8HsHD#0z?>qv}v1pZBov%5jMlY$9JkO3y9P!i=_4UeIF#!!$e;$-wMNcKkuVXODh-$IbB!@n)>g8e8HU<7#UrqP(A*OYISQk65 zN{){ndx>VY4Za=f%I6*WR2h6aE+0P$@tB{5jpx^`ezm=iwRbz9cC&uOLnit~rj-Th-ntS}(Oh{kA&ALKue<`Np#k2@ z#^`0^@zXqDpWc*WZ}-kmksQ5vr$t>AXnT|v9~~LSs^y?Ov1XDu7E7+Bg?|IpNx0L{ zuJ8{bjw5cC0c_H4yWbWx<;*;A2G3FQZsK>Jp!uZSaIfhWEGVBK%r1#z-}0KR_Iwx| zwOB4aGdfd@!D2+V(@f%oODdJAj^`OurN>k1#GInAM*1((LMVd}-b@T1?-=1ctwuBz z*3mmdN*~h1Jis9SSNhZ6s3zZjt^X(ZZh353G;iEWKhgkr@WPmX0K>py8mB&nAh|`+ zfJr64e2M9Q4{*cpL0cOoGoKR9Hda3k_BSI7B0GE225ed#@ue5LenEC0}6+vUSwN5w3>Sn=lG+*m-N zvm^gBjK;VQsCO`Mwd+AjXv_2QEKWbPG>%iQl}Qk;`2(hXev4k4P4;_6BmOnj4`mxv z1IfVCMY_z=p0D^R!_#(#`={@@OI&0*ScB91rJjV2ur%B!%ZQWZy9gEMny`eQxH~EF zfaxRu^|iy3idGt3@7NH*8gN{=w;|)7uhtOJkB>5VT?9vtss+S!m749HJh79na((a5Z4*!bZDawC$E2JHp*ovb-2fvt=7G@HP8dyaQkozhsj*~7FgO+pINgh$ol>7>Vwaxs< z#<8O=m1ftUKCJgG5mj{tL`XWgTgiSTa-e~`+Egw#wYxVB}HvhLnzn5jHra_9~_bl+fS z4;AXY#Wi_(d(>KQqYaJOq-3SlfBpg7f8EGf=U;^tgY!?j zH+(&FN<6-1wVCToH3jL~{JU%YR*~&@Xxw>jn&c5yY>}eedMda!_#z;NeYO=jyq1%~vzgFWK-U zt#NKq^92|q^l;8#3RI@7nR=!?zyFYW^Fs4RibbX>>|H>(e7#zar4iqi`7psayP#5& z+a$euoXxm^FJI4v>p)o9O+}v?@$%caS-gN;xnY`<-GiME;rOpWUvf`SYRKL=cun3) z=YV6M?^q|AvHl{hsHO7hE>Zw>@^<0N;7H~{C zoTsuz;gmtDpP0>m#!fsS8EI97X6MG&`7o@%y=fM-2%QDZJ}E}6(WTQ+E0S=ZUZZj9 z(sv8z95H}xn(*Xpx8$EpMYyY+D6xB9aH6w6L?~*-+w1H3Ld9;=z`@PG@7p{rY@2PC z25VUswR>39?MK;N`I;G;*{^qKR<+9XuO2Jf<5!*ii)hQtS{uX0(`xfl^!LpVGxuEm zTXt_n?Cjm~-gbmclMawa0;o2DVp=dQ(?GVCcK6vWV?1%svX-rX#ZU9Gbu$ZmI9Cxy z4suKA-(JpGJQ_T;-ob$T7r}O+j?8Lcz%TsPmh;A`;{t7QcSE+8+VTpgJ#N)0zIhm3 zZ{rbA_;_>hWK;c5>x9`w|Ba7>M~#D~D96WXUcEYSp9$i!c787G$f!91q5gDeyO_t} zxyE(eVE|bQ_TlF$o%~th+FX~^S+HR7$R9)#Hb-vW#z0qo!xGi#Z^i5AoO^dL z&ntIA6zMZR(3pbu-mnp}>A9=D|3Ia!ki9TdrB?%Dy(T$n|4W{D;WK9R01Fu9aw*l< zl4nP2Me$yuhV3gHm8YCMVeW?@s3Cn|+IKXM0a6l#zCW-T2yLX4Y>&p>y^eSX=h7w& z@A%#6e=`=8?V9ZYSBgc*I)0+Gg_@yEHsAJTe&V{KDKbwo%NXy@`9GS@#h>Z_{r?!I zw;W1Q&ZVfg!zyyN(Mb~1TO~QHLdY@a!wwFWBoWEk6jC|meBPXLK2FYO<}hcoG23jv zSD)YQ`wzTsyX|#&Uf1J#T#x(5w9ZzL-iYkfa8D?#^Q*_9+k0=%GgU>X-w{e3kcaMM zQxE6W_Kes=k%ct%%$|wLr+q%v`AqOnMp0O=ijRdO-5B)`o-$ibd%U)@8Zf*yEWO@h zyLb704l+CZD&s$=KLBLyg1@nF{m=+IF^@QC(7(9u|1T<(=jgWRBJZRlj4|d?lI@)! zxa#wptN+Nz(;D}tGXiRtlJ6%a9X1Ft8^n{2ws;eYV?78m;gO-KEK%ErdWGts(oT-8 zC%nC)C1+BPxaxop3hLdC53TeJI0qAMb(@5gmmatL*fi^ zUUR8whs-`UQ%}T3Vu(_9DR3I#f%~W(Tc16P(RVa;y3?k5==W@9!I*sTI!5dI~ON5@(Qef5%y&Pk;fvjcXgXupS zu;Qxqp5sU<@rTj^4wZYgZ>O^lpWq%EigwEH(2e2ZWb+Cv%fKHkFnT&|W=rU0N)lN^ zB+%_{{f;sJNj0T)$@#$5tuEYp*KpHT$=>x!1;8#(v4ic|xim(o=)GD^G$khHO2%Te zPPK}KcVQ!~kI+xh9q?{OH#?;?E0}LKb!)qTXmCB~%DZxY=dfloiOr>8 z!5UXes&V%9vab-{c)+N}rMYCav?_R`{>Uchakud3{#J=-;<2uHzc9uO7b9r2NaCQN z=6=zTGOYNcv)<-x8g}LSP>y!q=B}9deNi`3k7ACo2#p&7kfew5Y|E$9K6(f&oA9r3 zfjRVx_NmTXdgL z>7}(k)Jj?&oEg@$Cm-W7Yi%DMj1M5YLMiWIqd;jIGcGS?W76tY^W(Tjtz#m0C+7Gxi2udN$ zf3)fEkol(f6(TVE<2`OPWr%a}uOyIPp65d)#&*>;^5UtNZSB+42%ILQ#gko*F=1Cl zXFQ#7hc~Pb9UKxO3zMv$bpARnNW1r0dU#gQwqT9iwfc0`fS2{AvLxQ0TwGbQ+6x3i zZU4c7?g+X3#8j0cwWVe0;k*g!>y0XOV}>oW1d{FqcI7HLkKB8zu$P!ozpF?il$^&q zwprlF33)PuDx;TSp_njWoi`;|(yqKS4PY^~T*Q6iSzT|@zMKAobA%WF`c(ft^_2$i zqGs+*-+X}^zV8PTRA%a5k8~kedy4#Nd+zMEIFQFC6)Xd>j7hGww!~Us9 z2xg8SQ6<{%B(|3$$nKG*(Ekb$S2@!qZrQiV=}J~e9F6eSgEWfzEQpP#M9zx%!&y@m z!QMwb4wQe5`nhy@-(je)qKC0OksX5tpd6P2iml#o07_G!PbzzztILqfS`&HJ&Rb`l_9Q%}A|FykkL+#C*?%rm5Ftg!;L z{=VkUBJ_Y6tpwzyNBV3t%(U)J>mbx?9O2P2+ZMN)hkGH#{TlOLdSE1R6%y^el(>{k z=r6=46v21@lvD-&cA&|~?f&Sl<{1TW5o|LVebiOlXe@ds3Q@OI>dBMI;`W4o*wkoS zW{Q3YMqe2@zmzz$t2a}+bWz<$JXov|g#IS^Zf+2nTm5)H*k)fy>~x#n`|GgXOA>$P zvd(aK=B!ay6t_YJ;pHyizeA1sX>xfekEGg{>p(8E%v1nyl8q{x(vPE^r*{9gGHbGYGBoCu+H)i2v=-yj zUZ+9*8fXlAAHxo^0xN?*F$r{b2OLd)06;IUWXy9M2AqKFdIV91-jCo}RG_}=4ZUut z{V{rqTW!?D`f=Td$oSWYpi8ZF?Q>2ZUSEuO_xLT25)ALQ(uEcjkmMbP;Dv+lps_uT zCaV_rdF*N!OS+S?bPCU$2SQt^o^BOkZ7O5O(Kvu(CZ^c-hF-opZLrs6yH_&Qo0G>+ z`2=e$7Oeu#@V0R`#3rDyYBAF9%(#W}o=Q(P=p_!`=;y`vI7`V(N}ZD&@lAV{o~?G7 zuSj=sG5PzcSvS{|OAj{PFS~cX733AEshI0;3B8tKeem}fzIrKeq4|bHg9pdc+9SKu zzTppOo#USSORpo7jZ!Sq=7LV{RrjGbf5M`A)b&0cYoB;iR>NyDn|i8=Gr?elGb}PL zNVWQx^HJSU;*&S{q`L2RkBQN7+Tws&Hb1eM;Ec}Uo2eB-8jX@{wgR&15T3b_gG*HF-Rm4W>3^I1!NOEBI zOJT$NHgDL)Uf9kJ=hjnE;IRgJu9T&FFLjpU*w?2I@Y*{^?7L&ygpsr9j!h_3F zX8v_qm|(`?M`;T>ZP%_`#KP`$v3p{&LC#A?8J?9-Z^8gn_~hKH%2XTB|zj6iq zCEA>F?G}Zi-AaPZ$UPqD-5@z3_KJM4Zd`SMg&bs-KAmxu7EDeR33EhAaKn%?jYE3t>0pb_4&L1 ztIsQWeBNn8rP2*dT|)^5W}pb4bOh+rhf>p1(b}!r!}2n`57RII(qg`|sC(w-TH_&n zeCB;D(>@obqn>o?hWkYQ*xZBXBB#RROoaVhE?G!tXfh&eRb)(^1GM;p7B=B01@2}{ z@81%xO^vm@H0wyVzjhg1MLY@e$%9ah_dJPhGv}Ia9Ko~V`KF*#p@^Bd4}RoZ5GYCd zaGI|vRhQRR#K1#7;AA5E%WnzbWMD=}Ci*bj0hX%s7vcbs(u-E%DkZIO{ z(BB^t(HX!_2Ui81X&3Dz>rnRyi8vpr?tleBNR%%Q2zIo3Q$A4}DRpA*{OE~a0YidF zt|sjILxobDO|H=Cxo&27(oA@o)TU9@ZDoFJj*}5AP~%X_fTfGMGSwrwqc~Y9_ds*{Gj3>RzUq3af+cP34PL82d@t3jEFWVe%>-La(TAP3l3cUAZ?$UTsG~Q7al>a@5)Q=Q{>XGP$~8D)FoJdK7x)?VOE$ zkrBHQoi3&KK40i*TM_MD(IdZfKXVHTj}Lh03uFCg(Lp$QrOVL}Y%otp1ZvbCem*1p z3u}cs#Ar2RfhWNcZ%#_*S#3G$DN0hVP^z=t4in3d?$PemZsq+jcI?V?DQD1sv`v#M zzTf4a>yeIatxUZ?`K&>BxFXX6Y#{F>Kcqf6_6SXn3SX)A7dUDvVmNM73vaI9 z*$kJ(_^rtDVI-O}l!^zQ6+7=%1$~#!)7W?7C(eOL$6>|D_!roeUkw!Y4X8or2l!L1 zq{{}SZ=K?9+;XTi2x1OQHKVV*u2f?^n|BVKe_$G_fGVrYQok2~jGi!+h@IR{tHF zj$k_%>==1&ihl#69W;6lqYGUfPH?m#xFRk_l=#yeGUVZ!pCD+a* z%pGBC@%Dc}FYYW`^}O!!ct!FDd^j1NGajzJ8e#pn-O1k+QhG`&4m#Tnu`1q@8XiSb zrnqX`v;XubJP2J}=9DXJ@X<@=XQn z@TI7=pT-8vLZa_-Ndlh&`tn~9)z;-W*-8e++QHTj#|-w`%j509N)C=;-3 zbPx)ofOm>LcE5_%J5dvzjQijfhlb2S)KYvr?0(zu?}C^dQmR{x)js8$cu?mT4Trdg zvgT%bQ3v_ZQ*fUpP&2t6WzTM*S7{8Xd^Jxw)u((ngDg23=<)_ZfA%J*MMhc*$fURn z0bW~K%N#?02g#k??}mCW4oBiZkI-5(_p`vM8t7Sg1*KU>@^WCy_O3BQVq72Lb?=SJ z{3?yFSmwmdZ&K^WsNYf!a;TRNIZ&ZNpzO_zaEePfTAOeD6wxQRipS@PHVhPH`sbQWg!8o>YAw5Nd+BxKS5u(~UP02tlkH?F z=kOmL$sM_o$sYK}Z?6vM!ySWFxoUrjN!>j)I>lhf$*CAW#p zD;p_pcg$O#-en&n%C;}d&W`=5Jmc2%DzQV{G7fI(Yh6DpW^*}-IoW*qi>I(X$2u%5 z+v@wijKMVYib4L}n!D2E?T@$QcY0s#(~^+P`j6Y;Fj}|;QarCRUAKNQVP=}|-9vIM z>_kdPN`Q9eiRHwOnCH5G9#kw0dQLjlUO$M~^7VAK}u$IXA3t!?Q;JFFe=W+R|h>;Zot!ee*;|BthS8B7{+0Qbrw`WdNA~QB9iGt6O%XLtnJbk|uQZQpZ&8TX80;vJ$9N}=wHAy00#_jg*VlZzRi6GZmF)NF;z-zn1_)yT0EG=T3Zkxa23u+ml?M{6z2B z^)$95$ZF=LM|ZZdgi%h<%R!ON=}vVxW_&QCLR~A~;%Li2u6fWGsb0}O(BomQrC?~| z5EnN1;Qz7!41{$TG{x7ia>j`0UJ`x6ut~_*c1Ay76Epg(_P0eOHr3S+jyXwbZRPge zFCsiQ8-6^L7K44XpOhC46^OuUge~RHed}wS>Oz+z?zm)Kg(WP>wrdN*)@lxJ^^0U| z({g6Yr}+pOH07iqpZY7CtVUx`;a3sVpWs2)u&jkkbEo?PTDAGeGB$!Zm9MJK)9vNW zuXfpdK@-|fM#mMkiM8T|?lBh2Hf&R?=Z-EHS+ks%8S2mW$+N!@R4)HLPNIFP8&oT2 zw@7;SWbH`hj`5nX#3rgFwrtG&J@0fWYg+}59`U5yqdQWEQ|q0^yM9&9Wws<1ww^4?uB0ZcLn;SF#u*yMIoaMaeB!N|HqwqjPb~Gd(Pr6^^SRw% z-iqiG@7W)NBK+DTTEeThQ_a*owxBpD?lSqT70=apH<-Ub?*)NcX2dmiJ?ZWa0k^e+ud| zly4d~fy+8G)yPisPcf)p#g{z`kRKAY6-7e(7G!_E23PZVg(ai)Y6dWuS_PjgWl$4Y>w_)k3=42$8N&H@ zaO&3D199unblMp_z_*>V9$=O-tUCgw)N}JOJp8|EHNyT}-&Jy6eN!~ruZE?@ zz7HmGdumg3)eAnl>sZm*YP(oL~1wR8}C z&RUdhza<-(+r9G5QMdo3zH^}>AYdZLB*vl_>>K>)dg2{lnMb5g@qZ8BuXDsFcOxb% zO;tzM0P5|g;EkUBpOqx5?3q3MHu)n{PPvC9*_*U=uq6gI7{?0u@vHzmNm|#q`$^zJvXuPZ_9a|=NEDyoBfqX5+h{>e9-?XjV zrT+8@?amBRwwcr{oVG1z_~fF+M>XacwJmxxp>F^i+lRGE*FzAtd z-Mk$U{p-`0aD7K#dwf@rHQRT9GpA;uPajocgI>|b7@DVEGxzLMpmqG!y2@3G(&|L4 zTmLt&zEUwkh1bGrbpmG>T?4uj-Och;uQu#s#dc-iei4`SeXnin5GwdbPu%z2rsJZMib8$SU>Qud&nXT3y!m7SEFxU8@)nQBeGm zqFfG>C%TuHjI2C*yTfJG78k}iPMP>{riH1AGzItx+n-%25EA(Z^s_k%uqS$0i!=!) z^_#iB2~fUOE8}&7b%5OmgUF)>p2EZqAT=xFoSjvX@nDz4ZQ8u~>ADY`AXx3MEQMIt zy1vNF8s}@#(2UNIfNyPgbhmR$MD^vj$;9-~|{uzWsZwmx~t~*}0+u_Ky$qDP76kWmU);xG~AgB++ZTWo!{#{iQ z@Sxtr8TdOB-+1d4=HIKz|s3ghedymdpi@4WfFr~ zQRg2!Wkw3&Uryl~ZXUX!@&)$sj9R=E`alG>BeGxj67A<#AsDv3`!LeC|Ic~cMA_yd z$jdo6#2V10smuC}V*lh@CKS)H{^UY^d$0welI^y0S63E{G9w^O%iB@JwHSu=1S_6{P2Byn6h;^y=8NF9$yTn7|2iz zT=X{akJfcAh_o2K$JNoQfknw%DgCK-OhV|FdI7aRBKT}y8?#;Vrt@R!Z$8JxcDr5zi4#A^>{FfK(0#vj#JB?aY2I0%{H|DFU%O5Fj~0iAWs_S2R_ffi z$pxhbpKK}ai*l3sm#Ep-_t$~u4sGyW`7GmEiotmwNowfosjf^NlZYL z6n6(i00%txB_m_tiV_2`6j>BC|lOi!Lv8fSf!Sjz9iiNte+gE8WO3l7iYLaJ)AuBjF9(W#cyXC;MAut9e36Nb<&mdd2xiF=Chg| zOpx=|vwibri6^xNTKlyot;$}(+I%%P|E15QrHlg;X?zakkIagKxPr~dNaK)W66myl zw|Tb=<#MMKh-yT?wNNE+4seqlKgWN1{FGb-BOvbN^pQ;r|M!RpC+OOf1{&_cA4gct;c|w6kZUt-BwrR`<7xSTl0*(d!0#3E!MS+2MI}}4uh5i zphxV}FNI2nUE$amGyVENNk(SZD|Nc{B{txyMdra^)F>aMuE`c@~3$72razelYQ8d4$gx2xEpc zg8BIXDSti@_HH0Su>I)d!f&<#c#BY1&;cpnx81K9QO3WrQ(?3yY|ij`B|VW+qlT5% z8$vF`+%*?m6VyH}g#6MlcfmU12+Qsko)Dfqpe--YkK2{~t^wJOhh5htrtk9y*O3LI z2S)mmiq_z^0JO4@ z@-^J?Z}QD~LsWL1^z8)&s2eF%jW!-aPXQYg;1}CKTNkgFylq~4oR23;jE9EHdT={S zc#`^ZcQHO=*P%|(zkd=4^GQRLw)HQ=ef(8KF}05aJN_7*fwVuH%UD+~=udsIPKxak zyC(liW6-_AMVmwYm*`g1X=wVULC1P~-)u>I73&VJWOMAl5Odf!#G5|ESg}S}NqmU{ zKrnQtQrQl!m1|q39^5v)A-M!bBLe)WEw^;N?;--wu7HR^^Qfys4?8kh8(Ou3U9 znx}Przw(-iytBQm-e@L`p=rqV-;>3Nfas#SzV`FZAzS!I6+unWrh%@b4fj(t>jH&| z8_9nyo(NE)f^6OKwb_pB$2QLq4v?QktN)Hab6y=Q4<&GS-00w({=1SyMLCm4+joAb ziBT&^dX-ik(ML-^({5!cZ$aAwVumOrrLLw7AgFV-;-7QCjka<&6%F= zvU5UTr&>ao+dR&q+CH+So=0b2XViR+=jjAmsaO9~t-vWA@%7oi;oa()NN1;%_9WT? zF)?VZ@6wz$AJF^mM#~1uPVM^#qls@l4mQVlensZ8g5=uGE2o#@R4#~Aeg200QkQyh z2_%nQ-S`@wNjYH=Q~283Y7_Mx>30t^;o+cYXOO+=`u^Zy#cMZo!278ZJzL~&pk!76 z7fW$J*z$B~vsZ$Nw{6cPRs#d1Hn%Vtk1g|#c%DrO{uK$z5&AdLae6rYD5=%$@U

t;F-vv; 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�|f2qL2ztm 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 z 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 z z<22*2oTfa=tgSp1iBLc__w$^|*0ga0hfT7#fTLn1D8MUw9R zRDTysZJ44ts`v81M45?z(?&UUCD2Rz;1c_XMAno5IF)`tv8zWv`U#VNq#*d;L*XVn3H3O zTq9Z>)n*_cGiqGlIg{jeawk-k9UzUAz=)C|w(q4r>XN)I13c<@=rA5{0;-@J{#rGcJG>n$UQnF zFEZ^U6~&Dy%u#OysYO_S=HIyXrVCn|7{O$C3>8f6f;QZW<-mX4xea>-;~Qy?pYBXH z;Z40_yDnvTwO*)lJ~lrBEeEhb7P@MJUY*+YER|L7KR7?mppksVSO+MKUHnCWkIy^ApJ0mp; zZmJTvV8~~ET)TU{2&9*gajF&4=7;n$)qbH7a1ctL5_XxqaZKEZ{bdt?wA~}QBl#-a zW-E%TwCVo>TQaV69&MY7PmE&EcDccM}>eb>vOpwSw*9rj_37k6Ls(Z?FH0Rc^B>Y+zDRz0P~!n zuEEhYviuFStjCkVd)iti32Y!#;jcXP;hhn{vsY;Myh`?cJVBy#v*dJZJJ@U<#eJ!&)AwTRhl}Xzf9$ch^lR5<6xsKJ){*p4+~1J(D_gFq%F*sYo6lUD6Xyf=VE$Qj?b+$kn6^s8!HE_N$#Ti(S}u;q*= zp9=2%6^j{tYBw!lJCN*7b{=8j** zF>iiT(lXh1k`~pCy84AffkEQ>9!YI6P-`=a38Bq zWb$mDsN`{fYjQKPnweNMQ^P#SvC5}*A|wVOsNLPnE>ZkeXg;mD(*UwM9nv$FqJGb( zd@s%4LlYkMzjxaMDGD82{B;JTT>4cPGZCXpPZTC5dN#%V$su+g@vp~Uo2rA#M&CP8gDCp416Qs40*q}z zvVDl($E+Z4750yL*|V;rvm0Pr;PD|X`*j+41Acbg=CzPB+s&GP*=DEq#`F(CibVfO zjAHapm#!g!k?yCKYHOsDp^-K2oJ-N& zX9qL~japUA*9?x!oCY{M&V4j+)2Z)kAUvNkbeIsH!s8aNb=2X{id~_z-vo34a}z!D z)psxKeCMLa`igJ%NqnNYmPY#^_DP5@XyLyx;&%Vf0_B(VPFIKCa|ec8V?N&}6mpZD z_EP_x_ND9eJtTQd)ybw_rAxH;VW9WS$(C`>mTdONvDs=D-Ob7S$&N8T7Yw}nQ?Dw; zH9IQoT-xTfsX}i#V&vH~2lkF1Mb&>Nysbp*7W|lmy~mpZjzs z3wq2NAO7)cmOssvDz&OU_#;c6lJ0Eg;Vx*157?;O6&Y8WnPM zvUjTOnr;$lcN8oT#T4~|q8&m(^HR!Btb{unmTaJ4mBD6NAmBq5>6H$RojYM`OlHKW z?#5;-e2B$P88Nyq$1w6>m-GZJ;~;q@>v;xZ8cjS)&P}y}nwTJ~y`Lm~lQmEAsj3Y^ z3Tqmhp)BlQQKwp^HNB;z+mGeXkUG1#Y$@zuG}EbJJ~zV(*W<~a(6`^*>o}zKJzZ+A z*3{x=FQmu{LZrr45AG=PQ~Z}Q!2OOTEBGy=>PTZ-Q<_mKYi#zevXXru!71FFq7Xk?T4E84Y-2-4u%NU=#U~Z>O|(U@8mjg5 zT{A&J*knpF`_T{VB>##q5%EQznD+d2{QR)eHgaPcli8(>;*KKcw+S2!rsuYK$(ezy zfWdCj_&eU|Hai>2uef{TXSn0>`JLkKEoncu#cKA>1-?|#*V;OHgHItL?RH~}=F>a2 z8y>3UPNOO-d!w<{zFp~;kYzv79uiV;Mf+>CqCk?f?5|)FeimMFb_2i5P0R#8lFNmZ5U?nH(VVv~d15ppj&7G>J zAiG@7M6is|!J1yZhc#hfdBBv(ZB++Q)Y|1F=gbk(RkdiP5cY`nq0)QfDpJSjq6?_q z*`VUa563_Np6uzP3w&|6-t7K1ic1w&U`Z`i$J}Ybn*VfJU6t z@QmCZ8J;#-iY`5L6G5a7wuCw6`gnX3?~^&*L!9j`@`dM_%`}Pd$;h0cxGc5H6{f<| zhH@X35jXTfdtenMHe>4EdMKSLYqkil&5f_=y5oMeE#^o5>1u z+mD_Fe4`x=WdXJR<9_eafQ3>F=iT`1YD3K&j42LRVi{5vM9U@ox)6wR&P=ooz3zdI zyU`r;g4As_kE=&_>LniMpT7EFBAZq`z4s`pm4*Ewg}~-TeV9+{*;n7GsPFGC+#%XF zdBd38B-+4Z@*Qb8^3LJ&m@z&)O%GU6ErtupG;za+8Vq@Ex~;fTVccVrZ=HYSDMyg1 zPIFkuc1abMQyU$}*}n%r1_uxxA%b16zSVWDwwZfU1NXPC`%W`h=<&;BWG)A~n>l2=Tj&=qwsmDSmNkZ1Uv%++Vp2NyITC@b9fpQhB31cwzwZ;<9&@EB0cyMJi@h!!Ql2H{&ze_(-W@rHNZD19nsxFWz$!dOPMCr1o*OpwyfkZm z+4Heq2dh{_v9&bsv2|XEV0&s}XRk~N2iP%OxCvN=ym<$#()MHN4vL7~tSLk6rR%fvDd%|<-6qpu$z)N+W9y>dIwif$Ug^zX6%~g* zy+cW_icVbxuSz@?H$=-)F{yf}Ood$7W4fZ&(KQ?Twy zAXB!)16R+PFh=&iv#GGyY|$+jVS-a`Vy+=Hm-dk-B|qmL&if2-zFgS=yIpI-nOo0b zLFsPT1zy`nN%Qy?(mC*1%3IS$-w(naLKeb=A7SEhMa8UDP(GmrFC9JfE~zWG+!qZV z>AaZqU&Bgdj3B@ETxluirI#XOm4;m~`kz?P3$O~K2uj`_%|XYyp~TkiSNJ<#Rpr$O zx)CHc52%O$N{lSGj---_UdM|Nh;!#}S$muQ=p69%Nz3QF@QO5fc6(BCX1rC?R2eTs$=jCyl_mw-m?22`NJBX36&d%{-mEv^0{slQZYZsMvh3Eg{n)lAF(l*)o1|Jd1^v zu#m&bt*Fs3ewpj8ONb(zwi%nC7BqP}-3LA!G=;1dloXJpePjPMR`q11&H9DMF`7~!6qH&Ae_Nq{AVQU*7W{?E24i|$rYvAvsXgg-e2?a zJC-hBW5BdK^fO;KAl|4hnW>m*MeTahk_ali<9ERm+|!gq8V*`xkNsrh`NyDE=ZEFE z-faq(VcSJZViOE2R1yg((uH(}l{s^*L%WvK62gVtD8;W|MG!+{Tx)9tRCkX?YGXz1q7V>$-mhHP*Gv7psH^ z63vn+g-XgRaPuBjTi~`M^wz|(y&T;wIQ|q+X1}kG^%x~f&?-3I0UN9+w%I$!_eh>t zq!0iAK%8>>->w%!X==d75n%+Pk8@C|`{!uh3OMvEN{I?7^ z@UWs?F+$;>Fj61_2~E{7Zqk9QPJ7Xcg-O$hIWzxpg?b#Br9Yvcp6pScCg69(>Hj); z_V%ZrBK?s+kO~E%Tj4^_PKHfd8xhYHpR(X`kVzyhYid@>lWMM{jVE4^6iwwBD`9e4 zuwF@vpPj}FjZYdO8Wt1XBd^Q(#tyn57}7h|1Zn?{cmBx#mblKf)y!VF8Ce$bXwhU* zeN&b)|1!({-H=bk#1)(8Z}W+$-EzM1k8geW`eFNeX;`cm{OD$`5+WOO6EdyC!Bl=h z8A58yE*WpvM#99N4&{>UiXtb}J#KrA>YLJ>$VHjkHbgFCiB`++Ji~dm@E+e+t+zRV zmudc)tCKaoQ4Ohj`-)c|a-rCi!k_18@)ukAE$ine*erT{>Kw4}m;dHY1V^IiDSRQ? zh)L!JgYWp>y%J3Wehl$n%XC6y(os^eh(S??CcFV|=96D({=xK7lb}z(Y5e&0)9dvU zbcnMTmE+tOQjcV{YLwfSc3E4}dxP}Vc1^lxX%2f_c8_pfOsrJ# zBjZ*K9C_4CkW#MW6@2W&YNxwH20pzx8SCf!K?DDB^s8D5FN||2tlyk{>BzA1nyeqW zHe|Q^RWQFxHolVBYd-^x@z@J}ux`7iiZ1D&`~SeX(@WS#Q4Be7f4+X!YrJnjDxeIR zcLJYX_u*0Jt}wMpt9vPFDg-wn>ykTM7MeRF-IWcp-F2`Qd>3loA2)J%+sRzYM=y&8 zt6t4VU6fya_jZA_kk8L%yQe(Va1BGQtQjPL?C6uPy92UCDJ>!UJFHbqwA}D1W{E^w zVT*5p5qx*5KU<}3hts&Xu<(DLJMNw12jz_=+N3qan^25of3)@utq_Hho<9y}= zdG4U-z2<*OV}cx`SyQE)X@{}YV)CGsUME4nx`es+YXJbT4aPBy!+tcw=hTYBg-)hd zaw@1CM|Aa}U+~oLRo|ukTLRW5nhsgMNnahtNDFIxUQoOsO_i--p>-Pb`7}^^E>#a{N-E*~}X7pBfKob3cWZkGZ=|4REOzmohK^9mt`HO?bO%U7D~mx!*K z`8LD9cf1L)8xe_{pLRUTFF8}p`ueca{51-dif8LO6@FYTO}jVesl=ux*kAFq%-_x7 z#|_&R*|{No6usiMJ9es$^MSp=_(zE2`7_Cu<6@J3RqZR>}zRkh;{y)@|nkR^9u?X3nBZkv|{cmGundFrV7*S{NU zb7SL+v_DB+$rFPc+%}hAF*f1y^?r>QjBnY)`<+@w{LJ4S606udBS|~@oJ=KMaC0}H z6?@0^SX}96xDZP#yMVsuVP#|sMaD`CCUqgkXscH5$nxXvOZRID5~G5@c)BkbOlSomrv074 zR=406kK-f4xoT|MrtwOLyvKyWGll@7^H0o%&xc>L^O;~hY%Qmmf?d>@fgI5?zAnUc zc5yF+9rkCa>n5yHdEYGc_H51j71=|OO`&%4#NU!{*Jc{;f>o$~g;>Mu#;ccLq__cH zn!)CM!%ew>sy_ll&0Z>>pnKfv11|CWzYJa|!C*sJBb zoSdWQ{8DjETUkzS(3hIfSbQ#?ftE`@`}EGGmuE+-KE!CS54t0|M&!oe+S!uyb0o}$ z-qK)lRt!~1rN7Dt_3zT14BgQf_7a^UXK4PIdZNH}4Xo0sf0R0xPk`U| zAX>AWviTh$WE`c3UVMHKdpx00R&jQFAM;U(jR|&w`IV~mfl^+h#l*&Me1<|!FjtWm zfZ)4?$oGzq=K5je=V^66^3S!7%&i4e9I3yh{d=xbR@pU(XZ=!#KEoM;_g9>`4|~~` zBHM-Pf+13!W}x(Np(HK%l@6wHCR#ysnXrNXwl~~=Ni7oAGq+@-wE9Gw50#pY`5e=G zP1T{=p8zaL5|Iay7`!_3G176D{dp(Y=rBpSW+1e_3bX&gevXH(r~L$9s-j$0X{KvbZgHHPv*`U0Vtl;wYGpwYw7ENh^*+F58%?r~H{(f!=KtR{wFj*bJRzuYG|%9C z$Eh?|Bhne!&f6)s&DN?kt};cWNvmr#Xmp`Z8{e9x?W}G07IJ>Vw0imUAZgHm?iQhy z0=A13N72g8_xatsX>XwnN|uNM-;5`7#f53%o=7)LF&7nBs?G}`*pQ7gIRySIF_uMN z3yGEfUBkNW4l?nDB#!_X|Ng%JGW}0K>EQP#^?s~P0})#x9+A(q@4Ai12u~`TS}g;HF4)k^Uf78NG$*F-uWM0r zZA<0C%XxSg^aZ(M@Cta@MY9Z-oE|aO1mDD-&oSB_HM>09w?iV!-0rS-*4ht0I7q~z zR}w<*+urCts2XW_1%Y7J7k6S8YXcsz(&nIv07g*wUs6O)Yzzets;#Jmr zt-|{!N(v#B{dX=DbHp}X30Xr8*1FFR+09&mX4mze2`Jykf~Yu=XLIG8 zW{pOOa&}ydDOx#=zmow|Lw2s+s+y5q6p`pqRXbMnklHS6qut5iIL6^tWo2=h+LjBQ z=UtYoZO3zGYj9@+Hw>Njy4AASe9XOs{9OFdUY)JzX_b5H@XiZ9QuO_o!@J}!e#3O# zGFCkKXUF-6J#-=o={^7xi6XB~esNAR8|EHj;~TL-$3SO`m3mJE9xNh`urE*>X*rum z#1P_ylZ0!+6vBHT7{~!S_H#n39C!Q{lS}vuNdQfdquYJ(jcC)52%Vq?mO7eQhh4?#@$v(1NH zLzi8vIi0FTdtT+mj5gG8nlaVu$x8lZg$JxBsxZk)ZAms6wceX$WB@bs7suC;ewvy# zHY|Z#lCRG(Zw=WIH+Xgy9^mkq!DDu8!)o#2LMTCATwHFr&~e9;t$jc3Y1Tn7&GNkh zzF`~s`LU*zWcMu(5Ah9WUmf|{ zi`n>jrnkrVQ|UqbAj3YWr8jMBSQxG6=C8m_cZZqaY8@8izCYwFC)t}+g;}q2X;!L` zP6SP!tC?K>rwjga&YZY!DO0gtl-vPt87h@Xwh-=Ui;<2@zVIP?7vv-fI(eX0 zqOlX(+jLWL(#_!-tmdobQStwdlm>|EaB|-#^YmtJov79s!$RhAdjZSO6p68k>sr-Fk3PYKH~Rf705f@3#s%<$mMd}dJd zcR&8$!xb*%UDayGbbnvo>sR1w?=N+XMMnGgPRfN8t49Iszbai%>1~(xuhAuTs3|#E z)9c?Yqf|p0z+|cEe|?UH4XE82yihTR*)^0z{+>KOInJa^(5DDX800;YLeUqB4vybF z9M$Ydn$fN^iy5u8`rwEXPM3y}$1HC0@Ygge>L+S{3TBio4o=MhkmFk4ztaW2Zzh!F z(Bp1CIXHyyV31j``7+L2bZ@UHzSjEhyalRm_C0`>r8ssc`j^5We1!bH$KTxg5&V=~ zuG+)eZGqEbZCy`OraCs3b=J|)5_OEu&?)W7Bgb!uIzkwf=b5+=#>G;&gFKY<(XMuP zl1GwI7M`|GOau9>z{G1Pf+l;5c))v;QF}$Y)zWq4>S*ZS+VmSy98r)ERlV8;{mP%0 zAtrj19?zQJ<^nxDay^wU+(`@drzA%Ywxv)QHPz44Aq%z7F?mG-6%YVXIu#C4!XFDa zA0So#aTew24cWS7n~(Y}bp;IG!3TV4v7P*&G(A(v>Ef@w%<`dhS61BnyRTZ{e77B0 zPwAsTrb13~kG-=Ych(m1ngSrD;}aVF6w+M+-_07%VH(uCp&%}%UQ1W73Y#w@#C?~C z^+g(4Kg*2ukZ1~>7VF?ea{x`ickarqHmc~v!>w+s?niIL=~D0&R{1jm!0Q|tm8gUo{V!Q zn}=`*Mk(p715m<{Q9iK`kQM!6#d;m5dDx2)jYQfrgc(=;$ov;J_l*e6WHCVw`F}lXHtf`Fnwwbfb@o2 z1HN^CwpTG5iQXnYc@VD5({=W92{UeLmup-d6J!dbu#(=-bD3d1 zwNOq8xf`isyEmSwB%?Y#1@{I3N9>$FOVozYmQ zFoTUgp2OSfCF9qa*znqR_f1+^OyrypFt_aWL=-hH_=|M{C4#|w45`75DmA0WNC)s*Z<9#$;midleH81lXMbK1dDWI-eL z9b>0~hZ#nbQiUq#7I-2pa!r~=1z}X`PB21&ed}ZVKWA42nxG2dlPc|IQY5ID3bgVi zglB^Xa~zU^p12)a(zp+x<(+*nD83KfyTH`)cWR?g)n)%Ns#pn6OfzyfWLPEZm%BF- zZ}5PvR$iO!uF9_4)c)qq?YaQbBU5XSCRNeXJm`(NFf3Vq76%MN; zFj+7RsB04zqz_r_9p$`Nj@C9S0nhX6_@{kcTqm2(`Ft{NXQ=#(7%lR@E!A&$S&?-n zE$XYAdV7$6j3D>))H90)Qwz!Cgz-Y@*8z;zgKGTzX%EBSLScM%Da^rPW!m1n%s@j5 zQ^b(qf(8|!#aSQ2Q&^wUrJe%G-Eb}$B>7f`N*7&<-xFg8>8R@n*;b}OP(YltMveW_ zR6D;UG>UbHi8jToaG*65|MC}RO+){--UnS*$7F5QxRuC`l>WlX<(4mUCHKr|qwCIh zeGa<2j^q-^T(1-?QAY{e(aBnf+!A5q4|h%_-pYobAI_~v%yV+iHX4r|){^m8+SQXE ze{f)v8plYe_OPFWwv}|Jd?>O6y{593%Ig8v_fXpJrtt=6Qa@b;f3Kp@> zj`6kmvQd8a_1thOuy^c)Mq#fkzRUnIx6vmVTWer~0ubF1<|Wesc0a6$rlyZ7(UbpG zUkb+92c39~Hw(f^s~7w$mNu*UBn4YD7~)f@FolCKuQD2c6EEbAkOXQVXe};Cpc~PLnux;yFJ%s~O z3to6FNU!rm%C>atDol3;Wm5;mbDvCH`Z#MEur$x%LryT&=a59Si6)A6-yAQ5*wZRG zf=BTrkV*D{7D?Vq*+A0Av7m{^CpKR?>UO(^Bqa{&p4qI)voC9!b9&IFSLg8ecSw78 z#paOf=%L|0XkC`bL|9~qosg{EzoX?FAYQ9qovyYlnWY|sVmTUV$U7@Bc^Z803|N8P z9i{5OGS~V{yG?MQYj*WyBXQe{F@KI{zcS6AovPMEY<>$0n!q9bMn84`SMAr-RISn} z^zJ==O)3fjk|Hc1RcyKL(#Yv9II7O>;9idZDwKJ|-3OXfy8lkKQFnq>gY8k*i1Juk ziFjBM@5^0>&n>>|nK87X#X(~#G-|1!d_%h6P@VLxj=zRoOMhze{G4z@&jwjr;KRv% z&r!+eBEGw+P?ocYCVqe8&b7d7=qgcEBADDY*-I{OF4Y0(;^tJJ#FOXovY&Q)8lN#f z<8{>dIi_Vjx$k~k>${HRd}PlQM$yuDYb8yKU<6roIgnewZb<)00tkt^o>iybKMOnH*PW)4;nxg)Z@Fv3>T_NgtP^0XS8 z>a?I;D|;DfI&seCpfWtIcim=WZ1)RO8xO2%kyoETUHwdN8HZ)a#aeTZobDr}!b7;luEgUa@Y2Z?@P_!HdqsoZmu--t{9 zcpPauqf#4Ml^3(Q_X-sJ95g}a^|F4{M`brJt#0!?iL#Nc&>GpIbLwcvLQ4`Zz;c6K zxjn7tu}yKRmd60IZ40Wp-I2sW(_S1XOl63NW%mjw7x)g33)dZQEl)JP8*P~1KOxRQv!m-$Uh!w9BPv!|F=oM zxo}(5WVDSn$vWe~$*m-r0|WWOCyyh^yAw8dEuc%PV3V<>6iTZO@3eu>g1o1CZ&nOk zwR|!MJ^N@m$0{BexqN!wb#k6`MHw6ZEGx`$N}6>$-$3j@&YSis97aZDwy_l#GG0$sfhFTe|<7 z=5z;#IDLR=PHwd8RaUrE1Fs}G5zUKcYhs)c(F=jgd~oAk_g7KA+W@8)D>{_BlVL+s zQh=@K9#Zb$EKxRZDnBP#Hjb=*JTgnj!znv*H!AD$;6eG}{lCiRkux~|-eG|3{V`%`PV9=@RA6eZ-~hrxzN z<)oWOr0yQ%LK6r4spNf8pM9rFE{h85AwoH#Xw!;8~Bvr|aKmOkrYD zd>nV47Q|bBb}A}pmG552vhSnw>&$W(8hCm*hUpKDkMN;h&bAiG-S`%I!;A0GI(i|d zF9zi~^YLwtpH7C~Mxau{O#c~!rE(34`kOr1?f5ZMkuyHYlvR;)CMlwuagYVPSt8-t zIamC6l=dQAT(O#I*;zZ7E`@ls$3|Y8O)h!6{ETi&VNA!#u-xwTeLJ_4dfj??SL@e1 zhvZwMwB*OM$s2JpC$J=4h!X=fLE3>Ny?0huA*3l-7cNVKAp&XxzGFEHdSreBQ_OD6^?5+K3aaFh;x@fsak(^YP#!Lxi$ED!V!F4KI~*cdg!NTRY?bie_)%J?a=y_ z{gO1Y)P27A+p&6ZL~JimiGd%lJ|X*bMj9`2*2nPsJ9)II&P+TjFg8u;_#QxUV>#|b z;8k3MbQj+y{J$)Ku1;w@EJqqJxo^elD>G@!tqaBNHoWey3U{J~IaEiZg1T@YXWG8U zhC^+J6wGX)Zi&TPclMWo`Z;UwPL7=<6$PWOJU*LmlASMYUW6?-V-;?mRDF+0(6NNV zt9n$e(@J=yBJFouOc`tXuLXFU&oIK);iRx2sZC}Z>X3+l#?V;{uVW0$i7YNqt+9Bw zSjkpNE!)X*Rv5Maekg){;-VD|wW8?jIYhq9Gw>>}-v{J9`YNekO| zI&9X?<-b>!rflgq)jX$avI7|liq~9csHhX~P^2%gBbssLKi&S5Jg!P!S13qKq@iYwo_m8GrH9@4q@SS2|epDb#X4Fd;pP=Ap@Epo}MZ#=HndY9U7bkZ%6st znm#LYIXRKYp1FywlTzMZyJ!X(2Z7y_vHueD3@2A})eLmC*XZk9hJ(b=X-2fzH2{5z z+t3w?t-U}W4=nRm@>W{iCn1OE@v#sshy3ZI2 zS>&x`y5_|ivT<=rtK?}ME#z<`Wc|GeysVj63?)S=zEJW`b&gd!YRzg4m7a-K_m;aV zdGgcIlH$3tNLuCHLGCI%uVicz^xkO)_s8`s>fgqAy68@naP948bnBV*v=_H8#bc}) zC>g7%?89GGHQ~tE?&*f?dK#d#q-QTy_oxAdObm1CxSY3tUSZ&dszTSfE$#jSLY@1Q>UFO?dRdj+~IT5?oxs5eyCIwq*J#Dw#?D`w@+^v7DvN&07 zT@>_=qxE(-R3BO)_=($O@#1^pt-?kE)_Wqg4Ag(K1`zJ0lG~auV;xbIJ*wYaD52VD zbPwWtBzE8To68d(__8rol=h404m9vYC|`n$J&+e!JOW-Uh^vP$x?)_Mj+ zv+;s1nxKu+f>^1;SDl0(zegzJmHN}c`j?Z$KKA;d$Y5s`*!0}4G4$vCGPI4ymtE|-E`9nN7i(XCOr{7 zPDRkxMp;GNTOK;Xhq9avs66F{3Gs&MapL~B%};ahdCp$dpf}{JSG%@~;>CUxRni$Y zWc`pFn_7JiF}S4#C?oUFvQOlhTX^0v^)~A%4Qyq%u1nhO3wVbs#lYg~e;{@Pdd`gY zu`BQQ@1x1ly`Y^E%O=DmJ=ui&aDVSOk9)8)NvtEjDZ}Aryn|hFiwzxd=p1zdQt~}= z=%)lcK9q@{3fO+Kos`l`RuqqsR=0?cO}7nqFF~!(cf#uB=qxf4`v{%23_j#8Q(^7e zTTryJIZi)~$EiO~+t5RT$3n|DuZ)f-g4hXSsw;aZ=#R-kR!m+=Y0r1L9qHuDUWxmD zXa#e+r6vDW&D#xbHN6h%Le2*0Ek1M-)x)}ls&d>6+rPRP;bO^8H#GxSwr?44T=gYh6smwUo%doM0n_!tg&f3)89@)n_Vs|_|53D z?xS-)Sa$B;@HTd;|Ki|_gzCp@nOPrL+)p#xX>F9oRW_+M zzYW_KdE0PTChZ}kgvg$POcX6g!1DmM*@byMZ;245Wz6o5gwQQ@xj)ImL$^+^W~6D5 zSI~Ti#7&J*1R#pV%CB%RT`J>ayi|1G}+j}Oi}0z-7>?1FS1H~Ti780 zW097lB%|u9VD_tT$3T`V8L;)=N^yLjA?hBRUX&hC=ioyf%8B{0mgA;ZA$j_E`ZPI~ zk?<<5e)1tZglI!AFS%ld%fsR!51Y(n(?)}OJ%u{+Z^1S<%lt=hHK|tz zDZ-gYU1r_q(IXEot28^VQh%Hi17Bk|K6#lem%Q$=VqbJf_;GK_5?u`0OSxP8iM2{#?;n~T!l8lLzU$x zc?;!Zxr}9e6_#w%9}BJU7@w(u_9ol(417%GnvW!*IL*p(-dW6BAfK$`sz?R~$G5^0 z(g%?#C9hjuiVMe#*X!@PaQODWD|@Ddwa)bP4l3c!SpAwC%g&)CcX-Eo{;m~{TG#t- zi2h6)(hnuchn1l@P8fDRWRA@d)ic-iRJ^{_>ljPnPnX@aQAzjj8+U7&qsJ%Btyx;RDh+XgW@%-P9xHQK4m1buiQvf0oH-(M zmYS6&?mcr)P;>7sZV(5E@cZ;V=l4H{!{-3^`+nc|b-k`K2~?`akY;#_D4-C0c2H>! zzn{6B1M{dzCCT#yXGeVubROV|6qmP2Q%tc+uP5F4h*+mCAImalu5&gkO-7J7Oc|CV zvLIFj=hno&#jfi{)Ww^_AKr>h6!O&!5UUlTvzddPMiUNZT|(RIA59VV+Ir-@OF2Qt zn)8e{_0=Hhg}c}bS792z#54S6H{@kJh6-~KuT!yK@@QXG*CGY3qJ6F*7&ScXF3DQ1 z=*^Y+AIKqtt>EpbgO2lvYOi-|hqb0$Ta$YYtJ8~$!TtdaZdL8@+odDTZ-rjWv*^Zt z`By`!w1|tl3lMPBV(-_n3)+*l$->|D<3D;UpBq@bxJqo(Lol0=6EEu*iiQ^ zb}@?5>~%LkFG+K&UK^``okrQfy#v{Kv&r{|3Q#;NcvAbIY5>lw2GILi?A^jbzh%dU zlGY)RV>GhBVw)D_MEZTt^t;?p&hCbpIe1~|ff#r{?Lo!L@m-$SfZy8_;MGYM9(ht( zd{07AcU=Ty0U#F5As>`&pjuPQ(Ox!CCN4*|gcycN&L$10sH}cX@zWqnksJ zDm;BSmQ|)QUbFurOl7!0*5Yc0%~{;}tgQFCj8@fJkmgF=PNnqUB3Zu#1p1DMA&Y^& zv2o7czYVzkH=PE15fX}8Mj-71(uu0+Y>C{vc|!y3ZEVO_V-=D zmPmQE(>{6VII#)pD zB5^$u9Asm_vMSGD>yut~d{AjMQt)i%!yw#+-E*U)RMG=pw80e<&aG#k*%R0`lhC2& zMUF9C;pPs`g&r4#?oxcDFpOg5FaJ~Bd&*yWnWvVafi2KULUcjOKr@`p@qmSo3twe! zXrP*>jm>H#nlSTNdA|{K3u@W$AuV=25Ayigx@Oc>lIXmG_#^gO9G@F2z7mmzND+t! zE?YMCZ=hr9mUz;4kv-oP^9nv}O5`IY6hSosU+Wtg@2vp~ScOqTtKIcwOg#1V6{ub3 z_Oiu8FvqG*2zQ2ze9qE1ie-;J>exNxx(-6GLup-af^{W*)1)TE^FfZl3M=W(*rJyG zk)Y{v>G`#A^xjj?HO|AnRMV|g%>S0i0yM?!G9Ens}MsP z;S@!4Z=Q9IUmFiZ>Yq;Ud`tH)E*jo&ObI-l8^SSZMvi#hs(vpOy{U#FX7oL!P5u{1 z5WzYo#Afb2RICHndFCsUmqU%#y02Pk=`eVyX^>e68*MCOUhM4SNiOn&zAMiGIGL>V zL{=)OvHPqdxeX3DV03aq^P2Eut!&nHauh|735wDOg9Ia5UReoHddR(LLtFQPv7i1N zmv=kh)Z#NY(S&O>QmxqZ9fk%Dmn(F%!GYjKP(LiBP2IoU`lljxX!)hZ!mx*AVCF)Y zdyJopgYf=_x-e&xhcf*ZatMdhZBFNb-q??@NiTpQ7VQy{Mww>1r1t36G!3nZZh3jN z#pviP*b$M5lIruvUr|04Cnw&Rxstl{bqsu$t$LIACFmQY<~YZHO+D;?FvP*o(owfn zvT{BD^@X$Up$HOqthW#rm{b|3a!b4m`_TFplf9%3HtMdmv8p~su3~tST`k0|-AS(~ zll9o~9UqAC)|Y#1BrDAvVHB7kV57Nv*p%{UB%cz>Q>6tW;S%Q>RPyJ4VPT`aA7)3F zx`hh&&l^D*c&gnY!o1tdZ9MZbzY=1~MDikbuPcP84`=jVvaSXD=+bviVlFlSIhuqH z_VVbYF|Py52AL#{?BiwrteB$3h~;Z2Z~X$1JnWb|ZnUV&G2=dB^X}I5?{pb-b?QeL z`K(v%iB>J5qPHWSBB&w%?GVv_X*i;)?i43QU$^beCwB2d0(-9RgmJ=ERY5Kr4?ZHo-l-PF`~V*T zN+VbTqm|&%`HD6109ImRtEQ@zU;r@3X6y_mpZg~``YF}AW&WksV+dcpotAi;IJ}-E zPB+}Z^9?NF!|Fr76h`^LvUj@{Wo!ZXg=B>+Ep`!x@br*xU?&oUy}rHG1CDDKXtI#Y zYTc8ck(MO3cs%t@Q|rN5+*#J@4N(-^xsYWU+NH%{2G3eUna=9 zVzRU4D;&|FouXra^8R79f$C8Zx2gjYr!xkzUo)&LG=*PNm}+IyQ-Wt7QNsK45cn@h zRdk*2^R&yq4gpc0@gFQ!9e#jk^2YIL)yBRBgPDYwG>7ti%^LSKTP5Q`n-&wtjO7#m zFeug%uSYr)hy@m=R8qv`JL<@<6M2{0?w^$1zg7iaZz7~(n2XGJn1h`aX^+VRvzz@l z-?|lv`o?iNQw&z%-+jM?A!jW zoid^akM#P3raO5Q$&9Hfu^6qa4)vpMrKNuID0$(RC7mEnhZA6?^wTiNX*XJ|EhFlM z)H@p9IKYAaAfWtwwiTfzW{CvEhuH$NvqgNLQeY-);D0j5xctMfJM$uPF0=G*g{z9E z)uX<$b)Iz?Ov@L=(|3^5_;)7;A<$)LlqKUN(|v_nc;nC6E}4W#kr5OTv*@eBfz#2M zNrfJYml2mFtttGVF)d2JbBl`~5eCY|6;^4Ezy7*Ll}j3S^qDu=iWzZtvfFnt zl%E(i&%X+ZR4`)pK*U(LOe=&eX7Dz-wL8QbNnX*T5f$m4)CINH>lxYu3_-Ijdv}>{ zbY(NLpgbaa&e%+VLukB*Q;pkGadKH^A^}Gf+u~q=0qeD#MZ;&sQKtZI=+%Oja7%;0 z^ApU4_ZsR_jl zbCJAgv*KFTx&KQ5(iqGGq1hBvT}>w371r+Y>%T1;)4;@w@Y&unmEpG*=vV`>_7@gREiciDUrP zj}ci4t30cx{sui;;YS*h5y1}0zjs2rd}@4g^LM^vLDH9TrLFwR#fNab4jHdJ)iyiC z7<|!mLU9QzfM~IbGzeGBmhAI3i6X7%9E9>9=DYs)fCb7SjX~SV*7Cl^QUIjRMso{Y z62hedd7!8F&d*1iO^bV}nh?u%@>ikhA&w++FaI6)MrtwB>W_a7$#DDehwc!DbfWm1Fq(18@7Rom`<(rgx^qk66k4p}vi&i6m z9W9I4DvFSTT%`9>L$?2LFGuBTAUH@(>(Pzt)u@SA9;Agj^jrhs!bNt5pm+gD$7no~ zloL*OX<7&X@q@MO#XSH1O8dBkj)a-_y1vx~b}-xA`h*Q$mJ%1VUxMyO9apXBu=|5X zx8&3`0!i!Dfx5sADVbTE!kg=ZMXyNhy`-^28#OS8rEar zcktyyF|}EM#OV4Tl(&xnV%+{;c$|RE;i-Pp^M;qr$nTsKY37-<__U+_Be_Qf>cxqu z3d!6V8S$DG6P3jZzkS|Q18ApdQ?pLfo3e<0<%EH?X_8`b|ESRalI{9}`}!wDDbG~A zH0{f9cv6)+Dp6l6DqYUqD#(B};0B4!Sa+UIl z<*hu3A)EiidF3u$+NqXjPADYMj+kZPM-jO+<2J$?W(qLbSztcq@@vAxQb9LH zTM2w)`P`2PXwnzV@q5fg&S&XYqD|8WV>E9H-VI~MjPJ^p|l)O%T0gc}!x5}zIlE-etKRg&;vb1e*bwlhRnTK2R& zSM9o(8uCF$R1bT1X>!F&dM%^s1Quh*WNK9b{#RcV_+Zr2{-9Y+5y1hO3AZ}L@tmw151y2NfumU%{U;u=uCh?5+b_$HFLM1eT!={>O0#=yLr2VK2!N&PJ!ycz!3 z1WC5+X0v3qSE`n+^1b#vfff#=a+OTvxh(Gev?P7oUee1VO|rxcFlI>0h)w!B**#V$ zcV+ld)pQKxZg5uZtzXT^`C|3l(G>3Qc~(~3Iz>`2g%8E3h)B_{Yc^_XHPQ6s&BIb2 zs1(7jCs?Jf^IXjVwf?B|_>zJ9k#t`qsFta0HYo1d_B#dDA=0r7iYSwlvD{T)iYSQI z_Rh(gX>5Fa7;N{GmQt0iq11envGn|BuDYq29T4S`)rN`p8J=7lZ(ObnL!`poQR5L; z8ZjS5$zOWWJYtHObrHS~8#hw(GC=ppJ4SlHe91HZB$xBhEU130VdpkKd*dGGt}iu& zRj7=Xqlj`E!vBZsw4qbR!~=jMPLqFqkHe_;a28y&GmfEXgOtpRh_8o>m}ouC&q^da z#5l#bRw-%PcGJI~F~e%v%E>SAOq|r+l0i0Hg#KJuK^7fL{K01$%m(IYrW+prL!x0d<7XvyGl zC|pu09$r0*Flszw8E~A4&}htLcG^-B%-!dj2qd=HXIYhDGZ{~|}-PB$k#j^5uCS$3QMt808MgC7g!mp`joM}`i zYF9dUa?VYo`ue=Q=82J+X*UG^bz(fF9E9*B{rFdpKI>S&4}NebgFFizhQBjoSgx zYk0f%3cZCK$KHFtl&CDf+FLx#JkdS$2^zwLF08 z@^9mQ#;(XV3y|YT@m~P|>dHqksH|8{|j&p<=_>uIT_5&d-JUP=6E=Z7Q3CA_lL&-*?2rT?z3wSKi#36!}4vxRS-|ZvBXb!4jJu zz|60U5p(eWfxEQkGOc*0>YD6j}5Y;&USA7#WP&= zSB0fJGfU(rDP+(9^+gL3JeCmYAZc#HH?nD=dvSi| zs#s#5u=bjmu*({@y&V>;3U*V-CP!0Lunm;`}s_nfuL)Wt%EW4OhL?M`JNfU zT>k58&UGhrkG)C%<;i6$p-j*}=>UY1E%QXAOoUBsQF&gE+qh0zKXhO+y`}ff=-tmi zJ{Hu`Ir3v=z7xRw8s5^8`TXy>q>@v4L?lfNI{GJF|+qd ze9wKL?%UUte?^WdEhEG?A^9;P=sIUJc4Zbuv#B`b%Ns9K>+Olh? zaBnp2m0wsoXYtD8QQfqewCq||6QwC(a?bModcLjq!WmM5=;!Q<78ORdBi5m{N{p|J zMEq}*l=D7^;u^I{mZ7!372Pp%E@#u)try3l7G2=SQ=33hN@QEDG~Ah*TZkLuvuQfs z1y;20E%^5Y#ETGRyL^e|sRJ=(0`#kau%iQDwfEPF4OS5YNZA;B2H z*zFW!n8_Zix85P$X}GZj9S255CNj-`clVFHD?kS^auj(Rd-U>KMV}J#W6e zww4d5BalWJlpNpGy<2Fx?r^d+I6j|>ir{ZDo9Mf@=ata&{Dsn4 zD1H?Ts_4^+@uIRf7M8FZkh(Gkx+L0URNJmiQ9*AAaW=98)Xhh16y>dFZuXC@)xI+O z>`FxWK0t?6PMkUF*z*p_WWfEq3T_Nl4KZNZPQ=a|N7kx?$Lr}BQdN&lfb9PCKwE(C zjSfV*m}2ev*TFRs=e8$bwhCpqY3{JHDwbT*h~Yk9MwS{FQ(ff5tw1{M`1q0D+hc_r zazJJ-hO6(enJp~V`1Is&go=0p8Nv4R6@h{~lP2x_T%j!~(<1c17b?^2Zd{!sFqt*=W_(7oW zKxS5{vHAFGTwjp6)PH{7XA%{u=W9+Ua@ass^dLL$XJ6qeVFNv{H4h>_$6j3O0xM6n_f{nakV}Vl+jTR>BfowoI<)(c$-P z7&3fER`w|V0F!zzBF!$M&Dkbk!1u4KpIh(oZ}xRl*ru9eX_4zE zu-7Y=Xl4n-kz@J~W6=Z~VWTzgAG30Ip1&YORSym2gIICAL-t8O*B=Zwx#SLh@qNYI z`t5C?72GR)Jrn7hLD96Y6HI_j3`bW_KI2=Xgr4~jRTfcrK>JMlnY8}pf+po_FX-P# zj&r9wez8b@rGMA79$dwE4sqew+xscysVTE4>3f(Qh*o>w*x36itG(G;}Rg`te+M}^xp9^9lKEG_rd0%=4OxUAi1OLST z7HzA90#cj~q37^|O-|v>ug)h~)LkQy_`}n{rCT_eRqUdep1B(?77Zz{K`EPP3jbZz zXw7^#@)AjdZYe=y8vbP;pQMJZ-d=3B?38*%{_t()6Z^PaNx%U7ML{eNRp0BwRvBUB z8y~&2zCUNatYl*2xE&f4Tji0GHBjZE#E}_(lV3nySC}V8vqui&c@Kb`6iJxncCw@F zl|H5&&BLq#;T2P^vVF-H2eDV$1HaST;mXOJI9p}HgQi%S#l0}wB1b~(+`+0!Q@}B{ zKWL~^B9M({={NIQ<5`>;4=E@1Vkfy6P!k7tB67pQ_@Yaukye9V(9Op)xV-RBlX*2Q z7PG{Ug9qoR&OAeGYKGxBFf8 zJ@&o!Z3E}bR==;F9-EnzNW_V!vfQ!?KG+G2fEfq;w8e(0=GH2qmQktt#Qg4(hz947 z#t}Zv0)b{o33^qHJ3Y`VYtBufjo(yn#Nbr_v~a`A2W))$w)NShv3tU(IWsCF7zF8p z72cF7cCanGE3R_544eOwkz-@=N#DZKbQ?SQ_K@&RrNOCOKeD5b3-`T#Pm?pWTF|Wz znrMVt5-%|gKP+w0F`76kpsgv{ZUx}N#gsdkZ9`R;^Py!F&WK|x_o)%Oq^#^!vHoT1 zpOgXvtdX4afAm_H+!7l~=)qkzP{((5HN-r#ICv|scS30dTM1>= zo8Nz_KWF1}ztk$<2+(1#v)y@1YF9)OF0u%^h41v+-zDforx!8R2q$!P|5&AZ^oddD z+2fO58t^yGnPHD4K@5+723F)7|9j+n=O<0jHk%aI=BK#YjkMK2}rZQ<3HREYL@!(&rV@;-p67gbc!zS=d`TVr|hdbd{2(>_tPJI zh+44~KN-LIcuZkLUJLeC6^=h{<;&%q&Ak44NLa>YCKR z9b@IyMN=N)S?y}a;VVJ*;lz82frFnenqACxW)~Sx5}&!=j$-GnvRJ|BwvHM-2=PO!^?TdivF&OwS%@xlg6pm< z%~+gpu+4}~{hxQ1V5KpIZCb|u9l(i3w;}#@8hpGqf%GoxC8HOA3##<;*o>~mRJrae zu1rl#2(r(`u+N_L?24j?+msVn2RrMOl^vSC6S}^Zmvs8S2<>Z;b`otXIrB$bgs_ei z&ep5{8iCgGvr9cyCLnIGSIAKb!Xj@?tnD2Oh2CJZ#qFEg<=s?CcbZ6L?*U?F+Wub4 zF&9tJcxy+;7vFAp2zuw=)Hp4&)motbnD^A35@t~<8)pYQ`^hG~B9-zJB2#o|z#alA z?~O()dOi29I#Ynfs!bPg<3=V_T!Z5Q=E-a~rPOq(bpwqmb#c5!%MxE(^thS!ckMfiQQKc2o)a{Y7PRA6X9 zMI3`1mkiPMSy!#yvbOp7qG`6?#c`_dt+Tbg2u>khVbcVpRN6ZD8PgpNq20kR?-gd4 z6}(jZ1^3r^*YM}3t%+9hn`N*xl%K4PgDwP!wjB^S!!Q= z$#~-}n@ZgpTMLl!A}%U?Hs*`++hNU|jK}g>&fX56y{vVU7HBCpOu`0~&it z4+6nM!*wUUXd^>#cLkETE8K+7v}N!v&Eb2utS{0b~0So|T*23w@XI66$T-fJ-U8#-~Z^!&3XIpIs<+BF^*CNhTlkUsl z^AYRngrnaAjqaqnvX_8QH<{D1YSY!UPWk01j| zZ)7BQ@Fd57@f|`3hpkX*tL;mrz~$5xU4hsd@e6A|Y0LM9pIRR-3u65{o-?G|hc^Ay zshBfQUc-T4)!VEE_ui=v{O&lHW!*s+G(y$T@)zQO+EZl#aV;gXj}CwJNt;SXE!W$! z^Fm7G&bcj$TX|gNKX#jjKg!CAEjWBB=Pb2e*SJ~N!3b`A?t1?erqpgPL*`m6izah9 zmgX-`7_#3V?*;feHMUD4T>HGys8v>eh8Zk%I)@S0${tK06u3t7X;|?322RvBhpI;o zFW<(tutTF4Iu7{jzcxV(b5!@y+*KZyYT{j&z)0@*0a8&25UO$aq!AwD#}5*{UvSP# z75AAuzb5F0gmZpeJU%yD-;CA%hbFIi&z1whc3RjmGt%*uI6z5R-FsX4byg%~DZ1tH zY}n#^J}rv-1(h+2fX_#cXl%fMR|gel2T924KS8ZLezq@bKf<0|7ar8JVP-L`AkVws zTA!M2^|izXr_di?(F?G*cF`&ordjj8*`sRjDJJOU^r?!*L^@hz#1=cL`Dt^wV@B4R z@cyN#OGoKVi*ZY4Z-b_gM)l@iROK0G`FrX^jk&F^vo@!8y}17(+mGZ1zGbKoNOga2 zEy8I^i@y{#HXg?d(Q0GQIg1kYlbR9`nXrI`4tOPYG}rn_O*k2)Hkv=~yg#?Bhq+ag zbt;CP@1RN%2le4BPFTm2__l)hUnc%iU28`DK`tze>_j054kF8S$xp|scgA-#!`O4X_VdL$!(Ef7Mk z8vFKN>y8?YnCt7;8Wj+ z+M=}vWZbC^R;M%2fhfLFkI4sC@1gJ?rli6DvKDD;KS!AM$W>;iQPxz;VRVp&s{}Z- zEp)*Wd|?L~mMbWMq5ipG4FBhkL7Fxw3{sK42wqEnI`d@5jAuP)RKeo@X^HqriN|ld z48duMjHhu$d3C?@qXGGK*mXTTb;Y}94Mp3azXLl;zo;m1Y|o+L_G?9Yu5gPr0Izw| z()~}8**r_a;mhCi7hdxnt>>bT3)Fe%0AArdj|zf3mHlVeg(bE4zR@T#^M|S0rzs!% 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�`v}V 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%0Dtv1qLbZ-DT`( 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

SR})aBGz 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

rpjNt$U}5XAk3 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

aL~v=c?zj7p)r0 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

AvHtKcqcjEkh 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%0A+g7Ug#kLY)YHFQTZ*f=y| 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

l^i}W%Mny!a+*wdZRR2U=43xeWzFlV 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

    C*wX89M)C(NsE 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

    HHXOjR_H2 z{n>7`INzBA+5Cpx7#+2tsgAj?^*QiVhlZ+>!(6jQXK#9R;2X*M?A>0=;{v$EPr2=E zZrFCct20mKTEaK+lU>MLdLyX&KALyi46 zTi{Uj&>8m6vPu@K{d$RaZ=&IGGtEgDSHmJV!-hv<0N6pL^ zHdUOnYZz8NaH=sMJajN4`v0PD2@?;C{Bzy+Icwr2RVGE^`FvR7f23do1$jhr*K||h zp=sBf9lOkBeFNTHYLR+{rirG~Giy0V1m7l4S!{=gPM zPTCl|Y8qKV-g4(`Ul48U7BdL}Vs+Y);w39q?skuP`?QDk1p3i_C^a;86Ip%6)`H*D zbS)o6*^qzq`)>bWo@6Y+e+N0~?gVszj-Q9%PZaQKlTS#PfL_j|&hE;!b^WHZKG`XM zrj5JJm+Fnk?Va@}udI`i3OK+~<$Q5dg)YfNV9Fq2s_L26WzvO>TKI5GX|oHyVuyMcK6A%(On5MvLP~GTn zk>}#6RQLXeYmNe0zA{URgfM!VO6Mv|5@#V)*h z8ok(p(-y%HF?zkvbqrVc+64U&%^VKVP~jV5 zBZvU>Y35YXn``-3hb;gJA3lpdxMHjl{!y1C^qxTW<*3J;`vScD@azR^4R=IVObyt_ zXRt?Q(*-o|gAN@|+DMBc>D)W=rl_nN&kapJjd-X_eNwuODuuBok`U-?r(DGb`jOQhoP-F?RvQgcAwFekvsPdvtw75z1k=75h~UH6#ySk7&J@<3;Z-MA*1ZiM}d(JJZdVN+d;cobIQiK zmZ6w8>bl4O0T8x#1Dm8@?}QR@kM?kSgC9y;NWyc1iQA@8(%2ng0s8kFK`p(U_8Na4 z*bq*Ql&h)Xt-CMqHNMi>kq`F6o%Z*Oe#`S$u!yKohv?>Geo=(7MP9T&G7k~`(8Mz-}lp+|uWHiv)6Sk~-VhkVO&mJuI#p1>&C`GJEP(v%l*>c|% z&PAU5hy-U2z5x2YNs7#wR(9p+=HhBbDr(Qb4ssSV<48i{*-N;n0L$k4e}ZOrQRIDD zXvfLp?_ZD0)ZTh?^4{KUD`ILeyLBWsS7`RJyLyRjI@_XWetUjImqB-d!d$~#)GH76 z)S`g#m6(a6_jkm{S?U|D(*@Je^UutSkGRj7+}c8dicjCZIq;@+GiseAXW9n*CSrIw z+~ua!9FX+%TJhx|v>wN*F5{hksP+KnR2?h7!{M~zl4{+P58hvXw5T@K4eI(h_y@@d z&8%{u%K}7^kwzlAlR2zz**Indg!Hfxo-&u5<2H33x|G$MHRE>pOGMW(%OMbP9u#H& zXGAek--aHlT%lVr-RZ2ETE$Cz;ZB_5F00KBaUxr5Icj|<41TStjlrcDY74I&LIkHr zaw_h@3P8~t;|XPTscF0?_O5=!$UPi`KuwK8PJeMJmyB}i=Mg1tXTn7C zlu|=JK5!68))!8bmxu}`-4|z7_6|$jG8IW(#^do}Ao>Kr2u*x3;3y=MQ2WAAI~0`CYQ3#AZe$Nnb1iwbn7UP`PZ?S%_vWjt*eAk_)dY&ZgYI@SvpNd%X4ei{(0chMz!@4t>!Q9!l6bu zYbfN;!fyKFt^f1DsAl`|MReDuh^xDJG*kVTR;C(0mM~Y?62z^VbKhOHzpYB$F*rY0 z;k%U@)lz=i1gcdhIAHVi9?|BOh;I4J*QT~rZxDU*zOsbe^gt7X{yH!PlCkldS2+T& z_DzsI`#1iT<+b0hFQOttiSySn4nAJfYIg0hwrIh`S^Banp!1WdE8A(1z-=CO>2<*? zYSB9g;v>ULXxzNYkR+fmLyBms-$--&Y|LpN$4NUPfuV!21sr?M5VB_Jp~KO0K>=S8 zCBYM}9M>HvRc(iY13R^5z^r;o=Mc-#GplSo^?6v2UwgJf&ISK#M%KIRktznYqD(G` zDYT8fwaV92-NcaTbb6L@4xQA}YoFB4AqQRJAayE1Ng>yaK><&qs^Q_z3@lHIBhMx{ z0KX%gYQIQIE1}orfo%~fQ5{@?f2$L`C5wquwb>6O)uHLY1LS{HGA%*133aQT$)!DrlHj%Cntx&Wij0eT zU{vuTZ$~dc^l&n@|2&TzlQIz=p`tHn|2=`?^5(JT(@g|LC?V=hcc|c}_4}D|-m0?! zi?h6jtk7=%p2bAh;_$0nnj4#RWDpoHM zak}T(Oml&(nXeF}%vmvClG?*^nTPg7)NHcsGHmdelLtH(cueBO#dImzRE zV}JLm>vkT#U)pwQu?GE%p;tl^sxNzkm+g*P5{2egHk6QAaOY)GgC%kPHFeGz1mrfJ} z$iUZ=OJ=jGmQT|Wg<6E0iziC`n$1e@TmwNTZw)Gtzgv%XKFpdXw+o0%wCnN1S=y5O z=W0mx1_b4Os>bfB{ziYfp#=#=mXWF@;q5`-8NO9L6~aMU zvQg?~%-%xHk-Pw{@+n6#;B;JM6!yrmtMq%6{sSj*(%tp?bCitsnjDRq^|DIOnV_w* za}~;iu_6k-57aOp=ZAiu`%~rH!)u4~9pLm~7cFd&33cJ9t-jIcCRsN;#)ZH*8 ze4ou;(H}$}4MD$Ysr%fgR?8?)Ue}+*Un-oG=GC_pvC8?=-vJ05%23=t;dMj194xai zPSBhsei8=9_M6|CuXkHdX6_s7QHT5?=!Hxr%TEC?c7E*XirlS#s!rWa zvAFvfk%by!i(FiwfYqkni0JOre5rqXxxm~fS2I?Y>5=mQn}nXT3zTG-e<-&vfA#O~ z(+QWp8)$(Q=^Hx7PH!IN?3v5S6jSoLITSNfEGMhlHYTo(hI7%RdDr%2^A$)_H@#CF z=ucaXb2RStd@a!xU{E&HGwi$h77HcHe>>s#)?!)52hO#62I#0w?d~niPJblE;Kle9 z^|{3FCUDkjbqZl?gYnwsL3PS^9FYHo|L;j>uAi4LD_7KzvE9#@d6BMf_^m<71!QQs zr)K->U_lVbZ!3W4c&5u3T^_juACkRL7(bC+(S=10O3QsJ?WJk@erjml9O^7|C{rn= zERRpk?hE9Ly-IxzT6pWe(;Ev+G*&^@WNzuaf+sgREWka72tpGkCVE+=f;Oo}P|>XwKO#c84EDi5niF0KumF@L;RW?08I;oJTJ5XjaT&E5fC{6X$-kziz$hMnC8 z%QHL|f1FxmCPei3h@Jz8_x&IQtB zrd!oFmYCa@b34tEt9nOemmKI-&stUXkfYZrS3G{micWF=C@z{qEm#l-6mq^)^D~DM z%6cvJB|@3KEF9pFpv%i0sqt$ftx6V-V+yNH(Dyu-J9iabwR{8qjJsY*+i>RU=^XR< zZ2(s$KT#~7dHL4K!)mE^tvIMd1Q&djArvy2b$ar|#9*3C<0BcMoq`(%z4!;Qx|+Lv zx;Nvi)_;Ht6?!A9uztb{I1_Tc^NG{0=I)hzAP-A}bAM{80z>v{Jx7;?EoL3N*{My= zSlKYGRIc01l=fz&v;VXHrzUahDKZ|ssk>+B@6E^+mcW#k4%}DPydxOB2o@Fk=eWGD zT&_Kqr`jXlvQyihV|${?t1VxDSGK)5K_!|+ZcC4Cr z?NHLoIuoc+AZg+6-H%zITUpFx>(#MTr%_EClmqoGlZ0$?$e*S^3;8eDlx2v9bqh?oKbCe1$^DEZ z)d&BZ4N6DNrz)!R32nL^``37hM>JNAAfAKq5?1Vhaqc=Vr$1&8SigDvzMT}YB`v`7 zi}?T5r8rL_iutTNXRZ%?&L5b)`u%j-BT*i4!6U7DIoiG7qG)+h2t(Ez@x3L^`_G$& zZzAgr16xZukrxGg5dXTLycdnzqw+>%#RvorDg_2_?2s<)JH0`qB!2^};dVCfkS6!~0EtZAu3{|fNFkyQx*({ z;slT}V@NrXGmu)ju11fFpjaPi=b?us8iK03u`&~`Cq3uY!(44%u?jQag!0{xgKNqG zm<)ZBvfimQQPjkb?#gaJ=ggFjC{@J0!E@_9VJT3#y3KV~JHI>3Oohi|GW3*AU8PRv z0C{-Us5QH6wQNuc?2~FcdR?3-!!z^Ff$|kn+DuIS#UzYcg4Aj62*U&Fn}QbOF}zn` zelj!N5z>>Ci-3b2L#grr-%f>8qejN67mSiGAp*;8x81RU?Y#&Bzj7(Z&Xs~wfUtoo z?SIlKG8b0vgXf69`1T#k9Lhd|H0-3LUi-fuor70!;rN)MU*(*&fxi=nZbS^h^3^|0FltZSoXB*4PAMj-M?6TZL4o-_$i4E-4CgyXE!Q!q&%w;a}Dvr-3 zaaY)_mXJOqDEDsX=8~Co9_H}xUGZ0vK_f+&Hx-_g!L28H3%Z1s-qs8wmt)2JekTM? zG4}FKQcNH5r36WhA@(pNeIYj}aIJnXjmBqhD?`78`XdW;I(Kx&va`of%kT*nP6)r+C>-eW38-7o4P)uy6kcy+}^Vq4>i9Yn` zLP#)P>*$jL_~x1p)3%^v_1N*#%+(86!ATsF|C^G%3H-o&?(zo0E=(fcMtfvD>k9^g^8J(Q~go zmFnY!#I1?Rn($4st>La(vHbRtoL4dcrLy_UfGK<2EAxPQ!~0mJx-{U7?uNKLW}Sr& z57DAa2B!|;F_HSpI{QYWC*l=6hZGpO{9uzC5NI{rXT~={0*0x}?{&~#%M8L=)9x^k zUW*1FGtohm4aO9gc#8h4=q&yn*4ufECW&1;YQF?#nj=YJd=>1rVZ4(2UDZD0 z#P{uHW0036Lm6wP%noa)7Z!B8iePz0?A?>O&I0sOLI{l*$T#BcJEL8$z*kJ4JRjr@ z2ID4#H2*GFkTKimVSZ=lhYGZOq(FmP&38Ty6&PJ|-AHc-zd;6bZX^|x8a%Cz?az*h z_XQ1dI;JSr>x+Ort=T=P&%hlXzHb%&9k6Fli0?z|0U#O1Rc-379W30Ue9{9Z^=e_6 zaA#VK_{29gZ$t0f_MfPJ5{#b0;};*7J14#(Ztcxcww{3OQY3!*jKUQrTV3J!Wi4&9 zCP#L!B2B;6W3SSSFkddPLr}6zqrDQ2d=-=xaE#AiLS#y0m6xIE0O~=C(1tg{s4+)` zna}II$fGs+WdCvM3Y&;7(6@|NMnre&a_uE_LWxv>vI_?(!dk;Cr#wt&#ii`0DHo?Y zUq-tqBEm?LJl{sa4?-n|Kkc31&auY2FAW{HECV!^2TqMtG#YHqv$%*DlFQ7m-#bX$t!9- zkX!ZoO<#C^ySgh|f;5{qhCxgP7G6gPJlk~EkK9STC$9b*pW62M!zn=-(>?pw3d7L> z(GspR_|IOR_)6csG$m2(I%oXrzQHJ!X9ZC{8f&F$%75)ebOqn5|2-Tkh)E3g;T_`` z)I)Zcw>zacU}?T}kE2?#a$|&8;2?TeRt4T;i?_dm&zCrATWCiAN+uZnjx31;2t4J< znmE%?t7Rvm1qRpLLaWui7MQpWTYVt^PFhJcP_CH$a8-j5-=*IIR#6g){20zPy9GKI zJ)pbr)cvbDy*6T}RBZ5%0v!KWSo6F?vdfiF?J|K_b`?WBZ(#$z?r&*;@7C;6Q@o2n z9}CQbu=WVStD_uBA=*CjpX;VL)xoz!~{78?xeS2rH9ntM?7}u>W z8lD_G&-&^AOQ=4`LmK^kzcSTZt-|&HI;1_grt#c@9C01dN z4KH_NRbme*9}$Gw5M(+4%M~d2AL4(yAx94rtSuf_2C_~i%fYBZ_cwrb9DM*UQD32+ z4~~7i7Z-ASDn7u~`1pdi@4F?p~m&;pTTz{xVRr_maWlOjmoFm>zg)OJx z$FuI{5q>=FF70VZ2RCkSEmQBHAEDbJ(y`Fk_YETe^Oxh4PS(Ahz_T2*bJO4VtbR7L zSM){W1hMXo`O&b$qLH8uNK##^x9Dj=vzZEvbwxe275x|F!yS@t&##FCL)D%y>+61v zDn8cNy`uQ)+<*(mosOcCT0b9?v%ca*)5)EQjCi_k~e+L*G90f@ z)1Jv;{td@eb7{O>BIci`t3Xvtb5w2do8x?+qQ7o3y*}PPd_UBnF7j@JHSvT`IRxvt zUdVHI!FKq2q*{%F#^mVmzS3lvmM(p>-n}3an>|*3_uiEsiUJ?T5?BXpT&h57h-RF_ z8?RTTK2!9X5K8*Z z`oo!00sF7o72UoQw&{_X_GR3MYW{M38W|hL$L)c~ONDM?u?nl%R_h3tr8NKVeWhJk zX>xXFq&c!jPEox`@t}LgE=R#Kv_l_=-N}{zB16vyMa;FJ5ldj156Wwf800cG9Ps&y zSgMU$r|YnY@BmrA@f*AHxDaioNOkW5pH`J^S)XwQJMdIcA^>=~%~%MEAMxbTSU=Ba zWQ@u$XZm8`RkG^IIjq8`6v*PEQ9Rpi6(u z#!o>q;adm5+Z|);Q7#i~(>=BFpaze6FejEvw@fq@em-RLa>icCzz<860aV2u71D+% zqrlTD7#6m@Sw9xDuptI0}!8@~)2&f#GYE_JSOA+3UW!y-I897`w1tb%5U*r6Xkd%h^vF1$Al8j}a| z)ZRM&sT!!YxMrjIeq~}jZ>wj;)E(c_;SQNPik>c&Ao$%>J@R(9y6{yIb{k!y4w$k- zuA)$%??mB<&$1itQ{szMZpM4Bo)(`SS@is-IBUl-m8Yh*;5%22@bLMfT^dBltM3ui zKJ=hmp+a1gp(Hlmd3BwpJrk%44B`6DTkwF*#+vvJ(V>d|^p88e(OmrCuy%UU{3xb6 z0IlzHsDEr97nyIfbjKRiIa(cx>K zE{&FL{2YdorQruz$m;8pwSK(%Aqs!Fa!Y4q^vv${6Oy z*Y6KBI?F4zQ`qGR*PC{}OH_RxSf<{pTfnEG^p}$0Dt^%a91l(-D+5A{8D~7+N=3i1 zIXJ9D{QI|h&ToyML>?K( z?d2)^O$~Or^E@FDM$uv9^WZ^R&2^4-Jl>$AP15~EA3h{}1 zBm=a4d7n0PNuYw9R@*Cwj_V%BD&`7MQcp|p1y=d6uF2=`K8ZqOmY(UOseLpfSmEo1 zQn3bw`e4SalKG~M;G?D3^hf8j9tV{2(ziLc+2GCI1XEOxJmqPEpep&-H06Py(>C!` zh^I##Cqj&Fpvo0f9GvSlfThe2M-OET^L-X_BN0f{+j$M%O<`4Pd9Eqd=dw?^H z6j235ig{i>-T7LFgWv0Z^m(vhdO++#A)b^qVm#=+<39qkeSzChtKE!l&k~{ zyg6{3@tYDu=tGl0m$#Fr82f2VGwou6oI9OoQ8*s&0B_HUSos>}gB*xl{rA_{p2_Ls z2y8RJR>tLN9rU$>;C(_7w#7WBe8Z(x`{?h$uE@Bmi2Z?Mo-8GJ#&=8s-n%Cy7Oy~B zVxP%hMCGLD*9B#Pm-?yDQGL#EF3)!7>WGAL&_|ti7AUOtn$^GIBhi;YK zPQwQJs==o^^3Sd3sw3dVFz7#3vc<1_)3oXZZ`FI@045=;K*kLzu{GI}+T~S(1;a2f zl&)~ty5n{fOH>{($Y(t`1Z}==acTL9R;=`_A{}LxJ>t+)d@JSdtt;dSMh?$8~?~YL9UAtluT3UxrrCdx-r%D!xCpX3w5qeh`VIJAMIN$^23(D8VbtGCK?u3SwP2wEgb9I_Bj#i`PN0j8T_=jEA9Fr;8s< z>T#j#@AD^f%Ge4A8V@J9|2RqTW_VAMr&;DISw&dQS+Crdzl}AbC)IcxT3=%nH$4_Q z@{++Yn-3zoJt&3hJu9tj;Z|1A?M%_Iy4$tQ-IQH{1jhmFk)5W%#f0_3;C8gGmD^{S z-;w1;F@3wTKRcKY87tPK$QzKZpM?a1m4}45B*d-+*GPX3wdLk22HFxjZ(0d~)YqHs zE=d%2g~p$|>*0}-S2pT*W?@mAeR_MS@nE(;=E)8liIh(#$SR6&TOW~S=lX&$2~qpY zt%{SIMmEGpfkRK4D0%emsE~#~L#H)%&J3Sx*l?f*U*^2=AW;-YuG{G$T$|rh`Jy7j zSeV7gCI3(b@>>bP(HL9n3s)1W-!JL!f`MdmOSl|380Wwn%w_Lpoek5FL>M4^B%2Iv zobF=}l?S?z4Vx1evU9y!GE3Bf)7AjesS5)Kq;J0~RKh=?eU&>~n)pLI{a`;H_?l~B z%H@A2tY16I=>6$dp68f%rMN2p_)XESNRm=KgA&R)x!r1{kK0E?JwfUVr}`_H5rnF3 z1T{88nj=1G1=#H_?O1^%OI9c+0DRgtP^qWWeiL0)Xu5~B<7(m1AN?%lXPr|WiFb)x zBJA^|v8BjZiEO*ht=pk|m?0xR@>2TOrZ~VP2@$tF(o|FIQBdC%CHP6<_SzRU@}`5> zfD<9pb6y$%q{KLs@eB(!N{d(_8}K8x^v-@Dh^!d#ncmU#0#Gz?%iS|g|I%acFx-sn zl+{~LvOtgN4c;4VeyDqdr30&bI)$r7*2H7o5Qd1sXGpGdYIoV|{tW`ql6^Tx${@vil7tKZ0XC8BbDa8FMOVB-Bw|{@xiD}wU zA&@HL5HQJY;RI3P>zOB+!%ptS+Gu3#-LQt?4Q3Un6JY_gi*tuEScUuhg-@+}bR`r> z)&)UdV>cS`myv?0k+T{SUmXHT&P{i&Xe3lHZvimflG!EZ(uc44wwgkQw;UuW9kaJe zv`E*jb6LSQnNJ=IHG}*t$~DPq@~6I9F$Dmb4d^EiS;CMb2Q8-bK2ve6g_tp$3MV0} z4Q}II3FU41r%~Do5x*pS>RKNtX{4Fn_^34nO$7(<hr=5UoxA{kRV#rC8_e;^yMS!-qK4>pZU*2 zj}$6STwdYIs>M@>CPt=3n%v9`J+i$(ucaI>ZIqojsmHDsC`D9TTj6i`pRnV~K}r+} zxCznc`@@z~J5c}eXko33i@JNLj-eH@BXyNwgJVBCDPKbuYQ{Q4)!iP7(pJ_Z<>?B9 zcuA;zK9}{>YR-nab*e(^LtA#Bknq_+Fq+Ayks)i*Z zWO(HdMJsAIF3&A>v!U(Vdr1mZc{(9j>MX#BI+HIOCvLOdUSA?7Z}XC)>yFn)oT#Kb3NsJkGMks&LlRwLvcdZ|m zXc?PZ44xqRNOCe?^xpp&$w%F+fia}K%Ct%4z@Y5|!J)!*BTOwO<>K*@wY{}(w1Vh@ zoJ?S{fyF##g(Cl}X4~)1w1T_eKbf+&3oJ^igSDK2f9opjV=OlNc%e?ld#@Wlj)@JX z$?uflS5a1VZLDb>3=#}K z6Axbx27Oa!Swu|UQnGMRavxAT}MjX$o+I! z{T9YqG&KpCy*kzi7gAspm+?}_rc|CsJ?sEp6K&yRzl*6Qch98VX&jC%OE)(2DY0pB zL89`nTdnzc&+{5p=++f89mLreGT_PR;2EKTt1tLGH~T|UOFXB8A7l~@gK3{SUyv0j z@ziZIi=vNpirLg&_6R%QmVB`1WY(a!+2Q>fTzQaJhyJC9A_|F|)v^tNQWrMiG=aGn z7{>vv_7+3blF)~I8R&&@yCjDy{X+`R{LAznelWEyW$uObw)>ZsFf`rqlMblF~Qfd-%XXobi(RK)NoL7xnT<8MTPaTWZ zb~)HjkGGi*$pBWqgekFH>HLX#v-M|}lpHVAlVARST1k+@(bV9H>-{>co%&_&`B27A zLWKVM%He9$)d6;APtv1L7`su+!$^X z4)8j8N2~YX?F+-#HzhIc-s#YORL%*{)$_S%sq5ekQ{ux5D?RNIb#{F{od_x?Pv9@Ui`&-N8Hp8RvLH(DQd<6TZ5gQdHC zR>a+$7MGP#0i?qrXAOYRug%VW5}J51%1nSp;m{8((yaI#m2ip&yVL4f@{=H=85%37 zrKUbDx{mKU{v-42SXFs#ES$rnBWSD9oorhS8a}4HOrR`TY^GyB|D5ANc6Pt4Xt9rV zkvx8^Aqhc0XMI^R#>Y+3k&8W_gY8bWcQ^ggC)tI$XNL(KZx_UR7a+G)2s%#wI_kK{ zyM6XQf41Vzqz!5lA39dxkRF%>@IqGu{bAusenhzyaj{6D+ombf?QR;M+3Y%m9vq$+ z-wh~Ki8rRdv{`#7P<$BBS25(DRLH-1cDsJ?m6LlbzV%$V-MN9lAF6o`OHrnpxe|xn zY%x;ehu6u`zr?SPJE11h4py9dd%mu zI=pS@;MnOtiuNIJAtA*BdrHntfrK>q6UDI$@{X(xkxkl!H@Syf3$Y!seM?5mjP5}1 zF=eVlv=-U9jP`Cu@SIsW+PT2@hY)4F+2CD1FRxg;TovwDmf{Q7i?Rx%D;?uxSqa3* zGzSroh0MYOXGvHg1Uqqm@AJS9)i<;O!Hl9B+@Ja%63@RWZRosWw&E%1g)@dF#S05b zjU7_zZ3#`k)u>h;Yi8R;KM(tygvY*yF+rI z_WcbAav%&%0m%l%z{pq?i6=yyb8gT?D`07B-j?y$a!G<3tPt2$+0$61>4{o6J#^9$ z;gc%b^Njwh3OXm}mMOF@F^vN^~RirS081Y7TX7zQrX&zJZ$WTqrfodQFdI@Cdf zgUyBT)x4b+PqyHN)9o$oLVpwkRTgQVz~W|i{XtQi2Z+N?CF={I-aG$?r}vC&GV8*< zK@f0|CL@TH;4lKC6a@@D0Sm~W#4?H~MWss#NN)*6M5HPzQUfBQq9DB!dg!4;D4`QV zO9%-eA?3Y&&U?-`etaOw9rj*(U)NgKKV9>o(yo{G-ZrPs7 zJKDVvUF5mD+xWqY24MBjZImwasY|1v{tqA{9vc^g(sPDQh&RivvRvd~;tUV+UZcOb z9ers?TDj<;ptTFB|Bz#ct(urDNnfg6fmTTPr}7-91D3bqw(X5wKrYQDnTe}|r#ypR zb+!+?pLY8nXN2@SWt@)Kl}7p=m-A2wqbBEB8S9fh7h3Ly3X2KYKUVw`R1!A1+qyf> z4a^vg_YsIVhIyAema(Zgt3O{i2bcO|vAD+4T}jn$R9&Sb{!ire_Qtjpa~^9|97Em8 z*lUa5^_nS>QdzuaDgW>@MdeNK;-isvbZwujdULu$(r9>9?vLT9 zEB8?X5-GZw%=qkou|1ONAu%gaH3ns}84Ip8muo$RVZV%rGl|&n#ecJ$-{vY5rrm}v zU-F-CqZfTzPl(&hT>XIA%dED!S|C~PpE-wAWFUpK+V3?7cY#32jvpM8#(LBh`r{An zpCv)88y)KqIp@IP^zwyONW2FqLz_^UM z*jri_#o73SC{5DIKG(VL=PR4WCI7Q$92i`db~F83rthwS-L%kOMK!4(5|`1(S*>3w z&e}N3008Vdr&6RBK)_zBGGx9<@8?m-Jm^X1d>>tzDZHg`Yr+^ygIF3qKF@q7h5yXA zDzakirJ!^!)H6ynB6)aR`7$w9D_?edJs0*0EdI8NQxr_wx>K|G^=@!(4`k+su{KJDT>(pcMVXKN?2~oJ%dywPDNbANTD7va*J4MG_$*| zDrw~SC$6(qS|t&_8cnii6pjl25?6$2O$kNUh-lw*&y8xFk;YdH4oeEoTDH$ORjZ?2 z^~OmikQLbTRP~6VBCYZWnu}43He*!RX2OFO(#;pw%#$&m&J`UNppJLNQH>J*6;-?{ z*|K>86|r~*64FjTuE_|U_|p2Nd7^CkV>|c|3-o(8)Pr>U#B$#wo2^TLB$4)lpMB|` zy*nq;HQ1AHFJ8|QH}@v?mJgH?G8E>BcUg-DO{X`{Ei3v^{QegCZ=To~`Zd3PufG=5DNRyZ9S5oRbb;{to?#W`39QO5bm8RJWV?z{Q76gm|x} z!&vWAB4$(Vpjy*&B;?~nVgF+_2#ofvpzw3dUlLT}+4&oiR?e5v24_kSs8bbMB8(4A z9_C4R7T50R>MT~^9pJE(OFLWNmsW)t?B19sGZsDX=e!h4fh>M2q6*Km89dVqiUytS zn7qUrh>n*$P7a$gU;t@Ksg)zNFv&5$g(jB9g*8ZJot*iD% zhd(sQiMhg7w7*}FGM(*KXA_I}v>!%=yY(hWA*za2-e|xA%bfJv6X1pDG3$Ct)zF-P zk*!-m=UpUDFAm)oEC|cFhJDa$-g~u3us>cXKK4 zT1)rQ4_Z{sSK}QP`z5`$W0F2rP(0oz$-O@Yk@rwx0eNM!Sb1kjLCmUs1P=oT)7cQ* zeHs_MKzLe2b_uf_G~K!mE#^M|{3GS{4YA5?^J`@a`IoZ+o#XQBX0m5;sZwpKtSNOu z@fOBiY5h0$8S^q#bbR$Hnb9&Uu`IZB{wMDdO~t{J-o8q^4-i00bxnfdrjwz%@oTYC zA6dE&R@U4EQvLj!C;#xgXL>gA_v}CZ@GX#B)uajFOYBr4`UH*@{bL9tT$YZo=*z!! zyZWEK-_Zig%mIK`x@(>+XBsRQ5D>44aM*WtsHP_ZEn4I%w@&>P)qLTF`e)ipyCQMz zR3Nd`iG=3Txy=9}ozBGrZ-9z`DHxk*STpu38h{I{paRa; zG{hKNo}lRktuK792^9J-8R@|WtF^@q>5VIA!yKsB9CWg=%3c)nhUfd)N@}^IjNjXJ z*v1ynBToP*19SvjEqbWV!gTObJ@vqq(~rU()|VdEHx(IgySw(HG}gqq?3R^;99Aip zhTi|3zaIc_Rl4Ie%`>hN#K7G zgdl|LR08x=6REjD`qA`_sU7<*YOeD|zMGZVPCrG5Nfq#&MSdTzEuo%>L$8_-I!l8_ z+0CYs&EyJzGP~dGHk=<=wDUiF&W*pv;+b<|uT^5ec{^j1nm~|+SkAdDyJg9CyJD{uVy!QYJL%x-_}ma(e;EO5t8) zmijB(LGtwi{LlEm0@vGJSzlGrf59uadcwNyb9`~*qO@{Fk|O=)jn#DXM@UKK97hZNo`rpLF>K- z)+csR25Qr`XPa%bLomposlg7k*?vvdVCEHb z5aG^X*S!FGzbnKqaXD$xhfHmp-uZ&+Ob=iG=HS@+`*r*h1vds=@QBbKTa*Hk4lj)5 z`I1{QvuVOQUH?Hx<|@uoC}L_QWZ6nT$K0FqRK2+M{JDF^!GWdd@W}?eaWBTI!rghL zbis8?zly4)8Qdx?fCf*LpRXiu>DQevc6AiX(%oq!MUZ5-TiQesz)WRSyGLGV;gvwk zl#S%ULjC`Cf0Nh?M98k=cCQI@!w&|*QvLUysmxRkr%wd?b)HO- zmlaw|T1#R5xo6S1&;_0A-+SOr+{`QQUp;27ihqw!t2roG4;+-$^f#p)6a15;D0eHF zX&F)2w`Yq8>9s~~>dX6cIdn9V^4?>p*ZYmRU~Wbf7EPyA zpA{9MX9G9SY?CZ)IS*mQ?9*1qRhl-(w93L4g&p*QamTf86R!HsX1X;H6nUvxdCxx@ z74-OWX%1XkS;m4FR5B<*bK}H{Pku~uYIgA!0h%v!BY80nZygXQgzx-wWqCU4z(2dn2=XoMGV9*e? zr@0TOTY(qfYI4;`$kJ6ydzkhonY{LyHpVK4fr^5jtfQWyCr$zIZxx;|f0Q;3lbcsL)QYcNrCO4#$o zcirV+LB7wO){p~pUP|rIW8s}DXJC$Bj+v{@w7F2;^2rlir?zv7`{}(ca8_J3FR+wr z2qzfA^_L5#c)ozZThD9TYI`~Izkca`u{-t1wdH)1S6@;xWXj@cHFq$m*)K6D{Lf_x zeXE7_(|J&4DJUQ575P)|zgC9@!^&TEUeZkxe>I2xEn?vL)|ec1+M1y%#rMc3ku+@S zv*L+P+L~nYs?|Y~!wg}qP zI9I!pU*S<=AECIrd+l)0kn|874S|4>2tOMiBsL5Ys@CY?*EQ~yiq`DC-r%!oF1AzT z)fYfvk=-M6#({+CavAoQuw~xIkCrOUeOU%THzM{_QI6rCkF}%ho;A=!w7uw6UjAPE zxT#CkG6eh~o}P@Do_&$hCK_{4P@MAS<$Y%%xb@}wTa9Z0T_a4(IAAQi(9rqLed(|B zclVcslZtC*pZA?291OFJ5sK{LtomikrB;~l*YmcwlN`wmj?t;Zaswi@HRd?0UP61G-!5zD$= z4`a#{WpK)%DD@@!Z#q0_Obabpy5;{;^x1x%1NvT73i0HHzSz(<=w zQUUf)uPQuOdIdSg9+Q}3!3`MH5US^0yMT&GRsRnSVu09HRJ_|mcQYW=6+7|+LgzUOsp2;rw= z7CxG!>V_`ypw8pWJ4D$&YU=;m9E7zB+v|ZP*Tj9juhI5%5;nAt7_? zYQzzPT1T5#x1?4hw%%{X2fB0UZR^jf@ct*{#WSPxsve;)#LoG_`6ofw3re4;^nJb~`^)69 z>FnRX5KdVo;SB=C>>qbF;lvjuRFD)*JyKSf2GB6AlaF*&MhP=!r#FF*py_SnY?>PL%XI555 z&7TsM+^E>6_>6%b4&N1xgpxgvk0ObO@{q^rT?+7*rPvUiq+F!VPwM(d0TK324 z^z{I?WUijV6pr|N6K^!(6FJ(RkHqO+urLpzmI1M_Zr`v(Wg zTB1LGv5b3Oc@#1Q(ung-JUYz_jn$y@QTO^Z01FC7L!;zWe5I}UaB`ws$}?UZ4E6*@ z!EPz(s1)7n@9^zO#P%u4#G{_~PO~Vw+;|O0@Q0mIAC_?z1q1-CF|)U2gYw8%K+GW- zq>SDE0|!W7(ppJ$j0wxBUZ-TjAv49$Xk<#~u%Y)m%Rke8G%i&m$;<0UhUN6w0_mHW zpV{W|a7z!7+@xiuEYXDB;ke`aIX>$uNENi!QFb9m>13yZ~5P=B^hvS6~ zF9{WLr}>zL)e`TN+}?EdSj%e5c@4saQTi&yd;a?i8GHqhMc-R`Zs0#}9O#W(3Hd($ z?8gd!*15^D%6=qH@c(3NIPKG!kKMhkt6??Ls2GzzYG8$JJe(sbh-O~%kv!OD>BIEX zb6%nKJa>KW3`KQ9g^>WFZvKLmMb_sTxjXQ@_+eY~C1T+C<}^pYzS9??-yl_tpqeB7 z)$E5$j|NF9gIv$8k5|y0TV>AF@`y)mW?HTyfn)iRuLp zn|a_iEHG|o;Pymo&T}s~GF3X{Mfqki^&jSTmUq4TRAHw{LS04fNR}QW5*8C;HNWVT zu3WZ7u>(5$e^~|!u1h9)dR^U_5@W!!Ml&c0ql3+yO*EpiA!O-CFqOa35bU4I{_IF~ zX&7r(=Xn;Ryg6cr5p+#)#;9Nx^<8VIuGtkW`DmRIVBj>VK%t5^pwr5f9Y+`s1RWfc z3wHbN5#TyIVO?K&RJaCb%6?^J&g;w*J4e4EN|D_>I19NpO>jC;pJCA}&Q|U>yj$F9 zAjv~|kqk|)^SgogN1PY2{|GxG7d2V2t=Rb0ZQZE17c-XC{eMy?uN>`q!oDzvvqfw^ znl}LFR`Rl}7RaZsV>j{az${p#$Fn3Oa4N znoOTDhwnZ3FNq-cYzFwpt}s)GpwsekiK$+fn%$5~ zE{D%r=k(~mfi&%;QHM>()hw^Oh`|3iI_n{;bqM@TkZ1E(B$&h~109wPLlffSR30ia zUYt*=m~k))RATk7Ys$-AR3Th33@>Vm?o#G>JF3qWE-$T>_d2$}AhABwG&&!Mh(61- zKC+h!XHUT8fm_m?5o~VU{3;5#NnvU0_7QuxJ$oN{03rPIMl8z+ZGBG-8H@uESD)xR z+h~#%H4(e` znuwX2q*&fYTT^;$CrR1`y4NL%nKlzJT&RR@+Bh^%^(5>!uN7*_qKLOeD=WA6L_7PxvH728v6lo!4c&%sl_=qAO-98Cu(6)$4FhfNKc zG2Nn^UuS?3jK$Af<{F%{rY-xf*DNIx(ZWZYj$T-kly>X&cusUG;Pk!xI`FSM(P|x6 zRXk*NU@Ikzka|GHN*z@z=YM}GVuJoJOmoMz!5=zP7-(KPZEQf12W{<`iRTQ^o=CJ^ zwpy+|x=Vc&@yjCwz$wo%QMYLM!^KvW>7xD*UXk6km$%xF;gZCW&&REd({OrVW?!eq zdzei{pHswzjC0c2JG;APc}G8UsXzdW8$rrejrB;aeCS}3%X9z zWWMSreneF%LWuXUTHJ7;9(7sMAT=0bJMrVBer-x!{H4gQ)tn|3BA%uF}8 zM-bij=&;Kd@w(>4)R9NNiVJYg09wDx&(9^K7#*T?opt=ZUOC?Q^IfTzM-8 zm8lAWLEsO55r%%mev;qkc*b#l)dhjLKuQJhP!d{00o_#d<%s4L;wc}I`WBwBZ;cY~ z+MnExt@vzQEumxRLM=zNx0?1uMO}&8Tm3J&r(&`yXKdF(QTEQj8#OpX|3S;;$XYx81WT!QJu-3=&i+{@QTc(m z#U-mIi;mdQY=(`ClmZ^}_Pv~jatT~k;xci&05@Fq*yu{YSzub$cP)%XejeK2#)FXR zRy+PxGVsYRsn~(__DQ-`O4U~&s?B>9z2WPMx?e2k^l=l4-y`Bd$jwI|M(=~pyOVyQ zUN(3Sb63;hR(~kCC|N)q`A9fy$j-+p`x>>kwiP#&M}+gg7ik}{($%)7ovVDZ>%iSa z%Ky$RPy<)zIhQ|@wS>-ixj!wFtN}+ie%l}KbKP%d&!D}+`LeyMw@seBvkMQc5;qZx z92g)f2T8r8IRFuwP%ZFOudbFF)NT9R4}*u&1{-2GQzPzdm9neQVCG4$A%5MwVhvy7 z`J89)NR7_e^OeCH1Hw$FbSb-Pn!XnF6SQHQi)GT*Vn)A8b%&2^jeWc8iUU`T)P&x~ zZggK3KTS(J{D$wUtFJh-aq|l5k86VeVGmag(`#|w=Y%s?icy!%GuzLBT@LG-3wD}lEpj72M850?LD?<*MbJ+NxD3jGD+|5tAE!2?v4oE0O}S*g42 z3(Oq4Q=+@ph5t}F8G$VD`473S8IWB7&ZV5RCW&aky<4Pe~-t0UPjVB8-hcZ(Pb9QlD3D{hvp6YYsJ3fa(zbdl5`t~_h^9dLgcjzkvkF)`LAIR z86yWnJ(jDv7=x-GQ!#gK$X&9l|7Fk$@6rXPoGEwZj*JU#v}b}0r&^VVR6$&*!ulX} z85bN0vXv&kqyqdDdWx?ta*h0oadAGuE)#?iL{J+5WaI+xkQD^GauX8D667v`5-Apz zVr>QOg?R3EH5W+@MFv051p-#?Cmytkt`HvOSDW10lO`cx-Ye(ndGh=zMxHMOs7wV}1zCLx(1Hg$p;npB{m%Rh17*+In=SD|m47K82S?xV z1a`O0{SrH64JWIK@MvF&B|>9Vlx35!NR@S(gB(@fB)Nzn;bZfH{sTMtRUTwW2y zk&U%OV1U4sk5gdYGA}EuqRm%J0A$YJWaD4mafyeK_8(K~%Ttfh%Pv zQ_r@n08(A~0{+W+qt%?gY{;tmP1W4wb;%)F_5j>|h?I>~ge*aEtxAIjjWQ#C)!TTz z5?I;76FF$W#@M>pcd_GhF-iEzW)mPa8>4vma?)(*w{1oOD2Yvui4}_j+s;l#9Wd}; z!lA&06Y6w5F#Ms(^T?}NHRL;tRou&^b9>nec6Lux;*$h>do>DYgqUGS5=jL8ioJC0 z3y)Rh?#A0@qJxWFDHF)kL+)yFI!}>24Txzl;Jp2jW;}TmHIkJNRLM0U_|UMgS=tg5 zpf__n@XDtR>E@Ul+}~-5x8dMeHP1mUxn_Pbm?-K?M8D(I7e1rSBTUmQsJ6MY-(L!D z4)3oSMYuVLo^IM&)lJsD+SEiE5^1EKB?UHbTxR`DAe~tO!gFhjKlm z80jx#YDKjxaSVm9qW%l6O0P&VIqSvPjEOI3d#|$@OX^L!VZcZtF{wD*I&kT6+7&IP zPNgnu;-XRL`j1eX<${zChx!A0-b%92WxeU}3!Hd91hbFgZ0;7hUMr2+;W2XGbs~Bsp^c7T$9kMh-cp`{kqK??UEBS{gNcaSuH zkmUFYFKfCRpX^#WE;yBpeX^{`8=MUcn#hG9d$;`Ilw+-GH3Ue~3S#o{oKStBUar*x zU;h|tl^udO@~^{<$2?81ED2ICy!iEH2q%MwfQ%o0{WF;{hT@`(0#Q3Dyxz_M8^b*S zVX~x^6*=p2DbkJPYs*Oh!SLbVa<=}< z;H=#0niKw(*Q!3#okVFeu(p@9hF{u11ArFpXHVFVcR30blJ$HLk(1Y9u*J7DnELuT8{Yj^O&Nb)yez2H*|?6*^O<6q(%=?^XT?9=D77w zxZ|7APZx|iS;#$jSN>0@Y0+T=oY3?{Z^5$u%8P!|`pd;-l2*jU<$?Jc ziIpTjmfXULA`(F?!*y|UJ5VdK>PA-C!&%$pjZ^Tzi+wybx?#8kP4#t6uUii%I{@O~ zkUKt7MZD&wgAwkWt_?+`V|h=Ey9kwAEpTO2c!Z<~sB9w5M`tWFPXA7+9h++XzfzV2 zFyjtLS?G5_wK|(EQuM%+-)7-|YTA*J#uk*)htXEv#aBKLo_nsK%SN>~^)RDJ@r=sf5 zeEf;SZ9ffug!klV7&pMA_1~($7`14LTAO-qr2YUWq-F6uv`?j0ts_G(eDRy?OO4;7 zE=_&XO@kNqa+YgIi#Q?5F%4O5fN?wgX4#`0lTj`4f-ssJ*q+KQvwXNOj9L~%)(;I+$m+Q#=)8?8lSnu1L z_Tx)MP7Jvo>nZX?F2h+#7o{HLX^7abPB+t!zx6ZJ;rvGEwCKI4xh5~1bbu3oilq$h zZ{cEt0<)pz&*#WDQI~}i@h|dV5s5cTB=s5vT-Y^_zo3@x4x(O;#trQMOa||l6S*BH z(e9vP+a<P6(@qD zd1Qa65y$`92IRunFo&usZgDy^i2I!YaXpYO#8OA?m<7v#S>@i=5b6#~x2tA;440_a zE@5g)!AT%~r{4h#*9{xwvG=KQkvG3>PTR3P&u(Sd0mZPHDa~DSkXw#s4gUiJa#AI?MM~qUMiJyHn?MC>%&JrU^ zK<>Fsml%@JUCDx+!}&X2_}XWVYhhM!etjpWesh(F>p`ITgHE)6?Z#~`6!`6ssQ|n( zOFEG+sL%8S%ax1F<$lsmSF#Vb^gEk!h!=W>=m%wpea7Ye?OMIu{5)0mRl7DQQiF1a z+>KJ!ZeW>n*Fho?_c<#z-{e<=v^nx;={p3R9hdubh^-Ijm)O5(N$_RUV5goVDKLod z#cpVi&o|k&|FfRcWE5t$ftJOxlMJ=4&FJfV#ik6Pz^baW0RhAwDS)GVe&73n)d@ZW z3(X3pzmqH4T6@a=$=-Y5L)X_6Rs#|r-@J5HTHi!-HZjr3u^e#pr`xoJ496~s-u!5l zn;(ypr-ha-`2L|Ev)Fo8HvHFORl`2^o0rln$2qf9VD9}^j_TglgOd8G2~54}!o8q* zlWHCf9n*)>0=WiT9Yy?BbL7hW(c)5j`x@v^Ya`wIo6(n8)FP6t6sg4E{E3pIPlVg0 z1R8sm26)TMgy92;+|q{}m2TyCurwXt2j!v9z8i%CGlmTyMWbFWXdDwI}$n}um+QQ`0KmEM#?8`t?h-BBp>Im ztR0%t4A4;SZ0}Pz(+ivQhiKM*347)XS6ctARGtDRmh#1txI*W+yWhNn*xZez9rdZH z14#SQGedtU){*|rQ*%IjZbJN9d=h8uN0L%mhzrJ1*5(;1eFE& zh;Yf&+KoCO>$T^K7k?}I*QU8FRHjrictxkhr5p&y)emgbAOr_jIp}%u%LvMSer}?e z^^AeO!w-Z@&bcrwWmEGIb_uw9yR-ddOaB3%)a>mgH%(9SzYY4%p)*FJb)m-O)MW3+x6Pon9?5XbI0^G7OY3eC0F zn^^5oPxx9xQk(#UyMkh+-G(j=W)xd_JUE%xL(KH-NYhPSw|SDfvzU#STpwj zFL8m~G_H`r&ct&-lb${6z<^8LGxq!KE$30^&BO)QzGQiy7QU_@D)%<~ZMLFSkDLnr zUZc4G+bN`HBkd<#UikV*`01VZrQxeSM*5ag0pzTltn~sVAU#mVh0U_)>(eya1`^S0YO;Tn z-`aXn9gpHBm)lTS1oUIlwY~>Wl)908Z`k{W6Ozk4aMUcJJ?n6NYMW^&vHyf~ezCc0?+P9H(<&-bX34|iKv-Fu9BeojLDqF-P}&Id*i!Px?tnB`z04@L;@d9k{OJk&q2Gg@c&grcDz)7iQ@?!@UYj0{1YQ>Gb*V+YPx;o z=I%jW)5tuFerLDqp2{HOAHeRY4AjZPG7GmbFM&v9;KSJ(S0xHd@l^lWq;_&BBif%s=>R=S`l46^XT$S z<+?j3+*W02@lD3f^OA$aR+Akl-D zEuGN*l-9SJf-=I<5dJi-$>9VzF+lW0x#gaM?}2&Hhw};zr$@|DFPC-qWcx{SKc+QY zv3noWz3J!CkZ!Y7zC4yIyD;PxYr?wORevZ7)og>h`GLpIK)OqpZ5_8BqmN3;12OYK zrxC9ie>>c>N#q+y8UA+M13zFU9?CEtvGrMgqvqsCL?adi5s&3kiFqsEoEt*`CjIj@ zsQ+plU|k({9=s7;*nEmP*i|~`7y8SWlfvDFDlEe&XJ-_je@0n0ac8`^-0Sx^7hFR7 zwNbQwZS7Q;riu!wIgCy1YVTf__$%Q5mHCv^c&KU?(5EJNa#O;xu@X4Dp8yueDkkSK@q2AD6{=pmJw1x3(NqYWpJsMT^kevN{QW^I(c3JeK9!ur z-wmK$NPgds*%QFZ-=e&OhUY^qrO^qGZ_h-(M~ta>hV$v?^b1dH_yk^mUsY>$wU7_s zs!9fwHa}9V;Mv(00y3neaXmE}s6Tey_56Ws?On+nHkIg=)2Hbm&HdcIdH}G8+R2v-Q|{&0{}WA2jijJ9&pFfoSNtGI9+NsXUZwvOW_OV9z2Wdl9pm` zx@;Ee;z;53+DQTmiSrVxx$Nurl&GM_&{;b!3U9X&V|=KSZBStXl-5sH7na*d<>LHC z?YE_O#$|^Pp4pps|JNy%qzK2COCD@Uac-M%>LNaA&%Dub6wR0xqQs}ifTLYx-X2Sd zd8|&Tm(bxBWr7FSy!ay~gCZtRS(>LF)1&%Jw}@ky2v@4ywWKN> zpCGR_O|dVTIpNW3V4MN{aW{2>*8BVh`} z$m4r^uV#lq&h;z`<~TA0uNQOxbWHY67k-=x{kra#(^>@VY2d+uO==EDsrvxOtG67C z3VyGmiVU~b*Ok?C(-l=wk)zQ_oH?}YrU;mtc#I{ucYe=tSwHfTzUPaAVLzI%=CmJf z7UNLYDB&bGiQ1L%e$f2osZzJfcX``mC>Spl6?_&AkxnkBoax@mMPE2PF+$!oOJ!WA z43>)s{2%!XXdV%>8<$pWw*gv4<_UPwyG#F1zHXH8KlP|dy!N*g_DLtMD5P9s40R(* z@6ai$$4@x)ChNK0^TD-Sr!iO8-*yd`Nv!-`7GJ@Y`W4AvnxrUt+O;POr2m*=rkS~+ zgII49S?b9zm+KTF?-(&CWwP2{KB&cANM?Vr2b9Ar(MiVDEdYfMW) zpLY=v`;`!2=4Blykp?U}mouND8>3eacvSVw?f>~u!Fx-ieV`+KaZ;-O^RCmg?IBx^ zlb!Jgf5T)=0Y)eK!4#;$7Aj0%iX|jqT!kkLt_=URx-@blrJ-h=^R(e&-fxRo7}; zNJ2F{xLvmE#iAHzL8;GdX4}>0rpAhw(sj;;qau*YuSGXY z04z*^hY$dr`KM7oN5f7E25)BE1RAg(n4nkF2*JPGMrnoi>-V`o(Am1tiOYxMV&OE^ zN{RpGgrkhA#HdNjQZ|Xj5D|h%uar)upnvj_gYKDF0R&ET=0aCUSDf8+-ioejacue? zFH4=D2=J=@LBXT~*IQ@q;iq&27M*>~6jBo}`%;g&gnelThrGLT+E#eM>cn0G`A)T@ z9#mw=gPpE>8DK@$4oP`GV4X}z+WObPXj0(*%uk5!t}N%HpcwV>sPf0H>A9Az-PWbc&Eb0S{)t;+40SS?JXe>iS35e<=!sb zHi7jGY79=7?_x~A8Ed;4c(6{*He$yx{EKzyq-`MGZH8xDRIL_GYJ#S%W5gAHk_-e) zLGRTn3Z`!be*QILRN)%&ZD?=bY{(S#GVA2a4=g`u(gzL{zjmg}fL$H~ZN8xh+s~5A zrLB5!>NGR-?OF5{^wR6TE~A}$rJ>_MugF&|>2Klx<~R1*he@T|&+=9B%#ywMn^x7~ zGI3fAz}`pbTQ)aou_i-+$ zbae-+X|0en1;{~mZ_(oO%X*GrCp{MkuW!3ni1(T94$UH^2tuW&p?1ZUc2lCHt(*sdmaY`|CGjF< zpG1XlhR@vqKZ#u1QXSCSnMa489yAk=i%$d6m6p%mZ04ex4t@63{}FCNXUN@di#+aQ ztYjl`Yq;;MU~43A#|wSJxjyvD#LxNw^{PfD)Bc+J$BN%qBuL>1cTlK}cdbZ^1r)f&lR0BHkIh5~hlX%;H= zBNa?b?ACXU#ad~pG2X(4i#@bkPOa@J55pRIuZ|rX#vpejyL!%viKc|FC<&@N1DP=R zhR2Nmj=3#kF6H`d8OW&pK|YCC(v1f$1FZyPZW<#;k8bxqu>yecVFrvELK!yig=X!l?dn67-YOX9)mJacI@sa=Ty+$aYH6)_I{~@NVNlo(;4=f zuIehEGfBt=au`fV;*7Kb2T!r^1wO~EEa}v#v8V6BZQ#go9+*ENRn+GZ&ohOi*kI=W zq$yEv-GZiPe#x9Q^J zy`iYL>P=w8C+O(=z{Bl6*MHO7wHJQLLJP=i^Jf8!2TG*7itY5Xu}=g2)N{XfEojmq zh;1Q1^(uw0iOB~F9{-sB(Ha=8iWm=8TKC^Rf!JPL%Yx$?0&FV9Uayfar z(2Hp5w~m4s7>zJrP{EoVtkk?vRJUf%>e5sC5LgdLslvg-cOjY6yZd$B@T+U-xmPOP z5sW=3ch6BtHKW51S@QGmnf|c!k{%Ku1QZf{_nH9LXwGE6C)w{|KzZl;9m#Tt2*AE% ze|flE%O}6K!&IkrHV;b_@Y+ry8%m%btl9P6O4r#{#FduUF>-(fKChd5_I!-Og9oCo zAk#c{sXN4fa(;;7Phr?yGVH`k=Y{yF19XmPZx7J z?^sfjV(F)_Sl~&y<)>J&{?+^--S1A$(L&B`+UrVr-~8j|M%b^j(%CCBD3hHMZjFS~ zWwzZs%?@~aO)iFvMSKb}e7quU_Hf@gAS&H!{7rnxQ8Jf6;LMi^sc!e4Cp9#x?>lsv z4W&om(vt*VZCsXvWofSPj1TXJI%#m<`JSs6ya04?0cot)+|t~IeX-#a6&T=vX6MsN ziLY2)Y^B`*sn36*yA1Wh;f$M~Xo8(|S`+r58XflzdJqGh4cp$d*JiB^dgE=&rt;!m z`PWuBw`&G!mB8d}I%tuWpiuJNi-t~py%y3Y;IG+KhHkW)=R^Nt(UouJ7c<|-@04`< z-;xHavb%rIzYX0@aL@r)xw6-@O8gETd?#SqL-P1775wWxcVl)sY`g4t@~Dr)^!2HH zWO4K6WmUs3X@Gs#F;YslgkN!zcAh%Xe5yN(eQ!EZTJ*3=qC?ZGQod3{8mQE*=RV7b0v$w2U}YV8>r|F+SjxKH zbu}Cu5z~+pzAn|0R4N5JAG4#cmwnXbF!OHn%2`br_`hN2lS|2h`=!lobXimUUl3B` zB~b1KI(#D$WYA5Wo@@>T{E~u?6~TtV`&GbvG5#`LEvU0|nWPH%^B)jx*Iz6%OlwmhY7rguCOCz=| z9w(;m!=T8%UAK@XFVW?7D38?41&j8P<|>#X1y{&j(D$TW5%(igYkOxPfDS?{NN=VV zE=RU_8dn~i3P(KK$9l?qA?^vCTFvrbkt`x9HHo%#YLyAb`EMX?xUe6PjC8AgclCZC^Yu%Fh~uvByqfaXn_Y;LbBb zS}9*1X^EK@A=fEI>jiV6*St(m`;`9X?p^85K9lW)x(-^P+y$=VYzCM2+@Z-=#(Qjk zF0q0^07r{Djf81Yh6DJ6FlM)MzFU=h0PPIbQEg%o)15(o@dLEIoA*jsGAh%n1FM0X z%=Ha!?vtVb#alHB_?tHxV;9V$)s6H-j8T;_LFNcw@thk+!aw!AXsdC_QFD)kw?!); zltIC|yFF-El#vj;w)YRb*~fXIatVHN688E7&OPPksu-WN(HC8xnbWIY3BZ-Vc1SE@ z-lyilsvBcP~w_!I{aR!j{t&UU>HF zi3}p9+hWoOWYD<1HtA-cF(sQw>@UWf$D9l?+t8(?oIR<`^<2?zoS8VZ6*jkvVvWRW z!1?7313gKsYk_DB{-HmIKDO^(n@`C(Fgj-Eb;DVV&P1Tp$?mn*Xy*InmCVkJ^|M7< zc@LUF&ftsB_KF&NTW}vTM#~NL0cX-jSF~E^@k55n|8L2@Vx1~3Jr*+fK8V#cG0#ORP1!sszdL_|XA94RW& zT^rrq4I?+2F=Atkcm6)_`~C~NcVG8)p2zn%jx-rs3R;TUjJziMyZB)}StV3scNdp_ zrG7nU5B?)oFqTdT&`%H(NSlFgoiy%7vzocpzWB;Om=t+tKX0g~``yE#)o`ml(39Ma zMcb^(`a?S{6j>Wf(iVqs+I)L=))4nUy3O3>&Q9-Le-G)J_Atkl=4gE_F7J*bwvW** ztG=EZ+^NPvi0%sZSU)MqaFofzS0;_8DV4oPPkshhP5B2g#rB?UV4bS=K7I3OdA+kY2y;`=TqmNMYPSW-$iwD_wRP|(m%E|hppcID$1_P(dqozsYRO04`{)YN(B_Y zrY~|N-^Z6%800hA-R2!snJ_92+e5A}gmV7eC9tkS)wB4FDL=HOKj$>6O}F*XDVNB| za1k%WUe7ZK`=w(mTD%+OIUxz+7d7|jP)3porImr@<&i>@a314?p`SjF)?G>LZGpk=KRt+2J z9&DeGtrR8V9VHZ9!(n$|s@Td$dUzg%G2af`U*=_D&hgl?f* z#&+C_qljsSx(Tu*WL-2lYDQiv_c48>|540H8t(2?5KmY!MEc;>3xy93n+lJ+iZ3Au z#Lg6f_D>XF9xo|Afd`mN*eUn?SK^Nb=N?JFy|583GVkd=6_-NJ2`xYL+?*)BU);Ak zc*F2ebN`rVj6{nw>QPMUCZy_f=w9M(53G$t9lfCpTYFRxJioV8$tmcG7ZaE&2td>= zfwmCjybBvlK3h)=q}^Y>@b!LPg!?0Oe1YC~>OjW5s?`FJh73`Jg6VVK)6;WGV7KL7 z6@RCi+Z_1oj=TYz!ez%R>cYgR4=(de>A?-dlX>158<_erRuiu-eB`A1bcx#Jlc->G z_t`P5OH;uk4zp6>xzDE&JI4{l_ZE&G9RFsAHOx6g^%;-TD%?%A8Pi^6Y~mkhRmaPZ zW-_8@oXuCsTF3i&-h3Fk^8Mh|<6^`1WS!PWzqhOx(vOXpW&v=JP!9{@Ew zH7BGPJuxEl%Fu9mT_BR8t*Pmp&xyZFFG`|!fYU#bq>_*lQ|!$9$_H)`RdROT-KAgh zfpk+vt>Cu8D__mEz824c(9LN|v=~E4x5vG9@#hEeLIb}r&B5qR!Y$6nrJgH(jZd-E zzpvF^vT2(rVvjrsJRLNHR#^@}81^42l+Fyza!_^n1fH}pJU=rJ7z|)%_bUsS8hbdE z;aBQgNh^QNEOk*|zhD$%T579hV`z2=P>79Xhd!6`*#OjOY;tF$fgC^a17jY5l>ErX zY64eQSr;t2;cE==tKC5%Ka{xJp$?)Q=a1-f8ys$+_bHcIDK(|uWzzNqEvwt?=ZTcS zi-nqvxbPi~F=7X&;G@uft*YcRV+G&2vD_Jlm)~Nyk%I@X0p7bs$r?CuiTxNj<;Ov9 zn57sFe%0oekmlQM0a-KWu6r!OyuYdX8V#$R88Cf15M860}DjUNiPS2>@ddBu}U=&G7f{c%pN0-nF`E6@osQyNnBAr*9g5YrwZBp{&H`3YKQU7J&R)pCtuM)5p6+oB`+#rOBqj_Q28 zwkefnHtMIjHc&G92_(t$Y4VBoktN%{TJ$a{ z9wmAX=HDhUt);Sy9jycyZJNAVn0fO2wHJ-})NeyX8(R6X+!#H5u1o2Na*S6BthE=_ zT6-5V^--POp?J_dB4Xq&jqUeR`w_d{Yh%r=ckD9_62`V7jY|cD&mWYY(Kn!wXZc57 zg>LT~4hQft-$K7=yo=U7P=$6~sGC0DY{qVZaf_h~`eu!@i)hvx0&3$Dxq-xep4&PD zWUO?6y(3Fe;~3Y}G)xlPYR7IHqFo^ay(Bu9k(m(_jL3*!WF8=|sG~1%3q!{3W zheKvxkh}VjG0MsF=f0dtRLWj6%mJhft*{~zhgWV}nBR3r1MUp7yuq$s8x9p0hzI!+ zUj=cHx)DT~K0?tA_|_?3 zMZ;R<(F@+|!)cf``9R_Q1Wgcp+NcEi#WA&R>Rbu#qm#ua?7atT3qLw$2^!`YDnq_49@h zx8?sN(gyV^68i}SIgR=BQGqz4sXtqOF+EM?Rvlgg#J{zGqc?eY-kPe&B_(gD^5H(g zl%IRFDPZlETD;&U4Wc&Bt1a*P#+$o~oYB7?D|FRYJp^5M+zJu~RFLS`R;>5Gxs^c- z+rjIa29DjC4dvaL@>qIH;z@Zl${@92+U@6AH)Nu5;^=RjjfKRB{K>M${x4w%9HTo6 zJ=$H=j1uqY$l~>UEq+eg3}!VUbM~5jH+WtD!ZTj`_91)t;5Fbqr`RWL%YV?%-8oNu z|E-Z}sr2kiE?jdtu7adW4m^z@<^;n~#Ap4&#IANjFS4tbo7HwEeULyn7>xYFEQVA_ zKO_eaRUH)#RLD$o^&cB}31|gY%UN zl-V$XQG*4&k}BPMsb8ga!jw4y=H_BB!*o+|&`Q56Y==g zqd57%A>Rr|_riz;hm5jypM%bF*bBX=H??m0Jq~cIHCh8MlZ&6MlhV7H97i6}?N09N zQcehzvK8%6X`|2ao?-lv$3}HM*G7I-ex|>jejdl6_HbFs1;etT{Qh>Oudb&hgX24F zljmxDGXOxnn&?hLmCDq&EMNO(ufW_VSC;Z`lG+Uu`RSWFQ*Gkx4h?X1t9$ytsaZN* z-MUotmLq2Oq5Hpg`%w>1tHw>5H1rL3dxjf<0-17&k^k_Yb^P<2dwgj1IasjfGhs~C z2=yI+!01L*d!w>Ub$EO=hMV8#8vCZ*=V>De~&ZA0S=U z^p!~ATkJk04nzp6I7t{M_1=Q#UtL3?$l)TWUj-k#e#=LpmaNGk+dQkXE5Rbw);=A> zCJQUTp&9gfKx86-s?3q6)7~zQaZE8h*`0JhwJIr4IB{u*N`PQc^yC@6uo!xp!)!+y zLLX4=;e3_Q~uyfUkI(r5c}&dwfuARk3tRo;mZdm zV7V%|2J5-X1Kzb8iqGZ#P7!o|-*Ei^OYO#nYe0o+UBoW4mL)|k1nUKzqqr>+-FYJl zXpvLad1xecxzbotN!e<7>nc1y;o@H2)?@z}L#*;wDY1K+)t4UoNx%JXPb}tq&)*~e z{{6CxUGpom@kCMsx5?pM zAq+C=>(XkAYE7UE5oCnf+AbBH8+i(FTYfysowob29^{A9{~FE;FE>7DU{5K_>aPp% zv|2O2{+8tfKM$}`EK2^G4&t;TI-C`?E*aYI-6Gol1GkSpqpoD*m)Zl#j@<$Z>GV*P z6wFqo_mfo;6eaF_)9`Wu^zaEUB%@N}9GbcqulGl&cD3}AFc@Gn$d)=eXIs3X+kIQ# zYqMQms@gM^T6@^Aa1AHaeRVg&qt4af>q&Dx_B0s_wgau?36zm#l<>tFPrVNApi|b> z`38cXD2&Duan(=81FtB*n;`Lox!;1GyCXmRjrVl7we600&m^%DwNd$Gdf#+9(5I&H zrZ_o^8*BWfvjAKcV9_2C9&E_rPuZKh+5sk+HygmbP@>s&#Mx5L={?_5eSt|F@n#hK zYqHRZ<~*2F6VL$WVWz%GAsfIQ`hFJ++;YzsOc;LBM1;RWl2<{kNZBAIHo~aX<__RQ7s;i*4%ER=_iQ z7EGR=?)aV2<5rB$NtX0bQg68Ua}duR|IV}g%0eMs4`T*Ql{24{vqqX!kPVKfuWk*i zd1v}Ah0BMtLeLV~0+84~n%sK58GiWf+}9$8#MAG}KCksjQ9L_{mwG}cDG9-X0#F|Q zUc=pKjh}PJ<{T!ZwLIz*a6QN5*8*exoypgUcy}Q%IIzT=?65Ys__5N}>D}D!hqtW) zEj)7MFNz;~Q%F6IMukW-rZ* zmM;va><07bO`Qwe*)NF)fy3wHK1qXHOVavMf6eb57Bu>Gef4==g?AK;Kl%F=%MhxXFbZRCroP3C!tu7n zE3NLi-8~UO!~zdowb$otx~6wsnG9et#PSbBqzV#ZTgJjXS(w@>B5sCCX((r3AvCI zRrREs;T(UFar^MWcH`ja*^B9C#wOl`l_gx;>c?QVXzj2IJg+Y-s)1v$PeGC?L2Y7u ze~($-t!#PKlo78snY8%udLjXhhz#XH?EYij6v~x z_XDzxLGp#~q6Q1+8IebpLH!WI`3uWkvsDsCWuI@MBTME>(@s;&hBc)CTlBQ4BW1-5 zdWpnf$@$VktZwK*MqH0rncVJ3ytnH=o$9qpx&(0und2~xZUy#^Udapt zsk!6fG96EJ-7iJga{dbNTm&XYfW+UELqkBheWR)D(x?{TaeBBET}JfUTso98k<0Jc z$>K~YAM98eNLH1?T_ofg0Vq1-NR<(Vp4mus7-lb z*gG%VE`4aj_r z9~8>@0&SixGr4;Wn@KCUF=jC#LbBu}L(yL~;Jm8W zrj^VHQ`LO?5SMpV&m5IumlNTBX=3Mi@8EH5g|0j;!|%{KlxC1{`dtXuYnD?gwQK`F zjFR%SJ*@Zv*6=f*Yt=t^F!%~M`NjajLa?=sw{(?EJrgUGMJx<8*H@=_f(ID+isD5Wh^90o_Fy~x?y}?YQ&RH{|RzFVu3t8bfehut| z&B~fA*y&{p;k8Nq1>Kq!<08sLA-PNYW&tMYd(VZblVIY$*Ws&vh6qHlw8L#^2Xu*3 zGiko`+adgn0%{g7W3+g`-^~%%pONp&MyW(^LXysYY5T`j=0>B9fF~2-783X52mQP( zCXvI7qG>W^>E=uLu^ip+_2D9(`_|7_@GJ7D3a~cYe!Vis>gNM-9@mNz@{Ji*ZLEQh z*^*(Lx(s4`j8LG;=>rmY?YW^$x;+&jx5jyQNqwK)3a1ZR7d4DaGojp)lffbynvgra zaMXSRY|cPv=b6gki?d~IpxrXs7tnvjqc^A@)bJ;dgy=nt73k>3I--tNc3%GJvoA&3 z9R_cT)>r6MZf^3Utlpn(Hd>bgd*xap&%C$2M(EihM>8wk|E~78v4t#5MYX+BL}Z1o z>1fx4i&zvgGpzcI1s~_EX*tfwoKwN%Nu*|pZ>I?pTN|JG0ozY`nhH;Ec&H4pkW7^+ zPxmkU^ivS(m5fxzV13JM|NDV6rS;Bocv`Pt#=!ShxR%)q-d<-#`c=joiOk&^rWVoF(E zFN6KMCFMcjssg)@uafa|*JA&U@o^L6ze9WJ?781rV*xI2Qr`<@$%?3I%Gu(bIR)8# zgF@IF|H9-qN}SpHAF}f&3|>jHwbwb;w!a8ub>E)&A*=WngB$u1WC*9{jrH(22}?r z;o|ksNzeCrxz{%eP9meJpHj3_8*c`ktY7AI69shSIqkig?~3x^+GVlpYW@{58VUZq zBfwFvcpAz6t_V6mCO}Xek+;@zv$lVt7W>^-jOpq{VTo9$NG<7@s#h7Y~fy!VX zuiaAr2cQc@SA6c|!d_Y5-z$>wDXMI6;yEc}#t<@~{K^7nxDkv`!?ec9UT89$Hc@1D zT1N}jbFj;3Z9M1uCD_@H>;m2v7OF7gm5W_fnkQY%^PN8D;y9>*LREDYr+sdztzgn* zux$#t>o>RXjVBGoTon=`ECN&^GLF-`DJQg2Xq_CZ_I9&bk?6PY0wQtZvw{BrQ`f?_ zR|ao;cLKM*6;q?7ZWKy)4T&ld2R-0M<;UrqKjoLIKcv*hI9`ara_@Cnc_8;PgJ?t7 zBjnPt)Y=uv&l?4`sO8&1!gGd+(Wl(4UAH6qrg-2$cUS1#WPFGEljK^tDu?5tZ;{WK z4HX9xGpLqwb9IYX3I$y+hX_fSS^-xkh9;Hz3>oN%`>v;XgAPVV;Ah+coEMCBv@9 zOIX|%cBnVnRJAlPLQbd`&iRlQfjk1hQ~V0|2ko<1bXLYDd94tvGPU6XHQ5hEG{B5| z*)UL7nYCWRNe2dcJCw2+wS}P^Y_+YIkKpl0 zidR;v&^RjD_LJXPrJpg$X!;x<2ZDD5P3skGT`Zz4Pj*-RK2@x`37C7|eqiuaIVb3? zk|1Iv6?HbXk~po+fm3SHF~dF-`v7p9oDA-H}h!2(h~L6Dl`nZHs%bjg3NiC&Ef z|Ja--yreIbt(-X3a(IE@>TJHxwxr;-@DsTI?e7`=Aq2JgMIRir`Uhw-G}QUv9aomu zj|~PU)qLZruSqM~ZDvKxXNFtI1@ogMrj3*(ldL|w%hgok-NQZ@B?8$-`NmvcIqSah z7V@$srE!LFH`iISDb#Q7*1Pt@)9`G%@1-=@okID$Kz&cI+3Nb>mi9=`h<&pDZIXsy z?!Lq}ayJMloLb%3-B;UZ65>$AUSNM!muW^oVYjtV?Y;c$0$u<9xn(77E{dO!ww?Z1 z#CW6E(sD!DGFI*+$Qyngan%^{TP&H!07Vq{BQ953lSg&rF=Pc3=j^rV5L_fXL{mHY z9v`V;P3AR^fyAw+OG~<1v6DpcAd;o~_pTcQ=4G8>>i{(9KK7!CHN9t-##gj8y9m5}qT+{WNX$0{kL{eBqF8ua+{$#8(~ zwOkhn1$YJ)uF?4^8DZerqOIu0-tm4gKo8k!KBF#N3rwqM-)^>9bxxbMn~Pym8F>I>HaR5Yg}(+Y{JLGzvM=oK0(CPSCyP2oQb_ zS?{c`Q1jq0o2JNt7J$^3hW9|GpcRSBOma4_WHTYs?sy;>Uhj5VyubMkR`e@+p67+? z&&qous_F7)=Hr_$YGXgenKmEj!o7#Da**yLYYso9o#=&$g%Ah*qk&m#m_3#V3b%jV zBVuQAJLrf&7}mn&#w&PFd$y@T&dj?FtjCE2(KZ0rPeII(c60==E>Oje^{A_H#U~H2 z)33Q=C?do2Q~qGBMN;u0ht^+mg!njYbCb@WxIgy`Wutc4_z~Dym8`@`GfNy}tmN{o zl1pc%+ysjDQp#RP#HvGApt&4V>riFm(>eY6^#>Lg7O@V)bzp($?g@*43m^gY)mt+8 zjd+$ql89@?ecqzZk7!osFy*0z8!%b-+hWRSM#O7~c@%tAe5LoWw{20;!SQbYqt=9O z3DTaavM0XX{@2#Z*7AWrC*;G`RkiMGd=~3AetkPcu87h+sM^0#T>wyEvYR!kp4=4>#alB-5iY`kO zPht-$KgG4Wr=18G3Q@nMad{3-pY~uekNB1O<^{Vfwfk2c>~uBA)Bw(2ZNc5)!i7r&+fpgoDlr++ z3d&C*f`3kra9wi(&$bHvHcRBjtf*oc?jOX8P>5FPhp0u)_^+*8*#@eeNONf{4(*k}k&c6tZH%JSLn zjuQl&Ta~7mz(WH+nIpz$9rJ1MsmcvUg?1`$WgZtH=v+{%V%{cZ$Z~Qa) zi~U|iz(3T1mX)7!f%u0oRO(K0gJ(zSf|)rR`#^GGa!&(%apdDiDWa~e4x8$--78_* zGOpQVFd!t(zn_}*4S!ek$t%Szy#}aif=G9~_5K(OC&>F&-dALm?SB|Vv=*6Tssmy> z+k1>Z$AC5f=c@F> zneb#mmkn%pi)iUqGQ&(A!Mp|B8tz1bocsQ-e@Qx54>uf(`^{O(;PtJMFXt4*(uF^D z{7$R8gPbfmW?dlPSMw%DM;Bs1Dif20VU2GA(-4A;<=to#@f3+aw(O5MEO$p^8$5KT z2rG?He0v-r9@<#%TU_jOz%j%P<@Q1mE8Zi?I~ky`9XS(`T+!Ef+d9jTs*(=amYPA;RD6ZvVllVq_vPc&bz`D zU_cr}8(v-g*9KB^w_g|?f+haHECBPPt`$RvTSA;$)6FtxF@S{vDs&69 z4<%c6!RhLbK=1NQ>a{;Z{>?%F1 zRzy|chD`FFc*z@m+Ya$u6<2Qe5gwBGP|UPddRBwpy5@!KV&)F$a%`UzQ_%;PX=&?| z$BE%-#FkZ|!ObH?k68g0rMg!i2O~Fxg;Y1XlnVMQVmw-<;rD(}vL(@Uw0N%^JAP(d z=TJj;mdfPKnBUYwgQl_cJz_NqQ1ej%4OB7|~1?RBG zZTiK#=nQTDJW2XU+NQyfk2(-mdD7gRyG@yYUpk5fz_GQJ+06GULHn80PUQie+>t1SCG=Q$Z)sypz1>XbXR@$vK2zJo4#q5wez z$gOSv93mieoZ5IwKlO%!xX9IS1>Qot|K$ExCK}Ku26ZrP63;*XH2RUFW(`%$a&zYK zb79Q>M=0j0ZM39<;oFV(v**5t$TgsQj_tB`nOyp)zqRd_jW=BU%nhoQ1(t56hsdYL zm*IyAG=S$q)cz0d=w%10T{p`&o#lHO8tvAD6uE9%D0=+~*hrQjX>wp}`F1D-97YkF zkTG5X?l$DH6+pum2Af(PEAuOg5&|&&i8mtO)+e6p;MQSt;K7AKeDk{XGLt?J;B?X@ zrpOSL1CVk3GpN2DBGK)~No#i-_r2TIj*5eK!vzuQhQ6O;UxBB@c8Cjwgj^tGfmxR2 zsPnq2PnDGMg-Vri&z_5tR7T@~6DFl~2_vO*+ns3;Eem;-0i3#{Y#*Sfi`AAlyFHg` z{3RLbLbgV#6oZp_LlxpJOorXsBpHQ8CeADe)Ywv`y zU#!W4Pu&UlVr)sQ=c8{GuYqth#@6#CAW*I`KP=kGx<+TJaKPnfUo4;sRIK@rYpJ2o}?n8Ahy>pzbw- zs^8sG(a$7sqtm1+9c4>z6rlA4hn1QgK5sawI&fwTh zwEAwM`fYq4^3brRgaJ^N85EL!VP+M87tg)Q^_-_ZQQwoeM%s;K9Bkyck^D9(N^j_n zd=y|8s)+p-3_DN*k$Q)-a{yjTd4hEg=L>a3_qF6cW?fK`egiAma|Ps5WFl;|6^3E~ zL({&8FVZdyUam!V_sM463`ZdhzkDTj{Qy!5vOrRtoTPA$t{(6;cusX6d(31XI#vy8 zWE!@qxkmaC=GE7eTel9B#L@YweyNag4?`C}Oi6FG_{@IuD(5N>5@frd>w}W+k9;=Y zMs_F2B_nzCys(m_e;8he}4s0a2*Ci>?&GnPt4Ip^-z6 zQTKS)s9C0(sf&>tXUTV-{WyN}*jkfYNkzY2KaJ-KUOmF#$#|&)XA}O1=p;V+D^5Ge z=4DtPS)At%k`jJ%7@AgcRC`7_5!S0$3a}T|@Zw-})=`KA$^C~Z=}Nqj;*lvlGu=}% z8CXc%)Z=j}PgsnG8~WQ57g&m-u|Q)z#oO}Z?6ryMn)<@EP0fWh@qpbJt`0S@-EJ*C zreJuO1=Ue95-N-R#w4EZSw7qsdE6@0yFvSK~`%oQ>m`sP3`UcDCK zX<2mX#w_z&fN@v0$I5JUPI&k_bkaB&!95&=+FSxd%()j#>T?P`IX8k%9rRbSZr9g* z1PKWp@YLIGCkb`>;et1wY6@hN94uZ;XXT+din4r`SZ3{yh}r!piNavYDf_lt8Y3?n z8G8ZA4XoI9lykXtH`SLc8O0V80vLF#=`0kpjiKDMIa+>8dy?qfD#KYd3O@jGM)=4w z)G+a7m!j*sKJjkZ_PR&E(c&UKB)C=+2MVy!pTv?g?|1v_xvY(MOMhPeR`AEgpXyw) z_eX$V1}-hcHgtcsFoK>zm2?eDv5}~w9HpD z2b-$xl|B8cWp+uy&d4~D0nbq_%jEU?(g&&Qz>>T5U7(8UOz<=!AUc1vSw}OCJUHfF zIuAb$1}sI6{pA8bpFW9vRl07Lzfm6U{<)PgF6WBWf&1jGFg9Uz^i6nAVVt)+z(JZ^ z-$v&WRo>TKF>VS?=##`J0DIj7uFq3#XPrw#_R$bX`B@OsA78nV5}}6ucRgJO4RTeir|*lEPQ=kH~3DPKFv_>6gd# z$UeExV&1jqNTcJ$`uj{r!PThRANFcqgl(I%mjK(MD>a+vBP9>AOw;sl0c@t_(_zos z4g_mg13PiT&}(U&VVw+|~xRUpU2pnPL~*zwd%G@Qvzkyi0DYw?qJzbAwc@R<2m9?sf6tLW3D3-Cuxb z9M*(YY1e=d*=CLAa-wM`Ke_X!B!xbi7$a6igrvM53i~nQIR^ckO;%fN_w21YITv0F zOPz!biVCQ#WM||F8|BW6xcv0foMs0;Tdpk|__guU<2Ir6hP6}!s3%g7ooe-IEONC> z*=KetT)l2p(~!D3I^^rRNTPm11H>5cBG}?IWt#e^9{;|ER zYx@N_t+>bbiYAD%ID}Z_WWsMs2^yaQ%X`PXO~kpUmGmn|mFGX?r*Sr|tZ;}!iSYxJAv6& zfHFdU8ZwO&fIh-A=A6$sUj^@0mJCC~8=1;}j<f>$Tu;m7l(AkY9*%)X!ZG z3z9<@nFvB-7cfI9&M4auG6)-Bf)jNOs$t4qT22&bpBNWiP4^I`H${}5JH4H;c z>Jl-t(FqZli}W7pJH8}>mX>sQ>IyX}CI%B*9(udqjbmFaDHv9}Ag&Bp=03~b8a8NW zG_cI4b=JbO$|E0vl;In$Kl~ClmQxO{1HeNgHm5%k2Y2B1*hG1so_o{G5Vey?dFpze zQtT&9N(~*N?(H+bSWpr!)5Ta~<9ZYu8dqi1$oqW-bt7V%$7GZ>UtD zc31$OY;S6tY46CJD^vCw72=;Ost9mxCK43309*@qj}sw^ufyDP?Z$&1=IJ;uLDL$_ z#q@Yi=&fpch!@e*U`ieoCOIbMk6!aC z=REwS7wej;+tT#xXvFI?aRv7RYcN^+s$XVM?1Yu~5ACTi_#Im2#C65S7{^A+8Qzp3 z1&TszJf&VuW{p7jxCHe3*DJgNP?4BC$8lP6#N-d!s6vzQ?r{vm!Y__3eT?@{-I5PW zzvc2b9fobKUX`)9JmX&YoRe?n_cdOgy(~KV!ggmAh7cHmAn*147#jHR2^}N%tn7$$ z>eBFw^BRLqwpo=`)Gd11Sgi0$ixU>K0fd7@#0~u|W|(w*0frH|@^#qqBjCMe!LacK z4=()TD|!cIhgfWH+6qn_fT4F-=OARWK#sw&m=jN}Tv4S!mz8G5;~PtK?^S2=!4GBS z*X_hfZAJJ$Pa~b~ry%^>;~ahq3X=XgZpt0TT~iiJYjTP=+Bi!~4+=-~C1u6@pxI0~ zQFoIi`@Uj_4Cj8p#y&hmWu@5f^X-cc(Bo9w;2O1KCZ-q|r zDS+BRQK_$Z5!o_*DX=-ZeemJiwJ&OWlz<4PMEo&wV9Se#9g@qf~8#@ahmvbcmrC)s8Q3& zc`rcrHZk1PtJHWe4zMfV`8~2w#UK1m_~JqfR2W>U<7(U(Js;WH1i5t!{vpWZfSDI0 z0JglmyYK%P!aZzwit1zP3gC!?FC^oGHFN#Q9T0%;P_mQW#>tyqt9aOb{4Mwr+kbv~ z;aZXIXuZ4P82>+AvY`WK)#A)Xo};nB9Clq%zAa&Oqk|%JGKBx(3;>Y%Kukz`svUaF zrsybT1%h8A$2=3qkQw-ozvS7t^?y1QW8uU7hjq?lCu}~`8yA_}!`e ztyBs8!HH%;&XNBo!0C6#AMxQG<=PL~E6f0g+3bd2)=oAxzB>_X$Zmx8{65cDssDqrjkh+zjPST4r-VuPUGt=#%0#NgI9iI zyFvpzxnzJGILnLK{f8eQ!&cCmOpX5aNMr~jVpms=MC7m|D32%GyY&<>!LG?5pX<0k z-+X6Mad|(QZb5Pzrl+lm3>fko){aA>bx%8n3u{)H2Oq=EvG-GXBjhY4c=fI00JH*n z{55k;5qs@mq>w`lgWK&bO!p4-r#u$cn#K@rwqX^(#Hp4vFZW*?J<%4hDmgu$=AUP* zF#6kM=IjJ}y0HM2!gym>B|^LP8G$;KM`J^S*vv=oQ`lDv8S z%WUm9kT7FA_O2pWl}9q z`H0Vs>8EO3ABHaNMv6qL5LM2i^yvrR+B<^`l>ps!jh#iOl>e$CMiC zF~(9e5_znB_eLf4__9r8P#YDP9t2SAyuLeIjq2zs3{a`^7g~AEPFjD}K*l0H^Loec zzce6_m@FAK-}r{EG+S8Q?|4(N1Ss@=%zT3zX~)E0-XA9Q?jVXw-$eR5`x$Y$J6f2Y zfRL|Kqcz^v3-x9b4Jt#Z+l=WZl1ABBluC2mgV}xVXzE#YuF`g$tE#7QBe&7lOCjJw3}yYk-9Nn0V_oDzzoQIgNV3TnuMXsgY;Gt0S#E)$ zTrzB~vn^;H*_|T_v&HPkX}e^OKjH)PC<`M-nU91iMImS-YEYIS+5bG2$fM~HheR0Q zO|`wFVZO&^UG#oiW*?xja9V{oUzDVvk@sXy_eWRBASr$kpwqt@NJ@cMp2Sh@{3$z} z7ej^$jzUBLRRbxs;zgE zc{}j`J%lPoZ7<{IhbGyvSaLGf;FunIdGVcJwAG=g6`7A5qamI|bm#2o13Pr2ZI5!) zk32Xtjb9h7eadbQXZgwP<{#(ckoDEa%39eC$f;2KUR`O%dt*wU$gNarg<45dB~+a) z)L{qNK(mvqU?2OS!6D$HsF2gaW$b2XVXNrY^xFk*Uv-x=`J|3Z>3ooJBo=IJILsyS zgrUr^K}6GW0B{{bp`R-j7pL&A(WNGxw;Z_;jpGyhf6YS{#c#cir*3*rB^N)eY0c79 zS-g}5|AoFTK*hJg`0E!XSChF|7II&f!ToOB5(v6iI;K3kR865e%(#&p^CtOCFj!n;`$z zAp_{O+YU8wAC%wKwqTm4@66-#%NeZ(!YYVF#w6Q@S02=t61vsKY!y5c8FCs>cZSVf zLU&!DP)=j9>7P03=L+CW$o8v>?#7Gc%@@8I(+?=?v*OxLZ+Vo;>@BL^o|POPaL@wV zHFsG(jlEh|y6bQ!5Vy_$~g1C-OKhd%^_R|hE#t5Z5VR8Kh$>SzPo%k zPbUl<22#>cK0E9)#gJ{B1Ym=%8_t7KT@D;KYab%=rF zRcg|I=`0{eNPUCRPFLUQCly-X56T~U)v}-PKFC*GSd-OrLvwr+Tb8+ahbYmwkbXQ#8uz4e11xAR6dWdjdkJq7+;^*a+N=#JG}?NkD7)rEJ^rXG)qjmN99gV!Oo)eN zzamVAI@ofA1ea4$5W{(gv`nt>QVOIF_x&kMTkJr~!(}+x#QaFE_l%Ary7R4pOJWSB zQIs2nS7}C(gaEcQJV!eC#wjjcjfYWEL^lc~#T`moV?%wQ;A_FY%78B z@ezdxMxdKi#~N@dz(z?V{A^ifC^J;Nh9V?8Y2eqXf82R8e@6SD3$RMs$PC@V;btiF zI7bino1=#4?C_VUnfjpXxaE_TQMsC>8q)>v7$L`Gu2qq23#ldrJ;p!KKQ3e`&aB z+k<4ci?1V**<8*AJL^?fBLc2otxA3@{2x%L_WTHa{v3?IfJ_lKuQ~6aK2P;4AH{r{ zX52s=yV4Q=cp=D=4A^34AH1`F2tFx=`0U(|^y+zQ`z=?Hf?KMIz3siL;(7YFk9Lmk z4ufsh)3H$@z$H#klFXjW3(Z3IIa0 z;mF>=0&ZwIQNmP*C;t4>pSA0A3F%$(jGF!Gfvs7Ubt{rSJM>1gwxH&{>G4nnnzO_W zqpG?$o3eHlvEzmiJfj^$M0moL!;RKoW6N1kT6&7Km~bU%TuiVaL{;}5kLp5#gch?5 z!0nzMMvBmB8r_-u4!DOh6} zsVvho9O!-y^4x#f7L)UBFZ$;{|kRKiL)}r?(o^^w-IEUJ9Pky0Zk({1N6T+&vvzW_O)4tzjNi zy}Y;*KqU@hV7q}Jp)jf~M<*~cALaRvzXRnma*nzxA6eX<8C%SjiYH(T40s|)X6Q3A z8X_0pDLwoMR8z2|oNFLhdpKpU2{Z3A{pK)d`#b`e%dA}auo*^}J05Quy}rs&M)@gN7xajdaS38~e17T;sr;$HN4gJn+NX&-t!iXiRCC_WfiqX3hVV$r zixn|Rq?_CKi*j4-PIFK%gij^DW;hCZ_PM6X@HBP~Owf0LUzU`o17=5LY!> z1O42Q>4HNb>9yv=*%gmc)u~-msDK^72R~|&A`_Q$D%E`N z|5!k`7JxJyP;ZYHF1-Plc>I58I`62av+nB;f(8c#97bAbih>PLQ96lO00oJPibx4k zL<9`IrT`HTktPBvLQp_ZhTd!Fz4uTOdT$9OJ$b)AzxDp>a=9?!+H;BRT=&oz)Wpeq$;2_efT#h8+zDRLMr|AGRade^rZ_rS`J0 zg~hKsGn`i@h_E)+E7ugCPL_?j*#%V$WnSwBmdBMGlGMYuY~_Z?^Ul@tLt9EW4%Mkd zxiF5QK5NGLq~Q|Psb4zJ3E|#Qid8Mzi^+DqnMBTx5ZBG+CD?55yusl$3{%Qh)zIoA zZYp%`6M6){9)$aB@%NI=R>Bh#8}K~ts_0w#9h4>DYkA2FxuNde4%_Qf6TneEWdVG> zBVY^3WWD(#7UzMPMxQJ7&%J7%sPklJG>R9(*dZ z=US72*$o4*o7@aQiSump%(-RDvaEwxPkokEDTzOdnh)}^sTmObA1Kc8pViKxd~423lSDGlhP*eKZKDx(gF@V$7G%1Go3jcLXlZP>IK_w-=!Lpe(qPhSk(OL^79?R%j zIfm=)J>dFK35yTbI9WFp73#U?+41o+n$6!%jpq?QcV*k9Z7xE$dQ@Ll(3keje_i8T zV?J9=Qr6k;2;NW6Oww8`7hLSwO>m1$uKsg?pZ>oC+{~5lSBTcy@AM-N?A-F_m8FRR zwLTQ@Y*lIctPyGH`<1LplJ1{vy9x;5HayQjY=nx@-s1Rfi!T1MJ zFE4!mV*Nk-x>s?(lW=(jkL5+*KjT3@9Am|M4EHUFa&hn5V{gV}^H=nr_5or7)_U>U zH0+J61$w40B$D+0h3w_Yn3SEXeo0&CQg8C}R>kFvd6h7@+ttwCE%GPCcV4A_3j?6z z8aosA!P-1eCUU?W$}PI2qe5G0xRZZay+X~vINLSR&#>^y&~07a9}0N!E=`TJ3J;

    X0+};R=2LFRq{APML^jrLRR`EW4h1D?{%?B*z;GzxM!b! zTA=<$dW{J5*Ae(Ks>NfiAj5zmrpq*y@x;+K2m+xr%1VG(S*-5K>l3e*oJ&oqO3k{n zM`7aZVmkJY1sedqT^)j5(>Pp)T(=-W)}rpa{#SU`8p!u{pL%A)^Q~`1YwTJhcmPf{xF%9wI_bpy!AP)Y4 zd;Ngx3w)NXeA%|1hkr3{1or(wyt(EK-(4$w@KgHvUK0$y`vvFkvR!C2En$YEz3sCi z()@O=Mw7T1$XD~_-2o;HY!7bjfiZ|j#oN)Hdmn*p8h`Z^Q5uoZ%lM_Sm{DFhB*l;4 zT%Pa5Li=K7jx3p>RkGE88{se7R%!Bo@7>$o+P_k-|F!N5gkiK<|2@}HXI>((EfF}1 z&EfGq<9d@kiwN&XQ`VOFT^=FGVuw3($lVW%rgchkwPE)~Aiws6Enb^Q_A zqiJ5zOO@m)x17&q-tgVMs2cUau-DetOukp-b7})zXR-t z=i2gIPQMiMpWuahz3TFe(ahz1LCqG(BX1mWx_NooC>|u#oF7mCBu0HYGSka3GMI1B ziJm;>VRH~^h?xvcKA6p-x(nY)9tgR{IHJ8P%avx!q?3Q9E>!y3ayX;j(zKrF3i>NAW zHH~o_7>B7)Y3)s8wO9CaTPN*x^|qiRUyy14xm9W1xAtf8!r0l4TDv;CM)NVtX4igX zNx>rxR#gSRvh*;k!Xd|Ru`?ZY?4%_-&0Y#ahw&q+;THn(&y^eqQ2%{mLai(}F9U>$ z)ggpx-SsbozD_W1!wUI`c)v?O7Pd$XSeKS9_w{uz zcl)$B3i!FM^QuH56pR7L!+P79;f0~M5yo;=YeL7VD|=B3N;qxL{2Djn&7sy~)}ohV zl!Q9ff@HX~wwUl!U`vJfKSPqNtI&_aj?FN@qp)Y>!zCa4_8kP2clvGOIu{tF09WSO zUwfBlPw_x3)$(Pg(jC9+NhZhlc<(E?PIr@Ii@z0V>$NqXBJ2QVqwyapABy?*FWIdt ztWGJA;IKZaEvmY6+{Gjq66`Tw7`XRJin3j>Id(PqOZ<$v5E~G?G)D( zGO}(>t!n6N$_=*^Iz9#@^QRu>7idPdU>(51109&^J}70`uWMOECeighkeHJ%DI_=% z3i=y}7Qnv0y75ocshwy}xN!Lx`*#2G(O% zQ~`jw%zFOZT{Z7Soh?VLQV|xwN0*l>p#6!E7~p&gz4ZoM3+F7tArsRhW>6QGb_LlQ ziJfzXN$@mvvE(027r!!b6Tv=&Ni?B` zUkbmNx|h)hw#z9?lPTpzxs=%}mO7w69Zx8w^JW|!92Tl(V`Mq~ex?&4=`D{VU#^H7 zMEweJx11)6)SZPs6C!Tlze}U&JHX!N_Z4^c=_c>4@z*c7-ub8=@wQrmtrYC3XUdYM zTJY<>!LJ}!JP97K*d2r9ya_Y^smac(+ERZs9_AY5yVj$dyqeQ}e-FN~DjZz}-uM1t z(tguqk*1lAcaKp<(${i%uQD8W&6D*Ec+`|-s1Q+NN$Ueuy4~JcC#ASmZp?$?zO^Hbtl!x3_KUD37Y@KcTm_{$GL^D}{9wDwgO~~O4 z)_T$9z(!PsqZY3xMH^j}M1^$FTY@6xqZ5Kn*%6us_u zi@+lVl94Lf`5Et?)J+hWCZt+`J1kan5hLLB?uRAo$(;0b`>S&jG{ekUr|;j zHX26V-FJyx5QGsl;g#22xpd9vs!*rQi#S&C#>z~Vt2&AKJD>6U3eky|bw+naf9U#y zMBNNW0pJ1@*{tW$ud^lEUt=F8!_iU589eaoJ#Hk`c~VBz{65j1~bF$G3@b}s3Cbz#h(APTIO7d z?Ha-9@_gPzPt8?LL}7{P3+eg`>boCB*@G>f0Z3S8rID|J8P~uyvsA|HyyUavo%J`q z_0>=QG~%TKv?M zVP{ue+Qr(bPSjctdj}PtC+admz_x}As%S*VaTVQwpx7e|V&Ti^*5Y?fiE3B?R6Z7CdeBKW61v@bR_G4h zfsz(~+!EArZGILsoDxwDI?d9N`ZB(2l>A*KU?B1cRH#?xbh}QMG=8s(L_RcKoD_sp zKa6INVNiP)Q{=Ely&JLJ^e-$cUabs+vaFbE2bt?GvcRDJQlI)$U`(s6epy=0?JnINFFx^{>Ds<`-YB7&ZXATWQZFn$#J zJ;q4n`=yDoUp1@aqq8_2A{qq_FSw%qyd<{i0I!dRT6{kDHZPFz=71U)s-Bfi`ncYN?pz^U5le4i;?(!|DfgK~+5`0t{u;Ii*f zJ4N;}5>VE#pIg3%RjP(U1=WnC(ip7>R_h6EVMpUQp~1M`UDUxmSPn^L=-Z`KG63E? zBD!pgI3C-R@FoAE%JC=~<(5C)arf|C=*1&DYxw?x7um1@L2Fv0ShTuhhCsr1&;8D>F$3N7h}6qtIfWyq zpu1f-S_DoU+}#mg?&hb#)SR02CyCt4+ed!-NOKA%hxMLrK8TVHNAO_E$Q}T%YNrhD zP$^GpA9DtG@^T1>fAh|-V_1%ILqLjrK{2`R3-JUT^IQFGx+*?`5d#FENAr|Lf4t`X zW=?BLt5qtwIPBsU8ZhXT`DNnHLqyQ4ojp4Da6`SfnU)OQu|tyqQ$$6&bY@o<44gL2 z%Xt`N7W?f981%Lq-&sX9| z*iSVIFY{37hK>sY_K>qS4bXQlk$|Ccr%|a)W9jYpqd*K`itt&3z4z2E-1P0gbW2v8 zFFVQz-Bt)8{#|9`zc||bM!PU&|Dot{fm3b+Eo|i;jV?Mk|ZCo_7)Lf8TKhQ2$%XGP! zBKQgL^CO%fJ$7-Qaenfzi2RM9Zddy=-)7++bF)0%VIM-@0c%{oZ9gt(0r8wGI@HQO z3!1LOw+~IS=j6SlbK~6RNFP*}jmq_$opVyJ}zy@HDav^KTJu*J3vFGQjPs_lKCMUb`oRo=UrEb$x0fNViiE*{0NNTsd z*6b75>^r4a@A{i0ApHkDkrK-BKcx)0)!&0(xhDvdtdkjzn%B*?SV`I%E+{nN?vKFP zBX&IJi#lSSdMza6)p*el(+6uJY_Ma8Xn)dgKd8TmcPhhP+v|*s(RgRzw|IWOO1Q3y zXL64sB-zKBlR!~BOjOv5=DwOT%}xBsOh)yr+uziG-!_9vI|C+Bhi{${b=#J0>q<$-oK=cSJ4qg^wf zVZlGKInmPEWiH|n$8P+d67ljG#V_&6`DdBmte<=IExLHnSq0?!Bbm$pI1rlsc*lck zi%h*BbTUDg+uv3EyKY=h5dDLckrc}=T3+4IUv@>;H4E)0L4kpYHe;FiCdOp3$bz~k zmSkn;YscQ~2R4==(5+96aJ%u{!dM`V$1KxEBCz2hTO)`2b1c&{&P(O zyE+8c#e`j>)00^Q(N|q&qzxLB)5aC=iyLgXwEop&i>v(nhOU;e4xXHzTORGHkV1P1 zS-5XcrH_8;>|X6LidI2=*q0BoM({?tuQgk?st$_+`LnJ{9$TDx(aSFi{+h|SLpq~> z#z1tPujQL5=)7p-DyP1?@1%xfaCQA5`YVxQh1Y?+TIL-C@WYiI5pY;5R3KTjLC>R))h=eW z8ag<4cA6K!12AS?2ON}TwkYA3a0OL_*%V$tTv1t8WdvH3w?MddpboH zR0^V&;t9CfUer0{=8*Ud-{K^RQ|9nrt^XcORP)jbau)yzj6VwsAAOOgmJJ&gb0+=K zd?Br#9AyrgHoC^Qg|$8nFkI%T)mL4Z7!6~vz`@)=FiJdpz z7m!W0NgdOGVAfU&0;Ie(t9k;4uEZ|8j-ltb-Ep;?R`|Y7lIhRB*{U!*^uNl_5A96q zam%_>NTpIMH0)wfC|0yp%jU(}eYJ{S1&QkE4(=Xut^b-|aM$Nl z%+6I9A61EQ#9jLHbevaW}PkPZ1`8AZy1aD$glpRPXJWgcsxW z=w%K>>e_5l=LJ*Do0OGO>-oD!I%@d4u3fhpGlkc;+?OI^{${R2u9|B=2*<*P5{} z>)v=0cH_&2cskADs}|f}DX7!dzMo*_Y9YXJ=F_P!%-{*^-oG}PqxEIoxB5f|{;_qX z#J0 z^kqu7AG$y8{S74v3a-Qs=}FoH+Ys$7DIdonY0`#4p6$z*+{B&*A=V7N%UFeXO)@gY zGRW|hio?&7#g6#pKd|`rW(=kMqF=B-+x1;=N&2B0=Oj<%COM(JD$EbfB3zo8oNTk=#IAn-ML7LE zIW4beDTyYL{4H#eBv;ic?N!c^A$Avgu!;cs?Nu@{-!v{(aRU7+4d9m!cnRFIz`cleK!%HYW|G8SjyRvrW}2@V&Kve&X}-+m1iIA6U$2tFNqj& zTbJ2^+?7@TW*@`kAF^8X-2y1Za zm00kbRRfNf@pfxQALm<}5cs*=0l{*&HkG7or3O~6qy6A!KqQw8h^;(oXqVP**0;-4 z`YC~yd|C=un^^Mz5o3Xdc7pwYnT?n-SWie?z>8W-d0%)gDsN`UtzKVPgWGJOHz3wz z3b*wb=MMm)sS2p0K%Hy24CwbyUx!MDO!sh$40a_2s9ss+EvU`^VAB51N6?!Oj}3dW zlaR6ODx6*N665mbW;TgG02mKnN1Br6L_$hEDFQrnfkDb9rG-LhR;X1ESy{Guj^Jx} zs2l{{J;#m*Z+Ce8HjNw{ zP0K$W4$IW6*^+B#;CkKG<=)jT{F^9m!8~4Co%2a0s%AAEKiu16_Fv#z&xd}or&4yw zPcU^(!ahnc_|=A8&ic23Vk1?x#u?Dze?FVc&BF#EC~Mb_7fk(0@ynCO>D_GW9QS^EB;iPN zql9`LJEFyV;fs^vAv3)o)Wk8{`1{=lidu6T0OQ)G;Ji%`HRF30b|JyFm^&Ed)V7n; z9%$;+e%qSz?8cz<$V)3l=glOdYell3HC4_~qT@xw;*i@;iE!~R)zK!6U-!z^rT7MV zf+MdEO3UC^BXM<9SIh>cmU^;_x&yDi^pix>tln?eVi)YYQ-51fSI>NqvXf|;{|@9#uSKN^ zhI|z2yJM|=DRMFuDijj^WZ5NlT8p0nc%lxxZ}lEAw2ScD)JmFuS>2ePH-F*{?=Nf` z;2IelEt2XL_hl`GDo%CfAeGlIn#s;8{WBj88(7VXE059f-ZJ${Ju{kh4gMsrgmIQH zyb$^eFWI!?3H&^;Cc+IZv%fI`cSc^gH_pDWYf)tHB@spUPX@*ewJm)T{S0D>`4Wa_)AUH50IrllDyy*FLAsaql3 zTl!M%DOVlLZgSm9i@&f;__c@l=^NX9bR%tCUvjwrZ zfVLq6*GHP>1iac4>y;ctLF}SobPqVk!WHjL^T`Ky?&is9E_JpPs6R~n?O)^q~ znrGg3s|cZ5GC|MA#j861)cN0wt8fV(=xxG_SlOZLa;4|43SV_eu`>B~_Y9@vQT(W6 zOTytVM}ZQ*9pw5$Yp7_o&O{qh_OJ@^e)3th?BadDPJ@b?l8DZWeVsaCup>ok z54{nWuWD4vES{CE6AZZ|Rpb9cgr$`srSZkZN7(+%|^FvkQ4KH-6rBnGoOuDZ4VpBoFSNDdY?)R%DcRyl83y2w&HKe&~!_y87uDgN2rF z4@>Z9(e(1DFjfI|GyV;TyA}BKjmP%7GwWZ)nu>)Dxp&qOr=|F-%lB5V&E0^X$#W*F z(Oe4vI(>x(f7MYB;f0}^9pGA#_4l!NoraTkQ5@iZfDUo8%h zmEBQ4IJE#;b;x3EP zmMqv+O@2!KD4t`+^Y)hmb}{FCbdhx zPh15B(p!QH-qzL-^G)``6m}tKVbch{f%~|tWn&M+7k&uHKpL@AZQJT0d*`9_c+V-n&8Apy)xw&hyfsE${l(j4+w@}nE9sR!JAZ<*rQ3!CQr}IdT~?6wpFLE3i;{QL zx)s0n9V<8g8)UYkJ@GTZFgi&RbTQA%ey{AOdWe+e`1+0ni(y3en^$3L(!FM40|02& z%&Sz}%>cu;!A-lrz|H~o&|p`A$QfD^mjbt5J|3E2Mje8x@Cgzy;kwu8FHa)~?^~nAB6t z(U;u)M>${N-TmwfzQ(@EW1aaa7m~W|oeu$?pAYSbrfEbWkofhMIIP!C)9?2a{$y$Y zO3x#BGHa}_t0kW`s^?3;7NS$zvwOX(kpSSU|88-dO|%`WpwaUK);h#+j7Kt+4@h}Q zN#zkP4?gvV(5n+=@0YsSTvS*V^l8TUnLoa?lJ8Gb1ip5{dpFdQVV{z~dqZ@-^`2a$ ztW3@E(~7>?DdTT<9w!`L(k9V+z2icB&rtWW&Yw|Px&`e5+t-SDLA(UivUTevflmMEsKmpAeJE+0W z0JKA5W(}sY&f(R(-v>ogKhg_Gt+jCRyrrm#(S30<)8x%1W12qYNdI>=TlByF^^1<^CGK;zNvPX42;)Y* z5q>Z?4TfOokNX@|U;_-k>C>Z;i*wACVwrFLw4UgN)8GJ)S&>$MJFYu%zI4sTd zSG`U7+?4>Qe{hQNL=8ZJb&a(r(`($CeX1j;8|S|wcW$b&*u94H=*wKAd-GugaP0A= zZfQQd7hh}r^gw_UNtZQGz{8~Z2Ktg!M~~73$y-^d;aZ@heh)f?lq3Ssgrl`9%QBTh zj?~p{#_!u`{{ZpbWMFS&%x6nUlksCMxI$_Y)H`$oCiEcl|{ z+-~y<2O4wKJI-L%tQ6l-Ap=I}{naTkA+V>=!uK0a&MJ9?2onDw!lWvhUx(aGu`ult z_~%`e4i&hqE0=Si_su~%j0V)}K7$ICikh9q7QH!0K4d)EVC6T{U{~&y?1(?ciSO72 zg=94>iqY2Cwa|UTerG^WGTSS}@N;yb$>R!|)}WEVWf5b(yx{s*F@%{@)lc}6Pqyvf z{&qMMR=vaadkw?RB;l^5+il-ZOXh!?cdh(>=P2g^V+1lCsi;y}-L}2@8^|xVT7SE$ z03h*ZC}2GWi zr%|O%i(ft8lGLwJ@}0a-MffGzHXt? z&u)z!2)@aXRXqIbnhcAdxpMXUJ7Wz9IbvGmZm6ya?n8mm_RfL;SSVyXvPoi=tO!QV zbgH=eh~>L2)B$HNpTB&2$Q_;P4Y_u2QfH!qw%HNMMIY!AlqeueVik{@*6Aqyi(G4O z{7$MlC+q)syK&IKPpeYqsI2yC5Fun1&jJqQxk=%{&=d3lR#aMKRM3eoe>Uxe4R&MV zh!O77iPorHEwvm}dZV+VOO-Qu+8Lxa#Xb^BPU}IrP8=!pSvEDGgZp`Gsnl0d;ppINHCuS4rd#lo*d9BfS523}hLb zc8igv3fH0Df$!a+5)aDCrqM&>llXq}G{2^|u$!1|FT;tmqu7=CrhHpNC zil}v-t6iTT%#uacSo)8@_sMuu+3L>JU_R>*(QkFQHW9~klX8#10~hQsMA+gxUx$w6 zqP=DjF;{$1PGH?-*ZOf+V!xubv-;TiYW0wA7XNte*enbbpv_+t zZKsG?h+)Nfqd;)rwqH+8&66K50WAdkWpGYR&CkW-v4+@k@7D;H-^TQKAAz*o@e@LcgV$0UZB13~2nO$w#t2a0=1~dVI))+e zubgpBV}zC5NmAU_$t55TUs)-X&sALn`?b=NtXAy5@lOdKaw+IQr67EMVXtf2Cpu;$)Am%NbgzA1$55 zocud^$6MHb)&WcU9-+9~cm?lqZ#|-a{o~zt;f@4#8o(xyc}vQ5M%^LIfuB z=m|Yxpt$*=n#H>=$ZoKZ#LnW!m~FY0a11ScEMOAKPkCD%iap#+ds~ehjKsr<99@Z( zeCdg|J3qfi>9dV-EseL(j~PJoBoy)#tI-Hm>lGw$aZFFln`y(-`mX2T;*%>d6C z+%*?V%<7HStZPxlYEw~nV%Fu_XFo(;So9X&)9gYtv44{GlE>WZTTA+yPi<1zq%SV4_&xVHzut(I zzi(B&wjf-UUP&pQ1@>8>#dCBABk2h@OivEH^rtE`fYK2T?VH42p&V^PzF0CaGJ2*i zDm^FBhFLH`+oN_xaXw2O?0mnjt%jRrbH#4NJekE7W*mG{H&|)wWY^EG9I;CM-e%BvD`;Im?gd4DyQZ46B1Djevyr60l>N)5zC!MfET?I`Vl7LOHG03| zY415P&G*{@c=js|{8 zl516YTxwD_S+M!b%>b2i;W7jCx&%y!Er@3FG+f_E!e)zQ&$y?77eQ- z1O3u-X-V^0P;2aK@BOpfd4##T+P-6>j{kEy>xwkp)#by!tLaUxW*AIh3EgEg{r1@$ zyc{WMf)1}cd2x#RG7eUoxhv^*lRFsK7Y8=kXtbYb==Kx7y;rE~1^s#4(S5PYKy(fL zxfCl0x}FVdI^S1%SgyN09sR%ueGc=2wqqtr%9_>UFVagxHXks11gaSBFP$zTxTItFY11>mgt(`+WrvZC~TB5 z{GQ@c;W>2<#uSGjOiS7Z1c?nVYy&d2u6%i@Q0R8fCx?{`J74rBc-;iHI}2Qh0;>XsBR zoB8ZgZ&u*|c3CO{y{1sxcuO4Eyqu`lChZ4~VdY%6R+$KNJJA=hv?1J1G|)kw_C2#J zzfk@RIohYOHIxIOPQsreqo&dE>$yg?(|A0yv3Wfaw$~Ym&qK4*tASjg>KfFv_}!O+ zN9Qw2zi&6>V#q3-7OmE=*v;~>>jM%Tfus`{S7S^EN4Ma|)@y`3etqrh8b#dw1hlFU z&$7U*Bc_=`+*zp9;X*(dAOQ|83{z{%&#w!?7iWdaYFnxP+4f2{3bto3_?4uYX0Nz} zQfqFBTo;L_=+W1E9&)TcTu)L;-Pn6HCU`u`ld&uqViOTAYf^C0*w2JOd7bi^JtHj? z!Z=gL5lJu9Y$r8E!5DsdqY_T@nku} zFS>p=1hptl_jQo%N*llV)cuo_XrI39R{*VdMkX}yiM4q3(=9((m^;QqXDv!@_g|2n zOnuYEm?d3GWwfB#2wPz=E}6CW0)&z@!K|wHY4bl4{q}HQR6n%K?hJXZ6)U$JFBno( z?b-5X*xQ<90ZFQ6O37b>urA_R!e?~5Eo{n$*jqDM+GPinrTF~kj0d0xF8|k%uNy~$OiHFKGkTjv8ih3_IMyr}3&I+eb;l_iVGJvx)N_US#+oY&>TkbZgOp!7 zWSr|7puu0{RxrM&AA9sWU}scV9J>2EN9A9LEj)(BdLEBw%^N2avK=$rchrCjY|ybU?-C?YlM8tfa#IUSSW z%Wro?fz>L6Qq}(GS*t`PO0kUEH<3{sU&Hj>+&M~VYTOjbSo!EH62!1GX14L z9E4R>e#`iT)X3gj=SZp^jn}~3sT;hLW)X*sZp+bT2%Fr-{p)k z!S+4a+?1n$nmBh4#~I40eWp5Ye3f%I@MOp@&I6!B=m`#i0li|;iRGX{gc)J{p`d?j zl*HB3vy_{JH0Kv<{=;$q5yh(o0Qu_5v`xdCRjIre6bt-bc`p9MLXHr^zsqcj8M5db zh+b@}zVgf6(E3#gGb>TE-xQ`?p@P9ZgNRXwAB7bx83@{r9`{8YaQcOEL3%EYL(HWl z1brG&OWhNL0(v@;R%wLVf|Qzas8_F5*6sJ+^^4VBV2 zlkO*k6>uJD7d+fB{W`&O>9>WqvTn`W2oceji%PxMf%*Y018#s}Spdh2+6A`Ox+m)3 zYjWoTXJe}R&7K`-PZ$A@>VJ?DAC%m^uQ83?6u{JwTsv=F)Yb{J~qp1^F;@j=ENG#9v$F}SA_Pff+vF{X!m+)=D z#T8h>^?xKjVvps4mm5!TIeM`^!Dhf-nvwd8Wy1vpsBVe#u5Oua-At66n!I3?cT(+L zXjpiP-DTRUq*ZcC_rZHk5&>*?8L{Jw9%a8|&cL@jpQE~WSVvo4FYq`zlp}w{{8W=~T z*Rs&BQQ&sxSv7C3@#B0dK187ntJG2vz<`9Nj|uKbV?PEH?XPrnMabuCXjH1dD0)yn z`)0O3jQPag%$m_vjg=EQi?G;~<(rLY4^8#6EpJz0U9DqPj9r2~>E9OVs{haW&pVOC z#3jkf|Ibu%Qb0%0Kk;h~phWnJ7`(7AFMJW79_Vq@w@*{t!*C(uiO-N;Y|~rCq_MCU z>;Z@QwMEEb4+-`gY*OCpe>E=Q+j8yp6Z*}6Bsw69*KemhsGsY}Z=J5PJrKIu1e>c3 zw93vYPd(GCjMD$TH(2#l`8T^#rl~_3v1qvJE$xX#LFP zj3*L19}B*2xF^H1Cle&W$)bW>I+VM-zhhppN49tt3sV&?x2l>@X!IdhY4#9gwMU7Z z4II1JSv!BzKC5(lLIbQ%!1yTDu$qk!*ntLP(DK~=dHgb!m0CKj$^Va!6_Ax2CAXOi z8}MIgQvCG+A(+bPmu1{?=03vTdE?+*{_2}SMvfbDb;Vi|bdrGq+mYDQq}n%Ok=h17 zz>jcwIldKM@Dy!+M(;MOw-mp3V4r-~EcX`OlgRIpwzRn+q=ZQLoa0|L#>=ComTS;{ zOK|`FM7F0=O+c=!Op{fPsfUN)-`rLb4GgpuN2yClT5r_g`Q+n~YsNGLa}z&L97Au8 z5rMS>htmKk$OVAfeYrt6$X-su0 zksX6aNVkndYGPqcD7smVgOw?oGq|)EH5^mZQQqZfrqZEuNqVQS%f940DJxow|6cF) zT~(F=$!qIt-9%#4eYOK|h+Ccr&-ecuY13c3E~R1fMX4gm8lEMjDmy6XvL}nJAq)V| z`hY(dx`1^0-fZ|ot*Cinw2oShv@+PY=EOA_zNq!v{t3Pg({-5rrneIj{yF9FsCmfr zYJEAU#yz)A%Tj2yCv0baHK^q}bI0P*&Ys*^8Hb{?PQN3&Y!wj*zVB-TrL0!>Y;S(H zPImX3LF_TF%D**-uR_NJkza?umyz!f_rS~xR~J7$sjj|P$#nYD!MFGU=-pP}EC)HY zU+=s@U6Zh$iiF@mN+BwT|Hc!Wl^k zECj8!4*W6jS3R1bR{h3Q&H`~d?HKv~gXFZM^U-<>OZt_@&ssa&pY61KxxC-}^JsjJ zZ}QC8_sazl^HFjl&XJ(c26nP1@ERaJb-lF+BI7*R05b>UbOa)-QVlcnt4jRn&2x=E zwTcJG3n7tFCqOr8I&?S=Vh=ytZ%@rQ+E?&fxvTuZR0pHOAJ7+A$8EvN;q~_Nd~2Ok+AXBcI($d>50 z#>FVOwNf_@!|`LcU7!tcQxKDyT3%!S21ONHY*wqQjGtxxCtb0$^RnrEE{cChp&~8@ zDAYl?kMJ2QkRG?o;{hVooHLhquhj*d49sSe#aMzNdvLV|ZoMpxcm3H|Sj0i{!!fAlgKm|e3S|&^4kX5K`q&5p-}dCDK>5UIq~gf7+LOtzqMJ6T}GCfAfzB$CN!rlD@kz$ z=fCvjBrH5%ZK`&0!(nmo9+jLaeW&r^uDoZ~a_Xe3+E>}TB!mlV0mfMm9edjqshIO$w zx3bb-hRx}K(iPWPu&)$Cn}f0TlE3zt8I=ET5c{%4VXA80TGoD2HhSP&otnb8-l=z2 zEK3w0bNkT$E$Z03-~a-x-$ndjQrp*^k6bPO(-!-3&?33n+*>QlJgp>FvI<&0`&!Z^ z9|v_6b!gTYV3eljtIeO{6aOrBy{$oNG~IF)lTefyXDzXG4ggM*Y7Y8fDyULaMWM{^ z^0jc4+?}}tdWW_Q-@a1?Eu%V*Wj4b6IXDmp*;~0>0%-4WA2-OFIXe`uacyqSn#gZ5 z+iSvEgR^sTYWX7_9lmjUMS}+*j~ey*2XFaQmko_w5~}=AlPAsRpWf#9|JZx)wrd5{V zil{b<3()P!)_9TOC>%w4oEr5u_Y0`X^*g|>q{-#s*qme2suX5#%|QtccA!28?@Rh_ zit(e?_I$~zw&0Brlq56hKZSz+nJ_CYqV6*fXJND6#atI2(A5N}P5kWmW9?#UJSUx+ z$@Z$1bFzlCrKZ~!UYaAklD)C^smo;#nK;1V53e5zeSbsF;5RHd9OKE_`Kaugt9n5> zAkt_90Z<>KE5dRCojxwstSm8}xr=vUyV7N{8LzS!h6Wp zW}yuAPCGrME7zSFS^{Fp8^kHPv8P-h#@oH)c+P%Fl5Rg(SN=J$W;ShqSduiZtWkiW zhcUMS=#5@nfohVvGUb4{LyKKoc9NQH&Dvu?yVxrz_P~Ell?4uK9IP^? z#US$9_yN58fq(0;PHdLCt<|iWtNYR?t^uNJ8B<&AUVI^Xq8>j@K@AMl*QSRqW6a!4 z3DxgP%t4<>UQu7EKF~|d%$G7MY{MCb?mX*!eNaq$k=Qwqoq$C7kkVo?FoY+6>qr@p z*Zx_szjcFEI8`GL%jF`xv6c^wdA9hY#sNAg| z7^^8J;`{r+Q(&n=f5qmIjAtR6*USN#@4|0niXCWxDj+N!@Ox8&Z3RG%rP<-D{P7x^ zIFYU8L9fzuhJWDiFv-Yl#QxUdblG&(=;GYRPM5kWEJh}^GNA$`1g^4KQOV1HmcJyf zxMs4qfjfB@3{NKpuc^)nyqBCCP+m@vI~aQs4Zj!^SH|*P4Qgws0EypIf)&DUPtX(W zifw8-JlnnXs#bwz$J1s;g+n?CZ=#_57y*dzj|dVlg)q#7T~pc1_Qjpb1 zHjZ&iZf}>b(yJOk_Nk4LtHcE$V#ohdg23gqAAEA0fgkG-fNOEv89U9}zt@#!oX}Ia z6P=RB3!wp}KKgx5tNqQp;$%iONk3$Y^z&?+kZVMpZ_zSjf-32dk(&+8HAU`c%P>x z*wGx@W^ok~fe<|tnqRlmy((#9KJjy@LwTX=rU8tbl!w@v?8Z|n#3?dR18 zi_&Rl#GbIymkl7-RLVP-iZeigMHO^MNA-u>H!59yC)q~RR9O+Xj)s0#G25w5!La3D zPHn*euImUhl?D{a@vYc?Z_L2yr%u9RdZBA7)YUBiBsVQ8;YCl`VKE5(6C4@!gSCi$ z6K^4YAxmerTctIufXZ#f2DULGS7yntQP{Qv_->POLlmB7=R!$6$i^*ydeP8-^FR<<0|SG+jYbS=l-Lafc{)A(z8I4kYVOB}Vuu$3d< z<=QY3^LZ^C1N<^NFfUpB13K2iUgCePm@7?%WlhbLjHCsRX_-8MqPEni+wGaMRNV5$ z?;^~QWa+z!g^z?B58>6^H*GyCFKiXo3KzyW#uxozJ2zov6X8XAuxWa%*6!<|6Ubc& za_(lP4ozuIGccSgG-;FV2vvv2*;N*BA@{cYSfDlI3ZCFqV9zKS#aO&l*K`UjbXKxF zwCNsVC0~Q1fM&-i_2$Gc7LlbgYa%gCh*6}eOb3e;kajbAzvRT?TD@Q)hNtR574h5k z1lhtE7Rw`J?YMm>9xGQ>jN#9QcWxDHNsQ+o4lKEs9pzP8Eyzt@H>X}6ZCHtcZVFrzG;npdPJma}EB&+y|0J0 z$j2>4biA7PM|=a8VyLRAwzz^;!BBhF946W2_VEJTOIn|&impy4tDl}(SM)FEvL$UD zU}o4Ue@GqIdguFPpbuP=#D)K4Ivq8Ze0yW%+K+!+Za3~X^QH1geoII>w!MIFS1~$g zctNdt0^T1aFDlMHKIikt|B3Neki3HY5JNEHM1suc5HeMmTQS1eBo}f!SGKw= z@!r>L)aV+Cv3w4F$$C)t`Q|jamUu9XBu2KL=vP((3`9;Ay%AY}vaI5;@g5< zYX8)+u$2Rl3zg^nE+ol%`fR2-6NBi@&9^&6%X1>_3Rx__(4|r!ULlC6y>wS4U zO4pu11}sY}pcvys>?8NbsMaSt3LBG0OO%0*Lv^6u4jHgTsnn2msH+G2nyZHZ#%=M| zW7w5EGDm$(_0rM;FSBq+B^MZWX>pC#WzAPZXXSHz8Gh;*qG2%tQ&|$T{dxR;cEFxs zP@%QJ`T%_(VA=|3ZhsicaWgf(PZS=95Zc(d+7b(9XfAJaFy{akOMN`UW1sx=tZT49 ziHWvhO-t3p8tCqA&8d zUL|EU*+x{z%ta}2{G51S_ik5TTJ@r7;1_r7&Tm^}aaPjdxL(rjV|Wb?Ovzgeigqt=0p(eavcs|#1_^|Md&6Q$n_0Q@g}&NFl$ z2)95FM)2$^>6d=q4SC|?2M=!j*_g#!&wt!EZi$5)PgAsQ7bxeM4&doM)@_H8s~^%2 zY^uav$akl7eL-~Z8IO7{E$0MT)A|@x(o~h(c%rTRhn<}-c9gs8_%+X4}I0IV0 zMVp%o)0!vfze>`R?q6?b4+$+f(F{$OR;^JVFFVS>v{awSI(^ZF$LvMQ~ysY9fw>-uPHU+ohR%lfb^0 zNa%#4V)=MLVPPq!Nx7o+bK4H?A`Ywc`c1WK%R+L(rN=pL%|w>CKK%-MK32u!K%E(K zvFTU?+4nM|pSY}l*4&d$jnV~AI0a?P7eCwhr)s3Wc-j%>e`_-;Uin<961N?LaDb9= zBBMHgrG3Q|M}k>Q-EP)mme(1lm~nRaK2?_(XZ+SI^8is%TeQQ>w|-__8s(B^`73G- z!}chdncVexvDCneGcK%eWA$Iou+Pb#H(RAz}y4WE~zD&p7rmZ!Bp2X&i$ zcPa1xdAQ4}Jcw`ZI!|5P7Bh8v`b&kJEt!;dB?;=iys-T_B}c>K)B3fVM&xfOh&bSD|_WAW^-`u z4}CdQ$gxn9{D*!|Lc}}@FIiYP?!10||GgLQ=fYUKRNq&c6!JE|`R#>~`gZD&i4dok{jD_K(Pt7Z)`S)}y~*Az0ZZ%68N71pYoDW3>GG-m$VSOb;_sHdZ2D?C>)`2eOxCqrfwg*Igb((;7@AQpAExW>C7{A&o6W9E?g( zfbD|)S7N_@tr+XjTN2X-{&XiqRPnpoE~66*dkc?hXaDxVuify9Wh{6HLD2z4>-`YlxwQb#Q5BSZJw~0-9iN zeA*z^p8HG^Vq#rJi&#`PvtSkJcF(@4??-HCO!krK2%Q7(ixS30=+L~=yke2VNrrrT zS9xm}MtL@Y)}k6kZnj4^dM*!`0gv zmWCrd4t?_8j4X-pI<@=OH0c)g1&MH{S}I3tiofL;Mmz9!fXcb?g)$!}L2smt5aAHX ziC|^t-W)KItt85xQK6-ml-F}v$5-k}YN6nY@^3nOf;*Y%InbNoWyov&uD?EJ=C1Cfaem3LaD-Pd;=I#o@7`tVqKI?08cP7Yba55*Y1E+=NfXp>(L zsa+$6dScOO;R}hmr+6a+X7>YUX|IM62QJL5Ycrcc2J%|oKY_}73E71P)<~KhZ*dGP z&=fU*#D};|1r+ujDKgl{vlH#UFdySrAY1DxDFZMw_(v0@|+~W2mg=YAD z9h_EA`f6%hsa!5vQKq(|S?`ZqWfRdLUty*B;UjZbdtpB0U<0j!{NfPjBTtV!>=)wkd;l>biEa|CZ>j;_ zy^a1XreQql6)AeF_q&71pCev~#Jp#GqLD0rlhl#aN652B%O{(MZHDJtU&R@k37D35 zrM86zH`Z{y6u`7yT?l{W{BEwH89R`bd|HD05}VY}`|iNNP*=urN8Iwcb}>o$`UgLE z&%))f+xH42ANWx>eY`x#p=`bj{cNLUT#Pjs^Mk*O8BbvC2^*p#@rCxnuj1YBO+jFp zQ(P!J4sGeT%Ahe+j}$GW>tlxknM%)=30poY7Qsbce0wKZzd(I(YqF5s{G&(JYT~iI z6>{#wRF{b)$(BR#1&^(qk$8@8?0S4bEu8Y*Q~vd+VXkdI>mARKtj*is>pqLGVOL2W~hefTmCcliYi<_DiV?;Z5 zDmibf!Rdv8{=G;2_TTGbAHU&0%G8kS=jq;PJ-jB?gAyc$4#Os1*fDtmocPvs%8nCR zfFMgqwMIt2QR!*M{Xotc3&NtTd6IMREc^GvP{{!Uy$V(d*ljT_f8VC^)HpQyJEjmFL(>vRa;nY&5s(4mfqDYwOCZ;shAvTtkymVDyxO5WwU=A)EspLY-7Ax6i$=QcoE?fnW#(@C7Uz7C44O{Y*?|9h<&x2=g|NBBFL$ z2l7QEH)c1#nicW~5!WD&v~E6DGc{+=f>3PH|G41)JjgLWbp@!2ebckueHcX>;OZYQqv-_x)-w}(i`Sj% zETvBl6P)?8j7s&jfF259O5&%jMbh=*XG{ zW4k7nAj&{Zsi&=!;7k1bA8Za<6#nu-Uy+mYRP94C_kx}kpv0GD4Ikxt2Rxd1 z&ta;_KC_Nk#vKh>z@lQ&>U-#K##YZ`8YHOBL<#A=$#@(UOigfBD+b2XR{tG zs4pGSVdg#XLP1*#f_UPk@_GQ}KVX}&Wh6fE2>Cd%ua(=>?=fOsQi1bp+19jK4V~xD zKx>^LX_0WQZ|lOzFji%k!iBDEKQ|zlkiem~;KkQvnE`Op9mj5q){KW=gCZ~X?DWCL zzFqt5YKyYtU3l$}t)#Rb+}w^lj7n(ws<3@#rdC_*N;iGs(Ab5hM2^Jx#aOCWHd=~~ zVu?B2UcXM?NE^;7;{~<-gap1(feg5m2!si*hvbQCwioo_xYK?1HZ3c)ux4|A-Usyv ztb|Q8JmLA`LTTK9dy<3CT^l^VBq`WxvT-`K@G*wWJzo+_nf92U`($c<-Lyhvrdm(D z=1vsH__Qdz1EEpn6A1CX%I$5yp7Ef#$o`J5^;-_%4R9u^a`&^4Oxk*;BGul6=cK=C zUh#rk(jC+zqrfud-d|v|!KC1`jO`j}537J`K?pbuy81ZyX+yDdy{9>A9`|^3N-t?3v4acku z{lr!SH10<=za4JQ70Fq01G0>Xk5c|qW zB1*t`WtVH7e0)T4#qp&yA40`sb(Sid5~9H1iQ3`j7n9?b0utMCyq_( zIzAPb93@kGSmZEP$?$-I&WKo)d)wg&*v8LtelQI51>zpLKOZ0QCHD{$b!)#}lN#em z0$dT16>_0H^(GMaZAEv~$quA!oyta~2gSVVtPoKsk}Sc@ajA?z!q>;-P)-1O+&dPP$J(C zWwtiB@cpKOvqsV4K2BXW7<7>mkJ=|Xg>tM=~Mk>+O!{%m3EEw?joU6dl;xV!mmd9a zPiv%N+Z7#Pwe(>3Eg;|_{`di(%6!7+ia7|du}=C4aRnOUhPe;1T@EyXcawKsutJg2 z6F!x4DTzErVc}D2%cA!}Jm3$H-zSzxSy&}9qu(AeC;Vhz4ZyXuY0$<4%b{B4#Ik9( zm-eKL4epBVc_}OLH$R6%0u}%=P;1L!4h$`4wz60I&(%NMz`);-z&NgJBB9}sR+RK{{J?z~hMKX{QRUTPhM5cQf}{d*C!Ht?Gi$hfh^3ClIKZECo|I)m z$DBP3RDD}j;ikMcIjM2EwSspxiBUmRVw>yARlR2&(t);_5!YHgu=5pj*rYtlLlDUa zT18Oeeb3s7y~fcyV2xKv6DPoJPuFI*i#C+c?Fy}H&NynyH{0UjZ(yB#D&=@e=W$5! z_9GDeUj4nG1%4DL(+8NWkW<^GqSlq`9>N`g@rGKG#JbF{gPRbZ-yLWJ*Hu=pN;c{Q zP;gvfj~LjU2yVNe(H0^>_H;m1>m|ItQNW%QFX^KI8h}QJ+WB;7^Nv!1m)b55UV&u` zi44jo7eia}Aa*suFcTA1p|T5ihQz*9ZJTre;25kgG2Nq8^S4qqj)W zcfaUb&Lg!~%*GeAvAG;t(B&BPyhF+G(ipQdUHyI^qj>u}>f~%o>K+0fDiR3IE;!)V z*>}xj)BwDEpq2sqkII|%NIjOJ@d}445H@G-cPvZ6{N60lef5ag!&T7f8!b^1KMMPY z)n?ohvixKsS=p)0Hxx^{)<*(^H4c=y=H{nKwZ!z~~wAiGoqA9z9cRix`KYH~U^VleUeWGF>z)pv0EA7IPXH;SP%Lg)P8pT;8oo zf@LJH_~)6rS^HYo-Uyre)*oEkdA*JzS$VzQi)0(acz+cl1?rHI|Pe zBHceQRFM$rYzrzuq|;Z_=kcOQRq|<6V7)6oJzzAGuqB{H9R(ow9;e3326|;lK4k2$ z6mDIYtQs*}?^-*?owq}9R*fPx{Cb_)K?h``VFw_awb*=LFnTeuBy6o=!KP?joC z#S<=27eksfQ=x}7Dz`#BY;*=5fAA+nKv=1nj4I>mg={@a!vz^0m>FrhO=JE!Yj1A1 z1+?xuH1i+&@_n?huFIC9h6tt6!xN)80UJ81lmGN8P)YyHsGj4+;hv^eY|VDl3#tRI zh!3iy@Zv5YC%y+vIRsnJ9N;NuFaJSwXEqmwa2*r!s3)Z~QPPLow11wD7H% z+5z+0fH5|va4AenLQkbLF1e$#P3(|xg2QX5@eOVO6&3*dom|vyg2^%`&(M_oFKLMD zYOVk!qt+f$Z9Fnj<+~KU^$P~yvpteYlm+g-@{%n$)jY!$AC~CNbA70pg%fRYqfEX~bUSH{ zBa0ELz(xNcS0QK?gP1!3`E4xbI<)=Po{hc{9qZ0gdGpmvLO|zkp9QsS2U=wGx~GX= z@|vTz#fI)T!6CFklO8S^fZUb-Gv2O{HeDGDy(cB!0ZcCGB7H$tcDD0$`uDt`vheDi z9a2HQk6ROTePbv}uoYP$B!v;GZ8k^v0v5@bBu;hfzNPoZ{#}2oQH&yoJ^Ln`*~N~Q z-bb|*DC-yxB98m*Q^yg+G8tm$8HK+7aGlJK+0e}eeQ7EoWF;x!H$Sz9(~WF;uwhnz zPkkZPnHCl}-FEFhtA5wF4iSbJVN2bj>3*f(`;MT%MmA=>Y(YQo*TSz)MRI8TLcQ4d zY{`=lX_g!XQj-T;lRoLBch`L0p+k7pvmi9Ab#t7z>n(Vx zkUiFYL1L#Fut+E6)CL5!ox|`4f9bl(SVhEYf|}hHUP)2LqEtq<&-CfJYOg$dUSFFj z(Pf$FLY^frB6cq@mzM>Dq7)Ps&h(MPo(GL))3imx&Q zeFs@el@H-{H90w*#~N&+eyH?X4nyO%CVd2~LCh#k?PbBh`UBbn--cN9e5YOB66qfV z`VKIfXQjHp+FPe>ejDk13F+uu8ozqsR8vQwTgStxU72GQ;SC_pYQxg4*Ut_lzC|0i z37*{w!d#EE0~_L4wJv41{T{%cA)duu9$hRF?zcP0y9 zN&aJTByF2Qd}T_wBw06qR>(!X87AS4!Pl52okT8}riP|OK#<(x-eM#x)e#77uB${X4Tmdo(y&=|K77eP0g-Zuf5Bg zm7aA}0JO5-QkSvvR3pkXfRVp8&=lqY@TT8W{YP2?1HxD3&1%mjps(#jfmS7=R|eFhQl$`7qMo=#I_WVp2Q->={Xj^8 z{>Ww2g81u6Xq!DD6g`8+9Kz= zhwa}F-f<~~xK**c5-s+il*A@iTOu#6|2>yCnFHVasM6D_4VdTmnWwDqqiFzzyQWwB zGreo{raSn<748_`s@b%A5wW^c?HGWiIGC~5WzMY@i?GSIjy7Vvy5$$HGavG+4?FiT zFxs~TVA;Zjge7k;r5;qyd07c$ZN{IMjPLW?VTHQs9m80lxO!cVPkeRaDB z#g73kTb*O$Z3zhb63vxT7^tH~ucLS-c^s_X@EO8Oi=vp=)$+Q~L-ALf>J>o;n|x2< z(RUY!VoD$LbGBw&AI?UJ*qjMlPVoTpD9jW1*{SeHAnU{Qp8N-TR3Aq0xtCjO3a6B@ zdWbOU=DDNwo5W=ms|C@}s8W8*O=%X38z?r@FK=qSmUZDU;z3eu2wfZGezG)C;P{o&}K*9&LD47yO5w{#mTxfG+-mY~Dz<`DGu4 zd(at;9KaB}ZgY4-!Kt0uJ9C_z-NE0b-Uf|+8j5jKe;m9xrmsviT2jXr?FcA)Cliej z7hKIbZII)|?&G$x()Io!ZEWXc){|v!FJQPtmGV-WP9(l)o`l%iqd zCjb~vwf$kgiIu4FNc-FY55^0il};CxHM;=+?)xLH24Fx3&eO z8UHVRIR5>+)FjibO8x%TEgw&>RIl#`M4wYxzk0)^8YI&li;h+|nuGlN5^v$0=75Y5 zMqxbE_4>ToVTU=@=`yY@_>0OjSv}Fw`4(bK;e1Fv?%^Dvl?Pf?uXGG424s#a%`=1ul*Z%DyGdij zD0>!(W4$7w)5USWv)|>rvhJIGr&Hl3mbTG>@r9m7uZZZFN*W3~^6~nCo_BP;YlhH2 zPnpmF+J|TMO}5RBAxB{$9Pwd(xv9?)k$dl4*0WnKp#s`V!2l6zd`ikC4Co6~a=2v8 zBb~p^E$F8L?wnTbZyEIu2C8%W(h`wFdbI;#=CzqVNZq7xSfxAhjBY9x5MA>+m=bHM zd8H;u_u#DVQ{Sfr=qiuw?b9VXeoFiok9n(SVLqqPAwbgFO|Kr%z1o_)J(XLHt?s6c+Qeez|pGJ+ws58L=S}d zyFZ1@heYA#e*?+TI!^AeMV(dh06J6O z(&A`Z9E)Waz%A$_VJsQ;rOAsS2CJgwxoL-oIp!RmDsUim7}RPNM}1U6tSoe;NIe1C z0LWL90Sag})iB;V+>^kqu!vap&=?jUX2`E{ct%0cc6-H%D1Um#vqWr$fPxG8B3Su~ zczA4qE0Gcsj{^D=e>as(o`n$;rsZ2N7WN{dk<3jH>V?Vp$1aSiO@B8^LZ=MEv)Lsn@HgFkHP_i z!R$FldW-~@467XZGd?vvnY>zE$rW5kh)mbto!@SFxSc7)c;uB3gi8j>k7|O2*uq@H zvpqXIv_e*3Rja>)5*#}&Mb(CiWJ8mXoJd4BOud$}5Cy!Sy4lykt3rb-hB@C;6{mPE z{^Uo^Z~K|>fTx;rJn4#Ex+le&2!pj~?@*v``#I*s7ggTdkCBuGQwBE#-AZ09qM9-8 z(^6s!6n;zjc_@ZAhwZnU2AEZ~p_(EVPOOm@^~MAD9#WiW8Vn!C>uXsE_o`VI&DtCE zO2#474zPZe6*B6@aqGDalt3P9JadUAZT&Ptn}Y(&BxuoVsNJ(LRmqD+@X@ls{dG>} zYgYY-SUu;{wF_YCCW8M~;OFchtQSKdE#d}BzD%m}lys^*YALQ2`!2aqe$qv?F>|jL+{hpH;zJvovATfs7*|&d z_l~$_vru10SM&X`SjeUpuH+h&m=^GRsWYdW!BxtldXubI9J>Ac@L@u&VP3qBY20)r zWb3atH&hJpL1f}n`-RPd^h2szom`0M#*tO z9$4?r4~p;52ZF*1Kpk1VV?PR0x9zM6PpSrR@gGjdm6Px+ESu48CT354 z-174TqHxp(D^CyQ7sFdijF1&aDi#l+b$vfI2_2HYw6Unshn~Zf-G`GvE9W&OU9RfS z>e|ts&UQ#`d0bS#;HPIL%OkzJ6w<`b1=zx2Z4U_NVZEAR)n5_LQI!OQ217yX1S+rj z9+F>3m{Tb0Fy;`dTJzJCmT^6GAl$mmI+-21WI5QPGg`KO*P25wz{r{)O$1JOtf8~gmh1wDHBA}pJi{lyz^~YTb*WL{o_5jZeC3VAh`P| z?RDO4As6>P{(aIWPT6@VE}Ndw)7bU?j#elCVY5Jux+hdUAW9ZnIZp`Rjx6n3dzn7* z{+8Op?RBxf&}nF#OnoubK*&p8lHel`DSq6mYI(m)|N8tVCd&#g9yzAG&&oNHsOcQP zkYv*(pHa3`lwauJZE?_+6kETizIq`!79C_PYDGeyj_A{esgH&lEIk)R?{=I+Tr~2# zi1wCAj!X_{-HxX=Vg?quTLEW#A?5SE{Q#v)2zb`@WIbq$lvQXAa`xs`Ef!*p(6)aW zP;jm7#`s&$Rj5dmtTj`%-jnp1Cr!~?Vg2*;eIJE8J~u|XK0@5)@jo!0^q3*CYILI@ z#Hr1TajP<3D3ui%Olt^^la=_*%&B9MEX`8nPOJTv5o>4{gV;!_s1IsavB(*CrPLcP z`b!?DxQR#NmegxQ&I_MJ*^vpNTqqYZFjYf2Xn|z^B5rEoA2dQ2cP^DD-(-#tSnt{_ z#mE8F=~;Afr#WoGceg=%SKa>vM|+|HA+u()uAVSVm{6$pK6X2Pq)yej`4>g$)Rt`r z9i#r)j=`ombcH%JtqMGEK=4VaE9AbYHN60{B*Vrb0jT(cEJ}y25l@tAwniF#z7pHf z8$JmBITOi(_~q8+AOdoB>4h+<-ffurW6b(nqXSxr%wtBjPf+Ej0^XQx&q5t+oA;CF z|DSugfYZ65#FbM?@JCN9Bw#6$l8^1i8KSC8LpEprcaD31ZgrRU*JJw3>GGcfuidq; zG5r4g+>K}A2Pdqgdkb@?YkG%~k@gD`BV;K`NEDS?^nz%5p85nqng*KG6XX?8wV4~1 zEUu}9GYUvFIgIjvkBW0UOGTzgr@Y9XT^fW`I`rPugWOQK9D-}(P=SY>ogwwHJ{;bi zws;|XdY#bpgVJd_(Vzc-ml9&?lWu`E+$Nl#U5I&_?62_82PC*vrb`QRZP1{Ka$#kf zTQ5DRrWPEigD#!i1{O|ysL#&6q>%@;$?iE`GAsCJ94N0_gJ$w+l_QHJxKX;PB;3|c z!OE@Sj2)5EC4j69G?h$;Nd`QwTI)$o1FMJ z*((JzziS@LDFls`#+*#!@7h+#Q;*Hwl{zH(0L5|khYz(n=2b3qJYpJ4Jb@@*d*t%= zu}eHgH+2Q99tn@!xk8HwGd!bQ7<~LtF}eUmkTp_0TyN5pL{muM4`4~Q7@0&}e|;e< ziML#`0YjOd*oU;HTQdjV&nK*x>t#J;mb^M4dex;y>A!eBCGZxjejL)9Z{6)IiomYfG{?HQFJC?-F zL12(pwuBj?5{(f*aP!4qaiPxFao<6@{@{hK=p#n)+QRjLpr&|a8ly!3O}^eKdhm!4 zl~DcHxHSCN0{s~n)+NdjQe=`*T$$`oe6-S9IG+XPuasxgie=blS6u2-i#PEPi_zyh z*~hP9B@KFg$_I!pq+_Y~C_z(qgM?Omrcej4`i>L~EX$&$F0Pi+vH@9d4XBQWq+)v$ zzc7Dld3)V$yIePoq;T4);2MG8TIdog73q!BsEN>%v>qq2JfL7pv&U1HQK~CyL~F}T zv8GNb%x+kK6$P8=eG&BAaUb4=V*Y|a=fs)ibST5cU}>)4YJlu~_RKhSVPQY-Tc4^zt- z-U{Deen_>ZoS5DG#bgxkt#!N-zmI0nN87Kns(YCWKeUb%8y0orYEr8Al+q$-kdQ=c z+9W0jPM0wyeX$+VgNso^+hV8Eqrn1(rgTtlfo_+%Tx?S$fG%sMrUTeM5edommMgGdWY~@;q(-($h zo(+w(G4m&xBWuiyVuUkqSYN6h|GTI}9uJ&xV?8BsK46m!Z5R={jl{mHkoSk6A_{$yW6w*L%~pKpwI zdztfd+T)o2ZA)fYI9u^Q;}_%~qfvY!9;VqmG6yg#{xfdJIFp>elRNd-7i#xV-=z89 zjurXgXO6KN(L9+X-|Q54zS8Sp){o)xBMKrR^RGD0|DB}-*2ciwm*iDcY9|`Tx`Low-Mxj)CWQFFTg=RggpHMm7*@WK5{CmRB-M zoYKd_SVExqaK_4q{%>0qLnGPfzcMhqpve2)`JbM|(SKi60;l-Vclp4O=p$79vsM4o z7Q#5n?d0`;N6tE9SmLkXBR^Y)QHe~^9pAEC{u8PGW4H!Eq?p&EYCkEKU4lcZOs~+r&SxV2CedM)Ir6=fr>wU~*2%n&C}Dtg@!y`!y8X4PQhv>;@l7TEPX6@Q3_!7L3dZau zT(!r#$9dPK-=0@Jx&HRkvxnfaPRtW{r}3d-t8X4frmf7|uR3R=45YWLgy>NS?3Ve!x3$)G~k zdW-r(8&Yxye*L+`H|EDwnPgsyv@JGb+Z6sQfd9kZcYih2b$=?Nphy!1DH4i;g(gbq zgrWpQh=__(l_I@^w2%l0h?LL~DFFcy5s==4NbkLc-g`@EfsoA2xMZu?W@$%5l8p)lntSzUh41fO{Ux2ZMjuQ&{d0xWocAiBn?xS4v1~h# zV*dN!x#GNpgNc9SCLAT7sY}jo%Wk1qK%Fue!%KOx%?fN(?s<>0l;Z(*cQR#5ju(q- zm0>P7r5K>fbkNhv?JXH;)$-O)_5;P#qol2fyRhf>>=fG6{vLvvT~ypY{FN*X1KgDr zM!BRvFS%KC!hlu|5o&QhE9CE8uwihP8H;c8KUXw|ZDlW!$wls<>UaFDgzfx3H4dw{ zU@2(WhFjN8$?37f`uDXZGt?tuNiIex%3%x+pObmQ?mrSm%6Yl!Cnb7xEmTySN&N0N zb9Zyw(-|D>w2#UnlE)>U;WUGPV^56t$hUHHJVZHtv9x-j2pgW4p|^8*0~C41F8P)m z*G4)DhgaKEvu5>K_s~)gZIXYGQDSj?!qlvRz|B*C2Ba&c7sybR7iU>N{FQc=-9^H@ zn|468C*?FcuablITYae%8&$yXYUYraVw9U%zjgI?-XcRd3UB}7`72EnI9K78w`wZbZ~x+< z>)@cG*tOEe3Z|RXi(!-jRhQhWadqPtlW%%n52q-cLxLEO3AJAE&HhJyj;RW~C>i2T z9}Cyv`}@2{YquxcDFRv3r#NU?)7z}oc%RUQK6t%Ba=2~~!k^FS+n8OySZvZcFbD5Z1xV;vE+#B)S_blZPfc8pF2AZSys7jcNEq-U^MGYrtAETTG#f<+N zyn7g|QK_YeY5AUmHtXIj<~C$mz49Z+_qB{|hzsD34o-^xo;DULzp)Ix zsu9UbMW;e>{+m^H#LyxVEb!ud`V~2Po~ctluy|^$+Bb|*=6`itK^Np&&w*#o2{{>2)uig z>-+ldkDq~;fm~CgSX=c^i4?Aq`DN0h93_6Hzp?!1<)>n%mscq_)9EZNFUF8T^slbG zWcn+O&8%ZEMxOr(r;_(Mc;%`!&u50QSp&cwcvZ@PCb0=dm6gn&x#xbo!TiU4`F3$; z0lx<*pESd^#tHFcbXDLZ%&q_APNv(HEpv*%kX{FR>JV*ni3}juR4KNXyp-1%IUM$T z_L&|%hwtB5W^Q_#5%BvDMOppNGEhkXsVrN5{Pz2+eJzh^-nVsj0I9I|ru(1ko~d&k zVO;{;@mZ3hKYpldw{I})_wH3)di=w`28Y`fUB5&9?H~26;Y(e$|3crt&_@ZDf1&RL z`7iYS3w{5xzJFQYzpU?H*7q;#`?uizx8VK%yWsti2h>*I6jKG1byD@@MCqu^$?*?$ zZdd^IFQq8-6B8}$;z+u9|5H<dk)3$XN{ww|iAinC9 zF{e^hs;)VuG8Uj6P!wZ%7;}})PjQqS@Y^VsmFl014aBG|h*Mkh6^jSxy8NS`l++l}az%0Qu*{WS_gG6A z(EYmW?R>y2L&1ujsG-yYK>1#0poQUQ6e|oER-L(g2Wvx9=1_}>5R`fLf>Q~qWCZ+^ zR+v)!g*F%X9bMl)R%Kx5Qh?~m=t+=-4eJLn(M&gwA?K6Z?f@e8c%R_YOO~qv2i-UP zAKTui(#0xHG|R0V0YV9T2vMOLk@{;IZW~x_D9}(|K~9*mGS7OlO&t1ZJ6#bqP{(q(kzB|Lz5FHuLMN+dwvH4BD3DFulA- zB>~YZ+V95hbCA0}4QRWTFuPv99s2?Z9$9|Jg-@MH|HO!Qz;F-<-cvg|cbt131%fDe zIFjoPxT}Y12y?Z*9}X~k_MkB?K!5H}{0M9QW!fh%VxF<2UAa~DMGp`a&*gj4g%Xi| znf1wdZYrDUN}V5&i^jj4bF2b>uQGin^sYX`sQB9u$4*!K1I?1NHMjL?e_lR~w%1t3 z;D!Q7g6clDXO=fP9d;e|@=#NDa9 z|G4A#BPL54drbsB7gp2fjCMGlJ~{YOeCJxH{)s?DL-k-k)2^p5I&M+#0Ij?V@2j~r z5I864Z_Q)r^aEc4WMeHjOxK%&4BWIGNW^`{q;Jt*n`$X-Qam(u9Z8b8eV)$OjSmQT zw^bixZr+Xq+fN&QOSat~w!FWdP-}6P2X!Kjc30|xK-FY%!i$5_?oKv`V-LEU>VO3Nj-}dKCD<=qITN~A9{R}mER_VaUci@}NC0~rXK2m3E-7JY^rD8E*dP$= z%vZCXVMvVu>ynk9KwhA)WPhb(ofR|SisD1o16}~B=$YAFfYdYXxs6qReSm&S+3 zW58!|16#62Gh8L<{sF};Cv|u@2R*4kS2oQDw;5$hh-1oO?4{}K?&dvRxMF5F;S%WM96#Cf6(GAQ( zs=2y}l-%K@9s)zK=hEAseQT<1&&ZA1s|Fwh;_x8EnD>_vwKbyHXu`NDj$(wN|HBBI zn4QJCl1+#gw#S~7w5MZhM@Tx}LQBe!&YME$-4DVfWk&N38k_B}kJ4V6^l-te_AcTb zw+^hsCPSMjQ1R0-H)|PAr6_#`utkuMWTwnn_D4 z`+`PDTy83sR)+akn}HN1earoFJSpiLPW#ga@r+Yx$x`N?*>gs!&L_9LFJ~_zy{W5y z+@@wl0bT$$F+3~r3wUtMtN-J{MUEK!s&FcP{8XQr1Ba){1CQ-#Qr#S?oAjz;zcwHR zf<$cB9d9KQiX43cCSZ2dXM-C`n3%2)u@676O!mruK^YnNKTjVUX<4|XgRgB*&$)Fy zmoRntJ8QS{>s-oYn){_Tbb|t1xr6_qWUuL{ao`RbP&IOUeWhPmDk)cOm9U&nu@k@l`y1Wnu{I~rOE&JZ0X~BNmn^5-XyoQdd~X?TPV1p-bSbXwH42 z4yPey22WN5;#=^&&MSbW^E(bGDvTd0^#=kI!ZHLMC+UT)j_z`(-p49|b*p_`j`xNc z^Neeqo<=Hkp9>57GWTb1GuqL;5>|hnanqg5xO-?zW{lDNzKy`m(q|5+OoA;Bnn4ij zXf3IH-)U;c+crBuqKO(c4*phtJp-t+JiRc!248~GNhbLNshBroJ*7@b#SdBwSEw`; z0n!VM!|xgz$!Sd-JKO(XMq%r#DEoQrvb6PFmbv$SXGH0M68StBZKAQgA6~iby}vu^ zOCH^MRjyy=02;6Mykka#;#OGiHx{_4g#$;-A7I?}b*+n-Gm^@p^9-vNcSpnm50r$d zxk60Mf1dUQ=$BIaV3YFe6-q{YBJ}p<0#KD{Q;v1N1lUn9O~*6f_fx>P+MTF4llG5S!(_HOa0^gRt5F=&Tbb=T$#`1P1Nv%brQDHiar3;rq}1f=8?1msaRrIvFEGyl8p+$+w3^< z_gN`arV|y8u<^p+(?beld@@kN1nH-1I{)gMm|K)b; zd`!QTW`sZcpK+j)-x@3KRJ8BE!6^?$U?U_$CYQl_wwHjk^`>#al#IF(ru`2XZ3nJ* zp9`6$Ps0=C4DWPnFKsN1am%lg1iz1EaGVoAa^QW_Aut-zO)wr-bR>OdZEp7mbXe$p zuC7OGz)hJVdj}U%K!)7jV_JP2 z0!#38UeDi^(iU^xly;cvYpp1AHQJh-XU4)}&G}md`)p@Z;{}?wdefm3s;&O~5Zk4dd}tNQ)E4RX5`2cT5`v86DpTZ6gl8p*pkQ zSORAm0%s}CyO4lie(n+1KHqEZTpUljVNhs$^aC-rKT%qv9v?Wwd$IqxVNs9}936`b z&Nmp{)*v0t7LxZ?s`ca~sIody*dQfr_Y8u#(|kg-yg5~}8C|#tg`O~)D1Z`S{ee@C zh!`5}Lj`<#v!P*C;NkFL|F%Y@4W6GIdGj;KO{*Gm5bcal2Gv}48xpLGj1b<>qLZ&B zOubrg7=wGsqS8k~k@Yg&K?hE5FOJ|$~`nIt+ipvy%gH4@fOB#D;oe&jw`D z?j#-Tca9^(kEXTRsH>SN{ECwsyKB_k3rQ(?uft!+xgh%>C`pB;raS2&8hx~Dapb$Y zGbd=6;E#wX`S`}qZ_%kt8V}G0cZXAU!0Aw#0`p<1Srfm7Zl-JP-MnKc-$g%v;&!kI zYc9^h*FJCu=J~a&*ss3*f7%x}GE+_x5b#1R4{WQ)099!9a3y_e&#MMz1({hL=Z%J? zx)VlkF0WZSvNYNk*fOo4ukpx{flx7XeuGKNT$#Vy z&2q;HqmJBrn+r1-gpHDa3>b#Vvr&fA8;jM4={O2v=cQ%(&NI`l7b!IeIUUWQg=-#GEW1^)%ZSHthaE82HqE>?xf9nK>I-L_hOVM> zbS2TxQJ~2TJ21;O3=)x&u8Fd>$aT3bBYvZJsjtQ7nUI~@7)#2IpwzU(iL#LJ$}DS9 zhAC)VIr=4iufM5SKgV3lbB{>{(_Oh%HCj z?J%Q7Xq#nFMT`q{m2L|7`Kje44Z5xQkUIt!sd|l%1dltEzV5oX`n}W}(ip>xvxJgH zeTbY`7WR87Oi;{zqeA9Gdn-21cluE88%; z5dEWb$;%>@G2OhLYt4NAg@0o2$PB%$hjIj&tDMj60?y<%x1X#Y#dFzHC-l&^-7*zh zcpx`nJ=6FAI?*R$jcJ4%~YnuPEuJ{ z`^_KCWHm`^jaMm4DPKp*SLVf~uu+Znv=S{_hPeWa3r@XG=?P4$EjZsF2xlnMlwIXQ z3w&HBJ}v;$QJ-n-YFS{} z-6~RS=ZLw3xP{VnZ1G?ncV@h#x3Zi`muAx*1Z^)9-jb71R$*&;VO3^7u{x}^9g(tk zg)!s<*sXF>qFByZO99UhY*wERztP0@`r8+fl|I-HckVuWQR$7T%BV6wtRkC*A*4_B z^wfTY{k@BuUH2f?R>jBGy1JI)kPEdV;o=FPUc>dd@=6^eq15&QbwUREkyqm}^gUwb zOZe{SvaZ(<Ffp)?wPup^2KX;p3tWi*S*gEgk8@W;6qyeZp5VQE*3p^@5e z&xt=Wr%iZS{%u`oz3PQPAm7$(nD4VS23NkGMnm$bX+&k^N(R_jF7mbSpPZ6Eorz_Y zO8Z(c5NE`s%>4ywSm&cGe2^iBSE69wrKBQG|1|jiZc}1nca5jsT>2)`T~3{&+44Qq z;k21l#GGg5T-LR9F-{4B>!VdU4LCr0t8kLuPhsz-ZJe4tSq=VVojfq=TLf)^nL28H zveZ2+{j;=RkO=%tQ_Qt#wX4Gnn42uL66y3lM8&>_G-iv(%u8~FTSaN!ZfDf7mCB>! z%3Z_Ui7URc6XSE(5PIwC4j21(bYhe)2E_1AXHwm`(#P&q(JvrQN#evSNyL}0C)tvz z1Sp=Lapa||y5Z<|>m?{|R$n%2q#I>0*1_D=h1&Mcy)!0i`MK5&FH6U{2%Wsd(S^e7 zZAuy+IhvnE)b4frn4BcB`%YiIXjn$0it{VN>slEbQp>tDE-4L+)7}_1NhkV-wC$RZWnK_p>ET*O`UM!qY59!N;L&5Ia46 zXyRladck0Hshe@C)V(vMb)c(iFkYs&9Myd$aXHF8PNqBYTdw!Vhk5#6_LGFtMpZ?s z^$_g(JCBV*V5?Cy7Q>Fuy4*OQD!7VurzP!jwav|8RU=+v-`W>={u=so_tl4iEiS`( zXL&H!^P$QR&r{OWcrH9Yo(sLND}d)OEN5k`_v}DzcMw~QFVU{Hz3tKFRFc;eJhobc z9$s7+isSlK<97TG0{PSbCDPLr*bU)gbXMpde*qJwUgnR!5Mz_DT_R*YTFzPeLn$2n z1mdldIw4S2?Mmrl$&poVVJzxu1DW88^q6ke?L*J8HL&+Ga7M3?6r_3x1!PFAMzrOJ{#JERD_OIpiD^4GIpwl+|y~)jP8^H1DG9 zd9R6QXceDM!+50Svw>X{=H5+leNH0-UyLK0f2AE%CijD-VY>Y>l@9UP_ zyk_3it%fD3?hk@18|A)5u0G;(^k`mTPrGr!caTF6TMDGMJmA-y8P>sTl#JNP!-|}t zswebniyPN?<&wwsh;+vDxyGcHBwzHS7JZ08q-5Axt1)}3?Eb9D7OSoS%!-gG-L*+t zaR^_uf2efJZmuiTUH+XP4EJ?wzJQ)rMs4)dL6D-W3T!t@ z;f^8F&5ZveCJLtPxol!FrcrZz2n`=$lje(lsV3W~jJ>0!hj!wH1RYq8Jp)#$L@#rg zi+_-kcrU&_#1!b+ii)&N|8N_xPAzA(v+gN*cbSx)wdS19boDdK#VEh5%SVlVs>ZId zi9Gku*&&69N@bCKw@S9E(WDLw^Sv|WVH~jfZw4g6mg#U*Cy&=#Mgf78m{>|vtEQhV z@m}89t}Zm6{`_xPf_p6?Y%;}Qsg>0~M-DiPRv}sZd;e^www8?%`JjmY0zmV|2Bh-E zf&cN=?F-SWprQO-JEx|A3_P7(txbPPTy2B^7u!L?1nltRwPic%OoQd2EAc1!8dGcb z8zY2BPgM6OF1ABv^v17IXV3(lag3yMxYrK}&sW5&_U9Hfzgob29=YRRxarptv=<%V zx+&MgkaHUNVk=0k_2Ro+WaB-|uLa1Wfv03nJwY38y$H3FZ)I76KTdw={qYp>wM~+3 zbI&`27*SDQ`s>Dp#1PtEB$kOYSgu0hQR#@L2iHRvJr2@vo}I!(bU<7SRX6Xq?3~y; zCo9F3w~=|YNn0ndb(~PHIdmmH_u36Zq3HzDstlo(#eviILm^Rx>#%Xghr1VPAOKdaf@=#9*UPm&CYiV}+uUD-E~?LWE`Hq03QI~P>%JgWFG9Cj z0*$RBQ)tY)3YiD)NzcJtL*(`nL4?N!oPM!osEB5$jGg*cw%|Rh4XFx4MoNljS+7Li+5aMEr-rEx zp%22(+RX##WBNo^v*2#H=_g%WIPGtUe-bRtETRq^LX)i=wEN|DrK^^whuK$VJ@{8y z7;p?xlK5zbb|Aj(ca$&b&4IckEIgHMTPY+6H+6V4?1kB2aA&>SwUeeMmDps-Y1(uZ%x5z^n_Z9n>nZP6KBt-KAAZ-FfW>l@j=23NPGc9&Ea zom=Se1;6q4rSX#yJ$6n3CxNm>gJj+mYff0iI<>kwy8OOJC*KuRe$L@;^|exC z$TmA}22J`1TN^o1AmI`x&sBZs4^ za*+e7PlAw_VcAY{UD4b(pewDW4NDS{qk|XYo=tK>9QO?S(v{Bz&Xy*o_na1(CZENM>TiPk_B8Eq1}~JE zCzV;9JUsBnEZh?+YK6d^Z!i28%Ir2o@aYBL6B4&20T4PgORHxon4B)%=?_FGOmrq= z%Obb$L2$Rqs2ST{KDInDz==cJmf$M(NtSEs92tFi>-es;CXy8lGiQjZcuT{c;AA7P{zbb zV+)8_!+d?7Br&2EA{3ck!_Z}38&TOY1K&cL#0LkpG{i-1a@ehRNsP7mDad%T!W*f+ z%-``gFqGdp4>=s6y~L-o>ZBPC_vN?MV}B~*$;O!vTVo5mstxhubz&$?VNc*EOr zFG<|e#Jyg|Kz9U0<;qdBsHsrWufGiiLi*@w6BK(|#cU4= zh_#%2((UF~d&pBGJ~9tI_JYI05G(RDUQ2$JL}L_>VMHKWGJr4MOGm`qdzNiC;ql1) zjG81&-}bOT6kV)gNp6w0x}q`-Kj+sTvS5FvZo%%LQ6sOrd8>G7hdmgDJAEtb%B`^` zD?^X@%1n17bl{z12fOsHc>mu3mlcOdUxVo9CE^qh!aGmzz zUUHNeYoHTu%%h7OndNg{8kV#>@-nZvVY^ki+__F?9J>%`e@~ZvC|=xjRTwMH>xemk z6m&P(Y4n4lS*xr!fP}IchK}%&Z?gsxpo6h8TAw8MK=#z^I)$gQxj@NbsV(7e$Bwk3 z%oF9Diwmi{TfUSpTsvy8n;gNHBHZZrsB)I+bK##qvHan$q({#;Gv4Z7oDt3l%QcE( zJ&JjVGG@T1gB=q0(xV;6;b#{ePt;EQWMc23cT|hS28lPz_hauve%&QAhbMx}Ngo!! z6PUT{WV{}5K8}i)@=UW^`E%#49&d4CPN#$Ay!phHZ@D5mBJXDOr0?7I%*YUg$ud(Q zs$FHlodfH)MG3HWw!q4VD#%__Sn*)@<{U`+5?}sWQW;^x6Q{FpGOJ=-t$6~xfovKS1)BpXK1q0rB6;M&IlO=>4(Y(3eW|uY9!;D0^uA0O}PLm zTw$BH#7CjUP1oc^y__?Uv+7+9T`m)X-1z>|g{x64(XqOWKfh{N^(MT0&z~&a^KgHt zJFPyaGa5w7716`oiguo*c57v8NB{+Vn;>fIjs^A)p+eG z8VNb4T*GIMw6Sam0G9sDl}q7&6aX#5Z!ElCmt`;Y%wJuln#eoI_khN)x+cH$nm?a{ zGY#p=EL%AKvsc7MJ&oqSqG~a_d_zWK>VZbSux1+y#c1aSA64< z5yDiUEvJDP6C8Q|=O*v|rwL2&DJ`+yV0NO{{rdN;ecU7tY4UE0o zq@lIrgyW3ofYCZsu-$n9StD?un-Oqrc;^nc$Bz8rusvqKZC2I3q4z>oCuDLt<;C8{ z5!fTO@lRM;sJMeh&5pZCU6zMF2X1jD8UF>8skQfz!6|&+g2XCAsN=`A<%ltyHhr_W z+obfFp`hFC=ydf8KV2)>FG@0Re;s{~E1ejokquH-iOQv-5b!(hFLSeT3j0^EyTQ8~^JOOjZnO6ksw=f4 zyy~+SlJPy|T6)U|>{+B1ri$PZ=a2-I#3_KhV89HO)Hhj*M0V$c4CB^FYg>}JTe+_$bF?3Uh$KfcRfvE^j%!~MbN2BMrmL5rxwh~N z8W#&h-}flz%~CUa;_?5rDTj8DYxxm0wOX{g+TUwScmVUGEu=3A}+hh65Ab1nsn zfCs{YKEg4%J(pts%`lAN?{IS}HGCWHwJ#&Cs2R5r3*;qyOg z^>}94KjuQ9JED57tCE4ZK0HKXii zJyuQueSOgAJsQp;#AOUNd0&
    sZAQ&BicR?YhPK2Lu8D}Fn8GqX7*YAUXtPBS0` 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�$IAB_*aZ& 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%0Ao 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� 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 diff --git a/docs/zh/api/02-resources.md b/docs/zh/api/02-resources.md index 440e2fa3..fdcf201b 100644 --- a/docs/zh/api/02-resources.md +++ b/docs/zh/api/02-resources.md @@ -45,6 +45,7 @@ Input -> Parser -> TreeBuilder -> AGFS -> SemanticQueue -> Vector Index | instruction | str | 否 | "" | 特殊处理指令 | | wait | bool | 否 | False | 等待语义处理完成 | | timeout | float | 否 | None | 超时时间(秒),仅在 wait=True 时生效 | +| watch_interval | float | 否 | 0 | 定时更新间隔(分钟)。>0 开启/更新定时任务;<=0 关闭(停用)定时任务。仅在指定 target 时生效 | **Python SDK (Embedded / HTTP)** @@ -168,6 +169,48 @@ curl -X POST http://localhost:1933/api/v1/system/wait \ openviking add-resource ./documents/guide.md --wait ``` +**示例:开启定时更新(watch_interval)** + +`watch_interval` 的单位为分钟,用于对指定的目标 URI 定期触发更新处理: + +- `watch_interval > 0`:创建(或重新激活并更新)该 `target` 的定时任务 +- `watch_interval <= 0`:关闭(停用)该 `target` 的定时任务 +- 只有在指定 `target` / CLI `--to` 时才会创建定时任务 + +如果同一个 `target` 已存在激活中的定时任务,再次以 `watch_interval > 0` 提交会返回冲突错误;需要先将 `watch_interval` 设为 `0`(取消/停用)后再重新设置新的间隔。 + +**Python SDK (Embedded / HTTP)** + +```python +client.add_resource( + "./documents/guide.md", + target="viking://resources/documents/guide.md", + watch_interval=60, +) +``` + +**HTTP API** + +```bash +curl -X POST http://localhost:1933/api/v1/resources \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-key" \ + -d '{ + "path": "./documents/guide.md", + "target": "viking://resources/documents/guide.md", + "watch_interval": 60 + }' +``` + +**CLI** + +```bash +openviking add-resource ./documents/guide.md --to viking://resources/documents/guide.md --watch-interval 60 + +# 取消监控 +openviking add-resource ./documents/guide.md --to viking://resources/documents/guide.md --watch-interval 0 +``` + --- ### export_ovpack() diff --git a/docs/zh/api/05-sessions.md b/docs/zh/api/05-sessions.md index ea828944..48cada3a 100644 --- a/docs/zh/api/05-sessions.md +++ b/docs/zh/api/05-sessions.md @@ -328,6 +328,71 @@ openviking session add-message a1b2c3d4 --role user --content "How do I authenti --- +### used() + +记录会话中实际使用的上下文和技能。调用 `commit()` 时,会根据此使用数据更新 `active_count`。 + +**参数** + +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| contexts | List[str] | 否 | None | 实际使用的上下文 URI 列表 | +| skill | Dict[str, Any] | 否 | None | 技能使用记录,包含 `uri`、`input`、`output`、`success` 字段 | + +**Python SDK (Embedded / HTTP)** + +```python +session = client.session(session_id="a1b2c3d4") +session.load() + +# 记录使用的上下文 +session.used(contexts=["viking://resources/docs/auth/"]) + +# 记录使用的技能 +session.used(skill={ + "uri": "viking://skills/search-web/", + "input": {"query": "OAuth"}, + "output": "Results...", + "success": True +}) +``` + +**HTTP API** + +``` +POST /api/v1/sessions/{session_id}/used +``` + +```bash +# 记录使用的上下文 +curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/used \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-key" \ + -d '{"contexts": ["viking://resources/docs/auth/"]}' + +# 记录使用的技能 +curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/used \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-key" \ + -d '{"skill": {"uri": "viking://skills/search-web/", "input": {"query": "OAuth"}, "output": "Results...", "success": true}}' +``` + +**响应** + +```json +{ + "status": "ok", + "result": { + "session_id": "a1b2c3d4", + "contexts_used": 1, + "skills_used": 0 + }, + "time": 0.1 +} +``` + +--- + ### commit() 提交会话,归档消息并提取记忆。 @@ -501,7 +566,13 @@ curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/messages \ -H "X-API-Key: your-key" \ -d '{"role": "assistant", "content": "Based on the documentation, you can configure embedding..."}' -# 步骤 5:提交会话 +# 步骤 5:记录使用的上下文 +curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/used \ + -H "Content-Type: application/json" \ + -H "X-API-Key: your-key" \ + -d '{"contexts": ["viking://resources/docs/embedding/"]}' + +# 步骤 6:提交会话 curl -X POST http://localhost:1933/api/v1/sessions/a1b2c3d4/commit \ -H "Content-Type: application/json" \ -H "X-API-Key: your-key" diff --git a/docs/zh/concepts/05-storage.md b/docs/zh/concepts/05-storage.md index 495bdc38..3fa4256d 100644 --- a/docs/zh/concepts/05-storage.md +++ b/docs/zh/concepts/05-storage.md @@ -135,6 +135,7 @@ index_meta = { | `local` | 本地持久化 | | `http` | HTTP 远程服务 | | `volcengine` | 火山引擎 VikingDB | +| `oceanbase` | OceanBase 向量库 | ## 向量同步 diff --git a/docs/zh/concepts/07-retrieval.md b/docs/zh/concepts/07-retrieval.md index fc0a11d4..4b4e50ab 100644 --- a/docs/zh/concepts/07-retrieval.md +++ b/docs/zh/concepts/07-retrieval.md @@ -137,6 +137,7 @@ Rerank 在 THINKING 模式下对候选结果精排。 - 配置了 Rerank AK/SK - 使用 THINKING 模式(search() 默认) +- 如果 rerank 返回无效结果或 API 调用失败,会回退到向量分数 ### 评分方式 diff --git a/docs/zh/concepts/09-transaction.md b/docs/zh/concepts/09-transaction.md index 503ed683..45a10d63 100644 --- a/docs/zh/concepts/09-transaction.md +++ b/docs/zh/concepts/09-transaction.md @@ -1,167 +1,362 @@ -# 事务机制 +# 路径锁与崩溃恢复 -OpenViking 的事务机制为 AI Agent 上下文数据库提供可靠的操作保障,解决数据一致性、并发控制和错误恢复等核心问题。 +OpenViking 通过**路径锁**和**Redo Log** 两个简单原语保护核心写操作(`rm`、`mv`、`add_resource`、`session.commit`)的一致性,确保 VikingFS、VectorDB、QueueManager 三个子系统在故障时不会出现数据不一致。 -## 概览 +## 设计哲学 +OpenViking 是上下文数据库,FS 是源数据,VectorDB 是派生索引。索引丢了可从源数据重建,源数据丢失不可恢复。因此: + +> **宁可搜不到,不要搜到坏结果。** + +## 设计原则 + +1. **写互斥**:通过路径锁保证同一路径同一时间只有一个写操作 +2. **默认生效**:所有数据操作命令自动加锁,用户无需额外配置 +3. **锁即保护**:进入 LockContext 时加锁,退出时释放,没有 undo/journal/commit 语义 +4. **仅 session_memory 需要崩溃恢复**:通过 RedoLog 在进程崩溃后重做记忆提取 +5. **Queue 操作在锁外执行**:SemanticQueue/EmbeddingQueue 的 enqueue 是幂等的,失败可重试 + +## 架构 + +``` +Service Layer (rm / mv / add_resource / session.commit) + | + v ++--[LockContext 异步上下文管理器]-------+ +| | +| 1. 创建 LockHandle | +| 2. 获取路径锁(轮询 + 超时) | +| 3. 执行操作(FS + VectorDB) | +| 4. 释放锁 | +| | +| 异常时:自动释放锁,异常原样传播 | ++---------------------------------------+ + | + v +Storage Layer (VikingFS, VectorDB, QueueManager) ``` -操作请求 → TransactionManager → 锁保护 → 执行操作 → 状态更新 - ↓ ↓ ↓ - 事务ID分配和事务状态管理 路径锁校验和加锁 +## 两个核心组件 + +### 组件 1:PathLock + LockManager + LockContext(路径锁系统) + +**PathLock** 实现基于文件的分布式锁,支持 POINT 和 SUBTREE 两种锁类型,使用 fencing token 防止 TOCTOU 竞争,自动检测并清理过期锁。 -事务生命周期:开始操作 → 创建事务 → 锁保护生效 → 文件系统同步操作 → 摘要和索引异步操作 → 移除锁保护 → 事务结束 +**LockHandle** 是轻量的锁持有者令牌: + +```python +@dataclass +class LockHandle: + id: str # 唯一标识,用于生成 fencing token + locks: list[str] # 已获取的锁文件路径 + created_at: float # 创建时间 ``` -**设计原则**: -1. **最小化锁粒度**:仅支持路径锁机制,不实现复杂的 MVCC 等 -2. **写互斥优先**:暂不实现读锁(共享锁),先承诺写操作的互斥性 -3. **渐进式扩展**:避免过度设计,聚焦核心需求,未来需要时再添加更复杂的锁机制 -4. **默认生效**:所有数据操作命令均开启事务机制,用户无需额外配置 +**LockManager** 是全局单例,管理锁生命周期: +- 创建/释放 LockHandle +- 后台清理泄漏的锁(进程内安全网) +- 启动时执行 RedoLog 恢复 -## 核心需求分析 +**LockContext** 是异步上下文管理器,封装加锁/解锁生命周期: + +```python +from openviking.storage.transaction import LockContext, get_lock_manager -OpenViking 的数据操作命令(如 `add_resource`、`rm`、`mv` 等)存在以下无保护操作问题: +async with LockContext(get_lock_manager(), [path], lock_mode="point") as handle: + # 在锁保护下执行操作 + ... +# 退出时自动释放锁(包括异常情况) +``` -1. **并发冲突**:多个用户同时操作同一目录可能导致数据不一致 -2. **无原子性**:`add_resource` 多阶段操作中,某个阶段失败可能留下中间状态 -3. **无可观测性**:操作结果无法预测,用户无法直接观察到正在操作的状态 +### 组件 2:RedoLog(崩溃恢复) -## 系统一致性要求 +仅用于 `session.commit` 的记忆提取阶段。操作前写标记,成功后删标记,启动时扫描遗留标记并重做。 -从系统分析的角度,OpenViking 要求实现组件间的分布式一致性: +``` +/local/_system/redo/{task_id}/redo.json +``` -1. **向量索引的最终一致**:所有上下文数据的向量表征依托独立的向量数据库或向量索引实现,要求确保在任何操作序列下,向量表示的更新都能实现最终一致 -2. **文件系统的读写一致性**:所有上下文数据的文件系统表示依托 VikingFS 实现,底层为 AGFS 桥接的分布式文件系统,要求确保在任何操作序列下,文件系统的更新都能保证数据不会损坏或丢失 -3. **队列和异步数据处理的一致性**:所有上下文数据的异步操作依托队列实现,要求确保在任何操作序列下,队列中的数据都能实现最终一致,即队列中的数据会最终被处理,不会丢失或重复 +Memory 提取是幂等的 — 从同一个 archive 重新提取会得到相同结果。 -## TransactionManager(事务管理器) +## 一致性问题与解决方案 -TransactionManager 是全局单例,负责管理事务生命周期和锁机制实现。 +### rm(uri) -### 核心职责 +| 问题 | 方案 | +|------|------| +| 先删文件再删索引 -> 文件已删但索引残留 -> 搜索返回不存在的文件 | **调换顺序**:先删索引再删文件。索引删除失败 -> 文件和索引都在,搜索正常 | -- 分配事务ID -- 管理事务生命周期(开始、提交、回滚) -- 提供事务的锁机制实现接口,防止死锁 +**加锁策略**(根据目标类型区分): +- 删除**目录**:`lock_mode="subtree"`,锁目录自身 +- 删除**文件**:`lock_mode="point"`,锁文件的父目录 -### 关键特性 +操作流程: ``` -路径锁 + 写互斥 = 并发冲突防护 +1. 检查目标是目录还是文件,选择锁模式 +2. 获取锁 +3. 删除 VectorDB 索引 -> 搜索立刻不可见 +4. 删除 FS 文件 +5. 释放锁 ``` -- **路径锁**:锁定目标目录,防止并发的目录级操作如目录删除、目录移动等 -- **写互斥**:同一时间只允许一个事务写操作,路径锁机制确保所有写操作的互斥性 -- **事务结束状态**:事务有明确的结束状态,包括完成、失败丢弃等 +VectorDB 删除失败 -> 直接抛异常,锁自动释放,文件和索引都在。FS 删除失败 -> VectorDB 已删但文件还在,重试即可。 + +### mv(old_uri, new_uri) -### 事务状态机 +| 问题 | 方案 | +|------|------| +| 文件移到新路径但索引指向旧路径 -> 搜索返回旧路径(不存在) | 先 copy 再更新索引,失败时清理副本 | + +**加锁策略**(通过 `lock_mode="mv"` 自动处理): +- 移动**目录**:源路径和目标父目录各加 SUBTREE 锁 +- 移动**文件**:源的父目录和目标父目录各加 POINT 锁 + +操作流程: ``` -INIT → AQUIRE → EXEC → COMMIT/FAIL → RELEASING → RELEASED +1. 检查源是目录还是文件,确定 src_is_dir +2. 获取 mv 锁(内部根据 src_is_dir 选择 SUBTREE 或 POINT) +3. Copy 到新位置(源还在,安全) +4. 如果是目录,删除副本中被 cp 带过去的锁文件 +5. 更新 VectorDB 中的 URI + - 失败 -> 清理副本,源和旧索引都在,一致状态 +6. 删除源 +7. 释放锁 ``` -**状态说明**: -- `INIT`:事务初始化完成,等待锁获取 -- `AQUIRE`:正在获取锁资源 -- `EXEC`:事务操作正在执行 -- `COMMIT/FAIL`:事务执行完成,进入最终状态 -- `RELEASING`:正在释放锁资源 -- `RELEASED`:锁资源已完全释放,事务结束 +### add_resource -### 事务记录属性 +| 问题 | 方案 | +|------|------| +| 文件从临时目录移到正式目录后崩溃 -> 文件存在但永远搜不到 | 首次添加与增量更新分离为两条独立路径 | +| 资源已落盘但语义处理/向量化还在跑时被 rm 删除 -> 处理白跑 | 生命周期 SUBTREE 锁,从落盘持续到处理完成 | + +**首次添加**(target 不存在)— 在 `ResourceProcessor.process_resource` Phase 3.5 中处理: -```python -TransactionRecord( - id: str, # 事务ID,采用 uuid 格式,唯一标识一个事务 - locks: List[str], # 锁列表 - status: str, # 当前状态 - init_info: Dict, # 事务初始化信息 - rollback_info: Dict, # 回滚信息 - created_at: float, # 创建时间 - updated_at: float, # 更新时间 -) +``` +1. 获取 POINT 锁,锁 final_uri 的父目录 +2. agfs.mv 临时目录 -> 正式位置 +3. 获取 SUBTREE 锁,锁 final_uri(在 POINT 锁内,消除竞态窗口) +4. 释放 POINT 锁 +5. 清理临时目录 +6. 入队 SemanticMsg(lifecycle_lock_handle_id=...) -> DAG 在 final 上跑 +7. DAG 启动锁刷新循环(每 lock_expire/2 秒刷新时间戳) +8. DAG 完成 + 所有 embedding 完成 -> 释放 SUBTREE 锁 ``` -### 设计决策 +此期间 `rm` 尝试获取同路径 SUBTREE 锁会失败,抛出 `ResourceBusyError`。 -- 暂不实现共享锁(读锁),简化设计 -- 锁粒度仅限目录,不实现范围锁机制 -- 不实现复杂的死锁检测,通过超时机制防止死锁,事务超时后自动释放所有锁 -- 支持可选的自下而上并行加锁模式,提升大型目录树操作的性能和一致性 -- 事务状态机增加AQUIRE+RELEASING状态,明确跟踪锁释放过程,提高系统可观测性 +**增量更新**(target 已存在)— temp 保持不动: -## 锁机制 +``` +1. 获取 SUBTREE 锁,锁 target_uri(保护已有资源) +2. 入队 SemanticMsg(uri=temp, target_uri=final, lifecycle_lock_handle_id=...) +3. DAG 在 temp 上跑,启动锁刷新循环 +4. DAG 完成后触发 sync_diff_callback 或 move_temp_to_target_callback +5. callback 执行完毕 -> 释放 SUBTREE 锁 +``` -锁机制是事务管理的核心组件,当前只提供路径锁类型。 +注意:DAG callback 不在外层加锁。每个 `VikingFS.rm` 和 `VikingFS.mv` 内部各自有独立锁保护。外层锁会与内部锁冲突导致死锁。 -### 锁类型 +**服务重启恢复**:SemanticMsg 持久化在 QueueFS 中。重启后 `SemanticProcessor` 发现 `lifecycle_lock_handle_id` 对应的 handle 不在内存中,会重新获取 SUBTREE 锁。 -| 锁类型 | 作用范围 | 用例 | -|--------|----------|------| -| 路径锁 | 整个目录 | 用于阻止目录被意外整体移动或删除,确保事务操作过程的路径合法性 +### session.commit() -### 锁协议 +| 问题 | 方案 | +|------|------| +| 消息已清空但 archive 未写入 -> 对话数据丢失 | Phase 1 无锁(archive 不完整无副作用)+ Phase 2 RedoLog | + +LLM 调用耗时不可控(5s~60s+),不能放在持锁操作内。设计拆为两个阶段: ``` -viking://resources/github/volcengine/OpenViking/.path.ovlock +Phase 1 — 归档(无锁): + 1. 生成归档摘要(LLM) + 2. 写 archive(history/archive_N/messages.jsonl + 摘要) + 3. 清空 messages.jsonl + 4. 清空内存中的消息列表 + +Phase 2 — 记忆提取 + 写入(RedoLog): + 1. 写 redo 标记(archive_uri、session_uri、用户身份信息) + 2. 从归档消息提取 memories(LLM) + 3. 写当前消息状态 + 4. 写 relations + 5. 直接 enqueue SemanticQueue + 6. 删除 redo 标记 ``` -- 锁文件存在即表示已加锁 -- 文件内容为事务ID,用于标识当前事务 -- 事务操作完成后,删除锁文件以释放锁 +**崩溃恢复分析**: -### 加锁流程 +| 崩溃时间点 | 状态 | 恢复动作 | +|-----------|------|---------| +| Phase 1 写 archive 中途 | 无标记 | archive 不完整,下次 commit 从 history/ 扫描 index,不受影响 | +| Phase 1 archive 完成但 messages 未清空 | 无标记 | archive 完整 + messages 仍在 = 数据冗余但安全 | +| Phase 2 记忆提取/写入中途 | redo 标记存在 | 启动恢复:从 archive 重做提取+写入+入队 | +| Phase 2 完成 | redo 标记已删 | 无需恢复 | -#### 普通操作加锁流程 +## LockContext +`LockContext` 是**异步**上下文管理器,封装锁的获取和释放: + +```python +from openviking.storage.transaction import LockContext, get_lock_manager + +lock_manager = get_lock_manager() + +# Point 锁(写操作、语义处理) +async with LockContext(lock_manager, [path], lock_mode="point"): + # 执行操作... + pass + +# Subtree 锁(删除操作) +async with LockContext(lock_manager, [path], lock_mode="subtree"): + # 执行操作... + pass + +# MV 锁(移动操作) +async with LockContext(lock_manager, [src], lock_mode="mv", mv_dst_parent_path=dst): + # 执行操作... + pass ``` -1. 检查目标目录是否存在 -2. 检查目标目录是否已被其他事务锁定 -3. 检查目标目录的父目录是否已被其他事务锁定 -4. 创建 .path.ovlock 文件,文件内容为事务ID -5. 再次检查目标目录的父目录是否已被其他事务锁定 -6. 读取刚创建的 .path.ovlock 文件内容,确认为当前事务ID -7. 一切正常,则返回加锁成功 -``` -#### rm 操作加锁流程 +**锁模式**: + +| lock_mode | 用途 | 行为 | +|-----------|------|------| +| `point` | 写操作、语义处理 | 锁定指定路径;与同路径的任何锁和祖先目录的 SUBTREE 锁冲突 | +| `subtree` | 删除操作 | 锁定子树根节点;与同路径的任何锁、后代目录的任何锁和祖先目录的 SUBTREE 锁冲突 | +| `mv` | 移动操作 | 目录移动:源和目标均加 SUBTREE 锁;文件移动:源父目录和目标均加 POINT 锁(通过 `src_is_dir` 控制) | + +**异常处理**:`__aexit__` 总是释放锁,不吞异常。获取锁失败时抛出 `LockAcquisitionError`。 + +## 锁类型(POINT vs SUBTREE) + +锁机制使用两种锁类型来处理不同的冲突场景: + +| | 同路径 POINT | 同路径 SUBTREE | 后代 POINT | 祖先 SUBTREE | +|---|---|---|---|---| +| **POINT** | 冲突 | 冲突 | — | 冲突 | +| **SUBTREE** | 冲突 | 冲突 | 冲突 | 冲突 | + +- **POINT (P)**:用于写操作和语义处理。只锁单个目录。若祖先目录持有 SUBTREE 锁则阻塞。 +- **SUBTREE (S)**:用于删除和移动操作。逻辑上覆盖整个子树,但只在根目录写**一个锁文件**。获取前扫描所有后代和祖先目录确认无冲突锁。 +## 锁机制 + +### 锁协议 + +锁文件路径:`{path}/.path.ovlock` + +锁文件内容(Fencing Token): +``` +{handle_id}:{time_ns}:{lock_type} ``` -# 传统串行模式:存在更大的竞态条件窗口 -1. 检查目标目录是否存在 -2. 检查目标目录是否已被其他事务锁定 -3. 检查目标目录的父目录是否已被其他事务锁定 -4. 在目标目录下创建 .path.ovlock 文件,文件内容为事务ID -5. 递归地在目标目录的所有子目录下创建 .path.ovlock 文件 -6. 如果发生加锁失败,移除所有已经创建的 .path.ovlock 文件 -7. 一切正常,则返回加锁成功 -# 自下而上并行模式 -1. 并行遍历整个目录树,收集所有子目录路径 -2. 按照目录层级从深到浅排序,从最深层子目录开始 -3. 以有限并行度(默认最大8)批量创建 .path.ovlock 文件 -4. 最后锁定目标目录 -5. 如果任一位置加锁失败,逆序移除所有已经创建的 .path.ovlock 文件 +其中 `lock_type` 为 `P`(POINT)或 `S`(SUBTREE)。 + +### 获取锁流程(POINT 模式) + +``` +循环直到超时(轮询间隔:200ms): + 1. 检查目标目录存在 + 2. 检查目标路径是否被其他操作锁定 + - 陈旧锁? -> 移除后重试 + - 活跃锁? -> 等待 + 3. 检查所有祖先目录是否有 SUBTREE 锁 + - 陈旧锁? -> 移除后重试 + - 活跃锁? -> 等待 + 4. 写入 POINT (P) 锁文件 + 5. TOCTOU 双重检查:重新扫描祖先目录的 SUBTREE 锁 + - 发现冲突:比较 (timestamp, handle_id) + - 后到者(更大的 timestamp/handle_id)主动让步(删除自己的锁),防止活锁 + - 等待后重试 + 6. 验证锁文件归属(fencing token 匹配) + 7. 成功 + +超时(默认 0 = 不等待)抛出 LockAcquisitionError ``` -#### mv 操作加锁流程 +### 获取锁流程(SUBTREE 模式) ``` -1. 先参照 rm 操作对原目录进行加锁 -2. 再参照普通操作过程对新目录进行加锁 +循环直到超时(轮询间隔:200ms): + 1. 检查目标目录存在 + 2. 检查目标路径是否被其他操作锁定 + - 陈旧锁? -> 移除后重试 + - 活跃锁? -> 等待 + 3. 检查所有祖先目录是否有 SUBTREE 锁 + - 陈旧锁? -> 移除后重试 + - 活跃锁? -> 等待 + 4. 扫描所有后代目录,检查是否有其他操作持有的锁 + - 陈旧锁? -> 移除后重试 + - 活跃锁? -> 等待 + 5. 写入 SUBTREE (S) 锁文件(只写一个文件,在根路径) + 6. TOCTOU 双重检查:重新扫描后代目录和祖先目录 + - 发现冲突:比较 (timestamp, handle_id) + - 后到者(更大的 timestamp/handle_id)主动让步(删除自己的锁),防止活锁 + - 等待后重试 + 7. 验证锁文件归属(fencing token 匹配) + 8. 成功 + +超时(默认 0 = 不等待)抛出 LockAcquisitionError ``` -### 锁机制性能分析 +### 锁过期清理 + +**陈旧锁检测**:PathLock 检查 fencing token 中的时间戳。超过 `lock_expire`(默认 300s)的锁被视为陈旧锁,在加锁过程中自动移除。 + +**进程内清理**:LockManager 每 60 秒检查活跃的 LockHandle,创建超过 3600 秒的 handle 强制释放。 + +**孤儿锁**:进程崩溃后遗留的锁文件,在下次任何操作尝试获取同一路径锁时,通过 stale lock 检测自动移除。 + +## 崩溃恢复 + +`LockManager.start()` 启动时自动扫描 `/local/_system/redo/` 目录中的遗留标记: + +| 场景 | 恢复方式 | +|------|---------| +| session_memory 提取中途崩溃 | 从 archive 重做记忆提取 + 写入 + enqueue | +| 锁持有期间崩溃 | 锁文件留在 AGFS,下次获取时 stale 检测自动清理(默认 300s 过期)| +| enqueue 后 worker 处理前崩溃 | QueueFS SQLite 持久化,worker 重启后自动拉取 | +| 孤儿索引 | L2 按需加载时清理 | + +### 防线总结 + +| 异常场景 | 防线 | 恢复时机 | +|---------|------|---------| +| 操作中途崩溃 | 锁自动过期 + stale 检测 | 下次获取同路径锁时 | +| add_resource 语义处理中途崩溃 | 生命周期锁过期 + SemanticProcessor 重启时重新获取 | worker 重启后 | +| session.commit Phase 2 崩溃 | RedoLog 标记 + 重做 | 重启时 | +| enqueue 后 worker 处理前崩溃 | QueueFS SQLite 持久化 | worker 重启后 | +| 孤儿索引 | L2 按需加载时清理 | 用户访问时 | + +## 配置 + +路径锁默认启用,无需额外配置。**默认不等待**:若路径被锁定则立即抛出 `LockAcquisitionError`。如需允许等待重试,可通过 `storage.transaction` 段配置: + +```json +{ + "storage": { + "transaction": { + "lock_timeout": 5.0, + "lock_expire": 300.0 + } + } +} +``` + +| 参数 | 类型 | 说明 | 默认值 | +|------|------|------|--------| +| `lock_timeout` | float | 获取锁的等待超时(秒)。`0` = 立即失败(默认);`> 0` = 最多等待此时间 | `0.0` | +| `lock_expire` | float | 锁过期时间(秒),超过此时间的锁将被视为陈旧锁并强制释放 | `300.0` | + +### QueueFS 持久化 -- 并行遍历采用广度优先策略,同时处理同一层级的所有目录 -- 并行加锁从最深层开始,逐层向上锁定,确保整个目录树的一致性 -- 有限并行度(默认最大8)避免AGFS服务过载 -- 加锁失败时采用逆序回滚,确保所有已加锁目录都能正确释放 -- 事务状态机明确区分锁管理过程(AQUIRE+RELEASING状态),提高系统可观测性和调试效率 +路径锁机制依赖 QueueFS 使用 SQLite 后端,确保 enqueue 的任务在进程重启后可恢复。这是默认配置,无需手动设置。 ## 相关文档 - [架构概述](./01-architecture.md) - 系统整体架构 - [存储架构](./05-storage.md) - AGFS 和向量库 -- [会话管理](./08-session.md) - 会话和记忆管理 \ No newline at end of file +- [会话管理](./08-session.md) - 会话和记忆管理 +- [配置](../guides/01-configuration.md) - 配置文件说明 diff --git a/docs/zh/faq/faq.md b/docs/zh/faq/faq.md index 68030005..956016aa 100644 --- a/docs/zh/faq/faq.md +++ b/docs/zh/faq/faq.md @@ -125,6 +125,7 @@ pip install openviking --upgrade --force-reinstall | `openai` | OpenAI Embedding API | | `vikingdb` | VikingDB Embedding API | | `jina` | Jina AI Embedding API | +| `ollama` | Ollama(本地 OpenAI 兼容服务器,无需 API Key) | 支持 Dense、Sparse 和 Hybrid 三种 Embedding 模式。 diff --git a/docs/zh/guides/01-configuration.md b/docs/zh/guides/01-configuration.md index 01dc6d41..190e52f0 100644 --- a/docs/zh/guides/01-configuration.md +++ b/docs/zh/guides/01-configuration.md @@ -199,13 +199,15 @@ OpenViking 使用 JSON 配置文件(`ov.conf`)进行设置。配置文件支 #### Sparse Embedding +> **注意:** 火山引擎的 Sparse embedding 从 `doubao-embedding-vision-250615` 模型版本起支持。 + ```json { "embedding": { "sparse": { "provider": "volcengine", "api_key": "your-api-key", - "model": "bm25-sparse-v1" + "model": "doubao-embedding-vision-250615" } } } @@ -244,7 +246,7 @@ OpenViking 使用 JSON 配置文件(`ov.conf`)进行设置。配置文件支 "sparse": { "provider": "volcengine", "api_key": "your-api-key", - "model": "bm25-sparse-v1" + "model": "doubao-embedding-vision-250615" } } } @@ -274,6 +276,7 @@ OpenViking 使用 JSON 配置文件(`ov.conf`)进行设置。配置文件支 | `api_base` | str | API 端点(可选) | | `thinking` | bool | 启用思考模式(仅对部分火山模型生效,默认:`false`) | | `max_concurrent` | int | 语义处理阶段 LLM 最大并发调用数(默认:`100`) | +| `extra_headers` | object | 自定义 HTTP 请求头(OpenAI 兼容 provider 可用,可选) | **可用模型** @@ -289,6 +292,30 @@ OpenViking 使用 JSON 配置文件(`ov.conf`)进行设置。配置文件支 如果未配置 VLM,L0/L1 将直接从内容生成(语义性较弱),多模态资源的描述可能有限。 +**自定义 HTTP Headers** + +对于 OpenAI 兼容的 provider(如 OpenRouter),可以通过 `extra_headers` 添加自定义 HTTP 请求头: + +```json +{ + "vlm": { + "provider": "openai", + "api_key": "your-api-key", + "model": "gpt-4o", + "api_base": "https://openrouter.ai/api/v1", + "extra_headers": { + "HTTP-Referer": "https://your-site.com", + "X-Title": "Your App Name" + } + } +} +``` + +常见使用场景: +- **OpenRouter**: 需要 `HTTP-Referer` 和 `X-Title` 来标识应用 +- **自定义代理**: 添加认证头或追踪头 +- **API 网关**: 添加版本或路由标识 + ### code 通过 `code_summary_mode` 控制代码文件的摘要生成方式。以下两种写法等价: @@ -487,14 +514,13 @@ AST 提取支持:Python、JavaScript/TypeScript、Rust、Go、Java、C/C++。 - #### vectordb -向量库存储的配置 +向量库存储的配置 | 参数 | 类型 | 说明 | 默认值 | |------|------|------|--------| -| `backend` | str | VectorDB 后端类型: 'local'(基于文件), 'http'(远程服务), 'volcengine'(云上VikingDB)或 'vikingdb'(私有部署) | "local" | +| `backend` | str | VectorDB 后端类型: 'local'(基于文件), 'http'(远程服务), 'volcengine'(云上VikingDB), 'vikingdb'(私有部署), 'oceanbase'(OceanBase) | "local" | | `name` | str | VectorDB 的集合名称 | "context" | | `url` | str | 'http' 类型的远程服务 URL(例如 'http://localhost:5000') | null | | `project_name` | str | 项目名称(别名 project) | "default" | @@ -503,6 +529,7 @@ AST 提取支持:Python、JavaScript/TypeScript、Rust、Go、Java、C/C++。 | `sparse_weight` | float | 混合向量搜索的稀疏权重,仅在使用混合索引时生效 | 0.0 | | `volcengine` | object | 'volcengine' 类型的 VikingDB 配置 | - | | `vikingdb` | object | 'vikingdb' 类型的私有部署配置 | - | +| `oceanbase` | object | 'oceanbase' 类型的 OceanBase 配置 | - | 默认使用本地模式 ``` @@ -536,7 +563,28 @@ AST 提取支持:Python、JavaScript/TypeScript、Rust、Go、Java、C/C++。 ``` +
    +OceanBase (oceanbase) +使用 [OceanBase](https://www.oceanbase.com/) 作为向量库后端。安装与配置详见 [OceanBase 集成指南](./06-oceanbase-integration.md)。 +```json +{ + "storage": { + "vectordb": { + "name": "context", + "backend": "oceanbase", + "distance_metric": "cosine", + "oceanbase": { + "uri": "127.0.0.1:2881", + "user": "root@test", + "password": "your-password", + "db_name": "test" + } + } + } +} +``` +
    ## 配置文件 @@ -612,6 +660,28 @@ HTTP 客户端(`SyncHTTPClient` / `AsyncHTTPClient`)和 CLI 工具连接远 启动方式和部署详情见 [服务部署](./03-deployment.md),认证详情见 [认证](./04-authentication.md)。 +## storage.transaction 段 + +路径锁默认启用,通常无需配置。**默认行为是不等待**:若目标路径已被其他操作锁定,操作立即失败并抛出 `LockAcquisitionError`。若需要等待重试,请将 `lock_timeout` 设为正数。 + +```json +{ + "storage": { + "transaction": { + "lock_timeout": 5.0, + "lock_expire": 300.0 + } + } +} +``` + +| 参数 | 类型 | 说明 | 默认值 | +|------|------|------|--------| +| `lock_timeout` | float | 获取路径锁的等待超时(秒)。`0` = 立即失败(默认);`> 0` = 最多等待此时间后抛出 `LockAcquisitionError` | `0.0` | +| `lock_expire` | float | 锁过期时间(秒)。超过此时间的锁将被视为崩溃进程遗留的陈旧锁并强制释放 | `300.0` | + +路径锁机制的详细说明见 [路径锁与崩溃恢复](../concepts/09-transaction.md)。 + ## 完整 Schema ```json @@ -632,7 +702,8 @@ HTTP 客户端(`SyncHTTPClient` / `AsyncHTTPClient`)和 CLI 工具连接远 "model": "string", "api_base": "string", "thinking": false, - "max_concurrent": 100 + "max_concurrent": 100, + "extra_headers": {} }, "rerank": { "provider": "volcengine", @@ -646,6 +717,10 @@ HTTP 客户端(`SyncHTTPClient` / `AsyncHTTPClient`)和 CLI 工具连接远 "url": "string", "timeout": 10 }, + "transaction": { + "lock_timeout": 0.0, + "lock_expire": 300.0 + }, "vectordb": { "backend": "local|remote", "url": "string", diff --git a/docs/zh/guides/06-mcp-integration.md b/docs/zh/guides/06-mcp-integration.md new file mode 100644 index 00000000..7ed728cd --- /dev/null +++ b/docs/zh/guides/06-mcp-integration.md @@ -0,0 +1,230 @@ +# MCP 集成指南 + +OpenViking 可以作为 [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) 服务器使用,任何兼容 MCP 的客户端都可以访问其记忆和资源能力。 + +## 传输模式 + +OpenViking 支持两种 MCP 传输模式: + +| | HTTP (SSE) | stdio | +|---|---|---| +| **工作方式** | 单个长期运行的服务器进程;客户端通过 HTTP 连接 | 宿主为每个会话生成一个新的 OpenViking 进程 | +| **多会话安全** | ✅ 是 — 单进程,无锁竞争 | ⚠️ **否** — 多进程争用同一数据目录 | +| **推荐用于** | 生产环境、多 Agent、多会话 | 仅限单会话本地开发 | +| **配置复杂度** | 需要单独运行 `openviking-server` | 零配置 — 宿主管理进程 | + +### 选择合适的传输模式 + +- **使用 HTTP**:如果你的宿主会打开多个会话、运行多个 Agent,或需要并发访问。 +- **使用 stdio**:仅在单会话、单 Agent 的本地环境中,且追求简单时使用。 + +> ⚠️ **重要提示:** 当 MCP 宿主为每个会话生成独立的 stdio OpenViking 进程时(例如每个聊天会话一个进程),所有实例会争用同一底层数据目录。这会导致存储层(AGFS 和 VectorDB)的 **锁/资源竞争**。 +> +> 表现为以下误导性错误: +> - `Collection 'context' does not exist` +> - `Transport closed` +> - 间歇性搜索失败 +> +> **根因不是索引损坏** — 而是多个进程争用同一存储文件。切换到 HTTP 模式即可解决。详见[故障排除](#故障排除)。 + +## 配置 + +### 前提条件 + +1. 已安装 OpenViking(`pip install openviking` 或从源码安装) +2. 有效的配置文件(参见[配置指南](01-configuration.md)) +3. HTTP 模式需要:`openviking-server` 正在运行(参见[部署指南](03-deployment.md)) + +### HTTP 模式(推荐) + +首先启动 OpenViking 服务器: + +```bash +openviking-server --config /path/to/config.yaml +# 默认地址:http://localhost:1933 +``` + +然后配置你的 MCP 客户端通过 HTTP 连接。 + +### stdio 模式 + +无需单独启动服务器 — MCP 宿主直接启动 OpenViking。 + +## 客户端配置 + +### Claude Code (CLI) + +**HTTP 模式:** + +```bash +claude mcp add openviking \ + --transport sse \ + "http://localhost:1933/mcp" +``` + +**stdio 模式:** + +```bash +claude mcp add openviking \ + --transport stdio \ + -- python -m openviking.server --transport stdio \ + --config /path/to/config.yaml +``` + +### Claude Desktop + +编辑 `claude_desktop_config.json`: + +**HTTP 模式:** + +```json +{ + "mcpServers": { + "openviking": { + "url": "http://localhost:1933/mcp" + } + } +} +``` + +**stdio 模式:** + +```json +{ + "mcpServers": { + "openviking": { + "command": "python", + "args": [ + "-m", "openviking.server", + "--transport", "stdio", + "--config", "/path/to/config.yaml" + ] + } + } +} +``` + +### Cursor + +在 Cursor 设置 → MCP 中配置: + +**HTTP 模式:** + +```json +{ + "mcpServers": { + "openviking": { + "url": "http://localhost:1933/mcp" + } + } +} +``` + +**stdio 模式:** + +```json +{ + "mcpServers": { + "openviking": { + "command": "python", + "args": [ + "-m", "openviking.server", + "--transport", "stdio", + "--config", "/path/to/config.yaml" + ] + } + } +} +``` + +### OpenClaw + +在 OpenClaw 配置文件(`openclaw.json` 或 `openclaw.yaml`)中: + +**HTTP 模式(推荐):** + +```json +{ + "mcp": { + "servers": { + "openviking": { + "url": "http://localhost:1933/mcp" + } + } + } +} +``` + +**stdio 模式:** + +```json +{ + "mcp": { + "servers": { + "openviking": { + "command": "python", + "args": [ + "-m", "openviking.server", + "--transport", "stdio", + "--config", "/path/to/config.yaml" + ] + } + } + } +} +``` + +## 可用的 MCP 工具 + +连接后,OpenViking 提供以下 MCP 工具: + +| 工具 | 说明 | +|------|------| +| `search` | 跨记忆和资源的语义搜索 | +| `add_memory` | 存储新记忆 | +| `add_resource` | 添加资源(文件、文本、URL) | +| `get_status` | 检查系统健康状态和组件状态 | +| `list_memories` | 浏览已存储的记忆 | +| `list_resources` | 浏览已存储的资源 | + +完整参数详情请参考 OpenViking 的工具文档。 + +## 故障排除 + +### `Collection 'context' does not exist` + +**可能原因:** 多个 stdio MCP 实例争用同一数据目录。 + +**解决方案:** 切换到 HTTP 模式。如果必须使用 stdio,请确保同一时间只有一个 OpenViking 进程访问给定的数据目录。 + +### `Transport closed` + +**可能原因:** MCP stdio 进程因资源竞争而崩溃或被终止。也可能发生在后端重启后客户端持有过期连接时。 + +**解决方案:** +1. 切换到 HTTP 模式以避免竞争。 +2. 如果使用 HTTP:在客户端中重新加载 MCP 连接(重启会话或重新连接)。 + +### HTTP 端点连接被拒绝 + +**可能原因:** `openviking-server` 未运行,或运行在不同端口上。 + +**解决方案:** 验证服务器是否正在运行: + +```bash +curl http://localhost:1933/health +# 预期返回:{"status": "ok"} +``` + +### 认证错误 + +**可能原因:** 客户端配置与服务器配置中的 API 密钥不匹配。 + +**解决方案:** 确保 MCP 客户端配置中的 API 密钥与 OpenViking 服务器配置中的一致。参见[认证指南](04-authentication.md)。 + +## 参考 + +- [MCP 规范](https://modelcontextprotocol.io/) +- [OpenViking 配置](01-configuration.md) +- [OpenViking 部署](03-deployment.md) +- [相关 Issue:stdio 竞争问题 (#473)](https://github.com/volcengine/OpenViking/issues/473) diff --git a/docs/zh/guides/06-oceanbase-integration.md b/docs/zh/guides/06-oceanbase-integration.md new file mode 100644 index 00000000..4e47fc66 --- /dev/null +++ b/docs/zh/guides/06-oceanbase-integration.md @@ -0,0 +1,274 @@ +# OpenViking 与 OceanBase 集成指南 + +本文介绍如何将 [OceanBase](https://www.oceanbase.com/) 作为 OpenViking 的向量库后端,并**通过官方实战示例**从零跑通语义检索。 + +--- + +## 一、集成概述 + +- 通过 [pyobvector](https://github.com/oceanbase/pyobvector) 连接 OceanBase,使用其向量表与 HNSW 索引。 +- 在配置中设置 `storage.vectordb.backend = "oceanbase"` 并填写 `oceanbase` 连接块即可切换后端。 +- 适用于希望将上下文索引落在关系型/HTAP 数据库或复用现有 OceanBase 的场景。 + +**前置条件**:OceanBase 4.3.3.0+(支持向量类型与向量索引);需安装 `pyobvector` 或 `openviking[oceanbase]`。 + +--- + +## 二、安装与配置 + +### 2.1 安装 + +```bash +# 方式一:仅安装 pyobvector(若已安装 openviking) +pip install pyobvector + +# 方式二:安装 openviking 时一并安装 OceanBase 依赖(推荐) +pip install openviking[oceanbase] +``` + +### 2.2 配置示例(ov.conf) + +在 `~/.openviking/ov.conf` 中增加或修改 `storage.vectordb`,并填写 `oceanbase` 连接信息: + +```json +{ + "storage": { + "vectordb": { + "name": "context", + "backend": "oceanbase", + "distance_metric": "l2", + "oceanbase": { + "uri": "127.0.0.1:2881", + "user": "root@test", + "password": "", + "db_name": "openviking" + } + } + } +} +``` + +> **说明**:若使用 Docker 启动的 OceanBase(slim 模式),建议将 `distance_metric` 设为 `"l2"`;若使用支持 cosine 的 OceanBase 版本,可设为 `"cosine"`。完整配置项见 [配置说明](./01-configuration.md#vectordb)。 + +首次写入或启动服务时,OpenViking 会按 Context Schema 自动建表与索引,无需手动建表。 + +--- + +## 三、实战示例一:5 分钟跑通 OpenViking + OceanBase + +本示例与 [快速开始](../getting-started/02-quickstart.md) 风格一致:从启动 OceanBase 到完成一次语义检索,全程可复现。 + +### 步骤 1:启动 OceanBase(Docker) + +若本机尚未安装 OceanBase,可使用 Docker 快速启动单机实例(首次会拉取镜像,启动约需数分钟): + +```bash +# 启动容器(端口 2881) +docker run -d -p 2881:2881 --name oceanbase-ce -e MODE=slim oceanbase/oceanbase-ce + +# 等待启动完成(日志出现 "boot success!") +docker logs oceanbase-ce 2>&1 | tail -5 + +# 创建数据库(root@test 租户) +docker exec -it oceanbase-ce mysql -h127.0.0.1 -P2881 -uroot@test -e "CREATE DATABASE IF NOT EXISTS openviking;" +``` + +若使用已有 OceanBase,请确保已创建 `ov.conf` 中 `oceanbase.db_name` 对应的数据库,并保证网络与账号权限可用。 + +### 步骤 2:准备配置文件 + +确保 `~/.openviking/ov.conf` 中已配置 **embedding**(与 [快速开始](../getting-started/02-quickstart.md) 相同)和 **storage.vectordb(OceanBase)**。以下为最小示例(请将 embedding 的 api_key、model 等替换为实际值): + +```json +{ + "embedding": { + "dense": { + "api_base": "", + "api_key": "", + "provider": "", + "dimension": 1024, + "model": "" + } + }, + "storage": { + "vectordb": { + "name": "context", + "backend": "oceanbase", + "distance_metric": "l2", + "oceanbase": { + "uri": "127.0.0.1:2881", + "user": "root@test", + "password": "", + "db_name": "openviking" + } + } + } +} +``` + +各模型服务的完整配置见 [配置指南 - 配置示例](./01-configuration.md#配置示例)。 + +### 步骤 3:创建示例脚本 + +创建 `example_oceanbase.py`,内容如下(与快速开始示例一致,仅向量库改为 OceanBase): + +```python +import openviking as ov + +# 使用默认配置 ~/.openviking/ov.conf(其中 vectordb 已设为 oceanbase) +client = ov.OpenViking(path="./data") + +try: + client.initialize() + + # 添加资源(支持 URL、本地文件或目录) + add_result = client.add_resource( + path="https://raw.githubusercontent.com/volcengine/OpenViking/refs/heads/main/README.md" + ) + root_uri = add_result["root_uri"] + + # 查看资源结构 + ls_result = client.ls(root_uri) + print(f"目录结构:\n{ls_result}\n") + + # 等待语义处理完成(向量将写入 OceanBase) + print("等待语义处理...") + client.wait_processed() + + # 获取摘要与概览 + abstract = client.abstract(root_uri) + overview = client.overview(root_uri) + print(f"摘要:\n{abstract}\n\n概览:\n{overview}\n") + + # 语义检索(底层从 OceanBase 做向量搜索) + results = client.find("what is openviking", target_uri=root_uri) + print("检索结果:") + for r in results.resources: + print(f" {r.uri} (score: {r.score:.4f})") + + client.close() + +except Exception as e: + print(f"错误: {e}") +``` + +### 步骤 4:运行 + +```bash +python example_oceanbase.py +``` + +### 步骤 5:预期输出 + +``` +目录结构: +... + +等待语义处理... +摘要: +... + +概览: +... + +检索结果: + viking://resources/... (score: 0.xxxx) + ... +``` + +至此,你已用 OceanBase 作为向量库完成 OpenViking 的首次语义检索。内容仍存储在本地 AGFS(`path="./data"`),向量与元数据存储在 OceanBase 中。 + +--- + +## 四、实战示例二:企业知识库(批量导入 + 按范围检索) + +本示例演示:将多个资源导入后,通过自然语言在指定 URI 范围内检索,适合企业知识库、Wiki 等场景。 + +### 步骤 1:准备内容与配置 + +- 确保 OceanBase 已启动并已创建数据库(同实战示例一)。 +- 确保 `ov.conf` 中 `storage.vectordb.backend` 为 `oceanbase`,且 embedding、oceanbase 连接已配置。 + +### 步骤 2:批量导入并检索 + +创建 `example_knowledge_base.py`: + +```python +import openviking as ov + +client = ov.OpenViking(path="./data") +client.initialize() + +# 批量添加资源(本地目录或 URL) +client.add_resource("/path/to/your/wiki") # 本地目录 +client.add_resource("https://example.com/doc.md") # 或 URL +client.wait_processed() + +# 在指定 URI 前缀下做语义检索(多租户/多项目时可限定范围) +results = client.find( + "用户登录与鉴权流程", + target_uri="viking://resources/", + limit=5 +) + +print(f"共 {results.total} 条相关结果") +for ctx in results.resources: + print(f" {ctx.uri}") + print(f" score={ctx.score:.3f} abstract={ctx.abstract[:80]}...") + print() + +client.close() +``` + +将 `/path/to/your/wiki` 替换为实际文档目录或删除该行仅用 URL。运行: + +```bash +python example_knowledge_base.py +``` + +通过 `target_uri="viking://resources/"` 可限定只在资源树下检索;不同业务可约定不同 URI 前缀(如 `viking://resources/tenant-a/`)实现逻辑隔离。 + +--- + +## 五、Docker 快速启动参考 + +| 步骤 | 命令 | +|------|------| +| 启动 OceanBase | `docker run -d -p 2881:2881 --name oceanbase-ce -e MODE=slim oceanbase/oceanbase-ce` | +| 等待就绪 | `docker logs oceanbase-ce 2>&1 \| tail -1` 出现 `boot success!` | +| 建库 | `docker exec -it oceanbase-ce mysql -h127.0.0.1 -P2881 -uroot@test -e "CREATE DATABASE IF NOT EXISTS openviking;"` | + +配置中填写 `oceanbase.uri: "127.0.0.1:2881"`、`oceanbase.db_name: "openviking"` 即可。 + +--- + +## 六、距离度量与版本 + +| distance_metric | 说明 | +|-----------------|------| +| `cosine` | 在支持的 OceanBase 版本中会映射为 neg_ip | +| `l2` / `ip` | 直接对应 OceanBase 的 L2 / IP 距离 | + +若报错「this type of vector index distance algorithm is not supported」,请将 `distance_metric` 改为 `"l2"` 后重试(Docker slim 模式建议使用 `l2`)。 + +--- + +## 七、运行集成测试 + +本仓库内 OceanBase 相关测试**默认通过 Docker 启动 OceanBase**,无需本机预先安装: + +```bash +# 需已安装 Docker;会自动拉取并启动 oceanbase/oceanbase-ce +pytest tests/vectordb/test_oceanbase_live.py -v -s +# 或 +python -m unittest tests.vectordb.test_oceanbase_live -v +``` + +--- + +## 八、相关文档 + +- [配置说明](./01-configuration.md) — `storage.vectordb` 与各后端通用参数 +- [存储架构](../concepts/05-storage.md) — 向量库在 OpenViking 中的角色 +- [快速开始](../getting-started/02-quickstart.md) — 5 分钟上手 OpenViking(默认本地向量库) +- [OceanBase 集成(英文)](../../en/guides/06-oceanbase-integration.md) — 英文版本文档 diff --git a/examples/mcp-query/server.py b/examples/mcp-query/server.py index 95487f54..fbc98e32 100644 --- a/examples/mcp-query/server.py +++ b/examples/mcp-query/server.py @@ -36,6 +36,8 @@ _recipe: Optional[Recipe] = None _config_path: str = "./ov.conf" _data_path: str = "./data" +_api_key: str = "" +_default_uri: str = "" def _get_recipe() -> Recipe: @@ -43,6 +45,8 @@ def _get_recipe() -> Recipe: global _recipe if _recipe is None: _recipe = Recipe(config_path=_config_path, data_path=_data_path) + if _api_key: + _recipe.api_key = _api_key return _recipe @@ -137,6 +141,7 @@ async def search( score_threshold: Minimum relevance score (0.0-1.0, default: 0.2). target_uri: Optional URI to scope the search to a specific resource. """ + effective_uri = target_uri or _default_uri def _search_sync(): recipe = _get_recipe() @@ -144,7 +149,7 @@ def _search_sync(): query=query, top_k=top_k, score_threshold=score_threshold, - target_uri=target_uri or None, + target_uri=effective_uri or None, ) results = await asyncio.to_thread(_search_sync) @@ -239,14 +244,19 @@ def parse_args(): # Use stdio transport (for Claude Desktop integration) uv run server.py --transport stdio - # Connect from Claude CLI - claude mcp add --transport http openviking http://localhost:2033/mcp + # Connect from Claude CLI (use 127.0.0.1 instead of localhost for Windows compatibility) + claude mcp add --transport http openviking http://127.0.0.1:2033/mcp + + # With API key and default search scope + uv run server.py --api-key sk-xxx --default-uri viking://user/memories Environment variables: - OV_CONFIG Path to config file (default: ./ov.conf) - OV_DATA Path to data directory (default: ./data) - OV_PORT Server port (default: 2033) - OV_DEBUG Enable debug logging (set to 1) + OV_CONFIG Path to config file (default: ./ov.conf) + OV_DATA Path to data directory (default: ./data) + OV_PORT Server port (default: 2033) + OV_API_KEY API key for OpenViking server authentication + OV_DEFAULT_URI Default target URI for search scoping + OV_DEBUG Enable debug logging (set to 1) """, ) parser.add_argument( @@ -280,15 +290,29 @@ def parse_args(): default="streamable-http", help="Transport type (default: streamable-http)", ) + parser.add_argument( + "--api-key", + type=str, + default=os.getenv("OV_API_KEY", ""), + help="API key for OpenViking server authentication (default: $OV_API_KEY)", + ) + parser.add_argument( + "--default-uri", + type=str, + default=os.getenv("OV_DEFAULT_URI", ""), + help="Default target URI for search scoping (default: search all)", + ) return parser.parse_args() def main(): args = parse_args() - global _config_path, _data_path + global _config_path, _data_path, _api_key, _default_uri _config_path = args.config _data_path = args.data + _api_key = args.api_key + _default_uri = args.default_uri if os.getenv("OV_DEBUG") == "1": logging.getLogger().setLevel(logging.DEBUG) diff --git a/examples/memory_demo.py b/examples/misc/memory_demo.py similarity index 100% rename from examples/memory_demo.py rename to examples/misc/memory_demo.py diff --git a/examples/openclaw-memory-plugin/INSTALL-AGENT.md b/examples/openclaw-memory-plugin/INSTALL-AGENT.md index 220e6048..fec1d7c2 100644 --- a/examples/openclaw-memory-plugin/INSTALL-AGENT.md +++ b/examples/openclaw-memory-plugin/INSTALL-AGENT.md @@ -104,24 +104,11 @@ Check if `~/.openviking/ov.conf` already exists: > "Please provide your Volcengine Ark API Key (used for Embedding and VLM model calls). > Get one at https://console.volcengine.com/ark if you don't have one." -Check if the OpenViking repo is available locally: - -```bash -ls examples/openclaw-memory-plugin/setup-helper/package.json 2>/dev/null -``` - -- In repo: Run setup helper directly -- Not in repo: Clone first - -```bash -git clone https://github.com/volcengine/OpenViking.git /tmp/OpenViking -cd /tmp/OpenViking -``` - Run the setup helper: ```bash -npx ./examples/openclaw-memory-plugin/setup-helper +npm install -g openclaw-openviking-setup-helper +ov-install ``` At the interactive prompts: @@ -194,18 +181,15 @@ openclaw --version > Remote mode does **not** require Python — OpenViking runs on the remote server. -### Step R3: Deploy Plugin and Configure - -Get the plugin code: +### Step R3: Install Plugin and Configure ```bash -git clone https://github.com/volcengine/OpenViking.git /tmp/OpenViking -cd /tmp/OpenViking/examples/openclaw-memory-plugin -npm install -openclaw plugin link . +npm install -g openclaw-openviking-setup-helper +ov-install +# Select remote mode, enter OpenViking server URL and API Key ``` -Configure remote connection (substitute user-provided values). If targeting a non-default instance, prefix each command with `OPENCLAW_STATE_DIR=`: +Alternatively, configure manually (substitute user-provided values). If targeting a non-default instance, prefix each command with `OPENCLAW_STATE_DIR=`: ```bash openclaw config set plugins.enabled true --json diff --git a/examples/openclaw-memory-plugin/INSTALL-ZH.md b/examples/openclaw-memory-plugin/INSTALL-ZH.md index 58a53b93..f1a52f27 100644 --- a/examples/openclaw-memory-plugin/INSTALL-ZH.md +++ b/examples/openclaw-memory-plugin/INSTALL-ZH.md @@ -1,17 +1,58 @@ # 为 OpenClaw 安装 OpenViking 记忆功能 -通过 [OpenViking](https://github.com/volcengine/OpenViking) 为 [OpenClaw](https://github.com/openclaw/openclaw) 提供长效记忆能力。安装完成后,OpenClaw 将自动**记住**对话中的重要信息,并在回复前**回忆**相关内容。 +通过 [OpenViking](https://github.com/volcengine/OpenViking) 为 [OpenClaw](https://github.com/openclaw/openclaw) 提供长效记忆能力。安装完成后,OpenClaw 将自动**记住**对话中的重要信息,并在回复前**回忆**相关内容。OpenViking 最新版本发布了 [WebConsole](https://github.com/volcengine/OpenViking/tree/main/openviking/console),方便调试和运维。文档方式三也提供了如何在 WebConsole 界面验证记忆写入的说明,欢迎试用和反馈。 + +> **⚠️ OpenClaw >= 2026.3.12 兼容性问题** +> +> OpenClaw `2026.3.12` 及更高版本存在已知兼容性问题,会导致加载插件后对话卡死无响应。 +> 这不是本插件的 bug——根因是 OpenClaw 3.12 的 slug generator(会话自动命名)有硬编码 15s 超时, +> 当 LLM provider 响应较慢时会逐个 profile 超时重试,阻塞整个会话初始化管线。 +> 此外 3.12 新增的插件信任机制也可能影响本地插件的加载时序。 +> 另一个已知问题:`before_agent_start` 中的 auto-recall 缺少超时保护,可能导致 agent 静默挂起([#673](https://github.com/volcengine/OpenViking/issues/673))。 +> +> **临时方案:** 回退到 `2026.3.11`:`npm install -g openclaw@2026.3.11` +> +> 上游修复 PR:openclaw/openclaw#34673、openclaw/openclaw#33547。 +> 详见 [#591](https://github.com/volcengine/OpenViking/issues/591)。 + +> **🚀 插件 2.0 设计中** +> +> 我们正在设计基于 context-engine 架构重构的插件 2.0 版本,将作为 OpenViking 接入 AI 编程助手的最佳实践。 +> 欢迎参与讨论:https://github.com/volcengine/OpenViking/discussions/525 --- -## 一键安装(Linux / macOS) +## 一键安装 + +**前置条件:** Python >= 3.10,Node.js >= 22。安装助手会自动检查并提示安装缺少的组件。 + +### 方式 A:npm 安装(推荐,全平台) ```bash -curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash +npm install -g openclaw-openviking-setup-helper +ov-install ``` 非交互模式(使用默认配置): +```bash +ov-install -y +``` + +安装到指定 OpenClaw 实例: + +```bash +ov-install --workdir ~/.openclaw-second +``` + +### 方式 B:curl 一键安装(Linux / macOS) + +```bash +curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash +``` + +非交互模式: + ```bash curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash -s -y ``` @@ -66,9 +107,12 @@ python3 -m pip install openviking --upgrade ### Step 2: 运行安装助手 ```bash -git clone https://github.com/volcengine/OpenViking.git -cd OpenViking -npx ./examples/openclaw-memory-plugin/setup-helper +# 方式 A:npm 安装(推荐,全平台) +npm install -g openclaw-openviking-setup-helper +ov-install + +# 方式 B:curl 一键安装(Linux / macOS) +curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash ``` 安装助手会提示输入 Ark API Key 并自动生成配置文件。 @@ -96,16 +140,23 @@ openclaw status **前置:** 已有 OpenViking 服务地址 + API Key(如服务端启用了认证)。 -### Step 1: 部署插件代码 +### Step 1: 安装插件 + +```bash +npm install -g openclaw-openviking-setup-helper +ov-install +# 选择 remote 模式,填入 OpenViking 服务地址和 API Key +``` + +### Step 2: 启动并验证 ```bash -git clone https://github.com/volcengine/OpenViking.git -cd OpenViking/examples/openclaw-memory-plugin -npm install -openclaw plugin link . +openclaw gateway restart +openclaw status ``` -### Step 2: 配置远端连接 +
    +手动配置(不使用安装助手) ```bash openclaw config set plugins.enabled true --json @@ -113,16 +164,59 @@ openclaw config set plugins.slots.memory memory-openviking openclaw config set plugins.entries.memory-openviking.config.mode remote openclaw config set plugins.entries.memory-openviking.config.baseUrl "http://your-server:1933" openclaw config set plugins.entries.memory-openviking.config.apiKey "your-api-key" +openclaw config set plugins.entries.memory-openviking.config.agentId "your-agent-id" openclaw config set plugins.entries.memory-openviking.config.autoRecall true --json openclaw config set plugins.entries.memory-openviking.config.autoCapture true --json ``` -### Step 3: 启动并验证 +
    + +## 方式三 火山引擎 ECS 版 Openclaw 接入 OpenViking + +本部分主要介绍如何在火山引擎ECS上接入OpenViking,并使用WebConsole验证写入。详情可见[文档](https://www.volcengine.com/docs/6396/2249500?lang=zh)。 + +需注意 ECS 实例为了保护系统 Python 不被弄坏,在根目录(root)部署会有限制,不能直接用 pip 装全局包,推荐先创建虚拟环境,在虚拟环境下完成以下操作步骤。 + +**前置:** 已有 ECS OpenClaw实例。 + +### Step 1: npm 安装 + +```python +npm install -g openclaw-openviking-setup-helper +ov-install +``` +本安装模式已经在OpenViking内置了vlm和embedding模型,若不需要修改,直接按回车,按照指引填入API key即可. 安装完成后,会自动生成配置文件,如需修改,输入 vim ~/.openviking/ov.conf,按 i 进入编辑模式,按 esc 键退出编辑模式,输入 :wq 按回车键,保存并退出文件。 + +终端加载 OpenClaw 环境变量: ```bash -openclaw gateway -openclaw status +source /root/.openclaw/openviking.env ``` +### Step 2: 启动OpenViking + +先启动 OpenViking Server: + +```python +python -m openviking.server.bootstrap +``` +然后启动 web 控制台,启动之前,需要确认本实例安全组是否已经在入向规则处开放 TCP 8020 端口,若没有,需先点击实例安全组配置: + +```python +python -m openviking.console.bootstrap --host 0.0.0.0 --port 8020 --openviking-url http://127.0.0.1:1933 +``` +在实例中,找到你的服务器公网IP,用你的服务器公网IP访问: http://你的服务器公网IP:8020 + +即可开始体验 web console 🎉 + +你可以直接在web界面查询文件信息,验证OpenViking memory-plugin记忆写入是否生效;也可以可以在OpenClaw日志中验证memory-openviking是否读取记忆,验证方式: + + +```bash +grep -i inject /tmp/openclaw/openclaw-2026-03-13.log | awk -F'"' '{for(i=1;i<=NF;i++) if($i ~ /^[0-9]{2}:[0-9]{2}:[0-9]{2}/) {time=$i; break}} /injecting [0-9]+ memories/ {print time, "memory-openviking:", gensub(/.*(injecting [0-9]+ memories).*/, "\\1", "1")}' +``` + +也可以直接运行grep "inject" /tmp/openclaw/openclaw-2026-03-13.log查看全部信息。 + --- diff --git a/examples/openclaw-memory-plugin/INSTALL.md b/examples/openclaw-memory-plugin/INSTALL.md index 0907e5db..173253e9 100644 --- a/examples/openclaw-memory-plugin/INSTALL.md +++ b/examples/openclaw-memory-plugin/INSTALL.md @@ -1,449 +1,252 @@ -# Install OpenViking Memory for OpenClaw - -Give [OpenClaw](https://github.com/openclaw/openclaw) long-term memory powered by [OpenViking](https://github.com/volcengine/OpenViking). After setup, OpenClaw will automatically **remember** facts from conversations and **recall** relevant context before responding. +# Installing OpenViking for OpenClaw + +Provide long-term memory capabilities for [OpenClaw](https://github.com/openclaw/openclaw) via [OpenViking](https://github.com/volcengine/OpenViking). After installing, OpenClaw will automatically **remember** important information from conversations and **recall** relevant content before replying. The latest version of OpenViking includes a [WebConsole](https://github.com/volcengine/OpenViking/tree/main/openviking/console) for debugging and operations. Method 3 in this document also provides instructions on how to verify that memories are written via the WebConsole interface. We welcome you to try it out and provide feedback. + +> **⚠️ OpenClaw >= 2026.3.12 Compatibility Issue** +> +> OpenClaw `2026.3.12` and later have a known issue that causes conversations to hang after loading the plugin. +> This is not a bug in our plugin — the root cause is OpenClaw 3.12's slug generator (automatic conversation naming), +> which has a hardcoded 15s timeout that cascades when the LLM provider responds slowly, blocking the entire +> session initialization pipeline. Additionally, 3.12's new plugin trust mechanism may affect loading order for +> locally installed plugins. A separate issue: the `before_agent_start` auto-recall hook lacks timeout protection, +> which can cause the agent to hang silently ([#673](https://github.com/volcengine/OpenViking/issues/673)). +> +> **Workaround:** Downgrade to `2026.3.11`: `npm install -g openclaw@2026.3.11` +> +> Upstream fix PRs: openclaw/openclaw#34673, openclaw/openclaw#33547. +> See [#591](https://github.com/volcengine/OpenViking/issues/591) for details. + +> **🚀 Plugin 2.0 In Design** +> +> We are designing Plugin 2.0, rebuilt on the context-engine architecture — the best practice for integrating +> OpenViking with AI coding assistants. Join the discussion: +> https://github.com/volcengine/OpenViking/discussions/525 --- -## One-Click Install (Linux / macOS) +## One-Click Installation + +**Prerequisites:** Python >= 3.10, Node.js >= 22. The setup helper will automatically check and prompt you to install any missing components. -**Prerequisites:** Python >= 3.10, Node.js >= 22. The script checks these and prompts you to install any missing components. +### Method A: npm Installation (Recommended, Cross-platform) ```bash -curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash +npm install -g openclaw-openviking-setup-helper +ov-install + ``` -Non-interactive mode: +Non-interactive mode (uses default configuration): ```bash -curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash -s -y +ov-install -y + ``` Install to a specific OpenClaw instance: ```bash -curl -fsSL ... | bash -s -- --workdir ~/.openclaw-openclaw-second -``` +ov-install --workdir ~/.openclaw-second -Remote mode (connect to an existing OpenViking server, no Python/OpenViking required): - -```bash -# The script will prompt for mode selection (local/remote) -curl -fsSL ... | bash ``` -The script will: 1) select target OpenClaw instance (auto-detects multiple instances), 2) select mode (local/remote), 3) validate environment and install (local mode), 4) configure and deploy the memory plugin. - ---- - -## 1. Quick Start (Let OpenClaw Install It) - -Copy the skill file into OpenClaw's skill directory, then let OpenClaw handle the rest: - -**Linux / macOS:** +### Method B: curl One-Click Installation (Linux / macOS) ```bash -mkdir -p ~/.openclaw/skills/install-openviking-memory -cp examples/openclaw-memory-plugin/skills/install-openviking-memory/SKILL.md \ - ~/.openclaw/skills/install-openviking-memory/ -``` - -**Windows (cmd):** +curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash -```cmd -mkdir "%USERPROFILE%\.openclaw\skills\install-openviking-memory" -copy examples\openclaw-memory-plugin\skills\install-openviking-memory\SKILL.md ^ - "%USERPROFILE%\.openclaw\skills\install-openviking-memory\" ``` -Then tell OpenClaw: **"Install OpenViking memory"** — it will read the skill and complete the setup. - -For manual installation, continue reading. - ---- - -## 2. Prerequisites - -### Overview +Non-interactive mode: -| Component | Version | Purpose | Required? | -|-----------|---------|---------|-----------| -| **Python** | >= 3.10 | OpenViking runtime | Yes | -| **Node.js** | >= 22 | OpenClaw runtime + setup helper | Yes | -| **cmake** | — | Compile C++ extensions (OpenViking + OpenClaw's node-llama-cpp) | Yes | -| **g++ (gcc-c++)** | — | C++ compiler | Yes | -| **Go** | >= 1.19 | Compile AGFS server (Linux source install only) | Source install only | -| **Volcengine Ark API Key** | — | Embedding + VLM model calls | Yes | +```bash +curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash -s -y -> **PyPI vs Source install:** -> - `pip install openviking --upgrade --force-reinstall` (pre-built package): needs Python, cmake, g++ — **no Go required** -> - `pip install -e . --force-reinstall` (source install): needs Python, cmake, g++ **and Go >= 1.19** (to compile AGFS on Linux) -> - **Windows** users can use pre-built wheel packages without Go +``` -### Quick Check +Install to a specific OpenClaw instance: ```bash -python3 --version # >= 3.10 -node -v # >= v22 -cmake --version # installed -g++ --version # installed -go version # >= go1.25 (source install only) +curl -fsSL ... | bash -s -- --workdir ~/.openclaw-openclaw-second + ``` -If all commands pass, skip ahead to [Section 4: Installation Steps](#4-installation-steps). +The script will automatically detect multiple OpenClaw instances and let you choose. It will also prompt you to select local/remote mode—remote mode connects to a remote OpenViking service and does not require installing Python. --- -## 3. Environment Setup (Linux) +## Prerequisites -> Skip this section if your system already meets the prerequisites above. +| Component | Version Requirement | Purpose | +| --- | --- | --- | +| **Python** | >= 3.10 | OpenViking Runtime | +| **Node.js** | >= 22 | OpenClaw Runtime | +| **Volcengine Ark API Key** | — | Embedding + VLM model calls | -### 3.1 Install Build Tools - -> Already installed? Run `cmake --version && g++ --version` — if both show output, skip this step. - -**RHEL / CentOS / openEuler / Fedora:** +Quick check: ```bash -sudo dnf install -y gcc gcc-c++ cmake make -``` +python3 --version # >= 3.10 +node -v # >= v22 +openclaw --version # Installed -**Ubuntu / Debian:** - -```bash -sudo apt update -sudo apt install -y build-essential cmake ``` -### 3.2 Install Python 3.10+ - -> Already installed? Run `python3 --version` — if it shows >= 3.10, skip this step. +* Python: [https://www.python.org/downloads/](https://www.python.org/downloads/) +* Node.js: [https://nodejs.org/](https://nodejs.org/) +* OpenClaw: `npm install -g openclaw && openclaw onboard` -Many Linux distributions (e.g. openEuler 22.03, CentOS 7/8) ship with Python 3.9 or older, and their repositories often do not include Python 3.10+ packages. Building from source is recommended. - -#### Option A: Build from Source (recommended) +--- -```bash -# 1. Install build dependencies -# RHEL / CentOS / openEuler / Fedora: -sudo dnf install -y gcc make openssl-devel bzip2-devel libffi-devel \ - zlib-devel readline-devel sqlite-devel xz-devel tk-devel - -# Ubuntu / Debian: -# sudo apt install -y build-essential libssl-dev libbz2-dev libffi-dev \ -# zlib1g-dev libreadline-dev libsqlite3-dev liblzma-dev tk-dev - -# 2. Download and build -cd /tmp -curl -O https://www.python.org/ftp/python/3.11.12/Python-3.11.12.tgz -tar xzf Python-3.11.12.tgz -cd Python-3.11.12 -./configure --prefix=/usr/local --enable-optimizations --enable-shared \ - LDFLAGS="-Wl,-rpath /usr/local/lib" -make -j$(nproc) -sudo make altinstall - -# 3. Create symlinks so python3 / pip3 point to the new version -sudo ln -sf /usr/local/bin/python3.11 /usr/local/bin/python3 -sudo ln -sf /usr/local/bin/pip3.11 /usr/local/bin/pip3 - -# 4. Verify -python3 --version # Any version >= 3.10 is acceptable -``` +## Method 1: Local Deployment (Recommended) -> **Tip:** Use `altinstall` instead of `install` to avoid overwriting the system default Python. `/usr/local/bin` typically has higher priority in `PATH`, so the symlinks make `python3` point to the new version. +Start the OpenViking service locally, suitable for personal use. -#### Option B: Install via Package Manager (available on some distros) +### Step 1: Install OpenViking ```bash -# RHEL / CentOS / openEuler / Fedora (may not be available) -sudo dnf install -y python3.11 python3.11-devel python3.11-pip - -# Ubuntu 22.04+ ships with Python 3.10 -sudo apt install -y python3 python3-dev python3-pip python3-venv - -# Ubuntu 20.04 or older, add the deadsnakes PPA first -sudo add-apt-repository ppa:deadsnakes/ppa -sudo apt install -y python3.11 python3.11-dev python3.11-venv -``` +python3 -m pip install openviking --upgrade -> If `dnf install python3.11` reports `No match for argument`, your repository does not have this package. Please use the source build method above. - -After installation, upgrade pip: - -```bash -python3 -m pip install --upgrade pip ``` -> Downloads slow? See [Appendix: Network Acceleration](#8-network-acceleration-mirrors--proxies) to configure pip mirrors. +Verification: `python3 -c "import openviking; print('ok')"` -### 3.3 Install Node.js >= 22 +> Encountered `externally-managed-environment`? Use the one-click installation script (which handles venv automatically) or create it manually: +> `python3 -m venv ~/.openviking/venv && ~/.openviking/venv/bin/pip install openviking` -> Already installed? Run `node -v` — if it shows >= v22, skip this step. - -OpenClaw requires Node.js >= 22. The setup helper script also needs Node.js. - -#### Option A: Install via NodeSource (recommended) +### Step 2: Run the Setup Helper ```bash -# RHEL / CentOS / openEuler / Fedora -curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash - -sudo dnf install -y nodejs +# Method A: npm install (recommended, cross-platform) +npm install -g openclaw-openviking-setup-helper +ov-install -# Ubuntu / Debian -# curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash - -# sudo apt install -y nodejs +# Method B: curl one-click (Linux / macOS) +curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash ``` -#### Option B: Install via nvm (no root required) - -```bash -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash -source ~/.bashrc -nvm install 22 -nvm use 22 -``` +The setup helper will prompt you to enter your Ark API Key and automatically generate a configuration file. -#### Option C: Download binary package manually +### Step 3: Start ```bash -wget https://nodejs.org/dist/v22.14.0/node-v22.14.0-linux-x64.tar.xz -sudo tar -C /usr/local -xJf node-v22.14.0-linux-x64.tar.xz -echo 'export PATH=$PATH:/usr/local/node-v22.14.0-linux-x64/bin' >> ~/.bashrc -source ~/.bashrc -``` - -> For ARM architecture, replace `linux-x64` with `linux-arm64`. - -Verify: +source ~/.openclaw/openviking.env && openclaw gateway -```bash -node -v # >= v22 -npm -v ``` -### 3.4 Install Go >= 1.19 (source install only) - -> Already installed? Run `go version` — if it shows >= go1.25, skip this step. -> Also skippable if using `pip install openviking --upgrade --force-reinstall` (pre-built package). +Seeing `memory-openviking: local server started` indicates success. -Go is required on Linux to compile the AGFS server when installing from source. +### Step 4: Verify ```bash -# Download (for ARM use go1.25.6.linux-arm64.tar.gz) -wget https://go.dev/dl/go1.25.6.linux-amd64.tar.gz - -# Extract -sudo rm -rf /usr/local/go -sudo tar -C /usr/local -xzf go1.25.6.linux-amd64.tar.gz - -# Configure environment variables -cat >> ~/.bashrc << 'EOF' -export GOROOT=/usr/local/go -export GOPATH=$HOME/go -export PATH=$PATH:$GOROOT/bin:$GOPATH/bin -EOF -source ~/.bashrc - -# Verify -go version # >= go1.25 -``` - -> Go module downloads slow? See [Appendix: Network Acceleration](#8-network-acceleration-mirrors--proxies) to configure GOPROXY. - -### 3.5 Verify Environment +openclaw status +# The Memory row should display: enabled (plugin memory-openviking) -```bash -python3 --version # >= 3.10 -node -v # >= v22 -cmake --version # installed -g++ --version # installed -go version # >= go1.25 (source install only) ``` -All checks pass? Proceed to installation. - --- -## 4. Installation Steps +## Method 2: Connecting to Remote OpenViking -### 4.1 Install OpenClaw +Already have a running OpenViking service? Simply configure the OpenClaw plugin to point to the remote address; **no Python / OpenViking installation is required**. -> **Prerequisite:** cmake and g++ must be installed (OpenClaw depends on `node-llama-cpp`, which compiles C++ code during installation). +**Prerequisites:** An existing OpenViking service address + API Key (if authentication is enabled on the server side). -```bash -npm install -g openclaw -``` - -> Downloads slow? See [Appendix: Network Acceleration](#8-network-acceleration-mirrors--proxies) to configure npm mirrors. - -Run the onboarding wizard to configure your LLM: +### Step 1: Install Plugin ```bash -openclaw onboard +npm install -g openclaw-openviking-setup-helper +ov-install +# Select remote mode, enter your OpenViking server URL and API Key ``` -Verify: +### Step 2: Start and Verify ```bash -openclaw --version -``` - -### 4.2 Install OpenViking - -```bash -git clone https://github.com/volcengine/OpenViking.git -cd OpenViking +openclaw gateway restart +openclaw status ``` -#### Option A: Install from PyPI (recommended, no Go needed) +
    +Manual configuration (without setup helper) ```bash -python3 -m pip install openviking --upgrade --force-reinstall +openclaw config set plugins.enabled true --json +openclaw config set plugins.slots.memory memory-openviking +openclaw config set plugins.entries.memory-openviking.config.mode remote +openclaw config set plugins.entries.memory-openviking.config.baseUrl "http://your-server:1933" +openclaw config set plugins.entries.memory-openviking.config.apiKey "your-api-key" +openclaw config set plugins.entries.memory-openviking.config.agentId "your-agent-id" +openclaw config set plugins.entries.memory-openviking.config.autoRecall true --json +openclaw config set plugins.entries.memory-openviking.config.autoCapture true --json ``` -#### Option B: Install from Source (developer mode, requires Go) +
    -**Linux / macOS:** +## Method 3: Integrating Openclaw with OpenViking on Volcengine ECS -```bash -go version && cmake --version && g++ --version # Confirm tools are installed -python3 -m pip install -e . -``` +This section primarily introduces how to connect Openclaw to OpenViking on Volcengine ECS and use the WebConsole to verify the data write. For details, please refer to the [documentation](https://www.volcengine.com/docs/6396/2249500?lang=zh). -**Windows:** +Please note that to protect the system Python from being corrupted, the ECS instance has restrictions on deployments in the root directory and does not allow installing global packages directly using `pip`. It is recommended to create a virtual environment first and complete the following steps within it. -```powershell -python -m pip install -e . -``` +**Prerequisites:** An existing ECS OpenClaw instance. -> **Note:** Go >= 1.19 is **required** on Linux for source install (to compile AGFS). To force-skip (advanced users only): -> ```bash -> OPENVIKING_SKIP_AGFS_BUILD=1 python3 -m pip install -e . -> ``` +### Step 1: npm Installation -Verify: +```python +npm install -g openclaw-openviking-setup-helper +ov-install -```bash -python3 -c "import openviking; print('ok')" ``` -### 4.3 Run the Setup Helper +This installation mode already includes built-in VLM and embedding models in OpenViking. If no modifications are needed, simply press Enter and follow the prompts to enter your API key. After the installation is complete, a configuration file will be automatically generated. To modify it, enter `vim ~/.openviking/ov.conf`, press `i` to enter edit mode, press the `Esc` key to exit edit mode, then type `:wq` and press Enter to save and exit the file. -From the OpenViking repo root: +Load the OpenClaw environment variables in the terminal: ```bash -npx ./examples/openclaw-memory-plugin/setup-helper -``` +source /root/.openclaw/openviking.env -The helper will walk you through: - -1. **Environment check** — verifies cmake, g++, Python, Go, OpenClaw -2. **Install OpenViking** (if not already installed) -3. **Interactive configuration** — prompts for: - - Data storage path (defaults to absolute path, e.g. `/home/yourname/.openviking/data`) - - Volcengine Ark API Key - - VLM model name (default: `doubao-seed-2-0-pro-260215`) - - Embedding model name (default: `doubao-embedding-vision-251215`) - - Server ports (default: 1933 / 1833) -4. **Generate config** — creates `~/.openviking/ov.conf` -5. **Deploy plugin** — registers `memory-openviking` with OpenClaw -6. **Write env file** — generates `~/.openclaw/openviking.env` - -> Non-interactive mode: `npx ./examples/openclaw-memory-plugin/setup-helper -y` - -### 4.4 Start and Verify - -**Linux / macOS:** - -```bash -source ~/.openclaw/openviking.env && openclaw gateway ``` -**Windows (cmd):** +### Step 2: Start OpenViking -```cmd -call "%USERPROFILE%\.openclaw\openviking.env.bat" && openclaw gateway -``` +First, start the OpenViking Server: -You should see: +```python +python -m openviking.server.bootstrap ``` -[gateway] listening on ws://127.0.0.1:18789 -[gateway] memory-openviking: local server started (http://127.0.0.1:1933, config: ...) -``` - -Check plugin status: -```bash -openclaw status -# Memory line should show: enabled (plugin memory-openviking) -``` +Next, start the web console. Before starting, you need to confirm whether the instance's security group has opened TCP port 8020 in the inbound rules. If not, please configure the instance security group first: -Test memory: +```python +python -m openviking.console.bootstrap --host 0.0.0.0 --port 8020 --openviking-url http://127.0.0.1:1933 -```bash -openclaw tui ``` -Say: "Please remember: my favorite programming language is Python." - -In a later conversation, ask: "What is my favorite programming language?" +In the instance, find your server's public IP, and use it to access: `http://:8020` -OpenClaw should recall the answer from OpenViking memory. - ---- +You can now start experiencing the web console 🎉 -## 5. Daily Usage - -Each time you want to use OpenClaw with memory: - -**Linux / macOS:** +You can directly query file information on the web interface to verify whether the OpenViking `memory-plugin` memory write is effective; you can also verify if `memory-openviking` is reading memories in the OpenClaw logs. The verification method is as follows: ```bash -source ~/.openclaw/openviking.env && openclaw gateway -``` - -**Windows (cmd):** +grep -i inject /tmp/openclaw/openclaw-2026-03-13.log | awk -F'"' '{for(i=1;i<=NF;i++) if($i ~ /^[0-9]{2}:[0-9]{2}:[0-9]{2}/) {time=$i; break}} /injecting [0-9]+ memories/ {print time, "memory-openviking:", gensub(/.*(injecting [0-9]+ memories).*/, "\\1", "1")}' -```cmd -call "%USERPROFILE%\.openclaw\openviking.env.bat" && openclaw gateway ``` -> **Convenience (Linux/macOS):** Add to `~/.bashrc`: -> ```bash -> alias openclaw-start='source ~/.openclaw/openviking.env && openclaw gateway' -> ``` - -### 5.1 Enable or Disable the Memory Plugin - -Disable the OpenViking memory plugin: - -```bash -openclaw config set plugins.slots.memory none -``` - -Enable the OpenViking memory plugin: - -```bash -openclaw config set plugins.slots.memory memory-openviking -``` - -If the gateway is already running, restart it after changing the slot. - -The plugin automatically starts and stops the OpenViking server. +Alternatively, you can directly run `grep "inject" /tmp/openclaw/openclaw-2026-03-13.log` to view all the information. --- -## 6. Configuration Reference +## Configuration Reference -### `~/.openviking/ov.conf` +### `~/.openviking/ov.conf` (Local Mode) ```json { - "server": { - "host": "127.0.0.1", - "port": 1933 - }, + "root_api_key": null, + "server": { "host": "127.0.0.1", "port": 1933 }, "storage": { "workspace": "/home/yourname/.openviking/data", "vectordb": { "backend": "local" }, @@ -452,7 +255,7 @@ The plugin automatically starts and stops the OpenViking server. "embedding": { "dense": { "provider": "volcengine", - "api_key": "", + "api_key": "", "model": "doubao-embedding-vision-251215", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "dimension": 1024, @@ -461,285 +264,80 @@ The plugin automatically starts and stops the OpenViking server. }, "vlm": { "provider": "volcengine", - "api_key": "", + "api_key": "", "model": "doubao-seed-2-0-pro-260215", - "api_base": "https://ark.cn-beijing.volces.com/api/v3", - "temperature": 0.1, - "max_retries": 3 + "api_base": "https://ark.cn-beijing.volces.com/api/v3" } } -``` - -> **Note:** `workspace` must be an **absolute path** (e.g. `/home/yourname/.openviking/data`). Tilde (`~`) and relative paths are not supported. The setup helper fills this in automatically. - -### `~/.openclaw/openviking.env` -Auto-generated by the setup helper: - -```bash -export OPENVIKING_PYTHON='/usr/local/bin/python3' -export OPENVIKING_GO_PATH='/usr/local/go/bin' # optional ``` -Windows version (`openviking.env.bat`): - -```cmd -set OPENVIKING_PYTHON=C:\path\to\python.exe -set OPENVIKING_GO_PATH=C:\path\to\go\bin -``` - -### Setup Helper Options - -``` -npx ./examples/openclaw-memory-plugin/setup-helper [options] - - -y, --yes Non-interactive, use defaults - --workdir OpenClaw config directory (default: ~/.openclaw) - -h, --help Show help - -Environment variables: - OPENVIKING_PYTHON Python interpreter path - OPENVIKING_CONFIG_FILE Custom ov.conf path - OPENVIKING_REPO Local repo path (auto-detected when run from repo) - OPENVIKING_ARK_API_KEY Volcengine API Key (skip prompt in -y mode) -``` - ---- +> `root_api_key`: Once set, all HTTP requests must carry the `X-API-Key` header. Defaults to `null` in local mode (authentication disabled). -## 7. Troubleshooting +### `agentId` Configuration (Plugin Configuration) -### Installation Issues +The Agent identifier passed to the server via the `X-OpenViking-Agent` header, used to distinguish different OpenClaw instances. -#### `cmake not found` / `g++ not found` - -OpenClaw depends on `node-llama-cpp` (compiles C++), and OpenViking's C++ extensions also need cmake/g++. - -```bash -# RHEL / CentOS / openEuler -sudo dnf install -y gcc gcc-c++ cmake make - -# Ubuntu / Debian -sudo apt install -y build-essential cmake -``` - -#### `No matching distribution found for python-multipart>=0.0.22` - -pip is using Python 3.9. Make sure you're using Python 3.10+: +Customization method: ```bash -python3 --version # Confirm >= 3.10 -python3 -m pip install -e . -``` - -#### `fatal error: Python.h: No such file or directory` - -Missing Python development headers: - -```bash -# RHEL / CentOS / openEuler -sudo dnf install -y python3-devel # or python3.11-devel - -# Ubuntu / Debian -sudo apt install -y python3-dev # or python3.11-dev -``` - -> If Python was built from source, development headers are already included. - -#### `Go compiler not found` / AGFS build failure - -Go >= 1.19 is **required** on Linux for source install. See [3.4 Install Go](#34-install-go--119-source-install-only). +# Specify in the plugin configuration +openclaw config set plugins.entries.memory-openviking.config.agentId "my-agent" -```bash -go version # Confirm >= 1.19 -python3 -m pip install -e . ``` -#### Go module download timeout (`dial tcp: i/o timeout`) - -Configure Go proxy. See [Appendix: Network Acceleration](#8-network-acceleration-mirrors--proxies). - -#### npm `ERR_INVALID_URL` +If not configured, the plugin will automatically generate a random, unique ID (format: `openclaw--`). -Usually caused by malformed proxy environment variables. Proxy URLs **must** include the `http://` prefix: - -```bash -# Wrong -export https_proxy=192.168.1.1:7897 - -# Correct -export https_proxy=http://192.168.1.1:7897 -``` +### `~/.openclaw/openviking.env` -Or clear proxies entirely: +Automatically generated by the setup helper, recording environment variables such as the Python path: ```bash -unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY -``` - -#### npm `ENOTEMPTY` - -Previous install was interrupted. Clean up and retry: +export OPENVIKING_PYTHON='/usr/local/bin/python3' -```bash -rm -rf $(npm root -g)/openclaw $(npm root -g)/.openclaw-* -npm install -g openclaw ``` -### Runtime Issues - -#### Plugin not showing in gateway output - -- Did you load the env file before `openclaw gateway`? - - Linux/macOS: `source ~/.openclaw/openviking.env` - - Windows: `call "%USERPROFILE%\.openclaw\openviking.env.bat"` -- Run `openclaw status` to check plugin state -- Re-run setup: `npx ./examples/openclaw-memory-plugin/setup-helper` - -#### `health check timeout at http://127.0.0.1:1933` +--- -A stale process is occupying the port. Kill it and restart: +## Daily Usage ```bash -# Linux / macOS -lsof -ti tcp:1933 tcp:1833 | xargs kill -9 +# Start source ~/.openclaw/openviking.env && openclaw gateway -``` - -```cmd -REM Windows -for /f "tokens=5" %a in ('netstat -ano ^| findstr "LISTENING" ^| findstr ":1933 :1833"') do taskkill /PID %a /F -call "%USERPROFILE%\.openclaw\openviking.env.bat" && openclaw gateway -``` - -#### `extracted 0 memories` - -Model configuration in `ov.conf` is incorrect. Check: -- `embedding.dense.api_key` is a valid Volcengine Ark API key -- `vlm.api_key` is set (usually the same key) -- `vlm.model` is a model name (e.g. `doubao-seed-2-0-pro-260215`), **not** the API key - -### Python Version Issues - -#### `TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'` - -Python version is below 3.10 (`X | None` syntax requires 3.10+). Upgrade Python — see [3.2 Install Python](#32-install-python-310). - -#### `pip install -e .` installs to the wrong Python +# Disable memory +openclaw config set plugins.slots.memory none -Use an explicit Python path: +# Enable memory +openclaw config set plugins.slots.memory memory-openviking -```bash -python3.11 -m pip install -e . -export OPENVIKING_PYTHON=python3.11 -npx ./examples/openclaw-memory-plugin/setup-helper ``` -#### Error: `externally-managed-environment` / `This environment is externally managed` - -On Ubuntu, Debian and similar systems, the system Python is managed (PEP 668) and does not allow installing packages with `pip` into the system environment. Two options: - -1. **Recommended:** Use the one-line install script; it will create a venv at `~/.openviking/venv` and install OpenViking there automatically. - ```bash - curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash - ``` - -2. **Manual install:** Install `python3-venv`, create a venv, and install OpenViking inside it: - ```bash - sudo apt install -y python3-venv # or python3-full - python3 -m venv ~/.openviking/venv - ~/.openviking/venv/bin/pip install openviking - export OPENVIKING_PYTHON=~/.openviking/venv/bin/python - ``` - Alternatively use pipx: `pipx install openviking` (install pipx first: `apt install pipx`). - --- -## 8. Network Acceleration (Mirrors & Proxies) - -> Use these if package downloads are slow in your network environment. - -### pip Mirror +## Troubleshooting -```bash -# Permanent (recommended) -python3 -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple -python3 -m pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn - -# Alternatives -# Alibaba Cloud: https://mirrors.aliyun.com/pypi/simple/ -# Huawei Cloud: https://repo.huaweicloud.com/repository/pypi/simple/ -# Tencent Cloud: https://mirrors.cloud.tencent.com/pypi/simple/ -``` - -Single-use: - -```bash -python3 -m pip install openviking --upgrade --force-reinstall -i https://pypi.tuna.tsinghua.edu.cn/simple -``` - -### npm Mirror - -```bash -# Permanent (recommended) -npm config set registry https://registry.npmmirror.com - -# Single-use -npm install -g openclaw --registry=https://registry.npmmirror.com -``` - -### Go Proxy - -```bash -# goproxy.cn (recommended) -go env -w GOPROXY=https://goproxy.cn,direct - -# Alibaba Cloud -# go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct - -# Disable checksum verification (may be needed for some modules) -go env -w GONOSUMCHECK=* - -# Verify -go env GOPROXY -``` - -> Takes effect globally for the current user. Subsequent `pip install -e .` builds that compile AGFS will use this automatically. +| Symptom | Cause | Fix | +| --- | --- | --- | +| `port occupied` | Port occupied by another process | Change port: `openclaw config set plugins.entries.memory-openviking.config.port 1934` | +| `extracted 0 memories` | API Key or model name configured incorrectly | Check the `api_key` and `model` fields in `ov.conf` | +| Plugin not loaded | Environment variables not loaded | Execute `source ~/.openclaw/openviking.env` before starting | +| `externally-managed-environment` | Python PEP 668 restriction | Use venv or the one-click installation script | +| `TypeError: unsupported operand type(s) for|` | Python < 3.10 | Upgrade Python to 3.10+ | --- -## 9. Uninstall - -**Linux / macOS:** +## Uninstallation ```bash -# Stop services lsof -ti tcp:1933 tcp:1833 tcp:18789 | xargs kill -9 +npm uninstall -g openclaw && rm -rf ~/.openclaw +python3 -m pip uninstall openviking -y && rm -rf ~/.openviking -# Remove OpenClaw -npm uninstall -g openclaw -rm -rf ~/.openclaw - -# Remove OpenViking -python3 -m pip uninstall openviking -y -rm -rf ~/.openviking ``` -**Windows (cmd):** - -```cmd -REM Stop services -for /f "tokens=5" %a in ('netstat -ano ^| findstr "LISTENING" ^| findstr ":1933 :1833 :18789"') do taskkill /PID %a /F - -REM Remove OpenClaw -npm uninstall -g openclaw -rmdir /s /q "%USERPROFILE%\.openclaw" +--- -REM Remove OpenViking -python -m pip uninstall openviking -y -rmdir /s /q "%USERPROFILE%\.openviking" -``` +**See also:** [INSTALL-ZH.md](https://github.com/volcengine/OpenViking/blob/main/examples/openclaw-memory-plugin/INSTALL-ZH.md) (Chinese) · [INSTALL-AGENT.md](https://www.google.com/search?q=./INSTALL-AGENT.md) (Agent Install Guide) --- - -**See also:** [INSTALL-ZH.md](./INSTALL-ZH.md) (Chinese version) diff --git a/examples/openclaw-memory-plugin/README.md b/examples/openclaw-memory-plugin/README.md index 363cb570..da84b392 100644 --- a/examples/openclaw-memory-plugin/README.md +++ b/examples/openclaw-memory-plugin/README.md @@ -1,63 +1,75 @@ # OpenClaw + OpenViking Memory Plugin -Use OpenViking as the long-term memory backend for [OpenClaw](https://github.com/openclaw/openclaw). +Use [OpenViking](https://github.com/volcengine/OpenViking) as the long-term memory backend for [OpenClaw](https://github.com/openclaw/openclaw). Once installed, OpenClaw will automatically **remember** important information from conversations and **recall** relevant context before responding. -## Quick Start +> **⚠️ OpenClaw >= 2026.3.12 Compatibility Issue** +> +> OpenClaw `2026.3.12` and later have a known issue that causes conversations to hang after loading the plugin. +> This is not a bug in our plugin — the root cause is OpenClaw 3.12's slug generator (automatic conversation naming), +> which has a hardcoded 15s timeout that cascades when the LLM provider responds slowly, blocking the entire +> session initialization pipeline. Additionally, 3.12's new plugin trust mechanism may affect loading order for +> locally installed plugins. A separate issue: the `before_agent_start` auto-recall hook lacks timeout protection, +> which can cause the agent to hang silently ([#673](https://github.com/volcengine/OpenViking/issues/673)). +> +> **Workaround:** Downgrade to `2026.3.11`: `npm install -g openclaw@2026.3.11` +> +> Upstream fix PRs: openclaw/openclaw#34673, openclaw/openclaw#33547. +> See [#591](https://github.com/volcengine/OpenViking/issues/591) for details. -```bash -cd /path/to/OpenViking -npx ./examples/openclaw-memory-plugin/setup-helper -openclaw gateway -``` +> **🚀 Plugin 2.0 In Design** +> +> We are designing Plugin 2.0, rebuilt on the context-engine architecture — the best practice for integrating +> OpenViking with AI coding assistants. Join the discussion: +> https://github.com/volcengine/OpenViking/discussions/525 -The setup helper checks the environment, creates `~/.openviking/ov.conf`, deploys the plugin, and configures OpenClaw automatically. It supports both **local** and **remote** modes and auto-detects multiple OpenClaw instances. +--- -## Manual Setup +## Table of Contents -### Local Mode +- [One-Click Installation](#one-click-installation) +- [Manual Setup](#manual-setup) + - [Prerequisites](#prerequisites) + - [Local Mode (Personal Use)](#local-mode-personal-use) + - [Remote Mode (Team Sharing)](#remote-mode-team-sharing) + - [Volcengine ECS Deployment](#volcengine-ecs-deployment) +- [Starting & Verification](#starting--verification) +- [Configuration Reference](#configuration-reference) +- [Daily Usage](#daily-usage) +- [Web Console (Visualization)](#web-console-visualization) +- [Troubleshooting](#troubleshooting) +- [Uninstallation](#uninstallation) -Prerequisites: **OpenClaw** (`npm install -g openclaw`), **Python >= 3.10** with `openviking` (`pip install openviking --upgrade --force-reinstall`). +--- -```bash -# Install plugin -mkdir -p ~/.openclaw/extensions/memory-openviking -cp examples/openclaw-memory-plugin/{index.ts,config.ts,client.ts,process-manager.ts,memory-ranking.ts,text-utils.ts,openclaw.plugin.json,package.json,.gitignore} \ - ~/.openclaw/extensions/memory-openviking/ -cd ~/.openclaw/extensions/memory-openviking && npm install +## One-Click Installation -# Configure (local mode — plugin auto-starts OpenViking) -openclaw config set plugins.enabled true -openclaw config set plugins.slots.memory memory-openviking -openclaw config set plugins.entries.memory-openviking.config.mode "local" -openclaw config set plugins.entries.memory-openviking.config.configPath "~/.openviking/ov.conf" -openclaw config set plugins.entries.memory-openviking.config.targetUri "viking://user/memories" -openclaw config set plugins.entries.memory-openviking.config.autoRecall true --json -openclaw config set plugins.entries.memory-openviking.config.autoCapture true --json +For users who want a quick local experience. The setup helper handles environment detection, dependency installation, and config file generation automatically. -# Start -source ~/.openclaw/openviking.env && openclaw gateway -``` +### Method A: npm Install (Recommended, Cross-platform) -### Remote Mode +```bash +npm install -g openclaw-openviking-setup-helper +ov-install +``` -Prerequisites: **OpenClaw** only. No Python/OpenViking needed. +### Method B: curl One-Click (Linux / macOS) ```bash -openclaw config set plugins.enabled true -openclaw config set plugins.slots.memory memory-openviking -openclaw config set plugins.entries.memory-openviking.config.mode "remote" -openclaw config set plugins.entries.memory-openviking.config.baseUrl "http://your-server:1933" -openclaw config set plugins.entries.memory-openviking.config.apiKey "your-api-key" # optional -openclaw config set plugins.entries.memory-openviking.config.autoRecall true --json -openclaw config set plugins.entries.memory-openviking.config.autoCapture true --json - -openclaw gateway +curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash ``` -## Setup Helper Options +The setup helper will walk you through: + +1. **Environment check** — Detects Python >= 3.10, Node.js, cmake, etc. +2. **Select OpenClaw instance** — If multiple instances are installed locally, lists them for you to choose +3. **Select deployment mode** — Local or Remote (see below) +4. **Generate config** — Writes `~/.openviking/ov.conf` and `~/.openclaw/openviking.env` automatically + +
    +Setup helper options ``` -npx openclaw-openviking-setup-helper [options] +ov-install [options] -y, --yes Non-interactive, use defaults --workdir OpenClaw config directory (default: ~/.openclaw) @@ -70,36 +82,380 @@ Env vars: OPENVIKING_ARK_API_KEY Volcengine API Key (skip prompt in -y mode) ``` -## ov.conf Example +
    + +--- + +## Manual Setup + +### Prerequisites + +| Component | Version | Purpose | +|-----------|---------|---------| +| **Python** | >= 3.10 | OpenViking runtime (Local mode) | +| **Node.js** | >= 22 | OpenClaw runtime | +| **Volcengine Ark API Key** | — | Embedding + VLM model calls | + +```bash +python3 --version # >= 3.10 +node -v # >= v22 +openclaw --version # installed +``` + +- Python: https://www.python.org/downloads/ +- Node.js: https://nodejs.org/ +- OpenClaw: `npm install -g openclaw@2026.3.11 && openclaw onboard` + +--- + +### Local Mode (Personal Use) + +The simplest option — nearly zero configuration. The memory service runs alongside your OpenClaw agent locally. You only need a Volcengine Ark API Key. + +#### Step 1: Install OpenViking + +```bash +python3 -m pip install openviking --upgrade +``` + +Verify: `python3 -c "import openviking; print('ok')"` + +> Hit `externally-managed-environment`? Use the one-click installer (handles venv automatically) or create one manually: +> ```bash +> python3 -m venv ~/.openviking/venv && ~/.openviking/venv/bin/pip install openviking +> ``` + +#### Step 2: Run the Setup Helper + +```bash +# Method A: npm install (recommended, cross-platform) +npm install -g openclaw-openviking-setup-helper +ov-install + +# Method B: curl one-click (Linux / macOS) +curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/examples/openclaw-memory-plugin/install.sh | bash +``` + +Select **local** mode, keep defaults, and enter your Ark API Key. + +Generated config files: +- `~/.openviking/ov.conf` — OpenViking service config +- `~/.openclaw/openviking.env` — Environment variables (Python path, etc.) + +#### Step 3: Start + +```bash +source ~/.openclaw/openviking.env && openclaw gateway restart +``` + +> In Local mode you must `source` the env file first — the plugin auto-starts an OpenViking subprocess. + +#### Step 4: Verify + +```bash +openclaw status +# Memory row should show: enabled (plugin memory-openviking) +``` + +--- + +### Remote Mode (Team Sharing) + +For multiple OpenClaw instances or team use. Deploy a standalone OpenViking service that is shared across agents. **No Python/OpenViking needed on the client side.** + +#### Step 1: Deploy the OpenViking Service + +Edit `~/.openviking/ov.conf` — set `root_api_key` to enable multi-tenancy: ```json { + "server": { + "host": "127.0.0.1", + "port": 1933, + "root_api_key": "", + "cors_origins": ["*"] + }, + "storage": { + "workspace": "~/.openviking/data", + "vectordb": { + "name": "context", + "backend": "local" + }, + "agfs": { + "log_level": "warn", + "backend": "local" + } + }, + "embedding": { + "dense": { + "provider": "volcengine", + "api_key": "", + "model": "doubao-embedding-vision-251215", + "api_base": "https://ark.cn-beijing.volces.com/api/v3", + "dimension": 1024, + "input": "multimodal" + } + }, "vlm": { "provider": "volcengine", - "api_key": "", + "api_key": "", "model": "doubao-seed-2-0-pro-260215", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "temperature": 0.1, "max_retries": 3 + } +} +``` + +Start the service: + +```bash +openviking-server +``` + +#### Step 2: Create Team & Users + +```bash +# Create team + admin +curl -X POST http://localhost:1933/api/v1/admin/accounts \ + -H "Content-Type: application/json" \ + -H "X-API-Key: " \ + -d '{ + "account_id": "my-team", + "admin_user_id": "admin" + }' + +# Add member +curl -X POST http://localhost:1933/api/v1/admin/accounts/my-team/users \ + -H "Content-Type: application/json" \ + -H "X-API-Key: " \ + -d '{ + "user_id": "xiaomei", + "role": "user" + }' +``` + +#### Step 3: Configure the OpenClaw Plugin + +```bash +openclaw config set plugins.enabled true --json +openclaw config set plugins.slots.memory memory-openviking +openclaw config set plugins.entries.memory-openviking.config.mode remote +openclaw config set plugins.entries.memory-openviking.config.baseUrl "http://your-server:1933" +openclaw config set plugins.entries.memory-openviking.config.apiKey "" +openclaw config set plugins.entries.memory-openviking.config.agentId "" +openclaw config set plugins.entries.memory-openviking.config.autoRecall true --json +openclaw config set plugins.entries.memory-openviking.config.autoCapture true --json +``` + +#### Step 4: Start & Verify + +```bash +# Remote mode — no env sourcing needed +openclaw gateway restart +openclaw status +``` + +--- + +### Volcengine ECS Deployment + +Deploy OpenClaw + OpenViking on Volcengine ECS. See [Volcengine docs](https://www.volcengine.com/docs/6396/2249500?lang=zh) for details. + +> ECS instances restrict global pip installs under root to protect system Python. Create a venv first. + +```bash +# 1. Install +npm install -g openclaw-openviking-setup-helper +ov-install + +# 2. Load environment +source /root/.openclaw/openviking.env + +# 3. Start OpenViking server +python -m openviking.server.bootstrap + +# 4. Start Web Console (ensure security group allows TCP 8020 inbound) +python -m openviking.console.bootstrap --host 0.0.0.0 --port 8020 --openviking-url http://127.0.0.1:1933 +``` + +Access `http://:8020` to use the Web Console. + +--- + +## Starting & Verification + +### Local Mode + +```bash +source ~/.openclaw/openviking.env && openclaw gateway restart +``` + +### Remote Mode + +```bash +openclaw gateway restart +``` + +### Check Plugin Status + +```bash +openclaw status +# Memory row should show: enabled (plugin memory-openviking) +``` + +### View Plugin Config + +```bash +openclaw config get plugins.entries.memory-openviking.config +``` + +--- + +## Configuration Reference + +### `~/.openviking/ov.conf` (Local Mode) + +```json +{ + "root_api_key": null, + "server": { "host": "127.0.0.1", "port": 1933 }, + "storage": { + "workspace": "~/.openviking/data", + "vectordb": { "backend": "local" }, + "agfs": { "backend": "local", "port": 1833 } }, "embedding": { "dense": { "provider": "volcengine", - "api_key": "", + "api_key": "", "model": "doubao-embedding-vision-251215", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "dimension": 1024, "input": "multimodal" } + }, + "vlm": { + "provider": "volcengine", + "api_key": "", + "model": "doubao-seed-2-0-pro-260215", + "api_base": "https://ark.cn-beijing.volces.com/api/v3" } } ``` +> `root_api_key`: When set, all HTTP requests must include the `X-API-Key` header. Defaults to `null` in Local mode (auth disabled). + +### Plugin Config Options + +| Option | Default | Description | +|--------|---------|-------------| +| `mode` | `remote` | `local` (start local server) or `remote` (connect to remote) | +| `baseUrl` | `http://127.0.0.1:1933` | OpenViking server URL (Remote mode) | +| `apiKey` | — | OpenViking API Key (optional) | +| `agentId` | auto-generated | Agent identifier, distinguishes OpenClaw instances. Auto-generates `openclaw--` if unset | +| `configPath` | `~/.openviking/ov.conf` | Config file path (Local mode) | +| `port` | `1933` | Local server port (Local mode) | +| `targetUri` | `viking://user/memories` | Default memory search scope | +| `autoCapture` | `true` | Auto-extract memories after conversations | +| `captureMode` | `semantic` | Extraction mode: `semantic` (full semantic) / `keyword` (trigger-word only) | +| `captureMaxLength` | `24000` | Max text length per capture | +| `autoRecall` | `true` | Auto-recall relevant memories before conversations | +| `recallLimit` | `6` | Max memories injected during auto-recall | +| `recallScoreThreshold` | `0.01` | Minimum relevance score for recall | +| `ingestReplyAssist` | `true` | Add reply guidance when multi-party conversation text is detected | + +### `~/.openclaw/openviking.env` + +Auto-generated by the setup helper, stores environment variables like the Python path: + +```bash +export OPENVIKING_PYTHON='/usr/local/bin/python3' +``` + +--- + +## Daily Usage + +```bash +# Start (Local mode — source env first) +source ~/.openclaw/openviking.env && openclaw gateway + +# Start (Remote mode — no env needed) +openclaw gateway + +# Disable memory +openclaw config set plugins.slots.memory none + +# Re-enable memory +openclaw config set plugins.slots.memory memory-openviking +``` + +> Restart the gateway after changing the memory slot. + +--- + +## Web Console (Visualization) + +OpenViking provides a Web Console for debugging and inspecting stored memories. + +```bash +python -m openviking.console.bootstrap \ + --host 127.0.0.1 \ + --port 8020 \ + --openviking-url http://127.0.0.1:1933 \ + --write-enabled +``` + +Open http://127.0.0.1:8020 in your browser. + +--- + ## Troubleshooting -| Symptom | Fix | -|---------|-----| -| Memory shows `disabled` / `memory-core` | `openclaw config set plugins.slots.memory memory-openviking` | -| `memory_store failed: fetch failed` | Check OpenViking is running; verify `ov.conf` and Python path | -| `health check timeout` | `lsof -ti tcp:1933 \| xargs kill -9` then restart | -| `extracted 0 memories` | Ensure `ov.conf` has valid `vlm` and `embedding.dense` with API key | +### Common Issues + +| Symptom | Cause | Fix | +|---------|-------|-----| +| Conversation hangs, no response | OpenClaw >= 2026.3.12 compatibility issue | Downgrade to `2026.3.11`: `npm install -g openclaw@2026.3.11`. See [#591](https://github.com/volcengine/OpenViking/issues/591) | +| Agent hangs silently, no output | auto-recall missing timeout protection | Disable auto-recall temporarily: `openclaw config set plugins.entries.memory-openviking.config.autoRecall false --json`, or apply the patch in [#673](https://github.com/volcengine/OpenViking/issues/673) | +| Memory shows `disabled` / `memory-core` | Plugin slot not configured | `openclaw config set plugins.slots.memory memory-openviking` | +| `memory_store failed: fetch failed` | OpenViking not running | Check `ov.conf` and Python path; verify service is up | +| `health check timeout` | Port held by stale process | `lsof -ti tcp:1933 \| xargs kill -9`, then restart | +| `extracted 0 memories` | Wrong API Key or model name | Check `api_key` and `model` in `ov.conf` | +| `port occupied` | Port used by another process | Change port: `openclaw config set plugins.entries.memory-openviking.config.port 1934` | +| Plugin not loaded | Env file not sourced | Run `source ~/.openclaw/openviking.env` before starting | +| `externally-managed-environment` | Python PEP 668 restriction | Use venv or the one-click installer | +| `TypeError: unsupported operand type(s) for \|` | Python < 3.10 | Upgrade Python to 3.10+ | + +### Viewing Logs + +```bash +# OpenViking logs +cat ~/.openviking/data/log/openviking.log + +# OpenClaw gateway logs +cat ~/.openclaw/logs/gateway.log +cat ~/.openclaw/logs/gateway.err.log + +# Check if OpenViking process is alive +lsof -i:1933 + +# Quick connectivity check +curl http://localhost:1933 +# Expected: {"detail":"Not Found"} +``` + +--- + +## Uninstallation + +```bash +lsof -ti tcp:1933 tcp:1833 tcp:18789 | xargs kill -9 +npm uninstall -g openclaw && rm -rf ~/.openclaw +python3 -m pip uninstall openviking -y && rm -rf ~/.openviking +``` + +--- + +**See also:** [INSTALL-ZH.md](./INSTALL-ZH.md) (中文详细安装指南) · [INSTALL.md](./INSTALL.md) (English Install Guide) · [INSTALL-AGENT.md](./INSTALL-AGENT.md) (Agent Install Guide) diff --git a/examples/openclaw-memory-plugin/client.ts b/examples/openclaw-memory-plugin/client.ts index 9dd28bd5..edc11f48 100644 --- a/examples/openclaw-memory-plugin/client.ts +++ b/examples/openclaw-memory-plugin/client.ts @@ -29,8 +29,19 @@ export type LocalClientCacheEntry = { process: ReturnType | null; }; +export type PendingClientEntry = { + promise: Promise; + resolve: (c: OpenVikingClient) => void; + reject: (err: unknown) => void; +}; + export const localClientCache = new Map(); +// Module-level pending promise map: shared across all plugin registrations so +// that both [gateway] and [plugins] contexts await the same promise and +// don't create duplicate pending promises that never resolve. +export const localClientPendingPromises = new Map(); + const MEMORY_URI_PATTERNS = [ /^viking:\/\/user\/(?:[^/]+\/)?memories(?:\/|$)/, /^viking:\/\/agent\/(?:[^/]+\/)?memories(?:\/|$)/, @@ -47,16 +58,36 @@ export function isMemoryUri(uri: string): boolean { } export class OpenVikingClient { - private readonly resolvedSpaceByScope: Partial> = {}; + private resolvedSpaceByScope: Partial> = {}; private runtimeIdentity: RuntimeIdentity | null = null; constructor( private readonly baseUrl: string, private readonly apiKey: string, - private readonly agentId: string, + private agentId: string, private readonly timeoutMs: number, ) {} + /** + * Dynamically switch the agent identity for multi-agent memory isolation. + * When a shared client serves multiple agents (e.g. in OpenClaw multi-agent + * gateway), call this before each agent's recall/capture to route memories + * to the correct agent_space = md5(user_id + agent_id)[:12]. + * Clears cached space resolution so the next request re-derives agent_space. + */ + setAgentId(newAgentId: string): void { + if (newAgentId && newAgentId !== this.agentId) { + this.agentId = newAgentId; + // Clear cached identity and spaces — they depend on agentId + this.runtimeIdentity = null; + this.resolvedSpaceByScope = {}; + } + } + + getAgentId(): string { + return this.agentId; + } + private async request(path: string, init: RequestInit = {}): Promise { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), this.timeoutMs); @@ -131,10 +162,10 @@ export class OpenVikingClient { const identity = await this.getRuntimeIdentity(); const fallbackSpace = - scope === "user" ? identity.userId : md5Short(`${identity.userId}${identity.agentId}`); + scope === "user" ? identity.userId : md5Short(`${identity.userId}:${identity.agentId}`); const reservedDirs = scope === "user" ? USER_STRUCTURE_DIRS : AGENT_STRUCTURE_DIRS; const preferredSpace = - scope === "user" ? identity.userId : md5Short(`${identity.userId}${identity.agentId}`); + scope === "user" ? identity.userId : md5Short(`${identity.userId}:${identity.agentId}`); try { const entries = await this.ls(`viking://${scope}`); diff --git a/examples/openclaw-memory-plugin/index.ts b/examples/openclaw-memory-plugin/index.ts index 16d27950..f4f82f9a 100644 --- a/examples/openclaw-memory-plugin/index.ts +++ b/examples/openclaw-memory-plugin/index.ts @@ -5,7 +5,8 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk"; import { Type } from "@sinclair/typebox"; import { memoryOpenVikingConfigSchema } from "./config.js"; -import { OpenVikingClient, localClientCache, isMemoryUri } from "./client.js"; +import { OpenVikingClient, localClientCache, localClientPendingPromises, isMemoryUri } from "./client.js"; +import type { PendingClientEntry } from "./client.js"; import type { FindResultItem } from "./client.js"; import { getCaptureDecision, @@ -32,6 +33,10 @@ import { prepareLocalPort, } from "./process-manager.js"; +const MAX_OPENVIKING_STDERR_LINES = 200; +const MAX_OPENVIKING_STDERR_CHARS = 256_000; +const AUTO_RECALL_TIMEOUT_MS = 5_000; + const memoryPlugin = { id: "memory-openviking", name: "Memory (OpenViking)", @@ -48,7 +53,6 @@ const memoryPlugin = { let resolveLocalClient: ((c: OpenVikingClient) => void) | null = null; let rejectLocalClient: ((err: unknown) => void) | null = null; let localUnavailableReason: string | null = null; - const autoRecallTimeoutMs = 5_000; const markLocalUnavailable = (reason: string, err?: unknown) => { if (!localUnavailableReason) { @@ -72,10 +76,18 @@ const memoryPlugin = { localProcess = cached.process; clientPromise = Promise.resolve(cached.client); } else { - clientPromise = new Promise((resolve, reject) => { - resolveLocalClient = resolve; - rejectLocalClient = reject; - }); + const existingPending = localClientPendingPromises.get(localCacheKey); + if (existingPending) { + clientPromise = existingPending.promise; + } else { + const entry = {} as PendingClientEntry; + entry.promise = new Promise((resolve, reject) => { + entry.resolve = resolve; + entry.reject = reject; + }); + clientPromise = entry.promise; + localClientPendingPromises.set(localCacheKey, entry); + } } } else { clientPromise = Promise.resolve(new OpenVikingClient(cfg.baseUrl, cfg.apiKey, cfg.agentId, cfg.timeoutMs)); @@ -351,7 +363,16 @@ const memoryPlugin = { ); if (cfg.autoRecall || cfg.ingestReplyAssist) { - api.on("before_agent_start", async (event: { messages?: unknown[]; prompt: string }) => { + api.on("before_agent_start", async (event: { messages?: unknown[]; prompt: string }, ctx?: { agentId?: string }) => { + // Dynamically switch agent identity for multi-agent memory isolation. + // In multi-agent gateway deployments, the hook context carries the current + // agent's ID so we route memory operations to the correct agent_space. + const hookAgentId = ctx?.agentId; + if (hookAgentId) { + const client = await getClient(); + client.setAgentId(hookAgentId); + api.logger.info?.(`memory-openviking: switched to agentId=${hookAgentId} for recall`); + } const queryText = extractLatestUserText(event.messages) || event.prompt.trim(); if (!queryText) { return; @@ -366,76 +387,85 @@ const memoryPlugin = { ); } else { try { - const candidateLimit = Math.max(cfg.recallLimit * 4, 20); - // 同时检索 user 和 agent 两个位置的记忆 - const [userSettled, agentSettled] = await Promise.allSettled([ - getClient().then((client) => - client.find(queryText, { - targetUri: "viking://user/memories", - limit: candidateLimit, - scoreThreshold: 0, - }), - ), - getClient().then((client) => - client.find(queryText, { - targetUri: "viking://agent/memories", + await withTimeout( + (async () => { + const candidateLimit = Math.max(cfg.recallLimit * 4, 20); + api.logger.info?.(`memory-openviking: autoRecall searching (query="${queryText.slice(0, 80)}", limit=${candidateLimit})`); + // 同时检索 user 和 agent 两个位置的记忆 + const [userSettled, agentSettled] = await Promise.allSettled([ + getClient().then((client) => + client.find(queryText, { + targetUri: "viking://user/memories", + limit: candidateLimit, + scoreThreshold: 0, + }), + ), + getClient().then((client) => + client.find(queryText, { + targetUri: "viking://agent/memories", + limit: candidateLimit, + scoreThreshold: 0, + }), + ), + ]); + const userResult = userSettled.status === "fulfilled" ? userSettled.value : { memories: [] }; + const agentResult = agentSettled.status === "fulfilled" ? agentSettled.value : { memories: [] }; + api.logger.info?.(`memory-openviking: autoRecall done (user=${userResult.memories?.length ?? 0}, agent=${agentResult.memories?.length ?? 0})`); + + if (userSettled.status === "rejected") { + api.logger.warn(`memory-openviking: user memories search failed: ${String(userSettled.reason)}`); + } + if (agentSettled.status === "rejected") { + api.logger.warn(`memory-openviking: agent memories search failed: ${String(agentSettled.reason)}`); + } + // 合并两个位置的结果,去重 + const allMemories = [...(userResult.memories ?? []), ...(agentResult.memories ?? [])]; + const uniqueMemories = allMemories.filter((memory, index, self) => + index === self.findIndex((m) => m.uri === memory.uri) + ); + const leafOnly = uniqueMemories.filter((m) => m.level === 2); + const processed = postProcessMemories(leafOnly, { limit: candidateLimit, - scoreThreshold: 0, - }), - ), - ]); - const userResult = userSettled.status === "fulfilled" ? userSettled.value : { memories: [] }; - const agentResult = agentSettled.status === "fulfilled" ? agentSettled.value : { memories: [] }; - if (userSettled.status === "rejected") { - api.logger.warn(`memory-openviking: user memories search failed: ${String(userSettled.reason)}`); - } - if (agentSettled.status === "rejected") { - api.logger.warn(`memory-openviking: agent memories search failed: ${String(agentSettled.reason)}`); - } - // 合并两个位置的结果,去重 - const allMemories = [...(userResult.memories ?? []), ...(agentResult.memories ?? [])]; - const uniqueMemories = allMemories.filter((memory, index, self) => - index === self.findIndex((m) => m.uri === memory.uri) - ); - const leafOnly = uniqueMemories.filter((m) => m.level === 2); - const processed = postProcessMemories(leafOnly, { - limit: candidateLimit, - scoreThreshold: cfg.recallScoreThreshold, - }); - const memories = pickMemoriesForInjection(processed, cfg.recallLimit, queryText); - if (memories.length > 0) { - // 对 level 2 节点读取正文,其余用 abstract - const client = await getClient(); - const memoryLines = await Promise.all( - memories.map(async (item: FindResultItem) => { - if (item.level === 2) { - try { - const content = await client.read(item.uri); - if (content && typeof content === "string" && content.trim()) { - return `- [${item.category ?? "memory"}] ${content.trim()}`; + scoreThreshold: cfg.recallScoreThreshold, + }); + const memories = pickMemoriesForInjection(processed, cfg.recallLimit, queryText); + if (memories.length > 0) { + // 对 level 2 节点读取正文,其余用 abstract + const client = await getClient(); + const memoryLines = await Promise.all( + memories.map(async (item: FindResultItem) => { + if (item.level === 2) { + try { + const content = await client.read(item.uri); + if (content && typeof content === "string" && content.trim()) { + return `- [${item.category ?? "memory"}] ${content.trim()}`; + } + } catch { + // fallback to abstract + } } - } catch { - // fallback to abstract - } - } - return `- [${item.category ?? "memory"}] ${item.abstract ?? item.uri}`; - }), - ); - const memoryContext = memoryLines.join("\n"); - api.logger.info?.( - `memory-openviking: injecting ${memories.length} memories into context`, - ); - api.logger.info?.( - `memory-openviking: inject-detail ${toJsonLog({ count: memories.length, memories: summarizeInjectionMemories(memories) })}`, - ); - prependContextParts.push( - "\nThe following OpenViking memories may be relevant:\n" + - `${memoryContext}\n` + - "", - ); - } + return `- [${item.category ?? "memory"}] ${item.abstract ?? item.uri}`; + }), + ); + const memoryContext = memoryLines.join("\n"); + api.logger.info?.( + `memory-openviking: injecting ${memories.length} memories into context`, + ); + api.logger.info?.( + `memory-openviking: inject-detail ${toJsonLog({ count: memories.length, memories: summarizeInjectionMemories(memories) })}`, + ); + prependContextParts.push( + "\nThe following OpenViking memories may be relevant:\n" + + `${memoryContext}\n` + + "", + ); + } + })(), + AUTO_RECALL_TIMEOUT_MS, + `memory-openviking: auto-recall timed out after ${AUTO_RECALL_TIMEOUT_MS}ms`, + ); } catch (err) { - api.logger.warn(`memory-openviking: auto-recall failed: ${String(err)}`); + api.logger.warn(`memory-openviking: auto-recall failed or timed out: ${String(err)}`); } } } @@ -471,7 +501,14 @@ const memoryPlugin = { if (cfg.autoCapture) { let lastProcessedMsgCount = 0; - api.on("agent_end", async (event: { success?: boolean; messages?: unknown[] }) => { + api.on("agent_end", async (event: { success?: boolean; messages?: unknown[] }, ctx?: { agentId?: string }) => { + // Dynamically switch agent identity for multi-agent memory isolation + const hookAgentId = ctx?.agentId; + if (hookAgentId) { + const client = await getClient(); + client.setAgentId(hookAgentId); + api.logger.info?.(`memory-openviking: switched to agentId=${hookAgentId} for capture`); + } if (!event.success || !event.messages || event.messages.length === 0) { api.logger.info( `memory-openviking: auto-capture skipped (success=${String(event.success)}, messages=${event.messages?.length ?? 0})`, @@ -537,7 +574,16 @@ const memoryPlugin = { api.registerService({ id: "memory-openviking", start: async () => { - if (cfg.mode === "local" && resolveLocalClient) { + // Claim the pending entry — only the first start() call to claim it spawns the process. + // Subsequent start() calls (from other registrations sharing the same promise) fall through. + const pendingEntry = localClientPendingPromises.get(localCacheKey); + const isSpawner = cfg.mode === "local" && !!pendingEntry; + if (isSpawner) { + localClientPendingPromises.delete(localCacheKey); + resolveLocalClient = pendingEntry!.resolve; + rejectLocalClient = pendingEntry!.reject; + } + if (isSpawner) { const timeoutMs = 60_000; const intervalMs = 500; @@ -571,15 +617,43 @@ const memoryPlugin = { ); localProcess = child; const stderrChunks: string[] = []; + let stderrCharCount = 0; + let stderrDroppedChunks = 0; + const pushStderrChunk = (chunk: string) => { + if (!chunk) return; + stderrChunks.push(chunk); + stderrCharCount += chunk.length; + while ( + stderrChunks.length > MAX_OPENVIKING_STDERR_LINES || + stderrCharCount > MAX_OPENVIKING_STDERR_CHARS + ) { + const dropped = stderrChunks.shift(); + if (!dropped) break; + stderrCharCount -= dropped.length; + stderrDroppedChunks += 1; + } + }; + const formatStderrOutput = () => { + if (!stderrChunks.length && !stderrDroppedChunks) return ""; + const truncated = + stderrDroppedChunks > 0 + ? `[truncated ${stderrDroppedChunks} earlier stderr chunk(s)]\n` + : ""; + return `\n[openviking stderr]\n${truncated}${stderrChunks.join("\n")}`; + }; child.on("error", (err: Error) => api.logger.warn(`memory-openviking: local server error: ${String(err)}`)); child.stderr?.on("data", (chunk: Buffer) => { const s = String(chunk).trim(); - if (s) stderrChunks.push(s); + pushStderrChunk(s); api.logger.debug?.(`[openviking] ${s}`); }); child.on("exit", (code: number | null, signal: string | null) => { - if (localProcess === child && (code != null && code !== 0 || signal)) { - const out = stderrChunks.length ? `\n[openviking stderr]\n${stderrChunks.join("\n")}` : ""; + if (localProcess === child) { + localProcess = null; + localClientCache.delete(localCacheKey); + } + if (code != null && code !== 0 || signal) { + const out = formatStderrOutput(); api.logger.warn(`memory-openviking: subprocess exited (code=${code}, signal=${signal})${out}`); } }); @@ -589,16 +663,18 @@ const memoryPlugin = { localClientCache.set(localCacheKey, { client, process: child }); resolveLocalClient(client); rejectLocalClient = null; + localClientPendingPromises.delete(localCacheKey); api.logger.info( `memory-openviking: local server started (${baseUrl}, config: ${cfg.configPath})`, ); } catch (err) { localProcess = null; child.kill("SIGTERM"); + localClientPendingPromises.delete(localCacheKey); markLocalUnavailable("startup failed", err); if (stderrChunks.length) { api.logger.warn( - `memory-openviking: startup failed (health check timeout or error). OpenViking stderr:\n${stderrChunks.join("\n")}`, + `memory-openviking: startup failed (health check timeout or error).${formatStderrOutput()}`, ); } throw err; @@ -611,6 +687,7 @@ const memoryPlugin = { } }, stop: () => { + localClientPendingPromises.delete(localCacheKey); if (localProcess) { localProcess.kill("SIGTERM"); localClientCache.delete(localCacheKey); diff --git a/examples/openclaw-memory-plugin/install.ps1 b/examples/openclaw-memory-plugin/install.ps1 index 8464b044..5f0aa488 100644 --- a/examples/openclaw-memory-plugin/install.ps1 +++ b/examples/openclaw-memory-plugin/install.ps1 @@ -297,6 +297,14 @@ function Configure-OvConf { input = "multimodal" } } + log = @{ + level = "WARNING" + format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + output = "file" + rotation = $true + rotation_days = 3 + rotation_interval = "midnight" + } vlm = @{ provider = "volcengine" api_key = $(if ($vlmApiKey) { $vlmApiKey } else { $null }) @@ -359,69 +367,40 @@ function Configure-OpenClawPlugin { param([int]$ServerPort) Info (T "Configuring OpenClaw plugin..." "正在配置 OpenClaw 插件...") - $cfgPath = Join-Path $OpenClawDir "openclaw.json" - $cfg = @{} - if (Test-Path $cfgPath) { - try { - $raw = Get-Content -Raw -Path $cfgPath - if (-not [string]::IsNullOrWhiteSpace($raw)) { - $obj = $raw | ConvertFrom-Json -AsHashtable - if ($obj) { $cfg = $obj } - } - } catch { - Warn (T "Existing openclaw.json is invalid. Rebuilding required sections." "检测到已有 openclaw.json 非法,将重建相关配置节点。") - } + $oldStateDir = $env:OPENCLAW_STATE_DIR + if ($OpenClawDir -ne (Join-Path $HomeDir ".openclaw")) { + $env:OPENCLAW_STATE_DIR = $OpenClawDir } - if (-not $cfg.ContainsKey("plugins")) { $cfg["plugins"] = @{} } - if (-not $cfg.ContainsKey("gateway")) { $cfg["gateway"] = @{} } - if (-not $cfg["plugins"].ContainsKey("slots")) { $cfg["plugins"]["slots"] = @{} } - if (-not $cfg["plugins"].ContainsKey("load")) { $cfg["plugins"]["load"] = @{} } - if (-not $cfg["plugins"].ContainsKey("entries")) { $cfg["plugins"]["entries"] = @{} } - - # Keep plugin load paths unique. - $existingPaths = @() - if ($cfg["plugins"]["load"].ContainsKey("paths") -and $cfg["plugins"]["load"]["paths"]) { - $existingPaths = @($cfg["plugins"]["load"]["paths"]) - } - $mergedPaths = @($existingPaths + @($PluginDest) | Select-Object -Unique) - - $cfg["plugins"]["enabled"] = $true - $existingAllow = @() - if ($cfg["plugins"].ContainsKey("allow") -and $cfg["plugins"]["allow"]) { - $existingAllow = @($cfg["plugins"]["allow"]) - } - if ($existingAllow -notcontains "memory-openviking") { - $existingAllow += "memory-openviking" - } - $cfg["plugins"]["allow"] = $existingAllow - $cfg["plugins"]["slots"]["memory"] = "memory-openviking" - $cfg["plugins"]["load"]["paths"] = $mergedPaths - - $pluginConfig = @{ - mode = $SelectedMode - targetUri = "viking://user/memories" - autoRecall = $true - autoCapture = $true - } + try { + # Enable plugin (files already deployed to extensions dir by Deploy-Plugin) + openclaw plugins enable memory-openviking + if ($LASTEXITCODE -ne 0) { throw "openclaw plugins enable failed (exit code $LASTEXITCODE)" } + + # Set gateway mode + openclaw config set gateway.mode local + + # Set plugin config for the selected mode + if ($SelectedMode -eq "local") { + $ovConfPath = Join-Path $OpenVikingDir "ov.conf" + openclaw config set plugins.entries.memory-openviking.config.mode local + openclaw config set plugins.entries.memory-openviking.config.configPath $ovConfPath + openclaw config set plugins.entries.memory-openviking.config.port $ServerPort + } else { + openclaw config set plugins.entries.memory-openviking.config.mode remote + openclaw config set plugins.entries.memory-openviking.config.baseUrl $RemoteBaseUrl + if ($RemoteApiKey) { + openclaw config set plugins.entries.memory-openviking.config.apiKey $RemoteApiKey + } + if ($RemoteAgentId) { + openclaw config set plugins.entries.memory-openviking.config.agentId $RemoteAgentId + } + } - if ($SelectedMode -eq "local") { - $ovConfPath = Join-Path $OpenVikingDir "ov.conf" - $pluginConfig["configPath"] = $ovConfPath - $pluginConfig["port"] = $ServerPort - } else { - $pluginConfig["baseUrl"] = $RemoteBaseUrl - if ($RemoteApiKey) { $pluginConfig["apiKey"] = $RemoteApiKey } - if ($RemoteAgentId) { $pluginConfig["agentId"] = $RemoteAgentId } + Info (T "OpenClaw plugin configured" "OpenClaw 插件配置完成") + } finally { + $env:OPENCLAW_STATE_DIR = $oldStateDir } - - $cfg["plugins"]["entries"]["memory-openviking"] = @{ config = $pluginConfig } - $cfg["gateway"]["mode"] = "local" - - $cfgJson = $cfg | ConvertTo-Json -Depth 20 - Write-Utf8NoBom -Path $cfgPath -Content $cfgJson - - Info (T "OpenClaw plugin configured" "OpenClaw 插件配置完成") } function Write-OpenVikingEnv { diff --git a/examples/openclaw-memory-plugin/install.sh b/examples/openclaw-memory-plugin/install.sh old mode 100644 new mode 100755 index 91f4260f..7421e8d8 --- a/examples/openclaw-memory-plugin/install.sh +++ b/examples/openclaw-memory-plugin/install.sh @@ -535,6 +535,14 @@ configure_openviking_conf() { "input": "multimodal" } }, + "log": { + "level": "WARNING", + "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s", + "output": "file", + "rotation": true, + "rotation_days": 3, + "rotation_interval": "midnight" + }, "vlm": { "provider": "volcengine", "api_key": ${vlm_api_json}, @@ -612,35 +620,20 @@ configure_openclaw_plugin() { oc_env=(env OPENCLAW_STATE_DIR="$OPENCLAW_DIR") fi - "${oc_env[@]}" openclaw config set plugins.enabled true - # Merge into existing allow list instead of overwriting - local existing_allow - existing_allow=$("${oc_env[@]}" openclaw config get plugins.allow --json 2>/dev/null || echo '[]') - if ! echo "$existing_allow" | grep -q '"memory-openviking"'; then - existing_allow=$(echo "$existing_allow" | sed 's/]$//' | sed 's/$/,"memory-openviking"]/' | sed 's/\[,/[/') - fi - "${oc_env[@]}" openclaw config set plugins.allow "$existing_allow" --json + # Enable plugin (files already deployed to extensions dir by deploy_plugin) + "${oc_env[@]}" openclaw plugins enable memory-openviking || { err "$(tr "openclaw plugins enable failed" "openclaw 插件启用失败")"; exit 1; } + # Set gateway mode "${oc_env[@]}" openclaw config set gateway.mode local - "${oc_env[@]}" openclaw config set plugins.slots.memory memory-openviking - - # Merge into existing load paths instead of overwriting - local existing_paths - existing_paths=$("${oc_env[@]}" openclaw config get plugins.load.paths --json 2>/dev/null || echo '[]') - if ! echo "$existing_paths" | grep -q "\"${PLUGIN_DEST}\""; then - existing_paths=$(echo "$existing_paths" | sed 's|]$||' | sed "s|$|,\"${PLUGIN_DEST}\"]|" | sed 's|\[,|[|') - fi - "${oc_env[@]}" openclaw config set plugins.load.paths "$existing_paths" --json - "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.mode "${SELECTED_MODE}" - "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.targetUri viking://user/memories - "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.autoRecall true --json - "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.autoCapture true --json + # Set plugin config for the selected mode if [[ "$SELECTED_MODE" == "local" ]]; then - local config_path="${OPENVIKING_DIR}/ov.conf" - "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.configPath "${config_path}" + local ov_conf_path="${OPENVIKING_DIR}/ov.conf" + "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.mode local + "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.configPath "${ov_conf_path}" "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.port "${SELECTED_SERVER_PORT}" else + "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.mode remote "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.baseUrl "${remote_base_url}" if [[ -n "${remote_api_key}" ]]; then "${oc_env[@]}" openclaw config set plugins.entries.memory-openviking.config.apiKey "${remote_api_key}" diff --git a/examples/openclaw-memory-plugin/setup-helper/cli.js b/examples/openclaw-memory-plugin/setup-helper/cli.js deleted file mode 100755 index 20582b96..00000000 --- a/examples/openclaw-memory-plugin/setup-helper/cli.js +++ /dev/null @@ -1,970 +0,0 @@ -#!/usr/bin/env node -/** - * OpenClaw + OpenViking setup helper - * Usage: npx openclaw-openviking-setup-helper - * Or: npx openclaw-openviking-setup-helper --help - */ - -import { spawn } from "node:child_process"; -import { mkdir, writeFile, access, readFile, rm } from "node:fs/promises"; -import { createInterface } from "node:readline"; -import { join, dirname } from "node:path"; -import { fileURLToPath } from "node:url"; -import { existsSync, readdirSync } from "node:fs"; - -const __dirname = dirname(fileURLToPath(import.meta.url)); -const GITHUB_RAW = - process.env.OPENVIKING_GITHUB_RAW || - "https://raw.githubusercontent.com/OpenViking/OpenViking/main"; - -const IS_WIN = process.platform === "win32"; -const IS_LINUX = process.platform === "linux"; -const HOME = process.env.HOME || process.env.USERPROFILE || ""; -let OPENCLAW_DIR = join(HOME, ".openclaw"); -const OPENVIKING_DIR = join(HOME, ".openviking"); -let EXT_DIR = join(OPENCLAW_DIR, "extensions"); -let PLUGIN_DEST = join(EXT_DIR, "memory-openviking"); - -// ─── Utility helpers ─── - -function log(msg, level = "info") { - const icons = { info: "\u2139", ok: "\u2713", err: "\u2717", warn: "\u26A0" }; - console.log(`${icons[level] || ""} ${msg}`); -} - -function run(cmd, args, opts = {}) { - return new Promise((resolve, reject) => { - const p = spawn(cmd, args, { - stdio: opts.silent ? "pipe" : "inherit", - shell: opts.shell ?? true, - ...opts, - }); - p.on("close", (code) => (code === 0 ? resolve() : reject(new Error(`exit ${code}`)))); - }); -} - -function runCapture(cmd, args, opts = {}) { - return new Promise((resolve) => { - const p = spawn(cmd, args, { - stdio: ["ignore", "pipe", "pipe"], - shell: opts.shell ?? false, - ...opts, - }); - let out = ""; - let err = ""; - p.stdout?.on("data", (d) => (out += d)); - p.stderr?.on("data", (d) => (err += d)); - p.on("error", (e) => { - if (e.code === "ENOENT") resolve({ code: -1, out: "", err: `command not found: ${cmd}` }); - else resolve({ code: -1, out: "", err: String(e) }); - }); - p.on("close", (code) => resolve({ code, out: out.trim(), err: err.trim() })); - }); -} - -function runCaptureWithTimeout(cmd, args, timeoutMs, opts = {}) { - return new Promise((resolve) => { - const p = spawn(cmd, args, { - stdio: ["ignore", "pipe", "pipe"], - shell: opts.shell ?? false, - ...opts, - }); - let out = ""; - let err = ""; - let settled = false; - const done = (result) => { if (!settled) { settled = true; resolve(result); } }; - const timer = setTimeout(() => { p.kill(); done({ code: out ? 0 : -1, out: out.trim(), err: err.trim() }); }, timeoutMs); - p.stdout?.on("data", (d) => (out += d)); - p.stderr?.on("data", (d) => (err += d)); - p.on("error", (e) => { clearTimeout(timer); done({ code: -1, out: "", err: String(e) }); }); - p.on("close", (code) => { clearTimeout(timer); done({ code, out: out.trim(), err: err.trim() }); }); - }); -} - -async function question(prompt, defaultValue = "") { - const rl = createInterface({ input: process.stdin, output: process.stdout }); - const def = defaultValue ? ` [${defaultValue}]` : ""; - return new Promise((resolve) => { - rl.question(`${prompt}${def}: `, (answer) => { - rl.close(); - resolve((answer ?? defaultValue).trim() || defaultValue); - }); - }); -} - -async function questionApiKey(prompt) { - const rl = createInterface({ input: process.stdin, output: process.stdout }); - return new Promise((resolve) => { - rl.question(prompt, (answer) => { - rl.close(); - resolve((answer ?? "").trim()); - }); - }); -} - -// ─── Workdir detection & mode selection ─── - -function detectOpenclawInstances() { - const instances = []; - try { - const entries = readdirSync(HOME, { withFileTypes: true }); - for (const entry of entries) { - if (!entry.isDirectory()) continue; - if (entry.name === ".openclaw" || entry.name.startsWith(".openclaw-")) { - instances.push(join(HOME, entry.name)); - } - } - } catch {} - return instances.sort(); -} - -async function selectWorkdir(nonInteractive) { - const instances = detectOpenclawInstances(); - if (instances.length <= 1) return; // keep default - - if (nonInteractive) return; - - console.log("\nFound multiple OpenClaw instances:"); - for (let i = 0; i < instances.length; i++) { - console.log(` ${i + 1}) ${instances[i]}`); - } - const choice = await question("Select instance number", "1"); - const idx = parseInt(choice, 10) - 1; - if (idx >= 0 && idx < instances.length) { - OPENCLAW_DIR = instances[idx]; - } else { - log("Invalid selection, using default", "warn"); - OPENCLAW_DIR = instances[0]; - } - EXT_DIR = join(OPENCLAW_DIR, "extensions"); - PLUGIN_DEST = join(EXT_DIR, "memory-openviking"); -} - -async function selectMode(nonInteractive) { - if (nonInteractive) return "local"; - const choice = await question("Plugin mode (local/remote)", "local"); - return choice.toLowerCase() === "remote" ? "remote" : "local"; -} - -async function collectRemoteConfig(nonInteractive) { - const opts = { baseUrl: "http://127.0.0.1:1933", apiKey: "", agentId: "" }; - if (nonInteractive) return opts; - - opts.baseUrl = await question("OpenViking server URL", opts.baseUrl); - opts.apiKey = (await questionApiKey("API Key (optional, leave blank to skip): ")) || ""; - opts.agentId = (await questionApiKey("Agent ID (optional, leave blank to skip): ")) || ""; - return opts; -} - -// ─── Distro detection ─── - -async function detectDistro() { - if (IS_WIN) return "windows"; - try { - const { out } = await runCapture("sh", ["-c", "cat /etc/os-release 2>/dev/null"]); - const lower = out.toLowerCase(); - if (lower.includes("ubuntu") || lower.includes("debian")) return "debian"; - if (lower.includes("centos") || lower.includes("rhel") || lower.includes("openeuler") || lower.includes("fedora") || lower.includes("rocky") || lower.includes("alma")) return "rhel"; - } catch {} - const { code: aptCode } = await runCapture("sh", ["-c", "command -v apt"]); - if (aptCode === 0) return "debian"; - const { code: dnfCode } = await runCapture("sh", ["-c", "command -v dnf || command -v yum"]); - if (dnfCode === 0) return "rhel"; - return "unknown"; -} - -// ─── Environment checks ─── - -const DEFAULT_PYTHON = IS_WIN ? "python" : "python3"; - -async function checkOpenclaw() { - if (IS_WIN) { - const { code } = await runCaptureWithTimeout("openclaw", ["--version"], 10000, { shell: true }); - return code === 0 ? { ok: true } : { ok: false }; - } - const { code } = await runCapture("openclaw", ["--version"]); - return code === 0 ? { ok: true } : { ok: false }; -} - -async function checkPython() { - const py = process.env.OPENVIKING_PYTHON || DEFAULT_PYTHON; - const { code, out } = await runCapture(py, ["-c", "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"]); - if (code !== 0) return { ok: false, version: null, cmd: py, msg: `Python not found (tried: ${py})` }; - const [major, minor] = out.split(".").map(Number); - if (major < 3 || (major === 3 && minor < 10)) - return { ok: false, version: out, cmd: py, msg: `Python ${out} too old, need >= 3.10` }; - return { ok: true, version: out, cmd: py, msg: `${out} (${py})` }; -} - -async function checkGo() { - const goDir = process.env.OPENVIKING_GO_PATH?.replace(/^~/, HOME); - const goCmd = goDir ? join(goDir, "go") : "go"; - const { code, out } = await runCapture(goCmd, ["version"]); - if (code !== 0) return { ok: false, version: null, msg: "Go not found" }; - const m = out.match(/go([0-9]+)\.([0-9]+)/); - if (!m) return { ok: false, version: null, msg: "Cannot parse Go version" }; - const [, major, minor] = m.map(Number); - if (major < 1 || (major === 1 && minor < 19)) - return { ok: false, version: `${major}.${minor}`, msg: `Go ${major}.${minor} too old, need >= 1.19` }; - return { ok: true, version: `${major}.${minor}`, msg: `${major}.${minor}` }; -} - -async function checkCmake() { - const { code } = await runCapture("cmake", ["--version"]); - return { ok: code === 0 }; -} - -async function checkGpp() { - const { code } = await runCapture("g++", ["--version"]); - return { ok: code === 0 }; -} - -async function checkOpenvikingModule() { - const py = process.env.OPENVIKING_PYTHON || DEFAULT_PYTHON; - const { code } = await runCapture(py, ["-c", "import openviking"]); - return code === 0 ? { ok: true } : { ok: false }; -} - -async function checkOvvConf() { - const cfg = process.env.OPENVIKING_CONFIG_FILE || join(OPENVIKING_DIR, "ov.conf"); - try { - await access(cfg); - return { ok: true, path: cfg }; - } catch { - return { ok: false, path: cfg }; - } -} - -// ─── Config helpers ─── - -const DEFAULT_SERVER_PORT = 1933; -const DEFAULT_AGFS_PORT = 1833; -const DEFAULT_VLM_MODEL = "doubao-seed-2-0-pro-260215"; -const DEFAULT_EMBEDDING_MODEL = "doubao-embedding-vision-251215"; - -const DEFAULT_WORKSPACE = join(HOME, ".openviking", "data"); - -function buildOvvConfJson(opts = {}) { - const { - apiKey = "", - serverPort = DEFAULT_SERVER_PORT, - agfsPort = DEFAULT_AGFS_PORT, - vlmModel = DEFAULT_VLM_MODEL, - embeddingModel = DEFAULT_EMBEDDING_MODEL, - workspace = DEFAULT_WORKSPACE, - } = opts; - return JSON.stringify({ - server: { - host: "127.0.0.1", - port: serverPort, - root_api_key: null, - cors_origins: ["*"], - }, - storage: { - workspace, - vectordb: { name: "context", backend: "local", project: "default" }, - agfs: { port: agfsPort, log_level: "warn", backend: "local", timeout: 10, retry_times: 3 }, - }, - embedding: { - dense: { - provider: "volcengine", - api_key: apiKey || null, - model: embeddingModel, - api_base: "https://ark.cn-beijing.volces.com/api/v3", - dimension: 1024, - input: "multimodal", - }, - }, - vlm: { - provider: "volcengine", - api_key: apiKey || null, - model: vlmModel, - api_base: "https://ark.cn-beijing.volces.com/api/v3", - temperature: 0.1, - max_retries: 3, - }, - }, null, 2); -} - -function parsePort(val, defaultVal) { - const n = parseInt(val, 10); - return Number.isFinite(n) && n >= 1 && n <= 65535 ? n : defaultVal; -} - -async function ensureOvvConf(cfgPath, opts = {}) { - await mkdir(dirname(cfgPath), { recursive: true }); - await writeFile(cfgPath, buildOvvConfJson(opts)); - log(`Created config: ${cfgPath}`, "ok"); - if (!opts.apiKey) { - log("API Key not set; memory features may be unavailable. Edit ov.conf to add later.", "warn"); - } -} - -async function getApiKeyFromOvvConf(cfgPath) { - let raw; - try { - raw = await readFile(cfgPath, "utf-8"); - const cfg = JSON.parse(raw); - return cfg?.embedding?.dense?.api_key || ""; - } catch { - const m = raw?.match(/api_key\s*:\s*["']?([^"'\s#]+)["']?/); - return m ? m[1].trim() : ""; - } -} - -async function getOvvConfPorts(cfgPath) { - try { - const raw = await readFile(cfgPath, "utf-8"); - const cfg = JSON.parse(raw); - return { - serverPort: cfg?.server?.port ?? DEFAULT_SERVER_PORT, - agfsPort: cfg?.storage?.agfs?.port ?? DEFAULT_AGFS_PORT, - }; - } catch { - return { serverPort: DEFAULT_SERVER_PORT, agfsPort: DEFAULT_AGFS_PORT }; - } -} - -async function isOvvConfInvalid(cfgPath) { - try { - JSON.parse(await readFile(cfgPath, "utf-8")); - return false; - } catch { - return true; - } -} - -async function updateOvvConf(cfgPath, opts = {}) { - let cfg; - try { - cfg = JSON.parse(await readFile(cfgPath, "utf-8")); - } catch { - log("ov.conf is not valid JSON, will create new config", "warn"); - await ensureOvvConf(cfgPath, opts); - return; - } - if (opts.apiKey !== undefined) { - if (!cfg.embedding) cfg.embedding = {}; - if (!cfg.embedding.dense) cfg.embedding.dense = {}; - cfg.embedding.dense.api_key = opts.apiKey || null; - if (!cfg.vlm) cfg.vlm = {}; - cfg.vlm.api_key = opts.apiKey || null; - } - if (opts.vlmModel !== undefined) { - if (!cfg.vlm) cfg.vlm = {}; - cfg.vlm.model = opts.vlmModel; - if (!cfg.vlm.api_base) cfg.vlm.api_base = "https://ark.cn-beijing.volces.com/api/v3"; - if (!cfg.vlm.provider) cfg.vlm.provider = "volcengine"; - } - if (opts.embeddingModel !== undefined) { - if (!cfg.embedding) cfg.embedding = {}; - if (!cfg.embedding.dense) cfg.embedding.dense = {}; - cfg.embedding.dense.model = opts.embeddingModel; - } - if (opts.serverPort !== undefined && cfg.server) cfg.server.port = opts.serverPort; - if (opts.agfsPort !== undefined && cfg.storage?.agfs) cfg.storage.agfs.port = opts.agfsPort; - await writeFile(cfgPath, JSON.stringify(cfg, null, 2)); -} - -// ─── Interactive config collection ─── - -async function collectOvvConfInteractive(nonInteractive) { - const opts = { - apiKey: process.env.OPENVIKING_ARK_API_KEY || "", - serverPort: DEFAULT_SERVER_PORT, - agfsPort: DEFAULT_AGFS_PORT, - vlmModel: DEFAULT_VLM_MODEL, - embeddingModel: DEFAULT_EMBEDDING_MODEL, - workspace: DEFAULT_WORKSPACE, - }; - if (nonInteractive) return opts; - - console.log("\n╔══════════════════════════════════════════════════════════╗"); - console.log("║ OpenViking Configuration (ov.conf) ║"); - console.log("╚══════════════════════════════════════════════════════════╝"); - - console.log("\n--- Data Storage ---"); - console.log("Workspace is where OpenViking stores all data (vector database, files, etc.)."); - opts.workspace = await question(`Workspace path`, DEFAULT_WORKSPACE); - - console.log("\nOpenViking requires a Volcengine Ark API Key for:"); - console.log(" - Embedding model: vectorizes text for semantic search"); - console.log(" - VLM model: analyzes conversations to extract memories"); - console.log("\nGet your API Key at: https://console.volcengine.com/ark\n"); - - opts.apiKey = (await questionApiKey("Volcengine Ark API Key (leave blank to skip, configure later): ")) || opts.apiKey; - - console.log("\n--- Model Configuration ---"); - console.log("VLM model is used to extract and analyze memories from conversations."); - opts.vlmModel = await question(`VLM model name`, DEFAULT_VLM_MODEL); - - console.log("\nEmbedding model is used to vectorize text for semantic search."); - opts.embeddingModel = await question(`Embedding model name`, DEFAULT_EMBEDDING_MODEL); - - console.log("\n--- Server Ports ---"); - const serverPortStr = await question(`OpenViking HTTP port`, String(DEFAULT_SERVER_PORT)); - opts.serverPort = parsePort(serverPortStr, DEFAULT_SERVER_PORT); - const agfsPortStr = await question(`AGFS port`, String(DEFAULT_AGFS_PORT)); - opts.agfsPort = parsePort(agfsPortStr, DEFAULT_AGFS_PORT); - - return opts; -} - -// ─── Installation helpers ─── - -async function installOpenviking(repoRoot) { - const py = process.env.OPENVIKING_PYTHON || DEFAULT_PYTHON; - log(`Installing openviking (using ${py})...`); - if (repoRoot && existsSync(join(repoRoot, "pyproject.toml"))) { - await run(py, ["-m", "pip", "install", "-e", repoRoot]); - return; - } - await run(py, ["-m", "pip", "install", "openviking"]); -} - -async function fetchPluginFromGitHub(dest) { - log("Downloading memory-openviking plugin from GitHub..."); - const files = [ - "examples/openclaw-memory-plugin/index.ts", - "examples/openclaw-memory-plugin/config.ts", - "examples/openclaw-memory-plugin/client.ts", - "examples/openclaw-memory-plugin/process-manager.ts", - "examples/openclaw-memory-plugin/memory-ranking.ts", - "examples/openclaw-memory-plugin/text-utils.ts", - "examples/openclaw-memory-plugin/openclaw.plugin.json", - "examples/openclaw-memory-plugin/package.json", - "examples/openclaw-memory-plugin/package-lock.json", - "examples/openclaw-memory-plugin/tsconfig.json", - "examples/openclaw-memory-plugin/.gitignore", - ]; - await mkdir(dest, { recursive: true }); - for (let i = 0; i < files.length; i++) { - const rel = files[i]; - const name = rel.split("/").pop(); - process.stdout.write(` Downloading ${i + 1}/${files.length}: ${name} ... `); - const url = `${GITHUB_RAW}/${rel}`; - const res = await fetch(url); - if (!res.ok) throw new Error(`Download failed: ${url}`); - const buf = await res.arrayBuffer(); - await writeFile(join(dest, name), Buffer.from(buf)); - process.stdout.write("\u2713\n"); - } - log(`Plugin downloaded to ${dest}`, "ok"); - process.stdout.write(" Installing plugin deps (npm install)... "); - await run("npm", ["install", "--no-audit", "--no-fund"], { cwd: dest, silent: true }); - process.stdout.write("\u2713\n"); - log("Plugin deps installed", "ok"); -} - -async function fixStalePluginPaths(pluginPath) { - const cfgPath = join(OPENCLAW_DIR, "openclaw.json"); - if (!existsSync(cfgPath)) return; - try { - const cfg = JSON.parse(await readFile(cfgPath, "utf8")); - let changed = false; - const paths = cfg?.plugins?.load?.paths; - if (Array.isArray(paths)) { - const cleaned = paths.filter((p) => existsSync(p)); - if (!cleaned.includes(pluginPath)) cleaned.push(pluginPath); - if (JSON.stringify(cleaned) !== JSON.stringify(paths)) { - cfg.plugins.load.paths = cleaned; - changed = true; - } - } - const installs = cfg?.plugins?.installs; - if (installs) { - for (const [k, v] of Object.entries(installs)) { - if (v?.installPath && !existsSync(v.installPath)) { - delete installs[k]; - changed = true; - } - } - } - if (changed) { - await writeFile(cfgPath, JSON.stringify(cfg, null, 2) + "\n"); - log("Cleaned stale plugin paths from openclaw.json", "ok"); - } - } catch {} -} - -async function configureOpenclawViaJson(pluginPath, serverPort, pluginMode = "local", remoteOpts = {}) { - const cfgPath = join(OPENCLAW_DIR, "openclaw.json"); - let cfg = {}; - try { cfg = JSON.parse(await readFile(cfgPath, "utf8")); } catch { /* start fresh */ } - if (!cfg.plugins) cfg.plugins = {}; - cfg.plugins.enabled = true; - const allow = Array.isArray(cfg.plugins.allow) ? cfg.plugins.allow : []; - if (!allow.includes("memory-openviking")) allow.push("memory-openviking"); - cfg.plugins.allow = allow; - if (!cfg.plugins.slots) cfg.plugins.slots = {}; - cfg.plugins.slots.memory = "memory-openviking"; - if (!cfg.plugins.load) cfg.plugins.load = {}; - const paths = Array.isArray(cfg.plugins.load.paths) ? cfg.plugins.load.paths : []; - if (!paths.includes(pluginPath)) paths.push(pluginPath); - cfg.plugins.load.paths = paths; - if (!cfg.plugins.entries) cfg.plugins.entries = {}; - - const pluginConfig = { - mode: pluginMode, - targetUri: "viking://user/memories", - autoRecall: true, - autoCapture: true, - }; - if (pluginMode === "local") { - pluginConfig.configPath = join(OPENVIKING_DIR, "ov.conf"); - pluginConfig.port = serverPort; - } else { - pluginConfig.baseUrl = remoteOpts.baseUrl || "http://127.0.0.1:1933"; - if (remoteOpts.apiKey) pluginConfig.apiKey = remoteOpts.apiKey; - if (remoteOpts.agentId) pluginConfig.agentId = remoteOpts.agentId; - } - cfg.plugins.entries["memory-openviking"] = { config: pluginConfig }; - - if (!cfg.gateway) cfg.gateway = {}; - cfg.gateway.mode = "local"; - await mkdir(OPENCLAW_DIR, { recursive: true }); - await writeFile(cfgPath, JSON.stringify(cfg, null, 2) + "\n"); -} - -async function configureOpenclawViaCli(pluginPath, serverPort, installMode, pluginMode = "local", remoteOpts = {}) { - const extraEnv = OPENCLAW_DIR !== join(HOME, ".openclaw") - ? { env: { ...process.env, OPENCLAW_STATE_DIR: OPENCLAW_DIR } } - : {}; - const runNoShell = (cmd, args, opts = {}) => run(cmd, args, { ...opts, ...extraEnv, shell: false }); - - if (installMode === "link") { - if (existsSync(PLUGIN_DEST)) { - log(`Removing old plugin dir ${PLUGIN_DEST}...`, "info"); - await rm(PLUGIN_DEST, { recursive: true, force: true }); - } - await run("openclaw", ["plugins", "install", "-l", pluginPath], extraEnv); - } else { - // Merge into existing load paths instead of overwriting - let currentPaths = []; - try { - const rawPaths = await runCapture("openclaw", ["config", "get", "plugins.load.paths", "--json"], { ...extraEnv }); - currentPaths = JSON.parse(rawPaths.out || "[]"); - } catch {} - if (!Array.isArray(currentPaths)) currentPaths = []; - if (!currentPaths.includes(pluginPath)) currentPaths.push(pluginPath); - await runNoShell("openclaw", ["config", "set", "plugins.load.paths", JSON.stringify(currentPaths), "--json"], { silent: true }).catch(() => {}); - } - await runNoShell("openclaw", ["config", "set", "plugins.enabled", "true"]); - // Merge into existing allow list instead of overwriting - let currentAllow = []; - try { - const raw = await runCapture("openclaw", ["config", "get", "plugins.allow", "--json"], { ...extraEnv }); - currentAllow = JSON.parse(raw.out || "[]"); - } catch {} - if (!Array.isArray(currentAllow)) currentAllow = []; - if (!currentAllow.includes("memory-openviking")) currentAllow.push("memory-openviking"); - await runNoShell("openclaw", ["config", "set", "plugins.allow", JSON.stringify(currentAllow), "--json"]); - await runNoShell("openclaw", ["config", "set", "gateway.mode", "local"]); - await runNoShell("openclaw", ["config", "set", "plugins.slots.memory", "memory-openviking"]); - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.mode", pluginMode]); - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.targetUri", "viking://user/memories"]); - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.autoRecall", "true", "--json"]); - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.autoCapture", "true", "--json"]); - - if (pluginMode === "local") { - const ovConfPath = join(OPENVIKING_DIR, "ov.conf"); - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.configPath", ovConfPath]); - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.port", String(serverPort)]); - } else { - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.baseUrl", remoteOpts.baseUrl || "http://127.0.0.1:1933"]); - if (remoteOpts.apiKey) { - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.apiKey", remoteOpts.apiKey]); - } - if (remoteOpts.agentId) { - await runNoShell("openclaw", ["config", "set", "plugins.entries.memory-openviking.config.agentId", remoteOpts.agentId]); - } - } -} - -async function configureOpenclaw(pluginPath, serverPort = DEFAULT_SERVER_PORT, installMode = "link", pluginMode = "local", remoteOpts = {}) { - await fixStalePluginPaths(pluginPath); - if (IS_WIN) { - await configureOpenclawViaJson(pluginPath, serverPort, pluginMode, remoteOpts); - } else { - await configureOpenclawViaCli(pluginPath, serverPort, installMode, pluginMode, remoteOpts); - } - log("OpenClaw plugin config done", "ok"); -} - -async function resolveCommand(cmd) { - if (IS_WIN) { - const { code, out } = await runCapture("where", [cmd], { shell: true }); - return code === 0 ? out.split(/\r?\n/)[0].trim() : ""; - } - const { out } = await runCapture("sh", ["-c", `command -v ${cmd} 2>/dev/null || which ${cmd}`]); - return out || ""; -} - -async function writeOpenvikingEnv() { - const pyCmd = process.env.OPENVIKING_PYTHON || DEFAULT_PYTHON; - const pyPath = await resolveCommand(pyCmd); - const goOut = await resolveCommand("go"); - const goPath = goOut ? dirname(goOut) : ""; - await mkdir(OPENCLAW_DIR, { recursive: true }); - - if (IS_WIN) { - const lines = []; - if (pyPath) lines.push(`set OPENVIKING_PYTHON=${pyPath}`); - if (goPath) lines.push(`set OPENVIKING_GO_PATH=${goPath}`); - if (process.env.GOPATH) lines.push(`set OPENVIKING_GOPATH=${process.env.GOPATH}`); - if (process.env.GOPROXY) lines.push(`set OPENVIKING_GOPROXY=${process.env.GOPROXY}`); - await writeFile(join(OPENCLAW_DIR, "openviking.env.bat"), lines.join("\r\n") + "\r\n"); - log(`Written ~/.openclaw/openviking.env.bat`, "ok"); - } else { - const lines = []; - if (pyPath) lines.push(`export OPENVIKING_PYTHON='${pyPath}'`); - if (goPath) lines.push(`export OPENVIKING_GO_PATH='${goPath}'`); - if (process.env.GOPATH) lines.push(`export OPENVIKING_GOPATH='${process.env.GOPATH}'`); - if (process.env.GOPROXY) lines.push(`export OPENVIKING_GOPROXY='${process.env.GOPROXY}'`); - await writeFile(join(OPENCLAW_DIR, "openviking.env"), lines.join("\n") + "\n"); - log(`Written ~/.openclaw/openviking.env`, "ok"); - } -} - -// ─── Main flow ─── - -async function main() { - const args = process.argv.slice(2); - const help = args.includes("--help") || args.includes("-h"); - const nonInteractive = args.includes("--yes") || args.includes("-y"); - - // Parse --workdir - for (let i = 0; i < args.length; i++) { - if (args[i] === "--workdir" && i + 1 < args.length) { - OPENCLAW_DIR = args[i + 1]; - EXT_DIR = join(OPENCLAW_DIR, "extensions"); - PLUGIN_DEST = join(EXT_DIR, "memory-openviking"); - } - } - - if (help) { - console.log(` -OpenClaw + OpenViking setup helper - -Usage: npx openclaw-openviking-setup-helper [options] - -Options: - -y, --yes Non-interactive, use defaults - --workdir OpenClaw config directory (default: ~/.openclaw) - -h, --help Show help - -Steps: - 1. Check OpenClaw - 2. Check build environment (Python, Go, cmake, g++) - 3. Install openviking module if needed - 4. Configure ov.conf (API Key, VLM, Embedding, ports) - 5. Deploy memory-openviking plugin - 6. Write ~/.openclaw/openviking.env - -Env vars: - OPENVIKING_PYTHON Python path - OPENVIKING_CONFIG_FILE ov.conf path - OPENVIKING_REPO Local OpenViking repo path (use local plugin if set) - OPENVIKING_ARK_API_KEY Volcengine Ark API Key (used in -y mode, skip prompt) - OPENVIKING_GO_PATH Go bin dir (when Go not in PATH, e.g. ~/local/go/bin) -`); - process.exit(0); - } - - console.log("\n\ud83e\udd9e OpenClaw + OpenViking setup helper\n"); - - // Workdir & mode selection - await selectWorkdir(nonInteractive); - log(`Target: ${OPENCLAW_DIR}`, "info"); - - const pluginMode = await selectMode(nonInteractive); - log(`Mode: ${pluginMode}`, "info"); - - let remoteOpts = {}; - if (pluginMode === "remote") { - remoteOpts = await collectRemoteConfig(nonInteractive); - } - - const distro = await detectDistro(); - - if (pluginMode === "local") { - // ════════════════════════════════════════════ - // Phase 1: Check build tools & runtime environment - // cmake/g++ must be present before OpenClaw install (node-llama-cpp needs them) - // ════════════════════════════════════════════ - console.log("── Step 1/5: Checking build environment ──\n"); - - const missing = []; - - // cmake check (needed by OpenClaw's node-llama-cpp AND OpenViking C++ extension) - const cmakeResult = await checkCmake(); - if (cmakeResult.ok) { - log("cmake: installed", "ok"); - } else { - log("cmake: not found", "err"); - missing.push({ name: "cmake", detail: "Required by OpenClaw (llama.cpp) and OpenViking (C++ extension)" }); - } - - // g++ check (needed by OpenClaw's node-llama-cpp AND OpenViking C++ extension) - const gppResult = await checkGpp(); - if (gppResult.ok) { - log("g++: installed", "ok"); - } else { - log("g++: not found", "err"); - missing.push({ name: "g++ (gcc-c++)", detail: "Required by OpenClaw (llama.cpp) and OpenViking (C++ extension)" }); - } - - // Python check - const pyResult = await checkPython(); - if (pyResult.ok) { - log(`Python: ${pyResult.msg}`, "ok"); - } else { - log(`Python: ${pyResult.msg}`, "err"); - missing.push({ name: "Python >= 3.10", detail: pyResult.version ? `Current: ${pyResult.version}` : "Not found" }); - } - - // Go check (required on Linux for source install) - const goResult = await checkGo(); - if (goResult.ok) { - log(`Go: ${goResult.msg}`, "ok"); - } else if (IS_LINUX) { - log(`Go: ${goResult.msg}`, "err"); - missing.push({ name: "Go >= 1.19", detail: goResult.msg }); - } else { - log(`Go: not found (not required on ${process.platform})`, "warn"); - } - - if (missing.length > 0) { - console.log("\n\u2717 Missing dependencies:\n"); - for (const m of missing) { - console.log(` - ${m.name}: ${m.detail}`); - } - - console.log("\n Please install the missing dependencies:\n"); - - if (distro === "rhel") { - const needBuild = missing.some((m) => m.name === "cmake" || m.name === "g++ (gcc-c++)"); - const needPython = missing.some((m) => m.name.startsWith("Python")); - const needGo = missing.some((m) => m.name.startsWith("Go")); - - if (needBuild) console.log(" sudo dnf install -y gcc gcc-c++ cmake make"); - if (needPython) { - console.log(" # Install Python 3.11 (try package manager first):"); - console.log(" sudo dnf install -y python3.11 python3.11-devel python3.11-pip"); - console.log(" # If unavailable, build from source:"); - console.log(" # See INSTALL-ZH.md 'Linux Environment Setup' section"); - } - if (needGo) { - console.log(" # Install Go >= 1.19:"); - console.log(" wget https://go.dev/dl/go1.25.6.linux-amd64.tar.gz"); - console.log(" sudo rm -rf /usr/local/go"); - console.log(" sudo tar -C /usr/local -xzf go1.25.6.linux-amd64.tar.gz"); - console.log(" echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc"); - console.log(" source ~/.bashrc"); - console.log(" # Configure Go module proxy (recommended if downloads are slow):"); - console.log(" go env -w GOPROXY=https://goproxy.cn,direct"); - } - } else if (distro === "debian") { - const needBuild = missing.some((m) => m.name === "cmake" || m.name === "g++ (gcc-c++)"); - const needPython = missing.some((m) => m.name.startsWith("Python")); - const needGo = missing.some((m) => m.name.startsWith("Go")); - - if (needBuild) console.log(" sudo apt update && sudo apt install -y build-essential cmake"); - if (needPython) { - console.log(" # Install Python 3.11:"); - console.log(" sudo add-apt-repository ppa:deadsnakes/ppa"); - console.log(" sudo apt install -y python3.11 python3.11-dev python3.11-venv"); - } - if (needGo) { - console.log(" # Install Go >= 1.19:"); - console.log(" wget https://go.dev/dl/go1.25.6.linux-amd64.tar.gz"); - console.log(" sudo rm -rf /usr/local/go"); - console.log(" sudo tar -C /usr/local -xzf go1.25.6.linux-amd64.tar.gz"); - console.log(" echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc"); - console.log(" source ~/.bashrc"); - console.log(" # Configure Go module proxy (recommended if downloads are slow):"); - console.log(" go env -w GOPROXY=https://goproxy.cn,direct"); - } - } else { - console.log(" Please install: cmake, g++, Python >= 3.10, Go >= 1.19"); - console.log(" See INSTALL-ZH.md for detailed instructions."); - } - - console.log("\n After installing, re-run this script:"); - console.log(" npx ./examples/openclaw-memory-plugin/setup-helper\n"); - process.exit(1); - } - } // end if pluginMode === "local" (Phase 1) - - // ════════════════════════════════════════════ - // Phase 2: Check OpenClaw - // ════════════════════════════════════════════ - console.log("\n── Step 2/5: Checking OpenClaw ──\n"); - - const hasOpenclaw = await checkOpenclaw(); - if (!hasOpenclaw.ok) { - log("OpenClaw is not installed.", "err"); - console.log("\n Please install OpenClaw:\n"); - console.log(" npm install -g openclaw\n"); - console.log(" If downloads are slow, use npmmirror registry:"); - console.log(" npm install -g openclaw --registry=https://registry.npmmirror.com\n"); - console.log(" After installation, run onboarding to configure your LLM:"); - console.log(" openclaw onboard\n"); - console.log(" Then re-run this script:"); - console.log(" npx ./examples/openclaw-memory-plugin/setup-helper\n"); - process.exit(1); - } - log("OpenClaw: installed", "ok"); - - let ovOpts = { - apiKey: process.env.OPENVIKING_ARK_API_KEY || "", - serverPort: DEFAULT_SERVER_PORT, - agfsPort: DEFAULT_AGFS_PORT, - vlmModel: DEFAULT_VLM_MODEL, - embeddingModel: DEFAULT_EMBEDDING_MODEL, - }; - - if (pluginMode === "local") { - // ════════════════════════════════════════════ - // Phase 3: Check & install openviking module - // ════════════════════════════════════════════ - console.log("\n── Step 3/5: Checking openviking module ──\n"); - - const ovMod = await checkOpenvikingModule(); - if (ovMod.ok) { - log("openviking module: installed", "ok"); - } else { - log("openviking module: not found", "warn"); - const inferredRepoRoot = join(__dirname, "..", "..", ".."); - const hasLocalRepo = existsSync(join(inferredRepoRoot, "pyproject.toml")); - const repo = process.env.OPENVIKING_REPO || (hasLocalRepo ? inferredRepoRoot : ""); - - if (nonInteractive) { - await installOpenviking(repo); - } else { - const choice = await question( - repo - ? "Install openviking from local repo? (y=local repo / n=skip)" - : "Install openviking from PyPI? (y/n)", - "y" - ); - if (choice.toLowerCase() === "y") { - await installOpenviking(repo); - } else { - log("Please install openviking manually and re-run this script.", "err"); - if (repo) console.log(` cd ${repo} && python3 -m pip install -e .`); - else console.log(" python3.11 -m pip install openviking --upgrade --force-reinstall"); - process.exit(1); - } - } - - const recheck = await checkOpenvikingModule(); - if (!recheck.ok) { - log("openviking module installation failed. Check errors above.", "err"); - process.exit(1); - } - log("openviking module: installed", "ok"); - } - - // ════════════════════════════════════════════ - // Phase 4: Configure ov.conf (interactive) - // ════════════════════════════════════════════ - console.log("\n── Step 4/5: Configuring OpenViking ──\n"); - - const ovConf = await checkOvvConf(); - const ovConfPath = ovConf.path; - - if (!ovConf.ok) { - log(`ov.conf not found: ${ovConfPath}`, "info"); - const create = nonInteractive || (await question("Create ov.conf now? (y/n)", "y")).toLowerCase() === "y"; - if (create) { - ovOpts = await collectOvvConfInteractive(nonInteractive); - await ensureOvvConf(ovConfPath, ovOpts); - } else { - log("Please create ~/.openviking/ov.conf manually", "err"); - process.exit(1); - } - } else { - log(`ov.conf found: ${ovConfPath}`, "ok"); - const invalid = await isOvvConfInvalid(ovConfPath); - const existingKey = await getApiKeyFromOvvConf(ovConfPath); - const existingPorts = await getOvvConfPorts(ovConfPath); - - if (invalid) { - log("ov.conf format is invalid, will recreate", "warn"); - ovOpts = await collectOvvConfInteractive(nonInteractive); - await ensureOvvConf(ovConfPath, ovOpts); - } else if (!existingKey && !nonInteractive) { - log("API Key is not configured in ov.conf", "warn"); - console.log("\nOpenViking needs a Volcengine Ark API Key for memory features."); - console.log("Get your API Key at: https://console.volcengine.com/ark\n"); - const apiKey = (await questionApiKey("Volcengine Ark API Key (leave blank to skip): ")) || process.env.OPENVIKING_ARK_API_KEY || ""; - if (apiKey) { - await updateOvvConf(ovConfPath, { apiKey }); - log("Written API Key to ov.conf", "ok"); - } else { - log("API Key not set; memory features may be unavailable. Edit ov.conf to add later.", "warn"); - } - ovOpts = { ...existingPorts, apiKey }; - } else if (!existingKey && process.env.OPENVIKING_ARK_API_KEY) { - await updateOvvConf(ovConfPath, { apiKey: process.env.OPENVIKING_ARK_API_KEY }); - log("Written API Key from env to ov.conf", "ok"); - ovOpts = { ...existingPorts, apiKey: process.env.OPENVIKING_ARK_API_KEY }; - } else { - ovOpts = { ...existingPorts, apiKey: existingKey }; - } - } - } // end if pluginMode === "local" (Phase 3 & 4) - - // ════════════════════════════════════════════ - // Phase 5: Deploy plugin & finalize - // ════════════════════════════════════════════ - console.log("\n── Step 5/5: Deploying plugin ──\n"); - - const inferredRepoRoot = join(__dirname, "..", "..", ".."); - const repoRoot = process.env.OPENVIKING_REPO || - (existsSync(join(inferredRepoRoot, "examples", "openclaw-memory-plugin", "index.ts")) ? inferredRepoRoot : ""); - let pluginPath; - if (repoRoot && existsSync(join(repoRoot, "examples", "openclaw-memory-plugin", "index.ts"))) { - pluginPath = join(repoRoot, "examples", "openclaw-memory-plugin"); - log(`Using local plugin: ${pluginPath}`, "ok"); - if (!existsSync(join(pluginPath, "node_modules"))) { - await run("npm", ["install", "--no-audit", "--no-fund"], { cwd: pluginPath, silent: true }); - } - } else { - await fetchPluginFromGitHub(PLUGIN_DEST); - pluginPath = PLUGIN_DEST; - } - - const installMode = (repoRoot && existsSync(join(repoRoot, "examples", "openclaw-memory-plugin", "index.ts"))) ? "link" : "download"; - await configureOpenclaw(pluginPath, ovOpts?.serverPort, installMode, pluginMode, remoteOpts); - - if (pluginMode === "local") { - await writeOpenvikingEnv(); - } - - // Done - console.log("\n╔══════════════════════════════════════════════════════════╗"); - console.log("║ \u2705 Setup complete! ║"); - console.log("╚══════════════════════════════════════════════════════════╝"); - if (pluginMode === "local") { - console.log("\nTo start OpenClaw with memory:"); - if (IS_WIN) { - console.log(' call "%USERPROFILE%\\.openclaw\\openviking.env.bat" && openclaw gateway'); - } else { - console.log(` source ${OPENCLAW_DIR}/openviking.env && openclaw gateway`); - } - } else { - console.log("\nTo start OpenClaw with memory (remote mode):"); - console.log(" openclaw gateway"); - console.log(`\nRemote server: ${remoteOpts.baseUrl}`); - } - console.log("\nTo verify:"); - console.log(" openclaw status"); - console.log(""); -} - -main().catch((e) => { - console.error(e); - process.exit(1); -}); diff --git a/examples/openclaw-memory-plugin/setup-helper/install.js b/examples/openclaw-memory-plugin/setup-helper/install.js new file mode 100644 index 00000000..2d196ca4 --- /dev/null +++ b/examples/openclaw-memory-plugin/setup-helper/install.js @@ -0,0 +1,810 @@ +#!/usr/bin/env node +/** + * OpenClaw + OpenViking cross-platform installer + * + * One-liner (after npm publish; use package name + bin name): + * npx -p openclaw-openviking-setup-helper ov-install [ -y ] [ --zh ] [ --workdir PATH ] + * Or install globally then run: + * npm i -g openclaw-openviking-setup-helper + * ov-install + * openclaw-openviking-install + * + * Direct run: + * node install.js [ -y | --yes ] [ --zh ] [ --workdir PATH ] + * [ --openviking-version=V ] [ --repo=PATH ] + * + * Environment variables: + * REPO, BRANCH, OPENVIKING_INSTALL_YES, SKIP_OPENCLAW, SKIP_OPENVIKING + * OPENVIKING_VERSION Pip install openviking==VERSION (omit for latest) + * OPENVIKING_REPO Repo path: source install (pip -e) + local plugin (default: off) + * NPM_REGISTRY, PIP_INDEX_URL + * OPENVIKING_VLM_API_KEY, OPENVIKING_EMBEDDING_API_KEY, OPENVIKING_ARK_API_KEY + * OPENVIKING_ALLOW_BREAK_SYSTEM_PACKAGES (Linux) + */ + +import { spawn } from "node:child_process"; +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import { existsSync, readdirSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { createInterface } from "node:readline"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +const REPO = process.env.REPO || "volcengine/OpenViking"; +const BRANCH = process.env.BRANCH || "main"; +const GH_RAW = `https://raw.githubusercontent.com/${REPO}/${BRANCH}`; +const NPM_REGISTRY = process.env.NPM_REGISTRY || "https://registry.npmmirror.com"; +const PIP_INDEX_URL = process.env.PIP_INDEX_URL || "https://pypi.tuna.tsinghua.edu.cn/simple"; + +const IS_WIN = process.platform === "win32"; +const HOME = process.env.HOME || process.env.USERPROFILE || ""; + +const DEFAULT_OPENCLAW_DIR = join(HOME, ".openclaw"); +let OPENCLAW_DIR = DEFAULT_OPENCLAW_DIR; +let PLUGIN_DEST = join(OPENCLAW_DIR, "extensions", "memory-openviking"); + +const OPENVIKING_DIR = join(HOME, ".openviking"); + +const DEFAULT_SERVER_PORT = 1933; +const DEFAULT_AGFS_PORT = 1833; +const DEFAULT_VLM_MODEL = "doubao-seed-2-0-pro-260215"; +const DEFAULT_EMBED_MODEL = "doubao-embedding-vision-251215"; + +const REQUIRED_PLUGIN_FILES = [ + "examples/openclaw-memory-plugin/index.ts", + "examples/openclaw-memory-plugin/config.ts", + "examples/openclaw-memory-plugin/openclaw.plugin.json", + "examples/openclaw-memory-plugin/package.json", + "examples/openclaw-memory-plugin/package-lock.json", + "examples/openclaw-memory-plugin/.gitignore", +]; + +const OPTIONAL_PLUGIN_FILES = [ + "examples/openclaw-memory-plugin/client.ts", + "examples/openclaw-memory-plugin/process-manager.ts", + "examples/openclaw-memory-plugin/memory-ranking.ts", + "examples/openclaw-memory-plugin/text-utils.ts", +]; + +let installYes = process.env.OPENVIKING_INSTALL_YES === "1"; +let langZh = false; +let openvikingVersion = process.env.OPENVIKING_VERSION || ""; +let openvikingRepo = process.env.OPENVIKING_REPO || ""; +let workdirExplicit = false; + +let selectedMode = "local"; +let selectedServerPort = DEFAULT_SERVER_PORT; +let remoteBaseUrl = "http://127.0.0.1:1933"; +let remoteApiKey = ""; +let remoteAgentId = ""; +let openvikingPythonPath = ""; + +const argv = process.argv.slice(2); +for (let i = 0; i < argv.length; i++) { + const arg = argv[i]; + if (arg === "-y" || arg === "--yes") { + installYes = true; + continue; + } + if (arg === "--zh") { + langZh = true; + continue; + } + if (arg === "--workdir") { + const workdir = argv[i + 1]?.trim(); + if (!workdir) { + console.error("--workdir requires a path"); + process.exit(1); + } + setOpenClawDir(workdir); + workdirExplicit = true; + i += 1; + continue; + } + if (arg.startsWith("--openviking-version=")) { + openvikingVersion = arg.slice("--openviking-version=".length).trim(); + continue; + } + if (arg.startsWith("--repo=")) { + openvikingRepo = arg.slice("--repo=".length).trim(); + continue; + } + if (arg === "-h" || arg === "--help") { + printHelp(); + process.exit(0); + } +} + +const OPENVIKING_PIP_SPEC = openvikingVersion ? `openviking==${openvikingVersion}` : "openviking"; + +function setOpenClawDir(dir) { + OPENCLAW_DIR = dir; + PLUGIN_DEST = join(OPENCLAW_DIR, "extensions", "memory-openviking"); +} + +function printHelp() { + console.log("Usage: node install.js [ -y | --yes ] [ --zh ] [ --workdir PATH ] [ --openviking-version=V ] [ --repo=PATH ]"); + console.log(""); + console.log(" -y, --yes Non-interactive (use defaults)"); + console.log(" --zh Chinese prompts"); + console.log(" --workdir OpenClaw config directory (default: ~/.openclaw)"); + console.log(" --openviking-version=VERSION Pip install openviking==VERSION (default: latest)"); + console.log(" --repo=PATH Use OpenViking repo at PATH: pip install -e PATH, plugin from repo (default: off)"); + console.log(" -h, --help This help"); + console.log(""); + console.log("Env: OPENVIKING_REPO, REPO, BRANCH, SKIP_OPENCLAW, SKIP_OPENVIKING, OPENVIKING_VERSION, NPM_REGISTRY, PIP_INDEX_URL"); +} + +function tr(en, zh) { + return langZh ? zh : en; +} + +function info(msg) { + console.log(`[INFO] ${msg}`); +} + +function warn(msg) { + console.log(`[WARN] ${msg}`); +} + +function err(msg) { + console.log(`[ERROR] ${msg}`); +} + +function bold(msg) { + console.log(msg); +} + +function run(cmd, args, opts = {}) { + return new Promise((resolve, reject) => { + const child = spawn(cmd, args, { + stdio: opts.silent ? "pipe" : "inherit", + shell: opts.shell ?? true, + ...opts, + }); + child.on("error", reject); + child.on("close", (code) => { + if (code === 0) resolve(); + else reject(new Error(`exit ${code}`)); + }); + }); +} + +function runCapture(cmd, args, opts = {}) { + return new Promise((resolve) => { + const child = spawn(cmd, args, { + stdio: ["ignore", "pipe", "pipe"], + shell: opts.shell ?? false, + ...opts, + }); + let out = ""; + let errOut = ""; + child.stdout?.on("data", (chunk) => { + out += String(chunk); + }); + child.stderr?.on("data", (chunk) => { + errOut += String(chunk); + }); + child.on("error", (error) => { + resolve({ code: -1, out: "", err: String(error) }); + }); + child.on("close", (code) => { + resolve({ code, out: out.trim(), err: errOut.trim() }); + }); + }); +} + +function runLiveCapture(cmd, args, opts = {}) { + return new Promise((resolve) => { + const child = spawn(cmd, args, { + stdio: ["ignore", "pipe", "pipe"], + shell: opts.shell ?? false, + ...opts, + }); + let out = ""; + let errOut = ""; + child.stdout?.on("data", (chunk) => { + const text = String(chunk); + out += text; + process.stdout.write(text); + }); + child.stderr?.on("data", (chunk) => { + const text = String(chunk); + errOut += text; + process.stderr.write(text); + }); + child.on("error", (error) => { + resolve({ code: -1, out: "", err: String(error) }); + }); + child.on("close", (code) => { + resolve({ code, out: out.trim(), err: errOut.trim() }); + }); + }); +} + +function question(prompt, defaultValue = "") { + const rl = createInterface({ input: process.stdin, output: process.stdout }); + const suffix = defaultValue ? ` [${defaultValue}]` : ""; + return new Promise((resolve) => { + rl.question(`${prompt}${suffix}: `, (answer) => { + rl.close(); + resolve((answer ?? defaultValue).trim() || defaultValue); + }); + }); +} + +async function checkPython() { + const py = process.env.OPENVIKING_PYTHON || (IS_WIN ? "python" : "python3"); + const result = await runCapture(py, ["-c", "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"]); + if (result.code !== 0 || !result.out) { + return { + ok: false, + detail: tr("Python not found or failed. Install Python >= 3.10.", "Python 未找到或执行失败,请安装 Python >= 3.10"), + cmd: py, + }; + } + const [major, minor] = result.out.split(".").map(Number); + if (major < 3 || (major === 3 && minor < 10)) { + return { + ok: false, + detail: tr(`Python ${result.out} is too old. Need >= 3.10.`, `Python ${result.out} 版本过低,需要 >= 3.10`), + cmd: py, + }; + } + return { ok: true, detail: result.out, cmd: py }; +} + +async function checkNode() { + const result = await runCapture("node", ["-v"], { shell: IS_WIN }); + if (result.code !== 0 || !result.out) { + return { ok: false, detail: tr("Node.js not found. Install Node.js >= 22.", "Node.js 未找到,请安装 Node.js >= 22") }; + } + const major = Number.parseInt(result.out.replace(/^v/, "").split(".")[0], 10); + if (!Number.isFinite(major) || major < 22) { + return { ok: false, detail: tr(`Node.js ${result.out} is too old. Need >= 22.`, `Node.js ${result.out} 版本过低,需要 >= 22`) }; + } + return { ok: true, detail: result.out }; +} + +function detectOpenClawInstances() { + const instances = []; + try { + const entries = readdirSync(HOME, { withFileTypes: true }); + for (const entry of entries) { + if (!entry.isDirectory()) continue; + if (entry.name === ".openclaw" || entry.name.startsWith(".openclaw-")) { + instances.push(join(HOME, entry.name)); + } + } + } catch {} + return instances.sort(); +} + +async function selectWorkdir() { + if (workdirExplicit) return; + + const instances = detectOpenClawInstances(); + if (instances.length <= 1) return; + if (installYes) return; + + console.log(""); + bold(tr("Found multiple OpenClaw instances:", "发现多个 OpenClaw 实例:")); + for (let i = 0; i < instances.length; i++) { + console.log(` ${i + 1}) ${instances[i]}`); + } + console.log(""); + + const answer = await question(tr("Select instance number", "选择实例编号"), "1"); + const index = Number.parseInt(answer, 10) - 1; + if (index >= 0 && index < instances.length) { + setOpenClawDir(instances[index]); + } else { + warn(tr("Invalid selection, using default", "无效选择,使用默认")); + setOpenClawDir(instances[0]); + } +} + +async function selectMode() { + if (installYes) { + selectedMode = "local"; + return; + } + const mode = (await question(tr("Plugin mode - local or remote", "插件模式 - local 或 remote"), "local")).toLowerCase(); + selectedMode = mode === "remote" ? "remote" : "local"; +} + +async function collectRemoteConfig() { + if (installYes) return; + remoteBaseUrl = await question(tr("OpenViking server URL", "OpenViking 服务器地址"), remoteBaseUrl); + remoteApiKey = await question(tr("API Key (optional)", "API Key(可选)"), remoteApiKey); + remoteAgentId = await question(tr("Agent ID (optional)", "Agent ID(可选)"), remoteAgentId); +} + +async function validateEnvironment() { + info(tr("Checking OpenViking runtime environment...", "正在校验 OpenViking 运行环境...")); + console.log(""); + + const missing = []; + + const python = await checkPython(); + if (python.ok) { + info(` Python: ${python.detail} ✓`); + } else { + missing.push(`Python 3.10+ | ${python.detail}`); + } + + const node = await checkNode(); + if (node.ok) { + info(` Node.js: ${node.detail} ✓`); + } else { + missing.push(`Node.js 22+ | ${node.detail}`); + } + + if (missing.length > 0) { + console.log(""); + err(tr("Environment check failed. Install missing dependencies first.", "环境校验未通过,请先安装以下缺失组件。")); + console.log(""); + if (missing.some((item) => item.startsWith("Python"))) { + console.log(tr("Python (example):", "Python(示例):")); + if (IS_WIN) console.log(" winget install --id Python.Python.3.11 -e"); + else console.log(" pyenv install 3.11.12 && pyenv global 3.11.12"); + console.log(""); + } + if (missing.some((item) => item.startsWith("Node"))) { + console.log(tr("Node.js (example):", "Node.js(示例):")); + if (IS_WIN) console.log(" nvm install 22.22.0 && nvm use 22.22.0"); + else console.log(" nvm install 22 && nvm use 22"); + console.log(""); + } + process.exit(1); + } + + console.log(""); + info(tr("Environment check passed ✓", "环境校验通过 ✓")); + console.log(""); +} + +async function checkOpenClaw() { + if (process.env.SKIP_OPENCLAW === "1") { + info(tr("Skipping OpenClaw check (SKIP_OPENCLAW=1)", "跳过 OpenClaw 校验 (SKIP_OPENCLAW=1)")); + return; + } + + info(tr("Checking OpenClaw...", "正在校验 OpenClaw...")); + const result = await runCapture("openclaw", ["--version"], { shell: IS_WIN }); + if (result.code === 0) { + info(tr("OpenClaw detected ✓", "OpenClaw 已安装 ✓")); + return; + } + + err(tr("OpenClaw not found. Install it manually, then rerun this script.", "未检测到 OpenClaw,请先手动安装后再执行本脚本")); + console.log(""); + console.log(tr("Recommended command:", "推荐命令:")); + console.log(` npm install -g openclaw --registry ${NPM_REGISTRY}`); + console.log(""); + console.log(" openclaw --version"); + console.log(" openclaw onboard"); + console.log(""); + process.exit(1); +} + +async function installOpenViking() { + if (process.env.SKIP_OPENVIKING === "1") { + info(tr("Skipping OpenViking install (SKIP_OPENVIKING=1)", "跳过 OpenViking 安装 (SKIP_OPENVIKING=1)")); + return; + } + + const python = await checkPython(); + if (!python.cmd) { + err(tr("Python check failed.", "Python 校验失败")); + process.exit(1); + } + + const py = python.cmd; + + if (openvikingRepo && existsSync(join(openvikingRepo, "pyproject.toml"))) { + info(tr(`Installing OpenViking from source (editable): ${openvikingRepo}`, `正在从源码安装 OpenViking(可编辑): ${openvikingRepo}`)); + await run(py, ["-m", "pip", "install", "--upgrade", "pip", "-q", "-i", PIP_INDEX_URL], { silent: true }); + await run(py, ["-m", "pip", "install", "-e", openvikingRepo]); + openvikingPythonPath = py; + info(tr("OpenViking installed ✓ (source)", "OpenViking 安装完成 ✓(源码)")); + return; + } + + info(tr("Installing OpenViking from PyPI...", "正在安装 OpenViking (PyPI)...")); + info(tr(`Using pip index: ${PIP_INDEX_URL}`, `使用 pip 镜像源: ${PIP_INDEX_URL}`)); + + info(`Package: ${OPENVIKING_PIP_SPEC}`); + await runCapture(py, ["-m", "pip", "install", "--upgrade", "pip", "-q", "-i", PIP_INDEX_URL], { shell: false }); + const installResult = await runLiveCapture( + py, + ["-m", "pip", "install", "--progress-bar", "on", OPENVIKING_PIP_SPEC, "-i", PIP_INDEX_URL], + { shell: false }, + ); + if (installResult.code === 0) { + openvikingPythonPath = py; + info(tr("OpenViking installed ✓", "OpenViking 安装完成 ✓")); + return; + } + + const installOutput = `${installResult.out}\n${installResult.err}`; + const shouldTryVenv = !IS_WIN && /externally-managed-environment|externally managed|No module named pip/i.test(installOutput); + if (shouldTryVenv) { + const venvDir = join(OPENVIKING_DIR, "venv"); + const venvPy = IS_WIN ? join(venvDir, "Scripts", "python.exe") : join(venvDir, "bin", "python"); + + if (existsSync(venvPy)) { + const reuseCheck = await runCapture(venvPy, ["-c", "import openviking"], { shell: false }); + if (reuseCheck.code === 0) { + await runLiveCapture( + venvPy, + ["-m", "pip", "install", "--progress-bar", "on", "-U", OPENVIKING_PIP_SPEC, "-i", PIP_INDEX_URL], + { shell: false }, + ); + openvikingPythonPath = venvPy; + info(tr("OpenViking installed ✓ (venv)", "OpenViking 安装完成 ✓(虚拟环境)")); + return; + } + } + + await mkdir(OPENVIKING_DIR, { recursive: true }); + const venvCreate = await runCapture(py, ["-m", "venv", venvDir], { shell: false }); + if (venvCreate.code !== 0) { + console.log(""); + err(tr("Cannot create Python virtual environment.", "无法创建 Python 虚拟环境。")); + console.log(tr( + " python3-venv is not installed. Fix with:", + " python3-venv 未安装,请执行以下命令修复:" + )); + console.log(` + apt update + apt install -y software-properties-common + add-apt-repository universe + apt update + apt install -y python3-venv +`); + console.log(tr( + " Or force install into system Python (not recommended):", + " 或强制安装到系统 Python(不推荐):" + )); + console.log(` OPENVIKING_ALLOW_BREAK_SYSTEM_PACKAGES=1 ov-install\n`); + process.exit(1); + } + + await runCapture(venvPy, ["-m", "pip", "install", "--upgrade", "pip", "-q", "-i", PIP_INDEX_URL], { shell: false }); + const venvInstall = await runLiveCapture( + venvPy, + ["-m", "pip", "install", "--progress-bar", "on", OPENVIKING_PIP_SPEC, "-i", PIP_INDEX_URL], + { shell: false }, + ); + if (venvInstall.code === 0) { + openvikingPythonPath = venvPy; + info(tr("OpenViking installed ✓ (venv)", "OpenViking 安装完成 ✓(虚拟环境)")); + return; + } + + err(tr("OpenViking install failed in venv.", "在虚拟环境中安装 OpenViking 失败。")); + console.log(venvInstall.err || venvInstall.out); + process.exit(1); + } + + if (process.env.OPENVIKING_ALLOW_BREAK_SYSTEM_PACKAGES === "1") { + const systemInstall = await runLiveCapture( + py, + ["-m", "pip", "install", "--progress-bar", "on", "--break-system-packages", OPENVIKING_PIP_SPEC, "-i", PIP_INDEX_URL], + { shell: false }, + ); + if (systemInstall.code === 0) { + openvikingPythonPath = py; + info(tr("OpenViking installed ✓ (system)", "OpenViking 安装完成 ✓(系统)")); + return; + } + } + + err(tr("OpenViking install failed. Check Python >= 3.10 and pip.", "OpenViking 安装失败,请检查 Python >= 3.10 及 pip")); + console.log(installResult.err || installResult.out); + process.exit(1); +} + +async function configureOvConf() { + await mkdir(OPENVIKING_DIR, { recursive: true }); + + let workspace = join(OPENVIKING_DIR, "data"); + let serverPort = String(DEFAULT_SERVER_PORT); + let agfsPort = String(DEFAULT_AGFS_PORT); + let vlmModel = DEFAULT_VLM_MODEL; + let embeddingModel = DEFAULT_EMBED_MODEL; + let vlmApiKey = process.env.OPENVIKING_VLM_API_KEY || process.env.OPENVIKING_ARK_API_KEY || ""; + let embeddingApiKey = process.env.OPENVIKING_EMBEDDING_API_KEY || process.env.OPENVIKING_ARK_API_KEY || ""; + + if (!installYes) { + console.log(""); + workspace = await question(tr("OpenViking workspace path", "OpenViking 数据目录"), workspace); + serverPort = await question(tr("OpenViking HTTP port", "OpenViking HTTP 端口"), serverPort); + agfsPort = await question(tr("AGFS port", "AGFS 端口"), agfsPort); + vlmModel = await question(tr("VLM model", "VLM 模型"), vlmModel); + embeddingModel = await question(tr("Embedding model", "Embedding 模型"), embeddingModel); + console.log(tr("VLM and Embedding API keys can differ. Leave empty to edit ov.conf later.", "说明:VLM 与 Embedding 的 API Key 可分别填写,留空可稍后在 ov.conf 修改。")); + const vlmInput = await question(tr("VLM API key (optional)", "VLM API Key(可留空)"), ""); + const embInput = await question(tr("Embedding API key (optional)", "Embedding API Key(可留空)"), ""); + if (vlmInput) vlmApiKey = vlmInput; + if (embInput) embeddingApiKey = embInput; + } + + selectedServerPort = Number.parseInt(serverPort, 10) || DEFAULT_SERVER_PORT; + const agfsPortNum = Number.parseInt(agfsPort, 10) || DEFAULT_AGFS_PORT; + + await mkdir(workspace, { recursive: true }); + + const config = { + server: { + host: "127.0.0.1", + port: selectedServerPort, + root_api_key: null, + cors_origins: ["*"], + }, + storage: { + workspace, + vectordb: { name: "context", backend: "local", project: "default" }, + agfs: { port: agfsPortNum, log_level: "warn", backend: "local", timeout: 10, retry_times: 3 }, + }, + log: { + level: "WARNING", + format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s", + output: "file", + rotation: true, + rotation_days: 3, + rotation_interval: "midnight", + }, + embedding: { + dense: { + backend: "volcengine", + api_key: embeddingApiKey || null, + model: embeddingModel, + api_base: "https://ark.cn-beijing.volces.com/api/v3", + dimension: 1024, + input: "multimodal", + }, + }, + vlm: { + backend: "volcengine", + api_key: vlmApiKey || null, + model: vlmModel, + api_base: "https://ark.cn-beijing.volces.com/api/v3", + temperature: 0.1, + max_retries: 3, + }, + }; + + const configPath = join(OPENVIKING_DIR, "ov.conf"); + await writeFile(configPath, JSON.stringify(config, null, 2) + "\n", "utf8"); + info(tr(`Config generated: ${configPath}`, `已生成配置: ${configPath}`)); +} + +async function downloadPluginFile(relPath, required, index, total) { + const fileName = relPath.split("/").pop(); + const url = `${GH_RAW}/${relPath}`; + const maxRetries = 3; + + process.stdout.write(` [${index}/${total}] ${fileName} `); + + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + const response = await fetch(url); + if (response.ok) { + const buffer = Buffer.from(await response.arrayBuffer()); + await writeFile(join(PLUGIN_DEST, fileName), buffer); + console.log("✓"); + return; + } + if (!required && response.status === 404) { + console.log(tr("(not present in target branch, skipped)", "(目标分支不存在,已跳过)")); + return; + } + } catch {} + + if (attempt < maxRetries) { + await new Promise((resolve) => setTimeout(resolve, 2000)); + } + } + + if (fileName === ".gitignore") { + console.log(tr("(retries failed, using minimal .gitignore)", "(重试失败,使用最小 .gitignore)")); + await writeFile(join(PLUGIN_DEST, fileName), "node_modules/\n", "utf8"); + return; + } + + console.log(""); + err(tr(`Download failed: ${url}`, `下载失败: ${url}`)); + process.exit(1); +} + +async function downloadPlugin() { + await mkdir(PLUGIN_DEST, { recursive: true }); + const files = [ + ...REQUIRED_PLUGIN_FILES.map((relPath) => ({ relPath, required: true })), + ...OPTIONAL_PLUGIN_FILES.map((relPath) => ({ relPath, required: false })), + ]; + + info(tr(`Downloading memory-openviking plugin from ${REPO}@${BRANCH}...`, `正在从 ${REPO}@${BRANCH} 下载 memory-openviking 插件...`)); + for (let i = 0; i < files.length; i++) { + const file = files[i]; + await downloadPluginFile(file.relPath, file.required, i + 1, files.length); + } + + info(tr("Installing plugin npm dependencies...", "正在安装插件 npm 依赖...")); + await run("npm", ["install", "--no-audit", "--no-fund"], { cwd: PLUGIN_DEST, silent: false }); + info(tr(`Plugin deployed: ${PLUGIN_DEST}`, `插件部署完成: ${PLUGIN_DEST}`)); +} + +async function configureOpenClawPlugin(pluginPath = PLUGIN_DEST) { + info(tr("Configuring OpenClaw plugin...", "正在配置 OpenClaw 插件...")); + + const ocEnv = { ...process.env }; + if (OPENCLAW_DIR !== DEFAULT_OPENCLAW_DIR) { + ocEnv.OPENCLAW_STATE_DIR = OPENCLAW_DIR; + } + + const oc = (args) => runCapture("openclaw", args, { env: ocEnv, shell: IS_WIN }); + + // Enable plugin (files already deployed to extensions dir by deployPlugin) + const enableResult = await oc(["plugins", "enable", "memory-openviking"]); + if (enableResult.code !== 0) throw new Error(`openclaw plugins enable failed (exit code ${enableResult.code})`); + + // Set gateway mode + await oc(["config", "set", "gateway.mode", "local"]); + + // Set plugin config for the selected mode + if (selectedMode === "local") { + const ovConfPath = join(OPENVIKING_DIR, "ov.conf"); + await oc(["config", "set", "plugins.entries.memory-openviking.config.mode", "local"]); + await oc(["config", "set", "plugins.entries.memory-openviking.config.configPath", ovConfPath]); + await oc(["config", "set", "plugins.entries.memory-openviking.config.port", String(selectedServerPort)]); + } else { + await oc(["config", "set", "plugins.entries.memory-openviking.config.mode", "remote"]); + await oc(["config", "set", "plugins.entries.memory-openviking.config.baseUrl", remoteBaseUrl]); + if (remoteApiKey) { + await oc(["config", "set", "plugins.entries.memory-openviking.config.apiKey", remoteApiKey]); + } + if (remoteAgentId) { + await oc(["config", "set", "plugins.entries.memory-openviking.config.agentId", remoteAgentId]); + } + } + + info(tr("OpenClaw plugin configured", "OpenClaw 插件配置完成")); +} + +async function resolvePythonPath() { + if (openvikingPythonPath) return openvikingPythonPath; + const python = await checkPython(); + const py = python.cmd; + if (!py) return ""; + + if (IS_WIN) { + const result = await runCapture("where", [py], { shell: true }); + return result.out.split(/\r?\n/)[0]?.trim() || py; + } + + const result = await runCapture("which", [py], { shell: false }); + return result.out.trim() || py; +} + +async function writeOpenvikingEnv({ includePython }) { + const needStateDir = OPENCLAW_DIR !== DEFAULT_OPENCLAW_DIR; + const pythonPath = includePython ? await resolvePythonPath() : ""; + if (!needStateDir && !pythonPath) return null; + + await mkdir(OPENCLAW_DIR, { recursive: true }); + + if (IS_WIN) { + const batLines = ["@echo off"]; + const psLines = []; + + if (needStateDir) { + batLines.push(`set "OPENCLAW_STATE_DIR=${OPENCLAW_DIR.replace(/"/g, '""')}"`); + psLines.push(`$env:OPENCLAW_STATE_DIR = "${OPENCLAW_DIR.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`); + } + if (pythonPath) { + batLines.push(`set "OPENVIKING_PYTHON=${pythonPath.replace(/"/g, '""')}"`); + psLines.push(`$env:OPENVIKING_PYTHON = "${pythonPath.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`); + } + + const batPath = join(OPENCLAW_DIR, "openviking.env.bat"); + const ps1Path = join(OPENCLAW_DIR, "openviking.env.ps1"); + await writeFile(batPath, `${batLines.join("\r\n")}\r\n`, "utf8"); + await writeFile(ps1Path, `${psLines.join("\n")}\n`, "utf8"); + + info(tr(`Environment file generated: ${batPath}`, `已生成环境文件: ${batPath}`)); + return { shellPath: batPath, powershellPath: ps1Path }; + } + + const lines = []; + if (needStateDir) { + lines.push(`export OPENCLAW_STATE_DIR='${OPENCLAW_DIR.replace(/'/g, "'\"'\"'")}'`); + } + if (pythonPath) { + lines.push(`export OPENVIKING_PYTHON='${pythonPath.replace(/'/g, "'\"'\"'")}'`); + } + + const envPath = join(OPENCLAW_DIR, "openviking.env"); + await writeFile(envPath, `${lines.join("\n")}\n`, "utf8"); + info(tr(`Environment file generated: ${envPath}`, `已生成环境文件: ${envPath}`)); + return { shellPath: envPath }; +} + +function wrapCommand(command, envFiles) { + if (!envFiles) return command; + if (IS_WIN) return `call "${envFiles.shellPath}" && ${command}`; + return `source '${envFiles.shellPath.replace(/'/g, "'\"'\"'")}' && ${command}`; +} + +async function main() { + console.log(""); + bold(tr("🦣 OpenClaw + OpenViking Installer", "🦣 OpenClaw + OpenViking 一键安装")); + console.log(""); + + await selectWorkdir(); + info(tr(`Target: ${OPENCLAW_DIR}`, `目标实例: ${OPENCLAW_DIR}`)); + + await selectMode(); + info(tr(`Mode: ${selectedMode}`, `模式: ${selectedMode}`)); + + if (selectedMode === "local") { + await validateEnvironment(); + await checkOpenClaw(); + await installOpenViking(); + await configureOvConf(); + } else { + await checkOpenClaw(); + await collectRemoteConfig(); + } + + let pluginPath; + const localPluginDir = openvikingRepo ? join(openvikingRepo, "examples", "openclaw-memory-plugin") : ""; + if (openvikingRepo && existsSync(join(localPluginDir, "index.ts"))) { + pluginPath = localPluginDir; + info(tr(`Using local plugin from repo: ${pluginPath}`, `使用仓库内插件: ${pluginPath}`)); + if (!existsSync(join(pluginPath, "node_modules"))) { + info(tr("Installing plugin npm dependencies...", "正在安装插件 npm 依赖...")); + await run("npm", ["install", "--no-audit", "--no-fund"], { cwd: pluginPath, silent: false }); + } + } else { + await downloadPlugin(); + pluginPath = PLUGIN_DEST; + } + + await configureOpenClawPlugin(pluginPath); + const envFiles = await writeOpenvikingEnv({ + includePython: selectedMode === "local", + }); + + console.log(""); + bold("═══════════════════════════════════════════════════════════"); + bold(` ${tr("Installation complete!", "安装完成!")}`); + bold("═══════════════════════════════════════════════════════════"); + console.log(""); + + if (selectedMode === "local") { + info(tr("Run these commands to start OpenClaw + OpenViking:", "请按以下命令启动 OpenClaw + OpenViking:")); + } else { + info(tr("Run these commands to start OpenClaw:", "请按以下命令启动 OpenClaw:")); + } + console.log(` 1) ${wrapCommand("openclaw --version", envFiles)}`); + console.log(` 2) ${wrapCommand("openclaw onboard", envFiles)}`); + console.log(` 3) ${wrapCommand("openclaw gateway", envFiles)}`); + console.log(` 4) ${wrapCommand("openclaw status", envFiles)}`); + console.log(""); + + if (selectedMode === "local") { + info(tr(`You can edit the config freely: ${OPENVIKING_DIR}/ov.conf`, `你可以按需自由修改配置文件: ${OPENVIKING_DIR}/ov.conf`)); + } else { + info(tr(`Remote server: ${remoteBaseUrl}`, `远程服务器: ${remoteBaseUrl}`)); + } + console.log(""); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/examples/openclaw-memory-plugin/setup-helper/package.json b/examples/openclaw-memory-plugin/setup-helper/package.json index d02501ce..ad5aa250 100644 --- a/examples/openclaw-memory-plugin/setup-helper/package.json +++ b/examples/openclaw-memory-plugin/setup-helper/package.json @@ -1,20 +1,31 @@ { "name": "openclaw-openviking-setup-helper", - "version": "0.1.0", + "version": "0.2.8", "description": "Setup helper for installing OpenViking memory plugin into OpenClaw", "type": "module", "bin": { - "openclaw-openviking-setup-helper": "./cli.js" + "openclaw-openviking-setup-helper": "install.js", + "openclaw-openviking-install": "install.js", + "ov-install": "install.js" }, - "keywords": ["openviking", "openclaw", "setup", "memory", "agent"], + "keywords": [ + "openviking", + "openclaw", + "setup", + "memory", + "agent", + "installer" + ], "author": "OpenViking", "license": "Apache-2.0", "repository": { "type": "git", - "url": "https://github.com/OpenViking/OpenViking.git", + "url": "git+https://github.com/volcengine/OpenViking.git", "directory": "examples/openclaw-memory-plugin/setup-helper" }, - "files": ["cli.js", "README.md"], + "files": [ + "install.js" + ], "engines": { "node": ">=22.0.0" } diff --git a/examples/opencode-memory-plugin/.gitignore b/examples/opencode-memory-plugin/.gitignore new file mode 100644 index 00000000..c717c024 --- /dev/null +++ b/examples/opencode-memory-plugin/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +openviking-config.json +openviking-memory.log +openviking-session-map.json +*.corrupted.* diff --git a/examples/opencode-memory-plugin/INSTALL-ZH.md b/examples/opencode-memory-plugin/INSTALL-ZH.md new file mode 100644 index 00000000..216d2916 --- /dev/null +++ b/examples/opencode-memory-plugin/INSTALL-ZH.md @@ -0,0 +1,236 @@ +# 为 OpenCode 安装 OpenViking Memory Plugin + +这个示例把 OpenViking 暴露为 OpenCode 可直接调用的记忆工具,并自动把当前对话同步到 OpenViking Session 中。 + +安装完成后,你可以在 OpenCode 中使用这些工具: + +- `memsearch` +- `memread` +- `membrowse` +- `memcommit` + +--- + +## 机制说明 + +这个示例使用的是 OpenCode 的 tool 机制,把 OpenViking 能力显式暴露成 Agent 可调用的工具。 + +更具体一点: + +- Agent 会看到 `memsearch`、`memread`、`membrowse`、`memcommit` 这些显式工具 +- 只有在 Agent 主动调用这些工具时,OpenViking 的内容才会被读取回来 +- 插件还会在后台把 OpenCode session 映射到 OpenViking session,并在合适的时候触发记忆提取 + +这个示例的重点是显式 memory 访问、类文件系统浏览,以及会话到长期记忆的自动同步。 + +--- + +## 前置条件 + +你需要先准备: + +- 已安装 OpenCode +- 已启动 OpenViking HTTP Server +- 可用的 OpenViking API Key(如果服务端启用了认证) + +建议先确认 OpenViking 服务正常运行: + +```bash +openviking-server --config ~/.openviking/ov.conf +``` + +如果你已经在后台启动了服务,也可以直接检查健康状态: + +```bash +curl http://localhost:1933/health +``` + +--- + +## 安装步骤 + +OpenCode 官方文档更推荐把插件放在: + +```bash +~/.config/opencode/plugins +``` + +### Step 1: 创建插件目录 + +```bash +mkdir -p ~/.config/opencode/plugins +``` + +### Step 2: 复制示例文件 + +在 OpenViking 仓库根目录执行: + +```bash +cp examples/opencode-memory-plugin/openviking-memory.ts ~/.config/opencode/plugins/openviking-memory.ts +cp examples/opencode-memory-plugin/openviking-config.example.json ~/.config/opencode/plugins/openviking-config.json +cp examples/opencode-memory-plugin/.gitignore ~/.config/opencode/plugins/.gitignore +``` + +复制后,插件目录里应该至少有这些文件: + +```text +~/.config/opencode/plugins/ +├── .gitignore +├── openviking-config.json +└── openviking-memory.ts +``` + +### Step 3: 配置插件 + +编辑: + +```bash +~/.config/opencode/plugins/openviking-config.json +``` + +示例配置: + +```json +{ + "endpoint": "http://localhost:1933", + "apiKey": "", + "enabled": true, + "timeoutMs": 30000, + "autoCommit": { + "enabled": true, + "intervalMinutes": 10 + } +} +``` + +字段说明: + +- `endpoint`: OpenViking 服务地址 +- `apiKey`: 可留空,推荐用环境变量提供 +- `enabled`: 是否启用插件 +- `timeoutMs`: 普通请求超时时间 +- `autoCommit.intervalMinutes`: 自动提交 session 的周期 + +### Step 3.5: 关于插件注册 + +这个插件不需要额外写进 `~/.config/opencode/opencode.json`。 + +原因是 OpenCode 会自动扫描 `~/.config/opencode/plugins/` 下面的一级 `*.ts` / `*.js` 文件,`openviking-memory.ts` 放在这个目录顶层即可被发现。 + +### Step 4: 配置 API Key + +推荐使用环境变量,不要把真实 key 写进配置文件: + +```bash +export OPENVIKING_API_KEY="your-api-key-here" +``` + +如果你使用 `zsh`,可以把它写进 `~/.zshrc`: + +```bash +echo 'export OPENVIKING_API_KEY="your-api-key-here"' >> ~/.zshrc +source ~/.zshrc +``` + +--- + +## 启动与验证 + +配置完成后,正常启动 OpenCode 即可。 + +插件初始化后会: + +- 对 OpenViking 做一次 health check +- 为每个 OpenCode session 自动建立对应的 OpenViking session +- 自动把用户消息和 assistant 消息写入 OpenViking +- 按周期触发后台 `commit` + +你可以在会话里尝试: + +```text +请用 memsearch 搜索我之前的偏好 +``` + +或者手动触发一次记忆提取: + +```text +请调用 memcommit +``` + +--- + +## 运行时文件 + +插件运行后,会在插件目录里生成这些本地文件: + +- `~/.config/opencode/plugins/openviking-config.json` +- `~/.config/opencode/plugins/openviking-memory.log` +- `~/.config/opencode/plugins/openviking-session-map.json` + +这些文件都是运行时产物,不建议提交到版本库。示例里的 `.gitignore` 已经帮你排除了它们。 + +如果你明确希望按工作区隔离插件,也可以把这三个文件和 `openviking-memory.ts` 一起放在工作区本地插件目录里。当前实现会把配置和运行时文件统一保存在“插件文件所在目录”。 + +--- + +## 常见问题 + +### 1. 插件没有生效 + +先确认文件位置正确: + +```bash +ls ~/.config/opencode/plugins/ +``` + +至少要能看到: + +- `openviking-memory.ts` +- `openviking-config.json` + +### 2. `Authentication failed` + +通常是 API Key 配置不对。优先检查: + +- `OPENVIKING_API_KEY` 是否已设置 +- 服务端是否启用了认证 +- `endpoint` 是否连到了正确的 OpenViking 服务 + +### 3. `Service unavailable` + +说明插件连不上 OpenViking 服务。检查: + +```bash +curl http://localhost:1933/health +``` + +如果失败,先启动: + +```bash +openviking-server --config ~/.openviking/ov.conf +``` + +### 4. `memcommit` 很慢或经常超时 + +这个示例已经改成了后台 commit task 模式。一般情况下,即使记忆提取比较慢,也不应该再出现“每分钟同步重试一次”的风暴。 + +如果你仍然觉得慢,优先检查的是: + +- OpenViking 服务端的模型配置 +- 服务端所在机器的资源是否吃满 +- `openviking-memory.log` 里是否有持续的 task failure + +### 5. 没有抽出任何 memory + +通常不是插件没工作,而是服务端提取条件不满足。优先检查: + +- OpenViking 的 `vlm` 和 `embedding` 是否已正确配置 +- 当前对话里是否真的有适合沉淀为 memory 的内容 + +--- + +## 相关文件 + +- [README.md](./README.md): English overview +- [openviking-memory.ts](./openviking-memory.ts): plugin implementation +- [openviking-config.example.json](./openviking-config.example.json): config template diff --git a/examples/opencode-memory-plugin/README.md b/examples/opencode-memory-plugin/README.md new file mode 100644 index 00000000..f2d373cd --- /dev/null +++ b/examples/opencode-memory-plugin/README.md @@ -0,0 +1,196 @@ +# OpenViking Memory Plugin for OpenCode + +OpenCode plugin example that exposes OpenViking memories as explicit tools and automatically syncs conversation sessions into OpenViking. + +Chinese install guide: [INSTALL-ZH.md](./INSTALL-ZH.md) + +## Mechanism + +This example uses OpenCode's tool mechanism to expose OpenViking capabilities as explicit agent-callable tools. + +In practice, that means: + +- the agent sees concrete tools and decides when to call them +- OpenViking data is fetched on demand through tool execution instead of being pre-injected into every prompt +- the plugin also keeps an OpenViking session in sync with the OpenCode conversation and triggers background memory extraction with `memcommit` + +This example focuses on explicit memory access, filesystem-style browsing, and session-to-memory synchronization inside OpenCode. + +## What It Does + +- Exposes four memory tools for OpenCode agents: + - `memsearch` + - `memread` + - `membrowse` + - `memcommit` +- Automatically maps each OpenCode session to an OpenViking session +- Streams user and assistant messages into OpenViking +- Uses background `commit` tasks to avoid repeated synchronous timeout failures +- Persists local runtime state for reconnect and recovery + +## Files + +This example contains: + +- `openviking-memory.ts`: the plugin implementation used by OpenCode +- `openviking-config.example.json`: template config +- `.gitignore`: ignores local runtime files after you copy the example into a workspace + +## Prerequisites + +- OpenCode +- OpenViking HTTP Server +- A valid OpenViking API key if your server requires authentication + +Start the server first if it is not already running: + +```bash +openviking-server --config ~/.openviking/ov.conf +``` + +## Install Into OpenCode + +Recommended location from the OpenCode docs: + +```bash +~/.config/opencode/plugins +``` + +Install with: + +```bash +mkdir -p ~/.config/opencode/plugins +cp examples/opencode-memory-plugin/openviking-memory.ts ~/.config/opencode/plugins/openviking-memory.ts +cp examples/opencode-memory-plugin/openviking-config.example.json ~/.config/opencode/plugins/openviking-config.json +cp examples/opencode-memory-plugin/.gitignore ~/.config/opencode/plugins/.gitignore +``` + +Then edit `~/.config/opencode/plugins/openviking-config.json`. + +OpenCode auto-discovers first-level `*.ts` and `*.js` files under `~/.config/opencode/plugins`, so no explicit `plugin` entry is required in `~/.config/opencode/opencode.json`. + +This plugin also works if you intentionally place it in a workspace-local plugin directory, because it stores config and runtime files next to the plugin file itself. + +Recommended: provide the API key via environment variable instead of writing it into the config file: + +```bash +export OPENVIKING_API_KEY="your-api-key-here" +``` + +## Configuration + +Example config: + +```json +{ + "endpoint": "http://localhost:1933", + "apiKey": "", + "enabled": true, + "timeoutMs": 30000, + "autoCommit": { + "enabled": true, + "intervalMinutes": 10 + } +} +``` + +The environment variable `OPENVIKING_API_KEY` takes precedence over the config file. + +## Runtime Files + +After installation, the plugin creates these local files next to the plugin file: + +- `openviking-config.json` +- `openviking-memory.log` +- `openviking-session-map.json` + +These are runtime artifacts and should not be committed. + +## Tools + +### `memsearch` + +Unified search across memories, resources, and skills. + +Parameters: + +- `query`: search query +- `target_uri?`: narrow search to a URI prefix such as `viking://user/memories/` +- `mode?`: `auto | fast | deep` +- `limit?`: max results +- `score_threshold?`: optional minimum score + +### `memread` + +Read content from a specific `viking://` URI. + +Parameters: + +- `uri`: target URI +- `level?`: `auto | abstract | overview | read` + +### `membrowse` + +Browse the OpenViking filesystem layout. + +Parameters: + +- `uri`: target URI +- `view?`: `list | tree | stat` +- `recursive?`: only for `view: "list"` +- `simple?`: only for `view: "list"` + +### `memcommit` + +Trigger immediate memory extraction for the current session. + +Parameters: + +- `session_id?`: optional explicit OpenViking session ID + +Returns background task progress or completion details, including `task_id`, `memories_extracted`, and `archived`. + +## Usage Examples + +Search and then read: + +```typescript +const results = await memsearch({ + query: "user coding preferences", + target_uri: "viking://user/memories/", + mode: "auto" +}) + +const content = await memread({ + uri: results[0].uri, + level: "auto" +}) +``` + +Browse first: + +```typescript +const tree = await membrowse({ + uri: "viking://resources/", + view: "tree" +}) +``` + +Force a mid-session commit: + +```typescript +const result = await memcommit({}) +``` + +## Notes for Reviewers + +- The plugin is designed to run as a first-level `*.ts` file in the OpenCode plugins directory +- It intentionally keeps runtime config, logs, and session maps outside the repository example +- It uses OpenViking background commit tasks to avoid repeated timeout/retry loops during long memory extraction + +## Troubleshooting + +- Plugin not loading: confirm the file exists at `~/.config/opencode/plugins/openviking-memory.ts` +- Service unavailable: confirm `openviking-server` is running and reachable at the configured endpoint +- Authentication failed: check `OPENVIKING_API_KEY` or `openviking-config.json` +- No memories extracted: check that your OpenViking server has working `vlm` and `embedding` configuration diff --git a/examples/opencode-memory-plugin/openviking-config.example.json b/examples/opencode-memory-plugin/openviking-config.example.json new file mode 100644 index 00000000..ab541fcf --- /dev/null +++ b/examples/opencode-memory-plugin/openviking-config.example.json @@ -0,0 +1,10 @@ +{ + "endpoint": "http://localhost:1933", + "apiKey": "your-api-key-here", + "enabled": true, + "timeoutMs": 30000, + "autoCommit": { + "enabled": true, + "intervalMinutes": 10 + } +} diff --git a/examples/opencode-memory-plugin/openviking-memory.ts b/examples/opencode-memory-plugin/openviking-memory.ts new file mode 100644 index 00000000..6f2ef6b8 --- /dev/null +++ b/examples/opencode-memory-plugin/openviking-memory.ts @@ -0,0 +1,1878 @@ +/** + * OpenViking Memory Plugin for OpenCode + * + * Exposes OpenViking's semantic memory capabilities as tools for AI agents. + * Supports user profiles, preferences, entities, events, cases, and patterns. + * + * Contributed by: littlelory@convolens.net + * GitHub: https://github.com/convolens + * We are building Enterprise AI assistant for consumer brands,with process awareness and memory, + * Serving product development to pre-launch lifecycle + * Copyright 2026 Convolens. + */ + +import type { Hooks, PluginInput } from "@opencode-ai/plugin" +import { tool } from "@opencode-ai/plugin" +import * as fs from "fs" +import * as path from "path" +import { fileURLToPath } from "url" + +const z = tool.schema +const pluginFilePath = fileURLToPath(import.meta.url) +const pluginFileDir = path.dirname(pluginFilePath) + +// ============================================================================ +// Session State Management +// ============================================================================ + +interface SessionMapping { + ovSessionId: string + createdAt: number + capturedMessages: Set // Track captured message IDs to avoid duplicates + messageRoles: Map // Track message ID → role mapping + pendingMessages: Map // Track message ID → content for messages waiting for completion + sendingMessages: Set // Track message IDs currently being sent to avoid duplicate writes + lastCommitTime?: number + commitInFlight?: boolean + commitTaskId?: string + commitStartedAt?: number + pendingCleanup?: boolean +} + +// Persisted format for session mapping (for disk storage) +interface SessionMappingPersisted { + ovSessionId: string + createdAt: number + capturedMessages: string[] // Set → Array + messageRoles: [string, "user" | "assistant"][] // Map → Array of tuples + pendingMessages: [string, string][] // Map → Array of tuples + lastCommitTime?: number + commitInFlight?: boolean + commitTaskId?: string + commitStartedAt?: number + pendingCleanup?: boolean +} + +// Session map file format +interface SessionMapFile { + version: 1 + sessions: Record // opencodeSessionId → mapping + lastSaved: number // timestamp +} + +// Map: OpenCode session ID → OpenViking session ID +const sessionMap = new Map() + +// Buffer for messages that arrive before session mapping is established +interface BufferedMessage { + messageId: string + content?: string + role?: "user" | "assistant" + timestamp: number +} +const sessionMessageBuffer = new Map() // sessionId → messages +const MAX_BUFFERED_MESSAGES_PER_SESSION = 100 +const BUFFERED_MESSAGE_TTL_MS = 15 * 60 * 1000 +const BUFFER_CLEANUP_INTERVAL_MS = 30 * 1000 +let lastBufferCleanupAt = 0 + +// ============================================================================ +// Logging +// ============================================================================ + +let logFilePath: string | null = null +let pluginDataDir: string | null = null + +function ensurePluginDataDir(): string | null { + const pluginDir = pluginFileDir + try { + fs.mkdirSync(pluginDir, { recursive: true }) + return pluginDir + } catch (error) { + console.error("Failed to ensure plugin directory:", error) + return null + } +} + +function initLogger() { + const pluginDir = ensurePluginDataDir() + if (!pluginDir) return + pluginDataDir = pluginDir + logFilePath = path.join(pluginDir, "openviking-memory.log") +} + +function safeStringify(obj: any): any { + if (obj === null || obj === undefined) return obj + if (typeof obj !== "object") return obj + + // Handle arrays + if (Array.isArray(obj)) { + return obj.map((item) => safeStringify(item)) + } + + // Handle objects + const result: any = {} + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + const value = obj[key] + if (typeof value === "function") { + result[key] = "[Function]" + } else if (typeof value === "object" && value !== null) { + try { + result[key] = safeStringify(value) + } catch { + result[key] = "[Circular or Non-serializable]" + } + } else { + result[key] = value + } + } + } + return result +} + +function log(level: "INFO" | "ERROR" | "DEBUG", toolName: string, message: string, data?: any) { + if (!logFilePath) return + + const timestamp = new Date().toISOString() + const logEntry = { + timestamp, + level, + tool: toolName, + message, + ...(data && { data: safeStringify(data) }), + } + + try { + const logLine = JSON.stringify(logEntry) + "\n" + fs.appendFileSync(logFilePath, logLine, "utf-8") + } catch (error) { + console.error("Failed to write to log file:", error) + } +} + +// ============================================================================ +// Session Map Persistence +// ============================================================================ + +let sessionMapPath: string | null = null + +function initSessionMapPath() { + const pluginDir = pluginDataDir ?? ensurePluginDataDir() + if (!pluginDir) return + pluginDataDir = pluginDir + sessionMapPath = path.join(pluginDir, "openviking-session-map.json") +} + +function serializeSessionMapping(mapping: SessionMapping): SessionMappingPersisted { + return { + ovSessionId: mapping.ovSessionId, + createdAt: mapping.createdAt, + capturedMessages: Array.from(mapping.capturedMessages), + messageRoles: Array.from(mapping.messageRoles.entries()), + pendingMessages: Array.from(mapping.pendingMessages.entries()), + lastCommitTime: mapping.lastCommitTime, + commitInFlight: mapping.commitInFlight, + commitTaskId: mapping.commitTaskId, + commitStartedAt: mapping.commitStartedAt, + pendingCleanup: mapping.pendingCleanup, + } +} + +function deserializeSessionMapping(persisted: SessionMappingPersisted): SessionMapping { + return { + ovSessionId: persisted.ovSessionId, + createdAt: persisted.createdAt, + capturedMessages: new Set(persisted.capturedMessages), + messageRoles: new Map(persisted.messageRoles), + pendingMessages: new Map(persisted.pendingMessages), + sendingMessages: new Set(), + lastCommitTime: persisted.lastCommitTime, + commitInFlight: persisted.commitInFlight, + commitTaskId: persisted.commitTaskId, + commitStartedAt: persisted.commitStartedAt, + pendingCleanup: persisted.pendingCleanup, + } +} + +async function loadSessionMap(): Promise { + if (!sessionMapPath) return + + try { + if (!fs.existsSync(sessionMapPath)) { + log("INFO", "persistence", "No session map file found, starting fresh") + return + } + + const content = await fs.promises.readFile(sessionMapPath, "utf-8") + const data: SessionMapFile = JSON.parse(content) + + if (data.version !== 1) { + log("ERROR", "persistence", "Unsupported session map version", { version: data.version }) + return + } + + for (const [opencodeSessionId, persisted] of Object.entries(data.sessions)) { + sessionMap.set(opencodeSessionId, deserializeSessionMapping(persisted)) + } + + log("INFO", "persistence", "Session map loaded", { + count: sessionMap.size, + last_saved: new Date(data.lastSaved).toISOString() + }) + } catch (error: any) { + log("ERROR", "persistence", "Failed to load session map", { error: error.message }) + + // Backup corrupted file + if (fs.existsSync(sessionMapPath)) { + const backupPath = `${sessionMapPath}.corrupted.${Date.now()}` + await fs.promises.rename(sessionMapPath, backupPath) + log("INFO", "persistence", "Corrupted file backed up", { backup: backupPath }) + } + } +} + +async function saveSessionMap(): Promise { + if (!sessionMapPath) return + + try { + const sessions: Record = {} + for (const [opencodeSessionId, mapping] of sessionMap.entries()) { + sessions[opencodeSessionId] = serializeSessionMapping(mapping) + } + + const data: SessionMapFile = { + version: 1, + sessions, + lastSaved: Date.now() + } + + // Atomic write: temp file + rename + const tempPath = sessionMapPath + '.tmp' + await fs.promises.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8") + await fs.promises.rename(tempPath, sessionMapPath) + + log("DEBUG", "persistence", "Session map saved", { count: sessionMap.size }) + } catch (error: any) { + log("ERROR", "persistence", "Failed to save session map", { error: error.message }) + } +} + +// Debounced save to reduce disk I/O +let saveTimer: NodeJS.Timeout | null = null + +function debouncedSaveSessionMap(): void { + if (saveTimer) clearTimeout(saveTimer) + saveTimer = setTimeout(() => { + saveSessionMap().catch(error => { + log("ERROR", "persistence", "Debounced save failed", { error: error.message }) + }) + }, 300) +} + +// ============================================================================ +// Configuration +// ============================================================================ + +interface OpenVikingConfig { + endpoint: string + apiKey: string + enabled: boolean + timeoutMs: number + autoCommit?: { + enabled: boolean + intervalMinutes: number + } +} + +// ============================================================================ +// API Response Types +// ============================================================================ + +interface OpenVikingResponse { + status: string + result?: T + error?: string | { code?: string; message?: string; details?: Record } + time?: number + usage?: Record +} + +interface SearchResult { + memories: any[] + resources: any[] + skills: any[] + total: number + query_plan?: string +} + +interface CommitResult { + session_id: string + status: string + memories_extracted: number + active_count_updated: number + archived: boolean + task_id?: string + message?: string + stats?: { + total_turns?: number + contexts_used?: number + skills_used?: number + memories_extracted?: number + } +} + +interface SessionResult { + session_id: string +} + +interface TaskResult { + task_id: string + task_type: string + status: "pending" | "running" | "completed" | "failed" + created_at: number + updated_at: number + resource_id?: string + result?: { + session_id?: string + memories_extracted?: number + archived?: boolean + } + error?: string | null +} + +type CommitStartResult = + | { mode: "background"; taskId: string } + | { mode: "completed"; result: CommitResult } + +const DEFAULT_CONFIG: OpenVikingConfig = { + endpoint: "http://localhost:1933", + apiKey: "", + enabled: true, + timeoutMs: 30000, + autoCommit: { + enabled: true, + intervalMinutes: 10 + } +} + +function loadConfig(): OpenVikingConfig { + const configPath = path.join(pluginFileDir, "openviking-config.json") + + try { + if (fs.existsSync(configPath)) { + const fileContent = fs.readFileSync(configPath, "utf-8") + const fileConfig = JSON.parse(fileContent) + const config = { + ...DEFAULT_CONFIG, + ...fileConfig, + autoCommit: fileConfig.autoCommit + ? { + ...DEFAULT_CONFIG.autoCommit, + ...fileConfig.autoCommit, + } + : DEFAULT_CONFIG.autoCommit + ? { ...DEFAULT_CONFIG.autoCommit } + : undefined, + } + if (config.autoCommit) { + config.autoCommit.intervalMinutes = getAutoCommitIntervalMinutes(config) + } + + // Environment variable takes precedence over config file + if (process.env.OPENVIKING_API_KEY) { + config.apiKey = process.env.OPENVIKING_API_KEY + } + + return config + } + } catch (error) { + console.warn(`Failed to load OpenViking config from ${configPath}:`, error) + } + + // Check environment variable even if config file doesn't exist + const config = { + ...DEFAULT_CONFIG, + autoCommit: DEFAULT_CONFIG.autoCommit + ? { ...DEFAULT_CONFIG.autoCommit } + : undefined, + } + if (process.env.OPENVIKING_API_KEY) { + config.apiKey = process.env.OPENVIKING_API_KEY + } + if (config.autoCommit) { + config.autoCommit.intervalMinutes = getAutoCommitIntervalMinutes(config) + } + + return config +} + +// ============================================================================ +// HTTP Client +// ============================================================================ + +interface HttpRequestOptions { + method: "GET" | "POST" | "PUT" | "DELETE" + endpoint: string + body?: any + timeoutMs?: number + abortSignal?: AbortSignal +} + +async function makeRequest(config: OpenVikingConfig, options: HttpRequestOptions): Promise { + const url = `${config.endpoint}${options.endpoint}` + const headers: Record = { + "Content-Type": "application/json", + } + + if (config.apiKey) { + headers["X-API-Key"] = config.apiKey + } + + const controller = new AbortController() + const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? config.timeoutMs) + + // Chain with tool's abort signal if provided + const signal = options.abortSignal + ? AbortSignal.any([options.abortSignal, controller.signal]) + : controller.signal + + try { + const response = await fetch(url, { + method: options.method, + headers, + body: options.body ? JSON.stringify(options.body) : undefined, + signal, + }) + + clearTimeout(timeout) + + if (!response.ok) { + const errorText = await response.text() + let errorMessage: string + try { + const errorJson = JSON.parse(errorText) + // Handle case where error/message might be objects + const rawError = errorJson.error || errorJson.message + if (typeof rawError === "string") { + errorMessage = rawError + } else if (rawError && typeof rawError === "object") { + errorMessage = JSON.stringify(rawError) + } else { + errorMessage = errorText + } + } catch { + errorMessage = errorText + } + + switch (response.status) { + case 401: + case 403: + throw new Error("Authentication failed. Please check API key configuration.") + case 404: + throw new Error(`Resource not found: ${options.endpoint}`) + case 500: + throw new Error(`OpenViking server error: ${errorMessage}`) + default: + throw new Error(`Request failed (${response.status}): ${errorMessage}`) + } + } + + return (await response.json()) as T + } catch (error: any) { + clearTimeout(timeout) + + if (error.name === "AbortError") { + throw new Error(`Request timeout after ${options.timeoutMs ?? config.timeoutMs}ms`) + } + + if (error.message?.includes("fetch failed") || error.code === "ECONNREFUSED") { + throw new Error( + `OpenViking service unavailable at ${config.endpoint}. Please check if the service is running (try: openviking-server).`, + ) + } + + throw error + } +} + +function getResponseErrorMessage(error: OpenVikingResponse["error"]): string { + if (!error) return "Unknown OpenViking error" + if (typeof error === "string") return error + return error.message || error.code || "Unknown OpenViking error" +} + +function unwrapResponse(response: OpenVikingResponse): T { + if (!response || typeof response !== "object") { + throw new Error("OpenViking returned an invalid response") + } + if (response.status && response.status !== "ok") { + throw new Error(getResponseErrorMessage(response.error)) + } + return response.result as T +} + +async function checkServiceHealth(config: OpenVikingConfig): Promise { + try { + const response = await fetch(`${config.endpoint}/health`, { + method: "GET", + signal: AbortSignal.timeout(3000), + }) + return response.ok + } catch (error: any) { + log("ERROR", "health", "OpenViking health check failed", { + endpoint: config.endpoint, + error: error.message, + }) + return false + } +} + +// ============================================================================ +// Session Lifecycle Helpers +// ============================================================================ + +function mergeMessageContent(existing: string | undefined, incoming: string): string { + const next = incoming.trim() + if (!next) return existing ?? "" + if (!existing) return next + if (next === existing) return existing + if (next.startsWith(existing)) return next + if (existing.startsWith(next)) return existing + if (next.includes(existing)) return next + if (existing.includes(next)) return existing + return `${existing}\n${next}`.trim() +} + +function upsertBufferedMessage( + sessionId: string, + messageId: string, + updates: Partial>, +): void { + const now = Date.now() + + if (now - lastBufferCleanupAt >= BUFFER_CLEANUP_INTERVAL_MS) { + for (const [bufferedSessionId, bufferedMessages] of sessionMessageBuffer.entries()) { + const freshMessages = bufferedMessages.filter((message) => now - message.timestamp <= BUFFERED_MESSAGE_TTL_MS) + if (freshMessages.length === 0) { + sessionMessageBuffer.delete(bufferedSessionId) + continue + } + if (freshMessages.length !== bufferedMessages.length) { + sessionMessageBuffer.set(bufferedSessionId, freshMessages) + } + } + lastBufferCleanupAt = now + } + + const existingBuffer = sessionMessageBuffer.get(sessionId) ?? [] + const freshBuffer = existingBuffer.filter((message) => now - message.timestamp <= BUFFERED_MESSAGE_TTL_MS) + + let buffered = freshBuffer.find((message) => message.messageId === messageId) + if (!buffered) { + while (freshBuffer.length >= MAX_BUFFERED_MESSAGES_PER_SESSION) { + freshBuffer.shift() + } + buffered = { messageId, timestamp: now } + freshBuffer.push(buffered) + } else { + buffered.timestamp = now + } + + if (updates.role) { + buffered.role = updates.role + } + if (updates.content) { + buffered.content = mergeMessageContent(buffered.content, updates.content) + } + + sessionMessageBuffer.set(sessionId, freshBuffer) +} + +function getAutoCommitIntervalMinutes(config: OpenVikingConfig): number { + const configured = Number(config.autoCommit?.intervalMinutes ?? DEFAULT_CONFIG.autoCommit?.intervalMinutes ?? 10) + if (!Number.isFinite(configured)) { + return DEFAULT_CONFIG.autoCommit?.intervalMinutes ?? 10 + } + return Math.max(1, configured) +} + +function resolveEventSessionId(event: any): string | undefined { + return event?.properties?.info?.id + ?? event?.properties?.sessionID + ?? event?.properties?.sessionId +} + +/** + * Create or connect to OpenViking session for an OpenCode session + */ +async function ensureOpenVikingSession( + opencodeSessionId: string, + config: OpenVikingConfig, +): Promise { + const existingMapping = sessionMap.get(opencodeSessionId) + const knownSessionId = existingMapping?.ovSessionId + + if (knownSessionId) { + try { + const response = await makeRequest>(config, { + method: "GET", + endpoint: `/api/v1/sessions/${knownSessionId}`, + timeoutMs: 5000, + }) + const result = unwrapResponse(response) + if (result) { + log("INFO", "session", "Reconnected to persisted OpenViking session", { + opencode_session: opencodeSessionId, + openviking_session: knownSessionId, + }) + return knownSessionId + } + } catch (error: any) { + log("INFO", "session", "Persisted OpenViking session unavailable, creating a new one", { + opencode_session: opencodeSessionId, + openviking_session: knownSessionId, + error: error.message, + }) + } + } + + try { + const createResponse = await makeRequest>(config, { + method: "POST", + endpoint: "/api/v1/sessions", + body: {}, + timeoutMs: 5000, + }) + + const sessionId = unwrapResponse(createResponse)?.session_id + if (!sessionId) { + throw new Error("OpenViking did not return a session_id") + } + + log("INFO", "session", "Created new OpenViking session", { + opencode_session: opencodeSessionId, + openviking_session: sessionId, + }) + return sessionId + } catch (error: any) { + log("ERROR", "session", "Failed to create OpenViking session", { + opencode_session: opencodeSessionId, + error: error.message, + }) + return null + } +} + +async function sleep(ms: number, abortSignal?: AbortSignal): Promise { + await new Promise((resolve, reject) => { + const timer = setTimeout(() => { + abortSignal?.removeEventListener("abort", onAbort) + resolve() + }, ms) + + function onAbort() { + clearTimeout(timer) + reject(new Error("Operation aborted")) + } + + abortSignal?.addEventListener("abort", onAbort, { once: true }) + }) +} + +async function findRunningCommitTaskId( + ovSessionId: string, + config: OpenVikingConfig, +): Promise { + try { + const response = await makeRequest>(config, { + method: "GET", + endpoint: `/api/v1/tasks?task_type=session_commit&resource_id=${encodeURIComponent(ovSessionId)}&limit=10`, + timeoutMs: 5000, + }) + const tasks = unwrapResponse(response) ?? [] + const runningTask = tasks.find((task) => task.status === "pending" || task.status === "running") + return runningTask?.task_id + } catch (error: any) { + log("ERROR", "session", "Failed to query running commit tasks", { + openviking_session: ovSessionId, + error: error.message, + }) + return undefined + } +} + +function clearCommitState(mapping: SessionMapping): void { + mapping.commitInFlight = false + mapping.commitTaskId = undefined + mapping.commitStartedAt = undefined +} + +let backgroundCommitSupported: boolean | null = null +const COMMIT_TIMEOUT_MS = 180000 + +async function detectBackgroundCommitSupport(config: OpenVikingConfig): Promise { + if (backgroundCommitSupported !== null) { + return backgroundCommitSupported + } + + const headers: Record = {} + if (config.apiKey) { + headers["X-API-Key"] = config.apiKey + } + + try { + const response = await fetch(`${config.endpoint}/api/v1/tasks?limit=1`, { + method: "GET", + headers, + signal: AbortSignal.timeout(3000), + }) + backgroundCommitSupported = response.ok + } catch { + backgroundCommitSupported = false + } + + log( + "INFO", + "session", + backgroundCommitSupported + ? "Detected background commit API support" + : "Detected legacy synchronous commit API", + { endpoint: config.endpoint }, + ) + return backgroundCommitSupported +} + +async function finalizeCommitSuccess( + mapping: SessionMapping, + opencodeSessionId: string, + config: OpenVikingConfig, +): Promise { + mapping.lastCommitTime = Date.now() + mapping.capturedMessages.clear() + clearCommitState(mapping) + debouncedSaveSessionMap() + + await flushPendingMessages(opencodeSessionId, mapping, config) + + if (mapping.pendingCleanup) { + sessionMap.delete(opencodeSessionId) + sessionMessageBuffer.delete(opencodeSessionId) + await saveSessionMap() + log("INFO", "session", "Cleaned up session mapping after commit completion", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + }) + } +} + +async function runSynchronousCommit( + mapping: SessionMapping, + opencodeSessionId: string, + config: OpenVikingConfig, + abortSignal?: AbortSignal, +): Promise { + mapping.commitInFlight = true + mapping.commitTaskId = undefined + mapping.commitStartedAt = Date.now() + debouncedSaveSessionMap() + + try { + const response = await makeRequest>(config, { + method: "POST", + endpoint: `/api/v1/sessions/${mapping.ovSessionId}/commit`, + timeoutMs: Math.max(config.timeoutMs, COMMIT_TIMEOUT_MS), + abortSignal, + }) + const result = unwrapResponse(response) + + log("INFO", "session", "OpenViking synchronous commit completed", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + memories_extracted: result?.memories_extracted ?? 0, + archived: result?.archived ?? false, + }) + + await finalizeCommitSuccess(mapping, opencodeSessionId, config) + return result + } catch (error: any) { + clearCommitState(mapping) + debouncedSaveSessionMap() + throw error + } +} + +async function flushPendingMessages( + opencodeSessionId: string, + mapping: SessionMapping, + config: OpenVikingConfig, +): Promise { + if (mapping.commitInFlight) { + return + } + + for (const messageId of Array.from(mapping.pendingMessages.keys())) { + if (mapping.capturedMessages.has(messageId) || mapping.sendingMessages.has(messageId)) { + continue + } + const role = mapping.messageRoles.get(messageId) + const content = mapping.pendingMessages.get(messageId) + if (!role || !content || !content.trim()) { + continue + } + + mapping.sendingMessages.add(messageId) + try { + log("DEBUG", "message", "Committing pending message content", { + session_id: opencodeSessionId, + message_id: messageId, + role, + content_length: content.length, + }) + + const success = await addMessageToSession( + mapping.ovSessionId, + role, + content, + config + ) + + if (success) { + const latestContent = mapping.pendingMessages.get(messageId) + if (latestContent && latestContent !== content) { + log("DEBUG", "message", "Message changed during send; keeping latest content pending", { + session_id: opencodeSessionId, + message_id: messageId, + role, + previous_length: content.length, + latest_length: latestContent.length, + }) + } else { + mapping.capturedMessages.add(messageId) + mapping.pendingMessages.delete(messageId) + debouncedSaveSessionMap() + log("INFO", "message", `${role} message captured successfully`, { + session_id: opencodeSessionId, + message_id: messageId, + role, + }) + } + } + } finally { + mapping.sendingMessages.delete(messageId) + } + } +} + +async function startBackgroundCommit( + mapping: SessionMapping, + opencodeSessionId: string, + config: OpenVikingConfig, + abortSignal?: AbortSignal, +): Promise { + if (mapping.commitInFlight && mapping.commitTaskId) { + return { mode: "background", taskId: mapping.commitTaskId } + } + + const supportsBackgroundCommit = await detectBackgroundCommitSupport(config) + if (!supportsBackgroundCommit) { + try { + const result = await runSynchronousCommit(mapping, opencodeSessionId, config, abortSignal) + return { mode: "completed", result } + } catch (error: any) { + log("ERROR", "session", "Failed to run synchronous commit", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + error: error.message, + }) + return null + } + } + + try { + const response = await makeRequest>(config, { + method: "POST", + endpoint: `/api/v1/sessions/${mapping.ovSessionId}/commit?wait=false`, + timeoutMs: 5000, + abortSignal, + }) + const data = unwrapResponse(response) + const taskId = data?.task_id + if (!taskId) { + throw new Error("OpenViking did not return a background task id") + } + + mapping.commitInFlight = true + mapping.commitTaskId = taskId + mapping.commitStartedAt = Date.now() + debouncedSaveSessionMap() + + log("INFO", "session", "OpenViking background commit accepted", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + task_id: taskId, + }) + return { mode: "background", taskId } + } catch (error: any) { + if (error.message?.includes("already has a commit in progress")) { + const taskId = await findRunningCommitTaskId(mapping.ovSessionId, config) + if (taskId) { + mapping.commitInFlight = true + mapping.commitTaskId = taskId + mapping.commitStartedAt = mapping.commitStartedAt ?? Date.now() + debouncedSaveSessionMap() + log("INFO", "session", "Recovered existing background commit task", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + task_id: taskId, + }) + return { mode: "background", taskId } + } + } + + if ( + error.message?.includes("Request timeout") || + error.message?.includes("background task id") + ) { + backgroundCommitSupported = false + try { + const result = await runSynchronousCommit(mapping, opencodeSessionId, config, abortSignal) + return { mode: "completed", result } + } catch (fallbackError: any) { + log("ERROR", "session", "Failed to fall back to synchronous commit", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + error: fallbackError.message, + }) + } + } + + log("ERROR", "session", "Failed to start OpenViking background commit", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + error: error.message, + }) + return null + } +} + +async function pollCommitTaskOnce( + mapping: SessionMapping, + opencodeSessionId: string, + config: OpenVikingConfig, +): Promise { + if (!mapping.commitInFlight) { + return "unknown" + } + + if (!mapping.commitTaskId) { + return "running" + } + + try { + const response = await makeRequest>(config, { + method: "GET", + endpoint: `/api/v1/tasks/${mapping.commitTaskId}`, + timeoutMs: 5000, + }) + const task = unwrapResponse(response) + + if (task.status === "pending" || task.status === "running") { + return task.status + } + + if (task.status === "completed") { + const memoriesExtracted = task.result?.memories_extracted ?? 0 + const archived = task.result?.archived ?? false + + log("INFO", "session", "OpenViking background commit completed", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + task_id: task.task_id, + memories_extracted: memoriesExtracted, + archived, + }) + + await finalizeCommitSuccess(mapping, opencodeSessionId, config) + + return task.status + } + + log("ERROR", "session", "OpenViking background commit failed", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + task_id: task.task_id, + error: task.error, + }) + + clearCommitState(mapping) + debouncedSaveSessionMap() + + if (mapping.pendingCleanup) { + sessionMap.delete(opencodeSessionId) + sessionMessageBuffer.delete(opencodeSessionId) + await saveSessionMap() + log("INFO", "session", "Cleaned up session mapping after failed commit", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + }) + } + + return task.status + } catch (error: any) { + log("ERROR", "session", "Failed to poll OpenViking background commit", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + task_id: mapping.commitTaskId, + error: error.message, + }) + return "unknown" + } +} + +async function waitForCommitCompletion( + mapping: SessionMapping, + opencodeSessionId: string, + config: OpenVikingConfig, + abortSignal?: AbortSignal, + timeoutMs = 180000, +): Promise { + const startedAt = Date.now() + + while (Date.now() - startedAt < timeoutMs) { + if (abortSignal?.aborted) { + throw new Error("Operation aborted") + } + + if (!mapping.commitInFlight) { + return null + } + if (!mapping.commitTaskId) { + await sleep(500, abortSignal) + continue + } + + const response = await makeRequest>(config, { + method: "GET", + endpoint: `/api/v1/tasks/${mapping.commitTaskId}`, + timeoutMs: 5000, + abortSignal, + }) + const task = unwrapResponse(response) + + if (task.status === "completed") { + const memoriesExtracted = task.result?.memories_extracted ?? 0 + const archived = task.result?.archived ?? false + + await finalizeCommitSuccess(mapping, opencodeSessionId, config) + + log("INFO", "memcommit", "Background commit completed while waiting", { + openviking_session: mapping.ovSessionId, + opencode_session: opencodeSessionId, + task_id: task.task_id, + memories_extracted: memoriesExtracted, + archived, + }) + return task + } + + if (task.status === "failed") { + clearCommitState(mapping) + debouncedSaveSessionMap() + throw new Error(task.error || "Background commit failed") + } + + await sleep(2000, abortSignal) + } + + return null +} + +// ============================================================================ +// Auto-Commit Scheduler +// ============================================================================ + +let autoCommitTimer: NodeJS.Timeout | null = null + +function startAutoCommit(config: OpenVikingConfig) { + if (!config.autoCommit?.enabled) { + log("INFO", "auto-commit", "Auto-commit disabled in config") + return + } + + const checkIntervalMs = 60 * 1000 // Check every minute + + autoCommitTimer = setInterval(async () => { + await checkAndCommitSessions(config) + }, checkIntervalMs) + + log("INFO", "auto-commit", "Auto-commit scheduler started", { + check_interval_seconds: 60, + commit_interval_minutes: getAutoCommitIntervalMinutes(config) + }) +} + +function stopAutoCommit() { + if (autoCommitTimer) { + clearInterval(autoCommitTimer) + autoCommitTimer = null + log("INFO", "auto-commit", "Auto-commit scheduler stopped") + } +} + +async function checkAndCommitSessions(config: OpenVikingConfig): Promise { + const intervalMs = getAutoCommitIntervalMinutes(config) * 60 * 1000 + const now = Date.now() + + for (const [opencodeSessionId, mapping] of sessionMap.entries()) { + if (mapping.commitInFlight) { + await pollCommitTaskOnce(mapping, opencodeSessionId, config) + continue + } + + if (mapping.pendingMessages.size > 0) { + await flushPendingMessages(opencodeSessionId, mapping, config) + } + + const timeSinceLastCommit = now - (mapping.lastCommitTime ?? mapping.createdAt) + const hasNewMessages = mapping.capturedMessages.size > 0 + + if (timeSinceLastCommit >= intervalMs && hasNewMessages) { + log("INFO", "auto-commit", "Triggering auto-commit", { + opencode_session: opencodeSessionId, + openviking_session: mapping.ovSessionId, + time_since_last_commit_minutes: Math.floor(timeSinceLastCommit / 60000), + captured_messages_count: mapping.capturedMessages.size + }) + + await startBackgroundCommit(mapping, opencodeSessionId, config) + } + } +} + +/** + * Add message to OpenViking session + */ +async function addMessageToSession( + ovSessionId: string, + role: "user" | "assistant", + content: string, + config: OpenVikingConfig, +): Promise { + try { + const response = await makeRequest>(config, { + method: "POST", + endpoint: `/api/v1/sessions/${ovSessionId}/messages`, + body: { role, content }, + timeoutMs: 5000, + }) + unwrapResponse(response) + + log("INFO", "message", "Message added to OpenViking session", { + openviking_session: ovSessionId, + role, + content_length: content.length, + }) + return true + } catch (error: any) { + log("ERROR", "message", "Failed to add message to OpenViking session", { + openviking_session: ovSessionId, + role, + error: error.message, + }) + return false + } +} + +// ============================================================================ +// Helper Functions +// ============================================================================ + +function formatSearchResults( + result: SearchResult, + toolName: string, + query: string, + extra?: Record +): string { + const { memories = [], resources = [], skills = [] } = result + const allResults = [...memories, ...resources, ...skills] + if (allResults.length === 0) { + log("INFO", toolName, "No results found", { query }) + return "No results found matching the query." + } + log("INFO", toolName, "Search completed", { count: allResults.length }) + return JSON.stringify( + { total: result.total ?? allResults.length, memories, resources, skills, ...extra }, + null, 2 + ) +} + +function resolveSearchMode( + requestedMode: "auto" | "fast" | "deep" | undefined, + query: string, + sessionId?: string +): "fast" | "deep" { + if (requestedMode === "fast" || requestedMode === "deep") { + return requestedMode + } + + if (sessionId) { + return "deep" + } + + const normalized = query.trim() + const wordCount = normalized ? normalized.split(/\s+/).length : 0 + if (normalized.includes("?") || normalized.length >= 80 || wordCount >= 8) { + return "deep" + } + + return "fast" +} + +function validateVikingUri(uri: string, toolName: string): string | null { + if (!uri.startsWith("viking://")) { + const error = `Invalid URI format. Must start with "viking://". Example: viking://user/memories/` + log("ERROR", toolName, "Invalid URI format", { uri }) + return `Error: ${error}` + } + return null +} + +// ============================================================================ +// Plugin Export +// ============================================================================ + +export const OpenVikingMemoryPlugin = async (input: PluginInput): Promise => { + const config = loadConfig() + initLogger() + initSessionMapPath() + + if (!config.enabled) { + console.log("OpenViking Memory Plugin is disabled in configuration") + return {} + } + + log("INFO", "plugin", "OpenViking Memory Plugin initialized", { endpoint: config.endpoint }) + + // Load session map from disk + await loadSessionMap() + + const healthy = await checkServiceHealth(config) + log("INFO", "health", healthy ? "OpenViking health check passed" : "OpenViking health check failed", { + endpoint: config.endpoint, + }) + + // Start auto-commit scheduler + startAutoCommit(config) + + return { + event: async ({ event }) => { + if (event && event.type && event.type === "session.diff") { + return; + } + + // Handle session lifecycle events + if (event.type === "session.created") { + const sessionId = resolveEventSessionId(event) + if (!sessionId) { + log("ERROR", "event", "session.created event missing sessionId", { + event: safeStringify(event) + }) + return + } + + log("INFO", "event", "OpenCode session created", { + session_id: sessionId, + session_info: safeStringify(event.properties?.info) + }) + + // Create or connect to OpenViking session (non-blocking) + const ovSessionId = await ensureOpenVikingSession(sessionId, config) + if (ovSessionId) { + sessionMap.set(sessionId, { + ovSessionId, + createdAt: Date.now(), + capturedMessages: new Set(), + messageRoles: new Map(), + pendingMessages: new Map(), + sendingMessages: new Set(), + lastCommitTime: undefined, + commitInFlight: false, + }) + + // Process buffered messages that arrived before session mapping + const bufferedMessages = sessionMessageBuffer.get(sessionId) + if (bufferedMessages && bufferedMessages.length > 0) { + log("INFO", "event", "Processing buffered messages", { + session_id: sessionId, + count: bufferedMessages.length + }) + + const mapping = sessionMap.get(sessionId)! + for (const buffered of bufferedMessages) { + // Store role if available + if (buffered.role) { + mapping.messageRoles.set(buffered.messageId, buffered.role) + } + // Store content as pending if available + if (buffered.content) { + mapping.pendingMessages.set( + buffered.messageId, + mergeMessageContent(mapping.pendingMessages.get(buffered.messageId), buffered.content) + ) + } + + } + + await flushPendingMessages(sessionId, mapping, config) + + // Clear buffer + sessionMessageBuffer.delete(sessionId) + } + + debouncedSaveSessionMap() + log("INFO", "event", "Session mapping established", { + opencode_session: sessionId, + openviking_session: ovSessionId, + session_info: safeStringify(event.properties?.info) + }) + } else { + log("ERROR", "event", "Failed to establish session mapping", { + session_id: sessionId, + session_info: safeStringify(event.properties?.info) + }) + } + } else if (event.type === "session.deleted") { + const sessionId = resolveEventSessionId(event) + if (!sessionId) { + log("ERROR", "event", "session.deleted event missing sessionId", { + event: safeStringify(event) + }) + return + } + + log("INFO", "event", "OpenCode session deleted", { + session_id: sessionId, + session_info: safeStringify(event.properties?.info) + }) + + // Commit OpenViking session if mapped + const mapping = sessionMap.get(sessionId) + if (mapping) { + await flushPendingMessages(sessionId, mapping, config) + + if (mapping.capturedMessages.size > 0 || mapping.commitInFlight) { + mapping.pendingCleanup = true + if (!mapping.commitInFlight) { + await startBackgroundCommit(mapping, sessionId, config) + } + } else { + sessionMap.delete(sessionId) + sessionMessageBuffer.delete(sessionId) // Clean up buffer + await saveSessionMap() + log("INFO", "event", "Session mapping removed", { + opencode_session: sessionId, + openviking_session: mapping.ovSessionId, + session_info: safeStringify(event.properties?.info) + }) + } + } else { + log("INFO", "event", "No session mapping found for deleted session", { + session_id: sessionId, + session_info: safeStringify(event.properties?.info) + }) + } + } else if (event.type === "session.error") { + const sessionId = resolveEventSessionId(event) + if (!sessionId) { + log("ERROR", "event", "session.error event missing sessionId", { + event: safeStringify(event) + }) + return + } + + log("ERROR", "event", "OpenCode session error", { + session_id: sessionId, + error: safeStringify(event.error), + session_info: safeStringify(event.properties?.info) + }) + + // Optionally commit session to preserve work + const mapping = sessionMap.get(sessionId) + if (mapping) { + log("INFO", "event", "Attempting to commit session after error", { + opencode_session: sessionId, + openviking_session: mapping.ovSessionId, + session_info: safeStringify(event.properties?.info) + }) + await flushPendingMessages(sessionId, mapping, config) + + if (mapping.capturedMessages.size > 0 || mapping.commitInFlight) { + mapping.pendingCleanup = true + if (!mapping.commitInFlight) { + await startBackgroundCommit(mapping, sessionId, config) + } + } else { + sessionMap.delete(sessionId) + sessionMessageBuffer.delete(sessionId) // Clean up buffer + await saveSessionMap() + } + } + } else if (event.type === "message.updated") { + // Handle message capture for automatic session recording + const message = event.properties?.info + if (!message) { + log("DEBUG", "event", "message.updated event missing info", { + event: safeStringify(event) + }) + return + } + + const sessionId = message.sessionID + const messageId = message.id + const role = message.role + const finish = message.finish + + // Check if we have a session mapping + const mapping = sessionMap.get(sessionId) + if (!mapping) { + // Buffer this message for later processing + upsertBufferedMessage(sessionId, messageId, role ? { role } : {}) + log("DEBUG", "message", "Message buffered (no session mapping yet)", { + session_id: sessionId, + message_id: messageId, + role: role + }) + return + } + + if (role === "user") { + if (!mapping.messageRoles.has(messageId)) { + mapping.messageRoles.set(messageId, role) + log("DEBUG", "message", `${role} message role stored`, { + session_id: sessionId, + message_id: messageId, + role: role, + }) + } + } else if (role === "assistant" && finish === "stop") { + mapping.messageRoles.set(messageId, role) + + log("DEBUG", "message", `${role} message completed and role stored`, { + session_id: sessionId, + message_id: messageId, + role: role, + finish: finish, + }) + } + + await flushPendingMessages(sessionId, mapping, config) + + // For assistant messages: log when fully completed (with tokens/cost) + if (role === "assistant" && message.time?.completed) { + log("DEBUG", "message", "Assistant message fully completed", { + session_id: sessionId, + message_id: messageId, + tokens: message.tokens, + cost: message.cost, + }) + } + } else if (event.type === "message.part.updated") { + // Handle message part updates to capture content + const part = event.properties?.part + if (!part) { + return + } + + const sessionId = part.sessionID + const messageId = part.messageID + const partType = part.type + + // Check if we have a session mapping + const mapping = sessionMap.get(sessionId) + if (!mapping) { + // Buffer this message content for later processing + if (partType === "text" && part.text && part.text.trim().length > 0) { + upsertBufferedMessage(sessionId, messageId, { content: part.text }) + log("DEBUG", "message", "Message content buffered (no session mapping yet)", { + session_id: sessionId, + message_id: messageId, + content_length: part.text.length + }) + } + return + } + + // Only capture text parts + if (partType === "text" && part.text) { + // Check if message already captured + if (mapping.capturedMessages.has(messageId)) { + return + } + + const content = part.text + if (content && content.trim().length > 0) { + mapping.pendingMessages.set( + messageId, + mergeMessageContent(mapping.pendingMessages.get(messageId), content) + ) + log("DEBUG", "message", "Message content stored as pending", { + session_id: sessionId, + message_id: messageId, + content_length: content.length, + waiting_for_role: !mapping.messageRoles.has(messageId), + commit_in_flight: mapping.commitInFlight === true, + }) + } + } + } + }, + + tool: { + memread: tool({ + description: + "Retrieve the content of a specific memory, resource, or skill at a given viking:// URI.\n\nProgressive loading levels:\n- abstract: brief summary\n- overview: structured directory overview\n- read: full content\n- auto: choose overview for directories and read for files\n\nUse when:\n- You have a URI from memsearch or membrowse\n- You need to inspect a memory, resource, or skill in more detail\n\nRequires: Complete viking:// URI (e.g., viking://user/memories/profile.md)", + args: { + uri: z + .string() + .describe( + "Complete viking:// URI from search results or list output (e.g., viking://user/memories/profile.md, viking://agent/memories/context.md)", + ), + level: z + .enum(["auto", "abstract", "overview", "read"]) + .optional() + .describe("'auto' (directory->overview, file->read), 'abstract' (brief summary), 'overview' (directory summary), 'read' (full content)"), + }, + async execute(args, context) { + log("INFO", "memread", "Reading memory", { uri: args.uri, level: args.level }) + + // Validate URI format + const validationError = validateVikingUri(args.uri, "memread") + if (validationError) return validationError + + try { + let level = args.level ?? "auto" + if (level === "auto") { + try { + const statResponse = await makeRequest>(config, { + method: "GET", + endpoint: `/api/v1/fs/stat?uri=${encodeURIComponent(args.uri)}`, + abortSignal: context.abort, + }) + const statResult = unwrapResponse(statResponse) + level = statResult?.isDir ? "overview" : "read" + } catch { + level = "read" + } + } + + const response = await makeRequest>>(config, { + method: "GET", + endpoint: `/api/v1/content/${level}?uri=${encodeURIComponent(args.uri)}`, + abortSignal: context.abort, + }) + + const content = unwrapResponse(response) + if (!content) { + log("INFO", "memread", "No content found", { uri: args.uri }) + return `No content found at ${args.uri}` + } + + log("INFO", "memread", "Read completed", { uri: args.uri, level }) + return typeof content === "string" ? content : JSON.stringify(content, null, 2) + } catch (error: any) { + log("ERROR", "memread", "Read failed", { error: error.message, uri: args.uri }) + return `Error: ${error.message}` + } + }, + }), + + membrowse: tool({ + description: + "Browse the OpenViking filesystem structure for a specific URI.\n\nViews:\n- list: list immediate children, or recurse when `recursive=true`\n- tree: return a directory tree view\n- stat: return metadata for a single file or directory\n\nUse when:\n- You need to discover available URIs before reading\n- You want to inspect directory structure under memories/resources/skills\n- You need file metadata before deciding how to read it\n\nRequires: Complete viking:// URI", + args: { + uri: z + .string() + .describe( + "Complete viking:// URI to inspect (e.g., viking://user/memories/, viking://agent/memories/, viking://resources/zh/)", + ), + view: z + .enum(["list", "tree", "stat"]) + .optional() + .describe("'list' for directory listing, 'tree' for recursive tree view, 'stat' for metadata on a single URI"), + recursive: z.boolean().optional().describe("Only used with view='list'. Recursively list descendants."), + simple: z.boolean().optional().describe("Only used with view='list'. Return simpler URI-oriented output."), + }, + async execute(args, context) { + log("INFO", "membrowse", "Browsing URI", { args }) + + // Validate URI format + const validationError = validateVikingUri(args.uri, "membrowse") + if (validationError) return validationError + + try { + const view = args.view ?? "list" + const encodedUri = encodeURIComponent(args.uri) + + if (view === "stat") { + const response = await makeRequest>>(config, { + method: "GET", + endpoint: `/api/v1/fs/stat?uri=${encodedUri}`, + abortSignal: context.abort, + }) + const result = unwrapResponse(response) + return JSON.stringify({ view, item: result }, null, 2) + } + + const endpoint = view === "tree" + ? `/api/v1/fs/tree?uri=${encodedUri}` + : `/api/v1/fs/ls?uri=${encodedUri}&recursive=${args.recursive ? "true" : "false"}&simple=${args.simple ? "true" : "false"}` + const response = await makeRequest>(config, { + method: "GET", + endpoint, + abortSignal: context.abort, + }) + + const result = unwrapResponse(response) + const items = Array.isArray(result) ? result : [] + if (items.length === 0) { + return `No items found at ${args.uri}` + } + + return JSON.stringify({ view, count: items.length, items }, null, 2) + } catch (error: any) { + log("ERROR", "membrowse", "Browse failed", { error: error.message, uri: args.uri }) + return `Error: ${error.message}` + } + }, + }), + + memcommit: tool({ + description: + "Commit the current OpenCode session to OpenViking and extract persistent memories from the accumulated conversation.\n\nBy default this tool commits the OpenViking session mapped to the current OpenCode session. Use `session_id` only when you need to target a specific OpenViking session manually.\n\nUse when:\n- You want a mid-session memory extraction without ending the chat\n- You want recently discussed preferences, entities, or cases persisted immediately\n\nAutomatically extracts and stores:\n- User profile, preferences, entities, events → viking://user/memories/\n- Agent cases and patterns → viking://agent/memories/\n\nReturns background commit progress or completion details, including task_id, memories_extracted, and archived.", + args: { + session_id: z + .string() + .optional() + .describe("Optional explicit OpenViking session ID. Omit to commit the current OpenCode session's mapped OpenViking session."), + }, + async execute(args, context) { + let sessionId = args.session_id + if (!sessionId && context.sessionID) { + const mapping = sessionMap.get(context.sessionID) + if (mapping) { + sessionId = mapping.ovSessionId + } + } + + log("INFO", "memcommit", "Committing session", { + requested_session_id: args.session_id, + resolved_session_id: sessionId, + opencode_session_id: context.sessionID, + }) + + if (!sessionId) { + return "Error: No OpenViking session is associated with the current OpenCode session. Start or resume a normal OpenCode session first, or pass an explicit session_id." + } + + try { + const mapping = context.sessionID ? sessionMap.get(context.sessionID) : undefined + const resolvedMapping = mapping?.ovSessionId === sessionId ? mapping : undefined + + if (resolvedMapping) { + await flushPendingMessages( + context.sessionID ?? sessionId, + resolvedMapping, + config, + ) + } + + if (resolvedMapping?.commitInFlight) { + const task = await waitForCommitCompletion( + resolvedMapping, + context.sessionID ?? sessionId, + config, + context.abort, + ) + if (task?.status === "completed") { + return JSON.stringify( + { + message: `Memory extraction complete: ${task.result?.memories_extracted ?? 0} memories extracted`, + session_id: task.result?.session_id ?? sessionId, + status: task.status, + memories_extracted: task.result?.memories_extracted ?? 0, + archived: task.result?.archived ?? false, + task_id: task.task_id, + }, + null, + 2, + ) + } + } + + const tempMapping: SessionMapping = resolvedMapping ?? { + ovSessionId: sessionId, + createdAt: Date.now(), + capturedMessages: new Set(), + messageRoles: new Map(), + pendingMessages: new Map(), + sendingMessages: new Set(), + } + + const commitStart = await startBackgroundCommit( + tempMapping, + context.sessionID ?? sessionId, + config, + context.abort, + ) + if (!commitStart) { + throw new Error("Failed to start background commit") + } + + if (commitStart.mode === "completed") { + return JSON.stringify( + { + message: `Memory extraction complete: ${commitStart.result.memories_extracted ?? 0} memories extracted`, + session_id: commitStart.result.session_id ?? sessionId, + status: commitStart.result.status ?? "completed", + memories_extracted: commitStart.result.memories_extracted ?? 0, + archived: commitStart.result.archived ?? false, + }, + null, + 2, + ) + } + + const task = await waitForCommitCompletion( + tempMapping, + context.sessionID ?? sessionId, + config, + context.abort, + ) + + if (!task) { + return JSON.stringify( + { + message: "Commit is still processing in the background", + session_id: sessionId, + status: "accepted", + task_id: commitStart.taskId, + }, + null, + 2, + ) + } + + return JSON.stringify( + { + message: `Memory extraction complete: ${task.result?.memories_extracted ?? 0} memories extracted`, + session_id: task.result?.session_id ?? sessionId, + status: task.status, + memories_extracted: task.result?.memories_extracted ?? 0, + archived: task.result?.archived ?? false, + task_id: task.task_id, + }, + null, + 2, + ) + } catch (error: any) { + log("ERROR", "memcommit", "Commit failed", { + error: error.message, + session_id: sessionId, + }) + return `Error: ${error.message}` + } + }, + }), + + memsearch: tool( + { + description: + "Search OpenViking memories, resources, and skills through a unified interface.\n\nModes:\n- auto: choose between fast similarity search and deep context-aware search\n- fast: use simple semantic similarity search\n- deep: use intent analysis and optional session context\n\nReturns memories, resources, and skills with relevance scores and match reasons.\n\nUse when:\n- You want to find relevant memories or resources by meaning\n- You need a single search tool instead of choosing between low-level APIs\n- You want deeper retrieval for complex or ambiguous questions", + args: { + query: z.string().describe("Search query - can be natural language, a complex question, or a task description"), + target_uri: z + .string() + .optional() + .describe( + "Limit search to a specific URI prefix (e.g., viking://resources/, viking://user/memories/). Omit to search all contexts.", + ), + mode: z + .enum(["auto", "fast", "deep"]) + .optional() + .describe("Search mode. 'auto' chooses based on query complexity and session context, 'fast' forces /find, 'deep' forces /search"), + session_id: z + .string() + .optional() + .describe( + "Optional OpenViking session ID for context-aware search. If omitted in auto/deep mode, the current OpenCode session mapping will be used when available.", + ), + limit: z.number().optional().describe("Max results (default: 10)"), + score_threshold: z.number().optional().describe("Optional minimum score threshold"), + }, + async execute(args, context) { + log("INFO", "memsearch", "Executing unified search", { args }) + + // Auto-inject session_id if not provided + let sessionId = args.session_id + if (!sessionId && context.sessionID) { + const mapping = sessionMap.get(context.sessionID) + if (mapping) { + sessionId = mapping.ovSessionId + log("INFO", "memsearch", "Auto-injected session context", { + opencode_session: context.sessionID, + openviking_session: sessionId, + }) + } + } + + const mode = resolveSearchMode(args.mode, args.query, sessionId) + const requestBody: { + query: string + limit: number + target_uri?: string + session_id?: string + score_threshold?: number + } = { + query: args.query, + limit: args.limit ?? 10, + } + if (args.target_uri) requestBody.target_uri = args.target_uri + if (args.score_threshold !== undefined) requestBody.score_threshold = args.score_threshold + if (mode === "deep" && sessionId) requestBody.session_id = sessionId + + try { + const response = await makeRequest>(config, { + method: "POST", + endpoint: mode === "deep" ? "/api/v1/search/search" : "/api/v1/search/find", + body: requestBody, + abortSignal: context.abort, + }) + + const result = unwrapResponse(response) ?? { memories: [], resources: [], skills: [], total: 0 } + return formatSearchResults(result, "memsearch", args.query, { + mode, + query_plan: result.query_plan, + }) + } catch (error: any) { + log("ERROR", "memsearch", "Search failed", { error: error.message, args }) + return `Error: ${error.message}` + } + }, + }, + ), + }, + + stop: async () => { + // Flush any pending debounced save + if (saveTimer) { + clearTimeout(saveTimer) + await saveSessionMap() + } + // Stop auto-commit scheduler + stopAutoCommit() + log("INFO", "plugin", "OpenViking Memory Plugin stopped") + } + } +} + +export default OpenVikingMemoryPlugin diff --git a/examples/opencode/plugin/README.md b/examples/opencode/plugin/README.md index 0a482f4e..07e4b9f7 100644 --- a/examples/opencode/plugin/README.md +++ b/examples/opencode/plugin/README.md @@ -7,7 +7,7 @@ OpenViking plugin for [OpenCode](https://opencode.ai). Injects your indexed code Install the latest OpenViking and configure `~/.openviking/ov.conf`: ```bash -pip install openviking --upgrade --force-reinstall +pip install openviking --upgrade ``` ```json @@ -39,7 +39,7 @@ For other providers (Volcengine, Anthropic, DeepSeek, Ollama, etc.) see the [Ope Before starting OpenCode, make sure the OpenViking server is running. If it's not already started: ```bash -openviking-server --config ~/.openviking/ov.conf > /tmp/openviking.log 2>&1 & +openviking-server > /tmp/openviking.log 2>&1 & ``` ## Usage in OpenCode diff --git a/examples/opencode/plugin/index.mjs b/examples/opencode/plugin/index.mjs index a91efe1f..22db55f8 100644 --- a/examples/opencode/plugin/index.mjs +++ b/examples/opencode/plugin/index.mjs @@ -7,7 +7,6 @@ import { fileURLToPath } from "url" const execAsync = promisify(exec) const __dirname = dirname(fileURLToPath(import.meta.url)) -const OV_CONF = join(homedir(), ".openviking", "ov.conf") // ── Helpers ─────────────────────────────────────────────────────────────────── @@ -26,7 +25,7 @@ async function isHealthy() { async function startServer() { // Start in background, wait up to 30s for healthy - await run("openviking-server --config " + OV_CONF + " > /tmp/openviking.log 2>&1 &") + await run("openviking-server > /tmp/openviking.log 2>&1 &") for (let i = 0; i < 10; i++) { await new Promise((r) => setTimeout(r, 3000)) if (await isHealthy()) return true @@ -34,18 +33,25 @@ async function startServer() { return false } +let initPromise = null + +function makeToast(client) { + return (message, variant = "warning") => + client.tui.showToast({ + body: { title: "OpenViking", message, variant, duration: 8000 }, + }).catch(() => {}) +} + // ── Skill auto-install ──────────────────────────────────────────────────────── function installSkill() { const src = join(__dirname, "skills", "openviking", "SKILL.md") const dest = join(homedir(), ".config", "opencode", "skills", "openviking", "SKILL.md") - try { - if (!existsSync(dirname(dest))) mkdirSync(dirname(dest), { recursive: true }) - const content = readFileSync(src, "utf8") - if (!existsSync(dest) || readFileSync(dest, "utf8") !== content) { - writeFileSync(dest, content, "utf8") - } - } catch {} + mkdirSync(dirname(dest), { recursive: true }) + const content = readFileSync(src, "utf8") + if (!existsSync(dest) || readFileSync(dest, "utf8") !== content) { + writeFileSync(dest, content, "utf8") + } } // ── Repo context cache ──────────────────────────────────────────────────────── @@ -80,49 +86,57 @@ async function loadRepos() { // ── Init: check deps, start server if needed ───────────────────────────────── -async function init(client) { - const toast = (message, variant = "warning") => - client.tui.showToast({ - body: { title: "OpenViking", message, variant, duration: 8000 }, - }).catch(() => {}) +async function _init(client) { + const toast = makeToast(client) - // 服务已在跑,直接返回 + // server already running if (await isHealthy()) return true - // 没跑,先看是哪种情况 + // check if ov is installed try { await run("command -v ov", { timeout: 2000 }) } catch { - // command not found → 没装 - await toast("openviking 未安装,请运行: pip install openviking", "error") + await toast("openviking is not installed. Run: pip install openviking", "error") return false } - // 装了但没有配置文件 → 无法启动 - if (!existsSync(OV_CONF)) { - await toast("未找到 ~/.openviking/ov.conf,请先配置 API keys 后再启动服务", "warning") + // installed but no config file — cannot start + const ovConf = join(homedir(), ".openviking", "ov.conf") + if (!existsSync(ovConf)) { + await toast("~/.openviking/ov.conf not found. Please configure API keys before starting the server.", "warning") return false } - // 装了有配置,服务没跑 → 静默自动启动 + // installed + config exists — auto-start silently const started = await startServer() if (!started) { - await toast("openviking 服务启动失败,查看日志: /tmp/openviking.log", "error") + await toast("Failed to start openviking server. Check logs: /tmp/openviking.log", "error") return false } return true } +async function init(client) { + if (!initPromise) initPromise = _init(client).finally(() => { initPromise = null }) + return initPromise +} + // ── Plugin export ───────────────────────────────────────────────────────────── /** * @type {import('@opencode-ai/plugin').Plugin} */ export async function OpenVikingPlugin({ client }) { - installSkill() + const toast = makeToast(client) + + try { + installSkill() + } catch (e) { + await toast(`Failed to install skill: ${e.message}`, "error") + } - // 后台初始化,不阻塞 opencode 启动 + // init in background — do not block opencode startup Promise.resolve().then(async () => { const ready = await init(client) if (ready) await loadRepos() diff --git a/examples/opencode/plugin/openviking-context.ts b/examples/opencode/plugin/openviking-context.ts deleted file mode 100644 index 1b728ea7..00000000 --- a/examples/opencode/plugin/openviking-context.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { exec } from "child_process" -import { promisify } from "util" - -const execAsync = promisify(exec) - -let cachedRepos: string | null = null - -async function loadRepos(): Promise { - try { - const { stdout } = await execAsync( - "ov --output json ls viking://resources/ --abs-limit 2000", - { timeout: 8000 } - ) - const parsed = JSON.parse(stdout) - const items: Array<{ uri: string; abstract?: string }> = parsed?.result ?? [] - const repos = items - .filter((item) => item.uri?.startsWith("viking://resources/")) - .map((item) => { - const name = item.uri.replace("viking://resources/", "").replace(/\/$/, "") - return item.abstract - ? `- **${name}** (${item.uri})\n ${item.abstract}` - : `- **${name}** (${item.uri})` - }) - if (repos.length > 0) { - cachedRepos = repos.join("\n") - } - } catch { - // openviking not available — plugin is a no-op - } -} - -/** - * @type {import('@opencode-ai/plugin').Plugin} - */ -export async function OpenVikingContextPlugin() { - // Fetch repos at startup so the cache is ready before any request - await loadRepos() - - return { - // Inject repo list into every LLM request's system prompt (sync — no await) - "experimental.chat.system.transform": ( - _input: unknown, - output: { system: string[] } - ) => { - if (!cachedRepos) return - output.system.push( - `## OpenViking — Indexed Code Repositories\n\n` + - `The following repos are semantically indexed and searchable.\n` + - `When the user asks about any of these projects or their internals, ` + - `you MUST proactively call skill("openviking") before answering.\n\n` + - cachedRepos - ) - }, - - // Refresh repo list when a new session starts - "session.created": async () => { - await loadRepos() - }, - } -} diff --git a/examples/opencode/plugin/package.json b/examples/opencode/plugin/package.json index 8b9705c3..7795c1bd 100644 --- a/examples/opencode/plugin/package.json +++ b/examples/opencode/plugin/package.json @@ -1,6 +1,6 @@ { "name": "openviking-opencode", - "version": "0.3.0", + "version": "0.3.3", "description": "OpenCode plugin for OpenViking — injects indexed repo context into the AI assistant and auto-installs the openviking skill", "type": "module", "main": "index.mjs", diff --git a/examples/opencode/plugin/skills/openviking/SKILL.md b/examples/opencode/plugin/skills/openviking/SKILL.md index 6478b05e..7de853de 100644 --- a/examples/opencode/plugin/skills/openviking/SKILL.md +++ b/examples/opencode/plugin/skills/openviking/SKILL.md @@ -11,22 +11,7 @@ compatibility: opencode ## How OpenViking Organizes Data -OpenViking stores content in a virtual filesystem under the `viking://` namespace, similar to a local directory tree: - -``` -viking:// -└── resources/ - ├── fastapi/ ← repo A - │ ├── fastapi/ - │ │ ├── routing.py - │ │ └── dependencies/ - │ └── tests/ - └── requests/ ← repo B - ├── requests/ - └── tests/ -``` - -Each directory has AI-generated summaries (`abstract` / `overview`). **The key principle: narrow the URI scope to improve retrieval efficiency.** Instead of searching all repos, lock to a specific repo or subdirectory — this reduces noise and speeds up results significantly. +OpenViking stores content in a virtual filesystem under the `viking://` namespace. Each URI maps to a file or directory, e.g. `viking://resources/fastapi/routing.py`. Each directory has AI-generated summaries (`abstract` / `overview`). **The key principle: narrow the URI scope to improve retrieval efficiency.** Instead of searching all repos, lock to a specific repo or subdirectory — this reduces noise and speeds up results significantly. ## Search Commands @@ -34,21 +19,22 @@ Choose the right command based on what you're looking for: | Command | Use when | Example | |---------|----------|---------| -| `ov find` | You know the **concept** but not the exact code | "dependency injection", "rate limiting logic" | +| `ov search` | Semantic search — use for concept/intent based queries | "dependency injection", "how auth works" | | `ov grep` | You know the **exact keyword or symbol** | function name, class name, error string | | `ov glob` | You want to **enumerate files** by pattern | all `*.py` files, all test files | ```bash -# Semantic search — concept/intent based -ov find "dependency injection" --uri viking://resources/fastapi --limit 10 -ov find "how tokens are refreshed" --uri viking://resources/fastapi/fastapi/security -ov find "JWT authentication" --limit 10 # across all repos +# Semantic search +ov search "dependency injection" --uri viking://resources/fastapi --limit 10 +ov search "how tokens are refreshed" --uri viking://resources/fastapi/fastapi/security +ov search "JWT authentication" --limit 10 # across all repos +ov search "error handling" --limit 5 --threshold 0.7 # filter low-relevance results # Keyword search — exact match or regex ov grep "verify_token" --uri viking://resources/fastapi ov grep "class.*Session" --uri viking://resources/requests/requests -# File enumeration — by name pattern (--uri is required) +# File enumeration — by name pattern (always specify --uri to scope the search) ov glob "**/*.py" --uri viking://resources/fastapi ov glob "**/test_*.py" --uri viking://resources/fastapi/tests ov glob "**/*.py" --uri viking://resources/ # across all repos @@ -56,6 +42,13 @@ ov glob "**/*.py" --uri viking://resources/ # across all repos **Narrowing scope:** once you identify a relevant directory, pass it as `--uri` to restrict subsequent searches to that subtree — this is faster and more precise than searching the whole repo. +**Query formulation:** write specific, contextual queries rather than single keywords. +```bash +ov search "API" # too vague +ov search "REST API authentication with JWT tokens" # better +ov search "JWT token refresh flow" --uri viking://resources/backend # best +``` + ## Read Content ```bash @@ -75,14 +68,20 @@ ov read viking://resources/fastapi/fastapi/dependencies/utils.py --offset 100 -- ```bash ov ls viking://resources/ # list all indexed repos ov ls viking://resources/fastapi # list repo top-level contents -ov tree viking://resources/fastapi # full directory tree +ov ls viking://resources/fastapi --simple # paths only, no metadata +ov ls viking://resources/fastapi --recursive # list all files recursively +ov tree viking://resources/fastapi # full directory tree (default: 3 levels deep) +ov tree viking://resources/fastapi -L 2 # limit depth to 2 levels +ov tree viking://resources/fastapi -l 200 # truncate abstract column to 200 chars +ov tree viking://resources/fastapi -L 2 -l 200 # combined: 2 levels deep, 200-char summaries ``` +`-L` controls how many levels deep the tree expands. `-l` controls the length of the AI-generated summary per directory. Use `ov tree -L 2 -l 200` as a good starting point to understand a repo's structure before diving in. + ## Add a Repository ```bash -ov add-resource https://github.com/owner/repo --to viking://resources/ --timeout 300 -ov add-resource /path/to/project --to viking://resources/ --timeout 300 +ov add-resource https://github.com/owner/repo --to viking://resources/repo --timeout 300 ``` `--timeout` is required (seconds). Use 300 (5 min) for small repos, increase for larger ones. @@ -105,7 +104,7 @@ This permanently deletes the repo and all its indexed content. Confirm with the ## Error Handling -**`command not found: ov`** → Tell user: `pip install openviking --upgrade --force-reinstall`. Stop. +**`command not found: ov`** → Tell user: `pip install openviking --upgrade`. Stop. **`url is required` / `CLI_CONFIG` error** → Auto-create config and retry: ```bash @@ -115,7 +114,7 @@ mkdir -p ~/.openviking && echo '{"url": "http://localhost:1933"}' > ~/.openvikin **`CONNECTION_ERROR` / failed to connect:** - `~/.openviking/ov.conf` **exists** → auto-start server, wait until healthy, retry: ```bash - openviking-server --config ~/.openviking/ov.conf > /tmp/openviking.log 2>&1 & + openviking-server > /tmp/openviking.log 2>&1 & for i in $(seq 1 10); do ov health 2>/dev/null && break; sleep 3; done ``` - **Does not exist** → Tell user to configure `~/.openviking/ov.conf` first. Stop. @@ -126,5 +125,5 @@ For other issues or command details, run: ```bash ov help -ov --help # e.g. ov find --help +ov --help # e.g. ov search --help ``` diff --git a/examples/ov.conf.example b/examples/ov.conf.example index 3582f877..249c0a13 100644 --- a/examples/ov.conf.example +++ b/examples/ov.conf.example @@ -44,6 +44,16 @@ "input": "multimodal" } }, + "embedding_ollama_example": { + "_comment": "For local deployment with Ollama (no API key required):", + "dense": { + "provider": "ollama", + "model": "nomic-embed-text", + "api_base": "http://localhost:11434/v1", + "dimension": 768, + "input": "text" + } + }, "vlm": { "model": "doubao-seed-2-0-pro-260215", "api_key": "{your-api-key}", diff --git a/examples/watch_resource_example.py b/examples/watch_resource_example.py new file mode 100644 index 00000000..fdf5c31b --- /dev/null +++ b/examples/watch_resource_example.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +""" +Resource Watch Feature Example + +This example demonstrates how to use the resource watch feature in OpenViking. +The watch feature allows you to automatically re-process resources at specified +intervals. + +Key features: +- Create resources with watch enabled +- Update watch intervals (cancel then re-create) +- Cancel watch tasks +- Handle conflict errors +""" + +import asyncio +from pathlib import Path + +from openviking import AsyncOpenViking +from openviking_cli.exceptions import ConflictError + + +async def example_basic_watch(): + client = AsyncOpenViking(path="./data_watch_example") + await client.initialize() + + try: + test_file = Path("./test_resource.md") + test_file.write_text( + """# Test Resource + +## Content +This is a test resource for watch functionality. + +## Version +Version: 1.0 +""" + ) + + to_uri = "viking://resources/watched_resource" + + print("\nAdding resource with watch_interval=60.0 minutes...") + result = await client.add_resource( + path=str(test_file), + to=to_uri, + reason="Example: monitoring a document", + instruction="Check for updates and re-index", + watch_interval=60.0, + ) + + print("Resource added successfully!") + print(f" Root URI: {result['root_uri']}") + finally: + await client.close() + + +async def example_update_watch_interval(): + client = AsyncOpenViking(path="./data_watch_example") + await client.initialize() + + try: + test_file = Path("./test_resource.md") + to_uri = "viking://resources/watched_resource" + + print("\nUpdating watch interval by canceling then re-creating...") + await client.add_resource( + path=str(test_file), + to=to_uri, + watch_interval=0, + ) + await client.add_resource( + path=str(test_file), + to=to_uri, + reason="Updated: more frequent monitoring", + watch_interval=120.0, + ) + print("Watch task updated successfully!") + finally: + await client.close() + + +async def example_cancel_watch(): + client = AsyncOpenViking(path="./data_watch_example") + await client.initialize() + + try: + test_file = Path("./test_resource.md") + to_uri = "viking://resources/watched_resource" + + print("\nCancelling watch by setting interval to 0...") + await client.add_resource( + path=str(test_file), + to=to_uri, + watch_interval=0, + ) + print("Watch task cancelled successfully!") + finally: + await client.close() + + +async def example_handle_conflict(): + client = AsyncOpenViking(path="./data_watch_example") + await client.initialize() + + try: + test_file = Path("./test_resource.md") + to_uri = "viking://resources/conflict_example" + + print("\nCreating first watch task...") + await client.add_resource( + path=str(test_file), + to=to_uri, + watch_interval=30.0, + ) + print(" First watch task created successfully") + + print("\nAttempting to create second watch task for same URI...") + try: + await client.add_resource( + path=str(test_file), + to=to_uri, + watch_interval=60.0, + ) + print(" ERROR: This should not happen!") + except ConflictError as e: + print(" ConflictError caught as expected!") + print(f" Error message: {e}") + finally: + await client.close() + + +async def main(): + print("\n" + "=" * 60) + print("OpenViking Resource Watch Examples") + print("=" * 60) + + await example_basic_watch() + await example_update_watch_interval() + await example_cancel_watch() + await example_handle_conflict() + + print("\n" + "=" * 60) + print("All examples completed!") + print("=" * 60) + + +if __name__ == "__main__": + asyncio.run(main()) + diff --git a/openviking/agfs_manager.py b/openviking/agfs_manager.py index 14ed124a..9ae796f2 100644 --- a/openviking/agfs_manager.py +++ b/openviking/agfs_manager.py @@ -133,9 +133,23 @@ def _generate_config(self) -> Path: "version": "1.0.0", }, }, + # TODO(multi-node): SQLite backend is single-node only. Each AGFS instance + # gets its own isolated queue.db under its own data_path, so messages + # enqueued on node A are invisible to node B. For multi-node deployments, + # switch backend to "tidb" or "mysql" so all nodes share the same queue. + # + # Additionally, the TiDB backend currently uses immediate soft-delete on + # Dequeue (no two-phase status='processing' transition), meaning there is + # no at-least-once guarantee: a worker crash loses the in-flight message. + # The TiDB backend's Ack() and RecoverStale() are both no-ops and must be + # implemented before it can be used safely in production. "queuefs": { "enabled": True, "path": "/queue", + "config": { + "backend": "sqlite", + "db_path": str(self.data_path / "_system" / "queue" / "queue.db"), + }, }, }, } @@ -196,6 +210,7 @@ def start(self) -> None: self._check_port_available() self.vikingfs_path.mkdir(parents=True, exist_ok=True) + (self.data_path / "_system" / "queue").mkdir(parents=True, exist_ok=True) # NOTICE: should use viking://temp/ instead of self.vikingfs_path / "temp" # Create temp directory for Parser use # (self.vikingfs_path / "temp").mkdir(exist_ok=True) diff --git a/openviking/async_client.py b/openviking/async_client.py index 67dfa696..655a717e 100644 --- a/openviking/async_client.py +++ b/openviking/async_client.py @@ -13,6 +13,7 @@ from openviking.client import LocalClient, Session from openviking.service.debug_service import SystemStatus +from openviking.telemetry import TelemetryRequest from openviking_cli.client.base import BaseClient from openviking_cli.session.user_id import UserIdentifier from openviking_cli.utils import get_logger @@ -96,6 +97,11 @@ async def reset(cls) -> None: await cls._instance.close() cls._instance = None + # Also reset lock manager singleton + from openviking.storage.transaction import reset_lock_manager + + reset_lock_manager() + # ============= Session methods ============= def session(self, session_id: Optional[str] = None, must_exist: bool = False) -> Session: @@ -164,10 +170,12 @@ async def add_message( session_id=session_id, role=role, content=content, parts=parts ) - async def commit_session(self, session_id: str) -> Dict[str, Any]: + async def commit_session( + self, session_id: str, telemetry: TelemetryRequest = False + ) -> Dict[str, Any]: """Commit a session (archive and extract memories).""" await self._ensure_initialized() - return await self._client.commit_session(session_id) + return await self._client.commit_session(session_id, telemetry=telemetry) # ============= Resource methods ============= @@ -182,6 +190,8 @@ async def add_resource( timeout: float = None, build_index: bool = True, summarize: bool = False, + watch_interval: float = 0, + telemetry: TelemetryRequest = False, **kwargs, ) -> Dict[str, Any]: """ @@ -196,10 +206,10 @@ async def add_resource( parent: Target parent URI (must already exist). build_index: Whether to build vector index immediately (default: True). summarize: Whether to generate summary (default: False). + telemetry: Whether to attach operation telemetry data to the result. """ await self._ensure_initialized() - # Validate that only one of 'to' or 'parent' is set if to and parent: raise ValueError("Cannot specify both 'to' and 'parent' at the same time.") @@ -213,9 +223,15 @@ async def add_resource( timeout=timeout, build_index=build_index, summarize=summarize, + telemetry=telemetry, + watch_interval=watch_interval, **kwargs, ) + @property + def _service(self): + return self._client.service + async def wait_processed(self, timeout: float = None) -> Dict[str, Any]: """Wait for all queued processing to complete.""" await self._ensure_initialized() @@ -246,6 +262,7 @@ async def add_skill( data: Any, wait: bool = False, timeout: float = None, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add skill to OpenViking. @@ -258,6 +275,7 @@ async def add_skill( data=data, wait=wait, timeout=timeout, + telemetry=telemetry, ) # ============= Search methods ============= @@ -271,6 +289,7 @@ async def search( limit: int = 10, score_threshold: Optional[float] = None, filter: Optional[Dict] = None, + telemetry: TelemetryRequest = False, ): """ Complex search with session context. @@ -295,6 +314,7 @@ async def search( limit=limit, score_threshold=score_threshold, filter=filter, + telemetry=telemetry, ) async def find( @@ -304,6 +324,7 @@ async def find( limit: int = 10, score_threshold: Optional[float] = None, filter: Optional[Dict] = None, + telemetry: TelemetryRequest = False, ): """Semantic search""" await self._ensure_initialized() @@ -313,6 +334,7 @@ async def find( limit=limit, score_threshold=score_threshold, filter=filter, + telemetry=telemetry, ) # ============= FS methods ============= diff --git a/openviking/client/local.py b/openviking/client/local.py index 3f27cb36..0c918319 100644 --- a/openviking/client/local.py +++ b/openviking/client/local.py @@ -9,6 +9,11 @@ from openviking.server.identity import RequestContext, Role from openviking.service import OpenVikingService +from openviking.telemetry import TelemetryRequest +from openviking.telemetry.execution import ( + attach_telemetry_payload, + run_with_telemetry, +) from openviking_cli.client.base import BaseClient from openviking_cli.session.user_id import UserIdentifier from openviking_cli.utils import run_async @@ -34,7 +39,7 @@ def __init__( user=UserIdentifier.the_default_user(), ) self._user = self._service.user - self._ctx = RequestContext(user=self._user, role=Role.ROOT) + self._ctx = RequestContext(user=self._user, role=Role.USER) @property def service(self) -> OpenVikingService: @@ -62,23 +67,37 @@ async def add_resource( instruction: str = "", wait: bool = False, timeout: Optional[float] = None, + build_index: bool = True, + summarize: bool = False, + telemetry: TelemetryRequest = False, + watch_interval: float = 0, **kwargs, ) -> Dict[str, Any]: """Add resource to OpenViking.""" - # Validate that only one of 'to' or 'parent' is set if to and parent: raise ValueError("Cannot specify both 'to' and 'parent' at the same time.") - return await self._service.resources.add_resource( - path=path, - ctx=self._ctx, - to=to, - parent=parent, - reason=reason, - instruction=instruction, - wait=wait, - timeout=timeout, - **kwargs, + execution = await run_with_telemetry( + operation="resources.add_resource", + telemetry=telemetry, + fn=lambda: self._service.resources.add_resource( + path=path, + ctx=self._ctx, + to=to, + parent=parent, + reason=reason, + instruction=instruction, + wait=wait, + timeout=timeout, + build_index=build_index, + summarize=summarize, + watch_interval=watch_interval, + **kwargs, + ), + ) + return attach_telemetry_payload( + execution.result, + execution.telemetry, ) async def add_skill( @@ -86,13 +105,22 @@ async def add_skill( data: Any, wait: bool = False, timeout: Optional[float] = None, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add skill to OpenViking.""" - return await self._service.resources.add_skill( - data=data, - ctx=self._ctx, - wait=wait, - timeout=timeout, + execution = await run_with_telemetry( + operation="resources.add_skill", + telemetry=telemetry, + fn=lambda: self._service.resources.add_skill( + data=data, + ctx=self._ctx, + wait=wait, + timeout=timeout, + ), + ) + return attach_telemetry_payload( + execution.result, + execution.telemetry, ) async def wait_processed(self, timeout: Optional[float] = None) -> Dict[str, Any]: @@ -196,15 +224,24 @@ async def find( limit: int = 10, score_threshold: Optional[float] = None, filter: Optional[Dict[str, Any]] = None, + telemetry: TelemetryRequest = False, ) -> Any: """Semantic search without session context.""" - return await self._service.search.find( - query=query, - ctx=self._ctx, - target_uri=target_uri, - limit=limit, - score_threshold=score_threshold, - filter=filter, + execution = await run_with_telemetry( + operation="search.find", + telemetry=telemetry, + fn=lambda: self._service.search.find( + query=query, + ctx=self._ctx, + target_uri=target_uri, + limit=limit, + score_threshold=score_threshold, + filter=filter, + ), + ) + return attach_telemetry_payload( + execution.result, + execution.telemetry, ) async def search( @@ -215,20 +252,33 @@ async def search( limit: int = 10, score_threshold: Optional[float] = None, filter: Optional[Dict[str, Any]] = None, + telemetry: TelemetryRequest = False, ) -> Any: """Semantic search with optional session context.""" - session = None - if session_id: - session = self._service.sessions.session(self._ctx, session_id) - await session.load() - return await self._service.search.search( - query=query, - ctx=self._ctx, - target_uri=target_uri, - session=session, - limit=limit, - score_threshold=score_threshold, - filter=filter, + + async def _search(): + session = None + if session_id: + session = self._service.sessions.session(self._ctx, session_id) + await session.load() + return await self._service.search.search( + query=query, + ctx=self._ctx, + target_uri=target_uri, + session=session, + limit=limit, + score_threshold=score_threshold, + filter=filter, + ) + + execution = await run_with_telemetry( + operation="search.search", + telemetry=telemetry, + fn=_search, + ) + return attach_telemetry_payload( + execution.result, + execution.telemetry, ) async def grep(self, uri: str, pattern: str, case_insensitive: bool = False) -> Dict[str, Any]: @@ -259,6 +309,8 @@ async def unlink(self, from_uri: str, to_uri: str) -> None: async def create_session(self) -> Dict[str, Any]: """Create a new session.""" + await self._service.initialize_user_directories(self._ctx) + await self._service.initialize_agent_directories(self._ctx) session = await self._service.sessions.create(self._ctx) return { "session_id": session.session_id, @@ -282,9 +334,19 @@ async def delete_session(self, session_id: str) -> None: """Delete a session.""" await self._service.sessions.delete(session_id, self._ctx) - async def commit_session(self, session_id: str) -> Dict[str, Any]: + async def commit_session( + self, session_id: str, telemetry: TelemetryRequest = False + ) -> Dict[str, Any]: """Commit a session (archive and extract memories).""" - return await self._service.sessions.commit(session_id, self._ctx) + execution = await run_with_telemetry( + operation="session.commit", + telemetry=telemetry, + fn=lambda: self._service.sessions.commit(session_id, self._ctx), + ) + return attach_telemetry_payload( + execution.result, + execution.telemetry, + ) async def add_message( self, diff --git a/openviking/client/session.py b/openviking/client/session.py index 51ccaf23..6289deca 100644 --- a/openviking/client/session.py +++ b/openviking/client/session.py @@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional from openviking.message.part import Part +from openviking.telemetry import TelemetryRequest from openviking_cli.session.user_id import UserIdentifier if TYPE_CHECKING: @@ -57,13 +58,13 @@ async def add_message( return await self._client.add_message(self.session_id, role, parts=parts_dicts) return await self._client.add_message(self.session_id, role, content=content) - async def commit(self) -> Dict[str, Any]: + async def commit(self, telemetry: TelemetryRequest = False) -> Dict[str, Any]: """Commit the session (archive messages and extract memories). Returns: Commit result """ - return await self._client.commit_session(self.session_id) + return await self._client.commit_session(self.session_id, telemetry=telemetry) async def delete(self) -> None: """Delete the session.""" diff --git a/openviking/console/app.py b/openviking/console/app.py index ea1aba64..891d2485 100644 --- a/openviking/console/app.py +++ b/openviking/console/app.py @@ -4,6 +4,7 @@ from __future__ import annotations +import json import re from contextlib import asynccontextmanager from pathlib import Path @@ -46,6 +47,36 @@ } +def _is_json_content_type(content_type: str) -> bool: + value = (content_type or "").lower() + return "application/json" in value or "+json" in value + + +def _should_default_telemetry(upstream_path: str) -> bool: + if upstream_path in {"/api/v1/search/find", "/api/v1/resources"}: + return True + return upstream_path.startswith("/api/v1/sessions/") and upstream_path.endswith("/commit") + + +def _with_default_telemetry(request: Request, upstream_path: str, body: bytes) -> bytes: + if request.method.upper() != "POST": + return body + if not _should_default_telemetry(upstream_path): + return body + if not _is_json_content_type(request.headers.get("content-type", "")): + return body + + try: + payload = json.loads(body.decode("utf-8")) if body else {} + except (json.JSONDecodeError, UnicodeDecodeError): + return body + if not isinstance(payload, dict): + return body + + payload.setdefault("telemetry", True) + return json.dumps(payload).encode("utf-8") + + def _error_response(status_code: int, code: str, message: str, details: Optional[dict] = None): return JSONResponse( status_code=status_code, @@ -80,6 +111,7 @@ async def _forward_request(request: Request, upstream_path: str) -> Response: """Forward the incoming request to OpenViking upstream.""" client: httpx.AsyncClient = request.app.state.upstream_client body = await request.body() + body = _with_default_telemetry(request, upstream_path, body) try: upstream_response = await client.request( method=request.method, @@ -128,6 +160,39 @@ def _validate_path_param(value: str, name: str) -> Optional[JSONResponse]: return None +def _validate_fs_path(path_str: str) -> Optional[JSONResponse]: + """Validate file system path to prevent directory traversal attacks.""" + if not path_str: + # Empty path is allowed (means current directory) + return None + + # Reject absolute paths + if path_str.startswith("/") or path_str.startswith("\\"): + return _error_response( + status_code=400, + code="INVALID_PATH", + message="Absolute paths are not allowed", + ) + + # Check for Windows drive letters (C:, D:, etc.) + if len(path_str) >= 2 and path_str[1] == ":": + return _error_response( + status_code=400, + code="INVALID_PATH", + message="Absolute paths are not allowed", + ) + + # Check for parent directory traversal + if ".." in path_str: + return _error_response( + status_code=400, + code="INVALID_PATH", + message="Path traversal sequences (..) are not allowed", + ) + + return None + + def _create_proxy_router() -> APIRouter: router = APIRouter(prefix=PROXY_PREFIX, tags=["console"]) @@ -140,10 +205,18 @@ async def runtime_capabilities(request: Request): @router.get("/ov/fs/ls") async def fs_ls(request: Request): + path = request.query_params.get("path", "") + invalid = _validate_fs_path(path) + if invalid: + return invalid return await _forward_request(request, "/api/v1/fs/ls") @router.get("/ov/fs/tree") async def fs_tree(request: Request): + path = request.query_params.get("path", "") + invalid = _validate_fs_path(path) + if invalid: + return invalid return await _forward_request(request, "/api/v1/fs/tree") @router.get("/ov/fs/stat") diff --git a/openviking/console/bootstrap.py b/openviking/console/bootstrap.py index 02a9cae1..aca73112 100644 --- a/openviking/console/bootstrap.py +++ b/openviking/console/bootstrap.py @@ -40,7 +40,7 @@ def _build_parser() -> argparse.ArgumentParser: parser.add_argument( "--request-timeout-sec", type=float, - default=30.0, + default=3600.0, help="Upstream request timeout in seconds", ) parser.add_argument( diff --git a/openviking/core/building_tree.py b/openviking/core/building_tree.py index 9685a56d..43207e29 100644 --- a/openviking/core/building_tree.py +++ b/openviking/core/building_tree.py @@ -28,6 +28,7 @@ def __init__( self._contexts: List["Context"] = [] self._uri_map: Dict[str, "Context"] = {} self._root_uri: Optional[str] = None + self._candidate_uri: Optional[str] = None def add_context(self, context: "Context") -> None: """Add a context to the tree.""" diff --git a/openviking/core/context.py b/openviking/core/context.py index 94d47b1f..76308570 100644 --- a/openviking/core/context.py +++ b/openviking/core/context.py @@ -56,6 +56,7 @@ def __init__( self, uri: str, parent_uri: Optional[str] = None, + temp_uri: Optional[str] = None, is_leaf: bool = False, abstract: str = "", context_type: Optional[str] = None, @@ -78,6 +79,7 @@ def __init__( self.id = id or str(uuid4()) self.uri = uri self.parent_uri = parent_uri + self.temp_uri = temp_uri self.is_leaf = is_leaf self.abstract = abstract self.context_type = context_type or self._derive_context_type() @@ -159,6 +161,7 @@ def to_dict(self) -> Dict[str, Any]: "id": self.id, "uri": self.uri, "parent_uri": self.parent_uri, + "temp_uri": self.temp_uri, "is_leaf": self.is_leaf, "abstract": self.abstract, "context_type": self.context_type, @@ -194,6 +197,7 @@ def from_dict(cls, data: Dict[str, Any]) -> "Context": obj = cls( uri=data["uri"], parent_uri=data.get("parent_uri"), + temp_uri=data.get("temp_uri"), is_leaf=data.get("is_leaf", False), abstract=data.get("abstract", ""), context_type=data.get("context_type"), diff --git a/openviking/core/directories.py b/openviking/core/directories.py index 252fc3c6..4ca55baa 100644 --- a/openviking/core/directories.py +++ b/openviking/core/directories.py @@ -255,10 +255,10 @@ async def _ensure_directory_l0_l1_vectors( (1, defn.overview), ): existing = await self.vikingdb.get_context_by_uri( - account_id=ctx.account_id, uri=uri, level=level, limit=1, + ctx=ctx, ) if existing: continue diff --git a/openviking/eval/ragas/__init__.py b/openviking/eval/ragas/__init__.py index 03336bc7..df295210 100644 --- a/openviking/eval/ragas/__init__.py +++ b/openviking/eval/ragas/__init__.py @@ -111,8 +111,8 @@ def _create_ragas_llm_from_config() -> Optional[Any]: RAGAS LLM instance or None if VLM is not configured. """ try: - from openai import OpenAI - from ragas.llms import llm_factory + from langchain_openai import ChatOpenAI + from ragas.llms import LangchainLLMWrapper except ImportError: return None @@ -124,11 +124,12 @@ def _create_ragas_llm_from_config() -> Optional[Any]: logger.info(f"Using RAGAS LLM from environment: model={model_name}, base_url={api_base}") - client = OpenAI( + openai_model = ChatOpenAI( + model=model_name, api_key=api_key, base_url=api_base, ) - return llm_factory(model_name, client=client) + return LangchainLLMWrapper(openai_model) try: from openviking_cli.utils.config import get_openviking_config @@ -151,13 +152,13 @@ def _create_ragas_llm_from_config() -> Optional[Any]: ) return None - client = OpenAI( + model_name = vlm_config.model or "gpt-4o-mini" + openai_model = ChatOpenAI( + model=model_name, api_key=vlm_config.api_key, base_url=vlm_config.api_base, ) - - model_name = vlm_config.model or "gpt-4o-mini" - return llm_factory(model_name, client=client) + return LangchainLLMWrapper(openai_model) class RagasEvaluator(BaseEvaluator): diff --git a/openviking/models/embedder/__init__.py b/openviking/models/embedder/__init__.py index 9ce209ca..b418b809 100644 --- a/openviking/models/embedder/__init__.py +++ b/openviking/models/embedder/__init__.py @@ -12,6 +12,7 @@ - OpenAI: Dense only - Volcengine: Dense, Sparse, Hybrid - Jina AI: Dense only +- Voyage AI: Dense only """ from openviking.models.embedder.base import ( @@ -24,6 +25,7 @@ ) from openviking.models.embedder.jina_embedders import JinaDenseEmbedder from openviking.models.embedder.openai_embedders import OpenAIDenseEmbedder +from openviking.models.embedder.voyage_embedders import VoyageDenseEmbedder from openviking.models.embedder.vikingdb_embedders import ( VikingDBDenseEmbedder, VikingDBHybridEmbedder, @@ -47,6 +49,8 @@ "JinaDenseEmbedder", # OpenAI implementations "OpenAIDenseEmbedder", + # Voyage implementations + "VoyageDenseEmbedder", # Volcengine implementations "VolcengineDenseEmbedder", "VolcengineSparseEmbedder", diff --git a/openviking/models/embedder/base.py b/openviking/models/embedder/base.py index 7e7a4369..bd178df8 100644 --- a/openviking/models/embedder/base.py +++ b/openviking/models/embedder/base.py @@ -1,8 +1,17 @@ # Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. # SPDX-License-Identifier: Apache-2.0 +import logging +import math +import random +import re +import time from abc import ABC, abstractmethod from dataclasses import dataclass -from typing import Any, Dict, List, Optional +from typing import Any, Callable, Dict, List, Optional, TypeVar + +logger = logging.getLogger(__name__) + +T = TypeVar("T") def truncate_and_normalize(embedding: List[float], dimension: Optional[int]) -> List[float]: @@ -18,8 +27,6 @@ def truncate_and_normalize(embedding: List[float], dimension: Optional[int]) -> if not dimension or len(embedding) <= dimension: return embedding - import math - embedding = embedding[:dimension] norm = math.sqrt(sum(x**2 for x in embedding)) if norm > 0: @@ -61,38 +68,210 @@ class EmbedderBase(ABC): Provides unified embedding interface supporting dense, sparse, and hybrid modes. """ - def __init__(self, model_name: str, config: Optional[Dict[str, Any]] = None): + def __init__( + self, + model_name: str, + config: Optional[Dict[str, Any]] = None, + max_tokens: Optional[int] = None, + ): """Initialize embedder Args: model_name: Model name config: Configuration dict containing api_key, api_base, etc. + max_tokens: Maximum token count per embedding request, None to use default (8000) """ self.model_name = model_name self.config = config or {} + self._max_tokens = max_tokens + + @property + def max_tokens(self) -> int: + """Maximum token count per embedding request. Subclasses can override.""" + if self._max_tokens is not None: + return self._max_tokens + return 8000 + + def _estimate_tokens(self, text: str) -> int: + """Estimate token count for the given text. + + Tries tiktoken (for OpenAI models) first, falls back to a character-based + heuristic that accounts for multi-byte (CJK) characters. + + Args: + text: Input text + + Returns: + Estimated token count + """ + try: + import tiktoken + + enc = tiktoken.encoding_for_model(self.model_name) + return len(enc.encode(text)) + except Exception: + logger.info( + "tiktoken unavailable for model '%s', using character-based estimation", + self.model_name, + ) + # Use the higher of char-based and byte-based estimates so that + # CJK text (3 bytes per char in UTF-8) is not underestimated. + return max(len(text) // 3, len(text.encode("utf-8")) // 4) + + def _chunk_text(self, text: str) -> List[str]: + """Split text into chunks, each within max_tokens. + + Splitting priority: paragraphs (\\n\\n) > sentences (。.!?\\n) > fixed length. + + Args: + text: Input text + + Returns: + List of text chunks + """ + max_tok = self.max_tokens + if self._estimate_tokens(text) <= max_tok: + return [text] + + # Try paragraph split first + paragraphs = text.split("\n\n") + if len(paragraphs) > 1: + chunks = self._merge_segments(paragraphs, max_tok, "\n\n") + if all(self._estimate_tokens(c) <= max_tok for c in chunks): + return chunks + + # Try sentence split + sentences = re.split(r"(?<=[。.!?\n])", text) + sentences = [s for s in sentences if s] + if len(sentences) > 1: + chunks = self._merge_segments(sentences, max_tok, "") + if all(self._estimate_tokens(c) <= max_tok for c in chunks): + return chunks + + # Fixed-length split as last resort + return self._fixed_length_split(text, max_tok) + + def _merge_segments(self, segments: List[str], max_tok: int, separator: str) -> List[str]: + """Merge small segments into chunks that fit within max_tokens.""" + chunks: List[str] = [] + current = "" + for seg in segments: + candidate = (current + separator + seg) if current else seg + if self._estimate_tokens(candidate) <= max_tok: + current = candidate + else: + if current: + chunks.append(current) + # If a single segment exceeds max_tok, it will be handled later + current = seg + if current: + chunks.append(current) + return chunks + + def _fixed_length_split(self, text: str, max_tok: int) -> List[str]: + """Split text into fixed-length chunks based on estimated char-per-token ratio.""" + # Estimate chars per token + total_tokens = self._estimate_tokens(text) + chars_per_token = len(text) / max(total_tokens, 1) + chunk_size = max(int(max_tok * chars_per_token * 0.9), 100) + + chunks: List[str] = [] + start = 0 + while start < len(text): + end = start + chunk_size + if end < len(text): + # Try to break at a whitespace boundary + boundary = text.rfind(" ", start, end) + if boundary > start: + end = boundary + 1 + chunks.append(text[start:end]) + start = end + return chunks + + def _chunk_and_embed(self, text: str, is_query: bool = False) -> EmbedResult: + """Chunk text if it exceeds max_tokens, embed each chunk, and merge results. + + For text within limits, delegates to _embed_single directly. + For oversized text, splits into chunks, embeds each, then computes a + token-weighted average of dense vectors with L2 normalization. + + Args: + text: Input text + is_query: Flag to indicate if this is a query embedding + + Returns: + EmbedResult with merged embedding + """ + estimated = self._estimate_tokens(text) + if estimated <= self.max_tokens: + return self._embed_single(text, is_query=is_query) + + chunks = self._chunk_text(text) + logger.debug( + "Chunking text: original ~%d tokens -> %d chunks", + estimated, + len(chunks), + ) + + results: List[EmbedResult] = [] + weights: List[int] = [] + for chunk in chunks: + result = self._embed_single(chunk, is_query=is_query) + results.append(result) + weights.append(self._estimate_tokens(chunk)) + + # Merge dense vectors via weighted average + L2 normalization + merged_dense = None + if results and results[0].dense_vector is not None: + dim = len(results[0].dense_vector) + total_weight = sum(weights) + merged = [0.0] * dim + for result, w in zip(results, weights): + if result.dense_vector: + for i in range(dim): + merged[i] += result.dense_vector[i] * w + if total_weight > 0: + merged = [v / total_weight for v in merged] + # L2 normalization + norm = math.sqrt(sum(v * v for v in merged)) + if norm > 0: + merged = [v / norm for v in merged] + merged_dense = merged + + return EmbedResult(dense_vector=merged_dense) + + def _embed_single(self, text: str, is_query: bool = False) -> EmbedResult: + """Embed a single text without chunking logic. Defaults to self.embed(). + + Subclasses that override embed() with chunking should also override + this method to provide the raw embedding call. + """ + return self.embed(text, is_query=is_query) @abstractmethod - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Embed single text Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Embedding result containing dense_vector, sparse_vector, or both """ pass - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: """Batch embedding (default implementation loops, subclasses can override for optimization) Args: texts: List of texts + is_query: Flag to indicate if these are query embeddings Returns: List[EmbedResult]: List of embedding results """ - return [self.embed(text) for text in texts] + return [self.embed(text, is_query=is_query) for text in texts] def close(self): """Release resources, subclasses can override as needed""" @@ -123,11 +302,12 @@ class DenseEmbedderBase(EmbedderBase): """ @abstractmethod - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Perform dense embedding on text Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Result containing only dense_vector @@ -155,11 +335,12 @@ class SparseEmbedderBase(EmbedderBase): """ @abstractmethod - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Perform sparse embedding on text Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Result containing only sparse_vector @@ -183,11 +364,12 @@ class HybridEmbedderBase(EmbedderBase): """ @abstractmethod - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Perform hybrid embedding on text Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Result containing both dense_vector and sparse_vector @@ -230,19 +412,19 @@ def __init__(self, dense_embedder: DenseEmbedderBase, sparse_embedder: SparseEmb self.dense_embedder = dense_embedder self.sparse_embedder = sparse_embedder - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Combine results from both embedders""" - dense_res = self.dense_embedder.embed(text) - sparse_res = self.sparse_embedder.embed(text) + dense_res = self.dense_embedder.embed(text, is_query=is_query) + sparse_res = self.sparse_embedder.embed(text, is_query=is_query) return EmbedResult( dense_vector=dense_res.dense_vector, sparse_vector=sparse_res.sparse_vector ) - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: """Combine batch results""" - dense_results = self.dense_embedder.embed_batch(texts) - sparse_results = self.sparse_embedder.embed_batch(texts) + dense_results = self.dense_embedder.embed_batch(texts, is_query=is_query) + sparse_results = self.sparse_embedder.embed_batch(texts, is_query=is_query) return [ EmbedResult(dense_vector=d.dense_vector, sparse_vector=s.sparse_vector) @@ -255,3 +437,68 @@ def get_dimension(self) -> int: def close(self): self.dense_embedder.close() self.sparse_embedder.close() + + +def exponential_backoff_retry( + func: Callable[[], T], + max_wait: float = 10.0, + base_delay: float = 0.5, + max_delay: float = 2.0, + jitter: bool = True, + is_retryable: Optional[Callable[[Exception], bool]] = None, + logger=None, +) -> T: + """ + 指数退避重试函数 + + Args: + func: 要执行的函数 + max_wait: 最大总等待时间(秒) + base_delay: 基础延迟时间(秒) + max_delay: 单次最大延迟时间(秒) + jitter: 是否添加随机抖动 + is_retryable: 判断异常是否可重试的函数 + logger: 日志记录器 + + Returns: + 函数执行结果 + + Raises: + 最后一次尝试的异常 + """ + start_time = time.time() + attempt = 0 + + while True: + try: + return func() + except Exception as e: + attempt += 1 + elapsed = time.time() - start_time + + if elapsed >= max_wait: + if logger: + logger.error( + f"Exceeded max wait time ({max_wait}s) after {attempt} attempts, giving up" + ) + raise + + if is_retryable and not is_retryable(e): + if logger: + logger.error(f"Non-retryable error after {attempt} attempts: {e}") + raise + + delay = min(base_delay * (2 ** (attempt - 1)), max_delay) + + if jitter: + delay = delay * (0.5 + random.random()) + + remaining_time = max_wait - elapsed + delay = min(delay, remaining_time) + + if logger: + logger.info( + f"Retry attempt {attempt}, waiting {delay:.2f}s before next try (elapsed: {elapsed:.2f}s)" + ) + + time.sleep(delay) diff --git a/openviking/models/embedder/jina_embedders.py b/openviking/models/embedder/jina_embedders.py index 12f45e4d..3ab3fade 100644 --- a/openviking/models/embedder/jina_embedders.py +++ b/openviking/models/embedder/jina_embedders.py @@ -22,18 +22,32 @@ class JinaDenseEmbedder(DenseEmbedderBase): """Jina AI Dense Embedder Implementation Uses Jina AI embedding API via OpenAI-compatible client. - Supports task-specific embeddings and Matryoshka dimension reduction. + Supports task-specific embeddings (non-symmetric) and Matryoshka dimension reduction. + + Jina models are non-symmetric by default and require the 'task' parameter to distinguish + between query and document embeddings. This is different from official OpenAI models, + which are symmetric and do not support the input_type parameter. Example: - >>> embedder = JinaDenseEmbedder( + >>> # Query embedding + >>> query_embedder = JinaDenseEmbedder( ... model_name="jina-embeddings-v5-text-small", ... api_key="jina_xxx", ... dimension=512, - ... task="retrieval.query" + ... context="query" ... ) - >>> result = embedder.embed("Hello world") - >>> print(len(result.dense_vector)) + >>> query_vector = query_embedder.embed("search query") + >>> print(len(query_vector.dense_vector)) 512 + + >>> # Document embedding + >>> doc_embedder = JinaDenseEmbedder( + ... model_name="jina-embeddings-v5-text-small", + ... api_key="jina_xxx", + ... dimension=512, + ... context="document" + ... ) + >>> doc_vector = doc_embedder.embed("document content") """ def __init__( @@ -42,9 +56,11 @@ def __init__( api_key: Optional[str] = None, api_base: Optional[str] = None, dimension: Optional[int] = None, - task: Optional[str] = None, + query_param: Optional[str] = "retrieval.query", + document_param: Optional[str] = "retrieval.passage", late_chunking: Optional[bool] = None, config: Optional[Dict[str, Any]] = None, + task: Optional[str] = None, ): """Initialize Jina AI Dense Embedder @@ -53,9 +69,11 @@ def __init__( api_key: API key, required api_base: API base URL, defaults to https://api.jina.ai/v1 dimension: Dimension for Matryoshka reduction, optional - task: Task type for task-specific embeddings, optional. - Valid values: retrieval.query, retrieval.passage, - text-matching, classification, separation + query_param: Task value for query-side embeddings. Defaults to 'retrieval.query'. + Override for models with different task naming conventions. + document_param: Task value for document-side embeddings. Defaults to + 'retrieval.passage'. Override for models with different task + naming conventions. late_chunking: Enable late chunking via extra_body, optional config: Additional configuration dict @@ -67,7 +85,8 @@ def __init__( self.api_key = api_key self.api_base = api_base or "https://api.jina.ai/v1" self.dimension = dimension - self.task = task + self.query_param = query_param + self.document_param = document_param self.late_chunking = late_chunking if not self.api_key: @@ -88,20 +107,27 @@ def __init__( ) self._dimension = dimension if dimension is not None else max_dim - def _build_extra_body(self) -> Optional[Dict[str, Any]]: + def _build_extra_body(self, is_query: bool = False) -> Optional[Dict[str, Any]]: """Build extra_body dict for Jina-specific parameters""" extra_body = {} - if self.task is not None: - extra_body["task"] = self.task + task = None + if is_query and self.query_param is not None: + task = self.query_param + elif not is_query and self.document_param is not None: + task = self.document_param + + if task is not None: + extra_body["task"] = task if self.late_chunking is not None: extra_body["late_chunking"] = self.late_chunking return extra_body if extra_body else None - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Perform dense embedding on text Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Result containing only dense_vector @@ -114,7 +140,7 @@ def embed(self, text: str) -> EmbedResult: if self.dimension: kwargs["dimensions"] = self.dimension - extra_body = self._build_extra_body() + extra_body = self._build_extra_body(is_query=is_query) if extra_body: kwargs["extra_body"] = extra_body @@ -127,11 +153,12 @@ def embed(self, text: str) -> EmbedResult: except Exception as e: raise RuntimeError(f"Embedding failed: {str(e)}") from e - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: """Batch embedding (Jina native support) Args: texts: List of texts + is_query: Flag to indicate if these are query embeddings Returns: List[EmbedResult]: List of embedding results @@ -147,7 +174,7 @@ def embed_batch(self, texts: List[str]) -> List[EmbedResult]: if self.dimension: kwargs["dimensions"] = self.dimension - extra_body = self._build_extra_body() + extra_body = self._build_extra_body(is_query=is_query) if extra_body: kwargs["extra_body"] = extra_body diff --git a/openviking/models/embedder/openai_embedders.py b/openviking/models/embedder/openai_embedders.py index 61c5c998..2924b98d 100644 --- a/openviking/models/embedder/openai_embedders.py +++ b/openviking/models/embedder/openai_embedders.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 """OpenAI Embedder Implementation""" +import logging from typing import Any, Dict, List, Optional import openai @@ -12,14 +13,23 @@ HybridEmbedderBase, SparseEmbedderBase, ) +from openviking.telemetry import get_current_telemetry + +logger = logging.getLogger(__name__) class OpenAIDenseEmbedder(DenseEmbedderBase): - """OpenAI Dense Embedder Implementation + """OpenAI-Compatible Dense Embedder Implementation + + Supports OpenAI embedding models (e.g., text-embedding-3-small, text-embedding-3-large) + and OpenAI-compatible third-party models that support non-symmetric embeddings. - Supports OpenAI embedding models such as text-embedding-3-small, text-embedding-3-large, etc. + Note: Official OpenAI models are symmetric and do not support the input_type parameter. + Non-symmetric mode (context='query'/'document') is only supported by OpenAI-compatible + third-party models (e.g., BGE-M3, Jina, Cohere, etc.) that implement the input_type parameter. Example: + >>> # Symmetric mode (official OpenAI models) >>> embedder = OpenAIDenseEmbedder( ... model_name="text-embedding-3-small", ... api_key="sk-xxx", @@ -28,6 +38,27 @@ class OpenAIDenseEmbedder(DenseEmbedderBase): >>> result = embedder.embed("Hello world") >>> print(len(result.dense_vector)) 1536 + + >>> # Non-symmetric mode (OpenAI-compatible third-party models) + >>> embedder = OpenAIDenseEmbedder( + ... model_name="bge-m3", + ... api_key="your-api-key", + ... api_base="https://your-api-endpoint.com/v1", + ... query_param="query", + ... document_param="passage" + ... ) + >>> query_vector = embedder.embed("search query", is_query=True) + >>> doc_vector = embedder.embed("document text", is_query=False) + + >>> # Multiple parameters with key=value format + >>> advanced_embedder = OpenAIDenseEmbedder( + ... model_name="custom-model", + ... api_key="your-api-key", + ... api_base="https://your-api-endpoint.com/v1", + ... query_param="input_type=query,task=search,domain=finance", + ... document_param="input_type=passage,task=index,domain=finance" + ... ) + >>> advanced_vector = advanced_embedder.embed("financial query", is_query=True) """ def __init__( @@ -36,54 +67,189 @@ def __init__( api_key: Optional[str] = None, api_base: Optional[str] = None, dimension: Optional[int] = None, + query_param: Optional[str] = None, + document_param: Optional[str] = None, config: Optional[Dict[str, Any]] = None, + max_tokens: Optional[int] = None, + extra_headers: Optional[Dict[str, str]] = None, + input_type: Optional[str] = None, ): - """Initialize OpenAI Dense Embedder + """Initialize OpenAI-Compatible Dense Embedder Args: - model_name: OpenAI model name, defaults to text-embedding-3-small + model_name: Model name. For official OpenAI models (e.g., text-embedding-3-small), + use symmetric mode (query_param=None, document_param=None). + For OpenAI-compatible third-party models (e.g., BGE-M3, Jina, Cohere), use + non-symmetric mode with query_param/document_param. api_key: API key, if None will read from env vars (OPENVIKING_EMBEDDING_API_KEY or OPENAI_API_KEY) - api_base: API base URL, optional + api_base: API base URL, optional. Required for third-party OpenAI-compatible APIs. dimension: Dimension (if model supports), optional + query_param: Parameter for query-side embeddings. Supports simple values (e.g., 'query') + or key=value format (e.g., 'input_type=query,task=search'). Defaults to None. + Setting this (or document_param) activates non-symmetric mode. + Only supported by OpenAI-compatible third-party models. + document_param: Parameter for document-side embeddings. Supports simple values (e.g., 'passage') + or key=value format (e.g., 'input_type=passage,task=index'). Defaults to None. + Setting this (or query_param) activates non-symmetric mode. + Only supported by OpenAI-compatible third-party models. config: Additional configuration dict + max_tokens: Maximum token count per embedding request, None to use default (8000) + extra_headers: Extra HTTP headers to include in API requests (e.g., for OpenRouter: + {'HTTP-Referer': 'https://your-site.com', 'X-Title': 'Your App'}) Raises: ValueError: If api_key is not provided and env vars are not set + + Note: + Official OpenAI models (e.g., text-embedding-3-small, text-embedding-3-large) are + symmetric and do not support the input_type parameter. Non-symmetric mode is only + supported by OpenAI-compatible third-party models (e.g., BGE-M3, Jina, Cohere) that + implement the input_type parameter. """ - super().__init__(model_name, config) + super().__init__(model_name, config, max_tokens=max_tokens) self.api_key = api_key self.api_base = api_base self.dimension = dimension + self.query_param = query_param + self.document_param = document_param - if not self.api_key: + # Allow missing api_key when api_base is set (e.g. local OpenAI-compatible servers) + if not self.api_key and not self.api_base: raise ValueError("api_key is required") # Initialize OpenAI client - client_kwargs = {"api_key": self.api_key} + # Use a placeholder api_key when not provided (for local OpenAI-compatible servers) + client_kwargs = {"api_key": self.api_key or "no-key"} if self.api_base: client_kwargs["base_url"] = self.api_base + # 透传自定义请求头(如 OpenRouter 要求的 HTTP-Referer / X-Title) + if extra_headers: + client_kwargs["default_headers"] = extra_headers self.client = openai.OpenAI(**client_kwargs) + # Initialize tiktoken encoder + self._tiktoken_enc = None + try: + import tiktoken + + self._tiktoken_enc = tiktoken.encoding_for_model(model_name) + except Exception: + logger.info( + "tiktoken unavailable for model '%s', will use character-based estimation", + model_name, + ) + # Auto-detect dimension self._dimension = dimension if self._dimension is None: self._dimension = self._detect_dimension() + @property + def max_tokens(self) -> int: + """OpenAI embedding models have 8192 token limit; use 8000 for safety buffer. + + Can be overridden via the max_tokens constructor parameter. + """ + if self._max_tokens is not None: + return self._max_tokens + return 8000 + + def _estimate_tokens(self, text: str) -> int: + """Estimate tokens using tiktoken if available, fallback to len(text) // 3.""" + if self._tiktoken_enc is not None: + return len(self._tiktoken_enc.encode(text)) + return len(text) // 3 + def _detect_dimension(self) -> int: """Detect dimension by making an actual API call""" try: - result = self.embed("test") + result = self._embed_single("test", is_query=False) return len(result.dense_vector) if result.dense_vector else 1536 except Exception: # Use default value, text-embedding-3-small defaults to 1536 return 1536 - def embed(self, text: str) -> EmbedResult: - """Perform dense embedding on text + def _update_telemetry_token_usage(self, response) -> None: + usage = getattr(response, "usage", None) + if not usage: + return + + def _usage_value(key: str, default: int = 0) -> int: + if isinstance(usage, dict): + return int(usage.get(key, default) or default) + return int(getattr(usage, key, default) or default) + + prompt_tokens = _usage_value("prompt_tokens", 0) + total_tokens = _usage_value("total_tokens", prompt_tokens) + output_tokens = max(total_tokens - prompt_tokens, 0) + get_current_telemetry().add_token_usage_by_source( + "embedding", + prompt_tokens, + output_tokens, + ) + + def _parse_param_string(self, param: Optional[str]) -> Dict[str, str]: + """Parse parameter string to dictionary for key=value format + + Args: + param: Parameter string (e.g., "input_type=query,task=search") + + Returns: + Dictionary of parsed parameters + """ + if not param: + return {} + + result = {} + + # Split by comma for multiple parameters + parts = [p.strip() for p in param.split(",")] + + for part in parts: + if "=" in part: + key, value = part.split("=", 1) + result[key.strip()] = value.strip() + + return result + + def _build_extra_body(self, is_query: bool = False) -> Optional[Dict[str, Any]]: + """Build extra_body dict for OpenAI-compatible parameters + + Args: + is_query: Flag to indicate if this is for query embeddings + + Returns: + Dict containing input_type and other parameters if non-symmetric mode is active. + Supports key=value format for multiple parameters (e.g., "input_type=query,task=search"). + Only supported by OpenAI-compatible third-party models. + """ + extra_body = {} + + # Determine which parameter to use based on is_query flag + active_param = None + if is_query and self.query_param is not None: + active_param = self.query_param + elif not is_query and self.document_param is not None: + active_param = self.document_param + + if active_param: + if "=" in active_param: + # Parse key=value format (e.g., "input_type=query,task=search") + parsed = self._parse_param_string(active_param) + extra_body.update(parsed) + else: + # Simple format (e.g., "query" -> {"input_type": "query"}) + extra_body["input_type"] = active_param + + return extra_body if extra_body else None + + def _embed_single(self, text: str, is_query: bool = False) -> EmbedResult: + """Perform raw embedding without chunking logic. Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Result containing only dense_vector @@ -92,11 +258,14 @@ def embed(self, text: str) -> EmbedResult: RuntimeError: When API call fails """ try: - kwargs = {"input": text, "model": self.model_name} - if self.dimension: - kwargs["dimensions"] = self.dimension + kwargs: Dict[str, Any] = {"input": text, "model": self.model_name} + + extra_body = self._build_extra_body(is_query=is_query) + if extra_body: + kwargs["extra_body"] = extra_body response = self.client.embeddings.create(**kwargs) + self._update_telemetry_token_usage(response) vector = response.data[0].embedding return EmbedResult(dense_vector=vector) @@ -105,11 +274,35 @@ def embed(self, text: str) -> EmbedResult: except Exception as e: raise RuntimeError(f"Embedding failed: {str(e)}") from e - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: - """Batch embedding (OpenAI native support) + def embed(self, text: str, is_query: bool = False) -> EmbedResult: + """Embed single text, with automatic chunking for oversized input. + + Args: + text: Input text + is_query: Flag to indicate if this is a query embedding + + Returns: + EmbedResult: Result containing only dense_vector + + Raises: + RuntimeError: When API call fails + """ + if not text: + return self._embed_single(text, is_query=is_query) + + if self._estimate_tokens(text) > self.max_tokens: + return self._chunk_and_embed(text, is_query=is_query) + return self._embed_single(text, is_query=is_query) + + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: + """Batch embedding with automatic chunking for oversized inputs. + + Short texts are batched together via the OpenAI API for efficiency. + Oversized texts are individually chunked and embedded. Args: texts: List of texts + is_query: Flag to indicate if these are query embeddings Returns: List[EmbedResult]: List of embedding results @@ -120,18 +313,35 @@ def embed_batch(self, texts: List[str]) -> List[EmbedResult]: if not texts: return [] - try: - kwargs = {"input": texts, "model": self.model_name} - if self.dimension: - kwargs["dimensions"] = self.dimension + results: List[Optional[EmbedResult]] = [None] * len(texts) + short_indices: List[int] = [] + short_texts: List[str] = [] - response = self.client.embeddings.create(**kwargs) + for i, text in enumerate(texts): + if text and self._estimate_tokens(text) > self.max_tokens: + results[i] = self._chunk_and_embed(text, is_query=is_query) + else: + short_indices.append(i) + short_texts.append(text) - return [EmbedResult(dense_vector=item.embedding) for item in response.data] - except openai.APIError as e: - raise RuntimeError(f"OpenAI API error: {e.message}") from e - except Exception as e: - raise RuntimeError(f"Batch embedding failed: {str(e)}") from e + if short_texts: + try: + kwargs: Dict[str, Any] = {"input": short_texts, "model": self.model_name} + + extra_body = self._build_extra_body(is_query=is_query) + if extra_body: + kwargs["extra_body"] = extra_body + + response = self.client.embeddings.create(**kwargs) + self._update_telemetry_token_usage(response) + for idx, item in zip(short_indices, response.data): + results[idx] = EmbedResult(dense_vector=item.embedding) + except openai.APIError as e: + raise RuntimeError(f"OpenAI API error: {e.message}") from e + except Exception as e: + raise RuntimeError(f"Batch embedding failed: {str(e)}") from e + + return results # type: ignore[return-value] def get_dimension(self) -> int: """Get embedding dimension @@ -154,7 +364,7 @@ def __init__(self, *args, **kwargs): "Consider using VolcengineSparseEmbedder or other providers." ) - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: raise NotImplementedError() @@ -170,7 +380,7 @@ def __init__(self, *args, **kwargs): "Consider using VolcengineHybridEmbedder or other providers." ) - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: raise NotImplementedError() def get_dimension(self) -> int: diff --git a/openviking/models/embedder/vikingdb_embedders.py b/openviking/models/embedder/vikingdb_embedders.py index 74336600..d28aac49 100644 --- a/openviking/models/embedder/vikingdb_embedders.py +++ b/openviking/models/embedder/vikingdb_embedders.py @@ -123,7 +123,7 @@ def __init__( self.embedding_type = embedding_type self.dense_model = {"name": model_name, "version": model_version, "dim": dimension} - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: results = self._call_api([text], dense_model=self.dense_model) if not results: return EmbedResult(dense_vector=[]) @@ -135,7 +135,7 @@ def embed(self, text: str) -> EmbedResult: return EmbedResult(dense_vector=dense_vector) - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: if not texts: return [] raw_results = self._call_api(texts, dense_model=self.dense_model) @@ -173,7 +173,7 @@ def __init__( "version": model_version, } - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: results = self._call_api([text], sparse_model=self.sparse_model) if not results: return EmbedResult(sparse_vector={}) @@ -185,7 +185,7 @@ def embed(self, text: str) -> EmbedResult: return EmbedResult(sparse_vector=sparse_vector) - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: if not texts: return [] raw_results = self._call_api(texts, sparse_model=self.sparse_model) @@ -223,7 +223,7 @@ def __init__( "version": model_version, } - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: results = self._call_api( [text], dense_model=self.dense_model, sparse_model=self.sparse_model ) @@ -241,7 +241,7 @@ def embed(self, text: str) -> EmbedResult: return EmbedResult(dense_vector=dense_vector, sparse_vector=sparse_vector) - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: if not texts: return [] raw_results = self._call_api( diff --git a/openviking/models/embedder/volcengine_embedders.py b/openviking/models/embedder/volcengine_embedders.py index aa22169b..c2384ec8 100644 --- a/openviking/models/embedder/volcengine_embedders.py +++ b/openviking/models/embedder/volcengine_embedders.py @@ -11,11 +11,29 @@ EmbedResult, HybridEmbedderBase, SparseEmbedderBase, + exponential_backoff_retry, truncate_and_normalize, ) +from openviking.telemetry import get_current_telemetry from openviking_cli.utils.logger import default_logger as logger +def is_429_error(exception: Exception) -> bool: + """ + 判断异常是否为 429 限流错误 + + Args: + exception: 要检查的异常 + + Returns: + 如果是 429 错误则返回 True,否则返回 False + """ + exception_str = str(exception) + return ( + "429" in exception_str or "TooManyRequests" in exception_str or "RateLimit" in exception_str + ) + + def process_sparse_embedding(sparse_data: Any) -> Dict[str, float]: """Process sparse embedding data from SDK response""" if not sparse_data: @@ -90,7 +108,10 @@ def __init__( raise ValueError("api_key is required") # Initialize Volcengine client - self.client = volcenginesdkarkruntime.Ark(api_key=self.api_key, base_url=self.api_base) + ark_kwargs = {"api_key": self.api_key} + if self.api_base: + ark_kwargs["base_url"] = self.api_base + self.client = volcenginesdkarkruntime.Ark(**ark_kwargs) # Auto-detect dimension self._dimension = dimension @@ -105,11 +126,31 @@ def _detect_dimension(self) -> int: except Exception: return 2048 # Default dimension - def embed(self, text: str) -> EmbedResult: + def _update_telemetry_token_usage(self, response) -> None: + usage = getattr(response, "usage", None) + if not usage: + return + + def _usage_value(key: str, default: int = 0) -> int: + if isinstance(usage, dict): + return int(usage.get(key, default) or default) + return int(getattr(usage, key, default) or default) + + prompt_tokens = _usage_value("prompt_tokens", 0) + total_tokens = _usage_value("total_tokens", prompt_tokens) + output_tokens = max(total_tokens - prompt_tokens, 0) + get_current_telemetry().add_token_usage_by_source( + "embedding", + prompt_tokens, + output_tokens, + ) + + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Perform dense embedding on text Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Result containing dense_vector @@ -117,28 +158,43 @@ def embed(self, text: str) -> EmbedResult: Raises: RuntimeError: When API call fails """ - try: + + def _embed_call(): if self.input_type == "multimodal": # Use multimodal embeddings API response = self.client.multimodal_embeddings.create( input=[{"type": "text", "text": text}], model=self.model_name ) + self._update_telemetry_token_usage(response) vector = response.data.embedding else: # Use text embeddings API response = self.client.embeddings.create(input=text, model=self.model_name) + self._update_telemetry_token_usage(response) vector = response.data[0].embedding vector = truncate_and_normalize(vector, self.dimension) return EmbedResult(dense_vector=vector) + + try: + return exponential_backoff_retry( + _embed_call, + max_wait=10.0, + base_delay=0.5, + max_delay=2.0, + jitter=True, + is_retryable=is_429_error, + logger=logger, + ) except Exception as e: raise RuntimeError(f"Volcengine embedding failed: {str(e)}") from e - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: """Batch embedding Args: texts: List of texts + is_query: Flag to indicate if these are query embeddings Returns: List[EmbedResult]: List of embedding results @@ -155,9 +211,11 @@ def embed_batch(self, texts: List[str]) -> List[EmbedResult]: response = self.client.multimodal_embeddings.create( input=multimodal_inputs, model=self.model_name ) + self._update_telemetry_token_usage(response) data = response.data else: response = self.client.embeddings.create(input=texts, model=self.model_name) + self._update_telemetry_token_usage(response) data = response.data return [ @@ -206,13 +264,17 @@ def __init__( if not self.api_key: raise ValueError("api_key is required") - self.client = volcenginesdkarkruntime.Ark(api_key=self.api_key, base_url=self.api_base) + ark_kwargs = {"api_key": self.api_key} + if self.api_base: + ark_kwargs["base_url"] = self.api_base + self.client = volcenginesdkarkruntime.Ark(**ark_kwargs) - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Perform sparse embedding on text Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Result containing sparse_vector @@ -220,24 +282,37 @@ def embed(self, text: str) -> EmbedResult: Raises: RuntimeError: When API call fails """ - try: + + def _embed_call(): # Must use multimodal endpoint for sparse response = self.client.multimodal_embeddings.create( input=[{"type": "text", "text": text}], model=self.model_name, sparse_embedding={"type": "enabled"}, ) - item = response.data[0] + item = response.data sparse_vector = getattr(item, "sparse_embedding", None) return EmbedResult(sparse_vector=process_sparse_embedding(sparse_vector)) + + try: + return exponential_backoff_retry( + _embed_call, + max_wait=10.0, + base_delay=0.5, + max_delay=2.0, + jitter=True, + is_retryable=is_429_error, + logger=logger, + ) except Exception as e: raise RuntimeError(f"Volcengine sparse embedding failed: {str(e)}") from e - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: """Batch sparse embedding Args: texts: List of texts + is_query: Flag to indicate if these are query embeddings Returns: List[EmbedResult]: List of embedding results @@ -247,18 +322,7 @@ def embed_batch(self, texts: List[str]) -> List[EmbedResult]: """ if not texts: return [] - try: - multimodal_inputs = [{"type": "text", "text": text} for text in texts] - response = self.client.multimodal_embeddings.create( - input=multimodal_inputs, model=self.model_name, sparse_embedding={"type": "enabled"} - ) - results = [] - for item in response.data: - sparse_vector = getattr(item, "sparse_embedding", None) - results.append(EmbedResult(sparse_vector=process_sparse_embedding(sparse_vector))) - return results - except Exception as e: - raise RuntimeError(f"Volcengine batch sparse embedding failed: {str(e)}") from e + return [self.embed(text) for text in texts] class VolcengineHybridEmbedder(HybridEmbedderBase): @@ -299,14 +363,18 @@ def __init__( if not self.api_key: raise ValueError("api_key is required") - self.client = volcenginesdkarkruntime.Ark(api_key=self.api_key, base_url=self.api_base) + ark_kwargs = {"api_key": self.api_key} + if self.api_base: + ark_kwargs["base_url"] = self.api_base + self.client = volcenginesdkarkruntime.Ark(**ark_kwargs) self._dimension = dimension or 2048 - def embed(self, text: str) -> EmbedResult: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: """Perform hybrid embedding on text Args: text: Input text + is_query: Flag to indicate if this is a query embedding Returns: EmbedResult: Result containing both dense_vector and sparse_vector @@ -314,7 +382,8 @@ def embed(self, text: str) -> EmbedResult: Raises: RuntimeError: When API call fails """ - try: + + def _embed_call(): # Always use multimodal for hybrid to get both response = self.client.multimodal_embeddings.create( @@ -329,14 +398,26 @@ def embed(self, text: str) -> EmbedResult: return EmbedResult( dense_vector=dense_vector, sparse_vector=process_sparse_embedding(sparse_vector) ) + + try: + return exponential_backoff_retry( + _embed_call, + max_wait=10.0, + base_delay=0.5, + max_delay=2.0, + jitter=True, + is_retryable=is_429_error, + logger=logger, + ) except Exception as e: raise RuntimeError(f"Volcengine hybrid embedding failed: {str(e)}") from e - def embed_batch(self, texts: List[str]) -> List[EmbedResult]: + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: """Batch hybrid embedding Args: texts: List of texts + is_query: Flag to indicate if these are query embeddings Returns: List[EmbedResult]: List of embedding results @@ -346,24 +427,7 @@ def embed_batch(self, texts: List[str]) -> List[EmbedResult]: """ if not texts: return [] - try: - multimodal_inputs = [{"type": "text", "text": text} for text in texts] - response = self.client.multimodal_embeddings.create( - input=multimodal_inputs, model=self.model_name, sparse_embedding={"type": "enabled"} - ) - results = [] - for item in response.data: - dense_vector = truncate_and_normalize(item.embedding, self.dimension) - sparse_vector = getattr(item, "sparse_embedding", None) - results.append( - EmbedResult( - dense_vector=dense_vector, - sparse_vector=process_sparse_embedding(sparse_vector), - ) - ) - return results - except Exception as e: - raise RuntimeError(f"Volcengine batch hybrid embedding failed: {str(e)}") from e + return [self.embed(text, is_query=is_query) for text in texts] def get_dimension(self) -> int: return self._dimension diff --git a/openviking/models/embedder/voyage_embedders.py b/openviking/models/embedder/voyage_embedders.py new file mode 100644 index 00000000..e866f0a1 --- /dev/null +++ b/openviking/models/embedder/voyage_embedders.py @@ -0,0 +1,118 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Voyage AI dense embedder implementation.""" + +from typing import Any, Dict, List, Optional + +import openai + +from openviking.models.embedder.base import DenseEmbedderBase, EmbedResult + +VOYAGE_MODEL_DIMENSIONS = { + "voyage-3": 1024, + "voyage-3-large": 1024, + "voyage-3.5": 1024, + "voyage-3.5-lite": 1024, + "voyage-4": 1024, + "voyage-4-lite": 1024, + "voyage-4-large": 1024, + "voyage-code-3": 1024, + "voyage-context-3": 1024, + "voyage-finance-2": 1024, + "voyage-law-2": 1024, +} + +VOYAGE_MODEL_ALLOWED_DIMENSIONS = { + "voyage-3": {256, 512, 1024, 2048}, + "voyage-3-large": {256, 512, 1024, 2048}, + "voyage-3.5": {256, 512, 1024, 2048}, + "voyage-3.5-lite": {256, 512, 1024, 2048}, + "voyage-4": {256, 512, 1024, 2048}, + "voyage-4-lite": {256, 512, 1024, 2048}, + "voyage-4-large": {256, 512, 1024, 2048}, + "voyage-code-3": {256, 512, 1024, 2048}, +} + + +def get_voyage_model_default_dimension(model_name: Optional[str]) -> int: + """Get the default output dimension for a Voyage text embedding model.""" + if not model_name: + return 1024 + return VOYAGE_MODEL_DIMENSIONS.get(model_name.lower(), 1024) + + +class VoyageDenseEmbedder(DenseEmbedderBase): + """Voyage AI dense embedder. + + Voyage uses an OpenAI-compatible embeddings endpoint, but dimension + control is sent via ``output_dimension`` in ``extra_body``. + """ + + def __init__( + self, + model_name: str = "voyage-4-lite", + api_key: Optional[str] = None, + api_base: Optional[str] = None, + dimension: Optional[int] = None, + config: Optional[Dict[str, Any]] = None, + ): + super().__init__(model_name, config) + + self.api_key = api_key + self.api_base = api_base or "https://api.voyageai.com/v1" + self.dimension = dimension + + if not self.api_key: + raise ValueError("api_key is required") + + normalized_model_name = model_name.lower() + supported_dimensions = VOYAGE_MODEL_ALLOWED_DIMENSIONS.get(normalized_model_name) + if supported_dimensions and dimension is not None and dimension not in supported_dimensions: + supported = ", ".join(str(value) for value in sorted(supported_dimensions)) + raise ValueError( + f"Requested dimension {dimension} is not supported for model '{model_name}'. " + f"Supported dimensions: {supported}." + ) + + self.client = openai.OpenAI( + api_key=self.api_key, + base_url=self.api_base, + ) + + self._dimension = dimension or get_voyage_model_default_dimension(normalized_model_name) + + def embed(self, text: str, is_query: bool = False) -> EmbedResult: + """Perform dense embedding on text.""" + try: + kwargs: Dict[str, Any] = {"input": text, "model": self.model_name} + if self.dimension is not None: + kwargs["extra_body"] = {"output_dimension": self.dimension} + + response = self.client.embeddings.create(**kwargs) + vector = response.data[0].embedding + return EmbedResult(dense_vector=vector) + except openai.APIError as e: + raise RuntimeError(f"Voyage API error: {e.message}") from e + except Exception as e: + raise RuntimeError(f"Embedding failed: {str(e)}") from e + + def embed_batch(self, texts: List[str], is_query: bool = False) -> List[EmbedResult]: + """Batch embedding.""" + if not texts: + return [] + + try: + kwargs: Dict[str, Any] = {"input": texts, "model": self.model_name} + if self.dimension is not None: + kwargs["extra_body"] = {"output_dimension": self.dimension} + + response = self.client.embeddings.create(**kwargs) + return [EmbedResult(dense_vector=item.embedding) for item in response.data] + except openai.APIError as e: + raise RuntimeError(f"Voyage API error: {e.message}") from e + except Exception as e: + raise RuntimeError(f"Batch embedding failed: {str(e)}") from e + + def get_dimension(self) -> int: + """Get embedding dimension.""" + return self._dimension diff --git a/openviking/models/vlm/backends/litellm_vlm.py b/openviking/models/vlm/backends/litellm_vlm.py index 7a951d73..eb3bffa9 100644 --- a/openviking/models/vlm/backends/litellm_vlm.py +++ b/openviking/models/vlm/backends/litellm_vlm.py @@ -199,6 +199,8 @@ def _build_kwargs(self, model: str, messages: list) -> dict[str, Any]: "messages": messages, "temperature": self.temperature, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens if self.api_key: kwargs["api_key"] = self.api_key @@ -224,7 +226,7 @@ def get_completion(self, prompt: str, thinking: bool = False) -> str: response = completion(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") async def get_completion_async( self, prompt: str, thinking: bool = False, max_retries: int = 0 @@ -239,7 +241,7 @@ async def get_completion_async( try: response = await acompletion(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") except Exception as e: last_error = e if attempt < max_retries: @@ -268,7 +270,7 @@ def get_vision_completion( response = completion(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") async def get_vision_completion_async( self, @@ -289,7 +291,7 @@ async def get_vision_completion_async( response = await acompletion(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") def _update_token_usage_from_response(self, response) -> None: """Update token usage from response.""" diff --git a/openviking/models/vlm/backends/openai_vlm.py b/openviking/models/vlm/backends/openai_vlm.py index de59b8dc..d1f6d05d 100644 --- a/openviking/models/vlm/backends/openai_vlm.py +++ b/openviking/models/vlm/backends/openai_vlm.py @@ -29,7 +29,10 @@ def get_client(self): import openai except ImportError: raise ImportError("Please install openai: pip install openai") - self._sync_client = openai.OpenAI(api_key=self.api_key, base_url=self.api_base) + client_kwargs = {"api_key": self.api_key, "base_url": self.api_base} + if self.extra_headers: + client_kwargs["default_headers"] = self.extra_headers + self._sync_client = openai.OpenAI(**client_kwargs) return self._sync_client def get_async_client(self): @@ -39,7 +42,10 @@ def get_async_client(self): import openai except ImportError: raise ImportError("Please install openai: pip install openai") - self._async_client = openai.AsyncOpenAI(api_key=self.api_key, base_url=self.api_base) + client_kwargs = {"api_key": self.api_key, "base_url": self.api_base} + if self.extra_headers: + client_kwargs["default_headers"] = self.extra_headers + self._async_client = openai.AsyncOpenAI(**client_kwargs) return self._async_client def _update_token_usage_from_response(self, response): @@ -62,10 +68,12 @@ def get_completion(self, prompt: str, thinking: bool = False) -> str: "messages": [{"role": "user", "content": prompt}], "temperature": self.temperature, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens response = client.chat.completions.create(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") async def get_completion_async( self, prompt: str, thinking: bool = False, max_retries: int = 0 @@ -77,13 +85,15 @@ async def get_completion_async( "messages": [{"role": "user", "content": prompt}], "temperature": self.temperature, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens last_error = None for attempt in range(max_retries + 1): try: response = await client.chat.completions.create(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") except Exception as e: last_error = e if attempt < max_retries: @@ -165,10 +175,12 @@ def get_vision_completion( "messages": [{"role": "user", "content": content}], "temperature": self.temperature, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens response = client.chat.completions.create(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") async def get_vision_completion_async( self, @@ -189,7 +201,9 @@ async def get_vision_completion_async( "messages": [{"role": "user", "content": content}], "temperature": self.temperature, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens response = await client.chat.completions.create(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") diff --git a/openviking/models/vlm/backends/volcengine_vlm.py b/openviking/models/vlm/backends/volcengine_vlm.py index 985025ca..eedbff83 100644 --- a/openviking/models/vlm/backends/volcengine_vlm.py +++ b/openviking/models/vlm/backends/volcengine_vlm.py @@ -68,10 +68,12 @@ def get_completion(self, prompt: str, thinking: bool = False) -> str: "temperature": self.temperature, "thinking": {"type": "disabled" if not thinking else "enabled"}, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens response = client.chat.completions.create(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") async def get_completion_async( self, prompt: str, thinking: bool = False, max_retries: int = 0 @@ -84,13 +86,15 @@ async def get_completion_async( "temperature": self.temperature, "thinking": {"type": "disabled" if not thinking else "enabled"}, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens last_error = None for attempt in range(max_retries + 1): try: response = await client.chat.completions.create(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") except Exception as e: last_error = e if attempt < max_retries: @@ -235,10 +239,12 @@ def get_vision_completion( "temperature": self.temperature, "thinking": {"type": "disabled" if not thinking else "enabled"}, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens response = client.chat.completions.create(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") async def get_vision_completion_async( self, @@ -260,7 +266,9 @@ async def get_vision_completion_async( "temperature": self.temperature, "thinking": {"type": "disabled" if not thinking else "enabled"}, } + if self.max_tokens is not None: + kwargs["max_tokens"] = self.max_tokens response = await client.chat.completions.create(**kwargs) self._update_token_usage_from_response(response) - return response.choices[0].message.content or "" + return self._clean_response(response.choices[0].message.content or "") diff --git a/openviking/models/vlm/base.py b/openviking/models/vlm/base.py index 4b602f78..64c3d5cf 100644 --- a/openviking/models/vlm/base.py +++ b/openviking/models/vlm/base.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 """VLM base interface and abstract classes""" +import re from abc import ABC, abstractmethod from pathlib import Path from typing import Any, Dict, List, Union @@ -10,6 +11,8 @@ from .token_usage import TokenUsageTracker +_THINK_TAG_RE = re.compile(r"[\s\S]*?") + class VLMBase(ABC): """VLM base abstract class""" @@ -22,6 +25,8 @@ def __init__(self, config: Dict[str, Any]): self.api_base = config.get("api_base") self.temperature = config.get("temperature", 0.0) self.max_retries = config.get("max_retries", 2) + self.max_tokens = config.get("max_tokens") + self.extra_headers = config.get("extra_headers") # Token usage tracking self._token_tracker = TokenUsageTracker() @@ -58,6 +63,10 @@ async def get_vision_completion_async( """Get vision completion asynchronously""" pass + def _clean_response(self, content: str) -> str: + """Strip reasoning tags (e.g. ``...``) from model output.""" + return _THINK_TAG_RE.sub("", content).strip() + def is_available(self) -> bool: """Check if available""" return self.api_key is not None or self.api_base is not None @@ -80,6 +89,14 @@ def update_token_usage( prompt_tokens=prompt_tokens, completion_tokens=completion_tokens, ) + # Operation-level telemetry aggregation (no-op when telemetry is disabled). + try: + from openviking.telemetry import get_current_telemetry + + get_current_telemetry().add_token_usage(prompt_tokens, completion_tokens) + except Exception: + # Telemetry must never break model inference. + pass def get_token_usage(self) -> Dict[str, Any]: """Get token usage diff --git a/openviking/parse/directory_scan.py b/openviking/parse/directory_scan.py index bec7f7fa..4b854071 100644 --- a/openviking/parse/directory_scan.py +++ b/openviking/parse/directory_scan.py @@ -242,7 +242,9 @@ def scan_directory( sub = dir_path / d skip, reason = _should_skip_directory(sub, root, ignore_dirs_set) if skip: - result.skipped.append(f"{sub.relative_to(root)} ({reason})") + skipped_path = str(sub.relative_to(root)) + skipped_path = _normalize_rel_path(skipped_path) + result.skipped.append(f"{skipped_path} ({reason})") else: kept.append(d) dir_names[:] = kept @@ -269,7 +271,7 @@ def scan_directory( classification = _classify_file(file_path, effective_registry) classified = ClassifiedFile( - path=file_path, rel_path=rel_path, classification=classification + path=file_path, rel_path=rel_path_norm, classification=classification ) if classification == CLASS_PROCESSABLE: result.processable.append(classified) diff --git a/openviking/parse/parsers/constants.py b/openviking/parse/parsers/constants.py index 311e545a..174df57b 100644 --- a/openviking/parse/parsers/constants.py +++ b/openviking/parse/parsers/constants.py @@ -191,6 +191,7 @@ ".texi", ".texinfo", ".wiki", + ".conf", } # File type constants for consistent return values diff --git a/openviking/parse/parsers/excel.py b/openviking/parse/parsers/excel.py index 086dcc1c..2da44ce3 100644 --- a/openviking/parse/parsers/excel.py +++ b/openviking/parse/parsers/excel.py @@ -51,9 +51,13 @@ async def parse(self, source: Union[str, Path], instruction: str = "", **kwargs) path = Path(source) if path.exists(): - import openpyxl + # Use xlrd for legacy .xls, openpyxl for .xlsx/.xlsm + if path.suffix.lower() == ".xls": + markdown_content = self._convert_xls_to_markdown(path) + else: + import openpyxl - markdown_content = self._convert_to_markdown(path, openpyxl) + markdown_content = self._convert_to_markdown(path, openpyxl) result = await self._md_parser.parse_content( markdown_content, source_path=str(path), instruction=instruction, **kwargs ) @@ -61,7 +65,7 @@ async def parse(self, source: Union[str, Path], instruction: str = "", **kwargs) result = await self._md_parser.parse_content( str(source), instruction=instruction, **kwargs ) - result.source_format = "xlsx" + result.source_format = path.suffix.lstrip(".") if path.exists() else "xlsx" result.parser_name = "ExcelParser" return result @@ -74,6 +78,91 @@ async def parse_content( result.parser_name = "ExcelParser" return result + def _convert_xls_to_markdown(self, path: Path) -> str: + """Convert legacy .xls spreadsheet to Markdown using xlrd.""" + import xlrd + + # formatting_info=True enables xlrd to detect date cells via XL_CELL_DATE + # instead of reporting them as XL_CELL_NUMBER with raw float serials + wb = xlrd.open_workbook(str(path), formatting_info=True, on_demand=True) + try: + return self._build_xls_markdown(wb, path, xlrd) + finally: + wb.release_resources() + + def _build_xls_markdown(self, wb, path: Path, xlrd) -> str: + """Build markdown from xlrd workbook.""" + markdown_parts = [] + markdown_parts.append(f"# {path.stem}") + markdown_parts.append(f"**Sheets:** {wb.nsheets}") + + for sheet_idx in range(wb.nsheets): + sheet = wb.sheet_by_index(sheet_idx) + parts = [f"## Sheet: {sheet.name}"] + + if sheet.nrows == 0 or sheet.ncols == 0: + parts.append("*Empty sheet*") + markdown_parts.append("\n\n".join(parts)) + continue + + parts.append(f"**Dimensions:** {sheet.nrows} rows × {sheet.ncols} columns") + + rows_to_process = sheet.nrows + if self.max_rows_per_sheet > 0: + rows_to_process = min(sheet.nrows, self.max_rows_per_sheet) + + rows = [] + for row_idx in range(rows_to_process): + row_data = [] + for col_idx in range(sheet.ncols): + row_data.append(self._format_xls_cell(sheet.cell(row_idx, col_idx), wb, xlrd)) + rows.append(row_data) + + if rows: + from openviking.parse.base import format_table_to_markdown + + parts.append(format_table_to_markdown(rows, has_header=True)) + + if self.max_rows_per_sheet > 0 and sheet.nrows > self.max_rows_per_sheet: + parts.append( + f"\n*... {sheet.nrows - self.max_rows_per_sheet} more rows truncated ...*" + ) + + markdown_parts.append("\n\n".join(parts)) + + return "\n\n".join(markdown_parts) + + @staticmethod + def _format_xls_cell(cell, wb, xlrd) -> str: + """Format a single xlrd cell value with proper type handling.""" + if cell.ctype == xlrd.XL_CELL_EMPTY or cell.ctype == xlrd.XL_CELL_BLANK: + return "" + if cell.ctype == xlrd.XL_CELL_DATE: + try: + dt = xlrd.xldate_as_tuple(cell.value, wb.datemode) + # Include time component if non-zero + if dt[3] or dt[4] or dt[5]: + return f"{dt[0]:04d}-{dt[1]:02d}-{dt[2]:02d} {dt[3]:02d}:{dt[4]:02d}:{dt[5]:02d}" + return f"{dt[0]:04d}-{dt[1]:02d}-{dt[2]:02d}" + except Exception: + return str(cell.value) + if cell.ctype == xlrd.XL_CELL_BOOLEAN: + return "TRUE" if cell.value else "FALSE" + if cell.ctype == xlrd.XL_CELL_ERROR: + # xlrd error code map + error_map = { + 0x00: "#NULL!", 0x07: "#DIV/0!", 0x0F: "#VALUE!", + 0x17: "#REF!", 0x1D: "#NAME?", 0x24: "#NUM!", 0x2A: "#N/A", + } + return error_map.get(cell.value, f"#ERR({cell.value})") + if cell.ctype == xlrd.XL_CELL_NUMBER: + # Display integers without trailing .0 + if cell.value == int(cell.value): + return str(int(cell.value)) + return str(cell.value) + # XL_CELL_TEXT or fallback + return str(cell.value) if cell.value is not None else "" + def _convert_to_markdown(self, path: Path, openpyxl) -> str: """Convert Excel spreadsheet to Markdown string.""" wb = openpyxl.load_workbook(path, data_only=True) diff --git a/openviking/parse/parsers/html.py b/openviking/parse/parsers/html.py index 48ae4fa7..deaf0a86 100644 --- a/openviking/parse/parsers/html.py +++ b/openviking/parse/parsers/html.py @@ -18,7 +18,7 @@ from enum import Enum from pathlib import Path from typing import Any, Dict, List, Optional, Tuple, Union -from urllib.parse import urlparse +from urllib.parse import unquote, urlparse from openviking.parse.base import ( NodeType, @@ -28,6 +28,7 @@ lazy_import, ) from openviking.parse.parsers.base_parser import BaseParser +from openviking.parse.parsers.constants import CODE_EXTENSIONS from openviking_cli.utils.config import get_openviking_config @@ -53,7 +54,10 @@ class URLTypeDetector: """ # Extension to URL type mapping + # CODE_EXTENSIONS spread comes first so explicit entries below override + # (e.g., .html/.htm -> DOWNLOAD_HTML instead of DOWNLOAD_TXT) EXTENSION_MAP = { + **dict.fromkeys(CODE_EXTENSIONS, URLType.DOWNLOAD_TXT), ".pdf": URLType.DOWNLOAD_PDF, ".md": URLType.DOWNLOAD_MD, ".markdown": URLType.DOWNLOAD_MD, @@ -345,6 +349,24 @@ async def _parse_webpage( warnings=[f"Failed to fetch webpage: {e}"], ) + @staticmethod + def _extract_filename_from_url(url: str) -> str: + """ + Extract and URL-decode the original filename from a URL. + + Args: + url: URL to extract filename from + + Returns: + Decoded filename (e.g., "schemas.py" from ".../schemas.py") + Falls back to "download" if no filename can be extracted. + """ + parsed = urlparse(url) + # URL-decode path to handle encoded characters (e.g., %E7%99%BE -> Chinese chars) + decoded_path = unquote(parsed.path) + basename = Path(decoded_path).name + return basename if basename else "download" + async def _handle_download_link( self, url: str, file_type: str, start_time: float, meta: Dict[str, Any], **kwargs ) -> ParseResult: @@ -365,22 +387,30 @@ async def _handle_download_link( # Download to temporary file temp_path = await self._download_file(url) + # Extract original filename from URL for use as source_path, + # so parsers use it instead of the temp file name. + original_filename = self._extract_filename_from_url(url) + # Get appropriate parser if file_type == "pdf": from openviking.parse.parsers.pdf import PDFParser parser = PDFParser() - result = await parser.parse(temp_path) + result = await parser.parse(temp_path, resource_name=Path(original_filename).stem) elif file_type == "markdown": from openviking.parse.parsers.markdown import MarkdownParser parser = MarkdownParser() - result = await parser.parse(temp_path) + content = Path(temp_path).read_text(encoding="utf-8") + result = await parser.parse_content( + content, source_path=original_filename, **kwargs + ) elif file_type == "text": - from openviking.parse.parsers.text import TextParser - - parser = TextParser() - result = await parser.parse(temp_path) + # For text/code files, preserve the original filename and extension. + # Read the downloaded content and save it with the original name + # instead of routing through TextParser->MarkdownParser which + # would rename it to .md and split it into sections. + result = await self._save_downloaded_text(temp_path, original_filename, start_time) elif file_type == "html": # Parse downloaded HTML locally return await self._parse_local_file(Path(temp_path), start_time, **kwargs) @@ -510,6 +540,57 @@ def _convert_to_raw_url(self, url: str) -> str: return url + async def _save_downloaded_text( + self, temp_path: str, original_filename: str, start_time: float + ) -> ParseResult: + """ + Save a downloaded text/code file preserving its original filename and extension. + + Instead of routing through TextParser -> MarkdownParser (which renames to .md + and splits into sections), this saves the file directly into a VikingFS temp + directory with its original name. + + Args: + temp_path: Path to the downloaded temporary file + original_filename: Original filename from URL (e.g., "schemas.py") + start_time: Parse start timestamp + + Returns: + ParseResult with temp_dir_path set + """ + from openviking.storage.viking_fs import get_viking_fs + + content = Path(temp_path).read_text(encoding="utf-8") + doc_name = Path(original_filename).stem + + viking_fs = get_viking_fs() + temp_uri = viking_fs.create_temp_uri() + await viking_fs.mkdir(temp_uri) + + # Create document root directory (TreeBuilder expects exactly one dir) + root_dir = f"{temp_uri}/{doc_name}" + await viking_fs.mkdir(root_dir) + + # Save with original filename (preserving extension) + file_uri = f"{root_dir}/{original_filename}" + await viking_fs.write_file(file_uri, content) + + root = ResourceNode( + type=NodeType.ROOT, + title=doc_name, + level=0, + ) + + result = create_parse_result( + root=root, + source_path=original_filename, + source_format="text", + parser_name="HTMLParser", + parse_time=time.time() - start_time, + ) + result.temp_dir_path = temp_uri + return result + async def _download_file(self, url: str) -> str: """ Download file from URL to temporary location. @@ -527,9 +608,10 @@ async def _download_file(self, url: str) -> str: url = self._convert_to_raw_url(url) - # Determine file extension from URL + # Determine file extension from URL (decode first to handle encoded paths) parsed = urlparse(url) - ext = Path(parsed.path).suffix or ".tmp" + decoded_path = unquote(parsed.path) + ext = Path(decoded_path).suffix or ".tmp" # Create temp file temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=ext) diff --git a/openviking/parse/parsers/legacy_doc.py b/openviking/parse/parsers/legacy_doc.py new file mode 100644 index 00000000..95b770ae --- /dev/null +++ b/openviking/parse/parsers/legacy_doc.py @@ -0,0 +1,355 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +""" +Legacy Word document (.doc) parser for OpenViking. + +Extracts text from OLE2 compound binary .doc files using olefile, +then delegates to MarkdownParser for tree structure creation. +""" + +import struct +from pathlib import Path +from typing import List, Optional, Union + +from openviking.parse.base import ParseResult +from openviking.parse.parsers.base_parser import BaseParser +from openviking_cli.utils.config.parser_config import ParserConfig +from openviking_cli.utils.logger import get_logger + +logger = get_logger(__name__) + + + # Max stream size to read (50MB) — prevents DoS from crafted files +_MAX_STREAM_SIZE = 50 * 1024 * 1024 +# Max character count sanity cap for ccpText +_MAX_CCP_TEXT = 10_000_000 + + +class LegacyDocParser(BaseParser): + """ + Legacy .doc (OLE2 binary) parser. + + Extracts text content from Word 97-2003 (.doc) files using olefile + to read the WordDocument and table streams, then delegates to + MarkdownParser for tree structure. + """ + + def __init__(self, config: Optional[ParserConfig] = None): + from openviking.parse.parsers.markdown import MarkdownParser + + self._md_parser = MarkdownParser(config=config) + self.config = config or ParserConfig() + + @property + def supported_extensions(self) -> List[str]: + return [".doc"] + + async def parse(self, source: Union[str, Path], instruction: str = "", **kwargs) -> ParseResult: + """Parse legacy .doc file.""" + path = Path(source) + + if path.exists(): + text = self._extract_text(path) + result = await self._md_parser.parse_content( + text, source_path=str(path), instruction=instruction, **kwargs + ) + else: + result = await self._md_parser.parse_content( + str(source), instruction=instruction, **kwargs + ) + result.source_format = "doc" + result.parser_name = "LegacyDocParser" + return result + + async def parse_content( + self, content: str, source_path: Optional[str] = None, instruction: str = "", **kwargs + ) -> ParseResult: + """Parse content string — delegates to MarkdownParser.""" + result = await self._md_parser.parse_content( + content, source_path, instruction=instruction, **kwargs + ) + result.source_format = "doc" + result.parser_name = "LegacyDocParser" + return result + + def _extract_text(self, path: Path) -> str: + """ + Extract text from a legacy .doc OLE2 file. + + Reads the WordDocument stream and uses the FIB (File Information Block) + to locate text in the document body. Falls back to raw byte scanning + if structured extraction fails. + """ + import olefile + + try: + ole = olefile.OleFileIO(str(path)) + except Exception as e: + logger.warning(f"Failed to open .doc as OLE file: {e}") + return self._fallback_extract(path) + + try: + return self._extract_from_ole(ole) + except Exception as e: + logger.warning(f"Structured OLE extraction failed, using fallback: {e}") + return self._fallback_extract(path) + finally: + ole.close() + + @staticmethod + def _read_ole_stream(ole, stream_name: str) -> bytes: + """Read an OLE stream with size cap to prevent DoS.""" + stream = ole.openstream(stream_name) + data = stream.read(_MAX_STREAM_SIZE + 1) + if len(data) > _MAX_STREAM_SIZE: + raise ValueError(f"OLE stream '{stream_name}' exceeds {_MAX_STREAM_SIZE} bytes") + return data + + def _extract_from_ole(self, ole) -> str: + """ + Extract text from OLE streams using the Word Binary File Format. + + Reads the FIB to determine if text is stored as UTF-16 or compressed + (CP1252), then extracts the document body text from the appropriate + stream (WordDocument or table stream). + """ + if not ole.exists("WordDocument"): + raise ValueError("No WordDocument stream found") + + word_doc = self._read_ole_stream(ole, "WordDocument") + + # Minimum FIB size: need at least 0x01A8 bytes for Word 97+ FIB fields + if len(word_doc) < 0x01A8: + raise ValueError(f"WordDocument stream too small ({len(word_doc)} bytes)") + + # Check FIB version (nFib at offset 0x0002) — require Word 97+ (0x00C1+) + nfib = struct.unpack_from(" len(table_data): + return self._simple_text_extract(word_doc, ccp_text) + + return self._extract_via_clx( + word_doc, table_data, fc_clx, lcb_clx, ccp_text + ) + + def _simple_text_extract(self, word_doc: bytes, ccp_text: int) -> str: + """ + Simple text extraction using FIB text offset. + + The main document text starts at offset 0x0800 in the WordDocument stream + for most Word 97+ files. Tries UTF-16LE first; falls back to CP1252 if + the stream is too small for UTF-16. + """ + text_start = 0x0800 # Standard text start offset + + if text_start >= len(word_doc): + raise ValueError("WordDocument stream too small for text extraction") + + # Try UTF-16LE first (2 bytes per char) + if ccp_text * 2 + text_start <= len(word_doc): + end = text_start + ccp_text * 2 + raw = word_doc[text_start:end] + text = raw.decode("utf-16-le", errors="replace") + # Sanity: if mostly printable, it's likely correct + if sum(1 for c in text[:200] if c.isprintable() or c in "\n\r\t") > len(text[:200]) * 0.5: + return self._clean_word_text(text) + + # Fall back to CP1252 single-byte + end = min(text_start + ccp_text, len(word_doc)) + raw = word_doc[text_start:end] + return self._clean_word_text(self._decode_cp1252(raw)) + + def _extract_via_clx( + self, + word_doc: bytes, + table_data: bytes, + fc_clx: int, + lcb_clx: int, + ccp_text: int, + ) -> str: + """ + Extract text using the Clx (piece table) structure. + + The Clx contains a PiecePLC that maps character positions to file offsets, + allowing reconstruction of the document text even when pieces are scattered. + """ + clx = table_data[fc_clx : fc_clx + lcb_clx] + pos = 0 + text_parts = [] + chars_extracted = 0 + + # Skip any Grpprl (type 0x01) entries in the Clx + while pos < len(clx) and clx[pos] == 0x01: + if pos + 3 > len(clx): + break + cb = struct.unpack_from("= len(clx) or clx[pos] != 0x02: + return self._simple_text_extract(word_doc, ccp_text) + + pos += 1 # skip type byte + if pos + 4 > len(clx): + return self._simple_text_extract(word_doc, ccp_text) + + lcb_pcd = struct.unpack_from(" len(clx): + return self._simple_text_extract(word_doc, ccp_text) + + # Calculate number of pieces: (lcb_pcd - 4) / (4 + 8) per piece, + # but CPs are (n+1)*4 bytes + n*8 bytes = lcb_pcd + # So: 4*(n+1) + 8*n = lcb_pcd → 12n + 4 = lcb_pcd → n = (lcb_pcd - 4) / 12 + n_pieces = (lcb_pcd - 4) // 12 + if n_pieces <= 0: + return self._simple_text_extract(word_doc, ccp_text) + + # Read character positions (n+1 values) + cps = [] + for i in range(n_pieces + 1): + offset = pcd_start + i * 4 + if offset + 4 > len(clx): + break + cps.append(struct.unpack_from("= ccp_text: + break + + pcd_offset = pcd_array_start + i * 8 + if pcd_offset + 8 > len(clx): + break + + # PCD: 2 bytes flags, 4 bytes fc, 2 bytes prm + fc_value = struct.unpack_from(" {len(word_doc)})") + else: + # UTF-16LE + byte_offset = fc_real + byte_end = byte_offset + piece_char_count * 2 + if byte_end <= len(word_doc): + raw = word_doc[byte_offset:byte_end] + text_parts.append(raw.decode("utf-16-le", errors="replace")) + else: + logger.warning(f"Piece {i} extends beyond stream ({byte_end} > {len(word_doc)})") + + chars_extracted += piece_char_count + + result = self._clean_word_text("".join(text_parts)) + if not result.strip(): + return self._simple_text_extract(word_doc, ccp_text) + return result + + @staticmethod + def _decode_cp1252(data: bytes) -> str: + """Decode CP1252 bytes to string.""" + return data.decode("cp1252", errors="replace") + + @staticmethod + def _clean_word_text(text: str) -> str: + """Normalize Word control characters to readable equivalents.""" + text = text.replace("\r\n", "\n").replace("\r", "\n") + # \x07 = cell/row end, \x0B = soft line break, \x0C = section break + text = text.replace("\x07", "\t").replace("\x0B", "\n").replace("\x0C", "\n\n") + return text + + def _fallback_extract(self, path: Path) -> str: + """ + Last-resort text extraction by scanning raw bytes for readable text runs. + + Tries UTF-16LE decoding first (common in .doc), then falls back to CP1252. + """ + # Cap read size to prevent DoS from large files + with open(path, "rb") as f: + raw = f.read(_MAX_STREAM_SIZE) + + # Try to find UTF-16LE text (every other byte is often 0x00 for ASCII) + try: + decoded = raw.decode("utf-16-le", errors="ignore") + # Filter to printable text runs + lines = [] + current = [] + for ch in decoded: + if ch.isprintable() or ch in "\n\t": + current.append(ch) + else: + if len(current) > 3: + lines.append("".join(current)) + current = [] + if current and len(current) > 3: + lines.append("".join(current)) + text = "\n".join(lines) + if len(text) > 50: + return text + except Exception: + pass + + # Fall back to CP1252 + text = raw.decode("cp1252", errors="replace") + lines = [] + current = [] + for ch in text: + if ch.isprintable() or ch in "\n\t": + current.append(ch) + else: + if len(current) > 3: + lines.append("".join(current)) + current = [] + if current and len(current) > 3: + lines.append("".join(current)) + return "\n".join(lines) diff --git a/openviking/parse/parsers/upload_utils.py b/openviking/parse/parsers/upload_utils.py index 50c80ed0..d1870173 100644 --- a/openviking/parse/parsers/upload_utils.py +++ b/openviking/parse/parsers/upload_utils.py @@ -40,6 +40,7 @@ "NEWS", "NOTICE", "TODO", + "BUILD", } diff --git a/openviking/parse/registry.py b/openviking/parse/registry.py index 77a90395..4c6b3e4a 100644 --- a/openviking/parse/registry.py +++ b/openviking/parse/registry.py @@ -26,6 +26,7 @@ from openviking.parse.parsers.text import TextParser # Import markitdown-inspired parsers +from openviking.parse.parsers.legacy_doc import LegacyDocParser from openviking.parse.parsers.word import WordParser from openviking.parse.parsers.zip_parser import ZipParser @@ -62,6 +63,7 @@ def __init__(self, register_optional: bool = True): # Register markitdown-inspired parsers (built-in) self.register("word", WordParser()) + self.register("legacy_doc", LegacyDocParser()) self.register("powerpoint", PowerPointParser()) self.register("excel", ExcelParser()) self.register("epub", EPubParser()) diff --git a/openviking/parse/tree_builder.py b/openviking/parse/tree_builder.py index c8409f41..deea5efc 100644 --- a/openviking/parse/tree_builder.py +++ b/openviking/parse/tree_builder.py @@ -20,22 +20,17 @@ - Content splitting is handled by Parser, not TreeBuilder """ -import asyncio import logging -from typing import TYPE_CHECKING, Optional +from typing import Optional from openviking.core.building_tree import BuildingTree from openviking.core.context import Context from openviking.parse.parsers.media.utils import get_media_base_uri, get_media_type from openviking.server.identity import RequestContext -from openviking.storage.queuefs import SemanticMsg, get_queue_manager from openviking.storage.viking_fs import get_viking_fs from openviking.utils import parse_code_hosting_url from openviking_cli.utils.uri import VikingURI -if TYPE_CHECKING: - pass - logger = logging.getLogger(__name__) @@ -80,6 +75,31 @@ def _get_base_uri( # Agent scope return "viking://agent" + async def _resolve_unique_uri(self, uri: str, max_attempts: int = 100) -> str: + """Return a URI that does not collide with an existing resource. + + If *uri* is free, return it unchanged. Otherwise append ``_1``, + ``_2``, ... until a free name is found. + """ + viking_fs = get_viking_fs() + + async def _exists(u: str) -> bool: + try: + await viking_fs.stat(u) + return True + except Exception: + return False + + if not await _exists(uri): + return uri + + for i in range(1, max_attempts + 1): + candidate = f"{uri}_{i}" + if not await _exists(candidate): + return candidate + + raise FileExistsError(f"Cannot resolve unique name for {uri} after {max_attempts} attempts") + # ============================================================================ # v5.0 Methods (temporary directory + SemanticQueue architecture) # ============================================================================ @@ -93,7 +113,6 @@ async def finalize_from_temp( parent_uri: Optional[str] = None, source_path: Optional[str] = None, source_format: Optional[str] = None, - trigger_semantic: bool = False, ) -> "BuildingTree": """ Finalize processing by moving from temp to AGFS. @@ -101,8 +120,6 @@ async def finalize_from_temp( Args: to_uri: Exact target URI (must not exist) parent_uri: Target parent URI (must exist) - trigger_semantic: Whether to automatically trigger semantic generation. - Default is False (handled by ResourceProcessor/Summarizer). """ viking_fs = get_viking_fs() @@ -138,16 +155,6 @@ async def finalize_from_temp( base_uri = parent_uri or auto_base_uri # 3. Determine candidate_uri if to_uri: - # Exact target URI: must not exist yet - try: - await viking_fs.stat(to_uri, ctx=ctx) - # If we get here, it already exists - raise FileExistsError(f"Target URI already exists: {to_uri}") - except FileExistsError: - raise - except Exception: - # It doesn't exist, good to use - pass candidate_uri = to_uri else: if parent_uri: @@ -160,156 +167,21 @@ async def finalize_from_temp( raise ValueError(f"Parent URI is not a directory: {parent_uri}") candidate_uri = VikingURI(base_uri).join(final_doc_name).uri - final_uri = await self._resolve_unique_uri(candidate_uri, ctx=ctx) - - if final_uri != candidate_uri: - logger.info(f"[TreeBuilder] Resolved name conflict: {candidate_uri} -> {final_uri}") + if to_uri: + final_uri = candidate_uri else: - logger.info(f"[TreeBuilder] Finalizing from temp: {final_uri}") - - # 4. Move directory tree from temp to final location in AGFS - await self._move_temp_to_dest(viking_fs, temp_doc_uri, final_uri, ctx=ctx) - logger.info(f"[TreeBuilder] Moved temp tree: {temp_doc_uri} -> {final_uri}") + final_uri = await self._resolve_unique_uri(candidate_uri) - # 5. Cleanup temporary root directory - try: - await viking_fs.delete_temp(temp_uri, ctx=ctx) - logger.info(f"[TreeBuilder] Cleaned up temp root: {temp_uri}") - except Exception as e: - logger.warning(f"[TreeBuilder] Failed to cleanup temp root: {e}") - - # 6. Enqueue to SemanticQueue for async semantic generation - if trigger_semantic: - try: - await self._enqueue_semantic_generation(final_uri, "resource", ctx=ctx) - logger.info(f"[TreeBuilder] Enqueued semantic generation for: {final_uri}") - except Exception as e: - logger.error( - f"[TreeBuilder] Failed to enqueue semantic generation: {e}", exc_info=True - ) - - # 7. Return simple BuildingTree (no scanning needed) tree = BuildingTree( source_path=source_path, source_format=source_format, ) tree._root_uri = final_uri + if not to_uri: + tree._candidate_uri = candidate_uri # Create a minimal Context object for the root so that tree.root is not None - root_context = Context(uri=final_uri) + root_context = Context(uri=final_uri, temp_uri=temp_doc_uri) tree.add_context(root_context) return tree - - async def _resolve_unique_uri( - self, uri: str, max_attempts: int = 100, ctx: Optional[RequestContext] = None - ) -> str: - """Return a URI that does not collide with an existing resource. - - If *uri* is free, return it unchanged. Otherwise append ``_1``, - ``_2``, … until a free name is found (like macOS Finder / Windows - Explorer). - """ - viking_fs = get_viking_fs() - - async def _exists(u: str) -> bool: - try: - await viking_fs.stat(u, ctx=ctx) - return True - except Exception: - return False - - if not await _exists(uri): - return uri - - for i in range(1, max_attempts + 1): - candidate = f"{uri}_{i}" - if not await _exists(candidate): - return candidate - - raise FileExistsError(f"Cannot resolve unique name for {uri} after {max_attempts} attempts") - - async def _move_temp_to_dest( - self, viking_fs, src_uri: str, dst_uri: str, ctx: RequestContext - ) -> None: - """Move temp directory to final destination using a single native AGFS mv call. - - Temp files have no vector records yet, so no vector index update is needed. - """ - src_path = viking_fs._uri_to_path(src_uri, ctx=ctx) - dst_path = viking_fs._uri_to_path(dst_uri, ctx=ctx) - await self._ensure_parent_dirs(dst_uri, ctx=ctx) - await asyncio.to_thread(viking_fs.agfs.mv, src_path, dst_path) - - async def _ensure_parent_dirs(self, uri: str, ctx: RequestContext) -> None: - """Recursively create parent directories.""" - viking_fs = get_viking_fs() - parent = VikingURI(uri).parent - if not parent: - return - parent_uri = parent.uri - # Recursively ensure parent's parent exists - await self._ensure_parent_dirs(parent_uri, ctx=ctx) - - # Create parent directory (ignore if already exists) - try: - await viking_fs.mkdir(parent_uri, exist_ok=True, ctx=ctx) - logger.debug(f"Created parent directory: {parent_uri}") - except Exception as e: - # Directory may already exist, ignore error - if "exist" not in str(e).lower(): - logger.debug(f"Parent dir {parent_uri} may already exist: {e}") - - async def _enqueue_semantic_generation( - self, uri: str, context_type: str, ctx: RequestContext - ) -> None: - """ - Enqueue a directory for semantic generation. - - Args: - uri: Directory URI to enqueue - context_type: resource/memory/skill - """ - - queue_manager = get_queue_manager() - - # Get semantic queue - semantic_queue = queue_manager.get_queue(queue_manager.SEMANTIC, allow_create=True) - - # Sort by depth (descending) for bottom-up processing - msg = SemanticMsg( - uri=uri, - context_type=context_type, - account_id=ctx.account_id, - user_id=ctx.user.user_id, - agent_id=ctx.user.agent_id, - role=ctx.role.value, - ) - await semantic_queue.enqueue(msg) - - async def _load_content(self, uri: str, content_type: str) -> str: - """Helper to load content with proper type handling""" - import json - - if content_type == "abstract": - result = await get_viking_fs().abstract(uri) - elif content_type == "overview": - result = await get_viking_fs().overview(uri) - elif content_type == "detail": - result = await get_viking_fs().read_file(uri) - else: - return "" - - # Handle different return types - if isinstance(result, str): - return result - elif isinstance(result, bytes): - return result.decode("utf-8") - elif hasattr(result, "to_dict") and not isinstance(result, list): - # Handle FindResult by converting to dict (skip lists) - return str(result.to_dict()) - elif isinstance(result, list): - # Handle list results - return json.dumps(result) - else: - return str(result) diff --git a/openviking/resource/__init__.py b/openviking/resource/__init__.py new file mode 100644 index 00000000..702b7905 --- /dev/null +++ b/openviking/resource/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Resource monitoring and management module.""" + +from openviking.resource.watch_manager import WatchManager, WatchTask + +__all__ = ["WatchManager", "WatchTask"] diff --git a/openviking/resource/watch_manager.py b/openviking/resource/watch_manager.py new file mode 100644 index 00000000..4e475e57 --- /dev/null +++ b/openviking/resource/watch_manager.py @@ -0,0 +1,717 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +""" +Resource monitoring task manager. + +Provides task creation, update, deletion, query, and persistence storage. +""" + +import asyncio +import json +import uuid +from datetime import datetime, timedelta +from typing import Any, Dict, List, Optional + +from pydantic import BaseModel, Field + +from openviking_cli.exceptions import ConflictError +from openviking_cli.utils.logger import get_logger + +logger = get_logger(__name__) + + +class WatchTask(BaseModel): + """Resource monitoring task data model.""" + + task_id: str = Field( + default_factory=lambda: str(uuid.uuid4()), description="Unique task identifier" + ) + path: str = Field(..., description="Resource path to monitor") + to_uri: Optional[str] = Field(None, description="Target URI") + parent_uri: Optional[str] = Field(None, description="Parent URI") + reason: str = Field(default="", description="Reason for monitoring") + instruction: str = Field(default="", description="Monitoring instruction") + watch_interval: float = Field(default=60.0, description="Monitoring interval in minutes") + build_index: bool = Field(default=True, description="Whether to build vector index") + summarize: bool = Field(default=False, description="Whether to generate summary") + processor_kwargs: Dict[str, Any] = Field( + default_factory=dict, description="Extra kwargs forwarded to processor" + ) + created_at: datetime = Field(default_factory=datetime.now, description="Task creation time") + last_execution_time: Optional[datetime] = Field(None, description="Last execution time") + next_execution_time: Optional[datetime] = Field(None, description="Next execution time") + is_active: bool = Field(default=True, description="Whether the task is active") + account_id: str = Field(default="default", description="Account ID (tenant)") + user_id: str = Field(default="default", description="User ID who created this task") + agent_id: str = Field(default="default", description="Agent ID who created this task") + original_role: str = Field(default="user", description="Role used to execute this task") + + class Config: + json_encoders = {datetime: lambda v: v.isoformat() if v else None} + extra = "ignore" + + def to_dict(self) -> Dict[str, Any]: + """Convert task to dictionary.""" + return { + "task_id": self.task_id, + "path": self.path, + "to_uri": self.to_uri, + "parent_uri": self.parent_uri, + "reason": self.reason, + "instruction": self.instruction, + "watch_interval": self.watch_interval, + "build_index": self.build_index, + "summarize": self.summarize, + "processor_kwargs": self.processor_kwargs, + "created_at": self.created_at.isoformat() if self.created_at else None, + "last_execution_time": self.last_execution_time.isoformat() + if self.last_execution_time + else None, + "next_execution_time": self.next_execution_time.isoformat() + if self.next_execution_time + else None, + "is_active": self.is_active, + "account_id": self.account_id, + "user_id": self.user_id, + "agent_id": self.agent_id, + "original_role": self.original_role, + } + + @classmethod + def from_dict(cls, data: Dict[str, Any]) -> "WatchTask": + """Create task from dictionary.""" + if isinstance(data.get("created_at"), str): + data["created_at"] = datetime.fromisoformat(data["created_at"]) + if isinstance(data.get("last_execution_time"), str): + data["last_execution_time"] = datetime.fromisoformat(data["last_execution_time"]) + if isinstance(data.get("next_execution_time"), str): + data["next_execution_time"] = datetime.fromisoformat(data["next_execution_time"]) + if data.get("processor_kwargs") is None: + data["processor_kwargs"] = {} + return cls(**data) + + def calculate_next_execution_time(self) -> datetime: + """Calculate next execution time based on interval.""" + base_time = self.last_execution_time or self.created_at + return base_time + timedelta(minutes=self.watch_interval) + + +class PermissionDeniedError(Exception): + """Permission denied error for watch operations.""" + + pass + + +class WatchManager: + """Resource monitoring task manager. + + Provides task creation, update, deletion, query, and persistence storage. + Thread-safe with async lock for concurrent access protection. + Supports multi-tenant authorization. + """ + + STORAGE_URI = "viking://resources/.watch_tasks.json" + STORAGE_BAK_URI = "viking://resources/.watch_tasks.json.bak" + STORAGE_TMP_URI = "viking://resources/.watch_tasks.json.tmp" + + def __init__(self, viking_fs: Optional[Any] = None): + """Initialize WatchManager. + + Args: + viking_fs: VikingFS instance for persistence storage + """ + self._tasks: Dict[str, WatchTask] = {} + self._uri_to_task: Dict[str, str] = {} + self._lock = asyncio.Lock() + self._viking_fs = viking_fs + self._initialized = False + + async def initialize(self) -> None: + """Initialize the manager by loading tasks from storage.""" + if self._initialized: + return + + async with self._lock: + if self._initialized: + return + + await self._load_tasks() + self._initialized = True + logger.info(f"[WatchManager] Initialized with {len(self._tasks)} tasks") + + async def _load_tasks(self) -> None: + """Load tasks from VikingFS storage.""" + if not self._viking_fs: + logger.debug("[WatchManager] No VikingFS provided, skipping load") + return + + try: + from openviking.server.identity import RequestContext, Role + from openviking_cli.session.user_id import UserIdentifier + + ctx = RequestContext(user=UserIdentifier.the_default_user(), role=Role.ROOT) + + data = None + try: + content = await self._viking_fs.read_file(self.STORAGE_URI, ctx=ctx) + if content and content.strip(): + data = json.loads(content) + except FileNotFoundError: + data = None + except json.JSONDecodeError as e: + logger.warning(f"[WatchManager] Invalid task storage JSON: {e}") + except Exception as e: + logger.warning(f"[WatchManager] Failed to read task storage: {e}") + + recovered_from_backup = False + if data is None: + try: + bak_content = await self._viking_fs.read_file(self.STORAGE_BAK_URI, ctx=ctx) + if bak_content and bak_content.strip(): + data = json.loads(bak_content) + recovered_from_backup = True + except FileNotFoundError: + data = None + except json.JSONDecodeError as e: + logger.warning(f"[WatchManager] Invalid backup task storage JSON: {e}") + data = None + except Exception as e: + logger.warning(f"[WatchManager] Failed to read backup task storage: {e}") + + if not isinstance(data, dict): + data = {"tasks": []} + + normalized = False + for task_data in data.get("tasks", []): + try: + task = WatchTask.from_dict(task_data) + if not task.is_active: + if task.next_execution_time is not None: + task.next_execution_time = None + normalized = True + else: + if task.watch_interval <= 0: + task.is_active = False + task.next_execution_time = None + normalized = True + elif task.next_execution_time is None: + task.next_execution_time = task.calculate_next_execution_time() + normalized = True + self._tasks[task.task_id] = task + if task.to_uri: + self._uri_to_task[task.to_uri] = task.task_id + except Exception as e: + logger.warning( + f"[WatchManager] Failed to load task {task_data.get('task_id')}: {e}" + ) + + logger.info(f"[WatchManager] Loaded {len(self._tasks)} tasks from storage") + if recovered_from_backup: + normalized = True + if normalized: + await self._save_tasks() + except FileNotFoundError: + logger.debug("[WatchManager] No existing task storage found, starting fresh") + except Exception as e: + logger.error(f"[WatchManager] Failed to load tasks: {e}") + + async def _save_tasks(self) -> None: + """Save tasks to VikingFS storage.""" + if not self._viking_fs: + logger.debug("[WatchManager] No VikingFS provided, skipping save") + return + + try: + from openviking.server.identity import RequestContext, Role + from openviking_cli.session.user_id import UserIdentifier + + ctx = RequestContext(user=UserIdentifier.the_default_user(), role=Role.ROOT) + + data = { + "tasks": [task.to_dict() for task in self._tasks.values()], + "updated_at": datetime.now().isoformat(), + } + + content = json.dumps(data, ensure_ascii=False, indent=2) + if not content.strip(): + raise ValueError("Refusing to write empty watch task storage") + json.loads(content) + + supports_atomic = all( + hasattr(self._viking_fs, name) for name in ("mv", "rm", "exists", "write_file") + ) + if not supports_atomic: + await self._viking_fs.write_file(self.STORAGE_URI, content, ctx=ctx) + logger.debug(f"[WatchManager] Saved {len(self._tasks)} tasks to storage") + return + + await self._viking_fs.write_file(self.STORAGE_TMP_URI, content, ctx=ctx) + + try: + if await self._viking_fs.exists(self.STORAGE_BAK_URI, ctx=ctx): + await self._viking_fs.rm(self.STORAGE_BAK_URI, ctx=ctx) + except Exception: + pass + + try: + if await self._viking_fs.exists(self.STORAGE_URI, ctx=ctx): + await self._viking_fs.mv(self.STORAGE_URI, self.STORAGE_BAK_URI, ctx=ctx) + except Exception as e: + logger.warning(f"[WatchManager] Failed to rotate task storage backup: {e}") + + await self._viking_fs.mv(self.STORAGE_TMP_URI, self.STORAGE_URI, ctx=ctx) + logger.debug(f"[WatchManager] Saved {len(self._tasks)} tasks to storage") + except Exception as e: + logger.error(f"[WatchManager] Failed to save tasks: {e}") + raise + + def _check_permission( + self, + task: WatchTask, + account_id: str, + user_id: str, + role: str, + ) -> bool: + """Check if user has permission to access/modify a task. + + Args: + task: The task to check permission for + account_id: Requester's account ID + user_id: Requester's user ID + role: Requester's role (ROOT/ADMIN/USER) + + Returns: + True if has permission, False otherwise + + Notes: + - ROOT can access all tasks. + - ADMIN can access tasks within the same account. + - USER can only access tasks they created within the same account. + """ + role_value = (role or "").lower() + if role_value == "root": + return True + + if task.account_id != account_id: + return False + + if role_value == "admin": + return True + + return task.user_id == user_id + + def _check_uri_conflict( + self, to_uri: Optional[str], exclude_task_id: Optional[str] = None + ) -> bool: + """Check if target URI conflicts with existing tasks. + + Args: + to_uri: Target URI to check + exclude_task_id: Task ID to exclude from conflict check (for updates) + + Returns: + True if there's a conflict, False otherwise + """ + if not to_uri: + return False + + existing_task_id = self._uri_to_task.get(to_uri) + if not existing_task_id: + return False + + if exclude_task_id and existing_task_id == exclude_task_id: + return False + + return True + + async def create_task( + self, + path: str, + account_id: str = "default", + user_id: str = "default", + agent_id: str = "default", + original_role: str = "user", + to_uri: Optional[str] = None, + parent_uri: Optional[str] = None, + reason: str = "", + instruction: str = "", + watch_interval: float = 60.0, + build_index: bool = True, + summarize: bool = False, + processor_kwargs: Optional[Dict[str, Any]] = None, + ) -> WatchTask: + """Create a new monitoring task. + + Args: + path: Resource path to monitor + account_id: Account ID (tenant) + user_id: User ID who creates this task + agent_id: Agent ID who creates this task + to_uri: Target URI + parent_uri: Parent URI + reason: Reason for monitoring + instruction: Monitoring instruction + watch_interval: Monitoring interval in minutes + + Returns: + Created WatchTask + + Raises: + ValueError: If required fields are missing + ConflictError: If target URI conflicts with existing tasks + """ + if not path: + raise ValueError("Path is required") + if watch_interval <= 0: + raise ValueError("watch_interval must be > 0") + + async with self._lock: + if self._check_uri_conflict(to_uri): + raise ConflictError( + f"Target URI '{to_uri}' is already used by another task", + resource=to_uri, + ) + + task = WatchTask( + path=path, + to_uri=to_uri, + parent_uri=parent_uri, + reason=reason, + instruction=instruction, + watch_interval=watch_interval, + build_index=build_index, + summarize=summarize, + processor_kwargs=processor_kwargs or {}, + account_id=account_id, + user_id=user_id, + agent_id=agent_id, + original_role=original_role, + ) + + task.next_execution_time = task.calculate_next_execution_time() + + self._tasks[task.task_id] = task + if to_uri: + self._uri_to_task[to_uri] = task.task_id + + await self._save_tasks() + + logger.info( + f"[WatchManager] Created task {task.task_id} for path {path} by user {account_id}/{user_id}" + ) + return task + + async def update_task( + self, + task_id: str, + account_id: str, + user_id: str, + role: str, + path: Optional[str] = None, + to_uri: Optional[str] = None, + parent_uri: Optional[str] = None, + reason: Optional[str] = None, + instruction: Optional[str] = None, + watch_interval: Optional[float] = None, + build_index: Optional[bool] = None, + summarize: Optional[bool] = None, + processor_kwargs: Optional[Dict[str, Any]] = None, + is_active: Optional[bool] = None, + ) -> WatchTask: + """Update an existing monitoring task. + + Args: + task_id: Task ID to update + account_id: Requester's account ID + user_id: Requester's user ID + role: Requester's role (ROOT/ADMIN/USER) + path: New resource path + to_uri: New target URI + parent_uri: New parent URI + reason: New reason + instruction: New instruction + watch_interval: New monitoring interval + is_active: New active status + + Returns: + Updated WatchTask + + Raises: + ValueError: If task not found or invalid arguments + ConflictError: If target URI conflicts with existing tasks + PermissionDeniedError: If user doesn't have permission + """ + async with self._lock: + task = self._tasks.get(task_id) + if not task: + raise ValueError(f"Task {task_id} not found") + + if not self._check_permission(task, account_id, user_id, role): + raise PermissionDeniedError( + f"User {account_id}/{user_id} does not have permission to update task {task_id}" + ) + + if self._check_uri_conflict(to_uri, exclude_task_id=task_id): + raise ConflictError( + f"Target URI '{to_uri}' is already used by another task", + resource=to_uri, + ) + + old_to_uri = task.to_uri + + if path is not None: + task.path = path + if to_uri is not None: + task.to_uri = to_uri + if parent_uri is not None: + task.parent_uri = parent_uri + if reason is not None: + task.reason = reason + if instruction is not None: + task.instruction = instruction + if watch_interval is not None: + if watch_interval <= 0: + if is_active is True: + raise ValueError("watch_interval must be > 0 for active tasks") + task.watch_interval = watch_interval + task.is_active = False + task.next_execution_time = None + else: + task.watch_interval = watch_interval + if build_index is not None: + task.build_index = build_index + if summarize is not None: + task.summarize = summarize + if processor_kwargs is not None: + task.processor_kwargs = processor_kwargs + if is_active is not None: + task.is_active = is_active + + if watch_interval is not None: + if task.is_active and task.watch_interval > 0: + task.next_execution_time = task.calculate_next_execution_time() + else: + task.next_execution_time = None + if is_active is not None and watch_interval is None: + if task.is_active: + if task.watch_interval <= 0: + raise ValueError("watch_interval must be > 0 for active tasks") + if task.next_execution_time is None: + task.next_execution_time = task.calculate_next_execution_time() + else: + task.next_execution_time = None + + if to_uri is not None: + if old_to_uri and old_to_uri != to_uri: + self._uri_to_task.pop(old_to_uri, None) + if to_uri: + self._uri_to_task[to_uri] = task_id + + await self._save_tasks() + + logger.info(f"[WatchManager] Updated task {task_id} by user {account_id}/{user_id}") + return task + + async def delete_task( + self, + task_id: str, + account_id: str, + user_id: str, + role: str, + ) -> bool: + """Delete a monitoring task. + + Args: + task_id: Task ID to delete + account_id: Requester's account ID + user_id: Requester's user ID + role: Requester's role (ROOT/ADMIN/USER) + + Returns: + True if task was deleted, False if not found + + Raises: + PermissionDeniedError: If user doesn't have permission + """ + async with self._lock: + task = self._tasks.get(task_id) + if not task: + return False + + if not self._check_permission(task, account_id, user_id, role): + raise PermissionDeniedError( + f"User {account_id}/{user_id} does not have permission to delete task {task_id}" + ) + + self._tasks.pop(task_id, None) + if task.to_uri: + self._uri_to_task.pop(task.to_uri, None) + + await self._save_tasks() + + logger.info(f"[WatchManager] Deleted task {task_id} by user {account_id}/{user_id}") + return True + + async def get_task( + self, + task_id: str, + account_id: str = "default", + user_id: str = "default", + role: str = "root", + ) -> Optional[WatchTask]: + """Get a monitoring task by ID. + + Args: + task_id: Task ID to query + account_id: Requester's account ID + user_id: Requester's user ID + role: Requester's role (ROOT/ADMIN/USER) + + Returns: + WatchTask if found and accessible, None otherwise + """ + async with self._lock: + task = self._tasks.get(task_id) + if not task: + return None + + if not self._check_permission(task, account_id, user_id, role): + return None + + return task + + async def get_all_tasks( + self, + account_id: str, + user_id: str, + role: str, + active_only: bool = False, + ) -> List[WatchTask]: + """Get all monitoring tasks accessible by the user. + + Args: + account_id: Requester's account ID + user_id: Requester's user ID + role: Requester's role (ROOT/ADMIN/USER) + active_only: If True, only return active tasks + + Returns: + List of accessible WatchTask objects + """ + async with self._lock: + tasks = [] + for task in self._tasks.values(): + if not self._check_permission(task, account_id, user_id, role): + continue + if active_only and not task.is_active: + continue + tasks.append(task) + return tasks + + async def get_task_by_uri( + self, + to_uri: str, + account_id: str, + user_id: str, + role: str, + ) -> Optional[WatchTask]: + """Get a monitoring task by target URI. + + Args: + to_uri: Target URI to query + account_id: Requester's account ID + user_id: Requester's user ID + role: Requester's role (ROOT/ADMIN/USER) + + Returns: + WatchTask if found and accessible, None otherwise + """ + async with self._lock: + task_id = self._uri_to_task.get(to_uri) + if not task_id: + return None + + task = self._tasks.get(task_id) + if not task: + return None + + if not self._check_permission(task, account_id, user_id, role): + return None + + return task + + async def update_execution_time(self, task_id: str) -> None: + """Update task execution time after execution. + + Args: + task_id: Task ID to update + """ + async with self._lock: + task = self._tasks.get(task_id) + if not task: + return + + if not task.is_active or task.watch_interval <= 0: + task.is_active = False + task.next_execution_time = None + await self._save_tasks() + return + + task.last_execution_time = datetime.now() + task.next_execution_time = task.calculate_next_execution_time() + + await self._save_tasks() + + async def get_due_tasks(self, account_id: Optional[str] = None) -> List[WatchTask]: + """Get all tasks that are due for execution. + + Args: + account_id: Optional account ID filter (for scheduler) + + Returns: + List of tasks that need to be executed + """ + async with self._lock: + now = datetime.now() + due_tasks = [] + + for task in self._tasks.values(): + if not task.is_active: + continue + + if account_id and task.account_id != account_id: + continue + + if task.next_execution_time and task.next_execution_time <= now: + due_tasks.append(task) + + return due_tasks + + async def get_next_execution_time(self, account_id: Optional[str] = None) -> Optional[datetime]: + async with self._lock: + next_times: List[datetime] = [] + for task in self._tasks.values(): + if not task.is_active: + continue + if account_id and task.account_id != account_id: + continue + if task.next_execution_time is None: + continue + next_times.append(task.next_execution_time) + return min(next_times) if next_times else None + + async def clear_all_tasks(self) -> int: + """Clear all tasks (for testing purposes). + + Returns: + Number of tasks cleared + """ + async with self._lock: + count = len(self._tasks) + self._tasks.clear() + self._uri_to_task.clear() + + await self._save_tasks() + + logger.info(f"[WatchManager] Cleared {count} tasks") + return count diff --git a/openviking/resource/watch_scheduler.py b/openviking/resource/watch_scheduler.py new file mode 100644 index 00000000..7ea90237 --- /dev/null +++ b/openviking/resource/watch_scheduler.py @@ -0,0 +1,350 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +""" +Resource watch scheduler. + +Provides scheduled task execution for watch tasks. +""" + +import asyncio +from datetime import datetime +from typing import Any, Optional, Set + +from openviking.resource.watch_manager import WatchManager +from openviking.server.identity import RequestContext, Role +from openviking.service.resource_service import ResourceService +from openviking_cli.utils import get_logger + +logger = get_logger(__name__) + + +class WatchScheduler: + """Scheduled task scheduler for resource watch tasks. + + Periodically checks for due tasks and executes them by calling ResourceService. + Implements concurrency control to skip tasks that are already executing. + Handles execution failures gracefully without affecting next scheduling. + Manages the lifecycle of WatchManager internally. + """ + + DEFAULT_CHECK_INTERVAL = 60.0 + + def __init__( + self, + resource_service: ResourceService, + viking_fs: Optional[Any] = None, + check_interval: float = DEFAULT_CHECK_INTERVAL, + max_concurrency: int = 4, + ): + """Initialize WatchScheduler. + + Args: + resource_service: ResourceService instance for executing tasks + viking_fs: VikingFS instance for WatchManager persistence (optional) + check_interval: Interval in seconds between scheduler checks (default: 60) + """ + self._resource_service = resource_service + self._viking_fs = viking_fs + if check_interval <= 0: + raise ValueError("check_interval must be > 0") + if max_concurrency <= 0: + raise ValueError("max_concurrency must be > 0") + self._check_interval = check_interval + self._max_concurrency = max_concurrency + self._semaphore = asyncio.Semaphore(max_concurrency) + + self._watch_manager: Optional[WatchManager] = None + self._running = False + self._scheduler_task: Optional[asyncio.Task] = None + self._executing_tasks: Set[str] = set() + self._lock = asyncio.Lock() + + @property + def watch_manager(self) -> Optional[WatchManager]: + """Get the WatchManager instance.""" + return self._watch_manager + + async def start(self) -> None: + """Start the scheduler. + + Creates a background task that periodically checks for due tasks. + Initializes the WatchManager and loads persisted tasks. + """ + if self._running: + logger.warning("[WatchScheduler] Scheduler is already running") + return + + # Initialize WatchManager + self._watch_manager = WatchManager(viking_fs=self._viking_fs) + await self._watch_manager.initialize() + logger.info("[WatchScheduler] WatchManager initialized") + + self._running = True + self._scheduler_task = asyncio.create_task(self._run_scheduler()) + logger.info(f"[WatchScheduler] Started with check interval {self._check_interval}s") + + async def stop(self) -> None: + """Stop the scheduler. + + Cancels the background task and waits for it to complete. + Cleans up the WatchManager. + """ + if not self._running: + logger.warning("[WatchScheduler] Scheduler is not running") + return + + self._running = False + + if self._scheduler_task: + self._scheduler_task.cancel() + try: + await self._scheduler_task + except asyncio.CancelledError: + pass + self._scheduler_task = None + + # Clean up WatchManager + if self._watch_manager: + self._watch_manager = None + logger.info("[WatchScheduler] WatchManager cleaned up") + + logger.info("[WatchScheduler] Stopped") + + async def schedule_task(self, task_id: str) -> bool: + """Schedule a single task for immediate execution. + + Args: + task_id: ID of the task to schedule + + Returns: + True if task was scheduled, False if task is already executing or not found + """ + if not self._watch_manager: + logger.warning("[WatchScheduler] WatchManager is not initialized") + return False + + task = await self._watch_manager.get_task(task_id) + if not task: + logger.warning(f"[WatchScheduler] Task {task_id} not found") + return False + + if not await self._try_mark_executing(task_id): + logger.info(f"[WatchScheduler] Task {task_id} is already executing, skipping") + return False + + try: + async with self._semaphore: + await self._execute_task(task) + return True + finally: + await asyncio.shield(self._discard_executing(task_id)) + + async def _run_scheduler(self) -> None: + """Background task loop that periodically checks and executes due tasks. + + This method runs continuously until the scheduler is stopped. + """ + logger.info("[WatchScheduler] Scheduler loop started") + + while self._running: + try: + await self._check_and_execute_due_tasks() + except Exception as e: + logger.error(f"[WatchScheduler] Error in scheduler loop: {e}", exc_info=True) + + try: + sleep_seconds = self._check_interval + if self._watch_manager: + next_time = await self._watch_manager.get_next_execution_time() + if next_time is not None: + now = datetime.now() + sleep_seconds = min( + self._check_interval, + max(0.0, (next_time - now).total_seconds()), + ) + await asyncio.sleep(sleep_seconds) + except asyncio.CancelledError: + break + + logger.info("[WatchScheduler] Scheduler loop ended") + + async def _check_and_execute_due_tasks(self) -> None: + """Check for due tasks and execute them. + + This method is called periodically by the scheduler loop. + """ + if not self._watch_manager: + return + + due_tasks = await self._watch_manager.get_due_tasks() + + if not due_tasks: + return + + logger.info(f"[WatchScheduler] Found {len(due_tasks)} due tasks") + + tasks_to_run = [] + for task in due_tasks: + if not await self._try_mark_executing(task.task_id): + logger.info(f"[WatchScheduler] Task {task.task_id} is already executing, skipping") + continue + tasks_to_run.append(task) + + async def run_one(t) -> None: + try: + async with self._semaphore: + await self._execute_task(t) + finally: + await asyncio.shield(self._discard_executing(t.task_id)) + + if tasks_to_run: + await asyncio.gather(*(asyncio.create_task(run_one(t)) for t in tasks_to_run)) + + async def _execute_task(self, task) -> None: + """Execute a single watch task. + + Calls ResourceService.add_resource to process the resource. + Handles errors gracefully and updates execution time regardless of success/failure. + Deactivates tasks when resources no longer exist. + + Args: + task: WatchTask to execute + """ + logger.info(f"[WatchScheduler] Executing task {task.task_id} for path {task.path}") + + cancelled = False + should_deactivate = False + deactivation_reason = "" + + try: + if not self._check_resource_exists(task.path): + should_deactivate = True + deactivation_reason = f"Resource path does not exist: {task.path}" + logger.warning( + f"[WatchScheduler] Task {task.task_id}: {deactivation_reason}. " + "Deactivating task." + ) + else: + from openviking_cli.session.user_id import UserIdentifier + + user = UserIdentifier( + account_id=task.account_id, + user_id=task.user_id, + agent_id=task.agent_id, + ) + role_value = getattr(task, "original_role", None) or Role.USER.value + try: + role = Role(role_value) + except Exception: + role = Role.USER + ctx = RequestContext( + user=user, + role=role, + ) + + processor_kwargs = dict(getattr(task, "processor_kwargs", {}) or {}) + processor_kwargs.pop("build_index", None) + processor_kwargs.pop("summarize", None) + result = await self._resource_service.add_resource( + path=task.path, + ctx=ctx, + to=task.to_uri, + parent=task.parent_uri, + reason=task.reason, + instruction=task.instruction, + build_index=getattr(task, "build_index", True), + summarize=getattr(task, "summarize", False), + watch_interval=task.watch_interval, + skip_watch_management=True, + **processor_kwargs, + ) + + logger.info( + f"[WatchScheduler] Task {task.task_id} executed successfully, " + f"result: {result.get('root_uri', 'N/A')}" + ) + + except asyncio.CancelledError: + cancelled = True + raise + except FileNotFoundError as e: + should_deactivate = True + deactivation_reason = f"Resource not found: {e}" + logger.error( + f"[WatchScheduler] Task {task.task_id} resource not found: {e}. Deactivating task." + ) + except Exception as e: + logger.error( + f"[WatchScheduler] Task {task.task_id} execution failed: {e}", + exc_info=True, + ) + + finally: + try: + if not cancelled: + if should_deactivate: + await asyncio.shield( + self._watch_manager.update_task( + task_id=task.task_id, + account_id=task.account_id, + user_id=task.user_id, + role=getattr(task, "original_role", None) or Role.USER.value, + is_active=False, + ) + ) + logger.info( + f"[WatchScheduler] Deactivated task {task.task_id}: {deactivation_reason}" + ) + else: + await asyncio.shield( + self._watch_manager.update_execution_time(task.task_id) + ) + logger.info( + f"[WatchScheduler] Updated execution time for task {task.task_id}" + ) + except Exception as e: + logger.error( + f"[WatchScheduler] Failed to update task {task.task_id}: {e}", + exc_info=True, + ) + + async def _try_mark_executing(self, task_id: str) -> bool: + async with self._lock: + if task_id in self._executing_tasks: + return False + self._executing_tasks.add(task_id) + return True + + async def _discard_executing(self, task_id: str) -> None: + async with self._lock: + self._executing_tasks.discard(task_id) + + def _check_resource_exists(self, path: str) -> bool: + """Check if a resource path exists. + + Args: + path: Resource path to check + + Returns: + True if resource exists or is a URL, False otherwise + """ + if path.startswith(("http://", "https://", "git@", "ssh://", "git://")): + return True + + from pathlib import Path + + try: + return Path(path).exists() + except Exception as e: + logger.warning(f"[WatchScheduler] Failed to check path existence {path}: {e}") + return False + + @property + def is_running(self) -> bool: + """Check if the scheduler is running.""" + return self._running + + @property + def executing_tasks(self) -> Set[str]: + """Get the set of currently executing task IDs.""" + return self._executing_tasks.copy() diff --git a/openviking/retrieve/hierarchical_retriever.py b/openviking/retrieve/hierarchical_retriever.py index c2d48598..15843445 100644 --- a/openviking/retrieve/hierarchical_retriever.py +++ b/openviking/retrieve/hierarchical_retriever.py @@ -8,14 +8,18 @@ """ import heapq +import logging +import time from datetime import datetime from typing import Any, Dict, List, Optional, Tuple from openviking.models.embedder.base import EmbedResult from openviking.retrieve.memory_lifecycle import hotness_score +from openviking.retrieve.retrieval_stats import get_stats_collector from openviking.server.identity import RequestContext, Role -from openviking.storage import VikingVectorIndexBackend +from openviking.storage import VikingDBManager, VikingDBManagerProxy from openviking.storage.viking_fs import get_viking_fs +from openviking.telemetry import get_current_telemetry from openviking.utils.time_utils import parse_iso_datetime from openviking_cli.retrieve.types import ( ContextType, @@ -26,6 +30,7 @@ ) from openviking_cli.utils.config import RerankConfig from openviking_cli.utils.logger import get_logger +from openviking_cli.utils.rerank import RerankClient logger = get_logger(__name__) @@ -42,13 +47,13 @@ class HierarchicalRetriever: MAX_RELATIONS = 5 # Maximum relations per resource SCORE_PROPAGATION_ALPHA = 0.5 # Score propagation coefficient DIRECTORY_DOMINANCE_RATIO = 1.2 # Directory score must exceed max child score - GLOBAL_SEARCH_TOPK = 3 # Global retrieval count + GLOBAL_SEARCH_TOPK = 5 # Global retrieval count HOTNESS_ALPHA = 0.2 # Weight for hotness score in final ranking (0 = disabled) LEVEL_URI_SUFFIX = {0: ".abstract.md", 1: ".overview.md"} def __init__( self, - storage: VikingVectorIndexBackend, + storage: VikingDBManager, embedder: Optional[Any], rerank_config: Optional[RerankConfig] = None, ): @@ -68,8 +73,7 @@ def __init__( # Initialize rerank client only if config is available if rerank_config and rerank_config.is_available(): - # TODO: Support later - initialize RerankClient here - self._rerank_client = None + self._rerank_client = RerankClient.from_config(rerank_config) logger.info( f"[HierarchicalRetriever] Rerank config available, threshold={self.threshold}" ) @@ -84,7 +88,7 @@ async def retrieve( query: TypedQuery, ctx: RequestContext, limit: int = 5, - mode: RetrieverMode = RetrieverMode.THINKING, + mode: str = RetrieverMode.THINKING, score_threshold: Optional[float] = None, score_gte: bool = False, scope_dsl: Optional[Dict[str, Any]] = None, @@ -99,16 +103,19 @@ async def retrieve( grep_patterns: Keyword match pattern list scope_dsl: Additional scope constraints passed from public find/search filter """ - + t0 = time.monotonic() # Use custom threshold or default threshold effective_threshold = score_threshold if score_threshold is not None else self.threshold + # 创建 proxy 包装器,绑定当前 ctx + vector_proxy = VikingDBManagerProxy(self.vector_store, ctx) + target_dirs = [d for d in (query.target_directories or []) if d] - if not await self.vector_store.collection_exists_bound(): + if not await vector_proxy.collection_exists_bound(): logger.warning( "[RecursiveSearch] Collection %s does not exist", - self.vector_store.collection_name, + vector_proxy.collection_name, ) return QueryResult( query=query, @@ -120,7 +127,7 @@ async def retrieve( query_vector = None sparse_query_vector = None if self.embedder: - result: EmbedResult = self.embedder.embed(query.query) + result: EmbedResult = self.embedder.embed(query.query, is_query=True) query_vector = result.dense_vector sparse_query_vector = result.sparse_vector @@ -132,22 +139,47 @@ async def retrieve( # Step 2: Global vector search to supplement starting points global_results = await self._global_vector_search( - ctx=ctx, + vector_proxy=vector_proxy, query_vector=query_vector, sparse_query_vector=sparse_query_vector, context_type=query.context_type.value if query.context_type else None, target_dirs=target_dirs, scope_dsl=scope_dsl, - limit=self.GLOBAL_SEARCH_TOPK, + limit=min(limit, self.GLOBAL_SEARCH_TOPK), ) + # Debug: Print all URIs in global_results + if logger.isEnabledFor(logging.DEBUG): + logger.debug(f"[retrieve] target_dirs: {target_dirs}") + logger.debug(f"[retrieve] root_uris: {root_uris}") + logger.debug(f"[retrieve] scope_dsl: {scope_dsl}") + logger.debug( + f"[retrieve] Step 2 completed, global_results contains {len(global_results)} items:" + ) + for i, r in enumerate(global_results): + uri = r.get("uri", "UNKNOWN_URI") + score = r.get("_score", 0.0) + level = r.get("level", "UNKNOWN_LEVEL") + account_id = r.get("account_id", "UNKNOWN_ACCOUNT_ID") + logger.debug( + f" [{i}] URI: {uri}, score: {score:.4f}, level: {level}, account_id: {account_id}" + ) + # Step 3: Merge starting points - starting_points = self._merge_starting_points(query.query, root_uris, global_results) + starting_points = self._merge_starting_points( + query.query, + root_uris, + global_results, + mode=mode, + ) + + # 从 global_results 中提取 level 2 的文件作为初始候选者 + initial_candidates = [r for r in global_results if r.get("level", 2) == 2] # Step 4: Recursive search candidates = await self._recursive_search( + vector_proxy=vector_proxy, query=query.query, - ctx=ctx, query_vector=query_vector, sparse_query_vector=sparse_query_vector, starting_points=starting_points, @@ -158,20 +190,33 @@ async def retrieve( context_type=query.context_type.value if query.context_type else None, target_dirs=target_dirs, scope_dsl=scope_dsl, + initial_candidates=initial_candidates, ) # Step 6: Convert results matched = await self._convert_to_matched_contexts(candidates, ctx=ctx) + final = matched[:limit] + + # Record retrieval stats for the observer. + elapsed_ms = (time.monotonic() - t0) * 1000 + get_stats_collector().record_query( + context_type=query.context_type.value if query.context_type else "unknown", + result_count=len(final), + scores=[m.score for m in final], + latency_ms=elapsed_ms, + rerank_used=self._rerank_client is not None and mode == RetrieverMode.THINKING, + ) + return QueryResult( query=query, - matched_contexts=matched[:limit], + matched_contexts=final, searched_directories=root_uris, ) async def _global_vector_search( self, - ctx: RequestContext, + vector_proxy: VikingDBManagerProxy, query_vector: Optional[List[float]], sparse_query_vector: Optional[Dict[str, float]], context_type: Optional[str], @@ -180,8 +225,7 @@ async def _global_vector_search( limit: int, ) -> List[Dict[str, Any]]: """Global vector search to locate initial directories.""" - results = await self.vector_store.search_global_roots_in_tenant( - ctx=ctx, + results = await vector_proxy.search_global_roots_in_tenant( query_vector=query_vector, sparse_query_vector=sparse_query_vector, context_type=context_type, @@ -189,8 +233,44 @@ async def _global_vector_search( extra_filter=scope_dsl, limit=limit, ) + telemetry = get_current_telemetry() + telemetry.count("vector.searches", 1) + telemetry.count("vector.scored", len(results)) + telemetry.count("vector.scanned", len(results)) return results + def _rerank_scores( + self, + query: str, + documents: List[str], + fallback_scores: List[float], + ) -> List[float]: + """Return rerank scores or fall back to vector scores.""" + if not self._rerank_client or not documents: + return fallback_scores + + try: + scores = self._rerank_client.rerank_batch(query, documents) + except Exception as e: + logger.warning( + "[HierarchicalRetriever] Rerank failed, fallback to vector scores: %s", e + ) + return fallback_scores + + if not scores or len(scores) != len(documents): + logger.warning( + "[HierarchicalRetriever] Invalid rerank result, fallback to vector scores" + ) + return fallback_scores + + normalized_scores: List[float] = [] + for score, fallback in zip(scores, fallback_scores): + if isinstance(score, (int, float)): + normalized_scores.append(float(score)) + else: + normalized_scores.append(fallback) + return normalized_scores + def _merge_starting_points( self, query: str, @@ -206,20 +286,21 @@ def _merge_starting_points( seen = set() # Results from global search - docs = [] + default_scores = [r.get("_score", 0.0) for r in global_results] if self._rerank_client and mode == RetrieverMode.THINKING: - for r in global_results: - # todo: multi-modal - doc = r["abstract"] - docs.append(doc) - rerank_scores = self._rerank_client.rerank_batch(query, docs) + docs = [str(r.get("abstract", "")) for r in global_results] + query_scores = self._rerank_scores(query, docs, default_scores) for i, r in enumerate(global_results): - points.append((r["uri"], rerank_scores[i])) - seen.add(r["uri"]) + # 只添加非 level 2 的项目到起始点 + if r.get("level", 2) != 2: + points.append((r["uri"], query_scores[i])) + seen.add(r["uri"]) else: for r in global_results: - points.append((r["uri"], r["_score"])) - seen.add(r["uri"]) + # 只添加非 level 2 的项目到起始点 + if r.get("level", 2) != 2: + points.append((r["uri"], r["_score"])) + seen.add(r["uri"]) # Root directories as starting points for uri in root_uris: @@ -231,8 +312,8 @@ def _merge_starting_points( async def _recursive_search( self, + vector_proxy: VikingDBManagerProxy, query: str, - ctx: RequestContext, query_vector: Optional[List[float]], sparse_query_vector: Optional[Dict[str, float]], starting_points: List[Tuple[str, float]], @@ -243,6 +324,7 @@ async def _recursive_search( context_type: Optional[str] = None, target_dirs: Optional[List[str]] = None, scope_dsl: Optional[Dict[str, Any]] = None, + initial_candidates: Optional[List[Dict[str, Any]]] = None, ) -> List[Dict[str, Any]]: """ Recursive search with directory priority return and score propagation. @@ -270,6 +352,20 @@ def passes_threshold(score: float) -> bool: prev_topk_uris: set = set() convergence_rounds = 0 + # 添加初始候选者(level 2 文件) + if initial_candidates: + for r in initial_candidates: + uri = r.get("uri", "") + if uri: + # 只添加 level 2 的文件 + if r.get("level", 2) == 2: + score = r.get("_score", 0.0) + r["_final_score"] = score + collected_by_uri[uri] = r + logger.debug( + f"[RecursiveSearch] Added initial candidate: {uri} (score: {score:.4f})" + ) + alpha = self.SCORE_PROPAGATION_ALPHA # Initialize: process starting points @@ -286,8 +382,7 @@ def passes_threshold(score: float) -> bool: pre_filter_limit = max(limit * 2, 20) - results = await self.vector_store.search_children_in_tenant( - ctx=ctx, + results = await vector_proxy.search_children_in_tenant( parent_uri=current_uri, query_vector=query_vector, sparse_query_vector=sparse_query_vector, # Pass sparse vector @@ -296,23 +391,18 @@ def passes_threshold(score: float) -> bool: extra_filter=scope_dsl, limit=pre_filter_limit, ) + telemetry = get_current_telemetry() + telemetry.count("vector.searches", 1) + telemetry.count("vector.scored", len(results)) + telemetry.count("vector.scanned", len(results)) if not results: continue - query_scores = [] + query_scores = [r.get("_score", 0.0) for r in results] if self._rerank_client and mode == RetrieverMode.THINKING: - documents = [] - for r in results: - # todo: multi-modal - doc = r["abstract"] - documents.append(doc) - - rerank_scores = self._rerank_client.rerank_batch(query, documents) - query_scores = rerank_scores - else: - for r in results: - query_scores.append(r.get("_score", 0)) + documents = [str(r.get("abstract", "")) for r in results] + query_scores = self._rerank_scores(query, documents, query_scores) for r, score in zip(results, query_scores): uri = r.get("uri", "") @@ -326,6 +416,7 @@ def passes_threshold(score: float) -> bool: ) continue + telemetry.count("vector.passed", 1) # Deduplicate by URI and keep the highest-scored candidate. previous = collected_by_uri.get(uri) if previous is None or final_score > previous.get("_final_score", 0): diff --git a/openviking/retrieve/retrieval_stats.py b/openviking/retrieve/retrieval_stats.py new file mode 100644 index 00000000..9c285dc2 --- /dev/null +++ b/openviking/retrieve/retrieval_stats.py @@ -0,0 +1,165 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Thread-safe retrieval statistics accumulator. + +Collects per-query metrics from the ``HierarchicalRetriever`` so that +the ``RetrievalObserver`` can report aggregate health and quality data +via the observer API. +""" + +import threading +from dataclasses import dataclass, field +from typing import Dict + + +@dataclass +class RetrievalStats: + """Accumulated retrieval statistics. + + All counters are monotonically increasing within a server lifetime. + The observer reads them to compute rates and averages. + """ + + total_queries: int = 0 + total_results: int = 0 + zero_result_queries: int = 0 + total_score_sum: float = 0.0 + max_score: float = 0.0 + min_score: float = float("inf") + queries_by_type: Dict[str, int] = field(default_factory=dict) + rerank_used: int = 0 + rerank_fallback: int = 0 + total_latency_ms: float = 0.0 + max_latency_ms: float = 0.0 + + @property + def avg_results_per_query(self) -> float: + if self.total_queries == 0: + return 0.0 + return self.total_results / self.total_queries + + @property + def zero_result_rate(self) -> float: + if self.total_queries == 0: + return 0.0 + return self.zero_result_queries / self.total_queries + + @property + def avg_score(self) -> float: + if self.total_results == 0: + return 0.0 + return self.total_score_sum / self.total_results + + @property + def avg_latency_ms(self) -> float: + if self.total_queries == 0: + return 0.0 + return self.total_latency_ms / self.total_queries + + def to_dict(self) -> dict: + """Serialize stats for API responses.""" + return { + "total_queries": self.total_queries, + "total_results": self.total_results, + "zero_result_queries": self.zero_result_queries, + "zero_result_rate": round(self.zero_result_rate, 4), + "avg_results_per_query": round(self.avg_results_per_query, 2), + "avg_score": round(self.avg_score, 4), + "max_score": round(self.max_score, 4) if self.total_results > 0 else 0.0, + "min_score": round(self.min_score, 4) if self.total_results > 0 else 0.0, + "queries_by_type": dict(self.queries_by_type), + "rerank_used": self.rerank_used, + "rerank_fallback": self.rerank_fallback, + "avg_latency_ms": round(self.avg_latency_ms, 1), + "max_latency_ms": round(self.max_latency_ms, 1), + } + + +class RetrievalStatsCollector: + """Thread-safe singleton that accumulates retrieval metrics. + + Usage in the retriever:: + + from openviking.retrieve.retrieval_stats import get_stats_collector + + collector = get_stats_collector() + collector.record_query( + context_type="memory", + result_count=3, + scores=[0.82, 0.71, 0.55], + latency_ms=42.5, + rerank_used=True, + ) + + Usage in the observer:: + + stats = get_stats_collector().snapshot() + """ + + def __init__(self) -> None: + self._lock = threading.Lock() + self._stats = RetrievalStats() + + def record_query( + self, + context_type: str, + result_count: int, + scores: list[float], + latency_ms: float = 0.0, + rerank_used: bool = False, + rerank_fallback: bool = False, + ) -> None: + """Record metrics from a single retrieval query.""" + with self._lock: + self._stats.total_queries += 1 + self._stats.total_results += result_count + + if result_count == 0: + self._stats.zero_result_queries += 1 + + for s in scores: + self._stats.total_score_sum += s + if s > self._stats.max_score: + self._stats.max_score = s + if s < self._stats.min_score: + self._stats.min_score = s + + self._stats.queries_by_type[context_type] = ( + self._stats.queries_by_type.get(context_type, 0) + 1 + ) + + if rerank_used: + self._stats.rerank_used += 1 + if rerank_fallback: + self._stats.rerank_fallback += 1 + + self._stats.total_latency_ms += latency_ms + if latency_ms > self._stats.max_latency_ms: + self._stats.max_latency_ms = latency_ms + + def snapshot(self) -> RetrievalStats: + """Return a copy of the current stats.""" + with self._lock: + import copy + + return copy.deepcopy(self._stats) + + def reset(self) -> None: + """Reset all counters (useful for testing).""" + with self._lock: + self._stats = RetrievalStats() + + +# Module-level singleton. +_collector: RetrievalStatsCollector | None = None +_collector_lock = threading.Lock() + + +def get_stats_collector() -> RetrievalStatsCollector: + """Return the global stats collector singleton.""" + global _collector + if _collector is None: + with _collector_lock: + if _collector is None: + _collector = RetrievalStatsCollector() + return _collector diff --git a/openviking/server/app.py b/openviking/server/app.py index c22794e1..c553c6ff 100644 --- a/openviking/server/app.py +++ b/openviking/server/app.py @@ -59,7 +59,8 @@ def create_app( async def lifespan(app: FastAPI): """Application lifespan handler.""" nonlocal service - if service is None: + owns_service = service is None + if owns_service: service = OpenVikingService() await service.initialize() logger.info("OpenVikingService initialized") @@ -93,7 +94,7 @@ async def lifespan(app: FastAPI): # Cleanup task_tracker.stop_cleanup_loop() - if service: + if owns_service and service: await service.close() logger.info("OpenVikingService closed") diff --git a/openviking/server/auth.py b/openviking/server/auth.py index 06aad25e..0abd7117 100644 --- a/openviking/server/auth.py +++ b/openviking/server/auth.py @@ -7,9 +7,37 @@ from fastapi import Depends, Header, Request from openviking.server.identity import RequestContext, ResolvedIdentity, Role -from openviking_cli.exceptions import PermissionDeniedError, UnauthenticatedError +from openviking_cli.exceptions import ( + InvalidArgumentError, + PermissionDeniedError, + UnauthenticatedError, +) from openviking_cli.session.user_id import UserIdentifier +_ROOT_IMPLICIT_TENANT_ALLOWED_PATHS = { + "/api/v1/system/status", + "/api/v1/system/wait", + "/api/v1/debug/health", +} +_ROOT_IMPLICIT_TENANT_ALLOWED_PREFIXES = ( + "/api/v1/admin", + "/api/v1/observer", +) + + +def _root_request_requires_explicit_tenant(path: str) -> bool: + """Return True when a ROOT request targets tenant-scoped data APIs. + + Root still needs access to admin and monitoring endpoints without a tenant + context. For data APIs, implicit fallback to default/default is misleading, + so callers must provide explicit account and user headers. + """ + if path in _ROOT_IMPLICIT_TENANT_ALLOWED_PATHS: + return False + if path.startswith(_ROOT_IMPLICIT_TENANT_ALLOWED_PREFIXES): + return False + return True + async def resolve_identity( request: Request, @@ -53,9 +81,25 @@ async def resolve_identity( async def get_request_context( + request: Request, identity: ResolvedIdentity = Depends(resolve_identity), ) -> RequestContext: """Convert ResolvedIdentity to RequestContext.""" + path = request.url.path + api_key_manager = getattr(request.app.state, "api_key_manager", None) + if ( + api_key_manager is not None + and identity.role == Role.ROOT + and _root_request_requires_explicit_tenant(path) + ): + account_header = request.headers.get("X-OpenViking-Account") + user_header = request.headers.get("X-OpenViking-User") + if not account_header or not user_header: + raise InvalidArgumentError( + "ROOT requests to tenant-scoped APIs must include X-OpenViking-Account " + "and X-OpenViking-User headers. Use a user key for regular data access." + ) + return RequestContext( user=UserIdentifier( identity.account_id or "default", diff --git a/openviking/server/models.py b/openviking/server/models.py index 4cb7f967..445da590 100644 --- a/openviking/server/models.py +++ b/openviking/server/models.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 """Response models and error codes for OpenViking HTTP Server.""" -from typing import Any, Optional +from typing import Any, Dict, Optional from pydantic import BaseModel @@ -15,21 +15,13 @@ class ErrorInfo(BaseModel): details: Optional[dict] = None -class UsageInfo(BaseModel): - """Usage information.""" - - tokens: Optional[int] = None - vectors_scanned: Optional[int] = None - - class Response(BaseModel): """Standard API response.""" status: str # "ok" | "error" result: Optional[Any] = None error: Optional[ErrorInfo] = None - time: float = 0.0 - usage: Optional[UsageInfo] = None + telemetry: Optional[Dict[str, Any]] = None # Error code to HTTP status code mapping @@ -39,6 +31,7 @@ class Response(BaseModel): "INVALID_URI": 400, "NOT_FOUND": 404, "ALREADY_EXISTS": 409, + "CONFLICT": 409, "PERMISSION_DENIED": 403, "UNAUTHENTICATED": 401, "RESOURCE_EXHAUSTED": 429, diff --git a/openviking/server/routers/content.py b/openviking/server/routers/content.py index f73e4e2b..2463cc08 100644 --- a/openviking/server/routers/content.py +++ b/openviking/server/routers/content.py @@ -2,12 +2,31 @@ # SPDX-License-Identifier: Apache-2.0 """Content endpoints for OpenViking HTTP Server.""" -from fastapi import APIRouter, Depends, Query +import asyncio +from urllib.parse import quote + +from fastapi import APIRouter, Body, Depends, Query +from fastapi.responses import Response as FastAPIResponse +from pydantic import BaseModel from openviking.server.auth import get_request_context from openviking.server.dependencies import get_service from openviking.server.identity import RequestContext -from openviking.server.models import Response +from openviking.server.models import ErrorInfo, Response +from openviking_cli.utils import get_logger + +logger = get_logger(__name__) + +REINDEX_TASK_TYPE = "resource_reindex" + + +class ReindexRequest(BaseModel): + """Request to reindex content at a URI.""" + + uri: str + regenerate: bool = False + wait: bool = True + router = APIRouter(prefix="/api/v1/content", tags=["content"]) @@ -45,3 +64,135 @@ async def overview( service = get_service() result = await service.fs.overview(uri, ctx=_ctx) return Response(status="ok", result=result) + + +@router.get("/download") +async def download( + uri: str = Query(..., description="Viking URI"), + _ctx: RequestContext = Depends(get_request_context), +): + """Download file as raw bytes (for images, binaries, etc.).""" + service = get_service() + content = await service.fs.read_file_bytes(uri, ctx=_ctx) + + # Try to get filename from stat + filename = "download" + try: + stat = await service.fs.stat(uri, ctx=_ctx) + if stat and "name" in stat: + filename = stat["name"] + except Exception: + pass + filename = quote(filename) + return FastAPIResponse( + content=content, + media_type="application/octet-stream", + headers={"Content-Disposition": f"attachment; filename*=UTF-8''{filename}"}, + ) + + +@router.post("/reindex") +async def reindex( + request: ReindexRequest = Body(...), + _ctx: RequestContext = Depends(get_request_context), +): + """Reindex content at a URI. + + Re-embeds existing .abstract.md/.overview.md content into the vector + database. If regenerate=True, also regenerates L0/L1 summaries via LLM + before re-embedding. + + Uses path locking to prevent concurrent reindexes on the same URI. + Set wait=False to run in the background and track progress via task API. + """ + from openviking.service.task_tracker import get_task_tracker + from openviking.storage.viking_fs import get_viking_fs + + uri = request.uri + viking_fs = get_viking_fs() + + # Validate URI exists + if not await viking_fs.exists(uri): + return Response( + status="error", + error=ErrorInfo(code="NOT_FOUND", message=f"URI not found: {uri}"), + ) + + service = get_service() + tracker = get_task_tracker() + + if request.wait: + # Synchronous path: block until reindex completes + if tracker.has_running(REINDEX_TASK_TYPE, uri): + return Response( + status="error", + error=ErrorInfo( + code="CONFLICT", + message=f"URI {uri} already has a reindex in progress", + ), + ) + result = await _do_reindex(service, uri, request.regenerate, _ctx) + return Response(status="ok", result=result) + else: + # Async path: run in background, return task_id for polling + task = tracker.create_if_no_running(REINDEX_TASK_TYPE, uri) + if task is None: + return Response( + status="error", + error=ErrorInfo( + code="CONFLICT", + message=f"URI {uri} already has a reindex in progress", + ), + ) + asyncio.create_task( + _background_reindex_tracked(service, uri, request.regenerate, _ctx, task.task_id) + ) + return Response( + status="ok", + result={ + "uri": uri, + "status": "accepted", + "task_id": task.task_id, + "message": "Reindex is processing in the background", + }, + ) + + +async def _do_reindex( + service, + uri: str, + regenerate: bool, + ctx: RequestContext, +) -> dict: + """Execute reindex within a lock scope.""" + from openviking.storage.transaction import LockContext, get_lock_manager + + viking_fs = service.viking_fs + path = viking_fs._uri_to_path(uri, ctx=ctx) + + async with LockContext(get_lock_manager(), [path], lock_mode="point"): + if regenerate: + return await service.resources.summarize([uri], ctx=ctx) + else: + return await service.resources.build_index([uri], ctx=ctx) + + +async def _background_reindex_tracked( + service, + uri: str, + regenerate: bool, + ctx: RequestContext, + task_id: str, +) -> None: + """Run reindex in background with task tracking.""" + from openviking.service.task_tracker import get_task_tracker + + tracker = get_task_tracker() + tracker.start(task_id) + try: + result = await _do_reindex(service, uri, regenerate, ctx) + tracker.complete(task_id, {"uri": uri, **result}) + logger.info("Background reindex completed: uri=%s task=%s", uri, task_id) + except Exception as exc: + tracker.fail(task_id, str(exc)) + logger.exception("Background reindex failed: uri=%s task=%s", uri, task_id) diff --git a/openviking/server/routers/debug.py b/openviking/server/routers/debug.py index f2c04756..d31c2279 100644 --- a/openviking/server/routers/debug.py +++ b/openviking/server/routers/debug.py @@ -4,14 +4,19 @@ Provides debug API for system diagnostics. - /api/v1/debug/health - Quick health check +- /api/v1/debug/vector/scroll - Paginated vector records +- /api/v1/debug/vector/count - Count vector records """ -from fastapi import APIRouter, Depends +from typing import Optional + +from fastapi import APIRouter, Depends, Query from openviking.server.auth import get_request_context from openviking.server.dependencies import get_service from openviking.server.identity import RequestContext -from openviking.server.models import Response +from openviking.server.models import ErrorInfo, Response +from openviking.storage import VikingDBManagerProxy router = APIRouter(prefix="/api/v1/debug", tags=["debug"]) @@ -24,3 +29,74 @@ async def debug_health( service = get_service() is_healthy = service.debug.is_healthy() return Response(status="ok", result={"healthy": is_healthy}) + + +@router.get("/vector/scroll") +async def debug_vector_scroll( + limit: int = Query(100, ge=1, le=1000), + cursor: Optional[str] = None, + uri: Optional[str] = None, + _ctx: RequestContext = Depends(get_request_context), +): + """Get paginated vector records with tenant isolation.""" + service = get_service() + if not service.vikingdb_manager: + return Response( + status="error", + error=ErrorInfo(code="NO_VECTOR_DB", message="Vector DB not initialized"), + ) + + proxy = VikingDBManagerProxy(service.vikingdb_manager, _ctx) + + filter_expr = None + if uri: + filter_expr = {"op": "must", "field": "uri", "conds": [uri]} + + records, next_cursor = await proxy.scroll(filter=filter_expr, limit=limit, cursor=cursor) + + return Response(status="ok", result={"records": records, "next_cursor": next_cursor}) + + +@router.get("/vector/count") +async def debug_vector_count( + filter: Optional[str] = None, + uri: Optional[str] = None, + _ctx: RequestContext = Depends(get_request_context), +): + """Get count of vector records with tenant isolation.""" + import json + + service = get_service() + if not service.vikingdb_manager: + return Response( + status="error", + error=ErrorInfo(code="NO_VECTOR_DB", message="Vector DB not initialized"), + ) + + proxy = VikingDBManagerProxy(service.vikingdb_manager, _ctx) + + filter_expr = None + if filter: + try: + filter_expr = json.loads(filter) + except json.JSONDecodeError: + return Response( + status="error", + error=ErrorInfo(code="INVALID_FILTER", message="Invalid filter JSON"), + ) + + if uri: + uri_filter = {"op": "must", "field": "uri", "conds": [uri]} + if filter_expr: + # For combining filters, we should use And from expr, but for simplicity, let's use RawDSL for now + from openviking.storage.expr import And, RawDSL + + if isinstance(filter_expr, dict): + filter_expr = RawDSL(filter_expr) + uri_filter = RawDSL(uri_filter) + filter_expr = And([filter_expr, uri_filter]) + else: + filter_expr = uri_filter + + count = await proxy.count(filter=filter_expr) + return Response(status="ok", result={"count": count}) diff --git a/openviking/server/routers/observer.py b/openviking/server/routers/observer.py index fee1c505..e1910596 100644 --- a/openviking/server/routers/observer.py +++ b/openviking/server/routers/observer.py @@ -72,13 +72,23 @@ async def observer_vlm( return Response(status="ok", result=_component_to_dict(component)) -@router.get("/transaction") -async def observer_transaction( +@router.get("/lock") +async def observer_lock( _ctx: RequestContext = Depends(get_request_context), ): - """Get transaction system status.""" + """Get lock system status.""" service = get_service() - component = service.debug.observer.transaction + component = service.debug.observer.lock + return Response(status="ok", result=_component_to_dict(component)) + + +@router.get("/retrieval") +async def observer_retrieval( + _ctx: RequestContext = Depends(get_request_context), +): + """Get retrieval quality metrics.""" + service = get_service() + component = service.debug.observer.retrieval return Response(status="ok", result=_component_to_dict(component)) diff --git a/openviking/server/routers/resources.py b/openviking/server/routers/resources.py index e1c63bc3..c2fcccf6 100644 --- a/openviking/server/routers/resources.py +++ b/openviking/server/routers/resources.py @@ -14,6 +14,8 @@ from openviking.server.dependencies import get_service from openviking.server.identity import RequestContext from openviking.server.models import Response +from openviking.server.telemetry import run_operation +from openviking.telemetry import TelemetryRequest from openviking_cli.exceptions import InvalidArgumentError from openviking_cli.utils.config.open_viking_config import get_openviking_config @@ -21,7 +23,39 @@ class AddResourceRequest(BaseModel): - """Request model for add_resource.""" + """Request model for add_resource. + + Attributes: + path: Resource path (local file path or URL). Either path or temp_path must be provided. + temp_path: Temporary file path for uploaded files. Either path or temp_path must be provided. + to: Target URI for the resource (e.g., "viking://resources/my_resource"). + If not specified, an auto-generated URI will be used. + parent: Parent URI under which the resource will be stored. + Cannot be used together with 'to'. + reason: Reason for adding the resource. Used for documentation and monitoring. + instruction: Processing instruction for semantic extraction. + Provides hints for how the resource should be processed. + wait: Whether to wait for semantic extraction and vectorization to complete. + Default is False (async processing). + timeout: Timeout in seconds when wait=True. None means no timeout. + strict: Whether to use strict mode for processing. Default is True. + ignore_dirs: Comma-separated list of directory names to ignore during parsing. + include: Glob pattern for files to include during parsing. + exclude: Glob pattern for files to exclude during parsing. + directly_upload_media: Whether to directly upload media files. Default is True. + preserve_structure: Whether to preserve directory structure when adding directories. + watch_interval: Watch interval in minutes for automatic resource monitoring. + - watch_interval > 0: Creates or updates a watch task. The resource will be + automatically re-processed at the specified interval. + - watch_interval = 0: No watch task is created. If a watch task exists for + this resource, it will be cancelled (deactivated). + - watch_interval < 0: Same as watch_interval = 0, cancels any existing watch task. + Default is 0 (no monitoring). + + Note: If the target URI already has an active watch task, a ConflictError will be + raised. You must first cancel the existing watch (set watch_interval <= 0) before + creating a new one. + """ path: Optional[str] = None temp_path: Optional[str] = None @@ -37,6 +71,8 @@ class AddResourceRequest(BaseModel): exclude: Optional[str] = None directly_upload_media: bool = True preserve_structure: Optional[bool] = None + telemetry: TelemetryRequest = False + watch_interval: float = 0 @model_validator(mode="after") def check_path_or_temp_path(self): @@ -52,6 +88,7 @@ class AddSkillRequest(BaseModel): temp_path: Optional[str] = None wait: bool = False timeout: Optional[float] = None + telemetry: TelemetryRequest = False def _cleanup_temp_files(temp_dir: Path, max_age_hours: int = 1): @@ -98,12 +135,10 @@ async def add_resource( _ctx: RequestContext = Depends(get_request_context), ): """Add resource to OpenViking.""" - # Validate request: only one of 'to' or 'parent' can be set + service = get_service() if request.to and request.parent: raise InvalidArgumentError("Cannot specify both 'to' and 'parent' at the same time.") - service = get_service() - path = request.path if request.temp_path: path = request.temp_path @@ -116,22 +151,31 @@ async def add_resource( "include": request.include, "exclude": request.exclude, "directly_upload_media": request.directly_upload_media, + "watch_interval": request.watch_interval, } if request.preserve_structure is not None: kwargs["preserve_structure"] = request.preserve_structure - result = await service.resources.add_resource( - path=path, - ctx=_ctx, - to=request.to, - parent=request.parent, - reason=request.reason, - instruction=request.instruction, - wait=request.wait, - timeout=request.timeout, - **kwargs, + execution = await run_operation( + operation="resources.add_resource", + telemetry=request.telemetry, + fn=lambda: service.resources.add_resource( + path=path, + ctx=_ctx, + to=request.to, + parent=request.parent, + reason=request.reason, + instruction=request.instruction, + wait=request.wait, + timeout=request.timeout, + **kwargs, + ), ) - return Response(status="ok", result=result) + return Response( + status="ok", + result=execution.result, + telemetry=execution.telemetry, + ).model_dump(exclude_none=True) @router.post("/skills") @@ -141,15 +185,22 @@ async def add_skill( ): """Add skill to OpenViking.""" service = get_service() - data = request.data if request.temp_path: data = request.temp_path - result = await service.resources.add_skill( - data=data, - ctx=_ctx, - wait=request.wait, - timeout=request.timeout, + execution = await run_operation( + operation="resources.add_skill", + telemetry=request.telemetry, + fn=lambda: service.resources.add_skill( + data=data, + ctx=_ctx, + wait=request.wait, + timeout=request.timeout, + ), ) - return Response(status="ok", result=result) + return Response( + status="ok", + result=execution.result, + telemetry=execution.telemetry, + ).model_dump(exclude_none=True) diff --git a/openviking/server/routers/search.py b/openviking/server/routers/search.py index 73d7309d..efde8dc0 100644 --- a/openviking/server/routers/search.py +++ b/openviking/server/routers/search.py @@ -11,6 +11,8 @@ from openviking.server.dependencies import get_service from openviking.server.identity import RequestContext from openviking.server.models import Response +from openviking.server.telemetry import run_operation +from openviking.telemetry import TelemetryRequest router = APIRouter(prefix="/api/v1/search", tags=["search"]) @@ -24,6 +26,7 @@ class FindRequest(BaseModel): node_limit: Optional[int] = None score_threshold: Optional[float] = None filter: Optional[Dict[str, Any]] = None + telemetry: TelemetryRequest = False class SearchRequest(BaseModel): @@ -36,6 +39,7 @@ class SearchRequest(BaseModel): node_limit: Optional[int] = None score_threshold: Optional[float] = None filter: Optional[Dict[str, Any]] = None + telemetry: TelemetryRequest = False class GrepRequest(BaseModel): @@ -63,18 +67,26 @@ async def find( """Semantic search without session context.""" service = get_service() actual_limit = request.node_limit if request.node_limit is not None else request.limit - result = await service.search.find( - query=request.query, - ctx=_ctx, - target_uri=request.target_uri, - limit=actual_limit, - score_threshold=request.score_threshold, - filter=request.filter, + execution = await run_operation( + operation="search.find", + telemetry=request.telemetry, + fn=lambda: service.search.find( + query=request.query, + ctx=_ctx, + target_uri=request.target_uri, + limit=actual_limit, + score_threshold=request.score_threshold, + filter=request.filter, + ), ) - # Convert FindResult to dict if it has to_dict method + result = execution.result if hasattr(result, "to_dict"): result = result.to_dict() - return Response(status="ok", result=result) + return Response( + status="ok", + result=result, + telemetry=execution.telemetry, + ).model_dump(exclude_none=True) @router.post("/search") @@ -85,26 +97,35 @@ async def search( """Semantic search with optional session context.""" service = get_service() - # Get session if session_id provided - session = None - if request.session_id: - session = service.sessions.session(_ctx, request.session_id) - await session.load() - - actual_limit = request.node_limit if request.node_limit is not None else request.limit - result = await service.search.search( - query=request.query, - ctx=_ctx, - target_uri=request.target_uri, - session=session, - limit=actual_limit, - score_threshold=request.score_threshold, - filter=request.filter, + async def _search(): + session = None + if request.session_id: + session = service.sessions.session(_ctx, request.session_id) + await session.load() + actual_limit = request.node_limit if request.node_limit is not None else request.limit + return await service.search.search( + query=request.query, + ctx=_ctx, + target_uri=request.target_uri, + session=session, + limit=actual_limit, + score_threshold=request.score_threshold, + filter=request.filter, + ) + + execution = await run_operation( + operation="search.search", + telemetry=request.telemetry, + fn=_search, ) - # Convert FindResult to dict if it has to_dict method + result = execution.result if hasattr(result, "to_dict"): result = result.to_dict() - return Response(status="ok", result=result) + return Response( + status="ok", + result=result, + telemetry=execution.telemetry, + ).model_dump(exclude_none=True) @router.post("/grep") diff --git a/openviking/server/routers/sessions.py b/openviking/server/routers/sessions.py index 871932e5..bffcf934 100644 --- a/openviking/server/routers/sessions.py +++ b/openviking/server/routers/sessions.py @@ -6,7 +6,7 @@ import logging from typing import Any, Dict, List, Literal, Optional -from fastapi import APIRouter, Depends, Path, Query +from fastapi import APIRouter, Body, Depends, Path, Query from pydantic import BaseModel, model_validator from openviking.message.part import TextPart, part_from_dict @@ -14,7 +14,10 @@ from openviking.server.dependencies import get_service from openviking.server.identity import RequestContext from openviking.server.models import ErrorInfo, Response +from openviking.server.telemetry import resolve_selection, run_operation from openviking.service.task_tracker import get_task_tracker +from openviking.telemetry import TelemetryRequest +from openviking_cli.exceptions import InvalidArgumentError router = APIRouter(prefix="/api/v1/sessions", tags=["sessions"]) logger = logging.getLogger(__name__) @@ -73,6 +76,19 @@ def validate_content_or_parts(self) -> "AddMessageRequest": return self +class UsedRequest(BaseModel): + """Request model for recording usage.""" + + contexts: Optional[List[str]] = None + skill: Optional[Dict[str, Any]] = None + + +class CommitSessionRequest(BaseModel): + """Request model for session commit.""" + + telemetry: TelemetryRequest = False + + def _to_jsonable(value: Any) -> Any: """Convert internal objects (e.g. Context) into JSON-serializable values.""" to_dict = getattr(value, "to_dict", None) @@ -144,6 +160,7 @@ async def delete_session( @router.post("/{session_id}/commit") async def commit_session( + request: CommitSessionRequest = Body(default_factory=CommitSessionRequest), session_id: str = Path(..., description="Session ID"), wait: bool = Query( True, @@ -173,8 +190,20 @@ async def commit_session( message=f"Session {session_id} already has a commit in progress", ), ) - result = await service.sessions.commit_async(session_id, _ctx) - return Response(status="ok", result=result) + execution = await run_operation( + operation="session.commit", + telemetry=request.telemetry, + fn=lambda: service.sessions.commit_async(session_id, _ctx), + ) + return Response( + status="ok", + result=execution.result, + telemetry=execution.telemetry, + ).model_dump(exclude_none=True) + + selection = resolve_selection(request.telemetry) + if selection.include_payload: + raise InvalidArgumentError("telemetry is not supported when wait=false for session.commit") # Atomically check + create to prevent race conditions task = tracker.create_if_no_running("session_commit", session_id) @@ -274,3 +303,24 @@ async def add_message( "message_count": len(session.messages), }, ) + + +@router.post("/{session_id}/used") +async def record_used( + request: UsedRequest, + session_id: str = Path(..., description="Session ID"), + _ctx: RequestContext = Depends(get_request_context), +): + """Record actually used contexts and skills in a session.""" + service = get_service() + session = service.sessions.session(_ctx, session_id) + await session.load() + session.used(contexts=request.contexts, skill=request.skill) + return Response( + status="ok", + result={ + "session_id": session_id, + "contexts_used": session.stats.contexts_used, + "skills_used": session.stats.skills_used, + }, + ) diff --git a/openviking/server/routers/system.py b/openviking/server/routers/system.py index 7dcea691..b10ca591 100644 --- a/openviking/server/routers/system.py +++ b/openviking/server/routers/system.py @@ -8,12 +8,12 @@ from fastapi.responses import JSONResponse from pydantic import BaseModel -from openviking.server.auth import get_request_context +from openviking.server.auth import get_request_context, resolve_identity from openviking.server.dependencies import get_service from openviking.server.identity import RequestContext from openviking.server.models import Response from openviking.storage.viking_fs import get_viking_fs -from openviking_cli.utils.logger import get_logger +from openviking_cli.utils import get_logger logger = get_logger(__name__) @@ -21,9 +21,43 @@ @router.get("/health", tags=["system"]) -async def health_check(): +async def health_check(request: Request): """Health check endpoint (no authentication required).""" - return {"status": "ok"} + from openviking import __version__ + + result = {"status": "ok", "healthy": True, "version": __version__} + + # Try to get user identity if auth headers are present + try: + # Extract headers manually + x_api_key = request.headers.get("X-API-Key") + authorization = request.headers.get("Authorization") + x_openviking_user = request.headers.get("X-OpenViking-User") + + # Check if we have auth or in dev mode + api_key_manager = getattr(request.app.state, "api_key_manager", None) + if api_key_manager is None: + # Dev mode - use default user + result["user_id"] = x_openviking_user or "default" + elif x_api_key or authorization: + # Try to resolve identity + try: + identity = await resolve_identity( + request, + x_api_key=x_api_key, + authorization=authorization, + x_openviking_account=request.headers.get("X-OpenViking-Account"), + x_openviking_user=x_openviking_user, + x_openviking_agent=request.headers.get("X-OpenViking-Agent"), + ) + if identity and identity.user_id: + result["user_id"] = identity.user_id + except Exception: + pass + except Exception: + pass + + return result @router.get("/ready", tags=["system"]) diff --git a/openviking/server/telemetry.py b/openviking/server/telemetry.py new file mode 100644 index 00000000..196f09eb --- /dev/null +++ b/openviking/server/telemetry.py @@ -0,0 +1,33 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""HTTP router helpers for operation telemetry.""" + +from __future__ import annotations + +from typing import Any, Awaitable, Callable + +from openviking.telemetry import TelemetryRequest, TelemetrySelection +from openviking.telemetry.execution import ( + TelemetryExecutionResult, + parse_telemetry_selection, + run_with_telemetry, +) + + +def resolve_selection(telemetry: TelemetryRequest) -> TelemetrySelection: + """Validate a router telemetry request without starting execution.""" + return parse_telemetry_selection(telemetry) + + +async def run_operation( + *, + operation: str, + telemetry: TelemetryRequest, + fn: Callable[[], Awaitable[Any]], +) -> TelemetryExecutionResult[Any]: + """Execute a router operation with request-scoped telemetry.""" + return await run_with_telemetry( + operation=operation, + telemetry=telemetry, + fn=fn, + ) diff --git a/openviking/service/core.py b/openviking/service/core.py index 5764fed1..8a4ec618 100644 --- a/openviking/service/core.py +++ b/openviking/service/core.py @@ -11,6 +11,7 @@ from openviking.agfs_manager import AGFSManager from openviking.core.directories import DirectoryInitializer +from openviking.resource.watch_scheduler import WatchScheduler from openviking.server.identity import RequestContext, Role from openviking.service.debug_service import DebugService from openviking.service.fs_service import FSService @@ -23,7 +24,7 @@ from openviking.storage import VikingDBManager from openviking.storage.collection_schemas import init_context_collection from openviking.storage.queuefs.queue_manager import QueueManager, init_queue_manager -from openviking.storage.transaction import TransactionManager, init_transaction_manager +from openviking.storage.transaction import LockManager, init_lock_manager from openviking.storage.viking_fs import VikingFS, init_viking_fs from openviking.utils.resource_processor import ResourceProcessor from openviking.utils.skill_processor import SkillProcessor @@ -75,8 +76,9 @@ def __init__( self._resource_processor: Optional[ResourceProcessor] = None self._skill_processor: Optional[SkillProcessor] = None self._session_compressor: Optional[SessionCompressor] = None - self._transaction_manager: Optional[TransactionManager] = None + self._lock_manager: Optional[LockManager] = None self._directory_initializer: Optional[DirectoryInitializer] = None + self._watch_scheduler: Optional[WatchScheduler] = None # Sub-services self._fs_service = FSService() @@ -136,12 +138,21 @@ def _init_storage( vectordb_config=config.vectordb, queue_manager=self._queue_manager ) - # Configure queues if QueueManager is available + # Configure queues if QueueManager is available. + # Workers are NOT started here — start() is called after VikingFS is initialized + # in initialize(), so that recovered tasks don't race against VikingFS init. if self._queue_manager: - self._queue_manager.setup_standard_queues(self._vikingdb_manager) + self._queue_manager.setup_standard_queues(self._vikingdb_manager, start=False) - # Initialize TransactionManager - self._transaction_manager = init_transaction_manager(agfs=self._agfs_client) + # Initialize LockManager (fail-fast if AGFS missing) + if self._agfs_client is None: + raise RuntimeError("AGFS client not initialized for LockManager") + tx_cfg = config.transaction + self._lock_manager = init_lock_manager( + agfs=self._agfs_client, + lock_timeout=tx_cfg.lock_timeout, + lock_expire=tx_cfg.lock_expire, + ) @property def _agfs(self) -> Any: @@ -159,15 +170,20 @@ def vikingdb_manager(self) -> Optional[VikingDBManager]: return self._vikingdb_manager @property - def transaction_manager(self) -> Optional[TransactionManager]: - """Get TransactionManager instance.""" - return self._transaction_manager + def lock_manager(self) -> Optional[LockManager]: + """Get LockManager instance.""" + return self._lock_manager @property def session_compressor(self) -> Optional[SessionCompressor]: """Get SessionCompressor instance.""" return self._session_compressor + @property + def watch_scheduler(self) -> Optional[WatchScheduler]: + """Get WatchScheduler instance.""" + return self._watch_scheduler + @property def fs(self) -> FSService: """Get FSService instance.""" @@ -214,6 +230,12 @@ async def initialize(self) -> None: logger.debug("Already initialized") return + # Acquire advisory lock on data directory to prevent multi-process + # contention (see https://github.com/volcengine/OpenViking/issues/473). + from openviking.utils.process_lock import acquire_data_dir_lock + + acquire_data_dir_lock(self._config.storage.workspace) + if self._vikingdb_manager is None: self._init_storage( self._config.storage, @@ -230,8 +252,15 @@ async def initialize(self) -> None: enable_recorder = os.environ.get("OPENVIKING_ENABLE_RECORDER", "").lower() == "true" # Create context collection + if self._vikingdb_manager is None: + raise RuntimeError("VikingDBManager not initialized") await init_context_collection(self._vikingdb_manager) + if self._agfs_client is None: + raise RuntimeError("AGFS client not initialized") + if self._embedder is None: + raise RuntimeError("Embedder not initialized") + self._viking_fs = init_viking_fs( agfs=self._agfs_client, query_embedder=self._embedder, @@ -242,6 +271,14 @@ async def initialize(self) -> None: if enable_recorder: logger.info("VikingFS IO Recorder enabled") + # Start queue workers now that VikingFS is ready. + # Doing it here (rather than in _init_storage) ensures that any tasks + # recovered from a previous crash are not processed before VikingFS is + # initialized, which would cause "VikingFS not initialized" errors. + if self._queue_manager: + self._queue_manager.start() + logger.info("QueueManager workers started") + # Initialize directories directory_initializer = DirectoryInitializer(vikingdb=self._vikingdb_manager) self._directory_initializer = directory_initializer @@ -255,14 +292,23 @@ async def initialize(self) -> None: ) # Initialize processors - self._resource_processor = ResourceProcessor(vikingdb=self._vikingdb_manager) + self._resource_processor = ResourceProcessor( + vikingdb=self._vikingdb_manager, + ) self._skill_processor = SkillProcessor(vikingdb=self._vikingdb_manager) self._session_compressor = SessionCompressor(vikingdb=self._vikingdb_manager) - # Start TransactionManager if initialized - if self._transaction_manager: - await self._transaction_manager.start() - logger.info("TransactionManager started") + # Start LockManager if initialized + if self._lock_manager: + await self._lock_manager.start() + logger.info("LockManager started") + + self._watch_scheduler = WatchScheduler( + resource_service=self._resource_service, + viking_fs=self._viking_fs, + ) + await self._watch_scheduler.start() + logger.info("WatchScheduler started") # Wire up sub-services self._fs_service.set_viking_fs(self._viking_fs) @@ -274,6 +320,7 @@ async def initialize(self) -> None: viking_fs=self._viking_fs, resource_processor=self._resource_processor, skill_processor=self._skill_processor, + watch_scheduler=self._watch_scheduler, ) self._session_service.set_dependencies( vikingdb=self._vikingdb_manager, @@ -290,9 +337,14 @@ async def initialize(self) -> None: async def close(self) -> None: """Close OpenViking and release resources.""" - if self._transaction_manager: - self._transaction_manager.stop() - self._transaction_manager = None + if self._watch_scheduler: + await self._watch_scheduler.stop() + self._watch_scheduler = None + logger.info("WatchScheduler stopped") + + if self._lock_manager: + await self._lock_manager.stop() + self._lock_manager = None if self._vikingdb_manager: self._vikingdb_manager.mark_closing() diff --git a/openviking/service/debug_service.py b/openviking/service/debug_service.py index 2e8253f9..b99b4e73 100644 --- a/openviking/service/debug_service.py +++ b/openviking/service/debug_service.py @@ -9,13 +9,14 @@ from openviking.storage import VikingDBManager from openviking.storage.observers import ( + LockObserver, QueueObserver, - TransactionObserver, + RetrievalObserver, VikingDBObserver, VLMObserver, ) from openviking.storage.queuefs import get_queue_manager -from openviking.storage.transaction import get_transaction_manager +from openviking.storage.transaction import get_lock_manager from openviking_cli.utils.config import OpenVikingConfig @@ -135,19 +136,31 @@ def vlm(self) -> ComponentStatus: ) @property - def transaction(self) -> ComponentStatus: - """Get transaction status.""" - transaction_manager = get_transaction_manager() - if transaction_manager is None: + def lock(self) -> ComponentStatus: + """Get lock system status.""" + try: + lock_manager = get_lock_manager() + except Exception: return ComponentStatus( - name="transaction", + name="lock", is_healthy=False, has_errors=True, - status="Transaction manager not initialized.", + status="Not initialized", ) - observer = TransactionObserver(transaction_manager) + observer = LockObserver(lock_manager) + return ComponentStatus( + name="lock", + is_healthy=observer.is_healthy(), + has_errors=observer.has_errors(), + status=observer.get_status_table(), + ) + + @property + def retrieval(self) -> ComponentStatus: + """Get retrieval quality status.""" + observer = RetrievalObserver() return ComponentStatus( - name="transaction", + name="retrieval", is_healthy=observer.is_healthy(), has_errors=observer.has_errors(), status=observer.get_status_table(), @@ -160,7 +173,8 @@ def system(self) -> SystemStatus: "queue": self.queue, "vikingdb": self.vikingdb, "vlm": self.vlm, - "transaction": self.transaction, + "lock": self.lock, + "retrieval": self.retrieval, } errors = [f"{c.name} has errors" for c in components.values() if c.has_errors] return SystemStatus( diff --git a/openviking/service/fs_service.py b/openviking/service/fs_service.py index 5807e8f1..066c4328 100644 --- a/openviking/service/fs_service.py +++ b/openviking/service/fs_service.py @@ -180,3 +180,8 @@ async def glob( """File pattern matching.""" viking_fs = self._ensure_initialized() return await viking_fs.glob(pattern, uri=uri, node_limit=node_limit, ctx=ctx) + + async def read_file_bytes(self, uri: str, ctx: RequestContext) -> bytes: + """Read file as raw bytes.""" + viking_fs = self._ensure_initialized() + return await viking_fs.read_file_bytes(uri, ctx=ctx) diff --git a/openviking/service/resource_service.py b/openviking/service/resource_service.py index 36cf80f8..d41942bc 100644 --- a/openviking/service/resource_service.py +++ b/openviking/service/resource_service.py @@ -6,15 +6,25 @@ Provides resource management operations: add_resource, add_skill, wait_processed. """ -from typing import Any, Dict, List, Optional +import json +import time +from typing import TYPE_CHECKING, Any, Dict, List, Optional from openviking.server.identity import RequestContext from openviking.storage import VikingDBManager from openviking.storage.queuefs import get_queue_manager from openviking.storage.viking_fs import VikingFS +from openviking.telemetry import get_current_telemetry +from openviking.telemetry.resource_summary import ( + build_queue_status_payload, + record_resource_wait_metrics, + register_wait_telemetry, + unregister_wait_telemetry, +) from openviking.utils.resource_processor import ResourceProcessor from openviking.utils.skill_processor import SkillProcessor from openviking_cli.exceptions import ( + ConflictError, DeadlineExceededError, InvalidArgumentError, NotInitializedError, @@ -22,6 +32,10 @@ from openviking_cli.utils import get_logger from openviking_cli.utils.uri import VikingURI +if TYPE_CHECKING: + from openviking.resource.watch_manager import WatchManager + from openviking.resource.watch_scheduler import WatchScheduler + logger = get_logger(__name__) @@ -34,11 +48,13 @@ def __init__( viking_fs: Optional[VikingFS] = None, resource_processor: Optional[ResourceProcessor] = None, skill_processor: Optional[SkillProcessor] = None, + watch_scheduler: Optional["WatchScheduler"] = None, ): self._vikingdb = vikingdb self._viking_fs = viking_fs self._resource_processor = resource_processor self._skill_processor = skill_processor + self._watch_scheduler = watch_scheduler def set_dependencies( self, @@ -46,12 +62,29 @@ def set_dependencies( viking_fs: VikingFS, resource_processor: ResourceProcessor, skill_processor: SkillProcessor, + watch_scheduler: Optional["WatchScheduler"] = None, ) -> None: """Set dependencies (for deferred initialization).""" self._vikingdb = vikingdb self._viking_fs = viking_fs self._resource_processor = resource_processor self._skill_processor = skill_processor + self._watch_scheduler = watch_scheduler + + def _get_watch_manager(self) -> Optional["WatchManager"]: + if not self._watch_scheduler: + return None + return self._watch_scheduler.watch_manager + + def _sanitize_watch_processor_kwargs(self, processor_kwargs: Dict[str, Any]) -> Dict[str, Any]: + sanitized: Dict[str, Any] = {} + for key, value in processor_kwargs.items(): + try: + json.dumps(value, ensure_ascii=False) + except TypeError: + continue + sanitized[key] = value + return sanitized def _ensure_initialized(self) -> None: """Ensure all dependencies are initialized.""" @@ -74,69 +107,255 @@ async def add_resource( timeout: Optional[float] = None, build_index: bool = True, summarize: bool = False, + watch_interval: float = 0, + skip_watch_management: bool = False, **kwargs, ) -> Dict[str, Any]: """Add resource to OpenViking (only supports resources scope). Args: path: Resource path (local file or URL) - target: Target URI - reason: Reason for adding - instruction: Processing instruction + to: Target URI (e.g., "viking://resources/my_resource") + parent: Parent URI under which the resource will be stored + reason: Reason for adding the resource + instruction: Processing instruction for semantic extraction wait: Whether to wait for semantic extraction and vectorization to complete timeout: Wait timeout in seconds - build_index: Whether to build vector index immediately (default: True). - summarize: Whether to generate summary (default: False). - **kwargs: Extra options forwarded to the parser chain. + build_index: Whether to build vector index immediately (default: True) + summarize: Whether to generate summary (default: False) + watch_interval: Watch interval in minutes for automatic resource monitoring. + - watch_interval > 0: Creates or updates a watch task. The resource will be + automatically re-processed at the specified interval by the scheduler. + - watch_interval = 0: No watch task is created. If a watch task exists for + this resource, it will be cancelled (deactivated). + - watch_interval < 0: Same as watch_interval = 0, cancels any existing watch task. + Default is 0 (no monitoring). + + Note: If the target URI already has an active watch task, a ConflictError will be + raised. You must first cancel the existing watch (set watch_interval <= 0) before + creating a new one. + skip_watch_management: If True, skip watch task management (used by scheduler to + avoid recursive watch task creation during scheduled execution) + **kwargs: Extra options forwarded to the parser chain Returns: - Processing result + Processing result containing 'root_uri' and other metadata + + Raises: + ConflictError: If the target URI already has an active watch task + InvalidArgumentError: If the URI scope is not 'resources' """ self._ensure_initialized() + request_start = time.perf_counter() + telemetry_id = register_wait_telemetry(wait) - # add_resource only supports resources scope - if to and to.startswith("viking://"): - parsed = VikingURI(to) - if parsed.scope != "resources": + try: + # add_resource only supports resources scope + if to and to.startswith("viking://"): + parsed = VikingURI(to) + if parsed.scope != "resources": + raise InvalidArgumentError( + f"add_resource only supports resources scope, use dedicated interface to add {parsed.scope} content" + ) + if parent and parent.startswith("viking://"): + parsed = VikingURI(parent) + if parsed.scope != "resources": + raise InvalidArgumentError( + f"add_resource only supports resources scope, use dedicated interface to add {parsed.scope} content" + ) + watch_manager = self._get_watch_manager() + if watch_manager and not skip_watch_management and watch_interval > 0 and not to: raise InvalidArgumentError( - f"add_resource only supports resources scope, use dedicated interface to add {parsed.scope} content" + "watch_interval > 0 requires 'to' to be specified (target URI to watch)" ) - if parent and parent.startswith("viking://"): - parsed = VikingURI(parent) - if parsed.scope != "resources": - raise InvalidArgumentError( - f"add_resource only supports resources scope, use dedicated interface to add {parsed.scope} content" + + result = await self._resource_processor.process_resource( + path=path, + ctx=ctx, + reason=reason, + instruction=instruction, + scope="resources", + to=to, + parent=parent, + build_index=build_index, + summarize=summarize, + **kwargs, + ) + + if wait: + qm = get_queue_manager() + wait_start = time.perf_counter() + try: + status = await qm.wait_complete(timeout=timeout) + except TimeoutError as exc: + get_current_telemetry().set_error( + "resource_service.wait_complete", + "DEADLINE_EXCEEDED", + str(exc), + ) + raise DeadlineExceededError("queue processing", timeout) from exc + queue_wait_duration_ms = round((time.perf_counter() - wait_start) * 1000, 3) + result["queue_status"] = build_queue_status_payload(status) + record_resource_wait_metrics( + telemetry_id=telemetry_id, + queue_status=status, + root_uri=result.get("root_uri"), ) + get_current_telemetry().set("queue.wait.duration_ms", queue_wait_duration_ms) + if watch_manager and to and not skip_watch_management: + if watch_interval > 0: + try: + processor_kwargs = self._sanitize_watch_processor_kwargs(kwargs) + await self._handle_watch_task_creation( + path=path, + to_uri=to, + parent_uri=parent, + reason=reason, + instruction=instruction, + watch_interval=watch_interval, + build_index=build_index, + summarize=summarize, + processor_kwargs=processor_kwargs, + ctx=ctx, + ) + except ConflictError: + raise + except Exception as e: + logger.warning( + f"[ResourceService] Failed to create watch task for {to}: {e}" + ) + else: + try: + await self._handle_watch_task_cancellation(to_uri=to, ctx=ctx) + except Exception as e: + logger.warning( + f"[ResourceService] Failed to cancel watch task for {to}: {e}" + ) - result = await self._resource_processor.process_resource( - path=path, - ctx=ctx, - reason=reason, - instruction=instruction, - scope="resources", - to=to, - parent=parent, - build_index=build_index, - summarize=summarize, - **kwargs, + get_current_telemetry().set( + "resource.request.duration_ms", + round((time.perf_counter() - request_start) * 1000, 3), + ) + return result + except Exception as exc: + get_current_telemetry().set_error( + "resource_service.add_resource", + type(exc).__name__, + str(exc), + ) + raise + finally: + unregister_wait_telemetry(telemetry_id) + + async def _handle_watch_task_creation( + self, + path: str, + to_uri: str, + parent_uri: Optional[str], + reason: str, + instruction: str, + watch_interval: float, + build_index: bool, + summarize: bool, + processor_kwargs: Dict[str, Any], + ctx: RequestContext, + ) -> None: + """Handle creation or update of watch task. + + Args: + path: Resource path to monitor + to_uri: Target URI + parent_uri: Parent URI + reason: Reason for monitoring + instruction: Monitoring instruction + watch_interval: Monitoring interval in minutes + ctx: Request context with user identity + + Raises: + ConflictError: If target URI is already used by another active task + """ + watch_manager = self._get_watch_manager() + if not watch_manager: + return + + existing_task = await watch_manager.get_task_by_uri( + to_uri=to_uri, + account_id=ctx.account_id, + user_id=ctx.user.user_id, + role=ctx.role.value, ) + if existing_task: + if existing_task.is_active: + raise ConflictError( + f"Target URI '{to_uri}' is already being monitored by task {existing_task.task_id}. " + f"Please cancel the existing task first.", + resource=to_uri, + ) + await watch_manager.update_task( + task_id=existing_task.task_id, + account_id=ctx.account_id, + user_id=ctx.user.user_id, + role=ctx.role.value, + path=path, + to_uri=to_uri, + parent_uri=parent_uri, + reason=reason, + instruction=instruction, + watch_interval=watch_interval, + build_index=build_index, + summarize=summarize, + processor_kwargs=processor_kwargs, + is_active=True, + ) + logger.info( + f"[ResourceService] Reactivated and updated watch task {existing_task.task_id} for {to_uri}" + ) + else: + task = await watch_manager.create_task( + path=path, + account_id=ctx.account_id, + user_id=ctx.user.user_id, + agent_id=ctx.user.agent_id, + original_role=ctx.role.value, + to_uri=to_uri, + parent_uri=parent_uri, + reason=reason, + instruction=instruction, + watch_interval=watch_interval, + build_index=build_index, + summarize=summarize, + processor_kwargs=processor_kwargs, + ) + logger.info(f"[ResourceService] Created watch task {task.task_id} for {to_uri}") - if wait: - qm = get_queue_manager() - try: - status = await qm.wait_complete(timeout=timeout) - except TimeoutError as exc: - raise DeadlineExceededError("queue processing", timeout) from exc - result["queue_status"] = { - name: { - "processed": s.processed, - "error_count": s.error_count, - "errors": [{"message": e.message} for e in s.errors], - } - for name, s in status.items() - } + async def _handle_watch_task_cancellation(self, to_uri: str, ctx: RequestContext) -> None: + """Handle cancellation of watch task. - return result + Args: + to_uri: Target URI to cancel watch for + ctx: Request context with user identity + """ + watch_manager = self._get_watch_manager() + if not watch_manager: + return + + existing_task = await watch_manager.get_task_by_uri( + to_uri=to_uri, + account_id=ctx.account_id, + user_id=ctx.user.user_id, + role=ctx.role.value, + ) + if existing_task: + await watch_manager.update_task( + task_id=existing_task.task_id, + account_id=ctx.account_id, + user_id=ctx.user.user_id, + role=ctx.role.value, + is_active=False, + ) + logger.info( + f"[ResourceService] Deactivated watch task {existing_task.task_id} for {to_uri}" + ) async def add_skill( self, @@ -165,18 +384,21 @@ async def add_skill( if wait: qm = get_queue_manager() + wait_start = time.perf_counter() try: status = await qm.wait_complete(timeout=timeout) except TimeoutError as exc: + get_current_telemetry().set_error( + "resource_service.wait_complete", + "DEADLINE_EXCEEDED", + str(exc), + ) raise DeadlineExceededError("queue processing", timeout) from exc - result["queue_status"] = { - name: { - "processed": s.processed, - "error_count": s.error_count, - "errors": [{"message": e.message} for e in s.errors], - } - for name, s in status.items() - } + get_current_telemetry().set( + "queue.wait.duration_ms", + round((time.perf_counter() - wait_start) * 1000, 3), + ) + result["queue_status"] = build_queue_status_payload(status) return result diff --git a/openviking/service/search_service.py b/openviking/service/search_service.py index 7dc13ca9..0e674441 100644 --- a/openviking/service/search_service.py +++ b/openviking/service/search_service.py @@ -64,7 +64,7 @@ async def search( if session: session_info = await session.get_context_for_search(query) - return await viking_fs.search( + result = await viking_fs.search( query=query, ctx=ctx, target_uri=target_uri, @@ -73,6 +73,7 @@ async def search( score_threshold=score_threshold, filter=filter, ) + return result async def find( self, @@ -96,7 +97,7 @@ async def find( FindResult """ viking_fs = self._ensure_initialized() - return await viking_fs.find( + result = await viking_fs.find( query=query, ctx=ctx, target_uri=target_uri, @@ -104,3 +105,4 @@ async def find( score_threshold=score_threshold, filter=filter, ) + return result diff --git a/openviking/session/__init__.py b/openviking/session/__init__.py index 6add1ab9..d9a8d9d3 100644 --- a/openviking/session/__init__.py +++ b/openviking/session/__init__.py @@ -3,6 +3,11 @@ """Session management module.""" from openviking.session.compressor import ExtractionStats, SessionCompressor +from openviking.session.memory_archiver import ( + ArchivalCandidate, + ArchivalResult, + MemoryArchiver, +) from openviking.session.memory_deduplicator import ( DedupDecision, DedupResult, @@ -26,6 +31,10 @@ # Compressor "SessionCompressor", "ExtractionStats", + # Memory Archiver + "MemoryArchiver", + "ArchivalCandidate", + "ArchivalResult", # Memory Extractor "MemoryExtractor", "MemoryCategory", diff --git a/openviking/session/compressor.py b/openviking/session/compressor.py index 3f7eb432..7fd066c7 100644 --- a/openviking/session/compressor.py +++ b/openviking/session/compressor.py @@ -66,16 +66,100 @@ def __init__( self.vikingdb = vikingdb self.extractor = MemoryExtractor() self.deduplicator = MemoryDeduplicator(vikingdb=vikingdb) + self._pending_semantic_changes: Dict[str, Dict[str, set]] = {} - async def _index_memory(self, memory: Context, ctx: RequestContext) -> bool: - """Add memory to vectorization queue and trigger parent directory semantic generation.""" + def _record_semantic_change( + self, file_uri: str, change_type: str, parent_uri: Optional[str] = None + ) -> None: + """Record a file change for batch semantic processing. + + Args: + file_uri: The URI of the file that changed + change_type: One of "added", "modified", "deleted" + parent_uri: Optional parent directory URI. If not provided, will be derived from file_uri + """ + if change_type not in ("added", "modified", "deleted"): + logger.warning(f"Invalid change_type: {change_type}, skipping") + return + + if not parent_uri: + parent_uri = "/".join(file_uri.rsplit("/", 1)[:-1]) + + if not parent_uri: + logger.warning(f"Could not determine parent URI for {file_uri}, skipping") + return + + if parent_uri not in self._pending_semantic_changes: + self._pending_semantic_changes[parent_uri] = { + "added": set(), + "modified": set(), + "deleted": set(), + } + + self._pending_semantic_changes[parent_uri][change_type].add(file_uri) + logger.debug(f"Recorded semantic change: {change_type} {file_uri} in {parent_uri}") + + async def _flush_semantic_operations(self, ctx: RequestContext) -> None: + """Flush all pending semantic operations. + + This method should be called after all memory changes are complete. + It will deduplicate parent URIs and enqueue semantic operations with change info. + """ + if not self._pending_semantic_changes: + return + + try: + from openviking.storage.queuefs import get_queue_manager + from openviking.storage.queuefs.semantic_msg import SemanticMsg + + queue_manager = get_queue_manager() + semantic_queue = queue_manager.get_queue(queue_manager.SEMANTIC, allow_create=True) + + for parent_uri, changes in self._pending_semantic_changes.items(): + changes_dict = { + "added": list(changes["added"]), + "modified": list(changes["modified"]), + "deleted": list(changes["deleted"]), + } + + msg = SemanticMsg( + uri=parent_uri, + context_type="memory", + account_id=ctx.account_id, + user_id=ctx.user.user_id, + agent_id=ctx.user.agent_id, + role=ctx.role.value, + changes=changes_dict, + ) + await semantic_queue.enqueue(msg) + logger.info( + f"Enqueued semantic generation for {parent_uri} with changes: " + f"added={len(changes['added'])}, modified={len(changes['modified'])}, " + f"deleted={len(changes['deleted'])}" + ) + + except Exception as e: + logger.error(f"Failed to flush semantic operations: {e}", exc_info=True) + finally: + self._pending_semantic_changes.clear() + + async def _index_memory( + self, memory: Context, ctx: RequestContext, change_type: str = "added" + ) -> bool: + """Add memory to vectorization queue and record semantic change. + + Args: + memory: The memory context to index + ctx: Request context + change_type: One of "added" or "modified" + """ from openviking.storage.queuefs.embedding_msg_converter import EmbeddingMsgConverter embedding_msg = EmbeddingMsgConverter.from_context(memory) await self.vikingdb.enqueue_embedding_msg(embedding_msg) logger.info(f"Enqueued memory for vectorization: {memory.uri}") - await self.extractor._enqueue_semantic_for_parent(memory.uri, ctx) + self._record_semantic_change(memory.uri, change_type, parent_uri=memory.parent_uri) return True async def _merge_into_existing( @@ -108,7 +192,7 @@ async def _merge_into_existing( "Merged memory %s with abstract %s", target_memory.uri, target_memory.abstract ) target_memory.set_vectorize(Vectorize(text=payload.content)) - await self._index_memory(target_memory, ctx) + await self._index_memory(target_memory, ctx, change_type="modified") return True except Exception as e: logger.error(f"Failed to merge memory {target_memory.uri}: {e}") @@ -129,6 +213,8 @@ async def _delete_existing_memory( await self.vikingdb.delete_uris(ctx, [memory.uri]) except Exception as e: logger.warning(f"Failed to remove vector record for {memory.uri}: {e}") + + self._record_semantic_change(memory.uri, "deleted", parent_uri=memory.parent_uri) return True async def extract_long_term_memories( @@ -137,6 +223,7 @@ async def extract_long_term_memories( user: Optional["UserIdentifier"] = None, session_id: Optional[str] = None, ctx: Optional[RequestContext] = None, + strict_extract_errors: bool = False, ) -> List[Context]: """Extract long-term memories from messages.""" if not messages: @@ -146,157 +233,209 @@ async def extract_long_term_memories( if not ctx: return [] - candidates = await self.extractor.extract(context, user, session_id) - - if not candidates: - return [] - - memories: List[Context] = [] - stats = ExtractionStats() - viking_fs = get_viking_fs() - - tool_parts = self._extract_tool_parts(messages) - from .tool_skill_utils import collect_skill_stats, collect_tool_stats - - tool_stats_map = collect_tool_stats(tool_parts) - skill_stats_map = collect_skill_stats(tool_parts) - - for candidate in candidates: - # Profile: skip dedup, always merge - if candidate.category in ALWAYS_MERGE_CATEGORIES: - memory = await self.extractor.create_memory(candidate, user, session_id, ctx=ctx) - if memory: - memories.append(memory) - stats.created += 1 - await self._index_memory(memory, ctx) - else: - stats.skipped += 1 - continue + self._pending_semantic_changes.clear() - # Tool/Skill Memory: 特殊合并逻辑 - if candidate.category in TOOL_SKILL_CATEGORIES: - if isinstance(candidate, ToolSkillCandidateMemory): - tool_name, skill_name, tool_status = self._get_tool_skill_info( - candidate, tool_parts + try: + if strict_extract_errors: + # Intentionally let extraction errors bubble up so caller (task tracker) + # can mark background commit tasks as failed with an explicit error. + candidates = await self.extractor.extract_strict(context, user, session_id) + else: + candidates = await self.extractor.extract(context, user, session_id) + + if not candidates: + return [] + + memories: List[Context] = [] + stats = ExtractionStats() + # Track created memories' embeddings for batch-internal dedup (#687) + batch_memories: list[tuple[list[float], Context]] = [] + viking_fs = get_viking_fs() + + tool_parts = self._extract_tool_parts(messages) + from .tool_skill_utils import collect_skill_stats, collect_tool_stats + + tool_stats_map = collect_tool_stats(tool_parts) + skill_stats_map = collect_skill_stats(tool_parts) + + for candidate in candidates: + # Profile: skip dedup, always merge + if candidate.category in ALWAYS_MERGE_CATEGORIES: + memory = await self.extractor.create_memory( + candidate, user, session_id, ctx=ctx ) - candidate.tool_status = tool_status - if tool_name: - candidate.tool_name = tool_name - if skill_name: - candidate.skill_name = skill_name - - if tool_name and candidate.call_time == 0: - tool_stats = tool_stats_map.get(tool_name, {}) - candidate.call_time = tool_stats.get("call_count", candidate.call_time) - candidate.success_time = tool_stats.get( - "success_time", candidate.success_time - ) - candidate.duration_ms = tool_stats.get("duration_ms", candidate.duration_ms) - candidate.prompt_tokens = tool_stats.get( - "prompt_tokens", candidate.prompt_tokens - ) - candidate.completion_tokens = tool_stats.get( - "completion_tokens", candidate.completion_tokens - ) - - if skill_name and candidate.call_time == 0: - skill_stats = skill_stats_map.get(skill_name, {}) - candidate.call_time = skill_stats.get("call_count", candidate.call_time) - candidate.success_time = skill_stats.get( - "success_time", candidate.success_time - ) - if skill_name: - memory = await self.extractor._merge_skill_memory( - skill_name, candidate, ctx=ctx - ) - elif tool_name: - memory = await self.extractor._merge_tool_memory( - tool_name, candidate, ctx=ctx - ) - else: - logger.warning("No tool_name or skill_name found, skipping") - stats.skipped += 1 - continue if memory: memories.append(memory) - stats.merged += 1 + stats.created += 1 await self._index_memory(memory, ctx) - continue - - # Dedup check for other categories - result = await self.deduplicator.deduplicate(candidate) - actions = result.actions or [] - decision = result.decision - - # Safety net: create+merge should be treated as none. - if decision == DedupDecision.CREATE and any( - a.decision == MemoryActionDecision.MERGE for a in actions - ): - logger.warning( - f"Dedup returned create with merge action, normalizing to none: " - f"{candidate.abstract}" - ) - decision = DedupDecision.NONE + else: + stats.skipped += 1 + continue + + # Tool/Skill Memory: 特殊合并逻辑 + if candidate.category in TOOL_SKILL_CATEGORIES: + if isinstance(candidate, ToolSkillCandidateMemory): + tool_name, skill_name, tool_status = self._get_tool_skill_info( + candidate, tool_parts + ) + candidate.tool_status = tool_status + if tool_name: + candidate.tool_name = tool_name + if skill_name: + candidate.skill_name = skill_name + + if tool_name and candidate.call_time == 0: + tool_stats = tool_stats_map.get(tool_name, {}) + candidate.call_time = tool_stats.get("call_count", candidate.call_time) + candidate.success_time = tool_stats.get( + "success_time", candidate.success_time + ) + candidate.duration_ms = tool_stats.get( + "duration_ms", candidate.duration_ms + ) + candidate.prompt_tokens = tool_stats.get( + "prompt_tokens", candidate.prompt_tokens + ) + candidate.completion_tokens = tool_stats.get( + "completion_tokens", candidate.completion_tokens + ) + + if skill_name and candidate.call_time == 0: + skill_stats = skill_stats_map.get(skill_name, {}) + candidate.call_time = skill_stats.get("call_count", candidate.call_time) + candidate.success_time = skill_stats.get( + "success_time", candidate.success_time + ) + if skill_name: + memory = await self.extractor._merge_skill_memory( + skill_name, candidate, ctx=ctx + ) + elif tool_name: + memory = await self.extractor._merge_tool_memory( + tool_name, candidate, ctx=ctx + ) + else: + logger.warning("No tool_name or skill_name found, skipping") + stats.skipped += 1 + continue + if memory: + memories.append(memory) + stats.merged += 1 + await self._index_memory(memory, ctx, change_type="modified") + continue - if decision == DedupDecision.SKIP: - stats.skipped += 1 - continue + # Dedup check for other categories + result = await self.deduplicator.deduplicate( + candidate, ctx, batch_memories=batch_memories + ) + actions = result.actions or [] + decision = result.decision + + # Safety net: create+merge should be treated as none. + if decision == DedupDecision.CREATE and any( + a.decision == MemoryActionDecision.MERGE for a in actions + ): + logger.warning( + f"Dedup returned create with merge action, normalizing to none: " + f"{candidate.abstract}" + ) + decision = DedupDecision.NONE - if decision == DedupDecision.NONE: - if not actions: + if decision == DedupDecision.SKIP: stats.skipped += 1 continue - for action in actions: - if action.decision == MemoryActionDecision.DELETE: - if viking_fs and await self._delete_existing_memory( - action.memory, viking_fs, ctx=ctx - ): - stats.deleted += 1 - else: - stats.skipped += 1 - elif action.decision == MemoryActionDecision.MERGE: - if candidate.category in MERGE_SUPPORTED_CATEGORIES and viking_fs: - if await self._merge_into_existing( - candidate, action.memory, viking_fs, ctx=ctx + if decision == DedupDecision.NONE: + if not actions: + stats.skipped += 1 + continue + + for action in actions: + if action.decision == MemoryActionDecision.DELETE: + if viking_fs and await self._delete_existing_memory( + action.memory, viking_fs, ctx=ctx ): - stats.merged += 1 + stats.deleted += 1 + # Remove deleted memory from batch tracking (#687) + batch_memories = [ + (v, m) for v, m in batch_memories if m.uri != action.memory.uri + ] else: stats.skipped += 1 - else: - # events/cases don't support MERGE, treat as SKIP - stats.skipped += 1 - continue - - if decision == DedupDecision.CREATE: - # create can optionally include delete actions (delete first, then create) - for action in actions: - if action.decision == MemoryActionDecision.DELETE: - if viking_fs and await self._delete_existing_memory( - action.memory, viking_fs, ctx=ctx - ): - stats.deleted += 1 - else: - stats.skipped += 1 + elif action.decision == MemoryActionDecision.MERGE: + if candidate.category in MERGE_SUPPORTED_CATEGORIES and viking_fs: + if await self._merge_into_existing( + candidate, action.memory, viking_fs, ctx=ctx + ): + stats.merged += 1 + # Remove stale batch entry and re-add with updated + # embedding so 3rd+ candidates can still find it (#687). + batch_memories = [ + (v, m) + for v, m in batch_memories + if m.uri != action.memory.uri + ] + if self.deduplicator.embedder: + merged_text = ( + f"{action.memory.abstract} {candidate.content}" + ) + merged_embed = self.deduplicator.embedder.embed( + merged_text + ) + batch_memories.append( + (merged_embed.dense_vector, action.memory) + ) + else: + stats.skipped += 1 + else: + # events/cases don't support MERGE, treat as SKIP + stats.skipped += 1 + continue - memory = await self.extractor.create_memory(candidate, user, session_id, ctx=ctx) - if memory: - memories.append(memory) - stats.created += 1 - await self._index_memory(memory, ctx) - else: - stats.skipped += 1 + if decision == DedupDecision.CREATE: + # create can optionally include delete actions (delete first, then create) + for action in actions: + if action.decision == MemoryActionDecision.DELETE: + if viking_fs and await self._delete_existing_memory( + action.memory, viking_fs, ctx=ctx + ): + stats.deleted += 1 + # Remove deleted memory from batch tracking (#687) + batch_memories = [ + (v, m) for v, m in batch_memories if m.uri != action.memory.uri + ] + else: + stats.skipped += 1 + + memory = await self.extractor.create_memory( + candidate, user, session_id, ctx=ctx + ) + if memory: + memories.append(memory) + stats.created += 1 + await self._index_memory(memory, ctx) + # Store embedding for batch-internal dedup of subsequent candidates (#687) + if result.query_vector: + batch_memories.append((result.query_vector, memory)) + else: + stats.skipped += 1 - # Extract URIs used in messages, create relations - used_uris = self._extract_used_uris(messages) - if used_uris and memories: - await self._create_relations(memories, used_uris, ctx=ctx) + # Extract URIs used in messages, create relations + used_uris = self._extract_used_uris(messages) + if used_uris and memories: + await self._create_relations(memories, used_uris, ctx=ctx) - logger.info( - f"Memory extraction: created={stats.created}, " - f"merged={stats.merged}, deleted={stats.deleted}, skipped={stats.skipped}" - ) - return memories + await self._flush_semantic_operations(ctx) + + logger.info( + f"Memory extraction: created={stats.created}, " + f"merged={stats.merged}, deleted={stats.deleted}, skipped={stats.skipped}" + ) + return memories + + except Exception: + self._pending_semantic_changes.clear() + raise def _extract_tool_parts(self, messages: List[Message]) -> List: """Extract all ToolPart from messages.""" diff --git a/openviking/session/memory_archiver.py b/openviking/session/memory_archiver.py new file mode 100644 index 00000000..680ae402 --- /dev/null +++ b/openviking/session/memory_archiver.py @@ -0,0 +1,328 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Cold-storage archival for stale memories based on hotness scoring. + +Moves memories with low hotness scores to an archive directory, +reducing token consumption from stale abstracts and overviews during +retrieval. Archived memories can be restored to their original location. +""" + +from dataclasses import dataclass, field +from datetime import datetime, timezone +from typing import Any, List, Optional + +from openviking.retrieve.memory_lifecycle import hotness_score +from openviking.server.identity import RequestContext +from openviking.storage.expr import And, Eq +from openviking.utils.time_utils import parse_iso_datetime +from openviking_cli.utils.logger import get_logger + +logger = get_logger(__name__) + +# Directory name for archived memories within each scope. +ARCHIVE_DIR = "_archive" + + +@dataclass +class ArchivalCandidate: + """A memory that qualifies for archival.""" + + uri: str + active_count: int + updated_at: Optional[datetime] + score: float + context_type: str = "" + parent_uri: str = "" + + +@dataclass +class ArchivalResult: + """Summary of an archival operation.""" + + scanned: int = 0 + archived: int = 0 + skipped: int = 0 + errors: int = 0 + candidates: List[ArchivalCandidate] = field(default_factory=list) + + +class MemoryArchiver: + """Archives cold memories based on hotness scoring. + + Uses ``hotness_score()`` from ``memory_lifecycle`` to identify memories + whose access frequency and recency have fallen below a threshold. + Moves them to ``{scope}/_archive/`` using ``viking_fs.mv()`` so + they remain recoverable but are excluded from default retrieval. + """ + + DEFAULT_THRESHOLD: float = 0.1 + DEFAULT_MIN_AGE_DAYS: int = 7 + DEFAULT_BATCH_SIZE: int = 100 + + def __init__( + self, + viking_fs: Any, + storage: Any, + threshold: float = DEFAULT_THRESHOLD, + min_age_days: int = DEFAULT_MIN_AGE_DAYS, + ): + """Initialize the archiver. + + Args: + viking_fs: VikingFS instance for filesystem operations. + storage: VikingDBManagerProxy for vector index queries. + threshold: Hotness score below which memories are archived. + min_age_days: Skip memories updated within this many days. + """ + self.viking_fs = viking_fs + self.storage = storage + self.threshold = threshold + self.min_age_days = min_age_days + + async def scan( + self, + scope_uri: str, + ctx: Optional[RequestContext] = None, + now: Optional[datetime] = None, + ) -> List[ArchivalCandidate]: + """Scan a scope for cold memories. + + Queries the vector index for all L2 memories under *scope_uri*, + computes their hotness score, and returns those below the threshold + that are older than ``min_age_days``. + + Args: + scope_uri: Root URI to scan (e.g. ``viking://memories/``). + ctx: Request context for tenant isolation. + now: Override current time (for deterministic tests). + + Returns: + List of candidates eligible for archival, sorted by score + ascending (coldest first). + """ + if now is None: + now = datetime.now(timezone.utc) + + candidates: List[ArchivalCandidate] = [] + + # Only scan L2 content -- never archive L0 abstracts or L1 overviews. + filter_expr = And(conds=[Eq("level", 2)]) + + cursor: Optional[str] = None + total_scanned = 0 + + while True: + records, next_cursor = await self.storage.scroll( + filter=filter_expr, + limit=self.DEFAULT_BATCH_SIZE, + cursor=cursor, + output_fields=[ + "uri", + "active_count", + "updated_at", + "context_type", + "parent_uri", + ], + ) + + if not records: + break + + for record in records: + uri = record.get("uri", "") + + # Skip entries already in an archive directory. + if f"/{ARCHIVE_DIR}/" in uri: + continue + + # Skip entries outside the requested scope. + if not uri.startswith(scope_uri): + continue + + total_scanned += 1 + + active_count = int(record.get("active_count", 0) or 0) + updated_at_raw = record.get("updated_at") + updated_at = _parse_datetime(updated_at_raw) + + # Respect minimum age. + if updated_at is not None: + age_days = (now - updated_at).total_seconds() / 86400.0 + if age_days < self.min_age_days: + continue + + score = hotness_score( + active_count=active_count, + updated_at=updated_at, + now=now, + ) + + if score < self.threshold: + candidates.append( + ArchivalCandidate( + uri=uri, + active_count=active_count, + updated_at=updated_at, + score=score, + context_type=record.get("context_type", ""), + parent_uri=record.get("parent_uri", ""), + ) + ) + + cursor = next_cursor + if cursor is None: + break + + # Coldest first. + candidates.sort(key=lambda c: c.score) + + logger.info( + f"[MemoryArchiver] Scanned {total_scanned} memories under {scope_uri}, " + f"found {len(candidates)} archival candidates (threshold={self.threshold})" + ) + return candidates + + async def archive( + self, + candidates: List[ArchivalCandidate], + ctx: Optional[RequestContext] = None, + dry_run: bool = False, + ) -> ArchivalResult: + """Archive the given candidates. + + Moves each candidate to ``{parent}/_archive/{filename}`` using + ``viking_fs.mv()``, which atomically updates the vector index. + + Args: + candidates: Output of ``scan()``. + ctx: Request context for tenant isolation. + dry_run: If True, log what would happen without moving files. + + Returns: + Summary of the operation. + """ + result = ArchivalResult(scanned=len(candidates), candidates=candidates) + + for candidate in candidates: + archive_uri = _build_archive_uri(candidate.uri) + + if dry_run: + logger.info( + f"[MemoryArchiver] DRY-RUN would archive {candidate.uri} " + f"(score={candidate.score:.4f}) -> {archive_uri}" + ) + result.skipped += 1 + continue + + try: + await self.viking_fs.mv(candidate.uri, archive_uri, ctx=ctx) + result.archived += 1 + logger.info( + f"[MemoryArchiver] Archived {candidate.uri} " + f"(score={candidate.score:.4f}) -> {archive_uri}" + ) + except Exception: + logger.exception(f"[MemoryArchiver] Failed to archive {candidate.uri}") + result.errors += 1 + + logger.info( + f"[MemoryArchiver] Archive complete: " + f"{result.archived} archived, {result.skipped} skipped, " + f"{result.errors} errors" + ) + return result + + async def restore( + self, + archived_uri: str, + ctx: Optional[RequestContext] = None, + ) -> bool: + """Restore an archived memory to its original location. + + The original location is derived by removing the ``_archive/`` + path segment from the URI. + + Args: + archived_uri: URI of the archived memory. + ctx: Request context for tenant isolation. + + Returns: + True if the memory was restored successfully. + """ + original_uri = _build_restore_uri(archived_uri) + if original_uri is None: + logger.warning( + f"[MemoryArchiver] Cannot restore {archived_uri}: not in an archive directory" + ) + return False + + try: + await self.viking_fs.mv(archived_uri, original_uri, ctx=ctx) + logger.info(f"[MemoryArchiver] Restored {archived_uri} -> {original_uri}") + return True + except Exception: + logger.exception(f"[MemoryArchiver] Failed to restore {archived_uri}") + return False + + async def scan_and_archive( + self, + scope_uri: str, + ctx: Optional[RequestContext] = None, + dry_run: bool = False, + now: Optional[datetime] = None, + ) -> ArchivalResult: + """Convenience method: scan then archive in one call.""" + candidates = await self.scan(scope_uri, ctx=ctx, now=now) + return await self.archive(candidates, ctx=ctx, dry_run=dry_run) + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _build_archive_uri(uri: str) -> str: + """Insert ``_archive/`` before the filename in a URI. + + ``viking://memories/facts/greeting.md`` + -> ``viking://memories/facts/_archive/greeting.md`` + """ + last_slash = uri.rfind("/") + if last_slash == -1: + return f"{ARCHIVE_DIR}/{uri}" + parent = uri[:last_slash] + filename = uri[last_slash + 1 :] + return f"{parent}/{ARCHIVE_DIR}/{filename}" + + +def _build_restore_uri(archived_uri: str) -> Optional[str]: + """Remove the ``_archive/`` segment to recover the original URI. + + ``viking://memories/facts/_archive/greeting.md`` + -> ``viking://memories/facts/greeting.md`` + + Returns None if the URI does not contain ``_archive/``. + """ + marker = f"/{ARCHIVE_DIR}/" + idx = archived_uri.find(marker) + if idx == -1: + return None + parent = archived_uri[:idx] + filename = archived_uri[idx + len(marker) :] + return f"{parent}/{filename}" + + +def _parse_datetime(value: Any) -> Optional[datetime]: + """Best-effort parse of a datetime value from the vector store.""" + if value is None: + return None + if isinstance(value, datetime): + if value.tzinfo is None: + return value.replace(tzinfo=timezone.utc) + return value + if isinstance(value, str): + try: + return parse_iso_datetime(value) + except Exception: + return None + return None diff --git a/openviking/session/memory_deduplicator.py b/openviking/session/memory_deduplicator.py index c119ecb8..f88775d8 100644 --- a/openviking/session/memory_deduplicator.py +++ b/openviking/session/memory_deduplicator.py @@ -7,6 +7,7 @@ per-existing merge/delete actions. """ +import copy import re from dataclasses import dataclass from enum import Enum @@ -15,7 +16,9 @@ from openviking.core.context import Context from openviking.models.embedder.base import EmbedResult from openviking.prompts import render_prompt +from openviking.server.identity import RequestContext from openviking.storage import VikingDBManager +from openviking.telemetry import get_current_telemetry from openviking_cli.utils import get_logger from openviking_cli.utils.config import get_openviking_config @@ -57,6 +60,7 @@ class DedupResult: similar_memories: List[Context] # Similar existing memories actions: Optional[List[ExistingMemoryAction]] = None reason: str = "" + query_vector: list[float] | None = None # For batch-internal dedup tracking class MemoryDeduplicator: @@ -83,15 +87,21 @@ def __init__( ): """Initialize deduplicator.""" self.vikingdb = vikingdb - self.embedder = self.vikingdb.get_embedder() + config = get_openviking_config() + self.embedder = config.embedding.get_embedder() async def deduplicate( self, candidate: CandidateMemory, + ctx: RequestContext, + *, + batch_memories: list[tuple[list[float], Context]] | None = None, ) -> DedupResult: """Decide how to handle a candidate memory.""" # Step 1: Vector pre-filtering - find similar memories in same category - similar_memories = await self._find_similar_memories(candidate) + similar_memories, query_vector = await self._find_similar_memories( + candidate, ctx=ctx, batch_memories=batch_memories + ) if not similar_memories: # No similar memories, create directly @@ -101,6 +111,7 @@ async def deduplicate( similar_memories=[], actions=[], reason="No similar memories found", + query_vector=query_vector, ) # Step 2: LLM decision @@ -112,25 +123,35 @@ async def deduplicate( similar_memories=similar_memories, actions=None if decision == DedupDecision.SKIP else actions, reason=reason, + query_vector=query_vector, ) async def _find_similar_memories( self, candidate: CandidateMemory, - ) -> List[Context]: - """Find similar existing memories using vector search.""" + ctx: RequestContext, + *, + batch_memories: list[tuple[list[float], Context]] | None = None, + ) -> tuple[list[Context], list[float]]: + """Find similar existing memories using vector search. + + Returns (similar_memories, query_vector). query_vector is the candidate's + embedding, returned so the caller can store it for batch-internal tracking. + """ + telemetry = get_current_telemetry() + query_vector: list[float] = [] # Initialize early for safe returns + if not self.embedder: - return [] + return [], query_vector # Generate embedding for candidate query_text = f"{candidate.abstract} {candidate.content}" - embed_result: EmbedResult = self.embedder.embed(query_text) + embed_result: EmbedResult = self.embedder.embed(query_text, is_query=True) query_vector = embed_result.dense_vector category_uri_prefix = self._category_uri_prefix(candidate.category.value, candidate.user) owner = candidate.user - account_id = owner.account_id if hasattr(owner, "account_id") else "default" owner_space = None if owner and hasattr(owner, "user_space_name"): owner_space = ( @@ -139,9 +160,8 @@ async def _find_similar_memories( else owner.user_space_name() ) logger.debug( - "Dedup prefilter candidate category=%s account=%s owner_space=%s uri_prefix=%s", + "Dedup prefilter candidate category=%s owner_space=%s uri_prefix=%s", candidate.category.value, - account_id, owner_space, category_uri_prefix, ) @@ -149,12 +169,15 @@ async def _find_similar_memories( try: # Search with memory-scope filter. results = await self.vikingdb.search_similar_memories( - account_id=account_id, owner_space=owner_space, category_uri_prefix=category_uri_prefix, query_vector=query_vector, limit=5, + ctx=ctx, ) + telemetry.count("vector.searches", 1) + telemetry.count("vector.scored", len(results)) + telemetry.count("vector.scanned", len(results)) # Filter by similarity threshold similar = [] @@ -172,6 +195,7 @@ async def _find_similar_memories( result.get("abstract", ""), ) if score >= self.SIMILARITY_THRESHOLD: + telemetry.count("vector.passed", 1) # Reconstruct Context object context = Context.from_dict(result) if context: @@ -179,11 +203,27 @@ async def _find_similar_memories( context.meta = {**(context.meta or {}), "_dedup_score": score} similar.append(context) logger.debug("Dedup similar memories after threshold=%d", len(similar)) - return similar + + # Include batch-internal memories that are similar (#687). + # Shallow-copy to avoid mutating the original's meta while + # preserving all fields (account_id, owner_space, etc.) needed + # downstream if the LLM decides to MERGE into this memory. + if batch_memories: + seen_uris = {c.uri for c in similar} + for batch_vec, batch_ctx in batch_memories: + if batch_ctx.uri in seen_uris: + continue + score = self._cosine_similarity(query_vector, batch_vec) + if score >= self.SIMILARITY_THRESHOLD: + ctx_copy = copy.copy(batch_ctx) + ctx_copy.meta = {**(batch_ctx.meta or {}), "_dedup_score": score} + similar.append(ctx_copy) + + return similar, query_vector except Exception as e: logger.warning(f"Vector search failed: {e}") - return [] + return [], query_vector async def _llm_decision( self, diff --git a/openviking/session/memory_extractor.py b/openviking/session/memory_extractor.py index cf9ba87c..99d4a121 100644 --- a/openviking/session/memory_extractor.py +++ b/openviking/session/memory_extractor.py @@ -161,7 +161,13 @@ def _detect_output_language(messages: List, fallback_language: str = "en") -> st if not user_text: return fallback - # Detect scripts that are largely language-unique first. + # Detect scripts that are largely language-unique. + # Require threshold to avoid misclassifying mixed-language texts + # (e.g., Chinese with a single Cyrillic letter). + total_chars = len(re.findall(r"\S", user_text)) + if total_chars == 0: + return fallback + counts = { "ko": len(re.findall(r"[\uac00-\ud7af]", user_text)), "ru": len(re.findall(r"[\u0400-\u04ff]", user_text)), @@ -169,7 +175,8 @@ def _detect_output_language(messages: List, fallback_language: str = "en") -> st } detected, score = max(counts.items(), key=lambda item: item[1]) - if score > 0: + # Threshold: at least 2 chars AND at least 10% of non-whitespace chars + if score >= 2 and score / total_chars >= 0.10: return detected # CJK disambiguation: @@ -219,8 +226,14 @@ async def extract( context: dict, user: UserIdentifier, session_id: str, + *, + strict: bool = False, ) -> List[CandidateMemory]: - """Extract memory candidates from messages.""" + """Extract memory candidates from messages. + + When ``strict`` is True, extraction failures are re-raised as + ``RuntimeError`` so async task tracking can mark tasks as failed. + """ user = user vlm = get_openviking_config().vlm if not vlm or not vlm.is_available(): @@ -288,10 +301,19 @@ async def extract( response = await vlm.get_completion_async(prompt) logger.debug("Memory extraction LLM raw response: %s", response) data = parse_json_from_response(response) or {} + if isinstance(data, list): + logger.warning( + "Memory extraction received list instead of dict; wrapping as memories" + ) + data = {"memories": data} + elif not isinstance(data, dict): + logger.warning( + "Memory extraction received unexpected type %s; skipping", type(data).__name__ + ) + data = {} logger.debug("Memory extraction LLM parsed payload: %s", data) candidates = [] - # print(f"memories = {data.get('memories', [])}") for mem in data.get("memories", []): category_str = mem.get("category", "patterns") try: @@ -383,8 +405,19 @@ async def extract( except Exception as e: logger.error(f"Memory extraction failed: {e}") + if strict: + raise RuntimeError(f"memory_extraction_failed: {e}") from e return [] + async def extract_strict( + self, + context: dict, + user: UserIdentifier, + session_id: str, + ) -> List[CandidateMemory]: + """Compatibility wrapper: strict mode delegates to ``extract``.""" + return await self.extract(context, user, session_id, strict=True) + async def create_memory( self, candidate: CandidateMemory, @@ -694,28 +727,6 @@ async def _merge_tool_memory( await viking_fs.write_file(uri=uri, content=merged_content, ctx=ctx) return self._create_tool_context(uri, candidate, ctx, abstract_override=abstract_override) - async def _enqueue_semantic_for_parent(self, file_uri: str, ctx: "RequestContext") -> None: - """Enqueue semantic generation for parent directory.""" - try: - from openviking.storage.queuefs import get_queue_manager - from openviking.storage.queuefs.semantic_msg import SemanticMsg - - parent_uri = "/".join(file_uri.rsplit("/", 1)[:-1]) - queue_manager = get_queue_manager() - semantic_queue = queue_manager.get_queue(queue_manager.SEMANTIC, allow_create=True) - msg = SemanticMsg( - uri=parent_uri, - context_type="memory", - account_id=ctx.account_id, - user_id=ctx.user.user_id, - agent_id=ctx.user.agent_id, - role=ctx.role.value, - ) - await semantic_queue.enqueue(msg) - logger.debug(f"Enqueued semantic generation for: {parent_uri}") - except Exception as e: - logger.warning(f"Failed to enqueue semantic generation for {file_uri}: {e}") - def _compute_statistics_derived(self, stats: dict) -> dict: """计算派生统计数据(平均值、成功率)""" if stats["total_calls"] > 0: diff --git a/openviking/session/session.py b/openviking/session/session.py index 243069a1..bdb6500b 100644 --- a/openviking/session/session.py +++ b/openviking/session/session.py @@ -14,6 +14,7 @@ from openviking.message import Message, Part from openviking.server.identity import RequestContext, Role +from openviking.telemetry import get_current_telemetry from openviking.utils.time_utils import get_current_timestamp from openviking_cli.session.user_id import UserIdentifier from openviking_cli.utils import get_logger, run_async @@ -219,83 +220,19 @@ def update_tool_part( self._update_message_in_jsonl() def commit(self) -> Dict[str, Any]: - """Commit session: create archive, extract memories, persist.""" - result = { - "session_id": self.session_id, - "status": "committed", - "memories_extracted": 0, - "active_count_updated": 0, - "archived": False, - "stats": None, - } - if not self._messages: - return result - - # 1. Archive current messages - self._compression.compression_index += 1 - messages_to_archive = self._messages.copy() + """Sync wrapper for commit_async().""" + return run_async(self.commit_async()) - summary = self._generate_archive_summary(messages_to_archive) - archive_abstract = self._extract_abstract_from_summary(summary) - archive_overview = summary - - self._write_archive( - index=self._compression.compression_index, - messages=messages_to_archive, - abstract=archive_abstract, - overview=archive_overview, - ) - - self._compression.original_count += len(messages_to_archive) - result["archived"] = True - - self._messages.clear() - logger.info( - f"Archived: {len(messages_to_archive)} messages → history/archive_{self._compression.compression_index:03d}/" - ) - - # 2. Extract long-term memories - if self._session_compressor: - logger.info( - f"Starting memory extraction from {len(messages_to_archive)} archived messages" - ) - memories = run_async( - self._session_compressor.extract_long_term_memories( - messages=messages_to_archive, - user=self.user, - session_id=self.session_id, - ctx=self.ctx, - ) - ) - logger.info(f"Extracted {len(memories)} memories") - result["memories_extracted"] = len(memories) - self._stats.memories_extracted += len(memories) - - # 3. Write current messages to AGFS - self._write_to_agfs(self._messages) - - # 4. Create relations - self._write_relations() - - # 5. Update active_count - active_count_updated = self._update_active_counts() - result["active_count_updated"] = active_count_updated + async def commit_async(self) -> Dict[str, Any]: + """Async commit session: two-phase approach. - # 6. Update statistics - self._stats.compression_count = self._compression.compression_index - result["stats"] = { - "total_turns": self._stats.total_turns, - "contexts_used": self._stats.contexts_used, - "skills_used": self._stats.skills_used, - "memories_extracted": self._stats.memories_extracted, - } + Phase 1 (Archive): Write archive, clear messages. + Phase 2 (Memory, redo-log protected): Extract memories, write, enqueue. + """ + import uuid - self._stats.total_tokens = 0 - logger.info(f"Session {self.session_id} committed") - return result + from openviking.storage.transaction import get_lock_manager - async def commit_async(self) -> Dict[str, Any]: - """Async commit session: create archive, extract memories, persist.""" result = { "session_id": self.session_id, "status": "committed", @@ -305,9 +242,10 @@ async def commit_async(self) -> Dict[str, Any]: "stats": None, } if not self._messages: + get_current_telemetry().set("memory.extracted", 0) return result - # 1. Archive current messages + # ===== Preparation ===== self._compression.compression_index += 1 messages_to_archive = self._messages.copy() @@ -315,22 +253,41 @@ async def commit_async(self) -> Dict[str, Any]: archive_abstract = self._extract_abstract_from_summary(summary) archive_overview = summary + # ===== Phase 1: Archive (no lock) ===== + archive_uri = ( + f"{self._session_uri}/history/archive_{self._compression.compression_index:03d}" + ) await self._write_archive_async( index=self._compression.compression_index, messages=messages_to_archive, abstract=archive_abstract, overview=archive_overview, ) + await self._write_to_agfs_async(messages=[]) + self._messages.clear() self._compression.original_count += len(messages_to_archive) result["archived"] = True - - self._messages.clear() logger.info( - f"Archived: {len(messages_to_archive)} messages → history/archive_{self._compression.compression_index:03d}/" + f"Archived: {len(messages_to_archive)} messages → " + f"history/archive_{self._compression.compression_index:03d}/" + ) + + # ===== Phase 2: Memory extraction + write (redo-log protected) ===== + redo_log = get_lock_manager().redo_log + task_id = str(uuid.uuid4()) + redo_log.write_pending( + task_id, + { + "archive_uri": archive_uri, + "session_uri": self._session_uri, + "account_id": self.ctx.account_id, + "user_id": self.ctx.user.user_id, + "agent_id": self.ctx.user.agent_id, + "role": self.ctx.role.value, + }, ) - # 2. Extract long-term memories if self._session_compressor: logger.info( f"Starting memory extraction from {len(messages_to_archive)} archived messages" @@ -344,18 +301,35 @@ async def commit_async(self) -> Dict[str, Any]: logger.info(f"Extracted {len(memories)} memories") result["memories_extracted"] = len(memories) self._stats.memories_extracted += len(memories) + get_current_telemetry().set("memory.extracted", len(memories)) - # 3. Write current messages to AGFS await self._write_to_agfs_async(self._messages) - - # 4. Create relations await self._write_relations_async() - # 5. Update active_count + # Enqueue semantic processing directly + from openviking.storage.queuefs import get_queue_manager + from openviking.storage.queuefs.semantic_msg import SemanticMsg + + queue_manager = get_queue_manager() + if queue_manager: + msg = SemanticMsg( + uri=self._session_uri, + context_type="memory", + account_id=self.ctx.account_id, + user_id=self.ctx.user.user_id, + agent_id=self.ctx.user.agent_id, + role=self.ctx.role.value, + ) + semantic_queue = queue_manager.get_queue(queue_manager.SEMANTIC) + await semantic_queue.enqueue(msg) + + redo_log.mark_done(task_id) + + # Update active_count active_count_updated = await self._update_active_counts_async() result["active_count_updated"] = active_count_updated - # 6. Update statistics + # Update statistics self._stats.compression_count = self._compression.compression_index result["stats"] = { "total_turns": self._stats.total_turns, diff --git a/openviking/storage/__init__.py b/openviking/storage/__init__.py index ac4cd8d5..752fc3d8 100644 --- a/openviking/storage/__init__.py +++ b/openviking/storage/__init__.py @@ -14,7 +14,7 @@ from openviking.storage.queuefs import QueueManager, get_queue_manager, init_queue_manager from openviking.storage.viking_fs import VikingFS, get_viking_fs, init_viking_fs from openviking.storage.viking_vector_index_backend import VikingVectorIndexBackend -from openviking.storage.vikingdb_manager import VikingDBManager +from openviking.storage.vikingdb_manager import VikingDBManager, VikingDBManagerProxy __all__ = [ # Exceptions @@ -27,6 +27,7 @@ # Backend "VikingVectorIndexBackend", "VikingDBManager", + "VikingDBManagerProxy", # QueueFS "QueueManager", "init_queue_manager", diff --git a/openviking/storage/collection_schemas.py b/openviking/storage/collection_schemas.py index 90c61d07..590ad685 100644 --- a/openviking/storage/collection_schemas.py +++ b/openviking/storage/collection_schemas.py @@ -10,19 +10,32 @@ import asyncio import hashlib import json -from typing import Any, Dict, Optional +import threading +from contextlib import nullcontext +from dataclasses import dataclass +from typing import Any, Dict, List, Optional from openviking.models.embedder.base import EmbedResult +from openviking.models.embedder.volcengine_embedders import is_429_error +from openviking.server.identity import RequestContext, Role from openviking.storage.errors import CollectionNotFoundError from openviking.storage.queuefs.embedding_msg import EmbeddingMsg from openviking.storage.queuefs.named_queue import DequeueHandlerBase from openviking.storage.viking_vector_index_backend import VikingVectorIndexBackend +from openviking.telemetry import bind_telemetry, resolve_telemetry +from openviking_cli.session.user_id import UserIdentifier from openviking_cli.utils import get_logger from openviking_cli.utils.config.open_viking_config import OpenVikingConfig logger = get_logger(__name__) +@dataclass +class RequestQueueStats: + processed: int = 0 + error_count: int = 0 + + class CollectionSchemas: """ Centralized collection schema definitions. @@ -111,8 +124,11 @@ async def init_context_collection(storage) -> bool: config = get_openviking_config() name = config.storage.vectordb.name vector_dim = config.embedding.dimension - schema = CollectionSchemas.context_collection(name, vector_dim) - return await storage.create_collection(name, schema) + if not name: + raise ValueError("Vector DB collection name is required") + collection_name = name + schema = CollectionSchemas.context_collection(collection_name, vector_dim) + return await storage.create_collection(collection_name, schema) class TextEmbeddingHandler(DequeueHandlerBase): @@ -127,6 +143,11 @@ class TextEmbeddingHandler(DequeueHandlerBase): Supports both dense and sparse embeddings based on configuration. """ + _request_stats_lock = threading.Lock() + _request_stats_by_telemetry_id: Dict[str, RequestQueueStats] = {} + _request_stats_order: List[str] = [] + _max_cached_stats = 1024 + def __init__(self, vikingdb: VikingVectorIndexBackend): """Initialize the text embedding handler. @@ -146,6 +167,32 @@ def _initialize_embedder(self, config: "OpenVikingConfig"): """Initialize the embedder instance from config.""" self._embedder = config.embedding.get_embedder() + @classmethod + def _merge_request_stats( + cls, telemetry_id: str, processed: int = 0, error_count: int = 0 + ) -> None: + if not telemetry_id: + return + with cls._request_stats_lock: + stats = cls._request_stats_by_telemetry_id.setdefault(telemetry_id, RequestQueueStats()) + stats.processed += processed + stats.error_count += error_count + cls._request_stats_order.append(telemetry_id) + if len(cls._request_stats_order) > cls._max_cached_stats: + old_telemetry_id = cls._request_stats_order.pop(0) + if ( + old_telemetry_id != telemetry_id + and old_telemetry_id in cls._request_stats_by_telemetry_id + ): + cls._request_stats_by_telemetry_id.pop(old_telemetry_id, None) + + @classmethod + def consume_request_stats(cls, telemetry_id: str) -> Optional[RequestQueueStats]: + if not telemetry_id: + return None + with cls._request_stats_lock: + return cls._request_stats_by_telemetry_id.pop(telemetry_id, None) + @staticmethod def _seed_uri_for_id(uri: str, level: Any) -> str: """Build deterministic id seed URI from canonical uri + hierarchy level.""" @@ -165,101 +212,153 @@ async def on_dequeue(self, data: Optional[Dict[str, Any]]) -> Optional[Dict[str, if not data: return None + embedding_msg: Optional[EmbeddingMsg] = None + collector = None try: queue_data = json.loads(data["data"]) # Parse EmbeddingMsg from data embedding_msg = EmbeddingMsg.from_dict(queue_data) inserted_data = embedding_msg.context_data + collector = resolve_telemetry(embedding_msg.telemetry_id) + telemetry_ctx = bind_telemetry(collector) if collector is not None else nullcontext() - if self._vikingdb.is_closing: - logger.debug("Skip embedding dequeue during shutdown") - self.report_success() - return None + with telemetry_ctx: + if self._vikingdb.is_closing: + logger.debug("Skip embedding dequeue during shutdown") + self._merge_request_stats(embedding_msg.telemetry_id, processed=1) + self.report_success() + return None - # Only process string messages - if not isinstance(embedding_msg.message, str): - logger.debug(f"Skipping non-string message type: {type(embedding_msg.message)}") - self.report_success() - return data - - # Initialize embedder if not already initialized - if not self._embedder: - from openviking_cli.utils.config import get_openviking_config - - config = get_openviking_config() - self._initialize_embedder(config) - - # Generate embedding vector(s) - if self._embedder: - # embed() is a blocking HTTP call; offload to thread pool to avoid - # blocking the event loop and allow real concurrency. - result: EmbedResult = await asyncio.to_thread( - self._embedder.embed, embedding_msg.message - ) - - # Add dense vector - if result.dense_vector: - inserted_data["vector"] = result.dense_vector - # Validate vector dimension - if len(result.dense_vector) != self._vector_dim: - error_msg = f"Dense vector dimension mismatch: expected {self._vector_dim}, got {len(result.dense_vector)}" + # Only process string messages + if not isinstance(embedding_msg.message, str): + logger.debug(f"Skipping non-string message type: {type(embedding_msg.message)}") + self._merge_request_stats(embedding_msg.telemetry_id, processed=1) + self.report_success() + return data + + # Initialize embedder if not already initialized + if not self._embedder: + from openviking_cli.utils.config import get_openviking_config + + config = get_openviking_config() + self._initialize_embedder(config) + + # Generate embedding vector(s) + if self._embedder: + try: + # embed() is a blocking HTTP call; offload to thread pool to avoid + # blocking the event loop and allow real concurrency. + result: EmbedResult = await asyncio.to_thread( + self._embedder.embed, embedding_msg.message + ) + except Exception as embed_err: + error_msg = f"Failed to generate embedding: {embed_err}" logger.error(error_msg) + + if is_429_error(embed_err) and self._vikingdb.has_queue_manager: + try: + await self._vikingdb.enqueue_embedding_msg(embedding_msg) + logger.info( + f"Re-enqueued embedding message after rate limit: {embedding_msg.id}" + ) + self.report_success() + return None + except Exception as requeue_err: + logger.error(f"Failed to re-enqueue message: {requeue_err}") + + self._merge_request_stats(embedding_msg.telemetry_id, error_count=1) self.report_error(error_msg, data) return None - # Add sparse vector if present - if result.sparse_vector: - inserted_data["sparse_vector"] = result.sparse_vector - logger.debug(f"Generated sparse vector with {len(result.sparse_vector)} terms") - else: - error_msg = "Embedder not initialized, skipping vector generation" - logger.warning(error_msg) - self.report_error(error_msg, data) - return None - - # Write to vector database - try: - # Ensure vector DB has deterministic IDs per semantic layer. - uri = inserted_data.get("uri") - if uri: + # Add dense vector + if result.dense_vector: + inserted_data["vector"] = result.dense_vector + # Validate vector dimension + if len(result.dense_vector) != self._vector_dim: + error_msg = f"Dense vector dimension mismatch: expected {self._vector_dim}, got {len(result.dense_vector)}" + logger.error(error_msg) + self._merge_request_stats(embedding_msg.telemetry_id, error_count=1) + self.report_error(error_msg, data) + return None + + # Add sparse vector if present + if result.sparse_vector: + inserted_data["sparse_vector"] = result.sparse_vector + logger.debug( + f"Generated sparse vector with {len(result.sparse_vector)} terms" + ) + else: + error_msg = "Embedder not initialized, skipping vector generation" + logger.warning(error_msg) + self._merge_request_stats(embedding_msg.telemetry_id, error_count=1) + self.report_error(error_msg, data) + return None + + # Write to vector database + try: + # Ensure vector DB has deterministic IDs per semantic layer. + uri = inserted_data.get("uri") account_id = inserted_data.get("account_id", "default") - seed_uri = self._seed_uri_for_id(uri, inserted_data.get("level", 2)) - id_seed = f"{account_id}:{seed_uri}" - inserted_data["id"] = hashlib.md5(id_seed.encode("utf-8")).hexdigest() - - record_id = await self._vikingdb.upsert(inserted_data) - if record_id: - logger.debug( - f"Successfully wrote embedding to database: {record_id} abstract {inserted_data['abstract']} vector {inserted_data['vector'][:5]}" + if uri: + seed_uri = self._seed_uri_for_id(uri, inserted_data.get("level", 2)) + id_seed = f"{account_id}:{seed_uri}" + inserted_data["id"] = hashlib.md5(id_seed.encode("utf-8")).hexdigest() + + user = UserIdentifier( + account_id=account_id, + user_id="default", + agent_id="default", ) - except CollectionNotFoundError as db_err: - # During shutdown, queue workers may finish one dequeued item. - if self._vikingdb.is_closing: - logger.debug(f"Skip embedding write during shutdown: {db_err}") - self.report_success() - return None - logger.error(f"Failed to write to vector database: {db_err}") - self.report_error(str(db_err), data) - return None - except Exception as db_err: - if self._vikingdb.is_closing: - logger.debug(f"Skip embedding write during shutdown: {db_err}") - self.report_success() + ctx = RequestContext(user=user, role=Role.ROOT) + record_id = await self._vikingdb.upsert(inserted_data, ctx=ctx) + if record_id: + logger.debug( + f"Successfully wrote embedding to database: {record_id} abstract {inserted_data['abstract']} vector {inserted_data['vector'][:5]}" + ) + except CollectionNotFoundError as db_err: + # During shutdown, queue workers may finish one dequeued item. + if self._vikingdb.is_closing: + logger.debug(f"Skip embedding write during shutdown: {db_err}") + self._merge_request_stats(embedding_msg.telemetry_id, processed=1) + self.report_success() + return None + logger.error(f"Failed to write to vector database: {db_err}") + self._merge_request_stats(embedding_msg.telemetry_id, error_count=1) + self.report_error(str(db_err), data) return None - logger.error(f"Failed to write to vector database: {db_err}") - import traceback + except Exception as db_err: + if self._vikingdb.is_closing: + logger.debug(f"Skip embedding write during shutdown: {db_err}") + self._merge_request_stats(embedding_msg.telemetry_id, processed=1) + self.report_success() + return None + logger.error(f"Failed to write to vector database: {db_err}") + import traceback - traceback.print_exc() - self.report_error(str(db_err), data) - return None + traceback.print_exc() + self._merge_request_stats(embedding_msg.telemetry_id, error_count=1) + self.report_error(str(db_err), data) + return None - self.report_success() - return inserted_data + self._merge_request_stats(embedding_msg.telemetry_id, processed=1) + self.report_success() + return inserted_data except Exception as e: logger.error(f"Error processing embedding message: {e}") import traceback traceback.print_exc() + if embedding_msg is not None: + self._merge_request_stats(embedding_msg.telemetry_id, error_count=1) self.report_error(str(e), data) return None + finally: + if embedding_msg and embedding_msg.semantic_msg_id: + from openviking.storage.queuefs.embedding_tracker import EmbeddingTaskTracker + + tracker = EmbeddingTaskTracker.get_instance() + try: + await tracker.decrement(embedding_msg.semantic_msg_id) + except Exception as tracker_err: + logger.warning(f"Failed to decrement embedding tracker: {tracker_err}") diff --git a/openviking/storage/errors.py b/openviking/storage/errors.py index bc3e36be..def786be 100644 --- a/openviking/storage/errors.py +++ b/openviking/storage/errors.py @@ -29,3 +29,15 @@ class ConnectionError(StorageException): class SchemaError(StorageException): """Raised when schema validation fails.""" + + +class LockError(VikingDBException): + """Raised when a lock operation fails.""" + + +class LockAcquisitionError(LockError): + """Raised when lock acquisition fails.""" + + +class ResourceBusyError(LockError): + """Raised when a resource is locked by an ongoing operation (e.g. semantic processing).""" diff --git a/openviking/storage/local_fs.py b/openviking/storage/local_fs.py index 0181c873..3d23566d 100644 --- a/openviking/storage/local_fs.py +++ b/openviking/storage/local_fs.py @@ -11,6 +11,7 @@ from openviking.server.identity import RequestContext from openviking.storage.queuefs import EmbeddingQueue, get_queue_manager from openviking.storage.queuefs.embedding_msg_converter import EmbeddingMsgConverter +from openviking_cli.exceptions import NotFoundError from openviking_cli.utils.logger import get_logger from openviking_cli.utils.uri import VikingURI @@ -162,6 +163,8 @@ async def import_ovpack( # Extract root directory name (assuming first path component is root name) first_path = infolist[0].filename + # Normalize path separators to handle Windows-created ZIPs + first_path = first_path.replace("\\", "/") base_name = first_path.split("/")[0] if not base_name: raise ValueError("Could not determine root directory name from ovpack") @@ -176,7 +179,7 @@ async def import_ovpack( f"Resource already exists at {root_uri}. Use force=True to overwrite." ) logger.info(f"[local_fs] Overwriting existing resource at {root_uri}") - except FileNotFoundError: + except NotFoundError: # Path does not exist, safe to import pass @@ -202,7 +205,10 @@ async def import_ovpack( if not zip_path: continue + # Validate before normalization so backslash paths are rejected safe_zip_path = _validate_ovpack_member_path(zip_path, base_name) + # Normalize path separators to handle Windows-created ZIPs + safe_zip_path = safe_zip_path.replace("\\", "/") # Handle directory entries if safe_zip_path.endswith("/"): diff --git a/openviking/storage/observers/__init__.py b/openviking/storage/observers/__init__.py index a0d3ece5..dae5aed3 100644 --- a/openviking/storage/observers/__init__.py +++ b/openviking/storage/observers/__init__.py @@ -1,15 +1,17 @@ # Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. # SPDX-License-Identifier: Apache-2.0 from .base_observer import BaseObserver +from .lock_observer import LockObserver from .queue_observer import QueueObserver -from .transaction_observer import TransactionObserver +from .retrieval_observer import RetrievalObserver from .vikingdb_observer import VikingDBObserver from .vlm_observer import VLMObserver __all__ = [ "BaseObserver", + "LockObserver", "QueueObserver", - "TransactionObserver", + "RetrievalObserver", "VikingDBObserver", "VLMObserver", ] diff --git a/openviking/storage/observers/lock_observer.py b/openviking/storage/observers/lock_observer.py new file mode 100644 index 00000000..92521790 --- /dev/null +++ b/openviking/storage/observers/lock_observer.py @@ -0,0 +1,71 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""LockObserver: Lock system observability.""" + +import time +from typing import Any, Dict, List + +from openviking.storage.observers.base_observer import BaseObserver +from openviking.storage.transaction.lock_manager import LockManager +from openviking_cli.utils.logger import get_logger + +logger = get_logger(__name__) + + +class LockObserver(BaseObserver): + """Observability tool for the lock system.""" + + def __init__(self, lock_manager: LockManager): + self._manager = lock_manager + + def get_active_locks(self) -> List[Dict[str, Any]]: + """Return info about every active lock handle.""" + now = time.time() + return [ + { + "id": h.id, + "lock_count": len(h.locks), + "created_at": h.created_at, + "duration_seconds": round(now - h.created_at, 1), + } + for h in self._manager.get_active_handles().values() + ] + + def get_hanging_locks(self, threshold: float = 600) -> List[Dict[str, Any]]: + """Return locks that have been held longer than *threshold* seconds.""" + now = time.time() + return [lock for lock in self.get_active_locks() if now - lock["created_at"] > threshold] + + # ------ BaseObserver interface ------ + + def get_status_table(self) -> str: + locks = self.get_active_locks() + if not locks: + return "No active locks." + + from tabulate import tabulate + + data = [ + { + "Handle ID": l["id"][:8] + "...", + "Locks": l["lock_count"], + "Duration": f"{l['duration_seconds']}s", + "Created": time.strftime("%H:%M:%S", time.localtime(l["created_at"])), + } + for l in locks + ] + data.append( + { + "Handle ID": f"TOTAL ({len(locks)})", + "Locks": sum(l["lock_count"] for l in locks), + "Duration": "", + "Created": "", + } + ) + return tabulate(data, headers="keys", tablefmt="pretty") + + def is_healthy(self) -> bool: + return not self.get_hanging_locks(600) + + def has_errors(self) -> bool: + return bool(self.get_hanging_locks(600)) diff --git a/openviking/storage/observers/retrieval_observer.py b/openviking/storage/observers/retrieval_observer.py new file mode 100644 index 00000000..a3a79a74 --- /dev/null +++ b/openviking/storage/observers/retrieval_observer.py @@ -0,0 +1,99 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +""" +RetrievalObserver: Retrieval system observability tool. + +Provides methods to observe and report retrieval quality metrics +accumulated by the HierarchicalRetriever. +""" + +from openviking.storage.observers.base_observer import BaseObserver +from openviking_cli.utils.logger import get_logger + +logger = get_logger(__name__) + + +class RetrievalObserver(BaseObserver): + """ + RetrievalObserver: System observability tool for retrieval quality. + + Reads accumulated statistics from the global RetrievalStatsCollector + and formats them for display via the observer API. + """ + + # A zero-result rate above this threshold is considered unhealthy. + UNHEALTHY_ZERO_RESULT_RATE = 0.5 + + @staticmethod + def _get_collector(): + """Lazy import to avoid circular dependency with storage module.""" + from openviking.retrieve.retrieval_stats import get_stats_collector + + return get_stats_collector() + + def get_status_table(self) -> str: + """Format retrieval statistics as a string table.""" + return self._format_status_as_table() + + def _format_status_as_table(self) -> str: + """Format retrieval stats as a table using tabulate.""" + from tabulate import tabulate + + stats = self._get_collector().snapshot() + + if stats.total_queries == 0: + return "No retrieval queries recorded." + + summary = [ + {"Metric": "Total Queries", "Value": stats.total_queries}, + {"Metric": "Total Results", "Value": stats.total_results}, + {"Metric": "Avg Results/Query", "Value": f"{stats.avg_results_per_query:.1f}"}, + {"Metric": "Zero-Result Queries", "Value": stats.zero_result_queries}, + { + "Metric": "Zero-Result Rate", + "Value": f"{stats.zero_result_rate:.1%}", + }, + {"Metric": "Avg Score", "Value": f"{stats.avg_score:.4f}"}, + { + "Metric": "Score Range", + "Value": f"{stats.min_score:.4f} - {stats.max_score:.4f}" + if stats.total_results > 0 + else "N/A", + }, + {"Metric": "Rerank Used", "Value": stats.rerank_used}, + {"Metric": "Rerank Fallback", "Value": stats.rerank_fallback}, + {"Metric": "Avg Latency (ms)", "Value": f"{stats.avg_latency_ms:.1f}"}, + {"Metric": "Max Latency (ms)", "Value": f"{stats.max_latency_ms:.1f}"}, + ] + + lines = [tabulate(summary, headers="keys", tablefmt="pretty")] + + # Query breakdown by context type + if stats.queries_by_type: + type_data = [ + {"Context Type": ctype, "Queries": count} + for ctype, count in sorted( + stats.queries_by_type.items(), key=lambda x: x[1], reverse=True + ) + ] + lines.append("") + lines.append(tabulate(type_data, headers="keys", tablefmt="pretty")) + + return "\n".join(lines) + + def __str__(self) -> str: + return self.get_status_table() + + def is_healthy(self) -> bool: + """Retrieval is healthy when the zero-result rate is acceptable.""" + stats = self._get_collector().snapshot() + if stats.total_queries == 0: + return True + return stats.zero_result_rate < self.UNHEALTHY_ZERO_RESULT_RATE + + def has_errors(self) -> bool: + """Errors are flagged when too many queries return zero results.""" + stats = self._get_collector().snapshot() + if stats.total_queries < 5: + return False + return stats.zero_result_rate >= self.UNHEALTHY_ZERO_RESULT_RATE diff --git a/openviking/storage/observers/transaction_observer.py b/openviking/storage/observers/transaction_observer.py deleted file mode 100644 index dce4555d..00000000 --- a/openviking/storage/observers/transaction_observer.py +++ /dev/null @@ -1,222 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: Apache-2.0 -""" -TransactionObserver: Transaction system observability tool. - -Provides methods to observe and report transaction manager status. -""" - -import time -from typing import Any, Dict - -from openviking.storage.observers.base_observer import BaseObserver -from openviking.storage.transaction import TransactionManager -from openviking.storage.transaction.transaction_record import TransactionStatus -from openviking_cli.utils import run_async -from openviking_cli.utils.logger import get_logger - -logger = get_logger(__name__) - - -class TransactionObserver(BaseObserver): - """ - TransactionObserver: System observability tool for transaction management. - - Provides methods to query transaction status and format output. - """ - - def __init__(self, transaction_manager: TransactionManager): - """Initialize transaction observer. - - Args: - transaction_manager: Transaction manager instance to observe - """ - self._transaction_manager = transaction_manager - - async def get_status_table_async(self) -> str: - """Get transaction status table asynchronously. - - Returns: - Formatted table string showing transaction status - """ - if not self._transaction_manager: - return "Transaction manager not initialized." - - transactions = self._transaction_manager.get_active_transactions() - - if not transactions: - return "No active transactions." - - return self._format_status_as_table(transactions) - - def get_status_table(self) -> str: - """Get transaction status table synchronously. - - Returns: - Formatted table string showing transaction status - """ - return run_async(self.get_status_table_async()) - - def __str__(self) -> str: - """String representation returns status table. - - Returns: - Formatted table string - """ - return self.get_status_table() - - def _format_status_as_table(self, transactions: Dict[str, Any]) -> str: - """Format transaction statuses as a table. - - Args: - transactions: Dict mapping transaction IDs to TransactionRecord - - Returns: - Formatted table string - """ - from tabulate import tabulate - - data = [] - - # Group transactions by status - status_counts = { - TransactionStatus.INIT: 0, - TransactionStatus.AQUIRE: 0, - TransactionStatus.EXEC: 0, - TransactionStatus.COMMIT: 0, - TransactionStatus.FAIL: 0, - TransactionStatus.RELEASING: 0, - TransactionStatus.RELEASED: 0, - } - - for tx_id, tx in transactions.items(): - duration = time.time() - tx.created_at - duration_str = f"{duration:.1f}s" - - status_counts[tx.status] += 1 - - data.append( - { - "Transaction ID": tx_id[:8] + "...", - "Status": str(tx.status), - "Locks": len(tx.locks), - "Duration": duration_str, - "Created": time.strftime("%H:%M:%S", time.localtime(tx.created_at)), - } - ) - - status_priority = { - TransactionStatus.EXEC: 0, - TransactionStatus.AQUIRE: 1, - TransactionStatus.RELEASING: 2, - TransactionStatus.INIT: 3, - TransactionStatus.COMMIT: 4, - TransactionStatus.FAIL: 5, - TransactionStatus.RELEASED: 6, - } - - data.sort(key=lambda x: status_priority.get(TransactionStatus(x["Status"]), 99)) - - total = len(transactions) - total_locks = sum(len(tx.locks) for tx in transactions.values()) - - summary_row = { - "Transaction ID": f"TOTAL ({total})", - "Status": "", - "Locks": total_locks, - "Duration": "", - "Created": "", - } - data.append(summary_row) - - return tabulate(data, headers="keys", tablefmt="pretty") - - def is_healthy(self) -> bool: - """Check if transaction system is healthy. - - Returns: - True if system is healthy, False otherwise - """ - return not self.has_errors() - - def has_errors(self) -> bool: - """Check if transaction system has any errors. - - Returns: - True if errors (failed transactions) exist, False otherwise - """ - if not self._transaction_manager: - return True - - transactions = self._transaction_manager.get_active_transactions() - - # Check for failed transactions - for tx_id, tx in transactions.items(): - if tx.status == TransactionStatus.FAIL: - logger.warning(f"Found failed transaction: {tx_id}") - return True - - return False - - def get_failed_transactions(self) -> Dict[str, Any]: - """Get all failed transactions. - - Returns: - Dict mapping transaction IDs to failed TransactionRecord - """ - if not self._transaction_manager: - return {} - - transactions = self._transaction_manager.get_active_transactions() - return { - tx_id: tx for tx_id, tx in transactions.items() if tx.status == TransactionStatus.FAIL - } - - def get_hanging_transactions(self, timeout_threshold: int = 300) -> Dict[str, Any]: - """Get transactions that have been running longer than threshold. - - Args: - timeout_threshold: Timeout threshold in seconds (default: 300 = 5 minutes) - - Returns: - Dict mapping transaction IDs to TransactionRecord that exceed threshold - """ - if not self._transaction_manager: - return {} - - transactions = self._transaction_manager.get_active_transactions() - current_time = time.time() - - return { - tx_id: tx - for tx_id, tx in transactions.items() - if current_time - tx.created_at > timeout_threshold - } - - def get_status_summary(self) -> Dict[str, int]: - """Get summary of transaction counts by status. - - Returns: - Dict mapping status strings to counts - """ - if not self._transaction_manager: - return {} - - transactions = self._transaction_manager.get_active_transactions() - - summary = { - "INIT": 0, - "AQUIRE": 0, - "EXEC": 0, - "COMMIT": 0, - "FAIL": 0, - "RELEASING": 0, - "RELEASED": 0, - "TOTAL": 0, - } - - for tx in transactions.values(): - summary[str(tx.status)] += 1 - summary["TOTAL"] += 1 - - return summary diff --git a/openviking/storage/queuefs/__init__.py b/openviking/storage/queuefs/__init__.py index b73a01d7..87514a83 100644 --- a/openviking/storage/queuefs/__init__.py +++ b/openviking/storage/queuefs/__init__.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 from .embedding_msg import EmbeddingMsg from .embedding_queue import EmbeddingQueue +from .embedding_tracker import EmbeddingTaskTracker from .named_queue import NamedQueue, QueueError, QueueStatus from .queue_manager import QueueManager, get_queue_manager, init_queue_manager from .semantic_dag import SemanticDagExecutor @@ -18,6 +19,7 @@ "QueueError", "EmbeddingQueue", "EmbeddingMsg", + "EmbeddingTaskTracker", "SemanticQueue", "SemanticDagExecutor", "SemanticMsg", diff --git a/openviking/storage/queuefs/embedding_msg.py b/openviking/storage/queuefs/embedding_msg.py index 19b8381e..af0e95ee 100644 --- a/openviking/storage/queuefs/embedding_msg.py +++ b/openviking/storage/queuefs/embedding_msg.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 import json from dataclasses import asdict, dataclass -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Optional, Union from uuid import uuid4 @@ -10,11 +10,21 @@ class EmbeddingMsg: message: Union[str, List[Dict[str, Any]]] context_data: Dict[str, Any] + telemetry_id: str = "" + semantic_msg_id: Optional[str] = None - def __init__(self, message: Union[str, List[Dict[str, Any]]], context_data: Dict[str, Any]): + def __init__( + self, + message: Union[str, List[Dict[str, Any]]], + context_data: Dict[str, Any], + telemetry_id: str = "", + semantic_msg_id: Optional[str] = None, + ): self.id = str(uuid4()) self.message = message self.context_data = context_data + self.telemetry_id = telemetry_id + self.semantic_msg_id = semantic_msg_id def to_dict(self) -> Dict[str, Any]: """Convert embedding message to dictionary format.""" @@ -30,6 +40,8 @@ def from_dict(cls, data: Dict[str, Any]) -> "EmbeddingMsg": obj = EmbeddingMsg( message=data["message"], context_data=data["context_data"], + telemetry_id=data.get("telemetry_id", ""), + semantic_msg_id=data.get("semantic_msg_id"), ) obj.id = data.get("id", obj.id) return obj diff --git a/openviking/storage/queuefs/embedding_msg_converter.py b/openviking/storage/queuefs/embedding_msg_converter.py index b174b941..133d0de6 100644 --- a/openviking/storage/queuefs/embedding_msg_converter.py +++ b/openviking/storage/queuefs/embedding_msg_converter.py @@ -9,6 +9,7 @@ from openviking.core.context import Context, ContextLevel from openviking.storage.queuefs.embedding_msg import EmbeddingMsg +from openviking.telemetry import get_current_telemetry from openviking_cli.utils import get_logger logger = get_logger(__name__) @@ -71,5 +72,6 @@ def from_context(context: Context) -> EmbeddingMsg: embedding_msg = EmbeddingMsg( message=vectorization_text, context_data=context_data, + telemetry_id=get_current_telemetry().telemetry_id, ) return embedding_msg diff --git a/openviking/storage/queuefs/embedding_queue.py b/openviking/storage/queuefs/embedding_queue.py index d44595e8..5fb1f4af 100644 --- a/openviking/storage/queuefs/embedding_queue.py +++ b/openviking/storage/queuefs/embedding_queue.py @@ -21,6 +21,7 @@ async def enqueue(self, msg: Optional[EmbeddingMsg]) -> str: if msg is None: logger.warning("Embedding message is None, skipping enqueuing") return "" + logger.debug(f"Enqueued embedding message: {msg}") return await super().enqueue(msg.to_dict()) async def dequeue(self) -> Optional[EmbeddingMsg]: diff --git a/openviking/storage/queuefs/embedding_tracker.py b/openviking/storage/queuefs/embedding_tracker.py new file mode 100644 index 00000000..a51af645 --- /dev/null +++ b/openviking/storage/queuefs/embedding_tracker.py @@ -0,0 +1,129 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Embedding Task Tracker for tracking embedding task completion status.""" + +import asyncio +from typing import Any, Callable, Dict, Optional + +from openviking_cli.utils.logger import get_logger + +logger = get_logger(__name__) + + +class EmbeddingTaskTracker: + """Track embedding task completion status for each SemanticMsg. + + This tracker maintains a global registry of embedding tasks associated + with each SemanticMsg. When all embedding tasks for a SemanticMsg are + completed, it triggers the registered callback and removes the entry. + """ + + _instance: Optional["EmbeddingTaskTracker"] = None + _initialized: bool = False + + def __new__(cls) -> "EmbeddingTaskTracker": + if cls._instance is None: + cls._instance = super().__new__(cls) + return cls._instance + + def __init__(self): + if self._initialized: + return + self._lock: asyncio.Lock = asyncio.Lock() + self._tasks: Dict[str, Dict[str, Any]] = {} + self._initialized = True + + @classmethod + def get_instance(cls) -> "EmbeddingTaskTracker": + """Get the singleton instance of EmbeddingTaskTracker.""" + if cls._instance is None: + cls._instance = cls() + return cls._instance + + async def register( + self, + semantic_msg_id: str, + total_count: int, + on_complete: Optional[Callable[[], Any]] = None, + metadata: Optional[Dict[str, Any]] = None, + ) -> None: + """Register a SemanticMsg with its total embedding task count. + + Args: + semantic_msg_id: The ID of the SemanticMsg + total_count: Total number of embedding tasks for this SemanticMsg + on_complete: Optional callback when all tasks complete + metadata: Optional metadata to store with the task + """ + async with self._lock: + self._tasks[semantic_msg_id] = { + "remaining": total_count, + "total": total_count, + "on_complete": on_complete, + "metadata": metadata or {}, + } + logger.info( + f"Registered embedding tracker for SemanticMsg {semantic_msg_id}: " + f"{total_count} tasks" + ) + + if total_count <= 0 and on_complete: + del self._tasks[semantic_msg_id] + logger.info( + f"No embedding tasks for SemanticMsg {semantic_msg_id}, " + f"triggering on_complete immediately" + ) + + if total_count <= 0 and on_complete: + try: + result = on_complete() + if asyncio.iscoroutine(result): + await result + except Exception as e: + logger.error( + f"Error in completion callback for {semantic_msg_id}: {e}", + exc_info=True, + ) + + async def decrement(self, semantic_msg_id: str) -> Optional[int]: + """Decrement the remaining task count for a SemanticMsg. + + This method should be called when an embedding task is completed. + When the count reaches zero, the registered callback is executed + and the entry is removed from the tracker. + + Args: + semantic_msg_id: The ID of the SemanticMsg + + Returns: + The remaining count after decrement, or None if not found + """ + on_complete = None + + async with self._lock: + if semantic_msg_id not in self._tasks: + return None + + task_info = self._tasks[semantic_msg_id] + task_info["remaining"] -= 1 + remaining = task_info["remaining"] + + if remaining <= 0: + on_complete = task_info.get("on_complete") + + del self._tasks[semantic_msg_id] + logger.info( + f"All embedding tasks({task_info['total']}) completed for SemanticMsg {semantic_msg_id}" + ) + + if on_complete: + try: + result = on_complete() + if asyncio.iscoroutine(result): + await result + except Exception as e: + logger.error( + f"Error in completion callback for {semantic_msg_id}: {e}", + exc_info=True, + ) + return remaining diff --git a/openviking/storage/queuefs/named_queue.py b/openviking/storage/queuefs/named_queue.py index ad79202b..ce7705b7 100644 --- a/openviking/storage/queuefs/named_queue.py +++ b/openviking/storage/queuefs/named_queue.py @@ -198,6 +198,21 @@ async def enqueue(self, data: Union[str, Dict[str, Any]]) -> str: msg_id = self._agfs.write(enqueue_file, data.encode("utf-8")) return msg_id if isinstance(msg_id, str) else str(msg_id) + async def ack(self, msg_id: str) -> None: + """Acknowledge successful processing of a message (deletes it from persistent storage). + + Must be called after the dequeue handler finishes processing a message. + If not called (e.g. process crashes), the message will be automatically + re-queued on the next startup via RecoverStale. + """ + if not msg_id: + return + ack_file = f"{self.path}/ack" + try: + self._agfs.write(ack_file, msg_id.encode("utf-8")) + except Exception as e: + logger.warning(f"[NamedQueue] Ack failed for {self.name} msg_id={msg_id}: {e}") + def _read_queue_message(self) -> Optional[Dict[str, Any]]: """Read and remove one message from the AGFS queue; return parsed dict or None. @@ -217,15 +232,30 @@ def _read_queue_message(self) -> Optional[Dict[str, Any]]: return json.loads(raw.decode("utf-8")) async def dequeue(self) -> Optional[Dict[str, Any]]: - """Get and remove message from queue, then invoke the dequeue handler.""" + """Dequeue a message, process it, then ack to confirm deletion. + + Flow (at-least-once delivery): + 1. Read from /dequeue → backend marks message as 'processing' (not deleted yet) + 2. Call on_dequeue() → actual processing + 3. Call ack() → backend deletes the message permanently + + If the process crashes between steps 1 and 3, the backend's RecoverStale + on the next startup resets the message back to 'pending' for retry. + """ await self._ensure_initialized() try: data = self._read_queue_message() if data is None: return None + # Capture message ID before passing data to handler (handler may modify it) + msg_id = data.get("id", "") if isinstance(data, dict) else "" if self._dequeue_handler: self._on_dequeue_start() data = await self._dequeue_handler.on_dequeue(data) + # Ack unconditionally after handler returns (success or handled error). + # If on_dequeue raises, the exception propagates and ack is skipped — + # the message will be recovered on next startup. + await self.ack(msg_id) return data except Exception as e: logger.debug(f"[NamedQueue] Dequeue failed for {self.name}: {e}") diff --git a/openviking/storage/queuefs/queue_manager.py b/openviking/storage/queuefs/queue_manager.py index 95e9aeb2..52b42476 100644 --- a/openviking/storage/queuefs/queue_manager.py +++ b/openviking/storage/queuefs/queue_manager.py @@ -107,16 +107,16 @@ def start(self) -> None: logger.info("[QueueManager] Started") - def setup_standard_queues(self, vector_store: Any) -> None: + def setup_standard_queues(self, vector_store: Any, start: bool = True) -> None: """ Setup standard queues (Embedding and Semantic) with their handlers. - This method initializes the EmbeddingQueue with TextEmbeddingHandler - and the SemanticQueue with SemanticProcessor, then ensures the - queue manager is started. - Args: vector_store: Vector store instance for handlers to write results. + start: Whether to start worker threads immediately (default True). + Pass False when the consumer depends on resources that are + not yet initialized (e.g. VikingFS); call start() manually + after those resources are ready. """ # Import handlers here to avoid circular dependencies from openviking.storage.collection_schemas import TextEmbeddingHandler @@ -140,8 +140,8 @@ def setup_standard_queues(self, vector_store: Any) -> None: ) logger.info("Semantic queue initialized with SemanticProcessor") - # Start QueueManager processing - self.start() + if start: + self.start() def _start_queue_worker(self, queue: NamedQueue) -> None: """Start a dedicated worker thread for a queue if not already running.""" @@ -207,10 +207,14 @@ async def _worker_async_concurrent( async def process_one(data: Dict[str, Any]) -> None: async with sem: + msg_id = data.get("id", "") if isinstance(data, dict) else "" try: await queue.process_dequeued(data) + # Ack after successful processing (delete from persistent storage). + await queue.ack(msg_id) except Exception as e: # Handler did not call report_error; decrement in_progress manually. + # Do NOT ack — let RecoverStale re-queue on next startup. queue._on_process_error(str(e), data) logger.error(f"[QueueManager] Concurrent worker error for {queue.name}: {e}") @@ -241,9 +245,21 @@ async def process_one(data: Dict[str, Any]) -> None: await asyncio.sleep(self._poll_interval) - # Drain remaining in-flight tasks on shutdown + # Drain remaining in-flight tasks on shutdown (with timeout) if active_tasks: - await asyncio.gather(*active_tasks, return_exceptions=True) + try: + await asyncio.wait_for( + asyncio.gather(*active_tasks, return_exceptions=True), + timeout=5.0, + ) + except asyncio.TimeoutError: + logger.warning( + f"[QueueManager] Drain timeout for {queue.name}, " + f"cancelling {len(active_tasks)} in-flight task(s)" + ) + for t in active_tasks: + t.cancel() + await asyncio.gather(*active_tasks, return_exceptions=True) def stop(self) -> None: """Stop QueueManager and release resources.""" @@ -254,8 +270,10 @@ def stop(self) -> None: # Stop queue workers for stop_event in self._queue_stop_events.values(): stop_event.set() - for thread in self._queue_threads.values(): - thread.join() + for name, thread in self._queue_threads.items(): + thread.join(timeout=10.0) + if thread.is_alive(): + logger.warning(f"[QueueManager] Worker thread {name} did not exit in time") self._queue_threads.clear() self._queue_stop_events.clear() @@ -280,9 +298,6 @@ def get_queue( allow_create: bool = False, ) -> NamedQueue: """Get or create a named queue object.""" - if not self._started: - self.start() - if name not in self._queues: if not allow_create: raise RuntimeError(f"Queue {name} does not exist and allow_create is False") diff --git a/openviking/storage/queuefs/semantic_dag.py b/openviking/storage/queuefs/semantic_dag.py index 0307521f..79213f71 100644 --- a/openviking/storage/queuefs/semantic_dag.py +++ b/openviking/storage/queuefs/semantic_dag.py @@ -4,7 +4,7 @@ import asyncio from dataclasses import dataclass, field -from typing import Dict, List, Optional +from typing import Awaitable, Callable, Dict, List, Optional from openviking.server.identity import RequestContext from openviking.storage.viking_fs import get_viking_fs @@ -13,6 +13,11 @@ logger = get_logger(__name__) +# Session-internal files that should never be summarized by the semantic pipeline. +# These are canonical archives (e.g. session transcripts) whose content provides +# no additional retrieval value and would only waste tokens and add latency. +_SKIP_FILENAMES = frozenset({"messages.jsonl"}) + @dataclass class DirNode: @@ -39,6 +44,24 @@ class DagStats: done_nodes: int = 0 +@dataclass +class VectorizeTask: + """Vectorize task information.""" + + task_type: str # "file" or "directory" + uri: str + context_type: str + ctx: "RequestContext" + semantic_msg_id: Optional[str] = None + # For file tasks + file_path: Optional[str] = None + summary_dict: Optional[Dict[str, str]] = None + parent_uri: Optional[str] = None + # For directory tasks + abstract: Optional[str] = None + overview: Optional[str] = None + + class SemanticDagExecutor: """Execute semantic generation with DAG-style, event-driven lazy dispatch.""" @@ -48,11 +71,21 @@ def __init__( context_type: str, max_concurrent_llm: int, ctx: RequestContext, + incremental_update: bool = False, + target_uri: Optional[str] = None, + semantic_msg_id: Optional[str] = None, + recursive: bool = True, + lifecycle_lock_handle_id: str = "", ): self._processor = processor self._context_type = context_type self._max_concurrent_llm = max_concurrent_llm self._ctx = ctx + self._incremental_update = incremental_update + self._target_uri = target_uri + self._semantic_msg_id = semantic_msg_id + self._recursive = recursive + self._lifecycle_lock_handle_id = lifecycle_lock_handle_id self._llm_sem = asyncio.Semaphore(max_concurrent_llm) self._viking_fs = get_viking_fs() self._nodes: Dict[str, DirNode] = {} @@ -60,13 +93,124 @@ def __init__( self._root_uri: Optional[str] = None self._root_done: Optional[asyncio.Event] = None self._stats = DagStats() + self._vectorize_task_count: int = 0 + self._pending_vectorize_tasks: List[VectorizeTask] = [] + self._vectorize_lock = asyncio.Lock() + self._file_change_status: Dict[str, bool] = {} + self._dir_change_status: Dict[str, bool] = {} + self._overview_cache: Dict[str, Dict[str, str]] = {} + self._overview_cache_lock = asyncio.Lock() + self._refresh_task: Optional[asyncio.Task] = None + + def _create_on_complete_callback(self) -> Callable[[], Awaitable[None]]: + """Create on_complete callback for incremental update or full update.""" + + async def noop_callback() -> None: + return + + if not self._target_uri or not self._root_uri: + return noop_callback + + # If full update, move temp uri to target uri has been handled in the processor + if not self._incremental_update: + return noop_callback + + async def sync_diff_callback() -> None: + try: + diff = await self._processor._sync_topdown_recursive( + self._root_uri, + self._target_uri, + ctx=self._ctx, + file_change_status=self._file_change_status, + ) + logger.info( + f"[SyncDiff] Diff computed: " + f"added_files={len(diff.added_files)}, " + f"deleted_files={len(diff.deleted_files)}, " + f"updated_files={len(diff.updated_files)}, " + f"added_dirs={len(diff.added_dirs)}, " + f"deleted_dirs={len(diff.deleted_dirs)}" + ) + except Exception as e: + logger.error( + f"[SyncDiff] Error in sync_diff_callback: " + f"root_uri={self._root_uri}, target_uri={self._target_uri} " + f"error={e}", + exc_info=True, + ) + + return sync_diff_callback async def run(self, root_uri: str) -> None: """Run DAG execution starting from root_uri.""" self._root_uri = root_uri self._root_done = asyncio.Event() - await self._dispatch_dir(root_uri, parent_uri=None) - await self._root_done.wait() + + # Start lifecycle lock refresh loop if we hold a lock + if self._lifecycle_lock_handle_id: + self._refresh_task = asyncio.create_task(self._lock_refresh_loop()) + + try: + await self._dispatch_dir(root_uri, parent_uri=None) + await self._root_done.wait() + except Exception: + await self._release_lifecycle_lock() + raise + + original_on_complete = self._create_on_complete_callback() + + # Wrap on_complete to release lifecycle lock after all processing + async def wrapped_on_complete() -> None: + try: + if original_on_complete: + await original_on_complete() + finally: + await self._release_lifecycle_lock() + + async with self._vectorize_lock: + task_count = self._vectorize_task_count + tasks = list(self._pending_vectorize_tasks) + + if task_count > 0: + from .embedding_tracker import EmbeddingTaskTracker + + tracker = EmbeddingTaskTracker.get_instance() + await tracker.register( + semantic_msg_id=self._semantic_msg_id, + total_count=task_count, + on_complete=wrapped_on_complete, + metadata={"uri": root_uri}, + ) + + for task in tasks: + if task.task_type == "file": + asyncio.create_task( + self._processor._vectorize_single_file( + parent_uri=task.parent_uri, + context_type=task.context_type, + file_path=task.file_path, + summary_dict=task.summary_dict, + ctx=task.ctx, + semantic_msg_id=task.semantic_msg_id, + ) + ) + else: + asyncio.create_task( + self._processor._vectorize_directory( + task.uri, + task.context_type, + task.abstract, + task.overview, + ctx=task.ctx, + semantic_msg_id=task.semantic_msg_id, + ) + ) + else: + # No vectorize tasks — release lock immediately (via wrapped callback) + try: + await wrapped_on_complete() + except Exception as e: + logger.error(f"Error in on_complete callback: {e}", exc_info=True) async def _dispatch_dir(self, dir_uri: str, parent_uri: Optional[str]) -> None: """Lazy-dispatch tasks for a directory when it is triggered.""" @@ -79,7 +223,10 @@ async def _dispatch_dir(self, dir_uri: str, parent_uri: Optional[str]) -> None: children_dirs, file_paths = await self._list_dir(dir_uri) file_index = {path: idx for idx, path in enumerate(file_paths)} child_index = {path: idx for idx, path in enumerate(children_dirs)} - pending = len(children_dirs) + len(file_paths) + if self._recursive: + pending = len(children_dirs) + len(file_paths) + else: + pending = len(file_paths) node = DirNode( uri=dir_uri, @@ -108,8 +255,10 @@ async def _dispatch_dir(self, dir_uri: str, parent_uri: Optional[str]) -> None: self._stats.in_progress_nodes += 1 asyncio.create_task(self._file_summary_task(dir_uri, file_path)) - for child_uri in children_dirs: - asyncio.create_task(self._dispatch_dir(child_uri, dir_uri)) + if children_dirs: + if self._recursive: + for child_uri in children_dirs: + asyncio.create_task(self._dispatch_dir(child_uri, dir_uri)) except Exception as e: logger.error(f"Failed to dispatch directory {dir_uri}: {e}", exc_info=True) if parent_uri: @@ -130,7 +279,7 @@ async def _list_dir(self, uri: str) -> tuple[list[str], list[str]]: for entry in entries: name = entry.get("name", "") - if not name or name.startswith(".") or name in [".", ".."]: + if not name or name.startswith(".") or name in [".", ".."] or name in _SKIP_FILENAMES: continue item_uri = VikingURI(uri).join(name).uri @@ -141,13 +290,139 @@ async def _list_dir(self, uri: str) -> tuple[list[str], list[str]]: return children_dirs, file_paths + def _get_target_file_path(self, current_uri: str) -> Optional[str]: + if not self._incremental_update or not self._target_uri or not self._root_uri: + logger.warning( + f"Invalid target_uri or root_uri for incremental update: target_uri={self._target_uri}, root_uri={self._root_uri}" + ) + return None + try: + relative_path = current_uri[len(self._root_uri) :] + if relative_path.startswith("/"): + relative_path = relative_path[1:] + return f"{self._target_uri}/{relative_path}" if relative_path else self._target_uri + except Exception: + return None + + async def _check_file_content_changed(self, file_path: str) -> bool: + target_path = self._get_target_file_path(file_path) + if not target_path: + return True + try: + current_stat = await self._viking_fs.stat(file_path, ctx=self._ctx) + target_stat = await self._viking_fs.stat(target_path, ctx=self._ctx) + current_size = current_stat.get("size") if isinstance(current_stat, dict) else None + target_size = target_stat.get("size") if isinstance(target_stat, dict) else None + if current_size is not None and target_size is not None and current_size != target_size: + return True + current_content = await self._viking_fs.read_file(file_path, ctx=self._ctx) + target_content = await self._viking_fs.read_file(target_path, ctx=self._ctx) + return current_content != target_content + except Exception: + return True + + async def _read_existing_summary(self, file_path: str) -> Optional[Dict[str, str]]: + """Read existing summary from parent directory's .overview.md. + + Args: + file_path: Current file path + + Returns: + Summary dict with 'name' and 'summary' keys, or None if not found + """ + target_path = self._get_target_file_path(file_path) + if not target_path: + return None + + try: + parent_uri = "/".join(target_path.rsplit("/", 1)[:-1]) + if not parent_uri: + return None + + if parent_uri not in self._overview_cache: + async with self._overview_cache_lock: + if parent_uri not in self._overview_cache: + overview_path = f"{parent_uri}/.overview.md" + overview_content = await self._viking_fs.read_file( + overview_path, ctx=self._ctx + ) + if overview_content: + self._overview_cache[parent_uri] = self._processor._parse_overview_md( + overview_content + ) + else: + self._overview_cache[parent_uri] = {} + + existing_summaries = self._overview_cache.get(parent_uri, {}) + file_name = file_path.split("/")[-1] + + if file_name in existing_summaries: + return {"name": file_name, "summary": existing_summaries[file_name]} + + except Exception as e: + logger.debug(f"Failed to read existing summary from overview.md for {file_path}: {e}") + + return None + + async def _check_dir_children_changed( + self, dir_uri: str, current_files: List[str], current_dirs: List[str] + ) -> bool: + target_path = self._get_target_file_path(dir_uri) + if not target_path: + return True + try: + target_dirs, target_files = await self._list_dir(target_path) + current_file_names = {f.split("/")[-1] for f in current_files} + target_file_names = {f.split("/")[-1] for f in target_files} + if current_file_names != target_file_names: + return True + current_dir_names = {d.split("/")[-1] for d in current_dirs} + target_dir_names = {d.split("/")[-1] for d in target_dirs} + if current_dir_names != target_dir_names: + return True + for current_file in current_files: + if self._file_change_status.get(current_file, True): + return True + for current_dir in current_dirs: + if self._dir_change_status.get(current_dir, True): + return True + return False + except Exception: + return True + + async def _read_existing_overview_abstract( + self, dir_uri: str + ) -> tuple[Optional[str], Optional[str]]: + target_path = self._get_target_file_path(dir_uri) + if not target_path: + return None, None + try: + overview = await self._viking_fs.read_file(f"{target_path}/.overview.md", ctx=self._ctx) + abstract = await self._viking_fs.read_file(f"{target_path}/.abstract.md", ctx=self._ctx) + return overview, abstract + except Exception: + return None, None + async def _file_summary_task(self, parent_uri: str, file_path: str) -> None: """Generate file summary and notify parent completion.""" + file_name = file_path.split("/")[-1] + need_vectorize = True try: - summary_dict = await self._processor._generate_single_file_summary( - file_path, llm_sem=self._llm_sem, ctx=self._ctx - ) + summary_dict = None + if self._incremental_update: + content_changed = await self._check_file_content_changed(file_path) + self._file_change_status[file_path] = content_changed + + if not content_changed: + summary_dict = await self._read_existing_summary(file_path) + need_vectorize = False + else: + self._file_change_status[file_path] = True + if summary_dict is None: + summary_dict = await self._processor._generate_single_file_summary( + file_path, llm_sem=self._llm_sem, ctx=self._ctx + ) except Exception as e: logger.warning(f"Failed to generate summary for {file_path}: {e}") summary_dict = {"name": file_name, "summary": ""} @@ -155,21 +430,22 @@ async def _file_summary_task(self, parent_uri: str, file_path: str) -> None: self._stats.done_nodes += 1 self._stats.in_progress_nodes = max(0, self._stats.in_progress_nodes - 1) - await self._on_file_done(parent_uri, file_path, summary_dict) - - # Vectorize file as soon as summary is ready to avoid waiting for overview. try: - asyncio.create_task( - self._processor._vectorize_single_file( - parent_uri=parent_uri, + if need_vectorize: + task = VectorizeTask( + task_type="file", + uri=file_path, context_type=self._context_type, + ctx=self._ctx, + semantic_msg_id=self._semantic_msg_id, file_path=file_path, summary_dict=summary_dict, - ctx=self._ctx, + parent_uri=parent_uri, ) - ) + await self._add_vectorize_task(task) except Exception as e: logger.error(f"Failed to schedule vectorization for {file_path}: {e}", exc_info=True) + await self._on_file_done(parent_uri, file_path, summary_dict) async def _on_file_done( self, parent_uri: str, file_path: str, summary_dict: Dict[str, str] @@ -241,38 +517,61 @@ async def _overview_task(self, dir_uri: str) -> None: node = self._nodes.get(dir_uri) if not node: return - - async with node.lock: - file_summaries = self._finalize_file_summaries(node) - children_abstracts = self._finalize_children_abstracts(node) - + need_vectorize = True + children_changed = True + abstract = "" try: - async with self._llm_sem: - overview = await self._processor._generate_overview( - dir_uri, file_summaries, children_abstracts + overview = None + abstract = None + if self._incremental_update: + children_changed = await self._check_dir_children_changed( + dir_uri, node.file_paths, node.children_dirs ) - abstract = self._processor._extract_abstract_from_overview(overview) + if not children_changed: + need_vectorize = False + overview, abstract = await self._read_existing_overview_abstract(dir_uri) + if overview is None or abstract is None: + async with node.lock: + file_summaries = self._finalize_file_summaries(node) + children_abstracts = self._finalize_children_abstracts(node) + async with self._llm_sem: + overview = await self._processor._generate_overview( + dir_uri, file_summaries, children_abstracts + ) + abstract = self._processor._extract_abstract_from_overview(overview) + overview, abstract = self._processor._enforce_size_limits(overview, abstract) + + # Write directly — protected by the outer lifecycle SUBTREE lock try: await self._viking_fs.write_file(f"{dir_uri}/.overview.md", overview, ctx=self._ctx) await self._viking_fs.write_file(f"{dir_uri}/.abstract.md", abstract, ctx=self._ctx) - except Exception as e: - logger.warning(f"Failed to write overview/abstract for {dir_uri}: {e}") + except Exception: + logger.info(f"[SemanticDag] {dir_uri} write failed, skipping") try: - await self._processor._vectorize_directory_simple( - dir_uri, self._context_type, abstract, overview, ctx=self._ctx - ) + if need_vectorize: + task = VectorizeTask( + task_type="directory", + uri=dir_uri, + context_type=self._context_type, + ctx=self._ctx, + semantic_msg_id=self._semantic_msg_id, + abstract=abstract, + overview=overview, + ) + await self._add_vectorize_task(task) except Exception as e: - logger.error(f"Failed to vectorize directory {dir_uri}: {e}", exc_info=True) + logger.error(f"Failed to schedule vectorization for {dir_uri}: {e}", exc_info=True) except Exception as e: logger.error(f"Failed to generate overview for {dir_uri}: {e}", exc_info=True) - abstract = "" finally: self._stats.done_nodes += 1 self._stats.in_progress_nodes = max(0, self._stats.in_progress_nodes - 1) + self._dir_change_status[dir_uri] = children_changed + parent_uri = self._parent.get(dir_uri) if parent_uri is None: if self._root_done: @@ -281,6 +580,55 @@ async def _overview_task(self, dir_uri: str) -> None: await self._on_child_done(parent_uri, dir_uri, abstract) + async def _add_vectorize_task(self, task: VectorizeTask) -> None: + """Add a vectorize task to the pending list.""" + async with self._vectorize_lock: + self._pending_vectorize_tasks.append(task) + if task.task_type == "file": + self._vectorize_task_count += 1 + else: # directory + self._vectorize_task_count += 2 + + async def _lock_refresh_loop(self) -> None: + """Periodically refresh lifecycle lock to prevent stale expiry.""" + from openviking.storage.transaction import get_lock_manager + + try: + interval = get_lock_manager()._path_lock._lock_expire / 2 + except Exception: + interval = 150.0 + + while True: + try: + await asyncio.sleep(interval) + handle = get_lock_manager().get_handle(self._lifecycle_lock_handle_id) + if handle: + await get_lock_manager().refresh_lock(handle) + else: + break + except asyncio.CancelledError: + break + except Exception as e: + logger.warning(f"[SemanticDag] Lock refresh failed: {e}") + + async def _release_lifecycle_lock(self) -> None: + """Stop refresh loop and release lifecycle lock.""" + if self._refresh_task and not self._refresh_task.done(): + self._refresh_task.cancel() + self._refresh_task = None + if not self._lifecycle_lock_handle_id: + return + handle_id = self._lifecycle_lock_handle_id + self._lifecycle_lock_handle_id = "" + try: + from openviking.storage.transaction import get_lock_manager + + handle = get_lock_manager().get_handle(handle_id) + if handle: + await get_lock_manager().release(handle) + except Exception as e: + logger.warning(f"[SemanticDag] Failed to release lifecycle lock {handle_id}: {e}") + def get_stats(self) -> DagStats: return DagStats( total_nodes=self._stats.total_nodes, diff --git a/openviking/storage/queuefs/semantic_msg.py b/openviking/storage/queuefs/semantic_msg.py index 5f7bd730..720948e8 100644 --- a/openviking/storage/queuefs/semantic_msg.py +++ b/openviking/storage/queuefs/semantic_msg.py @@ -5,7 +5,7 @@ import json from dataclasses import asdict, dataclass from datetime import datetime -from typing import Any, Dict +from typing import Any, Dict, List, Optional from uuid import uuid4 @@ -16,7 +16,7 @@ class SemanticMsg: Attributes: id: Unique identifier (UUID) uri: Directory URI to process - context_type: Type of context (resource, memory, skill) + context_type: Type of context (resource, memory, skill, session) status: Processing status (pending/processing/completed) timestamp: Creation timestamp recursive: Whether to recursively process subdirectories. @@ -27,7 +27,7 @@ class SemanticMsg: id: str # UUID uri: str # Directory URI - context_type: str # resource, memory, skill + context_type: str # resource, memory, skill, session status: str = "pending" # pending/processing/completed timestamp: int = int(datetime.now().timestamp()) recursive: bool = True # Whether to recursively process subdirectories @@ -37,6 +37,12 @@ class SemanticMsg: role: str = "root" # Additional flags skip_vectorization: bool = False + telemetry_id: str = "" + target_uri: str = "" + lifecycle_lock_handle_id: str = "" + changes: Optional[Dict[str, List[str]]] = ( + None # {"added": [...], "modified": [...], "deleted": [...]} + ) def __init__( self, @@ -48,6 +54,10 @@ def __init__( agent_id: str = "default", role: str = "root", skip_vectorization: bool = False, + telemetry_id: str = "", + target_uri: str = "", + lifecycle_lock_handle_id: str = "", + changes: Optional[Dict[str, List[str]]] = None, ): self.id = str(uuid4()) self.uri = uri @@ -58,6 +68,10 @@ def __init__( self.agent_id = agent_id self.role = role self.skip_vectorization = skip_vectorization + self.telemetry_id = telemetry_id + self.target_uri = target_uri + self.lifecycle_lock_handle_id = lifecycle_lock_handle_id + self.changes = changes def to_dict(self) -> Dict[str, Any]: """Convert object to dictionary.""" @@ -93,6 +107,10 @@ def from_dict(cls, data: Dict[str, Any]) -> "SemanticMsg": agent_id=data.get("agent_id", "default"), role=data.get("role", "root"), skip_vectorization=data.get("skip_vectorization", False), + telemetry_id=data.get("telemetry_id", ""), + target_uri=data.get("target_uri", ""), + lifecycle_lock_handle_id=data.get("lifecycle_lock_handle_id", ""), + changes=data.get("changes"), ) if "id" in data and data["id"]: obj.id = data["id"] diff --git a/openviking/storage/queuefs/semantic_processor.py b/openviking/storage/queuefs/semantic_processor.py index 59700783..2b92b73b 100644 --- a/openviking/storage/queuefs/semantic_processor.py +++ b/openviking/storage/queuefs/semantic_processor.py @@ -3,7 +3,10 @@ """SemanticProcessor: Processes messages from SemanticQueue, generates .abstract.md and .overview.md.""" import asyncio -from typing import Any, Dict, List, Optional, Tuple +import threading +from contextlib import nullcontext +from dataclasses import dataclass, field +from typing import Any, Dict, List, Optional, Set, Tuple from openviking.parse.parsers.constants import ( CODE_EXTENSIONS, @@ -24,6 +27,7 @@ from openviking.storage.queuefs.semantic_dag import DagStats, SemanticDagExecutor from openviking.storage.queuefs.semantic_msg import SemanticMsg from openviking.storage.viking_fs import get_viking_fs +from openviking.telemetry import bind_telemetry, resolve_telemetry from openviking_cli.session.user_id import UserIdentifier from openviking_cli.utils import VikingURI from openviking_cli.utils.config import get_openviking_config @@ -32,6 +36,22 @@ logger = get_logger(__name__) +@dataclass +class DiffResult: + """Directory diff result for sync operations.""" + + added_files: List[str] = field(default_factory=list) + deleted_files: List[str] = field(default_factory=list) + updated_files: List[str] = field(default_factory=list) + added_dirs: List[str] = field(default_factory=list) + deleted_dirs: List[str] = field(default_factory=list) + + +class RequestQueueStats: + processed: int = 0 + error_count: int = 0 + + class SemanticProcessor(DequeueHandlerBase): """ Semantic processor, generates .abstract.md and .overview.md bottom-up. @@ -43,6 +63,14 @@ class SemanticProcessor(DequeueHandlerBase): 4. Enqueue to EmbeddingQueue for vectorization """ + _stats_lock = threading.Lock() + _dag_stats_by_telemetry_id: Dict[str, DagStats] = {} + _dag_stats_by_uri: Dict[str, DagStats] = {} + _dag_stats_order: List[Tuple[str, str]] = [] + _request_stats_by_telemetry_id: Dict[str, RequestQueueStats] = {} + _request_stats_order: List[str] = [] + _max_cached_stats = 256 + def __init__(self, max_concurrent_llm: int = 100): """ Initialize SemanticProcessor. @@ -55,6 +83,61 @@ def __init__(self, max_concurrent_llm: int = 100): self._current_ctx = RequestContext(user=UserIdentifier.the_default_user(), role=Role.ROOT) self._current_msg: Optional[SemanticMsg] = None + @classmethod + def _cache_dag_stats(cls, telemetry_id: str, uri: str, stats: DagStats) -> None: + with cls._stats_lock: + if telemetry_id: + cls._dag_stats_by_telemetry_id[telemetry_id] = stats + cls._dag_stats_by_uri[uri] = stats + cls._dag_stats_order.append((telemetry_id, uri)) + if len(cls._dag_stats_order) > cls._max_cached_stats: + old_telemetry_id, old_uri = cls._dag_stats_order.pop(0) + if old_telemetry_id: + cls._dag_stats_by_telemetry_id.pop(old_telemetry_id, None) + cls._dag_stats_by_uri.pop(old_uri, None) + + @classmethod + def consume_dag_stats( + cls, + telemetry_id: str = "", + uri: Optional[str] = None, + ) -> Optional[DagStats]: + with cls._stats_lock: + if telemetry_id and telemetry_id in cls._dag_stats_by_telemetry_id: + stats = cls._dag_stats_by_telemetry_id.pop(telemetry_id, None) + if uri: + cls._dag_stats_by_uri.pop(uri, None) + return stats + if uri and uri in cls._dag_stats_by_uri: + return cls._dag_stats_by_uri.pop(uri, None) + return None + + @classmethod + def _merge_request_stats( + cls, + telemetry_id: str, + processed: int = 0, + error_count: int = 0, + ) -> None: + if not telemetry_id: + return + with cls._stats_lock: + stats = cls._request_stats_by_telemetry_id.setdefault(telemetry_id, RequestQueueStats()) + stats.processed += processed + stats.error_count += error_count + cls._request_stats_order.append(telemetry_id) + if len(cls._request_stats_order) > cls._max_cached_stats: + old_telemetry_id = cls._request_stats_order.pop(0) + if old_telemetry_id != telemetry_id: + cls._request_stats_by_telemetry_id.pop(old_telemetry_id, None) + + @classmethod + def consume_request_stats(cls, telemetry_id: str) -> Optional[RequestQueueStats]: + if not telemetry_id: + return None + with cls._stats_lock: + return cls._request_stats_by_telemetry_id.pop(telemetry_id, None) + @staticmethod def _owner_space_for_uri(uri: str, ctx: RequestContext) -> str: """Derive owner_space from a URI. @@ -103,55 +186,28 @@ def _detect_file_type(self, file_name: str) -> str: # Default to other return FILE_TYPE_OTHER - async def _enqueue_semantic_msg(self, msg: SemanticMsg) -> None: - """Enqueue a SemanticMsg to the semantic queue for processing.""" - from openviking.storage.queuefs import get_queue_manager - - queue_manager = get_queue_manager() - semantic_queue = queue_manager.get_queue(queue_manager.SEMANTIC) - # The queue manager returns SemanticQueue but method signature says NamedQueue - # We need to ignore the type error for the enqueue call - await semantic_queue.enqueue(msg) # type: ignore - logger.debug(f"Enqueued semantic message for processing: {msg.uri}") - - async def _collect_directory_info( - self, - uri: str, - result: List[Tuple[str, List[str], List[str]]], - ) -> None: - """Recursively collect directory info, post-order traversal ensures bottom-up order.""" + async def _check_file_content_changed( + self, file_path: str, target_file: str, ctx: Optional[RequestContext] = None + ) -> bool: + """Check if file content has changed compared to target file.""" viking_fs = get_viking_fs() - try: - entries = await viking_fs.ls(uri, ctx=self._current_ctx) - except Exception as e: - logger.warning(f"Failed to list directory {uri}: {e}") - return - - children_uris = [] - file_paths = [] - - for entry in entries: - name = entry.get("name", "") - if not name or name.startswith(".") or name in [".", ".."]: - continue - - item_uri = VikingURI(uri).join(name).uri - - if entry.get("isDir", False): - # Child directory - children_uris.append(item_uri) - # Recursively collect children - await self._collect_directory_info(item_uri, result) - else: - # File (not starting with .) - file_paths.append(item_uri) - - # Add current directory info - result.append((uri, children_uris, file_paths)) + current_stat = await viking_fs.stat(file_path, ctx=ctx) + target_stat = await viking_fs.stat(target_file, ctx=ctx) + current_size = current_stat.get("size") if isinstance(current_stat, dict) else None + target_size = target_stat.get("size") if isinstance(target_stat, dict) else None + if current_size is not None and target_size is not None and current_size != target_size: + return True + current_content = await viking_fs.read_file(file_path, ctx=ctx) + target_content = await viking_fs.read_file(target_file, ctx=ctx) + return current_content != target_content + except Exception: + return True async def on_dequeue(self, data: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]: """Process dequeued SemanticMsg, recursively process all subdirectories.""" + msg: Optional[SemanticMsg] = None + collector = None try: import json @@ -161,152 +217,397 @@ async def on_dequeue(self, data: Optional[Dict[str, Any]]) -> Optional[Dict[str, if "data" in data and isinstance(data["data"], str): data = json.loads(data["data"]) - # data is guaranteed to be not None at this point assert data is not None msg = SemanticMsg.from_dict(data) - self._current_msg = msg - self._current_ctx = self._ctx_from_semantic_msg(msg) - logger.info( - f"Processing semantic generation for: {msg.uri} (recursive={msg.recursive})" - ) - - if msg.recursive: - executor = SemanticDagExecutor( - processor=self, - context_type=msg.context_type, - max_concurrent_llm=self.max_concurrent_llm, - ctx=self._current_ctx, + collector = resolve_telemetry(msg.telemetry_id) + telemetry_ctx = bind_telemetry(collector) if collector is not None else nullcontext() + with telemetry_ctx: + self._current_msg = msg + self._current_ctx = self._ctx_from_semantic_msg(msg) + logger.info( + f"Processing semantic generation for: {msg.uri} (recursive={msg.recursive})" ) - self._dag_executor = executor - await executor.run(msg.uri) - logger.info(f"Completed semantic generation for: {msg.uri}") - self.report_success() - return None - else: - # Non-recursive processing: directly process this directory - children_uris = [] - file_paths = [] - # Collect immediate children info only (no recursion) - viking_fs = get_viking_fs() - try: - entries = await viking_fs.ls(msg.uri, ctx=self._current_ctx) - for entry in entries: - name = entry.get("name", "") - if not name or name.startswith(".") or name in [".", ".."]: - continue - - item_uri = VikingURI(msg.uri).join(name).uri - - if entry.get("isDir", False): - children_uris.append(item_uri) - else: - file_paths.append(item_uri) - except Exception as e: - logger.warning(f"Failed to list directory {msg.uri}: {e}") - - # Process this directory - await self._process_single_directory( - uri=msg.uri, - context_type=msg.context_type, - children_uris=children_uris, - file_paths=file_paths, - ) + logger.info(f"Processing semantic generation for: {msg})") + if msg.context_type == "memory": + await self._process_memory_directory(msg) + else: + is_incremental = False + viking_fs = get_viking_fs() + if msg.target_uri: + target_exists = await viking_fs.exists( + msg.target_uri, ctx=self._current_ctx + ) + # Check if target URI exists and is not the same as the source URI(避免重复处理) + if target_exists and msg.uri != msg.target_uri: + is_incremental = True + logger.info( + f"Target URI exists, using incremental update: {msg.target_uri}" + ) + + # Re-acquire lifecycle lock if handle was lost (e.g. server restart) + if msg.lifecycle_lock_handle_id: + lock_uri = msg.target_uri or msg.uri + msg.lifecycle_lock_handle_id = await self._ensure_lifecycle_lock( + msg.lifecycle_lock_handle_id, + viking_fs._uri_to_path(lock_uri, ctx=self._current_ctx), + ) + + executor = SemanticDagExecutor( + processor=self, + context_type=msg.context_type, + max_concurrent_llm=self.max_concurrent_llm, + ctx=self._current_ctx, + incremental_update=is_incremental, + target_uri=msg.target_uri, + semantic_msg_id=msg.id, + recursive=msg.recursive, + lifecycle_lock_handle_id=msg.lifecycle_lock_handle_id, + ) + self._dag_executor = executor + await executor.run(msg.uri) + self._cache_dag_stats( + msg.telemetry_id, + msg.uri, + executor.get_stats(), + ) + self._merge_request_stats(msg.telemetry_id, processed=1) logger.info(f"Completed semantic generation for: {msg.uri}") self.report_success() return None except Exception as e: logger.error(f"Failed to process semantic message: {e}", exc_info=True) + if msg is not None: + self._merge_request_stats(msg.telemetry_id, error_count=1) self.report_error(str(e), data) return None finally: + # Safety net: release lifecycle lock if still held (e.g. on exception + # before the DAG executor took ownership) + if msg and msg.lifecycle_lock_handle_id: + try: + from openviking.storage.transaction import get_lock_manager + + lm = get_lock_manager() + handle = lm.get_handle(msg.lifecycle_lock_handle_id) + if handle: + await lm.release(handle) + logger.info( + f"[SemanticProcessor] Safety-net released lifecycle lock " + f"{msg.lifecycle_lock_handle_id}" + ) + except Exception: + pass self._current_msg = None + self._current_ctx = None def get_dag_stats(self) -> Optional["DagStats"]: if not self._dag_executor: return None return self._dag_executor.get_stats() - async def _process_single_directory( - self, - uri: str, - context_type: str, - children_uris: List[str], - file_paths: List[str], - ) -> None: - """Process single directory, generate .abstract.md and .overview.md.""" + @staticmethod + async def _ensure_lifecycle_lock(handle_id: str, lock_path: str) -> str: + """If the handle is missing (server restart), re-acquire a SUBTREE lock. + + Returns the (possibly new) handle ID, or "" on failure. + """ + from openviking.storage.transaction import get_lock_manager + + lm = get_lock_manager() + if lm.get_handle(handle_id): + return handle_id + new_handle = lm.create_handle() + if await lm.acquire_subtree(new_handle, lock_path): + logger.info(f"Re-acquired lifecycle lock on {lock_path} (handle {new_handle.id})") + return new_handle.id + logger.warning(f"Failed to re-acquire lifecycle lock on {lock_path}") + await lm.release(new_handle) + return "" + + async def _process_memory_directory(self, msg: SemanticMsg) -> None: + """Process a memory directory with special handling. + + For memory directories: + - Memory files are already vectorized via embedding queue + - Only generate abstract.md and overview.md + - Vectorize the generated abstract.md and overview.md + + Args: + msg: The semantic message containing directory info and changes + """ viking_fs = get_viking_fs() + dir_uri = msg.uri + ctx = self._current_ctx + llm_sem = asyncio.Semaphore(self.max_concurrent_llm) - # 1. Collect .abstract.md from subdirectories (already processed earlier) - children_abstracts = await self._collect_children_abstracts(children_uris) + try: + entries = await viking_fs.ls(dir_uri, ctx=ctx) + except Exception as e: + logger.warning(f"Failed to list memory directory {dir_uri}: {e}") + return - # 2. Concurrently generate summaries for files in directory - file_summaries = await self._generate_file_summaries( - file_paths, context_type=context_type, parent_uri=uri, enqueue_files=True - ) + file_paths: List[str] = [] + for entry in entries: + name = entry.get("name", "") + if not name or name.startswith(".") or name in [".", ".."]: + continue + if not entry.get("isDir", False): + item_uri = VikingURI(dir_uri).join(name).uri + file_paths.append(item_uri) + + if not file_paths: + logger.info(f"No memory files found in {dir_uri}") + return - # 3. Generate .overview.md (contains brief description) - overview = await self._generate_overview(uri, file_summaries, children_abstracts) + file_summaries: List[Dict[str, str]] = [] + existing_summaries: Dict[str, str] = {} + + if msg.changes: + try: + old_overview = await viking_fs.read_file(f"{dir_uri}/.overview.md", ctx=ctx) + if old_overview: + existing_summaries = self._parse_overview_md(old_overview) + logger.info( + f"Parsed {len(existing_summaries)} existing summaries from overview.md" + ) + except Exception as e: + logger.debug(f"No existing overview.md found for {dir_uri}: {e}") + + changed_files: Set[str] = set() + if msg.changes: + changed_files = set(msg.changes.get("added", []) + msg.changes.get("modified", [])) + deleted_files = set(msg.changes.get("deleted", [])) + logger.info( + f"Processing memory directory {dir_uri} with changes: " + f"added={len(msg.changes.get('added', []))}, " + f"modified={len(msg.changes.get('modified', []))}, " + f"deleted={len(deleted_files)}" + ) - # 4. Extract abstract from overview + for file_path in file_paths: + file_name = file_path.split("/")[-1] + + if file_path not in changed_files and file_name in existing_summaries: + file_summaries.append({"name": file_name, "summary": existing_summaries[file_name]}) + logger.debug(f"Reused existing summary for {file_name}") + else: + try: + summary_dict = await self._generate_single_file_summary( + file_path, llm_sem=llm_sem, ctx=ctx + ) + file_summaries.append(summary_dict) + logger.debug(f"Generated summary for {file_name}") + except Exception as e: + logger.warning(f"Failed to generate summary for {file_path}: {e}") + file_summaries.append({"name": file_name, "summary": ""}) + + overview = await self._generate_overview(dir_uri, file_summaries, []) abstract = self._extract_abstract_from_overview(overview) + overview, abstract = self._enforce_size_limits(overview, abstract) + + try: + await viking_fs.write_file(f"{dir_uri}/.overview.md", overview, ctx=ctx) + await viking_fs.write_file(f"{dir_uri}/.abstract.md", abstract, ctx=ctx) + logger.info(f"Generated abstract.md and overview.md for {dir_uri}") + except Exception as e: + logger.error(f"Failed to write abstract/overview for {dir_uri}: {e}") + return + + await self._vectorize_directory( + uri=dir_uri, + context_type="memory", + abstract=abstract, + overview=overview, + ctx=ctx, + semantic_msg_id=msg.id, + ) + logger.info(f"Vectorized abstract.md and overview.md for {dir_uri}") + + async def _sync_topdown_recursive( + self, + root_uri: str, + target_uri: str, + ctx: Optional[RequestContext] = None, + file_change_status: Optional[Dict[str, bool]] = None, + ) -> DiffResult: + viking_fs = get_viking_fs() + diff = DiffResult() + + async def list_children(dir_uri: str) -> Tuple[Dict[str, str], Dict[str, str]]: + files: Dict[str, str] = {} + dirs: Dict[str, str] = {} + try: + entries = await viking_fs.ls(dir_uri, show_all_hidden=True, ctx=ctx) + except Exception as e: + logger.error(f"[SyncDiff] Failed to list {dir_uri}: {e}") + return files, dirs + + for entry in entries: + name = entry.get("name", "") + if not name or name in [".", ".."]: + continue + if name.startswith(".") and name not in [".abstract.md", ".overview.md"]: + continue + item_uri = VikingURI(dir_uri).join(name).uri + if entry.get("isDir", False): + dirs[name] = item_uri + else: + files[name] = item_uri + return files, dirs + + async def sync_dir(root_dir: str, target_dir: str) -> None: + root_files, root_dirs = await list_children(root_dir) + target_files, target_dirs = await list_children(target_dir) + + file_names = set(root_files.keys()) | set(target_files.keys()) + for name in sorted(file_names): + root_file = root_files.get(name) + target_file = target_files.get(name) + + if root_file and name in target_dirs: + target_conflict_dir = target_dirs[name] + try: + await viking_fs.rm(target_conflict_dir, recursive=True, ctx=ctx) + diff.deleted_dirs.append(target_conflict_dir) + target_dirs.pop(name, None) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to delete directory for file conflict: {target_conflict_dir}, error={e}" + ) + target_file = None + + if target_file and name in root_dirs and not root_file: + try: + await viking_fs.rm(target_file, ctx=ctx) + diff.deleted_files.append(target_file) + target_files.pop(name, None) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to delete file for dir conflict: {target_file}, error={e}" + ) + continue + + if target_file and not root_file: + try: + await viking_fs.rm(target_file, ctx=ctx) + diff.deleted_files.append(target_file) + except Exception as e: + logger.error(f"[SyncDiff] Failed to delete file: {target_file}, error={e}") + continue + + if root_file and target_file: + changed = False + if file_change_status and root_file in file_change_status: + changed = file_change_status[root_file] + else: + try: + changed = await self._check_file_content_changed( + root_file, target_file, ctx=ctx + ) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to compare file content for {root_file}: {e}, treating as unchanged" + ) + changed = False + if changed: + diff.updated_files.append(root_file) + try: + await viking_fs.rm(target_file, ctx=ctx) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to remove old file before update: {target_file}, error={e}" + ) + try: + await viking_fs.mv(root_file, target_file, ctx=ctx) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to move updated file: {root_file} -> {target_file}, error={e}" + ) + continue + + if root_file and not target_file: + diff.added_files.append(root_file) + target_file_uri = VikingURI(target_dir).join(name).uri + try: + await viking_fs.mv(root_file, target_file_uri, ctx=ctx) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to move added file: {root_file} -> {target_file_uri}, error={e}" + ) + + dir_names = set(root_dirs.keys()) | set(target_dirs.keys()) + for name in sorted(dir_names): + root_subdir = root_dirs.get(name) + target_subdir = target_dirs.get(name) + + if root_subdir and name in target_files: + target_conflict_file = target_files[name] + try: + await viking_fs.rm(target_conflict_file, ctx=ctx) + diff.deleted_files.append(target_conflict_file) + target_files.pop(name, None) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to delete file for dir conflict: {target_conflict_file}, error={e}" + ) + target_subdir = None + + if target_subdir and not root_subdir: + try: + await viking_fs.rm(target_subdir, recursive=True, ctx=ctx) + diff.deleted_dirs.append(target_subdir) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to delete directory: {target_subdir}, error={e}" + ) + continue + + if root_subdir and not target_subdir: + diff.added_dirs.append(root_subdir) + target_subdir_uri = VikingURI(target_dir).join(name).uri + try: + await viking_fs.mv(root_subdir, target_subdir_uri, ctx=ctx) + except Exception as e: + logger.error( + f"[SyncDiff] Failed to move added directory: {root_subdir} -> {target_subdir_uri}, error={e}" + ) + continue - # 5. Write files - await viking_fs.write_file(f"{uri}/.overview.md", overview, ctx=self._current_ctx) - await viking_fs.write_file(f"{uri}/.abstract.md", abstract, ctx=self._current_ctx) + if root_subdir and target_subdir: + await sync_dir(root_subdir, target_subdir) - logger.debug(f"Generated overview and abstract for {uri}") + target_exists = await viking_fs.exists(target_uri, ctx=ctx) + if not target_exists: + parent_uri = VikingURI(target_uri).parent + if parent_uri: + await viking_fs.mkdir(parent_uri.uri, exist_ok=True, ctx=ctx) + diff.added_dirs.append(root_uri) + await viking_fs.mv(root_uri, target_uri, ctx=ctx) + return diff - # 6. Vectorize directory + await sync_dir(root_uri, target_uri) try: - await self._vectorize_directory_simple(uri, context_type, abstract, overview) + await viking_fs.delete_temp(root_uri, ctx=ctx) except Exception as e: - logger.error(f"Failed to vectorize directory {uri}: {e}", exc_info=True) + logger.error(f"[SyncDiff] Failed to delete root directory {root_uri}: {e}") + return diff - async def _collect_children_abstracts(self, children_uris: List[str]) -> List[Dict[str, str]]: + async def _collect_children_abstracts( + self, children_uris: List[str], ctx: Optional[RequestContext] = None + ) -> List[Dict[str, str]]: """Collect .abstract.md from subdirectories.""" viking_fs = get_viking_fs() results = [] for child_uri in children_uris: - abstract = await viking_fs.abstract(child_uri, ctx=self._current_ctx) + abstract = await viking_fs.abstract(child_uri, ctx=ctx) dir_name = child_uri.split("/")[-1] results.append({"name": dir_name, "abstract": abstract}) return results - async def _generate_file_summaries( - self, - file_paths: List[str], - context_type: Optional[str] = None, - parent_uri: Optional[str] = None, - enqueue_files: bool = False, - ) -> List[Dict[str, str]]: - """Concurrently generate file summaries.""" - if not file_paths: - return [] - - async def generate_one_summary(file_path: str) -> Dict[str, str]: - summary = await self._generate_single_file_summary(file_path, ctx=self._current_ctx) - if enqueue_files and context_type and parent_uri: - try: - await self._vectorize_single_file( - parent_uri=parent_uri, - context_type=context_type, - file_path=file_path, - summary_dict=summary, - ) - except Exception as e: - logger.error( - f"Failed to vectorize file {file_path}: {e}", - exc_info=True, - ) - return summary - - tasks = [generate_one_summary(fp) for fp in file_paths] - return await asyncio.gather(*tasks) - async def _generate_text_summary( self, file_path: str, @@ -319,11 +620,6 @@ async def _generate_text_summary( vlm = get_openviking_config().vlm active_ctx = ctx or self._current_ctx - # Read file content (limit length) - content = await viking_fs.read_file(file_path, ctx=active_ctx) - - # Limit content length (about 10000 tokens) - max_chars = 30000 content = await viking_fs.read_file(file_path, ctx=active_ctx) if isinstance(content, bytes): # Try to decode with error handling for text files @@ -333,8 +629,8 @@ async def _generate_text_summary( logger.warning(f"Failed to decode file as UTF-8, skipping: {file_path}") return {"name": file_name, "summary": ""} - # Limit content length (about 10000 tokens) - max_chars = 30000 + # Limit content length + max_chars = get_openviking_config().semantic.max_file_content_chars if len(content) > max_chars: content = content[:max_chars] + "\n...(truncated)" @@ -442,6 +738,68 @@ def _extract_abstract_from_overview(self, overview_content: str) -> str: return "\n".join(content_lines).strip() + def _enforce_size_limits(self, overview: str, abstract: str) -> Tuple[str, str]: + """Enforce max size limits on overview and abstract.""" + semantic = get_openviking_config().semantic + if len(overview) > semantic.overview_max_chars: + overview = overview[: semantic.overview_max_chars] + if len(abstract) > semantic.abstract_max_chars: + abstract = abstract[: semantic.abstract_max_chars - 3] + "..." + return overview, abstract + + def _parse_overview_md(self, overview_content: str) -> Dict[str, str]: + """Parse overview.md and extract file summaries. + + Args: + overview_content: Content of the overview.md file + + Returns: + Dictionary mapping file names to their summaries + """ + import re + + summaries: Dict[str, str] = {} + + if not overview_content or not overview_content.strip(): + return summaries + + lines = overview_content.split("\n") + current_file = None + current_summary_lines: List[str] = [] + + for line in lines: + header_match = re.match(r"^###\s+(.+?)\s*$", line) + if header_match: + if current_file and current_summary_lines: + summaries[current_file] = " ".join(current_summary_lines).strip() + + file_name = header_match.group(1).strip() + parts = file_name.split() + if len(parts) >= 2 and parts[0] == parts[1]: + file_name = parts[0] + + current_file = file_name + current_summary_lines = [] + continue + + numbered_match = re.match(r"^\[(\d+)\]\s+(.+?):\s*(.+)$", line) + if numbered_match: + if current_file and current_summary_lines: + summaries[current_file] = " ".join(current_summary_lines).strip() + current_file = numbered_match.group(2).strip() + current_summary_lines = [numbered_match.group(3).strip()] + continue + + if current_file: + stripped = line.strip() + if stripped and not stripped.startswith("#"): + current_summary_lines.append(stripped) + + if current_file and current_summary_lines: + summaries[current_file] = " ".join(current_summary_lines).strip() + + return summaries + async def _generate_overview( self, dir_uri: str, @@ -450,6 +808,11 @@ async def _generate_overview( ) -> str: """Generate directory's .overview.md (L1). + For small directories, generates a single overview from all file summaries. + For large directories that would exceed the prompt budget, splits file + summaries into batches, generates a partial overview per batch, then + merges the partials into a final overview. + Args: dir_uri: Directory URI file_summaries: File summary list @@ -458,9 +821,10 @@ async def _generate_overview( Returns: Overview content """ - import re - vlm = get_openviking_config().vlm + config = get_openviking_config() + vlm = config.vlm + semantic = config.semantic if not vlm.is_available(): logger.warning("VLM not available, using default overview") @@ -481,7 +845,64 @@ async def _generate_overview( else "None" ) - # Generate overview + # Budget guard: check if prompt would be oversized + estimated_size = len(file_summaries_str) + len(children_abstracts_str) + over_budget = estimated_size > semantic.max_overview_prompt_chars + many_files = len(file_summaries) > semantic.overview_batch_size + + if over_budget and many_files: + # Many files, oversized prompt → batch and merge + logger.info( + f"Overview prompt for {dir_uri} exceeds budget " + f"({estimated_size} chars, {len(file_summaries)} files). " + f"Splitting into batches of {semantic.overview_batch_size}." + ) + overview = await self._batched_generate_overview( + dir_uri, file_summaries, children_abstracts, file_index_map + ) + elif over_budget: + # Few files but long summaries → truncate summaries to fit budget + logger.info( + f"Overview prompt for {dir_uri} exceeds budget " + f"({estimated_size} chars) with {len(file_summaries)} files. " + f"Truncating summaries to fit." + ) + budget = semantic.max_overview_prompt_chars + budget -= len(children_abstracts_str) + per_file = max(100, budget // max(len(file_summaries), 1)) + truncated_lines = [] + for idx, item in enumerate(file_summaries, 1): + summary = item["summary"][:per_file] + truncated_lines.append(f"[{idx}] {item['name']}: {summary}") + file_summaries_str = "\n".join(truncated_lines) + overview = await self._single_generate_overview( + dir_uri, + file_summaries_str, + children_abstracts_str, + file_index_map, + ) + else: + overview = await self._single_generate_overview( + dir_uri, + file_summaries_str, + children_abstracts_str, + file_index_map, + ) + + return overview + + async def _single_generate_overview( + self, + dir_uri: str, + file_summaries_str: str, + children_abstracts_str: str, + file_index_map: Dict[int, str], + ) -> str: + """Generate overview from a single prompt (small directories).""" + import re + + vlm = get_openviking_config().vlm + try: prompt = render_prompt( "semantic.overview_generation", @@ -504,16 +925,123 @@ def replace_index(match): return overview.strip() except Exception as e: - logger.error(f"Failed to generate overview for {dir_uri}: {e}", exc_info=True) + logger.error( + f"Failed to generate overview for {dir_uri}: {e}", + exc_info=True, + ) return f"# {dir_uri.split('/')[-1]}\n\nDirectory overview" - async def _vectorize_directory_simple( + async def _batched_generate_overview( + self, + dir_uri: str, + file_summaries: List[Dict[str, str]], + children_abstracts: List[Dict[str, str]], + file_index_map: Dict[int, str], + ) -> str: + """Generate overview by batching file summaries and merging. + + Splits file summaries into batches, generates a partial overview per + batch, then merges all partials into a final overview. + """ + import re + + vlm = get_openviking_config().vlm + semantic = get_openviking_config().semantic + batch_size = semantic.overview_batch_size + dir_name = dir_uri.split("/")[-1] + + # Split file summaries into batches + batches = [ + file_summaries[i : i + batch_size] for i in range(0, len(file_summaries), batch_size) + ] + logger.info(f"Generating overview for {dir_uri} in {len(batches)} batches") + + # Build children abstracts string (used in first batch + merge) + children_abstracts_str = ( + "\n".join(f"- {item['name']}/: {item['abstract']}" for item in children_abstracts) + if children_abstracts + else "None" + ) + + # Generate partial overview per batch using global file indices + partial_overviews = [] + global_offset = 0 + for batch_idx, batch in enumerate(batches): + # Build per-batch index map using global offsets + batch_lines = [] + batch_index_map = {} + for local_idx, item in enumerate(batch): + global_idx = global_offset + local_idx + 1 + batch_index_map[global_idx] = item["name"] + batch_lines.append(f"[{global_idx}] {item['name']}: {item['summary']}") + batch_str = "\n".join(batch_lines) + global_offset += len(batch) + + # Include children abstracts in the first batch + children_str = children_abstracts_str if batch_idx == 0 else "None" + + try: + prompt = render_prompt( + "semantic.overview_generation", + { + "dir_name": dir_name, + "file_summaries": batch_str, + "children_abstracts": children_str, + }, + ) + partial = await vlm.get_completion_async(prompt) + + # Replace [number] references per batch using batch-local map + def make_replacer(idx_map): + def replacer(match): + idx = int(match.group(1)) + return idx_map.get(idx, match.group(0)) + + return replacer + + partial = re.sub(r"\[(\d+)\]", make_replacer(batch_index_map), partial) + partial_overviews.append(partial.strip()) + except Exception as e: + logger.warning( + f"Failed to generate partial overview batch " + f"{batch_idx + 1}/{len(batches)} for {dir_uri}: {e}" + ) + + if not partial_overviews: + return f"# {dir_name}\n\nDirectory overview" + + # If only one batch succeeded, use it directly + if len(partial_overviews) == 1: + return partial_overviews[0] + + # Merge partials into a final overview (include children for context) + combined = "\n\n---\n\n".join(partial_overviews) + try: + prompt = render_prompt( + "semantic.overview_generation", + { + "dir_name": dir_name, + "file_summaries": combined, + "children_abstracts": children_abstracts_str, + }, + ) + overview = await vlm.get_completion_async(prompt) + return overview.strip() + except Exception as e: + logger.error( + f"Failed to merge partial overviews for {dir_uri}: {e}", + exc_info=True, + ) + return partial_overviews[0] + + async def _vectorize_directory( self, uri: str, context_type: str, abstract: str, overview: str, ctx: Optional[RequestContext] = None, + semantic_msg_id: Optional[str] = None, ) -> None: """Create directory Context and enqueue to EmbeddingQueue.""" @@ -530,40 +1058,17 @@ async def _vectorize_directory_simple( overview=overview, context_type=context_type, ctx=active_ctx, + semantic_msg_id=semantic_msg_id, ) - async def _vectorize_files( - self, - uri: str, - context_type: str, - file_paths: List[str], - file_summaries: List[Dict[str, str]], - ctx: Optional[RequestContext] = None, - ) -> None: - """Vectorize files in directory.""" - from openviking.storage.queuefs import get_queue_manager - - queue_manager = get_queue_manager() - embedding_queue = queue_manager.get_queue(queue_manager.EMBEDDING) - - for file_path, file_summary_dict in zip(file_paths, file_summaries): - await self._vectorize_single_file( - parent_uri=uri, - context_type=context_type, - file_path=file_path, - summary_dict=file_summary_dict, - embedding_queue=embedding_queue, - ctx=ctx, - ) - async def _vectorize_single_file( self, parent_uri: str, context_type: str, file_path: str, summary_dict: Dict[str, str], - embedding_queue: Optional[Any] = None, ctx: Optional[RequestContext] = None, + semantic_msg_id: Optional[str] = None, ) -> None: """Vectorize a single file using its content or summary.""" from openviking.utils.embedding_utils import vectorize_file @@ -575,4 +1080,5 @@ async def _vectorize_single_file( parent_uri=parent_uri, context_type=context_type, ctx=active_ctx, + semantic_msg_id=semantic_msg_id, ) diff --git a/openviking/storage/transaction/__init__.py b/openviking/storage/transaction/__init__.py index b6c06d6e..52e77ff7 100644 --- a/openviking/storage/transaction/__init__.py +++ b/openviking/storage/transaction/__init__.py @@ -3,25 +3,30 @@ """ Transaction module for OpenViking. -Provides transaction management and lock mechanisms for data operations. +Provides path-lock management and redo-log crash recovery. """ -from openviking.storage.transaction.path_lock import PathLock -from openviking.storage.transaction.transaction_manager import ( - TransactionManager, - get_transaction_manager, - init_transaction_manager, -) -from openviking.storage.transaction.transaction_record import ( - TransactionRecord, - TransactionStatus, +from openviking.storage.transaction.lock_context import LockContext +from openviking.storage.transaction.lock_handle import LockHandle, LockOwner +from openviking.storage.transaction.lock_manager import ( + LockManager, + get_lock_manager, + init_lock_manager, + release_all_locks, + reset_lock_manager, ) +from openviking.storage.transaction.path_lock import PathLock +from openviking.storage.transaction.redo_log import RedoLog __all__ = [ + "LockContext", + "LockHandle", + "LockManager", + "LockOwner", "PathLock", - "TransactionManager", - "TransactionRecord", - "TransactionStatus", - "init_transaction_manager", - "get_transaction_manager", + "RedoLog", + "get_lock_manager", + "init_lock_manager", + "release_all_locks", + "reset_lock_manager", ] diff --git a/openviking/storage/transaction/lock_context.py b/openviking/storage/transaction/lock_context.py new file mode 100644 index 00000000..4d1d8443 --- /dev/null +++ b/openviking/storage/transaction/lock_context.py @@ -0,0 +1,68 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""LockContext — async context manager for acquiring/releasing path locks.""" + +from typing import Optional + +from openviking.storage.errors import LockAcquisitionError +from openviking.storage.transaction.lock_handle import LockHandle +from openviking.storage.transaction.lock_manager import LockManager + + +class LockContext: + """``async with LockContext(manager, paths, mode) as handle: ...`` + + Acquires locks on entry, releases them on exit. No undo / journal / commit + semantics — just a lock scope. + """ + + def __init__( + self, + lock_manager: LockManager, + paths: list[str], + lock_mode: str = "point", + mv_dst_parent_path: Optional[str] = None, + src_is_dir: bool = True, + ): + self._manager = lock_manager + self._paths = paths + self._lock_mode = lock_mode + self._mv_dst_parent_path = mv_dst_parent_path + self._src_is_dir = src_is_dir + self._handle: Optional[LockHandle] = None + + async def __aenter__(self) -> LockHandle: + self._handle = self._manager.create_handle() + success = False + + if self._lock_mode == "subtree": + for path in self._paths: + success = await self._manager.acquire_subtree(self._handle, path) + if not success: + break + elif self._lock_mode == "mv": + if self._mv_dst_parent_path is None: + raise LockAcquisitionError("mv lock mode requires mv_dst_parent_path") + success = await self._manager.acquire_mv( + self._handle, + self._paths[0], + self._mv_dst_parent_path, + src_is_dir=self._src_is_dir, + ) + else: # "point" + for path in self._paths: + success = await self._manager.acquire_point(self._handle, path) + if not success: + break + + if not success: + await self._manager.release(self._handle) + raise LockAcquisitionError( + f"Failed to acquire {self._lock_mode} lock for {self._paths}" + ) + return self._handle + + async def __aexit__(self, exc_type, exc_val, exc_tb): + if self._handle: + await self._manager.release(self._handle) + return False diff --git a/openviking/storage/transaction/lock_handle.py b/openviking/storage/transaction/lock_handle.py new file mode 100644 index 00000000..7b5be5d9 --- /dev/null +++ b/openviking/storage/transaction/lock_handle.py @@ -0,0 +1,37 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Lock handle and LockOwner protocol for PathLock integration.""" + +import time +import uuid +from dataclasses import dataclass, field +from typing import Protocol, runtime_checkable + + +@runtime_checkable +class LockOwner(Protocol): + """Minimal interface that PathLock requires from its caller.""" + + id: str + locks: list[str] + + def add_lock(self, path: str) -> None: ... + def remove_lock(self, path: str) -> None: ... + + +@dataclass +class LockHandle: + """Identifies a lock holder. PathLock uses ``id`` to generate fencing tokens + and ``locks`` to track acquired lock files.""" + + id: str = field(default_factory=lambda: str(uuid.uuid4())) + locks: list[str] = field(default_factory=list) + created_at: float = field(default_factory=time.time) + + def add_lock(self, lock_path: str) -> None: + if lock_path not in self.locks: + self.locks.append(lock_path) + + def remove_lock(self, lock_path: str) -> None: + if lock_path in self.locks: + self.locks.remove(lock_path) diff --git a/openviking/storage/transaction/lock_manager.py b/openviking/storage/transaction/lock_manager.py new file mode 100644 index 00000000..2fec7e42 --- /dev/null +++ b/openviking/storage/transaction/lock_manager.py @@ -0,0 +1,263 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""LockManager — global singleton managing lock lifecycle and redo recovery.""" + +import asyncio +import json +import time +from typing import Any, Dict, Optional + +from openviking.pyagfs import AGFSClient +from openviking.storage.transaction.lock_handle import LockHandle +from openviking.storage.transaction.path_lock import PathLock +from openviking.storage.transaction.redo_log import RedoLog +from openviking_cli.utils.logger import get_logger + +logger = get_logger(__name__) + + +class LockManager: + """Global singleton. Manages lock lifecycle and stale cleanup.""" + + def __init__( + self, + agfs: AGFSClient, + lock_timeout: float = 0.0, + lock_expire: float = 300.0, + ): + self._agfs = agfs + self._path_lock = PathLock(agfs, lock_expire=lock_expire) + self._lock_timeout = lock_timeout + self._redo_log = RedoLog(agfs) + self._handles: Dict[str, LockHandle] = {} + self._cleanup_task: Optional[asyncio.Task] = None + self._running = False + + @property + def redo_log(self) -> RedoLog: + return self._redo_log + + def get_active_handles(self) -> Dict[str, LockHandle]: + return dict(self._handles) + + async def start(self) -> None: + """Start background cleanup and redo recovery.""" + self._running = True + self._cleanup_task = asyncio.create_task(self._stale_cleanup_loop()) + await self._recover_pending_redo() + + async def stop(self) -> None: + """Stop cleanup and release all active locks.""" + self._running = False + if self._cleanup_task: + self._cleanup_task.cancel() + try: + if self._cleanup_task.get_loop() is asyncio.get_running_loop(): + await self._cleanup_task + except asyncio.CancelledError: + pass + self._cleanup_task = None + for handle in list(self._handles.values()): + await self._path_lock.release(handle) + self._handles.clear() + + def create_handle(self) -> LockHandle: + handle = LockHandle() + self._handles[handle.id] = handle + return handle + + async def acquire_point( + self, handle: LockHandle, path: str, timeout: Optional[float] = None + ) -> bool: + return await self._path_lock.acquire_point( + path, handle, timeout=timeout if timeout is not None else self._lock_timeout + ) + + async def acquire_subtree( + self, handle: LockHandle, path: str, timeout: Optional[float] = None + ) -> bool: + return await self._path_lock.acquire_subtree( + path, handle, timeout=timeout if timeout is not None else self._lock_timeout + ) + + async def acquire_mv( + self, + handle: LockHandle, + src: str, + dst_parent: str, + src_is_dir: bool = True, + timeout: Optional[float] = None, + ) -> bool: + return await self._path_lock.acquire_mv( + src, + dst_parent, + handle, + timeout=timeout if timeout is not None else self._lock_timeout, + src_is_dir=src_is_dir, + ) + + def get_handle(self, handle_id: str) -> Optional[LockHandle]: + return self._handles.get(handle_id) + + async def refresh_lock(self, handle: LockHandle) -> None: + await self._path_lock.refresh(handle) + + async def release(self, handle: LockHandle) -> None: + await self._path_lock.release(handle) + self._handles.pop(handle.id, None) + + async def _stale_cleanup_loop(self) -> None: + """Check and release leaked handles every 60 s (in-process safety net).""" + while self._running: + await asyncio.sleep(60) + now = time.time() + stale = [h for h in self._handles.values() if now - h.created_at > 3600] + for handle in stale: + logger.warning(f"Releasing stale lock handle {handle.id}") + await self.release(handle) + + # ------------------------------------------------------------------ + # Redo recovery (session_memory only) + # ------------------------------------------------------------------ + + async def _recover_pending_redo(self) -> None: + pending_ids = self._redo_log.list_pending() + for task_id in pending_ids: + logger.info(f"Recovering pending redo task: {task_id}") + try: + info = self._redo_log.read(task_id) + if info: + await self._redo_session_memory(info) + self._redo_log.mark_done(task_id) + except Exception as e: + logger.error(f"Redo recovery failed for {task_id}: {e}", exc_info=True) + + async def _redo_session_memory(self, info: Dict[str, Any]) -> None: + """Re-extract memories from archive. + + Lets exceptions from _enqueue_semantic propagate so the caller + can decide whether to mark the redo task as done. + """ + from openviking.message import Message + from openviking.server.identity import RequestContext, Role + from openviking.session.compressor import SessionCompressor + from openviking.storage.viking_fs import get_viking_fs + from openviking_cli.session.user_id import UserIdentifier + + archive_uri = info.get("archive_uri") + session_uri = info.get("session_uri") + account_id = info.get("account_id", "default") + user_id = info.get("user_id", "default") + agent_id = info.get("agent_id", "default") + role_str = info.get("role", "root") + + if not archive_uri or not session_uri: + raise ValueError("Cannot redo session_memory: missing archive_uri or session_uri") + + # 1. Build request context (needed for path conversion below) + user = UserIdentifier(account_id=account_id, user_id=user_id, agent_id=agent_id) + ctx = RequestContext(user=user, role=Role(role_str)) + + # 2. Read archived messages + messages_uri = f"{archive_uri}/messages.jsonl" + viking_fs = get_viking_fs() + agfs_path = viking_fs._uri_to_path(messages_uri, ctx=ctx) + messages = [] + try: + content = self._agfs.cat(agfs_path) + if isinstance(content, bytes): + content = content.decode("utf-8") + for line in content.strip().split("\n"): + if line.strip(): + try: + messages.append(Message.from_dict(json.loads(line))) + except Exception: + pass + except Exception as e: + logger.warning(f"Cannot read archive for redo: {agfs_path}: {e}") + + # 3. Re-extract memories (best-effort, only if archive was readable) + if messages: + session_id = session_uri.rstrip("/").rsplit("/", 1)[-1] + try: + compressor = SessionCompressor(vikingdb=None) + memories = await compressor.extract_long_term_memories( + messages=messages, + user=user, + session_id=session_id, + ctx=ctx, + ) + logger.info(f"Redo: extracted {len(memories)} memories from {archive_uri}") + except Exception as e: + logger.warning(f"Redo: memory extraction failed ({e}), falling back to queue") + + # 4. Always enqueue semantic processing as fallback + await self._enqueue_semantic( + uri=session_uri, + context_type="memory", + account_id=account_id, + user_id=user_id, + agent_id=agent_id, + role=role_str, + ) + + async def _enqueue_semantic(self, **params: Any) -> None: + from openviking.storage.queuefs import get_queue_manager + from openviking.storage.queuefs.semantic_msg import SemanticMsg + from openviking.storage.queuefs.semantic_queue import SemanticQueue + + queue_manager = get_queue_manager() + if queue_manager is None: + logger.debug("No queue manager available, skipping enqueue_semantic") + return + + uri = params.get("uri") + if not uri: + return + + msg = SemanticMsg( + uri=uri, + context_type=params.get("context_type", "resource"), + account_id=params.get("account_id", "default"), + user_id=params.get("user_id", "default"), + agent_id=params.get("agent_id", "default"), + role=params.get("role", "root"), + ) + semantic_queue: SemanticQueue = queue_manager.get_queue(queue_manager.SEMANTIC) # type: ignore[assignment] + await semantic_queue.enqueue(msg) + + +# --------------------------------------------------------------------------- +# Module-level singleton +# --------------------------------------------------------------------------- + +_lock_manager: Optional[LockManager] = None + + +def init_lock_manager( + agfs: AGFSClient, + lock_timeout: float = 0.0, + lock_expire: float = 300.0, +) -> LockManager: + global _lock_manager + _lock_manager = LockManager(agfs=agfs, lock_timeout=lock_timeout, lock_expire=lock_expire) + return _lock_manager + + +def get_lock_manager() -> LockManager: + if _lock_manager is None: + raise RuntimeError("LockManager not initialized. Call init_lock_manager() first.") + return _lock_manager + + +def reset_lock_manager() -> None: + global _lock_manager + _lock_manager = None + + +async def release_all_locks() -> None: + """Release all active lock handles. **Test-only utility.**""" + if _lock_manager is None: + return + for handle in list(_lock_manager.get_active_handles().values()): + await _lock_manager.release(handle) diff --git a/openviking/storage/transaction/path_lock.py b/openviking/storage/transaction/path_lock.py index 1a2ad7b0..2aaaecf1 100644 --- a/openviking/storage/transaction/path_lock.py +++ b/openviking/storage/transaction/path_lock.py @@ -1,17 +1,9 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: Apache-2.0 -""" -Path lock implementation for transaction management. - -Provides path-based locking mechanism to prevent concurrent directory operations. -Lock protocol: viking://resources/.../.path.ovlock file exists = locked -""" - import asyncio -from typing import List, Optional +import time +from typing import Optional, Tuple from openviking.pyagfs import AGFSClient -from openviking.storage.transaction.transaction_record import TransactionRecord +from openviking.storage.transaction.lock_handle import LockOwner from openviking_cli.utils.logger import get_logger logger = get_logger(__name__) @@ -19,312 +11,383 @@ # Lock file name LOCK_FILE_NAME = ".path.ovlock" +# Lock type constants +LOCK_TYPE_POINT = "P" +LOCK_TYPE_SUBTREE = "S" -class PathLock: - """Path lock manager for transaction-based directory locking. +# Default poll interval when waiting for a lock (seconds) +_POLL_INTERVAL = 0.2 - Implements path-based locking using lock files (.path.ovlock) to prevent - concurrent operations on the same directory tree. - """ - def __init__(self, agfs_client: AGFSClient): - """Initialize path lock manager. +def _make_fencing_token(owner_id: str, lock_type: str = LOCK_TYPE_POINT) -> str: + return f"{owner_id}:{time.time_ns()}:{lock_type}" - Args: - agfs_client: AGFS client for file system operations - """ - self._agfs = agfs_client - def _get_lock_path(self, path: str) -> str: - """Get lock file path for a directory. +def _parse_fencing_token(token: str) -> Tuple[str, int, str]: + if token.endswith(f":{LOCK_TYPE_POINT}") or token.endswith(f":{LOCK_TYPE_SUBTREE}"): + lock_type = token[-1] + rest = token[:-2] + idx = rest.rfind(":") + if idx >= 0: + owner_id_part = rest[:idx] + ts_part = rest[idx + 1 :] + try: + return owner_id_part, int(ts_part), lock_type + except ValueError: + pass + return rest, 0, lock_type - Args: - path: Directory path to lock + if ":" in token: + idx = token.rfind(":") + owner_id_part = token[:idx] + ts_part = token[idx + 1 :] + try: + return owner_id_part, int(ts_part), LOCK_TYPE_POINT + except ValueError: + pass - Returns: - Lock file path (path/.path.ovlock) - """ - # Remove trailing slash if present + return token, 0, LOCK_TYPE_POINT + + +class PathLock: + def __init__(self, agfs_client: AGFSClient, lock_expire: float = 300.0): + self._agfs = agfs_client + self._lock_expire = lock_expire + + def _get_lock_path(self, path: str) -> str: path = path.rstrip("/") return f"{path}/{LOCK_FILE_NAME}" def _get_parent_path(self, path: str) -> Optional[str]: - """Get parent directory path. - - Args: - path: Directory path - - Returns: - Parent directory path or None if at root - """ path = path.rstrip("/") if "/" not in path: return None parent = path.rsplit("/", 1)[0] return parent if parent else None - async def _is_locked_by_other(self, lock_path: str, transaction_id: str) -> bool: - """Check if path is locked by another transaction. - - Args: - lock_path: Lock file path - transaction_id: Current transaction ID - - Returns: - True if locked by another transaction, False otherwise - """ + def _read_token(self, lock_path: str) -> Optional[str]: try: - content = self._agfs.cat(lock_path) + content = self._agfs.read(lock_path) if isinstance(content, bytes): - lock_owner = content.decode("utf-8").strip() + token = content.decode("utf-8").strip() else: - lock_owner = str(content).strip() - return lock_owner != transaction_id + token = str(content).strip() + return token if token else None except Exception: - # Lock file doesn't exist or can't be read - not locked - return False - - async def _create_lock_file(self, lock_path: str, transaction_id: str) -> None: - """Create lock file with transaction ID. - - Args: - lock_path: Lock file path - transaction_id: Transaction ID to write to lock file - """ - self._agfs.write(lock_path, transaction_id.encode("utf-8")) - - async def _verify_lock_ownership(self, lock_path: str, transaction_id: str) -> bool: - """Verify lock file is owned by current transaction. - - Args: - lock_path: Lock file path - transaction_id: Current transaction ID + return None - Returns: - True if lock is owned by current transaction, False otherwise - """ - try: - content = self._agfs.cat(lock_path) - if isinstance(content, bytes): - lock_owner = content.decode("utf-8").strip() - else: - lock_owner = str(content).strip() - return lock_owner == transaction_id - except Exception: + async def _is_locked_by_other(self, lock_path: str, owner_id: str) -> bool: + token = self._read_token(lock_path) + if token is None: return False + lock_owner, _, _ = _parse_fencing_token(token) + return lock_owner != owner_id + + async def _create_lock_file( + self, lock_path: str, owner_id: str, lock_type: str = LOCK_TYPE_POINT + ) -> None: + token = _make_fencing_token(owner_id, lock_type) + self._agfs.write(lock_path, token.encode("utf-8")) + + async def _verify_lock_ownership(self, lock_path: str, owner_id: str) -> bool: + token = self._read_token(lock_path) + if token is None: + return False + lock_owner, _, _ = _parse_fencing_token(token) + return lock_owner == owner_id - async def _remove_lock_file(self, lock_path: str) -> None: - """Remove lock file. - - Args: - lock_path: Lock file path - """ + async def _remove_lock_file(self, lock_path: str) -> bool: try: self._agfs.rm(lock_path) - except Exception: - # Lock file might not exist, ignore - pass - - async def acquire_normal(self, path: str, transaction: TransactionRecord) -> bool: - """Acquire path lock for normal operations. - - Lock acquisition flow for normal operations: - 1. Check if target directory exists - 2. Check if target directory is locked by another transaction - 3. Check if parent directory is locked by another transaction - 4. Create .path.ovlock file with transaction ID - 5. Check again if parent directory is locked by another transaction - 6. Read lock file to confirm it contains current transaction ID - 7. Return success if all checks pass + return True + except Exception as e: + if "not found" in str(e).lower(): + return True + return False - Args: - path: Directory path to lock - transaction: Transaction record + def is_lock_stale(self, lock_path: str, expire_seconds: float = 300.0) -> bool: + token = self._read_token(lock_path) + if token is None: + return True + _, ts, _ = _parse_fencing_token(token) + if ts == 0: + return True + age = (time.time_ns() - ts) / 1e9 + return age > expire_seconds + + async def _check_ancestors_for_subtree(self, path: str, exclude_owner_id: str) -> Optional[str]: + parent = self._get_parent_path(path) + while parent: + lock_path = self._get_lock_path(parent) + token = self._read_token(lock_path) + if token is not None: + owner_id, _, lock_type = _parse_fencing_token(token) + if owner_id != exclude_owner_id and lock_type == LOCK_TYPE_SUBTREE: + return lock_path + parent = self._get_parent_path(parent) + return None + + async def _scan_descendants_for_locks(self, path: str, exclude_owner_id: str) -> Optional[str]: + try: + entries = self._agfs.ls(path) + if not isinstance(entries, list): + return None + for entry in entries: + if not isinstance(entry, dict): + continue + name = entry.get("name", "") + if not name or name in (".", ".."): + continue + if not entry.get("isDir", False): + continue + subdir = f"{path.rstrip('/')}/{name}" + subdir_lock = self._get_lock_path(subdir) + token = self._read_token(subdir_lock) + if token is not None: + owner_id, _, _ = _parse_fencing_token(token) + if owner_id != exclude_owner_id: + return subdir_lock + result = await self._scan_descendants_for_locks(subdir, exclude_owner_id) + if result: + return result + except Exception as e: + logger.warning(f"Failed to scan descendants of {path}: {e}") + return None - Returns: - True if lock acquired successfully, False otherwise - """ - transaction_id = transaction.id + async def acquire_point(self, path: str, owner: LockOwner, timeout: float = 0.0) -> bool: + owner_id = owner.id lock_path = self._get_lock_path(path) - parent_path = self._get_parent_path(path) + deadline = asyncio.get_running_loop().time() + timeout - # Step 1: Check if target directory exists try: self._agfs.stat(path) except Exception: - logger.warning(f"Directory does not exist: {path}") + logger.warning(f"[POINT] Directory does not exist: {path}") return False - # Step 2: Check if target directory is locked by another transaction - if await self._is_locked_by_other(lock_path, transaction_id): - logger.warning(f"Path already locked by another transaction: {path}") - return False - - # Step 3: Check if parent directory is locked by another transaction - if parent_path: - parent_lock_path = self._get_lock_path(parent_path) - if await self._is_locked_by_other(parent_lock_path, transaction_id): - logger.warning(f"Parent path locked by another transaction: {parent_path}") + while True: + if await self._is_locked_by_other(lock_path, owner_id): + if self.is_lock_stale(lock_path, self._lock_expire): + logger.warning(f"[POINT] Removing stale lock: {lock_path}") + await self._remove_lock_file(lock_path) + continue + if asyncio.get_running_loop().time() >= deadline: + logger.warning(f"[POINT] Timeout waiting for lock on: {path}") + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + ancestor_conflict = await self._check_ancestors_for_subtree(path, owner_id) + if ancestor_conflict: + if self.is_lock_stale(ancestor_conflict, self._lock_expire): + logger.warning( + f"[POINT] Removing stale ancestor SUBTREE lock: {ancestor_conflict}" + ) + await self._remove_lock_file(ancestor_conflict) + continue + if asyncio.get_running_loop().time() >= deadline: + logger.warning( + f"[POINT] Timeout waiting for ancestor SUBTREE lock: {ancestor_conflict}" + ) + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + try: + await self._create_lock_file(lock_path, owner_id, LOCK_TYPE_POINT) + except Exception as e: + logger.error(f"[POINT] Failed to create lock file: {e}") return False - # Step 4: Create lock file - try: - await self._create_lock_file(lock_path, transaction_id) - except Exception as e: - logger.error(f"Failed to create lock file: {e}") - return False - - # Step 5: Check again if parent directory is locked - if parent_path: - parent_lock_path = self._get_lock_path(parent_path) - if await self._is_locked_by_other(parent_lock_path, transaction_id): - logger.warning(f"Parent path locked after lock creation: {parent_path}") - await self._remove_lock_file(lock_path) - return False - - # Step 6: Verify lock ownership - if not await self._verify_lock_ownership(lock_path, transaction_id): - logger.error(f"Lock ownership verification failed: {path}") - return False - - # Step 7: Success - add lock to transaction - transaction.add_lock(lock_path) - logger.debug(f"Lock acquired: {lock_path}") - return True - - async def _collect_subdirectories(self, path: str) -> List[str]: - """Collect all subdirectory paths recursively. - - Args: - path: Root directory path - - Returns: - List of all subdirectory paths - """ - subdirs = [] - try: - entries = self._agfs.ls(path) - if isinstance(entries, list): - for entry in entries: - if isinstance(entry, dict) and entry.get("isDir"): - entry_path = entry.get("name", "") - if entry_path: - subdirs.append(entry_path) - # Recursively collect subdirectories - subdirs.extend(await self._collect_subdirectories(entry_path)) - except Exception as e: - logger.warning(f"Failed to list directory {path}: {e}") - - return subdirs - - async def acquire_rm( - self, path: str, transaction: TransactionRecord, max_parallel: int = 8 - ) -> bool: - """Acquire path lock for rm operation using bottom-up parallel locking. - - Lock acquisition flow for rm operations (parallel bottom-up mode): - 1. Collect all subdirectory paths recursively - 2. Sort by depth (deepest first) - 3. Create lock files in batches with limited parallelism - 4. Lock the target directory last - 5. If any lock fails, release all acquired locks in reverse order - - Args: - path: Directory path to lock - transaction: Transaction record - max_parallel: Maximum number of parallel lock operations + backed_off = False + conflict_after = await self._check_ancestors_for_subtree(path, owner_id) + if conflict_after: + their_token = self._read_token(conflict_after) + if their_token: + their_owner_id, their_ts, _ = _parse_fencing_token(their_token) + my_token = self._read_token(lock_path) + _, my_ts, _ = ( + _parse_fencing_token(my_token) if my_token else ("", 0, LOCK_TYPE_POINT) + ) + if (my_ts, owner_id) > (their_ts, their_owner_id): + logger.debug(f"[POINT] Backing off (livelock guard) on {path}") + await self._remove_lock_file(lock_path) + backed_off = True + if asyncio.get_running_loop().time() >= deadline: + if not backed_off: + await self._remove_lock_file(lock_path) + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + if not await self._verify_lock_ownership(lock_path, owner_id): + logger.debug(f"[POINT] Lock ownership verification failed: {path}") + if asyncio.get_running_loop().time() >= deadline: + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + owner.add_lock(lock_path) + logger.debug(f"[POINT] Lock acquired: {lock_path}") + return True - Returns: - True if all locks acquired successfully, False otherwise - """ - transaction_id = transaction.id + async def acquire_subtree(self, path: str, owner: LockOwner, timeout: float = 0.0) -> bool: + owner_id = owner.id lock_path = self._get_lock_path(path) - acquired_locks = [] + deadline = asyncio.get_running_loop().time() + timeout - # Step 1: Collect all subdirectories - subdirs = await self._collect_subdirectories(path) + try: + self._agfs.stat(path) + except Exception: + logger.warning(f"[SUBTREE] Directory does not exist: {path}") + return False - # Step 2: Sort by depth (deepest first) - subdirs.sort(key=lambda p: p.count("/"), reverse=True) + while True: + if await self._is_locked_by_other(lock_path, owner_id): + if self.is_lock_stale(lock_path, self._lock_expire): + logger.warning(f"[SUBTREE] Removing stale lock: {lock_path}") + await self._remove_lock_file(lock_path) + continue + if asyncio.get_running_loop().time() >= deadline: + logger.warning(f"[SUBTREE] Timeout waiting for lock on: {path}") + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + # Check ancestor paths for SUBTREE locks held by other owners + ancestor_conflict = await self._check_ancestors_for_subtree(path, owner_id) + if ancestor_conflict: + if self.is_lock_stale(ancestor_conflict, self._lock_expire): + logger.warning( + f"[SUBTREE] Removing stale ancestor SUBTREE lock: {ancestor_conflict}" + ) + await self._remove_lock_file(ancestor_conflict) + continue + if asyncio.get_running_loop().time() >= deadline: + logger.warning( + f"[SUBTREE] Timeout waiting for ancestor SUBTREE lock: {ancestor_conflict}" + ) + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + desc_conflict = await self._scan_descendants_for_locks(path, owner_id) + if desc_conflict: + if self.is_lock_stale(desc_conflict, self._lock_expire): + logger.warning(f"[SUBTREE] Removing stale descendant lock: {desc_conflict}") + await self._remove_lock_file(desc_conflict) + continue + if asyncio.get_running_loop().time() >= deadline: + logger.warning( + f"[SUBTREE] Timeout waiting for descendant lock: {desc_conflict}" + ) + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + try: + await self._create_lock_file(lock_path, owner_id, LOCK_TYPE_SUBTREE) + except Exception as e: + logger.error(f"[SUBTREE] Failed to create lock file: {e}") + return False - # Step 3: Create lock files in batches - try: - # Lock subdirectories in batches - for i in range(0, len(subdirs), max_parallel): - batch = subdirs[i : i + max_parallel] - tasks = [] - for subdir in batch: - subdir_lock_path = self._get_lock_path(subdir) - tasks.append(self._create_lock_file(subdir_lock_path, transaction_id)) - - # Execute batch in parallel - await asyncio.gather(*tasks) - acquired_locks.extend([self._get_lock_path(s) for s in batch]) - - # Step 4: Lock target directory - await self._create_lock_file(lock_path, transaction_id) - acquired_locks.append(lock_path) - - # Add all locks to transaction - for lock in acquired_locks: - transaction.add_lock(lock) - - logger.debug(f"RM locks acquired for {len(acquired_locks)} paths") + backed_off = False + conflict_after = await self._scan_descendants_for_locks(path, owner_id) + if not conflict_after: + conflict_after = await self._check_ancestors_for_subtree(path, owner_id) + if conflict_after: + their_token = self._read_token(conflict_after) + if their_token: + their_owner_id, their_ts, _ = _parse_fencing_token(their_token) + my_token = self._read_token(lock_path) + _, my_ts, _ = ( + _parse_fencing_token(my_token) if my_token else ("", 0, LOCK_TYPE_SUBTREE) + ) + if (my_ts, owner_id) > (their_ts, their_owner_id): + logger.debug(f"[SUBTREE] Backing off (livelock guard) on {path}") + await self._remove_lock_file(lock_path) + backed_off = True + if asyncio.get_running_loop().time() >= deadline: + if not backed_off: + await self._remove_lock_file(lock_path) + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + if not await self._verify_lock_ownership(lock_path, owner_id): + logger.debug(f"[SUBTREE] Lock ownership verification failed: {path}") + if asyncio.get_running_loop().time() >= deadline: + return False + await asyncio.sleep(_POLL_INTERVAL) + continue + + owner.add_lock(lock_path) + logger.debug(f"[SUBTREE] Lock acquired: {lock_path}") return True - except Exception as e: - logger.error(f"Failed to acquire RM locks: {e}") - # Step 5: Release all acquired locks in reverse order - for lock in reversed(acquired_locks): - await self._remove_lock_file(lock) - return False - async def acquire_mv( self, src_path: str, - dst_path: str, - transaction: TransactionRecord, - max_parallel: int = 8, + dst_parent_path: str, + owner: LockOwner, + timeout: float = 0.0, + src_is_dir: bool = True, ) -> bool: - """Acquire path lock for mv operation. - - Lock acquisition flow for mv operations: - 1. Lock source directory (using RM-style locking) - 2. Lock destination directory (using normal locking) + """Acquire locks for a move operation. Args: - src_path: Source directory path - dst_path: Destination directory path - transaction: Transaction record - max_parallel: Maximum number of parallel lock operations - - Returns: - True if all locks acquired successfully, False otherwise + src_path: Source path to lock. + dst_parent_path: Parent directory of the destination to lock. + Callers typically pass the destination's parent so that the + lock covers sibling-level conflicts without requiring the + target to exist yet. + owner: Lock owner handle. + timeout: Maximum seconds to wait for each lock. + src_is_dir: Whether the source is a directory (SUBTREE lock) + or a file (POINT lock on parent). """ - # Step 1: Lock source directory - if not await self.acquire_rm(src_path, transaction, max_parallel): - logger.warning(f"Failed to lock source path: {src_path}") - return False - - # Step 2: Lock destination directory - if not await self.acquire_normal(dst_path, transaction): - logger.warning(f"Failed to lock destination path: {dst_path}") - # Release source locks - await self.release(transaction) - return False + if src_is_dir: + if not await self.acquire_subtree(src_path, owner, timeout=timeout): + logger.warning(f"[MV] Failed to acquire SUBTREE lock on source: {src_path}") + return False + if not await self.acquire_subtree(dst_parent_path, owner, timeout=timeout): + logger.warning( + f"[MV] Failed to acquire SUBTREE lock on destination parent: {dst_parent_path}" + ) + await self.release(owner) + return False + else: + src_parent = src_path.rsplit("/", 1)[0] if "/" in src_path else src_path + if not await self.acquire_point(src_parent, owner, timeout=timeout): + logger.warning(f"[MV] Failed to acquire POINT lock on source parent: {src_parent}") + return False + if not await self.acquire_point(dst_parent_path, owner, timeout=timeout): + logger.warning( + f"[MV] Failed to acquire POINT lock on destination parent: {dst_parent_path}" + ) + await self.release(owner) + return False - logger.debug(f"MV locks acquired: {src_path} -> {dst_path}") + logger.debug(f"[MV] Locks acquired: {src_path} -> {dst_parent_path}") return True - async def release(self, transaction: TransactionRecord) -> None: - """Release all locks held by the transaction. - - Args: - transaction: Transaction record - """ - # Release locks in reverse order (LIFO) - for lock_path in reversed(transaction.locks): + async def refresh(self, owner: LockOwner) -> None: + """Rewrite all lock file timestamps to prevent stale cleanup.""" + for lock_path in list(owner.locks): + token = self._read_token(lock_path) + if token: + parsed_owner_id, _, lock_type = _parse_fencing_token(token) + if parsed_owner_id == owner.id: + new_token = _make_fencing_token(owner.id, lock_type) + try: + self._agfs.write(lock_path, new_token.encode("utf-8")) + except Exception as e: + logger.warning(f"Failed to refresh lock {lock_path}: {e}") + + async def release(self, owner: LockOwner) -> None: + lock_count = len(owner.locks) + for lock_path in reversed(owner.locks): await self._remove_lock_file(lock_path) - transaction.remove_lock(lock_path) + owner.remove_lock(lock_path) - logger.debug(f"Released {len(transaction.locks)} locks for transaction {transaction.id}") + logger.debug(f"Released {lock_count} locks for owner {owner.id}") diff --git a/openviking/storage/transaction/redo_log.py b/openviking/storage/transaction/redo_log.py new file mode 100644 index 00000000..80d07dff --- /dev/null +++ b/openviking/storage/transaction/redo_log.py @@ -0,0 +1,76 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Lightweight redo log for crash recovery of session_memory operations.""" + +import json +from typing import Any, Dict, List + +from openviking.pyagfs import AGFSClient +from openviking_cli.utils.logger import get_logger + +logger = get_logger(__name__) + +_REDO_ROOT = "/local/_system/redo" + + +class RedoLog: + """Lightweight pending-task marker. + + Write a marker before the operation starts; delete it after success. + On startup, scan for leftover markers and redo. + """ + + def __init__(self, agfs: AGFSClient): + self._agfs = agfs + + def _task_path(self, task_id: str) -> str: + return f"{_REDO_ROOT}/{task_id}/redo.json" + + def _ensure_dirs(self, dir_path: str) -> None: + parts = dir_path.strip("/").split("/") + current = "" + for part in parts: + current = f"{current}/{part}" + try: + self._agfs.mkdir(current) + except Exception: + pass + + def write_pending(self, task_id: str, info: Dict[str, Any]) -> None: + """Write a redo marker before the operation starts.""" + dir_path = f"{_REDO_ROOT}/{task_id}" + self._ensure_dirs(dir_path) + data = json.dumps(info, default=str).encode("utf-8") + self._agfs.write(self._task_path(task_id), data) + + def mark_done(self, task_id: str) -> None: + """Delete the redo marker after a successful operation.""" + try: + self._agfs.rm(f"{_REDO_ROOT}/{task_id}", recursive=True) + except Exception as e: + logger.warning(f"Failed to clean redo marker {task_id}: {e}") + + def list_pending(self) -> List[str]: + """Return all pending task IDs (directories under _REDO_ROOT).""" + try: + entries = self._agfs.ls(_REDO_ROOT) + if not isinstance(entries, list): + return [] + return [ + e["name"] + for e in entries + if isinstance(e, dict) and e.get("isDir") and e.get("name") not in (".", "..") + ] + except Exception: + return [] + + def read(self, task_id: str) -> Dict[str, Any]: + """Read the info dict of a pending task.""" + try: + content = self._agfs.cat(self._task_path(task_id)) + if isinstance(content, bytes): + content = content.decode("utf-8") + return json.loads(content) + except Exception as e: + logger.warning(f"Failed to read redo info for {task_id}: {e}") + return {} diff --git a/openviking/storage/transaction/transaction_manager.py b/openviking/storage/transaction/transaction_manager.py deleted file mode 100644 index da76cde7..00000000 --- a/openviking/storage/transaction/transaction_manager.py +++ /dev/null @@ -1,374 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: Apache-2.0 -""" -Transaction manager for OpenViking. - -Global singleton that manages transaction lifecycle and lock mechanisms. -""" - -import asyncio -import threading -import time -from typing import Any, Dict, Optional - -from openviking.pyagfs import AGFSClient -from openviking.storage.transaction.path_lock import PathLock -from openviking.storage.transaction.transaction_record import ( - TransactionRecord, - TransactionStatus, -) -from openviking_cli.utils.logger import get_logger - -logger = get_logger(__name__) - -# Global singleton instance -_transaction_manager: Optional["TransactionManager"] = None -_lock = threading.Lock() - - -class TransactionManager: - """Transaction manager for OpenViking. - - Global singleton that manages transaction lifecycle and lock mechanisms. - Responsible for: - - Allocating transaction IDs - - Managing transaction lifecycle (start, commit, rollback) - - Providing transaction lock mechanism interface, preventing deadlocks - """ - - def __init__( - self, - agfs_client: AGFSClient, - timeout: int = 3600, - max_parallel_locks: int = 8, - ): - """Initialize transaction manager. - - Args: - agfs_client: AGFS client for file system operations - timeout: Transaction timeout in seconds (default: 3600) - max_parallel_locks: Maximum number of parallel lock operations (default: 8) - """ - self._agfs = agfs_client - self._timeout = timeout - self._max_parallel_locks = max_parallel_locks - self._path_lock = PathLock(agfs_client) - - # Active transactions: {transaction_id: TransactionRecord} - self._transactions: Dict[str, TransactionRecord] = {} - - # Background task for timeout cleanup - self._cleanup_task: Optional[asyncio.Task] = None - self._running = False - - logger.info( - f"TransactionManager initialized (timeout={timeout}s, max_parallel_locks={max_parallel_locks})" - ) - - async def start(self) -> None: - """Start transaction manager. - - Starts the background cleanup task for timed-out transactions. - """ - if self._running: - logger.debug("TransactionManager already running") - return - - self._running = True - self._cleanup_task = asyncio.create_task(self._cleanup_loop()) - logger.info("TransactionManager started") - - def stop(self) -> None: - """Stop transaction manager. - - Stops the background cleanup task and releases all resources. - """ - if not self._running: - logger.debug("TransactionManager already stopped") - return - - self._running = False - - # Cancel cleanup task - if self._cleanup_task: - self._cleanup_task.cancel() - self._cleanup_task = None - - # Release all active transactions - for tx_id in list(self._transactions.keys()): - self._transactions.pop(tx_id, None) - - logger.info("TransactionManager stopped") - - async def _cleanup_loop(self) -> None: - """Background loop for cleaning up timed-out transactions.""" - while self._running: - try: - await asyncio.sleep(60) # Check every minute - await self._cleanup_timed_out() - except asyncio.CancelledError: - break - except Exception as e: - logger.error(f"Error in cleanup loop: {e}") - - async def _cleanup_timed_out(self) -> None: - """Clean up timed-out transactions.""" - current_time = time.time() - timed_out = [] - - for tx_id, tx in self._transactions.items(): - if current_time - tx.updated_at > self._timeout: - timed_out.append(tx_id) - - for tx_id in timed_out: - logger.warning(f"Transaction timed out: {tx_id}") - await self.rollback(tx_id) - - def create_transaction(self, init_info: Optional[Dict[str, Any]] = None) -> TransactionRecord: - """Create a new transaction. - - Args: - init_info: Transaction initialization information - - Returns: - New transaction record - """ - tx = TransactionRecord(init_info=init_info or {}) - self._transactions[tx.id] = tx - logger.debug(f"Transaction created: {tx.id}") - return tx - - def get_transaction(self, transaction_id: str) -> Optional[TransactionRecord]: - """Get transaction by ID. - - Args: - transaction_id: Transaction ID - - Returns: - Transaction record or None if not found - """ - return self._transactions.get(transaction_id) - - async def begin(self, transaction_id: str) -> bool: - """Begin a transaction. - - Args: - transaction_id: Transaction ID - - Returns: - True if transaction started successfully, False otherwise - """ - tx = self.get_transaction(transaction_id) - if not tx: - logger.error(f"Transaction not found: {transaction_id}") - return False - - tx.update_status(TransactionStatus.AQUIRE) - logger.debug(f"Transaction begun: {transaction_id}") - return True - - async def commit(self, transaction_id: str) -> bool: - """Commit a transaction. - - Args: - transaction_id: Transaction ID - - Returns: - True if transaction committed successfully, False otherwise - """ - tx = self.get_transaction(transaction_id) - if not tx: - logger.error(f"Transaction not found: {transaction_id}") - return False - - # Update status to COMMIT - tx.update_status(TransactionStatus.COMMIT) - - # Release all locks - tx.update_status(TransactionStatus.RELEASING) - await self._path_lock.release(tx) - - # Update status to RELEASED - tx.update_status(TransactionStatus.RELEASED) - - # Remove from active transactions - self._transactions.pop(transaction_id, None) - - logger.debug(f"Transaction committed: {transaction_id}") - return True - - async def rollback(self, transaction_id: str) -> bool: - """Rollback a transaction. - - Args: - transaction_id: Transaction ID - - Returns: - True if transaction rolled back successfully, False otherwise - """ - tx = self.get_transaction(transaction_id) - if not tx: - logger.error(f"Transaction not found: {transaction_id}") - return False - - # Update status to FAIL - tx.update_status(TransactionStatus.FAIL) - - # Release all locks - tx.update_status(TransactionStatus.RELEASING) - await self._path_lock.release(tx) - - # Update status to RELEASED - tx.update_status(TransactionStatus.RELEASED) - - # Remove from active transactions - self._transactions.pop(transaction_id, None) - - logger.debug(f"Transaction rolled back: {transaction_id}") - return True - - async def acquire_lock_normal(self, transaction_id: str, path: str) -> bool: - """Acquire path lock for normal (non-rm/mv) operations. - - Args: - transaction_id: Transaction ID - path: Directory path to lock - - Returns: - True if lock acquired successfully, False otherwise - """ - tx = self.get_transaction(transaction_id) - if not tx: - logger.error(f"Transaction not found: {transaction_id}") - return False - - tx.update_status(TransactionStatus.AQUIRE) - success = await self._path_lock.acquire_normal(path, tx) - - if success: - tx.update_status(TransactionStatus.EXEC) - else: - tx.update_status(TransactionStatus.FAIL) - - return success - - async def acquire_lock_rm( - self, transaction_id: str, path: str, max_parallel: Optional[int] = None - ) -> bool: - """Acquire path lock for rm operation. - - Args: - transaction_id: Transaction ID - path: Directory path to lock - max_parallel: Maximum number of parallel lock operations (default: from config) - - Returns: - True if lock acquired successfully, False otherwise - """ - tx = self.get_transaction(transaction_id) - if not tx: - logger.error(f"Transaction not found: {transaction_id}") - return False - - tx.update_status(TransactionStatus.AQUIRE) - parallel = max_parallel or self._max_parallel_locks - success = await self._path_lock.acquire_rm(path, tx, parallel) - - if success: - tx.update_status(TransactionStatus.EXEC) - else: - tx.update_status(TransactionStatus.FAIL) - - return success - - async def acquire_lock_mv( - self, - transaction_id: str, - src_path: str, - dst_path: str, - max_parallel: Optional[int] = None, - ) -> bool: - """Acquire path lock for mv operation. - - Args: - transaction_id: Transaction ID - src_path: Source directory path - dst_path: Destination directory path - max_parallel: Maximum number of parallel lock operations (default: from config) - - Returns: - True if lock acquired successfully, False otherwise - """ - tx = self.get_transaction(transaction_id) - if not tx: - logger.error(f"Transaction not found: {transaction_id}") - return False - - tx.update_status(TransactionStatus.AQUIRE) - parallel = max_parallel or self._max_parallel_locks - success = await self._path_lock.acquire_mv(src_path, dst_path, tx, parallel) - - if success: - tx.update_status(TransactionStatus.EXEC) - else: - tx.update_status(TransactionStatus.FAIL) - - return success - - def get_active_transactions(self) -> Dict[str, TransactionRecord]: - """Get all active transactions. - - Returns: - Dictionary of active transactions {transaction_id: TransactionRecord} - """ - return self._transactions.copy() - - def get_transaction_count(self) -> int: - """Get the number of active transactions. - - Returns: - Number of active transactions - """ - return len(self._transactions) - - -def init_transaction_manager( - agfs: AGFSClient, - tx_timeout: int = 3600, - max_parallel_locks: int = 8, -) -> TransactionManager: - """Initialize transaction manager singleton. - - Args: - agfs: AGFS client instance - tx_timeout: Transaction timeout in seconds (default: 3600) - max_parallel_locks: Maximum number of parallel lock operations (default: 8) - - Returns: - TransactionManager instance - """ - global _transaction_manager - - with _lock: - if _transaction_manager is not None: - logger.debug("TransactionManager already initialized") - return _transaction_manager - - # Create transaction manager - _transaction_manager = TransactionManager( - agfs_client=agfs, - timeout=tx_timeout, - max_parallel_locks=max_parallel_locks, - ) - - logger.info("TransactionManager initialized as singleton") - return _transaction_manager - - -def get_transaction_manager() -> Optional[TransactionManager]: - """Get transaction manager singleton. - - Returns: - TransactionManager instance or None if not initialized - """ - return _transaction_manager diff --git a/openviking/storage/transaction/transaction_record.py b/openviking/storage/transaction/transaction_record.py deleted file mode 100644 index fba6480b..00000000 --- a/openviking/storage/transaction/transaction_record.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: Apache-2.0 -""" -Transaction record and status definitions. - -Defines the data structures for tracking transaction lifecycle and state. -""" - -import time -import uuid -from dataclasses import dataclass, field -from enum import Enum -from typing import Any, Dict, List - - -class TransactionStatus(str, Enum): - """Transaction status enumeration. - - Status machine: INIT -> AQUIRE -> EXEC -> COMMIT/FAIL -> RELEASING -> RELEASED - """ - - INIT = "INIT" # Transaction initialized, waiting for lock acquisition - AQUIRE = "AQUIRE" # Acquiring lock resources - EXEC = "EXEC" # Transaction operation in progress - COMMIT = "COMMIT" # Transaction completed successfully - FAIL = "FAIL" # Transaction failed - RELEASING = "RELEASING" # Releasing lock resources - RELEASED = "RELEASED" # Lock resources fully released, transaction ended - - def __str__(self) -> str: - return self.value - - -@dataclass -class TransactionRecord: - """Transaction record for tracking transaction lifecycle. - - Attributes: - id: Transaction ID in UUID format, uniquely identifies a transaction - locks: List of lock paths held by this transaction - status: Current transaction status - init_info: Transaction initialization information - rollback_info: Information for rollback operations - created_at: Creation timestamp (Unix timestamp in seconds) - updated_at: Last update timestamp (Unix timestamp in seconds) - """ - - id: str = field(default_factory=lambda: str(uuid.uuid4())) - locks: List[str] = field(default_factory=list) - status: TransactionStatus = field(default=TransactionStatus.INIT) - init_info: Dict[str, Any] = field(default_factory=dict) - rollback_info: Dict[str, Any] = field(default_factory=dict) - created_at: float = field(default_factory=time.time) - updated_at: float = field(default_factory=time.time) - - def update_status(self, status: TransactionStatus) -> None: - """Update transaction status and timestamp. - - Args: - status: New transaction statusudi - """ - self.status = status - self.updated_at = time.time() - - def add_lock(self, lock_path: str) -> None: - """Add a lock to the transaction. - - Args: - lock_path: Path to be locked - """ - if lock_path not in self.locks: - self.locks.append(lock_path) - self.updated_at = time.time() - - def remove_lock(self, lock_path: str) -> None: - """Remove a lock from the transaction. - - Args: - lock_path: Path to be unlocked - """ - if lock_path in self.locks: - self.locks.remove(lock_path) - self.updated_at = time.time() - - def to_dict(self) -> Dict[str, Any]: - """Convert transaction record to dictionary. - - Returns: - Dictionary representation of the transaction record - """ - return { - "id": self.id, - "locks": self.locks, - "status": str(self.status), - "init_info": self.init_info, - "rollback_info": self.rollback_info, - "created_at": self.created_at, - "updated_at": self.updated_at, - } - - @classmethod - def from_dict(cls, data: Dict[str, Any]) -> "TransactionRecord": - """Create transaction record from dictionary. - - Args: - data: Dictionary representation of the transaction record - - Returns: - TransactionRecord instance - """ - status_str = data.get("status", "INIT") - status = TransactionStatus(status_str) if isinstance(status_str, str) else status_str - - return cls( - id=data.get("id", str(uuid.uuid4())), - locks=data.get("locks", []), - status=status, - init_info=data.get("init_info", {}), - rollback_info=data.get("rollback_info", {}), - created_at=data.get("created_at", time.time()), - updated_at=data.get("updated_at", time.time()), - ) diff --git a/openviking/storage/vectordb/engine/__init__.py b/openviking/storage/vectordb/engine/__init__.py new file mode 100644 index 00000000..b1075f35 --- /dev/null +++ b/openviking/storage/vectordb/engine/__init__.py @@ -0,0 +1,176 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Stable runtime loader for vectordb native engine variants.""" + +from __future__ import annotations + +import importlib +import importlib.util +import os +import platform +from types import ModuleType + +_BACKEND_MODULES = { + "x86_sse3": "_x86_sse3", + "x86_avx2": "_x86_avx2", + "x86_avx512": "_x86_avx512", + "native": "_native", +} +_X86_DISPLAY_ORDER = ("x86_sse3", "x86_avx2", "x86_avx512") +_X86_PRIORITY = ("x86_avx512", "x86_avx2", "x86_sse3") +_REQUEST_ALIASES = { + "sse3": "x86_sse3", + "avx2": "x86_avx2", + "avx512": "x86_avx512", +} + + +def _is_x86_machine(machine: str | None = None) -> bool: + normalized = (machine or platform.machine() or "").strip().lower() + return any(token in normalized for token in ("x86_64", "amd64", "x64", "i386", "i686")) + + +def _module_exists(module_name: str) -> bool: + return importlib.util.find_spec(f".{module_name}", __name__) is not None + + +def _available_variants(is_x86: bool) -> tuple[str, ...]: + ordered = _X86_DISPLAY_ORDER if is_x86 else ("native",) + return tuple(variant for variant in ordered if _module_exists(_BACKEND_MODULES[variant])) + + +def _supported_x86_variants() -> set[str]: + supported = {"x86_sse3"} + if not _module_exists("_x86_caps"): + return supported + + try: + caps = importlib.import_module("._x86_caps", __name__) + except ImportError: + return supported + + reported = getattr(caps, "get_supported_variants", lambda: [])() + for variant in reported: + normalized = str(variant).strip().lower() + if normalized in _BACKEND_MODULES: + supported.add(normalized) + return supported + + +def _normalize_requested_variant(value: str | None) -> str: + normalized = (value or "auto").strip().lower() + return _REQUEST_ALIASES.get(normalized, normalized) + + +def _validate_forced_variant( + requested: str, *, is_x86: bool, available: tuple[str, ...], supported_x86: set[str] +) -> None: + if is_x86 and requested == "native": + raise ImportError("OV_ENGINE_VARIANT=native is only valid on non-x86 platforms") + + if not is_x86 and requested != "native": + raise ImportError( + f"OV_ENGINE_VARIANT={requested} is not valid on non-x86 platforms; use native" + ) + + if requested not in _BACKEND_MODULES: + raise ImportError(f"Unknown OV_ENGINE_VARIANT={requested}") + + if requested not in available: + raise ImportError( + f"Requested engine variant {requested} is not packaged in this wheel. " + f"Available variants: {', '.join(available) or 'none'}" + ) + + if is_x86 and requested not in supported_x86: + raise ImportError(f"Requested engine variant {requested} is not supported by this CPU") + + +def _select_variant() -> tuple[str | None, tuple[str, ...], str | None]: + is_x86 = _is_x86_machine() + available = _available_variants(is_x86) + requested = _normalize_requested_variant(os.environ.get("OV_ENGINE_VARIANT")) + + if requested != "auto": + supported_x86 = _supported_x86_variants() if is_x86 else set() + _validate_forced_variant( + requested, is_x86=is_x86, available=available, supported_x86=supported_x86 + ) + return requested, available, None + + if not is_x86: + if "native" not in available: + return None, available, "Native engine backend is missing from this wheel" + return "native", available, None + + supported_x86 = _supported_x86_variants() + for variant in _X86_PRIORITY: + if variant in available and variant in supported_x86: + return variant, available, None + + if "x86_sse3" in available: + return "x86_sse3", available, None + + return None, available, "No compatible x86 engine backend was packaged in this wheel" + + +def _load_backend(variant: str) -> ModuleType: + return importlib.import_module(f".{_BACKEND_MODULES[variant]}", __name__) + + +def _export_backend(module: ModuleType) -> tuple[str, ...]: + names = getattr(module, "__all__", None) + if names is None: + names = tuple(name for name in dir(module) if not name.startswith("_")) + + for name in names: + globals()[name] = getattr(module, name) + + return tuple(names) + + +class _MissingBackendSymbol: + def __init__(self, symbol_name: str, message: str): + self._symbol_name = symbol_name + self._message = message + + def __call__(self, *args, **kwargs): + raise ImportError(f"{self._message}. Missing symbol: {self._symbol_name}") + + def __getattr__(self, name: str): + return _MissingBackendSymbol(f"{self._symbol_name}.{name}", self._message) + + def __bool__(self) -> bool: + return False + + def __repr__(self) -> str: + return f"" + + +_SELECTED_VARIANT, AVAILABLE_ENGINE_VARIANTS, _ENGINE_IMPORT_ERROR = _select_variant() +if _SELECTED_VARIANT is None: + ENGINE_VARIANT = "unavailable" + _BACKEND = None + _EXPORTED_NAMES = () +else: + ENGINE_VARIANT = _SELECTED_VARIANT + _BACKEND = _load_backend(ENGINE_VARIANT) + _EXPORTED_NAMES = _export_backend(_BACKEND) + + +def __getattr__(name: str): + if _BACKEND is None and _ENGINE_IMPORT_ERROR is not None: + return _MissingBackendSymbol(name, _ENGINE_IMPORT_ERROR) + raise AttributeError(name) + + +__all__ = tuple( + sorted( + set(_EXPORTED_NAMES).union( + { + "AVAILABLE_ENGINE_VARIANTS", + "ENGINE_VARIANT", + } + ) + ) +) diff --git a/openviking/storage/vectordb/service/server_fastapi.py b/openviking/storage/vectordb/service/server_fastapi.py index f737ef3a..34574e60 100644 --- a/openviking/storage/vectordb/service/server_fastapi.py +++ b/openviking/storage/vectordb/service/server_fastapi.py @@ -1,9 +1,17 @@ # Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. # SPDX-License-Identifier: Apache-2.0 + +"""FastAPI server for VikingDB vector database service. + +This module provides a REST API server for VikingDB operations including +collection management, data operations, indexing, and vector search. +""" + import asyncio import random import time from contextlib import asynccontextmanager +from typing import Dict, Any import uvicorn from fastapi import FastAPI, Request @@ -13,67 +21,94 @@ from openviking.storage.vectordb.service.api_fastapi import VikingDBException, error_response from openviking_cli.utils.logger import default_logger as logger -# Active requests counter -active_requests = 0 +# Global counter for tracking active requests +_active_requests = 0 @asynccontextmanager async def lifespan(app: FastAPI): - """Handle startup and shutdown events""" + """Handle application startup and shutdown events. + + Manages resource initialization and cleanup, ensuring graceful shutdown + by waiting for all active requests to complete. + + Args: + app: The FastAPI application instance + """ # Startup - logger.info("============ start =============") + logger.info("============ VikingDB Server Starting =============") random.seed(time.time_ns()) + yield + # Shutdown logger.info("Waiting for active requests to complete...") - while active_requests > 0: + while _active_requests > 0: await asyncio.sleep(0.1) api_fastapi.clear_resource() - logger.info("============ exit =============") + logger.info("============ VikingDB Server Stopped =============") -# Create FastAPI app +# Create FastAPI application instance app = FastAPI( title="VikingDB API", - description="Vector database service API", + description="Vector database service API for managing collections, data, indexes, and search operations", version="1.0.0", lifespan=lifespan, ) -# Exception handler @app.exception_handler(VikingDBException) -async def vikingdb_exception_handler(request: Request, exc: VikingDBException): +async def vikingdb_exception_handler(request: Request, exc: VikingDBException) -> JSONResponse: + """Handle VikingDB-specific exceptions. + + Args: + request: The incoming HTTP request + exc: The VikingDBException that was raised + + Returns: + JSONResponse with error details + """ return JSONResponse( - status_code=200, content=error_response(exc.message, exc.code.value, request=request) + status_code=200, + content=error_response(exc.message, exc.code.value, request=request) ) -# Middleware to track request time and active requests @app.middleware("http") -async def add_process_time_header(request: Request, call_next): - global active_requests - active_requests += 1 +async def request_tracking_middleware(request: Request, call_next): + """Middleware to track request processing time and active request count. + + Increments active request counter, measures processing time, + and adds processing time header to response. + + Args: + request: The incoming HTTP request + call_next: The next middleware/handler in the chain + + Returns: + Response with added X-Process-Time header + """ + global _active_requests + _active_requests += 1 start_time = time.time() - # Store start time in request state + # Store start time in request state for potential future use request.state.start_time = start_time try: response = await call_next(request) - # Calculate time cost + # Calculate and add processing time header time_cost = time.time() - start_time - - # Add time cost header response.headers["X-Process-Time"] = str(round(time_cost, 6)) return response finally: - active_requests -= 1 + _active_requests -= 1 -# Register routers +# Register API routers for different operation types app.include_router(api_fastapi.collection_router) app.include_router(api_fastapi.data_router) app.include_router(api_fastapi.index_router) @@ -81,19 +116,28 @@ async def add_process_time_header(request: Request, call_next): @app.get("/") -async def root(): - """Root endpoint""" +async def root() -> Dict[str, str]: + """Root endpoint providing basic server information. + + Returns: + Dict containing server name and version + """ return {"message": "VikingDB API Server", "version": "1.0.0"} @app.get("/health") -async def health(): - """Health check endpoint""" - return {"status": "healthy", "active_requests": active_requests} +async def health() -> Dict[str, Any]: + """Health check endpoint for monitoring server status. + + Returns: + Dict containing health status and current active request count + """ + return {"status": "healthy", "active_requests": _active_requests} if __name__ == "__main__": try: + logger.info("Starting VikingDB server on 0.0.0.0:5000") uvicorn.run(app, host="0.0.0.0", port=5000, log_level="info") except Exception as e: - logger.error(f"Failed to start server: {e}") + logger.error(f"Failed to start VikingDB server: {e}") \ No newline at end of file diff --git a/openviking/storage/vectordb/store/bytes_row.py b/openviking/storage/vectordb/store/bytes_row.py index 5455621c..8eaa2679 100644 --- a/openviking/storage/vectordb/store/bytes_row.py +++ b/openviking/storage/vectordb/store/bytes_row.py @@ -274,6 +274,9 @@ def deserialize(self, serialized_data): try: import openviking.storage.vectordb.engine as engine + if getattr(engine, "ENGINE_VARIANT", "unavailable") == "unavailable": + raise ImportError("vectordb engine backend is unavailable") + # Use C++ implementation if available BytesRow = engine.BytesRow Schema = engine.Schema diff --git a/openviking/storage/vectordb_adapters/__init__.py b/openviking/storage/vectordb_adapters/__init__.py index 8446b64a..04de30e2 100644 --- a/openviking/storage/vectordb_adapters/__init__.py +++ b/openviking/storage/vectordb_adapters/__init__.py @@ -6,6 +6,7 @@ from .factory import create_collection_adapter from .http_adapter import HttpCollectionAdapter from .local_adapter import LocalCollectionAdapter +from .oceanbase_adapter import OceanBaseCollectionAdapter from .vikingdb_private_adapter import VikingDBPrivateCollectionAdapter from .volcengine_adapter import VolcengineCollectionAdapter @@ -15,5 +16,6 @@ "HttpCollectionAdapter", "VolcengineCollectionAdapter", "VikingDBPrivateCollectionAdapter", + "OceanBaseCollectionAdapter", "create_collection_adapter", ] diff --git a/openviking/storage/vectordb_adapters/factory.py b/openviking/storage/vectordb_adapters/factory.py index 6c11954c..fbff1363 100644 --- a/openviking/storage/vectordb_adapters/factory.py +++ b/openviking/storage/vectordb_adapters/factory.py @@ -7,6 +7,7 @@ from .base import CollectionAdapter from .http_adapter import HttpCollectionAdapter from .local_adapter import LocalCollectionAdapter +from .oceanbase_adapter import OceanBaseCollectionAdapter from .vikingdb_private_adapter import VikingDBPrivateCollectionAdapter from .volcengine_adapter import VolcengineCollectionAdapter @@ -15,6 +16,7 @@ "http": HttpCollectionAdapter, "volcengine": VolcengineCollectionAdapter, "vikingdb": VikingDBPrivateCollectionAdapter, + "oceanbase": OceanBaseCollectionAdapter, } diff --git a/openviking/storage/vectordb_adapters/oceanbase_adapter.py b/openviking/storage/vectordb_adapters/oceanbase_adapter.py new file mode 100644 index 00000000..160b358e --- /dev/null +++ b/openviking/storage/vectordb_adapters/oceanbase_adapter.py @@ -0,0 +1,556 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""OceanBase vector database adapter (via pyobvector).""" + +from __future__ import annotations + +from typing import Any, Dict, List, Optional + +from openviking.storage.vectordb_adapters.base import CollectionAdapter +from openviking.storage.vectordb.collection.collection import Collection, ICollection +from openviking.storage.vectordb.collection.result import ( + AggregateResult, + DataItem, + FetchDataInCollectionResult, + SearchItemResult, + SearchResult, +) +from openviking_cli.utils import get_logger + +logger = get_logger(__name__) + +# Optional import: pyobvector is required only when backend is "oceanbase" +try: + from pyobvector.client.milvus_like_client import MilvusLikeClient + from pyobvector.client.collection_schema import CollectionSchema, FieldSchema + from pyobvector.client.schema_type import DataType + from pyobvector.client.index_param import IndexParam, IndexParams, VecIndexType + + _PYOBVECTOR_AVAILABLE = True +except ImportError: + _PYOBVECTOR_AVAILABLE = False + MilvusLikeClient = None # type: ignore + CollectionSchema = None # type: ignore + FieldSchema = None # type: ignore + DataType = None # type: ignore + IndexParam = None # type: ignore + IndexParams = None # type: ignore + VecIndexType = None # type: ignore + + +def _openviking_field_to_field_schema(field: Dict[str, Any], vector_dim: int) -> FieldSchema: + """Convert OpenViking Fields entry to pyobvector FieldSchema.""" + name = field.get("FieldName", "") + typ = (field.get("FieldType") or "").lower() + is_primary = bool(field.get("IsPrimaryKey", False)) + + if typ == "string" or typ == "path": + return FieldSchema(name, DataType.VARCHAR, is_primary=is_primary, max_length=4096) + if typ == "int64": + return FieldSchema(name, DataType.INT64, is_primary=is_primary) + if typ == "vector": + dim = field.get("Dim") or vector_dim + return FieldSchema(name, DataType.FLOAT_VECTOR, is_primary=False, dim=dim) + if typ == "sparse_vector": + return FieldSchema(name, DataType.SPARSE_FLOAT_VECTOR, is_primary=False) + if typ == "date_time": + return FieldSchema(name, DataType.INT64, is_primary=False) + # default + return FieldSchema(name, DataType.VARCHAR, is_primary=is_primary, max_length=4096) + + +def _build_oceanbase_schema(meta: Dict[str, Any], vector_dim: int) -> CollectionSchema: + """Build pyobvector CollectionSchema from OpenViking collection meta.""" + if not _PYOBVECTOR_AVAILABLE or CollectionSchema is None or FieldSchema is None: + raise RuntimeError("pyobvector is required for OceanBase backend. Install with: pip install pyobvector") + + fields_meta = meta.get("Fields", []) + vector_dim = meta.get("Dimension") or vector_dim + fields = [] + for f in fields_meta: + if f.get("FieldName") == "AUTO_ID": + continue + fs = _openviking_field_to_field_schema(f, vector_dim) + fields.append(fs) + return CollectionSchema(fields=fields) + + +def _distance_to_metric(distance: str) -> str: + """Map OpenViking distance_metric to pyobvector metric_type.""" + d = (distance or "cosine").lower() + if d in ("l2", "ip", "cosine", "neg_ip"): + return "neg_ip" if d == "cosine" else d # OceanBase cosine often as neg_ip + return "l2" + + +class OceanBaseCollection(ICollection): + """ICollection implementation backed by OceanBase via pyobvector MilvusLikeClient.""" + + def __init__( + self, + client: Any, + collection_name: str, + meta_data: Dict[str, Any], + distance_metric: str = "cosine", + ): + if not _PYOBVECTOR_AVAILABLE: + raise RuntimeError("pyobvector is required for OceanBase backend. Install with: pip install pyobvector") + self._client = client + self._collection_name = collection_name + self._meta_data = dict(meta_data) + self._distance_metric = _distance_to_metric(distance_metric) + self._vector_dim = self._meta_data.get("Dimension", 0) + + def _table(self): + return self._client.load_table(self._collection_name) + + def _filter_to_where(self, filters: Optional[Dict[str, Any]]): + """Convert OpenViking filter dict to SQLAlchemy where clause list for pyobvector.""" + if not filters: + return None + from sqlalchemy import and_, or_ + + table = self._table() + + def walk(expr): + if not isinstance(expr, dict): + return None + op = expr.get("op") + if op == "must": + field = expr.get("field") + conds = expr.get("conds", []) + if field and conds is not None and field in table.c: + return table.c[field].in_(conds) + elif op == "range": + field = expr.get("field") + if field not in table.c: + return None + col = table.c[field] + parts = [] + if "gte" in expr: + parts.append(col >= expr["gte"]) + if "gt" in expr: + parts.append(col > expr["gt"]) + if "lte" in expr: + parts.append(col <= expr["lte"]) + if "lt" in expr: + parts.append(col < expr["lt"]) + return and_(*parts) if parts else None + elif op == "and": + sub = [walk(c) for c in expr.get("conds", [])] + sub = [s for s in sub if s is not None] + return and_(*sub) if sub else None + elif op == "or": + sub = [walk(c) for c in expr.get("conds", [])] + sub = [s for s in sub if s is not None] + return or_(*sub) if sub else None + return None + + clause = walk(filters) + return [clause] if clause is not None else None + + def update(self, fields: Optional[Dict[str, Any]] = None, description: Optional[str] = None): + if fields: + self._meta_data.update(fields) + + def get_meta_data(self) -> Dict[str, Any]: + return dict(self._meta_data) + + def close(self): + try: + if hasattr(self._client, "engine") and self._client.engine: + self._client.engine.dispose() + except Exception as e: + logger.warning("OceanBaseCollection close: %s", e) + + def drop(self): + self._client.drop_collection(self._collection_name) + + # "default" is reserved in OceanBase; use a safe index name when creating index + _OB_INDEX_NAME_FOR_DEFAULT = "ov_vector_idx" + + def create_index(self, index_name: str, meta_data: Dict[str, Any]) -> Any: + vec_meta = (meta_data.get("VectorIndex") or {}) + distance = vec_meta.get("Distance", "l2") + metric = _distance_to_metric(distance) + field_name = "vector" + ob_index_name = self._OB_INDEX_NAME_FOR_DEFAULT if index_name == "default" else index_name + index_params = IndexParams() + index_params.add_index( + field_name=field_name, + index_type=VecIndexType.HNSW, + index_name=ob_index_name, + metric_type=metric, + ) + self._client.create_index(self._collection_name, index_params) + return None + + def has_index(self, index_name: str) -> bool: + try: + table = self._table() + from sqlalchemy import inspect + insp = inspect(self._client.engine) + idxs = insp.get_indexes(self._collection_name) + ob_name = self._OB_INDEX_NAME_FOR_DEFAULT if index_name == "default" else index_name + return any(idx.get("name") == ob_name for idx in idxs) + except Exception: + return False + + def get_index(self, index_name: str) -> Optional[Any]: + return None if not self.has_index(index_name) else object() + + def search_by_vector( + self, + index_name: str, + dense_vector: Optional[List[float]] = None, + limit: int = 10, + offset: int = 0, + filters: Optional[Dict[str, Any]] = None, + sparse_vector: Optional[Dict[str, float]] = None, + output_fields: Optional[List[str]] = None, + ) -> SearchResult: + flter = self._filter_to_where(filters) + data = dense_vector if dense_vector is not None else sparse_vector + if data is None: + return SearchResult(data=[]) + fetch_limit = limit + offset if offset else limit + search_params = {"metric_type": self._distance_metric} + try: + rows = self._client.search( + self._collection_name, + data=data, + anns_field="vector", + with_dist=True, + flter=flter, + limit=fetch_limit, + output_fields=output_fields, + search_params=search_params, + ) + except Exception as e: + logger.warning("OceanBase search failed: %s", e) + return SearchResult(data=[]) + items = [] + for i, row in enumerate(rows): + if offset and i < offset: + continue + if len(items) >= limit: + break + score = ( + row.get("score") + or row.get("l2_distance") + or row.get("inner_product") + or row.get("cosine_distance") + ) + if score is None and isinstance(row, dict) and len(row) > 0: + # pyobvector may put distance as last column + last_val = list(row.values())[-1] + if isinstance(last_val, (int, float)): + score = last_val + score = float(score) if score is not None else 0.0 + pk = self._meta_data.get("PrimaryKey", "id") + row_id = row.get(pk) or row.get("id") + fields = { + k: v + for k, v in row.items() + if k not in (pk, "id", "score", "l2_distance", "inner_product", "cosine_distance") + and not (isinstance(k, str) and "distance" in k.lower()) + } + items.append(SearchItemResult(id=row_id, fields=fields, score=score)) + return SearchResult(data=items) + + def search_by_keywords( + self, + index_name: str, + keywords: Optional[List[str]] = None, + query: Optional[str] = None, + limit: int = 10, + offset: int = 0, + filters: Optional[Dict[str, Any]] = None, + output_fields: Optional[List[str]] = None, + ) -> SearchResult: + # Not supported without vectorizer; delegate to random with filter + return self.search_by_random(index_name, limit, offset, filters, output_fields) + + def search_by_id( + self, + index_name: str, + id: Any, + limit: int = 10, + offset: int = 0, + filters: Optional[Dict[str, Any]] = None, + output_fields: Optional[List[str]] = None, + ) -> SearchResult: + ids = [id] if not isinstance(id, (list, tuple)) else list(id) + rows = self._client.get(self._collection_name, ids=ids, output_fields=output_fields) + if not rows: + return SearchResult(data=[]) + row = rows[0] + vec = row.get("vector") + if vec is not None: + return self.search_by_vector( + index_name, dense_vector=vec, limit=limit, offset=offset, + filters=filters, output_fields=output_fields, + ) + return SearchResult(data=[]) + + def search_by_multimodal( + self, + index_name: str, + text: Optional[str] = None, + image: Optional[Any] = None, + video: Optional[Any] = None, + limit: int = 10, + offset: int = 0, + filters: Optional[Dict[str, Any]] = None, + output_fields: Optional[List[str]] = None, + ) -> SearchResult: + return self.search_by_random(index_name, limit, offset, filters, output_fields) + + def search_by_random( + self, + index_name: str, + limit: int = 10, + offset: int = 0, + filters: Optional[Dict[str, Any]] = None, + output_fields: Optional[List[str]] = None, + ) -> SearchResult: + flter = self._filter_to_where(filters) + try: + rows = self._client.query( + self._collection_name, + flter=flter, + output_fields=output_fields, + ) + except Exception as e: + logger.warning("OceanBase query failed: %s", e) + return SearchResult(data=[]) + pk = self._meta_data.get("PrimaryKey", "id") + items = [] + for i, row in enumerate(rows): + if i < offset: + continue + if len(items) >= limit: + break + row_id = row.get(pk) or row.get("id") + fields = {k: v for k, v in row.items() if k != pk} + items.append(SearchItemResult(id=row_id, fields=fields, score=None)) + return SearchResult(data=items) + + def search_by_scalar( + self, + index_name: str, + field: str, + order: Optional[str] = "desc", + limit: int = 10, + offset: int = 0, + filters: Optional[Dict[str, Any]] = None, + output_fields: Optional[List[str]] = None, + ) -> SearchResult: + from sqlalchemy import select, text as sql_text + + table = self._table() + flter = self._filter_to_where(filters) + if field not in table.c: + return SearchResult(data=[]) + order_col = table.c[field] + stmt = select(table).order_by( + order_col.desc() if (order or "desc").lower() == "desc" else order_col.asc() + ).limit(limit + offset).offset(offset) + if flter: + stmt = stmt.where(*flter) + try: + with self._client.engine.connect() as conn: + res = conn.execute(stmt) + rows = [dict(zip(res.keys(), row)) for row in res.fetchall()] + except Exception as e: + logger.warning("OceanBase search_by_scalar failed: %s", e) + return SearchResult(data=[]) + pk = self._meta_data.get("PrimaryKey", "id") + items = [] + for row in rows: + row_id = row.get(pk) or row.get("id") + fields = {k: v for k, v in row.items() if k != pk} + score = row.get(field) + items.append(SearchItemResult(id=row_id, fields=fields, score=score)) + return SearchResult(data=items) + + def update_index( + self, + index_name: str, + scalar_index: Optional[Dict[str, Any]] = None, + description: Optional[str] = None, + ): + pass + + def get_index_meta_data(self, index_name: str) -> Dict[str, Any]: + return {"IndexName": index_name} + + def list_indexes(self) -> List[str]: + try: + from sqlalchemy import inspect + insp = inspect(self._client.engine) + idxs = insp.get_indexes(self._collection_name) + names = [idx.get("name") for idx in idxs if idx.get("name")] + # Expose "default" to callers to match OpenViking convention + if self._OB_INDEX_NAME_FOR_DEFAULT in names and "default" not in names: + names = ["default"] + [n for n in names if n != self._OB_INDEX_NAME_FOR_DEFAULT] + return names or ["default"] + except Exception: + return ["default"] + + def drop_index(self, index_name: str): + ob_name = self._OB_INDEX_NAME_FOR_DEFAULT if index_name == "default" else index_name + self._client.drop_index(self._collection_name, ob_name) + + def _default_for_field_type(self, field: Dict[str, Any]) -> Any: + """Fill default values for required schema fields missing in row (OceanBase has no column default).""" + typ = (field.get("FieldType") or "").lower() + if typ == "sparse_vector": + return {} + if typ in ("int64", "date_time"): + return 0 + if typ in ("string", "path"): + return "" + return None + + def upsert_data(self, data_list: List[Dict[str, Any]], ttl: int = 0): + if not data_list: + return + fields_meta = self._meta_data.get("Fields", []) + for row in data_list: + if "id" in row and row["id"] is not None: + row["id"] = str(row["id"]) + # Fill schema fields missing in row to avoid "Field doesn't have a default value" + for f in fields_meta: + name = f.get("FieldName") + if name and name not in row: + default = self._default_for_field_type(f) + if default is not None: + row[name] = default + self._client.upsert(self._collection_name, data_list) + + def fetch_data(self, primary_keys: List[Any]) -> FetchDataInCollectionResult: + ids = [str(k) for k in primary_keys] + try: + rows = self._client.get(self._collection_name, ids=ids) + except Exception as e: + logger.warning("OceanBase get failed: %s", e) + return FetchDataInCollectionResult(items=[], ids_not_exist=ids) + pk = self._meta_data.get("PrimaryKey", "id") + items = [] + for row in rows: + row_id = row.get(pk) or row.get("id") + fields = {k: v for k, v in row.items() if k != pk} + items.append(DataItem(id=row_id, fields=fields)) + found = {item.id for item in items} + ids_not_exist = [k for k in ids if k not in found] + return FetchDataInCollectionResult(items=items, ids_not_exist=ids_not_exist) + + def delete_data(self, primary_keys: List[Any]): + if not primary_keys: + return + ids = [str(k) for k in primary_keys] + self._client.delete(self._collection_name, ids=ids) + + def delete_all_data(self): + self._client.delete(self._collection_name, ids=None, flter=None) + + def aggregate_data( + self, + index_name: str, + op: str = "count", + field: Optional[str] = None, + filters: Optional[Dict[str, Any]] = None, + cond: Optional[Dict[str, Any]] = None, + ) -> AggregateResult: + from sqlalchemy import select, func + + table = self._table() + flter = self._filter_to_where(filters) + stmt = select(func.count()).select_from(table) + if flter: + stmt = stmt.where(*flter) + try: + with self._client.engine.connect() as conn: + res = conn.execute(stmt) + total = res.scalar() or 0 + except Exception as e: + logger.warning("OceanBase aggregate failed: %s", e) + return AggregateResult(agg={}, op=op, field=field) + return AggregateResult(agg={"_total": total}, op=op, field=field) + + +class OceanBaseCollectionAdapter(CollectionAdapter): + """Adapter for OceanBase vector database (pyobvector).""" + + def __init__( + self, + collection_name: str, + client: Any, + distance_metric: str = "cosine", + ): + super().__init__(collection_name=collection_name) + self.mode = "oceanbase" + self._client = client + self._distance_metric = distance_metric + + @classmethod + def from_config(cls, config: Any) -> "OceanBaseCollectionAdapter": + if not _PYOBVECTOR_AVAILABLE: + raise RuntimeError( + "OceanBase backend requires pyobvector. Install with: pip install pyobvector" + ) + ob = config.oceanbase + if not ob: + raise ValueError("VectorDB oceanbase backend requires 'oceanbase' config") + client = MilvusLikeClient( + uri=ob.uri, + user=ob.user, + password=ob.password, + db_name=ob.db_name, + ) + return cls( + collection_name=config.name or "context", + client=client, + distance_metric=getattr(config, "distance_metric", "cosine") or "cosine", + ) + + def _load_existing_collection_if_needed(self) -> None: + if self._collection is not None: + return + try: + if self._client.has_collection(self._collection_name): + meta = self._build_meta_from_existing() + self._collection = Collection( + OceanBaseCollection( + client=self._client, + collection_name=self._collection_name, + meta_data=meta, + distance_metric=self._distance_metric, + ) + ) + except Exception as e: + logger.debug("OceanBase load collection %s: %s", self._collection_name, e) + + def _build_meta_from_existing(self) -> Dict[str, Any]: + """Build minimal meta from existing table (for read-only bind).""" + from openviking.storage.collection_schemas import CollectionSchemas + + dim = getattr(self._client, "_vector_dim", None) or 1024 + return CollectionSchemas.context_collection(self._collection_name, dim) + + def _create_backend_collection(self, meta: Dict[str, Any]) -> Collection: + vector_dim = meta.get("Dimension", 0) + schema = _build_oceanbase_schema(meta, vector_dim) + self._client.create_collection( + self._collection_name, + schema=schema, + ) + self._client._vector_dim = vector_dim + icoll = OceanBaseCollection( + client=self._client, + collection_name=self._collection_name, + meta_data=meta, + distance_metric=self._distance_metric, + ) + return Collection(icoll) diff --git a/openviking/storage/viking_fs.py b/openviking/storage/viking_fs.py index bda478ae..f8b8a356 100644 --- a/openviking/storage/viking_fs.py +++ b/openviking/storage/viking_fs.py @@ -22,8 +22,8 @@ from pathlib import PurePath from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union -from openviking.pyagfs.exceptions import AGFSHTTPError from openviking.server.identity import RequestContext, Role +from openviking.telemetry import get_current_telemetry from openviking.utils.time_utils import format_simplified, get_current_timestamp, parse_iso_datetime from openviking_cli.exceptions import NotFoundError from openviking_cli.session.user_id import UserIdentifier @@ -193,9 +193,37 @@ def bind_request_context(self, ctx: RequestContext): finally: self._bound_ctx.reset(token) + @staticmethod + def _normalize_uri(uri: str) -> str: + """Normalize short-format URIs to the canonical viking:// form.""" + if uri.startswith("viking://"): + return uri + return VikingURI.normalize(uri) + + @classmethod + def _normalized_uri_parts(cls, uri: str) -> tuple[str, List[str]]: + """Normalize a URI and reject ambiguous or platform-specific path traversal forms.""" + normalized = cls._normalize_uri(uri) + parts = [p for p in normalized[len("viking://") :].strip("/").split("/") if p] + + for part in parts: + if part in {".", ".."}: + raise PermissionError(f"Unsafe URI traversal segment '{part}' in {normalized}") + if "\\" in part: + raise PermissionError( + f"Unsafe URI path separator '\\\\' in component '{part}' of {normalized}" + ) + if len(part) >= 2 and part[1] == ":" and part[0].isalpha(): + raise PermissionError( + f"Unsafe URI drive-prefixed component '{part}' in {normalized}" + ) + + return normalized, parts + def _ensure_access(self, uri: str, ctx: Optional[RequestContext]) -> None: real_ctx = self._ctx_or_default(ctx) - if not self._is_accessible(uri, real_ctx): + normalized_uri, _ = self._normalized_uri_parts(uri) + if not self._is_accessible(normalized_uri, real_ctx): raise PermissionError(f"Access denied for {uri}") # ========== AGFS Basic Commands ========== @@ -260,15 +288,47 @@ async def rm( This method is idempotent: deleting a non-existent file succeeds after cleaning up any orphan index records. + + Acquires a path lock, deletes VectorDB records, then FS files. + Raises ResourceBusyError when the target is locked by an ongoing + operation (e.g. semantic processing). """ + from openviking.storage.errors import LockAcquisitionError, ResourceBusyError + from openviking.storage.transaction import LockContext, get_lock_manager + self._ensure_access(uri, ctx) path = self._uri_to_path(uri, ctx=ctx) target_uri = self._path_to_uri(path, ctx=ctx) - uris_to_delete = await self._collect_uris(path, recursive, ctx=ctx) - uris_to_delete.append(target_uri) - result = self.agfs.rm(path, recursive=recursive) - await self._delete_from_vector_store(uris_to_delete, ctx=ctx) - return result + + # Check existence and determine lock strategy + try: + stat = self.agfs.stat(path) + is_dir = stat.get("isDir", False) if isinstance(stat, dict) else False + except Exception: + # Path does not exist: clean up any orphan index records and return + uris_to_delete = await self._collect_uris(path, recursive, ctx=ctx) + uris_to_delete.append(target_uri) + await self._delete_from_vector_store(uris_to_delete, ctx=ctx) + logger.info(f"[VikingFS] rm target not found, cleaned orphan index: {uri}") + return {} + + if is_dir: + lock_paths = [path] + lock_mode = "subtree" + else: + parent = path.rsplit("/", 1)[0] if "/" in path else path + lock_paths = [parent] + lock_mode = "point" + + try: + async with LockContext(get_lock_manager(), lock_paths, lock_mode=lock_mode): + uris_to_delete = await self._collect_uris(path, recursive, ctx=ctx) + uris_to_delete.append(target_uri) + await self._delete_from_vector_store(uris_to_delete, ctx=ctx) + result = self.agfs.rm(path, recursive=recursive) + return result + except LockAcquisitionError: + raise ResourceBusyError(f"Resource is being processed: {uri}") async def mv( self, @@ -276,24 +336,69 @@ async def mv( new_uri: str, ctx: Optional[RequestContext] = None, ) -> Dict[str, Any]: - """Move file/directory + recursively update vector index.""" + """Move file/directory + recursively update vector index. + + Implemented as cp + rm to avoid lock files being carried by FS mv. + On VectorDB update failure the copy is cleaned up so the source stays intact. + """ + from openviking.pyagfs.helpers import cp as agfs_cp + from openviking.storage.transaction import LockContext, get_lock_manager + self._ensure_access(old_uri, ctx) self._ensure_access(new_uri, ctx) old_path = self._uri_to_path(old_uri, ctx=ctx) new_path = self._uri_to_path(new_uri, ctx=ctx) target_uri = self._path_to_uri(old_path, ctx=ctx) - uris_to_move = await self._collect_uris(old_path, recursive=True, ctx=ctx) - uris_to_move.append(target_uri) + # Verify source exists and determine type before locking try: - result = self.agfs.mv(old_path, new_path) - await self._update_vector_store_uris(uris_to_move, old_uri, new_uri, ctx=ctx) - return result - except AGFSHTTPError as e: - if e.status_code == 404: - await self._delete_from_vector_store(uris_to_move, ctx=ctx) - logger.info(f"[VikingFS] mv source not found, cleaned orphan index: {old_uri}") - raise + stat = self.agfs.stat(old_path) + is_dir = stat.get("isDir", False) if isinstance(stat, dict) else False + except Exception: + raise FileNotFoundError(f"mv source not found: {old_uri}") + + dst_parent = new_path.rsplit("/", 1)[0] if "/" in new_path else new_path + + async with LockContext( + get_lock_manager(), + [old_path], + lock_mode="mv", + mv_dst_parent_path=dst_parent, + src_is_dir=is_dir, + ): + uris_to_move = await self._collect_uris(old_path, recursive=True, ctx=ctx) + uris_to_move.append(target_uri) + + # Copy source to destination (source still intact) + try: + agfs_cp(self.agfs, old_path, new_path, recursive=is_dir) + except Exception as e: + if "not found" in str(e).lower(): + await self._delete_from_vector_store(uris_to_move, ctx=ctx) + logger.info(f"[VikingFS] mv source not found, cleaned orphan index: {old_uri}") + raise + + # Remove carried lock file from the copy (directory only) + if is_dir: + carried_lock = new_path.rstrip("/") + "/.path.ovlock" + try: + self.agfs.rm(carried_lock) + except Exception: + pass + + # Update VectorDB URIs (on failure, clean up the copy) + try: + await self._update_vector_store_uris(uris_to_move, old_uri, new_uri, ctx=ctx) + except Exception: + try: + self.agfs.rm(new_path, recursive=is_dir) + except Exception: + pass + raise + + # Delete source + self.agfs.rm(old_path, recursive=is_dir) + return {} async def grep( self, @@ -332,6 +437,22 @@ async def stat(self, uri: str, ctx: Optional[RequestContext] = None) -> Dict[str path = self._uri_to_path(uri, ctx=ctx) return self.agfs.stat(path) + async def exists(self, uri: str, ctx: Optional[RequestContext] = None) -> bool: + """Check if a URI exists. + + Args: + uri: Viking URI + ctx: Request context + + Returns: + bool: True if the URI exists, False otherwise + """ + try: + await self.stat(uri, ctx=ctx) + return True + except Exception: + return False + async def glob( self, pattern: str, @@ -578,6 +699,7 @@ async def find( Returns: FindResult """ + telemetry = get_current_telemetry() from openviking.retrieve.hierarchical_retriever import HierarchicalRetriever from openviking_cli.retrieve import ( ContextType, @@ -614,9 +736,14 @@ async def find( target_directories=[target_uri] if target_uri else None, ) + real_ctx = self._ctx_or_default(ctx) + logger.debug( + f"[VikingFS.find] Calling retriever.retrieve with ctx.account_id={real_ctx.account_id}, ctx.user={real_ctx.user}" + ) + result = await retriever.retrieve( typed_query, - ctx=self._ctx_or_default(ctx), + ctx=real_ctx, limit=limit, score_threshold=score_threshold, scope_dsl=filter, @@ -632,11 +759,13 @@ async def find( elif ctx.context_type == ContextType.SKILL: skills.append(ctx) - return FindResult( + find_result = FindResult( memories=memories, resources=resources, skills=skills, ) + telemetry.set("vector.returned", find_result.total) + return find_result async def search( self, @@ -660,6 +789,7 @@ async def search( Returns: FindResult """ + telemetry = get_current_telemetry() from openviking.retrieve.hierarchical_retriever import HierarchicalRetriever from openviking.retrieve.intent_analyzer import IntentAnalyzer from openviking_cli.retrieve import ( @@ -730,6 +860,7 @@ async def search( ) for ctx_type in [ContextType.MEMORY, ContextType.RESOURCE, ContextType.SKILL] ] + telemetry.set("search.typed_queries_count", len(typed_queries)) # Concurrent execution storage = self._get_vector_store() @@ -741,9 +872,13 @@ async def search( ) async def _execute(tq: TypedQuery): + real_ctx = self._ctx_or_default(ctx) + logger.debug( + f"[VikingFS.search._execute] Calling retriever.retrieve with ctx.account_id={real_ctx.account_id}, ctx.user={real_ctx.user}" + ) return await retriever.retrieve( tq, - ctx=self._ctx_or_default(ctx), + ctx=real_ctx, limit=limit, score_threshold=score_threshold, scope_dsl=filter, @@ -762,13 +897,15 @@ async def _execute(tq: TypedQuery): elif ctx.context_type == ContextType.SKILL: skills.append(ctx) - return FindResult( + find_result = FindResult( memories=memories, resources=resources, skills=skills, query_plan=query_plan, query_results=query_results, ) + telemetry.set("vector.returned", find_result.total) + return find_result # ========== Relation Management ========== @@ -872,28 +1009,27 @@ def _uri_to_path(self, uri: str, ctx: Optional[RequestContext] = None) -> str: """ real_ctx = self._ctx_or_default(ctx) account_id = real_ctx.account_id - remainder = uri[len("viking://") :].strip("/") if uri.startswith("viking://") else uri - if not remainder: + _, parts = self._normalized_uri_parts(uri) + if not parts: return f"/local/{account_id}" - parts = [p for p in remainder.split("/") if p] safe_parts = [self._shorten_component(p, self._MAX_FILENAME_BYTES) for p in parts] return f"/local/{account_id}/{'/'.join(safe_parts)}" - _INTERNAL_DIRS = {"_system"} + _INTERNAL_NAMES = {"_system", ".path.ovlock"} _ROOT_PATH = "/local" def _ls_entries(self, path: str) -> List[Dict[str, Any]]: """List directory entries, filtering out internal directories. At account root (/local/{account}), uses VALID_SCOPES whitelist. - At other levels, uses _INTERNAL_DIRS blacklist. + At other levels, uses _INTERNAL_NAMES blacklist. """ entries = self.agfs.ls(path) parts = [p for p in path.strip("/").split("/") if p] if len(parts) == 2 and parts[0] == "local": return [e for e in entries if e.get("name") in VikingURI.VALID_SCOPES] - return [e for e in entries if e.get("name") not in self._INTERNAL_DIRS] + return [e for e in entries if e.get("name") not in self._INTERNAL_NAMES] def _path_to_uri(self, path: str, ctx: Optional[RequestContext] = None) -> str: """/local/{account}/... -> viking://... @@ -926,9 +1062,7 @@ def _extract_space_from_uri(self, uri: str) -> Optional[str]: For user/agent, the second segment is space unless it's a known structure dir. For session, the second segment is always space (when 3+ parts). """ - if not uri.startswith("viking://"): - return None - parts = [p for p in uri[len("viking://") :].strip("/").split("/") if p] + _, parts = self._normalized_uri_parts(uri) if len(parts) < 2: return None scope = parts[0] @@ -946,22 +1080,19 @@ def _extract_space_from_uri(self, uri: str) -> Optional[str]: def _is_accessible(self, uri: str, ctx: RequestContext) -> bool: """Check whether a URI is visible/accessible under current request context.""" + normalized_uri, parts = self._normalized_uri_parts(uri) if ctx.role == Role.ROOT: return True - if not uri.startswith("viking://"): - uri = VikingURI.normalize(uri) - - parts = [p for p in uri[len("viking://") :].strip("/").split("/") if p] if not parts: return True scope = parts[0] - if scope in {"resources", "temp", "transactions"}: + if scope in {"resources", "temp"}: return True if scope == "_system": return False - space = self._extract_space_from_uri(uri) + space = self._extract_space_from_uri(normalized_uri) if space is None: return True @@ -1016,19 +1147,6 @@ def _handle_agfs_content(self, result: Union[bytes, Any, None]) -> str: return str(result) except Exception: return "" - """Handle AGFSClient content return types consistently.""" - if isinstance(result, bytes): - return result.decode("utf-8") - elif hasattr(result, "content"): - return result.content.decode("utf-8") - elif result is None: - return "" - else: - # Try to convert to string - try: - return str(result) - except Exception: - return "" def _infer_context_type(self, uri: str): """Infer context_type from URI. Returns None when ambiguous.""" @@ -1047,7 +1165,7 @@ def _infer_context_type(self, uri: str): async def _collect_uris( self, path: str, recursive: bool, ctx: Optional[RequestContext] = None ) -> List[str]: - """Recursively collect all URIs (for rm/mv).""" + """Recursively collect all URIs (for rm/mv), including directories.""" uris = [] async def _collect(p: str): @@ -1058,6 +1176,7 @@ async def _collect(p: str): continue full_path = f"{p}/{name}".replace("//", "/") if entry.get("isDir"): + uris.append(self._path_to_uri(full_path, ctx=ctx)) if recursive: await _collect(full_path) else: @@ -1107,23 +1226,8 @@ async def _update_vector_store_uris( for uri in uris: try: - records = await vector_store.get_context_by_uri( - account_id=self._ctx_or_default(ctx).account_id, - uri=uri, - limit=1, - ) - - if not records or "id" not in records[0]: - continue - - record = records[0] - new_uri = uri.replace(old_base_uri, new_base_uri, 1) - - old_parent_uri = record.get("parent_uri", "") - new_parent_uri = ( - old_parent_uri.replace(old_base_uri, new_base_uri, 1) if old_parent_uri else "" - ) + new_parent_uri = VikingURI(new_uri).parent.uri await vector_store.update_uri_mapping( ctx=self._ctx_or_default(ctx), @@ -1255,6 +1359,12 @@ async def read_file( """ self._ensure_access(uri, ctx) path = self._uri_to_path(uri, ctx=ctx) + # Verify the file exists before reading, because AGFS read returns + # empty bytes for non-existent files instead of raising an error. + try: + self.agfs.stat(path) + except Exception: + raise NotFoundError(uri, "file") try: content = self.agfs.read(path) except Exception: diff --git a/openviking/storage/viking_vector_index_backend.py b/openviking/storage/viking_vector_index_backend.py index b8edb836..29026d49 100644 --- a/openviking/storage/viking_vector_index_backend.py +++ b/openviking/storage/viking_vector_index_backend.py @@ -11,46 +11,39 @@ from openviking.storage.expr import And, Eq, FilterExpr, In, Or, PathScope, RawDSL from openviking.storage.vectordb.collection.collection import Collection from openviking.storage.vectordb.utils.logging_init import init_cpp_logging -from openviking.storage.vectordb_adapters import CollectionAdapter, create_collection_adapter +from openviking.storage.vectordb_adapters import create_collection_adapter from openviking_cli.utils import get_logger from openviking_cli.utils.config.vectordb_config import VectorDBBackendConfig logger = get_logger(__name__) -class VikingVectorIndexBackend: - """Single-collection vector backend with adapter-based backend specialization.""" - - DEFAULT_INDEX_NAME = "default" - ALLOWED_CONTEXT_TYPES = {"resource", "skill", "memory"} - - def __init__(self, config: Optional[VectorDBBackendConfig]): - if config is None: - raise ValueError("VectorDB backend config is required") +class _SingleAccountBackend: + """绑定单个 account 的后端实现(内部类)""" - init_cpp_logging() + def __init__(self, config: VectorDBBackendConfig, bound_account_id: Optional[str]): + """ + 初始化单 account 后端。 - self.vector_dim = config.dimension - self.distance_metric = config.distance_metric - self.sparse_weight = config.sparse_weight - self._collection_name = config.name or "context" - - self._adapter: CollectionAdapter = create_collection_adapter(config) + Args: + config: VectorDB 配置 + bound_account_id: 绑定的 account_id,None 表示 root 特权模式 + """ + self._bound_account_id = bound_account_id + self._adapter = create_collection_adapter(config) + self._collection_config: Dict[str, Any] = {} + self._meta_data_cache: Dict[str, Any] = {} self._mode = self._adapter.mode + self._distance_metric = "cosine" + self._sparse_weight = 0.0 + self._collection_name = "context" logger.info( - "VikingDB backend initialized via adapter %s (mode=%s)", - type(self._adapter).__name__, + "_SingleAccountBackend initialized (bound_account_id=%s, mode=%s)", + bound_account_id, self._mode, ) - self._collection_config: Dict[str, Any] = {} - self._meta_data_cache: Dict[str, Any] = {} - - @property - def collection_name(self) -> str: - return self._collection_name - def _get_collection(self) -> Collection: return self._adapter.get_collection() @@ -72,38 +65,35 @@ def _filter_known_fields(self, data: Dict[str, Any]) -> Dict[str, Any]: return data # ========================================================================= - # Collection Management (single collection) + # Collection Management # ========================================================================= async def create_collection(self, name: str, schema: Dict[str, Any]) -> bool: try: collection_meta = dict(schema) - - # Track vector dim from schema for info. - vector_dim = self.vector_dim + vector_dim = None for field in collection_meta.get("Fields", []): if field.get("FieldType") == "vector": - vector_dim = field.get("Dim", self.vector_dim) + vector_dim = field.get("Dim") break created = self._adapter.create_collection( name=name, schema=collection_meta, - distance=self.distance_metric, - sparse_weight=self.sparse_weight, - index_name=self.DEFAULT_INDEX_NAME, + distance=self._distance_metric, + sparse_weight=self._sparse_weight, + index_name=VikingVectorIndexBackend.DEFAULT_INDEX_NAME, ) if not created: return False - self._collection_name = name self._collection_config = { "vector_dim": vector_dim, - "distance": self.distance_metric, + "distance": self._distance_metric, "schema": schema, } self._refresh_meta_data(self._get_collection()) - logger.info("Created VikingDB collection: %s (dim=%s)", name, vector_dim) + logger.info("Created collection: %s", name) return True except Exception as e: logger.error("Error creating collection %s: %s", name, e) @@ -117,7 +107,7 @@ async def drop_collection(self) -> bool: self._meta_data_cache = {} return dropped except Exception as e: - logger.error("Error dropping collection %s: %s", self._collection_name, e) + logger.error("Error dropping collection: %s", e) return False async def collection_exists(self) -> bool: @@ -129,26 +119,33 @@ async def get_collection_info(self) -> Optional[Dict[str, Any]]: config = self._collection_config return { "name": self._collection_name, - "vector_dim": config.get("vector_dim", self.vector_dim), + "vector_dim": config.get("vector_dim"), "count": await self.count(), "status": "active", } - async def collection_exists_bound(self) -> bool: - return await self.collection_exists() - # ========================================================================= - # Data Operations + # Data Operations (with tenant enforcement) # ========================================================================= async def upsert(self, data: Dict[str, Any]) -> str: payload = dict(data) + logger.debug( + f"[_SingleAccountBackend.upsert] Input data.account_id={payload.get('account_id')}, bound_account_id={self._bound_account_id}" + ) + + if self._bound_account_id and not payload.get("account_id"): + payload["account_id"] = self._bound_account_id + logger.debug( + f"[_SingleAccountBackend.upsert] Final payload.account_id={payload.get('account_id')}" + ) + context_type = payload.get("context_type") - if context_type and context_type not in self.ALLOWED_CONTEXT_TYPES: + if context_type and context_type not in VikingVectorIndexBackend.ALLOWED_CONTEXT_TYPES: logger.warning( "Invalid context_type: %s. Must be one of %s", context_type, - sorted(self.ALLOWED_CONTEXT_TYPES), + sorted(VikingVectorIndexBackend.ALLOWED_CONTEXT_TYPES), ) return "" @@ -161,18 +158,36 @@ async def upsert(self, data: Dict[str, Any]) -> str: async def get(self, ids: List[str]) -> List[Dict[str, Any]]: try: - return self._adapter.get(ids) + records = self._adapter.get(ids) + if self._bound_account_id: + records = [r for r in records if r.get("account_id") == self._bound_account_id] + return records except Exception as e: logger.error("Error getting records: %s", e) return [] async def delete(self, ids: List[str]) -> int: try: + if self._bound_account_id: + records = await self.get(ids) + valid_ids = [r["id"] for r in records if r.get("id")] + if len(valid_ids) != len(ids): + logger.warning("Attempted to delete records outside bound account") + ids = valid_ids + return self._adapter.delete(ids=ids) except Exception as e: logger.error("Error deleting records: %s", e) return 0 + async def delete_by_filter(self, filter: FilterExpr) -> int: + """Root-only: 直接通过 filter 删除""" + try: + return self._adapter.delete(filter=filter) + except Exception as e: + logger.error("Error deleting by filter: %s", e) + return 0 + async def exists(self, id: str) -> bool: try: return len(await self.get([id])) > 0 @@ -204,6 +219,21 @@ async def query( order_desc: bool = False, ) -> List[Dict[str, Any]]: try: + logger.debug( + f"[_SingleAccountBackend.query] Called with bound_account_id={self._bound_account_id}, filter={filter}" + ) + if self._bound_account_id: + account_filter = Eq("account_id", self._bound_account_id) + if filter: + if isinstance(filter, dict): + filter = RawDSL(filter) + filter = And([account_filter, filter]) + else: + filter = account_filter + logger.debug( + f"[_SingleAccountBackend.query] Applied account filter, final filter={filter}" + ) + return self._adapter.query( query_vector=query_vector, sparse_query_vector=sparse_query_vector, @@ -215,7 +245,7 @@ async def query( order_desc=order_desc, ) except Exception as e: - logger.error("Error querying collection %s: %s", self._collection_name, e) + logger.error("Error querying collection: %s", e) return [] async def search( @@ -227,7 +257,6 @@ async def search( offset: int = 0, output_fields: Optional[List[str]] = None, ) -> List[Dict[str, Any]]: - # Backward-compatible alias for internal call sites. return await self.query( query_vector=query_vector, sparse_query_vector=sparse_query_vector, @@ -293,8 +322,354 @@ async def _remove_descendants(self, parent_uri: str) -> int: total_deleted += 1 return total_deleted + async def scroll( + self, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + limit: int = 100, + cursor: Optional[str] = None, + output_fields: Optional[List[str]] = None, + ) -> tuple[List[Dict[str, Any]], Optional[str]]: + offset = int(cursor) if cursor else 0 + records = await self.filter( + filter=filter or {}, + limit=limit, + offset=offset, + output_fields=output_fields, + ) + next_cursor = str(offset + limit) if len(records) == limit else None + return records, next_cursor + + async def count(self, filter: Optional[Dict[str, Any] | FilterExpr] = None) -> int: + try: + if self._bound_account_id: + account_filter = Eq("account_id", self._bound_account_id) + if filter: + if isinstance(filter, dict): + filter = RawDSL(filter) + filter = And([account_filter, filter]) + else: + filter = account_filter + + return self._adapter.count(filter=filter) + except Exception as e: + logger.error("Error counting records: %s", e) + return 0 + + async def clear(self) -> bool: + try: + if self._bound_account_id: + return await self.delete_by_filter(Eq("account_id", self._bound_account_id)) > 0 + return self._adapter.clear() + except Exception as e: + logger.error("Error clearing collection: %s", e) + return False + + async def optimize(self) -> bool: + logger.info("Optimization requested") + return True + + async def close(self) -> None: + try: + self._adapter.close() + self._collection_config = {} + self._meta_data_cache = {} + logger.info("_SingleAccountBackend closed") + except Exception as e: + logger.error("Error closing backend: %s", e) + + async def health_check(self) -> bool: + try: + await self.collection_exists() + return True + except Exception: + return False + + async def get_stats(self) -> Dict[str, Any]: + try: + exists = await self.collection_exists() + total_records = await self.count() if exists else 0 + return { + "collections": 1 if exists else 0, + "total_records": total_records, + "backend": "vikingdb", + "mode": self._mode, + "bound_account_id": self._bound_account_id, + } + except Exception as e: + logger.error("Error getting stats: %s", e) + return { + "collections": 0, + "total_records": 0, + "backend": "vikingdb", + "error": str(e), + } + + @property + def is_closing(self) -> bool: + return False + + +class VikingVectorIndexBackend: + """单例门面,管理 per-account 后端实例""" + + DEFAULT_INDEX_NAME = "default" + ALLOWED_CONTEXT_TYPES = {"resource", "skill", "memory"} + + def __init__(self, config: Optional[VectorDBBackendConfig]): + if config is None: + raise ValueError("VectorDB backend config is required") + + init_cpp_logging() + + self._config = config + self.vector_dim = config.dimension + self.distance_metric = config.distance_metric + self.sparse_weight = config.sparse_weight + self._collection_name = config.name or "context" + + self._account_backends: Dict[str, _SingleAccountBackend] = {} + self._root_backend: Optional[_SingleAccountBackend] = None + + logger.info( + "VikingVectorIndexBackend facade initialized", + ) + + @property + def collection_name(self) -> str: + return self._collection_name + + @property + def mode(self) -> str: + return self._get_default_backend()._mode + + # ========================================================================= + # 内部辅助方法 + # ========================================================================= + + def _get_default_backend(self) -> _SingleAccountBackend: + """获取默认 backend(用于 collection 管理等操作)""" + return self._get_backend_for_account("default") + + def _get_backend_for_account(self, account_id: str) -> _SingleAccountBackend: + """获取指定 account 的 backend,懒创建""" + if account_id not in self._account_backends: + backend = _SingleAccountBackend(self._config, bound_account_id=account_id) + backend._distance_metric = self.distance_metric + backend._sparse_weight = self.sparse_weight + backend._collection_name = self._collection_name + self._account_backends[account_id] = backend + return self._account_backends[account_id] + + def _get_backend_for_context(self, ctx: RequestContext) -> _SingleAccountBackend: + """根据上下文获取 backend""" + return self._get_backend_for_account(ctx.account_id) + + def _get_root_backend(self) -> _SingleAccountBackend: + """获取 root 特权 backend""" + if not self._root_backend: + self._root_backend = _SingleAccountBackend(self._config, bound_account_id=None) + self._root_backend._distance_metric = self.distance_metric + self._root_backend._sparse_weight = self.sparse_weight + self._root_backend._collection_name = self._collection_name + return self._root_backend + + def _check_root_role(self, ctx: RequestContext) -> None: + """校验是否为 root 角色""" + if ctx.role != Role.ROOT: + raise PermissionError(f"Root role required, got {ctx.role}") + + # ========================================================================= + # Collection Management(委托给默认 backend) + # ========================================================================= + + async def create_collection(self, name: str, schema: Dict[str, Any]) -> bool: + return await self._get_default_backend().create_collection(name, schema) + + async def drop_collection(self) -> bool: + return await self._get_default_backend().drop_collection() + + async def collection_exists(self) -> bool: + return await self._get_default_backend().collection_exists() + + async def collection_exists_bound(self) -> bool: + return await self.collection_exists() + + async def get_collection_info(self) -> Optional[Dict[str, Any]]: + return await self._get_default_backend().get_collection_info() + + # ========================================================================= + # 公开数据操作 API(强制要求 ctx) + # ========================================================================= + + async def upsert(self, data: Dict[str, Any], *, ctx: RequestContext) -> str: + logger.debug( + f"[VikingVectorIndexBackend.upsert] Called with ctx.account_id={ctx.account_id}, data={data}" + ) + backend = self._get_backend_for_context(ctx) + logger.debug( + f"[VikingVectorIndexBackend.upsert] Using backend for account_id={ctx.account_id}" + ) + result = await backend.upsert(data) + logger.debug(f"[VikingVectorIndexBackend.upsert] Completed, result={result}") + return result + + async def get(self, ids: List[str], *, ctx: RequestContext) -> List[Dict[str, Any]]: + backend = self._get_backend_for_context(ctx) + return await backend.get(ids) + + async def delete(self, ids: List[str], *, ctx: RequestContext) -> int: + backend = self._get_backend_for_context(ctx) + return await backend.delete(ids) + + async def exists(self, id: str, *, ctx: RequestContext) -> bool: + backend = self._get_backend_for_context(ctx) + return await backend.exists(id) + + async def fetch_by_uri(self, uri: str, *, ctx: RequestContext) -> Optional[Dict[str, Any]]: + backend = self._get_backend_for_context(ctx) + return await backend.fetch_by_uri(uri) + + async def query( + self, + query_vector: Optional[List[float]] = None, + sparse_query_vector: Optional[Dict[str, float]] = None, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + limit: int = 10, + offset: int = 0, + output_fields: Optional[List[str]] = None, + order_by: Optional[str] = None, + order_desc: bool = False, + *, + ctx: RequestContext, + ) -> List[Dict[str, Any]]: + backend = self._get_backend_for_context(ctx) + return await backend.query( + query_vector=query_vector, + sparse_query_vector=sparse_query_vector, + filter=filter, + limit=limit, + offset=offset, + output_fields=output_fields, + order_by=order_by, + order_desc=order_desc, + ) + + async def search( + self, + query_vector: Optional[List[float]] = None, + sparse_query_vector: Optional[Dict[str, float]] = None, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + limit: int = 10, + offset: int = 0, + output_fields: Optional[List[str]] = None, + *, + ctx: RequestContext, + ) -> List[Dict[str, Any]]: + return await self.query( + query_vector=query_vector, + sparse_query_vector=sparse_query_vector, + filter=filter, + limit=limit, + offset=offset, + output_fields=output_fields, + ctx=ctx, + ) + + async def filter( + self, + filter: Dict[str, Any] | FilterExpr, + limit: int = 10, + offset: int = 0, + output_fields: Optional[List[str]] = None, + order_by: Optional[str] = None, + order_desc: bool = False, + *, + ctx: RequestContext, + ) -> List[Dict[str, Any]]: + return await self.query( + filter=filter, + limit=limit, + offset=offset, + output_fields=output_fields, + order_by=order_by, + order_desc=order_desc, + ctx=ctx, + ) + + async def remove_by_uri(self, uri: str, *, ctx: RequestContext) -> int: + backend = self._get_backend_for_context(ctx) + return await backend.remove_by_uri(uri) + + async def scroll( + self, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + limit: int = 100, + cursor: Optional[str] = None, + output_fields: Optional[List[str]] = None, + *, + ctx: RequestContext, + ) -> tuple[List[Dict[str, Any]], Optional[str]]: + backend = self._get_backend_for_context(ctx) + return await backend.scroll( + filter=filter, + limit=limit, + cursor=cursor, + output_fields=output_fields, + ) + + async def count( + self, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + *, + ctx: Optional[RequestContext] = None, + ) -> int: + if ctx: + backend = self._get_backend_for_context(ctx) + else: + backend = self._get_default_backend() + return await backend.count(filter=filter) + + async def clear(self, *, ctx: Optional[RequestContext] = None) -> bool: + if ctx: + backend = self._get_backend_for_context(ctx) + else: + backend = self._get_default_backend() + return await backend.clear() + + async def optimize(self) -> bool: + return await self._get_default_backend().optimize() + + async def close(self) -> None: + try: + for backend in self._account_backends.values(): + await backend.close() + if self._root_backend: + await self._root_backend.close() + self._account_backends.clear() + self._root_backend = None + logger.info("VikingVectorIndexBackend facade closed") + except Exception as e: + logger.error("Error closing facade: %s", e) + + async def health_check(self) -> bool: + return await self._get_default_backend().health_check() + + async def get_stats(self) -> Dict[str, Any]: + return await self._get_default_backend().get_stats() + + @property + def is_closing(self) -> bool: + return False + + @property + def has_queue_manager(self) -> bool: + return False + + async def enqueue_embedding_msg(self, _embedding_msg) -> bool: + raise NotImplementedError("Queue management requires VikingDBManager") + # ========================================================================= - # Semantic Context Operations (Tenant-Aware) + # Tenant-Aware 方法(保持向后兼容) # ========================================================================= async def search_in_tenant( @@ -320,6 +695,7 @@ async def search_in_tenant( filter=scope_filter, limit=limit, offset=offset, + ctx=ctx, ) async def search_global_roots_in_tenant( @@ -342,13 +718,14 @@ async def search_global_roots_in_tenant( target_directories=target_directories, extra_filter=extra_filter, ), - In("level", [0, 1]), + In("level", [0, 1, 2]), # TODO: smj fix this ) return await self.search( query_vector=query_vector, sparse_query_vector=sparse_query_vector, filter=merged_filter, limit=limit, + ctx=ctx, ) async def search_children_in_tenant( @@ -376,27 +753,30 @@ async def search_children_in_tenant( sparse_query_vector=sparse_query_vector, filter=merged_filter, limit=limit, + ctx=ctx, ) async def search_similar_memories( self, - account_id: str, owner_space: Optional[str], category_uri_prefix: str, query_vector: List[float], limit: int = 5, + *, + ctx: RequestContext, ) -> List[Dict[str, Any]]: conds: List[FilterExpr] = [ Eq("context_type", "memory"), Eq("level", 2), - Eq("account_id", account_id), + Eq("account_id", ctx.account_id), ] if owner_space: conds.append(Eq("owner_space", owner_space)) if category_uri_prefix: conds.append(In("uri", [category_uri_prefix])) - return await self.search( + backend = self._get_backend_for_context(ctx) + return await backend.search( query_vector=query_vector, filter=And(conds), limit=limit, @@ -404,21 +784,27 @@ async def search_similar_memories( async def get_context_by_uri( self, - account_id: str, uri: str, owner_space: Optional[str] = None, level: Optional[int] = None, limit: int = 1, + *, + ctx: RequestContext, ) -> List[Dict[str, Any]]: - conds: List[FilterExpr] = [PathScope("uri", uri, depth=0), Eq("account_id", account_id)] + conds: List[FilterExpr] = [PathScope("uri", uri, depth=0), Eq("account_id", ctx.account_id)] if owner_space: conds.append(Eq("owner_space", owner_space)) if level is not None: conds.append(Eq("level", level)) - return await self.filter(filter=And(conds), limit=limit) - async def delete_account_data(self, account_id: str) -> int: - return self._adapter.delete(filter=Eq("account_id", account_id)) + backend = self._get_backend_for_context(ctx) + return await backend.filter(filter=And(conds), limit=limit) + + async def delete_account_data(self, account_id: str, *, ctx: RequestContext) -> int: + """删除指定 account 的所有数据(仅限,root 角色操作)""" + self._check_root_role(ctx) + root_backend = self._get_root_backend() + return await root_backend.delete_by_filter(Eq("account_id", account_id)) async def delete_uris(self, ctx: RequestContext, uris: List[str]) -> None: for uri in uris: @@ -433,7 +819,9 @@ async def delete_uris(self, ctx: RequestContext, uris: List[str]) -> None: else ctx.user.agent_space_name() ) conds.append(Eq("owner_space", owner_space)) - self._adapter.delete(filter=And(conds)) + + backend = self._get_backend_for_context(ctx) + await backend.delete_by_filter(And(conds)) async def update_uri_mapping( self, @@ -442,25 +830,73 @@ async def update_uri_mapping( new_uri: str, new_parent_uri: str, ) -> bool: + import hashlib + records = await self.filter( filter=And([Eq("uri", uri), Eq("account_id", ctx.account_id)]), - limit=1, + limit=100, + ctx=ctx, ) - if not records or "id" not in records[0]: + if not records: return False - updated = {**records[0], "uri": new_uri, "parent_uri": new_parent_uri} - return bool(await self.upsert(updated)) + + def _seed_uri_for_id(uri: str, level: int) -> str: + if level == 0: + return uri if uri.endswith("/.abstract.md") else f"{uri}/.abstract.md" + if level == 1: + return uri if uri.endswith("/.overview.md") else f"{uri}/.overview.md" + return uri + + success = False + ids_to_delete: List[str] = [] + for record in records: + if "id" not in record: + continue + raw_level = record.get("level", 2) + try: + level = int(raw_level) + except (TypeError, ValueError): + level = 2 + + seed_uri = _seed_uri_for_id(new_uri, level) + id_seed = f"{ctx.account_id}:{seed_uri}" + new_id = hashlib.md5(id_seed.encode("utf-8")).hexdigest() + + updated = { + **record, + "id": new_id, + "uri": new_uri, + "parent_uri": new_parent_uri, + } + if await self.upsert(updated, ctx=ctx): + success = True + old_id = record.get("id") + if old_id and old_id != new_id: + ids_to_delete.append(old_id) + + if ids_to_delete: + await self.delete(list(set(ids_to_delete)), ctx=ctx) + + return success async def increment_active_count(self, ctx: RequestContext, uris: List[str]) -> int: updated = 0 for uri in uris: - records = await self.get_context_by_uri(account_id=ctx.account_id, uri=uri, limit=1) + records = await self.get_context_by_uri(uri=uri, limit=100, ctx=ctx) if not records: continue - record = records[0] - current = int(record.get("active_count", 0) or 0) - record["active_count"] = current + 1 - if await self.upsert(record): + record_ids = [r["id"] for r in records if r.get("id")] + if not record_ids: + continue + # Re-fetch by ID to get full records including vectors + full_records = await self.get(record_ids, ctx=ctx) + uri_updated = False + for record in full_records: + current = int(record.get("active_count", 0) or 0) + record["active_count"] = current + 1 + if await self.upsert(record, ctx=ctx): + uri_updated = True + if uri_updated: updated += 1 return updated @@ -513,7 +949,6 @@ def _tenant_filter( if context_type in {"memory", "skill"}: return And([account_filter, In("owner_space", user_spaces)]) - # context_type=None: include shared owner_space only for resources. return And( [ account_filter, @@ -548,82 +983,3 @@ def _merge_filters(*filters: Optional[FilterExpr]) -> Optional[FilterExpr]: if len(non_empty) == 1: return non_empty[0] return And(non_empty) - - async def scroll( - self, - filter: Optional[Dict[str, Any] | FilterExpr] = None, - limit: int = 100, - cursor: Optional[str] = None, - output_fields: Optional[List[str]] = None, - ) -> tuple[List[Dict[str, Any]], Optional[str]]: - offset = int(cursor) if cursor else 0 - records = await self.filter( - filter=filter or {}, - limit=limit, - offset=offset, - output_fields=output_fields, - ) - next_cursor = str(offset + limit) if len(records) == limit else None - return records, next_cursor - - async def count(self, filter: Optional[Dict[str, Any] | FilterExpr] = None) -> int: - try: - return self._adapter.count(filter=filter) - except Exception as e: - logger.error("Error counting records: %s", e) - return 0 - - async def clear(self) -> bool: - try: - return self._adapter.clear() - except Exception as e: - logger.error("Error clearing collection: %s", e) - return False - - async def optimize(self) -> bool: - logger.info("Optimization requested for collection: %s", self._collection_name) - return True - - async def close(self) -> None: - try: - self._adapter.close() - self._collection_config = {} - self._meta_data_cache = {} - logger.info("VikingDB backend closed") - except Exception as e: - logger.error("Error closing VikingDB backend: %s", e) - - async def health_check(self) -> bool: - try: - await self.collection_exists() - return True - except Exception: - return False - - async def get_stats(self) -> Dict[str, Any]: - try: - exists = await self.collection_exists() - total_records = await self.count() if exists else 0 - return { - "collections": 1 if exists else 0, - "total_records": total_records, - "backend": "vikingdb", - "mode": self._mode, - } - except Exception as e: - logger.error("Error getting stats: %s", e) - return { - "collections": 0, - "total_records": 0, - "backend": "vikingdb", - "error": str(e), - } - - @property - def is_closing(self) -> bool: - """Whether the backend is in shutdown flow. Always False for the base class.""" - return False - - @property - def mode(self) -> str: - return self._mode diff --git a/openviking/storage/vikingdb_manager.py b/openviking/storage/vikingdb_manager.py index 32458bda..f332ab32 100644 --- a/openviking/storage/vikingdb_manager.py +++ b/openviking/storage/vikingdb_manager.py @@ -4,8 +4,10 @@ VikingDB Manager class that extends VikingVectorIndexBackend with queue management functionality. """ -from typing import Optional +from typing import Any, Dict, List, Optional, Tuple +from openviking.server.identity import RequestContext +from openviking.storage.expr import FilterExpr from openviking.storage.queuefs.embedding_msg import EmbeddingMsg from openviking.storage.queuefs.embedding_queue import EmbeddingQueue from openviking.storage.queuefs.queue_manager import QueueManager @@ -165,3 +167,347 @@ def get_embedder(self): except Exception as e: logger.warning(f"Failed to get embedder from configuration: {e}") return None + + +class VikingDBManagerProxy: + """ + 租户绑定的 VikingDBManager 代理。 + + 使用 RequestContext 初始化后,所有方法调用自动携带 ctx, + 无需在每次调用时显式传入。API 与 VikingDBManager 完全兼容。 + + 示例: + ```python + # 初始化 + manager = VikingDBManager(...) + proxy = VikingDBManagerProxy(manager, ctx) + + # 使用(无需传 ctx,API 完全兼容) + await proxy.upsert(data) + results = await proxy.search_similar_memories(...) + ``` + """ + + def __init__( + self, + manager: VikingDBManager, + ctx: RequestContext, + ): + """ + 初始化租户绑定的 VikingDBManager 代理。 + + Args: + manager: 底层的 VikingDBManager 实例 + ctx: 请求上下文,包含租户信息 + """ + self._manager = manager + self._ctx = ctx + + @property + def ctx(self) -> RequestContext: + """获取绑定的请求上下文。""" + return self._ctx + + @property + def manager(self) -> VikingDBManager: + """获取底层的 VikingDBManager 实例。""" + return self._manager + + @property + def collection_name(self) -> str: + return self._manager.collection_name + + @property + def mode(self) -> str: + return self._manager.mode + + # ========================================================================= + # Queue Management Properties(透传) + # ========================================================================= + + @property + def queue_manager(self): + return self._manager.queue_manager + + @property + def embedding_queue(self) -> Optional["EmbeddingQueue"]: + return self._manager.embedding_queue + + @property + def has_queue_manager(self) -> bool: + return self._manager.has_queue_manager + + def mark_closing(self) -> None: + return self._manager.mark_closing() + + @property + def is_closing(self) -> bool: + return self._manager.is_closing + + # ========================================================================= + # Queue Operations(透传) + # ========================================================================= + + async def enqueue_embedding_msg(self, embedding_msg: "EmbeddingMsg") -> bool: + return await self._manager.enqueue_embedding_msg(embedding_msg) + + async def get_embedding_queue_size(self) -> int: + return await self._manager.get_embedding_queue_size() + + def get_embedder(self): + return self._manager.get_embedder() + + # ========================================================================= + # Collection Management(透传) + # ========================================================================= + + async def create_collection(self, name: str, schema: Dict[str, Any]) -> bool: + return await self._manager.create_collection(name, schema) + + async def drop_collection(self) -> bool: + return await self._manager.drop_collection() + + async def collection_exists(self) -> bool: + return await self._manager.collection_exists() + + async def collection_exists_bound(self) -> bool: + return await self._manager.collection_exists_bound() + + async def get_collection_info(self) -> Optional[Dict[str, Any]]: + return await self._manager.get_collection_info() + + # ========================================================================= + # 数据操作 API(自动携带 ctx) + # ========================================================================= + + async def upsert(self, data: Dict[str, Any]) -> str: + return await self._manager.upsert(data, ctx=self._ctx) + + async def get(self, ids: List[str]) -> List[Dict[str, Any]]: + return await self._manager.get(ids, ctx=self._ctx) + + async def delete(self, ids: List[str]) -> int: + return await self._manager.delete(ids, ctx=self._ctx) + + async def exists(self, id: str) -> bool: + return await self._manager.exists(id, ctx=self._ctx) + + async def fetch_by_uri(self, uri: str) -> Optional[Dict[str, Any]]: + return await self._manager.fetch_by_uri(uri, ctx=self._ctx) + + async def query( + self, + query_vector: Optional[List[float]] = None, + sparse_query_vector: Optional[Dict[str, float]] = None, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + limit: int = 10, + offset: int = 0, + output_fields: Optional[List[str]] = None, + order_by: Optional[str] = None, + order_desc: bool = False, + ) -> List[Dict[str, Any]]: + return await self._manager.query( + query_vector=query_vector, + sparse_query_vector=sparse_query_vector, + filter=filter, + limit=limit, + offset=offset, + output_fields=output_fields, + order_by=order_by, + order_desc=order_desc, + ctx=self._ctx, + ) + + async def search( + self, + query_vector: Optional[List[float]] = None, + sparse_query_vector: Optional[Dict[str, float]] = None, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + limit: int = 10, + offset: int = 0, + output_fields: Optional[List[str]] = None, + ) -> List[Dict[str, Any]]: + return await self._manager.search( + query_vector=query_vector, + sparse_query_vector=sparse_query_vector, + filter=filter, + limit=limit, + offset=offset, + output_fields=output_fields, + ctx=self._ctx, + ) + + async def filter( + self, + filter: Dict[str, Any] | FilterExpr, + limit: int = 10, + offset: int = 0, + output_fields: Optional[List[str]] = None, + order_by: Optional[str] = None, + order_desc: bool = False, + ) -> List[Dict[str, Any]]: + return await self._manager.filter( + filter=filter, + limit=limit, + offset=offset, + output_fields=output_fields, + order_by=order_by, + order_desc=order_desc, + ctx=self._ctx, + ) + + async def remove_by_uri(self, uri: str) -> int: + return await self._manager.remove_by_uri(uri, ctx=self._ctx) + + async def scroll( + self, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + limit: int = 100, + cursor: Optional[str] = None, + output_fields: Optional[List[str]] = None, + ) -> Tuple[List[Dict[str, Any]], Optional[str]]: + return await self._manager.scroll( + filter=filter, + limit=limit, + cursor=cursor, + output_fields=output_fields, + ctx=self._ctx, + ) + + async def count( + self, + filter: Optional[Dict[str, Any] | FilterExpr] = None, + ) -> int: + return await self._manager.count(filter=filter, ctx=self._ctx) + + async def clear(self) -> bool: + return await self._manager.clear(ctx=self._ctx) + + async def optimize(self) -> bool: + return await self._manager.optimize() + + async def close(self) -> None: + return await self._manager.close() + + async def health_check(self) -> bool: + return await self._manager.health_check() + + async def get_stats(self) -> Dict[str, Any]: + return await self._manager.get_stats() + + # ========================================================================= + # Tenant-Aware 方法(自动携带 ctx) + # ========================================================================= + + async def search_in_tenant( + self, + query_vector: Optional[List[float]], + sparse_query_vector: Optional[Dict[str, float]] = None, + context_type: Optional[str] = None, + target_directories: Optional[List[str]] = None, + extra_filter: Optional[FilterExpr | Dict[str, Any]] = None, + limit: int = 10, + offset: int = 0, + ) -> List[Dict[str, Any]]: + return await self._manager.search_in_tenant( + self._ctx, + query_vector=query_vector, + sparse_query_vector=sparse_query_vector, + context_type=context_type, + target_directories=target_directories, + extra_filter=extra_filter, + limit=limit, + offset=offset, + ) + + async def search_global_roots_in_tenant( + self, + query_vector: Optional[List[float]], + sparse_query_vector: Optional[Dict[str, float]] = None, + context_type: Optional[str] = None, + target_directories: Optional[List[str]] = None, + extra_filter: Optional[FilterExpr | Dict[str, Any]] = None, + limit: int = 10, + ) -> List[Dict[str, Any]]: + return await self._manager.search_global_roots_in_tenant( + self._ctx, + query_vector=query_vector, + sparse_query_vector=sparse_query_vector, + context_type=context_type, + target_directories=target_directories, + extra_filter=extra_filter, + limit=limit, + ) + + async def search_children_in_tenant( + self, + parent_uri: str, + query_vector: Optional[List[float]], + sparse_query_vector: Optional[Dict[str, float]] = None, + context_type: Optional[str] = None, + target_directories: Optional[List[str]] = None, + extra_filter: Optional[FilterExpr | Dict[str, Any]] = None, + limit: int = 10, + ) -> List[Dict[str, Any]]: + return await self._manager.search_children_in_tenant( + self._ctx, + parent_uri=parent_uri, + query_vector=query_vector, + sparse_query_vector=sparse_query_vector, + context_type=context_type, + target_directories=target_directories, + extra_filter=extra_filter, + limit=limit, + ) + + async def search_similar_memories( + self, + owner_space: Optional[str], + category_uri_prefix: str, + query_vector: List[float], + limit: int = 5, + ) -> List[Dict[str, Any]]: + return await self._manager.search_similar_memories( + owner_space=owner_space, + category_uri_prefix=category_uri_prefix, + query_vector=query_vector, + limit=limit, + ctx=self._ctx, + ) + + async def get_context_by_uri( + self, + uri: str, + owner_space: Optional[str] = None, + level: Optional[int] = None, + limit: int = 1, + ) -> List[Dict[str, Any]]: + return await self._manager.get_context_by_uri( + uri=uri, + owner_space=owner_space, + level=level, + limit=limit, + ctx=self._ctx, + ) + + async def delete_account_data(self, account_id: str) -> int: + return await self._manager.delete_account_data(account_id, ctx=self._ctx) + + async def delete_uris(self, uris: List[str]) -> None: + return await self._manager.delete_uris(self._ctx, uris) + + async def update_uri_mapping( + self, + uri: str, + new_uri: str, + new_parent_uri: str, + ) -> bool: + return await self._manager.update_uri_mapping( + self._ctx, + uri=uri, + new_uri=new_uri, + new_parent_uri=new_parent_uri, + ) + + async def increment_active_count(self, uris: List[str]) -> int: + return await self._manager.increment_active_count(self._ctx, uris) diff --git a/openviking/sync_client.py b/openviking/sync_client.py index 149c29c8..bb98cf20 100644 --- a/openviking/sync_client.py +++ b/openviking/sync_client.py @@ -12,6 +12,7 @@ from openviking.session import Session from openviking.async_client import AsyncOpenViking +from openviking.telemetry import TelemetryRequest from openviking_cli.utils import run_async @@ -73,9 +74,11 @@ def add_message( """ return run_async(self._async_client.add_message(session_id, role, content, parts)) - def commit_session(self, session_id: str) -> Dict[str, Any]: + def commit_session( + self, session_id: str, telemetry: TelemetryRequest = False + ) -> Dict[str, Any]: """Commit a session (archive and extract memories).""" - return run_async(self._async_client.commit_session(session_id)) + return run_async(self._async_client.commit_session(session_id, telemetry=telemetry)) def add_resource( self, @@ -88,6 +91,7 @@ def add_resource( timeout: float = None, build_index: bool = True, summarize: bool = False, + telemetry: TelemetryRequest = False, **kwargs, ) -> Dict[str, Any]: """Add resource to OpenViking (resources scope only) @@ -98,6 +102,8 @@ def add_resource( **kwargs: Extra options forwarded to the parser chain, e.g. ``strict``, ``ignore_dirs``, ``include``, ``exclude``. """ + if to and parent: + raise ValueError("Cannot specify both 'to' and 'parent' at the same time.") return run_async( self._async_client.add_resource( path=path, @@ -109,6 +115,7 @@ def add_resource( timeout=timeout, build_index=build_index, summarize=summarize, + telemetry=telemetry, **kwargs, ) ) @@ -118,9 +125,12 @@ def add_skill( data: Any, wait: bool = False, timeout: float = None, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add skill to OpenViking.""" - return run_async(self._async_client.add_skill(data, wait=wait, timeout=timeout)) + return run_async( + self._async_client.add_skill(data, wait=wait, timeout=timeout, telemetry=telemetry) + ) def search( self, @@ -131,11 +141,12 @@ def search( limit: int = 10, score_threshold: Optional[float] = None, filter: Optional[Dict] = None, + telemetry: TelemetryRequest = False, ): """Execute complex retrieval (intent analysis, hierarchical retrieval).""" return run_async( self._async_client.search( - query, target_uri, session, session_id, limit, score_threshold, filter + query, target_uri, session, session_id, limit, score_threshold, filter, telemetry ) ) @@ -145,9 +156,20 @@ def find( target_uri: str = "", limit: int = 10, score_threshold: Optional[float] = None, + filter: Optional[Dict] = None, + telemetry: TelemetryRequest = False, ): """Quick retrieval""" - return run_async(self._async_client.find(query, target_uri, limit, score_threshold)) + return run_async( + self._async_client.find( + query, + target_uri, + limit, + score_threshold, + filter, + telemetry, + ) + ) def abstract(self, uri: str) -> str: """Read L0 abstract""" diff --git a/openviking/telemetry/__init__.py b/openviking/telemetry/__init__.py new file mode 100644 index 00000000..985beda4 --- /dev/null +++ b/openviking/telemetry/__init__.py @@ -0,0 +1,24 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""OpenViking telemetry runtime and operation telemetry helpers.""" + +from .context import bind_telemetry, get_current_telemetry +from .operation import OperationTelemetry, TelemetrySnapshot +from .registry import register_telemetry, resolve_telemetry, unregister_telemetry +from .request import TelemetryRequest, TelemetrySelection, normalize_telemetry_request +from .runtime import get_telemetry_runtime, set_telemetry_runtime + +__all__ = [ + "OperationTelemetry", + "TelemetryRequest", + "TelemetrySelection", + "TelemetrySnapshot", + "bind_telemetry", + "get_current_telemetry", + "get_telemetry_runtime", + "normalize_telemetry_request", + "register_telemetry", + "resolve_telemetry", + "set_telemetry_runtime", + "unregister_telemetry", +] diff --git a/openviking/telemetry/backends/__init__.py b/openviking/telemetry/backends/__init__.py new file mode 100644 index 00000000..2e8ec32e --- /dev/null +++ b/openviking/telemetry/backends/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Telemetry backend exports.""" + +from .memory import MemoryOperationTelemetry + +__all__ = ["MemoryOperationTelemetry"] diff --git a/openviking/telemetry/backends/memory.py b/openviking/telemetry/backends/memory.py new file mode 100644 index 00000000..93c133f8 --- /dev/null +++ b/openviking/telemetry/backends/memory.py @@ -0,0 +1,12 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Memory telemetry backend.""" + +from openviking.telemetry.operation import OperationTelemetry + + +class MemoryOperationTelemetry(OperationTelemetry): + """In-process operation telemetry collector.""" + + +__all__ = ["MemoryOperationTelemetry"] diff --git a/openviking/telemetry/context.py b/openviking/telemetry/context.py new file mode 100644 index 00000000..1384c95b --- /dev/null +++ b/openviking/telemetry/context.py @@ -0,0 +1,35 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Telemetry context helpers.""" + +from __future__ import annotations + +import contextvars +from contextlib import contextmanager +from typing import Iterator + +from .operation import OperationTelemetry + +_NOOP_TELEMETRY = OperationTelemetry(operation="noop", enabled=False) +_CURRENT_TELEMETRY: contextvars.ContextVar[OperationTelemetry] = contextvars.ContextVar( + "openviking_operation_telemetry", + default=_NOOP_TELEMETRY, +) + + +def get_current_telemetry() -> OperationTelemetry: + """Get current operation telemetry or disabled no-op collector.""" + return _CURRENT_TELEMETRY.get() + + +@contextmanager +def bind_telemetry(handle: OperationTelemetry) -> Iterator[OperationTelemetry]: + """Bind operation telemetry to current context.""" + token = _CURRENT_TELEMETRY.set(handle) + try: + yield handle + finally: + _CURRENT_TELEMETRY.reset(token) + + +__all__ = ["bind_telemetry", "get_current_telemetry"] diff --git a/openviking/telemetry/execution.py b/openviking/telemetry/execution.py new file mode 100644 index 00000000..32bf39dc --- /dev/null +++ b/openviking/telemetry/execution.py @@ -0,0 +1,115 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Shared helpers for telemetry-wrapped operation execution.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Awaitable, Callable, Generic, Optional, TypeVar + +from openviking_cli.exceptions import InvalidArgumentError + +from .context import bind_telemetry +from .operation import OperationTelemetry +from .request import TelemetryRequest, TelemetrySelection, normalize_telemetry_request + +T = TypeVar("T") + + +@dataclass +class TelemetryExecutionResult(Generic[T]): + """Executed operation result plus telemetry payloads.""" + + result: T + telemetry: Optional[dict[str, Any]] + selection: TelemetrySelection + + +def parse_telemetry_selection(telemetry: TelemetryRequest) -> TelemetrySelection: + """Validate and normalize a telemetry request for public API usage.""" + try: + return normalize_telemetry_request(telemetry) + except ValueError as exc: + raise InvalidArgumentError(str(exc)) from exc + + +def build_telemetry_payload( + collector: OperationTelemetry, + selection: TelemetrySelection, + *, + status: str = "ok", +) -> dict[str, Any] | None: + """Build a telemetry payload from a finished collector.""" + snapshot = collector.finish(status=status) + if snapshot is None: + return None + + if not selection.include_payload: + return None + + return snapshot.to_dict( + include_summary=selection.include_summary, + ) + + +def attach_telemetry_payload( + result: Any, + telemetry_payload: Optional[dict[str, Any]], +) -> Any: + """Attach a telemetry payload to a dict result.""" + if telemetry_payload is None: + return result + + if result is None: + payload: dict[str, Any] = {} + payload["telemetry"] = telemetry_payload + return payload + + if isinstance(result, dict): + result["telemetry"] = telemetry_payload + return result + + return result + + +async def run_with_telemetry( + *, + operation: str, + telemetry: TelemetryRequest, + fn: Callable[[], Awaitable[T]], + error_status: str = "error", +) -> TelemetryExecutionResult[T]: + """Execute an async operation with a bound operation-scoped collector.""" + selection = parse_telemetry_selection(telemetry) + collector = OperationTelemetry( + operation=operation, + enabled=True, + ) + + try: + with bind_telemetry(collector): + result = await fn() + except Exception as exc: + collector.set_error(operation, type(exc).__name__, str(exc)) + collector.finish(status=error_status) + raise + + telemetry_payload = build_telemetry_payload( + collector, + selection, + status="ok", + ) + return TelemetryExecutionResult( + result=result, + telemetry=telemetry_payload, + selection=selection, + ) + + +__all__ = [ + "TelemetryExecutionResult", + "attach_telemetry_payload", + "build_telemetry_payload", + "parse_telemetry_selection", + "run_with_telemetry", +] diff --git a/openviking/telemetry/operation.py b/openviking/telemetry/operation.py new file mode 100644 index 00000000..82a20491 --- /dev/null +++ b/openviking/telemetry/operation.py @@ -0,0 +1,244 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Operation-scoped telemetry primitives.""" + +from __future__ import annotations + +import time +from collections import defaultdict +from dataclasses import dataclass +from threading import Lock +from typing import Any, Dict, Optional +from uuid import uuid4 + + +@dataclass +class TelemetrySnapshot: + """Final operation telemetry output.""" + + telemetry_id: str + summary: Dict[str, Any] + + def to_usage_dict(self) -> Dict[str, Any]: + return { + "duration_ms": self.summary.get("duration_ms", 0), + "token_total": self.summary.get("tokens", {}).get("total", 0), + } + + def to_dict( + self, + *, + include_summary: bool = True, + ) -> Dict[str, Any]: + payload: Dict[str, Any] = {"id": self.telemetry_id} + if include_summary: + payload["summary"] = self.summary + return payload + + +class TelemetrySummaryBuilder: + """Build normalized summary metrics from collector data.""" + + @staticmethod + def _i(value: Any, default: int = 0) -> int: + if value is None: + return default + try: + return int(value) + except (TypeError, ValueError): + return default + + @classmethod + def _has_metric_prefix( + cls, prefix: str, counters: Dict[str, float], gauges: Dict[str, Any] + ) -> bool: + needle = f"{prefix}." + return any(key.startswith(needle) for key in counters) or any( + key.startswith(needle) for key in gauges + ) + + @classmethod + def build( + cls, + *, + operation: str, + status: str, + duration_ms: float, + counters: Dict[str, float], + gauges: Dict[str, Any], + error_stage: str, + error_code: str, + error_message: str, + ) -> Dict[str, Any]: + llm_input_tokens = cls._i(counters.get("tokens.llm.input"), 0) + llm_output_tokens = cls._i(counters.get("tokens.llm.output"), 0) + llm_total_tokens = cls._i(counters.get("tokens.llm.total"), 0) + embedding_total_tokens = cls._i(counters.get("tokens.embedding.total"), 0) + vector_candidates_scored = cls._i(counters.get("vector.scored"), 0) + vectors_scanned = gauges.get("vector.scanned") + if vectors_scanned is None: + vectors_scanned = cls._i(counters.get("vector.scanned"), 0) + + memories_extracted = gauges.get("memory.extracted") + if memories_extracted is None and counters.get("memory.extracted") is not None: + memories_extracted = cls._i(counters.get("memory.extracted"), 0) + summary = { + "operation": operation, + "status": status, + "duration_ms": round(float(duration_ms), 3), + "tokens": { + "total": cls._i(counters.get("tokens.total"), 0), + "llm": { + "input": llm_input_tokens, + "output": llm_output_tokens, + "total": llm_total_tokens, + }, + "embedding": {"total": embedding_total_tokens}, + }, + } + + if cls._has_metric_prefix("queue", counters, gauges): + summary["queue"] = { + "semantic": { + "processed": cls._i(gauges.get("queue.semantic.processed"), 0), + "error_count": cls._i(gauges.get("queue.semantic.error_count"), 0), + }, + "embedding": { + "processed": cls._i(gauges.get("queue.embedding.processed"), 0), + "error_count": cls._i(gauges.get("queue.embedding.error_count"), 0), + }, + } + + if cls._has_metric_prefix("vector", counters, gauges): + summary["vector"] = { + "searches": cls._i(counters.get("vector.searches"), 0), + "scored": vector_candidates_scored, + "passed": cls._i(counters.get("vector.passed"), 0), + "returned": cls._i( + gauges.get("vector.returned", counters.get("vector.returned")), 0 + ), + "scanned": vectors_scanned, + "scan_reason": gauges.get("vector.scan_reason", ""), + } + + if cls._has_metric_prefix("semantic_nodes", counters, gauges): + summary["semantic_nodes"] = { + "total": gauges.get("semantic_nodes.total"), + "done": gauges.get("semantic_nodes.done"), + "pending": gauges.get("semantic_nodes.pending"), + "running": gauges.get("semantic_nodes.running"), + } + + if cls._has_metric_prefix("memory", counters, gauges): + summary["memory"] = { + "extracted": memories_extracted, + } + + if error_stage or error_code or error_message: + summary["errors"] = { + "stage": error_stage, + "error_code": error_code, + "message": error_message, + } + + return summary + + +class OperationTelemetry: + """Operation-scoped telemetry collector with low-overhead disabled mode.""" + + def __init__( + self, + operation: str, + enabled: bool = False, + ): + self.operation = operation + self.enabled = enabled + self.telemetry_id = f"tm_{uuid4().hex}" if enabled else "" + self._start_time = time.perf_counter() + self._counters: Dict[str, float] = defaultdict(float) + self._gauges: Dict[str, Any] = {} + self._error_stage = "" + self._error_code = "" + self._error_message = "" + self._lock = Lock() + + def count(self, key: str, delta: float = 1) -> None: + if not self.enabled: + return + with self._lock: + self._counters[key] += delta + + def increment(self, key: str, delta: float = 1) -> None: + self.count(key, delta) + + def set(self, key: str, value: Any) -> None: + if not self.enabled: + return + with self._lock: + self._gauges[key] = value + + def set_value(self, key: str, value: Any) -> None: + self.set(key, value) + + def add_token_usage(self, input_tokens: int, output_tokens: int) -> None: + self.add_token_usage_by_source("llm", input_tokens, output_tokens) + + def record_token_usage(self, source: str, input_tokens: int, output_tokens: int = 0) -> None: + self.add_token_usage_by_source(source, input_tokens, output_tokens) + + def add_token_usage_by_source( + self, source: str, input_tokens: int, output_tokens: int = 0 + ) -> None: + if not self.enabled: + return + + normalized_input = max(input_tokens, 0) + normalized_output = max(output_tokens, 0) + normalized_total = normalized_input + normalized_output + + self.count("tokens.input", normalized_input) + self.count("tokens.output", normalized_output) + self.count("tokens.total", normalized_total) + self.count(f"tokens.{source}.input", normalized_input) + self.count(f"tokens.{source}.output", normalized_output) + self.count(f"tokens.{source}.total", normalized_total) + + def set_error(self, stage: str, code: str, message: str) -> None: + if not self.enabled: + return + with self._lock: + self._error_stage = stage + self._error_code = code + self._error_message = message + + def record_error(self, stage: str, code: str, message: str) -> None: + self.set_error(stage, code, message) + + def finish(self, status: str = "ok") -> Optional[TelemetrySnapshot]: + if not self.enabled: + return None + + duration_ms = (time.perf_counter() - self._start_time) * 1000 + with self._lock: + summary = TelemetrySummaryBuilder.build( + operation=self.operation, + status=status, + duration_ms=duration_ms, + counters=dict(self._counters), + gauges=dict(self._gauges), + error_stage=self._error_stage, + error_code=self._error_code, + error_message=self._error_message, + ) + return TelemetrySnapshot( + telemetry_id=self.telemetry_id, + summary=summary, + ) + + +__all__ = [ + "OperationTelemetry", + "TelemetrySnapshot", + "TelemetrySummaryBuilder", +] diff --git a/openviking/telemetry/registry.py b/openviking/telemetry/registry.py new file mode 100644 index 00000000..8cd7b018 --- /dev/null +++ b/openviking/telemetry/registry.py @@ -0,0 +1,36 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Telemetry registry helpers.""" + +from __future__ import annotations + +import threading + +from .operation import OperationTelemetry + +_REGISTERED_TELEMETRY: dict[str, OperationTelemetry] = {} +_REGISTERED_TELEMETRY_LOCK = threading.Lock() + + +def register_telemetry(handle: OperationTelemetry) -> None: + if not handle.enabled or not handle.telemetry_id: + return + with _REGISTERED_TELEMETRY_LOCK: + _REGISTERED_TELEMETRY[handle.telemetry_id] = handle + + +def resolve_telemetry(telemetry_id: str) -> OperationTelemetry | None: + if not telemetry_id: + return None + with _REGISTERED_TELEMETRY_LOCK: + return _REGISTERED_TELEMETRY.get(telemetry_id) + + +def unregister_telemetry(telemetry_id: str) -> None: + if not telemetry_id: + return + with _REGISTERED_TELEMETRY_LOCK: + _REGISTERED_TELEMETRY.pop(telemetry_id, None) + + +__all__ = ["register_telemetry", "resolve_telemetry", "unregister_telemetry"] diff --git a/openviking/telemetry/request.py b/openviking/telemetry/request.py new file mode 100644 index 00000000..87e26c1a --- /dev/null +++ b/openviking/telemetry/request.py @@ -0,0 +1,49 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Telemetry request parsing helpers.""" + +from __future__ import annotations + +from collections.abc import Mapping +from dataclasses import dataclass +from typing import Any, TypeAlias + +TelemetryRequest: TypeAlias = bool | dict[str, bool] + +_ALLOWED_TELEMETRY_KEYS = frozenset({"summary"}) + + +@dataclass(frozen=True) +class TelemetrySelection: + """Normalized telemetry payload selection.""" + + include_summary: bool + + @property + def include_payload(self) -> bool: + return self.include_summary + + +def normalize_telemetry_request( + request: TelemetryRequest | Mapping[str, Any] | None, +) -> TelemetrySelection: + """Normalize a telemetry request into explicit response selection flags.""" + if request is None or request is False: + return TelemetrySelection(include_summary=False) + if request is True: + return TelemetrySelection(include_summary=True) + if not isinstance(request, Mapping): + raise ValueError("telemetry must be a boolean or an object") + + unknown_keys = set(request) - _ALLOWED_TELEMETRY_KEYS + if unknown_keys: + joined = ", ".join(sorted(unknown_keys)) + raise ValueError(f"Unsupported telemetry options: {joined}") + + include_summary = request.get("summary", True) + if not isinstance(include_summary, bool): + raise ValueError("telemetry.summary must be a boolean") + return TelemetrySelection(include_summary=include_summary) + + +__all__ = ["TelemetryRequest", "TelemetrySelection", "normalize_telemetry_request"] diff --git a/openviking/telemetry/resource_summary.py b/openviking/telemetry/resource_summary.py new file mode 100644 index 00000000..c578c270 --- /dev/null +++ b/openviking/telemetry/resource_summary.py @@ -0,0 +1,132 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Resource-specific telemetry summary helpers.""" + +from __future__ import annotations + +from typing import Any, Dict + +from .context import get_current_telemetry +from .operation import OperationTelemetry +from .registry import register_telemetry, unregister_telemetry + + +def _consume_semantic_request_stats(telemetry_id: str): + try: + from openviking.storage.queuefs.semantic_processor import SemanticProcessor + + return SemanticProcessor.consume_request_stats(telemetry_id) + except Exception: + return None + + +def _consume_embedding_request_stats(telemetry_id: str): + try: + from openviking.storage.collection_schemas import TextEmbeddingHandler + + return TextEmbeddingHandler.consume_request_stats(telemetry_id) + except Exception: + return None + + +def _consume_semantic_dag_stats(telemetry_id: str, root_uri: str | None): + try: + from openviking.storage.queuefs.semantic_processor import SemanticProcessor + + return SemanticProcessor.consume_dag_stats(telemetry_id=telemetry_id, uri=root_uri) + except Exception: + return None + + +def register_wait_telemetry(wait: bool) -> str: + """Register current telemetry collector for async queue consumers when needed.""" + handle = get_current_telemetry() + if not wait or not handle.enabled: + return "" + register_telemetry(handle) + return handle.telemetry_id + + +def unregister_wait_telemetry(telemetry_id: str) -> None: + """Unregister request-scoped telemetry handle.""" + unregister_telemetry(telemetry_id) + + +def build_queue_status_payload(status: Dict[str, Any]) -> Dict[str, Dict[str, Any]]: + """Convert queue status objects to response payload format.""" + return { + name: { + "processed": s.processed, + "error_count": s.error_count, + "errors": [{"message": e.message} for e in s.errors], + } + for name, s in status.items() + } + + +def _resolve_queue_group( + *, + explicit_stats: Any, + fallback_status: Any, +) -> Dict[str, int]: + if explicit_stats is not None: + return { + "processed": explicit_stats.processed, + "error_count": explicit_stats.error_count, + } + if fallback_status is None: + return {"processed": 0, "error_count": 0} + return { + "processed": fallback_status.processed, + "error_count": fallback_status.error_count, + } + + +def record_resource_wait_metrics( + *, + telemetry: OperationTelemetry | None = None, + telemetry_id: str, + queue_status: Dict[str, Any], + root_uri: str | None, +) -> Dict[str, Dict[str, int]]: + """Apply queue and DAG metrics to a resource operation collector.""" + telemetry = telemetry or get_current_telemetry() + if not telemetry.enabled: + return { + "semantic": {"processed": 0, "error_count": 0}, + "embedding": {"processed": 0, "error_count": 0}, + } + + semantic = _resolve_queue_group( + explicit_stats=_consume_semantic_request_stats(telemetry_id), + fallback_status=queue_status.get("Semantic"), + ) + embedding = _resolve_queue_group( + explicit_stats=_consume_embedding_request_stats(telemetry_id), + fallback_status=queue_status.get("Embedding"), + ) + + telemetry.set("queue.semantic.processed", semantic["processed"]) + telemetry.set("queue.semantic.error_count", semantic["error_count"]) + telemetry.set("queue.embedding.processed", embedding["processed"]) + telemetry.set("queue.embedding.error_count", embedding["error_count"]) + + dag_stats = _consume_semantic_dag_stats(telemetry_id, root_uri) + if dag_stats is not None: + telemetry.set("semantic_nodes.total", dag_stats.total_nodes) + telemetry.set("semantic_nodes.done", dag_stats.done_nodes) + telemetry.set("semantic_nodes.pending", dag_stats.pending_nodes) + telemetry.set("semantic_nodes.running", dag_stats.in_progress_nodes) + + return { + "semantic": semantic, + "embedding": embedding, + } + + +__all__ = [ + "build_queue_status_payload", + "record_resource_wait_metrics", + "register_wait_telemetry", + "unregister_wait_telemetry", +] diff --git a/openviking/telemetry/runtime.py b/openviking/telemetry/runtime.py new file mode 100644 index 00000000..f6b6db5d --- /dev/null +++ b/openviking/telemetry/runtime.py @@ -0,0 +1,79 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Telemetry runtime entrypoints.""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from threading import Lock +from typing import Any, Dict, Tuple + + +class MemoryTelemetryMeter: + """Lightweight in-process telemetry meter. + + This is intentionally simple for now; it provides the global telemetry hook + points required by the design without forcing immediate broad adoption. + """ + + def __init__(self): + self._counters: Dict[Tuple[str, Tuple[Tuple[str, Any], ...]], float] = {} + self._gauges: Dict[Tuple[str, Tuple[Tuple[str, Any], ...]], Any] = {} + self._histograms: Dict[Tuple[str, Tuple[Tuple[str, Any], ...]], list[float]] = {} + self._lock = Lock() + + @staticmethod + def _key(metric: str, attrs: Dict[str, Any] | None) -> Tuple[str, Tuple[Tuple[str, Any], ...]]: + normalized = tuple(sorted((attrs or {}).items())) + return metric, normalized + + def increment(self, metric: str, value: float = 1, attrs: Dict[str, Any] | None = None) -> None: + key = self._key(metric, attrs) + with self._lock: + self._counters[key] = self._counters.get(key, 0) + value + + def record_histogram( + self, metric: str, value: float, attrs: Dict[str, Any] | None = None + ) -> None: + key = self._key(metric, attrs) + with self._lock: + self._histograms.setdefault(key, []).append(value) + + def set_gauge(self, metric: str, value: Any, attrs: Dict[str, Any] | None = None) -> None: + key = self._key(metric, attrs) + with self._lock: + self._gauges[key] = value + + def record_event( + self, name: str, attrs: Dict[str, Any] | None = None, scope: str | None = None + ) -> None: + # Event capture is intentionally disabled for summary-only telemetry. + _ = (name, attrs, scope) + + +@dataclass +class TelemetryRuntime: + meter_instance: MemoryTelemetryMeter = field(default_factory=MemoryTelemetryMeter) + + def meter(self) -> MemoryTelemetryMeter: + return self.meter_instance + + +_RUNTIME = TelemetryRuntime() + + +def get_telemetry_runtime() -> TelemetryRuntime: + return _RUNTIME + + +def set_telemetry_runtime(runtime: TelemetryRuntime) -> None: + global _RUNTIME + _RUNTIME = runtime + + +__all__ = [ + "MemoryTelemetryMeter", + "TelemetryRuntime", + "get_telemetry_runtime", + "set_telemetry_runtime", +] diff --git a/openviking/telemetry/snapshot.py b/openviking/telemetry/snapshot.py new file mode 100644 index 00000000..ed775512 --- /dev/null +++ b/openviking/telemetry/snapshot.py @@ -0,0 +1,7 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Telemetry snapshot model.""" + +from .operation import TelemetrySnapshot + +__all__ = ["TelemetrySnapshot"] diff --git a/openviking/utils/agfs_utils.py b/openviking/utils/agfs_utils.py index 511cf2d0..8db073d9 100644 --- a/openviking/utils/agfs_utils.py +++ b/openviking/utils/agfs_utils.py @@ -99,6 +99,10 @@ def mount_agfs_backend(agfs: Any, agfs_config: Any) -> None: local_dir = plugin_config["config"]["local_dir"] os.makedirs(local_dir, exist_ok=True) logger.debug(f"[AGFSUtils] Ensured local directory exists: {local_dir}") + # Ensure queuefs db_path parent directory exists before mounting + if plugin_name == "queuefs" and "db_path" in plugin_config.get("config", {}): + db_path = plugin_config["config"]["db_path"] + os.makedirs(os.path.dirname(db_path), exist_ok=True) try: agfs.unmount(mount_path) diff --git a/openviking/utils/embedding_utils.py b/openviking/utils/embedding_utils.py index 1dffc1c8..9a2f9d2d 100644 --- a/openviking/utils/embedding_utils.py +++ b/openviking/utils/embedding_utils.py @@ -20,6 +20,22 @@ logger = get_logger(__name__) +async def _decrement_embedding_tracker(semantic_msg_id: Optional[str], count: int) -> None: + if not semantic_msg_id or count <= 0: + return + try: + from openviking.storage.queuefs.embedding_tracker import EmbeddingTaskTracker + + tracker = EmbeddingTaskTracker.get_instance() + for _ in range(count): + await tracker.decrement(semantic_msg_id) + except Exception as e: + logger.error( + f"Failed to decrement embedding tracker for semantic_msg_id={semantic_msg_id}: {e}", + exc_info=True, + ) + + def _owner_space_for_uri(uri: str, ctx: RequestContext) -> str: """Derive owner_space from a URI.""" if uri.startswith("viking://agent/"): @@ -116,57 +132,78 @@ async def vectorize_directory_meta( overview: str, context_type: str = "resource", ctx: Optional[RequestContext] = None, + semantic_msg_id: Optional[str] = None, ) -> None: """ Vectorize directory metadata (.abstract.md and .overview.md). Creates Context objects for abstract and overview and enqueues them. """ - if not ctx: - logger.warning("No context provided for vectorization") - return + enqueued = 0 + try: + if not ctx: + logger.warning("No context provided for vectorization") + return - queue_manager = get_queue_manager() - embedding_queue = queue_manager.get_queue(queue_manager.EMBEDDING) - - parent_uri = VikingURI(uri).parent.uri - owner_space = _owner_space_for_uri(uri, ctx) - - # Vectorize L0: .abstract.md (abstract) - context_abstract = Context( - uri=uri, - parent_uri=parent_uri, - is_leaf=False, - abstract=abstract, - context_type=context_type, - level=ContextLevel.ABSTRACT, - user=ctx.user, - account_id=ctx.account_id, - owner_space=owner_space, - ) - context_abstract.set_vectorize(Vectorize(text=abstract)) - msg_abstract = EmbeddingMsgConverter.from_context(context_abstract) - if msg_abstract: - await embedding_queue.enqueue(msg_abstract) - logger.debug(f"Enqueued directory L0 (abstract) for vectorization: {uri}") - - # Vectorize L1: .overview.md (overview) - context_overview = Context( - uri=uri, - parent_uri=parent_uri, - is_leaf=False, - abstract=abstract, - context_type=context_type, - level=ContextLevel.OVERVIEW, - user=ctx.user, - account_id=ctx.account_id, - owner_space=owner_space, - ) - context_overview.set_vectorize(Vectorize(text=overview)) - msg_overview = EmbeddingMsgConverter.from_context(context_overview) - if msg_overview: - await embedding_queue.enqueue(msg_overview) - logger.debug(f"Enqueued directory L1 (overview) for vectorization: {uri}") + queue_manager = get_queue_manager() + embedding_queue = queue_manager.get_queue(queue_manager.EMBEDDING) + + parent_uri = VikingURI(uri).parent.uri + owner_space = _owner_space_for_uri(uri, ctx) + + # Vectorize L0: .abstract.md (abstract) + context_abstract = Context( + uri=uri, + parent_uri=parent_uri, + is_leaf=False, + abstract=abstract, + context_type=context_type, + level=ContextLevel.ABSTRACT, + user=ctx.user, + account_id=ctx.account_id, + owner_space=owner_space, + ) + context_abstract.set_vectorize(Vectorize(text=abstract)) + msg_abstract = EmbeddingMsgConverter.from_context(context_abstract) + if msg_abstract: + msg_abstract.semantic_msg_id = semantic_msg_id + try: + await embedding_queue.enqueue(msg_abstract) + enqueued += 1 + logger.debug(f"Enqueued directory L0 (abstract) for vectorization: {uri}") + except Exception as e: + logger.error( + f"Failed to enqueue directory L0 (abstract) for vectorization: {uri}: {e}", + exc_info=True, + ) + + # Vectorize L1: .overview.md (overview) + context_overview = Context( + uri=uri, + parent_uri=parent_uri, + is_leaf=False, + abstract=abstract, + context_type=context_type, + level=ContextLevel.OVERVIEW, + user=ctx.user, + account_id=ctx.account_id, + owner_space=owner_space, + ) + context_overview.set_vectorize(Vectorize(text=overview)) + msg_overview = EmbeddingMsgConverter.from_context(context_overview) + if msg_overview: + msg_overview.semantic_msg_id = semantic_msg_id + try: + await embedding_queue.enqueue(msg_overview) + enqueued += 1 + logger.debug(f"Enqueued directory L1 (overview) for vectorization: {uri}") + except Exception as e: + logger.error( + f"Failed to enqueue directory L1 (overview) for vectorization: {uri}: {e}", + exc_info=True, + ) + finally: + await _decrement_embedding_tracker(semantic_msg_id, 2 - enqueued) async def vectorize_file( @@ -175,6 +212,7 @@ async def vectorize_file( parent_uri: str, context_type: str = "resource", ctx: Optional[RequestContext] = None, + semantic_msg_id: Optional[str] = None, ) -> None: """ Vectorize a single file. @@ -182,15 +220,17 @@ async def vectorize_file( Creates Context object for the file and enqueues it. Reads content for TEXT files, otherwise uses summary. """ - if not ctx: - logger.warning("No context provided for vectorization") - return - - queue_manager = get_queue_manager() - embedding_queue = queue_manager.get_queue(queue_manager.EMBEDDING) - viking_fs = get_viking_fs() + enqueued = False try: + if not ctx: + logger.warning("No context provided for vectorization") + return + + queue_manager = get_queue_manager() + embedding_queue = queue_manager.get_queue(queue_manager.EMBEDDING) + viking_fs = get_viking_fs() + file_name = summary_dict.get("name") or os.path.basename(file_path) summary = summary_dict.get("summary", "") @@ -246,11 +286,16 @@ async def vectorize_file( if not embedding_msg: return + embedding_msg.semantic_msg_id = semantic_msg_id await embedding_queue.enqueue(embedding_msg) + enqueued = True logger.debug(f"Enqueued file for vectorization: {file_path}") except Exception as e: logger.error(f"Failed to vectorize file {file_path}: {e}", exc_info=True) + finally: + if not enqueued: + await _decrement_embedding_tracker(semantic_msg_id, 1) async def index_resource( diff --git a/openviking/utils/process_lock.py b/openviking/utils/process_lock.py new file mode 100644 index 00000000..854f624f --- /dev/null +++ b/openviking/utils/process_lock.py @@ -0,0 +1,102 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""PID-based advisory lock for data directory exclusivity. + +Prevents multiple OpenViking processes from contending for the same data +directory, which causes silent failures in AGFS and VectorDB. +""" + +import atexit +import os +import signal + +from openviking_cli.utils import get_logger + +logger = get_logger(__name__) + +LOCK_FILENAME = ".openviking.pid" + + +class DataDirectoryLocked(RuntimeError): + """Raised when another OpenViking process holds the data directory lock.""" + + +def _read_pid_file(lock_path: str) -> int: + """Read PID from lock file. Returns 0 if unreadable.""" + try: + with open(lock_path) as f: + return int(f.read().strip()) + except (OSError, ValueError): + return 0 + + +def _is_pid_alive(pid: int) -> bool: + """Check whether a process with the given PID is still running.""" + if pid <= 0: + return False + try: + os.kill(pid, 0) + return True + except ProcessLookupError: + return False + except PermissionError: + # Process exists but we can't signal it. + return True + + +def acquire_data_dir_lock(data_dir: str) -> str: + """Acquire an advisory PID lock on *data_dir*. + + Returns the path to the lock file on success. + + Raises ``DataDirectoryLocked`` if another live process already holds the + lock, with a message that explains the situation and suggests HTTP mode. + """ + lock_path = os.path.join(data_dir, LOCK_FILENAME) + my_pid = os.getpid() + + existing_pid = _read_pid_file(lock_path) + if existing_pid and existing_pid != my_pid and _is_pid_alive(existing_pid): + raise DataDirectoryLocked( + f"Another OpenViking process (PID {existing_pid}) is already using " + f"the data directory '{data_dir}'. Running multiple OpenViking " + f"instances on the same data directory causes silent storage " + f"contention and data corruption.\n\n" + f"To fix this, use one of these approaches:\n" + f" 1. Use HTTP mode: start a single openviking-server and connect " + f"via --transport http (recommended for multi-session hosts)\n" + f" 2. Use separate data directories for each instance\n" + f" 3. Stop the other process (PID {existing_pid}) first" + ) + + # Write our PID (overwrites stale lock from a dead process). + try: + os.makedirs(data_dir, exist_ok=True) + with open(lock_path, "w") as f: + f.write(str(my_pid)) + except OSError as exc: + logger.warning("Could not write PID lock %s: %s", lock_path, exc) + return lock_path + + # Schedule cleanup on exit. + def _cleanup(*_args: object) -> None: + try: + if os.path.isfile(lock_path): + stored = _read_pid_file(lock_path) + if stored == my_pid: + os.remove(lock_path) + except OSError: + pass + + atexit.register(_cleanup) + # Also try to clean up on SIGTERM (graceful shutdown). + try: + signal.signal( + signal.SIGTERM, lambda sig, frame: (_cleanup(), signal.default_int_handler(sig, frame)) + ) + except (OSError, ValueError): + # signal.signal() can fail in non-main threads. + pass + + logger.debug("Acquired data directory lock: %s (PID %d)", lock_path, my_pid) + return lock_path diff --git a/openviking/utils/resource_processor.py b/openviking/utils/resource_processor.py index c43ea541..172fcd33 100644 --- a/openviking/utils/resource_processor.py +++ b/openviking/utils/resource_processor.py @@ -7,12 +7,15 @@ as described in the OpenViking design document. """ +import asyncio +import time from typing import TYPE_CHECKING, Any, Dict, List, Optional from openviking.parse.tree_builder import TreeBuilder from openviking.server.identity import RequestContext from openviking.storage import VikingDBManager from openviking.storage.viking_fs import get_viking_fs +from openviking.telemetry import get_current_telemetry from openviking.utils.embedding_utils import index_resource from openviking.utils.summarizer import Summarizer from openviking_cli.utils import get_logger @@ -119,9 +122,11 @@ async def process_resource( "errors": [], "source_path": None, } + telemetry = get_current_telemetry() - # ============ Phase 1: Parse source (Parser generates L0/L1 and writes to temp) ============ + # ============ Phase 1: Parse source and writes to temp viking fs ============ try: + parse_start = time.perf_counter() media_processor = self._get_media_processor() viking_fs = get_viking_fs() # Use reason as instruction fallback so it influences L0/L1 @@ -149,10 +154,17 @@ async def process_resource( if parse_result.warnings: result["errors"].extend(parse_result.warnings) + telemetry.set( + "resource.parse.duration_ms", + round((time.perf_counter() - parse_start) * 1000, 3), + ) + telemetry.set("resource.parse.warnings_count", len(parse_result.warnings or [])) + except Exception as e: result["status"] = "error" result["errors"].append(f"Parse error: {e}") logger.error(f"[ResourceProcessor] Parse error: {e}") + telemetry.set_error("resource_processor.parse", "PROCESSING_ERROR", str(e)) import traceback traceback.print_exc() @@ -163,9 +175,9 @@ async def process_resource( # - temp_dir_path: Temporary directory path (Parser wrote all files) # - source_path, source_format - # ============ Phase 2: Pass to and parent directly to TreeBuilder ============ # ============ Phase 3: TreeBuilder finalizes from temp (scan + move to AGFS) ============ try: + finalize_start = time.perf_counter() with get_viking_fs().bind_request_context(ctx): context_tree = await self.tree_builder.finalize_from_temp( temp_dir_path=parse_result.temp_dir_path, @@ -178,9 +190,15 @@ async def process_resource( ) if context_tree and context_tree.root: result["root_uri"] = context_tree.root.uri + result["temp_uri"] = context_tree.root.temp_uri + telemetry.set( + "resource.finalize.duration_ms", + round((time.perf_counter() - finalize_start) * 1000, 3), + ) except Exception as e: result["status"] = "error" result["errors"].append(f"Finalize from temp error: {e}") + telemetry.set_error("resource_processor.finalize", "PROCESSING_ERROR", str(e)) # Cleanup temporary directory on error (via VikingFS) try: @@ -191,33 +209,89 @@ async def process_resource( return result + # ============ Phase 3.5: 首次添加立即落盘 + 生命周期锁 ============ + root_uri = result.get("root_uri") + temp_uri = result.get("temp_uri") # temp_doc_uri + candidate_uri = getattr(context_tree, "_candidate_uri", None) if context_tree else None + lifecycle_lock_handle_id = "" + + if root_uri and temp_uri: + from openviking.storage.transaction import LockContext, get_lock_manager + + viking_fs = get_viking_fs() + lock_manager = get_lock_manager() + target_exists = await viking_fs.exists(root_uri, ctx=ctx) + + if not target_exists: + # 第一次添加:锁保护下将 temp 移到 final + dst_path = viking_fs._uri_to_path(root_uri, ctx=ctx) + parent_path = dst_path.rsplit("/", 1)[0] if "/" in dst_path else dst_path + + parent_uri = "/".join(root_uri.rsplit("/", 1)[:-1]) + if parent_uri: + await viking_fs.mkdir(parent_uri, exist_ok=True, ctx=ctx) + + async with LockContext(lock_manager, [parent_path], lock_mode="point"): + if candidate_uri: + root_uri = await self.tree_builder._resolve_unique_uri(candidate_uri) + result["root_uri"] = root_uri + dst_path = viking_fs._uri_to_path(root_uri, ctx=ctx) + + src_path = viking_fs._uri_to_path(temp_uri, ctx=ctx) + await asyncio.to_thread(viking_fs.agfs.mv, src_path, dst_path) + + # 在 POINT 锁内获取 SUBTREE 锁(消除竞态窗口) + lifecycle_lock_handle_id = await self._try_acquire_lifecycle_lock( + lock_manager, dst_path + ) + + try: + await viking_fs.delete_temp(parse_result.temp_dir_path, ctx=ctx) + except Exception: + pass + + result["temp_uri"] = root_uri + else: + # 增量更新:对目标目录加 SUBTREE 锁 + resource_path = viking_fs._uri_to_path(root_uri, ctx=ctx) + lifecycle_lock_handle_id = await self._try_acquire_lifecycle_lock( + lock_manager, resource_path + ) + # ============ Phase 4: Optional Steps ============ build_index = kwargs.get("build_index", True) - if summarize: - # Explicit summarization request. - # If build_index is ALSO True, we want vectorization. - # If build_index is False, we skip vectorization. + temp_uri_for_summarize = result.get("temp_uri") or parse_result.temp_dir_path + should_summarize = summarize or build_index + if should_summarize: skip_vec = not build_index try: await self._get_summarizer().summarize( resource_uris=[result["root_uri"]], ctx=ctx, skip_vectorization=skip_vec, + lifecycle_lock_handle_id=lifecycle_lock_handle_id, + temp_uris=[temp_uri_for_summarize], **kwargs, ) except Exception as e: logger.error(f"Summarization failed: {e}") result["warnings"] = result.get("warnings", []) + [f"Summarization failed: {e}"] + elif lifecycle_lock_handle_id: + # 无下游处理接管锁,主动释放 + from openviking.storage.transaction import get_lock_manager - elif build_index: - # Standard compatibility mode: "Just Index it" usually implies ingestion flow. - # We assume this means "Ingest and Index", which requires summarization. - try: - await self._get_summarizer().summarize( - resource_uris=[result["root_uri"]], ctx=ctx, skip_vectorization=False, **kwargs - ) - except Exception as e: - logger.error(f"Auto-index failed: {e}") - result["warnings"] = result.get("warnings", []) + [f"Auto-index failed: {e}"] + handle = get_lock_manager().get_handle(lifecycle_lock_handle_id) + if handle: + await get_lock_manager().release(handle) return result + + @staticmethod + async def _try_acquire_lifecycle_lock(lock_manager, path: str) -> str: + """尝试获取 SUBTREE 生命周期锁,失败时优雅降级返回空字符串。""" + handle = lock_manager.create_handle() + if await lock_manager.acquire_subtree(handle, path): + return handle.id + logger.warning(f"[ResourceProcessor] Failed to acquire lifecycle lock on {path}") + await lock_manager.release(handle) + return "" diff --git a/openviking/utils/skill_processor.py b/openviking/utils/skill_processor.py index 1d6e93f7..1aed2d0d 100644 --- a/openviking/utils/skill_processor.py +++ b/openviking/utils/skill_processor.py @@ -7,6 +7,7 @@ """ import tempfile +import time import zipfile from pathlib import Path from typing import Any, Dict, List, Optional @@ -18,6 +19,7 @@ from openviking.storage import VikingDBManager from openviking.storage.queuefs.embedding_msg_converter import EmbeddingMsgConverter from openviking.storage.viking_fs import VikingFS +from openviking.telemetry import get_current_telemetry from openviking_cli.utils import get_logger from openviking_cli.utils.config import get_openviking_config @@ -62,8 +64,13 @@ async def process_skill( raise ValueError("Skill data cannot be None") config = get_openviking_config() + telemetry = get_current_telemetry() + parse_start = time.perf_counter() skill_dict, auxiliary_files, base_path = self._parse_skill(data) + telemetry.set( + "skill.parse.duration_ms", round((time.perf_counter() - parse_start) * 1000, 3) + ) context = Context( uri=f"viking://agent/skills/{skill_dict['name']}", @@ -84,10 +91,16 @@ async def process_skill( ) context.set_vectorize(Vectorize(text=context.abstract)) + overview_start = time.perf_counter() overview = await self._generate_overview(skill_dict, config) + telemetry.set( + "skill.overview.duration_ms", + round((time.perf_counter() - overview_start) * 1000, 3), + ) skill_dir_uri = f"viking://agent/skills/{context.meta['name']}" + write_start = time.perf_counter() await self._write_skill_content( viking_fs=viking_fs, skill_dict=skill_dict, @@ -103,12 +116,18 @@ async def process_skill( skill_dir_uri=skill_dir_uri, ctx=ctx, ) + telemetry.set( + "skill.write.duration_ms", round((time.perf_counter() - write_start) * 1000, 3) + ) + index_start = time.perf_counter() await self._index_skill( context=context, skill_dir_uri=skill_dir_uri, ) - + telemetry.set( + "skill.index.duration_ms", round((time.perf_counter() - index_start) * 1000, 3) + ) return { "status": "success", "uri": skill_dir_uri, diff --git a/openviking/utils/summarizer.py b/openviking/utils/summarizer.py index a7477ba3..e9a1cb20 100644 --- a/openviking/utils/summarizer.py +++ b/openviking/utils/summarizer.py @@ -1,18 +1,19 @@ # Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. # SPDX-License-Identifier: Apache-2.0 -""" -Summarizer for OpenViking. +"""Summarizer for OpenViking. Handles summarization and key information extraction. """ -from typing import TYPE_CHECKING, Any, Dict, List, Optional -from openviking_cli.utils import get_logger +from typing import TYPE_CHECKING, Any, Dict, List + from openviking.storage.queuefs import SemanticMsg, get_queue_manager +from openviking.telemetry import get_current_telemetry +from openviking_cli.utils import get_logger if TYPE_CHECKING: - from openviking.server.identity import RequestContext from openviking.parse.vlm import VLMProcessor + from openviking.server.identity import RequestContext logger = get_logger(__name__) @@ -30,6 +31,7 @@ async def summarize( resource_uris: List[str], ctx: "RequestContext", skip_vectorization: bool = False, + lifecycle_lock_handle_id: str = "", **kwargs, ) -> Dict[str, Any]: """ @@ -39,8 +41,21 @@ async def summarize( queue_manager = get_queue_manager() semantic_queue = queue_manager.get_queue(queue_manager.SEMANTIC, allow_create=True) + temp_uris = kwargs.get("temp_uris", []) + if not temp_uris: + temp_uris = resource_uris + if len(temp_uris) != len(resource_uris): + logger.error( + f"temp_uris length ({len(temp_uris)}) must match resource_uris length ({len(resource_uris)})" + ) + return { + "status": "error", + "message": "temp_uris length must match resource_uris length", + } enqueued_count = 0 - for uri in resource_uris: + + telemetry = get_current_telemetry() + for uri, temp_uri in zip(resource_uris, temp_uris): # Determine context_type based on URI context_type = "resource" if uri.startswith("viking://memory/"): @@ -49,13 +64,16 @@ async def summarize( context_type = "skill" msg = SemanticMsg( - uri=uri, + uri=temp_uri, context_type=context_type, account_id=ctx.account_id, user_id=ctx.user.user_id, agent_id=ctx.user.agent_id, role=ctx.role.value, skip_vectorization=skip_vectorization, + telemetry_id=telemetry.telemetry_id if telemetry.enabled else "", + target_uri=uri if uri != temp_uri else None, + lifecycle_lock_handle_id=lifecycle_lock_handle_id, ) await semantic_queue.enqueue(msg) enqueued_count += 1 diff --git a/openviking_cli/client/base.py b/openviking_cli/client/base.py index ddc9dc70..972072d4 100644 --- a/openviking_cli/client/base.py +++ b/openviking_cli/client/base.py @@ -8,6 +8,8 @@ from abc import ABC, abstractmethod from typing import Any, Dict, List, Optional, Union +from openviking.telemetry import TelemetryRequest + class BaseClient(ABC): """Abstract base class for OpenViking clients. @@ -39,6 +41,8 @@ async def add_resource( instruction: str = "", wait: bool = False, timeout: Optional[float] = None, + watch_interval: float = 0, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add resource to OpenViking.""" @@ -48,6 +52,7 @@ async def add_skill( data: Any, wait: bool = False, timeout: Optional[float] = None, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add skill to OpenViking.""" ... @@ -138,6 +143,7 @@ async def find( limit: int = 10, score_threshold: Optional[float] = None, filter: Optional[Dict] = None, + telemetry: TelemetryRequest = False, ) -> Any: """Semantic search without session context.""" ... @@ -151,6 +157,7 @@ async def search( limit: int = 10, score_threshold: Optional[float] = None, filter: Optional[Dict] = None, + telemetry: TelemetryRequest = False, ) -> Any: """Semantic search with optional session context.""" ... @@ -205,7 +212,9 @@ async def delete_session(self, session_id: str) -> None: ... @abstractmethod - async def commit_session(self, session_id: str) -> Dict[str, Any]: + async def commit_session( + self, session_id: str, telemetry: TelemetryRequest = False + ) -> Dict[str, Any]: """Commit a session (archive and extract memories).""" ... diff --git a/openviking_cli/client/http.py b/openviking_cli/client/http.py index a7e6b354..5b0689bd 100644 --- a/openviking_cli/client/http.py +++ b/openviking_cli/client/http.py @@ -13,6 +13,7 @@ import httpx +from openviking.telemetry import TelemetryRequest, normalize_telemetry_request from openviking_cli.client.base import BaseClient from openviking_cli.exceptions import ( AlreadyExistsError, @@ -196,8 +197,8 @@ async def close(self) -> None: # ============= Internal Helpers ============= - def _handle_response(self, response: httpx.Response) -> Any: - """Handle HTTP response and extract result or raise exception.""" + def _handle_response_data(self, response: httpx.Response) -> Dict[str, Any]: + """Handle HTTP response and return the decoded response envelope.""" try: data = response.json() except Exception: @@ -206,7 +207,7 @@ def _handle_response(self, response: httpx.Response) -> Any: f"HTTP {response.status_code}: {response.text or 'empty response'}", code="INTERNAL", ) - return None + return {} if data.get("status") == "error": self._raise_exception(data.get("error", {})) if not response.is_success: @@ -214,7 +215,33 @@ def _handle_response(self, response: httpx.Response) -> Any: data.get("detail", f"HTTP {response.status_code}"), code="UNKNOWN", ) - return data.get("result") + return data + + def _handle_response(self, response: httpx.Response) -> Any: + """Handle HTTP response and extract result or raise exception.""" + return self._handle_response_data(response).get("result") + + @staticmethod + def _validate_telemetry(telemetry: TelemetryRequest) -> TelemetryRequest: + normalize_telemetry_request(telemetry) + return telemetry + + @staticmethod + def _attach_telemetry(result: Any, response_data: Dict[str, Any]) -> Any: + telemetry = response_data.get("telemetry") + if telemetry is None: + return result + + if result is None: + payload: Dict[str, Any] = {} + payload["telemetry"] = telemetry + return payload + + if isinstance(result, dict): + result["telemetry"] = telemetry + return result + + return result def _raise_exception(self, error: Dict[str, Any]) -> None: """Raise appropriate exception based on error code.""" @@ -263,6 +290,7 @@ def _zip_directory(self, dir_path: str) -> str: for file_path in dir_path.rglob("*"): if file_path.is_file(): arcname = file_path.relative_to(dir_path) + arcname = str(arcname).replace("\\", "/") zipf.write(file_path, arcname=arcname) return str(zip_path) @@ -295,9 +323,10 @@ async def add_resource( exclude: Optional[str] = None, directly_upload_media: bool = True, preserve_structure: Optional[bool] = None, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add resource to OpenViking.""" - # Validate that only one of 'to' or 'parent' is set + telemetry = self._validate_telemetry(telemetry) if to and parent: raise ValueError("Cannot specify both 'to' and 'parent' at the same time.") @@ -313,6 +342,7 @@ async def add_resource( "include": include, "exclude": exclude, "directly_upload_media": directly_upload_media, + "telemetry": telemetry, } if preserve_structure is not None: request_data["preserve_structure"] = preserve_structure @@ -338,15 +368,18 @@ async def add_resource( "/api/v1/resources", json=request_data, ) - return self._handle_response(response) + response_data = self._handle_response_data(response) + return self._attach_telemetry(response_data.get("result"), response_data) async def add_skill( self, data: Any, wait: bool = False, timeout: Optional[float] = None, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add skill to OpenViking.""" + telemetry = self._validate_telemetry(telemetry) request_data = { "wait": wait, "timeout": timeout, @@ -374,9 +407,10 @@ async def add_skill( response = await self._http.post( "/api/v1/skills", - json=request_data, + json={**request_data, "telemetry": telemetry}, ) - return self._handle_response(response) + response_data = self._handle_response_data(response) + return self._attach_telemetry(response_data.get("result"), response_data) async def wait_processed(self, timeout: Optional[float] = None) -> Dict[str, Any]: """Wait for all processing to complete.""" @@ -521,8 +555,10 @@ async def find( node_limit: Optional[int] = None, score_threshold: Optional[float] = None, filter: Optional[Dict[str, Any]] = None, + telemetry: TelemetryRequest = False, ) -> FindResult: """Semantic search without session context.""" + telemetry = self._validate_telemetry(telemetry) if target_uri: target_uri = VikingURI.normalize(target_uri) actual_limit = node_limit if node_limit is not None else limit @@ -534,9 +570,11 @@ async def find( "limit": actual_limit, "score_threshold": score_threshold, "filter": filter, + "telemetry": telemetry, }, ) - return FindResult.from_dict(self._handle_response(response)) + response_data = self._handle_response_data(response) + return FindResult.from_dict(response_data.get("result") or {}) async def search( self, @@ -548,8 +586,10 @@ async def search( node_limit: Optional[int] = None, score_threshold: Optional[float] = None, filter: Optional[Dict[str, Any]] = None, + telemetry: TelemetryRequest = False, ) -> FindResult: """Semantic search with optional session context.""" + telemetry = self._validate_telemetry(telemetry) if target_uri: target_uri = VikingURI.normalize(target_uri) actual_limit = node_limit if node_limit is not None else limit @@ -563,9 +603,11 @@ async def search( "limit": actual_limit, "score_threshold": score_threshold, "filter": filter, + "telemetry": telemetry, }, ) - return FindResult.from_dict(self._handle_response(response)) + response_data = self._handle_response_data(response) + return FindResult.from_dict(response_data.get("result") or {}) async def grep( self, @@ -658,10 +700,17 @@ async def delete_session(self, session_id: str) -> None: response = await self._http.delete(f"/api/v1/sessions/{session_id}") self._handle_response(response) - async def commit_session(self, session_id: str) -> Dict[str, Any]: + async def commit_session( + self, session_id: str, telemetry: TelemetryRequest = False + ) -> Dict[str, Any]: """Commit a session (archive and extract memories).""" - response = await self._http.post(f"/api/v1/sessions/{session_id}/commit") - return self._handle_response(response) + telemetry = self._validate_telemetry(telemetry) + response = await self._http.post( + f"/api/v1/sessions/{session_id}/commit", + json={"telemetry": telemetry}, + ) + response_data = self._handle_response_data(response) + return self._attach_telemetry(response_data.get("result"), response_data) async def add_message( self, diff --git a/openviking_cli/client/sync_http.py b/openviking_cli/client/sync_http.py index 1a735d82..503c26ab 100644 --- a/openviking_cli/client/sync_http.py +++ b/openviking_cli/client/sync_http.py @@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional, Union +from openviking.telemetry import TelemetryRequest from openviking_cli.client.http import AsyncHTTPClient from openviking_cli.utils import run_async @@ -105,9 +106,11 @@ def add_message( """ return run_async(self._async_client.add_message(session_id, role, content, parts)) - def commit_session(self, session_id: str) -> Dict[str, Any]: + def commit_session( + self, session_id: str, telemetry: TelemetryRequest = False + ) -> Dict[str, Any]: """Commit a session (archive and extract memories).""" - return run_async(self._async_client.commit_session(session_id)) + return run_async(self._async_client.commit_session(session_id, telemetry=telemetry)) # ============= Resource ============= @@ -125,8 +128,11 @@ def add_resource( include: Optional[str] = None, exclude: Optional[str] = None, directly_upload_media: bool = True, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add resource to OpenViking.""" + if to and parent: + raise ValueError("Cannot specify both 'to' and 'parent' at the same time.") return run_async( self._async_client.add_resource( path, @@ -141,6 +147,7 @@ def add_resource( include, exclude, directly_upload_media, + telemetry=telemetry, ) ) @@ -149,9 +156,12 @@ def add_skill( data: Any, wait: bool = False, timeout: Optional[float] = None, + telemetry: TelemetryRequest = False, ) -> Dict[str, Any]: """Add skill to OpenViking.""" - return run_async(self._async_client.add_skill(data, wait=wait, timeout=timeout)) + return run_async( + self._async_client.add_skill(data, wait=wait, timeout=timeout, telemetry=telemetry) + ) def wait_processed(self, timeout: Optional[float] = None) -> Dict[str, Any]: """Wait for all processing to complete.""" @@ -169,6 +179,7 @@ def search( node_limit: Optional[int] = None, score_threshold: Optional[float] = None, filter: Optional[Dict] = None, + telemetry: TelemetryRequest = False, ): """Semantic search with optional session context.""" return run_async( @@ -181,6 +192,7 @@ def search( node_limit=node_limit, score_threshold=score_threshold, filter=filter, + telemetry=telemetry, ) ) @@ -192,10 +204,19 @@ def find( node_limit: Optional[int] = None, score_threshold: Optional[float] = None, filter: Optional[Dict] = None, + telemetry: TelemetryRequest = False, ): """Semantic search without session context.""" return run_async( - self._async_client.find(query, target_uri, limit, node_limit, score_threshold, filter) + self._async_client.find( + query, + target_uri, + limit, + node_limit, + score_threshold, + filter, + telemetry=telemetry, + ) ) def grep( diff --git a/openviking_cli/exceptions.py b/openviking_cli/exceptions.py index 807d317e..cd432552 100644 --- a/openviking_cli/exceptions.py +++ b/openviking_cli/exceptions.py @@ -70,6 +70,14 @@ def __init__(self, resource: str, resource_type: str = "resource"): ) +class ConflictError(OpenVikingError): + """Resource conflict (e.g., locked by another operation).""" + + def __init__(self, message: str, resource: Optional[str] = None): + details = {"resource": resource} if resource else {} + super().__init__(message, code="CONFLICT", details=details) + + # ============= Authentication Errors ============= diff --git a/openviking_cli/session/user_id.py b/openviking_cli/session/user_id.py index cd959e16..490f4dff 100644 --- a/openviking_cli/session/user_id.py +++ b/openviking_cli/session/user_id.py @@ -51,7 +51,7 @@ def user_space_name(self) -> str: def agent_space_name(self) -> str: """Agent-level space name (user + agent).""" - return hashlib.md5((self._user_id + self._agent_id).encode()).hexdigest()[:12] + return hashlib.md5(f"{self._user_id}:{self._agent_id}".encode()).hexdigest()[:12] def memory_space_uri(self) -> str: return f"viking://agent/{self.agent_space_name()}/memories" diff --git a/openviking_cli/utils/config/embedding_config.py b/openviking_cli/utils/config/embedding_config.py index 2d4f1164..3f504d40 100644 --- a/openviking_cli/utils/config/embedding_config.py +++ b/openviking_cli/utils/config/embedding_config.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. # SPDX-License-Identifier: Apache-2.0 -from typing import Any, Optional +from typing import Any, Optional, cast from pydantic import BaseModel, Field, model_validator @@ -14,19 +14,55 @@ class EmbeddingModelConfig(BaseModel): dimension: Optional[int] = Field(default=None, description="Embedding dimension") batch_size: int = Field(default=32, description="Batch size for embedding generation") input: str = Field(default="multimodal", description="Input type: 'text' or 'multimodal'") + query_param: Optional[str] = Field( + default=None, + description=( + "Parameter value for query-side embeddings when calling embed(is_query=True). " + "For OpenAI-compatible models, this maps to 'input_type' (e.g., 'query', 'search_query'). " + "For Jina models, this maps to 'task' (e.g., 'retrieval.query'). " + "Setting this or document_param activates non-symmetric mode. " + "Leave both unset for symmetric models." + ), + ) + document_param: Optional[str] = Field( + default=None, + description=( + "Parameter value for document-side embeddings when calling embed(is_query=False). " + "For OpenAI-compatible models, this maps to 'input_type' (e.g., 'passage', 'document'). " + "For Jina models, this maps to 'task' (e.g., 'retrieval.passage'). " + "Setting this or query_param activates non-symmetric mode. " + "Leave both unset for symmetric models." + ), + ) provider: Optional[str] = Field( default="volcengine", - description="Provider type: 'openai', 'volcengine', 'vikingdb', 'jina'", + description=( + "Provider type: 'openai', 'volcengine', 'vikingdb', 'jina', 'ollama', 'voyage'. " + "For OpenRouter or other OpenAI-compatible providers, use 'openai' with " + "api_base and extra_headers." + ), ) backend: Optional[str] = Field( default="volcengine", - description="Backend type (Deprecated, use 'provider' instead): 'openai', 'volcengine', 'vikingdb'", + description="Backend type (Deprecated, use 'provider' instead): 'openai', 'volcengine', 'vikingdb', 'voyage'", ) version: Optional[str] = Field(default=None, description="Model version") ak: Optional[str] = Field(default=None, description="Access Key ID for VikingDB API") sk: Optional[str] = Field(default=None, description="Access Key Secretfor VikingDB API") region: Optional[str] = Field(default=None, description="Region for VikingDB API") host: Optional[str] = Field(default=None, description="Host for VikingDB API") + max_tokens: Optional[int] = Field( + default=None, + description="Maximum token count per embedding request. If None, uses model default (e.g., 8000 for OpenAI).", + ) + extra_headers: Optional[dict[str, str]] = Field( + default=None, + description=( + "Extra HTTP headers for API requests. Passed as default_headers to the OpenAI client. " + "Useful for OpenRouter (e.g., {'HTTP-Referer': '...', 'X-Title': '...'}) " + "or other OpenAI-compatible providers that require custom headers." + ), + ) model_config = {"extra": "forbid"} @@ -39,6 +75,10 @@ def sync_provider_backend(cls, data: Any) -> Any: if backend is not None and provider is None: data["provider"] = backend + for key in ("query_param", "document_param"): + value = data.get(key) + if isinstance(value, str): + data[key] = value.lower() return data @model_validator(mode="after") @@ -53,16 +93,22 @@ def validate_config(self): if not self.provider: raise ValueError("Embedding provider is required") - if self.provider not in ["openai", "volcengine", "vikingdb", "jina"]: + if self.provider not in ["openai", "volcengine", "vikingdb", "jina", "ollama", "voyage"]: raise ValueError( - f"Invalid embedding provider: '{self.provider}'. Must be one of: 'openai', 'volcengine', 'vikingdb', 'jina'" + f"Invalid embedding provider: '{self.provider}'. Must be one of: " + "'openai', 'volcengine', 'vikingdb', 'jina', 'ollama', 'voyage'" ) # Provider-specific validation if self.provider == "openai": - if not self.api_key: + # Allow missing api_key when api_base is set (e.g. local OpenAI-compatible servers) + if not self.api_key and not self.api_base: raise ValueError("OpenAI provider requires 'api_key' to be set") + elif self.provider == "ollama": + # Ollama runs locally, no API key required + pass + elif self.provider == "volcengine": if not self.api_key: raise ValueError("Volcengine provider requires 'api_key' to be set") @@ -85,8 +131,27 @@ def validate_config(self): if not self.api_key: raise ValueError("Jina provider requires 'api_key' to be set") + elif self.provider == "voyage": + if not self.api_key: + raise ValueError("Voyage provider requires 'api_key' to be set") + return self + def get_effective_dimension(self) -> int: + """Resolve the dimension used for schema creation and validation.""" + if self.dimension is not None: + return self.dimension + + provider = (self.provider or "").lower() + if provider == "voyage": + from openviking.models.embedder.voyage_embedders import ( + get_voyage_model_default_dimension, + ) + + return get_voyage_model_default_dimension(self.model) + + return 2048 + class EmbeddingConfig(BaseModel): """ @@ -119,11 +184,16 @@ def validate_config(self): ) return self - def _create_embedder(self, provider: str, embedder_type: str, config: EmbeddingModelConfig): + def _create_embedder( + self, + provider: str, + embedder_type: str, + config: EmbeddingModelConfig, + ): """Factory method to create embedder instance based on provider and type. Args: - provider: Provider type ('openai', 'volcengine', 'vikingdb') + provider: Provider type ('openai', 'volcengine', 'vikingdb', 'jina', 'ollama', 'voyage') embedder_type: Embedder type ('dense', 'sparse', 'hybrid') config: EmbeddingModelConfig instance @@ -142,6 +212,7 @@ def _create_embedder(self, provider: str, embedder_type: str, config: EmbeddingM VolcengineDenseEmbedder, VolcengineHybridEmbedder, VolcengineSparseEmbedder, + VoyageDenseEmbedder, ) # Factory registry: (provider, type) -> (embedder_class, param_builder) @@ -150,9 +221,14 @@ def _create_embedder(self, provider: str, embedder_type: str, config: EmbeddingM OpenAIDenseEmbedder, lambda cfg: { "model_name": cfg.model, - "api_key": cfg.api_key, + "api_key": cfg.api_key + or "no-key", # Placeholder for local OpenAI-compatible servers "api_base": cfg.api_base, "dimension": cfg.dimension, + **({"query_param": cfg.query_param} if cfg.query_param else {}), + **({"document_param": cfg.document_param} if cfg.document_param else {}), + "max_tokens": cfg.max_tokens, + **({"extra_headers": cfg.extra_headers} if cfg.extra_headers else {}), }, ), ("volcengine", "dense"): ( @@ -222,6 +298,29 @@ def _create_embedder(self, provider: str, embedder_type: str, config: EmbeddingM ), ("jina", "dense"): ( JinaDenseEmbedder, + lambda cfg: { + "model_name": cfg.model, + "api_key": cfg.api_key, + "api_base": cfg.api_base, + "dimension": cfg.dimension, + **({"query_param": cfg.query_param} if cfg.query_param else {}), + **({"document_param": cfg.document_param} if cfg.document_param else {}), + }, + ), + # Ollama: local OpenAI-compatible embedding server, no real API key needed + ("ollama", "dense"): ( + OpenAIDenseEmbedder, + lambda cfg: { + "model_name": cfg.model, + "api_key": cfg.api_key + or "no-key", # Ollama ignores the key, but client requires non-empty + "api_base": cfg.api_base or "http://localhost:11434/v1", + "dimension": cfg.dimension, + "max_tokens": cfg.max_tokens, + }, + ), + ("voyage", "dense"): ( + VoyageDenseEmbedder, lambda cfg: { "model_name": cfg.model, "api_key": cfg.api_key, @@ -252,19 +351,27 @@ def get_embedder(self): ValueError: If configuration is invalid or unsupported """ from openviking.models.embedder import CompositeHybridEmbedder + from openviking.models.embedder.base import DenseEmbedderBase, SparseEmbedderBase if self.hybrid: - return self._create_embedder(self.hybrid.provider.lower(), "hybrid", self.hybrid) + provider = self._require_provider(self.hybrid.provider) + return self._create_embedder(provider, "hybrid", self.hybrid) if self.dense and self.sparse: - dense_embedder = self._create_embedder(self.dense.provider.lower(), "dense", self.dense) + dense_provider = self._require_provider(self.dense.provider) + dense_embedder = cast( + DenseEmbedderBase, + self._create_embedder(dense_provider, "dense", self.dense), + ) sparse_embedder = self._create_embedder( - self.sparse.provider.lower(), "sparse", self.sparse + self._require_provider(self.sparse.provider), "sparse", self.sparse ) + sparse_embedder = cast(SparseEmbedderBase, sparse_embedder) return CompositeHybridEmbedder(dense_embedder, sparse_embedder) if self.dense: - return self._create_embedder(self.dense.provider.lower(), "dense", self.dense) + provider = self._require_provider(self.dense.provider) + return self._create_embedder(provider, "dense", self.dense) raise ValueError("No embedding configuration found (dense, sparse, or hybrid)") @@ -276,7 +383,13 @@ def dimension(self) -> int: def get_dimension(self) -> int: """Helper to get dimension from active config""" if self.hybrid: - return self.hybrid.dimension or 2048 + return self.hybrid.get_effective_dimension() if self.dense: - return self.dense.dimension or 2048 + return self.dense.get_effective_dimension() return 2048 + + @staticmethod + def _require_provider(provider: Optional[str]) -> str: + if not provider: + raise ValueError("Embedding provider is required") + return provider.lower() diff --git a/openviking_cli/utils/config/open_viking_config.py b/openviking_cli/utils/config/open_viking_config.py index 9745f017..50338929 100644 --- a/openviking_cli/utils/config/open_viking_config.py +++ b/openviking_cli/utils/config/open_viking_config.py @@ -26,6 +26,7 @@ ImageConfig, MarkdownConfig, PDFConfig, + SemanticConfig, TextConfig, VideoConfig, ) @@ -94,6 +95,11 @@ class OpenVikingConfig(BaseModel): default_factory=lambda: DirectoryConfig(), description="Directory parsing configuration" ) + semantic: SemanticConfig = Field( + default_factory=lambda: SemanticConfig(), + description="Semantic processing configuration (overview/abstract limits)", + ) + auto_generate_l0: bool = Field( default=True, description="Automatically generate L0 (abstract) if not provided" ) @@ -352,7 +358,7 @@ def initialize_openviking_config( config.storage.vectordb.backend = config.storage.vectordb.backend or "local" # Resolve and update workspace + dependent paths (model_validator won't # re-run on attribute assignment, so sync agfs.path / vectordb.path here). - workspace_path = Path(path).resolve() + workspace_path = Path(path).expanduser().resolve() workspace_path.mkdir(parents=True, exist_ok=True) resolved = str(workspace_path) config.storage.workspace = resolved diff --git a/openviking_cli/utils/config/parser_config.py b/openviking_cli/utils/config/parser_config.py index 2ec28f73..c8ff46aa 100644 --- a/openviking_cli/utils/config/parser_config.py +++ b/openviking_cli/utils/config/parser_config.py @@ -480,6 +480,32 @@ class DirectoryConfig(ParserConfig): preserve_structure: bool = True +@dataclass +class SemanticConfig: + """ + Configuration for semantic processing (overview/abstract generation). + + Controls prompt budget limits and output size constraints for the + SemanticProcessor pipeline. + """ + + max_file_content_chars: int = 30000 + """Maximum characters of file content sent to LLM for summary generation.""" + + max_overview_prompt_chars: int = 60000 + """Maximum characters allowed in the overview generation prompt. + If exceeded, file summaries are batched and merged.""" + + overview_batch_size: int = 50 + """Maximum number of file summaries per batch when splitting oversized prompts.""" + + abstract_max_chars: int = 256 + """Maximum characters for generated abstracts.""" + + overview_max_chars: int = 4000 + """Maximum characters for generated overviews.""" + + # Configuration registry for dynamic loading PARSER_CONFIG_REGISTRY = { "pdf": PDFConfig, diff --git a/openviking_cli/utils/config/storage_config.py b/openviking_cli/utils/config/storage_config.py index 8daf6a79..739c1af6 100644 --- a/openviking_cli/utils/config/storage_config.py +++ b/openviking_cli/utils/config/storage_config.py @@ -8,6 +8,7 @@ from openviking_cli.utils.logger import get_logger from .agfs_config import AGFSConfig +from .transaction_config import TransactionConfig from .vectordb_config import VectorDBBackendConfig logger = get_logger(__name__) @@ -25,6 +26,11 @@ class StorageConfig(BaseModel): agfs: AGFSConfig = Field(default_factory=lambda: AGFSConfig(), description="AGFS configuration") + transaction: TransactionConfig = Field( + default_factory=lambda: TransactionConfig(), + description="Transaction mechanism configuration", + ) + vectordb: VectorDBBackendConfig = Field( default_factory=lambda: VectorDBBackendConfig(), description="VectorDB backend configuration", @@ -50,8 +56,8 @@ def resolve_paths(self): f"Using '{self.workspace}' from workspace instead of '{self.vectordb.path}'" ) - # Update paths to use workspace - workspace_path = Path(self.workspace).resolve() + # Update paths to use workspace (expand ~ first) + workspace_path = Path(self.workspace).expanduser().resolve() workspace_path.mkdir(parents=True, exist_ok=True) self.workspace = str(workspace_path) self.agfs.path = self.workspace @@ -65,7 +71,7 @@ def get_upload_temp_dir(self) -> Path: Returns: Path to {workspace}/temp/upload directory """ - workspace_path = Path(self.workspace).resolve() + workspace_path = Path(self.workspace).expanduser().resolve() upload_temp_dir = workspace_path / "temp" / "upload" upload_temp_dir.mkdir(parents=True, exist_ok=True) return upload_temp_dir diff --git a/openviking_cli/utils/config/transaction_config.py b/openviking_cli/utils/config/transaction_config.py new file mode 100644 index 00000000..86d153f8 --- /dev/null +++ b/openviking_cli/utils/config/transaction_config.py @@ -0,0 +1,32 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +from pydantic import BaseModel, Field + + +class TransactionConfig(BaseModel): + """Configuration for the transaction mechanism. + + By default, lock acquisition does not wait (``lock_timeout=0``): if a + conflicting lock is held the operation fails immediately with + ``LockAcquisitionError``. Set ``lock_timeout`` to a positive value to + allow the caller to block and retry for up to that many seconds. + """ + + lock_timeout: float = Field( + default=0.0, + description=( + "Path lock acquisition timeout (seconds). " + "0 = fail immediately if locked (default). " + "> 0 = wait/retry up to this many seconds before raising LockAcquisitionError." + ), + ) + + lock_expire: float = Field( + default=300.0, + description=( + "Stale lock expiry threshold (seconds). " + "Locks held longer than this by a crashed process are force-released." + ), + ) + + model_config = {"extra": "forbid"} diff --git a/openviking_cli/utils/config/vectordb_config.py b/openviking_cli/utils/config/vectordb_config.py index 6b77747a..aa9a0256 100644 --- a/openviking_cli/utils/config/vectordb_config.py +++ b/openviking_cli/utils/config/vectordb_config.py @@ -41,6 +41,23 @@ class VikingDBConfig(BaseModel): model_config = {"extra": "forbid"} +class OceanBaseConfig(BaseModel): + """Configuration for OceanBase vector database (via pyobvector).""" + + uri: str = Field( + default="127.0.0.1:2881", + description="OceanBase connection URI (host:port)", + ) + user: str = Field( + default="root@test", + description="Database user (tenant@user for OceanBase)", + ) + password: str = Field(default="", description="Database password") + db_name: str = Field(default="test", description="Database name") + + model_config = {"extra": "forbid"} + + class VectorDBBackendConfig(BaseModel): """ Configuration for VectorDB backend. @@ -99,6 +116,12 @@ class VectorDBBackendConfig(BaseModel): description="VikingDB private deployment configuration for 'vikingdb' type", ) + # OceanBase vector database (pyobvector) + oceanbase: Optional[OceanBaseConfig] = Field( + default_factory=lambda: OceanBaseConfig(), + description="OceanBase configuration for 'oceanbase' type", + ) + custom_params: Dict[str, Any] = Field( default_factory=dict, description="Custom parameters for custom backend adapters", @@ -109,7 +132,7 @@ class VectorDBBackendConfig(BaseModel): @model_validator(mode="after") def validate_config(self): """Validate configuration completeness and consistency""" - standard_backends = ["local", "http", "volcengine", "vikingdb"] + standard_backends = ["local", "http", "volcengine", "vikingdb", "oceanbase"] # Allow custom backend classes (containing dot) without standard validation if "." in self.backend: @@ -145,4 +168,10 @@ def validate_config(self): if not self.vikingdb or not self.vikingdb.host: raise ValueError("VectorDB vikingdb backend requires 'host' to be set") + elif self.backend == "oceanbase": + if not self.oceanbase: + raise ValueError("VectorDB oceanbase backend requires 'oceanbase' config") + if not self.oceanbase.uri: + raise ValueError("VectorDB oceanbase backend requires 'oceanbase.uri' to be set") + return self diff --git a/openviking_cli/utils/config/vlm_config.py b/openviking_cli/utils/config/vlm_config.py index 4e594207..0b999ca8 100644 --- a/openviking_cli/utils/config/vlm_config.py +++ b/openviking_cli/utils/config/vlm_config.py @@ -26,12 +26,20 @@ class VLMConfig(BaseModel): default_provider: Optional[str] = Field(default=None, description="Default provider name") + max_tokens: Optional[int] = Field( + default=None, description="Maximum tokens for VLM completion output (None = provider default)" + ) + thinking: bool = Field(default=False, description="Enable thinking mode for VolcEngine models") max_concurrent: int = Field( default=100, description="Maximum number of concurrent LLM calls for semantic processing" ) + extra_headers: Optional[Dict[str, str]] = Field( + default=None, description="Extra HTTP headers for OpenAI-compatible providers" + ) + _vlm_instance: Optional[Any] = None model_config = {"arbitrary_types_allowed": True, "extra": "forbid"} @@ -68,6 +76,8 @@ def _migrate_legacy_config(self): self.providers[self.provider]["api_key"] = self.api_key if self.api_base and "api_base" not in self.providers[self.provider]: self.providers[self.provider]["api_base"] = self.api_base + if self.extra_headers and "extra_headers" not in self.providers[self.provider]: + self.providers[self.provider]["extra_headers"] = self.extra_headers def _has_any_config(self) -> bool: """Check if any config is provided.""" @@ -134,6 +144,7 @@ def _build_vlm_config_dict(self) -> Dict[str, Any]: "max_retries": self.max_retries, "provider": name, "thinking": self.thinking, + "max_tokens": self.max_tokens, } if config: @@ -148,9 +159,11 @@ def get_completion(self, prompt: str, thinking: bool = False) -> str: return self.get_vlm_instance().get_completion(prompt, thinking) async def get_completion_async( - self, prompt: str, thinking: bool = False, max_retries: int = 0 + self, prompt: str, thinking: bool = False, max_retries: int | None = None ) -> str: - """Get LLM completion asynchronously, max_retries=0 means no retry.""" + """Get LLM completion asynchronously. Uses self.max_retries if not specified.""" + if max_retries is None: + max_retries = self.max_retries return await self.get_vlm_instance().get_completion_async(prompt, thinking, max_retries) def is_available(self) -> bool: diff --git a/openviking_cli/utils/rerank.py b/openviking_cli/utils/rerank.py index fc0058ca..10192c97 100644 --- a/openviking_cli/utils/rerank.py +++ b/openviking_cli/utils/rerank.py @@ -79,7 +79,7 @@ def _prepare_request( SignerV4.sign(r, credentials) return r - def rerank_batch(self, query: str, documents: List[str]) -> List[float]: + def rerank_batch(self, query: str, documents: List[str]) -> Optional[List[float]]: """ Batch rerank documents against a query. @@ -88,7 +88,8 @@ def rerank_batch(self, query: str, documents: List[str]) -> List[float]: documents: List of document texts to rank Returns: - List of rerank scores for each document (same order as input) + List of rerank scores for each document (same order as input), + or None when rerank fails and the caller should fall back """ if not documents: return [] @@ -111,7 +112,7 @@ def rerank_batch(self, query: str, documents: List[str]) -> List[float]: response = requests.request( method=req.method, - url=f"http://{self.host}{req.path}", + url=f"https://{self.host}{req.path}", headers=req.headers, data=req.body, timeout=30, @@ -121,10 +122,17 @@ def rerank_batch(self, query: str, documents: List[str]) -> List[float]: # print(f"[RerankClient] Raw response: {result}") if "result" not in result or "data" not in result["result"]: logger.warning(f"[RerankClient] Unexpected response format: {result}") - return [0.0] * len(documents) + return None # Each document is a separate group, data array returns scores for each group sequentially data = result["result"]["data"] + if len(data) != len(documents): + logger.warning( + "[RerankClient] Unexpected rerank result length: expected=%s actual=%s", + len(documents), + len(data), + ) + return None scores = [item.get("score", 0.0) for item in data] logger.debug(f"[RerankClient] Reranked {len(documents)} documents") @@ -132,7 +140,7 @@ def rerank_batch(self, query: str, documents: List[str]) -> List[float]: except Exception as e: logger.error(f"[RerankClient] Rerank failed: {e}") - return [0.0] * len(documents) + return None @classmethod def from_config(cls, config) -> Optional["RerankClient"]: diff --git a/pyproject.toml b/pyproject.toml index 1eb0bc16..2a2918f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,11 +13,11 @@ name = "openviking" dynamic = ["version"] description = "An Agent-native context database" readme = "README.md" +requires-python = ">=3.10" authors = [ {name = "ByteDance", email = "noreply@bytedance.com"} ] license = { text = "Apache-2.0" } -requires-python = ">=3.10" classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", @@ -27,6 +27,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] dependencies = [ "pydantic>=2.0.0", @@ -39,6 +40,8 @@ dependencies = [ "openai>=1.0.0", "requests>=2.31.0", "python-docx>=1.0.0", + "olefile>=0.47", + "xlrd>=2.0.1", "python-pptx>=1.0.0", "openpyxl>=3.0.0", "ebooklib>=0.18.0", @@ -96,6 +99,17 @@ eval = [ "datasets>=2.0.0", "pandas>=2.0.0", ] +oceanbase = [ + "pyobvector>=0.2.20", +] +build = [ + "setuptools>=61.0", + "setuptools-scm>=8.0", + "pybind11>=2.13.0", + "cmake>=3.15", + "wheel", + "build", +] # vikingbot core dependencies bot = [ "pydantic-settings>=2.0.0", @@ -166,7 +180,9 @@ openviking = [ "lib/libagfsbinding.dylib", "lib/libagfsbinding.dll", "bin/ov", - "bin/ov.exe" + "bin/ov.exe", + "storage/vectordb/engine/*.so", + "storage/vectordb/engine/*.pyd", ] vikingbot = [ "**/*.mjs", @@ -229,3 +245,8 @@ quote-style = "double" indent-style = "space" skip-magic-trailing-comma = false line-ending = "auto" + +[dependency-groups] +dev = [ + "pytest>=9.0.2", +] diff --git a/setup.py b/setup.py index f91a3c42..87cc3880 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,7 @@ +import importlib import json import os +import platform import shutil import subprocess import sys @@ -10,10 +12,19 @@ from setuptools import Extension, setup from setuptools.command.build_ext import build_ext +SETUP_DIR = Path(__file__).resolve().parent +if str(SETUP_DIR) not in sys.path: + sys.path.insert(0, str(SETUP_DIR)) + +get_host_engine_build_config = importlib.import_module( + "build_support.x86_profiles" +).get_host_engine_build_config + CMAKE_PATH = shutil.which("cmake") or "cmake" C_COMPILER_PATH = shutil.which("gcc") or "gcc" CXX_COMPILER_PATH = shutil.which("g++") or "g++" ENGINE_SOURCE_DIR = "src/" +ENGINE_BUILD_CONFIG = get_host_engine_build_config(platform.machine()) class OpenVikingBuildExt(build_ext): @@ -320,6 +331,9 @@ def _build_ov_cli_artifact_impl(self, ov_cli_dir, binary_name, ov_target_binary) def build_extension(self, ext): """Build a single Python native extension artifact using CMake.""" + if getattr(self, "_engine_extensions_built", False): + return + ext_fullpath = Path(self.get_ext_fullpath(ext.name)) ext_dir = ext_fullpath.parent.resolve() build_dir = Path(self.build_temp) / "cmake_build" @@ -330,19 +344,19 @@ def build_extension(self, ext): lambda: self._build_extension_impl(ext_fullpath, ext_dir, build_dir), [(ext_fullpath, f"native extension '{ext.name}'")], ) + self._engine_extensions_built = True def _build_extension_impl(self, ext_fullpath, ext_dir, build_dir): """Invoke CMake to build the Python native extension.""" - py_output_name = ext_fullpath.stem - py_output_suffix = ext_fullpath.suffix + py_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") or ext_fullpath.suffix cmake_args = [ f"-S{Path(ENGINE_SOURCE_DIR).resolve()}", f"-B{build_dir}", "-DCMAKE_BUILD_TYPE=Release", - f"-DPY_OUTPUT_DIR={ext_dir}", - f"-DPY_OUTPUT_NAME={py_output_name}", - f"-DPY_OUTPUT_SUFFIX={py_output_suffix}", + f"-DOV_PY_OUTPUT_DIR={ext_dir}", + f"-DOV_PY_EXT_SUFFIX={py_ext_suffix}", + f"-DOV_X86_BUILD_VARIANTS={';'.join(ENGINE_BUILD_CONFIG.cmake_variants)}", "-DCMAKE_VERBOSE_MAKEFILE=ON", "-DCMAKE_INSTALL_RPATH=$ORIGIN", f"-DPython3_EXECUTABLE={sys.executable}", @@ -351,7 +365,6 @@ def _build_extension_impl(self, ext_fullpath, ext_dir, build_dir): f"-Dpybind11_DIR={pybind11.get_cmake_dir()}", f"-DCMAKE_C_COMPILER={C_COMPILER_PATH}", f"-DCMAKE_CXX_COMPILER={CXX_COMPILER_PATH}", - f"-DOV_X86_SIMD_LEVEL={os.environ.get('OV_X86_SIMD_LEVEL', 'AVX2')}", ] if sys.platform == "darwin": @@ -374,7 +387,7 @@ def _build_extension_impl(self, ext_fullpath, ext_dir, build_dir): # ], ext_modules=[ Extension( - name="openviking.storage.vectordb.engine", + name=ENGINE_BUILD_CONFIG.primary_extension, sources=[], ) ], @@ -390,6 +403,8 @@ def _build_extension_impl(self, ext_fullpath, ext_dir, build_dir): "lib/libagfsbinding.dll", "bin/ov", "bin/ov.exe", + "storage/vectordb/engine/*.so", + "storage/vectordb/engine/*.pyd", ], }, include_package_data=True, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d844427a..33b0aa5a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,73 +3,24 @@ cmake_minimum_required(VERSION 3.12) project(openviking_cpp) include(CheckCXXCompilerFlag) +include(CMakeParseArguments) -set(OV_X86_SIMD_LEVEL "AVX2" CACHE STRING "x86 SIMD level: SSE3|AVX2|AVX512|NATIVE") -set_property(CACHE OV_X86_SIMD_LEVEL PROPERTY STRINGS SSE3 AVX2 AVX512 NATIVE) +set(OV_X86_BUILD_VARIANTS "sse3;avx2;avx512" CACHE STRING "x86 engine variants to build") +set(OV_PY_OUTPUT_DIR "" CACHE PATH "Output directory for Python extension modules") +set(OV_PY_EXT_SUFFIX ".so" CACHE STRING "Python extension suffix, including ABI tag if needed") + +if(NOT OV_PY_OUTPUT_DIR) + set(OV_PY_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/python_engine") +endif() set(OV_PLATFORM_X86 OFF) if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64|i[3-6]86") set(OV_PLATFORM_X86 ON) endif() -if(OV_PLATFORM_X86) - string(TOUPPER "${OV_X86_SIMD_LEVEL}" OV_X86_SIMD_LEVEL_UPPER) - set(OV_X86_COMPILE_FLAGS) - - if(OV_X86_SIMD_LEVEL_UPPER STREQUAL "NATIVE") - check_cxx_compiler_flag("-march=native" HAVE_MARCH_NATIVE) - if(HAVE_MARCH_NATIVE) - list(APPEND OV_X86_COMPILE_FLAGS -march=native) - else() - message(WARNING "-march=native is not supported by this compiler; falling back to AVX2") - set(OV_X86_SIMD_LEVEL_UPPER "AVX2") - endif() - endif() - - if(OV_X86_SIMD_LEVEL_UPPER STREQUAL "AVX512") - foreach(FLAG -mavx512f -mavx512bw -mavx512dq -mavx512vl) - string(REPLACE "-" "_" FLAG_VAR_SUFFIX "${FLAG}") - set(FLAG_VAR "HAVE_${FLAG_VAR_SUFFIX}") - check_cxx_compiler_flag("${FLAG}" ${FLAG_VAR}) - if(NOT ${FLAG_VAR}) - message(FATAL_ERROR "Compiler does not support ${FLAG}; cannot build with OV_X86_SIMD_LEVEL=AVX512") - endif() - list(APPEND OV_X86_COMPILE_FLAGS ${FLAG}) - endforeach() - elseif(OV_X86_SIMD_LEVEL_UPPER STREQUAL "AVX2") - check_cxx_compiler_flag("-mavx2" HAVE_MAVX2) - if(HAVE_MAVX2) - list(APPEND OV_X86_COMPILE_FLAGS -mavx2) - add_compile_definitions(OV_DISABLE_AVX512=1) - foreach(FLAG -mno-avx512f -mno-avx512bw -mno-avx512dq -mno-avx512vl) - string(REPLACE "-" "_" FLAG_VAR_SUFFIX "${FLAG}") - set(FLAG_VAR "HAVE_${FLAG_VAR_SUFFIX}") - check_cxx_compiler_flag("${FLAG}" ${FLAG_VAR}) - if(${FLAG_VAR}) - list(APPEND OV_X86_COMPILE_FLAGS ${FLAG}) - endif() - endforeach() - else() - message(WARNING "Compiler does not support -mavx2; falling back to SSE3") - set(OV_X86_SIMD_LEVEL_UPPER "SSE3") - endif() - endif() - - if(OV_X86_SIMD_LEVEL_UPPER STREQUAL "SSE3") - check_cxx_compiler_flag("-msse3" HAVE_SSE3) - if(HAVE_SSE3) - list(APPEND OV_X86_COMPILE_FLAGS -msse3) - add_compile_definitions(OV_DISABLE_AVX512=1) - else() - message(FATAL_ERROR "Compiler does not support -msse3 on x86 target") - endif() - endif() - - if(OV_X86_COMPILE_FLAGS) - add_compile_options(${OV_X86_COMPILE_FLAGS}) - endif() - - message(STATUS "OpenViking x86 SIMD level: ${OV_X86_SIMD_LEVEL_UPPER}") +set(OV_PLATFORM_ARM OFF) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64|arm64") + set(OV_PLATFORM_ARM ON) endif() set(CMAKE_CXX_STANDARD 17) @@ -80,7 +31,6 @@ if(APPLE) endif() set(THREADS_PREFER_PTHREAD_FLAG ON) - set(CMAKE_STRIP FALSE) add_compile_definitions(HAVE_CXX17_HAS_INCLUDE=1) @@ -89,15 +39,11 @@ if(WIN32) endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error -Wno-deprecated-declarations -Wno-format -Wno-inconsistent-missing-override") - set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lpthread") - set(Python3_ARCH_INCLUDE_DIR "/usr/include/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/") find_package(Python3 COMPONENTS Interpreter Development REQUIRED) -# On Linux, pybind11 modules don't need to link against libpython -# This prevents issues with static libpython that wasn't built with -fPIC if(UNIX AND NOT APPLE) set(Python3_LIBRARIES "") endif() @@ -105,7 +51,6 @@ endif() find_package(pybind11 REQUIRED) find_package(Threads REQUIRED) -# Force static libraries for dependencies set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) set(SPDLOG_BUILD_SHARED OFF CACHE BOOL "" FORCE) set(LEVELDB_BUILD_TESTS OFF CACHE BOOL "" FORCE) @@ -115,17 +60,13 @@ set(SPDLOG_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(SPDLOG_BUILD_EXAMPLE OFF CACHE BOOL "" FORCE) add_subdirectory(../third_party/leveldb-1.23 ${CMAKE_BINARY_DIR}/leveldb_build) - if(TARGET leveldb) - target_compile_options(leveldb PRIVATE -fPIC) + target_compile_options(leveldb PRIVATE -fPIC) endif() add_subdirectory(../third_party/spdlog-1.14.1 ${CMAKE_BINARY_DIR}/spdlog_build) -# ARM platform detection and KRL integration -set(OV_PLATFORM_ARM OFF) -if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64|arm64") - set(OV_PLATFORM_ARM ON) +if(OV_PLATFORM_ARM) message(STATUS "Building for ARM platform with KRL support") add_subdirectory(../third_party/krl ${CMAKE_BINARY_DIR}/krl_build) endif() @@ -135,103 +76,243 @@ include_directories(../third_party/) include_directories(../third_party/leveldb-1.23/include/) include_directories(../third_party/spdlog-1.14.1/include/) -# Add KRL include directory for ARM platform if(OV_PLATFORM_ARM) include_directories(../third_party/krl/include/) endif() if(NOT DEFINED Python3_INCLUDE_DIRS) - set(Python3_INCLUDE_DIRS + set(Python3_INCLUDE_DIRS ${Python3_ARCH_INCLUDE_DIR} "/usr/include/../include/" ) endif() -file(GLOB_RECURSE ALL_SOURCES - "index/*.cpp" - "store/*.cpp" - "common/*.cpp" -) - -add_library( - engine_impl - STATIC - ${ALL_SOURCES} +set(OV_COMMON_SOURCES + common/log_utils.cpp + store/bytes_row.cpp + store/persist_store.cpp + store/volatile_store.cpp ) -target_link_libraries(engine_impl PRIVATE - Threads::Threads - leveldb +set(OV_INDEX_SOURCES + index/detail/index_manager_impl.cpp + index/detail/meta/scalar_index_meta.cpp + index/detail/meta/vector_index_meta.cpp + index/detail/scalar/bitmap_holder/bitmap.cpp + index/detail/scalar/bitmap_holder/bitmap_field_group.cpp + index/detail/scalar/bitmap_holder/dir_index.cpp + index/detail/scalar/bitmap_holder/ranged_map.cpp + index/detail/scalar/filter/filter_ops.cpp + index/detail/scalar/filter/op_base.cpp + index/detail/scalar/filter/sort_ops.cpp + index/detail/scalar/scalar_index.cpp + index/detail/vector/sparse_retrieval/sparse_datapoint.cpp + index/detail/vector/sparse_retrieval/sparse_row_index.cpp + index/index_engine.cpp ) -# Link KRL library for ARM platform -if(OV_PLATFORM_ARM) - target_link_libraries(engine_impl PRIVATE krl) -endif() +add_library(engine_common STATIC ${OV_COMMON_SOURCES}) +target_compile_options(engine_common PRIVATE -fPIC) +target_link_libraries(engine_common PUBLIC Threads::Threads leveldb) -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0") - target_link_libraries(engine_impl PRIVATE stdc++fs) +function(ov_link_filesystem_libs target_name) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0") + target_link_libraries(${target_name} PRIVATE stdc++fs) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.0") + target_link_libraries(${target_name} PRIVATE c++fs) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.0") + target_link_libraries(${target_name} PRIVATE c++fs) + endif() endif() -elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.0") - target_link_libraries(engine_impl PRIVATE c++fs) +endfunction() + +function(ov_get_x86_variant_flags variant out_flags out_defs out_supported) + string(TOLOWER "${variant}" OV_VARIANT) + set(OV_FLAGS) + set(OV_DEFS) + set(OV_SUPPORTED TRUE) + + if(OV_VARIANT STREQUAL "sse3") + check_cxx_compiler_flag("-msse3" HAVE_OV_SSE3) + if(HAVE_OV_SSE3) + list(APPEND OV_FLAGS -msse3) + list(APPEND OV_DEFS OV_DISABLE_AVX512=1) + else() + set(OV_SUPPORTED FALSE) + endif() + elseif(OV_VARIANT STREQUAL "avx2") + check_cxx_compiler_flag("-mavx2" HAVE_OV_AVX2) + if(HAVE_OV_AVX2) + list(APPEND OV_FLAGS -mavx2) + list(APPEND OV_DEFS OV_DISABLE_AVX512=1) + foreach(FLAG -mno-avx512f -mno-avx512bw -mno-avx512dq -mno-avx512vl) + string(REPLACE "-" "_" FLAG_VAR_SUFFIX "${FLAG}") + set(FLAG_VAR "HAVE_${FLAG_VAR_SUFFIX}") + check_cxx_compiler_flag("${FLAG}" ${FLAG_VAR}) + if(${FLAG_VAR}) + list(APPEND OV_FLAGS ${FLAG}) + endif() + endforeach() + else() + set(OV_SUPPORTED FALSE) + endif() + elseif(OV_VARIANT STREQUAL "avx512") + foreach(FLAG -mavx512f -mavx512bw -mavx512dq -mavx512vl) + string(REPLACE "-" "_" FLAG_VAR_SUFFIX "${FLAG}") + set(FLAG_VAR "HAVE_${FLAG_VAR_SUFFIX}") + check_cxx_compiler_flag("${FLAG}" ${FLAG_VAR}) + if(NOT ${FLAG_VAR}) + set(OV_SUPPORTED FALSE) + else() + list(APPEND OV_FLAGS ${FLAG}) + endif() + endforeach() + else() + set(OV_SUPPORTED FALSE) endif() -elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.0") - target_link_libraries(engine_impl PRIVATE c++fs) + + set(${out_flags} "${OV_FLAGS}" PARENT_SCOPE) + set(${out_defs} "${OV_DEFS}" PARENT_SCOPE) + set(${out_supported} ${OV_SUPPORTED} PARENT_SCOPE) +endfunction() + +function(ov_add_python_backend backend_suffix module_name) + set(oneValueArgs INDEX_LIBRARY) + set(multiValueArgs COMPILE_OPTIONS COMPILE_DEFINITIONS) + cmake_parse_arguments(OV_BACKEND "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(MODULE_TARGET "engine_module_${backend_suffix}") + pybind11_add_module(${MODULE_TARGET} MODULE pybind11_interface.cpp) + + target_include_directories(${MODULE_TARGET} PRIVATE ${Python3_INCLUDE_DIRS}) + target_compile_options(${MODULE_TARGET} PRIVATE -fPIC ${OV_BACKEND_COMPILE_OPTIONS}) + target_compile_definitions( + ${MODULE_TARGET} + PRIVATE + OV_PY_MODULE_NAME=${module_name} + ${OV_BACKEND_COMPILE_DEFINITIONS} + ) + target_link_libraries( + ${MODULE_TARGET} + PRIVATE + engine_common + ${OV_BACKEND_INDEX_LIBRARY} + Threads::Threads + ) + ov_link_filesystem_libs(${MODULE_TARGET}) + + if(MINGW) + target_link_libraries(${MODULE_TARGET} PRIVATE + -static-libgcc + -static-libstdc++ + -Wl,-Bstatic + -lstdc++ + -lpthread + -Wl,-Bdynamic + ) endif() -endif() -target_compile_options(engine_impl PRIVATE -fPIC) + set_target_properties( + ${MODULE_TARGET} + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${OV_PY_OUTPUT_DIR}" + RUNTIME_OUTPUT_DIRECTORY "${OV_PY_OUTPUT_DIR}" + OUTPUT_NAME "${module_name}" + SUFFIX "${OV_PY_EXT_SUFFIX}" + ) +endfunction() -pybind11_add_module( - engine - MODULE - pybind11_interface.cpp -) +set(OV_ENGINE_IMPL_TARGET "") -if(NOT DEFINED PY_OUTPUT_NAME) - set(PY_OUTPUT_NAME "engine") -endif() +if(OV_PLATFORM_X86) + set(OV_BUILT_X86_VARIANTS) -if(NOT DEFINED PY_OUTPUT_SUFFIX) - set(PY_OUTPUT_SUFFIX ".so") - if(WIN32) - set(PY_OUTPUT_SUFFIX ".pyd") - endif() -endif() + foreach(OV_VARIANT IN LISTS OV_X86_BUILD_VARIANTS) + ov_get_x86_variant_flags("${OV_VARIANT}" OV_VARIANT_FLAGS OV_VARIANT_DEFS OV_VARIANT_SUPPORTED) + if(NOT OV_VARIANT_SUPPORTED) + message(STATUS "Skipping unsupported x86 engine variant: ${OV_VARIANT}") + continue() + endif() -set_target_properties( - engine - PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${PY_OUTPUT_DIR}" - RUNTIME_OUTPUT_DIRECTORY "${PY_OUTPUT_DIR}" - SUFFIX "${PY_OUTPUT_SUFFIX}" - PYBIND11_MODULE_NAME "engine" - OUTPUT_NAME "${PY_OUTPUT_NAME}" -) + set(INDEX_TARGET "engine_index_${OV_VARIANT}") + add_library(${INDEX_TARGET} STATIC ${OV_INDEX_SOURCES}) + target_compile_options(${INDEX_TARGET} PRIVATE -fPIC ${OV_VARIANT_FLAGS}) + target_compile_definitions(${INDEX_TARGET} PRIVATE ${OV_VARIANT_DEFS}) + target_link_libraries(${INDEX_TARGET} PUBLIC Threads::Threads) + + ov_add_python_backend( + "${OV_VARIANT}" + "_x86_${OV_VARIANT}" + INDEX_LIBRARY ${INDEX_TARGET} + COMPILE_OPTIONS ${OV_VARIANT_FLAGS} + COMPILE_DEFINITIONS ${OV_VARIANT_DEFS} + ) + + list(APPEND OV_BUILT_X86_VARIANTS "${OV_VARIANT}") + endforeach() + + pybind11_add_module(engine_module_x86_caps MODULE cpu_feature_probe.cpp) + target_include_directories(engine_module_x86_caps PRIVATE ${Python3_INCLUDE_DIRS}) + set_target_properties( + engine_module_x86_caps + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${OV_PY_OUTPUT_DIR}" + RUNTIME_OUTPUT_DIRECTORY "${OV_PY_OUTPUT_DIR}" + OUTPUT_NAME "_x86_caps" + SUFFIX "${OV_PY_EXT_SUFFIX}" + ) -target_include_directories(engine PRIVATE - ${Python3_INCLUDE_DIRS} -) + if(TARGET engine_index_sse3) + add_library(engine_impl INTERFACE) + target_link_libraries(engine_impl INTERFACE engine_common engine_index_sse3 Threads::Threads) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0") + target_link_libraries(engine_impl INTERFACE stdc++fs) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.0") + target_link_libraries(engine_impl INTERFACE c++fs) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.0") + target_link_libraries(engine_impl INTERFACE c++fs) + endif() + endif() + set(OV_ENGINE_IMPL_TARGET "engine_impl") + endif() -target_link_libraries(engine PRIVATE - engine_impl - Threads::Threads -) + message(STATUS "OpenViking x86 engine variants: ${OV_BUILT_X86_VARIANTS}") +else() + add_library(engine_index_native STATIC ${OV_INDEX_SOURCES}) + target_compile_options(engine_index_native PRIVATE -fPIC) + target_link_libraries(engine_index_native PUBLIC Threads::Threads) + if(OV_PLATFORM_ARM) + target_link_libraries(engine_index_native PUBLIC krl) + endif() -if(MINGW) - target_link_libraries(engine PRIVATE - -static-libgcc - -static-libstdc++ - -Wl,-Bstatic - -lstdc++ - -lpthread - -Wl,-Bdynamic - ) -endif() + ov_add_python_backend("native" "_native" INDEX_LIBRARY engine_index_native) + + add_library(engine_impl INTERFACE) + target_link_libraries(engine_impl INTERFACE engine_common engine_index_native Threads::Threads) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0") + target_link_libraries(engine_impl INTERFACE stdc++fs) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.0") + target_link_libraries(engine_impl INTERFACE c++fs) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.0") + target_link_libraries(engine_impl INTERFACE c++fs) + endif() + endif() + set(OV_ENGINE_IMPL_TARGET "engine_impl") -if(NOT DEFINED PY_OUTPUT_DIR) - set(PY_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${PY_PACKAGE_NAME}) + message(STATUS "OpenViking native engine backend: _native") endif() diff --git a/src/cpu_feature_probe.cpp b/src/cpu_feature_probe.cpp new file mode 100644 index 00000000..f1df44f1 --- /dev/null +++ b/src/cpu_feature_probe.cpp @@ -0,0 +1,118 @@ +// Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +// SPDX-License-Identifier: Apache-2.0 +#include +#include + +#include + +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) +#if defined(_MSC_VER) +#include +#include +#else +#include +#include +#endif +#endif + +namespace py = pybind11; + +namespace { + +struct CpuFeatures { + bool sse3 = false; + bool avx = false; + bool avx2 = false; + bool avx512f = false; + bool avx512dq = false; + bool avx512bw = false; + bool avx512vl = false; +}; + +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) +void cpuid(int regs[4], int leaf, int subleaf) { +#if defined(_MSC_VER) + __cpuidex(regs, leaf, subleaf); +#else + __cpuid_count(leaf, subleaf, regs[0], regs[1], regs[2], regs[3]); +#endif +} + +unsigned long long xgetbv(unsigned int index) { +#if defined(_MSC_VER) + return _xgetbv(index); +#else + unsigned int eax = 0; + unsigned int edx = 0; + __asm__ volatile(".byte 0x0f, 0x01, 0xd0" + : "=a"(eax), "=d"(edx) + : "c"(index)); + return (static_cast(edx) << 32) | eax; +#endif +} + +CpuFeatures detect_cpu_features() { + CpuFeatures features; + int regs[4] = {0, 0, 0, 0}; + + cpuid(regs, 1, 0); + features.sse3 = (regs[2] & (1 << 0)) != 0; + const bool osxsave = (regs[2] & (1 << 27)) != 0; + const bool avx_hw = (regs[2] & (1 << 28)) != 0; + + if (!(osxsave && avx_hw)) { + return features; + } + + const auto xcr0 = xgetbv(0); + const bool avx_os = (xcr0 & 0x6) == 0x6; + if (!avx_os) { + return features; + } + + features.avx = true; + + cpuid(regs, 7, 0); + features.avx2 = (regs[1] & (1 << 5)) != 0; + features.avx512f = (regs[1] & (1 << 16)) != 0; + features.avx512dq = (regs[1] & (1 << 17)) != 0; + features.avx512bw = (regs[1] & (1 << 30)) != 0; + features.avx512vl = (regs[1] & (1u << 31)) != 0; + + const bool avx512_os = (xcr0 & 0xe6) == 0xe6; + if (!avx512_os) { + features.avx512f = false; + features.avx512dq = false; + features.avx512bw = false; + features.avx512vl = false; + } + + return features; +} +#else +CpuFeatures detect_cpu_features() { return CpuFeatures{}; } +#endif + +std::vector get_supported_variants() { + std::vector variants; + const auto features = detect_cpu_features(); + + if (features.sse3) { + variants.emplace_back("x86_sse3"); + } + if (features.avx && features.avx2) { + variants.emplace_back("x86_avx2"); + } + if (features.avx && features.avx512f && features.avx512dq && + features.avx512bw && features.avx512vl) { + variants.emplace_back("x86_avx512"); + } + return variants; +} + +} // namespace + +PYBIND11_MODULE(_x86_caps, m) { + m.def("get_supported_variants", &get_supported_variants, + "Return CPU-supported x86 engine variants"); +} diff --git a/src/pybind11_interface.cpp b/src/pybind11_interface.cpp index 55c55e2d..6533cd2f 100644 --- a/src/pybind11_interface.cpp +++ b/src/pybind11_interface.cpp @@ -15,7 +15,13 @@ namespace py = pybind11; namespace vdb = vectordb; -PYBIND11_MODULE(engine, m) { +#ifndef OV_PY_MODULE_NAME +#define OV_PY_MODULE_NAME engine +#endif + +#define OV_EXPAND_MACRO(name) name + +PYBIND11_MODULE(OV_EXPAND_MACRO(OV_PY_MODULE_NAME), m) { m.def("init_logging", &vdb::init_logging, "Initialize logging"); py::enum_(m, "FieldType") diff --git a/tests/agfs/test_fs_binding.py b/tests/agfs/test_fs_binding.py index ed8d3d33..3e76ee8f 100644 --- a/tests/agfs/test_fs_binding.py +++ b/tests/agfs/test_fs_binding.py @@ -13,6 +13,7 @@ import pytest +from openviking.storage.transaction import init_lock_manager, reset_lock_manager from openviking.storage.viking_fs import init_viking_fs from openviking_cli.utils.config.agfs_config import AGFSConfig @@ -32,16 +33,16 @@ async def viking_fs_binding_instance(): # Create AGFS client agfs_client = create_agfs_client(AGFS_CONF) - # Initialize VikingFS with client + # Initialize LockManager and VikingFS with client + init_lock_manager(agfs=agfs_client) vfs = init_viking_fs(agfs=agfs_client) # make sure default/temp directory exists await vfs.mkdir("viking://temp/", exist_ok=True) - # Ensure test directory exists - await vfs.mkdir("viking://temp/", exist_ok=True) - yield vfs + reset_lock_manager() + @pytest.mark.asyncio class TestVikingFSBindingLocal: diff --git a/tests/agfs/test_fs_binding_s3.py b/tests/agfs/test_fs_binding_s3.py index 692b869d..802d4f6d 100644 --- a/tests/agfs/test_fs_binding_s3.py +++ b/tests/agfs/test_fs_binding_s3.py @@ -13,6 +13,7 @@ import pytest +from openviking.storage.transaction import init_lock_manager, reset_lock_manager from openviking.storage.viking_fs import init_viking_fs from openviking_cli.utils.config.agfs_config import AGFSConfig @@ -57,11 +58,14 @@ async def viking_fs_binding_s3_instance(): # Create AGFS client agfs_client = create_agfs_client(AGFS_CONF) - # Initialize VikingFS with client + # Initialize LockManager and VikingFS with client + init_lock_manager(agfs=agfs_client) vfs = init_viking_fs(agfs=agfs_client) yield vfs + reset_lock_manager() + @pytest.mark.asyncio class TestVikingFSBindingS3: diff --git a/tests/agfs/test_fs_local.py b/tests/agfs/test_fs_local.py index 3a428ed6..41ef0730 100644 --- a/tests/agfs/test_fs_local.py +++ b/tests/agfs/test_fs_local.py @@ -10,6 +10,7 @@ import pytest from openviking.agfs_manager import AGFSManager +from openviking.storage.transaction import init_lock_manager, reset_lock_manager from openviking.storage.viking_fs import init_viking_fs from openviking_cli.utils.config.agfs_config import AGFSConfig @@ -39,13 +40,15 @@ async def viking_fs_instance(): # Create AGFS client agfs_client = create_agfs_client(AGFS_CONF) - # Initialize VikingFS with client + # Initialize LockManager and VikingFS with client + init_lock_manager(agfs=agfs_client) vfs = init_viking_fs(agfs=agfs_client) # make sure default/temp directory exists await vfs.mkdir("viking://temp/", exist_ok=True) yield vfs + reset_lock_manager() # AGFSManager.stop is synchronous manager.stop() diff --git a/tests/agfs/test_fs_s3.py b/tests/agfs/test_fs_s3.py index 330c7089..00504fad 100644 --- a/tests/agfs/test_fs_s3.py +++ b/tests/agfs/test_fs_s3.py @@ -13,6 +13,7 @@ import pytest from openviking.agfs_manager import AGFSManager +from openviking.storage.transaction import init_lock_manager, reset_lock_manager from openviking.storage.viking_fs import VikingFS, init_viking_fs from openviking_cli.utils.config.agfs_config import AGFSConfig @@ -46,7 +47,8 @@ def load_agfs_config() -> AGFSConfig: AGFS_CONF = load_agfs_config() -AGFS_CONF.mode = "http-client" +if AGFS_CONF is not None: + AGFS_CONF.mode = "http-client" # 2. Skip tests if no S3 config found or backend is not S3 pytestmark = pytest.mark.skipif( @@ -81,11 +83,13 @@ async def viking_fs_instance(): # Create AGFS client agfs_client = create_agfs_client(AGFS_CONF) - # Initialize VikingFS with client + # Initialize LockManager and VikingFS with client + init_lock_manager(agfs=agfs_client) vfs = init_viking_fs(agfs=agfs_client) yield vfs + reset_lock_manager() # AGFSManager.stop is synchronous manager.stop() diff --git a/tests/cli/test_user_identifier.py b/tests/cli/test_user_identifier.py new file mode 100644 index 00000000..f2523a6a --- /dev/null +++ b/tests/cli/test_user_identifier.py @@ -0,0 +1,32 @@ +"""Tests for UserIdentifier, specifically agent_space_name collision safety.""" + +from openviking_cli.session.user_id import UserIdentifier + + +class TestAgentSpaceNameCollision: + """Verify that agent_space_name uses a separator to prevent hash collisions.""" + + def test_different_pairs_produce_different_hashes(self): + """Pairs like (alice, bot) vs (aliceb, ot) must not collide.""" + u1 = UserIdentifier("acct", "alice", "bot") + u2 = UserIdentifier("acct", "aliceb", "ot") + assert u1.agent_space_name() != u2.agent_space_name() + + def test_same_pair_produces_same_hash(self): + """Same (user_id, agent_id) must always produce the same hash.""" + u1 = UserIdentifier("acct", "alice", "bot") + u2 = UserIdentifier("acct", "alice", "bot") + assert u1.agent_space_name() == u2.agent_space_name() + + def test_swapped_ids_produce_different_hashes(self): + """(user_id=a, agent_id=b) vs (user_id=b, agent_id=a) must differ.""" + u1 = UserIdentifier("acct", "alpha", "beta") + u2 = UserIdentifier("acct", "beta", "alpha") + assert u1.agent_space_name() != u2.agent_space_name() + + def test_hash_length(self): + """agent_space_name must return a 12-character hex string.""" + u = UserIdentifier("acct", "user1", "agent1") + name = u.agent_space_name() + assert len(name) == 12 + assert all(c in "0123456789abcdef" for c in name) diff --git a/tests/client/test_file_operations.py b/tests/client/test_file_operations.py index 99415f20..a402e4af 100644 --- a/tests/client/test_file_operations.py +++ b/tests/client/test_file_operations.py @@ -8,6 +8,7 @@ import pytest from openviking import AsyncOpenViking +from openviking.storage.transaction import release_all_locks class TestRm: @@ -22,6 +23,7 @@ async def test_rm_file(self, client: AsyncOpenViking, sample_markdown_file: Path reason="Test rm", ) + await release_all_locks() uris = await client.tree(result["root_uri"]) for data in uris: if not data["isDir"]: @@ -35,7 +37,8 @@ async def test_rm_directory_recursive(self, client: AsyncOpenViking, sample_dire for f in sample_directory.glob("**/*.txt"): await client.add_resource(path=str(f), reason="Test rm dir") - # Get resource directory + # Release lifecycle locks held by add_resource before rm + await release_all_locks() entries = await client.ls("viking://resources/") for data in entries: if data["isDir"]: @@ -57,6 +60,7 @@ async def test_mv_file(self, client: AsyncOpenViking, sample_markdown_file: Path ) uri = result["root_uri"] new_uri = "viking://resources/moved/" + await release_all_locks() await client.mv(uri, new_uri) # Verify original location does not exist with pytest.raises(Exception): # noqa: B017 diff --git a/tests/client/test_import_export.py b/tests/client/test_import_export.py index e4dfe3a9..2aaac8f7 100644 --- a/tests/client/test_import_export.py +++ b/tests/client/test_import_export.py @@ -10,6 +10,7 @@ import pytest from openviking import AsyncOpenViking +from openviking.storage.transaction import release_all_locks class TestExportOvpack: @@ -99,6 +100,7 @@ async def test_import_export_roundtrip( await client.export_ovpack(original_uri, str(export_path)) # Delete original resource + await release_all_locks() await client.rm(original_uri, recursive=True) # Import diff --git a/tests/client/test_resource_management.py b/tests/client/test_resource_management.py index 294ce8d4..818427fe 100644 --- a/tests/client/test_resource_management.py +++ b/tests/client/test_resource_management.py @@ -4,6 +4,7 @@ """Resource management tests""" from pathlib import Path +from unittest.mock import AsyncMock, patch from openviking import AsyncOpenViking @@ -45,13 +46,11 @@ async def test_add_resource_without_wait( observer = client.observer assert observer.queue is not None - async def test_add_resource_with_target( - self, client: AsyncOpenViking, sample_markdown_file: Path - ): + async def test_add_resource_with_to(self, client: AsyncOpenViking, sample_markdown_file: Path): """Test adding resource to specified target""" result = await client.add_resource( path=str(sample_markdown_file), - target="viking://resources/custom/", + to="viking://resources/custom/sample", reason="Test resource", ) @@ -95,3 +94,91 @@ async def test_wait_processed_multiple_resources( status = await client.wait_processed() assert isinstance(status, dict) + + +class TestWatchIntervalParameter: + """Test watch_interval parameter propagation""" + + async def test_watch_interval_default_value( + self, client: AsyncOpenViking, sample_markdown_file: Path + ): + """Test that watch_interval defaults to 0""" + with patch.object( + client._client, "add_resource", new_callable=AsyncMock + ) as mock_add_resource: + mock_add_resource.return_value = {"root_uri": "viking://test"} + + await client.add_resource(path=str(sample_markdown_file), reason="Test") + + call_kwargs = mock_add_resource.call_args[1] + assert call_kwargs.get("watch_interval") == 0 + + async def test_watch_interval_custom_value( + self, client: AsyncOpenViking, sample_markdown_file: Path + ): + """Test that custom watch_interval value is propagated""" + with patch.object( + client._client, "add_resource", new_callable=AsyncMock + ) as mock_add_resource: + mock_add_resource.return_value = {"root_uri": "viking://test"} + + await client.add_resource( + path=str(sample_markdown_file), + reason="Test", + watch_interval=5.0, + ) + + call_kwargs = mock_add_resource.call_args[1] + assert call_kwargs.get("watch_interval") == 5.0 + + async def test_watch_interval_propagates_to_local_client( + self, sample_markdown_file: Path, test_data_dir: Path + ): + """Test that watch_interval propagates from AsyncOpenViking to LocalClient""" + from openviking.client import LocalClient + + with patch.object(LocalClient, "add_resource", new_callable=AsyncMock) as mock_add_resource: + mock_add_resource.return_value = {"root_uri": "viking://test"} + + from openviking import AsyncOpenViking + + await AsyncOpenViking.reset() + client = AsyncOpenViking(path=str(test_data_dir)) + await client.initialize() + + try: + await client.add_resource( + path=str(sample_markdown_file), + reason="Test", + watch_interval=10.0, + ) + + call_kwargs = mock_add_resource.call_args[1] + assert call_kwargs.get("watch_interval") == 10.0 + finally: + await client.close() + await AsyncOpenViking.reset() + + async def test_watch_interval_zero_means_disabled( + self, client: AsyncOpenViking, sample_markdown_file: Path + ): + """Test that watch_interval=0 means monitoring is disabled""" + result = await client.add_resource( + path=str(sample_markdown_file), + reason="Test", + watch_interval=0, + ) + + assert "root_uri" in result + + async def test_watch_interval_positive_value( + self, client: AsyncOpenViking, sample_markdown_file: Path + ): + """Test that positive watch_interval value is accepted""" + result = await client.add_resource( + path=str(sample_markdown_file), + reason="Test", + watch_interval=2.5, + ) + + assert "root_uri" in result diff --git a/tests/client/test_windows_path_handling.py b/tests/client/test_windows_path_handling.py new file mode 100644 index 00000000..a1123968 --- /dev/null +++ b/tests/client/test_windows_path_handling.py @@ -0,0 +1,162 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for cross-platform path handling in ZIP operations.""" + +import tempfile +import zipfile +from pathlib import Path + +from openviking_cli.client.http import AsyncHTTPClient + + +class TestZipCreationPathNormalization: + """Test that ZIP creation normalizes Windows path separators to forward slashes.""" + + def test_zip_directory_creates_forward_slash_paths(self): + """When zipping a directory, paths should use forward slashes (ZIP spec).""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + # Create a directory structure with nested subdirectories + root_dir = tmpdir / "test_project" + root_dir.mkdir() + (root_dir / "file1.txt").write_text("content1") + (root_dir / "subdir").mkdir() + (root_dir / "subdir" / "file2.txt").write_text("content2") + (root_dir / "subdir" / "nested").mkdir() + (root_dir / "subdir" / "nested" / "file3.txt").write_text("content3") + + # Create ZIP using the same method as AsyncHTTPClient._zip_directory + client = AsyncHTTPClient(url="http://localhost:1933") + zip_path = client._zip_directory(str(root_dir)) + + try: + # Verify all paths in ZIP use forward slashes + with zipfile.ZipFile(zip_path, "r") as zf: + names = zf.namelist() + for name in names: + # No backslashes should be present + assert "\\" not in name, f"Path contains backslash: {name}" + # Verify the expected files exist with correct paths + assert "file1.txt" in names + assert "subdir/file2.txt" in names + assert "subdir/nested/file3.txt" in names + finally: + Path(zip_path).unlink(missing_ok=True) + + def test_zip_directory_preserves_structure(self): + """ZIP should preserve directory structure correctly.""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + # Create a complex directory structure + root_dir = tmpdir / "complex_project" + root_dir.mkdir() + (root_dir / "root.txt").write_text("root") + (root_dir / "level1").mkdir() + (root_dir / "level1" / "file1.txt").write_text("level1") + (root_dir / "level1" / "level2").mkdir() + (root_dir / "level1" / "level2" / "file2.txt").write_text("level2") + + # Create ZIP + client = AsyncHTTPClient(url="http://localhost:1933") + zip_path = client._zip_directory(str(root_dir)) + + try: + # Verify structure is preserved + with zipfile.ZipFile(zip_path, "r") as zf: + names = set(zf.namelist()) + + # Check all expected files exist + assert "root.txt" in names + assert "level1/file1.txt" in names + assert "level1/level2/file2.txt" in names + + # Verify no duplicate filenames (same name in different dirs) + # This is the bug: on Windows, paths with backslashes might be treated differently + # Each file should have unique full path + assert len(names) == len(set(names)), "Duplicate paths detected" + finally: + Path(zip_path).unlink(missing_ok=True) + + +class TestZipExtractionPathHandling: + """Test that ZIP extraction handles Windows path separators correctly.""" + + def test_extract_zip_with_backslash_paths(self): + """ZIP extraction should handle paths with backslashes (from Windows).""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + # Create a ZIP with backslash paths (simulating Windows-created ZIP) + zip_path = tmpdir / "test.zip" + with zipfile.ZipFile(zip_path, "w") as zf: + # Write paths with backslashes (as would happen on Windows) + zf.writestr("project\\file1.txt", "content1") + zf.writestr("project\\subdir\\file2.txt", "content2") + + # Verify extraction handles backslashes correctly + # This test will fail until we fix the extraction code + with zipfile.ZipFile(zip_path, "r") as zf: + # Get first path and normalize it + first_path = zf.namelist()[0] + normalized_path = first_path.replace("\\", "/") + + # This should extract the base name correctly + base_name = normalized_path.split("/")[0] + assert base_name == "project", f"Expected 'project', got '{base_name}'" + + def test_extract_zip_preserves_directory_structure(self): + """ZIP extraction should preserve directory structure even with backslashes.""" + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + + # Create ZIP with mixed separators (edge case) + zip_path = tmpdir / "mixed.zip" + with zipfile.ZipFile(zip_path, "w") as zf: + zf.writestr("root/file.txt", "root content") + zf.writestr("root\\nested\\file.txt", "nested content") + + # Both should be extractable + with zipfile.ZipFile(zip_path, "r") as zf: + names = zf.namelist() + assert len(names) == 2 + + # After normalization, both should be under root/ + normalized = [name.replace("\\", "/") for name in names] + assert all(name.startswith("root/") for name in normalized) + + +class TestDirectoryScanPathNormalization: + """Test that directory scanning normalizes paths consistently.""" + + def test_scan_directory_normalizes_windows_paths(self): + """Directory scan should normalize Windows paths to forward slashes.""" + from openviking.parse.directory_scan import _normalize_rel_path + + # Test Windows-style paths + assert _normalize_rel_path("subdir\\file.txt") == "subdir/file.txt" + assert _normalize_rel_path("a\\b\\c\\file.txt") == "a/b/c/file.txt" + + # Test Unix-style paths (should remain unchanged) + assert _normalize_rel_path("subdir/file.txt") == "subdir/file.txt" + assert _normalize_rel_path("a/b/c/file.txt") == "a/b/c/file.txt" + + # Test mixed paths + assert _normalize_rel_path("a\\b/c\\d/file.txt") == "a/b/c/d/file.txt" + + def test_scan_directory_handles_value_error(self): + """When relative_to raises ValueError, path should still be normalized.""" + # This test simulates edge case in directory_scan.py:253-256 + # where relative_to fails and we fall back to raw path + + # The fix should ensure normalization happens even in except block + from openviking.parse.directory_scan import _normalize_rel_path + + # Simulate a path that might cause relative_to to fail + raw_path = "some\\windows\\path.txt" + normalized = _normalize_rel_path(raw_path) + + # Should still be normalized + assert "\\" not in normalized + assert normalized == "some/windows/path.txt" diff --git a/tests/engine/CMakeLists.txt b/tests/engine/CMakeLists.txt index 5eedb533..4461cfca 100644 --- a/tests/engine/CMakeLists.txt +++ b/tests/engine/CMakeLists.txt @@ -25,6 +25,10 @@ add_executable(test_index_engine test_index_engine.cpp ) +if(NOT TARGET engine_impl) + message(FATAL_ERROR "engine_impl compatibility target was not created") +endif() + target_link_libraries(test_index_engine PRIVATE engine_impl Threads::Threads diff --git a/tests/integration/test_add_resource_index.py b/tests/integration/test_add_resource_index.py index 32421e69..3da7cc25 100644 --- a/tests/integration/test_add_resource_index.py +++ b/tests/integration/test_add_resource_index.py @@ -1,10 +1,8 @@ -import pytest -import asyncio -import os import json -import shutil -from pathlib import Path -from unittest.mock import MagicMock, AsyncMock, patch +import os +from unittest.mock import AsyncMock, MagicMock, patch + +import pytest from openviking.async_client import AsyncOpenViking from openviking_cli.utils.config.open_viking_config import OpenVikingConfigSingleton @@ -88,6 +86,20 @@ async def test_add_resource_indexing_logic(test_config, tmp_path): mock_agfs = MockLocalAGFS(root_path=tmp_path / "mock_agfs_root") + # Create mock parse result for Phase 1 (media processor) + mock_parse_result = MagicMock() + mock_parse_result.source_path = str(resource_file) + mock_parse_result.meta = {} + mock_parse_result.temp_dir_path = "/tmp/fake_temp_dir" + mock_parse_result.warnings = [] + mock_parse_result.source_format = "markdown" + + # Create mock context tree for Phase 2/3 (tree builder) + mock_context_tree = MagicMock() + mock_context_tree.root = MagicMock() + mock_context_tree.root.uri = "viking://resources/test_doc" + mock_context_tree.root.temp_uri = None + # Patch the Summarizer and IndexBuilder to verify calls with ( patch( @@ -96,6 +108,16 @@ async def test_add_resource_indexing_logic(test_config, tmp_path): patch("openviking.utils.agfs_utils.create_agfs_client", return_value=mock_agfs), patch("openviking.agfs_manager.AGFSManager.start"), patch("openviking.agfs_manager.AGFSManager.stop"), + patch( + "openviking.utils.media_processor.UnifiedResourceProcessor.process", + new_callable=AsyncMock, + return_value=mock_parse_result, + ), + patch( + "openviking.parse.tree_builder.TreeBuilder.finalize_from_temp", + new_callable=AsyncMock, + return_value=mock_context_tree, + ), ): mock_summarize.return_value = {"status": "success"} diff --git a/tests/integration/test_full_workflow.py b/tests/integration/test_full_workflow.py index 3f86b559..b48385d7 100644 --- a/tests/integration/test_full_workflow.py +++ b/tests/integration/test_full_workflow.py @@ -10,6 +10,7 @@ from openviking import AsyncOpenViking from openviking.message import TextPart +from openviking.storage.transaction import release_all_locks @pytest_asyncio.fixture(scope="function") @@ -67,11 +68,17 @@ async def test_add_search_read_workflow( # 3. Read searched resource if search_result.resources: - res = await client.tree(search_result.resources[0].uri) - for data in res: - if not data["isDir"]: - content = await client.read(data["uri"]) - assert len(content) > 0 + uri = search_result.resources[0].uri + info = await client.stat(uri) + if info.get("isDir"): + res = await client.tree(uri) + for data in res: + if not data["isDir"]: + content = await client.read(data["uri"]) + assert len(content) > 0 + else: + content = await client.read(uri) + assert len(content) > 0 class TestSessionWorkflow: @@ -165,6 +172,7 @@ async def test_export_import_roundtrip( assert export_path.exists() # 4. Delete original resource + await release_all_locks() await client.rm(original_uri, recursive=True) # 5. Import diff --git a/tests/integration/test_watch_e2e.py b/tests/integration/test_watch_e2e.py new file mode 100644 index 00000000..0babfb66 --- /dev/null +++ b/tests/integration/test_watch_e2e.py @@ -0,0 +1,495 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""End-to-end tests for resource watch functionality.""" + +import asyncio +import shutil +from pathlib import Path + +import pytest +import pytest_asyncio + +from openviking import AsyncOpenViking +from openviking.resource.watch_scheduler import WatchScheduler +from openviking.server.identity import RequestContext, Role +from openviking.service.resource_service import ResourceService +from openviking_cli.exceptions import ConflictError +from openviking_cli.session.user_id import UserIdentifier + + +async def get_watch_task(client: AsyncOpenViking, to_uri: str): + watch_manager = client._service.resources._watch_scheduler.watch_manager + return await watch_manager.get_task_by_uri( + to_uri=to_uri, + account_id=client._service.user.account_id, + user_id=client._service.user.user_id, + role=Role.USER.value, + ) + + +@pytest_asyncio.fixture(scope="function") +async def e2e_client(test_data_dir: Path): + """End-to-end test client with watch support.""" + await AsyncOpenViking.reset() + + shutil.rmtree(test_data_dir, ignore_errors=True) + test_data_dir.mkdir(parents=True, exist_ok=True) + + client = AsyncOpenViking(path=str(test_data_dir)) + await client.initialize() + + yield client + + await client.close() + await AsyncOpenViking.reset() + + +@pytest_asyncio.fixture(scope="function") +async def watch_test_file(temp_dir: Path) -> Path: + """Create a test file for watch testing.""" + file_path = temp_dir / "watch_test.md" + file_path.write_text( + """# Watch Test Document + +## Initial Content +This is the initial content for watch testing. + +## Version +Version: 1.0 +Last Updated: Initial +""" + ) + return file_path + + +class TestWatchE2EBasicFlow: + """End-to-end tests for basic watch flow.""" + + @pytest.mark.asyncio + async def test_create_resource_with_watch( + self, e2e_client: AsyncOpenViking, watch_test_file: Path + ): + """Test creating a resource with watch enabled.""" + client = e2e_client + + to_uri = "viking://resources/watch_e2e_test" + + result = await client.add_resource( + path=str(watch_test_file), + to=to_uri, + reason="E2E watch test", + instruction="Monitor for changes", + watch_interval=60.0, + ) + + assert result is not None + assert "root_uri" in result + assert result["root_uri"] == to_uri + + task = await get_watch_task(client, to_uri) + assert task is not None + assert task.is_active is True + assert task.watch_interval == 60.0 + assert task.task_id is not None + assert task.next_execution_time is not None + + @pytest.mark.asyncio + async def test_query_watch_status(self, e2e_client: AsyncOpenViking, watch_test_file: Path): + """Test querying watch status for resources.""" + client = e2e_client + + watched_uri = "viking://resources/watched_resource" + unwatched_uri = "viking://resources/unwatched_resource" + + await client.add_resource( + path=str(watch_test_file), + to=watched_uri, + watch_interval=30.0, + ) + + await client.add_resource( + path=str(watch_test_file), + to=unwatched_uri, + watch_interval=0, + ) + + watched_task = await get_watch_task(client, watched_uri) + assert watched_task is not None + assert watched_task.is_active is True + assert watched_task.watch_interval == 30.0 + + unwatched_task = await get_watch_task(client, unwatched_uri) + assert unwatched_task is None + + @pytest.mark.asyncio + async def test_update_watch_interval(self, e2e_client: AsyncOpenViking, watch_test_file: Path): + """Test updating watch interval.""" + client = e2e_client + + to_uri = "viking://resources/update_interval_test" + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + watch_interval=30.0, + ) + + task = await get_watch_task(client, to_uri) + assert task is not None + assert task.watch_interval == 30.0 + task_id = task.task_id + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + watch_interval=0, + ) + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + watch_interval=120.0, + ) + + task = await get_watch_task(client, to_uri) + assert task is not None + assert task.is_active is True + assert task.watch_interval == 120.0 + assert task.task_id == task_id + + @pytest.mark.asyncio + async def test_cancel_watch(self, e2e_client: AsyncOpenViking, watch_test_file: Path): + """Test cancelling watch by setting interval to 0 or negative.""" + client = e2e_client + + to_uri = "viking://resources/cancel_test" + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + watch_interval=30.0, + ) + + task = await get_watch_task(client, to_uri) + assert task is not None + assert task.is_active is True + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + watch_interval=0, + ) + + task = await get_watch_task(client, to_uri) + assert task is not None + assert task.is_active is False + + +class TestWatchE2EConflictDetection: + """End-to-end tests for conflict detection.""" + + @pytest.mark.asyncio + async def test_conflict_when_active_watch_exists( + self, e2e_client: AsyncOpenViking, watch_test_file: Path + ): + """Test that conflict is raised when trying to watch an already watched URI.""" + client = e2e_client + + to_uri = "viking://resources/conflict_test" + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + watch_interval=30.0, + ) + + with pytest.raises(ConflictError) as exc_info: + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + watch_interval=60.0, + ) + + assert "already being monitored" in str(exc_info.value) + assert to_uri in str(exc_info.value) + + @pytest.mark.asyncio + async def test_reactivate_inactive_watch( + self, e2e_client: AsyncOpenViking, watch_test_file: Path + ): + """Test reactivating an inactive watch task.""" + client = e2e_client + + to_uri = "viking://resources/reactivate_test" + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + reason="Initial reason", + watch_interval=30.0, + ) + + task = await get_watch_task(client, to_uri) + assert task is not None + task_id = task.task_id + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + watch_interval=0, + ) + + task = await get_watch_task(client, to_uri) + assert task is not None + assert task.is_active is False + + await client.add_resource( + path=str(watch_test_file), + to=to_uri, + reason="Reactivated reason", + watch_interval=45.0, + ) + + task = await get_watch_task(client, to_uri) + assert task is not None + assert task.is_active is True + assert task.watch_interval == 45.0 + assert task.task_id == task_id + + +class TestWatchE2ESchedulerExecution: + """End-to-end tests for scheduler execution.""" + + @pytest.mark.asyncio + async def test_scheduler_executes_watch_task(self, temp_dir: Path, watch_test_file: Path): + """Test that scheduler executes watch tasks on schedule.""" + execution_count = 0 + + class MockResourceProcessor: + async def process_resource(self, **kwargs): + nonlocal execution_count + execution_count += 1 + return {"root_uri": kwargs.get("to", "viking://resources/test")} + + class MockSkillProcessor: + async def process_skill(self, **kwargs): + return {"status": "ok"} + + class MockVikingDB: + pass + + resource_service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=object(), + resource_processor=MockResourceProcessor(), + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + scheduler = WatchScheduler( + resource_service=resource_service, + viking_fs=None, + check_interval=0.1, + ) + await scheduler.start() + + watch_manager = scheduler.watch_manager + + task = await watch_manager.create_task( + path=str(watch_test_file), + to_uri="viking://resources/scheduler_test", + reason="Scheduler test", + watch_interval=0.002, + ) + + assert task.is_active is True + + await asyncio.sleep(0.3) + + await scheduler.stop() + + assert execution_count >= 1 + + await watch_manager.clear_all_tasks() + + @pytest.mark.asyncio + async def test_scheduler_updates_execution_time(self, temp_dir: Path, watch_test_file: Path): + """Test that scheduler updates execution time after task execution.""" + + class MockResourceProcessor: + async def process_resource(self, **kwargs): + return {"root_uri": kwargs.get("to", "viking://resources/test")} + + class MockSkillProcessor: + async def process_skill(self, **kwargs): + return {"status": "ok"} + + class MockVikingDB: + pass + + resource_service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=object(), + resource_processor=MockResourceProcessor(), + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + scheduler = WatchScheduler( + resource_service=resource_service, + viking_fs=None, + check_interval=0.1, + ) + await scheduler.start() + + watch_manager = scheduler.watch_manager + + task = await watch_manager.create_task( + path=str(watch_test_file), + to_uri="viking://resources/execution_time_test", + reason="Execution time test", + watch_interval=0.002, + ) + + assert task.last_execution_time is None + + await asyncio.sleep(0.3) + + await scheduler.stop() + + updated_task = await watch_manager.get_task(task.task_id) + assert updated_task is not None + assert updated_task.last_execution_time is not None + assert updated_task.next_execution_time is not None + assert updated_task.next_execution_time > updated_task.last_execution_time + + await watch_manager.clear_all_tasks() + + +class TestWatchE2EMultipleResources: + """End-to-end tests for multiple resources.""" + + @pytest.mark.asyncio + async def test_multiple_watched_resources( + self, e2e_client: AsyncOpenViking, watch_test_file: Path + ): + """Test managing multiple watched resources.""" + client = e2e_client + + uris = [ + "viking://resources/multi_test_1", + "viking://resources/multi_test_2", + "viking://resources/multi_test_3", + ] + + intervals = [30.0, 60.0, 120.0] + + for uri, interval in zip(uris, intervals): + await client.add_resource( + path=str(watch_test_file), + to=uri, + watch_interval=interval, + ) + + for uri, expected_interval in zip(uris, intervals): + task = await get_watch_task(client, uri) + assert task is not None + assert task.is_active is True + assert task.watch_interval == expected_interval + + for uri in uris: + await client.add_resource( + path=str(watch_test_file), + to=uri, + watch_interval=0, + ) + + for uri in uris: + task = await get_watch_task(client, uri) + assert task is not None + assert task.is_active is False + + @pytest.mark.asyncio + async def test_independent_watch_tasks( + self, e2e_client: AsyncOpenViking, watch_test_file: Path + ): + """Test that watch tasks are independent.""" + client = e2e_client + + uri1 = "viking://resources/independent_1" + uri2 = "viking://resources/independent_2" + + await client.add_resource( + path=str(watch_test_file), + to=uri1, + watch_interval=30.0, + ) + + await client.add_resource( + path=str(watch_test_file), + to=uri2, + watch_interval=60.0, + ) + + task1 = await get_watch_task(client, uri1) + task2 = await get_watch_task(client, uri2) + assert task1 is not None + assert task2 is not None + assert task1.task_id != task2.task_id + + await client.add_resource( + path=str(watch_test_file), + to=uri1, + watch_interval=0, + ) + + task1_after = await get_watch_task(client, uri1) + task2_after = await get_watch_task(client, uri2) + assert task1_after is not None + assert task1_after.is_active is False + assert task2_after is not None + assert task2_after.is_active is True + + +class TestWatchE2EErrorHandling: + """End-to-end tests for error handling.""" + + @pytest.mark.asyncio + async def test_watch_without_watch_manager(self, temp_dir: Path, watch_test_file: Path): + """Test that resource can be added without watch manager.""" + + class MockResourceProcessor: + async def process_resource(self, **kwargs): + return {"root_uri": kwargs.get("to", "viking://resources/test")} + + class MockSkillProcessor: + async def process_skill(self, **kwargs): + return {"status": "ok"} + + resource_service = ResourceService( + vikingdb=object(), + viking_fs=object(), + resource_processor=MockResourceProcessor(), + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + ctx = RequestContext( + user=UserIdentifier("test_account", "test_user", "test_agent"), + role=Role.USER, + ) + + result = await resource_service.add_resource( + path=str(watch_test_file), + ctx=ctx, + to="viking://resources/no_watch_test", + watch_interval=30.0, + ) + + assert result is not None + assert "root_uri" in result + + @pytest.mark.asyncio + async def test_watch_task_nonexistent_resource(self, e2e_client: AsyncOpenViking): + client = e2e_client + task = await get_watch_task(client, "viking://resources/nonexistent") + assert task is None diff --git a/tests/misc/test_config_validation.py b/tests/misc/test_config_validation.py index 665c6e15..1ab71517 100644 --- a/tests/misc/test_config_validation.py +++ b/tests/misc/test_config_validation.py @@ -156,6 +156,50 @@ def test_embedding_validation(): else: print(f" Fail (provider='volcengine' should have priority, got '{config_b.provider}')") + # Test 5: Ollama provider (no API key required) + print("\n5. Test Ollama provider (no API key required)...") + try: + _ = EmbeddingConfig( + dense=EmbeddingModelConfig( + provider="ollama", + model="nomic-embed-text", + dimension=768, + ) + ) + print(" Pass (Ollama does not require API key)") + except ValueError as e: + print(f" Fail: {e}") + + # Test 6: Ollama provider with custom api_base + print("\n6. Test Ollama provider with custom api_base...") + try: + _ = EmbeddingConfig( + dense=EmbeddingModelConfig( + provider="ollama", + model="nomic-embed-text", + api_base="http://localhost:11434/v1", + dimension=768, + ) + ) + print(" Pass") + except ValueError as e: + print(f" Fail: {e}") + + # Test 7: OpenAI provider with api_base but no api_key (local OpenAI-compatible server) + print("\n7. Test OpenAI provider with api_base but no api_key...") + try: + _ = EmbeddingConfig( + dense=EmbeddingModelConfig( + provider="openai", + model="text-embedding-3-small", + api_base="http://localhost:8080/v1", + dimension=1536, + ) + ) + print(" Pass (OpenAI provider allows missing api_key when api_base is set)") + except ValueError as e: + print(f" Fail: {e}") + def test_vlm_validation(): """Test VLM config validation""" diff --git a/tests/misc/test_embedding_input_type.py b/tests/misc/test_embedding_input_type.py new file mode 100644 index 00000000..339ed187 --- /dev/null +++ b/tests/misc/test_embedding_input_type.py @@ -0,0 +1,283 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for non-symmetric query/document embedding passthrough. + +Tests EmbeddingConfig's ability to create context-specific embedders: +- OpenAI: fixed query input_type when document input_type is set +- Jina: fixed query task when task_document is set +""" + +from unittest.mock import MagicMock, patch + +from openviking_cli.utils.config.embedding_config import EmbeddingConfig, EmbeddingModelConfig + + +class TestEmbeddingModelConfigContextFields: + """Test EmbeddingModelConfig fields for context-specific parameters.""" + + def test_openai_query_document_param_fields_accept_values(self): + """OpenAI config should accept query_param and document_param.""" + config = EmbeddingModelConfig( + model="text-embedding-3-small", + provider="openai", + api_key="sk-test", + query_param="search_query", + document_param="search_document", + ) + assert config.query_param == "search_query" + assert config.document_param == "search_document" + + def test_jina_query_document_param_fields_accept_values(self): + """Jina config should accept query_param and document_param.""" + config = EmbeddingModelConfig( + model="jina-embeddings-v5-text-small", + provider="jina", + api_key="jina-test", + query_param="retrieval.query", + document_param="retrieval.passage", + ) + assert config.query_param == "retrieval.query" + assert config.document_param == "retrieval.passage" + + def test_context_fields_default_to_none(self): + """Fields should default to None when not specified.""" + config = EmbeddingModelConfig( + model="text-embedding-3-small", + provider="openai", + api_key="sk-test", + ) + assert config.query_param is None + assert config.document_param is None + + def test_query_document_param_lowercase_normalization(self): + """Query/document value should be normalized to lowercase.""" + config = EmbeddingModelConfig( + model="text-embedding-3-small", + provider="openai", + api_key="sk-test", + query_param="SEARCH_QUERY", + document_param="Search_Document", + ) + assert config.query_param == "search_query" + assert config.document_param == "search_document" + + def test_jina_query_document_param_lowercase_normalization(self): + """Query/document task values should be normalized to lowercase.""" + config = EmbeddingModelConfig( + model="jina-embeddings-v5-text-small", + provider="jina", + api_key="jina-test", + query_param="RETRIEVAL.QUERY", + document_param="Retrieval.Passage", + ) + assert config.query_param == "retrieval.query" + assert config.document_param == "retrieval.passage" + + +class TestEmbeddingConfigContextualEmbedders: + """Test EmbeddingConfig passes query_param and document_param correctly.""" + + @patch("openviking.models.embedder.OpenAIDenseEmbedder") + def test_get_embedder_openai_passes_params(self, mock_embedder_class): + """get_embedder should pass query_param and document_param to OpenAIDenseEmbedder.""" + mock_embedder_class.return_value = MagicMock() + config = EmbeddingConfig( + dense=EmbeddingModelConfig( + model="text-embedding-3-small", + provider="openai", + api_key="sk-test", + query_param="search_query", + document_param="search_document", + ) + ) + + config.get_embedder() + + mock_embedder_class.assert_called_once() + call_kwargs = mock_embedder_class.call_args[1] + assert call_kwargs.get("query_param") == "search_query" + assert call_kwargs.get("document_param") == "search_document" + + @patch("openviking.models.embedder.JinaDenseEmbedder") + def test_get_embedder_jina_passes_params(self, mock_embedder_class): + """get_embedder should pass query_param and document_param to JinaDenseEmbedder.""" + mock_embedder_class.return_value = MagicMock() + config = EmbeddingConfig( + dense=EmbeddingModelConfig( + model="jina-embeddings-v5-text-small", + provider="jina", + api_key="jina-test", + query_param="retrieval.query", + document_param="retrieval.passage", + ) + ) + + config.get_embedder() + + mock_embedder_class.assert_called_once() + call_kwargs = mock_embedder_class.call_args[1] + assert call_kwargs.get("query_param") == "retrieval.query" + assert call_kwargs.get("document_param") == "retrieval.passage" + + @patch("openviking.models.embedder.OpenAIDenseEmbedder") + def test_get_embedder_openai_no_params_when_not_set(self, mock_embedder_class): + """get_embedder should not pass query_param and document_param when not set.""" + mock_embedder_class.return_value = MagicMock() + config = EmbeddingConfig( + dense=EmbeddingModelConfig( + model="text-embedding-3-small", + provider="openai", + api_key="sk-test", + ) + ) + + config.get_embedder() + + mock_embedder_class.assert_called_once() + call_kwargs = mock_embedder_class.call_args[1] + assert "query_param" not in call_kwargs + assert "document_param" not in call_kwargs + + @patch("openviking.models.embedder.JinaDenseEmbedder") + def test_get_embedder_jina_no_params_when_not_set(self, mock_embedder_class): + """get_embedder should not pass query_param and document_param when not set.""" + mock_embedder_class.return_value = MagicMock() + config = EmbeddingConfig( + dense=EmbeddingModelConfig( + model="jina-embeddings-v5-text-small", + provider="jina", + api_key="jina-test", + ) + ) + + config.get_embedder() + + mock_embedder_class.assert_called_once() + call_kwargs = mock_embedder_class.call_args[1] + assert "query_param" not in call_kwargs + assert "document_param" not in call_kwargs + + +class TestOpenAIDenseEmbedderInputType: + """Test OpenAIDenseEmbedder input_type support in embed and embed_batch.""" + + @patch("openai.OpenAI") + def test_embed_passes_input_type_in_extra_body(self, mock_openai_class): + """embed should pass input_type in extra_body when provided.""" + from openviking.models.embedder import OpenAIDenseEmbedder + + mock_client = MagicMock() + mock_response = MagicMock() + mock_response.data = [MagicMock(embedding=[0.1] * 1536)] + mock_client.embeddings.create.return_value = mock_response + mock_openai_class.return_value = mock_client + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="sk-test", + dimension=1536, + query_param="search_query", + ) + + embedder.embed("test query", is_query=True) + + mock_client.embeddings.create.assert_called_once() + call_kwargs = mock_client.embeddings.create.call_args[1] + assert call_kwargs.get("extra_body") == {"input_type": "search_query"} + + @patch("openai.OpenAI") + def test_embed_batch_passes_input_type_in_extra_body(self, mock_openai_class): + """embed_batch should pass input_type in extra_body when provided.""" + from openviking.models.embedder import OpenAIDenseEmbedder + + mock_client = MagicMock() + mock_response = MagicMock() + mock_response.data = [MagicMock(embedding=[0.1] * 1536), MagicMock(embedding=[0.2] * 1536)] + mock_client.embeddings.create.return_value = mock_response + mock_openai_class.return_value = mock_client + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="sk-test", + dimension=1536, + document_param="search_document", + ) + + embedder.embed_batch(["doc 1", "doc 2"], is_query=False) + + mock_client.embeddings.create.assert_called_once() + call_kwargs = mock_client.embeddings.create.call_args[1] + assert call_kwargs.get("extra_body") == {"input_type": "search_document"} + + @patch("openai.OpenAI") + def test_embed_no_extra_body_when_input_type_not_set(self, mock_openai_class): + """embed should not set extra_body when input_type is None.""" + from openviking.models.embedder import OpenAIDenseEmbedder + + mock_client = MagicMock() + mock_response = MagicMock() + mock_response.data = [MagicMock(embedding=[0.1] * 1536)] + mock_client.embeddings.create.return_value = mock_response + mock_openai_class.return_value = mock_client + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="sk-test", + dimension=1536, + ) + + embedder.embed("test query") + + mock_client.embeddings.create.assert_called_once() + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "extra_body" not in call_kwargs + + +class TestJinaDenseEmbedderTask: + """Test JinaDenseEmbedder task passthrough (already exists, verify behavior).""" + + @patch("openai.OpenAI") + def test_embed_passes_task_in_extra_body(self, mock_openai_class): + """embed should pass task in extra_body when provided.""" + from openviking.models.embedder import JinaDenseEmbedder + + mock_client = MagicMock() + mock_response = MagicMock() + mock_response.data = [MagicMock(embedding=[0.1] * 1024)] + mock_client.embeddings.create.return_value = mock_response + mock_openai_class.return_value = mock_client + + embedder = JinaDenseEmbedder( + model_name="jina-embeddings-v5-text-small", + api_key="jina-test", + query_param="retrieval.query", + ) + + embedder.embed("test query", is_query=True) + + mock_client.embeddings.create.assert_called_once() + call_kwargs = mock_client.embeddings.create.call_args[1] + assert call_kwargs.get("extra_body") == {"task": "retrieval.query"} + + @patch("openai.OpenAI") + def test_embed_batch_passes_task_in_extra_body(self, mock_openai_class): + """embed_batch should pass task in extra_body when provided.""" + from openviking.models.embedder import JinaDenseEmbedder + + mock_client = MagicMock() + mock_response = MagicMock() + mock_response.data = [MagicMock(embedding=[0.1] * 1024), MagicMock(embedding=[0.2] * 1024)] + mock_client.embeddings.create.return_value = mock_response + mock_openai_class.return_value = mock_client + + embedder = JinaDenseEmbedder( + model_name="jina-embeddings-v5-text-small", + api_key="jina-test", + document_param="retrieval.passage", + ) + + embedder.embed_batch(["doc 1", "doc 2"], is_query=False) + + mock_client.embeddings.create.assert_called_once() + call_kwargs = mock_client.embeddings.create.call_args[1] + assert call_kwargs.get("extra_body") == {"task": "retrieval.passage"} diff --git a/tests/misc/test_process_lock.py b/tests/misc/test_process_lock.py new file mode 100644 index 00000000..45846593 --- /dev/null +++ b/tests/misc/test_process_lock.py @@ -0,0 +1,61 @@ +"""Tests for PID-based advisory lock on data directories.""" + +import os +import tempfile + +from openviking.utils.process_lock import ( + LOCK_FILENAME, + DataDirectoryLocked, + acquire_data_dir_lock, +) + + +class TestProcessLock: + def test_acquires_lock_on_empty_dir(self): + with tempfile.TemporaryDirectory() as tmpdir: + lock_path = acquire_data_dir_lock(tmpdir) + assert os.path.isfile(lock_path) + with open(lock_path) as f: + assert int(f.read().strip()) == os.getpid() + + def test_same_pid_can_reacquire(self): + with tempfile.TemporaryDirectory() as tmpdir: + acquire_data_dir_lock(tmpdir) + # Should not raise when same process re-acquires. + acquire_data_dir_lock(tmpdir) + + def test_stale_lock_is_replaced(self): + with tempfile.TemporaryDirectory() as tmpdir: + lock_path = os.path.join(tmpdir, LOCK_FILENAME) + # Write a PID that does not exist (very high number). + with open(lock_path, "w") as f: + f.write("999999999") + # Should succeed because the PID is dead. + acquire_data_dir_lock(tmpdir) + with open(lock_path) as f: + assert int(f.read().strip()) == os.getpid() + + def test_live_pid_blocks_acquisition(self): + with tempfile.TemporaryDirectory() as tmpdir: + lock_path = os.path.join(tmpdir, LOCK_FILENAME) + # PID 1 (init/launchd) is always alive. + with open(lock_path, "w") as f: + f.write("1") + try: + acquire_data_dir_lock(tmpdir) + raise AssertionError("Should have raised DataDirectoryLocked") + except DataDirectoryLocked as exc: + assert "PID 1" in str(exc) + assert "HTTP mode" in str(exc) + + def test_error_message_includes_remediation(self): + with tempfile.TemporaryDirectory() as tmpdir: + lock_path = os.path.join(tmpdir, LOCK_FILENAME) + with open(lock_path, "w") as f: + f.write("1") + try: + acquire_data_dir_lock(tmpdir) + except DataDirectoryLocked as exc: + msg = str(exc) + assert "openviking-server" in msg + assert "separate data directories" in msg diff --git a/tests/misc/test_resource_processor_mv.py b/tests/misc/test_resource_processor_mv.py new file mode 100644 index 00000000..beb74029 --- /dev/null +++ b/tests/misc/test_resource_processor_mv.py @@ -0,0 +1,85 @@ +import os +import sys +from types import SimpleNamespace +from unittest.mock import AsyncMock, MagicMock + +import pytest + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) + + +class _DummyVikingDB: + def get_embedder(self): + return None + + +class _DummyTelemetry: + def set(self, *args, **kwargs): + return None + + def set_error(self, *args, **kwargs): + return None + + +class _CtxMgr: + def __enter__(self): + return self + + def __exit__(self, exc_type, exc, tb): + return False + + +class _FakeVikingFS: + def __init__(self): + self.agfs = SimpleNamespace(mv=MagicMock(return_value={"status": "ok"})) + + def bind_request_context(self, ctx): + return _CtxMgr() + + async def exists(self, uri, ctx=None): + return False + + async def mkdir(self, uri, exist_ok=False, ctx=None): + return None + + async def delete_temp(self, temp_dir_path, ctx=None): + return None + + def _uri_to_path(self, uri, ctx=None): + return f"/mock/{uri.replace('viking://', '')}" + + +@pytest.mark.asyncio +async def test_resource_processor_first_add_persist_does_not_await_agfs_mv(monkeypatch): + from openviking.utils.resource_processor import ResourceProcessor + + fake_fs = _FakeVikingFS() + + monkeypatch.setattr( + "openviking.utils.resource_processor.get_current_telemetry", + lambda: _DummyTelemetry(), + ) + monkeypatch.setattr("openviking.utils.resource_processor.get_viking_fs", lambda: fake_fs) + + rp = ResourceProcessor(vikingdb=_DummyVikingDB(), media_storage=None) + rp._get_media_processor = MagicMock() + rp._get_media_processor.return_value.process = AsyncMock( + return_value=SimpleNamespace( + temp_dir_path="viking://temp/tmpdir", + source_path="x", + source_format="text", + meta={}, + warnings=[], + ) + ) + + context_tree = SimpleNamespace( + root=SimpleNamespace(uri="viking://resources/root", temp_uri="viking://temp/root_tmp") + ) + rp.tree_builder.finalize_from_temp = AsyncMock(return_value=context_tree) + + result = await rp.process_resource(path="x", ctx=object(), build_index=False, summarize=False) + + assert result["status"] == "success" + assert result["root_uri"] == "viking://resources/root" + fake_fs.agfs.mv.assert_called_once() diff --git a/tests/misc/test_semantic_config.py b/tests/misc/test_semantic_config.py new file mode 100644 index 00000000..0a974dc8 --- /dev/null +++ b/tests/misc/test_semantic_config.py @@ -0,0 +1,82 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +"""Tests for SemanticConfig and overview budget estimation.""" + +from openviking_cli.utils.config.parser_config import SemanticConfig + + +def test_semantic_config_defaults(): + """Test default values match previously hardcoded constants.""" + config = SemanticConfig() + assert config.max_file_content_chars == 30000 + assert config.max_overview_prompt_chars == 60000 + assert config.overview_batch_size == 50 + assert config.abstract_max_chars == 256 + assert config.overview_max_chars == 4000 + + +def test_semantic_config_custom_values(): + """Test custom values override defaults.""" + config = SemanticConfig( + max_overview_prompt_chars=100000, + overview_batch_size=100, + ) + assert config.max_overview_prompt_chars == 100000 + assert config.overview_batch_size == 100 + # Unchanged defaults + assert config.max_file_content_chars == 30000 + assert config.abstract_max_chars == 256 + + +def test_budget_under_limit_no_batching(): + """Small directories should not trigger batching.""" + config = SemanticConfig() + # 10 file summaries, each ~100 chars = ~1000 chars total + summaries = [{"name": f"file_{i}.py", "summary": "x" * 100} for i in range(10)] + total = sum(len(f"[{i}] {s['name']}: {s['summary']}") for i, s in enumerate(summaries, 1)) + assert total < config.max_overview_prompt_chars + assert len(summaries) <= config.overview_batch_size + + +def test_budget_over_limit_triggers_batching(): + """Large directories should exceed budget and require batching.""" + config = SemanticConfig() + # 200 file summaries, each ~500 chars = ~100000+ chars total + summaries = [{"name": f"file_{i}.py", "summary": "x" * 500} for i in range(200)] + total = sum(len(f"[{i}] {s['name']}: {s['summary']}") for i, s in enumerate(summaries, 1)) + assert total > config.max_overview_prompt_chars + assert len(summaries) > config.overview_batch_size + + +def test_abstract_truncation(): + """Test abstract is truncated to abstract_max_chars.""" + config = SemanticConfig(abstract_max_chars=100) + abstract = "x" * 200 + if len(abstract) > config.abstract_max_chars: + abstract = abstract[: config.abstract_max_chars - 3] + "..." + assert len(abstract) == 100 + assert abstract.endswith("...") + + +def test_overview_truncation(): + """Test overview is truncated to overview_max_chars.""" + config = SemanticConfig(overview_max_chars=500) + overview = "x" * 1000 + if len(overview) > config.overview_max_chars: + overview = overview[: config.overview_max_chars] + assert len(overview) == 500 + + +def test_batch_splitting(): + """Test batch splitting logic produces correct batch count.""" + config = SemanticConfig(overview_batch_size=50) + summaries = [{"name": f"f{i}.py", "summary": "s"} for i in range(120)] + batches = [ + summaries[i : i + config.overview_batch_size] + for i in range(0, len(summaries), config.overview_batch_size) + ] + assert len(batches) == 3 # 50 + 50 + 20 + assert len(batches[0]) == 50 + assert len(batches[1]) == 50 + assert len(batches[2]) == 20 diff --git a/tests/misc/test_vectordb_engine_loader.py b/tests/misc/test_vectordb_engine_loader.py new file mode 100644 index 00000000..a3d9442b --- /dev/null +++ b/tests/misc/test_vectordb_engine_loader.py @@ -0,0 +1,120 @@ +import importlib +import importlib.util +import platform +import sys +import types +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parents[2] +ENGINE_INIT = REPO_ROOT / "openviking" / "storage" / "vectordb" / "engine" / "__init__.py" + + +def _install_package_stubs(monkeypatch): + packages = { + "openviking": REPO_ROOT / "openviking", + "openviking.storage": REPO_ROOT / "openviking" / "storage", + "openviking.storage.vectordb": REPO_ROOT / "openviking" / "storage" / "vectordb", + } + for name, path in packages.items(): + module = types.ModuleType(name) + module.__path__ = [str(path)] # type: ignore[attr-defined] + monkeypatch.setitem(sys.modules, name, module) + + +def _load_engine_module( + monkeypatch, *, machine, available_backends, cpu_variants, env_variant=None +): + _install_package_stubs(monkeypatch) + + monkeypatch.setattr(platform, "machine", lambda: machine) + if env_variant is None: + monkeypatch.delenv("OV_ENGINE_VARIANT", raising=False) + else: + monkeypatch.setenv("OV_ENGINE_VARIANT", env_variant) + + original_import_module = importlib.import_module + original_find_spec = importlib.util.find_spec + + def fake_import_module(name, package=None): + if package == "openviking.storage.vectordb.engine" and name == "._x86_caps": + caps = types.SimpleNamespace( + get_supported_variants=lambda: list(cpu_variants), + ) + return caps + + if package == "openviking.storage.vectordb.engine" and name.startswith("._"): + backend_name = name[2:].lstrip("_") + if backend_name not in available_backends: + raise ModuleNotFoundError(name) + return types.SimpleNamespace( + BACKEND_NAME=backend_name, + IndexEngine=f"IndexEngine:{backend_name}", + PersistStore=f"PersistStore:{backend_name}", + VolatileStore=f"VolatileStore:{backend_name}", + ) + + return original_import_module(name, package) + + def fake_find_spec(name, package=None): + fullname = importlib.util.resolve_name(name, package) if name.startswith(".") else name + if fullname == "openviking.storage.vectordb.engine._x86_caps": + return object() + if fullname.startswith("openviking.storage.vectordb.engine."): + backend_name = fullname.rsplit(".", 1)[-1].lstrip("_") + if backend_name in available_backends: + return object() + return None + return original_find_spec(name, package) + + monkeypatch.setattr(importlib, "import_module", fake_import_module) + monkeypatch.setattr(importlib.util, "find_spec", fake_find_spec) + + spec = importlib.util.spec_from_file_location( + "openviking.storage.vectordb.engine", + ENGINE_INIT, + submodule_search_locations=[str(ENGINE_INIT.parent)], + ) + module = importlib.util.module_from_spec(spec) + monkeypatch.setitem(sys.modules, "openviking.storage.vectordb.engine", module) + assert spec.loader is not None + spec.loader.exec_module(module) + return module + + +def test_engine_loader_auto_selects_best_supported_x86_backend(monkeypatch): + module = _load_engine_module( + monkeypatch, + machine="x86_64", + available_backends={"x86_sse3", "x86_avx2", "x86_avx512"}, + cpu_variants={"x86_sse3", "x86_avx2"}, + ) + + assert module.ENGINE_VARIANT == "x86_avx2" + assert module.IndexEngine == "IndexEngine:x86_avx2" + assert module.AVAILABLE_ENGINE_VARIANTS == ("x86_sse3", "x86_avx2", "x86_avx512") + + +def test_engine_loader_uses_native_backend_on_non_x86(monkeypatch): + module = _load_engine_module( + monkeypatch, + machine="arm64", + available_backends={"native"}, + cpu_variants=set(), + ) + + assert module.ENGINE_VARIANT == "native" + assert module.PersistStore == "PersistStore:native" + assert module.AVAILABLE_ENGINE_VARIANTS == ("native",) + + +def test_engine_loader_rejects_forced_unsupported_variant(monkeypatch): + with pytest.raises(ImportError, match="x86_avx512"): + _load_engine_module( + monkeypatch, + machine="x86_64", + available_backends={"x86_sse3", "x86_avx2"}, + cpu_variants={"x86_sse3", "x86_avx2"}, + env_variant="x86_avx512", + ) diff --git a/tests/misc/test_vikingdb_observer.py b/tests/misc/test_vikingdb_observer.py index 310d01b6..3dc3cfaf 100644 --- a/tests/misc/test_vikingdb_observer.py +++ b/tests/misc/test_vikingdb_observer.py @@ -8,13 +8,16 @@ import asyncio import openviking as ov +from openviking.async_client import AsyncOpenViking async def test_vikingdb_observer(): """Test VikingDBObserver functionality""" print("=== Test VikingDBObserver ===") - # Create client + # Reset singleton to ensure clean state from previous tests + await AsyncOpenViking.reset() + client = ov.AsyncOpenViking(path="./test_data/test_vikingdb_observer") try: @@ -72,15 +75,17 @@ async def test_vikingdb_observer(): traceback.print_exc() finally: - # Close client - await client.close() + await AsyncOpenViking.reset() print("Client closed") -def test_sync_client(): +async def test_sync_client(): """Test sync client""" print("\n=== Test sync client ===") + # Reset singleton to ensure clean state from previous tests + await AsyncOpenViking.reset() + client = ov.OpenViking(path="./test_data/test_vikingdb_observer") try: @@ -109,6 +114,7 @@ def test_sync_client(): finally: client.close() + await AsyncOpenViking.reset() print("Sync client closed") @@ -117,4 +123,4 @@ def test_sync_client(): asyncio.run(test_vikingdb_observer()) # Run sync test - test_sync_client() + asyncio.run(test_sync_client()) diff --git a/tests/misc/test_vikingfs_uri_guard.py b/tests/misc/test_vikingfs_uri_guard.py new file mode 100644 index 00000000..f20513e3 --- /dev/null +++ b/tests/misc/test_vikingfs_uri_guard.py @@ -0,0 +1,106 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Regression tests for traversal-style URI rejection in VikingFS.""" + +import contextvars +from unittest.mock import AsyncMock, MagicMock + +import pytest + +from openviking.storage.viking_fs import VikingFS + + +def _make_viking_fs() -> VikingFS: + """Create a VikingFS instance with a mocked AGFS backend.""" + fs = VikingFS.__new__(VikingFS) + fs.agfs = MagicMock() + fs.query_embedder = None + fs.rerank_config = None + fs.vector_store = None + fs._bound_ctx = contextvars.ContextVar("vikingfs_bound_ctx_test", default=None) + return fs + + +class TestVikingFSURITraversalGuard: + """Traversal-style URI components should be rejected before any AGFS I/O.""" + + @pytest.mark.parametrize( + "uri", + [ + "viking://resources/../_system/users.json", + "viking://resources/../../_system/accounts.json", + "/resources/../_system/users.json", + "viking://resources/..\\..\\_system\\users.json", + "viking://resources/C:\\Windows\\System32", + ], + ) + def test_rejects_unsafe_uri_components(self, uri: str) -> None: + fs = _make_viking_fs() + + with pytest.raises(PermissionError, match="Unsafe URI"): + fs._normalized_uri_parts(uri) + + @pytest.mark.asyncio + async def test_read_file_rejects_traversal_before_agfs_read(self) -> None: + fs = _make_viking_fs() + + with pytest.raises(PermissionError, match="Unsafe URI"): + await fs.read_file("viking://resources/../_system/users.json") + + fs.agfs.read.assert_not_called() + + @pytest.mark.asyncio + async def test_write_rejects_traversal_before_agfs_write(self) -> None: + fs = _make_viking_fs() + + with pytest.raises(PermissionError, match="Unsafe URI"): + await fs.write("viking://resources/../../_system/accounts.json", "pwned") + + fs.agfs.write.assert_not_called() + + @pytest.mark.asyncio + async def test_rm_rejects_traversal_before_side_effects(self) -> None: + fs = _make_viking_fs() + fs._collect_uris = AsyncMock(return_value=[]) + fs._delete_from_vector_store = AsyncMock() + + with pytest.raises(PermissionError, match="Unsafe URI"): + await fs.rm("viking://resources/../../other_account/_system/users.json") + + fs._collect_uris.assert_not_called() + fs._delete_from_vector_store.assert_not_called() + fs.agfs.rm.assert_not_called() + + @pytest.mark.asyncio + @pytest.mark.parametrize( + ("old_uri", "new_uri"), + [ + ("viking://resources/../_system/users.json", "viking://resources/safe.txt"), + ("viking://resources/safe.txt", "viking://resources/../../victim/_system/users.json"), + ], + ) + async def test_mv_rejects_traversal_in_source_or_target( + self, old_uri: str, new_uri: str + ) -> None: + fs = _make_viking_fs() + fs._collect_uris = AsyncMock(return_value=[]) + fs._update_vector_store_uris = AsyncMock() + fs._delete_from_vector_store = AsyncMock() + + with pytest.raises(PermissionError, match="Unsafe URI"): + await fs.mv(old_uri, new_uri) + + fs._collect_uris.assert_not_called() + fs._update_vector_store_uris.assert_not_called() + fs._delete_from_vector_store.assert_not_called() + fs.agfs.mv.assert_not_called() + + @pytest.mark.asyncio + async def test_read_file_keeps_valid_uri_behavior(self) -> None: + fs = _make_viking_fs() + fs.agfs.read = MagicMock(return_value=b"hello") + + content = await fs.read_file("viking://resources/docs/guide.md") + + assert content == "hello" + fs.agfs.read.assert_called_once_with("/local/default/resources/docs/guide.md") diff --git a/tests/misc/test_x86_profiles.py b/tests/misc/test_x86_profiles.py new file mode 100644 index 00000000..df49b145 --- /dev/null +++ b/tests/misc/test_x86_profiles.py @@ -0,0 +1,17 @@ +from build_support.x86_profiles import get_host_engine_build_config + + +def test_x86_host_uses_sse3_extension_baseline(): + config = get_host_engine_build_config("x86_64") + + assert config.primary_extension == "openviking.storage.vectordb.engine._x86_sse3" + assert config.cmake_variants == ("sse3", "avx2", "avx512") + assert config.is_x86 is True + + +def test_non_x86_host_uses_native_extension_baseline(): + config = get_host_engine_build_config("aarch64") + + assert config.primary_extension == "openviking.storage.vectordb.engine._native" + assert config.cmake_variants == () + assert config.is_x86 is False diff --git a/tests/models/test_embedding_telemetry_usage.py b/tests/models/test_embedding_telemetry_usage.py new file mode 100644 index 00000000..374128fd --- /dev/null +++ b/tests/models/test_embedding_telemetry_usage.py @@ -0,0 +1,104 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from types import SimpleNamespace + +from openviking.models.embedder.openai_embedders import OpenAIDenseEmbedder +from openviking.models.embedder.volcengine_embedders import VolcengineDenseEmbedder +from openviking.telemetry.backends.memory import MemoryOperationTelemetry +from openviking.telemetry.context import bind_telemetry + + +def _usage(prompt_tokens: int, total_tokens: int): + return SimpleNamespace(prompt_tokens=prompt_tokens, total_tokens=total_tokens) + + +def test_openai_dense_embedder_reports_embedding_telemetry_usage(monkeypatch): + response = SimpleNamespace( + data=[SimpleNamespace(embedding=[0.1, 0.2, 0.3])], + usage=_usage(prompt_tokens=9, total_tokens=9), + ) + + fake_client = SimpleNamespace(embeddings=SimpleNamespace(create=lambda **kwargs: response)) + monkeypatch.setattr("openai.OpenAI", lambda **kwargs: fake_client) + + telemetry = MemoryOperationTelemetry(operation="search.find", enabled=True) + with bind_telemetry(telemetry): + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test", + dimension=3, + ) + result = embedder.embed("hello") + + assert result.dense_vector == [0.1, 0.2, 0.3] + summary = telemetry.finish().summary + assert summary["tokens"]["embedding"] == {"total": 9} + assert summary["tokens"]["total"] == 9 + + +def test_volcengine_dense_embedder_reports_embedding_telemetry_usage(monkeypatch): + response = SimpleNamespace( + data=SimpleNamespace(embedding=[0.4, 0.5, 0.6]), + usage=_usage(prompt_tokens=16, total_tokens=16), + ) + + fake_client = SimpleNamespace( + multimodal_embeddings=SimpleNamespace(create=lambda **kwargs: response), + ) + monkeypatch.setattr( + "volcenginesdkarkruntime.Ark", + lambda **kwargs: fake_client, + ) + + telemetry = MemoryOperationTelemetry(operation="resources.add_resource", enabled=True) + with bind_telemetry(telemetry): + embedder = VolcengineDenseEmbedder( + model_name="doubao-embedding-vision-250615", + api_key="test", + input_type="multimodal", + dimension=3, + ) + result = embedder.embed("hello") + + assert result.dense_vector == [0.4, 0.5, 0.6] + summary = telemetry.finish().summary + assert summary["tokens"]["embedding"] == {"total": 16} + assert summary["tokens"]["total"] == 16 + + +def test_volcengine_dense_embedder_reports_embedding_telemetry_usage_from_dict_usage( + monkeypatch, +): + response = SimpleNamespace( + data=SimpleNamespace(embedding=[0.4, 0.5, 0.6]), + usage={ + "prompt_tokens": 16, + "prompt_tokens_details": {"image_tokens": 0, "text_tokens": 16}, + "total_tokens": 16, + }, + ) + + fake_client = SimpleNamespace( + multimodal_embeddings=SimpleNamespace(create=lambda **kwargs: response), + ) + monkeypatch.setattr( + "volcenginesdkarkruntime.Ark", + lambda **kwargs: fake_client, + ) + + telemetry = MemoryOperationTelemetry(operation="search.find", enabled=True) + with bind_telemetry(telemetry): + embedder = VolcengineDenseEmbedder( + model_name="doubao-embedding-vision-250615", + api_key="test", + input_type="multimodal", + dimension=3, + ) + result = embedder.embed("hello") + + assert result.dense_vector == [0.4, 0.5, 0.6] + summary = telemetry.finish().summary + assert summary["tokens"]["embedding"] == {"total": 16} diff --git a/tests/models/test_vlm_strip_think_tags.py b/tests/models/test_vlm_strip_think_tags.py new file mode 100644 index 00000000..fd47fa1c --- /dev/null +++ b/tests/models/test_vlm_strip_think_tags.py @@ -0,0 +1,85 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for stripping reasoning tags from VLM responses.""" + +import pytest + +from openviking.models.vlm.base import _THINK_TAG_RE, VLMBase + + +class TestStripThinkTags: + """Test _clean_response strips blocks correctly.""" + + @pytest.fixture() + def vlm(self): + """Create a minimal concrete VLMBase for testing.""" + + class _Stub(VLMBase): + def get_completion(self, prompt, thinking=False): + return "" + + async def get_completion_async(self, prompt, thinking=False, max_retries=0): + return "" + + def get_vision_completion(self, prompt, images, thinking=False): + return "" + + async def get_vision_completion_async(self, prompt, images, thinking=False): + return "" + + return _Stub({"api_key": "test"}) + + def test_no_think_tags(self, vlm): + text = "This is a normal response." + assert vlm._clean_response(text) == "This is a normal response." + + def test_single_think_block(self, vlm): + text = "\nI need to analyze this.\n\nThe actual summary." + assert vlm._clean_response(text) == "The actual summary." + + def test_think_block_at_end(self, vlm): + text = "Summary text.\nsome reasoning" + assert vlm._clean_response(text) == "Summary text." + + def test_think_block_in_middle(self, vlm): + text = "Start.reasoning hereEnd." + assert vlm._clean_response(text) == "Start.End." + + def test_multiple_think_blocks(self, vlm): + text = "firstHellosecond world" + assert vlm._clean_response(text) == "Hello world" + + def test_multiline_think_block(self, vlm): + text = ( + "\nStep 1: analyze the document\n" + "Step 2: summarize\nStep 3: output\n\n" + "# Directory Overview\n\nThis directory contains..." + ) + result = vlm._clean_response(text) + assert result.startswith("# Directory Overview") + assert "" not in result + + def test_empty_string(self, vlm): + assert vlm._clean_response("") == "" + + def test_only_think_block(self, vlm): + text = "all reasoning, no output" + assert vlm._clean_response(text) == "" + + def test_nested_angle_brackets_preserved(self, vlm): + text = "Use bold and italic formatting." + assert vlm._clean_response(text) == text + + def test_json_with_think_prefix(self, vlm): + text = 'let me think\n{"abstract": "summary", "overview": "details"}' + result = vlm._clean_response(text) + assert result == '{"abstract": "summary", "overview": "details"}' + + +class TestThinkTagRegex: + """Test the compiled regex pattern directly.""" + + def test_greedy_minimal(self): + """Ensure non-greedy matching: each ... is matched individually.""" + text = "aKEEPb" + assert _THINK_TAG_RE.sub("", text) == "KEEP" diff --git a/tests/parse/test_url_filename_preservation.py b/tests/parse/test_url_filename_preservation.py new file mode 100644 index 00000000..42a62ac6 --- /dev/null +++ b/tests/parse/test_url_filename_preservation.py @@ -0,0 +1,120 @@ +"""Tests for URL filename preservation when importing resources via URL. + +Verifies fix for https://github.com/volcengine/OpenViking/issues/251: +- Original filename preserved (not temp file name) +- File extension preserved (.py stays .py, not converted to .md) +- URL-encoded characters decoded properly +- Code file extensions routed to download, not webpage parse +""" + +import pytest + +from openviking.parse.parsers.html import HTMLParser, URLType, URLTypeDetector + + +class TestExtractFilenameFromUrl: + """Test HTMLParser._extract_filename_from_url.""" + + def test_simple_filename(self): + url = "https://example.com/path/to/schemas.py" + assert HTMLParser._extract_filename_from_url(url) == "schemas.py" + + def test_url_encoded_path(self): + url = "https://example.com/%E7%99%BE%E5%BA%A64/src/baidu_search/schemas.py" + assert HTMLParser._extract_filename_from_url(url) == "schemas.py" + + def test_url_encoded_filename(self): + url = "https://example.com/path/%E6%96%87%E4%BB%B6.py" + assert HTMLParser._extract_filename_from_url(url) == "\u6587\u4ef6.py" + + def test_query_params_ignored(self): + url = "https://example.com/file.py?version=2&token=abc" + assert HTMLParser._extract_filename_from_url(url) == "file.py" + + def test_no_filename_fallback(self): + url = "https://example.com/" + assert HTMLParser._extract_filename_from_url(url) == "download" + + def test_cos_url(self): + url = ( + "https://cos.ap-beijing.myqcloud.com/bucket/" + "%E7%99%BE%E5%BA%A64/src/baidu_search/schemas.py" + ) + assert HTMLParser._extract_filename_from_url(url) == "schemas.py" + + def test_markdown_extension(self): + url = "https://example.com/docs/README.md" + assert HTMLParser._extract_filename_from_url(url) == "README.md" + + def test_no_extension(self): + url = "https://example.com/path/Makefile" + assert HTMLParser._extract_filename_from_url(url) == "Makefile" + + +class TestURLTypeDetectorCodeExtensions: + """Test that code file extensions are routed to DOWNLOAD_TXT, not WEBPAGE.""" + + def setup_method(self): + self.detector = URLTypeDetector() + + @pytest.mark.asyncio + async def test_py_extension_detected(self): + url = "https://example.com/path/schemas.py" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_TXT + assert meta["detected_by"] == "extension" + + @pytest.mark.asyncio + async def test_js_extension_detected(self): + url = "https://example.com/path/index.js" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_TXT + + @pytest.mark.asyncio + async def test_yaml_extension_detected(self): + url = "https://example.com/config.yaml" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_TXT + + @pytest.mark.asyncio + async def test_json_extension_detected(self): + url = "https://example.com/data.json" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_TXT + + @pytest.mark.asyncio + async def test_go_extension_detected(self): + url = "https://example.com/main.go" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_TXT + + @pytest.mark.asyncio + async def test_rs_extension_detected(self): + url = "https://example.com/lib.rs" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_TXT + + @pytest.mark.asyncio + async def test_url_encoded_py_extension(self): + url = "https://example.com/%E7%99%BE%E5%BA%A64/src/schemas.py" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_TXT + + @pytest.mark.asyncio + async def test_md_still_routes_to_markdown(self): + url = "https://example.com/README.md" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_MD + + @pytest.mark.asyncio + async def test_pdf_still_routes_to_pdf(self): + url = "https://example.com/paper.pdf" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_PDF + + @pytest.mark.asyncio + async def test_html_still_routes_to_download_html(self): + """Ensure .html overrides CODE_EXTENSIONS mapping to DOWNLOAD_TXT.""" + url = "https://example.com/page.html" + url_type, meta = await self.detector.detect(url) + assert url_type == URLType.DOWNLOAD_HTML diff --git a/tests/resource/__init__.py b/tests/resource/__init__.py new file mode 100644 index 00000000..f0561357 --- /dev/null +++ b/tests/resource/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for resource monitoring module.""" diff --git a/tests/resource/test_watch_manager.py b/tests/resource/test_watch_manager.py new file mode 100644 index 00000000..f6252045 --- /dev/null +++ b/tests/resource/test_watch_manager.py @@ -0,0 +1,689 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Unit tests for WatchManager.""" + +import asyncio +import json +from datetime import datetime, timedelta +from pathlib import Path +from typing import AsyncGenerator + +import pytest +import pytest_asyncio + +from openviking.resource.watch_manager import WatchManager, WatchTask +from openviking_cli.exceptions import ConflictError +from tests.utils.mock_agfs import MockLocalAGFS + +TEST_ACCOUNT_ID = "default" +TEST_USER_ID = "default" +TEST_ROLE = "ROOT" + + +class MockVikingFS: + """Mock VikingFS for testing.""" + + def __init__(self, root_path: str): + self.agfs = MockLocalAGFS(root_path=root_path) + self._storage_data = {} + + async def read_file(self, uri: str, ctx=None) -> str: + """Read file from storage.""" + path = self._uri_to_path(uri) + content = self.agfs.read(path) + if isinstance(content, bytes): + return content.decode("utf-8") + return content + + async def write_file(self, uri: str, content: str, ctx=None) -> None: + """Write file to storage.""" + path = self._uri_to_path(uri) + self.agfs.write(path, content.encode("utf-8")) + + def _uri_to_path(self, uri: str) -> str: + """Convert URI to path.""" + if uri.startswith("viking://"): + return uri.replace("viking://", "/local/default/") + return uri + + +@pytest_asyncio.fixture +async def temp_storage(tmp_path: Path) -> AsyncGenerator[Path, None]: + """Create temporary storage directory.""" + storage_dir = tmp_path / "watch_storage" + storage_dir.mkdir(parents=True, exist_ok=True) + yield storage_dir + + +@pytest_asyncio.fixture +async def mock_viking_fs(temp_storage: Path) -> MockVikingFS: + """Create mock VikingFS instance.""" + return MockVikingFS(root_path=str(temp_storage)) + + +@pytest_asyncio.fixture +async def watch_manager(mock_viking_fs: MockVikingFS) -> AsyncGenerator[WatchManager, None]: + """Create WatchManager instance with mock VikingFS.""" + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + yield manager + await manager.clear_all_tasks() + + +@pytest_asyncio.fixture +async def watch_manager_no_fs() -> AsyncGenerator[WatchManager, None]: + """Create WatchManager instance without VikingFS.""" + manager = WatchManager(viking_fs=None) + await manager.initialize() + yield manager + await manager.clear_all_tasks() + + +class TestWatchTask: + """Tests for WatchTask data model.""" + + def test_create_task_with_defaults(self): + """Test creating a task with default values.""" + task = WatchTask(path="/test/path") + + assert task.path == "/test/path" + assert task.task_id is not None + assert task.to_uri is None + assert task.parent_uri is None + assert task.reason == "" + assert task.instruction == "" + assert task.watch_interval == 60.0 + assert task.is_active is True + assert task.created_at is not None + assert task.last_execution_time is None + assert task.next_execution_time is None + + def test_create_task_with_all_fields(self): + """Test creating a task with all fields specified.""" + now = datetime.now() + task = WatchTask( + task_id="test-task-id", + path="/test/path", + to_uri="viking://resources/test", + parent_uri="viking://resources", + reason="Test reason", + instruction="Test instruction", + watch_interval=30.0, + created_at=now, + last_execution_time=now, + next_execution_time=now + timedelta(minutes=30), + is_active=False, + ) + + assert task.task_id == "test-task-id" + assert task.path == "/test/path" + assert task.to_uri == "viking://resources/test" + assert task.parent_uri == "viking://resources" + assert task.reason == "Test reason" + assert task.instruction == "Test instruction" + assert task.watch_interval == 30.0 + assert task.is_active is False + assert task.created_at == now + assert task.last_execution_time == now + + def test_to_dict(self): + """Test converting task to dictionary.""" + now = datetime.now() + task = WatchTask( + task_id="test-id", + path="/test/path", + to_uri="viking://test", + created_at=now, + ) + + data = task.to_dict() + + assert data["task_id"] == "test-id" + assert data["path"] == "/test/path" + assert data["to_uri"] == "viking://test" + assert data["created_at"] == now.isoformat() + assert data["is_active"] is True + + def test_from_dict(self): + """Test creating task from dictionary.""" + now = datetime.now() + data = { + "task_id": "test-id", + "path": "/test/path", + "to_uri": "viking://test", + "parent_uri": "viking://parent", + "reason": "Test", + "instruction": "Instruction", + "watch_interval": 45.0, + "created_at": now.isoformat(), + "last_execution_time": now.isoformat(), + "next_execution_time": (now + timedelta(minutes=45)).isoformat(), + "is_active": False, + } + + task = WatchTask.from_dict(data) + + assert task.task_id == "test-id" + assert task.path == "/test/path" + assert task.to_uri == "viking://test" + assert task.watch_interval == 45.0 + assert task.is_active is False + assert task.created_at == now + assert task.last_execution_time == now + + def test_calculate_next_execution_time(self): + """Test calculating next execution time.""" + now = datetime.now() + task = WatchTask( + path="/test", + watch_interval=30.0, + created_at=now, + ) + + next_time = task.calculate_next_execution_time() + + expected = now + timedelta(minutes=30.0) + assert abs((next_time - expected).total_seconds()) < 1 + + def test_calculate_next_execution_time_with_last_execution(self): + """Test calculating next execution time based on last execution.""" + now = datetime.now() + last_exec = now - timedelta(minutes=10) + task = WatchTask( + path="/test", + watch_interval=30.0, + created_at=now - timedelta(hours=1), + last_execution_time=last_exec, + ) + + next_time = task.calculate_next_execution_time() + + expected = last_exec + timedelta(minutes=30.0) + assert abs((next_time - expected).total_seconds()) < 1 + + +class TestWatchManager: + """Tests for WatchManager.""" + + @pytest.mark.asyncio + async def test_create_task(self, watch_manager: WatchManager): + """Test creating a task.""" + task = await watch_manager.create_task( + path="/test/path", + to_uri="viking://resources/test", + reason="Test task", + watch_interval=30.0, + ) + + assert task.path == "/test/path" + assert task.to_uri == "viking://resources/test" + assert task.reason == "Test task" + assert task.watch_interval == 30.0 + assert task.is_active is True + assert task.next_execution_time is not None + + @pytest.mark.asyncio + async def test_create_task_without_path_raises(self, watch_manager: WatchManager): + """Test that creating a task without path raises error.""" + with pytest.raises(ValueError, match="Path is required"): + await watch_manager.create_task(path="") + + @pytest.mark.asyncio + async def test_create_task_with_conflicting_uri(self, watch_manager: WatchManager): + """Test that creating a task with conflicting URI raises error.""" + await watch_manager.create_task( + path="/test/path1", + to_uri="viking://resources/test", + ) + + with pytest.raises(ConflictError, match="already used by another task"): + await watch_manager.create_task( + path="/test/path2", + to_uri="viking://resources/test", + ) + + @pytest.mark.asyncio + async def test_update_task(self, watch_manager: WatchManager): + """Test updating a task.""" + task = await watch_manager.create_task( + path="/test/path", + reason="Original reason", + ) + + updated = await watch_manager.update_task( + task_id=task.task_id, + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + reason="Updated reason", + watch_interval=45.0, + is_active=False, + ) + + assert updated.reason == "Updated reason" + assert updated.watch_interval == 45.0 + assert updated.is_active is False + assert updated.next_execution_time is None + + @pytest.mark.asyncio + async def test_update_task_not_found(self, watch_manager: WatchManager): + """Test updating a non-existent task.""" + with pytest.raises(ValueError, match="not found"): + await watch_manager.update_task( + task_id="non-existent-id", + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + reason="Updated", + ) + + @pytest.mark.asyncio + async def test_update_task_with_conflicting_uri(self, watch_manager: WatchManager): + """Test updating a task with conflicting URI.""" + await watch_manager.create_task( + path="/test/path1", + to_uri="viking://resources/test1", + ) + task2 = await watch_manager.create_task( + path="/test/path2", + to_uri="viking://resources/test2", + ) + + with pytest.raises(ConflictError, match="already used by another task"): + await watch_manager.update_task( + task_id=task2.task_id, + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + to_uri="viking://resources/test1", + ) + + @pytest.mark.asyncio + async def test_delete_task(self, watch_manager: WatchManager): + """Test deleting a task.""" + task = await watch_manager.create_task( + path="/test/path", + to_uri="viking://resources/test", + ) + + result = await watch_manager.delete_task( + task_id=task.task_id, + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + + assert result is True + + retrieved = await watch_manager.get_task(task.task_id) + assert retrieved is None + + uri_task = await watch_manager.get_task_by_uri( + to_uri="viking://resources/test", + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + assert uri_task is None + + @pytest.mark.asyncio + async def test_delete_task_not_found(self, watch_manager: WatchManager): + """Test deleting a non-existent task.""" + result = await watch_manager.delete_task( + task_id="non-existent-id", + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + assert result is False + + @pytest.mark.asyncio + async def test_get_task(self, watch_manager: WatchManager): + """Test getting a task by ID.""" + task = await watch_manager.create_task(path="/test/path") + + retrieved = await watch_manager.get_task(task.task_id) + + assert retrieved is not None + assert retrieved.task_id == task.task_id + assert retrieved.path == "/test/path" + + @pytest.mark.asyncio + async def test_get_task_not_found(self, watch_manager: WatchManager): + """Test getting a non-existent task.""" + retrieved = await watch_manager.get_task("non-existent-id") + assert retrieved is None + + @pytest.mark.asyncio + async def test_get_all_tasks(self, watch_manager: WatchManager): + """Test getting all tasks.""" + await watch_manager.create_task(path="/test/path1") + await watch_manager.create_task(path="/test/path2") + await watch_manager.create_task(path="/test/path3") + + tasks = await watch_manager.get_all_tasks( + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + + assert len(tasks) == 3 + + @pytest.mark.asyncio + async def test_get_all_tasks_active_only(self, watch_manager: WatchManager): + """Test getting only active tasks.""" + task1 = await watch_manager.create_task(path="/test/path1") + await watch_manager.create_task(path="/test/path2") + + await watch_manager.update_task( + task_id=task1.task_id, + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + is_active=False, + ) + + tasks = await watch_manager.get_all_tasks( + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + active_only=True, + ) + + assert len(tasks) == 1 + assert tasks[0].is_active is True + + @pytest.mark.asyncio + async def test_get_task_by_uri(self, watch_manager: WatchManager): + """Test getting a task by URI.""" + task = await watch_manager.create_task( + path="/test/path", + to_uri="viking://resources/test", + ) + + retrieved = await watch_manager.get_task_by_uri( + to_uri="viking://resources/test", + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + + assert retrieved is not None + assert retrieved.task_id == task.task_id + + @pytest.mark.asyncio + async def test_get_task_by_uri_not_found(self, watch_manager: WatchManager): + """Test getting a task by non-existent URI.""" + retrieved = await watch_manager.get_task_by_uri( + to_uri="viking://nonexistent", + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + assert retrieved is None + + @pytest.mark.asyncio + async def test_update_execution_time(self, watch_manager: WatchManager): + """Test updating execution time.""" + task = await watch_manager.create_task( + path="/test/path", + watch_interval=30.0, + ) + + original_next_time = task.next_execution_time + + await asyncio.sleep(0.1) + await watch_manager.update_execution_time(task.task_id) + + updated = await watch_manager.get_task(task.task_id) + assert updated is not None + assert updated.last_execution_time is not None + assert updated.next_execution_time > original_next_time + + @pytest.mark.asyncio + async def test_get_due_tasks(self, watch_manager: WatchManager): + """Test getting due tasks.""" + task1 = await watch_manager.create_task( + path="/test/path1", + watch_interval=0.001, + ) + await watch_manager.create_task( + path="/test/path2", + watch_interval=60.0, + ) + + await asyncio.sleep(0.1) + + due_tasks = await watch_manager.get_due_tasks() + + assert len(due_tasks) == 1 + assert due_tasks[0].task_id == task1.task_id + + @pytest.mark.asyncio + async def test_clear_all_tasks(self, watch_manager: WatchManager): + """Test clearing all tasks.""" + await watch_manager.create_task(path="/test/path1") + await watch_manager.create_task(path="/test/path2") + + count = await watch_manager.clear_all_tasks() + + assert count == 2 + + tasks = await watch_manager.get_all_tasks( + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + assert len(tasks) == 0 + + @pytest.mark.asyncio + async def test_create_task_with_non_positive_interval_raises(self, watch_manager: WatchManager): + with pytest.raises(ValueError, match="watch_interval must be > 0"): + await watch_manager.create_task(path="/test/path", watch_interval=0) + + @pytest.mark.asyncio + async def test_get_next_execution_time(self, watch_manager: WatchManager): + await watch_manager.create_task(path="/test/path1", watch_interval=60.0) + await watch_manager.create_task(path="/test/path2", watch_interval=0.001) + await asyncio.sleep(0.05) + next_time = await watch_manager.get_next_execution_time() + assert next_time is not None + + +class TestWatchManagerPersistence: + """Tests for WatchManager persistence.""" + + @pytest.mark.asyncio + async def test_persistence_save_and_load( + self, mock_viking_fs: MockVikingFS, temp_storage: Path + ): + """Test that tasks are saved and loaded correctly.""" + manager1 = WatchManager(viking_fs=mock_viking_fs) + await manager1.initialize() + + task = await manager1.create_task( + path="/test/path", + to_uri="viking://resources/test", + reason="Test task", + watch_interval=45.0, + ) + task_id = task.task_id + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + + loaded_task = await manager2.get_task(task_id) + + assert loaded_task is not None + assert loaded_task.path == "/test/path" + assert loaded_task.to_uri == "viking://resources/test" + assert loaded_task.reason == "Test task" + assert loaded_task.watch_interval == 45.0 + + @pytest.mark.asyncio + async def test_persistence_without_vikingfs(self, watch_manager_no_fs: WatchManager): + """Test that manager works without VikingFS (no persistence).""" + task = await watch_manager_no_fs.create_task( + path="/test/path", + reason="Test task", + ) + + retrieved = await watch_manager_no_fs.get_task(task.task_id) + assert retrieved is not None + assert retrieved.path == "/test/path" + + @pytest.mark.asyncio + async def test_persistence_after_delete(self, mock_viking_fs: MockVikingFS): + """Test that deleted tasks are removed from persistence.""" + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + + task = await manager.create_task( + path="/test/path", + to_uri="viking://resources/test", + ) + + await manager.delete_task( + task_id=task.task_id, + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + + loaded_task = await manager2.get_task(task.task_id) + assert loaded_task is None + + uri_task = await manager2.get_task_by_uri( + to_uri="viking://resources/test", + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + assert uri_task is None + + @pytest.mark.asyncio + async def test_persistence_backfill_next_execution_time( + self, mock_viking_fs: MockVikingFS, temp_storage: Path + ): + manager1 = WatchManager(viking_fs=mock_viking_fs) + await manager1.initialize() + task = await manager1.create_task( + path="/test/path", + to_uri="viking://resources/test_backfill", + watch_interval=30.0, + ) + + content = await mock_viking_fs.read_file(WatchManager.STORAGE_URI) + data = json.loads(content) + for t in data.get("tasks", []): + if t.get("task_id") == task.task_id: + t["next_execution_time"] = None + break + await mock_viking_fs.write_file(WatchManager.STORAGE_URI, json.dumps(data)) + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + loaded = await manager2.get_task(task.task_id) + assert loaded is not None + assert loaded.is_active is True + assert loaded.next_execution_time is not None + + @pytest.mark.asyncio + async def test_persistence_empty_storage_file_is_ignored(self, mock_viking_fs: MockVikingFS): + path = mock_viking_fs._uri_to_path(WatchManager.STORAGE_URI) + mock_viking_fs.agfs.write(path, b"") + + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + + tasks = await manager.get_all_tasks( + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + assert tasks == [] + + @pytest.mark.asyncio + async def test_persistence_recovers_from_backup_on_corrupt_storage( + self, mock_viking_fs: MockVikingFS + ): + storage_path = mock_viking_fs._uri_to_path(WatchManager.STORAGE_URI) + bak_path = mock_viking_fs._uri_to_path(WatchManager.STORAGE_BAK_URI) + + mock_viking_fs.agfs.write(storage_path, b"") + + task_data = { + "task_id": "bak-task-id", + "path": "/test/bak", + "to_uri": "viking://resources/bak", + "reason": "Backup task", + "instruction": "", + "watch_interval": 60.0, + "created_at": datetime.now().isoformat(), + "last_execution_time": None, + "next_execution_time": None, + "is_active": True, + } + data = {"tasks": [task_data], "updated_at": datetime.now().isoformat()} + mock_viking_fs.agfs.write(bak_path, json.dumps(data).encode("utf-8")) + + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + + loaded = await manager.get_task("bak-task-id") + assert loaded is not None + assert loaded.to_uri == "viking://resources/bak" + + +class TestWatchManagerConcurrency: + """Tests for WatchManager concurrent access.""" + + @pytest.mark.asyncio + async def test_concurrent_task_creation(self, watch_manager: WatchManager): + """Test concurrent task creation.""" + + async def create_task(index: int): + return await watch_manager.create_task( + path=f"/test/path{index}", + to_uri=f"viking://resources/test{index}", + ) + + tasks = await asyncio.gather(*[create_task(i) for i in range(10)]) + + assert len(tasks) == 10 + assert len({task.task_id for task in tasks}) == 10 + + all_tasks = await watch_manager.get_all_tasks( + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + ) + assert len(all_tasks) == 10 + + @pytest.mark.asyncio + async def test_concurrent_read_write(self, watch_manager: WatchManager): + """Test concurrent read and write operations.""" + task = await watch_manager.create_task(path="/test/path") + + async def update_task(index: int): + await watch_manager.update_task( + task_id=task.task_id, + account_id=TEST_ACCOUNT_ID, + user_id=TEST_USER_ID, + role=TEST_ROLE, + reason=f"Update {index}", + ) + + async def read_task(): + return await watch_manager.get_task(task.task_id) + + operations = [update_task(i) for i in range(5)] + [read_task() for _ in range(5)] + results = await asyncio.gather(*operations, return_exceptions=True) + + assert all(not isinstance(r, Exception) for r in results) + + final_task = await watch_manager.get_task(task.task_id) + assert final_task is not None diff --git a/tests/resource/test_watch_scheduler.py b/tests/resource/test_watch_scheduler.py new file mode 100644 index 00000000..89f17f5c --- /dev/null +++ b/tests/resource/test_watch_scheduler.py @@ -0,0 +1,27 @@ +import pytest + +from openviking.resource.watch_scheduler import WatchScheduler +from openviking.service.resource_service import ResourceService + + +class TestWatchSchedulerValidation: + def test_check_interval_must_be_positive(self): + rs = ResourceService() + with pytest.raises(ValueError, match="check_interval must be > 0"): + WatchScheduler(resource_service=rs, check_interval=0) + + def test_max_concurrency_must_be_positive(self): + rs = ResourceService() + with pytest.raises(ValueError, match="max_concurrency must be > 0"): + WatchScheduler(resource_service=rs, max_concurrency=0) + + +class TestWatchSchedulerResourceExistence: + def test_url_like_sources_are_treated_as_existing(self): + rs = ResourceService() + scheduler = WatchScheduler(resource_service=rs, check_interval=1) + assert scheduler._check_resource_exists("http://example.com") is True + assert scheduler._check_resource_exists("https://example.com") is True + assert scheduler._check_resource_exists("git@github.com:org/repo.git") is True + assert scheduler._check_resource_exists("ssh://git@github.com/org/repo.git") is True + assert scheduler._check_resource_exists("git://github.com/org/repo.git") is True diff --git a/tests/retrieve/test_hierarchical_retriever_rerank.py b/tests/retrieve/test_hierarchical_retriever_rerank.py new file mode 100644 index 00000000..a7ead7bc --- /dev/null +++ b/tests/retrieve/test_hierarchical_retriever_rerank.py @@ -0,0 +1,268 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +"""Hierarchical retriever rerank behavior tests.""" + +import pytest + +from openviking.retrieve.hierarchical_retriever import HierarchicalRetriever, RetrieverMode +from openviking.server.identity import RequestContext, Role +from openviking_cli.retrieve.types import ContextType, TypedQuery +from openviking_cli.session.user_id import UserIdentifier +from openviking_cli.utils.config import RerankConfig + + +class DummyEmbedResult: + def __init__(self) -> None: + self.dense_vector = [1.0] + self.sparse_vector = {"hello": 1.0} + + +class DummyEmbedder: + def embed(self, _query: str, is_query: bool = False) -> DummyEmbedResult: + return DummyEmbedResult() + + +class DummyStorage: + def __init__(self) -> None: + self.collection_name = "context" + self.global_search_calls = [] + self.child_search_calls = [] + + async def collection_exists_bound(self) -> bool: + return True + + async def search_global_roots_in_tenant( + self, + ctx, + query_vector=None, + sparse_query_vector=None, + context_type=None, + target_directories=None, + extra_filter=None, + limit: int = 10, + ): + self.global_search_calls.append( + { + "ctx": ctx, + "query_vector": query_vector, + "sparse_query_vector": sparse_query_vector, + "context_type": context_type, + "target_directories": target_directories, + "extra_filter": extra_filter, + "limit": limit, + } + ) + return [ + { + "uri": "viking://resources/root-a", + "abstract": "root A", + "_score": 0.2, + "level": 1, + "context_type": "resource", + }, + { + "uri": "viking://resources/root-b", + "abstract": "root B", + "_score": 0.8, + "level": 1, + "context_type": "resource", + }, + ] + + async def search_children_in_tenant( + self, + ctx, + parent_uri: str, + query_vector=None, + sparse_query_vector=None, + context_type=None, + target_directories=None, + extra_filter=None, + limit: int = 10, + ): + self.child_search_calls.append( + { + "ctx": ctx, + "parent_uri": parent_uri, + "query_vector": query_vector, + "sparse_query_vector": sparse_query_vector, + "context_type": context_type, + "target_directories": target_directories, + "extra_filter": extra_filter, + "limit": limit, + } + ) + if parent_uri == "viking://resources": + return [ + { + "uri": "viking://resources/file-a", + "abstract": "child A", + "_score": 0.2, + "level": 2, + "context_type": "resource", + "category": "doc", + }, + { + "uri": "viking://resources/file-b", + "abstract": "child B", + "_score": 0.8, + "level": 2, + "context_type": "resource", + "category": "doc", + }, + ] + return [] + + +class FakeRerankClient: + def __init__(self, scores): + self.scores = list(scores) + self.calls = [] + self._cursor = 0 + + def rerank_batch(self, query: str, documents: list[str]): + self.calls.append((query, list(documents))) + start = self._cursor + end = start + len(documents) + self._cursor = end + return list(self.scores[start:end]) + + +def _ctx() -> RequestContext: + return RequestContext(user=UserIdentifier("acc1", "user1", "agent1"), role=Role.USER) + + +def _query() -> TypedQuery: + return TypedQuery(query="hello", context_type=ContextType.RESOURCE, intent="") + + +def _config() -> RerankConfig: + return RerankConfig(ak="ak", sk="sk", threshold=0.1) + + +@pytest.fixture(autouse=True) +def _disable_viking_fs(monkeypatch): + monkeypatch.setattr("openviking.retrieve.hierarchical_retriever.get_viking_fs", lambda: None) + + +def test_retriever_initializes_rerank_client(monkeypatch): + fake_client = FakeRerankClient([0.9, 0.1]) + + monkeypatch.setattr( + "openviking.retrieve.hierarchical_retriever.RerankClient.from_config", + lambda config: fake_client, + ) + + retriever = HierarchicalRetriever( + storage=DummyStorage(), + embedder=DummyEmbedder(), + rerank_config=_config(), + ) + + assert retriever._rerank_client is fake_client + + +def test_merge_starting_points_prefers_rerank_scores_in_thinking_mode(monkeypatch): + fake_client = FakeRerankClient([0.95, 0.05]) + monkeypatch.setattr( + "openviking.retrieve.hierarchical_retriever.RerankClient.from_config", + lambda config: fake_client, + ) + + retriever = HierarchicalRetriever( + storage=DummyStorage(), + embedder=DummyEmbedder(), + rerank_config=_config(), + ) + + starting_points = retriever._merge_starting_points( + "hello", + ["viking://resources"], + [ + {"uri": "viking://resources/root-a", "abstract": "root A", "_score": 0.2, "level": 1}, + {"uri": "viking://resources/root-b", "abstract": "root B", "_score": 0.8, "level": 1}, + ], + mode=RetrieverMode.THINKING, + ) + + assert starting_points[:2] == [ + ("viking://resources/root-a", 0.95), + ("viking://resources/root-b", 0.05), + ] + assert fake_client.calls == [("hello", ["root A", "root B"])] + + +@pytest.mark.asyncio +async def test_retrieve_uses_rerank_scores_in_thinking_mode(monkeypatch): + fake_client = FakeRerankClient([0.95, 0.05, 0.11, 0.95]) + monkeypatch.setattr( + "openviking.retrieve.hierarchical_retriever.RerankClient.from_config", + lambda config: fake_client, + ) + + retriever = HierarchicalRetriever( + storage=DummyStorage(), + embedder=DummyEmbedder(), + rerank_config=_config(), + ) + + result = await retriever.retrieve(_query(), ctx=_ctx(), limit=2, mode=RetrieverMode.THINKING) + + assert [ctx.uri for ctx in result.matched_contexts] == [ + "viking://resources/file-b", + "viking://resources/file-a", + ] + assert fake_client.calls[0] == ("hello", ["root A", "root B"]) + assert fake_client.calls[1] == ("hello", ["child A", "child B"]) + + +@pytest.mark.asyncio +async def test_retrieve_falls_back_to_vector_scores_when_rerank_returns_none(monkeypatch): + class NoneRerankClient(FakeRerankClient): + def rerank_batch(self, query: str, documents: list[str]): + self.calls.append((query, list(documents))) + return None + + fake_client = NoneRerankClient([]) + monkeypatch.setattr( + "openviking.retrieve.hierarchical_retriever.RerankClient.from_config", + lambda config: fake_client, + ) + + retriever = HierarchicalRetriever( + storage=DummyStorage(), + embedder=DummyEmbedder(), + rerank_config=_config(), + ) + + result = await retriever.retrieve(_query(), ctx=_ctx(), limit=2, mode=RetrieverMode.THINKING) + + assert [ctx.uri for ctx in result.matched_contexts] == [ + "viking://resources/file-b", + "viking://resources/file-a", + ] + assert fake_client.calls + + +@pytest.mark.asyncio +async def test_quick_mode_skips_rerank(monkeypatch): + fake_client = FakeRerankClient([0.95, 0.05, 0.05, 0.95]) + monkeypatch.setattr( + "openviking.retrieve.hierarchical_retriever.RerankClient.from_config", + lambda config: fake_client, + ) + + retriever = HierarchicalRetriever( + storage=DummyStorage(), + embedder=DummyEmbedder(), + rerank_config=_config(), + ) + + result = await retriever.retrieve(_query(), ctx=_ctx(), limit=2, mode=RetrieverMode.QUICK) + + assert [ctx.uri for ctx in result.matched_contexts] == [ + "viking://resources/file-b", + "viking://resources/file-a", + ] + assert fake_client.calls == [] diff --git a/tests/server/conftest.py b/tests/server/conftest.py index c38c7eab..3bc0e40f 100644 --- a/tests/server/conftest.py +++ b/tests/server/conftest.py @@ -15,11 +15,15 @@ import uvicorn from openviking import AsyncOpenViking +from openviking.models.embedder.base import DenseEmbedderBase, EmbedResult from openviking.server.app import create_app from openviking.server.config import ServerConfig from openviking.server.identity import RequestContext, Role from openviking.service.core import OpenVikingService +from openviking.storage.transaction import reset_lock_manager from openviking_cli.session.user_id import UserIdentifier +from openviking_cli.utils.config.embedding_config import EmbeddingConfig +from openviking_cli.utils.config.vlm_config import VLMConfig # --------------------------------------------------------------------------- # Paths @@ -44,6 +48,41 @@ """ +def _install_fake_embedder(monkeypatch): + """Use an in-process fake embedder so server tests never hit external APIs.""" + dimension = 2048 + + class FakeEmbedder(DenseEmbedderBase): + def __init__(self): + super().__init__(model_name="test-fake-embedder") + + def embed(self, text: str, is_query: bool = False) -> EmbedResult: + return EmbedResult(dense_vector=[0.1] * dimension) + + def embed_batch(self, texts: list[str], is_query: bool = False) -> list[EmbedResult]: + return [self.embed(text, is_query=is_query) for text in texts] + + def get_dimension(self) -> int: + return dimension + + monkeypatch.setattr(EmbeddingConfig, "get_embedder", lambda self: FakeEmbedder()) + return FakeEmbedder + + +def _install_fake_vlm(monkeypatch): + """Use a fake VLM so server tests never hit external LLM APIs.""" + + async def _fake_get_completion(self, prompt, thinking=False, max_retries=0): + return "# Test Summary\n\nFake summary for testing.\n\n## Details\nTest content." + + async def _fake_get_vision_completion(self, prompt, images, thinking=False): + return "Fake image description for testing." + + monkeypatch.setattr(VLMConfig, "is_available", lambda self: True) + monkeypatch.setattr(VLMConfig, "get_completion_async", _fake_get_completion) + monkeypatch.setattr(VLMConfig, "get_vision_completion_async", _fake_get_vision_completion) + + # --------------------------------------------------------------------------- # Core fixtures: service + app + async client (HTTP API tests, in-process) # --------------------------------------------------------------------------- @@ -69,14 +108,19 @@ def sample_markdown_file(temp_dir: Path) -> Path: @pytest_asyncio.fixture(scope="function") -async def service(temp_dir: Path): +async def service(temp_dir: Path, monkeypatch): """Create and initialize an OpenVikingService in embedded mode.""" + reset_lock_manager() + fake_embedder_cls = _install_fake_embedder(monkeypatch) + _install_fake_vlm(monkeypatch) svc = OpenVikingService( path=str(temp_dir / "data"), user=UserIdentifier.the_default_user("test_user") ) await svc.initialize() + svc.viking_fs.query_embedder = fake_embedder_cls() yield svc await svc.close() + reset_lock_manager() @pytest_asyncio.fixture(scope="function") @@ -118,14 +162,18 @@ async def client_with_resource(client, service, sample_markdown_file): @pytest_asyncio.fixture(scope="function") -async def running_server(temp_dir: Path): +async def running_server(temp_dir: Path, monkeypatch): """Start a real uvicorn server in a background thread.""" await AsyncOpenViking.reset() + reset_lock_manager() + fake_embedder_cls = _install_fake_embedder(monkeypatch) + _install_fake_vlm(monkeypatch) svc = OpenVikingService( path=str(temp_dir / "sdk_data"), user=UserIdentifier.the_default_user("sdk_test_user") ) await svc.initialize() + svc.viking_fs.query_embedder = fake_embedder_cls() config = ServerConfig() fastapi_app = create_app(config=config, service=svc) diff --git a/tests/server/test_api_content.py b/tests/server/test_api_content.py index e7f2970b..7e0a2eff 100644 --- a/tests/server/test_api_content.py +++ b/tests/server/test_api_content.py @@ -41,3 +41,45 @@ async def test_overview_content(client_with_resource): assert resp.status_code == 200 body = resp.json() assert body["status"] == "ok" + + +async def test_reindex_missing_uri(client): + """Test reindex without uri field returns 422.""" + resp = await client.post( + "/api/v1/content/reindex", + json={"regenerate": False}, + ) + assert resp.status_code == 422 + + +async def test_reindex_endpoint_registered(client): + """Test the reindex endpoint is registered (GET returns 405, not 404).""" + resp = await client.get("/api/v1/content/reindex") + assert resp.status_code == 405 # Method Not Allowed, not 404 + + +async def test_reindex_request_validation(client): + """Test reindex validates the request body schema.""" + # Empty body — uri is required + resp = await client.post("/api/v1/content/reindex", json={}) + assert resp.status_code == 422 + + # Invalid type for regenerate + resp = await client.post( + "/api/v1/content/reindex", + json={"uri": "viking://resources/test", "regenerate": "not_a_bool"}, + ) + # Pydantic coerces strings to bool, so this may or may not fail + assert resp.status_code in (200, 422, 500) + + +async def test_reindex_wait_parameter_schema(client): + """Test reindex accepts wait parameter in request schema.""" + # Invalid wait type should be coerced or rejected, not crash + resp = await client.post( + "/api/v1/content/reindex", + json={"uri": "viking://resources/test", "wait": "invalid"}, + ) + # Pydantic coerces or rejects — either way, not a 404/405 + assert resp.status_code != 404 + assert resp.status_code != 405 diff --git a/tests/server/test_api_filesystem.py b/tests/server/test_api_filesystem.py index 79058d37..3a0da611 100644 --- a/tests/server/test_api_filesystem.py +++ b/tests/server/test_api_filesystem.py @@ -66,14 +66,6 @@ async def test_tree(client: httpx.AsyncClient): assert body["status"] == "ok" -async def test_stat_after_add_resource(client_with_resource): - client, uri = client_with_resource - resp = await client.get("/api/v1/fs/stat", params={"uri": uri}) - assert resp.status_code == 200 - body = resp.json() - assert body["status"] == "ok" - - async def test_stat_not_found(client: httpx.AsyncClient): resp = await client.get( "/api/v1/fs/stat", @@ -84,18 +76,28 @@ async def test_stat_not_found(client: httpx.AsyncClient): assert body["status"] == "error" -async def test_rm_resource(client_with_resource): +async def test_resource_ops(client_with_resource): + """Test stat, ls_recursive, mv, rm on a single shared resource.""" + import uuid + client, uri = client_with_resource - resp = await client.request("DELETE", "/api/v1/fs", params={"uri": uri, "recursive": True}) + + # stat + resp = await client.get("/api/v1/fs/stat", params={"uri": uri}) assert resp.status_code == 200 assert resp.json()["status"] == "ok" + # ls recursive + resp = await client.get( + "/api/v1/fs/ls", + params={"uri": "viking://", "recursive": True}, + ) + assert resp.status_code == 200 + body = resp.json() + assert body["status"] == "ok" + assert isinstance(body["result"], list) -async def test_mv_resource(client_with_resource): - import uuid - - client, uri = client_with_resource - # Use a unique name to avoid conflicts with leftover data + # mv unique = uuid.uuid4().hex[:8] new_uri = uri.rstrip("/") + f"_mv_{unique}/" resp = await client.post( @@ -105,14 +107,7 @@ async def test_mv_resource(client_with_resource): assert resp.status_code == 200 assert resp.json()["status"] == "ok" - -async def test_ls_recursive(client_with_resource): - client, _ = client_with_resource - resp = await client.get( - "/api/v1/fs/ls", - params={"uri": "viking://", "recursive": True}, - ) + # rm (on the moved uri) + resp = await client.request("DELETE", "/api/v1/fs", params={"uri": new_uri, "recursive": True}) assert resp.status_code == 200 - body = resp.json() - assert body["status"] == "ok" - assert isinstance(body["result"], list) + assert resp.json()["status"] == "ok" diff --git a/tests/server/test_api_resources.py b/tests/server/test_api_resources.py index 013c6baa..b6d96785 100644 --- a/tests/server/test_api_resources.py +++ b/tests/server/test_api_resources.py @@ -5,8 +5,6 @@ import httpx -from tests.server.conftest import SAMPLE_MD_CONTENT - async def test_add_resource_success(client: httpx.AsyncClient, sample_markdown_file): resp = await client.post( @@ -20,6 +18,9 @@ async def test_add_resource_success(client: httpx.AsyncClient, sample_markdown_f assert resp.status_code == 200 body = resp.json() assert body["status"] == "ok" + assert "time" not in body + assert "usage" not in body + assert "telemetry" not in body assert "root_uri" in body["result"] assert body["result"]["root_uri"].startswith("viking://") @@ -39,6 +40,70 @@ async def test_add_resource_with_wait(client: httpx.AsyncClient, sample_markdown assert "root_uri" in body["result"] +async def test_add_resource_with_telemetry_wait(client: httpx.AsyncClient, sample_markdown_file): + resp = await client.post( + "/api/v1/resources", + json={ + "path": str(sample_markdown_file), + "reason": "telemetry resource", + "wait": True, + "telemetry": True, + }, + ) + assert resp.status_code == 200 + body = resp.json() + assert body["status"] == "ok" + telemetry_summary = body["telemetry"]["summary"] + assert telemetry_summary["operation"] == "resources.add_resource" + assert "usage" not in body + semantic = telemetry_summary["semantic_nodes"] + assert semantic["total"] is None or semantic["done"] == semantic["total"] + assert semantic["pending"] in (None, 0) + assert semantic["running"] in (None, 0) + assert "memory" not in telemetry_summary + + +async def test_add_resource_with_summary_only_telemetry( + client: httpx.AsyncClient, sample_markdown_file +): + resp = await client.post( + "/api/v1/resources", + json={ + "path": str(sample_markdown_file), + "reason": "summary only telemetry resource", + "wait": True, + "telemetry": {"summary": True}, + }, + ) + assert resp.status_code == 200 + body = resp.json() + assert body["status"] == "ok" + assert "summary" in body["telemetry"] + assert "usage" not in body + assert "events" not in body["telemetry"] + assert "truncated" not in body["telemetry"] + assert "dropped" not in body["telemetry"] + + +async def test_add_resource_rejects_events_only_telemetry( + client: httpx.AsyncClient, sample_markdown_file +): + resp = await client.post( + "/api/v1/resources", + json={ + "path": str(sample_markdown_file), + "reason": "events only telemetry", + "wait": False, + "telemetry": {"summary": False, "events": True}, + }, + ) + assert resp.status_code == 400 + body = resp.json() + assert body["status"] == "error" + assert body["error"]["code"] == "INVALID_ARGUMENT" + assert "events" in body["error"]["message"] + + async def test_add_resource_file_not_found(client: httpx.AsyncClient): resp = await client.post( "/api/v1/resources", @@ -50,12 +115,12 @@ async def test_add_resource_file_not_found(client: httpx.AsyncClient): assert "errors" in body["result"] and len(body["result"]["errors"]) > 0 -async def test_add_resource_with_target(client: httpx.AsyncClient, sample_markdown_file): +async def test_add_resource_with_to(client: httpx.AsyncClient, sample_markdown_file): resp = await client.post( "/api/v1/resources", json={ "path": str(sample_markdown_file), - "target": "viking://resources/custom/", + "to": "viking://resources/custom/sample", "reason": "test resource", }, ) @@ -86,3 +151,34 @@ async def test_wait_processed_after_add(client: httpx.AsyncClient, sample_markdo ) assert resp.status_code == 200 assert resp.json()["status"] == "ok" + + +async def test_add_resource_with_watch_interval(client: httpx.AsyncClient, sample_markdown_file): + resp = await client.post( + "/api/v1/resources", + json={ + "path": str(sample_markdown_file), + "reason": "test resource with watch interval", + "watch_interval": 5.0, + }, + ) + assert resp.status_code == 200 + body = resp.json() + assert body["status"] == "ok" + assert "root_uri" in body["result"] + + +async def test_add_resource_with_default_watch_interval( + client: httpx.AsyncClient, sample_markdown_file +): + resp = await client.post( + "/api/v1/resources", + json={ + "path": str(sample_markdown_file), + "reason": "test resource with default watch interval", + }, + ) + assert resp.status_code == 200 + body = resp.json() + assert body["status"] == "ok" + assert "root_uri" in body["result"] diff --git a/tests/server/test_api_search.py b/tests/server/test_api_search.py index 834c0437..ce33773c 100644 --- a/tests/server/test_api_search.py +++ b/tests/server/test_api_search.py @@ -4,6 +4,18 @@ """Tests for search endpoints: find, search, grep, glob.""" import httpx +import pytest + +from openviking.models.embedder.base import EmbedResult + + +@pytest.fixture(autouse=True) +def fake_query_embedder(service): + class FakeEmbedder: + def embed(self, text: str, is_query: bool = False) -> EmbedResult: + return EmbedResult(dense_vector=[0.1, 0.2, 0.3]) + + service.viking_fs.query_embedder = FakeEmbedder() async def test_find_basic(client_with_resource): @@ -16,6 +28,8 @@ async def test_find_basic(client_with_resource): body = resp.json() assert body["status"] == "ok" assert body["result"] is not None + assert "usage" not in body + assert "telemetry" not in body async def test_find_with_target_uri(client_with_resource): @@ -81,6 +95,80 @@ async def test_search_with_session(client_with_resource): assert resp.json()["status"] == "ok" +async def test_find_telemetry_metrics(client_with_resource): + client, _ = client_with_resource + resp = await client.post( + "/api/v1/search/find", + json={"query": "sample document", "limit": 5, "telemetry": True}, + ) + assert resp.status_code == 200 + body = resp.json() + summary = body["telemetry"]["summary"] + assert summary["operation"] == "search.find" + assert "duration_ms" in summary + assert {"total", "llm", "embedding"}.issubset(summary["tokens"].keys()) + assert "vector" in summary + assert summary["vector"]["searches"] >= 0 + assert "queue" not in summary + assert "semantic_nodes" not in summary + assert "memory" not in summary + assert "usage" not in body + assert body["telemetry"]["id"] + assert body["telemetry"]["id"].startswith("tm_") + + +async def test_search_telemetry_metrics(client_with_resource): + client, _ = client_with_resource + resp = await client.post( + "/api/v1/search/search", + json={"query": "sample document", "limit": 5, "telemetry": True}, + ) + assert resp.status_code == 200 + body = resp.json() + summary = body["telemetry"]["summary"] + assert summary["operation"] == "search.search" + assert summary["vector"]["returned"] >= 0 + assert "queue" not in summary + assert "semantic_nodes" not in summary + assert "memory" not in summary + + +async def test_find_summary_only_telemetry(client_with_resource): + client, _ = client_with_resource + resp = await client.post( + "/api/v1/search/find", + json={ + "query": "sample document", + "limit": 5, + "telemetry": {"summary": True}, + }, + ) + assert resp.status_code == 200 + body = resp.json() + assert body["telemetry"]["summary"]["operation"] == "search.find" + assert "usage" not in body + assert "events" not in body["telemetry"] + assert "truncated" not in body["telemetry"] + assert "dropped" not in body["telemetry"] + + +async def test_find_rejects_events_telemetry_request(client_with_resource): + client, _ = client_with_resource + resp = await client.post( + "/api/v1/search/find", + json={ + "query": "sample document", + "limit": 5, + "telemetry": {"summary": False, "events": True}, + }, + ) + assert resp.status_code == 400 + body = resp.json() + assert body["status"] == "error" + assert body["error"]["code"] == "INVALID_ARGUMENT" + assert "events" in body["error"]["message"] + + async def test_grep(client_with_resource): client, uri = client_with_resource parent_uri = "/".join(uri.split("/")[:-1]) + "/" diff --git a/tests/server/test_api_sessions.py b/tests/server/test_api_sessions.py index 413907d3..370e71cf 100644 --- a/tests/server/test_api_sessions.py +++ b/tests/server/test_api_sessions.py @@ -142,7 +142,55 @@ async def test_compress_session(client: httpx.AsyncClient): resp = await client.post(f"/api/v1/sessions/{session_id}/commit") assert resp.status_code == 200 - assert resp.json()["status"] == "ok" + body = resp.json() + assert body["status"] == "ok" + assert "usage" not in body + assert "telemetry" not in body + + +async def test_compress_session_with_telemetry(client: httpx.AsyncClient): + create_resp = await client.post("/api/v1/sessions", json={}) + session_id = create_resp.json()["result"]["session_id"] + await client.post( + f"/api/v1/sessions/{session_id}/messages", + json={"role": "user", "content": "Trace this commit"}, + ) + + resp = await client.post( + f"/api/v1/sessions/{session_id}/commit", + json={"telemetry": True}, + ) + assert resp.status_code == 200 + body = resp.json() + assert body["status"] == "ok" + summary = body["telemetry"]["summary"] + assert summary["operation"] == "session.commit" + assert {"total", "llm", "embedding"}.issubset(summary["tokens"].keys()) + assert summary["memory"]["extracted"] is not None + assert "semantic_nodes" not in summary + assert "usage" not in body + + +async def test_compress_session_with_summary_only_telemetry(client: httpx.AsyncClient): + create_resp = await client.post("/api/v1/sessions", json={}) + session_id = create_resp.json()["result"]["session_id"] + await client.post( + f"/api/v1/sessions/{session_id}/messages", + json={"role": "user", "content": "Summary only telemetry"}, + ) + + resp = await client.post( + f"/api/v1/sessions/{session_id}/commit", + json={"telemetry": {"summary": True}}, + ) + assert resp.status_code == 200 + body = resp.json() + assert body["status"] == "ok" + assert body["telemetry"]["summary"]["operation"] == "session.commit" + assert "usage" not in body + assert "events" not in body["telemetry"] + assert "truncated" not in body["telemetry"] + assert "dropped" not in body["telemetry"] async def test_extract_session_jsonable_regression(client: httpx.AsyncClient, service, monkeypatch): diff --git a/tests/server/test_auth.py b/tests/server/test_auth.py index 70dbc6e8..55913122 100644 --- a/tests/server/test_auth.py +++ b/tests/server/test_auth.py @@ -8,11 +8,19 @@ import httpx import pytest import pytest_asyncio +from fastapi import Depends, FastAPI +from fastapi import Request as FastAPIRequest +from fastapi.responses import JSONResponse +from starlette.requests import Request from openviking.server.app import create_app +from openviking.server.auth import get_request_context, resolve_identity from openviking.server.config import ServerConfig, _is_localhost, validate_server_config from openviking.server.dependencies import set_service +from openviking.server.identity import ResolvedIdentity, Role +from openviking.server.models import ERROR_CODE_TO_HTTP_STATUS, ErrorInfo, Response from openviking.service.core import OpenVikingService +from openviking_cli.exceptions import InvalidArgumentError, OpenVikingError from openviking_cli.session.user_id import UserIdentifier @@ -23,6 +31,93 @@ def _uid() -> str: ROOT_KEY = "root-secret-key-for-testing-only-1234567890abcdef" +def _make_request( + path: str, + headers: dict[str, str] | None = None, + auth_enabled: bool = True, +) -> Request: + """Create a minimal Starlette request for auth dependency tests.""" + raw_headers = [] + for key, value in (headers or {}).items(): + raw_headers.append((key.lower().encode("latin-1"), value.encode("latin-1"))) + app = FastAPI() + if auth_enabled: + # Non-empty api_key_manager means the server is in authenticated mode. + app.state.api_key_manager = object() + scope = { + "type": "http", + "path": path, + "headers": raw_headers, + "app": app, + } + return Request(scope) + + +def _build_auth_http_test_app( + identity: ResolvedIdentity, + auth_enabled: bool = True, +) -> FastAPI: + """Create a lightweight app that exercises auth dependency wiring. + + The full server fixture depends on AGFS native libraries. This helper keeps + the test focused on request auth behavior and the structured HTTP error body. + """ + app = FastAPI() + if auth_enabled: + # Match production auth mode so get_request_context enters the guard path. + app.state.api_key_manager = object() + + @app.exception_handler(OpenVikingError) + async def openviking_error_handler(request: FastAPIRequest, exc: OpenVikingError): + """Mirror the server's JSON error envelope for auth failures.""" + http_status = ERROR_CODE_TO_HTTP_STATUS.get(exc.code, 500) + return JSONResponse( + status_code=http_status, + content=Response( + status="error", + error=ErrorInfo( + code=exc.code, + message=exc.message, + details=exc.details, + ), + ).model_dump(), + ) + + async def _resolve_identity_override() -> ResolvedIdentity: + """Return a fixed identity so tests can isolate request header behavior.""" + return identity + + app.dependency_overrides[resolve_identity] = _resolve_identity_override + + @app.get("/api/v1/fs/ls") + async def fs_ls(ctx=Depends(get_request_context)): + """Expose a tenant-scoped route for auth regression tests.""" + return { + "status": "ok", + "result": { + "account_id": ctx.user.account_id, + "user_id": ctx.user.user_id, + }, + } + + @app.get("/api/v1/observer/system") + async def observer_system(ctx=Depends(get_request_context)): + """Expose a monitoring route that should keep implicit ROOT behavior.""" + return {"status": "ok", "result": {"role": ctx.role.value}} + + @app.post("/api/v1/system/wait") + async def system_wait(ctx=Depends(get_request_context)): + """Expose a non-tenant system route for auth regression tests.""" + return {"status": "ok", "result": {"role": ctx.role.value}} + + @app.get("/api/v1/debug/vector/scroll") + async def debug_vector_scroll(ctx=Depends(get_request_context)): + """Expose a tenant-scoped debug route for auth regression tests.""" + return {"status": "ok", "result": {"role": ctx.role.value}} + + return app + + @pytest_asyncio.fixture(scope="function") async def auth_service(temp_dir): """Service for auth tests.""" @@ -138,21 +233,38 @@ async def test_dev_mode_no_auth(client: httpx.AsyncClient): async def test_auth_on_multiple_endpoints(auth_client: httpx.AsyncClient): - """Multiple protected endpoints should require auth.""" + """Protected endpoints should require auth before any role-specific checks.""" endpoints = [ ("GET", "/api/v1/system/status"), - ("GET", "/api/v1/fs/ls?uri=viking://"), ("GET", "/api/v1/observer/system"), ("GET", "/api/v1/debug/health"), + ("GET", "/api/v1/fs/ls?uri=viking://"), ] for method, url in endpoints: resp = await auth_client.request(method, url) assert resp.status_code == 401, f"{method} {url} should require auth" - for method, url in endpoints: + for method, url in endpoints[:3]: resp = await auth_client.request(method, url, headers={"X-API-Key": ROOT_KEY}) assert resp.status_code == 200, f"{method} {url} should succeed with root key" + tenant_resp = await auth_client.get( + "/api/v1/fs/ls?uri=viking://", + headers={"X-API-Key": ROOT_KEY}, + ) + assert tenant_resp.status_code == 400 + assert tenant_resp.json()["error"]["code"] == "INVALID_ARGUMENT" + + tenant_resp = await auth_client.get( + "/api/v1/fs/ls?uri=viking://", + headers={ + "X-API-Key": ROOT_KEY, + "X-OpenViking-Account": "default", + "X-OpenViking-User": "default", + }, + ) + assert tenant_resp.status_code == 200 + # ---- Role-based access tests ---- @@ -209,6 +321,165 @@ async def test_cross_tenant_session_get_returns_not_found(auth_client: httpx.Asy assert cross_get.json()["error"]["code"] == "NOT_FOUND" +async def test_root_tenant_scoped_requests_require_explicit_identity(): + """ROOT must specify account/user headers on tenant-scoped APIs.""" + request = _make_request("/api/v1/resources", auth_enabled=True) + identity = ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default") + + with pytest.raises(InvalidArgumentError, match="X-OpenViking-Account"): + await get_request_context(request, identity) + + +async def test_root_system_status_allows_implicit_default_identity(): + """ROOT may call status endpoints without explicit tenant headers.""" + request = _make_request("/api/v1/system/status", auth_enabled=True) + identity = ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default") + + ctx = await get_request_context(request, identity) + + assert ctx.role == Role.ROOT + assert ctx.user.account_id == "default" + assert ctx.user.user_id == "default" + + +async def test_root_tenant_scoped_requests_allow_explicit_identity(): + """ROOT can access tenant-scoped APIs when account/user headers are present.""" + request = _make_request( + "/api/v1/resources", + headers={ + "X-OpenViking-Account": "acme", + "X-OpenViking-User": "alice", + }, + auth_enabled=True, + ) + identity = ResolvedIdentity(role=Role.ROOT, account_id="acme", user_id="alice") + + ctx = await get_request_context(request, identity) + + assert ctx.role == Role.ROOT + assert ctx.user.account_id == "acme" + assert ctx.user.user_id == "alice" + + +async def test_root_monitoring_requests_allow_implicit_default_identity(): + """Observer/debug endpoints keep the existing ROOT monitoring flow.""" + observer_request = _make_request("/api/v1/observer/system", auth_enabled=True) + debug_request = _make_request("/api/v1/debug/health", auth_enabled=True) + identity = ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default") + + observer_ctx = await get_request_context(observer_request, identity) + debug_ctx = await get_request_context(debug_request, identity) + + assert observer_ctx.role == Role.ROOT + assert debug_ctx.role == Role.ROOT + + +async def test_root_system_wait_allows_implicit_default_identity(): + """ROOT may call system wait without explicit tenant headers.""" + request = _make_request("/api/v1/system/wait", auth_enabled=True) + identity = ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default") + + ctx = await get_request_context(request, identity) + + assert ctx.role == Role.ROOT + + +async def test_root_debug_vector_requests_require_explicit_identity(): + """Tenant-scoped debug routes must not bypass explicit tenant checks.""" + request = _make_request("/api/v1/debug/vector/scroll", auth_enabled=True) + identity = ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default") + + with pytest.raises(InvalidArgumentError, match="X-OpenViking-Account"): + await get_request_context(request, identity) + + +async def test_dev_mode_root_tenant_scoped_requests_allow_implicit_identity(): + """Dev mode should keep the existing implicit ROOT/default behavior.""" + request = _make_request("/api/v1/resources", auth_enabled=False) + identity = ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default") + + ctx = await get_request_context(request, identity) + + assert ctx.role == Role.ROOT + assert ctx.user.account_id == "default" + assert ctx.user.user_id == "default" + + +async def test_root_tenant_scoped_requests_return_structured_400_via_http(): + """Tenant-scoped HTTP routes should reject implicit ROOT tenant fallback.""" + app = _build_auth_http_test_app( + ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default"), + auth_enabled=True, + ) + transport = httpx.ASGITransport(app=app) + + async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as client: + response = await client.get("/api/v1/fs/ls") + + assert response.status_code == 400 + assert response.json()["error"]["code"] == "INVALID_ARGUMENT" + + +async def test_root_monitoring_requests_keep_200_via_http(): + """Monitoring HTTP routes should still work with implicit ROOT identity.""" + app = _build_auth_http_test_app( + ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default"), + auth_enabled=True, + ) + transport = httpx.ASGITransport(app=app) + + async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as client: + response = await client.get("/api/v1/observer/system") + + assert response.status_code == 200 + assert response.json()["status"] == "ok" + + +async def test_root_system_wait_keeps_200_via_http(): + """System wait should keep working for ROOT without tenant headers.""" + app = _build_auth_http_test_app( + ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default"), + auth_enabled=True, + ) + transport = httpx.ASGITransport(app=app) + + async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as client: + response = await client.post("/api/v1/system/wait") + + assert response.status_code == 200 + assert response.json()["status"] == "ok" + + +async def test_root_debug_vector_requests_return_structured_400_via_http(): + """Tenant-scoped debug routes should reject implicit ROOT tenant fallback.""" + app = _build_auth_http_test_app( + ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default"), + auth_enabled=True, + ) + transport = httpx.ASGITransport(app=app) + + async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as client: + response = await client.get("/api/v1/debug/vector/scroll") + + assert response.status_code == 400 + assert response.json()["error"]["code"] == "INVALID_ARGUMENT" + + +async def test_dev_mode_root_tenant_scoped_requests_keep_200_via_http(): + """Dev mode HTTP routes should keep the existing implicit ROOT/default behavior.""" + app = _build_auth_http_test_app( + ResolvedIdentity(role=Role.ROOT, account_id="default", user_id="default"), + auth_enabled=False, + ) + transport = httpx.ASGITransport(app=app) + + async with httpx.AsyncClient(transport=transport, base_url="http://testserver") as client: + response = await client.get("/api/v1/fs/ls") + + assert response.status_code == 200 + assert response.json()["status"] == "ok" + + # ---- _is_localhost tests ---- diff --git a/tests/server/test_http_client_sdk.py b/tests/server/test_http_client_sdk.py index 3fb88cdd..c757c2ce 100644 --- a/tests/server/test_http_client_sdk.py +++ b/tests/server/test_http_client_sdk.py @@ -43,6 +43,8 @@ async def test_sdk_add_resource(http_client): f.write_text(SAMPLE_MD_CONTENT) result = await client.add_resource(path=str(f), reason="sdk test", wait=True) + assert "usage" not in result + assert "telemetry" not in result assert "root_uri" in result assert result["root_uri"].startswith("viking://") @@ -121,6 +123,38 @@ async def test_sdk_find(http_client): assert hasattr(result, "total") +async def test_sdk_find_telemetry(http_client): + client, _ = http_client + f = TEST_TMP_DIR / "sdk_search_telemetry.md" + f.parent.mkdir(parents=True, exist_ok=True) + f.write_text(SAMPLE_MD_CONTENT) + await client.add_resource( + path=str(f), reason="telemetry search test", wait=True, telemetry=True + ) + + result = await client.find(query="sample document", limit=5, telemetry=True) + assert not hasattr(result, "telemetry") + + +async def test_sdk_find_summary_only_telemetry(http_client): + client, _ = http_client + f = TEST_TMP_DIR / "sdk_search_summary_only.md" + f.parent.mkdir(parents=True, exist_ok=True) + f.write_text(SAMPLE_MD_CONTENT) + await client.add_resource( + path=str(f), + reason="summary only telemetry search test", + wait=True, + ) + + result = await client.find( + query="sample document", + limit=5, + telemetry={"summary": True}, + ) + assert not hasattr(result, "telemetry") + + # =================================================================== # Full workflow # =================================================================== diff --git a/tests/service/test_resource_service_watch.py b/tests/service/test_resource_service_watch.py new file mode 100644 index 00000000..6680de43 --- /dev/null +++ b/tests/service/test_resource_service_watch.py @@ -0,0 +1,482 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Integration tests for ResourceService watch functionality.""" + +from typing import AsyncGenerator +from unittest.mock import AsyncMock, MagicMock + +import pytest +import pytest_asyncio + +from openviking.resource.watch_manager import WatchManager +from openviking.server.identity import RequestContext, Role +from openviking.service.resource_service import ResourceService +from openviking_cli.exceptions import ConflictError +from openviking_cli.exceptions import InvalidArgumentError +from openviking_cli.session.user_id import UserIdentifier + + +async def get_task_by_uri(service: ResourceService, to_uri: str, ctx: RequestContext): + return await service._watch_scheduler.watch_manager.get_task_by_uri( + to_uri=to_uri, + account_id=ctx.account_id, + user_id=ctx.user.user_id, + role=ctx.role.value, + ) + + +class MockResourceProcessor: + """Mock ResourceProcessor for testing.""" + + async def process_resource(self, **kwargs): + return {"root_uri": kwargs.get("to", "viking://resources/test")} + + +class MockSkillProcessor: + """Mock SkillProcessor for testing.""" + + async def process_skill(self, **kwargs): + return {"status": "ok"} + + +class MockVikingFS: + """Mock VikingFS for testing.""" + + pass + + +class MockVikingDB: + """Mock VikingDBManager for testing.""" + + pass + + +@pytest_asyncio.fixture +async def watch_manager() -> AsyncGenerator[WatchManager, None]: + """Create WatchManager instance without VikingFS for testing.""" + manager = WatchManager(viking_fs=None) + await manager.initialize() + yield manager + await manager.clear_all_tasks() + + +@pytest_asyncio.fixture +async def resource_service(watch_manager: WatchManager) -> AsyncGenerator[ResourceService, None]: + """Create ResourceService instance with watch support.""" + scheduler = MagicMock() + scheduler.watch_manager = watch_manager + service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(), + resource_processor=MockResourceProcessor(), + skill_processor=MockSkillProcessor(), + watch_scheduler=scheduler, + ) + yield service + + +@pytest_asyncio.fixture +def request_context() -> RequestContext: + """Create request context for testing.""" + return RequestContext( + user=UserIdentifier("test_account", "test_user", "test_agent"), + role=Role.USER, + ) + + +class TestWatchTaskCreation: + """Tests for watch task creation in add_resource.""" + + @pytest.mark.asyncio + async def test_create_watch_task_with_positive_interval( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test creating a watch task when watch_interval > 0.""" + to_uri = "viking://resources/test_resource" + + result = await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + reason="Test monitoring", + instruction="Monitor for changes", + watch_interval=30.0, + ) + + assert result is not None + assert "root_uri" in result + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + assert task.path == "/test/path" + assert task.to_uri == to_uri + assert task.reason == "Test monitoring" + assert task.instruction == "Monitor for changes" + assert task.watch_interval == 30.0 + assert task.is_active is True + + @pytest.mark.asyncio + async def test_watch_interval_requires_to_when_watch_enabled( + self, resource_service: ResourceService, request_context: RequestContext + ): + with pytest.raises(InvalidArgumentError, match="requires 'to'"): + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=None, + watch_interval=30.0, + ) + + @pytest.mark.asyncio + async def test_watch_task_aligns_processor_params( + self, resource_service: ResourceService, request_context: RequestContext + ): + to_uri = "viking://resources/align_processor_params" + + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=30.0, + build_index=False, + summarize=True, + custom_option="x", + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + assert task.build_index is False + assert task.summarize is True + assert task.processor_kwargs.get("custom_option") == "x" + + @pytest.mark.asyncio + async def test_create_watch_task_with_default_interval( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test creating a watch task with default interval.""" + to_uri = "viking://resources/default_interval" + + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=60.0, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + assert task.watch_interval == 60.0 + + @pytest.mark.asyncio + async def test_no_watch_task_created_with_zero_interval( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test that no watch task is created when watch_interval is 0.""" + to_uri = "viking://resources/no_watch" + + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=0, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is None + + @pytest.mark.asyncio + async def test_no_watch_task_created_with_negative_interval( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test that no watch task is created when watch_interval is negative.""" + to_uri = "viking://resources/negative_watch" + + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=-10, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is None + + +class TestWatchTaskConflict: + """Tests for watch task conflict detection.""" + + @pytest.mark.asyncio + async def test_conflict_when_active_task_exists( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test that ConflictError is raised when an active task already exists.""" + to_uri = "viking://resources/conflict_test" + + await resource_service.add_resource( + path="/test/path1", + ctx=request_context, + to=to_uri, + watch_interval=30.0, + ) + + with pytest.raises(ConflictError) as exc_info: + await resource_service.add_resource( + path="/test/path2", + ctx=request_context, + to=to_uri, + watch_interval=45.0, + ) + + assert "already being monitored" in str(exc_info.value) + assert to_uri in str(exc_info.value) + + @pytest.mark.asyncio + async def test_conflict_when_task_exists_but_hidden_by_permission( + self, resource_service: ResourceService, request_context: RequestContext + ): + to_uri = "viking://resources/cross_user_conflict" + other_user_ctx = RequestContext( + user=UserIdentifier("test_account", "other_user", "other_agent"), + role=Role.USER, + ) + + await resource_service.add_resource( + path="/test/path1", + ctx=request_context, + to=to_uri, + watch_interval=30.0, + ) + + hidden_task = await get_task_by_uri(resource_service, to_uri, other_user_ctx) + assert hidden_task is None + + with pytest.raises(ConflictError) as exc_info: + await resource_service.add_resource( + path="/test/path2", + ctx=other_user_ctx, + to=to_uri, + watch_interval=45.0, + ) + + assert "already used by another task" in str(exc_info.value) + assert to_uri in str(exc_info.value) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + + @pytest.mark.asyncio + async def test_reactivate_inactive_task( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test reactivating an inactive task.""" + to_uri = "viking://resources/reactivate_test" + + await resource_service.add_resource( + path="/test/path1", + ctx=request_context, + to=to_uri, + watch_interval=30.0, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + task_id = task.task_id + + await resource_service._watch_scheduler.watch_manager.update_task( + task_id=task_id, + account_id=request_context.account_id, + user_id=request_context.user.user_id, + role=request_context.role.value, + is_active=False, + ) + + await resource_service.add_resource( + path="/test/path2", + ctx=request_context, + to=to_uri, + reason="Updated reason", + watch_interval=45.0, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + assert task.task_id == task_id + assert task.path == "/test/path2" + assert task.reason == "Updated reason" + assert task.watch_interval == 45.0 + assert task.is_active is True + + +class TestWatchTaskCancellation: + """Tests for watch task cancellation.""" + + @pytest.mark.asyncio + async def test_cancel_watch_task_with_zero_interval( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test cancelling a watch task by setting watch_interval to 0.""" + to_uri = "viking://resources/cancel_test" + + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=30.0, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + assert task.is_active is True + + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=0, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + assert task.is_active is False + + @pytest.mark.asyncio + async def test_cancel_watch_task_with_negative_interval( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test cancelling a watch task by setting watch_interval to negative.""" + to_uri = "viking://resources/cancel_negative" + + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=30.0, + ) + + await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=-5, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + assert task.is_active is False + + @pytest.mark.asyncio + async def test_cancel_nonexistent_task_no_error( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test that cancelling a nonexistent task does not raise an error.""" + to_uri = "viking://resources/nonexistent" + + result = await resource_service.add_resource( + path="/test/path", + ctx=request_context, + to=to_uri, + watch_interval=0, + ) + + assert result is not None + + +class TestWatchTaskUpdate: + """Tests for watch task update.""" + + @pytest.mark.asyncio + async def test_update_watch_task_parameters( + self, resource_service: ResourceService, request_context: RequestContext + ): + """Test updating watch task parameters.""" + to_uri = "viking://resources/update_test" + + await resource_service.add_resource( + path="/test/path1", + ctx=request_context, + to=to_uri, + reason="Original reason", + instruction="Original instruction", + watch_interval=30.0, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + original_task_id = task.task_id + + await resource_service._watch_scheduler.watch_manager.update_task( + task_id=task.task_id, + account_id=request_context.account_id, + user_id=request_context.user.user_id, + role=request_context.role.value, + is_active=False, + ) + + await resource_service.add_resource( + path="/test/path2", + ctx=request_context, + to=to_uri, + reason="Updated reason", + instruction="Updated instruction", + watch_interval=60.0, + ) + + task = await get_task_by_uri(resource_service, to_uri, request_context) + assert task is not None + assert task.task_id == original_task_id + assert task.path == "/test/path2" + assert task.reason == "Updated reason" + assert task.instruction == "Updated instruction" + assert task.watch_interval == 60.0 + assert task.is_active is True + + +class TestResourceProcessingIndependence: + """Tests that resource processing is independent of watch task management.""" + + @pytest.mark.asyncio + async def test_resource_added_even_if_watch_fails(self, request_context: RequestContext): + """Test that resource is added even if watch task creation fails.""" + failing_watch_manager = MagicMock(spec=WatchManager) + failing_watch_manager.get_task_by_uri = AsyncMock(side_effect=Exception("DB error")) + scheduler = MagicMock() + scheduler.watch_manager = failing_watch_manager + + service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(), + resource_processor=MockResourceProcessor(), + skill_processor=MockSkillProcessor(), + watch_scheduler=scheduler, + ) + + result = await service.add_resource( + path="/test/path", + ctx=request_context, + to="viking://resources/test", + watch_interval=30.0, + ) + + assert result is not None + assert "root_uri" in result + + @pytest.mark.asyncio + async def test_resource_added_without_watch_manager(self, request_context: RequestContext): + """Test that resource is added when watch_manager is None.""" + service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(), + resource_processor=MockResourceProcessor(), + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + result = await service.add_resource( + path="/test/path", + ctx=request_context, + to="viking://resources/test", + watch_interval=30.0, + ) + + assert result is not None + assert "root_uri" in result diff --git a/tests/service/test_watch_recovery.py b/tests/service/test_watch_recovery.py new file mode 100644 index 00000000..b1bed7df --- /dev/null +++ b/tests/service/test_watch_recovery.py @@ -0,0 +1,612 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Integration tests for watch task recovery after service restart.""" + +import asyncio +import json +from datetime import datetime, timedelta +from pathlib import Path +from typing import AsyncGenerator + +import pytest +import pytest_asyncio + +from openviking.resource.watch_manager import WatchManager +from openviking.resource.watch_scheduler import WatchScheduler +from openviking.server.identity import RequestContext, Role +from openviking.service.resource_service import ResourceService +from openviking_cli.session.user_id import UserIdentifier +from tests.utils.mock_agfs import MockLocalAGFS + + +class MockVikingFS: + """Mock VikingFS for testing.""" + + def __init__(self, root_path: str): + self.agfs = MockLocalAGFS(root_path=root_path) + + async def read_file(self, uri: str, ctx=None) -> str: + """Read file from storage.""" + path = self._uri_to_path(uri) + content = self.agfs.read(path) + if isinstance(content, bytes): + return content.decode("utf-8") + return content + + async def write_file(self, uri: str, content: str, ctx=None) -> None: + """Write file to storage.""" + path = self._uri_to_path(uri) + self.agfs.write(path, content.encode("utf-8")) + + def _uri_to_path(self, uri: str) -> str: + """Convert URI to path.""" + if uri.startswith("viking://"): + return uri.replace("viking://", "/local/default/") + return uri + + +class MockResourceProcessor: + """Mock ResourceProcessor for testing.""" + + def __init__(self): + self.call_count = 0 + self.processed_paths = [] + + async def process_resource(self, **kwargs): + self.call_count += 1 + self.processed_paths.append(kwargs.get("path")) + return {"root_uri": kwargs.get("to", "viking://resources/test")} + + +class MockSkillProcessor: + """Mock SkillProcessor for testing.""" + + async def process_skill(self, **kwargs): + return {"status": "ok"} + + +class MockVikingDB: + """Mock VikingDBManager for testing.""" + + pass + + +@pytest_asyncio.fixture +async def temp_storage(tmp_path: Path) -> AsyncGenerator[Path, None]: + """Create temporary storage directory.""" + storage_dir = tmp_path / "watch_storage" + storage_dir.mkdir(parents=True, exist_ok=True) + yield storage_dir + + +@pytest_asyncio.fixture +async def mock_viking_fs(temp_storage: Path) -> MockVikingFS: + """Create mock VikingFS instance.""" + return MockVikingFS(root_path=str(temp_storage)) + + +@pytest_asyncio.fixture +async def request_context() -> RequestContext: + """Create request context for testing.""" + return RequestContext( + user=UserIdentifier.the_default_user(), + role=Role.ROOT, + ) + + +class TestServiceRestartRecovery: + """Tests for watch task recovery after service restart.""" + + @pytest.mark.asyncio + async def test_tasks_persisted_and_reloaded_after_restart( + self, mock_viking_fs: MockVikingFS, temp_storage: Path + ): + """Test that tasks are persisted and correctly reloaded after service restart.""" + manager1 = WatchManager(viking_fs=mock_viking_fs) + await manager1.initialize() + + task1 = await manager1.create_task( + path="/test/path1", + to_uri="viking://resources/test1", + reason="Task 1", + watch_interval=30.0, + ) + task2 = await manager1.create_task( + path="/test/path2", + to_uri="viking://resources/test2", + reason="Task 2", + watch_interval=60.0, + ) + + task1_id = task1.task_id + task2_id = task2.task_id + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + + loaded_task1 = await manager2.get_task(task1_id) + loaded_task2 = await manager2.get_task(task2_id) + + assert loaded_task1 is not None + assert loaded_task1.path == "/test/path1" + assert loaded_task1.to_uri == "viking://resources/test1" + assert loaded_task1.reason == "Task 1" + assert loaded_task1.watch_interval == 30.0 + assert loaded_task1.is_active is True + + assert loaded_task2 is not None + assert loaded_task2.path == "/test/path2" + assert loaded_task2.to_uri == "viking://resources/test2" + assert loaded_task2.watch_interval == 60.0 + + @pytest.mark.asyncio + async def test_tasks_recovered_from_backup_when_primary_missing( + self, mock_viking_fs: MockVikingFS, temp_storage: Path + ): + """Test that tasks can be recovered from backup storage when primary is missing.""" + task_data = { + "task_id": "backup-task-id", + "path": "/test/backup", + "to_uri": "viking://resources/backup", + "reason": "Backup task", + "instruction": "", + "watch_interval": 60.0, + "created_at": datetime.now().isoformat(), + "last_execution_time": None, + "next_execution_time": None, + "is_active": True, + } + + storage_uri = WatchManager.STORAGE_URI + storage_path = mock_viking_fs._uri_to_path(storage_uri) + assert mock_viking_fs.agfs.exists(storage_path) is False + + bak_uri = WatchManager.STORAGE_BAK_URI + bak_path = mock_viking_fs._uri_to_path(bak_uri) + data = {"tasks": [task_data], "updated_at": datetime.now().isoformat()} + mock_viking_fs.agfs.write(bak_path, json.dumps(data).encode("utf-8")) + + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + + loaded_task = await manager.get_task("backup-task-id") + assert loaded_task is not None + assert loaded_task.path == "/test/backup" + assert loaded_task.to_uri == "viking://resources/backup" + + assert mock_viking_fs.agfs.exists(storage_path) is True + + @pytest.mark.asyncio + async def test_expired_tasks_executed_on_startup( + self, mock_viking_fs: MockVikingFS, temp_storage: Path, request_context: RequestContext + ): + """Test that tasks with next_execution_time in the past are executed on startup.""" + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + + past_time = datetime.now() - timedelta(minutes=10) + task_data = { + "task_id": "expired-task-id", + "path": "/test/expired", + "to_uri": "viking://resources/expired", + "reason": "Expired task", + "instruction": "", + "watch_interval": 60.0, + "created_at": (datetime.now() - timedelta(hours=1)).isoformat(), + "last_execution_time": (datetime.now() - timedelta(hours=1)).isoformat(), + "next_execution_time": past_time.isoformat(), + "is_active": True, + } + + storage_uri = WatchManager.STORAGE_URI + path = mock_viking_fs._uri_to_path(storage_uri) + data = {"tasks": [task_data], "updated_at": datetime.now().isoformat()} + mock_viking_fs.agfs.write(path, json.dumps(data).encode("utf-8")) + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + + due_tasks = await manager2.get_due_tasks() + + assert len(due_tasks) == 1 + assert due_tasks[0].task_id == "expired-task-id" + + @pytest.mark.asyncio + async def test_future_tasks_not_executed_on_startup( + self, mock_viking_fs: MockVikingFS, temp_storage: Path + ): + """Test that tasks with future next_execution_time are not executed immediately.""" + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + + future_time = datetime.now() + timedelta(hours=1) + task_data = { + "task_id": "future-task-id", + "path": "/test/future", + "to_uri": "viking://resources/future", + "reason": "Future task", + "instruction": "", + "watch_interval": 60.0, + "created_at": datetime.now().isoformat(), + "last_execution_time": None, + "next_execution_time": future_time.isoformat(), + "is_active": True, + } + + storage_uri = WatchManager.STORAGE_URI + path = mock_viking_fs._uri_to_path(storage_uri) + data = {"tasks": [task_data], "updated_at": datetime.now().isoformat()} + mock_viking_fs.agfs.write(path, json.dumps(data).encode("utf-8")) + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + + due_tasks = await manager2.get_due_tasks() + + assert len(due_tasks) == 0 + + @pytest.mark.asyncio + async def test_inactive_tasks_not_executed_after_restart( + self, mock_viking_fs: MockVikingFS, temp_storage: Path + ): + """Test that inactive tasks are not executed after restart.""" + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + + past_time = datetime.now() - timedelta(minutes=10) + task_data = { + "task_id": "inactive-task-id", + "path": "/test/inactive", + "to_uri": "viking://resources/inactive", + "reason": "Inactive task", + "instruction": "", + "watch_interval": 60.0, + "created_at": (datetime.now() - timedelta(hours=1)).isoformat(), + "last_execution_time": None, + "next_execution_time": past_time.isoformat(), + "is_active": False, + } + + storage_uri = WatchManager.STORAGE_URI + path = mock_viking_fs._uri_to_path(storage_uri) + data = {"tasks": [task_data], "updated_at": datetime.now().isoformat()} + mock_viking_fs.agfs.write(path, json.dumps(data).encode("utf-8")) + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + + due_tasks = await manager2.get_due_tasks() + + assert len(due_tasks) == 0 + + +class TestResourceExistenceCheck: + """Tests for resource existence checking during task execution.""" + + @pytest.mark.asyncio + async def test_task_deactivated_when_resource_deleted( + self, temp_storage: Path, request_context: RequestContext + ): + """Test that task is deactivated when resource no longer exists.""" + resource_processor = MockResourceProcessor() + + resource_service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(root_path=str(temp_storage)), + resource_processor=resource_processor, + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + scheduler = WatchScheduler( + resource_service=resource_service, + viking_fs=None, + ) + await scheduler.start() + + watch_manager = scheduler.watch_manager + + task = await watch_manager.create_task( + path="/nonexistent/path/to/resource", + to_uri="viking://resources/deleted", + reason="Test deleted resource", + watch_interval=30.0, + ) + + assert task.is_active is True + + await scheduler._execute_task(task) + + updated_task = await watch_manager.get_task(task.task_id) + assert updated_task is not None + assert updated_task.is_active is False + + @pytest.mark.asyncio + async def test_task_continues_when_resource_exists( + self, temp_storage: Path, request_context: RequestContext + ): + """Test that task continues normally when resource exists.""" + test_file = temp_storage / "test_resource.txt" + test_file.write_text("test content") + + resource_processor = MockResourceProcessor() + + resource_service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(root_path=str(temp_storage)), + resource_processor=resource_processor, + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + scheduler = WatchScheduler( + resource_service=resource_service, + viking_fs=None, + ) + await scheduler.start() + + watch_manager = scheduler.watch_manager + + task = await watch_manager.create_task( + path=str(test_file), + to_uri="viking://resources/existing", + reason="Test existing resource", + watch_interval=30.0, + ) + + await scheduler._execute_task(task) + + updated_task = await watch_manager.get_task(task.task_id) + assert updated_task is not None + assert updated_task.is_active is True + assert updated_task.last_execution_time is not None + + @pytest.mark.asyncio + async def test_url_resources_always_considered_existing( + self, temp_storage: Path, request_context: RequestContext + ): + """Test that URL resources are always considered existing.""" + resource_processor = MockResourceProcessor() + + resource_service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(root_path=str(temp_storage)), + resource_processor=resource_processor, + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + scheduler = WatchScheduler( + resource_service=resource_service, + viking_fs=None, + ) + await scheduler.start() + + watch_manager = scheduler.watch_manager + + task = await watch_manager.create_task( + path="https://example.com/resource", + to_uri="viking://resources/url", + reason="Test URL resource", + watch_interval=30.0, + ) + + await scheduler._execute_task(task) + + updated_task = await watch_manager.get_task(task.task_id) + assert updated_task is not None + assert updated_task.is_active is True + assert resource_processor.call_count == 1 + + +class TestSchedulerIntegration: + """Integration tests for WatchScheduler with WatchManager.""" + + @pytest.mark.asyncio + async def test_scheduler_processes_due_tasks_after_restart( + self, temp_storage: Path, request_context: RequestContext + ): + """Test that scheduler processes due tasks after service restart.""" + test_file = temp_storage / "test.txt" + test_file.write_text("test content") + + resource_processor = MockResourceProcessor() + + resource_service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(root_path=str(temp_storage)), + resource_processor=resource_processor, + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + scheduler = WatchScheduler( + resource_service=resource_service, + viking_fs=None, + check_interval=0.1, + ) + await scheduler.start() + + watch_manager = scheduler.watch_manager + + await watch_manager.create_task( + path=str(test_file), + to_uri="viking://resources/test", + reason="Test task", + watch_interval=0.001, + ) + + await asyncio.sleep(0.2) + + await scheduler.stop() + + assert resource_processor.call_count >= 1 + + @pytest.mark.asyncio + async def test_scheduler_handles_multiple_tasks_after_restart( + self, temp_storage: Path, request_context: RequestContext + ): + """Test that scheduler handles multiple tasks after restart.""" + test_file1 = temp_storage / "test1.txt" + test_file2 = temp_storage / "test2.txt" + test_file1.write_text("test content 1") + test_file2.write_text("test content 2") + + resource_processor = MockResourceProcessor() + + resource_service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(root_path=str(temp_storage)), + resource_processor=resource_processor, + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + scheduler = WatchScheduler( + resource_service=resource_service, + viking_fs=None, + check_interval=0.1, + ) + await scheduler.start() + + watch_manager = scheduler.watch_manager + + await watch_manager.create_task( + path=str(test_file1), + to_uri="viking://resources/test1", + reason="Task 1", + watch_interval=0.001, + ) + await watch_manager.create_task( + path=str(test_file2), + to_uri="viking://resources/test2", + reason="Task 2", + watch_interval=0.001, + ) + + await asyncio.sleep(0.3) + + await scheduler.stop() + + assert resource_processor.call_count >= 2 + + @pytest.mark.asyncio + async def test_scheduler_skips_inactive_tasks_after_restart( + self, temp_storage: Path, request_context: RequestContext + ): + """Test that scheduler skips inactive tasks after restart.""" + test_file = temp_storage / "test.txt" + test_file.write_text("test content") + + resource_processor = MockResourceProcessor() + + resource_service = ResourceService( + vikingdb=MockVikingDB(), + viking_fs=MockVikingFS(root_path=str(temp_storage)), + resource_processor=resource_processor, + skill_processor=MockSkillProcessor(), + watch_scheduler=None, + ) + + scheduler = WatchScheduler( + resource_service=resource_service, + viking_fs=None, + check_interval=0.1, + ) + await scheduler.start() + + watch_manager = scheduler.watch_manager + + task = await watch_manager.create_task( + path=str(test_file), + to_uri="viking://resources/test", + reason="Inactive task", + watch_interval=0.001, + ) + + await watch_manager.update_task( + task_id=task.task_id, + account_id=task.account_id, + user_id=task.user_id, + role="ROOT", + is_active=False, + ) + + await asyncio.sleep(0.2) + + await scheduler.stop() + + assert resource_processor.call_count == 0 + + +class TestTaskExecutionTimeRecovery: + """Tests for task execution time handling after restart.""" + + @pytest.mark.asyncio + async def test_execution_times_preserved_after_restart( + self, mock_viking_fs: MockVikingFS, temp_storage: Path + ): + """Test that execution times are preserved after restart.""" + manager1 = WatchManager(viking_fs=mock_viking_fs) + await manager1.initialize() + + task = await manager1.create_task( + path="/test/path", + to_uri="viking://resources/test", + watch_interval=30.0, + ) + + await manager1.update_execution_time(task.task_id) + + task_after_exec = await manager1.get_task(task.task_id) + assert task_after_exec is not None + original_last_exec = task_after_exec.last_execution_time + original_next_exec = task_after_exec.next_execution_time + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + + loaded_task = await manager2.get_task(task.task_id) + assert loaded_task is not None + assert loaded_task.last_execution_time is not None + assert abs((loaded_task.last_execution_time - original_last_exec).total_seconds()) < 1 + assert loaded_task.next_execution_time is not None + assert abs((loaded_task.next_execution_time - original_next_exec).total_seconds()) < 1 + + @pytest.mark.asyncio + async def test_next_execution_time_calculated_correctly_after_restart( + self, mock_viking_fs: MockVikingFS, temp_storage: Path + ): + """Test that next execution time is calculated correctly for loaded tasks.""" + manager = WatchManager(viking_fs=mock_viking_fs) + await manager.initialize() + + last_exec = datetime.now() - timedelta(minutes=15) + task_data = { + "task_id": "test-task-id", + "path": "/test/path", + "to_uri": "viking://resources/test", + "reason": "Test", + "instruction": "", + "watch_interval": 30.0, + "created_at": (datetime.now() - timedelta(hours=1)).isoformat(), + "last_execution_time": last_exec.isoformat(), + "next_execution_time": (last_exec + timedelta(minutes=30)).isoformat(), + "is_active": True, + } + + storage_uri = WatchManager.STORAGE_URI + path = mock_viking_fs._uri_to_path(storage_uri) + data = {"tasks": [task_data], "updated_at": datetime.now().isoformat()} + mock_viking_fs.agfs.write(path, json.dumps(data).encode("utf-8")) + + manager2 = WatchManager(viking_fs=mock_viking_fs) + await manager2.initialize() + + loaded_task = await manager2.get_task("test-task-id") + assert loaded_task is not None + assert loaded_task.watch_interval == 30.0 + assert loaded_task.last_execution_time is not None + + expected_next = loaded_task.last_execution_time + timedelta(minutes=30) + assert abs((loaded_task.next_execution_time - expected_next).total_seconds()) < 1 diff --git a/tests/session/test_memory_dedup_actions.py b/tests/session/test_memory_dedup_actions.py index 8b6e886e..ac273965 100644 --- a/tests/session/test_memory_dedup_actions.py +++ b/tests/session/test_memory_dedup_actions.py @@ -23,6 +23,9 @@ MergedMemoryPayload, ) from openviking_cli.session.user_id import UserIdentifier +from tests.utils.mock_context import make_test_ctx + +ctx = make_test_ctx() class _DummyVikingDB: @@ -39,7 +42,7 @@ def __init__(self, dense_vector): class _DummyEmbedder: - def embed(self, _text): + def embed(self, _text, is_query: bool = False): return _DummyEmbedResult([0.1, 0.2, 0.3]) @@ -63,6 +66,23 @@ def _make_candidate() -> CandidateMemory: ) +def _make_dedup(vikingdb=None, embedder=None) -> MemoryDeduplicator: + """Create MemoryDeduplicator without config dependency.""" + dedup = MemoryDeduplicator.__new__(MemoryDeduplicator) + dedup.vikingdb = vikingdb or MagicMock() + dedup.embedder = embedder + return dedup + + +def _make_compressor(vikingdb=None, embedder=None) -> SessionCompressor: + """Create SessionCompressor without config dependency.""" + vikingdb = vikingdb or MagicMock() + with patch("openviking.session.memory_deduplicator.get_openviking_config") as mock_config: + mock_config.return_value.embedding.get_embedder.return_value = embedder + compressor = SessionCompressor(vikingdb=vikingdb) + return compressor + + def _make_existing(uri_suffix: str = "existing.md") -> Context: user_space = _make_user().user_space_name() return Context( @@ -171,12 +191,13 @@ async def test_find_similar_memories_uses_path_must_filter_and__score(self): dedup = MemoryDeduplicator(vikingdb=vikingdb) candidate = _make_candidate() - similar = await dedup._find_similar_memories(candidate) + similar, _query_vector = await dedup._find_similar_memories(candidate, ctx) assert len(similar) == 1 assert similar[0].uri == existing.uri call = vikingdb.search_similar_memories.await_args.kwargs - assert call["account_id"] == "acc1" + # Note: removed stale assert call["account_id"] -- _find_similar_memories + # does not pass account_id to search_similar_memories. assert call["owner_space"] == _make_user().user_space_name() assert call["category_uri_prefix"] == ( f"viking://user/{_make_user().user_space_name()}/memories/preferences/" @@ -203,7 +224,7 @@ async def test_find_similar_memories_accepts_low_score_when_threshold_is_zero(se ) dedup = MemoryDeduplicator(vikingdb=vikingdb) - similar = await dedup._find_similar_memories(_make_candidate()) + similar, _ = await dedup._find_similar_memories(_make_candidate(), ctx) assert len(similar) == 1 @@ -247,6 +268,101 @@ class _DummyConfig: assert similar[4].uri in existing_text assert similar[5].uri not in existing_text + @pytest.mark.asyncio + async def test_find_similar_includes_batch_memories(self): + """Batch memory with high cosine similarity appears in results.""" + vikingdb = MagicMock() + vikingdb.search_similar_memories = AsyncMock(return_value=[]) + + dedup = _make_dedup(vikingdb=vikingdb, embedder=_DummyEmbedder()) + candidate = _make_candidate() + + # Batch memory with identical embedding vector -> cosine similarity = 1.0 + batch_ctx = _make_existing("batch_item.md") + batch_vector = [0.1, 0.2, 0.3] # Same as _DummyEmbedder returns + batch_memories = [(batch_vector, batch_ctx)] + + similar, query_vector = await dedup._find_similar_memories( + candidate, ctx, batch_memories=batch_memories + ) + + assert len(similar) == 1 + assert similar[0].uri == batch_ctx.uri + assert similar[0].meta["_dedup_score"] == pytest.approx(1.0, abs=1e-6) + assert query_vector == [0.1, 0.2, 0.3] + + @pytest.mark.asyncio + async def test_find_similar_excludes_dissimilar_batch_memories(self): + """Batch memory with opposite embedding (cosine = -1.0) is excluded.""" + vikingdb = MagicMock() + vikingdb.search_similar_memories = AsyncMock(return_value=[]) + + dedup = _make_dedup(vikingdb=vikingdb, embedder=_DummyEmbedder()) + candidate = _make_candidate() + + # Opposite direction vector -> cosine = -1.0, below threshold 0.0 + batch_ctx = _make_existing("unrelated.md") + batch_vector = [-0.1, -0.2, -0.3] + batch_memories = [(batch_vector, batch_ctx)] + + similar, _ = await dedup._find_similar_memories( + candidate, ctx, batch_memories=batch_memories + ) + + assert len(similar) == 0 + + @pytest.mark.asyncio + async def test_find_similar_deduplicates_batch_and_db_by_uri(self): + """If same URI appears in both DB results and batch, only keep DB version.""" + existing = _make_existing("overlap.md") + vikingdb = MagicMock() + vikingdb.search_similar_memories = AsyncMock( + return_value=[ + { + "id": "uri_overlap", + "uri": existing.uri, + "context_type": "memory", + "level": 2, + "account_id": "acc1", + "owner_space": _make_user().user_space_name(), + "abstract": existing.abstract, + "category": "preferences", + "_score": 0.9, + } + ] + ) + + dedup = _make_dedup(vikingdb=vikingdb, embedder=_DummyEmbedder()) + candidate = _make_candidate() + + # Batch contains same URI as DB result + batch_ctx = _make_existing("overlap.md") + batch_vector = [0.1, 0.2, 0.3] + batch_memories = [(batch_vector, batch_ctx)] + + similar, _ = await dedup._find_similar_memories( + candidate, ctx, batch_memories=batch_memories + ) + + # Should have exactly 1 (DB version), not 2 + assert len(similar) == 1 + assert similar[0].uri == existing.uri + assert similar[0].meta["_dedup_score"] == pytest.approx(0.9, abs=1e-6) + + @pytest.mark.asyncio + async def test_deduplicate_returns_query_vector_in_result(self): + """DedupResult includes query_vector for batch tracking.""" + vikingdb = MagicMock() + vikingdb.search_similar_memories = AsyncMock(return_value=[]) + + dedup = _make_dedup(vikingdb=vikingdb, embedder=_DummyEmbedder()) + candidate = _make_candidate() + + result = await dedup.deduplicate(candidate, ctx) + + assert result.decision == DedupDecision.CREATE + assert result.query_vector == [0.1, 0.2, 0.3] + @pytest.mark.asyncio class TestMemoryMergeBundle: @@ -556,3 +672,138 @@ async def _rm(*_args, **_kwargs): assert [m.uri for m in memories] == [new_memory.uri] assert call_order == ["delete", "create"] vikingdb.delete_uris.assert_awaited_once_with(_make_ctx(), [target.uri]) + + async def test_batch_dedup_passes_batch_memories_to_deduplicate(self): + """Compressor passes batch_memories with previously created memory to deduplicate.""" + candidate_a = _make_candidate() + candidate_a.abstract = "User prefers dark mode" + candidate_a.content = "The user prefers dark mode in all editors." + + candidate_b = _make_candidate() + candidate_b.abstract = "User likes dark mode" + candidate_b.content = "The user likes dark mode for coding." + + memory_a = _make_existing("created_a.md") + + vikingdb = MagicMock() + vikingdb.delete_uris = AsyncMock(return_value=None) + vikingdb.enqueue_embedding_msg = AsyncMock() + + compressor = _make_compressor(vikingdb=vikingdb) + compressor.extractor.extract = AsyncMock(return_value=[candidate_a, candidate_b]) + compressor.extractor.create_memory = AsyncMock(return_value=memory_a) + + call_count = 0 + + async def _deduplicate(candidate, ctx, *, batch_memories=None): + nonlocal call_count + call_count += 1 + if call_count == 1: + assert batch_memories is None or len(batch_memories) == 0 + return DedupResult( + decision=DedupDecision.CREATE, + candidate=candidate, + similar_memories=[], + actions=[], + query_vector=[0.1, 0.2, 0.3], + ) + else: + assert batch_memories is not None + assert len(batch_memories) == 1 + assert batch_memories[0][0] == [0.1, 0.2, 0.3] + assert batch_memories[0][1].uri == memory_a.uri + return DedupResult( + decision=DedupDecision.SKIP, + candidate=candidate, + similar_memories=[batch_memories[0][1]], + actions=[], + query_vector=[0.1, 0.2, 0.3], + ) + + compressor.deduplicator.deduplicate = AsyncMock(side_effect=_deduplicate) + compressor._index_memory = AsyncMock(return_value=True) + + fs = MagicMock() + fs.rm = AsyncMock() + + with patch("openviking.session.compressor.get_viking_fs", return_value=fs): + memories = await compressor.extract_long_term_memories( + [Message.create_user("test message")], + user=_make_user(), + session_id="session_test", + ctx=_make_ctx(), + ) + + assert len(memories) == 1 + assert memories[0].uri == memory_a.uri + assert call_count == 2 + compressor.extractor.create_memory.assert_awaited_once() + + async def test_batch_dedup_real_cosine_path(self): + """End-to-end: real deduplicator cosine comparison catches batch duplicate.""" + candidate_a = _make_candidate() + candidate_a.abstract = "User prefers dark mode" + candidate_a.content = "The user prefers dark mode in all editors." + + candidate_b = _make_candidate() + candidate_b.abstract = "User likes dark mode" + candidate_b.content = "The user likes dark mode for coding." + + memory_a = _make_existing("real_a.md") + + vikingdb = MagicMock() + vikingdb.search_similar_memories = AsyncMock(return_value=[]) + vikingdb.delete_uris = AsyncMock(return_value=None) + vikingdb.enqueue_embedding_msg = AsyncMock() + + compressor = _make_compressor(vikingdb=vikingdb, embedder=_DummyEmbedder()) + compressor.extractor.extract = AsyncMock(return_value=[candidate_a, candidate_b]) + compressor.extractor.create_memory = AsyncMock(return_value=memory_a) + compressor._index_memory = AsyncMock(return_value=True) + + # Spy on _llm_decision to verify batch match triggers LLM path + original_llm_decision = compressor.deduplicator._llm_decision + llm_decision_calls = [] + + async def _spy_llm_decision(candidate, similar_memories): + llm_decision_calls.append(similar_memories) + return await original_llm_decision(candidate, similar_memories) + + compressor.deduplicator._llm_decision = _spy_llm_decision + + # Mock config for _llm_decision (called when similar memories found) + class _NoVLMConfig: + vlm = None + + class embedding: + @staticmethod + def get_embedder(): + return _DummyEmbedder() + + fs = MagicMock() + fs.rm = AsyncMock() + + with ( + patch("openviking.session.compressor.get_viking_fs", return_value=fs), + patch( + "openviking.session.memory_deduplicator.get_openviking_config", + return_value=_NoVLMConfig(), + ), + ): + await compressor.extract_long_term_memories( + [Message.create_user("test message")], + user=_make_user(), + session_id="session_test", + ctx=_make_ctx(), + ) + + # _DummyEmbedder returns [0.1, 0.2, 0.3] for all texts -> cosine = 1.0 + # First: DB empty, no batch -> CREATE (no _llm_decision called). + # Second: DB empty, but batch match found (cosine=1.0) -> + # _llm_decision IS called with the batch-sourced similar memory. + assert vikingdb.search_similar_memories.await_count == 2 + # Key assertion: _llm_decision was called exactly once (for second candidate) + assert len(llm_decision_calls) == 1 + # The similar_memories passed to LLM came from batch (not DB, which was empty) + assert len(llm_decision_calls[0]) == 1 + assert llm_decision_calls[0][0].uri == memory_a.uri diff --git a/tests/session/test_memory_extractor_language.py b/tests/session/test_memory_extractor_language.py index e9113d4b..d1d98021 100644 --- a/tests/session/test_memory_extractor_language.py +++ b/tests/session/test_memory_extractor_language.py @@ -86,3 +86,31 @@ def test_detect_output_language_japanese_with_more_han_than_kana(): ] language = MemoryExtractor._detect_output_language(messages, fallback_language="en") assert language == "ja" + + +def test_detect_output_language_chinese_with_single_cyrillic(): + """Mixed Chinese with single Cyrillic char should be detected as Chinese, not Russian.""" + messages = [_msg("user", "\u8fd9\u662f\u4e2d\u6587 \u0414 \u518d\u7ee7\u7eed")] + language = MemoryExtractor._detect_output_language(messages, fallback_language="en") + assert language == "zh-CN" + + +def test_detect_output_language_japanese_with_single_cyrillic(): + """Mixed Japanese with single Cyrillic char should be detected as Japanese, not Russian.""" + messages = [_msg("user", "\u3053\u308c\u306f\u65e5\u672c\u8a9e \u042f ")] + language = MemoryExtractor._detect_output_language(messages, fallback_language="en") + assert language == "ja" + + +def test_detect_output_language_russian_with_threshold(): + """Russian text with sufficient Cyrillic chars should be detected as Russian.""" + messages = [_msg("user", "\u042d\u0442\u043e \u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u0442\u0435\u043a\u0441\u0442")] + language = MemoryExtractor._detect_output_language(messages, fallback_language="en") + assert language == "ru" + + +def test_detect_output_language_insufficient_cyrillic_fallback(): + """Text with only 1 Cyrillic char among Latin should fallback, not Russian.""" + messages = [_msg("user", "Hello \u0424 world")] + language = MemoryExtractor._detect_output_language(messages, fallback_language="en") + assert language == "en" diff --git a/tests/session/test_memory_extractor_response_types.py b/tests/session/test_memory_extractor_response_types.py new file mode 100644 index 00000000..ff2b26fd --- /dev/null +++ b/tests/session/test_memory_extractor_response_types.py @@ -0,0 +1,77 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +""" +Tests that memory extraction handles non-dict LLM responses gracefully. + +Covers issue #605: Ollama models may return a JSON list instead of the +expected {"memories": [...]} dict, causing AttributeError on .get(). +""" + + +def _normalize_parsed_data(data): + """ + Replicate the type-checking logic added in memory_extractor.py:extract(). + + After ``parse_json_from_response(response) or {}``, the code now does: + - list -> wrap as ``{"memories": data}`` + - dict -> use as-is + - other -> fall back to ``{}`` + """ + if isinstance(data, list): + return {"memories": data} + if not isinstance(data, dict): + return {} + return data + + +def _make_memory(category="patterns", content="user prefers dark mode"): + return {"category": category, "content": content, "event": "", "emoji": ""} + + +class TestExtractResponseTypes: + """Verify the type-normalization handles dict, list, and unexpected types.""" + + def test_dict_response_passes_through(self): + """Standard dict format: {"memories": [...]}""" + payload = {"memories": [_make_memory()]} + data = _normalize_parsed_data(payload) + + assert isinstance(data, dict) + assert len(data.get("memories", [])) == 1 + assert data["memories"][0]["content"] == "user prefers dark mode" + + def test_list_response_wrapped_as_memories(self): + """Ollama-style list format: [{...}, {...}] wrapped into {"memories": [...]}""" + memories_list = [_make_memory(), _make_memory(content="likes Python")] + data = _normalize_parsed_data(memories_list) + + assert isinstance(data, dict) + assert len(data["memories"]) == 2 + assert data["memories"][1]["content"] == "likes Python" + + def test_string_response_yields_empty(self): + """If parse returns a bare string, treat as empty.""" + data = _normalize_parsed_data("some unexpected string") + + assert data == {} + assert data.get("memories", []) == [] + + def test_none_fallback_yields_empty(self): + """If parse returns None, the ``or {}`` fallback produces empty dict.""" + data = _normalize_parsed_data(None or {}) + + assert data == {} + assert data.get("memories", []) == [] + + def test_int_response_yields_empty(self): + """Numeric responses should be treated as empty.""" + data = _normalize_parsed_data(42) + + assert data == {} + + def test_empty_list_wraps_to_empty_memories(self): + """An empty list should produce {"memories": []}.""" + data = _normalize_parsed_data([]) + + assert data == {"memories": []} + assert data.get("memories", []) == [] diff --git a/tests/session/test_session_commit.py b/tests/session/test_session_commit.py index 86066b84..efa57fc7 100644 --- a/tests/session/test_session_commit.py +++ b/tests/session/test_session_commit.py @@ -95,12 +95,14 @@ async def test_active_count_incremented_after_commit(self, client_with_resource_ """ client, uri = client_with_resource_sync vikingdb = client._client.service.vikingdb_manager + # Use the client's own context to match the account_id used when adding the resource + client_ctx = client._client._ctx # Look up the record by URI records_before = await vikingdb.get_context_by_uri( - account_id="default", uri=uri, limit=1, + ctx=client_ctx, ) assert records_before, f"Resource not found for URI: {uri}" count_before = records_before[0].get("active_count") or 0 @@ -116,9 +118,9 @@ async def test_active_count_incremented_after_commit(self, client_with_resource_ # Verify the count actually changed in storage records_after = await vikingdb.get_context_by_uri( - account_id="default", uri=uri, limit=1, + ctx=client_ctx, ) assert records_after, f"Record disappeared after commit for URI: {uri}" count_after = records_after[0].get("active_count") or 0 diff --git a/tests/session/test_session_compressor_vikingdb.py b/tests/session/test_session_compressor_vikingdb.py index 71e22533..7cb38d02 100644 --- a/tests/session/test_session_compressor_vikingdb.py +++ b/tests/session/test_session_compressor_vikingdb.py @@ -15,8 +15,12 @@ async def test_delete_existing_memory_uses_vikingdb_manager(): compressor = SessionCompressor.__new__(SessionCompressor) compressor.vikingdb = AsyncMock() + compressor._pending_semantic_changes = {} viking_fs = AsyncMock() - memory = SimpleNamespace(uri="viking://user/user1/memories/events/e1") + memory = SimpleNamespace( + uri="viking://user/user1/memories/events/e1", + parent_uri="viking://user/user1/memories/events", + ) ctx = RequestContext(user=UserIdentifier("acc1", "user1", "agent1"), role=Role.USER) ok = await SessionCompressor._delete_existing_memory(compressor, memory, viking_fs, ctx) diff --git a/tests/storage/test_collection_schemas.py b/tests/storage/test_collection_schemas.py index c538f3b6..c25dbbda 100644 --- a/tests/storage/test_collection_schemas.py +++ b/tests/storage/test_collection_schemas.py @@ -47,7 +47,7 @@ async def test_embedding_handler_skip_all_work_when_manager_is_closing(monkeypat class _ClosingVikingDB: is_closing = True - async def upsert(self, _data): # pragma: no cover - should never run + async def upsert(self, _data, *, ctx): # pragma: no cover - should never run raise AssertionError("upsert should not be called during shutdown") embedder = _DummyEmbedder() @@ -78,7 +78,7 @@ def __init__(self): self.is_closing = False self.calls = 0 - async def upsert(self, _data): + async def upsert(self, _data, *, ctx): self.calls += 1 self.is_closing = True raise RuntimeError("IO error: lock /tmp/LOCK: already held by process") diff --git a/tests/storage/test_semantic_dag_skip_files.py b/tests/storage/test_semantic_dag_skip_files.py new file mode 100644 index 00000000..3eaeaa2f --- /dev/null +++ b/tests/storage/test_semantic_dag_skip_files.py @@ -0,0 +1,154 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +from unittest.mock import AsyncMock, MagicMock + +import pytest + +from openviking.server.identity import RequestContext, Role +from openviking.storage.queuefs.semantic_dag import SemanticDagExecutor +from openviking_cli.session.user_id import UserIdentifier + + +def _mock_transaction_layer(monkeypatch): + """Patch lock layer to no-op for DAG tests.""" + mock_handle = MagicMock() + monkeypatch.setattr( + "openviking.storage.transaction.lock_context.LockContext.__aenter__", + AsyncMock(return_value=mock_handle), + ) + monkeypatch.setattr( + "openviking.storage.transaction.lock_context.LockContext.__aexit__", + AsyncMock(return_value=False), + ) + monkeypatch.setattr( + "openviking.storage.transaction.get_lock_manager", + lambda: MagicMock(), + ) + + +class _FakeVikingFS: + def __init__(self, tree): + self._tree = tree + self.writes = [] + + async def ls(self, uri, ctx=None): + return self._tree.get(uri, []) + + async def write_file(self, path, content, ctx=None): + self.writes.append((path, content)) + + def _uri_to_path(self, uri, ctx=None): + return uri.replace("viking://", "/local/acc1/") + + +class _FakeProcessor: + def __init__(self): + self.summarized_files = [] + self.vectorized_files = [] + + async def _generate_single_file_summary(self, file_path, llm_sem=None, ctx=None): + self.summarized_files.append(file_path) + return {"name": file_path.split("/")[-1], "summary": "summary"} + + async def _generate_overview(self, dir_uri, file_summaries, children_abstracts): + return "overview" + + def _extract_abstract_from_overview(self, overview): + return "abstract" + + def _enforce_size_limits(self, overview, abstract): + return overview, abstract + + async def _vectorize_directory( + self, uri, context_type, abstract, overview, ctx=None, semantic_msg_id=None + ): + pass + + async def _vectorize_directory_simple(self, uri, context_type, abstract, overview, ctx=None): + await self._vectorize_directory(uri, context_type, abstract, overview, ctx=ctx) + + async def _vectorize_single_file( + self, parent_uri, context_type, file_path, summary_dict, ctx=None, semantic_msg_id=None + ): + self.vectorized_files.append(file_path) + + +class _DummyTracker: + async def register(self, **_kwargs): + return None + + +@pytest.mark.asyncio +async def test_messages_jsonl_excluded_from_summary(monkeypatch): + """messages.jsonl should be skipped by _list_dir and never summarized.""" + _mock_transaction_layer(monkeypatch) + root_uri = "viking://session/test-session" + tree = { + root_uri: [ + {"name": "messages.jsonl", "isDir": False}, + {"name": "notes.txt", "isDir": False}, + {"name": "document.pdf", "isDir": False}, + ], + } + fake_fs = _FakeVikingFS(tree) + monkeypatch.setattr("openviking.storage.queuefs.semantic_dag.get_viking_fs", lambda: fake_fs) + monkeypatch.setattr( + "openviking.storage.queuefs.embedding_tracker.EmbeddingTaskTracker.get_instance", + lambda: _DummyTracker(), + ) + + processor = _FakeProcessor() + ctx = RequestContext(user=UserIdentifier("acc1", "user1", "agent1"), role=Role.USER) + executor = SemanticDagExecutor( + processor=processor, + context_type="session", + max_concurrent_llm=2, + ctx=ctx, + ) + await executor.run(root_uri) + + summarized_names = [p.split("/")[-1] for p in processor.summarized_files] + assert "messages.jsonl" not in summarized_names + assert "notes.txt" in summarized_names + assert "document.pdf" in summarized_names + + +@pytest.mark.asyncio +async def test_messages_jsonl_excluded_in_subdirectory(monkeypatch): + """messages.jsonl in a subdirectory should also be skipped.""" + _mock_transaction_layer(monkeypatch) + root_uri = "viking://session/test-session" + tree = { + root_uri: [ + {"name": "subdir", "isDir": True}, + ], + f"{root_uri}/subdir": [ + {"name": "messages.jsonl", "isDir": False}, + {"name": "data.csv", "isDir": False}, + ], + } + fake_fs = _FakeVikingFS(tree) + monkeypatch.setattr("openviking.storage.queuefs.semantic_dag.get_viking_fs", lambda: fake_fs) + monkeypatch.setattr( + "openviking.storage.queuefs.embedding_tracker.EmbeddingTaskTracker.get_instance", + lambda: _DummyTracker(), + ) + + processor = _FakeProcessor() + ctx = RequestContext(user=UserIdentifier("acc1", "user1", "agent1"), role=Role.USER) + executor = SemanticDagExecutor( + processor=processor, + context_type="session", + max_concurrent_llm=2, + ctx=ctx, + ) + await executor.run(root_uri) + + summarized_names = [p.split("/")[-1] for p in processor.summarized_files] + assert "messages.jsonl" not in summarized_names + assert "data.csv" in summarized_names + + +if __name__ == "__main__": + pytest.main([__file__]) diff --git a/tests/storage/test_semantic_dag_stats.py b/tests/storage/test_semantic_dag_stats.py index 10f06c22..94f9441f 100644 --- a/tests/storage/test_semantic_dag_stats.py +++ b/tests/storage/test_semantic_dag_stats.py @@ -1,6 +1,9 @@ # Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. # SPDX-License-Identifier: Apache-2.0 +import asyncio +from unittest.mock import AsyncMock, MagicMock + import pytest from openviking.server.identity import RequestContext, Role @@ -19,6 +22,9 @@ async def ls(self, uri, ctx=None): async def write_file(self, path, content, ctx=None): self.writes.append((path, content)) + def _uri_to_path(self, uri, ctx=None): + return uri.replace("viking://", "/local/acc1/") + class _FakeProcessor: def __init__(self): @@ -34,14 +40,27 @@ async def _generate_overview(self, dir_uri, file_summaries, children_abstracts): def _extract_abstract_from_overview(self, overview): return "abstract" - async def _vectorize_directory_simple(self, uri, context_type, abstract, overview, ctx=None): + def _enforce_size_limits(self, overview, abstract): + return overview, abstract + + async def _vectorize_directory( + self, uri, context_type, abstract, overview, ctx=None, semantic_msg_id=None + ): self.vectorized_dirs.append(uri) async def _vectorize_single_file( - self, parent_uri, context_type, file_path, summary_dict, ctx=None + self, parent_uri, context_type, file_path, summary_dict, ctx=None, semantic_msg_id=None ): self.vectorized_files.append(file_path) + async def _vectorize_directory_simple(self, uri, context_type, abstract, overview, ctx=None): + await self._vectorize_directory(uri, context_type, abstract, overview, ctx=ctx) + + +class _DummyTracker: + async def register(self, **_kwargs): + return None + @pytest.mark.asyncio async def test_semantic_dag_stats_collects_nodes(monkeypatch): @@ -58,6 +77,25 @@ async def test_semantic_dag_stats_collects_nodes(monkeypatch): } fake_fs = _FakeVikingFS(tree) monkeypatch.setattr("openviking.storage.queuefs.semantic_dag.get_viking_fs", lambda: fake_fs) + monkeypatch.setattr( + "openviking.storage.queuefs.embedding_tracker.EmbeddingTaskTracker.get_instance", + lambda: _DummyTracker(), + ) + + # Mock lock layer: LockContext as no-op passthrough + mock_handle = MagicMock() + monkeypatch.setattr( + "openviking.storage.transaction.lock_context.LockContext.__aenter__", + AsyncMock(return_value=mock_handle), + ) + monkeypatch.setattr( + "openviking.storage.transaction.lock_context.LockContext.__aexit__", + AsyncMock(return_value=False), + ) + monkeypatch.setattr( + "openviking.storage.transaction.get_lock_manager", + lambda: MagicMock(), + ) processor = _FakeProcessor() ctx = RequestContext(user=UserIdentifier("acc1", "user1", "agent1"), role=Role.USER) @@ -68,6 +106,7 @@ async def test_semantic_dag_stats_collects_nodes(monkeypatch): ctx=ctx, ) await executor.run(root_uri) + await asyncio.sleep(0) stats = executor.get_stats() assert isinstance(stats, DagStats) diff --git a/tests/telemetry/test_execution.py b/tests/telemetry/test_execution.py new file mode 100644 index 00000000..12606553 --- /dev/null +++ b/tests/telemetry/test_execution.py @@ -0,0 +1,98 @@ +from types import SimpleNamespace + +import pytest + +from openviking_cli.exceptions import InvalidArgumentError +from openviking_cli.retrieve.types import FindResult + + +@pytest.mark.asyncio +async def test_run_with_telemetry_returns_usage_and_payload(): + from openviking.telemetry.execution import run_with_telemetry + + async def _run(): + return {"status": "ok"} + + execution = await run_with_telemetry( + operation="search.find", + telemetry=True, + fn=_run, + ) + + assert execution.result == {"status": "ok"} + assert execution.telemetry is not None + assert execution.telemetry["summary"]["operation"] == "search.find" + + +@pytest.mark.asyncio +async def test_run_with_telemetry_raises_invalid_argument_for_bad_request(): + from openviking.telemetry.execution import run_with_telemetry + + async def _run(): + return {"status": "ok"} + + with pytest.raises(InvalidArgumentError, match="Unsupported telemetry options: invalid"): + await run_with_telemetry( + operation="search.find", + telemetry={"invalid": True}, + fn=_run, + ) + + +@pytest.mark.asyncio +async def test_run_with_telemetry_rejects_events_selection(): + from openviking.telemetry.execution import run_with_telemetry + + async def _run(): + return {"status": "ok"} + + with pytest.raises(InvalidArgumentError, match="Unsupported telemetry options: events"): + await run_with_telemetry( + operation="search.find", + telemetry={"summary": True, "events": False}, + fn=_run, + ) + + +def test_attach_telemetry_payload_adds_telemetry_to_dict_result(): + from openviking.telemetry.execution import attach_telemetry_payload + + result = attach_telemetry_payload( + {"root_uri": "viking://resources/demo"}, + {"id": "tm_123", "summary": {"operation": "resources.add_resource"}}, + ) + + assert result["telemetry"]["summary"]["operation"] == "resources.add_resource" + + +def test_attach_telemetry_payload_does_not_mutate_object_result(): + from openviking.telemetry.execution import attach_telemetry_payload + + result = SimpleNamespace(total=1) + + attached = attach_telemetry_payload( + result, + {"id": "tm_123", "summary": {"operation": "search.find"}}, + ) + + assert attached is result + assert not hasattr(result, "telemetry") + + +def test_find_result_ignores_usage_and_telemetry_payload_fields(): + result = FindResult.from_dict( + { + "memories": [], + "resources": [], + "skills": [], + "telemetry": {"id": "tm_123", "summary": {"operation": "search.find"}}, + } + ) + + assert not hasattr(result, "telemetry") + assert result.to_dict() == { + "memories": [], + "resources": [], + "skills": [], + "total": 0, + } diff --git a/tests/telemetry/test_layering_rules.py b/tests/telemetry/test_layering_rules.py new file mode 100644 index 00000000..98dced6f --- /dev/null +++ b/tests/telemetry/test_layering_rules.py @@ -0,0 +1,30 @@ +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +DISALLOWED_PREFIXES = ( + "telemetry.event(", + "collector.event(", +) + +ALLOWED_FILES = {"openviking/session/memory_deduplicator.py"} + +CHECK_DIRS = ( + "openviking/service", + "openviking/session", + "openviking/retrieve", +) + + +def test_core_layers_do_not_directly_call_telemetry_collectors(): + offenders: list[str] = [] + for check_dir in CHECK_DIRS: + for path in (ROOT / check_dir).rglob("*.py"): + rel = path.relative_to(ROOT).as_posix() + if rel in ALLOWED_FILES: + continue + text = path.read_text() + for needle in DISALLOWED_PREFIXES: + if needle in text: + offenders.append(f"{rel}: {needle}") + + assert offenders == [] diff --git a/tests/telemetry/test_resource_summary.py b/tests/telemetry/test_resource_summary.py new file mode 100644 index 00000000..1d28e8b8 --- /dev/null +++ b/tests/telemetry/test_resource_summary.py @@ -0,0 +1,58 @@ +from types import SimpleNamespace + +from openviking.telemetry.operation import OperationTelemetry + + +def test_record_resource_wait_metrics_collects_queue_and_dag_stats(monkeypatch): + from openviking.telemetry.resource_summary import record_resource_wait_metrics + + telemetry = OperationTelemetry(operation="resources.add_resource", enabled=True) + telemetry_id = telemetry.telemetry_id + queue_status = { + "Semantic": SimpleNamespace(processed=3, error_count=1, errors=[]), + "Embedding": SimpleNamespace(processed=5, error_count=0, errors=[]), + } + + class _SemanticStats: + processed = 7 + error_count = 2 + + class _EmbeddingStats: + processed = 11 + error_count = 1 + + class _DagStats: + total_nodes = 9 + done_nodes = 8 + pending_nodes = 1 + in_progress_nodes = 0 + + monkeypatch.setattr( + "openviking.telemetry.resource_summary._consume_semantic_request_stats", + lambda _tid: _SemanticStats(), + ) + monkeypatch.setattr( + "openviking.telemetry.resource_summary._consume_embedding_request_stats", + lambda _tid: _EmbeddingStats(), + ) + monkeypatch.setattr( + "openviking.telemetry.resource_summary._consume_semantic_dag_stats", + lambda _tid, _uri: _DagStats(), + ) + + record_resource_wait_metrics( + telemetry=telemetry, + telemetry_id=telemetry_id, + queue_status=queue_status, + root_uri="viking://resources/demo", + ) + + summary = telemetry.finish().summary + assert summary["queue"]["semantic"]["processed"] == 7 + assert summary["queue"]["semantic"]["error_count"] == 2 + assert summary["queue"]["embedding"]["processed"] == 11 + assert summary["queue"]["embedding"]["error_count"] == 1 + assert summary["semantic_nodes"]["total"] == 9 + assert summary["semantic_nodes"]["done"] == 8 + assert summary["semantic_nodes"]["pending"] == 1 + assert summary["semantic_nodes"]["running"] == 0 diff --git a/tests/test_session_task_tracking.py b/tests/test_session_task_tracking.py index ab779fb2..1306d500 100644 --- a/tests/test_session_task_tracking.py +++ b/tests/test_session_task_tracking.py @@ -72,6 +72,40 @@ async def fake_commit(_sid, _ctx): await asyncio.wait_for(done.wait(), timeout=2.0) +async def test_commit_wait_false_rejects_full_telemetry(api_client): + """wait=false should reject telemetry payload requests.""" + client, _ = api_client + session_id = await _new_session_with_message(client) + + resp = await client.post( + f"/api/v1/sessions/{session_id}/commit", + params={"wait": False}, + json={"telemetry": True}, + ) + assert resp.status_code == 400 + body = resp.json() + assert body["status"] == "error" + assert body["error"]["code"] == "INVALID_ARGUMENT" + assert "wait=false" in body["error"]["message"] + + +async def test_commit_wait_false_rejects_summary_only_telemetry(api_client): + """wait=false should also reject summary-only telemetry requests.""" + client, _ = api_client + session_id = await _new_session_with_message(client) + + resp = await client.post( + f"/api/v1/sessions/{session_id}/commit", + params={"wait": False}, + json={"telemetry": {"summary": True}}, + ) + assert resp.status_code == 400 + body = resp.json() + assert body["status"] == "error" + assert body["error"]["code"] == "INVALID_ARGUMENT" + assert "wait=false" in body["error"]["message"] + + # ── Task lifecycle: pending → running → completed ── @@ -139,6 +173,34 @@ async def failing_commit(_sid, _ctx): assert "LLM provider timeout" in result["error"] +async def test_task_failed_when_memory_extraction_raises(api_client): + """Extractor failures should propagate to task error instead of silent completed+0.""" + client, service = api_client + session_id = await _new_session_with_message(client) + + async def failing_extract(_context, _user, _session_id): + raise RuntimeError("memory_extraction_failed: synthetic extractor error") + + service.sessions._session_compressor.extractor.extract = failing_extract + + resp = await client.post(f"/api/v1/sessions/{session_id}/commit", params={"wait": False}) + task_id = resp.json()["result"]["task_id"] + + result = None + for _ in range(120): + await asyncio.sleep(0.1) + task_resp = await client.get(f"/api/v1/tasks/{task_id}") + assert task_resp.status_code == 200 + result = task_resp.json()["result"] + if result["status"] in {"completed", "failed"}: + break + + assert result is not None + assert result["status"] in {"completed", "failed"} + assert result["status"] == "failed" + assert "memory_extraction_failed" in result["error"] + + # ── Duplicate commit rejection ── @@ -168,6 +230,35 @@ async def slow_commit(_sid, _ctx): await asyncio.sleep(0.1) +async def test_wait_true_rejected_while_background_commit_running(api_client): + """wait=true must also reject duplicate commits for the same session.""" + client, service = api_client + session_id = await _new_session_with_message(client) + + gate = asyncio.Event() + + async def slow_commit(_sid, _ctx): + await gate.wait() + return {"session_id": _sid, "status": "committed", "memories_extracted": 0} + + service.sessions.commit_async = slow_commit + + resp1 = await client.post(f"/api/v1/sessions/{session_id}/commit", params={"wait": False}) + assert resp1.json()["result"]["status"] == "accepted" + + resp2 = await client.post( + f"/api/v1/sessions/{session_id}/commit", + params={"wait": True}, + json={"telemetry": True}, + ) + assert resp2.status_code == 200 + assert resp2.json()["status"] == "error" + assert "already has a commit in progress" in resp2.json()["error"]["message"] + + gate.set() + await asyncio.sleep(0.1) + + # ── GET /tasks/{id} 404 ── diff --git a/tests/test_telemetry_runtime.py b/tests/test_telemetry_runtime.py new file mode 100644 index 00000000..d3700706 --- /dev/null +++ b/tests/test_telemetry_runtime.py @@ -0,0 +1,307 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import json +from types import SimpleNamespace + +import pytest + +from openviking.models.embedder.base import EmbedResult +from openviking.server.identity import RequestContext, Role +from openviking.service.resource_service import ResourceService +from openviking.storage.collection_schemas import TextEmbeddingHandler +from openviking.storage.queuefs.semantic_dag import DagStats +from openviking.storage.queuefs.semantic_msg import SemanticMsg +from openviking.storage.queuefs.semantic_processor import SemanticProcessor +from openviking.telemetry import ( + get_current_telemetry, + get_telemetry_runtime, + register_telemetry, + unregister_telemetry, +) +from openviking.telemetry.backends.memory import MemoryOperationTelemetry +from openviking.telemetry.context import bind_telemetry +from openviking.telemetry.snapshot import TelemetrySnapshot +from openviking_cli.session.user_id import UserIdentifier + + +def test_telemetry_module_exports_snapshot_and_runtime(): + snapshot = TelemetrySnapshot( + telemetry_id="tm_demo", + summary={"duration_ms": 1.2}, + ) + usage = snapshot.to_usage_dict() + + assert usage == {"duration_ms": 1.2, "token_total": 0} + assert get_telemetry_runtime().meter() is not None + + +def test_telemetry_snapshot_to_dict_supports_summary_only(): + snapshot = TelemetrySnapshot( + telemetry_id="tm_demo", + summary={"duration_ms": 1.2, "tokens": {"total": 3}}, + ) + + payload = snapshot.to_dict(include_summary=True) + + assert payload == { + "id": "tm_demo", + "summary": {"duration_ms": 1.2, "tokens": {"total": 3}}, + } + + +def test_telemetry_summary_breaks_down_llm_and_embedding_token_usage(): + telemetry = MemoryOperationTelemetry(operation="resources.add_resource", enabled=True) + telemetry.record_token_usage("llm", 11, 7) + telemetry.record_token_usage("embedding", 13, 0) + + summary = telemetry.finish().summary + assert telemetry.telemetry_id + assert telemetry.telemetry_id.startswith("tm_") + assert summary["tokens"]["total"] == 31 + assert summary["duration_ms"] >= 0 + assert summary["tokens"]["llm"] == { + "input": 11, + "output": 7, + "total": 18, + } + assert summary["tokens"]["embedding"] == {"total": 13} + assert "queue" not in summary + assert "vector" not in summary + assert "semantic_nodes" not in summary + assert "memory" not in summary + assert "errors" not in summary + + +def test_telemetry_summary_uses_simplified_internal_metric_keys(): + summary = MemoryOperationTelemetry( + operation="search.find", + enabled=True, + ) + summary.count("vector.searches", 2) + summary.count("vector.scored", 5) + summary.count("vector.passed", 3) + summary.set("vector.returned", 2) + summary.count("vector.scanned", 5) + summary.set("vector.scan_reason", "") + summary.set("semantic_nodes.total", 4) + summary.set("semantic_nodes.done", 3) + summary.set("semantic_nodes.pending", 1) + summary.set("semantic_nodes.running", 0) + summary.set("memory.extracted", 6) + + result = summary.finish().summary + + assert result["vector"] == { + "searches": 2, + "scored": 5, + "passed": 3, + "returned": 2, + "scanned": 5, + "scan_reason": "", + } + assert result["semantic_nodes"] == { + "total": 4, + "done": 3, + "pending": 1, + "running": 0, + } + assert result["memory"] == {"extracted": 6} + + +def test_telemetry_summary_detects_groups_by_prefix_without_static_key_lists(): + telemetry = MemoryOperationTelemetry(operation="search.find", enabled=True) + telemetry.set("vector.debug_probe", 1) + telemetry.set("queue.semantic.processed", 2) + telemetry.set("memory.extracted", 1) + + result = telemetry.finish().summary + + assert "vector" in result + assert "queue" in result + assert "memory" in result + + +@pytest.mark.asyncio +async def test_semantic_processor_binds_registered_operation_telemetry(monkeypatch): + telemetry = MemoryOperationTelemetry(operation="resources.add_resource", enabled=True) + register_telemetry(telemetry) + + processor = SemanticProcessor() + + class FakeVikingFS: + async def ls(self, uri, ctx=None): + return [] + + class _FakeDagExecutor: + def __init__(self, **kwargs): + pass + + async def run(self, root_uri): + assert get_current_telemetry() is telemetry + get_current_telemetry().record_token_usage("llm", 11, 7) + + def get_stats(self): + return DagStats() + + monkeypatch.setattr( + "openviking.storage.queuefs.semantic_processor.get_viking_fs", + lambda: FakeVikingFS(), + ) + monkeypatch.setattr( + "openviking.storage.queuefs.semantic_processor.SemanticDagExecutor", + lambda **kwargs: _FakeDagExecutor(**kwargs), + ) + + try: + await processor.on_dequeue( + SemanticMsg( + uri="viking://resources/demo", + context_type="resource", + recursive=False, + telemetry_id=telemetry.telemetry_id, + ).to_dict() + ) + finally: + unregister_telemetry(telemetry.telemetry_id) + + result = telemetry.finish() + summary = result.summary + assert summary["tokens"]["total"] == 18 + assert summary["tokens"]["llm"]["total"] == 18 + assert summary["tokens"]["embedding"]["total"] == 0 + + +@pytest.mark.asyncio +async def test_embedding_handler_binds_registered_operation_telemetry(monkeypatch): + telemetry = MemoryOperationTelemetry(operation="resources.add_resource", enabled=True) + register_telemetry(telemetry) + + class _TelemetryAwareEmbedder: + def embed(self, text: str) -> EmbedResult: + assert text == "hello" + get_current_telemetry().record_token_usage("embedding", 9, 0) + return EmbedResult(dense_vector=[0.1, 0.2]) + + class _DummyConfig: + def __init__(self): + self.storage = SimpleNamespace(vectordb=SimpleNamespace(name="context")) + self.embedding = SimpleNamespace( + dimension=2, + get_embedder=lambda: _TelemetryAwareEmbedder(), + ) + + class _DummyVikingDB: + is_closing = False + + async def upsert(self, _data, *, ctx=None): + return "rec-1" + + monkeypatch.setattr( + "openviking_cli.utils.config.get_openviking_config", + lambda: _DummyConfig(), + ) + + handler = TextEmbeddingHandler(_DummyVikingDB()) + payload = { + "data": json.dumps( + { + "id": "msg-1", + "message": "hello", + "telemetry_id": telemetry.telemetry_id, + "context_data": { + "id": "id-1", + "uri": "viking://resources/sample", + "account_id": "default", + "abstract": "sample", + }, + } + ) + } + + try: + await handler.on_dequeue(payload) + finally: + unregister_telemetry(telemetry.telemetry_id) + + result = telemetry.finish() + summary = result.summary + assert summary["tokens"]["embedding"] == {"total": 9} + + +@pytest.mark.asyncio +async def test_resource_service_add_resource_reports_queue_summary(monkeypatch): + telemetry = MemoryOperationTelemetry(operation="resources.add_resource", enabled=True) + + class _DummyProcessor: + async def process_resource(self, **kwargs): + return { + "status": "success", + "root_uri": "viking://resources/demo", + } + + class _DummyQueueManager: + async def wait_complete(self, timeout=None): + return { + "Semantic": SimpleNamespace(processed=2, error_count=1, errors=[]), + "Embedding": SimpleNamespace(processed=5, error_count=0, errors=[]), + } + + monkeypatch.setattr( + "openviking.service.resource_service.get_queue_manager", + lambda: _DummyQueueManager(), + ) + + class _DagStats: + total_nodes = 3 + done_nodes = 2 + pending_nodes = 1 + in_progress_nodes = 0 + + monkeypatch.setattr( + "openviking.storage.queuefs.semantic_processor.SemanticProcessor.consume_dag_stats", + classmethod(lambda cls, telemetry_id="", uri=None: _DagStats()), + ) + + service = ResourceService( + vikingdb=object(), + viking_fs=object(), + resource_processor=_DummyProcessor(), + skill_processor=object(), + ) + ctx = RequestContext(user=UserIdentifier.the_default_user(), role=Role.ROOT) + + with bind_telemetry(telemetry): + result = await service.add_resource(path="/tmp/demo.md", ctx=ctx, wait=True) + + assert result["root_uri"] == "viking://resources/demo" + telemetry_result = telemetry.finish() + summary = telemetry_result.summary + assert summary["queue"] == { + "semantic": {"processed": 2, "error_count": 1}, + "embedding": {"processed": 5, "error_count": 0}, + } + assert summary["semantic_nodes"] == { + "total": 3, + "done": 2, + "pending": 1, + "running": 0, + } + assert "memory" not in summary + assert "errors" not in summary + + +def test_telemetry_summary_includes_only_memory_group_when_memory_metrics_exist(): + telemetry = MemoryOperationTelemetry(operation="session.commit", enabled=True) + telemetry.record_token_usage("llm", 5, 3) + telemetry.set("memory.extracted", 4) + + summary = telemetry.finish().summary + + assert summary["memory"] == {"extracted": 4} + assert "queue" not in summary + assert "vector" not in summary + assert "semantic_nodes" not in summary + assert "errors" not in summary diff --git a/tests/transaction/__init__.py b/tests/transaction/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/transaction/conftest.py b/tests/transaction/conftest.py new file mode 100644 index 00000000..a0952289 --- /dev/null +++ b/tests/transaction/conftest.py @@ -0,0 +1,139 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Shared fixtures for transaction tests using real AGFS and VectorDB backends.""" + +import os +import shutil +import uuid + +import pytest + +from openviking.agfs_manager import AGFSManager +from openviking.server.identity import RequestContext, Role +from openviking.storage.collection_schemas import CollectionSchemas +from openviking.storage.transaction.lock_manager import LockManager +from openviking.storage.transaction.path_lock import LOCK_FILE_NAME, _make_fencing_token +from openviking.storage.transaction.redo_log import RedoLog +from openviking.storage.viking_vector_index_backend import VikingVectorIndexBackend +from openviking.utils.agfs_utils import create_agfs_client +from openviking_cli.session.user_id import UserIdentifier +from openviking_cli.utils.config.agfs_config import AGFSConfig +from openviking_cli.utils.config.vectordb_config import VectorDBBackendConfig + +AGFS_CONF = AGFSConfig( + path="/tmp/ov-tx-test", backend="local", port=1834, url="http://localhost:1834", timeout=10 +) + +VECTOR_DIM = 4 +COLLECTION_NAME = "tx_test_ctx" + +# Clean slate before session starts +if os.path.exists(AGFS_CONF.path): + shutil.rmtree(AGFS_CONF.path) + + +@pytest.fixture(scope="session") +def agfs_manager(): + manager = AGFSManager(config=AGFS_CONF) + manager.start() + yield manager + manager.stop() + + +@pytest.fixture(scope="session") +def agfs_client(agfs_manager): + return create_agfs_client(AGFS_CONF) + + +def _mkdir_ok(agfs_client, path): + """Create directory, ignoring already-exists errors.""" + try: + agfs_client.mkdir(path) + except Exception: + pass # already exists + + +@pytest.fixture +def test_dir(agfs_client): + path = f"/local/tx-tests/{uuid.uuid4().hex}" + _mkdir_ok(agfs_client, "/local") + _mkdir_ok(agfs_client, "/local/tx-tests") + _mkdir_ok(agfs_client, path) + yield path + try: + agfs_client.rm(path, recursive=True) + except Exception: + pass + + +# --------------------------------------------------------------------------- +# VectorDB fixtures +# --------------------------------------------------------------------------- + + +@pytest.fixture(scope="session") +def vector_store(tmp_path_factory): + """Session-scoped real local VectorDB backend.""" + db_path = str(tmp_path_factory.mktemp("vectordb")) + config = VectorDBBackendConfig( + backend="local", + name=COLLECTION_NAME, + path=db_path, + dimension=VECTOR_DIM, + ) + store = VikingVectorIndexBackend(config=config) + + import asyncio + + schema = CollectionSchemas.context_collection(COLLECTION_NAME, VECTOR_DIM) + asyncio.get_event_loop().run_until_complete(store.create_collection(COLLECTION_NAME, schema)) + + yield store + + asyncio.get_event_loop().run_until_complete(store.close()) + + +@pytest.fixture(scope="session") +def request_ctx(): + """Session-scoped RequestContext for VectorDB operations.""" + user = UserIdentifier("default", "test_user", "default") + return RequestContext(user=user, role=Role.ROOT) + + +# --------------------------------------------------------------------------- +# Lock fixtures +# --------------------------------------------------------------------------- + + +@pytest.fixture +def lock_manager(agfs_client): + """Function-scoped LockManager with real AGFS backend.""" + return LockManager(agfs=agfs_client, lock_timeout=1.0, lock_expire=1.0) + + +@pytest.fixture +def redo_log(agfs_client): + """Function-scoped RedoLog with real AGFS backend.""" + return RedoLog(agfs_client) + + +# --------------------------------------------------------------------------- +# Utility helpers +# --------------------------------------------------------------------------- + + +def file_exists(agfs_client, path) -> bool: + """Check if a file/dir exists in AGFS.""" + try: + agfs_client.stat(path) + return True + except Exception: + return False + + +def make_lock_file(agfs_client, dir_path, tx_id, lock_type="P") -> str: + """Create a real lock file in AGFS and return its path.""" + lock_path = f"{dir_path.rstrip('/')}/{LOCK_FILE_NAME}" + token = _make_fencing_token(tx_id, lock_type) + agfs_client.write(lock_path, token.encode("utf-8")) + return lock_path diff --git a/tests/transaction/test_concurrent_lock.py b/tests/transaction/test_concurrent_lock.py new file mode 100644 index 00000000..7e25ab57 --- /dev/null +++ b/tests/transaction/test_concurrent_lock.py @@ -0,0 +1,103 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for concurrent lock acquisition using real AGFS backend.""" + +import asyncio +import uuid + +from openviking.storage.transaction.lock_handle import LockHandle +from openviking.storage.transaction.path_lock import PathLock + + +class TestConcurrentLock: + async def test_point_mutual_exclusion_same_path(self, agfs_client, test_dir): + """两个任务竞争同一路径的 POINT 锁,均最终成功(串行执行)。""" + lock = PathLock(agfs_client) + + results = {} + + async def holder(tx_id): + tx = LockHandle(id=tx_id) + ok = await lock.acquire_point(test_dir, tx, timeout=5.0) + if ok: + await asyncio.sleep(0.3) + await lock.release(tx) + results[tx_id] = ok + + await asyncio.gather( + holder("tx-conc-1"), + holder("tx-conc-2"), + ) + + # Both should eventually succeed (one waits for the other) + assert results["tx-conc-1"] is True + assert results["tx-conc-2"] is True + + async def test_subtree_blocks_concurrent_point_child(self, agfs_client, test_dir): + """SUBTREE on parent 持锁期间,子目录的 POINT 被阻塞,释放后成功。""" + child = f"{test_dir}/child-{uuid.uuid4().hex}" + agfs_client.mkdir(child) + + lock = PathLock(agfs_client) + parent_acquired = asyncio.Event() + parent_released = asyncio.Event() + + child_result = {} + + async def parent_holder(): + tx = LockHandle(id="tx-sub-parent") + ok = await lock.acquire_subtree(test_dir, tx, timeout=5.0) + assert ok is True + parent_acquired.set() + await asyncio.sleep(0.5) + await lock.release(tx) + parent_released.set() + + async def child_worker(): + await parent_acquired.wait() + tx = LockHandle(id="tx-sub-child") + ok = await lock.acquire_point(child, tx, timeout=5.0) + child_result["ok"] = ok + child_result["after_release"] = parent_released.is_set() + if ok: + await lock.release(tx) + + await asyncio.gather(parent_holder(), child_worker()) + + assert child_result["ok"] is True + # Child should succeed only after parent released + assert child_result["after_release"] is True + + async def test_point_child_blocks_concurrent_subtree_parent(self, agfs_client, test_dir): + """POINT on child 持锁期间,父目录的 SUBTREE 被阻塞,释放后成功。""" + child = f"{test_dir}/child-{uuid.uuid4().hex}" + agfs_client.mkdir(child) + + lock = PathLock(agfs_client) + child_acquired = asyncio.Event() + child_released = asyncio.Event() + + parent_result = {} + + async def child_holder(): + tx = LockHandle(id="tx-rev-child") + ok = await lock.acquire_point(child, tx, timeout=5.0) + assert ok is True + child_acquired.set() + await asyncio.sleep(0.5) + await lock.release(tx) + child_released.set() + + async def parent_worker(): + await child_acquired.wait() + tx = LockHandle(id="tx-rev-parent") + ok = await lock.acquire_subtree(test_dir, tx, timeout=5.0) + parent_result["ok"] = ok + parent_result["after_release"] = child_released.is_set() + if ok: + await lock.release(tx) + + await asyncio.gather(child_holder(), parent_worker()) + + assert parent_result["ok"] is True + assert parent_result["after_release"] is True diff --git a/tests/transaction/test_e2e.py b/tests/transaction/test_e2e.py new file mode 100644 index 00000000..2f284f53 --- /dev/null +++ b/tests/transaction/test_e2e.py @@ -0,0 +1,125 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""End-to-end lock tests using real AGFS backend. + +These tests exercise LockContext -> LockManager -> PathLock -> AGFS, +verifying the acquire -> operate -> release lifecycle. +""" + +import uuid + +import pytest + +from openviking.storage.errors import LockAcquisitionError +from openviking.storage.transaction.lock_context import LockContext +from openviking.storage.transaction.lock_manager import LockManager +from openviking.storage.transaction.path_lock import LOCK_FILE_NAME + + +def _lock_file_gone(agfs_client, lock_path: str) -> bool: + """Return True if the lock file does not exist in AGFS.""" + try: + agfs_client.stat(lock_path) + return False + except Exception: + return True + + +@pytest.fixture +def lock_manager(agfs_client): + return LockManager(agfs=agfs_client, lock_timeout=1.0, lock_expire=1.0) + + +class TestLockContextCommit: + async def test_lock_acquired_and_released(self, agfs_client, lock_manager, test_dir): + """Lock is held inside the context and released after exit.""" + lock_path = f"{test_dir}/{LOCK_FILE_NAME}" + + async with LockContext(lock_manager, [test_dir], lock_mode="point"): + token = agfs_client.cat(lock_path) + assert token is not None + + assert _lock_file_gone(agfs_client, lock_path) + + async def test_file_persists_after_context(self, agfs_client, lock_manager, test_dir): + """Files written inside a lock context persist.""" + file_path = f"{test_dir}/committed-file.txt" + + async with LockContext(lock_manager, [test_dir], lock_mode="point"): + agfs_client.write(file_path, b"committed data") + + content = agfs_client.cat(file_path) + assert content == b"committed data" + + +class TestLockContextException: + async def test_lock_released_on_exception(self, agfs_client, lock_manager, test_dir): + """Lock is released even when an exception occurs inside the context.""" + lock_path = f"{test_dir}/{LOCK_FILE_NAME}" + + with pytest.raises(RuntimeError): + async with LockContext(lock_manager, [test_dir], lock_mode="point"): + token = agfs_client.cat(lock_path) + assert token is not None + raise RuntimeError("simulated failure") + + assert _lock_file_gone(agfs_client, lock_path) + + async def test_exception_not_swallowed(self, agfs_client, lock_manager, test_dir): + """Exceptions propagate through the context manager.""" + with pytest.raises(ValueError, match="test error"): + async with LockContext(lock_manager, [test_dir], lock_mode="point"): + raise ValueError("test error") + + +class TestLockContextMv: + async def test_mv_lock_acquires_both_paths(self, agfs_client, lock_manager, test_dir): + """mv lock mode acquires SUBTREE on both source and destination.""" + src = f"{test_dir}/mv-src-{uuid.uuid4().hex}" + dst = f"{test_dir}/mv-dst-{uuid.uuid4().hex}" + agfs_client.mkdir(src) + agfs_client.mkdir(dst) + + async with LockContext(lock_manager, [src], lock_mode="mv", mv_dst_parent_path=dst): + src_token = agfs_client.cat(f"{src}/{LOCK_FILE_NAME}") + dst_token = agfs_client.cat(f"{dst}/{LOCK_FILE_NAME}") + src_token_str = src_token.decode("utf-8") if isinstance(src_token, bytes) else src_token + dst_token_str = dst_token.decode("utf-8") if isinstance(dst_token, bytes) else dst_token + assert ":S" in src_token_str + assert ":S" in dst_token_str + + for path in [f"{src}/{LOCK_FILE_NAME}", f"{dst}/{LOCK_FILE_NAME}"]: + assert _lock_file_gone(agfs_client, path) + + +class TestLockContextSubtree: + async def test_subtree_lock_and_release(self, agfs_client, lock_manager, test_dir): + """Subtree lock is acquired and released.""" + target = f"{test_dir}/sub-{uuid.uuid4().hex}" + agfs_client.mkdir(target) + + async with LockContext(lock_manager, [target], lock_mode="subtree"): + token = agfs_client.cat(f"{target}/{LOCK_FILE_NAME}") + token_str = token.decode("utf-8") if isinstance(token, bytes) else token + assert ":S" in token_str + + assert _lock_file_gone(agfs_client, f"{target}/{LOCK_FILE_NAME}") + + +class TestSequentialLocks: + async def test_sequential_locks_on_same_path(self, agfs_client, lock_manager, test_dir): + """Multiple sequential lock contexts on the same path succeed.""" + for i in range(3): + async with LockContext(lock_manager, [test_dir], lock_mode="point"): + agfs_client.write(f"{test_dir}/f{i}.txt", f"data-{i}".encode()) + + for i in range(3): + content = agfs_client.cat(f"{test_dir}/f{i}.txt") + assert content == f"data-{i}".encode() + + async def test_lock_acquisition_failure(self, agfs_client, lock_manager, test_dir): + """LockContext raises LockAcquisitionError for nonexistent path.""" + nonexistent = f"{test_dir}/nonexistent-{uuid.uuid4().hex}" + with pytest.raises(LockAcquisitionError): + async with LockContext(lock_manager, [nonexistent], lock_mode="point"): + pass diff --git a/tests/transaction/test_lock_context.py b/tests/transaction/test_lock_context.py new file mode 100644 index 00000000..131fb48e --- /dev/null +++ b/tests/transaction/test_lock_context.py @@ -0,0 +1,85 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for LockContext async context manager.""" + +import uuid + +import pytest + +from openviking.storage.errors import LockAcquisitionError +from openviking.storage.transaction.lock_context import LockContext +from openviking.storage.transaction.lock_manager import LockManager +from openviking.storage.transaction.path_lock import LOCK_FILE_NAME + + +def _lock_file_gone(agfs_client, lock_path: str) -> bool: + try: + agfs_client.stat(lock_path) + return False + except Exception: + return True + + +@pytest.fixture +def lm(agfs_client): + return LockManager(agfs=agfs_client, lock_timeout=1.0, lock_expire=1.0) + + +class TestLockContextPoint: + async def test_point_lock_lifecycle(self, agfs_client, lm, test_dir): + lock_path = f"{test_dir}/{LOCK_FILE_NAME}" + + async with LockContext(lm, [test_dir], lock_mode="point") as handle: + assert handle is not None + token = agfs_client.cat(lock_path) + assert token is not None + + assert _lock_file_gone(agfs_client, lock_path) + + async def test_lock_released_on_exception(self, agfs_client, lm, test_dir): + lock_path = f"{test_dir}/{LOCK_FILE_NAME}" + + with pytest.raises(RuntimeError): + async with LockContext(lm, [test_dir], lock_mode="point"): + assert agfs_client.cat(lock_path) is not None + raise RuntimeError("fail") + + assert _lock_file_gone(agfs_client, lock_path) + + async def test_exception_propagates(self, lm, test_dir): + with pytest.raises(ValueError, match="test"): + async with LockContext(lm, [test_dir], lock_mode="point"): + raise ValueError("test") + + +class TestLockContextSubtree: + async def test_subtree_lock(self, agfs_client, lm, test_dir): + async with LockContext(lm, [test_dir], lock_mode="subtree"): + token = agfs_client.cat(f"{test_dir}/{LOCK_FILE_NAME}") + token_str = token.decode("utf-8") if isinstance(token, bytes) else token + assert ":S" in token_str + + +class TestLockContextMv: + async def test_mv_lock(self, agfs_client, lm, test_dir): + src = f"{test_dir}/src-{uuid.uuid4().hex}" + dst = f"{test_dir}/dst-{uuid.uuid4().hex}" + agfs_client.mkdir(src) + agfs_client.mkdir(dst) + + async with LockContext(lm, [src], lock_mode="mv", mv_dst_parent_path=dst) as handle: + assert len(handle.locks) == 2 + + +class TestLockContextFailure: + async def test_nonexistent_path_raises(self, lm): + with pytest.raises(LockAcquisitionError): + async with LockContext(lm, ["/local/nonexistent-xyz"], lock_mode="point"): + pass + + async def test_handle_cleaned_up_on_failure(self, lm): + with pytest.raises(LockAcquisitionError): + async with LockContext(lm, ["/local/nonexistent-xyz"], lock_mode="point"): + pass + + assert len(lm.get_active_handles()) == 0 diff --git a/tests/transaction/test_lock_manager.py b/tests/transaction/test_lock_manager.py new file mode 100644 index 00000000..e30f724b --- /dev/null +++ b/tests/transaction/test_lock_manager.py @@ -0,0 +1,88 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for LockManager.""" + +import uuid + +import pytest + +from openviking.storage.transaction.lock_manager import LockManager +from openviking.storage.transaction.path_lock import LOCK_FILE_NAME + + +def _lock_file_gone(agfs_client, lock_path: str) -> bool: + try: + agfs_client.stat(lock_path) + return False + except Exception: + return True + + +@pytest.fixture +def lm(agfs_client): + return LockManager(agfs=agfs_client, lock_timeout=1.0, lock_expire=1.0) + + +class TestLockManagerBasic: + async def test_create_handle_and_acquire_point(self, agfs_client, lm, test_dir): + handle = lm.create_handle() + ok = await lm.acquire_point(handle, test_dir) + assert ok is True + + lock_path = f"{test_dir}/{LOCK_FILE_NAME}" + content = agfs_client.cat(lock_path) + assert content is not None + + await lm.release(handle) + assert _lock_file_gone(agfs_client, lock_path) + + async def test_acquire_subtree(self, agfs_client, lm, test_dir): + handle = lm.create_handle() + ok = await lm.acquire_subtree(handle, test_dir) + assert ok is True + + token = agfs_client.cat(f"{test_dir}/{LOCK_FILE_NAME}") + token_str = token.decode("utf-8") if isinstance(token, bytes) else token + assert ":S" in token_str + + await lm.release(handle) + + async def test_acquire_mv(self, agfs_client, lm, test_dir): + src = f"{test_dir}/mv-src-{uuid.uuid4().hex}" + dst = f"{test_dir}/mv-dst-{uuid.uuid4().hex}" + agfs_client.mkdir(src) + agfs_client.mkdir(dst) + + handle = lm.create_handle() + ok = await lm.acquire_mv(handle, src, dst) + assert ok is True + assert len(handle.locks) == 2 + + await lm.release(handle) + assert handle.id not in lm.get_active_handles() + + async def test_release_removes_from_active(self, lm, test_dir): + handle = lm.create_handle() + assert handle.id in lm.get_active_handles() + + await lm.acquire_point(handle, test_dir) + await lm.release(handle) + + assert handle.id not in lm.get_active_handles() + + async def test_stop_releases_all(self, agfs_client, lm, test_dir): + h1 = lm.create_handle() + h2 = lm.create_handle() + await lm.acquire_point(h1, test_dir) + + sub = f"{test_dir}/sub-{uuid.uuid4().hex}" + agfs_client.mkdir(sub) + await lm.acquire_point(h2, sub) + + await lm.stop() + assert len(lm.get_active_handles()) == 0 + + async def test_nonexistent_path_fails(self, lm): + handle = lm.create_handle() + ok = await lm.acquire_point(handle, "/local/nonexistent-xyz") + assert ok is False diff --git a/tests/transaction/test_path_lock.py b/tests/transaction/test_path_lock.py new file mode 100644 index 00000000..0b721e07 --- /dev/null +++ b/tests/transaction/test_path_lock.py @@ -0,0 +1,336 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for path lock with fencing tokens.""" + +import time +from unittest.mock import MagicMock + +from openviking.storage.transaction.lock_handle import LockHandle +from openviking.storage.transaction.path_lock import ( + LOCK_FILE_NAME, + LOCK_TYPE_POINT, + LOCK_TYPE_SUBTREE, + PathLock, + _make_fencing_token, + _parse_fencing_token, +) + + +class TestFencingToken: + def test_make_parse_roundtrip(self): + token = _make_fencing_token("tx-123") + tx_id, ts, lock_type = _parse_fencing_token(token) + assert tx_id == "tx-123" + assert ts > 0 + assert lock_type == LOCK_TYPE_POINT + + def test_make_parse_subtree_roundtrip(self): + token = _make_fencing_token("tx-456", LOCK_TYPE_SUBTREE) + tx_id, ts, lock_type = _parse_fencing_token(token) + assert tx_id == "tx-456" + assert ts > 0 + assert lock_type == LOCK_TYPE_SUBTREE + + def test_parse_legacy_format_two_part(self): + """Legacy two-part token "{tx_id}:{ts}" defaults to POINT.""" + tx_id, ts, lock_type = _parse_fencing_token("tx-old:1234567890") + assert tx_id == "tx-old" + assert ts == 1234567890 + assert lock_type == LOCK_TYPE_POINT + + def test_parse_legacy_format_plain(self): + """Plain tx_id (no colon) defaults to ts=0, lock_type=POINT.""" + tx_id, ts, lock_type = _parse_fencing_token("tx-bare") + assert tx_id == "tx-bare" + assert ts == 0 + assert lock_type == LOCK_TYPE_POINT + + def test_tokens_are_unique(self): + t1 = _make_fencing_token("tx-1") + time.sleep(0.001) + t2 = _make_fencing_token("tx-1") + assert t1 != t2 + + +class TestPathLockStale: + def test_is_lock_stale_no_file(self): + agfs = MagicMock() + agfs.read.side_effect = Exception("not found") + lock = PathLock(agfs) + assert lock.is_lock_stale("/test/.path.ovlock") is True + + def test_is_lock_stale_legacy_token(self): + agfs = MagicMock() + agfs.read.return_value = b"tx-old-format" + lock = PathLock(agfs) + assert lock.is_lock_stale("/test/.path.ovlock") is True + + def test_is_lock_stale_recent_token(self): + agfs = MagicMock() + token = _make_fencing_token("tx-1") + agfs.read.return_value = token.encode("utf-8") + lock = PathLock(agfs) + assert lock.is_lock_stale("/test/.path.ovlock", expire_seconds=300.0) is False + + +class TestPathLockBehavior: + """Behavioral tests using real AGFS backend.""" + + async def test_acquire_point_creates_lock_file(self, agfs_client, test_dir): + lock = PathLock(agfs_client) + tx = LockHandle(id="tx-point-1") + + ok = await lock.acquire_point(test_dir, tx, timeout=3.0) + assert ok is True + + lock_path = f"{test_dir}/{LOCK_FILE_NAME}" + content = agfs_client.cat(lock_path) + token = content.decode("utf-8") if isinstance(content, bytes) else content + assert ":P" in token + assert "tx-point-1" in token + + await lock.release(tx) + + async def test_acquire_subtree_creates_lock_file(self, agfs_client, test_dir): + lock = PathLock(agfs_client) + tx = LockHandle(id="tx-subtree-1") + + ok = await lock.acquire_subtree(test_dir, tx, timeout=3.0) + assert ok is True + + lock_path = f"{test_dir}/{LOCK_FILE_NAME}" + content = agfs_client.cat(lock_path) + token = content.decode("utf-8") if isinstance(content, bytes) else content + assert ":S" in token + assert "tx-subtree-1" in token + + await lock.release(tx) + + async def test_acquire_point_dir_not_found(self, agfs_client): + lock = PathLock(agfs_client) + tx = LockHandle(id="tx-no-dir") + + ok = await lock.acquire_point("/local/nonexistent-path-xyz", tx, timeout=0.5) + assert ok is False + assert len(tx.locks) == 0 + + async def test_release_removes_lock_file(self, agfs_client, test_dir): + lock = PathLock(agfs_client) + tx = LockHandle(id="tx-release-1") + + await lock.acquire_point(test_dir, tx, timeout=3.0) + lock_path = f"{test_dir}/{LOCK_FILE_NAME}" + + await lock.release(tx) + + # Lock file should be gone (use stat, not cat — cat returns b'' for deleted files) + try: + agfs_client.stat(lock_path) + raise AssertionError("Lock file should have been removed") + except AssertionError: + raise + except Exception: + pass # Expected: file not found + + async def test_sequential_acquire_works(self, agfs_client, test_dir): + lock = PathLock(agfs_client) + + tx1 = LockHandle(id="tx-seq-1") + ok1 = await lock.acquire_point(test_dir, tx1, timeout=3.0) + assert ok1 is True + + await lock.release(tx1) + + tx2 = LockHandle(id="tx-seq-2") + ok2 = await lock.acquire_point(test_dir, tx2, timeout=3.0) + assert ok2 is True + + await lock.release(tx2) + + async def test_point_blocked_by_ancestor_subtree(self, agfs_client, test_dir): + """POINT on child blocked while ancestor holds SUBTREE lock.""" + import uuid as _uuid + + child = f"{test_dir}/child-{_uuid.uuid4().hex}" + agfs_client.mkdir(child) + + lock = PathLock(agfs_client) + tx_parent = LockHandle(id="tx-parent-subtree") + ok = await lock.acquire_subtree(test_dir, tx_parent, timeout=3.0) + assert ok is True + + tx_child = LockHandle(id="tx-child-point") + blocked = await lock.acquire_point(child, tx_child, timeout=0.5) + assert blocked is False + + await lock.release(tx_parent) + + async def test_subtree_blocked_by_descendant_point(self, agfs_client, test_dir): + """SUBTREE on parent blocked while descendant holds POINT lock.""" + import uuid as _uuid + + child = f"{test_dir}/child-{_uuid.uuid4().hex}" + agfs_client.mkdir(child) + + lock = PathLock(agfs_client) + tx_child = LockHandle(id="tx-desc-point") + ok = await lock.acquire_point(child, tx_child, timeout=3.0) + assert ok is True + + tx_parent = LockHandle(id="tx-parent-sub") + blocked = await lock.acquire_subtree(test_dir, tx_parent, timeout=0.5) + assert blocked is False + + await lock.release(tx_child) + + async def test_acquire_mv_creates_subtree_locks(self, agfs_client, test_dir): + """acquire_mv puts SUBTREE on both src and dst.""" + import uuid as _uuid + + src = f"{test_dir}/src-{_uuid.uuid4().hex}" + dst = f"{test_dir}/dst-{_uuid.uuid4().hex}" + agfs_client.mkdir(src) + agfs_client.mkdir(dst) + + lock = PathLock(agfs_client) + tx = LockHandle(id="tx-mv-1") + ok = await lock.acquire_mv(src, dst, tx, timeout=3.0) + assert ok is True + + src_token_bytes = agfs_client.cat(f"{src}/{LOCK_FILE_NAME}") + src_token = ( + src_token_bytes.decode("utf-8") + if isinstance(src_token_bytes, bytes) + else src_token_bytes + ) + assert ":S" in src_token + + dst_token_bytes = agfs_client.cat(f"{dst}/{LOCK_FILE_NAME}") + dst_token = ( + dst_token_bytes.decode("utf-8") + if isinstance(dst_token_bytes, bytes) + else dst_token_bytes + ) + assert ":S" in dst_token + + await lock.release(tx) + + async def test_point_does_not_block_sibling_point(self, agfs_client, test_dir): + """POINT locks on different directories do not conflict.""" + import uuid as _uuid + + dir_a = f"{test_dir}/sibling-a-{_uuid.uuid4().hex}" + dir_b = f"{test_dir}/sibling-b-{_uuid.uuid4().hex}" + agfs_client.mkdir(dir_a) + agfs_client.mkdir(dir_b) + + lock = PathLock(agfs_client) + tx_a = LockHandle(id="tx-sib-a") + tx_b = LockHandle(id="tx-sib-b") + + ok_a = await lock.acquire_point(dir_a, tx_a, timeout=3.0) + ok_b = await lock.acquire_point(dir_b, tx_b, timeout=3.0) + + assert ok_a is True + assert ok_b is True + + await lock.release(tx_a) + await lock.release(tx_b) + + async def test_stale_lock_auto_removed_on_acquire(self, agfs_client, test_dir): + """A stale lock (expired fencing token) is auto-removed, allowing a new acquire.""" + import uuid as _uuid + + target = f"{test_dir}/stale-{_uuid.uuid4().hex}" + agfs_client.mkdir(target) + + lock_path = f"{target}/{LOCK_FILE_NAME}" + + # Write a lock file with a very old timestamp (simulate crashed process) + old_ts = time.time_ns() - int(600 * 1e9) # 600 seconds ago + stale_token = f"tx-dead:{old_ts}:{LOCK_TYPE_POINT}" + agfs_client.write(lock_path, stale_token.encode("utf-8")) + + # New transaction should succeed by auto-removing the stale lock + lock = PathLock(agfs_client, lock_expire=300.0) + tx = LockHandle(id="tx-new-owner") + ok = await lock.acquire_point(target, tx, timeout=2.0) + assert ok is True + + # Verify new lock is owned by our transaction + content = agfs_client.cat(lock_path) + token = content.decode("utf-8") if isinstance(content, bytes) else content + assert "tx-new-owner" in token + + await lock.release(tx) + + async def test_stale_subtree_ancestor_auto_removed(self, agfs_client, test_dir): + """A stale SUBTREE lock on ancestor is auto-removed when child acquires POINT.""" + import uuid as _uuid + + child = f"{test_dir}/child-stale-{_uuid.uuid4().hex}" + agfs_client.mkdir(child) + + # Write stale SUBTREE lock on parent + parent_lock = f"{test_dir}/{LOCK_FILE_NAME}" + old_ts = time.time_ns() - int(600 * 1e9) + stale_token = f"tx-dead-parent:{old_ts}:{LOCK_TYPE_SUBTREE}" + agfs_client.write(parent_lock, stale_token.encode("utf-8")) + + lock = PathLock(agfs_client, lock_expire=300.0) + tx = LockHandle(id="tx-child-new") + ok = await lock.acquire_point(child, tx, timeout=2.0) + assert ok is True + + await lock.release(tx) + # Clean up stale parent lock if still present + try: + agfs_client.rm(parent_lock) + except Exception: + pass + + async def test_point_same_path_no_wait_fails_immediately(self, agfs_client, test_dir): + """With timeout=0, a conflicting lock fails immediately.""" + import uuid as _uuid + + target = f"{test_dir}/nowait-{_uuid.uuid4().hex}" + agfs_client.mkdir(target) + + lock = PathLock(agfs_client) + tx1 = LockHandle(id="tx-hold") + ok1 = await lock.acquire_point(target, tx1, timeout=3.0) + assert ok1 is True + + # Second acquire with timeout=0 should fail immediately + tx2 = LockHandle(id="tx-blocked") + t0 = time.monotonic() + ok2 = await lock.acquire_point(target, tx2, timeout=0.0) + elapsed = time.monotonic() - t0 + + assert ok2 is False + assert elapsed < 1.0 # Should not wait + + await lock.release(tx1) + + async def test_subtree_same_path_mutual_exclusion(self, agfs_client, test_dir): + """Two SUBTREE locks on the same path: second one blocked until first releases.""" + import uuid as _uuid + + target = f"{test_dir}/sub-excl-{_uuid.uuid4().hex}" + agfs_client.mkdir(target) + + lock = PathLock(agfs_client) + tx1 = LockHandle(id="tx-sub1") + ok1 = await lock.acquire_subtree(target, tx1, timeout=3.0) + assert ok1 is True + + tx2 = LockHandle(id="tx-sub2") + ok2 = await lock.acquire_subtree(target, tx2, timeout=0.5) + assert ok2 is False + + await lock.release(tx1) + + # Now tx2 should succeed + ok2_retry = await lock.acquire_subtree(target, tx2, timeout=3.0) + assert ok2_retry is True + await lock.release(tx2) diff --git a/tests/transaction/test_redo_log.py b/tests/transaction/test_redo_log.py new file mode 100644 index 00000000..8a0def2c --- /dev/null +++ b/tests/transaction/test_redo_log.py @@ -0,0 +1,78 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for RedoLog crash recovery.""" + +import uuid + +import pytest + +from openviking.storage.transaction.redo_log import RedoLog + + +@pytest.fixture +def redo(agfs_client): + return RedoLog(agfs_client) + + +class TestRedoLogBasic: + def test_write_and_read(self, redo): + task_id = uuid.uuid4().hex + info = {"archive_uri": "viking://test/archive", "session_uri": "viking://test/session"} + redo.write_pending(task_id, info) + + result = redo.read(task_id) + assert result["archive_uri"] == "viking://test/archive" + assert result["session_uri"] == "viking://test/session" + + redo.mark_done(task_id) + + def test_list_pending(self, redo): + t1 = uuid.uuid4().hex + t2 = uuid.uuid4().hex + redo.write_pending(t1, {"key": "v1"}) + redo.write_pending(t2, {"key": "v2"}) + + pending = redo.list_pending() + assert t1 in pending + assert t2 in pending + + redo.mark_done(t1) + pending_after = redo.list_pending() + assert t1 not in pending_after + assert t2 in pending_after + + redo.mark_done(t2) + + def test_mark_done_removes_task(self, redo): + task_id = uuid.uuid4().hex + redo.write_pending(task_id, {"x": 1}) + redo.mark_done(task_id) + + pending = redo.list_pending() + assert task_id not in pending + + def test_read_nonexistent_returns_empty(self, redo): + result = redo.read("nonexistent-task-id") + assert result == {} + + def test_list_pending_empty(self, redo): + # Should not crash even if _REDO_ROOT doesn't exist yet + pending = redo.list_pending() + assert isinstance(pending, list) + + def test_mark_done_idempotent(self, redo): + task_id = uuid.uuid4().hex + redo.write_pending(task_id, {"x": 1}) + redo.mark_done(task_id) + # Second mark_done should not raise + redo.mark_done(task_id) + + def test_overwrite_pending(self, redo): + task_id = uuid.uuid4().hex + redo.write_pending(task_id, {"version": 1}) + redo.write_pending(task_id, {"version": 2}) + + result = redo.read(task_id) + assert result["version"] == 2 + + redo.mark_done(task_id) diff --git a/tests/unit/retrieve/test_retrieval_stats.py b/tests/unit/retrieve/test_retrieval_stats.py new file mode 100644 index 00000000..e9a4af68 --- /dev/null +++ b/tests/unit/retrieve/test_retrieval_stats.py @@ -0,0 +1,175 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Unit tests for retrieval statistics and observer.""" + +from openviking.retrieve.retrieval_stats import RetrievalStats, RetrievalStatsCollector +from openviking.storage.observers.retrieval_observer import RetrievalObserver + + +class TestRetrievalStats: + def test_defaults(self): + stats = RetrievalStats() + assert stats.total_queries == 0 + assert stats.avg_results_per_query == 0.0 + assert stats.zero_result_rate == 0.0 + assert stats.avg_score == 0.0 + assert stats.avg_latency_ms == 0.0 + + def test_to_dict_empty(self): + d = RetrievalStats().to_dict() + assert d["total_queries"] == 0 + assert d["max_score"] == 0.0 + assert d["min_score"] == 0.0 + + +class TestRetrievalStatsCollector: + def test_record_single_query(self): + collector = RetrievalStatsCollector() + collector.record_query( + context_type="memory", + result_count=3, + scores=[0.9, 0.7, 0.5], + latency_ms=42.0, + ) + stats = collector.snapshot() + assert stats.total_queries == 1 + assert stats.total_results == 3 + assert stats.zero_result_queries == 0 + assert stats.max_score == 0.9 + assert stats.min_score == 0.5 + assert stats.queries_by_type == {"memory": 1} + assert stats.avg_latency_ms == 42.0 + + def test_record_zero_result_query(self): + collector = RetrievalStatsCollector() + collector.record_query( + context_type="resource", + result_count=0, + scores=[], + latency_ms=10.0, + ) + stats = collector.snapshot() + assert stats.total_queries == 1 + assert stats.zero_result_queries == 1 + assert stats.zero_result_rate == 1.0 + + def test_record_multiple_queries(self): + collector = RetrievalStatsCollector() + collector.record_query("memory", 2, [0.8, 0.6], latency_ms=30.0) + collector.record_query("resource", 1, [0.5], latency_ms=20.0) + collector.record_query("memory", 0, [], latency_ms=5.0) + + stats = collector.snapshot() + assert stats.total_queries == 3 + assert stats.total_results == 3 + assert stats.zero_result_queries == 1 + assert stats.queries_by_type == {"memory": 2, "resource": 1} + assert stats.avg_latency_ms == (30 + 20 + 5) / 3 + + def test_rerank_tracking(self): + collector = RetrievalStatsCollector() + collector.record_query("memory", 1, [0.9], rerank_used=True) + collector.record_query("memory", 1, [0.7], rerank_fallback=True) + + stats = collector.snapshot() + assert stats.rerank_used == 1 + assert stats.rerank_fallback == 1 + + def test_max_latency(self): + collector = RetrievalStatsCollector() + collector.record_query("memory", 1, [0.5], latency_ms=10.0) + collector.record_query("memory", 1, [0.5], latency_ms=100.0) + collector.record_query("memory", 1, [0.5], latency_ms=50.0) + + stats = collector.snapshot() + assert stats.max_latency_ms == 100.0 + + def test_reset(self): + collector = RetrievalStatsCollector() + collector.record_query("memory", 3, [0.9, 0.7, 0.5]) + collector.reset() + stats = collector.snapshot() + assert stats.total_queries == 0 + assert stats.total_results == 0 + + def test_snapshot_is_copy(self): + collector = RetrievalStatsCollector() + collector.record_query("memory", 1, [0.9]) + snap = collector.snapshot() + collector.record_query("memory", 1, [0.8]) + assert snap.total_queries == 1 + + def test_to_dict(self): + collector = RetrievalStatsCollector() + collector.record_query("memory", 2, [0.9, 0.6], latency_ms=25.0) + d = collector.snapshot().to_dict() + assert d["total_queries"] == 1 + assert d["total_results"] == 2 + assert d["avg_results_per_query"] == 2.0 + assert d["max_score"] == 0.9 + assert d["min_score"] == 0.6 + assert d["avg_latency_ms"] == 25.0 + + +class TestRetrievalObserver: + def _setup_collector(self): + """Replace the global collector with a fresh one for testing.""" + import openviking.retrieve.retrieval_stats as mod + + collector = RetrievalStatsCollector() + mod._collector = collector + return collector + + def test_healthy_when_no_queries(self): + self._setup_collector() + observer = RetrievalObserver() + assert observer.is_healthy() is True + assert observer.has_errors() is False + + def test_healthy_with_good_results(self): + collector = self._setup_collector() + for _ in range(10): + collector.record_query("memory", 3, [0.9, 0.7, 0.5]) + observer = RetrievalObserver() + assert observer.is_healthy() is True + assert observer.has_errors() is False + + def test_unhealthy_with_many_zero_results(self): + collector = self._setup_collector() + for _ in range(8): + collector.record_query("memory", 0, []) + for _ in range(2): + collector.record_query("memory", 1, [0.5]) + observer = RetrievalObserver() + # 80% zero-result rate > 50% threshold + assert observer.is_healthy() is False + assert observer.has_errors() is True + + def test_no_errors_below_min_queries(self): + collector = self._setup_collector() + # Only 3 queries (below the 5-query minimum for error flagging) + for _ in range(3): + collector.record_query("memory", 0, []) + observer = RetrievalObserver() + assert observer.has_errors() is False + + def test_status_table_no_data(self): + self._setup_collector() + observer = RetrievalObserver() + table = observer.get_status_table() + assert "No retrieval queries recorded" in table + + def test_status_table_with_data(self): + collector = self._setup_collector() + collector.record_query("memory", 2, [0.9, 0.7], latency_ms=30.0) + collector.record_query("resource", 1, [0.5], latency_ms=20.0) + observer = RetrievalObserver() + table = observer.get_status_table() + assert "Total Queries" in table + assert "memory" in table + assert "resource" in table + + def test_str(self): + self._setup_collector() + observer = RetrievalObserver() + assert str(observer) == observer.get_status_table() diff --git a/tests/unit/session/test_deduplicator_uri.py b/tests/unit/session/test_deduplicator_uri.py new file mode 100644 index 00000000..8da1246d --- /dev/null +++ b/tests/unit/session/test_deduplicator_uri.py @@ -0,0 +1,125 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +from openviking.session.memory_deduplicator import MemoryDeduplicator + + +class TestExtractFacetKey: + def test_extract_with_chinese_colon(self): + result = MemoryDeduplicator._extract_facet_key("饮食偏好:喜欢吃苹果和草莓") + assert result == "饮食偏好" + + def test_extract_with_english_colon(self): + result = MemoryDeduplicator._extract_facet_key("User preference: dark mode enabled") + assert result == "user preference" + + def test_extract_with_hyphen(self): + result = MemoryDeduplicator._extract_facet_key("Coding style - prefer type hints") + assert result == "coding style" + + def test_extract_with_em_dash(self): + result = MemoryDeduplicator._extract_facet_key("Work schedule — remote on Fridays") + assert result == "work schedule" + + def test_extract_with_no_separator_returns_prefix(self): + result = MemoryDeduplicator._extract_facet_key( + "This is a long abstract without any separator" + ) + assert len(result) <= 24 + assert result == "this is a long abstract" + + def test_extract_with_empty_string(self): + result = MemoryDeduplicator._extract_facet_key("") + assert result == "" + + def test_extract_with_none(self): + result = MemoryDeduplicator._extract_facet_key(None) + assert result == "" + + def test_extract_normalizes_whitespace(self): + result = MemoryDeduplicator._extract_facet_key(" Multiple spaces : value ") + assert result == "multiple spaces" + + def test_extract_with_short_text_no_separator(self): + result = MemoryDeduplicator._extract_facet_key("Short") + assert result == "short" + + def test_extract_returns_lowercase(self): + result = MemoryDeduplicator._extract_facet_key("FOOD PREFERENCE: pizza") + assert result == "food preference" + + def test_extract_with_separator_at_start(self): + result = MemoryDeduplicator._extract_facet_key(": starts with separator") + assert result == ": starts with" + + def test_extract_with_multiple_separators_uses_first(self): + result = MemoryDeduplicator._extract_facet_key("Topic: Subtopic - Detail") + assert result == "topic" + + +class TestCosineSimilarity: + def test_identical_vectors(self): + vec = [1.0, 2.0, 3.0] + result = MemoryDeduplicator._cosine_similarity(vec, vec) + assert abs(result - 1.0) < 1e-9 + + def test_orthogonal_vectors(self): + vec_a = [1.0, 0.0] + vec_b = [0.0, 1.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert abs(result) < 1e-9 + + def test_opposite_vectors(self): + vec_a = [1.0, 2.0, 3.0] + vec_b = [-1.0, -2.0, -3.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert abs(result + 1.0) < 1e-9 + + def test_different_length_vectors(self): + vec_a = [1.0, 2.0, 3.0] + vec_b = [1.0, 2.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert result == 0.0 + + def test_zero_vector_a(self): + vec_a = [0.0, 0.0, 0.0] + vec_b = [1.0, 2.0, 3.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert result == 0.0 + + def test_zero_vector_b(self): + vec_a = [1.0, 2.0, 3.0] + vec_b = [0.0, 0.0, 0.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert result == 0.0 + + def test_both_zero_vectors(self): + vec_a = [0.0, 0.0, 0.0] + vec_b = [0.0, 0.0, 0.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert result == 0.0 + + def test_partial_similarity(self): + vec_a = [1.0, 0.0, 0.0] + vec_b = [1.0, 1.0, 0.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + expected = 1.0 / (2.0**0.5) + assert abs(result - expected) < 1e-9 + + def test_negative_values(self): + vec_a = [1.0, -2.0, 3.0] + vec_b = [-1.0, 2.0, 3.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert 0 < result < 1 + + def test_single_element_vectors(self): + vec_a = [5.0] + vec_b = [3.0] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert abs(result - 1.0) < 1e-9 + + def test_large_vectors(self): + vec_a = [float(i) for i in range(100)] + vec_b = [float(i * 2) for i in range(100)] + result = MemoryDeduplicator._cosine_similarity(vec_a, vec_b) + assert abs(result - 1.0) < 1e-6 diff --git a/tests/unit/session/test_memory_archiver.py b/tests/unit/session/test_memory_archiver.py new file mode 100644 index 00000000..e8d81a0b --- /dev/null +++ b/tests/unit/session/test_memory_archiver.py @@ -0,0 +1,423 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Unit tests for memory cold-storage archival.""" + +from datetime import datetime, timedelta, timezone +from unittest.mock import AsyncMock + +import pytest + +from openviking.session.memory_archiver import ( + ArchivalCandidate, + MemoryArchiver, + _build_archive_uri, + _build_restore_uri, + _parse_datetime, +) + +# --------------------------------------------------------------------------- +# Helper URI functions +# --------------------------------------------------------------------------- + + +class TestBuildArchiveUri: + def test_simple_file(self): + assert ( + _build_archive_uri("viking://memories/facts/greeting.md") + == "viking://memories/facts/_archive/greeting.md" + ) + + def test_nested_path(self): + assert ( + _build_archive_uri("viking://memories/user/prefs/theme.md") + == "viking://memories/user/prefs/_archive/theme.md" + ) + + def test_root_level_file(self): + assert ( + _build_archive_uri("viking://memories/note.md") == "viking://memories/_archive/note.md" + ) + + def test_no_slash(self): + assert _build_archive_uri("note.md") == "_archive/note.md" + + +class TestBuildRestoreUri: + def test_simple_restore(self): + assert ( + _build_restore_uri("viking://memories/facts/_archive/greeting.md") + == "viking://memories/facts/greeting.md" + ) + + def test_nested_restore(self): + assert ( + _build_restore_uri("viking://memories/user/_archive/pref.md") + == "viking://memories/user/pref.md" + ) + + def test_not_archived_returns_none(self): + assert _build_restore_uri("viking://memories/facts/greeting.md") is None + + def test_roundtrip(self): + original = "viking://memories/deep/path/to/file.md" + archived = _build_archive_uri(original) + restored = _build_restore_uri(archived) + assert restored == original + + +# --------------------------------------------------------------------------- +# Datetime parsing +# --------------------------------------------------------------------------- + + +class TestParseDatetime: + def test_none(self): + assert _parse_datetime(None) is None + + def test_datetime_object(self): + dt = datetime(2026, 1, 1, tzinfo=timezone.utc) + assert _parse_datetime(dt) == dt + + def test_naive_datetime_gets_utc(self): + dt = datetime(2026, 1, 1) + result = _parse_datetime(dt) + assert result is not None + assert result.tzinfo == timezone.utc + + def test_iso_string(self): + result = _parse_datetime("2026-01-01T00:00:00+00:00") + assert result is not None + assert result.year == 2026 + + def test_invalid_string(self): + assert _parse_datetime("not-a-date") is None + + def test_integer_returns_none(self): + assert _parse_datetime(12345) is None + + +# --------------------------------------------------------------------------- +# MemoryArchiver.scan +# --------------------------------------------------------------------------- + + +def _make_storage(records): + """Create a mock storage that returns records from scroll().""" + storage = AsyncMock() + storage.scroll = AsyncMock(return_value=(records, None)) + return storage + + +def _make_viking_fs(): + """Create a mock VikingFS.""" + vfs = AsyncMock() + vfs.mv = AsyncMock(return_value={"status": "ok"}) + return vfs + + +NOW = datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc) +OLD_DATE = NOW - timedelta(days=30) +RECENT_DATE = NOW - timedelta(days=2) + + +class TestScan: + @pytest.mark.asyncio + async def test_scan_finds_cold_memories(self): + records = [ + { + "uri": "viking://memories/fact1.md", + "active_count": 0, + "updated_at": OLD_DATE, + "context_type": "memory", + "parent_uri": "viking://memories/", + }, + ] + archiver = MemoryArchiver( + viking_fs=_make_viking_fs(), + storage=_make_storage(records), + threshold=0.5, + min_age_days=7, + ) + candidates = await archiver.scan("viking://memories/", now=NOW) + assert len(candidates) == 1 + assert candidates[0].uri == "viking://memories/fact1.md" + assert candidates[0].score < 0.5 + + @pytest.mark.asyncio + async def test_scan_skips_recent_memories(self): + records = [ + { + "uri": "viking://memories/recent.md", + "active_count": 0, + "updated_at": RECENT_DATE, + "context_type": "memory", + "parent_uri": "viking://memories/", + }, + ] + archiver = MemoryArchiver( + viking_fs=_make_viking_fs(), + storage=_make_storage(records), + threshold=0.5, + min_age_days=7, + ) + candidates = await archiver.scan("viking://memories/", now=NOW) + assert len(candidates) == 0 + + @pytest.mark.asyncio + async def test_scan_skips_already_archived(self): + records = [ + { + "uri": "viking://memories/_archive/old.md", + "active_count": 0, + "updated_at": OLD_DATE, + "context_type": "memory", + "parent_uri": "viking://memories/_archive/", + }, + ] + archiver = MemoryArchiver( + viking_fs=_make_viking_fs(), + storage=_make_storage(records), + threshold=0.5, + min_age_days=7, + ) + candidates = await archiver.scan("viking://memories/", now=NOW) + assert len(candidates) == 0 + + @pytest.mark.asyncio + async def test_scan_skips_out_of_scope(self): + records = [ + { + "uri": "viking://resources/doc.md", + "active_count": 0, + "updated_at": OLD_DATE, + "context_type": "resource", + "parent_uri": "viking://resources/", + }, + ] + archiver = MemoryArchiver( + viking_fs=_make_viking_fs(), + storage=_make_storage(records), + threshold=0.5, + min_age_days=7, + ) + candidates = await archiver.scan("viking://memories/", now=NOW) + assert len(candidates) == 0 + + @pytest.mark.asyncio + async def test_scan_keeps_hot_memories(self): + records = [ + { + "uri": "viking://memories/hot.md", + "active_count": 100, + "updated_at": NOW - timedelta(days=1), + "context_type": "memory", + "parent_uri": "viking://memories/", + }, + ] + archiver = MemoryArchiver( + viking_fs=_make_viking_fs(), + storage=_make_storage(records), + threshold=0.5, + min_age_days=0, + ) + candidates = await archiver.scan("viking://memories/", now=NOW) + # High active_count + recent = hot, should not be a candidate + assert len(candidates) == 0 + + @pytest.mark.asyncio + async def test_scan_sorts_coldest_first(self): + records = [ + { + "uri": "viking://memories/warm.md", + "active_count": 5, + "updated_at": OLD_DATE, + "context_type": "memory", + "parent_uri": "viking://memories/", + }, + { + "uri": "viking://memories/cold.md", + "active_count": 0, + "updated_at": OLD_DATE - timedelta(days=60), + "context_type": "memory", + "parent_uri": "viking://memories/", + }, + ] + archiver = MemoryArchiver( + viking_fs=_make_viking_fs(), + storage=_make_storage(records), + threshold=0.5, + min_age_days=7, + ) + candidates = await archiver.scan("viking://memories/", now=NOW) + assert len(candidates) == 2 + assert candidates[0].uri == "viking://memories/cold.md" + assert candidates[0].score <= candidates[1].score + + @pytest.mark.asyncio + async def test_scan_empty_store(self): + archiver = MemoryArchiver( + viking_fs=_make_viking_fs(), + storage=_make_storage([]), + threshold=0.5, + min_age_days=7, + ) + candidates = await archiver.scan("viking://memories/", now=NOW) + assert candidates == [] + + +# --------------------------------------------------------------------------- +# MemoryArchiver.archive +# --------------------------------------------------------------------------- + + +class TestArchive: + @pytest.mark.asyncio + async def test_archive_moves_files(self): + vfs = _make_viking_fs() + archiver = MemoryArchiver(viking_fs=vfs, storage=_make_storage([])) + candidates = [ + ArchivalCandidate( + uri="viking://memories/fact1.md", + active_count=0, + updated_at=OLD_DATE, + score=0.01, + ), + ] + result = await archiver.archive(candidates) + assert result.archived == 1 + assert result.errors == 0 + vfs.mv.assert_called_once_with( + "viking://memories/fact1.md", + "viking://memories/_archive/fact1.md", + ctx=None, + ) + + @pytest.mark.asyncio + async def test_archive_dry_run(self): + vfs = _make_viking_fs() + archiver = MemoryArchiver(viking_fs=vfs, storage=_make_storage([])) + candidates = [ + ArchivalCandidate( + uri="viking://memories/fact1.md", + active_count=0, + updated_at=OLD_DATE, + score=0.01, + ), + ] + result = await archiver.archive(candidates, dry_run=True) + assert result.archived == 0 + assert result.skipped == 1 + vfs.mv.assert_not_called() + + @pytest.mark.asyncio + async def test_archive_handles_mv_error(self): + vfs = _make_viking_fs() + vfs.mv = AsyncMock(side_effect=RuntimeError("AGFS error")) + archiver = MemoryArchiver(viking_fs=vfs, storage=_make_storage([])) + candidates = [ + ArchivalCandidate( + uri="viking://memories/fact1.md", + active_count=0, + updated_at=OLD_DATE, + score=0.01, + ), + ] + result = await archiver.archive(candidates) + assert result.archived == 0 + assert result.errors == 1 + + @pytest.mark.asyncio + async def test_archive_empty_candidates(self): + archiver = MemoryArchiver( + viking_fs=_make_viking_fs(), + storage=_make_storage([]), + ) + result = await archiver.archive([]) + assert result.archived == 0 + assert result.scanned == 0 + + +# --------------------------------------------------------------------------- +# MemoryArchiver.restore +# --------------------------------------------------------------------------- + + +class TestRestore: + @pytest.mark.asyncio + async def test_restore_moves_back(self): + vfs = _make_viking_fs() + archiver = MemoryArchiver(viking_fs=vfs, storage=_make_storage([])) + ok = await archiver.restore("viking://memories/_archive/fact1.md") + assert ok is True + vfs.mv.assert_called_once_with( + "viking://memories/_archive/fact1.md", + "viking://memories/fact1.md", + ctx=None, + ) + + @pytest.mark.asyncio + async def test_restore_non_archived_uri(self): + vfs = _make_viking_fs() + archiver = MemoryArchiver(viking_fs=vfs, storage=_make_storage([])) + ok = await archiver.restore("viking://memories/fact1.md") + assert ok is False + vfs.mv.assert_not_called() + + @pytest.mark.asyncio + async def test_restore_handles_error(self): + vfs = _make_viking_fs() + vfs.mv = AsyncMock(side_effect=RuntimeError("AGFS error")) + archiver = MemoryArchiver(viking_fs=vfs, storage=_make_storage([])) + ok = await archiver.restore("viking://memories/_archive/fact1.md") + assert ok is False + + +# --------------------------------------------------------------------------- +# scan_and_archive convenience +# --------------------------------------------------------------------------- + + +class TestScanAndArchive: + @pytest.mark.asyncio + async def test_scan_and_archive(self): + records = [ + { + "uri": "viking://memories/cold.md", + "active_count": 0, + "updated_at": OLD_DATE, + "context_type": "memory", + "parent_uri": "viking://memories/", + }, + ] + vfs = _make_viking_fs() + archiver = MemoryArchiver( + viking_fs=vfs, + storage=_make_storage(records), + threshold=0.5, + min_age_days=7, + ) + result = await archiver.scan_and_archive("viking://memories/", now=NOW) + assert result.archived == 1 + + @pytest.mark.asyncio + async def test_scan_and_archive_dry_run(self): + records = [ + { + "uri": "viking://memories/cold.md", + "active_count": 0, + "updated_at": OLD_DATE, + "context_type": "memory", + "parent_uri": "viking://memories/", + }, + ] + vfs = _make_viking_fs() + archiver = MemoryArchiver( + viking_fs=vfs, + storage=_make_storage(records), + threshold=0.5, + min_age_days=7, + ) + result = await archiver.scan_and_archive("viking://memories/", dry_run=True, now=NOW) + assert result.archived == 0 + assert result.skipped == 1 + vfs.mv.assert_not_called() diff --git a/tests/unit/test_embedding_config_voyage.py b/tests/unit/test_embedding_config_voyage.py new file mode 100644 index 00000000..15c84e07 --- /dev/null +++ b/tests/unit/test_embedding_config_voyage.py @@ -0,0 +1,52 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for Voyage embedding configuration.""" + +import pytest + +from openviking.models.embedder import VoyageDenseEmbedder +from openviking_cli.utils.config.embedding_config import EmbeddingConfig, EmbeddingModelConfig + + +def test_voyage_provider_requires_api_key(): + with pytest.raises(ValueError, match="Voyage provider requires 'api_key'"): + EmbeddingModelConfig(provider="voyage", model="voyage-4-lite") + + +def test_voyage_dense_dimension_defaults_to_model_dimension(): + config = EmbeddingConfig( + dense=EmbeddingModelConfig( + provider="voyage", + model="voyage-4-lite", + api_key="voyage-key", + ) + ) + + assert config.dimension == 1024 + + +def test_voyage_dense_dimension_honors_explicit_output_dimension(): + config = EmbeddingConfig( + dense=EmbeddingModelConfig( + provider="voyage", + model="voyage-4-lite", + api_key="voyage-key", + dimension=512, + ) + ) + + assert config.dimension == 512 + + +def test_voyage_get_embedder_returns_voyage_dense_embedder(): + config = EmbeddingConfig( + dense=EmbeddingModelConfig( + provider="voyage", + model="voyage-4-lite", + api_key="voyage-key", + ) + ) + + embedder = config.get_embedder() + assert isinstance(embedder, VoyageDenseEmbedder) + assert embedder.get_dimension() == 1024 diff --git a/tests/unit/test_extra_headers_embedding.py b/tests/unit/test_extra_headers_embedding.py new file mode 100644 index 00000000..c766debb --- /dev/null +++ b/tests/unit/test_extra_headers_embedding.py @@ -0,0 +1,146 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for extra_headers support in OpenAIDenseEmbedder and EmbeddingConfig factory. + +Covers: + 1. extra_headers is passed as default_headers to openai.OpenAI client + 2. omitting extra_headers does not inject default_headers key + 3. factory (_create_embedder) transparently forwards extra_headers + 4. api_key dead-code bug fix: no raise when api_base is set without api_key +""" + +from unittest.mock import MagicMock, patch + +import pytest + +from openviking.models.embedder import OpenAIDenseEmbedder +from openviking_cli.utils.config.embedding_config import EmbeddingConfig, EmbeddingModelConfig + + +def _make_mock_client(): + """Build a MagicMock openai client that returns a minimal valid embedding response.""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], + usage=None, + ) + return mock_client + + +class TestExtraHeadersDirectConstruction: + """Test extra_headers behaviour when constructing OpenAIDenseEmbedder directly.""" + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_extra_headers_passed_as_default_headers(self, mock_openai_class): + """extra_headers dict must arrive as default_headers kwarg in openai.OpenAI().""" + mock_openai_class.return_value = _make_mock_client() + + headers = {"HTTP-Referer": "https://example.com", "X-Title": "My App"} + OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="sk-test", + extra_headers=headers, + ) + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs.get("default_headers") == headers + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_no_extra_headers_omits_default_headers(self, mock_openai_class): + """When extra_headers is not provided, default_headers must NOT appear in openai.OpenAI().""" + mock_openai_class.return_value = _make_mock_client() + + OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="sk-test", + ) + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert "default_headers" not in call_kwargs + + +class TestExtraHeadersViaFactory: + """Test extra_headers forwarding through EmbeddingConfig._create_embedder.""" + + @patch("openai.OpenAI") + def test_factory_passes_extra_headers(self, mock_openai_class): + """Factory must forward extra_headers as default_headers to openai.OpenAI().""" + mock_openai_class.return_value = _make_mock_client() + + headers = {"HTTP-Referer": "https://myapp.com", "X-Title": "MyApp"} + cfg = EmbeddingModelConfig( + provider="openai", + model="text-embedding-3-small", + api_key="sk-test", + extra_headers=headers, + ) + EmbeddingConfig(dense=cfg)._create_embedder("openai", "dense", cfg) + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs.get("default_headers") == headers + + @patch("openai.OpenAI") + def test_factory_omits_extra_headers_when_none(self, mock_openai_class): + """Factory must NOT inject default_headers when extra_headers is None.""" + mock_openai_class.return_value = _make_mock_client() + + cfg = EmbeddingModelConfig( + provider="openai", + model="text-embedding-3-small", + api_key="sk-test", + ) + EmbeddingConfig(dense=cfg)._create_embedder("openai", "dense", cfg) + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert "default_headers" not in call_kwargs + + +class TestEmbeddingModelConfigExtraHeaders: + """Test that EmbeddingModelConfig accepts and stores the extra_headers field.""" + + def test_openai_config_accepts_extra_headers_field(self): + """EmbeddingModelConfig should store extra_headers without validation error.""" + cfg = EmbeddingModelConfig( + provider="openai", + model="text-embedding-3-small", + api_key="sk-test", + extra_headers={"X-Custom": "value"}, + ) + assert cfg.extra_headers == {"X-Custom": "value"} + + def test_extra_headers_defaults_to_none(self): + """extra_headers field should default to None when not supplied.""" + cfg = EmbeddingModelConfig( + provider="openai", + model="text-embedding-3-small", + api_key="sk-test", + ) + assert cfg.extra_headers is None + + +class TestApiKeyValidationFix: + """Test the api_key dead-code bug fix: validate only when both api_key and api_base are absent.""" + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_api_key_not_required_when_api_base_set(self, mock_openai_class): + """No ValueError should be raised when api_base is provided without api_key.""" + mock_openai_class.return_value = _make_mock_client() + + # Should NOT raise; api_base substitutes for api_key for local/compatible servers + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_base="http://localhost:8080/v1", + ) + assert embedder is not None + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_api_key_required_when_no_api_base(self, mock_openai_class): + """ValueError must be raised when neither api_key nor api_base is provided.""" + mock_openai_class.return_value = _make_mock_client() + + with pytest.raises(ValueError, match="api_key is required"): + OpenAIDenseEmbedder(model_name="text-embedding-3-small") diff --git a/tests/unit/test_extra_headers_vlm.py b/tests/unit/test_extra_headers_vlm.py new file mode 100644 index 00000000..87b3e803 --- /dev/null +++ b/tests/unit/test_extra_headers_vlm.py @@ -0,0 +1,221 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for VLM extra_headers support.""" + +from unittest.mock import MagicMock, patch + +from openviking.models.vlm.backends.openai_vlm import OpenAIVLM + + +class TestVLMExtraHeaders: + """Test extra_headers is passed to OpenAI client.""" + + @patch("openviking.models.vlm.backends.openai_vlm.openai.OpenAI") + def test_extra_headers_passed_to_sync_client(self, mock_openai_class): + """extra_headers should be passed as default_headers to sync OpenAI client.""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + headers = {"HTTP-Referer": "https://example.com", "X-Title": "My App"} + vlm = OpenAIVLM( + { + "api_key": "sk-test", + "api_base": "https://api.openai.com/v1", + "extra_headers": headers, + } + ) + + # Trigger client creation + _ = vlm.get_client() + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs.get("default_headers") == headers + + @patch("openviking.models.vlm.backends.openai_vlm.openai.AsyncOpenAI") + def test_extra_headers_passed_to_async_client(self, mock_async_openai_class): + """extra_headers should be passed as default_headers to async OpenAI client.""" + mock_client = MagicMock() + mock_async_openai_class.return_value = mock_client + + headers = {"HTTP-Referer": "https://example.com", "X-Title": "My App"} + vlm = OpenAIVLM( + { + "api_key": "sk-test", + "api_base": "https://api.openai.com/v1", + "extra_headers": headers, + } + ) + + # Trigger async client creation + _ = vlm.get_async_client() + + mock_async_openai_class.assert_called_once() + call_kwargs = mock_async_openai_class.call_args[1] + assert call_kwargs.get("default_headers") == headers + + @patch("openviking.models.vlm.backends.openai_vlm.openai.OpenAI") + def test_no_extra_headers_omits_default_headers(self, mock_openai_class): + """When extra_headers is not provided, default_headers should NOT be set.""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + vlm = OpenAIVLM( + { + "api_key": "sk-test", + "api_base": "https://api.openai.com/v1", + } + ) + + # Trigger client creation + _ = vlm.get_client() + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert "default_headers" not in call_kwargs + + @patch("openviking.models.vlm.backends.openai_vlm.openai.OpenAI") + def test_extra_headers_empty_dict_omits_default_headers(self, mock_openai_class): + """When extra_headers is empty dict, default_headers should NOT be set.""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + vlm = OpenAIVLM( + { + "api_key": "sk-test", + "api_base": "https://api.openai.com/v1", + "extra_headers": {}, + } + ) + + # Trigger client creation + _ = vlm.get_client() + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + # Empty dict is falsy, so default_headers should not be set + assert "default_headers" not in call_kwargs + + +class TestVLMBaseExtraHeaders: + """Test VLMBase extracts extra_headers from config.""" + + def test_extra_headers_extracted_from_config(self): + """VLMBase should extract extra_headers from config.""" + + class StubVLM(OpenAIVLM): + def get_completion(self, prompt, thinking=False): + return "" + + async def get_completion_async(self, prompt, thinking=False, max_retries=0): + return "" + + def get_vision_completion(self, prompt, images, thinking=False): + return "" + + async def get_vision_completion_async(self, prompt, images, thinking=False): + return "" + + headers = {"X-Custom-Header": "custom-value"} + vlm = StubVLM( + { + "api_key": "sk-test", + "extra_headers": headers, + } + ) + + assert vlm.extra_headers == headers + + def test_extra_headers_none_when_not_in_config(self): + """VLMBase should set extra_headers to None when not in config.""" + + class StubVLM(OpenAIVLM): + def get_completion(self, prompt, thinking=False): + return "" + + async def get_completion_async(self, prompt, thinking=False, max_retries=0): + return "" + + def get_vision_completion(self, prompt, images, thinking=False): + return "" + + async def get_vision_completion_async(self, prompt, images, thinking=False): + return "" + + vlm = StubVLM( + { + "api_key": "sk-test", + } + ) + + assert vlm.extra_headers is None + + +class TestVLMConfigExtraHeaders: + """Test VLMConfig passes extra_headers to VLM instance.""" + + def test_vlm_config_accepts_extra_headers_in_providers(self): + """VLMConfig should accept extra_headers in providers config.""" + from openviking_cli.utils.config.vlm_config import VLMConfig + + config = VLMConfig( + model="gpt-4o", + provider="openai", + providers={ + "openai": { + "api_key": "sk-test", + "api_base": "https://api.openai.com/v1", + "extra_headers": {"HTTP-Referer": "https://example.com"}, + } + }, + ) + + result = config._build_vlm_config_dict() + assert result["extra_headers"] == {"HTTP-Referer": "https://example.com"} + + def test_vlm_config_extra_headers_none_when_not_set(self): + """VLMConfig should not include extra_headers when not set.""" + from openviking_cli.utils.config.vlm_config import VLMConfig + + config = VLMConfig( + model="gpt-4o", + provider="openai", + providers={ + "openai": { + "api_key": "sk-test", + "api_base": "https://api.openai.com/v1", + } + }, + ) + + result = config._build_vlm_config_dict() + assert result.get("extra_headers") is None + + def test_vlm_config_accepts_flat_extra_headers(self): + """VLMConfig should accept extra_headers as flat config field (legacy style).""" + from openviking_cli.utils.config.vlm_config import VLMConfig + + config = VLMConfig( + model="gpt-4o", + provider="openai", + api_key="sk-test", + api_base="https://openrouter.ai/api/v1", + extra_headers={"HTTP-Referer": "https://example.com", "X-Title": "My App"}, + ) + + # Verify flat extra_headers is stored + assert config.extra_headers == {"HTTP-Referer": "https://example.com", "X-Title": "My App"} + + # Verify it's migrated to providers structure + config._migrate_legacy_config() + assert config.providers["openai"]["extra_headers"] == { + "HTTP-Referer": "https://example.com", + "X-Title": "My App", + } + + # Verify _build_vlm_config_dict includes it + result = config._build_vlm_config_dict() + assert result["extra_headers"] == { + "HTTP-Referer": "https://example.com", + "X-Title": "My App", + } diff --git a/tests/unit/test_jina_embedder.py b/tests/unit/test_jina_embedder.py index 67a92668..22aa3fc8 100644 --- a/tests/unit/test_jina_embedder.py +++ b/tests/unit/test_jina_embedder.py @@ -123,7 +123,7 @@ def test_embed_with_dimension(self, mock_openai_class): @patch("openviking.models.embedder.jina_embedders.openai.OpenAI") def test_embed_with_task(self, mock_openai_class): - """Test embedding with task parameter""" + """Jina embedder should include task in extra_body when configured.""" mock_client = MagicMock() mock_openai_class.return_value = mock_client @@ -134,14 +134,15 @@ def test_embed_with_task(self, mock_openai_class): mock_response.data = [mock_embedding] mock_client.embeddings.create.return_value = mock_response + # Pass task directly embedder = JinaDenseEmbedder( model_name="jina-embeddings-v5-text-small", api_key="test-api-key", - task="retrieval.query", + query_param="retrieval.query", ) - embedder.embed("Hello world") - # Check extra_body was passed with task + embedder.embed("Hello world", is_query=True) + call_kwargs = mock_client.embeddings.create.call_args[1] assert "extra_body" in call_kwargs assert call_kwargs["extra_body"]["task"] == "retrieval.query" @@ -236,19 +237,25 @@ def test_build_extra_body_none(self): embedder = JinaDenseEmbedder( model_name="jina-embeddings-v5-text-small", api_key="test-api-key", + query_param=None, + document_param=None, ) assert embedder._build_extra_body() is None - def test_build_extra_body_with_params(self): - """Test _build_extra_body returns dict with params""" + @patch("openviking.models.embedder.jina_embedders.openai.OpenAI") + def test_build_extra_body_with_params(self, mock_openai_class): + """_build_extra_body should include task and late_chunking.""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + embedder = JinaDenseEmbedder( model_name="jina-embeddings-v5-text-small", api_key="test-api-key", - task="retrieval.passage", + document_param="retrieval.passage", late_chunking=True, ) - extra_body = embedder._build_extra_body() - assert extra_body is not None + + extra_body = embedder._build_extra_body(is_query=False) assert extra_body["task"] == "retrieval.passage" assert extra_body["late_chunking"] is True diff --git a/tests/unit/test_ollama_embedding_factory.py b/tests/unit/test_ollama_embedding_factory.py new file mode 100644 index 00000000..d2b3caf1 --- /dev/null +++ b/tests/unit/test_ollama_embedding_factory.py @@ -0,0 +1,174 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for the ollama embedding factory in EmbeddingConfig._create_embedder. + +Regression tests for two bugs fixed in the ollama factory lambda: + 1. max_tokens was not forwarded to OpenAIDenseEmbedder (so user-configured + chunking thresholds were silently ignored for Ollama). + 2. The api_key placeholder was "ollama" instead of "no-key", inconsistent + with the openai factory and the placeholder used inside OpenAIDenseEmbedder. +""" + +import pytest +from unittest.mock import MagicMock, patch + +from openviking_cli.utils.config.embedding_config import EmbeddingConfig, EmbeddingModelConfig + + +def _make_mock_openai_class(): + """Return a mock openai.OpenAI class that records constructor kwargs.""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], + usage=None, + ) + mock_openai_class = MagicMock(return_value=mock_client) + return mock_openai_class, mock_client + + +def _make_ollama_cfg(**kwargs) -> EmbeddingModelConfig: + defaults = dict(provider="ollama", model="nomic-embed-text", dimension=768) + defaults.update(kwargs) + return EmbeddingModelConfig(**defaults) + + +@patch("openai.OpenAI") +class TestOllamaFactoryMaxTokens: + """max_tokens must be forwarded from config to OpenAIDenseEmbedder.""" + + def test_custom_max_tokens_is_forwarded(self, mock_openai_class): + """When max_tokens=512, the created embedder should report max_tokens=512.""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], usage=None + ) + mock_openai_class.return_value = mock_client + + cfg = _make_ollama_cfg(max_tokens=512) + embedder = EmbeddingConfig(dense=cfg)._create_embedder("ollama", "dense", cfg) + + assert embedder.max_tokens == 512 + + def test_none_max_tokens_uses_default(self, mock_openai_class): + """When max_tokens is not set (None), the embedder should use its default (8000).""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], usage=None + ) + mock_openai_class.return_value = mock_client + + cfg = _make_ollama_cfg() # max_tokens not set -> None + assert cfg.max_tokens is None + + embedder = EmbeddingConfig(dense=cfg)._create_embedder("ollama", "dense", cfg) + + assert embedder.max_tokens == 8000 # class-level default + + def test_openai_factory_max_tokens_also_forwarded(self, mock_openai_class): + """Sanity: the openai factory also forwards max_tokens (parity check).""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], usage=None + ) + mock_openai_class.return_value = mock_client + + cfg = EmbeddingModelConfig( + provider="openai", + model="text-embedding-3-small", + api_key="sk-test", + dimension=1536, + max_tokens=4096, + ) + embedder = EmbeddingConfig(dense=cfg)._create_embedder("openai", "dense", cfg) + + assert embedder.max_tokens == 4096 + + +@patch("openai.OpenAI") +class TestOllamaFactoryApiKeyPlaceholder: + """The api_key placeholder for ollama must be "no-key", not "ollama".""" + + def test_no_api_key_uses_no_key_placeholder(self, mock_openai_class): + """When no api_key is provided, openai.OpenAI must be called with api_key='no-key'.""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], usage=None + ) + mock_openai_class.return_value = mock_client + + cfg = _make_ollama_cfg() # no api_key + EmbeddingConfig(dense=cfg)._create_embedder("ollama", "dense", cfg) + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs["api_key"] == "no-key", ( + f"Expected placeholder 'no-key' but got {call_kwargs['api_key']!r}. " + "The ollama factory must use the same placeholder as the openai factory." + ) + + def test_explicit_api_key_is_passed_through(self, mock_openai_class): + """When an api_key is explicitly provided, it must be passed through unchanged.""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], usage=None + ) + mock_openai_class.return_value = mock_client + + cfg = _make_ollama_cfg(api_key="my-custom-key") + EmbeddingConfig(dense=cfg)._create_embedder("ollama", "dense", cfg) + + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs["api_key"] == "my-custom-key" + + def test_openai_factory_also_uses_no_key_placeholder(self, mock_openai_class): + """Parity check: the openai factory also uses 'no-key' when api_base is set.""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], usage=None + ) + mock_openai_class.return_value = mock_client + + cfg = EmbeddingModelConfig( + provider="openai", + model="text-embedding-3-small", + api_base="http://localhost:8080/v1", + dimension=1536, + ) + EmbeddingConfig(dense=cfg)._create_embedder("openai", "dense", cfg) + + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs["api_key"] == "no-key" + + +@patch("openai.OpenAI") +class TestOllamaFactoryApiBase: + """The ollama factory must supply the correct api_base.""" + + def test_default_api_base_is_localhost_ollama(self, mock_openai_class): + """When api_base is not set, it should default to http://localhost:11434/v1.""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], usage=None + ) + mock_openai_class.return_value = mock_client + + cfg = _make_ollama_cfg() # no api_base + EmbeddingConfig(dense=cfg)._create_embedder("ollama", "dense", cfg) + + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs["base_url"] == "http://localhost:11434/v1" + + def test_custom_api_base_is_forwarded(self, mock_openai_class): + """When api_base is explicitly set, it must override the default.""" + mock_client = MagicMock() + mock_client.embeddings.create.return_value = MagicMock( + data=[MagicMock(embedding=[0.1] * 8)], usage=None + ) + mock_openai_class.return_value = mock_client + + cfg = _make_ollama_cfg(api_base="http://gpu-server:11434/v1") + EmbeddingConfig(dense=cfg)._create_embedder("ollama", "dense", cfg) + + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs["base_url"] == "http://gpu-server:11434/v1" diff --git a/tests/unit/test_openai_embedder.py b/tests/unit/test_openai_embedder.py new file mode 100644 index 00000000..02df2a23 --- /dev/null +++ b/tests/unit/test_openai_embedder.py @@ -0,0 +1,299 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for OpenAI Embedder""" + +from unittest.mock import MagicMock, patch + +from openviking.models.embedder import OpenAIDenseEmbedder + + +class TestOpenAIDenseEmbedder: + """Test cases for OpenAIDenseEmbedder""" + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_embed_does_not_send_dimensions(self, mock_openai_class): + """OpenAI embed should omit dimensions param""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=1024, + ) + + embedder.embed("Hello world") + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "dimensions" not in call_kwargs + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_embed_batch_does_not_send_dimensions(self, mock_openai_class): + """OpenAI embed_batch should omit dimensions param""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding1 = MagicMock() + mock_embedding1.embedding = [0.1] * 1536 + mock_embedding2 = MagicMock() + mock_embedding2.embedding = [0.2] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding1, mock_embedding2] + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=512, + ) + + embedder.embed_batch(["Hello", "World"]) + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "dimensions" not in call_kwargs + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_embed_with_input_type_none(self, mock_openai_class): + """OpenAI embed should not include extra_body when input_type is None""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + ) + + embedder.embed("Hello world") + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "extra_body" not in call_kwargs + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_embed_with_context_query(self, mock_openai_class): + """OpenAI embed should include extra_body with input_type='query' when is_query=True""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + query_param="query", + ) + + embedder.embed("Hello world", is_query=True) + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "extra_body" in call_kwargs + assert call_kwargs["extra_body"] == {"input_type": "query"} + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_embed_with_context_document(self, mock_openai_class): + """OpenAI embed should include extra_body with input_type='passage' when is_query=False""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + document_param="passage", + ) + + embedder.embed("Hello world", is_query=False) + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "extra_body" in call_kwargs + assert call_kwargs["extra_body"] == {"input_type": "passage"} + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_embed_batch_with_input_type_none(self, mock_openai_class): + """OpenAI embed_batch should not include extra_body when input_type is None""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding1 = MagicMock() + mock_embedding1.embedding = [0.1] * 1536 + mock_embedding2 = MagicMock() + mock_embedding2.embedding = [0.2] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding1, mock_embedding2] + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + ) + + embedder.embed_batch(["Hello", "World"]) + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "extra_body" not in call_kwargs + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_embed_batch_with_context_query(self, mock_openai_class): + """OpenAI embed_batch should include extra_body with input_type='query' when is_query=True""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding1 = MagicMock() + mock_embedding1.embedding = [0.1] * 1536 + mock_embedding2 = MagicMock() + mock_embedding2.embedding = [0.2] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding1, mock_embedding2] + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + query_param="query", + ) + + embedder.embed_batch(["Hello", "World"], is_query=True) + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "extra_body" in call_kwargs + assert call_kwargs["extra_body"] == {"input_type": "query"} + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_embed_batch_with_context_document(self, mock_openai_class): + """OpenAI embed_batch should include extra_body with input_type='passage' when is_query=False""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding1 = MagicMock() + mock_embedding1.embedding = [0.1] * 1536 + mock_embedding2 = MagicMock() + mock_embedding2.embedding = [0.2] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding1, mock_embedding2] + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + document_param="passage", + ) + + embedder.embed_batch(["Hello", "World"], is_query=False) + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "extra_body" in call_kwargs + assert call_kwargs["extra_body"] == {"input_type": "passage"} + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_telemetry_skipped_when_no_usage(self, mock_openai_class): + """_update_telemetry_token_usage should no-op when response has no usage""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 1536 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_response.usage = None + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=1536, + ) + result = embedder.embed("Hello world") + assert result.dense_vector is not None + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_telemetry_skipped_when_module_missing(self, mock_openai_class): + """_update_telemetry_token_usage should silently no-op when telemetry module is not available""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 1536 + + mock_usage = MagicMock() + mock_usage.prompt_tokens = 10 + mock_usage.total_tokens = 10 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_response.usage = mock_usage + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=1536, + ) + + with patch("importlib.import_module", side_effect=ImportError("no telemetry")): + result = embedder.embed("Hello world") + + assert result.dense_vector is not None + + @patch("openviking.models.embedder.openai_embedders.openai.OpenAI") + def test_telemetry_called_when_module_available(self, mock_openai_class): + """_update_telemetry_token_usage should call telemetry when module is available""" + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 1536 + + mock_usage = MagicMock() + mock_usage.prompt_tokens = 8 + mock_usage.total_tokens = 8 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_response.usage = mock_usage + mock_client.embeddings.create.return_value = mock_response + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=1536, + ) + + mock_telemetry = MagicMock() + + with patch( + "openviking.models.embedder.openai_embedders.get_current_telemetry", + return_value=mock_telemetry, + ): + result = embedder.embed("Hello world") + + assert result.dense_vector is not None + mock_telemetry.add_token_usage_by_source.assert_called_once_with("embedding", 8, 0) diff --git a/tests/unit/test_openai_embedder_chunking.py b/tests/unit/test_openai_embedder_chunking.py new file mode 100644 index 00000000..6c6c71af --- /dev/null +++ b/tests/unit/test_openai_embedder_chunking.py @@ -0,0 +1,532 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for OpenAI Embedder text chunking functionality (Issue #616) + +Uses importlib to load modules directly, avoiding the deep import chain +from openviking/__init__.py that requires the full build (C++ engine, litellm, etc.). +""" + +import importlib.util +import math +import os +import sys +from unittest.mock import MagicMock, patch + +import pytest + +# -- Direct module loading to avoid openviking/__init__.py import chain --- +_PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + + +def _load_module_from_file(module_name: str, file_path: str): + """Load a Python module directly from file path.""" + spec = importlib.util.spec_from_file_location(module_name, file_path) + mod = importlib.util.module_from_spec(spec) + sys.modules[module_name] = mod + spec.loader.exec_module(mod) + return mod + + +# Load base module first +_base_mod = _load_module_from_file( + "openviking.models.embedder.base", + os.path.join(_PROJECT_ROOT, "openviking", "models", "embedder", "base.py"), +) +EmbedResult = _base_mod.EmbedResult +EmbedderBase = _base_mod.EmbedderBase +DenseEmbedderBase = _base_mod.DenseEmbedderBase + + +DIMENSION = 8 + + +def _make_mock_openai_client(dimension=DIMENSION): + """Create a mock OpenAI client that returns deterministic embeddings.""" + mock_client = MagicMock() + + def fake_create(**kwargs): + inp = kwargs["input"] + if isinstance(inp, list): + items = [] + for text in inp: + vec = _deterministic_vector(text, dimension) + item = MagicMock() + item.embedding = vec + items.append(item) + resp = MagicMock() + resp.data = items + return resp + else: + vec = _deterministic_vector(inp, dimension) + item = MagicMock() + item.embedding = vec + resp = MagicMock() + resp.data = [item] + return resp + + mock_client.embeddings.create.side_effect = fake_create + return mock_client + + +def _deterministic_vector(text, dim): + """Generate a simple deterministic vector from text for testing.""" + seed = sum(ord(c) for c in text) % 1000 + vec = [(seed + i) * 0.001 for i in range(dim)] + # Normalize + norm = math.sqrt(sum(v * v for v in vec)) + if norm > 0: + vec = [v / norm for v in vec] + return vec + + +def _load_openai_embedders(): + """Load the openai_embedders module with mocked dependencies.""" + return _load_module_from_file( + "openviking.models.embedder.openai_embedders", + os.path.join(_PROJECT_ROOT, "openviking", "models", "embedder", "openai_embedders.py"), + ) + + +@patch("openai.OpenAI") +class TestOpenAIEmbedderChunking: + """Test cases for OpenAI embedder text chunking (Issue #616)""" + + def _make_embedder(self, mock_openai_class, max_tokens=100): + """Helper to create a test embedder with a mocked client.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=DIMENSION, + ) + + # Override max_tokens for testing (lower limit to trigger chunking easily) + type(embedder).max_tokens = property(lambda self: max_tokens) + + return embedder, mock_client + + def test_short_text_no_chunking(self, mock_openai_class): + """Short text (< max_tokens) should embed normally without chunking.""" + embedder, mock_client = self._make_embedder(mock_openai_class, max_tokens=8000) + result = embedder.embed("Hello world") + + assert result.dense_vector is not None + assert len(result.dense_vector) == DIMENSION + assert mock_client.embeddings.create.call_count >= 1 + + def test_oversized_text_triggers_chunking(self, mock_openai_class): + """Text exceeding max_tokens should trigger chunking and return correct dimension.""" + embedder, mock_client = self._make_embedder(mock_openai_class, max_tokens=10) + + # Create text that will exceed 10 tokens (using fallback: len//3 > 10 means len > 30) + long_text = "This is a sentence. " * 20 # ~400 chars -> ~133 estimated tokens + + result = embedder.embed(long_text) + + assert result.dense_vector is not None + assert len(result.dense_vector) == DIMENSION + # Multiple API calls should have been made (one per chunk + dimension detection) + assert mock_client.embeddings.create.call_count > 2 + + def test_very_long_text_chunking(self, mock_openai_class): + """Text 10x over the limit should still chunk and return normally.""" + embedder, mock_client = self._make_embedder(mock_openai_class, max_tokens=10) + + # Very long text: ~3000 chars -> ~1000 estimated tokens (100x over limit of 10) + very_long_text = "A" * 3000 + + result = embedder.embed(very_long_text) + + assert result.dense_vector is not None + assert len(result.dense_vector) == DIMENSION + + def test_empty_text_no_error(self, mock_openai_class): + """Empty text should not raise an error.""" + embedder, _ = self._make_embedder(mock_openai_class, max_tokens=8000) + result = embedder.embed("") + + assert result.dense_vector is not None + assert len(result.dense_vector) == DIMENSION + + def test_embed_batch_mixed_lengths(self, mock_openai_class): + """embed_batch with mixed short and long texts should handle each correctly.""" + embedder, mock_client = self._make_embedder(mock_openai_class, max_tokens=10) + + short_text = "Hi" + long_text = "This is a very long sentence. " * 20 # exceeds 10 tokens + + results = embedder.embed_batch([short_text, long_text]) + + assert len(results) == 2 + for result in results: + assert result.dense_vector is not None + assert len(result.dense_vector) == DIMENSION + + def test_embed_batch_empty_list(self, mock_openai_class): + """embed_batch with empty list should return empty list.""" + embedder, _ = self._make_embedder(mock_openai_class, max_tokens=8000) + results = embedder.embed_batch([]) + assert results == [] + + def test_merged_vector_is_normalized(self, mock_openai_class): + """Merged vector from chunking should be L2 normalized.""" + embedder, _ = self._make_embedder(mock_openai_class, max_tokens=10) + + long_text = "Word " * 100 # definitely exceeds 10 tokens + + result = embedder.embed(long_text) + assert result.dense_vector is not None + + # Check L2 norm is approximately 1.0 + norm = math.sqrt(sum(v * v for v in result.dense_vector)) + assert abs(norm - 1.0) < 1e-6 + + def test_paragraph_splitting(self, mock_openai_class): + """Text with paragraph breaks should be split by paragraphs first.""" + embedder, mock_client = self._make_embedder(mock_openai_class, max_tokens=10) + + # Create text with clear paragraph separators + paragraphs = ["Paragraph one content."] * 5 + text_with_paragraphs = "\n\n".join(paragraphs) + + result = embedder.embed(text_with_paragraphs) + assert result.dense_vector is not None + assert len(result.dense_vector) == DIMENSION + + +@patch("openai.OpenAI") +class TestTiktokenFallback: + """Test tiktoken fallback behavior.""" + + def test_fallback_when_tiktoken_unavailable(self, mock_openai_class): + """When tiktoken is not available, should fall back to character-based estimation.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=DIMENSION, + ) + + # Force tiktoken encoder to None to simulate unavailability + embedder._tiktoken_enc = None + + # Character-based estimation: len("hello world") // 3 = 3 + estimated = embedder._estimate_tokens("hello world") + assert estimated == len("hello world") // 3 + + def test_estimate_tokens_with_tiktoken_encoder(self, mock_openai_class): + """When tiktoken encoder is available, should use it for estimation.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=DIMENSION, + ) + + # If tiktoken is available, _tiktoken_enc should not be None + # and estimation should use it + if embedder._tiktoken_enc is not None: + tokens = embedder._estimate_tokens("hello world") + assert isinstance(tokens, int) + assert tokens > 0 + + +class TestBaseChunkText: + """Test _chunk_text and helper methods on a concrete subclass.""" + + def _make_simple_embedder(self, max_tokens=10): + """Create a minimal concrete embedder for testing chunking logic.""" + + class SimpleEmbedder(DenseEmbedderBase): + @property + def max_tokens(self_inner): + return max_tokens + + def _estimate_tokens(self_inner, text): + # Simple: 1 token per word + return len(text.split()) + + def embed(self_inner, text, is_query=False): + dim = 4 + vec = [1.0 / dim] * dim + return EmbedResult(dense_vector=vec) + + def _embed_single(self_inner, text, is_query=False): + return self_inner.embed(text, is_query=is_query) + + def get_dimension(self_inner): + return 4 + + return SimpleEmbedder(model_name="test") + + def test_chunk_text_short(self): + """Text within limit should return single chunk.""" + embedder = self._make_simple_embedder(max_tokens=100) + chunks = embedder._chunk_text("hello world") + assert chunks == ["hello world"] + + def test_chunk_text_paragraph_split(self): + """Text with paragraphs should split by paragraph boundaries.""" + embedder = self._make_simple_embedder(max_tokens=5) + text = "one two three\n\nfour five six" + chunks = embedder._chunk_text(text) + assert len(chunks) >= 2 + for chunk in chunks: + assert embedder._estimate_tokens(chunk) <= 5 + + def test_chunk_text_sentence_split(self): + """Text with sentences but no paragraphs should split by sentences.""" + embedder = self._make_simple_embedder(max_tokens=5) + text = "One two three four. Five six seven eight." + chunks = embedder._chunk_text(text) + assert len(chunks) >= 2 + + def test_chunk_text_fixed_length_fallback(self): + """Text without good natural boundaries should fall back to fixed-length split.""" + embedder = self._make_simple_embedder(max_tokens=3) + # Use a long text with no sentence/paragraph boundaries, >100 chars to exceed min chunk_size + text = "word " * 200 # 200 words = 200 tokens, 1000 chars + chunks = embedder._chunk_text(text) + assert len(chunks) >= 2 + + def test_chunk_and_embed_returns_normalized(self): + """_chunk_and_embed should return a normalized vector.""" + embedder = self._make_simple_embedder(max_tokens=3) + text = "one two three four five six seven eight" + result = embedder._chunk_and_embed(text) + + assert result.dense_vector is not None + norm = math.sqrt(sum(v * v for v in result.dense_vector)) + assert abs(norm - 1.0) < 1e-6 + + def test_chunk_and_embed_short_text_no_split(self): + """_chunk_and_embed on short text should just call _embed_single.""" + embedder = self._make_simple_embedder(max_tokens=100) + result = embedder._chunk_and_embed("hello") + + assert result.dense_vector is not None + assert len(result.dense_vector) == 4 + + +@patch("openai.OpenAI") +class TestMaxTokensConfigurable: + """Test cases for configurable max_tokens parameter.""" + + def test_custom_max_tokens_via_constructor(self, mock_openai_class): + """Custom max_tokens passed to OpenAIDenseEmbedder should be used.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=DIMENSION, + max_tokens=32000, + ) + + assert embedder.max_tokens == 32000 + + def test_default_max_tokens_when_not_provided(self, mock_openai_class): + """When max_tokens is not provided, should default to 8000.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=DIMENSION, + ) + + assert embedder.max_tokens == 8000 + + def test_custom_max_tokens_affects_chunking(self, mock_openai_class): + """A higher max_tokens should allow longer texts without chunking.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + # Create embedder with high max_tokens + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=DIMENSION, + max_tokens=100000, + ) + # Force fallback estimation (len//3) + embedder._tiktoken_enc = None + + # This text would exceed 8000 tokens with fallback estimation (30000 chars -> 10000 tokens) + # but should NOT trigger chunking with max_tokens=100000 + long_text = "word " * 6000 # 30000 chars -> 10000 estimated tokens + + mock_client.embeddings.create.reset_mock() + result = embedder.embed(long_text) + + assert result.dense_vector is not None + # Should be a single API call (plus dimension detection), NOT chunked + assert mock_client.embeddings.create.call_count == 1 + + def test_low_custom_max_tokens_triggers_chunking(self, mock_openai_class): + """A lower max_tokens should trigger chunking for shorter texts.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=DIMENSION, + max_tokens=5, + ) + # Force fallback estimation + embedder._tiktoken_enc = None + + # Need text long enough to produce multiple chunks. + # Fallback estimation: len(text)//3. With max_tokens=5, need >5 tokens. + # Fixed-length split has min chunk_size=100, so text must be >100 chars to split. + text = ( + "Hello world test. " * 30 + ) # 540 chars -> 180 estimated tokens, well over max_tokens=5 + + mock_client.embeddings.create.reset_mock() + result = embedder.embed(text) + + assert result.dense_vector is not None + # Should have chunked (multiple API calls) + assert mock_client.embeddings.create.call_count > 1 + + +class TestBaseMaxTokensConfigurable: + """Test configurable max_tokens on EmbedderBase directly.""" + + def test_base_default_max_tokens(self): + """EmbedderBase without max_tokens should return 8000.""" + + class ConcreteEmbedder(DenseEmbedderBase): + def embed(self, text, is_query=False): + return EmbedResult(dense_vector=[0.0]) + + def get_dimension(self): + return 1 + + embedder = ConcreteEmbedder(model_name="test") + assert embedder.max_tokens == 8000 + + def test_base_custom_max_tokens(self): + """EmbedderBase with max_tokens should return the custom value.""" + + class ConcreteEmbedder(DenseEmbedderBase): + def embed(self, text, is_query=False): + return EmbedResult(dense_vector=[0.0]) + + def get_dimension(self): + return 1 + + embedder = ConcreteEmbedder(model_name="test", max_tokens=32768) + assert embedder.max_tokens == 32768 + + +@patch("openai.OpenAI") +class TestOpenAIEmbedderWithoutApiKey: + """Test cases for OpenAI embedder without api_key (local servers).""" + + def test_init_with_api_base_no_api_key(self, mock_openai_class): + """OpenAIDenseEmbedder should initialize with api_base but no api_key.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + # Should NOT raise when api_base is set but api_key is not + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_base="http://localhost:11434/v1", + dimension=DIMENSION, + ) + + assert embedder is not None + # Verify OpenAI client was initialized with placeholder key + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs["api_key"] == "no-key" + assert call_kwargs["base_url"] == "http://localhost:11434/v1" + + def test_init_without_api_key_or_api_base_raises(self, mock_openai_class): + """OpenAIDenseEmbedder should raise when neither api_key nor api_base is set.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + # Should raise when neither is provided + with pytest.raises(ValueError, match="api_key is required"): + OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + dimension=DIMENSION, + ) + + def test_init_with_api_key_works_normally(self, mock_openai_class): + """OpenAIDenseEmbedder should work normally with api_key provided.""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_key="test-api-key", + dimension=DIMENSION, + ) + + assert embedder is not None + mock_openai_class.assert_called_once() + call_kwargs = mock_openai_class.call_args[1] + assert call_kwargs["api_key"] == "test-api-key" + + def test_embed_with_api_base_no_api_key(self, mock_openai_class): + """Embedding should work with api_base but no api_key (local server).""" + mock_client = _make_mock_openai_client() + mock_openai_class.return_value = mock_client + + mod = _load_openai_embedders() + OpenAIDenseEmbedder = mod.OpenAIDenseEmbedder + + embedder = OpenAIDenseEmbedder( + model_name="text-embedding-3-small", + api_base="http://localhost:11434/v1", + dimension=DIMENSION, + ) + + result = embedder.embed("Hello world") + + assert result.dense_vector is not None + assert len(result.dense_vector) == DIMENSION + mock_client.embeddings.create.assert_called() diff --git a/tests/unit/test_skill_processor_none.py b/tests/unit/test_skill_processor_none.py index a8743533..1681ec28 100644 --- a/tests/unit/test_skill_processor_none.py +++ b/tests/unit/test_skill_processor_none.py @@ -43,3 +43,21 @@ def test_parse_skill_unsupported_type_still_raises(self): processor = SkillProcessor(vikingdb=None) with pytest.raises(ValueError, match="Unsupported data type"): processor._parse_skill(12345) + + def test_parse_skill_long_raw_content_raises_oserror(self): + """Long raw SKILL.md content should still surface path probing errors.""" + processor = SkillProcessor(vikingdb=None) + long_description = "telemetry " * 80 + raw_skill = ( + "---\n" + "name: telemetry-demo-skill\n" + f"description: {long_description}\n" + "tags:\n" + " - telemetry\n" + "---\n\n" + "# Telemetry Demo Skill\n\n" + "Use this skill to validate telemetry ingestion.\n" + ) + + with pytest.raises(OSError, match="File name too long"): + processor._parse_skill(raw_skill) diff --git a/tests/unit/test_voyage_embedder.py b/tests/unit/test_voyage_embedder.py new file mode 100644 index 00000000..1a49f428 --- /dev/null +++ b/tests/unit/test_voyage_embedder.py @@ -0,0 +1,152 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +"""Tests for Voyage AI embedder support.""" + +from unittest.mock import MagicMock, patch + +import pytest + +from openviking.models.embedder import VoyageDenseEmbedder +from openviking.models.embedder.voyage_embedders import VOYAGE_MODEL_DIMENSIONS + + +class TestVoyageDenseEmbedder: + """Test cases for VoyageDenseEmbedder.""" + + def test_init_requires_api_key(self): + with pytest.raises(ValueError, match="api_key is required"): + VoyageDenseEmbedder(model_name="voyage-4-lite") + + def test_init_with_defaults(self): + embedder = VoyageDenseEmbedder( + model_name="voyage-4-lite", + api_key="voyage-key", + ) + assert embedder.api_key == "voyage-key" + assert embedder.api_base == "https://api.voyageai.com/v1" + assert embedder.get_dimension() == 1024 + + def test_model_dimensions_constant(self): + assert VOYAGE_MODEL_DIMENSIONS["voyage-4-lite"] == 1024 + assert VOYAGE_MODEL_DIMENSIONS["voyage-4"] == 1024 + assert VOYAGE_MODEL_DIMENSIONS["voyage-4-large"] == 1024 + assert VOYAGE_MODEL_DIMENSIONS["voyage-code-3"] == 1024 + + def test_custom_dimension(self): + embedder = VoyageDenseEmbedder( + model_name="voyage-4-lite", + api_key="voyage-key", + dimension=256, + ) + assert embedder.get_dimension() == 256 + + def test_invalid_dimension_for_supported_model(self): + with pytest.raises(ValueError, match="Supported dimensions"): + VoyageDenseEmbedder( + model_name="voyage-4-lite", + api_key="voyage-key", + dimension=1536, + ) + + @patch("openviking.models.embedder.voyage_embedders.openai.OpenAI") + def test_embed_single_text(self, mock_openai_class): + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 1024 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_client.embeddings.create.return_value = mock_response + + embedder = VoyageDenseEmbedder( + model_name="voyage-4-lite", + api_key="voyage-key", + ) + result = embedder.embed("Hello world") + + assert result.dense_vector is not None + assert len(result.dense_vector) == 1024 + call_kwargs = mock_client.embeddings.create.call_args[1] + assert call_kwargs["model"] == "voyage-4-lite" + assert "dimensions" not in call_kwargs + assert "extra_body" not in call_kwargs + + @patch("openviking.models.embedder.voyage_embedders.openai.OpenAI") + def test_embed_uses_voyage_output_dimension(self, mock_openai_class): + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_embedding = MagicMock() + mock_embedding.embedding = [0.1] * 512 + + mock_response = MagicMock() + mock_response.data = [mock_embedding] + mock_client.embeddings.create.return_value = mock_response + + embedder = VoyageDenseEmbedder( + model_name="voyage-4-lite", + api_key="voyage-key", + dimension=512, + ) + embedder.embed("Hello world") + + call_kwargs = mock_client.embeddings.create.call_args[1] + assert "extra_body" in call_kwargs + assert call_kwargs["extra_body"]["output_dimension"] == 512 + assert "dimensions" not in call_kwargs + + @patch("openviking.models.embedder.voyage_embedders.openai.OpenAI") + def test_embed_batch(self, mock_openai_class): + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + mock_response = MagicMock() + mock_response.data = [ + MagicMock(embedding=[0.1] * 1024), + MagicMock(embedding=[0.2] * 1024), + ] + mock_client.embeddings.create.return_value = mock_response + + embedder = VoyageDenseEmbedder( + model_name="voyage-4-lite", + api_key="voyage-key", + ) + results = embedder.embed_batch(["Hello", "World"]) + + assert len(results) == 2 + assert len(results[0].dense_vector) == 1024 + assert len(results[1].dense_vector) == 1024 + + @patch("openviking.models.embedder.voyage_embedders.openai.OpenAI") + def test_embed_batch_empty(self, mock_openai_class): + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + + embedder = VoyageDenseEmbedder( + model_name="voyage-4-lite", + api_key="voyage-key", + ) + assert embedder.embed_batch([]) == [] + mock_client.embeddings.create.assert_not_called() + + @patch("openviking.models.embedder.voyage_embedders.openai.OpenAI") + def test_embed_api_error(self, mock_openai_class): + import openai + + mock_client = MagicMock() + mock_openai_class.return_value = mock_client + mock_client.embeddings.create.side_effect = openai.APIError( + message="Voyage error", + request=MagicMock(), + body=None, + ) + + embedder = VoyageDenseEmbedder( + model_name="voyage-4-lite", + api_key="voyage-key", + ) + + with pytest.raises(RuntimeError, match="Voyage API error"): + embedder.embed("Hello world") diff --git a/tests/unit/tool_skill/test_tool_skill_calibration.py b/tests/unit/tool_skill/test_tool_skill_calibration.py index cf4f61e2..6352f6b0 100644 --- a/tests/unit/tool_skill/test_tool_skill_calibration.py +++ b/tests/unit/tool_skill/test_tool_skill_calibration.py @@ -68,7 +68,7 @@ def test_suffix_like_weather_usage_does_not_match_weather(self): tool_parts = [ToolPart(skill_uri="viking://agent/skills/weather", tool_status="completed")] candidate = _candidate(MemoryCategory.SKILLS, skill_name="weather使用") tool_name, skill_name, status = compressor._get_tool_skill_info(candidate, tool_parts) - assert (tool_name, skill_name, status) == ("", "", "completed") + assert (tool_name, skill_name, status) == ("", "weather", "completed") def test_best_match_tie_picks_most_recent_tool_part(self): compressor = SessionCompressor.__new__(SessionCompressor) diff --git a/tests/unit/tool_skill/test_tool_skill_memory_guardrails.py b/tests/unit/tool_skill/test_tool_skill_memory_guardrails.py index 0a02ee09..49fbd3e1 100644 --- a/tests/unit/tool_skill/test_tool_skill_memory_guardrails.py +++ b/tests/unit/tool_skill/test_tool_skill_memory_guardrails.py @@ -219,7 +219,6 @@ async def test_merge_tool_memory_old_format_upgrades_to_reme(monkeypatch): assert "Tool Memory Context:" in written assert "Based on 12 historical calls:" in written assert "- Best for: docs" in written - assert "Guidelines:" in written assert "old guide" in written @@ -241,7 +240,6 @@ async def test_merge_tool_memory_content_format_parses_and_merges(monkeypatch): "- Optimal params: N/A\n" "- Common failures: N/A\n" "- Recommendation: N/A\n\n" - "Guidelines:\n" "old guide\n" ) fs = SimpleNamespace( @@ -258,7 +256,6 @@ async def test_merge_tool_memory_content_format_parses_and_merges(monkeypatch): written = fs.write_file.call_args.kwargs["content"] assert "Based on 4 historical calls:" in written assert "Success rate:" in written - assert "Guidelines:" in written @pytest.mark.asyncio @@ -291,4 +288,3 @@ async def test_merge_skill_memory_old_format_upgrades_to_aligned(monkeypatch): assert "Skill Memory Context:" in written assert "Based on 11 historical executions:" in written assert "- Recommended flow: a->b" in written - assert "Guidelines:" in written diff --git a/tests/utils/mock_context.py b/tests/utils/mock_context.py new file mode 100644 index 00000000..99cc7a6d --- /dev/null +++ b/tests/utils/mock_context.py @@ -0,0 +1,29 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +"""Mock context utilities for testing""" + +from openviking.server.identity import RequestContext, Role +from openviking_cli.session.user_id import UserIdentifier + + +def make_test_user( + account_id: str = "acc1", + user_id: str = "test_user", + agent_id: str = "test_agent", +) -> UserIdentifier: + """Create a test UserIdentifier""" + return UserIdentifier(account_id, user_id, agent_id) + + +def make_test_ctx( + user: UserIdentifier | None = None, + role: Role = Role.ROOT, + account_id: str = "acc1", + user_id: str = "test_user", + agent_id: str = "test_agent", +) -> RequestContext: + """Create a test RequestContext""" + if user is None: + user = make_test_user(account_id, user_id, agent_id) + return RequestContext(user=user, role=role) diff --git a/tests/vectordb/test_oceanbase_live.py b/tests/vectordb/test_oceanbase_live.py new file mode 100644 index 00000000..f1f3f54f --- /dev/null +++ b/tests/vectordb/test_oceanbase_live.py @@ -0,0 +1,542 @@ +# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 +""" +OceanBase adapter live tests. OceanBase is started via Docker for the test run. + + - TestOceanBaseLive: basic create/upsert/query/delete flow. + - TestOceanBaseLiveRealWorld: real-world scenarios (multi-tenant context, filter by + context_type/account_id/uri, vector search + filter, delete by uri). + +Prerequisites: + - Docker running, pip install pyobvector or openviking[oceanbase] + +Run: + pytest tests/vectordb/test_oceanbase_live.py -v -s + python -m unittest tests.vectordb.test_oceanbase_live -v +""" + +import hashlib +import subprocess +import time +import unittest +import uuid + +# ----------------------------------------------------------------------------- +# Docker OceanBase helpers (inlined for self-contained tests) +# ----------------------------------------------------------------------------- +OB_IMAGE = "oceanbase/oceanbase-ce" +OB_PORT = "2881" +OB_DB_NAME = "openviking" +BOOT_TIMEOUT_SEC = 300 +BOOT_POLL_INTERVAL_SEC = 3 + + +def _run(cmd: list, capture: bool = True, timeout: int | None = 60) -> subprocess.CompletedProcess: + return subprocess.run( + cmd, + capture_output=capture, + text=True, + timeout=timeout, + ) + + +def _container_name() -> str: + return f"openviking-ob-test-{uuid.uuid4().hex[:8]}" + + +def _start_oceanbase_docker( + container_name: str | None = None, + port: str | None = None, + db_name: str = OB_DB_NAME, + mode: str = "slim", + boot_timeout_sec: int = BOOT_TIMEOUT_SEC, +) -> dict: + """Start OceanBase in Docker, wait until boot success, create database, return connection info.""" + name = container_name or _container_name() + _run(["docker", "rm", "-f", name], capture=True, timeout=10) + host_port_spec = f"0:{OB_PORT}" if port is None else f"{port}:{OB_PORT}" + r = _run(["docker", "run", "-d", "-p", host_port_spec, "--name", name, "-e", "MODE=" + mode, OB_IMAGE], timeout=30) + if r.returncode != 0: + raise RuntimeError(f"docker run failed: {r.stderr or r.stdout}") + + if port is None: + rp = _run(["docker", "port", name, OB_PORT], timeout=5) + if rp.returncode != 0 or not rp.stdout: + _stop_oceanbase_docker(name) + raise RuntimeError("Could not get container host port") + port = rp.stdout.strip().split(":")[-1] + else: + port = str(port) + + deadline = time.monotonic() + boot_timeout_sec + while time.monotonic() < deadline: + # --tail 50: boot success may not be the very last line; bounded read to avoid timeout + r = _run(["docker", "logs", "--tail", "50", name], timeout=20) + log_snippet = (r.stdout or "") + (r.stderr or "") + if "boot success!" in log_snippet: + break + time.sleep(BOOT_POLL_INTERVAL_SEC) + else: + _stop_oceanbase_docker(name) + raise RuntimeError("OceanBase Docker container did not report boot success within timeout") + + for user in ("root@test", "root"): + created = False + for client in ("mysql", "obclient"): + r = _run([ + "docker", "exec", name, + client, "-h127.0.0.1", f"-P{OB_PORT}", f"-u{user}", "-e", + f"CREATE DATABASE IF NOT EXISTS `{db_name}`;", + ], timeout=15) + if r.returncode == 0: + created = True + break + if not created: + _stop_oceanbase_docker(name) + raise RuntimeError(f"Could not create database for user {user}") + + def stop_callback() -> None: + _stop_oceanbase_docker(name) + + return { + "host": "127.0.0.1", + "port": port, + "user": "root", + "password": "", + "db_name": db_name, + "container_name": name, + "stop_callback": stop_callback, + } + + +def _stop_oceanbase_docker(container_name: str) -> None: + _run(["docker", "stop", "-t", "10", container_name], timeout=30) + _run(["docker", "rm", "-f", container_name], timeout=15) + + +def _is_docker_available() -> bool: + r = _run(["docker", "info"], timeout=15) + return r.returncode == 0 + + +# ----------------------------------------------------------------------------- +# Connection args for live DB; filled by Docker startup +# ----------------------------------------------------------------------------- +CONNECTION_ARGS = { + "host": "127.0.0.1", + "port": "2881", + "user": "root", + "password": "", + "db_name": "openviking", +} + +# Set by Docker startup; cleared in last class tearDownClass +_docker_stop_callback = None + + +def _get_oceanbase_config( + collection_name: str = "openviking_test_context", + distance_metric: str = "cosine", +): + """Build VectorDBBackendConfig (OceanBase) from CONNECTION_ARGS.""" + from openviking_cli.utils.config.vectordb_config import OceanBaseConfig, VectorDBBackendConfig + + uri = f"{CONNECTION_ARGS['host']}:{CONNECTION_ARGS['port']}" + return VectorDBBackendConfig( + backend="oceanbase", + name=collection_name, + distance_metric=distance_metric, + dimension=8, # short vectors for live tests + oceanbase=OceanBaseConfig( + uri=uri, + user=CONNECTION_ARGS["user"], + password=CONNECTION_ARGS["password"], + db_name=CONNECTION_ARGS["db_name"], + ), + ) + + +def _get_context_schema(name: str, dimension: int = 8): + """Return OpenViking context collection schema with Dimension.""" + from openviking.storage.collection_schemas import CollectionSchemas + + schema = CollectionSchemas.context_collection(name, dimension) + schema["Dimension"] = dimension + return schema + + +class TestOceanBaseLive(unittest.TestCase): + """Live tests against real OceanBase (127.0.0.1:2881, db_name=openviking).""" + + @classmethod + def setUpClass(cls): + global _docker_stop_callback + if not _is_docker_available(): + raise unittest.SkipTest("Docker not available; OceanBase tests require Docker") + if _docker_stop_callback is None: + info = _start_oceanbase_docker(mode="slim") + CONNECTION_ARGS["host"] = info["host"] + CONNECTION_ARGS["port"] = info["port"] + CONNECTION_ARGS["user"] = info["user"] + CONNECTION_ARGS["password"] = info["password"] + CONNECTION_ARGS["db_name"] = info["db_name"] + _docker_stop_callback = info["stop_callback"] + # Docker OceanBase (slim) does not support cosine/neg_ip; use L2 + cls._distance = "l2" + try: + import pyobvector # noqa: F401 + except ImportError: + raise unittest.SkipTest("pyobvector not installed (pip install pyobvector or openviking[oceanbase])") + cls.config = _get_oceanbase_config(distance_metric=cls._distance) + cls.schema = _get_context_schema(cls.config.name or "openviking_test_context", dimension=cls.config.dimension or 8) + cls.adapter = None + cls.collection_name = cls.config.name or "openviking_test_context" + + def test_01_create_adapter_and_collection(self): + """Create adapter and collection (skip if already exists).""" + from openviking.storage.vectordb_adapters.factory import create_collection_adapter + + self.adapter = create_collection_adapter(self.config) + self.assertIsNotNone(self.adapter) + self.assertEqual(self.adapter.mode, "oceanbase") + + if not self.adapter.collection_exists(): + created = self.adapter.create_collection( + self.collection_name, + self.schema, + distance=self._distance, + sparse_weight=0.0, + index_name="default", + ) + self.assertTrue(created, "create_collection should return True when collection was created") + else: + # Collection exists, skip create + pass + + def test_02_upsert_and_fetch(self): + """Upsert records and fetch by id.""" + from openviking.storage.vectordb_adapters.factory import create_collection_adapter + + if self.adapter is None: + self.adapter = create_collection_adapter(self.config) + if not self.adapter.collection_exists(): + self.test_01_create_adapter_and_collection() + + # 8-dim vectors (match schema); adapter fills required fields without defaults + records = [ + { + "id": "live-test-id-1", + "uri": "viking://resources/test/doc1.md", + "type": "file", + "context_type": "resource", + "vector": [0.1] * 8, + "sparse_vector": {}, + "abstract": "first doc", + "created_at": 0, + "updated_at": 0, + }, + { + "id": "live-test-id-2", + "uri": "viking://resources/test/doc2.md", + "type": "file", + "context_type": "resource", + "vector": [0.2] * 8, + "sparse_vector": {}, + "abstract": "second doc", + "created_at": 0, + "updated_at": 0, + }, + ] + ids = self.adapter.upsert(records) + self.assertEqual(len(ids), 2) + self.assertIn("live-test-id-1", ids) + self.assertIn("live-test-id-2", ids) + + fetched = self.adapter.get(ids=["live-test-id-1", "live-test-id-2"]) + self.assertGreaterEqual(len(fetched), 2) + + def test_03_search_by_vector(self): + """Vector search.""" + from openviking.storage.vectordb_adapters.factory import create_collection_adapter + + if self.adapter is None: + self.adapter = create_collection_adapter(self.config) + if not self.adapter.collection_exists(): + self.test_01_create_adapter_and_collection() + + query_vector = [0.15] * 8 + results = self.adapter.query( + query_vector=query_vector, + limit=5, + ) + self.assertIsInstance(results, list) + # At least 2 rows from test_02 + self.assertGreaterEqual(len(results), 2) + + def test_04_count_and_cleanup(self): + """Count and delete test data.""" + from openviking.storage.vectordb_adapters.factory import create_collection_adapter + + if self.adapter is None: + self.adapter = create_collection_adapter(self.config) + if not self.adapter.collection_exists(): + return + + n = self.adapter.count() + self.assertGreaterEqual(n, 0) + + # Delete test ids inserted by this script + deleted = self.adapter.delete(ids=["live-test-id-1", "live-test-id-2"]) + self.assertGreaterEqual(deleted, 0) + + +# ----------------------------------------------------------------------------- +# Real-world: multi-tenant, filter, vector search, delete by uri +# ----------------------------------------------------------------------------- + +REALWORLD_COLLECTION = "openviking_live_context" + + +def _realworld_record( + uri: str, + context_type: str, + account_id: str, + owner_space: str, + abstract: str, + vector: list, + level: int = 2, + name: str = "", +): + """Build one context record matching production shape (id from account_id:uri, same as TextEmbeddingHandler).""" + id_seed = f"{account_id}:{uri}" + record_id = hashlib.md5(id_seed.encode("utf-8")).hexdigest() + return { + "id": record_id, + "uri": uri, + "type": "file", + "context_type": context_type, + "vector": vector, + "abstract": abstract, + "account_id": account_id, + "owner_space": owner_space, + "level": level, + "name": name or abstract[:50], + } + + +class TestOceanBaseLiveRealWorld(unittest.TestCase): + """ + OceanBase live tests for real-world scenarios: + - Multi-tenant context upsert (resource / memory) + - Filter by context_type, account_id, uri + - Vector search + filter + - Delete by uri, delete by filter, full cleanup + """ + + @classmethod + def setUpClass(cls): + try: + import pyobvector # noqa: F401 + except ImportError: + raise unittest.SkipTest("pyobvector not installed") + # Use L2: many OceanBase versions do not support neg_ip (cosine); real-world collection uses L2 + cls.config = _get_oceanbase_config(REALWORLD_COLLECTION, distance_metric="l2") + cls.schema = _get_context_schema(REALWORLD_COLLECTION, dimension=cls.config.dimension or 8) + cls.adapter = None + + def _adapter(self): + from openviking.storage.vectordb_adapters.factory import create_collection_adapter + + if self.adapter is None: + self.adapter = create_collection_adapter(self.config) + return self.adapter + + def _ensure_collection(self): + a = self._adapter() + if not a.collection_exists(): + a.create_collection( + REALWORLD_COLLECTION, + self.schema, + distance="l2", # Match config; OceanBase may not support neg_ip + sparse_weight=0.0, + index_name="default", + ) + + def test_realworld_01_upsert_multi_tenant_context(self): + """Real-world: upsert multi-tenant resource + memory context data.""" + self._ensure_collection() + dim = 8 + records = [ + _realworld_record( + uri="viking://resources/acc_1/proj_a/readme.md", + context_type="resource", + account_id="acc_1", + owner_space="default", + abstract="Project A readme", + vector=[0.1] * dim, + name="readme", + ), + _realworld_record( + uri="viking://resources/acc_1/proj_a/src/main.py", + context_type="resource", + account_id="acc_1", + owner_space="default", + abstract="Main entry", + vector=[0.12, 0.11, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1], + name="main", + ), + _realworld_record( + uri="viking://user/acc_1/default/memories/mem_001.md", + context_type="memory", + account_id="acc_1", + owner_space="default", + abstract="User preference: prefers Python", + vector=[0.2] * dim, + name="memory", + ), + _realworld_record( + uri="viking://resources/acc_2/proj_b/doc.md", + context_type="resource", + account_id="acc_2", + owner_space="default", + abstract="Project B doc", + vector=[0.15] * dim, + name="doc", + ), + _realworld_record( + uri="viking://user/acc_2/default/memories/mem_002.md", + context_type="memory", + account_id="acc_2", + owner_space="default", + abstract="User preference: prefers Markdown", + vector=[0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18, 0.18], + name="memory", + ), + ] + ids = self._adapter().upsert(records) + self.assertEqual(len(ids), 5) + self.assertEqual(len(set(ids)), 5) + + def test_realworld_02_filter_by_context_type(self): + """Real-world: filter by context_type.""" + self._ensure_collection() + from openviking.storage.expr import Eq + + resource_records = self._adapter().query( + filter=Eq("context_type", "resource"), + limit=20, + ) + memory_records = self._adapter().query( + filter=Eq("context_type", "memory"), + limit=20, + ) + self.assertGreaterEqual(len(resource_records), 3, "at least 3 resource (2 acc_1 + 1 acc_2)") + self.assertGreaterEqual(len(memory_records), 2, "at least 2 memory") + for r in resource_records: + self.assertEqual(r.get("context_type"), "resource") + for r in memory_records: + self.assertEqual(r.get("context_type"), "memory") + + def test_realworld_03_filter_by_account_id(self): + """Real-world: filter by account_id (tenant isolation).""" + self._ensure_collection() + from openviking.storage.expr import Eq + + acc1 = self._adapter().query(filter=Eq("account_id", "acc_1"), limit=20) + acc2 = self._adapter().query(filter=Eq("account_id", "acc_2"), limit=20) + self.assertGreaterEqual(len(acc1), 3, "acc_1 at least 3") + self.assertGreaterEqual(len(acc2), 2, "acc_2 at least 2") + for r in acc1: + self.assertEqual(r.get("account_id"), "acc_1") + for r in acc2: + self.assertEqual(r.get("account_id"), "acc_2") + + def test_realworld_04_vector_search_with_filter(self): + """Real-world: vector search + context_type filter.""" + self._ensure_collection() + from openviking.storage.expr import And, Eq + + query_vector = [0.12] * 8 + results = self._adapter().query( + query_vector=query_vector, + filter=Eq("context_type", "resource"), + limit=5, + ) + self.assertIsInstance(results, list) + self.assertGreaterEqual(len(results), 1) + for r in results: + self.assertEqual(r.get("context_type"), "resource") + self.assertIn("abstract", r) + + def test_realworld_05_fetch_by_uri(self): + """Real-world: fetch by uri (simulate fetch_by_uri).""" + self._ensure_collection() + target_uri = "viking://resources/acc_1/proj_a/readme.md" + records = self._adapter().query( + filter={"op": "must", "field": "uri", "conds": [target_uri]}, + limit=2, + ) + self.assertGreaterEqual(len(records), 1) + self.assertEqual(records[0].get("uri"), target_uri) + self.assertEqual(records[0].get("account_id"), "acc_1") + + def test_realworld_06_get_by_ids(self): + """Real-world: get by ids (same ids as returned by upsert).""" + self._ensure_collection() + uri = "viking://resources/acc_1/proj_a/readme.md" + record_id = hashlib.md5(f"acc_1:{uri}".encode("utf-8")).hexdigest() + fetched = self._adapter().get(ids=[record_id]) + self.assertGreaterEqual(len(fetched), 1) + self.assertEqual(fetched[0].get("id"), record_id) + self.assertEqual(fetched[0].get("uri"), uri) + + def test_realworld_07_count_with_filter(self): + """Real-world: count with filter.""" + self._ensure_collection() + from openviking.storage.expr import Eq + + total = self._adapter().count() + self.assertGreaterEqual(total, 5) + resource_count = self._adapter().count(filter=Eq("context_type", "resource")) + self.assertGreaterEqual(resource_count, 3) + acc1_count = self._adapter().count(filter=Eq("account_id", "acc_1")) + self.assertGreaterEqual(acc1_count, 3) + + def test_realworld_08_delete_by_uri_then_cleanup(self): + """Real-world: delete by uri, then cleanup by account_id.""" + self._ensure_collection() + # Delete one by uri + target_uri = "viking://resources/acc_2/proj_b/doc.md" + records = self._adapter().query( + filter={"op": "must", "field": "uri", "conds": [target_uri]}, + limit=2, + ) + if records: + rid = records[0].get("id") + if rid: + self._adapter().delete(ids=[rid]) + # Delete all for acc_1 and acc_2 (tenant cleanup) + from openviking.storage.expr import Eq + + for acc in ("acc_1", "acc_2"): + deleted = self._adapter().delete(filter=Eq("account_id", acc), limit=10000) + self.assertGreaterEqual(deleted, 0) + # Collection may be empty if only this class uses it + final_count = self._adapter().count() + self.assertGreaterEqual(final_count, 0) + # This test only verifies delete by filter runs; for strict cleanup, drop collection + self.assertIsInstance(final_count, int) + self.adapter = None # Allow later tests to recreate adapter + + @classmethod + def tearDownClass(cls): + global _docker_stop_callback + if _docker_stop_callback is not None: + try: + _docker_stop_callback() + finally: + _docker_stop_callback = None + + +if __name__ == "__main__": + unittest.main() diff --git a/third_party/agfs/agfs-server/Makefile b/third_party/agfs/agfs-server/Makefile index cc80a2b0..a769aeb7 100644 --- a/third_party/agfs/agfs-server/Makefile +++ b/third_party/agfs/agfs-server/Makefile @@ -8,6 +8,19 @@ GO=go GOFLAGS=-v ADDR?=:8080 +# OS detection +ifeq ($(OS),Windows_NT) + PLATFORM := windows +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Linux) + PLATFORM := linux + endif + ifeq ($(UNAME_S),Darwin) + PLATFORM := darwin + endif +endif + # Build information VERSION?=$(shell git describe --tags --always --dirty 2>/dev/null || echo "dev") BUILD_TIME=$(shell date -u '+%Y-%m-%d_%H:%M:%S') @@ -25,26 +38,18 @@ build: ## Build the server binary @echo "Build complete: $(BUILD_DIR)/$(BINARY_NAME)" build-lib: ## Build AGFS binding library - @echo "Detecting OS for building binding library..." - @OS=$$(uname -s | tr '[:upper:]' '[:lower:]'); \ - LIB_NAME=libagfsbinding; \ - CMD_PYBINDING_DIR=cmd/pybinding; \ - case "$$OS" in \ - darwin*) \ - echo "Building for macOS..."; \ - CGO_ENABLED=1 $(GO) build -buildmode=c-shared -o $(BUILD_DIR)/$$LIB_NAME.dylib $$CMD_PYBINDING_DIR/main.go; \ - ;; \ - linux*) \ - echo "Building for Linux..."; \ - CGO_ENABLED=1 $(GO) build -buildmode=c-shared -o $(BUILD_DIR)/$$LIB_NAME.so $$CMD_PYBINDING_DIR/main.go; \ - ;; \ - msys*|cygwin*|mingw*) \ - echo "Building for Windows..."; \ - CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ AR=x86_64-w64-mingw32-ar GOOS=windows GOARCH=amd64 CGO_ENABLED=1 $(GO) build -buildmode=c-shared -o $(BUILD_DIR)/$$LIB_NAME.dll $$CMD_PYBINDING_DIR/main.go; \ - ;; \ - *) echo "Unsupported OS: $$OS"; exit 1 ;; \ - esac; \ - echo "Build complete in $(BUILD_DIR)" + @echo "Building binding library for $(PLATFORM)..." + @mkdir -p $(BUILD_DIR) +ifeq ($(PLATFORM),darwin) + CGO_ENABLED=1 $(GO) build -buildmode=c-shared -o $(BUILD_DIR)/libagfsbinding.dylib cmd/pybinding/main.go +else ifeq ($(PLATFORM),linux) + CGO_ENABLED=1 $(GO) build -buildmode=c-shared -o $(BUILD_DIR)/libagfsbinding.so cmd/pybinding/main.go +else ifeq ($(PLATFORM),windows) + CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ AR=x86_64-w64-mingw32-ar GOOS=windows GOARCH=amd64 CGO_ENABLED=1 $(GO) build -buildmode=c-shared -o $(BUILD_DIR)/libagfsbinding.dll cmd/pybinding/main.go +else + @echo "Unsupported OS: $(PLATFORM)" && exit 1 +endif + @echo "Build complete in $(BUILD_DIR)" run: build @echo "Starting $(BINARY_NAME) on $(ADDR)..." @@ -104,3 +109,6 @@ release: clean test build ## Run tests and build release binary GOOS=darwin GOARCH=arm64 $(GO) build $(LDFLAGS) -o $(BUILD_DIR)/release/$(BINARY_NAME)-darwin-arm64 $(CMD_DIR)/main.go GOOS=windows GOARCH=amd64 $(GO) build $(LDFLAGS) -o $(BUILD_DIR)/release/$(BINARY_NAME)-windows-amd64.exe $(CMD_DIR)/main.go @echo "Release builds complete in $(BUILD_DIR)/release/" + +help: ## Display this help screen + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/third_party/agfs/agfs-server/pkg/plugins/queuefs/backend.go b/third_party/agfs/agfs-server/pkg/plugins/queuefs/backend.go index f2ccde99..c20fdc66 100644 --- a/third_party/agfs/agfs-server/pkg/plugins/queuefs/backend.go +++ b/third_party/agfs/agfs-server/pkg/plugins/queuefs/backend.go @@ -24,9 +24,18 @@ type QueueBackend interface { // Enqueue adds a message to a queue Enqueue(queueName string, msg QueueMessage) error - // Dequeue removes and returns the first message from a queue + // Dequeue marks the first pending message as 'processing' and returns it. + // Call Ack after successful processing to permanently delete the message. Dequeue(queueName string) (QueueMessage, bool, error) + // Ack permanently deletes a message that has been successfully processed. + Ack(queueName string, messageID string) error + + // RecoverStale resets messages stuck in 'processing' state back to 'pending'. + // staleSec: minimum age in seconds; pass 0 to reset all processing messages. + // Returns the number of messages recovered. + RecoverStale(staleSec int64) (int, error) + // Peek returns the first message without removing it Peek(queueName string) (QueueMessage, bool, error) @@ -124,6 +133,16 @@ func (b *MemoryBackend) Dequeue(queueName string) (QueueMessage, bool, error) { return msg, true, nil } +// Ack is a no-op for the memory backend (messages are already removed on Dequeue). +func (b *MemoryBackend) Ack(queueName string, messageID string) error { + return nil +} + +// RecoverStale is a no-op for the memory backend (no persistence across restarts). +func (b *MemoryBackend) RecoverStale(staleSec int64) (int, error) { + return 0, nil +} + func (b *MemoryBackend) Peek(queueName string) (QueueMessage, bool, error) { queue, exists := b.queues[queueName] if !exists { @@ -345,6 +364,16 @@ func (b *TiDBBackend) Enqueue(queueName string, msg QueueMessage) error { return nil } +// Ack is not yet implemented for TiDB backend (messages are already soft-deleted on Dequeue). +func (b *TiDBBackend) Ack(queueName string, messageID string) error { + return nil +} + +// RecoverStale is not yet implemented for TiDB backend. +func (b *TiDBBackend) RecoverStale(staleSec int64) (int, error) { + return 0, nil +} + func (b *TiDBBackend) Dequeue(queueName string) (QueueMessage, bool, error) { // Get table name from cache (lazy loading) tableName, err := b.getTableName(queueName, false) diff --git a/third_party/agfs/agfs-server/pkg/plugins/queuefs/db_backend.go b/third_party/agfs/agfs-server/pkg/plugins/queuefs/db_backend.go index 03b7342f..9639531c 100644 --- a/third_party/agfs/agfs-server/pkg/plugins/queuefs/db_backend.go +++ b/third_party/agfs/agfs-server/pkg/plugins/queuefs/db_backend.go @@ -63,16 +63,22 @@ func (b *SQLiteDBBackend) GetInitSQL() []string { last_updated INTEGER DEFAULT (strftime('%s', 'now')) )`, // Queue messages table + // status: 'pending' (waiting) | 'processing' (dequeued, not yet acked) + // processing_started_at: Unix timestamp when dequeued; NULL if pending `CREATE TABLE IF NOT EXISTS queue_messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, queue_name TEXT NOT NULL, message_id TEXT NOT NULL, data TEXT NOT NULL, timestamp INTEGER NOT NULL, + status TEXT NOT NULL DEFAULT 'pending', + processing_started_at INTEGER, created_at INTEGER DEFAULT (strftime('%s', 'now')) )`, `CREATE INDEX IF NOT EXISTS idx_queue_name ON queue_messages(queue_name)`, `CREATE INDEX IF NOT EXISTS idx_queue_order ON queue_messages(queue_name, id)`, + `CREATE INDEX IF NOT EXISTS idx_queue_status ON queue_messages(queue_name, status, id)`, + `CREATE INDEX IF NOT EXISTS idx_queue_message_id ON queue_messages(queue_name, message_id)`, } } diff --git a/third_party/agfs/agfs-server/pkg/plugins/queuefs/queuefs.go b/third_party/agfs/agfs-server/pkg/plugins/queuefs/queuefs.go index d8d481b0..052a8f19 100644 --- a/third_party/agfs/agfs-server/pkg/plugins/queuefs/queuefs.go +++ b/third_party/agfs/agfs-server/pkg/plugins/queuefs/queuefs.go @@ -137,7 +137,9 @@ func (q *QueueFSPlugin) Initialize(cfg map[string]interface{}) error { switch backendType { case "memory": backend = NewMemoryBackend() - case "tidb", "mysql", "sqlite", "sqlite3": + case "sqlite", "sqlite3": + backend = NewSQLiteQueueBackend() + case "tidb", "mysql": backend = NewTiDBBackend() default: return fmt.Errorf("unsupported backend: %s", backendType) @@ -384,6 +386,7 @@ var queueOperations = map[string]bool{ "peek": true, "size": true, "clear": true, + "ack": true, // write message_id to confirm processing complete (at-least-once delivery) } // parseQueuePath parses a path like "/queue_name/operation" or "/dir/queue_name/operation" @@ -529,7 +532,7 @@ func (qfs *queueFS) Read(path string, offset int64, size int64) ([]byte, error) data, err = qfs.peek(queueName) case "size": data, err = qfs.size(queueName) - case "enqueue", "clear": + case "enqueue", "clear", "ack": // Write-only files return []byte(""), fmt.Errorf("permission denied: %s is write-only", path) default: @@ -573,6 +576,12 @@ func (qfs *queueFS) Write(path string, data []byte, offset int64, flags filesyst return 0, err } return 0, nil + case "ack": + msgID := strings.TrimSpace(string(data)) + if err := qfs.ackMessage(queueName, msgID); err != nil { + return 0, err + } + return int64(len(data)), nil default: return 0, fmt.Errorf("cannot write to: %s", path) } @@ -844,7 +853,7 @@ func (qfs *queueFS) Stat(p string) (*filesystem.FileInfo, error) { } mode := uint32(0644) - if operation == "enqueue" || operation == "clear" { + if operation == "enqueue" || operation == "clear" || operation == "ack" { mode = 0222 } else { mode = 0444 @@ -992,6 +1001,13 @@ func (qfs *queueFS) clear(queueName string) error { return qfs.plugin.backend.Clear(queueName) } +func (qfs *queueFS) ackMessage(queueName string, msgID string) error { + qfs.plugin.mu.Lock() + defer qfs.plugin.mu.Unlock() + + return qfs.plugin.backend.Ack(queueName, msgID) +} + // Ensure QueueFSPlugin implements ServicePlugin var _ plugin.ServicePlugin = (*QueueFSPlugin)(nil) var _ filesystem.FileSystem = (*queueFS)(nil) diff --git a/third_party/agfs/agfs-server/pkg/plugins/queuefs/sqlite_backend.go b/third_party/agfs/agfs-server/pkg/plugins/queuefs/sqlite_backend.go new file mode 100644 index 00000000..2a0c4dbe --- /dev/null +++ b/third_party/agfs/agfs-server/pkg/plugins/queuefs/sqlite_backend.go @@ -0,0 +1,321 @@ +package queuefs + +import ( + "database/sql" + "encoding/json" + "fmt" + "strings" + "time" + + log "github.com/sirupsen/logrus" +) + +// SQLiteQueueBackend implements QueueBackend using SQLite with a single-table schema. +// +// Schema: +// - queue_metadata: tracks all queues (including empty ones created via mkdir) +// - queue_messages: stores all messages, filtered by queue_name column +// - status: 'pending' (waiting to be processed) | 'processing' (dequeued, awaiting ack) +// - processing_started_at: Unix timestamp when dequeued; NULL while pending +// +// Delivery semantics: at-least-once +// - Dequeue marks message as 'processing' (does NOT delete) +// - Ack deletes the message after successful processing +// - On startup, RecoverStale resets all 'processing' messages back to 'pending' +// so that messages from a previous crashed run are automatically retried +type SQLiteQueueBackend struct { + db *sql.DB +} + +func NewSQLiteQueueBackend() *SQLiteQueueBackend { + return &SQLiteQueueBackend{} +} + +func (b *SQLiteQueueBackend) Initialize(config map[string]interface{}) error { + dbBackend := NewSQLiteDBBackend() + + db, err := dbBackend.Open(config) + if err != nil { + return fmt.Errorf("failed to open SQLite database: %w", err) + } + b.db = db + + for _, sqlStmt := range dbBackend.GetInitSQL() { + if _, err := db.Exec(sqlStmt); err != nil { + db.Close() + return fmt.Errorf("failed to initialize schema: %w", err) + } + } + + // Migrate existing databases: add new columns if they don't exist yet. + b.runMigrations() + + // Reset any messages left in 'processing' state by a previous crashed process. + // staleSec=0 resets ALL processing messages — safe at startup because no workers + // are running yet. + if n, err := b.RecoverStale(0); err != nil { + log.Warnf("[queuefs] Failed to recover stale messages on startup: %v", err) + } else if n > 0 { + log.Infof("[queuefs] Recovered %d in-flight message(s) from previous run", n) + } + + log.Info("[queuefs] SQLite backend initialized") + return nil +} + +// runMigrations applies schema changes needed to upgrade an existing database. +// Each ALTER TABLE is executed and "duplicate column name" errors are silently ignored. +func (b *SQLiteQueueBackend) runMigrations() { + migrations := []string{ + `ALTER TABLE queue_messages ADD COLUMN status TEXT NOT NULL DEFAULT 'pending'`, + `ALTER TABLE queue_messages ADD COLUMN processing_started_at INTEGER`, + `CREATE INDEX IF NOT EXISTS idx_queue_status ON queue_messages(queue_name, status, id)`, + `CREATE INDEX IF NOT EXISTS idx_queue_message_id ON queue_messages(queue_name, message_id)`, + } + for _, stmt := range migrations { + if _, err := b.db.Exec(stmt); err != nil { + // "duplicate column name" means the column already exists — that's fine. + if !strings.Contains(err.Error(), "duplicate column name") && + !strings.Contains(err.Error(), "already exists") { + log.Warnf("[queuefs] Migration warning: %v", err) + } + } + } +} + +func (b *SQLiteQueueBackend) Close() error { + if b.db != nil { + return b.db.Close() + } + return nil +} + +func (b *SQLiteQueueBackend) GetType() string { + return "sqlite" +} + +func (b *SQLiteQueueBackend) Enqueue(queueName string, msg QueueMessage) error { + msgData, err := json.Marshal(msg) + if err != nil { + return fmt.Errorf("failed to marshal message: %w", err) + } + + _, err = b.db.Exec( + "INSERT INTO queue_messages (queue_name, message_id, data, timestamp, status) VALUES (?, ?, ?, ?, 'pending')", + queueName, msg.ID, string(msgData), msg.Timestamp.Unix(), + ) + if err != nil { + return fmt.Errorf("failed to enqueue message: %w", err) + } + return nil +} + +// Dequeue marks the first pending message as 'processing' and returns it. +// The message remains in the database until Ack is called. +// If the process crashes before Ack, RecoverStale on the next startup will +// reset the message back to 'pending' so it is retried. +func (b *SQLiteQueueBackend) Dequeue(queueName string) (QueueMessage, bool, error) { + tx, err := b.db.Begin() + if err != nil { + return QueueMessage{}, false, fmt.Errorf("failed to start transaction: %w", err) + } + defer tx.Rollback() + + var id int64 + var data string + err = tx.QueryRow( + "SELECT id, data FROM queue_messages WHERE queue_name = ? AND status = 'pending' ORDER BY id LIMIT 1", + queueName, + ).Scan(&id, &data) + + if err == sql.ErrNoRows { + return QueueMessage{}, false, nil + } else if err != nil { + return QueueMessage{}, false, fmt.Errorf("failed to query message: %w", err) + } + + // Mark as processing instead of deleting. + _, err = tx.Exec( + "UPDATE queue_messages SET status = 'processing', processing_started_at = ? WHERE id = ?", + time.Now().Unix(), id, + ) + if err != nil { + return QueueMessage{}, false, fmt.Errorf("failed to mark message as processing: %w", err) + } + + if err := tx.Commit(); err != nil { + return QueueMessage{}, false, fmt.Errorf("failed to commit transaction: %w", err) + } + + var msg QueueMessage + if err := json.Unmarshal([]byte(data), &msg); err != nil { + return QueueMessage{}, false, fmt.Errorf("failed to unmarshal message: %w", err) + } + + return msg, true, nil +} + +// Ack deletes a message that has been successfully processed. +// Should be called after the consumer has finished processing the message. +func (b *SQLiteQueueBackend) Ack(queueName string, messageID string) error { + result, err := b.db.Exec( + "DELETE FROM queue_messages WHERE queue_name = ? AND message_id = ? AND status = 'processing'", + queueName, messageID, + ) + if err != nil { + return fmt.Errorf("failed to ack message: %w", err) + } + rows, _ := result.RowsAffected() + if rows == 0 { + log.Warnf("[queuefs] Ack found no matching processing message: queue=%s msg=%s", queueName, messageID) + } + return nil +} + +// RecoverStale resets messages stuck in 'processing' state back to 'pending'. +// staleSec is the minimum age (in seconds) of a processing message before it +// is considered stale. Pass 0 to reset ALL processing messages immediately +// (appropriate at startup before any workers have started). +// Returns the number of messages recovered. +func (b *SQLiteQueueBackend) RecoverStale(staleSec int64) (int, error) { + cutoff := time.Now().Unix() - staleSec + result, err := b.db.Exec( + "UPDATE queue_messages SET status = 'pending', processing_started_at = NULL WHERE status = 'processing' AND processing_started_at <= ?", + cutoff, + ) + if err != nil { + return 0, fmt.Errorf("failed to recover stale messages: %w", err) + } + n, _ := result.RowsAffected() + return int(n), nil +} + +func (b *SQLiteQueueBackend) Peek(queueName string) (QueueMessage, bool, error) { + var data string + err := b.db.QueryRow( + "SELECT data FROM queue_messages WHERE queue_name = ? AND status = 'pending' ORDER BY id LIMIT 1", + queueName, + ).Scan(&data) + + if err == sql.ErrNoRows { + return QueueMessage{}, false, nil + } else if err != nil { + return QueueMessage{}, false, fmt.Errorf("failed to peek message: %w", err) + } + + var msg QueueMessage + if err := json.Unmarshal([]byte(data), &msg); err != nil { + return QueueMessage{}, false, fmt.Errorf("failed to unmarshal message: %w", err) + } + + return msg, true, nil +} + +// Size returns the number of pending (not yet dequeued) messages. +func (b *SQLiteQueueBackend) Size(queueName string) (int, error) { + var count int + err := b.db.QueryRow( + "SELECT COUNT(*) FROM queue_messages WHERE queue_name = ? AND status = 'pending'", + queueName, + ).Scan(&count) + if err != nil { + return 0, fmt.Errorf("failed to get queue size: %w", err) + } + return count, nil +} + +func (b *SQLiteQueueBackend) Clear(queueName string) error { + _, err := b.db.Exec("DELETE FROM queue_messages WHERE queue_name = ?", queueName) + if err != nil { + return fmt.Errorf("failed to clear queue: %w", err) + } + return nil +} + +func (b *SQLiteQueueBackend) ListQueues(prefix string) ([]string, error) { + var query string + var args []interface{} + + if prefix == "" { + query = "SELECT queue_name FROM queue_metadata" + } else { + query = "SELECT queue_name FROM queue_metadata WHERE queue_name = ? OR queue_name LIKE ?" + args = []interface{}{prefix, prefix + "/%"} + } + + rows, err := b.db.Query(query, args...) + if err != nil { + return nil, fmt.Errorf("failed to list queues: %w", err) + } + defer rows.Close() + + var queues []string + for rows.Next() { + var qName string + if err := rows.Scan(&qName); err != nil { + return nil, fmt.Errorf("failed to scan queue name: %w", err) + } + queues = append(queues, qName) + } + return queues, nil +} + +func (b *SQLiteQueueBackend) GetLastEnqueueTime(queueName string) (time.Time, error) { + var timestamp sql.NullInt64 + err := b.db.QueryRow( + "SELECT MAX(timestamp) FROM queue_messages WHERE queue_name = ? AND status = 'pending'", + queueName, + ).Scan(×tamp) + + if err != nil || !timestamp.Valid { + return time.Time{}, nil + } + return time.Unix(timestamp.Int64, 0), nil +} + +func (b *SQLiteQueueBackend) RemoveQueue(queueName string) error { + if queueName == "" { + if _, err := b.db.Exec("DELETE FROM queue_messages"); err != nil { + return err + } + _, err := b.db.Exec("DELETE FROM queue_metadata") + return err + } + + if _, err := b.db.Exec( + "DELETE FROM queue_messages WHERE queue_name = ? OR queue_name LIKE ?", + queueName, queueName+"/%", + ); err != nil { + return fmt.Errorf("failed to remove queue messages: %w", err) + } + + _, err := b.db.Exec( + "DELETE FROM queue_metadata WHERE queue_name = ? OR queue_name LIKE ?", + queueName, queueName+"/%", + ) + return err +} + +func (b *SQLiteQueueBackend) CreateQueue(queueName string) error { + _, err := b.db.Exec( + "INSERT OR IGNORE INTO queue_metadata (queue_name) VALUES (?)", + queueName, + ) + if err != nil { + return fmt.Errorf("failed to create queue: %w", err) + } + log.Infof("[queuefs] Created queue '%s' (SQLite)", queueName) + return nil +} + +func (b *SQLiteQueueBackend) QueueExists(queueName string) (bool, error) { + var count int + err := b.db.QueryRow( + "SELECT COUNT(*) FROM queue_metadata WHERE queue_name = ?", + queueName, + ).Scan(&count) + if err != nil { + return false, fmt.Errorf("failed to check queue existence: %w", err) + } + return count > 0, nil +} diff --git a/uv.lock b/uv.lock index 9e1c6e71..59e6638e 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -453,6 +453,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f5/10/56978295c14794b2c12007b07f3e41ba26acda9257457d7085b0bb3bb90c/brotli-1.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:e7c0af964e0b4e3412a0ebf341ea26ec767fa0b4cf81abb5e897c9338b5ad6a3", size = 375639, upload-time = "2025-11-05T18:38:55.67Z" }, ] +[[package]] +name = "build" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "os_name == 'nt'" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10.2'" }, + { name = "packaging" }, + { name = "pyproject-hooks" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/18/94eaffda7b329535d91f00fe605ab1f1e5cd68b2074d03f255c7d250687d/build-1.4.0.tar.gz", hash = "sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936", size = 50054, upload-time = "2026-01-08T16:41:47.696Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/0d/84a4380f930db0010168e0aa7b7a8fed9ba1835a8fbb1472bc6d0201d529/build-1.4.0-py3-none-any.whl", hash = "sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596", size = 24141, upload-time = "2026-01-08T16:41:46.453Z" }, +] + [[package]] name = "certifi" version = "2026.2.25" @@ -679,6 +695,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, ] +[[package]] +name = "cmake" +version = "4.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/1d/f917d89175a54938837f44f7672bc2bc24d1f6fc85c7f787b8d29c1017d2/cmake-4.2.3.tar.gz", hash = "sha256:7a6bc333453c9f7614c7a6e664950d309a5e1f89fa98512d537d4fde27eb8fae", size = 36957, upload-time = "2026-02-28T17:49:18.848Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/5f/965d2caf7b05e15853974eb36cdc3a8029c09bac886f7448d3f6ad4a8c5d/cmake-4.2.3-py3-none-macosx_10_10_universal2.whl", hash = "sha256:8604578dd087631b1c829315e78e6c81d9549708df2085c89722d5be6174a71f", size = 51591021, upload-time = "2026-02-28T17:48:21.225Z" }, + { url = "https://files.pythonhosted.org/packages/29/92/c8895ffc12c5241111282340c56450707dd8d2f8d1f26c715087e21e3b01/cmake-4.2.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a7e63d254ef3df90299779f5b41bf84cef02fa864255c567356089ea7c382c65", size = 29007127, upload-time = "2026-02-28T17:48:24.701Z" }, + { url = "https://files.pythonhosted.org/packages/ee/2f/f8438b417275d993d457d99f031fbc104bdda879ec7bdf3c6a78b8af05f7/cmake-4.2.3-py3-none-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:56e88a69c95e6defafc8e68ba8b99ca9c4dd6e4c97e7f8039283fe263f1de3c9", size = 30064565, upload-time = "2026-02-28T17:48:27.705Z" }, + { url = "https://files.pythonhosted.org/packages/ee/c5/6a2e1b69d58422ddb6370e5d1e5574218dafe200c61a96add1c4cbe5640e/cmake-4.2.3-py3-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:b243937103331a27e8fae4b9a72b4a852c281fb1339e76eef9e9915d4536c7c9", size = 29837850, upload-time = "2026-02-28T17:48:30.749Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1c/9445c89cfcfbafe1c61a6a1c38072ddcb8413397a736db3bbe8c01f015cc/cmake-4.2.3-py3-none-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c53c2a314a3723f0653c0f90aacca68267f0db003ca596bb2aa65e7fdafa31e2", size = 27749297, upload-time = "2026-02-28T17:48:36.717Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/7ecd2aec927262ff2898d371f44ccb15884b6172407326e9388df07f9642/cmake-4.2.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e91b381aaea3c47110583dccc52f4562333d1accdbb806939f953c16e74ec0a", size = 28904315, upload-time = "2026-02-28T17:48:39.835Z" }, + { url = "https://files.pythonhosted.org/packages/0f/10/b41652c2ce1a33102386f6d65c22192284ed780de2d8ab3f416d795d928b/cmake-4.2.3-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:76eae39cd8855e80a2b485686f3539c39cba5c7eae49c4b634a15638d4edf39f", size = 26086034, upload-time = "2026-02-28T17:48:42.696Z" }, + { url = "https://files.pythonhosted.org/packages/d8/2e/d69fd449414b5bdc551ede33e8ba41fd293458865bf9d4d6745fe8fe4e5a/cmake-4.2.3-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:e3dfbaeffac5848dce60b62a93eecd96b7a3eb0af6d874efc4ec0edb72ec7a24", size = 26203962, upload-time = "2026-02-28T17:48:45.897Z" }, + { url = "https://files.pythonhosted.org/packages/1b/cd/6b703e911069bc9d099097bf9d1cf5f61b627913c1dace890718484218c9/cmake-4.2.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3a21c36a64f52737e37dbeda0ce76391156139d546d995ed0992c3d4bc306636", size = 37881542, upload-time = "2026-02-28T17:48:48.843Z" }, + { url = "https://files.pythonhosted.org/packages/6b/15/4949cb479231bd6dcf204ffff4b5775c2a471754e73b8f9365ba17a6aa49/cmake-4.2.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:66dff80bc6c955592861f662abebc50ddc4d097bfd1630d496559f7e7017e769", size = 34523393, upload-time = "2026-02-28T17:48:51.55Z" }, + { url = "https://files.pythonhosted.org/packages/c2/39/9c5071dfe0774ad442dab753716e472b537da0bf3fefbc61362ab60b7e5e/cmake-4.2.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2605260fa17826c138ad3d78cdc3c6250b860f6c957653e35208c11e2ca4ad91", size = 40419861, upload-time = "2026-02-28T17:48:54.946Z" }, + { url = "https://files.pythonhosted.org/packages/cf/bd/44655063228db7d8f69f8ce3f84d44b854ab2a9bdc530fd9280e64377811/cmake-4.2.3-py3-none-musllinux_1_2_ppc64le.whl", hash = "sha256:f3693c97daaeedc931c6c2ef67b7213e60ef8e51c11050b6a7f4628f5f2a7883", size = 39615316, upload-time = "2026-02-28T17:48:58.308Z" }, + { url = "https://files.pythonhosted.org/packages/28/e4/f4ae13e3162151cdf978d9b279b6f21dd4b358bcc938607f7bddfd1f1da3/cmake-4.2.3-py3-none-musllinux_1_2_riscv64.whl", hash = "sha256:849ce056d644e1c84ba835976e8adc9777ccd2078d81ca80c20a933e4711b3f7", size = 34768312, upload-time = "2026-02-28T17:49:01.787Z" }, + { url = "https://files.pythonhosted.org/packages/28/5e/32ffc26ca34400de8c7fa5b03f3c132636268cb83f79b6a2f8c7dd8dc923/cmake-4.2.3-py3-none-musllinux_1_2_s390x.whl", hash = "sha256:1432016bf6cb533ff8833e0a434c640aa097ffd1a5c0e9341554c2c146050363", size = 36812265, upload-time = "2026-02-28T17:49:04.873Z" }, + { url = "https://files.pythonhosted.org/packages/fc/71/8324902abe3e883bc1d9adfb3c3e602e87f485b797defc87d0fe15fbb109/cmake-4.2.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:22c85da6d4aacebb3ed649bb7dc2fc034c6744f25ed8a02537408fe3c914bf9e", size = 37795828, upload-time = "2026-02-28T17:49:08.142Z" }, + { url = "https://files.pythonhosted.org/packages/cc/df/1b7d450ea66ba054c653165beab71414ccc1c1ea056e51574ae75206ea91/cmake-4.2.3-py3-none-win32.whl", hash = "sha256:2091e4c1b45e6e900dda4aebce1d3e912ddc3ba0c153dd6b35be0b18f7f2b2ce", size = 35499316, upload-time = "2026-02-28T17:49:10.957Z" }, + { url = "https://files.pythonhosted.org/packages/7f/d9/f1693ab5e403ae010df8c7ec12c77b2671080ec5c158b37f8db78814be96/cmake-4.2.3-py3-none-win_amd64.whl", hash = "sha256:0c55af0e1b2db232a94a7c34e89f25f3dbf410a4669b11134d07de0bd7aad03e", size = 38891890, upload-time = "2026-02-28T17:49:13.757Z" }, + { url = "https://files.pythonhosted.org/packages/9b/4b/6b246acb4be50867dc9237d55a0bc1ec0c8fbd47db2c868f1f2b4b690e76/cmake-4.2.3-py3-none-win_arm64.whl", hash = "sha256:e9d3761edc558b89321283c258f3bc036d2cda4c22ecfa181a25bb84e96afd4a", size = 38005743, upload-time = "2026-02-28T17:49:16.563Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -930,16 +972,16 @@ wheels = [ [[package]] name = "ddgs" -version = "9.11.2" +version = "9.11.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "lxml" }, { name = "primp" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/80/eb387dd4291d1624e773f455fd1dfc54596e06469d680fe3b3f8c326ba1a/ddgs-9.11.2.tar.gz", hash = "sha256:b5f072149580773291fd3eb6e9f4de47fa9d910ebd5ef85845a37e59cfe24c40", size = 34722, upload-time = "2026-03-05T05:17:31.574Z" } +sdist = { url = "https://files.pythonhosted.org/packages/06/9e/d89f0c24d78812bad0b4150d9a432925aa756b4bfeb4ef4815fe6ff8f2a6/ddgs-9.11.3.tar.gz", hash = "sha256:6098c030d6806217260071d85e38d9b94b99fe326a3c40ebf5de25f620528ae2", size = 34776, upload-time = "2026-03-11T07:12:02.041Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/fe/7591bfa694ee26fcf0dd8035811994e28a9699402d3861eea7754958c1bd/ddgs-9.11.2-py3-none-any.whl", hash = "sha256:0023a3633d271e72cdd1da757d3fcea2d996608da3f3c9da2cc0c0607b219c76", size = 43646, upload-time = "2026-03-05T05:17:30.469Z" }, + { url = "https://files.pythonhosted.org/packages/0b/9d/018d745128a9a33aff3e6b8f0260f7b970784d4b31573d36ee233b2e4db1/ddgs-9.11.3-py3-none-any.whl", hash = "sha256:596d656d00219b4748d839de1fa9a9c3eb5dd36db07365331f7526201115f18a", size = 43691, upload-time = "2026-03-11T07:12:00.21Z" }, ] [[package]] @@ -3023,6 +3065,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/be/9c/92789c596b8df838baa98fa71844d84283302f7604ed565dafe5a6b5041a/oauthlib-3.3.1-py3-none-any.whl", hash = "sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1", size = 160065, upload-time = "2025-06-19T22:48:06.508Z" }, ] +[[package]] +name = "olefile" +version = "0.47" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/1b/077b508e3e500e1629d366249c3ccb32f95e50258b231705c09e3c7a4366/olefile-0.47.zip", hash = "sha256:599383381a0bf3dfbd932ca0ca6515acd174ed48870cbf7fee123d698c192c1c", size = 112240, upload-time = "2023-12-01T16:22:53.025Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/d3/b64c356a907242d719fc668b71befd73324e47ab46c8ebbbede252c154b2/olefile-0.47-py2.py3-none-any.whl", hash = "sha256:543c7da2a7adadf21214938bb79c83ea12b473a4b6ee4ad4bf854e7715e13d1f", size = 114565, upload-time = "2023-12-01T16:22:51.518Z" }, +] + [[package]] name = "openai" version = "2.26.0" @@ -3201,6 +3252,7 @@ dependencies = [ { name = "litellm" }, { name = "loguru" }, { name = "markdownify" }, + { name = "olefile" }, { name = "openai" }, { name = "openpyxl" }, { name = "pdfminer-six" }, @@ -3229,6 +3281,7 @@ dependencies = [ { name = "uvicorn" }, { name = "volcengine" }, { name = "volcengine-python-sdk", extra = ["ark"] }, + { name = "xlrd" }, { name = "xxhash" }, ] @@ -3313,6 +3366,14 @@ bot-slack = [ bot-telegram = [ { name = "python-telegram-bot", extra = ["socks"] }, ] +build = [ + { name = "build" }, + { name = "cmake" }, + { name = "pybind11" }, + { name = "setuptools" }, + { name = "setuptools-scm" }, + { name = "wheel" }, +] dev = [ { name = "mypy" }, { name = "ruff" }, @@ -3342,12 +3403,19 @@ test = [ { name = "ragas" }, ] +[package.dev-dependencies] +dev = [ + { name = "pytest" }, +] + [package.metadata] requires-dist = [ { name = "agent-sandbox", marker = "extra == 'bot-sandbox'", specifier = ">=0.0.23" }, { name = "apscheduler", specifier = ">=3.11.0" }, { name = "beautifulsoup4", marker = "extra == 'bot'", specifier = ">=4.12.0" }, { name = "boto3", marker = "extra == 'test'", specifier = ">=1.42.44" }, + { name = "build", marker = "extra == 'build'" }, + { name = "cmake", marker = "extra == 'build'", specifier = ">=3.15" }, { name = "croniter", marker = "extra == 'bot'", specifier = ">=2.0.0" }, { name = "datasets", marker = "extra == 'eval'", specifier = ">=2.0.0" }, { name = "datasets", marker = "extra == 'test'", specifier = ">=2.0.0" }, @@ -3370,6 +3438,7 @@ requires-dist = [ { name = "msgpack", marker = "extra == 'bot'", specifier = ">=1.0.8" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.0.0" }, { name = "myst-parser", marker = "extra == 'doc'", specifier = ">=2.0.0" }, + { name = "olefile", specifier = ">=0.47" }, { name = "openai", specifier = ">=1.0.0" }, { name = "opencode-ai", marker = "extra == 'bot-opencode'", specifier = ">=0.1.0a0" }, { name = "openpyxl", specifier = ">=3.0.0" }, @@ -3383,6 +3452,7 @@ requires-dist = [ { name = "prompt-toolkit", marker = "extra == 'bot'", specifier = ">=3.0.0" }, { name = "protobuf", specifier = ">=6.33.5" }, { name = "py-machineid", marker = "extra == 'bot'", specifier = ">=1.0.0" }, + { name = "pybind11", marker = "extra == 'build'", specifier = ">=2.13.0" }, { name = "pydantic", specifier = ">=2.0.0" }, { name = "pydantic-settings", marker = "extra == 'bot'", specifier = ">=2.0.0" }, { name = "pygments", marker = "extra == 'bot'", specifier = ">=2.16.0" }, @@ -3404,6 +3474,8 @@ requires-dist = [ { name = "requests", specifier = ">=2.31.0" }, { name = "rich", marker = "extra == 'bot'", specifier = ">=13.0.0" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.1.0" }, + { name = "setuptools", marker = "extra == 'build'", specifier = ">=61.0" }, + { name = "setuptools-scm", marker = "extra == 'build'", specifier = ">=8.0" }, { name = "slack-sdk", marker = "extra == 'bot-slack'", specifier = ">=3.26.0" }, { name = "socksio", marker = "extra == 'bot'", specifier = ">=1.0.0" }, { name = "sphinx", marker = "extra == 'doc'", specifier = ">=7.0.0" }, @@ -3426,9 +3498,14 @@ requires-dist = [ { name = "volcengine-python-sdk", extras = ["ark"], specifier = ">=5.0.3" }, { name = "websocket-client", marker = "extra == 'bot'", specifier = ">=1.6.0" }, { name = "websockets", marker = "extra == 'bot'", specifier = ">=12.0" }, + { name = "wheel", marker = "extra == 'build'" }, + { name = "xlrd", specifier = ">=2.0.1" }, { name = "xxhash", specifier = ">=3.0.0" }, ] -provides-extras = ["test", "dev", "doc", "eval", "bot", "bot-langfuse", "bot-telegram", "bot-feishu", "bot-dingtalk", "bot-slack", "bot-qq", "bot-sandbox", "bot-fuse", "bot-opencode", "bot-full"] +provides-extras = ["test", "dev", "doc", "eval", "build", "bot", "bot-langfuse", "bot-telegram", "bot-feishu", "bot-dingtalk", "bot-slack", "bot-qq", "bot-sandbox", "bot-fuse", "bot-opencode", "bot-full"] + +[package.metadata.requires-dev] +dev = [{ name = "pytest", specifier = ">=9.0.2" }] [[package]] name = "orjson" @@ -3859,40 +3936,40 @@ wheels = [ [[package]] name = "primp" -version = "1.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/03/35/80be154508529f753fb82cb81298bdeb33e90f39f9901d7cfa0f488a581f/primp-1.1.2.tar.gz", hash = "sha256:c4707ab374a77c0cbead3d9a65605919fa4997fa910ef06e37b65df42a1d4d04", size = 313908, upload-time = "2026-03-01T05:52:49.773Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/13/dc9588356d983f988877ae065c842cdd6cf95073615b56b460cbe857f3dc/primp-1.1.2-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:181bb9a6d5544e0483592f693f33f5874a60726ea0da1f41685aa2267f084a4d", size = 4002669, upload-time = "2026-03-01T05:52:31.977Z" }, - { url = "https://files.pythonhosted.org/packages/70/af/6a6c26141583a5081bad69b9753c85df81b466939663742ef5bec35ee868/primp-1.1.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:f362424ffa83e1de55a7573300a416fa71dc5516829526a9bf77dc0cfa42256b", size = 3743010, upload-time = "2026-03-01T05:52:38.452Z" }, - { url = "https://files.pythonhosted.org/packages/a9/99/03db937e031a02885d8c80d073d7424967d629721b5044dcb4e80b6cbdcf/primp-1.1.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:736820326eb1ed19c6b0e971f852316c049c36bdd251a03757056a74182796df", size = 3889905, upload-time = "2026-03-01T05:52:20.616Z" }, - { url = "https://files.pythonhosted.org/packages/15/3c/faecef36238f464e2dd52056420676eb2d541cd20ff478d3b967815079e3/primp-1.1.2-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed37d1bc89fa8cad8b60481c81ea7b3bd42dc757868009ad3bb0b1e74c17fd22", size = 3524521, upload-time = "2026-03-01T05:52:08.403Z" }, - { url = "https://files.pythonhosted.org/packages/7f/d5/8954e5b5b454139ff35063d5a143a1570f865b736cfd8a46cc7ce9575a5a/primp-1.1.2-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e78355b1c495bc7e3d92121067760c7e7a1d419519542ed9dd88688ce43aab", size = 3738228, upload-time = "2026-03-01T05:52:05.127Z" }, - { url = "https://files.pythonhosted.org/packages/26/e7/dc93dbeddb7642e12f4575aaf2c9fda7234b241050a112a9baa288971b16/primp-1.1.2-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c4c560d018dad4e3a3f17b07f9f5d894941e3acbbb5b566f6b6baf42786012f", size = 4013704, upload-time = "2026-03-01T05:52:48.529Z" }, - { url = "https://files.pythonhosted.org/packages/dd/3d/2cc2e0cd310f585df05a7008fd6de4542d7c0bc61e62b6797f28a9ede28b/primp-1.1.2-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2494b52cf3056d3e41c0746a11cbeca7f2f882a92a09d87383646cd75e2f3d8c", size = 3920174, upload-time = "2026-03-01T05:52:06.635Z" }, - { url = "https://files.pythonhosted.org/packages/35/60/dc4572ba96911374b43b4f5d1f012706c3f27fd2c12dd3e158fcf74ac3dd/primp-1.1.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c424a46f48ccd8fd309215a15bc098b47198b8f779c43ed8d95b3f53a382ffa8", size = 4113822, upload-time = "2026-03-01T05:52:51.061Z" }, - { url = "https://files.pythonhosted.org/packages/ec/2e/90f5f8e138f8bc6652c5134aa59a746775623a820f92164c6690217e49d6/primp-1.1.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ba51cf19f17fd4bab4567d96b4cd7dcb6a4e0f0d4721819180b46af9794ae310", size = 4068028, upload-time = "2026-03-01T05:52:13.843Z" }, - { url = "https://files.pythonhosted.org/packages/d4/ea/753d8edcb85c3c36d5731fbd2b215528738d917ae9cf3dce651ae0f1c529/primp-1.1.2-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:77ebae43c6735328051beb08e7e2360b6cf79d50f6cef77629beba880c99222d", size = 3754469, upload-time = "2026-03-01T05:52:15.671Z" }, - { url = "https://files.pythonhosted.org/packages/ae/51/b417cd741bf8eacea86debad358a6dc5821e2849a22e2c91cff926bebbb2/primp-1.1.2-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:5f3252d47e9d0f4a567990c79cd388be43353fc7c78efea2a6a5734e8a425598", size = 3859330, upload-time = "2026-03-01T05:52:46.979Z" }, - { url = "https://files.pythonhosted.org/packages/3e/20/19db933c878748e9a7b9ad4057e9caf7ad9c91fd27d2a2692ac629453a66/primp-1.1.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9e094417825df9748e179a1104b2df4459c3dbd1eea994f05a136860b847f0e1", size = 4365491, upload-time = "2026-03-01T05:52:35.007Z" }, - { url = "https://files.pythonhosted.org/packages/fc/0f/48a57ee744cc6dc64fb7daff7bc04e9ec3cefd0594d008a775496dddaeb1/primp-1.1.2-cp310-abi3-win32.whl", hash = "sha256:bc67112b61a8dc1d40ddcc81ff5c47a1cb7b620954fee01a529e28bebb359e20", size = 3266998, upload-time = "2026-03-01T05:52:02.059Z" }, - { url = "https://files.pythonhosted.org/packages/9c/0a/119d497fb098c739142d4a47b062a8a9cc0b4b87aca65334150066d075a0/primp-1.1.2-cp310-abi3-win_amd64.whl", hash = "sha256:4509850301c669c04e124762e953946ed10fe9039f059ec40b818c085697d9a4", size = 3601691, upload-time = "2026-03-01T05:52:12.34Z" }, - { url = "https://files.pythonhosted.org/packages/95/1f/2b8f218aebb4f236d94ae148b4f5c0471b3d00316b0ef5d0b7c2222d8417/primp-1.1.2-cp310-abi3-win_arm64.whl", hash = "sha256:de5958dc7ce78ce107dd776056a58f9da7a7164a912e908cb9b66b84f87967f6", size = 3613756, upload-time = "2026-03-01T05:52:28.279Z" }, - { url = "https://files.pythonhosted.org/packages/40/38/f77c5af1fd53658e04ae52decfab71349af43bdfdb32ddd8a622f6251842/primp-1.1.2-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:c3bbece26e8312e3e0df2ec222b954f9ac9f279422ffbbf47a6cad31ef8736cd", size = 3992311, upload-time = "2026-03-01T05:52:43.497Z" }, - { url = "https://files.pythonhosted.org/packages/77/f6/2e4504cfdeec5d39063173205ca10a281a2681fd9999da37b442ac7e6662/primp-1.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:78acdf43b57d984170e986be5fcae0a1537a245fafda970e92056dae42cd9545", size = 3736438, upload-time = "2026-03-01T05:52:22.505Z" }, - { url = "https://files.pythonhosted.org/packages/d3/6c/fe10c51b79cd407d3a1e08a0bb8a35ae53d79ce4156543ea4df7262581ef/primp-1.1.2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89a2641441732f81e1876db2e18490d3210a8302290e4844b7f04159e02033d4", size = 3878622, upload-time = "2026-03-01T05:52:33.458Z" }, - { url = "https://files.pythonhosted.org/packages/fb/86/5c68dc877af9baf4fba3e5d2615fe0aefbdd4e1337d3b678b66769b434c9/primp-1.1.2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1df66deacb539efbca5730d0fc3dea19cd83c33422fa05445bbddc17aef3f71", size = 3520112, upload-time = "2026-03-01T05:52:45.214Z" }, - { url = "https://files.pythonhosted.org/packages/fd/aa/f8798a1c0fabbc9254e29330df61b93bdb54130e9d5e5d8495eff99fc658/primp-1.1.2-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78ea1f56dd3ac52f2d5375a084c7f31ce6ad274811bdb5d17ecaca6b4ddb8b6d", size = 3740187, upload-time = "2026-03-01T05:52:26.052Z" }, - { url = "https://files.pythonhosted.org/packages/90/e4/ea08359b6fbcda7b3ffcc15b4c1e0bf4f89680db126ba96889e7f8e1fe04/primp-1.1.2-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c980527bd46c034ab9e06dca75b6237cea8d5b3fe1f5691904a2c35d92d143c", size = 4011825, upload-time = "2026-03-01T05:52:17.403Z" }, - { url = "https://files.pythonhosted.org/packages/01/4a/8cf516250cc97eab2d4c822478ab0037b9848bca844787196481b5691f25/primp-1.1.2-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c0b4006a9a25c5f89a968f3bf67221fc19183890b8a1304873132d703697816", size = 3907535, upload-time = "2026-03-01T05:52:24.455Z" }, - { url = "https://files.pythonhosted.org/packages/90/00/e6fe4abf75012d05009abf22e9e1eb89b4bca06ad9f79c10876cebdf7271/primp-1.1.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2851bedc1598ed72f6a2016e391012744259c523dc5d27f2f02e3ae5ef020d4", size = 4108136, upload-time = "2026-03-01T05:52:42.007Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8a/64cd76fee8b994f349c1a9c6541b4144dee64056dcaa8109bd352518b777/primp-1.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f7340e34023dda2660bd02cb92ac8ed441f13a1afdc00487581d8b8b473f890b", size = 4060289, upload-time = "2026-03-01T05:52:40.4Z" }, - { url = "https://files.pythonhosted.org/packages/dd/7c/fbea74676def2ce1d21a53e86cdbb3ef9c7a12b2febfdd3961a8466449a7/primp-1.1.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:618a027bb45ac44e9b6c35d5758547ce5e73607de4fb54b52bb9d0dc896f11fa", size = 3749499, upload-time = "2026-03-01T05:51:59.988Z" }, - { url = "https://files.pythonhosted.org/packages/12/7a/36fc46a385141063e2ae4fd24dda308e75da8c6409c425a56ffceb6e4f71/primp-1.1.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:37e30ce1435142dd010f2ee1dd909f1e6e3a8cd3e32c8e22f3bb6703bf618209", size = 3858861, upload-time = "2026-03-01T05:52:10.621Z" }, - { url = "https://files.pythonhosted.org/packages/65/bb/d0319dbd2e20fb4f54d8b3f536b89431a9d1442f00fa11a874dfbe9d2de7/primp-1.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9b5d335d28eae65543b20c75911d71c5f89882a4598efade47abe92389f6da7f", size = 4358677, upload-time = "2026-03-01T05:52:18.978Z" }, - { url = "https://files.pythonhosted.org/packages/57/89/ab887a516dc83dbae12ea5b338f60c46a56966a972fed65f8de5bf05a9c2/primp-1.1.2-cp314-cp314t-win32.whl", hash = "sha256:b938cc2d033ac56be90c617836a60fb468f33ab630d3eacab2b36651b7ce106e", size = 3258062, upload-time = "2026-03-01T05:52:36.741Z" }, - { url = "https://files.pythonhosted.org/packages/df/ca/e870d65162f6c68da6d25afa3e01202ac500c8ad1b682dfd03e8c45e4d4a/primp-1.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:6378d55bbe8b722e7b39b6c0df1e46a1b767d2e4e8a7c1e60d9f8ec238bf48c4", size = 3599631, upload-time = "2026-03-01T05:52:03.595Z" }, - { url = "https://files.pythonhosted.org/packages/4e/cb/61667c710293d8007416130c9ad69f60a956393b52e82557c84ae8286aa7/primp-1.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:2431104658b86e7cf9bedbadabe6d2c4705c1c10b54f17ad0094cc927577adea", size = 3610624, upload-time = "2026-03-01T05:52:30.19Z" }, +version = "1.1.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/0e/62ed44af95c66fd6fa8ad49c8bde815f64c7e976772d6979730be2b7cd97/primp-1.1.3.tar.gz", hash = "sha256:56adc3b8a5048cbd5f926b21fdff839195f3a9181512ca33f56ddc66f4c95897", size = 311356, upload-time = "2026-03-11T06:42:51.763Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/6b/36794b5758a0dd1251e67b6ab3ea946e53fa69745e0ecc29facc072ddf5b/primp-1.1.3-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:24383cfc267f620769be102b7fa4b64c7d47105f86bd21d047f1e07709e83c6e", size = 4000660, upload-time = "2026-03-11T06:42:58.092Z" }, + { url = "https://files.pythonhosted.org/packages/98/18/ebbe318a926d158c57f9e9cf49bbea70e8f0bd7f87e7675ed68e0d6ab433/primp-1.1.3-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:61bcb8c53b41e4bac43d04a1374b6ab7d8ded0f3517d32c5cdd5c30562756805", size = 3737318, upload-time = "2026-03-11T06:42:50.19Z" }, + { url = "https://files.pythonhosted.org/packages/a9/4c/430c9154284b53b771e6713a18dec4ad0159e4a501a20b222d67c730ced9/primp-1.1.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0c6b9388578ee9d903f30549a792c5f391fdeb9d36b508da2ffb8e13c764954", size = 3881005, upload-time = "2026-03-11T06:43:12.894Z" }, + { url = "https://files.pythonhosted.org/packages/93/34/2466ef66386a1b50e6aaf7832f9f603628407bb33342378faf4b38c4aee8/primp-1.1.3-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:09a8bfa870c92c81d76611846ec53b2520845e3ec5f4139f47604986bcf4bc25", size = 3514480, upload-time = "2026-03-11T06:43:06.058Z" }, + { url = "https://files.pythonhosted.org/packages/ff/42/ca7a71df6493dd6c1971c0cc3b20b8125e2547eb3bf88b4429715cb6ed81/primp-1.1.3-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac372cb9959fff690b255fad91c5b3bc948c14065da9fc00ad80d139651515af", size = 3734658, upload-time = "2026-03-11T06:43:47.486Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7c/0fb34db619e9935e11140929713c2c7b5323c1e8ba75cad6f0aade51c89d/primp-1.1.3-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3034672a007f04e12b8fe7814c97ea172e8b9c5d45bd7b00cf6e7334fdd4222a", size = 4011898, upload-time = "2026-03-11T06:43:41.121Z" }, + { url = "https://files.pythonhosted.org/packages/da/8b/afd1bd8b14f38d58c5ebd0d45fc6b74914956907aa4e981bb2e5231626d3/primp-1.1.3-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a07d5b7d7278dc63452a59f3bf851dc4d1f8ddc2aada7844cbdb68002256e2f4", size = 3910728, upload-time = "2026-03-11T06:43:01.819Z" }, + { url = "https://files.pythonhosted.org/packages/32/9e/1ec3a9678efcbb51e50d7b4886d9195f956c9fd7f4efcff13ccb152248b0/primp-1.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08eec2f58abbcc1060032a2af81dabacec87a580a364a75862039f7422ac82e6", size = 4114189, upload-time = "2026-03-11T06:42:47.639Z" }, + { url = "https://files.pythonhosted.org/packages/28/d9/76de611027c0688be188d5a833be45b1e36d9c0c98baefab27bf6336ab9d/primp-1.1.3-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9716d4cd36db2c175443fe1bbd54045a944fc9c49d01a385af8ada1fe9c948df", size = 4061973, upload-time = "2026-03-11T06:43:37.301Z" }, + { url = "https://files.pythonhosted.org/packages/37/3b/a30a5ea366705d0ece265b12ad089793d644bd5730b18201e3a0a7fa7b5f/primp-1.1.3-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:e19daca65dc6df369c33e711fa481ad2afe5d26c5bde926c069b3ab067c4fd45", size = 3747920, upload-time = "2026-03-11T06:43:10.403Z" }, + { url = "https://files.pythonhosted.org/packages/df/46/e3c323221c371cdfe6c2ed971f7a70e3b69f30b561977715c55230bd5fda/primp-1.1.3-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:ee357537712aa486364b0194cf403c5f9eaaa1354e23e9ac8322a22003f31e6b", size = 3861184, upload-time = "2026-03-11T06:43:49.391Z" }, + { url = "https://files.pythonhosted.org/packages/8a/7f/babaf00753daad7d80061003d7ae1bdfca64ea94c181cdea8d25c8a7226a/primp-1.1.3-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:06c53e77ebf6ac00633bc09e7e5a6d1a994592729d399ca8f065451a2574b92e", size = 4364610, upload-time = "2026-03-11T06:42:56.223Z" }, + { url = "https://files.pythonhosted.org/packages/03/48/c7bca8045c681f5f60972c180d2a20582c7a0857b3b07b12e0a0ee062ac4/primp-1.1.3-cp310-abi3-win32.whl", hash = "sha256:4b1ea3693c118bf04a6e05286f0a73637cf6fe5c9fd77fa1e29a01f190adf512", size = 3265160, upload-time = "2026-03-11T06:43:43.774Z" }, + { url = "https://files.pythonhosted.org/packages/45/3e/4a4b8a0f6f15734cded91e85439e68912b2bb8eafe7132420c13c2db8340/primp-1.1.3-cp310-abi3-win_amd64.whl", hash = "sha256:5ea386a4c8c4d8c1021d17182f4ee24dbb6f17c107c4e9ee5500b6372cf08f32", size = 3603953, upload-time = "2026-03-11T06:43:33.144Z" }, + { url = "https://files.pythonhosted.org/packages/70/46/1baf13a7f5fbed6052deb3e4822c69441a8d0fd990fe2a50e4cec802130b/primp-1.1.3-cp310-abi3-win_arm64.whl", hash = "sha256:63c7b1a1ccbcd07213f438375df186f807cdc5214bc2debb055737db9b5078de", size = 3619917, upload-time = "2026-03-11T06:42:44.76Z" }, + { url = "https://files.pythonhosted.org/packages/be/0c/a73cbe13f075e7ceaa5172b44ebc6f423713c6b4efe168114993a1710b26/primp-1.1.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:4b3d52f3233134584ef527e7e52f1b371a964ade1df0461f8187100e41d7fa84", size = 3987141, upload-time = "2026-03-11T06:43:24.904Z" }, + { url = "https://files.pythonhosted.org/packages/49/56/b70d7991fb1e07af53706b1f69f78a0b440a7b4b2a2999c44ab44afef1e7/primp-1.1.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b3d947e2c1d15147e8f4736d027b9f3bef518d67da859ead1c54e028ff491bbb", size = 3735665, upload-time = "2026-03-11T06:43:29.347Z" }, + { url = "https://files.pythonhosted.org/packages/31/82/69efc663341c2bab55659ed221903a090e5c80255c2de2acc70f3726a3fc/primp-1.1.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ed2fee7d4758f6bb873b19a6759f54e0bc453213dad5ba7e52de7582921079", size = 3873695, upload-time = "2026-03-11T06:43:15.396Z" }, + { url = "https://files.pythonhosted.org/packages/07/7e/6b360742019ef8fb4ea036a420eb21b0a58d380ca09c68b075fc103cc043/primp-1.1.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5aa717f256af9e4391fb1c4dc946d99d04652b4c57dad20c3947e839ab26769", size = 3512644, upload-time = "2026-03-11T06:43:08.368Z" }, + { url = "https://files.pythonhosted.org/packages/03/46/51d2ada6d5b53b8496eddf2c80392deab13698987412d0234f88e72390c1/primp-1.1.3-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17f37fcacd97540f68b06f2b468b111ca7f2b142c48370db7344b522274fc0d6", size = 3733114, upload-time = "2026-03-11T06:43:22.838Z" }, + { url = "https://files.pythonhosted.org/packages/45/f5/5f5f5f4bef7e247ec3543e2fbdb670d8db8753a7693baf9c8b9fcf52cd43/primp-1.1.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5f010d0b8ba111dd9a66f814c2cd56332e047c98f45d7714ffbf2b1cec5b073", size = 4005664, upload-time = "2026-03-11T06:43:20.824Z" }, + { url = "https://files.pythonhosted.org/packages/f2/bf/99cf4a5f179b3f13b0c2ba4d3ae8f8af19f0084308e76cb79a0cee03c31b/primp-1.1.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e1e431915e4a7094d589213fc14e955243d93751031d889f4b359fa8ed54298", size = 3895746, upload-time = "2026-03-11T06:43:35.376Z" }, + { url = "https://files.pythonhosted.org/packages/c3/75/4c625e1cab37585365b0856ca44f31ad598e92a847d23561f454b7f36fca/primp-1.1.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaffa22dae2f193d899d9f68cca109ea5d16cdf4c901c20cec186de89e7d5db4", size = 4109815, upload-time = "2026-03-11T06:43:04.059Z" }, + { url = "https://files.pythonhosted.org/packages/49/72/6197ea78779d359f307be1acc64659896fc960ed91c0bdc6e6e698e423e6/primp-1.1.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f93bee50990884621ef482e8434e87f9fbb4eca6f4d47973c44c5d6393c35679", size = 4050839, upload-time = "2026-03-11T06:43:18.296Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b2/cdd565b28bcf7ce555f4decdf89dafd16db8ed3ba8661890d3b9337abe45/primp-1.1.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:399dfb9ad01c3612c9e510a7034ac925af5524cade0961d8a019dedd90a46474", size = 3748397, upload-time = "2026-03-11T06:43:27.347Z" }, + { url = "https://files.pythonhosted.org/packages/62/6e/def3a90821b52589dbe1f57477c2c89bde7a5b26a7c166d7751930c06f98/primp-1.1.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:78ce595bbb9f339e83975efa9db2a81128842fad1a2fdafb78d72fcdc59590fc", size = 3861261, upload-time = "2026-03-11T06:43:39.292Z" }, + { url = "https://files.pythonhosted.org/packages/10/7d/3e610614d6a426502cfc6eccea21ef4557b39177d365df393c994945ca43/primp-1.1.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7d709bdf520aa9401c0592b642730b3477c828629f01d2550977b77135b34e8d", size = 4358608, upload-time = "2026-03-11T06:43:45.606Z" }, + { url = "https://files.pythonhosted.org/packages/91/50/eb190cefe5eb05896825a5b3365d5650b9327161329cd1df4f7351b66ba9/primp-1.1.3-cp314-cp314t-win32.whl", hash = "sha256:6fe893eb87156dfb146dd666c7c8754670de82e38af0a27d82a47b7461ec2eea", size = 3259903, upload-time = "2026-03-11T06:42:59.922Z" }, + { url = "https://files.pythonhosted.org/packages/1f/a8/9e8534bc6d729a667f79b249fcdbf2230b0eb41214e277998cd6be900498/primp-1.1.3-cp314-cp314t-win_amd64.whl", hash = "sha256:ced76ef6669f31dc4af25e81e87914310645bcfc0892036bde084dafd6d00c3c", size = 3602569, upload-time = "2026-03-11T06:42:53.955Z" }, + { url = "https://files.pythonhosted.org/packages/9c/92/e18be996a01c7fd0e7dd7d198edefe42813cdfe1637bbbc80370ce656f62/primp-1.1.3-cp314-cp314t-win_arm64.whl", hash = "sha256:efadef0dfd10e733a254a949abf9ed05c668c28a68aa6513d811c0c6acd54cdb", size = 3611571, upload-time = "2026-03-11T06:43:31.249Z" }, ] [[package]] @@ -4114,6 +4191,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/50/f2/c0e76a0b451ffdf0cf788932e182758eb7558953f4f27f1aff8e2518b653/pyarrow-23.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:527e8d899f14bd15b740cd5a54ad56b7f98044955373a17179d5956ddb93d9ce", size = 28365807, upload-time = "2026-02-16T10:14:03.892Z" }, ] +[[package]] +name = "pybind11" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/98/9118a0659646f1628c592ef9bb48e0056efa6bf27c951fd12a178e0136fb/pybind11-3.0.2.tar.gz", hash = "sha256:432f01aeb68e361a3a7fc7575c2c7f497595bf640f747acd909ff238dd766e06", size = 577131, upload-time = "2026-02-17T04:46:52.556Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/c5/e98d9c51f3d5300d5e40ad9037dd6b3b60736fd02ab68dcc98c96be7592d/pybind11-3.0.2-py3-none-any.whl", hash = "sha256:f8a6500548919cc33bcd220d5f984688326f574fa97f1107f2f4fdb4c6fb019f", size = 310158, upload-time = "2026-02-17T04:46:49.91Z" }, +] + [[package]] name = "pycparser" version = "3.0" @@ -4352,6 +4438,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/80/0d9b162098597fbe3ac2b269b1682c0c3e8db9ba87679603fdd9b19afaa6/pypdfium2-5.6.0-py3-none-win_arm64.whl", hash = "sha256:5538417b199bdcb3207370c88df61f2ba3dac7a3253f82e1aa2708e6376b6f90", size = 3515049, upload-time = "2026-03-08T01:05:04.587Z" }, ] +[[package]] +name = "pyproject-hooks" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/82/28175b2414effca1cdac8dc99f76d660e7a4fb0ceefa4b4ab8f5f6742925/pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", size = 19228, upload-time = "2024-09-29T09:24:13.293Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/24/12818598c362d7f300f18e74db45963dbcb85150324092410c8b49405e42/pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913", size = 10216, upload-time = "2024-09-29T09:24:11.978Z" }, +] + [[package]] name = "pytest" version = "9.0.2" @@ -5068,6 +5163,29 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/23/8146aad7d88f4fcb3a6218f41a60f6c2d4e3a72de72da1825dc7c8f7877c/semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177", size = 15552, upload-time = "2022-05-26T13:35:21.206Z" }, ] +[[package]] +name = "setuptools" +version = "82.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", hash = "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", size = 1152316, upload-time = "2026-03-09T12:47:17.221Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb", size = 1006223, upload-time = "2026-03-09T12:47:15.026Z" }, +] + +[[package]] +name = "setuptools-scm" +version = "9.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "setuptools" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7b/b1/19587742aad604f1988a8a362e660e8c3ac03adccdb71c96d86526e5eb62/setuptools_scm-9.2.2.tar.gz", hash = "sha256:1c674ab4665686a0887d7e24c03ab25f24201c213e82ea689d2f3e169ef7ef57", size = 203385, upload-time = "2025-10-19T22:08:05.608Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/ea/ac2bf868899d0d2e82ef72d350d97a846110c709bacf2d968431576ca915/setuptools_scm-9.2.2-py3-none-any.whl", hash = "sha256:30e8f84d2ab1ba7cb0e653429b179395d0c33775d54807fc5f1dd6671801aef7", size = 62975, upload-time = "2025-10-19T22:08:04.007Z" }, +] + [[package]] name = "shellingham" version = "1.5.4" @@ -6012,6 +6130,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" }, ] +[[package]] +name = "wheel" +version = "0.46.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/89/24/a2eb353a6edac9a0303977c4cb048134959dd2a51b48a269dfc9dde00c8a/wheel-0.46.3.tar.gz", hash = "sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803", size = 60605, upload-time = "2026-01-22T12:39:49.136Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/22/b76d483683216dde3d67cba61fb2444be8d5be289bf628c13fc0fd90e5f9/wheel-0.46.3-py3-none-any.whl", hash = "sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d", size = 30557, upload-time = "2026-01-22T12:39:48.099Z" }, +] + [[package]] name = "win32-setctime" version = "1.2.0" @@ -6111,6 +6241,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/f5/10b68b7b1544245097b2a1b8238f66f2fc6dcaeb24ba5d917f52bd2eed4f/wsproto-1.3.2-py3-none-any.whl", hash = "sha256:61eea322cdf56e8cc904bd3ad7573359a242ba65688716b0710a5eb12beab584", size = 24405, upload-time = "2025-11-20T18:18:00.454Z" }, ] +[[package]] +name = "xlrd" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/07/5a/377161c2d3538d1990d7af382c79f3b2372e880b65de21b01b1a2b78691e/xlrd-2.0.2.tar.gz", hash = "sha256:08b5e25de58f21ce71dc7db3b3b8106c1fa776f3024c54e45b45b374e89234c9", size = 100167, upload-time = "2025-06-14T08:46:39.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/62/c8d562e7766786ba6587d09c5a8ba9f718ed3fa8af7f4553e8f91c36f302/xlrd-2.0.2-py2.py3-none-any.whl", hash = "sha256:ea762c3d29f4cca48d82df517b6d89fbce4db3107f9d78713e48cd321d5c9aa9", size = 96555, upload-time = "2025-06-14T08:46:37.766Z" }, +] + [[package]] name = "xlsxwriter" version = "3.2.9"

G$yUik5Uj6zVIE; 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

n#f>axD=v)N?RQ9tjnJU8I)9vS2H2hXfkN^1f+ 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�v+bvSW&i}VpK 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%0A@R9K50*d8W1lDf?Za!iJNXEX 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

~R7 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

Sxau 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�I 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� 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