跳至主要內容

API 參考

後端提供 REST API 與執行用 WebSocket。所有端點都使用與應用程式相同的來源(預設為 http://localhost:8000)。驗證欄使用驗證一節定義的五種值。每個表格都會連結到相關的使用說明頁面。

伺服器也提供 FastAPI 產生的 schema:GET /openapi.json(OpenAPI 3.1,涵蓋本頁每條 HTTP route,不含 WebSocket)、GET /docs(Swagger UI,另有輔助頁面 /docs/oauth2-redirect)與 GET /redoc。這四條都是 open。/docs 與 /redoc 會從 cdn.jsdelivr.net 載入 script,因此瀏覽器必須能連上網際網路才能顯示;/openapi.json 不需要。有預先建置的前端時,對 /api/ 與 /ws/ 以外其他路徑的 GET,若前端建置中有該路徑的檔案就回傳該檔案(/assets/... 的 bundle、/build-info.json,以及 release 前端的 /LICENSE、/NOTICE、/THIRD_PARTY_NOTICES.md、/COMMERCIAL-LICENSE.md 與 /CONTRIBUTING.md),否則回傳 index.html。/assets/ 底下不存在的檔案,以及 /api/ 或 /ws/ 底下沒有對應 route 的路徑,都回傳 404,不會回傳編輯器頁面。

驗證​

驗證意義
open不需憑證。大多數 GET / HEAD / OPTIONS 請求使用這項規則;下方已發佈應用程式與 API key 的列會標出例外。
tokenX-CodefyUI-Token session header。一般 middleware 會要求 /api/ 底下的每個 POST / PUT / PATCH / DELETE 都帶上它,但 /api/apps 與 /api/keys 由各 route 依本表其中一項規則自行驗證。所有應用程式管理 route(包含 GET /api/apps 與 GET /api/apps/{slug}/versions)以及整個 /api/keys 都使用這項憑證。遺漏或錯誤時:403 {"detail": "Missing or invalid X-CodefyUI-Token header"}。token 檔案的位置,以及它為何每次重啟都會輪替:見把 graph 當成函式呼叫,第 2 節。
token+loopbacktoken,加上伺服器必須綁定至回送位址(127.0.0.1、localhost、::1)——否則回傳 403——除非事先匯出 CODEFYUI_ALLOW_REMOTE_PACK_INSTALL=1(套件包)或 CODEFYUI_ALLOW_REMOTE_PLUGIN_INSTALL=1(外掛)。此閘門讀取 CODEFYUI_HOST,從不讀取 socket。
API key只接受 Authorization: Bearer cdui_...。使用 session token 時,錯誤訊息會指出此處需要 API key。驗證失敗會在 run envelope 內回傳 401,並包含 WWW-Authenticate: Bearer。key 透過 /api/keys 建立;請參閱發佈,第 2 節。
worker tokenWorker agent 用一次性 enrollment token 向 POST /api/workers/enroll 換得的長期憑證,在 /ws/worker 以 X-CodefyUI-Token header(或 ?token=)傳送,也用於 POST /api/runs/{run_id}/artifacts/upload 的 header,替在該 worker 上的 run 上傳。任何來源都接受;它代表一個 worker,該連線的 hello 必須使用這個名稱。DELETE /api/workers/{id} 撤銷它。伺服器只保存它的 sha256 雜湊值。見遠端 Worker。
enrollment tokenabcdef.0123456789abcdef,由 POST /api/workers/enrollments 產生。只有 POST /api/workers/enroll 接受它(放在 JSON body,不需 session token);該 route 依用戶端位址限速(10 次,之後每分鐘 10 次;超過回 429 並附 Retry-After)。
key-or-token接受任一種憑證。這些 metadata 讀取是 GET 通常開放之外的另一組例外。兩種憑證都沒有時,會回傳 401 {"detail": "..."}。

Host guard 會在其他所有檢查之前處理每個 request,包括 SPA 頁面與 WebSocket。Host header 不在 allowlist 內時,會回傳 421 {"detail": "Misdirected Request (Host not allowed)"}。allowlist 由 CODEFYUI_HOST 與 CODEFYUI_PORT 推導,並可透過 CODEFYUI_EXTRA_ALLOWED_HOSTS 擴充。SSH worker 的通道從不連到這個連接埠,也沒有任何 Host 會讓 request 被當成來自通道:通道接到伺服器只為那個 worker 開的監聽埠(私有資料夾裡的 Unix socket;Windows 上則是 127.0.0.1 的臨時連接埠),那裡只提供 /ws/worker(worker token;session token 一律被拒)、POST /api/workers/enroll(enrollment token),以及帶有有效 worker token(沒有則回 403)時 transfer 後端的輸入下載路徑與 POST /api/runs/{run_id}/artifacts/upload。那裡的其他路徑一律回 404,包括 GET /api/auth/bootstrap,不論 Host 為何(遠端 Worker,透過 SSH 連線);請參閱發佈,第 6 節與放在反向代理後面。token middleware 會略過 GET /api/auth/bootstrap,讓前端取得 token。只要 Host 獲准就能呼叫此端點,包括伺服器綁定至區網位址時的遠端 client。

健康狀態與系統​

端點方法驗證說明
/api/healthGETopen健康探測,包含 status、version、boot_id(用來讓 client 偵測伺服器重新啟動的行程識別碼)、nodes_loaded、presets_loaded、caches(各記憶體內 store 目前使用的位元組與上限;請參閱訓練記憶體),以及伺服器以 --project 執行時的 project(專案目錄絕對路徑)。
/api/auth/bootstrapGETopen對任何 Host 獲准的請求回傳 {"token": "..."}——前端取得 session token 的方式。
/api/system/devicesGETopen可用於執行圖表的運算裝置:最佳可用的 default,加上一份能區分 NVIDIA CUDA、AMD ROCm 與 Apple MPS 的具名 devices 清單。每個裝置另帶 memory:請求當下讀到的 {total_bytes, free_bytes, source}(source 為 nvml、torch.cuda、torch.mps 或 psutil),讀不到時為 null。NVIDIA 顯示卡透過 NVML(nvidia-ml-py)讀取,讀不到時改用 torch。支援編輯器的裝置選擇器,加速器會顯示可用 / 總共 GiB。
/api/system/fingerprintGETopen此伺服器目前的環境指紋與摘要:{fingerprint, digest}。見執行環境。
/api/system/fingerprints/{digest}GETopen依摘要取回某個 run 記錄過的指紋;沒有 run 記錄過時回傳 404。run 刪除後仍可查詢。

節點與預設組合​

端點方法驗證說明
/api/nodesGETopen列出所有節點定義。每個節點都帶有 details(較長的說明;description 已足夠時為空)、provider(builtin、custom 或 plugin:<id>)與 requires_pack(節點宣告的套件包,沒有則為 null),每個 SELECT 參數則帶有 option_packs(選項值到套件包 id 的對應)。編輯器會讓目前使用但尚未安裝的值保持可選取並顯示警告,將其他尚未安裝的選項變灰,並提供安裝入口。這兩個欄位都不會阻止 run;不能在缺少套件包時執行的節點會在 execute 中拒絕執行,內建節點就是如此(參閱自訂節點)。
/api/nodes/{node_name}GETopen取得單一節點定義。
/api/nodes/reloadPOSTtoken重新探索每一個節點與預設組合來源:從磁碟重新 import 自訂節點與外掛;重新註冊但不重新 import 內建節點;重新掃描預設組合。回傳 {builtin, custom, plugins, presets, total};與 POST /api/plugins/reload 完全相同。
/api/nodes/script/validatePOSTtoken在輸入 PythonScript body 時,依 Tier-0 政策檢查它({"code"}):{ok, error, line, defines_run, allowed_modules}。ok: false 是正常的 200,不是錯誤。
/api/presetsGETopen列出預設組合定義。
/api/presets/{name}GETopen取得單一預設組合定義。
/api/presets/createPOSTtoken從請求中的完整 nodes 與 edges 建立新預設組合;編輯器會送出目前的整張畫布。

圖表​

端點方法驗證說明
/api/graph/validatePOSTtoken驗證一張圖,回傳 {valid, errors, issues}。errors 以英文句子列出每個問題;issues 依相同順序,每個問題一筆 {message, code, node_id, params}:message 就是 errors 中的那一句,code 是檢查的代碼(尚未有代碼的檢查為 null),node_id 是問題所在的節點,params 是句子中提到的值。編輯器用這些欄位以介面語言顯示問題,並以標題指出節點。
/api/graph/savePOSTtoken儲存一張圖。request body 是這張圖,加上兩個選填欄位:file 是要寫入的位址(檔名主體),以及 overwrite。不給 file 就是「用 name 推出位址」,也就是另存新檔。這種請求帶 overwrite: false 就是選擇啟用衝突保護:如果推出來的位址已經有東西,伺服器不會寫入,而是回 409,body 為 {"detail": {"error": "graph_exists", "file", "name"}},其中 file 是伺服器算出來的檔名主體,name 是那個位址上既有圖的標題;要覆蓋就帶 overwrite: true 再送一次。完全不帶 overwrite 則維持這個端點一直以來的行為:不管位址上有沒有東西都直接寫入,所以現有的 client 跟腳本不受影響。有帶 file 的請求是存回原處,不會被這樣擋下來。response 為 {message, path, file}:path 是寫入的檔案,file 是伺服器推出的位址,之後的儲存、載入與重新命名都使用它。
/api/graph/load/{name}GETopen載入一張已儲存的圖。
/api/graph/listGETopen以 [{name, file, modified}] 列出已儲存的圖:name 是檔案內儲存的標題,file 是載入、重新命名或刪除時使用的位址,modified 是檔案的修改時間,單位為 epoch 秒(在專案目錄中是 .graph.json 檔案的時間,不是版面檔案的)。在專案目錄中,同一個名稱同時以 <name>.graph.json 與舊版 <name>.json 存在時回傳 409。
/api/graph/renamePOSTtoken重新命名一張已儲存的圖:{"from": "<file>", "to": "<new name>"},兩者都不可為空;其他 key 會回傳 422。會搬移檔案(在專案目錄中也包含其 layout/ 檔案),並把 to 寫入檔案作為其 name。回傳 {message, name, file},其中 file 是經過清理、之後要使用的位址。from 不存在時回傳 404;to 已被使用、to 的版面檔案存在但沒有對應的圖,或同一個名稱同時有兩種檔案形式時回傳 409;檔案不是可讀取的 JSON,或在專案目錄中 to 以 .graph 或 .layout 結尾時回傳 400。側邊欄圖表分頁的重新命名使用這條 route(分頁與持久化)。
/api/graph/{name}DELETEtoken刪除一張已儲存的圖,在專案目錄中也會刪除其版面檔案。回傳 {message, removed},即已刪除的路徑清單。沒有東西時回傳 404;同一個名稱同時有兩種檔案形式時回傳 409。同一分頁的刪除使用這條 route。
/api/graph/exportPOSTtoken匯出單檔、headless 的 Python runner。它會內嵌圖表,並需要相容的 CodefyUI 後端環境,但不需要執行中的伺服器。response 為 {script, warnings},warnings 列出填了絕對路徑、會把腳本綁在這台電腦上的檔案參數。
/api/graph/contract/{name}GETopen從已儲存圖表推導出的函式簽名——inputs、outputs、problems——供腳本呼叫。參閱把 graph 當成函式呼叫,第 3 節。
/api/graph/run/{name}POSTtoken將最新儲存的檔案當成函式執行:輸入 {inputs, timeout_s, device, record_outputs},每種結果都輸出九鍵 envelope。參閱把 graph 當成函式呼叫,第 4 節。
/api/examples/listGETopen列出內建範例圖與已啟用外掛的範例圖:[{name, description, category, path, source, node_count, edge_count, section, family, order}]。source 為 builtin 或 plugin:<id>,node_count 不計入註記,section、family 與 order 決定範例在範例集中的位置(參閱範例集,新增範例)。
/api/examples/loadGETopen載入一張範例圖;?path= 是清單某一列的 path。

Run 與 sweep​

端點方法驗證說明
/api/runsPOSTtoken將 run 送進佇列並立即回傳:{run_id, status: "running" | "queued"}。options.target({worker, devices},以及 pool、memory_gib、memory_source 與 wait)指定在哪裡執行:local、已連線的 worker,或 any(Run 佇列,Worker)。指定的 worker 名稱在這台伺服器啟動後從未出現過、該 worker 不提供該裝置,或降級的 worker 缺少圖用到的節點型別(訊息會列出這些型別)時回 400;已知但目前離線的 worker 會讓 run 排入佇列,等它重新連線。
/api/runsGETopen由新到舊列出;?status= 可重複,?limit= 上限為 500,?offset= 指定起始列。每列都包含 queue_position、queue_reason(排隊中的 run 除了排隊順序之外為何還不能開始,例如 waiting for worker gpu-box to reconnect,否則為 null)、queue_reason_code 與 queue_reason_params(同一個原因的代碼與參數,供用戶端以自己的語言顯示:worker_reconnect、worker_draining、worker_no_mount、any_no_worker、any_no_worker_mount、any_unavailable,以及記憶體准入與單次 worker 的 memory_wait、memory_no_budget、one_shot_start、one_shot_taken、one_shot_run_id、one_shot_pool、budget_raised(估計值被調高且另有原因時,放在該原因的 params.raised);沒有原因時為 null)、active、final_metrics、fingerprint_digest、execution_facts、worker_id(local、worker 名稱,或 any run 尚未放置前的 any)、devices(要求的裝置集合或 null;在 worker 上的 run 則是它取得的裝置)metric_producers({名稱: [節點 id]},run 層級的 series 為 null)與 worker_status(在 worker 上執行中的 run 為 {worker_id, state, disconnected_at, resume_deadline},state 是 connected 或 disconnected,斷線期間兩個時間為 Unix 秒數;其他 run 為 null);GET /api/runs/{id} 另有 late_result(run 在這裡結束後 worker 才回報其結束方式時為 {status, error, worker_id, at},否則為 null);response 也包含未分頁的 total。
/api/runs/{run_id}GETopen回傳單一 run(欄位與列表的每列相同,包含 worker_id 與 devices)與 last_cursor(client 從這個位置開始輪詢事件),以及 fingerprint:其 fingerprint_digest 所指的環境文件(run 開始前為 null),與 provenance:依記錄順序排列的節點來源紀錄(沒有 provenance 選項的 run 為 [];參閱節點來源)。
/api/workersGETopen所有已加入的 worker agent,以及這台伺服器啟動以來見過的其他 agent:{workers: [{id, name, status, draining, same_host, version, fingerprint_digest, platform, mounts, devices[{value, kind, index, name, memory, slots, shared_with}], running, connected_at, last_heartbeat_at, enrolled, credential, plain_http, node_catalog, degraded_reasons}], local, rejections}。status 為 online、degraded(心跳延遲,或節點目錄與這台伺服器不同;degraded_reasons 列出 heartbeat 和/或 node_catalog)、draining(已連線但不接新的 run;另有布林欄位 draining)、disconnected,或 offline(已加入,但伺服器啟動後尚未連線;connected_at 為 null,從未出現過的 worker last_heartbeat_at 也為 null);enrolled 表示該 worker 持有可撤銷的憑證,credential 表示它的連線如何驗證(worker_token、session_token 或 null);same_host 為 true 表示 agent 在這台機器上;plain_http 為 true 表示它的連線是從另一台機器來的未加密 ws://(即「未加密 HTTP」標記:uvicorn 回報的 scheme 不是 wss,且對端不是 loopback,例如同一台機器的 agent 或 SSH 通道的本機端;見 遠端 Worker,信任);memory 是最近一次心跳的 {total_bytes, free_bytes, source},或 null;slots 是該 (worker, device) slot 的 {limit, taken},或 null;裝置實體上就是這台伺服器的某個裝置時,shared_with 為 "local",此時它共用伺服器的 slot(加總時只算一次),否則為 null。local 以 {id: "local", devices[{value, kind, slots}]} 列出這台伺服器自己的裝置,沒有 run service 時為 null。mounts 是 worker 宣告的各個儲存 label 與它那邊的路徑;在這台機器上的 worker 另會以這台伺服器的路徑顯示伺服器的 label,local.mounts 是這台伺服器自己的 label 與路徑(儲存:共用檔案系統)。fingerprint_digest 是該 worker 的環境指紋摘要,可用 GET /api/system/fingerprints/{digest} 查詢(上次連線未回報時為 null)。node_catalog 為 {status, hash, missing, extra}:match、mismatch(附上這台伺服器有而 worker 缺少的節點型別,以及反過來的型別),或 unknown(worker 未回報)(遠端 Worker,讓 worker 保持同步)。每個 worker 另有 ssh_enabled(這台伺服器同名的 SSH worker 是否啟用;不是 SSH worker 時為 null)、memory_budget(它的 agent 是否強制記憶體預算)、one_shot(單次 agent 為 {run_id, took},否則為 null)與 instance_of / instance(共用憑證的執行個體,否則為 null);它的每個裝置另有 policy(exclusive 或 shared)、admission(共用卡的帳本,否則為 null)、same_card(提供同一個實體裝置的其他提供者,[{worker, device, policy, online, memory_budget}]),以及另一個提供者的上限適用時 slots 中的 limited_by({worker, device})。rejections 是未能連上的 agent 依名稱最近一次被拒的握手,新的在前,[{name, reason, at, peer}](at 為 epoch 秒,peer 為用戶端位址;只存在記憶體中,該名稱連線成功後清除);試圖搶用已連線 worker 名稱而被拒的嘗試只列在這裡,不會顯示在該 worker 的卡片上。worker registry 無法使用時回 503。
/api/workers/{id}/drainPOSTtoken不再把新的 run 放到該 worker;它正在執行的 run 會繼續。回傳該 worker 的資料;未知的 worker 回 404。
/api/workers/{id}/undrainPOSTtoken恢復把 run 放到該 worker。回傳該 worker 的資料;未知的 worker 回 404。
/api/workers/{id}DELETEtoken撤銷該 worker 的憑證、中斷它的連線(執行中的 run 以 interrupted 結束)並移除它;仍在佇列中等它的 run 會立即以 worker <id> was removed 失敗。回傳 {id, revoked, failed_runs}。之後它的 agent 都會被拒絕。未知的 worker 回 404。
/api/workers/enrollmentsPOSTtoken新的 enrollment token:body 為 {ttl_s?, uses?, label?, worker?, control_url?}(ttl_s 60 到 604800,預設 86400;uses 1 到 100,預設 1)。worker 會產生綁定該已知 worker 的重新核發 token(未知的 worker 回 404):只有這種 token 能加入已被使用的名稱,而且只能加入該名稱。回傳 {id, token, expires_at, uses_left, state, label, worker, created_at, control_url, command};command 是 cdui agent start --control <control_url> --token <token>(重新核發 token 另加 --name <worker>;伺服器知道憑證指紋且為 https 時另加 --ca-fingerprint <tls_fingerprint>),control_url 取自 body(須為不含 shell 字元的 http(s)://host[:port][/path],否則回 422),否則取自這個請求的 scheme 與 Host。Token 只出現在這個回應中。
/api/workers/enrollmentsGETtoken已發出的 enrollment token(新的在前),不含其秘密值:{enrollments: [{id, label, worker, created_at, expires_at, uses_left, state}], control_url, other_machine_urls, listening_on_loopback, tls_fingerprint, fingerprint_command}。state 為 pending、expired 或 used;過期與用完的 token 會保留在清單中直到刪除。other_machine_urls 是白名單中其他機器可能連得到的位址。tls_fingerprint 是 CODEFYUI_TLS_CERT_FILE 中第一張憑證公鑰的 sha256:<hex>,未設定或讀不到時為 null;fingerprint_command 是在 TLS proxy 主機上算出同一個值的 openssl 指令。
/api/workers/enrollments/{id}DELETEtoken撤銷(或清除)一個 enrollment token。未知的 id 回 404。
/api/workers/agent-commandPOSTtoken為另一個位址產生某個 enrollment token 的 agent 指令,與上面的 command 出自同一個函式:body 為 {control_url, token, worker?},回傳 {control_url, command}。Token 只放在 body(不放在 URL),伺服器不會比對也不會保存它。位址、token 或 worker 名稱格式不對時回 422。
/api/workers/enrollPOSTenrollment token{token, name, platform?, devices?, mounts?} -> {worker_id, worker_token}。用掉 token 的一次使用次數並建立該 worker。名稱已加入、或正被同機 agent 連線使用時回 409("worker X is already enrolled; remove it or create a re-key token for it"),除非 token 是綁定該名稱的重新核發 token,此時會核發新的憑證(舊憑證失效,其連線會被關閉)。未知、已過期或已用完的 token 回 401 並說明原因;重新核發 token 用在其他名稱時回 403;名稱不合法或為保留字(local、any、enroll、enrollments)回 400;超過限速回 429。被拒絕的加入不會扣次數。這個路徑只有 POST 不需要 session token。經由 SSH worker 的通道時,限速依 SSH worker 計算,而非依 client 位址。
/api/workers/sshGETtoken這台伺服器自己啟動的 SSH worker(遠端 Worker,透過 SSH 連線):{ssh_workers: [{id, target, port, identity, remote_cdui, remote_port, enabled, state, last_error, exit_code, tail, attempts, retry_at, up_since, gave_up, pid, remote_pid}], ssh_available, port_range, default_remote_cdui}。state 為 connecting(ssh 執行中、agent 尚未連線)、up、failed(ssh 已結束;last_error 是它最後輸出的幾行,retry_at 是下次嘗試的時間)或 stopped(已停用)。remote_port 是該 worker 取自 CODEFYUI_SSH_REMOTE_PORT_RANGE 的槽位:它在遠端主機上的狀態資料夾是 ~/.codefyui-ssh/<id>-<槽位>/(<id> 是這台伺服器的實例 ID),通道的 Unix socket 就在裡面。ssh_available 表示這台機器的 PATH 上有沒有 ssh。這個 GET 需要 session token。
/api/workers/sshPOSTtoken新增 SSH worker 並啟動它:{target, port?, identity?, remote_cdui?, name?}。target 為 user@host、host 或 ssh 的 Host 別名;identity 是這台機器上的金鑰檔(必須存在);remote_cdui 是遠端主機上的啟動器(預設 ~/CodefyUI/cdui);name 預設為 target 的主機名稱。值無法使用或找不到 ssh 時回 400,名稱已被某個 SSH worker 或其他 worker 使用時回 409。回傳該筆資料。
/api/workers/ssh/{id}/enablePOSTtoken恢復該 worker 接受 run,並重新啟動它的 ssh 連線;對已停止重試的啟用項目(gave_up: true,轉送被拒)則重試。未知的項目回 404。
/api/workers/ssh/{id}/disablePOSTtoken先讓該 worker 停止接新 run,再結束它的 ssh 連線:遠端 agent 會停止,仍在執行的 run 以 interrupted 結束。未知的項目回 404。
/api/workers/ssh/{id}DELETEtoken停止這個 SSH worker 並刪除它的項目;它的加入憑證保留(DELETE /api/workers/{id} 會撤銷憑證,也會一併移除 SSH 項目)。
/api/runs/{run_id}DELETEtoken刪除已完成的 run 及其事件、metrics、artifact 列與擷取的輸出;還在佇列或執行中則回傳 409。artifact 檔案會留在磁碟上,但 worker 為該 run 上傳的檔案除外:這裡的 run 資料夾,以及 S3 bucket 中除 output/ 以外的物件(S3 或 MinIO bucket);這些物件無法移除時,回應會帶有說明原因的 warning。
/api/runs/{run_id}/cancelPOSTtoken協作式停止——{run_id, status, cancelled};若 run 早已結束,cancelled: false(仍為 200)。
/api/runs/{run_id}/eventsGETopen回傳 ?cursor= 之後的事件;?wait= 最多長輪詢 60 秒,?limit= 上限為 2000。回傳 {run_id, status, active, events[{cursor, type, payload, ts}], cursor}。頁面可能少於 limit 筆;下一個 request 應使用回傳的 cursor。
/api/runs/{run_id}/metricsGETopen依 (name, step) 排序的已記錄純量序列;?name= 篩選,?format=csv 下載(UTF-8 BOM,儲存格可防公式注入)。JSON 形式也會列出 names。
/api/runs/{run_id}/artifactsGETopenrun 記錄的檔案(checkpoint、匯出內容、影像),由舊到新;?kind= 篩選,未知的 kind 會得到空清單。每筆為 {id, kind, path, meta, created_at, backend, mount_label, relative_path, worker_id, bucket}:path 是檔案在這台伺服器上的位置,這台伺服器沒有該掛載的 mount 資料列則為 null(此時只以 mount_label 與 relative_path 表示);backend 為 local(絕對路徑,掛載功能之前的資料列皆是)、mount(worker 寫在共用掛載上的檔案,以 mount_label 下的 relative_path 儲存,並轉換成這台伺服器的路徑)transfer(沒有掛載的 worker 上傳到這裡的檔案,存在這台伺服器資料夾下的 relative_path)或 s3(沒有掛載的 worker 上傳到 S3 bucket 的檔案,path 為 s3://<bucket>/<key>,relative_path 為物件 key,bucket 為 bucket);worker_id 是寫出檔案的 run 所在的 worker(local:這台伺服器);除 s3 外每筆的 bucket 皆為 null,除 mount 外每筆的 mount_label 皆為 null。
/api/runs/{run_id}/artifacts/uploadPOSTworker token正在某個 worker 上執行的 run 的輸出檔(儲存:沒有共用檔案系統)。Multipart,先表單欄位:kind、name(相對路徑)、place(預設 run,或 data)與選填的 sha256(會核對),再來是 file;內容以串流寫入磁碟。run 存放於 <資料夾>/runs/<run_id>/<kind>/<name>;data(writer 節點的檔案,name 位於 models/、media/ 或 output/ 之下)存放到這台伺服器資料夾中相同的相對路徑,不會覆蓋不同的檔案(較新的檔案加上 -1、-2 ... 後綴)。再次上傳相同內容回 200 與相同的鍵值。回應 {path, bytes, sha256},path 是 worker 之後回報的鍵值。Session token 可替任何 worker run 上傳;worker token 只能替在該 worker 上的 run 上傳(否則 409,run 不在任何 worker 上執行時亦同);兩者皆無則 403。上限為 CODEFYUI_MAX_UPLOAD_SIZE(413)。
/api/runs/{run_id}/artifacts/{artifact_id}/downloadGETopen以附件形式下載 transfer 資料列的檔案(run 資料夾中的檔案,或放進資料夾的 writer 檔案)。s3 資料列(S3 或 MinIO bucket)的物件從 bucket 串流送出,CODEFYUI_S3_DOWNLOAD=presign 時則以 307 導向預先簽署的 URL;連不上 bucket 時回 503。其他資料列(檔案就在它的 path)與資料夾(TensorBoard 資料夾)回 400;資料列或檔案不存在時回 404。
/api/sweepsPOSTtoken將參數 sweep 編譯成多個變體 run,全部排入佇列——回傳 201、sweep_id 與每個變體各一個 run_id。
/api/sweeps/{sweep_id}GETopen排名後的比較表——最佳優先的 variants、best、counts,以及存在時的 objective_warning;?format=csv 可下載。
/api/sweeps/{sweep_id}/cancelPOSTtoken取消每一個排隊中或執行中的變體:{sweep_id, state, cancelled, already_finished, variants[]},依變體索引順序每個一筆。
/api/studiesPOSTtoken送出一個 study:以單一明確目標,將各變體各重複數次,作為排隊的 child run。回傳 201 與該 study;帶有 Idempotency-Key header(或 idempotency_key)時,重送相同請求會回傳 200 與同一個 study,且不建立任何東西;同一個 key 用於不同請求則回傳 409。
/api/studiesGETopen由新到舊的清單,附上目前 attempt 依狀態分類的 counts;?status= 可指定一個狀態,或以 | 分隔的多個狀態,另有 ?limit=(最多 500)與 ?offset=。
/api/studies/{study_id}GETopenstudy 的 status、revision、owner(送出它的外掛,或 null)、halt(讓它暫停的預算,或 null)、budget_usage(每項預算的用量,以及哪一項已用完)、每個 attempt 及其 run_id、stop_reason 與已複製的證據、各變體的 aggregate(count、mean、std、values)、是否具排名資格、標示完全相同平手的 rankings,以及 last_cursor。
/api/studies/{study_id}/eventsGETopen?cursor= 之後的 study 稽核紀錄;study 仍在進行時,?wait= 最多長輪詢 60 秒。回傳 {study_id, status, revision, events[{cursor, type, payload, ts}], cursor}。
/api/studies/{study_id}/cancelPOSTtoken停止排程並取消進行中的 child;已完成的 attempt 會保留。body 可選填 {expected_revision}。已 succeeded 的 study,以及 study 已超過 expected_revision 時,回傳 409。
/api/studies/{study_id}/resumePOSTtoken繼續一個 interrupted、cancelled、failed 或 halted 的 study:已完成的重複會略過,被取消、中斷或遺失的重複會得到新的 attempt。body 可選填 {budget, expected_revision}:budget 會取代 study 的預算。其他狀態、仍已用完的預算,以及過期的 expected_revision 回傳 409。
/api/studies/{study_id}/variants/{index}/graphGETopen某個變體執行的圖(SECRET 值為空白):{study_id, variant_index, label, graph}。

Runs API。 POST /api/runs 接受 {"graph": {...}, "options": {...}, "name": "..."}。graph 使用已儲存圖的 JSON 格式(nodes、edges,以及選用的 presets、subgraphs 與 settings)。body 不是 JSON 或沒有 graph 物件時回傳 422;graph 無效(例如 nodes 為空或 settings.device 無效)或選項無效時回傳 400;run service 無法使用,或 interactive lane 的送出數超過上限時,回傳 503。選項 key 是封閉集合:device、seed、deterministic、record_outputs、lane、畫布旗標 verbose、graph_id、weights_persistent、backward_mode、auto_backward,引擎錯誤政策 error_mode、max_retries、target,以及 provenance("identity" 或 "content",參閱節點來源;"off" 或不提供則不記錄,也不儲存此鍵)。有提供 options.target.devices 時 run 的裝置是它的第一個,否則有提供 options.device 時就是它,否則為 graph 的 settings.device(參閱圖的 settings 物件),再否則為 cpu。target 是 {"worker", "devices"}:worker 為 local(預設)、已連線 worker agent 的名稱,或 any;devices 是同一種類的具體裝置集合。pool: "one-shot" 把 run 放到一次性 worker 上(遠端 Worker:一次性 worker);memory_gib、memory_source 與 wait 用於依記憶體共用的 worker 卡,memory_gib 搭配 local 時回 400(多 GPU:共用一張卡)。伺服器啟動以來從未連線過的 worker 名稱、不提供這些裝置的 worker、這台伺服器與它見過的 worker 都無法服務的 any run,worker target 搭配 interactive lane,以及在 agent 不支援的指名 worker 上使用 record_outputs,都回傳 400;已知但目前離線的 worker 會讓 run 排隊等它重新連線。在這台伺服器上,集合 run 占用每個裝置的 slot,並在第一個裝置上執行;在 worker 上則全部使用(參閱執行佇列:Workers 與執行架構)。run 的 status 只會是 queued、running、succeeded、failed、cancelled 或 interrupted。/events 有兩個上限:單一 payload 超過 CODEFYUI_RUN_EVENT_PAYLOAD_CAP_BYTES(128 KB)時,輸出會以省略標記取代後再儲存;response 超過 CODEFYUI_RUN_EVENTS_RESPONSE_CAP_BYTES(4 MB)時會結束。佇列順序、lane、保留政策與 cdui run 請見執行佇列。

Sweeps。 POST /api/sweeps 接受 base_graph、一份 sweep_spec(method 為 grid 或 random、seed、samples,以及 params[{node_id, param, values | range}])、必要的 objective(metric、direction 為 minimize 或 maximize,以及可省略、用來指定以哪個節點的 series 排名的 node_id)、同一組 options、name 與 seed_variants。最多建立 CODEFYUI_MAX_SWEEP_RUNS(32)個變體。每個變體都是一般的 /api/runs 列,可分別追蹤其 /events 端點。spec、驗證錯誤與取消行為請見執行佇列——Sweeps。

Studies。 POST /api/studies 接受 name、必要的 objective(node_id、metric 與 direction 三者皆必填)、base_graph、variants[{label, graph | ops[{node_id, param, value}]}]、repetitions(1 到 32)、seed、options(與 sweep 相同,但不可含 seed,也不可使用 interactive lane)、budget(max_runs、max_parallel_runs、max_run_seconds、max_active_seconds)、resume_policy(explicit 或 auto)以及 idempotency_key(以 plugin: 開頭的 key 會被拒絕:這個前綴用於區隔外掛 job)。study 的 status 只會是 queued、running、cancel_requested、succeeded、failed、cancelled、interrupted 或 halted(預算用完);attempt 的狀態則是 pending、submitting、queued、running、succeeded、failed、cancelled、interrupted、lost 或 timed_out(因 max_run_seconds 被停止)。預算由伺服器強制執行,請見實驗研究:預算。只有所有排定重複都成功並記錄到目標值的變體才會排名。sweep 表格會以失敗的 run 記錄到的值為它排名;在 study 中,這樣的 run 會讓所屬變體失去排名資格。每個 child 都是一般的 /api/runs 列,帶有 study_id 與 study_attempt_id。種子、排名、取消、繼續與重新啟動政策請見執行佇列——Studies。

執行環境​

run 會記錄兩項送出時的資訊;自 #344 起,另外記錄兩項實際執行時的資訊。

  • 送出時:options(裝置、種子、決定性等,請求未指定的部分由圖的 settings 補上),以及 git_commit、git_dirty 與 plugin_pins(使用者專案的 commit 與 lockfile 中啟用的外掛)。這些描述的是請求與專案,不是執行它的 CodefyUI 程式碼。
  • 開始執行時:fingerprint_digest 與 execution_facts,在 run 離開佇列、開始執行時寫入。因此在佇列中等待期間伺服器更新過的 run,記錄的是實際執行它的環境,而送出時的欄位維持原值。在 worker 上執行的 run,fingerprint_digest 描述的是該 worker。run 開始時,它是 worker 的 agent 連線時回報的指紋(#781);接著 run 子行程在載入 run 所用的程式碼、外掛與自訂節點後回報自己的指紋並取而代之,execution_facts.fingerprint_source 指出摘要是兩者中的哪一個。子行程的裝置資訊(accelerators、devices、CUDA_VISIBLE_DEVICES 與 HIP_VISIBLE_DEVICES)取自 agent 的文件,因為 agent 會把每個 run 限制在它自己的卡上;所以 agent 啟動後機器沒有任何變更時,兩個摘要相同。execution_facts.worker_id 指出是哪個 worker,run 自己的卡記錄在 execution_facts.visible_devices 與 device_aliases。

GET /api/system/fingerprint 回傳伺服器目前的指紋文件,schema_version 為 2。每份文件都包含所有鍵,無法讀取的資訊為 null:

鍵內容
codefyuiversion、commit、dirty 與 commit_source:伺服器從 checkout 執行時為 git,只有 frontend/dist/build-info.json 記有 commit 時為 build-info,否則為 null。每個伺服器行程只讀取一次,因為執行的是啟動時載入的程式碼。
python、platformPython 版本與實作;作業系統、核心版本、機器架構與 macOS 版本。
libraries、torch_build已安裝的 torch、torchvision、numpy 與 mlx 版本;torch 的建置 commit,以及 CUDA、HIP 與 cuDNN 版本。
accelerators、devicesCUDA、ROCm、MPS 與 MLX 是否可用、每張 CUDA 卡的名稱與 compute capability、pynvml 能讀到時的 NVIDIA 驅動程式版本;伺服器的預設裝置與提供的裝置清單。
plugins每個啟用的套件:source_kind、source、ref、version、revision、revision_kind、immutable 與 content_sha256。從儲存庫安裝的套件記錄其 commit(git-sha,immutable: true)。內建套件隨 checkout 一起發佈,因此其 revision 是 CodefyUI 的 commit(codefyui-commit),source 為 plugins/<id>;只有 checkout 乾淨(codefyui.dirty 為 false)時才是 immutable。連結的本機套件沒有不可變的 revision:它的 revision 是收集指紋時其檔案的摘要(content-sha256,immutable: false),能識別檔案但無法還原檔案,路徑也不會記錄。content_sha256 是每個可讀取目錄之套件的這份摘要(依排序後的相對路徑合併每個檔案位元組的 sha256,略過名為 .git、.hg、.svn、__pycache__、node_modules、.mypy_cache、.pytest_cache、.ruff_cache、.ipynb_checkpoints、.venv、venv、env、.tox、.nox、build、dist 與 *.egg-info 的目錄,以及名為 .DS_Store、Thumbs.db、*.pyc 與 *.pyo 的檔案,也就是版本控制、快取、虛擬環境、建置產物與檔案管理員的中繼資料;位於 git checkout 內的套件目錄改以 git ls-files 列出,因此計入已追蹤的檔案,以及未被 .gitignore 排除的未追蹤檔案;未安裝 git、目錄不在 checkout 內,或 git 超過 10 秒未回應時,改為走訪目錄),所以安裝後被原地修改的套件會改變摘要;目錄無法讀取時為 null。
custom_nodes、optional_packages每個啟用的自訂節點檔案的 sha256;每個 Package Center pip 套件的已安裝版本(未安裝為 null)。
env一份固定清單中、會影響數值或裝置選擇的環境變數值,例如 CUBLAS_WORKSPACE_CONFIG、CUDA_VISIBLE_DEVICES 與 ONEDNN_MAX_CPU_ISA。不讀取其他環境變數。

文件中不含主機名稱、使用者名稱、家目錄路徑或機密。digest 是文件正規化 JSON(鍵排序、無空白、UTF-8)的 sha256,涵蓋所有鍵:相同環境得到相同摘要,任何一項記錄的資訊改變都會得到不同摘要。每份不同的文件只儲存一次;保留策略與 DELETE /api/runs/{run_id} 都不會刪除它,因此 run 刪除後,/api/system/fingerprints/{digest} 仍能查到該摘要。

儲存的文件保留寫入時的 schema_version。版本 1(CodefyUI 3.1)的 plugins 項目沒有 immutable 與 content_sha256,連結的本機套件 revision 為 null;版本 2 加入這兩個鍵與內容 revision。即使是同一台機器,版本 1 與版本 2 的文件也不會有相同摘要。

execution_facts 把請求與實際結果並列。requested 包含儲存的選項中的 device、seed 與 deterministic,以及圖中的 graph_settings_device 與 graph_settings_seed。resolved 包含排程器解析出的裝置(例如 auto 會變成 mps:0)、交給引擎的種子與決定性旗標,以及 numerics:run 開始時 torch 的預設 dtype、float32 矩陣乘法精度、TF32 與 cuDNN benchmark 開關,以及執行緒數。目前沒有 run 層級的精度選項;混合精度是訓練節點的參數,記錄在圖快照中。具有自己 device 參數的節點可以為該節點覆寫 run 的裝置。fingerprint_source 指出 fingerprint_digest 描述的是哪個行程:process(執行此 run 的這台伺服器)、worker-hello(連線時的 worker agent;run 子行程尚未回報,或無法回報)、worker-run(worker 的 run 子行程,它也會填入 resolved.numerics),或沒有記錄指紋時為 null。worker 上的 run 在子行程回報之前沒有 resolved.numerics。execution_facts 的 schema_version 為 3;在此之前寫入的列沒有 fingerprint_source。

已執行的 run 結束時,無論結果為何,execution_facts 都會加上 peak_memory。CUDA run 會為伺服器行程佔用記憶體的每張卡各記錄一筆,run 自己的卡排在最前面,所以釘選到其他卡的節點也會算進去:{"cuda:0": {"allocated_bytes": N, "reserved_bytes": M, "exact": false}},是 run 期間配置器的最高水位(max_memory_allocated、max_memory_reserved)。MPS run 記錄 {"mps": {"held_bytes": N, "exact": false}}:run 結束時 Metal 驅動程式為伺服器行程佔用的記憶體,包含快取。MPS 沒有峰值計數器,所以這不是峰值。CPU run 也用同樣方式量測,所以節點釘選到的 CUDA 卡會出現在對應表中。沒有任何卡被使用的 run(單純的 CPU run),或伺服器沒有載入 torch、從未初始化 CUDA 時的 run,記錄 null。在 run 開始時重設過計數器的卡上,run 期間沒有配置的保留記憶體不列入,因為那是先前的 run 留下的快取。在執行前就停止的 run,或執行器失敗且沒有回報的 run,不記錄(沒有這個鍵)。在伺服器行程內執行的 run,exact 一律為 false,因為這些 run 共用同一個 CUDA context。在 worker 上執行的 run 由只執行這一個 run 的子行程執行,所以它的 CUDA 項目為 exact: true,且不會標 shared;MPS 的數字因為包含驅動程式的快取,在任何地方都維持 exact: false。峰值計數器屬於整個行程,所以 run 只有在該卡上沒有其他行程內的 run 時才會在開始時重設計數器;否則不重設,以免抹掉另一個 run 的峰值,並把該卡標為 "shared": true,表示數字也包含另一個 run。Runs 面板的詳細資訊標題列以「峰值記憶體」顯示最大的 CUDA 值,MPS 則以「結束時佔用記憶體」顯示,滑鼠移上去會列出每個裝置。

摘要與種子相同,並不保證數值完全相同。非決定性的 kernel 與執行緒排程仍可能改變結果,相同種子在不同硬體或函式庫版本上也可能得到不同數值。摘要只回答兩個環境是否相同。

節點來源​

指紋說明的是哪份程式碼執行了 run,並不說明圖讀取了哪些資料或權重。使用 run 選項 provenance 時,讀取資料集或載入模型的節點也會記錄這些資訊,每個節點一筆(#344)。Queue on... 對話框中的對應選項是「資料與模型來源」。

  • "identity":檔案的位置、數量、大小、最後修改時間,以及識別雜湊:每個檔案的路徑、大小與修改時間合併後的雜湊(content.method: "stat")。不讀取檔案內容,成本約等於列出檔案。
  • "content":同上,再加上內容雜湊(content.method: "sha256"):每個檔案位元組的 sha256,依排序後的相對路徑合併。單一檔案的摘要就是 sha256sum 印出的值。雜湊是增量的:每個檔案的雜湊依其路徑、大小、修改時間與 inode 保存在 <user data>/cache/content-hashes/,這些值未變的檔案不會再讀一次,因此大型資料集只有第一次 run 會完整讀取。快取不會放在資料集裡,遺失快取只代表要重新讀取檔案。依同一規則,原地改寫但大小、修改時間與 inode 都不變的檔案,會沿用先前的雜湊。

識別雜湊不是內容雜湊:保持大小不變、且落在同一個時間戳刻度內的修改,或會重設修改時間的複製,都可能讓它與內容不一致。只在兩筆紀錄的 content.method 相同時比較 content.digest。

兩種識別走訪相同的檔案。走訪會跟隨目錄的符號連結,因此類別資料夾連結到另一顆磁碟的資料集資料夾,會以連結到的檔案識別;連回走訪目前所在目錄的連結(迴圈)不會跟隨,並以 note 說明。走訪只略過版本控制目錄(.git、.hg、.svn)、__pycache__、工具快取(node_modules、.mypy_cache、.pytest_cache、.ruff_cache、.ipynb_checkpoints)與 *.pyc / *.pyo 檔;其餘檔案都依節點的載入器讀取的方式雜湊,因此名為 build 或 env 的類別資料夾也屬於資料集。較長的產生內容清單只適用於套件目錄(參閱執行環境中的 plugins)。

不使用此選項時不記錄任何東西,儲存的 options 不含 provenance 鍵,run 的事件與結果也不變。紀錄在每個節點完成後,依它的參數與輸出收集,不改變節點的行為。在 worker 上由 run 子行程收集,再由控制面儲存。

會記錄來源的節點型別:

節點kind記錄內容
CSVReaderdataset該檔案;rows 是節點輸出 tensor 的列數。
Datasetdatasettorchvision 資料集名稱與 split,以及 data_dir 下該資料集自己的目錄(MNIST/、cifar-10-batches-py/);rows 是資料集長度。torchvision 資料集沒有版本。
ImageFolderDatasetdataset該 split 的資料夾;rows 是影像數。
HuggingFaceDatasetdataset儲存庫 id、subset 與 split。revision.resolved 是快取檔案來源的資料集儲存庫 commit(hf-commit,從 datasets 快取路徑讀取,否則讀本機 hub 快取的 refs/main),內容識別涵蓋 Arrow 快取檔,rows 是資料集長度。此節點不固定版本,因此 revision.requested 為 null(預設分支)。
KaggleDatasetdataset資料集 slug。revision.resolved 是 kagglehub 下載的版本(kaggle-version),revision.requested 是 slug 固定的版本(若有);rows 是影像數。
ModelLoader、CheckpointLoadermodel權重檔。本機 checkpoint 沒有版本,因此以內容識別作為它的識別。
HFTextGeneratemodel模型儲存庫。revision.requested 是 Package Center 目錄固定的版本,revision.resolved 是已下載 snapshot 的 commit(hf-commit),內容識別涵蓋 snapshot 的檔案。

每筆紀錄(schema_version 1)都包含下列所有鍵;未知的資訊為 null,原因不明顯時 notes 會說明:

{
"schema_version": 1, "node_id": "csv", "node_type": "CSVReader",
"kind": "dataset", "mode": "content",
"source": {"type": "file", "name": null, "location": "files",
"path": "iris.csv", "subset": null},
"split": null,
"revision": {"requested": null, "resolved": null, "kind": null},
"content": {"method": "sha256", "digest": "e036f888...", "exists": true,
"files": 1, "bytes": 4551, "latest_mtime": "2026-10-21T11:46:52Z",
"truncated": false, "unreadable": 0, "reused": 1, "hashed": 0},
"rows": 150, "notes": ["rows counts the rows the node kept"]
}

source.path 一定不是絕對路徑,而是相對於找到檔案的 CodefyUI 目錄,該目錄由 source.location 指出(models、files、data、project、working-dir、hf-cache、packs);不在這些目錄下的檔案只記錄檔名,location 為 "external"。檔案系統根目錄(/、C:\)或家目錄不算這些目錄,因此從 / 啟動的伺服器(systemd unit 預設的工作目錄、容器的 WORKDIR /)同樣把外部檔案記為 external。節點未指定檔案時 content 為 null。任一輸入不存在、檔案或目錄無法讀取(unreadable 計數),或走訪在 200,000 個檔案處停止(truncated)時,content.digest 為 null;notes 列出不存在、無法讀取或未跟隨的項目。外掛註冊的 provider 也得到相同結構:它沒有提供的鍵為 null。reused 與 hashed(僅內容模式)分別計算雜湊來自快取的檔案數,以及這次 run 讀取的檔案數。GET /api/runs/{run_id} 以 provenance 回傳這些紀錄,Runs 面板在 run 詳細資訊的「資料與模型」下顯示,紀錄會隨 run 一起刪除。

執行輸出與狀態​

端點方法驗證說明
/api/execution/outputs/{run_id}GETopen列出某次 run 擷取的連接埠。
/api/execution/outputs/{run_id}DELETEtoken清除某次擷取的 run。
/api/execution/outputs/{run_id}/{node_id}/{port}GETopen取得一個已擷取的張量(支援 ?slice=0,:,: 與 ?max_elements=,預設 4096、上限 1,000,000);切片仍然過大時回傳 413。?preview=true(不可與 slice 同時使用)會讓超過 max_elements 的張量回傳伺服器依 shape 選出的前段切片,回應中帶有 slice、sliced_shape 與 truncated: true;未超過上限的張量完整回傳。節點已執行但這個 port 沒有產生值(None)時回傳 204;run 或 port 沒有任何紀錄時回傳 404。
/api/execution/outputs/{run_id}/{node_id}/{port}/statsGETopen回傳單一已擷取 port 的伺服器端摘要統計:固定的一組純量與 64-bin histogram;label tensor 則回傳值計數。無論 tensor 大小,response 通常只有一到兩 KB。超過 CODEFYUI_STATS_SAMPLE_THRESHOLD(4,000,000 個元素)的 tensor 會進行取樣。節點已執行但這個 port 沒有產生值(None)時回傳 204;run 或 port 沒有任何紀錄時回傳 404。
/api/execution/outputs/{run_id}/{node_id}/__steps_indexGETopen某節點的步驟追蹤 metadata(檢視器 → 步驟分頁)。
/api/execution/outputs/{run_id}/{node_id}/__grad_indexGETopen已擷取的梯度 metadata(檢視器 → 反向分頁)。加上 ?inner=true 時,兩種索引都會列出區塊或預設組合卡片內部節點的紀錄,每筆項目以 node_id 標示所屬節點。
/api/execution/outputs/{run_id}/value?node_id=&port=GETopen與 {node_id}/{port} 路徑形式相同,用於路徑放不下的節點 id:子圖內的節點(<instance>/<node>)。同樣接受 slice、max_elements 與 preview。
/api/execution/outputs/{run_id}/stats?node_id=&port=GETopen與 /stats 路徑形式相同,用於這類 id。
/api/execution/outputs/{run_id}/steps?node_id=GETopen與 __steps_index 相同,用於這類 id。
/api/execution/outputs/{run_id}/grads?node_id=GETopen與 __grad_index 相同,用於這類 id。
/api/execution/state/resetPOSTtoken重設已保存的層權重(單一節點或單一圖表)。
/api/execution/state/listGETopen列出保存了多少模組(診斷用)。

已發佈的應用程式與 API key​

端點方法驗證說明
/api/appsGETtoken列出應用程式——slug、graph_name、active_version、versions_count、record_io。
/api/apps/{slug}/publishPOSTtoken將指定的已儲存圖表凍結成該 slug 的下一版並啟用(新 slug 使用 "create": true);先執行 /run 的前置檢查。
/api/apps/{slug}/versionsGETtoken每一個版本及其 note、provenance(git_commit、git_dirty)與 active 旗標。
/api/apps/{slug}/activatePOSTtoken將 slug 指向任一既有版本({"version": n})——也是 rollback 路徑。
/api/apps/{slug}/unpublishPOSTtoken設定 active_version = null;版本與 run 都會保留。
/api/apps/{slug}PATCHtoken不需重新發佈即可切換 record_io。
/api/apps/{slug}DELETEtoken移除應用程式、它的所有版本與所有 run 紀錄——無法復原。
/api/apps/{slug}/invokePOSTAPI key執行作用中的版本:body 與 envelope 都和 /api/graph/run/{name} 相同,並填入 app 與 version。
/api/apps/{slug}/openapi.jsonGETkey-or-token作用中版本的一份獨立 OpenAPI 3.1 文件。
/api/apps/{slug}/runsGETkey-or-token由新到舊的 run 紀錄,僅含 metadata;以 ?before= 與 ?before_id= 分頁。
/api/apps/{slug}/runs/{run_id}GETkey-or-token單一紀錄,包含其輸入、輸出與節點 timings。
/api/keysPOSTtoken產生 key({"name"});完整的 cdui_... token 只會在這次回應中出現。
/api/keysGETtoken列出 key——id、name、prefix、timestamps,絕不含 secret;已撤銷的列仍會列出。
/api/keys/{key_id}/revokePOSTtoken軟性撤銷;找不到時回傳 404 key_not_found。

生命週期、run 紀錄、分頁與每個應用程式的 OpenAPI 文件,請見發佈。

自訂節點與外掛​

端點方法驗證說明
/api/custom-nodesGETopen列出自訂節點。
/api/custom-nodes/uploadPOSTtoken上傳一個自訂節點。
/api/custom-nodes/togglePOSTtoken啟用/停用一個自訂節點。
/api/custom-nodes/{filename}DELETEtoken刪除一個自訂節點。
/api/pluginsGETopen列出已安裝的外掛包。
/api/plugins/catalogGETopen列出型錄與已安裝的外掛。每列包含其狀態:已安裝、已停用、明確移除或檔案遺失。
/api/plugins/generationGETopen回傳重載計數器,每次重新探索節點與外掛都會加一。只有在頁面載入時已安裝啟用中的連結外掛,編輯器才會輪詢它,並在數值改變時重新啟用外掛前端;參閱外掛。
/api/plugins/{id}GETopen取得某外掛的 manifest 與 README。
/api/plugins/reloadPOSTtoken與 POST /api/nodes/reload 相同。
/api/plugins/inspectPOSTtoken+loopback在單一個已解析 commit 上檢查型錄名稱、owner/repo 或 URL。回傳安裝需求並存入 inspection_id,但不安裝外掛。
/api/plugins/installPOSTtoken+loopback安裝 inspection_id 指定的 manifest;回傳 202 與 job_id。伺服器使用已檢查的 manifest,不接受這個 request 提供安裝 metadata。
/api/plugins/jobs/{job_id}/eventsGETopen回傳安裝 job 在 ?cursor= 之後的 log 與進度。?wait= 最多長輪詢 60 秒。job 可能以 needs_restart 結束,並包含伺服器停止後要執行的指令。
/api/plugins/jobs/{job_id}/cancelPOSTtoken+loopback取消執行中的安裝並移除部分寫入的內容。
/api/plugins/{id}/updatePOSTtoken+loopback檢查外掛的 GitHub repository 是否有更新。回傳 202 {"job_id"}、200 {"status": "up_to_date", "sha"},或在更新需要額外權限時回傳 200 {"status": "needs_consent", "inspection", "capabilities_added", "allowed_modules_added"}。若需同意,請呼叫 POST /api/plugins/install {"inspection_id", "accept_capabilities", "trust_author"} 完成更新,不需使用 force。更新會保留啟用狀態。內建外掛、本機連結外掛,或 manifest 已改用另一個外掛 id 的 repository,會回傳 400 not_updatable。
/api/plugins/{id}DELETEtoken+loopback解除安裝外掛。內建外掛會保留檔案並記錄為已移除;本機連結目錄不會變更。Python 套件也會保留;response 會列出其他地方都不再需要的套件,並附上移除它們的指令。
/api/plugins/{id}/enablePOSTtoken啟用一個已安裝的外掛並重新探索。
/api/plugins/{id}/disablePOSTtoken停用它,但不解除安裝。
/plugins/{id}/frontend/{path}GETopen當已啟用外掛的 manifest 宣告 [frontend] 時,提供其 frontend/ 目錄中的檔案;否則回傳 404。route 會在每個 request 重讀 lockfile,因此安裝、啟用、停用與解除安裝不需重啟即可生效。Cache-Control: no-cache 會要求瀏覽器在更新後重新驗證。
/plugins/{id}/assets/{path}GET, HEADopen提供已啟用外掛 assets/ 目錄中的檔案,使用偵測到的 media type;未知時使用 application/octet-stream。此 route 使用與 frontend route 相同的每次 request lockfile 檢查與重新驗證。目錄 request 與外掛目錄以外的路徑都會被拒絕。

:::note 安裝外掛需要綁定回送位址的伺服器 inspect、install、job cancel、update 與 DELETE 需要上述回送位址閘門。這些操作可以下載、安裝或移除第三方程式碼,檢查來源時也會依呼叫端提供的內容連線 GitHub。reload、enable 與 disable 只處理伺服器上已有的程式碼,因此只需要 token。這些 route 的拒絕回應使用 busy、already_installed、consent_required 等可供機器判讀的 code;請參閱外掛中心下的表格。job 事件帶有英文的步驟 label,以及英文的失敗 message 與 hint。client 應以步驟 id(resolve、download、extract、verify、deps、stage、lock、reload)判斷:編輯器會翻譯這些 id,只有遇到不認得的 id 時才顯示英文 label。失敗訊息維持英文。 :::

外掛 job​

外掛可以用自己的 id,把持久化的工作交給伺服器,做法依循 Graph Copilot 外掛的 backend agent contract(#343)。study 類型(spec_version 1)的 job 就是一個 study,其 owner 為該外掛:它的 spec 是一個 POST /api/studies 的 body,下列 route 與 /api/studies 一一對應。每個 job 也會出現在 GET /api/studies 與 Studies 面板中。伺服器不載入外掛提供的伺服器端程式碼(AgentJobHandler);study 是唯一的類型。

EndpointMethodAuth說明
/api/plugins/{plugin_id}/jobs/kindsGETopen{plugin_id, api_version, kinds[{kind, spec_version, description}]}。沒有外掛 job 功能的伺服器回傳 404,外掛可以在這裡檢查功能是否存在,否則繼續使用頁面內的引擎。
/api/plugins/{plugin_id}/jobsPOSTtoken送出 {kind, spec_version, spec, idempotency_key?}。idempotency key 為必填(Idempotency-Key header、body 的 idempotency_key 或 spec 的 idempotency_key;三者必須一致),並以外掛為範圍。回傳 202 與 job(study 詳細資料,加上 job_id、plugin_id、kind、spec_version、api_version、created: true 與 request_digest);以同一個 key 重送回傳 200 與同一個 job;同一個 key 用於其他請求回傳 409。外掛未安裝回傳 404,已停用回傳 409,未知的 kind 或 spec_version 回傳 400,spec 不符合 study schema 回傳 422。
/api/plugins/{plugin_id}/jobsGETopen該外掛的 job,由新到舊,附上 counts;?status=、?limit= 與 ?offset= 與 study 相同。
/api/plugins/{plugin_id}/jobs/{job_id}GETopen一個 job,內容與 GET /api/studies/{id} 相同。其他外掛的 job,或送到 /api/studies 的 study,回傳 404。
/api/plugins/{plugin_id}/jobs/{job_id}/eventsGETopen?after=(或 ?cursor=)之後的 job 稽核紀錄;每個事件另帶有 sequence(即它的 cursor)。?wait= 最多長輪詢 60 秒。
/api/plugins/{plugin_id}/jobs/{job_id}/cancelPOSTtoken與 study 的 cancel 相同,可選填 {expected_revision}。外掛停用時仍可使用。
/api/plugins/{plugin_id}/jobs/{job_id}/resumePOSTtoken與 study 的 resume 相同,可選填 {budget, expected_revision}。外掛必須為啟用狀態。
/api/plugins/{plugin_id}/jobs/{job_id}/variants/{index}/graphGETopen某個變體執行的圖,用來把選定的變體開成分頁。

Graph Copilot。 使用者在對話中核准實驗計畫後,外掛可以把執行交給伺服器:以 GET .../jobs/kinds 確認功能存在;以 POST /api/plugins/graph-copilot/jobs 送出 kind: "study",並以計畫作為 study spec(變體為套用在目前圖上的 ops、目標為明確的 node_id + metric、重複次數、種子與 budget),idempotency key 由核准的計畫產生,確保重送時不會啟動第二次;接著以 GET .../jobs/{job_id}/events?after= 或 GET .../jobs/{job_id} 從任何分頁追蹤,並以 GET .../variants/{index}/graph 套用勝出的變體。分頁關閉後 job 仍會繼續執行。模型對話與核准仍在外掛的頁面中進行;伺服器不執行任何模型。

選用套件包​

端點方法驗證說明
/api/packsGETopen列出所有套件包、已安裝項目、下載大小,以及此伺服器是否支援安裝,另包含 active_job、last_restart_job(最近一次 restart mode 安裝的結果,沒有則為 null)、remote_install_allowed、launch_mode、restart_available 與 gpu。
/api/packs/{id}/installPOSTtoken+loopback啟動安裝 job——回傳 202 {"job_id"};套件包與外掛合計同時只執行一個 job。body(選用;未知 key 會回傳 422):items(預設為整個套件包扣除已下載的內容)、mode——live(預設)或 restart,後者會讓 helper 在伺服器自行停止後安裝套件(參閱讓伺服器重新啟動的安裝)——variant(僅 GPU 套件包:選哪個 torch wheel;不在 allowlist 的名稱會回傳 422),以及 from_dir(伺服器上由 cdui packs export 做成的離線套件包的絕對路徑;相對路徑回傳 422,型錄無法擔保的套件包,或對 restart mode 套件包指定 from_dir,回傳 400;參閱離線安裝)。在 job 建立前就會拒絕的情形:未知項目回傳 400;缺少必要套件包時回傳 {detail, blocked_by};另一個安裝執行中時回傳 409 {detail, job_id[, reason]};restart mode 無法使用或被拒絕時回傳 409 {detail, command[, reason]}(請自行執行 command);磁碟容不下下載內容時回傳 507 {detail, needed, free};restart helper 無法啟動時回傳 500。
/api/packs/jobs/{job_id}/cancelPOSTtoken+loopback取消執行中的 job。進行中的下載會停止,不會完成目前檔案。由於 graph 與套件包下載共用一個 transfer session,取消操作也會中斷 graph 當時正在進行的 Hugging Face 資料集或 tokenizer 下載。
/api/packs/jobs/{job_id}/eventsGETopen回傳 job 在 ?cursor= 之後的 log 與進度事件。?wait= 最多長輪詢 60 秒。
/api/packs/{id}/items/{item_id}DELETEtoken+loopback刪除一個已下載的模型並釋放其位元組——未知項目回傳 404;該套件包自己的安裝執行中時回傳 409 {detail, job_id};其他行程持有檔案而未能刪除時(Windows),則回傳 removed: false。套件包的 Python 套件無法從執行中的伺服器移除——參閱 cdui packs remove。

回送位址閘門用來保護會在伺服器 Python 環境中執行 package manager 的操作。型錄會限制可要求安裝的套件。型錄、restart mode 與 cdui packs 請見選用套件包。

版本控制​

這些 route 支援版本控制分頁。它們在伺服器啟動時指定的專案目錄(--project)中執行伺服器本身的 git。讀取為 open,每個寫入都需要 session token,而且沒有回送位址閘門。

端點方法驗證說明
/api/git/statusGETopen{repo: {state, project_dir, git_version, nested_toplevel}, status}。repo.state 為 no_project、git_missing、git_too_old、not_repo 或 ready;ready 以外的狀態仍回傳 200,且 status: null。nested_toplevel 指出 not_repo 的專案目錄位於哪個 repository 之內。
/api/git/logGETopen一頁歷史紀錄,由新到舊:{commits[{sha, short, parents, author_name, author_email, authored_at, refs, subject, body}], has_more, unborn}。?skip= 為 0 到 2147483647(預設 0),?limit= 為 1 到 100(預設 30);超出範圍回傳 422。
/api/git/commits/{sha}/filesGETopen某個 commit 相對於其第一個 parent 變更的檔案:[{path, orig_path, kind, xy, score}]。
/api/git/diffGETopen單一檔案的 patch:?path=、?scope=worktree|index|commit,以及 ?sha=:scope=commit 必須提供它,另外兩種 scope 則會拒絕它(空的 sha= 視為沒有提供)。?blobs=1 會另外回傳兩側的完整內容。回傳 {patch, binary, truncated, old_ref, new_ref, old_text, new_text, old_missing, new_missing};patch 超過 1 MiB 的部分會被截掉。
/api/git/fileGETopen單一檔案在 ?ref=(HEAD、index、worktree,或 7 到 40 個十六進位字元的 commit id)的內容:{text, binary, size, truncated}。text 最多 2 MiB;超過時 truncated 為 true,text 可能為空。在 worktree 讀取被忽略的檔案會回傳 403 ignored。
/api/git/configGETopen{name, email, name_scope, email_scope};scope 為 local、global、system,未設定時為 null。
/api/git/branchesGETopen{current, detached, local[{name, sha, current, upstream, ahead, behind, gone, subject, committed_at}], remote[{name, remote, sha, subject, committed_at}]}。
/api/git/remotesGETopen[{name, fetch_url, push_url}]。URL 中的密碼或 token 會顯示為 ***。
/api/git/stashesGETopen由新到舊:[{index, message, branch, created_at}];index 是 git 的 stash@{N}。
/api/git/initPOSTtoken把專案目錄變成 repository,並寫入與 cdui project init 相同的 .gitignore(第一行為 .env)與 .gitattributes。既有的 .gitignore 若沒有忽略 .env,會在最後加上這一行;其他既有檔案維持不變。不需要 body。
/api/git/stagePOSTtoken{paths: [...]}(最多 500 個)或 {all: true},只能擇一;兩者都給、都不給,或清單為空時回傳 422。
/api/git/unstagePOSTtoken相同的 body;把這些路徑移出 index。
/api/git/discardPOSTtoken相同的 body;已追蹤的檔案從 index 還原,未追蹤的檔案則刪除。被忽略的檔案永遠不會被動到。
/api/git/commitPOSTtoken{message, all?: false, amend?: false},message 最多 10,000 個字元;detail.sha 與 detail.short 是新 commit 的 id。
/api/git/configPUTtoken{name?, email?},一律寫入這個 repository 自己的設定(--local);兩者都沒有時回傳 400 invalid_value。回傳寫入後讀到的身分,格式與 GET 相同。
/api/git/branchesPOSTtoken{name, checkout?: true, start_point?}:建立分支,除非 checkout 為 false,否則切換過去。
/api/git/checkoutPOSTtoken{target, kind: "local" | "remote"}:切換到本機分支,或建立追蹤遠端分支的本機分支(此時 target 為 <remote>/<branch>)。changed_paths 列出有變動的檔案。
/api/git/branches/{name}PUTtoken{new_name}:重新命名分支。{name} 可以包含 /。
/api/git/branches/{name}DELETEtoken刪除已合併的分支。未合併的分支回傳 409 branch_not_merged,直到加上 ?force=1 再送一次;目前所在的分支回傳 400。
/api/git/remotesPOSTtoken{name, url}:新增遠端。url 必須是 https://、ssh://、file:// 或 user@host:path,否則回傳 400 invalid_url;名稱已被使用時回傳 409 remote_exists。
/api/git/remotes/{name}PUTtoken{url}:讓遠端指向另一個 URL,URL 規則相同。
/api/git/remotes/{name}DELETEtoken移除遠端。
/api/git/stashesPOSTtoken{message?, include_untracked?: true};{} 是有效的 body(完全沒有 body 的 request 回傳 422)。detail.stash 一律為 0。沒有東西可以 stash 時回傳 400。
/api/git/stashes/{index}/popPOSTtoken套用 stash 並將它丟棄。pop 發生衝突時回傳 409 conflict,並保留該 stash。
/api/git/stashes/{index}/applyPOSTtoken套用 stash 並保留它。
/api/git/stashes/{index}DELETEtoken丟棄一個 stash。在這條與上面兩條 route 中,目前清單裡沒有的 index 回傳 404,負數 index 回傳 422。
/api/git/merge/abortPOSTtoken復原進行中的合併;沒有進行中的合併時回傳 404。不需要 body。
/api/git/resolvePOSTtoken{path, side: "ours" | "theirs" | "mark"},檔案必須是 status 列為衝突的檔案,否則回傳 400 path_not_in_status。mark 會以磁碟上的現況暫存該檔案。
/api/git/fetchPOSTtoken{remote?};一般的 body 是 {}。會 fetch 並 prune。
/api/git/pullPOSTtoken{strategy?: "ff-only" | "merge"}(預設 ff-only):先 fetch,再合併 upstream。ff-only 下分支已分歧時回傳 409 diverged;合併發生衝突時回傳 409 conflict,合併會維持進行中。
/api/git/pushPOSTtoken{remote?, set_upstream?: false}。set_upstream: true 會把分支發佈(push -u)到 remote;省略 remote 時,分支有 upstream 就發佈到 upstream 所在的遠端,否則發佈到唯一的遠端(有多個遠端時回傳 400 invalid_value,沒有遠端時回傳 409 no_remote)。沒有 set_upstream: true 卻帶 remote 時回傳 400。沒有 upstream 的一般 push 回傳 409 no_upstream。detail.published 指出實際執行的是哪一種。
/api/git/syncPOSTtoken先 pull(只做 fast-forward)再 push;分支沒有 upstream 或 upstream 已消失時則改為發佈。不需要 body。遇到第一個失敗就停止,之前已完成的步驟維持完成;detail.steps 列出執行過的步驟。
  • Response。 除了 PUT /api/git/config,每個寫入都回傳 {status, changed_paths, head, detail}:最新的 status、這次操作變動的檔案、操作後的 HEAD,以及各操作專屬的額外資訊。
  • 錯誤。 失敗時回傳 {"detail": {"code", "message", "hint", "stderr"}}。code 來自編輯器會翻譯的固定清單,stderr 是 git 自身輸出的結尾;message、hint 與 stderr 中看起來像憑證的內容都會被遮蔽。busy(409)另外帶有 op,即目前持有鎖的操作。503 git_service_unavailable 表示伺服器啟動時沒有建立 git 服務。
  • Repository 狀態。 除了 status 與 init,每條 route 都需要 repo.state 為 ready,否則以該狀態作為 code 失敗:no_project(409;伺服器啟動時沒有使用 --project)、git_missing(503)、git_too_old(409)或 not_repo(409)。init 只需要專案目錄與 git 2.23 以上版本。
  • 一次一個操作。 有寫入正在執行時,第二個寫入回傳 409 busy。fetch、push,以及 pull 與 sync 的網路步驟使用另一把鎖,因此 push 傳輸期間仍然可以 commit,而第二個網路請求才會收到 409 busy。
  • Dotenv 檔案。 /diff 與 /file 在任何 ref 都會拒絕任一路徑段為 .env 或 .env.*(.env.example 除外;比對不分大小寫)的路徑,回傳 403 ignored。

檔案、模型、影像與媒體​

端點方法驗證說明
/api/filesGETopen列出已上傳的資料檔(.csv、.tsv、.txt、.json)——CSVReader 等節點背後的 DATA_FILE 下拉選單。
/api/files/uploadPOSTtoken上傳資料檔(只接受上述四種副檔名)。
/api/files/download/{filename}GETopen下載資料檔。
/api/files/{filename}DELETEtoken刪除資料檔。
/api/modelsGETopen列出已上傳的模型檔案。
/api/models/uploadPOSTtoken上傳模型權重檔。
/api/models/download/{filename}GETopen下載模型權重檔(支援巢狀路徑)。
/api/models/{filename}DELETEtoken刪除模型檔案。
/api/imagesGETopen列出已上傳的影像檔案。
/api/images/uploadPOSTtoken上傳影像檔案。
/api/images/download/{filename}GETopen下載影像檔案。
/api/images/{filename}DELETEtoken刪除影像檔案。
/api/mediaGETopen遞迴列出 run 產生的媒體(.mp4、.webm、.gif、.png、.jpg、.jpeg)。
/api/media/{filename}GETopen使用真正的 Content-Type 與 Range 支援,以 inline 形式提供單一媒體檔,因此 <video> 元素可以 seek。唯讀:檔案只會因節點(VideoWrite)寫入而出現在這裡——沒有 upload,也沒有 delete。

LLM 代理​

端點方法驗證說明
/api/llm/chatPOSTtoken從設定的 provider 串流統一格式的 SSE chat completion(OpenAI / OpenRouter / Anthropic / OpenAI-Codex / 自訂 OpenAI 相容端點)。
/api/llm/modelsPOSTtoken列出某個 provider 可用的模型。
/api/llm/codex/loginPOSTtoken啟動 OpenAI-Codex(ChatGPT 帳號)OAuth 登入流程。
/api/llm/codex/statusGETopen回報 OpenAI-Codex OAuth 登入狀態。
/api/llm/codex/logoutPOSTtoken清除已儲存的 OpenAI-Codex OAuth token。

限制與錯誤​

  • Body 大小。 MAX_RUN_BODY_BYTES(64 MB,CODEFYUI_MAX_RUN_BODY_BYTES)限制每個 request body,並在位元組抵達時逐步計數,包括 chunked request。四條 route 改用 MAX_UPLOAD_SIZE(500 MB,CODEFYUI_MAX_UPLOAD_SIZE):/api/files/upload、/api/images/upload、/api/models/upload 與 /api/custom-nodes/upload。這些 route 另保留 64 KB 給 multipart metadata,並將設定的上限套用到檔案本身。超過任一上限時會回傳 413。

  • 檔案名稱。 四條上傳 route 會以檔名中最後一個 / 之後的部分儲存檔案;名稱若是 Windows 無法儲存的,會回傳 400:含有 < > : " \ | ? * 或控制字元、以 UTF-8 計算超過 255 bytes(一個中文字占 3 bytes)、只由點組成,或是 con.csv 這類裝置名稱。這條規則在每種伺服器作業系統上都相同,所以上傳的檔案可以在 Windows、macOS 與 Linux 之間移動。下載與刪除 route 以及 /api/custom-nodes/toggle 會拒絕含有控制字元的名稱;在 Windows 伺服器上,也會拒絕含有上述字元的名稱。在 Linux 與 macOS 上,這類名稱照常查找,所以已經以這類名稱存放的檔案仍然可以取用。這些 route 不限制名稱長度:某一段超過伺服器檔案系統上限的名稱會回傳 404。/api/custom-nodes/upload 與 /api/custom-nodes/toggle 另外拒絕以 __ 開頭的名稱,例如 __init__.py。每個拒絕的 detail 都會說明該改什麼。/api/presets/create 對預設組合名稱套用同一條規則,長度以實際寫入的檔名(名稱加上 .json)計算,並回傳帶代碼的 detail。

  • 拒絕順序。 Host guard 先執行,可能回傳 421;接著是驗證,可能回傳 403 或 401;最後才檢查 body 大小。被拒絕的 request body 不會被讀取。因此,未驗證的 request 不會收到 413 response。

  • WebSocket frame。 Transport 會執行 WS_MAX_MESSAGE_BYTES(CODEFYUI_WS_MAX_MESSAGE_BYTES,預設等於 request body 上限)。frame 超過上限時,連線會以 code 1009 關閉,而不是回傳 413。手動啟動 uvicorn 時請參閱把 graph 當成函式呼叫,第 8 節。

  • 錯誤格式。 API 依 route 類別使用四種格式:

    1. {"detail": "<text>"}——預設格式,包含 413 response,以及回送位址閘門在外掛與套件包 route 上回傳的 403。套件包 route 會在 detail 旁加入 job_id、reason、blocked_by、command、needed 與 free 等欄位。
    2. {"detail": {"code", "message", "details"}}——應用程式管理 route 與 /api/keys,例如 404 app_not_found、422 incomplete_cursor 與 404 key_not_found。
    3. {"detail": {"code", ...}},不含 message——外掛中心 route。其他欄位可能包含 job_id、known、missing_capabilities、allowed_modules、plugin_id、inspection_id 與 id。
    4. {"detail": {"code", "message", "hint", "stderr"}}——所有 /api/git 失敗;busy 另外帶有 op。參閱版本控制。

    有兩種格式不分 route 類別:/api/graph/save 的衝突保護回傳 409 {"detail": {"error": "graph_exists", "file", "name"}};request 不符合 route 宣告的 body 或 query 參數時(缺少欄位、body 禁止未知 key 時出現未知 key、數值超出範圍),回傳 FastAPI 的 422 {"detail": [{"type", "loc", "msg", ...}]}。

    POST /api/graph/run/{name} 與 POST /api/apps/{slug}/invoke 是以上所有格式的例外:每一個 response——包括 413 與 401——都是九鍵 run envelope,參閱這份 envelope。

WebSocket 協定​

端點方法驗證說明
/ws/executionWebSockettokenrun 的附掛/訂閱檢視:execute 啟動一個 run,attach 從指定 cursor 重播事件 log 再接著即時追蹤,detach 取消訂閱,cancel 停止 run。關閉 socket 永遠不會取消。
/ws/workerWebSocketworker token,或來自 loopback 的 tokenWorker agent(cdui agent start)連線的位置。憑證以 X-CodefyUI-Token(或 ?token=)傳送:任何來源都接受 worker token,session token 只接受來自 loopback 的連線。Host 不在允許清單,或帶有 Origin header 的請求,會在 socket 被接受前以 4003 關閉(HTTP client 看到的是 403);憑證遺漏或無效時回 HTTP 401(在 uvicorn 下;不支援握手回應的伺服器則以 4401 關閉,同樣顯示為 403)。只有 401 會讓 agent 判定自己的 token 被拒。第一個 frame 必須在 10 秒內送出 hello;協定版本或 CodefyUI 版本不符(兩端必須執行同一個版本)、worker 名稱不合法或為保留字、worker token 的 hello 使用其他 worker 的名稱,或新連線要取代以不同方式驗證的同名現有連線,都會收到 reject 並關閉。只有從 loopback 連入且回報這台機器 id 的 worker 才算在同一台機器上。frame 定義在 backend/app/core/worker_protocol.py;請參閱執行架構。關閉時該 worker 的 run 會繼續在它上面執行並變成 disconnected;worker 在 CODEFYUI_WORKER_RESUME_GRACE_S(300 秒)內重新連線就會接續,超過後以 interrupted 結束;寬限為 0 或 worker 被移除時則立即結束(遠端 Worker:連線中斷時)。

交握。 ws://<host>:<port>/ws/execution?token=<session token>——由於瀏覽器無法在 WebSocket 交握時設定 header,因此使用 ?token= query parameter;非瀏覽器 client 也可使用 X-CodefyUI-Token header。在 socket 被接受前的 close code:Host——或瀏覽器的 Origin——不在白名單時為 4003;token 遺漏或無效時為 4401;之後 frame 超過大小上限時為 1009。

Client action——帶有 action 欄位的 JSON text frame:

動作欄位效果
executenodes、edges、presets、subgraphs、settings、device、seed、deterministic、record_outputs、changed_nodes、name,以及畫布旗標(verbose_mode、graph_id、weights_persistent、backward_mode、auto_backward、error_mode、max_retries)在 interactive lane 送出,並附掛到新的 run。此 socket 已在追蹤的 run 會被 detach,而不是 cancel。settings 是 graph 自己的設定物件,會與 run 的 graph 一起儲存;run 本身使用 device,省略時為 cpu。run 會以 name(畫布送出的是分頁名稱)列出,最多 64 個字元。
attachrun_id、cursor(整數、至少為 0,且不得超過 run 的最新 cursor)從 cursor 重播事件 log,接著即時追蹤;取代先前的 attachment。
detach—停止追蹤。絕不會取消。
cancelrun_id(選用;預設為附掛的 run)協作式停止。v2 之前的別名 stop 已在 3.0 移除。
clear_cache—清除這個 socket 的 execution cache。

Server frame。 已儲存的 run 事件使用 {type, run_id, cursor, ...payload}(execution_start、node_status、execution_stopped 等)。區塊或預設組合卡片的 node_status 會彙總其內部所有節點;這些內部節點會以 inner_node_status {node_id, container_id, status} 回報,發生錯誤時另含 error 與 error_type;節點有產出時另含 outputs(其媒體項目與連接埠摘要;文字仍由卡片的 frame 傳送)。其中 node_id 是 run 為節點指定的識別碼(<instance>/<node>,巢狀區塊會再往下延伸),container_id 則是最外層的卡片。卡片最終的 node_status 會附上其對外輸出的連接埠摘要。卡片內部節點的進度訊息仍是該卡片的 node_status,並以 inner_node_id 指出是哪個節點。run 略過(bypass)的節點會在任何節點執行前回報一次,狀態為 bypassed;因 Switch 的 selector 參數沒有選到其分支而未執行的節點也會同樣回報,狀態為 unselected。client 重新附掛時使用 cursor。僅由 transport 產生的 frame 包含 attached {run_id, cursor, status}、detached {run_id}、cancel_ack {run_id, status, cancelled}、沒有可取消 run 時的 execution_stopped {reason: "not_running"}、cache_cleared、action 無效或未知時的 error {error},以及 run service 拒絕送出時的 execution_error {error}。cancel_ack 只確認已收到 request;run 停止後會再發出自己的 execution_stopped 事件。因 interactive 上限或每個 session 一個 run 的規則而拒絕時,也會包含 rejected: true 與目前附掛的 run_id。此時不會啟動新 run,原有 attachment 會維持作用中。