diff --git a/plugins/google_meet/README.md b/plugins/google_meet/README.md index 53049a584644..62d0bd6700a1 100644 --- a/plugins/google_meet/README.md +++ b/plugins/google_meet/README.md @@ -96,6 +96,34 @@ On macOS, hermes will **not** switch your system audio input automatically — t user has to do it. This is deliberate: switching default input on a whim would be a surprising side effect. +### Configuring the OpenAI Realtime model + +Realtime mode uses the OpenAI Realtime API. By default the bot connects with +`gpt-realtime`. Override the model via env var: + +| Env var | Default | Purpose | +|---|---|---| +| `HERMES_MEET_REALTIME_MODEL` | `gpt-realtime` | OpenAI Realtime model identifier passed in the WebSocket URL | +| `HERMES_MEET_REALTIME_VOICE` | `alloy` | Voice id (e.g. `alloy`, `verse`, `marin`, `cedar`) | +| `HERMES_MEET_REALTIME_KEY` | falls back to `OPENAI_API_KEY` | API key for the Realtime WS | +| `HERMES_MEET_REALTIME_INSTRUCTIONS` | none | System instructions string | + +Supported model identifiers (as of the 2026-05-07 OpenAI Realtime API GA): + +| Identifier | When to use | +|---|---| +| `gpt-realtime` | Default. Stable baseline. | +| `gpt-realtime-2` | Recommended for new agents. GPT-5-class reasoning, 128K context. | +| `gpt-realtime-2025-08-28` | Pinned snapshot for `gpt-realtime-2`. Use when you want pinned behavior. | + +Hermes does not validate the value, so any current or future identifier OpenAI +ships will pass straight through. Example: + +```bash +echo 'HERMES_MEET_REALTIME_MODEL=gpt-realtime-2' >> ~/.hermes/.env +hermes meet join https://meet.google.com/abc-defg-hij --mode realtime +``` + ## Remote node host On the node machine (e.g. user's Mac with a signed-in Chrome): diff --git a/plugins/google_meet/SKILL.md b/plugins/google_meet/SKILL.md index 4f009f9d1edc..c1721289faee 100644 --- a/plugins/google_meet/SKILL.md +++ b/plugins/google_meet/SKILL.md @@ -31,6 +31,8 @@ The user says any of: Pick `realtime` only when the user actually wants the agent to speak. It costs real money (OpenAI Realtime is pay-per-audio-minute) and requires a virtual audio device set up on the machine running the bot. +Realtime mode connects to the OpenAI Realtime API. The model is configurable via `HERMES_MEET_REALTIME_MODEL` (default `gpt-realtime`). Set it to `gpt-realtime-2` for the GPT-5-class voice model, or pin to the snapshot `gpt-realtime-2025-08-28` for stable behavior. See `plugins/google_meet/README.md` for the full env-var table. + ## Two locations | Location | When | diff --git a/tests/plugins/test_google_meet_realtime.py b/tests/plugins/test_google_meet_realtime.py index 71d022169372..9e781fbc6765 100644 --- a/tests/plugins/test_google_meet_realtime.py +++ b/tests/plugins/test_google_meet_realtime.py @@ -86,7 +86,8 @@ def _connect(url, **kwargs): # --------------------------------------------------------------------------- -def test_connect_sends_session_update_with_voice_and_instructions(monkeypatch): +@pytest.mark.parametrize("model_id", ["gpt-realtime", "gpt-realtime-2"]) +def test_connect_sends_session_update_with_voice_and_instructions(monkeypatch, model_id): from plugins.google_meet.realtime.openai_client import RealtimeSession ws = _FakeWS(recv_frames=[]) @@ -94,7 +95,7 @@ def test_connect_sends_session_update_with_voice_and_instructions(monkeypatch): sess = RealtimeSession( api_key="sk-test", - model="gpt-realtime", + model=model_id, voice="verse", instructions="Be brief.", ) @@ -102,7 +103,7 @@ def test_connect_sends_session_update_with_voice_and_instructions(monkeypatch): # Auth + beta headers set. assert captured["url"].startswith("wss://api.openai.com/v1/realtime") - assert "model=gpt-realtime" in captured["url"] + assert f"model={model_id}" in captured["url"] headers = captured["headers"] or [] hdict = dict(headers) assert hdict.get("Authorization") == "Bearer sk-test" diff --git a/website/docs/user-guide/features/built-in-plugins.md b/website/docs/user-guide/features/built-in-plugins.md index 7a25ce6b1945..a0456f939326 100644 --- a/website/docs/user-guide/features/built-in-plugins.md +++ b/website/docs/user-guide/features/built-in-plugins.md @@ -207,6 +207,16 @@ The agent kicks off the meeting join, streams the transcription back into its co **When to use it:** recurring standups where you want a bot to transcribe + summarize for async attendees; deposition-style interviews where you want structured notes; any case where you'd otherwise need Fireflies / Otter / Grain. When you'd rather not have an AI listening in — don't enable it. +**Realtime mode (optional):** the bot can speak back into the call via the OpenAI Realtime API when joined with `mode='realtime'` (see `plugins/google_meet/README.md` for the audio bridge setup). The model identifier is configurable: + +| Variable | Default | Purpose | +|---|---|---| +| `HERMES_MEET_REALTIME_MODEL` | `gpt-realtime` | OpenAI Realtime model identifier passed in the WebSocket URL | +| `HERMES_MEET_REALTIME_KEY` | falls back to `OPENAI_API_KEY` | API key for the Realtime WebSocket | +| `HERMES_MEET_REALTIME_VOICE` | `alloy` | Voice id (`alloy`, `verse`, `marin`, `cedar`) | + +Supported model identifiers (as of the 2026-05-07 OpenAI Realtime API GA): `gpt-realtime` (stable baseline), `gpt-realtime-2` (recommended for new agents; GPT-5-class reasoning, 128K context window), and the pinned snapshot `gpt-realtime-2025-08-28`. Hermes does not validate the value, so future identifiers OpenAI ships work without a Hermes upgrade. + **Disabling:** `hermes plugins disable google_meet`. Any cached transcripts and recordings stay in `~/.hermes/cache/google_meet/` until you remove them. ### hermes-achievements