fix: raise Cursor SDK bridge timeout for daily LLM calls
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -65,6 +65,7 @@ DAILY_CN_AI_NEWS=1
|
|||||||
# cursor — 强制 Cursor SDK
|
# cursor — 强制 Cursor SDK
|
||||||
# CURSOR_API_KEY=cursor_...
|
# CURSOR_API_KEY=cursor_...
|
||||||
# CURSOR_MODEL=composer-2.5
|
# CURSOR_MODEL=composer-2.5
|
||||||
|
# CURSOR_TIMEOUT=600
|
||||||
# DAILY_CURSOR_CWD=.
|
# DAILY_CURSOR_CWD=.
|
||||||
|
|
||||||
# 新增榜对比(较昨日 Top15,供 Agent 导语/signals;列表展示 Top N)
|
# 新增榜对比(较昨日 Top15,供 Agent 导语/signals;列表展示 Top N)
|
||||||
|
|||||||
@@ -2,18 +2,52 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from cursor_sdk import Agent, AgentOptions, CursorAgentError, LocalAgentOptions
|
import os
|
||||||
|
|
||||||
from daily.config import env
|
from cursor_sdk import Agent, AgentOptions, Client, CursorAgentError, LocalAgentOptions
|
||||||
|
|
||||||
|
from daily.config import env, env_int
|
||||||
from daily.cursor_bridge import cursor_cwd, warm_cursor_bridge
|
from daily.cursor_bridge import cursor_cwd, warm_cursor_bridge
|
||||||
|
|
||||||
|
_sdk_client: Client | None = None
|
||||||
|
_sdk_client_key: tuple[str, str, float] | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def cursor_timeout_seconds() -> float:
|
||||||
|
"""Cursor bridge unary/stream 超时(秒);与 bot 共用 CURSOR_TIMEOUT。"""
|
||||||
|
return float(env_int("CURSOR_TIMEOUT", 600))
|
||||||
|
|
||||||
|
|
||||||
|
def _cursor_sdk_client() -> Client:
|
||||||
|
"""带自定义超时的 bridge Client(SDK 默认 unary 仅 60s,复杂 Agent 任务易超时)。"""
|
||||||
|
global _sdk_client, _sdk_client_key
|
||||||
|
|
||||||
|
warm_cursor_bridge()
|
||||||
|
url = os.environ.get("CURSOR_SDK_BRIDGE_URL", "")
|
||||||
|
token = os.environ.get("CURSOR_SDK_BRIDGE_TOKEN", "")
|
||||||
|
timeout = cursor_timeout_seconds()
|
||||||
|
key = (url, token, timeout)
|
||||||
|
if _sdk_client is not None and _sdk_client_key == key:
|
||||||
|
return _sdk_client
|
||||||
|
if _sdk_client is not None:
|
||||||
|
_sdk_client.close()
|
||||||
|
_sdk_client = Client(
|
||||||
|
base_url=url,
|
||||||
|
auth_token=token,
|
||||||
|
unary_timeout=timeout,
|
||||||
|
stream_timeout=timeout,
|
||||||
|
allow_api_key_env_fallback=False,
|
||||||
|
)
|
||||||
|
_sdk_client_key = key
|
||||||
|
return _sdk_client
|
||||||
|
|
||||||
|
|
||||||
def cursor_chat(system: str, user: str) -> str:
|
def cursor_chat(system: str, user: str) -> str:
|
||||||
api_key = (env("CURSOR_API_KEY") or "").strip()
|
api_key = (env("CURSOR_API_KEY") or "").strip()
|
||||||
if not api_key:
|
if not api_key:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
warm_cursor_bridge()
|
client = _cursor_sdk_client()
|
||||||
cwd = cursor_cwd()
|
cwd = cursor_cwd()
|
||||||
model = env("CURSOR_MODEL") or "composer-2.5"
|
model = env("CURSOR_MODEL") or "composer-2.5"
|
||||||
prompt = f"{system}\n\n{user}"
|
prompt = f"{system}\n\n{user}"
|
||||||
@@ -25,6 +59,7 @@ def cursor_chat(system: str, user: str) -> str:
|
|||||||
model=model,
|
model=model,
|
||||||
local=LocalAgentOptions(cwd=cwd),
|
local=LocalAgentOptions(cwd=cwd),
|
||||||
),
|
),
|
||||||
|
client=client,
|
||||||
)
|
)
|
||||||
except CursorAgentError as exc:
|
except CursorAgentError as exc:
|
||||||
raise RuntimeError(f"LLM 调用失败:{exc.message}") from exc
|
raise RuntimeError(f"LLM 调用失败:{exc.message}") from exc
|
||||||
|
|||||||
15
tests/test_cursor_client.py
Normal file
15
tests/test_cursor_client.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
|
def test_cursor_timeout_seconds_default(monkeypatch):
|
||||||
|
import daily.cursor_client as cc
|
||||||
|
|
||||||
|
monkeypatch.delenv("CURSOR_TIMEOUT", raising=False)
|
||||||
|
assert cc.cursor_timeout_seconds() == 600.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_cursor_timeout_seconds_from_env(monkeypatch):
|
||||||
|
import daily.cursor_client as cc
|
||||||
|
|
||||||
|
monkeypatch.setenv("CURSOR_TIMEOUT", "900")
|
||||||
|
assert cc.cursor_timeout_seconds() == 900.0
|
||||||
Reference in New Issue
Block a user