Compare commits

..

9 Commits

Author SHA1 Message Date
Junyan Qin (Chin)
8af401eea4 chore: release v3.4.14.2 (#1326) 2025-04-23 17:34:00 +08:00
Junyan Qin (Chin)
446546b69f fix(dify runner): response message event incorrect when using agent app (#1325) 2025-04-23 16:55:52 +08:00
Junyan Qin (Chin)
8a6d9d76da perf: reduce newline in think tag converting (#1319) 2025-04-20 13:41:02 +08:00
Junyan Qin (Chin)
92acaf6c27 chore: release 3.4.14.1 (#1315) 2025-04-19 22:30:22 +08:00
Junyan Qin (Chin)
4d53b3cb06 doc: update README
doc: update README
2025-04-18 20:25:50 +08:00
Junyan Qin (Chin)
7cad4ffa37 Merge pull request #1311 from RockChinQ/feat/ppio
feat: add support for ppio
2025-04-17 16:36:01 +08:00
Junyan Qin
b6f312325f chore: fix 2025-04-17 16:33:35 +08:00
Junyan Qin
43a6492cab chore: migration for ppio config 2025-04-17 16:32:19 +08:00
WangCham
92e3546e8a feat: add support for ppio 2025-04-17 16:18:05 +08:00
13 changed files with 155 additions and 53 deletions

4
.gitignore vendored
View File

@@ -38,5 +38,5 @@ botpy.log*
/poc
/libs/wecom_api/test.py
/venv
/jp-tyo-churros-05.rockchin.top
test.py
test.py
/web_ui

View File

@@ -8,7 +8,7 @@
<a href="https://trendshift.io/repositories/12901" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12901" alt="RockChinQ%2FLangBot | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
<a href="https://docs.langbot.app">项目主页</a>
<a href="https://langbot.app">项目主页</a>
<a href="https://docs.langbot.app/insight/intro.html">功能介绍</a>
<a href="https://docs.langbot.app/insight/guide.html">部署文档</a>
<a href="https://docs.langbot.app/usage/faq.html">常见问题</a>
@@ -110,6 +110,7 @@
| [Anthropic](https://www.anthropic.com/) | ✅ | |
| [xAI](https://x.ai/) | ✅ | |
| [智谱AI](https://open.bigmodel.cn/) | ✅ | |
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型和 GPU 资源平台 |
| [Dify](https://dify.ai) | ✅ | LLMOps 平台 |
| [Ollama](https://ollama.com/) | ✅ | 本地大模型运行平台 |
| [LMStudio](https://lmstudio.ai/) | ✅ | 本地大模型运行平台 |

View File

@@ -7,7 +7,7 @@
<a href="https://trendshift.io/repositories/12901" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12901" alt="RockChinQ%2FLangBot | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
<a href="https://docs.langbot.app">Home</a>
<a href="https://langbot.app">Home</a>
<a href="https://docs.langbot.app/insight/intro.html">Features</a>
<a href="https://docs.langbot.app/insight/guide.html">Deployment</a>
<a href="https://docs.langbot.app/usage/faq.html">FAQ</a>
@@ -108,6 +108,7 @@ Directly use the released version to run, see the [Manual Deployment](https://do
| [xAI](https://x.ai/) | ✅ | |
| [Zhipu AI](https://open.bigmodel.cn/) | ✅ | |
| [Dify](https://dify.ai) | ✅ | LLMOps platform |
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | LLM and GPU resource platform |
| [Ollama](https://ollama.com/) | ✅ | Local LLM running platform |
| [LMStudio](https://lmstudio.ai/) | ✅ | Local LLM running platform |
| [GiteeAI](https://ai.gitee.com/) | ✅ | LLM interface gateway(MaaS) |

View File

@@ -7,7 +7,7 @@
<a href="https://trendshift.io/repositories/12901" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12901" alt="RockChinQ%2FLangBot | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
<a href="https://docs.langbot.app">ホーム</a>
<a href="https://langbot.app">ホーム</a>
<a href="https://docs.langbot.app/insight/intro.html">機能</a>
<a href="https://docs.langbot.app/insight/guide.html">デプロイ</a>
<a href="https://docs.langbot.app/usage/faq.html">FAQ</a>
@@ -106,6 +106,7 @@ LangBotはBTPanelにリストされています。BTPanelをインストール
| [Anthropic](https://www.anthropic.com/) | ✅ | |
| [xAI](https://x.ai/) | ✅ | |
| [Zhipu AI](https://open.bigmodel.cn/) | ✅ | |
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型とGPUリソースプラットフォーム |
| [Dify](https://dify.ai) | ✅ | LLMOpsプラットフォーム |
| [Ollama](https://ollama.com/) | ✅ | ローカルLLM実行プラットフォーム |
| [LMStudio](https://lmstudio.ai/) | ✅ | ローカルLLM実行プラットフォーム |

View File

@@ -3,9 +3,9 @@ from __future__ import annotations
from .. import migration
@migration.migration_class("modelscope-config-completion", 4)
@migration.migration_class("modelscope-config-completion", 39)
class ModelScopeConfigCompletionMigration(migration.Migration):
"""OpenAI配置迁移
"""ModelScope配置迁移
"""
async def need_migrate(self) -> bool:

View File

@@ -0,0 +1,30 @@
from __future__ import annotations
from .. import migration
@migration.migration_class("ppio-config", 40)
class PPIOConfigMigration(migration.Migration):
"""PPIO配置迁移
"""
async def need_migrate(self) -> bool:
"""判断当前环境是否需要运行此迁移
"""
return 'ppio-chat-completions' not in self.ap.provider_cfg.data['requester'] \
or 'ppio' not in self.ap.provider_cfg.data['keys']
async def run(self):
"""执行迁移
"""
if 'ppio-chat-completions' not in self.ap.provider_cfg.data['requester']:
self.ap.provider_cfg.data['requester']['ppio-chat-completions'] = {
'base-url': 'https://api.ppinfra.com/v3/openai',
'args': {},
'timeout': 120,
}
if 'ppio' not in self.ap.provider_cfg.data['keys']:
self.ap.provider_cfg.data['keys']['ppio'] = []
await self.ap.provider_cfg.dump_config()

View File

@@ -12,7 +12,7 @@ from ..migrations import m020_wecom_config, m021_lark_config, m022_lmstudio_conf
from ..migrations import m026_qqofficial_config, m027_wx_official_account_config, m028_aliyun_requester_config
from ..migrations import m029_dashscope_app_api_config, m030_lark_config_cmpl, m031_dingtalk_config, m032_volcark_config
from ..migrations import m033_dify_thinking_config, m034_gewechat_file_url_config, m035_wxoa_mode, m036_wxoa_loading_message
from ..migrations import m037_mcp_config, m038_tg_dingtalk_markdown, m039_modelscope_cfg_completion
from ..migrations import m037_mcp_config, m038_tg_dingtalk_markdown, m039_modelscope_cfg_completion, m040_ppio_config
@stage.stage_class("MigrationStage")

View File

@@ -65,7 +65,7 @@ class OpenAIChatCompletions(requester.LLMAPIRequester):
# deepseek的reasoner模型
if reasoning_content is not None:
chatcmpl_message['content'] = "<think>\n" + reasoning_content + "\n</think>\n\n"+ chatcmpl_message['content']
chatcmpl_message['content'] = "<think>\n" + reasoning_content + "\n</think>\n"+ chatcmpl_message['content']
message = llm_entities.Message(**chatcmpl_message)

View File

@@ -0,0 +1,20 @@
from __future__ import annotations
import openai
from . import chatcmpl, modelscopechatcmpl
from .. import requester
from ....core import app
class PPIOChatCompletions(chatcmpl.OpenAIChatCompletions):
"""欧派云 ChatCompletion API 请求器"""
client: openai.AsyncClient
requester_cfg: dict
def __init__(self, ap: app.Application):
self.ap = ap
self.requester_cfg = self.ap.provider_cfg.data['requester']['ppio-chat-completions']

View File

@@ -0,0 +1,34 @@
apiVersion: v1
kind: LLMAPIRequester
metadata:
name: ppio-chat-completions
label:
en_US: ppio
zh_CN: 派欧云
spec:
config:
- name: base-url
label:
en_US: Base URL
zh_CN: 基础 URL
type: string
required: true
default: "https://api.ppinfra.com/v3/openai"
- name: args
label:
en_US: Args
zh_CN: 附加参数
type: object
required: true
default: {}
- name: timeout
label:
en_US: Timeout
zh_CN: 超时时间
type: int
required: true
default: 120
execution:
python:
path: ./ppiochatcmpl.py
attr: PPIOChatCompletions

View File

@@ -164,12 +164,14 @@ class DifyServiceAPIRunner(runner.RequestRunner):
for image_id in image_ids
]
ignored_events = ["agent_message"]
ignored_events = []
inputs = {}
inputs.update(query.variables)
pending_agent_message = ''
async for chunk in self.dify_client.chat_messages(
inputs=inputs,
query=plain_text,
@@ -183,50 +185,55 @@ class DifyServiceAPIRunner(runner.RequestRunner):
if chunk["event"] in ignored_events:
continue
if chunk["event"] == "agent_thought":
if chunk['tool'] != '' and chunk['observation'] != '': # 工具调用结果,跳过
continue
if chunk['thought'].strip() != '': # 文字回复内容
msg = llm_entities.Message(
role="assistant",
content=chunk["thought"],
)
yield msg
if chunk['tool']:
msg = llm_entities.Message(
role="assistant",
tool_calls=[
llm_entities.ToolCall(
id=chunk['id'],
type="function",
function=llm_entities.FunctionCall(
name=chunk["tool"],
arguments=json.dumps({}),
),
)
],
)
yield msg
if chunk['event'] == 'message_file':
if chunk['type'] == 'image' and chunk['belongs_to'] == 'assistant':
base_url = self.dify_client.base_url
if base_url.endswith('/v1'):
base_url = base_url[:-3]
image_url = base_url + chunk['url']
if chunk['event'] == 'agent_message':
pending_agent_message += chunk['answer']
else:
if pending_agent_message.strip() != '':
pending_agent_message = pending_agent_message.replace('</details>Action:', '</details>')
yield llm_entities.Message(
role="assistant",
content=[llm_entities.ContentElement.from_image_url(image_url)],
content=self._try_convert_thinking(pending_agent_message),
)
if chunk['event'] == 'error':
raise errors.DifyAPIError("dify 服务错误: " + chunk['message'])
pending_agent_message = ''
if chunk["event"] == "agent_thought":
if chunk['tool'] != '' and chunk['observation'] != '': # 工具调用结果,跳过
continue
if chunk['tool']:
msg = llm_entities.Message(
role="assistant",
tool_calls=[
llm_entities.ToolCall(
id=chunk['id'],
type="function",
function=llm_entities.FunctionCall(
name=chunk["tool"],
arguments=json.dumps({}),
),
)
],
)
yield msg
if chunk['event'] == 'message_file':
if chunk['type'] == 'image' and chunk['belongs_to'] == 'assistant':
base_url = self.dify_client.base_url
if base_url.endswith('/v1'):
base_url = base_url[:-3]
image_url = base_url + chunk['url']
yield llm_entities.Message(
role="assistant",
content=[llm_entities.ContentElement.from_image_url(image_url)],
)
if chunk['event'] == 'error':
raise errors.DifyAPIError("dify 服务错误: " + chunk['message'])
query.session.using_conversation.uuid = chunk["conversation_id"]
@@ -303,11 +310,11 @@ class DifyServiceAPIRunner(runner.RequestRunner):
msg = llm_entities.Message(
role="assistant",
content=chunk["data"]["outputs"][
content=self._try_convert_thinking(chunk["data"]["outputs"][
self.ap.provider_cfg.data["dify-service-api"]["workflow"][
"output-key"
]
],
]),
)
yield msg

View File

@@ -1,4 +1,4 @@
semantic_version = "v3.4.14"
semantic_version = "v3.4.14.2"
debug_mode = False

View File

@@ -34,6 +34,9 @@
],
"modelscope": [
"xxxxxxxx"
],
"ppio": [
"xxxxxxxx"
]
},
"requester": {
@@ -103,6 +106,11 @@
"base-url": "https://api-inference.modelscope.cn/v1",
"args": {},
"timeout": 120
},
"ppio-chat-completions": {
"base-url": "https://api.ppinfra.com/v3/openai",
"args": {},
"timeout": 120
}
},
"model": "gpt-4o",