From ba8844e798c0453021e9f7b1f816f8f76270f3f6 Mon Sep 17 00:00:00 2001
From: "changhuiping.chp" <392752049@qq.com>
Date: Wed, 19 Jul 2023 18:14:16 +0800
Subject: [PATCH 1/7] fix: update code from db-gpt
---
app/agents/layout.tsx | 13 -
app/agents/page.tsx | 214 -----------
app/chat/page.tsx | 216 ++++++++++-
app/datastores/documents/page.tsx | 588 +++++++++++++++---------------
app/datastores/page.tsx | 1 -
hooks/useAgentChat.ts | 304 ++++++++-------
6 files changed, 650 insertions(+), 686 deletions(-)
delete mode 100644 app/agents/layout.tsx
delete mode 100644 app/agents/page.tsx
diff --git a/app/agents/layout.tsx b/app/agents/layout.tsx
deleted file mode 100644
index 8c94ab3..0000000
--- a/app/agents/layout.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Box } from '@/lib/mui';
-
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode
-}) {
- return (
- <>
- {children}
- >
- )
-}
diff --git a/app/agents/page.tsx b/app/agents/page.tsx
deleted file mode 100644
index 3dcd846..0000000
--- a/app/agents/page.tsx
+++ /dev/null
@@ -1,214 +0,0 @@
-"use client"
-import ChatBoxComp from '@/components/chatBox';
-import { Chart, LineAdvance, Interval, Tooltip, getTheme } from 'bizcharts';
-import { Card, CardContent, Typography, Grid, styled, Sheet } from '@/lib/mui';
-import { Stack } from '@mui/material';
-import useAgentChat from '@/hooks/useAgentChat';
-
-
-const Item = styled(Sheet)(({ theme }) => ({
- ...theme.typography.body2,
- padding: theme.spacing(1),
- textAlign: 'center',
- borderRadius: 4,
- color: theme.vars.palette.text.secondary,
-}));
-
-const Agents = () => {
- const { handleChatSubmit, history } = useAgentChat({
- queryAgentURL: `/v1/chat/completions`,
- });
-
- const data = [
- {
- month: "Jan",
- city: "Tokyo",
- temperature: 7
- },
- {
- month: "Feb",
- city: "Tokyo",
- temperature: 13
- },
- {
- month: "Mar",
- city: "Tokyo",
- temperature: 16.5
- },
- {
- month: "Apr",
- city: "Tokyo",
- temperature: 14.5
- },
- {
- month: "May",
- city: "Tokyo",
- temperature: 10
- },
- {
- month: "Jun",
- city: "Tokyo",
- temperature: 7.5
- },
- {
- month: "Jul",
- city: "Tokyo",
- temperature: 9.2
- },
- {
- month: "Aug",
- city: "Tokyo",
- temperature: 14.5
- },
- {
- month: "Sep",
- city: "Tokyo",
- temperature: 9.3
- },
- {
- month: "Oct",
- city: "Tokyo",
- temperature: 8.3
- },
- {
- month: "Nov",
- city: "Tokyo",
- temperature: 8.9
- },
- {
- month: "Dec",
- city: "Tokyo",
- temperature: 5.6
- },
- ];
-
- const d1 = [
- { year: '1951 年', sales: 0 },
- { year: '1952 年', sales: 52 },
- { year: '1956 年', sales: 61 },
- { year: '1957 年', sales: 45 },
- { year: '1958 年', sales: 48 },
- { year: '1959 年', sales: 38 },
- { year: '1960 年', sales: 38 },
- { year: '1962 年', sales: 38 },
- ];
-
- const topCard = [{
- label: 'Revenue Won',
- value: '$7,811,851'
- }, {
- label: 'Close %',
- value: '37.7%'
- }, {
- label: 'AVG Days to Close',
- value: '121'
- }, {
- label: 'Opportunities Won',
- value: '526'
- }];
-
- return (
-
-
-
-
-
- -
-
- {topCard.map((item) => (
-
-
-
-
- {item.label}
-
-
- {item.value}
-
-
-
-
- ))}
-
-
- -
-
-
-
- Revenue Won by Month
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- Close % by Month
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Close % by Month
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Close % by Month
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
-
-export default Agents;
\ No newline at end of file
diff --git a/app/chat/page.tsx b/app/chat/page.tsx
index 529b56e..4141230 100644
--- a/app/chat/page.tsx
+++ b/app/chat/page.tsx
@@ -1,10 +1,14 @@
"use client"
import { useRequest } from 'ahooks';
import { sendGetRequest, sendPostRequest } from '@/utils/request';
+import { Card, CardContent, Typography, Grid, Table } from "@/lib/mui";
import useAgentChat from '@/hooks/useAgentChat';
import ChatBoxComp from '@/components/chatBoxTemp';
import { useDialogueContext } from '@/app/context/dialogue';
import { useSearchParams } from 'next/navigation';
+import { useMemo } from 'react';
+import { Chart, LineAdvance, Interval, Tooltip, getTheme } from "bizcharts";
+import lodash from 'lodash';
const AgentPage = () => {
const searchParams = useSearchParams();
@@ -33,17 +37,209 @@ const AgentPage = () => {
initHistory: historyList?.data
});
+ const chartsData = useMemo(() => {
+ try {
+ const contextTemp = history?.[history.length - 1]?.context;
+ const contextObj = JSON.parse(contextTemp);
+ return contextObj?.template_name === 'sales_report' ? contextObj?.charts : undefined;
+ } catch (e) {
+ return undefined;
+ }
+ }, [history]);
+
+ const chartRows = useMemo(() => {
+ if (chartsData) {
+ let res = [];
+ // 若是有类型为 IndicatorValue 的,提出去,独占一行
+ const chartCalc = chartsData?.filter(
+ (item) => item.chart_type === "IndicatorValue"
+ );
+ if (chartCalc.length > 0) {
+ res.push({
+ rowIndex: res.length,
+ cols: chartCalc,
+ type: "IndicatorValue",
+ });
+ }
+ let otherCharts = chartsData?.filter(
+ (item) => item.chart_type !== "IndicatorValue"
+ );
+ let otherLength = otherCharts.length;
+ let curIndex = 0;
+ // charts 数量 3~8个,暂定每行排序
+ let chartLengthMap = [
+ [0],
+ [1],
+ [2],
+ [1, 2],
+ [1, 3],
+ [2, 1, 2],
+ [2, 1, 3],
+ [3, 1, 3],
+ [3, 2, 3],
+ ];
+ let currentRowsSort = chartLengthMap[otherLength];
+ currentRowsSort.forEach((item) => {
+ if (item > 0) {
+ const rowsItem = otherCharts.slice(curIndex, curIndex + item);
+ curIndex = curIndex + item;
+ res.push({
+ rowIndex: res.length,
+ cols: rowsItem,
+ });
+ }
+ });
+ return res;
+ }
+ return undefined;
+ }, [chartsData]);
+
return (
- <>
- {
- await refreshDialogList();
- }}
- messages={history || []}
- onSubmit={handleChatSubmit}
- paramsList={paramsList?.data}
- />
- >
+
+ {chartsData && (
+
+
+ {chartRows?.map((chartRow) => (
+
+ {chartRow.cols.map((col) => {
+ if (col.chart_type === "IndicatorValue") {
+ return (
+
+ {col.values.map((item) => (
+
+
+
+
+ {item.name}
+
+ {item.value}
+
+
+
+ ))}
+
+ );
+ } else if (col.chart_type === "LineChart") {
+ return (
+
+
+
+
+ {col.chart_name}
+
+
+
+
+
+
+
+
+
+ );
+ } else if (col.chart_type === "BarChart") {
+ return (
+
+
+
+
+ {col.chart_name}
+
+
+
+
+
+
+
+
+
+
+ );
+ } else if (col.chart_type === 'Table') {
+ const data = lodash.groupBy(col.values, 'type');
+ return (
+
+
+
+
+
+ {col.chart_name}
+
+
+
+
+
+ {Object.keys(data).map(key => (
+ {key} |
+ ))}
+
+
+
+ {Object.values(data)?.[0]?.map((value, i) => (
+
+ {Object.keys(data)?.map(k => (
+ {data?.[k]?.[i].value || ''} |
+ ))}
+
+ ))}
+
+
+
+
+
+
+ )
+ }
+ })}
+
+ ))}
+
+
+ )}
+
+
+ {
+ await refreshDialogList();
+ }}
+ messages={history || []}
+ onSubmit={handleChatSubmit}
+ paramsList={paramsList?.data}
+ />
+
+
+
+
)
}
diff --git a/app/datastores/documents/page.tsx b/app/datastores/documents/page.tsx
index 3749145..acf10be 100644
--- a/app/datastores/documents/page.tsx
+++ b/app/datastores/documents/page.tsx
@@ -1,38 +1,34 @@
'use client'
-import { useRouter, useSearchParams } from 'next/navigation'
+import { useRouter } from 'next/navigation'
import React, { useState, useEffect } from 'react'
+import { InboxOutlined } from '@ant-design/icons'
+import CheckCircleOutlinedIcon from '@mui/icons-material/CheckCircleOutlined'
+import ContentPasteSearchOutlinedIcon from '@mui/icons-material/ContentPasteSearchOutlined'
+import type { UploadProps } from 'antd'
+import { message, Upload } from 'antd'
import {
useColorScheme,
+ Modal,
Button,
- Table,
Sheet,
- Modal,
- Box,
Stack,
+ Box,
Input,
Textarea,
- Chip,
Switch,
Typography,
- Breadcrumbs,
- Link,
styled
} from '@/lib/mui'
-import moment from 'moment'
-import { InboxOutlined } from '@ant-design/icons'
-import CheckCircleOutlinedIcon from '@mui/icons-material/CheckCircleOutlined'
-import CachedIcon from '@mui/icons-material/Cached'
-import type { UploadProps } from 'antd'
-import { Upload, Pagination, Popover, message } from 'antd'
import {
sendSpacePostRequest,
sendSpaceUploadPostRequest
} from '@/utils/request'
const { Dragger } = Upload
+
const Item = styled(Sheet)(({ theme }) => ({
- width: '50%',
+ width: '33%',
backgroundColor:
theme.palette.mode === 'dark' ? theme.palette.background.level1 : '#fff',
...theme.typography.body2,
@@ -41,7 +37,9 @@ const Item = styled(Sheet)(({ theme }) => ({
borderRadius: 4,
color: theme.vars.palette.text.secondary
}))
-const stepsOfAddingDocument = [
+
+const stepsOfAddingSpace = [
+ 'Knowledge Space Config',
'Choose a Datasource type',
'Setup the Datasource'
]
@@ -63,24 +61,22 @@ const documentTypeList = [
'Upload a document, document type can be PDF, CSV, Text, PowerPoint, Word, Markdown'
}
]
-const page_size = 20
-const Documents = () => {
+const Index = () => {
const router = useRouter()
- const spaceName = useSearchParams().get('name')
- const { mode } = useColorScheme()
- const [isAddDocumentModalShow, setIsAddDocumentModalShow] =
- useState(false)
const [activeStep, setActiveStep] = useState(0)
const [documentType, setDocumentType] = useState('')
- const [documents, setDocuments] = useState([])
+ const [knowledgeSpaceList, setKnowledgeSpaceList] = useState([])
+ const [isAddKnowledgeSpaceModalShow, setIsAddKnowledgeSpaceModalShow] =
+ useState(false)
+ const [knowledgeSpaceName, setKnowledgeSpaceName] = useState('')
+ const [owner, setOwner] = useState('')
+ const [description, setDescription] = useState('')
const [webPageUrl, setWebPageUrl] = useState('')
const [documentName, setDocumentName] = useState('')
const [textSource, setTextSource] = useState('')
const [text, setText] = useState('')
const [originFileObj, setOriginFileObj] = useState(null)
- const [total, setTotal] = useState(0)
- const [current, setCurrent] = useState(0)
const [synchChecked, setSynchChecked] = useState(true)
const props: UploadProps = {
name: 'file',
@@ -97,217 +93,193 @@ const Documents = () => {
}
}
useEffect(() => {
- async function fetchDocuments() {
- const data = await sendSpacePostRequest(
- `/knowledge/${spaceName}/document/list`,
- {
- page: 1,
- page_size
- }
- )
+ async function fetchData() {
+ const data = await sendSpacePostRequest('/knowledge/space/list', {})
if (data.success) {
- setDocuments(data.data.data)
- setTotal(data.data.total)
- setCurrent(data.data.page)
+ setKnowledgeSpaceList(data.data)
}
}
- fetchDocuments()
+ fetchData()
}, [])
return (
-
-
+
-
- {
- router.push('/datastores')
- }}
- key="Knowledge Space"
- underline="hover"
- color="neutral"
- fontSize="inherit"
- >
- Knowledge Space
-
- Documents
-
-
-
- {documents.length ? (
- <>
-
setIsAddKnowledgeSpaceModalShow(true)}
+ className="bg-[#E9EBEE] dark:bg-[#484848]"
>
-
-
- Name |
- Type |
- Size |
- Last Synch |
- Status |
- Result |
- Operation |
-
-
-
- {documents.map((row: any) => (
-
- {row.doc_name} |
-
-
- {row.doc_type}
-
- |
- {row.chunk_size} chunks |
- {moment(row.last_sync).format('YYYY-MM-DD HH:MM:SS')} |
-
-
- {row.status}
-
- |
-
- {(function () {
- if (row.status === 'TODO' || row.status === 'RUNNING') {
- return ''
- } else if (row.status === 'FINISHED') {
- return (
-
-
- SUCCESS
-
-
- )
- } else {
- return (
-
-
- FAILED
-
-
- )
- }
- })()}
- |
-
- {
- <>
-
-
- >
- }
- |
-
- ))}
-
-
-
- {
- const data = await sendSpacePostRequest(
- `/knowledge/${spaceName}/document/list`,
- {
- page,
- page_size
- }
- )
- if (data.success) {
- setDocuments(data.data.data)
- setTotal(data.data.total)
- setCurrent(data.data.page)
+
+ +
+
+
+ space
+
+
+ {knowledgeSpaceList.map((item: any, index: number) => (
+
-
- >
- ) : (
- <>>
- )}
+ onClick={() => {
+ router.push(`/datastores/documents?name=${item.name}`)
+ }}
+ className="bg-[#FFFFFF] dark:bg-[#484848]"
+ >
+
+
+ {item.name}
+
+
+
+
+ {item.vector_type}
+
+ Vector
+
+
+
+ {item.owner}
+
+ Owner
+
+
+
+ {item.docs || 0}
+
+ Docs
+
+
+
+ ))}
+
+
+
+
+
+
+
{
alignItems: 'center',
'z-index': 1000
}}
- open={isAddDocumentModalShow}
- onClose={() => setIsAddDocumentModalShow(false)}
+ open={isAddKnowledgeSpaceModalShow}
+ onClose={() => setIsAddKnowledgeSpaceModalShow(false)}
>
{
>
- {stepsOfAddingDocument.map((item: any, index: number) => (
+ {stepsOfAddingSpace.map((item: any, index: number) => (
- {
{activeStep === 0 ? (
+ <>
+
+ Knowledge Space Name:
+ setKnowledgeSpaceName(e.target.value)}
+ sx={{ marginBottom: '20px' }}
+ />
+ Owner:
+ setOwner(e.target.value)}
+ sx={{ marginBottom: '20px' }}
+ />
+ Description:
+ setDescription(e.target.value)}
+ sx={{ marginBottom: '20px' }}
+ />
+
+
+ >
+ ) : activeStep === 1 ? (
<>
{documentTypeList.map((item: any) => (
@@ -367,7 +403,7 @@ const Documents = () => {
}}
onClick={() => {
setDocumentType(item.type)
- setActiveStep(1)
+ setActiveStep(2)
}}
>
@@ -456,7 +492,7 @@ const Documents = () => {
@@ -473,36 +509,23 @@ const Documents = () => {
return
}
const data = await sendSpacePostRequest(
- `/knowledge/${spaceName}/document/add`,
+ `/knowledge/${knowledgeSpaceName}/document/add`,
{
doc_name: documentName,
content: webPageUrl,
doc_type: 'URL'
}
)
- data.success &&
- synchChecked &&
- sendSpacePostRequest(
- `/knowledge/${spaceName}/document/sync`,
- {
- doc_ids: [data.data]
- }
- )
if (data.success) {
message.success('success')
- setIsAddDocumentModalShow(false)
- const data = await sendSpacePostRequest(
- `/knowledge/${spaceName}/document/list`,
- {
- page: current,
- page_size
- }
- )
- if (data.success) {
- setDocuments(data.data.data)
- setTotal(data.data.total)
- setCurrent(data.data.page)
- }
+ setIsAddKnowledgeSpaceModalShow(false)
+ synchChecked &&
+ sendSpacePostRequest(
+ `/knowledge/${knowledgeSpaceName}/document/sync`,
+ {
+ doc_ids: [data.data]
+ }
+ )
} else {
message.error(data.err_msg || 'failed')
}
@@ -515,33 +538,21 @@ const Documents = () => {
formData.append('doc_name', documentName)
formData.append('doc_file', originFileObj)
formData.append('doc_type', 'DOCUMENT')
+
const data = await sendSpaceUploadPostRequest(
- `/knowledge/${spaceName}/document/upload`,
+ `/knowledge/${knowledgeSpaceName}/document/upload`,
formData
)
- data.success &&
- synchChecked &&
- sendSpacePostRequest(
- `/knowledge/${spaceName}/document/sync`,
- {
- doc_ids: [data.data]
- }
- )
if (data.success) {
message.success('success')
- setIsAddDocumentModalShow(false)
- const data = await sendSpacePostRequest(
- `/knowledge/${spaceName}/document/list`,
- {
- page: current,
- page_size
- }
- )
- if (data.success) {
- setDocuments(data.data.data)
- setTotal(data.data.total)
- setCurrent(data.data.page)
- }
+ setIsAddKnowledgeSpaceModalShow(false)
+ synchChecked &&
+ sendSpacePostRequest(
+ `/knowledge/${knowledgeSpaceName}/document/sync`,
+ {
+ doc_ids: [data.data]
+ }
+ )
} else {
message.error(data.err_msg || 'failed')
}
@@ -551,7 +562,7 @@ const Documents = () => {
return
}
const data = await sendSpacePostRequest(
- `/knowledge/${spaceName}/document/add`,
+ `/knowledge/${knowledgeSpaceName}/document/add`,
{
doc_name: documentName,
source: textSource,
@@ -559,29 +570,16 @@ const Documents = () => {
doc_type: 'TEXT'
}
)
- data.success &&
- synchChecked &&
- sendSpacePostRequest(
- `/knowledge/${spaceName}/document/sync`,
- {
- doc_ids: [data.data]
- }
- )
if (data.success) {
message.success('success')
- setIsAddDocumentModalShow(false)
- const data = await sendSpacePostRequest(
- `/knowledge/${spaceName}/document/list`,
- {
- page: current,
- page_size
- }
- )
- if (data.success) {
- setDocuments(data.data.data)
- setTotal(data.data.total)
- setCurrent(data.data.page)
- }
+ setIsAddKnowledgeSpaceModalShow(false)
+ synchChecked &&
+ sendSpacePostRequest(
+ `/knowledge/${knowledgeSpaceName}/document/sync`,
+ {
+ doc_ids: [data.data]
+ }
+ )
} else {
message.error(data.err_msg || 'failed')
}
@@ -595,8 +593,8 @@ const Documents = () => {
)}
-
+
)
}
-export default Documents
+export default Index
diff --git a/app/datastores/page.tsx b/app/datastores/page.tsx
index 3abf025..acf10be 100644
--- a/app/datastores/page.tsx
+++ b/app/datastores/page.tsx
@@ -64,7 +64,6 @@ const documentTypeList = [
const Index = () => {
const router = useRouter()
- const { mode } = useColorScheme()
const [activeStep, setActiveStep] = useState(0)
const [documentType, setDocumentType] = useState('')
const [knowledgeSpaceList, setKnowledgeSpaceList] = useState([])
diff --git a/hooks/useAgentChat.ts b/hooks/useAgentChat.ts
index f14f72b..c45d4fe 100644
--- a/hooks/useAgentChat.ts
+++ b/hooks/useAgentChat.ts
@@ -1,170 +1,168 @@
import {
- EventStreamContentType,
- fetchEventSource,
- } from '@microsoft/fetch-event-source';
- import useStateReducer from './useStateReducer';
+ EventStreamContentType,
+ fetchEventSource,
+} from '@microsoft/fetch-event-source';
+import useStateReducer from './useStateReducer';
import { Message } from '@/types';
import { useEffect } from 'react';
import { useDialogueContext } from '@/app/context/dialogue';
- type Props = {
- queryAgentURL: string;
- channel?: "dashboard" | "website" | "slack" | "crisp";
- queryBody?: any;
- initHistory?: Message[];
- };
+type Props = {
+ queryAgentURL: string;
+ channel?: "dashboard" | "website" | "slack" | "crisp";
+ queryBody?: any;
+ initHistory?: Message[];
+};
+
+const useAgentChat = ({
+ queryAgentURL,
+ channel,
+ queryBody,
+ initHistory
+}: Props) => {
+ const [state, setState] = useStateReducer({
+ history: (initHistory || []) as { role: 'human' | 'view'; context: string; id?: string }[],
+ });
+
+ const { refreshDialogList } = useDialogueContext();
+
+ useEffect(() => {
+ if (initHistory) setState({ history: initHistory });
+ }, [initHistory]);
+
+ const handleChatSubmit = async (context: string, otherQueryBody?: any) => {
+ if (!context) {
+ return;
+ }
- const useAgentChat = ({
- queryAgentURL,
- channel,
- queryBody,
- initHistory
- }: Props) => {
- const [state, setState] = useStateReducer({
- history: (initHistory || []) as { role: 'human' | 'view'; context: string; id?: string }[],
+ const history = [...state.history, { role: 'human', context }];
+ const nextIndex = history.length;
+
+ setState({
+ history: history as any,
});
- const { refreshDialogList } = useDialogueContext();
+ let answer = '';
+ let error = '';
- useEffect(() => {
- if (initHistory) setState({ history: initHistory });
- }, [initHistory]);
+ try {
+ const ctrl = new AbortController();
+ let buffer = '';
- const handleChatSubmit = async (context: string, otherQueryBody?: any) => {
- if (!context) {
- return;
- }
-
- const history = [...state.history, { role: 'human', context }];
- const nextIndex = history.length;
-
- setState({
- history: history as any,
- });
-
- let answer = '';
- let error = '';
-
- try {
- const ctrl = new AbortController();
- let buffer = '';
-
- await fetchEventSource(`${process.env.API_BASE_URL ? process.env.API_BASE_URL : ''}${"/api" + queryAgentURL}`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- ...otherQueryBody,
- ...queryBody,
- user_input: context,
- channel,
- }),
- signal: ctrl.signal,
-
- async onopen(response) {
- if (history.length <= 1) {
- refreshDialogList();
- const searchParams = new URLSearchParams(window.location.search);
- searchParams.delete('initMessage');
- window.history.replaceState(null, null, `?${searchParams.toString()}`);
+ await fetchEventSource(`${process.env.API_BASE_URL ? process.env.API_BASE_URL : ''}${"/api" + queryAgentURL}`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ ...otherQueryBody,
+ ...queryBody,
+ user_input: context,
+ channel,
+ }),
+ signal: ctrl.signal,
+
+ async onopen(response) {
+ if (history.length <= 1) {
+ refreshDialogList();
+ const searchParams = new URLSearchParams(window.location.search);
+ searchParams.delete('initMessage');
+ window.history.replaceState(null, null, `?${searchParams.toString()}`);
+ }
+ if (
+ response.ok &&
+ response.headers.get('content-type') === EventStreamContentType
+ ) {
+ return; // everything's good
+ } else if (
+ response.status >= 400 &&
+ response.status < 500 &&
+ response.status !== 429
+ ) {
+ if (response.status === 402) {
+ //throw new ApiError(ApiErrorType.USAGE_LIMIT);
}
- if (
- response.ok &&
- response.headers.get('content-type') === EventStreamContentType
- ) {
- return; // everything's good
- } else if (
- response.status >= 400 &&
- response.status < 500 &&
- response.status !== 429
- ) {
- if (response.status === 402) {
- //throw new ApiError(ApiErrorType.USAGE_LIMIT);
+ // client-side errors are usually non-retriable:
+ //throw new FatalError();
+ } else {
+ //throw new RetriableError();
+ }
+ },
+ onclose() {
+ // if the server closes the connection unexpectedly, retry:
+ console.log('onclose');
+ },
+ onerror(err) {
+ throw new Error(err);
+ },
+ onmessage: (event) => {
+ event.data = event.data.replaceAll('\\n', '\n');
+
+ if (event.data === '[DONE]') {
+ ctrl.abort();
+ } else if (event.data?.startsWith('[ERROR]')) {
+ ctrl.abort();
+ setState({
+ history: [
+ ...history,
+ {
+ role: 'view',
+ context: event.data.replace('[ERROR]', ''),
+ } as any,
+ ],
+ });
+ } else {
+ const h = [...history];
+ if (event.data) {
+ if (h?.[nextIndex]) {
+ h[nextIndex].context = `${event.data}`;
+ } else {
+ h.push({ role: 'view', context: event.data });
}
- // client-side errors are usually non-retriable:
- //throw new FatalError();
- } else {
- //throw new RetriableError();
- }
- },
- onclose() {
- // if the server closes the connection unexpectedly, retry:
- console.log('onclose');
- },
- onerror(err) {
- throw new Error(err);
- },
- onmessage: (event) => {
- console.log(event, 'e');
- event.data = event.data.replaceAll('\\n', '\n');
-
- if (event.data === '[DONE]') {
- ctrl.abort();
- } else if (event.data?.startsWith('[ERROR]')) {
- ctrl.abort();
setState({
- history: [
- ...history,
- {
- role: 'view',
- context: event.data.replace('[ERROR]', ''),
- } as any,
- ],
+ history: h as any,
});
- } else {
- const h = [...history];
- if (event.data) {
- if (h?.[nextIndex]) {
- h[nextIndex].context = `${event.data}`;
- } else {
- h.push({ role: 'view', context: event.data });
- }
- setState({
- history: h as any,
- });
- }
-
}
- },
- });
- } catch (err) {
- console.log('---e', err);
+
+ }
+ },
+ });
+ } catch (err) {
+ console.log(err);
+
+ setState({
+ history: [
+ ...history,
+ { role: 'view', context: answer || '请求出错' as string },
+ ] as any,
+ });
+ // if (err instanceof ApiError) {
+ // if (err?.message) {
+ // error = err?.message;
+
+ // if (error === ApiErrorType.USAGE_LIMIT) {
+ // answer =
+ // 'Usage limit reached. Please upgrade your plan to get higher usage.';
+ // } else {
+ // answer = `Error: ${error}`;
+ // }
+ // } else {
+ // answer = `Error: ${error}`;
+ // }
- setState({
- history: [
- ...history,
- { role: 'view', context: answer || '请求出错' as string },
- ] as any,
- });
- // if (err instanceof ApiError) {
- // if (err?.message) {
- // error = err?.message;
-
- // if (error === ApiErrorType.USAGE_LIMIT) {
- // answer =
- // 'Usage limit reached. Please upgrade your plan to get higher usage.';
- // } else {
- // answer = `Error: ${error}`;
- // }
- // } else {
- // answer = `Error: ${error}`;
- // }
-
- // setState({
- // history: [
- // ...history,
- // { from: 'ai', message: answer as string },
- // ] as any,
- // });
- // }
- }
- };
- return {
- handleChatSubmit,
- history: state.history,
- };
+ // setState({
+ // history: [
+ // ...history,
+ // { from: 'ai', message: answer as string },
+ // ] as any,
+ // });
+ // }
+ }
};
-
- export default useAgentChat;
-
\ No newline at end of file
+ return {
+ handleChatSubmit,
+ history: state.history,
+ };
+};
+
+export default useAgentChat;
From 18cef2495975ee245dcd872fd5fa4c8d9c478aa8 Mon Sep 17 00:00:00 2001
From: "changhuiping.chp" <392752049@qq.com>
Date: Fri, 21 Jul 2023 10:04:52 +0800
Subject: [PATCH 2/7] fix: add Skeleton&tab change duplicate request
---
app/chat/page.tsx | 93 ++++++++++++---
components/chatBoxTemp.tsx | 131 ++++++++++++++++++--
hooks/useAgentChat.ts | 52 ++++----
package-lock.json | 236 ++++++++++++++++++++++++-------------
package.json | 4 +-
5 files changed, 380 insertions(+), 136 deletions(-)
diff --git a/app/chat/page.tsx b/app/chat/page.tsx
index 4141230..e62c1a1 100644
--- a/app/chat/page.tsx
+++ b/app/chat/page.tsx
@@ -1,22 +1,52 @@
"use client"
+import { useEffect, useMemo, useState } from 'react';
+import { Chart, LineAdvance, Interval, Tooltip, getTheme } from "bizcharts";
+import { Card, CardContent, Typography, Grid, Table, Skeleton, AspectRatio, Box, aspectRatioClasses } from "@/lib/mui";
import { useRequest } from 'ahooks';
import { sendGetRequest, sendPostRequest } from '@/utils/request';
-import { Card, CardContent, Typography, Grid, Table } from "@/lib/mui";
import useAgentChat from '@/hooks/useAgentChat';
import ChatBoxComp from '@/components/chatBoxTemp';
import { useDialogueContext } from '@/app/context/dialogue';
import { useSearchParams } from 'next/navigation';
-import { useMemo } from 'react';
-import { Chart, LineAdvance, Interval, Tooltip, getTheme } from "bizcharts";
+
import lodash from 'lodash';
+const ChartSkeleton = () => {
+ return (
+
+
+
+
+
+
+
+ )
+};
+
const AgentPage = () => {
+ const [chartsData, setChartsData] = useState();
const searchParams = useSearchParams();
const { refreshDialogList } = useDialogueContext();
const id = searchParams.get('id');
const scene = searchParams.get('scene');
- const { data: historyList } = useRequest(async () => await sendGetRequest('/v1/chat/dialogue/messages/history', {
+ const { data: historyList, run: runHistoryList } = useRequest(async () => await sendGetRequest('/v1/chat/dialogue/messages/history', {
con_uid: id
}), {
ready: !!id,
@@ -34,16 +64,17 @@ const AgentPage = () => {
conv_uid: id,
chat_mode: scene || 'chat_normal',
},
- initHistory: historyList?.data
+ initHistory: historyList?.data,
+ runHistoryList
});
- const chartsData = useMemo(() => {
+ useEffect(() => {
try {
const contextTemp = history?.[history.length - 1]?.context;
const contextObj = JSON.parse(contextTemp);
- return contextObj?.template_name === 'sales_report' ? contextObj?.charts : undefined;
+ setChartsData(contextObj?.template_name === 'sales_report' ? contextObj?.charts : undefined);
} catch (e) {
- return undefined;
+ setChartsData(undefined);
}
}, [history]);
@@ -117,7 +148,7 @@ const AgentPage = () => {
>
{col.values.map((item) => (
-
+
{item.name}
@@ -132,11 +163,14 @@ const AgentPage = () => {
} else if (col.chart_type === "LineChart") {
return (
-
+
{col.chart_name}
+
+ {col.chart_desc}
+
{
} else if (col.chart_type === "BarChart") {
return (
-
+
{col.chart_name}
+
+ {col.chart_desc}
+
{
const data = lodash.groupBy(col.values, 'type');
return (
-
-
+
{col.chart_name}
+
+ {col.chart_desc}
+
{
)}
-
-
+ {!chartsData && scene === 'chat_dashboard' && (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+
+
{
await refreshDialogList();
}}
+ isChartChat={scene === 'chat_dashboard'}
messages={history || []}
onSubmit={handleChatSubmit}
paramsList={paramsList?.data}
+ setChartsData={setChartsData}
/>
diff --git a/components/chatBoxTemp.tsx b/components/chatBoxTemp.tsx
index a4a1473..68db9d7 100644
--- a/components/chatBoxTemp.tsx
+++ b/components/chatBoxTemp.tsx
@@ -1,7 +1,7 @@
import { zodResolver } from '@hookform/resolvers/zod';
import SendRoundedIcon from '@mui/icons-material/SendRounded';
-import { Card, CircularProgress, IconButton, Input, Stack, Select, Option, Tooltip, Box, useColorScheme } from '@/lib/mui';
-import React, { useState } from 'react';
+import { Card, CircularProgress, IconButton, Input, Stack, Select, Option, Box, Modal, ModalDialog, ModalClose, Button, Link } from '@/lib/mui';
+import React, { useState, useRef } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { Message } from '@/types';
@@ -11,13 +11,20 @@ import Markdown from 'markdown-to-jsx';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { okaidia } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { useSearchParams } from 'next/navigation';
+import lodash from 'lodash';
+import AceEditor from 'react-ace';
+import 'ace-builds/src-noconflict/mode-json';
+import 'ace-builds/src-noconflict/ext-language_tools';
+import { message } from 'antd';
type Props = {
messages: Message[];
onSubmit: (message: string, otherQueryBody?: any) => Promise
;
readOnly?: boolean;
paramsList?: { [key: string]: string };
+ isChartChat: boolean;
clearIntialMessage?: () => void;
+ setChartsData?: (chartsData: any) => void;
};
const Schema = z.object({ query: z.string().min(1) });
@@ -27,13 +34,19 @@ const ChatBoxComp = ({
onSubmit,
readOnly,
paramsList,
- clearIntialMessage
+ isChartChat = false,
+ clearIntialMessage,
+ setChartsData
}: Props) => {
const searchParams = useSearchParams();
const initMessage = searchParams.get('initMessage');
- const scrollableRef = React.useRef(null);
+ const scrollableRef = useRef(null);
const [isLoading, setIsLoading] = useState(false);
const [currentParam, setCurrentParam] = useState();
+ const [jsonModalOpen, setJsonModalOpen] = useState(false);
+ const [currentJsonIndex, setCurrentJsonIndex] = useState();
+ const [showMessages, setShowMessages] = useState(messages);
+ const [jsonValue, setJsonValue] = useState('');
const methods = useForm>({
resolver: zodResolver(Schema),
@@ -42,7 +55,6 @@ const ChatBoxComp = ({
const submit = async ({ query }: z.infer) => {
try {
- console.log('submit');
setIsLoading(true);
methods.reset();
await onSubmit(query, {
@@ -79,11 +91,20 @@ const ChatBoxComp = ({
wrapper: React.Fragment,
};
+ const handleJson2Obj = (jsonStr: string) => {
+ let res = jsonStr;
+ try {
+ res = JSON.parse(jsonStr);
+ } catch (e) {
+ console.log(e);
+ }
+ return res;
+ };
+
React.useEffect(() => {
if (!scrollableRef.current) {
return;
}
-
scrollableRef.current.scrollTo(0, scrollableRef.current.scrollHeight);
}, [messages?.length]);
@@ -99,6 +120,20 @@ const ChatBoxComp = ({
}
}, [paramsList]);
+ React.useEffect(() => {
+ if (isChartChat) {
+ let temp = lodash.cloneDeep(messages);
+ temp.forEach(item => {
+ if (item?.role === 'view' && typeof item?.context === 'string') {
+ item.context = handleJson2Obj(item?.context);
+ }
+ })
+ setShowMessages(temp.filter(item => ['view', 'human'].includes(item.role)));
+ } else {
+ setShowMessages(messages.filter(item => ['view', 'human'].includes(item.role)));
+ }
+ }, [isChartChat, messages]);
+
return (
- {messages.filter(item => ['view', 'human'].includes(item.role))?.map((each, index) => {
+ {showMessages.map((each, index) => {
return (
-
- {each.context?.replaceAll('\\n', '\n')}
-
+ {
+ (isChartChat && each.role === 'view' && typeof each?.context === 'object') ? (
+ <>
+ {`[${each.context.template_name}]: `}
+ {
+ setJsonModalOpen(true);
+ setCurrentJsonIndex(index);
+ setJsonValue(JSON.stringify(each?.context, null, 2));
+ }}
+ >
+ {each.context.template_introduce || '暂无介绍'}
+
+ >
+ ) : (
+
+ {each.context?.replaceAll?.('\\n', '\n')}
+
+ )
+ }
@@ -246,6 +302,61 @@ const ChatBoxComp = ({
)}
+ setJsonModalOpen(false)}
+ >
+
+
+
+
+
+
+
+
);
}
diff --git a/hooks/useAgentChat.ts b/hooks/useAgentChat.ts
index c45d4fe..5e7733a 100644
--- a/hooks/useAgentChat.ts
+++ b/hooks/useAgentChat.ts
@@ -12,24 +12,42 @@ type Props = {
channel?: "dashboard" | "website" | "slack" | "crisp";
queryBody?: any;
initHistory?: Message[];
+ runHistoryList?: () => void;
};
const useAgentChat = ({
queryAgentURL,
channel,
queryBody,
- initHistory
+ initHistory,
+ runHistoryList
}: Props) => {
const [state, setState] = useStateReducer({
history: (initHistory || []) as { role: 'human' | 'view'; context: string; id?: string }[],
});
const { refreshDialogList } = useDialogueContext();
+ const ctrl = new AbortController();
useEffect(() => {
if (initHistory) setState({ history: initHistory });
}, [initHistory]);
+ const handleVisibleChange = async () => {
+ if (document.visibilityState === 'hidden') {
+ ctrl.abort();
+ } else {
+ await runHistoryList?.();
+ document.removeEventListener('visibilitychange', handleVisibleChange);
+ }
+ }
+
+ useEffect(() => {
+ return () => {
+ document.removeEventListener('visibilitychange', handleVisibleChange);
+ }
+ }, []);
+
const handleChatSubmit = async (context: string, otherQueryBody?: any) => {
if (!context) {
return;
@@ -43,12 +61,8 @@ const useAgentChat = ({
});
let answer = '';
- let error = '';
try {
- const ctrl = new AbortController();
- let buffer = '';
-
await fetchEventSource(`${process.env.API_BASE_URL ? process.env.API_BASE_URL : ''}${"/api" + queryAgentURL}`, {
method: 'POST',
headers: {
@@ -91,15 +105,19 @@ const useAgentChat = ({
onclose() {
// if the server closes the connection unexpectedly, retry:
console.log('onclose');
+ document.removeEventListener('visibilitychange', handleVisibleChange);
},
- onerror(err) {
+ onerror(err) {
+ console.log('onerror');
throw new Error(err);
},
onmessage: (event) => {
+ document.addEventListener('visibilitychange', handleVisibleChange);
event.data = event.data.replaceAll('\\n', '\n');
if (event.data === '[DONE]') {
ctrl.abort();
+ document.removeEventListener('visibilitychange', handleVisibleChange);
} else if (event.data?.startsWith('[ERROR]')) {
ctrl.abort();
setState({
@@ -136,29 +154,9 @@ const useAgentChat = ({
{ role: 'view', context: answer || '请求出错' as string },
] as any,
});
- // if (err instanceof ApiError) {
- // if (err?.message) {
- // error = err?.message;
-
- // if (error === ApiErrorType.USAGE_LIMIT) {
- // answer =
- // 'Usage limit reached. Please upgrade your plan to get higher usage.';
- // } else {
- // answer = `Error: ${error}`;
- // }
- // } else {
- // answer = `Error: ${error}`;
- // }
-
- // setState({
- // history: [
- // ...history,
- // { from: 'ai', message: answer as string },
- // ] as any,
- // });
- // }
}
};
+
return {
handleChatSubmit,
history: state.history,
diff --git a/package-lock.json b/package-lock.json
index 727e944..2aedc4f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,7 +16,7 @@
"@hookform/resolvers": "^3.0.0",
"@microsoft/fetch-event-source": "^2.0.1",
"@mui/icons-material": "^5.11.16",
- "@mui/joy": "5.0.0-alpha.72",
+ "@mui/joy": "5.0.0-alpha.88",
"@mui/lab": "5.0.0-alpha.124",
"@mui/material": "^5.13.6",
"@mui/styled-engine-sc": "^5.12.0",
@@ -25,6 +25,7 @@
"@types/node": "20.3.1",
"@types/react": "18.2.14",
"@types/react-dom": "18.2.6",
+ "ace-builds": "^1.12.5",
"ahooks": "^3.7.8",
"antd": "^5.6.2",
"autoprefixer": "10.4.14",
@@ -41,6 +42,7 @@
"nprogress": "^0.2.0",
"postcss": "8.4.24",
"react": "18.2.0",
+ "react-ace": "^10.1.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.43.8",
"react-syntax-highlighter": "^15.5.0",
@@ -1066,9 +1068,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.22.5",
- "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.5.tgz",
- "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==",
+ "version": "7.22.6",
+ "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.6.tgz",
+ "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
"dependencies": {
"regenerator-runtime": "^0.13.11"
},
@@ -1512,9 +1514,9 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/@mui/core-downloads-tracker": {
- "version": "5.13.4",
- "resolved": "https://registry.npmmirror.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.4.tgz",
- "integrity": "sha512-yFrMWcrlI0TqRN5jpb6Ma9iI7sGTHpytdzzL33oskFHNQ8UgrtPas33Y1K7sWAMwCrr1qbWDrOHLAQG4tAzuSw=="
+ "version": "5.14.1",
+ "resolved": "https://registry.npmmirror.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.1.tgz",
+ "integrity": "sha512-mIa1WmDmNr1LoupV1Rbxt9bTFKMbIn10RHG1bnZ/FJCkAYpuU/D4n+R+ttiycgcZNngU++zyh/OQeJblzbQPzg=="
},
"node_modules/@mui/icons-material": {
"version": "5.11.16",
@@ -1538,18 +1540,18 @@
}
},
"node_modules/@mui/joy": {
- "version": "5.0.0-alpha.72",
- "resolved": "https://registry.npmmirror.com/@mui/joy/-/joy-5.0.0-alpha.72.tgz",
- "integrity": "sha512-Tlf5HkRUpYMuVAjLWZY/k1mqF8fGHH5l3OL4Q8SZIiYZF+k6loMrapCI2L70qDVDbb6C42G0/9qrOczJNMIF4A==",
- "dependencies": {
- "@babel/runtime": "^7.21.0",
- "@mui/base": "5.0.0-alpha.122",
- "@mui/core-downloads-tracker": "^5.11.14",
- "@mui/system": "^5.11.14",
- "@mui/types": "^7.2.3",
- "@mui/utils": "^5.11.13",
+ "version": "5.0.0-alpha.88",
+ "resolved": "https://registry.npmmirror.com/@mui/joy/-/joy-5.0.0-alpha.88.tgz",
+ "integrity": "sha512-zG+kYy7JV07nQWHXtZP7+78pf3erv+X07aHetbwb9etx7pqGhxTxeBeT2WltH3hAUEUEr9GqfChcBe2MWy2ziQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.22.6",
+ "@mui/base": "5.0.0-beta.8",
+ "@mui/core-downloads-tracker": "^5.14.1",
+ "@mui/system": "^5.14.1",
+ "@mui/types": "^7.2.4",
+ "@mui/utils": "^5.14.1",
"clsx": "^1.2.1",
- "csstype": "^3.1.1",
+ "csstype": "^3.1.2",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
},
@@ -1576,15 +1578,15 @@
}
},
"node_modules/@mui/joy/node_modules/@mui/base": {
- "version": "5.0.0-alpha.122",
- "resolved": "https://registry.npmmirror.com/@mui/base/-/base-5.0.0-alpha.122.tgz",
- "integrity": "sha512-IgZEFQyHa39J1+Q3tekVdhPuUm1fr3icddaNLmiAIeYTVXmR7KR5FhBAIL0P+4shlPq0liUPGlXryoTm0iCeFg==",
+ "version": "5.0.0-beta.8",
+ "resolved": "https://registry.npmmirror.com/@mui/base/-/base-5.0.0-beta.8.tgz",
+ "integrity": "sha512-b4vVjMZx5KzzEMf4arXKoeV5ZegAMOoPwoy1vfUBwhvXc2QtaaAyBp50U7OA2L06Leubc1A+lEp3eqwZoFn87g==",
"dependencies": {
- "@babel/runtime": "^7.21.0",
- "@emotion/is-prop-valid": "^1.2.0",
- "@mui/types": "^7.2.3",
- "@mui/utils": "^5.11.13",
- "@popperjs/core": "^2.11.6",
+ "@babel/runtime": "^7.22.6",
+ "@emotion/is-prop-valid": "^1.2.1",
+ "@mui/types": "^7.2.4",
+ "@mui/utils": "^5.14.1",
+ "@popperjs/core": "^2.11.8",
"clsx": "^1.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
@@ -1728,12 +1730,12 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/@mui/private-theming": {
- "version": "5.13.1",
- "resolved": "https://registry.npmmirror.com/@mui/private-theming/-/private-theming-5.13.1.tgz",
- "integrity": "sha512-HW4npLUD9BAkVppOUZHeO1FOKUJWAwbpy0VQoGe3McUYTlck1HezGHQCfBQ5S/Nszi7EViqiimECVl9xi+/WjQ==",
+ "version": "5.13.7",
+ "resolved": "https://registry.npmmirror.com/@mui/private-theming/-/private-theming-5.13.7.tgz",
+ "integrity": "sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==",
"dependencies": {
- "@babel/runtime": "^7.21.0",
- "@mui/utils": "^5.13.1",
+ "@babel/runtime": "^7.22.5",
+ "@mui/utils": "^5.13.7",
"prop-types": "^15.8.1"
},
"engines": {
@@ -1802,15 +1804,15 @@
}
},
"node_modules/@mui/system": {
- "version": "5.13.6",
- "resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz",
- "integrity": "sha512-G3Xr28uLqU3DyF6r2LQkHGw/ku4P0AHzlKVe7FGXOPl7X1u+hoe2xxj8Vdiq/69II/mh9OP21i38yBWgWb7WgQ==",
+ "version": "5.14.1",
+ "resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.14.1.tgz",
+ "integrity": "sha512-u+xlsU34Jdkgx1CxmBnIC4Y08uPdVX5iEd3S/1dggDFtOGp+Lj8xmKRJAQ8PJOOJLOh8pDwaZx4AwXikL4l1QA==",
"dependencies": {
- "@babel/runtime": "^7.22.5",
- "@mui/private-theming": "^5.13.1",
+ "@babel/runtime": "^7.22.6",
+ "@mui/private-theming": "^5.13.7",
"@mui/styled-engine": "^5.13.2",
"@mui/types": "^7.2.4",
- "@mui/utils": "^5.13.6",
+ "@mui/utils": "^5.14.1",
"clsx": "^1.2.1",
"csstype": "^3.1.2",
"prop-types": "^15.8.1"
@@ -1850,13 +1852,13 @@
}
},
"node_modules/@mui/utils": {
- "version": "5.13.6",
- "resolved": "https://registry.npmmirror.com/@mui/utils/-/utils-5.13.6.tgz",
- "integrity": "sha512-ggNlxl5NPSbp+kNcQLmSig6WVB0Id+4gOxhx644987v4fsji+CSXc+MFYLocFB/x4oHtzCUlSzbVHlJfP/fXoQ==",
+ "version": "5.14.1",
+ "resolved": "https://registry.npmmirror.com/@mui/utils/-/utils-5.14.1.tgz",
+ "integrity": "sha512-39KHKK2JeqRmuUcLDLwM+c2XfVC136C5/yUyQXmO2PVbOb2Bol4KxtkssEqCbTwg87PSCG3f1Tb0keRsK7cVGw==",
"dependencies": {
- "@babel/runtime": "^7.22.5",
+ "@babel/runtime": "^7.22.6",
"@types/prop-types": "^15.7.5",
- "@types/react-is": "^18.2.0",
+ "@types/react-is": "^18.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
},
@@ -2442,6 +2444,11 @@
"react": "*"
}
},
+ "node_modules/ace-builds": {
+ "version": "1.12.5",
+ "resolved": "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.12.5.tgz",
+ "integrity": "sha512-2OTOZZdXVqWHfsV63n/bWLJ4uGnGNm9uwEQSECbEzMpKF2RKxD04lWu7s+eRBTZoEbqPXziyI1qamJH2OAwdwA=="
+ },
"node_modules/acorn": {
"version": "8.9.0",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.9.0.tgz",
@@ -3521,6 +3528,11 @@
"node": ">=0.3.1"
}
},
+ "node_modules/diff-match-patch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+ },
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -5168,6 +5180,16 @@
"resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmmirror.com/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
+ "node_modules/lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmmirror.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -7020,6 +7042,22 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-ace": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmmirror.com/react-ace/-/react-ace-10.1.0.tgz",
+ "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
+ "dependencies": {
+ "ace-builds": "^1.4.14",
+ "diff-match-patch": "^1.0.5",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "prop-types": "^15.7.2"
+ },
+ "peerDependencies": {
+ "react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz",
@@ -9241,9 +9279,9 @@
}
},
"@babel/runtime": {
- "version": "7.22.5",
- "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.5.tgz",
- "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==",
+ "version": "7.22.6",
+ "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.6.tgz",
+ "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
"requires": {
"regenerator-runtime": "^0.13.11"
}
@@ -9594,9 +9632,9 @@
}
},
"@mui/core-downloads-tracker": {
- "version": "5.13.4",
- "resolved": "https://registry.npmmirror.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.4.tgz",
- "integrity": "sha512-yFrMWcrlI0TqRN5jpb6Ma9iI7sGTHpytdzzL33oskFHNQ8UgrtPas33Y1K7sWAMwCrr1qbWDrOHLAQG4tAzuSw=="
+ "version": "5.14.1",
+ "resolved": "https://registry.npmmirror.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.1.tgz",
+ "integrity": "sha512-mIa1WmDmNr1LoupV1Rbxt9bTFKMbIn10RHG1bnZ/FJCkAYpuU/D4n+R+ttiycgcZNngU++zyh/OQeJblzbQPzg=="
},
"@mui/icons-material": {
"version": "5.11.16",
@@ -9607,32 +9645,32 @@
}
},
"@mui/joy": {
- "version": "5.0.0-alpha.72",
- "resolved": "https://registry.npmmirror.com/@mui/joy/-/joy-5.0.0-alpha.72.tgz",
- "integrity": "sha512-Tlf5HkRUpYMuVAjLWZY/k1mqF8fGHH5l3OL4Q8SZIiYZF+k6loMrapCI2L70qDVDbb6C42G0/9qrOczJNMIF4A==",
- "requires": {
- "@babel/runtime": "^7.21.0",
- "@mui/base": "5.0.0-alpha.122",
- "@mui/core-downloads-tracker": "^5.11.14",
- "@mui/system": "^5.11.14",
- "@mui/types": "^7.2.3",
- "@mui/utils": "^5.11.13",
+ "version": "5.0.0-alpha.88",
+ "resolved": "https://registry.npmmirror.com/@mui/joy/-/joy-5.0.0-alpha.88.tgz",
+ "integrity": "sha512-zG+kYy7JV07nQWHXtZP7+78pf3erv+X07aHetbwb9etx7pqGhxTxeBeT2WltH3hAUEUEr9GqfChcBe2MWy2ziQ==",
+ "requires": {
+ "@babel/runtime": "^7.22.6",
+ "@mui/base": "5.0.0-beta.8",
+ "@mui/core-downloads-tracker": "^5.14.1",
+ "@mui/system": "^5.14.1",
+ "@mui/types": "^7.2.4",
+ "@mui/utils": "^5.14.1",
"clsx": "^1.2.1",
- "csstype": "^3.1.1",
+ "csstype": "^3.1.2",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
},
"dependencies": {
"@mui/base": {
- "version": "5.0.0-alpha.122",
- "resolved": "https://registry.npmmirror.com/@mui/base/-/base-5.0.0-alpha.122.tgz",
- "integrity": "sha512-IgZEFQyHa39J1+Q3tekVdhPuUm1fr3icddaNLmiAIeYTVXmR7KR5FhBAIL0P+4shlPq0liUPGlXryoTm0iCeFg==",
+ "version": "5.0.0-beta.8",
+ "resolved": "https://registry.npmmirror.com/@mui/base/-/base-5.0.0-beta.8.tgz",
+ "integrity": "sha512-b4vVjMZx5KzzEMf4arXKoeV5ZegAMOoPwoy1vfUBwhvXc2QtaaAyBp50U7OA2L06Leubc1A+lEp3eqwZoFn87g==",
"requires": {
- "@babel/runtime": "^7.21.0",
- "@emotion/is-prop-valid": "^1.2.0",
- "@mui/types": "^7.2.3",
- "@mui/utils": "^5.11.13",
- "@popperjs/core": "^2.11.6",
+ "@babel/runtime": "^7.22.6",
+ "@emotion/is-prop-valid": "^1.2.1",
+ "@mui/types": "^7.2.4",
+ "@mui/utils": "^5.14.1",
+ "@popperjs/core": "^2.11.8",
"clsx": "^1.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
@@ -9709,12 +9747,12 @@
}
},
"@mui/private-theming": {
- "version": "5.13.1",
- "resolved": "https://registry.npmmirror.com/@mui/private-theming/-/private-theming-5.13.1.tgz",
- "integrity": "sha512-HW4npLUD9BAkVppOUZHeO1FOKUJWAwbpy0VQoGe3McUYTlck1HezGHQCfBQ5S/Nszi7EViqiimECVl9xi+/WjQ==",
+ "version": "5.13.7",
+ "resolved": "https://registry.npmmirror.com/@mui/private-theming/-/private-theming-5.13.7.tgz",
+ "integrity": "sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==",
"requires": {
- "@babel/runtime": "^7.21.0",
- "@mui/utils": "^5.13.1",
+ "@babel/runtime": "^7.22.5",
+ "@mui/utils": "^5.13.7",
"prop-types": "^15.8.1"
}
},
@@ -9739,15 +9777,15 @@
}
},
"@mui/system": {
- "version": "5.13.6",
- "resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.13.6.tgz",
- "integrity": "sha512-G3Xr28uLqU3DyF6r2LQkHGw/ku4P0AHzlKVe7FGXOPl7X1u+hoe2xxj8Vdiq/69II/mh9OP21i38yBWgWb7WgQ==",
+ "version": "5.14.1",
+ "resolved": "https://registry.npmmirror.com/@mui/system/-/system-5.14.1.tgz",
+ "integrity": "sha512-u+xlsU34Jdkgx1CxmBnIC4Y08uPdVX5iEd3S/1dggDFtOGp+Lj8xmKRJAQ8PJOOJLOh8pDwaZx4AwXikL4l1QA==",
"requires": {
- "@babel/runtime": "^7.22.5",
- "@mui/private-theming": "^5.13.1",
+ "@babel/runtime": "^7.22.6",
+ "@mui/private-theming": "^5.13.7",
"@mui/styled-engine": "^5.13.2",
"@mui/types": "^7.2.4",
- "@mui/utils": "^5.13.6",
+ "@mui/utils": "^5.14.1",
"clsx": "^1.2.1",
"csstype": "^3.1.2",
"prop-types": "^15.8.1"
@@ -9760,13 +9798,13 @@
"requires": {}
},
"@mui/utils": {
- "version": "5.13.6",
- "resolved": "https://registry.npmmirror.com/@mui/utils/-/utils-5.13.6.tgz",
- "integrity": "sha512-ggNlxl5NPSbp+kNcQLmSig6WVB0Id+4gOxhx644987v4fsji+CSXc+MFYLocFB/x4oHtzCUlSzbVHlJfP/fXoQ==",
+ "version": "5.14.1",
+ "resolved": "https://registry.npmmirror.com/@mui/utils/-/utils-5.14.1.tgz",
+ "integrity": "sha512-39KHKK2JeqRmuUcLDLwM+c2XfVC136C5/yUyQXmO2PVbOb2Bol4KxtkssEqCbTwg87PSCG3f1Tb0keRsK7cVGw==",
"requires": {
- "@babel/runtime": "^7.22.5",
+ "@babel/runtime": "^7.22.6",
"@types/prop-types": "^15.7.5",
- "@types/react-is": "^18.2.0",
+ "@types/react-is": "^18.2.1",
"prop-types": "^15.8.1",
"react-is": "^18.2.0"
},
@@ -10174,6 +10212,11 @@
"integrity": "sha512-QlN0RJSBVQBwLRNxbxjQ5qzqYIGn+K7USppMoIOVlf7fxXHsnQZ2bEsa6Pm74bt6DVQxpUE8HqvdStn6Y9FV1w==",
"requires": {}
},
+ "ace-builds": {
+ "version": "1.12.5",
+ "resolved": "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.12.5.tgz",
+ "integrity": "sha512-2OTOZZdXVqWHfsV63n/bWLJ4uGnGNm9uwEQSECbEzMpKF2RKxD04lWu7s+eRBTZoEbqPXziyI1qamJH2OAwdwA=="
+ },
"acorn": {
"version": "8.9.0",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.9.0.tgz",
@@ -11044,6 +11087,11 @@
"resolved": "https://registry.npmmirror.com/diff/-/diff-5.1.0.tgz",
"integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw=="
},
+ "diff-match-patch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+ },
"dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -12364,6 +12412,16 @@
"resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmmirror.com/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmmirror.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -13808,6 +13866,18 @@
"loose-envify": "^1.1.0"
}
},
+ "react-ace": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmmirror.com/react-ace/-/react-ace-10.1.0.tgz",
+ "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
+ "requires": {
+ "ace-builds": "^1.4.14",
+ "diff-match-patch": "^1.0.5",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "prop-types": "^15.7.2"
+ }
+ },
"react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz",
diff --git a/package.json b/package.json
index 47cde7c..42a03d1 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"@hookform/resolvers": "^3.0.0",
"@microsoft/fetch-event-source": "^2.0.1",
"@mui/icons-material": "^5.11.16",
- "@mui/joy": "5.0.0-alpha.72",
+ "@mui/joy": "5.0.0-alpha.88",
"@mui/lab": "5.0.0-alpha.124",
"@mui/material": "^5.13.6",
"@mui/styled-engine-sc": "^5.12.0",
@@ -28,6 +28,7 @@
"@types/node": "20.3.1",
"@types/react": "18.2.14",
"@types/react-dom": "18.2.6",
+ "ace-builds": "^1.12.5",
"ahooks": "^3.7.8",
"antd": "^5.6.2",
"autoprefixer": "10.4.14",
@@ -44,6 +45,7 @@
"nprogress": "^0.2.0",
"postcss": "8.4.24",
"react": "18.2.0",
+ "react-ace": "^10.1.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.43.8",
"react-syntax-highlighter": "^15.5.0",
From 7b6c4be95e4b4432865ec0e247bc0dee1e0a2b1b Mon Sep 17 00:00:00 2001
From: "changhuiping.chp" <392752049@qq.com>
Date: Fri, 21 Jul 2023 11:26:12 +0800
Subject: [PATCH 3/7] fix: npm run compile 'window is not defined' error
---
components/chatBoxTemp.tsx | 53 +++++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 21 deletions(-)
diff --git a/components/chatBoxTemp.tsx b/components/chatBoxTemp.tsx
index 68db9d7..a86169a 100644
--- a/components/chatBoxTemp.tsx
+++ b/components/chatBoxTemp.tsx
@@ -12,9 +12,6 @@ import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { okaidia } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { useSearchParams } from 'next/navigation';
import lodash from 'lodash';
-import AceEditor from 'react-ace';
-import 'ace-builds/src-noconflict/mode-json';
-import 'ace-builds/src-noconflict/ext-language_tools';
import { message } from 'antd';
type Props = {
@@ -101,6 +98,17 @@ const ChatBoxComp = ({
return res;
};
+ const MyAceEditor = React.useMemo(() => {
+ // fix npm run compile 'window is not defined' error
+ if (typeof window !== 'undefined' && typeof window?.fetch === 'function') {
+ const AceEditor = require('react-ace');
+ require('ace-builds/src-noconflict/mode-json');
+ require('ace-builds/src-noconflict/ext-language_tools');
+ return AceEditor.default;
+ }
+ return undefined;
+ }, []);
+
React.useEffect(() => {
if (!scrollableRef.current) {
return;
@@ -312,24 +320,27 @@ const ChatBoxComp = ({
>
-
+ {!!MyAceEditor && (
+
+ )}
+