Enhance image processing and error handling in AICore and tasks

- Improved response parsing in AICore to handle both array and dictionary formats, including detailed error logging.
- Updated image directory handling in tasks to prioritize web-accessible paths for image storage, with robust fallback mechanisms.
- Adjusted image URL generation in serializers and frontend components to support new directory structure and ensure proper accessibility.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-12 04:45:13 +00:00
parent c29ecc1664
commit 03909a1fab
4 changed files with 179 additions and 61 deletions

View File

@@ -25,6 +25,24 @@ interface ContentImageCellProps {
export default function ContentImageCell({ image, maxPromptLength = 100 }: ContentImageCellProps) {
const [showFullPrompt, setShowFullPrompt] = useState(false);
// Convert local file path to web-accessible URL
const getLocalImageUrl = (imagePath: string): string => {
// If path contains 'ai-images', convert to web URL
if (imagePath.includes('ai-images')) {
const filename = imagePath.split('ai-images/')[1] || imagePath.split('ai-images\\')[1];
if (filename) {
return `/images/ai-images/${filename}`;
}
}
// If path is already a web path, return as-is
if (imagePath.startsWith('/images/')) {
return imagePath;
}
// Otherwise, try to extract filename and use ai-images path
const filename = imagePath.split('/').pop() || imagePath.split('\\').pop();
return `/images/ai-images/${filename}`;
};
if (!image) {
return (
<div className="text-gray-400 dark:text-gray-500 text-sm">-</div>
@@ -77,34 +95,69 @@ export default function ContentImageCell({ image, maxPromptLength = 100 }: Conte
</div>
)}
{image.status === 'generated' && image.image_url && (
<a
href={image.image_url}
target="_blank"
rel="noopener noreferrer"
className="block group"
>
<img
src={image.image_url}
alt={prompt || 'Generated image'}
className="w-full h-24 object-cover rounded border border-gray-300 dark:border-gray-600 group-hover:opacity-80 transition-opacity"
onError={(e) => {
// Fallback to placeholder if image fails to load
const target = e.target as HTMLImageElement;
target.style.display = 'none';
target.parentElement!.innerHTML = `
<div class="w-full h-24 bg-gray-200 dark:bg-gray-700 rounded border-2 border-dashed border-gray-300 dark:border-gray-600 flex items-center justify-center">
<p class="text-xs text-gray-500 dark:text-gray-400">Image not available</p>
</div>
`;
}}
/>
</a>
)}
{image.status === 'generated' && !image.image_url && (
<div className="w-full h-24 bg-yellow-100 dark:bg-yellow-900/20 rounded border border-yellow-300 dark:border-yellow-700 flex items-center justify-center">
<p className="text-xs text-yellow-700 dark:text-yellow-400">No URL available</p>
{image.status === 'generated' && (
<div className="space-y-1">
{/* Show local image if available, otherwise show original URL */}
{image.image_path ? (
<>
<img
src={getLocalImageUrl(image.image_path)}
alt={prompt || 'Generated image'}
className="w-full h-24 object-cover rounded border border-gray-300 dark:border-gray-600"
onError={(e) => {
// Fallback to original URL if local image fails
const target = e.target as HTMLImageElement;
if (image.image_url) {
target.src = image.image_url;
} else {
target.style.display = 'none';
target.parentElement!.innerHTML = `
<div class="w-full h-24 bg-gray-200 dark:bg-gray-700 rounded border-2 border-dashed border-gray-300 dark:border-gray-600 flex items-center justify-center">
<p class="text-xs text-gray-500 dark:text-gray-400">Image not available</p>
</div>
`;
}
}}
/>
{image.image_url && (
<a
href={image.image_url}
target="_blank"
rel="noopener noreferrer"
className="block w-full text-center px-2 py-1 text-xs text-brand-500 hover:text-brand-600 dark:text-brand-400 dark:hover:text-brand-300 border border-brand-300 dark:border-brand-700 rounded hover:bg-brand-50 dark:hover:bg-brand-900/20 transition-colors"
>
View Original
</a>
)}
</>
) : image.image_url ? (
<a
href={image.image_url}
target="_blank"
rel="noopener noreferrer"
className="block group"
>
<img
src={image.image_url}
alt={prompt || 'Generated image'}
className="w-full h-24 object-cover rounded border border-gray-300 dark:border-gray-600 group-hover:opacity-80 transition-opacity"
onError={(e) => {
// Fallback to placeholder if image fails to load
const target = e.target as HTMLImageElement;
target.style.display = 'none';
target.parentElement!.innerHTML = `
<div class="w-full h-24 bg-gray-200 dark:bg-gray-700 rounded border-2 border-dashed border-gray-300 dark:border-gray-600 flex items-center justify-center">
<p class="text-xs text-gray-500 dark:text-gray-400">Image not available</p>
</div>
`;
}}
/>
</a>
) : (
<div className="w-full h-24 bg-yellow-100 dark:bg-yellow-900/20 rounded border border-yellow-300 dark:border-yellow-700 flex items-center justify-center">
<p className="text-xs text-yellow-700 dark:text-yellow-400">No URL available</p>
</div>
)}
</div>
)}