From cc8869aeeae4892d633d0071d1de46edf7a76741 Mon Sep 17 00:00:00 2001 From: p <1332606303@qq.com> Date: Wed, 28 Jan 2026 21:08:37 +0800 Subject: [PATCH] fix: add task log --- backend/app/models/models.py | 2 +- backend/app/routers/generation.py | 19 ++++++--- backend/app/services/ai_service.py | 45 +++++++++++++------- frontend/src/views/project/StoryboardTab.vue | 4 +- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/backend/app/models/models.py b/backend/app/models/models.py index be4fb5b..eaab0b5 100644 --- a/backend/app/models/models.py +++ b/backend/app/models/models.py @@ -42,7 +42,6 @@ class TaskBase(SQLModel): status: str # 'pending', 'processing', 'completed', 'failed' progress: int = 0 # 0-100 message: Optional[str] = None - logs: List[str] = Field(default=[], sa_column=Column(JSON)) name: Optional[str] = None description: Optional[str] = None result: Dict = Field(default={}, sa_column=Column(JSON)) @@ -88,6 +87,7 @@ class Task(TaskBase, table=True): project_id: str = Field(foreign_key="project.id") created_at: datetime = Field(default_factory=datetime.utcnow) updated_at: datetime = Field(default_factory=datetime.utcnow) + logs: List[str] = Field(default=[], sa_column=Column(JSON)) project: Project = Relationship(back_populates="tasks") diff --git a/backend/app/routers/generation.py b/backend/app/routers/generation.py index 6ca8fc7..7ec19db 100644 --- a/backend/app/routers/generation.py +++ b/backend/app/routers/generation.py @@ -13,6 +13,7 @@ import traceback import logging import sys +import time # Configure logging logging.basicConfig(level=logging.INFO, stream=sys.stdout) @@ -635,11 +636,19 @@ Ensure the character's expression and pose reflect their personality: {personali """ log_task_event(session, task_id, f"Calling AI service for character {char.name}...") - image_bytes = ai.generate_image( - prompt, - aspect_ratio=char.project.aspect_ratio or "16:9", - resolution=char.project.resolution or "2K" - ) + start_time = time.time() + try: + image_bytes = ai.generate_image( + prompt, + aspect_ratio=char.project.aspect_ratio or "16:9", + resolution=char.project.resolution or "2K" + ) + elapsed = time.time() - start_time + log_task_event(session, task_id, f"AI generation finished in {elapsed:.2f}s. Image size: {len(image_bytes)} bytes.") + except Exception as e: + elapsed = time.time() - start_time + log_task_event(session, task_id, f"AI generation failed after {elapsed:.2f}s: {str(e)}") + raise e relative_url = save_generated_image(session, char.project_id, "character", char.id, image_bytes) diff --git a/backend/app/services/ai_service.py b/backend/app/services/ai_service.py index aeac605..6adc139 100644 --- a/backend/app/services/ai_service.py +++ b/backend/app/services/ai_service.py @@ -1,5 +1,6 @@ import os import time +import logging from typing import List, Optional from sqlmodel import Session from app.models.models import ModelConfig @@ -8,6 +9,8 @@ from google.genai import types from PIL import Image import io +logger = logging.getLogger(__name__) + class AIService: def __init__(self, session: Session): self.session = session @@ -30,15 +33,20 @@ class AIService: full_prompt = f"{system_prompt}\n\nUser Input: {user_input}\n\nPlease generate the full storyboard in JSON format as requested." - try: - response = client.models.generate_content( - model=model_name, - contents=full_prompt - ) - return response.text - except Exception as e: - print(f"Error generating storyboard: {e}") - raise e + max_retries = 3 + for attempt in range(max_retries): + try: + response = client.models.generate_content( + model=model_name, + contents=full_prompt + ) + return response.text + except Exception as e: + logger.error(f"Error generating storyboard (Attempt {attempt + 1}/{max_retries}): {e}") + if attempt < max_retries - 1: + time.sleep(2 ** attempt) + continue + raise e def generate_image(self, prompt: str, context_images: List[str] = None, aspect_ratio: str = "16:9", resolution: str = "2K") -> bytes: client, model_name = self._get_client("image") @@ -51,15 +59,20 @@ class AIService: prev_img = Image.open(img_path) contents.append(prev_img) except Exception as e: - print(f"Failed to load context image {img_path}: {e}") + logger.warning(f"Failed to load context image {img_path}: {e}") else: # Log missing context image but don't fail, just skip it - print(f"Warning: Context image not found at {img_path}, skipping.") + logger.warning(f"Warning: Context image not found at {img_path}, skipping.") # Retry loop max_retries = 3 for attempt in range(max_retries): try: + logger.info(f"DEBUG: Starting image generation attempt {attempt + 1}/{max_retries} with model {model_name}...") + logger.info(f"DEBUG: Prompt length: {len(prompt)}") + if context_images: + logger.info(f"DEBUG: Context images count: {len(context_images)}") + response = client.models.generate_content( model=model_name, contents=contents, @@ -70,28 +83,30 @@ class AIService: ), ) ) + logger.info(f"DEBUG: Generation API call completed for attempt {attempt + 1}") if response.parts: for part in response.parts: if part.inline_data is not None: image_data = part.inline_data.data if len(image_data) > 0: + logger.info(f"DEBUG: Successfully received image data ({len(image_data)} bytes)") return image_data else: - print(f"Warning: Received empty image data on attempt {attempt + 1}") + logger.warning(f"Warning: Received empty image data on attempt {attempt + 1}") # Check for text refusal/error if response.text: - print(f"Model response text (no image): {response.text}") + logger.warning(f"Model response text (no image): {response.text}") - print(f"Attempt {attempt + 1} failed: No valid image data found in response.") + logger.warning(f"Attempt {attempt + 1} failed: No valid image data found in response.") if attempt == max_retries - 1: raise ValueError(f"No image found in response after {max_retries} retries. Last response: {response.text if response.text else 'Empty'}") time.sleep(2 ** attempt) except Exception as e: - print(f"Error generating image (Attempt {attempt + 1}/{max_retries}): {e}") + logger.error(f"Error generating image (Attempt {attempt + 1}/{max_retries}): {e}") if attempt < max_retries - 1: time.sleep(2 ** attempt) continue diff --git a/frontend/src/views/project/StoryboardTab.vue b/frontend/src/views/project/StoryboardTab.vue index 2768297..5c3ead9 100644 --- a/frontend/src/views/project/StoryboardTab.vue +++ b/frontend/src/views/project/StoryboardTab.vue @@ -59,10 +59,10 @@ -
+
- {{ item.data.prompt }} + {{ item.data.prompt || 'No prompt set' }}