Welcome to the AgentTool project tutorial!
Before an AI agent can write code, fix bugs, or answer questions, it needs to know who it is. In this first chapter, we will explore the Agent Definition & Discovery layer.
Imagine you are playing a Tabletop Role-Playing Game (RPG). Before you start the adventure, you need a Character Sheet. This sheet tells you:
In AgentTool, an Agent Definition is exactly like that Character Sheet. It defines the agent's stats before the "adventure" (the coding task) begins. Without this definition, the system is just a blank slate with no personality or permissions.
Throughout this chapter, we will solve a specific problem: We want to create a specialized agent named "BugHunter".
Unlike a general assistant, BugHunter should:
To understand how AgentTool creates agents, we need to understand three core concepts:
The most beginner-friendly way to define an agent in AgentTool is using a Markdown file. The system parses these files to build the "Character Sheet."
To create our "BugHunter", we would create a file named BugHunter.md in our configuration directory.
---
name: BugHunter
description: specialized agent for finding bugs
tools: ['readFile', 'grep']
model: claude-3-5-sonnet
---
You are BugHunter. Your goal is to find errors.
You are skeptical of all code.
Always verify logic before approving.
When AgentTool loads this file, it converts it into a JavaScript object that looks roughly like this:
// Conceptual representation of the loaded agent
const bugHunterAgent = {
agentType: "BugHunter",
whenToUse: "specialized agent for finding bugs",
tools: ["readFile", "grep"],
getSystemPrompt: () => "You are BugHunter..." // The text body
};
This object is now ready to be used by the Agent Execution Runtime.
How does the system turn a text file into code? Let's look at the "Discovery" process.
.md files.--- dashes) and the "Body" (the instructions).activeAgents.
Let's look at the actual code that makes this happen. We will look at builtInAgents.ts and loadAgentsDir.ts.
Some agents are so important they are written directly in TypeScript, not Markdown. These act as the "default" characters.
From builtInAgents.ts:
// simplified from builtInAgents.ts
export function getBuiltInAgents(): AgentDefinition[] {
// Start with the essentials
const agents = [
GENERAL_PURPOSE_AGENT,
STATUSLINE_SETUP_AGENT,
]
// Add specialized agents if enabled
if (areExplorePlanAgentsEnabled()) {
agents.push(EXPLORE_AGENT, PLAN_AGENT)
}
return agents
}
Explanation: This function simply returns an array of pre-configured objects. Notice it checks flags (like areExplorePlanAgentsEnabled) to see if experimental agents (like the ones we will see in Specialized Built-in Agents) should be included.
This is where the magic happens for our custom "BugHunter". The system reads the file and splits it into metadata and prompt.
From loadAgentsDir.ts:
// simplified from loadAgentsDir.ts
export function parseAgentFromMarkdown(
frontmatter: any,
content: string
): CustomAgentDefinition | null {
const agentType = frontmatter['name'] // e.g., "BugHunter"
const description = frontmatter['description']
// If no name, it's not a valid agent file
if (!agentType) return null
// Create the agent object
return {
agentType: agentType,
whenToUse: description,
tools: frontmatter['tools'], // e.g., ['readFile']
getSystemPrompt: () => content.trim() // The text body
}
}
Explanation:
frontmatter (parsed YAML) and the content (the text body).name to use as the ID (agentType).tools directly from the config.getSystemPrompt that returns the main text. This prompt tells the AI how to behave (discussed more in Dynamic Prompt Engineering).Finally, we need to combine the built-ins with the custom markdown agents.
// simplified from loadAgentsDir.ts
export const getAgentDefinitionsWithOverrides = async (cwd) => {
// 1. Load custom files from disk
const markdownFiles = await loadMarkdownFilesForSubdir('agents', cwd)
// 2. Convert files to Agent objects
const customAgents = markdownFiles.map(file =>
parseAgentFromMarkdown(file.frontmatter, file.content)
)
// 3. Get built-in agents
const builtInAgents = getBuiltInAgents()
// 4. Combine them
return {
activeAgents: [...builtInAgents, ...customAgents]
}
}
Explanation: This function acts as the coordinator. It calls the file loader, parses the results, grabs the built-ins, and merges them into one final list of activeAgents.
In this chapter, we learned that an Agent Definition is simply a configuration that gives the AI a name, a set of tools, and a personality.
Now that the system has discovered who the agents are, let's take a closer look at the default characters provided by the system.
Next Chapter: Specialized Built-in Agents
Generated by Code IQ