binary-husky/gpt_academic · error · RuntimeError
程序终止。
Error message
程序终止。
What it means
This is the watchdog (看门狗) of the Spark bridge's long-connection predict loop. observe_window[1] holds the timestamp of the last caller activity; if the generator produced no completion within watch_dog_patience (5 seconds) of that timestamp, the loop aborts with RuntimeError('程序终止。') to prevent a hung thread.
Source
Thrown at request_llms/bridge_spark.py:34
def predict_no_ui_long_connection(inputs:str, llm_kwargs:dict, history:list=[], sys_prompt:str="",
observe_window:list=[], console_silence:bool=False):
"""
⭐多线程方法
函数的说明请见 request_llms/bridge_all.py
"""
watch_dog_patience = 5
response = ""
if validate_key() is False:
raise RuntimeError('请配置讯飞星火大模型的XFYUN_APPID, XFYUN_API_KEY, XFYUN_API_SECRET')
from .com_sparkapi import SparkRequestInstance
sri = SparkRequestInstance()
for response in sri.generate(inputs, llm_kwargs, history, sys_prompt, use_image_api=False):
if len(observe_window) >= 1:
observe_window[0] = response
if len(observe_window) >= 2:
if (time.time()-observe_window[1]) > watch_dog_patience: raise RuntimeError("程序终止。")
return response
def predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):
"""
⭐单线程方法
函数的说明请见 request_llms/bridge_all.py
"""
chatbot.append((inputs, ""))
yield from update_ui(chatbot=chatbot, history=history)
if validate_key() is False:
yield from update_ui_latest_msg(lastmsg="[Local Message] 请配置讯飞星火大模型的XFYUN_APPID, XFYUN_API_KEY, XFYUN_API_SECRET", chatbot=chatbot, history=history, delay=0)
return
if additional_fn is not None:
from core_functional import handle_core_functionality
inputs, history = handle_core_functionality(additional_fn, inputs, history, chatbot)
View on GitHub (pinned to d6bde0fa54)
Solutions
- Check network/proxy connectivity to wss://spark-api.xf-yun.com (WebSocket must be allowed, not just HTTPS)
- Retry the request — transient stalls on the Spark WebSocket commonly clear on a new connection
- If long responses legitimately take >5s between chunks, raise watch_dog_patience in bridge_spark.py or have the caller refresh observe_window[1] on every UI tick
- Inspect com_sparkapi.py generate() logs for the underlying disconnect reason (auth error, quota, protocol error)
Example fix
# before watch_dog_patience = 5 # after (only if your network is slow and streams stall between chunks) watch_dog_patience = 30
Defensive patterns
Strategy: retry
Validate before calling
import socket
socket.create_connection(('spark-api.xf-yun.com', 443), timeout=3).close() # quick WS reachability probe Try / catch
try:
predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window)
except RuntimeError as e:
if str(e) == '程序终止。':
logger.warning('Spark stream stalled >5s; retrying once')
return predict_no_ui_long_connection(...)
raise Prevention
- Keep observe_window[1] refreshed from the caller thread every UI tick
- Wrap one-shot plugin calls with a single retry on watchdog aborts
- Monitor time-between-chunks; if consistently near 5s, raise patience before it bites
When it happens
Trigger: sri.generate() stops yielding chunks (WebSocket stalled, network drop, iFlytek server stops responding) while observe_window carries [response, last_update_time] and time.time() - observe_window[1] > 5. It is raised inside predict_no_ui_long_connection() in request_llms/bridge_spark.py:34.
Common situations: Unstable network to spark-api.xf-yun.com; proxy/firewall blocking WebSocket upgrade; iFlytek service throttling or rate-limiting the appid; the caller forgot to keep refreshing observe_window[1] so even a healthy slow stream trips the 5-second patience.
Related errors
AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14).
Data as JSON: /api/errors/0f4a5e522a36dda7.
Report an issue: GitHub.