aiqcamp commited on
Commit
bcd9bb8
ยท
verified ยท
1 Parent(s): 417aa68

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -195
app.py CHANGED
@@ -5,7 +5,7 @@ import time
5
  import logging
6
  import google.generativeai as genai
7
 
8
- # Configure logging
9
  logging.basicConfig(
10
  level=logging.INFO,
11
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
@@ -16,11 +16,11 @@ logging.basicConfig(
16
  )
17
  logger = logging.getLogger("idea_generator")
18
 
19
- # Get Gemini API Key from environment variable
20
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
21
  genai.configure(api_key=GEMINI_API_KEY)
22
 
23
- # Helper function to select one option from a transformation string with a slash
24
  def choose_alternative(transformation):
25
  if "/" not in transformation:
26
  return transformation
@@ -42,7 +42,7 @@ def choose_alternative(transformation):
42
  else:
43
  return random.choice([left, right])
44
 
45
- # Physical transformation categories and related changes
46
  physical_transformation_categories = {
47
  "๊ณต๊ฐ„์  ๋ณ€ํ™”": [
48
  "์ „์ง„/ํ›„์ง„ ์ด๋™", "์ขŒ/์šฐ ์ด๋™", "์ƒ์Šน/ํ•˜๊ฐ•", "ํ”ผ์น˜ ํšŒ์ „", "์š” ํšŒ์ „", "๋กค ํšŒ์ „",
@@ -101,103 +101,33 @@ physical_transformation_categories = {
101
  ]
102
  }
103
 
104
- # Marketing transformation categories
105
- marketing_transformation_categories = {
106
- "๋ธŒ๋žœ๋“œ/์•„์ด๋ดํ‹ฐํ‹ฐ ๋ณ€ํ™”": [
107
- "๋ธŒ๋žœ๋“œ๋ช… ๋ณ€๊ฒฝ/๋ฆฌ๋ธŒ๋žœ๋”ฉ", "๋กœ๊ณ  ์žฌ์„ค๊ณ„/ํ˜„๋Œ€ํ™”", "์Šฌ๋กœ๊ฑด ์—…๋ฐ์ดํŠธ/๋ณ€๊ฒฝ",
108
- "๋ธŒ๋žœ๋“œ ์ปฌ๋Ÿฌ ํŒ”๋ ˆํŠธ ๋ณ€๊ฒฝ", "๋ธŒ๋žœ๋“œ ๋ณด์ด์Šค/ํ†ค ์กฐ์ •", "๋ธŒ๋žœ๋“œ ํฌ์ง€์…”๋‹ ์žฌ์ •๋ฆฝ",
109
- "๋ธŒ๋žœ๋“œ ์Šคํ† ๋ฆฌ ์žฌ๊ตฌ์„ฑ", "๋ธŒ๋žœ๋“œ ์•„ํ‚คํ…์ฒ˜ ์žฌ๊ตฌ์„ฑ", "๋ธŒ๋žœ๋“œ ํผ์Šค๋„๋ฆฌํ‹ฐ ์ง„ํ™”",
110
- "๋ธŒ๋žœ๋“œ ์ด๋ฏธ์ง€ ์žฌ์ •๋ฆฝ"
111
- ],
112
- "์ œํ’ˆ/์„œ๋น„์Šค ๋ณ€ํ™”": [
113
- "๊ธฐ๋Šฅ์  ์—…๊ทธ๋ ˆ์ด๋“œ/๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ", "ํฌ์žฅ/ํŒจํ‚ค์ง• ์žฌ์„ค๊ณ„", "์ œํ’ˆ ์‚ฌ์ด์ฆˆ/์šฉ๋Ÿ‰ ์กฐ์ •",
114
- "SKU ํ™•์žฅ/์ถ•์†Œ", "๋งž์ถคํ˜•/๊ฐœ์ธํ™” ์˜ต์…˜ ์ถ”๊ฐ€", "ํ”„๋ฆฌ๋ฏธ์—„/๋ฒ ์ด์ง ๋ผ์ธ ์ถœ์‹œ",
115
- "ํ•œ์ •ํŒ/์‹œ์ฆŒ ์—๋””์…˜ ์ถœ์‹œ", "์ฝœ๋ผ๋ณด๋ ˆ์ด์…˜/ํฌ๋กœ์Šค์˜ค๋ฒ„ ์ œํ’ˆ", "์ง€์†๊ฐ€๋Šฅ์„ฑ ๊ฐœ์„ ",
116
- "๋ฒˆ๋“ค๋ง/์–ธ๋ฒˆ๋“ค๋ง ์ „๋žต ๋ณ€๊ฒฝ"
117
- ],
118
- "๊ฐ€๊ฒฉ ์ „๋žต ๋ณ€ํ™”": [
119
- "ํ”„๋ฆฌ๋ฏธ์—„/๋Ÿญ์…”๋ฆฌ ๊ฐ€๊ฒฉ ํฌ์ง€์…”๋‹", "๊ฐ€๊ฒฉ ํ•˜๋ฝ/๊ฒฝ์ œ์  ํฌ์ง€์…”๋‹", "๊ฐ€์น˜ ๊ธฐ๋ฐ˜ ๊ฐ€๊ฒฉ ์ฑ…์ •",
120
- "๋™์  ๊ฐ€๊ฒฉ ์ •์ฑ… ๋„์ž…", "๋ฉค๋ฒ„์‹ญ/๊ตฌ๋… ๋ชจ๋ธ ์ „ํ™˜", "๊ฐ€๊ฒฉ ์„ธ๋ถ„ํ™” ์ „๋žต",
121
- "ํ”„๋กœ๋ชจ์…˜ ๊ฐ€๊ฒฉ ์ „๋žต ๋ณ€๊ฒฝ", "์‹ฌ๋ฆฌ์  ๊ฐ€๊ฒฉ ์ฑ…์ • ์ ์šฉ", "๋ฒˆ๋“ค ๊ฐ€๊ฒฉ ์ „๋žต ๋„์ž…",
122
- "ํ”„๋ฆฌ๋ฏธ์—„/์ด์ฝ”๋…ธ๋ฏธ ์ด์ค‘ ์ „๋žต"
123
- ],
124
- "ํ”„๋กœ๋ชจ์…˜/์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ๋ณ€ํ™”": [
125
- "๋ฉ”์‹œ์ง€ ํ”„๋ ˆ์ด๋ฐ ๋ณ€๊ฒฝ", "ํƒ€๊ฒŸ ์˜ค๋””์–ธ์Šค ํ™•์žฅ/์žฌ์ •์˜", "๊ฐ์„ฑ์ /์ด์„ฑ์  ์†Œ๊ตฌ์  ์ „ํ™˜",
126
- "์Šคํ† ๋ฆฌํ…”๋ง ๋ฐฉ์‹ ๋ณ€ํ™”", "์ฝ˜ํ…์ธ  ๋งˆ์ผ€ํŒ… ์ „๋žต ์กฐ์ •", "ํฌ๋ฆฌ์—์ดํ‹ฐ๋ธŒ ๋ฐฉํ–ฅ์„ฑ ๋ณ€๊ฒฝ",
127
- "๊ด‘๊ณ  ์บ ํŽ˜์ธ ์žฌ์„ค๊ณ„", "๋ธŒ๋žœ๋“œ ์•ฐ๋ฐฐ์„œ๋”/์ธํ”Œ๋ฃจ์–ธ์„œ ๊ต์ฒด", "์–ธ์–ด/ํŠธ๋ก  ์กฐ์ •",
128
- "๋น„์ฃผ์–ผ ์•„์ด๋ดํ‹ฐํ‹ฐ ์—…๋ฐ์ดํŠธ"
129
- ],
130
- "์ฑ„๋„/์œ ํ†ต ๋ณ€ํ™”": [
131
- "์˜จ๋ผ์ธ/์˜คํ”„๋ผ์ธ ์ „๋žต ์ „ํ™˜", "์˜ด๋‹ˆ์ฑ„๋„ ํ†ตํ•ฉ/๋ถ„๋ฆฌ", "์œ ํ†ต ํŒŒํŠธ๋„ˆ์‹ญ ํ™•์žฅ/์ถ•์†Œ",
132
- "D2C(Direct-to-Consumer) ๋ชจ๋ธ ๋„์ž…", "๋ฆฌํ…Œ์ผ ๊ฒฝํ—˜ ์žฌ์„ค๊ณ„", "์„œ๋น„์Šค ๋”œ๋ฆฌ๋ฒ„๋ฆฌ ๋ฐฉ์‹ ๋ณ€๊ฒฝ",
133
- "ํŒ์—…/์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์œ ํ†ต ์ „๋žต", "์ง€์—ญ์  ํ™•์žฅ/์ถ•์†Œ", "ํŒŒํŠธ๋„ˆ ์ƒํƒœ๊ณ„ ์žฌ๊ตฌ์„ฑ",
134
- "๋””์ง€ํ„ธ ๋งˆ์ผ“ํ”Œ๋ ˆ์ด์Šค ์ „๋žต ๋ณ€ํ™”"
135
- ],
136
- "๊ณ ๊ฐ ๊ฒฝํ—˜ ๋ณ€ํ™”": [
137
- "๊ณ ๊ฐ ์—ฌ์ • ์žฌ์„ค๊ณ„", "ํผ์Šค๋„๋ผ์ด์ œ์ด์…˜/๋งž์ถคํ™” ๊ฐ•ํ™”", "์„œ๋น„์Šค ๋ ˆ๋ฒจ ์กฐ์ •",
138
- "๋กœ์—ดํ‹ฐ ํ”„๋กœ๊ทธ๋žจ ์žฌ๊ตฌ์„ฑ", "๊ณ ๊ฐ ์ฐธ์—ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋ณ€ํ™”", "์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค/UX ๊ฐœ์„ ",
139
- "๊ณ ๊ฐ ์„œ๋น„์Šค ํ”„๋กœํ† ์ฝœ ๋ณ€๊ฒฝ", "ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„ ์žฌ์„ค๊ณ„", "์ž๊ฐ€ ์„œ๋น„์Šค ์˜ต์…˜ ํ™•์žฅ",
140
- "์ฒดํ—˜ํ˜• ๋งˆ์ผ€ํŒ… ์š”์†Œ ๊ฐ•ํ™”"
141
- ],
142
- "๋””์ง€ํ„ธ ๋งˆ์ผ€ํŒ… ๋ณ€ํ™”": [
143
- "๊ฒ€์ƒ‰ ์ตœ์ ํ™”(SEO) ์ „๋žต ๋ณ€๊ฒฝ", "์†Œ์…œ ๋ฏธ๋””์–ด ํ”Œ๋žซํผ ํฌํŠธํด๋ฆฌ์˜ค ์กฐ์ •", "์ฝ˜ํ…์ธ  ํƒ€์ž…/ํฌ๋งท ๋‹ค์–‘ํ™”",
144
- "๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ํƒ€๊ฒŸํŒ… ์ •๊ตํ™”", "๋งˆ์ผ€ํŒ… ์ž๋™ํ™” ํ™•์žฅ/์กฐ์ •", "๋””์ง€ํ„ธ ๊ด‘๊ณ  ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ตœ์ ํ™”",
145
- "์ด๋ฉ”์ผ ๋งˆ์ผ€ํŒ… ์ „๋žต ๋ณ€ํ™”", "๋ชจ๋ฐ”์ผ ์ตœ์ ํ™” ์ „๋žต ๊ฐ•ํ™”", "AR/VR ๋งˆ์ผ€ํŒ… ์š”์†Œ ํ†ตํ•ฉ",
146
- "์ธ๊ณต์ง€๋Šฅ ๊ธฐ๋ฐ˜ ๋งˆ์ผ€ํŒ… ๋„์ž…"
147
- ],
148
- "์‹œ์žฅ ํฌ์ง€์…”๋‹ ๋ณ€ํ™”": [
149
- "์‹œ์žฅ ์„ธ๊ทธ๋จผํŠธ ์žฌ์ •์˜", "๊ฒฝ์Ÿ์‚ฌ ๋Œ€๋น„ ํฌ์ง€์…”๋‹ ๋ณ€๊ฒฝ", "ํ‹ˆ์ƒˆ์‹œ์žฅ/๋ฉ”์ธ์ŠคํŠธ๋ฆผ ์ „๋žต ์ „ํ™˜",
150
- "์‚ฐ์—…/์นดํ…Œ๊ณ ๋ฆฌ ํšก๋‹จ ์žฌํฌ์ง€์…”๋‹", "์ง€๋ฆฌ์  ํƒ€๊ฒŸ ์‹œ์žฅ ํ™•์žฅ/์ถ•์†Œ", "๊ธ€๋กœ๋ฒŒ/๋กœ์ปฌ ํฌ์ง€์…”๋‹ ์กฐ์ •",
151
- "๋ฌธํ™”์  ๋งฅ๋ฝ ์ ์‘", "์ฃผ์š” ์‹œ์žฅ ๋ฉ”์‹œ์ง€ ์žฌ์ •์˜", "ํŠน์„ฑ ์ฐจ๋ณ„ํ™” ๊ฐ•ํ™”/๋ณ€๊ฒฝ",
152
- "๊ฐ€์น˜ ์ œ์•ˆ ์žฌ๊ตฌ์„ฑ"
153
- ],
154
- "ํ˜์‹ /ํŠธ๋ Œ๋“œ ๋ฐ˜์‘": [
155
- "์ฒจ๋‹จ ๊ธฐ์ˆ  ํ†ตํ•ฉ", "ํŠธ๋ Œ๋“œ ์–ผ๋ฆฌ์–ด๋‹ตํ„ฐ/ํŒ”๋กœ์›Œ ํฌ์ง€์…”๋‹", "์ง€์†๊ฐ€๋Šฅ์„ฑ/์นœํ™˜๊ฒฝ ์ „๋žต ๊ฐ•ํ™”",
156
- "์‚ฌํšŒ์  ์ฑ…์ž„ ์ด๋‹ˆ์…”ํ‹ฐ๋ธŒ ๋„์ž…", "๋””์ง€ํ„ธ ํŠธ๋žœ์Šคํฌ๋ฉ”์ด์…˜ ๊ฐ€์†ํ™”", "ํ—ฌ์Šค/์›ฐ๋น™ ์š”์†Œ ๊ฐ•ํ™”",
157
- "์„ธ๋Œ€๋ณ„ ํŠธ๋ Œ๋“œ ๋ฐ˜์‘ ์ ์šฉ", "๋ฏธ๋ž˜์ง€ํ–ฅ์  ํ˜์‹  ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜", "๋ฌธํ™”์  ํ˜„์ƒ ์—ฐ๊ณ„ ๋งˆ์ผ€ํŒ…",
158
- "ํฌ๋กœ์Šค ์ธ๋”์ŠคํŠธ๋ฆฌ ํ˜์‹  ์ ์šฉ"
159
- ],
160
- "๋ฐ์ดํ„ฐ/๋ถ„์„ ๊ธฐ๋ฐ˜ ๋ณ€ํ™”": [
161
- "๊ณ ๊ฐ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ๋ฐฉ์‹ ๋ณ€๊ฒฝ", "์˜ˆ์ธก ๋ถ„์„ ๋ชจ๋ธ ๋„์ž…/๊ฐ•ํ™”", "A/B ํ…Œ์ŠคํŒ… ์ฒด๊ณ„ ๊ตฌ์ถ•/ํ™•์žฅ",
162
- "์†Œ๋น„์ž ์ธ์‚ฌ์ดํŠธ ๋ฐœ๊ตด ๋ฐฉ์‹ ๋ณ€ํ™”", "๋งˆ์ผ€ํŒ… ROI ์ธก์ • ํ”„๋ ˆ์ž„์›Œํฌ ๋ณ€๊ฒฝ", "์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ํ™œ์šฉ ์ฒด๊ณ„ ๊ตฌ์ถ•",
163
- "ํ”„๋ผ์ด๋ฒ„์‹œ ์ค‘์‹ฌ ๋ฐ์ดํ„ฐ ์ „๋žต", "์„ธ๊ทธ๋จผํ…Œ์ด์…˜ ๋ชจ๋ธ ๊ณ ๋„ํ™”", "๋””์ง€ํ„ธ ํ–‰๋™ ๋ถ„์„ ์ฒด๊ณ„ ๊ฐ•ํ™”",
164
- "ํ†ตํ•ฉ ๋งˆ์ผ€ํŒ… ๋ฐ์ดํ„ฐ ๋Œ€์‹œ๋ณด๋“œ ๊ตฌ์ถ•"
165
- ]
166
- }
167
-
168
  def query_gemini_api(prompt):
169
  try:
170
- # Use a stable model
171
  model = genai.GenerativeModel('gemini-2.0-flash-thinking-exp-01-21')
172
 
173
- # Generate content with a simple approach
174
  response = model.generate_content(prompt)
175
-
176
- # Check the response - defensive handling
177
  try:
178
- # First try .text attribute
179
  if hasattr(response, 'text'):
180
  return response.text
181
 
182
- # Try accessing candidates (safely)
183
  if hasattr(response, 'candidates') and response.candidates:
184
  if len(response.candidates) > 0:
185
  candidate = response.candidates[0]
186
-
187
- # Try accessing content and parts
188
  if hasattr(candidate, 'content'):
189
  content = candidate.content
190
-
191
  if hasattr(content, 'parts') and content.parts:
192
  if len(content.parts) > 0:
193
  return content.parts[0].text
194
-
195
- # Direct parts access attempt
196
  if hasattr(response, 'parts') and response.parts:
197
  if len(response.parts) > 0:
198
  return response.parts[0].text
199
-
200
- # Fallback if all attempts fail
201
  return "Unable to generate a response. API response structure is different than expected."
202
 
203
  except Exception as inner_e:
@@ -206,23 +136,29 @@ def query_gemini_api(prompt):
206
 
207
  except Exception as e:
208
  logger.error(f"Error calling Gemini API: {e}")
209
-
210
- # Check for API key validation error
211
  if "API key not valid" in str(e):
212
  return "API key is not valid. Please check your GEMINI_API_KEY environment variable."
213
-
214
  return f"An error occurred while calling the API: {str(e)}"
215
 
216
- # Generate enhanced descriptions without unnecessary questions or explanations
217
- def enhance_with_llm(base_description, obj_name, category, is_marketing=False):
218
- domain = "๋งˆ์ผ€ํŒ…" if is_marketing else "๋ฌผ๋ฆฌ์ "
219
- prompt = f"""๋‹ค์Œ์€ '{obj_name}'์˜ '{domain} {category}' ๊ด€๋ จ ๊ฐ„๋‹จํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค:
 
 
220
  "{base_description}"
221
- ํ•ด๋‹น ์„ค๋ช…์„ 3-4๋ฌธ์žฅ์˜ ์ฐฝ์˜์ ์ธ ๋‹ต๋ณ€์œผ๋กœ ํ™•์žฅํ•˜์—ฌ ์ถœ๋ ฅํ•˜๋ผ."""
 
 
 
 
 
222
  return query_gemini_api(prompt)
223
 
224
- # Generate physical transformations for a single object
225
- def generate_single_object_physical_transformations(obj):
 
 
226
  results = {}
227
  for category, transformations in physical_transformation_categories.items():
228
  transformation = choose_alternative(random.choice(transformations))
@@ -230,17 +166,10 @@ def generate_single_object_physical_transformations(obj):
230
  results[category] = {"base": base_description, "enhanced": None}
231
  return results
232
 
233
- # Generate marketing transformations for a single object
234
- def generate_single_object_marketing_transformations(obj):
235
- results = {}
236
- for category, transformations in marketing_transformation_categories.items():
237
- transformation = choose_alternative(random.choice(transformations))
238
- base_description = f"{obj}์ด(๊ฐ€) {transformation} ์ „๋žต์„ ์‹คํ–‰ํ–ˆ๋‹ค"
239
- results[category] = {"base": base_description, "enhanced": None}
240
- return results
241
-
242
- # Generate physical transformations for two objects
243
- def generate_two_objects_physical_interaction(obj1, obj2):
244
  results = {}
245
  for category, transformations in physical_transformation_categories.items():
246
  transformation = choose_alternative(random.choice(transformations))
@@ -252,21 +181,10 @@ def generate_two_objects_physical_interaction(obj1, obj2):
252
  results[category] = {"base": base_description, "enhanced": None}
253
  return results
254
 
255
- # Generate marketing transformations for two objects
256
- def generate_two_objects_marketing_interaction(obj1, obj2):
257
- results = {}
258
- for category, transformations in marketing_transformation_categories.items():
259
- transformation = choose_alternative(random.choice(transformations))
260
- template = random.choice([
261
- "{obj1}์ด(๊ฐ€) {obj2}์˜ ๋ธŒ๋žœ๋“œ ํŠน์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ {change}๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค",
262
- "{obj1}๊ณผ(์™€) {obj2}์˜ ํ˜‘์—…์œผ๋กœ {change}๊ฐ€ ์‹œ์žฅ์— ๋„์ž…๋˜์—ˆ๋‹ค"
263
- ])
264
- base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
265
- results[category] = {"base": base_description, "enhanced": None}
266
- return results
267
-
268
- # Generate physical transformations for three objects
269
- def generate_three_objects_physical_interaction(obj1, obj2, obj3):
270
  results = {}
271
  for category, transformations in physical_transformation_categories.items():
272
  transformation = choose_alternative(random.choice(transformations))
@@ -278,82 +196,43 @@ def generate_three_objects_physical_interaction(obj1, obj2, obj3):
278
  results[category] = {"base": base_description, "enhanced": None}
279
  return results
280
 
281
- # Generate marketing transformations for three objects
282
- def generate_three_objects_marketing_interaction(obj1, obj2, obj3):
283
- results = {}
284
- for category, transformations in marketing_transformation_categories.items():
285
- transformation = choose_alternative(random.choice(transformations))
286
- template = random.choice([
287
- "{obj1}, {obj2}, {obj3}์ด(๊ฐ€) ๊ณต๋™ ๋งˆ์ผ€ํŒ…์œผ๋กœ {change}๊ฐ€ ์‹œ๋„ˆ์ง€๋ฅผ ์ฐฝ์ถœํ–ˆ๋‹ค",
288
- "{obj1}์ด(๊ฐ€) {obj2}์™€(๊ณผ) {obj3}์˜ ๊ณ ๊ฐ์ธต์„ ํ†ตํ•ฉํ•˜์—ฌ {change}๋กœ ์ƒˆ๋กœ์šด ์‹œ์žฅ์„ ์ฐฝ์ถœํ–ˆ๋‹ค"
289
- ])
290
- base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
291
- results[category] = {"base": base_description, "enhanced": None}
292
- return results
293
-
294
- # Enhance descriptions using the LLM
295
- def enhance_descriptions(results, objects, is_marketing=False):
296
  obj_name = " ๋ฐ ".join([obj for obj in objects if obj])
297
  for category, result in results.items():
298
- result["enhanced"] = enhance_with_llm(result["base"], obj_name, category, is_marketing)
299
  return results
300
 
301
- # Generate physical transformations based on number of objects
302
- def generate_physical_transformations(text1, text2=None, text3=None):
303
- if text2 and text3:
304
- results = generate_three_objects_physical_interaction(text1, text2, text3)
305
- objects = [text1, text2, text3]
306
- elif text2:
307
- results = generate_two_objects_physical_interaction(text1, text2)
308
- objects = [text1, text2]
309
- else:
310
- results = generate_single_object_physical_transformations(text1)
311
- objects = [text1]
312
- return enhance_descriptions(results, objects, is_marketing=False)
313
-
314
- # Generate marketing transformations based on number of objects
315
- def generate_marketing_transformations(text1, text2=None, text3=None):
316
  if text2 and text3:
317
- results = generate_three_objects_marketing_interaction(text1, text2, text3)
318
  objects = [text1, text2, text3]
319
  elif text2:
320
- results = generate_two_objects_marketing_interaction(text1, text2)
321
  objects = [text1, text2]
322
  else:
323
- results = generate_single_object_marketing_transformations(text1)
324
  objects = [text1]
325
- return enhance_descriptions(results, objects, is_marketing=True)
326
 
327
- # Format results for display
 
 
328
  def format_results(results):
329
  formatted = ""
330
  for category, result in results.items():
331
- formatted += f"## {category}\n**๊ธฐ๋ณธ ๋ณ€ํ™”**: {result['base']}\n\n**์ž์„ธํ•œ ์„ค๋ช…**: {result['enhanced']}\n\n---\n\n"
332
  return formatted
333
 
334
- # Process physical inputs and generate transformations
335
- def process_physical_inputs(text1, text2, text3):
336
- messages = []
337
- messages.append("์ž…๋ ฅ๊ฐ’ ํ™•์ธ ์ค‘...")
338
- time.sleep(0.3)
339
- text1 = text1.strip() if text1 else None
340
- text2 = text2.strip() if text2 else None
341
- text3 = text3.strip() if text3 else None
342
- if not text1:
343
- messages.append("์˜ค๋ฅ˜: ์ตœ์†Œ ํ•˜๋‚˜์˜ ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.")
344
- return "\n\n".join(messages)
345
- messages.append("๋ฌผ๋ฆฌ์  ๋ณ€ํ™” ์•„์ด๋””์–ด ์ƒ์„ฑ ์ค‘...")
346
- time.sleep(0.3)
347
- results = generate_physical_transformations(text1, text2, text3)
348
- messages.append("๊ฒฐ๊ณผ ํฌ๋งทํŒ… ์ค‘...")
349
- time.sleep(0.3)
350
- formatted = format_results(results)
351
- messages.append("์™„๋ฃŒ!")
352
- messages.append(formatted)
353
- return "\n\n".join(messages)
354
-
355
- # Process marketing inputs and generate transformations
356
- def process_marketing_inputs(text1, text2, text3):
357
  messages = []
358
  messages.append("์ž…๋ ฅ๊ฐ’ ํ™•์ธ ์ค‘...")
359
  time.sleep(0.3)
@@ -363,24 +242,34 @@ def process_marketing_inputs(text1, text2, text3):
363
  if not text1:
364
  messages.append("์˜ค๋ฅ˜: ์ตœ์†Œ ํ•˜๋‚˜์˜ ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.")
365
  return "\n\n".join(messages)
366
- messages.append("๋งˆ์ผ€ํŒ… ๋ณ€ํ™” ์•„์ด๋””์–ด ์ƒ์„ฑ ์ค‘...")
 
367
  time.sleep(0.3)
368
- results = generate_marketing_transformations(text1, text2, text3)
 
369
  messages.append("๊ฒฐ๊ณผ ํฌ๋งทํŒ… ์ค‘...")
370
  time.sleep(0.3)
371
  formatted = format_results(results)
 
372
  messages.append("์™„๋ฃŒ!")
373
  messages.append(formatted)
 
374
  return "\n\n".join(messages)
375
 
376
- # Check for API key and return warning message if needed
 
 
377
  def get_warning_message():
378
  if not GEMINI_API_KEY:
379
  return "โš ๏ธ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ GEMINI_API_KEY๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. Gemini API ํ‚ค๋ฅผ ์„ค์ •ํ•˜์„ธ์š”."
380
  return ""
381
 
382
- # Create the Gradio UI
383
- with gr.Blocks(title="ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ฐฝ์˜์  ์•„์ด๋””์–ด ์ƒ์„ฑ๊ธฐ", theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")) as demo:
 
 
 
 
384
  gr.HTML("""
385
  <style>
386
  body { background: linear-gradient(135deg, #e0eafc, #cfdef3); font-family: 'Arial', sans-serif; }
@@ -392,23 +281,26 @@ with gr.Blocks(title="ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ฐฝ์˜์  ์•„์ด๋””์–ด ์ƒ์„ฑ๊ธฐ", theme=
392
  .gr-button { background-color: #4CAF50; color: white; border: none; border-radius: 4px; padding: 8px 16px; }
393
  </style>
394
  """)
395
- gr.Markdown("# ๐Ÿš€ ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ฐฝ์˜์  ์•„์ด๋””์–ด ์ƒ์„ฑ๊ธฐ")
396
- gr.Markdown("์ž…๋ ฅํ•œ ํ‚ค์›Œ๋“œ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ฐฝ์˜์ ์ธ ๋ฌผ๋ฆฌ์ /๋งˆ์ผ€ํŒ… ๋ณ€ํ™” ์•„์ด๋””์–ด๋ฅผ ๋„์ถœํ•ฉ๋‹ˆ๋‹ค. ์ตœ๋Œ€ 3๊ฐœ์˜ ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๏ฟฝ๏ฟฝ๋‹ค.")
 
 
397
  warning = gr.Markdown(get_warning_message())
 
 
398
  with gr.Row():
399
  with gr.Column(scale=1):
400
  text_input1 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 1 (ํ•„์ˆ˜)", placeholder="์˜ˆ: ์Šค๋งˆํŠธํฐ")
401
  text_input2 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 2 (์„ ํƒ)", placeholder="์˜ˆ: ์ธ๊ณต์ง€๋Šฅ")
402
  text_input3 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 3 (์„ ํƒ)", placeholder="์˜ˆ: ํ—ฌ์Šค์ผ€์–ด")
403
  submit_button = gr.Button("์•„์ด๋””์–ด ์ƒ์„ฑํ•˜๊ธฐ")
 
 
404
  with gr.Column(scale=2):
405
- with gr.Tabs():
406
- with gr.TabItem("๋ฌผ๋ฆฌ์  ๋ณ€ํ™” ์•„์ด๋””์–ด", id="physical_tab"):
407
- physical_output = gr.Markdown(label="๋ฌผ๋ฆฌ์  ๋ณ€ํ™” ์•„์ด๋””์–ด ๊ฒฐ๊ณผ")
408
- with gr.TabItem("๋งˆ์ผ€ํŒ… ๋ณ€ํ™” ์•„์ด๋””์–ด", id="marketing_tab"):
409
- marketing_output = gr.Markdown(label="๋งˆ์ผ€ํŒ… ๋ณ€ํ™” ์•„์ด๋””์–ด ๊ฒฐ๊ณผ")
410
-
411
- # Add some example combinations
412
  gr.Examples(
413
  examples=[
414
  ["์Šค๋งˆํŠธํฐ", "", ""],
@@ -419,9 +311,10 @@ with gr.Blocks(title="ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ฐฝ์˜์  ์•„์ด๋””์–ด ์ƒ์„ฑ๊ธฐ", theme=
419
  inputs=[text_input1, text_input2, text_input3],
420
  )
421
 
422
- # Connect the button click events to functions
423
- submit_button.click(fn=process_physical_inputs, inputs=[text_input1, text_input2, text_input3], outputs=physical_output)
424
- submit_button.click(fn=process_marketing_inputs, inputs=[text_input1, text_input2, text_input3], outputs=marketing_output)
 
425
 
426
  if __name__ == "__main__":
427
- demo.launch(debug=True)
 
5
  import logging
6
  import google.generativeai as genai
7
 
8
+ # ๋กœ๊น… ์„ค์ •
9
  logging.basicConfig(
10
  level=logging.INFO,
11
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
 
16
  )
17
  logger = logging.getLogger("idea_generator")
18
 
19
+ # Gemini API ํ‚ค๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜ GEMINI_API_KEY์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
20
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
21
  genai.configure(api_key=GEMINI_API_KEY)
22
 
23
+ # ์Šฌ๋ž˜์‹œ("/")๊ฐ€ ํฌํ•จ๋œ ๋ณ€ํ™˜ ๋ฌธ์ž์—ด์—์„œ ๋‘ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋งŒ ์„ ํƒํ•˜๋Š” ํ—ฌํผ ํ•จ์ˆ˜
24
  def choose_alternative(transformation):
25
  if "/" not in transformation:
26
  return transformation
 
42
  else:
43
  return random.choice([left, right])
44
 
45
+ # ์ฐฝ์˜์ ์ธ ๋ชจ๋ธ/์ปจ์…‰/ํ˜•์ƒ ๋ณ€ํ™” ์•„์ด๋””์–ด๋ฅผ ์œ„ํ•œ ์นดํ…Œ๊ณ ๋ฆฌ (๊ธฐ์กด '๋ฌผ๋ฆฌ์  ๋ณ€ํ™”' ์‚ฌ์ „ ์œ ์ง€)
46
  physical_transformation_categories = {
47
  "๊ณต๊ฐ„์  ๋ณ€ํ™”": [
48
  "์ „์ง„/ํ›„์ง„ ์ด๋™", "์ขŒ/์šฐ ์ด๋™", "์ƒ์Šน/ํ•˜๊ฐ•", "ํ”ผ์น˜ ํšŒ์ „", "์š” ํšŒ์ „", "๋กค ํšŒ์ „",
 
101
  ]
102
  }
103
 
104
+ ##############################################################################
105
+ # Gemini API ํ˜ธ์ถœ ํ•จ์ˆ˜ (์˜ˆ: gemini-2.0-flash-thinking-exp-01-21 -> ๋‹ค๋ฅธ ๋ชจ๋ธ ์‚ฌ์šฉ ์‹œ ์ˆ˜์ •)
106
+ ##############################################################################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  def query_gemini_api(prompt):
108
  try:
109
+ # ์˜ˆ์‹œ: ๊ธฐ์กด gemini-2.0... ๋Œ€์‹ , ๋‹ค๋ฅธ ๋ชจ๋ธ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ต์ฒดํ•˜์„ธ์š”.
110
  model = genai.GenerativeModel('gemini-2.0-flash-thinking-exp-01-21')
111
 
 
112
  response = model.generate_content(prompt)
113
+
114
+ # ์‘๋‹ต ๊ตฌ์กฐ ๋ฐฉ์–ด์ ์œผ๋กœ ์ฒ˜๋ฆฌ
115
  try:
 
116
  if hasattr(response, 'text'):
117
  return response.text
118
 
 
119
  if hasattr(response, 'candidates') and response.candidates:
120
  if len(response.candidates) > 0:
121
  candidate = response.candidates[0]
 
 
122
  if hasattr(candidate, 'content'):
123
  content = candidate.content
 
124
  if hasattr(content, 'parts') and content.parts:
125
  if len(content.parts) > 0:
126
  return content.parts[0].text
 
 
127
  if hasattr(response, 'parts') and response.parts:
128
  if len(response.parts) > 0:
129
  return response.parts[0].text
130
+
 
131
  return "Unable to generate a response. API response structure is different than expected."
132
 
133
  except Exception as inner_e:
 
136
 
137
  except Exception as e:
138
  logger.error(f"Error calling Gemini API: {e}")
 
 
139
  if "API key not valid" in str(e):
140
  return "API key is not valid. Please check your GEMINI_API_KEY environment variable."
 
141
  return f"An error occurred while calling the API: {str(e)}"
142
 
143
+ ##############################################################################
144
+ # ์„ค๋ช… ํ™•์žฅ ํ•จ์ˆ˜: "๋ชจ๋ธ/์ปจ์…‰/ํ˜•์ƒ์˜ ๋ณ€ํ™”์— ๋Œ€ํ•œ ์ดํ•ด์™€ ํ˜์‹  ํฌ์ธํŠธ, ๊ธฐ๋Šฅ์„ฑ ๋“ฑ์„ ์ค‘์‹ฌ"์œผ๋กœ
145
+ ##############################################################################
146
+ def enhance_with_llm(base_description, obj_name, category):
147
+ prompt = f"""
148
+ ๋‹ค์Œ์€ '{obj_name}'์˜ '{category}' ๊ด€๋ จ ๊ฐ„๋‹จํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค:
149
  "{base_description}"
150
+
151
+ ์œ„ ๋‚ด์šฉ์„ ๋ณด๋‹ค ๊ตฌ์ฒดํ™”ํ•˜์—ฌ,
152
+ 1) ์ฐฝ์˜์ ์ธ ๋ชจ๋ธ/์ปจ์…‰/ํ˜•์ƒ์˜ ๋ณ€ํ™”์— ๋Œ€ํ•œ ์ดํ•ด,
153
+ 2) ํ˜์‹  ํฌ์ธํŠธ์™€ ๊ธฐ๋Šฅ์„ฑ ๋“ฑ์„ ์ค‘์‹ฌ์œผ๋กœ
154
+ 3~4๋ฌธ์žฅ์˜ ์•„์ด๋””์–ด๋กœ ํ™•์žฅํ•ด ์ฃผ์„ธ์š”.
155
+ """
156
  return query_gemini_api(prompt)
157
 
158
+ ##############################################################################
159
+ # ๋‹จ์ผ ํ‚ค์›Œ๋“œ(์˜ค๋ธŒ์ ํŠธ)์— ๋Œ€ํ•œ "์ฐฝ์˜์  ๋ณ€ํ™” ์•„์ด๋””์–ด" ์ƒ์„ฑ
160
+ ##############################################################################
161
+ def generate_single_object_transformations(obj):
162
  results = {}
163
  for category, transformations in physical_transformation_categories.items():
164
  transformation = choose_alternative(random.choice(transformations))
 
166
  results[category] = {"base": base_description, "enhanced": None}
167
  return results
168
 
169
+ ##############################################################################
170
+ # ๋‘ ํ‚ค์›Œ๋“œ์— ๋Œ€ํ•œ "์ฐฝ์˜์  ๋ณ€ํ™” ์•„์ด๋””์–ด" ์ƒ์„ฑ
171
+ ##############################################################################
172
+ def generate_two_objects_interaction(obj1, obj2):
 
 
 
 
 
 
 
173
  results = {}
174
  for category, transformations in physical_transformation_categories.items():
175
  transformation = choose_alternative(random.choice(transformations))
 
181
  results[category] = {"base": base_description, "enhanced": None}
182
  return results
183
 
184
+ ##############################################################################
185
+ # ์„ธ ํ‚ค์›Œ๋“œ์— ๋Œ€ํ•œ "์ฐฝ์˜์  ๋ณ€ํ™” ์•„์ด๋””์–ด" ์ƒ์„ฑ
186
+ ##############################################################################
187
+ def generate_three_objects_interaction(obj1, obj2, obj3):
 
 
 
 
 
 
 
 
 
 
 
188
  results = {}
189
  for category, transformations in physical_transformation_categories.items():
190
  transformation = choose_alternative(random.choice(transformations))
 
196
  results[category] = {"base": base_description, "enhanced": None}
197
  return results
198
 
199
+ ##############################################################################
200
+ # ์ƒ์„ฑ๋œ ๊ธฐ๋ณธ ์„ค๋ช…์„ LLM์„ ํ†ตํ•ด ํ™•์žฅ
201
+ ##############################################################################
202
+ def enhance_descriptions(results, objects):
 
 
 
 
 
 
 
 
 
 
 
203
  obj_name = " ๋ฐ ".join([obj for obj in objects if obj])
204
  for category, result in results.items():
205
+ result["enhanced"] = enhance_with_llm(result["base"], obj_name, category)
206
  return results
207
 
208
+ ##############################################################################
209
+ # ์‚ฌ์šฉ์ž ์ž…๋ ฅ(์ตœ๋Œ€ 3๊ฐœ ํ‚ค์›Œ๋“œ)์— ๋”ฐ๋ผ ์ฐฝ์˜์  ๋ณ€ํ™” ์•„์ด๋””์–ด ์ƒ์„ฑ
210
+ ##############################################################################
211
+ def generate_transformations(text1, text2=None, text3=None):
 
 
 
 
 
 
 
 
 
 
 
212
  if text2 and text3:
213
+ results = generate_three_objects_interaction(text1, text2, text3)
214
  objects = [text1, text2, text3]
215
  elif text2:
216
+ results = generate_two_objects_interaction(text1, text2)
217
  objects = [text1, text2]
218
  else:
219
+ results = generate_single_object_transformations(text1)
220
  objects = [text1]
221
+ return enhance_descriptions(results, objects)
222
 
223
+ ##############################################################################
224
+ # ๊ฒฐ๊ณผ ํฌ๋งทํŒ…
225
+ ##############################################################################
226
  def format_results(results):
227
  formatted = ""
228
  for category, result in results.items():
229
+ formatted += f"## {category}\n**๊ธฐ๋ณธ ์•„์ด๋””์–ด**: {result['base']}\n\n**ํ™•์žฅ๋œ ์•„์ด๋””์–ด**: {result['enhanced']}\n\n---\n\n"
230
  return formatted
231
 
232
+ ##############################################################################
233
+ # Gradio UI์—์„œ ํ˜ธ์ถœํ•  ํ•จ์ˆ˜
234
+ ##############################################################################
235
+ def process_inputs(text1, text2, text3):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  messages = []
237
  messages.append("์ž…๋ ฅ๊ฐ’ ํ™•์ธ ์ค‘...")
238
  time.sleep(0.3)
 
242
  if not text1:
243
  messages.append("์˜ค๋ฅ˜: ์ตœ์†Œ ํ•˜๋‚˜์˜ ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.")
244
  return "\n\n".join(messages)
245
+
246
+ messages.append("์ฐฝ์˜์ ์ธ ๋ชจ๋ธ/์ปจ์…‰/ํ˜•์ƒ ๋ณ€ํ™” ์•„์ด๋””์–ด ์ƒ์„ฑ ์ค‘...")
247
  time.sleep(0.3)
248
+ results = generate_transformations(text1, text2, text3)
249
+
250
  messages.append("๊ฒฐ๊ณผ ํฌ๋งทํŒ… ์ค‘...")
251
  time.sleep(0.3)
252
  formatted = format_results(results)
253
+
254
  messages.append("์™„๋ฃŒ!")
255
  messages.append(formatted)
256
+
257
  return "\n\n".join(messages)
258
 
259
+ ##############################################################################
260
+ # API ํ‚ค ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€
261
+ ##############################################################################
262
  def get_warning_message():
263
  if not GEMINI_API_KEY:
264
  return "โš ๏ธ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ GEMINI_API_KEY๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. Gemini API ํ‚ค๋ฅผ ์„ค์ •ํ•˜์„ธ์š”."
265
  return ""
266
 
267
+ ##############################################################################
268
+ # Gradio UI
269
+ ##############################################################################
270
+ with gr.Blocks(title="ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ฐฝ์˜์  ๋ณ€ํ™” ์•„์ด๋””์–ด ์ƒ์„ฑ๊ธฐ",
271
+ theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")) as demo:
272
+
273
  gr.HTML("""
274
  <style>
275
  body { background: linear-gradient(135deg, #e0eafc, #cfdef3); font-family: 'Arial', sans-serif; }
 
281
  .gr-button { background-color: #4CAF50; color: white; border: none; border-radius: 4px; padding: 8px 16px; }
282
  </style>
283
  """)
284
+
285
+ gr.Markdown("# ๐Ÿš€ ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ฐฝ์˜์  ๋ณ€ํ™” ์•„์ด๋””์–ด ์ƒ์„ฑ๊ธฐ")
286
+ gr.Markdown("์ž…๋ ฅํ•œ **ํ‚ค์›Œ๋“œ**(์ตœ๋Œ€ 3๊ฐœ)๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ, **์ฐฝ์˜์ ์ธ ๋ชจ๋ธ/์ปจ์…‰/ํ˜•์ƒ ๋ณ€ํ™”**์— ๋Œ€ํ•œ ์ดํ•ด์™€ **ํ˜์‹  ํฌ์ธํŠธ**, **๊ธฐ๋Šฅ์„ฑ** ๋“ฑ์„ ์ค‘์‹ฌ์œผ๋กœ ํ™•์žฅ๋œ ์•„์ด๋””์–ด๋ฅผ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค.")
287
+
288
  warning = gr.Markdown(get_warning_message())
289
+
290
+ # ์ขŒ์ธก ์ž…๋ ฅ ์˜์—ญ
291
  with gr.Row():
292
  with gr.Column(scale=1):
293
  text_input1 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 1 (ํ•„์ˆ˜)", placeholder="์˜ˆ: ์Šค๋งˆํŠธํฐ")
294
  text_input2 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 2 (์„ ํƒ)", placeholder="์˜ˆ: ์ธ๊ณต์ง€๋Šฅ")
295
  text_input3 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 3 (์„ ํƒ)", placeholder="์˜ˆ: ํ—ฌ์Šค์ผ€์–ด")
296
  submit_button = gr.Button("์•„์ด๋””์–ด ์ƒ์„ฑํ•˜๊ธฐ")
297
+
298
+ # ์šฐ์ธก ์ถœ๋ ฅ ์˜์—ญ (ํƒญ์€ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉ)
299
  with gr.Column(scale=2):
300
+ with gr.TabItem("์ฐฝ์˜์ ์ธ ๋ชจ๋ธ/์ปจ์…‰/ํ˜•์ƒ ๋ณ€ํ™” ์•„์ด๋””์–ด", id="creative_tab"):
301
+ idea_output = gr.Markdown(label="์•„์ด๋””์–ด ๊ฒฐ๊ณผ")
302
+
303
+ # ์˜ˆ์‹œ ์ž…๋ ฅ
 
 
 
304
  gr.Examples(
305
  examples=[
306
  ["์Šค๋งˆํŠธํฐ", "", ""],
 
311
  inputs=[text_input1, text_input2, text_input3],
312
  )
313
 
314
+ # ๋ฒ„ํŠผ ์ด๋ฒคํŠธ: ์ฒซ ๋ฒˆ์งธ ํƒญ์—๋งŒ ์—ฐ๊ฒฐ
315
+ submit_button.click(fn=process_inputs,
316
+ inputs=[text_input1, text_input2, text_input3],
317
+ outputs=idea_output)
318
 
319
  if __name__ == "__main__":
320
+ demo.launch(debug=True)