In the [previous chapter](02_input_handling__textbuffer_editor_.md), we saw how Codex captures your commands and messages using a neat multi-line input editor. But once you hit Enter, where does that input *go*? What part of Codex actually understands your request, talks to the AI, and makes things happen?
Meet the **Agent Loop**, the heart and brain of the Codex CLI.
## What's the Big Idea? Like a Helpful Assistant
Imagine you have a very capable personal assistant. You give them a task, like "Find the latest sales report, summarize it, and email it to the team." Your assistant doesn't just magically do it all at once. They follow a process:
1.**Understand the Request:** Listen carefully to what you asked for.
2.**Gather Information:** Look for the sales report file.
3.**Perform Actions:** Read the report, write a summary.
4.**Ask for Confirmation (if needed):** "I've drafted the summary and email. Should I send it now?"
5.**Complete the Task:** Send the email after getting your 'yes'.
6.**Report Back:** Let you know the email has been sent.
The **Agent Loop** in Codex acts much like this assistant. It's the central piece of logic that manages the entire conversation and workflow between you and the AI model (like OpenAI's GPT-4).
Let's take our simple example: You type `codex "write a python script that prints hello world and run it"`.
The Agent Loop is responsible for:
1. Taking your input ("write a python script...").
2. Sending this request to the powerful AI model via the OpenAI API.
3. Getting the AI's response, which might include:
* Text: "Okay, here's the script..."
* A request to perform an action (a "function call"): "I need to run this command: `python -c 'print(\"hello world\")'`"
4. Showing you the text part of the response in the [Terminal UI](01_terminal_ui__ink_components_.md).
3.**Response Processing:** Receives the AI's response. This could be simple text, or it could include a request to use a tool (like running a shell command). This is covered more in [Response & Tool Call Handling](05_response___tool_call_handling.md).
* Package the tool's result (e.g., command output) to send back to the AI in the next step.
5.**Update State:** Adds the AI's message and any tool results to the conversation history. Shows updates in the UI.
6.**Loop:** If the task isn't finished (e.g., because a tool was used and the AI needs to react to the result), it sends the updated conversation back to the AI (Step 2). If the task *is* finished, it waits for your next input.
## Using the Agent Loop (From the UI's Perspective)
You don't directly interact with the `AgentLoop` class code when *using* Codex. Instead, the main UI component (`TerminalChat` in `terminal-chat.tsx`) creates and manages an `AgentLoop` instance.
Think of the UI component holding the "remote control" for the Agent Loop assistant.
return()=>agentRef.current?.terminate();// Clean up when done
},[config,approvalPolicy/* ... */]);
// --- Function to send user input to the assistant ---
constsubmitInputToAgent=(userInput)=>{
if(agentRef.current){
// Tell the assistant to process this input
agentRef.current.run([userInput/* ... */]);
}
};
// --- UI Rendering ---
return(
<Box>
{/* Display 'items' using TerminalMessageHistory */}
{/* Display input box (TerminalChatInput) or confirmationPrompt */}
{/* Pass `submitInputToAgent` to the input box */}
{/* Pass function to handle confirmation decision */}
</Box>
);
}
```
***Initialization:** The UI creates an `AgentLoop`, giving it the necessary configuration ([Configuration Management](07_configuration_management.md)) and crucial **callback functions**. These callbacks are how the Agent Loop communicates back to the UI:
*`onItem`: "Here's a new message (from user, AI, or tool) to display."
*`onLoading`: "I'm starting/stopping my work."
*`getCommandConfirmation`: "I need to run this command. Please ask the user and tell me their decision."
***Running:** When you submit input via the `<TerminalChatInput>`, the UI calls the `agentRef.current.run(...)` method, handing off your request to the Agent Loop.
***Updates:** The Agent Loop does its work, calling the `onItem` and `onLoading` callbacks whenever something changes. The UI listens to these callbacks and updates the display accordingly (setting state variables like `items` and `loading`, which causes React to re-render).
***Confirmation:** If the Agent Loop needs approval, it calls `getCommandConfirmation`. The UI pauses, shows the command review prompt, waits for your decision, and then returns the decision back to the Agent Loop, which then proceeds or stops based on your choice.
## Under the Hood: A Step-by-Step Flow
Let's trace our "hello world" example again, focusing on the interactions:
```mermaid
sequenceDiagram
participant User
participant InkUI as Terminal UI (Ink)
participant AgentLoop
participant OpenAI
participant CmdExec as Command Execution
User->>InkUI: Types "write & run hello world", presses Enter
This diagram shows the back-and-forth orchestration performed by the Agent Loop, coordinating between the UI, the AI model, and the command execution system.
## Inside `agent-loop.ts`
The core logic lives in `codex-cli/src/utils/agent/agent-loop.ts`. Let's peek at a *very* simplified structure:
return[outputItem];// This goes into `turnInput` for the next loop
}
// ... other methods like cancel(), terminate() ...
}
```
***Constructor:** Sets up the connection to OpenAI and stores the configuration and callbacks passed in by the UI.
***`run()`:** This is the main engine.
* It signals loading starts (`onLoading(true)`).
* It enters a `while` loop that continues as long as there's something to send to the AI (initially the user's message, later potentially the results from tools).
* Inside the loop, it calls `this.oai.responses.create()` to talk to the AI model, sending the current conversation turn.
* It processes the `stream` of events coming back from the AI.
* For each piece of content (`response.output_item.done`), it calls `onItem` to show it in the UI.
* When the AI's turn is complete (`response.completed`), it checks if the AI asked to use any tools (`function_call`).
* If a tool call is found, it calls `handleFunctionCall`.
***`handleFunctionCall()`:**
* Parses the details of the tool request (e.g., the command arguments).
* Uses `handleExecCommand` (which contains logic related to [Approval Policy](04_approval_policy___security.md) and [Command Execution](06_command_execution___sandboxing.md)) to potentially run the command, using the `getCommandConfirmation` callback if needed.
* Formats the result of the tool execution (e.g., command output) into a specific `function_call_output` message.
* Returns this output message. The `run` method adds this to `turnInput`, so the *next* iteration of the `while` loop will send this result back to the AI, letting it know what happened.
***Finally:** Once the `while` loop finishes (meaning the AI didn't request any more tools in its last response), it signals loading is done (`onLoading(false)`).
This loop ensures that the conversation flows logically, handling text, tool requests, user approvals, and tool results in a structured way.
The Agent Loop is the central orchestrator within Codex. It acts like a diligent assistant, taking your requests, interacting with the powerful AI model, managing tools like shell commands, ensuring safety through approvals, and keeping the conversation state updated. It connects the [Terminal UI](01_terminal_ui__ink_components_.md) where you interact, the [Input Handling](02_input_handling__textbuffer_editor_.md) that captures your text, the AI model that provides intelligence, and the systems that actually execute actions ([Command Execution & Sandboxing](06_command_execution___sandboxing.md)).
Understanding the Agent Loop helps you see how Codex manages the complex back-and-forth required to turn your natural language requests into concrete actions. But when the Agent Loop wants to run a command suggested by the AI, how does Codex decide whether to ask for your permission first? That crucial safety mechanism is the topic of our next chapter.