feat: restore按钮样式

This commit is contained in:
li
2025-07-29 11:07:12 +08:00
parent c73bf14ece
commit fbc3011b90
10 changed files with 40 additions and 63 deletions
@@ -1,7 +1,7 @@
function getImportPath(filename) {
return `./${filename}`;
}
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-DkAITO_h.js","copilot_web/vendor-markdown-CBmlBP6m.js","copilot_web/vendor-react-Dixhfmvb.js","copilot_web/message-components-BfemXQD4.js","copilot_web/input.js","copilot_web/assets/input-B8oe5d8t.css","copilot_web/fonts.css"].map(path => {
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-C5do68H6.js","copilot_web/vendor-markdown-CBmlBP6m.js","copilot_web/vendor-react-Dixhfmvb.js","copilot_web/message-components-BfemXQD4.js","copilot_web/input.js","copilot_web/assets/input-kXfBSbki.css","copilot_web/fonts.css"].map(path => {
const apiBase = window.comfyAPI?.api?.api?.api_base;
if (apiBase) {
// 有 API base 时,使用完整路径
@@ -11,4 +11,4 @@ function getImportPath(filename) {
return `./${path}`;
}
}))))=>i.map(i=>d[i]);
import{_ as a}from"./input.js";import{j as e}from"./vendor-markdown-CBmlBP6m.js";import{r as t,R as i}from"./vendor-react-Dixhfmvb.js";import{C as n}from"./message-components-BfemXQD4.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-DkAITO_h.js")),__vite__mapDeps([0,1,2,3,4,5,6])).then(o=>({default:o.default})));function c(){const[o,r]=t.useState(!1);return t.useEffect(()=>{const l=()=>{r(!0)};return window.addEventListener(s.EXPLAIN_NODE,l),()=>window.removeEventListener(s.EXPLAIN_NODE,l)},[]),e.jsx(n,{children:e.jsx("div",{className:"h-full w-full flex flex-col",children:e.jsx(t.Suspense,{fallback:e.jsx("div",{className:"h-full w-full flex items-center justify-center",children:"Loading..."}),children:e.jsx(d,{visible:!0,triggerUsage:o,onUsageTriggered:()=>r(!1)})})})})}const O=Object.freeze(Object.defineProperty({__proto__:null,default:c},Symbol.toStringTag,{value:"Module"}));export{O as A,s as C};
import{_ as a}from"./input.js";import{j as o}from"./vendor-markdown-CBmlBP6m.js";import{r as t,R as i}from"./vendor-react-Dixhfmvb.js";import{C as n}from"./message-components-BfemXQD4.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-C5do68H6.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 o}from"./vendor-markdown-CBmlBP6m.js";import{r as a}from"./vendor-react-Dixhfmvb.js";import{B as D,g as y,W as w,a as h}from"./message-components-BfemXQD4.js";const I=({checkpointId:l,onRestore:x})=>{const[u,p]=a.useState(!1),n=async()=>{if(!u){p(!0);try{const i=await w.restoreWorkflowCheckpoint(l),g=i.workflow_data_ui||i.workflow_data;g&&(i.workflow_data_ui?h.loadGraphData(g):h.loadApiJson(g),console.log(`Restored workflow checkpoint ${l}`),x())}catch(i){console.error("Failed to restore checkpoint:",i),alert("Failed to restore workflow checkpoint. Please try again.")}finally{p(!1)}}};return o.jsx("button",{onClick:n,disabled:u,className:`p-1 rounded transition-colors ${u?"text-gray-400 cursor-not-allowed":"text-gray-500 hover:text-blue-600 hover:bg-blue-50"}`,title:`Restore checkpoint ${l}`,children:o.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"currentColor",className:u?"animate-spin":"",children:[o.jsx("path",{d:"M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"}),o.jsx("path",{d:"M8 4.466V2.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 6.658A.25.25 0 0 1 8 6.466z"})]})})};function M({content:l,name:x="Assistant",avatar:u,onAddMessage:p,onUpdateMessage:n,onFinishLoad:i,messageId:g}){const[f,_]=a.useState(!1),[E,O]=a.useState(""),[R,S]=a.useState(!1),[v,j]=a.useState(null);a.useEffect(()=>{i?.()},[]);const r=a.useMemo(()=>{try{return JSON.parse(l)}catch(e){return console.error("Failed to parse message content:",e),null}},[l]),b=a.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])||v,C=async()=>{if(f)return;const e=y(),t={id:e,role:"ai",content:JSON.stringify({text:`🔍 Starting workflow analysis...
`,ext:[]}),format:"markdown",name:"Assistant",finished:!1,debugGuide:!0};p?.(t);try{await N(),await A(e)}finally{_(!1)}},N=async()=>{try{const e=await h.graphToPrompt(),t=localStorage.getItem("sessionId")||"";if(t&&e){const s=await w.saveWorkflowCheckpoint(t,e.output,e.workflow,"debug_start");if(j(s.version_id),console.log(`Saved debug start checkpoint: ${s.version_id}`),n&&r){const c=[...r.ext||[]].filter(m=>m.type!=="debug_start_checkpoint"&&!(m.type==="debug_checkpoint"&&m.data?.checkpoint_type==="debug_start"));c.push({type:"debug_start_checkpoint",data:{checkpoint_id:s.version_id,checkpoint_type:"debug_start"}});const k={id:g||y(),role:"ai",content:JSON.stringify({text:r.text,ext:c}),format:"debug_guide",name:"Assistant"};n(k)}}}catch(e){console.error("Failed to save checkpoint before debug:",e)}},A=async e=>{try{const t=await h.graphToPrompt();let s="",d=null;for await(const c of w.streamDebugAgent(t))if(c.text){s=c.text,c.ext&&(d=c.ext);const k={id:e,role:"ai",content:JSON.stringify({text:s,ext:d||[]}),format:"markdown",name:"Assistant",finished:!1,debugGuide:!0};n?.(k)}n?.({id:e,role:"ai",content:JSON.stringify({text:s,ext:d||[]}),format:"markdown",name:"Assistant",finished:!0,debugGuide:!0})}catch(t){console.error("Error calling debug agent:",t),S(!1);const d={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};n?.(d)}};return r?o.jsx(D,{name:x,children:o.jsxs("div",{className:"bg-gray-100 p-4 rounded-lg",children:[o.jsxs("div",{className:"flex justify-between items-start",children:[o.jsx("p",{className:"text-gray-700 text-sm flex-1",children:r.text}),b&&o.jsx("div",{className:"ml-2 flex-shrink-0",children:o.jsx(I,{checkpointId:b,onRestore:()=>{console.log("Workflow restored from checkpoint")}})})]}),o.jsx("div",{className:"flex mt-4",children:o.jsx("button",{onClick:C,disabled:f,className:`px-4 py-2 text-white text-sm rounded-md transition-colors ${f?"bg-gray-400 cursor-not-allowed":"bg-blue-500 hover:bg-blue-600"}`,children:f?"Analyzing...":"Debug Errors"})})]})}):null}export{M as DebugGuide};
+10
View File
@@ -0,0 +1,10 @@
function getImportPath(filename) {
return `./${filename}`;
}
import{j as o}from"./vendor-markdown-CBmlBP6m.js";import{r as a}from"./vendor-react-Dixhfmvb.js";import{B as D,g as b,a as h,W as w}from"./message-components-BfemXQD4.js";import{c as A}from"./workflowChat-C5do68H6.js";import"./input.js";/* empty css */import"./App-aIt2YzCk.js";/**
* @license lucide-react v0.475.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const E=[["path",{d:"M9 14 4 9l5-5",key:"102s5s"}],["path",{d:"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11",key:"f3b9sd"}]],R=A("Undo2",E),O=({checkpointId:l,onRestore:x})=>{const[p,f]=a.useState(!1),n=async()=>{if(!p){f(!0);try{const i=await w.restoreWorkflowCheckpoint(l),u=i.workflow_data_ui||i.workflow_data;u&&(i.workflow_data_ui?h.loadGraphData(u):h.loadApiJson(u),console.log(`Restored workflow checkpoint ${l}`),x())}catch(i){console.error("Failed to restore checkpoint:",i),alert("Failed to restore workflow checkpoint. Please try again.")}finally{f(!1)}}};return o.jsxs("button",{onClick:n,disabled:p,className:`flex flex-row items-center gap-1 p-1 rounded transition-colors ${p?"text-gray-400 cursor-not-allowed":"text-gray-500 hover:!bg-gray-100 hover:!text-gray-600"}`,title:`Restore checkpoint ${l}`,children:[o.jsx(R,{size:12}),o.jsx("span",{className:"text-xs",children:"Restore checkpoint"})]})};function H({content:l,name:x="Assistant",avatar:p,onAddMessage:f,onUpdateMessage:n,onFinishLoad:i,messageId:u}){const[g,_]=a.useState(!1),[J,T]=a.useState(""),[$,S]=a.useState(!1),[j,v]=a.useState(null);a.useEffect(()=>{i?.()},[]);const r=a.useMemo(()=>{try{return JSON.parse(l)}catch(e){return console.error("Failed to parse message content:",e),null}},[l]),y=a.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,N=async()=>{if(g)return;const e=b(),t={id:e,role:"ai",content:JSON.stringify({text:`🔍 Starting workflow analysis...
`,ext:[]}),format:"markdown",name:"Assistant",finished:!1,debugGuide:!0};f?.(t);try{await C(),await I(e)}finally{_(!1)}},C=async()=>{try{const e=await h.graphToPrompt(),t=localStorage.getItem("sessionId")||"";if(t&&e){const s=await w.saveWorkflowCheckpoint(t,e.output,e.workflow,"debug_start");if(v(s.version_id),console.log(`Saved debug start checkpoint: ${s.version_id}`),n&&r){const c=[...r.ext||[]].filter(k=>k.type!=="debug_start_checkpoint"&&!(k.type==="debug_checkpoint"&&k.data?.checkpoint_type==="debug_start"));c.push({type:"debug_start_checkpoint",data:{checkpoint_id:s.version_id,checkpoint_type:"debug_start"}});const m={id:u||b(),role:"ai",content:JSON.stringify({text:r.text,ext:c}),format:"debug_guide",name:"Assistant"};n(m)}}}catch(e){console.error("Failed to save checkpoint before debug:",e)}},I=async e=>{try{const t=await h.graphToPrompt();let s="",d=null;for await(const c of w.streamDebugAgent(t))if(c.text){s=c.text,c.ext&&(d=c.ext);const m={id:e,role:"ai",content:JSON.stringify({text:s,ext:d||[]}),format:"markdown",name:"Assistant",finished:!1,debugGuide:!0};n?.(m)}n?.({id:e,role:"ai",content:JSON.stringify({text:s,ext:d||[]}),format:"markdown",name:"Assistant",finished:!0,debugGuide:!0})}catch(t){console.error("Error calling debug agent:",t),S(!1);const d={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};n?.(d)}};return r?o.jsx(D,{name:x,children:o.jsxs("div",{className:"bg-gray-100 p-4 rounded-lg",children:[o.jsx("div",{className:"flex justify-between items-start",children:o.jsx("p",{className:"text-gray-700 text-sm flex-1",children:r.text})}),o.jsx("div",{className:"flex mt-4",children:o.jsx("button",{onClick:N,disabled:g,className:`px-4 py-2 text-white text-sm rounded-md transition-colors ${g?"bg-gray-400 cursor-not-allowed":"bg-blue-500 hover:bg-blue-600"}`,children:g?"Analyzing...":"Debug Errors"})}),o.jsx("div",{className:"flex justify-end mt-2",children:y&&o.jsx("div",{className:"ml-2 flex-shrink-0",children:o.jsx(O,{checkpointId:y,onRestore:()=>{console.log("Workflow restored from checkpoint")}})})})]})}):null}export{H as DebugGuide};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+19 -24
View File
@@ -4,6 +4,7 @@ import { generateUUID } from '../../../utils/uuid';
import { queuePrompt } from '../../../utils/queuePrompt';
import { app } from '../../../utils/comfyapp';
import { WorkflowChatAPI } from '../../../apis/workflowChatApi';
import { Undo2 } from 'lucide-react';
// Restore checkpoint icon component
const RestoreCheckpointIcon = ({ checkpointId, onRestore }: { checkpointId: number; onRestore: () => void }) => {
@@ -44,23 +45,15 @@ const RestoreCheckpointIcon = ({ checkpointId, onRestore }: { checkpointId: numb
<button
onClick={handleRestore}
disabled={isRestoring}
className={`p-1 rounded transition-colors ${
className={`flex flex-row items-center gap-1 p-1 rounded transition-colors ${
isRestoring
? 'text-gray-400 cursor-not-allowed'
: 'text-gray-500 hover:text-blue-600 hover:bg-blue-50'
: 'text-gray-500 hover:!bg-gray-100 hover:!text-gray-600'
}`}
title={`Restore checkpoint ${checkpointId}`}
>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="currentColor"
className={isRestoring ? 'animate-spin' : ''}
>
<path d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"/>
<path d="M8 4.466V2.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 6.658A.25.25 0 0 1 8 6.466z"/>
</svg>
<Undo2 size={12} />
<span className="text-xs">Restore checkpoint</span>
</button>
);
};
@@ -268,18 +261,6 @@ export function DebugGuide({ content, name = 'Assistant', avatar, onAddMessage,
<p className="text-gray-700 text-sm flex-1">
{response.text}
</p>
{/* Restore checkpoint icon */}
{checkpointId && (
<div className="ml-2 flex-shrink-0">
<RestoreCheckpointIcon
checkpointId={checkpointId}
onRestore={() => {
console.log('Workflow restored from checkpoint');
}}
/>
</div>
)}
</div>
<div className="flex mt-4">
@@ -295,6 +276,20 @@ export function DebugGuide({ content, name = 'Assistant', avatar, onAddMessage,
{isDebugging ? 'Analyzing...' : 'Debug Errors'}
</button>
</div>
<div className="flex justify-end mt-2">
{/* Restore checkpoint icon */}
{checkpointId && (
<div className="ml-2 flex-shrink-0">
<RestoreCheckpointIcon
checkpointId={checkpointId}
onRestore={() => {
console.log('Workflow restored from checkpoint');
}}
/>
</div>
)}
</div>
</div>
</BaseMessage>
);
+2 -2
View File
@@ -74,7 +74,7 @@ const Showcase: React.FC = () => {
const getShowcaes = () => {
const language = app.extensionManager.setting.get('Comfy.Locale')
let list = showcases_en
let title = 'welcome to ComfyUI Copilot!'
let title = ''
switch (language) {
case 'zh':
title = '欢迎使用ComfyUI Copilot!'
@@ -82,7 +82,7 @@ const Showcase: React.FC = () => {
break;
case 'en':
default:
title = 'welcome to ComfyUI Copilot!'
title = 'Welcome to ComfyUI Copilot!'
list = showcases_en
break;
}
-23
View File
@@ -603,29 +603,6 @@
.animate-bounce {
animation: bounce 1s infinite;
}
@keyframes breathe {
0%, 100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.7;
transform: scale(1.05);
}
}
@keyframes colorBreathe {
0%, 100% {
color: #6b7280;
}
50% {
color: #22c55e;
}
}
.animate-breathe-green {
animation: breathe 3s ease-in-out infinite, colorBreathe 3s ease-in-out infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);