feat:接入mcp,为模型提供图表信息

This commit is contained in:
2026-10-01 06:33:44 -07:00
parent 618290d852
commit f1b2a70ad1
44 changed files with 6531 additions and 207 deletions
+35 -15
View File
@@ -3,9 +3,37 @@
from copy import deepcopy
from app.actions.base import BaseActionHandler
from app.resources.material_fields import editable_fields, known_prop_keys
from app.schemas.actions import UpdateAction
from app.schemas.screen import Screen
from app.schemas.screen import Screen, ScreenNode
def fit_existing_path(node: ScreenNode, action: UpdateAction) -> UpdateAction:
"""字段定义允许的路径在组件中可能还没有中间对象(例如未开启过的数值标签)
前端只按已有路径赋值,这里把缺失的部分折叠进值里:改为更新最近的已有对象,
值为补齐的嵌套对象;缺失的若是数组元素则无法补齐,保持原样交给执行时报错
"""
if action.section == "name":
return action
current = getattr(node, action.section) or {}
for index, segment in enumerate(action.path[:-1]):
if isinstance(current, dict) and isinstance(segment, str) and segment not in current:
rest = action.path[index + 1 :]
if not all(isinstance(item, str) for item in rest):
return action
value = action.value
for item in reversed(rest):
value = {item: value}
return action.model_copy(
update={"path": action.path[: index + 1], "value": value}
)
if isinstance(current, dict) and isinstance(segment, str):
current = current[segment]
elif isinstance(current, list) and type(segment) is int and segment < len(current):
current = current[segment]
else:
return action
return action
class UpdateHandler(BaseActionHandler[UpdateAction]):
@@ -13,23 +41,15 @@ class UpdateHandler(BaseActionHandler[UpdateAction]):
# 确认目标存在,后续路径访问和赋值均在大屏副本中进行
result, target = self.copy_target(screen, action.target_id)
# 组件名称是节点顶层字段,没有后续路径
if action.section == "name":
target.name = action.value
return result
# 未设置的 style 视为空对象,只允许直接添加末级字段
if action.section == "style" and target.style is None:
target.style = {}
# props 第一层不能新造字段:渲染器不会读取约定外的字段,新造只会“成功”却没有效果
if action.section == "props":
known = known_prop_keys(target)
if known is not None and action.path[0] not in known:
labels = "、".join(
f"{field['label']}={field['section']}.{field['path']}"
for field in editable_fields(target.type)
)
raise ValueError(
f"组件 {target.type} 的 props 没有字段 {action.path[0]!r},"
f"不能新造组件级属性;可编辑字段:{labels or '无'}"
)
# 获取动作指定的属性区域,作为路径遍历的起点
current = getattr(target, action.section)
# 逐段访问路径,只有到达末级时才写入新值