Interacciones de transmisión
Cuando creas una interacción, puedes configurar stream: true para transmitir la respuesta de forma incremental con eventos enviados por el servidor (SSE).
Python
from google import genai
client = genai.Client()
stream = client.interactions.create(
model="gemini-3-flash-preview",
input="Count to from 1 to 25.",
stream=True,
)
for event in stream:
if event.event_type == "step.delta":
if event.delta.type == "text":
print(event.delta.text, end="", flush=True)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const stream = await client.interactions.create({
model: "gemini-3-flash-preview",
input: "Count to from 1 to 25.",
stream: true,
});
for await (const event of stream) {
if (event.event_type === "step.delta") {
if (event.delta.type === "text") {
process.stdout.write(event.delta.text);
}
}
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
--no-buffer \
-d '{
"model": "gemini-3-flash-preview",
"input": "Count to from 1 to 25.",
"stream": true
}'
event: interaction.created
data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.created"}
event: interaction.status_update
data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}
event: step.start
data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"}
event: step.delta
data: {"index":0,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}
event: step.stop
data: {"index":0,"event_type":"step.stop"}
event: step.start
data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"}
event: step.delta
data: {"index":1,"delta":{"text":"1, 2, 3, 4, 5, 6, ","type":"text"},"event_type":"step.delta"}
event: step.delta
data: {"index":1,"delta":{"text":"7, 8, 9, 10, 11, 12, 13,","type":"text"},"event_type":"step.delta"}
...
event: step.stop
data: {"index":1,"event_type":"step.stop"}
event: interaction.completed
data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":346,"total_input_tokens":11,"input_tokens_by_modality":[{"modality":"text","tokens":11}],"total_cached_tokens":0,"total_output_tokens":90,"total_tool_use_tokens":0,"total_thought_tokens":245},"created":"2026-05-12T18:44:51Z","updated":"2026-05-12T18:44:51Z","service_tier":"standard","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.completed"}
event: done
data: [DONE]
Tipos de eventos
Cada evento enviado por el servidor incluye un event_type con nombre y datos JSON asociados. La API de Interactions usa un modelo de transmisión simétrico en el que todo el contenido (texto, llamadas a herramientas y razonamiento) fluye a través de un evento basado en pasos coherente.
Cada transmisión sigue este flujo de eventos:
interaction.created: Se crea la interacción y se incluyen metadatos (ID, modelo y estado).- Una serie de pasos, cada uno de los cuales consta de lo siguiente:
- Un evento
step.start, que indica el tipo de paso (p.ej.,model_output,thought,function_call). - Uno o más eventos
step.deltacon datos incrementales para ese paso. - Un evento
step.stopque marca el paso como completado.
- Un evento
- Un evento
interaction.completedcon estadísticasusagefinales.
Cuando configuras stream: false, la API muestra un solo objeto interaction con un array steps. Cada elemento de steps es la versión completamente ensamblada de un ciclo step.start → step.delta(s) → step.stop.
interaction.created
Se envía cuando se crea la interacción por primera vez. Contiene el ID de la interacción, el modelo y el estado inicial.
event: interaction.created
data: {"interaction": {"id": "...", "model": "gemini-3-flash-preview", "status": "in_progress", "object": "interaction"}, "event_type": "interaction.created"}
interaction.status_update
Indica una transición de estado a nivel de la interacción. Puede aparecer entre los pasos.
event: interaction.status_update
data: {"interaction_id": "...", "status": "in_progress", "event_type": "interaction.status_update"}
step.start
Marca el comienzo de un nuevo paso. Contiene el type y el index del paso. El tipo de paso determina qué tipos de delta se deben esperar y cómo aparece el paso en una respuesta que no es de transmisión:
| Tipo de paso | Tipos de delta esperados | Descripción |
|---|---|---|
model_output |
text, image, audio |
El contenido de la respuesta final del modelo. |
thought |
thought_signature, thought_summary |
Razonamiento de cadena de pensamientos. summary solo está presente cuando se habilitan thinking_summaries. |
function_call |
arguments_delta |
Una solicitud para que el cliente ejecute una función. Establece el estado de la interacción en requires_action. |
| Herramientas del servidor | Varía según la herramienta | Herramientas ejecutadas por la API (p.ej., google_search_call, google_search_result, code_execution_call, code_execution_result). |
Consulta la referencia de la API de Interactions para obtener la lista completa.
event: step.start
data: {"index": 0, "step": {"type": "model_output"}, "event_type": "step.start"}
Para las llamadas a funciones, el paso incluye el nombre de la función, el ID y los argumentos vacíos {}.
event: step.start
data: {"index": 0, "step": {"type": "function_call", "id":"un6k8t18", "name": "get_weather", "arguments":{}}, "event_type": "step.start"}
step.delta
Datos incrementales para el paso actual. El objeto delta contiene un campo type que determina su forma.
Ejemplos:
text: Token de texto incremental de un paso model_output:
event: step.delta
data: {"index": 0, "delta": {"type": "text", "text": "Hello, my name is Phil"}, "event_type": "step.delta"}
event: step.delta
data: {"index": 0, "delta": {"type": "text", "text": ", and I live in Germany." }, "event_type": "step.delta"}
image: Datos de imagen codificados en base64 de un paso model_output:
event: step.delta
data: {"index": 0, "delta": {"type": "image", "mime_type": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCg..."}, "event_type": "step.delta"}
thought_summary: Contenido de resumen de razonamiento de un paso thought:
event: step.delta
data: {"index": 0, "delta": {"type": "thought_summary", "content": {"type": "text", "text": "I need to find the GCD..."}}, "event_type": "step.delta"}
arguments_delta: Cadena JSON (parcial) para los argumentos de la llamada a función. Se debe acumular en los deltas:
event: step.delta
data: {"index": 0, "delta": {"type": "arguments_delta", "arguments": "{\"location\": \"San Francisco, CA\"}"}, "event_type": "step.delta"}
Estos son algunos de los tipos de delta más comunes. Para obtener la lista completa de todos los tipos de delta, consulta la referencia de la API de Interactions.
step.stop
Marca el final de un paso. Contiene el index del paso.
event: step.stop
data: {"index": 0, "event_type": "step.stop"}
interaction.completed
Se envía cuando finaliza la interacción. Contiene el objeto de interacción final con estadísticas usage. En el modo que no es de transmisión, este es el objeto de respuesta de nivel superior. No incluye steps en la respuesta.
event: interaction.completed
data: {"interaction": {"id": "v1_abc123", "status": "completed", "usage": {"total_input_tokens": 7, "total_output_tokens": 12, "total_tokens": 19}}, "event_type": "interaction.completed"}
error
Se envía cuando se produce un error durante la interacción. Contiene un objeto de error con un mensaje y un código.
event: error
data: {"error":{"message":"Deadline expired before operation could complete.","code":"gateway_timeout"},"event_type":"error"}
Transmisión con herramientas
La API de Interactions admite la transmisión con herramientas del cliente (llamada a función) y herramientas del servidor (Búsqueda de Google, ejecución de código, etcétera) en una sola solicitud. Durante la transmisión, las invocaciones de herramientas aparecen como pasos tipados en el flujo de eventos. Para las llamadas a funciones, el evento step.start entrega el nombre de la función y los eventos step.delta transmiten los argumentos como cadenas JSON (arguments_delta). Debes acumular estos deltas para obtener los argumentos completos. La API ejecuta automáticamente las herramientas del servidor, como la Búsqueda de Google, y produce pasos google_search_call y google_search_result.
Transmisión con llamada a función
Para realizar la llamada a función con transmisión, el cliente debe controlar una conversación de varios turnos: 1. Turno 1 (solicitud de función): Llama a interactions.create con stream: true y tus tools definidas. La API transmitirá un paso function_call. Debes acumular las cadenas JSON de argumentos incrementales (arguments_delta) de los eventos step.delta hasta que la interacción se complete con el estado requires_action.
2. Turno 2 (envío del resultado): Vuelve a llamar a interactions.create, pasa el previous_interaction_id (que coincide con el ID de la primera interacción) y envía un bloque function_result dentro del array input. Esto reanuda la transmisión, lo que permite que el modelo genere su respuesta final.
Python
from google import genai
client = genai.Client()
weather_tool = {
"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"]
}
}
# Turn 1: Request function call
stream = client.interactions.create(
model="gemini-3-flash-preview",
tools=[weather_tool],
input="What is the weather in Paris right now?",
stream=True,
)
first_interaction_id = None
func_call_id = None
func_call_name = None
func_args_accumulated = ""
for event in stream:
if event.event_type == "interaction.created":
first_interaction_id = event.interaction.id
elif event.event_type == "step.start":
step = event.step
if step.type == "function_call":
func_call_id = step.id
func_call_name = step.name
elif event.event_type == "step.delta":
if event.delta.type == "arguments_delta":
func_args_accumulated += event.delta.arguments
# Turn 2: Execute tool and send the result back to resume stream
if func_call_id:
# Execute weather_tool using accumulated arguments
# args = json.loads(func_args_accumulated)
dummy_result = {
"content": [{"type": "text", "text": '{"weather": "Sunny and 22°C"}'}]
}
stream2 = client.interactions.create(
model="gemini-3-flash-preview",
previous_interaction_id=first_interaction_id,
input=[{
"type": "function_result",
"name": func_call_name,
"call_id": func_call_id,
"result": dummy_result
}],
stream=True,
)
for event in stream2:
if event.event_type == "step.delta":
if event.delta.type == "text":
print(event.delta.text, end="", flush=True)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const weatherTool = {
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"]
}
};
// Turn 1: Request function call
const stream = await client.interactions.create({
model: "gemini-3-flash-preview",
tools: [weatherTool],
input: "What is the weather in Paris right now?",
stream: true,
});
let firstInteractionId = null;
let funcCallId = null;
let funcCallName = null;
let funcArgsAccumulated = "";
for await (const event of stream) {
if (event.event_type === "interaction.created") {
firstInteractionId = event.interaction.id;
} else if (event.event_type === "step.start") {
const step = event.step;
if (step.type === "function_call") {
funcCallId = step.id;
funcCallName = step.name;
}
} else if (event.event_type === "step.delta") {
if (event.delta.type === "arguments_delta") {
funcArgsAccumulated += event.delta.arguments;
}
}
}
// Turn 2: Execute tool and send the result back to resume stream
if (funcCallId && firstInteractionId && funcCallName) {
// const args = JSON.parse(funcArgsAccumulated);
const dummyResult = {
content: [{ type: "text", text: '{"weather": "Sunny and 22°C"}' }]
};
const stream2 = await client.interactions.create({
model: "gemini-3-flash-preview",
previous_interaction_id: firstInteractionId,
input: [{
type: "function_result",
name: funcCallName,
call_id: funcCallId,
result: dummyResult
}],
stream: true,
});
for await (const event of stream2) {
if (event.event_type === "step.delta") {
if (event.delta.type === "text") {
process.stdout.write(event.delta.text);
}
}
}
}
REST
Turno 1: Solicitar llamada a función
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
--no-buffer \
-d '{
"model": "gemini-3-flash-preview",
"input": "What is the weather in Paris right now?",
"stream": true,
"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"]
}
}
]
}'
Turno 2: Envía el resultado de la función con previous_interaction_id y call_id del turno 1
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
--no-buffer \
-d '{
"model": "gemini-3-flash-preview",
"previous_interaction_id": "v1_ChdGUVFJYXBXVUdLVEF4TjhQ...",
"stream": true,
"input": [
{
"type": "function_result",
"name": "get_weather",
"call_id": "CALL_ID",
"result": {
"content": [
{
"type": "text",
"text": "{\"weather\": \"Sunny and 22°C\"}"
}
]
}
}
]
}'
Transmisión con varias herramientas
En el siguiente ejemplo, se usan una herramienta function y google_search en una solicitud:
Python
from google import genai
client = genai.Client()
tools = [
{"type": "google_search"},
{
"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"]
}
}
]
stream = client.interactions.create(
model="gemini-3-flash-preview",
tools=tools,
input="Search what it the largest mountain in Europe and what the weather is there right now?",
stream=True,
)
for event in stream:
if event.event_type == "step.start":
step = event.step
print(f"\n--- Step {event.index}: {step.type} ---")
# Show details for tool steps
if step.type == "google_search_call":
print(f" Search ID: {step.id}")
elif step.type == "google_search_result":
print(f" Result for: {step.call_id}")
elif step.type == "function_call":
print(f" Function: {step.name}({step.arguments})")
elif event.event_type == "step.delta":
if event.delta.type == "text":
print(event.delta.text, end="", flush=True)
elif event.delta.type == "google_search_call":
print(f" Queries: {event.delta.arguments}")
elif event.delta.type == "arguments_delta":
print(f" Args chunk: {event.delta.arguments}", end="", flush=True)
elif event.event_type == "interaction.completed":
print(f"\n\nStatus: {event.interaction.status}")
if event.interaction.status == "requires_action":
print("Action required: provide function call results to continue.")
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const tools = [
{ type: "google_search" },
{
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"]
}
}
];
const stream = await client.interactions.create({
model: "gemini-3-flash-preview",
tools: tools,
input: "Search what it the largest mountain in Europe and what the weather is there right now?",
stream: true,
});
for await (const event of stream) {
if (event.event_type === "step.start") {
const step = event.step;
console.log(`\n--- Step ${event.index}: ${step.type} ---`);
// Show details for tool steps
if (step.type === "google_search_call") {
console.log(` Search ID: ${step.id}`);
} else if (step.type === "google_search_result") {
console.log(` Result for: ${step.call_id}`);
} else if (step.type === "function_call") {
console.log(` Function: ${step.name}(${JSON.stringify(step.arguments)})`);
}
} else if (event.event_type === "step.delta") {
if (event.delta.type === "text") {
process.stdout.write(event.delta.text);
} else if (event.delta.type === "google_search_call") {
console.log(` Queries: ${JSON.stringify(event.delta.arguments?.queries)}`);
} else if (event.step.type === "google_search_result") {
console.log(` Result for: ${event.step.call_id}`);
} else if (event.delta.type === "arguments_delta") {
process.stdout.write(` Args chunk: ${event.delta.arguments}`);
}
} else if (event.event_type === "interaction.completed") {
console.log(`\n\nStatus: ${event.interaction.status}`);
if (event.interaction.status === "requires_action") {
console.log("Action required: provide function call results to continue.");
}
}
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
--no-buffer \
-d '{
"model": "gemini-3-flash-preview",
"input": "Search what it the largest mountain in Europe and what the weather is there right now?",
"stream": true,
"tools": [
{ "type": "google_search" },
{
"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"]
}
}
]
}'
event: interaction.created
data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.created"}
event: interaction.status_update
data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}
event: step.start
data: {"index":0,"step":{"id":"mkutnkgn","signature":"","type":"google_search_call"},"event_type":"step.start"}
event: step.delta
data: {"index":0,"delta":{"signature":"...","type":"google_search_call","arguments":{"queries":["largest mountain in Europe"]}},"event_type":"step.delta"}
event: step.stop
data: {"index":0,"event_type":"step.stop"}
event: step.start
data: {"index":1,"step":{"call_id":"mkutnkgn","signature":"","type":"google_search_result"},"event_type":"step.start"}
event: step.delta
data: {"index":1,"delta":{"signature":"...","type":"google_search_result","is_error":false},"event_type":"step.delta"}
event: step.stop
data: {"index":1,"event_type":"step.stop"}
event: step.start
data: {"index":2,"step":{"type":"thought"},"event_type":"step.start"}
event: step.delta
data: {"index":2,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}
event: step.stop
data: {"index":2,"event_type":"step.stop"}
event: step.start
data: {"index":3,"step":{"id":"ktr5aysg","type":"function_call","name":"get_weather","arguments":{}},"event_type":"step.start"}
event: step.delta
data: {"index":3,"delta":{"arguments":"{\"location\":\"Mount Elbrus, Russia\"}","type":"arguments_delta"},"event_type":"step.delta"}
event: step.stop
data: {"index":3,"event_type":"step.stop"}
event: interaction.completed
data: {"interaction":{"id":"v1_...","status":"requires_action","usage":{"total_tokens":299,"total_input_tokens":138,"input_tokens_by_modality":[{"modality":"text","tokens":138}],"total_cached_tokens":0,"total_output_tokens":20,"total_tool_use_tokens":0,"total_thought_tokens":141},"created":"2026-05-12T17:24:26Z","updated":"2026-05-12T17:24:26Z","service_tier":"standard","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.completed"}
event: done
data: [DONE]
Transmisión con razonamiento
Cuando el modelo usa el razonamiento, recibirás pasos thought con dos tipos de delta distintos: thought_summary (contenido de resumen de texto o imagen incremental) y thought_signature (una representación encriptada del razonamiento interno del modelo, que se envía como el último delta antes de step.stop). Si se habilita thinking_summaries, los deltas thought_summary transmiten un resumen del razonamiento del modelo. Para obtener más detalles sobre el razonamiento, consulta la guía de razonamiento.
Python
from google import genai
client = genai.Client()
stream = client.interactions.create(
model="gemini-3-flash-preview",
input="What is the greatest common divisor of 1071 and 462?",
generation_config={
"thinking_summaries": "auto"
},
stream=True,
)
for event in stream:
if event.event_type == "step.start":
print(f"\n--- Step: {event.step.type} ---")
elif event.event_type == "step.delta":
if event.delta.type == "thought_summary":
if event.delta.content.type == "text":
print(event.delta.content.text, end="", flush=True)
elif event.delta.type == "text":
print(event.delta.text, end="", flush=True)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const stream = await client.interactions.create({
model: "gemini-3-flash-preview",
input: "What is the greatest common divisor of 1071 and 462?",
generation_config: {
thinking_summaries: "auto",
},
stream: true,
});
for await (const event of stream) {
if (event.event_type === "step.start") {
console.log(`\n--- Step: ${event.step.type} ---`);
} else if (event.event_type === "step.delta") {
if (event.delta.type === "thought_summary") {
if (event.delta.content.type === "text") {
process.stdout.write(event.delta.content.text);
}
} else if (event.delta.type === "text") {
process.stdout.write(event.delta.text);
}
}
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
--no-buffer \
-d '{
"model": "gemini-3-flash-preview",
"input": "What is the greatest common divisor of 1071 and 462?",
"stream": true,
"generation_config": {
"thinking_summaries": "auto"
}
}'
event: interaction.created
data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.created"}
event: interaction.status_update
data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}
event: step.start
data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"}
event: step.delta
data: {"index":0,"delta":{"content":{"text":"**Implementing Euclidean Algorithm**\n\nI've just worked through a detailed example applying the Euclidean algorithm to find the GCD of 1071 and 462, confirming its step-by-step nature. The calculations went smoothly, tracking the remainders until zero. My focus is now solidifying the implementation logic, ensuring accuracy and considering potential edge cases. I'll translate this example into code.\n\n\n","type":"text"},"type":"thought_summary"},"event_type":"step.delta"}
event: step.delta
data: {"index":0,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}
event: step.stop
data: {"index":0,"event_type":"step.stop"}
event: step.start
data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"}
...
Transmisión con agentes
La API de Interactions admite agentes como Deep Research. Los agentes usan background=True y muestran resultados de forma asíncrona, pero también puedes transmitir interacciones de agentes para recibir actualizaciones de progreso y pasos intermedios a medida que ocurren. Para obtener más detalles, consulta la guía de Deep Research.
Python
from google import genai
client = genai.Client()
stream = client.interactions.create(
agent="deep-research-preview-04-2026",
input="Research the latest advances in quantum computing.",
stream=True,
background=True,
agent_config={
"type": "deep-research",
"thinking_summaries": "auto"
}
)
for event in stream:
if event.event_type == "step.start":
print(f"\n--- Step: {event.step.type} ---")
elif event.event_type == "step.delta":
if event.delta.type == "text":
print(event.delta.text, end="", flush=True)
elif event.delta.type == "thought_summary":
if event.delta.content.type == "text":
print(event.delta.content.text, end="", flush=True)
elif event.event_type == "interaction.completed":
print(f"\n\nTotal Tokens: {event.interaction.usage.total_tokens}")
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const stream = await client.interactions.create({
agent: "deep-research-preview-04-2026",
input: "Research the latest advances in quantum computing.",
stream: true,
background: true,
agent_config: {
type: "deep-research",
thinking_summaries: "auto"
}
});
for await (const event of stream) {
if (event.event_type === "step.start") {
console.log(`\n--- Step: ${event.step.type} ---`);
} else if (event.event_type === "step.delta") {
if (event.delta.type === "text") {
process.stdout.write(event.delta.text);
} else if (event.delta.type === "thought_summary") {
if (event.delta.content.type === "text") {
process.stdout.write(event.delta.content.text);
}
}
} else if (event.event_type === "interaction.completed") {
console.log(`\n\nTotal Tokens: ${event.interaction.usage.total_tokens}`);
}
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
--no-buffer \
-d '{
"agent": "deep-research-preview-04-2026",
"input": "Research the latest advances in quantum computing.",
"stream": true,
"background": true,
"agent_config": {
"type": "deep-research",
"thinking_summaries": "auto"
}
}'
event: interaction.created
data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","agent":"deep-research-preview-04-2026"},"event_type":"interaction.created"}
event: interaction.status_update
data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}
event: step.start
data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"}
event: step.delta
data: {"index":0,"delta":{"content":{"text":"***Generating research plan***\n\nTo best answer your request, I'm starting by constructing a comprehensive research plan. This will outline the key areas I need to investigate and the strategy I'll use to connect them."},"type":"thought_summary"},"event_type":"step.delta"}
... (additional thought steps) ...
event: step.stop
data: {"index":0,"event_type":"step.stop"}
event: step.start
data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"}
event: step.delta
data: {"index":1,"delta":{"text":"# The Quantum Inflection Point: Exhaustive Analysis of Hardware, Algorithms, and Market Dynamics in 2026\n\n## Executive Summary\n\n..."},"event_type":"step.delta"}
event: step.stop
data: {"index":1,"event_type":"step.stop"}
event: interaction.completed
data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":1117031,"total_input_tokens":428865,"total_output_tokens":22294,"total_thought_tokens":26213},"created":"2026-05-12T17:24:27Z","updated":"2026-05-12T17:24:27Z","object":"interaction","agent":"deep-research-preview-04-2026"},"event_type":"interaction.completed"}
event: done
data: [DONE]
Transmisión de generación de imágenes
La API de Interactions admite la transmisión de varias modalidades de salida de forma simultánea. Si solicitas text y image en response_format, puedes recibir texto intercalado y generar imágenes en la misma transmisión.
En el siguiente ejemplo, se usa gemini-3.1-flash-image-preview (Nano Banana 2) para buscar información y generar una historia con ilustraciones intercaladas.
Python
from google import genai
client = genai.Client()
stream = client.interactions.create(
model="gemini-3.1-flash-image-preview",
tools=[{"type": "google_search", "search_types": ["web_search", "image_search"]}],
input="Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",
response_format=[
{"type": "text"},
{"type": "image"}
],
stream=True,
)
for event in stream:
if event.event_type == "step.delta":
if event.delta.type == "text":
print(event.delta.text, end="", flush=True)
elif event.delta.type == "image":
print(f"\n[Image chunk: {len(event.delta.data)} bytes]", end="", flush=True)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const stream = await client.interactions.create({
model: "gemini-3.1-flash-image-preview",
tools: [{ type: "google_search", search_types: ["web_search", "image_search"] }],
input: "Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",
response_format: [
{ type: "text" },
{ type: "image" }
],
stream: true,
});
for await (const event of stream) {
if (event.event_type === "step.delta") {
if (event.delta.type === "text") {
process.stdout.write(event.delta.text);
} else if (event.delta.type === "image") {
console.log(`\n[Image chunk: ${event.delta.data.length} bytes]`);
}
}
}
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-H "Api-Revision: 2026-05-20" \
--no-buffer \
-d '{
"model": "gemini-3.1-flash-image-preview",
"input": "Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",
"stream": true,
"tools": [
{ "type": "google_search",
"search_types": ["web_search", "image_search"]
}
],
"generation_config": {
"thinking_summaries": "auto"
},
"response_format": [
{ "type": "text" }, { "type": "image"}
]
}'
event: interaction.created
data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3.1-flash-image-preview"},"event_type":"interaction.created"}
event: interaction.status_update
data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}
event: step.start
data: {"index":0,"step":{"type":"model_output"},"event_type":"step.start"}
event: step.delta
data: {"index":0,"delta":{"text":"Here is a short illustrated story about the Colosseum...\n\n### Part 1: The New Flavian Amphitheater\n\n...","type":"text"},"event_type":"step.delta"}
...
event: step.stop
data: {"index":0,"event_type":"step.stop"}
event: step.start
data: {"index":1,"step":{"type":"thought"},"event_type":"step.start"}
event: step.delta
data: {"index":1,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}
event: step.stop
data: {"index":1,"event_type":"step.stop"}
event: step.start
data: {"index":2,"step":{"type":"model_output"},"event_type":"step.start"}
event: step.delta
data: {"index":2,"delta":{"mime_type":"image/jpeg","data":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCg...","type":"image"},"event_type":"step.delta"}
event: step.delta
data: {"index":2,"delta":{"text":"### Part 2: The Hypogeum and the Wait\n\n...","type":"text"},"event_type":"step.delta"}
...
event: step.stop
data: {"index":2,"event_type":"step.stop"}
event: step.start
data: {"index":3,"step":{"type":"thought"},"event_type":"step.start"}
event: step.delta
data: {"index":3,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}
event: step.stop
data: {"index":3,"event_type":"step.stop"}
event: step.start
data: {"index":4,"step":{"type":"model_output"},"event_type":"step.start"}
event: step.delta
data: {"index":4,"delta":{"mime_type":"image/jpeg","data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...","type":"image"},"event_type":"step.delta"}
event: step.delta
data: {"index":4,"delta":{"text":"### Part 3: The Moment of Spectacle\n\n...","type":"text"},"event_type":"step.delta"}
...
event: step.stop
data: {"index":4,"event_type":"step.stop"}
event: interaction.completed
data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":6128,"total_input_tokens":29,"total_output_tokens":6099,"output_tokens_by_modality":[{"modality":"image","tokens":4480}]}},"event_type":"interaction.completed"}
event: done
data: [DONE]
Cómo controlar eventos desconocidos
De acuerdo con la política de control de versiones de la API, es posible que se agreguen nuevos tipos de eventos y tipos de delta con el tiempo. Tu código debe controlar los tipos de eventos desconocidos de forma correcta: registra y omite los eventos que no reconozcas en lugar de generar un error.
¿Qué sigue?
- Obtén más información sobre la API de Interactions.
- Explora la llamada a función con herramientas.
- Obtén información sobre el razonamiento para mejorar el razonamiento.
- Prueba el agente de Deep Research para tareas de larga duración.
- Consulta la referencia de la API de Interactions para obtener todos los tipos de eventos y tipos de delta.