Commit graph

1 commit

Author SHA1 Message Date
eb84f27941 feat(v0.6-5): env_reporter + router wiring + include_in_llm_context per-adapter toggle -- LLM gains read access to every adapter table via the existing mesh_reporter pre-rendered prompt-injection pattern
Closes audit doc Section C. The LLM can now answer "any fires near me?",
"how are band conditions?", "why didnt I hear about that quake?"
without any tool-use / MCP / SQL pass-through -- via the same prompt-
injection contract mesh_reporter uses.

env_reporter (meshai/notifications/env_reporter.py):
  - EnvReporter class with build_env_summary / build_fires_detail /
    build_alerts_detail / build_quakes_detail / build_traffic_detail /
    build_gauges_detail / build_swpc_detail / build_drop_audit / build_all
  - Reads from fires + firms_pixels + nws_alerts + quake_events +
    traffic_events + gauge_readings + swpc_events +
    band_conditions_broadcasts + event_log + dispatcher_state
  - Each build_*_detail() checks adapter_meta.include_in_llm_context for
    the relevant adapter(s) before reading; turning the meta off via
    /api/adapter-meta drops that adapters block out of the LLM prompt
  - Defensive: missing meta row defaults to True (include); DB-unavailable
    returns empty string; per-block 3000-char cap
  - Module-level env_reporter singleton for the router

Router wiring (meshai/router.py):
  - Extended _MESH_KEYWORDS dispatcher with _ENV_KEYWORDS_TO_SUBTYPE
    mapping (fire/quake/flood/warning/storm/road/swpc/etc -> coarse
    subtype). "flood" intentionally precedes "warning" so
    "river flood warning" routes to gauges, not alerts
  - _detect_env_subtype helper at module level (also test-importable)
  - _is_mesh_question now also fires for env keywords -- single detector
    per Matt s spec
  - _detect_mesh_scope returns ("env", subtype) when an env keyword
    matches, taking precedence over the node/region branches
  - generate_llm_response: when scope_type == "env", appends
    env_reporter.build_all() + env_reporter.build_drop_audit(hours=1)
    to the system prompt. Wrapped in try/except so a reporter fault
    never blocks the LLM call

Tests:
  - tests/test_env_reporter.py (18 cases): meta gate, every build_*
    method shape, build_all combines blocks, all-off produces empty
  - tests/test_router_env_scope.py (18 cases): parametrized subtype
    detection across fires/quakes/alerts/gauges/traffic/swpc, word-
    boundary check (firearm != fire), synthetic-probe end-to-end
    (seed fires table -> env_reporter emits a fires block with the
    seeded row)

Test count: 761 -> 797 (+36 new, 0 regressions).
2026-06-05 20:11:40 +00:00