ginipick commited on
Commit
62d2b15
Β·
verified Β·
1 Parent(s): 6db8a66

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -80
app.py CHANGED
@@ -316,17 +316,19 @@ def ginigen_app():
316
 
317
  # 예제 주제 선택
318
  sb.subheader("예제 주제")
319
- if sb.button("2025λ…„ 뢀동산 μ„ΈκΈˆ μ œλ„", key="example1"):
320
- st.session_state.example_topic = EXAMPLE_TOPICS["example1"]
321
- st.rerun()
322
-
323
- if sb.button("여름 지역별 μΆ•μ œμ™€ λͺ…μ†Œ", key="example2"):
324
- st.session_state.example_topic = EXAMPLE_TOPICS["example2"]
325
- st.rerun()
326
-
327
- if sb.button("μ‹ μ„±μž₯ μ‚°μ—… 투자 κ°€μ΄λ“œ", key="example3"):
328
- st.session_state.example_topic = EXAMPLE_TOPICS["example3"]
329
- st.rerun()
 
 
330
 
331
  sb.subheader("기타 μ„€μ •")
332
  sb.toggle("μžλ™ μ €μž₯", key="auto_save")
@@ -375,79 +377,83 @@ def ginigen_app():
375
  if "image" in m:
376
  st.image(m["image"], caption=m.get("image_caption", ""))
377
 
378
- # ── μ‚¬μš©μž μž…λ ₯ λ˜λŠ” 예제 주제 처리
379
  prompt = st.chat_input("무엇을 λ„μ™€λ“œλ¦΄κΉŒμš”?")
380
 
381
- # 예제 μ£Όμ œκ°€ μ„ νƒλ˜μ—ˆμœΌλ©΄ 처리
382
- if hasattr(st.session_state, 'example_topic') and st.session_state.example_topic:
383
- prompt = st.session_state.example_topic
384
- # 처리 ν›„ 예제 주제 μ΄ˆκΈ°ν™”
385
- del st.session_state.example_topic
386
-
387
  if prompt:
388
- st.session_state.messages.append({"role": "user", "content": prompt})
389
- with st.chat_message("user"): st.markdown(prompt)
390
 
391
- with st.chat_message("assistant"):
392
- placeholder = st.empty(); answer = ""
393
-
394
- # μ„ νƒλœ ν…œν”Œλ¦Ώ, 톀, 단어 수둜 μ‹œμŠ€ν…œ ν”„λ‘¬ν”„νŠΈ 생성
395
- sys_prompt = get_system_prompt(
396
- template=st.session_state.blog_template,
397
- tone=st.session_state.blog_tone,
398
- word_count=st.session_state.word_count
399
- )
400
-
401
- if st.session_state.use_web_search:
402
- with st.spinner("μ›Ή 검색 쀑…"):
403
- search_md = do_web_search(keywords(prompt))
404
- sys_prompt += f"\n\n검색 κ²°κ³Ό:\n{search_md}\n"
405
-
406
- # Claude 슀트리밍
407
- with client.messages.stream(
408
- model=st.session_state.ai_model, max_tokens=MAX_TOKENS,
409
- system=sys_prompt,
410
- messages=[{"role": m["role"], "content": m["content"]}
411
- for m in st.session_state.messages]
412
- ) as stream:
413
- for t in stream.text_stream:
414
- answer += t or ""
415
- placeholder.markdown(answer + "β–Œ")
416
- placeholder.markdown(answer)
417
-
418
- # 이미지 μ˜΅μ…˜
419
- answer_entry_saved = False
420
- if st.session_state.generate_image:
421
- with st.spinner("이미지 생성 쀑…"):
422
- ip = extract_image_prompt(answer, prompt)
423
- img, cap = generate_image(ip)
424
- if img:
425
- st.image(img, caption=cap)
426
- st.session_state.messages.append(
427
- {"role": "assistant", "content": answer,
428
- "image": img, "image_caption": cap})
429
- answer_entry_saved = True
430
- if not answer_entry_saved:
431
- st.session_state.messages.append(
432
- {"role": "assistant", "content": answer})
433
-
434
- # λ³Έλ¬Έ λ‹€μš΄λ‘œλ“œ λ²„νŠΌ (MD / HTML)
435
- st.subheader("이 λΈ”λ‘œκ·Έ λ‹€μš΄λ‘œλ“œ")
436
- b1, b2 = st.columns(2)
437
- b1.download_button("λ§ˆν¬λ‹€μš΄", answer,
438
- file_name=f"{prompt[:30]}.md", mime="text/markdown")
439
- b2.download_button("HTML", md_to_html(answer, prompt[:30]),
440
- file_name=f"{prompt[:30]}.html", mime="text/html")
441
-
442
- # ── μžλ™ λ°±μ—… μ €μž₯
443
- if st.session_state.auto_save and st.session_state.messages:
444
- try:
445
- fn = f"chat_history_auto_{datetime.now():%Y%m%d_%H%M%S}.json"
446
- with open(fn, "w", encoding="utf-8") as fp:
447
- json.dump(st.session_state.messages, fp,
448
- ensure_ascii=False, indent=2)
449
- except Exception as e:
450
- logging.error(f"μžλ™ μ €μž₯ μ‹€νŒ¨: {e}")
 
 
 
 
 
 
 
 
 
 
 
451
 
452
  # ──────────────────────────────── main / requirements ──────────────────────
453
  def main(): ginigen_app()
 
316
 
317
  # 예제 주제 선택
318
  sb.subheader("예제 주제")
319
+
320
+ col1, col2, col3 = sb.columns(3)
321
+
322
+ # μˆ˜μ •: 예제 선택 μ‹œ 직접 μ²˜λ¦¬ν•˜λ„λ‘ λ³€κ²½
323
+ if col1.button("뢀동산 μ„ΈκΈˆ", key="ex1"):
324
+ # 예제 주제λ₯Ό μž…λ ₯으둜 μ¦‰μ‹œ 처리 (rerun 없이)
325
+ process_example(EXAMPLE_TOPICS["example1"])
326
+
327
+ if col2.button("여름 μΆ•μ œ", key="ex2"):
328
+ process_example(EXAMPLE_TOPICS["example2"])
329
+
330
+ if col3.button("투자 κ°€μ΄λ“œ", key="ex3"):
331
+ process_example(EXAMPLE_TOPICS["example3"])
332
 
333
  sb.subheader("기타 μ„€μ •")
334
  sb.toggle("μžλ™ μ €μž₯", key="auto_save")
 
377
  if "image" in m:
378
  st.image(m["image"], caption=m.get("image_caption", ""))
379
 
380
+ # ── μ‚¬μš©μž μž…λ ₯ 처리
381
  prompt = st.chat_input("무엇을 λ„μ™€λ“œλ¦΄κΉŒμš”?")
382
 
 
 
 
 
 
 
383
  if prompt:
384
+ process_input(prompt)
 
385
 
386
+
387
+ def process_example(topic):
388
+ """예제 주제λ₯Ό 직접 μ²˜λ¦¬ν•˜λŠ” ν•¨μˆ˜ (rerun 없이)"""
389
+ process_input(topic)
390
+
391
+
392
+ def process_input(prompt):
393
+ """μ‚¬μš©μž μž…λ ₯ 처리 ν•¨μˆ˜ (일반 μž…λ ₯κ³Ό 예제 μž…λ ₯ λͺ¨λ‘ 처리)"""
394
+ st.session_state.messages.append({"role": "user", "content": prompt})
395
+ with st.chat_message("user"): st.markdown(prompt)
396
+
397
+ with st.chat_message("assistant"):
398
+ placeholder = st.empty(); answer = ""
399
+
400
+ # μ„ νƒλœ ν…œν”Œλ¦Ώ, 톀, 단어 수둜 μ‹œμŠ€ν…œ ν”„λ‘¬ν”„νŠΈ 생성
401
+ sys_prompt = get_system_prompt(
402
+ template=st.session_state.blog_template,
403
+ tone=st.session_state.blog_tone,
404
+ word_count=st.session_state.word_count
405
+ )
406
+
407
+ if st.session_state.use_web_search:
408
+ with st.spinner("μ›Ή 검색 쀑…"):
409
+ search_md = do_web_search(keywords(prompt))
410
+ sys_prompt += f"\n\n검색 κ²°κ³Ό:\n{search_md}\n"
411
+
412
+ # Claude 슀트리밍
413
+ with client.messages.stream(
414
+ model=st.session_state.ai_model, max_tokens=MAX_TOKENS,
415
+ system=sys_prompt,
416
+ messages=[{"role": m["role"], "content": m["content"]}
417
+ for m in st.session_state.messages]
418
+ ) as stream:
419
+ for t in stream.text_stream:
420
+ answer += t or ""
421
+ placeholder.markdown(answer + "β–Œ")
422
+ placeholder.markdown(answer)
423
+
424
+ # 이미지 μ˜΅μ…˜
425
+ answer_entry_saved = False
426
+ if st.session_state.generate_image:
427
+ with st.spinner("이미지 생성 쀑…"):
428
+ ip = extract_image_prompt(answer, prompt)
429
+ img, cap = generate_image(ip)
430
+ if img:
431
+ st.image(img, caption=cap)
432
+ st.session_state.messages.append(
433
+ {"role": "assistant", "content": answer,
434
+ "image": img, "image_caption": cap})
435
+ answer_entry_saved = True
436
+ if not answer_entry_saved:
437
+ st.session_state.messages.append(
438
+ {"role": "assistant", "content": answer})
439
+
440
+ # λ³Έλ¬Έ λ‹€μš΄λ‘œλ“œ λ²„νŠΌ (MD / HTML)
441
+ st.subheader("이 λΈ”λ‘œκ·Έ λ‹€μš΄λ‘œλ“œ")
442
+ b1, b2 = st.columns(2)
443
+ b1.download_button("λ§ˆν¬λ‹€μš΄", answer,
444
+ file_name=f"{prompt[:30]}.md", mime="text/markdown")
445
+ b2.download_button("HTML", md_to_html(answer, prompt[:30]),
446
+ file_name=f"{prompt[:30]}.html", mime="text/html")
447
+
448
+ # ── μžλ™ λ°±μ—… μ €μž₯
449
+ if st.session_state.auto_save and st.session_state.messages:
450
+ try:
451
+ fn = f"chat_history_auto_{datetime.now():%Y%m%d_%H%M%S}.json"
452
+ with open(fn, "w", encoding="utf-8") as fp:
453
+ json.dump(st.session_state.messages, fp,
454
+ ensure_ascii=False, indent=2)
455
+ except Exception as e:
456
+ logging.error(f"μžλ™ μ €μž₯ μ‹€νŒ¨: {e}")
457
 
458
  # ──────────────────────────────── main / requirements ──────────────────────
459
  def main(): ginigen_app()