Spaces:
Sleeping
Sleeping
haepa_mac commited on
Commit Β·
b2bd8b0
1
Parent(s): 67cb297
π― Fix API integration for persona generation + improve UI organization
Browse files
app.py
CHANGED
|
@@ -198,14 +198,27 @@ HUMOR_STYLE_MAPPING = {
|
|
| 198 |
"Self-deprecating": "self_deprecating"
|
| 199 |
}
|
| 200 |
|
| 201 |
-
def create_persona_from_image(image, name, location, time_spent, object_type, progress=gr.Progress()):
|
| 202 |
"""νλ₯΄μλ μμ± ν¨μ - API μ€μ μ μ©"""
|
| 203 |
global persona_generator
|
| 204 |
|
| 205 |
if image is None:
|
| 206 |
return None, "μ΄λ―Έμ§λ₯Ό μ
λ‘λν΄μ£ΌμΈμ.", "", {}, None, [], [], [], "", None, gr.update(visible=False)
|
| 207 |
|
| 208 |
-
progress(0.1, desc="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
|
| 210 |
user_context = {
|
| 211 |
"name": name,
|
|
@@ -229,20 +242,22 @@ def create_persona_from_image(image, name, location, time_spent, object_type, pr
|
|
| 229 |
if image.format in ['AVIF', 'WEBP'] or image.mode not in ['RGB', 'RGBA']:
|
| 230 |
image = image.convert('RGB')
|
| 231 |
|
| 232 |
-
#
|
| 233 |
-
|
| 234 |
-
persona_generator = PersonaGenerator()
|
| 235 |
|
| 236 |
progress(0.3, desc="μ΄λ―Έμ§ λΆμ μ€...")
|
| 237 |
# μ΄λ―Έμ§ μ²λ¦¬ λ°©μ μμ - PIL Image κ°μ²΄λ₯Ό μ§μ μ λ¬
|
| 238 |
-
image_analysis =
|
| 239 |
|
| 240 |
progress(0.5, desc="νλ₯΄μλ μμ± μ€...")
|
| 241 |
# νλ‘ νΈμλ νλ₯΄μλ μμ±
|
| 242 |
-
frontend_persona =
|
| 243 |
|
| 244 |
# λ°±μλ νλ₯΄μλ μμ± (ꡬ쑰νλ ν둬ννΈ ν¬ν¨)
|
| 245 |
-
backend_persona =
|
|
|
|
|
|
|
|
|
|
| 246 |
|
| 247 |
# νλ₯΄μλ μ 보 ν¬λ§·ν
|
| 248 |
persona_name = backend_persona["κΈ°λ³Έμ 보"]["μ΄λ¦"]
|
|
@@ -274,7 +289,7 @@ def create_persona_from_image(image, name, location, time_spent, object_type, pr
|
|
| 274 |
|
| 275 |
return (
|
| 276 |
backend_persona, # current_persona
|
| 277 |
-
f"β
{persona_name} νλ₯΄μλκ° μμ±λμμ΅λλ€!", # status_output
|
| 278 |
summary_display, # persona_summary_display
|
| 279 |
backend_persona["μ±κ²©νΉμ±"], # personality_traits_output (hidden)
|
| 280 |
humor_chart, # humor_chart_output
|
|
@@ -289,7 +304,7 @@ def create_persona_from_image(image, name, location, time_spent, object_type, pr
|
|
| 289 |
except Exception as e:
|
| 290 |
import traceback
|
| 291 |
traceback.print_exc()
|
| 292 |
-
return None, f"β νλ₯΄μλ μμ± μ€ μ€λ₯ λ°μ: {str(e)}", "", {}, None, [], [], [], "", None, gr.update(visible=False)
|
| 293 |
|
| 294 |
def generate_personality_preview(persona_name, personality_traits):
|
| 295 |
"""μ±κ²© νΉμ±μ κΈ°λ°μΌλ‘ ν λ¬Έμ₯ 미리보기 μμ±"""
|
|
@@ -418,23 +433,29 @@ def adjust_persona_traits(persona, warmth, competence, extraversion, humor_style
|
|
| 418 |
traceback.print_exc()
|
| 419 |
return persona, f"μ‘°μ μ€ μ€λ₯ λ°μ: {str(e)}", {}
|
| 420 |
|
| 421 |
-
def finalize_persona(persona):
|
| 422 |
"""νλ₯΄μλ μ΅μ’
νμ - API μ€μ μ μ©"""
|
| 423 |
global persona_generator
|
| 424 |
|
| 425 |
if not persona:
|
| 426 |
return None, "νλ₯΄μλκ° μμ΅λλ€.", "", {}, None, [], [], [], "", None
|
| 427 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 428 |
try:
|
| 429 |
-
#
|
| 430 |
-
|
| 431 |
-
persona_generator = PersonaGenerator()
|
| 432 |
|
| 433 |
# μ΄λ―Έ λ°±μλ νλ₯΄μλμΈ κ²½μ°μ νλ‘ νΈμλ νλ₯΄μλμΈ κ²½μ° κ΅¬λΆ
|
| 434 |
if "ꡬ쑰νν둬ννΈ" not in persona:
|
| 435 |
# νλ‘ νΈμλ νλ₯΄μλμΈ κ²½μ° λ°±μλ νλ₯΄μλλ‘ λ³ν
|
| 436 |
image_analysis = {"object_type": persona.get("κΈ°λ³Έμ 보", {}).get("μ ν", "μ μ μλ μ¬λ¬Ό")}
|
| 437 |
-
persona =
|
|
|
|
|
|
|
|
|
|
| 438 |
|
| 439 |
persona_name = persona["κΈ°λ³Έμ 보"]["μ΄λ¦"]
|
| 440 |
|
|
@@ -469,7 +490,7 @@ def finalize_persona(persona):
|
|
| 469 |
|
| 470 |
return (
|
| 471 |
persona, # current_persona
|
| 472 |
-
f"β
{persona_name} μμ±!", # status_output
|
| 473 |
summary_display, # persona_summary_display
|
| 474 |
persona["μ±κ²©νΉμ±"], # personality_traits_output
|
| 475 |
humor_chart, # humor_chart_output
|
|
@@ -483,7 +504,7 @@ def finalize_persona(persona):
|
|
| 483 |
except Exception as e:
|
| 484 |
import traceback
|
| 485 |
traceback.print_exc()
|
| 486 |
-
return None, f"β νλ₯΄μλ νμ μ€ μ€λ₯ λ°μ: {str(e)}", "", {}, None, [], [], [], "", None
|
| 487 |
|
| 488 |
def plot_humor_matrix(humor_data):
|
| 489 |
"""μ λ¨Έ λ§€νΈλ¦μ€ μκ°ν - μμ΄ λ μ΄λΈ μ¬μ©"""
|
|
@@ -1253,6 +1274,13 @@ def create_main_interface():
|
|
| 1253 |
gr.Markdown("### π€ νμ¬ νλ₯΄μλ")
|
| 1254 |
chat_persona_greeting = gr.Markdown("", elem_classes=["persona-greeting"])
|
| 1255 |
current_persona_info = gr.JSON(label="νμ¬ νλ₯΄μλ μ 보", visible=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1256 |
|
| 1257 |
with gr.Column(scale=1):
|
| 1258 |
gr.Markdown("### π¬ λν")
|
|
@@ -1275,16 +1303,15 @@ def create_main_interface():
|
|
| 1275 |
|
| 1276 |
# π§ λν λΆμ ν μΆκ°
|
| 1277 |
with gr.Tab("π§ λν λΆμ"):
|
| 1278 |
-
gr.Markdown("### π λν κΈ°λ‘
|
| 1279 |
|
| 1280 |
with gr.Row():
|
| 1281 |
with gr.Column():
|
| 1282 |
-
gr.Markdown("####
|
| 1283 |
-
|
| 1284 |
-
conversation_download_file = gr.File(label="λ€μ΄λ‘λ", visible=False)
|
| 1285 |
|
| 1286 |
import_file = gr.File(label="π€ λν κΈ°λ‘ JSON μ
λ‘λ", file_types=[".json"])
|
| 1287 |
-
import_result = gr.Textbox(label="
|
| 1288 |
|
| 1289 |
with gr.Column():
|
| 1290 |
gr.Markdown("#### π μ€μκ° ν€μλ λΆμ")
|
|
@@ -1302,7 +1329,7 @@ def create_main_interface():
|
|
| 1302 |
# μ΄λ²€νΈ νΈλ€λ¬
|
| 1303 |
create_btn.click(
|
| 1304 |
fn=create_persona_from_image,
|
| 1305 |
-
inputs=[image_input, name_input, location_input, time_spent_input, object_type_input],
|
| 1306 |
outputs=[
|
| 1307 |
current_persona, status_output, persona_summary_display, personality_traits_output,
|
| 1308 |
humor_chart_output, attractive_flaws_output, contradictions_output,
|
|
@@ -1330,7 +1357,7 @@ def create_main_interface():
|
|
| 1330 |
# νλ₯΄μλ μ΅μ’
νμ
|
| 1331 |
finalize_btn.click(
|
| 1332 |
fn=finalize_persona,
|
| 1333 |
-
inputs=[current_persona],
|
| 1334 |
outputs=[
|
| 1335 |
current_persona, status_output, persona_summary_display, personality_traits_output,
|
| 1336 |
humor_chart_output, attractive_flaws_output, contradictions_output,
|
|
@@ -1433,16 +1460,17 @@ def create_main_interface():
|
|
| 1433 |
outputs=[personas_list]
|
| 1434 |
)
|
| 1435 |
|
| 1436 |
-
# μ΄λ²€νΈ
|
| 1437 |
-
|
| 1438 |
export_conversation_history,
|
| 1439 |
-
outputs=[
|
| 1440 |
).then(
|
| 1441 |
lambda x: gr.update(visible=True) if x else gr.update(visible=False),
|
| 1442 |
-
inputs=[
|
| 1443 |
-
outputs=[
|
| 1444 |
)
|
| 1445 |
|
|
|
|
| 1446 |
import_file.upload(
|
| 1447 |
import_conversation_history,
|
| 1448 |
inputs=[import_file],
|
|
|
|
| 198 |
"Self-deprecating": "self_deprecating"
|
| 199 |
}
|
| 200 |
|
| 201 |
+
def create_persona_from_image(image, name, location, time_spent, object_type, api_provider="gemini", api_key=None, progress=gr.Progress()):
|
| 202 |
"""νλ₯΄μλ μμ± ν¨μ - API μ€μ μ μ©"""
|
| 203 |
global persona_generator
|
| 204 |
|
| 205 |
if image is None:
|
| 206 |
return None, "μ΄λ―Έμ§λ₯Ό μ
λ‘λν΄μ£ΌμΈμ.", "", {}, None, [], [], [], "", None, gr.update(visible=False)
|
| 207 |
|
| 208 |
+
progress(0.1, desc="μ€μ νμΈ μ€...")
|
| 209 |
+
|
| 210 |
+
# API ν€ κ²μ¦
|
| 211 |
+
if not api_key or not api_key.strip():
|
| 212 |
+
return None, "β **API ν€κ° νμν©λλ€!** μλ¨μ 'API μ€μ ' μΉμ
μμ λ¨Όμ API ν€λ₯Ό μ€μ ν΄μ£ΌμΈμ.", "", {}, None, [], [], [], "", None, gr.update(visible=False)
|
| 213 |
+
|
| 214 |
+
# API ν€ νμ κ²μ¦
|
| 215 |
+
api_key = api_key.strip()
|
| 216 |
+
if api_provider == "gemini" and not api_key.startswith("AI"):
|
| 217 |
+
return None, "β **Gemini API ν€ νμμ΄ μ¬λ°λ₯΄μ§ μμ΅λλ€.** 'AIza...' ννμ¬μΌ ν©λλ€.", "", {}, None, [], [], [], "", None, gr.update(visible=False)
|
| 218 |
+
elif api_provider == "openai" and not api_key.startswith("sk-"):
|
| 219 |
+
return None, "β **OpenAI API ν€ νμμ΄ μ¬λ°λ₯΄μ§ μμ΅λλ€.** 'sk-...' ννμ¬μΌ ν©λλ€.", "", {}, None, [], [], [], "", None, gr.update(visible=False)
|
| 220 |
+
|
| 221 |
+
progress(0.2, desc="API μ°κ²° νμΈ μ€...")
|
| 222 |
|
| 223 |
user_context = {
|
| 224 |
"name": name,
|
|
|
|
| 242 |
if image.format in ['AVIF', 'WEBP'] or image.mode not in ['RGB', 'RGBA']:
|
| 243 |
image = image.convert('RGB')
|
| 244 |
|
| 245 |
+
# PersonaGenerator μΈμ€ν΄μ€ μμ± (API ν€ ν¬ν¨)
|
| 246 |
+
generator = PersonaGenerator(api_provider=api_provider, api_key=api_key)
|
|
|
|
| 247 |
|
| 248 |
progress(0.3, desc="μ΄λ―Έμ§ λΆμ μ€...")
|
| 249 |
# μ΄λ―Έμ§ μ²λ¦¬ λ°©μ μμ - PIL Image κ°μ²΄λ₯Ό μ§μ μ λ¬
|
| 250 |
+
image_analysis = generator.analyze_image(image)
|
| 251 |
|
| 252 |
progress(0.5, desc="νλ₯΄μλ μμ± μ€...")
|
| 253 |
# νλ‘ νΈμλ νλ₯΄μλ μμ±
|
| 254 |
+
frontend_persona = generator.create_frontend_persona(image_analysis, user_context)
|
| 255 |
|
| 256 |
# λ°±μλ νλ₯΄μλ μμ± (ꡬ쑰νλ ν둬ννΈ ν¬ν¨)
|
| 257 |
+
backend_persona = generator.create_backend_persona(frontend_persona, image_analysis)
|
| 258 |
+
|
| 259 |
+
# κΈλ‘λ² μΈμ€ν΄μ€ μ
λ°μ΄νΈ (μ±κ³΅ν κ²½μ°μλ§)
|
| 260 |
+
persona_generator = generator
|
| 261 |
|
| 262 |
# νλ₯΄μλ μ 보 ν¬λ§·ν
|
| 263 |
persona_name = backend_persona["κΈ°λ³Έμ 보"]["μ΄λ¦"]
|
|
|
|
| 289 |
|
| 290 |
return (
|
| 291 |
backend_persona, # current_persona
|
| 292 |
+
f"β
{persona_name} νλ₯΄μλκ° μμ±λμμ΅λλ€! (API: {api_provider})", # status_output
|
| 293 |
summary_display, # persona_summary_display
|
| 294 |
backend_persona["μ±κ²©νΉμ±"], # personality_traits_output (hidden)
|
| 295 |
humor_chart, # humor_chart_output
|
|
|
|
| 304 |
except Exception as e:
|
| 305 |
import traceback
|
| 306 |
traceback.print_exc()
|
| 307 |
+
return None, f"β νλ₯΄μλ μμ± μ€ μ€λ₯ λ°μ: {str(e)}\n\nπ‘ **ν΄κ²°λ°©λ²**: API ν€κ° μ¬λ°λ₯Έμ§ νμΈνκ³ μΈν°λ· μ°κ²°μ νμΈν΄λ³΄μΈμ.", "", {}, None, [], [], [], "", None, gr.update(visible=False)
|
| 308 |
|
| 309 |
def generate_personality_preview(persona_name, personality_traits):
|
| 310 |
"""μ±κ²© νΉμ±μ κΈ°λ°μΌλ‘ ν λ¬Έμ₯ 미리보기 μμ±"""
|
|
|
|
| 433 |
traceback.print_exc()
|
| 434 |
return persona, f"μ‘°μ μ€ μ€λ₯ λ°μ: {str(e)}", {}
|
| 435 |
|
| 436 |
+
def finalize_persona(persona, api_provider="gemini", api_key=None):
|
| 437 |
"""νλ₯΄μλ μ΅μ’
νμ - API μ€μ μ μ©"""
|
| 438 |
global persona_generator
|
| 439 |
|
| 440 |
if not persona:
|
| 441 |
return None, "νλ₯΄μλκ° μμ΅λλ€.", "", {}, None, [], [], [], "", None
|
| 442 |
|
| 443 |
+
# API ν€ κ²μ¦
|
| 444 |
+
if not api_key or not api_key.strip():
|
| 445 |
+
return None, "β **API ν€κ° νμν©λλ€!** μλ¨μ 'API μ€μ ' μΉμ
μμ λ¨Όμ API ν€λ₯Ό μ€μ ν΄μ£ΌμΈμ.", "", {}, None, [], [], [], "", None
|
| 446 |
+
|
| 447 |
try:
|
| 448 |
+
# PersonaGenerator μΈμ€ν΄μ€ μμ± (API ν€ ν¬ν¨)
|
| 449 |
+
generator = PersonaGenerator(api_provider=api_provider, api_key=api_key.strip())
|
|
|
|
| 450 |
|
| 451 |
# μ΄λ―Έ λ°±μλ νλ₯΄μλμΈ κ²½μ°μ νλ‘ νΈμλ νλ₯΄μλμΈ κ²½μ° κ΅¬λΆ
|
| 452 |
if "ꡬ쑰νν둬ννΈ" not in persona:
|
| 453 |
# νλ‘ νΈμλ νλ₯΄μλμΈ κ²½μ° λ°±μλ νλ₯΄μλλ‘ λ³ν
|
| 454 |
image_analysis = {"object_type": persona.get("κΈ°λ³Έμ 보", {}).get("μ ν", "μ μ μλ μ¬λ¬Ό")}
|
| 455 |
+
persona = generator.create_backend_persona(persona, image_analysis)
|
| 456 |
+
|
| 457 |
+
# κΈλ‘λ² μΈμ€ν΄μ€ μ
λ°μ΄νΈ (μ±κ³΅ν κ²½μ°μλ§)
|
| 458 |
+
persona_generator = generator
|
| 459 |
|
| 460 |
persona_name = persona["κΈ°λ³Έμ 보"]["μ΄λ¦"]
|
| 461 |
|
|
|
|
| 490 |
|
| 491 |
return (
|
| 492 |
persona, # current_persona
|
| 493 |
+
f"β
{persona_name} μμ±! (API: {api_provider})", # status_output
|
| 494 |
summary_display, # persona_summary_display
|
| 495 |
persona["μ±κ²©νΉμ±"], # personality_traits_output
|
| 496 |
humor_chart, # humor_chart_output
|
|
|
|
| 504 |
except Exception as e:
|
| 505 |
import traceback
|
| 506 |
traceback.print_exc()
|
| 507 |
+
return None, f"β νλ₯΄μλ νμ μ€ μ€λ₯ λ°μ: {str(e)}\n\nπ‘ **ν΄κ²°λ°©λ²**: API ν€κ° μ¬λ°λ₯Έμ§ νμΈνκ³ μΈν°λ· μ°κ²°μ νμΈν΄λ³΄μΈμ.", "", {}, None, [], [], [], "", None
|
| 508 |
|
| 509 |
def plot_humor_matrix(humor_data):
|
| 510 |
"""μ λ¨Έ λ§€νΈλ¦μ€ μκ°ν - μμ΄ λ μ΄λΈ μ¬μ©"""
|
|
|
|
| 1274 |
gr.Markdown("### π€ νμ¬ νλ₯΄μλ")
|
| 1275 |
chat_persona_greeting = gr.Markdown("", elem_classes=["persona-greeting"])
|
| 1276 |
current_persona_info = gr.JSON(label="νμ¬ νλ₯΄μλ μ 보", visible=False)
|
| 1277 |
+
|
| 1278 |
+
# λν κΈ°λ‘ κ΄λ¦¬
|
| 1279 |
+
with gr.Group():
|
| 1280 |
+
gr.Markdown("### πΎ λν κΈ°λ‘ κ΄λ¦¬")
|
| 1281 |
+
gr.Markdown("νμ¬ λνλ₯Ό JSON νμΌλ‘ λ€μ΄λ‘λνμ¬ λ³΄κ΄νμΈμ.")
|
| 1282 |
+
chat_export_btn = gr.Button("π₯ νμ¬ λν κΈ°λ‘ λ€μ΄λ‘λ", variant="secondary")
|
| 1283 |
+
chat_download_file = gr.File(label="λ€μ΄λ‘λ", visible=False)
|
| 1284 |
|
| 1285 |
with gr.Column(scale=1):
|
| 1286 |
gr.Markdown("### π¬ λν")
|
|
|
|
| 1303 |
|
| 1304 |
# π§ λν λΆμ ν μΆκ°
|
| 1305 |
with gr.Tab("π§ λν λΆμ"):
|
| 1306 |
+
gr.Markdown("### π λν κΈ°λ‘ λΆμ λ° ν€μλ μΆμΆ")
|
| 1307 |
|
| 1308 |
with gr.Row():
|
| 1309 |
with gr.Column():
|
| 1310 |
+
gr.Markdown("#### π€ λν κΈ°λ‘ λΆμνκΈ°")
|
| 1311 |
+
gr.Markdown("μ μ₯λ λν κΈ°λ‘ JSON νμΌμ μ
λ‘λνμ¬ λΆμν΄λ³΄μΈμ.")
|
|
|
|
| 1312 |
|
| 1313 |
import_file = gr.File(label="π€ λν κΈ°λ‘ JSON μ
λ‘λ", file_types=[".json"])
|
| 1314 |
+
import_result = gr.Textbox(label="μ
λ‘λ κ²°κ³Ό", lines=3, interactive=False)
|
| 1315 |
|
| 1316 |
with gr.Column():
|
| 1317 |
gr.Markdown("#### π μ€μκ° ν€μλ λΆμ")
|
|
|
|
| 1329 |
# μ΄λ²€νΈ νΈλ€λ¬
|
| 1330 |
create_btn.click(
|
| 1331 |
fn=create_persona_from_image,
|
| 1332 |
+
inputs=[image_input, name_input, location_input, time_spent_input, object_type_input, api_provider, api_key_input],
|
| 1333 |
outputs=[
|
| 1334 |
current_persona, status_output, persona_summary_display, personality_traits_output,
|
| 1335 |
humor_chart_output, attractive_flaws_output, contradictions_output,
|
|
|
|
| 1357 |
# νλ₯΄μλ μ΅μ’
νμ
|
| 1358 |
finalize_btn.click(
|
| 1359 |
fn=finalize_persona,
|
| 1360 |
+
inputs=[current_persona, api_provider, api_key_input],
|
| 1361 |
outputs=[
|
| 1362 |
current_persona, status_output, persona_summary_display, personality_traits_output,
|
| 1363 |
humor_chart_output, attractive_flaws_output, contradictions_output,
|
|
|
|
| 1460 |
outputs=[personas_list]
|
| 1461 |
)
|
| 1462 |
|
| 1463 |
+
# λννκΈ° νμ λν κΈ°λ‘ λ€μ΄λ‘λ μ΄λ²€νΈ
|
| 1464 |
+
chat_export_btn.click(
|
| 1465 |
export_conversation_history,
|
| 1466 |
+
outputs=[chat_download_file]
|
| 1467 |
).then(
|
| 1468 |
lambda x: gr.update(visible=True) if x else gr.update(visible=False),
|
| 1469 |
+
inputs=[chat_download_file],
|
| 1470 |
+
outputs=[chat_download_file]
|
| 1471 |
)
|
| 1472 |
|
| 1473 |
+
# λν λΆμ νμ μ
λ‘λ μ΄λ²€νΈ
|
| 1474 |
import_file.upload(
|
| 1475 |
import_conversation_history,
|
| 1476 |
inputs=[import_file],
|