Commit graph

2 commits

Author SHA1 Message Date
b1535744a1
fix(tests): stop poisoning sys.modules session-wide with a bare MagicMock (#160)
Three test files (test_llm_scoping, test_fix_meshcore_save_and_llm_test,
test_config_partial_save_merge) did `sys.modules.setdefault(_mod, MagicMock())`
to stub an optional import. `setdefault` installs the MagicMock into
sys.modules for the ENTIRE pytest session even when the real package is
present — so any LATER test that does `await <that module>.<coro>(...)`
(e.g. `await aiosqlite.connect(...)`) fails with
"object MagicMock can't be used in 'await' expression" / "Event loop is closed".

This is what made test_fire_tracker_phase4::test_natural_language_fire_
question_routes_to_llm pass in isolation but fail in full-suite order — the
leak came from an earlier file, not the victim. #140 hardened the victim's
own config/history isolation but couldn't fix an external sys.modules poison.

Fix: only fall back to the MagicMock when the real module genuinely fails to
import (guarded assignment), so a present package is never replaced. Root-cause
fix in the polluters, not a skip on the victim.

Suite: 2422 passed, 0 failed, 72 skipped — fully green (was 6 failed before
#140, then 1 order-dependent failure after). Confirmed deterministic across
repeated full runs.

Co-authored-by: Matt Johnson <mj@k7zvx.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 14:25:11 -06:00
a191200a12
feat(meshcore): decouple per-mesh LLM DM gate + mesh-scoped chat context (#19)
- router.should_respond branches on message.transport: MeshCore DMs are
  governed solely by meshcore_context.respond_to_dms (enforced at the
  transport); Meshtastic solely by bot.respond_to_dms. No global gate.
- MeshObservation tagged per-transport; the LLM "recent traffic" block is
  scoped to the originating mesh (keyword override for the other mesh),
  labeled by mesh so the model knows which it is describing.
- MeshCore observe_channels is now opt-in (empty = observe none).
- Chat-context retention 30d -> 14d (both meshes).
- Meshtastic integer channel-index filter no longer misapplied to MeshCore
  observations (their channel is a companion slot index).
- Frontend: relabel DM toggles per-mesh ("Answer direct messages",
  Meshtastic-only / MeshCore-only), remove the false channel-mention
  tooltips, opt-in wording for MeshCore observe-channels.

Tests: +tests/test_llm_scoping.py (10), context-filter updated for opt-in;
0 new failures (34 pre-existing).

Co-authored-by: Matt Johnson <mj@k7zvx.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 18:39:26 -06:00