bugfix: restore checkpoint

This commit is contained in:
ai-business-hql
2025-08-19 18:04:55 +08:00
15 changed files with 33 additions and 863 deletions
-14
View File
@@ -1,14 +0,0 @@
function getImportPath(filename) {
return `./${filename}`;
}
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-DRLZy61n.js","copilot_web/vendor-markdown-BAJQc3l1.js","copilot_web/vendor-react-Dixhfmvb.js","copilot_web/message-components-DtpRtuWw.js","copilot_web/input.js","copilot_web/assets/input-Dx1yyZQD.css","copilot_web/fonts.css"].map(path => {
const apiBase = window.comfyAPI?.api?.api?.api_base;
if (apiBase) {
// 有 API base 时,使用完整路径
return `${apiBase.substring(1)}/${path}`;
} else {
// 没有 API base 时,使用相对路径
return `./${path}`;
}
}))))=>i.map(i=>d[i]);
import{_ as a}from"./input.js";import{j as o}from"./vendor-markdown-BAJQc3l1.js";import{r as t,R as i}from"./vendor-react-Dixhfmvb.js";import{C as n}from"./message-components-DtpRtuWw.js";const s={EXPLAIN_NODE:"copilot:explain-node",TOOLBOX_USAGE:"copilot:toolbox-usage",TOOLBOX_PARAMETERS:"copilot:toolbox-parameters",TOOLBOX_DOWNSTREAMNODES:"copilot:toolbox-downstreamnodes"},d=i.lazy(()=>a(()=>import(getImportPath("workflowChat-DRLZy61n.js")).then(e=>e.w),__vite__mapDeps([0,1,2,3,4,5,6])).then(e=>({default:e.default})));function c(){const[e,r]=t.useState(!1);return t.useEffect(()=>{const l=()=>{r(!0)};return window.addEventListener(s.EXPLAIN_NODE,l),()=>window.removeEventListener(s.EXPLAIN_NODE,l)},[]),o.jsx(n,{children:o.jsx("div",{className:"h-full w-full flex flex-col",children:o.jsx(t.Suspense,{fallback:o.jsx("div",{className:"h-full w-full flex items-center justify-center",children:"Loading..."}),children:o.jsx(d,{visible:!0,triggerUsage:e,onUsageTriggered:()=>r(!1)})})})})}const O=Object.freeze(Object.defineProperty({__proto__:null,default:c},Symbol.toStringTag,{value:"Module"}));export{O as A,s as C};
-5
View File
@@ -1,5 +0,0 @@
function getImportPath(filename) {
return `./${filename}`;
}
import{j as s}from"./vendor-markdown-BAJQc3l1.js";import{r as i}from"./vendor-react-Dixhfmvb.js";import{u as A,B as D,R as E,h as x,a as m,W as b}from"./message-components-DtpRtuWw.js";function M({content:f,name:k="Assistant",avatar:O,onAddMessage:y,onUpdateMessage:c,messageId:w}){const{dispatch:u,abortControllerRef:l}=A(),[d,_]=i.useState(!1),[T,G]=i.useState(""),[J,S]=i.useState(!1),[j,N]=i.useState(null),r=i.useMemo(()=>{try{return JSON.parse(f)}catch(e){return console.error("Failed to parse message content:",e),null}},[f]),h=i.useMemo(()=>{if(!r||!r.ext)return null;const e=r.ext.find(t=>t.type==="debug_start_checkpoint"||t.type==="debug_checkpoint"&&t.data?.checkpoint_type==="debug_start");return e&&e.data&&e.data.checkpoint_id?e.data.checkpoint_id:null},[r])||j,C=async()=>{if(d)return;const e=x(),t={id:e,role:"ai",content:JSON.stringify({text:`🔍 Starting workflow analysis...
`,ext:[]}),format:"markdown",name:"Assistant",finished:!1,debugGuide:!0};y?.(t);try{await v(),u({type:"SET_LOADING",payload:!0}),await I(e)}finally{_(!1)}},v=async()=>{try{const e=await m.graphToPrompt(),t=localStorage.getItem("sessionId")||"";if(t&&e){const n=await b.saveWorkflowCheckpoint(t,e.output,e.workflow,"debug_start");if(N(n.version_id),console.log(`Saved debug start checkpoint: ${n.version_id}`),c&&r){const o=[...r.ext||[]].filter(g=>g.type!=="debug_start_checkpoint"&&!(g.type==="debug_checkpoint"&&g.data?.checkpoint_type==="debug_start"));o.push({type:"debug_start_checkpoint",data:{checkpoint_id:n.version_id,checkpoint_type:"debug_start"}});const p={id:w||x(),role:"ai",content:JSON.stringify({text:r.text,ext:o}),format:"debug_guide",name:"Assistant"};c(p)}}}catch(e){console.error("Failed to save checkpoint before debug:",e)}},I=async e=>{try{const t=await m.graphToPrompt();let n="",a=null;l&&(l.current=new AbortController);for await(const o of b.streamDebugAgent(t,l?.current?.signal||void 0))if(o.text){n=o.text,o.ext&&(a=o.ext);const p={id:e,role:"ai",content:JSON.stringify({text:n,ext:a||[]}),format:"markdown",name:"Assistant",finished:!1,debugGuide:!0};c?.(p)}c?.({id:e,role:"ai",content:JSON.stringify({text:n,ext:a||[]}),format:"markdown",name:"Assistant",finished:!0,debugGuide:!0}),u({type:"SET_LOADING",payload:!1}),l.current=null}catch(t){console.error("Error calling debug agent:",t),S(!1);const a={id:e,role:"ai",content:JSON.stringify({text:`I encountered an error while analyzing your workflow: ${t.message||"Unknown error"}`,ext:[]}),format:"markdown",name:"Assistant",finished:!0};c?.(a),u({type:"SET_LOADING",payload:!1}),l.current=null}};return r?s.jsx(D,{name:k,children:s.jsxs("div",{className:"bg-gray-100 pt-4 px-4 pb-3 rounded-lg",children:[s.jsx("div",{className:"flex justify-between items-start",children:s.jsx("p",{className:"text-gray-700 text-sm flex-1",children:r.text})}),s.jsx("div",{className:"flex justify-end mt-4",children:s.jsx("button",{onClick:C,disabled:d,className:`debug-btn bg-debug-btn text-sm text-[#fff] rounded-lg px-4 py-2 ${d?"cursor-not-allowed":"cursor-pointer"}`,children:d?"Analyzing...":"Debug Errors"})}),s.jsx("div",{className:"flex justify-end mt-2",children:!!h&&s.jsx("div",{className:"ml-2 flex-shrink-0",children:s.jsx(E,{checkpointId:h,onRestore:()=>{console.log("Workflow restored from checkpoint")}})})})]})}):null}export{M as DebugGuide};
-4
View File
@@ -1,4 +0,0 @@
function getImportPath(filename) {
return `./${filename}`;
}
import{j as e}from"./vendor-markdown-BAJQc3l1.js";import{b as f,c as h,B as m,p as u,R as w}from"./message-components-DtpRtuWw.js";import{r as k}from"./vendor-react-Dixhfmvb.js";import{B as j}from"./workflowChat-DRLZy61n.js";import"./input.js";/* empty css */import"./App-DFg5976E.js";const v=i=>{const{title:a="",isWorkflowUpdate:d=!1,className:n="",children:c}=i,[s,r]=k.useState(!1);return e.jsx(j,{className:"rounded-lg ",borderClassName:"rounded-lg",children:e.jsxs("div",{className:`flex flex-col ${n} ${s?"":"max-h-[200px]"}`,children:[e.jsxs("div",{className:"flex justify-between items-center pb-2 border-b border-gray-100",children:[e.jsx("div",{children:typeof a=="string"?e.jsx("h3",{className:"text-sm text-[#fff] font-medium",children:a}):a}),e.jsx("button",{onClick:()=>{r(!s)},children:s?e.jsx(f,{className:"text-gray-700"}):e.jsx(h,{className:"text-gray-700"})})]}),e.jsx("div",{className:"overflow-hidden flex-1",children:c})]})})};function B({content:i,name:a="Assistant",avatar:d,format:n="markdown"}){const c=()=>{let s=null,r=!1,o;try{if(o=JSON.parse(i),o.ext){let t=o.ext.find(l=>l.type==="workflow_rewrite_checkpoint"||l.type==="debug_checkpoint"&&l.data?.checkpoint_type==="workflow_rewrite_start");t&&t.data&&t.data.checkpoint_id?(s=t.data.checkpoint_id,r=!0):(t=o.ext.find(l=>l.type==="workflow_rewrite_complete"),t&&t.data&&t.data.version_id?(s=t.data.version_id,r=!0):(t=o.ext.find(l=>l.type==="debug_checkpoint"),t&&t.data&&t.data.checkpoint_id&&(s=t.data.checkpoint_id,r=!1))),o.ext.find(l=>l.type==="workflow_update")&&(r=!0)}}catch(t){return console.error("Failed to parse DebugResult content:",t),null}const x=r?e.jsxs("div",{className:"flex items-center text-green-500",children:[e.jsx("svg",{className:"w-5 h-5 mr-2",fill:"currentColor",viewBox:"0 0 20 20",children:e.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",clipRule:"evenodd"})}),e.jsx("h4",{className:"font-bold text-xl",children:"Workflow Updated Successfully"})]}):e.jsxs("div",{className:"flex items-center text-gray-900",children:[e.jsx("svg",{className:"w-5 h-5 mr-2",viewBox:"0 0 1024 1024",version:"1.1",xmlns:"http://www.w3.org/2000/svg","p-id":"28108",fill:"currentColor",children:e.jsx("path",{d:"M401.048025 844.855924c0 20.341281 16.643052 36.984333 36.984333 36.984333l147.936307 0c20.341281 0 36.984333-16.643052 36.984333-36.984333L622.952998 807.872614 401.048025 807.872614 401.048025 844.855924zM512 142.159744c-142.943596 0-258.888282 115.944686-258.888282 258.888282 0 88.021729 44.011376 165.503405 110.951975 212.288964l0 83.58365c0 20.341281 16.643052 36.984333 36.984333 36.984333l221.903949 0c20.341281 0 36.984333-16.643052 36.984333-36.984333l0-83.58365c66.941622-46.784536 110.951975-124.266212 110.951975-212.288964C770.888282 258.104429 654.943596 142.159744 512 142.159744zM617.588827 552.682561l-31.621185 22.005176 0 85.248569L438.031335 659.936307l0-85.063351L406.41015 552.866756c-49.743938-34.764781-79.33079-91.350544-79.33079-151.634536 0-101.890598 83.029018-184.92064 184.92064-184.92064s184.92064 83.029018 184.92064 184.92064C696.919617 461.332017 667.332764 517.91778 617.588827 552.682561z","p-id":"28277"})}),e.jsx("h4",{className:"font-bold text-xl",children:"Workflow Updated Finished"})]}),p=r?e.jsx("div",{className:"mt-3 text-xs text-gray-700",children:"💡 If you're not satisfied with the changes, click the restore button to revert to the previous version."}):null;return e.jsxs("div",{className:"sticky top-0 left-0 w-full bg-gray-100 p-4 rounded-lg overflow-hidden",children:[e.jsx(v,{title:x,isWorkflowUpdate:r,className:"p-4",children:e.jsxs("div",{className:"prose prose-sm max-w-none",children:[n==="markdown"?e.jsx(u,{response:o||{}}):e.jsx("pre",{className:"whitespace-pre-wrap text-gray-700 text-sm leading-relaxed h-full",children:o?.text||""}),p]})}),e.jsx("div",{className:"flex justify-end mt-2",children:!!s&&e.jsx("div",{className:"ml-2 flex-shrink-0",children:e.jsx(w,{checkpointId:s,onRestore:()=>{console.log(`Workflow restored from ${r?"workflow update":"debug"} checkpoint`)},title:r?`Restore to this version (Version ${s})`:`Restore checkpoint ${s}`})})})]})};return e.jsx(m,{name:a,children:c()})}export{B as DebugResult};
File diff suppressed because one or more lines are too long
-14
View File
@@ -1,14 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="cc-icon-logo" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="cc-icon-logo" horiz-adv-x="1673"
d="M953.240 271.522c7.894-6.874 12.965-16.634 19.585-24.709 11.100-13.542 23.393-25.939 36.892-37.094 56.683-46.839 134.714-63.303 205.904-46.280 36.563 8.744 71.347 27.153 98.834 52.889 6.503 6.089 26.996 19.767 21.187 30.485-9.427 17.396-31.912 31.962-45.898 45.893-4.414 4.397-10.841 13.638-17.632 14.025-8.042 0.458-18.046-13.623-23.549-18.443-14.098-12.353-30.474-20.840-48.239-26.551-86.646-27.857-171.451 32.122-189.787 118.031-19.441 91.078 54.091 198.993 153.313 189.040 24.603-2.468 46.791-9.195 68.243-21.640 8.668-5.028 22.977-21.652 32.930-21.475 6.976 0.124 13.251 9.647 17.670 14.093l36.477 36.459c6.590 6.636 14.250 12.156 6.741 21.193-15.330 18.450-37.542 32.228-58.519 43.305-118.109 62.355-262.374 13.472-323.782-103.311-35.469-67.452-25.685-150.041-68.487-214.140-30.167-45.177-80.951-74.275-136.022-70.413-19.842 1.391-39.756 6.076-57.653 14.847-104.915 51.407-113.944 202.931-23.532 272.699 38.111 29.409 90.649 36.425 135.309 18.880 11.810-4.640 22.625-10.821 32.945-18.183 4.417-3.151 10.625-9.812 16.473-9.484 6.426 0.363 12.309 8.692 16.473 12.855 11.977 11.973 23.349 24.496 35.298 36.475 4.345 4.355 14.559 11.600 12.080 18.825-3.723 10.854-20.787 20.481-29.729 26.835-33.085 23.507-73.643 37.831-114.130 40.263-129.389 7.774-246.857-87.826-260.937-218.877-11.557-107.563 36.224-215.138 135.041-266.113 84.024-43.342 187.873-30.941 261.204 27.158 19.671 15.585 46.151 38.408 55.300 62.466z" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

-1
View File
File diff suppressed because one or more lines are too long
-38
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-4
View File
@@ -1,4 +0,0 @@
function getImportPath(filename) {
return `./${filename}`;
}
File diff suppressed because one or more lines are too long
+33 -26
View File
@@ -4,7 +4,7 @@
import { BaseMessage } from './BaseMessage';
import { InformationCircleIcon } from '@heroicons/react/24/outline';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import RestoreCheckpoint from '../../ui/RestoreCheckpoint';
interface ExtItem {
@@ -30,34 +30,41 @@ export function UserMessage({ content, trace_id, ext }: UserMessageProps) {
}
};
const [checkpointId, setChekpointId] = useState<number | null>(null);
const [images, setImages] = useState<any[]>([])
// Check if there's a checkpoint in ext data for workflow_update or param_update
let checkpointId: number | null = null;
let images: any[] = [];
// let checkpointId: number | null = null;
// let images: any[] = [];
// 添加调试日志
console.log(`[UserMessage] Received ext data:`, ext);
if (ext) {
// Look for workflow_rewrite_checkpoint or debug_checkpoint related to workflow updates
const checkpointExt = ext.find((item) =>
item.type === 'workflow_rewrite_checkpoint' ||
(item.type === 'debug_checkpoint' && item.data?.checkpoint_type === 'workflow_rewrite_start')
);
console.log(`[UserMessage] Found checkpoint ext:`, checkpointExt);
if (checkpointExt && checkpointExt.data && checkpointExt.data.checkpoint_id) {
checkpointId = checkpointExt.data.checkpoint_id;
console.log(`[UserMessage] Extracted checkpoint ID:`, checkpointId);
useEffect(() => {
// 添加调试日志
console.log(`[UserMessage] Received ext data:`, ext);
if (ext) {
// Look for workflow_rewrite_checkpoint or debug_checkpoint related to workflow updates
const checkpointExt = ext.find((item) =>
item.type === 'workflow_rewrite_checkpoint' ||
(item.type === 'debug_checkpoint' && item.data?.checkpoint_type === 'workflow_rewrite_start')
);
console.log(`[UserMessage] Found checkpoint ext:`, checkpointExt);
if (checkpointExt && checkpointExt.data && checkpointExt.data.checkpoint_id) {
// checkpointId = checkpointExt.data.checkpoint_id;
setChekpointId(checkpointExt.data.checkpoint_id)
console.log(`[UserMessage] Extracted checkpoint ID:`, checkpointExt.data.checkpoint_id);
}
const hasImages = ext.some((item) => item.type === 'img');
if (hasImages) {
let _images: any[] = []
ext.filter((item) => item.type === 'img').forEach((item) => _images = _images.concat(item.data));
setImages(_images)
}
// If we have workflow/param updates but no checkpoint, we could show a message about it
// But for now, we only show restore button if we have a checkpoint
}
const hasImages = ext.some((item) => item.type === 'img');
if (hasImages) {
ext.filter((item) => item.type === 'img').forEach((item) => images = images.concat(item.data));
}
// If we have workflow/param updates but no checkpoint, we could show a message about it
// But for now, we only show restore button if we have a checkpoint
}
}, [ext])
return (
<BaseMessage name="User" isUser={true}>