453 lines
16 KiB
Markdown
453 lines
16 KiB
Markdown
# State Machine Documentation for Frontend Chat Workflow
|
|
|
|
## Overview
|
|
|
|
The Chat Workflow frontend implements a state machine that manages user interactions through a well-defined sequence of states. This system coordinates the user interface components, handles file attachments, and manages communication with the backend to provide a seamless multi-agent chat experience.
|
|
|
|
## Core Objects
|
|
|
|
### Frontend Workflow State Object
|
|
```json
|
|
{
|
|
"status": "string", // null or "running", "completed", "failed", "stopped"
|
|
"workflowId": "string", // null or Unique workflow identifier
|
|
"logs": [], // Log entries
|
|
"chatMessages": [], // Chat messages
|
|
"lastPolledLogId": "string", // ID of last polled log
|
|
"lastPolledMessageId": "string", // ID of last polled message
|
|
"dataStats": {
|
|
"bytesSent": int, // Data sent to backend
|
|
"bytesReceived": int, // Data received from backend
|
|
"tokensUsed": float // Used tokens required for billing
|
|
}
|
|
}
|
|
```
|
|
|
|
### User Input State Object
|
|
```json
|
|
{
|
|
"promptText": "string", // Current user input text
|
|
"additionalFiles": [], // List of file IDs to attach
|
|
"domElements": {} // References to UI DOM elements
|
|
}
|
|
```
|
|
|
|
### Log Entry Object
|
|
```json
|
|
{
|
|
"id": "log_timestamp",
|
|
"message": "string",
|
|
"progress": int, // Optional, 0-100
|
|
"type": "string", // info, warning, error
|
|
"timestamp": "ISO-datetime",
|
|
"agentName": "string", // Name of the agent that generated the log
|
|
"waiting": boolean, // Whether this log shows a waiting indicator
|
|
"highlighted": boolean // Whether this log should be visually highlighted
|
|
}
|
|
```
|
|
|
|
### Chat Message Object
|
|
```json
|
|
{
|
|
"id": "msg_type_timestamp",
|
|
"role": "string", // user, assistant
|
|
"agentName": "string",
|
|
"content": "string",
|
|
"documents": [], // List of document objects
|
|
"timestamp": "ISO-datetime",
|
|
"status": "string" // first, step, last ("workflowComplete" can be asked as `status`=="last")
|
|
}
|
|
```
|
|
|
|
### File Object
|
|
```json
|
|
{
|
|
"id": "file_uuid-string",
|
|
"name": "filename.ext",
|
|
"size": int,
|
|
"fileId": int,
|
|
"contentType": "string", // mime type
|
|
}
|
|
```
|
|
|
|
## State Machine Workflow
|
|
|
|
### 1. Initial State
|
|
- **State**: `null` (No workflow active)
|
|
- **UI Elements**:
|
|
- Empty chat container with placeholder
|
|
- Prompt input field enabled
|
|
- "Start" button enabled
|
|
- "Stop" button hidden
|
|
- File upload area enabled
|
|
- Empty log panel
|
|
- **User Actions**:
|
|
- Enter prompt text
|
|
- Add files via upload or drag & drop
|
|
- Select pre-defined prompts from dropdown
|
|
- Click Start button
|
|
- **API Interactions**: None in this state
|
|
|
|
### 2. Prompt Preparation
|
|
- **State**: `null` (transitioning to `running`)
|
|
- **Triggers**:
|
|
- User typing in prompt field (updates `userInputState.promptText`)
|
|
- File uploads/drag & drop (adds to `userInputState.additionalFiles`)
|
|
- Prompt selection from dropdown (sets `userInputState.promptText`)
|
|
- **Process**:
|
|
- Files are uploaded to backend via `uploadAndAddFile()`
|
|
- Files appear in attachment list with name, size, remove option
|
|
- Prompt visualization is updated with file count and names
|
|
- **State Changes**:
|
|
- `userInputState.additionalFiles` array updated
|
|
- `userInputState.promptText` updated
|
|
- **UI Updates**:
|
|
- File attachment list rendered
|
|
- Prompt preview area shows attached files
|
|
- **API Interactions**:
|
|
- `POST /api/files/upload`: For each file being attached, an API call is made to upload the file and get a file ID
|
|
- Response contains file metadata which is stored in the frontend state
|
|
|
|
### 3. Workflow Initialization
|
|
- **State**: `running`
|
|
- **Trigger**: User clicks "Start" button or presses Enter
|
|
- **Process**:
|
|
- Validate user input (ensures non-empty prompt)
|
|
- Set loading state (disable start button, show spinner)
|
|
- Submit prompt and files
|
|
- Receive workflow ID from backend
|
|
- **State Changes**:
|
|
- `status` → `running`
|
|
- `workflowId` set to returned ID
|
|
- `userInputState.additionalFiles` reset to empty array
|
|
- `userInputState.promptText` reset to empty string
|
|
- **UI Updates**:
|
|
- Chat messages container shown
|
|
- User message appears in chat
|
|
- Log entry added: "Workflow started"
|
|
- System chat message added: "Multi-Agent Chat has been started"
|
|
- Start button becomes Send button, deactivated and with animation
|
|
- Stop button becomes visible
|
|
- Input field disabled temporarily
|
|
- **API Interactions**:
|
|
- `POST /api/workflows/start`: Submit user prompt and list of file IDs
|
|
- Request payload: `{ prompt: string, fileIds: array }`
|
|
- Response contains `workflowId` which is stored for future API calls
|
|
- For continuing an existing workflow: `POST /api/workflows/start?id={workflowId}`
|
|
|
|
### 4. Polling for Updates
|
|
- **State**: `running`
|
|
- **Process**:
|
|
- `pollWorkflowStatus()` initiated with workflow ID
|
|
- `pollWorkflowLogs()` and `pollWorkflowMessages()` called periodically
|
|
- Last log and message IDs tracked to request only new items
|
|
- New logs and messages added to state
|
|
- **State Changes**:
|
|
- `logs` array updated with new log entries
|
|
- `chatMessages` array updated with new messages
|
|
- `lastPolledLogId` and `lastPolledMessageId` updated
|
|
- `dataStats` updated with sent/received bytes and tokens
|
|
- **UI Updates**:
|
|
- Updated and new logs rendered in log panel
|
|
- Updated and new chat messages rendered in chat area
|
|
- Waiting animation shown on latest log entry
|
|
- Data statistics counters updated
|
|
- **API Interactions**:
|
|
- `GET /api/workflows/{workflowId}/status`: Polls workflow status (every 2000ms)
|
|
- `GET /api/workflows/{workflowId}/logs?id={lastPolledLogId}`: Gets only logs newer than the last polled log
|
|
- `GET /api/workflows/{workflowId}/messages?id={lastPolledMessageId}`: Gets only messages newer than the last polled message
|
|
- Polling continues until workflow status changes from "running" or a message with status "last" is received
|
|
|
|
### 5. Workflow Running
|
|
- **State**: `running`
|
|
- **Process**:
|
|
- Backend processes user input through agent workflow
|
|
- Frontend continuously polls for updates
|
|
- Log entries show progress of agents
|
|
- Chat messages display agent responses
|
|
- **UI Elements**:
|
|
- Stop button visible and enabled
|
|
- Input field disabled
|
|
- Log panel shows processing steps with progress indicators
|
|
- Chat displays multi-agent conversation
|
|
- **User Actions**:
|
|
- Click Stop button to interrupt workflow
|
|
- View file attachments in messages
|
|
- Preview or download files
|
|
- **API Interactions**:
|
|
- Continued polling via endpoints described in State 4
|
|
- `POST /api/workflows/{workflowId}/stop`: If user clicks Stop button
|
|
|
|
### 6. Workflow Completion
|
|
- **State**: `completed`
|
|
- **Trigger**: Backend returns workflow status "completed" or message with status "last"
|
|
- **Process**:
|
|
- Final message displayed, input enabled for new prompt
|
|
- Polling stops
|
|
- **State Changes**:
|
|
- `status` → `completed`
|
|
- **UI Updates**:
|
|
- Stop button hidden
|
|
- Start button enabled
|
|
- Input field enabled and focused
|
|
- Final log shows "Workflow completed"
|
|
- **API Interactions**:
|
|
- No further API calls until user inputs new prompt
|
|
|
|
### 7. Workflow Failure
|
|
- **State**: `failed`
|
|
- **Trigger**: Backend returns workflow status "failed"
|
|
- **Process**:
|
|
- Error message displayed, option to retry
|
|
- Polling stops
|
|
- **State Changes**:
|
|
- `status` → `failed`
|
|
- **UI Updates**:
|
|
- Error indicators in UI
|
|
- Retry option enabled
|
|
- Input field enabled
|
|
- **API Interactions**:
|
|
- No further API calls until user initiates retry
|
|
|
|
### 8. Workflow Stopped
|
|
- **State**: `stopped`
|
|
- **Trigger**: User clicks Stop button or backend returns "stopped"
|
|
- **Process**:
|
|
- Workflow processing interrupted
|
|
- Polling stops
|
|
- **State Changes**:
|
|
- `status` → `stopped`
|
|
- **UI Updates**:
|
|
- Resume option enabled
|
|
- Start button enabled
|
|
- Input field enabled
|
|
- **API Interactions**:
|
|
- No further API calls until user continues or resets
|
|
|
|
### 9. User Input Requested
|
|
- **State**: Varies based on workflow state
|
|
- **Trigger**: Received message with status "last" or workflow status not "running"
|
|
- **Process**:
|
|
- Special log entry added: "Waiting for user input to continue"
|
|
- Input field enabled for user response
|
|
- **State Changes**:
|
|
- `status` → The status from the workflow
|
|
- **UI Updates**:
|
|
- Stop Polling
|
|
- Waiting animation stopped
|
|
- Input field enabled and focused
|
|
- Send button enabled
|
|
- Send button shows "Start" for new workflow or "Send" for continuation
|
|
- Input field may show specific placeholder
|
|
- Stop button hidden
|
|
- **API Interactions**:
|
|
- No API calls until user provides input
|
|
|
|
### 10. Continuation Preparation
|
|
- **State**: `completed`, `failed`, or `stopped` (transitioning to `running`)
|
|
- **Trigger**: User enters new input after previous workflow cycle
|
|
- **Process**:
|
|
- Prepare continuation with existing workflow ID
|
|
- Similar to Prompt Preparation but preserves context
|
|
- **State Changes**:
|
|
- `userInputState.promptText` updated
|
|
- `userInputState.additionalFiles` updated if new files added
|
|
- **UI Updates**:
|
|
- File attachment list updated if changed
|
|
- Send button ready for continuation
|
|
- **API Interactions**:
|
|
- Same as Prompt Preparation if new files are added
|
|
|
|
### 11. Workflow Resumption
|
|
- **State**: `running`
|
|
- **Trigger**: User continues workflow after stop/failure/completion
|
|
- **Process**:
|
|
- Submit new input with existing workflow ID
|
|
- **State Changes**:
|
|
- `status` → `running`
|
|
- New user message added
|
|
- **UI Updates**:
|
|
- Similar to Workflow Initialization but preserves history
|
|
- Polling resumes
|
|
- **API Interactions**:
|
|
- `POST /api/workflows/start?id={workflowId}`: Sends continuation prompt with existing workflow ID
|
|
- Polling endpoints resume as in State 4
|
|
|
|
### 12. Workflow Reset
|
|
- **State**: `null`
|
|
- **Trigger**: User clicks Reset button
|
|
- **Process**:
|
|
- All state data cleared
|
|
- UI reset to initial state
|
|
- **State Changes**:
|
|
- `status` → `null`
|
|
- `workflowId` → `null`
|
|
- `logs` → `[]`
|
|
- `chatMessages` → `[]`
|
|
- **UI Updates**:
|
|
- Empty chat state shown
|
|
- Log panel cleared
|
|
- Input field reset
|
|
- Chat area cleared
|
|
- File attachments removed
|
|
- **API Interactions**:
|
|
- Optional `DELETE /api/workflows/{workflowId}` to clean up server resources
|
|
|
|
## API Interaction Details
|
|
|
|
### Polling Implementation
|
|
The frontend implements a sophisticated polling mechanism that efficiently retrieves only the new data:
|
|
|
|
1. **Initialization**:
|
|
- When a workflow starts, the frontend stores the workflow ID
|
|
- Initial polling begins immediately after receiving workflow ID
|
|
|
|
2. **Selective Data Retrieval**:
|
|
- Frontend tracks `lastPolledLogId` and `lastPolledMessageId`
|
|
- Each polling request includes the last ID to receive only newer items
|
|
- This significantly reduces bandwidth and processing requirements
|
|
|
|
3. **Polling Schedule**:
|
|
- Status polling: Every 2000ms while in `running` state
|
|
- Logs polling: Every 1000ms while in `running` state
|
|
- Messages polling: Every 1000ms while in `running` state
|
|
- All polling stops when workflow status changes from `running`
|
|
|
|
4. **Retry Mechanism**:
|
|
- Network failures trigger exponential backoff
|
|
- Starting at 1000ms, doubling up to 16000ms max
|
|
- After 5 consecutive failures, displays connection error
|
|
|
|
5. **Polling Suspension**:
|
|
- Polling automatically pauses when browser tab is inactive
|
|
- Resumes when tab becomes active again
|
|
- Can be manually suspended with `suspendPolling()` during UI transitions
|
|
|
|
### API Endpoints Used
|
|
|
|
| Frontend Function | Backend Endpoint | Parameters | Description |
|
|
|-------------------|------------------|------------|-------------|
|
|
| `startWorkflow()` | `POST /api/workflows/start` | `{ prompt: string, fileIds: [] }` | Starts new workflow |
|
|
| `continueWorkflow()` | `POST /api/workflows/start?id={workflowId}` | `{ prompt: string, fileIds: [] }` | Continues existing workflow |
|
|
| `pollWorkflowStatus()` | `GET /api/workflows/{workflowId}/status` | None | Gets current workflow status |
|
|
| `pollWorkflowLogs()` | `GET /api/workflows/{workflowId}/logs?id={lastLogId}` | Optional log ID | Gets logs newer than specified ID |
|
|
| `pollWorkflowMessages()` | `GET /api/workflows/{workflowId}/messages?id={lastMessageId}` | Optional message ID | Gets messages newer than specified ID |
|
|
| `stopWorkflow()` | `POST /api/workflows/{workflowId}/stop` | None | Interrupts running workflow |
|
|
| `resetWorkflow()` | `DELETE /api/workflows/{workflowId}` | None | Cleans up workflow resources |
|
|
| `uploadFile()` | `POST /api/files/upload` | FormData with file | Uploads file and returns file ID |
|
|
| `deleteMessage()` | `DELETE /api/workflows/{workflowId}/messages/{messageId}` | None | Removes message from workflow |
|
|
| `removeFileFromMessage()` | `DELETE /api/workflows/{workflowId}/messages/{messageId}/files/{fileId}` | None | Removes file from message |
|
|
|
|
## Special Features
|
|
|
|
### File Handling
|
|
1. **File Upload**:
|
|
- Direct upload via button or drag & drop
|
|
- FileId added to `userInputState.additionalFiles`
|
|
- UI renders file in attachment list
|
|
- Each file can be removed individually
|
|
|
|
2. **File Preview**:
|
|
- Files in messages can be previewed
|
|
- Preview shows content based on file type (text, image, PDF)
|
|
- Files can be downloaded or copied to clipboard
|
|
- Various file formats supported with appropriate visualizations
|
|
|
|
### Chat Message Rendering
|
|
1. **Message Types**:
|
|
- User messages (grey background)
|
|
- Agent messages (white background)
|
|
- Moderator questions (specially formatted)
|
|
|
|
2. **Message Features**:
|
|
- Collapsible for long content
|
|
- Symbol to delete message
|
|
- File attachments with preview options
|
|
- Markdown-like formatting support
|
|
- Agent name and timestamp display
|
|
|
|
### Log Panel Features
|
|
1. **Log Types**:
|
|
- Info (blue)
|
|
- Warning (orange)
|
|
- Error (red)
|
|
|
|
2. **Log Features**:
|
|
- Log items are read selectively from API: Only the last log entry and newer ones
|
|
- Progress indicators for agent tasks; before a next log message is rendered, the last log message progress is set to 100%
|
|
- Waiting animation for ongoing processes
|
|
- Agent-specific highlighting
|
|
- Collapsible detailed information, meaning the first n (e.g., 40) characters are by default displayed with "..." at the end. By clicking on "..." the additional part can be expanded/collapsed
|
|
- Timestamp display
|
|
|
|
### Waiting States
|
|
1. **Animation**:
|
|
- Dots animation in log entries
|
|
- Spinner in Send button during loading
|
|
- Progress indicators in agent logs
|
|
|
|
2. **State Management**:
|
|
- `waiting` flag in log objects
|
|
- `waitingDotsInterval` controls animation
|
|
- `setLoadingState()` manages UI element states
|
|
|
|
## State Transitions
|
|
|
|
```
|
|
[null] → [running] // Initial prompt submission
|
|
[running] → [running] // Ongoing polling updates
|
|
[running] → [completed] // Workflow completes successfully
|
|
[running] → [stopped] // User manually stops workflow
|
|
[running] → [failed] // Error occurs during workflow
|
|
[completed] → [running] // User continues workflow with new input
|
|
[stopped] → [running] // User continues after manual stop
|
|
[failed] → [running] // User retries workflow despite error
|
|
[any] → [null] // User resets workflow
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
### Client-side Errors
|
|
1. **Network Errors**:
|
|
- Retry mechanism in polling functions
|
|
- Exponential backoff for repeated failures
|
|
- Informative error logs for debugging
|
|
|
|
2. **UI Errors**:
|
|
- Validation before state changes
|
|
- Fallback DOM element selection
|
|
- Error boundaries for component isolation
|
|
|
|
### Backend Communication Errors
|
|
1. **API Failures**:
|
|
- Error logging in console
|
|
- User-friendly error messages in UI
|
|
- Error state with option to retry
|
|
- Toast notifications for transient errors
|
|
|
|
2. **Data Inconsistencies**:
|
|
- ID matching with fallback to partial matching
|
|
- Multiple file reference methods
|
|
- Content extraction fallbacks
|
|
|
|
## Implementation Notes
|
|
|
|
1. **Module Structure**:
|
|
- `workflow.js`: Main initialization and coordination
|
|
- `workflowState.js`: State management
|
|
- `workflowApi.js`: Backend communication
|
|
- `workflowUi.js`: UI rendering
|
|
- `workflowUtils.js`: Helper functions
|
|
|
|
2. **Key Functions**:
|
|
- `workflowInit()`: Entry point for initialization
|
|
- `workflowStatusUpdate()`: Core state transition function
|
|
- `workflowStatusPoll()`: Main update loop
|
|
- `workflowUserInput()`: Handles user input submission
|
|
- `renderLogs()` and `renderMessages()`: UI update functions
|
|
|
|
3. **Performance Optimizations**:
|
|
- Selective DOM updates
|
|
- Scroll position preservation
|
|
- Data size estimation for statistics
|
|
- Conditional re-rendering
|