Merge remote-tracking branch 'upstream/develop' into feat/quota-check-decorator
This commit is contained in:
11
.github/workflows/release-notify-wechat.yml
vendored
11
.github/workflows/release-notify-wechat.yml
vendored
@@ -121,6 +121,8 @@ jobs:
|
||||
AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
SOURCERY_FOUND: ${{ steps.sourcery.outputs.found }}
|
||||
SOURCERY_SUMMARY: ${{ steps.sourcery.outputs.summary }}
|
||||
QWEN_SUMMARY: ${{ steps.qwen.outputs.summary }}
|
||||
@@ -135,11 +137,16 @@ jobs:
|
||||
label = "AI变更摘要"
|
||||
summary = os.environ.get("QWEN_SUMMARY", "AI 摘要生成失败")
|
||||
|
||||
pr_number = os.environ.get("PR_NUMBER", "")
|
||||
short_sha = os.environ.get("MERGE_SHA", "")[:7]
|
||||
|
||||
content = (
|
||||
"## 🚀 Release 发布通知\n"
|
||||
"> 📦 **分支**: " + os.environ["BRANCH"] + "\n"
|
||||
"> <EFBFBD> **分支**: " + os.environ["BRANCH"] + "\n"
|
||||
"> 👤 **提交人**: " + os.environ["AUTHOR"] + "\n"
|
||||
"> 📝 **标题**: " + os.environ["PR_TITLE"] + "\n\n"
|
||||
"> 📝 **标题**: " + os.environ["PR_TITLE"] + "\n"
|
||||
"> 🔢 **PR编号**: #" + pr_number + "\n"
|
||||
"> 🔖 **Commit**: " + short_sha + "\n\n"
|
||||
"### 🧠 " + label + "\n" +
|
||||
summary + "\n\n"
|
||||
"---\n"
|
||||
|
||||
@@ -443,10 +443,10 @@ async def retrieve_chunks(
|
||||
match retrieve_data.retrieve_type:
|
||||
case chunk_schema.RetrieveType.PARTICIPLE:
|
||||
rs = vector_service.search_by_full_text(query=retrieve_data.query, top_k=retrieve_data.top_k, indices=indices, score_threshold=retrieve_data.similarity_threshold, file_names_filter=retrieve_data.file_names_filter)
|
||||
return success(data=rs, msg="retrieval successful")
|
||||
return success(data=jsonable_encoder(rs), msg="retrieval successful")
|
||||
case chunk_schema.RetrieveType.SEMANTIC:
|
||||
rs = vector_service.search_by_vector(query=retrieve_data.query, top_k=retrieve_data.top_k, indices=indices, score_threshold=retrieve_data.vector_similarity_weight, file_names_filter=retrieve_data.file_names_filter)
|
||||
return success(data=rs, msg="retrieval successful")
|
||||
return success(data=jsonable_encoder(rs), msg="retrieval successful")
|
||||
case _:
|
||||
rs1 = vector_service.search_by_vector(query=retrieve_data.query, top_k=retrieve_data.top_k, indices=indices, score_threshold=retrieve_data.vector_similarity_weight, file_names_filter=retrieve_data.file_names_filter)
|
||||
rs2 = vector_service.search_by_full_text(query=retrieve_data.query, top_k=retrieve_data.top_k, indices=indices, score_threshold=retrieve_data.similarity_threshold, file_names_filter=retrieve_data.file_names_filter)
|
||||
|
||||
@@ -165,7 +165,7 @@ def _get_ontology_service(
|
||||
api_key=api_key_config.api_key,
|
||||
base_url=api_key_config.api_base,
|
||||
is_omni=api_key_config.is_omni,
|
||||
support_thinking="thinking" in (api_key_config.capability or []),
|
||||
capability=api_key_config.capability,
|
||||
max_retries=3,
|
||||
timeout=60.0
|
||||
)
|
||||
|
||||
@@ -41,6 +41,7 @@ class LangChainAgent:
|
||||
max_tool_consecutive_calls: int = 3, # 单个工具最大连续调用次数
|
||||
deep_thinking: bool = False, # 是否启用深度思考模式
|
||||
thinking_budget_tokens: Optional[int] = None, # 深度思考 token 预算
|
||||
json_output: bool = False, # 是否强制 JSON 输出
|
||||
capability: Optional[List[str]] = None # 模型能力列表,用于校验是否支持深度思考
|
||||
):
|
||||
"""初始化 LangChain Agent
|
||||
@@ -64,7 +65,6 @@ class LangChainAgent:
|
||||
self.streaming = streaming
|
||||
self.is_omni = is_omni
|
||||
self.max_tool_consecutive_calls = max_tool_consecutive_calls
|
||||
self.deep_thinking = deep_thinking and ("thinking" in (capability or []))
|
||||
|
||||
# 工具调用计数器:记录每个工具的连续调用次数
|
||||
self.tool_call_counter: Dict[str, int] = {}
|
||||
@@ -80,6 +80,12 @@ class LangChainAgent:
|
||||
|
||||
self.system_prompt = system_prompt or "你是一个专业的AI助手"
|
||||
|
||||
# ChatTongyi 要求 messages 含 'json' 字样才能使用 response_format
|
||||
# 在 system prompt 中注入 JSON 要求
|
||||
from app.models.models_model import ModelProvider
|
||||
if json_output and provider.lower() == ModelProvider.DASHSCOPE and not is_omni:
|
||||
self.system_prompt += "\n请以JSON格式输出。"
|
||||
|
||||
logger.debug(
|
||||
f"Agent 迭代次数配置: max_iterations={self.max_iterations}, "
|
||||
f"tool_count={len(self.tools)}, "
|
||||
@@ -87,23 +93,17 @@ class LangChainAgent:
|
||||
f"auto_calculated={max_iterations is None}"
|
||||
)
|
||||
|
||||
# 根据 capability 校验是否真正支持深度思考
|
||||
actual_deep_thinking = self.deep_thinking
|
||||
if deep_thinking and not actual_deep_thinking:
|
||||
logger.warning(
|
||||
f"模型 {model_name} 不支持深度思考(capability 中无 'thinking'),已自动关闭 deep_thinking"
|
||||
)
|
||||
|
||||
# 创建 RedBearLLM(支持多提供商)
|
||||
# 创建 RedBearLLM,capability 校验由 RedBearModelConfig 统一处理
|
||||
model_config = RedBearModelConfig(
|
||||
model_name=model_name,
|
||||
provider=provider,
|
||||
api_key=api_key,
|
||||
base_url=api_base,
|
||||
is_omni=is_omni,
|
||||
deep_thinking=actual_deep_thinking,
|
||||
thinking_budget_tokens=thinking_budget_tokens if actual_deep_thinking else None,
|
||||
support_thinking="thinking" in (capability or []),
|
||||
capability=capability,
|
||||
deep_thinking=deep_thinking,
|
||||
thinking_budget_tokens=thinking_budget_tokens,
|
||||
json_output=json_output,
|
||||
extra_params={
|
||||
"temperature": temperature,
|
||||
"max_tokens": max_tokens,
|
||||
@@ -112,6 +112,9 @@ class LangChainAgent:
|
||||
)
|
||||
|
||||
self.llm = RedBearLLM(model_config, type=ModelType.CHAT)
|
||||
# 从经过校验的 config 读取实际生效的能力开关
|
||||
self.deep_thinking = model_config.deep_thinking
|
||||
self.json_output = model_config.json_output
|
||||
|
||||
# 获取底层模型用于真正的流式调用
|
||||
self._underlying_llm = self.llm._model if hasattr(self.llm, '_model') else self.llm
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from typing import Any, Dict, Optional, TypeVar
|
||||
from typing import Any, Dict, List, Optional, TypeVar
|
||||
|
||||
from langchain_aws import ChatBedrock
|
||||
from langchain_community.chat_models import ChatTongyi
|
||||
@@ -9,12 +9,12 @@ from langchain_core.embeddings import Embeddings
|
||||
from langchain_core.language_models import BaseLLM
|
||||
from langchain_ollama import OllamaLLM
|
||||
from langchain_openai import ChatOpenAI, OpenAI
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
from app.core.error_codes import BizCode
|
||||
from app.core.exceptions import BusinessException
|
||||
from app.models.models_model import ModelProvider, ModelType
|
||||
from app.core.models.volcano_chat import VolcanoChatOpenAI
|
||||
from app.core.models.compatible_chat import CompatibleChatOpenAI
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@@ -25,10 +25,11 @@ class RedBearModelConfig(BaseModel):
|
||||
provider: str
|
||||
api_key: str
|
||||
base_url: Optional[str] = None
|
||||
capability: List[str] = Field(default_factory=list) # 模型能力列表,驱动所有能力开关
|
||||
is_omni: bool = False # 是否为 Omni 模型
|
||||
deep_thinking: bool = False # 是否启用深度思考模式
|
||||
thinking_budget_tokens: Optional[int] = None # 深度思考 token 预算
|
||||
support_thinking: bool = False # 模型是否支持 enable_thinking 参数(capability 含 thinking)
|
||||
json_output: bool = False # 是否强制 JSON 输出
|
||||
# 请求超时时间(秒)- 默认120秒以支持复杂的LLM调用,可通过环境变量 LLM_TIMEOUT 配置
|
||||
timeout: float = Field(default_factory=lambda: float(os.getenv("LLM_TIMEOUT", "120.0")))
|
||||
# 最大重试次数 - 默认2次以避免过长等待,可通过环境变量 LLM_MAX_RETRIES 配置
|
||||
@@ -36,6 +37,23 @@ class RedBearModelConfig(BaseModel):
|
||||
concurrency: int = 5 # 并发限流
|
||||
extra_params: Dict[str, Any] = {}
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _resolve_capabilities(self) -> "RedBearModelConfig":
|
||||
from app.core.logging_config import get_business_logger
|
||||
logger = get_business_logger()
|
||||
if self.deep_thinking and "thinking" not in self.capability:
|
||||
logger.warning(
|
||||
f"模型 {self.model_name} 不支持深度思考(capability 中无 'thinking'),已自动关闭 deep_thinking"
|
||||
)
|
||||
self.deep_thinking = False
|
||||
self.thinking_budget_tokens = None
|
||||
if self.json_output and "json_output" not in self.capability:
|
||||
logger.warning(
|
||||
f"模型 {self.model_name} 不支持 JSON 输出(capability 中无 'json_output'),已自动关闭 json_output"
|
||||
)
|
||||
self.json_output = False
|
||||
return self
|
||||
|
||||
|
||||
class RedBearModelFactory:
|
||||
"""模型工厂类"""
|
||||
@@ -74,17 +92,20 @@ class RedBearModelFactory:
|
||||
is_streaming = bool(config.extra_params.get("streaming"))
|
||||
if is_streaming:
|
||||
params["stream_usage"] = True
|
||||
# 只有支持 thinking 的模型才传 enable_thinking
|
||||
if config.support_thinking:
|
||||
model_kwargs: Dict[str, Any] = config.extra_params.get("model_kwargs", {})
|
||||
if is_streaming:
|
||||
model_kwargs["enable_thinking"] = config.deep_thinking
|
||||
if config.deep_thinking:
|
||||
model_kwargs["incremental_output"] = True
|
||||
if config.thinking_budget_tokens:
|
||||
model_kwargs["thinking_budget"] = config.thinking_budget_tokens
|
||||
else:
|
||||
model_kwargs["enable_thinking"] = False
|
||||
# 支持 thinking 的模型始终传 enable_thinking,关闭时显式传 False 避免模型默认开启思考
|
||||
if "thinking" in config.capability:
|
||||
extra_body = params.setdefault("extra_body", {})
|
||||
if config.deep_thinking:
|
||||
extra_body["enable_thinking"] = False
|
||||
if is_streaming:
|
||||
extra_body["enable_thinking"] = True
|
||||
if config.thinking_budget_tokens:
|
||||
extra_body["thinking_budget"] = config.thinking_budget_tokens
|
||||
params["extra_body"] = extra_body
|
||||
# JSON 输出模式
|
||||
if config.json_output:
|
||||
model_kwargs = params.setdefault("model_kwargs", {})
|
||||
model_kwargs["response_format"] = {"type": "json_object"}
|
||||
params["model_kwargs"] = model_kwargs
|
||||
return params
|
||||
|
||||
@@ -108,27 +129,30 @@ class RedBearModelFactory:
|
||||
**config.extra_params
|
||||
}
|
||||
# 流式模式下启用 stream_usage 以获取 token 统计
|
||||
if config.extra_params.get("streaming"):
|
||||
params["stream_usage"] = True
|
||||
# 深度思考模式
|
||||
is_streaming = bool(config.extra_params.get("streaming"))
|
||||
if config.support_thinking:
|
||||
if is_streaming and not config.is_omni:
|
||||
if provider == ModelProvider.VOLCANO:
|
||||
# 火山引擎深度思考仅流式调用支持,非流式时不传 thinking 参数
|
||||
thinking_config: Dict[str, Any] = {
|
||||
"type": "enabled" if config.deep_thinking else "disabled"
|
||||
}
|
||||
if config.deep_thinking and config.thinking_budget_tokens:
|
||||
thinking_config["budget_tokens"] = config.thinking_budget_tokens
|
||||
params["extra_body"] = {"thinking": thinking_config}
|
||||
else:
|
||||
# 始终显式传递 enable_thinking,不支持该参数的模型(如 DeepSeek-R1)会直接忽略
|
||||
model_kwargs: Dict[str, Any] = config.extra_params.get("model_kwargs", {})
|
||||
model_kwargs["enable_thinking"] = config.deep_thinking
|
||||
if config.deep_thinking and config.thinking_budget_tokens:
|
||||
model_kwargs["thinking_budget"] = config.thinking_budget_tokens
|
||||
params["model_kwargs"] = model_kwargs
|
||||
if is_streaming:
|
||||
params["stream_usage"] = True
|
||||
# 支持 thinking 的模型始终传 enable_thinking,关闭时显式传 False 避免模型默认开启思考
|
||||
if "thinking" in config.capability:
|
||||
# VOLCANO 深度思考仅流式支持
|
||||
if provider == ModelProvider.VOLCANO:
|
||||
thinking_config: Dict[str, Any] = {"type": "enabled" if config.deep_thinking else "disabled"}
|
||||
if config.deep_thinking and config.thinking_budget_tokens:
|
||||
thinking_config["budget_tokens"] = config.thinking_budget_tokens
|
||||
params["extra_body"] = {"thinking": thinking_config}
|
||||
else:
|
||||
extra_body = params.setdefault("extra_body", {})
|
||||
if config.deep_thinking:
|
||||
extra_body["enable_thinking"] = False
|
||||
if is_streaming:
|
||||
extra_body["enable_thinking"] = True
|
||||
if config.thinking_budget_tokens:
|
||||
extra_body["thinking_budget"] = config.thinking_budget_tokens
|
||||
params["extra_body"] = extra_body
|
||||
# JSON 输出模式
|
||||
if config.json_output:
|
||||
params.setdefault("model_kwargs", {})
|
||||
params["model_kwargs"]["response_format"] = {"type": "json_object"}
|
||||
return params
|
||||
elif provider == ModelProvider.DASHSCOPE:
|
||||
params = {
|
||||
@@ -137,18 +161,21 @@ class RedBearModelFactory:
|
||||
"max_retries": config.max_retries,
|
||||
**config.extra_params
|
||||
}
|
||||
# 只有支持 thinking 的模型才传 enable_thinking
|
||||
if config.support_thinking:
|
||||
# 支持 thinking 的模型始终传 enable_thinking,关闭时显式传 False 避免模型默认开启思考
|
||||
if "thinking" in config.capability:
|
||||
is_streaming = bool(config.extra_params.get("streaming"))
|
||||
model_kwargs: Dict[str, Any] = config.extra_params.get("model_kwargs", {})
|
||||
if is_streaming:
|
||||
model_kwargs["enable_thinking"] = config.deep_thinking
|
||||
if config.deep_thinking:
|
||||
model_kwargs["incremental_output"] = True
|
||||
if config.thinking_budget_tokens:
|
||||
model_kwargs["thinking_budget"] = config.thinking_budget_tokens
|
||||
else:
|
||||
model_kwargs = params.setdefault("model_kwargs", {})
|
||||
if config.deep_thinking:
|
||||
model_kwargs["enable_thinking"] = False
|
||||
if is_streaming:
|
||||
model_kwargs["enable_thinking"] = True
|
||||
model_kwargs["incremental_output"] = True
|
||||
if config.thinking_budget_tokens:
|
||||
model_kwargs["thinking_budget"] = config.thinking_budget_tokens
|
||||
params["model_kwargs"] = model_kwargs
|
||||
if config.json_output:
|
||||
model_kwargs = params.setdefault("model_kwargs", {})
|
||||
model_kwargs["response_format"] = {"type": "json_object"}
|
||||
params["model_kwargs"] = model_kwargs
|
||||
return params
|
||||
elif provider == ModelProvider.BEDROCK:
|
||||
@@ -196,6 +223,10 @@ class RedBearModelFactory:
|
||||
params["additional_model_request_fields"] = {
|
||||
"thinking": {"type": "enabled", "budget_tokens": budget}
|
||||
}
|
||||
# JSON 输出模式
|
||||
if config.json_output:
|
||||
params.setdefault("model_kwargs", {})
|
||||
params["model_kwargs"]["response_format"] = {"type": "json_object"}
|
||||
return params
|
||||
else:
|
||||
raise BusinessException(f"不支持的提供商: {provider}", code=BizCode.PROVIDER_NOT_SUPPORTED)
|
||||
@@ -224,11 +255,11 @@ def get_provider_llm_class(config: RedBearModelConfig, type: ModelType = ModelTy
|
||||
"""根据模型提供商获取对应的模型类"""
|
||||
provider = config.provider.lower()
|
||||
|
||||
# dashscope 的 omni 模型使用 OpenAI 兼容模式
|
||||
# dashscope的omni模型 和 volcano模型使用
|
||||
if provider == ModelProvider.DASHSCOPE and config.is_omni:
|
||||
return ChatOpenAI
|
||||
return CompatibleChatOpenAI
|
||||
if provider == ModelProvider.VOLCANO:
|
||||
return VolcanoChatOpenAI
|
||||
return CompatibleChatOpenAI
|
||||
if provider in [ModelProvider.OPENAI, ModelProvider.XINFERENCE, ModelProvider.GPUSTACK]:
|
||||
if type == ModelType.LLM:
|
||||
return OpenAI
|
||||
|
||||
@@ -12,8 +12,8 @@ from langchain_core.outputs import ChatGenerationChunk, ChatResult
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
|
||||
class VolcanoChatOpenAI(ChatOpenAI):
|
||||
"""火山引擎 Chat 模型,支持深度思考内容(reasoning_content)的流式和非流式透传。"""
|
||||
class CompatibleChatOpenAI(ChatOpenAI):
|
||||
"""火山和千问的omni兼容模型,支持深度思考内容(reasoning_content)的流式和非流式透传。"""
|
||||
|
||||
def _create_chat_result(self, response: Union[dict, Any], generation_info: Optional[dict] = None) -> ChatResult:
|
||||
result = super()._create_chat_result(response, generation_info)
|
||||
@@ -6,7 +6,8 @@ models:
|
||||
description: AI21 Labs大语言模型,completion生成模式,256000上下文窗口
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -20,6 +21,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- vision
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -38,6 +40,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -54,7 +57,8 @@ models:
|
||||
description: Cohere大语言模型,支持智能体思考、工具调用、流式工具调用,128000上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -72,6 +76,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -87,7 +92,8 @@ models:
|
||||
description: Meta Llama大语言模型,支持智能体思考、工具调用,128000上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -101,7 +107,8 @@ models:
|
||||
description: Mistral AI大语言模型,支持智能体思考、工具调用,32000上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -115,7 +122,8 @@ models:
|
||||
description: OpenAI大语言模型,支持智能体思考、工具调用、流式工具调用,32768上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -130,7 +138,8 @@ models:
|
||||
description: Qwen大语言模型,支持智能体思考、工具调用、流式工具调用,32768上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
|
||||
@@ -8,6 +8,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -22,6 +23,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -36,6 +38,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -48,7 +51,8 @@ models:
|
||||
description: DeepSeek-V3.1大语言模型,支持智能体思考,131072超大上下文窗口,对话模式,支持丰富生成参数调节
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -61,7 +65,8 @@ models:
|
||||
description: DeepSeek-V3.2-exp实验版大语言模型,支持智能体思考,131072超大上下文窗口,对话模式,支持丰富生成参数调节
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -74,7 +79,8 @@ models:
|
||||
description: DeepSeek-V3.2大语言模型,支持智能体思考,131072超大上下文窗口,对话模式,支持丰富生成参数调节
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -87,7 +93,8 @@ models:
|
||||
description: DeepSeek-V3大语言模型,支持智能体思考,64000上下文窗口,对话模式,支持文本与JSON格式输出
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -100,7 +107,8 @@ models:
|
||||
description: farui-plus大语言模型,支持多工具调用、智能体思考、流式工具调用,12288上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -115,7 +123,8 @@ models:
|
||||
description: GLM-4.7大语言模型,支持多工具调用、智能体思考、流式工具调用,202752超大上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -133,6 +142,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -150,6 +160,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -180,6 +191,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -210,7 +222,7 @@ models:
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -376,6 +388,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- video
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -448,6 +461,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- video
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -466,6 +480,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- video
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -481,7 +496,8 @@ models:
|
||||
description: qwen2.5-0.5b-instruct大语言模型,支持多工具调用、智能体思考、流式工具调用,32768上下文窗口,对话模式,未废弃
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -498,6 +514,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -513,7 +530,7 @@ models:
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -530,6 +547,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -546,6 +564,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -561,7 +580,7 @@ models:
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -578,6 +597,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -594,6 +614,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -610,6 +631,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -626,6 +648,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -641,7 +664,7 @@ models:
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -656,7 +679,7 @@ models:
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -672,6 +695,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -687,6 +711,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -702,6 +727,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -719,6 +745,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -736,6 +763,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -752,6 +780,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -768,7 +797,7 @@ models:
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -785,6 +814,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -803,6 +833,8 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- audio
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: true
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -822,7 +854,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -844,6 +876,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -864,7 +897,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -886,6 +919,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -907,6 +941,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -928,6 +963,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -947,6 +983,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -964,6 +1001,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -979,6 +1017,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -994,6 +1033,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
|
||||
@@ -10,6 +10,7 @@ models:
|
||||
- vision
|
||||
- audio
|
||||
- video
|
||||
- json_output
|
||||
is_omni: true
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -27,7 +28,8 @@ models:
|
||||
description: gpt-3.5-turbo-0125大语言模型,支持多工具调用、智能体思考、流式工具调用,16385上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -42,7 +44,8 @@ models:
|
||||
description: gpt-3.5-turbo-1106大语言模型,支持多工具调用、智能体思考、流式工具调用,16385上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -57,7 +60,8 @@ models:
|
||||
description: gpt-3.5-turbo-16k大语言模型,支持多工具调用、智能体思考、流式工具调用,16385上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -84,7 +88,8 @@ models:
|
||||
description: gpt-3.5-turbo大语言模型,支持多工具调用、智能体思考、流式工具调用,16385上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -99,7 +104,8 @@ models:
|
||||
description: gpt-4-0125-preview大语言模型,支持多工具调用、智能体思考、流式工具调用,128000上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -114,7 +120,8 @@ models:
|
||||
description: gpt-4-1106-preview大语言模型,支持多工具调用、智能体思考、流式工具调用,128000上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -131,6 +138,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- vision
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -146,7 +154,8 @@ models:
|
||||
description: gpt-4-turbo-preview大语言模型,支持多工具调用、智能体思考、流式工具调用,128000上下文窗口,对话模式
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -163,6 +172,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- vision
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -194,6 +204,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -213,6 +224,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -231,6 +243,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -248,6 +261,7 @@ models:
|
||||
is_official: true
|
||||
capability:
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -266,6 +280,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -284,6 +299,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -302,6 +318,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -321,6 +338,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -340,6 +358,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
|
||||
@@ -11,6 +11,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -26,6 +27,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -41,6 +43,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -56,6 +59,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -72,6 +76,7 @@ models:
|
||||
capability:
|
||||
- vision
|
||||
- video
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -87,6 +92,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -102,6 +108,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -117,6 +124,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -132,6 +140,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -148,6 +157,7 @@ models:
|
||||
- vision
|
||||
- video
|
||||
- thinking
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -175,7 +185,8 @@ models:
|
||||
description: 全新一代主力模型,性能全面升级,在知识、代码、推理等方面表现卓越。最大支持 128k 上下文窗口,输出长度支持最大 12k tokens。
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
@@ -187,7 +198,8 @@ models:
|
||||
description: 全新一代轻量版模型,极致响应速度,效果与时延均达到全球一流水平。支持 32k 上下文窗口,输出长度支持最大 12k tokens。
|
||||
is_deprecated: false
|
||||
is_official: true
|
||||
capability: []
|
||||
capability:
|
||||
- json_output
|
||||
is_omni: false
|
||||
tags:
|
||||
- 大语言模型
|
||||
|
||||
@@ -116,6 +116,11 @@ class LLMNodeConfig(BaseNodeConfig):
|
||||
description="Top-p 采样参数"
|
||||
)
|
||||
|
||||
json_output: bool = Field(
|
||||
default=False,
|
||||
description="是否以 JSON 格式输出"
|
||||
)
|
||||
|
||||
frequency_penalty: float | None = Field(
|
||||
default=None,
|
||||
ge=-2.0,
|
||||
|
||||
@@ -22,6 +22,7 @@ from app.db import get_db_context
|
||||
from app.models import ModelType
|
||||
from app.schemas.model_schema import ModelInfo
|
||||
from app.services.model_service import ModelConfigService
|
||||
from app.models.models_model import ModelProvider
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -126,7 +127,11 @@ class LLMNode(BaseNode):
|
||||
|
||||
# 4. 创建 LLM 实例(使用已提取的数据)
|
||||
# 注意:对于流式输出,需要在模型初始化时设置 streaming=True
|
||||
extra_params = {"streaming": stream} if stream else {}
|
||||
extra_params: dict[str, Any] = {"streaming": stream} if stream else {}
|
||||
if self.typed_config.temperature is not None:
|
||||
extra_params["temperature"] = self.typed_config.temperature
|
||||
if self.typed_config.max_tokens is not None:
|
||||
extra_params["max_tokens"] = self.typed_config.max_tokens
|
||||
|
||||
llm = RedBearLLM(
|
||||
RedBearModelConfig(
|
||||
@@ -135,7 +140,9 @@ class LLMNode(BaseNode):
|
||||
api_key=model_info.api_key,
|
||||
base_url=model_info.api_base,
|
||||
extra_params=extra_params,
|
||||
is_omni=model_info.is_omni
|
||||
is_omni=model_info.is_omni,
|
||||
capability=model_info.capability,
|
||||
json_output=self.typed_config.json_output,
|
||||
),
|
||||
type=model_info.model_type
|
||||
)
|
||||
@@ -218,6 +225,16 @@ class LLMNode(BaseNode):
|
||||
rendered = self._render_template(prompt_template, variable_pool)
|
||||
self.messages = [{"role": "user", "content": rendered}]
|
||||
|
||||
# ChatTongyi 要求 messages 含 'json' 字样才能使用 response_format,在 system prompt 中注入
|
||||
if (self.typed_config.json_output
|
||||
and model_info.provider.lower() == ModelProvider.DASHSCOPE
|
||||
and not model_info.is_omni):
|
||||
system_msg = next((m for m in self.messages if m["role"] == "system"), None)
|
||||
if system_msg:
|
||||
system_msg["content"] += "\n请以JSON格式输出。"
|
||||
else:
|
||||
self.messages.insert(0, {"role": "system", "content": "请以JSON格式输出。"})
|
||||
|
||||
return llm
|
||||
|
||||
async def execute(self, state: WorkflowState, variable_pool: VariablePool) -> AIMessage:
|
||||
|
||||
@@ -245,6 +245,7 @@ class ModelParameters(BaseModel):
|
||||
stop: Optional[List[str]] = Field(default=None, description="停止序列")
|
||||
deep_thinking: bool = Field(default=False, description="是否启用深度思考模式(需模型支持,如 DeepSeek-R1、QwQ 等)")
|
||||
thinking_budget_tokens: Optional[int] = Field(default=None, ge=1024, le=131072, description="深度思考 token 预算(仅部分模型支持)")
|
||||
json_output: bool = Field(default=False, description="是否强制 JSON 格式输出(需模型支持 json_output 能力)")
|
||||
|
||||
|
||||
class VariableDefinition(BaseModel):
|
||||
|
||||
@@ -120,6 +120,7 @@ class AppChatService:
|
||||
tools=tools,
|
||||
deep_thinking=model_parameters.get("deep_thinking", False),
|
||||
thinking_budget_tokens=model_parameters.get("thinking_budget_tokens"),
|
||||
json_output=model_parameters.get("json_output", False),
|
||||
capability=api_key_obj.capability or [],
|
||||
)
|
||||
|
||||
@@ -392,6 +393,7 @@ class AppChatService:
|
||||
streaming=True,
|
||||
deep_thinking=model_parameters.get("deep_thinking", False),
|
||||
thinking_budget_tokens=model_parameters.get("thinking_budget_tokens"),
|
||||
json_output=model_parameters.get("json_output", False),
|
||||
capability=api_key_obj.capability or [],
|
||||
)
|
||||
|
||||
|
||||
@@ -544,7 +544,7 @@ class ConversationService:
|
||||
api_key=api_key,
|
||||
base_url=api_base,
|
||||
is_omni=is_omni,
|
||||
support_thinking="thinking" in (capability or []),
|
||||
capability=capability,
|
||||
),
|
||||
type=ModelType(model_type)
|
||||
)
|
||||
|
||||
@@ -597,6 +597,7 @@ class AgentRunService:
|
||||
tools=tools,
|
||||
deep_thinking=effective_params.get("deep_thinking", False),
|
||||
thinking_budget_tokens=effective_params.get("thinking_budget_tokens"),
|
||||
json_output=effective_params.get("json_output", False),
|
||||
capability=api_key_config.get("capability", []),
|
||||
)
|
||||
|
||||
@@ -853,6 +854,7 @@ class AgentRunService:
|
||||
streaming=True,
|
||||
deep_thinking=effective_params.get("deep_thinking", False),
|
||||
thinking_budget_tokens=effective_params.get("thinking_budget_tokens"),
|
||||
json_output=effective_params.get("json_output", False),
|
||||
capability=api_key_config.get("capability", []),
|
||||
)
|
||||
|
||||
|
||||
@@ -415,9 +415,11 @@ class LLMRouter:
|
||||
api_key=api_key_config.api_key,
|
||||
base_url=api_key_config.api_base,
|
||||
is_omni=api_key_config.is_omni,
|
||||
support_thinking="thinking" in (api_key_config.capability or []),
|
||||
temperature=0.3,
|
||||
max_tokens=500
|
||||
capability=api_key_config.capability,
|
||||
extra_params={
|
||||
"temperature": 0.3,
|
||||
"max_tokens": 500
|
||||
}
|
||||
)
|
||||
|
||||
logger.debug(f"创建 LLM 实例 - Provider: {api_key_config.provider}, Model: {api_key_config.model_name}")
|
||||
|
||||
@@ -393,7 +393,7 @@ class MasterAgentRouter:
|
||||
api_key=api_key_config.api_key,
|
||||
base_url=api_key_config.api_base,
|
||||
is_omni=api_key_config.is_omni,
|
||||
support_thinking="thinking" in (api_key_config.capability or []),
|
||||
capability=api_key_config.capability,
|
||||
extra_params = extra_params
|
||||
)
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ class MemoryPerceptualService:
|
||||
api_key=model_config.api_key,
|
||||
base_url=model_config.api_base,
|
||||
is_omni=model_config.is_omni,
|
||||
support_thinking="thinking" in (model_config.capability or []),
|
||||
capability=model_config.capability,
|
||||
)
|
||||
)
|
||||
return llm, model_config
|
||||
|
||||
@@ -47,7 +47,8 @@ class ModelParameterMerger:
|
||||
"n": 1,
|
||||
"stop": None,
|
||||
"deep_thinking": False,
|
||||
"thinking_budget_tokens": None
|
||||
"thinking_budget_tokens": None,
|
||||
"json_output": False
|
||||
}
|
||||
|
||||
# 合并参数:默认值 -> 模型配置 -> Agent 配置
|
||||
|
||||
@@ -125,9 +125,11 @@ class ModelConfigService:
|
||||
api_key=api_key,
|
||||
base_url=api_base,
|
||||
is_omni=is_omni,
|
||||
support_thinking="thinking" in (capability or []),
|
||||
temperature=0.7,
|
||||
max_tokens=100
|
||||
capability=capability,
|
||||
extra_params={
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 100
|
||||
}
|
||||
)
|
||||
|
||||
# 根据模型类型选择不同的验证方式
|
||||
|
||||
@@ -2616,9 +2616,11 @@ class MultiAgentOrchestrator:
|
||||
api_key=api_key_config.api_key,
|
||||
base_url=api_key_config.api_base,
|
||||
is_omni=api_key_config.is_omni,
|
||||
support_thinking="thinking" in (api_key_config.capability or []),
|
||||
temperature=0.7, # 整合任务使用中等温度
|
||||
max_tokens=2000
|
||||
capability=api_key_config.capability,
|
||||
extra_params={
|
||||
"temperature": 0.7, # 整合任务使用中等温度
|
||||
"max_tokens": 2000
|
||||
}
|
||||
)
|
||||
|
||||
# 创建 LLM 实例
|
||||
@@ -2795,10 +2797,12 @@ class MultiAgentOrchestrator:
|
||||
api_key=api_key_config.api_key,
|
||||
base_url=api_key_config.api_base,
|
||||
is_omni=api_key_config.is_omni,
|
||||
support_thinking="thinking" in (api_key_config.capability or []),
|
||||
temperature=0.7,
|
||||
max_tokens=2000,
|
||||
extra_params={"streaming": True} # 启用流式输出
|
||||
capability=api_key_config.capability,
|
||||
extra_params={
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 2000,
|
||||
"streaming": True # 启用流式输出
|
||||
}
|
||||
)
|
||||
|
||||
# 创建 LLM 实例
|
||||
|
||||
@@ -186,7 +186,7 @@ class PromptOptimizerService:
|
||||
api_key=api_config.api_key,
|
||||
base_url=api_config.api_base,
|
||||
is_omni=api_config.is_omni,
|
||||
support_thinking="thinking" in (api_config.capability or []),
|
||||
capability=api_config.capability,
|
||||
), type=ModelType(model_config.type))
|
||||
try:
|
||||
prompt_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'prompt')
|
||||
|
||||
@@ -250,7 +250,8 @@ class SharedChatService:
|
||||
tools=tools,
|
||||
deep_thinking=model_parameters.get("deep_thinking", False),
|
||||
thinking_budget_tokens=model_parameters.get("thinking_budget_tokens"),
|
||||
capability=api_key_obj.capability or [],
|
||||
json_output=model_parameters.get("json_output", False),
|
||||
capability=api_key_obj.capability,
|
||||
)
|
||||
|
||||
# 加载历史消息
|
||||
@@ -455,6 +456,7 @@ class SharedChatService:
|
||||
streaming=True,
|
||||
deep_thinking=model_parameters.get("deep_thinking", False),
|
||||
thinking_budget_tokens=model_parameters.get("thinking_budget_tokens"),
|
||||
json_output=model_parameters.get("json_output", False),
|
||||
capability=api_key_obj.capability or [],
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,40 @@
|
||||
{
|
||||
"v0.3.0": {
|
||||
"introduction": {
|
||||
"codeName": "破晓",
|
||||
"releaseDate": "2026-4-15",
|
||||
"upgradePosition": "🐻 全面升级应用工作流、记忆智能与系统稳健性,引入版本化API、多模态记忆感知及大量工作流增强,打造更可靠、精准的 MemoryBear",
|
||||
"coreUpgrades": [
|
||||
"1. 应用与API增强<br>* 版本化API调用支持:对外服务API支持指定版本调用<br>* 工作流检查清单:新增结构化验证步骤<br>* 深度思考参数精准控制:仅向支持深度推理的模型发送思考参数<br>* 提示器模型返回优化:优化提示器模型响应处理",
|
||||
"2. 记忆智能 🧠<br>* 多模态记忆感知Agent:支持多模态记忆读取与写入<br>* OpenClaw内置工具:新增内置工具扩展Agent工具集",
|
||||
"3. 用户体验 🎨<br>* 流式渲染稳定性优化:解决LLM流式输出页面抖动问题<br>* 记忆中枢更名:「记忆相关」更名为「记忆中枢」",
|
||||
"4. 工作流改进 ⚙️<br>* 三级变量模板转换:支持三级变量解析<br>* VL模型Token统计:修复模型组合中VL模型Token未统计问题<br>* 导入工作流功能特性同步:正确同步开场白、引用等属性<br>* 会话变量名称唯一性校验:防止变量名冲突<br>* 文件类型提取修复:正确提取file.type信息<br>* 条件分支显示修复:值为0或会话变量时正确渲染<br>* Object/Array校验规则:防止JSON序列化错误<br>* HTTP请求Body字段修正:body字段从name改为key",
|
||||
"5. 知识库 📚<br>* Embedding Token截断安全边界:统一添加8000 token截断,优化Excel独立chunk处理",
|
||||
"6. 稳健性与缺陷修复 🔧<br>* 原子性更新与批量访问失败修复<br>* 对话别名提取错误修复<br>* 工作流别名提取修正(区分用户和AI回复)<br>* RAG记忆分页数据修复<br>* 隐式记忆详情显示修复<br>* 向量查询驱动关闭异常修复<br>* 用户管理启停异常修复<br>* 模型列表筛选不一致修复",
|
||||
"<br>",
|
||||
"v0.3.0 标志着 MemoryBear 向生产成熟度迈出坚实一步。后续版本将持续深化工作流表达力、记忆检索精度和跨模态理解能力,强化复杂Agent编排支持,稳固大规模生产部署基础。",
|
||||
"<br>",
|
||||
"MemoryBear — 破晓 🐻✨"
|
||||
]
|
||||
},
|
||||
"introduction_en": {
|
||||
"codeName": "PoXiao",
|
||||
"releaseDate": "2026-4-15",
|
||||
"upgradePosition": "🐻 Comprehensive upgrades across application workflows, memory intelligence, and system robustness — introducing versioned APIs, multimodal memory perception, and extensive workflow enhancements for a more reliable MemoryBear",
|
||||
"coreUpgrades": [
|
||||
"1. Application & API Enhancements<br>* Versioned API Support: External APIs now support version-specific calls<br>* Workflow Checklist: Structured validation steps before deployment<br>* Deep Thinking Parameter Control: Only send thinking params to supported models<br>* Prompt Optimizer Return Optimization: Improved prompt optimizer response handling",
|
||||
"2. Memory Intelligence 🧠<br>* Multimodal Memory Perception Agent: Read/write multimodal memory<br>* OpenClaw Built-in Tool: New built-in tool for agent operations",
|
||||
"3. User Experience 🎨<br>* Streaming Render Stabilization: Eliminated page jitter during LLM output<br>* Memory Hub Renaming: Renamed to better reflect central memory role",
|
||||
"4. Workflow Improvements ⚙️<br>* Three-Level Variable Template Conversion: Support for three-level variable resolution<br>* VL Model Token Tracking: Fixed token tracking for VL models in model groups<br>* Imported Workflow Feature Sync: Properly sync opening messages, citations, etc.<br>* Session Variable Name Uniqueness: Prevent variable name conflicts<br>* File Type Extraction Fix: Correctly extract file.type information<br>* Condition Branch Display Fix: Correct rendering for value 0 or session variables<br>* Object/Array Validation Rules: Prevent JSON serialization save errors<br>* HTTP Request Body Key Fix: Body field uses key instead of name",
|
||||
"5. Knowledge Base 📚<br>* Embedding Token Truncation Safety: Unified 8000-token boundary, optimized Excel chunk processing",
|
||||
"6. Robustness & Bug Fixes 🔧<br>* Atomic update & batch access failure fixes<br>* Conversation alias extraction fix<br>* Workflow alias extraction correction (user vs AI distinction)<br>* RAG memory pagination fix<br>* Implicit memory detail display fix<br>* Vector query driver closed exception fix<br>* User management enable/disable fix<br>* Model list filter inconsistency fix",
|
||||
"<br>",
|
||||
"v0.3.0 marks a meaningful step toward production maturity for MemoryBear. Upcoming releases will deepen workflow expressiveness, memory retrieval precision, and cross-modal understanding while strengthening complex agent orchestration and large-scale deployment foundations.",
|
||||
"<br>",
|
||||
"MemoryBear — Daybreak 🐻✨"
|
||||
]
|
||||
}
|
||||
},
|
||||
"v0.2.10": {
|
||||
"introduction": {
|
||||
"codeName": "炼剑",
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-03-07 16:49:59
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-25 11:21:59
|
||||
* @Last Modified time: 2026-04-17 10:11:54
|
||||
*/
|
||||
import { useEffect, useState, type FC } from 'react';
|
||||
import { type FC, useEffect, useState } from 'react';
|
||||
import { Select, Flex, Space } from 'antd';
|
||||
import type { SelectProps } from 'antd/es/select';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -22,16 +22,10 @@ interface ModelSelectProps extends SelectProps {
|
||||
fontClassName?: string;
|
||||
isAutoFetch?: boolean;
|
||||
initialData?: Model[];
|
||||
updateOptions?: (options: Model[]) => void;
|
||||
}
|
||||
|
||||
const ModelSelect: FC<ModelSelectProps> = ({
|
||||
params,
|
||||
placeholder,
|
||||
fontClassName,
|
||||
isAutoFetch = true,
|
||||
initialData = [],
|
||||
...props
|
||||
}) => {
|
||||
const ModelSelect: FC<ModelSelectProps> = ({ params, placeholder, fontClassName, isAutoFetch = true, initialData = [], updateOptions, ...props }) => {
|
||||
const { t } = useTranslation();
|
||||
const [options, setOptions] = useState<Model[]>([]);
|
||||
|
||||
@@ -60,6 +54,10 @@ const ModelSelect: FC<ModelSelectProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (updateOptions) updateOptions([...options, ...initialData]);
|
||||
}, [options, initialData])
|
||||
|
||||
return (
|
||||
<Select
|
||||
placeholder={placeholder ?? t('common.pleaseSelect')}
|
||||
|
||||
@@ -629,6 +629,7 @@ export const en = {
|
||||
video: 'Video',
|
||||
thinking: 'Deep Thinking',
|
||||
is_thinking: 'Deep Thinking Support',
|
||||
json_output: 'Support JSON formatted output',
|
||||
},
|
||||
knowledgeBase: {
|
||||
home: 'Home',
|
||||
@@ -1524,6 +1525,7 @@ export const en = {
|
||||
}`,
|
||||
uploadCover: 'Import and Overwrite',
|
||||
refresh: 'Refresh Current Page',
|
||||
json_output: 'Support JSON formatted output',
|
||||
},
|
||||
userMemory: {
|
||||
userMemory: 'User Memory',
|
||||
@@ -2287,6 +2289,7 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re
|
||||
messagesPlaceholder: 'Write prompts here, type "{" to insert variables, type "insert" to insert',
|
||||
vision: 'Vision',
|
||||
parameterSettings: 'Parameter Settings',
|
||||
json_output: 'Support JSON formatted output',
|
||||
},
|
||||
start: {
|
||||
variables: 'Input Fields',
|
||||
|
||||
@@ -859,6 +859,7 @@ export const zh = {
|
||||
}`,
|
||||
uploadCover: '导入并覆盖',
|
||||
refresh: '刷新当前页',
|
||||
json_output: '支持JSON格式化输出',
|
||||
},
|
||||
table: {
|
||||
totalRecords: '共 {{total}} 条记录'
|
||||
@@ -1307,6 +1308,7 @@ export const zh = {
|
||||
video: '视频',
|
||||
thinking: '深度思考',
|
||||
is_thinking: '支持深度思考',
|
||||
json_output: '支持JSON格式化输出',
|
||||
},
|
||||
timezones: {
|
||||
'Asia/Shanghai': '中国标准时间 (UTC+8)',
|
||||
@@ -2248,6 +2250,7 @@ export const zh = {
|
||||
messagesPlaceholder: '在此处编写提示,输入“{”插入变量,输入“insert”插入',
|
||||
vision: '视觉',
|
||||
parameterSettings: '参数设置',
|
||||
json_output: '支持JSON格式化输出',
|
||||
},
|
||||
start: {
|
||||
variables: '输入字段',
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:28:07
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-31 16:56:57
|
||||
* @Last Modified time: 2026-04-16 18:51:01
|
||||
*/
|
||||
/**
|
||||
* Model Configuration Modal
|
||||
@@ -102,14 +102,15 @@ const ModelConfigModal = forwardRef<ModelConfigModalRef, ModelConfigModalProps>(
|
||||
}
|
||||
/** Handle model selection change */
|
||||
const handleChange: SelectProps['onChange'] = (_value, option) => {
|
||||
if (source === 'chat') {
|
||||
form.setFieldValue('label', (option as Model).name)
|
||||
}
|
||||
|
||||
form.setFieldsValue({
|
||||
const newValues: ModelConfig = {
|
||||
capability: (option as Model).capability,
|
||||
deep_thinking: false,
|
||||
})
|
||||
json_output: false
|
||||
}
|
||||
if (source === 'chat') {
|
||||
newValues.label = (option as Model).name
|
||||
}
|
||||
form.setFieldsValue(newValues)
|
||||
}
|
||||
|
||||
/** Expose methods to parent component */
|
||||
@@ -119,12 +120,10 @@ const ModelConfigModal = forwardRef<ModelConfigModalRef, ModelConfigModalProps>(
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
const { deep_thinking: _, ...rest } = data?.model_parameters || {}
|
||||
const { deep_thinking: _, json_output: __, ...rest } = data?.model_parameters || {}
|
||||
form.setFieldsValue(rest)
|
||||
}, [values?.default_model_config_id])
|
||||
|
||||
|
||||
console.log('handleChange values', values)
|
||||
return (
|
||||
<RbModal
|
||||
title={t('application.modelConfig')}
|
||||
@@ -159,6 +158,9 @@ const ModelConfigModal = forwardRef<ModelConfigModalRef, ModelConfigModalProps>(
|
||||
<FormItem name="deep_thinking" valuePropName="checked" hidden={!['model', 'chat'].includes(source) || !(values?.deep_thinking || values?.capability?.includes('thinking'))}>
|
||||
<Checkbox>{t('application.deep_thinking')}</Checkbox>
|
||||
</FormItem>
|
||||
<FormItem name="json_output" valuePropName="checked" hidden={!(values?.capability?.includes('json_output'))}>
|
||||
<Checkbox>{t('application.json_output')}</Checkbox>
|
||||
</FormItem>
|
||||
{source === 'chat' && <FormItem name="label" hidden />}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:29:49
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-04-07 15:46:19
|
||||
* @Last Modified time: 2026-04-16 18:20:14
|
||||
*/
|
||||
import type { KnowledgeConfig } from './components/Knowledge/types'
|
||||
import type { Variable } from './components/VariableList/types'
|
||||
@@ -24,20 +24,21 @@ export interface ModelConfig {
|
||||
default_model_config_id?: string;
|
||||
capability?: Capability[];
|
||||
/** Temperature for response randomness (0-2) */
|
||||
temperature: number;
|
||||
temperature?: number;
|
||||
/** Maximum tokens in response */
|
||||
max_tokens: number;
|
||||
max_tokens?: number;
|
||||
/** Top-p sampling parameter */
|
||||
top_p: number;
|
||||
top_p?: number;
|
||||
/** Frequency penalty */
|
||||
frequency_penalty: number;
|
||||
frequency_penalty?: number;
|
||||
/** Presence penalty */
|
||||
presence_penalty: number;
|
||||
presence_penalty?: number;
|
||||
/** Number of completions to generate */
|
||||
n: number;
|
||||
n?: number;
|
||||
/** Stop sequences */
|
||||
stop?: string;
|
||||
deep_thinking?: boolean;
|
||||
json_output?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:49:28
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-31 13:56:18
|
||||
* @Last Modified time: 2026-04-16 18:03:53
|
||||
*/
|
||||
/**
|
||||
* Custom Model Modal
|
||||
@@ -14,7 +14,7 @@ import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
|
||||
import { Form, Input, App, Checkbox, Button, Row, Col } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { CustomModelForm, ModelListItem, CustomModelModalRef, CustomModelModalProps } from '../types';
|
||||
import type { CustomModelForm, ModelListItem, CustomModelModalRef, CustomModelModalProps, Capability } from '../types';
|
||||
import RbModal from '@/components/RbModal'
|
||||
import CustomSelect from '@/components/CustomSelect'
|
||||
import UploadImages from '@/components/Upload/UploadImages'
|
||||
@@ -73,6 +73,7 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
|
||||
is_video: capability?.includes('video') || false,
|
||||
is_audio: capability?.includes('audio') || false,
|
||||
is_thinking: capability?.includes('thinking') || false,
|
||||
json_output: capability?.includes('json_output') || false,
|
||||
});
|
||||
} else {
|
||||
setIsEdit(false);
|
||||
@@ -102,13 +103,13 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
|
||||
form
|
||||
.validateFields()
|
||||
.then((values) => {
|
||||
const { logo, type, is_vision, is_video, is_audio, is_omni, is_thinking, ...rest } = values;
|
||||
const { logo, type, is_vision, is_video, is_audio, is_omni, is_thinking, json_output, ...rest } = values;
|
||||
const formData: CustomModelForm = {
|
||||
...rest,
|
||||
type,
|
||||
}
|
||||
if (!['embedding', 'rerank'].includes(type as string)) {
|
||||
let capability = is_omni ? ["vision", "audio", 'video'] : []
|
||||
let capability: Capability[] = is_omni ? ["vision", "audio", 'video'] : []
|
||||
|
||||
if (!is_omni) {
|
||||
if (is_vision) {
|
||||
@@ -124,6 +125,9 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
|
||||
if (is_thinking) {
|
||||
capability.push('thinking')
|
||||
}
|
||||
if (json_output) {
|
||||
capability.push('json_output')
|
||||
}
|
||||
|
||||
formData.capability = capability
|
||||
formData.is_omni = is_omni
|
||||
@@ -269,6 +273,11 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
|
||||
<Checkbox>{t('modelNew.is_thinking')}</Checkbox>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form.Item name="json_output" valuePropName="checked" className="rb:mb-0!">
|
||||
<Checkbox>{t('modelNew.json_output')}</Checkbox>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
</Form>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:50:18
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-03-31 15:48:02
|
||||
* @Last Modified time: 2026-04-16 18:04:46
|
||||
*/
|
||||
/**
|
||||
* Type definitions for Model Management
|
||||
@@ -296,6 +296,7 @@ export interface CustomModelForm {
|
||||
is_audio?: boolean;
|
||||
is_omni?: boolean;
|
||||
is_thinking?: boolean;
|
||||
json_output?: boolean;
|
||||
capability?: Capability[];
|
||||
}
|
||||
|
||||
@@ -325,7 +326,7 @@ export interface BaseRef {
|
||||
modelListDetailRefresh?: () => void;
|
||||
}
|
||||
|
||||
export type Capability = 'vision' | 'audio' | 'video' | 'thinking';
|
||||
export type Capability = 'vision' | 'audio' | 'video' | 'thinking' | 'json_output';
|
||||
export interface Model {
|
||||
name: string;
|
||||
type: string;
|
||||
|
||||
@@ -1,16 +1,38 @@
|
||||
import { type FC } from "react";
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-03-07 14:55:04
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-04-17 10:05:32
|
||||
*/
|
||||
import { type FC, useEffect, useState } from "react";
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Form } from 'antd'
|
||||
import { Form, Switch } from 'antd'
|
||||
|
||||
import RbSlider from '@/components/RbSlider'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import ModelSelect from '@/components/ModelSelect'
|
||||
import type { Model } from '@/views/ModelManagement/types';
|
||||
|
||||
const ModelConfig: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const form = Form.useFormInstance()
|
||||
const model_id = Form.useWatch(['model_id'], form)
|
||||
console.log('ModelConfig', model_id)
|
||||
const [selectedModel, setSelectedModel] = useState<Model | null>(null)
|
||||
const [options, setOptions] = useState<Model[]>([])
|
||||
|
||||
const updateOptions = (options: Model[]) => {
|
||||
setOptions(options)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (model_id && options) {
|
||||
const model = options.find(item => item.id === model_id)
|
||||
setSelectedModel(model || null)
|
||||
form.setFieldValue('json_output', false)
|
||||
} else {
|
||||
setSelectedModel(null)
|
||||
}
|
||||
}, [model_id, options])
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -25,6 +47,7 @@ const ModelConfig: FC = () => {
|
||||
params={{ type: 'llm,chat' }}
|
||||
className="rb:w-full!"
|
||||
size="small"
|
||||
updateOptions={updateOptions}
|
||||
/>
|
||||
</Form.Item>
|
||||
{model_id && (
|
||||
@@ -52,7 +75,7 @@ const ModelConfig: FC = () => {
|
||||
<Form.Item
|
||||
name="max_tokens"
|
||||
label={t('workflow.config.llm.max_tokens')}
|
||||
className="rb:mb-0!"
|
||||
className="rb:mb-1.5!"
|
||||
>
|
||||
<RbSlider
|
||||
min={256}
|
||||
@@ -63,6 +86,16 @@ const ModelConfig: FC = () => {
|
||||
className="rb:-mt-2!"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="json_output"
|
||||
valuePropName="checked"
|
||||
label={t('workflow.config.llm.json_output')}
|
||||
layout="horizontal"
|
||||
className="rb:mb-0!"
|
||||
hidden={!(selectedModel?.capability?.includes('json_output'))}
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
</RbCard>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 15:06:18
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-04-07 19:56:56
|
||||
* @Last Modified time: 2026-04-16 17:52:30
|
||||
*/
|
||||
import LoopNode from './components/Nodes/LoopNode';
|
||||
import NormalNode from './components/Nodes/NormalNode';
|
||||
@@ -101,6 +101,10 @@ export const nodeLibrary: NodeLibrary[] = [
|
||||
step: 1,
|
||||
defaultValue: 2000
|
||||
},
|
||||
json_output: {
|
||||
type: 'define',
|
||||
defaultValue: false
|
||||
},
|
||||
context: {
|
||||
type: 'variableList',
|
||||
placeholder: 'workflow.config.llm.contextPlaceholder'
|
||||
|
||||
Reference in New Issue
Block a user