For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Navegação principal

Gerenciamento de sessões do GPT-Live

Configure sessões, mantenha o contexto e gerencie o ciclo de vida da conversa.

Depois de se conectar ao GPT-Live, use eventos de sessão para atualizar o contexto, exibir transcrições e gerenciar o ciclo de vida da conexão. O modelo pode ouvir e falar ao mesmo tempo, então mantenha separados no seu aplicativo os eventos recebidos, a reprodução de áudio e o estado das tarefas do backend.

Este guia pressupõe que sua conexão já tenha emitido session.started. Consulte Conexões para saber como configurar a conexão e fazer streaming de áudio, e Delegação e ferramentas para saber como executar tarefas no backend.

Configure uma sessão

Escolha o modelo, a voz e o modo de delegação ao criar a sessão. Forneça ao modelo instruções para a conversa e inclua o histórico relevante. O GPT-Live gerencia o contexto automaticamente à medida que a conversa avança.

Campos de configuração

ConfiguraçãoConfigurar na inicializaçãoAlterar durante a sessão
ModeloDefina o campo obrigatório model.Inicie uma nova sessão para alterá-lo.
InstruçõesDefina instructions para orientar o comportamento na conversa, com até 16.384 tokens.Adicione instruções com session.instructions.append.
HistóricoPreencha input com mensagens de texto anteriores relevantes. O valor padrão é [].Acrescente contexto; não substitua o histórico fornecido na inicialização.
VozDefina audio.output.voice como uma voz compatível ou uma voz personalizada autorizada. O padrão é marin.Inicie uma nova sessão para alterá-la.
DelegaçãoDefina delegation.type como client ou responses. Se a delegação for omitida ou definida como null, o modo cliente será selecionado.Atualize as configurações de Responses dentro do modo existente.
ArmazenamentoDefina store como true para permitir a criação de forks da sessão. O valor padrão é false.Escolha na inicialização.

Opções de voz

Escolha uma voz ao criar a sessão. Defina audio.output.voice como o nome usado na API, por exemplo, "quartz". O GPT-Live inclui estas opções de voz adicionais:

VozNome na APIIdiomaInfluência regionalApresentaçãoOrigem
QuartzquartzInglêsAustralianaFemininaGerada
RipplerippleInglêsAustralianaMasculinaNatural
VespervesperInglêsBritânicaMasculinaNatural
WillowwillowInglêsIrlandesaFemininaNatural
StonestoneInglêsIrlandesaMasculinaNatural
GleamgleamInglêsNorte-americanaFemininaNatural
MeridianmeridianInglêsNorte-americanaMasculinaNatural
BossabossaPortuguêsBrasileiraFemininaNatural
TempotempoPortuguêsBrasileiraMasculinaNatural
BeaconbeaconInglêsFilipinaMasculinaGerada
DeltadeltaInglêsSul dos EUAFemininaGerada
CindercinderInglêsSul dos EUAMasculinaGerada

A influência regional descreve o estilo de fala de uma voz, sem garantir a fidelidade do sotaque. Para obter uma voz aprovada criada a partir de uma gravação sua, consulte Vozes personalizadas.

Para WebSocket, escolha o audio.format compartilhado na inicialização; ele não pode ser alterado durante a sessão. Para WebRTC, omita esse campo, pois a conexão negocia seu formato de áudio. Consulte Formatos de áudio do WebSocket para saber mais sobre formatos e streaming.

Atualize uma sessão em andamento

Use session.update para alterar session.delegation.responses em uma sessão que já usa delegação via Responses. Envie apenas as configurações que deseja alterar; as configurações omitidas mantêm seus valores. Consulte Configure a delegação via Responses para conhecer as configurações e o fluxo de atualização.

Você não pode alterar o modo de delegação após a inicialização. Em particular, definir delegation como null seleciona o modo cliente; isso não redefine uma sessão Responses. Os campos de inicialização model, instructions, input, audio e store não são aceitos em atualizações. Campos de configuração desconhecidos são rejeitados.

Uma atualização bem-sucedida emite session.updated com a configuração completa resultante da sessão. Quando você fornece um event_id, a confirmação o retorna como client_event_id. Verifique se há comandos rejeitados, além de confirmações. A aceitação confirma a atualização da configuração; ela não comprova que uma tarefa do backend foi executada nem que o modelo falou.

Forneça histórico e contexto

Use o histórico fornecido na inicialização para retomar um assunto e acrescente contexto relevante à medida que a conversa avança. Mantenha as instruções confiáveis do aplicativo separadas das mensagens do usuário e dos resultados factuais.

Inicie uma sessão com uma conversa anterior

Inclua mensagens de texto anteriores em session.input ao criar a sessão. Por exemplo, adicione este campo input à sua configuração de criação da sessão:

export const session = {
  model: "gpt-live-1",
  input: [
    {
      type: "message",
      role: "user",
      content: [
        {
          type: "input_text",
          text: "I need help with my recent order.",
        },
      ],
    },
    {
      type: "message",
      role: "assistant",
      content: [
        {
          type: "output_text",
          text: "What is the order number?",
        },
      ],
    },
  ],
};

A lista aceita até 128 mensagens e um total de 8.192 tokens. Os papéis compatíveis são developer, user e assistant, cada um com uma parte de texto. As mensagens de desenvolvedor e de usuário usam input_text; as mensagens do assistente usam text ou output_text. Coloque as instruções confiáveis do aplicativo em instructions ou em uma mensagem de desenvolvedor. A lista não aceita o papel system.

Selecione o histórico necessário para a próxima interação. input é um campo de inicialização, não uma forma de substituir o histórico durante uma sessão em andamento. Ele também não aceita todos os tipos de itens de entrada do backend usados na delegação via Responses.

Entenda quando o contexto chega ao modelo

Todo o conteúdo de input fornecido na criação da sessão fica disponível para o modelo quando a sessão começa. Coloque nesse campo o contexto de que o modelo precisa desde o início.

Durante uma sessão em andamento, os eventos session.instructions.append, session.thinking.append e session.commentary.append fornecem conteúdo ao modelo ao longo do tempo. Suas confirmações aguardam até que o avanço dos quadros alcance o fim estimado da injeção de contexto. Os valores retornados de start_ms e end_ms descrevem um intervalo estimado na linha do tempo da sessão, não a conclusão da fala ou da reprodução. Eles não comprovam que o modelo consumiu toda a atualização. Não presuma que a próxima fala do modelo refletirá a atualização inteira.

Se o avanço dos quadros parar, uma confirmação pode permanecer pendente. O encerramento da sessão informa um erro para as adições pendentes. Associe cada confirmação ao event_id enviado por meio de client_event_id e continue tratando erros enquanto aguarda.

Adicione contexto durante a conversa

Escolha um evento com base em como o modelo deve usar a atualização:

  • session.instructions.append: adicione instruções confiáveis do aplicativo que influenciem o comportamento e a fala.
  • session.thinking.append: adicione contexto factual sem pedir ao modelo que o diga imediatamente.
  • session.commentary.append: forneça informações para o modelo dizer em voz alta, que ele pode parafrasear.

Cada evento recebe content como uma string simples de até 500 tokens e exige um delegation_id. Use null para contexto que se aplica à sessão inteira. Por exemplo, envie o seguinte depois que seu aplicativo verificar a aceitação do usuário e iniciar a consulta:

export function sendUpdate(connection) {
  connection.send({
    type: "session.thinking.append",
    event_id: "context_1",
    delegation_id: null,
    content:
      "The user has already accepted the terms. The account lookup is still running.",
  });
}

Aguarde session.thinking.appended com client_event_id: "context_1" ou trate um erro. A confirmação indica que o contexto foi aceito. Ela não confirma a fala, a reprodução nem a conclusão de uma ação externa.

O contexto silencioso pode influenciar falas posteriores; ele não constitui uma barreira de privacidade. Não inclua credenciais, segredos nem textos que o modelo jamais deva revelar em nenhum dos três eventos. Use o evento de instruções para comportamentos definidos pelo aplicativo, não para saídas não confiáveis de ferramentas. Garanta que seu aplicativo aplique as permissões e exija as confirmações necessárias.

Para navegação entre páginas, seleções e outras mudanças na interface, consulte Compartilhe o contexto da interface para enviar atualizações concisas que ajudem o GPT-Live a entender a que o usuário está se referindo.

Para resultados vinculados a uma tarefa do backend, use um ID conhecido de delegação do cliente e siga as orientações de Envie o tipo certo de atualização. Esse ID não é um ID de resposta da Responses nem um ID de chamada de ferramenta.

Use instruções para orientar a conversa depois que uma verificação do aplicativo for acionada. Seu servidor pode monitorar eventos e enviar essas correções por um WebSocket de canal auxiliar conectado à sessão existente ou pelo WebSocket principal da sessão. Consulte Aplique mecanismos de proteção à conversa para saber mais sobre verificações simultâneas, bloqueio de ações e controle de reprodução.

Crie a interface da conversa

Exiba as transcrições e o estado do microfone independentemente do progresso do backend. Receber texto do assistente não informa quanto do áudio o usuário já ouviu.

Deltas da transcrição

Escute session.input_transcript.delta para a fala do usuário e session.output_transcript.delta para a fala do assistente. Cada evento contém um fragmento de texto e seu intervalo na linha do tempo da sessão:

{
  "type": "session.input_transcript.delta",
  "event_id": "event_transcript_1",
  "delta": "What is",
  "start_ms": 1000,
  "end_ms": 1200
}

Acrescente os fragmentos em ordem para cada interlocutor, preservando start_ms e end_ms. Esses valores representam milissegundos na linha do tempo da sessão, com intervalos que incluem o início e excluem o fim. Eles não são marcações de horário real, horários de chegada de pacotes nem alinhamentos exatos entre palavras e áudio.

Somente intervalos que contêm texto de transcrição geram eventos, e a entrega pela rede pode ser irregular. Não deduza que houve silêncio pela ausência de um evento nem trate um fragmento como um turno completo do usuário. Os deltas da transcrição não têm um ID de item nem um evento que confirme de forma definitiva a conclusão de um turno.

O processamento dos fragmentos de transcrição é opcional. Você pode usá-los para atualizar sua interface, executar verificações ou iniciar tarefas antecipadamente enquanto a conversa continua. Para verificações leves, considere um modelo pequeno como gpt-5.6-luna com baixo esforço de raciocínio. Consulte Reaja a fragmentos de transcrição para ver exemplos e orientações de conexão.

Para aplicar mecanismos de proteção à conversa, verifique o texto acumulado do usuário e do assistente à medida que ele chega. A entrega da transcrição não fornece um buffer antecipado para aprovar a fala antes da reprodução. Consulte Controle a reprodução quando necessário.

Se sua interface agrupa o texto em turnos, permita que esse agrupamento seja revisto. Preserve os fragmentos originais, permita a sobreposição dos intervalos do usuário e do assistente e ajuste qualquer tempo limite entre fragmentos com base em conversas gravadas. Uma breve confirmação do outro interlocutor pode fazer parte de uma troca ainda em andamento. O agrupamento de fragmentos não deve, por si só, acionar a execução de ferramentas nem cancelar tarefas no backend.

Mantenha as informações de tempo da transcrição separadas da reprodução de áudio. Os eventos session.output_audio.delta do WebSocket não têm campos de tempo nem um evento de conclusão do áudio de saída; o WebRTC entrega o áudio pela sua faixa de mídia. Consulte Conexões para saber como lidar com o áudio.

Exiba legendas

Crie linhas de legenda que possam crescer enquanto os dois interlocutores falam:

  1. Preserve o texto. Armazene os valores originais de delta, start_ms e end_ms de cada interlocutor. Concatene o texto exatamente como recebido, incluindo espaços e palavras repetidas. Não remova espaços das extremidades dos fragmentos nem insira espaços entre eles.
  2. Atualize cada interlocutor de forma independente. Permita que as linhas do usuário e do assistente cresçam durante falas sobrepostas. Mantenha o texto anterior do assistente visível após uma interrupção e inicie uma nova linha quando ele retomar a fala.
  3. Mantenha as linhas estáveis. Atribua IDs de exibição na sua aplicação e preserve a ordem das linhas à medida que o texto cresce. Não derive a identidade de uma linha do texto que muda nem das marcações de tempo de término, e não mova uma linha para o final sempre que ela receber um fragmento.
  4. Reavalie o agrupamento quando houver fragmentos atrasados. Use as marcações de tempo da transcrição para agrupar fragmentos próximos do mesmo interlocutor. Permita que textos atrasados atualizem linhas anteriores e que a atribuição dos fragmentos às linhas seja revista, preservando os fragmentos originais. Esses grupos de exibição não são turnos semanticamente completos; qualquer limiar de intervalo entre fragmentos é uma escolha da aplicação que precisa ser testada.
  5. Deixe o leitor controlar a rolagem. Acompanhe os novos textos enquanto o leitor estiver no final. Pause a rolagem automática quando ele rolar para cima e ofereça uma forma de voltar às legendas mais recentes.
  6. Mostre o progresso das ferramentas em uma área de status. Use os eventos de transcrição do assistente para legendar a fala. Exiba a atividade das ferramentas e os resultados do backend fora das legendas; receber um resultado não significa que o assistente já o tenha dito.

Teste a exibição com falas sobrepostas, confirmações breves, interrupções, pausas longas e traduções em que o texto dos dois interlocutores chega em ritmos diferentes.

Controle a entrada do microfone

Envie session.input_audio.mute para silenciar a entrada sem encerrar a sessão:

export function sendUpdate(connection) {
  connection.send({
    type: "session.input_audio.mute",
    event_id: "mute_1",
  });
}

Aguarde session.input_audio.muted com client_event_id: "mute_1" antes de considerar o comando aceito. Para retomar a entrada, envie session.input_audio.unmute e aguarde session.input_audio.unmuted. Trate os erros de ambos os comandos.

Silenciar a entrada não interrompe a inferência, as tarefas delegadas nem a fala gerada. Controle a captura do microfone e a reprodução de áudio separadamente na sua aplicação quando esses controles forem necessários.

Cumprimente antes que o interlocutor fale

Para solicitar uma saudação após session.started:

  1. Envie um único novo session.instructions.append com delegation_id: null. Inclua a saudação, o idioma e uma instrução explícita para cumprimentar imediatamente, sem esperar pelo interlocutor, e depois pausar e ouvir. Mantenha as instruções de inicialização existentes.
  2. Aguarde session.instructions.appended, conferindo se o client_event_id corresponde ao seu comando. Trate qualquer rejeição do comando antes de continuar.
  3. Mantenha o áudio de entrada ativo, incluindo o silêncio antes de o interlocutor falar. No WebSocket, continue enviando session.input_audio.append; no WebRTC, mantenha ativa a faixa de áudio de entrada negociada. Acompanhe a transcrição e o áudio de saída para identificar a saudação.

Use o idioma especificado pela sua aplicação até que o interlocutor fale; não o deduza a partir de um nome, número de telefone ou localização. Consulte Criação de prompts para modelos de voz para saber como elaborar prompts.

Para uma saudação que precise seguir as instruções da aplicação, envie essas instruções com session.instructions.append e depois use um session.commentary.append curto para solicitar que o assistente comece. Por exemplo: “Begin the conversation now, following the instructions provided.” Mantenha o áudio de entrada ativo, incluindo o silêncio antes de o interlocutor falar.

As instruções solicitam uma saudação; elas não garantem as palavras exatas nem a reprodução sem interrupções. A API não emite um evento de conclusão da abertura, e a confirmação de recebimento não significa que a saudação foi ouvida. Use a reprodução controlada pela aplicação se o áudio precisar seguir o texto palavra por palavra. Teste sua saudação com os idiomas e as interrupções que sua aplicação suporta.

Transmita um aviso

Use session.instructions.append para solicitar palavras específicas para um aviso falado. session.commentary.append pode parafrasear o texto. Após session.started, por exemplo, envie:

export function sendUpdate(connection) {
  connection.send({
    type: "session.instructions.append",
    event_id: "disclosure_1",
    delegation_id: null,
    content:
      "Immediately say the following disclosure exactly and in full before responding to the caller: This call may be recorded for quality and training purposes.",
  });
}

Mantenha o áudio de entrada ativo conforme descrito em Cumprimente antes que o interlocutor fale. Escolha com cuidado o momento de transmitir o aviso: uma instrução enviada durante a conversa pode interromper uma fala em andamento.

Isso solicita as palavras desejadas; não garante que sejam transmitidas exatamente. Verifique o aviso falado completo e sua reprodução efetiva antes de marcá-lo como transmitido. session.instructions.appended confirma apenas que a instrução foi aceita. Se for necessário transmitir o áudio exato, reproduza pela sua aplicação uma gravação verificada ou um clipe renderizado e controle a saída do GPT-Live durante a reprodução. Consulte Controle a reprodução quando necessário.

Gerencie conversas mais longas

O GPT-Live gerencia automaticamente o contexto durante conversas longas; nenhum parâmetro de configuração é necessário. As instruções fornecidas no início da sessão são preservadas durante toda a compactação. Você não precisa reenviá-las.

A janela de contexto padrão comporta 128.000 tokens, incluindo suas instruções, o texto da conversa e os tokens de áudio que não aparecem na transcrição.

O GPT-Live resume o histórico mais antigo da conversa em segundo plano. Quando o uso do contexto ultrapassa 90%, ele inicia um mecanismo de voz substituto dentro da mesma sessão. O substituto recebe suas instruções originais e até 8.192 tokens do histórico da conversa, contendo mensagens recentes e, quando disponível, um resumo das mensagens mais antigas. Preparar um resumo não altera imediatamente o contexto do mecanismo em execução.

Detalhes mais antigos da conversa podem ser resumidos ou omitidos. Mantenha fatos importantes, ações confirmadas e o estado atual das tarefas na sua aplicação e forneça contexto relevante quando necessário.

Armazene uma sessão e crie um fork

Defina store como true na configuração da sessão, no momento da criação, para salvar uma gravação e permitir seu download ou a criação de um fork posteriormente. O armazenamento tem false como padrão e precisa estar habilitado para seu projeto. Downloads e forks exigem uma gravação armazenada e concluída e uma política de dados que permita a persistência. As gravações expiram após 30 dias. Com zero retenção de dados, store é tratado como false, e o download de gravações e a criação de forks ficam indisponíveis. Consulte Controles de dados do GPT-Live.

Por exemplo, adicione este campo ao objeto session no evento session.start do WebSocket ou na solicitação de criação do WebRTC:

{
  "store": true
}

Salve o ID da sessão de origem recebido em session.started ou na resposta de criação do WebRTC. Um fork inicia uma nova sessão com um novo ID a partir do estado armazenado da sessão. Ele não reabre a conexão original nem reutiliza o ID da sessão de origem.

Inicie o fork pelo transporte que sua aplicação usa:

TransporteInicie o fork
WebSocketConecte-se a wss://api.openai.com/v1/live/sessions/{source_session_id}/fork.
WebRTCEnvie uma nova oferta SDP para POST /v1/live/sessions/{source_session_id}/fork. Aplique a resposta transport.sdp retornada à nova conexão entre pares.

Um fork herda a configuração da sessão armazenada, sujeito às regras de transporte abaixo. Para um fork via WebSocket, envie session.start com o objeto obrigatório session; {} não fornece nenhuma substituição de configuração. Não forneça um novo modelo nem repita as instruções ou a entrada originais. Você pode substituir store, as configurações de delegação do Responses e o novo formato de áudio do WebSocket. Forks via WebRTC podem substituir store, as configurações de delegação do Responses e as permissões do cliente frontend. Ao omitir store em um fork, ele herda a configuração da sessão de origem.

Um fork via WebSocket não herda o formato de áudio de origem: defina audio.format explicitamente ou use o padrão PCM16 a 24 kHz. Ele também descarta as permissões herdadas do canal de dados do frontend. Forks via WebRTC negociam seu formato de áudio e rejeitam audio.format; eles preservam as configurações de permissão do frontend, a menos que você as substitua.

Aguarde session.started antes de enviar outros comandos WebSocket. O WebRTC é iniciado pela solicitação HTTP e não deve receber um segundo session.start no seu canal de dados.

Inicie um fork via WebSocket

Defina OPENAI_API_KEY. Os exemplos usam o ID da sessão de origem armazenada, salvo pela sua aplicação. Eles confirmam a inicialização e depois encerram o fork. Para continuar a conversa, envie e receba áudio após session.started usando o fluxo de conexão WebSocket. Consulte a referência de fork via WebSocket para ver os campos e eventos de inicialização.

import OpenAI from "openai";
import { ForksWS } from "openai/resources/live/forks/ws";

async function forkSession(sourceSessionId) {
  const ws = new ForksWS(new OpenAI(), { session_id: sourceSessionId });
  let finalized = false;
  try {
    for await (const event of ws) {
      if (event.type === "open") {
        ws.send({ type: "session.start", session: {} });
      } else if (event.type === "error") {
        throw event.error;
      } else if (event.type === "message") {
        if (event.message.type === "session.started") {
          console.log("Fork ready:", event.message.session.id);
          // This startup example closes the fork after confirming it is ready.
          ws.send({ type: "session.close" });
        } else if (event.message.type === "session.closed") {
          console.log("Final usage:", event.message.usage);
          finalized = true;
          break;
        }
      }
    }
    if (!finalized) throw new Error("Connection closed before session.closed");
  } finally {
    ws.close();
  }
}

Inicie um fork via WebRTC

Crie uma nova oferta SDP no seu frontend e envie-a ao seu backend. Os exemplos de backend a seguir usam essa oferta e o ID da sessão de origem armazenada, salvo na sua aplicação:

import OpenAI from "openai";

async function forkSession(sourceSessionId, offerSdp) {
  const client = new OpenAI();
  const fork = await client.live.sessions.fork(sourceSessionId, {
    transport: { type: "webrtc", sdp: offerSdp },
  });
  console.log(JSON.stringify(fork));
}

Retorne a resposta ao frontend, aplique transport.sdp como resposta da nova conexão entre pares e guarde o novo session.id. Mantenha a chave de API no backend.

Use o novo ID de sessão nas conexões de canal lateral e nos controles de sessão posteriores. Mantenha o estado das tarefas da aplicação separadamente: restaurar o estado da conversa não confirma que uma ação pendente no backend foi concluída. Confira os resultados incertos antes de tentar executar uma ação novamente. Se você não tiver uma sessão armazenada para criar um fork, inicie uma nova sessão com o histórico salvo.

Baixar uma gravação

Após a finalização da gravação armazenada, baixe o áudio com GET /v1/live/sessions/{session_id}/content. A resposta contém dados binários em formato WAV estéreo, com o áudio de entrada no canal esquerdo e o áudio de saída no canal direito. Os exemplos usam o ID da sessão armazenada fornecido pela sua aplicação e gravam a resposta em recording.wav à medida que ela é recebida:

import OpenAI from "openai";
import { createWriteStream } from "node:fs";
import { pipeline } from "node:stream/promises";

async function downloadRecording(sessionId) {
  const client = new OpenAI();
  const response = await client.live.sessions.downloadRecording(sessionId);
  if (!response.body) throw new Error("Recording response has no body");
  await pipeline(response.body, createWriteStream("recording.wav"));
}

Tratar erros e encerrar a sessão

Continue lendo os eventos da sessão até que ela seja finalizada. Diferencie um comando rejeitado, uma falha de conexão e uma sessão concluída para que sua aplicação possa se recuperar adequadamente.

Tratar comandos rejeitados

Leia os eventos error junto com as confirmações de recebimento. Quando presente, error.client_event_id identifica o comando enviado que falhou:

{
  "type": "error",
  "event_id": "event_error",
  "error": {
    "type": "invalid_request_error",
    "code": "immutable_field_update",
    "message": "The delegation type cannot change after session startup.",
    "param": "session.delegation.type",
    "client_event_id": "event_update"
  }
}

Um código de erro pode ser null, e um erro pode não incluir um ID de evento do cliente. Trate esses casos sem presumir que um comando foi bem-sucedido. Em caso de erro relacionado a um campo imutável, mantenha a configuração atual ou crie uma nova sessão com as configurações desejadas.

Lidar com a moderação

A moderação pode afetar a sessão de duas maneiras:

  • Alguns eventos de moderação encerram a sessão.
  • Outros interrompem o áudio do assistente pelo restante da fala atual e emitem um evento error sem encerrar a sessão.

Leia os eventos error mesmo durante a reprodução do áudio. Não presuma que todo erro de moderação encerra a sessão ou que uma interrupção de áudio significa que a conexão falhou. Mantenha o estado da aplicação alinhado ao ciclo de vida da sessão e não marque uma mensagem falada que foi interrompida como totalmente entregue. Os mecanismos de proteção da conversa no nível da aplicação continuam separados desse comportamento de moderação integrado.

Uso e encerramento ordenado

session.usage.updated informa a duração acumulada de voz em segundos:

{
  "type": "session.usage.updated",
  "event_id": "event_usage_1",
  "usage": { "seconds": 12 },
  "context_window": { "usage_ratio": 0.42 }
}

Esses valores são registros do total em cada momento, não incrementos a serem somados. O uso de tokens no backend é contabilizado separadamente; preserve os dados de uso contidos nos eventos aninhados de conclusão do Responses. Consulte Otimização de custos para saber mais sobre a contabilização do uso.

Para encerrar de forma ordenada:

  1. Conclua todo o trabalho delegado ao Responses de que sua aplicação precisa, incluindo resultados de funções pendentes e continuações de respostas.
  2. Registre o ouvinte de session.closed antes de enviar session.close.
  3. Envie session.close e pare de enviar novos trabalhos para a sessão. Mantenha ativos a conexão WebSocket ou WebRTC, o canal de dados e qualquer receptor de canal lateral conectado enquanto os eventos pendentes da sessão são recebidos.
  4. Leia os valores finais de usage.seconds e reason, além do instantâneo da sessão, em session.closed. Preserve os dados de uso do trabalho delegado já recebidos por meio de response.event.
  5. Libere os recursos de transporte e os dispositivos de áudio após esse evento. Se a finalização falhar ou exceder o tempo limite definido pela sua aplicação, informe que a finalização ficou incompleta e libere os recursos.

O envio de session.close cancela as solicitações do Responses na fila e rejeita comandos posteriores. Uma resposta ativa pode ser concluída, mas uma resposta que aguarda o resultado de uma função não pode continuar após o início do encerramento. Decida separadamente se deseja concluir ou cancelar o trabalho que sua aplicação executa por meio da delegação ao cliente.

O evento session.closed confirma a finalização; a sessão incluída nele é um instantâneo da configuração. O fechamento de um socket, por si só, não confirma o sucesso, e um código de fechamento do transporte após um evento final válido não invalida a finalização. Fechar a conexão WebRTC imediatamente após enviar o comando pode impedir a entrega do evento final.

O campo reason do evento final explica por que a sessão foi encerrada:

MotivoSignificado
close_requestedSua aplicação enviou session.close ou chamou o endpoint de encerramento da chamada.
expiredA sessão atingiu o limite de duração.
contentUm filtro de segurança encerrou a sessão.
remote_hangupA conexão principal remota foi encerrada de forma ordenada.
connection_lostA conexão principal ou a conexão com o servidor de origem foi perdida inesperadamente.

Um evento session.closed confirma a finalização mesmo quando o motivo é uma perda de conexão ou um encerramento por segurança. Sem esse evento, o uso final permanece sem confirmação. Uma sessão armazenada pode demorar mais para ser finalizada enquanto sua gravação é salva; escolha um tempo limite para a aplicação que leve em conta o armazenamento.

Recuperar-se de uma falha de conexão

Um erro HTTP na criação da sessão significa que ela não chegou a emitir session.started. Trate os erros de inicialização separadamente dos erros em uma sessão em execução. Se uma conexão em execução falhar antes de session.closed, preserve os dados de uso mais recentes observados e marque o uso final como não confirmado.

Se houver uma sessão armazenada disponível, crie um fork dela para iniciar uma nova sessão a partir do estado salvo. Caso contrário, crie uma sessão substituta com o histórico salvo relevante. Confira as ações pendentes no backend antes de tentar executá-las novamente e descarte resultados desatualizados da sessão anterior. Restaure o estado da aplicação explicitamente, sem presumir que uma nova conexão retoma a sessão anterior ou o trabalho pendente dela.