# Python 3.11+: pip install 'websockets>=14,<16'
import asyncio, json, os
from websockets.asyncio.client import connect
async def main():
async with asyncio.timeout(120):
async with connect("wss://api.tu-zi.com/v1beta/live?model=YOUR_MODEL", additional_headers={
'Authorization': "Bearer " + os.environ["API_KEY"]
}, max_size=2*1024*1024, max_queue=4, compression=None) as ws:
completed = sent = received_output = False
await ws.send("{\"setup\":{\"model\":\"models/YOUR_MODEL\",\"generationConfig\":{\"responseModalities\":[\"AUDIO\"]}}}")
async for message in ws:
event = json.loads(message)
if 'error' in event:
raise RuntimeError(event['error'])
if 'setupComplete' in event and not sent:
sent = True
await ws.send("{\"clientContent\":{\"turns\":[{\"role\":\"user\",\"parts\":[{\"text\":\"Say hello briefly.\"}]}],\"turnComplete\":true}}")
content = event.get('serverContent', {})
if content.get('interrupted'):
raise RuntimeError('Turn was interrupted; no complete result')
text = content.get('outputTranscription', {}).get('text', '')
if text:
received_output = True
print(text, end='', flush=True)
# Consume content.modelTurn.parts[].inlineData for PCM audio.
if any(part.get('inlineData', {}).get('data') or part.get('text') for part in content.get('modelTurn', {}).get('parts', [])):
received_output = True
if content.get('turnComplete'):
if not sent or not received_output:
raise RuntimeError('Turn ended without model output')
completed = True
print(event.get('usageMetadata', {}))
break
if not completed:
raise RuntimeError('Connection closed before a complete turn')
asyncio.run(main())
// Node.js: npm install ws
import WebSocket from 'ws';
const ws = new WebSocket("wss://api.tu-zi.com/v1beta/live?model=YOUR_MODEL", {
headers: { Authorization: "Bearer " + process.env.API_KEY },
perMessageDeflate: false,
maxPayload: 2 * 1024 * 1024,
});
let completed = false, sent = false, receivedOutput = false, failed = false;
function fail(error) {
if (failed) return;
failed = true;
console.error(error);
process.exitCode = 1;
ws.terminate();
}
const timeout = setTimeout(() => fail(new Error('Timed out before a complete turn')), 120000);
ws.on('close', () => {
clearTimeout(timeout);
if (!completed && !failed) fail(new Error('Connection closed before a complete turn'));
});
ws.on('error', fail);
ws.on('open', () => ws.send(JSON.stringify({
"setup": {
"model": "models/YOUR_MODEL",
"generationConfig": {
"responseModalities": [
"AUDIO"
]
}
}
})));
ws.on('message', (message) => {
if (failed || completed) return;
try {
const event = JSON.parse(message.toString());
if (event.error) throw new Error(JSON.stringify(event.error));
if (event.setupComplete && !sent) {
sent = true;
ws.send(JSON.stringify({"clientContent":{"turns":[{"role":"user","parts":[{"text":"Say hello briefly."}]}],"turnComplete":true}}));
}
const content = event.serverContent || {};
if (content.interrupted) throw new Error('Turn was interrupted; no complete result');
const text = content.outputTranscription?.text;
if (text) { receivedOutput = true; process.stdout.write(text); }
// Consume content.modelTurn.parts[].inlineData for PCM audio.
if (content.modelTurn?.parts?.some(part => part.inlineData?.data || part.text)) receivedOutput = true;
if (content.turnComplete) {
if (!sent || !receivedOutput) throw new Error('Turn ended without model output');
completed = true;
console.log(event.usageMetadata);
ws.close();
}
} catch (error) { fail(error); }
});