Add thinking box UI and fix async event loop errors

- Show thinking progress in a separate animated box above chatbot
  (🤔 사고 중... while streaming, 💭 사고 완료 when answer starts)
- Fix ValueError: add missing 5th yield value (thinking_box) to all
  respond() yield statements
- Fix [Reset] and other sync handlers: replace asyncio.get_event_loop()
  .run_until_complete() with asyncio.run() for AnyIO thread compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sal
2026-06-01 10:33:15 +09:00
parent 0424cf4b31
commit 8c859971d1
+7 -12
View File
@@ -95,23 +95,20 @@ async def tts_speak(text: str) -> str | None:
async def respond(message, history, show_thinking, user_id, use_tts, run_ids):
if not message.strip():
yield history, "", None, run_ids
yield history, "", None, run_ids, gr.update()
return
history = list(history)
run_ids = list(run_ids)
history.append({"role": "user", "content": message})
history.append({"role": "assistant", "content": ""})
yield history, "", None, run_ids
yield history, "", None, run_ids, gr.update(value="", visible=False)
collected_run_id: str | None = None
tts_text = "" # 순수 답변만 누적 (TTS용)
thinking_acc = "" # 사고 과정 누적
thinking_active = False
# 사고 과정 박스 초기화
yield history, "", None, run_ids, gr.update(value="", visible=False)
try:
async for token, run_id in api_client.chat(message, user_id, show_thinking):
if run_id is not None:
@@ -171,9 +168,7 @@ def handle_feedback(like_data: gr.LikeData, history, run_ids, user_id):
rating = 1 if like_data.liked else -1
try:
asyncio.get_event_loop().run_until_complete(
api_client.save_feedback(user_id, user_msg, asst_msg, rating, run_id)
)
asyncio.run(api_client.save_feedback(user_id, user_msg, asst_msg, rating, run_id))
except Exception as e:
print(f"[Feedback] 저장 실패: {e}")
@@ -184,7 +179,7 @@ def switch_user(user_id):
def reset_chat(user_id):
try:
asyncio.get_event_loop().run_until_complete(api_client.reset(user_id))
asyncio.run(api_client.reset(user_id))
except Exception as e:
print(f"[Reset] 실패: {e}")
return [], []
@@ -199,7 +194,7 @@ def ingest_files(files):
results = []
for path in paths:
try:
result = asyncio.get_event_loop().run_until_complete(api_client.ingest(path))
result = asyncio.run(api_client.ingest(path))
name = os.path.basename(path)
results.append(f"{name}{result.get('chunks', '?')}개 청크")
except Exception as e:
@@ -209,7 +204,7 @@ def ingest_files(files):
def list_docs():
try:
sources = asyncio.get_event_loop().run_until_complete(api_client.list_documents())
sources = asyncio.run(api_client.list_documents())
return [[os.path.basename(s), s] for s in sources]
except Exception as e:
return [[f"오류: {e}", ""]]
@@ -219,7 +214,7 @@ def delete_doc(source):
if not source.strip():
return "삭제할 파일 경로를 입력하세요.", list_docs()
try:
asyncio.get_event_loop().run_until_complete(api_client.delete_document(source.strip()))
asyncio.run(api_client.delete_document(source.strip()))
return f"삭제 완료: {os.path.basename(source.strip())}", list_docs()
except Exception as e:
return f"오류: {e}", list_docs()