Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1723,7 +1723,177 @@ You consider all perspectives: producers, actors, audience.
|
|
1723 |
You provide feedback that's critical yet encouraging."""
|
1724 |
}
|
1725 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1726 |
|
|
|
|
|
1727 |
def _parse_character_profile(self, content: str, role: str) -> CharacterProfile:
|
1728 |
"""Parse character profile from content"""
|
1729 |
# Extract character details using regex or string parsing
|
|
|
1723 |
You provide feedback that's critical yet encouraging."""
|
1724 |
}
|
1725 |
}
|
1726 |
+
|
1727 |
+
return base_prompts.get(language, base_prompts["English"])
|
1728 |
+
|
1729 |
+
|
1730 |
+
|
1731 |
+
# --- Main process ---
|
1732 |
+
def process_screenplay_stream(self, query: str, screenplay_type: str, genre: str,
|
1733 |
+
language: str, session_id: Optional[str] = None
|
1734 |
+
) -> Generator[Tuple[str, List[Dict[str, Any]], str], None, None]:
|
1735 |
+
"""Main screenplay generation process"""
|
1736 |
+
try:
|
1737 |
+
resume_from_stage = 0
|
1738 |
+
if session_id:
|
1739 |
+
self.current_session_id = session_id
|
1740 |
+
session = ScreenplayDatabase.get_session(session_id)
|
1741 |
+
if session:
|
1742 |
+
query = session['user_query']
|
1743 |
+
screenplay_type = session['screenplay_type']
|
1744 |
+
genre = session['genre']
|
1745 |
+
language = session['language']
|
1746 |
+
resume_from_stage = session['current_stage'] + 1
|
1747 |
+
else:
|
1748 |
+
self.current_session_id = ScreenplayDatabase.create_session(
|
1749 |
+
query, screenplay_type, genre, language
|
1750 |
+
)
|
1751 |
+
logger.info(f"Created new screenplay session: {self.current_session_id}")
|
1752 |
+
|
1753 |
+
stages = []
|
1754 |
+
if resume_from_stage > 0:
|
1755 |
+
# Get existing stages from database
|
1756 |
+
db_stages = ScreenplayDatabase.get_stages(self.current_session_id)
|
1757 |
+
stages = [{
|
1758 |
+
"name": s['stage_name'],
|
1759 |
+
"status": s['status'],
|
1760 |
+
"content": s.get('content', ''),
|
1761 |
+
"page_count": s.get('page_count', 0)
|
1762 |
+
} for s in db_stages]
|
1763 |
+
|
1764 |
+
for stage_idx in range(resume_from_stage, len(SCREENPLAY_STAGES)):
|
1765 |
+
role, stage_name = SCREENPLAY_STAGES[stage_idx]
|
1766 |
+
|
1767 |
+
if stage_idx >= len(stages):
|
1768 |
+
stages.append({
|
1769 |
+
"name": stage_name,
|
1770 |
+
"status": "active",
|
1771 |
+
"content": "",
|
1772 |
+
"page_count": 0
|
1773 |
+
})
|
1774 |
+
else:
|
1775 |
+
stages[stage_idx]["status"] = "active"
|
1776 |
+
|
1777 |
+
yield f"🔄 Processing {stage_name}...", stages, self.current_session_id
|
1778 |
+
|
1779 |
+
prompt = self.get_stage_prompt(stage_idx, role, query, screenplay_type,
|
1780 |
+
genre, language, stages)
|
1781 |
+
stage_content = ""
|
1782 |
+
|
1783 |
+
for chunk in self.call_llm_streaming([{"role": "user", "content": prompt}],
|
1784 |
+
role, language):
|
1785 |
+
stage_content += chunk
|
1786 |
+
stages[stage_idx]["content"] = stage_content
|
1787 |
+
if role == "screenwriter":
|
1788 |
+
stages[stage_idx]["page_count"] = len(stage_content.split('\n')) / 55
|
1789 |
+
yield f"🔄 {stage_name} in progress...", stages, self.current_session_id
|
1790 |
+
|
1791 |
+
# Process content based on role
|
1792 |
+
if role == "producer":
|
1793 |
+
self._process_producer_content(stage_content)
|
1794 |
+
elif role == "story_developer":
|
1795 |
+
self._process_story_content(stage_content)
|
1796 |
+
elif role == "character_designer":
|
1797 |
+
self._process_character_content(stage_content)
|
1798 |
+
elif role == "scene_planner":
|
1799 |
+
self._process_scene_content(stage_content)
|
1800 |
+
|
1801 |
+
stages[stage_idx]["status"] = "complete"
|
1802 |
+
ScreenplayDatabase.save_stage(
|
1803 |
+
self.current_session_id, stage_idx, stage_name, role,
|
1804 |
+
stage_content, "complete"
|
1805 |
+
)
|
1806 |
+
|
1807 |
+
yield f"✅ {stage_name} completed", stages, self.current_session_id
|
1808 |
+
|
1809 |
+
# Final processing
|
1810 |
+
final_screenplay = ScreenplayDatabase.get_screenplay_content(self.current_session_id)
|
1811 |
+
title = self.screenplay_tracker.screenplay_bible.title
|
1812 |
+
logline = self.screenplay_tracker.screenplay_bible.logline
|
1813 |
+
|
1814 |
+
ScreenplayDatabase.update_final_screenplay(
|
1815 |
+
self.current_session_id, final_screenplay, title, logline
|
1816 |
+
)
|
1817 |
+
|
1818 |
+
yield f"✅ Screenplay completed! {title}", stages, self.current_session_id
|
1819 |
+
|
1820 |
+
except Exception as e:
|
1821 |
+
logger.error(f"Screenplay generation error: {e}", exc_info=True)
|
1822 |
+
yield f"❌ Error occurred: {e}", stages if 'stages' in locals() else [], self.current_session_id
|
1823 |
+
|
1824 |
+
def get_stage_prompt(self, stage_idx: int, role: str, query: str,
|
1825 |
+
screenplay_type: str, genre: str, language: str,
|
1826 |
+
stages: List[Dict]) -> str:
|
1827 |
+
"""Generate stage-specific prompt"""
|
1828 |
+
if stage_idx == 0: # Producer
|
1829 |
+
return self.create_producer_prompt(query, screenplay_type, genre, language)
|
1830 |
+
|
1831 |
+
if stage_idx == 1: # Story Developer
|
1832 |
+
return self.create_story_developer_prompt(
|
1833 |
+
stages[0]["content"], query, screenplay_type, genre, language
|
1834 |
+
)
|
1835 |
+
|
1836 |
+
if stage_idx == 2: # Character Designer
|
1837 |
+
return self.create_character_designer_prompt(
|
1838 |
+
stages[0]["content"], stages[1]["content"], genre, language
|
1839 |
+
)
|
1840 |
+
|
1841 |
+
if stage_idx == 3: # Structure Critic
|
1842 |
+
return self.create_critic_structure_prompt(
|
1843 |
+
stages[1]["content"], stages[2]["content"], screenplay_type, genre, language
|
1844 |
+
)
|
1845 |
+
|
1846 |
+
if stage_idx == 4: # Scene Planner
|
1847 |
+
return self.create_scene_planner_prompt(
|
1848 |
+
stages[1]["content"], stages[2]["content"], screenplay_type, genre, language
|
1849 |
+
)
|
1850 |
+
|
1851 |
+
# Screenwriter acts
|
1852 |
+
if role == "screenwriter":
|
1853 |
+
act_mapping = {5: "Act 1", 7: "Act 2A", 9: "Act 2B", 11: "Act 3"}
|
1854 |
+
if stage_idx in act_mapping:
|
1855 |
+
act = act_mapping[stage_idx]
|
1856 |
+
previous_acts = self._get_previous_acts(stages, stage_idx)
|
1857 |
+
return self.create_screenwriter_prompt(
|
1858 |
+
act, stages[4]["content"], stages[2]["content"],
|
1859 |
+
previous_acts, screenplay_type, genre, language
|
1860 |
+
)
|
1861 |
+
|
1862 |
+
# Script doctor reviews
|
1863 |
+
if role == "script_doctor":
|
1864 |
+
act_mapping = {6: "Act 1", 8: "Act 2A", 10: "Act 2B"}
|
1865 |
+
if stage_idx in act_mapping:
|
1866 |
+
act = act_mapping[stage_idx]
|
1867 |
+
act_content = stages[stage_idx-1]["content"]
|
1868 |
+
return self.create_script_doctor_prompt(act_content, act, genre, language)
|
1869 |
+
|
1870 |
+
# Final reviewer
|
1871 |
+
if role == "final_reviewer":
|
1872 |
+
complete_screenplay = ScreenplayDatabase.get_screenplay_content(self.current_session_id)
|
1873 |
+
return self.create_final_reviewer_prompt(
|
1874 |
+
complete_screenplay, screenplay_type, genre, language
|
1875 |
+
)
|
1876 |
+
|
1877 |
+
return ""
|
1878 |
+
|
1879 |
+
def _get_previous_acts(self, stages: List[Dict], current_idx: int) -> str:
|
1880 |
+
"""Get previous acts content"""
|
1881 |
+
previous = []
|
1882 |
+
act_indices = {5: [], 7: [5], 9: [5, 7], 11: [5, 7, 9]}
|
1883 |
+
|
1884 |
+
if current_idx in act_indices:
|
1885 |
+
for idx in act_indices[current_idx]:
|
1886 |
+
if idx < len(stages) and stages[idx]["content"]:
|
1887 |
+
previous.append(stages[idx]["content"])
|
1888 |
+
|
1889 |
+
return "\n\n---\n\n".join(previous) if previous else ""
|
1890 |
+
|
1891 |
+
|
1892 |
+
|
1893 |
+
|
1894 |
|
1895 |
+
|
1896 |
+
|
1897 |
def _parse_character_profile(self, content: str, role: str) -> CharacterProfile:
|
1898 |
"""Parse character profile from content"""
|
1899 |
# Extract character details using regex or string parsing
|