From c2a53175d5ee0175dd258b3f2b4c6d5975ac6b4e Mon Sep 17 00:00:00 2001 From: FuQuan233 Date: Fri, 24 Apr 2026 13:57:11 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8=20=E6=94=AF=E6=8C=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E7=BE=A4=E6=88=90=E5=91=98=E7=BE=A4=E5=90=8D=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nonebot_plugin_llmchat/onebottools.py | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/nonebot_plugin_llmchat/onebottools.py b/nonebot_plugin_llmchat/onebottools.py index 166e0d4..84d7c58 100644 --- a/nonebot_plugin_llmchat/onebottools.py +++ b/nonebot_plugin_llmchat/onebottools.py @@ -83,6 +83,21 @@ class OneBotTools: }, }, }, + { + "type": "function", + "function": { + "name": "ob__set_group_card", + "description": "修改群成员的群名片。需要机器人有管理员权限。", + "parameters": { + "type": "object", + "properties": { + "user_id": {"type": "string", "description": "要修改名片的用户QQ号"}, + "card": {"type": "string", "description": "新的群名片内容,留空则清除群名片"}, + }, + "required": ["user_id"], + }, + }, + }, ] def get_friendly_name(self, tool_name: str) -> str: @@ -94,6 +109,7 @@ class OneBotTools: "ob__get_group_member_list": "OneBot - 获取成员列表", "ob__poke_user": "OneBot - 戳一戳用户", "ob__recall_message": "OneBot - 撤回消息", + "ob__set_group_card": "OneBot - 修改群名片", } return friendly_names.get(tool_name, tool_name) @@ -118,6 +134,8 @@ class OneBotTools: return await self._poke_user(bot, group_id, tool_args) elif tool_name == "ob__recall_message": return await self._recall_message(bot, group_id, tool_args) + elif tool_name == "ob__set_group_card": + return await self._set_group_card(bot, group_id, tool_args) else: return f"未知的工具: {tool_name}" @@ -212,4 +230,16 @@ class OneBotTools: except Exception as e: return f"撤回消息失败: {e!s}" + async def _set_group_card(self, bot: Bot, group_id: int, args: dict[str, Any]) -> str: + """修改群成员名片""" + user_id = int(args["user_id"]) + card = args.get("card", "") # 如果没有提供card参数,默认为空字符串(清除名片) + try: + await bot.set_group_card(group_id=group_id, user_id=user_id, card=card) + if card: + return f"成功修改用户 {user_id} 的群名片为: {card}" + else: + return f"成功清除用户 {user_id} 的群名片" + except Exception as e: + return f"修改群名片失败: {e!s}" From d7d6c14b3f15d65b953abec1cef074a76e267ac0 Mon Sep 17 00:00:00 2001 From: FuQuan233 Date: Fri, 24 Apr 2026 14:36:05 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=A8=20=E6=B7=BB=E5=8A=A0=E9=A2=9D?= =?UTF-8?q?=E5=A4=96=E8=AF=B7=E6=B1=82=E4=BD=93=E5=AD=97=E6=AE=B5=E5=92=8C?= =?UTF-8?q?=E6=8E=A8=E7=90=86=E5=86=85=E5=AE=B9=E8=AF=B7=E6=B1=82=E9=80=89?= =?UTF-8?q?=E9=A1=B9=E5=88=B0=E9=A2=84=E8=AE=BE=E9=85=8D=E7=BD=AE=E4=BB=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81deepseek-v4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++++++++ nonebot_plugin_llmchat/__init__.py | 32 ++++++++++++++++++++++-------- nonebot_plugin_llmchat/config.py | 5 +++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 882feb0..a3f2272 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,8 @@ _✨ 支持多API预设、MCP协议、内置工具、联网搜索、视觉模型 | proxy | 否 | 无 | 请求API时使用的HTTP代理 | | support_mcp | 否 | False | 是否支持MCP协议 | | support_image | 否 | False | 是否支持图片输入 | +| extra_body | 否 | {} | 额外的请求体字段,用于兼容不同API的特殊参数 | +| request_with_reasoning_content | 否 | false | 请求中是否包含推理过程内容(部分模型要求进行了工具调用后,必须完整回传推理过程给API) | LLMCHAT__MCP_SERVERS同样为一个dict,key为服务器名称,value配置的格式基本兼容 Claude.app 的配置格式,具体支持如下 @@ -184,6 +186,18 @@ LLMCHAT__MCP_SERVERS同样为一个dict,key为服务器名称,value配置的 LLMCHAT__PRIVATE_CHAT_PRESET="deepseek-v1" LLMCHAT__API_PRESETS=' [ + { + "name": "deepseek-v4-pro", + "api_key": "sk-your-api-key", + "model_name": "deepseek-v4-pro", + "api_base": "https://api.deepseek.com", + "support_mcp": true, + "support_image": false, + "extra_body": { + "thinking": {"type": "enabled"} + }, + "request_with_reasoning_content": true + }, { "name": "aliyun-deepseek-v3", "api_key": "sk-your-api-key", diff --git a/nonebot_plugin_llmchat/__init__.py b/nonebot_plugin_llmchat/__init__.py index 4dad9fd..fda18d2 100755 --- a/nonebot_plugin_llmchat/__init__.py +++ b/nonebot_plugin_llmchat/__init__.py @@ -443,6 +443,7 @@ async def process_messages(context_id: int, is_group: bool = True): "max_tokens": preset.max_tokens, "temperature": preset.temperature, "timeout": 60, + "extra_body": preset.extra_body, } if preset.support_mcp: @@ -461,10 +462,14 @@ async def process_messages(context_id: int, is_group: bool = True): # 处理响应并处理工具调用 while preset.support_mcp and message and message.tool_calls: - new_messages.append({ + llm_reply: ChatCompletionMessageParam = { "role": "assistant", + "content": message.content, "tool_calls": [tool_call.model_dump() for tool_call in message.tool_calls] - }) + } + + if preset.request_with_reasoning_content: + llm_reply["reasoning_content"] = message.reasoning_content# pyright: ignore[reportGeneralTypeIssues] # 发送LLM调用工具时的回复,一般没有 if message.content: @@ -531,6 +536,9 @@ async def process_messages(context_id: int, is_group: bool = True): # openai的sdk里的assistant消息暂时没有images字段,需要单独处理 llm_reply["images"] = reply_images # pyright: ignore[reportGeneralTypeIssues] + if preset.request_with_reasoning_content: + llm_reply["reasoning_content"] = reasoning_content# pyright: ignore[reportGeneralTypeIssues] + new_messages.append(llm_reply) # 请求成功后再保存历史记录,保证user和assistant穿插,防止R1模型报错 @@ -540,12 +548,20 @@ async def process_messages(context_id: int, is_group: bool = True): if state.output_reasoning_content and reasoning_content: try: bot = get_bot(str(event.self_id)) - await bot.send_group_forward_msg( - group_id=group_id, - messages=build_reasoning_forward_nodes( - bot.self_id, reasoning_content - ), - ) + if is_group: + await bot.send_group_forward_msg( + group_id=group_id, + messages=build_reasoning_forward_nodes( + bot.self_id, reasoning_content + ), + ) + else: + await bot.send_private_forward_msg( + user_id=context_id, + messages=build_reasoning_forward_nodes( + bot.self_id, reasoning_content + ), + ) except Exception as e: logger.error(f"合并转发消息发送失败:\n{e!s}\n") diff --git a/nonebot_plugin_llmchat/config.py b/nonebot_plugin_llmchat/config.py index 6ecebf1..8d94ec4 100755 --- a/nonebot_plugin_llmchat/config.py +++ b/nonebot_plugin_llmchat/config.py @@ -13,6 +13,11 @@ class PresetConfig(BaseModel): proxy: str = Field("", description="HTTP代理服务器") support_mcp: bool = Field(False, description="是否支持MCP") support_image: bool = Field(False, description="是否支持图片输入") + extra_body: dict = Field({}, description="额外的请求体字段,用于兼容不同API的特殊参数") + request_with_reasoning_content: bool = Field( + False, + description="请求中是否包含推理过程内容(部分模型要求进行了工具调用后,必须完整回传推理过程给API)" + ) class MCPServerConfig(BaseModel): """MCP服务器配置""" From e234048bff16fbd2039045ec330e1771da1ed2da Mon Sep 17 00:00:00 2001 From: FuQuan233 Date: Fri, 24 Apr 2026 14:39:08 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=90=9B=20=E4=BF=AE=E5=A4=8D=E7=A7=81?= =?UTF-8?q?=E8=81=8A=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8F=90=E7=A4=BA=E8=AF=8D?= =?UTF-8?q?=E5=AE=9E=E9=99=85=E6=9C=AA=E7=94=9F=E6=95=88=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nonebot_plugin_llmchat/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nonebot_plugin_llmchat/__init__.py b/nonebot_plugin_llmchat/__init__.py index fda18d2..1ac68dd 100755 --- a/nonebot_plugin_llmchat/__init__.py +++ b/nonebot_plugin_llmchat/__init__.py @@ -101,7 +101,6 @@ class PrivateChatState: self.last_active = time.time() self.past_events = deque(maxlen=plugin_config.past_events_size) self.group_prompt: str | None = None - self.user_prompt: str | None = None self.output_reasoning_content = False @@ -364,7 +363,7 @@ async def process_messages(context_id: int, is_group: bool = True): # 构建系统提示,分成多行以满足行长限制 chat_type = "群聊" if is_group else "私聊" bot_names = "、".join(list(driver.config.nickname)) - default_prompt = (state.group_prompt if is_group else state.user_prompt) or plugin_config.default_prompt + default_prompt = (state.group_prompt) or plugin_config.default_prompt system_lines = [ f"我想要你帮我在{chat_type}中闲聊,大家一般叫你{bot_names}。", From 885c87160b6fd501c2ed67e9137bf82e2e39d482 Mon Sep 17 00:00:00 2001 From: FuQuan233 Date: Fri, 24 Apr 2026 14:42:43 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=94=96=20=E6=9B=B4=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E8=87=B30.5.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7b45de2..7e4c03f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nonebot-plugin-llmchat" -version = "0.5.0" +version = "0.5.1" description = "Nonebot AI group chat plugin supporting multiple API preset configurations" license = "GPL" authors = ["FuQuan i@fuquan.moe"]