snowspeeder f043d6b078 Fix major Nearlight deviations from design review
- Expose End conversation + readable draft during connecting/waiting
- Stop masking assistant speaking/thinking state in Type/muted modes
- Restrict failure diagnosis to real causes (no invented network text)
- Replace old blue tint with Rosewood everywhere
- Fix transcript short-content bottom-anchor (top-align short histories)
- Settings: visible Server URL label, focus on rejected save, edit clears
  saved confirmation, trim-aware unchanged detection
- Task detail: live store lookup with missing-task state
- Task rows: status text label restored
2026-09-12 08:20:43 -04:00
2026-08-31 19:50:46 -04:00
2026-09-12 06:26:58 -04:00
2026-08-31 19:50:46 -04:00
2026-09-12 06:26:58 -04:00

Voice — iOS client for Hope Voice

Native SwiftUI iOS app (iOS 17+) that talks to the Hope Voice agent: voice/text conversation, transcript history, voice & model pickers, and a background-tasks panel. Uses hope-voice-api.

Status: Core functionality is implemented and verified in simulator to the extent the environment allows. Full device qualification (mic capture, interruption behavior) remains pending. The native Talk/Activity redesign is implemented — see PLAN.md and docs/DEVICE_TESTING.md.

Prerequisites

  • Xcode 16+ (Swift 6), iOS 17 simulator or a real iPhone on the LAN.
  • xcodegen (brew install xcodegen).
  • The voice container running on Unraid (LiveKit + token server).
  • Mic: the simulator mic is unreliable in this environment (CoreAudio -4010, 0 input channels) — voice mode needs a real device. If the simulator was wiped, grant permission first: xcrun simctl privacy booted grant microphone dev.shane.voice.

Build & run

xcodegen generate   # regenerate Voice.xcodeproj after file changes
xcodebuild -project Voice.xcodeproj -scheme Voice_iOS \
  -destination 'generic/platform=iOS Simulator' build

The scheme is Voice_iOS (not Voice). Bundle id: dev.shane.voice. To run in the simulator, use Xcode or xcrun simctl with the built app.

Server configuration

Default base URL is https://192.168.86.2:9178 (see Sources/App/SettingsStore.swift). Change it at runtime in Settings → Server URL (the app disconnects and recreates the session when idle). The app derives the LiveKit signaling endpoint from this base URL.

TLS cert pinning

The deployment uses a persistent self-signed cert. The entrypoint regenerates it if missing or issued for a different IP. The pinned SHA-256 in Sources/Networking/TLSPinning.swift must match after any actual cert rotation:

openssl s_client -connect 192.168.86.2:9178 </dev/null 2>/dev/null \
  | openssl x509 -outform der | openssl dgst -sha256

Paste the new hash into TLSPinning.pinnedCertSHA256Hex. Until you do, token calls fail with a pin mismatch (not a network error).

Features

  • Conversation — LiveKit room with the Hope agent; voice mode (mic + TTS) and text mode (composer), toggleable and persisted. State machine (idle/connecting/listening/thinking/ speaking) driven by audio levels, with a compact status indicator and mic meter.
  • Transcripts — partials updated in place, finals with timestamps, delivery-marker stripping, last-50 history persisted to UserDefaults, clear button.
  • Voice & model pickers — 13 Azure TTS voices; LLM models from the agent's models message. Both persist and sync on join (set_voice/set_model).
  • Activity tab — live task_event updates (steps, result, error) with an active count badge on the tab.

Known limitations

  • Simulator mic: CoreAudio returns -4010 (no usable input source) in this environment; voice capture must be verified on a real device. Text mode works in the simulator.
  • Cert pin rotation: see above — re-export the pin after each server cert regeneration.
  • LiveKit signaling uses plain ws://192.168.86.2:7880 (not wss) because the Swift SDK cannot trust the self-signed cert on its WebSocket; token calls still go over pinned TLS.

Docs

S
Description
Real-time voice assistant: LiveKit + Azure Speech + local Gemma LLM
Readme
6 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 42.3%
Swift 27.3%
HTML 16.5%
JavaScript 7.8%
CSS 5.3%
Other 0.8%