2025-12-22 23:40:57 +00:00
|
|
|
|
---
|
2026-01-04 14:32:47 +00:00
|
|
|
|
summary: "Agent tool surface for Clawdbot (browser, canvas, nodes, cron) replacing clawdbot-* skills"
|
2025-12-22 23:40:57 +00:00
|
|
|
|
read_when:
|
|
|
|
|
|
- Adding or modifying agent tools
|
2026-01-04 14:32:47 +00:00
|
|
|
|
- Retiring or changing clawdbot-* skills
|
2025-12-22 23:40:57 +00:00
|
|
|
|
---
|
|
|
|
|
|
|
2026-01-04 14:32:47 +00:00
|
|
|
|
# Tools (Clawdbot)
|
2025-12-22 23:40:57 +00:00
|
|
|
|
|
2026-01-04 14:32:47 +00:00
|
|
|
|
Clawdbot exposes **first-class agent tools** for browser, canvas, nodes, and cron.
|
|
|
|
|
|
These replace the old `clawdbot-*` skills: the tools are typed, no shelling,
|
2025-12-22 23:40:57 +00:00
|
|
|
|
and the agent should rely on them directly.
|
|
|
|
|
|
|
2026-01-05 00:05:21 +01:00
|
|
|
|
## Disabling tools
|
|
|
|
|
|
|
|
|
|
|
|
You can globally allow/deny tools via `agent.tools` in `clawdbot.json`
|
|
|
|
|
|
(deny wins). This prevents disallowed tools from being sent to providers.
|
|
|
|
|
|
|
|
|
|
|
|
```json5
|
|
|
|
|
|
{
|
|
|
|
|
|
agent: {
|
|
|
|
|
|
tools: {
|
|
|
|
|
|
deny: ["browser"]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-22 23:40:57 +00:00
|
|
|
|
## Tool inventory
|
|
|
|
|
|
|
2025-12-25 00:25:11 +00:00
|
|
|
|
### `bash`
|
|
|
|
|
|
Run shell commands in the workspace.
|
|
|
|
|
|
|
|
|
|
|
|
Core parameters:
|
|
|
|
|
|
- `command` (required)
|
2026-01-03 20:15:02 +00:00
|
|
|
|
- `yieldMs` (auto-background after timeout, default 10000)
|
2025-12-25 00:25:11 +00:00
|
|
|
|
- `background` (immediate background)
|
2025-12-25 17:58:19 +00:00
|
|
|
|
- `timeout` (seconds; kills the process if exceeded, default 1800)
|
2026-01-04 05:15:42 +00:00
|
|
|
|
- `elevated` (bool; run on host if elevated mode is enabled/allowed)
|
2026-01-03 20:15:02 +00:00
|
|
|
|
- Need a real TTY? Use the tmux skill.
|
2025-12-25 00:25:11 +00:00
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- Returns `status: "running"` with a `sessionId` when backgrounded.
|
|
|
|
|
|
- Use `process` to poll/log/write/kill/clear background sessions.
|
2026-01-07 23:18:21 +01:00
|
|
|
|
- If `process` is disallowed, `bash` runs synchronously and ignores `yieldMs`/`background`.
|
2026-01-08 22:57:08 +01:00
|
|
|
|
- `elevated` is gated by `agent.elevated` (global sender allowlist) and runs on the host.
|
2025-12-25 00:25:11 +00:00
|
|
|
|
|
|
|
|
|
|
### `process`
|
|
|
|
|
|
Manage background bash sessions.
|
|
|
|
|
|
|
|
|
|
|
|
Core actions:
|
|
|
|
|
|
- `list`, `poll`, `log`, `write`, `kill`, `clear`, `remove`
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- `poll` returns new output and exit status when complete.
|
2025-12-25 17:58:19 +00:00
|
|
|
|
- `log` supports line-based `offset`/`limit` (omit `offset` to grab the last N lines).
|
2026-01-07 23:35:04 +01:00
|
|
|
|
- `process` is scoped per agent; sessions from other agents are not visible.
|
2025-12-25 00:25:11 +00:00
|
|
|
|
|
2026-01-03 12:39:52 +01:00
|
|
|
|
### `browser`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
Control the dedicated clawd browser.
|
|
|
|
|
|
|
|
|
|
|
|
Core actions:
|
|
|
|
|
|
- `status`, `start`, `stop`, `tabs`, `open`, `focus`, `close`
|
|
|
|
|
|
- `snapshot` (aria/ai)
|
|
|
|
|
|
- `screenshot` (returns image block + `MEDIA:<path>`)
|
|
|
|
|
|
- `act` (UI actions: click/type/press/hover/drag/select/fill/resize/wait/evaluate)
|
|
|
|
|
|
- `navigate`, `console`, `pdf`, `upload`, `dialog`
|
|
|
|
|
|
|
2026-01-04 03:32:40 +00:00
|
|
|
|
Profile management:
|
|
|
|
|
|
- `profiles` — list all browser profiles with status
|
|
|
|
|
|
- `create-profile` — create new profile with auto-allocated port (or `cdpUrl`)
|
|
|
|
|
|
- `delete-profile` — stop browser, delete user data, remove from config (local only)
|
|
|
|
|
|
- `reset-profile` — kill orphan process on profile's port (local only)
|
|
|
|
|
|
|
|
|
|
|
|
Common parameters:
|
|
|
|
|
|
- `controlUrl` (defaults from config)
|
|
|
|
|
|
- `profile` (optional; defaults to `browser.defaultProfile`)
|
2025-12-22 23:40:57 +00:00
|
|
|
|
Notes:
|
2026-01-05 22:17:14 +01:00
|
|
|
|
- Requires `browser.enabled=true` (default is `true`; set `false` to disable).
|
2025-12-22 23:40:57 +00:00
|
|
|
|
- Uses `browser.controlUrl` unless `controlUrl` is passed explicitly.
|
2026-01-04 03:32:40 +00:00
|
|
|
|
- All actions accept optional `profile` parameter for multi-instance support.
|
|
|
|
|
|
- When `profile` is omitted, uses `browser.defaultProfile` (defaults to "clawd").
|
|
|
|
|
|
- Profile names: lowercase alphanumeric + hyphens only (max 64 chars).
|
|
|
|
|
|
- Port range: 18800-18899 (~100 profiles max).
|
|
|
|
|
|
- Remote profiles are attach-only (no start/stop/reset).
|
2025-12-26 19:02:19 +00:00
|
|
|
|
- `snapshot` defaults to `ai`; use `aria` for the accessibility tree.
|
|
|
|
|
|
- `act` requires `ref` from `snapshot --format ai`; use `evaluate` for rare CSS selector needs.
|
2025-12-30 19:22:38 +00:00
|
|
|
|
- Avoid `act` → `wait` by default; use it only in exceptional cases (no reliable UI state to wait on).
|
2026-01-01 09:35:20 +00:00
|
|
|
|
- `upload` can optionally pass a `ref` to auto-click after arming.
|
2026-01-01 09:44:29 +00:00
|
|
|
|
- `upload` also supports `inputRef` (aria ref) or `element` (CSS selector) to set `<input type="file">` directly.
|
2025-12-22 23:40:57 +00:00
|
|
|
|
|
2026-01-03 12:39:52 +01:00
|
|
|
|
### `canvas`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
Drive the node Canvas (present, eval, snapshot, A2UI).
|
|
|
|
|
|
|
|
|
|
|
|
Core actions:
|
|
|
|
|
|
- `present`, `hide`, `navigate`, `eval`
|
|
|
|
|
|
- `snapshot` (returns image block + `MEDIA:<path>`)
|
|
|
|
|
|
- `a2ui_push`, `a2ui_reset`
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- Uses gateway `node.invoke` under the hood.
|
|
|
|
|
|
- If no `node` is provided, the tool picks a default (single connected node or local mac node).
|
2025-12-27 01:36:24 +01:00
|
|
|
|
- A2UI is v0.8 only (no `createSurface`); the CLI rejects v0.9 JSONL with line errors.
|
2026-01-08 07:16:05 +01:00
|
|
|
|
- Quick smoke: `clawdbot nodes canvas a2ui push --node <id> --text "Hello from A2UI"`.
|
2025-12-22 23:40:57 +00:00
|
|
|
|
|
2026-01-03 12:39:52 +01:00
|
|
|
|
### `nodes`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
Discover and target paired nodes; send notifications; capture camera/screen.
|
|
|
|
|
|
|
|
|
|
|
|
Core actions:
|
|
|
|
|
|
- `status`, `describe`
|
|
|
|
|
|
- `pending`, `approve`, `reject` (pairing)
|
|
|
|
|
|
- `notify` (macOS `system.notify`)
|
2026-01-08 00:17:44 +00:00
|
|
|
|
- `run` (macOS `system.run`)
|
2025-12-22 23:40:57 +00:00
|
|
|
|
- `camera_snap`, `camera_clip`, `screen_record`
|
2026-01-04 00:54:44 +01:00
|
|
|
|
- `location_get`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- Camera/screen commands require the node app to be foregrounded.
|
|
|
|
|
|
- Images return image blocks + `MEDIA:<path>`.
|
|
|
|
|
|
- Videos return `FILE:<path>` (mp4).
|
2026-01-04 00:54:44 +01:00
|
|
|
|
- Location returns a JSON payload (lat/lon/accuracy/timestamp).
|
2026-01-08 00:24:11 +00:00
|
|
|
|
- `run` params: `command` argv array; optional `cwd`, `env` (`KEY=VAL`), `commandTimeoutMs`, `invokeTimeoutMs`, `needsScreenRecording`.
|
|
|
|
|
|
|
|
|
|
|
|
Example (`run`):
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"action": "run",
|
|
|
|
|
|
"node": "office-mac",
|
|
|
|
|
|
"command": ["echo", "Hello"],
|
|
|
|
|
|
"env": ["FOO=bar"],
|
|
|
|
|
|
"commandTimeoutMs": 12000,
|
|
|
|
|
|
"invokeTimeoutMs": 45000,
|
|
|
|
|
|
"needsScreenRecording": false
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
2025-12-22 23:40:57 +00:00
|
|
|
|
|
2026-01-04 19:35:00 +01:00
|
|
|
|
### `image`
|
|
|
|
|
|
Analyze an image with the configured image model.
|
|
|
|
|
|
|
|
|
|
|
|
Core parameters:
|
|
|
|
|
|
- `image` (required path or URL)
|
|
|
|
|
|
- `prompt` (optional; defaults to "Describe the image.")
|
|
|
|
|
|
- `model` (optional override)
|
|
|
|
|
|
- `maxBytesMb` (optional size cap)
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
2026-01-06 00:56:29 +00:00
|
|
|
|
- Only available when `agent.imageModel` is configured (primary or fallbacks).
|
2026-01-04 19:35:00 +01:00
|
|
|
|
- Uses the image model directly (independent of the main chat model).
|
|
|
|
|
|
|
2026-01-03 12:39:52 +01:00
|
|
|
|
### `cron`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
Manage Gateway cron jobs and wakeups.
|
|
|
|
|
|
|
|
|
|
|
|
Core actions:
|
|
|
|
|
|
- `status`, `list`
|
|
|
|
|
|
- `add`, `update`, `remove`, `run`, `runs`
|
|
|
|
|
|
- `wake` (enqueue system event + optional immediate heartbeat)
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- `add` expects a full cron job object (same schema as `cron.add` RPC).
|
2026-01-05 23:09:48 -03:00
|
|
|
|
- `update` uses `{ id, patch }`.
|
2025-12-22 23:40:57 +00:00
|
|
|
|
|
2026-01-03 12:39:52 +01:00
|
|
|
|
### `gateway`
|
2026-01-08 01:29:56 +01:00
|
|
|
|
Restart or apply updates to the running Gateway process (in-place).
|
2025-12-25 17:58:19 +00:00
|
|
|
|
|
|
|
|
|
|
Core actions:
|
2026-01-08 07:16:05 +01:00
|
|
|
|
- `restart` (sends `SIGUSR1` to the current process; `clawdbot gateway` restart in-place)
|
2026-01-08 01:29:56 +01:00
|
|
|
|
- `config.get` / `config.schema`
|
|
|
|
|
|
- `config.apply` (validate + write config + restart + wake)
|
|
|
|
|
|
- `update.run` (run update + restart + wake)
|
2025-12-25 17:58:19 +00:00
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- Use `delayMs` (defaults to 2000) to avoid interrupting an in-flight reply.
|
|
|
|
|
|
|
2026-01-07 06:53:01 +01:00
|
|
|
|
### `sessions_list` / `sessions_history` / `sessions_send` / `sessions_spawn`
|
2026-01-03 23:44:38 +01:00
|
|
|
|
List sessions, inspect transcript history, or send to another session.
|
|
|
|
|
|
|
|
|
|
|
|
Core parameters:
|
|
|
|
|
|
- `sessions_list`: `kinds?`, `limit?`, `activeMinutes?`, `messageLimit?` (0 = none)
|
|
|
|
|
|
- `sessions_history`: `sessionKey`, `limit?`, `includeTools?`
|
|
|
|
|
|
- `sessions_send`: `sessionKey`, `message`, `timeoutSeconds?` (0 = fire-and-forget)
|
2026-01-08 06:55:28 +00:00
|
|
|
|
- `sessions_spawn`: `task`, `label?`, `agentId?`, `model?`, `runTimeoutSeconds?`, `cleanup?`
|
2026-01-03 23:44:38 +01:00
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- `main` is the canonical direct-chat key; global/unknown are hidden.
|
|
|
|
|
|
- `messageLimit > 0` fetches last N messages per session (tool messages filtered).
|
|
|
|
|
|
- `sessions_send` waits for final completion when `timeoutSeconds > 0`.
|
2026-01-07 06:53:01 +01:00
|
|
|
|
- `sessions_spawn` starts a sub-agent run and posts an announce reply back to the requester chat.
|
2026-01-07 16:14:25 +00:00
|
|
|
|
- `sessions_spawn` is non-blocking and returns `status: "accepted"` immediately.
|
2026-01-04 03:37:44 +01:00
|
|
|
|
- `sessions_send` runs a reply‑back ping‑pong (reply `REPLY_SKIP` to stop; max turns via `session.agentToAgent.maxPingPongTurns`, 0–5).
|
|
|
|
|
|
- After the ping‑pong, the target agent runs an **announce step**; reply `ANNOUNCE_SKIP` to suppress the announcement.
|
2026-01-03 23:44:38 +01:00
|
|
|
|
|
2026-01-08 07:06:36 +00:00
|
|
|
|
### `agents_list`
|
|
|
|
|
|
List agent ids that the current session may target with `sessions_spawn`.
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- Result is restricted to per-agent allowlists (`routing.agents.<agentId>.subagents.allowAgents`).
|
|
|
|
|
|
- When `["*"]` is configured, the tool includes all configured agents and marks `allowAny: true`.
|
|
|
|
|
|
|
2026-01-02 17:41:47 -06:00
|
|
|
|
### `discord`
|
|
|
|
|
|
Send Discord reactions, stickers, or polls.
|
|
|
|
|
|
|
|
|
|
|
|
Core actions:
|
|
|
|
|
|
- `react` (`channelId`, `messageId`, `emoji`)
|
|
|
|
|
|
- `reactions` (`channelId`, `messageId`, optional `limit`)
|
|
|
|
|
|
- `sticker` (`to`, `stickerIds`, optional `content`)
|
|
|
|
|
|
- `poll` (`to`, `question`, `answers`, optional `allowMultiselect`, `durationHours`, `content`)
|
|
|
|
|
|
- `permissions` (`channelId`)
|
|
|
|
|
|
- `readMessages` (`channelId`, optional `limit`/`before`/`after`/`around`)
|
|
|
|
|
|
- `sendMessage` (`to`, `content`, optional `mediaUrl`, `replyTo`)
|
|
|
|
|
|
- `editMessage` (`channelId`, `messageId`, `content`)
|
|
|
|
|
|
- `deleteMessage` (`channelId`, `messageId`)
|
|
|
|
|
|
- `threadCreate` (`channelId`, `name`, optional `messageId`, `autoArchiveMinutes`)
|
|
|
|
|
|
- `threadList` (`guildId`, optional `channelId`, `includeArchived`, `before`, `limit`)
|
|
|
|
|
|
- `threadReply` (`channelId`, `content`, optional `mediaUrl`, `replyTo`)
|
|
|
|
|
|
- `pinMessage`/`unpinMessage` (`channelId`, `messageId`)
|
|
|
|
|
|
- `listPins` (`channelId`)
|
|
|
|
|
|
- `searchMessages` (`guildId`, `content`, optional `channelId`/`channelIds`, `authorId`/`authorIds`, `limit`)
|
|
|
|
|
|
- `memberInfo` (`guildId`, `userId`)
|
|
|
|
|
|
- `roleInfo` (`guildId`)
|
|
|
|
|
|
- `emojiList` (`guildId`)
|
|
|
|
|
|
- `roleAdd`/`roleRemove` (`guildId`, `userId`, `roleId`)
|
|
|
|
|
|
- `channelInfo` (`channelId`)
|
|
|
|
|
|
- `channelList` (`guildId`)
|
|
|
|
|
|
- `voiceStatus` (`guildId`, `userId`)
|
|
|
|
|
|
- `eventList` (`guildId`)
|
|
|
|
|
|
- `eventCreate` (`guildId`, `name`, `startTime`, optional `endTime`, `description`, `channelId`, `entityType`, `location`)
|
|
|
|
|
|
- `timeout` (`guildId`, `userId`, optional `durationMinutes`, `until`, `reason`)
|
|
|
|
|
|
- `kick` (`guildId`, `userId`, optional `reason`)
|
|
|
|
|
|
- `ban` (`guildId`, `userId`, optional `reason`, `deleteMessageDays`)
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
- `to` accepts `channel:<id>` or `user:<id>`.
|
|
|
|
|
|
- Polls require 2–10 answers and default to 24 hours.
|
|
|
|
|
|
- `reactions` returns per-emoji user lists (limited to 100 per reaction).
|
2026-01-07 04:24:11 +01:00
|
|
|
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
2026-01-02 17:47:09 -06:00
|
|
|
|
- `discord.actions.*` gates Discord tool actions; `roles` + `moderation` default to `false`.
|
2026-01-02 17:41:47 -06:00
|
|
|
|
- `searchMessages` follows the Discord preview spec (limit max 25, channel/author filters accept arrays).
|
2026-01-06 18:25:52 +00:00
|
|
|
|
- The tool is only exposed when the current provider is Discord.
|
2026-01-02 17:41:47 -06:00
|
|
|
|
|
2026-01-07 04:10:13 +01:00
|
|
|
|
### `whatsapp`
|
|
|
|
|
|
Send WhatsApp reactions.
|
|
|
|
|
|
|
|
|
|
|
|
Core actions:
|
|
|
|
|
|
- `react` (`chatJid`, `messageId`, `emoji`, optional `remove`, `participant`, `fromMe`, `accountId`)
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
2026-01-07 04:24:11 +01:00
|
|
|
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
2026-01-07 04:10:13 +01:00
|
|
|
|
- `whatsapp.actions.*` gates WhatsApp tool actions.
|
|
|
|
|
|
- The tool is only exposed when the current provider is WhatsApp.
|
|
|
|
|
|
|
|
|
|
|
|
### `telegram`
|
2026-01-08 00:50:29 +00:00
|
|
|
|
Send Telegram messages or reactions.
|
2026-01-07 04:10:13 +01:00
|
|
|
|
|
|
|
|
|
|
Core actions:
|
2026-01-08 00:50:29 +00:00
|
|
|
|
- `sendMessage` (`to`, `content`, optional `mediaUrl`, `replyToMessageId`, `messageThreadId`)
|
2026-01-07 04:10:13 +01:00
|
|
|
|
- `react` (`chatId`, `messageId`, `emoji`, optional `remove`)
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
|
2026-01-07 04:24:11 +01:00
|
|
|
|
- Reaction removal semantics: see [/tools/reactions](/tools/reactions).
|
2026-01-07 04:10:13 +01:00
|
|
|
|
- `telegram.actions.*` gates Telegram tool actions.
|
|
|
|
|
|
- The tool is only exposed when the current provider is Telegram.
|
|
|
|
|
|
|
2025-12-22 23:40:57 +00:00
|
|
|
|
## Parameters (common)
|
|
|
|
|
|
|
2026-01-03 12:39:52 +01:00
|
|
|
|
Gateway-backed tools (`canvas`, `nodes`, `cron`):
|
2025-12-22 23:40:57 +00:00
|
|
|
|
- `gatewayUrl` (default `ws://127.0.0.1:18789`)
|
|
|
|
|
|
- `gatewayToken` (if auth enabled)
|
|
|
|
|
|
- `timeoutMs`
|
|
|
|
|
|
|
|
|
|
|
|
Browser tool:
|
|
|
|
|
|
- `controlUrl` (defaults from config)
|
|
|
|
|
|
|
|
|
|
|
|
## Recommended agent flows
|
|
|
|
|
|
|
|
|
|
|
|
Browser automation:
|
2026-01-03 12:39:52 +01:00
|
|
|
|
1) `browser` → `status` / `start`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
2) `snapshot` (ai or aria)
|
|
|
|
|
|
3) `act` (click/type/press)
|
|
|
|
|
|
4) `screenshot` if you need visual confirmation
|
|
|
|
|
|
|
|
|
|
|
|
Canvas render:
|
2026-01-03 12:39:52 +01:00
|
|
|
|
1) `canvas` → `present`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
2) `a2ui_push` (optional)
|
|
|
|
|
|
3) `snapshot`
|
|
|
|
|
|
|
|
|
|
|
|
Node targeting:
|
2026-01-03 12:39:52 +01:00
|
|
|
|
1) `nodes` → `status`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
2) `describe` on the chosen node
|
2026-01-08 00:24:11 +00:00
|
|
|
|
3) `notify` / `run` / `camera_snap` / `screen_record`
|
2025-12-22 23:40:57 +00:00
|
|
|
|
|
|
|
|
|
|
## Safety
|
|
|
|
|
|
|
2026-01-08 00:24:11 +00:00
|
|
|
|
- Avoid direct `system.run`; use `nodes` → `run` only with explicit user consent.
|
2025-12-22 23:40:57 +00:00
|
|
|
|
- Respect user consent for camera/screen capture.
|
|
|
|
|
|
- Use `status/describe` to ensure permissions before invoking media commands.
|
2025-12-23 00:29:38 +00:00
|
|
|
|
|
2026-01-08 23:06:56 +01:00
|
|
|
|
## How tools are presented to the agent
|
|
|
|
|
|
|
|
|
|
|
|
Tools are exposed in two parallel channels:
|
|
|
|
|
|
|
|
|
|
|
|
1) **System prompt text**: a human-readable list + guidance.
|
|
|
|
|
|
2) **Tool schema**: the structured function definitions sent to the model API.
|
|
|
|
|
|
|
|
|
|
|
|
That means the agent sees both “what tools exist” and “how to call them.” If a tool
|
|
|
|
|
|
doesn’t appear in the system prompt or the schema, the model cannot call it.
|