# Conversational Agent: passo a passo

Da documentação da API do Lero: https://lero.studio/docs#agente-guia. Tudo num arquivo só: https://lero.studio/docs/llms-full.txt.

O Conversational Agent é uma ligação de voz em tempo real. O HTTP só faz o discovery e o signaling; depois, o áudio e os eventos vão peer-to-peer por WebRTC. Latência típica de ~1 s, com barge-in (a pessoa interrompe e o agente para).

1. **Discover.** `GET /v1/agents` devolve as versões, os LLMs e as vozes que a sua chave pode usar.
2. **Connect.** No client WebRTC, crie o data channel `chat` antes da offer, adicione 1 track de áudio (o microfone) e espere o ICE gathering.
3. **Signaling.** Mande a SDP offer para `POST /v1/agents/conversation` (do seu backend, com a chave) e aplique a SDP answer. A conversa começa e o agente cumprimenta.
4. **Custom agent (opcional).** No mesmo POST, `instrucoes` (system prompt), `conhecimento` (knowledge base), `abertura`, `palavras` e os ajustes fazem o agente ser o seu.
5. **Live context (opcional).** Durante a ligação, mande pelo `chat` o que o agente precisa ver: o código de um live coding, o carrinho, a tela.
6. **Events.** Leia pelo `chat` o transcript, o estado e a latência de cada turno.
7. **Hang up.** Feche a `RTCPeerConnection`.

Live context e controle, pelo data channel (toda mensagem precisa do campo `type`):

```javascript
// live context: one panel per key, always the latest version (send the full text on change, ~every 2 s)
chat.send(JSON.stringify({ type: "lero-contexto", chave: "codigo", texto: editor.getValue() }));
chat.send(JSON.stringify({ type: "lero-contexto", chave: "testes", texto: "3/5 testes passaram", responder: true }));

// system note: the person does not hear it; the agent acts on the next free turn (responder: false only stores it)
chat.send(JSON.stringify({ type: "lero-instrucao", texto: "O tempo da fase 2 acabou. Passe para a fase 3." }));

// exact utterance, bypasses the LLM
chat.send(JSON.stringify({ type: "lero-falar", texto: "Faltam 5 minutos." }));
```

| mensagem | campos | o que faz |
|---|---|---|
| `lero-contexto` | `chave` (até 60), `texto` (até 20 mil), `responder` | Um painel vivo por chave (até 8). Só a versão mais nova entra na próxima resposta. `texto` vazio apaga. |
| `lero-instrucao` | `texto` (até 4 mil), `responder` | System note que a pessoa não ouve: troca de fase, tempo, dica. |
| `lero-falar` | `texto` (até 2 mil) | O agente fala exatamente o texto, sem passar pelo LLM. |

Events que chegam pelo `chat` (campo `tipo`):

| tipo | campos |
|---|---|
| `estado` | `estado`: conectado, na_fila, ouvindo, pensando, falando, aviso_fim, encerrada; `motivo` no fim |
| `fala` | `papel` (pessoa ou agente), `texto`, `final`, `interrompido`: o transcript ao vivo |
| `latencia` | `total_ms` e as etapas do turno |
| `ignorado` | um backchannel curto ("uhum") que não interrompeu o agente |

A ligação acaba quando você fecha a conexão, na despedida por silêncio (se `silencio_s` estiver ligado) ou depois de 10 minutos sem fala. Toda ligação fica gravada (áudio, transcript e a config do agente) para a revisão de qualidade.
