@langgraph-js/ui 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +6 -6
- package/cli.mjs +36 -36
- package/dist/assets/index-BHPbGlnP.js +192 -0
- package/dist/assets/index-Du4LMUX2.css +1 -0
- package/dist/index.html +14 -14
- package/index.html +22 -22
- package/package.json +11 -8
- package/src/chat/Chat.tsx +164 -112
- package/src/chat/FileUpload/index.ts +105 -0
- package/src/chat/chat.css +403 -361
- package/src/chat/components/FileList.css +129 -0
- package/src/chat/components/FileList.tsx +73 -0
- package/src/chat/components/HistoryList.tsx +192 -192
- package/src/chat/components/JsonEditorPopup.css +81 -0
- package/src/chat/components/JsonEditorPopup.tsx +57 -0
- package/src/chat/components/MessageAI.tsx +24 -20
- package/src/chat/components/MessageHuman.tsx +55 -15
- package/src/chat/components/MessageTool.tsx +46 -47
- package/src/chat/components/UsageMetadata.tsx +40 -34
- package/src/chat/context/ChatContext.tsx +29 -29
- package/src/chat/context/ExtraParamsContext.tsx +42 -0
- package/src/chat/store/index.ts +24 -24
- package/src/chat/tools.ts +33 -33
- package/src/chat/types.ts +16 -16
- package/src/hooks/useLocalStorage.ts +27 -27
- package/src/index.ts +1 -1
- package/src/login/Login.css +93 -93
- package/src/login/Login.tsx +92 -92
- package/test/App.tsx +9 -9
- package/test/main.tsx +5 -5
- package/test/vite-env.d.ts +1 -1
- package/tsconfig.json +21 -21
- package/tsconfig.node.json +9 -9
- package/vite.config.ts +17 -17
- package/dist/assets/index-B6G4BLix.js +0 -164
- package/dist/assets/index-BAcH-2-3.css +0 -1
package/src/login/Login.css
CHANGED
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
.login-container {
|
|
2
|
-
max-width: 600px;
|
|
3
|
-
margin: 2rem auto;
|
|
4
|
-
padding: 2rem;
|
|
5
|
-
background: #fff;
|
|
6
|
-
border-radius: 8px;
|
|
7
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.header-group {
|
|
11
|
-
display: flex;
|
|
12
|
-
gap: 1rem;
|
|
13
|
-
align-items: flex-start;
|
|
14
|
-
padding: 1rem;
|
|
15
|
-
background: #f8f9fa;
|
|
16
|
-
border-radius: 4px;
|
|
17
|
-
position: relative;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.form-group {
|
|
21
|
-
flex: 1;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.form-group label {
|
|
25
|
-
display: block;
|
|
26
|
-
margin-bottom: 0.5rem;
|
|
27
|
-
color: #333;
|
|
28
|
-
font-weight: 500;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.form-group input {
|
|
32
|
-
width: 100%;
|
|
33
|
-
padding: 0.5rem;
|
|
34
|
-
border: 1px solid #ddd;
|
|
35
|
-
border-radius: 4px;
|
|
36
|
-
font-size: 1rem;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.form-group input:focus {
|
|
40
|
-
outline: none;
|
|
41
|
-
border-color: #007bff;
|
|
42
|
-
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.button-group {
|
|
46
|
-
display: flex;
|
|
47
|
-
gap: 1rem;
|
|
48
|
-
margin-top: 1rem;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
button {
|
|
52
|
-
padding: 0.5rem 1rem;
|
|
53
|
-
border: none;
|
|
54
|
-
border-radius: 4px;
|
|
55
|
-
font-size: 1rem;
|
|
56
|
-
cursor: pointer;
|
|
57
|
-
transition: background-color 0.2s;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
button[type="submit"] {
|
|
61
|
-
background-color: #007bff;
|
|
62
|
-
color: white;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
button[type="submit"]:hover {
|
|
66
|
-
background-color: #0056b3;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
button[type="button"] {
|
|
70
|
-
background-color: #6c757d;
|
|
71
|
-
color: white;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
button[type="button"]:hover {
|
|
75
|
-
background-color: #5a6268;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.remove-header {
|
|
79
|
-
background-color: #dc3545;
|
|
80
|
-
color: white;
|
|
81
|
-
padding: 0.25rem 0.5rem;
|
|
82
|
-
font-size: 0.875rem;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.remove-header:hover {
|
|
86
|
-
background-color: #c82333;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
p {
|
|
90
|
-
margin-bottom: 1.5rem;
|
|
91
|
-
color: #666;
|
|
92
|
-
text-align: center;
|
|
93
|
-
}
|
|
1
|
+
.login-container {
|
|
2
|
+
max-width: 600px;
|
|
3
|
+
margin: 2rem auto;
|
|
4
|
+
padding: 2rem;
|
|
5
|
+
background: #fff;
|
|
6
|
+
border-radius: 8px;
|
|
7
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.header-group {
|
|
11
|
+
display: flex;
|
|
12
|
+
gap: 1rem;
|
|
13
|
+
align-items: flex-start;
|
|
14
|
+
padding: 1rem;
|
|
15
|
+
background: #f8f9fa;
|
|
16
|
+
border-radius: 4px;
|
|
17
|
+
position: relative;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.form-group {
|
|
21
|
+
flex: 1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.form-group label {
|
|
25
|
+
display: block;
|
|
26
|
+
margin-bottom: 0.5rem;
|
|
27
|
+
color: #333;
|
|
28
|
+
font-weight: 500;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.form-group input {
|
|
32
|
+
width: 100%;
|
|
33
|
+
padding: 0.5rem;
|
|
34
|
+
border: 1px solid #ddd;
|
|
35
|
+
border-radius: 4px;
|
|
36
|
+
font-size: 1rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.form-group input:focus {
|
|
40
|
+
outline: none;
|
|
41
|
+
border-color: #007bff;
|
|
42
|
+
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.button-group {
|
|
46
|
+
display: flex;
|
|
47
|
+
gap: 1rem;
|
|
48
|
+
margin-top: 1rem;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
button {
|
|
52
|
+
padding: 0.5rem 1rem;
|
|
53
|
+
border: none;
|
|
54
|
+
border-radius: 4px;
|
|
55
|
+
font-size: 1rem;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
transition: background-color 0.2s;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
button[type="submit"] {
|
|
61
|
+
background-color: #007bff;
|
|
62
|
+
color: white;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
button[type="submit"]:hover {
|
|
66
|
+
background-color: #0056b3;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
button[type="button"] {
|
|
70
|
+
background-color: #6c757d;
|
|
71
|
+
color: white;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
button[type="button"]:hover {
|
|
75
|
+
background-color: #5a6268;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.remove-header {
|
|
79
|
+
background-color: #dc3545;
|
|
80
|
+
color: white;
|
|
81
|
+
padding: 0.25rem 0.5rem;
|
|
82
|
+
font-size: 0.875rem;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.remove-header:hover {
|
|
86
|
+
background-color: #c82333;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
p {
|
|
90
|
+
margin-bottom: 1.5rem;
|
|
91
|
+
color: #666;
|
|
92
|
+
text-align: center;
|
|
93
|
+
}
|
package/src/login/Login.tsx
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import "./Login.css";
|
|
3
|
-
|
|
4
|
-
interface HeaderConfig {
|
|
5
|
-
key: string;
|
|
6
|
-
value: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const Login: React.FC = () => {
|
|
10
|
-
const [headers, setHeaders] = useState<HeaderConfig[]>([{ key: "authorization", value: "" }]);
|
|
11
|
-
const [withCredentials, setWithCredentials] = useState<boolean>(localStorage.getItem("withCredentials") === "true");
|
|
12
|
-
const [apiUrl, setApiUrl] = useState<string>(localStorage.getItem("apiUrl") || "");
|
|
13
|
-
|
|
14
|
-
const addHeader = () => {
|
|
15
|
-
setHeaders([...headers, { key: "", value: "" }]);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const removeHeader = (index: number) => {
|
|
19
|
-
setHeaders(headers.filter((_, i) => i !== index));
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const updateHeader = (index: number, field: "key" | "value", value: string) => {
|
|
23
|
-
const newHeaders = [...headers];
|
|
24
|
-
newHeaders[index][field] = value;
|
|
25
|
-
setHeaders(newHeaders);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const handleLogin = () => {
|
|
29
|
-
const headerObject = Object.fromEntries(headers.map((k) => [k.key, k.value]));
|
|
30
|
-
|
|
31
|
-
localStorage.setItem("code", JSON.stringify(headerObject));
|
|
32
|
-
localStorage.setItem("withCredentials", JSON.stringify(withCredentials));
|
|
33
|
-
localStorage.setItem("apiUrl", apiUrl);
|
|
34
|
-
location.reload();
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div className="login-container">
|
|
39
|
-
<form
|
|
40
|
-
onSubmit={(e) => {
|
|
41
|
-
e.preventDefault();
|
|
42
|
-
handleLogin();
|
|
43
|
-
}}
|
|
44
|
-
>
|
|
45
|
-
<h2>LangGraph UI</h2>
|
|
46
|
-
<p>登录,自定义请求头配置</p>
|
|
47
|
-
|
|
48
|
-
<div className="form-group api-url-group">
|
|
49
|
-
<label htmlFor="api-url">API URL</label>
|
|
50
|
-
<input type="text" id="api-url" value={apiUrl} onChange={(e) => setApiUrl(e.target.value)} placeholder="例如: http://localhost:8123" />
|
|
51
|
-
</div>
|
|
52
|
-
|
|
53
|
-
{headers.map((header, index) => (
|
|
54
|
-
<div key={index} className="header-group">
|
|
55
|
-
<div className="form-group">
|
|
56
|
-
<input type="text" id={`header-key-${index}`} value={header.key} onChange={(e) => updateHeader(index, "key", e.target.value)} placeholder="例如: authorization" required />
|
|
57
|
-
</div>
|
|
58
|
-
<div className="form-group">
|
|
59
|
-
<input
|
|
60
|
-
type="text"
|
|
61
|
-
id={`header-value-${index}`}
|
|
62
|
-
value={header.value}
|
|
63
|
-
onChange={(e) => updateHeader(index, "value", e.target.value)}
|
|
64
|
-
placeholder="例如: Bearer token;无则填 1"
|
|
65
|
-
required
|
|
66
|
-
/>
|
|
67
|
-
</div>
|
|
68
|
-
{index > 0 && (
|
|
69
|
-
<button type="button" className="remove-header" onClick={() => removeHeader(index)}>
|
|
70
|
-
删除
|
|
71
|
-
</button>
|
|
72
|
-
)}
|
|
73
|
-
</div>
|
|
74
|
-
))}
|
|
75
|
-
<div className="with-credentials-option">
|
|
76
|
-
<label>
|
|
77
|
-
<input type="checkbox" checked={withCredentials} onChange={(e) => setWithCredentials(e.target.checked)} />
|
|
78
|
-
启用 withCredentials(跨域请求时发送 Cookie)
|
|
79
|
-
</label>
|
|
80
|
-
</div>
|
|
81
|
-
<div className="button-group">
|
|
82
|
-
<button type="button" onClick={addHeader}>
|
|
83
|
-
添加请求头
|
|
84
|
-
</button>
|
|
85
|
-
<button type="submit">保存配置</button>
|
|
86
|
-
</div>
|
|
87
|
-
</form>
|
|
88
|
-
</div>
|
|
89
|
-
);
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export default Login;
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import "./Login.css";
|
|
3
|
+
|
|
4
|
+
interface HeaderConfig {
|
|
5
|
+
key: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const Login: React.FC = () => {
|
|
10
|
+
const [headers, setHeaders] = useState<HeaderConfig[]>([{ key: "authorization", value: "" }]);
|
|
11
|
+
const [withCredentials, setWithCredentials] = useState<boolean>(localStorage.getItem("withCredentials") === "true");
|
|
12
|
+
const [apiUrl, setApiUrl] = useState<string>(localStorage.getItem("apiUrl") || "");
|
|
13
|
+
|
|
14
|
+
const addHeader = () => {
|
|
15
|
+
setHeaders([...headers, { key: "", value: "" }]);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const removeHeader = (index: number) => {
|
|
19
|
+
setHeaders(headers.filter((_, i) => i !== index));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const updateHeader = (index: number, field: "key" | "value", value: string) => {
|
|
23
|
+
const newHeaders = [...headers];
|
|
24
|
+
newHeaders[index][field] = value;
|
|
25
|
+
setHeaders(newHeaders);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const handleLogin = () => {
|
|
29
|
+
const headerObject = Object.fromEntries(headers.map((k) => [k.key, k.value]));
|
|
30
|
+
|
|
31
|
+
localStorage.setItem("code", JSON.stringify(headerObject));
|
|
32
|
+
localStorage.setItem("withCredentials", JSON.stringify(withCredentials));
|
|
33
|
+
localStorage.setItem("apiUrl", apiUrl);
|
|
34
|
+
location.reload();
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className="login-container">
|
|
39
|
+
<form
|
|
40
|
+
onSubmit={(e) => {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
handleLogin();
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
<h2>LangGraph UI</h2>
|
|
46
|
+
<p>登录,自定义请求头配置</p>
|
|
47
|
+
|
|
48
|
+
<div className="form-group api-url-group">
|
|
49
|
+
<label htmlFor="api-url">API URL</label>
|
|
50
|
+
<input type="text" id="api-url" value={apiUrl} onChange={(e) => setApiUrl(e.target.value)} placeholder="例如: http://localhost:8123" />
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
{headers.map((header, index) => (
|
|
54
|
+
<div key={index} className="header-group">
|
|
55
|
+
<div className="form-group">
|
|
56
|
+
<input type="text" id={`header-key-${index}`} value={header.key} onChange={(e) => updateHeader(index, "key", e.target.value)} placeholder="例如: authorization" required />
|
|
57
|
+
</div>
|
|
58
|
+
<div className="form-group">
|
|
59
|
+
<input
|
|
60
|
+
type="text"
|
|
61
|
+
id={`header-value-${index}`}
|
|
62
|
+
value={header.value}
|
|
63
|
+
onChange={(e) => updateHeader(index, "value", e.target.value)}
|
|
64
|
+
placeholder="例如: Bearer token;无则填 1"
|
|
65
|
+
required
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
{index > 0 && (
|
|
69
|
+
<button type="button" className="remove-header" onClick={() => removeHeader(index)}>
|
|
70
|
+
删除
|
|
71
|
+
</button>
|
|
72
|
+
)}
|
|
73
|
+
</div>
|
|
74
|
+
))}
|
|
75
|
+
<div className="with-credentials-option">
|
|
76
|
+
<label>
|
|
77
|
+
<input type="checkbox" checked={withCredentials} onChange={(e) => setWithCredentials(e.target.checked)} />
|
|
78
|
+
启用 withCredentials(跨域请求时发送 Cookie)
|
|
79
|
+
</label>
|
|
80
|
+
</div>
|
|
81
|
+
<div className="button-group">
|
|
82
|
+
<button type="button" onClick={addHeader}>
|
|
83
|
+
添加请求头
|
|
84
|
+
</button>
|
|
85
|
+
<button type="submit">保存配置</button>
|
|
86
|
+
</div>
|
|
87
|
+
</form>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default Login;
|
package/test/App.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import Chat from "../src/chat/Chat";
|
|
2
|
-
import Login from "../src/login/Login";
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
function App() {
|
|
5
|
-
const [isLogin, setIsLogin] = useState(localStorage.getItem("code"));
|
|
6
|
-
return <>{isLogin ? <Chat /> : <Login></Login>}</>;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export default App;
|
|
1
|
+
import Chat from "../src/chat/Chat";
|
|
2
|
+
import Login from "../src/login/Login";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
function App() {
|
|
5
|
+
const [isLogin, setIsLogin] = useState(localStorage.getItem("code"));
|
|
6
|
+
return <>{isLogin ? <Chat /> : <Login></Login>}</>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default App;
|
package/test/main.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import ReactDOM from "react-dom/client";
|
|
3
|
-
import App from "./App";
|
|
4
|
-
|
|
5
|
-
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import App from "./App";
|
|
4
|
+
|
|
5
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
|
package/test/vite-env.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
|
1
|
+
/// <reference types="vite/client" />
|
package/tsconfig.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
6
|
-
"allowJs": false,
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
"esModuleInterop": false,
|
|
9
|
-
"allowSyntheticDefaultImports": true,
|
|
10
|
-
"strict": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"module": "ESNext",
|
|
13
|
-
"moduleResolution": "Node",
|
|
14
|
-
"resolveJsonModule": true,
|
|
15
|
-
"isolatedModules": true,
|
|
16
|
-
"noEmit": true,
|
|
17
|
-
"jsx": "react-jsx"
|
|
18
|
-
},
|
|
19
|
-
"include": ["test", "test/**/*.tsx"],
|
|
20
|
-
"references": [{ "path": "./tsconfig.node.json" }]
|
|
21
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
6
|
+
"allowJs": false,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"esModuleInterop": false,
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"module": "ESNext",
|
|
13
|
+
"moduleResolution": "Node",
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"jsx": "react-jsx"
|
|
18
|
+
},
|
|
19
|
+
"include": ["test", "test/**/*.tsx"],
|
|
20
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
21
|
+
}
|
package/tsconfig.node.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"composite": true,
|
|
4
|
-
"module": "esnext",
|
|
5
|
-
"moduleResolution": "node",
|
|
6
|
-
"allowSyntheticDefaultImports": true
|
|
7
|
-
},
|
|
8
|
-
"include": ["vite.config.ts"]
|
|
9
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"composite": true,
|
|
4
|
+
"module": "esnext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"allowSyntheticDefaultImports": true
|
|
7
|
+
},
|
|
8
|
+
"include": ["vite.config.ts"]
|
|
9
|
+
}
|
package/vite.config.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import react from "@vitejs/plugin-react";
|
|
2
|
-
import { defineConfig } from "vite";
|
|
3
|
-
import basicSsl from "@vitejs/plugin-basic-ssl";
|
|
4
|
-
|
|
5
|
-
// https://vitejs.dev/config/
|
|
6
|
-
export default defineConfig(({ mode }) => {
|
|
7
|
-
const isHttps = mode === "https";
|
|
8
|
-
return {
|
|
9
|
-
plugins: [react(), isHttps ? basicSsl() : undefined],
|
|
10
|
-
optimizeDeps: {
|
|
11
|
-
exclude: ["@langgraph-js/ui", "@langgraph-js/sdk"],
|
|
12
|
-
},
|
|
13
|
-
server: {
|
|
14
|
-
port: 1111,
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
});
|
|
1
|
+
import react from "@vitejs/plugin-react";
|
|
2
|
+
import { defineConfig } from "vite";
|
|
3
|
+
import basicSsl from "@vitejs/plugin-basic-ssl";
|
|
4
|
+
|
|
5
|
+
// https://vitejs.dev/config/
|
|
6
|
+
export default defineConfig(({ mode }) => {
|
|
7
|
+
const isHttps = mode === "https";
|
|
8
|
+
return {
|
|
9
|
+
plugins: [react(), isHttps ? basicSsl() : undefined],
|
|
10
|
+
optimizeDeps: {
|
|
11
|
+
exclude: ["@langgraph-js/ui", "@langgraph-js/sdk"],
|
|
12
|
+
},
|
|
13
|
+
server: {
|
|
14
|
+
port: 1111,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
});
|