mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 02:51:58 +00:00
941723b17c
- 身份与工具:登录页建第一个管理员(认人接口的 401 说明能不能建);搭建者有只读的人和组名录,选人给候选并核对名字;授权三行带标题;端点请求头名校验(空名、非法名存不进、发不出时说清原因);写入能力在工具页试运行一律演练、不发送,HTTP 状态照实说成败;写记忆不算只读、查询能力只能选同一端点上的只读能力;审批与遮罩的说法和实际规则一致;开登录时不要署名、导入和发布记登录的人;使用者不显示推演等只给搭建者的操作,403 按是否开登录说话;登录页只认一次人 - 流程与实例:图里用到的岗位(派给谁、超时升级给谁、发送确认派给谁)全部派生、没绑人的发布时报错;写外部系统的参数按能力声明的类型收拢后再算哈希和发送,收不成就不发;发起人的实例页只看这一步的状态,处理人才给待办卡;会签进度带登录核实和时间,升级后照实写规则;实例状态写流程的结论(已退回、未确认、等待核实写入结果),核实生效后不再挂失败原因;流程应用首页不派生最近封存运行的结果块,看板没数据时是安静的空态;样例⑩的金额带类型和下限、待办标题带金额,表单上下限前后端一起生效 - 看板与证据:定时任务模板加 ISO 周、上一 ISO 周、本月、上月;出处链穿过原样解析查询结果的整形节点,追不到原始数据的照实说停在哪里,样例⑨改用 cell();应用首页和版本历史都能做成应用;指标块单位不重复;版本列表带退役说明;定时任务页头跟着刷新;删视图要确认、新视图能起名;编辑器属性用中文名、术语带解释 - 指标出具(用户 2026-10-15 拍板):契约只写「指标来自」、上游没有报告撰写节点、成果里没有模型写的话时按指标出具——必需指标齐、指标输入追到原始数据、成果字段里的数回指得上才完整出具;受管级要求每个指标静态地追到原始数据(governed.metric_untraced);出具横幅和应用印章写明按指标 - 受管工作流降为已发布只给管理员(Q8 顺延,服务端同样拦);工作流接口带当前发布版的级别,画布上改过之后也认得出受管工作流
114 lines
7.8 KiB
Python
114 lines
7.8 KiB
Python
"""受信组件目录 v1(docs/design/app-platform-and-look.md §2.2、§3.5)。
|
||
|
||
一份目录,四个使用方:应用页、人工节点表单、agent 拟的询问、助手生成。模型只能从这里挑组件;前端只有一张
|
||
「名字 → 渲染器」的表,遇到不认识的组件显示「此组件需要更新前端」,不报错、不空白。
|
||
|
||
每个组件登记:名字、中文名、类别、版本、props 的 JSON Schema、允许的绑定种类、能不能有子组件。
|
||
props 里每一项都写 title(属性面板上的中文名),取值不直观的另写 description;枚举写 x-enum-labels(和 enum 按位置
|
||
对应,同表单 agentlab.form/1 的写法)。这几样是注解,不参与校验。
|
||
服务端校验器和解析器由 app/apps/ 的实现按名字注册(BE-3);开发者扩展组件时,目录项、校验器、解析器、前端渲染器
|
||
四样都要给,缺一样启动即报错(check_registry)。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
CATEGORIES = ("layout", "display", "input", "process")
|
||
CATEGORY_LABEL = {"layout": "布局", "display": "展示", "input": "输入", "process": "流程"}
|
||
|
||
|
||
def _props(**properties: Any) -> dict[str, Any]:
|
||
return {"type": "object", "additionalProperties": False, "properties": properties}
|
||
|
||
|
||
def _text(title: str, **more: Any) -> dict[str, Any]:
|
||
return {"type": "string", "maxLength": 200, "title": title, **more}
|
||
|
||
|
||
def _long(title: str) -> dict[str, Any]:
|
||
return {"type": "string", "maxLength": 4000, "title": title}
|
||
|
||
|
||
def _enum(title: str, **labels: str) -> dict[str, Any]:
|
||
"""枚举:值是键,中文是 x-enum-labels(按位置对应)。"""
|
||
return {"enum": list(labels), "x-enum-labels": list(labels.values()), "title": title}
|
||
|
||
|
||
_CHART = _enum("图形", line="折线图", bar="柱状图")
|
||
|
||
COMPONENTS: list[dict[str, Any]] = [
|
||
# ---- 布局 ----
|
||
{"name": "page", "label": "页面", "category": "layout", "version": 1, "children": True, "bindings": [],
|
||
"props": _props(title=_text("标题"))},
|
||
{"name": "section", "label": "分区", "category": "layout", "version": 1, "children": True, "bindings": [],
|
||
"props": _props(title=_text("标题"), description=_long("说明"))},
|
||
{"name": "columns", "label": "分栏", "category": "layout", "version": 1, "children": True, "bindings": [],
|
||
"props": _props(count={"type": "integer", "minimum": 1, "maximum": 4, "title": "列数"})},
|
||
{"name": "tabs", "label": "页签", "category": "layout", "version": 1, "children": True, "bindings": [],
|
||
"props": _props(labels={"type": "array", "items": {"type": "string", "maxLength": 200}, "maxItems": 8,
|
||
"title": "页签名", "description": "按顺序对应里面的子组件"})},
|
||
{"name": "divider", "label": "分隔线", "category": "layout", "version": 1, "children": False, "bindings": [],
|
||
"props": _props()},
|
||
# ---- 展示 ----
|
||
{"name": "stamp", "label": "印章", "category": "display", "version": 1, "children": False,
|
||
"bindings": ["run"], "props": _props(compact={"type": "boolean", "title": "紧凑显示"})},
|
||
{"name": "metric", "label": "指标块", "category": "display", "version": 1, "children": False,
|
||
"bindings": ["metric", "cell"],
|
||
"props": _props(label=_text("名称"),
|
||
unit=_text("单位", description="绑定单元格时写在数下面;绑定指标时数里已经带着口径卡的单位"),
|
||
conv=_text("换算", description="万、亿、pct(百分比)、int(取整)或 .N(保留 N 位小数)"))},
|
||
{"name": "series", "label": "趋势", "category": "display", "version": 1, "children": False,
|
||
"bindings": ["series"], "props": _props(label=_text("名称"), chart=_CHART)},
|
||
{"name": "table", "label": "表格", "category": "display", "version": 1, "children": False,
|
||
"bindings": ["query"],
|
||
"props": _props(title=_text("标题"),
|
||
columns={"type": "array", "items": {"type": "string", "maxLength": 200}, "title": "显示的列",
|
||
"description": "列名,不填显示全部列"},
|
||
sort={"type": "string", "title": "排序列", "description": "按哪一列排序,写列名;前面加「-」为降序"},
|
||
limit={"type": "integer", "minimum": 1, "title": "最多显示行数"})},
|
||
{"name": "chart", "label": "图表", "category": "display", "version": 1, "children": False,
|
||
"bindings": ["query"],
|
||
"props": _props(title=_text("标题"), chart=_CHART, x=_text("横轴列"),
|
||
y={"type": "array", "items": {"type": "string", "maxLength": 200}, "maxItems": 4,
|
||
"title": "纵轴列", "description": "最多 4 列"})},
|
||
{"name": "report", "label": "报告", "category": "display", "version": 1, "children": False,
|
||
"bindings": ["report"], "props": _props(title=_text("标题"))},
|
||
{"name": "text", "label": "文字", "category": "display", "version": 1, "children": False, "bindings": [],
|
||
"props": _props(markdown=_long("正文(Markdown)"))},
|
||
{"name": "notice", "label": "提示", "category": "display", "version": 1, "children": False, "bindings": [],
|
||
"props": _props(text=_long("提示文字"), tone=_enum("样式", info="说明", warn="提醒", error="错误"))},
|
||
{"name": "field", "label": "字段", "category": "display", "version": 1, "children": False,
|
||
"bindings": ["input", "output", "run"], "props": _props(label=_text("名称"))},
|
||
{"name": "status", "label": "状态", "category": "display", "version": 1, "children": False,
|
||
"bindings": ["run"], "props": _props(label=_text("名称"))},
|
||
# ---- 输入 ----
|
||
{"name": "form", "label": "表单", "category": "input", "version": 1, "children": False, "bindings": [],
|
||
"props": _props(form={"type": "string", "title": "表单"}, submit_label=_text("提交按钮文字"))},
|
||
# ---- 流程 ----
|
||
{"name": "entry_button", "label": "发起按钮", "category": "process", "version": 1, "children": False,
|
||
"bindings": [], "props": _props(entry={"type": "string", "title": "入口"}, label=_text("按钮文字"))},
|
||
{"name": "instance_list", "label": "实例列表", "category": "process", "version": 1, "children": False,
|
||
"bindings": [], "props": _props(entry={"type": "string", "title": "入口"},
|
||
who=_enum("显示谁的", mine="我发起的", all="全部实例"),
|
||
limit={"type": "integer", "minimum": 1, "maximum": 200, "title": "最多显示几条"})},
|
||
{"name": "instance_header", "label": "实例概况", "category": "process", "version": 1, "children": False,
|
||
"bindings": [], "props": _props()},
|
||
{"name": "instance_timeline", "label": "实例进度", "category": "process", "version": 1, "children": False,
|
||
"bindings": [], "props": _props()},
|
||
{"name": "task_list", "label": "待办列表", "category": "process", "version": 1, "children": False,
|
||
"bindings": [], "props": _props(scope=_enum("范围", mine="派给我的", instance="本实例的"))},
|
||
{"name": "task_form", "label": "待办表单", "category": "process", "version": 1, "children": False,
|
||
"bindings": ["task"], "props": _props()},
|
||
{"name": "signoffs", "label": "会签进度", "category": "process", "version": 1, "children": False,
|
||
"bindings": ["task"], "props": _props()},
|
||
{"name": "action_status", "label": "动作状态", "category": "process", "version": 1, "children": False,
|
||
"bindings": ["action"], "props": _props(label=_text("名称"))},
|
||
]
|
||
|
||
BY_NAME: dict[str, dict[str, Any]] = {c["name"]: c for c in COMPONENTS}
|
||
|
||
|
||
def catalog_payload() -> dict[str, Any]:
|
||
"""GET /api/apps/catalog 的返回:组件目录 + 类别名。助手生成时也给模型看这一份(只给名字、中文名、props、绑定)。"""
|
||
return {"version": 1, "categories": CATEGORY_LABEL, "components": COMPONENTS}
|