Zum Inhalt springen
BeeuniBeeuni
Deutsch
Esc
↑↓navigieren↵öffnen⌘Jvorschau
Auf dieser Seite

Werkzeuge

Ein Tool-Modul läuft auf jedem Agent-Harness. beeuni.yaml listet die Beeuni-Tools und die projektspezifischen Tools auf, und die tools-Liste jedes Agents legt fest, wer sie aufrufen darf.

Ein Tool ist eine Funktion, die das Modell während eines Turns aufruft. Eine Session hat drei Arten von Tools, auf beiden Harnesses, Standard-Harness und Experimental-Harness:

Art Namen Implementiert von
Harness-Tools bash, read, write, edit, glob, grep, task, question, … Dem Harness.
Beeuni-Tools web_search, image_search, scrape_webpage, memory, show Beeuni. beeuni.yaml führt jedes als <name>: beeuni:<name> auf. Ein Projekt ohne Schlüssel tools: erhält alle fünf.
Projekt-Tools Jeder von dir deklarierte Name Deinem Projekt: ein Modul, deklariert unter tools: in beeuni.yaml.

Beeuni-Tools und Projekt-Tools sind harness-unabhängig. Der Sandbox-Daemon lädt für jedes Tool ein Modul und führt es für beide Harnesses mit demselben Namen, denselben Argumenten und derselben Ausgabe aus. Experimental-Harness ruft das Modul im Prozess des Daemons auf. Standard-Harness ruft es über ein vom Daemon geschriebenes Plugin auf, das jeden Aufruf an den Daemon weiterleitet. Ein Modul importiert niemals ein Harness-Paket.

Beeuni-Tools in beeuni.yaml

Ein neues Projekt führt die fünf Beeuni-Tools unter tools: auf:

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> bedeutet: das von Beeuni gepflegte Tool. Eine Korrektur daran erreicht jedes Projekt, das es aufführt, ohne dass das Projekt geändert werden muss.

Welche Beeuni-Tools eine Session erhält

beeuni.yaml Die Session erhält
Kein Schlüssel tools:, weder in der Stammdatei noch in einer importierten Datei Alle fünf Beeuni-Tools. Ein Projekt, das vor Einführung dieser Liste erstellt wurde, behält sie alle.
Einen Schlüssel tools:, auch einen leeren (tools: {} oder tools:, wenn alle Zeilen gelöscht wurden) Nur die Beeuni-Tools, die darin als beeuni:<name> oder als Modul aufgeführt sind, das das Tool ersetzt.

Die projektspezifischen Tools werden in beiden Fällen geladen.

Anzeigen, welche Tools eine Session erhält

beeuni tools ls liest beeuni.yaml und seine Importe und gibt jedes Tool aus, das eine Session erhält, gefolgt von den Beeuni-Tools, die das Projekt entfernt hat:

$ 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.
Art Bedeutung
beeuni Ein Beeuni-Tool, aufgeführt als beeuni:<name> (oder alle, wenn kein Schlüssel tools: vorhanden ist).
beeuni (overridden) Ein Beeuni-Toolname mit Modulpfad: Stattdessen wird das Modul des Projekts ausgeführt.
project Ein projektspezifisches Tool.

beeuni tools ls --json gibt { manifest, tools_key, tools: [{ name, kind, source }], removed } aus.

Ein Beeuni-Tool entfernen

Lösche seine Zeile unter tools:. Jeder Agent des Projekts verliert das Tool, auf beiden Harnesses und in jeder Session, die nach dem Mergen des Änderungsauftrags startet. Wenn du ein Tool nur für einen Agent entfernen willst, verwende stattdessen agents.<name>.tools.

In einer Session eines Projekts, das ein Tool entfernt hat:

  • Standard-Harness bietet dem Modell das Tool nicht an.
  • Experimental-Harness bietet das Tool nicht an. Ein Aufruf schlägt mit Tool show not found fehl (für show).
  • Der Daemon antwortet auf POST /beeuni/tools/<name> mit 404 und no tool named <name> is loaded.
  • Ein Skill, der das Tool nennt, wird weiterhin geladen. Zum Beispiel nennt beeuni-memory memory. Das Modell liest den Skill, findet kein solches Tool und verwendet andere Tools: Ohne memory liest und bearbeitet es mit den Datei-Tools die Dateien unter memory/.

Ein Beeuni-Tool ändern: auskoppeln

beeuni tools eject <name> erstellt eine eigene Kopie eines Beeuni-Tools im Projekt:

$ 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.
  • Es schreibt den Beeuni-Quellcode – dieselben Bytes, die die Sandbox ausführt – nach tools/<name>.ts. Die Datei importiert nur node:*-Module und liest BEEUNI_API_URL, BEEUNI_TOKEN sowie Provider-Schlüssel aus context.env, sodass sie direkt ausführbar ist.
  • Es setzt <name>: tools/<name>.ts in beeuni.yaml, und zwar in der Datei, die den Eintrag deklariert (der Stammdatei oder einer importierten Datei). Alle anderen Zeilen und Kommentare bleiben erhalten. Die geänderte Zeile endet mit # ejected from beeuni:<name>.
  • Wenn kein Schlüssel tools: vorhanden ist, wird einer erstellt und die übrigen vier Beeuni-Tools werden als beeuni:<name> aufgeführt, sodass durch das Auskoppeln nichts entfernt wird.
  • Der Vorgang wird abgebrochen, wenn tools/<name>.ts vorhanden ist oder das Tool bereits auf ein anderes Modul verweist. --force überschreibt.
  • Ein Name, der kein Beeuni-Tool ist, wird abgelehnt.

Die Kopie gehört dir. Beeuni aktualisiert sie nicht mehr. Um zum gepflegten Tool zurückzukehren, setze die Zeile wieder auf <name>: beeuni:<name> und lösche die Datei.

Ohne Auskoppeln überschreiben

Ein Beeuni-Toolname mit Modulpfad ersetzt das Beeuni-Tool auf jedem Harness:

tools:
  web_search: integrations/search/web_search.ts

Ansichten der Web-UI

Die Web-UI hat für jedes Beeuni-Tool eine Ansicht, die anhand des Toolnamens ausgewählt wird. Die Ansichten show und memory lesen die Argumente des Aufrufs (type, path, url, content, items; command, path). Die Ansichten web_search, image_search und scrape_webpage lesen das Ausgabe-JSON. Eine geänderte Kopie mit demselben Namen muss diese Argumente und diese Ausgabeform beibehalten, sonst zeigt die UI die unverarbeitete Ausgabe.

Validierung

beeuni validate prüft die Liste:

  • <name> in beeuni:<name> muss ein Beeuni-Tool sein, und der Schlüssel muss mit ihm übereinstimmen. web_search: beeuni:image_search ist ein Fehler: 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.
  • Ein Schlüssel tools:, der kein Beeuni-Tool aufführt, löst eine Warnung aus: Sessions of this project get no Beeuni tool (web_search, image_search, scrape_webpage, memory, show). Add `<name>: beeuni:<name>` to keep one. Sie weist auf ein Projekt hin, das sein erstes eigenes Tool hinzugefügt und versehentlich die fünf Beeuni-Tools entfernt hat.
  • Wenn tools eines Agents ein Beeuni-Tool nennt, das das Projekt nicht lädt, wird eine Warnung ausgegeben: "show" is a Beeuni tool this project does not load: add `show: beeuni:show` under the top-level `tools`, or remove it here.

Die Manifest-Referenz enthält alle Regeln.

Ein Projekt-Tool schreiben

// 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

Der Standardexport ist ein einfaches Objekt:

Feld Regel
description Nichtleere Zeichenfolge. Das Modell liest sie, um zu entscheiden, wann das Tool aufgerufen werden soll.
parameters JSON Schema der Argumente, type: 'object'. Das Modell erhält es unverändert; führe erforderliche Argumente also unter required auf. Beeuni validiert die Argumente nicht dagegen.
execute(args, context) Gibt eine Zeichenfolge oder einen beliebigen JSON-Wert zurück (als eingerücktes JSON gesendet). Darf async sein. Ein ausgelöster Fehler ist der Fehler des Tools; das Modell liest seine Meldung.

context enthält:

Feld Beschreibung
sessionId Die Beeuni-Session, zu der der Aufruf gehört.
agent Der Agent, der den Aufruf getätigt hat.
directory Der Checkout des Projekts, /workspace. Löse relative Pfade relativ dazu auf.
env Die Umgebung der Box sowie die Geheimnisse, die dieser Agent aktuell erhält. Ein Geheimnis liest du mit context.env.NAME: Ein Geheimnis, das nach dem Start der Box geändert wurde, ist in context.env enthalten, nicht in process.env.
signal Ein AbortSignal, das abgebrochen wird, wenn der Nutzer den Turn beendet. Übergib es an fetch.
  • Ausgabegröße. Eine Ausgabe mit mehr als 50 KB oder 2.000 Zeilen wird vollständig in einer Datei im temporären Verzeichnis der Sandbox gespeichert. Das Modell erhält den Anfang, die Größe und den Dateipfad. Gib zurück, was das Modell benötigt, keinen unbearbeiteten Dump.
  • Fehler. Ein ausgelöster Fehler beendet den Aufruf, und das Modell liest die Fehlermeldung. Formuliere eine Meldung, aus der hervorgeht, was geändert werden muss.
  • Importe. Ein Modul darf node:*-Module, Bun-APIs und relative Dateien importieren. Ein Paket wird aus einem node_modules neben oder oberhalb des Moduls aufgelöst. Die Sandbox installiert keine Pakete für ein Tool, und ein Config-Release enthält nur Dateien, die Git verfolgt. Verwende fetch für HTTP-APIs. TypeScript wird ohne Build-Schritt ausgeführt.
  • Fehler beim Laden. Ein Modul, das nicht geladen werden kann (fehlende Datei, kein Standardexport, ein parameters, das kein Objektschema ist, ein Fehler beim Import oder ein nicht auflösbares Paket), wird ausgelassen; die übrigen Tools werden weiterhin geladen. Der Daemon protokolliert [tools] project tools that did not load mit dem Grund für jedes Tool.

parameters mit zod

zod 4 erzeugt dasselbe 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`
  },
}

Dieses Modul wird nur geladen, wenn zod aus einem node_modules im Checkout aufgelöst werden kann, in dem die Session läuft. Andernfalls schlägt es mit Cannot find package 'zod' fehl. Um das Schema mit zod zu schreiben und als einfaches JSON Schema bereitzustellen, gib es einmal aus und kopiere die Ausgabe nach parameters:

bun -e "import { z } from 'zod'; console.log(JSON.stringify(z.toJSONSchema(z.object({ id: z.string() })), null, 2))"

Beispiel: Eine HTTP-API mit einem Projektgeheimnis aufrufen

Speichere den Schlüssel als Projektgeheimnis. Der Befehl liest den Wert von stdin:

beeuni secrets set WEATHER_API_KEY=-

Gewähre den Agents, die das Tool aufrufen, Zugriff auf das Geheimnis. Der beeuni-Agent des Startprojekts hat secrets: all. Ein Agent mit eingeschränktem Umfang führt es auf: secrets: [WEATHER_API_KEY].

Schreibe das Modul:

// 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 }
  },
}

Deklariere es:

tools:
  # … the Beeuni tools you keep
  weather_now: tools/weather_now.ts

Beispiel: web_search überschreiben

beeuni tools eject web_search schreibt tools/web_search.ts und setzt web_search: tools/web_search.ts. Ändere anschließend die Kopie. Um beispielsweise nur Ergebnisse von einer Website zu erhalten, füge die Website vor der Anfrage jeder Abfrage in execute hinzu:

// 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}`)

Behalte den Namen, die Argumente und das Ausgabe-JSON bei, damit Skills, die web_search nennen, und die Ansicht der Web-UI weiterhin funktionieren.

Ein Tool testen

beeuni validate prüft den Namen, den Pfad, eine fehlende Datei und die Werte von beeuni:. beeuni tools ls zeigt, welche Tools eine Session erhält.

Führe anschließend einen Commit und Push durch und öffne einen Änderungsauftrag. Starte nach dem Mergen eine Session und fordere einen Aufruf mit echten Argumenten an:

beeuni sessions new --wait --prompt "Call the weather_now tool once with city Berlin and print its output."

Ein Tool, das nicht geladen wird, wird dem Modell nicht angeboten. Ein Tool, das einen Fehler auslöst, antwortet mit seiner Fehlermeldung. beeuni sessions log <id> gibt die Nachrichten der Session aus, einschließlich jedes Tool-Aufrufs und seines Status.

Tools deklarieren

tools: ordnet jeden Toolnamen seinem Modul zu oder einen Beeuni-Toolnamen beeuni:<name>. Du kannst den Ordner eines Moduls frei wählen.

tools:
  web_search: beeuni:web_search
  memory: beeuni:memory
  lookup_order: tools/lookup_order.ts
  crm_note: integrations/crm/note.ts
  • Ein Name muss in snake_case und höchstens 64 Zeichen lang sein: ^[a-z][a-z0-9_]{0,63}$.
  • Ein Harness-Toolname ist ein Fehler. Ein Beeuni-Toolname akzeptiert beeuni:<name> oder einen Modulpfad; das Modul ersetzt das Beeuni-Tool auf jedem Harness.
  • Ein Pfad muss relativ zum Repository sein und mit .ts, .js, .mts, .mjs, .cts oder .cjs enden.
  • Eine unter imports: aufgeführte Datei darf Tools deklarieren. Wird ein Name in zwei Dateien deklariert, ist das ein Fehler. Ein Schlüssel tools: in einer importierten Datei zählt für die Auswahlregel als Schlüssel tools:.

Die Manifest-Referenz enthält alle Regeln.

Wer welches Tool verwenden darf

agents.<name>.tools legt fest, welche Tools das Modell eines Agents sieht. Sie führt Harness-, Beeuni- und Projekt-Tools gleichermaßen auf.

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
Wert Der Agent erhält
weggelassen oder all Alle Tools.
none Kein Tool.
eine Liste Nur die aufgeführten Tools. Eine Liste mit * ist all.
{ exclude: [...] } Alle Tools außer den aufgeführten.
{ bash: false, … } Die frühere Map-Form: false entfernt ein Tool.
  • tools bestimmt die Sichtbarkeit. Die Regeln für permission des Agents entscheiden weiterhin, ob ein Aufruf erlaubt, nachzufragen oder abzulehnen ist. Ein Tool, das nicht in der Liste steht, wird dem Modell verborgen und bei einem Aufruf abgelehnt.
  • Eine Agent-Liste kann kein Beeuni-Tool hinzufügen, das das Projekt nicht lädt. Führe es zuerst unter tools: auf oberster Ebene auf.
  • Ein mit dem Tool task gestarteter Subagent erhält auf Experimental-Harness nur die Tools, die sowohl seine eigene Liste als auch die Liste des Session-Agents zulassen. Auf Standard-Harness erhält er die Tools aus seiner eigenen Liste: Standard-Harness wendet die Regeln eines Agents nur auf diesen Agent an. Damit ein Agent keine Delegation ausführen kann, lass task aus seiner Liste weg.
  • Connector-Tools folgen agents.<name>.connectors, nicht dieser Liste.
  • beeuni validate warnt vor einem Namen, der weder ein Harness-, Beeuni- noch ein Projekt-Tool ist, und vor einem Beeuni-Tool, das das Projekt nicht lädt. Ein Tippfehler in einer exclude-Liste lässt das echte Tool aktiviert.

In Standard-Harness umfasst bash auch die Tools pty_* des Terminal-Plugins. Außerdem verwenden write, edit und apply_patch dieselbe Berechtigung: Wenn eines aufgeführt wird, werden alle drei angezeigt; wenn eines ausgeschlossen wird, werden alle drei verborgen. Experimental-Harness hat separate Tools write und edit.

Wann eine Änderung wirksam wird

Eine Session lädt ihre Tools beim Start ihrer Laufzeitumgebung. Eine Änderung wird nach dem Mergen des Änderungsauftrags wirksam: Neue Sessions laden sie; bei Config-Releases lädt eine laufende Session sie bei der nächsten Konvergenz. Auf Experimental-Harness startet eine Änderung an einem Projekt-Tool oder an der Liste der Beeuni-Tools die Laufzeitumgebung direkt neu, sofern gerade kein Turn läuft; das Gespräch wird fortgesetzt.

Tools in harnesses/opencode/tools/

Standard-Harness lädt weiterhin benutzerdefinierte Tools aus seinem Konfigurationsverzeichnis. Experimental-Harness tut das nicht. Projekte, die vor den gehosteten Tools erstellt wurden, enthalten dort Kopien der Beeuni-Tools (web_search.ts, memory.ts, …).

  • In Standard-Harness hat ein Tool in diesem Ordner Vorrang vor dem gehosteten Tool mit demselben Namen. Daher behält ein Projekt seine Kopie, bis es sie löscht. Lösche die Kopien der Beeuni-Tools: Der Daemon stellt die Tools bereit, die beeuni.yaml aufführt, auf beiden Harnesses.
  • Damit ein Standard-Harness-Tool auf beiden Harnesses ausgeführt wird, verschiebe es aus dem Ordner, ersetze tool({ description, args, execute }) durch ein einfaches Objekt, dessen parameters JSON Schema ist, lies Geheimnisse aus context.env und deklariere es unter tools:.

War diese Seite hilfreich?