Files
tia_regional_xai_tts_pool/docs/refactor-log.md
2026-08-21 08:37:51 -03:00

30 KiB

Refactor Log

Este arquivo registra o que mudou a cada etapa do refactor incremental.

Nota:

  • as entradas 000 a 010 foram escritas antes da consolidacao da estrutura atual do repositorio
  • por isso, varias delas ainda referenciam caminhos antigos sem o prefixo src/
  • a partir da entrada 011, os caminhos refletem o layout atual da raiz + src/

Como preencher

Para cada mudanca relevante, registrar:

  • data
  • objetivo
  • arquivos alterados
  • comportamento preservado
  • comportamento alterado
  • risco conhecido
  • validacao executada
  • proximo passo

Entrada 000 - Baseline documental

  • Data: 2026-03-27
  • Objetivo: criar uma base de documentacao viva para acompanhar o refactor incremental
  • Arquivos alterados:
    • README.md
    • docs/README.md
    • docs/refactor-plan.md
    • docs/refactor-log.md
    • docs/api-overview.md
  • Comportamento preservado: nenhum codigo de execucao foi alterado
  • Comportamento alterado: nenhum
  • Risco conhecido: a documentacao precisa ser mantida junto das mudancas, senao perde valor
  • Validacao executada: revisao manual do conteudo criado
  • Proximo passo: iniciar Fase 1 com extracao dos adapters de pipeline, speech, bridge e export

Entrada 001 - Fase 1 / adapters extraidos

  • Data: 2026-03-27
  • Objetivo: extrair boundaries de pipeline, speech, bridge e export sem mudar o comportamento publico da API
  • Arquivos alterados:
    • app/livekit/main.py
    • app/livekit/adapters/pipeline_adapter.py
    • app/livekit/adapters/speech_service.py
    • app/livekit/adapters/bridge_gateway.py
    • app/livekit/adapters/export_service.py
    • docs/refactor-log.md
  • Comportamento preservado:
    • contrato do websocket do bridge
    • fluxo STT -> pipeline -> TTS
    • notificacao DONE para o bridge
    • exportacao final de sessao
  • Comportamento alterado:
    • nenhum comportamento publico planejado
    • app/livekit/main.py passa a delegar responsabilidades para adapters
  • Risco conhecido:
    • como a extracao preserva a logica inline, ainda existe acoplamento forte no runtime
    • faltam testes automatizados de regressao para interrupcao, idle nudge e finalizacao
  • Validacao executada:
    • revisao manual do diff
    • validacao sintatica prevista apos a extracao
  • Proximo passo:
    • reduzir nonlocal no runtime com um CallRuntime explicito
    • preparar o terreno para policies e scheduler unificados

Entrada 002 - Fase 2 / runtime explicito

  • Data: 2026-03-27
  • Objetivo: encapsular o fluxo da chamada em um CallRuntime com CallState explicito, reduzindo estado implícito e nonlocal em app/livekit/main.py
  • Arquivos alterados:
    • app/livekit/main.py
    • app/livekit/runtime/state.py
    • app/livekit/runtime/call_runtime.py
    • docs/refactor-log.md
    • docs/api-overview.md
  • Comportamento preservado:
    • contrato do websocket do bridge
    • fluxo STT -> pipeline -> TTS
    • idle nudge, interrupcao e finalizacao continuam com a mesma logica operacional
    • exportacao e notificacao DONE continuam sendo disparadas pelo agent
  • Comportamento alterado:
    • app/livekit/main.py passa a ser majoritariamente wiring do session e construcao do runtime
    • o estado mutavel da chamada fica concentrado em CallState
  • Risco conhecido:
    • as regras ainda nao foram transformadas em policies puras; a logica segue acoplada ao runtime, apenas mais organizada
    • ainda faltam testes automatizados para cenarios concorrentes de fala, interrupcao e fechamento
  • Validacao executada:
    • revisao manual do diff
    • PYTHONDONTWRITEBYTECODE=1 python3 -m py_compile app/livekit/main.py app/livekit/adapters/bridge_gateway.py app/livekit/adapters/export_service.py app/livekit/adapters/pipeline_adapter.py app/livekit/adapters/speech_service.py app/livekit/runtime/state.py app/livekit/runtime/call_runtime.py
  • Proximo passo:
    • introduzir command/execution boundaries no runtime
    • preparar a migracao de interrupcao, idle e finalize para policies + scheduler

Entrada 003 - Fase 3 / commands e executor

  • Data: 2026-03-29
  • Objetivo: separar efeitos colaterais do CallRuntime por meio de comandos tipados e um executor dedicado
  • Arquivos alterados:
    • app/livekit/main.py
    • app/livekit/runtime/commands.py
    • app/livekit/runtime/command_executor.py
    • app/livekit/runtime/call_runtime.py
    • docs/refactor-log.md
    • docs/api-overview.md
  • Comportamento preservado:
    • contrato do websocket do bridge
    • fluxo STT -> pipeline -> TTS
    • sequencia de idle nudge, interrupcao e finalizacao
    • integracao com LiveKit, pipeline e export sem troca de contrato
  • Comportamento alterado:
    • CallRuntime deixa de chamar diretamente bridge/export/speech/pipeline para os principais side effects
    • side effects passam a trafegar por comandos (commands.py) executados por RuntimeCommandExecutor
  • Risco conhecido:
    • ainda existe conhecimento de regras dentro de CallRuntime; a extracao atual isola efeitos, mas nao transforma as regras em policies puras
    • agent._ready, agent._run_lock e coordenacao de fila ainda pertencem ao runtime
  • Validacao executada:
    • revisao manual do diff
    • validacao sintatica com python3 -c 'from pathlib import Path; paths = [...]; [compile(Path(p).read_text(), p, "exec") for p in paths]'
  • Proximo passo:
    • extrair policies de interrupcao, idle e finalizacao
    • introduzir scheduler unico para timers e reduzir logica condicional no runtime

Entrada 004 - Fase 4 / policies e scheduler

  • Data: 2026-03-29
  • Objetivo: mover regras de interrupcao, idle e finalize-once para policies dedicadas e centralizar timers em um scheduler unico
  • Arquivos alterados:
    • app/livekit/main.py
    • app/livekit/policies/interrupt_policy.py
    • app/livekit/policies/idle_policy.py
    • app/livekit/policies/finalization_policy.py
    • app/livekit/runtime/scheduler.py
    • app/livekit/runtime/state.py
    • app/livekit/runtime/call_runtime.py
    • docs/refactor-log.md
    • docs/api-overview.md
  • Comportamento preservado:
    • contrato do websocket do bridge
    • fluxo STT -> pipeline -> TTS
    • timers de idle nudge e idle close continuam ativos
    • finalizacao por DONE, room_empty, shutdown_callback e no_user_response continua existindo
  • Comportamento alterado:
    • InterruptPolicy passa a decidir interrupcao por stage e filtro de backchannel
    • IdlePolicy passa a concentrar regras de nudge/close
    • FinalizationPolicy passa a concentrar regras de finalize-once e room-empty
    • TimerScheduler passa a concentrar arm/cancel/token dos timers
    • CallState deixa de carregar estado interno de timers
  • Risco conhecido:
    • o CallRuntime ainda conhece a ordem operacional completa da chamada; as policies reduzem acoplamento, mas ainda nao existe reducer/event engine
    • RuntimeConfig ainda carrega campos hoje parcialmente sobrepostos pelas policies; isso pode ser simplificado em um corte futuro
  • Validacao executada:
    • revisao manual do diff
    • validacao sintatica com python3 -c 'from pathlib import Path; paths = [...]; [compile(Path(p).read_text(), p, "exec") for p in paths]'
  • Proximo passo:
    • avaliar se vale introduzir eventos/comandos mais declarativos no runtime ou parar aqui e estabilizar
    • se seguir, o proximo salto natural e um reducer/event engine ou a evolucao da integracao de IA (llm_node ou agente remoto)

Entrada 005 - Estabilizacao / testes unitarios do runtime

  • Data: 2026-03-29
  • Objetivo: adicionar cobertura automatizada para os cenarios mais criticos do runtime sem depender de LiveKit real
  • Arquivos alterados:
    • tests/__init__.py
    • tests/livekit/__init__.py
    • tests/livekit/test_runtime.py
    • docs/refactor-log.md
  • Comportamento preservado:
    • nenhum contrato publico da API foi alterado
    • nenhum fluxo de audio ou websocket foi modificado
  • Comportamento alterado:
    • o repositorio passa a ter uma suite unitária para policies, scheduler, command executor e cenarios críticos do CallRuntime
  • Risco conhecido:
    • os testes ainda usam doubles/fakes e nao substituem validacao integrada com LiveKit real
    • ainda faltam cenarios mais completos de timer real, callback de room e speech handle real
  • Validacao executada:
    • python3 -m unittest tests.livekit.test_runtime -v
    • python3 -m unittest discover -s tests -v
  • Proximo passo:
    • ampliar cobertura para speech handle real e integracao de callbacks com objetos LiveKit reais, se isso passar a ser area de regressao
    • ou encerrar a fase de estabilizacao e voltar a discutir a evolucao da camada de IA

Entrada 006 - Backend remoto via websocket

  • Data: 2026-03-29
  • Objetivo: permitir trocar a pipeline local por um agent remoto via websocket, preservando o fluxo STT -> IA -> TTS e o runtime atual
  • Arquivos alterados:
    • app/livekit/main.py
    • app/livekit/adapters/agent_backend.py
    • app/livekit/adapters/backend_factory.py
    • app/livekit/adapters/pipeline_adapter.py
    • app/livekit/adapters/remote_agent_ws_adapter.py
    • app/livekit/runtime/command_executor.py
    • requirements.txt
    • tests/livekit/test_remote_agent_ws_adapter.py
    • docs/refactor-log.md
    • docs/api-overview.md
  • Comportamento preservado:
    • contrato do websocket do bridge
    • fluxo de audio com LiveKit e TTS no agent local
    • runtime de interrupcao, idle nudge e finalizacao
    • backend langgraph segue como default
  • Comportamento alterado:
    • o backend da camada de IA passa a ser selecionavel por AGENT_BACKEND
    • quando AGENT_BACKEND=remote_ws, o agent envia cada turno transcrito para um websocket remoto e vocaliza a resposta retornada
    • a finalizacao pode opcionalmente buscar um result remoto via mensagem type=end
    • o bridge agora repassa agent, RouterCallKeyDay, RouterCallKey, ANI, GSM e ID_FATURA para o agent quando esses campos vierem no metadata do cliente
    • o adapter remoto roteia a chamada para endpoints diferentes de acordo com agent (conta, oferta, cobranca)
    • o agent conta passou a usar contrato proprio em websocket com action/payload na entrada e result.content na resposta
  • Risco conhecido:
    • o contrato do websocket remoto ainda e interno e precisa ser homologado com o agent externo real
    • o adapter atual usa conexao websocket por turno, nao uma sessao persistente
    • se o agent remoto nao devolver stage, a politica local dependera do ultimo stage conhecido ou do default configurado
    • o campo timestamp e gerado localmente no momento de cada turno; se o integrador exigir outro formato, isso ainda precisa ser alinhado
  • Validacao executada:
    • testes unitarios do adapter remoto e factory
    • execucao da suite unittest
  • Proximo passo:
    • homologar o contrato do websocket remoto com payload/resposta reais
    • decidir se a conexao remota deve continuar por turno ou evoluir para sessao persistente

Entrada 007 - Cliente web de voz e call_config por chamada

  • Data: 2026-03-30
  • Objetivo: disponibilizar um cliente web para testar o fluxo de voz pelo navegador e permitir overrides de STT, TTS e AGENT por chamada
  • Arquivos alterados:
    • app/ws_gateway/main.py
    • app/ws_gateway/voice_client.html
    • app/ws_gateway/call_config.py
    • app/livekit/main.py
    • app/livekit/call_config.py
    • app/livekit/adapters/backend_factory.py
    • tests/config/test_call_config.py
    • docs/api-overview.md
    • docs/refactor-log.md
  • Comportamento preservado:
    • fluxo principal de audio via /ws/agent
    • bridge continua recebendo start, audio binario e encerrando com stop
    • defaults de STT, TTS e backend continuam vindo de env quando nao houver override
  • Comportamento alterado:
    • /voice-client agora serve um cliente web para capturar microfone e ouvir o audio retornado
    • o start pode carregar call_config com overrides por chamada
    • o agent agora aplica overrides de backend, STT e TTS para a sessao corrente
  • Risco conhecido:
    • o cliente web usa ScriptProcessorNode, que e suficiente para homologacao mas nao e a opcao mais moderna da Web Audio API
    • os providers dinamicos suportados ainda sao os que ja existem no projeto (internal_http e elevenlabs)
  • Validacao executada:
    • testes puros de call_config
    • execucao da suite unittest
  • Proximo passo:
    • se o cliente web passar a ser usado em rotina de homologacao, vale migrar a captura/playback para AudioWorklet
    • se surgirem novos providers de STT/TTS, plugar nas factories por chamada

Entrada 008 - Timeline estruturada por chamada

  • Data: 2026-03-30
  • Objetivo: criar observabilidade ponta a ponta para entender o caminho bridge -> livekit -> stt -> backend -> tts -> stop por chamada
  • Arquivos alterados:
    • app/utils/call_timeline.py
    • app/ws_gateway/main.py
    • app/livekit/main.py
    • app/livekit/runtime/call_runtime.py
    • app/livekit/adapters/backend_factory.py
    • app/livekit/adapters/pipeline_adapter.py
    • app/livekit/adapters/remote_agent_ws_adapter.py
    • app/livekit/adapters/bridge_gateway.py
    • app/providers/stt_internal_livekit.py
    • tests/utils/test_call_timeline.py
    • docs/api-overview.md
    • docs/refactor-log.md
  • Comportamento preservado:
    • contrato publico de WS /ws/agent
    • fluxo de audio ja existente entre cliente, bridge, LiveKit e agent
    • backends de IA, STT e TTS seguem com a mesma responsabilidade funcional
  • Comportamento alterado:
    • bridge e agent agora escrevem uma timeline estruturada em jsonl compartilhada por chamada
    • a timeline usa o mesmo timeline_id e o mesmo origin_unix_ms entre os dois processos para manter a ordem relativa dos eventos
    • o bridge passou a registrar eventos como ready_sent, dispatch_started, agent_join, client_audio_enabled, done_packet_received e call_end
    • o agent passou a registrar eventos como user_transcript_final, pipeline_run_started, pipeline_run_completed, tts_stage_started, interrupt_marked, finalize_started e finalize_completed
    • o provider de STT agora registra etapas de reconhecimento (stt_recognize_started, stt_vosk_completed, stt_http_completed)
    • o backend remoto por websocket agora registra remote_agent_request e remote_agent_response
  • Risco conhecido:
    • a timeline registra payloads de request do backend remoto, o que aumenta a verbosidade e pode expor dados sensiveis em ambiente de debug
    • o arquivo jsonl e compartilhado entre dois processos locais; o uso atual com flock e suficiente para dev/homologacao, mas nao substitui observabilidade centralizada
  • Validacao executada:
    • py_compile dos arquivos alterados
    • teste unitario novo de timeline
    • execucao completa da suite unittest
  • Proximo passo:
    • decidir se a timeline deve continuar sempre habilitada em dev ou ficar atras de flag por ambiente
    • se a homologacao exigir, adicionar visualizador simples da timeline no cliente web

Entrada 009 - Fake remoto para homologacao via UI

  • Data: 2026-03-30
  • Objetivo: permitir testar o fluxo STT -> remote_ws -> TTS pela UI mesmo sem o agent remoto real estar de pe
  • Arquivos alterados:
    • app/ws_gateway/fake_remote_agent.py
    • app/ws_gateway/main.py
    • app/ws_gateway/voice_client.html
    • app/livekit/adapters/backend_factory.py
    • tests/ws_gateway/test_fake_remote_agent.py
    • tests/livekit/test_remote_agent_ws_adapter.py
    • docs/api-overview.md
    • docs/refactor-log.md
  • Comportamento preservado:
    • backend remote_ws continua exigindo URL real quando selecionado
    • o contrato do adapter remoto segue o mesmo
  • Comportamento alterado:
    • o bridge agora expoe WS /fake-agent/ws
    • a UI ganhou a opcao remote_ws_fake
    • quando remote_ws_fake e selecionado, o agent local aponta para REMOTE_AGENT_WS_FAKE_URL ou usa por padrao ws://127.0.0.1:8000/fake-agent/ws
    • o fake responde nos contratos conta e generico, com progressao simples de stages e encerramento por palavras-chave como encerrar, obrigado e tchau
  • Risco conhecido:
    • o fake nao simula comportamento de negocio real; ele serve apenas para homologacao tecnica do fluxo de voz
    • o fake e stateless por conexao, entao a progressao depende do stage enviado pelo agent local
  • Validacao executada:
    • testes unitarios do fake remoto
    • testes do backend fake no adapter remoto
    • execucao completa da suite unittest
  • Proximo passo:
    • se a homologacao pedir cenarios mais realistas, adicionar scripts por agent (conta, oferta, cobranca) com respostas configuraveis

Template de nova entrada

  • Data:
  • Objetivo:
  • Arquivos alterados:
  • Comportamento preservado:
  • Comportamento alterado:
  • Risco conhecido:
  • Validacao executada:
  • Proximo passo:

Entrada 010 - Correcao do roteamento remote_ws_fake

  • Data: 2026-03-30
  • Objetivo: garantir que a selecao remote_ws_fake na UI nao seja sobrescrita pela URL real configurada em REMOTE_AGENT_WS_URL
  • Arquivos alterados:
    • app/livekit/adapters/backend_factory.py
    • app/livekit/adapters/remote_agent_ws_adapter.py
    • tests/livekit/test_remote_agent_ws_adapter.py
    • docs/api-overview.md
    • docs/refactor-log.md
  • Comportamento preservado:
    • remote_ws continua usando REMOTE_AGENT_WS_URL
    • o adapter remoto continua sendo o mesmo para backend real e fake
  • Comportamento alterado:
    • remote_ws_fake agora prioriza sempre REMOTE_AGENT_WS_FAKE_URL, mesmo quando REMOTE_AGENT_WS_URL existe no ambiente
    • a timeline do adapter remoto agora diferencia backend=remote_ws_fake de backend=remote_ws
  • Risco conhecido:
    • aliases como fake_remote_ws e ws_fake continuam sendo tratados como remote_ws_fake, mas o label emitido na timeline fica canonico como remote_ws_fake
  • Validacao executada:
    • python3 -m unittest tests.livekit.test_remote_agent_ws_adapter -v
    • python3 -m py_compile app/livekit/adapters/backend_factory.py app/livekit/adapters/remote_agent_ws_adapter.py tests/livekit/test_remote_agent_ws_adapter.py
  • Proximo passo:
    • validar na chamada real da UI que o timeline e o request usam ws://127.0.0.1:8000/fake-agent/ws

Entrada 011 - Reorganizacao da raiz e remocao de boilerplate

  • Data: 2026-04-06
  • Objetivo: consolidar a estrutura real do projeto na raiz do repositorio, mantendo src/app e src/agent como codigo-fonte canonico
  • Arquivos alterados:
    • README.md
    • makefile
    • Dockerfile
    • pytest.ini
    • .env.example
    • .gitignore
    • .dockerignore
    • requirements.txt
    • livekit.yaml
    • docs/*
    • tests/*
    • k8s/deployment.yaml
    • remocao de pyproject.toml, uv.lock, README copy.md, configs/config.example.yaml e scripts herdados do boilerplate
  • Comportamento preservado:
    • src/app e src/agent permanecem como raiz do codigo de execucao
    • o bridge FastAPI continua em src/app/ws_gateway/main.py
    • o projeto continua usando PYTHONPATH=src
  • Comportamento alterado:
    • a raiz do repositorio passa a refletir o projeto real, e nao mais o boilerplate original
    • requirements.txt passa a ser a fonte principal de dependencias
    • artefatos de runtime (logs, timeline, __pycache__) deixam de ser versionados
  • Risco conhecido:
    • arquivos de infra legados fora do fluxo principal ainda poderiam carregar suposicoes antigas do boilerplate
    • a migracao para requirements.txt simplifica a operacao, mas remove o lockfile anterior
  • Validacao executada:
    • python3 -m compileall src tests
    • python3 -m pytest tests/utils/test_call_timeline.py -q
  • Proximo passo:
    • revisar a infra auxiliar restante e reduzir ruido operacional na raiz

Entrada 012 - Simplificacao do compose local de observabilidade

  • Data: 2026-04-06
  • Objetivo: transformar o docker-compose.yml em uma stack minima e coerente para Langfuse local
  • Arquivos alterados:
    • docker-compose.yml
  • Comportamento preservado:
    • a stack opcional de Langfuse continua disponivel para uso local
    • a aplicacao principal segue fora do compose, operada via make
  • Comportamento alterado:
    • remocao do servico mongo
    • consolidacao apenas de langfuse-web, langfuse-worker, postgres, redis, clickhouse e minio
    • reducao de duplicacao com anchors para configuracoes compartilhadas
  • Risco conhecido:
    • o compose continua sendo opcional e depende de configuracao explicita do projeto para apontar para Langfuse self-hosted
  • Validacao executada:
    • validacao sintatica do YAML com parser local
  • Proximo passo:
    • se a equipe mantiver uso frequente, considerar alvos dedicados no makefile para subir e derrubar a stack

Entrada 013 - Provider TTS opcional desacoplado do import global

  • Data: 2026-04-06
  • Objetivo: impedir que a falta do SDK do ElevenLabs quebrasse o import do modulo inteiro de TTS
  • Arquivos alterados:
    • src/app/providers/tts.py
    • tests/providers/test_tts.py
  • Comportamento preservado:
    • selecao de provider TTS por configuracao
    • suporte aos providers ja existentes
  • Comportamento alterado:
    • o SDK do ElevenLabs deixa de ser carregado no topo do modulo e passa a ser resolvido sob demanda
    • ausencia do SDK passa a gerar missing_elevenlabs_sdk, em vez de falha de import que derruba testes e providers nao relacionados
  • Risco conhecido:
    • o provider continua opcional, mas a disciplina de dependencias ainda segue concentrada em requirements.txt
  • Validacao executada:
    • python3 -m pytest tests/providers/test_tts.py -q
    • python3 -m pytest tests/adapters/test_azure_tts.py -q
  • Proximo passo:
    • continuar removendo acoplamentos desnecessarios entre providers e entrypoints

Entrada 014 - Remocao de mocks e hardcodes dos pipelines de texto

  • Data: 2026-04-06
  • Objetivo: tirar codigo de demonstracao do caminho produtivo dos endpoints de texto
  • Arquivos alterados:
    • src/app/services/session_context.py
    • src/app/services/text_pipeline.py
    • src/app/services/text_pipeline_stream.py
    • src/app/ws_gateway/main.py
    • tests/services/test_session_context.py
  • Comportamento preservado:
    • os endpoints /ws/text e /ws/text_stream continuam aceitando a mesma sessao de entrada
    • os pipelines continuam recebendo mailing e intro
  • Comportamento alterado:
    • remocao do uso de app.models.mock
    • remocao de protocolo e dados fixos hardcoded nos pipelines
    • introducao de extracao explicita de protocolo via session_context
  • Risco conhecido:
    • se existiam fluxos de dev que dependiam dos mocks antigos, eles passam a precisar de payloads reais
  • Validacao executada:
    • python3 -m pytest -q
    • resultado observado na etapa: 36 passed
  • Proximo passo:
    • consolidar contratos duplicados entre gateway e runtime

Entrada 015 - Unificacao de call_config

  • Data: 2026-04-06
  • Objetivo: eliminar duplicacao entre as implementacoes de call_config do gateway e do runtime LiveKit
  • Arquivos alterados:
    • src/app/common/call_config.py
    • src/app/ws_gateway/call_config.py
    • src/app/livekit/call_config.py
    • tests/config/test_call_config.py
  • Comportamento preservado:
    • API publica de build_call_config(...)
    • API publica de normalize_call_config(...) e resolucao dos campos auxiliares
  • Comportamento alterado:
    • a normalizacao passa a ter um nucleo compartilhado em src/app/common/call_config.py
    • ws_gateway e livekit viram wrappers leves para o mesmo contrato
  • Risco conhecido:
    • qualquer evolucao futura de call_config passa a ter impacto compartilhado entre bridge e agent, o que e desejado, mas exige disciplina de compatibilidade
  • Validacao executada:
    • python3 -m pytest tests/config/test_call_config.py -q
    • python3 -m pytest -q
    • resultado observado na etapa: 36 passed
  • Proximo passo:
    • iniciar a quebra incremental do monolito em src/app/ws_gateway/main.py

Entrada 016 - Extracao do parsing inicial da sessao no bridge

  • Data: 2026-04-06
  • Objetivo: remover do ws_gateway/main.py a logica de parsing da mensagem start, resolucao de mailing e montagem de intro/nudge
  • Arquivos alterados:
    • src/app/ws_gateway/session_start.py
    • src/app/ws_gateway/main.py
    • tests/ws_gateway/test_session_start.py
  • Comportamento preservado:
    • contrato de primeira mensagem type=start
    • geracao de mailing, intro e nudge
    • construcao do contexto do agente remoto a partir de metadata + mailing
  • Comportamento alterado:
    • criacao da dataclass StartSessionContext
    • centralizacao de parse_start_payload, recv_start_message e build_remote_agent_context em modulo proprio
    • /ws/agent, /ws/text e /ws/text_stream passam a consumir um contexto estruturado, e nao uma tuple solta
  • Risco conhecido:
    • o contrato de entrada continua dependente do payload do cliente; a extracao melhora testabilidade, mas nao redefine o protocolo
  • Validacao executada:
    • python3 -m compileall src/app/ws_gateway src/app/services tests/ws_gateway
    • python3 -m pytest tests/ws_gateway/test_session_start.py -q
    • python3 -m pytest -q
    • resultado observado na etapa: 39 passed
  • Proximo passo:
    • extrair o bootstrap da chamada para reduzir ainda mais a responsabilidade do endpoint

Entrada 017 - Extracao do bootstrap da chamada do bridge

  • Data: 2026-04-06
  • Objetivo: separar a preparacao da chamada do runtime do endpoint /ws/agent
  • Arquivos alterados:
    • src/app/ws_gateway/session_bootstrap.py
    • src/app/ws_gateway/main.py
    • tests/ws_gateway/test_session_bootstrap.py
  • Comportamento preservado:
    • geracao de token de acesso ao LiveKit
    • montagem de call_config, remote_agent_context, timeline e dispatch_metadata
    • fallbacks de protocolo e telefone
  • Comportamento alterado:
    • introducao da dataclass BridgeSessionBootstrap
    • centralizacao de room_name, identity, token, protocol, phone_number e dispatch_metadata em um builder dedicado
    • main.py passa a consumir um pacote pronto de bootstrap
  • Risco conhecido:
    • o bootstrap ainda depende de envs e factories externas; a extracao organiza responsabilidade, mas nao muda a politica de configuracao
  • Validacao executada:
    • python3 -m compileall src/app/ws_gateway tests/ws_gateway
    • python3 -m pytest tests/ws_gateway/test_session_bootstrap.py -q
    • python3 -m pytest -q
    • resultado observado na etapa: 41 passed
  • Proximo passo:
    • extrair o ciclo de vida da sessao LiveKit do endpoint

Entrada 018 - Extracao do lifecycle da sessao LiveKit no bridge

  • Data: 2026-04-06
  • Objetivo: remover do endpoint os handlers de participante, o processamento do pacote DONE e o watcher de encerramento
  • Arquivos alterados:
    • src/app/ws_gateway/session_lifecycle.py
    • src/app/ws_gateway/main.py
    • tests/ws_gateway/test_session_lifecycle.py
  • Comportamento preservado:
    • deteccao de entrada e saida do agente remoto
    • processamento do pacote agent.stage com DONE
    • envio de stop para o cliente ao final da chamada
  • Comportamento alterado:
    • criacao de RoomLifecycleState para concentrar agent_participant e done_payload
    • extracao de register_room_lifecycle_handlers(...)
    • extracao de watch_call_done(...)
  • Risco conhecido:
    • o fluxo ainda depende de coordenacao concorrente entre tasks do bridge; a extracao reduz tamanho do endpoint, mas nao muda o modelo de concorrencia
  • Validacao executada:
    • python3 -m compileall src/app/ws_gateway tests/ws_gateway
    • python3 -m pytest tests/ws_gateway/test_session_lifecycle.py -q
    • python3 -m pytest -q
    • resultado observado na etapa: 43 passed
  • Proximo passo:
    • extrair a camada de intro/sinalizacao do bridge

Entrada 019 - Extracao da intro TTS e da sinalizacao de audio no bridge

  • Data: 2026-04-07
  • Objetivo: isolar do endpoint o trecho responsavel por intro TTS, liberacao do audio do cliente, sinalizacao client_audio_enabled e bootstrap do streaming do agente
  • Arquivos alterados:
    • src/app/ws_gateway/session_audio.py
    • src/app/ws_gateway/main.py
    • tests/ws_gateway/test_session_audio.py
  • Comportamento preservado:
    • intro sintetizada antes da liberacao do audio do cliente
    • emissao do controle client_audio_enabled para o agente
    • inicializacao do worker que consome audio do agente quando ele fica pronto
  • Comportamento alterado:
    • extracao de play_intro_to_client(...)
    • extracao de notify_client_audio_enabled(...)
    • extracao de stream_agent_audio_when_ready(...)
    • main.py passa a gerenciar explicitamente a task t_control, em vez de disparar a notificacao como fire-and-forget
    • ajuste de typing para evitar import-time acidental de audioop em testes unitarios do modulo novo
  • Risco conhecido:
    • o caminho quente de audio continua centralizado em main.py; ainda faltam as primitivas de transporte para o arquivo deixar de ser monolitico
  • Validacao executada:
    • python3 -m compileall src/app/ws_gateway tests/ws_gateway
    • python3 -m pytest tests/ws_gateway/test_session_audio.py -q
    • python3 -m pytest -q
    • resultado observado na etapa: 46 passed
  • Proximo passo:
    • extrair as primitivas de transporte de audio e LiveKit (ws_audio_receiver, publish_queue_to_livekit, connect_publish_livekit, stream_agent_audio_to_queue)

Entrada 020 - Validacao do Dockerfile para CI/CD

  • Data: 2026-04-07
  • Objetivo: revisar o Dockerfile frente ao layout atual do projeto e corrigir o principal risco de compatibilidade para pipeline
  • Arquivos alterados:
    • Dockerfile
  • Comportamento preservado:
    • execucao do bridge via uvicorn app.ws_gateway.main:app
    • exposicao da porta 8000
    • PYTHONPATH=/app/src
    • healthcheck em /health
  • Comportamento alterado:
    • troca da base de python:3.13-slim para python:3.12-slim
    • o ajuste foi necessario porque o projeto ainda depende de audioop em src/app/ws_gateway/main.py e src/app/utils/background.py
  • Risco conhecido:
    • o build real da imagem nao conseguiu ser concluido nesta maquina porque nem o daemon Docker nem a conexao efetiva do Podman estavam operacionais no momento da validacao
    • portanto, a validacao foi estrutural e de coerencia do arquivo, nao um smoke test completo de container
  • Validacao executada:
    • revisao manual de Dockerfile, .dockerignore, requirements.txt, makefile e k8s/deployment.yaml
    • tentativa de docker build, bloqueada por daemon indisponivel
    • tentativa de podman build, bloqueada por conexao local com a VM do Podman
  • Proximo passo:
    • executar um build real da imagem assim que houver runtime de containers disponivel no host ou direto no pipeline