Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -126,8 +126,14 @@ def initialize_flux_api():
|
|
| 126 |
global FLUX_API_ENABLED, flux_api_client
|
| 127 |
|
| 128 |
try:
|
| 129 |
-
logger.info("Connecting to FLUX API...")
|
| 130 |
flux_api_client = Client(FLUX_API_URL)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
FLUX_API_ENABLED = True
|
| 132 |
logger.info("FLUX API connected successfully")
|
| 133 |
return True
|
|
@@ -667,8 +673,7 @@ def generate_flux_prompt(title: str, content: str, style_key: str) -> str:
|
|
| 667 |
"""
|
| 668 |
Build a FLUX image-generation prompt for one slide, using six pre-defined
|
| 669 |
visual styles (Product Design, Mindmap, Mockup, Infographic, Diagram,
|
| 670 |
-
Flowchart).
|
| 671 |
-
๋ชจ๋ ๊ธ๋จธ๋ฆฌ ๊ธฐํธ๋ฅผ ์ฒ๋ฆฌํ๋ค.
|
| 672 |
"""
|
| 673 |
# 1) clean bullet points (max 8)
|
| 674 |
bullets = [
|
|
@@ -678,28 +683,33 @@ def generate_flux_prompt(title: str, content: str, style_key: str) -> str:
|
|
| 678 |
][:8]
|
| 679 |
|
| 680 |
if bullets:
|
| 681 |
-
nodes_block = '\n'.join(f"- {b}" for b in bullets)
|
| 682 |
tree_block = '\n'.join(
|
| 683 |
f"{'โโโ' if i < len(bullets)-1 else 'โโโ'} {b}"
|
| 684 |
for i, b in enumerate(bullets)
|
| 685 |
)
|
| 686 |
else:
|
| 687 |
-
|
| 688 |
-
tree_block =
|
| 689 |
|
| 690 |
-
# 2) choose template & inject nodes
|
| 691 |
template = EXAMPLE_PROMPTS.get(style_key, EXAMPLE_PROMPTS["Diagram"])
|
| 692 |
-
prompt_body = template.format(
|
| 693 |
|
| 694 |
-
# 3) stylistic tail
|
| 695 |
tail = (
|
| 696 |
"corporate colour palette, white background, hand-drawn line style; "
|
| 697 |
"boxes, arrows, connectors clearly visible; high-resolution vector."
|
| 698 |
)
|
| 699 |
|
| 700 |
-
|
| 701 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 702 |
|
|
|
|
| 703 |
|
| 704 |
def _save_temp_image(img_bytes: bytes, suffix=".png") -> str:
|
| 705 |
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
|
|
@@ -2260,7 +2270,9 @@ def generate_ppt_content(topic: str, num_slides: int, additional_context: str, u
|
|
| 2260 |
5. ๊ฐ ์น์
์ฌ์ด์ ๋น ์ค ์์
|
| 2261 |
6. ์ด {num_slides}์ฅ ์์ฑ
|
| 2262 |
7. ๊ฐ ํฌ์ธํธ๋ '-' ๊ธฐํธ๋ก ์์ํ์ธ์ (์ด๋ชจ์ง๋ ์๋์ผ๋ก ์ถ๊ฐ๋ฉ๋๋ค)
|
| 2263 |
-
8. ๋
ธํธ๋ ํด๋น ์ฌ๋ผ์ด๋์ ๋ด์ฉ์ ๋ฐํ์๊ฐ ์ฒญ์ค์๊ฒ ์ค๋ช
ํ๋ ๊ตฌ์ด์ฒด ๋๋ณธ์ผ๋ก ์์ฑํ์ธ์
|
|
|
|
|
|
|
| 2264 |
else:
|
| 2265 |
system_prompt = f"""You are a professional PPT presentation expert.
|
| 2266 |
Create content for exactly {num_slides} slides on the given topic.
|
|
@@ -2289,6 +2301,8 @@ Notes: [Speaker script]
|
|
| 2289 |
|
| 2290 |
(Continue this way until Slide {num_slides})
|
| 2291 |
|
|
|
|
|
|
|
| 2292 |
**Important instructions:**
|
| 2293 |
1. Each slide starts with "Slide number"
|
| 2294 |
2. Title: followed by the actual title (no numbers)
|
|
@@ -2297,7 +2311,9 @@ Notes: [Speaker script]
|
|
| 2297 |
5. No empty lines between sections
|
| 2298 |
6. Create exactly {num_slides} slides
|
| 2299 |
7. Start each point with '-' (emojis will be added automatically)
|
| 2300 |
-
8. Notes should be a speaker script explaining the slide content in conversational style
|
|
|
|
|
|
|
| 2301 |
|
| 2302 |
# Add search results if web search is performed
|
| 2303 |
if additional_context:
|
|
@@ -2361,9 +2377,21 @@ Notes: [Speaker script]
|
|
| 2361 |
except json.JSONDecodeError:
|
| 2362 |
logger.warning(f"JSON parsing failed: {data_str}")
|
| 2363 |
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2364 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2365 |
except Exception as e:
|
| 2366 |
logger.error(f"LLM API error: {str(e)}")
|
|
|
|
|
|
|
| 2367 |
yield f"โ ๏ธ Error generating content: {str(e)}"
|
| 2368 |
|
| 2369 |
##############################################################################
|
|
|
|
| 126 |
global FLUX_API_ENABLED, flux_api_client
|
| 127 |
|
| 128 |
try:
|
| 129 |
+
logger.info(f"Connecting to FLUX API at {FLUX_API_URL}...")
|
| 130 |
flux_api_client = Client(FLUX_API_URL)
|
| 131 |
+
|
| 132 |
+
# API ์ ๋ณด ํ์ธ
|
| 133 |
+
if hasattr(flux_api_client, 'view_api'):
|
| 134 |
+
api_info = flux_api_client.view_api()
|
| 135 |
+
logger.info(f"FLUX API endpoints: {api_info}")
|
| 136 |
+
|
| 137 |
FLUX_API_ENABLED = True
|
| 138 |
logger.info("FLUX API connected successfully")
|
| 139 |
return True
|
|
|
|
| 673 |
"""
|
| 674 |
Build a FLUX image-generation prompt for one slide, using six pre-defined
|
| 675 |
visual styles (Product Design, Mindmap, Mockup, Infographic, Diagram,
|
| 676 |
+
Flowchart).
|
|
|
|
| 677 |
"""
|
| 678 |
# 1) clean bullet points (max 8)
|
| 679 |
bullets = [
|
|
|
|
| 683 |
][:8]
|
| 684 |
|
| 685 |
if bullets:
|
|
|
|
| 686 |
tree_block = '\n'.join(
|
| 687 |
f"{'โโโ' if i < len(bullets)-1 else 'โโโ'} {b}"
|
| 688 |
for i, b in enumerate(bullets)
|
| 689 |
)
|
| 690 |
else:
|
| 691 |
+
# ๋ถ๋ฆฟ์ด ์์ผ๋ฉด ์ ๋ชฉ์ ์ฌ์ฉ
|
| 692 |
+
tree_block = f"โโโ {title}"
|
| 693 |
|
| 694 |
+
# 2) choose template & inject tree only (not nodes)
|
| 695 |
template = EXAMPLE_PROMPTS.get(style_key, EXAMPLE_PROMPTS["Diagram"])
|
| 696 |
+
prompt_body = template.format(tree=tree_block) # โ nodes ์ ๊ฑฐ, tree๋ง ์ฌ์ฉ
|
| 697 |
|
| 698 |
+
# 3) stylistic tail
|
| 699 |
tail = (
|
| 700 |
"corporate colour palette, white background, hand-drawn line style; "
|
| 701 |
"boxes, arrows, connectors clearly visible; high-resolution vector."
|
| 702 |
)
|
| 703 |
|
| 704 |
+
final_prompt = f"{prompt_body}\n\n{tail}".strip()
|
| 705 |
+
|
| 706 |
+
# ๋๋ฒ๊น
์ฉ ๋ก๊ทธ ์ถ๊ฐ
|
| 707 |
+
logger.info(f"[FLUX Prompt] Style: {style_key}")
|
| 708 |
+
logger.info(f"[FLUX Prompt] Generated: {final_prompt[:200]}...")
|
| 709 |
+
|
| 710 |
+
return final_prompt
|
| 711 |
|
| 712 |
+
|
| 713 |
|
| 714 |
def _save_temp_image(img_bytes: bytes, suffix=".png") -> str:
|
| 715 |
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=suffix)
|
|
|
|
| 2270 |
5. ๊ฐ ์น์
์ฌ์ด์ ๋น ์ค ์์
|
| 2271 |
6. ์ด {num_slides}์ฅ ์์ฑ
|
| 2272 |
7. ๊ฐ ํฌ์ธํธ๋ '-' ๊ธฐํธ๋ก ์์ํ์ธ์ (์ด๋ชจ์ง๋ ์๋์ผ๋ก ์ถ๊ฐ๋ฉ๋๋ค)
|
| 2273 |
+
8. ๋
ธํธ๋ ํด๋น ์ฌ๋ผ์ด๋์ ๋ด์ฉ์ ๋ฐํ์๊ฐ ์ฒญ์ค์๊ฒ ์ค๋ช
ํ๋ ๊ตฌ์ด์ฒด ๋๋ณธ์ผ๋ก ์์ฑํ์ธ์
|
| 2274 |
+
9. ๊ฐ ๊ธ๋จธ๋ฆฌ ๊ธฐํธ ํฌ์ธํธ๋ ๊ตฌ์ฒด์ ์ด๊ณ ๋ช
ํํ๊ฒ ์์ฑํ์ธ์
|
| 2275 |
+
10. ๋ค์ด์ด๊ทธ๋จ์ด๋ ํ๋ก์ฐ์ฐจํธ๋ก ํํํ๊ธฐ ์ข์ ๋ด์ฉ์ ๊ตฌ์กฐํ๋ ๋ฐฉ์์ผ๋ก ์์ฑํ์ธ์"""
|
| 2276 |
else:
|
| 2277 |
system_prompt = f"""You are a professional PPT presentation expert.
|
| 2278 |
Create content for exactly {num_slides} slides on the given topic.
|
|
|
|
| 2301 |
|
| 2302 |
(Continue this way until Slide {num_slides})
|
| 2303 |
|
| 2304 |
+
{layout_instructions}
|
| 2305 |
+
|
| 2306 |
**Important instructions:**
|
| 2307 |
1. Each slide starts with "Slide number"
|
| 2308 |
2. Title: followed by the actual title (no numbers)
|
|
|
|
| 2311 |
5. No empty lines between sections
|
| 2312 |
6. Create exactly {num_slides} slides
|
| 2313 |
7. Start each point with '-' (emojis will be added automatically)
|
| 2314 |
+
8. Notes should be a speaker script explaining the slide content in conversational style
|
| 2315 |
+
9. Make each bullet point specific and clear
|
| 2316 |
+
10. Structure content that would work well as diagrams or flowcharts"""
|
| 2317 |
|
| 2318 |
# Add search results if web search is performed
|
| 2319 |
if additional_context:
|
|
|
|
| 2377 |
except json.JSONDecodeError:
|
| 2378 |
logger.warning(f"JSON parsing failed: {data_str}")
|
| 2379 |
continue
|
| 2380 |
+
|
| 2381 |
+
# ์ต์ข
์๋ต ๋ก๊น
(๋๋ฒ๊น
์ฉ)
|
| 2382 |
+
logger.info(f"Generated {len(full_response)} characters of content")
|
| 2383 |
+
logger.debug(f"First 500 chars of response: {full_response[:500]}")
|
| 2384 |
|
| 2385 |
+
except requests.exceptions.Timeout:
|
| 2386 |
+
logger.error("LLM API timeout")
|
| 2387 |
+
yield "โ ๏ธ Error: Request timed out. Please try again."
|
| 2388 |
+
except requests.exceptions.RequestException as e:
|
| 2389 |
+
logger.error(f"LLM API request error: {str(e)}")
|
| 2390 |
+
yield f"โ ๏ธ Error: Network error - {str(e)}"
|
| 2391 |
except Exception as e:
|
| 2392 |
logger.error(f"LLM API error: {str(e)}")
|
| 2393 |
+
import traceback
|
| 2394 |
+
logger.error(f"Traceback: {traceback.format_exc()}")
|
| 2395 |
yield f"โ ๏ธ Error generating content: {str(e)}"
|
| 2396 |
|
| 2397 |
##############################################################################
|