Skip to content

fix: make plugin imports rollback-safe - #9900

Open
JosephTian876 wants to merge 1 commit into
AstrBotDevs:masterfrom
JosephTian876:fix/plugin-import-transaction
Open

fix: make plugin imports rollback-safe#9900
JosephTian876 wants to merge 1 commit into
AstrBotDevs:masterfrom
JosephTian876:fix/plugin-import-transaction

Conversation

@JosephTian876

@JosephTian876 JosephTian876 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Plugin decorators mutate global Provider and tool registries while a module is imported. If that import raises, including during missing-dependency recovery, retrying in the same process can retain duplicate or partially registered objects. This also prevents startup from safely separating plugin discovery from plugin activation.

This PR makes plugin import side effects transactional without changing startup order or runtime Provider reload behavior.

Modifications / 改动点

  • Remove only Provider adapters and tools owned by the failed plugin module tree before retrying or reporting failure.

  • Resolve tool ownership from the raw handler module, including functools.partial handlers.

  • Traverse Handoff wrappers and agent child tools so nested registrations are claimed and rolled back consistently.

  • Canonicalize successful submodule registrations to the plugin's main module.

  • Preserve Core tools, sibling plugins, and unrelated registrations that appear concurrently.

  • Clear a plugin's failed-import record after a later ordinary retry succeeds.

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

pytest tests/test_plugin_manager.py tests/unit/test_core_lifecycle.py
90 passed

ruff format --check .
502 files already formatted

ruff check .
All checks passed!

git diff --check
passed

The regressions cover partial Provider/tool registration, missing-dependency reimport, nested Handoff/agent tools, sibling and Core ownership, concurrent unrelated registrations, and successful retry cleanup.

No dependencies or API/OpenAPI schemas change. Startup phase ordering is intentionally left to the follow-up update of #9513; this PR is its rollback-safety prerequisite.


Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc. / Not applicable: this is a bug fix and adds no user-facing feature.
  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 My changes do not introduce malicious code.

Summary by Sourcery

Make plugin registration side effects transactional so failed imports can be retried safely without disturbing unrelated runtime registrations.

Bug Fixes:

  • Make plugin imports rollback-safe by removing partial Provider, platform, and tool registrations when imports fail or are retried.
  • Prevent duplicate registrations during dependency recovery and clear failed-plugin state after a later successful retry.

Enhancements:

  • Improve ownership detection for partial handlers and nested Handoff or agent tools while preserving Core, sibling, and unrelated registrations.
  • Canonicalize successfully imported plugin tool ownership for consistent lifecycle management.

Tests:

  • Add regression coverage for partial imports, dependency recovery, nested tools, ownership isolation, concurrent registrations, and successful retries.

@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 reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. If the module-prefix ownership or retry cleanup is wrong, a failed plugin can leave stale provider or tool registrations behind, or cleanup can remove a legitimate registration from the running process. Those effects are bounded and can be repaired by restarting or reloading the process, although reverting would not undo registrations already made during a process run.


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.

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.

1 participant