From f28adaaff87ccd16e8e57b52021ade77a5a3ad66 Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Mon, 6 Oct 2025 21:07:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=E4=BC=98=E5=8C=96=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=B0=83=E7=94=A8=E8=BE=93=E5=87=BA=E5=A4=84=E7=90=86?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=E5=85=BC=E5=AE=B9=E6=80=A7=E5=92=8C?= =?UTF-8?q?=E7=A8=B3=E5=AE=9A=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 chat_agent 函数中,确保工具调用输出为字符串类型,避免 SQLite 不支持列表类型的问题 - 更新 load_chat_model 函数,新增 stream_usage 参数以支持流式使用 - 移除不必要的代码,简化 utils.py 文件,提升可读性 - 优化 AgentStatsComponent.vue,移除冗余样式,提升性能和用户体验 --- server/routers/chat_router.py | 8 ++- src/agents/common/models.py | 4 ++ src/agents/common/utils.py | 63 ------------------- .../dashboard/AgentStatsComponent.vue | 20 ------ 4 files changed, 11 insertions(+), 84 deletions(-) diff --git a/server/routers/chat_router.py b/server/routers/chat_router.py index 8978a81a..95ce2ebb 100644 --- a/server/routers/chat_router.py +++ b/server/routers/chat_router.py @@ -211,10 +211,16 @@ async def chat_agent( name = msg_dict.get("name", "") if tool_call_id: + # 确保tool_output是字符串类型,避免SQLite不支持列表类型 + if isinstance(content, list): + tool_output = json.dumps(content) if content else "" + else: + tool_output = str(content) + # 通过 LangGraph tool_call_id 精确匹配并更新 updated_tc = conv_mgr.update_tool_call_output( langgraph_tool_call_id=tool_call_id, - tool_output=content, + tool_output=tool_output, status="success", ) if updated_tc: diff --git a/src/agents/common/models.py b/src/agents/common/models.py index befe1329..bbe078f2 100644 --- a/src/agents/common/models.py +++ b/src/agents/common/models.py @@ -26,6 +26,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel: model=model_name, api_key=SecretStr(api_key), base_url=base_url, + stream_usage=True, ) model_info = config.model_names.get(provider, {}) @@ -40,6 +41,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel: api_key=SecretStr(api_key), base_url=base_url, api_base=base_url, + stream_usage=True, ) elif provider == "together": @@ -49,6 +51,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel: model=model, api_key=SecretStr(api_key), base_url=base_url, + stream_usage=True, ) else: @@ -59,6 +62,7 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel: model=model, api_key=SecretStr(api_key), base_url=base_url, + stream_usage=True, ) except Exception as e: raise ValueError(f"Model provider {provider} load failed, {e} \n {traceback.format_exc()}") diff --git a/src/agents/common/utils.py b/src/agents/common/utils.py index 84dc5077..ebbcbfdb 100644 --- a/src/agents/common/utils.py +++ b/src/agents/common/utils.py @@ -1,71 +1,8 @@ -import os -import traceback from datetime import UTC, datetime -from langchain_core.language_models import BaseChatModel from langchain_core.messages import AIMessageChunk, ToolMessage from langchain_core.runnables import RunnableConfig -from pydantic import SecretStr - -from src import config from src.agents.common.base import BaseAgent -from src.models import get_custom_model -from src.utils import get_docker_safe_url - - -def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel: - """ - Load a chat model from a fully specified name. - """ - provider, model = fully_specified_name.split("/", maxsplit=1) - - if provider == "custom": - from langchain_openai import ChatOpenAI - - model_info = get_custom_model(model) - api_key = model_info.get("api_key") or "custom_model" - base_url = get_docker_safe_url(model_info["api_base"]) - model_name = model_info.get("name") or "custom_model" - return ChatOpenAI( - model=model_name, - api_key=SecretStr(api_key), - base_url=base_url, - ) - - model_info = config.model_names.get(provider, {}) - api_key = os.getenv(model_info["env"][0], model_info["env"][0]) - base_url = get_docker_safe_url(model_info["base_url"]) - - if provider in ["deepseek", "dashscope"]: - from langchain_deepseek import ChatDeepSeek - - return ChatDeepSeek( - model=model, - api_key=SecretStr(api_key), - base_url=base_url, - api_base=base_url, - ) - - elif provider == "together": - from langchain_together import ChatTogether - - return ChatTogether( - model=model, - api_key=SecretStr(api_key), - base_url=base_url, - ) - - else: - try: # 其他模型,默认使用OpenAIBase, like openai, zhipuai - from langchain_openai import ChatOpenAI - - return ChatOpenAI( - model=model, - api_key=SecretStr(api_key), - base_url=base_url, - ) - except Exception as e: - raise ValueError(f"Model provider {provider} load failed, {e} \n {traceback.format_exc()}") async def agent_cli(agent: BaseAgent, config: RunnableConfig | None = None): diff --git a/web/src/components/dashboard/AgentStatsComponent.vue b/web/src/components/dashboard/AgentStatsComponent.vue index 49947619..6254de86 100644 --- a/web/src/components/dashboard/AgentStatsComponent.vue +++ b/web/src/components/dashboard/AgentStatsComponent.vue @@ -63,8 +63,6 @@ :data-source="topPerformers" size="small" :pagination="false" - :row-class-name="getRowClassName" - :scroll="{ y: 240 }" >