Pular para o conteúdo principal

Contrato do protocolo SSE

POST /chat/control/stream responde com Server-Sent Events (text/event-stream): uma resposta de longa duração que entrega o texto à medida que ele é gerado, além de eventos estruturados sobre lugares, ações no mapa e rotas.

Esta página define o contrato desse fluxo. Se você usar kaleidr.js, o painel de chat interpreta o fluxo automaticamente, sem precisar desta página. Consulte-a ao criar seu próprio cliente. Há clientes funcionais em Node e Python em Como ler o fluxo; o corpo da requisição está em Endpoints.

/chat/summary/stream e /chat/button/stream usam o mesmo formato de quadro com menos tipos de eventos. Eles são descritos no final desta página.

Antes de o fluxo começar​

Uma requisição rejeitada nunca se transforma em fluxo. Falhas de autenticação, escopo, cota, limite de requisições, validação ou tamanho retornam uma resposta HTTP comum com corpo JSON e status 4xx (Erros). Confira o status primeiro e interprete o corpo como SSE somente quando ele for 200.

A requisição tem limites de tamanho: no máximo 400 mensagens, 64.000 caracteres por mensagem e 200.000 caracteres somados em todas as mensagens. Ultrapassar algum limite retorna 422 com um código como conversation_too_long; um corpo acima de 2 MiB retorna 413. A lista completa está em Endpoints.

Uma resposta bem-sucedida contém estes cabeçalhos:

HTTP/1.1 200 OK
Content-Type: text/event-stream; charset=utf-8
Cache-Control: no-cache, no-transform

Formato dos quadros​

Um quadro tem uma ou duas linhas seguidas de uma linha em branco. As linhas terminam com \n.

event: place
data: {"name": "Louvre Museum", "coordinates": {"lat": 48.8606, "lng": 2.3376}}

data: {"text": "The Louvre sits on the right bank"}

: keep-alive

  • Um quadro identificado contém uma linha event: seguida de uma linha data:.
  • Um quadro de texto contém somente uma linha data: e nenhuma linha event:.
  • Um comentário começa com dois-pontos. O Kaleidr envia : keep-alive como sinal de atividade; ele não contém dados.
  • data: sempre contém um objeto JSON completo em uma única linha. O texto usa UTF-8.

Os blocos recebidos pela rede não correspondem necessariamente aos quadros. Uma leitura pode conter metade de um quadro ou vários. Armazene o que receber em buffer, separe pelas quebras de linha e só processe um quadro quando chegar à linha em branco que o encerra.

Regra de compatibilidade​

Ignore nomes de eventos desconhecidos e campos que você não utiliza. Eventos e campos podem ser adicionados a este contrato sem mudança de versão. Um cliente que falhe ao receber um evento desconhecido deixará de funcionar.

Eventos estáveis​

event:DadosSignificado
(sem nome){ text }Próximo trecho do texto da resposta. Acrescente ao texto existente. Pode conter marcadores [[Name]] ao redor de nomes de lugares.
phase{ type: "phase", phase: "thinking", session_id }A requisição foi aceita e o processamento começou. phase sempre é "thinking".
start{ type: "start", session_id, purpose: "control" }O texto está prestes a começar a ser enviado.
place{ name, coordinates?: { lat, lng }, address?, category?, icon?, source?, id?, unverified? }Um lugar da resposta. Agrupe pelo name; as primeiras coordenadas recebidas para cada nome são definitivas. source: "vendor" identifica um lugar dos dados da organização e source: "map" um lugar já mostrado no mapa publicado.
place_linkedcampos do lugar mais is_update?Mais detalhes de um lugar já enviado. Incorpore ao lugar com o mesmo name; ignore se ainda não o recebeu.
early_actions{ type: "early_actions", actions: [ { type, payload } ], places_count, is_partial: true }Ações de mapa aplicáveis antes de a resposta terminar, enviadas assim que dois ou mais lugares têm coordenadas.
prompt_options{ type: "prompt_options", schema_version, kind, question, allow_free_text, options: [ { label, send_text } ] }Pergunta com escolhas quando a requisição é ambígua. Mostre as opções e envie o send_text escolhido como próxima mensagem do usuário.
route_clear{}Remova as rotas desenhadas. Novas rotas serão enviadas.
route{ type: "route", schema_version, id?, profile, origin, destination, primary, alternatives[], comparison[], stops?, color?, label?, transit?, attribution? }Rota calculada. Em perguntas de direções, chega antes do texto para que o mapa seja desenhado durante a geração da resposta.
end{ type: "end", full_text, places[], actions[], question_type, response_time, total_tokens?, dropped_places? }A resposta está completa. Este é o resultado definitivo.
error{ type: "error", message, code?, partial_text }A resposta falhou. Enviado no lugar de end.
quota{ type: "quota", product, meter, tier, used, limit, reset_at, period } com chave de servidor; { type: "quota", meter, reset_at } com token de sessãoUso dos créditos de IA da organização após a cobrança da chamada. Último evento do fluxo, depois de end ou error. Consulte quota.
: keep-alivelinha de comentárioSinal de atividade após dez segundos de silêncio. Ignore-o, mas conte-o como atividade.

Removido: grounding (2026-09-05). Ele não é mais enviado.

Cartões e camadas de dados em tempo real​

Perguntas sobre fatos em tempo real ou medidos podem acrescentar um destes eventos. Um cartão chega antes do texto; uma camada pode chegar durante ou depois. Eles são adicionais: renderize os que forem compatíveis e ignore os demais. Novos campos podem ser adicionados.

event:DadosEnviado para
weather_cardobjeto com lat, lng, name, temperaturas (temp_c, temp_f), conditions, forecast[] opcionalCondições meteorológicas atuais em um lugar.
weather_layerobjeto com layer, tile_path_template, tile_size, max_zoom, scope, attributionSobreposição de temperatura em uma região.
satellite_cardobjeto com name, norad_id, lat, lng, altitude_km, velocity_kms, observed_atPosição de um satélite identificado pelo nome.
constellation_layerobjeto com group, features[] de { name, norad_id, lat, lng } e track opcionalSatélites próximos ao apresentado no cartão.
building_cardobjeto com lat, lng, name opcional, height_m, num_floorsInformações sobre um edifício.
trees_cardobjeto com lat, lng, count, radius_mÁrvores inventariadas ao redor de um ponto.
heritage_cardobjeto com lat, lng, count, sites[]Locais históricos ao redor de um ponto.
rail_cardobjeto com lat, lng, lines[] e nearest_station opcionalLinhas ferroviárias próximas a um ponto.
arrivals_cardobjeto com lat, lng, stop, departures[], alerts[], attributionPartidas de transporte público em uma parada.
vehicles_layerobjeto com operator, vehicles[], shapes[], attributionPosições dos veículos de transporte público para a parada ou linha do cartão.
streetview_cardobjeto com lat, lng, image_id, image_lat, image_lngImagens ao nível da rua perto de um lugar.

Quando enviados, cinco destes elementos são repetidos em end com o mesmo nome, permitindo que um cliente que perdeu o evento ainda os leia: weather_card, satellite_card, constellation_layer, weather_layer e vehicles_layer (por exemplo, end.weather_card). Os outros cartões não são repetidos em end. Listagens de eventos ao vivo não são disponibilizadas pela API da plataforma: consulte Licenças de dados.

Diagnóstico e experimental (fora do contrato)​

Estes eventos podem aparecer no fluxo, mas não fazem parte do contrato. Não dependa deles.

event:DadosObservações
debug{ scope, … }Diagnóstico interno. Não enviado em requisições normais.
place_name_found{ name, is_early }Aviso antecipado de que um nome de lugar foi mencionado. Use o evento place que chega em seguida.

Ordem dos eventos​

O fluxo passa por estas etapas. As etapas marcadas como opcionais não aparecem em todos os fluxos.

  1. Opcional. Eventos place com source: "vendor": até três lugares dos dados da sua organização quando a chave tem o escopo vendor. Eles são enviados primeiro para que o mapa possa desenhá-los imediatamente.
  2. phase. Sempre o primeiro evento da própria resposta.
  3. Opcional. Comentários : keep-alive enquanto a resposta é preparada.
  4. Opcional. Eventos antes do texto: prompt_options ou route_clear, seguido de route, e um cartão.
  5. start.
  6. Quadros de texto intercalados com place, place_linked, early_actions e, às vezes, route_clear, route e eventos de camadas. Sinais de atividade preenchem os períodos de silêncio.
  7. Opcional. Eventos tardios de place, place_linked, camadas e rotas após o texto terminar.
  8. end ou error.
  9. Opcional. quota.
  10. O servidor fecha a conexão.

Duas consequências para o cliente:

  • end não é o último evento. Continue lendo até o corpo ser encerrado, ou perderá quota.
  • Um fluxo pode fechar sem end e sem error, por exemplo, quando a rede cai. Considere como falha qualquer fluxo encerrado sem evento terminal.

Detalhes dos dados​

Texto e marcadores​

Os quadros de texto contêm somente texto, nunca dados estruturados. O texto pode incluir marcadores de colchetes duplos em nomes de lugares, como near [[Louvre Museum]], que o painel de chat transforma em links para os pinos do mapa. Para mostrar texto simples, remova os colchetes e mantenha o nome.

place​

CampoTipoObservações
namestringChave usada na combinação de registros.
coordinatesobject { lat, lng }Graus decimais. Pode estar ausente. Um lugar mencionado mas não localizado é enviado sem coordenadas e com unverified: true. Não desenhe um pino.
addressstringOpcional.
categorystringOpcional.
iconstringOpcional. Um emoji do lugar.
sourcestringOpcional. "vendor" para um lugar dos dados da sua organização. "map" para um lugar já exibido no mapa publicado: o painel não adiciona outro pino porque o mapa já o desenha.
idstringOpcional. Presente nos lugares provenientes dos seus dados.
unverifiedbooleanOpcional. true quando a localização não foi confirmada.

Um lugar pode conter outros campos. Ignore os que você não usa.

O mesmo nome pode aparecer várias vezes: primeiro com coordenadas e depois com outros detalhes. Mantenha um único registro por nome, nunca mova um pino depois de receber as coordenadas e deixe os eventos posteriores preencherem os outros campos.

Ações​

early_actions.actions e end.actions são listas de { type, payload }.

Tipo de açãoDadosO que fazer
map.fitBounds{ coordinates: [[lng, lat], …], padding, maxZoom, duration }Ajuste a câmera para abranger as coordenadas.
places.highlight{ places: [ { name, lat, lng } ], options }Destaque esses lugares.
map.showRoute{ id, label, profile, coordinates: [[lng, lat], …], distance_m, duration_s, turn_by_turn[], transit?, attribution? }Desenhe a linha e mostre sua attribution.
route.clear{ id? }Remova a rota com esse id, ou todas se não houver id.

Outros tipos de ação podem aparecer. Ignore os que você não reconhece. Observe os dois formatos de coordenadas: um lugar possui coordinates: { lat, lng }, enquanto uma linha é uma lista de pares [lng, lat].

route​

primary contém a linha a ser desenhada: { coordinates: [[lng, lat], …], distance_m, duration_s, turn_by_turn[] }. Cada etapa de turn_by_turn contém text e pode ter direction_type, distance_m, duration_s, lat e lng. origin e destination têm um label cada. alternatives[] contém outras linhas com um route_id, e comparison[] informa o delta_duration_s de cada alternativa em relação à rota principal. Se presente, stops[] contém pontos { lat, lng, name } ordenados de uma rota com várias paradas.

Uma rota rodoviária contém attribution: { text, url, license }. Mostre text com link para url sempre que desenhar a rota. Uma viagem por transporte público traz o crédito da operadora dentro de transit.

Cada evento route tem um id. Desenhar uma rota com um id existente substitui essa rota.

end​

CampoTipoObservações
full_textstringResposta completa. Prefira-a à concatenação dos quadros de texto.
placesarrayLista final ordenada de lugares. Combine-a pelo nome com os lugares já coletados.
actionsarrayAções finais de mapa. Aplique-as; elas substituem early_actions.
dropped_placesarray of stringsOpcional. Nomes enviados antes que não fazem parte da resposta final. Remova seus pinos.
question_typestringRótulo que indica o tipo de pergunta. Apenas informativo.
response_timenumberTempo da resposta em segundos.
total_tokensnumberOpcional. Quantidade de tokens usados, que define o valor cobrado.

error​

event: error
data: {"type": "error", "code": "upstream_stall", "message": "The AI service stopped responding. Please try again.", "partial_text": "The Louvre sits"}

message pode ser exibido ao usuário. partial_text é o texto produzido antes da falha. code aparece em apenas um caso:

CasocodeO que fazer
A resposta parou de progredir ou o fluxo atingiu o comprimento máximo"upstream_stall"Ofereça uma nova tentativa.
Qualquer outra falha durante a respostaausenteMostre message; tentar novamente pode funcionar.

Depois de error, não há end. Ainda pode ocorrer um evento quota.

quota​

Os campos dependem da credencial usada para abrir o fluxo.

CampoTipoChave de servidor ou chave legadaToken de sessão
typetexto, "quota"SimSim
metertextoSimSim
reset_attexto, ISO 8601 com deslocamentoSimSim
producttextoSimNão
periodtextoSimNão
tiertextoSimNão
usednúmeroSimNão
limitnúmeroSimNão

Um token de sessão é usado pelos visitantes de uma página: pode ser obtido de uma chave publicável ou de uma sessão de visitante de um mapa publicado. O evento quota informa quando o período será reiniciado, sem revelar plano, uso nem limite da organização. Um cliente no navegador não deve esperar used ou limit. A mesma regra se aplica ao corpo da resposta 429 quota_exceeded; consulte Cotas e limites de requisições.

Sinais de atividade e tempos limite​

ComportamentoValorO que o cliente deve fazer
Sinal de atividade do fluxo de chatUm comentário : keep-alive após dez segundos sem outra saídaReinicie o temporizador de inatividade ao receber quaisquer bytes, inclusive comentários.
Conexão inativaUma conexão sem dados por cerca de um minuto pode ser fechada durante o transporteDefina um tempo limite de inatividade (leitura) de 30 a 60 segundos. Não use um tempo limite total curto.
Tempo até o primeiro textoPode levar dezenas de segundos em perguntas difíceisMostre o progresso a partir de phase; não interprete a espera como falha.
Duração máxima do fluxoCerca de dez minutos, quando o servidor envia error com upstream_stallDefina um tempo limite total um pouco maior que dez minutos como proteção.

Interrupção de fluxos e cobrança​

Feche a conexão para interromper o fluxo. O servidor percebe isso em cerca de dez segundos e para de gerar a resposta.

  • Um fluxo concluído é cobrado pelos tokens usados na resposta, informados em end.total_tokens.
  • Um fluxo interrompido ou com falha antes de terminar é cobrado por uma estimativa. Ela corresponde, no mínimo, ao tamanho da conversa enviada na requisição ou é calculada a partir do texto já transmitido. Por isso, pode superar a reserva inicial feita quando a requisição foi aceita: encerrar a conexão no primeiro quadro não torna gratuita uma conversa longa.
  • Lugares dos seus próprios dados (source: "vendor") não entram na cobrança.

Uma nova tentativa é outra requisição e será cobrada novamente. Consulte Cotas e limites de requisições.

Fluxos de resumos e botões​

Esses dois endpoints alimentam o cartão de lugar no Kaleidr Chat. Eles usam o mesmo formato de quadro, os mesmos quadros de texto sem identificação e o mesmo evento quota final. Diferem do fluxo de chat em três pontos: não enviam phase, não enviam eventos de lugar ou ação e não enviam sinais de atividade. Use tempo limite de inatividade de 60 segundos.

Ambos rejeitam campos longos demais antes de iniciar com 422 field_too_long e ignoram campos que não listam: consulte Endpoints. Se um deles for interrompido ou falhar, o custo será estimado com base no texto já enviado e nunca será maior que a reserva inicial.

POST /chat/summary/stream, para um lugar:

  1. Opcional. address com dados { type: "address", address, source }
  2. start com dados { type: "start", poi_type }
  3. Opcional, podendo se repetir. url com dados { type: "url", website, source }
  4. Quadros de texto com dados { text }
  5. end com dados { type: "end", full_text, summary, poi_type, category, city, country, sources[], website?, total_tokens? }, ou error com dados { type: "error", message, partial_text }
  6. Opcional. quota

POST /chat/summary/stream, para um edifício (type: "building"):

  1. start com dados { type: "start", address }
  2. Quadros de texto
  3. end com dados { type: "end", full_text, parsed, total_tokens? }, ou error
  4. Opcional. quota

POST /chat/button/stream:

  1. start com dados { type: "start", query_type }
  2. Quadros de texto
  3. end com dados { type: "end", full_text, reply, query_type, first_token_ms, total_ms, total_tokens? }
  4. Opcional. quota

O fluxo de botões não tem evento error. Se falhar depois de começar, a conexão fecha sem end. Uma falha antes de começar retorna HTTP 500 com {"detail": "Button chat stream error"}.

POST /spot/overview/stream envia os quadros de resumo de lugar descritos acima, precedidos de um quadro place com dados { type: "place", name }: o nome completo do local ou região descrito, como "Springfield, Ohio, United States of America", para rotulá-lo ou copiá-lo. Ele chega antes de qualquer outro quadro e pode estar ausente. Não é o evento place do stream de chat e não traz coordenadas. Para um ref que não pode descrever, envia um único quadro error com dados { type: "error", message, ref } em vez do resumo. Consulte Endpoints.

Páginas relacionadas​