Spaces:
Sleeping
Sleeping
Update app/main.py
Browse files- app/main.py +14 -7
app/main.py
CHANGED
|
@@ -122,7 +122,7 @@ def stream_openrouter(messages: list, model: str) -> Generator[str, None, None]:
|
|
| 122 |
logger.error(f"Streaming failed: {e}")
|
| 123 |
raise HTTPException(status_code=500, detail=f"Failed to stream: {str(e)}")
|
| 124 |
|
| 125 |
-
def generate_outline_stream(transcript: str, model: str) -> Generator[str, None, None]:
|
| 126 |
"""Generate and stream outline from (summarized) transcript."""
|
| 127 |
if not transcript:
|
| 128 |
yield "Error: Transcript is empty"
|
|
@@ -130,10 +130,11 @@ def generate_outline_stream(transcript: str, model: str) -> Generator[str, None,
|
|
| 130 |
|
| 131 |
summarized = summarize_transcript(transcript)
|
| 132 |
|
| 133 |
-
|
|
|
|
| 134 |
You are a creative novelist specializing in dark romance novels featuring open marriages, BDSM, and swinging lifestyles. Analyze the provided podcast transcript summary for themes, dialogues, character dynamics, and plot seeds. Explicit content is expected—generate mature, consensual erotic scenes with psychological depth, power imbalances, jealousy, and redemption arcs.
|
| 135 |
|
| 136 |
-
Output ONLY a detailed, gripping chapter-by-chapter outline for a
|
| 137 |
|
| 138 |
## Chapter X: Title
|
| 139 |
- **Hook:** Pulse-pounding opening scene (e.g., mid-BDSM encounter).
|
|
@@ -146,10 +147,13 @@ def generate_outline_stream(transcript: str, model: str) -> Generator[str, None,
|
|
| 146 |
Ensure overall arc: rising erotic tension, mid-book betrayal/redemption, explosive finale. Expand ideas into addictive, original plot.
|
| 147 |
"""
|
| 148 |
|
|
|
|
|
|
|
|
|
|
| 149 |
user_prompt = f"Generate dark romance outline from this transcript summary:\n\n{summarized}"
|
| 150 |
|
| 151 |
messages = [
|
| 152 |
-
{"role": "system", "content":
|
| 153 |
{"role": "user", "content": user_prompt}
|
| 154 |
]
|
| 155 |
|
|
@@ -165,9 +169,12 @@ def generate_outline_stream(transcript: str, model: str) -> Generator[str, None,
|
|
| 165 |
async def generate_novel_stream(
|
| 166 |
transcript: str = Form(None),
|
| 167 |
file: Optional[UploadFile] = File(None),
|
| 168 |
-
model: str = Form(DEFAULT_MODEL)
|
|
|
|
|
|
|
|
|
|
| 169 |
):
|
| 170 |
-
logger.info(f"Starting streaming generation - Model: {model}")
|
| 171 |
try:
|
| 172 |
# Handle file upload if provided
|
| 173 |
if file:
|
|
@@ -179,7 +186,7 @@ async def generate_novel_stream(
|
|
| 179 |
raise HTTPException(status_code=400, detail="Provide either transcript text or a file.")
|
| 180 |
|
| 181 |
return StreamingResponse(
|
| 182 |
-
generate_outline_stream(transcript_text, model),
|
| 183 |
media_type="text/plain"
|
| 184 |
)
|
| 185 |
except HTTPException:
|
|
|
|
| 122 |
logger.error(f"Streaming failed: {e}")
|
| 123 |
raise HTTPException(status_code=500, detail=f"Failed to stream: {str(e)}")
|
| 124 |
|
| 125 |
+
def generate_outline_stream(transcript: str, model: str, chapter_count: int, word_count: int, custom_prompt: Optional[str]) -> Generator[str, None, None]:
|
| 126 |
"""Generate and stream outline from (summarized) transcript."""
|
| 127 |
if not transcript:
|
| 128 |
yield "Error: Transcript is empty"
|
|
|
|
| 130 |
|
| 131 |
summarized = summarize_transcript(transcript)
|
| 132 |
|
| 133 |
+
# Build dynamic system prompt
|
| 134 |
+
base_prompt = f"""
|
| 135 |
You are a creative novelist specializing in dark romance novels featuring open marriages, BDSM, and swinging lifestyles. Analyze the provided podcast transcript summary for themes, dialogues, character dynamics, and plot seeds. Explicit content is expected—generate mature, consensual erotic scenes with psychological depth, power imbalances, jealousy, and redemption arcs.
|
| 136 |
|
| 137 |
+
Output ONLY a detailed, gripping chapter-by-chapter outline for a {word_count}-word novel ({chapter_count} chapters, ~{word_count // chapter_count} words each) in markdown format. No JSON, no intro/explanation. Structure each chapter as:
|
| 138 |
|
| 139 |
## Chapter X: Title
|
| 140 |
- **Hook:** Pulse-pounding opening scene (e.g., mid-BDSM encounter).
|
|
|
|
| 147 |
Ensure overall arc: rising erotic tension, mid-book betrayal/redemption, explosive finale. Expand ideas into addictive, original plot.
|
| 148 |
"""
|
| 149 |
|
| 150 |
+
if custom_prompt:
|
| 151 |
+
base_prompt = f"User instructions: {custom_prompt}. Adapt the outline accordingly.\n\n{base_prompt}"
|
| 152 |
+
|
| 153 |
user_prompt = f"Generate dark romance outline from this transcript summary:\n\n{summarized}"
|
| 154 |
|
| 155 |
messages = [
|
| 156 |
+
{"role": "system", "content": base_prompt},
|
| 157 |
{"role": "user", "content": user_prompt}
|
| 158 |
]
|
| 159 |
|
|
|
|
| 169 |
async def generate_novel_stream(
|
| 170 |
transcript: str = Form(None),
|
| 171 |
file: Optional[UploadFile] = File(None),
|
| 172 |
+
model: str = Form(DEFAULT_MODEL),
|
| 173 |
+
chapter_count: int = Form(10),
|
| 174 |
+
word_count: int = Form(90000),
|
| 175 |
+
custom_prompt: Optional[str] = Form(None)
|
| 176 |
):
|
| 177 |
+
logger.info(f"Starting streaming generation - Model: {model}, Chapters: {chapter_count}, Words: {word_count}")
|
| 178 |
try:
|
| 179 |
# Handle file upload if provided
|
| 180 |
if file:
|
|
|
|
| 186 |
raise HTTPException(status_code=400, detail="Provide either transcript text or a file.")
|
| 187 |
|
| 188 |
return StreamingResponse(
|
| 189 |
+
generate_outline_stream(transcript_text, model, chapter_count, word_count, custom_prompt),
|
| 190 |
media_type="text/plain"
|
| 191 |
)
|
| 192 |
except HTTPException:
|