OpenMAIC 页面克隆(page-clone)指南:Copy-then-Edit 设计复用实战
OpenMAIC 页面克隆page-clone指南Copy-then-Edit 设计复用实战【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC克隆页面的技术就是把课程里某一页已经存在的好设计原样复制一份再把新内容装进去而不重画任何一笔。本文基于 OpenMAIC Agent Runtime 中的page-clone技能skills/agent-runtime/page-clone/SKILL.md系统讲解这条唯一的克隆路径——duplicate_scene复制 patch_stage逐槽位改写——包括完整调用序列、每个改动应当落在哪个 JSON 路径、内容装不下时的四种取舍以及结束页面时如何补旁白并扫除模板残留。读完你就能在不触碰设计的前提下把任意一页已有页面无论来自导入的 PPTX 还是课程先前自己写的页面安全地克隆出多页新内容。为什么克隆必须先复制、再编辑page-clone的核心前提是一句话设计已经存在于另一页上你的工作是把新内容放进那个设计里而不是重画它。这个 Runtime 里只有一条克隆路径即复制后再编辑其他任何方式都不会得到你想要的结果。原因在于generate_scene的工作方式。从实现看generate_scene每次都会根据该页的 outline 条目重新生成整棵元素树见 lib/server/agent-runtime/generation-tools.ts模型每次都会凭空发明一套新元素树。因此如果你对一个刚复制出来的页面调用generate_scene你恰恰会毁掉你当初想保留的那个设计。此外克隆路径没有任何形状校验——设计之所以被保留是因为你复制了它至于哪些元素是内容、哪些是骨架这个判断完全由 Agent 自己负责。从工具注册表也能看到这条纪律被代码层明确固化在 lib/agent-runtime/stage-writer-tools.ts 的STAGE_WRITER_TOOL_NAMES集合中duplicate_scene与generate_scene、patch_stage、generate_actions、generate_tts、edit_deck并列都是写文档类工具——这些写操作在服务器端被标记为executionMode: sequential避免并行写者互相覆盖有专门的测试固定这一关联。克隆六步序列page-clone规定的完整克隆流程是六个步骤按顺序执行、一次只处理一页第 1 步duplicate_scene复制模板页调用duplicate_scene({ templateSceneId, targetOrder, title })在目标位置得到模型页的精确副本。templateOrder也能用但传 id 更安全。复制出来的页面携带完整内容、没有旁白动作actions 为空并且获得一条新的 outline 条目。title参数必须用于命名新页面条目会继承模型页的 brief如果一个副本还叫「第 3 章回顾」那会同时误导学习者和后续的旁白生成步骤。看源码实现generation-tools.ts能确认更多细节参数定义为DuplicateParamsstageId必填、templateSceneId/templateOrder二选一优先用 id、targetOrder整数最小 1必填、title可选。新页面的 id 由duplicateId(sessionId, callId)计算scene-dup-前缀 SHA-256 摘要前 16 位因此重复调用同一工具调用是幂等的——重放时直接返回 This page was already duplicated. Nothing changed.。副本通过structuredClone(template)生成然后重置id、outlineId、stageId、order、title并把actions置空数组。目标位置使用Math.min(params.targetOrder, scenes.length 1)收敛随后调用shiftCourseOrders把后续页面的 order 顺延同时同步更新文档 outline。第 2 步用read_stage读取副本source 模式对副本调用read_stage路径为path:/scenes/order|id、detail:source。这是你的寻址空间和保真度来源它返回整页的持久化 JSON包括原始内容 HTML、内联 span、字体、颜色、填充、阴影、几何信息与 z-order。它是你所有 patch 路径的根——你在/content/canvas/elements/2/content读到的字段就通过同一条路径写回去。从这份结果中原样复制未修改的标记和样式字段绝不要从被剥离的纯文本去重建它们。这一点与 slide-dsl 的读写语义一致写入路径会把你发送的内容按字节原样存储没有标记白名单、没有清理器、没有颜色或字体归一化。实现上lib/server/agent-runtime/dsl-tools.tsread_stage支持detail为tree紧凑、source精确 JSON大体积媒体字节被省略、text纯文本三种深度且source/text模式在超过 12000 字符后会分页并返回nextOffset。第 3 步逐元素判定内容槽位 vs 骨架对每个元素做出判断内容槽位content slot是那些文字属于旧主题的元素骨架skeleton是其余一切——分隔线、色带、页码、Logo、装饰形状、背景美术——即使骨架元素里也含有文字也要保持原样不动。第 4 步每个内容槽位调用一次patch_stage对每个内容槽位调用一次patch_stageop:set作用于承载该槽位文字的确切路径——段落用/content/canvas/elements/3/content表格单元格用/content/canvas/elements/5/data/0/0/text。一次调用只写一个叶子节点你没有点名的一切都保持复制来的值。slide-dsl是哪个字段承载哪种元素类型文字的手册。克隆期间不要patch 几何或样式路径——它们就是你复制的设计本身。第 5 步编辑后用detail:text复查编辑完成后再次调用read_stagedetail:text。它会以{ path, id, type, text }的形式返回每个含文字的元素外加页面级的combinedText让你一次调用就读完整页文字并获得修复所需的指针。用它扫描源主题残留读取报告由你决定什么是过时的然后用set、remove或delete_element处理掉。第 6 步generate_actions补旁白对副本调用generate_actions生成旁白音频默认开启。复制出来的页面是沉默的——duplicate_scene实现中actions: []与generate_actions工具在 generation-tools.ts 的职责划分正好印证这一点。效率提示一次只处理一页编辑前务必重读。每次patch_stage的结果已经携带了页面最新的清单所以同一页上连续多轮编辑只需要开头调用一次read_stage而不是每轮都调用。改动落在哪里路径即语义对克隆的幻灯片patch_stage支持set、remove、str_replace、add_element、delete_element五种操作克隆场景下最常用的选择是set作用于最小的内容叶子。真正的问题永远是哪条路径承载这次改动。以下是page-clone给出的完整对照表需求调用实际发生的事文本块里的新文字set/content/canvas/elements/N/content逐字节存储你的 HTML——没有任何过滤改写文字时保留源元素的span标记与内联样式形状标签里的新文字set/content/canvas/elements/N/text/content只有标签的 HTML 移动字体、颜色、垂直对齐、行高、形状填充与路径全部保持不变一个表格单元格set/content/canvas/elements/N/data/0/0/text单个单元格的纯文本其余单元格、id、colspan、rowspan与逐单元格样式不受影响一行代码set/content/canvas/elements/N/lines/1/content一行的文字且保留每一行的 id——语言、文件名、字号和代码框都存活一个公式set/content/canvas/elements/N/latex替换公式源码并重新渲染渲染器真正绘制的缓存 KaTeXhtml图表标签或数字set/content/canvas/elements/N/data/labels/2单个条目保持labels、legends、series维度一致换成另一张图set/content/canvas/elements/N/src把元素指向另一个源。它永远不会凭空创建图片——先通过generate_image拿到真实src并保留原图而不是编造一个 URL微调一个框set/content/canvas/elements/N/left或top/width/height一次只改一个数字。在克隆页上这是修复而不是常规步骤去掉一个可选字段remove/content/canvas/elements/N/fill删除该 key。对不存在的路径remove会失败删除必填字段也会失败内容槽位多了一个delete_elementelementId移除元素以及绑定到它身上的任何动画真正的新元素add_element完整元素 JSON不带id校验每个字段与富文本值分配 id按afterId或index插入重排重叠元素set/content/canvas/elements唯一没有叶子的改动——把整个数组整体重写、重排保持相同的 id 与类型重命名页面edit_deck retitle只改标题deck 和 outline 条目两处都改代码层面patch_stage的定位dsl-tools.ts与表格完全一致它原子地patch/scenes/order|sceneId下的一个场景set/remove使用以该场景 source 为根的 JSON Pointer/content/...或/actions/...str_replace在指针指向的字符串字段内替换一处精确匹配replaceAll可全部替换add_element/delete_element保持服务器拥有的元素身份。三条让克隆安全的底层性质在动手之前有三个性质值得知道它们使这套操作可以放心依赖只有你点名的路径会变。未点名的字段保持复制值这是设计被复制所以被保留的机制保证。身份不可 patch。id 集合以及每个 id 的类型必须原样返回——这正是新增或删除元素需要独立操作符add_element/delete_element的原因。被拒绝的 patch 什么都不改。错误的路径、未知的字段、不安全的 HTML 或非法结果都会响亮地失败页面保持原状。另外系统不会把你的颜色或字体朝某种家样式归一化——这正是被复制的设计能在编辑后存活的原因。内容规则很简单源 HTML 进源 HTML 出。改动返回的段落和 span 内部的文字不要把一个文本块拍扁成纯文本也不要合成新的样式。对列表保持每个条目一个p标记写在文本里slide-craft会解释为什么这里的ul不渲染标记。当克隆页需要再多一个槽位时最便宜且诚实的来源是页面上已有的元素读出它的 JSON用add_element复制一份带上你想要的文字和框。add_element是全保真的所以调用方必须提供每个几何与样式字段——这正是已有元素比空白元素更适合当起点的原因也是为什么它被定位为最后手段而不是常规步骤。内容装不进布局时四种取舍按优先级这是正常情况不是错误一个只有三个要点槽位的布局撞上七点内容是需要你来化解的不匹配没有任何工具会替你化解。按优先级排序裁剪内容到布局容量。借用来的布局本身就是一页能说多少的声明。收紧表达保住设计撑大页面毁掉设计。拆成两次克隆。再次复制模型页把剩余内容带到第二份副本上。两页按 deck 自身形式呈现胜过一页塞满。换一页更宽敞的模型页。如果课程里有为更多内容而建的布局克隆那一页并用edit_deck delete放弃当前副本。最后手段才去撑大布局。用add_element复制最接近的内容元素把它的框对齐进周围元素的节奏左边缘和间距严格取自源框的几何值新文字直接写入。从这一刻起你在画画了——如果粗心一眼就能看出来。内容槽位少于布局容量是更容易的方向把能有意义填充的填上其余的用delete_element删掉。永远不要让模板的旧文字留在页面上。一个既没替换也没删除的槽位就是一个 bug——旧主题泄漏进新主题——read_stage detail:text的全页文字扫描就是发布前抓住它的扫帚。溢出纪律为模型页文字设计的字号不一定是为你文字设计的字号。目标是与被替换文字保持同一个数量级——那个长度是为那个框精心选择的也是你手里唯一的尺寸信息。当你的替换明显更长时缩短措辞而不是把框放大。在render_scene_preview已注册时用它做验证并把调用花在真正有价值的地方从某个模型页克隆的第一页以及任何文字明显长于被替换内容的后续克隆。其余情况跳过——预览要消耗调用额度。如果页面溢出了加载pro-editing在其两次预览轮次的预算内收敛——先缩短文字只有文字已经紧凑时才去设置框两轮仍未收敛就把内容挪到更宽敞的布局或者把页面命名权交给用户绝不发布文字跑出框外的页面。收尾页面补旁白并清扫残留对副本调用generate_actions当周边页面有一致的旁白风格寄存器时带上styleDirective。旁白是根据页面持久化内容加上其 outline 条目写成的而该条目的 brief 来自模型页——所以你刚写的内容必须脱离上下文也能自明标题必须是新页面的标题。生成后用read_stage detail:source读回结果检查结果的两半每条语音动作都带有audioId每句语音都在讲这一页的主题而不是模型页的——一段本章回顾式旁白或者从 brief 继承来的主题名跟幻灯片上的模板文字一样属于残留。修复它用patch_stage作用于该动作的/actions/N/text指针然后对该页执行generate_tts让音频与文字匹配。这个分工在工具注册表中清晰可见generate_actions负责动作生成generate_tts负责音频回填两者都是写工具lib/agent-runtime/stage-writer-tools.ts并在generate_actions实现中generation-tools.ts通过synthesizeSceneNarration与force: false的语义配合。本技能在技能体系中的位置style-clone负责课程级工作把导入的 deck 当作布局库来阅读、分类并为每个 outline 条目指派一种布局。它调用本技能完成逐页的机械操作。slide-dsl是你正在 patch 的 JSON 的字段手册——十种元素类型、每种类型的文字藏在哪个字段、哪些值合法、渲染器对你写入的 HTML 到底做了什么。准备 patch 一个从未碰过的字段或 patch 被拒绝时加载它。pro-editing管理页面已经就是你想要的样子的编辑。克隆结果不对时加载它并遵循它的预览预算。slide-craft是替换内容必须满足的设计法则——高度表、字体比例、对比度配对、富文本真实渲染方式。槽位需要的不是同长度换句时加载它。stage-design仍然管辖整个 stage 的搭建。以上技能均位于 skills/agent-runtime/ 目录下style-clone/SKILL.md、slide-dsl/SKILL.md、pro-editing/SKILL.md、slide-craft/SKILL.md、stage-design/SKILL.md。硬规则先复制再编辑。永远不要对复制页调用generate_scene。它会从 outline 条目重新掷骰生成元素树借来的设计就此消失。内容变设计不变。克隆期间不碰几何路径、不碰样式路径、不新增元素、不重排除非布局确实必须生长且你已经先读过相邻框的几何值。每个元素最终都要么被替换、要么被刻意保留、要么被删除。不允许模板文字靠侥幸存活。永远执行文字扫描。read_stage detail:text返回每个元素的文字加一个combinedText全部读完用它交给你的path修复发现的问题。读取只报告——它从不替你决定或编辑。事实不会随布局旅行。从模型页带过来的文字在新上下文里是一种断言如果它属于旧主题就必须离开。一次一页。duplicate_scene然后这一页的编辑然后这一页的动作——然后才是下一页。每次写入都按落地即持久化。【免费下载链接】OpenMAICOpen Multi-Agent Interactive Classroom — Get an immersive, multi-agent learning experience in just one click项目地址: https://gitcode.com/GitHub_Trending/op/OpenMAIC创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考