Add passive mesh context awareness — observe channel traffic, inject into LLM prompts

New context.py module: ring buffer (50K hard cap, ~25MB ceiling) passively
records all channel broadcasts. Observations are formatted with relative
timestamps and injected into the system prompt when generating LLM responses.
Only public channel traffic is observed; DMs to the bot are excluded (already
in per-user history). Bot's own node ID is auto-added to ignore list.

Config: context.enabled, observe_channels, ignore_nodes, max_age, max_context_items
TUI: new Context settings submenu (menu item 7)
Hourly prune removes expired observations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ubuntu 2026-02-24 22:02:42 +00:00
commit 63a2caad37
7 changed files with 302 additions and 12 deletions

View file

@ -10,6 +10,7 @@ from .backends.base import LLMBackend
from .commands import CommandContext, CommandDispatcher
from .config import Config
from .connector import MeshConnector, MeshMessage
from .context import MeshContext
from .history import ConversationHistory
logger = logging.getLogger(__name__)
@ -61,12 +62,14 @@ class MessageRouter:
history: ConversationHistory,
dispatcher: CommandDispatcher,
llm_backend: LLMBackend,
context: MeshContext = None,
):
self.config = config
self.connector = connector
self.history = history
self.dispatcher = dispatcher
self.llm = llm_backend
self.context = context
def should_respond(self, message: MeshMessage) -> bool:
@ -147,6 +150,16 @@ class MessageRouter:
if getattr(self.config.llm, 'use_system_prompt', True):
system_prompt = self.config.llm.system_prompt
# Inject mesh context if available
if self.context:
max_items = getattr(self.config.context, 'max_context_items', 20)
context_block = self.context.get_context_block(max_items=max_items)
if context_block:
system_prompt += (
"\n\n--- Recent mesh traffic (for context only, not messages to you) ---\n"
+ context_block
)
try:
response = await self.llm.generate(
messages=history,