ForcePilot/src/agents/open_deep_research/configuration.py
Wenjie Zhang 7d4722b62c feat: 更新知识库相关配置
- 实现QA数据
- 优化现在创建知识库的体验
- 优化文件处理与加载方法
- 整体的格式检查与优化
- 优化 Embedding model 的加载逻辑,修复并行问题
- 优化整体的颜色布局
- 移除未使用的接口(前后端)
- 优化知识库的 chunk 逻辑
- 添加新的 Embedding模型支持
- 修复新建知识库后,Agent无法reload的问题
2025-07-26 03:36:54 +08:00

236 lines
7.5 KiB
Python

from pydantic import BaseModel, Field
from typing import Any, Optional
from langchain_core.runnables import RunnableConfig
import os
from enum import Enum
from src.agents.registry import BaseModelConfiguration
class SearchAPI(Enum):
ANTHROPIC = "anthropic"
OPENAI = "openai"
TAVILY = "tavily"
NONE = "none"
class MCPConfig(BaseModel):
url: str | None = Field(
default=None,
optional=True,
)
"""The URL of the MCP server"""
tools: list[str] | None = Field(
default=None,
optional=True,
)
"""The tools to make available to the LLM"""
auth_required: bool | None = Field(
default=False,
optional=True,
)
"""Whether the MCP server requires authentication"""
class OriConfiguration(BaseModel):
# General Configuration
max_structured_output_retries: int = Field(
default=3,
metadata={
"x_oap_ui_config": {
"type": "number",
"default": 3,
"min": 1,
"max": 10,
"description": "Maximum number of retries for structured output calls from models"
}
}
)
allow_clarification: bool = Field(
default=True,
metadata={
"x_oap_ui_config": {
"type": "boolean",
"default": True,
"description": "Whether to allow the researcher to ask the user clarifying questions before starting research"
}
}
)
max_concurrent_research_units: int = Field(
default=5,
metadata={
"x_oap_ui_config": {
"type": "slider",
"default": 5,
"min": 1,
"max": 20,
"step": 1,
"description": "Maximum number of research units to run concurrently. This will allow the researcher to use multiple sub-agents to conduct research. Note: with more concurrency, you may run into rate limits." # noqa: E501
}
}
)
# Research Configuration
search_api: SearchAPI = Field(
default=SearchAPI.TAVILY,
metadata={
"x_oap_ui_config": {
"type": "select",
"default": "tavily",
"description": "Search API to use for research. NOTE: Make sure your Researcher Model supports the selected search API.",
"options": [
{"label": "Tavily", "value": SearchAPI.TAVILY.value},
{"label": "OpenAI Native Web Search", "value": SearchAPI.OPENAI.value},
{"label": "Anthropic Native Web Search", "value": SearchAPI.ANTHROPIC.value},
{"label": "None", "value": SearchAPI.NONE.value}
]
}
}
)
max_researcher_iterations: int = Field(
default=3,
metadata={
"x_oap_ui_config": {
"type": "slider",
"default": 3,
"min": 1,
"max": 10,
"step": 1,
"description": "Maximum number of research iterations for the Research Supervisor. This is the number of times the Research Supervisor will reflect on the research and ask follow-up questions."
}
}
)
max_react_tool_calls: int = Field(
default=5,
metadata={
"x_oap_ui_config": {
"type": "slider",
"default": 5,
"min": 1,
"max": 30,
"step": 1,
"description": "Maximum number of tool calling iterations to make in a single researcher step."
}
}
)
# Model Configuration
summarization_model: str = Field(
default="openai:gpt-4.1-nano",
metadata={
"x_oap_ui_config": {
"type": "text",
"default": "openai:gpt-4.1-nano",
"description": "Model for summarizing research results from Tavily search results"
}
}
)
summarization_model_max_tokens: int = Field(
default=8192,
metadata={
"x_oap_ui_config": {
"type": "number",
"default": 8192,
"description": "Maximum output tokens for summarization model"
}
}
)
research_model: str = Field(
default="openai:gpt-4.1",
metadata={
"x_oap_ui_config": {
"type": "text",
"default": "openai:gpt-4.1",
"description": "Model for conducting research. NOTE: Make sure your Researcher Model supports the selected search API."
}
}
)
research_model_max_tokens: int = Field(
default=10000,
metadata={
"x_oap_ui_config": {
"type": "number",
"default": 10000,
"description": "Maximum output tokens for research model"
}
}
)
compression_model: str = Field(
default="openai:gpt-4.1-mini",
metadata={
"x_oap_ui_config": {
"type": "text",
"default": "openai:gpt-4.1-mini",
"description": "Model for compressing research findings from sub-agents. NOTE: Make sure your Compression Model supports the selected search API."
}
}
)
compression_model_max_tokens: int = Field(
default=8192,
metadata={
"x_oap_ui_config": {
"type": "number",
"default": 8192,
"description": "Maximum output tokens for compression model"
}
}
)
final_report_model: str = Field(
default="openai:gpt-4.1",
metadata={
"x_oap_ui_config": {
"type": "text",
"default": "openai:gpt-4.1",
"description": "Model for writing the final report from all research findings"
}
}
)
final_report_model_max_tokens: int = Field(
default=10000,
metadata={
"x_oap_ui_config": {
"type": "number",
"default": 10000,
"description": "Maximum output tokens for final report model"
}
}
)
# MCP server configuration
mcp_config: MCPConfig | None = Field(
default=None,
optional=True,
metadata={
"x_oap_ui_config": {
"type": "mcp",
"description": "MCP server configuration"
}
}
)
mcp_prompt: str | None = Field(
default=None,
optional=True,
metadata={
"x_oap_ui_config": {
"type": "text",
"description": "Any additional instructions to pass along to the Agent regarding the MCP tools that are available to it."
}
}
)
@classmethod
def from_runnable_config(
cls, config: RunnableConfig | None = None
) -> "Configuration":
"""Create a Configuration instance from a RunnableConfig."""
configurable = config.get("configurable", {}) if config else {}
field_names = list(cls.model_fields.keys())
values: dict[str, Any] = {
field_name: os.environ.get(field_name.upper(), configurable.get(field_name))
for field_name in field_names
}
return cls(**{k: v for k, v in values.items() if v is not None})
class Config:
arbitrary_types_allowed = True
class Configuration(BaseModelConfiguration, OriConfiguration):
pass