mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-08 23:06:03 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8af401eea4 | ||
|
|
446546b69f | ||
|
|
8a6d9d76da | ||
|
|
92acaf6c27 | ||
|
|
4d53b3cb06 | ||
|
|
7cad4ffa37 | ||
|
|
b6f312325f | ||
|
|
43a6492cab | ||
|
|
92e3546e8a |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -38,5 +38,5 @@ botpy.log*
|
|||||||
/poc
|
/poc
|
||||||
/libs/wecom_api/test.py
|
/libs/wecom_api/test.py
|
||||||
/venv
|
/venv
|
||||||
/jp-tyo-churros-05.rockchin.top
|
test.py
|
||||||
test.py
|
/web_ui
|
||||||
@@ -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://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/intro.html">功能介绍</a> |
|
||||||
<a href="https://docs.langbot.app/insight/guide.html">部署文档</a> |
|
<a href="https://docs.langbot.app/insight/guide.html">部署文档</a> |
|
||||||
<a href="https://docs.langbot.app/usage/faq.html">常见问题</a> |
|
<a href="https://docs.langbot.app/usage/faq.html">常见问题</a> |
|
||||||
@@ -110,6 +110,7 @@
|
|||||||
| [Anthropic](https://www.anthropic.com/) | ✅ | |
|
| [Anthropic](https://www.anthropic.com/) | ✅ | |
|
||||||
| [xAI](https://x.ai/) | ✅ | |
|
| [xAI](https://x.ai/) | ✅ | |
|
||||||
| [智谱AI](https://open.bigmodel.cn/) | ✅ | |
|
| [智谱AI](https://open.bigmodel.cn/) | ✅ | |
|
||||||
|
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型和 GPU 资源平台 |
|
||||||
| [Dify](https://dify.ai) | ✅ | LLMOps 平台 |
|
| [Dify](https://dify.ai) | ✅ | LLMOps 平台 |
|
||||||
| [Ollama](https://ollama.com/) | ✅ | 本地大模型运行平台 |
|
| [Ollama](https://ollama.com/) | ✅ | 本地大模型运行平台 |
|
||||||
| [LMStudio](https://lmstudio.ai/) | ✅ | 本地大模型运行平台 |
|
| [LMStudio](https://lmstudio.ai/) | ✅ | 本地大模型运行平台 |
|
||||||
|
|||||||
@@ -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://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/intro.html">Features</a> |
|
||||||
<a href="https://docs.langbot.app/insight/guide.html">Deployment</a> |
|
<a href="https://docs.langbot.app/insight/guide.html">Deployment</a> |
|
||||||
<a href="https://docs.langbot.app/usage/faq.html">FAQ</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/) | ✅ | |
|
| [xAI](https://x.ai/) | ✅ | |
|
||||||
| [Zhipu AI](https://open.bigmodel.cn/) | ✅ | |
|
| [Zhipu AI](https://open.bigmodel.cn/) | ✅ | |
|
||||||
| [Dify](https://dify.ai) | ✅ | LLMOps platform |
|
| [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 |
|
| [Ollama](https://ollama.com/) | ✅ | Local LLM running platform |
|
||||||
| [LMStudio](https://lmstudio.ai/) | ✅ | Local LLM running platform |
|
| [LMStudio](https://lmstudio.ai/) | ✅ | Local LLM running platform |
|
||||||
| [GiteeAI](https://ai.gitee.com/) | ✅ | LLM interface gateway(MaaS) |
|
| [GiteeAI](https://ai.gitee.com/) | ✅ | LLM interface gateway(MaaS) |
|
||||||
|
|||||||
@@ -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://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/intro.html">機能</a> |
|
||||||
<a href="https://docs.langbot.app/insight/guide.html">デプロイ</a> |
|
<a href="https://docs.langbot.app/insight/guide.html">デプロイ</a> |
|
||||||
<a href="https://docs.langbot.app/usage/faq.html">FAQ</a> |
|
<a href="https://docs.langbot.app/usage/faq.html">FAQ</a> |
|
||||||
@@ -106,6 +106,7 @@ LangBotはBTPanelにリストされています。BTPanelをインストール
|
|||||||
| [Anthropic](https://www.anthropic.com/) | ✅ | |
|
| [Anthropic](https://www.anthropic.com/) | ✅ | |
|
||||||
| [xAI](https://x.ai/) | ✅ | |
|
| [xAI](https://x.ai/) | ✅ | |
|
||||||
| [Zhipu AI](https://open.bigmodel.cn/) | ✅ | |
|
| [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プラットフォーム |
|
| [Dify](https://dify.ai) | ✅ | LLMOpsプラットフォーム |
|
||||||
| [Ollama](https://ollama.com/) | ✅ | ローカルLLM実行プラットフォーム |
|
| [Ollama](https://ollama.com/) | ✅ | ローカルLLM実行プラットフォーム |
|
||||||
| [LMStudio](https://lmstudio.ai/) | ✅ | ローカルLLM実行プラットフォーム |
|
| [LMStudio](https://lmstudio.ai/) | ✅ | ローカルLLM実行プラットフォーム |
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ from __future__ import annotations
|
|||||||
from .. import migration
|
from .. import migration
|
||||||
|
|
||||||
|
|
||||||
@migration.migration_class("modelscope-config-completion", 4)
|
@migration.migration_class("modelscope-config-completion", 39)
|
||||||
class ModelScopeConfigCompletionMigration(migration.Migration):
|
class ModelScopeConfigCompletionMigration(migration.Migration):
|
||||||
"""OpenAI配置迁移
|
"""ModelScope配置迁移
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def need_migrate(self) -> bool:
|
async def need_migrate(self) -> bool:
|
||||||
|
|||||||
30
pkg/core/migrations/m040_ppio_config.py
Normal file
30
pkg/core/migrations/m040_ppio_config.py
Normal 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()
|
||||||
@@ -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 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 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 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")
|
@stage.stage_class("MigrationStage")
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class OpenAIChatCompletions(requester.LLMAPIRequester):
|
|||||||
|
|
||||||
# deepseek的reasoner模型
|
# deepseek的reasoner模型
|
||||||
if reasoning_content is not None:
|
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)
|
message = llm_entities.Message(**chatcmpl_message)
|
||||||
|
|
||||||
|
|||||||
20
pkg/provider/modelmgr/requesters/ppiochatcmpl.py
Normal file
20
pkg/provider/modelmgr/requesters/ppiochatcmpl.py
Normal 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']
|
||||||
34
pkg/provider/modelmgr/requesters/ppiochatcmpl.yaml
Normal file
34
pkg/provider/modelmgr/requesters/ppiochatcmpl.yaml
Normal 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
|
||||||
@@ -164,12 +164,14 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
for image_id in image_ids
|
for image_id in image_ids
|
||||||
]
|
]
|
||||||
|
|
||||||
ignored_events = ["agent_message"]
|
ignored_events = []
|
||||||
|
|
||||||
inputs = {}
|
inputs = {}
|
||||||
|
|
||||||
inputs.update(query.variables)
|
inputs.update(query.variables)
|
||||||
|
|
||||||
|
pending_agent_message = ''
|
||||||
|
|
||||||
async for chunk in self.dify_client.chat_messages(
|
async for chunk in self.dify_client.chat_messages(
|
||||||
inputs=inputs,
|
inputs=inputs,
|
||||||
query=plain_text,
|
query=plain_text,
|
||||||
@@ -183,50 +185,55 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
|
|
||||||
if chunk["event"] in ignored_events:
|
if chunk["event"] in ignored_events:
|
||||||
continue
|
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(
|
yield llm_entities.Message(
|
||||||
role="assistant",
|
role="assistant",
|
||||||
content=[llm_entities.ContentElement.from_image_url(image_url)],
|
content=self._try_convert_thinking(pending_agent_message),
|
||||||
)
|
)
|
||||||
if chunk['event'] == 'error':
|
pending_agent_message = ''
|
||||||
raise errors.DifyAPIError("dify 服务错误: " + chunk['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"]
|
query.session.using_conversation.uuid = chunk["conversation_id"]
|
||||||
|
|
||||||
@@ -303,11 +310,11 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
|
|
||||||
msg = llm_entities.Message(
|
msg = llm_entities.Message(
|
||||||
role="assistant",
|
role="assistant",
|
||||||
content=chunk["data"]["outputs"][
|
content=self._try_convert_thinking(chunk["data"]["outputs"][
|
||||||
self.ap.provider_cfg.data["dify-service-api"]["workflow"][
|
self.ap.provider_cfg.data["dify-service-api"]["workflow"][
|
||||||
"output-key"
|
"output-key"
|
||||||
]
|
]
|
||||||
],
|
]),
|
||||||
)
|
)
|
||||||
|
|
||||||
yield msg
|
yield msg
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
semantic_version = "v3.4.14"
|
semantic_version = "v3.4.14.2"
|
||||||
|
|
||||||
debug_mode = False
|
debug_mode = False
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
],
|
],
|
||||||
"modelscope": [
|
"modelscope": [
|
||||||
"xxxxxxxx"
|
"xxxxxxxx"
|
||||||
|
],
|
||||||
|
"ppio": [
|
||||||
|
"xxxxxxxx"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"requester": {
|
"requester": {
|
||||||
@@ -103,6 +106,11 @@
|
|||||||
"base-url": "https://api-inference.modelscope.cn/v1",
|
"base-url": "https://api-inference.modelscope.cn/v1",
|
||||||
"args": {},
|
"args": {},
|
||||||
"timeout": 120
|
"timeout": 120
|
||||||
|
},
|
||||||
|
"ppio-chat-completions": {
|
||||||
|
"base-url": "https://api.ppinfra.com/v3/openai",
|
||||||
|
"args": {},
|
||||||
|
"timeout": 120
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"model": "gpt-4o",
|
"model": "gpt-4o",
|
||||||
|
|||||||
Reference in New Issue
Block a user