mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-19 02:12:46 +08:00
✨ feat: 阿里云百炼应用工作流支持自定义动态变量 #552
This commit is contained in:
@@ -1,90 +0,0 @@
|
||||
'''
|
||||
Dify 调用 Stage
|
||||
'''
|
||||
import traceback
|
||||
from typing import Union, AsyncGenerator
|
||||
from ...context import PipelineContext
|
||||
from ..stage import Stage
|
||||
from astrbot.core.platform.astr_message_event import AstrMessageEvent
|
||||
from astrbot.core.message.message_event_result import MessageEventResult, ResultContentType
|
||||
from astrbot.core.message.components import Image
|
||||
from astrbot.core import logger
|
||||
from astrbot.core.utils.metrics import Metric
|
||||
from astrbot.core.provider.entites import ProviderRequest
|
||||
from astrbot.core.star.star_handler import star_handlers_registry, EventType
|
||||
|
||||
class DifyRequestSubStage(Stage):
|
||||
|
||||
async def initialize(self, ctx: PipelineContext) -> None:
|
||||
self.ctx = ctx
|
||||
|
||||
async def process(self, event: AstrMessageEvent) -> Union[None, AsyncGenerator[None, None]]:
|
||||
req: ProviderRequest = None
|
||||
|
||||
provider = self.ctx.plugin_manager.context.get_using_provider()
|
||||
|
||||
if not provider:
|
||||
return
|
||||
|
||||
if provider.meta().type != "dify":
|
||||
return
|
||||
|
||||
if event.get_extra("provider_request"):
|
||||
req = event.get_extra("provider_request")
|
||||
assert isinstance(req, ProviderRequest), "provider_request 必须是 ProviderRequest 类型。"
|
||||
else:
|
||||
req = ProviderRequest(prompt="", image_urls=[])
|
||||
if self.ctx.astrbot_config['provider_settings']['wake_prefix']:
|
||||
if not event.message_str.startswith(self.ctx.astrbot_config['provider_settings']['wake_prefix']):
|
||||
return
|
||||
req.prompt = event.message_str[len(self.ctx.astrbot_config['provider_settings']['wake_prefix']):]
|
||||
for comp in event.message_obj.message:
|
||||
if isinstance(comp, Image):
|
||||
image_url = comp.url if comp.url else comp.file
|
||||
req.image_urls.append(image_url)
|
||||
req.session_id = event.session_id
|
||||
event.set_extra("provider_request", req)
|
||||
|
||||
if not req.prompt:
|
||||
return
|
||||
|
||||
req.session_id = event.unified_msg_origin
|
||||
|
||||
# 执行请求 LLM 前事件钩子。
|
||||
# 装饰 system_prompt 等功能
|
||||
handlers = star_handlers_registry.get_handlers_by_event_type(EventType.OnLLMRequestEvent)
|
||||
for handler in handlers:
|
||||
try:
|
||||
await handler.handler(event, req)
|
||||
except BaseException:
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
try:
|
||||
logger.debug(f"Dify 请求 Payload: {req.__dict__}")
|
||||
llm_response = await provider.text_chat(**req.__dict__) # 请求 LLM
|
||||
await Metric.upload(llm_tick=1, model_name=provider.get_model(), provider_type=provider.meta().type)
|
||||
|
||||
# 执行 LLM 响应后的事件。
|
||||
handlers = star_handlers_registry.get_handlers_by_event_type(EventType.OnLLMResponseEvent)
|
||||
for handler in handlers:
|
||||
try:
|
||||
await handler.handler(event, llm_response)
|
||||
except BaseException:
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
if llm_response.role == 'assistant':
|
||||
# text completion
|
||||
event.set_result(MessageEventResult().message(llm_response.completion_text)
|
||||
.set_result_content_type(ResultContentType.LLM_RESULT))
|
||||
return
|
||||
elif llm_response.role == 'err':
|
||||
event.set_result(MessageEventResult().message(f"AstrBot 请求失败。\n错误信息: {llm_response.completion_text}"))
|
||||
return
|
||||
elif llm_response.role == 'tool':
|
||||
event.set_result(MessageEventResult().message(f"Dify 暂不支持工具调用。"))
|
||||
yield
|
||||
|
||||
except BaseException as e:
|
||||
logger.error(traceback.format_exc())
|
||||
event.set_result(MessageEventResult().message("AstrBot 请求 Dify 失败:" + str(e)))
|
||||
return
|
||||
@@ -54,7 +54,7 @@ class LLMRequestSubStage(Stage):
|
||||
conversation_id = await self.conv_manager.get_curr_conversation_id(event.unified_msg_origin)
|
||||
if not conversation_id:
|
||||
conversation_id = await self.conv_manager.new_conversation(event.unified_msg_origin)
|
||||
req.session_id = conversation_id
|
||||
req.session_id = event.unified_msg_origin
|
||||
conversation = await self.conv_manager.get_conversation(event.unified_msg_origin, conversation_id)
|
||||
req.conversation = conversation
|
||||
req.contexts = json.loads(conversation.history)
|
||||
@@ -154,6 +154,6 @@ class LLMRequestSubStage(Stage):
|
||||
contexts_to_save = list(filter(lambda item: '_no_save' not in item, contexts))
|
||||
await self.conv_manager.update_conversation(
|
||||
event.unified_msg_origin,
|
||||
req.session_id,
|
||||
req.conversation.cid,
|
||||
history=contexts_to_save
|
||||
)
|
||||
@@ -3,7 +3,6 @@ from ..stage import Stage, register_stage
|
||||
from ..context import PipelineContext
|
||||
from .method.llm_request import LLMRequestSubStage
|
||||
from .method.star_request import StarRequestSubStage
|
||||
from .method.dify_request import DifyRequestSubStage
|
||||
from astrbot.core.platform.astr_message_event import AstrMessageEvent
|
||||
from astrbot.core.star.star_handler import StarHandlerMetadata
|
||||
from astrbot.core.provider.entites import ProviderRequest
|
||||
@@ -21,9 +20,6 @@ class ProcessStage(Stage):
|
||||
|
||||
self.star_request_sub_stage = StarRequestSubStage()
|
||||
await self.star_request_sub_stage.initialize(ctx)
|
||||
|
||||
self.dify_request_sub_stage = DifyRequestSubStage()
|
||||
await self.dify_request_sub_stage.initialize(ctx)
|
||||
|
||||
async def process(self, event: AstrMessageEvent) -> Union[None, AsyncGenerator[None, None]]:
|
||||
'''处理事件
|
||||
@@ -59,10 +55,5 @@ class ProcessStage(Stage):
|
||||
logger.info("未找到可用的 LLM 提供商,请先前往配置服务提供商。")
|
||||
return
|
||||
|
||||
match provider.meta().type:
|
||||
case "dify":
|
||||
async for _ in self.dify_request_sub_stage.process(event):
|
||||
yield
|
||||
case _:
|
||||
async for _ in self.llm_request_sub_stage.process(event):
|
||||
yield
|
||||
async for _ in self.llm_request_sub_stage.process(event):
|
||||
yield
|
||||
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import functools
|
||||
from typing import List
|
||||
from .. import Provider, Personality
|
||||
from ..entites import LLMResponse
|
||||
@@ -47,6 +48,11 @@ class ProviderDashscope(ProviderOpenAIOfficial):
|
||||
system_prompt: str = None,
|
||||
**kwargs,
|
||||
) -> LLMResponse:
|
||||
|
||||
# 获得会话变量
|
||||
session_vars = sp.get("session_variables", {})
|
||||
session_var = session_vars.get(session_id, {})
|
||||
|
||||
if self.dashscope_app_type in ["agent", "dialog-workflow"]:
|
||||
# 支持多轮对话的
|
||||
new_record = {"role": "user", "content": prompt}
|
||||
@@ -60,27 +66,30 @@ class ProviderDashscope(ProviderOpenAIOfficial):
|
||||
if '_no_save' in part:
|
||||
del part['_no_save']
|
||||
# 调用阿里云百炼 API
|
||||
partial = functools.partial(
|
||||
Application.call,
|
||||
app_id = self.app_id,
|
||||
api_key = self.api_key,
|
||||
messages = context_query,
|
||||
biz_params = session_var or None,
|
||||
)
|
||||
response = await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
Application.call,
|
||||
self.app_id,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
self.api_key,
|
||||
context_query
|
||||
partial
|
||||
)
|
||||
else:
|
||||
# 不支持多轮对话的
|
||||
# 调用阿里云百炼 API
|
||||
partial = functools.partial(
|
||||
Application.call,
|
||||
app_id = self.app_id,
|
||||
promtp = prompt,
|
||||
api_key = self.api_key,
|
||||
biz_params=session_var or None,
|
||||
)
|
||||
response = await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
Application.call,
|
||||
self.app_id,
|
||||
prompt,
|
||||
None,
|
||||
None,
|
||||
self.api_key
|
||||
partial
|
||||
)
|
||||
|
||||
logger.debug(f"dashscope resp: {response}")
|
||||
|
||||
@@ -83,9 +83,6 @@ AstrBot 指令:
|
||||
/tool ls: 函数工具
|
||||
/key: API Key(op)
|
||||
/websearch: 网页搜索
|
||||
|
||||
[其他]
|
||||
/set 变量名 值: 为会话定义变量(Dify 工作流输入)
|
||||
{notice}"""
|
||||
|
||||
event.set_result(MessageEventResult().message(msg).use_t2i(False))
|
||||
|
||||
Reference in New Issue
Block a user