Ferramentas e skills#
GETCatálogo de ferramentas#
GET /v1/agent-tools — as ferramentas selecionáveis (embutidas ∪ custom):
{ tools: [ { name, label, description } ] }.
generate_image — o agente gera uma imagem no meio do run#
Habilite como qualquer built-in ("tools": ["generate_image"]) e o agente passa a
poder produzir uma imagem REAL durante o run, em vez de apenas descrevê-la. O modelo
chama a ferramenta com:
| argumento | obrigatório | valores |
|---|---|---|
prompt |
sim | texto, até 4000 caracteres |
aspect |
não | square (padrão), portrait, landscape |
quality |
não | draft, standard (padrão), high |
n |
não | 1 a 4 (padrão 1) |
O resultado que o agente recebe — e que aparece no tool_calls do turno — traz
images[].url (URL assinada, ver §Geração de imagens para o TTL e como baixar),
asset_id, mime_type, byte_size, mais model_used e revised_prompt. O base64
inline não vem: o resultado da tool ocupa a janela de contexto do modelo, e a URL
entrega a imagem sem custar contexto. Toda geração entra no histórico do tenant
(GET /v1/images/generations), então baixar depois é um read normal.
Não há como o modelo escolher size, model ou imagens de referência: aspect já
seleciona o tamanho, o modelo padrão é decisão de custo da sua conta, e referências
continuam disponíveis nas rotas de geração onde você as fornece.
Cada chamada gasta de verdade — em dólar ou em quota. A ferramenta resolve a sua
OPENAI_API_KEYdo cofre (GET/PUT /v1/tool-secrets), cai para a chave de plataforma, e — se nenhuma existir — cai para o modelo de assinaturacodex/gpt-image-2, que não precisa de chave nenhuma. Ou seja: com o cofre vazio o agente ainda gera imagem, e você lê no resultado qual caminho foi usado (provider:openai= crédito de API,codex= assinatura;key_source:vault|platform|subscription). No caminho de assinatura,aspectequalitysão advisory — o backend decide, e a resposta reporta osize/qualityque ele realmente produziu.
IMAGE_KEY_REQUIREDsó aparece quando não há chave nem caminho de assinatura; uma credencial que o provedor recusa (expirada, revogada, sem billing) devolveIMAGE_PROVIDER_REJECTED— nesse caso revise a chave no cofre, não os argumentos.
GETCatálogo de modelos e provedores#
GET /v1/llm-catalog (alias: GET /v1/providers) — o catálogo de modelos,
agrupado por provedor. Use-o para popular a sua UI com provedores, modelos,
janelas de contexto e efforts REAIS em vez de descobrir por tentativa:
Modelos OpenAI aposentados. A plataforma roda OpenAI 5.6 e mais novos. Gerações anteriores —
gpt-5.5,gpt-5.4,gpt-5.4-mini,gpt-5.4-nano,gpt-5.3-codex,gpt-4o,gpt-4o-mini,gpt-4.1*e a sérieo1/o3/o4— não aparecem mais neste catálogo e são recusadas com400 MODEL_RETIREDao criar/atualizar um agente (inclusive viadefault_modelno compat). A rejeição é explícita de propósito: preferimos que a sua integração falhe no write, e não que ela rode meses num modelo diferente do que pediu. Migre paragpt-5.6-luna(o mais barato),gpt-5.6-terraougpt-5.6-sol— ou para a família GPT-6.Família GPT-6 (desde 2026-09-25).
gpt-6-luna,gpt-6-solegpt-6-astraestão no catálogo, pela API key (openai, effortslow|medium|high) e pela assinatura (codex/gpt-6-*, efforts atémax, custo0). A geração 6 é nomeada sem versão menor (gpt-6-luna, nãogpt-6.0-luna); até esta data o piso lia isso como a nomenclatura antiga e respondia400 MODEL_RETIREDpara o id crugpt-6-*. Corrigido: o piso continua sendo "OpenAI 5.6 e mais novos", e a 6 está acima dele.Isso vale só para o provedor OpenAI. Modelos de outros provedores não mudaram — inclusive
gpt-oss-*, que apesar do prefixogpt-é o modelo de pesos abertos servido por Cerebras/OpenRouter e continua disponível.
Provedor codex — GPT-5.6 Luna com effort max#
O grupo codex ("OpenAI (ChatGPT subscription)") expõe:
| id | Efforts | Custo reportado |
|---|---|---|
codex/gpt-5.6-luna |
low, medium, high, xhigh, max |
0 |
codex/gpt-5.6-sol |
low, medium, high, xhigh, max |
0 |
codex/gpt-6-luna |
low, medium, high, xhigh, max |
0 |
codex/gpt-6-sol |
low, medium, high, xhigh, max |
0 |
codex/gpt-6-astra |
low, medium, high, xhigh, max |
0 |
Use o id com o prefixo codex/ — é ele que roteia para este provedor:
{ "model": "codex/gpt-5.6-sol", "reasoning_effort": "max" }
Correção de contrato (2026-08-16). Até esta data, runs em
codex/gpt-5.6-solvinham comtotal_cost_usdcalculado à tarifa de API dogpt-5.6-sol($5/$30 por 1M) em vez de0. Era um defeito do nosso medidor, não uma cobrança: nenhum desses valores foi faturado por ninguém. O custo agora é decidido pelo provedor resolvido — qualquer modelo servido por um provedor de assinatura reporta0, tenha ou não linha de catálogo. Se você arquivoutotal_cost_usdde runscodex/*antes desta data, esses números estão inflados e devem ser lidos como0.
Duas diferenças que importam para a sua integração:
xhighemaxfuncionam aqui. Nogpt-5.6-lunanormal (provedoropenai) os efforts param emhigh; pedirmaxlá é aceito mas o modelo raciocina comohigh. Emcodex/gpt-5.6-lunaomaxé repassado de verdade. Consultethinking_effortsno catálogo em vez de assumir.input_cost_per_1meoutput_cost_per_1msão0, e as runs saem comtotal_cost_usd: 0. Não é modelo grátis nem erro de catálogo: é um plano de assinatura de valor fixo, então não existe custo por token para reportar. Se o seu billing somatotal_cost_usd, este provedor contribui zero por contrato — não trate como dado faltando. Isso vale para todo modelo do grupocodex, inclusive um que ainda não esteja listado acima: o preço sai do provedor, não do id.
O available deste grupo pode vir false (assinatura não configurada no
ambiente). Cheque available antes de oferecer o modelo na sua UI — é
exatamente para isso que ele existe. Enquanto false, use gpt-5.6-luna do
grupo openai, que é o mesmo modelo cobrado por token.
{
"providers": [
{
"provider": "kimi", "label": "Kimi", "available": true,
"models": [
{ "id": "k3", "provider": "kimi", "label": "K3",
"context_window": 1048576, "max_output_tokens": null,
"input_cost_per_1m": 0, "output_cost_per_1m": 0,
"supports_tools": true, "supports_vision": true,
"supports_tool_choice": true,
"supports_thinking": true,
"thinking_efforts": ["low", "high", "max"],
"default_thinking_effort": "high" }
]
}
],
"default_fallbacks": [
{ "model": "codex/gpt-5.6-luna", "provider": "codex", "available": true }
]
}
Semântica dos campos novos (contrato: desconhecido = null, nunca um chute):
-
available— se o provedor pode servir AGORA. Ele fica no GRUPO do provedor, não em cada modelo. Umif (model.available)lêundefinede esconderia o modelo da sua UI — a checagem éif (provider.available !== false), no nível do grupo.null= indeterminado (não conseguimos consultar o engine no momento); nunca umfalsefabricado.Mudou em 2026-08-28 (carta bia). Antes,
availablesignificava só "a credencial está configurada". Uma chave configurada pode ter sido revogada no provedor, e foi: aOPENAI_API_KEYdo ambiente passou a responder401 invalid_api_keya toda chamada enquanto o catálogo continuava anunciandoopenai: available: true— o que é pior quefalse, porque aponta a sua UI para modelos que nunca respondem. Agoraavailableé "configurada E não foi recusada pelo upstream na última chamada real": quando o provedor rejeita a credencial, o grupo virafalsena hora, e volta atruesozinho na primeira chamada que ele aceitar (rotação de chave não exige restart). A recusa é observada nas chamadas que já acontecem — não sondamos provedor para responder este campo.Continua não sendo checagem de saldo: crédito esgotado aparece como erro no turno (
class: "quota"), não comoavailable: false. -
supports_tool_choice— o provedor deste modelo mapeiatool_choice. Quandofalse, mandartool_choice(inclusive"none") neste modelo é recusado com400 TOOL_CHOICE_UNSUPPORTEDem vez de ser descartado em silêncio. Use este campo no seu seletor para nunca oferecer uma combinação que morre no dispatch. Hoje o único grupo comfalseé Gemini (google). -
max_output_tokens— teto de saída documentado pelo provedor;nullquando o provedor não publica. -
cached_input_cost_per_1m— preço por 1M de tokens de entrada servidos do cache de prompt do provedor.nullquando o provedor não publica uma tarifa de cache para o modelo, e nesse caso o cache é cobrado a preço cheio de entrada — nunca aplicamos um desconto que não temos como sustentar. Tokens de cache são um subconjunto deinput_tokense chegam emusage.cached_tokens. Novo em 2026-08-16: antes desta data todo token de cache era cobrado a preço cheio, o que superestimava o custo reportado — em uma run real de 884.745 tokens de entrada com 99,8% de cache, por 9,6×. -
supports_thinking— o runtime expõe o raciocínio deste modelo separado do texto final (thinkingnos eventos/respostas). -
thinking_efforts+default_thinking_effort— os valores dereasoning_effortque efetivamente mudam o comportamento deste modelo, e o aplicado quando o agente não define nenhum. Três estados, e a diferença entrenulle[]é intencional:valor significa mandar reasoning_effort["low","high","max"]a escada publicada deste modelo só esses valores nullo modelo raciocina, mas o provedor não publica uma escada discreta (MiniMax, Gemini) qualquer valor válido é aceito — não contradizemos o que não conseguimos verificar []o provedor publica uma recusa do parâmetro: o modelo raciocina e ainda assim responde erro se você escolher o nível ( grok-4.20)nenhum — é 400 EFFORT_NOT_SUPPORTEDsupports_thinking: falseo modelo não raciocina nenhum — é 400 EFFORT_NOT_SUPPORTEDNos dois últimos casos o seu seletor não deve oferecer nível nenhum. Os dois renderizam igual ("sem seletor");
[]diz a mais que mandar um é erro.
Novo em 2026-08-29 (carta bia). Antes desta data um reasoning_effort que o
modelo não aceitava era validado só contra o conjunto da plataforma
(low|medium|high|xhigh|max) e descartado em silêncio mais adiante — do seu
lado isso é indistinguível de ter funcionado. Agora o par (modelo, effort) é
validado em todas as portas que o escrevem, inclusive o override por
dispatch, e um par impossível é 400 EFFORT_NOT_SUPPORTED com a mensagem
nomeando o conjunto que teria funcionado.
default_fallbacks — a reserva da plataforma#
O catálogo também declara a cadeia de reserva do ambiente: os modelos que
atendem quando o primário de um agente falha por credencial/cota/indisponibilidade
e o agente não declarou um fallback próprio.
"default_fallbacks": [
{ "model": "codex/gpt-5.6-luna", "provider": "codex", "available": true }
]
Lista vazia = não há reserva de plataforma; um agente sem fallback próprio
morre na primeira recusa do primário. Cada entrada carrega o available do seu
provedor pela mesma regra acima, então dá para responder "a minha reserva
responde?" sem tentar. A cadeia vem na ordem em que é tentada — é
aqui que se confere qual provedor pode substituir o seu, sem perguntar a
ninguém. E dá para recusá-la por dispatch: ver disable_model_fallback.
Novo em 2026-08-28 (carta bia). Existe porque essa cadeia era invisível: ela
apontava para um único modelo cuja chave estava revogada, e não havia superfície
onde notar. Reserva que não pode responder é pior que não ter reserva — se a
sua integração depende de continuidade, declare o seu próprio fallback no
agente em vez de herdar o da plataforma, que é um piso operacional nosso e pode
mudar.
Entre os provedores estão Kimi (k3 com 1M de contexto, k3-256k,
kimi-for-coding, kimi-for-coding-highspeed — todos thinking-only, efforts
low|high|max) e MiniMax (MiniMax-M3, MiniMax-M2.7, MiniMax-M2.5,
MiniMax-M2.1, MiniMax-M2 + variantes -highspeed). Em todos os provedores o
content das respostas vem saneado: o raciocínio nunca chega inline no texto
(nada de <think> cru) — ele vem no campo/evento thinking.
POSTCriar ferramenta REST#
POST /v1/tools (owner/admin) — corpo customToolRequest:
| Campo | Tipo | Regra |
|---|---|---|
name |
string | obrigatório, regex ^http_[a-z0-9_]{1,120}$ |
url |
string | obrigatório, validado contra SSRF |
method |
string | GET/POST/… (upper-case) |
display_name, description |
string | — |
header_template, query_template |
objeto | mapa string→string; use ${secret:NOME} para segredos do cofre |
body_template |
string | — |
input_schema |
JSON | schema dos argumentos — validado no save (ver abaixo) |
timeout_ms |
int | default 15000 |
max_response_kb |
int | default 256 |
enabled |
bool? | default true |
tenant_external_id |
string? | escopa a ferramenta a UM cliente final; ausente = visível a toda a conta |
Resposta 201: customToolResponse (ecoa tenant_id). Leituras (GET /v1/tools,
/v1/tools/{id}) são all-auth. Erros: TOOL_NAME_INVALID, TOOL_URL_INVALID,
SECRET_NOT_FOUND, TOOL_NAME_CONFLICT, TOOL_SCHEMA_INVALID.
input_schema é validado no save (desde 2026-08-19)#
O input_schema vai literalmente para o provedor de LLM (input_schema na
Anthropic, function.parameters na OpenAI/Kimi, parameters no Gemini). Um
schema que o provedor recusa derruba a rodada inteira — e junto com ela todas
as outras ferramentas do turno. Por isso ele agora é recusado no momento em que
você grava, com o caminho exato do campo:
POST /v1/tools
{"name":"http_x","input_schema":{"type":"object","properties":{"body":{"description":"…"}}}}
HTTP/1.1 400 Bad Request
{
"error_code": "TOOL_SCHEMA_INVALID",
"path": "properties.body",
"message": "input_schema: properties.body: missing \"type\" (or one of anyOf/oneOf/allOf/enum/const/$ref)"
}
As regras (o mínimo denominador que os quatro provedores aceitam):
| Regra | Exemplo recusado |
|---|---|
a raiz declara "type":"object" |
{"properties":{…}}, "texto", 42 |
toda propriedade, em qualquer nível, declara type (ou anyOf/oneOf/allOf/enum/const/$ref) |
{"body":{"description":"…"}} |
type pertence a string|number|integer|boolean|object|array|null |
{"type":"strig"} |
array traz items |
{"type":"array"} |
required só cita propriedades declaradas |
required:["nao_existe"] |
$ref é local (começa com #) |
{"$ref":"https://…"} |
| ≤ 32 KB e ≤ 16 níveis de aninhamento | — |
input_schema ausente continua válido e significa "esta ferramenta não recebe
argumentos" (equivale a {"type":"object","properties":{}}).
Vale nos quatro caminhos de escrita: POST /v1/tools, PATCH /v1/tools/{id},
POST /v1/tools/test-draft, e o provisionamento de integrações
(POST/PATCH /v1/projects/{pid}/integrations/{id}/tools e o lote
.../tools/sync). No lote, um item recusado conta como falha do item — e como o
prune só roda com failed == 0, um schema malformado nunca apaga as
ferramentas que já funcionavam.
Reprovisionamento é idempotente pelo nome — trate o 409, não o 500. O nome
da ferramenta é único por conta. Se você reconcilia seu conjunto de ferramentas num
loop (o padrão de quem embute agentes), o POST de uma que já existe responde:
HTTP/1.1 409 Conflict
{
"error_code": "TOOL_NAME_CONFLICT",
"id": "0d7f…", ← a ferramenta que JÁ está lá
"name": "http_minha_tool",
"message": "a tool named http_minha_tool already exists in this company — PATCH /v1/tools/{id} to update it"
}
O id vem no corpo justamente para você seguir com PATCH /v1/tools/{id} sem
precisar de um GET /v1/tools para descobri-lo. Trate 409 como "já existe, siga
em frente" — não como falha a repetir.
Mudança de contrato (2026-08-15): esse caso devolvia
500 INTERNAL_ERRORcom a mensagem "failed to create tool (name may already exist)". Se o seu cliente depende do500ou faz match naquela string, migre para o409+error_code. O mesmo vale paraPOST /v1/skills, que agora devolve409 SKILL_NAME_CONFLICT.
Checklist: do zero à ferramenta funcionando no turno. Criar a ferramenta NÃO basta — para o modelo enxergá-la e o segredo resolver, são quatro passos:
- Crie a ferramenta (
POST /v1/tools). O nome segue^http_[a-z0-9_]{1,120}$. - Crie o segredo com um nome do alfabeto do resolvedor (
PUT /v1/tool-secrets):NOMEcasa[A-Za-z0-9_-]{1,128}(letras, dígitos,_e-). Fora disso o upsert devolve400. (Antes de 2026-07-25 o cofre aceitava qualquer nome e um nome fora do alfabeto fazia o placeholder${secret:...}viajar LITERAL na requisição: o endpoint respondia 401 como se a credencial estivesse errada, e nada indicava que o problema era a RESOLUÇÃO na origem, não o destino.) - Anexe a ferramenta ao agente (
PATCH /v1/agents/{id}comtools= a união do que já estava + a nova). O modelo só vê o que está notools[]do agente: criar a ferramenta NÃO a anexa, e um agente criado ANTES dela não a recebe automaticamente — sem o patch, ele nunca a terá no catálogo do turno. - Teste antes de depender (
POST /v1/tools/{id}/testcom args de exemplo): executa a chamada real (guardada contra SSRF) e mostra o que o endpoint recebeu. Um segredo que não resolve aparece aqui como 401 do destino — em segundos, não no meio de um run de minutos.
Escopo por tenant (opcional). POST /v1/tools e PUT /v1/tool-secrets
({ name, value, tenant_external_id? }) aceitam o eixo de tenant. Sem ele o recurso é
da conta inteira — o comportamento de sempre. Com ele valem duas garantias no runtime:
- Um agente do tenant A monta apenas ferramentas do tenant A ou da conta inteira.
A ferramenta de outro tenant é ignorada mesmo se o
tools:[...]do agente citar o nome (o vínculo é por nome, então sem isso o nome seria a permissão). - Um
${secret:NOME}dentro de uma ferramenta do tenant A resolve apenas segredos do tenant A ou da conta inteira. O segredo de outro tenant segue o mesmo caminho de um segredo inexistente (substituição vazia), então o valor nunca chega ao endpoint.
O nome continua único por conta — tenant é eixo de visibilidade, não namespace (o
modelo escolhe a ferramenta pelo nome dentro do turno, então dois nomes iguais no mesmo
catálogo seriam ambíguos). Use o seu próprio prefixo para segregar. O escopo é
imutável: um PUT /v1/tool-secrets que mudaria o tenant de um segredo existente
devolve 409 SECRET_SCOPE_IMMUTABLE — remova e recrie, para que uma rotação distraída
nunca alargue silenciosamente um segredo de tenant para a conta toda.
Gerenciar ferramentas#
| Rota | Ação |
|---|---|
GET /v1/tools · GET /v1/tools/{id} |
Listar / detalhar (all-auth) |
PATCH /v1/tools/{id} |
Update esparso (owner/admin) |
DELETE /v1/tools/{id} |
Remover (owner/admin) |
POST /v1/tools/{id}/test |
Dry-run da ferramenta salva, com args de exemplo |
POST /v1/tools/draft |
Tool-builder com IA: descreva a integração em texto, receba um rascunho de ferramenta |
POST /v1/tools/test-draft |
Dry-run de um rascunho sem salvar (corpo = a ferramenta) |
GET /v1/tools/{id}/versions · POST /v1/tools/{id}/versions/{vid}/restore |
Histórico de snapshots + restauração |
Segredos do cofre (os ${secret:NOME} dos templates): GET /v1/tool-secrets
lista (name + last4, nunca o valor), PUT /v1/tool-secrets cria/atualiza
({ name, value, tenant_external_id? }), DELETE /v1/tool-secrets/{name} remove.
Regras do ${secret:NOME}: o NOME casa [A-Za-z0-9_-]{1,128} — fora disso o
PUT devolve 400 (a escrita e a leitura usam o mesmo alfabeto; um nome que o
resolvedor não enxerga falha na hora de salvar, nunca no meio de um dispatch). A
resolução é fail-closed: segredo ausente, indecifrável ou de outro tenant
resolve para string vazia — nunca o placeholder literal — então o endpoint recebe
uma credencial vazia. Se o seu endpoint responde 401 no dispatch, verifique nesta
ordem: (a) o NOME no template bate exatamente com o nome no cofre; (b) o segredo
está no mesmo escopo de tenant da ferramenta (ou é da conta inteira); (c) o last4
em GET /v1/tool-secrets é o valor que você espera.
Cabeçalhos confiáveis que a plataforma envia à sua ferramenta#
Cada dispatch carrega o escopo do run em cabeçalhos que a engine assina do lado dela — eles vêm do run request, nunca dos argumentos que o modelo escreveu, então sua ferramenta pode confiar neles para autorizar e para deduplicar:
| Header | Sempre? | Significado |
|---|---|---|
X-Tenant-ID |
sim | conta (organização) dona do run |
X-Project-ID |
sim | projeto do run |
X-Agent-ID |
sim | agente que chamou a ferramenta |
X-Session-ID |
sim | conversa — estável entre turnos |
X-Stream-ID |
sim | ESTE run — muda a cada turno |
X-Tool-Call-ID |
em run de agente | ESTA invocação da ferramenta, dentro do turno |
X-Project-Tenant-ID |
quando há | cliente final do projeto (eixo de tenant) |
X-Runtime-Token-ID |
quando há | token prt_ que originou o run |
X-End-User-ID / X-End-User-External-ID |
quando há | usuário final vinculado ao run |
X-Tool-Call-IDexiste quando um agente chamou a ferramenta (o id vem da invocação do provider). O dispatch one-shot dePOST /v1/tools/{id}/testnão tem invocação de provider nenhuma, então esse header não vem no dry-run — trate-o como presente-em-run, ausente-em-teste, nunca como obrigatório.
Para idempotência use X-Tool-Call-ID, não o corpo. Ele identifica uma invocação
única e é reenviado idêntico se o mesmo dispatch for repetido, enquanto X-Session-ID
cobre a conversa inteira e X-Stream-ID o turno inteiro (vários chamados de ferramenta
compartilham ambos). Qualquer id vindo no corpo é escrito pelo modelo e pode repetir.
timeout_ms é o prazo que vale. O deadline da sua ferramenta é o timeout_ms que
você configurou (default 15000). O run não tem mais wall clock próprio (desde
2026-08-24); o único teto acima da ferramenta é o da infraestrutura (3600 s por
requisição). Não existe mais um teto de 60s do lado do
cliente HTTP: uma ferramenta que declara 180000 recebe de fato os 180s, desde que o run
ainda tenha essa folga.
GETSkills#
GET /v1/skills — { skills: [ { id, name, description, body, scope, read_only, … } ], total }.
POST /v1/skills cria ({ name, description?, body }; SKILL_NAME_REQUIRED,
SKILL_BODY_REQUIRED). Skills globais da plataforma são read-only
(SKILL_READONLY).
Uma skill é um pacote de instruções reutilizável (nome + descrição + corpo). No
prompt, o agente vê um catálogo progressivo: só nome+descrição entram de cara;
quando a tarefa casa com a descrição, ele chama a tool load_skill(name) e
recebe o corpo inteiro sob demanda.
Gerenciar skills#
| Rota | Ação |
|---|---|
PATCH /v1/skills/{id} |
Update esparso (name/description/body) |
DELETE /v1/skills/{id} |
Remover → 204 |
POST /v1/skills/{id}/preview |
Corpo { system_prompt? } → { header, body, injected, assembled }: o que entra no prompt de cara (header) e o que load_skill devolve (body). Determinístico, sem LLM |
GET /v1/skills/{id}/versions · POST /v1/skills/{id}/versions/{vid}/restore |
Histórico + restauração |
Skills de um agente (plug/unplug)#
| Rota | Ação |
|---|---|
GET /v1/agents/{id}/skills |
{ bindings: [ { skill_id, name, description, scope, read_only, enabled, priority } ], total } |
PUT /v1/agents/{id}/skills |
Corpo { bindings: [ { skill_id, enabled?, priority? } ] } — define atomicamente o conjunto plugado (plug/unplug/reordenar/toggle) |
PATCH /v1/agents/{id}/skills/{skillId} |
Corpo { enabled?, priority? } — liga/desliga ou reordena UMA skill plugada (404 SKILL_NOT_ACTIVE se não está plugada) |