Welcome to the fourth chapter of the Agents project tutorial!
In the previous chapter, File Persistence Layer, we built the backend logic to save our agents to disk. However, currently, the only way to create an agent is to manually write a Markdown file or code a JavaScript object by hand. This is error-prone and intimidating for new users.
Imagine filing your taxes. You could read the raw tax code and write your submission on a blank piece of paper. But it is much easier to use software that asks you one simple question at a time: "What is your name?", "How much did you earn?", "Do you have children?".
We need a Creation Wizardโa guided interface that breaks down the complex task of defining an agent into small, manageable steps.
code-reviewer
In this chapter, we will build a UI that asks the user the following questions in order, to recreate our code-reviewer agent:
code-reviewer)You are an expert...)readFile)The Wizard is built on a "State Machine" pattern. Here are the key components:
wizardData): A temporary data bucket that holds the answers collected so far. It starts empty and fills up as the user moves from step to step.goNext() (validate and move forward) and goBack() (return to correct mistake).Let's visualize how the Wizard manages data. It acts like a conveyor belt.
Let's look at how we implement this structure in React.
CreateAgentWizard.tsx)This component acts as the manager. It defines the order of the steps. It doesn't handle the logic of each step; it just lists them.
// From CreateAgentWizard.tsx
export function CreateAgentWizard({ onCancel }) {
// Define the sequence of screens
const steps = [
TypeStep, // Step 1: Ask for Name
PromptStep, // Step 2: Ask for System Prompt
ToolsStep, // Step 3: Ask for Tools
ConfirmStepWrapper // Step 4: Summary & Save
];
// The WizardProvider manages the state between these steps
return (
<WizardProvider
steps={steps}
onCancel={onCancel}
/>
);
}
Explanation: We create an array called steps. The WizardProvider is a special component that renders the first step, then waits for a signal to render the second, and so on.
TypeStep.tsx)How does an individual screen work? Let's look at the first step where the user enters the name.
It needs to:
// From TypeStep.tsx
export function TypeStep() {
// 1. Get wizard controls
const { goNext, updateWizardData } = useWizard();
const [input, setInput] = useState("");
const handleSubmit = () => {
// 2. Validate
if (input.includes(" ")) return setError("No spaces!");
// 3. Save to Accumulator
updateWizardData({ agentType: input });
// 4. Move to next screen
goNext();
};
return <TextInput onSubmit={handleSubmit} />;
}
Explanation: The useWizard hook gives us access to the "Brain" of the wizard. updateWizardData merges our new input into the global data bucket. goNext tells the Orchestrator to switch to the next component in the list.
ConfirmStepWrapper.tsx)The final step is special. It doesn't ask a question; it displays the summary and calls the backend to save the file.
// From ConfirmStepWrapper.tsx
export function ConfirmStepWrapper() {
const { wizardData } = useWizard(); // Access the full bucket
const handleSave = async () => {
// Call the logic we built in Chapter 3
await saveAgentToFile(
wizardData.agentType,
wizardData.systemPrompt,
wizardData.tools
);
};
// Render the summary view
return <ConfirmStep data={wizardData} onSave={handleSave} />;
}
Explanation: This component pulls all the data collected in previous steps (wizardData). When the user confirms, it calls saveAgentToFile, which we learned about in the File Persistence Layer chapter.
By combining these components, we have solved our problem:
CreateAgentWizard loads TypeStep.TypeStep validates and saves to wizardData.PromptStep.wizardData.ConfirmStepWrapper.code-reviewer.md is created on disk.
In this chapter, we learned how to build a Creation Wizard. We treated the agent creation process as a State Machine, collecting data piece-by-piece in a wizardData bucket before saving it. This ensures that we never create invalid or incomplete agents.
Now that we have an agent with a list of tools (like readFile or runCommand), how does the system actually know which tool to pick during a conversation?
Next Chapter: Tool Selection System
Generated by Code IQ