feat: Python parity for wol / banter / conversation / ddg_answer + 11 tests
New `wave59_handlers.py` (~250 lines) mirroring four Rust-only packs: - wol: pure-Python magic packet via socket + SO_BROADCAST. No PowerShell shellout (unlike the Rust pack). Reads MAC from memory_store under 'wol_<alias>' or JARVIS_WOL_TARGET env. Same MAC format tolerance (colons / dashes / dots / bare) as the Rust normaliser. - banter: pause/resume state + fire-one. Python edition doesn't run a background banter thread (the Rust daemon already does), so this is just the user-facing surface — same voice phrases work. - conversation: do_conversation_summary calls Groq with last 12 turns from main.py's `message_log`. set_history_ref() injects the live list reference at startup so the handler reads up-to-date history without a circular import. Offline-safe: GROQ_TOKEN missing → speak the last user message instead. do_conversation_repeat re-speaks the last assistant turn. - ddg_answer: urllib + DuckDuckGo Instant Answer JSON. Picks AbstractText → Answer → Definition → RelatedTopics[0]. Opens duckduckgo.com search fallback when nothing instant. extensions.py / main.py / commands.yaml: 7 new dispatch entries + proxy fns. commands.yaml now at 207 entries. tests/test_wave59_handlers.py: 11 unit tests for MAC normalisation, magic packet shape, WOL error paths, banter state machine, DDG trigger stripping, conversation history handling. Network calls deliberately NOT exercised here — they belong to integration tests. Tests: 104 → 115 (+11).
This commit is contained in:
parent
cdd331af35
commit
633850d0f7
5 changed files with 536 additions and 0 deletions
23
main.py
23
main.py
|
|
@ -112,6 +112,15 @@ system_message = {"role": "system", "content": (
|
|||
)}
|
||||
message_log = [system_message]
|
||||
|
||||
# Let wave59_handlers.do_conversation_* read the live history without
|
||||
# circular-importing main.py. The reference is shared (the list is mutated
|
||||
# in-place by `va_respond`), so summary/repeat always see the latest turns.
|
||||
try:
|
||||
import wave59_handlers as _w59
|
||||
_w59.set_history_ref(message_log)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
client = OpenAI(api_key=config.GROQ_TOKEN, base_url=config.GROQ_BASE_URL)
|
||||
|
||||
model = vosk.Model("model_small")
|
||||
|
|
@ -1805,6 +1814,20 @@ def run_action(action):
|
|||
extensions.do_expenses_week(action, _current_voice or '')
|
||||
elif t == 'expenses_breakdown':
|
||||
extensions.do_expenses_breakdown(action, _current_voice or '')
|
||||
elif t == 'wol':
|
||||
extensions.do_wol(action, _current_voice or '')
|
||||
elif t == 'banter_fire':
|
||||
extensions.do_banter_fire(action, _current_voice or '')
|
||||
elif t == 'banter_pause':
|
||||
extensions.do_banter_pause(action, _current_voice or '')
|
||||
elif t == 'banter_resume':
|
||||
extensions.do_banter_resume(action, _current_voice or '')
|
||||
elif t == 'conversation_summary':
|
||||
extensions.do_conversation_summary(action, _current_voice or '')
|
||||
elif t == 'conversation_repeat':
|
||||
extensions.do_conversation_repeat(action, _current_voice or '')
|
||||
elif t == 'ddg_answer':
|
||||
extensions.do_ddg_answer(action, _current_voice or '')
|
||||
|
||||
|
||||
_current_voice: str = ''
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue