loop
Bug Fixes
/stop Command Output Unified
- Add
consume_should_end_flag()andreset_should_end_flag()helpers for atomic stop signal handling - Prevent duplicate stop messages by emitting empty speech from secondary stop paths
- Apply consistent prefix formatting via
apply_system_reply_formatbased on conversation mode - Add empty speech guard to prevent bare "(name) 回复:" bubbles
Dynamic Sensor Template Rendering
- Convert DynamicSensor and DynamicBinarySensor from polling to event-driven
async_track_template_result - Add graceful TemplateError handling to eliminate log spam when templates reference unavailable context variables
WebSocket Subscription Race Condition
- Fix ReferenceError "Cannot access 's' before initialization" by deferring event delivery via setTimeout(0)
- Wrap callback in try/catch to isolate errors from WebSocket dispatch
- Ensure status bar and file upload UI appear in all ha-assist-chat instances via deepQueryAll
History Display
- Update internal tag stripping regex to support both ASCII colon (:) and fullwidth colon for CJK contexts
- Prevent internal system context blocks from leaking into frontend message display
New Features
Live Turn Snapshot Persistence
- Add live_turn_store.py for persisting conversation turn state to disk
- Save snapshot on WebSocket detach with status (running, cancelled, error, finished)
- Reset live_response_parts at turn start to prevent stale fragments in live view
- Emit stream_end event when detached pipeline completes
Conversation History Duplicate Consolidation
- Add
consolidate_duplicates()method to ConversationHistory class - Detect duplicates by fingerprinting first message within 20-second windows
- Merge shorter duplicate into longer one while preserving unique turns
Full Changelog: v8.9.0...v9.0.0