2025-10-25 14:50:14 -03:00
# Tool Definition
2025-11-21 12:13:48 -03:00
In BotServer, a **tool** is simply a `.bas` file. That's it!
## How It Works
1. **Create a `.bas` file** in your `.gbdialog/` folder
2. **The LLM automatically discovers it** and can call it when needed
3. **No manual registration required** - it just works!
2025-11-23 17:02:22 -03:00
### Tool Discovery and Execution Flow
2025-11-24 13:02:30 -03:00
< svg width = "700" height = "600" viewBox = "0 0 700 600" xmlns = "http://www.w3.org/2000/svg" style = "background: transparent;" >
<!-- Title -->
< text x = "350" y = "25" text-anchor = "middle" font-family = "system-ui, -apple-system, sans-serif" font-size = "16" font-weight = "300" fill = "currentColor" opacity = "0.9" > LLM Tool Discovery and Execution Pipeline< / text >
<!-- User Input -->
< rect x = "200" y = "50" width = "300" height = "40" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "8" opacity = "0.8" / >
< text x = "350" y = "75" text-anchor = "middle" font-family = "system-ui" font-size = "12" fill = "currentColor" > "Send an email to John about the meeting"< / text >
<!-- Arrow down -->
< path d = "M 350 90 L 350 120" stroke = "currentColor" stroke-width = "2" fill = "none" marker-end = "url( #arrow1 )" opacity = "0.6" />
<!-- LLM Analysis -->
< rect x = "250" y = "120" width = "200" height = "50" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "8" opacity = "0.8" / >
< text x = "350" y = "140" text-anchor = "middle" font-family = "system-ui" font-size = "13" font-weight = "500" fill = "currentColor" > LLM Analyzes< / text >
< text x = "350" y = "158" text-anchor = "middle" font-family = "system-ui" font-size = "11" fill = "currentColor" opacity = "0.7" > "Need email tool"< / text >
<!-- Arrow down -->
< path d = "M 350 170 L 350 200" stroke = "currentColor" stroke-width = "2" fill = "none" marker-end = "url( #arrow1 )" opacity = "0.6" />
<!-- Tool Discovery -->
< rect x = "150" y = "200" width = "400" height = "80" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "8" opacity = "0.8" / >
< text x = "350" y = "220" text-anchor = "middle" font-family = "system-ui" font-size = "13" font-weight = "500" fill = "currentColor" > Tool Discovery< / text >
<!-- Inner box for tools list -->
< rect x = "240" y = "230" width = "220" height = "40" fill = "none" stroke = "currentColor" stroke-width = "1" rx = "4" opacity = "0.5" stroke-dasharray = "3,2" / >
< text x = "350" y = "246" text-anchor = "middle" font-family = "monospace" font-size = "10" fill = "currentColor" opacity = "0.8" > Scan .gbdialog/< / text >
< text x = "350" y = "260" text-anchor = "middle" font-family = "monospace" font-size = "9" fill = "currentColor" opacity = "0.7" > • send-email.bas ✓ • create-task.bas • get-weather.bas< / text >
<!-- Arrow down -->
< path d = "M 350 280 L 350 310" stroke = "currentColor" stroke-width = "2" fill = "none" marker-end = "url( #arrow1 )" opacity = "0.6" />
<!-- Parameter Collection -->
< rect x = "200" y = "310" width = "300" height = "70" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "8" opacity = "0.8" / >
< text x = "350" y = "330" text-anchor = "middle" font-family = "system-ui" font-size = "13" font-weight = "500" fill = "currentColor" > Parameter Collection< / text >
< text x = "350" y = "350" text-anchor = "middle" font-family = "monospace" font-size = "10" fill = "currentColor" opacity = "0.7" > to → "John"< / text >
< text x = "350" y = "364" text-anchor = "middle" font-family = "monospace" font-size = "10" fill = "currentColor" opacity = "0.7" > subject → "Meeting"< / text >
< text x = "350" y = "378" text-anchor = "middle" font-family = "monospace" font-size = "10" fill = "currentColor" opacity = "0.7" > body → (generated)< / text >
<!-- Arrow down -->
< path d = "M 350 380 L 350 410" stroke = "currentColor" stroke-width = "2" fill = "none" marker-end = "url( #arrow1 )" opacity = "0.6" />
<!-- Execute Tool -->
< rect x = "250" y = "410" width = "200" height = "50" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "8" opacity = "0.8" / >
< text x = "350" y = "430" text-anchor = "middle" font-family = "system-ui" font-size = "13" font-weight = "500" fill = "currentColor" > Execute Tool< / text >
< text x = "350" y = "448" text-anchor = "middle" font-family = "monospace" font-size = "11" fill = "currentColor" opacity = "0.7" > send-email.bas< / text >
<!-- Arrow down -->
< path d = "M 350 460 L 350 490" stroke = "currentColor" stroke-width = "2" fill = "none" marker-end = "url( #arrow1 )" opacity = "0.6" />
<!-- Return Result -->
< rect x = "250" y = "490" width = "200" height = "50" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "8" opacity = "0.8" / >
< text x = "350" y = "510" text-anchor = "middle" font-family = "system-ui" font-size = "13" font-weight = "500" fill = "currentColor" > Return Result< / text >
< text x = "350" y = "528" text-anchor = "middle" font-family = "system-ui" font-size = "11" fill = "currentColor" opacity = "0.7" > "Email sent!"< / text >
<!-- Arrow marker -->
< defs >
< marker id = "arrow1" markerWidth = "10" markerHeight = "10" refX = "9" refY = "5" orient = "auto" >
< polygon points = "0 0, 10 5, 0 10" fill = "currentColor" opacity = "0.6" / >
< / marker >
< / defs >
< / svg >
2025-11-23 17:02:22 -03:00
2025-11-21 12:13:48 -03:00
## Simple Example
Create `get-weather.bas` :
```bas
' This tool gets weather information
' The LLM will call this when users ask about weather
TALK "Let me check the weather for you..."
2025-11-24 13:02:30 -03:00
weather = GET "/api/weather/San Francisco"
2025-11-21 12:13:48 -03:00
TALK "The weather is: " + weather
```
That's a tool! The LLM now knows it can call this when users ask about weather.
## Tool with Parameters
Create `send-email.bas` :
```bas
' Send an email to someone
PARAM to AS STRING
PARAM subject AS STRING
PARAM body AS STRING
2025-11-24 13:02:30 -03:00
GET "/email/send" WITH to, subject, body
2025-11-21 12:13:48 -03:00
TALK "Email sent to " + to
```
The `PARAM` declarations tell the LLM what parameters this tool accepts.
## Making Tools Available
### Method 1: Automatic Discovery (Default)
All `.bas` files in your `.gbdialog/` folder are automatically available.
```
mybot.gbai/
mybot.gbdialog/
start.bas ← Entry point
get-weather.bas ← Tool (auto-discovered)
send-email.bas ← Tool (auto-discovered)
create-task.bas ← Tool (auto-discovered)
```
### Method 2: Manual Registration
In your `start.bas` , explicitly add tools:
```bas
' Register tools for this conversation
2025-11-23 20:12:09 -03:00
USE TOOL "get-weather"
USE TOOL "send-email"
USE TOOL "create-task"
2025-11-21 12:13:48 -03:00
TALK "Hello! I can help with weather, email, and tasks."
```
2025-11-24 13:02:30 -03:00
### Method 3: LLM-Driven Tool Selection
2025-11-21 12:13:48 -03:00
2025-11-24 13:02:30 -03:00
Let the LLM decide which tools to use naturally:
2025-11-21 12:13:48 -03:00
```bas
' In start.bas
2025-11-24 13:02:30 -03:00
' Load all available tools - LLM decides when to use them
USE TOOL "weather"
USE TOOL "email"
USE TOOL "enrollment"
2025-11-21 12:13:48 -03:00
2025-11-24 13:02:30 -03:00
TALK "I can help with various tasks. What do you need?"
' The LLM will automatically call the right tool based on user intent
2025-11-21 12:13:48 -03:00
```
## Tool Format Conversion
BotServer automatically converts your `.bas` tools to:
- **MCP (Model Context Protocol)** format
2025-11-24 13:02:30 -03:00
- **Groq/OpenAI-compatible function calling** format
2025-11-21 12:13:48 -03:00
- Other LLM provider formats
You never write these formats manually - just write `.bas` files!
2025-11-23 17:02:22 -03:00
### Conversion Pipeline
2025-11-24 13:02:30 -03:00
< svg width = "600" height = "400" viewBox = "0 0 600 400" xmlns = "http://www.w3.org/2000/svg" style = "background: transparent;" >
<!-- Title -->
< text x = "300" y = "25" text-anchor = "middle" font-family = "system-ui, -apple-system, sans-serif" font-size = "14" font-weight = "300" fill = "currentColor" opacity = "0.9" > Tool Format Conversion Pipeline< / text >
<!-- Source file -->
< rect x = "220" y = "50" width = "160" height = "35" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "6" opacity = "0.8" / >
< text x = "300" y = "72" text-anchor = "middle" font-family = "monospace" font-size = "12" fill = "currentColor" > send-email.bas< / text >
<!-- Arrow down -->
< path d = "M 300 85 L 300 110" stroke = "currentColor" stroke-width = "2" fill = "none" marker-end = "url( #arrow2 )" opacity = "0.6" />
<!-- BASIC Parser -->
< rect x = "200" y = "110" width = "200" height = "70" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "8" opacity = "0.8" / >
< text x = "300" y = "130" text-anchor = "middle" font-family = "system-ui" font-size = "12" font-weight = "500" fill = "currentColor" > BASIC Parser< / text >
< text x = "300" y = "148" text-anchor = "middle" font-family = "system-ui" font-size = "10" fill = "currentColor" opacity = "0.7" > • Extract PARAM< / text >
< text x = "300" y = "162" text-anchor = "middle" font-family = "system-ui" font-size = "10" fill = "currentColor" opacity = "0.7" > • Parse DESCRIPTION< / text >
< text x = "300" y = "176" text-anchor = "middle" font-family = "system-ui" font-size = "10" fill = "currentColor" opacity = "0.7" > • Analyze code< / text >
<!-- Branching arrows -->
< path d = "M 300 180 L 300 200 L 120 200 L 120 230" stroke = "currentColor" stroke-width = "1.5" fill = "none" marker-end = "url( #arrow2 )" opacity = "0.5" />
< path d = "M 300 180 L 300 200 L 240 200 L 240 230" stroke = "currentColor" stroke-width = "1.5" fill = "none" marker-end = "url( #arrow2 )" opacity = "0.5" />
< path d = "M 300 180 L 300 200 L 360 200 L 360 230" stroke = "currentColor" stroke-width = "1.5" fill = "none" marker-end = "url( #arrow2 )" opacity = "0.5" />
< path d = "M 300 180 L 300 200 L 480 200 L 480 230" stroke = "currentColor" stroke-width = "1.5" fill = "none" marker-end = "url( #arrow2 )" opacity = "0.5" />
<!-- Format boxes -->
< rect x = "70" y = "230" width = "100" height = "40" fill = "none" stroke = "currentColor" stroke-width = "1" rx = "6" opacity = "0.7" / >
< text x = "120" y = "254" text-anchor = "middle" font-family = "system-ui" font-size = "11" fill = "currentColor" > MCP Format< / text >
< rect x = "190" y = "230" width = "100" height = "40" fill = "none" stroke = "currentColor" stroke-width = "1" rx = "6" opacity = "0.7" / >
< text x = "240" y = "254" text-anchor = "middle" font-family = "system-ui" font-size = "11" fill = "currentColor" > OpenAI Function< / text >
< rect x = "310" y = "230" width = "100" height = "40" fill = "none" stroke = "currentColor" stroke-width = "1" rx = "6" opacity = "0.7" / >
< text x = "360" y = "254" text-anchor = "middle" font-family = "system-ui" font-size = "11" fill = "currentColor" > Claude Tool< / text >
< rect x = "430" y = "230" width = "100" height = "40" fill = "none" stroke = "currentColor" stroke-width = "1" rx = "6" opacity = "0.7" / >
< text x = "480" y = "254" text-anchor = "middle" font-family = "system-ui" font-size = "11" fill = "currentColor" > Local Model< / text >
<!-- Converging arrows -->
< path d = "M 120 270 L 120 290 L 300 290 L 300 310" stroke = "currentColor" stroke-width = "1.5" fill = "none" opacity = "0.5" / >
< path d = "M 240 270 L 240 290 L 300 290" stroke = "currentColor" stroke-width = "1.5" fill = "none" opacity = "0.5" / >
< path d = "M 360 270 L 360 290 L 300 290" stroke = "currentColor" stroke-width = "1.5" fill = "none" opacity = "0.5" / >
< path d = "M 480 270 L 480 290 L 300 290 L 300 310" stroke = "currentColor" stroke-width = "1.5" fill = "none" marker-end = "url( #arrow2 )" opacity = "0.5" />
<!-- LLM Provider -->
< rect x = "200" y = "310" width = "200" height = "50" fill = "none" stroke = "currentColor" stroke-width = "1.5" rx = "8" opacity = "0.8" / >
< text x = "300" y = "330" text-anchor = "middle" font-family = "system-ui" font-size = "12" font-weight = "500" fill = "currentColor" > LLM Provider< / text >
< text x = "300" y = "348" text-anchor = "middle" font-family = "system-ui" font-size = "10" fill = "currentColor" opacity = "0.7" > Receives Native Format< / text >
<!-- Arrow marker -->
< defs >
< marker id = "arrow2" markerWidth = "8" markerHeight = "8" refX = "7" refY = "4" orient = "auto" >
< polygon points = "0 0, 8 4, 0 8" fill = "currentColor" opacity = "0.6" / >
< / marker >
< / defs >
< / svg >
2025-11-23 17:02:22 -03:00
2025-11-21 12:13:48 -03:00
## Complete Example
Here's a real tool from the codebase - `enrollment.bas` :
```bas
2025-11-24 13:02:30 -03:00
PARAM name AS string LIKE "Abreu Silva" DESCRIPTION "Required full name of the individual."
PARAM birthday AS date LIKE "23/09/2001" DESCRIPTION "Required birth date of the individual in DD/MM/YYYY format."
PARAM email AS string LIKE "abreu.silva@example .com" DESCRIPTION "Required email address for contact purposes."
PARAM personalid AS integer LIKE "12345678900" DESCRIPTION "Required Personal ID number of the individual (only numbers)."
PARAM address AS string LIKE "Rua das Flores, 123 - SP" DESCRIPTION "Required full address of the individual."
DESCRIPTION "This is the enrollment process, called when the user wants to enroll. Once all information is collected, confirm the details and inform them that their enrollment request has been successfully submitted."
' The actual tool logic is simple
SAVE "enrollments.csv", id, name, birthday, email, personalid, address
TALK "Successfully enrolled " + name + "!"
' That's it! The LLM handles:
' - Natural conversation to collect parameters
' - Validation and error handling
' - Confirming details with the user
' - All the complex interaction flow
2025-11-21 12:13:48 -03:00
```
## That's It!
To create a tool:
1. ✅ Create a `.bas` file
2. ✅ Add `PARAM` declarations if you need parameters
3. ✅ Write your logic using `TALK` , `HEAR` , `CALL` , etc.
4. ✅ Done!
The LLM will automatically:
- Discover your tool
- Understand what it does (from comments and code)
- Know when to call it
- Pass the right parameters
No JSON schemas, no manual registration, no complex configuration. Just write BASIC!
## Best Practices
### 1. Add Comments
The LLM reads your comments to understand the tool:
```bas
' This tool books a meeting room
' It checks availability and sends calendar invites
PARAM room_name AS STRING
PARAM date AS STRING
PARAM attendees AS ARRAY
```
### 2. Validate Parameters
Always validate input:
```bas
IF room_name IS NULL THEN
TALK "Please specify which room you want to book."
RETURN
ENDIF
```
### 3. Provide Feedback
Let users know what's happening:
```bas
TALK "Checking room availability..."
2025-11-24 13:02:30 -03:00
available = GET "/calendar/check" WITH room_name, date
2025-11-21 12:13:48 -03:00
IF available THEN
TALK "Great! Booking the room now..."
2025-11-24 13:02:30 -03:00
GET "/calendar/book" WITH room_name, date, attendees
2025-11-21 12:13:48 -03:00
TALK "Meeting room booked successfully!"
ELSE
TALK "Sorry, that room is not available on " + date
ENDIF
```
## Tool Discovery
The LLM discovers tools by:
1. **Reading `.bas` files** in your `.gbdialog/` folder
2. **Extracting comments** to understand purpose
3. **Parsing PARAM declarations** to understand parameters
4. **Building a function signature** automatically
Example tool discovery from `send-email.bas` :
```
Function: send-email
Description: Send an email to someone
Parameters:
- to: STRING (required)
- subject: STRING (required)
- body: STRING (required)
```
This is generated automatically from your `.bas` file!
## Removing Tools
2025-11-23 20:12:09 -03:00
### Dynamic Tool Management
2025-11-21 12:13:48 -03:00
```bas
' Remove a specific tool
2025-11-23 20:12:09 -03:00
REMOVE TOOL "send-email"
2025-11-21 12:13:48 -03:00
' Clear all tools
2025-11-23 20:12:09 -03:00
CLEAR TOOLS
2025-11-21 12:13:48 -03:00
' List active tools
2025-11-23 20:12:09 -03:00
tools = LIST TOOLS
2025-11-21 12:13:48 -03:00
TALK "Available tools: " + tools
```
## Next Steps
- [PARAM Declaration ](./param-declaration.md ) - Parameter types and validation
- [GET Keyword Integration ](./get-integration.md ) - Using GET to call tools
- [External APIs ](./external-apis.md ) - Calling external services