Skip to content

Commit 6406350

Browse files
dennys246claude
andcommitted
fix(sim): restore reaction + percept verbosity in sim display
The foundations/reaction work introduced five new observable surfaces but none fed into the sim_logger display system. Two were regressions: 1. ReactionBus events were invisible — the old route_pain_percept called sim_pain() but Phase 2a deleted that code path without replacing the display hook. Now PainBus.__init__ wires a subscribe_all on its ReactionBus that calls a new sim_reaction() function. All reaction kinds (pain, fear, hunger, etc.) show in --display bio automatically. 2. Percept factories bypassed sim_percept — the Phase 4 factories (make_text_percept, make_scene_percept, make_intero_percept) became the canonical Percept construction path but didn't log. Now each factory calls _log_percept() which best-effort invokes sim_percept(). No-op outside simulation context. Three files, 36 LOC: - sim_logger.py: new sim_reaction(kind, intensity, source) at BIO tier - percept_factory.py: _log_percept helper + calls in all 3 factories - pain_bus.py: _sim_log_reaction subscriber + wiring in PainBus init Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7485f03 commit 6406350

3 files changed

Lines changed: 36 additions & 0 deletions

File tree

src/maxim/agents/percept_factory.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@
2121
from maxim.agents.percept_context import PerceptContext
2222

2323

24+
def _log_percept(source: str, content: str | None, modality: str) -> None:
25+
"""Best-effort sim_percept call. No-op outside simulation context."""
26+
try:
27+
from maxim.simulation.sim_logger import sim_percept
28+
29+
sim_percept(source, (content or "")[:80], modality=modality)
30+
except Exception:
31+
pass
32+
33+
2434
def make_text_percept(
2535
text: str,
2636
*,
@@ -49,6 +59,7 @@ def make_text_percept(
4959
)
5060
if sensory is None:
5161
sensory = SensoryTag(modality=SensoryModality.NARRATIVE)
62+
_log_percept(source, text, "text")
5263
return Percept(
5364
timestamp=ts,
5465
source=source,
@@ -79,6 +90,7 @@ def make_scene_percept(
7990
)
8091
if sensory is None:
8192
sensory = SensoryTag(modality=SensoryModality.NARRATIVE)
93+
_log_percept("narrative", scene_text, "text")
8294
return Percept(
8395
timestamp=ts,
8496
source="narrative",
@@ -111,6 +123,7 @@ def make_intero_percept(
111123
)
112124
if sensory is None:
113125
sensory = SensoryTag(modality=SensoryModality.INTEROCEPTION)
126+
_log_percept(source, content, "intero")
114127
return Percept(
115128
timestamp=ts,
116129
source=source,

src/maxim/proprioception/pain_bus.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
logger = logging.getLogger(__name__)
2727

2828

29+
def _sim_log_reaction(reaction: "Reaction") -> None:
30+
"""Best-effort sim_reaction call for the simulation display."""
31+
try:
32+
from maxim.simulation.sim_logger import sim_reaction
33+
34+
sim_reaction(reaction.kind, reaction.intensity, reaction.source)
35+
except Exception:
36+
pass
37+
38+
2939
class PainBus:
3040
"""Backward-compatible wrapper around ReactionBus.
3141
@@ -39,6 +49,10 @@ def __init__(self, history_size: int = 200) -> None:
3949
history_size=history_size,
4050
refractory_overrides={"pain": 0.5},
4151
)
52+
# Wire sim_logger so the simulation display shows reaction events.
53+
# Replaces the sim_pain() call lost when route_pain_percept was
54+
# deleted in Phase 2a.
55+
self.reaction_bus.subscribe_all(_sim_log_reaction)
4256

4357
def subscribe(self, callback: Callable[[PainSignal], None]) -> None:
4458
def _adapter(reaction: "Reaction") -> None:

src/maxim/simulation/sim_logger.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,15 @@ def sim_debug(subsystem: str, action: str, **kwargs: Any) -> None:
517517
sim_log(subsystem, action, kwargs if kwargs else None, _force_debug=True)
518518

519519

520+
def sim_reaction(kind: str, intensity: float, source: str, **kwargs: Any) -> None:
521+
"""Log a Reaction from the ReactionBus.
522+
523+
Generalizes sim_pain for all reaction kinds. Replaces the sim_pain
524+
call lost when route_pain_percept was deleted in Phase 2a.
525+
"""
526+
sim_log("REACTION", f"{kind} (intensity={intensity:.2f}) from {source}", kwargs if kwargs else None)
527+
528+
520529
def sim_pain(pain_type: str, intensity: float, **kwargs: Any) -> None:
521530
"""Log a pain signal."""
522531
sim_log("PAIN", f"{pain_type} (intensity={intensity:.2f})", kwargs if kwargs else None)

0 commit comments

Comments
 (0)