Separate thinking tokens from meta — use __thinking key for display
stream_response() now yields {"__thinking": str} for thinking content
instead of {"__meta": str}. Removed [사고 과정]/[/사고 과정] marker
yields; consumers handle thinking display independently.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -257,9 +257,7 @@ class AgentService:
|
|||||||
if isinstance(data, dict) and "__thinking" in data:
|
if isinstance(data, dict) and "__thinking" in data:
|
||||||
# thinking 첫 토큰 도착 시 agent 레이블 + prev_node 갱신
|
# thinking 첫 토큰 도착 시 agent 레이블 + prev_node 갱신
|
||||||
if "agent" != prev_node:
|
if "agent" != prev_node:
|
||||||
if thinking_open:
|
thinking_open = False
|
||||||
yield {"__meta": "\n[/사고 과정]\n"}
|
|
||||||
thinking_open = False
|
|
||||||
content_started = False
|
content_started = False
|
||||||
if lg:
|
if lg:
|
||||||
elapsed = time.perf_counter() - start_time
|
elapsed = time.perf_counter() - start_time
|
||||||
@@ -267,10 +265,8 @@ class AgentService:
|
|||||||
yield {"__meta": f"\n[LangGraph → {label}] ({elapsed:.2f}s)\n"}
|
yield {"__meta": f"\n[LangGraph → {label}] ({elapsed:.2f}s)\n"}
|
||||||
prev_node = "agent"
|
prev_node = "agent"
|
||||||
if _think_verbose:
|
if _think_verbose:
|
||||||
if not thinking_open:
|
thinking_open = True
|
||||||
yield {"__meta": "\n[사고 과정]\n"}
|
yield {"__thinking": data["__thinking"]}
|
||||||
thinking_open = True
|
|
||||||
yield {"__meta": data["__thinking"]}
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# ── messages 이벤트 ──────────────────────────────────────
|
# ── messages 이벤트 ──────────────────────────────────────
|
||||||
@@ -280,9 +276,7 @@ class AgentService:
|
|||||||
# ── 노드 전환 시 플래그 리셋 + 레이블 출력 ──────────────
|
# ── 노드 전환 시 플래그 리셋 + 레이블 출력 ──────────────
|
||||||
# (agent 레이블은 custom 이벤트 핸들러에서 이미 처리될 수 있으므로 중복 방지)
|
# (agent 레이블은 custom 이벤트 핸들러에서 이미 처리될 수 있으므로 중복 방지)
|
||||||
if node != prev_node:
|
if node != prev_node:
|
||||||
if thinking_open:
|
thinking_open = False
|
||||||
yield {"__meta": "\n[/사고 과정]\n"}
|
|
||||||
thinking_open = False
|
|
||||||
content_started = False
|
content_started = False
|
||||||
if lg:
|
if lg:
|
||||||
elapsed = time.perf_counter() - start_time
|
elapsed = time.perf_counter() - start_time
|
||||||
@@ -298,9 +292,7 @@ class AgentService:
|
|||||||
# ── agent 노드 — AIMessageChunk만 처리 (중복 방지) ──────
|
# ── agent 노드 — AIMessageChunk만 처리 (중복 방지) ──────
|
||||||
if node == "agent" and isinstance(chunk, AIMessageChunk):
|
if node == "agent" and isinstance(chunk, AIMessageChunk):
|
||||||
if chunk.tool_calls:
|
if chunk.tool_calls:
|
||||||
if thinking_open:
|
thinking_open = False
|
||||||
yield {"__meta": "\n[/사고 과정]\n"}
|
|
||||||
thinking_open = False
|
|
||||||
for tc in chunk.tool_calls:
|
for tc in chunk.tool_calls:
|
||||||
pending_tool_calls[tc["id"]] = tc
|
pending_tool_calls[tc["id"]] = tc
|
||||||
if tc.get("name") == "search_documents":
|
if tc.get("name") == "search_documents":
|
||||||
@@ -314,9 +306,7 @@ class AgentService:
|
|||||||
yield {"__meta": f" [tool_call: {tc['name']}({args_str})]\n"}
|
yield {"__meta": f" [tool_call: {tc['name']}({args_str})]\n"}
|
||||||
|
|
||||||
elif chunk.content:
|
elif chunk.content:
|
||||||
if thinking_open:
|
thinking_open = False
|
||||||
yield {"__meta": "\n[/사고 과정]\n"}
|
|
||||||
thinking_open = False
|
|
||||||
if lg and not content_started:
|
if lg and not content_started:
|
||||||
yield {"__meta": "\n[LangGraph → agent: 최종 답변 생성]\n\n"}
|
yield {"__meta": "\n[LangGraph → agent: 최종 답변 생성]\n\n"}
|
||||||
content_started = True
|
content_started = True
|
||||||
@@ -329,9 +319,7 @@ class AgentService:
|
|||||||
if not content_started and not thinking_open:
|
if not content_started and not thinking_open:
|
||||||
thinking = chunk.additional_kwargs.get("thinking", "")
|
thinking = chunk.additional_kwargs.get("thinking", "")
|
||||||
if thinking and _think_verbose:
|
if thinking and _think_verbose:
|
||||||
yield {"__meta": "\n[사고 과정]\n"}
|
yield {"__thinking": thinking}
|
||||||
yield {"__meta": thinking}
|
|
||||||
yield {"__meta": "\n[/사고 과정]\n"}
|
|
||||||
if chunk.content:
|
if chunk.content:
|
||||||
if lg:
|
if lg:
|
||||||
yield {"__meta": "\n[LangGraph → agent: 최종 답변 생성]\n\n"}
|
yield {"__meta": "\n[LangGraph → agent: 최종 답변 생성]\n\n"}
|
||||||
@@ -359,9 +347,7 @@ class AgentService:
|
|||||||
result_lines = [b for b in chunk.content.split("\n\n") if b.strip()]
|
result_lines = [b for b in chunk.content.split("\n\n") if b.strip()]
|
||||||
yield {"__meta": f" [웹 검색 결과: {len(result_lines)}건 → agent 복귀]\n"}
|
yield {"__meta": f" [웹 검색 결과: {len(result_lines)}건 → agent 복귀]\n"}
|
||||||
|
|
||||||
if thinking_open:
|
thinking_open = False
|
||||||
yield {"__meta": "\n[/사고 과정]\n"}
|
|
||||||
|
|
||||||
self._last_run_id = str(run_id)
|
self._last_run_id = str(run_id)
|
||||||
|
|
||||||
# 대화 내용을 MySQL에 저장
|
# 대화 내용을 MySQL에 저장
|
||||||
|
|||||||
Reference in New Issue
Block a user