Universal.Operative.Sdk.GoogleGemini 1.2.0

dotnet add package Universal.Operative.Sdk.GoogleGemini --version 1.2.0
                    
NuGet\Install-Package Universal.Operative.Sdk.GoogleGemini -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Universal.Operative.Sdk.GoogleGemini" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Universal.Operative.Sdk.GoogleGemini" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Universal.Operative.Sdk.GoogleGemini" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Universal.Operative.Sdk.GoogleGemini --version 1.2.0
                    
#r "nuget: Universal.Operative.Sdk.GoogleGemini, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Universal.Operative.Sdk.GoogleGemini@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Universal.Operative.Sdk.GoogleGemini&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Universal.Operative.Sdk.GoogleGemini&version=1.2.0
                    
Install as a Cake Tool

About

Universal.Operative.Sdk.GoogleGemini plugs Google's Gemini models into Universal.Operative.Sdk via an IModel adapter (Model) backed by the Universal.Google.Gemini.Client transport (Gemini's v1beta REST/SSE API).

How to Use

Installation

dotnet add package Universal.Operative.Sdk.GoogleGemini

Configuration

using Universal.Operative.Sdk;
using Universal.Operative.Sdk.GoogleGemini;

IModel model = new Model(apiKey, new Model.Options
{
    ModelId = Models.Gemini35Flash,
    MaxOutputTokens = 4096,
});

The constructor also accepts an existing Universal.Google.Gemini.Client.V1Beta.GeminiClient in place of an API key, so you can reuse a pre-built client (custom headers, handlers, ...) across models:

using Universal.Google.Gemini.Client.V1Beta;

GeminiClient client = new GeminiClient(apiKey);
IModel model = new Model(client, new Model.Options { ModelId = Models.Gemini35Flash });

Usage

Drop the model into EngineBuilder like any other IModel:

IEngine engine = EngineBuilder.FromDefaults(model)
    .AddBaselineTools()
    .Build();

await foreach (EngineEvent e in engine.ExecuteAsync(conversation))
{
    // handle events as usual — see Universal.Operative.Sdk's Package.md
}

Extended thinking

Model.Options.ThinkingConfig forwards directly to Gemini's thinkingConfig (thinking budget, whether to surface thought summaries). Thinking text round-trips through the universal ReasoningBlock.Text, the same slot Anthropic's extended thinking uses.

Gemini's thoughtSignature, however, does not live on the thought itself — verified against live responses, it's attached to whichever block concludes the thinking segment (the final answer TextBlock, or the ToolCallBlock for the function call that followed). Since neither has a native signature slot, it round-trips via the Gemini extension property added onto Block:

using Universal.Operative.Sdk.GoogleGemini;

string? signature = someBlock.Gemini.ThoughtSignature;

You only need to read this if you're inspecting history yourself — the adapter re-attaches it to the right outbound part automatically when you replay a conversation, so tool calls and answers produced under ThinkingConfig continue to validate correctly on the next turn.

Usage accounting

Gemini reports thinking tokens (thoughtsTokenCount) and tool-use prompt tokens (toolUsePromptTokenCount) as additive counters alongside promptTokenCount/candidatesTokenCount — unlike Usage.InputTokens/OutputTokens, which mirror Gemini's own headline counters as-is. Use Usage.Gemini to read the breakdown, and GeminiUsageExtensions.ProjectCompactionTokens as a CompactionTransformer.Options.ProjectedTokensCalculator so auto-compaction accounts for thinking-token cost correctly.

Prompt caching

Gemini 2.5+ already caches long context automatically — no configuration needed; savings show up in Usage.Gemini's cachedContentTokenCount. For a guaranteed cache hit instead, create a CachedContent via GeminiClient.CreateCachedContentAsync and reference it:

IModel model = new Model(client, new Model.Options
{
    ModelId = Models.Gemini35Flash,
    CachedContentName = cachedContent.Name,
});

A referenced cache carries its own system instruction/tools, so the request omits Message.Tools/Conversation.System while it's set.

License

Free for noncommercial use under the Universal.Operative Noncommercial License. Source is closed; commercial use requires a separate license from Andrew Ong.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 28 7/28/2026
1.1.0 29 7/28/2026
1.0.5 32 7/28/2026
1.0.4 54 7/27/2026
1.0.3 49 7/26/2026
1.0.2 91 7/23/2026
1.0.1 94 7/21/2026
1.0.0 98 7/15/2026

1.2.0 — Updated for Universal.Operative.Sdk 4.0.0: ToolDefinition.Parameters is now Universal.Common.Json.JsonSchema instead of JsonElement; the schema walker that builds Gemini's FunctionDeclaration.Parameters now reads it directly.