mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-05-22 07:34:47 +02:00
fix(notifications): inject llm_backend into build_pipeline
build_pipeline previously constructed its own LLMBackend from
config.llm, which:
- duplicated main.py's already-running backend instance
- failed to inherit env-loaded LLM_API_KEY when called from
short-lived scripts (eyeball checks, tests), forcing fallback
- prevented pipeline components from sharing the live backend
build_pipeline and build_pipeline_components now require an
llm_backend parameter. main.py passes the same instance it
constructed for its primary responder. Tests pass mocks. The
digest accumulator now uses the live, authenticated backend.
Added test_build_pipeline_uses_provided_backend to lock in the
injection contract.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
9674e94efb
commit
a4cb29002d
3 changed files with 47 additions and 40 deletions
|
|
@ -50,6 +50,13 @@ class FailingLLMBackend:
|
|||
raise RuntimeError("LLM unavailable")
|
||||
|
||||
|
||||
def _make_mock_backend():
|
||||
"""Create a standard mock LLM backend for tests."""
|
||||
mock = MagicMock()
|
||||
mock.generate = AsyncMock(return_value="stub summary")
|
||||
return mock
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ACCUMULATOR EVENT LOGGING TESTS
|
||||
# ============================================================
|
||||
|
|
@ -478,7 +485,7 @@ def test_pipeline_routes_event_to_accumulator():
|
|||
"""Events via bus.emit end up in DigestAccumulator."""
|
||||
config = Config()
|
||||
bus, inhibitor, grouper, toggle_filter, dispatcher, accumulator = \
|
||||
build_pipeline_components(config)
|
||||
build_pipeline_components(config, _make_mock_backend())
|
||||
|
||||
event = make_event(
|
||||
source="test",
|
||||
|
|
@ -499,7 +506,7 @@ def test_pipeline_routes_immediate_to_both():
|
|||
"""Immediate events go to both dispatcher and accumulator in Phase 2.4."""
|
||||
config = Config()
|
||||
bus, inhibitor, grouper, toggle_filter, dispatcher, accumulator = \
|
||||
build_pipeline_components(config)
|
||||
build_pipeline_components(config, _make_mock_backend())
|
||||
|
||||
event = make_event(
|
||||
source="test",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Tests for ToggleFilter (Phase 2.4)."""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, AsyncMock
|
||||
|
||||
from meshai.notifications.events import make_event
|
||||
from meshai.notifications.pipeline.toggle_filter import ToggleFilter
|
||||
|
|
@ -101,16 +102,31 @@ class TestToggleFilterPipelineWiring:
|
|||
|
||||
def test_toggle_filter_pipeline_drops_disabled_toggle(self):
|
||||
"""Events for disabled toggles don't reach dispatcher or accumulator."""
|
||||
# Create config with only weather enabled
|
||||
config = Config()
|
||||
# We'll check by using build_pipeline_components and inspecting
|
||||
# In Phase 2.4, build_pipeline_components returns toggle_filter
|
||||
|
||||
# Pass mock LLM backend
|
||||
mock_backend = MagicMock()
|
||||
mock_backend.generate = AsyncMock(return_value="stub summary")
|
||||
|
||||
# Note: without toggles.enabled set, filter is a no-op
|
||||
# This test verifies the wiring is correct
|
||||
bus, inhibitor, grouper, toggle_filter, dispatcher, accumulator = \
|
||||
build_pipeline_components(config)
|
||||
bus, inhibitor, grouper, toggle_filter, dispatcher, accumulator = build_pipeline_components(config, mock_backend)
|
||||
|
||||
# Verify toggle_filter is in the chain
|
||||
assert toggle_filter is not None
|
||||
assert hasattr(toggle_filter, 'handle')
|
||||
|
||||
def test_build_pipeline_uses_provided_backend(self):
|
||||
"""build_pipeline_components uses the provided llm_backend."""
|
||||
config = Config()
|
||||
|
||||
# Sentinel backend with unique attribute
|
||||
sentinel = MagicMock()
|
||||
sentinel.unique_marker = "I_AM_THE_SENTINEL"
|
||||
sentinel.generate = AsyncMock(return_value="sentinel summary")
|
||||
|
||||
bus, inhibitor, grouper, toggle_filter, dispatcher, accumulator = build_pipeline_components(config, sentinel)
|
||||
|
||||
# Accumulator should have the exact sentinel instance
|
||||
assert accumulator._llm is sentinel
|
||||
assert accumulator._llm.unique_marker == "I_AM_THE_SENTINEL"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue