automation fixes

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-03 12:24:59 +00:00
parent aa8b8a9756
commit 316cafab1b
14 changed files with 1079 additions and 225 deletions

View File

@@ -140,7 +140,7 @@ class AutomationLogger:
def _get_stage_log_path(self, account_id: int, site_id: int, run_id: str, stage_number: int) -> str:
"""Get stage log file path"""
run_dir = self._get_run_dir(account_id, site_id, run_id)
return os.path.join(run_dir, f'stage_{stage_number}.log')
return os.path.join(run_dir, f'stage_{str(stage_number)}.log')
def _append_to_main_log(self, account_id: int, site_id: int, run_id: str, message: str):
"""Append message to main log file"""

View File

@@ -17,6 +17,7 @@ from igny8_core.auth.models import Account, Site
from igny8_core.modules.planner.models import Keywords, Clusters, ContentIdeas
from igny8_core.modules.writer.models import Tasks, Content, Images
from igny8_core.ai.models import AITaskLog
from igny8_core.ai.engine import AIEngine
# AI Functions
from igny8_core.ai.functions.auto_cluster import AutoClusterFunction
@@ -79,8 +80,8 @@ class AutomationService:
# Check credit balance (with 20% buffer)
required_credits = int(estimated_credits * 1.2)
if self.account.credits_balance < required_credits:
raise ValueError(f"Insufficient credits. Need ~{required_credits}, you have {self.account.credits_balance}")
if self.account.credits < required_credits:
raise ValueError(f"Insufficient credits. Need ~{required_credits}, you have {self.account.credits}")
# Create run_id and log files
run_id = self.logger.start_run(self.account.id, self.site.id, trigger_type)
@@ -102,7 +103,7 @@ class AutomationService:
)
self.logger.log_stage_progress(
run_id, self.account.id, self.site.id, 0,
f"Credit check: Account has {self.account.credits_balance} credits, estimated need: {estimated_credits} credits"
f"Credit check: Account has {self.account.credits} credits, estimated need: {estimated_credits} credits"
)
logger.info(f"[AutomationService] Started run: {run_id}")
@@ -164,10 +165,11 @@ class AutomationService:
stage_number, f"Processing batch {batch_num}/{total_batches} ({len(batch)} keywords)"
)
# Call AI function
result = AutoClusterFunction().execute(
payload={'ids': batch},
account=self.account
# Call AI function via AIEngine
engine = AIEngine(account=self.account)
result = engine.execute(
fn=AutoClusterFunction(),
payload={'ids': batch}
)
# Monitor task
@@ -258,10 +260,11 @@ class AutomationService:
stage_number, f"Generating ideas for cluster: {cluster.name}"
)
# Call AI function
result = GenerateIdeasFunction().execute(
payload={'ids': [cluster.id]},
account=self.account
# Call AI function via AIEngine
engine = AIEngine(account=self.account)
result = engine.execute(
fn=GenerateIdeasFunction(),
payload={'ids': [cluster.id]}
)
# Monitor task
@@ -418,11 +421,10 @@ class AutomationService:
stage_name = "Tasks → Content (AI)"
start_time = time.time()
# Query queued tasks
# Query queued tasks (all queued tasks need content generated)
pending_tasks = Tasks.objects.filter(
site=self.site,
status='queued',
content__isnull=True
status='queued'
)
total_count = pending_tasks.count()
@@ -453,10 +455,11 @@ class AutomationService:
stage_number, f"Generating content for task: {task.title}"
)
# Call AI function
result = GenerateContentFunction().execute(
payload={'ids': [task.id]},
account=self.account
# Call AI function via AIEngine
engine = AIEngine(account=self.account)
result = engine.execute(
fn=GenerateContentFunction(),
payload={'ids': [task.id]}
)
# Monitor task
@@ -551,10 +554,11 @@ class AutomationService:
stage_number, f"Extracting prompts from: {content.title}"
)
# Call AI function
result = GenerateImagePromptsFunction().execute(
payload={'ids': [content.id]},
account=self.account
# Call AI function via AIEngine
engine = AIEngine(account=self.account)
result = engine.execute(
fn=GenerateImagePromptsFunction(),
payload={'ids': [content.id]}
)
# Monitor task
@@ -641,10 +645,11 @@ class AutomationService:
stage_number, f"Generating image: {image.image_type} for '{content_title}'"
)
# Call AI function
result = GenerateImagesFunction().execute(
payload={'image_ids': [image.id]},
account=self.account
# Call AI function via AIEngine
engine = AIEngine(account=self.account)
result = engine.execute(
fn=GenerateImagesFunction(),
payload={'image_ids': [image.id]}
)
# Monitor task

View File

@@ -311,3 +311,117 @@ class AutomationViewSet(viewsets.ViewSet):
'current_balance': site.account.credits,
'sufficient': site.account.credits >= (estimated_credits * 1.2)
})
@action(detail=False, methods=['get'])
def pipeline_overview(self, request):
"""
GET /api/v1/automation/pipeline_overview/?site_id=123
Get pipeline overview with pending counts for all stages
"""
site, error_response = self._get_site(request)
if error_response:
return error_response
from igny8_core.business.planning.models import Keywords, Clusters, ContentIdeas
from igny8_core.business.content.models import Tasks, Content, Images
from django.db.models import Count
# Stage 1: Keywords pending clustering
stage_1_pending = Keywords.objects.filter(
site=site,
status='new',
cluster__isnull=True,
disabled=False
).count()
# Stage 2: Clusters needing ideas
stage_2_pending = Clusters.objects.filter(
site=site,
status='new',
disabled=False
).exclude(
ideas__isnull=False
).count()
# Stage 3: Ideas ready to queue
stage_3_pending = ContentIdeas.objects.filter(
site=site,
status='new'
).count()
# Stage 4: Tasks ready for content generation
# Tasks don't have content FK - check if content exists via task title matching
stage_4_pending = Tasks.objects.filter(
site=site,
status='queued'
).count()
# Stage 5: Content ready for image prompts
stage_5_pending = Content.objects.filter(
site=site,
status='draft'
).annotate(
images_count=Count('images')
).filter(
images_count=0
).count()
# Stage 6: Image prompts ready for generation
stage_6_pending = Images.objects.filter(
site=site,
status='pending'
).count()
# Stage 7: Content ready for review
stage_7_ready = Content.objects.filter(
site=site,
status='review'
).count()
return Response({
'stages': [
{
'number': 1,
'name': 'Keywords → Clusters',
'pending': stage_1_pending,
'type': 'AI'
},
{
'number': 2,
'name': 'Clusters → Ideas',
'pending': stage_2_pending,
'type': 'AI'
},
{
'number': 3,
'name': 'Ideas → Tasks',
'pending': stage_3_pending,
'type': 'Local'
},
{
'number': 4,
'name': 'Tasks → Content',
'pending': stage_4_pending,
'type': 'AI'
},
{
'number': 5,
'name': 'Content → Image Prompts',
'pending': stage_5_pending,
'type': 'AI'
},
{
'number': 6,
'name': 'Image Prompts → Images',
'pending': stage_6_pending,
'type': 'AI'
},
{
'number': 7,
'name': 'Manual Review Gate',
'pending': stage_7_ready,
'type': 'Manual'
}
]
})