---
title: "Alati"
description: "Jedan modul alata radi u svakom okruženju za agente. beeuni.yaml navodi Beeuni alate i alate samog projekta, a lista alata svakog agenta određuje ko sme da ih poziva."
---

Алатка је функција коју модел позива током једног потеза. Једна
[сесија](/docs/sr/work/sessions) има три врсте, у оба
[окружења](/docs/sr/work/harnesses), стандардни harness и експериментални harness:

| Врста | Називи | Имплементира |
| --- | --- | --- |
| Алатке окружења | `bash`, `read`, `write`, `edit`, `glob`, `grep`, `task`, `question`, … | Окружење. |
| Beeuni алатке | `web_search`, `image_search`, `scrape_webpage`, `memory`, `show` | Beeuni. `beeuni.yaml` наводи сваку од њих као `<name>: beeuni:<name>`. Пројекат без кључа `tools:` добија свих пет. |
| Алатке пројекта | Било који назив који декларишете | Ваш пројекат: један модул, декларисан под `tools:` у `beeuni.yaml`. |

Beeuni алатке и алатке пројекта независне су од окружења. Демон изолованог окружења учитава један модул по алатки и покреће га у било ком окружењу, са истим називом, аргументима и излазом. експериментални harness позива модул у процесу демона. стандардни harness га позива преко додатка који демон уписује, а који сваки позив прослеђује демону. Модул никада не увози пакет окружења.

<a id="beeuni-tools-in-beeuniyaml"></a>

## Beeuni алатке у beeuni.yaml

Нови пројекат наводи пет Beeuni алатки под `tools:`:

```yaml
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>` значи: алатка коју одржава Beeuni. Исправка те алатке стиже до сваког пројекта који је наводи, без измена у пројекту.

<a id="which-beeuni-tools-a-session-gets"></a>

### Које Beeuni алатке сесија добија

| `beeuni.yaml` | Сесија добија |
| --- | --- |
| Нема кључа `tools:`, ни у коренској датотеци ни у било којој [увезеној](/docs/sr/project/manifest#imports) датотеци | Свих пет Beeuni алатки. Пројекат направљен пре постојања ове листе задржава их све. |
| Кључ `tools:`, чак и празан (`tools: {}` или `tools:` са обрисаним свим редовима) | Само Beeuni алатке које наводи, као `beeuni:<name>` или као модул који замењује алатку. |

Сопствене алатке пројекта учитавају се у оба случаја.

<a id="see-what-a-session-gets"></a>

### Погледајте шта сесија добија

`beeuni tools ls` чита `beeuni.yaml` и његове увозе и исписује сваку алатку коју сесија добија, а затим Beeuni алатке које је пројекат уклонио:

```text
$ 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.
```

| Врста | Значење |
| --- | --- |
| `beeuni` | Beeuni алатка, наведена као `beeuni:<name>` (или свака, без кључа `tools:`). |
| `beeuni (overridden)` | Назив Beeuni алатке са путањом модула: уместо ње се покреће модул пројекта. |
| `project` | Алатка самог пројекта. |

`beeuni tools ls --json` исписује `{ manifest, tools_key, tools: [{ name, kind, source }], removed }`.

<a id="remove-a-beeuni-tool"></a>

### Уклоните Beeuni алатку

Обришите њен ред под `tools:`. Сваки агент пројекта губи алатку, у оба окружења, у свакој сесији која започне након спајања захтева за измену. Да бисте алатку ускратили само једном агенту, користите
[`agents.<name>.tools`](#who-may-use-which-tool) уместо тога.

Сесија пројекта који је уклонио алатку:

- **стандардни harness** не нуди алатку моделу.
- **експериментални harness** не нуди алатку. Позив јој не успева са `Tool show not found`
  (за `show`).
- **Демон** одговара на `POST /beeuni/tools/<name>` са `404` и
  `no tool named <name> is loaded`.
- **Вештина која наводи алатку и даље се учитава.** На пример, `beeuni-memory`
  наводи `memory`. Модел чита вештину, не налази такву алатку и користи
  друге алатке: без `memory` чита и уређује датотеке под `memory/`
  помоћу алатки за рад са датотекама.

<a id="change-a-beeuni-tool-eject"></a>

### Измените Beeuni алатку: издвојите је

`beeuni tools eject <name>` даје пројекту сопствену копију Beeuni алатке:

```text
$ 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.
```

- Уписује изворни код Beeuni алатке, исте бајтове које покреће изоловано окружење, у `tools/<name>.ts`. Датотека увози само `node:*` модуле и чита `BEEUNI_API_URL`, `BEEUNI_TOKEN` и кључеве добављача из `context.env`, па ради без измена.
- Поставља `<name>: tools/<name>.ts` у `beeuni.yaml`, у датотеци која декларише улазну тачку (коренској датотеци или увезеној датотеци). Сваки други ред и коментар остаје. Измењени ред се завршава са `# ejected from beeuni:<name>`.
- Ако нема кључа `tools:`, креира га и наводи преостале четири Beeuni алатке као `beeuni:<name>`, тако да издвајање ништа не уклања.
- Одбија рад када постоји `tools/<name>.ts` или када алатка већ упућује на други модул. `--force` преписује постојеће.
- Одбија назив који није Beeuni алатка.

Копија је ваша. Beeuni је више не ажурира. Да бисте се вратили на одржавану алатку, вратите ред на `<name>: beeuni:<name>` и избришите датотеку.

<a id="override-without-eject"></a>

### Замените без издвајања

Назив Beeuni алатке са путањом модула замењује Beeuni алатку у сваком окружењу:

```yaml
tools:
  web_search: integrations/search/web_search.ts
```

<a id="the-web-ui-views"></a>

### Прикази веб корисничког интерфејса

Веб кориснички интерфејс има приказ за сваку Beeuni алатку, изабран на основу назива алатке. Прикази `show` и `memory` читају аргументе позива (`type`, `path`, `url`, `content`, `items`; `command`, `path`). Прикази `web_search`, `image_search` и `scrape_webpage` читају излазни JSON. Измењена копија која задржава назив мора да задржи те аргументе и тај облик излаза, иначе интерфејс приказује сирови излаз.

<a id="validation"></a>

### Провера

`beeuni validate` проверава листу:

- `<name>` у `beeuni:<name>` мора бити Beeuni алатка, а кључ мора бити једнак њеном називу. `web_search: beeuni:image_search` је грешка:
  ``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.``
- Кључ `tools:` који не наводи ниједну Beeuni алатку представља упозорење:
  ``Sessions of this project get no Beeuni tool (web_search, image_search, scrape_webpage, memory, show). Add `<name>: beeuni:<name>` to keep one.``
  Открива пројекат који дода прву сопствену алатку и случајно одбаци свих пет.
- Агент чији `tools` наводи Beeuni алатку коју пројекат не учитава представља упозорење: ``"show" is a Beeuni tool this project does not load: add `show: beeuni:show` under the top-level `tools`, or remove it here.``

[Референца манифеста](/docs/sr/project/manifest#tools) садржи сва правила.

<a id="write-a-project-tool"></a>

## Напишите алатку пројекта

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

```yaml
# beeuni.yaml
tools:
  web_search: beeuni:web_search
  # … the other Beeuni tools you keep
  lookup_order: tools/lookup_order.ts
```

Подразумевани извоз је обичан објекат:

| Поље | Правило |
| --- | --- |
| `description` | Непразан стринг. Модел га чита да би одлучио када да позове алатку. |
| `parameters` | [JSON Schema](https://json-schema.org) аргумената, `type: 'object'`. Модел га прима таквог какав је, зато наведите обавезне аргументе у `required`. Beeuni не проверава аргументе у односу на њега. |
| `execute(args, context)` | Враћа стринг или било коју JSON вредност (послату као увучени JSON). Може бити `async`. Избачена грешка је грешка алатке, а модел чита њену поруку. |

`context` садржи:

| Поље | Шта је то |
| --- | --- |
| `sessionId` | Beeuni сесија којој позив припада. |
| `agent` | Агент који је упутио позив. |
| `directory` | Преузета копија пројекта, `/workspace`. Релативну путању разрешите у односу на њу. |
| `env` | Окружење кутије и [тајне](/docs/sr/project/secrets) које овај агент прима, у њиховом тренутном стању. Тајну прочитајте као `context.env.NAME`: тајна промењена након покретања кутије налази се у `context.env`, а не у `process.env`. |
| `signal` | `AbortSignal` који прекида рад када корисник заустави потез. Проследите га у `fetch`. |

- **Величина излаза.** Излаз већи од 50 KB или 2.000 редова у целини се чува у датотеци у привременом директоријуму sandbox-а. Модел добија почетак излаза, величину и путању до датотеке. Вратите оно што је моделу потребно, а не сирови излаз.
- **Грешке.** Бачена грешка завршава позив, а модел чита поруку о грешци. Баците поруку која објашњава шта треба променити.
- **Увоз.** Модул може да увози `node:*` модуле, Bun API-је и релативне датотеке. Пакет се разрешава из директоријума `node_modules` поред модула или изнад њега. Sandbox не инсталира пакете за алатку, а [издање конфигурације](/docs/sr/work/runtime#config-convergence) садржи само датотеке које Git прати. Користите `fetch` за HTTP API-је. TypeScript се покреће без корака за изградњу.
- **Неуспеси.** Модул који не може да се учита (недостајућа датотека, нема подразумевани извоз, `parameters` који није шема објекта, грешка при увозу или пакет који не може да се разреши) изоставља се, а остале алатке се и даље учитавају. Демон бележи `[tools] project tools that did not load` са разлогом за сваку алатку.

<a id="parameters-with-zod"></a>

### `parameters` помоћу zod-а

zod 4 генерише исту JSON Schema:

```ts
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`
  },
}
```

Овај модул се учитава само ако се `zod` разрешава из `node_modules` у checkout-у у ком се сесија покреће. У супротном долази до грешке `Cannot find package 'zod'`.
Да бисте написали шему помоћу zod-а и испоручили обичну JSON Schema, једном је одштампајте и налепите излаз у `parameters`:

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

<a id="example-call-an-http-api-with-a-project-secret"></a>

### Пример: позивање HTTP API-ја помоћу тајне пројекта

Сачувајте кључ као тајну пројекта. Команда чита вредност са stdin-а:

```bash
beeuni secrets set WEATHER_API_KEY=-
```

Доделите тајну агентима који позивају алатку. Агент `beeuni` из почетног шаблона има `secrets: all`. Агент са ограниченим приступом наводи је овако: `secrets: [WEATHER_API_KEY]`.

Напишите модул:

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

Декларишите га:

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

<a id="example-override-websearch"></a>

### Пример: замена за `web_search`

`beeuni tools eject web_search` пише `tools/web_search.ts` и поставља
`web_search: tools/web_search.ts`. Затим измените копију. На пример, да бисте задржали резултате само са једног сајта, додајте сајт у сваки упит у `execute`, пре захтева:

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

Задржите име, аргументе и излазни JSON да би вештине које именују `web_search` и приказ веб корисничког интерфејса и даље радили.

<a id="test-a-tool"></a>

### Тестирање алатке

`beeuni validate` проверава име, путању, недостајућу датотеку и вредности `beeuni:`. `beeuni tools ls` показује шта сесија добија.

Затим направите комит, пошаљите измене и отворите захтев за измену. Када се он споји, покрените сесију и затражите један позив са стварним аргументима:

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

Алатка која не може да се учита не нуди се моделу. Алатка која баци грешку одговара поруком о грешци. `beeuni sessions log <id>` исписује поруке сесије, укључујући сваки позив алатке и његов статус.

<a id="declare-tools"></a>

## Декларисање алатки

`tools:` мапира свако име алатке на њен модул, а име Beeuni алатке на `beeuni:<name>`. Путању до фасцикле модула можете да изаберете сами.

```yaml
tools:
  web_search: beeuni:web_search
  memory: beeuni:memory
  lookup_order: tools/lookup_order.ts
  crm_note: integrations/crm/note.ts
```

- Име се пише у snake_case и може имати највише 64 знака: `^[a-z][a-z0-9_]{0,63}$`.
- Име алатке окружења за извршавање је грешка. Име Beeuni алатке прихвата `beeuni:<name>` или путању до модула; модул замењује Beeuni алатку у сваком окружењу за извршавање.
- Путања је релативна у односу на репозиторијум и завршава се наставком `.ts`, `.js`, `.mts`, `.mjs`, `.cts` или `.cjs`.
- Датотека наведена у одељку [`imports:`](/docs/sr/project/manifest#imports) може да декларише алатке. Ако је исто име декларисано у две датотеке, то је грешка. Кључ `tools:` у увезеној датотеци рачуна се као кључ `tools:` за правило избора.

[Референца манифеста](/docs/sr/project/manifest#tools) садржи сва правила.

<a id="who-may-use-which-tool"></a>

## Ко може да користи које алатке

`agents.<name>.tools` одређује које алатке модел агента види. Односи се подједнако на алатке окружења за извршавање, Beeuni и пројекта.

```yaml
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
```

| Вредност | Агент добија |
| --- | --- |
| изостављено или `all` | Све алатке. |
| `none` | Ниједну алатку. |
| листа | Само наведене алатке. Листа која садржи `*` је `all`. |
| `{ exclude: [...] }` | Све алатке осим наведених. |
| `{ bash: false, … }` | Ранији облик мапе: `false` уклања алатку. |

- `tools` одређује видљивост. Правила `permission` агента и даље одређују да ли је позив дозвољен, да ли је потребно одобрење или је одбијен. Алатка која није на листи скривена је од модела и позив те алатке се одбија.
- Листа агента не може да дода Beeuni алатку коју пројекат не учитава. Прво је наведите у `tools:` на највишем нивоу.
- Подагент покренут алатком `task` добија само алатке које дозвољавају и његова листа и листа агента сесије у експериментални harness-ју. У стандардни harness-у добија алатке са сопствене листе: стандардни harness примењује правила агента само на тог агента. Да бисте спречили агента да делегира, изоставите `task` са његове листе.
- Алатке [конектора](/docs/sr/connect/connectors) прате `agents.<name>.connectors`, а не ову листу.
- `beeuni validate` упозорава на име које није алатка окружења за извршавање, Beeuni или пројекта, као и на Beeuni алатку коју пројекат не учитава. Ако је име погрешно унето у листу `exclude`, стварна алатка остаје укључена.

У стандардни harness-у, `bash` обухвата и алатке `pty_*` додатка за терминал, а `write`, `edit` и `apply_patch` деле једну дозволу: навођењем једне приказују се све три, а изостављањем једне скривају се све три. У експериментални harness-ју алатке `write` и `edit` имају засебне дозволе.

<a id="when-a-change-takes-effect"></a>

## Када измена ступа на снагу

Сесија учитава алатке при покретању окружења за извршавање. Измена се примењује након спајања захтева за измену: нове сесије је учитавају, а уз [издања конфигурације](/docs/sr/work/runtime#config-convergence) покренута сесија је учитава при следећем усаглашавању. У експериментални harness-ју, измена алатке пројекта или листе Beeuni алатки поново покреће окружење за извршавање на истом месту када се не извршава ниједан потез; разговор се наставља.

<a id="tools-in-harnessesopencodetools"></a>

## Алатке у `harnesses/opencode/tools/`

стандардни harness и даље учитава прилагођене алатке из директоријума конфигурације. експериментални harness то не ради. Пројекти настали пре увођења хостованих алатки у том директоријуму садрже копије Beeuni алатки (`web_search.ts`, `memory.ts`, …).

- У стандардни harness-у, алатка у тој фасцикли има предност над хостованом алатком истог имена, па пројекат задржава своју копију док је не избрише. Избришите копије Beeuni алатки: демон хостује оне које наводи `beeuni.yaml`, у оба окружења за извршавање.
- Да би стандардни harness алатка радила у оба окружења за извршавање, преместите је из те фасцикле, замените `tool({ description, args, execute })` обичним објектом чији је `parameters` JSON Schema, читајте тајне из `context.env` и декларишите алатку под `tools:`.
