Skip to content

Agent APIs

Gunpal Jain edited this page Nov 15, 2026 · 1 revision

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.

Prerequisites

  • 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)).

Decisions

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, with NoulCriteria (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.

Voices

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.

Agents

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

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).

Triggers

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

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.

Error handling

  • API errors are thrown as GenerativeAI.Exceptions.ApiException (ErrorCode, ErrorStatus, ErrorMessage). 403/404/FAILED_PRECONDITION usually means the API is not enabled for the project; 402/429 means billing or quota.
  • ArgumentException for missing required fields (for example a trigger without Schedule or TimeZone).
  • TriggersClient.WaitForExecutionAsync throws TimeoutException when 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}");
}

Related pages

Clone this wiki locally