---
title: Visualize respostas com deltas de eventos
url: https://platform.claude.com/docs/pt-BR/managed-agents/event-deltas
description: Renderize o texto de resposta do agente como uma prévia ao vivo enquanto o modelo ainda o está gerando.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

Por padrão, o texto de resposta do agente chega ao [fluxo de eventos da sessão](https://platform.claude.com/docs/pt-BR/managed-agents/events-and-streaming) como eventos `agent.message` em buffer. Cada um é emitido somente depois que a requisição ao modelo que o produziu termina. Os "event deltas" (deltas de eventos) permitem que você renderize esse texto de forma incremental, como uma prévia ao vivo, enquanto o modelo ainda o está gerando.

As prévias são um auxílio de exibição de melhor esforço, e o `agent.message` em buffer é sempre o registro oficial. Um cliente que ignora as prévias ainda recebe um fluxo completo e correto.

## Ative as prévias

As prévias são opcionais por conexão de fluxo. Adicione o parâmetro de consulta `event_deltas[]` ao fluxo que você está lendo e repita-o uma vez para cada tipo de evento que você deseja visualizar. Os valores aceitos são `agent.message` e `agent.thinking`. Qualquer outro valor retorna um erro 400, assim como uma requisição com mais de 100 valores.

Ambos os endpoints de fluxo aceitam o parâmetro:

* **Fluxo no nível da sessão:** `GET /v1/sessions/{session_id}/events/stream`
* **Fluxo de thread da sessão:** `GET /v1/sessions/{session_id}/threads/{thread_id}/stream`

As prévias de um subagente aparecem [no próprio fluxo de thread desse subagente](https://platform.claude.com/docs/pt-BR/managed-agents/event-deltas#preview-session-thread-events).

`[]` é um padrão glob do shell, então coloque a URL entre aspas sempre que você construir a requisição em um shell. Os exemplos codificam os colchetes em porcentagem como `%5B%5D`, o que também funciona.

### Eventos de prévia

Quando um evento com prévia começa, o fluxo emite um `event_start` contendo o tipo e o `id` do evento que está por vir:

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

Para `agent.message`, o início é seguido por eventos `event_delta` contendo texto incremental. Cada delta nomeia o evento que estende em `event_id` e o bloco de conteúdo que estende em `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`, apenas o `event_start` é emitido, como um sinal de que um bloco de pensamento começou. Nenhum evento `event_delta` o segue. O evento `agent.thinking` em buffer que conclui a prévia é um sinal de progresso e não contém nenhum conteúdo de pensamento.

Diferentemente dos eventos persistidos, `event_start` e `event_delta` não têm `id` nem `processed_at` próprios. O único identificador que eles carregam é o `id` do evento que visualizam. Suas strings de tipo também são a exceção à convenção de nomenclatura `{domain}.{action}` dos eventos persistidos.

<Note>
  Os deltas de eventos usam um formato de transmissão diferente do [Streaming de mensagens](https://platform.claude.com/docs/pt-BR/build-with-claude/streaming), e a diferença é intencional. Um `agent.message` com prévia recebe um único `event_start` seguido apenas por eventos `event_delta`. Não há eventos de início ou parada por bloco de conteúdo nem evento de parada para o próprio evento com prévia. O tipo de delta é `content_delta`, não `content_block_delta`. O código acumulador escrito para a Messages API não funciona sem alterações.
</Note>

## Acumule e reconcilie

Todo SDK que oferece suporte a deltas de eventos inclui um [auxiliar acumulador](https://platform.claude.com/docs/pt-BR/managed-agents/event-deltas#sdk-accumulator-helpers) que cuida da contabilidade do `index` para você. O padrão manual desta seção funciona em todas as linguagens quando você precisa de uma contabilidade personalizada. Aplique-o aos tipos de eventos gerados.

No padrão manual, mantenha o texto da prévia em um mapa temporário indexado por `(event_id, index)` e trate o evento em buffer como o registro. Reconcilie os dois por requisição ao modelo.

Um turno começa com um único evento `session.status_running`. Em um turno que é concluído normalmente, cada requisição ao modelo produz então estes eventos, em ordem:

1. `span.model_request_start`
2. `event_start`
3. Os eventos `event_delta`
4. O `agent.message` em buffer
5. [`span.model_request_end`](https://platform.claude.com/docs/pt-BR/managed-agents/reference#event-types) (na aba Span events)

Na transmissão, esta é a parte com prévia dessa sequência, intercalada com os outros eventos em buffer da conexão:

```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": [...]}
```

A linha `event_delta` se repete uma vez por fragmento de texto. Processe cada evento à medida que ele chega:

1. Em `event_start`, anote o `id` anunciado. Os identificadores sempre coincidem: `event_start.event.id`, cada `event_delta.event_id` e o `id` do `agent.message` em buffer são o mesmo valor.
2. Em cada `event_delta`, anexe `delta.content.text` à entrada em `(event_id, delta.index)` e renderize o texto acumulado. O primeiro delta para um `index` cria essa entrada.
3. Quando o `agent.message` em buffer chegar, associe-o pelo `id`, descarte a prévia acumulada e renderize o conteúdo da mensagem em seu lugar.
4. Em `span.model_request_end`, feche qualquer prévia que não tenha sido reconciliada pelo seu evento em buffer. Nenhum outro delta chegará para ela. Se o turno apresentar erro ou for interrompido, o evento em buffer pode nunca chegar, mas `span.model_request_end` ainda chega.

O padrão depende de duas garantias:

* Concatenar os deltas de uma prévia na ordem de chegada, indexados por `(event_id, index)`, resulta em um prefixo de `content[index].text` no evento em buffer. Não é necessariamente o texto inteiro, porque os deltas podem ser [descartados sob carga](https://platform.claude.com/docs/pt-BR/managed-agents/event-deltas#limitations).
* Uma conexão emite no máximo um `event_start` por `event_id`, e o evento em buffer é a última coisa que essa conexão entrega para esse `id`.

### Auxiliares acumuladores do SDK

O auxiliar de cada SDK cuida da contabilidade do `index` (csharp, go: `Index`). Os auxiliares de Go, Java, Ruby e C# também indexam a prévia acumulada pelo `id` (csharp, go: `ID`) do evento. Com os auxiliares de Python, TypeScript e PHP, mantenha esse mapa você mesmo e incorpore cada delta à entrada do seu `id` (csharp, go: `ID`).

Os exemplos a seguir ativam as prévias de `agent.message` e as reconciliam com o evento em buffer:

<CodeGroup exclude="shell:cURL, shell:CLI">
  <CodeGroupItem language="cURL">
    Este fluxo de trabalho precisa de mais lógica do que um único comando de shell. Use o [Claude SDK](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/overview) para executá-lo.
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    Este fluxo de trabalho precisa de mais lógica do que um único comando de shell. Use o [Claude SDK](https://platform.claude.com/docs/pt-BR/cli-sdks-libraries/overview) para executá-lo.
  </CodeGroupItem>

  ```python Python
  # Snapshots de prévia, indexados pelo id do evento. accumulate_managed_agents_event incorpora cada
  # event_start / event_delta em um snapshot de agent.message; o agent.message
  # em buffer o substitui.
  previews: dict[str, BetaManagedAgentsAgentMessageEvent] = {}

  # Ative as prévias de agent.message nesta conexão
  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":
                  # O evento em buffer é o registro: ele substitui e fecha a prévia
                  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":
                  # Não virão mais deltas. Feche qualquer prévia cujo
                  # evento em buffer nunca chegou.
                  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
  // Snapshots de prévia, indexados pelo id do evento. `accumulateManagedAgentsEvent`
  // incorpora prévias event_start / event_delta em um snapshot de agent.message.
  const previews = new Map<string, BetaManagedAgentsAgentMessageEvent>();

  // Ative prévias de agent.message apenas para esta conexão
  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. Anote o id anunciado e abra o snapshot. Os deltas e o
        //    evento em buffer têm o mesmo 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. Incorpore o fragmento ao snapshot e renderize-o
        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. O evento em buffer é o registro: ele substitui e fecha a prévia
        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. Não virão mais deltas. Feche qualquer prévia que nunca foi reconciliada.
        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#
  // Ativa deltas de eventos: eventos agent.message são pré-visualizados à medida que são produzidos.
  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 prévia por (id do evento, índice de conteúdo). O
  // agent.message em buffer que vem a seguir traz o conteúdo completo, então ele substitui a
  // prévia acumulada em vez de ser anexado a ela.
  Dictionary<string, SortedDictionary<long, string>> previews = [];

  await foreach (var streamEvent in stream.Enumerate())
  {
      if (streamEvent.TryPickStartEvent(out var start))
      {
          // Uma prévia aberta para o evento com este id. Este stream só ativa
          // deltas de agent.message; TryPick* retorna false em vez de lançar exceção,
          // então outros tipos de prévia (incluindo os adicionados depois) são ignorados.
          if (start.Event.TryPickAgentMessage(out var preview))
          {
              Console.WriteLine($"event_start             {preview.Type.Raw()} {preview.ID}");
          }
      }
      else if (streamEvent.TryPickDeltaEvent(out var delta))
      {
          // Insere em um novo índice, anexa em um 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))
      {
          // Deltas são best-effort: descarte a prévia e use o evento em buffer
          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 _))
      {
          // Não virão mais deltas; fecha qualquer prévia que nunca foi reconciliada.
          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
  	// Ativa prévias incrementais de 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)
  	}

  	// O acumulador combina fragmentos event_start / event_delta em
  	// snapshots de agent.message por id de evento. O valor zero já está pronto para uso.
  	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:
  			// O evento em buffer traz o conteúdo completo: o acumulador
  			// substitui a prévia por ele
  			fmt.Printf("agent.message           %s %q\n", event.ID, previews.AgentMessageText(event.ID))
  		case anthropic.BetaManagedAgentsSpanModelRequestEndEvent:
  			// Não virão mais deltas para esta requisição. O acumulador
  			// descarta seus snapshots aqui, fechando qualquer prévia que nunca foi
  			// reconciliada por um agent.message em buffer.
  			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 prévia, indexado por ID do evento e depois índice do conteúdo. O agent.message em buffer o substitui.
  Map<String, Map<Long, StringBuilder>> previews = new HashMap<>();

  // Ativa as prévias de agent.message nesta conexão
  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 -> {
                  // O evento em buffer é o registro: descarte a prévia e renderize o conteúdo dele
                  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 -> {
                  // Não virão mais deltas. Feche qualquer prévia cujo evento em buffer nunca chegou.
                  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;

  // Snapshots de prévia, indexados pelo id do evento. EventAccumulator::accumulate() adiciona cada
  // event_start / event_delta a um snapshot de agent.message; o
  // agent.message em buffer o substitui.
  $previews = [];

  // O texto de um snapshot ou evento agent.message
  $textOf = fn (ManagedAgentsAgentMessageEvent $message): string => implode(
      '',
      array_map(
          fn ($block) => $block->text,
          array_filter(
              $message->content,
              fn ($block) => $block instanceof ManagedAgentsTextBlock,
          ),
      ),
  );

  // Ative as prévias de agent.message nesta conexão
  $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:
              // Ignore um delta atrasado de uma prévia que já foi substituída ou fechada
              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:
              // O evento em buffer é o registro: ele substitui e fecha a prévia
              unset($previews[$event->id]);
              printf("agent.message           %s %s\n", $event->id, json_encode($textOf($event)));
              break;
          case $event instanceof ManagedAgentsSpanModelRequestEndEvent:
              // Não virão mais deltas. Feche qualquer prévia cujo
              // evento em buffer nunca chegou.
              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
  # Ativa os deltas de evento: as prévias de agent.message chegam via streaming como fragmentos incrementais.
  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 prévia por (event_id, index) em buffers explicitamente mutáveis
  # (`+""`) para que `<<` possa anexar no lugar. O agent.message em buffer com
  # o mesmo id é autoritativo e substitui o que quer que os deltas tenham montado.
  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
      # Substituir: descarta a prévia acumulada e renderiza o evento completo.
      buffers.delete(event.id)
      puts "agent.message           #{event.id} #{event.content.map(&:text).join.inspect}"
    when Anthropic::Beta::Sessions::BetaManagedAgentsSpanModelRequestEndEvent
      # Não virão mais deltas. Fecha qualquer prévia que nunca foi reconciliada.
      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 outros tipos de evento
    end
  end
  ```
</CodeGroup>

## Visualize eventos de threads da sessão

Em uma sessão [multiagente](https://platform.claude.com/docs/pt-BR/managed-agents/multiagent-orchestration), cada thread da sessão tem seu próprio fluxo de eventos. Ele aceita o mesmo parâmetro `event_deltas[]` com os mesmos valores.

Uma conexão visualiza apenas a thread que está lendo. O fluxo no nível da sessão visualiza a thread principal, e as prévias de uma thread filha nunca são replicadas nele. Para acompanhar o texto de um subagente enquanto o modelo o gera, abra o fluxo de thread desse subagente.

O caminho de um fluxo de thread termina em `/threads/{thread_id}/stream`. `/events/stream` existe apenas no nível da sessão, portanto não há um endpoint `/threads/{thread_id}/events/stream`.

`event_start` e `event_delta` têm o mesmo formato em um fluxo de thread e no fluxo no nível da sessão, e o padrão de [acumular e reconciliar](https://platform.claude.com/docs/pt-BR/managed-agents/event-deltas#accumulate-and-reconcile) se aplica conforme descrito. Execute uma instância de acumulador por conexão de fluxo.

<CodeGroup>
  ```bash cURL
  # O stream da thread aceita o mesmo parâmetro event_deltas[] que o stream da sessão.
  # Codifique os colchetes em percent-encoding (%5B%5D) e coloque a URL entre aspas.
  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
  # O stream de thread aceita o mesmo parâmetro event_deltas que o stream de sessão,
  # uma flag --event-delta por tipo de evento a pré-visualizar.
  ant beta:sessions:threads:events stream \
    --session-id "$SESSION_ID" \
    --thread-id "$THREAD_ID" \
    --event-delta agent.message
  ```

  ```python Python
  # Liste as threads da sessão e escolha uma filha: threads filhas têm parent_thread_id
  # não nulo, e o parent_thread_id da thread principal é null.
  child_thread = next(
      thread
      for thread in client.beta.sessions.threads.list(session.id)
      if thread.parent_thread_id is not None
  )

  # O stream da thread filha aceita o mesmo parâmetro event_deltas que o
  # stream da sessão.
  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":
                  # O evento em buffer é o registro oficial; renderize o conteúdo dele
                  print()
                  for block in event.content:
                      if block.type == "text":
                          print(block.text, end="")
                  print()
              case "session.thread_status_idle":
                  break
  ```

  ```typescript TypeScript
  // Liste as threads da sessão e escolha uma filha: threads filhas têm parent_thread_id
  // não nulo, e o parent_thread_id da thread principal é nulo.
  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");
  }

  // O stream da thread filha aceita o mesmo parâmetro event_deltas que o
  // stream da sessão.
  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": {
        // O evento em buffer é o registro oficial; renderize seu conteúdo.
        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 as threads da sessão e escolhe uma filha: threads filhas têm
  // parent_thread_id não nulo, e o parent_thread_id da thread principal é nulo.
  var threads = await client.Beta.Sessions.Threads.List(session.ID);
  var childThread = threads.Items.First(thread => thread.ParentThreadID is not null);

  // O stream da thread filha aceita o mesmo parâmetro event_deltas que o
  // stream da sessão.
  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))
      {
          // O evento em buffer é o registro oficial; renderize o conteúdo dele.
          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 as threads da sessão e escolhe uma filha: threads filhas têm parent_thread_id
  	// não nulo, e o parent_thread_id da thread principal é 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)
  	}

  	// O stream da thread filha aceita o mesmo parâmetro event_deltas que o
  	// stream da sessão; execute um loop de leitura por conexão 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:
  			// O evento em buffer é o registro oficial; renderize o conteúdo dele.
  			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 as threads da sessão e escolhe uma filha: threads filhas têm parent_thread_id
  // não nulo, e o parent_thread_id da thread principal é null.
  var childThread = client.beta().sessions().threads().list(session.id()).autoPager().stream()
      .filter(thread -> thread.parentThreadId().isPresent())
      .findFirst()
      .orElseThrow();

  // O stream da thread filha aceita o mesmo parâmetro event_deltas que o stream
  // da sessão. Sua classe de params tem o mesmo nome simples da de sessão, então qualifique-a.
  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 -> {
                  // O evento em buffer é o registro oficial; renderize o conteúdo dele.
                  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;

  // Liste as threads da sessão e escolha uma filha: threads filhas têm um
  // parentThreadID não nulo, e o parentThreadID da thread principal é nulo.
  $childThread = null;
  foreach ($client->beta->sessions->threads->list($session->id)->pagingEachItem() as $thread) {
      if ($thread->parentThreadID !== null) {
          $childThread = $thread;
          break;
      }
  }

  // O stream da thread filha aceita o mesmo parâmetro eventDeltas que o
  // stream da sessão.
  $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:
              // O evento em buffer é o registro oficial; renderize o conteúdo dele
              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 as threads da sessão e escolhe uma filha: threads filhas têm parent_thread_id
  # não nulo, e o parent_thread_id da thread principal é null.
  child_thread = client.beta.sessions.threads.list(session.id).to_enum.find { it.parent_thread_id }

  # O stream da thread filha aceita o mesmo parâmetro event_deltas que o
  # stream da sessão.
  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
      # O evento em buffer é o registro autoritativo; renderize seu conteúdo.
      puts
      event.content.each { print it.text }
      puts
    when Anthropic::Beta::Sessions::BetaManagedAgentsSessionThreadStatusIdleEvent
      break
    else
      # ignora outros tipos de evento
    end
  end
  ```
</CodeGroup>

O loop de leitura termina em [`session.thread_status_idle`](https://platform.claude.com/docs/pt-BR/managed-agents/reference#event-types), o evento emitido quando o turno da thread da sessão termina e a thread fica ociosa.

## Limitações

* **Melhor esforço:** Sob carga, o servidor pode descartar deltas de um evento. Quando isso acontece, você recebe um prefixo contíguo do texto e depois nenhum outro delta para esse evento. O `agent.message` em buffer ainda chega completo. Nunca trate uma prévia acumulada como final.
* **Sem reprodução ao reconectar:** Os deltas são entregues apenas à conexão que os ativou, enquanto ela estiver aberta. Isso se aplica igualmente ao fluxo no nível da sessão e a cada fluxo de thread da sessão. Uma conexão aberta depois que uma requisição ao modelo começou não recebe deltas para esse evento em andamento. Não há como solicitar novamente os deltas perdidos.
* **Uma thread, apenas texto:** As prévias abrangem o texto do assistente na [thread que a conexão está lendo](https://platform.claude.com/docs/pt-BR/managed-agents/event-deltas#preview-session-thread-events). Uso de ferramentas, resultados de ferramentas e resultados de MCP nunca são visualizados.
* **Nunca persistidos:** `event_start` e `event_delta` existem apenas no fluxo ao vivo. Eles não aparecem no histórico de eventos da sessão (`GET /v1/sessions/{session_id}/events`) nem no histórico de eventos de qualquer thread da sessão.

## Solucione problemas de prévias

| O que você vê                                                          | O que significa                                                                                                                                                                                                                                                                                                                                                                                   |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Um fluxo com eventos em buffer, mas sem `event_start` ou `event_delta` | A conexão que você está lendo não ativou as prévias, ou o turno nunca passou pela thread que você está transmitindo. `event_deltas[]` se aplica por conexão, não por sessão. Para descobrir qual thread foi executada, liste as threads da sessão (`GET /v1/sessions/{session_id}/threads`).                                                                                                      |
| Um fluxo que cai durante uma prévia                                    | Os deltas não são reproduzidos novamente. Siga o [procedimento de reconexão](https://platform.claude.com/docs/pt-BR/managed-agents/events-and-streaming#reconnect-without-missing-events): reabra o fluxo e liste o histórico de eventos. O histórico inclui todos os eventos em buffer emitidos enquanto você estava desconectado, incluindo o `agent.message` que sua prévia estava aguardando. |
| Um 404 na URL do fluxo                                                 | O caminho ou um ID está errado, ou a requisição não contém nenhum cabeçalho beta de managed-agents. Os endpoints de thread são restritos ao beta, então sem o cabeçalho eles não existem.                                                                                                                                                                                                         |
| Um 400 mencionando `event_deltas`                                      | Apenas `agent.message` e `agent.thinking` são aceitos.                                                                                                                                                                                                                                                                                                                                            |

## Próximos passos

<CardGroup cols={2}>
  <Card title="Fluxo de eventos da sessão" icon="lightning" href="https://platform.claude.com/docs/pt-BR/managed-agents/events-and-streaming">
    Envie eventos, transmita respostas e interrompa ou redirecione sua sessão durante a execução.
  </Card>

  <Card title="Orquestração multiagente" icon="stack" href="https://platform.claude.com/docs/pt-BR/managed-agents/multiagent-orchestration">
    Coordene vários agentes em uma única sessão.
  </Card>
</CardGroup>
