Strumenti
Un modulo di strumenti funziona con ogni harness per agenti. beeuni.yaml elenca gli strumenti Beeuni e quelli del progetto, mentre l’elenco degli strumenti di ciascun agente stabilisce chi può usarli.
Uno strumento è una funzione che il modello chiama durante un turno. Una sessione ha tre tipi di strumenti, su entrambi gli harness, harness standard e harness sperimentale:
| Tipo | Nomi | Implementato da |
|---|---|---|
| Strumenti dell’harness | bash, read, write, edit, glob, grep, task, question, … |
L’harness. |
| Strumenti Beeuni | web_search, image_search, scrape_webpage, memory, show |
Beeuni. beeuni.yaml elenca ciascuno come <name>: beeuni:<name>. Un progetto senza la chiave tools: li riceve tutti e cinque. |
| Strumenti del progetto | Qualsiasi nome dichiari | Il progetto: un modulo dichiarato sotto tools: in beeuni.yaml. |
Gli strumenti Beeuni e quelli del progetto sono indipendenti dall’harness. Il daemon della sandbox carica un modulo per ogni strumento e lo esegue su entrambi gli harness, con lo stesso nome, gli stessi argomenti e lo stesso output. harness sperimentale chiama il modulo nel processo del daemon. harness standard lo chiama tramite un plugin scritto dal daemon, che inoltra ogni chiamata al daemon. Un modulo non importa mai un pacchetto dell’harness.
Strumenti Beeuni in beeuni.yaml
Un nuovo progetto elenca i cinque strumenti Beeuni sotto 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 che lo strumento è gestito da Beeuni. Una correzione viene applicata a ogni progetto che lo elenca, senza modifiche al progetto.
Quali strumenti Beeuni riceve una sessione
beeuni.yaml |
Strumenti ricevuti dalla sessione |
|---|---|
Nesbeeuni chiave tools:, nel file radice o in qualsiasi file importato |
Tutti e cinque gli strumenti Beeuni. Un progetto creato prima che esistesse questo elenco li mantiene tutti. |
Una chiave tools:, anche vuota (tools: {} oppure tools: con tutte le righe eliminate) |
Solo gli strumenti Beeuni elencati, come beeuni:<name> o come modulo che sostituisce lo strumento. |
Gli strumenti propri del progetto vengono caricati in entrambi i casi.
Vedere quali strumenti riceve una sessione
beeuni tools ls legge beeuni.yaml e i file importati, quindi stampa ogni strumento ricevuto da una sessione e gli strumenti Beeuni rimossi dal progetto:
$ 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 | Significato |
|---|---|
beeuni |
Uno strumento Beeuni, elencato come beeuni:<name> (o tutti, se manca la chiave tools:). |
beeuni (overridden) |
Nome di uno strumento Beeuni con il percorso di un modulo: viene eseguito il modulo del progetto. |
project |
Uno strumento del progetto. |
beeuni tools ls --json stampa { manifest, tools_key, tools: [{ name, kind, source }], removed }.
Rimuovere uno strumento Beeuni
Elimina la relativa riga sotto tools:. Tutti gli agenti del progetto perdono lo strumento, su entrambi gli harness, in ogni sessione avviata dopo l’unione della richiesta di modifica. Per impedire a un solo agente di usare uno strumento, usa agents.<name>.tools.
In una sessione di un progetto che ha rimosso uno strumento:
- harness standard non offre lo strumento al modello.
- harness sperimentale non offre lo strumento. Una chiamata non riuscita restituisce
Tool show not found(pershow). - Il daemon risponde a
POST /beeuni/tools/<name>con404eno tool named <name> is loaded. - Una skill che nomina lo strumento viene comunque caricata. Per esempio,
beeuni-memorynominamemory. Il modello legge la skill, non trova lo strumento e ne usa altri: senzamemorylegge e modifica i file sottomemory/con gli strumenti per i file.
Modificare uno strumento Beeuni: eject
beeuni tools eject <name> crea una copia di uno strumento Beeuni nel progetto:
$ 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.
- Scrive in
tools/<name>.tsil sorgente Beeuni, gli stessi byte eseguiti dalla sandbox. Il file importa solo modulinode:*e leggeBEEUNI_API_URL,BEEUNI_TOKENe le chiavi del provider dacontext.env, quindi è subito eseguibile. - Imposta
<name>: tools/<name>.tsinbeeuni.yaml, nel file che dichiara la voce (il file radice o un file importato). Tutte le altre righe e i commenti restano invariati. La riga modificata termina con# ejected from beeuni:<name>. - Se manca la chiave
tools:, la crea ed elenca gli altri quattro strumenti Beeuni comebeeuni:<name>, così l’eject non rimuove nulla. - Si rifiuta di procedere se esiste
tools/<name>.tso se lo strumento rimanda già a un altro modulo.--forcesovrascrive. - Si rifiuta di usare un nome che non sia quello di uno strumento Beeuni.
La copia è tua. Beeuni non la aggiorna harness sperimentaleù. Per tornare allo strumento gestito, reimposta la riga su <name>: beeuni:<name> ed elimina il file.
Sovrascrivere senza eject
Un nome di strumento Beeuni associato al percorso di un modulo sostituisce lo strumento Beeuni su ogni harness:
tools:
web_search: integrations/search/web_search.ts
Le viste dell’interfaccia web
L’interfaccia web ha una vista per ogni strumento Beeuni, selezionata in base al nome dello strumento. Le viste show e memory leggono gli argomenti della chiamata (type, path, url, content, items; command, path). Le viste web_search, image_search e scrape_webpage leggono il JSON di output. Una copia modificata che mantiene lo stesso nome deve mantenere gli stessi argomenti e la stessa struttura dell’output, altrimenti l’interfaccia mostra l’output grezzo.
Convalida
beeuni validate controlla l’elenco:
<name>inbeeuni:<name>deve essere uno strumento Beeuni e la chiave deve corrispondere.web_search: beeuni:image_searchè un errore: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.- Una chiave
tools:che non elenca alcuno strumento Beeuni genera un avviso:Sessions of this project get no Beeuni tool (web_search, image_search, scrape_webpage, memory, show). Add `<name>: beeuni:<name>` to keep one.Serve a rilevare un progetto che aggiunge il primo strumento proprio ed elimina per errore i cinque strumenti predefiniti. - Un agente il cui
toolsnomina uno strumento Beeuni che il progetto non carica genera un avviso:"show" is a Beeuni tool this project does not load: add `show: beeuni:show` under the top-level `tools`, or remove it here.
Il riferimento del manifest contiene tutte le regole.
Scrivere uno strumento del progetto
// 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
L’esportazione predefinita è un semplice oggetto:
| Campo | Regola |
|---|---|
description |
Stringa non vuota. Il modello la legge per decidere quando chiamare lo strumento. |
parameters |
JSON Schema degli argomenti, type: 'object'. Il modello lo riceve così com’è, quindi elenca gli argomenti obbligatori in required. Beeuni non convalida gli argomenti rispetto allo schema. |
execute(args, context) |
Restituisce una stringa o un qualsiasi valore JSON (inviato come JSON indentato). Può essere async. Un errore generato è l’errore dello strumento e il modello ne legge il messaggio. |
context contiene:
| Campo | Descrizione |
|---|---|
sessionId |
La sessione Beeuni a cui appartiene la chiamata. |
agent |
L’agente che ha effettuato la chiamata. |
directory |
Il checkout del progetto, /workspace. Risolvi i percorsi relativi rispetto a esso. |
env |
L’ambiente del box e i segreti che questo agente riceve, nello stato attuale. Leggi un segreto come context.env.NAME: un segreto modificato dopo l’avvio del box si trova in context.env, non in process.env. |
signal |
Un AbortSignal che interrompe l’esecuzione quando l’utente ferma il turno. Passalo a fetch. |
- Dimensione dell’output. Un output superiore a 50 KB o 2.000 righe viene salvato per intero in un file nella directory temporanea della sandbox. Il modello riceve l’inizio, le dimensioni e il percorso del file. Restituisci ciò che serve al modello, non un dump grezzo.
- Errori. Un errore generato termina la chiamata e il modello ne legge il messaggio. Genera un messaggio che spieghi cosa modificare.
- Importazioni. Un modulo può importare moduli
node:*, API Bun e file relativi. Un pacchetto viene risolto a partire da unnode_modulesaccanto al modulo o in una directory superiore. La sandbox non installa pacchetti per uno strumento e una release di configurazione contiene solo i file tracciati da Git. Usafetchper le API HTTP. TypeScript viene eseguito senza passaggi di build. - Errori di caricamento. Un modulo che non viene caricato (file mancante, nesbeeuni esportazione predefinita, uno
parametersche non è uno schema a oggetto, un errore durante l’importazione o un pacchetto non risolvibile) viene escluso, ma gli altri strumenti continuano a caricarsi. Per ogni strumento il daemon registra[tools] project tools that did not loadcon il motivo.
parameters con zod
zod 4 produce lo stesso 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`
},
}
Questo modulo viene caricato solo se zod è risolvibile a partire da un node_modules nel checkout in cui viene eseguita la sessione. In caso contrario, restituisce Cannot find package 'zod'.
Per scrivere lo schema con zod e distribuire un JSON Schema semplice, stampalo una volta e incolla l’output in parameters:
bun -e "import { z } from 'zod'; console.log(JSON.stringify(z.toJSONSchema(z.object({ id: z.string() })), null, 2))"
Esempio: chiamare un’API HTTP con un segreto del progetto
Salva la chiave come segreto del progetto. Il comando legge il valore dallo standard input:
beeuni secrets set WEATHER_API_KEY=-
Concedi il segreto agli agenti che chiamano lo strumento. L’agente beeuni del modello iniziale dispone di secrets: all. Un agente con autorizzazioni limitate lo elenca: secrets: [WEATHER_API_KEY].
Scrivi il modulo:
// 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 }
},
}
Dichiaralo:
tools:
# … the Beeuni tools you keep
weather_now: tools/weather_now.ts
Esempio: sostituire web_search
beeuni tools eject web_search scrive tools/web_search.ts e imposta web_search: tools/web_search.ts. Poi modifica la copia. Per esempio, per mantenere i risultati di un solo sito, aggiungi il sito a ogni query in execute, prima della richiesta:
// 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}`)
Mantieni il nome, gli argomenti e il JSON di output, così le skill che nominano web_search e la vista dell’interfaccia web continuano a funzionare.
Testare uno strumento
beeuni validate controlla il nome, il percorso, l’eventuale assenza del file e i valori beeuni:. beeuni tools ls mostra quali strumenti riceve una sessione.
Quindi esegui commit e push e apri una richiesta di modifica. Dopo l’unione, avvia una sessione e chiedi una chiamata con argomenti reali:
beeuni sessions new --wait --prompt "Call the weather_now tool once with city Berlin and print its output."
Uno strumento che non viene caricato non viene offerto al modello. Uno strumento che genera un errore risponde con il relativo messaggio. beeuni sessions log <id> stampa i messaggi della sessione, con ogni chiamata allo strumento e il relativo stato.
Dichiarare gli strumenti
tools: associa ogni nome di strumento al relativo modulo, oppure un nome di strumento Beeuni a beeuni:<name>. Puoi scegliere liberamente la cartella del modulo.
tools:
web_search: beeuni:web_search
memory: beeuni:memory
lookup_order: tools/lookup_order.ts
crm_note: integrations/crm/note.ts
- Un nome deve essere in snake_case e contenere al massimo 64 caratteri:
^[a-z][a-z0-9_]{0,63}$. - Un nome di strumento dell’harness è un errore. Un nome di strumento Beeuni accetta
beeuni:<name>o un percorso di modulo; il modulo sostituisce lo strumento Beeuni su ogni harness. - Un percorso è relativo alla repo e termina in
.ts,.js,.mts,.mjs,.ctso.cjs. - Un file elencato sotto
imports:può dichiarare strumenti. Dichiarare lo stesso nome in due file è un errore. Una chiavetools:in un file importato viene considerata una chiavetools:ai fini della regola di selezione.
Il riferimento del manifest contiene tutte le regole.
Chi può usare quali strumenti
agents.<name>.tools determina quali strumenti vede il modello di un agente. Include gli strumenti dell’harness, Beeuni e del progetto.
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
| Valore | Strumenti ricevuti dall’agente |
|---|---|
omesso oppure all |
Tutti gli strumenti. |
none |
Nessuno strumento. |
| un elenco | Solo gli strumenti elencati. Un elenco con * è all. |
{ exclude: [...] } |
Tutti gli strumenti tranne quelli elencati. |
{ bash: false, … } |
La precedente forma a mappa: false rimuove uno strumento. |
toolsdetermina la visibilità. Le regolepermissiondell’agente stabiliscono comunque se una chiamata è consentita, richiede conferma o viene negata. Uno strumento non incluso nell’elenco è nascosto al modello e la sua chiamata viene negata.- Un elenco di un agente non può aggiungere uno strumento Beeuni che il progetto non carica. Elencalo prima in
tools:a livello principale. - Un subagente avviato con lo strumento
task: su harness sperimentale riceve solo gli strumenti consentiti sia dal proprio elenco sia da quello dell’agente della sessione. Su harness standard riceve gli strumenti del proprio elenco: harness standard applica le regole di un agente solo a quell’agente. Per impedire a un agente di delegare, non includeretasknel suo elenco. - Gli strumenti Connector seguono
agents.<name>.connectors, non questo elenco. beeuni validateavvisa se un nome non corrisponde a uno strumento dell’harness, Beeuni o del progetto, o a uno strumento Beeuni non caricato dal progetto. Un nome errato in un elencoexcludelascia attivo lo strumento corretto.
Su harness standard, bash comprende anche gli strumenti pty_* del plugin terminale, mentre write, edit e apply_patch condividono un’autorizzazione: elencarne uno li mostra tutti e tre, escluderne uno li nasconde tutti e tre. harness sperimentale ha strumenti write e edit separati.
Quando entra in vigore una modifica
Una sessione carica gli strumenti all’avvio del runtime. Una modifica si applica dopo l’unione della richiesta: le nuove sessioni la caricano e, con le release di configurazione, una sessione in esecuzione la carica alla successiva convergenza. Su harness sperimentale, una modifica a uno strumento del progetto o all’elenco degli strumenti Beeuni riavvia il runtime sul posto quando non è in corso un turno; la conversazione continua.
Strumenti in harnesses/opencode/tools/
harness standard continua a caricare gli strumenti personalizzati dalla propria directory di configurazione. harness sperimentale non lo fa. I progetti creati prima degli strumenti ospitati contengono copie degli strumenti Beeuni (web_search.ts, memory.ts, …).
- Su harness standard, uno strumento in quella cartella prevale sullo strumento ospitato con lo stesso nome, quindi il progetto conserva la propria copia finché non la elimina. Elimina le copie degli strumenti Beeuni: il daemon ospita quelli elencati in
beeuni.yaml, su entrambi gli harness. - Per fare in modo che uno strumento harness standard venga eseguito su entrambi gli harness, spostalo fuori dalla cartella, sostituisci
tool({ description, args, execute })con un semplice oggetto il cuiparameterssia JSON Schema, leggi i segreti dacontext.enve dichiaralo sottotools:.