Ferramentas
Um módulo de ferramentas é executado em todos os ambientes de agente. beeuni.yaml lista as ferramentas do Beeuni e as ferramentas do próprio projeto, e a lista de ferramentas de cada agente determina quem pode chamá-las.
Uma ferramenta é uma função que o modelo chama durante um turno. Uma sessão tem três tipos, em ambos os harnesses, harness padrão e harness experimental:
| Tipo | Nomes | Implementado por |
|---|---|---|
| Ferramentas do harness | bash, read, write, edit, glob, grep, task, question, … |
O harness. |
| Ferramentas Beeuni | web_search, image_search, scrape_webpage, memory, show |
Beeuni. beeuni.yaml lista cada uma como <name>: beeuni:<name>. Um projeto sem a chave tools: recebe as cinco. |
| Ferramentas do projeto | Qualquer nome que você declarar | Seu projeto: um módulo, declarado em tools: em beeuni.yaml. |
As ferramentas Beeuni e as ferramentas do projeto são independentes do harness. O daemon do sandbox carrega um módulo por ferramenta e o executa em qualquer um dos harnesses, com o mesmo nome, argumentos e saída. harness experimental chama o módulo no processo do daemon. harness padrão o chama por meio de um plugin escrito pelo daemon, que encaminha cada chamada ao daemon. Um módulo nunca importa um pacote do harness.
Ferramentas Beeuni em beeuni.yaml
Um projeto novo lista as cinco ferramentas Beeuni em tools::
tools:
web_search: beeuni:web_search # maintained by Beeuni, updated automatically
image_search: beeuni:image_search
scrape_webpage: beeuni:scrape_webpage
memory: beeuni:memory
show: beeuni:show
# lookup_order: tools/lookup_order.ts # your own tool: a module in your repo
beeuni:<name> significa: a ferramenta mantida pela Beeuni. Uma correção nela chega a todos os projetos que a listam, sem alterações no projeto.
Quais ferramentas Beeuni uma sessão recebe
beeuni.yaml |
A sessão recebe |
|---|---|
Sem chave tools:, no arquivo raiz ou em qualquer arquivo importado |
Todas as cinco ferramentas Beeuni. Um projeto criado antes da existência desta lista continua com todas elas. |
Uma chave tools:, mesmo vazia (tools: {} ou tools: com todas as linhas removidas) |
Apenas as ferramentas Beeuni que ela lista, como beeuni:<name> ou como um módulo que substitui a ferramenta. |
As ferramentas próprias do projeto são carregadas nos dois casos.
Veja o que uma sessão recebe
beeuni tools ls lê beeuni.yaml e suas importações e imprime cada ferramenta que uma sessão recebe, seguida das ferramentas Beeuni removidas pelo projeto:
$ beeuni tools ls
NAME KIND SOURCE
web_search beeuni (overridden) tools/web_search.ts
scrape_webpage beeuni beeuni:scrape_webpage
memory beeuni beeuni:memory
show beeuni beeuni:show
lookup_order project tools/lookup_order.ts
Removed Beeuni tools: image_search
Add `<name>: beeuni:<name>` under `tools:` to get one back.
| Tipo | Significado |
|---|---|
beeuni |
Uma ferramenta Beeuni, listada como beeuni:<name> (ou todas, se não houver chave tools:). |
beeuni (overridden) |
Um nome de ferramenta Beeuni com um caminho de módulo: o módulo do projeto é executado no lugar dela. |
project |
Uma ferramenta própria do projeto. |
beeuni tools ls --json imprime { manifest, tools_key, tools: [{ name, kind, source }], removed }.
Remover uma ferramenta Beeuni
Exclua a linha correspondente em tools:. Todos os agentes do projeto perdem a ferramenta, nos dois harnesses, em todas as sessões iniciadas depois da aprovação da solicitação de alteração. Para manter uma ferramenta disponível para apenas um agente, use
agents.<name>.tools.
Em uma sessão de um projeto que removeu uma ferramenta:
- harness padrão não oferece a ferramenta ao modelo.
- harness experimental não oferece a ferramenta. Uma chamada a ela falha com
Tool show not found(parashow). - O daemon responde
POST /beeuni/tools/<name>com404eno tool named <name> is loaded. - Uma skill que menciona a ferramenta continua sendo carregada. Por exemplo,
beeuni-memorymencionamemory. O modelo lê a skill, não encontra essa ferramenta e usa outras ferramentas: semmemory, ele lê e edita os arquivos emmemory/usando as ferramentas de arquivos.
Alterar uma ferramenta Beeuni: ejetar
beeuni tools eject <name> dá ao projeto uma cópia própria de uma ferramenta Beeuni:
$ beeuni tools eject web_search
✓ Ejected web_search
wrote tools/web_search.ts (the Beeuni source, now the project's to change)
set beeuni.yaml: tools.web_search: tools/web_search.ts
Next:
1. Edit tools/web_search.ts. Keep the default export: { description, parameters, execute(args, context) }.
2. beeuni validate
3. git add tools/web_search.ts beeuni.yaml && git commit -m "Own the web_search tool"
4. Open a change request: git push origin HEAD && beeuni cr open --title "Own the web_search tool"
Sessions load the copy after the change request merges.
- Ele grava o código-fonte da Beeuni — os mesmos bytes executados pelo sandbox — em
tools/<name>.ts. O arquivo importa apenas módulosnode:*e lêBEEUNI_API_URL,BEEUNI_TOKENe as chaves do provedor decontext.env, então é executado sem alterações. - Ele define
<name>: tools/<name>.tsembeeuni.yaml, no arquivo que declara a entrada (o arquivo raiz ou um arquivo importado). Todas as outras linhas e comentários são mantidos. A linha alterada termina com# ejected from beeuni:<name>. - Se não houver uma chave
tools:, ele a cria e lista as outras quatro ferramentas Beeuni comobeeuni:<name>, então a ejeção não remove nada. - Ele se recusa a prosseguir se
tools/<name>.tsexistir ou se a ferramenta já apontar para outro módulo.--forcesubstitui o arquivo existente. - Ele se recusa a aceitar um nome que não seja de uma ferramenta Beeuni.
A cópia é sua. A Beeuni não a atualizará mais. Para voltar à ferramenta mantida, altere a linha para <name>: beeuni:<name> e exclua o arquivo.
Substituir sem ejetar
Um nome de ferramenta Beeuni com um caminho de módulo substitui a ferramenta Beeuni em todos os harnesses:
tools:
web_search: integrations/search/web_search.ts
As visualizações da interface web
A interface web tem uma visualização para cada ferramenta Beeuni, selecionada pelo nome da ferramenta. As visualizações show e memory leem os argumentos da chamada (type, path, url,
content, items; command, path). As visualizações web_search, image_search e
scrape_webpage leem o JSON da saída. Uma cópia alterada que mantenha o nome precisa manter esses argumentos e esse formato de saída, ou a interface exibirá a saída bruta.
Validação
beeuni validate verifica a lista:
<name>embeeuni:<name>precisa ser uma ferramenta Beeuni, e a chave deve ser igual a ela.web_search: beeuni:image_searché um erro:must be `beeuni:web_search` (the Beeuni tool) or a repo-relative path to a .ts or .js module (e.g. `tools/web_search.ts`) that replaces it.- Uma chave
tools:que não lista nenhuma ferramenta Beeuni gera um aviso:Sessions of this project get no Beeuni tool (web_search, image_search, scrape_webpage, memory, show). Add `<name>: beeuni:<name>` to keep one.Isso detecta um projeto que adiciona sua primeira ferramenta própria e remove as cinco por acidente. - Um agente cujo
toolsmenciona uma ferramenta Beeuni que o projeto não carrega gera um aviso:"show" is a Beeuni tool this project does not load: add `show: beeuni:show` under the top-level `tools`, or remove it here.
A referência do manifesto contém todas as regras.
Escrever uma ferramenta do projeto
// tools/lookup_order.ts
export default {
description: 'Look up an order by id. Returns its status and carrier.',
parameters: {
type: 'object',
properties: {
id: { type: 'string', description: 'The order id, e.g. "A-1042"' },
include_items: { type: 'boolean', description: 'Also list the items' },
},
required: ['id'],
},
async execute(args, context) {
const response = await fetch(`https://orders.example.com/v1/orders/${args.id}`, {
headers: { authorization: `Bearer ${context.env.ORDERS_API_KEY}` },
signal: context.signal,
})
if (!response.ok) throw new Error(`orders API answered ${response.status}`)
return await response.json()
},
}
# beeuni.yaml
tools:
web_search: beeuni:web_search
# … the other Beeuni tools you keep
lookup_order: tools/lookup_order.ts
A exportação padrão é um objeto simples:
| Campo | Regra |
|---|---|
description |
String não vazia. O modelo a lê para decidir quando chamar a ferramenta. |
parameters |
JSON Schema dos argumentos, type: 'object'. O modelo o recebe como está, então liste os argumentos obrigatórios em required. A Beeuni não valida os argumentos de acordo com esse esquema. |
execute(args, context) |
Retorna uma string ou qualquer valor JSON (enviado como JSON indentado). Pode ser async. Um erro lançado é o erro da ferramenta, e o modelo lê a mensagem. |
context contém:
| Campo | O que é |
|---|---|
sessionId |
A sessão Beeuni à qual a chamada pertence. |
agent |
O agente que fez a chamada. |
directory |
O checkout do projeto, /workspace. Resolva um caminho relativo com base nele. |
env |
O ambiente da caixa mais os segredos que este agente recebe, como estão agora. Leia um segredo como context.env.NAME: um segredo alterado depois que a caixa foi iniciada está em context.env, não em process.env. |
signal |
Um AbortSignal que aborta quando o usuário interrompe o turno. Passe-o para fetch. |
- Tamanho da saída. Uma saída com mais de 50 KB ou 2.000 linhas é salva integralmente em um arquivo no diretório temporário do sandbox. O modelo recebe o início, o tamanho e o caminho do arquivo. Retorne o que o modelo precisa, não um despejo bruto.
- Erros. Um erro lançado encerra a chamada, e o modelo lê a mensagem de erro. Lance uma mensagem que diga o que alterar.
- Importações. Um módulo pode importar módulos
node:*, APIs do Bun e arquivos relativos. Um pacote é resolvido a partir de umnode_modulesao lado do módulo ou acima dele. O sandbox não instala pacotes para uma ferramenta, e uma versão de configuração contém apenas os arquivos rastreados pelo Git. Usefetchpara APIs HTTP. O TypeScript é executado sem uma etapa de build. - Falhas. Um módulo que não carrega (arquivo ausente, sem exportação padrão,
parametersque não é um esquema de objeto, erro na importação ou pacote não resolvido) é ignorado, e as outras ferramentas continuam carregando. O daemon registra[tools] project tools that did not loadcom o motivo de cada ferramenta.
parameters com zod
O zod 4 gera o mesmo JSON Schema:
import { z } from 'zod'
export default {
description: 'Look up an order by id.',
parameters: z.toJSONSchema(z.object({ id: z.string().describe('The order id') })),
async execute(args) {
return `order ${args.id}: shipped`
},
}
Este módulo só carrega onde zod pode ser resolvido a partir de um node_modules no checkout em que a sessão é executada. Caso contrário, falha com Cannot find package 'zod'.
Para escrever o esquema com zod e distribuir JSON Schema simples, imprima-o uma vez e cole a saída em parameters:
bun -e "import { z } from 'zod'; console.log(JSON.stringify(z.toJSONSchema(z.object({ id: z.string() })), null, 2))"
Exemplo: chamar uma API HTTP com um segredo do projeto
Armazene a chave como segredo do projeto. O comando lê o valor da entrada padrão:
beeuni secrets set WEATHER_API_KEY=-
Conceda acesso ao segredo aos agentes que chamam a ferramenta. O agente beeuni do projeto inicial tem secrets: all. Um agente com escopo definido o lista: secrets: [WEATHER_API_KEY].
Escreva o módulo:
// tools/weather_now.ts
export default {
description: 'Current weather for a city: temperature in °C and conditions.',
parameters: {
type: 'object',
properties: { city: { type: 'string', description: 'City name, e.g. "Berlin"' } },
required: ['city'],
},
async execute(args, context) {
const key = context.env.WEATHER_API_KEY
if (!key) throw new Error('WEATHER_API_KEY is not set: run `beeuni secrets set WEATHER_API_KEY=-` and grant it to this agent.')
const url = `https://api.weather.example.com/v1/current?city=${encodeURIComponent(args.city)}`
const response = await fetch(url, { headers: { authorization: `Bearer ${key}` }, signal: context.signal })
if (!response.ok) throw new Error(`weather API answered ${response.status}: ${await response.text()}`)
const data = await response.json()
return { city: args.city, temperature_c: data.temp_c, conditions: data.conditions }
},
}
Declare-o:
tools:
# … the Beeuni tools you keep
weather_now: tools/weather_now.ts
Exemplo: substituir web_search
beeuni tools eject web_search grava tools/web_search.ts e define
web_search: tools/web_search.ts. Em seguida, altere a cópia. Por exemplo, para manter
resultados de apenas um site, adicione o site a cada consulta em execute, antes da solicitação:
// tools/web_search.ts, inside execute()
const queries = String(args.query ?? '').split('|||').map((query) => query.trim()).filter(Boolean)
.map((query) => `site:docs.example.com ${query}`)
Mantenha o nome, os argumentos e o JSON da saída para que as skills que mencionam
web_search e a visualização da interface web continuem funcionando.
Testar uma ferramenta
beeuni validate verifica o nome, o caminho, um arquivo ausente e os valores de beeuni:. beeuni tools ls mostra o que uma sessão recebe.
Depois, faça commit, push e abra uma solicitação de alteração. Após a aprovação, inicie uma sessão e solicite uma chamada com argumentos reais:
beeuni sessions new --wait --prompt "Call the weather_now tool once with city Berlin and print its output."
Uma ferramenta que não carrega não é oferecida ao modelo. Uma ferramenta que lança um erro responde com a mensagem de erro. beeuni sessions log <id> imprime as mensagens da sessão, com cada chamada de ferramenta e seu status.
Declarar ferramentas
tools: mapeia cada nome de ferramenta para seu módulo, ou um nome de ferramenta Beeuni para beeuni:<name>. Você escolhe a pasta do módulo.
tools:
web_search: beeuni:web_search
memory: beeuni:memory
lookup_order: tools/lookup_order.ts
crm_note: integrations/crm/note.ts
- Um nome deve estar em snake_case e ter no máximo 64 caracteres:
^[a-z][a-z0-9_]{0,63}$. - Um nome de ferramenta do harness é um erro. Um nome de ferramenta Beeuni aceita
beeuni:<name>ou um caminho de módulo; o módulo substitui a ferramenta Beeuni em todos os harnesses. - Um caminho deve ser relativo ao repositório e terminar em
.ts,.js,.mts,.mjs,.ctsou.cjs. - Um arquivo listado em
imports:pode declarar ferramentas. Declarar um nome em dois arquivos é um erro. Uma chavetools:em um arquivo importado conta como uma chavetools:para a regra de seleção.
A referência do manifesto contém todas as regras.
Quem pode usar cada ferramenta
agents.<name>.tools decide quais ferramentas o modelo de um agente vê. Ela inclui ferramentas do harness, Beeuni e do projeto.
agents:
beeuni:
tools: all # every tool (the default)
researcher:
tools: [read, grep, web_search, lookup_order] # only these
support:
tools:
exclude: [bash, write, edit] # every tool but these
greeter:
tools: none # no tool
| Valor | O agente recebe |
|---|---|
omitido ou all |
Todas as ferramentas. |
none |
Nenhuma ferramenta. |
| uma lista | Apenas as ferramentas listadas. Uma lista com * é all. |
{ exclude: [...] } |
Todas as ferramentas, exceto as listadas. |
{ bash: false, … } |
O formato de mapa anterior: false remove uma ferramenta. |
toolsdecide a visibilidade. As regraspermissiondo agente ainda determinam se uma chamada é permitida, precisa de confirmação ou é negada. Uma ferramenta que não está na lista fica oculta para o modelo e é negada se for chamada.- Uma lista de agente não pode adicionar uma ferramenta Beeuni que o projeto não carrega. Liste-a primeiro em
tools:no nível superior. - Um subagente iniciado com a ferramenta
task: no harness experimental, ele recebe apenas as ferramentas permitidas tanto pela própria lista quanto pela lista do agente da sessão. No harness padrão, ele recebe as ferramentas da própria lista: o harness padrão aplica as regras de um agente somente a esse agente. Para impedir que um agente delegue, deixetaskfora da lista dele. - As ferramentas do Connector seguem
agents.<name>.connectors, não esta lista. beeuni validateavisa quando um nome não corresponde a uma ferramenta do harness, da Beeuni ou do projeto, e também quando o projeto não carrega uma ferramenta Beeuni. Um erro de digitação em uma listaexcludemantém a ferramenta real ativada.
No harness padrão, bash também abrange as ferramentas pty_* do plugin de terminal, e write, edit e apply_patch compartilham uma permissão: listar uma mostra as três, e excluir uma oculta as três. O harness experimental tem ferramentas write e edit separadas.
Quando uma alteração entra em vigor
Uma sessão carrega suas ferramentas quando o runtime é iniciado. Uma alteração se aplica depois que a solicitação de alteração é aprovada: novas sessões carregam a alteração e, com versões de configuração, uma sessão em execução a carrega na próxima convergência. No harness experimental, uma alteração em uma ferramenta do projeto ou na lista de ferramentas Beeuni reinicia o runtime no mesmo lugar quando nenhum turno está em execução; a conversa continua.
Ferramentas em harnesses/opencode/tools/
O harness padrão ainda carrega ferramentas personalizadas do diretório de configuração. O harness experimental não. Projetos criados antes da disponibilização de ferramentas hospedadas incluem cópias das ferramentas Beeuni nesse diretório
(web_search.ts, memory.ts, …).
- No harness padrão, uma ferramenta nessa pasta tem prioridade sobre a ferramenta hospedada de mesmo nome, então o projeto mantém sua cópia até removê-la. Exclua as cópias das ferramentas Beeuni: o daemon hospeda as que
beeuni.yamllista, nos dois harnesses. - Para executar uma ferramenta do harness padrão nos dois harnesses, mova-a para fora da pasta, substitua
tool({ description, args, execute })por um objeto simples cujoparametersseja JSON Schema, leia os segredos decontext.enve declare a ferramenta emtools:.