Skip to content

refactor(bluebubbles): migrate BlueBubbles adapter to bundled plugin - #31872

Closed
wesleysimplicio wants to merge 1 commit into
NousResearch:mainfrom
wesleysimplicio:chore/plugin-bluebubbles
Closed

refactor(bluebubbles): migrate BlueBubbles adapter to bundled plugin#31872
wesleysimplicio wants to merge 1 commit into
NousResearch:mainfrom
wesleysimplicio:chore/plugin-bluebubbles

Conversation

@wesleysimplicio

@wesleysimplicio wesleysimplicio commented May 25, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Migrate the BlueBubbles (iMessage) gateway adapter from the legacy gateway/platforms/bluebubbles.py import into a self-contained bundled plugin under plugins/platforms/bluebubbles/, following the exact same pattern used by the Mattermost plugin migration.

Root cause

The detailed rationale from the original PR body is preserved below. This template update keeps the review structure consistent with #29640.

Fix

Why this shape

This shape mirrors #29640 so reviewers can quickly compare scope, root cause, fix, tests, and related context without having to decode a custom PR description.

Tests

  1. hermes gateway run with BLUEBUBBLES_SERVER_URL and BLUEBUBBLES_PASSWORD set — adapter loads via plugin system, webhook listener starts
  2. hermes setup → BlueBubbles — interactive wizard prompts for URL, password, allowlist, home channel (same flow as before)
  3. Cron delivery with deliver=bluebubbles — runs via _standalone_send() without a live gateway
  4. hermes config edit with bluebubbles: YAML block — env vars get set via _apply_yaml_config()
  5. Existing Mattermost plugin unaffected — share same register_platform() pattern

Generated by Hermes Turbo

Related PRs / issues

  • Original body preserved below for full context.
Original body

Summary

Migrate the BlueBubbles (iMessage) gateway adapter from the legacy gateway/platforms/bluebubbles.py import into a self-contained bundled plugin under plugins/platforms/bluebubbles/, following the exact same pattern used by the Mattermost plugin migration.

What Changed

Added — plugins/platforms/bluebubbles/

  • __init__.py — standard plugin entry point exposing register
  • adapter.py — full adapter (copied from gateway/platforms/bluebubbles.py) with appended registration functions:
    • register(ctx) — plugin entry point, calls ctx.register_platform(...)
    • _standalone_send() — out-of-process cron delivery via BlueBubbles REST API
    • interactive_setup() — interactive setup wizard (replaces hermes_cli/setup.py::_setup_bluebubbles)
    • _apply_yaml_config() — YAML→env config bridge for config.yaml bluebubbles: keys
    • _is_connected() — connectivity probe
  • plugin.yaml — plugin metadata

Removed

  • gateway/run.py: removed the elif platform == Platform.BLUEBUBBLES: hardcoded import block
  • hermes_cli/gateway.py: removed the "bluebubbles": _s._setup_bluebubbles mapping
  • hermes_cli/setup.py: removed _setup_bluebubbles() function

Fluxo

  1. Copied gateway/platforms/bluebubbles.pyplugins/platforms/bluebubbles/adapter.py
  2. Adiciona register(), _standalone_send(), interactive_setup(), _apply_yaml_config(), _is_connected() no final do adapter, seguindo exatamente o padrão do Mattermost
  3. Remove import hardcoded do BlueBubbles do gateway/run.py::build_adapter()
  4. Comenta a entrada do BlueBubbles no hermes_cli/gateway.py::_builtin_setup_fn()
  5. Remove _setup_bluebubbles() do hermes_cli/setup.py

Visão

Same zero-regression migration pattern proven by Mattermost:

Aspect Before After
Adapter location gateway/platforms/bluebubbles.py plugins/platforms/bluebubbles/adapter.py
Import method Hardcoded elif in build_adapter() Plugin system register() auto-discovery
Setup wizard hermes_cli/setup.py::_setup_bluebubbles() interactive_setup() in plugin adapter
Config bridge gateway/config.py _apply_yaml_config() in plugin adapter
Cron delivery N/A (no standalone sender) _standalone_send() in plugin adapter

Test Plan

  1. hermes gateway run with BLUEBUBBLES_SERVER_URL and BLUEBUBBLES_PASSWORD set — adapter loads via plugin system, webhook listener starts
  2. hermes setup → BlueBubbles — interactive wizard prompts for URL, password, allowlist, home channel (same flow as before)
  3. Cron delivery with deliver=bluebubbles — runs via _standalone_send() without a live gateway
  4. hermes config edit with bluebubbles: YAML block — env vars get set via _apply_yaml_config()
  5. Existing Mattermost plugin unaffected — share same register_platform() pattern

Generated by Hermes Turbo


Generated by Hermes Turbo

Add register(), _standalone_send(), interactive_setup(),
_apply_yaml_config(), and _is_connected() to the BlueBubbles plugin
adapter following the exact Mattermost migration pattern.

Old code removed from:
- gateway/run.py: BlueBubbles elif block in build_adapter()
- hermes_cli/gateway.py: _setup_bluebubbles mapping (comment out)
- hermes_cli/setup.py: _setup_bluebubbles() function
@alt-glitch alt-glitch added type/refactor Code restructuring, no behavior change P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins comp/gateway Gateway runner, session dispatch, delivery labels May 25, 2026
@talwayh1

Copy link
Copy Markdown

CI Self-Heal: Test Flake Fix

Tests (run 26383939558): The test test_model_switch_uses_requested_provider flaked with:

AssertionError: assert 'custom' == 'anthropic'

Root cause: xdist worker state pollution. A previous test in the same worker registers a custom provider that shadows 'anthropic', causing an extra resolve_runtime_provider call that pushes the expected call out of runtime_calls[-1] position.

Fix submitted in PR #31880: Switches from position-dependent runtime_calls[-1] to position-independent "anthropic" in runtime_calls. The state.agent.provider == "anthropic" assertion already validates correctness.

No changes needed on this PR — the fix targets main and will back-propagate.

@wesleysimplicio

Copy link
Copy Markdown
Contributor Author

Thanks for the CI self-heal and the heads-up. That makes sense — I'll leave this PR unchanged since the fix is targeting in #31880 and should back-propagate once it lands. I'll recheck this branch after the upstream fix is merged.

@wesleysimplicio

Copy link
Copy Markdown
Contributor Author

Correction: thanks for the CI self-heal and the heads-up. That makes sense — I will leave this PR unchanged since the fix is targeting upstream main in #31880 and should back-propagate once it lands. I will recheck this branch after the upstream fix is merged.

@wesleysimplicio

Copy link
Copy Markdown
Contributor Author

Closing non-fix PR as requested — mantendo apenas PRs de fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/refactor Code restructuring, no behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants