Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/_common/agents/remember-to-disconnect.mdx
Original file line number Diff line number Diff line change
@@ -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.
:::
49 changes: 48 additions & 1 deletion docs/integrations/gemini-live-integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
:::

Expand Down Expand Up @@ -278,3 +278,50 @@ Fishjam handles raw bytes, while Google GenAI SDKs often expect Base64 strings.

</TabItem>
</Tabs>

## 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.
Original file line number Diff line number Diff line change
@@ -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.
:::
Original file line number Diff line number Diff line change
Expand Up @@ -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.
:::

Expand Down
2 changes: 1 addition & 1 deletion versioned_docs/version-0.26.0/tutorials/livestreaming.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
:::
Original file line number Diff line number Diff line change
Expand Up @@ -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.
:::

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
:::
Original file line number Diff line number Diff line change
Expand Up @@ -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.
:::

Expand Down
Loading