This page documents the chat modal and playground interface used in Langflow's frontend, including the ChatMessageType data model, ContentBlock rendering pipeline, streaming token display, file attachments, and session management. For information about how the frontend triggers flow builds and consumes SSE events, see Build and Execution Flow. For the underlying message persistence layer and memory API, see Memory and Message Management. For the event streaming system that delivers tokens to the frontend, see Event Streaming.
The chat interface is the primary way users interact with a running flow. It is surfaced as the Playground panel within the main flow editor and as a dedicated full-screen chat view. Both are rendered from the IOModal component (located at src/frontend/src/modals/IOModal/). The interface:
ChatMessageType objects.content_blocks array, dispatching to per-type sub-renderers.PlaygroundEvent events.session_id for conversation history.Diagram: IOModal Component Hierarchy
Sources: src/frontend/src/modals/IOModal/components/chatView/fileComponent/utils/get-classes.tsx
The central type used throughout the chat interface is ChatMessageType, defined in src/frontend/src/types/chat/index.ts.
Core fields of ChatMessageType:
| Field | Type | Description |
|---|---|---|
id | string | Unique message identifier |
isSend | boolean | true for user-sent messages, false for bot responses |
message | string | Object | Raw message body |
text | string | number | Rendered text content |
timestamp | string | ISO timestamp |
session_id | string? | Conversation session identifier |
flow_id | string? | Flow that produced this message |
sender | string? | Sender role, e.g., "User" or "Machine" |
sender_name | string? | Display name for the sender |
stream_url | string | null | undefined | URL for streaming response tokens |
content_blocks | ContentBlock[]? | Structured content blocks for rich rendering |
files | Array<{path, type, name} | string>? | Attached file references |
properties | PropertiesType? | Display overrides and metadata |
edit | boolean? | Whether the message has been edited |
icon | string? | Icon to display alongside the message |
category | string? | Message category tag |
PropertiesType fields:
| Field | Type | Purpose |
|---|---|---|
source | SourceType | Component that generated the message |
icon | string? | Icon override |
background_color | string? | Custom bubble background |
text_color | string? | Custom text color |
allow_markdown | boolean? | Whether to render markdown |
state | string? | Processing state indicator |
positive_feedback | boolean | null? | Thumbs-up/down feedback value |
build_duration | number | null? | Build time in ms |
edited | boolean? | Whether user edited the message |
Sources: src/frontend/src/types/chat/index.ts
Structured messages use the ContentBlock type instead of a flat string. A single ChatMessageType may contain multiple ContentBlock entries—one per logical output section (e.g., a reasoning block and a final answer block).
Diagram: ContentBlock Type Hierarchy
Sources: src/frontend/src/types/chat/index.ts
Each element in ContentBlock.contents is a discriminated union keyed on type:
type value | Interface | Key Fields |
|---|---|---|
"text" | TextContent | text: string |
"code" | CodeContent | code: string, language: string, title?: string |
"media" | MediaContent | urls: string[], caption?: string |
"json" | JSONContent | data: Record<string, JSONValue> |
"tool_use" | ToolContent | name, tool_input, output, error |
"error" | ErrorContent | component, field, reason, solution, traceback |
All content types extend BaseContent, which provides type: string, duration?: number, and an optional header object with title and icon fields.
Sources: src/frontend/src/types/chat/index.ts78-136
Real-time token streaming is driven by PlaygroundEvent objects, which arrive over the SSE channel established during flow execution (see Event Streaming for how this channel is created).
PlaygroundEvent structure:
event_type: "message" | "error" | "warning" | "info" | "token"
sender_name: string
text?: string
token?: string // present when event_type === "token"
content_blocks?: ContentBlock[]
files?: string[]
timestamp?: string
id?: string
flow_id?: string
session_id?: string
Diagram: Streaming Token Flow
When event_type === "token", the token field contains an incremental text chunk. The frontend appends it to the current message's text field for display. When a final "message" event arrives, the full ChatMessageType (including content_blocks) replaces the in-progress entry.
The stream_url field on a ChatMessageType is an alternative mechanism: when set, the frontend opens a separate streaming connection to that URL to fetch response tokens for that specific message.
Sources: src/frontend/src/types/chat/index.ts147-164
The files field on ChatMessageType carries an array of file references. Each element is either:
string path, or{ path: string; type: string; name: string }.Within chatView, attached files are rendered by the fileComponent sub-component. The get-classes.tsx utility inside fileComponent/utils/ controls the hover and shadow styling of the file tile:
src/frontend/src/modals/IOModal/components/chatView/fileComponent/utils/get-classes.tsx1-5
File uploads from the user side are handled by use-post-upload-file (in src/frontend/src/controllers/API/queries/files/), which POSTs the file to the backend and returns a path that is then embedded in the outgoing ChatMessageType.
Sources: src/frontend/src/types/chat/index.ts8-9 src/frontend/src/modals/IOModal/components/chatView/fileComponent/utils/get-classes.tsx, src/frontend/src/controllers/API/queries/files/index.ts
Every chat exchange is scoped by a session_id string. All messages with the same session_id form a single conversation history. Sessions are per-flow: a single flow can have many sessions.
Backend session API (from /monitor router):
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/monitor/messages/sessions | List distinct session_id values for the current user, optionally filtered by flow_id |
GET | /api/v1/monitor/messages | Fetch messages, filterable by flow_id, session_id, sender, sender_name, order_by |
PUT | /api/v1/monitor/messages/{message_id} | Edit a single message (sets edit=true if text changes) |
PATCH | /api/v1/monitor/messages/session/{old_session_id} | Rename a session (updates all messages to new session_id) |
DELETE | /api/v1/monitor/messages | Delete messages by list of UUIDs |
DELETE | /api/v1/monitor/messages/session/{session_id} | Delete all messages in a session |
Diagram: Session Management Data Flow
Sources: src/backend/base/langflow/api/v1/monitor.py44-188
The Message class (re-exported in src/backend/base/langflow/schema/message.py from lfx.schema.message) is the canonical backend representation. Its MessageResponse variant is what the monitor API returns.
Key fields that map to ChatMessageType:
Backend (MessageTable) | Frontend (ChatMessageType) |
|---|---|
session_id | session_id |
flow_id | flow_id |
sender | sender |
sender_name | sender_name |
text | text |
content_blocks (JSON list) | content_blocks |
properties (JSON dict) | properties |
files (JSON list) | files |
timestamp | timestamp |
edit | edit |
error (bool) | (used to filter; maps to ErrorContent blocks) |
The content_blocks and properties columns are stored as JSON in the database. The aadd_messagetables function in src/backend/base/langflow/memory.py179-228 handles JSON parsing on read and session.add / session.commit on write.
Sources: src/backend/base/langflow/schema/message.py, src/backend/base/langflow/memory.py128-228 src/backend/base/langflow/api/v1/monitor.py66-99
Diagram: Full Lifecycle of a Chat Message
Sources: src/backend/base/langflow/memory.py301-337 src/backend/base/langflow/api/v1/monitor.py66-99 src/frontend/src/types/chat/index.ts147-164
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.