This commit is contained in:
+38
-10
@@ -58,8 +58,8 @@ class GenerateRequest(BaseModel):
|
|||||||
framework: str = Field("snowflake", description="Story framework")
|
framework: str = Field("snowflake", description="Story framework")
|
||||||
genre: str = Field("fiction", description="Genre")
|
genre: str = Field("fiction", description="Genre")
|
||||||
book_type: str = Field("fiction", description="Book type (fiction/nonfiction)")
|
book_type: str = Field("fiction", description="Book type (fiction/nonfiction)")
|
||||||
target_word_count: int = Field(5000, description="Target word count")
|
target_word_count: int = Field(5000, ge=1, le=500000, description="Target word count")
|
||||||
chapters: int = Field(3, description="Number of chapters")
|
chapters: int = Field(3, ge=1, le=100, description="Number of chapters")
|
||||||
tone: str = Field("literary", description="Writing tone")
|
tone: str = Field("literary", description="Writing tone")
|
||||||
use_crewai: bool = Field(False, description="Use CrewAI instead of LangGraph")
|
use_crewai: bool = Field(False, description="Use CrewAI instead of LangGraph")
|
||||||
use_autogen: bool = Field(True, description="Use AutoGen critique")
|
use_autogen: bool = Field(True, description="Use AutoGen critique")
|
||||||
@@ -312,17 +312,45 @@ async def generate_stream(request: GenerateRequest):
|
|||||||
yield "data: " + json.dumps({"status": "ingested", "message": f"Ingested {len(seed_concept)} characters"}) + "\n\n"
|
yield "data: " + json.dumps({"status": "ingested", "message": f"Ingested {len(seed_concept)} characters"}) + "\n\n"
|
||||||
|
|
||||||
if not seed_concept:
|
if not seed_concept:
|
||||||
raise HTTPException(status_code=400, detail="Must provide concept or repo")
|
yield "data: " + json.dumps({"status": "error", "message": "Must provide concept or repo"}) + "\n\n"
|
||||||
|
return
|
||||||
|
|
||||||
# For now, just stream a completion message
|
# Call run_opus and return real result
|
||||||
# Full streaming requires modifying the LangGraph workflow
|
|
||||||
yield "data: " + json.dumps({"status": "generating", "progress": 0.1, "message": "Starting generation..."}) + "\n\n"
|
yield "data: " + json.dumps({"status": "generating", "progress": 0.1, "message": "Starting generation..."}) + "\n\n"
|
||||||
|
|
||||||
# TODO: Implement actual streaming from LangGraph workflow
|
try:
|
||||||
# This requires modifying run_opus to yield progress events
|
result = await run_opus(
|
||||||
yield "data: " + json.dumps({"status": "generating", "progress": 0.5, "message": "Generating manuscript..."}) + "\n\n"
|
seed_concept=seed_concept,
|
||||||
|
framework=request.framework,
|
||||||
yield "data: " + json.dumps({"status": "complete", "progress": 1.0, "message": "Generation complete"}) + "\n\n"
|
genre=request.genre,
|
||||||
|
target_word_count=request.target_word_count,
|
||||||
|
)
|
||||||
|
|
||||||
|
yield "data: " + json.dumps({"status": "generating", "progress": 0.5, "message": "Processing result..."}) + "\n\n"
|
||||||
|
|
||||||
|
# Extract manuscript from result
|
||||||
|
if isinstance(result, dict):
|
||||||
|
manuscript = result.get("manuscript", "")
|
||||||
|
if not manuscript:
|
||||||
|
chapters = result.get("chapters", [])
|
||||||
|
if chapters:
|
||||||
|
manuscript = "\n\n---\n\n".join(str(c) for c in chapters)
|
||||||
|
else:
|
||||||
|
manuscript = str(result)
|
||||||
|
else:
|
||||||
|
manuscript = str(result)
|
||||||
|
|
||||||
|
word_count = len(manuscript.split())
|
||||||
|
|
||||||
|
yield "data: " + json.dumps({
|
||||||
|
"status": "complete",
|
||||||
|
"progress": 1.0,
|
||||||
|
"message": f"Generation complete ({word_count} words)",
|
||||||
|
"manuscript": manuscript[:1000] + "..." if len(manuscript) > 1000 else manuscript
|
||||||
|
}) + "\n\n"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
yield "data: " + json.dumps({"status": "error", "message": str(e)}) + "\n\n"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
yield "data: " + json.dumps({"status": "error", "message": str(e)}) + "\n\n"
|
yield "data: " + json.dumps({"status": "error", "message": str(e)}) + "\n\n"
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class LLMClient:
|
|||||||
model: str = "MiniMax/MiniMax-M2.1",
|
model: str = "MiniMax/MiniMax-M2.1",
|
||||||
base_url: Optional[str] = None,
|
base_url: Optional[str] = None,
|
||||||
max_retries: int = 3,
|
max_retries: int = 3,
|
||||||
|
timeout: float = 120.0,
|
||||||
):
|
):
|
||||||
"""Initialize LLM client.
|
"""Initialize LLM client.
|
||||||
|
|
||||||
@@ -36,10 +37,12 @@ class LLMClient:
|
|||||||
model: Model name
|
model: Model name
|
||||||
base_url: Optional custom base URL
|
base_url: Optional custom base URL
|
||||||
max_retries: Maximum retry attempts (default 3)
|
max_retries: Maximum retry attempts (default 3)
|
||||||
|
timeout: HTTP timeout in seconds (default 120.0)
|
||||||
"""
|
"""
|
||||||
self.api_key = api_key or os.environ.get("MINIMAX_API_KEY") or os.environ.get("OPENAI_API_KEY")
|
self.api_key = api_key or os.environ.get("MINIMAX_API_KEY") or os.environ.get("OPENAI_API_KEY")
|
||||||
self.provider = provider
|
self.provider = provider
|
||||||
self.model = model
|
self.model = model
|
||||||
|
self.timeout = timeout
|
||||||
|
|
||||||
# Normalize model name for MiniMax
|
# Normalize model name for MiniMax
|
||||||
if provider == "minimax":
|
if provider == "minimax":
|
||||||
@@ -56,8 +59,8 @@ class LLMClient:
|
|||||||
else:
|
else:
|
||||||
self.base_url = "https://api.openai.com/v1"
|
self.base_url = "https://api.openai.com/v1"
|
||||||
|
|
||||||
# Async client
|
# Async client with configurable timeout
|
||||||
self._async_client = httpx.AsyncClient(timeout=120.0)
|
self._async_client = httpx.AsyncClient(timeout=self.timeout)
|
||||||
|
|
||||||
# Initialize retry handler
|
# Initialize retry handler
|
||||||
retry_config = RetryConfig(
|
retry_config = RetryConfig(
|
||||||
@@ -307,4 +310,5 @@ def get_llm_client(config: Optional[Any] = None) -> LLMClient:
|
|||||||
api_key=cfg.agent.api_key,
|
api_key=cfg.agent.api_key,
|
||||||
provider=cfg.agent.provider,
|
provider=cfg.agent.provider,
|
||||||
model=cfg.agent.model,
|
model=cfg.agent.model,
|
||||||
|
timeout=getattr(cfg.agent, 'timeout', 120.0),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user