multi-agent-system / instructor.py
factorstudios's picture
Create instructor.py
70ac245 verified
Raw
History Blame Contribute Delete
4.01 kB
"""Instructor module for generating storytelling briefs from trending topics."""
import os
import json
import logging
from typing import Any, Dict, List, Optional
from base_agent import BaseAgent
from config import settings
logger = logging.getLogger(__name__)
class Instructor(BaseAgent):
"""Instructor Agent: Fuses trending topics into storytelling briefs.
This agent uses Instructor.md as a persistent pre-prompt and calls the
DashScope API using the Qwen model specified in the environment.
"""
def __init__(self):
"""Initialize the Instructor agent with guidelines from Instructor.md."""
# Load guidelines from the root folder
content = self._load_instructor_md()
# Construct the full system prompt (pre-prompt)
system_prompt = f"""You are the Instructor Agent, a master of viral storytelling and audience psychology.
Your primary role is to take trending topics and fuse them into compelling, viral-ready storytelling briefs.
### YOUR CORE PRINCIPLES (from Instructor.md):
{content}
### YOUR OBJECTIVE:
1. Analyze the trending topics provided by the user.
2. Synthesize these trends into a single, cohesive storytelling concept.
3. Ensure the concept leverages human psychology (relatability, conflict, transformation).
4. Output a structured JSON brief that will drive the multi-agent writing pipeline.
### OUTPUT JSON STRUCTURE:
{{
"user_brief": "The main story prompt/premise based on the trends.",
"hook_brief": "A specific 3-second hook to grab attention.",
"style_guide": "The visual and tonal style (e.g., 'TikTok relatable comedy').",
"character_bible": "Brief description of the key characters.",
"world_building_document": "The setting and world rules.",
"season_arc_document": "How this episode fits into a larger context.",
"character_voice_guide": "How characters should speak.",
"continuity_log": "The starting state of the world."
}}
"""
super().__init__(
agent_id="instructor",
agent_name="Instructor",
system_prompt=system_prompt
)
def _load_instructor_md(self) -> str:
"""Load the Instructor.md file from the root directory."""
try:
# Look for Instructor.md in the current working directory (root)
path = "Instructor.md"
if not os.path.exists(path):
# Fallback to the directory of this file
path = os.path.join(os.path.dirname(__file__), "Instructor.md")
with open(path, "r") as f:
return f.read()
except Exception as e:
logger.error(f"Failed to load Instructor.md: {str(e)}")
return "Master viral storytelling and audience psychology."
def generate_brief(self, trending_topics: List[str]) -> Dict[str, Any]:
"""Generate a storytelling brief from trending topics using the LLM.
Args:
trending_topics: List of topics to fuse.
Returns:
Dictionary containing the brief fields.
"""
inputs = {
"trending_topics": trending_topics,
"instruction": "Fuse these trending topics into a viral storytelling brief following your core principles."
}
logger.info(f"[INSTRUCTOR] Calling DashScope API (Model: {settings.model_name}) to generate brief...")
# Use the BaseAgent's process method which calls the LLM (DashScope/Qwen)
brief = self.process(inputs)
# Validation and defaults for the pipeline
required = [
"user_brief", "hook_brief", "style_guide", "character_bible",
"world_building_document", "season_arc_document",
"character_voice_guide", "continuity_log"
]
for field in required:
if field not in brief:
brief[field] = f"Auto-generated {field.replace('_', ' ')}."
return brief