Resolve duas camadas de problema identificadas em teste end-to-end: 1. Embeddings falhavam com HTTP 404 (/codex/v1/embeddings não existe). Solução: Captain::Llm::EmbeddingService sempre usa OpenAI tradicional via Llm::Config.with_api_key(legacy_settings). ProviderConfig expõe legacy_openai_settings pra isso. 2. Servidor Codex ocasionalmente responde com response.failed + code=server_error (instabilidade transitória). Client agora retenta até 2x com backoff exponencial (0.5s, 1.5s) em erros retryable: HTTP 5xx, server_error no response.failed, ou stream inacabado. Outras correções nesta etapa: - Scenario#agent_model: em modo Codex, ignora CAPTAIN_OPEN_AI_MODEL_SCENARIO (que pode ter gpt-4o legado) e usa ProviderConfig.model. - ExtractionService/ContradictionCheckerService/TranslateQueryService: trocam constantes hardcoded gpt-4o-mini/gpt-4.1-nano por ProviderConfig.light_model (respeitando o provider ativo). - ProviderConfig.DEFAULT_CODEX_MODEL agora é gpt-5.2 (reconhecido pelo RubyLLM; gpt-5.4 não está no catalog do gem). Validado ponta-a-ponta: WhatsApp → Chatwoot → Jasmine → handoff Daniela → faq_lookup com embedding OK → resposta com preços corretos. Docs em docs/captain-codex-oauth.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| _prod_snapshot | ||
| _staging_current | ||
| target | ||
| jasmine_orchestrator.md | ||
| README.md | ||
Captain — prompts versionados
Todo prompt da Jasmine (orchestrator) e dos cenários (Daniela, Maria,
Disponibilidade, etc) vive em arquivos .md aqui. O DB é só espelho.
Estrutura
db/seed_prompts/
├── README.md ← você está aqui
│
├── _prod_snapshot/ ← snapshot dos prompts ATUAIS de produção
│ │ (extraído de iachat_production em 2026-04-22)
│ ├── assistants/ (4 Jasmines: qnn01, primeal, primevl, express)
│ └── scenarios/ (12 cenários, 3 por assistente)
│
├── _staging_current/ ← prompts ATIVOS no staging (iachat-v2)
│ │ que o Rodrigo e Claude revisaram juntos
│ ├── assistants/ (jasmine.md — versão melhorada com saudação nominal)
│ └── scenarios/ (daniela_reservas v3 com pré-reserva, etc)
│
└── target/ ← APLICADO no DB pela migration de seed
├── assistants/
└── scenarios/
Regra simples
_prod_snapshot/= só referência histórica. Não é aplicado._staging_current/= só referência do que testamos. Não é aplicado.target/= source of truth. A migration sincroniza isso no DB.
Arquivos vazios em target/ = a migration não toca aquele prompt.
Útil pra deployar mudanças seletivas (ex: subir só Daniela melhorada
sem mexer na Jasmine de cada unidade).
Workflow de revisão (o que estamos fazendo agora)
Pra cada prompt:
- Olhar
_prod_snapshot/X.md(o que tá em prod hoje) - Olhar
_staging_current/X.md(se existir — versão melhorada) - Decidir o conteúdo final: pode ser igual ao staging, igual ao prod
ou novo. Salvar em
target/X.md. - Quando todos os prompts revisados estiverem em
target/, mergear pra main e deployar — a migration aplica em prod.
Convenção de nomes
Os nomes batem com name/title no banco:
| Slug do arquivo | Captain::Assistant#name |
|---|---|
jasmine_qnn01 |
Jasmine( Qnn01) |
jasmine_primeal |
Jasmine(PrimeAL) |
jasmine_primevl |
Jasmine(PrimeVL) |
jasmine_express |
Jasmine (Express) |
| Slug do cenário | Captain::Scenario#title |
|---|---|
daniela_reservas |
Daniela_Reservas |
disponibilidade_suites |
Disponibilidade de suites |
maria_fotos |
maria_fotos |
outras_unidades |
outras_unidades |
reclamacoes_ouvidoria |
Reclamacoes_Ouvidoria |
Cenários se aplicam a TODAS as unidades cujo arquivo bate. Pra
customizar por unidade, prefixe com <assistant_slug>__:
target/scenarios/daniela_reservas.md→ aplica em todas as 4target/scenarios/jasmine_primeal__daniela_reservas.md→ só PrimeAL (sobrescreve o genérico se ambos existirem)
Estado atual da revisão
Em revisão. target/ está vazio. Nada será aplicado em prod até
preenchermos os arquivos lá.