gateway/notes/doc_statemachine_frontend.md
2025-04-26 02:13:22 +02:00

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