@ftarganski/omni-ai 1.1.5 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1485 -0
- package/package.json +4 -2
package/README.md
ADDED
|
@@ -0,0 +1,1485 @@
|
|
|
1
|
+
# omni-ai
|
|
2
|
+
|
|
3
|
+
**Framework provider-agnostic de AI agents e skills para monorepos TypeScript.**
|
|
4
|
+
|
|
5
|
+
Configure qualquer provider LLM (Anthropic, OpenAI, GitHub Copilot, ou self-hosted) e compose agentes reutilizáveis para seus projetos — geração de backend, componentes frontend, revisão UX, validação QA, e mais — tudo via CLI ou API programática.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Como funciona
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
cd meu-projeto
|
|
13
|
+
omni run backend-dev "crie o módulo de pedidos com CRUD e GraphQL"
|
|
14
|
+
│
|
|
15
|
+
▼
|
|
16
|
+
CLI (omni)
|
|
17
|
+
│ lê config/omni-ai.yaml ← provider, modelo e agentsDir
|
|
18
|
+
│ resolve "backend-dev" ← busca agents/**/*.yaml por name:
|
|
19
|
+
│ instancia o provider ← AnthropicProvider / OpenAIProvider
|
|
20
|
+
│ monta o SkillRegistry ← read-file, write-file, search-code...
|
|
21
|
+
│ cria o Agent → agent.run()
|
|
22
|
+
│
|
|
23
|
+
└─ Loop agentico:
|
|
24
|
+
1. Envia systemPrompt + input para o LLM
|
|
25
|
+
2. LLM retorna texto ou tool calls
|
|
26
|
+
3. Skills são executadas (lê/escreve arquivos no meu-projeto/)
|
|
27
|
+
4. Resultados voltam para o LLM
|
|
28
|
+
5. Repete até concluir ou atingir maxIterations
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
As skills (`read-file`, `write-file`, `search-code`, etc.) operam sempre no **diretório onde você executou o comando** (`process.cwd()`). O config e os agents ficam no repositório `omni-ai`.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Instalação
|
|
36
|
+
|
|
37
|
+
### Pré-requisitos
|
|
38
|
+
|
|
39
|
+
| Ferramenta | Versão mínima |
|
|
40
|
+
|------------|---------------|
|
|
41
|
+
| Node.js | 22.x |
|
|
42
|
+
| pnpm | 9.x |
|
|
43
|
+
|
|
44
|
+
### 1. Clonar e instalar
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/Ftarganski/omni-ai.git
|
|
48
|
+
cd omni-ai
|
|
49
|
+
pnpm install
|
|
50
|
+
pnpm build
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 2. Configurar o provider
|
|
54
|
+
|
|
55
|
+
**Opção A — wizard interativo (recomendado):**
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
omni init
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Opção B — manual:**
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
cp config/omni-ai.example.yaml config/omni-ai.yaml
|
|
65
|
+
cp .env.example .env
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Edite `config/omni-ai.yaml` e `.env` de acordo com o provider escolhido. Veja a seção [Providers](#providers) abaixo.
|
|
69
|
+
|
|
70
|
+
### 3. Disponibilizar o CLI globalmente
|
|
71
|
+
|
|
72
|
+
**Opção A — via npm (pacote publicado):**
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm install -g @ftarganski/omni-ai
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Opção B — via link local (desenvolvimento):**
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Na raiz do omni-ai, uma vez só
|
|
82
|
+
pnpm build
|
|
83
|
+
npm link bundle/omni-ai
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Depois disso, `omni` funciona de qualquer diretório.
|
|
87
|
+
|
|
88
|
+
### 4. Testar a instalação
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# A partir do próprio omni-ai (ou de qualquer projeto)
|
|
92
|
+
omni list agents
|
|
93
|
+
omni list providers
|
|
94
|
+
omni list skills
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Uso rápido
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Entrar no projeto alvo
|
|
103
|
+
cd /path/para/meu-projeto
|
|
104
|
+
|
|
105
|
+
# Rodar um agente
|
|
106
|
+
omni run backend-dev "crie o módulo de pedidos"
|
|
107
|
+
|
|
108
|
+
# Com sessão de memória (persiste entre runs)
|
|
109
|
+
omni run backend-dev "continue o módulo de pedidos" --session user1:feature1
|
|
110
|
+
|
|
111
|
+
# Modo verbose — mostra iterações e tokens por step
|
|
112
|
+
omni run qa-backend "valide src/orders/orders.service.ts" --verbose
|
|
113
|
+
|
|
114
|
+
# Salvar output em arquivo
|
|
115
|
+
omni run backend-dev "crie módulo de notificações" --output implementacao.md
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## CLI — Referência completa
|
|
121
|
+
|
|
122
|
+
### `omni run`
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
omni run <agent> "<prompt>" [opções]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
| Opção | Tipo | Descrição |
|
|
129
|
+
|-------|------|-----------|
|
|
130
|
+
| `--config <path>` | string | Caminho para o `omni-ai.yaml` (padrão: detectado automaticamente) |
|
|
131
|
+
| `--session <id>` | string | ID de sessão no formato `"resourceId:threadId"` — habilita memória SQLite entre runs |
|
|
132
|
+
| `--output <file>` | string | Salva o output completo em um arquivo |
|
|
133
|
+
| `--verbose` | flag | Exibe cada iteração, tool calls e contagem de tokens por step |
|
|
134
|
+
| `--stream` | flag | Transmite tokens em tempo real enquanto o agente responde |
|
|
135
|
+
|
|
136
|
+
**Exemplos:**
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Backend — gera módulo completo
|
|
140
|
+
omni run backend-dev "crie o módulo de customers com CRUD, GraphQL e listeners"
|
|
141
|
+
|
|
142
|
+
# Frontend — gera componente
|
|
143
|
+
omni run frontend-dev "crie a página de listagem de pedidos com filtros e paginação"
|
|
144
|
+
|
|
145
|
+
# UX — audita e corrige problemas
|
|
146
|
+
omni run ux-lead "audite o componente OrderForm"
|
|
147
|
+
|
|
148
|
+
# QA — valida código gerado
|
|
149
|
+
omni run qa-lead "valide todos os arquivos em src/orders/"
|
|
150
|
+
|
|
151
|
+
# Com memória entre sessões
|
|
152
|
+
omni run backend-dev "o que você implementou no módulo de customers?" --session dev1:customers
|
|
153
|
+
|
|
154
|
+
# Agente específico + output em arquivo
|
|
155
|
+
omni run backend-schema "crie o schema para a entidade Invoice" --output invoice-schema.md
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### `omni list`
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
omni list agents # Lista todos os agentes disponíveis (nome + descrição)
|
|
164
|
+
omni list skills # Lista todas as skills registradas
|
|
165
|
+
omni list providers # Lista os providers registrados e seus tipos
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### `omni chain`
|
|
171
|
+
|
|
172
|
+
Executa uma sequência de agentes em pipeline: a saída de cada agente se torna a entrada do próximo.
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
omni chain "<prompt>" <agent1> <agent2> [agent3...]
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
| Opção | Tipo | Descrição |
|
|
179
|
+
|-------|------|-----------|
|
|
180
|
+
| `--config <path>` | string | Caminho para o `omni-ai.yaml` |
|
|
181
|
+
| `--output <file>` | string | Salva o output final em arquivo |
|
|
182
|
+
| `--verbose` | flag | Imprime o output de cada agente intermediário |
|
|
183
|
+
| `--stream` | flag | Transmite tokens em tempo real para cada agente da cadeia |
|
|
184
|
+
|
|
185
|
+
**Exemplos:**
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Schema → implementação → validação
|
|
189
|
+
omni chain "crie módulo de orders" backend-schema backend-dev qa-backend
|
|
190
|
+
|
|
191
|
+
# Geração de componente + auditoria UX
|
|
192
|
+
omni chain "crie a página de listagem de pedidos" frontend-dev ux-reviewer
|
|
193
|
+
|
|
194
|
+
# Com output salvo
|
|
195
|
+
omni chain "crie o módulo de customers" backend-schema backend-dev qa-backend --output customers.md
|
|
196
|
+
|
|
197
|
+
# Verbose — mostra output intermediário de cada agente
|
|
198
|
+
omni chain "crie módulo de invoices" backend-schema backend-dev --verbose
|
|
199
|
+
|
|
200
|
+
# Streaming em tempo real ao longo da cadeia
|
|
201
|
+
omni chain "crie e revise o módulo de orders" backend-dev qa-backend --stream
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Output visual:**
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
◆ backend-schema [anthropic / claude-sonnet-4-6]
|
|
208
|
+
... (3 iterações)
|
|
209
|
+
|
|
210
|
+
↓ saída passada para: backend-dev
|
|
211
|
+
|
|
212
|
+
◆ backend-dev [anthropic / claude-sonnet-4-6]
|
|
213
|
+
... (8 iterações)
|
|
214
|
+
|
|
215
|
+
↓ saída passada para: qa-backend
|
|
216
|
+
|
|
217
|
+
◆ qa-backend [anthropic / claude-sonnet-4-6]
|
|
218
|
+
... (4 iterações)
|
|
219
|
+
|
|
220
|
+
<output final do qa-backend>
|
|
221
|
+
|
|
222
|
+
Tokens: 18.400 entrada · 5.200 saída · ~$0.084
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
### `omni init`
|
|
228
|
+
|
|
229
|
+
Wizard interativo que gera `config/omni-ai.yaml` e atualiza o `.env` sem editar arquivos manualmente.
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
omni init
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
O wizard irá:
|
|
236
|
+
|
|
237
|
+
1. Perguntar qual provider usar (Copilot, Anthropic, OpenAI ou Custom/self-hosted)
|
|
238
|
+
2. Solicitar a API key ou token via campo oculto (não aparece no terminal)
|
|
239
|
+
3. Permitir selecionar o modelo padrão
|
|
240
|
+
4. Opcionalmente configurar um segundo provider para agentes específicos
|
|
241
|
+
5. Gerar `config/omni-ai.yaml` e atualizar `.env` preservando entradas existentes
|
|
242
|
+
6. Exibir os próximos passos com exemplos de comandos
|
|
243
|
+
|
|
244
|
+
**Quando usar:** na primeira vez que configurar o omni-ai, ou quando quiser trocar ou adicionar um provider.
|
|
245
|
+
|
|
246
|
+
> Se `config/omni-ai.yaml` já existir, o wizard pergunta antes de sobrescrever.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
### `omni serve`
|
|
251
|
+
|
|
252
|
+
Inicia um servidor HTTP local para executar agentes via REST ou SSE.
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
omni serve [opções]
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
| Opção | Tipo | Descrição |
|
|
259
|
+
|-------|------|-----------|
|
|
260
|
+
| `--port <number>` | number | Porta (padrão: 3000) |
|
|
261
|
+
| `--config <path>` | string | Caminho para `omni-ai.yaml` |
|
|
262
|
+
|
|
263
|
+
**Endpoints:**
|
|
264
|
+
|
|
265
|
+
| Método | Rota | Descrição |
|
|
266
|
+
|--------|------|-----------|
|
|
267
|
+
| `GET` | `/health` | Status do servidor e versão |
|
|
268
|
+
| `GET` | `/agents` | Lista todos os agentes disponíveis |
|
|
269
|
+
| `POST` | `/run` | Executa um agente (JSON response) |
|
|
270
|
+
| `POST` | `/run/stream` | Executa um agente com streaming SSE |
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# Iniciar o servidor
|
|
274
|
+
omni serve --port 4000
|
|
275
|
+
|
|
276
|
+
# Executar um agente via API
|
|
277
|
+
curl -X POST http://localhost:3000/run \
|
|
278
|
+
-H "Content-Type: application/json" \
|
|
279
|
+
-d '{"agent": "backend-dev", "prompt": "liste os endpoints do módulo de orders"}'
|
|
280
|
+
|
|
281
|
+
# Com sessão
|
|
282
|
+
curl -X POST http://localhost:3000/run \
|
|
283
|
+
-d '{"agent": "backend-dev", "prompt": "continue o módulo de customers", "session": "dev1:customers"}'
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
### `omni watch`
|
|
289
|
+
|
|
290
|
+
Reexecuta um agente automaticamente quando arquivos do projeto mudam.
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
omni watch <agent> "<prompt>" [opções]
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
| Opção | Tipo | Descrição |
|
|
297
|
+
|-------|------|-----------|
|
|
298
|
+
| `--config <path>` | string | Caminho para `omni-ai.yaml` |
|
|
299
|
+
| `--glob <pattern>` | string | Glob dos arquivos a observar (padrão: `src/**/*.{ts,js,yaml,json}`) |
|
|
300
|
+
| `--debounce <ms>` | number | Delay de debounce em ms (padrão: 500) |
|
|
301
|
+
| `--stream` | flag | Transmite tokens em tempo real |
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
# Reexecuta qa-backend sempre que um .ts muda
|
|
305
|
+
omni watch qa-backend "valide os arquivos modificados" --glob "src/**/*.ts"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### `omni eval`
|
|
311
|
+
|
|
312
|
+
Avalia um agente contra um dataset de pares `(input, expected)`.
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
omni eval <agent> <dataset.json> [opções]
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
| Opção | Tipo | Descrição |
|
|
319
|
+
|-------|------|-----------|
|
|
320
|
+
| `--config <path>` | string | Caminho para `omni-ai.yaml` |
|
|
321
|
+
| `--concurrency <n>` | number | Avaliações paralelas (padrão: 3) |
|
|
322
|
+
| `--output <file>` | string | Salva relatório JSON em arquivo |
|
|
323
|
+
|
|
324
|
+
**Formato do dataset:**
|
|
325
|
+
|
|
326
|
+
```json
|
|
327
|
+
[
|
|
328
|
+
{ "input": "qual é a capital do Brasil?", "expected": "Brasília" },
|
|
329
|
+
{ "input": "o que é TypeScript?", "expected": "superset tipado de JavaScript" }
|
|
330
|
+
]
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**Saída:**
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
◆ omni eval agent: backend-dev dataset: qa.json
|
|
337
|
+
|
|
338
|
+
✓ q1 exact
|
|
339
|
+
✓ q2 contains
|
|
340
|
+
✗ q3 miss
|
|
341
|
+
|
|
342
|
+
Score: 2/3 (66.7%)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
### `omni export`
|
|
348
|
+
|
|
349
|
+
Exporta o histórico de uma sessão como Markdown ou JSON.
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
omni export <sessionId> [opções]
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
| Opção | Tipo | Descrição |
|
|
356
|
+
|-------|------|-----------|
|
|
357
|
+
| `--format <format>` | `markdown` \| `json` | Formato de saída (padrão: `markdown`) |
|
|
358
|
+
| `--output <file>` | string | Salva em arquivo em vez de stdout |
|
|
359
|
+
| `--limit <n>` | number | Limita às últimas N mensagens |
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
# Exportar sessão como Markdown
|
|
363
|
+
omni export dev1:customers
|
|
364
|
+
|
|
365
|
+
# Exportar como JSON para arquivo
|
|
366
|
+
omni export dev1:customers --format json --output session.json
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
### `omni mcp serve`
|
|
372
|
+
|
|
373
|
+
Expõe todas as skills registradas como ferramentas MCP sobre stdio. Permite que clientes MCP (como Claude Desktop) chamem as skills diretamente.
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
omni mcp serve
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
O servidor usa o transporte **stdio** — adequado para ser iniciado como subprocesso por um cliente MCP.
|
|
380
|
+
|
|
381
|
+
**Configuração no Claude Desktop (`claude_desktop_config.json`):**
|
|
382
|
+
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"mcpServers": {
|
|
386
|
+
"omni-ai": {
|
|
387
|
+
"command": "omni",
|
|
388
|
+
"args": ["mcp", "serve"]
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Providers
|
|
397
|
+
|
|
398
|
+
### GitHub Copilot (recomendado para usuários GitHub)
|
|
399
|
+
|
|
400
|
+
Não requer conta separada — usa o seu token GitHub existente.
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
# 1. Autenticar com GitHub CLI (se ainda não fez)
|
|
404
|
+
gh auth login
|
|
405
|
+
|
|
406
|
+
# 2. Obter o token
|
|
407
|
+
gh auth token
|
|
408
|
+
# Copia o valor e cola no .env abaixo
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
# .env
|
|
413
|
+
GITHUB_TOKEN=ghp_...
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
```yaml
|
|
417
|
+
# config/omni-ai.yaml
|
|
418
|
+
defaultProvider: copilot
|
|
419
|
+
|
|
420
|
+
providers:
|
|
421
|
+
- name: copilot
|
|
422
|
+
type: copilot
|
|
423
|
+
apiKey: ${GITHUB_TOKEN}
|
|
424
|
+
baseUrl: https://api.githubcopilot.com
|
|
425
|
+
defaultModel: gpt-4o
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
> **Nota:** Requer uma assinatura ativa do GitHub Copilot (Individual, Business ou Enterprise).
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
### Anthropic (Claude)
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
# .env
|
|
436
|
+
ANTHROPIC_API_KEY=sk-ant-api03-...
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
```yaml
|
|
440
|
+
# config/omni-ai.yaml
|
|
441
|
+
defaultProvider: anthropic
|
|
442
|
+
|
|
443
|
+
providers:
|
|
444
|
+
- name: anthropic
|
|
445
|
+
type: anthropic
|
|
446
|
+
apiKey: ${ANTHROPIC_API_KEY}
|
|
447
|
+
defaultModel: claude-sonnet-4-6
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Como obter: [console.anthropic.com](https://console.anthropic.com) → API Keys → Create key
|
|
451
|
+
|
|
452
|
+
**Modelos disponíveis:**
|
|
453
|
+
|
|
454
|
+
| Modelo | ID | Uso recomendado |
|
|
455
|
+
|--------|----|-----------------|
|
|
456
|
+
| Claude Opus 4.7 | `claude-opus-4-7` | Raciocínio complexo, contexto longo |
|
|
457
|
+
| Claude Sonnet 4.6 | `claude-sonnet-4-6` | Qualidade/velocidade balanceados ✓ |
|
|
458
|
+
| Claude Haiku 4.5 | `claude-haiku-4-5-20251001` | Tarefas rápidas e de baixo custo |
|
|
459
|
+
|
|
460
|
+
> **Atenção:** A API Anthropic requer `temperature <= 1.0`. O adapter valida isso automaticamente.
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
### OpenAI (GPT)
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
# .env
|
|
468
|
+
OPENAI_API_KEY=sk-proj-...
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
```yaml
|
|
472
|
+
# config/omni-ai.yaml
|
|
473
|
+
defaultProvider: openai
|
|
474
|
+
|
|
475
|
+
providers:
|
|
476
|
+
- name: openai
|
|
477
|
+
type: openai
|
|
478
|
+
apiKey: ${OPENAI_API_KEY}
|
|
479
|
+
defaultModel: gpt-4o
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Como obter: [platform.openai.com](https://platform.openai.com) → API keys
|
|
483
|
+
|
|
484
|
+
**Modelos disponíveis:**
|
|
485
|
+
|
|
486
|
+
| Modelo | ID | Uso recomendado |
|
|
487
|
+
|--------|----|-----------------|
|
|
488
|
+
| GPT-4o | `gpt-4o` | Multimodal, raciocínio forte |
|
|
489
|
+
| GPT-4o mini | `gpt-4o-mini` | Rápido, custo eficiente |
|
|
490
|
+
| o1 | `o1` | Raciocínio avançado |
|
|
491
|
+
| o3-mini | `o3-mini` | Raciocínio rápido |
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
### Google Gemini
|
|
496
|
+
|
|
497
|
+
```bash
|
|
498
|
+
# .env
|
|
499
|
+
GOOGLE_API_KEY=AIza...
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
```yaml
|
|
503
|
+
# config/omni-ai.yaml
|
|
504
|
+
defaultProvider: google
|
|
505
|
+
|
|
506
|
+
providers:
|
|
507
|
+
- name: google
|
|
508
|
+
type: google
|
|
509
|
+
apiKey: ${GOOGLE_API_KEY}
|
|
510
|
+
defaultModel: gemini-2.0-flash
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
Como obter: [aistudio.google.com](https://aistudio.google.com) → Get API key
|
|
514
|
+
|
|
515
|
+
**Modelos disponíveis:**
|
|
516
|
+
|
|
517
|
+
| Modelo | ID | Uso recomendado |
|
|
518
|
+
|--------|----|-----------------|
|
|
519
|
+
| Gemini 2.0 Flash | `gemini-2.0-flash` | Rápido, multimodal, custo baixo ✓ |
|
|
520
|
+
| Gemini 1.5 Pro | `gemini-1.5-pro` | Contexto longo (1M tokens) |
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
### Groq (inferência ultrarrápida)
|
|
525
|
+
|
|
526
|
+
```bash
|
|
527
|
+
# .env
|
|
528
|
+
GROQ_API_KEY=gsk_...
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
```yaml
|
|
532
|
+
# config/omni-ai.yaml
|
|
533
|
+
providers:
|
|
534
|
+
- name: groq
|
|
535
|
+
type: groq
|
|
536
|
+
apiKey: ${GROQ_API_KEY}
|
|
537
|
+
defaultModel: llama-3.3-70b-versatile
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
Como obter: [console.groq.com](https://console.groq.com) → API Keys
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
### Ollama (local / self-hosted)
|
|
545
|
+
|
|
546
|
+
```yaml
|
|
547
|
+
# config/omni-ai.yaml
|
|
548
|
+
providers:
|
|
549
|
+
- name: ollama
|
|
550
|
+
type: ollama
|
|
551
|
+
defaultModel: llama3.2
|
|
552
|
+
# baseUrl padrão: http://localhost:11434/v1
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
Não requer API key. Requer [Ollama](https://ollama.com) em execução local.
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
### Custom / self-hosted (Azure, vLLM, LM Studio...)
|
|
560
|
+
|
|
561
|
+
Qualquer endpoint compatível com a API OpenAI de chat completions:
|
|
562
|
+
|
|
563
|
+
```yaml
|
|
564
|
+
# config/omni-ai.yaml
|
|
565
|
+
providers:
|
|
566
|
+
- name: azure
|
|
567
|
+
type: custom
|
|
568
|
+
baseUrl: https://meu-recurso.openai.azure.com/openai/deployments/gpt-4o
|
|
569
|
+
apiKey: ${AZURE_API_KEY}
|
|
570
|
+
defaultModel: gpt-4o
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
Endpoints compatíveis: **Azure OpenAI**, **LM Studio**, **vLLM**, **Together AI**, **Mistral AI**, **Perplexity**.
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
### Múltiplos providers
|
|
578
|
+
|
|
579
|
+
Você pode declarar vários providers e cada agente pode usar um diferente:
|
|
580
|
+
|
|
581
|
+
```yaml
|
|
582
|
+
defaultProvider: copilot
|
|
583
|
+
|
|
584
|
+
providers:
|
|
585
|
+
- name: copilot
|
|
586
|
+
type: copilot
|
|
587
|
+
apiKey: ${GITHUB_TOKEN}
|
|
588
|
+
defaultModel: gpt-4o
|
|
589
|
+
|
|
590
|
+
- name: anthropic
|
|
591
|
+
type: anthropic
|
|
592
|
+
apiKey: ${ANTHROPIC_API_KEY}
|
|
593
|
+
defaultModel: claude-sonnet-4-6
|
|
594
|
+
|
|
595
|
+
- name: ollama
|
|
596
|
+
type: custom
|
|
597
|
+
baseUrl: http://localhost:11434/v1
|
|
598
|
+
defaultModel: llama3.2
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
No arquivo YAML do agente, basta declarar `provider: anthropic` para sobrescrever o padrão apenas para aquele agente.
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## Configuração — referência completa
|
|
606
|
+
|
|
607
|
+
### `omni-ai.yaml`
|
|
608
|
+
|
|
609
|
+
```yaml
|
|
610
|
+
version: "1"
|
|
611
|
+
|
|
612
|
+
# Provider padrão para todos os agentes (a menos que o agente sobrescreva)
|
|
613
|
+
defaultProvider: copilot
|
|
614
|
+
|
|
615
|
+
# Diretório dos YAML de agentes (relativo à raiz do omni-ai)
|
|
616
|
+
agentsDir: agents
|
|
617
|
+
|
|
618
|
+
providers:
|
|
619
|
+
- name: copilot
|
|
620
|
+
type: copilot # "anthropic" | "openai" | "copilot" | "google" | "groq" | "ollama" | "custom"
|
|
621
|
+
apiKey: ${GITHUB_TOKEN} # referência a variável de ambiente — nunca hardcode
|
|
622
|
+
baseUrl: https://api.githubcopilot.com
|
|
623
|
+
defaultModel: gpt-4o # modelo usado quando o agente não especifica
|
|
624
|
+
|
|
625
|
+
agents:
|
|
626
|
+
# Agente inline — definido diretamente no config (não precisa de arquivo YAML separado)
|
|
627
|
+
- name: code-reviewer
|
|
628
|
+
description: Revisa código para qualidade, bugs e segurança
|
|
629
|
+
systemPrompt: |
|
|
630
|
+
Você é um revisor de código especialista...
|
|
631
|
+
skills:
|
|
632
|
+
- read-file
|
|
633
|
+
- search-code
|
|
634
|
+
maxIterations: 5
|
|
635
|
+
|
|
636
|
+
# Agente com override de provider/modelo
|
|
637
|
+
- name: doc-writer
|
|
638
|
+
description: Gera documentação
|
|
639
|
+
provider: anthropic # sobrescreve defaultProvider só para este agente
|
|
640
|
+
model: claude-haiku-4-5-20251001 # sobrescreve defaultModel
|
|
641
|
+
systemPrompt: |
|
|
642
|
+
Você é um redator técnico...
|
|
643
|
+
maxIterations: 3
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
### Herança de provider e modelo
|
|
647
|
+
|
|
648
|
+
```
|
|
649
|
+
omni-ai.yaml
|
|
650
|
+
└─ defaultProvider: copilot ← se aplica a todos os agentes
|
|
651
|
+
└─ providers[copilot]
|
|
652
|
+
└─ defaultModel: gpt-4o ← se aplica a todos os agentes
|
|
653
|
+
|
|
654
|
+
agents/backend/backend-dev.yaml
|
|
655
|
+
├─ provider: (ausente) → usa defaultProvider (copilot)
|
|
656
|
+
├─ provider: anthropic → sobrescreve só para este agente
|
|
657
|
+
├─ model: (ausente) → usa defaultModel do provider resolvido
|
|
658
|
+
└─ model: gpt-4o-mini → sobrescreve só para este agente
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Campos do agente YAML
|
|
662
|
+
|
|
663
|
+
| Campo | Tipo | Padrão | Descrição |
|
|
664
|
+
|-------|------|--------|-----------|
|
|
665
|
+
| `name` | `string` | obrigatório | Identificador único |
|
|
666
|
+
| `description` | `string` | obrigatório | O que o agente faz |
|
|
667
|
+
| `provider` | `string` | herda | Nome do provider — omita para usar `defaultProvider` |
|
|
668
|
+
| `model` | `string` | herda | ID do modelo — omita para usar `defaultModel` do provider |
|
|
669
|
+
| `systemPrompt` | `string` | obrigatório | Instruções do agente |
|
|
670
|
+
| `skills` | `string[]` | `[]` | Skills que o agente pode chamar como ferramentas |
|
|
671
|
+
| `maxIterations` | `number` | `10` | Máximo de iterações do loop agentico |
|
|
672
|
+
| `temperature` | `number` | padrão do provider | Temperatura de amostragem (0–2; max 1.0 para Anthropic) |
|
|
673
|
+
|
|
674
|
+
---
|
|
675
|
+
|
|
676
|
+
## Catálogo de agentes
|
|
677
|
+
|
|
678
|
+
### Backend (7 agentes)
|
|
679
|
+
|
|
680
|
+
| Agente | Arquivo | O que faz |
|
|
681
|
+
|--------|---------|-----------|
|
|
682
|
+
| `backend-dev` | `agents/backend/backend-dev.yaml` | Orquestrador — feature NestJS completa: schema → serviço → resolver → listeners → tests |
|
|
683
|
+
| `backend-schema` | `agents/backend/backend-schema.yaml` | Schema DynamoDB OneTable com `defineSchema()` |
|
|
684
|
+
| `backend-service` | `agents/backend/backend-service.yaml` | NestJS service com CRUD, eventos, error helpers, caching |
|
|
685
|
+
| `backend-resolver` | `agents/backend/backend-resolver.yaml` | GraphQL resolver com padrão federation + SDL |
|
|
686
|
+
| `backend-listener` | `agents/backend/backend-listener.yaml` | Event listeners com `@OnEventCatcher` |
|
|
687
|
+
| `backend-test` | `agents/backend/backend-test.yaml` | Testes Jest de integração com DynamoDB local real |
|
|
688
|
+
| `backend-atom-app` | `agents/backend/backend-atom-app.yaml` | Conectores Atom framework (sessões, ARNs, roteamento de mensagens) |
|
|
689
|
+
|
|
690
|
+
### Frontend (5 agentes)
|
|
691
|
+
|
|
692
|
+
| Agente | Arquivo | O que faz |
|
|
693
|
+
|--------|---------|-----------|
|
|
694
|
+
| `frontend-dev` | `agents/frontend/frontend-dev.yaml` | Orquestrador — feature React completa: route → componentes → hooks |
|
|
695
|
+
| `frontend-ui-component` | `agents/frontend/frontend-ui-component.yaml` | Componentes UI primitivos estilo shadcn/ui com CVA + Radix |
|
|
696
|
+
| `frontend-module-component` | `agents/frontend/frontend-module-component.yaml` | Componentes de feature conectados a dados (TanStack Query) |
|
|
697
|
+
| `frontend-page-route` | `agents/frontend/frontend-page-route.yaml` | Páginas TanStack Router com layouts responsivos |
|
|
698
|
+
| `frontend-custom-hook` | `agents/frontend/frontend-custom-hook.yaml` | Custom React hooks tipados e SSR-safe |
|
|
699
|
+
|
|
700
|
+
### UX (5 agentes)
|
|
701
|
+
|
|
702
|
+
| Agente | Arquivo | O que faz |
|
|
703
|
+
|--------|---------|-----------|
|
|
704
|
+
| `ux-lead` | `agents/ux/ux-lead.yaml` | Orquestrador — auditoria UX completa em 10 dimensões, corrige críticos e documenta os demais |
|
|
705
|
+
| `ux-reviewer` | `agents/ux/ux-reviewer.yaml` | Revisão UX detalhada com findings por severidade (Critical / Moderate / Low) |
|
|
706
|
+
| `ux-states` | `agents/ux/ux-states.yaml` | Componentes de estado: Skeleton, Empty, Error e Success |
|
|
707
|
+
| `ux-forms` | `agents/ux/ux-forms.yaml` | Formulários com validação, autocomplete, acessibilidade e estados de loading |
|
|
708
|
+
| `ux-motion` | `agents/ux/ux-motion.yaml` | Micro-interações e transições com `motion-safe:` obrigatório |
|
|
709
|
+
|
|
710
|
+
### QA (4 agentes)
|
|
711
|
+
|
|
712
|
+
| Agente | Arquivo | O que faz |
|
|
713
|
+
|--------|---------|-----------|
|
|
714
|
+
| `qa-lead` | `agents/qa/qa-lead.yaml` | Orquestrador — classifica arquivos, delega aos agentes especializados e emite veredicto de merge |
|
|
715
|
+
| `qa-frontend` | `agents/qa/qa-frontend.yaml` | Valida React/TypeScript: imports, tokens Tailwind, responsividade, acessibilidade |
|
|
716
|
+
| `qa-ux` | `agents/qa/qa-ux.yaml` | Valida UX: feedback states, formulários, motion, content tone |
|
|
717
|
+
| `qa-backend` | `agents/qa/qa-backend.yaml` | Valida NestJS: services, resolvers, schema GraphQL, listeners, testes |
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
## Skills disponíveis
|
|
722
|
+
|
|
723
|
+
As skills são as ferramentas que os agentes podem chamar durante o loop agentico. Todas operam dentro do `cwd` (diretório do projeto alvo) — nunca fora dele. Disponíveis via subpath exports de `@ftarganski/omni-ai`.
|
|
724
|
+
|
|
725
|
+
**Filesystem (`@ftarganski/omni-ai/skills/fs`)**
|
|
726
|
+
|
|
727
|
+
| Skill | O que faz |
|
|
728
|
+
|-------|-----------|
|
|
729
|
+
| `read-file` | Lê o conteúdo completo de um arquivo |
|
|
730
|
+
| `write-file` | Escreve ou sobrescreve um arquivo (cria diretórios automaticamente) |
|
|
731
|
+
| `list-directory` | Lista arquivos em um diretório (recursivo, filtro por extensão) |
|
|
732
|
+
|
|
733
|
+
**Código (`@ftarganski/omni-ai/skills/code`)**
|
|
734
|
+
|
|
735
|
+
| Skill | O que faz |
|
|
736
|
+
|-------|-----------|
|
|
737
|
+
| `search-code` | Busca texto ou regex em arquivos TypeScript/TSX |
|
|
738
|
+
|
|
739
|
+
**UX (`@ftarganski/omni-ai/skills/ux`)**
|
|
740
|
+
|
|
741
|
+
| Skill | O que faz |
|
|
742
|
+
|-------|-----------|
|
|
743
|
+
| `audit-accessibility` | Scan heurístico de a11y em TSX (alt, aria-label, foco, contraste...) |
|
|
744
|
+
|
|
745
|
+
**Git (`@ftarganski/omni-ai/skills/git`)**
|
|
746
|
+
|
|
747
|
+
| Skill | O que faz |
|
|
748
|
+
|-------|-----------|
|
|
749
|
+
| `git-status` | Retorna o status atual do repositório |
|
|
750
|
+
| `git-diff` | Retorna o diff de um arquivo ou do repositório |
|
|
751
|
+
| `git-log` | Lista commits recentes com autoria e mensagem |
|
|
752
|
+
| `git-commit-message` | Gera mensagem de commit a partir de um diff (chamada LLM) |
|
|
753
|
+
|
|
754
|
+
**HTTP (`@ftarganski/omni-ai/skills/http`)**
|
|
755
|
+
|
|
756
|
+
| Skill | O que faz |
|
|
757
|
+
|-------|-----------|
|
|
758
|
+
| `http-request` | Requisição HTTP autenticada (Bearer, Basic, OAuth2 client-credentials) |
|
|
759
|
+
|
|
760
|
+
**Multimodal (`@ftarganski/omni-ai/skills/multimodal`)**
|
|
761
|
+
|
|
762
|
+
| Skill | O que faz |
|
|
763
|
+
|-------|-----------|
|
|
764
|
+
| `analyze-image` | Analisa screenshots, diagramas ou mockups via providers com visão |
|
|
765
|
+
|
|
766
|
+
**Backend (`@ftarganski/omni-ai/skills/backend`)**
|
|
767
|
+
|
|
768
|
+
| Skill | O que faz |
|
|
769
|
+
|-------|-----------|
|
|
770
|
+
| `find-code-pattern` | Localiza padrões de código em arquivos TypeScript |
|
|
771
|
+
| `analyze-nestjs-module` | Analisa estrutura de módulos NestJS |
|
|
772
|
+
| `analyze-dynamo-schema` | Analisa schemas DynamoDB/TableService |
|
|
773
|
+
| `analyze-graphql-schema` | Analisa schemas GraphQL |
|
|
774
|
+
|
|
775
|
+
**Frontend (`@ftarganski/omni-ai/skills/frontend`)**
|
|
776
|
+
|
|
777
|
+
| Skill | O que faz |
|
|
778
|
+
|-------|-----------|
|
|
779
|
+
| `find-component-pattern` | Localiza padrões em componentes React/TSX |
|
|
780
|
+
| `analyze-component` | Analisa props, hooks e estrutura de componentes |
|
|
781
|
+
| `analyze-module-structure` | Analisa a estrutura de módulos frontend |
|
|
782
|
+
|
|
783
|
+
**QA (`@ftarganski/omni-ai/skills/qa`)**
|
|
784
|
+
|
|
785
|
+
| Skill | O que faz |
|
|
786
|
+
|-------|-----------|
|
|
787
|
+
| `find-test-pattern` | Localiza padrões em arquivos de teste |
|
|
788
|
+
| `analyze-test-coverage` | Analisa cobertura de testes por módulo |
|
|
789
|
+
|
|
790
|
+
### Segurança das skills de filesystem
|
|
791
|
+
|
|
792
|
+
`read-file`, `write-file` e `list-directory` resolvem todos os caminhos relativos ao `cwd` e **rejeitam qualquer path que escape o diretório do projeto** (bloqueando ataques de path traversal como `../../../etc/passwd`).
|
|
793
|
+
|
|
794
|
+
---
|
|
795
|
+
|
|
796
|
+
## Memória e sessões
|
|
797
|
+
|
|
798
|
+
### Via CLI (--session)
|
|
799
|
+
|
|
800
|
+
```bash
|
|
801
|
+
# Primeira execução — sessão é criada e armazenada em ~/.omni-ai/sessions.db
|
|
802
|
+
omni run backend-dev "crie o módulo de pedidos com CRUD" --session dev1:orders
|
|
803
|
+
|
|
804
|
+
# Segunda execução — o agente carrega o histórico da sessão anterior como contexto
|
|
805
|
+
omni run backend-dev "adicione o listener de busca ao módulo de pedidos" --session dev1:orders
|
|
806
|
+
|
|
807
|
+
# Consulta de contexto anterior
|
|
808
|
+
omni run backend-dev "quais arquivos você criou na sessão anterior?" --session dev1:orders
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
O ID de sessão segue o formato `"resourceId:threadId"`. Use `resourceId` para identificar o usuário ou projeto, e `threadId` para a feature ou conversa específica.
|
|
812
|
+
|
|
813
|
+
### Via API programática
|
|
814
|
+
|
|
815
|
+
```typescript
|
|
816
|
+
import { createRuntime } from "@ftarganski/omni-ai";
|
|
817
|
+
import { SQLiteMemoryStore, ObservationMaskingCompactor } from "@ftarganski/omni-ai/memory";
|
|
818
|
+
|
|
819
|
+
const runtime = await createRuntime({
|
|
820
|
+
skills: [/* suas skills extras */],
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
// Sem memória — execução simples
|
|
824
|
+
const result = await runtime.run("backend-dev", "crie o módulo de clientes");
|
|
825
|
+
console.log(result.output);
|
|
826
|
+
|
|
827
|
+
// Com memória entre sessões
|
|
828
|
+
const store = new SQLiteMemoryStore({ path: "./sessions.db" });
|
|
829
|
+
|
|
830
|
+
const result2 = await runtime.run(
|
|
831
|
+
"backend-dev",
|
|
832
|
+
"adicione busca ao módulo de clientes",
|
|
833
|
+
{
|
|
834
|
+
session: { resourceId: "user-42", threadId: "feature-customers" },
|
|
835
|
+
memoryStore: store,
|
|
836
|
+
}
|
|
837
|
+
);
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
### Compactors — redução de consumo de tokens
|
|
841
|
+
|
|
842
|
+
Sem compaction, cada iteração reencaminha todo o histórico:
|
|
843
|
+
|
|
844
|
+
```
|
|
845
|
+
Iteração 1: 1.000 tokens
|
|
846
|
+
Iteração 2: 3.500 tokens
|
|
847
|
+
Iteração 3: 8.200 tokens → Total: 26.700 tokens
|
|
848
|
+
Iteração 4: 14.000 tokens
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
Com `ObservationMaskingCompactor`:
|
|
852
|
+
|
|
853
|
+
```
|
|
854
|
+
Iteração 1: 1.000 tokens
|
|
855
|
+
Iteração 2: 3.500 tokens
|
|
856
|
+
Iteração 3: 1.800 tokens ← resultados antigos de tool mascarados
|
|
857
|
+
Iteração 4: 2.100 tokens → Total: 8.400 tokens (redução de 68%)
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
| Compactor | Estratégia | Chamadas LLM | Ideal para |
|
|
861
|
+
|-----------|-----------|--------------|-----------|
|
|
862
|
+
| `ObservationMaskingCompactor` | Substitui corpo de tool results antigos por `[masked ~N tokens]` | 0 | Agentes intensivos em leitura de arquivos |
|
|
863
|
+
| `SummaryCompactor` | LLM resume mensagens antigas, mantém N recentes verbatim | 1 por trigger | Conversas longas, raciocínio multi-step |
|
|
864
|
+
|
|
865
|
+
---
|
|
866
|
+
|
|
867
|
+
### Busca semântica com embeddings
|
|
868
|
+
|
|
869
|
+
`SemanticMemoryStore` substitui a busca por palavras-chave (FTS5) por similaridade de coseno usando embeddings do provider.
|
|
870
|
+
|
|
871
|
+
```typescript
|
|
872
|
+
import { createRuntime } from "@ftarganski/omni-ai";
|
|
873
|
+
import { SQLiteMemoryStore, SemanticMemoryStore } from "@ftarganski/omni-ai/memory";
|
|
874
|
+
import { OpenAIProvider } from "@ftarganski/omni-ai/provider-openai";
|
|
875
|
+
|
|
876
|
+
// Provider com suporte a embeddings (capabilities.embedding = true)
|
|
877
|
+
const embeddingProvider = new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY! });
|
|
878
|
+
|
|
879
|
+
// Persiste mensagens no SQLite + busca semântica em memória
|
|
880
|
+
const store = new SemanticMemoryStore(
|
|
881
|
+
embeddingProvider,
|
|
882
|
+
new SQLiteMemoryStore({ path: "./sessions.db" })
|
|
883
|
+
);
|
|
884
|
+
|
|
885
|
+
const runtime = await createRuntime({ skills, memoryStore: store });
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
**Busca por similaridade:**
|
|
889
|
+
|
|
890
|
+
```typescript
|
|
891
|
+
const results = await store.search(
|
|
892
|
+
{ resourceId: "user1", threadId: "thread1" },
|
|
893
|
+
"como foi implementado o módulo de orders?",
|
|
894
|
+
5 // topK
|
|
895
|
+
);
|
|
896
|
+
// results: [{ content: "...", score: 0.91 }, ...]
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
**`VectorIndex`** — índice vetorial in-memory para uso direto:
|
|
900
|
+
|
|
901
|
+
```typescript
|
|
902
|
+
import { VectorIndex } from "@ftarganski/omni-ai/memory";
|
|
903
|
+
|
|
904
|
+
const index = new VectorIndex<string>();
|
|
905
|
+
index.add("doc1", embeddingVector1);
|
|
906
|
+
index.add("doc2", embeddingVector2);
|
|
907
|
+
|
|
908
|
+
const results = index.query(queryVector, 3); // [{ id: "doc1", score: 0.94 }, ...]
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
---
|
|
912
|
+
|
|
913
|
+
## Estrutura do repositório
|
|
914
|
+
|
|
915
|
+
```
|
|
916
|
+
omni-ai/
|
|
917
|
+
│
|
|
918
|
+
├── packages/ # pacotes npm (pnpm workspaces)
|
|
919
|
+
│ ├── core/ # @omni-ai/core
|
|
920
|
+
│ │ └── src/
|
|
921
|
+
│ │ ├── types.ts # IProvider, ISkill, IAgent, IMemoryStore...
|
|
922
|
+
│ │ ├── config/
|
|
923
|
+
│ │ │ ├── schema.ts # Zod schema do omni-ai.yaml
|
|
924
|
+
│ │ │ └── loader.ts # loadConfig() com substituição de env vars
|
|
925
|
+
│ │ ├── agents/
|
|
926
|
+
│ │ │ ├── agent.ts # Loop agentico + integração de memória
|
|
927
|
+
│ │ │ └── loader.ts # loadAgent() — carrega YAML + resolve provider
|
|
928
|
+
│ │ ├── providers/registry.ts # ProviderRegistry (factory por type string)
|
|
929
|
+
│ │ ├── skills/registry.ts # SkillRegistry
|
|
930
|
+
│ │ └── bootstrap.ts # createRuntime() — API de alto nível
|
|
931
|
+
│ │
|
|
932
|
+
│ ├── provider-anthropic/ # @omni-ai/provider-anthropic
|
|
933
|
+
│ │ └── src/
|
|
934
|
+
│ │ ├── provider.ts # AnthropicProvider implements IProvider
|
|
935
|
+
│ │ ├── mappers.ts # Conversão omni-ai ↔ Anthropic SDK types
|
|
936
|
+
│ │ └── index.ts # Registra "anthropic" no ProviderRegistry
|
|
937
|
+
│ │
|
|
938
|
+
│ ├── provider-openai/ # @omni-ai/provider-openai
|
|
939
|
+
│ │ └── src/
|
|
940
|
+
│ │ ├── provider.ts # OpenAIProvider implements IProvider
|
|
941
|
+
│ │ ├── mappers.ts # Conversão omni-ai ↔ OpenAI SDK types
|
|
942
|
+
│ │ └── index.ts # Registra "openai" e "copilot" no ProviderRegistry
|
|
943
|
+
│ │
|
|
944
|
+
│ ├── memory/ # @omni-ai/memory
|
|
945
|
+
│ │ └── src/
|
|
946
|
+
│ │ ├── stores/
|
|
947
|
+
│ │ │ ├── in-memory.ts # InMemoryStore (padrão, sem persistência)
|
|
948
|
+
│ │ │ ├── sqlite.ts # SQLiteMemoryStore (arquivo local, FTS5)
|
|
949
|
+
│ │ │ └── semantic-memory-store.ts # SemanticMemoryStore (busca por cosine similarity)
|
|
950
|
+
│ │ ├── compactors/
|
|
951
|
+
│ │ │ ├── observation-masking.ts # Mascara tool results antigos (zero LLM)
|
|
952
|
+
│ │ │ └── summary.ts # Resumo por LLM (1 chamada por trigger)
|
|
953
|
+
│ │ ├── vector.ts # VectorIndex + cosineSimilarity
|
|
954
|
+
│ │ └── utils.ts # estimateTokens() compartilhado
|
|
955
|
+
│ │
|
|
956
|
+
│ ├── skills-fs/ # @omni-ai/skills-fs
|
|
957
|
+
│ │ └── src/
|
|
958
|
+
│ │ ├── read-file.ts # Lê arquivo (com validação de path traversal)
|
|
959
|
+
│ │ ├── write-file.ts # Escreve arquivo (com validação de path)
|
|
960
|
+
│ │ └── list-directory.ts # Lista diretório (com validação de path)
|
|
961
|
+
│ │
|
|
962
|
+
│ ├── skills-code/ # @omni-ai/skills-code
|
|
963
|
+
│ │ └── src/
|
|
964
|
+
│ │ └── search-code.ts # Busca texto/regex em arquivos TypeScript
|
|
965
|
+
│ │
|
|
966
|
+
│ ├── skills-ux/ # @omni-ai/skills-ux
|
|
967
|
+
│ │ └── src/
|
|
968
|
+
│ │ └── audit-accessibility.ts # Scan heurístico a11y de componentes TSX
|
|
969
|
+
│ │
|
|
970
|
+
│ └── cli/ # @omni-ai/cli
|
|
971
|
+
│ └── src/
|
|
972
|
+
│ ├── bin.ts # Entry point, carrega .env
|
|
973
|
+
│ ├── commands/
|
|
974
|
+
│ │ ├── run.ts # omni run <agent> "<prompt>"
|
|
975
|
+
│ │ ├── chain.ts # omni chain "<prompt>" <agent1> <agent2>...
|
|
976
|
+
│ │ ├── list.ts # omni list agents|skills|providers
|
|
977
|
+
│ │ └── init.ts # omni init — wizard interativo
|
|
978
|
+
│ └── utils/
|
|
979
|
+
│ ├── format.ts # Output formatado (tokens, iterações, erros)
|
|
980
|
+
│ └── config-path.ts # Resolve caminho do omni-ai.yaml
|
|
981
|
+
│
|
|
982
|
+
├── agents/ # Definições YAML dos agentes (21 agentes)
|
|
983
|
+
│ ├── backend/ # 7 agentes NestJS/TypeScript
|
|
984
|
+
│ ├── frontend/ # 5 agentes React/TypeScript
|
|
985
|
+
│ ├── ux/ # 5 agentes UX
|
|
986
|
+
│ └── qa/ # 4 agentes QA
|
|
987
|
+
│
|
|
988
|
+
├── docs/ # Documentação
|
|
989
|
+
│ ├── providers/
|
|
990
|
+
│ │ ├── anthropic.md # Setup detalhado Anthropic
|
|
991
|
+
│ │ ├── openai.md # Setup detalhado OpenAI
|
|
992
|
+
│ │ └── copilot.md # Setup detalhado GitHub Copilot
|
|
993
|
+
│ └── templates/
|
|
994
|
+
│ ├── agent.yaml # Template para novos agentes
|
|
995
|
+
│ └── skill.ts # Template para novas skills
|
|
996
|
+
│
|
|
997
|
+
├── config/
|
|
998
|
+
│ └── omni-ai.example.yaml # Template de configuração (copie → omni-ai.yaml)
|
|
999
|
+
│
|
|
1000
|
+
├── .env.example # Template de variáveis de ambiente
|
|
1001
|
+
└── tsconfig.ide.json # Paths para resolução de tipos no VS Code
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
---
|
|
1005
|
+
|
|
1006
|
+
## Usando de outro projeto
|
|
1007
|
+
|
|
1008
|
+
O `omni-ai` é um repositório central — os agentes e o config ficam nele. Você usa o CLI de dentro de qualquer projeto alvo.
|
|
1009
|
+
|
|
1010
|
+
### Setup único (instalação global)
|
|
1011
|
+
|
|
1012
|
+
```bash
|
|
1013
|
+
npm install -g @ftarganski/omni-ai
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
### Uso do dia a dia
|
|
1017
|
+
|
|
1018
|
+
```bash
|
|
1019
|
+
# 1. Entrar no projeto alvo
|
|
1020
|
+
cd /caminho/para/meu-projeto
|
|
1021
|
+
|
|
1022
|
+
# 2. Rodar agentes normalmente
|
|
1023
|
+
omni run backend-dev "crie o módulo de produtos"
|
|
1024
|
+
omni run frontend-dev "crie a página de listagem de produtos"
|
|
1025
|
+
omni run qa-lead "valide src/products/"
|
|
1026
|
+
omni run ux-reviewer "audite src/components/modules/Products/"
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
As skills sempre operam em `/caminho/para/meu-projeto` — o agente lê, escreve e busca arquivos nesse diretório, nunca fora dele.
|
|
1030
|
+
|
|
1031
|
+
### Alternativa sem instalação global
|
|
1032
|
+
|
|
1033
|
+
```bash
|
|
1034
|
+
# Usando node diretamente (após pnpm build)
|
|
1035
|
+
node /caminho/para/omni-ai/bundle/omni-ai/dist/cli/bin.js run backend-dev "..."
|
|
1036
|
+
|
|
1037
|
+
# Ou com alias no shell (~/.bashrc, ~/.zshrc ou $PROFILE no PowerShell)
|
|
1038
|
+
alias omni="node /caminho/para/omni-ai/bundle/omni-ai/dist/cli/bin.js"
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
---
|
|
1042
|
+
|
|
1043
|
+
## Estendendo o framework
|
|
1044
|
+
|
|
1045
|
+
### Criar um agente personalizado
|
|
1046
|
+
|
|
1047
|
+
Copie `docs/templates/agent.yaml` para `agents/<domínio>/<domínio>-<função>.yaml`:
|
|
1048
|
+
|
|
1049
|
+
```yaml
|
|
1050
|
+
name: my-agent
|
|
1051
|
+
description: O que este agente faz em uma linha
|
|
1052
|
+
# provider: anthropic # opcional — herda defaultProvider do omni-ai.yaml
|
|
1053
|
+
# model: gpt-4o-mini # opcional — herda defaultModel do provider
|
|
1054
|
+
systemPrompt: |
|
|
1055
|
+
Você é um assistente especializado em...
|
|
1056
|
+
Descreva as restrições, formato de output e comportamento.
|
|
1057
|
+
skills:
|
|
1058
|
+
- read-file
|
|
1059
|
+
- search-code
|
|
1060
|
+
- write-file
|
|
1061
|
+
maxIterations: 10
|
|
1062
|
+
temperature: 0.2
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
O arquivo estará disponível via `omni run my-agent "..."` imediatamente — sem rebuild.
|
|
1066
|
+
|
|
1067
|
+
### Criar uma skill personalizada
|
|
1068
|
+
|
|
1069
|
+
Copie `docs/templates/skill.ts` e implemente `ISkill`:
|
|
1070
|
+
|
|
1071
|
+
```typescript
|
|
1072
|
+
import type { ISkill } from "@ftarganski/omni-ai";
|
|
1073
|
+
import { z } from "zod";
|
|
1074
|
+
|
|
1075
|
+
const InputSchema = z.object({
|
|
1076
|
+
query: z.string().describe("Termo a buscar"),
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
type Input = z.infer<typeof InputSchema>;
|
|
1080
|
+
|
|
1081
|
+
export const myDatabaseSkill: ISkill<Input, string[]> = {
|
|
1082
|
+
name: "search-database",
|
|
1083
|
+
description: "Busca registros no banco de dados externo",
|
|
1084
|
+
|
|
1085
|
+
async execute(input: Input): Promise<string[]> {
|
|
1086
|
+
const { query } = InputSchema.parse(input);
|
|
1087
|
+
// sua lógica aqui
|
|
1088
|
+
return await fetchFromExternalApi(query);
|
|
1089
|
+
},
|
|
1090
|
+
};
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
Registre a skill ao criar o runtime:
|
|
1094
|
+
|
|
1095
|
+
```typescript
|
|
1096
|
+
import { createRuntime } from "@ftarganski/omni-ai";
|
|
1097
|
+
import { myDatabaseSkill } from "./my-database-skill.js";
|
|
1098
|
+
|
|
1099
|
+
const runtime = await createRuntime({
|
|
1100
|
+
skills: [myDatabaseSkill],
|
|
1101
|
+
});
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
Ou passe diretamente no CLI customizando o `run.ts`.
|
|
1105
|
+
|
|
1106
|
+
### Criar um provider personalizado
|
|
1107
|
+
|
|
1108
|
+
Implemente `IProvider` de `@ftarganski/omni-ai`:
|
|
1109
|
+
|
|
1110
|
+
```typescript
|
|
1111
|
+
import type { IProvider, CompletionRequest, CompletionResponse } from "@ftarganski/omni-ai";
|
|
1112
|
+
import { registerProvider } from "@ftarganski/omni-ai";
|
|
1113
|
+
|
|
1114
|
+
class MyProvider implements IProvider {
|
|
1115
|
+
readonly name: string;
|
|
1116
|
+
readonly capabilities = {
|
|
1117
|
+
chat: true, embedding: false, streaming: false, toolUse: true, vision: false,
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
constructor(private readonly config: { apiKey: string; name: string }) {
|
|
1121
|
+
this.name = config.name;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
async complete(request: CompletionRequest): Promise<CompletionResponse> {
|
|
1125
|
+
const response = await callMyApi(request);
|
|
1126
|
+
return {
|
|
1127
|
+
content: response.text,
|
|
1128
|
+
toolCalls: [],
|
|
1129
|
+
usage: { inputTokens: response.in, outputTokens: response.out },
|
|
1130
|
+
model: request.model ?? "my-model",
|
|
1131
|
+
provider: this.name,
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
// Registrar o type string para o omni-ai.yaml
|
|
1137
|
+
registerProvider("my-provider", (config) => new MyProvider(config));
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
Adicione o `docs/providers/<nome>.md` e declare no `omni-ai.yaml`:
|
|
1141
|
+
|
|
1142
|
+
```yaml
|
|
1143
|
+
providers:
|
|
1144
|
+
- name: my-provider
|
|
1145
|
+
type: my-provider
|
|
1146
|
+
apiKey: ${MY_API_KEY}
|
|
1147
|
+
defaultModel: my-model-v1
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
---
|
|
1151
|
+
|
|
1152
|
+
## Recursos avançados
|
|
1153
|
+
|
|
1154
|
+
### Agentes paralelos — `parallel()`
|
|
1155
|
+
|
|
1156
|
+
Executa múltiplos agentes ao mesmo tempo no mesmo input e agrega os resultados.
|
|
1157
|
+
|
|
1158
|
+
```typescript
|
|
1159
|
+
import { createRuntime, parallel } from "@ftarganski/omni-ai";
|
|
1160
|
+
|
|
1161
|
+
const runtime = await createRuntime({ skills });
|
|
1162
|
+
|
|
1163
|
+
const result = await parallel(runtime, {
|
|
1164
|
+
agents: ["backend-dev", "qa-backend", "ux-reviewer"],
|
|
1165
|
+
input: "revise o módulo de orders para qualidade, testes e acessibilidade",
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
for (const [agent, outcome] of Object.entries(result.results)) {
|
|
1169
|
+
if ("error" in outcome) {
|
|
1170
|
+
console.error(`${agent}: ${outcome.error}`);
|
|
1171
|
+
} else {
|
|
1172
|
+
console.log(`${agent} (${outcome.iterations} iterações):\n${outcome.output}\n`);
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
console.log(`Tokens totais: ${result.usage.inputTokens + result.usage.outputTokens}`);
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
Um agente com falha não cancela os demais — `parallel()` usa `Promise.allSettled` internamente.
|
|
1180
|
+
|
|
1181
|
+
---
|
|
1182
|
+
|
|
1183
|
+
### SkillMiddleware
|
|
1184
|
+
|
|
1185
|
+
Intercepção configurável ao redor de cada chamada de skill. Útil para logging, rate-limiting, cache e auditoria.
|
|
1186
|
+
|
|
1187
|
+
```typescript
|
|
1188
|
+
import { createRuntime } from "@ftarganski/omni-ai";
|
|
1189
|
+
import type { SkillMiddlewareFn } from "@ftarganski/omni-ai";
|
|
1190
|
+
|
|
1191
|
+
// Middleware de logging
|
|
1192
|
+
const loggingMiddleware: SkillMiddlewareFn = async (name, input, ctx, next) => {
|
|
1193
|
+
console.time(`skill:${name}`);
|
|
1194
|
+
const result = await next();
|
|
1195
|
+
console.timeEnd(`skill:${name}`);
|
|
1196
|
+
return result;
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1199
|
+
// Middleware de cache em memória
|
|
1200
|
+
const cache = new Map<string, unknown>();
|
|
1201
|
+
const cachingMiddleware: SkillMiddlewareFn = async (name, input, ctx, next) => {
|
|
1202
|
+
const key = `${name}:${JSON.stringify(input)}`;
|
|
1203
|
+
if (cache.has(key)) return cache.get(key);
|
|
1204
|
+
const result = await next();
|
|
1205
|
+
cache.set(key, result);
|
|
1206
|
+
return result;
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
const runtime = await createRuntime({ skills });
|
|
1210
|
+
|
|
1211
|
+
// Middleware configurado por agente no YAML ou programaticamente
|
|
1212
|
+
const result = await runtime.run("backend-dev", "revise os arquivos em src/", {
|
|
1213
|
+
middleware: [loggingMiddleware, cachingMiddleware],
|
|
1214
|
+
});
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
A cadeia executa na ordem de declaração: cada middleware chama `next()` para passar o controle ao próximo, com a skill real no fundo da pilha.
|
|
1218
|
+
|
|
1219
|
+
---
|
|
1220
|
+
|
|
1221
|
+
### MCP — Model Context Protocol
|
|
1222
|
+
|
|
1223
|
+
#### Servidor: expor skills como ferramentas MCP
|
|
1224
|
+
|
|
1225
|
+
```typescript
|
|
1226
|
+
import { createMcpServer } from "@ftarganski/omni-ai/mcp";
|
|
1227
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
1228
|
+
import { readFileSkill, writeFileSkill } from "@ftarganski/omni-ai/skills/fs";
|
|
1229
|
+
|
|
1230
|
+
const server = createMcpServer([readFileSkill, writeFileSkill], { name: "omni-ai" });
|
|
1231
|
+
await server.connect(new StdioServerTransport());
|
|
1232
|
+
```
|
|
1233
|
+
|
|
1234
|
+
Via CLI:
|
|
1235
|
+
|
|
1236
|
+
```bash
|
|
1237
|
+
omni mcp serve
|
|
1238
|
+
```
|
|
1239
|
+
|
|
1240
|
+
#### Cliente: consumir um servidor MCP como skills
|
|
1241
|
+
|
|
1242
|
+
```typescript
|
|
1243
|
+
import { connectMcpSkills } from "@ftarganski/omni-ai/mcp";
|
|
1244
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
1245
|
+
import { createRuntime } from "@ftarganski/omni-ai";
|
|
1246
|
+
|
|
1247
|
+
// Conecta a um servidor MCP externo e descobre seus tools
|
|
1248
|
+
const transport = new StdioClientTransport({ command: "npx", args: ["-y", "@my/mcp-server"] });
|
|
1249
|
+
const mcpSkills = await connectMcpSkills(transport);
|
|
1250
|
+
|
|
1251
|
+
// Usa os tools remotos como qualquer ISkill nativa
|
|
1252
|
+
const runtime = await createRuntime({ skills: mcpSkills });
|
|
1253
|
+
const result = await runtime.run("backend-dev", "pesquise na documentação o contrato da API");
|
|
1254
|
+
```
|
|
1255
|
+
|
|
1256
|
+
---
|
|
1257
|
+
|
|
1258
|
+
## Interfaces TypeScript principais
|
|
1259
|
+
|
|
1260
|
+
```typescript
|
|
1261
|
+
// @ftarganski/omni-ai
|
|
1262
|
+
|
|
1263
|
+
interface IProvider {
|
|
1264
|
+
readonly name: string;
|
|
1265
|
+
readonly capabilities: ProviderCapabilities;
|
|
1266
|
+
complete(request: CompletionRequest): Promise<CompletionResponse>;
|
|
1267
|
+
embed?(request: EmbeddingRequest): Promise<EmbeddingResponse>; // requer capabilities.embedding = true
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
interface ProviderCapabilities {
|
|
1271
|
+
chat: boolean;
|
|
1272
|
+
embedding: boolean;
|
|
1273
|
+
streaming: boolean; // suporte a onToken em CompletionRequest
|
|
1274
|
+
toolUse: boolean;
|
|
1275
|
+
vision: boolean;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
interface CompletionRequest {
|
|
1279
|
+
messages: Message[];
|
|
1280
|
+
model?: string;
|
|
1281
|
+
temperature?: number;
|
|
1282
|
+
systemPrompt?: string;
|
|
1283
|
+
tools?: ToolDefinition[];
|
|
1284
|
+
onToken?: (chunk: string) => void; // habilita streaming chunk a chunk
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
interface ISkill<TInput = unknown, TOutput = unknown> {
|
|
1288
|
+
readonly name: string;
|
|
1289
|
+
readonly description: string;
|
|
1290
|
+
execute(input: TInput, ctx: SkillContext): Promise<TOutput>;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
interface IAgent {
|
|
1294
|
+
readonly config: AgentConfig;
|
|
1295
|
+
run(options: AgentRunOptions): Promise<AgentRunResult>;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
// Intercepta a execução de cada skill — chame next() para continuar a cadeia
|
|
1299
|
+
type SkillMiddlewareFn = (
|
|
1300
|
+
name: string,
|
|
1301
|
+
input: unknown,
|
|
1302
|
+
ctx: SkillContext,
|
|
1303
|
+
next: () => Promise<unknown>
|
|
1304
|
+
) => Promise<unknown>;
|
|
1305
|
+
|
|
1306
|
+
interface AgentConfig {
|
|
1307
|
+
name: string;
|
|
1308
|
+
description: string;
|
|
1309
|
+
provider?: string; // opcional — herda defaultProvider
|
|
1310
|
+
model?: string; // opcional — herda defaultModel do provider
|
|
1311
|
+
systemPrompt: string;
|
|
1312
|
+
skills?: string[];
|
|
1313
|
+
maxIterations?: number; // padrão: 10
|
|
1314
|
+
temperature?: number;
|
|
1315
|
+
memory?: MemoryConfig;
|
|
1316
|
+
middleware?: SkillMiddlewareFn[]; // interceptação de tool calls
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
interface AgentRunOptions {
|
|
1320
|
+
input: string;
|
|
1321
|
+
context?: Record<string, unknown>;
|
|
1322
|
+
session?: SessionId; // habilita persistência de memória
|
|
1323
|
+
onToken?: (chunk: string) => void; // habilita streaming de tokens em tempo real
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
interface AgentRunResult {
|
|
1327
|
+
output: string;
|
|
1328
|
+
iterations: number;
|
|
1329
|
+
usage?: { inputTokens: number; outputTokens: number };
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
interface SessionId {
|
|
1333
|
+
resourceId: string; // identificador estável (ex: user ID, workspace ID)
|
|
1334
|
+
threadId: string; // identificador da conversa ou feature
|
|
1335
|
+
}
|
|
1336
|
+
```
|
|
1337
|
+
|
|
1338
|
+
---
|
|
1339
|
+
|
|
1340
|
+
## Arquitetura de pacotes
|
|
1341
|
+
|
|
1342
|
+
O npm publica um único pacote com subpath exports:
|
|
1343
|
+
|
|
1344
|
+
```
|
|
1345
|
+
@ftarganski/omni-ai ← core: Agent, Runtime, ISkill, IProvider...
|
|
1346
|
+
@ftarganski/omni-ai/skills ← todas as skills
|
|
1347
|
+
@ftarganski/omni-ai/skills/fs ← read-file, write-file, list-directory
|
|
1348
|
+
@ftarganski/omni-ai/skills/git ← git-diff, git-log, git-status, git-commit-message
|
|
1349
|
+
@ftarganski/omni-ai/skills/code ← search-code
|
|
1350
|
+
@ftarganski/omni-ai/skills/http ← http-request
|
|
1351
|
+
@ftarganski/omni-ai/skills/ux ← audit-accessibility
|
|
1352
|
+
@ftarganski/omni-ai/skills/multimodal ← analyze-image
|
|
1353
|
+
@ftarganski/omni-ai/skills/backend ← analyze-dynamo-schema, analyze-graphql-schema, ...
|
|
1354
|
+
@ftarganski/omni-ai/skills/frontend ← analyze-component, analyze-module-structure, ...
|
|
1355
|
+
@ftarganski/omni-ai/skills/qa ← analyze-test-coverage, find-test-pattern
|
|
1356
|
+
@ftarganski/omni-ai/memory ← SQLiteMemoryStore, InMemoryStore, compactors, VectorIndex
|
|
1357
|
+
@ftarganski/omni-ai/mcp ← createMcpServer, connectMcpSkills, McpSkill
|
|
1358
|
+
@ftarganski/omni-ai/provider-anthropic ← AnthropicProvider
|
|
1359
|
+
@ftarganski/omni-ai/provider-openai ← OpenAIProvider (+ Copilot, Groq, Ollama)
|
|
1360
|
+
@ftarganski/omni-ai/provider-google ← GoogleProvider
|
|
1361
|
+
bin: omni ← CLI completo
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
Internamente o repositório é um monorepo com pacotes separados (`packages/core`, `packages/skills`, etc.) que são bundlados pelo tsup no pacote único publicado.
|
|
1365
|
+
|
|
1366
|
+
---
|
|
1367
|
+
|
|
1368
|
+
## Comandos de desenvolvimento
|
|
1369
|
+
|
|
1370
|
+
```bash
|
|
1371
|
+
# Instalar dependências
|
|
1372
|
+
pnpm install
|
|
1373
|
+
|
|
1374
|
+
# Build de todos os pacotes
|
|
1375
|
+
pnpm build
|
|
1376
|
+
|
|
1377
|
+
# Type-check sem build
|
|
1378
|
+
pnpm typecheck
|
|
1379
|
+
|
|
1380
|
+
# Lint em todos os pacotes
|
|
1381
|
+
pnpm lint
|
|
1382
|
+
|
|
1383
|
+
# Rodar testes
|
|
1384
|
+
pnpm test
|
|
1385
|
+
|
|
1386
|
+
# Build de um pacote interno específico
|
|
1387
|
+
pnpm --filter @omni-ai/core build
|
|
1388
|
+
|
|
1389
|
+
# Reconstruir e testar o CLI
|
|
1390
|
+
pnpm build && omni list agents
|
|
1391
|
+
```
|
|
1392
|
+
|
|
1393
|
+
---
|
|
1394
|
+
|
|
1395
|
+
## Roadmap
|
|
1396
|
+
|
|
1397
|
+
### Concluído
|
|
1398
|
+
|
|
1399
|
+
**Pacote publicado**
|
|
1400
|
+
- [x] `@ftarganski/omni-ai` — pacote único com todos os subpaths, bin `omni`, bundlado via tsup
|
|
1401
|
+
|
|
1402
|
+
**Internamente (monorepo, não publicados)**
|
|
1403
|
+
- [x] core — interfaces, ProviderRegistry, SkillRegistry, config schema (Zod), `parallel()`, `SkillMiddleware`
|
|
1404
|
+
- [x] memory — InMemoryStore, SQLiteMemoryStore, SemanticMemoryStore, VectorIndex, ObservationMaskingCompactor, SummaryCompactor
|
|
1405
|
+
- [x] mcp — servidor MCP (expõe skills como tools) e cliente MCP (`McpSkill`, `connectMcpSkills`)
|
|
1406
|
+
- [x] provider-anthropic — adapter completo com mapeamento de tipos, tool use e streaming
|
|
1407
|
+
- [x] provider-openai — cobre OpenAI, GitHub Copilot, Groq, Ollama e qualquer endpoint OpenAI-compatible
|
|
1408
|
+
- [x] provider-google — adapter Google Gemini com chat, vision e embeddings
|
|
1409
|
+
- [x] skills — 20 skills em 8 subpaths: fs, code, ux, git, http, multimodal, backend, frontend, qa
|
|
1410
|
+
- [x] cli — `omni run`, `omni list`, `omni chain`, `omni init`, `omni new`, `omni serve`, `omni watch`, `omni eval`, `omni export`, `omni mcp serve`
|
|
1411
|
+
|
|
1412
|
+
**Core**
|
|
1413
|
+
- [x] Bootstrap `createRuntime()` — API de alto nível para uso programático
|
|
1414
|
+
- [x] 21 agentes prontos — backend (7), frontend (5), ux (5), qa (4)
|
|
1415
|
+
- [x] Herança de provider/modelo — agentes herdam do config, podem sobrescrever
|
|
1416
|
+
- [x] Agentes inline — definição direta no `omni-ai.yaml`
|
|
1417
|
+
- [x] Streaming de tokens em tempo real
|
|
1418
|
+
- [x] Memória e sessões — SQLite persistente com FTS5 e busca semântica por embeddings
|
|
1419
|
+
- [x] Compactors — redução automática de contexto (masking + summarization)
|
|
1420
|
+
- [x] Retry automático com backoff exponencial + fallback de provider
|
|
1421
|
+
- [x] `SkillMiddleware` — cadeia de interceptação configurável por agente
|
|
1422
|
+
- [x] `parallel()` — execução concorrente de múltiplos agentes com agregação de resultados
|
|
1423
|
+
- [x] Suporte multimodal — `ContentPart[]` em mensagens; `analyze-image` skill
|
|
1424
|
+
- [x] Compatibilidade MCP — `omni mcp serve` (stdio), `McpSkill` para consumir servers externos
|
|
1425
|
+
- [x] 296 testes automatizados — 41 arquivos, cobertura ≥ 80% em todas as métricas
|
|
1426
|
+
- [x] Biome — linting e formatação unificados em todos os pacotes
|
|
1427
|
+
- [x] CI/CD — GitHub Actions: lint → build → typecheck → test; branch protection; publish workflow
|
|
1428
|
+
|
|
1429
|
+
### Próximos passos
|
|
1430
|
+
|
|
1431
|
+
**CLI & DX**
|
|
1432
|
+
- [x] `omni new` — scaffold interativo para criar agente, skill ou provider a partir de template
|
|
1433
|
+
- [x] `omni eval` — avaliação em lote: roda agente contra dataset de `(input, expected)` e reporta acurácia
|
|
1434
|
+
- [x] `omni serve` — inicia servidor HTTP local para chamar agentes via REST ou SSE (sem CLI)
|
|
1435
|
+
- [x] `omni watch` — reexecuta agente automaticamente quando arquivos do projeto mudam (modo dev)
|
|
1436
|
+
- [x] `omni export` — exporta histórico de sessão em markdown ou JSON
|
|
1437
|
+
|
|
1438
|
+
**Providers & resiliência**
|
|
1439
|
+
- [x] `@omni-ai/provider-google` — adapter para Gemini 1.5 / 2.0 (chat, vision, embeddings)
|
|
1440
|
+
- [x] Suporte a Groq — modelos Llama/DeepSeek via LPU (free tier, sem cartão)
|
|
1441
|
+
- [x] Suporte a Ollama — modelos locais sem API key (Llama, Qwen, Phi, DeepSeek)
|
|
1442
|
+
- [x] Retry automático com backoff exponencial — recuperação transparente de rate-limit e erros 5xx
|
|
1443
|
+
- [x] Fallback de provider — rota pedidos para um provider secundário quando o primário falha
|
|
1444
|
+
|
|
1445
|
+
**Skills**
|
|
1446
|
+
- [x] `@omni-ai/skills-git` — git status, diff, log, commit message (para agentes de review e release)
|
|
1447
|
+
- [x] `@omni-ai/skills-http` — chamadas HTTP autenticadas (OAuth/Bearer) para integrar APIs externas
|
|
1448
|
+
- [x] Suporte multimodal — skill `analyze-image` para análise de screenshots, diagramas e mockups
|
|
1449
|
+
|
|
1450
|
+
**Core**
|
|
1451
|
+
- [x] Compatibilidade MCP (Model Context Protocol) — expor skills como tools MCP e consumir servidores MCP externos
|
|
1452
|
+
- [x] Agentes paralelos — `parallel()` wrapper para rodar agentes concorrentemente e agregar resultados
|
|
1453
|
+
- [x] `SkillMiddleware` — hooks de interceptação para logging, rate-limiting e cache de tool calls
|
|
1454
|
+
- [x] Publicação npm — publicar os pacotes `@omni-ai/*` no registro público do npm
|
|
1455
|
+
|
|
1456
|
+
---
|
|
1457
|
+
|
|
1458
|
+
## Troubleshooting
|
|
1459
|
+
|
|
1460
|
+
**`omni: command not found`**
|
|
1461
|
+
O CLI não está vinculado globalmente. Execute `pnpm --filter @omni-ai/cli link --global` na raiz do `omni-ai`, ou use `node packages/cli/dist/bin.js` diretamente.
|
|
1462
|
+
|
|
1463
|
+
**`Provider "anthropic" not found in config`**
|
|
1464
|
+
O arquivo `config/omni-ai.yaml` não existe ou não declara o provider. Execute `omni init` para criá-lo, ou copie `config/omni-ai.example.yaml`.
|
|
1465
|
+
|
|
1466
|
+
**`Error: ANTHROPIC_API_KEY is not set`**
|
|
1467
|
+
A variável de ambiente não está carregada. Verifique se `.env` existe e contém a chave. O CLI carrega `.env` automaticamente, mas você pode validar com `node -e "require('dotenv').config(); console.log(process.env.ANTHROPIC_API_KEY)"`.
|
|
1468
|
+
|
|
1469
|
+
**`maxIterations exceeded`**
|
|
1470
|
+
O agente atingiu o limite de iterações sem concluir. Aumente `maxIterations` no YAML do agente ou torne o prompt mais específico para reduzir o número de tool calls.
|
|
1471
|
+
|
|
1472
|
+
**Tokens consumidos muito altos**
|
|
1473
|
+
Use `ObservationMaskingCompactor` via API programática para mascarar tool results antigos. Reduz o contexto em até 70% em agentes intensivos em leitura de arquivos.
|
|
1474
|
+
|
|
1475
|
+
**`Access denied: path resolves outside the working directory`**
|
|
1476
|
+
O agente tentou acessar um arquivo fora do `cwd`. Execute o comando de dentro do diretório do projeto alvo, ou verifique se o agente está usando paths relativos corretos.
|
|
1477
|
+
|
|
1478
|
+
**Build falha com `Cannot find module`**
|
|
1479
|
+
O pacote referenciado não foi buildado ainda. Execute `pnpm build` na raiz para compilar todos os pacotes na ordem correta de dependências.
|
|
1480
|
+
|
|
1481
|
+
---
|
|
1482
|
+
|
|
1483
|
+
## Licença
|
|
1484
|
+
|
|
1485
|
+
MIT
|