teqo-backup/docs/plans/worktree-launch-default-llm-max-gateway-impl.md
2026-08-23 16:08:12 -03:00

91 lines
9.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Impl: Worktree launch default → LLM max via Vercel AI Gateway
Status: rascunho
Atualizado em: 2026-08-23
Issue: #784
Intenção: docs/plans/worktree-launch-default-llm-max-gateway.md
Appetite restante: ~0,5–1 dia (ajustado da intenção: mudança é config-only, sem migration, sem code além da constante)
## Leitura da intenção
- **Outcome:** o default de launch do worktree opencode (`pnpm worktree next/plan/new`) passa a rotear o DeepSeek pela rota do **Vercel AI Gateway** (`vercel/deepseek/deepseek-v4-flash` — cache/estabilidade/failover) em vez da rota direta atual (`deepseek/deepseek-v4-flash`), o provider fica exposto no `opencode.json` do repo e as variantes low/high/**max** ficam disponíveis — verificável pela linha de launch emitida pelo preset e pelos testes unitários atualizados.
- **O que NÃO negociar:** anti-goals da intenção — NÃO mudar o cardápio de execução de Issues (`work-issue.md`/`plan-issue.md` nem o pin de `opencodeCommands.unit.spec.ts`); NÃO tocar no `~/.config/opencode/opencode.jsonc` global do humano; NÃO editar docs históricos (`docs/plans`, `docs/CHANGELOG-AGENTS.md:208,212` congelado). Fix de variantes é **config-only** em `opencode.json` — sem migration, sem code.
- **O que reavaliar:** a hipótese de produto "a sessão **abre** com a variante max". Verificação ao vivo (opencode 1.18.21): o TUI (`opencode <dir> --model X --auto`) não tem flag `--variant` (só `opencode run` tem; `--model` aceita estritamente `provider/model`, sem sufixo de variante). A variante não é forçável na linha de launch — ela é **selecionável no TUI** (keybind variant_cycle) e **sticky** por model key (`~/.local/state/opencode/model.json`), com fallback para `model.request.variant` do catálogo. A intenção é atendida expondo as variantes no override + roteando o preset pelo gateway; a linha de launch é a verificação primária aceita.
## Abordagem recomendada
```mermaid
flowchart LR
P["pnpm worktree next/plan/new"] --> L["scripts/lib/worktree.mjs\nOPENCODE_PRESET_MODEL = vercel/deepseek/deepseek-v4-flash"]
L --> D["opencodeLaunchDirective (scripts/lib/worktree.mjs:145)\nlinha de launch --model vercel/deepseek/deepseek-v4-flash"]
D --> T["TUI opencode"]
C["opencode.json\nprovider.vercel + variants low/high/max"] --> T
T -->|"max (sticky via model.json)"| G["Vercel AI Gateway\ncache / estabilidade / failover"]
```
**Opções consideradas:** A | B | C
**Recomendação:** B — mudar a constante single-source do preset para a rota do gateway (`vercel/deepseek/deepseek-v4-flash`) e expor as variantes low/high/max via override do model config no `opencode.json` do projeto (bloco `provider.vercel.models["deepseek/deepseek-v4-flash"].variants`, max com `reasoningEffort: "max"`). É a única opção que atende o outcome dentro das capacidades reais do TUI, preserva o cardápio de execução intacto, é verificável (linha de launch + testes unit) e cabe no appetite (config-only). O override foi validado ao vivo (`opencode debug config` mostra o override; `opencode run --model vercel/deepseek/deepseek-v4-flash --variant max` funciona).
**Rejeitadas:**
- **A — agente default com `variant: max`** (`model.agent`/default): muda o comportamento de launch de **todas** as sessões do repo e força a variante por fora do TUI, arriscando o cardápio de execução de Issues (que pina `model: deepseek/deepseek-v4-flash` no frontmatter dos comandos) e o próprio modelo de descoberta no TUI. Rejeitada porque é mais intrusiva do que a intenção pede e fere o "config-only" (variante no default muda a experiência de todo mundo, não só o preset).
- **C — flag `--variant` na linha de launch** (`--model ...:max` ou `--variant max`): o TUI do opencode não suporta (`tui.ts` só expõe `--model`; formato estritamente `provider/model`). Verificado ao vivo (erro de servidor em `:max`). Rejeitada por impossibilidade técnica upstream.
### Componentes / mudanças
- **`OPENCODE_PRESET_MODEL`** (`scripts/lib/worktree.mjs:28`): valor → `'vercel/deepseek/deepseek-v4-flash'`; comentário `:23-26` atualizado para "preset → rota do Vercel AI Gateway". É a **única** fonte da string (OPS26); emitida em `opencodeLaunchDirective` (`:145`) — nenhum outro código lê/duplica o literal.
- **`opencode.json`** (`:10-34`): adicionar o provider `vercel` **ao lado** de `cheapest-inference` (não substituir) com override do model config:
```json
"vercel": {
"models": {
"deepseek/deepseek-v4-flash": {
"variants": {
"low": { "reasoningEffort": "low" },
"high": { "reasoningEffort": "high" },
"max": { "reasoningEffort": "max" }
}
}
}
}
```
(variantes exatamente como no fix de variantes da intenção; o provider `vercel` é built-in/models.dev, credencial do gateway já no ambiente — sem npm/options adicionais.)
- **`tests/unit/worktree.unit.spec.ts`** (`:151,159,165,171,177,180,185,196`): atualizar os 8 literais da linha de launch para `vercel/deepseek/deepseek-v4-flash`; `:185` pina a constante (`OPENCODE_PRESET_MODEL`) — trocar o literal esperado. **NÃO** mexer em `tests/unit/opencodeCommands.unit.spec.ts:36-38` (pina o frontmatter dos comandos de execução — anti-goal).
- **Textos (string atualizada, sentido OPS26 preservado — "preset é constante em `scripts/lib/worktree.mjs`"):**
- `scripts/worktree.mjs:27` (docblock) e `:778` (help console.log)
- `.agents/shell/worktree.sh:10` (comentário header)
- `.agents/skills/worktree-next-issue/SKILL.md:34` (texto do skill)
- **Migration:** sem migration — config/tooling apenas; nenhum schema de Payload muda, `pnpm migrate`/`migrate:create` não se aplicam.
- **Access / Consent:** N/A — não há collection nem dado de cidadão envolvido; não afeta login de campanha nem LGPD.
- **UI:** N/A — TUI do opencode é consumidor, não produto deste plano (nenhum componente Next/Payload do repo muda).
### Dados → forma (se aplicável)
N/A — tooling. Não há dado de negócio sendo modelado: a mudança é uma constante de config + bloco de provider no `opencode.json`. (Perguntas de data-presentation não se aplicam.)
## Fases verificáveis
1. **Constante + opencode.json + testes** — `scripts/lib/worktree.mjs:23-28`, `opencode.json` (bloco `provider.vercel`), `tests/unit/worktree.unit.spec.ts` (8 literais + pin `:185`). Quota: maior parte do appetite.
2. **Textos** — `scripts/worktree.mjs:27,:778`, `.agents/shell/worktree.sh:10`, `.agents/skills/worktree-next-issue/SKILL.md:34`. Quota: resto do appetite.
3. **Gates** — `pnpm test:unit` (foco em `tests/unit/worktree.unit.spec.ts`, opcionalmente com `-t` no spec); `pnpm gate:fast` (lint + typecheck + test:unit); validação manual: `opencode debug config` mostra o provider `vercel` + variants do override, e um launch real de teste (`pnpm worktree next` em branch descartável) emite `--model vercel/deepseek/deepseek-v4-flash` e responde; push via `pnpm push` → CI PR (checks).
## Rabbit holes / Não escopo (engenharia)
- NÃO mudar `.opencode/commands/work-issue.md:3` / `plan-issue.md:3` (frontmatter `model: deepseek/deepseek-v4-flash`) nem o pin de `tests/unit/opencodeCommands.unit.spec.ts:36-38` — o cardápio de execução de Issues fica intacto (anti-goal).
- NÃO forçar a variante via agente default (opção A rejeitada) — variante fica selecionável e sticky no TUI, não imposta.
- NÃO tocar no `~/.config/opencode/opencode.jsonc` global do humano — o provider vive no `opencode.json` do repo.
- NÃO editar `docs/CHANGELOG-AGENTS.md:208,212` nem outros docs históricos (`docs/plans`, changelogs) — congelados.
- NÃO criar provider duplicado/renomear `cheapest-inference` — `vercel` entra ao lado.
- Não inventar flag `--variant` no launch do preset (TUI não suporta) nem sufixo `:max` no `--model` (formato inválido).
## Riscos e mitigação
- **O TUI não força a variante na linha de launch** (sem `--variant`; `--model` é estritamente `provider/model`) → a sessão pode abrir com `request.variant` do catálogo (não o max). Mitigação: variantes low/high/max expostas pelo override e cicláveis no TUI com sticky persistente (`~/.local/state/opencode/model.json`); o aceite de produto foi ajustado — a **linha de launch emitida pelo preset** (`--model vercel/deepseek/deepseek-v4-flash`) é a verificação primária.
- **Override rejeitado pelo config loader do opencode** (model config v1 não é setável via user config em todas as versões) → mitigação: validar `opencode debug config` (mostra o override) e `opencode run --model vercel/deepseek/deepseek-v4-flash --variant max` no PR, antes de marcar aprovado; documentar no plano se versões futuras mudarem o formato.
- **String duplicada em textos fora da constante** → mitigação: os 4 pontos de texto são atualizados na mesma mudança (Fase 2) e os testes unit pínam a linha de launch, então qualquer deriva volta a aparecer na CI.
- **Erro de digitação no valor da constante (rota do gateway)** → mitigação: testes unit comparam a linha emitida com o literal esperado; `:185` pina a própria constante.
## Aceite de engenharia
- [ ] Aceite de produto da intenção coberto: preset emite `--model vercel/deepseek/deepseek-v4-flash`; variantes low/high/max expostas no `opencode.json` (max com `reasoningEffort: "max"`); verificável pela linha de launch + testes unit atualizados.
- [ ] Anti-goals preservados: `work-issue.md`/`plan-issue.md` e `opencodeCommands.unit.spec.ts` intactos; `~/.config/opencode/opencode.jsonc` intacto; `docs/CHANGELOG-AGENTS.md` e docs históricos intactos; config-only (sem migration, sem code além da constante).
- [ ] Invariantes AGENTS/engineering-standards: constante single-source mantida (OPS26), provider adicionado ao lado (sem twinning), testes de domínio atualizados onde o literal muda.
- [ ] `pnpm test:unit` verde (spec `worktree.unit.spec.ts`) e `pnpm gate:fast` verde; `opencode debug config` validado no PR.