# ============================================================ # 长任务进度 / Thinking 日志(moduleId: core-progress, 可重生 ✅) # 同步代码 emit → 网关 SSE 轮询 drain → 前端 Thinking 面板 # ============================================================ from __future__ import annotations import threading import time from collections import deque from typing import Any _lock = threading.Lock() _buf: deque[dict[str, Any]] = deque(maxlen=200) _active = False def begin_progress() -> None: """一轮对话开始:清空缓冲并启用(跨线程可见)。""" global _active with _lock: _buf.clear() _active = True def end_progress() -> None: global _active with _lock: _active = False def emit_thinking( step: str, detail: str = "", *, status: str = "running", pct: float | None = None, ) -> None: """推送一条 Thinking 步骤(线程安全,供 SQL 扫描等后台线程调用)。""" with _lock: if not _active: return ev: dict[str, Any] = { "type": "thinking", "step": step, "detail": detail or "", "status": status, # running | done | warn "ts": time.time(), } if pct is not None: ev["pct"] = max(0.0, min(100.0, float(pct))) _buf.append(ev) def drain_thinking() -> list[dict[str, Any]]: """取出并清空当前缓冲。""" with _lock: items = list(_buf) _buf.clear() return items