Welcome to the seventh and final chapter of the Agents project tutorial!
In the previous chapter, AI Generator Service, we learned how to conjure up a fully functional agent using just a simple sentence. We asked the AI to build a test-runner, and it did.
But what happens if you change your mind? What if you want your test-runner to be blue instead of green? Or perhaps you want to upgrade its "brain" to a smarter model?
Imagine you just built a house. If you decide you want to paint the kitchen yellow, you don't tear down the entire house and build a new one. You simply renovate the kitchen.
In software, without an Editor, changing an agent means either:
.md file and manually typing changes (riskyβyou might break the syntax).We need a safe "Settings Screen" that allows us to tweak specific attributes of an existing agent without touching the dangerous parts.
test-runner
In this chapter, we will build the Agent Editor. We will take the test-runner agent we generated previously and:
The Agent Editor is built like a "mini-application" inside our main app. It relies on:
Let's look at how the Editor handles the flow of a user modifying an agent.
The editor is a loop. It shows a menu, waits for you to pick a setting, lets you change it, and then saves.
The logic for this system is primarily in AgentEditor.tsx. Let's break down how it manages these screens.
editMode)Just like our main Menu Controller, the Editor needs to know which screen to show.
// From AgentEditor.tsx
type EditMode = 'menu' | 'edit-tools' | 'edit-color' | 'edit-model';
export function AgentEditor({ agent }) {
// 1. Track which sub-screen we are on
const [editMode, setEditMode] = useState<EditMode>('menu');
// 2. Decide what to render
switch (editMode) {
case 'menu': return renderMenu();
case 'edit-tools': return <ToolSelector ... />;
case 'edit-color': return <ColorPicker ... />;
case 'edit-model': return <ModelSelector ... />;
}
}
Explanation: This switch statement is the heart of the editor. By changing the editMode variable, we can swap the entire screen from a menu to a color picker instantly.
When editMode is 'menu', we display a list of actions.
// From AgentEditor.tsx
const menuItems = [
{
label: 'Open in editor',
action: handleOpenInEditor
},
{
label: 'Edit tools',
action: () => setEditMode('edit-tools')
},
{
label: 'Edit color',
action: () => setEditMode('edit-color')
}
];
Explanation: This simple array defines what the user sees. If they click "Edit color", we run the function that changes the state to edit-color, triggering the switch statement above.
ColorPicker.tsx)Let's look at one of the sub-screens. This component allows the user to visually scroll through colors.
// From ColorPicker.tsx
export function ColorPicker({ onConfirm }) {
// Track the user's selection
const [selectedIndex, setSelectedIndex] = useState(0);
// When user presses Enter
const handleEnter = () => {
const selected = COLOR_OPTIONS[selectedIndex];
onConfirm(selected); // Send choice back to Parent
};
return <Box>{/* Render list of colors */}</Box>;
}
Explanation: This component is simple. It lets the user pick a value and then calls onConfirm. It doesn't know how to save the file; it just reports the choice back to the AgentEditor.
When a sub-screen returns a value, the AgentEditor must save it to the disk. We reuse the concepts from the File Persistence Layer.
// From AgentEditor.tsx
const handleSave = async (changes) => {
const { color, model, tools } = changes;
// 1. Check if anything actually changed
if (color === agent.color && !model && !tools) return;
// 2. Update the file on disk
await updateAgentFile(
agent,
agent.whenToUse,
tools ?? agent.tools, // Use new tools OR keep old ones
agent.getSystemPrompt(),
color ?? agent.color // Use new color OR keep old one
);
};
Explanation:
updateAgentFile (a helper function similar to saveAgentToFile).?? operator means: "If the user provided a new value, use it. Otherwise, keep the existing value from the agent."
Let's trace our goal of updating the test-runner:
test-runner and chooses "Edit". AgentEditor opens in menu mode.editMode becomes edit-color.ColorPicker appears. User highlights "Blue" and presses Enter.ColorPicker calls onConfirm('blue').handleSave is called with { color: 'blue' }.test-runner.md file, updates the metadata header to color: blue, and writes it back to disk.editMode goes back to menu, showing the success message.Congratulations! You have completed the Agents project tutorial.
We have built a complete lifecycle management system for AI agents:
You now possess a fully modular system where AI agents can be created, managed, and persisted. You can now focus on expanding the capabilities of your agents by adding new tools or refining their system prompts!
Generated by Code IQ