Loading...
Loading...
Use when the user runs /add-voice, types Voice Mode, or asks to add Grok realtime voice to an app, including replacing an STT-LLM-TTS cascade or OpenAI Realtime. Wire speech-to-speech, safe auth, and app mic. Composer: waveform button, mic icon reserved for dictation. For mic-to-text only use /add-dictation; to speak text replies use /add-read-aloud. To add debug logging and fix from logs use /debug-voice.
npx skill4agent add cursor/plugins add-voice/add-voicewss://api.x.ai/v1/realtime?model=grok-voice-latestwswebsockets/v1/stt/v1/ttsXAI_API_KEYPOST https://api.x.ai/v1/realtime/client_secretssec-websocket-protocolxai-client-secret.<token>wss://api.x.ai/v1/realtime?model=grok-voice-latestsession.updatevoiceeveinstructionsturn_detection: { type: "server_vad" }nullaudio.input.transcription.model: "grok-transcribe"conversation.item.input_audio_transcription.updatedweb_searchx_searchfile_searchmcpfunctionAudioContextinput_audio_buffer.appendresponse.output_audio.deltainput_audio_buffer.speech_startedinput_audio_buffer.committeditem_id…transcription.updatedresponse.output_audio_transcript.delta.doneresponse.donefunction_call_outputresponse.createWaveformIcon weight="bold"fillconversation.item.createresponse.createprefers-reduced-motionConnecting…Listening…Thinking…Speaking…sr-onlyrole="status"/add-dictationconst url = "wss://api.x.ai/v1/realtime?model=grok-voice-latest";
// Node: pass Authorization header. Browser: use xai-client-secret.<token> protocol.
const ws = new WebSocket(url /* , { headers: { Authorization: `Bearer ${token}` } } */);
ws.addEventListener("open", () => {
ws.send(JSON.stringify({
type: "session.update",
session: {
voice: "eve",
instructions: "You are a helpful voice agent.",
turn_detection: { type: "server_vad" },
},
}));
});
ws.addEventListener("message", (ev) => {
const event = JSON.parse(String(ev.data));
if (event.type === "response.output_audio.delta") {
// decode base64 PCM and play
}
});import json, os, websockets
url = "wss://api.x.ai/v1/realtime?model=grok-voice-latest"
headers = {"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"}
async with websockets.connect(url, additional_headers=headers) as ws:
await ws.send(json.dumps({
"type": "session.update",
"session": {
"voice": "eve",
"instructions": "You are a helpful voice agent.",
"turn_detection": {"type": "server_vad"},
},
}))
async for raw in ws:
event = json.loads(raw)
if event.get("type") == "response.output_audio.delta":
pass # decode and play/debug-voicePOST /api/voice/log.voice-logs/<sessionId>.ndjsonconversation.item.createresponse.createclient_secrets/debug-voice/add-dictation/add-read-aloud