{"record":{"id":"a25637d194d91f33","repo":"binary-husky/gpt_academic","slug":"error-a25637","errorCode":null,"errorMessage":"程序终止。","messagePattern":"程序终止。","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"request_llms/bridge_skylark2.py","lineNumber":30,"sourceCode":"def predict_no_ui_long_connection(inputs:str, llm_kwargs:dict, history:list=[], sys_prompt:str=\"\",\n                                  observe_window:list=[], console_silence:bool=False):\n    \"\"\"\n        ⭐ 多线程方法\n        函数的说明请见 request_llms/bridge_all.py\n    \"\"\"\n    watch_dog_patience = 5\n    response = \"\"\n\n    if validate_key() is False:\n        raise RuntimeError('请配置YUNQUE_SECRET_KEY')\n\n    from .com_skylark2api import YUNQUERequestInstance\n    sri = YUNQUERequestInstance()\n    for response in sri.generate(inputs, llm_kwargs, history, sys_prompt):\n        if len(observe_window) >= 1:\n            observe_window[0] = response\n        if len(observe_window) >= 2:\n            if (time.time()-observe_window[1]) > watch_dog_patience: raise RuntimeError(\"程序终止。\")\n    return response\n\ndef predict(inputs, llm_kwargs, plugin_kwargs, chatbot, history=[], system_prompt='', stream = True, additional_fn=None):\n    \"\"\"\n        ⭐ 单线程方法\n        函数的说明请见 request_llms/bridge_all.py\n    \"\"\"\n    chatbot.append((inputs, \"\"))\n    yield from update_ui(chatbot=chatbot, history=history)\n\n    # 尝试导入依赖，如果缺少依赖，则给出安装建议\n    try:\n        check_packages([\"zhipuai\"])\n    except:\n        yield from update_ui_latest_msg(f\"导入软件依赖失败。使用该模型需要额外依赖，安装方法```pip install --upgrade zhipuai```。\",\n                                         chatbot=chatbot, history=history, delay=0)\n        return\n","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/request_llms/bridge_skylark2.py#L12-L48","documentation":"Watchdog RuntimeError('程序终止。') in bridge_skylark2.predict_no_ui_long_connection: while iterating YUNQUERequestInstance.generate, the heartbeat timestamp observe_window[1] exceeded watch_dog_patience (5s) without being fed, aborting the loop. Standard cooperative-cancellation mechanism shared by all bridges; with Skylark2's Volcano Engine streaming it fires on caller-side cancellation or a stalled feeder thread.","triggerScenarios":"User cancels generation (feeder stops updating observe_window[1]); caller never starts a feeder thread; Volcano endpoint stalling >5s between yields while nobody refreshes the heartbeat.","commonSituations":"Gradio Stop during Skylark2 generation; plugin authors unaware of the two-element observe_window contract; network hiccup to Volcano cloud plus no feeder.","solutions":["On genuine cancellation, catch RuntimeError, discard partial output, and exit gracefully","Start a daemon thread that writes time.time() into observe_window[1] every 1-2s while the result is wanted","Increase watch_dog_patience for slow Volcano routes","Distinguish this from provider errors by matching the '程序终止' message before retrying"],"exampleFix":"# before\nresult = predict_no_ui_long_connection(inputs, llm_kwargs, history, observe_window=ow)\n\n# after\ntry:\n    result = predict_no_ui_long_connection(inputs, llm_kwargs, history, observe_window=ow)\nexcept RuntimeError as e:\n    if '程序终止' in str(e):\n        return partial_from(ow[0])  # user cancelled; keep partial\n    raise","handlingStrategy":"try-catch","validationCode":"import time\nassert len(observe_window) >= 2, 'watchdog contract requires heartbeat slot'\nobserve_window[1] = time.time()","typeGuard":null,"tryCatchPattern":"try:\n    result = predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window=ow)\nexcept RuntimeError as e:\n    if '程序终止' in str(e):\n        return ow[0]  # user cancelled - salvage partial stream text\n    raise","preventionTips":["Reuse one watchdog feeder helper for every bridge call in your plugin","Refresh the heartbeat even while doing local post-processing between polls","Match on the message string to separate cancellation from Skylark API errors"],"tags":["skylark2","watchdog","cancellation","concurrency","streaming"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}