This feature is currently only supported with Mastra backends. If interested
in support for other providers, please reach out or join our Discord. For
example backend code in Mastra, reach out as well!
How it works
This system uses Cedar’s existing architecture patterns:- State Management: Stores workflow data in Cedar state (learn more about this concept)
- Response Processors: Handles the suspend/resume logic (learn more about this concept)
- Message Renderers: Creates the interactive UI (learn more about this concept)
- Input subscriptions (optionally): Sends workflow states to the backend with future messages (learn more about this concept).
- Backend suspends workflow - Your agent reaches a point requiring user input and returns a
humanInTheLoopresponse - Cedar processes suspension - The response processor stores workflow data and creates an interactive message
- User interacts - The UI displays workflow information with customizable UI that allows the user to provide the necessary data/input
- Workflow resumes - User input is sent to the backend to continue the suspended workflow
Backend Response Handling
Response Type
Your backend should return responses withtype: "humanInTheLoop" when a workflow needs to be suspended:
Example Backend Response
Built-in Response Processor
Cedar automatically processeshumanInTheLoop responses with the built-in processor:
packages/cedar-os/src/store/agentConnection/responseProcessors/humanInTheLoopResponseProcessor.ts
Storing workflow suspension data on the frontend
The preconfigured response processor stores all workflow suspension data in a single state key called'humanInTheLoop'. Each workflow is stored by its runId with complete lifecycle information:
Custom State Setters
The response processor also registers custom setters on thehumanInTheLoop state that handle workflow operations:
resume: Resumes a suspended workflow by sending the resume request to the backend and updating the workflow statecancel: Cancels a suspended workflow and updates the state to cancelled
resumeCallback and cancelCallback functions that get passed to message renderers. You can also access them directly if you want to resume a workflow from somewhere else in the UI:
Message Rendering and User Input
Message Type
When a workflow is suspended, the built in response processor creates messages using theHumanInTheLoopMessage type:
packages/cedar-os/src/store/messages/renderers/HumanInTheLoopRenderer.tsx
Backend Integration
Required Routes
Your backend must implement a resume endpoint to handle workflow continuation:Resume Endpoint (POST /chat/resume)
Default endpoint:/chat/resume or /chat/resume/stream (configurable via resumePath in provider config)
Request format:
Provider Configuration
Configure the resume endpoint in your Cedar provider config:Nested Workflows
Support complex workflows with hierarchical step paths:Advanced Usage
State Subscriptions
Extract workflow states directly from Cedar state to display in the frontend:Cross-Message Workflow Data
If you want the user to be able to resume a workflow by just typing a response, you should subscribe the storedhumanInTheLoop state to the additionalContext. This means that at the next call to the backend, we will send that data and you can process it as you wish to implement custom resume logic.
Complete Example: Approval Workflow
Here’s a comprehensive example showing an approval workflow implementation:1. Provider Configuration
2. Custom Typed Renderer
3. Register Custom Renderer
4. Backend Implementation
Your backend should return suspension responses like:5. Complete User Flow
- User: “Please process the payment to vendor@example.com for $10,000”
- Backend: Returns suspension response above
- Cedar: Processes response, stores state, creates interactive message
- UI: Shows approval form with transaction details
- User: Reviews details, adds feedback, clicks “Approve”
- Cedar: Calls resume endpoint with approval data
- Backend: Continues workflow, processes payment, returns completion
- UI: Shows success message with approval details

