Runtime Architecture
If you draw the Coding Agent runtime only as "CLI calls CodingAgent, which then calls the model," you will miss too many of the layers that actually shape behavior.
Looking at the current source, a complete run goes through at least 5 layers:
- factory assembly layer
- coding agent build layer
- session execution layer
- host/runtime interaction layer
- MCP external tool runtime layer
The goal of this page is not to list module names, but to make clear: what state each layer actually holds, what behavior it decides, and what its boundaries with adjacent layers are.
1. Start with the outermost assembly entry point
The real preparation entry point for CLI / TUI / ACP today is:
ai4j-cli/.../DefaultCodingCliAgentFactory.java
The main flow of prepare(...) is straightforward:
resolveProtocol(options)createModelClient(options, protocol)prepareMcpRuntime(options, pausedServers, terminal)buildAgent(options, terminal, interactionState, modelClient, mcpRuntimeManager)- return
PreparedCodingAgent
This means the runtime does not "grow automatically" inside CodingAgent; instead, the CLI factory first assembles:
- protocol
- provider
- workspace
- MCP
- approval
- stream options
into a runnable environment.
2. What the factory layer actually decides
DefaultCodingCliAgentFactory currently decides at least 6 things:
- whether to use
ChatModelClientorResponsesModelClient - how the current provider / baseUrl / apiKey is written into
Configuration - the
CliWorkspaceConfigcorresponding to the current workspace - whether to initialize
CliMcpRuntimeManager - how the approval decorator is attached
- whether to inject experimental subagent / delivery team
So the factory layer is not "a tiny object creator," but the first entry point for runtime policy.
Once you switch:
- provider
- protocol
- model
- the visible MCP set
- approval mode
it is rarely a single field change — most of the time you are reassembling the entire runtime.
3. CodingAgentBuilder is the real fork point that turns a generic Agent into a Coding Agent
Moving inward from the factory, the next critical layer is:
ai4j-coding/.../CodingAgentBuilder.java
This builder currently also takes care of:
WorkspaceContextresolutionCodingSkillDiscovery.enrich(...)CodingAgentOptions/AgentOptionsnormalization- built-in coding tool registry creation
- built-in tool executor creation
DefaultCodingRuntimecreation- custom tool merging
- subagent / handoff merging
- workspace system prompt injection
Only then does it hand all of this off to:
AgentBuilder
So the architecturally accurate description is:
Coding Agent = generic Agent core + coding runtime assembly layer.
4. What the Coding Agent core layer actually holds
If you only look at CodingAgentBuilder.build(), the objects this layer truly gathers are:
AgentModelClientWorkspaceContextCodingAgentOptionsAgentToolRegistryToolExecutorCodingRuntimeSubAgentRegistryHandoffPolicy
The key state this adds over an ordinary Agent is:
- workspace semantics
- coding-specific tools
- coding-specific runtime
- child-session / delegation capability
In other words, the Coding Agent itself is no longer a simple "single model + single tool table" executor.
5. Why DefaultCodingRuntime is a layer of its own
Many people on first read mistake CodingRuntime for "the host interface layer."
It is not.
ai4j-coding/.../runtime/DefaultCodingRuntime.java
Today it is more of a coding work orchestration layer. It owns:
delegate(...)- background task scheduling
- child session creation
CodingTasklifecycleCodingSessionLinkpersistenceCodingToolPolicyResolverapplication- runtime listeners
That is, what this layer cares about is:
- how tasks are split off
- how child sessions inherit the parent context
- which tools a child agent is allowed to use
- how foreground and background tasks are tracked
It is not a UI runtime, nor a model runtime — it is a coding work runtime.
6. The session execution layer and the host runtime are not the same layer
This is also the spot where the current docs are easiest to misread.
Session execution layer
The core objects are:
CodingSessionCodingAgentLoopController
They are responsible for:
- how a single prompt becomes a multi-turn outer loop
- auto-continue and stop
- compact / checkpoint
- process snapshots
- state export / restore
Host runtime
The core objects are:
CodingCliSessionRunnerHeadlessCodingSessionRuntime
They are responsible for:
- how user input enters the session
- how events are surfaced to CLI/TUI/ACP
- how to persist and replay
- how approval interactions communicate with the host
So:
CodingSessionis the execution session coreCodingCliSessionRunner/HeadlessCodingSessionRuntimeare the host drivers
The two are not one layer.
7. Where DefaultCodingSessionManager sits in the architecture
DefaultCodingSessionManager is also frequently miscategorized into the host UI layer.
In fact it is more of a session lifecycle service.
It handles:
createresumeforksaveloadlistappendEventlistEvents
and also processes:
- workspace match validation
rootSessionId / parentSessionIdSESSION_CREATED / RESUMED / FORKED / SAVEDevents
So the correct positioning of this layer is:
- not responsible for reasoning
- not responsible for UI
- responsible for session lifecycle and ledger
8. Why the CLI/TUI path and the ACP/headless path are split
CLI / TUI
Primarily driven by:
CodingCliSessionRunner
It leans more toward an interactive controller, with responsibilities including:
- receiving user input and slash commands
- managing the current
ManagedCodingSession - handling session switching and runtime rebuilds
- driving terminal/TUI rendering
ACP / headless
Primarily driven by:
HeadlessCodingSessionRuntimeAcpJsonRpcServer
HeadlessCodingSessionRuntime turns a single prompt into structured events such as:
USER_MESSAGEASSISTANT_MESSAGETOOL_CALLTOOL_RESULTAUTO_CONTINUE / AUTO_STOP / BLOCKEDCOMPACTERROR
AcpJsonRpcServer then sends these events to the host over the protocol.
So the ACP path is not about the terminal experience — it is about a protocolized event stream.
9. Why the MCP runtime is a live runtime layer of its own
The MCP layer today is not "read a config file and splice together a few tool definitions."
CliMcpRuntimeManager
On startup it will:
- parse the resolved config
- build a
CliMcpConnectionHandleper server - connect
listTools()- validate tool-name conflicts
- convert to OpenAI-style
Tool - generate the
toolRegistryandtoolExecutor - maintain
connected / disabled / paused / error / missingstate
In particular, it explicitly guards against conflicts with built-in tools:
bashread_filewrite_fileapply_patch
This shows that MCP in the Coding Agent is not a static extension point, but a connectable, pausable, fallible, rebuildable runtime layer.
10. Which layer /experimental affects
This is another spot that is easy to get wrong.
/experimental currently does not affect:
- the model client
- the session manager
- the TUI renderer
What it affects is what DefaultCodingCliAgentFactory attaches while building the agent:
- whether to attach the experimental subagent
- whether to attach the delivery team surface
In other words, it changes the callable agent surface that the current session exposes to the model — not the underlying runtime semantics as a whole.
11. Which layer approval interception belongs in
The current approval chain is:
DefaultCodingCliAgentFactory->CodingAgentOptions.toolExecutorDecorator->CodingAgentBuilder.createBuiltInToolExecutor(...)->CliToolApprovalDecorator/AcpToolApprovalDecorator
This shows that approval belongs in:
- the tool execution entry layer
and not in:
- the shell layer
- the session manager layer
- the UI renderer layer
Then the outer loop turns an approval rejection into BLOCKED_BY_APPROVAL.
This is a very clean layering:
- the decorator decides "can it execute"
- the loop decides "how the session stops after a rejection"
12. Why the runtime often needs to be "rebuilt"
In the Coding Agent, the following changes tend to trigger a runtime rebuild:
- provider/profile changes
- protocol changes
- model changes
- MCP server state changes
- workspace experimental setting changes
The reason is not UI caprice — these changes directly affect:
AgentModelClienttoolRegistrytoolExecutor- the approval decorator
- the available subagent surface
So many configuration changes are, in essence, execution-environment changes.
13. From an extension standpoint, which layer to change first
If your requirement is:
-
change provider / protocol wiring start with
DefaultCodingCliAgentFactory -
change delegation / child session / background task semantics start with
DefaultCodingRuntime -
change session persistence and replay start with
DefaultCodingSessionManager/SessionEventStore -
change host streaming event behavior start with
HeadlessCodingSessionRuntimeorCodingCliSessionRunner -
change MCP integration and conflict validation start with
CliMcpRuntimeManager -
change approval policy start with
ToolExecutorDecoratorandCliToolApprovalDecorator
Editing by layer this way is far more stable than diving into the CodingAgent main class and hacking at random.
14. The conclusion worth remembering from this page
The AI4J Coding Agent runtime today is not a single-layer system, but a clear, layered assembly chain:
- the factory layer decides provider, protocol, workspace, MCP, approval, and the experimental surface
- the builder layer assembles these into a coding-specific agent core
- the runtime layer owns delegation and child work sessions
- the session layer owns the outer loop, compact, processes, and state
- the host layer owns CLI/TUI/ACP interaction and event surfacing
- the MCP runtime layer owns external tool connection and conflict governance
Once you see this chain clearly, the next time you change a feature you will know which layer to edit — rather than dumping everything into the single CodingAgent class.
15. Further reading
- Sessions, streaming, and processes
- Tools and the approval mechanism
- Compact and checkpoint mechanism
- MCP and ACP
→ API Javadoc: CodingAgentBuilder (the ai4j-coding module; the core class of the assembly fork point in §3 of this page)