diff --git a/api-report/genai-node.api.md b/api-report/genai-node.api.md
index d62bb9304..b48eab2bd 100644
--- a/api-report/genai-node.api.md
+++ b/api-report/genai-node.api.md
@@ -4,8 +4,11 @@
```ts
+///
+
import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { GoogleAuthOptions } from 'google-auth-library';
+import { ReadableStream as ReadableStream_2 } from 'stream/web';
// @public
export interface ActivityEnd {
@@ -33,6 +36,19 @@ export enum AdapterSize {
ADAPTER_SIZE_UNSPECIFIED = "ADAPTER_SIZE_UNSPECIFIED"
}
+// @public
+interface AllowedTools {
+ mode?: ToolChoiceType;
+ tools?: Array;
+}
+
+// @public
+interface Annotation {
+ end_index?: number;
+ source?: string;
+ start_index?: number;
+}
+
// @public
export interface ApiAuth {
apiKeyConfig?: ApiAuthApiKeyConfig;
@@ -78,6 +94,19 @@ export interface AudioChunk {
sourceMetadata?: LiveMusicSourceMetadata;
}
+// @public
+interface AudioContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: AudioMimeType;
+ type: 'audio';
+ // (undocumented)
+ uri?: string;
+}
+
+// @public
+type AudioMimeType = 'audio/wav' | 'audio/mp3' | 'audio/aiff' | 'audio/aac' | 'audio/ogg' | 'audio/flac' | (string & {});
+
// @public
export interface AudioTranscriptionConfig {
}
@@ -147,6 +176,68 @@ export interface AutomaticFunctionCallingConfig {
maximumRemoteCalls?: number;
}
+// @public (undocumented)
+interface BaseCreateAgentInteractionParams {
+ agent: (string & {}) | 'deep-research-pro-preview-12-2025';
+ agent_config?: DynamicAgentConfig | DeepResearchAgentConfig;
+ api_version?: string;
+ background?: boolean;
+ input: string | Array | Array | TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ previous_interaction_id?: string;
+ response_format?: unknown;
+ response_mime_type?: string;
+ response_modalities?: Array<'text' | 'image' | 'audio'>;
+ store?: boolean;
+ stream?: boolean;
+ system_instruction?: string;
+ tools?: Array;
+}
+
+// @public (undocumented)
+interface BaseCreateModelInteractionParams {
+ api_version?: string;
+ background?: boolean;
+ generation_config?: GenerationConfig_2;
+ input: string | Array | Array | TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ model: Model_2;
+ previous_interaction_id?: string;
+ response_format?: unknown;
+ response_mime_type?: string;
+ response_modalities?: Array<'text' | 'image' | 'audio'>;
+ store?: boolean;
+ stream?: boolean;
+ system_instruction?: string;
+ tools?: Array;
+}
+
+// Warning: (ae-forgotten-export) The symbol "APIResource" needs to be exported by the entry point index.d.ts
+//
+// @public (undocumented)
+class BaseInteractions extends APIResource {
+ cancel(id: string, params?: InteractionCancelParams | null | undefined, options?: RequestOptions): APIPromise;
+ // Warning: (ae-forgotten-export) The symbol "RequestOptions" needs to be exported by the entry point index.d.ts
+ // Warning: (ae-forgotten-export) The symbol "APIPromise" needs to be exported by the entry point index.d.ts
+ create(params: CreateModelInteractionParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // Warning: (ae-forgotten-export) The symbol "Stream" needs to be exported by the entry point index.d.ts
+ //
+ // (undocumented)
+ create(params: CreateModelInteractionParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ create(params: CreateAgentInteractionParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // (undocumented)
+ create(params: CreateAgentInteractionParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ create(params: BaseCreateModelInteractionParams | BaseCreateAgentInteractionParams, options?: RequestOptions): APIPromise | Interaction>;
+ delete(id: string, params?: InteractionDeleteParams | null | undefined, options?: RequestOptions): APIPromise;
+ get(id: string, params?: InteractionGetParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // (undocumented)
+ get(id: string, params: InteractionGetParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ get(id: string, params?: InteractionGetParamsBase | undefined, options?: RequestOptions): APIPromise | Interaction>;
+ // (undocumented)
+ static readonly _key: readonly ['interactions'];
+}
+
// @public
export interface BaseUrlParameters {
// (undocumented)
@@ -368,12 +459,34 @@ export interface CitationMetadata {
citations?: Citation[];
}
+// @public
+interface CodeExecutionCallArguments {
+ code?: string;
+ language?: 'python';
+}
+
+// @public
+interface CodeExecutionCallContent {
+ arguments?: CodeExecutionCallArguments;
+ id?: string;
+ type: 'code_execution_call';
+}
+
// @public
export interface CodeExecutionResult {
outcome?: Outcome;
output?: string;
}
+// @public
+interface CodeExecutionResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: string;
+ signature?: string;
+ type: 'code_execution_result';
+}
+
// @public
export interface CompletionStats {
failedCount?: string;
@@ -413,6 +526,202 @@ export interface Content {
role?: string;
}
+// @public (undocumented)
+interface ContentDelta {
+ // (undocumented)
+ delta?: ContentDelta.TextDelta | ContentDelta.ImageDelta | ContentDelta.AudioDelta | ContentDelta.DocumentDelta | ContentDelta.VideoDelta | ContentDelta.ThoughtSummaryDelta | ContentDelta.ThoughtSignatureDelta | ContentDelta.FunctionCallDelta | ContentDelta.FunctionResultDelta | ContentDelta.CodeExecutionCallDelta | ContentDelta.CodeExecutionResultDelta | ContentDelta.URLContextCallDelta | ContentDelta.URLContextResultDelta | ContentDelta.GoogleSearchCallDelta | ContentDelta.GoogleSearchResultDelta | ContentDelta.MCPServerToolCallDelta | ContentDelta.MCPServerToolResultDelta | ContentDelta.FileSearchResultDelta;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.delta';
+ // (undocumented)
+ index?: number;
+}
+
+// @public (undocumented)
+namespace ContentDelta {
+ // (undocumented)
+ interface AudioDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: AudioMimeType;
+ type: 'audio';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface CodeExecutionCallDelta {
+ arguments?: CodeExecutionCallArguments;
+ id?: string;
+ type: 'code_execution_call';
+ }
+ // (undocumented)
+ interface CodeExecutionResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: string;
+ // (undocumented)
+ signature?: string;
+ type: 'code_execution_result';
+ }
+ // (undocumented)
+ interface DocumentDelta {
+ // (undocumented)
+ data?: string;
+ // (undocumented)
+ mime_type?: string;
+ type: 'document';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface FileSearchResultDelta {
+ // (undocumented)
+ result?: Array;
+ type: 'file_search_result';
+ }
+ // (undocumented)
+ namespace FileSearchResultDelta {
+ interface Result {
+ file_search_store?: string;
+ text?: string;
+ title?: string;
+ }
+ }
+ // (undocumented)
+ interface FunctionCallDelta {
+ // (undocumented)
+ arguments?: {
+ [key: string]: unknown;
+ };
+ id?: string;
+ // (undocumented)
+ name?: string;
+ type: 'function_call';
+ }
+ // (undocumented)
+ interface FunctionResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ name?: string;
+ result?: FunctionResultDelta.Items | string;
+ type: 'function_result';
+ }
+ // (undocumented)
+ namespace FunctionResultDelta {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+ }
+ // (undocumented)
+ interface GoogleSearchCallDelta {
+ arguments?: GoogleSearchCallArguments;
+ id?: string;
+ type: 'google_search_call';
+ }
+ // (undocumented)
+ interface GoogleSearchResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: Array;
+ // (undocumented)
+ signature?: string;
+ type: 'google_search_result';
+ }
+ // (undocumented)
+ interface ImageDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: ImageMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'image';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface MCPServerToolCallDelta {
+ // (undocumented)
+ arguments?: {
+ [key: string]: unknown;
+ };
+ id?: string;
+ // (undocumented)
+ name?: string;
+ // (undocumented)
+ server_name?: string;
+ type: 'mcp_server_tool_call';
+ }
+ // (undocumented)
+ interface MCPServerToolResultDelta {
+ call_id?: string;
+ // (undocumented)
+ name?: string;
+ result?: MCPServerToolResultDelta.Items | string;
+ // (undocumented)
+ server_name?: string;
+ type: 'mcp_server_tool_result';
+ }
+ // (undocumented)
+ namespace MCPServerToolResultDelta {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+ }
+ // (undocumented)
+ interface TextDelta {
+ annotations?: Array;
+ // (undocumented)
+ text?: string;
+ type: 'text';
+ }
+ // (undocumented)
+ interface ThoughtSignatureDelta {
+ signature?: string;
+ type: 'thought_signature';
+ }
+ // (undocumented)
+ interface ThoughtSummaryDelta {
+ content?: TextContent | ImageContent;
+ type: 'thought_summary';
+ }
+ // (undocumented)
+ interface URLContextCallDelta {
+ arguments?: URLContextCallArguments;
+ id?: string;
+ type: 'url_context_call';
+ }
+ // (undocumented)
+ interface URLContextResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: Array;
+ // (undocumented)
+ signature?: string;
+ type: 'url_context_result';
+ }
+ // (undocumented)
+ interface VideoDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: VideoMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'video';
+ // (undocumented)
+ uri?: string;
+ }
+}
+
// @public
export interface ContentEmbedding {
statistics?: ContentEmbeddingStatistics;
@@ -437,6 +746,25 @@ export class ContentReferenceImage {
toReferenceImageAPI(): ReferenceImageAPIInternal;
}
+// @public (undocumented)
+interface ContentStart {
+ content?: TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.start';
+ // (undocumented)
+ index?: number;
+}
+
+// @public (undocumented)
+interface ContentStop {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.stop';
+ // (undocumented)
+ index?: number;
+}
+
// @public (undocumented)
export type ContentUnion = Content | PartUnion[] | PartUnion;
@@ -496,6 +824,16 @@ export class CountTokensResponse {
totalTokens?: number;
}
+// @public (undocumented)
+interface CreateAgentInteractionParamsNonStreaming extends BaseCreateAgentInteractionParams {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface CreateAgentInteractionParamsStreaming extends BaseCreateAgentInteractionParams {
+ stream: true;
+}
+
// @public
export interface CreateAuthTokenConfig {
abortSignal?: AbortSignal;
@@ -606,6 +944,16 @@ export function createFunctionResponsePartFromUri(uri: string, mimeType: string)
// @public
export function createModelContent(partOrString: PartListUnion | string): Content;
+// @public (undocumented)
+interface CreateModelInteractionParamsNonStreaming extends BaseCreateModelInteractionParams {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface CreateModelInteractionParamsStreaming extends BaseCreateModelInteractionParams {
+ stream: true;
+}
+
// @public
export function createPartFromBase64(data: string, mimeType: string, mediaResolution?: PartMediaResolutionLevel): Part;
@@ -703,6 +1051,12 @@ export interface DatasetStats {
userOutputTokenDistribution?: DatasetDistribution;
}
+// @public
+interface DeepResearchAgentConfig {
+ thinking_summaries?: 'auto' | 'none';
+ type?: 'deep-research';
+}
+
// @public
export interface DeleteBatchJobConfig {
abortSignal?: AbortSignal;
@@ -822,6 +1176,17 @@ interface Document_2 {
}
export { Document_2 as Document }
+// @public
+interface DocumentContent {
+ // (undocumented)
+ data?: string;
+ // (undocumented)
+ mime_type?: string;
+ type: 'document';
+ // (undocumented)
+ uri?: string;
+}
+
// @public
export enum DocumentState {
// (undocumented)
@@ -850,6 +1215,13 @@ export interface DownloadFileParameters {
file: DownloadableFileUnion;
}
+// @public
+interface DynamicAgentConfig {
+ // (undocumented)
+ [k: string]: unknown;
+ type?: 'dynamic';
+}
+
// @public
export interface DynamicRetrievalConfig {
dynamicThreshold?: number;
@@ -997,6 +1369,22 @@ export enum Environment {
ENVIRONMENT_UNSPECIFIED = "ENVIRONMENT_UNSPECIFIED"
}
+// @public (undocumented)
+interface ErrorEvent_2 {
+ error?: ErrorEvent_2.Error;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'error';
+}
+
+// @public (undocumented)
+namespace ErrorEvent_2 {
+ interface Error {
+ code?: string;
+ message?: string;
+ }
+}
+
// @public
export interface ExecutableCode {
code?: string;
@@ -1093,6 +1481,21 @@ export interface FileSearch {
topK?: number;
}
+// @public
+interface FileSearchResultContent {
+ result?: Array;
+ type: 'file_search_result';
+}
+
+// @public (undocumented)
+namespace FileSearchResultContent {
+ interface Result {
+ file_search_store?: string;
+ text?: string;
+ title?: string;
+ }
+}
+
// @public
export interface FileSearchStore {
activeDocumentsCount?: string;
@@ -1153,6 +1556,15 @@ export enum FinishReason {
UNEXPECTED_TOOL_CALL = "UNEXPECTED_TOOL_CALL"
}
+// @public
+interface Function_2 {
+ description?: string;
+ name?: string;
+ parameters?: unknown;
+ // (undocumented)
+ type: 'function';
+}
+
// @public
export interface FunctionCall {
args?: Record;
@@ -1162,6 +1574,16 @@ export interface FunctionCall {
willContinue?: boolean;
}
+// @public
+interface FunctionCallContent {
+ arguments: {
+ [key: string]: unknown;
+ };
+ id: string;
+ name: string;
+ type: 'function_call';
+}
+
// @public
export interface FunctionCallingConfig {
allowedFunctionNames?: string[];
@@ -1227,6 +1649,24 @@ export enum FunctionResponseScheduling {
WHEN_IDLE = "WHEN_IDLE"
}
+// @public
+interface FunctionResultContent {
+ call_id: string;
+ is_error?: boolean;
+ name?: string;
+ result: FunctionResultContent.Items | unknown | string;
+ type: 'function_result';
+}
+
+// @public (undocumented)
+namespace FunctionResultContent {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+}
+
// @public
export interface GeminiPreferenceExample {
completions?: GeminiPreferenceExampleCompletion[];
@@ -1462,6 +1902,19 @@ export interface GenerationConfig {
topP?: number;
}
+// @public
+interface GenerationConfig_2 {
+ max_output_tokens?: number;
+ seed?: number;
+ speech_config?: Array;
+ stop_sequences?: Array;
+ temperature?: number;
+ thinking_level?: ThinkingLevel_2;
+ thinking_summaries?: 'auto' | 'none';
+ tool_choice?: ToolChoice;
+ top_p?: number;
+}
+
// @public
export interface GenerationConfigRoutingConfig {
autoMode?: GenerationConfigRoutingConfigAutoRoutingMode;
@@ -1600,6 +2053,8 @@ export class GoogleGenAI {
// (undocumented)
readonly fileSearchStores: FileSearchStores;
// (undocumented)
+ get interactions(): Interactions_2;
+ // (undocumented)
readonly live: Live;
// (undocumented)
readonly models: Models;
@@ -1644,6 +2099,34 @@ export interface GoogleSearch {
timeRangeFilter?: Interval;
}
+// @public
+interface GoogleSearchCallArguments {
+ queries?: Array;
+}
+
+// @public
+interface GoogleSearchCallContent {
+ arguments?: GoogleSearchCallArguments;
+ id?: string;
+ type: 'google_search_call';
+}
+
+// @public
+interface GoogleSearchResult {
+ rendered_content?: string;
+ title?: string;
+ url?: string;
+}
+
+// @public
+interface GoogleSearchResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: Array;
+ signature?: string;
+ type: 'google_search_result';
+}
+
// @public
export interface GoogleSearchRetrieval {
dynamicRetrievalConfig?: DynamicRetrievalConfig;
@@ -1832,6 +2315,20 @@ export interface ImageConfig {
outputMimeType?: string;
}
+// @public
+interface ImageContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: ImageMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'image';
+ // (undocumented)
+ uri?: string;
+}
+
+// @public
+type ImageMimeType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/heic' | 'image/heif' | (string & {});
+
// @public
export enum ImagePromptLanguage {
auto = "auto",
@@ -1898,6 +2395,166 @@ export class InlinedResponse {
response?: GenerateContentResponse;
}
+// @public
+interface Interaction {
+ agent?: (string & {}) | 'deep-research-pro-preview-12-2025';
+ created?: string;
+ error?: Interaction.Error;
+ id: string;
+ model?: Model_2;
+ object?: 'interaction';
+ outputs?: Array;
+ previous_interaction_id?: string;
+ role?: string;
+ status: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled';
+ updated?: string;
+ usage?: Usage;
+}
+
+// @public (undocumented)
+namespace Interaction {
+ interface Error {
+ code?: string;
+ message?: string;
+ }
+}
+
+// @public (undocumented)
+interface InteractionCancelParams {
+ api_version?: string;
+}
+
+// @public (undocumented)
+type InteractionCreateParams = CreateModelInteractionParamsNonStreaming | CreateModelInteractionParamsStreaming | CreateAgentInteractionParamsNonStreaming | CreateAgentInteractionParamsStreaming;
+
+// @public (undocumented)
+interface InteractionDeleteParams {
+ api_version?: string;
+}
+
+// @public (undocumented)
+type InteractionDeleteResponse = unknown;
+
+// @public (undocumented)
+interface InteractionEvent {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'interaction.start' | 'interaction.complete';
+ interaction?: Interaction;
+}
+
+// @public (undocumented)
+type InteractionGetParams = InteractionGetParamsNonStreaming | InteractionGetParamsStreaming;
+
+// @public (undocumented)
+interface InteractionGetParamsBase {
+ api_version?: string;
+ last_event_id?: string;
+ stream?: boolean;
+}
+
+// @public (undocumented)
+interface InteractionGetParamsNonStreaming extends InteractionGetParamsBase {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface InteractionGetParamsStreaming extends InteractionGetParamsBase {
+ stream: true;
+}
+
+declare namespace Interactions {
+ export {
+ BaseInteractions,
+ Interactions_2 as Interactions,
+ AllowedTools,
+ Annotation,
+ AudioContent,
+ AudioMimeType,
+ CodeExecutionCallArguments,
+ CodeExecutionCallContent,
+ CodeExecutionResultContent,
+ ContentDelta,
+ ContentStart,
+ ContentStop,
+ DeepResearchAgentConfig,
+ DocumentContent,
+ DynamicAgentConfig,
+ ErrorEvent_2 as ErrorEvent,
+ FileSearchResultContent,
+ Function_2 as Function,
+ FunctionCallContent,
+ FunctionResultContent,
+ GenerationConfig_2 as GenerationConfig,
+ GoogleSearchCallArguments,
+ GoogleSearchCallContent,
+ GoogleSearchResult,
+ GoogleSearchResultContent,
+ ImageContent,
+ ImageMimeType,
+ Interaction,
+ InteractionEvent,
+ InteractionSSEEvent,
+ InteractionStatusUpdate,
+ MCPServerToolCallContent,
+ MCPServerToolResultContent,
+ Model_2 as Model,
+ SpeechConfig_2 as SpeechConfig,
+ TextContent,
+ ThinkingLevel_2 as ThinkingLevel,
+ ThoughtContent,
+ Tool_2 as Tool,
+ ToolChoice,
+ ToolChoiceConfig,
+ ToolChoiceType,
+ Turn,
+ URLContextCallArguments,
+ URLContextCallContent,
+ URLContextResult,
+ URLContextResultContent,
+ Usage,
+ VideoContent,
+ VideoMimeType,
+ InteractionDeleteResponse,
+ InteractionCreateParams,
+ BaseCreateModelInteractionParams,
+ BaseCreateAgentInteractionParams,
+ CreateModelInteractionParamsNonStreaming,
+ CreateModelInteractionParamsStreaming,
+ CreateAgentInteractionParamsNonStreaming,
+ CreateAgentInteractionParamsStreaming,
+ InteractionDeleteParams,
+ InteractionCancelParams,
+ InteractionGetParams,
+ InteractionGetParamsBase,
+ InteractionGetParamsNonStreaming,
+ InteractionGetParamsStreaming
+ }
+}
+
+// @public (undocumented)
+class Interactions_2 extends BaseInteractions {
+}
+
+// @public (undocumented)
+namespace Interactions_2 {
+ { type AllowedTools as AllowedTools, type Annotation as Annotation, type AudioContent as AudioContent, type AudioMimeType as AudioMimeType, type CodeExecutionCallArguments as CodeExecutionCallArguments, type CodeExecutionCallContent as CodeExecutionCallContent, type CodeExecutionResultContent as CodeExecutionResultContent, type ContentDelta as ContentDelta, type ContentStart as ContentStart, type ContentStop as ContentStop, type DeepResearchAgentConfig as DeepResearchAgentConfig, type DocumentContent as DocumentContent, type DynamicAgentConfig as DynamicAgentConfig, type ErrorEvent as ErrorEvent, type FileSearchResultContent as FileSearchResultContent, type Function as Function, type FunctionCallContent as FunctionCallContent, type FunctionResultContent as FunctionResultContent, type GenerationConfig as GenerationConfig, type GoogleSearchCallArguments as GoogleSearchCallArguments, type GoogleSearchCallContent as GoogleSearchCallContent, type GoogleSearchResult as GoogleSearchResult, type GoogleSearchResultContent as GoogleSearchResultContent, type ImageContent as ImageContent, type ImageMimeType as ImageMimeType, type Interaction as Interaction, type InteractionEvent as InteractionEvent, type InteractionSSEEvent as InteractionSSEEvent, type InteractionStatusUpdate as InteractionStatusUpdate, type MCPServerToolCallContent as MCPServerToolCallContent, type MCPServerToolResultContent as MCPServerToolResultContent, type Model as Model, type SpeechConfig as SpeechConfig, type TextContent as TextContent, type ThinkingLevel as ThinkingLevel, type ThoughtContent as ThoughtContent, type Tool as Tool, type ToolChoice as ToolChoice, type ToolChoiceConfig as ToolChoiceConfig, type ToolChoiceType as ToolChoiceType, type Turn as Turn, type URLContextCallArguments as URLContextCallArguments, type URLContextCallContent as URLContextCallContent, type URLContextResult as URLContextResult, type URLContextResultContent as URLContextResultContent, type Usage as Usage, type VideoContent as VideoContent, type VideoMimeType as VideoMimeType, type InteractionDeleteResponse as InteractionDeleteResponse, type InteractionCreateParams as InteractionCreateParams, type CreateModelInteractionParamsNonStreaming as CreateModelInteractionParamsNonStreaming, type CreateModelInteractionParamsStreaming as CreateModelInteractionParamsStreaming, type CreateAgentInteractionParamsNonStreaming as CreateAgentInteractionParamsNonStreaming, type CreateAgentInteractionParamsStreaming as CreateAgentInteractionParamsStreaming, type InteractionDeleteParams as InteractionDeleteParams, type InteractionCancelParams as InteractionCancelParams, type InteractionGetParams as InteractionGetParams, type InteractionGetParamsNonStreaming as InteractionGetParamsNonStreaming, type InteractionGetParamsStreaming as InteractionGetParamsStreaming, };
+}
+
+// @public (undocumented)
+type InteractionSSEEvent = InteractionEvent | InteractionStatusUpdate | ContentStart | ContentDelta | ContentStop | ErrorEvent_2;
+
+// @public (undocumented)
+interface InteractionStatusUpdate {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'interaction.status_update';
+ // (undocumented)
+ interaction_id?: string;
+ // (undocumented)
+ status?: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled';
+}
+
// @public
export interface Interval {
endTime?: string;
@@ -2451,6 +3108,35 @@ export enum MaskReferenceMode {
MASK_MODE_USER_PROVIDED = "MASK_MODE_USER_PROVIDED"
}
+// @public
+interface MCPServerToolCallContent {
+ arguments: {
+ [key: string]: unknown;
+ };
+ id: string;
+ name: string;
+ server_name: string;
+ type: 'mcp_server_tool_call';
+}
+
+// @public
+interface MCPServerToolResultContent {
+ call_id: string;
+ name?: string;
+ result: MCPServerToolResultContent.Items | unknown | string;
+ server_name?: string;
+ type: 'mcp_server_tool_result';
+}
+
+// @public (undocumented)
+namespace MCPServerToolResultContent {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+}
+
// @public
export function mcpToTool(...args: [...Client[], CallableToolConfig | Client]): CallableTool;
@@ -2513,6 +3199,9 @@ export interface Model {
version?: string;
}
+// @public
+type Model_2 = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-preview-09-2025' | 'gemini-2.5-flash-lite' | 'gemini-2.5-flash-lite-preview-09-2025' | 'gemini-2.5-flash-preview-native-audio-dialog' | 'gemini-2.5-flash-image-preview' | 'gemini-2.5-pro-preview-tts' | 'gemini-3-pro-preview' | (string & {});
+
// @public (undocumented)
export class Models extends BaseModule {
constructor(apiClient: ApiClient);
@@ -3114,6 +3803,13 @@ export interface SpeechConfig {
voiceConfig?: VoiceConfig;
}
+// @public
+interface SpeechConfig_2 {
+ language?: string;
+ speaker?: string;
+ voice?: string;
+}
+
// @public (undocumented)
export type SpeechConfigUnion = SpeechConfig | string;
@@ -3249,6 +3945,13 @@ export interface TestTableItem {
skipInApiMode?: string;
}
+// @public
+interface TextContent {
+ annotations?: Array;
+ text?: string;
+ type: 'text';
+}
+
// @public
export interface ThinkingConfig {
includeThoughts?: boolean;
@@ -3263,6 +3966,16 @@ export enum ThinkingLevel {
THINKING_LEVEL_UNSPECIFIED = "THINKING_LEVEL_UNSPECIFIED"
}
+// @public (undocumented)
+type ThinkingLevel_2 = 'low' | 'high';
+
+// @public
+interface ThoughtContent {
+ signature?: string;
+ summary?: Array;
+ type: 'thought';
+}
+
// @public (undocumented)
export class Tokens extends BaseModule {
constructor(apiClient: ApiClient);
@@ -3290,6 +4003,59 @@ export interface Tool {
urlContext?: UrlContext;
}
+// @public
+type Tool_2 = Function_2 | Tool_2.GoogleSearch | Tool_2.CodeExecution | Tool_2.URLContext | Tool_2.ComputerUse | Tool_2.MCPServer | Tool_2.FileSearch;
+
+// @public (undocumented)
+namespace Tool_2 {
+ interface CodeExecution {
+ // (undocumented)
+ type: 'code_execution';
+ }
+ interface ComputerUse {
+ environment?: 'browser';
+ excludedPredefinedFunctions?: Array;
+ // (undocumented)
+ type: 'computer_use';
+ }
+ interface FileSearch {
+ file_search_store_names?: Array;
+ metadata_filter?: string;
+ top_k?: number;
+ // (undocumented)
+ type: 'file_search';
+ }
+ interface GoogleSearch {
+ // (undocumented)
+ type: 'google_search';
+ }
+ interface MCPServer {
+ allowed_tools?: Array;
+ headers?: {
+ [key: string]: string;
+ };
+ name?: string;
+ // (undocumented)
+ type: 'mcp_server';
+ url?: string;
+ }
+ interface URLContext {
+ // (undocumented)
+ type: 'url_context';
+ }
+}
+
+// @public
+type ToolChoice = ToolChoiceType | ToolChoiceConfig;
+
+// @public (undocumented)
+interface ToolChoiceConfig {
+ allowed_tools?: AllowedTools;
+}
+
+// @public (undocumented)
+type ToolChoiceType = 'auto' | 'any' | 'none' | 'validated';
+
// @public
export interface ToolCodeExecution {
}
@@ -3426,6 +4192,12 @@ export interface TuningValidationDataset {
vertexDatasetResource?: string;
}
+// @public (undocumented)
+interface Turn {
+ content?: string | Array;
+ role?: string;
+}
+
// @public
export enum TurnCompleteReason {
MALFORMED_FUNCTION_CALL = "MALFORMED_FUNCTION_CALL",
@@ -3582,11 +4354,38 @@ export class UpscaleImageResponse {
export interface UrlContext {
}
+// @public
+interface URLContextCallArguments {
+ urls?: Array;
+}
+
+// @public
+interface URLContextCallContent {
+ arguments?: URLContextCallArguments;
+ id?: string;
+ type: 'url_context_call';
+}
+
// @public
export interface UrlContextMetadata {
urlMetadata?: UrlMetadata[];
}
+// @public
+interface URLContextResult {
+ status?: 'success' | 'error' | 'paywall' | 'unsafe';
+ url?: string;
+}
+
+// @public
+interface URLContextResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: Array;
+ signature?: string;
+ type: 'url_context_result';
+}
+
// @public
export interface UrlMetadata {
retrievedUrl?: string;
@@ -3602,6 +4401,40 @@ export enum UrlRetrievalStatus {
URL_RETRIEVAL_STATUS_UNSPECIFIED = "URL_RETRIEVAL_STATUS_UNSPECIFIED"
}
+// @public
+interface Usage {
+ cached_tokens_by_modality?: Array;
+ input_tokens_by_modality?: Array;
+ output_tokens_by_modality?: Array;
+ tool_use_tokens_by_modality?: Array;
+ total_cached_tokens?: number;
+ total_input_tokens?: number;
+ total_output_tokens?: number;
+ total_reasoning_tokens?: number;
+ total_tokens?: number;
+ total_tool_use_tokens?: number;
+}
+
+// @public (undocumented)
+namespace Usage {
+ interface CachedTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface InputTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface OutputTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface ToolUseTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+}
+
// @public
export interface UsageMetadata {
cachedContentTokenCount?: number;
@@ -3682,6 +4515,17 @@ export enum VideoCompressionQuality {
OPTIMIZED = "OPTIMIZED"
}
+// @public
+interface VideoContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: VideoMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'video';
+ // (undocumented)
+ uri?: string;
+}
+
// @public
export interface VideoGenerationMask {
image?: Image_2;
@@ -3715,6 +4559,9 @@ export interface VideoMetadata {
startOffset?: string;
}
+// @public
+type VideoMimeType = 'video/mp4' | 'video/mpeg' | 'video/mov' | 'video/avi' | 'video/x-flv' | 'video/mpg' | 'video/webm' | 'video/wmv' | 'video/3gpp' | (string & {});
+
// @public (undocumented)
export interface VoiceActivityDetectionSignal {
vadSignalType?: VadSignalType;
diff --git a/api-report/genai-web.api.md b/api-report/genai-web.api.md
index d62bb9304..b48eab2bd 100644
--- a/api-report/genai-web.api.md
+++ b/api-report/genai-web.api.md
@@ -4,8 +4,11 @@
```ts
+///
+
import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { GoogleAuthOptions } from 'google-auth-library';
+import { ReadableStream as ReadableStream_2 } from 'stream/web';
// @public
export interface ActivityEnd {
@@ -33,6 +36,19 @@ export enum AdapterSize {
ADAPTER_SIZE_UNSPECIFIED = "ADAPTER_SIZE_UNSPECIFIED"
}
+// @public
+interface AllowedTools {
+ mode?: ToolChoiceType;
+ tools?: Array;
+}
+
+// @public
+interface Annotation {
+ end_index?: number;
+ source?: string;
+ start_index?: number;
+}
+
// @public
export interface ApiAuth {
apiKeyConfig?: ApiAuthApiKeyConfig;
@@ -78,6 +94,19 @@ export interface AudioChunk {
sourceMetadata?: LiveMusicSourceMetadata;
}
+// @public
+interface AudioContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: AudioMimeType;
+ type: 'audio';
+ // (undocumented)
+ uri?: string;
+}
+
+// @public
+type AudioMimeType = 'audio/wav' | 'audio/mp3' | 'audio/aiff' | 'audio/aac' | 'audio/ogg' | 'audio/flac' | (string & {});
+
// @public
export interface AudioTranscriptionConfig {
}
@@ -147,6 +176,68 @@ export interface AutomaticFunctionCallingConfig {
maximumRemoteCalls?: number;
}
+// @public (undocumented)
+interface BaseCreateAgentInteractionParams {
+ agent: (string & {}) | 'deep-research-pro-preview-12-2025';
+ agent_config?: DynamicAgentConfig | DeepResearchAgentConfig;
+ api_version?: string;
+ background?: boolean;
+ input: string | Array | Array | TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ previous_interaction_id?: string;
+ response_format?: unknown;
+ response_mime_type?: string;
+ response_modalities?: Array<'text' | 'image' | 'audio'>;
+ store?: boolean;
+ stream?: boolean;
+ system_instruction?: string;
+ tools?: Array;
+}
+
+// @public (undocumented)
+interface BaseCreateModelInteractionParams {
+ api_version?: string;
+ background?: boolean;
+ generation_config?: GenerationConfig_2;
+ input: string | Array | Array | TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ model: Model_2;
+ previous_interaction_id?: string;
+ response_format?: unknown;
+ response_mime_type?: string;
+ response_modalities?: Array<'text' | 'image' | 'audio'>;
+ store?: boolean;
+ stream?: boolean;
+ system_instruction?: string;
+ tools?: Array;
+}
+
+// Warning: (ae-forgotten-export) The symbol "APIResource" needs to be exported by the entry point index.d.ts
+//
+// @public (undocumented)
+class BaseInteractions extends APIResource {
+ cancel(id: string, params?: InteractionCancelParams | null | undefined, options?: RequestOptions): APIPromise;
+ // Warning: (ae-forgotten-export) The symbol "RequestOptions" needs to be exported by the entry point index.d.ts
+ // Warning: (ae-forgotten-export) The symbol "APIPromise" needs to be exported by the entry point index.d.ts
+ create(params: CreateModelInteractionParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // Warning: (ae-forgotten-export) The symbol "Stream" needs to be exported by the entry point index.d.ts
+ //
+ // (undocumented)
+ create(params: CreateModelInteractionParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ create(params: CreateAgentInteractionParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // (undocumented)
+ create(params: CreateAgentInteractionParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ create(params: BaseCreateModelInteractionParams | BaseCreateAgentInteractionParams, options?: RequestOptions): APIPromise | Interaction>;
+ delete(id: string, params?: InteractionDeleteParams | null | undefined, options?: RequestOptions): APIPromise;
+ get(id: string, params?: InteractionGetParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // (undocumented)
+ get(id: string, params: InteractionGetParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ get(id: string, params?: InteractionGetParamsBase | undefined, options?: RequestOptions): APIPromise | Interaction>;
+ // (undocumented)
+ static readonly _key: readonly ['interactions'];
+}
+
// @public
export interface BaseUrlParameters {
// (undocumented)
@@ -368,12 +459,34 @@ export interface CitationMetadata {
citations?: Citation[];
}
+// @public
+interface CodeExecutionCallArguments {
+ code?: string;
+ language?: 'python';
+}
+
+// @public
+interface CodeExecutionCallContent {
+ arguments?: CodeExecutionCallArguments;
+ id?: string;
+ type: 'code_execution_call';
+}
+
// @public
export interface CodeExecutionResult {
outcome?: Outcome;
output?: string;
}
+// @public
+interface CodeExecutionResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: string;
+ signature?: string;
+ type: 'code_execution_result';
+}
+
// @public
export interface CompletionStats {
failedCount?: string;
@@ -413,6 +526,202 @@ export interface Content {
role?: string;
}
+// @public (undocumented)
+interface ContentDelta {
+ // (undocumented)
+ delta?: ContentDelta.TextDelta | ContentDelta.ImageDelta | ContentDelta.AudioDelta | ContentDelta.DocumentDelta | ContentDelta.VideoDelta | ContentDelta.ThoughtSummaryDelta | ContentDelta.ThoughtSignatureDelta | ContentDelta.FunctionCallDelta | ContentDelta.FunctionResultDelta | ContentDelta.CodeExecutionCallDelta | ContentDelta.CodeExecutionResultDelta | ContentDelta.URLContextCallDelta | ContentDelta.URLContextResultDelta | ContentDelta.GoogleSearchCallDelta | ContentDelta.GoogleSearchResultDelta | ContentDelta.MCPServerToolCallDelta | ContentDelta.MCPServerToolResultDelta | ContentDelta.FileSearchResultDelta;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.delta';
+ // (undocumented)
+ index?: number;
+}
+
+// @public (undocumented)
+namespace ContentDelta {
+ // (undocumented)
+ interface AudioDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: AudioMimeType;
+ type: 'audio';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface CodeExecutionCallDelta {
+ arguments?: CodeExecutionCallArguments;
+ id?: string;
+ type: 'code_execution_call';
+ }
+ // (undocumented)
+ interface CodeExecutionResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: string;
+ // (undocumented)
+ signature?: string;
+ type: 'code_execution_result';
+ }
+ // (undocumented)
+ interface DocumentDelta {
+ // (undocumented)
+ data?: string;
+ // (undocumented)
+ mime_type?: string;
+ type: 'document';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface FileSearchResultDelta {
+ // (undocumented)
+ result?: Array;
+ type: 'file_search_result';
+ }
+ // (undocumented)
+ namespace FileSearchResultDelta {
+ interface Result {
+ file_search_store?: string;
+ text?: string;
+ title?: string;
+ }
+ }
+ // (undocumented)
+ interface FunctionCallDelta {
+ // (undocumented)
+ arguments?: {
+ [key: string]: unknown;
+ };
+ id?: string;
+ // (undocumented)
+ name?: string;
+ type: 'function_call';
+ }
+ // (undocumented)
+ interface FunctionResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ name?: string;
+ result?: FunctionResultDelta.Items | string;
+ type: 'function_result';
+ }
+ // (undocumented)
+ namespace FunctionResultDelta {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+ }
+ // (undocumented)
+ interface GoogleSearchCallDelta {
+ arguments?: GoogleSearchCallArguments;
+ id?: string;
+ type: 'google_search_call';
+ }
+ // (undocumented)
+ interface GoogleSearchResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: Array;
+ // (undocumented)
+ signature?: string;
+ type: 'google_search_result';
+ }
+ // (undocumented)
+ interface ImageDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: ImageMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'image';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface MCPServerToolCallDelta {
+ // (undocumented)
+ arguments?: {
+ [key: string]: unknown;
+ };
+ id?: string;
+ // (undocumented)
+ name?: string;
+ // (undocumented)
+ server_name?: string;
+ type: 'mcp_server_tool_call';
+ }
+ // (undocumented)
+ interface MCPServerToolResultDelta {
+ call_id?: string;
+ // (undocumented)
+ name?: string;
+ result?: MCPServerToolResultDelta.Items | string;
+ // (undocumented)
+ server_name?: string;
+ type: 'mcp_server_tool_result';
+ }
+ // (undocumented)
+ namespace MCPServerToolResultDelta {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+ }
+ // (undocumented)
+ interface TextDelta {
+ annotations?: Array;
+ // (undocumented)
+ text?: string;
+ type: 'text';
+ }
+ // (undocumented)
+ interface ThoughtSignatureDelta {
+ signature?: string;
+ type: 'thought_signature';
+ }
+ // (undocumented)
+ interface ThoughtSummaryDelta {
+ content?: TextContent | ImageContent;
+ type: 'thought_summary';
+ }
+ // (undocumented)
+ interface URLContextCallDelta {
+ arguments?: URLContextCallArguments;
+ id?: string;
+ type: 'url_context_call';
+ }
+ // (undocumented)
+ interface URLContextResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: Array;
+ // (undocumented)
+ signature?: string;
+ type: 'url_context_result';
+ }
+ // (undocumented)
+ interface VideoDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: VideoMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'video';
+ // (undocumented)
+ uri?: string;
+ }
+}
+
// @public
export interface ContentEmbedding {
statistics?: ContentEmbeddingStatistics;
@@ -437,6 +746,25 @@ export class ContentReferenceImage {
toReferenceImageAPI(): ReferenceImageAPIInternal;
}
+// @public (undocumented)
+interface ContentStart {
+ content?: TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.start';
+ // (undocumented)
+ index?: number;
+}
+
+// @public (undocumented)
+interface ContentStop {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.stop';
+ // (undocumented)
+ index?: number;
+}
+
// @public (undocumented)
export type ContentUnion = Content | PartUnion[] | PartUnion;
@@ -496,6 +824,16 @@ export class CountTokensResponse {
totalTokens?: number;
}
+// @public (undocumented)
+interface CreateAgentInteractionParamsNonStreaming extends BaseCreateAgentInteractionParams {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface CreateAgentInteractionParamsStreaming extends BaseCreateAgentInteractionParams {
+ stream: true;
+}
+
// @public
export interface CreateAuthTokenConfig {
abortSignal?: AbortSignal;
@@ -606,6 +944,16 @@ export function createFunctionResponsePartFromUri(uri: string, mimeType: string)
// @public
export function createModelContent(partOrString: PartListUnion | string): Content;
+// @public (undocumented)
+interface CreateModelInteractionParamsNonStreaming extends BaseCreateModelInteractionParams {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface CreateModelInteractionParamsStreaming extends BaseCreateModelInteractionParams {
+ stream: true;
+}
+
// @public
export function createPartFromBase64(data: string, mimeType: string, mediaResolution?: PartMediaResolutionLevel): Part;
@@ -703,6 +1051,12 @@ export interface DatasetStats {
userOutputTokenDistribution?: DatasetDistribution;
}
+// @public
+interface DeepResearchAgentConfig {
+ thinking_summaries?: 'auto' | 'none';
+ type?: 'deep-research';
+}
+
// @public
export interface DeleteBatchJobConfig {
abortSignal?: AbortSignal;
@@ -822,6 +1176,17 @@ interface Document_2 {
}
export { Document_2 as Document }
+// @public
+interface DocumentContent {
+ // (undocumented)
+ data?: string;
+ // (undocumented)
+ mime_type?: string;
+ type: 'document';
+ // (undocumented)
+ uri?: string;
+}
+
// @public
export enum DocumentState {
// (undocumented)
@@ -850,6 +1215,13 @@ export interface DownloadFileParameters {
file: DownloadableFileUnion;
}
+// @public
+interface DynamicAgentConfig {
+ // (undocumented)
+ [k: string]: unknown;
+ type?: 'dynamic';
+}
+
// @public
export interface DynamicRetrievalConfig {
dynamicThreshold?: number;
@@ -997,6 +1369,22 @@ export enum Environment {
ENVIRONMENT_UNSPECIFIED = "ENVIRONMENT_UNSPECIFIED"
}
+// @public (undocumented)
+interface ErrorEvent_2 {
+ error?: ErrorEvent_2.Error;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'error';
+}
+
+// @public (undocumented)
+namespace ErrorEvent_2 {
+ interface Error {
+ code?: string;
+ message?: string;
+ }
+}
+
// @public
export interface ExecutableCode {
code?: string;
@@ -1093,6 +1481,21 @@ export interface FileSearch {
topK?: number;
}
+// @public
+interface FileSearchResultContent {
+ result?: Array;
+ type: 'file_search_result';
+}
+
+// @public (undocumented)
+namespace FileSearchResultContent {
+ interface Result {
+ file_search_store?: string;
+ text?: string;
+ title?: string;
+ }
+}
+
// @public
export interface FileSearchStore {
activeDocumentsCount?: string;
@@ -1153,6 +1556,15 @@ export enum FinishReason {
UNEXPECTED_TOOL_CALL = "UNEXPECTED_TOOL_CALL"
}
+// @public
+interface Function_2 {
+ description?: string;
+ name?: string;
+ parameters?: unknown;
+ // (undocumented)
+ type: 'function';
+}
+
// @public
export interface FunctionCall {
args?: Record;
@@ -1162,6 +1574,16 @@ export interface FunctionCall {
willContinue?: boolean;
}
+// @public
+interface FunctionCallContent {
+ arguments: {
+ [key: string]: unknown;
+ };
+ id: string;
+ name: string;
+ type: 'function_call';
+}
+
// @public
export interface FunctionCallingConfig {
allowedFunctionNames?: string[];
@@ -1227,6 +1649,24 @@ export enum FunctionResponseScheduling {
WHEN_IDLE = "WHEN_IDLE"
}
+// @public
+interface FunctionResultContent {
+ call_id: string;
+ is_error?: boolean;
+ name?: string;
+ result: FunctionResultContent.Items | unknown | string;
+ type: 'function_result';
+}
+
+// @public (undocumented)
+namespace FunctionResultContent {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+}
+
// @public
export interface GeminiPreferenceExample {
completions?: GeminiPreferenceExampleCompletion[];
@@ -1462,6 +1902,19 @@ export interface GenerationConfig {
topP?: number;
}
+// @public
+interface GenerationConfig_2 {
+ max_output_tokens?: number;
+ seed?: number;
+ speech_config?: Array;
+ stop_sequences?: Array;
+ temperature?: number;
+ thinking_level?: ThinkingLevel_2;
+ thinking_summaries?: 'auto' | 'none';
+ tool_choice?: ToolChoice;
+ top_p?: number;
+}
+
// @public
export interface GenerationConfigRoutingConfig {
autoMode?: GenerationConfigRoutingConfigAutoRoutingMode;
@@ -1600,6 +2053,8 @@ export class GoogleGenAI {
// (undocumented)
readonly fileSearchStores: FileSearchStores;
// (undocumented)
+ get interactions(): Interactions_2;
+ // (undocumented)
readonly live: Live;
// (undocumented)
readonly models: Models;
@@ -1644,6 +2099,34 @@ export interface GoogleSearch {
timeRangeFilter?: Interval;
}
+// @public
+interface GoogleSearchCallArguments {
+ queries?: Array;
+}
+
+// @public
+interface GoogleSearchCallContent {
+ arguments?: GoogleSearchCallArguments;
+ id?: string;
+ type: 'google_search_call';
+}
+
+// @public
+interface GoogleSearchResult {
+ rendered_content?: string;
+ title?: string;
+ url?: string;
+}
+
+// @public
+interface GoogleSearchResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: Array;
+ signature?: string;
+ type: 'google_search_result';
+}
+
// @public
export interface GoogleSearchRetrieval {
dynamicRetrievalConfig?: DynamicRetrievalConfig;
@@ -1832,6 +2315,20 @@ export interface ImageConfig {
outputMimeType?: string;
}
+// @public
+interface ImageContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: ImageMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'image';
+ // (undocumented)
+ uri?: string;
+}
+
+// @public
+type ImageMimeType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/heic' | 'image/heif' | (string & {});
+
// @public
export enum ImagePromptLanguage {
auto = "auto",
@@ -1898,6 +2395,166 @@ export class InlinedResponse {
response?: GenerateContentResponse;
}
+// @public
+interface Interaction {
+ agent?: (string & {}) | 'deep-research-pro-preview-12-2025';
+ created?: string;
+ error?: Interaction.Error;
+ id: string;
+ model?: Model_2;
+ object?: 'interaction';
+ outputs?: Array;
+ previous_interaction_id?: string;
+ role?: string;
+ status: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled';
+ updated?: string;
+ usage?: Usage;
+}
+
+// @public (undocumented)
+namespace Interaction {
+ interface Error {
+ code?: string;
+ message?: string;
+ }
+}
+
+// @public (undocumented)
+interface InteractionCancelParams {
+ api_version?: string;
+}
+
+// @public (undocumented)
+type InteractionCreateParams = CreateModelInteractionParamsNonStreaming | CreateModelInteractionParamsStreaming | CreateAgentInteractionParamsNonStreaming | CreateAgentInteractionParamsStreaming;
+
+// @public (undocumented)
+interface InteractionDeleteParams {
+ api_version?: string;
+}
+
+// @public (undocumented)
+type InteractionDeleteResponse = unknown;
+
+// @public (undocumented)
+interface InteractionEvent {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'interaction.start' | 'interaction.complete';
+ interaction?: Interaction;
+}
+
+// @public (undocumented)
+type InteractionGetParams = InteractionGetParamsNonStreaming | InteractionGetParamsStreaming;
+
+// @public (undocumented)
+interface InteractionGetParamsBase {
+ api_version?: string;
+ last_event_id?: string;
+ stream?: boolean;
+}
+
+// @public (undocumented)
+interface InteractionGetParamsNonStreaming extends InteractionGetParamsBase {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface InteractionGetParamsStreaming extends InteractionGetParamsBase {
+ stream: true;
+}
+
+declare namespace Interactions {
+ export {
+ BaseInteractions,
+ Interactions_2 as Interactions,
+ AllowedTools,
+ Annotation,
+ AudioContent,
+ AudioMimeType,
+ CodeExecutionCallArguments,
+ CodeExecutionCallContent,
+ CodeExecutionResultContent,
+ ContentDelta,
+ ContentStart,
+ ContentStop,
+ DeepResearchAgentConfig,
+ DocumentContent,
+ DynamicAgentConfig,
+ ErrorEvent_2 as ErrorEvent,
+ FileSearchResultContent,
+ Function_2 as Function,
+ FunctionCallContent,
+ FunctionResultContent,
+ GenerationConfig_2 as GenerationConfig,
+ GoogleSearchCallArguments,
+ GoogleSearchCallContent,
+ GoogleSearchResult,
+ GoogleSearchResultContent,
+ ImageContent,
+ ImageMimeType,
+ Interaction,
+ InteractionEvent,
+ InteractionSSEEvent,
+ InteractionStatusUpdate,
+ MCPServerToolCallContent,
+ MCPServerToolResultContent,
+ Model_2 as Model,
+ SpeechConfig_2 as SpeechConfig,
+ TextContent,
+ ThinkingLevel_2 as ThinkingLevel,
+ ThoughtContent,
+ Tool_2 as Tool,
+ ToolChoice,
+ ToolChoiceConfig,
+ ToolChoiceType,
+ Turn,
+ URLContextCallArguments,
+ URLContextCallContent,
+ URLContextResult,
+ URLContextResultContent,
+ Usage,
+ VideoContent,
+ VideoMimeType,
+ InteractionDeleteResponse,
+ InteractionCreateParams,
+ BaseCreateModelInteractionParams,
+ BaseCreateAgentInteractionParams,
+ CreateModelInteractionParamsNonStreaming,
+ CreateModelInteractionParamsStreaming,
+ CreateAgentInteractionParamsNonStreaming,
+ CreateAgentInteractionParamsStreaming,
+ InteractionDeleteParams,
+ InteractionCancelParams,
+ InteractionGetParams,
+ InteractionGetParamsBase,
+ InteractionGetParamsNonStreaming,
+ InteractionGetParamsStreaming
+ }
+}
+
+// @public (undocumented)
+class Interactions_2 extends BaseInteractions {
+}
+
+// @public (undocumented)
+namespace Interactions_2 {
+ { type AllowedTools as AllowedTools, type Annotation as Annotation, type AudioContent as AudioContent, type AudioMimeType as AudioMimeType, type CodeExecutionCallArguments as CodeExecutionCallArguments, type CodeExecutionCallContent as CodeExecutionCallContent, type CodeExecutionResultContent as CodeExecutionResultContent, type ContentDelta as ContentDelta, type ContentStart as ContentStart, type ContentStop as ContentStop, type DeepResearchAgentConfig as DeepResearchAgentConfig, type DocumentContent as DocumentContent, type DynamicAgentConfig as DynamicAgentConfig, type ErrorEvent as ErrorEvent, type FileSearchResultContent as FileSearchResultContent, type Function as Function, type FunctionCallContent as FunctionCallContent, type FunctionResultContent as FunctionResultContent, type GenerationConfig as GenerationConfig, type GoogleSearchCallArguments as GoogleSearchCallArguments, type GoogleSearchCallContent as GoogleSearchCallContent, type GoogleSearchResult as GoogleSearchResult, type GoogleSearchResultContent as GoogleSearchResultContent, type ImageContent as ImageContent, type ImageMimeType as ImageMimeType, type Interaction as Interaction, type InteractionEvent as InteractionEvent, type InteractionSSEEvent as InteractionSSEEvent, type InteractionStatusUpdate as InteractionStatusUpdate, type MCPServerToolCallContent as MCPServerToolCallContent, type MCPServerToolResultContent as MCPServerToolResultContent, type Model as Model, type SpeechConfig as SpeechConfig, type TextContent as TextContent, type ThinkingLevel as ThinkingLevel, type ThoughtContent as ThoughtContent, type Tool as Tool, type ToolChoice as ToolChoice, type ToolChoiceConfig as ToolChoiceConfig, type ToolChoiceType as ToolChoiceType, type Turn as Turn, type URLContextCallArguments as URLContextCallArguments, type URLContextCallContent as URLContextCallContent, type URLContextResult as URLContextResult, type URLContextResultContent as URLContextResultContent, type Usage as Usage, type VideoContent as VideoContent, type VideoMimeType as VideoMimeType, type InteractionDeleteResponse as InteractionDeleteResponse, type InteractionCreateParams as InteractionCreateParams, type CreateModelInteractionParamsNonStreaming as CreateModelInteractionParamsNonStreaming, type CreateModelInteractionParamsStreaming as CreateModelInteractionParamsStreaming, type CreateAgentInteractionParamsNonStreaming as CreateAgentInteractionParamsNonStreaming, type CreateAgentInteractionParamsStreaming as CreateAgentInteractionParamsStreaming, type InteractionDeleteParams as InteractionDeleteParams, type InteractionCancelParams as InteractionCancelParams, type InteractionGetParams as InteractionGetParams, type InteractionGetParamsNonStreaming as InteractionGetParamsNonStreaming, type InteractionGetParamsStreaming as InteractionGetParamsStreaming, };
+}
+
+// @public (undocumented)
+type InteractionSSEEvent = InteractionEvent | InteractionStatusUpdate | ContentStart | ContentDelta | ContentStop | ErrorEvent_2;
+
+// @public (undocumented)
+interface InteractionStatusUpdate {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'interaction.status_update';
+ // (undocumented)
+ interaction_id?: string;
+ // (undocumented)
+ status?: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled';
+}
+
// @public
export interface Interval {
endTime?: string;
@@ -2451,6 +3108,35 @@ export enum MaskReferenceMode {
MASK_MODE_USER_PROVIDED = "MASK_MODE_USER_PROVIDED"
}
+// @public
+interface MCPServerToolCallContent {
+ arguments: {
+ [key: string]: unknown;
+ };
+ id: string;
+ name: string;
+ server_name: string;
+ type: 'mcp_server_tool_call';
+}
+
+// @public
+interface MCPServerToolResultContent {
+ call_id: string;
+ name?: string;
+ result: MCPServerToolResultContent.Items | unknown | string;
+ server_name?: string;
+ type: 'mcp_server_tool_result';
+}
+
+// @public (undocumented)
+namespace MCPServerToolResultContent {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+}
+
// @public
export function mcpToTool(...args: [...Client[], CallableToolConfig | Client]): CallableTool;
@@ -2513,6 +3199,9 @@ export interface Model {
version?: string;
}
+// @public
+type Model_2 = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-preview-09-2025' | 'gemini-2.5-flash-lite' | 'gemini-2.5-flash-lite-preview-09-2025' | 'gemini-2.5-flash-preview-native-audio-dialog' | 'gemini-2.5-flash-image-preview' | 'gemini-2.5-pro-preview-tts' | 'gemini-3-pro-preview' | (string & {});
+
// @public (undocumented)
export class Models extends BaseModule {
constructor(apiClient: ApiClient);
@@ -3114,6 +3803,13 @@ export interface SpeechConfig {
voiceConfig?: VoiceConfig;
}
+// @public
+interface SpeechConfig_2 {
+ language?: string;
+ speaker?: string;
+ voice?: string;
+}
+
// @public (undocumented)
export type SpeechConfigUnion = SpeechConfig | string;
@@ -3249,6 +3945,13 @@ export interface TestTableItem {
skipInApiMode?: string;
}
+// @public
+interface TextContent {
+ annotations?: Array;
+ text?: string;
+ type: 'text';
+}
+
// @public
export interface ThinkingConfig {
includeThoughts?: boolean;
@@ -3263,6 +3966,16 @@ export enum ThinkingLevel {
THINKING_LEVEL_UNSPECIFIED = "THINKING_LEVEL_UNSPECIFIED"
}
+// @public (undocumented)
+type ThinkingLevel_2 = 'low' | 'high';
+
+// @public
+interface ThoughtContent {
+ signature?: string;
+ summary?: Array;
+ type: 'thought';
+}
+
// @public (undocumented)
export class Tokens extends BaseModule {
constructor(apiClient: ApiClient);
@@ -3290,6 +4003,59 @@ export interface Tool {
urlContext?: UrlContext;
}
+// @public
+type Tool_2 = Function_2 | Tool_2.GoogleSearch | Tool_2.CodeExecution | Tool_2.URLContext | Tool_2.ComputerUse | Tool_2.MCPServer | Tool_2.FileSearch;
+
+// @public (undocumented)
+namespace Tool_2 {
+ interface CodeExecution {
+ // (undocumented)
+ type: 'code_execution';
+ }
+ interface ComputerUse {
+ environment?: 'browser';
+ excludedPredefinedFunctions?: Array;
+ // (undocumented)
+ type: 'computer_use';
+ }
+ interface FileSearch {
+ file_search_store_names?: Array;
+ metadata_filter?: string;
+ top_k?: number;
+ // (undocumented)
+ type: 'file_search';
+ }
+ interface GoogleSearch {
+ // (undocumented)
+ type: 'google_search';
+ }
+ interface MCPServer {
+ allowed_tools?: Array;
+ headers?: {
+ [key: string]: string;
+ };
+ name?: string;
+ // (undocumented)
+ type: 'mcp_server';
+ url?: string;
+ }
+ interface URLContext {
+ // (undocumented)
+ type: 'url_context';
+ }
+}
+
+// @public
+type ToolChoice = ToolChoiceType | ToolChoiceConfig;
+
+// @public (undocumented)
+interface ToolChoiceConfig {
+ allowed_tools?: AllowedTools;
+}
+
+// @public (undocumented)
+type ToolChoiceType = 'auto' | 'any' | 'none' | 'validated';
+
// @public
export interface ToolCodeExecution {
}
@@ -3426,6 +4192,12 @@ export interface TuningValidationDataset {
vertexDatasetResource?: string;
}
+// @public (undocumented)
+interface Turn {
+ content?: string | Array;
+ role?: string;
+}
+
// @public
export enum TurnCompleteReason {
MALFORMED_FUNCTION_CALL = "MALFORMED_FUNCTION_CALL",
@@ -3582,11 +4354,38 @@ export class UpscaleImageResponse {
export interface UrlContext {
}
+// @public
+interface URLContextCallArguments {
+ urls?: Array;
+}
+
+// @public
+interface URLContextCallContent {
+ arguments?: URLContextCallArguments;
+ id?: string;
+ type: 'url_context_call';
+}
+
// @public
export interface UrlContextMetadata {
urlMetadata?: UrlMetadata[];
}
+// @public
+interface URLContextResult {
+ status?: 'success' | 'error' | 'paywall' | 'unsafe';
+ url?: string;
+}
+
+// @public
+interface URLContextResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: Array;
+ signature?: string;
+ type: 'url_context_result';
+}
+
// @public
export interface UrlMetadata {
retrievedUrl?: string;
@@ -3602,6 +4401,40 @@ export enum UrlRetrievalStatus {
URL_RETRIEVAL_STATUS_UNSPECIFIED = "URL_RETRIEVAL_STATUS_UNSPECIFIED"
}
+// @public
+interface Usage {
+ cached_tokens_by_modality?: Array;
+ input_tokens_by_modality?: Array;
+ output_tokens_by_modality?: Array;
+ tool_use_tokens_by_modality?: Array;
+ total_cached_tokens?: number;
+ total_input_tokens?: number;
+ total_output_tokens?: number;
+ total_reasoning_tokens?: number;
+ total_tokens?: number;
+ total_tool_use_tokens?: number;
+}
+
+// @public (undocumented)
+namespace Usage {
+ interface CachedTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface InputTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface OutputTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface ToolUseTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+}
+
// @public
export interface UsageMetadata {
cachedContentTokenCount?: number;
@@ -3682,6 +4515,17 @@ export enum VideoCompressionQuality {
OPTIMIZED = "OPTIMIZED"
}
+// @public
+interface VideoContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: VideoMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'video';
+ // (undocumented)
+ uri?: string;
+}
+
// @public
export interface VideoGenerationMask {
image?: Image_2;
@@ -3715,6 +4559,9 @@ export interface VideoMetadata {
startOffset?: string;
}
+// @public
+type VideoMimeType = 'video/mp4' | 'video/mpeg' | 'video/mov' | 'video/avi' | 'video/x-flv' | 'video/mpg' | 'video/webm' | 'video/wmv' | 'video/3gpp' | (string & {});
+
// @public (undocumented)
export interface VoiceActivityDetectionSignal {
vadSignalType?: VadSignalType;
diff --git a/api-report/genai.api.md b/api-report/genai.api.md
index d62bb9304..b48eab2bd 100644
--- a/api-report/genai.api.md
+++ b/api-report/genai.api.md
@@ -4,8 +4,11 @@
```ts
+///
+
import type { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { GoogleAuthOptions } from 'google-auth-library';
+import { ReadableStream as ReadableStream_2 } from 'stream/web';
// @public
export interface ActivityEnd {
@@ -33,6 +36,19 @@ export enum AdapterSize {
ADAPTER_SIZE_UNSPECIFIED = "ADAPTER_SIZE_UNSPECIFIED"
}
+// @public
+interface AllowedTools {
+ mode?: ToolChoiceType;
+ tools?: Array;
+}
+
+// @public
+interface Annotation {
+ end_index?: number;
+ source?: string;
+ start_index?: number;
+}
+
// @public
export interface ApiAuth {
apiKeyConfig?: ApiAuthApiKeyConfig;
@@ -78,6 +94,19 @@ export interface AudioChunk {
sourceMetadata?: LiveMusicSourceMetadata;
}
+// @public
+interface AudioContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: AudioMimeType;
+ type: 'audio';
+ // (undocumented)
+ uri?: string;
+}
+
+// @public
+type AudioMimeType = 'audio/wav' | 'audio/mp3' | 'audio/aiff' | 'audio/aac' | 'audio/ogg' | 'audio/flac' | (string & {});
+
// @public
export interface AudioTranscriptionConfig {
}
@@ -147,6 +176,68 @@ export interface AutomaticFunctionCallingConfig {
maximumRemoteCalls?: number;
}
+// @public (undocumented)
+interface BaseCreateAgentInteractionParams {
+ agent: (string & {}) | 'deep-research-pro-preview-12-2025';
+ agent_config?: DynamicAgentConfig | DeepResearchAgentConfig;
+ api_version?: string;
+ background?: boolean;
+ input: string | Array | Array | TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ previous_interaction_id?: string;
+ response_format?: unknown;
+ response_mime_type?: string;
+ response_modalities?: Array<'text' | 'image' | 'audio'>;
+ store?: boolean;
+ stream?: boolean;
+ system_instruction?: string;
+ tools?: Array;
+}
+
+// @public (undocumented)
+interface BaseCreateModelInteractionParams {
+ api_version?: string;
+ background?: boolean;
+ generation_config?: GenerationConfig_2;
+ input: string | Array | Array | TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ model: Model_2;
+ previous_interaction_id?: string;
+ response_format?: unknown;
+ response_mime_type?: string;
+ response_modalities?: Array<'text' | 'image' | 'audio'>;
+ store?: boolean;
+ stream?: boolean;
+ system_instruction?: string;
+ tools?: Array;
+}
+
+// Warning: (ae-forgotten-export) The symbol "APIResource" needs to be exported by the entry point index.d.ts
+//
+// @public (undocumented)
+class BaseInteractions extends APIResource {
+ cancel(id: string, params?: InteractionCancelParams | null | undefined, options?: RequestOptions): APIPromise;
+ // Warning: (ae-forgotten-export) The symbol "RequestOptions" needs to be exported by the entry point index.d.ts
+ // Warning: (ae-forgotten-export) The symbol "APIPromise" needs to be exported by the entry point index.d.ts
+ create(params: CreateModelInteractionParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // Warning: (ae-forgotten-export) The symbol "Stream" needs to be exported by the entry point index.d.ts
+ //
+ // (undocumented)
+ create(params: CreateModelInteractionParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ create(params: CreateAgentInteractionParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // (undocumented)
+ create(params: CreateAgentInteractionParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ create(params: BaseCreateModelInteractionParams | BaseCreateAgentInteractionParams, options?: RequestOptions): APIPromise | Interaction>;
+ delete(id: string, params?: InteractionDeleteParams | null | undefined, options?: RequestOptions): APIPromise;
+ get(id: string, params?: InteractionGetParamsNonStreaming, options?: RequestOptions): APIPromise;
+ // (undocumented)
+ get(id: string, params: InteractionGetParamsStreaming, options?: RequestOptions): APIPromise>;
+ // (undocumented)
+ get(id: string, params?: InteractionGetParamsBase | undefined, options?: RequestOptions): APIPromise | Interaction>;
+ // (undocumented)
+ static readonly _key: readonly ['interactions'];
+}
+
// @public
export interface BaseUrlParameters {
// (undocumented)
@@ -368,12 +459,34 @@ export interface CitationMetadata {
citations?: Citation[];
}
+// @public
+interface CodeExecutionCallArguments {
+ code?: string;
+ language?: 'python';
+}
+
+// @public
+interface CodeExecutionCallContent {
+ arguments?: CodeExecutionCallArguments;
+ id?: string;
+ type: 'code_execution_call';
+}
+
// @public
export interface CodeExecutionResult {
outcome?: Outcome;
output?: string;
}
+// @public
+interface CodeExecutionResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: string;
+ signature?: string;
+ type: 'code_execution_result';
+}
+
// @public
export interface CompletionStats {
failedCount?: string;
@@ -413,6 +526,202 @@ export interface Content {
role?: string;
}
+// @public (undocumented)
+interface ContentDelta {
+ // (undocumented)
+ delta?: ContentDelta.TextDelta | ContentDelta.ImageDelta | ContentDelta.AudioDelta | ContentDelta.DocumentDelta | ContentDelta.VideoDelta | ContentDelta.ThoughtSummaryDelta | ContentDelta.ThoughtSignatureDelta | ContentDelta.FunctionCallDelta | ContentDelta.FunctionResultDelta | ContentDelta.CodeExecutionCallDelta | ContentDelta.CodeExecutionResultDelta | ContentDelta.URLContextCallDelta | ContentDelta.URLContextResultDelta | ContentDelta.GoogleSearchCallDelta | ContentDelta.GoogleSearchResultDelta | ContentDelta.MCPServerToolCallDelta | ContentDelta.MCPServerToolResultDelta | ContentDelta.FileSearchResultDelta;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.delta';
+ // (undocumented)
+ index?: number;
+}
+
+// @public (undocumented)
+namespace ContentDelta {
+ // (undocumented)
+ interface AudioDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: AudioMimeType;
+ type: 'audio';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface CodeExecutionCallDelta {
+ arguments?: CodeExecutionCallArguments;
+ id?: string;
+ type: 'code_execution_call';
+ }
+ // (undocumented)
+ interface CodeExecutionResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: string;
+ // (undocumented)
+ signature?: string;
+ type: 'code_execution_result';
+ }
+ // (undocumented)
+ interface DocumentDelta {
+ // (undocumented)
+ data?: string;
+ // (undocumented)
+ mime_type?: string;
+ type: 'document';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface FileSearchResultDelta {
+ // (undocumented)
+ result?: Array;
+ type: 'file_search_result';
+ }
+ // (undocumented)
+ namespace FileSearchResultDelta {
+ interface Result {
+ file_search_store?: string;
+ text?: string;
+ title?: string;
+ }
+ }
+ // (undocumented)
+ interface FunctionCallDelta {
+ // (undocumented)
+ arguments?: {
+ [key: string]: unknown;
+ };
+ id?: string;
+ // (undocumented)
+ name?: string;
+ type: 'function_call';
+ }
+ // (undocumented)
+ interface FunctionResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ name?: string;
+ result?: FunctionResultDelta.Items | string;
+ type: 'function_result';
+ }
+ // (undocumented)
+ namespace FunctionResultDelta {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+ }
+ // (undocumented)
+ interface GoogleSearchCallDelta {
+ arguments?: GoogleSearchCallArguments;
+ id?: string;
+ type: 'google_search_call';
+ }
+ // (undocumented)
+ interface GoogleSearchResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: Array;
+ // (undocumented)
+ signature?: string;
+ type: 'google_search_result';
+ }
+ // (undocumented)
+ interface ImageDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: ImageMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'image';
+ // (undocumented)
+ uri?: string;
+ }
+ // (undocumented)
+ interface MCPServerToolCallDelta {
+ // (undocumented)
+ arguments?: {
+ [key: string]: unknown;
+ };
+ id?: string;
+ // (undocumented)
+ name?: string;
+ // (undocumented)
+ server_name?: string;
+ type: 'mcp_server_tool_call';
+ }
+ // (undocumented)
+ interface MCPServerToolResultDelta {
+ call_id?: string;
+ // (undocumented)
+ name?: string;
+ result?: MCPServerToolResultDelta.Items | string;
+ // (undocumented)
+ server_name?: string;
+ type: 'mcp_server_tool_result';
+ }
+ // (undocumented)
+ namespace MCPServerToolResultDelta {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+ }
+ // (undocumented)
+ interface TextDelta {
+ annotations?: Array;
+ // (undocumented)
+ text?: string;
+ type: 'text';
+ }
+ // (undocumented)
+ interface ThoughtSignatureDelta {
+ signature?: string;
+ type: 'thought_signature';
+ }
+ // (undocumented)
+ interface ThoughtSummaryDelta {
+ content?: TextContent | ImageContent;
+ type: 'thought_summary';
+ }
+ // (undocumented)
+ interface URLContextCallDelta {
+ arguments?: URLContextCallArguments;
+ id?: string;
+ type: 'url_context_call';
+ }
+ // (undocumented)
+ interface URLContextResultDelta {
+ call_id?: string;
+ // (undocumented)
+ is_error?: boolean;
+ // (undocumented)
+ result?: Array;
+ // (undocumented)
+ signature?: string;
+ type: 'url_context_result';
+ }
+ // (undocumented)
+ interface VideoDelta {
+ // (undocumented)
+ data?: string;
+ mime_type?: VideoMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'video';
+ // (undocumented)
+ uri?: string;
+ }
+}
+
// @public
export interface ContentEmbedding {
statistics?: ContentEmbeddingStatistics;
@@ -437,6 +746,25 @@ export class ContentReferenceImage {
toReferenceImageAPI(): ReferenceImageAPIInternal;
}
+// @public (undocumented)
+interface ContentStart {
+ content?: TextContent | ImageContent | AudioContent | DocumentContent | VideoContent | ThoughtContent | FunctionCallContent | FunctionResultContent | CodeExecutionCallContent | CodeExecutionResultContent | URLContextCallContent | URLContextResultContent | GoogleSearchCallContent | GoogleSearchResultContent | MCPServerToolCallContent | MCPServerToolResultContent | FileSearchResultContent;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.start';
+ // (undocumented)
+ index?: number;
+}
+
+// @public (undocumented)
+interface ContentStop {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'content.stop';
+ // (undocumented)
+ index?: number;
+}
+
// @public (undocumented)
export type ContentUnion = Content | PartUnion[] | PartUnion;
@@ -496,6 +824,16 @@ export class CountTokensResponse {
totalTokens?: number;
}
+// @public (undocumented)
+interface CreateAgentInteractionParamsNonStreaming extends BaseCreateAgentInteractionParams {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface CreateAgentInteractionParamsStreaming extends BaseCreateAgentInteractionParams {
+ stream: true;
+}
+
// @public
export interface CreateAuthTokenConfig {
abortSignal?: AbortSignal;
@@ -606,6 +944,16 @@ export function createFunctionResponsePartFromUri(uri: string, mimeType: string)
// @public
export function createModelContent(partOrString: PartListUnion | string): Content;
+// @public (undocumented)
+interface CreateModelInteractionParamsNonStreaming extends BaseCreateModelInteractionParams {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface CreateModelInteractionParamsStreaming extends BaseCreateModelInteractionParams {
+ stream: true;
+}
+
// @public
export function createPartFromBase64(data: string, mimeType: string, mediaResolution?: PartMediaResolutionLevel): Part;
@@ -703,6 +1051,12 @@ export interface DatasetStats {
userOutputTokenDistribution?: DatasetDistribution;
}
+// @public
+interface DeepResearchAgentConfig {
+ thinking_summaries?: 'auto' | 'none';
+ type?: 'deep-research';
+}
+
// @public
export interface DeleteBatchJobConfig {
abortSignal?: AbortSignal;
@@ -822,6 +1176,17 @@ interface Document_2 {
}
export { Document_2 as Document }
+// @public
+interface DocumentContent {
+ // (undocumented)
+ data?: string;
+ // (undocumented)
+ mime_type?: string;
+ type: 'document';
+ // (undocumented)
+ uri?: string;
+}
+
// @public
export enum DocumentState {
// (undocumented)
@@ -850,6 +1215,13 @@ export interface DownloadFileParameters {
file: DownloadableFileUnion;
}
+// @public
+interface DynamicAgentConfig {
+ // (undocumented)
+ [k: string]: unknown;
+ type?: 'dynamic';
+}
+
// @public
export interface DynamicRetrievalConfig {
dynamicThreshold?: number;
@@ -997,6 +1369,22 @@ export enum Environment {
ENVIRONMENT_UNSPECIFIED = "ENVIRONMENT_UNSPECIFIED"
}
+// @public (undocumented)
+interface ErrorEvent_2 {
+ error?: ErrorEvent_2.Error;
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'error';
+}
+
+// @public (undocumented)
+namespace ErrorEvent_2 {
+ interface Error {
+ code?: string;
+ message?: string;
+ }
+}
+
// @public
export interface ExecutableCode {
code?: string;
@@ -1093,6 +1481,21 @@ export interface FileSearch {
topK?: number;
}
+// @public
+interface FileSearchResultContent {
+ result?: Array;
+ type: 'file_search_result';
+}
+
+// @public (undocumented)
+namespace FileSearchResultContent {
+ interface Result {
+ file_search_store?: string;
+ text?: string;
+ title?: string;
+ }
+}
+
// @public
export interface FileSearchStore {
activeDocumentsCount?: string;
@@ -1153,6 +1556,15 @@ export enum FinishReason {
UNEXPECTED_TOOL_CALL = "UNEXPECTED_TOOL_CALL"
}
+// @public
+interface Function_2 {
+ description?: string;
+ name?: string;
+ parameters?: unknown;
+ // (undocumented)
+ type: 'function';
+}
+
// @public
export interface FunctionCall {
args?: Record;
@@ -1162,6 +1574,16 @@ export interface FunctionCall {
willContinue?: boolean;
}
+// @public
+interface FunctionCallContent {
+ arguments: {
+ [key: string]: unknown;
+ };
+ id: string;
+ name: string;
+ type: 'function_call';
+}
+
// @public
export interface FunctionCallingConfig {
allowedFunctionNames?: string[];
@@ -1227,6 +1649,24 @@ export enum FunctionResponseScheduling {
WHEN_IDLE = "WHEN_IDLE"
}
+// @public
+interface FunctionResultContent {
+ call_id: string;
+ is_error?: boolean;
+ name?: string;
+ result: FunctionResultContent.Items | unknown | string;
+ type: 'function_result';
+}
+
+// @public (undocumented)
+namespace FunctionResultContent {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+}
+
// @public
export interface GeminiPreferenceExample {
completions?: GeminiPreferenceExampleCompletion[];
@@ -1462,6 +1902,19 @@ export interface GenerationConfig {
topP?: number;
}
+// @public
+interface GenerationConfig_2 {
+ max_output_tokens?: number;
+ seed?: number;
+ speech_config?: Array;
+ stop_sequences?: Array;
+ temperature?: number;
+ thinking_level?: ThinkingLevel_2;
+ thinking_summaries?: 'auto' | 'none';
+ tool_choice?: ToolChoice;
+ top_p?: number;
+}
+
// @public
export interface GenerationConfigRoutingConfig {
autoMode?: GenerationConfigRoutingConfigAutoRoutingMode;
@@ -1600,6 +2053,8 @@ export class GoogleGenAI {
// (undocumented)
readonly fileSearchStores: FileSearchStores;
// (undocumented)
+ get interactions(): Interactions_2;
+ // (undocumented)
readonly live: Live;
// (undocumented)
readonly models: Models;
@@ -1644,6 +2099,34 @@ export interface GoogleSearch {
timeRangeFilter?: Interval;
}
+// @public
+interface GoogleSearchCallArguments {
+ queries?: Array;
+}
+
+// @public
+interface GoogleSearchCallContent {
+ arguments?: GoogleSearchCallArguments;
+ id?: string;
+ type: 'google_search_call';
+}
+
+// @public
+interface GoogleSearchResult {
+ rendered_content?: string;
+ title?: string;
+ url?: string;
+}
+
+// @public
+interface GoogleSearchResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: Array;
+ signature?: string;
+ type: 'google_search_result';
+}
+
// @public
export interface GoogleSearchRetrieval {
dynamicRetrievalConfig?: DynamicRetrievalConfig;
@@ -1832,6 +2315,20 @@ export interface ImageConfig {
outputMimeType?: string;
}
+// @public
+interface ImageContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: ImageMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'image';
+ // (undocumented)
+ uri?: string;
+}
+
+// @public
+type ImageMimeType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/heic' | 'image/heif' | (string & {});
+
// @public
export enum ImagePromptLanguage {
auto = "auto",
@@ -1898,6 +2395,166 @@ export class InlinedResponse {
response?: GenerateContentResponse;
}
+// @public
+interface Interaction {
+ agent?: (string & {}) | 'deep-research-pro-preview-12-2025';
+ created?: string;
+ error?: Interaction.Error;
+ id: string;
+ model?: Model_2;
+ object?: 'interaction';
+ outputs?: Array;
+ previous_interaction_id?: string;
+ role?: string;
+ status: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled';
+ updated?: string;
+ usage?: Usage;
+}
+
+// @public (undocumented)
+namespace Interaction {
+ interface Error {
+ code?: string;
+ message?: string;
+ }
+}
+
+// @public (undocumented)
+interface InteractionCancelParams {
+ api_version?: string;
+}
+
+// @public (undocumented)
+type InteractionCreateParams = CreateModelInteractionParamsNonStreaming | CreateModelInteractionParamsStreaming | CreateAgentInteractionParamsNonStreaming | CreateAgentInteractionParamsStreaming;
+
+// @public (undocumented)
+interface InteractionDeleteParams {
+ api_version?: string;
+}
+
+// @public (undocumented)
+type InteractionDeleteResponse = unknown;
+
+// @public (undocumented)
+interface InteractionEvent {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'interaction.start' | 'interaction.complete';
+ interaction?: Interaction;
+}
+
+// @public (undocumented)
+type InteractionGetParams = InteractionGetParamsNonStreaming | InteractionGetParamsStreaming;
+
+// @public (undocumented)
+interface InteractionGetParamsBase {
+ api_version?: string;
+ last_event_id?: string;
+ stream?: boolean;
+}
+
+// @public (undocumented)
+interface InteractionGetParamsNonStreaming extends InteractionGetParamsBase {
+ stream?: false;
+}
+
+// @public (undocumented)
+interface InteractionGetParamsStreaming extends InteractionGetParamsBase {
+ stream: true;
+}
+
+declare namespace Interactions {
+ export {
+ BaseInteractions,
+ Interactions_2 as Interactions,
+ AllowedTools,
+ Annotation,
+ AudioContent,
+ AudioMimeType,
+ CodeExecutionCallArguments,
+ CodeExecutionCallContent,
+ CodeExecutionResultContent,
+ ContentDelta,
+ ContentStart,
+ ContentStop,
+ DeepResearchAgentConfig,
+ DocumentContent,
+ DynamicAgentConfig,
+ ErrorEvent_2 as ErrorEvent,
+ FileSearchResultContent,
+ Function_2 as Function,
+ FunctionCallContent,
+ FunctionResultContent,
+ GenerationConfig_2 as GenerationConfig,
+ GoogleSearchCallArguments,
+ GoogleSearchCallContent,
+ GoogleSearchResult,
+ GoogleSearchResultContent,
+ ImageContent,
+ ImageMimeType,
+ Interaction,
+ InteractionEvent,
+ InteractionSSEEvent,
+ InteractionStatusUpdate,
+ MCPServerToolCallContent,
+ MCPServerToolResultContent,
+ Model_2 as Model,
+ SpeechConfig_2 as SpeechConfig,
+ TextContent,
+ ThinkingLevel_2 as ThinkingLevel,
+ ThoughtContent,
+ Tool_2 as Tool,
+ ToolChoice,
+ ToolChoiceConfig,
+ ToolChoiceType,
+ Turn,
+ URLContextCallArguments,
+ URLContextCallContent,
+ URLContextResult,
+ URLContextResultContent,
+ Usage,
+ VideoContent,
+ VideoMimeType,
+ InteractionDeleteResponse,
+ InteractionCreateParams,
+ BaseCreateModelInteractionParams,
+ BaseCreateAgentInteractionParams,
+ CreateModelInteractionParamsNonStreaming,
+ CreateModelInteractionParamsStreaming,
+ CreateAgentInteractionParamsNonStreaming,
+ CreateAgentInteractionParamsStreaming,
+ InteractionDeleteParams,
+ InteractionCancelParams,
+ InteractionGetParams,
+ InteractionGetParamsBase,
+ InteractionGetParamsNonStreaming,
+ InteractionGetParamsStreaming
+ }
+}
+
+// @public (undocumented)
+class Interactions_2 extends BaseInteractions {
+}
+
+// @public (undocumented)
+namespace Interactions_2 {
+ { type AllowedTools as AllowedTools, type Annotation as Annotation, type AudioContent as AudioContent, type AudioMimeType as AudioMimeType, type CodeExecutionCallArguments as CodeExecutionCallArguments, type CodeExecutionCallContent as CodeExecutionCallContent, type CodeExecutionResultContent as CodeExecutionResultContent, type ContentDelta as ContentDelta, type ContentStart as ContentStart, type ContentStop as ContentStop, type DeepResearchAgentConfig as DeepResearchAgentConfig, type DocumentContent as DocumentContent, type DynamicAgentConfig as DynamicAgentConfig, type ErrorEvent as ErrorEvent, type FileSearchResultContent as FileSearchResultContent, type Function as Function, type FunctionCallContent as FunctionCallContent, type FunctionResultContent as FunctionResultContent, type GenerationConfig as GenerationConfig, type GoogleSearchCallArguments as GoogleSearchCallArguments, type GoogleSearchCallContent as GoogleSearchCallContent, type GoogleSearchResult as GoogleSearchResult, type GoogleSearchResultContent as GoogleSearchResultContent, type ImageContent as ImageContent, type ImageMimeType as ImageMimeType, type Interaction as Interaction, type InteractionEvent as InteractionEvent, type InteractionSSEEvent as InteractionSSEEvent, type InteractionStatusUpdate as InteractionStatusUpdate, type MCPServerToolCallContent as MCPServerToolCallContent, type MCPServerToolResultContent as MCPServerToolResultContent, type Model as Model, type SpeechConfig as SpeechConfig, type TextContent as TextContent, type ThinkingLevel as ThinkingLevel, type ThoughtContent as ThoughtContent, type Tool as Tool, type ToolChoice as ToolChoice, type ToolChoiceConfig as ToolChoiceConfig, type ToolChoiceType as ToolChoiceType, type Turn as Turn, type URLContextCallArguments as URLContextCallArguments, type URLContextCallContent as URLContextCallContent, type URLContextResult as URLContextResult, type URLContextResultContent as URLContextResultContent, type Usage as Usage, type VideoContent as VideoContent, type VideoMimeType as VideoMimeType, type InteractionDeleteResponse as InteractionDeleteResponse, type InteractionCreateParams as InteractionCreateParams, type CreateModelInteractionParamsNonStreaming as CreateModelInteractionParamsNonStreaming, type CreateModelInteractionParamsStreaming as CreateModelInteractionParamsStreaming, type CreateAgentInteractionParamsNonStreaming as CreateAgentInteractionParamsNonStreaming, type CreateAgentInteractionParamsStreaming as CreateAgentInteractionParamsStreaming, type InteractionDeleteParams as InteractionDeleteParams, type InteractionCancelParams as InteractionCancelParams, type InteractionGetParams as InteractionGetParams, type InteractionGetParamsNonStreaming as InteractionGetParamsNonStreaming, type InteractionGetParamsStreaming as InteractionGetParamsStreaming, };
+}
+
+// @public (undocumented)
+type InteractionSSEEvent = InteractionEvent | InteractionStatusUpdate | ContentStart | ContentDelta | ContentStop | ErrorEvent_2;
+
+// @public (undocumented)
+interface InteractionStatusUpdate {
+ event_id?: string;
+ // (undocumented)
+ event_type?: 'interaction.status_update';
+ // (undocumented)
+ interaction_id?: string;
+ // (undocumented)
+ status?: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled';
+}
+
// @public
export interface Interval {
endTime?: string;
@@ -2451,6 +3108,35 @@ export enum MaskReferenceMode {
MASK_MODE_USER_PROVIDED = "MASK_MODE_USER_PROVIDED"
}
+// @public
+interface MCPServerToolCallContent {
+ arguments: {
+ [key: string]: unknown;
+ };
+ id: string;
+ name: string;
+ server_name: string;
+ type: 'mcp_server_tool_call';
+}
+
+// @public
+interface MCPServerToolResultContent {
+ call_id: string;
+ name?: string;
+ result: MCPServerToolResultContent.Items | unknown | string;
+ server_name?: string;
+ type: 'mcp_server_tool_result';
+}
+
+// @public (undocumented)
+namespace MCPServerToolResultContent {
+ // (undocumented)
+ interface Items {
+ // (undocumented)
+ items?: Array;
+ }
+}
+
// @public
export function mcpToTool(...args: [...Client[], CallableToolConfig | Client]): CallableTool;
@@ -2513,6 +3199,9 @@ export interface Model {
version?: string;
}
+// @public
+type Model_2 = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-preview-09-2025' | 'gemini-2.5-flash-lite' | 'gemini-2.5-flash-lite-preview-09-2025' | 'gemini-2.5-flash-preview-native-audio-dialog' | 'gemini-2.5-flash-image-preview' | 'gemini-2.5-pro-preview-tts' | 'gemini-3-pro-preview' | (string & {});
+
// @public (undocumented)
export class Models extends BaseModule {
constructor(apiClient: ApiClient);
@@ -3114,6 +3803,13 @@ export interface SpeechConfig {
voiceConfig?: VoiceConfig;
}
+// @public
+interface SpeechConfig_2 {
+ language?: string;
+ speaker?: string;
+ voice?: string;
+}
+
// @public (undocumented)
export type SpeechConfigUnion = SpeechConfig | string;
@@ -3249,6 +3945,13 @@ export interface TestTableItem {
skipInApiMode?: string;
}
+// @public
+interface TextContent {
+ annotations?: Array;
+ text?: string;
+ type: 'text';
+}
+
// @public
export interface ThinkingConfig {
includeThoughts?: boolean;
@@ -3263,6 +3966,16 @@ export enum ThinkingLevel {
THINKING_LEVEL_UNSPECIFIED = "THINKING_LEVEL_UNSPECIFIED"
}
+// @public (undocumented)
+type ThinkingLevel_2 = 'low' | 'high';
+
+// @public
+interface ThoughtContent {
+ signature?: string;
+ summary?: Array;
+ type: 'thought';
+}
+
// @public (undocumented)
export class Tokens extends BaseModule {
constructor(apiClient: ApiClient);
@@ -3290,6 +4003,59 @@ export interface Tool {
urlContext?: UrlContext;
}
+// @public
+type Tool_2 = Function_2 | Tool_2.GoogleSearch | Tool_2.CodeExecution | Tool_2.URLContext | Tool_2.ComputerUse | Tool_2.MCPServer | Tool_2.FileSearch;
+
+// @public (undocumented)
+namespace Tool_2 {
+ interface CodeExecution {
+ // (undocumented)
+ type: 'code_execution';
+ }
+ interface ComputerUse {
+ environment?: 'browser';
+ excludedPredefinedFunctions?: Array;
+ // (undocumented)
+ type: 'computer_use';
+ }
+ interface FileSearch {
+ file_search_store_names?: Array;
+ metadata_filter?: string;
+ top_k?: number;
+ // (undocumented)
+ type: 'file_search';
+ }
+ interface GoogleSearch {
+ // (undocumented)
+ type: 'google_search';
+ }
+ interface MCPServer {
+ allowed_tools?: Array;
+ headers?: {
+ [key: string]: string;
+ };
+ name?: string;
+ // (undocumented)
+ type: 'mcp_server';
+ url?: string;
+ }
+ interface URLContext {
+ // (undocumented)
+ type: 'url_context';
+ }
+}
+
+// @public
+type ToolChoice = ToolChoiceType | ToolChoiceConfig;
+
+// @public (undocumented)
+interface ToolChoiceConfig {
+ allowed_tools?: AllowedTools;
+}
+
+// @public (undocumented)
+type ToolChoiceType = 'auto' | 'any' | 'none' | 'validated';
+
// @public
export interface ToolCodeExecution {
}
@@ -3426,6 +4192,12 @@ export interface TuningValidationDataset {
vertexDatasetResource?: string;
}
+// @public (undocumented)
+interface Turn {
+ content?: string | Array;
+ role?: string;
+}
+
// @public
export enum TurnCompleteReason {
MALFORMED_FUNCTION_CALL = "MALFORMED_FUNCTION_CALL",
@@ -3582,11 +4354,38 @@ export class UpscaleImageResponse {
export interface UrlContext {
}
+// @public
+interface URLContextCallArguments {
+ urls?: Array;
+}
+
+// @public
+interface URLContextCallContent {
+ arguments?: URLContextCallArguments;
+ id?: string;
+ type: 'url_context_call';
+}
+
// @public
export interface UrlContextMetadata {
urlMetadata?: UrlMetadata[];
}
+// @public
+interface URLContextResult {
+ status?: 'success' | 'error' | 'paywall' | 'unsafe';
+ url?: string;
+}
+
+// @public
+interface URLContextResultContent {
+ call_id?: string;
+ is_error?: boolean;
+ result?: Array;
+ signature?: string;
+ type: 'url_context_result';
+}
+
// @public
export interface UrlMetadata {
retrievedUrl?: string;
@@ -3602,6 +4401,40 @@ export enum UrlRetrievalStatus {
URL_RETRIEVAL_STATUS_UNSPECIFIED = "URL_RETRIEVAL_STATUS_UNSPECIFIED"
}
+// @public
+interface Usage {
+ cached_tokens_by_modality?: Array;
+ input_tokens_by_modality?: Array;
+ output_tokens_by_modality?: Array;
+ tool_use_tokens_by_modality?: Array;
+ total_cached_tokens?: number;
+ total_input_tokens?: number;
+ total_output_tokens?: number;
+ total_reasoning_tokens?: number;
+ total_tokens?: number;
+ total_tool_use_tokens?: number;
+}
+
+// @public (undocumented)
+namespace Usage {
+ interface CachedTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface InputTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface OutputTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+ interface ToolUseTokensByModality {
+ modality?: 'text' | 'image' | 'audio';
+ tokens?: number;
+ }
+}
+
// @public
export interface UsageMetadata {
cachedContentTokenCount?: number;
@@ -3682,6 +4515,17 @@ export enum VideoCompressionQuality {
OPTIMIZED = "OPTIMIZED"
}
+// @public
+interface VideoContent {
+ // (undocumented)
+ data?: string;
+ mime_type?: VideoMimeType;
+ resolution?: 'low' | 'medium' | 'high';
+ type: 'video';
+ // (undocumented)
+ uri?: string;
+}
+
// @public
export interface VideoGenerationMask {
image?: Image_2;
@@ -3715,6 +4559,9 @@ export interface VideoMetadata {
startOffset?: string;
}
+// @public
+type VideoMimeType = 'video/mp4' | 'video/mpeg' | 'video/mov' | 'video/avi' | 'video/x-flv' | 'video/mpg' | 'video/webm' | 'video/wmv' | 'video/3gpp' | (string & {});
+
// @public (undocumented)
export interface VoiceActivityDetectionSignal {
vadSignalType?: VadSignalType;
diff --git a/package-lock.json b/package-lock.json
index d0688fbd6..e1505d064 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -90,7 +90,6 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -359,8 +358,7 @@
"resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz",
"integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==",
"dev": true,
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
@@ -1482,7 +1480,8 @@
"optional": true,
"os": [
"android"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.53.3",
@@ -1496,7 +1495,8 @@
"optional": true,
"os": [
"android"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.53.3",
@@ -1510,7 +1510,8 @@
"optional": true,
"os": [
"darwin"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.53.3",
@@ -1524,7 +1525,8 @@
"optional": true,
"os": [
"darwin"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.53.3",
@@ -1538,7 +1540,8 @@
"optional": true,
"os": [
"freebsd"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.53.3",
@@ -1552,7 +1555,8 @@
"optional": true,
"os": [
"freebsd"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.53.3",
@@ -1566,7 +1570,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.53.3",
@@ -1580,7 +1585,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.53.3",
@@ -1594,7 +1600,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.53.3",
@@ -1608,7 +1615,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.53.3",
@@ -1622,7 +1630,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.53.3",
@@ -1636,7 +1645,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.53.3",
@@ -1650,7 +1660,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.53.3",
@@ -1664,7 +1675,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.53.3",
@@ -1678,7 +1690,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.53.3",
@@ -1692,7 +1705,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.53.3",
@@ -1706,7 +1720,8 @@
"optional": true,
"os": [
"linux"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.53.3",
@@ -1720,7 +1735,8 @@
"optional": true,
"os": [
"openharmony"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.53.3",
@@ -1734,7 +1750,8 @@
"optional": true,
"os": [
"win32"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.53.3",
@@ -1748,7 +1765,8 @@
"optional": true,
"os": [
"win32"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.53.3",
@@ -1762,7 +1780,8 @@
"optional": true,
"os": [
"win32"
- ]
+ ],
+ "peer": true
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.53.3",
@@ -1776,7 +1795,8 @@
"optional": true,
"os": [
"win32"
- ]
+ ],
+ "peer": true
},
"node_modules/@rushstack/node-core-library": {
"version": "5.19.1",
@@ -1994,7 +2014,6 @@
"integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -2100,7 +2119,6 @@
"integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
"dev": true,
"license": "BSD-2-Clause",
- "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.62.0",
"@typescript-eslint/types": "5.62.0",
@@ -2324,7 +2342,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2736,7 +2753,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -3799,7 +3815,6 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -3856,7 +3871,6 @@
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -4241,7 +4255,6 @@
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.1",
@@ -8108,7 +8121,6 @@
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -10063,7 +10075,6 @@
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -10131,7 +10142,6 @@
"integrity": "sha512-Tqoa05bu+t5s8CTZFaGpCH2ub3QeT9YDkXbPd3uQ4SfsLoh1/vv2GEYAioPoxCWJJNsenXlC88tRjwoHNts1oQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.24.1",
"@typescript-eslint/types": "8.24.1",
@@ -10870,7 +10880,6 @@
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
diff --git a/sdk-samples/interactions_basic.ts b/sdk-samples/interactions_basic.ts
new file mode 100644
index 000000000..07f6e1e51
--- /dev/null
+++ b/sdk-samples/interactions_basic.ts
@@ -0,0 +1,32 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'why is the sky blue?',
+ });
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_function_calling_client_state.ts b/sdk-samples/interactions_function_calling_client_state.ts
new file mode 100644
index 000000000..74a394ab6
--- /dev/null
+++ b/sdk-samples/interactions_function_calling_client_state.ts
@@ -0,0 +1,104 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI, Interactions} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ const fcConversationHistory: Interactions.InteractionCreateParams['input'] = [
+ {
+ type: 'text',
+ text: 'Schedule a meeting for 2025-11-01 at 10 am with Peter and Amir about the Next Gen API.',
+ },
+ ];
+
+ // 1. Model decides to call the function
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: fcConversationHistory,
+ tools: [
+ {
+ name: 'schedule_meeting',
+ description:
+ 'Schedules a meeting with specified attendees at a given time and date.',
+ parameters: {
+ type: 'object',
+ properties: {
+ attendees: {
+ type: 'array',
+ items: {type: 'string'},
+ description: 'List of people attending the meeting.',
+ },
+ date: {
+ type: 'string',
+ description: 'Date of the meeting (e.g., 2024-07-29)',
+ },
+ time: {
+ type: 'string',
+ description: 'Time of the meeting (e.g., 15:00)',
+ },
+ topic: {
+ type: 'string',
+ description: 'The subject or topic of the meeting.',
+ },
+ },
+ required: ['attendees', 'date', 'time', 'topic'],
+ },
+ type: 'function',
+ },
+ ],
+ });
+
+ // add model response back to history
+ if (response.outputs) {
+ fcConversationHistory.push(...response.outputs);
+ }
+
+ for (const output of response.outputs ?? []) {
+ if (output.type == 'function_call') {
+ console.log(
+ `Function call: ${output.name} with arguments ${output.arguments}`,
+ );
+
+ // 2. Execute the function and get a result
+ // In a real app, you would call your function here.
+ // const call_result = schedule_meeting(output.arguments);
+
+ // 3. Send the result back to the model
+ fcConversationHistory.push({
+ type: 'function_result',
+ name: output.name!,
+ call_id: output.id!,
+ result: 'Meeting scheduled successfully.',
+ });
+
+ const response2 = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: fcConversationHistory,
+ });
+ console.log(`Final response: ${response2}`);
+ } else {
+ console.log(`Output: ${output}`);
+ }
+ }
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_function_calling_server_state.ts b/sdk-samples/interactions_function_calling_server_state.ts
new file mode 100644
index 000000000..9045f0e61
--- /dev/null
+++ b/sdk-samples/interactions_function_calling_server_state.ts
@@ -0,0 +1,93 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ // 1. Model decides to call the function
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input:
+ 'Schedule a meeting for 2025-11-01 at 10 am with Peter and Amir about the Next Gen API',
+ tools: [
+ {
+ name: 'schedule_meeting',
+ description:
+ 'Schedules a meeting with specified attendees at a given time and date.',
+ parameters: {
+ type: 'object',
+ properties: {
+ attendees: {
+ type: 'array',
+ items: {type: 'string'},
+ description: 'List of people attending the meeting.',
+ },
+ date: {
+ type: 'string',
+ description: 'Date of the meeting (e.g., 2024-07-29)',
+ },
+ time: {
+ type: 'string',
+ description: 'Time of the meeting (e.g., 15:00)',
+ },
+ topic: {
+ type: 'string',
+ description: 'The subject or topic of the meeting.',
+ },
+ },
+ required: ['attendees', 'date', 'time', 'topic'],
+ },
+ type: 'function',
+ },
+ ],
+ });
+
+ for (const output of response.outputs ?? []) {
+ if (output.type == 'function_call') {
+ console.log(
+ `Function call: ${output.name} with arguments ${output.arguments}`,
+ );
+
+ // 2. Execute the function and get a result
+ // In a real app, you would call your function here.
+ // const call_result = schedule_meeting(output.arguments);
+
+ // 3. Send the result back to the model
+ const response2 = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: [
+ {
+ type: 'function_result',
+ name: output.name,
+ call_id: output.id,
+ result: 'Meeting scheduled successfully.',
+ },
+ ],
+ });
+ console.log(`Final response: ${response2}`);
+ } else {
+ console.log(`Output: ${output}`);
+ }
+ }
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_get.ts b/sdk-samples/interactions_get.ts
new file mode 100644
index 000000000..401b78060
--- /dev/null
+++ b/sdk-samples/interactions_get.ts
@@ -0,0 +1,35 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'why is the sky blue?',
+ });
+ console.debug(response);
+
+ const getResponse = await ai.interactions.get(response.id);
+ console.debug(getResponse);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_multimodal_input_text_and_audio.ts b/sdk-samples/interactions_multimodal_input_text_and_audio.ts
new file mode 100644
index 000000000..69dfa386c
--- /dev/null
+++ b/sdk-samples/interactions_multimodal_input_text_and_audio.ts
@@ -0,0 +1,54 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+import fs from 'fs';
+import path from 'path';
+import {fileURLToPath} from 'url';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ // Load and encode the audio
+ const __filename = fileURLToPath(import.meta.url);
+ const __dirname = path.dirname(__filename);
+ const audioPath = path.join(__dirname, '../sample_audio.mp3');
+ const audioBuffer = fs.readFileSync(audioPath);
+ const base64Audio = audioBuffer.toString('base64');
+
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: [
+ {
+ type: 'text',
+ text: 'What does this audio say?',
+ },
+ {
+ type: 'audio',
+ data: base64Audio,
+ mime_type: 'audio/mpeg',
+ },
+ ],
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_multimodal_input_text_and_audio_with_generate_content.ts b/sdk-samples/interactions_multimodal_input_text_and_audio_with_generate_content.ts
new file mode 100644
index 000000000..97eee4a6e
--- /dev/null
+++ b/sdk-samples/interactions_multimodal_input_text_and_audio_with_generate_content.ts
@@ -0,0 +1,82 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+import fs from 'fs';
+import path from 'path';
+import {fileURLToPath} from 'url';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ // Load and encode the audio
+ const __filename = fileURLToPath(import.meta.url);
+ const __dirname = path.dirname(__filename);
+ const audioPath = path.join(__dirname, '../sample_audio.mp3');
+ const audioBuffer = fs.readFileSync(audioPath);
+ const base64Audio = audioBuffer.toString('base64');
+
+ console.log(
+ '[Interactions] Start interactions multimodal input text and audio',
+ );
+
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: [
+ {
+ type: 'text',
+ text: 'What does this audio say?',
+ },
+ {
+ type: 'audio',
+ data: base64Audio,
+ mime_type: 'audio/mpeg',
+ },
+ ],
+ });
+
+ console.debug(response);
+
+ console.log('[Generate Content] Start generate content');
+
+ const generateContentResponse = await ai.models.generateContent({
+ model: 'gemini-2.5-flash',
+ contents: [
+ {
+ role: 'user',
+ parts: [
+ {
+ text: 'What does this audio say?',
+ },
+ {
+ inlineData: {
+ mimeType: 'audio/mpeg',
+ data: base64Audio,
+ },
+ },
+ ],
+ },
+ ],
+ });
+
+ console.debug(generateContentResponse.text);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_multimodal_input_text_and_image.ts b/sdk-samples/interactions_multimodal_input_text_and_image.ts
new file mode 100644
index 000000000..d48edd9f0
--- /dev/null
+++ b/sdk-samples/interactions_multimodal_input_text_and_image.ts
@@ -0,0 +1,55 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+import fs from 'fs';
+import path from 'path';
+import {fileURLToPath} from 'url';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ // Load and encode the image
+ const imagePath = path.join(__dirname, '../car.png');
+ const imageBuffer = fs.readFileSync(imagePath);
+ const base64Image = imageBuffer.toString('base64');
+
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: [
+ {
+ type: 'text',
+ text: 'What is this landmark?',
+ },
+ {
+ type: 'image',
+ data: base64Image,
+ mime_type: 'image/png',
+ },
+ ],
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_multimodal_input_text_and_image_with_generate_content.ts b/sdk-samples/interactions_multimodal_input_text_and_image_with_generate_content.ts
new file mode 100644
index 000000000..6f0eb88a2
--- /dev/null
+++ b/sdk-samples/interactions_multimodal_input_text_and_image_with_generate_content.ts
@@ -0,0 +1,81 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+import fs from 'fs';
+import path from 'path';
+import {fileURLToPath} from 'url';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ console.log(
+ '[Interactions] Start interactions multimodal input text and image',
+ );
+
+ // Load and encode the image
+ const imagePath = path.join(__dirname, '../car.png');
+ const imageBuffer = fs.readFileSync(imagePath);
+ const base64Image = imageBuffer.toString('base64');
+
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: [
+ {
+ type: 'text',
+ text: 'What is this landmark?',
+ },
+ {
+ type: 'image',
+ data: base64Image,
+ mime_type: 'image/png',
+ },
+ ],
+ });
+ console.debug(response);
+
+ console.log('[Generate Content] Start generate content');
+ const generateContentResponse = await ai.models.generateContent({
+ model: 'gemini-2.5-flash',
+ contents: [
+ {
+ role: 'user',
+ parts: [
+ {
+ text: 'What is this landmark?',
+ },
+ {
+ inlineData: {
+ mimeType: 'image/png',
+ data: base64Image,
+ },
+ },
+ ],
+ },
+ ],
+ });
+
+ console.debug(generateContentResponse.text);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_multimodal_response_audio.ts b/sdk-samples/interactions_multimodal_response_audio.ts
new file mode 100644
index 000000000..c3b252391
--- /dev/null
+++ b/sdk-samples/interactions_multimodal_response_audio.ts
@@ -0,0 +1,43 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const interaction = await ai.interactions.create({
+ model: 'gemini-2.5-flash-preview-tts',
+ input: 'Say cheerfully: Have a wonderful day!',
+ response_modalities: ['audio'],
+ generation_config: {
+ speech_config: [{voice: 'achernar', language: 'en'}],
+ },
+ });
+
+ interaction.outputs?.forEach((output, index) => {
+ if (output.type === 'audio') {
+ console.log(`Audio output ${index + 1}:`, output);
+ } else {
+ console.log(`Output ${index + 1}: ${output}`);
+ }
+ });
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_multimodal_response_audio_with_generate_content.ts b/sdk-samples/interactions_multimodal_response_audio_with_generate_content.ts
new file mode 100644
index 000000000..d61682844
--- /dev/null
+++ b/sdk-samples/interactions_multimodal_response_audio_with_generate_content.ts
@@ -0,0 +1,71 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ console.log('[Interactions] Start interactions multimodal response audio');
+
+ const interaction = await ai.interactions.create({
+ model: 'gemini-2.5-flash-preview-tts',
+ input: 'Say cheerfully: Have a wonderful day!',
+ response_modalities: ['audio'],
+ generation_config: {
+ speech_config: [{voice: 'achernar', language: 'en'}],
+ },
+ });
+
+ interaction.outputs?.forEach((output, index) => {
+ if (output.type === 'audio') {
+ console.log(`Audio output ${index + 1}:`, output);
+ } else {
+ console.log(`Output ${index + 1}: ${output}`);
+ }
+ });
+
+ console.log('[Generate Content] Start generate content');
+ const generateContentResponse = await ai.models.generateContent({
+ model: 'gemini-2.5-flash-preview-tts',
+ config: {
+ responseModalities: ['AUDIO'],
+ },
+ contents: [
+ {
+ role: 'user',
+ parts: [
+ {
+ text: 'Say cheerfully: Have a wonderful day!',
+ },
+ ],
+ },
+ ],
+ });
+ console.debug(
+ 'Generate Content response text: ',
+ generateContentResponse.text,
+ );
+ console.debug(
+ 'Generate Content response data: ',
+ generateContentResponse.data,
+ );
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_multimodal_response_image.ts b/sdk-samples/interactions_multimodal_response_image.ts
new file mode 100644
index 000000000..a0a14b996
--- /dev/null
+++ b/sdk-samples/interactions_multimodal_response_image.ts
@@ -0,0 +1,40 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const interaction = await ai.interactions.create({
+ model: 'gemini-2.5-flash-image-preview',
+ response_modalities: ['image'],
+ input: 'Generate an image of a futuristic cityscape at sunset.',
+ });
+
+ interaction.outputs?.forEach((output, index) => {
+ if (output.type === 'image') {
+ console.log(`Image output ${index + 1}:`, output);
+ } else {
+ console.log(`Output ${index + 1}: ${output}`);
+ }
+ });
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_multimodal_response_image_with_generate_content.ts b/sdk-samples/interactions_multimodal_response_image_with_generate_content.ts
new file mode 100644
index 000000000..34f46848d
--- /dev/null
+++ b/sdk-samples/interactions_multimodal_response_image_with_generate_content.ts
@@ -0,0 +1,68 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ console.log('[Interactions] Start interactions multimodal response image');
+
+ const interaction = await ai.interactions.create({
+ model: 'gemini-2.5-flash-image-preview',
+ response_modalities: ['image'],
+ input: 'Generate an image of a futuristic cityscape at sunset.',
+ });
+
+ interaction.outputs?.forEach((output, index) => {
+ if (output.type === 'image') {
+ console.log(`Image output ${index + 1}:`, output);
+ } else {
+ console.log(`Output ${index + 1}: ${output}`);
+ }
+ });
+
+ console.log('[Generate Content] Start generate content');
+ const generateContentResponse = await ai.models.generateContent({
+ model: 'gemini-2.5-flash-image',
+ config: {
+ responseModalities: ['TEXT', 'IMAGE'],
+ },
+ contents: [
+ {
+ role: 'user',
+ parts: [
+ {
+ text: 'Generate an image of a futuristic cityscape at sunset.',
+ },
+ ],
+ },
+ ],
+ });
+ console.debug(
+ 'Generate Content response text: ',
+ generateContentResponse.text,
+ );
+ console.debug(
+ 'Generate Content response data: ',
+ generateContentResponse.data,
+ );
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_stateful.ts b/sdk-samples/interactions_stateful.ts
new file mode 100644
index 000000000..0da7a12a7
--- /dev/null
+++ b/sdk-samples/interactions_stateful.ts
@@ -0,0 +1,43 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ // Start the conversation
+ console.log('User: What are the three largest cities in Spain?');
+ const response1 = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'What are the three largest cities in Spain?',
+ });
+ console.log('Model: ', response1);
+
+ // Continue the conversation using the previous interaction ID
+ console.log('\nUser: What is the most famous landmark in the second one?');
+ const response2 = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'What is the most famous landmark in the second one?',
+ });
+ console.log('Model: ', response2);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_stateless.ts b/sdk-samples/interactions_stateless.ts
new file mode 100644
index 000000000..f02337732
--- /dev/null
+++ b/sdk-samples/interactions_stateless.ts
@@ -0,0 +1,58 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI, Interactions} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ const conversationHistory: Interactions.InteractionCreateParams['input'] = [
+ {
+ type: 'text',
+ text: 'What are the three largest cities in Spain?',
+ },
+ ];
+
+ console.log('User: What are the three largest cities in Spain?');
+ const response1 = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ store: false,
+ input: conversationHistory,
+ });
+ console.log('Model: ', response1);
+
+ if (response1.outputs) {
+ conversationHistory.push(...response1.outputs);
+ }
+ conversationHistory.push({
+ type: 'text',
+ text: 'What is the most famous landmark in the second one?',
+ });
+
+ console.log('\nUser: What is the most famous landmark in the second one?');
+ const response2 = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ store: false,
+ input: conversationHistory,
+ });
+ console.log('Model: ', response2);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_streaming.ts b/sdk-samples/interactions_streaming.ts
new file mode 100644
index 000000000..20e4daf26
--- /dev/null
+++ b/sdk-samples/interactions_streaming.ts
@@ -0,0 +1,45 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const stream = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'Tell me a story',
+ stream: true,
+ });
+
+ for await (const event of stream) {
+ switch (event.event_type) {
+ case 'content.delta':
+ switch (event.delta?.type) {
+ case 'text':
+ process.stdout.write(event.delta.text ?? '');
+ break;
+ }
+ }
+ }
+
+ process.stdout.write('\n');
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_structured_output_json.ts b/sdk-samples/interactions_structured_output_json.ts
new file mode 100644
index 000000000..14ad2fd5a
--- /dev/null
+++ b/sdk-samples/interactions_structured_output_json.ts
@@ -0,0 +1,35 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'Which are the colors of a rainbow',
+ response_mime_type: 'application/json',
+ response_format: {type: 'array', description: 'A list of colors'},
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_tool_call_with_code_execution.ts b/sdk-samples/interactions_tool_call_with_code_execution.ts
new file mode 100644
index 000000000..c9aaa9915
--- /dev/null
+++ b/sdk-samples/interactions_tool_call_with_code_execution.ts
@@ -0,0 +1,34 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'What is the sum of the first 100 integers?',
+ tools: [{type: 'code_execution'}],
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_tool_call_with_computer_use.ts b/sdk-samples/interactions_tool_call_with_computer_use.ts
new file mode 100644
index 000000000..7d72343b6
--- /dev/null
+++ b/sdk-samples/interactions_tool_call_with_computer_use.ts
@@ -0,0 +1,35 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input:
+ 'Search for highly rated smart fridges with touchscreen, 2 doors, around 25 cu ft, priced below 4000 dollars on Google Shopping. Create a bulleted list of the 3 cheapest options in the format of name, description, price in an easy-to-read layout.',
+ tools: [{type: 'computer_use', environment: 'browser'}],
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_tool_call_with_functions.ts b/sdk-samples/interactions_tool_call_with_functions.ts
new file mode 100644
index 000000000..7e092e55b
--- /dev/null
+++ b/sdk-samples/interactions_tool_call_with_functions.ts
@@ -0,0 +1,65 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input:
+ 'Schedule a meeting for 10/06/2028 at 10 am with Peter and Amir about the Next Gen API',
+ tools: [
+ {
+ name: 'schedule_meeting',
+ description:
+ 'Schedules a meeting with specified attendees at a given time and date.',
+ parameters: {
+ type: 'object',
+ properties: {
+ attendees: {
+ type: 'array',
+ items: {type: 'string'},
+ description: 'List of people attending the meeting.',
+ },
+ date: {
+ type: 'string',
+ description: 'Date of the meeting (e.g., 2024-07-29)',
+ },
+ time: {
+ type: 'string',
+ description: 'Time of the meeting (e.g., 15:00)',
+ },
+ topic: {
+ type: 'string',
+ description: 'The subject or topic of the meeting.',
+ },
+ },
+ required: ['attendees', 'date', 'time', 'topic'],
+ },
+ type: 'function',
+ },
+ ],
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_tool_call_with_google_search.ts b/sdk-samples/interactions_tool_call_with_google_search.ts
new file mode 100644
index 000000000..dac412118
--- /dev/null
+++ b/sdk-samples/interactions_tool_call_with_google_search.ts
@@ -0,0 +1,34 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'Why is the sky blue',
+ tools: [{type: 'google_search'}],
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_tool_call_with_mcp_server.ts b/sdk-samples/interactions_tool_call_with_mcp_server.ts
new file mode 100644
index 000000000..661175a09
--- /dev/null
+++ b/sdk-samples/interactions_tool_call_with_mcp_server.ts
@@ -0,0 +1,42 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'What is the temperature today in London?',
+ system_instruction:
+ 'Today is 9-23-2025. Any dates before this are in the past, and any dates after this are in the future.',
+ tools: [
+ {
+ type: 'mcp_server',
+ name: 'weather_service',
+ url: 'https://gemini-api-demos.uc.r.appspot.com/mcp',
+ },
+ ],
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_tool_call_with_mime_type.ts b/sdk-samples/interactions_tool_call_with_mime_type.ts
new file mode 100644
index 000000000..0327bd24c
--- /dev/null
+++ b/sdk-samples/interactions_tool_call_with_mime_type.ts
@@ -0,0 +1,64 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ apiVersion: 'v1alpha',
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-3-pro-preview',
+ input: 'What is the weather in New York?',
+ tools: [
+ {
+ type: 'function',
+ name: 'get_weather',
+ description: 'Get the current weather in a given location',
+ parameters: {
+ type: 'object',
+ properties: {
+ location: {
+ type: 'string',
+ description: 'The city and state, e.g. San Francisco, CA',
+ },
+ },
+ required: ['location'],
+ },
+ },
+ ],
+ response_format: {
+ type: 'object',
+ properties: {
+ location: {type: 'string'},
+ temperature: {type: 'number'},
+ condition: {type: 'string'},
+ recommendation: {type: 'string'},
+ },
+ required: ['location', 'temperature', 'condition', 'recommendation'],
+ },
+ response_mime_type: 'application/json',
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error(
+ 'This version of the GenAI SDK does not support Vertex AI API for interactions.',
+ );
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_tool_call_with_url_context.ts b/sdk-samples/interactions_tool_call_with_url_context.ts
new file mode 100644
index 000000000..64e819e81
--- /dev/null
+++ b/sdk-samples/interactions_tool_call_with_url_context.ts
@@ -0,0 +1,35 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input:
+ 'Compare the ingredients and cooking times from the recipes at https://www.foodnetwork.com/recipes/ina-garten/perfect-roast-chicken-recipe-1940592 and https://www.allrecipes.com/recipe/21151/simple-whole-roast-chicken/',
+ tools: [{type: 'url_context'}],
+ });
+
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/interactions_with_config.ts b/sdk-samples/interactions_with_config.ts
new file mode 100644
index 000000000..951130a04
--- /dev/null
+++ b/sdk-samples/interactions_with_config.ts
@@ -0,0 +1,34 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {GoogleGenAI} from '@google/genai';
+
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GOOGLE_GENAI_USE_VERTEXAI = process.env.GOOGLE_GENAI_USE_VERTEXAI;
+
+async function createInteractionsFromMLDev() {
+ const ai = new GoogleGenAI({
+ apiKey: GEMINI_API_KEY,
+ });
+
+ const response = await ai.interactions.create({
+ model: 'gemini-2.5-flash',
+ input: 'Tell me a story',
+ system_instruction: 'You are a helpful assistant',
+ });
+ console.debug(response);
+}
+
+async function main() {
+ if (GOOGLE_GENAI_USE_VERTEXAI) {
+ throw new Error('Interactions API is not yet supported on Vertex');
+ } else {
+ await createInteractionsFromMLDev().catch((e) =>
+ console.error('got error', e),
+ );
+ }
+}
+
+main();
diff --git a/sdk-samples/package-lock.json b/sdk-samples/package-lock.json
index 99b833e33..c2113cc12 100644
--- a/sdk-samples/package-lock.json
+++ b/sdk-samples/package-lock.json
@@ -22,7 +22,7 @@
},
"..": {
"name": "@google/genai",
- "version": "1.30.0",
+ "version": "1.32.0",
"license": "Apache-2.0",
"dependencies": {
"google-auth-library": "^10.3.0",
@@ -60,8 +60,8 @@
"typescript-eslint": "8.24.1",
"undici": "^7.16.0",
"undici-types": "^7.16.0",
- "zod": "^3.22.4",
- "zod-to-json-schema": "^3.22.4"
+ "zod": "^3.25.0",
+ "zod-to-json-schema": "^3.25.0"
},
"engines": {
"node": ">=20.0.0"
diff --git a/src/client.ts b/src/client.ts
index 7d33252eb..acb5cb6fa 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -16,6 +16,8 @@ import {CrossUploader} from './cross/_cross_uploader.js';
import {CrossWebSocketFactory} from './cross/_cross_websocket.js';
import {Files} from './files.js';
import {FileSearchStores} from './filesearchstores.js';
+import GeminiNextGenAPI from './interactions/index.js';
+import {Interactions as GeminiNextGenInteractions} from './interactions/resources/interactions.js';
import {Live} from './live.js';
import {Models} from './models.js';
import {Operations} from './operations.js';
@@ -136,6 +138,42 @@ export class GoogleGenAI {
readonly authTokens: Tokens;
readonly tunings: Tunings;
readonly fileSearchStores: FileSearchStores;
+ private _interactions: GeminiNextGenInteractions | undefined;
+
+ get interactions(): GeminiNextGenInteractions {
+ if (this._interactions !== undefined) {
+ return this._interactions;
+ }
+
+ console.warn(
+ 'GoogleGenAI.interactions: Interactions usage is experimental and may change in future versions.',
+ );
+
+ if (this.vertexai) {
+ throw new Error(
+ 'This version of the GenAI SDK does not support Vertex AI API for interactions.',
+ );
+ }
+
+ const httpOpts = this.httpOptions;
+
+ // Unsupported Options Warnings
+ if (httpOpts?.extraBody) {
+ console.warn(
+ 'GoogleGenAI.interactions: Client level httpOptions.extraBody is not supported by the interactions client and will be ignored.',
+ );
+ }
+
+ const nextGenClient = new GeminiNextGenAPI({
+ baseURL: this.apiClient.getBaseUrl(),
+ apiKey: this.apiKey,
+ defaultHeaders: this.apiClient.getDefaultHeaders(),
+ timeout: httpOpts?.timeout,
+ });
+ this._interactions = nextGenClient.interactions;
+
+ return this._interactions;
+ }
constructor(options: GoogleGenAIOptions) {
if (options.apiKey == null) {
diff --git a/src/index.ts b/src/index.ts
index 6853db510..a82ac4b23 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -11,6 +11,7 @@ export * from './chats';
export {GoogleGenAI, GoogleGenAIOptions} from './client';
export * from './errors';
export {Files} from './files';
+export type * as Interactions from './interactions/resources/interactions.js';
export * from './live';
export {mcpToTool} from './mcp/_mcp';
export {Models} from './models';
diff --git a/src/interactions/OWNERS b/src/interactions/OWNERS
new file mode 100644
index 000000000..da35fbc61
--- /dev/null
+++ b/src/interactions/OWNERS
@@ -0,0 +1,4 @@
+file://depot/google3/third_party/javascript/google_genai/OWNERS
+
+# Interactions API developers
+file://depot/google3/labs/language/genai/interactions/OWNERS
\ No newline at end of file
diff --git a/src/interactions/api-promise.ts b/src/interactions/api-promise.ts
new file mode 100644
index 000000000..68ee3bf7e
--- /dev/null
+++ b/src/interactions/api-promise.ts
@@ -0,0 +1,8 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/** @deprecated Import from ./core/api-promise instead */
+export * from './core/api-promise.js';
diff --git a/src/interactions/client.ts b/src/interactions/client.ts
new file mode 100644
index 000000000..dd5f58900
--- /dev/null
+++ b/src/interactions/client.ts
@@ -0,0 +1,874 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types.js';
+import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestInit } from './internal/types.js';
+import { uuid4 } from './internal/utils/uuid.js';
+import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values.js';
+import { sleep } from './internal/utils/sleep.js';
+export type { Logger, LogLevel } from './internal/utils/log.js';
+import { castToError, isAbortError } from './internal/errors.js';
+import type { APIResponseProps } from './internal/parse.js';
+import { getPlatformHeaders } from './internal/detect-platform.js';
+import * as Shims from './internal/shims.js';
+import * as Opts from './internal/request-options.js';
+import { VERSION } from './version.js';
+import * as Errors from './core/error.js';
+import * as Uploads from './core/uploads.js';
+import * as API from './resources/index.js';
+import { APIPromise } from './core/api-promise.js';
+import {
+ AllowedTools,
+ Annotation,
+ AudioContent,
+ AudioMimeType,
+ CodeExecutionCallArguments,
+ CodeExecutionCallContent,
+ CodeExecutionResultContent,
+ ContentDelta,
+ ContentStart,
+ ContentStop,
+ CreateAgentInteractionParamsNonStreaming,
+ CreateAgentInteractionParamsStreaming,
+ CreateModelInteractionParamsNonStreaming,
+ CreateModelInteractionParamsStreaming,
+ DeepResearchAgentConfig,
+ DocumentContent,
+ DynamicAgentConfig,
+ ErrorEvent,
+ FileSearchResultContent,
+ Function,
+ FunctionCallContent,
+ FunctionResultContent,
+ GenerationConfig,
+ GoogleSearchCallArguments,
+ GoogleSearchCallContent,
+ GoogleSearchResult,
+ GoogleSearchResultContent,
+ ImageContent,
+ ImageMimeType,
+ Interaction,
+ InteractionCancelParams,
+ InteractionCreateParams,
+ InteractionDeleteParams,
+ InteractionDeleteResponse,
+ InteractionEvent,
+ InteractionGetParams,
+ InteractionGetParamsNonStreaming,
+ InteractionGetParamsStreaming,
+ InteractionSSEEvent,
+ InteractionStatusUpdate,
+ Interactions,
+ MCPServerToolCallContent,
+ MCPServerToolResultContent,
+ Model,
+ SpeechConfig,
+ TextContent,
+ ThinkingLevel,
+ ThoughtContent,
+ Tool,
+ ToolChoice,
+ ToolChoiceConfig,
+ ToolChoiceType,
+ Turn,
+ URLContextCallArguments,
+ URLContextCallContent,
+ URLContextResult,
+ URLContextResultContent,
+ Usage,
+ VideoContent,
+ VideoMimeType,
+} from './resources/interactions.js';
+import { type Fetch } from './internal/builtin-types.js';
+import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers.js';
+import { FinalRequestOptions, RequestOptions } from './internal/request-options.js';
+import { readEnv } from './internal/utils/env.js';
+import {
+ type LogLevel,
+ type Logger,
+ formatRequestDetails,
+ loggerFor,
+ parseLogLevel,
+} from './internal/utils/log.js';
+import { isEmptyObj } from './internal/utils/values.js';
+
+export interface ClientOptions {
+ /**
+ * Defaults to process.env['GEMINI_API_KEY'].
+ */
+ apiKey?: string | null | undefined;
+
+ apiVersion?: string | undefined;
+
+ /**
+ * Override the default base URL for the API, e.g., "https://api.example.com/v2/"
+ *
+ * Defaults to process.env['GEMINI_NEXT_GEN_API_BASE_URL'].
+ */
+ baseURL?: string | null | undefined;
+
+ /**
+ * The maximum amount of time (in milliseconds) that the client should wait for a response
+ * from the server before timing out a single request.
+ *
+ * Note that request timeouts are retried by default, so in a worst-case scenario you may wait
+ * much longer than this timeout before the promise succeeds or fails.
+ *
+ * @unit milliseconds
+ */
+ timeout?: number | undefined;
+ /**
+ * Additional `RequestInit` options to be passed to `fetch` calls.
+ * Properties will be overridden by per-request `fetchOptions`.
+ */
+ fetchOptions?: MergedRequestInit | undefined;
+
+ /**
+ * Specify a custom `fetch` function implementation.
+ *
+ * If not provided, we expect that `fetch` is defined globally.
+ */
+ fetch?: Fetch | undefined;
+
+ /**
+ * The maximum number of times that the client will retry a request in case of a
+ * temporary failure, like a network error or a 5XX error from the server.
+ *
+ * @default 2
+ */
+ maxRetries?: number | undefined;
+
+ /**
+ * Default headers to include with every request to the API.
+ *
+ * These can be removed in individual requests by explicitly setting the
+ * header to `null` in request options.
+ */
+ defaultHeaders?: HeadersLike | undefined;
+
+ /**
+ * Default query parameters to include with every request to the API.
+ *
+ * These can be removed in individual requests by explicitly setting the
+ * param to `undefined` in request options.
+ */
+ defaultQuery?: Record | undefined;
+
+ /**
+ * Set the log level.
+ *
+ * Defaults to process.env['GEMINI_NEXT_GEN_API_LOG'] or 'warn' if it isn't set.
+ */
+ logLevel?: LogLevel | undefined;
+
+ /**
+ * Set the logger.
+ *
+ * Defaults to globalThis.console.
+ */
+ logger?: Logger | undefined;
+}
+
+/**
+ * Base class for Gemini Next Gen API API clients.
+ */
+export class BaseGeminiNextGenAPIClient {
+ apiKey: string | null;
+ apiVersion: string;
+
+ baseURL: string;
+ maxRetries: number;
+ timeout: number;
+ logger: Logger;
+ logLevel: LogLevel | undefined;
+ fetchOptions: MergedRequestInit | undefined;
+
+ private fetch: Fetch;
+ private encoder: Opts.RequestEncoder;
+ protected idempotencyHeader?: string;
+ private _options: ClientOptions;
+
+ /**
+ * API Client for interfacing with the Gemini Next Gen API API.
+ *
+ * @param {string | null | undefined} [opts.apiKey=process.env['GEMINI_API_KEY'] ?? null]
+ * @param {string | undefined} [opts.apiVersion=v1beta]
+ * @param {string} [opts.baseURL=process.env['GEMINI_NEXT_GEN_API_BASE_URL'] ?? https://generativelanguage.googleapis.com] - Override the default base URL for the API.
+ * @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
+ * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
+ * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
+ * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
+ * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
+ * @param {Record} opts.defaultQuery - Default query parameters to include with every request to the API.
+ */
+ constructor({
+ baseURL = readEnv('GEMINI_NEXT_GEN_API_BASE_URL'),
+ apiKey = readEnv('GEMINI_API_KEY') ?? null,
+ apiVersion = 'v1beta',
+ ...opts
+ }: ClientOptions = {}) {
+ const options: ClientOptions = {
+ apiKey,
+ apiVersion,
+ ...opts,
+ baseURL: baseURL || `https://generativelanguage.googleapis.com`,
+ };
+
+ this.baseURL = options.baseURL!;
+ this.timeout = options.timeout ?? BaseGeminiNextGenAPIClient.DEFAULT_TIMEOUT /* 1 minute */;
+ this.logger = options.logger ?? console;
+ const defaultLogLevel = 'warn';
+ // Set default logLevel early so that we can log a warning in parseLogLevel.
+ this.logLevel = defaultLogLevel;
+ this.logLevel =
+ parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ??
+ parseLogLevel(readEnv('GEMINI_NEXT_GEN_API_LOG'), "process.env['GEMINI_NEXT_GEN_API_LOG']", this) ??
+ defaultLogLevel;
+ this.fetchOptions = options.fetchOptions;
+ this.maxRetries = options.maxRetries ?? 2;
+ this.fetch = options.fetch ?? Shims.getDefaultFetch();
+ this.encoder = Opts.FallbackEncoder;
+
+ this._options = options;
+
+ this.apiKey = apiKey;
+ this.apiVersion = apiVersion;
+ }
+
+ /**
+ * Create a new client instance re-using the same options given to the current client with optional overriding.
+ */
+ withOptions(options: Partial): this {
+ const client = new (this.constructor as any as new (props: ClientOptions) => typeof this)({
+ ...this._options,
+ baseURL: this.baseURL,
+ maxRetries: this.maxRetries,
+ timeout: this.timeout,
+ logger: this.logger,
+ logLevel: this.logLevel,
+ fetch: this.fetch,
+ fetchOptions: this.fetchOptions,
+ apiKey: this.apiKey,
+ apiVersion: this.apiVersion,
+ ...options,
+ });
+ return client;
+ }
+
+ /**
+ * Check whether the base URL is set to its default.
+ */
+ private baseURLOverridden() {
+ return this.baseURL !== 'https://generativelanguage.googleapis.com';
+ }
+
+ protected defaultQuery(): Record | undefined {
+ return this._options.defaultQuery;
+ }
+
+ protected validateHeaders({ values, nulls }: NullableHeaders) {
+ if (this.apiKey && values.get('x-goog-api-key')) {
+ return;
+ }
+ if (nulls.has('x-goog-api-key')) {
+ return;
+ }
+
+ throw new Error(
+ 'Could not resolve authentication method. Expected the apiKey to be set. Or for the "x-goog-api-key" headers to be explicitly omitted',
+ );
+ }
+
+ protected async authHeaders(opts: FinalRequestOptions): Promise {
+ if (this.apiKey == null) {
+ return undefined;
+ }
+ return buildHeaders([{ 'x-goog-api-key': this.apiKey }]);
+ }
+
+ /**
+ * Basic re-implementation of `qs.stringify` for primitive types.
+ */
+ protected stringifyQuery(query: Record): string {
+ return Object.entries(query)
+ .filter(([_, value]) => typeof value !== 'undefined')
+ .map(([key, value]) => {
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
+ }
+ if (value === null) {
+ return `${encodeURIComponent(key)}=`;
+ }
+ throw new Errors.GeminiNextGenAPIClientError(
+ `Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`,
+ );
+ })
+ .join('&');
+ }
+
+ private getUserAgent(): string {
+ return `${this.constructor.name}/JS ${VERSION}`;
+ }
+
+ protected defaultIdempotencyKey(): string {
+ return `stainless-node-retry-${uuid4()}`;
+ }
+
+ protected makeStatusError(
+ status: number,
+ error: Object,
+ message: string | undefined,
+ headers: Headers,
+ ): Errors.APIError {
+ return Errors.APIError.generate(status, error, message, headers);
+ }
+
+ buildURL(
+ path: string,
+ query: Record | null | undefined,
+ defaultBaseURL?: string | undefined,
+ ): string {
+ const baseURL = (!this.baseURLOverridden() && defaultBaseURL) || this.baseURL;
+ const url =
+ isAbsoluteURL(path) ?
+ new URL(path)
+ : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
+
+ const defaultQuery = this.defaultQuery();
+ if (!isEmptyObj(defaultQuery)) {
+ query = { ...defaultQuery, ...query };
+ }
+
+ if (typeof query === 'object' && query && !Array.isArray(query)) {
+ url.search = this.stringifyQuery(query as Record);
+ }
+
+ return url.toString();
+ }
+
+ /**
+ * Used as a callback for mutating the given `FinalRequestOptions` object.
+ */
+ protected async prepareOptions(options: FinalRequestOptions): Promise {}
+
+ /**
+ * Used as a callback for mutating the given `RequestInit` object.
+ *
+ * This is useful for cases where you want to add certain headers based off of
+ * the request properties, e.g. `method` or `url`.
+ */
+ protected async prepareRequest(
+ request: RequestInit,
+ { url, options }: { url: string; options: FinalRequestOptions },
+ ): Promise {}
+
+ get(path: string, opts?: PromiseOrValue): APIPromise {
+ return this.methodRequest('get', path, opts);
+ }
+
+ post(path: string, opts?: PromiseOrValue): APIPromise {
+ return this.methodRequest('post', path, opts);
+ }
+
+ patch(path: string, opts?: PromiseOrValue): APIPromise {
+ return this.methodRequest('patch', path, opts);
+ }
+
+ put(path: string, opts?: PromiseOrValue): APIPromise {
+ return this.methodRequest('put', path, opts);
+ }
+
+ delete(path: string, opts?: PromiseOrValue): APIPromise {
+ return this.methodRequest('delete', path, opts);
+ }
+
+ private methodRequest(
+ method: HTTPMethod,
+ path: string,
+ opts?: PromiseOrValue,
+ ): APIPromise {
+ return this.request(
+ Promise.resolve(opts).then((opts) => {
+ return { method, path, ...opts };
+ }),
+ );
+ }
+
+ request(
+ options: PromiseOrValue,
+ remainingRetries: number | null = null,
+ ): APIPromise {
+ return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
+ }
+
+ private async makeRequest(
+ optionsInput: PromiseOrValue,
+ retriesRemaining: number | null,
+ retryOfRequestLogID: string | undefined,
+ ): Promise {
+ const options = await optionsInput;
+ const maxRetries = options.maxRetries ?? this.maxRetries;
+ if (retriesRemaining == null) {
+ retriesRemaining = maxRetries;
+ }
+
+ await this.prepareOptions(options);
+
+ const { req, url, timeout } = await this.buildRequest(options, {
+ retryCount: maxRetries - retriesRemaining,
+ });
+
+ await this.prepareRequest(req, { url, options });
+
+ /** Not an API request ID, just for correlating local log entries. */
+ const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
+ const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
+ const startTime = Date.now();
+
+ loggerFor(this).debug(
+ `[${requestLogID}] sending request`,
+ formatRequestDetails({
+ retryOfRequestLogID,
+ method: options.method,
+ url,
+ options,
+ headers: req.headers,
+ }),
+ );
+
+ if (options.signal?.aborted) {
+ throw new Errors.APIUserAbortError();
+ }
+
+ const controller = new AbortController();
+ const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
+ const headersTime = Date.now();
+
+ if (response instanceof globalThis.Error) {
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
+ if (options.signal?.aborted) {
+ throw new Errors.APIUserAbortError();
+ }
+ // detect native connection timeout errors
+ // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
+ // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
+ // others do not provide enough information to distinguish timeouts from other connection errors
+ const isTimeout =
+ isAbortError(response) ||
+ /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
+ if (retriesRemaining) {
+ loggerFor(this).info(
+ `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`,
+ );
+ loggerFor(this).debug(
+ `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`,
+ formatRequestDetails({
+ retryOfRequestLogID,
+ url,
+ durationMs: headersTime - startTime,
+ message: response.message,
+ }),
+ );
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
+ }
+ loggerFor(this).info(
+ `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`,
+ );
+ loggerFor(this).debug(
+ `[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`,
+ formatRequestDetails({
+ retryOfRequestLogID,
+ url,
+ durationMs: headersTime - startTime,
+ message: response.message,
+ }),
+ );
+ if (isTimeout) {
+ throw new Errors.APIConnectionTimeoutError();
+ }
+ throw new Errors.APIConnectionError({ cause: response });
+ }
+
+ const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${
+ response.ok ? 'succeeded' : 'failed'
+ } with status ${response.status} in ${headersTime - startTime}ms`;
+
+ if (!response.ok) {
+ const shouldRetry = await this.shouldRetry(response);
+ if (retriesRemaining && shouldRetry) {
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
+
+ // We don't need the body of this response.
+ await Shims.CancelReadableStream(response.body);
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
+ loggerFor(this).debug(
+ `[${requestLogID}] response error (${retryMessage})`,
+ formatRequestDetails({
+ retryOfRequestLogID,
+ url: response.url,
+ status: response.status,
+ headers: response.headers,
+ durationMs: headersTime - startTime,
+ }),
+ );
+ return this.retryRequest(
+ options,
+ retriesRemaining,
+ retryOfRequestLogID ?? requestLogID,
+ response.headers,
+ );
+ }
+
+ const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
+
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
+
+ const errText = await response.text().catch((err: any) => castToError(err).message);
+ const errJSON = safeJSON(errText);
+ const errMessage = errJSON ? undefined : errText;
+
+ loggerFor(this).debug(
+ `[${requestLogID}] response error (${retryMessage})`,
+ formatRequestDetails({
+ retryOfRequestLogID,
+ url: response.url,
+ status: response.status,
+ headers: response.headers,
+ message: errMessage,
+ durationMs: Date.now() - startTime,
+ }),
+ );
+ // @ts-ignore
+ const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
+ throw err;
+ }
+
+ loggerFor(this).info(responseInfo);
+ loggerFor(this).debug(
+ `[${requestLogID}] response start`,
+ formatRequestDetails({
+ retryOfRequestLogID,
+ url: response.url,
+ status: response.status,
+ headers: response.headers,
+ durationMs: headersTime - startTime,
+ }),
+ );
+
+ return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
+ }
+
+ async fetchWithTimeout(
+ url: RequestInfo,
+ init: RequestInit | undefined,
+ ms: number,
+ controller: AbortController,
+ ): Promise {
+ const { signal, method, ...options } = init || {};
+ if (signal) signal.addEventListener('abort', () => controller.abort());
+
+ const timeout = setTimeout(() => controller.abort(), ms);
+
+ const isReadableBody =
+ ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) ||
+ (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
+
+ const fetchOptions: RequestInit = {
+ signal: controller.signal as any,
+ ...(isReadableBody ? { duplex: 'half' } : {}),
+ method: 'GET',
+ ...options,
+ };
+ if (method) {
+ // Custom methods like 'patch' need to be uppercased
+ // See https://github.com/nodejs/undici/issues/2294
+ fetchOptions.method = method.toUpperCase();
+ }
+
+ try {
+ // use undefined this binding; fetch errors if bound to something else in browser/cloudflare
+ return await this.fetch.call(undefined, url, fetchOptions);
+ } finally {
+ clearTimeout(timeout);
+ }
+ }
+
+ private async shouldRetry(response: Response): Promise {
+ // Note this is not a standard header.
+ const shouldRetryHeader = response.headers.get('x-should-retry');
+
+ // If the server explicitly says whether or not to retry, obey.
+ if (shouldRetryHeader === 'true') return true;
+ if (shouldRetryHeader === 'false') return false;
+
+ // Retry on request timeouts.
+ if (response.status === 408) return true;
+
+ // Retry on lock timeouts.
+ if (response.status === 409) return true;
+
+ // Retry on rate limits.
+ if (response.status === 429) return true;
+
+ // Retry internal errors.
+ if (response.status >= 500) return true;
+
+ return false;
+ }
+
+ private async retryRequest(
+ options: FinalRequestOptions,
+ retriesRemaining: number,
+ requestLogID: string,
+ responseHeaders?: Headers | undefined,
+ ): Promise {
+ let timeoutMillis: number | undefined;
+
+ // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
+ const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms');
+ if (retryAfterMillisHeader) {
+ const timeoutMs = parseFloat(retryAfterMillisHeader);
+ if (!Number.isNaN(timeoutMs)) {
+ timeoutMillis = timeoutMs;
+ }
+ }
+
+ // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
+ const retryAfterHeader = responseHeaders?.get('retry-after');
+ if (retryAfterHeader && !timeoutMillis) {
+ const timeoutSeconds = parseFloat(retryAfterHeader);
+ if (!Number.isNaN(timeoutSeconds)) {
+ timeoutMillis = timeoutSeconds * 1000;
+ } else {
+ timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
+ }
+ }
+
+ // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
+ // just do what it says, but otherwise calculate a default
+ if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
+ const maxRetries = options.maxRetries ?? this.maxRetries;
+ timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
+ }
+ await sleep(timeoutMillis);
+
+ return this.makeRequest(options, retriesRemaining - 1, requestLogID);
+ }
+
+ private calculateDefaultRetryTimeoutMillis(retriesRemaining: number, maxRetries: number): number {
+ const initialRetryDelay = 0.5;
+ const maxRetryDelay = 8.0;
+
+ const numRetries = maxRetries - retriesRemaining;
+
+ // Apply exponential backoff, but not more than the max.
+ const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
+
+ // Apply some jitter, take up to at most 25 percent of the retry time.
+ const jitter = 1 - Math.random() * 0.25;
+
+ return sleepSeconds * jitter * 1000;
+ }
+
+ async buildRequest(
+ inputOptions: FinalRequestOptions,
+ { retryCount = 0 }: { retryCount?: number } = {},
+ ): Promise<{ req: FinalizedRequestInit; url: string; timeout: number }> {
+ const options = { ...inputOptions };
+ const { method, path, query, defaultBaseURL } = options;
+
+ const url = this.buildURL(path!, query as Record, defaultBaseURL);
+ if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
+ options.timeout = options.timeout ?? this.timeout;
+ const { bodyHeaders, body } = this.buildBody({ options });
+ const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
+
+ const req: FinalizedRequestInit = {
+ method,
+ headers: reqHeaders,
+ ...(options.signal && { signal: options.signal }),
+ ...((globalThis as any).ReadableStream &&
+ body instanceof (globalThis as any).ReadableStream && { duplex: 'half' }),
+ ...(body && { body }),
+ ...((this.fetchOptions as any) ?? {}),
+ ...((options.fetchOptions as any) ?? {}),
+ };
+
+ return { req, url, timeout: options.timeout };
+ }
+
+ private async buildHeaders({
+ options,
+ method,
+ bodyHeaders,
+ retryCount,
+ }: {
+ options: FinalRequestOptions;
+ method: HTTPMethod;
+ bodyHeaders: HeadersLike;
+ retryCount: number;
+ }): Promise {
+ let idempotencyHeaders: HeadersLike = {};
+ if (this.idempotencyHeader && method !== 'get') {
+ if (!options.idempotencyKey) options.idempotencyKey = this.defaultIdempotencyKey();
+ idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
+ }
+
+ const headers = buildHeaders([
+ idempotencyHeaders,
+ {
+ Accept: 'application/json',
+ 'User-Agent': this.getUserAgent(),
+ 'X-Stainless-Retry-Count': String(retryCount),
+ ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
+ ...getPlatformHeaders(),
+ },
+ await this.authHeaders(options),
+ this._options.defaultHeaders,
+ bodyHeaders,
+ options.headers,
+ ]);
+
+ this.validateHeaders(headers);
+
+ return headers.values;
+ }
+
+ private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): {
+ bodyHeaders: HeadersLike;
+ body: BodyInit | undefined;
+ } {
+ if (!body) {
+ return { bodyHeaders: undefined, body: undefined };
+ }
+ const headers = buildHeaders([rawHeaders]);
+ if (
+ // Pass raw type verbatim
+ ArrayBuffer.isView(body) ||
+ body instanceof ArrayBuffer ||
+ body instanceof DataView ||
+ (typeof body === 'string' &&
+ // Preserve legacy string encoding behavior for now
+ headers.values.has('content-type')) ||
+ // `Blob` is superset of `File`
+ ((globalThis as any).Blob && body instanceof (globalThis as any).Blob) ||
+ // `FormData` -> `multipart/form-data`
+ body instanceof FormData ||
+ // `URLSearchParams` -> `application/x-www-form-urlencoded`
+ body instanceof URLSearchParams ||
+ // Send chunked stream (each chunk has own `length`)
+ ((globalThis as any).ReadableStream && body instanceof (globalThis as any).ReadableStream)
+ ) {
+ return { bodyHeaders: undefined, body: body as BodyInit };
+ } else if (
+ typeof body === 'object' &&
+ (Symbol.asyncIterator in body ||
+ (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))
+ ) {
+ return { bodyHeaders: undefined, body: Shims.ReadableStreamFrom(body as AsyncIterable) };
+ } else {
+ return this.encoder({ body, headers });
+ }
+ }
+
+ static DEFAULT_TIMEOUT = 60000; // 1 minute
+}
+
+/**
+ * API Client for interfacing with the Gemini Next Gen API API.
+ */
+export class GeminiNextGenAPIClient extends BaseGeminiNextGenAPIClient {
+ static GeminiNextGenAPIClient = this;
+
+ static GeminiNextGenAPIClientError = Errors.GeminiNextGenAPIClientError;
+ static APIError = Errors.APIError;
+ static APIConnectionError = Errors.APIConnectionError;
+ static APIConnectionTimeoutError = Errors.APIConnectionTimeoutError;
+ static APIUserAbortError = Errors.APIUserAbortError;
+ static NotFoundError = Errors.NotFoundError;
+ static ConflictError = Errors.ConflictError;
+ static RateLimitError = Errors.RateLimitError;
+ static BadRequestError = Errors.BadRequestError;
+ static AuthenticationError = Errors.AuthenticationError;
+ static InternalServerError = Errors.InternalServerError;
+ static PermissionDeniedError = Errors.PermissionDeniedError;
+ static UnprocessableEntityError = Errors.UnprocessableEntityError;
+
+ static toFile = Uploads.toFile;
+
+ interactions: API.Interactions = new API.Interactions(this);
+}
+
+GeminiNextGenAPIClient.Interactions = Interactions;
+
+export declare namespace GeminiNextGenAPIClient {
+ export type RequestOptions = Opts.RequestOptions;
+
+ export {
+ Interactions as Interactions,
+ type AllowedTools as AllowedTools,
+ type Annotation as Annotation,
+ type AudioContent as AudioContent,
+ type AudioMimeType as AudioMimeType,
+ type CodeExecutionCallArguments as CodeExecutionCallArguments,
+ type CodeExecutionCallContent as CodeExecutionCallContent,
+ type CodeExecutionResultContent as CodeExecutionResultContent,
+ type ContentDelta as ContentDelta,
+ type ContentStart as ContentStart,
+ type ContentStop as ContentStop,
+ type DeepResearchAgentConfig as DeepResearchAgentConfig,
+ type DocumentContent as DocumentContent,
+ type DynamicAgentConfig as DynamicAgentConfig,
+ type ErrorEvent as ErrorEvent,
+ type FileSearchResultContent as FileSearchResultContent,
+ type Function as Function,
+ type FunctionCallContent as FunctionCallContent,
+ type FunctionResultContent as FunctionResultContent,
+ type GenerationConfig as GenerationConfig,
+ type GoogleSearchCallArguments as GoogleSearchCallArguments,
+ type GoogleSearchCallContent as GoogleSearchCallContent,
+ type GoogleSearchResult as GoogleSearchResult,
+ type GoogleSearchResultContent as GoogleSearchResultContent,
+ type ImageContent as ImageContent,
+ type ImageMimeType as ImageMimeType,
+ type Interaction as Interaction,
+ type InteractionEvent as InteractionEvent,
+ type InteractionSSEEvent as InteractionSSEEvent,
+ type InteractionStatusUpdate as InteractionStatusUpdate,
+ type MCPServerToolCallContent as MCPServerToolCallContent,
+ type MCPServerToolResultContent as MCPServerToolResultContent,
+ type Model as Model,
+ type SpeechConfig as SpeechConfig,
+ type TextContent as TextContent,
+ type ThinkingLevel as ThinkingLevel,
+ type ThoughtContent as ThoughtContent,
+ type Tool as Tool,
+ type ToolChoice as ToolChoice,
+ type ToolChoiceConfig as ToolChoiceConfig,
+ type ToolChoiceType as ToolChoiceType,
+ type Turn as Turn,
+ type URLContextCallArguments as URLContextCallArguments,
+ type URLContextCallContent as URLContextCallContent,
+ type URLContextResult as URLContextResult,
+ type URLContextResultContent as URLContextResultContent,
+ type Usage as Usage,
+ type VideoContent as VideoContent,
+ type VideoMimeType as VideoMimeType,
+ type InteractionDeleteResponse as InteractionDeleteResponse,
+ type InteractionCreateParams as InteractionCreateParams,
+ type CreateModelInteractionParamsNonStreaming as CreateModelInteractionParamsNonStreaming,
+ type CreateModelInteractionParamsStreaming as CreateModelInteractionParamsStreaming,
+ type CreateAgentInteractionParamsNonStreaming as CreateAgentInteractionParamsNonStreaming,
+ type CreateAgentInteractionParamsStreaming as CreateAgentInteractionParamsStreaming,
+ type InteractionDeleteParams as InteractionDeleteParams,
+ type InteractionCancelParams as InteractionCancelParams,
+ type InteractionGetParams as InteractionGetParams,
+ type InteractionGetParamsNonStreaming as InteractionGetParamsNonStreaming,
+ type InteractionGetParamsStreaming as InteractionGetParamsStreaming,
+ };
+}
diff --git a/src/interactions/core/README.md b/src/interactions/core/README.md
new file mode 100644
index 000000000..485fce861
--- /dev/null
+++ b/src/interactions/core/README.md
@@ -0,0 +1,3 @@
+# `core`
+
+This directory holds public modules implementing non-resource-specific SDK functionality.
diff --git a/src/interactions/core/api-promise.ts b/src/interactions/core/api-promise.ts
new file mode 100644
index 000000000..2cf0b0487
--- /dev/null
+++ b/src/interactions/core/api-promise.ts
@@ -0,0 +1,98 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { type BaseGeminiNextGenAPIClient } from '../client.js';
+
+import { type PromiseOrValue } from '../internal/types.js';
+import { APIResponseProps, defaultParseResponse } from '../internal/parse.js';
+
+/**
+ * A subclass of `Promise` providing additional helper methods
+ * for interacting with the SDK.
+ */
+export class APIPromise extends Promise {
+ private parsedPromise: Promise | undefined;
+ private client: BaseGeminiNextGenAPIClient;
+
+ constructor(
+ client: BaseGeminiNextGenAPIClient,
+ private responsePromise: Promise,
+ private parseResponse: (
+ client: BaseGeminiNextGenAPIClient,
+ props: APIResponseProps,
+ ) => PromiseOrValue = defaultParseResponse,
+ ) {
+ super((resolve) => {
+ // this is maybe a bit weird but this has to be a no-op to not implicitly
+ // parse the response body; instead .then, .catch, .finally are overridden
+ // to parse the response
+ resolve(null as any);
+ });
+ this.client = client;
+ }
+
+ _thenUnwrap(transform: (data: T, props: APIResponseProps) => U): APIPromise {
+ return new APIPromise(this.client, this.responsePromise, async (client, props) =>
+ transform(await this.parseResponse(client, props), props),
+ );
+ }
+
+ /**
+ * Gets the raw `Response` instance instead of parsing the response
+ * data.
+ *
+ * If you want to parse the response body but still get the `Response`
+ * instance, you can use {@link withResponse()}.
+ *
+ * 👋 Getting the wrong TypeScript type for `Response`?
+ * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
+ * to your `tsconfig.json`.
+ */
+ asResponse(): Promise {
+ return this.responsePromise.then((p) => p.response);
+ }
+
+ /**
+ * Gets the parsed response data and the raw `Response` instance.
+ *
+ * If you just want to get the raw `Response` instance without parsing it,
+ * you can use {@link asResponse()}.
+ *
+ * 👋 Getting the wrong TypeScript type for `Response`?
+ * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
+ * to your `tsconfig.json`.
+ */
+ async withResponse(): Promise<{ data: T; response: Response }> {
+ const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
+ return { data, response };
+ }
+
+ private parse(): Promise {
+ if (!this.parsedPromise) {
+ this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.client, data));
+ }
+ return this.parsedPromise;
+ }
+
+ override then(
+ onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null,
+ onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null,
+ ): Promise {
+ return this.parse().then(onfulfilled, onrejected);
+ }
+
+ override catch(
+ onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null,
+ ): Promise {
+ return this.parse().catch(onrejected);
+ }
+
+ override finally(onfinally?: (() => void) | undefined | null): Promise {
+ return this.parse().finally(onfinally);
+ }
+}
diff --git a/src/interactions/core/error.ts b/src/interactions/core/error.ts
new file mode 100644
index 000000000..1a163bd80
--- /dev/null
+++ b/src/interactions/core/error.ts
@@ -0,0 +1,136 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { castToError } from '../internal/errors.js';
+
+export class GeminiNextGenAPIClientError extends Error {}
+
+export class APIError<
+ TStatus extends number | undefined = number | undefined,
+ THeaders extends Headers | undefined = Headers | undefined,
+ TError extends Object | undefined = Object | undefined,
+> extends GeminiNextGenAPIClientError {
+ /** HTTP status for the response that caused the error */
+ readonly status: TStatus;
+ /** HTTP headers for the response that caused the error */
+ readonly headers: THeaders;
+ /** JSON body of the response that caused the error */
+ readonly error: TError;
+
+ constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) {
+ super(`${APIError.makeMessage(status, error, message)}`);
+ this.status = status;
+ this.headers = headers;
+ this.error = error;
+ }
+
+ private static makeMessage(status: number | undefined, error: any, message: string | undefined) {
+ const msg =
+ error?.message ?
+ typeof error.message === 'string' ?
+ error.message
+ : JSON.stringify(error.message)
+ : error ? JSON.stringify(error)
+ : message;
+
+ if (status && msg) {
+ return `${status} ${msg}`;
+ }
+ if (status) {
+ return `${status} status code (no body)`;
+ }
+ if (msg) {
+ return msg;
+ }
+ return '(no status code or body)';
+ }
+
+ static generate(
+ status: number | undefined,
+ errorResponse: Object | undefined,
+ message: string | undefined,
+ headers: Headers | undefined,
+ ): APIError {
+ if (!status || !headers) {
+ return new APIConnectionError({ message, cause: castToError(errorResponse) });
+ }
+
+ const error = errorResponse as Record;
+
+ if (status === 400) {
+ return new BadRequestError(status, error, message, headers);
+ }
+
+ if (status === 401) {
+ return new AuthenticationError(status, error, message, headers);
+ }
+
+ if (status === 403) {
+ return new PermissionDeniedError(status, error, message, headers);
+ }
+
+ if (status === 404) {
+ return new NotFoundError(status, error, message, headers);
+ }
+
+ if (status === 409) {
+ return new ConflictError(status, error, message, headers);
+ }
+
+ if (status === 422) {
+ return new UnprocessableEntityError(status, error, message, headers);
+ }
+
+ if (status === 429) {
+ return new RateLimitError(status, error, message, headers);
+ }
+
+ if (status >= 500) {
+ return new InternalServerError(status, error, message, headers);
+ }
+
+ return new APIError(status, error, message, headers);
+ }
+}
+
+export class APIUserAbortError extends APIError {
+ constructor({ message }: { message?: string } = {}) {
+ super(undefined, undefined, message || 'Request was aborted.', undefined);
+ }
+}
+
+export class APIConnectionError extends APIError {
+ constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) {
+ super(undefined, undefined, message || 'Connection error.', undefined);
+ // in some environments the 'cause' property is already declared
+ // @ts-ignore
+ if (cause) this.cause = cause;
+ }
+}
+
+export class APIConnectionTimeoutError extends APIConnectionError {
+ constructor({ message }: { message?: string } = {}) {
+ super({ message: message ?? 'Request timed out.' });
+ }
+}
+
+export class BadRequestError extends APIError<400, Headers> {}
+
+export class AuthenticationError extends APIError<401, Headers> {}
+
+export class PermissionDeniedError extends APIError<403, Headers> {}
+
+export class NotFoundError extends APIError<404, Headers> {}
+
+export class ConflictError extends APIError<409, Headers> {}
+
+export class UnprocessableEntityError extends APIError<422, Headers> {}
+
+export class RateLimitError extends APIError<429, Headers> {}
+
+export class InternalServerError extends APIError {}
diff --git a/src/interactions/core/resource.ts b/src/interactions/core/resource.ts
new file mode 100644
index 000000000..4b3fc77ef
--- /dev/null
+++ b/src/interactions/core/resource.ts
@@ -0,0 +1,22 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { BaseGeminiNextGenAPIClient } from '../client.js';
+
+export abstract class APIResource {
+ /**
+ * The key path from the client. For example, a resource accessible as `client.resource.subresource` would
+ * have a property `static override readonly _key = Object.freeze(['resource', 'subresource'] as const);`.
+ */
+ static readonly _key: readonly string[] = [];
+ protected _client: BaseGeminiNextGenAPIClient;
+
+ constructor(client: BaseGeminiNextGenAPIClient) {
+ this._client = client;
+ }
+}
diff --git a/src/interactions/core/streaming.ts b/src/interactions/core/streaming.ts
new file mode 100644
index 000000000..6496fc8fa
--- /dev/null
+++ b/src/interactions/core/streaming.ts
@@ -0,0 +1,334 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { GeminiNextGenAPIClientError } from './error.js';
+import { type ReadableStream } from '../internal/shim-types.js';
+import { makeReadableStream } from '../internal/shims.js';
+import { findDoubleNewlineIndex, LineDecoder } from '../internal/decoders/line.js';
+import { ReadableStreamToAsyncIterable } from '../internal/shims.js';
+import { isAbortError } from '../internal/errors.js';
+import { encodeUTF8 } from '../internal/utils/bytes.js';
+import { loggerFor } from '../internal/utils/log.js';
+import type { BaseGeminiNextGenAPIClient } from '../client.js';
+
+type Bytes = string | ArrayBuffer | Uint8Array | null | undefined;
+
+export type ServerSentEvent = {
+ event: string | null;
+ data: string;
+ raw: string[];
+};
+
+export class Stream- implements AsyncIterable
- {
+ controller: AbortController;
+ private client: BaseGeminiNextGenAPIClient | undefined;
+
+ constructor(
+ private iterator: () => AsyncIterator
- ,
+ controller: AbortController,
+ client?: BaseGeminiNextGenAPIClient,
+ ) {
+ this.controller = controller;
+ this.client = client;
+ }
+
+ static fromSSEResponse
- (
+ response: Response,
+ controller: AbortController,
+ client?: BaseGeminiNextGenAPIClient,
+ ): Stream
- {
+ let consumed = false;
+ const logger = client ? loggerFor(client) : console;
+
+ async function* iterator(): AsyncIterator
- {
+ if (consumed) {
+ throw new GeminiNextGenAPIClientError(
+ 'Cannot iterate over a consumed stream, use `.tee()` to split the stream.',
+ );
+ }
+ consumed = true;
+ let done = false;
+ try {
+ for await (const sse of _iterSSEMessages(response, controller)) {
+ if (done) continue;
+
+ if (sse.data.startsWith('[DONE]')) {
+ done = true;
+ continue;
+ } else {
+ try {
+ // @ts-ignore
+ yield JSON.parse(sse.data);
+ } catch (e) {
+ logger.error(`Could not parse message into JSON:`, sse.data);
+ logger.error(`From chunk:`, sse.raw);
+ throw e;
+ }
+ }
+ }
+ done = true;
+ } catch (e) {
+ // If the user calls `stream.controller.abort()`, we should exit without throwing.
+ if (isAbortError(e)) return;
+ throw e;
+ } finally {
+ // If the user `break`s, abort the ongoing request.
+ if (!done) controller.abort();
+ }
+ }
+
+ return new Stream(iterator, controller, client);
+ }
+
+ /**
+ * Generates a Stream from a newline-separated ReadableStream
+ * where each item is a JSON value.
+ */
+ static fromReadableStream
- (
+ readableStream: ReadableStream,
+ controller: AbortController,
+ client?: BaseGeminiNextGenAPIClient,
+ ): Stream
- {
+ let consumed = false;
+
+ async function* iterLines(): AsyncGenerator {
+ const lineDecoder = new LineDecoder();
+
+ const iter = ReadableStreamToAsyncIterable(readableStream);
+ for await (const chunk of iter) {
+ for (const line of lineDecoder.decode(chunk)) {
+ yield line;
+ }
+ }
+
+ for (const line of lineDecoder.flush()) {
+ yield line;
+ }
+ }
+
+ async function* iterator(): AsyncIterator
- {
+ if (consumed) {
+ throw new GeminiNextGenAPIClientError(
+ 'Cannot iterate over a consumed stream, use `.tee()` to split the stream.',
+ );
+ }
+ consumed = true;
+ let done = false;
+ try {
+ for await (const line of iterLines()) {
+ if (done) continue;
+ // @ts-ignore
+ if (line) yield JSON.parse(line);
+ }
+ done = true;
+ } catch (e) {
+ // If the user calls `stream.controller.abort()`, we should exit without throwing.
+ if (isAbortError(e)) return;
+ throw e;
+ } finally {
+ // If the user `break`s, abort the ongoing request.
+ if (!done) controller.abort();
+ }
+ }
+
+ return new Stream(iterator, controller, client);
+ }
+
+ [Symbol.asyncIterator](): AsyncIterator
- {
+ return this.iterator();
+ }
+
+ /**
+ * Splits the stream into two streams which can be
+ * independently read from at different speeds.
+ */
+ tee(): [Stream
- , Stream
- ] {
+ const left: Array>> = [];
+ const right: Array>> = [];
+ const iterator = this.iterator();
+
+ const teeIterator = (queue: Array>>): AsyncIterator
- => {
+ return {
+ next: () => {
+ if (queue.length === 0) {
+ const result = iterator.next();
+ left.push(result);
+ right.push(result);
+ }
+ return queue.shift()!;
+ },
+ };
+ };
+
+ return [
+ new Stream(() => teeIterator(left), this.controller, this.client),
+ new Stream(() => teeIterator(right), this.controller, this.client),
+ ];
+ }
+
+ /**
+ * Converts this stream to a newline-separated ReadableStream of
+ * JSON stringified values in the stream
+ * which can be turned back into a Stream with `Stream.fromReadableStream()`.
+ */
+ toReadableStream(): ReadableStream {
+ const self = this;
+ let iter: AsyncIterator
- ;
+
+ return makeReadableStream({
+ async start() {
+ iter = self[Symbol.asyncIterator]();
+ },
+ async pull(ctrl: any) {
+ try {
+ const { value, done } = await iter.next();
+ if (done) return ctrl.close();
+
+ const bytes = encodeUTF8(JSON.stringify(value) + '\n');
+
+ ctrl.enqueue(bytes);
+ } catch (err) {
+ ctrl.error(err);
+ }
+ },
+ async cancel() {
+ await iter.return?.();
+ },
+ });
+ }
+}
+
+export async function* _iterSSEMessages(
+ response: Response,
+ controller: AbortController,
+): AsyncGenerator {
+ if (!response.body) {
+ controller.abort();
+ if (
+ typeof (globalThis as any).navigator !== 'undefined' &&
+ (globalThis as any).navigator.product === 'ReactNative'
+ ) {
+ throw new GeminiNextGenAPIClientError(
+ `The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`,
+ );
+ }
+ throw new GeminiNextGenAPIClientError(`Attempted to iterate over a response with no body`);
+ }
+
+ const sseDecoder = new SSEDecoder();
+ const lineDecoder = new LineDecoder();
+
+ const iter = ReadableStreamToAsyncIterable(response.body);
+ for await (const sseChunk of iterSSEChunks(iter)) {
+ for (const line of lineDecoder.decode(sseChunk)) {
+ const sse = sseDecoder.decode(line);
+ if (sse) yield sse;
+ }
+ }
+
+ for (const line of lineDecoder.flush()) {
+ const sse = sseDecoder.decode(line);
+ if (sse) yield sse;
+ }
+}
+
+/**
+ * Given an async iterable iterator, iterates over it and yields full
+ * SSE chunks, i.e. yields when a double new-line is encountered.
+ */
+async function* iterSSEChunks(iterator: AsyncIterableIterator): AsyncGenerator {
+ let data = new Uint8Array();
+
+ for await (const chunk of iterator) {
+ if (chunk == null) {
+ continue;
+ }
+
+ const binaryChunk =
+ chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
+ : typeof chunk === 'string' ? encodeUTF8(chunk)
+ : chunk;
+
+ let newData = new Uint8Array(data.length + binaryChunk.length);
+ newData.set(data);
+ newData.set(binaryChunk, data.length);
+ data = newData;
+
+ let patternIndex;
+ while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) {
+ yield data.slice(0, patternIndex);
+ data = data.slice(patternIndex);
+ }
+ }
+
+ if (data.length > 0) {
+ yield data;
+ }
+}
+
+class SSEDecoder {
+ private data: string[];
+ private event: string | null;
+ private chunks: string[];
+
+ constructor() {
+ this.event = null;
+ this.data = [];
+ this.chunks = [];
+ }
+
+ decode(line: string) {
+ if (line.endsWith('\r')) {
+ line = line.substring(0, line.length - 1);
+ }
+
+ if (!line) {
+ // empty line and we didn't previously encounter any messages
+ if (!this.event && !this.data.length) return null;
+
+ const sse: ServerSentEvent = {
+ event: this.event,
+ data: this.data.join('\n'),
+ raw: this.chunks,
+ };
+
+ this.event = null;
+ this.data = [];
+ this.chunks = [];
+
+ return sse;
+ }
+
+ this.chunks.push(line);
+
+ if (line.startsWith(':')) {
+ return null;
+ }
+
+ let [fieldname, _, value] = partition(line, ':');
+
+ if (value.startsWith(' ')) {
+ value = value.substring(1);
+ }
+
+ if (fieldname === 'event') {
+ this.event = value;
+ } else if (fieldname === 'data') {
+ this.data.push(value);
+ }
+
+ return null;
+ }
+}
+
+function partition(str: string, delimiter: string): [string, string, string] {
+ const index = str.indexOf(delimiter);
+ if (index !== -1) {
+ return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)];
+ }
+
+ return [str, '', ''];
+}
diff --git a/src/interactions/core/uploads.ts b/src/interactions/core/uploads.ts
new file mode 100644
index 000000000..27a020a47
--- /dev/null
+++ b/src/interactions/core/uploads.ts
@@ -0,0 +1,8 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export { type Uploadable } from '../internal/uploads.js';
+export { toFile, type ToFileInput, type BlobLikePart } from '../internal/to-file.js';
diff --git a/src/interactions/error.ts b/src/interactions/error.ts
new file mode 100644
index 000000000..cfecafa72
--- /dev/null
+++ b/src/interactions/error.ts
@@ -0,0 +1,8 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/** @deprecated Import from ./core/error instead */
+export * from './core/error.js';
diff --git a/src/interactions/index.ts b/src/interactions/index.ts
new file mode 100644
index 000000000..f09f1f7bd
--- /dev/null
+++ b/src/interactions/index.ts
@@ -0,0 +1,28 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export { GeminiNextGenAPIClient as default } from './client.js';
+
+export { type Uploadable, type BlobLikePart, toFile } from './core/uploads.js';
+export { APIPromise } from './core/api-promise.js';
+export { BaseGeminiNextGenAPIClient, GeminiNextGenAPIClient, type ClientOptions } from './client.js';
+export {
+ GeminiNextGenAPIClientError,
+ APIError,
+ APIConnectionError,
+ APIConnectionTimeoutError,
+ APIUserAbortError,
+ NotFoundError,
+ ConflictError,
+ RateLimitError,
+ BadRequestError,
+ AuthenticationError,
+ InternalServerError,
+ PermissionDeniedError,
+ UnprocessableEntityError,
+} from './core/error.js';
diff --git a/src/interactions/internal/README.md b/src/interactions/internal/README.md
new file mode 100644
index 000000000..3ef5a25ba
--- /dev/null
+++ b/src/interactions/internal/README.md
@@ -0,0 +1,3 @@
+# `internal`
+
+The modules in this directory are not importable outside this package and will change between releases.
diff --git a/src/interactions/internal/builtin-types.ts b/src/interactions/internal/builtin-types.ts
new file mode 100644
index 000000000..c73a68858
--- /dev/null
+++ b/src/interactions/internal/builtin-types.ts
@@ -0,0 +1,99 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export type Fetch = (input: string | URL | Request, init?: RequestInit) => Promise;
+
+/**
+ * An alias to the builtin `RequestInit` type so we can
+ * easily alias it in import statements if there are name clashes.
+ *
+ * https://developer.mozilla.org/docs/Web/API/RequestInit
+ */
+type _RequestInit = RequestInit;
+
+/**
+ * An alias to the builtin `Response` type so we can
+ * easily alias it in import statements if there are name clashes.
+ *
+ * https://developer.mozilla.org/docs/Web/API/Response
+ */
+type _Response = Response;
+
+/**
+ * The type for the first argument to `fetch`.
+ *
+ * https://developer.mozilla.org/docs/Web/API/Window/fetch#resource
+ */
+type _RequestInfo = Request | URL | string;
+
+/**
+ * The type for constructing `RequestInit` Headers.
+ *
+ * https://developer.mozilla.org/docs/Web/API/RequestInit#setting_headers
+ */
+type _HeadersInit = RequestInit['headers'];
+
+/**
+ * The type for constructing `RequestInit` body.
+ *
+ * https://developer.mozilla.org/docs/Web/API/RequestInit#body
+ */
+type _BodyInit = RequestInit['body'];
+
+/**
+ * An alias to the builtin `Array` type so we can
+ * easily alias it in import statements if there are name clashes.
+ */
+type _Array = Array;
+
+/**
+ * An alias to the builtin `Record` type so we can
+ * easily alias it in import statements if there are name clashes.
+ */
+type _Record = Record;
+
+export type {
+ _Array as Array,
+ _BodyInit as BodyInit,
+ _HeadersInit as HeadersInit,
+ _Record as Record,
+ _RequestInfo as RequestInfo,
+ _RequestInit as RequestInit,
+ _Response as Response,
+};
+
+/**
+ * A copy of the builtin `EndingType` type as it isn't fully supported in certain
+ * environments and attempting to reference the global version will error.
+ *
+ * https://github.com/microsoft/TypeScript/blob/49ad1a3917a0ea57f5ff248159256e12bb1cb705/src/lib/dom.generated.d.ts#L27941
+ */
+type EndingType = 'native' | 'transparent';
+
+/**
+ * A copy of the builtin `BlobPropertyBag` type as it isn't fully supported in certain
+ * environments and attempting to reference the global version will error.
+ *
+ * https://github.com/microsoft/TypeScript/blob/49ad1a3917a0ea57f5ff248159256e12bb1cb705/src/lib/dom.generated.d.ts#L154
+ * https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob#options
+ */
+export interface BlobPropertyBag {
+ endings?: EndingType;
+ type?: string;
+}
+
+/**
+ * A copy of the builtin `FilePropertyBag` type as it isn't fully supported in certain
+ * environments and attempting to reference the global version will error.
+ *
+ * https://github.com/microsoft/TypeScript/blob/49ad1a3917a0ea57f5ff248159256e12bb1cb705/src/lib/dom.generated.d.ts#L503
+ * https://developer.mozilla.org/en-US/docs/Web/API/File/File#options
+ */
+export interface FilePropertyBag extends BlobPropertyBag {
+ lastModified?: number;
+}
diff --git a/src/interactions/internal/decoders/line.ts b/src/interactions/internal/decoders/line.ts
new file mode 100644
index 000000000..4206b92f0
--- /dev/null
+++ b/src/interactions/internal/decoders/line.ts
@@ -0,0 +1,141 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { concatBytes, decodeUTF8, encodeUTF8 } from '../utils/bytes.js';
+
+export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined;
+
+/**
+ * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally
+ * reading lines from text.
+ *
+ * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258
+ */
+export class LineDecoder {
+ // prettier-ignore
+ static NEWLINE_CHARS = new Set(['\n', '\r']);
+ static NEWLINE_REGEXP = /\r\n|[\n\r]/g;
+
+ private buffer: Uint8Array;
+ private carriageReturnIndex: number | null;
+
+ constructor() {
+ this.buffer = new Uint8Array();
+ this.carriageReturnIndex = null;
+ }
+
+ decode(chunk: Bytes): string[] {
+ if (chunk == null) {
+ return [];
+ }
+
+ const binaryChunk =
+ chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
+ : typeof chunk === 'string' ? encodeUTF8(chunk)
+ : chunk;
+
+ this.buffer = concatBytes([this.buffer, binaryChunk]);
+
+ const lines: string[] = [];
+ let patternIndex;
+ while ((patternIndex = findNewlineIndex(this.buffer, this.carriageReturnIndex)) != null) {
+ if (patternIndex.carriage && this.carriageReturnIndex == null) {
+ // skip until we either get a corresponding `\n`, a new `\r` or nothing
+ this.carriageReturnIndex = patternIndex.index;
+ continue;
+ }
+
+ // we got double \r or \rtext\n
+ if (
+ this.carriageReturnIndex != null &&
+ (patternIndex.index !== this.carriageReturnIndex + 1 || patternIndex.carriage)
+ ) {
+ lines.push(decodeUTF8(this.buffer.subarray(0, this.carriageReturnIndex - 1)));
+ this.buffer = this.buffer.subarray(this.carriageReturnIndex);
+ this.carriageReturnIndex = null;
+ continue;
+ }
+
+ const endIndex =
+ this.carriageReturnIndex !== null ? patternIndex.preceding - 1 : patternIndex.preceding;
+
+ const line = decodeUTF8(this.buffer.subarray(0, endIndex));
+ lines.push(line);
+
+ this.buffer = this.buffer.subarray(patternIndex.index);
+ this.carriageReturnIndex = null;
+ }
+
+ return lines;
+ }
+
+ flush(): string[] {
+ if (!this.buffer.length) {
+ return [];
+ }
+ return this.decode('\n');
+ }
+}
+
+/**
+ * This function searches the buffer for the end patterns, (\r or \n)
+ * and returns an object with the index preceding the matched newline and the
+ * index after the newline char. `null` is returned if no new line is found.
+ *
+ * ```ts
+ * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 }
+ * ```
+ */
+function findNewlineIndex(
+ buffer: Uint8Array,
+ startIndex: number | null,
+): { preceding: number; index: number; carriage: boolean } | null {
+ const newline = 0x0a; // \n
+ const carriage = 0x0d; // \r
+
+ for (let i = startIndex ?? 0; i < buffer.length; i++) {
+ if (buffer[i] === newline) {
+ return { preceding: i, index: i + 1, carriage: false };
+ }
+
+ if (buffer[i] === carriage) {
+ return { preceding: i, index: i + 1, carriage: true };
+ }
+ }
+
+ return null;
+}
+
+export function findDoubleNewlineIndex(buffer: Uint8Array): number {
+ // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n)
+ // and returns the index right after the first occurrence of any pattern,
+ // or -1 if none of the patterns are found.
+ const newline = 0x0a; // \n
+ const carriage = 0x0d; // \r
+
+ for (let i = 0; i < buffer.length - 1; i++) {
+ if (buffer[i] === newline && buffer[i + 1] === newline) {
+ // \n\n
+ return i + 2;
+ }
+ if (buffer[i] === carriage && buffer[i + 1] === carriage) {
+ // \r\r
+ return i + 2;
+ }
+ if (
+ buffer[i] === carriage &&
+ buffer[i + 1] === newline &&
+ i + 3 < buffer.length &&
+ buffer[i + 2] === carriage &&
+ buffer[i + 3] === newline
+ ) {
+ // \r\n\r\n
+ return i + 4;
+ }
+ }
+
+ return -1;
+}
diff --git a/src/interactions/internal/detect-platform.ts b/src/interactions/internal/detect-platform.ts
new file mode 100644
index 000000000..3152e85d2
--- /dev/null
+++ b/src/interactions/internal/detect-platform.ts
@@ -0,0 +1,200 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { VERSION } from '../version.js';
+
+export const isRunningInBrowser = () => {
+ return (
+ // @ts-ignore
+ (typeof window !== 'undefined' &&
+ // @ts-ignore
+ typeof window.document !== 'undefined' && typeof navigator !== 'undefined')
+ );
+};
+
+type DetectedPlatform = 'deno' | 'node' | 'edge' | 'unknown';
+
+/**
+ * Note this does not detect 'browser'; for that, use getBrowserInfo().
+ */
+function getDetectedPlatform(): DetectedPlatform {
+ if (typeof Deno !== 'undefined' && Deno.build != null) {
+ return 'deno';
+ }
+ if (typeof EdgeRuntime !== 'undefined') {
+ return 'edge';
+ }
+ if (
+ Object.prototype.toString.call(
+ typeof (globalThis as any).process !== 'undefined' ? (globalThis as any).process : 0,
+ ) === '[object process]'
+ ) {
+ return 'node';
+ }
+ return 'unknown';
+}
+
+declare const Deno: any;
+declare const EdgeRuntime: any;
+type Arch = 'x32' | 'x64' | 'arm' | 'arm64' | `other:${string}` | 'unknown';
+type PlatformName =
+ | 'MacOS'
+ | 'Linux'
+ | 'Windows'
+ | 'FreeBSD'
+ | 'OpenBSD'
+ | 'iOS'
+ | 'Android'
+ | `Other:${string}`
+ | 'Unknown';
+type Browser = 'ie' | 'edge' | 'chrome' | 'firefox' | 'safari';
+type PlatformProperties = {
+ 'X-Stainless-Lang': 'js';
+ 'X-Stainless-Package-Version': string;
+ 'X-Stainless-OS': PlatformName;
+ 'X-Stainless-Arch': Arch;
+ 'X-Stainless-Runtime': 'node' | 'deno' | 'edge' | `browser:${Browser}` | 'unknown';
+ 'X-Stainless-Runtime-Version': string;
+};
+const getPlatformProperties = (): PlatformProperties => {
+ const detectedPlatform = getDetectedPlatform();
+ if (detectedPlatform === 'deno') {
+ return {
+ 'X-Stainless-Lang': 'js',
+ 'X-Stainless-Package-Version': VERSION,
+ 'X-Stainless-OS': normalizePlatform(Deno.build.os),
+ 'X-Stainless-Arch': normalizeArch(Deno.build.arch),
+ 'X-Stainless-Runtime': 'deno',
+ 'X-Stainless-Runtime-Version':
+ typeof Deno.version === 'string' ? Deno.version : Deno.version?.deno ?? 'unknown',
+ };
+ }
+ if (typeof EdgeRuntime !== 'undefined') {
+ return {
+ 'X-Stainless-Lang': 'js',
+ 'X-Stainless-Package-Version': VERSION,
+ 'X-Stainless-OS': 'Unknown',
+ 'X-Stainless-Arch': `other:${EdgeRuntime}`,
+ 'X-Stainless-Runtime': 'edge',
+ 'X-Stainless-Runtime-Version': (globalThis as any).process.version,
+ };
+ }
+ // Check if Node.js
+ if (detectedPlatform === 'node') {
+ return {
+ 'X-Stainless-Lang': 'js',
+ 'X-Stainless-Package-Version': VERSION,
+ 'X-Stainless-OS': normalizePlatform((globalThis as any).process.platform ?? 'unknown'),
+ 'X-Stainless-Arch': normalizeArch((globalThis as any).process.arch ?? 'unknown'),
+ 'X-Stainless-Runtime': 'node',
+ 'X-Stainless-Runtime-Version': (globalThis as any).process.version ?? 'unknown',
+ };
+ }
+
+ const browserInfo = getBrowserInfo();
+ if (browserInfo) {
+ return {
+ 'X-Stainless-Lang': 'js',
+ 'X-Stainless-Package-Version': VERSION,
+ 'X-Stainless-OS': 'Unknown',
+ 'X-Stainless-Arch': 'unknown',
+ 'X-Stainless-Runtime': `browser:${browserInfo.browser}`,
+ 'X-Stainless-Runtime-Version': browserInfo.version,
+ };
+ }
+
+ // TODO add support for Cloudflare workers, etc.
+ return {
+ 'X-Stainless-Lang': 'js',
+ 'X-Stainless-Package-Version': VERSION,
+ 'X-Stainless-OS': 'Unknown',
+ 'X-Stainless-Arch': 'unknown',
+ 'X-Stainless-Runtime': 'unknown',
+ 'X-Stainless-Runtime-Version': 'unknown',
+ };
+};
+
+type BrowserInfo = {
+ browser: Browser;
+ version: string;
+};
+
+declare const navigator: { userAgent: string } | undefined;
+
+// Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts
+function getBrowserInfo(): BrowserInfo | null {
+ if (typeof navigator === 'undefined' || !navigator) {
+ return null;
+ }
+
+ // NOTE: The order matters here!
+ const browserPatterns = [
+ { key: 'edge' as const, pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
+ { key: 'ie' as const, pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
+ { key: 'ie' as const, pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
+ { key: 'chrome' as const, pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
+ { key: 'firefox' as const, pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
+ { key: 'safari' as const, pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ },
+ ];
+
+ // Find the FIRST matching browser
+ for (const { key, pattern } of browserPatterns) {
+ const match = pattern.exec(navigator.userAgent);
+ if (match) {
+ const major = match[1] || 0;
+ const minor = match[2] || 0;
+ const patch = match[3] || 0;
+
+ return { browser: key, version: `${major}.${minor}.${patch}` };
+ }
+ }
+
+ return null;
+}
+
+const normalizeArch = (arch: string): Arch => {
+ // Node docs:
+ // - https://nodejs.org/api/process.html#processarch
+ // Deno docs:
+ // - https://doc.deno.land/deno/stable/~/Deno.build
+ if (arch === 'x32') return 'x32';
+ if (arch === 'x86_64' || arch === 'x64') return 'x64';
+ if (arch === 'arm') return 'arm';
+ if (arch === 'aarch64' || arch === 'arm64') return 'arm64';
+ if (arch) return `other:${arch}`;
+ return 'unknown';
+};
+
+const normalizePlatform = (platform: string): PlatformName => {
+ // Node platforms:
+ // - https://nodejs.org/api/process.html#processplatform
+ // Deno platforms:
+ // - https://doc.deno.land/deno/stable/~/Deno.build
+ // - https://github.com/denoland/deno/issues/14799
+
+ platform = platform.toLowerCase();
+
+ // NOTE: this iOS check is untested and may not work
+ // Node does not work natively on IOS, there is a fork at
+ // https://github.com/nodejs-mobile/nodejs-mobile
+ // however it is unknown at the time of writing how to detect if it is running
+ if (platform.includes('ios')) return 'iOS';
+ if (platform === 'android') return 'Android';
+ if (platform === 'darwin') return 'MacOS';
+ if (platform === 'win32') return 'Windows';
+ if (platform === 'freebsd') return 'FreeBSD';
+ if (platform === 'openbsd') return 'OpenBSD';
+ if (platform === 'linux') return 'Linux';
+ if (platform) return `Other:${platform}`;
+ return 'Unknown';
+};
+
+let _platformHeaders: PlatformProperties;
+export const getPlatformHeaders = () => {
+ return (_platformHeaders ??= getPlatformProperties());
+};
diff --git a/src/interactions/internal/errors.ts b/src/interactions/internal/errors.ts
new file mode 100644
index 000000000..6c43ba768
--- /dev/null
+++ b/src/interactions/internal/errors.ts
@@ -0,0 +1,39 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export function isAbortError(err: unknown) {
+ return (
+ typeof err === 'object' &&
+ err !== null &&
+ // Spec-compliant fetch implementations
+ (('name' in err && (err as any).name === 'AbortError') ||
+ // Expo fetch
+ ('message' in err && String((err as any).message).includes('FetchRequestCanceledException')))
+ );
+}
+
+export const castToError = (err: any): Error => {
+ if (err instanceof Error) return err;
+ if (typeof err === 'object' && err !== null) {
+ try {
+ if (Object.prototype.toString.call(err) === '[object Error]') {
+ // @ts-ignore - not all envs have native support for cause yet
+ const error = new Error(err.message, err.cause ? { cause: err.cause } : {});
+ if (err.stack) error.stack = err.stack;
+ // @ts-ignore - not all envs have native support for cause yet
+ if (err.cause && !error.cause) error.cause = err.cause;
+ if (err.name) error.name = err.name;
+ return error;
+ }
+ } catch {}
+ try {
+ return new Error(JSON.stringify(err));
+ } catch {}
+ }
+ return new Error(err);
+};
diff --git a/src/interactions/internal/headers.ts b/src/interactions/internal/headers.ts
new file mode 100644
index 000000000..f3980425b
--- /dev/null
+++ b/src/interactions/internal/headers.ts
@@ -0,0 +1,103 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { isReadonlyArray } from './utils/values.js';
+
+type HeaderValue = string | undefined | null;
+export type HeadersLike =
+ | Headers
+ | readonly HeaderValue[][]
+ | Record
+ | undefined
+ | null
+ | NullableHeaders;
+
+const brand_privateNullableHeaders = /* @__PURE__ */ Symbol('brand.privateNullableHeaders');
+
+/**
+ * @internal
+ * Users can pass explicit nulls to unset default headers. When we parse them
+ * into a standard headers type we need to preserve that information.
+ */
+export type NullableHeaders = {
+ /** Brand check, prevent users from creating a NullableHeaders. */
+ [brand_privateNullableHeaders]: true;
+ /** Parsed headers. */
+ values: Headers;
+ /** Set of lowercase header names explicitly set to null. */
+ nulls: Set;
+};
+
+function* iterateHeaders(headers: HeadersLike): IterableIterator {
+ if (!headers) return;
+
+ if (brand_privateNullableHeaders in headers) {
+ const { values, nulls } = headers;
+ yield* values.entries();
+ for (const name of nulls) {
+ yield [name, null];
+ }
+ return;
+ }
+
+ let shouldClear = false;
+ let iter: Iterable;
+ if (headers instanceof Headers) {
+ iter = headers.entries();
+ } else if (isReadonlyArray(headers)) {
+ iter = headers;
+ } else {
+ shouldClear = true;
+ iter = Object.entries(headers ?? {});
+ }
+ for (let row of iter) {
+ const name = row[0];
+ if (typeof name !== 'string') throw new TypeError('expected header name to be a string');
+ const values = isReadonlyArray(row[1]) ? row[1] : [row[1]];
+ let didClear = false;
+ for (const value of values) {
+ if (value === undefined) continue;
+
+ // Objects keys always overwrite older headers, they never append.
+ // Yield a null to clear the header before adding the new values.
+ if (shouldClear && !didClear) {
+ didClear = true;
+ yield [name, null];
+ }
+ yield [name, value];
+ }
+ }
+}
+
+export const buildHeaders = (newHeaders: HeadersLike[]): NullableHeaders => {
+ const targetHeaders = new Headers();
+ const nullHeaders = new Set();
+ for (const headers of newHeaders) {
+ const seenHeaders = new Set();
+ for (const [name, value] of iterateHeaders(headers)) {
+ const lowerName = name.toLowerCase();
+ if (!seenHeaders.has(lowerName)) {
+ targetHeaders.delete(name);
+ seenHeaders.add(lowerName);
+ }
+ if (value === null) {
+ targetHeaders.delete(name);
+ nullHeaders.add(lowerName);
+ } else {
+ targetHeaders.append(name, value);
+ nullHeaders.delete(lowerName);
+ }
+ }
+ }
+ return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders };
+};
+
+export const isEmptyHeaders = (headers: HeadersLike) => {
+ for (const _ of iterateHeaders(headers)) return false;
+ return true;
+};
diff --git a/src/interactions/internal/parse.ts b/src/interactions/internal/parse.ts
new file mode 100644
index 000000000..5642d1a71
--- /dev/null
+++ b/src/interactions/internal/parse.ts
@@ -0,0 +1,73 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import type { FinalRequestOptions } from './request-options.js';
+import { Stream } from '../core/streaming.js';
+import { type BaseGeminiNextGenAPIClient } from '../client.js';
+import { formatRequestDetails, loggerFor } from './utils/log.js';
+
+export type APIResponseProps = {
+ response: Response;
+ options: FinalRequestOptions;
+ controller: AbortController;
+ requestLogID: string;
+ retryOfRequestLogID: string | undefined;
+ startTime: number;
+};
+
+export async function defaultParseResponse(
+ client: BaseGeminiNextGenAPIClient,
+ props: APIResponseProps,
+): Promise {
+ const { response, requestLogID, retryOfRequestLogID, startTime } = props;
+ const body = await (async () => {
+ if (props.options.stream) {
+ loggerFor(client).debug('response', response.status, response.url, response.headers, response.body);
+
+ // Note: there is an invariant here that isn't represented in the type system
+ // that if you set `stream: true` the response type must also be `Stream`
+
+ if (props.options.__streamClass) {
+ return props.options.__streamClass.fromSSEResponse(response, props.controller, client) as any;
+ }
+
+ return Stream.fromSSEResponse(response, props.controller, client) as any;
+ }
+
+ // fetch refuses to read the body when the status code is 204.
+ if (response.status === 204) {
+ return null as T;
+ }
+
+ if (props.options.__binaryResponse) {
+ return response as unknown as T;
+ }
+
+ const contentType = response.headers.get('content-type');
+ const mediaType = contentType?.split(';')[0]?.trim();
+ const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json');
+ if (isJSON) {
+ const json = await response.json();
+ return json as T;
+ }
+
+ const text = await response.text();
+ return text as unknown as T;
+ })();
+ loggerFor(client).debug(
+ `[${requestLogID}] response parsed`,
+ formatRequestDetails({
+ retryOfRequestLogID,
+ url: response.url,
+ status: response.status,
+ body,
+ durationMs: Date.now() - startTime,
+ }),
+ );
+ return body;
+}
diff --git a/src/interactions/internal/request-options.ts b/src/interactions/internal/request-options.ts
new file mode 100644
index 000000000..0416ecd50
--- /dev/null
+++ b/src/interactions/internal/request-options.ts
@@ -0,0 +1,99 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { NullableHeaders } from './headers.js';
+
+import type { BodyInit } from './builtin-types.js';
+import { Stream } from '../core/streaming.js';
+import type { HTTPMethod, MergedRequestInit } from './types.js';
+import { type HeadersLike } from './headers.js';
+
+export type FinalRequestOptions = RequestOptions & { method: HTTPMethod; path: string };
+
+export type RequestOptions = {
+ /**
+ * The HTTP method for the request (e.g., 'get', 'post', 'put', 'delete').
+ */
+ method?: HTTPMethod;
+
+ /**
+ * The URL path for the request.
+ *
+ * @example "/v1/foo"
+ */
+ path?: string;
+
+ /**
+ * Query parameters to include in the request URL.
+ */
+ query?: object | undefined | null;
+
+ /**
+ * The request body. Can be a string, JSON object, FormData, or other supported types.
+ */
+ body?: unknown;
+
+ /**
+ * HTTP headers to include with the request. Can be a Headers object, plain object, or array of tuples.
+ */
+ headers?: HeadersLike;
+
+ /**
+ * The maximum number of times that the client will retry a request in case of a
+ * temporary failure, like a network error or a 5XX error from the server.
+ *
+ * @default 2
+ */
+ maxRetries?: number;
+
+ stream?: boolean | undefined;
+
+ /**
+ * The maximum amount of time (in milliseconds) that the client should wait for a response
+ * from the server before timing out a single request.
+ *
+ * @unit milliseconds
+ */
+ timeout?: number;
+
+ /**
+ * Additional `RequestInit` options to be passed to the underlying `fetch` call.
+ * These options will be merged with the client's default fetch options.
+ */
+ fetchOptions?: MergedRequestInit;
+
+ /**
+ * An AbortSignal that can be used to cancel the request.
+ */
+ signal?: AbortSignal | undefined | null;
+
+ /**
+ * A unique key for this request to enable idempotency.
+ */
+ idempotencyKey?: string;
+
+ /**
+ * Override the default base URL for this specific request.
+ */
+ defaultBaseURL?: string | undefined;
+
+ __binaryResponse?: boolean | undefined;
+ __streamClass?: typeof Stream;
+};
+
+export type EncodedContent = { bodyHeaders: HeadersLike; body: BodyInit };
+export type RequestEncoder = (request: { headers: NullableHeaders; body: unknown }) => EncodedContent;
+
+export const FallbackEncoder: RequestEncoder = ({ headers, body }) => {
+ return {
+ bodyHeaders: {
+ 'content-type': 'application/json',
+ },
+ body: JSON.stringify(body),
+ };
+};
diff --git a/src/interactions/internal/shim-types.ts b/src/interactions/internal/shim-types.ts
new file mode 100644
index 000000000..ecb614bfe
--- /dev/null
+++ b/src/interactions/internal/shim-types.ts
@@ -0,0 +1,32 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+/**
+ * Shims for types that we can't always rely on being available globally.
+ *
+ * Note: these only exist at the type-level, there is no corresponding runtime
+ * version for any of these symbols.
+ */
+
+type NeverToAny = T extends never ? any : T;
+
+/** @ts-ignore */
+type _DOMReadableStream = globalThis.ReadableStream;
+
+/** @ts-ignore */
+type _NodeReadableStream = import('stream/web').ReadableStream;
+
+type _ConditionalNodeReadableStream =
+ typeof globalThis extends { ReadableStream: any } ? never : _NodeReadableStream;
+
+type _ReadableStream = NeverToAny<
+ | ([0] extends [1 & _DOMReadableStream] ? never : _DOMReadableStream)
+ | ([0] extends [1 & _ConditionalNodeReadableStream] ? never : _ConditionalNodeReadableStream)
+>;
+
+export type { _ReadableStream as ReadableStream };
diff --git a/src/interactions/internal/shims.ts b/src/interactions/internal/shims.ts
new file mode 100644
index 000000000..4f305833f
--- /dev/null
+++ b/src/interactions/internal/shims.ts
@@ -0,0 +1,113 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+/**
+ * This module provides internal shims and utility functions for environments where certain Node.js or global types may not be available.
+ *
+ * These are used to ensure we can provide a consistent behaviour between different JavaScript environments and good error
+ * messages in cases where an environment isn't fully supported.
+ */
+
+import type { Fetch } from './builtin-types.js';
+import type { ReadableStream } from './shim-types.js';
+
+export function getDefaultFetch(): Fetch {
+ if (typeof fetch !== 'undefined') {
+ return fetch as any;
+ }
+
+ throw new Error(
+ '`fetch` is not defined as a global; Either pass `fetch` to the client, `new GeminiNextGenAPIClient({ fetch })` or polyfill the global, `globalThis.fetch = fetch`',
+ );
+}
+
+type ReadableStreamArgs = ConstructorParameters;
+
+export function makeReadableStream(...args: ReadableStreamArgs): ReadableStream {
+ const ReadableStream = (globalThis as any).ReadableStream;
+ if (typeof ReadableStream === 'undefined') {
+ // Note: All of the platforms / runtimes we officially support already define
+ // `ReadableStream` as a global, so this should only ever be hit on unsupported runtimes.
+ throw new Error(
+ '`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`',
+ );
+ }
+
+ return new ReadableStream(...args);
+}
+
+export function ReadableStreamFrom(iterable: Iterable | AsyncIterable): ReadableStream {
+ let iter: AsyncIterator | Iterator =
+ Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
+
+ return makeReadableStream({
+ start() {},
+ async pull(controller: any) {
+ const { done, value } = await iter.next();
+ if (done) {
+ controller.close();
+ } else {
+ controller.enqueue(value);
+ }
+ },
+ async cancel() {
+ await iter.return?.();
+ },
+ });
+}
+
+/**
+ * Most browsers don't yet have async iterable support for ReadableStream,
+ * and Node has a very different way of reading bytes from its "ReadableStream".
+ *
+ * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490
+ */
+export function ReadableStreamToAsyncIterable(stream: any): AsyncIterableIterator {
+ if (stream[Symbol.asyncIterator]) return stream;
+
+ const reader = stream.getReader();
+ return {
+ async next() {
+ try {
+ const result = await reader.read();
+ if (result?.done) reader.releaseLock(); // release lock when stream becomes closed
+ return result;
+ } catch (e) {
+ reader.releaseLock(); // release lock when stream becomes errored
+ throw e;
+ }
+ },
+ async return() {
+ const cancelPromise = reader.cancel();
+ reader.releaseLock();
+ await cancelPromise;
+ return { done: true, value: undefined };
+ },
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ };
+}
+
+/**
+ * Cancels a ReadableStream we don't need to consume.
+ * See https://undici.nodejs.org/#/?id=garbage-collection
+ */
+export async function CancelReadableStream(stream: any): Promise {
+ if (stream === null || typeof stream !== 'object') return;
+
+ if (stream[Symbol.asyncIterator]) {
+ await stream[Symbol.asyncIterator]().return?.();
+ return;
+ }
+
+ const reader = stream.getReader();
+ const cancelPromise = reader.cancel();
+ reader.releaseLock();
+ await cancelPromise;
+}
diff --git a/src/interactions/internal/to-file.ts b/src/interactions/internal/to-file.ts
new file mode 100644
index 000000000..3218f6a17
--- /dev/null
+++ b/src/interactions/internal/to-file.ts
@@ -0,0 +1,160 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads.js';
+import type { FilePropertyBag } from './builtin-types.js';
+import { checkFileSupport } from './uploads.js';
+
+export type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView;
+
+/**
+ * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc.
+ * Don't add arrayBuffer here, node-fetch doesn't have it
+ */
+export interface BlobLike {
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */
+ readonly size: number;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */
+ readonly type: string;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */
+ text(): Promise;
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */
+ slice(start?: number, end?: number): BlobLike;
+}
+
+/**
+ * This check adds the arrayBuffer() method type because it is available and used at runtime
+ */
+const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise