[Pitch] Council - Usei IA como contexto e o foco foi engenharia.
Desenvolvi um projeto de estudo que me deu um bom termômetro de engenharia de software na prática. O Council é um orquestrador CLI multiagente para LLMs, feito em Python, do zero.
A ideia não era "brincar de prompt", e sim atacar problemas reais de engenharia, como:
- orquestração de múltiplos agentes com papéis diferentes (planejamento, crítica, implementação, revisão);
- execução via subprocessos integrando CLIs como claude, gemini e codex;
- streaming de saída em tempo real no terminal (sem ficar refém de execução bloqueante);
- gerenciamento de estado e contexto entre rodadas;
- TUI/CLI para operação mais rica;
- separação de responsabilidades (estado, execução, UI) para manter o sistema sustentável.
O objetivo principal não era "aprender sobre IA", mas aprendizado de engenharia de integração, arquitetura, resiliência e controle de fluxo e me deafiar a sair da camada de uso e construir a camada de infraestrutura/orquestração por trás.
Neste momento estou evoluindo o projeto, com foco em segurança e robustez. Já identifiquei e documentei pontos de atenção no docs/SECURITY.md e estou mitigando essas brechas gradualmente, enquanto implemento, por etapas, os próximos avanços definidos no ROADMAP.md.
Disponibilizei o código no GitHub (https://github.com/juniormartinxo/council)
Flow da aplicação
flowchart TD
A["Usuario executa council run ou council tui"] --> B["main.py parseia argumentos"]
B --> C["Resolve flow config: cli, env, cwd, user ou default"]
C --> D["Carrega e valida FlowStep"]
D --> E["Inicializa CouncilState, UI, Executor e Orchestrator"]
E --> F["orchestrator.run_flow(user_prompt)"]
F --> G["state.add_turn(Human), painel inicial e abertura de run no history"]
G --> H{"Para cada passo"}
H --> I["Monta template context com full_context, last_output e outputs anteriores encapsulados"]
I --> J["render_step_input(step, context)"]
J --> K["_step"]
K --> L["executor.run_cli(command, input_data)"]
L --> M{"command contem placeholder input?"}
M -- "Sim" --> N["Encapsula payload e injeta no argv"]
M -- "Nao" --> O{"gemini prompt sem valor?"}
O -- "Sim" --> P["Encapsula payload e anexa ao argv"]
O -- "Nao" --> Q["Envia input_data via stdin"]
N --> R["subprocess.Popen com shell false"]
P --> R
Q --> R
R --> S["Streaming de stdout para UI + coleta de output"]
S --> T{"Erro / timeout / abort?"}
T -- "Sim" --> U["Registra erro, fecha run, encerra fluxo"]
T -- "Nao" --> V["state.add_turn assistant, show_panel e grava step no history"]
V --> W{"UI pediu feedback humano?"}
W -- "Sim" --> X["Monta follow-up com resposta anterior encapsulada"]
X --> K
W -- "Nao" --> Y["Atualiza step_outputs e last_output"]
Y --> H
H --> Z["Fim dos passos: fecha run como sucesso"]
Z --> AA["Exibe sucesso final"]