Chat API Endpoint
Relevant source files
The following files were used as context for generating this wiki page:
The Chat API Endpoint is a critical server-side component within the Bolt architecture that handles asynchronous communication between the client interface and the Large Language Model (LLM). It serves as the primary gateway for processing user prompts, managing streaming responses, and facilitating "message continuation" when token limits are reached.
This endpoint is implemented as a Remix Action Function, designed to run in a Cloudflare Workers environment. It integrates tightly with the frontend's chat state management and the persistence layer, ensuring that every interaction is recorded and that the LLM has access to the current state of the project files via unified diffs.
Architecture and Data Flow
The Chat API follows a request-response streaming model. When a user sends a message, the client-side useChat hook targets the /api/chat route. The server processes the conversation history and returns a readable stream that the client consumes in real-time.
Request Handling
The endpoint extracts a list of messages from the JSON body of the request. These messages typically include the conversation history and the latest user prompt, which may be prefixed with file modifications formatted as HTML-like tags (e.g., <bolt_file_modifications>).
Sources: app/routes/api.chat.ts:12-14, app/utils/diff.ts:89-106
Data Flow Diagram
The following diagram illustrates the lifecycle of a request to the Chat API endpoint:
The diagram shows how the SwitchableStream allows the server to swap data sources (for message continuation) without breaking the initial HTTP connection with the client.
Sources: app/routes/api.chat.ts:16-52
Core Implementation Logic
Switchable Stream and Continuation
A unique feature of the Bolt Chat API is the SwitchableStream. If the LLM stops generating due to reaching the maximum token limit (finishReason === 'length'), the server automatically triggers a continuation.
- Limit Check: It verifies if the number of segments hasn't exceeded
MAX_RESPONSE_SEGMENTS. - Context Injection: It appends the current assistant response and a specific
CONTINUE_PROMPTto the message history. - Source Switching: It requests a new stream from the LLM and calls
stream.switchSource()to pipe the new content into the existing readable stream.
Sources: app/routes/api.chat.ts:22-42
Client-Side Integration
The client initiates requests through the useChat hook. Before sending, the workbench store saves all files to ensure the LLM receives the latest state. If file modifications exist, they are calculated as diffs and prepended to the user message.
// app/components/chat/Chat.client.tsx:162-181
const sendMessage = async (_event: React.UIEvent, messageInput?: string) => {
await workbenchStore.saveAllFiles();
const fileModifications = workbenchStore.getFileModifcations();
if (fileModifications !== undefined) {
const diff = fileModificationsToHTML(fileModifications);
append({ role: 'user', content: `${diff}\n\n${_input}` });
} else {
append({ role: 'user', content: _input });
}
};
Sources: app/components/chat/Chat.client.tsx:162-181, app/utils/diff.ts:89-106
Data Persistence and Synchronization
Every successful interaction handled via the API is persisted through the useChatHistory hook on the client side. This involves a dual-persistence strategy:
| Storage Type | Description | File Reference |
|---|---|---|
| IndexedDB | Primary browser-based storage for chat history items and metadata. | app/lib/persistence/db.ts |
| Local Filesystem | Secondary storage using the File System Access API. Saves .boltnew.json and project files. | app/lib/persistence/fileSystem.ts |
Persistence Workflow
- On Finish: Once the API stream finishes, the client calls
storeMessageHistory. - ID Generation: If it's a new chat, a new ID is generated via
getNextId. - Sync: The messages are saved to IndexedDB and then mirrored to the local directory (if the user has granted access).
Sources: app/lib/persistence/useChatHistory.ts:98-132, app/lib/persistence/db.ts:68-85
API Parameters and Schema
The endpoint expects a POST request with a JSON body.
Request Body Schema
| Field | Type | Description |
|---|---|---|
messages | Array<Message> | An array of message objects containing role ('user', 'assistant', or 'system') and content. |
Response
| Status | Header | Body |
|---|---|---|
| 200 OK | contentType: text/plain | A continuous text stream of the LLM response. |
| 500 Error | N/A | Internal Server Error. |
Sources: app/routes/api.chat.ts:13-58
Conclusion
The Chat API Endpoint acts as the orchestrator for AI-driven development in Bolt. By utilizing a SwitchableStream, it provides a seamless user experience even when dealing with complex, long-form code generation. Its integration with the workbench's diffing engine ensures that the AI assistant remains perfectly synchronized with the user's local file changes.