feat:接入mcp,为模型提供图表信息
This commit is contained in:
+48
-21
@@ -53,6 +53,46 @@ REPAIR_TASK_PROMPT = """# 当前阶段:修正重试
|
||||
"""
|
||||
|
||||
|
||||
FIELD_QUERY_PROMPT = """# 查询组件字段
|
||||
field_groups 按物料类型列出本次相关组件的字段分组,节点的 type 就是物料类型
|
||||
确定要改的字段:用用户原话中对属性的说法(input_context 中的提问,不用改写后的需求)调用 search_fields;
|
||||
返回多个字段时,依据字段说明判断用户指的是哪一个;用户看的是大屏画面,没有提到图层列表、属性面板等编辑器位置时,按画面上看得到的内容理解
|
||||
需要了解一组相关字段时用 get_fields,一次可查多个分组
|
||||
只能使用查询到的字段路径,值须符合字段的类型、可选值和取值范围;查不到对应字段说明不支持,不自行编造路径
|
||||
"""
|
||||
|
||||
# 这些动作会写组件属性,需要先查物料字段
|
||||
FIELD_ACTIONS = frozenset({"update", "add"})
|
||||
|
||||
|
||||
def action_types(requirement: Requirement, screen_plan: ScreenPlan | None) -> set[str]:
|
||||
"""本次需要的动作类型:简单修改按需求变更,规划按各组件的处理方式"""
|
||||
if screen_plan is None:
|
||||
return {
|
||||
"update_canvas" if change.target_scope == "canvas" else change.operation
|
||||
for change in requirement.changes
|
||||
}
|
||||
types = set()
|
||||
if screen_plan.canvas_changes:
|
||||
types.add("update_canvas")
|
||||
for item in screen_plan.components:
|
||||
if item.disposition in ("add", "replace"):
|
||||
types.add("add")
|
||||
elif item.disposition == "remove":
|
||||
types.add("delete")
|
||||
elif item.disposition == "modify":
|
||||
types.update(("move", "resize"))
|
||||
if item.design:
|
||||
types.add("update")
|
||||
return types
|
||||
|
||||
|
||||
def uses_material_fields(
|
||||
requirement: Requirement, screen_plan: ScreenPlan | None
|
||||
) -> bool:
|
||||
return bool(action_types(requirement, screen_plan) & FIELD_ACTIONS)
|
||||
|
||||
|
||||
def build_action_prompt(
|
||||
requirement: Requirement,
|
||||
screen_plan: ScreenPlan | None = None,
|
||||
@@ -60,40 +100,27 @@ def build_action_prompt(
|
||||
repairing: bool = False,
|
||||
) -> str:
|
||||
"""只组合本次任务需要的规则,不改变 Schema 或后端校验范围"""
|
||||
types = action_types(requirement, screen_plan)
|
||||
sections = [ACTION_SYSTEM_PROMPT]
|
||||
if screen_plan is None:
|
||||
sections.append(SIMPLE_TASK_PROMPT)
|
||||
action_types = {
|
||||
"update_canvas" if change.target_scope == "canvas" else change.operation
|
||||
for change in requirement.changes
|
||||
}
|
||||
else:
|
||||
sections.append(PLAN_TASK_PROMPT)
|
||||
action_types = set()
|
||||
dispositions = {item.disposition for item in screen_plan.components}
|
||||
if screen_plan.canvas_changes:
|
||||
sections.append(
|
||||
"## 调整画布\n将 canvas_changes 中的最终属性值转换为 update_canvas,完整覆盖且不添加其他画布字段"
|
||||
)
|
||||
action_types.add("update_canvas")
|
||||
if any(item.disposition == "add" for item in screen_plan.components):
|
||||
action_types.add("add")
|
||||
if any(item.disposition == "replace" for item in screen_plan.components):
|
||||
if "replace" in dispositions:
|
||||
sections.append(REPLACE_PLAN_PROMPT)
|
||||
action_types.add("add")
|
||||
if any(item.disposition == "remove" for item in screen_plan.components):
|
||||
action_types.add("delete")
|
||||
modifications = [
|
||||
item for item in screen_plan.components if item.disposition == "modify"
|
||||
]
|
||||
if modifications:
|
||||
if "modify" in dispositions:
|
||||
sections.append(MODIFY_PLAN_PROMPT)
|
||||
action_types.update(("move", "resize"))
|
||||
if any(item.design for item in modifications):
|
||||
action_types.add("update")
|
||||
if types & FIELD_ACTIONS:
|
||||
sections.append(FIELD_QUERY_PROMPT)
|
||||
|
||||
# 排序保证提示词顺序稳定,缺少动作说明时直接报错,避免静默遗漏
|
||||
sections.append("# 本次可用动作\n" + "、".join(sorted(action_types)))
|
||||
sections.extend(ACTION_RULES[name] for name in sorted(action_types))
|
||||
sections.append("# 本次可用动作\n" + "、".join(sorted(types)))
|
||||
sections.extend(ACTION_RULES[name] for name in sorted(types))
|
||||
if repairing:
|
||||
sections.append(REPAIR_TASK_PROMPT)
|
||||
return "\n\n".join(section.strip() for section in sections)
|
||||
|
||||
@@ -21,13 +21,11 @@ properties 只包含需要修改的画布顶层字段,宽高为最终绝对值
|
||||
不需要改变的尺寸省略,不改变组件位置
|
||||
""",
|
||||
"update": """## update:更新已有组件属性
|
||||
依据快照选择 props / style 下的字段路径,不猜测不存在的嵌套结构
|
||||
path 中字符串是对象键,整数是数组下标;中间路径必须存在,数组下标不能越界
|
||||
只替换指定字段,不做深度合并;null 表示赋值,不表示删除
|
||||
提供 editable_fields 时,它是该组件属性面板的字段:用户说的名称(如名字、标题、颜色)优先对应 label 相符的字段,使用其 section 和 path
|
||||
props 第一层只能使用组件已有或物料默认配置中的字段,不新造组件级属性;更深层的配置可以按需新增
|
||||
字段路径的第一段写入 section(name / props / style),其余各段写入 path,数字段写成整数下标;name 的 path 为空列表
|
||||
例如字段 props.option.title.text 写成 section=props、path=["option", "title", "text"]
|
||||
layout 字段不用 update:位置用 move,尺寸用 resize
|
||||
只替换指定字段,不做深度合并;组件中还没有的中间对象由后端补齐
|
||||
不通过修改属性改变组件类型(如把 series 的 type 改成其他图表类型),组件类型由节点 type 和物料决定
|
||||
style 为 null 时可用单层路径添加属性,保留未要求修改的配置
|
||||
""",
|
||||
"add": """## add:按物料新增组件
|
||||
每个 add 规划对应一个新增动作,用 plan_id 关联规划,component_key 选择 component_materials 中的物料
|
||||
|
||||
@@ -15,6 +15,7 @@ REFLECTION_SYSTEM_PROMPT = f"""## 任务
|
||||
需要用户补充、外部资源或尚未支持的能力时,retryable=false,说明缺少什么
|
||||
{DATA_BINDING_GUIDE}
|
||||
因数据绑定校验失败时,去掉 dataId 并保留物料示例数据即可修正,retryable=true
|
||||
字段错误(field_error)时,查询字段定义,建议改用查到的字段路径或合法取值;物料没有能满足需求的字段时,retryable=false
|
||||
|
||||
## 边界
|
||||
保持需求和规划范围,不通过遗漏需求、猜测字段或替换用户意图来绕过错误
|
||||
|
||||
Reference in New Issue
Block a user