717 lines
No EOL
24 KiB
JavaScript
717 lines
No EOL
24 KiB
JavaScript
/**
|
|
* workflow.js
|
|
* The main coordinator module for the workflow functionality
|
|
* Acts as the entry point and orchestrates interactions between all other modules
|
|
* Implements a state machine for workflow status management
|
|
*/
|
|
|
|
import api from '../shared/apiCalls.js';
|
|
import * as WorkflowCoordination from './workflowCoordination.js';
|
|
import * as WorkflowUI from './workflowUi.js';
|
|
import * as WorkflowData from './workflowData.js';
|
|
|
|
// DOM elements mapping
|
|
const domElements = {};
|
|
|
|
// State machine constants
|
|
const WORKFLOW_STATES = {
|
|
NULL: null,
|
|
RUNNING: 'running',
|
|
COMPLETED: 'completed',
|
|
FAILED: 'failed',
|
|
STOPPED: 'stopped'
|
|
};
|
|
|
|
/**
|
|
* Initializes the workflow module
|
|
* @param {Object} globalStateObj - Global application state
|
|
*/
|
|
function initWorkflowModule(globalStateObj) {
|
|
console.log("Initializing workflow module...");
|
|
|
|
try {
|
|
// Initialize DOM elements
|
|
initDomElements();
|
|
|
|
// Initialize coordination layer with initial state
|
|
WorkflowCoordination.initCoordination({
|
|
status: WORKFLOW_STATES.NULL,
|
|
workflowId: "",
|
|
logs: [],
|
|
chatMessages: [],
|
|
lastPolledLogId: null,
|
|
lastPolledMessageId: null,
|
|
dataStats: {
|
|
bytesSent: 0,
|
|
bytesReceived: 0,
|
|
tokensUsed: 0
|
|
},
|
|
pollFailCount: 0
|
|
});
|
|
|
|
// Make DOM elements available to coordination layer
|
|
WorkflowCoordination.userInputState.domElements = domElements;
|
|
|
|
// Initialize UI layer with callbacks
|
|
WorkflowUI.initUI(
|
|
WorkflowCoordination.getWorkflowState(),
|
|
{
|
|
onResetWorkflow: resetWorkflow,
|
|
onStopWorkflow: stopWorkflow,
|
|
onLayoutChange: handleLayoutChange
|
|
}
|
|
);
|
|
|
|
// Initialize data layer
|
|
WorkflowData.initDataLayer(globalStateObj);
|
|
|
|
// Setup event listeners
|
|
setupEventListeners();
|
|
|
|
// Initialize file handling
|
|
initFileHandling();
|
|
|
|
// Load prompt options
|
|
if (globalStateObj && globalStateObj.mainView) {
|
|
loadPromptOptions(globalStateObj.mainView.availablePrompts || []);
|
|
}
|
|
|
|
// Show initial prompt view
|
|
WorkflowCoordination.showInitialPromptView();
|
|
|
|
console.log("Workflow module successfully initialized with state:", WORKFLOW_STATES.NULL);
|
|
} catch (error) {
|
|
console.error("Error initializing workflow module:", error);
|
|
window.utils.ui.showError("Failed to initialize workflow module: " + error.message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initializes all DOM element references
|
|
*/
|
|
function initDomElements() {
|
|
console.log("Initializing DOM elements");
|
|
|
|
// Main containers
|
|
domElements.workflowContainer = document.querySelector('.workflow-container');
|
|
domElements.workflowHeader = document.querySelector('.workflow-header');
|
|
domElements.chatSection = document.querySelector('.chat-section');
|
|
domElements.workflowFooter = document.querySelector('.workflow-footer');
|
|
|
|
// UI components
|
|
domElements.resetBtn = document.getElementById('reset-btn');
|
|
domElements.stopWorkflowBtn = document.getElementById('stop-workflow-btn');
|
|
domElements.executionLog = document.getElementById('execution-log');
|
|
domElements.agentChatMessages = document.getElementById('agent-chat-messages');
|
|
domElements.emptyChatState = document.getElementById('empty-chat-state');
|
|
domElements.userMessageInput = document.getElementById('user-message-input');
|
|
domElements.sendUserMessageBtn = document.getElementById('send-user-message-btn');
|
|
domElements.toggleHeaderBtn = document.getElementById('toggle-header-btn');
|
|
domElements.userInputArea = document.getElementById('user-input-area');
|
|
|
|
// File handling
|
|
domElements.filePreviewContainer = document.getElementById('file-preview-container');
|
|
domElements.filePreviewContent = document.getElementById('file-preview-content');
|
|
domElements.downloadFileBtn = document.getElementById('download-file-btn');
|
|
domElements.copyFileBtn = document.getElementById('copy-file-btn');
|
|
domElements.uploadAdditionalFileBtn = document.getElementById('upload-additional-file-btn');
|
|
domElements.additionalFileInput = document.getElementById('additional-file-input');
|
|
domElements.additionalFilesContainer = document.getElementById('additional-files-container');
|
|
|
|
// Prompt selection
|
|
domElements.promptSelectMain = document.getElementById('prompt-select-main');
|
|
|
|
// Statistics
|
|
domElements.dataStatisticsEl = document.getElementById('data-statistics');
|
|
|
|
// Log found elements vs missing elements
|
|
const foundElements = Object.keys(domElements).filter(key => domElements[key] !== null).length;
|
|
const missingElements = Object.keys(domElements).filter(key => domElements[key] === null);
|
|
|
|
console.log(`DOM elements initialized: ${foundElements} found, ${missingElements.length} missing`);
|
|
if (missingElements.length > 0) {
|
|
console.warn("Missing DOM elements:", missingElements.join(', '));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets up event listeners
|
|
*/
|
|
function setupEventListeners() {
|
|
console.log("Setting up event listeners");
|
|
|
|
// User input handling
|
|
if (domElements.userMessageInput) {
|
|
// Track input changes
|
|
domElements.userMessageInput.addEventListener('input', (e) => {
|
|
WorkflowCoordination.userInputState.promptText = e.target.value;
|
|
});
|
|
|
|
// Handle Enter key for submission
|
|
domElements.userMessageInput.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
e.preventDefault();
|
|
sendUserResponse();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Send button
|
|
if (domElements.sendUserMessageBtn) {
|
|
// Remove any existing listeners
|
|
const newButton = domElements.sendUserMessageBtn.cloneNode(true);
|
|
if (domElements.sendUserMessageBtn.parentNode) {
|
|
domElements.sendUserMessageBtn.parentNode.replaceChild(newButton, domElements.sendUserMessageBtn);
|
|
}
|
|
domElements.sendUserMessageBtn = newButton;
|
|
|
|
newButton.addEventListener('click', sendUserResponse);
|
|
}
|
|
|
|
// Reset button
|
|
if (domElements.resetBtn) {
|
|
domElements.resetBtn.addEventListener('click', resetWorkflow);
|
|
}
|
|
|
|
// Stop workflow button
|
|
if (domElements.stopWorkflowBtn) {
|
|
domElements.stopWorkflowBtn.addEventListener('click', stopWorkflow);
|
|
}
|
|
|
|
// Prompt selection
|
|
if (domElements.promptSelectMain) {
|
|
domElements.promptSelectMain.addEventListener('change', handlePromptSelection);
|
|
}
|
|
|
|
// Add custom event listeners for workflow state changes
|
|
document.addEventListener('workflowStatusChanged', handleWorkflowStatusChange);
|
|
}
|
|
|
|
/**
|
|
* Handler for workflow status change events
|
|
* @param {CustomEvent} event - The status change event
|
|
*/
|
|
function handleWorkflowStatusChange(event) {
|
|
const { status, previousStatus, options } = event.detail;
|
|
|
|
console.log(`Workflow status transition: ${previousStatus} → ${status}`);
|
|
|
|
// Update UI based on state transitions
|
|
switch (status) {
|
|
case WORKFLOW_STATES.RUNNING:
|
|
// Show running UI state
|
|
if (domElements.stopWorkflowBtn) {
|
|
domElements.stopWorkflowBtn.style.display = 'inline-block';
|
|
}
|
|
if (domElements.emptyChatState) {
|
|
domElements.emptyChatState.style.display = 'none';
|
|
}
|
|
if (domElements.agentChatMessages) {
|
|
domElements.agentChatMessages.style.display = 'block';
|
|
}
|
|
break;
|
|
|
|
case WORKFLOW_STATES.COMPLETED:
|
|
// Show completed UI state
|
|
if (domElements.stopWorkflowBtn) {
|
|
domElements.stopWorkflowBtn.style.display = 'none';
|
|
}
|
|
WorkflowCoordination.showInitialPromptView();
|
|
break;
|
|
|
|
case WORKFLOW_STATES.FAILED:
|
|
// Show failed UI state with retry option
|
|
if (domElements.stopWorkflowBtn) {
|
|
domElements.stopWorkflowBtn.style.display = 'none';
|
|
}
|
|
WorkflowCoordination.showInitialPromptView();
|
|
// Optionally show error UI
|
|
window.utils.ui.showToast(options.message || "Workflow failed", "error");
|
|
break;
|
|
|
|
case WORKFLOW_STATES.STOPPED:
|
|
// Show stopped UI state with resume option
|
|
if (domElements.stopWorkflowBtn) {
|
|
domElements.stopWorkflowBtn.style.display = 'none';
|
|
}
|
|
WorkflowCoordination.showInitialPromptView();
|
|
break;
|
|
|
|
case WORKFLOW_STATES.NULL:
|
|
// Reset to initial state
|
|
if (domElements.stopWorkflowBtn) {
|
|
domElements.stopWorkflowBtn.style.display = 'none';
|
|
}
|
|
if (domElements.emptyChatState) {
|
|
domElements.emptyChatState.style.display = 'flex';
|
|
}
|
|
if (domElements.agentChatMessages) {
|
|
domElements.agentChatMessages.style.display = 'none';
|
|
}
|
|
WorkflowCoordination.showInitialPromptView();
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initializes file handling functionality
|
|
*/
|
|
function initFileHandling() {
|
|
// Setup file input handling
|
|
if (domElements.uploadAdditionalFileBtn && domElements.additionalFileInput) {
|
|
domElements.uploadAdditionalFileBtn.addEventListener('click', () => {
|
|
domElements.additionalFileInput.click();
|
|
});
|
|
|
|
domElements.additionalFileInput.addEventListener('change', (event) => {
|
|
const files = event.target.files;
|
|
for (let file of files) {
|
|
handleFileSelection(file);
|
|
}
|
|
event.target.value = '';
|
|
});
|
|
}
|
|
|
|
// Initialize drag & drop
|
|
if (domElements.userInputArea) {
|
|
initDragAndDrop(domElements.userInputArea);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initializes drag and drop functionality
|
|
* @param {HTMLElement} dropArea - The area where files can be dropped
|
|
*/
|
|
function initDragAndDrop(dropArea) {
|
|
console.log("Initializing drag & drop for files");
|
|
|
|
// Prevent default drag behaviors
|
|
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
|
dropArea.addEventListener(eventName, preventDefaults, false);
|
|
});
|
|
|
|
// Highlight drop area when item is dragged over it
|
|
dropArea.addEventListener('dragenter', () => {
|
|
dropArea.classList.add('dragging');
|
|
});
|
|
|
|
dropArea.addEventListener('dragover', () => {
|
|
dropArea.classList.add('dragging');
|
|
});
|
|
|
|
// Remove highlight when item is dragged out or dropped
|
|
dropArea.addEventListener('dragleave', () => {
|
|
dropArea.classList.remove('dragging');
|
|
});
|
|
|
|
dropArea.addEventListener('drop', (e) => {
|
|
dropArea.classList.remove('dragging');
|
|
const files = e.dataTransfer.files;
|
|
|
|
if (files.length > 0) {
|
|
for (let file of files) {
|
|
handleFileSelection(file);
|
|
}
|
|
}
|
|
});
|
|
|
|
function preventDefaults(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles file selection from input or drop
|
|
* @param {File} file - The selected file
|
|
*/
|
|
async function handleFileSelection(file) {
|
|
try {
|
|
// Upload and process file
|
|
const processedFile = await api.uploadFile(file);
|
|
|
|
// Add to additional files list if successful
|
|
if (processedFile) {
|
|
const fileExists = WorkflowCoordination.userInputState.additionalFiles.some(f => f.id === processedFile.id);
|
|
|
|
if (!fileExists) {
|
|
WorkflowCoordination.userInputState.additionalFiles.push(processedFile);
|
|
WorkflowUI.renderAdditionalFiles(WorkflowCoordination.userInputState.additionalFiles);
|
|
WorkflowUI.updatePromptVisualization();
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error(`Error processing file ${file.name}:`, error);
|
|
window.utils.ui.showToast("File Processing Error", `Failed to process file ${file.name}: ${error.message}`, "error");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Loads prompt options into the select dropdown
|
|
* @param {Array} prompts - Available prompt templates
|
|
*/
|
|
function loadPromptOptions(prompts) {
|
|
if (!domElements.promptSelectMain || !prompts) {
|
|
return;
|
|
}
|
|
|
|
// Clear existing options, keeping the default
|
|
while (domElements.promptSelectMain.options.length > 1) {
|
|
domElements.promptSelectMain.remove(1);
|
|
}
|
|
|
|
// Add prompts to select
|
|
prompts.forEach(prompt => {
|
|
const option = document.createElement('option');
|
|
option.value = prompt.id;
|
|
option.textContent = prompt.name || `Prompt ${prompt.id}`;
|
|
domElements.promptSelectMain.appendChild(option);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handles selection from the prompt dropdown
|
|
*/
|
|
function handlePromptSelection() {
|
|
if (!domElements.promptSelectMain || !domElements.userMessageInput) {
|
|
return;
|
|
}
|
|
|
|
const selectedPromptId = domElements.promptSelectMain.value;
|
|
|
|
if (!selectedPromptId) {
|
|
domElements.userMessageInput.value = '';
|
|
WorkflowCoordination.userInputState.promptText = '';
|
|
return;
|
|
}
|
|
|
|
// Find selected prompt
|
|
const prompts = window.globalState?.mainView?.availablePrompts || [];
|
|
const selectedPrompt = prompts.find(p => String(p.id) === selectedPromptId);
|
|
|
|
if (selectedPrompt) {
|
|
domElements.userMessageInput.value = selectedPrompt.content;
|
|
WorkflowCoordination.userInputState.promptText = selectedPrompt.content;
|
|
domElements.userMessageInput.focus();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends a user response to the workflow based on current state
|
|
*/
|
|
async function sendUserResponse() {
|
|
if (!domElements.userMessageInput) {
|
|
console.error("Error: userMessageInput not found");
|
|
window.utils.ui.showToast("No input available", "error");
|
|
return;
|
|
}
|
|
|
|
// Get user message
|
|
const userMessage = WorkflowCoordination.userInputState.promptText.trim();
|
|
if (!userMessage) {
|
|
window.utils.ui.showToast("Missing Input. Please enter a message", "warning");
|
|
return;
|
|
}
|
|
|
|
// Get current workflow state
|
|
const workflowState = WorkflowCoordination.getWorkflowState();
|
|
|
|
// Set loading state
|
|
WorkflowCoordination.setLoadingState(true);
|
|
|
|
try {
|
|
// Create or continue workflow based on current state
|
|
if (workflowState.workflowId &&
|
|
[WORKFLOW_STATES.COMPLETED, WORKFLOW_STATES.FAILED, WORKFLOW_STATES.STOPPED].includes(workflowState.status)) {
|
|
|
|
// This is a continuation of a completed/failed/stopped workflow
|
|
await continueExistingWorkflow(workflowState.workflowId, userMessage);
|
|
|
|
} else if (workflowState.workflowId && workflowState.status === WORKFLOW_STATES.RUNNING) {
|
|
|
|
// Continuing a running workflow
|
|
await continueRunningWorkflow(workflowState.workflowId, userMessage);
|
|
|
|
} else {
|
|
|
|
// Starting a new workflow
|
|
await createNewWorkflow(userMessage);
|
|
}
|
|
|
|
// Reset input after successful submission
|
|
domElements.userMessageInput.value = '';
|
|
WorkflowCoordination.userInputState.promptText = '';
|
|
WorkflowCoordination.clearAttachedFiles();
|
|
|
|
} catch (error) {
|
|
console.error("Error sending message:", error);
|
|
|
|
// Transition to failed state if we were in running state
|
|
if (workflowState.status === WORKFLOW_STATES.RUNNING) {
|
|
WorkflowCoordination.updateWorkflowStatus(WORKFLOW_STATES.FAILED, {
|
|
message: `Communication error: ${error.message}`,
|
|
systemMessage: "Failed to process your request"
|
|
});
|
|
}
|
|
|
|
window.utils.ui.showToast(`Communication Error: Failed to send message: ${error.message}`, "error");
|
|
} finally {
|
|
// Unlock UI
|
|
WorkflowCoordination.setLoadingState(false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a new workflow with user prompt
|
|
* @param {string} userMessage - User prompt
|
|
*/
|
|
async function createNewWorkflow(userMessage) {
|
|
console.log("Starting new workflow");
|
|
|
|
// Add log entry for starting workflow
|
|
const startLog = WorkflowCoordination.addLogEntry("Starting new workflow...", "info");
|
|
|
|
try {
|
|
// Transition state to running before API call
|
|
WorkflowCoordination.updateWorkflowStatus(WORKFLOW_STATES.RUNNING, {
|
|
message: "Preparing workflow",
|
|
logId: startLog.id
|
|
});
|
|
|
|
// Create new workflow
|
|
const response = await WorkflowData.createWorkflow(
|
|
userMessage,
|
|
WorkflowCoordination.userInputState.additionalFiles
|
|
);
|
|
|
|
if (!response || !response.id) {
|
|
throw new Error("Failed to start workflow: No workflow ID received");
|
|
}
|
|
|
|
// Set active workflow
|
|
WorkflowCoordination.setActiveWorkflow(response.id);
|
|
|
|
// Start polling for updates
|
|
WorkflowData.pollWorkflowStatus(response.id).catch(error => {
|
|
console.error("Error in polling process:", error);
|
|
// Optionally handle the error (e.g., show a notification)
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("Error creating workflow:", error);
|
|
|
|
// Revert to null state
|
|
WorkflowCoordination.updateWorkflowStatus(WORKFLOW_STATES.NULL, {
|
|
message: `Failed to create workflow: ${error.message}`,
|
|
systemMessage: "Failed to start workflow"
|
|
});
|
|
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Continues a completed, failed, or stopped workflow
|
|
* @param {string} workflowId - ID of the workflow
|
|
* @param {string} userMessage - User prompt
|
|
*/
|
|
async function continueExistingWorkflow(workflowId, userMessage) {
|
|
console.log(`Continuing workflow ${workflowId} from ${WorkflowCoordination.getWorkflowStatus()} state`);
|
|
|
|
// Add log entry
|
|
const continueLog = WorkflowCoordination.addLogEntry("Continuing workflow...", "info");
|
|
|
|
try {
|
|
// Transition state to running
|
|
WorkflowCoordination.updateWorkflowStatus(WORKFLOW_STATES.RUNNING, {
|
|
message: "Resuming workflow",
|
|
logId: continueLog.id
|
|
});
|
|
|
|
// Get file IDs
|
|
const additionalFileIds = WorkflowCoordination.userInputState.additionalFiles.map(file => file.id);
|
|
|
|
// Submit user input
|
|
await WorkflowData.submitUserInput(
|
|
workflowId,
|
|
userMessage,
|
|
additionalFileIds
|
|
);
|
|
|
|
// Start polling
|
|
WorkflowData.pollWorkflowStatus(workflowId);
|
|
|
|
} catch (error) {
|
|
console.error("Error continuing workflow:", error);
|
|
|
|
// Revert to previous state
|
|
WorkflowCoordination.updateWorkflowStatus(WORKFLOW_STATES.FAILED, {
|
|
message: `Failed to continue workflow: ${error.message}`,
|
|
systemMessage: "Failed to process your request"
|
|
});
|
|
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Continues a running workflow
|
|
* @param {string} workflowId - ID of the workflow
|
|
* @param {string} userMessage - User prompt
|
|
*/
|
|
async function continueRunningWorkflow(workflowId, userMessage) {
|
|
console.log(`Continuing running workflow ${workflowId}`);
|
|
|
|
try {
|
|
// Get file IDs
|
|
const additionalFileIds = WorkflowCoordination.userInputState.additionalFiles.map(file => file.id);
|
|
|
|
// Submit user input
|
|
await WorkflowData.submitUserInput(
|
|
workflowId,
|
|
userMessage,
|
|
additionalFileIds
|
|
);
|
|
|
|
// Update logs
|
|
WorkflowCoordination.addLogEntry("Continuing workflow with user input", "info");
|
|
|
|
// Make sure we're still in running state
|
|
if (WorkflowCoordination.getWorkflowStatus() !== WORKFLOW_STATES.RUNNING) {
|
|
WorkflowCoordination.updateWorkflowStatus(WORKFLOW_STATES.RUNNING, {
|
|
message: "Processing user input"
|
|
});
|
|
}
|
|
|
|
// Poll for updates
|
|
WorkflowData.pollWorkflowStatus(workflowId);
|
|
|
|
} catch (error) {
|
|
console.error("Error submitting to running workflow:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stops the current workflow
|
|
*/
|
|
async function stopWorkflow() {
|
|
const workflowState = WorkflowCoordination.getWorkflowState();
|
|
|
|
if (!workflowState.workflowId || workflowState.status !== WORKFLOW_STATES.RUNNING) {
|
|
console.warn("No running workflow to stop");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// IMMEDIATELY modify state before async operations
|
|
// This prevents race conditions during workflow stopping
|
|
workflowState.pollActive = false;
|
|
|
|
// Clear polling sequence to prevent orphaned polling
|
|
if (workflowState._pollingSequenceId) {
|
|
workflowState._pollingSequenceId = null;
|
|
}
|
|
|
|
// Add log entry
|
|
WorkflowCoordination.addLogEntry("Stopping workflow...", "warning");
|
|
|
|
// Call API to stop workflow
|
|
await WorkflowData.stopWorkflow(workflowState.workflowId);
|
|
|
|
// Update to stopped status
|
|
WorkflowCoordination.updateWorkflowStatus(WORKFLOW_STATES.STOPPED, {
|
|
message: "Workflow has been stopped",
|
|
systemMessage: "Workflow was manually stopped"
|
|
});
|
|
|
|
console.log("Workflow stopped successfully, polling disabled");
|
|
|
|
} catch (error) {
|
|
console.error("Error stopping workflow:", error);
|
|
|
|
// Log error but still try to update UI state
|
|
WorkflowCoordination.addLogEntry(`Error stopping workflow: ${error.message}`, "error");
|
|
|
|
// Force status to stopped even if API call failed
|
|
WorkflowCoordination.updateWorkflowStatus(WORKFLOW_STATES.STOPPED, {
|
|
message: "Workflow stopped with errors",
|
|
systemMessage: "Workflow was stopped but there were errors"
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resets the workflow completely
|
|
*/
|
|
function resetWorkflow() {
|
|
// Stop any ongoing polling
|
|
workflowState.pollActive = false;
|
|
|
|
// Clear polling sequence to prevent orphaned polling
|
|
if (workflowState._pollingSequenceId) {
|
|
workflowState._pollingSequenceId = null;
|
|
}
|
|
|
|
// Reset state
|
|
workflowState = {
|
|
status: null,
|
|
workflowId: "",
|
|
logs: [],
|
|
chatMessages: [],
|
|
lastPolledLogId: null,
|
|
lastPolledMessageId: null,
|
|
dataStats: {
|
|
bytesSent: 0,
|
|
bytesReceived: 0,
|
|
tokensUsed: 0
|
|
},
|
|
pollFailCount: 0,
|
|
pollActive: false
|
|
};
|
|
|
|
// Reset user input
|
|
userInputState.promptText = "";
|
|
userInputState.additionalFiles = [];
|
|
|
|
// Stop animations
|
|
stopWaitingAnimation();
|
|
|
|
// Dispatch event for UI update
|
|
const event = new CustomEvent('workflowReset');
|
|
document.dispatchEvent(event);
|
|
|
|
console.log("Workflow state reset");
|
|
}
|
|
|
|
/**
|
|
* Handles layout changes
|
|
* @param {Object} layoutConfig - Layout configuration
|
|
*/
|
|
function handleLayoutChange(layoutConfig) {
|
|
console.log("Layout change:", layoutConfig);
|
|
|
|
// Implement layout change handling logic
|
|
if (layoutConfig.collapseHeader) {
|
|
if (domElements.workflowHeader) {
|
|
domElements.workflowHeader.classList.add('collapsed');
|
|
}
|
|
}
|
|
|
|
if (layoutConfig.expandHeader) {
|
|
if (domElements.workflowHeader) {
|
|
domElements.workflowHeader.classList.remove('collapsed');
|
|
}
|
|
}
|
|
|
|
// Force layout adjustment
|
|
setTimeout(() => {
|
|
window.dispatchEvent(new Event('resize'));
|
|
}, 100);
|
|
}
|
|
|
|
// Export the initialization function
|
|
export {
|
|
initWorkflowModule,
|
|
WORKFLOW_STATES
|
|
}; |