diff --git a/docs/_common/agents/remember-to-disconnect.mdx b/docs/_common/agents/remember-to-disconnect.mdx index 4960eed1..d1a45cd5 100644 --- a/docs/_common/agents/remember-to-disconnect.mdx +++ b/docs/_common/agents/remember-to-disconnect.mdx @@ -1,3 +1,3 @@ -:::danger Remember to disconnect your agents! +:::danger[Remember to disconnect your agents!] It's important to disconnect agents, because **every connected agent generates usage** just as a normal peer. ::: diff --git a/docs/integrations/gemini-live-integration.mdx b/docs/integrations/gemini-live-integration.mdx index bc0f138f..a871db1e 100644 --- a/docs/integrations/gemini-live-integration.mdx +++ b/docs/integrations/gemini-live-integration.mdx @@ -152,7 +152,7 @@ Create a Fishjam agent configured to match the audio format that the Google clie ### Step 3: Connect the Streams -:::warning Encoding +:::warning[Encoding] Fishjam handles raw bytes, while Google GenAI SDKs often expect Base64 strings. Ensure you convert between them correctly as shown below. ::: @@ -278,3 +278,50 @@ Fishjam handles raw bytes, while Google GenAI SDKs often expect Base64 strings. + +## Troubleshooting Gemini API keys + +If your agent joins the room but silently does nothing — no audio, no transcription, and no error — the problem is almost always the Gemini API key. + +:::warning[API key errors surface asynchronously] +`createClient` is a thin synchronous wrapper around Google's `GoogleGenAI` and makes no network call, so an invalid or unauthorized key is **not** rejected when you create the client. The key is only exercised later, when `live.connect()` opens the Live websocket. Authentication and access failures then typically surface through the Live session callbacks (`onerror` / `onclose`) rather than as a thrown exception. (Other problems, such as a malformed config, can still reject the awaited `connect()` call — keep a `try/catch` around it too.) +::: + +Always implement the `onerror` and `onclose` callbacks and log the close code and reason. That is where the real error message appears: + +```ts +import GeminiIntegration from "@fishjam-cloud/js-server-sdk/gemini"; +import { Modality, type LiveServerMessage } from "@google/genai"; + +const genAi = GeminiIntegration.createClient({ + apiKey: process.env.GOOGLE_API_KEY!, +}); +const GEMINI_MODEL = "gemini-2.5-flash-native-audio-preview-12-2025"; +const handleMessage = (msg: LiveServerMessage) => {}; + +// ---cut--- +const session = await genAi.live.connect({ + model: GEMINI_MODEL, + config: { responseModalities: [Modality.AUDIO] }, + callbacks: { + onopen: () => console.log("Gemini Live connected"), + onerror: (e) => console.error("Gemini Live error:", e), + onclose: (e) => + console.error(`Gemini Live closed: code=${e.code} reason=${e.reason}`), + onmessage: handleMessage, + }, +}); +``` + +### Common reasons a key doesn't work + +- Wrong or mistyped key, or a key from the wrong Google Cloud project. +- The Gemini API is not enabled for the key's project. +- Region or country restriction — the Gemini API (or its free tier) is not available in your region. +- Model-specific rejection. The native-audio Live models (e.g. `gemini-2.5-flash-native-audio-preview-*`) can reject an otherwise-valid key: the websocket closes with code `1008` and the message _"Your API key was reported as leaked. Please use another API key."_ (even when the key is not actually leaked), or with code `1011` internal errors. A key that works for other models can still fail here. + +### How to fix + +- Verify or regenerate your key at [Google AI Studio](https://aistudio.google.com/app/apikey). +- Confirm the Gemini API is enabled for the key's project and that your region is supported. +- If you see the `1008` "leaked" message, rotate to a freshly generated key. diff --git a/versioned_docs/version-0.26.0/_common/agents/remember-to-disconnect.mdx b/versioned_docs/version-0.26.0/_common/agents/remember-to-disconnect.mdx index 4960eed1..d1a45cd5 100644 --- a/versioned_docs/version-0.26.0/_common/agents/remember-to-disconnect.mdx +++ b/versioned_docs/version-0.26.0/_common/agents/remember-to-disconnect.mdx @@ -1,3 +1,3 @@ -:::danger Remember to disconnect your agents! +:::danger[Remember to disconnect your agents!] It's important to disconnect agents, because **every connected agent generates usage** just as a normal peer. ::: diff --git a/versioned_docs/version-0.26.0/integrations/gemini-live-integration.mdx b/versioned_docs/version-0.26.0/integrations/gemini-live-integration.mdx index 33518a1e..139b6533 100644 --- a/versioned_docs/version-0.26.0/integrations/gemini-live-integration.mdx +++ b/versioned_docs/version-0.26.0/integrations/gemini-live-integration.mdx @@ -152,7 +152,7 @@ Create a Fishjam agent configured to match the audio format that the Google clie ### Step 3: Connect the Streams -:::warning Encoding +:::warning[Encoding] Fishjam handles raw bytes, while Google GenAI SDKs often expect Base64 strings. Ensure you convert between them correctly as shown below. ::: diff --git a/versioned_docs/version-0.26.0/tutorials/livestreaming.mdx b/versioned_docs/version-0.26.0/tutorials/livestreaming.mdx index a160ea3e..b00a9388 100644 --- a/versioned_docs/version-0.26.0/tutorials/livestreaming.mdx +++ b/versioned_docs/version-0.26.0/tutorials/livestreaming.mdx @@ -21,7 +21,7 @@ In this tutorial we explain how to publish and view streams with the client SDKs If you prefer to use WHIP or WHEP directly, then you should read [WHIP/WHEP with Fishjam](../how-to/backend/whip-whep). ::: -:::info Cost-effective audio livestreams +:::info[Cost-effective audio livestreams] Fishjam supports audio-only livestreams at a reduced cost of $0.20 per 1000 minutes of the streamer and each listener (compared to $0.80 for video livestreams). This is ideal for podcasts, radio-style broadcasts, or any scenario where video isn't necessary. See [Audio-only calls](../how-to/backend/audio-only-calls) for more information. diff --git a/versioned_docs/version-0.27.0/_common/agents/remember-to-disconnect.mdx b/versioned_docs/version-0.27.0/_common/agents/remember-to-disconnect.mdx index 4960eed1..d1a45cd5 100644 --- a/versioned_docs/version-0.27.0/_common/agents/remember-to-disconnect.mdx +++ b/versioned_docs/version-0.27.0/_common/agents/remember-to-disconnect.mdx @@ -1,3 +1,3 @@ -:::danger Remember to disconnect your agents! +:::danger[Remember to disconnect your agents!] It's important to disconnect agents, because **every connected agent generates usage** just as a normal peer. ::: diff --git a/versioned_docs/version-0.27.0/integrations/gemini-live-integration.mdx b/versioned_docs/version-0.27.0/integrations/gemini-live-integration.mdx index 33518a1e..139b6533 100644 --- a/versioned_docs/version-0.27.0/integrations/gemini-live-integration.mdx +++ b/versioned_docs/version-0.27.0/integrations/gemini-live-integration.mdx @@ -152,7 +152,7 @@ Create a Fishjam agent configured to match the audio format that the Google clie ### Step 3: Connect the Streams -:::warning Encoding +:::warning[Encoding] Fishjam handles raw bytes, while Google GenAI SDKs often expect Base64 strings. Ensure you convert between them correctly as shown below. ::: diff --git a/versioned_docs/version-0.28.0/_common/agents/remember-to-disconnect.mdx b/versioned_docs/version-0.28.0/_common/agents/remember-to-disconnect.mdx index 4960eed1..d1a45cd5 100644 --- a/versioned_docs/version-0.28.0/_common/agents/remember-to-disconnect.mdx +++ b/versioned_docs/version-0.28.0/_common/agents/remember-to-disconnect.mdx @@ -1,3 +1,3 @@ -:::danger Remember to disconnect your agents! +:::danger[Remember to disconnect your agents!] It's important to disconnect agents, because **every connected agent generates usage** just as a normal peer. ::: diff --git a/versioned_docs/version-0.28.0/integrations/gemini-live-integration.mdx b/versioned_docs/version-0.28.0/integrations/gemini-live-integration.mdx index bc0f138f..43a0eeca 100644 --- a/versioned_docs/version-0.28.0/integrations/gemini-live-integration.mdx +++ b/versioned_docs/version-0.28.0/integrations/gemini-live-integration.mdx @@ -152,7 +152,7 @@ Create a Fishjam agent configured to match the audio format that the Google clie ### Step 3: Connect the Streams -:::warning Encoding +:::warning[Encoding] Fishjam handles raw bytes, while Google GenAI SDKs often expect Base64 strings. Ensure you convert between them correctly as shown below. :::