Merge branch 'parameter_debug_dev'
This commit is contained in:
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
function getImportPath(filename) {
|
||||
return `./${filename}`;
|
||||
}
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-C3ZWZR1l.js","copilot_web/input.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-C_KwPGE8.js","copilot_web/assets/input-BFxtFr8c.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 t}from"./vendor-markdown-Dek94WS0.js";import{r,R as i}from"./vendor-react-V04_Axys.js";import{C as n}from"./message-components-C_KwPGE8.js";/* empty css */const o={EXPLAIN_NODE:"copilot:explain-node"},d=i.lazy(()=>a(()=>import(getImportPath("workflowChat-C3ZWZR1l.js")).then(e=>e.w),__vite__mapDeps([0,1,2,3,4,5,6])).then(e=>({default:e.default})));function p(){const[e,s]=r.useState(!1);return r.useEffect(()=>{const l=()=>{s(!0)};return window.addEventListener(o.EXPLAIN_NODE,l),()=>window.removeEventListener(o.EXPLAIN_NODE,l)},[]),t.jsx(n,{children:t.jsx("div",{className:"h-full w-full flex flex-col",children:t.jsx(r.Suspense,{fallback:t.jsx("div",{className:"h-full w-full flex items-center justify-center",children:"Loading..."}),children:t.jsx(d,{visible:!0,triggerUsage:e,onUsageTriggered:()=>s(!1)})})})})}export{p as default};
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-QQb_1pUR.js","copilot_web/input.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-B9b4Aopv.js","copilot_web/assets/input-CfrhPaqY.css","copilot_web/fonts.css"].map(path => {
|
||||
const apiBase = window.comfyAPI?.api?.api?.api_base;
|
||||
const prefix = apiBase ? `${apiBase.substring(1)}/` : '';
|
||||
return `${prefix}${path}`;
|
||||
}))))=>i.map(i=>d[i]);
|
||||
import{_ as a}from"./input.js";import{j as t}from"./vendor-markdown-Dek94WS0.js";import{r,R as i}from"./vendor-react-V04_Axys.js";import{C as n}from"./message-components-B9b4Aopv.js";/* empty css */const o={EXPLAIN_NODE:"copilot:explain-node"},d=i.lazy(()=>a(()=>import("./workflowChat-QQb_1pUR.js").then(e=>e.w),__vite__mapDeps([0,1,2,3,4,5,6])).then(e=>({default:e.default})));function p(){const[e,s]=r.useState(!1);return r.useEffect(()=>{const l=()=>{s(!0)};return window.addEventListener(o.EXPLAIN_NODE,l),()=>window.removeEventListener(o.EXPLAIN_NODE,l)},[]),t.jsx(n,{children:t.jsx("div",{className:"h-full w-full flex flex-col",children:t.jsx(r.Suspense,{fallback:t.jsx("div",{className:"h-full w-full flex items-center justify-center",children:"Loading..."}),children:t.jsx(d,{visible:!0,triggerUsage:e,onUsageTriggered:()=>s(!1)})})})})}export{p as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
@@ -1 +0,0 @@
|
||||
import{j as t}from"./vendor-markdown-Dek94WS0.js";import{W as p,g as u,a as d}from"./message-components-B9b4Aopv.js";import{r as N}from"./vendor-react-V04_Axys.js";function O({content:v,name:C="Assistant",avatar:_,latestInput:y,installedNodes:k,onAddMessage:g}){const h=JSON.parse(v),w=h.ext?.find(e=>e.type==="workflow")?.data||[],[i,c]=N.useState({}),b=async e=>{if(!e.id){console.error("No workflow id provided");return}const r=String(e.id);if(!i[r]){c(o=>({...o,[r]:!0})),p.trackEvent({event_type:"workflow_accept",message_type:"workflow",message_id:h.message_id,data:{workflow_id:e.id,workflow_name:e.name}});try{const o=await p.getOptimizedWorkflow(e.id,y);if(o.workflow){const a=new Set;if(o.workflow.nodes)for(const s of o.workflow.nodes)a.add(s.type);else for(const s of Object.values(o.workflow))a.add(s.class_type);const n=Array.from(a).filter(s=>!k.includes(s));if(console.log("[WorkflowOption] Missing node types:",n),n.length>0){try{console.log("[WorkflowOption] Fetching info for missing nodes");const s=await p.batchGetNodeInfo(n);console.log("[WorkflowOption] Received node infos:",s);const m={text:"",ext:[{type:"node_install_guide",data:s.map(l=>({name:l.name,repository_url:l.github_url}))}]},f={id:u(),role:"ai",content:JSON.stringify(m),format:"markdown",name:"Assistant",metadata:{pendingWorkflow:o.workflow,optimizedParams:o.optimized_params}};g?.(f)}catch(s){console.error("[WorkflowOption] Error fetching node info:",s),alert("Error checking required nodes. Please try again.")}finally{c(s=>({...s,[r]:!1}))}return}j(o.workflow,o.optimized_params)}}catch(o){console.error("Failed to optimize workflow:",o),alert("Failed to optimize workflow. Please try again.")}finally{c(o=>({...o,[r]:!1}))}}},j=(e,r)=>{e.nodes?d.loadGraphData(e):d.loadApiJson(e);for(const[a,n,s,m,f]of r){const l=d.graph._nodes_by_id[a].widgets;for(const x of l)x.name===m&&(x.value=f)}d.graph.setDirtyCanvas(!1,!0);const o={id:u(),role:"tool",content:JSON.stringify({text:"The workflow has been successfully loaded to the canvas",ext:[]}),format:"markdown",name:"Assistant"};g?.(o)};return t.jsx("div",{className:"space-y-3",children:w.length>0&&t.jsx("div",{className:"flex flex-col space-y-4",children:w.map((e,r)=>{const o=e.id?String(e.id):"";return t.jsxs("div",{className:"flex items-center gap-4 p-4 rounded-lg border border-gray-200 hover:bg-gray-50",children:[e.image&&t.jsx("img",{src:e.image,alt:e.name,className:"w-14 h-14 object-cover rounded-lg",onError:a=>{const n=a.target;n.onerror=null,n.src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='56' viewBox='0 0 56 56' fill='none'%3E%3Crect width='56' height='56' fill='%23F3F4F6'/%3E%3Cpath d='M28 28C30.2091 28 32 26.2091 32 24C32 21.7909 30.2091 20 28 20C25.7909 20 24 21.7909 24 24C24 26.2091 25.7909 28 28 28Z' fill='%239CA3AF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M18.7253 37.6307C19.8278 35.1533 22.6897 33.6 26 33.6H30C33.3103 33.6 36.1722 35.1533 37.2747 37.6307C37.6419 38.4561 37.0611 39.2 36.1694 39.2H19.8306C18.9389 39.2 18.3581 38.4561 18.7253 37.6307Z' fill='%239CA3AF'/%3E%3C/svg%3E"}}),t.jsxs("div",{className:"flex-1 break-words flex flex-col h-[4.5rem] justify-between",children:[t.jsx("div",{children:t.jsx("h3",{className:"font-medium text-sm line-clamp-2 h-10 overflow-hidden",children:e.name})}),t.jsxs("div",{className:"flex justify-between items-center mt-1",children:[e.description&&t.jsxs("div",{className:"relative group",children:[t.jsx("div",{className:"w-5 h-5 flex items-center justify-center text-gray-500 cursor-help",children:t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",className:"w-4 h-4",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z"})})}),t.jsx("div",{className:"absolute bottom-full left-0 mb-2 hidden group-hover:block",children:t.jsx("div",{className:"bg-gray-900 text-white text-xs rounded-md py-2 px-3 min-w-[400px] whitespace-normal break-words",children:e.description})})]}),t.jsx("button",{onClick:()=>b(e),disabled:i[o],className:`px-3 py-1.5 ${i[o]?"bg-gray-400 cursor-not-allowed":"bg-blue-500 hover:bg-blue-600"} text-white rounded-md transition-colors text-xs`,children:i[o]?"Loading...":"Accept"})]})]})]},r)})})})}export{O as WorkflowOption};
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
function getImportPath(filename) {
|
||||
return `./${filename}`;
|
||||
}
|
||||
import{j as t}from"./vendor-markdown-Dek94WS0.js";import{W as p,g as u,a as d}from"./message-components-C_KwPGE8.js";import{r as N}from"./vendor-react-V04_Axys.js";function O({content:v,name:C="Assistant",avatar:_,latestInput:y,installedNodes:k,onAddMessage:g}){const h=JSON.parse(v),w=h.ext?.find(e=>e.type==="workflow")?.data||[],[i,c]=N.useState({}),b=async e=>{if(!e.id){console.error("No workflow id provided");return}const r=String(e.id);if(!i[r]){c(o=>({...o,[r]:!0})),p.trackEvent({event_type:"workflow_accept",message_type:"workflow",message_id:h.message_id,data:{workflow_id:e.id,workflow_name:e.name}});try{const o=await p.getOptimizedWorkflow(e.id,y);if(o.workflow){const a=new Set;if(o.workflow.nodes)for(const s of o.workflow.nodes)a.add(s.type);else for(const s of Object.values(o.workflow))a.add(s.class_type);const n=Array.from(a).filter(s=>!k.includes(s));if(console.log("[WorkflowOption] Missing node types:",n),n.length>0){try{console.log("[WorkflowOption] Fetching info for missing nodes");const s=await p.batchGetNodeInfo(n);console.log("[WorkflowOption] Received node infos:",s);const m={text:"",ext:[{type:"node_install_guide",data:s.map(l=>({name:l.name,repository_url:l.github_url}))}]},f={id:u(),role:"ai",content:JSON.stringify(m),format:"markdown",name:"Assistant",metadata:{pendingWorkflow:o.workflow,optimizedParams:o.optimized_params}};g?.(f)}catch(s){console.error("[WorkflowOption] Error fetching node info:",s),alert("Error checking required nodes. Please try again.")}finally{c(s=>({...s,[r]:!1}))}return}j(o.workflow,o.optimized_params)}}catch(o){console.error("Failed to optimize workflow:",o),alert("Failed to optimize workflow. Please try again.")}finally{c(o=>({...o,[r]:!1}))}}},j=(e,r)=>{e.nodes?d.loadGraphData(e):d.loadApiJson(e);for(const[a,n,s,m,f]of r){const l=d.graph._nodes_by_id[a].widgets;for(const x of l)x.name===m&&(x.value=f)}d.graph.setDirtyCanvas(!1,!0);const o={id:u(),role:"tool",content:JSON.stringify({text:"The workflow has been successfully loaded to the canvas",ext:[]}),format:"markdown",name:"Assistant"};g?.(o)};return t.jsx("div",{className:"space-y-3",children:w.length>0&&t.jsx("div",{className:"flex flex-col space-y-4",children:w.map((e,r)=>{const o=e.id?String(e.id):"";return t.jsxs("div",{className:"flex items-center gap-4 p-4 rounded-lg border border-gray-200 hover:bg-gray-50",children:[e.image&&t.jsx("img",{src:e.image,alt:e.name,className:"w-14 h-14 object-cover rounded-lg",onError:a=>{const n=a.target;n.onerror=null,n.src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='56' viewBox='0 0 56 56' fill='none'%3E%3Crect width='56' height='56' fill='%23F3F4F6'/%3E%3Cpath d='M28 28C30.2091 28 32 26.2091 32 24C32 21.7909 30.2091 20 28 20C25.7909 20 24 21.7909 24 24C24 26.2091 25.7909 28 28 28Z' fill='%239CA3AF'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M18.7253 37.6307C19.8278 35.1533 22.6897 33.6 26 33.6H30C33.3103 33.6 36.1722 35.1533 37.2747 37.6307C37.6419 38.4561 37.0611 39.2 36.1694 39.2H19.8306C18.9389 39.2 18.3581 38.4561 18.7253 37.6307Z' fill='%239CA3AF'/%3E%3C/svg%3E"}}),t.jsxs("div",{className:"flex-1 break-words flex flex-col h-[4.5rem] justify-between",children:[t.jsx("div",{children:t.jsx("h3",{className:"font-medium text-sm line-clamp-2 h-10 overflow-hidden",children:e.name})}),t.jsxs("div",{className:"flex justify-between items-center mt-1",children:[e.description&&t.jsxs("div",{className:"relative group",children:[t.jsx("div",{className:"w-5 h-5 flex items-center justify-center text-gray-500 cursor-help",children:t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",className:"w-4 h-4",children:t.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z"})})}),t.jsx("div",{className:"absolute bottom-full left-0 mb-2 hidden group-hover:block",children:t.jsx("div",{className:"bg-gray-900 text-white text-xs rounded-md py-2 px-3 min-w-[400px] whitespace-normal break-words",children:e.description})})]}),t.jsx("button",{onClick:()=>b(e),disabled:i[o],className:`px-3 py-1.5 ${i[o]?"bg-gray-400 cursor-not-allowed":"bg-blue-500 hover:bg-blue-600"} text-white rounded-md transition-colors text-xs`,children:i[o]?"Loading...":"Accept"})]})]})]},r)})})})}export{O as WorkflowOption};
|
||||
+1
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
Vendored
+14
-2
@@ -1,2 +1,14 @@
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/App-mzuNw1xF.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-B9b4Aopv.js","copilot_web/fonts.css"])))=>i.map(i=>d[i]);
|
||||
import{j as s}from"./vendor-markdown-Dek94WS0.js";import{a as w,R as p,r as x}from"./vendor-react-V04_Axys.js";import{w as v,a as g}from"./message-components-B9b4Aopv.js";/* empty css */const R="modulepreload",b=function(e){return"/"+e},m={},C=function(c,a,P){let d=Promise.resolve();if(a&&a.length>0){document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),t=r?.nonce||r?.getAttribute("nonce");d=Promise.allSettled(a.map(o=>{if(o=b(o),o in m)return;m[o]=!0;const i=o.endsWith(".css"),h=i?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${h}`))return;const n=document.createElement("link");if(n.rel=i?"stylesheet":R,i||(n.as="script"),n.crossOrigin="",n.href=o,t&&n.setAttribute("nonce",t),document.head.appendChild(n),i)return new Promise((y,E)=>{n.addEventListener("load",y),n.addEventListener("error",()=>E(new Error(`Unable to preload CSS for ${o}`)))})}))}function u(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return d.then(r=>{for(const t of r||[])t.status==="rejected"&&u(t.reason);return c().catch(u)})};var l={},f=w;l.createRoot=f.createRoot,l.hydrateRoot=f.hydrateRoot;const S=p.lazy(()=>C(async()=>{const{default:e}=await import("./App-mzuNw1xF.js");return{default:e}},__vite__mapDeps([0,1,2,3,4])).then(({default:e})=>({default:e})));function j(){return new Promise(e=>{if(document.body)return e(document.body);document.addEventListener("DOMContentLoaded",()=>{e(document.body)})})}j().then(()=>v()).then(()=>{g.extensionManager.registerSidebarTab({id:"comfyui-copilot",icon:"cc-icon-logo",title:"ComfyUI Copilot",tooltip:"ComfyUI Copilot",type:"custom",render:e=>{const c=document.createElement("div");c.id="comfyui-copilot-plugin",c.className="h-full w-full flex flex-col",e.style.height="100%",e.appendChild(c),l.createRoot(c).render(s.jsx(p.StrictMode,{children:s.jsx(x.Suspense,{fallback:s.jsx("div",{className:"h-full w-full flex items-center justify-center",children:"Loading..."}),children:s.jsx(S,{})})}))}})});export{C as _};
|
||||
function getImportPath(filename) {
|
||||
return `./${filename}`;
|
||||
}
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/App-C63C0sLF.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-C_KwPGE8.js","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{j as s}from"./vendor-markdown-Dek94WS0.js";import{a as w,R as p,r as x}from"./vendor-react-V04_Axys.js";import{w as v,a as g}from"./message-components-C_KwPGE8.js";/* empty css */const R="modulepreload",b=function(e){return"/"+e},m={},C=function(c,a,P){let d=Promise.resolve();if(a&&a.length>0){document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),t=r?.nonce||r?.getAttribute("nonce");d=Promise.allSettled(a.map(o=>{if(o=b(o),o in m)return;m[o]=!0;const i=o.endsWith(".css"),h=i?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${o}"]${h}`))return;const n=document.createElement("link");if(n.rel=i?"stylesheet":R,i||(n.as="script"),n.crossOrigin="",n.href=o,t&&n.setAttribute("nonce",t),document.head.appendChild(n),i)return new Promise((y,E)=>{n.addEventListener("load",y),n.addEventListener("error",()=>E(new Error(`Unable to preload CSS for ${o}`)))})}))}function u(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return d.then(r=>{for(const t of r||[])t.status==="rejected"&&u(t.reason);return c().catch(u)})};var l={},f=w;l.createRoot=f.createRoot,l.hydrateRoot=f.hydrateRoot;const S=p.lazy(()=>C(async()=>{const{default:e}=await import(getImportPath("App-C63C0sLF.js"));return{default:e}},__vite__mapDeps([0,1,2,3,4])).then(({default:e})=>({default:e})));function j(){return new Promise(e=>{if(document.body)return e(document.body);document.addEventListener("DOMContentLoaded",()=>{e(document.body)})})}j().then(()=>v()).then(()=>{g.extensionManager.registerSidebarTab({id:"comfyui-copilot",icon:"cc-icon-logo",title:"ComfyUI Copilot",tooltip:"ComfyUI Copilot",type:"custom",render:e=>{const c=document.createElement("div");c.id="comfyui-copilot-plugin",c.className="h-full w-full flex flex-col",e.style.height="100%",e.appendChild(c),l.createRoot(c).render(s.jsx(p.StrictMode,{children:s.jsx(x.Suspense,{fallback:s.jsx("div",{className:"h-full w-full flex items-center justify-center",children:"Loading..."}),children:s.jsx(S,{})})}))}})});export{C as _};
|
||||
|
||||
Vendored
+46
-43
File diff suppressed because one or more lines are too long
+4
-1
@@ -1,4 +1,7 @@
|
||||
import{r as so,c as ri,g as oo}from"./vendor-react-V04_Axys.js";var $a={exports:{}},tn={};/**
|
||||
function getImportPath(filename) {
|
||||
return `./${filename}`;
|
||||
}
|
||||
import{r as so,c as ri,g as oo}from"./vendor-react-V04_Axys.js";var $a={exports:{}},tn={};/**
|
||||
* @license React
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
|
||||
+4
-1
@@ -1,4 +1,7 @@
|
||||
var vd=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Ja(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Uo={exports:{}},T={};/**
|
||||
function getImportPath(filename) {
|
||||
return `./${filename}`;
|
||||
}
|
||||
var vd=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Ja(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Uo={exports:{}},T={};/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
|
||||
+4
-1
@@ -1 +1,4 @@
|
||||
import"./vendor-react-V04_Axys.js";
|
||||
function getImportPath(filename) {
|
||||
return `./${filename}`;
|
||||
}
|
||||
import"./vendor-react-V04_Axys.js";
|
||||
|
||||
+141
File diff suppressed because one or more lines are too long
-129
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "ComfyUI-Copilot"
|
||||
description = "Your Intelligent Assistant for Comfy-UI."
|
||||
version = "1.3.0"
|
||||
version = "1.3.3"
|
||||
license = {file = "LICENSE"}
|
||||
|
||||
[project.urls]
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"build": "vite build && node scripts/post-build.js",
|
||||
"build:css": "tailwindcss -i ./src/scoped-tailwind.css -o ./src/output.css --watch",
|
||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview",
|
||||
|
||||
+69
-18
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
* @Author: ai-business-hql qingli.hql@alibaba-inc.com
|
||||
* @Date: 2025-02-17 20:53:45
|
||||
* @LastEditors: ai-business-hql qingli.hql@alibaba-inc.com
|
||||
* @LastEditTime: 2025-06-05 11:18:48
|
||||
* @FilePath: /comfyui_copilot/ui/scripts/post-build.js
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import glob from 'glob';
|
||||
@@ -8,44 +16,87 @@ import { dirname } from 'path';
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
// 在 dist/copilot_web 目录下查找包含 __vite__mapDeps 的 JS 文件
|
||||
// 在 dist/copilot_web 目录下查找所有 JS 文件
|
||||
const distDir = path.resolve(__dirname, '../../dist/copilot_web');
|
||||
const files = glob.sync(`${distDir}/**/App-*.js`);
|
||||
const files = glob.sync(`${distDir}/**/*.js`);
|
||||
|
||||
files.forEach(file => {
|
||||
console.log('start modify', file)
|
||||
let content = fs.readFileSync(file, 'utf-8');
|
||||
|
||||
// 检查是否已经有 getImportPath 函数(function 或 const 形式)
|
||||
// if (!content.includes('getImportPath')) {
|
||||
// content = `function getImportPath(filename) {
|
||||
// const apiBase = window.comfyAPI?.api?.api?.api_base;
|
||||
// if (apiBase) {
|
||||
// // 有 API base 时,使用完整路径
|
||||
// return \`\${apiBase.substring(1)}/copilot_web/\${filename}\`;
|
||||
// } else {
|
||||
// // 没有 API base 时,使用相对路径(因为所有文件都在同一目录)
|
||||
// return \`./\${filename}\`;
|
||||
// }
|
||||
// }
|
||||
// ` + content;
|
||||
// }
|
||||
if (!content.includes('getImportPath')) {
|
||||
content = `function getImportPath(filename) {
|
||||
return \`./\${filename}\`;
|
||||
}
|
||||
` + content;
|
||||
}
|
||||
|
||||
if (content.includes('__vite__mapDeps')) {
|
||||
// 提取新格式的依赖数组,使用非贪婪匹配
|
||||
const depsMatch = content.match(/const __vite__mapDeps=\(.*?m\.f=\[(.*?)\]/);
|
||||
// 尝试两种不同的格式
|
||||
let depsMatch = content.match(/const __vite__mapDeps=\(.*?m\.f=\[(.*?)\]/);
|
||||
|
||||
// 如果第一种格式不匹配,尝试第二种格式(用于 input.js)
|
||||
if (!depsMatch) {
|
||||
depsMatch = content.match(/const __vite__mapDeps=\(.*?m\.f\|\|\(m\.f=\[(.*?)\]\)\)\)/);
|
||||
}
|
||||
|
||||
if (depsMatch && depsMatch[1]) {
|
||||
const originalDeps = depsMatch[1];
|
||||
|
||||
// 如果文件中还没有路径转换逻辑,则添加
|
||||
if (!content.includes('window.comfyAPI?.api?.api?.api_base')) {
|
||||
if (!content.includes('.map(path =>')) {
|
||||
// 替换整个 __vite__mapDeps 函数,处理两种可能的格式
|
||||
content = content.replace(
|
||||
/const __vite__mapDeps=.*?\)=>i\.map\(i=>d\[i\]\);/,
|
||||
/const __vite__mapDeps=\([^;]+\);/,
|
||||
`const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=[${originalDeps}].map(path => {
|
||||
const apiBase = window.comfyAPI?.api?.api?.api_base;
|
||||
const prefix = apiBase ? \`\${apiBase.substring(1)}/\` : '';
|
||||
return \`\${prefix}\${path}\`;
|
||||
if (apiBase) {
|
||||
// 有 API base 时,使用完整路径
|
||||
return \`\${apiBase.substring(1)}/\${path}\`;
|
||||
} else {
|
||||
// 没有 API base 时,使用相对路径
|
||||
return \`./\${path}\`;
|
||||
}
|
||||
}))))=>i.map(i=>d[i]);`
|
||||
);
|
||||
} else {
|
||||
// 如果已经有路径转换逻辑,只替换依赖数组部分
|
||||
content = content.replace(
|
||||
/const __vite__mapDeps=\(.*?\)=>i\.map\(i=>d\[i\]\);/,
|
||||
`const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=[${originalDeps}])))=>i.map(i=>d[i]);`
|
||||
);
|
||||
}
|
||||
|
||||
fs.writeFileSync(file, content, 'utf-8');
|
||||
console.log(`Modified ${path.basename(file)}`);
|
||||
console.log(`Modified ${path.basename(file)} - __vite__mapDeps`);
|
||||
} else {
|
||||
console.log(`No deps pattern found in ${path.basename(file)}`);
|
||||
}
|
||||
} else {
|
||||
console.log(`No __vite__mapDeps found in ${path.basename(file)}`);
|
||||
}
|
||||
});
|
||||
|
||||
// 处理 import("filename") 形式的动态导入
|
||||
const dynamicImportPattern = /import\("([^"]+\.js)"\)/g;
|
||||
if (dynamicImportPattern.test(content)) {
|
||||
content = content.replace(dynamicImportPattern, (match, filename) => {
|
||||
// 只处理相对路径的导入
|
||||
if (filename.startsWith('./') || !filename.includes('/')) {
|
||||
const cleanFilename = filename.startsWith('./') ? filename.substring(2) : filename;
|
||||
return `import(getImportPath("${cleanFilename}"))`;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
}
|
||||
|
||||
fs.writeFileSync(file, content, 'utf-8');
|
||||
console.log(`Modified ${path.basename(file)}`);
|
||||
});
|
||||
|
||||
// 不需要单独处理 input.js,因为它已经在上面的循环中被处理了
|
||||
@@ -480,6 +480,29 @@ export namespace WorkflowChatAPI {
|
||||
// This should never be reached due to the throw in the loop, but TypeScript needs it
|
||||
throw lastError;
|
||||
}
|
||||
|
||||
export async function listModels(): Promise<{ models: { name: string; image_enable: boolean }[] }> {
|
||||
const apiKey = getApiKey();
|
||||
const browserLanguage = getBrowserLanguage();
|
||||
|
||||
// Prepare headers
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
'accept': 'application/json',
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'trace-id': generateUUID(),
|
||||
'Accept-Language': browserLanguage,
|
||||
};
|
||||
|
||||
const response = await fetch(`${BASE_URL}/v1/models`, {
|
||||
method: 'GET',
|
||||
headers,
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
return result as { models: { name: string; image_enable: boolean }[] };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* @Author: 晴知 qingli.hql@alibaba-inc.com
|
||||
* @Date: 2024-11-28 10:19:07
|
||||
* @LastEditors: ai-business-hql ai.bussiness.hql@gmail.com
|
||||
* @LastEditTime: 2025-04-22 17:52:22
|
||||
* @LastEditors: ai-business-hql qingli.hql@alibaba-inc.com
|
||||
* @LastEditTime: 2025-06-05 15:01:55
|
||||
* @FilePath: /comfyui_copilot/ui/src/components/chat/ChatHeader.tsx
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
@@ -73,7 +73,7 @@ export function ChatHeader({
|
||||
bg-white border-gray-200 sticky top-2 z-10">
|
||||
<div className="flex items-center space-x-1">
|
||||
<img
|
||||
src={logoImage}
|
||||
src={`.${logoImage}`}
|
||||
alt="ComfyUI-Copilot Logo"
|
||||
className="h-7 w-7 -ml-1"
|
||||
/>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { ChangeEvent, KeyboardEvent, useState, useRef, useEffect } from 'react';
|
||||
import { SendIcon, ImageIcon, PlusIcon, XIcon } from './Icons';
|
||||
import React from 'react';
|
||||
import { WorkflowChatAPI } from '../../apis/workflowChatApi';
|
||||
|
||||
interface ChatInputProps {
|
||||
input: string;
|
||||
@@ -27,25 +28,6 @@ export interface UploadedImage {
|
||||
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
||||
const SUPPORTED_FORMATS = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
||||
|
||||
const models_conf = [
|
||||
{
|
||||
"name": "gpt-4o",
|
||||
"image_enable": true
|
||||
},
|
||||
{
|
||||
"name": "gpt-4o-mini",
|
||||
"image_enable": true
|
||||
},
|
||||
{
|
||||
"name": "qwen-plus",
|
||||
"image_enable": false
|
||||
},
|
||||
{
|
||||
"name": "DeepSeek-V3",
|
||||
"image_enable": false
|
||||
}
|
||||
]
|
||||
|
||||
export function ChatInput({
|
||||
input,
|
||||
loading,
|
||||
@@ -59,6 +41,7 @@ export function ChatInput({
|
||||
onModelChange,
|
||||
}: ChatInputProps) {
|
||||
const [showUploadModal, setShowUploadModal] = useState(false);
|
||||
const [models, setModels] = useState<{ name: string; image_enable: boolean }[]>([]);
|
||||
const fileInputRef = React.useRef<HTMLInputElement>(null);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
@@ -72,6 +55,39 @@ export function ChatInput({
|
||||
}
|
||||
}, [input]);
|
||||
|
||||
// Load models on component mount
|
||||
useEffect(() => {
|
||||
const loadModels = async () => {
|
||||
try {
|
||||
const result = await WorkflowChatAPI.listModels();
|
||||
setModels(result.models);
|
||||
} catch (error) {
|
||||
console.error('Failed to load models:', error);
|
||||
// Fallback to default models if API fails
|
||||
setModels([
|
||||
{
|
||||
"name": "gpt-4o",
|
||||
"image_enable": true
|
||||
},
|
||||
{
|
||||
"name": "gpt-4o-mini",
|
||||
"image_enable": true
|
||||
},
|
||||
{
|
||||
"name": "qwen-plus",
|
||||
"image_enable": false
|
||||
},
|
||||
{
|
||||
"name": "DeepSeek-V3",
|
||||
"image_enable": false
|
||||
}
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
loadModels();
|
||||
}, []);
|
||||
|
||||
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
if (event.target.files) {
|
||||
const invalidFiles: string[] = [];
|
||||
@@ -161,7 +177,7 @@ export function ChatInput({
|
||||
focus:border-transparent hover:bg-gray-50
|
||||
transition-colors border-0"
|
||||
>
|
||||
{models_conf.map((model) => (
|
||||
{models.map((model) => (
|
||||
<option value={model.name} key={model.name}>{model.name}</option>
|
||||
))}
|
||||
</select>
|
||||
@@ -170,11 +186,11 @@ export function ChatInput({
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowUploadModal(true)}
|
||||
disabled={!models_conf.find(model => model.name === selectedModel)?.image_enable}
|
||||
disabled={!models.find(model => model.name === selectedModel)?.image_enable}
|
||||
className={`p-1.5 text-gray-500 bg-white border-none
|
||||
hover:bg-gray-100 hover:text-gray-600
|
||||
transition-all duration-200 outline-none
|
||||
${!models_conf.find(model => model.name === selectedModel)?.image_enable ? 'opacity-50 cursor-not-allowed' : ''}`}>
|
||||
${!models.find(model => model.name === selectedModel)?.image_enable ? 'opacity-50 cursor-not-allowed' : ''}`}>
|
||||
<ImageIcon className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -66,10 +66,11 @@ export const HistoryItemScreen: React.FC<HistoryItemScreenProps> = ({
|
||||
<ImageModal
|
||||
visible={modalVisible}
|
||||
imageUrl={modalImageUrl}
|
||||
params={{
|
||||
...params,
|
||||
params={modalImageParams ? {
|
||||
...modalImageParams,
|
||||
// Keep the nodeName for context, ensuring it's always available
|
||||
nodeNames: { [historyItem.nodeName.split('<')[0]]: historyItem.nodeName.split('<')[0] }
|
||||
}}
|
||||
} : undefined}
|
||||
onClose={closeImageModal}
|
||||
/>
|
||||
|
||||
|
||||
@@ -117,6 +117,18 @@ export const ResultGalleryScreen: React.FC<ResultGalleryScreenProps> = ({
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div className="p-2 text-xs text-gray-600 bg-white max-h-16 overflow-y-auto">
|
||||
{Object.entries(image.params)
|
||||
// Filter out nodeParams and other complex objects from display
|
||||
.filter(([paramName, value]) =>
|
||||
paramName !== 'nodeParams' &&
|
||||
typeof value !== 'object'
|
||||
)
|
||||
.map(([paramName, value]) => (
|
||||
<div key={paramName}>{paramName}: {String(value)}</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -427,6 +427,9 @@
|
||||
.h-px {
|
||||
height: 1px;
|
||||
}
|
||||
.max-h-16 {
|
||||
max-height: 4rem;
|
||||
}
|
||||
.max-h-60 {
|
||||
max-height: 15rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user