Skip to content

feat(sdk-python): rewrite to async generator API per arch doc §12.1 - #7

Merged
Raphjacksun7 merged 1 commit into
mainfrom
feat/wave3-sdk-python-rewrite
Jun 10, 2026
Merged

Raphjacksun7 merged 1 commit into
mainfrom
feat/wave3-sdk-python-rewrite

Conversation

@Raphjacksun7

Copy link
Copy Markdown
Contributor

Linked issue

Closes #HIDDEN-003 (sdk-python LEAVE gap, see FAKE_SCAFFOLD_INVENTORY)

Summary

Rewrites the Python SDK to match the architecture document §12.1 specification. Two conflicting partial implementations (client.py and station.py) are replaced by a single clean PocketStation class.

  • Binary wire format fixed: broadcast() now sends raw PCM bytes over WebSocket. The old implementation sent base64-encoded JSON — a protocol deviation that would have broken any real relay integration.
  • Error propagation fixed: listen() now propagates WebSocket errors to the caller. The old implementation had a bare except: return that swallowed all errors silently.
  • LEAVE message implemented: disconnect() and __aexit__ now send LEAVE JSON before closing the WebSocket. Burns down the FAKE_SCAFFOLD_INVENTORY partial row.
  • Unified context manager API: async with PocketStation(...) as station: calls connect() on enter, disconnect() on exit.
  • AudioFrame gains timestamp_ns: monotonic nanosecond timestamp at frame receipt, matching arch doc §4.1.

Scope control

  • I modified only this repo.
  • I respected the repo phase gate.
  • I did not edit architecture docs unless explicitly assigned.
  • I did not add dependencies without approval.

Tests run

python -m pytest tests/ -v
# 13 passed in 0.08s

Risks

None. No change to relay-facing protocol beyond fixing the binary wire format bug.

Reviewer focus

  1. broadcast() — confirm raw bytes over WebSocket is correct for the relay receiver.
  2. disconnect()finally: await ws.close() closes socket even if LEAVE send fails.
  3. listen() — no try/except around async for; errors reach the caller.

STAFF_REVIEW

Purpose: Align Python SDK with arch doc §12.1. Fix binary wire format and error-swallowing bugs. Close LEAVE gap from FAKE_SCAFFOLD_INVENTORY.

Files changed: Deleted client.py, test_client.py. Rewritten station.py, test_station.py. Updated __init__.py, types.py, FAKE_SCAFFOLD_INVENTORY.md.

Architecture boundary affected: Python SDK (Tier 2) only. No relay/api-server/audio-core changes.

Behavior preserved: _ensure_room() credential caching, AudioFrame.samples, all type definitions preserved.

Tests proving behavior: 13 GWT tests — SUBSCRIBE on connect, binary bytes on broadcast, LEAVE on aexit, ConnectionError propagation, AudioFrame sequence numbering.

What is still mocked/stubbed: WebRTC transport — intentionally DEFERRED (Python is WebSocket listener/voice-agent tier only).

Public API change: PocketStationClient and PocketStationSession removed. These had a name collision in the old __init__.py and were never documented.

Unsupported claims added/removed: None.

FAKE_SCAFFOLD_INVENTORY.md updated: Yes — close() LEAVE message PARTIAL row burned down.

Final decision: PASS

…fix binary wire format

- Delete pocketstation/client.py (HTTP-only, no WebSocket, no LEAVE)
- Delete tests/test_client.py (tests for deleted module)
- Rewrite pocketstation/station.py: single PocketStation class with
  connect()/listen()/broadcast()/disconnect() and async context manager
- broadcast() sends raw binary PCM bytes, not base64 JSON (wire format fix)
- listen() propagates WebSocket errors to caller instead of swallowing them
- disconnect() sends LEAVE message before closing WebSocket
- AudioFrame gains timestamp_ns field (arch doc §4.1 sequence_number + timestamp_ns)
- Update __init__.py: remove PocketStationClient/PocketStationSession exports
- Burn down FAKE_SCAFFOLD_INVENTORY.md 'close() LEAVE message' partial row
- 13 tests passing (9 new GWT-structured tests covering the four behavioral properties)
@Raphjacksun7
Raphjacksun7 merged commit 7c65b04 into main Jun 10, 2026
6 checks passed
@Raphjacksun7
Raphjacksun7 deleted the feat/wave3-sdk-python-rewrite branch June 10, 2026 01:01
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