---
title: Previsualiza respuestas con deltas de eventos
url: https://platform.claude.com/docs/es/managed-agents/event-deltas
description: Renderiza el texto de respuesta del agente como una vista previa en vivo mientras el modelo aún lo está generando.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

De forma predeterminada, el texto de respuesta del agente llega al [flujo de eventos de la sesión](https://platform.claude.com/docs/es/managed-agents/events-and-streaming) como eventos `agent.message` almacenados en búfer. Cada uno se emite solo después de que finaliza la solicitud al modelo que lo produjo. Los "event deltas" (deltas de eventos) te permiten renderizar ese texto de forma incremental, como una vista previa en vivo, mientras el modelo aún lo está generando.

Las vistas previas son una ayuda de visualización de mejor esfuerzo, y el `agent.message` almacenado en búfer es siempre el registro autoritativo. Un cliente que ignora las vistas previas sigue recibiendo un flujo completo y correcto.

## Activa las vistas previas

Las vistas previas se activan por conexión de flujo. Agrega el parámetro de consulta `event_deltas[]` al flujo que estás leyendo y repítelo una vez por cada tipo de evento que quieras previsualizar. Los valores aceptados son `agent.message` y `agent.thinking`. Cualquier otro valor devuelve un error 400, al igual que una solicitud con más de 100 valores.

Ambos endpoints de flujo aceptan el parámetro:

* **Flujo a nivel de sesión:** `GET /v1/sessions/{session_id}/events/stream`
* **Flujo de hilo de sesión:** `GET /v1/sessions/{session_id}/threads/{thread_id}/stream`

Las vistas previas de un subagente aparecen en [el propio flujo de hilo de ese subagente](https://platform.claude.com/docs/es/managed-agents/event-deltas#preview-session-thread-events).

`[]` es un patrón glob de shell, así que pon la URL entre comillas siempre que construyas la solicitud en un shell. Los ejemplos codifican los corchetes con codificación porcentual como `%5B%5D`, lo cual también funciona.

### Eventos de vista previa

Cuando comienza un evento previsualizado, el flujo emite un `event_start` que lleva el tipo y el `id` del evento próximo:

```json
{
  "type": "event_start",
  "event": {
    "type": "agent.message",
    "id": "sevt_01abc..."
  }
}
```

Para `agent.message`, al inicio le siguen eventos `event_delta` que llevan texto incremental. Cada delta nombra el evento que extiende en `event_id` y el bloque de contenido que extiende en `delta.index`:

```json
{
  "type": "event_delta",
  "event_id": "sevt_01abc...",
  "delta": {
    "type": "content_delta",
    "index": 0,
    "content": {
      "type": "text",
      "text": "Here is the summary"
    }
  }
}
```

Para `agent.thinking`, solo se emite el `event_start`, como señal de que ha comenzado un bloque de pensamiento. No le siguen eventos `event_delta`. El evento `agent.thinking` almacenado en búfer que concluye la vista previa es una señal de progreso y no lleva contenido de pensamiento.

A diferencia de los eventos persistidos, `event_start` y `event_delta` no tienen `id` ni `processed_at` propios. El único identificador que llevan es el `id` del evento que previsualizan. Sus cadenas de tipo también son la excepción a la convención de nomenclatura `{domain}.{action}` de los eventos persistidos.

<Note>
  Los deltas de eventos usan un formato de transmisión diferente al de [Streaming de mensajes](https://platform.claude.com/docs/es/build-with-claude/streaming), y la diferencia es intencional. Un `agent.message` previsualizado recibe un único `event_start` seguido solo de eventos `event_delta`. No hay eventos de inicio o fin por bloque de contenido ni un evento de fin para el propio evento previsualizado. El tipo de delta es `content_delta`, no `content_block_delta`. El código acumulador escrito para la Messages API no se puede reutilizar sin cambios.
</Note>

## Acumula y concilia

Cada SDK que admite deltas de eventos incluye un [asistente acumulador](https://platform.claude.com/docs/es/managed-agents/event-deltas#sdk-accumulator-helpers) que gestiona la contabilidad de `index` por ti. El patrón manual de esta sección funciona en todos los lenguajes cuando necesitas una contabilidad personalizada. Aplícalo a los tipos de eventos generados.

En el patrón manual, guarda el texto de vista previa en un mapa temporal indexado por `(event_id, index)` y trata el evento almacenado en búfer como el registro. Concilia ambos por cada solicitud al modelo.

Un turno se abre con un único evento `session.status_running`. En un turno que se completa normalmente, cada solicitud al modelo produce entonces estos eventos, en orden:

1. `span.model_request_start`
2. `event_start`
3. Los eventos `event_delta`
4. El `agent.message` almacenado en búfer
5. [`span.model_request_end`](https://platform.claude.com/docs/es/managed-agents/reference#event-types) (en la pestaña Span events)

En la transmisión, esta es la parte previsualizada de esa secuencia, intercalada con los demás eventos almacenados en búfer de la conexión:

```text wrap
event_start     {"event": {"type": "agent.message", "id": "sevt_01abc..."}}
event_delta     {"event_id": "sevt_01abc...", "delta": {"type": "content_delta", "index": 0, "content": {"type": "text", "text": "..."}}}
...
agent.message   {"id": "sevt_01abc...", "content": [...]}
```

La línea `event_delta` se repite una vez por cada fragmento de texto. Procesa cada evento a medida que llega:

1. En `event_start`, anota el `id` anunciado. Los identificadores siempre coinciden: `event_start.event.id`, cada `event_delta.event_id` y el `id` del `agent.message` almacenado en búfer son el mismo valor.
2. En cada `event_delta`, agrega `delta.content.text` a la entrada en `(event_id, delta.index)` y renderiza el texto acumulado. El primer delta para un `index` crea esa entrada.
3. Cuando llegue el `agent.message` almacenado en búfer, emparéjalo por `id`, descarta la vista previa acumulada y renderiza en su lugar el contenido del mensaje.
4. En `span.model_request_end`, cierra cualquier vista previa que no haya sido conciliada por su evento almacenado en búfer. No llegarán más deltas para ella. Si el turno produce un error o se interrumpe, es posible que el evento almacenado en búfer nunca llegue, pero `span.model_request_end` sí llega.

El patrón se basa en dos garantías:

* Concatenar los deltas de una vista previa en orden de llegada, indexados por `(event_id, index)`, da un prefijo de `content[index].text` en el evento almacenado en búfer. No es necesariamente el texto completo, porque los deltas podrían [descartarse bajo carga](https://platform.claude.com/docs/es/managed-agents/event-deltas#limitations).
* Una conexión emite como máximo un `event_start` por `event_id`, y el evento almacenado en búfer es lo último que esa conexión entrega para ese `id`.

### Asistentes acumuladores del SDK

El asistente de cada SDK gestiona la contabilidad de `index` (csharp, go: `Index`). Los asistentes de Go, Java, Ruby y C# también indexan la vista previa acumulada por el `id` (csharp, go: `ID`) del evento. Con los asistentes de Python, TypeScript y PHP, mantén ese mapa tú mismo e incorpora cada delta en la entrada correspondiente a su `id` (csharp, go: `ID`).

Los siguientes ejemplos activan las vistas previas de `agent.message` y las concilian con el evento almacenado en búfer:

<CodeGroup exclude="shell:cURL, shell:CLI">
  <CodeGroupItem language="cURL">
    Este flujo de trabajo necesita más lógica que un solo comando de shell. Usa el [SDK de Claude](https://platform.claude.com/docs/es/cli-sdks-libraries/overview) para ejecutarlo.
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    Este flujo de trabajo necesita más lógica que un solo comando de shell. Usa el [SDK de Claude](https://platform.claude.com/docs/es/cli-sdks-libraries/overview) para ejecutarlo.
  </CodeGroupItem>

  ```python Python
  # Instantáneas de vista previa, indexadas por id de evento. accumulate_managed_agents_event integra cada
  # event_start / event_delta en una instantánea de agent.message; el
  # agent.message almacenado en búfer la reemplaza.
  previews: dict[str, BetaManagedAgentsAgentMessageEvent] = {}

  # Activa las vistas previas de agent.message en esta conexión
  with client.beta.sessions.events.stream(
      session.id, event_deltas=["agent.message"]
  ) as stream:
      client.beta.sessions.events.send(
          session.id,
          events=[
              {
                  "type": "user.message",
                  "content": [
                      {"type": "text", "text": "Describe the repo in one sentence."}
                  ],
              },
          ],
      )

      for event in stream:
          match event.type:
              case "event_start":
                  snapshot = accumulate_managed_agents_event(None, event)
                  if snapshot is not None:
                      previews[event.event.id] = snapshot
                  print(f"event_start             {event.event.type} {event.event.id}")
              case "event_delta":
                  preview = accumulate_managed_agents_event(
                      previews.get(event.event_id), event
                  )
                  if preview is not None:
                      previews[event.event_id] = preview
                      text = "".join(block.text for block in preview.content)
                      print(f"event_delta             preview: {text!r}")
              case "agent.message":
                  # El evento en búfer es el registro: reemplaza y cierra la vista previa
                  preview = accumulate_managed_agents_event(
                      previews.pop(event.id, None), event
                  )
                  text = "".join(block.text for block in preview.content)
                  print(f"agent.message           {event.id} {text!r}")
              case "span.model_request_end":
                  # No llegarán más deltas. Cierra cualquier vista previa cuyo
                  # evento en búfer nunca llegó.
                  for event_id in previews:
                      print(f"span.model_request_end  closing preview for {event_id}")
                  previews.clear()
              case "session.status_idle":
                  break
  ```

  ```typescript TypeScript
  // Instantáneas de vista previa, indexadas por id de evento. `accumulateManagedAgentsEvent`
  // combina las vistas previas event_start / event_delta en una instantánea agent.message.
  const previews = new Map<string, BetaManagedAgentsAgentMessageEvent>();

  // Activa las vistas previas de agent.message solo para esta conexión
  const stream = await client.beta.sessions.events.stream(session.id, {
    event_deltas: ["agent.message"]
  });
  await client.beta.sessions.events.send(session.id, {
    events: [
      {
        type: "user.message",
        content: [{ type: "text", text: "Summarize the repo README" }]
      }
    ]
  });

  deltas: for await (const event of stream) {
    switch (event.type) {
      case "event_start": {
        // 1. Anota el id anunciado y abre la instantánea. Los deltas y el
        //    evento en búfer llevan el mismo id.
        const preview = accumulateManagedAgentsEvent(undefined, event);
        if (preview) {
          previews.set(event.event.id, preview);
        }
        console.log(`event_start             ${event.event.type} ${event.event.id}`);
        break;
      }
      case "event_delta": {
        // 2. Combina el fragmento en la instantánea y renderízala
        const preview = accumulateManagedAgentsEvent(previews.get(event.event_id), event);
        if (preview) {
          previews.set(event.event_id, preview);
          const text = preview.content
            .map((block) => (block.type === "text" ? block.text : ""))
            .join("");
          console.log(`event_delta             preview: ${JSON.stringify(text)}`);
        }
        break;
      }
      case "agent.message": {
        // 3. El evento en búfer es el registro: reemplaza y cierra la vista previa
        const message = accumulateManagedAgentsEvent(previews.get(event.id), event);
        previews.delete(event.id);
        const text = message.content
          .map((block) => (block.type === "text" ? block.text : ""))
          .join("");
        console.log(`agent.message           ${event.id} ${JSON.stringify(text)}`);
        break;
      }
      case "span.model_request_end":
        // 4. No llegarán más deltas. Cierra cualquier vista previa nunca conciliada.
        for (const eventId of previews.keys()) {
          console.log(`span.model_request_end  closing preview for ${eventId}`);
        }
        previews.clear();
        break;
      case "session.status_idle":
        break deltas;
    }
  }
  stream.controller.abort();
  ```

  ```csharp C#
  // Activa los deltas de eventos: los eventos agent.message se previsualizan a medida que se producen.
  using var stream = await client.Beta.Sessions.Events.WithRawResponse.StreamStreaming(
      session.ID,
      new() { EventDeltas = [BetaManagedAgentsDeltaType.AgentMessage] }
  );
  await client.Beta.Sessions.Events.Send(session.ID, new()
  {
      Events =
      [
          new BetaManagedAgentsUserMessageEventParams
          {
              Type = BetaManagedAgentsUserMessageEventParamsType.UserMessage,
              Content =
              [
                  new BetaManagedAgentsTextBlock
                  {
                      Type = BetaManagedAgentsTextBlockType.Text,
                      Text = "Write a haiku about event streams.",
                  },
              ],
          },
      ],
  });

  // Acumula fragmentos de vista previa por (id de evento, índice de contenido). El
  // agent.message en búfer que sigue trae el contenido completo, así que reemplaza la
  // vista previa acumulada en lugar de añadirse a ella.
  Dictionary<string, SortedDictionary<long, string>> previews = [];

  await foreach (var streamEvent in stream.Enumerate())
  {
      if (streamEvent.TryPickStartEvent(out var start))
      {
          // Se abrió una vista previa para el evento con este id. Este stream solo activa
          // deltas de agent.message; TryPick* devuelve false en lugar de lanzar excepción,
          // así que se omiten otros tipos de vista previa (incluidos los que se añadan después).
          if (start.Event.TryPickAgentMessage(out var preview))
          {
              Console.WriteLine($"event_start             {preview.Type.Raw()} {preview.ID}");
          }
      }
      else if (streamEvent.TryPickDeltaEvent(out var delta))
      {
          // Inserta en un índice nuevo, añade en uno existente
          if (!previews.TryGetValue(delta.EventID, out var fragments))
          {
              previews[delta.EventID] = fragments = [];
          }
          var index = delta.Delta.Index ?? 0;
          fragments[index] = fragments.GetValueOrDefault(index, "") + delta.Delta.Content.Text;
          Console.WriteLine($"event_delta             preview: {fragments[index]}");
      }
      else if (streamEvent.TryPickAgentMessageEvent(out var message))
      {
          // Los deltas son de mejor esfuerzo: descarta la vista previa y usa el evento en búfer
          previews.Remove(message.ID);
          var text = string.Concat(message.Content.Select(block =>
              block.TryPickBetaManagedAgentsTextBlock(out var textBlock) ? textBlock.Text : ""));
          Console.WriteLine($"agent.message           {message.ID} {text}");
      }
      else if (streamEvent.TryPickSpanModelRequestEndEvent(out _))
      {
          // No llegarán más deltas; cierra cualquier vista previa que nunca se haya conciliado.
          foreach (var eventId in previews.Keys)
          {
              Console.WriteLine($"span.model_request_end  closing preview for {eventId}");
          }
          previews.Clear();
      }
      else if (streamEvent.TryPickSessionStatusIdleEvent(out _))
      {
          break;
      }
  }
  ```

  ```go Go
  	// Activa las vistas previas incrementales de los eventos agent.message
  	stream := client.Beta.Sessions.Events.StreamEvents(ctx, session.ID, anthropic.BetaSessionEventStreamParams{
  		EventDeltas: []anthropic.BetaManagedAgentsDeltaType{
  			anthropic.BetaManagedAgentsDeltaTypeAgentMessage,
  		},
  	})

  	if _, err := client.Beta.Sessions.Events.Send(ctx, session.ID, anthropic.BetaSessionEventSendParams{
  		Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
  			OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
  				Type: anthropic.BetaManagedAgentsUserMessageEventParamsTypeUserMessage,
  				Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
  					OfText: &anthropic.BetaManagedAgentsTextBlockParam{
  						Type: anthropic.BetaManagedAgentsTextBlockTypeText,
  						Text: "Write a haiku about the ocean.",
  					},
  				}},
  			},
  		}},
  	}); err != nil {
  		panic(err)
  	}

  	// El acumulador combina los fragmentos event_start / event_delta en
  	// instantáneas de agent.message por id de evento. El valor cero está listo para usarse.
  	var previews anthropic.BetaManagedAgentsEventAccumulator

  deltas:
  	for stream.Next() {
  		event := stream.Current()
  		previews.Accumulate(event)

  		switch event := event.AsAny().(type) {
  		case anthropic.BetaManagedAgentsStartEvent:
  			fmt.Printf("event_start             %s %s\n", event.Event.Type, event.Event.ID)
  		case anthropic.BetaManagedAgentsDeltaEvent:
  			fmt.Printf("event_delta             preview: %q\n", previews.AgentMessageText(event.EventID))
  		case anthropic.BetaManagedAgentsAgentMessageEvent:
  			// El evento en búfer contiene el contenido completo: el acumulador
  			// reemplaza la vista previa con él
  			fmt.Printf("agent.message           %s %q\n", event.ID, previews.AgentMessageText(event.ID))
  		case anthropic.BetaManagedAgentsSpanModelRequestEndEvent:
  			// No llegarán más deltas para esta solicitud. El acumulador
  			// descarta aquí sus instantáneas, cerrando cualquier vista previa que nunca
  			// se haya conciliado con un agent.message en búfer.
  			fmt.Println("span.model_request_end  no more deltas for this request")
  		case anthropic.BetaManagedAgentsSessionStatusIdleEvent:
  			break deltas
  		}
  	}
  	if err := stream.Err(); err != nil {
  		panic(err)
  	}
  	stream.Close()
  ```

  ```java Java
  // Texto de vista previa, indexado por ID de evento y luego índice de contenido. El agent.message en búfer lo reemplaza.
  Map<String, Map<Long, StringBuilder>> previews = new HashMap<>();

  // Activa las vistas previas de agent.message en esta conexión
  try (var stream = client.beta().sessions().events().streamStreaming(
          session.id(),
          EventStreamParams.builder()
              .addEventDelta(BetaManagedAgentsDeltaType.AGENT_MESSAGE)
              .build()
  )) {
      client.beta().sessions().events().send(
          session.id(),
          EventSendParams.builder()
              .addEvent(BetaManagedAgentsUserMessageEventParams.builder()
                  .type(BetaManagedAgentsUserMessageEventParams.Type.USER_MESSAGE)
                  .addTextContent("Describe the repo in one sentence.")
                  .build())
              .build()
      );

      Iterable<BetaManagedAgentsStreamSessionEvents> events = stream.stream()::iterator;
      deltas:
      for (var event : events) {
          switch (event.type().value()) {
              case EVENT_START -> {
                  if (event.asEventStart().event().isAgentMessage()) {
                      var preview = event.asEventStart().event().asAgentMessage();
                      IO.println("event_start             " + preview.type().asString() + " " + preview.id());
                  }
              }
              case EVENT_DELTA -> {
                  var eventDelta = event.asEventDelta();
                  var fragment = eventDelta.delta();
                  var buffer = previews
                      .computeIfAbsent(eventDelta.eventId(), _ -> new HashMap<>())
                      .computeIfAbsent(fragment.index().orElse(0L), _ -> new StringBuilder());
                  buffer.append(fragment.content().text());
                  IO.println("event_delta             preview: " + buffer);
              }
              case AGENT_MESSAGE -> {
                  // El evento en búfer es el registro: descarta su vista previa y renderiza su contenido
                  var message = event.asAgentMessage();
                  previews.remove(message.id());
                  var text = message.content().stream()
                      .flatMap(block -> block.text().stream())
                      .map(textBlock -> textBlock.text())
                      .collect(Collectors.joining());
                  IO.println("agent.message           " + message.id() + " " + text);
              }
              case SPAN_MODEL_REQUEST_END -> {
                  // No llegarán más deltas. Cierra cualquier vista previa cuyo evento en búfer nunca llegó.
                  previews.keySet().forEach(eventId ->
                      IO.println("span.model_request_end  closing preview for " + eventId));
                  previews.clear();
              }
              case SESSION_STATUS_IDLE -> {
                  break deltas;
              }
          }
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\Sessions\BetaManagedAgentsDeltaEvent;
  use Anthropic\Beta\Sessions\BetaManagedAgentsDeltaType;
  use Anthropic\Beta\Sessions\BetaManagedAgentsStartEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsAgentMessageEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsSessionStatusIdleEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsSpanModelRequestEndEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock;
  use Anthropic\Lib\Sessions\EventAccumulator;

  // Instantáneas de vista previa, indexadas por id de evento. EventAccumulator::accumulate() agrega cada
  // event_start / event_delta a una instantánea de agent.message; el
  // agent.message almacenado en búfer la reemplaza.
  $previews = [];

  // El texto de una instantánea o evento agent.message
  $textOf = fn (ManagedAgentsAgentMessageEvent $message): string => implode(
      '',
      array_map(
          fn ($block) => $block->text,
          array_filter(
              $message->content,
              fn ($block) => $block instanceof ManagedAgentsTextBlock,
          ),
      ),
  );

  // Activa las vistas previas de agent.message en esta conexión
  $stream = $client->beta->sessions->events->streamStream(
      $session->id,
      eventDeltas: [BetaManagedAgentsDeltaType::AGENT_MESSAGE],
  );

  $client->beta->sessions->events->send(
      $session->id,
      events: [
          [
              'type' => 'user.message',
              'content' => [['type' => 'text', 'text' => 'Describe the repo in one sentence.']],
          ],
      ],
  );

  foreach ($stream as $event) {
      switch (true) {
          case $event instanceof BetaManagedAgentsStartEvent:
              $snapshot = EventAccumulator::accumulate(null, $event);
              if ($snapshot !== null) {
                  $previews[$event->event->id] = $snapshot;
              }
              printf("event_start             %s %s\n", $event->event->type, $event->event->id);
              break;
          case $event instanceof BetaManagedAgentsDeltaEvent:
              // Omite un delta tardío de una vista previa que ya se reemplazó o cerró
              if (!isset($previews[$event->eventID])) {
                  break; // Break switch statement
              }
              $previews[$event->eventID] = EventAccumulator::accumulate($previews[$event->eventID], $event);
              printf("event_delta             preview: %s\n", json_encode($textOf($previews[$event->eventID])));
              break;
          case $event instanceof ManagedAgentsAgentMessageEvent:
              // El evento almacenado en búfer es el registro: reemplaza y cierra la vista previa
              unset($previews[$event->id]);
              printf("agent.message           %s %s\n", $event->id, json_encode($textOf($event)));
              break;
          case $event instanceof ManagedAgentsSpanModelRequestEndEvent:
              // No llegarán más deltas. Cierra cualquier vista previa cuyo
              // evento almacenado en búfer nunca llegó.
              foreach (array_keys($previews) as $eventID) {
                  printf("span.model_request_end  closing preview for %s\n", $eventID);
              }
              $previews = [];
              break;
          case $event instanceof ManagedAgentsSessionStatusIdleEvent:
              break 2; // Break foreach loop
      }
  }
  $stream->close();
  ```

  ```ruby Ruby
  # Activa los deltas de eventos: las vistas previas de agent.message llegan como fragmentos incrementales.
  stream = client.beta.sessions.events.stream_events(
    session.id,
    event_deltas: [Anthropic::Beta::BetaManagedAgentsDeltaType::AGENT_MESSAGE]
  )

  client.beta.sessions.events.send_(
    session.id,
    events: [{
      type: "user.message",
      content: [{type: "text", text: "Give a one-sentence project tagline."}]
    }]
  )

  # Acumula fragmentos de vista previa por (event_id, index) en búferes explícitamente mutables
  # (`+""`) para que `<<` pueda anexar in situ. El agent.message en búfer con
  # el mismo id es autoritativo y reemplaza lo que hayan construido los deltas.
  buffers = Hash.new do |by_event, event_id|
    by_event[event_id] = Hash.new { |fragments, index| fragments[index] = +"" }
  end

  stream.each do |event|
    case event
    when Anthropic::Beta::BetaManagedAgentsStartEvent
      puts "event_start             #{event.event.type} #{event.event.id}"
    when Anthropic::Beta::BetaManagedAgentsDeltaEvent
      delta = event.delta
      fragment = delta.content.text
      buffers[event.event_id][delta.index || 0] << fragment
      puts "event_delta             preview: #{buffers[event.event_id][delta.index || 0].inspect}"
    when Anthropic::Beta::Sessions::BetaManagedAgentsAgentMessageEvent
      # Reemplaza: descarta la vista previa acumulada y renderiza el evento completo.
      buffers.delete(event.id)
      puts "agent.message           #{event.id} #{event.content.map(&:text).join.inspect}"
    when Anthropic::Beta::Sessions::BetaManagedAgentsSpanModelRequestEndEvent
      # No llegarán más deltas. Cierra cualquier vista previa que nunca se haya conciliado.
      buffers.each_key { |event_id| puts "span.model_request_end  closing preview for #{event_id}" }
      buffers.clear
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusIdleEvent
      break
    else
      # ignora otros tipos de eventos
    end
  end
  ```
</CodeGroup>

## Previsualiza eventos de hilos de sesión

En una sesión [multiagente](https://platform.claude.com/docs/es/managed-agents/multiagent-orchestration), cada hilo de sesión tiene su propio flujo de eventos. Acepta el mismo parámetro `event_deltas[]` con los mismos valores.

Una conexión previsualiza solo el hilo que está leyendo. El flujo a nivel de sesión previsualiza el hilo principal, y las vistas previas de un hilo hijo nunca se publican también en él. Para ver el texto de un subagente a medida que el modelo lo genera, abre el flujo de hilo de ese subagente.

La ruta de un flujo de hilo termina en `/threads/{thread_id}/stream`. `/events/stream` existe solo a nivel de sesión, por lo que no hay un endpoint `/threads/{thread_id}/events/stream`.

`event_start` y `event_delta` tienen la misma forma en un flujo de hilo que en el flujo a nivel de sesión, y el patrón de [acumular y conciliar](https://platform.claude.com/docs/es/managed-agents/event-deltas#accumulate-and-reconcile) se aplica tal como está escrito. Ejecuta una instancia de acumulador por cada conexión de flujo.

<CodeGroup>
  ```bash cURL
  # El stream del hilo acepta el mismo parámetro event_deltas[] que el stream de la sesión.
  # Codifica los corchetes en porcentaje (%5B%5D) y pon la URL entre comillas.
  curl --fail-with-body -sS -N \
    "https://api.anthropic.com/v1/sessions/$SESSION_ID/threads/$THREAD_ID/stream?beta=true&event_deltas%5B%5D=agent.message" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "accept: text/event-stream"
  ```

  ```bash CLI
  # El stream de hilo acepta el mismo parámetro event_deltas que el stream de sesión,
  # un flag --event-delta por cada tipo de evento a previsualizar.
  ant beta:sessions:threads:events stream \
    --session-id "$SESSION_ID" \
    --thread-id "$THREAD_ID" \
    --event-delta agent.message
  ```

  ```python Python
  # Lista los hilos de la sesión y elige un hijo: los hilos hijos tienen un
  # parent_thread_id no nulo, y el parent_thread_id del hilo principal es null.
  child_thread = next(
      thread
      for thread in client.beta.sessions.threads.list(session.id)
      if thread.parent_thread_id is not None
  )

  # El stream del hilo hijo acepta el mismo parámetro event_deltas que el
  # stream de la sesión.
  with client.beta.sessions.threads.events.stream(
      child_thread.id,
      session_id=session.id,
      event_deltas=["agent.message"],
  ) as stream:
      for event in stream:
          match event.type:
              case "event_delta":
                  print(event.delta.content.text, end="")
              case "agent.message":
                  # El evento en búfer es el registro autoritativo; renderiza su contenido
                  print()
                  for block in event.content:
                      if block.type == "text":
                          print(block.text, end="")
                  print()
              case "session.thread_status_idle":
                  break
  ```

  ```typescript TypeScript
  // Lista los hilos de la sesión y elige un hijo: los hilos hijos tienen parent_thread_id
  // no nulo, y el parent_thread_id del hilo principal es null.
  let childThreadId: string | undefined;
  for await (const thread of client.beta.sessions.threads.list(session.id)) {
    if (thread.parent_thread_id !== null) {
      childThreadId = thread.id;
      break;
    }
  }
  if (!childThreadId) {
    throw new Error("No child thread found");
  }

  // El stream del hilo hijo acepta el mismo parámetro event_deltas que el
  // stream de la sesión.
  const stream = await client.beta.sessions.threads.events.stream(childThreadId, {
    session_id: session.id,
    event_deltas: ["agent.message"]
  });

  threadDeltas: for await (const event of stream) {
    switch (event.type) {
      case "event_delta":
        process.stdout.write(event.delta.content.text);
        break;
      case "agent.message": {
        // El evento en búfer es el registro autoritativo; renderiza su contenido.
        process.stdout.write("\n");
        const text = event.content
          .map((block) => (block.type === "text" ? block.text : ""))
          .join("");
        console.log(text);
        break;
      }
      case "session.thread_status_idle":
        break threadDeltas;
    }
  }
  stream.controller.abort();
  ```

  ```csharp C#
  // Lista los hilos de la sesión y elige un hijo: los hilos hijos tienen un
  // parent_thread_id no nulo, y el parent_thread_id del hilo principal es null.
  var threads = await client.Beta.Sessions.Threads.List(session.ID);
  var childThread = threads.Items.First(thread => thread.ParentThreadID is not null);

  // El stream del hilo hijo acepta el mismo parámetro event_deltas que el
  // stream de la sesión.
  using var stream = await client.Beta.Sessions.Threads.Events.WithRawResponse.StreamStreaming(
      childThread.ID,
      new() { SessionID = session.ID, EventDeltas = [BetaManagedAgentsDeltaType.AgentMessage] }
  );

  await foreach (var streamEvent in stream.Enumerate())
  {
      if (streamEvent.TryPickDeltaEvent(out var delta))
      {
          Console.Write(delta.Delta.Content.Text);
      }
      else if (streamEvent.TryPickAgentMessageEvent(out var message))
      {
          // El evento en búfer es el registro autoritativo; renderiza su contenido.
          Console.WriteLine();
          var text = string.Concat(message.Content.Select(block =>
              block.TryPickBetaManagedAgentsTextBlock(out var textBlock) ? textBlock.Text : ""));
          Console.WriteLine(text);
      }
      else if (streamEvent.TryPickSessionThreadStatusIdleEvent(out _))
      {
          break;
      }
  }
  ```

  ```go Go
  	// Lista los hilos de la sesión y elige un hijo: los hilos hijos tienen un
  	// parent_thread_id no nulo, y el parent_thread_id del hilo principal es nulo.
  	var childThreadID string
  	threads := client.Beta.Sessions.Threads.ListAutoPaging(ctx, session.ID, anthropic.BetaSessionThreadListParams{})
  	for threads.Next() {
  		if thread := threads.Current(); thread.ParentThreadID != "" {
  			childThreadID = thread.ID
  			break
  		}
  	}
  	if err := threads.Err(); err != nil {
  		panic(err)
  	}

  	// El stream del hilo hijo acepta el mismo parámetro event_deltas que el
  	// stream de la sesión; ejecuta un bucle de lectura por cada conexión de stream.
  	stream := client.Beta.Sessions.Threads.Events.StreamEvents(ctx, childThreadID, anthropic.BetaSessionThreadEventStreamParams{
  		SessionID: session.ID,
  		EventDeltas: []anthropic.BetaManagedAgentsDeltaType{
  			anthropic.BetaManagedAgentsDeltaTypeAgentMessage,
  		},
  	})

  threadDeltas:
  	for stream.Next() {
  		switch event := stream.Current().AsAny().(type) {
  		case anthropic.BetaManagedAgentsDeltaEvent:
  			fmt.Print(event.Delta.Content.Text)
  		case anthropic.BetaManagedAgentsAgentMessageEvent:
  			// El evento en búfer es el registro autoritativo; renderiza su contenido.
  			fmt.Println()
  			// lista de tipo concreto: BetaManagedAgentsTextBlock
  			for _, block := range event.Content {
  				fmt.Print(block.Text)
  			}
  			fmt.Println()
  		case anthropic.BetaManagedAgentsSessionThreadStatusIdleEvent:
  			break threadDeltas
  		}
  	}
  	if err := stream.Err(); err != nil {
  		panic(err)
  	}
  	stream.Close()
  ```

  ```java Java
  // Lista los hilos de la sesión y elige un hijo: los hilos hijos tienen un
  // parent_thread_id no nulo, y el parent_thread_id del hilo principal es null.
  var childThread = client.beta().sessions().threads().list(session.id()).autoPager().stream()
      .filter(thread -> thread.parentThreadId().isPresent())
      .findFirst()
      .orElseThrow();

  // El stream del hilo hijo acepta el mismo parámetro event_deltas que el stream
  // de la sesión. Su clase de params comparte el nombre simple de la de sesión, así que califícala.
  try (var stream = client.beta().sessions().threads().events().streamStreaming(
          childThread.id(),
          com.anthropic.models.beta.sessions.threads.events.EventStreamParams.builder()
              .sessionId(session.id())
              .addEventDelta(BetaManagedAgentsDeltaType.AGENT_MESSAGE)
              .build()
  )) {
      Iterable<BetaManagedAgentsStreamSessionThreadEvents> events = stream.stream()::iterator;
      threadDeltas:
      for (var event : events) {
          switch (event.type().value()) {
              case EVENT_DELTA -> IO.print(event.asEventDelta().delta().content().text());
              case AGENT_MESSAGE -> {
                  // El evento en búfer es el registro autoritativo; renderiza su contenido.
                  IO.println();
                  event.asAgentMessage().content().forEach(block -> block.text().ifPresent(textBlock -> IO.print(textBlock.text())));
                  IO.println();
              }
              case SESSION_THREAD_STATUS_IDLE -> {
                  break threadDeltas;
              }
          }
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\Sessions\BetaManagedAgentsDeltaEvent;
  use Anthropic\Beta\Sessions\BetaManagedAgentsDeltaType;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsAgentMessageEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsSessionThreadStatusIdleEvent;
  use Anthropic\Beta\Sessions\Events\ManagedAgentsTextBlock;

  // Lista los hilos de la sesión y elige un hijo: los hilos hijos tienen un
  // parentThreadID no nulo, y el parentThreadID del hilo principal es null.
  $childThread = null;
  foreach ($client->beta->sessions->threads->list($session->id)->pagingEachItem() as $thread) {
      if ($thread->parentThreadID !== null) {
          $childThread = $thread;
          break;
      }
  }

  // El stream del hilo hijo acepta el mismo parámetro eventDeltas que el
  // stream de la sesión.
  $stream = $client->beta->sessions->threads->events->streamStream(
      $childThread->id,
      sessionID: $session->id,
      eventDeltas: [BetaManagedAgentsDeltaType::AGENT_MESSAGE],
  );

  foreach ($stream as $event) {
      switch (true) {
          case $event instanceof BetaManagedAgentsDeltaEvent:
              echo $event->delta->content->text;
              break;
          case $event instanceof ManagedAgentsAgentMessageEvent:
              // El evento almacenado en búfer es el registro autoritativo; renderiza su contenido
              echo "\n";
              foreach ($event->content as $block) {
                  if ($block instanceof ManagedAgentsTextBlock) {
                      echo $block->text;
                  }
              }
              echo "\n";
              break;
          case $event instanceof ManagedAgentsSessionThreadStatusIdleEvent:
              break 2; // Break foreach loop
      }
  }
  $stream->close();
  ```

  ```ruby Ruby
  # Lista los hilos de la sesión y elige un hijo: los hilos hijos tienen un parent_thread_id
  # no nulo, y el parent_thread_id del hilo principal es null.
  child_thread = client.beta.sessions.threads.list(session.id).to_enum.find { it.parent_thread_id }

  # El stream del hilo hijo acepta el mismo parámetro event_deltas que el
  # stream de la sesión.
  stream = client.beta.sessions.threads.events.stream_events(
    child_thread.id,
    session_id: session.id,
    event_deltas: [Anthropic::Beta::BetaManagedAgentsDeltaType::AGENT_MESSAGE]
  )

  stream.each do |event|
    case event
    when Anthropic::Beta::BetaManagedAgentsDeltaEvent
      print event.delta.content.text
    when Anthropic::Beta::Sessions::BetaManagedAgentsAgentMessageEvent
      # El evento en búfer es el registro autoritativo; renderiza su contenido.
      puts
      event.content.each { print it.text }
      puts
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionThreadStatusIdleEvent
      break
    else
      # ignora otros tipos de eventos
    end
  end
  ```
</CodeGroup>

El bucle de lectura termina en [`session.thread_status_idle`](https://platform.claude.com/docs/es/managed-agents/reference#event-types), el evento que se emite cuando finaliza el turno del hilo de sesión y el hilo queda inactivo.

## Limitaciones

* **Mejor esfuerzo:** Bajo carga, el servidor podría descartar deltas de un evento. Cuando lo hace, recibes un prefijo contiguo del texto y luego ningún delta más para ese evento. El `agent.message` almacenado en búfer sigue llegando completo. Nunca trates una vista previa acumulada como definitiva.
* **Sin repetición al reconectar:** Los deltas se entregan solo a la conexión que los activó, mientras está abierta. Esto se aplica por igual al flujo a nivel de sesión y a cada flujo de hilo de sesión. Una conexión abierta después de que comenzó una solicitud al modelo no recibe deltas para ese evento en curso. No hay forma de volver a solicitar los deltas perdidos.
* **Un hilo, solo texto:** Las vistas previas cubren el texto del asistente en [el hilo que la conexión está leyendo](https://platform.claude.com/docs/es/managed-agents/event-deltas#preview-session-thread-events). El uso de herramientas, los resultados de herramientas y los resultados de MCP nunca se previsualizan.
* **Nunca se persisten:** `event_start` y `event_delta` existen solo en el flujo en vivo. No aparecen en el historial de eventos de la sesión (`GET /v1/sessions/{session_id}/events`) ni en el historial de eventos de ningún hilo de sesión.

## Solución de problemas de vistas previas

| Lo que ves                                                                        | Qué significa                                                                                                                                                                                                                                                                                                                                                                                           |
| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Un flujo con eventos almacenados en búfer pero sin `event_start` ni `event_delta` | La conexión que estás leyendo no activó las vistas previas, o el turno nunca tocó el hilo que estás transmitiendo. `event_deltas[]` se aplica por conexión, no por sesión. Para saber qué hilo se ejecutó, lista los hilos de la sesión (`GET /v1/sessions/{session_id}/threads`).                                                                                                                      |
| Un flujo que se corta durante una vista previa                                    | Los deltas no se repiten. Sigue el [procedimiento de reconexión](https://platform.claude.com/docs/es/managed-agents/events-and-streaming#reconnect-without-missing-events): vuelve a abrir el flujo y lista el historial de eventos. El historial incluye cualquier evento almacenado en búfer emitido mientras estabas desconectado, incluido el `agent.message` que tu vista previa estaba esperando. |
| Un 404 en la URL del flujo                                                        | La ruta o un ID es incorrecto, o la solicitud no lleva ningún encabezado beta de managed-agents. Los endpoints de hilos están restringidos a la beta, así que sin el encabezado no existen.                                                                                                                                                                                                             |
| Un 400 que menciona `event_deltas`                                                | Solo se aceptan `agent.message` y `agent.thinking`.                                                                                                                                                                                                                                                                                                                                                     |

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Flujo de eventos de la sesión" icon="lightning" href="https://platform.claude.com/docs/es/managed-agents/events-and-streaming">
    Envía eventos, transmite respuestas e interrumpe o redirige tu sesión a mitad de la ejecución.
  </Card>

  <Card title="Orquestación multiagente" icon="stack" href="https://platform.claude.com/docs/es/managed-agents/multiagent-orchestration">
    Coordina varios agentes dentro de una sola sesión.
  </Card>
</CardGroup>
