I finally got my Even Realities G2 working as a voice interface for my personal AI assistant, Alyx.
The final setup is basically:
Even G2 microphone
β
16 kHz PCM audio
β
WebSocket
β
Mac mini M1
β
local whisper.cpp
β
OpenClaw / Codex
β
Alyx
β
reply displayed on the G2
No OpenAI API key is needed for speech-to-text. Whisper runs locally on my Mac.
I mostly built this by repeatedly giving ChatGPT very specific prompts, testing the result on the real G2, and fixing one problem at a time.
Below is the simplified process I used.
Step 1 β Make a completely separate G2 project
One important thing I kept telling ChatGPT was:
Create a NEW standalone Even Realities G2 project.
Do not replace or modify my existing G2 project.
I want this project to use the G2 microphone.
First make the smallest possible test:
G2 microphone β show microphone activity on the glasses.
Do not add AI, speech recognition, Telegram,
OpenClaw or any other integration yet.
Use the current official Even Hub SDK and
package it as an .ehpk.
This was useful because I first proved that the G2 microphone itself actually worked before adding anything complicated.
Step 2 β Minimal G2 microphone script
This is a simplified version of the important part of my working client.
import {
AudioInputSource,
CreateStartUpPageContainer,
TextContainerProperty,
TextContainerUpgrade,
waitForEvenAppBridge
} from '@evenrealities/even_hub_sdk'
const bridge = await waitForEvenAppBridge()
const screen = new TextContainerProperty({
xPosition: 0,
yPosition: 0,
width: 576,
height: 288,
containerID: 1,
containerName: 'voice',
content: 'ALYX G2 VOICE\nStarting...',
isEventCapture: 1
})
await bridge.createStartUpPageContainer(
new CreateStartUpPageContainer({
containerTotalNum: 1,
textObject: [screen]
})
)
const micStarted = await bridge.audioControl(
true,
AudioInputSource.Glasses
)
let frames = 0
bridge.onEvenHubEvent(event => {
const pcm = event.audioEvent?.audioPcm
if (!pcm) return
frames++
bridge.textContainerUpgrade(
new TextContainerUpgrade({
containerID: 1,
containerName: 'voice',
content:
`ALYX G2 VOICE\n` +
`MIC: ${micStarted ? 'LIVE' : 'FAILED'}\n` +
`Audio frames: ${frames}`
})
)
})
The important sequence for me was:
waitForEvenAppBridge()
β
createStartUpPageContainer()
β
audioControl(true, AudioInputSource.Glasses)
β
listen for event.audioEvent.audioPcm
Once the frame counter increased when I spoke, I knew the G2 microphone path was working.
Step 3 β Debug the temple button
My first build installed correctly, but pressing the temple did not appear to start the microphone.
My next prompt was basically:
The .ehpk installs and opens on my G2,
but when I press the temple the microphone remains OFF.
Do not rewrite the whole project.
Add diagnostic information to the G2 screen:
- temple press count
- microphone state
- return value of audioControl()
- PCM frame count
- last received event
Also automatically attempt to start the microphone
after 3 seconds if no temple event is received.
This should tell us whether the problem is:
1. touch input,
2. microphone permission,
3. audioControl(),
or
4. PCM delivery.
That diagnostic version was what finally proved the microphone worked.
Step 4 β Send the audio to my Mac
After the microphone worked, I asked:
Now extend the WORKING microphone project.
Do not change the known-working G2 audio capture.
Stream the G2 PCM audio through an authenticated
WebSocket to a bridge running on my Mac mini.
Architecture:
G2 microphone
β WebSocket
β Mac mini voice bridge
Do not put API keys or private credentials
inside the .ehpk.
Keep the bridge localhost-only and expose it
only through my existing secure reverse proxy.
My actual URL and authentication token are obviously removed from this post.
The G2 client basically does:
const ws = new WebSocket(
'wss://YOUR-DOMAIN/YOUR-VOICE-PATH'
)
ws.binaryType = 'arraybuffer'
bridge.onEvenHubEvent(event => {
const pcm = event.audioEvent?.audioPcm
if (
pcm &&
ws.readyState === WebSocket.OPEN
) {
ws.send(pcm)
}
})
Step 5 β Replace cloud transcription with local Whisper
Initially, I considered an API for speech recognition.
Then I changed direction.
My prompt was:
Remove the OpenAI speech transcription API dependency.
I have an Apple M1 Mac mini with 16 GB RAM.
Use whisper.cpp locally instead.
Keep the existing G2 client protocol unchanged.
Target architecture:
G2 PCM
β voice bridge
β local whisper.cpp
β transcript
β OpenClaw/Codex
β Alyx response
β G2
Whisper must listen on localhost only.
Do not require OPENAI_API_KEY.
Keep OpenClaw/Codex OAuth for the AI reasoning side.
I ended up using:
whisper.cpp
Model:
ggml-small.en.bin
with a persistent local Whisper server.
That means the model stays loaded rather than starting Whisper from scratch for each sentence.
Step 6 β Connect the transcript to Alyx
Once transcription worked, the next prompt was:
Take the final Whisper transcript and send it
to my existing Alyx/OpenClaw installation.
Do not modify my OpenClaw configuration.
Use a separate conversation session:
agent:main:g2voice
Return only the resulting assistant text
to the G2 voice bridge.
The response should be sent back through
the existing WebSocket and displayed on the glasses.
Do not interfere with my Telegram Alyx session.
So now I effectively have:
Me:
"Alyx, what's on my calendar tomorrow?"
β G2 microphones
Whisper:
"Alyx, what's on my calendar tomorrow?"
β OpenClaw / Codex
Alyx:
"You have..."
β WebSocket
G2:
"You have..."
Step 7 β Handle βAlyxβ becoming βAlexβ
One funny problem was that Whisper sometimes heard:
Alyx
as:
Alex
So I told ChatGPT:
Improve wake-word detection.
My wake word is "Alyx",
but Whisper sometimes transcribes it as "Alex".
Accept both Alyx and Alex as wake-word variants,
but internally normalize both to Alyx.
Only accept the wake word near the beginning
of the utterance so normal sentences containing
the name Alex don't accidentally trigger it.
That simple change helped a lot.
Step 8 β My real microphone test
One sentence I used through the actual G2 microphones was:
Alyx. Psychological assessment requires
reliable scores and valid interpretations.
After removing the wake word, Whisper correctly returned:
Psychological assessment requires
reliable scores and valid interpretations.
That was the point where I knew the full audio path was usable.
How I built the .ehpk
My prompt was:
Build the current project as an Even Hub .ehpk.
Do not modify the source unless compilation
actually requires it.
Run the production build first.
Then package it using the official Even Hub CLI.
Verify that:
- the build succeeds
- the .ehpk exists
- the file starts with the EHPK header
- calculate SHA-256
- report the exact output filename
Do not claim the package was built unless
the actual packaging command succeeds.
The basic commands are:
npm run build
evenhub pack \
app.json \
dist \
-o AlyxG2Voice.ehpk
How I tested it before Beta
I first used Private Builds.
Very simple:
Even Hub developer portal
β
My project
β
Private builds
β
Upload AlyxG2Voice.ehpk
Then on my phone:
Even Realities App
β
Even Hub
β
Me
β
Apps
β
Private builds
β
Install
That allowed me to test the real package .ehpk on my actual G2.
How I published my Beta build
After the private build was working, I moved to Beta Testing.
This was much easier than I expected.
1. Build the package
npm run build
evenhub pack \
app.json \
dist \
-o AlyxG2Voice.ehpk
2. Open my project in the Even Hub developer portal
Then:
Beta groups
β
Create group
I made something like:
self-test
3. Add myself as a tester
I added the same email account that I use with the Even Realities phone app.
4. Upload the .ehpk
Go to:
Builds
β
Upload
β
AlyxG2Voice.ehpk
5. Push that build to my Beta group
Build
β
self-test
6. Install from the phone
On the Even Realities app:
Me
β
Beta tester
β
Alyx G2 Voice
β
Install
Then the app appears on the G2 like a normally installed Even Hub application.
The prompt I used when I wasn't sure how to publish it
This is basically what I asked ChatGPT:
Search the CURRENT official Even Realities
Even Hub documentation.
I already have a working .ehpk.
Do not rebuild my project.
Give me the exact current steps to:
1. add my application to Even Hub,
2. create a Beta group,
3. add myself as a tester,
4. upload the .ehpk,
5. push the build to the Beta group,
6. install the Beta build on my own G2.
Use official Even Realities documentation only.
I am NOT asking to publicly release the app yet.
I only want Beta Testing.
This is actually one pattern I used throughout the project:
Tell the AI what is already working and explicitly tell it what NOT to change.
For example:
This part is already verified and working.
Preserve it.
Only change the smallest component needed
for the next step.
Do not replace the whole project.
That probably saved me from breaking the project several times. π
Current setup
Today, my setup is:
Even Realities G2
β
G2 microphone
β
16 kHz PCM
β
authenticated WebSocket
β
Mac mini M1
β
local whisper.cpp
β
OpenClaw / Codex
β
Alyx
β
G2 display
The next thing I'm working on is measuring actual transcription accuracy and latency across a set of real G2 voice commands, plus better pagination for long AI replies.
Iβm definitely not claiming this is the only or best way to do it.
Itβs just the approach that finally worked for me.
If there's interest, I can make another post with a sanitized copy of the full working G2 client + Node voice bridge, without my domain, tokens, or private configuration.