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

  1. Check network/proxy connectivity to wss://spark-api.xf-yun.com (WebSocket must be allowed, not just HTTPS)
  2. Retry the request — transient stalls on the Spark WebSocket commonly clear on a new connection
  3. 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
  4. 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

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.