Files
DemonGatanjieu-Anomalous_Mo…/docs/architecture/ui-flows.md
T
DemonGatanjieuandClaude Opus 5.5 2280e55fde Let an AI read the workflows it is offered
A run with Gemini 3.8 Flash asked for picture to picture and built it node by node, 13 failed calls on the way, with an official example ready:

- list_workflows was 23,630 characters on 17 cards, 21,033 of them settings. Antigravity files an answer over about 4,000 away, unread. A list of more than 3 now goes with name, route, tags and short notes.
- Examples showed only when no saved workflow matched, and only by English words: 图生图 found nothing. They are always named now, and found by their Chinese titles, img2img, txt2img and inpaint.
- Every card's route line was empty, and cards_of found nothing, since c84b596: _list_recipes leaves the graph out, and the tests fed cards that had one. Both ask for it now, with a test on a file on disk.

A waiting task the user wrote to also takes its name from what they wrote, instead of the AI's "take the task".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 17:51:12 +08:00

20 KiB
Raw Blame History

界面地图:点哪里、去哪里、为什么

这份是界面地图的手写部分,只写代码里看不出来的东西:每一块是干什么的、点了以后发生什么、为什么这样设计、同一个东西统一叫什么。 具体在哪个文件、哪一行、调哪个接口,不要在这里找,直接问代码(永远是最新的):

node tools/ui_map.mjs find 屏幕上的字      比如 find AI 改副本:哪个文件画的、样式在哪、调哪个接口、后端哪个函数
node tools/ui_map.mjs find /anomalous/ai_tasks    这个接口由谁处理、前端谁在调
node tools/ui_map.mjs find ui_ai_marker.js        这个文件显示哪些字、调哪些接口、被谁用
node tools/ui_map.mjs build                写出 docs/ui-map.md:按页面列出全部文件、文字和接口(不进版本库)

写这份文档的规矩(node tools/check_structure.mjs 会检查):

  • 「」 里只放屏幕上的原字(中文界面),一个字都不能差;太长的句子可以只写开头,结尾加 …。界面改了字,检查就会报错,提醒你回来改这里。
  • 文件名和接口用反引号,比如 ui_ai_task_canvas.js、/anomalous/ai_tasks/{task_id};不存在了检查也会报错。
  • 最后的“统一叫法”表:一个东西只用一个名字。表里“不再用”的词,只要还出现在界面文字里,检查就报错。

AI 工作台

三栏:左边任务列表,中间一个任务的时间线,右边侧栏。放不下侧栏时(侧边停靠、窗口窄;侧边停靠的宽度拖窗口右边缘调,最窄 480,每个页面都要在这个宽度下能用)标题栏的图标开关不显示,改成任务上方一排带字的标签:「时间线」和各个侧栏,一次看一个,切换都在这一排。再窄一些(侧边停靠就是这样),任务列表是从左边盖上来的抽屉,后面露出当前任务:一看就知道这是会话记录,点露出来的部分或按 Esc 回到任务;没有任务时列表铺满。

左栏:任务列表(ui_ai_task_list.js)

看到的 点了以后 后端
「新任务」 马上开一个任务,显示“等 AI 接手”,要做什么在那一页写(可以不写);下一个来调用的 AI 直接接手它,不会接在旧任务后面 POST /anomalous/ai_tasks
「连接 AI」 弹出连接说明:地址、复制给 AI 的那句话、各个软件怎么加(ui_ai_connect.js) 无
「关卡」 AI 做哪些事要先问你(改画布、用显卡、下载……),还有 AI 怎么等你回答、怎么等跑图(ui_ai_gate.js) /anomalous/ai_gates
「全部」「进行中」「等你回答」「出错」 只筛这一栏,不改任何东西 无
一个任务 中间显示它。看过的、鼠标停过的马上出来,再悄悄补上最新内容(ai_task_cache.js) GET /anomalous/ai_tasks/{task_id}
任务行上的 ⋯ 鼠标移到任务上才出现,当前任务一直有。菜单和标题栏的 ⋯ 一样(ui_ai_task_menu.js),不用先打开这个任务 POST /anomalous/ai_tasks/{task_id}

一条线上的任务排在一起:后续任务缩进一层挂在最早的任务下面,链再长也只缩一层,最早的任务上写「共 {count} 个」。整组排在它最新动静的那一天下面,别的日子的任务在时间前面写上自己的日期。点了筛选就不分组,符合的任务单独排,带「↳ 后续任务」。从列表移除中间的任务时,它的后续任务接到它的上一个任务上,线不断。

收起:标题栏最左边的按钮(「收起 / 展开任务列表…」)。收起后列表仍在左边排好、藏起来,鼠标碰到这个按钮、或者从页面往左移到最左边缘,下一帧就滑出来;离开后 0.35 秒收回,点了任务马上收回。

为什么:列表每 5 秒刷新一次,只重画变了的行(sync_rows.js),所以滚动位置不会跳、鼠标下面的行不会闪。

中间:任务的标题栏

看到的 点了以后 后端
「AI 改副本」 / 「AI 改当前画布」 打开二选一:「改副本」(先把当前工作流复制到新标签页,AI 只改副本)或「改当前画布」。点开才换,不会点一下就悄悄切换 POST /anomalous/ai_tasks/{task_id}(canvas)
「切到副本」 切到这个任务的副本标签页,并显示画布(mcp_task_tab.js) 无
「撤销画布上的改动」 按操作记录把 AI 在画布上的改动一步步撤销(canvas_undo.js) 无
⋯ 里的「改名」 / 「从列表移除」 移除只删这条记录,图、画布、工作流都不动 POST /anomalous/ai_tasks/{task_id}
⋯ 里的「打开隐私模式」 这个任务的图不再发给 AI;开着时标题栏多一个「隐私模式」,点它关掉(ui_ai_privacy.js) POST /anomalous/ai_tasks/{task_id}(privacy)
⋯ 里的「接着哪个任务…」 把这个任务接在另一个后面,两边都显示链接(ui_ai_task_links.js) POST /anomalous/ai_tasks/{task_id}(from)

AMB 更新以后,AI 软件还拿着旧的工具列表来调用时,标题栏下面出现一行黄字「AI 软件拿的还是旧的工具列表,会多走弯路。请重新连接:Antigravity 重启一下,或在它的 MCP 设置里把 anomalous 关掉再打开;然后开个新对话。」,AI 那边也会收到同样的提醒(mcp_directory.stale,按每个 AI 软件上次取的列表比对)。AI 软件重新取工具列表(tools/list)后这行自动消失。

标题栏右上角的一排是侧栏的开关:「展台」「节点结构」「决策」「素材」「成果」(ui_ai_side_views.js),同一时间只开一个。

标题栏固定两行:名字和工具,下面是任务信息和前后任务的链接。不常用的都收在 ⋯ 里(ui_ai_task_menu.js)。侧栏打开、中间变窄时,状态和「切到副本」只留图标,名字放不下就省略,不把工具挤到下一行。

时间线上面一行:这个任务走过的阶段(点了跳到那一步)和这个任务出了什么。

中间:等 AI 接手的任务(ui_ai_ready.js)

「新任务」之后、AI 还没来时,中间这一页只有一件事:「把这句话发给你的 AI」和「复制这句话」。

  • 想先交代的话、要给的图,都放最下面的留言框,它的提示写着「可以先交代几句,比如:用樱花 LoRA 出三张图让我挑」。发出去的列在那句话下面,AI 接手时一起收到。
  • 从来没有 AI 连过时,最上面先是「先把 AI 连上 AMB」和「查看连接方法」:没连上的 AI 看不懂那句话。连过以后这张卡片不再出现,要连别的 AI 走左栏的「连接 AI」。

为什么:以前“等 AI 接手”说了三遍,下面还有“写一句要做什么”“从图库挑图”两行,和留言框是同一件事,连过 AI 的人也一直看到“第一次用?”。现在一页只留一个动作,要交代的事只有留言框一个地方。任务名由 AI 接手时起,想自己起就用 ⋯ 里的改名。那句话不叫 AI 一接手就停下来问你,而是照任务里的交代做,没交代才问。

AI 问你的问题(ui_ai_panel.js、ui_ai_now.js、ui_ai_gate.js)

展台里的选择题、留言框上方的提问条、关卡卡片都按同一个做法:

  • 选项是一按就发出去的按钮,右边有箭头,上面写着「点一个就发给 AI」;点了马上变成选中的样子,再显示“已发送 / AI 已收到”。
  • 「让 AI 定」放在问题的右上角,是一个虚线小按钮,不跟选项挤在一起,免得被当成“确认”。
  • 自己写的那一行默认收起:「都不是,我自己说…」,关卡卡片上是「说说想怎么改…」,点了才出输入框。
  • 写了一半的回答一直留着(只留在这个页面里):AI 又问了新问题、读走了另一个回答,问题重画时字、光标位置和选区都还在,那一行也不会收起;展台和底部提问条同步同一道题的草稿,刷新只把焦点还给原来正在编辑的位置;这个问题一直排在提问条最前面。窄窗口里你正在打字时,新来的问题只点亮「展台」标签,不把你切过去。
  • 只有真按键才算“在打字”(每几秒告诉一次服务器):停手一分钟以后照常算时间,光标停在框里不算。动手写过回答的问题,到时间也不会按推荐的替你选,AI 停下等你。

为什么:看到一个框,人就以为要填;选项和下面的按钮排在一起,人就以为要先选再确认。写到一半的话被清掉、被切走,或者人走开了被替你选掉,都比多等一会儿糟。

中间:时间线

  • 从上往下读,编号 1、2、3……;AI 连着查资料、连着改画布的几步折成一行(ui_ai_chain.js),点开看每一步。
  • 每一步下面写它做了什么(ui_ai_step_body.js),出的东西能直接去:图片进看图器、模型进模型页、画布改动能定位和撤销(ui_ai_results.js)。
  • 跑完的图下面是「这次效果:」「效果好」「不太行」(ui_ai_verdict.js),点了就告诉 AI,再点一下收回。
  • 图片上鼠标移上去有工具(ui_ai_images.js):「图片与参数」、「保存为…」、勾两张对比,还有 ✎ 标注。
  • 时间线和展台里的图先用缩略图(/anomalous/output_thumbnail),显示得比缩略图大时才换原图(/anomalous/output_preview:超大图换的是 4096 像素的预览),打开任务不用等大图。

标注:「标给 AI 看:哪里要改」(ui_ai_marker.js)

框、圈、箭头、画笔,每个标记写一句要怎么改;右边选「怎么改」:

  • 「交给 AI 判断」:AI 看说明自己决定。
  • 「只改标出的地方」:其余保持原样,框、圈、画笔和涂抹的地方做成遮罩放进 input 文件夹,AI 只重绘这些地方。用「涂重绘区」时自动选上。
  • 「整张重新出图」:按说明整张重画,不做局部重绘。

「发给 AI」以后(POST /anomalous/ai_tasks/{task_id}/marks),AI 下一步收到的第一句就是你选的改法,写明是你的要求(ai_marks.py)。时间线里这条标注写着「改法:{mode}」,方便核对 AI 有没有照做。

中间最下面:留言框(ui_ai_message.js)

  • 「给 AI 留言,比如:背景再亮一点。…」:Enter 发送(POST /anomalous/ai_tasks/{task_id}/message)。
  • 打 @ 提到素材和图(ui_ai_mention.js),开头打 / 是快捷指令(ui_ai_commands.js):/停止、/撤销、/展台、/节点结构、/素材、/副本、/当前画布 马上生效;/重跑、/解释、/继续 帮你写好一句话。
  • 「从图库选图给 AI」(ui_ai_gallery_pick.js),拖进来或粘贴截图(ui_ai_drop.js,存进输出文件夹的 ai_inbox)。
  • 留言框上面的一条(ui_ai_now.js):正在出图的进度、要你允许的事、AI 问你的问题;AI 停下时给出可以复制给它的句子,比如「继续」(ui_ai_call.js)。

为什么:AMB 不能主动叫醒外部的 AI。发出去的留言会等着,AI 下一次调用任何工具时一起收到(ai_panels.py 的 attach_pending),或者它来读回答时收到。AI 已经停了,就要你回 AI 软件里说一句,所以那里总有一句可以复制的话。

右栏:侧栏

开关 里面是什么 主要文件
「展台」 AI 画的面板,从上往下排,旧的在上、新的在下;要你回答的在这里回答(POST /anomalous/ai_tasks/{task_id}/answer)。来了新面板而你在往上看时,出现「↓ 查看最新」 ui_ai_side.js、ui_ai_panel.js、ui_ai_stage.js
「节点结构」 这次运行实际用的节点、和上次比改了什么 ui_ai_run_map.js
「决策」 你在面板上的选择、允许和拒绝、AI 记下的关键决定 ui_ai_decisions.js
「素材」 「给 AI 的素材」:挑模型、节点、搭配、工作流、提示词交给 AI;「来源」列表里鼠标所在的行会亮,选中的打勾。模型和模型页一样:按类型分、有基础模型的分类条,同一模型的几个版本是一张卡,版本单独写,点它换版本,已选的跟着换 ui_ai_toolbox.js、ui_ai_facet_menu.js
「成果」 这个任务出的图、工作流、搭配、提示词、音频,按步骤排 ui_ai_outputs.js
「做法」 AMB 现成的做法和 skill。右边的开关全局关掉一个,AI 就看不到;能用的做法上有「这次用它」,只对这个任务:AI 会收到,这一类活 AMB 直接按它搭,AI 要别的也一样(POST /anomalous/ai_tasks/{task_id}/way) ui_ai_blocks.js

存档(ui_snapshot_bar.js)

右键节点或画布空白处「存档当前工作流」后出现在画布下方,因为存档时人在画布上改东西,AMB 的窗口会盖住画布。存档跟着工作流走:切标签换成那个工作流的,没有存档的标签没有这一条;刷新、重启都还在。

  • 存档的数字:回到那一步,在同一个标签页里,算一步撤销,Ctrl+Z 能回来,也可以接着改出新分支。亮着的数字就是画布现在的样子,画布一改就灭。
  • 回到一个存档时,输出节点上的图也换成这个存档跑出来的:跑了几次就都排在节点里,和批量出图一样,新的在前,最多 16 张。这个存档在某个节点上没有图(没跑过,或图删了),那个节点就空着,不留别的存档的图,免得看错。Load Image 选的图不动。Ctrl+Z 退回的只是画布,节点上的图不跟着退。
  • 条上只放最新的 6 个,更早的收进一个「前 N 个」,点开是存档页。「运行」跑的是全部存档,不是画布现在的样子。
  • 数字旁边的框:这个存档跑几次。条上的 +:再存一个。⌄:收成贴在画布底边的小把手。「随机」和「锁种」管整组运行的种子。
  • 条放在画布这块区域里,居中对着画布,打开底部的日志也不会盖住它。提示飘在条的上方,按钮不会被顶开;跑完提示自己消失。
  • 「看图」:打开下面的存档页,停在这个画布那一块。
  • 运行前逐个存档让 ComfyUI 检查,有问题一次都不排。跑的是副本,画布和上面的种子都不动。

存档页(ui_saves_list.js)

「工作流」页顶上的「存档」。所有存档按画布分块,画布关了、文件删了的也在;每块能折叠,默认只展开当前画布。

  • 块的顶上:「运行 N 次」按存档顺序跑这一块,一次只跑一个画布;再点别的块,就排在后面,先点先跑。「删掉这组」进回收站。
  • 每个存档一张卡:左边是和上一个比改了什么、跑几次和按钮,右边是出的图(新的在前;窗口太窄才排到下面)。窗口够宽时卡片并排,和工作流卡一样铺开。
  • 图:一行放得下多少放多少,其余折叠成最后一格,写着还有几张。点开看大图;鼠标移上去有「查看参数」,打开参数页后左右键在这个存档的全部图里切换。只有预览没保存的图没有参数。
  • 点这一格(或 ⋯ 里的「看全部 N 张图」):这个存档的全部图,用图库的卡片,操作和图库页一样;「← 全部存档」或 Esc 回来。
  • 「运行」:只跑这一个存档,每次换新种子,不看「锁种」。还有几次在跑写在这个存档自己的卡上。
  • 「收藏为工作流」:存成一张新的工作流卡,之后互不影响。存档只能变成工作流卡,不变成预设或搭配。
  • ⋯:「回到这里」(画布开着才有)、「在新标签页打开」(画布开着算一条新分支,存档从空开始;画布没了,这组存档接着用)、「删掉这个存档」。

工作流页的「官方示例」(ui_recipe_examples.js)

工作流页第一张卡片是「官方示例」,放最后的话,卡片一多就找不到了。点开是一个窗口,按方案分组(文生图、两段放大、图生图、局部重绘),方案下面是各个版本,每个版本有备注和「新画布打开」。两段放大有三个版本:SDXL / SD 1.5、Anima、Anima · Tile 锁图(「推荐」)。SDXL 和 Anima 必须分开,模型的加载节点不一样。打开时后端按版本填上你已有的模型和文件(GET /anomalous/example_workflows?id=…)。缺节点包或模型的版本照样列出来,写明缺什么,节点包能点进 Manager,这一条没有打开按钮。搜索或筛选时这张卡片不显示。

AI 这边:没有合适的已存工作流时,list_workflows 给它这里能跑的版本,每条写着适合什么模型,打开和运行都和已存工作流一样;有合适的时也列出示例的名字,免得 AI 不知道。用中文(图生图、两段放大)也搜得到。用户存过的工作流优先,也不会被同名示例盖掉。

为什么:新装的人一张卡片都没有,AI 也没有现成路线可跑。只放一张卡片,不占用户自己的位置;方案只是窗口里的分组,每个版本仍是一条独立的工作流,不是一张卡里放几套参数。Tile 版的数值和做法 upscale_tile 的 Anima 版一致,有测试看着。

模型选择器(ui_node_model_picker.js)

换模型时选一个。插入 LoRA 时可以选多个:点卡片加入,再点一下取消,卡片左上角的数字就是接上去的顺序。装了 rgthree 或 Easy-Use 时底部能选用哪种节点(官方的串成一串,第三方的放进一个节点),记住上次的选择。放好后新节点都是选中的,可以一起拖走,落在视野外时画布会移过去;Ctrl+Z 一次全部退回。第三方节点放上去后自己还会变一下高度,所以窗口多留一小会儿,等它们稳定再排位置、记撤销。

设计上的固定做法

  • 从上往下读:时间线、展台都是旧的在上、新的在下;看最新的时候自动跟着往下,往上翻着看时不打断,只出现“去最新”的按钮。
  • 重画只重做变了的部分:工作台随时在刷新,滚动位置、打了一半的字、展开的东西都不能丢。
  • 会改东西的地方说清楚后果:二选一要写每一种是什么意思;删除写明删的是什么、不删什么。
  • 鼠标移上去要有反馈:列表行、菜单项悬停变亮,当前选中的有底色或打勾。
  • AI 改画布默认改副本:你正开着的工作流不被 AI 动。

统一叫法

说法 English 不再用 不再用(English)
副本(AI 改的那份工作流) copy 专用标签页、自己的标签页、新开标签页 own tab
素材(交给 AI 的模型、节点……) materials 材料 —
留言(你写给 AI 的话) message 消息 —
节点结构 node map 结构图、运行结构 node structure
连接 AI connect an AI 最近接入、接入过 —
撤销 undo 撤回 —
展台 stage 画板、舞台 —
成果 results 产出 —
关卡 gates 闸门 —
工作流(存下的整套工作流,“工作流”页的卡片) workflow 配方(配方包、搭配方案除外) recipe(recipe package 除外)、recipes
配方包(把一个工作流打包发给别人的 .zip) recipe package — —
搭配(主模型 + LoRA + 提示词) combo — —
预设(工作流卡里存的一组参数,“工作流”页卡片的详情里) preset 参数方案 parameter set

“不再用”里可以写例外,比如“配方(配方包、搭配方案除外)”:这两个词里的“配方”不算。{recipe} 这样的占位符也不算。

还没统一的

  • node tools/ui_map.mjs build 的最后一节列出没有文件用到的文字(2026-10-25 清理过一次,当时为 0),清理前先确认不是拼出来的 key、也不是后端错误信息当 key 用的(t(error.message))。