mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-05 05:16:03 +00:00
Compare commits
5 Commits
v4.2.1
...
v4.3.0.bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87ecb4e519 | ||
|
|
df524b8a7a | ||
|
|
8a7df423ab | ||
|
|
cafd623c92 | ||
|
|
4df11ef064 |
@@ -109,6 +109,7 @@ docker compose up -d
|
|||||||
| [智谱AI](https://open.bigmodel.cn/) | ✅ | |
|
| [智谱AI](https://open.bigmodel.cn/) | ✅ | |
|
||||||
| [优云智算](https://www.compshare.cn/?ytag=GPU_YY-gh_langbot) | ✅ | 大模型和 GPU 资源平台 |
|
| [优云智算](https://www.compshare.cn/?ytag=GPU_YY-gh_langbot) | ✅ | 大模型和 GPU 资源平台 |
|
||||||
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型和 GPU 资源平台 |
|
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型和 GPU 资源平台 |
|
||||||
|
| [胜算云](https://www.shengsuanyun.com/?from=CH_KYIPP758) | ✅ | 大模型和 GPU 资源平台 |
|
||||||
| [302.AI](https://share.302.ai/SuTG99) | ✅ | 大模型聚合平台 |
|
| [302.AI](https://share.302.ai/SuTG99) | ✅ | 大模型聚合平台 |
|
||||||
| [Google Gemini](https://aistudio.google.com/prompts/new_chat) | ✅ | |
|
| [Google Gemini](https://aistudio.google.com/prompts/new_chat) | ✅ | |
|
||||||
| [Dify](https://dify.ai) | ✅ | LLMOps 平台 |
|
| [Dify](https://dify.ai) | ✅ | LLMOps 平台 |
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ Or visit the demo environment: https://demo.langbot.dev/
|
|||||||
| [CompShare](https://www.compshare.cn/?ytag=GPU_YY-gh_langbot) | ✅ | LLM and GPU resource platform |
|
| [CompShare](https://www.compshare.cn/?ytag=GPU_YY-gh_langbot) | ✅ | LLM and GPU resource platform |
|
||||||
| [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 |
|
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | LLM and GPU resource platform |
|
||||||
|
| [ShengSuanYun](https://www.shengsuanyun.com/?from=CH_KYIPP758) | ✅ | LLM and GPU resource platform |
|
||||||
| [302.AI](https://share.302.ai/SuTG99) | ✅ | LLM gateway(MaaS) |
|
| [302.AI](https://share.302.ai/SuTG99) | ✅ | LLM gateway(MaaS) |
|
||||||
| [Google Gemini](https://aistudio.google.com/prompts/new_chat) | ✅ | |
|
| [Google Gemini](https://aistudio.google.com/prompts/new_chat) | ✅ | |
|
||||||
| [Ollama](https://ollama.com/) | ✅ | Local LLM running platform |
|
| [Ollama](https://ollama.com/) | ✅ | Local LLM running platform |
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ LangBotはBTPanelにリストされています。BTPanelをインストール
|
|||||||
| [Zhipu AI](https://open.bigmodel.cn/) | ✅ | |
|
| [Zhipu AI](https://open.bigmodel.cn/) | ✅ | |
|
||||||
| [CompShare](https://www.compshare.cn/?ytag=GPU_YY-gh_langbot) | ✅ | 大模型とGPUリソースプラットフォーム |
|
| [CompShare](https://www.compshare.cn/?ytag=GPU_YY-gh_langbot) | ✅ | 大模型とGPUリソースプラットフォーム |
|
||||||
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型とGPUリソースプラットフォーム |
|
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型とGPUリソースプラットフォーム |
|
||||||
|
| [ShengSuanYun](https://www.shengsuanyun.com/?from=CH_KYIPP758) | ✅ | LLMとGPUリソースプラットフォーム |
|
||||||
| [302.AI](https://share.302.ai/SuTG99) | ✅ | LLMゲートウェイ(MaaS) |
|
| [302.AI](https://share.302.ai/SuTG99) | ✅ | LLMゲートウェイ(MaaS) |
|
||||||
| [Google Gemini](https://aistudio.google.com/prompts/new_chat) | ✅ | |
|
| [Google Gemini](https://aistudio.google.com/prompts/new_chat) | ✅ | |
|
||||||
| [Dify](https://dify.ai) | ✅ | LLMOpsプラットフォーム |
|
| [Dify](https://dify.ai) | ✅ | LLMOpsプラットフォーム |
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ docker compose up -d
|
|||||||
| [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/) | ✅ | |
|
||||||
|
| [勝算雲](https://www.shengsuanyun.com/?from=CH_KYIPP758) | ✅ | 大模型和 GPU 資源平台 |
|
||||||
| [優雲智算](https://www.compshare.cn/?ytag=GPU_YY-gh_langbot) | ✅ | 大模型和 GPU 資源平台 |
|
| [優雲智算](https://www.compshare.cn/?ytag=GPU_YY-gh_langbot) | ✅ | 大模型和 GPU 資源平台 |
|
||||||
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型和 GPU 資源平台 |
|
| [PPIO](https://ppinfra.com/user/register?invited_by=QJKFYD&utm_source=github_langbot) | ✅ | 大模型和 GPU 資源平台 |
|
||||||
| [302.AI](https://share.302.ai/SuTG99) | ✅ | 大模型聚合平台 |
|
| [302.AI](https://share.302.ai/SuTG99) | ✅ | 大模型聚合平台 |
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class DBMigratePipelineRemoveCotConfig(migration.DBMigration):
|
|||||||
config = serialized_pipeline['config']
|
config = serialized_pipeline['config']
|
||||||
|
|
||||||
if 'remove-think' not in config['output']['misc']:
|
if 'remove-think' not in config['output']['misc']:
|
||||||
config['output']['misc']['remove-think'] = True
|
config['output']['misc']['remove-think'] = False
|
||||||
|
|
||||||
await self.ap.persistence_mgr.execute_async(
|
await self.ap.persistence_mgr.execute_async(
|
||||||
sqlalchemy.update(persistence_pipeline.LegacyPipeline)
|
sqlalchemy.update(persistence_pipeline.LegacyPipeline)
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ class AiocqhttpMessageConverter(adapter.MessageConverter):
|
|||||||
await process_message_data(msg_data, reply_list)
|
await process_message_data(msg_data, reply_list)
|
||||||
|
|
||||||
reply_msg = platform_message.Quote(
|
reply_msg = platform_message.Quote(
|
||||||
message_id=msg.data['id'], sender_id=msg_datas['user_id'], origin=reply_list
|
message_id=msg.data['id'], sender_id=msg_datas['sender']['user_id'], origin=reply_list
|
||||||
)
|
)
|
||||||
yiri_msg_list.append(reply_msg)
|
yiri_msg_list.append(reply_msg)
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import openai.types.chat.chat_completion as chat_completion
|
|||||||
|
|
||||||
|
|
||||||
class ShengSuanYunChatCompletions(chatcmpl.OpenAIChatCompletions):
|
class ShengSuanYunChatCompletions(chatcmpl.OpenAIChatCompletions):
|
||||||
"""胜算云 ChatCompletion API 请求器"""
|
"""胜算云(ModelSpot.AI) ChatCompletion API 请求器"""
|
||||||
|
|
||||||
client: openai.AsyncClient
|
client: openai.AsyncClient
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|||||||
import typing
|
import typing
|
||||||
import json
|
import json
|
||||||
import uuid
|
import uuid
|
||||||
import re
|
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
|
|
||||||
@@ -38,33 +37,9 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
base_url=self.pipeline_config['ai']['dify-service-api']['base-url'],
|
base_url=self.pipeline_config['ai']['dify-service-api']['base-url'],
|
||||||
)
|
)
|
||||||
|
|
||||||
def _try_convert_thinking(self, resp_text: str) -> str:
|
|
||||||
"""尝试转换 Dify 的思考提示"""
|
|
||||||
if not resp_text.startswith(
|
|
||||||
'<details style="color:gray;background-color: #f8f8f8;padding: 8px;border-radius: 4px;" open> <summary> Thinking... </summary>'
|
|
||||||
):
|
|
||||||
return resp_text
|
|
||||||
|
|
||||||
if self.pipeline_config['ai']['dify-service-api']['thinking-convert'] == 'original':
|
|
||||||
return resp_text
|
|
||||||
|
|
||||||
if self.pipeline_config['ai']['dify-service-api']['thinking-convert'] == 'remove':
|
|
||||||
return re.sub(
|
|
||||||
r'<details style="color:gray;background-color: #f8f8f8;padding: 8px;border-radius: 4px;" open> <summary> Thinking... </summary>.*?</details>',
|
|
||||||
'',
|
|
||||||
resp_text,
|
|
||||||
flags=re.DOTALL,
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.pipeline_config['ai']['dify-service-api']['thinking-convert'] == 'plain':
|
|
||||||
pattern = r'<details style="color:gray;background-color: #f8f8f8;padding: 8px;border-radius: 4px;" open> <summary> Thinking... </summary>(.*?)</details>'
|
|
||||||
thinking_text = re.search(pattern, resp_text, flags=re.DOTALL)
|
|
||||||
content_text = re.sub(pattern, '', resp_text, flags=re.DOTALL)
|
|
||||||
return f'<think>{thinking_text.group(1)}</think>\n{content_text}'
|
|
||||||
|
|
||||||
def _process_thinking_content(
|
def _process_thinking_content(
|
||||||
self,
|
self,
|
||||||
content: str,
|
content: str,
|
||||||
) -> tuple[str, str]:
|
) -> tuple[str, str]:
|
||||||
"""处理思维链内容
|
"""处理思维链内容
|
||||||
|
|
||||||
@@ -354,8 +329,9 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
|
|
||||||
yield msg
|
yield msg
|
||||||
|
|
||||||
|
async def _chat_messages_chunk(
|
||||||
async def _chat_messages_chunk(self, query: core_entities.Query) -> typing.AsyncGenerator[llm_entities.MessageChunk, None]:
|
self, query: core_entities.Query
|
||||||
|
) -> typing.AsyncGenerator[llm_entities.MessageChunk, None]:
|
||||||
"""调用聊天助手"""
|
"""调用聊天助手"""
|
||||||
cov_id = query.session.using_conversation.uuid or ''
|
cov_id = query.session.using_conversation.uuid or ''
|
||||||
query.variables['conversation_id'] = cov_id
|
query.variables['conversation_id'] = cov_id
|
||||||
@@ -371,8 +347,6 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
for image_id in image_ids
|
for image_id in image_ids
|
||||||
]
|
]
|
||||||
|
|
||||||
mode = 'basic' # 标记是基础编排还是工作流编排
|
|
||||||
|
|
||||||
basic_mode_pending_chunk = ''
|
basic_mode_pending_chunk = ''
|
||||||
|
|
||||||
inputs = {}
|
inputs = {}
|
||||||
@@ -411,6 +385,7 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
continue
|
continue
|
||||||
if '</think>' in chunk['answer'] and not think_end:
|
if '</think>' in chunk['answer'] and not think_end:
|
||||||
import re
|
import re
|
||||||
|
|
||||||
content = re.sub(r'^\n</think>', '', chunk['answer'])
|
content = re.sub(r'^\n</think>', '', chunk['answer'])
|
||||||
basic_mode_pending_chunk += content
|
basic_mode_pending_chunk += content
|
||||||
think_end = True
|
think_end = True
|
||||||
@@ -433,13 +408,11 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
is_final=is_final,
|
is_final=is_final,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if chunk is None:
|
if chunk is None:
|
||||||
raise errors.DifyAPIError('Dify API 没有返回任何响应,请检查网络连接和API配置')
|
raise errors.DifyAPIError('Dify API 没有返回任何响应,请检查网络连接和API配置')
|
||||||
|
|
||||||
query.session.using_conversation.uuid = chunk['conversation_id']
|
query.session.using_conversation.uuid = chunk['conversation_id']
|
||||||
|
|
||||||
|
|
||||||
async def _agent_chat_messages_chunk(
|
async def _agent_chat_messages_chunk(
|
||||||
self, query: core_entities.Query
|
self, query: core_entities.Query
|
||||||
) -> typing.AsyncGenerator[llm_entities.MessageChunk, None]:
|
) -> typing.AsyncGenerator[llm_entities.MessageChunk, None]:
|
||||||
@@ -496,6 +469,7 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
continue
|
continue
|
||||||
if '</think>' in chunk['answer'] and not think_end:
|
if '</think>' in chunk['answer'] and not think_end:
|
||||||
import re
|
import re
|
||||||
|
|
||||||
content = re.sub(r'^\n</think>', '', chunk['answer'])
|
content = re.sub(r'^\n</think>', '', chunk['answer'])
|
||||||
pending_agent_message += content
|
pending_agent_message += content
|
||||||
think_end = True
|
think_end = True
|
||||||
@@ -509,7 +483,6 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
elif chunk['event'] == 'message_end':
|
elif chunk['event'] == 'message_end':
|
||||||
is_final = True
|
is_final = True
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if chunk['event'] == 'agent_thought':
|
if chunk['event'] == 'agent_thought':
|
||||||
if chunk['tool'] != '' and chunk['observation'] != '': # 工具调用结果,跳过
|
if chunk['tool'] != '' and chunk['observation'] != '': # 工具调用结果,跳过
|
||||||
continue
|
continue
|
||||||
@@ -543,7 +516,6 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
role='assistant',
|
role='assistant',
|
||||||
content=[llm_entities.ContentElement.from_image_url(image_url)],
|
content=[llm_entities.ContentElement.from_image_url(image_url)],
|
||||||
is_final=is_final,
|
is_final=is_final,
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if chunk['event'] == 'error':
|
if chunk['event'] == 'error':
|
||||||
@@ -560,7 +532,9 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
|
|
||||||
query.session.using_conversation.uuid = chunk['conversation_id']
|
query.session.using_conversation.uuid = chunk['conversation_id']
|
||||||
|
|
||||||
async def _workflow_messages_chunk(self, query: core_entities.Query) -> typing.AsyncGenerator[llm_entities.MessageChunk, None]:
|
async def _workflow_messages_chunk(
|
||||||
|
self, query: core_entities.Query
|
||||||
|
) -> typing.AsyncGenerator[llm_entities.MessageChunk, None]:
|
||||||
"""调用工作流"""
|
"""调用工作流"""
|
||||||
|
|
||||||
if not query.session.using_conversation.uuid:
|
if not query.session.using_conversation.uuid:
|
||||||
@@ -618,6 +592,7 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
continue
|
continue
|
||||||
if '</think>' in chunk['data']['text'] and not think_end:
|
if '</think>' in chunk['data']['text'] and not think_end:
|
||||||
import re
|
import re
|
||||||
|
|
||||||
content = re.sub(r'^\n</think>', '', chunk['data']['text'])
|
content = re.sub(r'^\n</think>', '', chunk['data']['text'])
|
||||||
workflow_contents += content
|
workflow_contents += content
|
||||||
think_end = True
|
think_end = True
|
||||||
@@ -650,7 +625,6 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
|
|
||||||
yield msg
|
yield msg
|
||||||
|
|
||||||
|
|
||||||
if messsage_idx % 8 == 0 or is_final:
|
if messsage_idx % 8 == 0 or is_final:
|
||||||
yield llm_entities.MessageChunk(
|
yield llm_entities.MessageChunk(
|
||||||
role='assistant',
|
role='assistant',
|
||||||
@@ -694,4 +668,4 @@ class DifyServiceAPIRunner(runner.RequestRunner):
|
|||||||
else:
|
else:
|
||||||
raise errors.DifyAPIError(
|
raise errors.DifyAPIError(
|
||||||
f'不支持的 Dify 应用类型: {self.pipeline_config["ai"]["dify-service-api"]["app-type"]}'
|
f'不支持的 Dify 应用类型: {self.pipeline_config["ai"]["dify-service-api"]["app-type"]}'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -51,7 +51,6 @@
|
|||||||
"base-url": "https://api.dify.ai/v1",
|
"base-url": "https://api.dify.ai/v1",
|
||||||
"app-type": "chat",
|
"app-type": "chat",
|
||||||
"api-key": "your-api-key",
|
"api-key": "your-api-key",
|
||||||
"thinking-convert": "plain",
|
|
||||||
"timeout": 30
|
"timeout": 30
|
||||||
},
|
},
|
||||||
"dashscope-app-api": {
|
"dashscope-app-api": {
|
||||||
@@ -88,7 +87,7 @@
|
|||||||
"at-sender": true,
|
"at-sender": true,
|
||||||
"quote-origin": true,
|
"quote-origin": true,
|
||||||
"track-function-calls": false,
|
"track-function-calls": false,
|
||||||
"remove-think": true
|
"remove-think": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,28 +118,6 @@ stages:
|
|||||||
zh_Hans: API 密钥
|
zh_Hans: API 密钥
|
||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
- name: thinking-convert
|
|
||||||
label:
|
|
||||||
en_US: CoT Convert
|
|
||||||
zh_Hans: 思维链转换策略
|
|
||||||
type: select
|
|
||||||
required: true
|
|
||||||
default: plain
|
|
||||||
options:
|
|
||||||
- name: plain
|
|
||||||
label:
|
|
||||||
en_US: Convert to <think>...</think>
|
|
||||||
zh_Hans: 转换成 <think>...</think>
|
|
||||||
- name: original
|
|
||||||
label:
|
|
||||||
en_US: Original
|
|
||||||
zh_Hans: 原始
|
|
||||||
- name: remove
|
|
||||||
label:
|
|
||||||
en_US: Remove
|
|
||||||
zh_Hans: 移除
|
|
||||||
|
|
||||||
|
|
||||||
- name: dashscope-app-api
|
- name: dashscope-app-api
|
||||||
label:
|
label:
|
||||||
en_US: Aliyun Dashscope App API
|
en_US: Aliyun Dashscope App API
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ stages:
|
|||||||
en_US: Remove CoT
|
en_US: Remove CoT
|
||||||
zh_Hans: 删除思维链
|
zh_Hans: 删除思维链
|
||||||
description:
|
description:
|
||||||
en_US: If enabled, LangBot will remove the LLM thought content in response
|
en_US: 'If enabled, LangBot will remove the LLM thought content in response. Note: When using streaming response, removing CoT may cause the first token to wait for a long time.'
|
||||||
zh_Hans: 如果启用,将自动删除大模型回复中的模型思考内容
|
zh_Hans: '如果启用,将自动删除大模型回复中的模型思考内容。注意:当您使用流式响应时,删除思维链可能会导致首个 Token 的等待时间过长'
|
||||||
type: boolean
|
type: boolean
|
||||||
required: true
|
required: true
|
||||||
default: true
|
default: false
|
||||||
|
|||||||
Reference in New Issue
Block a user