From 412f29060655405c05ee8b26ec346f75f8fbae1c Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Wed, 5 Feb 2025 21:55:10 +0800 Subject: [PATCH 1/9] fix(wrapper): potential tool_calls misjudgment --- pkg/pipeline/wrapper/wrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/pipeline/wrapper/wrapper.py b/pkg/pipeline/wrapper/wrapper.py index 1ffb3147..a06e4a80 100644 --- a/pkg/pipeline/wrapper/wrapper.py +++ b/pkg/pipeline/wrapper/wrapper.py @@ -102,7 +102,7 @@ class ResponseWrapper(stage.PipelineStage): new_query=query ) - if result.tool_calls is not None: # 有函数调用 + if result.tool_calls is not None and len(result.tool_calls) > 0: # 有函数调用 function_names = [tc.function.name for tc in result.tool_calls] From d0606b79b0a0f580631755d4d1517fd533ed4244 Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Wed, 5 Feb 2025 22:10:50 +0800 Subject: [PATCH 2/9] chore: update issue template --- .github/ISSUE_TEMPLATE/bug-report.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index 397c49fe..7181f918 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -11,9 +11,12 @@ body: - 其他(或暂未使用) - Nakuru(go-cqhttp) - aiocqhttp(使用 OneBot 协议接入的) - - qq-botpy(QQ官方API) + - qq-botpy(QQ官方API WebSocket) + - qqofficial(QQ官方API Webhook) - lark(飞书) - wecom(企业微信) + - gewechat(个人微信) + - discord validations: required: true - type: input From eceaf85807e82eb79c0eafb65b946ee6a5908c72 Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Thu, 6 Feb 2025 14:48:43 +0800 Subject: [PATCH 3/9] feat: use stream req in the chatcmpl (#992) --- pkg/provider/modelmgr/requesters/chatcmpl.py | 64 ++++++++++++++++++- .../modelmgr/requesters/deepseekchatcmpl.py | 3 + 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/pkg/provider/modelmgr/requesters/chatcmpl.py b/pkg/provider/modelmgr/requesters/chatcmpl.py index 9e3014af..55ee0687 100644 --- a/pkg/provider/modelmgr/requesters/chatcmpl.py +++ b/pkg/provider/modelmgr/requesters/chatcmpl.py @@ -8,6 +8,7 @@ from typing import AsyncGenerator import openai import openai.types.chat.chat_completion as chat_completion +import openai.types.chat.chat_completion_message_tool_call as chat_completion_message_tool_call import httpx import aiohttp import async_lru @@ -40,6 +41,7 @@ class OpenAIChatCompletions(requester.LLMAPIRequester): timeout=self.requester_cfg['timeout'], http_client=httpx.AsyncClient( trust_env=True, + timeout=self.requester_cfg['timeout'] ) ) @@ -47,7 +49,67 @@ class OpenAIChatCompletions(requester.LLMAPIRequester): self, args: dict, ) -> chat_completion.ChatCompletion: - return await self.client.chat.completions.create(**args) + args["stream"] = True + + chunk = None + + pending_content = "" + + tool_calls = [] + + resp_gen: openai.AsyncStream = await self.client.chat.completions.create(**args) + + async for chunk in resp_gen: + # print(chunk) + if not chunk: + continue + + if chunk.choices[0].delta.content is not None: + pending_content += chunk.choices[0].delta.content + + if chunk.choices[0].delta.tool_calls is not None: + for tool_call in chunk.choices[0].delta.tool_calls: + for tc in tool_calls: + if tc.index == tool_call.index: + tc.function.arguments += tool_call.function.arguments + break + else: + tool_calls.append(tool_call) + + real_tool_calls = [] + + for tc in tool_calls: + function = chat_completion_message_tool_call.Function( + name=tc.function.name, + arguments=tc.function.arguments + ) + real_tool_calls.append(chat_completion_message_tool_call.ChatCompletionMessageToolCall( + id=tc.id, + function=function, + type="function" + )) + + return chat_completion.ChatCompletion( + id=chunk.id, + object="chat.completion", + created=chunk.created, + choices=[ + chat_completion.Choice( + index=0, + message=chat_completion.ChatCompletionMessage( + role="assistant", + content=pending_content, + tool_calls=real_tool_calls if len(real_tool_calls) > 0 else None + ), + finish_reason=chunk.choices[0].finish_reason, + logprobs=chunk.choices[0].logprobs, + ) + ], + model=args["model"], + service_tier=chunk.service_tier, + system_fingerprint=chunk.system_fingerprint, + usage=chunk.usage + ) if chunk else None async def _make_msg( self, diff --git a/pkg/provider/modelmgr/requesters/deepseekchatcmpl.py b/pkg/provider/modelmgr/requesters/deepseekchatcmpl.py index bf414745..7b8c9ca8 100644 --- a/pkg/provider/modelmgr/requesters/deepseekchatcmpl.py +++ b/pkg/provider/modelmgr/requesters/deepseekchatcmpl.py @@ -46,6 +46,9 @@ class DeepseekChatCompletions(chatcmpl.OpenAIChatCompletions): # 发送请求 resp = await self._req(args) + if resp is None: + raise errors.RequesterError('接口返回为空,请确定模型提供商服务是否正常') + # 处理请求结果 message = await self._make_msg(resp) From dbe6272bd8c3cd29b39c0c89032080254ec872c7 Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Thu, 6 Feb 2025 14:52:01 +0800 Subject: [PATCH 4/9] chore: release v3.4.6.1 --- pkg/core/notes/n003_print_version.py | 21 +++++++++++++++++++++ pkg/core/stages/show_notes.py | 2 +- pkg/utils/constants.py | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 pkg/core/notes/n003_print_version.py diff --git a/pkg/core/notes/n003_print_version.py b/pkg/core/notes/n003_print_version.py new file mode 100644 index 00000000..6eed21d6 --- /dev/null +++ b/pkg/core/notes/n003_print_version.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +import typing +import os +import sys +import logging + +from .. import note, app + + +@note.note_class("PrintVersion", 3) +class PrintVersion(note.LaunchNote): + """打印版本信息 + """ + + async def need_show(self) -> bool: + return True + + async def yield_note(self) -> typing.AsyncGenerator[typing.Tuple[str, int], None]: + + yield f"当前版本:{self.ap.ver_mgr.get_current_version()}", logging.INFO diff --git a/pkg/core/stages/show_notes.py b/pkg/core/stages/show_notes.py index 91cdbf01..63d8f580 100644 --- a/pkg/core/stages/show_notes.py +++ b/pkg/core/stages/show_notes.py @@ -1,7 +1,7 @@ from __future__ import annotations from .. import stage, app, note -from ..notes import n001_classic_msgs, n002_selection_mode_on_windows +from ..notes import n001_classic_msgs, n002_selection_mode_on_windows, n003_print_version @stage.stage_class("ShowNotesStage") diff --git a/pkg/utils/constants.py b/pkg/utils/constants.py index 0dce973c..5d6ee96d 100644 --- a/pkg/utils/constants.py +++ b/pkg/utils/constants.py @@ -1,4 +1,4 @@ -semantic_version = "v3.4.6" +semantic_version = "v3.4.6.1" debug_mode = False From d0ceaff6ed89ff5cf0a4fec16ea92fa2453464d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 02:56:43 +0000 Subject: [PATCH 5/9] chore(deps): bump jsonpath-plus from 10.1.0 to 10.2.0 in /web Bumps [jsonpath-plus](https://github.com/s3u/JSONPath) from 10.1.0 to 10.2.0. - [Release notes](https://github.com/s3u/JSONPath/releases) - [Changelog](https://github.com/JSONPath-Plus/JSONPath/blob/main/CHANGES.md) - [Commits](https://github.com/s3u/JSONPath/compare/v10.1.0...v10.2.0) --- updated-dependencies: - dependency-name: jsonpath-plus dependency-type: indirect ... Signed-off-by: dependabot[bot] --- web/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index d692c64b..331b2815 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -4410,14 +4410,14 @@ } }, "node_modules/jsonpath-plus": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.1.0.tgz", - "integrity": "sha512-gHfV1IYqH8uJHYVTs8BJX1XKy2/rR93+f8QQi0xhx95aCiXn1ettYAd5T+7FU6wfqyDoX/wy0pm/fL3jOKJ9Lg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.2.0.tgz", + "integrity": "sha512-T9V+8iNYKFL2n2rF+w02LBOT2JjDnTjioaNFrxRy0Bv1y/hNsqR/EBK7Ojy2ythRHwmz2cRIls+9JitQGZC/sw==", "license": "MIT", "dependencies": { - "@jsep-plugin/assignment": "^1.2.1", - "@jsep-plugin/regex": "^1.0.3", - "jsep": "^1.3.9" + "@jsep-plugin/assignment": "^1.3.0", + "@jsep-plugin/regex": "^1.0.4", + "jsep": "^1.4.0" }, "bin": { "jsonpath": "bin/jsonpath-cli.js", From e83b0a7825f0d0ce3a15ec183c88197d4377277f Mon Sep 17 00:00:00 2001 From: Lorenzo Feng <42567930+7emotions@users.noreply.github.com> Date: Fri, 7 Feb 2025 21:19:47 +0800 Subject: [PATCH 6/9] fix: remove fatal clearance to message from QQWebhook --- pkg/platform/sources/qqofficial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/platform/sources/qqofficial.py b/pkg/platform/sources/qqofficial.py index f41e84db..c85868b0 100644 --- a/pkg/platform/sources/qqofficial.py +++ b/pkg/platform/sources/qqofficial.py @@ -47,7 +47,7 @@ class QQOfficialMessageConverter(adapter.MessageConverter): yiri_msg_list.append( platform_message.Image(base64=base64_url) ) - message = '' + yiri_msg_list.append(platform_message.Plain(text=message)) chain = platform_message.MessageChain(yiri_msg_list) return chain From 21cfb6ee6f305a4310082aa4a7d9032754167a4c Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Fri, 7 Feb 2025 23:57:51 +0800 Subject: [PATCH 7/9] fix: some field may not exist in chatcmplchunk --- pkg/provider/modelmgr/requesters/chatcmpl.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/provider/modelmgr/requesters/chatcmpl.py b/pkg/provider/modelmgr/requesters/chatcmpl.py index 55ee0687..0b1c4cf2 100644 --- a/pkg/provider/modelmgr/requesters/chatcmpl.py +++ b/pkg/provider/modelmgr/requesters/chatcmpl.py @@ -101,14 +101,14 @@ class OpenAIChatCompletions(requester.LLMAPIRequester): content=pending_content, tool_calls=real_tool_calls if len(real_tool_calls) > 0 else None ), - finish_reason=chunk.choices[0].finish_reason, + finish_reason=chunk.choices[0].finish_reason if hasattr(chunk.choices[0], 'finish_reason') and chunk.choices[0].finish_reason is not None else 'stop', logprobs=chunk.choices[0].logprobs, ) ], - model=args["model"], - service_tier=chunk.service_tier, - system_fingerprint=chunk.system_fingerprint, - usage=chunk.usage + model=chunk.model, + service_tier=chunk.service_tier if hasattr(chunk, 'service_tier') else None, + system_fingerprint=chunk.system_fingerprint if hasattr(chunk, 'system_fingerprint') else None, + usage=chunk.usage if hasattr(chunk, 'usage') else None ) if chunk else None async def _make_msg( From 4d8ebc8c38b2b3c49ee636aa949bd0c9d642658a Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Sat, 8 Feb 2025 00:05:12 +0800 Subject: [PATCH 8/9] chore: release v3.4.6.2 --- pkg/utils/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/utils/constants.py b/pkg/utils/constants.py index 5d6ee96d..61ed497b 100644 --- a/pkg/utils/constants.py +++ b/pkg/utils/constants.py @@ -1,4 +1,4 @@ -semantic_version = "v3.4.6.1" +semantic_version = "v3.4.6.2" debug_mode = False From d7687913a9b734d4fb83b9c866b774fd2b82f823 Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Mon, 10 Feb 2025 11:04:57 +0800 Subject: [PATCH 9/9] doc(README.md): update trendingshift badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc78032c..2921bf23 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@