Initial commit: THE FACTORY - Iterative Image Generation
Tasks: - image_generate: Generate image from prompt - image_variant: Generate variant of existing image - image_upscale: Increase resolution Models: SDXL, Flux, SDXL-Turbo RunPod Serverless Handler
This commit is contained in:
254
director.py
Normal file
254
director.py
Normal file
@@ -0,0 +1,254 @@
|
||||
"""
|
||||
=============================================================================
|
||||
THE FACTORY - Director
|
||||
=============================================================================
|
||||
Coordina el proceso de generación iterativa.
|
||||
- Prepara contexto para el Executor
|
||||
- Decide cuándo converger
|
||||
- Gestiona presupuesto
|
||||
=============================================================================
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
from config import FactoryConfig, FunctionType
|
||||
|
||||
logger = logging.getLogger("factory.director")
|
||||
|
||||
|
||||
class Director:
|
||||
"""
|
||||
El Director coordina el proceso de generación iterativa.
|
||||
"""
|
||||
|
||||
def __init__(self, config: FactoryConfig):
|
||||
self.config = config
|
||||
|
||||
def prepare_context(
|
||||
self,
|
||||
seed: str,
|
||||
objective: str,
|
||||
function: FunctionType,
|
||||
previous_artifact: Optional[Any],
|
||||
feedback: Optional[str],
|
||||
iteration: int,
|
||||
context: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Prepara el contexto para el Executor.
|
||||
|
||||
Args:
|
||||
seed: Prompt inicial
|
||||
objective: Objetivo a alcanzar
|
||||
function: Tipo de función
|
||||
previous_artifact: Artefacto de iteración anterior
|
||||
feedback: Feedback del Evaluator
|
||||
iteration: Número de iteración actual
|
||||
context: Contexto adicional del usuario
|
||||
|
||||
Returns:
|
||||
Contexto preparado para el Executor
|
||||
"""
|
||||
exec_context = {
|
||||
"seed": seed,
|
||||
"objective": objective,
|
||||
"function": function,
|
||||
"iteration": iteration,
|
||||
"is_first_iteration": iteration == 1,
|
||||
"user_context": context
|
||||
}
|
||||
|
||||
if iteration == 1:
|
||||
# Primera iteración: usar seed directamente
|
||||
exec_context["prompt"] = self._build_initial_prompt(seed, objective, function)
|
||||
else:
|
||||
# Iteraciones posteriores: incorporar feedback
|
||||
exec_context["previous_artifact"] = previous_artifact
|
||||
exec_context["feedback"] = feedback
|
||||
exec_context["prompt"] = self._build_refinement_prompt(
|
||||
seed, objective, function, previous_artifact, feedback, iteration
|
||||
)
|
||||
|
||||
# Seleccionar modelo apropiado
|
||||
exec_context["model"] = self._select_model(function, iteration, context)
|
||||
|
||||
return exec_context
|
||||
|
||||
def _build_initial_prompt(
|
||||
self,
|
||||
seed: str,
|
||||
objective: str,
|
||||
function: FunctionType
|
||||
) -> str:
|
||||
"""Construye prompt para primera iteración."""
|
||||
|
||||
if function == FunctionType.TEXT_GENERATION:
|
||||
return f"""Genera contenido de alta calidad basado en lo siguiente:
|
||||
|
||||
SOLICITUD:
|
||||
{seed}
|
||||
|
||||
OBJETIVO:
|
||||
{objective}
|
||||
|
||||
Proporciona una respuesta completa, bien estructurada y profesional."""
|
||||
|
||||
elif function == FunctionType.CODE_GENERATION:
|
||||
return f"""Genera código de alta calidad basado en lo siguiente:
|
||||
|
||||
SOLICITUD:
|
||||
{seed}
|
||||
|
||||
OBJETIVO:
|
||||
{objective}
|
||||
|
||||
El código debe:
|
||||
- Ser limpio y bien documentado
|
||||
- Seguir mejores prácticas
|
||||
- Incluir manejo de errores apropiado
|
||||
- Ser eficiente y mantenible"""
|
||||
|
||||
elif function == FunctionType.IMAGE_GENERATION:
|
||||
return f"""{seed}
|
||||
|
||||
Style: Professional, high quality, detailed
|
||||
Objective: {objective}"""
|
||||
|
||||
elif function == FunctionType.DOCUMENT_GENERATION:
|
||||
return f"""Genera un documento profesional:
|
||||
|
||||
TIPO DE DOCUMENTO:
|
||||
{seed}
|
||||
|
||||
OBJETIVO:
|
||||
{objective}
|
||||
|
||||
El documento debe ser:
|
||||
- Profesional y bien formateado
|
||||
- Completo con toda la información necesaria
|
||||
- Claro y fácil de leer"""
|
||||
|
||||
else:
|
||||
return f"{seed}\n\nObjective: {objective}"
|
||||
|
||||
def _build_refinement_prompt(
|
||||
self,
|
||||
seed: str,
|
||||
objective: str,
|
||||
function: FunctionType,
|
||||
previous_artifact: Any,
|
||||
feedback: str,
|
||||
iteration: int
|
||||
) -> str:
|
||||
"""Construye prompt para iteraciones de refinamiento."""
|
||||
|
||||
# Truncar artefacto anterior si es muy largo
|
||||
prev_str = str(previous_artifact)
|
||||
if len(prev_str) > 2000:
|
||||
prev_str = prev_str[:2000] + "\n[...truncado...]"
|
||||
|
||||
if function in [FunctionType.TEXT_GENERATION, FunctionType.DOCUMENT_GENERATION]:
|
||||
return f"""Mejora el siguiente contenido basándote en el feedback:
|
||||
|
||||
SOLICITUD ORIGINAL:
|
||||
{seed}
|
||||
|
||||
OBJETIVO:
|
||||
{objective}
|
||||
|
||||
CONTENIDO ANTERIOR (iteración {iteration - 1}):
|
||||
{prev_str}
|
||||
|
||||
FEEDBACK A INCORPORAR:
|
||||
{feedback}
|
||||
|
||||
Genera una versión mejorada que aborde el feedback mientras mantiene los aspectos positivos."""
|
||||
|
||||
elif function == FunctionType.CODE_GENERATION:
|
||||
return f"""Mejora el siguiente código basándote en el feedback:
|
||||
|
||||
SOLICITUD ORIGINAL:
|
||||
{seed}
|
||||
|
||||
OBJETIVO:
|
||||
{objective}
|
||||
|
||||
CÓDIGO ANTERIOR (iteración {iteration - 1}):
|
||||
```
|
||||
{prev_str}
|
||||
```
|
||||
|
||||
FEEDBACK A INCORPORAR:
|
||||
{feedback}
|
||||
|
||||
Genera una versión mejorada del código."""
|
||||
|
||||
elif function == FunctionType.IMAGE_GENERATION:
|
||||
return f"""{seed}
|
||||
|
||||
Previous attempt feedback: {feedback}
|
||||
Iteration: {iteration}
|
||||
Objective: {objective}
|
||||
Improve based on feedback while maintaining the core concept."""
|
||||
|
||||
else:
|
||||
return f"""Mejora basándote en el feedback:
|
||||
|
||||
Original: {seed}
|
||||
Objetivo: {objective}
|
||||
Anterior: {prev_str}
|
||||
Feedback: {feedback}
|
||||
|
||||
Genera versión mejorada."""
|
||||
|
||||
def _select_model(
|
||||
self,
|
||||
function: FunctionType,
|
||||
iteration: int,
|
||||
context: Dict[str, Any]
|
||||
) -> str:
|
||||
"""Selecciona el modelo apropiado."""
|
||||
|
||||
# Si el usuario especificó un modelo, usarlo
|
||||
if "model" in context:
|
||||
return context["model"]
|
||||
|
||||
# Por defecto, usar el modelo configurado para la función
|
||||
return self.config.default_models.get(function, "claude-sonnet")
|
||||
|
||||
def should_converge(
|
||||
self,
|
||||
confidence: float,
|
||||
iteration: int,
|
||||
previous_confidence: float,
|
||||
budget_used: float,
|
||||
budget_total: float
|
||||
) -> bool:
|
||||
"""
|
||||
Decide si el job debe converger.
|
||||
|
||||
Criterios:
|
||||
1. Umbral de confianza alcanzado
|
||||
2. Rendimientos decrecientes (mejora < threshold)
|
||||
3. Presupuesto casi agotado
|
||||
"""
|
||||
|
||||
# 1. Umbral de confianza
|
||||
if confidence >= self.config.convergence_threshold:
|
||||
logger.info(f"Convergencia por umbral: {confidence:.2f} >= {self.config.convergence_threshold}")
|
||||
return True
|
||||
|
||||
# 2. Rendimientos decrecientes
|
||||
if iteration > 1 and confidence >= self.config.diminishing_returns_min_confidence:
|
||||
improvement = confidence - previous_confidence
|
||||
if improvement < self.config.diminishing_returns_threshold:
|
||||
logger.info(f"Convergencia por rendimientos decrecientes: mejora {improvement:.3f} < {self.config.diminishing_returns_threshold}")
|
||||
return True
|
||||
|
||||
# 3. Presupuesto casi agotado (>90% usado)
|
||||
if budget_used >= budget_total * 0.9:
|
||||
logger.info(f"Convergencia por presupuesto: ${budget_used:.4f} >= 90% de ${budget_total:.4f}")
|
||||
return True
|
||||
|
||||
return False
|
||||
Reference in New Issue
Block a user