166 lines
4.9 KiB
Markdown
166 lines
4.9 KiB
Markdown
---
|
|
name: clip-agent
|
|
description: Gerir agente Paperclip individual — estado, config, AGENTS.md, histórico runs, issues. Aceita nome como argumento. Usar quando "clip agent", "agente clip", "ver agente", "estado do CTO".
|
|
context: fork
|
|
layer: wiki
|
|
---
|
|
|
|
# /clip-agent — Gerir Agente Paperclip
|
|
|
|
Aceita argumento: nome do agente (ex: `/clip-agent CTO`).
|
|
|
|
## Constantes
|
|
|
|
```
|
|
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
|
|
COMPANY_ID: ebe10308-efd7-453f-86ab-13e6fe84004f
|
|
AGENTS_PATH: /media/ealmeida/Dados/Hub/04-Stack/02.06-Clip/agents/
|
|
```
|
|
|
|
## Procedimento
|
|
|
|
### Passo 1: Contexto completo do agente
|
|
|
|
Invocar tool MCP: `mcp__paperclip__diag_agent_full_context(agent_name="{{NOME}}")`
|
|
|
|
Esta tool retorna config, últimas runs, membership, permissões e tokens — cobre os Passos 1, 3, 6, 7 e 7b de uma só vez. Se multiplos resultados, mostrar lista e pedir clarificacao.
|
|
|
|
### Passo 2: Hierarquia
|
|
|
|
Quem lhe reporta:
|
|
```sql
|
|
SELECT name, role, status FROM agents
|
|
WHERE reports_to = '{{AGENT_ID}}'
|
|
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
|
ORDER BY role, name;
|
|
```
|
|
|
|
A quem reporta:
|
|
```sql
|
|
SELECT name, role FROM agents WHERE id = '{{REPORTS_TO_ID}}';
|
|
```
|
|
|
|
### Passo 3: Ultimas 5 runs
|
|
|
|
```sql
|
|
SELECT hr.status, hr.started_at, hr.finished_at, LEFT(hr.error, 80) as erro
|
|
FROM heartbeat_runs hr
|
|
WHERE hr.agent_id = '{{AGENT_ID}}'
|
|
ORDER BY hr.started_at DESC LIMIT 5;
|
|
```
|
|
|
|
### Passo 4: Issues atribuidas
|
|
|
|
```sql
|
|
SELECT title, status, priority FROM issues
|
|
WHERE assignee_agent_id = '{{AGENT_ID}}'
|
|
AND status NOT IN ('done','cancelled')
|
|
ORDER BY priority, status;
|
|
```
|
|
|
|
### Passo 4b: Verificar falsos blockers (INC-07)
|
|
|
|
Se o agente tem issues `blocked`, invocar tool MCP: `mcp__paperclip__diag_false_blockers` e filtrar pelo agente. TODO: criar diag_* tool per-agent se uso recorrente.
|
|
|
|
Se `sub_activas > 0` e o agente está operacional → falso blocker. Alertar: "Issue {{ID}} marcada como blocked mas tem sub-tasks activas — deveria ser in_progress."
|
|
|
|
### Passo 5: AGENTS.md
|
|
|
|
Procurar em `AGENTS_PATH`:
|
|
```bash
|
|
find /media/ealmeida/Dados/Hub/04-Stack/02.06-Clip/agents/ -name "AGENTS.md" -exec grep -l "{{NOME}}" {} \;
|
|
```
|
|
|
|
Se encontrado, ler e apresentar resumo (primeiras 30 linhas).
|
|
|
|
## Formato de output
|
|
|
|
```
|
|
## Agente: {{NOME}}
|
|
|
|
**Role:** {{role}} | **Status:** {{status}} | **Ultimo heartbeat:** {{last_heartbeat_at}}
|
|
**Reporta a:** {{reports_to_name}} | **Budget:** {{spent}}/{{budget}} ({{pct}}%)
|
|
**Tokens cached:** {{tokens_M}}M | **CWD:** {{cwd}} | **Model:** {{model}}
|
|
|
|
### Equipa (reportam a este agente)
|
|
| Nome | Role | Status |
|
|
...
|
|
|
|
### Ultimas 5 runs
|
|
| Status | Início | Fim | Erro |
|
|
...
|
|
|
|
### Issues atribuidas
|
|
| Titulo | Status | Prioridade |
|
|
...
|
|
|
|
### Skills atribuidas
|
|
[lista de desiredSkills ou "Sem skills (apenas built-in paperclip)"]
|
|
|
|
### AGENTS.md
|
|
[resumo ou path]
|
|
```
|
|
|
|
### Passo 6: Skills do agente
|
|
|
|
```sql
|
|
SELECT
|
|
adapter_config->'paperclipSkillSync'->'desiredSkills' as desired_skills
|
|
FROM agents
|
|
WHERE id = '{{AGENT_ID}}';
|
|
```
|
|
|
|
Se nao NULL, listar as skills. Se NULL, indicar "Sem skills atribuidas (apenas built-in paperclip)".
|
|
|
|
Para ver detalhes das skills disponiveis na empresa:
|
|
```sql
|
|
SELECT name, slug, key, source_type FROM company_skills
|
|
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
|
ORDER BY name;
|
|
```
|
|
|
|
### Skills atribuídas ao agente
|
|
|
|
```sql
|
|
-- Ver skills desejadas (configuradas via API)
|
|
SELECT
|
|
a.name as agente,
|
|
a.adapter_config->'paperclipSkillSync'->'desiredSkills' as desired_skills
|
|
FROM agents a
|
|
WHERE a.id = '{{AGENT_ID}}';
|
|
```
|
|
|
|
**Acções disponíveis:**
|
|
- Ver skills da empresa: `SELECT name, slug FROM company_skills WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'`
|
|
- Atribuir skills via API (fetch no browser): `POST /api/agents/{{AGENT_ID}}/skills/sync` com `{ "desiredSkills": ["slug1", "slug2"] }`
|
|
|
|
### Membership (OBRIGATÓRIO — sem isto, permissões não funcionam)
|
|
|
|
A função `hasPermission()` verifica **primeiro** se o agente tem membership activa em `company_memberships`. Sem membership → permissão negada mesmo com grants correctos.
|
|
|
|
```sql
|
|
-- Verificar membership
|
|
SELECT status, membership_role FROM company_memberships
|
|
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
|
AND principal_id = '{{AGENT_ID}}';
|
|
```
|
|
|
|
Se **0 rows** → agente não tem membership. Criar:
|
|
```sql
|
|
INSERT INTO company_memberships (id, company_id, principal_type, principal_id, status, membership_role, created_at, updated_at)
|
|
VALUES (gen_random_uuid(), 'ebe10308-efd7-453f-86ab-13e6fe84004f', 'agent', '{{AGENT_ID}}', 'active', 'member', NOW(), NOW());
|
|
```
|
|
|
|
**Nota:** Agentes criados via SQL directo NÃO recebem membership automaticamente — apenas os onboarded via fluxo OpenClaw/hiring. Sempre criar membership ao adicionar agentes manualmente.
|
|
|
|
### Permissões do agente
|
|
|
|
```sql
|
|
SELECT permission_key FROM principal_permission_grants
|
|
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
|
AND principal_id = '{{AGENT_ID}}';
|
|
```
|
|
|
|
Para adicionar `tasks:assign` (necessário para delegação):
|
|
```sql
|
|
INSERT INTO principal_permissi |