refactor: 重构智能体管理和基础代理类
- 将 AgentManager 类中的方法重命名为更具描述性的名称,并优化了代理的注册和实例化逻辑。 - 添加了线程ID和用户ID字段到基础代理类,并改进了获取历史消息的逻辑,增加了错误处理。 - 在 ChatbotAgent 中确保创建图时设置 checkpointer,并处理可能的异常。
This commit is contained in:
parent
44fad724bf
commit
6475170c4b
@ -31,7 +31,7 @@ async def get_default_agent(current_user: User = Depends(get_required_user)):
|
|||||||
default_agent_id = config.default_agent_id
|
default_agent_id = config.default_agent_id
|
||||||
# 如果没有设置默认智能体,尝试获取第一个可用的智能体
|
# 如果没有设置默认智能体,尝试获取第一个可用的智能体
|
||||||
if not default_agent_id:
|
if not default_agent_id:
|
||||||
agents = [agent.get_info() for agent in agent_manager.agents.values()]
|
agents = await agent_manager.get_agents_info()
|
||||||
if agents:
|
if agents:
|
||||||
default_agent_id = agents[0].get("name", "")
|
default_agent_id = agents[0].get("name", "")
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ async def set_default_agent(agent_id: str = Body(..., embed=True), current_user
|
|||||||
"""设置默认智能体ID (仅管理员)"""
|
"""设置默认智能体ID (仅管理员)"""
|
||||||
try:
|
try:
|
||||||
# 验证智能体是否存在
|
# 验证智能体是否存在
|
||||||
agents = [agent.get_info() for agent in agent_manager.agents.values()]
|
agents = await agent_manager.get_agents_info()
|
||||||
agent_ids = [agent.get("name", "") for agent in agents]
|
agent_ids = [agent.get("name", "") for agent in agents]
|
||||||
|
|
||||||
if agent_id not in agent_ids:
|
if agent_id not in agent_ids:
|
||||||
@ -161,7 +161,8 @@ async def call(query: str = Body(...), meta: dict = Body(None), current_user: Us
|
|||||||
@chat.get("/agent")
|
@chat.get("/agent")
|
||||||
async def get_agent(current_user: User = Depends(get_required_user)):
|
async def get_agent(current_user: User = Depends(get_required_user)):
|
||||||
"""获取所有可用智能体(需要登录)"""
|
"""获取所有可用智能体(需要登录)"""
|
||||||
agents = [agent.get_info() for agent in agent_manager.agents.values()]
|
agents = await agent_manager.get_agents_info()
|
||||||
|
# logger.debug(f"agents: {agents}")
|
||||||
return {"agents": agents}
|
return {"agents": agents}
|
||||||
|
|
||||||
@chat.post("/agent/{agent_name}")
|
@chat.post("/agent/{agent_name}")
|
||||||
@ -195,7 +196,7 @@ async def chat_agent(agent_name: str,
|
|||||||
yield make_chunk(status="init", meta=meta, msg=HumanMessage(content=query).model_dump())
|
yield make_chunk(status="init", meta=meta, msg=HumanMessage(content=query).model_dump())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
agent = agent_manager.get_runnable_agent(agent_name)
|
agent = agent_manager.get_agent(agent_name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting agent {agent_name}: {e}, {traceback.format_exc()}")
|
logger.error(f"Error getting agent {agent_name}: {e}, {traceback.format_exc()}")
|
||||||
yield make_chunk(message=f"Error getting agent {agent_name}: {e}", status="error")
|
yield make_chunk(message=f"Error getting agent {agent_name}: {e}", status="error")
|
||||||
@ -284,7 +285,7 @@ async def get_agent_history(
|
|||||||
"""获取智能体历史消息(需要登录)"""
|
"""获取智能体历史消息(需要登录)"""
|
||||||
try:
|
try:
|
||||||
# 获取Agent实例和配置类
|
# 获取Agent实例和配置类
|
||||||
agent = agent_manager.get_runnable_agent(agent_name)
|
agent = agent_manager.get_agent(agent_name)
|
||||||
if not agent:
|
if not agent:
|
||||||
raise HTTPException(status_code=404, detail=f"智能体 {agent_name} 不存在")
|
raise HTTPException(status_code=404, detail=f"智能体 {agent_name} 不存在")
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +1,42 @@
|
|||||||
|
import asyncio
|
||||||
from src.agents.chatbot import ChatbotAgent
|
from src.agents.chatbot import ChatbotAgent
|
||||||
from src.agents.react import ReActAgent
|
from src.agents.react import ReActAgent
|
||||||
|
|
||||||
class AgentManager:
|
class AgentManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.agents = {}
|
self._classes = {}
|
||||||
self.agent_instances = {} # 存储已创建的 agent 实例
|
self._instances = {} # 存储已创建的 agent 实例
|
||||||
|
|
||||||
def add_agent(self, agent_id, agent_class):
|
def register_agent(self, agent_id, agent_class):
|
||||||
self.agents[agent_id] = agent_class
|
self._classes[agent_id] = agent_class
|
||||||
|
|
||||||
def get_runnable_agent(self, agent_id, **kwargs):
|
def init_all_agents(self):
|
||||||
|
for agent_id, agent_class in self._classes.items():
|
||||||
|
self.get_agent(agent_id)
|
||||||
|
|
||||||
|
def get_agent(self, agent_id, **kwargs):
|
||||||
# 检查是否已经创建了该 agent 的实例
|
# 检查是否已经创建了该 agent 的实例
|
||||||
if agent_id not in self.agent_instances:
|
if agent_id not in self._instances:
|
||||||
agent_class = self.get_agent(agent_id)
|
agent_class = self._classes[agent_id]
|
||||||
self.agent_instances[agent_id] = agent_class()
|
self._instances[agent_id] = agent_class()
|
||||||
return self.agent_instances[agent_id]
|
|
||||||
|
|
||||||
def get_agent(self, agent_id):
|
return self._instances[agent_id]
|
||||||
return self.agents[agent_id]
|
|
||||||
|
def get_agents(self):
|
||||||
|
return list(self._instances.values())
|
||||||
|
|
||||||
|
async def get_agents_info(self):
|
||||||
|
agents = self.get_agents()
|
||||||
|
return await asyncio.gather(*[a.get_info() for a in agents])
|
||||||
|
|
||||||
|
|
||||||
agent_manager = AgentManager()
|
agent_manager = AgentManager()
|
||||||
agent_manager.add_agent("chatbot", ChatbotAgent)
|
agent_manager.register_agent("chatbot", ChatbotAgent)
|
||||||
# agent_manager.add_agent("react", ReActAgent) # 暂时屏蔽 ReActAgent
|
agent_manager.register_agent("react", ReActAgent) # 暂时屏蔽 ReActAgent
|
||||||
|
agent_manager.init_all_agents()
|
||||||
|
|
||||||
__all__ = ["agent_manager"]
|
__all__ = ["agent_manager"]
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
agent = agent_manager.get_agent("chatbot")
|
pass
|
||||||
conf = agent_manager.get_configuration("chatbot")
|
|
||||||
agent_info = {
|
|
||||||
"name": agent.name,
|
|
||||||
"description": agent.description,
|
|
||||||
}
|
|
||||||
print(agent_info)
|
|
||||||
@ -15,24 +15,6 @@ class ChatbotConfiguration(Configuration):
|
|||||||
configurable 为 False 的配置项不能被用户配置,只能由开发者预设。
|
configurable 为 False 的配置项不能被用户配置,只能由开发者预设。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
thread_id: str = field(
|
|
||||||
default_factory=lambda: str(uuid.uuid4()),
|
|
||||||
metadata={
|
|
||||||
"name": "线程ID",
|
|
||||||
"configurable": False,
|
|
||||||
"description": "用来描述智能体的角色和行为"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
user_id: str = field(
|
|
||||||
default_factory=lambda: str(uuid.uuid4()),
|
|
||||||
metadata={
|
|
||||||
"name": "用户ID",
|
|
||||||
"configurable": False,
|
|
||||||
"description": "用来描述智能体的角色和行为"
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
system_prompt: str = field(
|
system_prompt: str = field(
|
||||||
default="You are a helpful assistant.",
|
default="You are a helpful assistant.",
|
||||||
metadata={
|
metadata={
|
||||||
|
|||||||
@ -75,11 +75,18 @@ class ChatbotAgent(BaseAgent):
|
|||||||
workflow.add_edge("tools", "chatbot")
|
workflow.add_edge("tools", "chatbot")
|
||||||
workflow.add_edge("chatbot", END)
|
workflow.add_edge("chatbot", END)
|
||||||
|
|
||||||
# 创建数据库连接
|
# 创建数据库连接并确保设置 checkpointer
|
||||||
sqlite_checkpointer = AsyncSqliteSaver(await self.get_async_conn())
|
try:
|
||||||
graph = workflow.compile(checkpointer=sqlite_checkpointer)
|
sqlite_checkpointer = AsyncSqliteSaver(await self.get_async_conn())
|
||||||
self.graph = graph
|
graph = workflow.compile(checkpointer=sqlite_checkpointer)
|
||||||
return graph
|
self.graph = graph
|
||||||
|
return graph
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"构建 Graph 设置 checkpointer 时出错: {e}")
|
||||||
|
# 即使出错也返回一个可用的图实例,只是无法保存历史
|
||||||
|
graph = workflow.compile()
|
||||||
|
self.graph = graph
|
||||||
|
return graph
|
||||||
|
|
||||||
async def get_async_conn(self) -> aiosqlite.Connection:
|
async def get_async_conn(self) -> aiosqlite.Connection:
|
||||||
"""获取异步数据库连接"""
|
"""获取异步数据库连接"""
|
||||||
|
|||||||
@ -1,36 +1,12 @@
|
|||||||
from dataclasses import dataclass, field
|
|
||||||
from datetime import datetime, timezone
|
|
||||||
|
|
||||||
from langchain_core.tools import tool
|
from dataclasses import dataclass
|
||||||
from langchain_openai import ChatOpenAI
|
|
||||||
|
|
||||||
from src.agents.registry import Configuration
|
from src.agents.registry import Configuration
|
||||||
|
|
||||||
def get_default_requirements():
|
|
||||||
return ["TAVILY_API_KEY"]
|
|
||||||
|
|
||||||
@tool
|
|
||||||
def multiply(first_int: int, second_int: int) -> int:
|
|
||||||
"""Multiply two integers together."""
|
|
||||||
return first_int * second_int
|
|
||||||
|
|
||||||
@dataclass(kw_only=True)
|
@dataclass(kw_only=True)
|
||||||
class ReActConfiguration(Configuration):
|
class ReActConfiguration(Configuration):
|
||||||
"""ReAct 的配置"""
|
"""配置"""
|
||||||
|
|
||||||
system_prompt: str = field(
|
pass
|
||||||
default=f"You are a helpful assistant. Now is {datetime.now(tz=timezone.utc).isoformat()}",
|
|
||||||
metadata={
|
|
||||||
"description": "The system prompt to use for the agent's interactions. "
|
|
||||||
"This prompt sets the context and behavior for the agent."
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
model: str = field(
|
|
||||||
default="zhipu/glm-4-plus",
|
|
||||||
metadata={
|
|
||||||
"description": "The name of the language model to use for the agent's main interactions. "
|
|
||||||
"Should be in the form: provider/model-name."
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|||||||
@ -2,28 +2,22 @@ import asyncio
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
from src.utils import logger
|
||||||
from src.agents.registry import BaseAgent
|
from src.agents.registry import BaseAgent
|
||||||
from src.agents.react.configuration import ReActConfiguration
|
from src.agents.react.configuration import ReActConfiguration
|
||||||
|
|
||||||
class ReActAgent(BaseAgent):
|
class ReActAgent(BaseAgent):
|
||||||
name = "react"
|
name = "react"
|
||||||
description = "A react agent that can answer questions and help with tasks."
|
description = "A react agent that can answer questions and help with tasks."
|
||||||
|
config_schema = ReActConfiguration
|
||||||
|
|
||||||
def get_graph(self, **kwargs):
|
async def get_graph(self, **kwargs):
|
||||||
"""构建图"""
|
|
||||||
from .workflows import graph
|
from .workflows import graph
|
||||||
return graph
|
return graph
|
||||||
|
|
||||||
def main():
|
|
||||||
agent = ReActAgent(ReActConfiguration())
|
|
||||||
|
|
||||||
thread_id = str(uuid.uuid4())
|
|
||||||
config = {"configurable": {"thread_id": thread_id}}
|
|
||||||
|
|
||||||
from src.agents.utils import agent_cli
|
|
||||||
asyncio.run(agent_cli(agent, config))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
pass
|
||||||
# asyncio.run(main())
|
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from langchain_openai import ChatOpenAI
|
from langchain_openai import ChatOpenAI
|
||||||
|
from langgraph.checkpoint.memory import InMemorySaver
|
||||||
from src import graph_base
|
|
||||||
|
|
||||||
model = ChatOpenAI(model="glm-4-plus",
|
model = ChatOpenAI(model="glm-4-plus",
|
||||||
api_key=os.getenv("ZHIPUAI_API_KEY"),
|
api_key=os.getenv("ZHIPUAI_API_KEY"),
|
||||||
@ -23,4 +22,4 @@ tools = []
|
|||||||
|
|
||||||
from langgraph.prebuilt import create_react_agent
|
from langgraph.prebuilt import create_react_agent
|
||||||
|
|
||||||
graph = create_react_agent(model, tools=tools)
|
graph = create_react_agent(model, tools=tools, checkpointer=InMemorySaver())
|
||||||
|
|||||||
@ -2,6 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
|
import uuid
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Type, Annotated, Optional, TypedDict
|
from typing import Type, Annotated, Optional, TypedDict
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
@ -139,6 +140,23 @@ class Configuration(dict):
|
|||||||
return confs
|
return confs
|
||||||
|
|
||||||
|
|
||||||
|
thread_id: str = field(
|
||||||
|
default_factory=lambda: str(uuid.uuid4()),
|
||||||
|
metadata={
|
||||||
|
"name": "线程ID",
|
||||||
|
"configurable": False,
|
||||||
|
"description": "用来描述智能体的角色和行为"
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
user_id: str = field(
|
||||||
|
default_factory=lambda: str(uuid.uuid4()),
|
||||||
|
metadata={
|
||||||
|
"name": "用户ID",
|
||||||
|
"configurable": False,
|
||||||
|
"description": "用来描述智能体的角色和行为"
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
class BaseAgent():
|
class BaseAgent():
|
||||||
|
|
||||||
@ -146,66 +164,85 @@ class BaseAgent():
|
|||||||
定义一个基础 Agent 供 各类 graph 继承
|
定义一个基础 Agent 供 各类 graph 继承
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name: str = field(default="base_agent")
|
name = "base_agent"
|
||||||
description: str = field(default="base_agent")
|
description = "base_agent"
|
||||||
config_schema: Configuration = Configuration
|
config_schema: Configuration = Configuration
|
||||||
requirements: list[str]
|
requirements: list[str]
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
self.check_requirements()
|
self.check_requirements()
|
||||||
|
|
||||||
@classmethod
|
async def get_info(self):
|
||||||
def get_info(cls):
|
|
||||||
return {
|
return {
|
||||||
"name": cls.name,
|
"name": self.name if hasattr(self, "name") else "Unknown",
|
||||||
"description": cls.description,
|
"description": self.description if hasattr(self, "description") else "Unknown",
|
||||||
"config_schema": cls.config_schema.to_dict(),
|
"config_schema": self.config_schema.to_dict(),
|
||||||
"requirements": cls.requirements if hasattr(cls, "requirements") else [],
|
"requirements": self.requirements if hasattr(self, "requirements") else [],
|
||||||
"all_tools": cls.all_tools if hasattr(cls, "all_tools") else [],
|
"all_tools": self.all_tools if hasattr(self, "all_tools") else [],
|
||||||
|
"has_checkpointer": await self.check_checkpointer(),
|
||||||
|
"met_requirements": self.check_requirements(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def check_requirements(self):
|
def check_requirements(self):
|
||||||
if not hasattr(self, "requirements") or not self.requirements:
|
if not hasattr(self, "requirements") or not self.requirements:
|
||||||
return
|
return True
|
||||||
for requirement in self.requirements:
|
for requirement in self.requirements:
|
||||||
if requirement not in os.environ:
|
if requirement not in os.environ:
|
||||||
raise ValueError(f"没有配置{requirement} 环境变量,请在 src/.env 文件中配置,并重新启动服务")
|
raise ValueError(f"没有配置{requirement} 环境变量,请在 src/.env 文件中配置,并重新启动服务")
|
||||||
|
return True
|
||||||
|
|
||||||
async def stream_values(self, messages: list[str], config_schema: RunnableConfig = None, **kwargs):
|
async def stream_values(self, messages: list[str], config_schema: RunnableConfig = None, **kwargs):
|
||||||
graph = await self.get_graph(config_schema=config_schema, **kwargs)
|
graph = await self.get_graph()
|
||||||
logger.debug(f"stream_values: {config_schema}")
|
logger.debug(f"stream_values: {config_schema}")
|
||||||
for event in graph.astream({"messages": messages}, stream_mode="values", config=config_schema):
|
for event in graph.astream({"messages": messages}, stream_mode="values", config=config_schema):
|
||||||
yield event["messages"]
|
yield event["messages"]
|
||||||
|
|
||||||
async def stream_messages(self, messages: list[str], config_schema: RunnableConfig = None, **kwargs):
|
async def stream_messages(self, messages: list[str], config_schema: RunnableConfig = None, **kwargs):
|
||||||
graph = await self.get_graph(config_schema=config_schema, **kwargs)
|
graph = await self.get_graph()
|
||||||
logger.debug(f"stream_messages: {config_schema}")
|
logger.debug(f"stream_messages: {config_schema}")
|
||||||
|
|
||||||
async for msg, metadata in graph.astream({"messages": messages}, stream_mode="messages", config=config_schema):
|
async for msg, metadata in graph.astream({"messages": messages}, stream_mode="messages", config=config_schema):
|
||||||
yield msg, metadata
|
yield msg, metadata
|
||||||
|
|
||||||
|
async def check_checkpointer(self):
|
||||||
|
app = await self.get_graph()
|
||||||
|
if not hasattr(app, "checkpointer") or app.checkpointer is None:
|
||||||
|
logger.warning(f"智能体 {self.name} 的 Graph 未配置 checkpointer,无法获取历史记录")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
async def get_history(self, user_id, thread_id) -> list[dict]:
|
async def get_history(self, user_id, thread_id) -> list[dict]:
|
||||||
"""获取历史消息"""
|
"""获取历史消息"""
|
||||||
# 获取LangGraph应用实例
|
try:
|
||||||
app = await self.get_graph()
|
app = await self.get_graph()
|
||||||
# 构建配置信息
|
|
||||||
config = {"configurable": {"thread_id": thread_id, "user_id": user_id}}
|
|
||||||
# 获取状态
|
|
||||||
state = await app.aget_state(config)
|
|
||||||
|
|
||||||
result = []
|
if not await self.check_checkpointer():
|
||||||
if state:
|
return []
|
||||||
messages = state.values.get('messages', [])
|
|
||||||
for msg in messages:
|
|
||||||
if hasattr(msg, 'model_dump'):
|
|
||||||
msg_dict = msg.model_dump() # 转换成字典
|
|
||||||
else:
|
|
||||||
# 如果消息没有model_dump方法,尝试转成dict
|
|
||||||
msg_dict = dict(msg) if hasattr(msg, '__dict__') else {"content": str(msg)}
|
|
||||||
result.append(msg_dict)
|
|
||||||
|
|
||||||
return result
|
config = {"configurable": {"thread_id": thread_id, "user_id": user_id}}
|
||||||
|
state = await app.aget_state(config)
|
||||||
|
|
||||||
|
result = []
|
||||||
|
if state:
|
||||||
|
messages = state.values.get('messages', [])
|
||||||
|
for msg in messages:
|
||||||
|
if hasattr(msg, 'model_dump'):
|
||||||
|
msg_dict = msg.model_dump() # 转换成字典
|
||||||
|
else:
|
||||||
|
msg_dict = dict(msg) if hasattr(msg, '__dict__') else {"content": str(msg)}
|
||||||
|
result.append(msg_dict)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"获取智能体 {self.name} 历史消息出错: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_graph(self, **kwargs) -> CompiledStateGraph:
|
async def get_graph(self, **kwargs) -> CompiledStateGraph:
|
||||||
|
"""
|
||||||
|
获取并编译对话图实例。
|
||||||
|
必须确保在编译时设置 checkpointer,否则将无法获取历史记录。
|
||||||
|
例如: graph = workflow.compile(checkpointer=sqlite_checkpointer)
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<span>正在加载历史记录...</span>
|
<span>正在加载历史记录...</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="convs.length === 0" class="chat-examples">
|
<div v-else-if="convs.length === 0 && !onGoingConv.messages.length" class="chat-examples">
|
||||||
<h1>{{ currentAgent ? currentAgent.name : '请选择一个智能体开始对话' }}</h1>
|
<h1>{{ currentAgent ? currentAgent.name : '请选择一个智能体开始对话' }}</h1>
|
||||||
<p>{{ currentAgent ? currentAgent.description : '不同的智能体有不同的专长和能力' }}</p>
|
<p>{{ currentAgent ? currentAgent.description : '不同的智能体有不同的专长和能力' }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -35,7 +35,7 @@ import { useRouter } from 'vue-router';
|
|||||||
import { useUserStore } from '@/stores/user';
|
import { useUserStore } from '@/stores/user';
|
||||||
import { UserOutlined, LogoutOutlined } from '@ant-design/icons-vue';
|
import { UserOutlined, LogoutOutlined } from '@ant-design/icons-vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { CircleUser, LogOut } from 'lucide-vue-next';
|
import { CircleUser, UserRoundCheck } from 'lucide-vue-next';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|||||||
@ -59,14 +59,14 @@
|
|||||||
<div class="sidebar" :class="{ 'is-open': state.agentSiderbarConfigOpen }">
|
<div class="sidebar" :class="{ 'is-open': state.agentSiderbarConfigOpen }">
|
||||||
<div class="agent-info">
|
<div class="agent-info">
|
||||||
<h3 @click="toggleDebugMode">描述</h3>
|
<h3 @click="toggleDebugMode">描述</h3>
|
||||||
<p>{{ agents[selectedAgentId]?.description }}</p>
|
<p>{{ selectedAgent.description }}</p>
|
||||||
|
<pre v-if="state.debug_mode">{{ selectedAgent }}</pre>
|
||||||
|
|
||||||
<div v-if="selectedAgentId && configSchema" class="config-modal-content">
|
<div v-if="selectedAgentId && configSchema" class="config-modal-content">
|
||||||
<!-- 配置表单 -->
|
<!-- 配置表单 -->
|
||||||
<a-form :model="agentConfig" layout="vertical">
|
<a-form :model="agentConfig" layout="vertical">
|
||||||
<div class="empty-config" v-if="state.isEmptyConfig">
|
<a-alert v-if="state.isEmptyConfig" type="warning" message="该智能体没有配置项" show-icon/>
|
||||||
<a-alert type="warning" message="该智能体没有配置项" show-icon/>
|
<a-alert v-if="!selectedAgent.has_checkpointer" type="error" message="该智能体没有配置 Checkpointer,功能无法正常使用,参考:https://langchain-ai.github.io/langgraph/concepts/persistence/" show-icon/>
|
||||||
</div>
|
|
||||||
<!-- 统一显示所有配置项 -->
|
<!-- 统一显示所有配置项 -->
|
||||||
<template v-for="(value, key) in configurableItems" :key="key">
|
<template v-for="(value, key) in configurableItems" :key="key">
|
||||||
<a-form-item
|
<a-form-item
|
||||||
@ -185,7 +185,9 @@ const state = reactive({
|
|||||||
Object.keys(configurableItems.value).length === 0
|
Object.keys(configurableItems.value).length === 0
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
const configSchema = computed(() => agents.value[selectedAgentId.value]?.config_schema || {});
|
|
||||||
|
const selectedAgent = computed(() => agents.value[selectedAgentId.value] || {});
|
||||||
|
const configSchema = computed(() => selectedAgent.value.config_schema || {});
|
||||||
const configurableItems = computed(() => configSchema.value.configurable_items || {});
|
const configurableItems = computed(() => configSchema.value.configurable_items || {});
|
||||||
|
|
||||||
// 配置状态
|
// 配置状态
|
||||||
@ -617,6 +619,11 @@ const toggleSidebar = () => {
|
|||||||
.config-modal-content {
|
.config-modal-content {
|
||||||
max-height: 70vh;
|
max-height: 70vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
user-select: text;
|
||||||
|
|
||||||
|
div[role="alert"] {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user