fix: 修复硅基流动接口与 langchain stream event v3 不兼容的问题

This commit is contained in:
Wenjie Zhang 2026-06-09 00:05:47 +08:00
parent 7f387fd6e7
commit e37bd7c808
9 changed files with 26 additions and 21 deletions

View File

@ -6,6 +6,10 @@ from yuxi.utils import get_docker_safe_url
from yuxi.utils.logging_config import logger
def _requires_non_streaming_tool_calls(provider_id: str, model_id: str) -> bool:
return provider_id.startswith("siliconflow")
def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
if not fully_specified_name:
raise ValueError("model spec 不能为空")
@ -47,10 +51,14 @@ def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
from langchain_openai import ChatOpenAI
openai_kwargs = dict(kwargs)
if _requires_non_streaming_tool_calls(info.provider_id, info.model_id):
openai_kwargs.setdefault("disable_streaming", "tool_calling")
return ChatOpenAI(
model=info.model_id,
api_key=SecretStr(api_key),
base_url=base_url,
stream_usage=True,
**kwargs,
**openai_kwargs,
)

View File

@ -24,12 +24,6 @@ BUILTIN_PROVIDERS: list[dict[str, Any]] = [
# "api_key_env": "GEMINI_API_KEY",
# "models_endpoint": "https://generativelanguage.googleapis.com/v1beta/models",
# },
# {
# "provider_id": "lmstudio",
# "display_name": "LM Studio",
# "base_url": "http://localhost:1234/v1",
# "models_endpoint": "http://localhost:1234/v1/models",
# },
{
"provider_id": "deepseek",
"display_name": "DeepSeek",

View File

@ -33,7 +33,7 @@ class ModelInfo:
# 运行时配置
api_key: str
base_url: str
provider_type: str # openai / anthropic / gemini / openrouter / lmstudio
provider_type: str # openai / anthropic / gemini / openrouter
# 可选配置
headers: dict[str, str] = field(default_factory=dict)

View File

@ -20,7 +20,7 @@ from yuxi.storage.postgres.models_business import ModelProvider
VALID_MODEL_TYPES = {"chat", "embedding", "rerank"}
VALID_MODEL_SOURCES = {"manual", "remote"}
VALID_PROVIDER_TYPES = {"openai", "anthropic", "gemini", "openrouter", "lmstudio"}
VALID_PROVIDER_TYPES = {"openai", "anthropic", "gemini", "openrouter"}
_PROVIDER_ID_RE = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9_-]{1,99}$")

View File

@ -231,7 +231,7 @@ def _message_chunk_yuxi_events(
"type": "tool_call_delta",
"message_id": message_id,
"tool_call_id": tool_call_chunk.get("id"),
"name": tool_call_chunk.get("name"),
"name": tool_call_chunk.get("name") or None,
"args_delta": args_delta,
"index": tool_call_chunk.get("index") if tool_call_chunk.get("index") is not None else 0,
**route,
@ -377,7 +377,7 @@ async def _save_ai_message(
for tc in tool_calls_data:
await conv_repo.add_tool_call(
message_id=ai_msg.id,
tool_name=tc.get("name", "unknown"),
tool_name=tc.get("name") or "unknown",
tool_input=tc.get("args", {}),
status="pending",
langgraph_tool_call_id=tc.get("id"),

View File

@ -57,6 +57,7 @@
- 优化智能体对话页细节:状态面板隐藏空 section待办名称限制为 20 个中文汉字以内,模型选择器展示供应商名称,并收紧附件状态标签与文件编辑浮动操作样式。
- 标准化 Agent run/SSE 执行链路run 创建时持久化输入消息并提交后入队worker 统一写入 Redis Stream envelopeSSE 输出 `event/data/id`、心跳注释、`Last-Event-ID` 回放和终止 `end` 事件;前端强制使用 run API 并支持 ask_user_question 中断后以 resume run 恢复;事件 envelope 构造收敛到统一 helper前端优先使用 envelope 一级 `thread_id` 路由。
- Agent run SSE 新增 `verbose=false` 精简模式:默认仍返回完整事件载荷;精简模式仅在 SSE 输出前重建最小 payload跳过 `metadata` 和空 `yuxi.agent_state`,将同一 data 内的 `request_id` 外提为单个字段,移除 chunk 中重复的 `meta`、`metadata`、`thread_id`、`response`、空 `namespace` 和图片 base64 等调试字段,保留消息增量、工具调用、工具结果、非空 Agent state、终止状态和 SSE 游标,前端订阅默认使用精简模式。
- 修复 SiliconFlow MiniMax 工具调用流式兼容MiniMax 在 OpenAI 兼容流中会在参数增量 chunk 返回空 `function.name`LangGraph v3 event stream 会将空名称写入最终工具调用并导致工具执行失败;该模型默认对工具调用禁用流式模型响应,保留 LangGraph v3 运行事件并避免 agent-chat 中出现空工具名。
- 收敛后端模块边界:文档解析从 `plugins.parser` 移动到 `knowledge.parser`,内容审查从 `plugins.guard` 移动到 `services.guard`
- 收敛文件服务边界文件预览判断抽为独立服务Viewer 文件系统的 workspace 分支复用用户 workspace 服务,线程运行时上下文解析从泛化 `filesystem_service` 拆出为 agent runtime helper。
- 升级 DeepAgents 到 0.6.7 并适配新版文件系统协议SubAgentMiddleware 改为显式 subagent specSkills prompt 补齐新版占位符sandbox/skills backend 复用新版 `ReadResult`、`GlobResult`、`GrepResult` 等协议类型,文件权限在 backend 层明确区分 skills、uploads、outputs 与 workspace保留最小 `CustomCompositeBackend` 以避免非 route glob 误扫其他 routeAgent 上下文压缩改为复用 DeepAgents SummarizationMiddleware历史摘要与大工具结果统一 offload 到 outputs。

View File

@ -17,29 +17,33 @@
**智能体**
- [ ] 子智能体缺少异步的机制
- [ ] 子智能体缺少 steer 机制
- [ ] 子智能体的双向通信,缺少 ask_for_main_agent 的机制
- [ ] 子智能体缺少异步的机制 <Badge text="v0.7.1" />
- [ ] 子智能体缺少 steer 机制 <Badge text="v0.7.1" />
- [ ] 子智能体的双向通信,缺少 ask_for_main_agent 的机制 <Badge text="v0.7.1" />
- [ ] 子智能体与子智能体的通信机制
- [ ] 如何停掉一个子智能体、查看智能体的进度
- [ ] RAG 评估支持 Agent 模式
- [ ] 添加 Agent 独立调用接口,方便后续评估使用
- [ ] 任务队列 <Badge text="v0.7.2" />
**并发与分布式**
- [ ] 提高 FastAPI 的并发能力
**其他**
- [ ] 历史对话新增分组(或者叫做项目)
- [ ] 集成 Memory基于 deepagents 的文件后端实现,需要考虑定位
- [ ] 模型供应商类型继续补齐非 OpenAI 兼容适配,并清理不再支持的 provider type 字样 <Badge text="v0.7.1" />
**仅设想**
- [ ] Yuxi-cli 相关的功能,放在后续版本中实现(不是类似于编程助手,而是管理平台的工,等各个 router 接口优化之后)
- [ ] Yuxi-cli 支持 `yuxi upload <DIR_NAME>`,将本地文件夹上传到系统中
### Bugs
- [ ] 目前的知识库的图片存在公开访问风险
- [ ] 点开对话的时候要能够自动定位到尾部,而不是最开始。
- [ ] HTML 渲染侧边模式底部有部分无法渲染,全屏情况下下面有白边
- [ ] Summary 无法正常触发
---

View File

@ -741,10 +741,9 @@ defineExpose({
<span>Provider Type</span>
<a-select v-model:value="providerForm.provider_type">
<a-select-option value="openai">openai</a-select-option>
<a-select-option value="anthropic">anthropic</a-select-option>
<!-- <a-select-option value="anthropic">anthropic</a-select-option>
<a-select-option value="gemini">gemini</a-select-option>
<a-select-option value="openrouter">openrouter</a-select-option>
<a-select-option value="lmstudio">lmstudio</a-select-option>
<a-select-option value="openrouter">openrouter</a-select-option> -->
</a-select>
</label>
</div>

View File

@ -10,7 +10,6 @@ export const modelIcons = {
dashscope: `${ICON_BASE}/bailian-color.svg`,
deepseek: `${ICON_BASE}/deepseek-color.svg`,
google: `${ICON_BASE}/google-color.svg`,
lmstudio: `${ICON_BASE}/lmstudio.svg`,
minimax: `${ICON_BASE}/minimax-color.svg`,
'minimax-cn': `${ICON_BASE}/minimax-color.svg`,
modelscope: `${ICON_BASE}/modelscope-color.svg`,