Welcome back! In Background Lifecycle Management, we built a "security guard" (a timer) that wakes up every 30 seconds. But right now, that guard just wakes up and stares at the wall.
In this chapter, we will give the guard a job. We will learn how to perform Forked Agent Execution.
Imagine a Head Chef (the Main Agent) cooking a very complex 5-course meal. They are deeply focused on chopping onions and reducing wine.
You want to know how the food tastes. You have two options:
In AI terms:
If we interrupt the main agent, we "pollute" its memory with questions like "What are you doing?". By forking, we create a parallel reality, ask a question, and then delete that reality.
We use a function called runForkedAgent. This function takes a snapshot of the current conversation and spins up a temporary process to generate a response.
First, we need to decide what we want to ask the Sous-Chef. We create a message just like a normal user would.
import { createUserMessage } from '../../utils/messages.js'
// We ask the AI to describe its work in present tense
const promptText = `Describe your most recent action in 3-5 words...`
// Wrap it in a message object
const userMessage = createUserMessage({ content: promptText })
Now we call the magic function. We pass it the message and the current "ingredients" (parameters).
import { runForkedAgent } from '../../utils/forkedAgent.js'
// This creates the parallel process
const result = await runForkedAgent({
promptMessages: [userMessage], // The question
cacheSafeParams: forkParams, // The memory snapshot
querySource: 'agent_summary', // Label for logging
})
What just happened?
Let's visualize how the Main Agent and the Forked Agent interact.
Notice that the "Head Chef" (Main Agent) never sees the message "What are you doing?". It only sees the final report (if we choose to show it).
Let's look at how this fits into the runSummary function we created in the previous chapter.
We need to get the current state of the agent. We will go into detail on how to get cleanMessages in Transcript Sanitization, but for now, assume we have the message history.
// agentSummary.ts
// 1. Prepare the parameters (The Ingredients)
const forkParams: CacheSafeParams = {
...baseParams,
forkContextMessages: cleanMessages, // The conversation history
}
Our Sous-Chef is here to observe, not to cook. We don't want the summarizer to accidentally delete a file or run a test. We will learn more about this in Tool Governance (Denial).
// agentSummary.ts
// 2. Define strict rules: NO TOOLS ALLOWED.
const canUseTool = async () => ({
behavior: 'deny' as const,
message: 'No tools needed for summary',
decisionReason: { type: 'other', reason: 'summary only' },
})
Now we put it all together inside our worker loop.
// agentSummary.ts
// 3. Execute the fork
const result = await runForkedAgent({
promptMessages: [
createUserMessage({ content: buildSummaryPrompt(previousSummary) }),
],
cacheSafeParams: forkParams,
canUseTool, // Apply our safety rules
overrides: { abortController: summaryAbortController },
})
The result object contains a list of messages. We need to find the AI's response.
// agentSummary.ts
// 4. Extract the text
for (const msg of result.messages) {
if (msg.type === 'assistant') {
const textBlock = msg.message.content.find(b => b.type === 'text')
if (textBlock) {
const summaryText = textBlock.text.trim()
console.log("Summary:", summaryText)
// Save the summary to the UI...
}
}
}
You might be wondering: "Isn't it expensive to copy the whole conversation every 30 seconds?"
Ideally, yes. However, modern LLM providers use Prompt Caching. Because the "Ingredients" (the history) are exactly the same for the Head Chef and the Sous-Chef, the API doesn't charge us full price to process them again.
To make this work, we have to be very careful not to change settings like maxOutputTokens between the two agents. We will cover this optimization strategy in Prompt Cache Optimization.
You now understand Forked Agent Execution.
However, simply passing the entire raw conversation history to the Sous-Chef can be messy. The raw history might contain huge file dumps or failed tool calls. We need to clean up the ingredients before the Sous-Chef tastes them.
In the next chapter, we will learn how to prepare our data.
Next Chapter: Transcript Sanitization
Generated by Code IQ