Skip to content

Commit b9d58f9

Browse files
authored
✨ 优化超时配置 (#40)
1 parent 3b65f55 commit b9d58f9

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ plugins = ["nonebot_plugin_deepseek"]
102102
| deepseek__enable_models ||[{ "name": "deepseek-chat" }, { "name": "deepseek-reasoner" }]|启用的模型 [配置说明](https://github.com/KomoriDev/nonebot-plugin-deepseek/wiki/%E9%85%8D%E7%BD%AE#enable_models-%E9%85%8D%E7%BD%AE%E8%AF%B4%E6%98%8E)|
103103
| deepseek__prompt ||| 模型预设 |
104104
| deepseek__stream || False | 是否启用流式传输 |
105+
| deepseek__timeout || {"api_request": 100, "user_input": 60} | 超时设定 |
105106
| deepseek__md_to_pic || False | 是否启用 Markdown 转图片 |
106107
|deepseek__enable_send_thinking|| False | 是否发送思维链 |
107108

nonebot_plugin_deepseek/apis/request.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ async def chat(cls, message: list[dict[str, str]], model: str = "deepseek-chat")
2626
prompt = model_dump(model_config, exclude_none=True).get("prompt", config.prompt)
2727

2828
json = {
29-
"messages": [{"content": prompt, "role": "system"}] + message if prompt else message,
29+
"messages": ([{"content": prompt, "role": "system"}] + message if prompt else message),
3030
"model": model,
3131
**model_config.to_dict(),
3232
}
@@ -56,12 +56,16 @@ async def query_balance(cls, model_name: str) -> Balance:
5656

5757

5858
async def common_request(base_url: str, api_key: str, json: dict):
59+
timeout_config = config.timeout
5960
async with httpx.AsyncClient() as client:
6061
response = await client.post(
6162
f"{base_url}/chat/completions",
62-
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
63+
headers={
64+
"Authorization": f"Bearer {api_key}",
65+
"Content-Type": "application/json",
66+
},
6367
json=json,
64-
timeout=50,
68+
timeout=(timeout_config if isinstance(timeout_config, int) else timeout_config.api_request),
6569
)
6670
if error := response.json().get("error"):
6771
raise RequestException(error["message"])
@@ -74,7 +78,10 @@ async def stream_request(base_url: str, api_key: str, json: dict):
7478
async with client.stream(
7579
"POST",
7680
f"{base_url}/chat/completions",
77-
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
81+
headers={
82+
"Authorization": f"Bearer {api_key}",
83+
"Content-Type": "application/json",
84+
},
7885
json=json,
7986
) as response:
8087
ret_list: Optional[StreamChoiceList] = None
@@ -107,7 +114,9 @@ async def stream_request(base_url: str, api_key: str, json: dict):
107114
return ret_list.transform()
108115

109116

110-
def sse_middle(line: str) -> Union[tuple[Literal["data", "event", "id", "retry", "::", "error"], str], None]:
117+
def sse_middle(
118+
line: str,
119+
) -> Union[tuple[Literal["data", "event", "id", "retry", "::", "error"], str], None]:
111120
"""单行SSE数据解析"""
112121
line = line.strip("\r")
113122
if not line:

nonebot_plugin_deepseek/config.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ def to_dict(self):
139139
)
140140

141141

142+
class TimeoutConfig(BaseModel):
143+
api_request: int = Field(default=100)
144+
"""API request timeout (Not applicable for streaming)"""
145+
user_input: int = Field(default=60)
146+
"""User input timeout"""
147+
148+
142149
class ScopedConfig(BaseModel):
143150
api_key: str = ""
144151
"""Your API Key from deepseek"""
@@ -153,8 +160,8 @@ class ScopedConfig(BaseModel):
153160
"""Text to Image"""
154161
enable_send_thinking: bool = False
155162
"""Whether to send model thinking chain"""
156-
context_timeout: int = Field(default=50, gt=50)
157-
"""Multi-round conversation timeout"""
163+
timeout: Union[int, TimeoutConfig] = Field(default_factory=TimeoutConfig)
164+
"""Timeout"""
158165
stream: bool = False
159166
"""Stream"""
160167

nonebot_plugin_deepseek/utils.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ async def _handle_single_conversion(self) -> None:
5454
await self._send_response(message)
5555

5656
async def _handle_multi_round_conversion(self) -> None:
57-
async for resp in self.waiter(default=False, timeout=config.context_timeout):
57+
timeout = config.timeout if isinstance(config.timeout, int) else config.timeout.user_input
58+
async for resp in self.waiter(default=False, timeout=timeout):
5859
await self._process_waiter_response(resp)
5960

6061
if resp == "rollback":
@@ -73,7 +74,12 @@ async def _handle_multi_round_conversion(self) -> None:
7374

7475
def _setup_waiter(self) -> Waiter[Union[str, Literal[False]]]:
7576
permission = Permission(User.from_event(self.event, perm=self.matcher.permission))
76-
waiter = Waiter(waits=["message"], handler=self._waiter_handler, matcher=self.matcher, permission=permission)
77+
waiter = Waiter(
78+
waits=["message"],
79+
handler=self._waiter_handler,
80+
matcher=self.matcher,
81+
permission=permission,
82+
)
7783
waiter.future.set_result("")
7884
return waiter
7985

@@ -92,8 +98,14 @@ def _prompt_handler(self, msg: UniMsg) -> UniMsg:
9298
return msg
9399

94100
async def _process_waiter_response(self, resp: Union[bool, str]) -> None:
101+
timeout = config.timeout if isinstance(config.timeout, int) else config.timeout.user_input
102+
95103
if resp == "" and not self.context:
96-
_resp = await prompt("你想对 DeepSeek 说什么呢?", handler=self._prompt_handler, timeout=60)
104+
_resp = await prompt(
105+
"你想对 DeepSeek 说什么呢?",
106+
handler=self._prompt_handler,
107+
timeout=timeout,
108+
)
97109
if _resp is None:
98110
await UniMessage.text("等待超时").finish(reply_to=self.message_id)
99111
resp = self._waiter_handler(_resp, skip=True)
@@ -138,7 +150,13 @@ async def _handle_tool_calls(self, message: Message) -> bool:
138150
self.context.pop()
139151
return False
140152

141-
self.context.append({"role": "tool", "tool_call_id": message.tool_calls[0].id, "content": result})
153+
self.context.append(
154+
{
155+
"role": "tool",
156+
"tool_call_id": message.tool_calls[0].id,
157+
"content": result,
158+
}
159+
)
142160
return True
143161

144162
async def _get_response_message(self) -> Optional[Message]:

0 commit comments

Comments
 (0)