Welcome to Chapter 5!
In the previous chapter, Permission & Safety Layer, we established a security guard to decide if a skill is allowed to run.
Now we face a different challenge: Information Overload.
Some skills are messy. Imagine asking the AI to "Write a full web application." That process involves creating files, reading errors, fixing bugs, and running tests. If all that "thinking" happens in the main conversation, your chat history becomes cluttered with hundreds of lines of logs. The AI eventually runs out of memory (Context Window) and forgets what you originally asked!
This brings us to the Forked Execution Strategy.
To understand Forked Execution, imagine you are working at a desk.
Without Forking: You want to build a chair. You bring all the wood, saws, and glue onto your desk. You build it right there. Now your desk is covered in sawdust, you can't find your pen, and you have no room to work on anything else.
With Forking: You want to build a chair. You hire a Contractor. You send them to a separate Workshop.
Your desk remains clean.
Let's say you ask the AI: "Refactor the authentication module."
This is a heavy task.
The Main Agent's memory stays fresh because it never saw the 5,000 tokens of "messy work."
How does SkillTool handle this handoff?
Let's look at SkillTool.ts to see how we implement this "Workshop."
When a skill is defined, it has a property called context. If this is set to 'fork', SkillTool knows not to run it at the desk.
// From SkillTool.ts (inside call function)
// Check if skill should run as a forked sub-agent
if (command?.type === 'prompt' && command.context === 'fork') {
return executeForkedSkill(
command,
commandName,
args,
context,
// ... params ...
)
}
Explanation: This is the traffic controller. If the command says "fork," we route it to executeForkedSkill.
executeForkedSkill)This function creates the "Workshop." It generates a new Agent ID and prepares a fresh environment.
// From SkillTool.ts (inside executeForkedSkill)
async function executeForkedSkill(command, ...): Promise<ToolResult<Output>> {
const agentId = createAgentId() // New Identity
// Prepare the specific prompt for the sub-agent
const { baseAgent, promptMessages } = await prepareForkedCommandContext(
command,
args || '',
context
)
// ... execution logic follows ...
}
Explanation: createAgentId() ensures this new agent is distinct from the main one. prepareForkedCommandContext loads the specific instructions for the skill (e.g., "You are an expert bug fixer...").
Now we run the Sub-Agent using runAgent. This is the same engine that powers the main agent, but it's running in a loop inside our tool.
// From SkillTool.ts
const agentMessages: Message[] = []
// Run the sub-agent
for await (const message of runAgent({
agentDefinition,
promptMessages,
override: { agentId }, // Use the temporary ID
// ... other context ...
})) {
agentMessages.push(message)
// ... logic to show progress on UI ...
}
Explanation:
for await because the agent generates a stream of events (thoughts, tool calls, outputs).agentMessages so the sub-agent has its own short-term memory.Remember Chapter 2: Skill User Interface (UI)? We need to show the user that the "Contractor" is working, even though the "Desk" is quiet.
// From SkillTool.ts
if (hasToolContent && onProgress) {
onProgress({
toolUseID: `skill_${parentMessage.message.id}`,
data: {
type: 'skill_progress',
agentId, // Tie progress to the sub-agent
message: m,
},
})
}
Explanation: This pipes the logs from the "Workshop" (Sub-Agent) to the User's screen, appearing inside the nested box we saw in the UI chapter.
Once the Sub-Agent finishes, we throw away its history (agentMessages) and just return the final result.
// From SkillTool.ts
const resultText = extractResultText(
agentMessages,
'Skill execution completed',
)
// The sub-agent is destroyed (memory released)
return {
data: {
success: true,
status: 'forked', // Tells the UI this was a fork
result: resultText,
},
}
Explanation: The massive list of agentMessages (the sawdust) is discarded. Only resultText (the finished chair) is returned to the Main Agent.
The Forked Execution Strategy is a powerful way to manage complexity.
We have built a system that can run commands (Ch 1), display them (Ch 2), manage prompts (Ch 3), check permissions (Ch 4), and now handle complex tasks in isolation (Ch 5).
But so far, we've assumed all these skills are already installed on your machine. What if you need a skill that lives in the cloud? What if your team shares skills remotely?
Next Chapter: Remote Skill Loading
Generated by Code IQ