A deep dive into Cedar-OS internal architecture
AgentConnectionSlice
- Handles all LLM communication and response processing
StateSlice
- Allows agents to read and write to local react states
AgentInputContextSlice
- Gathers and formats context (such as state) for AI consumption
MessagesSlice
- Stores and renders chat messages
addMessage
from messagesSlice
to persist and add the user message to chat history.
3. Let agent read state through stateSlice
But now, how does the agent know what it’s supposed to write a response to? Our next step is to allow the agent to read from local states.
To do this, we have stateSlice
which provides functions like registerState
. This lets us register a state into a central place no matter where and how the local states are distributed.
4. agentInputContext
agentInputContext handles the context that we pass into the agent. It stringifies the context & editor through stringifyInputContext
and stringifyAdditionalContext
and helps generally manage the context we’re giving the agent.
For example, it allows users to use @notation to mention a specific email or user through useStateBasedMentionProvider()
.
5. callLLM()
Now that we’ve pulled all the necessary context for the agent to execute its task effectively, we can pass it all in through the agentConnectionSlice
which calls the LLM.
handleLLMResponse
When the LLM returns a response, it gets passed to handleLLMResponse()
which processes an array of items that can be either strings (text content) or structured objects.
2. Type-based processing with response processors
The system uses a switch-like mechanism through processStructuredResponse()
that looks at the type
field of structured responses and routes them to registered response processors:
message
type - Handled by messageResponseProcessor
, converts backend message format to chat messagesaction
type - Handled by actionResponseProcessor
, executes state mutations through executeCustomSetter()
progress_update
type - Shows loading states and progress indicatorsmessagesSlice
Text content and processed messages get added to the chat history via addMessage()
in the messagesSlice
. This handles the display and persistence of conversation history.
4. State mutations through registered setters
For action
type responses, the system calls executeCustomSetter()
which uses the parameters from registerState()
to execute the appropriate custom setter function, allowing the AI to modify application state based on the registered schema and available setters.