613 lines
30 KiB
Markdown
613 lines
30 KiB
Markdown
# 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
|