A real-time AI assistant for Meta Ray-Ban smart glasses powered by Qwen (or any OpenAI-compatible API). See what you see, hear what you say, and take actions on your behalf — all through voice.
This is a fork of VisionClaw with two key changes: Gemini Live replaced by Qwen VL via OpenAI-compatible API, and OpenClaw replaced by Hermes as the agentic tool backend.
Built on Meta Wearables DAT SDK (iOS) / DAT Android SDK (Android) + Qwen VL API + Hermes (optional).
Supported platforms: iOS (iPhone) and Android (Pixel, Samsung, etc.)
Put on your glasses, tap the AI button, and talk:
- "What am I looking at?" -- Qwen sees through your glasses camera and describes the scene
- "Add milk to my shopping list" -- delegates to Hermes, which executes the task via your connected backend
- "Send a message to John saying I'll be late" -- routes through Hermes to your messaging integrations
- "Search for the best coffee shops nearby" -- web search via Hermes, results spoken back
The glasses camera streams at ~1fps to Qwen for visual context, while audio flows bidirectionally in real-time.
Meta Ray-Ban Glasses (or phone camera)
|
| video frames + mic audio
v
iOS / Android App (this project)
|
| JPEG frames (~1fps) + PCM audio (16kHz)
v
Qwen VL API (OpenAI-compatible endpoint)
|
|-- Audio response (PCM 24kHz) --> App --> Speaker
|-- Tool calls (execute) -------> App --> Hermes Gateway
| |
| v
| Agentic actions: web search,
| messaging, smart home,
| notes, reminders, etc.
| |
|<---- Tool response (text) <----- App <-------+
|
v
Qwen speaks the result
Key pieces:
- Qwen VL API -- vision-language model via OpenAI-compatible endpoint (DashScope, Ollama, or any compatible backend)
- Hermes (optional) -- agentic gateway that gives Qwen the ability to take real-world actions; exposes a standard
/v1/chat/completions+/healthAPI with Bearer token auth - Phone mode -- test the full pipeline using your phone camera instead of glasses
- WebRTC streaming -- share your glasses POV live to a browser viewer
git clone https://github.com/tr10ne/visionqwen.git
cd visionqwen/samples/CameraAccess
open CameraAccess.xcodeprojCopy the example file and fill in your values:
cp CameraAccess/Secrets.swift.example CameraAccess/Secrets.swiftEdit Secrets.swift with your Qwen API key and endpoint (required) and optional Hermes/WebRTC config:
static let geminiAPIKey = "YOUR_QWEN_API_KEY"
static let geminiBaseURL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
// or "http://localhost:11434/v1" for local Ollama
static let geminiModel = "qwen-vl-max"Note: Field names in
Secrets.swiftare unchanged from the original codebase. SetgeminiAPIKeyto your Qwen API key andgeminiBaseURLto your OpenAI-compatible endpoint.
Get a free API key at DashScope or run locally via Ollama.
Select your iPhone as the target device and hit Run (Cmd+R).
Without glasses (iPhone mode):
- Tap "Start on iPhone" -- uses your iPhone's back camera
- Tap the AI button to start a Qwen session
- Talk to the AI -- it can see through your iPhone camera
With Meta Ray-Ban glasses:
First, enable Developer Mode in the Meta AI app:
- Open the Meta AI app on your iPhone
- Go to Settings (gear icon, bottom left)
- Tap App Info
- Tap the App version number 5 times -- this unlocks Developer Mode
- Go back to Settings -- you'll now see a Developer Mode toggle. Turn it on.
Then in VisionQwen:
- Tap "Start Streaming" in the app
- Tap the AI button for voice + vision conversation
git clone https://github.com/tr10ne/visionqwen.gitOpen samples/CameraAccessAndroid/ in Android Studio.
The Meta DAT Android SDK is distributed via GitHub Packages. You need a GitHub Personal Access Token with read:packages scope.
- Go to GitHub > Settings > Developer Settings > Personal Access Tokens and create a classic token with
read:packagesscope - In
samples/CameraAccessAndroid/local.properties, add:
github_token=YOUR_GITHUB_TOKENTip: If you have the
ghCLI installed, you can rungh auth tokento get a valid token. Make sure it hasread:packagesscope -- if not, rungh auth refresh -s read:packages.Note: GitHub Packages requires authentication even for public repositories. The 401 error means your token is missing or invalid.
cd samples/CameraAccessAndroid/app/src/main/java/com/meta/wearable/dat/externalsampleapps/cameraaccess/
cp Secrets.kt.example Secrets.ktEdit Secrets.kt with your Qwen API key and endpoint:
const val geminiApiKey = "YOUR_QWEN_API_KEY"
const val geminiBaseUrl = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
const val geminiModel = "qwen-vl-max"Note: Field names in
Secrets.ktare unchanged from the original codebase.
- Let Gradle sync in Android Studio (it will download the DAT SDK from GitHub Packages)
- Select your Android phone as the target device
- Click Run (Shift+F10)
Wireless debugging: You can also install via ADB wirelessly. Enable Wireless debugging in your phone's Developer Options, then pair with
adb pair <ip>:<port>.
Without glasses (Phone mode):
- Tap "Start on Phone" -- uses your phone's back camera
- Tap the AI button (sparkle icon) to start a Qwen session
- Talk to the AI -- it can see through your phone camera
With Meta Ray-Ban glasses:
Enable Developer Mode in the Meta AI app (same steps as iOS above), then:
- Tap "Start Streaming" in the app
- Tap the AI button for voice + vision conversation
Hermes gives Qwen the ability to take real-world actions. Without it, Qwen operates in voice + vision only mode.
The app communicates with Hermes via a standard OpenAI-compatible /v1/chat/completions endpoint with Bearer token auth. Hermes must also expose a /health endpoint for connection checks.
iOS -- In Secrets.swift:
static let openClawHost = "http://your-hermes-host"
static let openClawPort = 18789
static let openClawGatewayToken = "your-bearer-token-here"Android -- In Secrets.kt:
const val openClawHost = "http://your-hermes-host"
const val openClawPort = 18789
const val openClawGatewayToken = "your-bearer-token-here"Note: The field names
openClawHost,openClawPort, andopenClawGatewayTokenare unchanged from the original codebase but now point to your Hermes instance.
Both iOS and Android also have an in-app Settings screen where you can change these values at runtime without editing source code.
The app expects your Hermes gateway to implement:
| Endpoint | Method | Purpose |
|---|---|---|
/health |
GET |
Connection check -- must return 2xx-4xx |
/v1/chat/completions |
POST |
Chat with model: "hermes", standard OpenAI messages format |
Auth: Authorization: Bearer <token> on all requests. No OpenClaw-specific headers (x-openclaw-*) are used.
curl -H "Authorization: Bearer your-token" http://your-hermes-host:18789/healthAll source code is in samples/CameraAccess/CameraAccess/:
| File | Purpose |
|---|---|
Gemini/GeminiConfig.swift |
API keys, model config, system prompt |
Gemini/GeminiLiveService.swift |
WebSocket client for Qwen VL API (OpenAI-compatible) |
Gemini/AudioManager.swift |
Mic capture (PCM 16kHz) + audio playback (PCM 24kHz) |
Gemini/GeminiSessionViewModel.swift |
Session lifecycle, tool call wiring, transcript state |
OpenClaw/ToolCallModels.swift |
Tool declarations, data types |
OpenClaw/OpenClawBridge.swift |
HTTP client for Hermes gateway (/health ping + /v1/chat/completions) |
OpenClaw/ToolCallRouter.swift |
Routes tool calls to Hermes |
iPhone/IPhoneCameraManager.swift |
AVCaptureSession wrapper for iPhone camera mode |
WebRTC/WebRTCClient.swift |
WebRTC peer connection + SDP negotiation |
WebRTC/SignalingClient.swift |
WebSocket signaling for WebRTC rooms |
All source code is in samples/CameraAccessAndroid/app/src/main/java/.../cameraaccess/:
| File | Purpose |
|---|---|
gemini/GeminiConfig.kt |
API keys, model config, system prompt |
gemini/GeminiLiveService.kt |
OkHttp WebSocket client for Qwen VL API (OpenAI-compatible) |
gemini/AudioManager.kt |
AudioRecord (16kHz) + AudioTrack (24kHz) |
gemini/GeminiSessionViewModel.kt |
Session lifecycle, tool call wiring, UI state |
openclaw/ToolCallModels.kt |
Tool declarations, data classes |
openclaw/OpenClawBridge.kt |
HTTP client for Hermes gateway (/health ping + /v1/chat/completions) |
openclaw/ToolCallRouter.kt |
Routes tool calls to Hermes |
phone/PhoneCameraManager.kt |
CameraX wrapper for phone camera mode |
webrtc/WebRTCClient.kt |
WebRTC peer connection (stream-webrtc-android) |
webrtc/SignalingClient.kt |
OkHttp WebSocket signaling for WebRTC rooms |
settings/SettingsManager.kt |
SharedPreferences with Secrets.kt fallback |
- Input: Phone mic -> AudioManager (PCM Int16, 16kHz mono, 100ms chunks) -> Qwen API
- Output: Qwen API -> AudioManager playback queue -> Phone speaker
- iOS iPhone mode: Uses
.voiceChataudio session for echo cancellation + mic gating during AI speech - iOS Glasses mode: Uses
.videoChataudio session (mic is on glasses, speaker is on phone -- no echo) - Android: Uses
VOICE_COMMUNICATIONaudio source for built-in acoustic echo cancellation
- Glasses: DAT SDK video stream (24fps) -> throttle to ~1fps -> JPEG (50% quality) -> Qwen VL API
- Phone: Camera capture (30fps) -> throttle to ~1fps -> JPEG -> Qwen VL API
Both apps declare a single execute tool that routes everything through Hermes:
- User says "Add eggs to my shopping list"
- Qwen speaks "Sure, adding that now" (verbal acknowledgment before tool call)
- App sends
toolCallwithexecute(task: "Add eggs to the shopping list") ToolCallRoutersends HTTP POST to Hermes at/v1/chat/completionswithmodel: "hermes"- Hermes executes the task
- Result returns via
toolResponse - Qwen speaks the confirmation
Share your glasses POV in real-time to a browser viewer with bidirectional audio and video.
- Tap the Live button in the app
- The app connects to a signaling server and gets a 6-character room code
- Share the code -- the viewer opens the server URL in a browser and enters it
- WebRTC peer connection is established (SDP + ICE via the signaling server)
- Media flows peer-to-peer: glasses video to browser, browser camera back to iOS PiP
Key details:
- Signaling server: Node.js + WebSocket, located at
samples/CameraAccess/server/-- serves the browser viewer and relays SDP/ICE - NAT traversal: Google STUN servers + ExpressTURN relay (fetched from
/api/turn) - Video: 24 fps, 2.5 Mbps max bitrate
- Background handling: 60-second grace period for iOS app backgrounding -- room stays alive for reconnection
- Constraint: Cannot run simultaneously with an active AI session (audio device conflict)
For full details, see samples/CameraAccess/CameraAccess/WebRTC/README.md.
- iOS 17.0+
- Xcode 15.0+
- Qwen API key (DashScope or local Ollama)
- Meta Ray-Ban glasses (optional -- use iPhone mode for testing)
- Hermes instance (optional -- for agentic actions)
- Android 14+ (API 34+)
- Android Studio Ladybug or newer
- GitHub account with
read:packagestoken (for DAT SDK) - Qwen API key (DashScope or local Ollama)
- Meta Ray-Ban glasses (optional -- use Phone mode for testing)
- Hermes instance (optional -- for agentic actions)
AI doesn't hear me -- Check that microphone permission is granted. Speak clearly and at normal volume.
Hermes connection timeout -- Make sure your phone can reach the Hermes host, the service is running, and the URL/port in Secrets is correct. Verify with:
curl -H "Authorization: Bearer your-token" http://your-hermes-host:18789/health"API key not configured" -- Add your Qwen API key in Secrets.swift (geminiAPIKey field) or in the in-app Settings.
Echo/feedback in iPhone mode -- The app mutes the mic while the AI is speaking. If you still hear echo, try turning down the volume.
Gradle sync fails with 401 Unauthorized -- Your GitHub token is missing or doesn't have read:packages scope. Check local.properties. Generate a new token at github.com/settings/tokens.
API timeout -- Ensure your geminiBaseUrl is reachable from your phone. If using Ollama locally, make sure it's bound to 0.0.0.0 and not just localhost.
Audio not working -- Ensure RECORD_AUDIO permission is granted. On Android 13+, you may need to grant this permission manually in Settings > Apps.
Phone camera not starting -- Ensure CAMERA permission is granted. CameraX requires both the permission and a valid lifecycle.
For DAT SDK issues, see the developer documentation or the discussions forum.
VisionQwen is a fork of VisionClaw by Xiaoan Liu, DaeHo Lee, Eric J Gonzalez, Mar Gonzalez-Franco, and Ryo Suzuki. Original paper: VisionClaw: Always-On AI Agents through Smart Glasses (arXiv:2604.03486).
This source code is licensed under the license found in the LICENSE file in the root directory of this source tree.



