feat:减小chunks来优化性能,在userMessage右下角添加icon用于复制trace_id

This commit is contained in:
晴知
2025-02-21 13:16:37 +08:00
parent c49bf72757
commit a2ed2015c0
24 changed files with 696 additions and 537 deletions
+6
View File
@@ -0,0 +1,6 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-YHBEer0-.js","copilot_web/vendor-markdown-Dek94WS0.js","copilot_web/vendor-react-V04_Axys.js","copilot_web/message-components-DAhwqZXx.js","copilot_web/input.js","copilot_web/assets/input-DHLrLZYh.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{_}from"./input.js";import{j as n}from"./vendor-markdown-Dek94WS0.js";import{r as t,R as m}from"./vendor-react-V04_Axys.js";const b=9999999,g={EXPLAIN_NODE:"copilot:explain-node"},y="/copilot_web/assets/logo-BTZhX0BN.png",L=m.lazy(()=>_(()=>import("./workflowChat-YHBEer0-.js"),__vite__mapDeps([0,1,2,3,4,5])).then(r=>({default:r.default})));function N(){const r=t.useRef(null),[p,a]=t.useState(!1),[i,d]=t.useState(),[s,u]=t.useState(!1),[l,x]=t.useState({x:0,y:0}),[h,c]=t.useState(!1);t.useEffect(()=>{const e=()=>{console.log("Explain node event received"),a(!0),c(!0)};return window.addEventListener(g.EXPLAIN_NODE,e),()=>window.removeEventListener(g.EXPLAIN_NODE,e)},[]),t.useEffect(()=>{d({x:window.innerWidth-160,y:20})},[]);const E=e=>{e.preventDefault(),u(!0);const o=e.currentTarget.getBoundingClientRect();x({x:e.clientX-o.left,y:e.clientY-o.top})};return t.useEffect(()=>{const e=f=>{if(s){const v=Math.min(Math.max(0,f.clientX-l.x),window.innerWidth-100),w=Math.min(Math.max(0,f.clientY-l.y),window.innerHeight-40);d({x:v,y:w})}},o=()=>{u(!1)};return s&&(document.addEventListener("mousemove",e),document.addEventListener("mouseup",o)),()=>{document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",o)}},[s,l]),i?n.jsx("div",{ref:r,children:n.jsxs("div",{className:"fixed",style:{zIndex:b,left:i.x,top:i.y,cursor:s?"grabbing":"grab"},children:[n.jsxs("button",{onMouseDown:E,onClick:()=>{a(!0)},className:"px-2 py-1 border border-gray-300 rounded-md bg-white text-black hover:bg-blue-300 hover:font-bold transition-colors select-none w-40 flex items-center space-x-1",style:{marginLeft:"-40px"},children:[n.jsx("img",{src:y,alt:"ComfyUI-Copilot Logo",className:"h-8 w-8"}),n.jsx("span",{className:"text-[14px] font-medium text-gray-800",children:"ComfyUI-Copilot"})]}),n.jsx(m.Suspense,{fallback:n.jsx("div",{children:"Loading..."}),children:n.jsx(L,{onClose:()=>{a(!1),c(!1)},visible:p,triggerUsage:h,onUsageTriggered:()=>c(!1)})})]})}):null}const I=Object.freeze(Object.defineProperty({__proto__:null,default:N},Symbol.toStringTag,{value:"Module"}));export{I as A,y as l};
-6
View File
@@ -1,6 +0,0 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["copilot_web/workflowChat-BvDkCk05.js","copilot_web/input.js","copilot_web/assets/input-CH_9SpKL.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{r as t,j as n,R as w,_}from"./input.js";const b=9999999,g={EXPLAIN_NODE:"copilot:explain-node"},y="/copilot_web/assets/logo-BTZhX0BN.png",N=w.lazy(()=>_(()=>import("./workflowChat-BvDkCk05.js"),__vite__mapDeps([0,1,2])));function L(){const f=t.useRef(null),[m,r]=t.useState(!1),[a,c]=t.useState(),[s,u]=t.useState(!1),[i,p]=t.useState({x:0,y:0}),[x,l]=t.useState(!1);t.useEffect(()=>{const e=()=>{console.log("Explain node event received"),r(!0),l(!0)};return window.addEventListener(g.EXPLAIN_NODE,e),()=>window.removeEventListener(g.EXPLAIN_NODE,e)},[]),t.useEffect(()=>{c({x:window.innerWidth-160,y:20})},[]);const h=e=>{e.preventDefault(),u(!0);const o=e.currentTarget.getBoundingClientRect();p({x:e.clientX-o.left,y:e.clientY-o.top})};return t.useEffect(()=>{const e=d=>{if(s){const E=Math.min(Math.max(0,d.clientX-i.x),window.innerWidth-100),v=Math.min(Math.max(0,d.clientY-i.y),window.innerHeight-40);c({x:E,y:v})}},o=()=>{u(!1)};return s&&(document.addEventListener("mousemove",e),document.addEventListener("mouseup",o)),()=>{document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",o)}},[s,i]),a?n.jsx("div",{ref:f,children:n.jsxs("div",{className:"fixed",style:{zIndex:b,left:a.x,top:a.y,cursor:s?"grabbing":"grab"},children:[n.jsxs("button",{onMouseDown:h,onClick:()=>{r(!0)},className:"px-2 py-1 border border-gray-300 rounded-md bg-white text-black hover:bg-blue-300 hover:font-bold transition-colors select-none w-40 flex items-center space-x-1",style:{marginLeft:"-40px"},children:[n.jsx("img",{src:y,alt:"ComfyUI-Copilot Logo",className:"h-8 w-8"}),n.jsx("span",{className:"text-[14px] font-medium text-gray-800",children:"ComfyUI-Copilot"})]}),n.jsx(N,{onClose:()=>{r(!1),l(!1)},visible:m,triggerUsage:x,onUsageTriggered:()=>l(!1)})]})}):null}const D=Object.freeze(Object.defineProperty({__proto__:null,default:L},Symbol.toStringTag,{value:"Module"}));export{D as A,y as l};
+1
View File
@@ -0,0 +1 @@
import{j as e}from"./vendor-markdown-Dek94WS0.js";import{W as f,g as h,a as l}from"./message-components-DAhwqZXx.js";import"./vendor-react-V04_Axys.js";function A({content:g,name:j="Assistant",avatar:k,latestInput:x,installedNodes:w,onAddMessage:d}){const c=JSON.parse(g).ext?.find(o=>o.type==="workflow")?.data||[],u=async o=>{if(!o.id){console.error("No workflow id provided");return}try{const t=await f.getOptimizedWorkflow(o.id,x);if(t.workflow){const n=new Set;for(const s of t.workflow.nodes)n.add(s.type);const r=Array.from(n).filter(s=>!w.includes(s));if(console.log("[WorkflowOption] Missing node types:",r),r.length>0)try{console.log("[WorkflowOption] Fetching info for missing nodes");const s=await f.batchGetNodeInfo(r);console.log("[WorkflowOption] Received node infos:",s);const m={text:"",ext:[{type:"node_install_guide",data:s.map(a=>({name:a.name,repository_url:a.github_url}))}]},i={id:h(),role:"ai",content:JSON.stringify(m),format:"markdown",name:"Assistant",metadata:{pendingWorkflow:t.workflow,optimizedParams:t.optimized_params}};d?.(i);return}catch(s){console.error("[WorkflowOption] Error fetching node info:",s),alert("Error checking required nodes. Please try again.");return}v(t.workflow,t.optimized_params)}}catch(t){console.error("Failed to optimize workflow:",t)}},v=(o,t)=>{l.loadGraphData(o);for(const[r,s,m,i,a]of t){const y=l.graph._nodes_by_id[r].widgets;for(const p of y)p.name===i&&(p.value=a)}l.graph.setDirtyCanvas(!1,!0);const n={id:h(),role:"tool",content:JSON.stringify({text:"The workflow has been successfully loaded to the canvas",ext:[]}),format:"markdown",name:"Assistant"};d?.(n)};return e.jsx("div",{className:"space-y-3",children:c.length>0&&e.jsx("div",{className:"flex flex-col space-y-4",children:c.map((o,t)=>e.jsxs("div",{className:"flex items-center gap-4 p-4 rounded-lg border border-gray-200 hover:bg-gray-50",children:[o.image&&e.jsx("img",{src:o.image,alt:o.name,className:"w-14 h-14 object-cover rounded-lg",onError:n=>{const r=n.target;r.onerror=null,r.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"}}),e.jsxs("div",{className:"flex-1 break-words flex flex-col h-[4.5rem] justify-between",children:[e.jsx("div",{children:e.jsx("h3",{className:"font-medium text-sm line-clamp-2 h-10 overflow-hidden",children:o.name})}),e.jsxs("div",{className:"flex justify-between items-center mt-1",children:[o.description&&e.jsxs("div",{className:"relative group",children:[e.jsx("div",{className:"w-5 h-5 flex items-center justify-center text-gray-500 cursor-help",children:e.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:e.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"})})}),e.jsx("div",{className:"absolute bottom-full left-0 mb-2 hidden group-hover:block",children:e.jsx("div",{className:"bg-gray-900 text-white text-xs rounded-md py-1 px-2 max-w-xs",children:o.description})})]}),e.jsx("button",{onClick:()=>u(o),className:"px-3 py-1.5 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition-colors text-xs",children:"Accept"})]})]})]},t))})})}export{A as WorkflowOption};
File diff suppressed because one or more lines are too long
+2 -40
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
+1
View File
@@ -0,0 +1 @@
import"./vendor-react-V04_Axys.js";
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+15
View File
@@ -8,6 +8,7 @@
"name": "comfyui-workspace-manager",
"version": "0.0.0",
"dependencies": {
"@heroicons/react": "^2.2.0",
"@tabler/icons-react": "^2.42.0",
"dexie": "^3.2.4",
"dexie-react-hooks": "^1.1.7",
@@ -899,6 +900,14 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@heroicons/react": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/@heroicons/react/-/react-2.2.0.tgz",
"integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
"peerDependencies": {
"react": ">= 16 || ^19.0.0-rc"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.13",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
@@ -6903,6 +6912,12 @@
"integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==",
"dev": true
},
"@heroicons/react": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/@heroicons/react/-/react-2.2.0.tgz",
"integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
"requires": {}
},
"@humanwhocodes/config-array": {
"version": "0.11.13",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
+1
View File
@@ -13,6 +13,7 @@
"build:prod": "VITE_API_BASE_URL=https://comfyui-copilot-server.onrender.com vite build && node scripts/post-build.js"
},
"dependencies": {
"@heroicons/react": "^2.2.0",
"@tabler/icons-react": "^2.42.0",
"dexie": "^3.2.4",
"dexie-react-hooks": "^1.1.7",
+15 -10
View File
@@ -5,7 +5,9 @@ import React, { useRef, useState, useEffect } from "react";
import { DRAWER_Z_INDEX } from "./const";
import { COPILOT_EVENTS } from "./constants/events";
import logoImage from '../../assets/logo.png';
const WorkflowChat = React.lazy(() => import("./workflowChat/workflowChat"));
const WorkflowChat = React.lazy(() => import("./workflowChat/workflowChat").then(module => ({
default: module.default
})));
export default function App() {
const workspaceContainerRef = useRef(null);
@@ -95,15 +97,18 @@ export default function App() {
/>
<span className="text-[14px] font-medium text-gray-800">ComfyUI-Copilot</span>
</button>
<WorkflowChat
onClose={() => {
setShowChat(false);
setShouldTriggerUsage(false);
}}
visible={showChat}
triggerUsage={shouldTriggerUsage}
onUsageTriggered={() => setShouldTriggerUsage(false)}
/>
<React.Suspense fallback={<div>Loading...</div>}>
<WorkflowChat
onClose={() => {
setShowChat(false);
setShouldTriggerUsage(false);
}}
visible={showChat}
triggerUsage={shouldTriggerUsage}
onUsageTriggered={() => setShouldTriggerUsage(false)}
/>
</React.Suspense>
</div>
</div>
);
+3 -2
View File
@@ -24,7 +24,8 @@ export namespace WorkflowChatAPI {
prompt: string,
images: File[] = [],
intent: string | null = null,
ext: any | null = null
ext: any | null = null,
trace_id?: string
): AsyncGenerator<ChatResponse> {
try {
const apiKey = getApiKey();
@@ -59,7 +60,7 @@ export namespace WorkflowChatAPI {
'accept': 'application/json',
'Access-Control-Allow-Origin': '*',
'Authorization': `Bearer ${apiKey}`,
'trace-id': generateUUID(),
'trace-id': trace_id || generateUUID(),
},
body: JSON.stringify({
session_id: sessionId,
+2 -1
View File
@@ -128,8 +128,9 @@ export function ChatInput({
focus:border-transparent hover:bg-gray-50
transition-colors border-0"
>
<option value="gpt-4o">gpt-4o</option>
<option value="gpt-4o-mini">gpt-4o-mini</option>
<option value="gpt-4o">gpt-4o</option>
<option value="DeepSeek-V3">DeepSeek-V3</option>
</select>
+16 -2
View File
@@ -13,6 +13,7 @@ import { LoadingMessage } from "./messages/LoadingMessage";
import { generateUUID } from "../../utils/uuid";
import { app } from "../../utils/comfyapp";
import { addNodeOnGraph } from "../../utils/graphUtils";
import React, { lazy } from "react";
interface MessageListProps {
messages: Message[];
@@ -27,12 +28,25 @@ const getAvatar = (name?: string) => {
return `https://ui-avatars.com/api/?name=${name || 'User'}&background=random`;
};
// 使用动态导入替换直接导入
// const AIMessage = lazy(() => import('./messages/AIMessage').then(m => ({ default: m.AIMessage })));
// const UserMessage = lazy(() => import('./messages/UserMessage').then(m => ({ default: m.UserMessage })));
const WorkflowOption = lazy(() => import('./messages/WorkflowOption').then(m => ({ default: m.WorkflowOption })));
const NodeSearch = lazy(() => import('./messages/NodeSearch').then(m => ({ default: m.NodeSearch })));
const NodeRecommend = lazy(() => import('./messages/NodeRecommend').then(m => ({ default: m.NodeRecommend })));
const DownstreamSubgraphs = lazy(() => import('./messages/DownstreamSubgraphs').then(m => ({ default: m.DownstreamSubgraphs })));
const NodeInstallGuide = lazy(() => import('./messages/NodeInstallGuide').then(m => ({ default: m.NodeInstallGuide })));
export function MessageList({ messages, latestInput, onOptionClick, installedNodes, onAddMessage, loading }: MessageListProps) {
const renderMessage = (message: Message) => {
const renderMessage = (message: Message) => {
console.log('[MessageList] Rendering message:', message);
if (message.role === 'user') {
return <UserMessage key={message.id} content={message.content} />;
return <UserMessage
key={message.id}
content={message.content}
trace_id={message.trace_id}
/>;
}
if (message.role === 'ai' || message.role === 'tool') {
@@ -1,3 +1,11 @@
/*
* @Author: 晴知 qingli.hql@alibaba-inc.com
* @Date: 2025-02-17 20:53:45
* @LastEditors: 晴知 qingli.hql@alibaba-inc.com
* @LastEditTime: 2025-02-20 18:11:08
* @FilePath: /comfyui_copilot/ui/src/components/chat/SelectedNodeInfo.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// Copyright (C) 2025 AIDC-AI
// Licensed under the MIT License.
@@ -2,7 +2,7 @@
* @Author: 晴知 qingli.hql@alibaba-inc.com
* @Date: 2024-12-26 17:16:51
* @LastEditors: 晴知 qingli.hql@alibaba-inc.com
* @LastEditTime: 2025-02-13 21:02:17
* @LastEditTime: 2025-02-21 13:14:49
* @FilePath: /comfyui_copilot/ui/src/components/chat/messages/NodeInstallGuide.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@@ -2,16 +2,47 @@
// Licensed under the MIT License.
import { BaseMessage } from './BaseMessage';
import { InformationCircleIcon } from '@heroicons/react/24/outline';
import { useState } from 'react';
interface UserMessageProps {
content: string;
trace_id?: string;
}
export function UserMessage({ content }: UserMessageProps) {
export function UserMessage({ content, trace_id }: UserMessageProps) {
const [showTooltip, setShowTooltip] = useState(false);
const [copied, setCopied] = useState(false);
const handleCopyTraceId = async () => {
if (trace_id) {
await navigator.clipboard.writeText(trace_id);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}
};
return (
<BaseMessage name="User" isUser={true}>
<div className="w-full rounded-lg border border-gray-700 p-4 text-gray-700 text-sm break-words">
<div className="w-full rounded-lg border border-gray-700 p-4 text-gray-700 text-sm break-words relative">
<p className="whitespace-pre-wrap">{content}</p>
{trace_id && (
<div
className="absolute bottom-1.5 right-1.5 cursor-pointer opacity-40 hover:opacity-100 transition-opacity"
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
onClick={handleCopyTraceId}
>
<InformationCircleIcon className="h-3.5 w-3.5 text-gray-500 hover:text-gray-700" />
{/* Tooltip */}
{showTooltip && (
<div className="absolute right-0 -top-6 bg-gray-700 text-white text-[10px] py-0.5 px-1.5 rounded shadow-sm whitespace-nowrap">
{copied ? 'Copied!' : `Copy trace ID`}
</div>
)}
</div>
)}
</div>
</BaseMessage>
);
@@ -0,0 +1,17 @@
export const markdownComponents = {
p: ({ children }) => {
return <p className="!my-0.5 leading-relaxed text-xs">{children}</p>
},
h1: ({ children }) => {
return <h1 className="text-base font-semibold !my-1">{children}</h1>
},
// ... 其他组件配置
};
export const markdownPlugins = {
rehypePlugins: [
[rehypeExternalLinks, { target: '_blank' }],
rehypeKatex
],
remarkPlugins: [remarkGfm, remarkMath]
};
+4 -2
View File
@@ -78,12 +78,14 @@ export interface ChatResponse {
export interface Message {
id: string;
role: string;
content: string;
role: 'user' | 'ai' | 'tool';
name?: string;
type?: string;
format?: string;
finished?: boolean;
type?: string;
metadata?: any;
trace_id?: string;
}
export interface ToolCall {
+17 -3
View File
@@ -33,7 +33,7 @@ export default function WorkflowChat({ onClose, visible = true, triggerUsage = f
const [width, setWidth] = useState(window.innerWidth / 3);
const [isResizing, setIsResizing] = useState(false);
const [uploadedImages, setUploadedImages] = useState<UploadedImage[]>([]);
const [selectedModel, setSelectedModel] = useState<string>("gpt-4o");
const [selectedModel, setSelectedModel] = useState<string>("gpt-4o-mini");
useEffect(() => {
if (messageDivRef.current) {
@@ -114,11 +114,14 @@ export default function WorkflowChat({ onClose, visible = true, triggerUsage = f
if ((input.trim() === "" && !selectedNodeInfo) || !sessionId) return;
setLoading(true);
setLatestInput(input);
const traceId = generateUUID(); // Generate trace_id for this request
const userMessage: Message = {
id: generateUUID(),
role: "user",
content: input,
trace_id: traceId, // Add trace_id to user message
};
setMessages(prev => [...prev, userMessage]);
@@ -133,7 +136,8 @@ export default function WorkflowChat({ onClose, visible = true, triggerUsage = f
input,
uploadedImages.map(img => img.file),
null, // intent
modelExt // ext
modelExt, // ext
traceId // Pass trace_id to API call
)) {
const aiMessage: Message = {
id: generateUUID(),
@@ -195,16 +199,26 @@ export default function WorkflowChat({ onClose, visible = true, triggerUsage = f
if (!sessionId || !selectedNodeInfo) return;
setLoading(true);
const traceId = generateUUID(); // Generate trace_id for this request
const userMessage: Message = {
id: generateUUID(),
role: "user",
content: selectedNodeInfo.comfyClass || selectedNodeInfo.type,
trace_id: traceId, // Add trace_id to user message
};
setMessages(prev => [...prev, userMessage]);
try {
for await (const response of WorkflowChatAPI.streamInvokeServer(sessionId, selectedNodeInfo.comfyClass || selectedNodeInfo.type, [], intent, ext)) {
for await (const response of WorkflowChatAPI.streamInvokeServer(
sessionId,
selectedNodeInfo.comfyClass || selectedNodeInfo.type,
[],
intent,
ext,
traceId // Pass trace_id to API call
)) {
const aiMessage: Message = {
id: generateUUID(),
role: "ai",
+43
View File
@@ -1,6 +1,15 @@
/*
* @Author: 晴知 qingli.hql@alibaba-inc.com
* @Date: 2024-12-10 22:11:57
* @LastEditors: 晴知 qingli.hql@alibaba-inc.com
* @LastEditTime: 2025-02-21 11:50:22
* @FilePath: /comfyui_copilot/ui/vite.config.ts
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { exec } from 'child_process';
import path from 'path';
const rewriteImportPlugin = ({ isDev }) => {
return {
@@ -72,8 +81,42 @@ export default defineConfig(({ mode }) => ({
entryFileNames: "copilot_web/[name].js",
chunkFileNames: `copilot_web/[name]-[hash].js`,
assetFileNames: `copilot_web/assets/[name]-[hash].[ext]`,
manualChunks: {
// 只包含实际使用的 React 相关依赖
'vendor-react': ['react', 'react-dom'],
// Markdown 相关依赖
'vendor-markdown': [
'react-markdown',
'remark-gfm',
'remark-math',
'rehype-katex',
'rehype-external-links'
],
// UI 组件
'vendor-ui': [
'@heroicons/react',
'@tabler/icons-react'
],
// 消息组件
'message-components': [
'./src/components/chat/messages/AIMessage',
'./src/components/chat/messages/UserMessage',
'./src/components/chat/messages/NodeInstallGuide',
'./src/components/chat/messages/NodeSearch',
'./src/components/chat/messages/NodeRecommend',
'./src/components/chat/messages/DownstreamSubgraphs',
],
}
},
},
// Enable compression
target: 'esnext',
minify: 'esbuild',
cssMinify: true,
chunkSizeWarningLimit: 600 // 适当调整警告阈值
},
plugins: [react(), rewriteImportPlugin({ isDev: mode === "development" })],
}));