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
@@ -0,0 +1,63 @@
"""send_file:在对话/工作流场景下投递一份文件给用户。
regulatory_node 直接对话场景下用此工具把生成的文件发给用户:
- 工作流场景(带 trace_id):写入 data/artifact/<trace_id>/,前端通过 SSE
收到带下载链接的卡片。
- 直接对话场景(无 trace_id):退化为把文件内容拼回字符串返回给 agent,
让 agent 再以代码块形式吐给用户。
"""
import json
import re
import uuid
from pathlib import Path
from kilostar.utils.ray_hook import ray_actor_hook
from kilostar.utils.settings import get_artifact_dir
_SAFE_NAME_RE = re.compile(r"[^A-Za-z0-9._-]+")
def _sanitize_filename(name: str) -> str:
name = name.strip().replace("\\", "/").split("/")[-1]
name = _SAFE_NAME_RE.sub("_", name)
return name or "file"
async def send_file(filename: str, content: str, trace_id: str = "") -> str:
"""把 agent 生成的文件作为附件投递给用户。
Args:
filename: 文件名(含扩展名),如 "report.md" / "main.py"
content: 文件内容(UTF-8 文本)
trace_id: 当前会话/工作流的 trace_id;为空时退化为直接返回内容
Returns:
发送结果说明或文件内容
"""
if not trace_id:
return f"文件 {filename} 内容如下:\n\n```\n{content}\n```"
safe_name = _sanitize_filename(filename)
artifact_id = uuid.uuid4().hex[:12]
trace_dir: Path = get_artifact_dir() / trace_id
trace_dir.mkdir(parents=True, exist_ok=True)
file_path = trace_dir / f"{artifact_id}_{safe_name}"
file_path.write_text(content, encoding="utf-8")
payload = json.dumps(
{
"type": "file",
"filename": safe_name,
"artifact_id": artifact_id,
"url": f"/api/v1/resource/artifact/{trace_id}/{artifact_id}",
"size": len(content.encode("utf-8")),
},
ensure_ascii=False,
)
actor_list = ray_actor_hook("global_workflow_manager")
await actor_list.global_workflow_manager.put_pending.remote(
trace_id, f"__FILE__{payload}"
)
return f"已发送文件: {safe_name}"