feat: Provider model_settings 全链路 + 监管节点工具集 + 重型插件注入 + 前端打磨

- Provider model_settings (Provider+Model 级别参数配置): DB JSONB → API → GSM → AgentFactory.resolve → 三节点 agent.run 注入
- 新增 data/toolset/regulatory_toolset/: 监管节点专属工具(query_workflow_status / query_task_list / send_file)
- send_file 从 interactive_toolset 迁移至 regulatory_toolset,interactive 仅保留 approval
- mcp_helper 合入 GlobalPluginManager dispatch tools
- 前端 Provider 弹窗参数设置区加 JSON 编辑器(model_settings)
- 前端 Plugin 页面新增"重型插件"Tab(HeavyPluginList 占位)
- .gitignore 精简:去除系统默认项,修复 data/ 子目录追踪
- data/toolset/ 与 data/plugin/ 首次纳入版本控制

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 13:10:31 +00:00
parent 6d658b4f4d
commit 005ce566a8
49 changed files with 1093 additions and 30 deletions
@@ -184,6 +184,7 @@ class GlobalStateMachine:
provider_url,
provider_apikey,
provider_owner,
model_settings=None,
):
"""新增一个模型 Provider:内存注册 + 数据库持久化一并完成。"""
result = await self._global_provider_manager.add_provider(
@@ -193,6 +194,7 @@ class GlobalStateMachine:
provider_apikey=provider_apikey,
provider_owner=provider_owner,
postgres_database=self.postgres_database,
model_settings=model_settings or {},
)
self._publish_snapshot()
return result
@@ -13,8 +13,8 @@
# limitations under the License.
from abc import ABC, abstractmethod
from pydantic import BaseModel
from typing import List
from pydantic import BaseModel, Field
from typing import Any, Dict, List
from enum import Enum
@@ -35,6 +35,7 @@ class Provider(BaseModel):
provider_type: str
provider_owner: str | None = None
provider_status: ProviderStatus = ProviderStatus.UP
model_settings: Dict[str, Dict[str, Any]] = Field(default_factory=dict)
class ProviderArgs(BaseModel):
@@ -44,6 +45,7 @@ class ProviderArgs(BaseModel):
provider_url: str
provider_apikey: str
provider_owner: str
model_settings: Dict[str, Dict[str, Any]] = Field(default_factory=dict)
class BaseProvider(ABC):
@@ -78,4 +78,5 @@ class ClaudeProvider(BaseProvider):
provider_url=provider_args.provider_url,
provider_models=provider_models,
provider_type="claude",
model_settings=provider_args.model_settings,
)
@@ -81,4 +81,5 @@ class DeepseekProvider(BaseProvider):
provider_url=provider_args.provider_url,
provider_models=provider_models,
provider_type="deepseek",
model_settings=provider_args.model_settings,
)
@@ -78,4 +78,5 @@ class GeminiProvider(BaseProvider):
provider_url=provider_args.provider_url,
provider_models=provider_models,
provider_type="gemini",
model_settings=provider_args.model_settings,
)
@@ -81,4 +81,5 @@ class OpenAIProvider(BaseProvider):
provider_url=provider_args.provider_url,
provider_models=provider_models,
provider_type="openai",
model_settings=provider_args.model_settings,
)
@@ -58,6 +58,7 @@ class ProviderManager:
provider_apikey,
provider_owner,
postgres_database,
model_settings=None,
) -> None:
"""新增并落库一个 Provider
@@ -77,6 +78,7 @@ class ProviderManager:
provider_url=provider_url,
provider_apikey=provider_apikey,
provider_owner=provider_owner,
model_settings=model_settings or {},
)
try:
import ulid
@@ -96,6 +98,7 @@ class ProviderManager:
provider_models=provider.provider_models,
provider_type=provider.provider_type,
provider_owner=provider.provider_owner,
model_settings=provider.model_settings,
)
logger.info(f"已添加适配器{provider_title}")
@@ -40,6 +40,7 @@ class ConsciousnessNode:
self.logger = get_logger("consciousness_node")
self.agent: None | Agent = None
self.locale: str = "zh"
self._model_settings: dict = {}
async def create_agent(
self,
@@ -73,6 +74,7 @@ class ConsciousnessNode:
tools=tools,
toolsets=toolsets,
)
self._model_settings = AgentFactory.resolve_model_settings(provider, model_id)
@self.agent.system_prompt
async def dynamic_prompt(ctx: RunContext[ConsciousnessNodeDeps]):
@@ -221,7 +223,7 @@ class ConsciousnessNode:
)
self.logger.debug("ConsciousnessNode: 开始生成工作流 (原生重试开启)")
prompt = "根据original_command制定严密的可执行workflow"
result = await self.agent.run(prompt, deps=deps)
result = await self.agent.run(prompt, deps=deps, model_settings=self._model_settings or None)
return result.output
elif isinstance(payload, ForWorkflowInput):
@@ -236,6 +238,7 @@ class ConsciousnessNode:
result = await self.agent.run(
f"处理此工作流步骤信息:\n{payload.workflow_step.model_dump_json()}",
deps=deps,
model_settings=self._model_settings or None,
)
return result.output
@@ -251,6 +254,7 @@ class ConsciousnessNode:
result = await self.agent.run(
f"基于以下工作流的执行记录,生成技术报告:\n{payload.workflow.model_dump_json()}",
deps=deps,
model_settings=self._model_settings or None,
)
return result.output
except Exception as e:
@@ -38,6 +38,7 @@ class ControlNode:
self.logger = get_logger("control_node")
self.agent: Agent | None = None
self._model_settings: dict = {}
async def create_agent(
self,
@@ -87,6 +88,7 @@ class ControlNode:
tools=callables,
toolsets=toolsets,
)
self._model_settings = AgentFactory.resolve_model_settings(provider, model_id)
@self.agent.system_prompt
async def dynamic_prompt(ctx: RunContext[ControlNodeDeps]):
@@ -121,6 +123,7 @@ class ControlNode:
result = await self.agent.run(
f"请根据提供的 workflow_step 上下文,执行此步骤并输出结果。\n详细指令或附加数据:{payload.workflow_step.model_dump_json()}",
deps=deps,
model_settings=self._model_settings or None,
)
return result.output
except Exception as e:
@@ -40,6 +40,7 @@ class RegulatoryNode:
self.logger = get_logger("regulatory_node")
self.agent: None | Agent = None
self._model_settings: dict = {}
async def create_agent(
self,
@@ -88,6 +89,7 @@ class RegulatoryNode:
tools=tools,
toolsets=toolsets,
)
self._model_settings = AgentFactory.resolve_model_settings(provider, model_id)
@self.agent.system_prompt
async def dynamic_prompt(ctx: RunContext[RegulatoryNodeDeps]):
@@ -178,6 +180,7 @@ class RegulatoryNode:
instructions=self._CHAT_INSTRUCTIONS,
event_stream_handler=_stream_handler,
message_history=message_history,
model_settings=self._model_settings or None,
)
except Exception as e:
self.logger.exception(f"RegulatoryNode.stream_working failed: {e}")
@@ -204,6 +207,7 @@ class RegulatoryNode:
user_prompt=message,
deps=deps,
message_history=message_history,
model_settings=self._model_settings or None,
)
response: MessageResponse = agent_response.output
response.platform = platform
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List, Optional
from typing import Any, Dict, List, Optional
from sqlalchemy import String, Text, Boolean, text
from sqlalchemy.dialects.postgresql import JSONB # 针对供应商模型列表优化
from sqlalchemy.orm import Mapped, mapped_column
@@ -41,3 +41,8 @@ class ProviderModel(BaseDataModel):
server_default=text("true"),
comment="该服务商节点是否在线/启用",
)
model_settings: Mapped[Optional[Dict[str, Any]]] = mapped_column(
JSONB,
nullable=True,
comment="模型调用参数:{model_id 或 __default__: ModelSettings dict}",
)
@@ -69,6 +69,7 @@ class ProviderDatabase:
provider_type=provider.provider_type,
provider_owner=provider.provider_owner,
is_active=provider.is_active,
model_settings=provider.model_settings,
)
for provider in results
]