Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
# ββββββββββββββββββββββββββββββββ Imports ββββββββββββββββββββββββββββββββ
|
2 |
-
import os, json, re, logging, requests, markdown
|
3 |
from datetime import datetime
|
4 |
|
5 |
import streamlit as st
|
@@ -14,6 +14,22 @@ BRAVE_ENDPOINT = "https://api.search.brave.com/res/v1/web/search"
|
|
14 |
IMAGE_API_URL = "http://211.233.58.201:7896"
|
15 |
MAX_TOKENS = 7_999
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
# ββββββββββββββββββββββββββββββββ λ‘κΉ
ββββββββββββββββββββββββββββββββββββββ
|
18 |
logging.basicConfig(level=logging.INFO,
|
19 |
format="%(asctime)s - %(levelname)s - %(message)s")
|
@@ -22,8 +38,8 @@ logging.basicConfig(level=logging.INFO,
|
|
22 |
client = anthropic.Anthropic(api_key=ANTHROPIC_KEY)
|
23 |
|
24 |
# ββββββββββββββββββββββββββββββββ λΈλ‘κ·Έ μμ± μμ€ν
ν둬ννΈ ββββββββββββββββ
|
25 |
-
def get_system_prompt() -> str:
|
26 |
-
|
27 |
λΉμ μ μ λ¬Έ λΈλ‘κ·Έ μμ± μ λ¬Έκ°μ
λλ€. λͺ¨λ λΈλ‘κ·Έ κΈ μμ± μμ²μ λν΄ λ€μμ 8λ¨κ³ νλ μμν¬λ₯Ό μ² μ ν λ°λ₯΄λ, μμ°μ€λ½κ³ λ§€λ ₯μ μΈ κΈμ΄ λλλ‘ μμ±ν΄μΌ ν©λλ€:
|
28 |
|
29 |
λ
μ μ°κ²° λ¨κ³
|
@@ -65,15 +81,78 @@ def get_system_prompt() -> str:
|
|
65 |
8.1. μ§μ μ± μλ κ°μ¬ μΈμ¬
|
66 |
8.2. λ€μ 컨ν
μΈ μκ³ λ‘ κΈ°λκ° μ‘°μ±
|
67 |
8.3. μν΅ μ±λ μλ΄
|
|
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
# ββββββββββββββββββββββββββββββββ Brave Search API βββββββββββββββββββββββββ
|
79 |
def brave_search(query: str, count: int = 5):
|
@@ -90,48 +169,74 @@ def brave_search(query: str, count: int = 5):
|
|
90 |
"X-Subscription-Token": BRAVE_KEY
|
91 |
}
|
92 |
params = {"q": query, "count": str(count)}
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
"
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
def mock_results(query: str) -> str:
|
|
|
112 |
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
113 |
-
return (f"#
|
114 |
-
f"
|
115 |
-
"
|
116 |
-
"
|
|
|
|
|
|
|
|
|
117 |
|
118 |
def do_web_search(query: str) -> str:
|
|
|
119 |
try:
|
120 |
arts = brave_search(query, 5)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
except Exception as e:
|
122 |
-
logging.error(f"
|
123 |
-
return mock_results(query)
|
124 |
-
if not arts:
|
125 |
return mock_results(query)
|
126 |
|
127 |
-
hdr = "# μΉ κ²μ κ²°κ³Ό\nμλ μ 보λ₯Ό μ°Έκ³ ν΄μ λ΅λ³νμΈμ.\n\n"
|
128 |
-
body = "\n".join(
|
129 |
-
f"### Result {a['index']}: {a['title']}\n\n{a['snippet']}\n\n"
|
130 |
-
f"**μΆμ²**: [{a['displayed_link']}]({a['link']})\n\n---\n"
|
131 |
-
for a in arts
|
132 |
-
)
|
133 |
-
return hdr + body
|
134 |
-
|
135 |
# ββββββββββββββββββββββββββββββββ μ΄λ―Έμ§ Β· λ³ν μ νΈ ββββββββββββββββββββββββ
|
136 |
def generate_image(prompt, w=768, h=768, g=3.5, steps=30, seed=3):
|
137 |
if not prompt: return None, "ν둬ννΈ λΆμ‘±"
|
@@ -174,17 +279,38 @@ def ginigen_app():
|
|
174 |
messages=[],
|
175 |
auto_save=True,
|
176 |
generate_image=False,
|
177 |
-
use_web_search=False
|
|
|
|
|
|
|
178 |
)
|
179 |
for k, v in defaults.items():
|
180 |
st.session_state.setdefault(k, v)
|
181 |
|
182 |
# ββ μ¬μ΄λλ° μ»¨νΈλ‘€
|
183 |
sb = st.sidebar
|
184 |
-
sb.title("
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
sb.toggle("μλ μ μ₯", key="auto_save")
|
186 |
sb.toggle("μ΄λ―Έμ§ μλ μμ±", key="generate_image")
|
187 |
-
|
|
|
|
|
|
|
|
|
188 |
|
189 |
# ββ μ΅κ·Ό λΈλ‘κ·Έ λ€μ΄λ‘λ (λ§ν¬λ€μ΄ / HTML)
|
190 |
latest_blog = next(
|
@@ -231,7 +357,13 @@ def ginigen_app():
|
|
231 |
|
232 |
with st.chat_message("assistant"):
|
233 |
placeholder = st.empty(); answer = ""
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
|
236 |
if st.session_state.use_web_search:
|
237 |
with st.spinner("μΉ κ²μ μ€β¦"):
|
@@ -297,4 +429,4 @@ if __name__ == "__main__":
|
|
297 |
"markdown>=3.5.1",
|
298 |
"pillow>=10.1.0"
|
299 |
]))
|
300 |
-
main()
|
|
|
1 |
# ββββββββββββββββββββββββββββββββ Imports ββββββββββββββββββββββββββββββββ
|
2 |
+
import os, json, re, logging, requests, markdown, time
|
3 |
from datetime import datetime
|
4 |
|
5 |
import streamlit as st
|
|
|
14 |
IMAGE_API_URL = "http://211.233.58.201:7896"
|
15 |
MAX_TOKENS = 7_999
|
16 |
|
17 |
+
# λΈλ‘κ·Έ ν
νλ¦Ώ λ° μ€νμΌ μ μ
|
18 |
+
BLOG_TEMPLATES = {
|
19 |
+
"standard": "μ λ¬Έ λΈλ‘κ·Έ μμ± μ λ¬Έκ°λ‘μ 8λ¨κ³ νλ μμν¬λ₯Ό λ°λΌ μμ°μ€λ½κ³ λ§€λ ₯μ μΈ κΈ μμ±",
|
20 |
+
"tutorial": "λ¨κ³λ³ νν λ¦¬μΌ νμμΌλ‘, λͺ
νν κ³Όμ κ³Ό κ²°κ³Όλ₯Ό 보μ¬μ£Όλ κ°μ΄λ μμ±",
|
21 |
+
"review": "μ ν/μλΉμ€ λΆμ μ€μ¬μ 리뷰 νμ, μ₯λ¨μ λΆμκ³Ό μΆμ² ν¬ν¨",
|
22 |
+
"storytelling": "κ°μΈ κ²½νμ΄λ μ¬λ‘λ₯Ό μ€μ¬μΌλ‘ ν μ€ν 리ν
λ§ νμμ λΈλ‘κ·Έ μμ±",
|
23 |
+
"seo_optimized": "κ²μμμ§ μ΅μ ν(SEO)λ₯Ό κ³ λ €ν ν€μλ μ€μ¬ λΈλ‘κ·Έ μμ±"
|
24 |
+
}
|
25 |
+
|
26 |
+
BLOG_TONES = {
|
27 |
+
"professional": "μ λ¬Έμ μ΄κ³ 곡μμ μΈ μ΄μ‘°λ‘ μμ±",
|
28 |
+
"casual": "μΉκ·Όνκ³ λν체 μ€μ¬μ νΈμν ν€μΌλ‘ μμ±",
|
29 |
+
"humorous": "μ λ¨Έμ μ¬μΉλ₯Ό κ°λ―Έν κ°λ²Όμ΄ μ΄μ‘°λ‘ μμ±",
|
30 |
+
"storytelling": "μ΄μΌκΈ°λ₯Ό λ€λ €μ£Όλ― κ°μ±μ μ΄κ³ λͺ°μ
κ° μλ ν€μΌλ‘ μμ±"
|
31 |
+
}
|
32 |
+
|
33 |
# ββββββββββββββββββββββββββββββββ λ‘κΉ
ββββββββββββββββββββββββββββββββββββββ
|
34 |
logging.basicConfig(level=logging.INFO,
|
35 |
format="%(asctime)s - %(levelname)s - %(message)s")
|
|
|
38 |
client = anthropic.Anthropic(api_key=ANTHROPIC_KEY)
|
39 |
|
40 |
# ββββββββββββββββββββββββββββββββ λΈλ‘κ·Έ μμ± μμ€ν
ν둬ννΈ ββββββββββββββββ
|
41 |
+
def get_system_prompt(template="standard", tone="professional", word_count=1750) -> str:
|
42 |
+
base_prompt = """
|
43 |
λΉμ μ μ λ¬Έ λΈλ‘κ·Έ μμ± μ λ¬Έκ°μ
λλ€. λͺ¨λ λΈλ‘κ·Έ κΈ μμ± μμ²μ λν΄ λ€μμ 8λ¨κ³ νλ μμν¬λ₯Ό μ² μ ν λ°λ₯΄λ, μμ°μ€λ½κ³ λ§€λ ₯μ μΈ κΈμ΄ λλλ‘ μμ±ν΄μΌ ν©λλ€:
|
44 |
|
45 |
λ
μ μ°κ²° λ¨κ³
|
|
|
81 |
8.1. μ§μ μ± μλ κ°μ¬ μΈμ¬
|
82 |
8.2. λ€μ 컨ν
μΈ μκ³ λ‘ κΈ°λκ° μ‘°μ±
|
83 |
8.3. μν΅ μ±λ μλ΄
|
84 |
+
"""
|
85 |
|
86 |
+
# ν
νλ¦Ώλ³ μΆκ° μ§μΉ¨
|
87 |
+
template_guides = {
|
88 |
+
"tutorial": """
|
89 |
+
μ΄ λΈλ‘κ·Έλ νν λ¦¬μΌ νμμΌλ‘ μμ±ν΄ μ£ΌμΈμ:
|
90 |
+
- λͺ
νν λͺ©νμ μ΅μ’
κ²°κ³Όλ¬Ό λ¨Όμ μ μ
|
91 |
+
- λ¨κ³λ³λ‘ λͺ
ννκ² κ΅¬λΆλ κ³Όμ μ€λͺ
|
92 |
+
- κ° λ¨κ³λ§λ€ μ΄λ―Έμ§λ₯Ό μ½μ
ν μμΉ νμ
|
93 |
+
- μμ μμ μκ°κ³Ό λμ΄λ λͺ
μ
|
94 |
+
- νμν λꡬλ μ¬μ μ§μ μλ΄
|
95 |
+
- λ¬Έμ ν΄κ²° νκ³Ό μμ£Ό λ°μνλ μ€μ ν¬ν¨
|
96 |
+
- μλ£ ν λ€μ λ¨κ³λ μμ©λ² μ μ
|
97 |
+
""",
|
98 |
+
|
99 |
+
"review": """
|
100 |
+
μ΄ λΈλ‘κ·Έλ 리뷰 νμμΌλ‘ μμ±ν΄ μ£ΌμΈμ:
|
101 |
+
- κ°κ΄μ μ¬μ€κ³Ό μ£Όκ΄μ νκ° κ΅¬λΆ
|
102 |
+
- λͺ
νν νκ° κΈ°μ€ μ μ
|
103 |
+
- μ₯μ κ³Ό λ¨μ κ· νμκ² μμ
|
104 |
+
- μ μ¬ μ ν/μλΉμ€μ λΉκ΅
|
105 |
+
- λꡬμκ² μ ν©νμ§ νκ² μ€λͺ
|
106 |
+
- ꡬ체μ μΈ μ¬μ© κ²½νκ³Ό κ²°κ³Ό ν¬ν¨
|
107 |
+
- μ΅μ’
μΆμ² μ¬λΆμ λμ μ μ
|
108 |
+
""",
|
109 |
+
|
110 |
+
"storytelling": """
|
111 |
+
μ΄ λΈλ‘κ·Έλ μ€ν 리ν
λ§ νμμΌλ‘ μμ±ν΄ μ£ΌμΈμ:
|
112 |
+
- μ€μ μΈλ¬Όμ΄λ μ¬λ‘λ‘ μμ
|
113 |
+
- λ¬Έμ μν©κ³Ό κ°μ μ μ°κ²° κ°ν
|
114 |
+
- κ°λ±κ³Ό ν΄κ²°κ³Όμ μ€μ¬μ λ΄λ¬ν°λΈ
|
115 |
+
- κ΅νκ³Ό λ°°μμ μμ°μ€λ½κ² ν¬ν¨
|
116 |
+
- λ
μκ° κ³΅κ°ν μ μλ κ°μ μ μ μ§
|
117 |
+
- μ΄μΌκΈ°μ μ μ©ν μ 보μ κ· ν μ μ§
|
118 |
+
- λ
μμκ² μμ μ μ΄μΌκΈ°λ₯Ό μκ°ν΄λ³΄κ² μ λ
|
119 |
+
""",
|
120 |
+
|
121 |
+
"seo_optimized": """
|
122 |
+
μ΄ λΈλ‘κ·Έλ SEO μ΅μ ν νμμΌλ‘ μμ±ν΄ μ£ΌμΈμ:
|
123 |
+
- ν΅μ¬ ν€μλλ₯Ό μ λͺ©, μμ λͺ©, 첫 λ¨λ½μ λ°°μΉ
|
124 |
+
- κ΄λ ¨ ν€μλλ₯Ό μμ°μ€λ½κ² λ³Έλ¬Έμ λΆμ°
|
125 |
+
- 300-500μ λΆλμ λͺ
νν λ¨λ½ ꡬμ±
|
126 |
+
- μ§λ¬Έ νμμ μμ λͺ© νμ©
|
127 |
+
- λͺ©λ‘, ν, κ°μ‘° ν
μ€νΈ λ± λ€μν μμ νμ©
|
128 |
+
- λ΄λΆ λ§ν¬ μ½μ
μμΉ νμ
|
129 |
+
- 2000-3000μ μ΄μμ μΆ©λΆν μ½ν
μΈ μ 곡
|
130 |
"""
|
131 |
+
}
|
132 |
+
|
133 |
+
# ν€λ³ μΆκ° μ§μΉ¨
|
134 |
+
tone_guides = {
|
135 |
+
"professional": "μ λ¬Έμ μ΄κ³ κΆμμλ μ΄μ‘°λ‘ μμ±νλ, μ λ¬Έ μ©μ΄λ μ μ ν μ€λͺ
ν΄ μ£ΌμΈμ. λ°μ΄ν°μ μ°κ΅¬ κ²°κ³Όλ₯Ό οΏ½οΏ½οΏ½μ¬μΌλ‘ λ
Όλ¦¬μ νλ¦μ μ μ§νμΈμ.",
|
136 |
+
"casual": "μΉκ·Όνκ³ λννλ― νΈμν μ΄μ‘°λ‘ μμ±ν΄ μ£ΌμΈμ. '~λ€μ', '~ν΄μ' κ°μ λν체λ₯Ό μ¬μ©νκ³ , κ°μΈμ κ²½νκ³Ό λΉμ λ₯Ό ν΅ν΄ λ΄μ©μ μ λ¬νμΈμ.",
|
137 |
+
"humorous": "μ λ¨Έμ μ¬μΉμλ ννμ μ μ ν νμ©ν΄ μ£ΌμΈμ. μ¬λ―Έμλ λΉμ λ μμ, κ°λ²Όμ΄ λλ΄μ ν¬ν¨νλ, μ 보μ μ νμ±κ³Ό μ μ©μ±μ μ μ§νμΈμ.",
|
138 |
+
"storytelling": "μ΄μΌκΈ°λ₯Ό λ€λ €μ£Όλ― κ°μ±μ μ΄κ³ λͺ°μ
κ° μλ ν€μΌλ‘ μμ±ν΄ μ£ΌμΈμ. μΈλ¬Ό, λ°°κ²½, κ°λ±, ν΄κ²°κ³Όμ μ΄ λ΄κΈ΄ λ΄λ¬ν°λΈ ꡬ쑰λ₯Ό νμ©νμΈμ."
|
139 |
+
}
|
140 |
+
|
141 |
+
# μ΅μ’
ν둬ννΈ μ‘°ν©
|
142 |
+
final_prompt = base_prompt
|
143 |
+
|
144 |
+
# μ νλ ν
νλ¦Ώ μ§μΉ¨ μΆκ°
|
145 |
+
if template in template_guides:
|
146 |
+
final_prompt += "\n" + template_guides[template]
|
147 |
+
|
148 |
+
# μ νλ ν€ μ§μΉ¨ μΆκ°
|
149 |
+
if tone in tone_guides:
|
150 |
+
final_prompt += f"\n\nν€μ€λ§€λ: {tone_guides[tone]}"
|
151 |
+
|
152 |
+
# κΈμ μ μ§μΉ¨ μΆκ°
|
153 |
+
final_prompt += f"\n\nμμ± μ μ€μμ¬ν\n9.1. κΈμ μ: {word_count-250}-{word_count+250}μ λ΄μΈ\n9.2. λ¬Έλ¨ κΈΈμ΄: 3-4λ¬Έμ₯ μ΄λ΄\n9.3. μκ°μ ꡬλΆ: μμ λͺ©, ꡬλΆμ , λ²νΈ λͺ©λ‘ νμ©\n9.4. λ°μ΄ν°: λͺ¨λ μ 보μ μΆμ² λͺ
μ\n9.5. κ°λ
μ±: λͺ
νν λ¨λ½ ꡬλΆκ³Ό κ°μ‘°μ μ¬μ©"
|
154 |
+
|
155 |
+
return final_prompt
|
156 |
|
157 |
# ββββββββββββββββββββββββββββββββ Brave Search API βββββββββββββββββββββββββ
|
158 |
def brave_search(query: str, count: int = 5):
|
|
|
169 |
"X-Subscription-Token": BRAVE_KEY
|
170 |
}
|
171 |
params = {"q": query, "count": str(count)}
|
172 |
+
|
173 |
+
for attempt in range(3): # μ΅λ 3λ² μ¬μλ
|
174 |
+
try:
|
175 |
+
r = requests.get(BRAVE_ENDPOINT, headers=headers, params=params, timeout=15)
|
176 |
+
r.raise_for_status()
|
177 |
+
data = r.json()
|
178 |
+
|
179 |
+
# κ²°κ³Ό νμ νμΈ λ° λ‘κΉ
|
180 |
+
logging.info(f"Brave κ²μ κ²°κ³Ό λ°μ΄ν° ꡬ쑰: {list(data.keys())}")
|
181 |
+
|
182 |
+
raw = data.get("web", {}).get("results") or data.get("results", [])
|
183 |
+
if not raw:
|
184 |
+
logging.warning(f"Brave κ²μ κ²°κ³Ό μμ. μλ΅: {data}")
|
185 |
+
raise ValueError("κ²μ κ²°κ³Όκ° μμ΅λλ€")
|
186 |
+
|
187 |
+
arts = []
|
188 |
+
for i, res in enumerate(raw[:count], 1):
|
189 |
+
url = res.get("url", res.get("link", ""))
|
190 |
+
host = re.sub(r"https?://(www\.)?", "", url).split("/")[0]
|
191 |
+
arts.append({
|
192 |
+
"index": i,
|
193 |
+
"title": res.get("title", "μ λͺ© μμ"),
|
194 |
+
"link": url,
|
195 |
+
"snippet": res.get("description", res.get("text", "λ΄μ© μμ")),
|
196 |
+
"displayed_link": host
|
197 |
+
})
|
198 |
+
|
199 |
+
logging.info(f"Brave κ²μ μ±κ³΅: {len(arts)}κ° κ²°κ³Ό")
|
200 |
+
return arts
|
201 |
+
|
202 |
+
except Exception as e:
|
203 |
+
logging.error(f"Brave κ²μ μ€ν¨ (μλ {attempt+1}/3): {e}")
|
204 |
+
if attempt < 2: # λ§μ§λ§ μλκ° μλλ©΄ λκΈ° ν μ¬μλ
|
205 |
+
time.sleep(2)
|
206 |
+
|
207 |
+
return [] # λͺ¨λ μλ μ€ν¨ μ λΉ λͺ©λ‘ λ°ν
|
208 |
|
209 |
def mock_results(query: str) -> str:
|
210 |
+
"""κ²μ API μ€ν¨ μ κ°μ κ²μ κ²°κ³Ό μ 곡"""
|
211 |
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
212 |
+
return (f"# κ²μ κ²°κ³Ό λ체 λ΄μ© (μμ±: {ts})\n\n"
|
213 |
+
f"κ²μ API νΈμΆμ΄ μ€ν¨νμ΅λλ€. μ£Όμ '{query}'μ λν΄ κΈ°μ‘΄ μ§μμ νμ©ν΄ λ΅λ³ν΄ μ£ΌμΈμ.\n\n"
|
214 |
+
f"λ€μ λ΄μ©μ΄ λμμ΄ λ μ μμ΅λλ€:\n\n"
|
215 |
+
f"- {query}μ κΈ°λ³Έ κ°λ
κ³Ό μ€μμ±\n"
|
216 |
+
f"- μΌλ°μ μΌλ‘ μλ €μ§ κ΄λ ¨ ν΅κ³μ νΈλ λ\n"
|
217 |
+
f"- ν΄λΉ μ£Όμ μ λν μ λ¬Έκ°λ€μ μΌλ°μ μΈ κ²¬ν΄\n"
|
218 |
+
f"- λ
μλ€μ΄ μ€μ λ‘ κΆκΈν΄ν λ§ν μ§λ¬Έλ€\n\n"
|
219 |
+
f"μ°Έκ³ : μ΄ λ΄μ©μ μ€μκ° κ²μ κ²°κ³Όκ° μλ λ체 μλ΄μ
λλ€.\n\n")
|
220 |
|
221 |
def do_web_search(query: str) -> str:
|
222 |
+
"""μΉ κ²μ μν λ° κ²°κ³Ό ν¬λ§·ν
"""
|
223 |
try:
|
224 |
arts = brave_search(query, 5)
|
225 |
+
if not arts:
|
226 |
+
logging.warning("κ²μ κ²°κ³Ό μμ, λ체 μ½ν
μΈ μ¬μ©")
|
227 |
+
return mock_results(query)
|
228 |
+
|
229 |
+
hdr = "# μΉ κ²μ κ²°κ³Ό\nμλ μ 보λ₯Ό μ°Έκ³ ν΄μ λ΅λ³νμΈμ.\n\n"
|
230 |
+
body = "\n".join(
|
231 |
+
f"### Result {a['index']}: {a['title']}\n\n{a['snippet']}\n\n"
|
232 |
+
f"**μΆμ²**: [{a['displayed_link']}]({a['link']})\n\n---\n"
|
233 |
+
for a in arts
|
234 |
+
)
|
235 |
+
return hdr + body
|
236 |
except Exception as e:
|
237 |
+
logging.error(f"μΉ κ²μ μ 체 νλ‘μΈμ€ μ€ν¨: {str(e)}")
|
|
|
|
|
238 |
return mock_results(query)
|
239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
# ββββββββββββββββββββββββββββββββ μ΄λ―Έμ§ Β· λ³ν μ νΈ ββββββββββββββββββββββββ
|
241 |
def generate_image(prompt, w=768, h=768, g=3.5, steps=30, seed=3):
|
242 |
if not prompt: return None, "ν둬ννΈ λΆμ‘±"
|
|
|
279 |
messages=[],
|
280 |
auto_save=True,
|
281 |
generate_image=False,
|
282 |
+
use_web_search=False,
|
283 |
+
blog_template="standard",
|
284 |
+
blog_tone="professional",
|
285 |
+
word_count=1750
|
286 |
)
|
287 |
for k, v in defaults.items():
|
288 |
st.session_state.setdefault(k, v)
|
289 |
|
290 |
# ββ μ¬μ΄λλ° μ»¨νΈλ‘€
|
291 |
sb = st.sidebar
|
292 |
+
sb.title("λΈλ‘κ·Έ μ€μ ")
|
293 |
+
|
294 |
+
# λΈλ‘κ·Έ ν
νλ¦Ώ λ° μ€νμΌ μ ν
|
295 |
+
sb.subheader("λΈλ‘κ·Έ μ€νμΌ μ€μ ")
|
296 |
+
sb.selectbox("λΈλ‘κ·Έ ν
νλ¦Ώ", options=list(BLOG_TEMPLATES.keys()),
|
297 |
+
format_func=lambda x: x.replace("_", " ").title(),
|
298 |
+
key="blog_template")
|
299 |
+
|
300 |
+
sb.selectbox("λΈλ‘κ·Έ ν€", options=list(BLOG_TONES.keys()),
|
301 |
+
format_func=lambda x: x.replace("_", " ").title(),
|
302 |
+
key="blog_tone")
|
303 |
+
|
304 |
+
sb.slider("λΈλ‘κ·Έ κΈΈμ΄ (λ¨μ΄ μ)", 800, 3000, 1750, key="word_count")
|
305 |
+
|
306 |
+
sb.subheader("κΈ°ν μ€μ ")
|
307 |
sb.toggle("μλ μ μ₯", key="auto_save")
|
308 |
sb.toggle("μ΄λ―Έμ§ μλ μμ±", key="generate_image")
|
309 |
+
|
310 |
+
# μΉ κ²μ ν κΈ (λͺ¨λν°λ§μ μν΄ μ μ§νλ κΈ°λ³Έκ°μ False)
|
311 |
+
search_enabled = sb.toggle("μΉ κ²μ μ¬μ©", value=False, key="use_web_search")
|
312 |
+
if search_enabled:
|
313 |
+
st.warning("β οΈ μΉ κ²μ κΈ°λ₯μ νμ¬ λΆμμ ν μ μμ΅λλ€. κ²μ κ²°κ³Όκ° μμΌλ©΄ κΈ°λ³Έ μ§μμΌλ‘ λ체λ©λλ€.")
|
314 |
|
315 |
# ββ μ΅κ·Ό λΈλ‘κ·Έ λ€μ΄λ‘λ (λ§ν¬λ€μ΄ / HTML)
|
316 |
latest_blog = next(
|
|
|
357 |
|
358 |
with st.chat_message("assistant"):
|
359 |
placeholder = st.empty(); answer = ""
|
360 |
+
|
361 |
+
# μ νλ ν
νλ¦Ώ, ν€, λ¨μ΄ μλ‘ μμ€ν
ν둬ννΈ μμ±
|
362 |
+
sys_prompt = get_system_prompt(
|
363 |
+
template=st.session_state.blog_template,
|
364 |
+
tone=st.session_state.blog_tone,
|
365 |
+
word_count=st.session_state.word_count
|
366 |
+
)
|
367 |
|
368 |
if st.session_state.use_web_search:
|
369 |
with st.spinner("μΉ κ²μ μ€β¦"):
|
|
|
429 |
"markdown>=3.5.1",
|
430 |
"pillow>=10.1.0"
|
431 |
]))
|
432 |
+
main()
|