Migration — Phase 67: Gemini AI Provider
Migration — Phase 67: Gemini AI Provider
Shape: Additive opt-in companion. No consumer migration required.
What changes
A new NuGet companion ToolUp.AIProviders.Gemini ships alongside ToolUp.AIProviders.Claude and ToolUp.AIProviders.OpenAI. The companion implements IAIProvider against Google's Generative Language API (v1beta), supports the gemini-2.5-* and gemini-1.5-* model families, and is BYOK-capable via ISecretStore under the _platform scope key GEMINI_API_KEY.
No SDK interfaces changed. No existing-provider code touched. No consumer is required to do anything — consumers wishing to expose Gemini add the package reference and append a builder to the DefaultAIProviderFactory.create builders list.
Diff to apply (opt-in)
A consumer that wants to offer Gemini alongside its existing providers adds:
<!-- Server csproj / fsproj -->
<PackageReference Include="ToolUp.AIProviders.Gemini" />
…and appends a builder entry to the deployment's compose step. The shape is the same as Claude / OpenAI:
open GeminiAIProvider
let geminiBuilder = {
Descriptor = {
Id = ProviderId
DisplayName = "Google Gemini"
SupportedModels = KnownModels
DefaultModel = DefaultModel
Capabilities = {
AIProviderCapabilities.unknown with
Streaming = true
ToolUse = true
Vision = true
SupportsPromptCaching = true
ProviderName = "google-gemini"
Model = DefaultModel
}
}
Build = fun apiKey model -> createWithApiKeyAndModel apiKey model
}
// Then in the existing builder list:
DefaultAIProviderFactory.create
[ ClaudeAIProvider.builder
OpenAIProvider.builder
geminiBuilder ] // append; existing entries unchanged
providerProfile
secretStore
fallbackPolicy
platformProvider
Store the API key under _platform scope, name GEMINI_API_KEY.
Verification steps
dotnet buildof the consuming app remains clean (additive<PackageReference>).- A user-configured Gemini
ProviderEntryresolves viaIAIProviderFactory.Resolveand serves amodels/gemini-2.5-flashormodels/gemini-2.5-procompletion. - Streaming, tool use, and multimodal input round-trip in the same forge-internal shape as Claude / OpenAI for the same inputs (semantically equivalent — exact bytes differ per vendor wire format).
/health/readyincludes aai_provider:google-geminiprobe verifying the secret-store key is set.
Rollback
Remove the <PackageReference> + the appended builder entry. No data, schema, or stored-config migration is involved — the SDK's IProviderProfile quietly ignores entries whose ProviderId no longer matches a registered builder (surfaced as UnknownProvider per the existing ProviderResolutionError contract).