"""需求操作名词表的单一来源,需求协议、提示词、能力检查和范围校验都引用这里""" # 模型可能使用的同义操作名,统一成词表中的标准名称;新增别名只改这里 OPERATION_ALIASES: dict[str, str] = { "restyle": "update", "change_type": "replace", "convert": "replace", } # 直接修改已有组件支持的操作,每一项都要有对应的动作规则 NODE_OPERATIONS: tuple[str, ...] = ("move", "resize", "update", "delete") # 直接修改画布支持的操作,最终都转换为 update_canvas 动作 CANVAS_OPERATIONS: tuple[str, ...] = ("update", "resize", "update_canvas") # 规划路径中,对已有组件做调整的操作;reflow、layout 表示整体重排,只走规划 PLAN_ADJUST_OPERATIONS: tuple[str, ...] = ( "move", "resize", "update", "reflow", "layout", ) # 只能通过规划完成的操作:新增要从物料目录选型并安排位置,重排要整体布局, # 更换组件类型实际是换成另一种物料,要从目录选型,不能靠修改属性完成 PLAN_ONLY_OPERATIONS: tuple[str, ...] = ("add", "reflow", "layout", "replace") # 写进协议描述和提示词的操作说明,词表变化时自动同步 OPERATION_GUIDE = ( f"修改已有组件用 {'、'.join(NODE_OPERATIONS)}," "修改画布用 update 或 resize,新增用 add;" "更换已有组件的类型(如折线图改饼图)用 replace,目标类型写入 parameters,不用 update;" "颜色、背景、文字等样式和属性修改统一用 update,具体内容写入 parameters" ) def normalize_operation(operation: str) -> str: """把同义操作名转换成标准名称,未登记的名称原样返回""" return OPERATION_ALIASES.get(operation, operation) def is_direct_operation(target_scope: str, operation: str) -> bool: """判断是否为无需规划即可直接转换为动作的操作""" if target_scope == "nodes": return operation in NODE_OPERATIONS if target_scope == "canvas": return operation in CANVAS_OPERATIONS return False def requires_planning(target_scope: str, operation: str) -> bool: """判断是否必须先规划;未登记的操作不在此列,由能力检查判为不支持""" return not is_direct_operation(target_scope, operation) and ( operation in PLAN_ONLY_OPERATIONS ) def is_canvas_operation(target_scope: str, operation: str) -> bool: """判断是否为画布属性修改""" return target_scope == "canvas" and operation in CANVAS_OPERATIONS