# llm-gemini [![PyPI](https://img.shields.io/pypi/v/llm-gemini.svg)](https://pypi.org/project/llm-gemini/) [![Changelog](https://img.shields.io/github/v/release/simonw/llm-gemini?include_prereleases&label=changelog)](https://github.com/simonw/llm-gemini/releases) [![Tests](https://github.com/simonw/llm-gemini/workflows/Test/badge.svg)](https://github.com/simonw/llm-gemini/actions?query=workflow%3ATest) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/simonw/llm-gemini/blob/main/LICENSE) API access to Google's Gemini models ## Installation Install this plugin in the same environment as [LLM](https://llm.datasette.io/). ```bash llm install llm-gemini ``` ## Usage Configure the model by setting a key called "gemini" to your [API key](https://aistudio.google.com/app/apikey): ```bash llm keys set gemini ``` ``` ``` You can also set the API key by assigning it to the environment variable `LLM_GEMINI_KEY`. Now run the model using `-m gemini-flash-latest`, for example: ```bash llm -m gemini-flash-latest "A short joke about a pelican and a walrus" ``` > A pelican and a walrus are sitting at a bar. The pelican orders a fishbowl cocktail, and the walrus orders a plate of clams. The bartender asks, "So, what brings you two together?" > > The walrus sighs and says, "It's a long story. Let's just say we met through a mutual friend... of the fin." You can set the [default model](https://llm.datasette.io/en/stable/setup.html#setting-a-custom-default-model) to avoid the extra `-m` option: ```bash llm models default gemini-flash-latest llm "A joke about a pelican and a walrus" ``` ## Available models - `gemini/gemini-4-argon`: Gemini 4 Argon - `gemini/gemini-3.8-flash`: Gemini 3.8 Flash - `gemini/gemini-3.7-flash`: Gemini 3.7 Flash - `gemini/gemini-3.5-flash-lite`: Gemini 3.5 Flash Lite - `gemini/gemini-3.6-flash`: Gemini 3.6 Flash - `gemini/gemini-3.5-flash`: Gemini 3.5 Flash - `gemini/gemini-3.1-flash-lite`: Gemini 3.1 Flash Lite - `gemini/gemma-4-31b-it`: Gemma 4 31B Instruct - `gemini/gemma-4-26b-a4b-it`: Gemma 4 26B-A4B Instruct - `gemini/gemini-3.1-flash-lite-preview`: Gemini 3.1 Flash Lite Preview - `gemini/gemini-3.1-pro-preview-customtools` - `gemini/gemini-3.1-pro-preview`: Gemini 3.1 Pro Preview - `gemini/gemini-3-flash-preview`: Gemini 3 Flash Preview - `gemini/gemini-flash-lite-latest`: Latest Gemini Flash Lite - `gemini/gemini-flash-latest`: Latest Gemini Flash - `gemini/gemini-2.5-flash`: Gemini 2.5 Flash All of these models have aliases that omit the `gemini/` prefix, for example: ```bash llm -m gemini-flash-latest --schema 'name,age int,bio' 'invent a dog' ``` ### Images, audio and video Gemini models are multi-modal. You can provide images, audio or video files as input like this: ```bash llm -m gemini-flash-latest 'extract text' -a image.jpg ``` Or with a URL: ```bash llm -m gemini-flash-latest 'describe image' \ -a https://static.simonwillison.net/static/2024/pelicans.jpg ``` Audio works too: ```bash llm -m gemini-flash-latest 'transcribe audio' -a audio.mp3 ``` And video: ```bash llm -m gemini-flash-latest 'describe what happens' -a video.mp4 ``` The Gemini prompting guide includes [extensive advice](https://ai.google.dev/gemini-api/docs/file-prompting-strategies) on multi-modal prompting. ### YouTube videos You can provide YouTube video URLs as attachments as well: ```bash llm -m gemini-flash-latest -a 'https://www.youtube.com/watch?v=9o1_DL9uNlM' \ 'Produce a summary with relevant URLs and code example snippets, then an accurate transcript with timestamps.' ``` [Example output here](https://gist.github.com/simonw/1b07aafb2bfc112b180ab68c864511cb). These will be processed with media resolution `low` by default. You can use the `-o media_resolution X` option to set that to `medium`, `high`, or `unspecified`. ### JSON output Use `-o json_object 1` to force the output to be JSON: ```bash llm -m gemini-flash-latest -o json_object 1 \ '3 largest cities in California, list of {"name": "..."}' ``` Outputs: ```json {"cities": [{"name": "Los Angeles"}, {"name": "San Diego"}, {"name": "San Jose"}]} ``` ### Thinking Gemini 3 and later models support a [thinking level](https://ai.google.dev/gemini-api/docs/thinking) that controls how much reasoning the model does before it responds. Set it with `-o thinking_level X`: ```bash llm -m gemini-4-argon -o thinking_level high \ 'Prove that there are infinitely many primes' ``` The supported levels vary by model. If you don't set a level the model uses its own default. | Model | Thinking levels | | --- | --- | | `gemini-3-flash-preview` | `minimal`, `low`, `medium`, `high` | | `gemini-3.1-pro-preview` | `low`, `medium`, `high` | | `gemini-3.1-pro-preview-customtools` | `low`, `medium`, `high` | | `gemini-3.1-flash-lite-preview` | `minimal`, `low`, `medium`, `high` | | `gemini-3.1-flash-lite` | `minimal`, `low`, `medium`, `high` | | `gemini-3.5-flash` | `minimal`, `low`, `medium`, `high` | | `gemini-3.6-flash` | `minimal`, `low`, `medium`, `high` | | `gemini-3.7-flash` | `low`, `medium`, `high` | | `gemini-3.8-flash` | `low`, `medium`, `high` | | `gemini-3.5-flash-lite` | `minimal`, `low`, `medium`, `high` | | `gemini-4-argon` | `low`, `medium`, `high` | The `gemini-2.5-flash`, `gemini-flash-latest` and `gemini-flash-lite-latest` models instead take a thinking budget in tokens, using `-o thinking_budget X`. Set it to `0` to disable thinking. ### Code execution Gemini models can [write and execute code](https://ai.google.dev/gemini-api/docs/code-execution) - they can decide to write Python code, execute it in a secure sandbox and use the result as part of their response. Enable this server-side tool with `-T CodeExecution`: ```bash llm -m gemini-3.6-flash -T CodeExecution \ 'use python to calculate (factorial of 13) * 3' ``` ### Google search Some Gemini models support [Grounding with Google Search](https://ai.google.dev/gemini-api/docs/google-search), where the model can run a Google search and use the results as part of answering a prompt. Using this feature may incur additional requirements in terms of how you use the results. Consult [Google's documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/ground-gemini#web-ground-gemini) for more details. Enable this server-side tool with `-T GoogleSearch`: ```bash llm -m gemini-3.6-flash -T GoogleSearch \ 'What happened in Ireland today?' ``` The plugin leaves the model's response text unchanged and retains Gemini's raw `groundingMetadata` on the response part. Use `llm logs -c --json` after running a prompt to inspect that metadata, which includes [additional information](https://github.com/simonw/llm-gemini/pull/29#issuecomment-2606201877) about grounded results. When Gemini returns native server-side tool invocation parts, the plugin exposes those as structured server-side tool call and result events as well. ### URL context Gemini models support a [URL context](https://ai.google.dev/gemini-api/docs/url-context) tool which, when enabled, allows the models to fetch additional content from URLs as part of their execution. Enable this server-side tool with `-T URLContext` - for example: ```bash llm -m gemini-2.5-flash -T URLContext 'Latest headline on simonwillison.net' ``` Extra tokens introduced by this tool will be charged as input tokens. Use `--usage` to see details of those: ```bash llm -m gemini-2.5-flash -T URLContext --usage \ 'Latest headline on simonwillison.net' ``` Outputs: ``` The latest headline on simonwillison.net as of August 17, 2025, is "TIL: Running a gpt-oss eval suite against LM Studio on a Mac.". Token usage: 9,613 input, 87 output, {"candidatesTokenCount": 57, "promptTokensDetails": [{"modality": "TEXT", "tokenCount": 10}], "toolUsePromptTokenCount": 9603, "toolUsePromptTokensDetails": [{"modality": "TEXT", "tokenCount": 9603}], "thoughtsTokenCount": 30} ``` The `"toolUsePromptTokenCount"` key shows how many tokens were used for that URL context. ### Chat To chat interactively with the model, run `llm chat`: ```bash llm chat -m gemini-flash-latest ``` ### Timeouts By default there is no `timeout` against the Gemini API. You can use the `timeout` option to protect against API requests that hang indefinitely. With the CLI tool that looks like this, to set a 1.5 second timeout: ```bash llm -m gemini-flash-latest 'epic saga about mice' -o timeout 1.5 ``` In the Python library timeouts are used like this: ```python import httpx, llm model = llm.get_model("gemini/gemini-flash-latest") try: response = model.prompt( "epic saga about mice", timeout=1.5 ) print(response.text()) except httpx.TimeoutException: print("Timeout exceeded") ``` An `httpx.TimeoutException` subclass will be raised if the timeout is exceeded. ## Embeddings The plugin supports Google's current [Gemini embedding models](https://ai.google.dev/gemini-api/docs/embeddings): - `gemini-embedding-2` is the latest model. - `gemini-embedding-001` remains available for text-only use cases. Run that against a single string like this: ```bash llm embed -m gemini-embedding-2 -c 'hello world' ``` This returns a JSON array of 3072 numbers. Both models have variants that ask Gemini to return its recommended smaller vector sizes of 768 or 1536 dimensions, specified as a suffix on the model ID: - `gemini-embedding-2` - 3072 numbers - `gemini-embedding-2-1536` - 1536 numbers - `gemini-embedding-2-768` - 768 numbers - `gemini-embedding-001` - 3072 numbers - `gemini-embedding-001-1536` - 1536 numbers - `gemini-embedding-001-768` - 768 numbers The embedding spaces used by the two models are incompatible. If you switch an existing collection from `gemini-embedding-001` to `gemini-embedding-2`, you must re-embed all of its content. This command will embed every `README.md` file in child directories of the current directory and store the results in a SQLite database called `embed.db` in a collection called `readmes`: ```bash llm embed-multi readmes -d embed.db -m gemini-embedding-2-768 \ --files . '*/README.md' ``` You can then run similarity searches against that collection like this: ```bash llm similar readmes -c 'upload csvs to stuff' -d embed.db ``` See the [LLM embeddings documentation](https://llm.datasette.io/en/stable/embeddings/cli.html) for further details. ## Listing all Gemini API models The `llm gemini models` command lists all of the models that are exposed by the Gemini API, some of which may not be available through this plugin. ```bash llm gemini models ``` You can add a `--key X` option to use a different API key. To filter models by their supported generation methods use `--method` one or more times: ```bash llm gemini models --method embedContent ``` If you provide multiple methods you will see models that support any of them. ## Development To set up this plugin locally, first checkout the code, then run the tests with `uv`: ```bash cd llm-gemini uv run pytest ``` Run `llm` with the plugin like this: ```bash uv run llm models -q gemini ``` This project uses [pytest-recording](https://github.com/kiwicom/pytest-recording) to record Gemini API responses for the tests. If you add a new test that calls the API you can capture the API response like this: ```bash PYTEST_GEMINI_API_KEY="$(llm keys get gemini)" uv run pytest --record-mode once ``` You will need to have stored a valid Gemini API key using this command first: ```bash llm keys set gemini # Paste key here ```