Skip to content
Merged
30 changes: 30 additions & 0 deletions docs/inference/use-google-gemini.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,36 @@ NemoClaw validates the selected provider and model before creating the sandbox.
NemoClaw validates Gemini inference through its OpenAI-compatible Chat Completions path.
When you enter a custom Gemini model ID, NemoClaw checks Google's native model catalog and accepts IDs with or without the `models/` prefix.
It skips the Responses API probe because Gemini does not support `/v1/responses`.
When NemoClaw reads the native Google model catalog, it keeps only models that support `generateContent`.
Embedding-only models are filtered out of the catalog, so they do not appear as onboarding choices.

## Troubleshooting

Model validation can fail with these messages:

- `Could not validate model against https://generativelanguage.googleapis.com/v1beta/models: <reason>`
NemoClaw could not read the Google model catalog.
The `<reason>` value identifies an authentication, network, response, or pagination failure.
Verify `GEMINI_API_KEY`, host access to `generativelanguage.googleapis.com`, and the reported response.
- `Model '<model>' is not available from Google Gemini. Checked https://generativelanguage.googleapis.com/v1beta/models.`
The catalog did not contain the model ID.
This message also appears when the catalog omits `models`, because NemoClaw treats the response as an empty catalog.
Check the ID for typing errors.
Custom IDs can include or omit the `models/` prefix.
Embedding-only models do not appear because they do not support `generateContent`.
- `Unexpected Gemini model catalog response: expected a top-level models array`
The Google model catalog returned a non-null `models` value that is not an array.
Retry the request, then inspect the Google service or proxy response if the error continues.
- `Gemini model catalog pagination repeated page token '<token>'`
The catalog repeated a `nextPageToken`, so NemoClaw stopped reading pages.
Retry the request, then inspect the Google service or proxy response if the error continues.
- `Gemini model catalog pagination exceeded <count> pages`
The catalog exhausted the 25-page `GEMINI_MODEL_CATALOG_MAX_PAGES` limit.
Retry the request, then inspect the Google service or proxy response if the error continues.
- `Onboard inference smoke check failed.`
The validation request failed.
The output shows the provider, model, and API base URL.
Compare these values with your configuration.

## Related Topics

Expand Down
72 changes: 72 additions & 0 deletions src/lib/inference/provider-models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,78 @@ describe("provider model helpers", () => {
});
});

it("reports an unavailable Gemini model when the catalog omits models (#8971)", () => {
const result = validateOpenAiLikeModel(
"Google Gemini",
"https://generativelanguage.googleapis.com/v1beta/openai/",
"gemini-2.5-flash",
"AIzaFakeKey123",
{
runCurlProbeImpl: () => ({
ok: true,
httpStatus: 200,
curlStatus: 0,
body: JSON.stringify({}),
stderr: "",
message: "",
}),
},
);

expect(result).toEqual({
ok: false,
httpStatus: 200,
curlStatus: 0,
message: `Model 'gemini-2.5-flash' is not available from Google Gemini. Checked ${GEMINI_NATIVE_MODELS_ENDPOINT_URL}.`,
});
});

it("reports an unavailable Gemini model when the catalog models value is null (#8971)", () => {
const result = validateOpenAiLikeModel(
"Google Gemini",
"https://generativelanguage.googleapis.com/v1beta/openai/",
"gemini-2.5-flash",
"AIzaFakeKey123",
{
runCurlProbeImpl: () => ({
ok: true,
httpStatus: 200,
curlStatus: 0,
body: JSON.stringify({ models: null }),
stderr: "",
message: "",
}),
},
);

expect(result).toEqual({
ok: false,
httpStatus: 200,
curlStatus: 0,
message: `Model 'gemini-2.5-flash' is not available from Google Gemini. Checked ${GEMINI_NATIVE_MODELS_ENDPOINT_URL}.`,
});
});

it("rejects a Gemini catalog whose models value is not an array (#8971)", () => {
const result = fetchGeminiModels("AIzaFakeKey123", {
runCurlProbeImpl: () => ({
ok: true,
httpStatus: 200,
curlStatus: 0,
body: JSON.stringify({ models: {} }),
stderr: "",
message: "",
}),
});

expect(result).toEqual({
ok: false,
httpStatus: 200,
curlStatus: 0,
message: "Unexpected Gemini model catalog response: expected a top-level models array",
});
});

it("fails Gemini native catalog pagination after the bounded page budget (#6975)", () => {
const requestedUrls: string[] = [];

Expand Down
Loading