Skip to main content

llm_gemini 0.7.0 copy "llm_gemini: ^0.7.0" to clipboard
llm_gemini: ^0.7.0 copied to clipboard

Google Gemini API backend for LLM interactions. Provides streaming chat, embeddings, and tool calling via the Gemini API.

Changelog #

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased] #

0.7.0 - 2026-09-22 #

Added #

  • LLMUsage.cachedTokens from total_cached_tokens. It stays on providerMetadata as well.

Fixed #

  • service_unavailable, the code Google actually sends when a model is over capacity, was not in the symbolic status map — only the gRPC spelling UNAVAILABLE was — so a mid-stream capacity failure carried no status and could never be classified as retryable.
  • RetryConfig.retryableStatusCodes never applied to streaming requests. A non-2xx arrives as a returned response rather than a thrown error, so the retry around the send never saw it and a 429 or 503 from Google failed on the first attempt.
  • A failure reported in-band — 200, then an error event on the stream — was not retried either, because it arrives after the send has returned. Both are now re-issued while nothing has reached the caller.
  • Cancelling a streamChat subscription aborts the request.

Changed #

  • A function_result's name is read from LLMMessage.toolName, falling back to status.
  • All packages bumped to 0.7.0; llm_core constraint updated to ^0.7.0.

0.6.0 - 2026-09-17 #

Fixed #

  • Argument fragments that did not decode were silently replaced with {}, so the tool ran without arguments. Such calls are now returned in invalidToolCalls.

0.5.0 - 2026-09-11 #

Fixed #

  • An interaction truncated at max_output_tokens reported LLMFinishReason.toolCalls when it had produced function-call steps, hiding the truncation behind a call whose arguments may stop mid-JSON. Truncated interactions now report length.

Changed #

  • The tool-call classification this package already applied is now the shared LLMFinishReason.resolve rule from llm_core, so every backend behaves the same way.

0.4.0 - 2026-08-30 #

Fixed #

  • Mid-stream error codes are mapped to an HTTP status even when they are not numeric. A live free-tier quota failure reports "quota_exceeded" as a string, which read as a number left statusCode null — and retry classification works off the status, so a mid-stream quota or capacity error was never recognized as retryable. Numeric codes, numeric strings and Google's symbolic statuses are all handled.

Added #

  • Streaming tool calls surface as they arrive on LLMChunkMessage.toolCallDeltas. The Interactions API reports the tool in step.start before any argument fragment, and those fragments were already parsed but never surfaced.
  • extraHeaders on GeminiChatRepository and its builder. Protocol headers and x-goog-api-key always take precedence.

0.3.2 - 2026-08-18 #

Changed #

  • Version bumped to 0.3.2 in lockstep with the other packages, and the llm_core constraint raised to ^0.3.2. No other changes to this package.

0.3.1 - 2026-08-18 #

Added #

  • example/ — a CLI example and README, matching the other backend packages.

Fixed #

  • streamChat applies a timeout to the send operation. It previously opted out, so a request that wedged before response headers arrived never recovered.
  • The default HTTP client is now createLLMHttpClient(), which applies TimeoutConfig.connectionTimeout and bounds the connection pool.

Changed #

  • Documented default model is gemini-3.5-flash-lite; the previously referenced gemini-3.1-flash-lite does not exist in Google's model list.
  • Dependency floors raised: Dart SDK ^3.12.0 (was ^3.8.0), http ^1.6.0, lints ^6.1.0, test ^1.31.0.

0.3.0 - 2026-08-17 #

Added #

  • reasoningEffort maps to thinking_level (wins over the budget mapping).
  • Thought-token usage surfaced as LLMUsage.reasoningTokens.

Fixed #

  • Migrated to the Interactions API's steps-based input format (user_input/ model_output/function_call steps) — the old turn-based format is now rejected by the live API.
  • Tool loops echo the model's thought signature (required by the API), carried through the tool-call id.
  • Structured output sends the JSON schema inline; the json_schema wrapper type is rejected by the live API.
  • think: false sent thinking_summaries: 'off', which the live API rejects with a 400; it now sends 'none'.
  • Empty user messages sent an empty text block (a 400); now a single-space block, the only shape the API accepts for a degenerate empty message.

0.2.0 - 2026-08-12 #

Initial release of the Google Gemini backend for the dart-llm ecosystem.

Added #

  • GeminiChatRepository — streaming chat via the Interactions API (POST /v1beta/interactions). Google labels the older generateContent endpoint legacy, so this package targets Interactions from the outset. Requests carry model, input, stream, store, tools, response_format, and generation_config; responses are parsed from interaction.created, step.start, step.delta, step.stop, and interaction.completed events.
  • The API key is sent in the x-goog-api-key header, for chat and embeddings alike — never appended to the URL as key=…, where it would leak into logs, proxies, and crash reports.
  • Stateless by default: requests send store: false and serialize the whole conversation into input as role-tagged turns, matching LLMChatRepository's stateless contract. Server-side continuation is opt-in via backendOptions['previous_interaction_id'].
  • Tool/function calling with automatic tool-loop execution (autoExecuteTools: true). Declarations are sent as a flat tools array of {"type": "function", "name", "description", "parameters"} entries. Tool calls carry the server-provided call id, and argument JSON is assembled by concatenating arguments_delta fragments.
  • Thinking, with thought_summary deltas populating LLMChunkMessage.thinking and text deltas populating LLMChunkMessage.content — the two are kept separate rather than reasoning being emitted as ordinary assistant output. LLMChatOptions.reasoningBudget maps onto the discrete generation_config.thinking_level (minimal/low/medium/high); the Interactions API has no raw token budget. Override with backendOptions['thinking_level'].
  • thought_signature values are accumulated per step index and surfaced via LLMChunk.providerMetadata['thought_signatures'].
  • Structured output via LLMChatOptions.responseFormat, mapped onto the response_format array. Standard lowercase JSON Schema is forwarded unchanged. Propagated through tool-call loops so the constraint holds across every turn.
  • Embeddings via embed() and batchEmbed() (embedContent / batchEmbedContents).
  • Usage mapping for the Interactions field names (total_tokens, total_input_tokens, total_output_tokens, total_cached_tokens, total_thought_tokens, total_tool_use_tokens); thought, cached and total counts are surfaced through LLMChunk.providerMetadata alongside interaction_id.
  • GeminiChatRepository.builder() for fluent configuration, with retry, timeout, rate limiting, response cache, and metrics support.

Notes #

  • topP, topK and stopSequences are not sent: the Interactions generation_config documents no equivalent. Pass them through backendOptions['generation_config'] if your account supports them.
  • Defaults and docs use gemini-3.5-flash-lite. The gemini-3.1-flash-lite id referenced during development does not appear in Google's published model list.

Verification status #

This package has not been exercised against the live Gemini API — there was no API key available. Coverage is unit tests asserting the serialized request body and parsed stream events; the integration suites are key-gated and unrun.

Two shapes are inferred from prose rather than read from a specification and are the first things to check if requests fail with HTTP 400:

  • The role-tagged input turn envelope ({"role": "user"|"model", "content": [ … ]}), together with the text, function_call and image input blocks and the placement of function_result blocks on a user turn. All of this is confined to GeminiMessageConverter.buildStatelessInput, which documents each assumption individually.
  • The response_format element shape ([{"type": "json_object"}] / [{"type": "json_schema", "name", "schema"}]); only the fact that it is an array is documented.

Known limitation: thought_signature values are surfaced on the response, but Google documents no input block for echoing them back, so multi-turn function calling may still hit "Function call is missing a thought_signature".

0
likes
160
points
390
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Google Gemini API backend for LLM interactions. Provides streaming chat, embeddings, and tool calling via the Gemini API.

Repository (GitHub)
View/report issues
Contributing

Topics

#google #gemini #llm #ai #embeddings

License

MIT (license)

Dependencies

http, llm_core

More

Packages that depend on llm_gemini