mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 10:41:59 +00:00
277982ead3
- 蓝图:bp_* 操作和逐卡白名单、蓝图检查、留痕、按蓝图判权限;五个场景模板加自由形(骨架、关节、应用骨架、定时任务),实例化与骨架比对;BlueprintApplier / TemplateApplier(只收模板声明过的关节)与自查;look 新类别口径卡;蓝图对话和填关节两个流式接口,不同组的关节并行填、出错的组串行重试;模板列表 - 试运行与发布单:四种起点(对话、模板、问数据的一轮、已发布版本);试运行是探索运行,草稿应用按这次运行解析、印章写试运行,流程类派给自己、不触发升级;发布单九步、预检只读、每步留痕、停下后接着做、核对卡片指纹和应用管理权、启动时整理中断的单;白话层覆盖全部问题编号 - 记录表与文件:平台托管只追加的记录表、按高水位固定数据、连接上的临时视图做行级可见、写入走动作(records_append)、表版本在发布时切换、草稿不影响线上、记录列表遮敏感列;文件按哈希存、两步上传、提交时绑定运行、下载按读权限、清理、file_text、按配方导入一期(table_import_period) - 个人应用:存成个人应用(问数据的约束)、刷新(遮罩、只读、每日上限)、只有拥有者看得见、提交审核与共享副本、开关下发到认人接口;页面编辑的候选;隐藏组件不下发;三条新检查
85 lines
5.5 KiB
Python
85 lines
5.5 KiB
Python
"""开登录后 user 角色的问数据运行能用什么(D-c,§3.12「问数据、助手」那一行,Q2)。
|
||
|
||
管理员开了「使用者可以问数据」之后,user 角色经 POST /api/runs 发起的只能是问数据当场搭的探索运行(api/runs.py 的
|
||
start_run 先查来源和运行类别)。图本身再按这里收窄,理由是同一条:对 user 角色来说遮罩就是边界(A7 第 6 条),它能
|
||
碰的只有「读数据、整理、撰写」这一类,不能执行代码、不能调外部系统、不能写任何东西:
|
||
|
||
- 节点只许:输入、模型、Agent、报告、输出、知识库检索、数据整形、条件分支、口径卡、合并查询。调用工具(会写外部系统)、
|
||
代码、协作、子工作流、循环、人工审批、记忆写入、校验、双盲复算、反方审稿一律不许——后几种不是危险,而是问数据用不到,
|
||
多放一种就多一处要单独核对遮罩的地方;
|
||
- Agent 的工具只许数据源工具(db_query__ / db_schema__,查询结果按 MASK_RESULTS_OPTION 在工具边界遮)和只读的内置工具
|
||
(计算、当前时间、JSON 取值、知识库检索、记忆读取)。自定义工具、MCP、文件、网页、HTTP、代码执行一律不许;模板拼出来的
|
||
工具名({{ vars.tool }})发起时不知道是谁,也不许。数据源查询一律只读:可写源上的写语句由守卫拒掉,不交给审批(api/runs.py
|
||
给运行打上 READ_ONLY_OPTION)——Agent 的 approval 是发起人自己写在图里的,写成 never 就不问人了;
|
||
- 记忆范围、知识库不由发起人挑:记忆和知识库里的内容不经遮罩,搭建者的 Agent 存进去的查询原文,换个范围就读到了。
|
||
记忆固定为这位使用者自己的范围(chat_memory_scope;问数据里写不了记忆,它读到的只会是空的),知识库固定为设置里的
|
||
运行默认值。节点上、图级 defaults 里写了 memory_scope / collection 的图不许发起,请求体里带的同样拒(api/runs.py)。
|
||
|
||
没在这里列出的节点类型、工具,以后加了也默认不许(白名单),要放开得先想清楚遮罩怎么守。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
#: 问数据运行里 user 角色能用的节点类型(engine/schema.py 的 NodeType 取值)
|
||
CHAT_NODE_TYPES = frozenset({"input", "llm", "agent", "report", "output", "retrieve", "transform", "branch",
|
||
"metrics", "merge"})
|
||
#: Agent 能绑的只读内置工具(tools/builtin/)
|
||
CHAT_BUILTIN_TOOLS = frozenset({"calculator", "current_time", "json_query", "kb_search", "memory_recall"})
|
||
#: 运行时改记忆范围、知识库的配置键(engine/nodes 的 ctx.cfg("memory_scope") / ctx.cfg("collection"),图级 defaults 同样生效)
|
||
SCOPE_KEYS = ("memory_scope", "collection")
|
||
SCOPE_REFUSED = "没有权限:使用者在问数据中不能指定记忆范围和知识库,使用的是管理员设好的默认值"
|
||
|
||
|
||
def chat_memory_scope(actor: str | None) -> str:
|
||
"""user 角色问数据运行的记忆范围:每人一份,和搭建者的不相通。"""
|
||
return f"chat:{actor or 'anonymous'}"
|
||
|
||
|
||
def _tool_allowed(name: str) -> bool:
|
||
from app.tools.datasource import source_of_tool
|
||
|
||
return name in CHAT_BUILTIN_TOOLS or bool(source_of_tool(name))
|
||
|
||
|
||
def _set(value: Any) -> bool:
|
||
"""配置里填了值。和运行时 NodeContext.cfg 同一个规则:只有 None、空串算没填——全是空白的串运行时也照用。"""
|
||
return value not in (None, "")
|
||
|
||
|
||
def chat_graph_problem(graph: Any, *, where: str = "问数据") -> str | None:
|
||
"""这张图 user 角色能不能在问数据里运行:能用返回 None,不能用交回一句给人看的原因(403 的 detail)。
|
||
|
||
图不成形(GraphSpec 校验不过)时也返回 None:交给 launch_run 照常报校验问题——两边用的是同一个 GraphSpec,过不了
|
||
校验的图本来就发起不了。
|
||
|
||
where 是说法里的「在哪」:个人应用(blueprints/personal.py)用的是同一份白名单,只把「问数据」换成「个人应用」。"""
|
||
from app.engine.launch import tool_bindings
|
||
from app.engine.schema import GraphSpec, type_label
|
||
|
||
if not isinstance(graph, dict):
|
||
return None
|
||
try:
|
||
spec = GraphSpec.model_validate(graph)
|
||
except ValueError:
|
||
return None
|
||
scope_refused = SCOPE_REFUSED.replace("问数据", where)
|
||
if any(_set(spec.defaults.get(key)) for key in SCOPE_KEYS):
|
||
return scope_refused
|
||
for node in spec.nodes:
|
||
if str(node.type) not in CHAT_NODE_TYPES:
|
||
return (f"没有权限:使用者在{where}中不能使用「{type_label(node.type)}」节点(「{node.title}」)。"
|
||
"如需这类处理,请联系搭建者做成应用")
|
||
if any(_set(node.config.get(key)) for key in SCOPE_KEYS):
|
||
return f"{scope_refused}(「{node.title}」)"
|
||
for who, name in tool_bindings(spec):
|
||
if "{{" in name:
|
||
return f"没有权限:{who}的工具名由模板拼成,发起前无法确定是哪个工具,使用者在{where}中不能这样绑定工具"
|
||
if not _tool_allowed(name):
|
||
return (f"没有权限:{who}绑定了工具「{name}」。使用者在{where}中只能使用数据源查询和只读的内置工具"
|
||
"(计算、当前时间、JSON 取值、知识库检索、记忆读取)")
|
||
return None
|
||
|
||
|
||
__all__ = ["CHAT_BUILTIN_TOOLS", "CHAT_NODE_TYPES", "SCOPE_REFUSED", "chat_graph_problem", "chat_memory_scope"]
|