Welcome to the GlobTool project!
In this tutorial series, we will build a powerful utility that allows an AI system to search for files on your computer. If you've ever used a terminal command like ls *.txt or searched for a file in your code editor, you know how useful this is. We are giving that superpower to an AI.
Imagine an AI as a very smart assistant sitting in a windowless room. It knows a lot about coding, but it cannot see your computer's hard drive. It's blind to your files.
To fix this, we need to give the AI a Tool.
A Tool is like a "skill card" or a plugin. It tells the AI:
In this chapter, we will look at the Tool Definition, which is the blueprint that holds all these pieces together.
GlobTool
In our project, the main object is called GlobTool. It acts as a container. Think of it as a form you fill out to register a new employee. You need to fill in their name, their job title, and the specific tasks they are allowed to perform.
We create this definition using a helper function called buildTool.
First, we need to give our tool an identity so the system knows when to use it.
// From GlobTool.ts
import { buildTool } from '../../Tool.js'
import { GLOB_TOOL_NAME, DESCRIPTION } from './prompt.js'
export const GlobTool = buildTool({
name: GLOB_TOOL_NAME, // 'Glob'
searchHint: 'find files by name pattern or wildcard',
async description() {
return DESCRIPTION
},
// ... continued below
Explanation:
name: This is the unique ID of the tool.searchHint: A short tagline humans see in the UI.description: A longer explanation for the AI. It tells the AI why it should use this tool (e.g., "Use this to find files using patterns like *.ts").The AI needs to know strictly what data to send to the tool (Inputs) and what data to expect back (Outputs).
// ... inside buildTool({
get inputSchema() {
return inputSchema() // Detailed in Chapter 2
},
get outputSchema() {
return outputSchema() // Detailed in Chapter 2
},
Explanation: We don't write the logic here directly; we point to schemas. This ensures the AI doesn't try to send us random text when we need a specific file pattern.
We need to tell the system how "dangerous" or "heavy" this tool is.
// ... inside buildTool({
isConcurrencySafe() {
return true // Can run multiple times at once
},
isReadOnly() {
return true // Does NOT modify files
},
Explanation:
isReadOnly: This is crucial for safety. Since GlobTool only finds files and doesn't delete or write them, we mark it as read-only. This helps the system trust the tool.Finally, the definition includes the actual code that runs when the tool is called.
// ... inside buildTool({
async call(input, context) {
// 1. Get the pattern from input
// 2. Search the filesystem
// 3. Return the list of files
return { data: output }
}
}) // End of buildTool
Explanation:
The call function is the engine. When the AI decides "I want to search for files," this function executes.
When the system starts up, it reads this GlobTool definition. Here is the flow of events when a user interacts with it:
GlobTool.description in our definition to see if this tool can help.
Let's look at a slightly larger snippet from GlobTool.ts to see how the definition aggregates UI logic alongside business logic.
// GlobTool.ts
export const GlobTool = buildTool({
name: GLOB_TOOL_NAME,
// UI Helpers
userFacingName,
renderToolUseMessage,
// Logic Helpers
getPath({ path }): string {
return path ? expandPath(path) : getCwd()
},
// ... rest of configuration
})
Explanation: The definition is a "one-stop-shop."
renderToolUseMessage controls how the tool looks in the chat window (see UI Rendering).getPath is a helper function specific to this tool to figure out which folder to search in.The Tool Definition is the wrapper that turns raw code into a capability the AI can understand. It bundles:
call function)Now that we have our container, we need to be very specific about what data we allow inside it.
Generated by Code IQ