#E1, #E2 que são resolvidos em runtime com os outputs dos passos anteriores. Combinados, evitam o padrão caro de “despachar um agente, esperar, pensar de novo, despachar outro”.
Quando ativa:
/plan <task> força; CHATCLI_QUALITY_PLAN_FIRST_MODE=always sempre; auto (default) dispara quando ComplexityScore(task) >= 6.Formato do plano
OPlannerAgent, quando recebe a marcação PlannerStructuredOutputDirective no início da task, emite JSON estrito:
Placeholders ReWOO
Qualquer passo pode injetar output de passos anteriores via#E<n>:
| Sintaxe | Efeito |
|---|---|
#E1 | Substitui pelo output trimmed completo |
#E1.summary | Primeira linha não vazia do output |
#E1.head=200 | Primeiros 200 runes com … se truncado |
#E1.last=200 | Últimos 200 runes com … no início |
Heurística de complexidade
A funçãoComplexityScore(task) → int[0,10] é calibrada para disparar Plan-First só quando paga. O score blends três sinais:
| Sinal | Cap | O que conta |
|---|---|---|
| Verbos de ação | 5 | implement, add, create, fix, refactor, write, test, deploy, build, run, update, … — bilíngue (en + pt-BR: implementar, adicionar, criar, corrigir, escrever, …) |
| Artefatos de arquivo | 3 | Matches em \b[\w./-]+\.(go|ts|py|md|yaml|…)\b + Dockerfile|Makefile|… |
| Sequenciadores | 2 | then, after, finally, e depois, e em seguida, por fim, após, … |
Exemplos
- Trivial (score 1)
- Multi-action (score 6+)
- PT-BR (score 6+)
auto não dispara Plan-First. Orquestrador lida direto.Fluxo de execução
runPlanFirstIfApplicable
Checa
cli.pendingPlanFirst (one-shot) ou quality.ShouldPlanFirst(cfg, userQuery).Planner dispatch
agentDispatcher.Dispatch([{Agent: planner, Task: PlannerStructuredOutputDirective + userQuery}]).ParsePlan
Tolerante a markdown code fences e trailing prose. Valida: IDs únicos, deps apontam para passos anteriores, placeholders
#E<n> apontam para IDs declarados.TopologicalOrder + Execute
Ordem topológica estável (sort lex em ties) garante reprodutibilidade. Cada passo: resolve placeholders → dispatcher.Dispatch → armazena output.
Inject report
Dois messages sintéticos vão para
cli.history:- assistant: o JSON do plano (o modelo vê o que foi tentado)
- system:
FinalReportdeterminístico com task/agent/status/output por passo
Tolerância a falhas
Um passo que falha não aborta a run. O comportamento é “continue downstream with substituted error”:HadErrors é setado para Reflexion decidir se escala.
/plan — invocação manual
cli.pendingPlanFirst é consumido e cleared na primeira invocação de /agent ou /coder subsequente.
Variáveis de ambiente
| Env var | Default | Valores | Efeito |
|---|---|---|---|
CHATCLI_QUALITY_PLAN_FIRST_MODE | auto | off|auto|always | Modo de disparo |
CHATCLI_QUALITY_PLAN_FIRST_THRESHOLD | 6 | 0..10 | Score mínimo para auto disparar |
Override por persona (CHATCLI_AGENT_PLANNER_*)
OPlannerAgent respeita os overrides usuais de agent:
Observabilidade
Cada run emite logs estruturados:Quando desligar
Leia também
#3 Reflexion
Reflexion consome
HadErrors do plan runner para gerar lições quando passos falham.Multi-Agent Orchestration
O dispatcher que Plan-Runner reutiliza é o mesmo do orquestrador padrão.
PlannerAgent (pré-PR)
O agent existia desde antes do pipeline — esse padrão formaliza como invocá-lo de forma determinística.
Configuração completa
Todos os env vars e slashes num lugar só.