Reference in New Issue
Block a user
Delete Branch "perplexity/Timmy-time-dashboard:feature/world-interface-heartbeat-871-872"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implements both #871 (WorldInterface abstraction) and #872 (Heartbeat Loop v2) in a single cohesive change.
Issue #871 — Gymnasium-style WorldInterface
src/infrastructure/world/interface.py— AbstractWorldInterfacebase class withobserve() → PerceptionOutput,act(CommandInput) → ActionResult,speak(message, target)contract. Optionalconnect()/disconnect()lifecycle hooks.src/infrastructure/world/types.py— CanonicalPerceptionOutput,CommandInput,ActionResult,ActionStatusdataclasses (compatible with PR #864's morrowind/schemas.py types).src/infrastructure/world/registry.py—AdapterRegistry— register adapters by name, instantiate by config. Module-level convenience functions exposed via__init__.py.src/infrastructure/world/adapters/mock.py—MockWorldAdapter— returns configurable canned perception, logs all commands and speech. Inspectableaction_logandspeech_logfor testing.src/infrastructure/world/adapters/tes3mp.py—TES3MPWorldAdapterstub — imports cleanly, raisesNotImplementedErroron all core methods with guidance comments.Issue #872 — Heartbeat Loop v2
src/loop/heartbeat.py—Heartbeatclass that drives the cognitive cycle:observe() → gather → reason → act → world.act() → reflect → broadcastthink_once()behaviour is preserved.CycleRecorddataclass logs each cycle with observation, reasoning summary, action, status, and durationheartbeat.cycleevents with action + reasoning summaryon_cycleasync callback for external consumersstart()/stop()for background loop managementsrc/loop/phase1_gather.py— Enhanced to foldperceptionmetadata from the heartbeat into gathered context when present. No change to existing behaviour when perception is absent.Tests (63 passing)
tests/infrastructure/world/test_interface.py— ABC contract, type construction, subclass requirementstests/infrastructure/world/test_registry.py— Register, get, overwrite warning, type checkingtests/infrastructure/world/test_mock_adapter.py— Full observe/act/speak cycle, lifecycle, action loggingtests/infrastructure/world/test_tes3mp_adapter.py— Stub instantiation, all methods raise NotImplementedErrortests/loop/test_heartbeat.py— Embodied + passive cycles, broadcast, logging, lifecycle, callbackstests/loop/test_three_phase.py— Existing tests pass (no regressions)Design Decisions
types.pyfrominterface.py: Types can be imported without pulling in the ABC, keeping lightweight consumers decoupled.run_cycle()remains the primitive;Heartbeatcomposes it with world interaction. Existing code that callsrun_cycle()directly is unaffected.PerceptionOutput/CommandInputtypes. Easy to consolidate when #864 merges.Testing
🤖 Generated with Claude Code