Skip to content

fix: defer provider binding during cold start#176

Merged
EterUltimate merged 3 commits into
mainfrom
codex/fix-provider-cold-start
Jun 7, 2026
Merged

fix: defer provider binding during cold start#176
EterUltimate merged 3 commits into
mainfrom
codex/fix-provider-cold-start

Conversation

@EterUltimate

@EterUltimate EterUltimate commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fixes [Bug] 没有找到Reranker 提供商 ID与Embedding 提供商 ID #171 by avoiding noisy provider ID lookups while AstrBot provider registries are still empty during cold start.
  • Adds provider registry inspection helpers for embedding/rerank factories and defers binding until registry lists are visible.
  • Retries V2 provider binding during start, warmup, first message processing, context retrieval, and delayed lifecycle provider refresh.
  • Bumps plugin version metadata and README badges to 3.1.6 for release.

Validation

  • python -m py_compile services\provider_registry.py services\embedding\factory.py services\reranker\factory.py services\core_learning\v2_learning_integration.py core\plugin_lifecycle.py tests\unit\test_provider_registry_rebind.py
  • git diff --check -- core/plugin_lifecycle.py services/core_learning/v2_learning_integration.py services/embedding/factory.py services/reranker/factory.py services/provider_registry.py tests/unit/test_provider_registry_rebind.py metadata.yaml __init__.py README.md README_EN.md
  • python -m pytest -q tests\unit\test_provider_registry_rebind.py tests\integration\test_package_imports.py tests\integration\test_config_blueprint.py (11 passed)

Pre-review

  • AstrBot pre-review script was run and still reports existing repository-wide logger/StarTools/requirements warnings unrelated to this provider cold-start fix.

Fixes #171

Summary by Sourcery

Defer binding of embedding and rerank providers until AstrBot provider registries are ready, and add retry-based rebinding across the v2 learning lifecycle.

Bug Fixes:

  • Avoid noisy 'provider not found' lookups during cold start by inspecting provider registries before resolving IDs.
  • Ensure v2 knowledge and memory managers wait for required embedding providers instead of failing permanently when registries are initially empty.

Enhancements:

  • Introduce provider registry inspection utilities shared by embedding and rerank factories to detect registry readiness and provider availability.
  • Add periodic, lock-guarded refresh of embedding/rerank bindings and dependent v2 modules during start, warmup, message processing, context retrieval, and delayed provider refresh.
  • Improve logging and retryability flags for LightRAG and Mem0 managers when dependencies are missing or optional integrations are not installed.

Build:

  • Bump plugin version fields in package metadata to 3.1.6.

Documentation:

  • Update README badges and plugin metadata to version 3.1.6 for release.

Tests:

  • Add unit regression tests covering provider factory behavior when registries are empty and v2 integration rebinding after registries become ready.

@sourcery-ai

sourcery-ai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Implements deferred and retriable provider binding for AstrBot v2 integration to avoid noisy lookup warnings during cold start, adds shared provider registry inspection utilities used by embedding/rerank factories, wires these retries into startup/warmup/runtime paths, and bumps plugin metadata to version 3.1.6.

Sequence diagram for deferred provider binding during cold start

sequenceDiagram
    actor AstrBotCore
    participant PluginLifecycle
    participant V2Integration
    participant EmbeddingFactory
    participant ProviderRegistry
    participant FrameworkContext

    AstrBotCore->>PluginLifecycle: _delayed_provider_reinitialization()
    PluginLifecycle->>V2Integration: refresh_provider_bindings(force=True)

    V2Integration->>EmbeddingFactory: create(config, context)
    EmbeddingFactory->>ProviderRegistry: normalize_provider_id(config.embedding_provider_id)
    EmbeddingFactory->>ProviderRegistry: collect_framework_providers(context, EmbeddingProvider)
    ProviderRegistry-->>EmbeddingFactory: providers, inspected=True, errors

    alt [providers empty]
        EmbeddingFactory->>ProviderRegistry: framework_registry_has_any_provider(context)
        ProviderRegistry-->>EmbeddingFactory: registry_has_any_provider=False
        EmbeddingFactory-->>V2Integration: None
        V2Integration-->>PluginLifecycle: refreshed=False
    else [provider visible]
        EmbeddingFactory->>ProviderRegistry: find_provider_by_id(providers, provider_id)
        ProviderRegistry-->>EmbeddingFactory: provider
        EmbeddingFactory->>EmbeddingFactory: _wrap_provider(provider_id, provider)
        EmbeddingFactory-->>V2Integration: embedding_provider
        V2Integration->>V2Integration: refresh_provider_bindings()
        V2Integration-->>PluginLifecycle: refreshed=True
    end
Loading

File-Level Changes

Change Details Files
Add deferred, retriable provider binding and module creation in V2LearningIntegration, invoked across lifecycle events.
  • Introduce provider retry state (_started flag, retry lock, timestamps, retryable flags) in V2LearningIntegration.init.
  • Add refresh_provider_bindings() to lazily (re)bind embedding/rerank providers, create knowledge/memory managers and refresh exemplar library with concurrency control and logging.
  • Refactor module startup into _start_one() and _active_modules(), and call refresh_provider_bindings() from start(), warmup(), process_message(), and get_enhanced_context().
  • Add helper predicates for embedding/rerank configuration, exemplar embedding refresh, and retry decisions; mark knowledge/memory managers as non-retryable on ImportError.
  • Improve knowledge/memory manager creation logging to distinguish between missing config, waiting for registry readiness, and hard fallback cases.
services/core_learning/v2_learning_integration.py
Use shared provider registry inspection helpers to avoid noisy ID lookups during cold start in embedding/rerank factories.
  • Normalize provider IDs via normalize_provider_id before use in embedding and rerank factories.
  • In EmbeddingProviderFactory._resolve_framework_provider(), inspect embedding provider registries via collect_framework_providers and find_provider_by_id; fall back to readiness checks via framework_registry_has_any_provider and adjust logging for empty or mismatched registries.
  • Factor provider wrapping/validation into EmbeddingProviderFactory._wrap_provider() and add _provider_ids() helper for diagnostics.
  • In RerankProviderFactory.create(), mirror the registry inspection and readiness logic used by the embedding factory, with a shared _wrap_provider() and _provider_ids() helpers for rerank providers.
services/embedding/factory.py
services/reranker/factory.py
Introduce reusable provider registry utilities to safely inspect framework provider lists and readiness.
  • Add normalize_provider_id() to standardize provider ID inputs.
  • Implement collect_framework_providers() to aggregate providers from context getter methods and provider_manager structures with error capture and deduping.
  • Provide framework_registry_has_any_provider() to detect whether any provider is visible across multiple registry entry points.
  • Add find_provider_by_id() and internal helpers (_safe_getattr, _extend_provider_list, _as_list, _dedupe_providers) to support robust inspection without triggering noisy errors or mock interactions.
services/provider_registry.py
Trigger v2 provider rebinding during delayed plugin provider reinitialization.
  • Extend _delayed_provider_reinitialization to call v2_integration.refresh_provider_bindings(force=True) when available.
  • Log a completion message when v2 provider delayed binding refresh succeeds.
core/plugin_lifecycle.py
Add regression tests for provider cold-start handling and plugin alias loading.
  • Create a test helper to load the plugin package under an alias and clean up sys.modules afterwards.
  • Add unit tests ensuring embedding and rerank factories do not call get_provider_by_id when framework registries are empty but configured IDs are present.
  • Add an async test verifying V2LearningIntegration.refresh_provider_bindings() successfully rebinds providers once registry lists become populated, without using ID-based lookups, using dummy embedding/rerank providers.
tests/unit/test_provider_registry_rebind.py
Bump plugin version and documentation badges for release 3.1.6.
  • Update version in init.py to 3.1.6.
  • Update metadata.yaml version field to 3.1.6.
  • Update README and README_EN version badges from 3.1.5 to 3.1.6.
__init__.py
metadata.yaml
README.md
README_EN.md

Assessment against linked issues

Issue Objective Addressed Explanation
#171 Defer resolution of embedding and rerank providers during AstrBot cold start so that when provider registries are still empty, the plugin does not emit noisy "Provider 'embedding' / 'rerank' not found" warnings for otherwise valid configurations.
#171 Automatically (re)bind embedding/rerank providers and dependent V2 modules (knowledge/memory managers, exemplar library) once the AstrBot provider registry becomes ready, without requiring a manual plugin reload.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In V2LearningIntegration.refresh_provider_bindings the time.monotonic()/interval guard is duplicated both before and inside the lock; consider extracting this into a small helper or performing the check only inside the lock to reduce repetition and potential drift.
  • The hard-coded _provider_retry_interval of 10 seconds in V2LearningIntegration may not suit all deployments; consider making this configurable via the existing config object or constructor parameter so operators can tune retry aggressiveness.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `V2LearningIntegration.refresh_provider_bindings` the `time.monotonic()`/interval guard is duplicated both before and inside the lock; consider extracting this into a small helper or performing the check only inside the lock to reduce repetition and potential drift.
- The hard-coded `_provider_retry_interval` of 10 seconds in `V2LearningIntegration` may not suit all deployments; consider making this configurable via the existing config object or constructor parameter so operators can tune retry aggressiveness.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@EterUltimate EterUltimate force-pushed the codex/fix-provider-cold-start branch 2 times, most recently from 51a5cbf to b7a506d Compare June 7, 2026 06:49
@EterUltimate EterUltimate force-pushed the codex/fix-provider-cold-start branch from b7a506d to 6f7ac82 Compare June 7, 2026 06:52
@EterUltimate

Copy link
Copy Markdown
Collaborator Author

本 PR 已完成本地审查和 CI:Python syntax、Ruff、commitlint、Sourcery review 均通过。Sourcery 的两条建议也已处理:Provider 重试间隔现在可配置,重复的 retry interval 判断已抽成 helper。当前仅剩 main 分支规则要求 1 个 approving review,批准后即可 rebase merge 并发布 3.1.6。

@EterUltimate EterUltimate requested a review from NickCharlie June 7, 2026 06:54
@EterUltimate EterUltimate merged commit 4a43702 into main Jun 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 没有找到Reranker 提供商 ID与Embedding 提供商 ID

1 participant