Implement V2 AI functions and enhance progress handling
- Added support for new V2 functions: `auto_cluster_v2` and `generate_ideas_v2`, including backend logic and API endpoints. - Updated model configuration to ensure V2 functions validate the presence of models before execution. - Enhanced progress modal to provide better feedback during asynchronous tasks, including task IDs for debugging. - Updated frontend components to integrate new V2 functionalities and improve user experience with clustering and idea generation.
This commit is contained in:
@@ -232,8 +232,10 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
`/v1/system/settings/task_progress/${taskId}/`
|
||||
);
|
||||
|
||||
// Helper function to start auto-increment progress (1% every 350ms until 80%)
|
||||
// Only runs when no backend updates are coming (smooth fill-in animation)
|
||||
// Helper function to start auto-increment progress
|
||||
// 0-50%: 300ms per 1%
|
||||
// 50-80%: 500ms per 1%
|
||||
// If stuck at 80%: 1% per 500ms
|
||||
const startAutoIncrement = () => {
|
||||
// Clear any existing auto-increment interval
|
||||
if (autoIncrementIntervalRef.current) {
|
||||
@@ -241,11 +243,10 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
autoIncrementIntervalRef.current = null;
|
||||
}
|
||||
|
||||
// Only start if we're below 80% and status is processing
|
||||
// Only start if we're below 100% and status is processing
|
||||
const current = displayedPercentageRef.current;
|
||||
if (current < 80) {
|
||||
// Use a slightly longer interval to avoid conflicts with backend updates
|
||||
autoIncrementIntervalRef.current = setInterval(() => {
|
||||
if (current < 100) {
|
||||
const doIncrement = () => {
|
||||
setProgress(prev => {
|
||||
// Check current status - stop if not processing
|
||||
if (prev.status !== 'processing') {
|
||||
@@ -257,17 +258,30 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
}
|
||||
|
||||
const currentPercent = displayedPercentageRef.current;
|
||||
// Only increment if still below 80%
|
||||
if (currentPercent < 80) {
|
||||
const newPercentage = Math.min(currentPercent + 1, 80);
|
||||
let newPercentage = currentPercent;
|
||||
let nextInterval = 300; // Default 300ms
|
||||
|
||||
if (currentPercent < 50) {
|
||||
// 0-50%: 300ms per 1%
|
||||
newPercentage = Math.min(currentPercent + 1, 50);
|
||||
nextInterval = 300;
|
||||
} else if (currentPercent < 80) {
|
||||
// 50-80%: 500ms per 1%
|
||||
newPercentage = Math.min(currentPercent + 1, 80);
|
||||
nextInterval = 500;
|
||||
} else if (currentPercent < 100) {
|
||||
// Stuck at 80%+: 1% per 500ms
|
||||
newPercentage = Math.min(currentPercent + 1, 99);
|
||||
nextInterval = 500;
|
||||
}
|
||||
|
||||
if (newPercentage > currentPercent && newPercentage < 100) {
|
||||
displayedPercentageRef.current = newPercentage;
|
||||
|
||||
// Stop if we've reached 80%
|
||||
if (newPercentage >= 80) {
|
||||
if (autoIncrementIntervalRef.current) {
|
||||
clearInterval(autoIncrementIntervalRef.current);
|
||||
autoIncrementIntervalRef.current = null;
|
||||
}
|
||||
// Restart interval with new speed if needed
|
||||
if (autoIncrementIntervalRef.current) {
|
||||
clearInterval(autoIncrementIntervalRef.current);
|
||||
autoIncrementIntervalRef.current = setInterval(doIncrement, nextInterval);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -275,7 +289,7 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
percentage: newPercentage,
|
||||
};
|
||||
} else {
|
||||
// Stop if we've reached 80%
|
||||
// Stop if we've reached 100% or can't increment
|
||||
if (autoIncrementIntervalRef.current) {
|
||||
clearInterval(autoIncrementIntervalRef.current);
|
||||
autoIncrementIntervalRef.current = null;
|
||||
@@ -283,7 +297,11 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
return prev;
|
||||
}
|
||||
});
|
||||
}, 350); // Slightly longer interval to reduce conflicts
|
||||
};
|
||||
|
||||
// Start with appropriate interval based on current percentage
|
||||
const initialInterval = current < 50 ? 300 : 500;
|
||||
autoIncrementIntervalRef.current = setInterval(doIncrement, initialInterval);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -387,19 +405,20 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
const safeTargetPercentage = Math.max(targetPercentage, currentDisplayedPercentage);
|
||||
|
||||
// Smooth progress animation: increment gradually until reaching target
|
||||
// Use smaller increments and faster updates for smoother animation
|
||||
// Speed: 300ms per 1% until 50%, then 500ms per 1%
|
||||
if (safeTargetPercentage > currentDisplayedPercentage) {
|
||||
// Start smooth animation
|
||||
let animatedPercentage = currentDisplayedPercentage;
|
||||
const animateProgress = () => {
|
||||
if (animatedPercentage < safeTargetPercentage) {
|
||||
// Calculate increment based on distance for smooth animation
|
||||
const diff = safeTargetPercentage - animatedPercentage;
|
||||
// Use smaller increments for smoother feel
|
||||
// If close (< 5%), increment by 1, otherwise by 2
|
||||
const increment = diff <= 5 ? 1 : Math.min(2, Math.ceil(diff / 10));
|
||||
// Always increment by 1%
|
||||
const increment = 1;
|
||||
animatedPercentage = Math.min(animatedPercentage + increment, safeTargetPercentage);
|
||||
displayedPercentageRef.current = animatedPercentage;
|
||||
|
||||
// Determine speed based on current percentage
|
||||
const speed = animatedPercentage < 50 ? 300 : 500; // 300ms until 50%, then 500ms
|
||||
|
||||
setProgress({
|
||||
percentage: animatedPercentage,
|
||||
message: friendlyMessage,
|
||||
@@ -414,13 +433,17 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
});
|
||||
|
||||
if (animatedPercentage < safeTargetPercentage) {
|
||||
// Smooth updates: 150ms for better UX
|
||||
stepTransitionTimeoutRef.current = setTimeout(animateProgress, 150);
|
||||
// Use appropriate speed based on current percentage
|
||||
const nextSpeed = animatedPercentage < 50 ? 300 : 500;
|
||||
stepTransitionTimeoutRef.current = setTimeout(animateProgress, nextSpeed);
|
||||
} else {
|
||||
stepTransitionTimeoutRef.current = null;
|
||||
// After reaching target, start auto-increment if below 80% and no backend update pending
|
||||
if (safeTargetPercentage < 80) {
|
||||
startAutoIncrement();
|
||||
} else if (safeTargetPercentage >= 80 && safeTargetPercentage < 100) {
|
||||
// If at 80%+, start slow auto-increment (1% per 500ms)
|
||||
startAutoIncrement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -435,7 +458,8 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
} else {
|
||||
// Same step or first step - start animation immediately
|
||||
currentStepRef.current = currentStep;
|
||||
animateProgress();
|
||||
const initialSpeed = currentDisplayedPercentage < 50 ? 300 : 500;
|
||||
stepTransitionTimeoutRef.current = setTimeout(animateProgress, initialSpeed);
|
||||
}
|
||||
} else {
|
||||
// Target is same or less than current - just update message and details
|
||||
@@ -455,6 +479,9 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
// Start auto-increment if below 80% and no backend update
|
||||
if (currentDisplayedPercentage < 80 && safeTargetPercentage === currentDisplayedPercentage) {
|
||||
startAutoIncrement();
|
||||
} else if (currentDisplayedPercentage >= 80 && currentDisplayedPercentage < 100) {
|
||||
// If at 80%+, start slow auto-increment (1% per 500ms)
|
||||
startAutoIncrement();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,26 +554,61 @@ export function useProgressModal(): UseProgressModalReturn {
|
||||
} else if (response.state === 'SUCCESS') {
|
||||
const meta = response.meta || {};
|
||||
|
||||
// Clear any existing transition timeout
|
||||
// Clear any existing transition timeout and auto-increment
|
||||
if (stepTransitionTimeoutRef.current) {
|
||||
clearTimeout(stepTransitionTimeoutRef.current);
|
||||
stepTransitionTimeoutRef.current = null;
|
||||
}
|
||||
if (autoIncrementIntervalRef.current) {
|
||||
clearInterval(autoIncrementIntervalRef.current);
|
||||
autoIncrementIntervalRef.current = null;
|
||||
}
|
||||
|
||||
// Get completion message with extracted values
|
||||
const completionMessage = meta.message || '';
|
||||
const allSteps = [...(meta.request_steps || []), ...(meta.response_steps || [])];
|
||||
const stepInfo = getStepInfo('DONE', completionMessage, allSteps);
|
||||
|
||||
// Update to 100% with user-friendly completion message
|
||||
currentStepRef.current = 'DONE';
|
||||
displayedPercentageRef.current = 100;
|
||||
setProgress({
|
||||
percentage: 100,
|
||||
message: stepInfo.friendlyMessage,
|
||||
status: 'completed',
|
||||
details: meta.details,
|
||||
});
|
||||
// Smooth completion animation: 5% per 500ms until 100%
|
||||
const currentPercent = displayedPercentageRef.current;
|
||||
if (currentPercent < 100) {
|
||||
const animateToCompletion = () => {
|
||||
const current = displayedPercentageRef.current;
|
||||
if (current < 100) {
|
||||
const increment = Math.min(5, 100 - current); // 5% per step, or remaining if less
|
||||
const newPercentage = current + increment;
|
||||
displayedPercentageRef.current = newPercentage;
|
||||
|
||||
setProgress({
|
||||
percentage: newPercentage,
|
||||
message: stepInfo.friendlyMessage,
|
||||
status: 'completed',
|
||||
details: meta.details,
|
||||
});
|
||||
|
||||
if (newPercentage < 100) {
|
||||
stepTransitionTimeoutRef.current = setTimeout(animateToCompletion, 500);
|
||||
} else {
|
||||
currentStepRef.current = 'DONE';
|
||||
}
|
||||
} else {
|
||||
currentStepRef.current = 'DONE';
|
||||
}
|
||||
};
|
||||
|
||||
currentStepRef.current = 'DONE';
|
||||
animateToCompletion();
|
||||
} else {
|
||||
// Already at 100%, just update message and status
|
||||
currentStepRef.current = 'DONE';
|
||||
displayedPercentageRef.current = 100;
|
||||
setProgress({
|
||||
percentage: 100,
|
||||
message: stepInfo.friendlyMessage,
|
||||
status: 'completed',
|
||||
details: meta.details,
|
||||
});
|
||||
}
|
||||
|
||||
// Update final step logs
|
||||
if (meta.request_steps || meta.response_steps) {
|
||||
|
||||
Reference in New Issue
Block a user