Repository navigation
Agent APIs
These clients cover the agent-related resources of the Gemini API. They follow the matching python-genai clients
(client.decisions, client.voices, client.agents, client.environments, client.triggers,
client.credentials). Agents, environments, triggers and credentials are experimental in python-genai and may
change.
| Client | Resource | What it does |
|---|---|---|
DecisionsClient |
/decisions |
Calibrated yes/no, choice and score answers about an input |
VoicesClient |
/voices |
Design, remix, replicate and list text-to-speech voices |
AgentsClient |
/agents |
Reusable agent definitions for interactions |
EnvironmentsClient |
/environments |
Sandbox environments for agents, with workspace file upload/download |
TriggersClient |
/triggers |
Run an agent interaction on a cron schedule |
CredentialsClient |
/credentials |
Write-only secrets that agent environments can use |
All of them are in the GenerativeAI.Clients namespace; their types are in GenerativeAI.Types.
Availability. These are Gemini API resources ({base}/{version}/{collection}). The clients also build Vertex AI
URLs (.../projects/{project}/locations/{location}/{collection}) when given a Vertex adapter, but whether a resource
is enabled there depends on Google's service. A 403/404/FAILED_PRECONDITION error usually means the feature is not
enabled for your project.
- NuGet package:
Google_GenerativeAI - A Gemini API key. See Authentication.
using GenerativeAI;
using GenerativeAI.Clients;
using GenerativeAI.Types;
var googleAi = new GoogleAi(apiKey);
var decisions = googleAi.CreateDecisionsClient();
var voices = googleAi.CreateVoicesClient();
var agents = googleAi.CreateAgentsClient();
var environments = googleAi.CreateEnvironmentsClient();
var triggers = googleAi.CreateTriggersClient();
var credentials = googleAi.CreateCredentialsClient();
// Each client can also be constructed directly, e.g. new DecisionsClient(new GoogleAIPlatformAdapter(apiKey)).The Decisions API evaluates structured questions against a shared input with a decision model
(DecisionModels.GeminiDecision1) and returns calibrated probabilities. Question types:
-
NoulDecisionQuestion: yes/no, withNoulCriteria(TrueDescription,FalseDescription). Answer:NoulDecisionAnswer(Noul,Confidence). -
ChoiceDecisionQuestion: pick one of several options (Criteria: option → description). Answer:ChoiceDecisionAnswer(Choice,Confidence,Probabilities). -
ScoreDecisionQuestion: a score against a list of criteria. Answer:ScoreDecisionAnswer(Score,Confidence,Legend,Probabilities).
var response = await decisions.CreateAsync(
DecisionModels.GeminiDecision1,
"The sky on a clear day is blue.",
new Dictionary<string, DecisionQuestion>
{
["sky_color"] = new ChoiceDecisionQuestion
{
Instructions = "Which color does the text say the sky is?",
Criteria = new Dictionary<string, string>
{
["blue"] = "The text says the sky is blue.",
["green"] = "The text says the sky is green."
}
},
["is_factual"] = new NoulDecisionQuestion
{
Instructions = "Is the statement factually correct?",
Criteria = new NoulCriteria { TrueDescription = "Correct", FalseDescription = "Incorrect" }
}
});
if (response.Answers?["sky_color"] is ChoiceDecisionAnswer choice)
Console.WriteLine($"{choice.Choice} ({choice.Confidence})");
if (response.Answers?["is_factual"] is NoulDecisionAnswer noul)
Console.WriteLine($"P(true) = {noul.Noul}");The input is an InteractionInput (a string converts implicitly). response.PromptFeedback explains a blocked
request.
Create custom text-to-speech voices and browse the voice catalog.
// Voice design: create a voice from a description ("prompted" voice).
Voice designed = await voices.DesignAsync("A calm, warm narrator voice.", displayName: "narrator", store: true);
Console.WriteLine($"{designed.Id} {designed.Key} {designed.Type}"); // Type == VoiceTypes.Prompted
// Remix an existing voice.
Voice remixed = await voices.RemixAsync(designed.Id!, "Make it slightly faster and brighter.", store: true);
// Replicate a voice from recorded audio. A consent recording from the speaker is required.
Voice replicated = await voices.ReplicateAsync(
VoiceAudioData.FromBytes(await File.ReadAllBytesAsync("speaker.wav"), "audio/wav"),
VoiceAudioData.FromBytes(await File.ReadAllBytesAsync("consent.wav"), "audio/wav"),
displayName: "my-voice", store: true);
// List voices (custom and prebuilt), with optional filters.
var page = await voices.ListAsync(new ListVoicesOptions { Type = new List<string> { VoiceTypes.Prebuilt } }, pageSize: 20);
await foreach (var v in voices.ListAllAsync())
Console.WriteLine($"{v.Id} {v.DisplayName} {v.Gender} {v.LanguageCode}");
var voice = await voices.GetAsync(designed.Id!);
await voices.DeleteAsync(designed.Id!);Designing a voice generates audio samples (Voice.SampleAudio), so it is billed. Use a voice's Key/Id as the
voice of a speech request, for example through VoiceConfig.Voice in a speech config.
An Agent is a reusable definition (base agent, AgentConfig, system instruction, tools and base environment)
that interactions can reference.
var agent = await agents.CreateAsync(new Agent
{
Id = "research-helper",
BaseAgent = InteractionAgents.DeepResearchPreview042026,
Description = "Researches topics for the support team.",
SystemInstruction = "Cite your sources."
});
var fetched = await agents.GetAsync("research-helper");
var page = await agents.ListAsync(pageSize: 10);
await foreach (var a in agents.ListAllAsync())
Console.WriteLine(a.Id);
await agents.DeleteAsync("research-helper");Use agents with the Interactions API (CreateInteractionRequest.Agent).
Environments are sandboxes that agent interactions run in. They can mount sources (GCS bucket, inline files,
repositories, skill registry; see EnvironmentSourceTypes) and have workspace files you can list, upload and
download.
AgentEnvironment env = await environments.CreateAsync(); // or pass a CreateEnvironmentRequest
Console.WriteLine($"{env.Id} {env.Status}");
// Upload from a stream (or use the overload that takes a local file path).
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes("hello")))
{
await environments.UploadFileAsync(env.Id!, "data/hello.txt", stream, "text/plain", overwrite: true);
}
// Upload a tar/tar.gz archive and unpack it into a folder.
await environments.UploadFileAsync(env.Id!, "project", "project.tar.gz", extract: true);
// List and download workspace files.
await foreach (var file in environments.ListAllFilesAsync(env.Id!, recursive: true))
Console.WriteLine($"{file.Path} {file.Type} {file.SizeBytes}");
byte[] content = await environments.DownloadFileAsync(env.Id!, "data/hello.txt");
await environments.DeleteAsync(env.Id!);Reference an environment from an interaction with CreateInteractionRequest.Environment; an
InteractionEnvironmentReference converts implicitly from an environment ID string or from an
InteractionEnvironment configuration (environment variables, network allowlist, sources).
A trigger runs an interaction on a cron schedule. Interaction, Schedule and TimeZone are required.
Trigger trigger = await triggers.CreateAsync(new CreateTriggerRequest
{
DisplayName = "daily-digest",
Schedule = "0 8 * * *",
TimeZone = "Europe/London",
Interaction = new CreateInteractionRequest
{
Agent = InteractionAgents.DeepResearchPreview042026,
Input = "Summarize yesterday's AI news."
}
});
await triggers.PauseAsync(trigger.Id!);
await triggers.ResumeAsync(trigger.Id!);
await triggers.UpdateAsync(trigger.Id!, new UpdateTriggerRequest { DisplayName = "morning-digest" });
// Run it now and wait for the execution.
TriggerExecution run = await triggers.RunAsync(trigger.Id!);
var finished = await triggers.WaitForExecutionAsync(trigger.Id!, run.Id!, timeout: TimeSpan.FromMinutes(30));
Console.WriteLine($"{finished.Status} {finished.InteractionId}"); // TriggerExecutionStatuses.*
await foreach (var exec in triggers.ListAllExecutionsAsync(trigger.Id!))
Console.WriteLine($"{exec.Id} {exec.Status}");
await triggers.DeleteAsync(trigger.Id!);Credentials store secrets that environments can use without exposing them. Secrets are write-only: reads return
metadata (Id, Type, Status) but never the secret.
var created = await credentials.CreateAsync(new EnvironmentVariableCredentialConfig
{
Id = "github-token",
// System.Environment: GenerativeAI.Types also has an Environment type.
Value = System.Environment.GetEnvironmentVariable("GITHUB_TOKEN"),
InjectionLocation = new List<string> { CredentialInjectionLocations.Header },
TrustedDomains = new List<string> { "api.github.com" }
});
// Other types: BearerTokenCredentialConfig (Token, HeaderName, Prefix) and
// OAuth2CredentialConfig (ClientId, ClientSecret, RefreshToken, TokenUrl, Scopes).
var cred = await credentials.GetAsync("github-token");
await foreach (var c in credentials.ListAllAsync())
Console.WriteLine($"{c.Id} {c.Type} {c.Status}");
await credentials.UpdateAsync("github-token",
new EnvironmentVariableCredentialConfig { Value = "new-value" }, updateMask: "value");
await credentials.DeleteAsync("github-token");When updating, the credential type must match the stored credential.
- API errors are thrown as
GenerativeAI.Exceptions.ApiException(ErrorCode,ErrorStatus,ErrorMessage). 403/404/FAILED_PRECONDITIONusually means the API is not enabled for the project; 402/429 means billing or quota. -
ArgumentExceptionfor missing required fields (for example a trigger withoutScheduleorTimeZone). -
TriggersClient.WaitForExecutionAsyncthrowsTimeoutExceptionwhen its timeout is exceeded.
try
{
var env = await environments.CreateAsync();
}
catch (ApiException ex) when (ex.ErrorCode is 403 or 404 || ex.ErrorStatus == "FAILED_PRECONDITION")
{
Console.WriteLine($"Environments are not available for this project: {ex.ErrorMessage}");
}Getting Started
- Initialization
- Authentication
- Configuration & Error Handling
- Supported Models
- Migration Guide (v4)
- Release Notes (v4)
Core Features
- Generate Content
- Chat Session
- Streaming
- Multimodal Features
- JSON Mode
- Function Calling
- Embeddings
- Context Caching
Gemini APIs
- Interactions API
- Multimodal Live API
- File Search
- Batch API
- Model Tuning
- Webhooks
- Agent APIs
- Image Generation
- Video Generation
- Speech Generation
- Files Client
- Model Client
Vertex AI
Integrations
Guides
Legacy