Skip to content

fix(agent-api): guard voice_desired_state toggle with a Lock (closes #1922) - #1975

Closed
john-the-dev wants to merge 1 commit into
sonichi:mainfrom
john-the-dev:fix/agent-api-voice-toggle-lock
Closed

john-the-dev wants to merge 1 commit into
sonichi:mainfrom
john-the-dev:fix/agent-api-voice-toggle-lock

Conversation

@john-the-dev

Copy link
Copy Markdown
Collaborator

Summary

Test plan

  • python3 tests/agent-api-delegation.test.py — PASS (no regression in the endpoint test suite)
  • python3 tests/agent-api-task-field-injection.test.py — PASS

🤖 Generated with Claude Code

https://claude.ai/code/session_01QB3qZQrwponfum2JFNvHeh

…onichi#1922)

/voice/toggle has a read-modify-write on voice_desired_state. With
ThreadingHTTPServer (PR sonichi#1921), two simultaneous POSTs can interleave and
double-toggle back to the original state. Add _voice_state_lock (threading.Lock)
and acquire it around the toggle's read-then-assign. Harmless with the current
single-threaded HTTPServer; necessary when sonichi#1921 lands.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QB3qZQrwponfum2JFNvHeh
@john-the-dev

Copy link
Copy Markdown
Collaborator Author

Duplicate of #1928 which already fixes #1922 (voice_desired_state toggle lock). Closing.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Gate

❌ Diff coverage BELOW the 95% bar — uncovered changed lines listed below. Whole-tree (informational): 33%.

Diff Coverage

Diff: origin/main...HEAD, staged and unstaged changes

  • src/agent-api.py (50.0%): Missing lines 768-769

Summary

  • Total: 4 lines
  • Missing: 2 lines
  • Coverage: 50%

src/agent-api.py

Lines 764-773

  764 
  765         if path == "/voice/toggle":
  766             if not self.check_auth():
  767                 return
! 768             with _voice_state_lock:
! 769                 voice_desired_state = "connected" if voice_desired_state == "disconnected" else "disconnected"
  770             self.send_json(200, {"state": voice_desired_state})
  771             return
  772 
  773         if path == "/voice/set":

john-the-dev added a commit to john-the-dev/sutando that referenced this pull request Jul 7, 2026
…ge gate

Adds tests/agent-api-voice-toggle.test.py to exercise the
`with _voice_state_lock:` block added in sonichi#1975.  Follows the
main-thread-server pattern from agent-api-delegation.test.py so the
coverage tracer records the handler dispatch on the main (traced) thread.

Checks: initial state is "disconnected", first toggle → "connected",
second toggle → "disconnected", lock object is a real threading.Lock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QB3qZQrwponfum2JFNvHeh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant