feat(chat): 优化工具调用输出处理,确保兼容性和稳定性

- 在 chat_agent 函数中,确保工具调用输出为字符串类型,避免 SQLite 不支持列表类型的问题
- 更新 load_chat_model 函数,新增 stream_usage 参数以支持流式使用
- 移除不必要的代码,简化 utils.py 文件,提升可读性
- 优化 AgentStatsComponent.vue,移除冗余样式,提升性能和用户体验
This commit is contained in:
Wenjie Zhang 2025-10-06 21:07:33 +08:00
parent 52ce5f51bd
commit f28adaaff8
4 changed files with 11 additions and 84 deletions

View File

@ -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:

View File

@ -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()}")

View File

@ -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):

View File

@ -63,8 +63,6 @@
:data-source="topPerformers"
size="small"
:pagination="false"
:row-class-name="getRowClassName"
:scroll="{ y: 240 }"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.key === 'rank'">
@ -190,12 +188,6 @@ const getScoreColor = (score) => {
return '#a3d8e8'
}
const getRowClassName = (record, index) => {
if (index === 0) return 'top-rank first'
if (index === 1) return 'top-rank second'
if (index === 2) return 'top-rank third'
return ''
}
//
const initConversationToolChart = () => {
@ -396,18 +388,6 @@ defineExpose({
}
}
//
:deep(.ant-table-tbody > tr.top-rank.first) {
background: linear-gradient(90deg, rgba(255, 215, 0, 0.1) 0%, transparent 100%);
}
:deep(.ant-table-tbody > tr.top-rank.second) {
background: linear-gradient(90deg, rgba(192, 192, 192, 0.1) 0%, transparent 100%);
}
:deep(.ant-table-tbody > tr.top-rank.third) {
background: linear-gradient(90deg, rgba(205, 127, 50, 0.1) 0%, transparent 100%);
}
:deep(.ant-progress-bg) {
transition: all 0.3s ease;