366 lines
14 KiB
Markdown
366 lines
14 KiB
Markdown
# State Machine Documentation for Backend Chat Workflow
|
|
|
|
## Overview
|
|
|
|
The Chat Workflow system implements a state machine that processes user inputs through a sequence of well-defined steps. The system orchestrates interactions between users, project managers, and specialized agents to produce final outputs.
|
|
|
|
## Core Objects
|
|
|
|
### Workflow Object
|
|
```json
|
|
{
|
|
"id": "uuid-string",
|
|
"mandateId": int,
|
|
"userId": int,
|
|
"name": "Workflow name",
|
|
"startedAt": "ISO-datetime",
|
|
"messages": [], // References to messages
|
|
"messageIds": [], // List of message IDs
|
|
"logs": [], // Log entries
|
|
"dataStats": {}, // Performance metrics
|
|
"currentRound": int, // Increments with each interaction
|
|
"status": "string", // running, completed, failed, stopped
|
|
"lastActivity": "ISO-datetime"
|
|
}
|
|
```
|
|
|
|
### Message Object
|
|
```json
|
|
{
|
|
"id": "msg_uuid-string",
|
|
"workflowId": "workflow-uuid",
|
|
"role": "string", // user, assistant
|
|
"agentName": "string", // Empty for user, agent name for assistant
|
|
"content": "string", // The message text
|
|
"documents": [], // List of document objects
|
|
"timestamp": "ISO-datetime",
|
|
"sequenceNo": int, // Position in conversation
|
|
"status": "string" // first, step, last
|
|
}
|
|
```
|
|
|
|
### Log Entry Object
|
|
```json
|
|
{
|
|
"id": "log_uuid-string",
|
|
"workflowId": "workflow-uuid",
|
|
"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
|
|
"status": "string" // current workflow status (running, completed, failed, stopped)
|
|
}
|
|
```
|
|
|
|
### Document Object
|
|
```json
|
|
{
|
|
"id": "doc_uuid-string",
|
|
"fileId": int,
|
|
"name": "string", // Filename without extension
|
|
"ext": "string", // File extension
|
|
"data": "base64-encoded-string", // File contents
|
|
"contents": [] // Extracted content items in text format
|
|
}
|
|
```
|
|
|
|
### Content Item Object
|
|
```json
|
|
{
|
|
"sequenceNr": int, // Sequence in the document
|
|
"name": "string",
|
|
"ext": "string",
|
|
"contentType": "string", // mime type
|
|
"data": "string|base64", // Original content
|
|
"dataExtracted": "string", // Optional AI-processed content based on extraction requirement
|
|
"metadata": {
|
|
"isText": boolean,
|
|
"base64Encoded": boolean,
|
|
"aiProcessed": boolean,
|
|
// Optional metadata specific to content type
|
|
},
|
|
"summary": "string" // AI-generated static summary of the content
|
|
}
|
|
```
|
|
|
|
## State Machine Workflow
|
|
|
|
### 1. Workflow Initialization
|
|
- **Trigger**: User message received via `/api/workflows/start` OR `/api/workflows/start?id=string`
|
|
- **Input**: `UserInputRequest` with `prompt` and optional `listFileId`
|
|
- **Process**:
|
|
- If `id` existing and workflow exists for `id`==`workflowId`: Load workflow, increment `currentRound`, set status "running"
|
|
- Else: Create new workflow with "currentRound"=1, status "running"
|
|
- **Logs**: "Workflow initialized" or "Running workflow", progress 0%
|
|
- **API Responses**:
|
|
- Success: 200 OK with workflow ID
|
|
- Error: 400 Bad Request if input invalid, 404 Not Found if workflow ID not found
|
|
|
|
### 2. Workflow Exception
|
|
- **Trigger**:
|
|
- User stopped workflow via API
|
|
- An exception happened
|
|
- **Process**:
|
|
- If status=="stopped": Set workflow status to "stopped", add message with status "last", update lastActivity, stop execution immediately
|
|
- If status=="failed": Set workflow status to "failed", add message with status "last", update lastActivity, stop execution immediately
|
|
- Else: Continue normally
|
|
- **Logs**: "Workflow failure reported", progress 100%
|
|
- **API Responses**:
|
|
- For stop request: 200 OK when workflow successfully stopped
|
|
- For exceptions: 500 Internal Server Error with error details
|
|
|
|
### 3. User Message Processing
|
|
- **Process**:
|
|
- Transform user input into message object with documents, message status "first"
|
|
- Extract contents from files using `getDocumentContents()`
|
|
- Generate static summaries for each content item
|
|
- **State Changes**:
|
|
- Add user message to `workflow.messages` array
|
|
- Add message ID to `workflow.messageIds` array
|
|
- Update `workflow.lastActivity`
|
|
- **Logs**: "Workflow processing started", progress 0%
|
|
|
|
### 4. Project Manager Analysis
|
|
- **Process**:
|
|
- Generate prompt for project manager AI
|
|
- Project manager analyzes request and documents
|
|
- Project manager generates work plan and response
|
|
- **Outputs**:
|
|
- `objFinalDocuments`: List of str "filename.ext" for expected final output documents
|
|
- `objWorkplan`: List of agent tasks
|
|
- `objUserResponse`: Text response to user
|
|
- `userLanguage`: Detected language code (e.g. en)
|
|
- **State Changes**:
|
|
- Add assistant message with project manager response, status "step"
|
|
- Set user language in mydom interface
|
|
- **Logs**: "Analyzing request and planning work" (10%), "Planned outputs" (20%), "Work plan created" (25%)
|
|
|
|
### 5. Agent Execution
|
|
- **Process** (For each task in workplan):
|
|
- Prepare input documents for agent
|
|
- Execute agent with standardized task object
|
|
- Save produced documents
|
|
- Create assistant message with agent response, status "step"
|
|
- **Agent Task Object**:
|
|
```json
|
|
{
|
|
"taskId": "uuid-string",
|
|
"workflowId": "workflow-uuid",
|
|
"prompt": "string",
|
|
"inputDocuments": [], // list of documents including original document data and all content items data with original (attribute "data") and based on prompt (attribute "dataExtracted")
|
|
"outputSpecifications": [
|
|
{
|
|
"label": "filename.ext",
|
|
"description": "string"
|
|
}
|
|
],
|
|
"context": {
|
|
"workflowRound": int,
|
|
"agentType": "string",
|
|
"timestamp": "ISO-datetime",
|
|
"language": "language-code"
|
|
}
|
|
}
|
|
```
|
|
- **Agent Result Object**:
|
|
```json
|
|
{
|
|
"feedback": "string", // Text describing what the agent did
|
|
"documents": [
|
|
{
|
|
"label": "filename.ext",
|
|
"content": "string|binary" // Document contents
|
|
}
|
|
]
|
|
}
|
|
```
|
|
- **State Changes**: Add assistant message for each agent with agentName set, status "step"
|
|
- **Logs**: "Running task X/Y: agentName" with progress updates from 30% to 90%
|
|
|
|
### 6. Final Response Generation
|
|
- **Process**:
|
|
- Create final message reviewing promised and delivered documents
|
|
- Add documents to workflow
|
|
- **State Changes**: Add final assistant message from projectManager, status "last"
|
|
- **Logs**: "Creating final response" (90%)
|
|
|
|
### 7. Workflow Completion
|
|
- **Process**:
|
|
- Finalize workflow and update status
|
|
- **State Changes**:
|
|
- Set workflow status to "completed"
|
|
- Update `workflow.lastActivity`
|
|
- **Logs**: "Workflow completed successfully" with progress 100%
|
|
- **API Responses**:
|
|
- A message with status "last" is included in the response
|
|
- Status endpoint will return "completed"
|
|
|
|
### 8. Workflow Stopped
|
|
- **Trigger**: `/api/workflows/{workflowId}/stop` endpoint called
|
|
- **Process**:
|
|
- Immediately interrupt workflow execution
|
|
- Save current state and mark as stopped
|
|
- **State Changes**:
|
|
- Set workflow status to "stopped"
|
|
- Update lastActivity timestamp
|
|
- **Logs**: "Workflow stopped by user" with progress 100%
|
|
- **API Responses**:
|
|
- 200 OK with confirmation message
|
|
|
|
### 9. Workflow Failed
|
|
- **Trigger**: Exception during workflow execution
|
|
- **Process**:
|
|
- Log error details
|
|
- Set workflow status to "failed"
|
|
- **State Changes**:
|
|
- Set workflow status to "failed"
|
|
- Update lastActivity timestamp
|
|
- **Logs**: Detailed error message with progress 100%
|
|
- **API Responses**:
|
|
- Status endpoint will return "failed" with error context
|
|
|
|
### 10. Workflow Resumption
|
|
- **Trigger**: `/api/workflows/start?id={workflowId}` endpoint called with existing workflow ID
|
|
- **Process**:
|
|
- Load existing workflow
|
|
- Increment currentRound counter
|
|
- Start processing from user message
|
|
- **State Changes**:
|
|
- Set status to "running"
|
|
- Increment currentRound
|
|
- Add new user message
|
|
- **Logs**: "Resuming workflow, round {currentRound}" with progress 0%
|
|
- **API Responses**:
|
|
- Same as workflow initialization
|
|
|
|
### 11. Workflow Reset/Deletion
|
|
- **Trigger**: `/api/workflows/{workflowId}` DELETE endpoint called
|
|
- **Process**:
|
|
- Remove all workflow data from storage
|
|
- **State Changes**:
|
|
- Workflow no longer exists in the system
|
|
- **Logs**: Log in system log that workflow was deleted
|
|
- **API Responses**:
|
|
- 200 OK if successful
|
|
- 404 Not Found if workflow didn't exist
|
|
|
|
## API Endpoints and Polling Support
|
|
|
|
### Main Workflow Endpoints
|
|
- `POST /api/workflows/start?id=string`: Submit user input to start a new workflow, optional with workflow id to continue existing workflow
|
|
- `POST /api/workflows/{workflowId}/stop`: Stop a running workflow: Immediately to set workflow status to "stopped"
|
|
- `DELETE /api/workflows/{workflowId}`: Delete a workflow
|
|
- `GET /api/workflows/{workflowId}/status`: Get workflow status (running, completed, failed, stopped)
|
|
- `GET /api/workflows/{workflowId}/logs?id=string`: Get workflow logs, optional with log id to get only logs produced after and including log with log id
|
|
- `GET /api/workflows/{workflowId}/messages?id=string`: Get workflow messages, optional with message id to get only messages produced after and including message with log id
|
|
|
|
### Document Management
|
|
- `DELETE /api/workflows/{workflowId}/messages/{messageId}`: Delete a message
|
|
- `DELETE /api/workflows/{workflowId}/messages/{messageId}/files/{fileId}`: Remove file from message
|
|
|
|
### Backend Support for Frontend Polling
|
|
|
|
The backend implements efficient support for frontend polling mechanisms:
|
|
|
|
1. **Selective Data Transfer**:
|
|
- Both `/logs` and `/messages` endpoints accept an optional `id` parameter
|
|
- When provided, only records with IDs equal to or newer than the specified ID are returned
|
|
- This minimizes data transfer and improves performance
|
|
|
|
2. **Log Storage**:
|
|
- Each log entry includes timestamp, progress indicators, and status
|
|
- Frontend can accurately track workflow progress and update UI accordingly
|
|
- Logs are stored in chronological order with monotonically increasing IDs
|
|
|
|
3. **Message Handling**:
|
|
- Messages include a status field ("first", "step", "last")
|
|
- The "last" status indicates completion of the current workflow round
|
|
- Frontend uses this to determine when to enable user input
|
|
|
|
4. **Status Endpoint**:
|
|
- Lightweight endpoint that returns only the current workflow status
|
|
- Used by frontend to detect state changes without transferring all data
|
|
- Also includes lastActivity timestamp to detect stalled workflows
|
|
|
|
5. **Caching Layer**:
|
|
- Backend implements caching for frequent polling requests
|
|
- Reduces database load and improves response times
|
|
- Cache invalidation occurs when workflow status changes
|
|
|
|
6. **Batch Processing**:
|
|
- Large log or message sets are paginated automatically
|
|
- Frontend receives data in manageable chunks
|
|
- Prevents memory issues with long-running workflows
|
|
|
|
## Document Object Structure Clarification
|
|
The Document Object contains both raw data and processed contents:
|
|
- `data`: Contains the base64-encoded binary representation of the entire original file
|
|
- `contents`: Contains an array of structured Content Item objects extracted from the original file
|
|
|
|
The relationship works as follows:
|
|
1. When a file is uploaded, its binary data is stored in the `data` field
|
|
2. The original file's complete data is always preserved in the document's `data` field
|
|
3. The file is then processed by content extractors based on file type (PDF, image, text, etc.)
|
|
4. Each logically separate piece of content is added to the `contents` array
|
|
5. For text files, there might be just one content item
|
|
6. For PDFs, there might be multiple content items (one per page or per embedded image)
|
|
7. For complex documents, content items might represent different sections or formats
|
|
8. Each content item contains its own `data` field with the specific extracted content; for agents convenience it contains the additional field `dataExtracted` with extracted data based on agents task prompt
|
|
|
|
This dual structure allows agents to:
|
|
- Access the complete original file when needed
|
|
- Work with pre-processed, extracted content for efficiency
|
|
- Process specific sections of a document without loading the entire file
|
|
|
|
## State Transitions
|
|
|
|
```
|
|
[null] → [running] // New workflow created
|
|
[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 (new round)
|
|
[stopped] → [running] // User continues after manual stop (new round)
|
|
[failed] → [running] // User retries workflow despite error (new round)
|
|
[any] → [null] // Workflow deleted
|
|
```
|
|
|
|
## Exception Handling
|
|
|
|
### Rules
|
|
- Workflow status changes to "failed" on exceptions, all message and workflow generation exceptions to handle to ensure data consistency in the database
|
|
- Errors are logged in workflow logs with type "error"
|
|
- Produced project manager analysis output, inputs to agents, output from agents, workflow items, message items are all logged for debugging in the logger with type "debug"
|
|
- HTTP exceptions are returned to the client with appropriate status codes
|
|
- Failed agent tasks are recorded but don't stop the workflow
|
|
|
|
### Workflow Stop Conditions
|
|
- User explicitly cancels the workflow via the stop endpoint
|
|
|
|
Action to take:
|
|
- workflow to set to "stopped" status
|
|
|
|
### Workflow Failure Conditions
|
|
- Unhandled exceptions in the main workflow execution path
|
|
- Project manager analysis fails to generate a valid workplan
|
|
- More than 50% of the agent tasks in the workplan fail to complete
|
|
- Timeout exceeded (workflow runs longer than the configured maximum duration)
|
|
- System resource limits exceeded (memory, CPU, etc.)
|
|
|
|
Action to take, when a workflow fails:
|
|
- The last log entry will contain details about the failure reason
|
|
- workflow to set to "failed" status
|
|
|
|
### Workflow Exception Checkpoints
|
|
At the following points in the code the Workflow Execution routine is called:
|
|
- Before adding or updating a message to the workflow
|
|
- Before doing an API call
|
|
|
|
## Special Notes
|
|
|
|
1. **Document Processing**: Files uploaded by users are processed with content extraction to make them accessible to agents.
|
|
2. **AI Language Support**: The system detects and adapts to the user's language.
|
|
3. **Round Counting**: Each interaction increments the `currentRound` counter.
|
|
4. **Agent Registry**: Agents are loaded dynamically and registered in the AgentRegistry.
|
|
5. **Standardized Task Processing**: All agents implement the same task processing interface.
|