diff --git a/web/components/chat/agent-content.tsx b/web/components/chat/agent-content.tsx index 041d0e5ec..164d4f3e0 100644 --- a/web/components/chat/agent-content.tsx +++ b/web/components/chat/agent-content.tsx @@ -2,7 +2,7 @@ import { ChatContext } from '@/app/chat-context'; import { IChatDialogueMessageSchema } from '@/types/chat'; import classNames from 'classnames'; import { memo, useContext } from 'react'; -import ReactMarkdown from 'react-markdown'; +import { GPTVis } from '@antv/gpt-vis'; import markdownComponents from './chat-content/config'; import rehypeRaw from 'rehype-raw'; @@ -21,15 +21,21 @@ function AgentContent({ content }: Props) { return (
{isView ? ( - + {formatMarkdownVal(content.context)} - + ) : (
{content.context}
)} diff --git a/web/components/chat/chat-content/VisResponse.tsx b/web/components/chat/chat-content/VisResponse.tsx index 248b9bce2..371f203ec 100644 --- a/web/components/chat/chat-content/VisResponse.tsx +++ b/web/components/chat/chat-content/VisResponse.tsx @@ -6,7 +6,7 @@ import { githubLightTheme } from '@uiw/react-json-view/githubLight'; import { Alert, Spin } from 'antd'; import classNames from 'classnames'; import React, { useContext, useMemo } from 'react'; -import ReactMarkdown from 'react-markdown'; +import { GPTVis } from '@antv/gpt-vis'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; @@ -41,30 +41,36 @@ const VisResponse: React.FC<{ data: VisResponseProps }> = ({ data }) => { return (
} /> })} + {...(type === "warning" && { + icon: } />, + })} /> {data.result && ( )} {data.err_msg && ( - + {data.err_msg} - + )}
); diff --git a/web/components/chat/chat-content/agent-messages.tsx b/web/components/chat/chat-content/agent-messages.tsx index 4940a8e39..f327d816f 100644 --- a/web/components/chat/chat-content/agent-messages.tsx +++ b/web/components/chat/chat-content/agent-messages.tsx @@ -1,7 +1,6 @@ import ModelIcon from '@/new-components/chat/content/ModelIcon'; -import { LinkOutlined, SwapRightOutlined } from '@ant-design/icons'; -import { Popover, Space } from 'antd'; -import ReactMarkdown from 'react-markdown'; +import { SwapRightOutlined } from '@ant-design/icons'; +import { GPTVis } from '@antv/gpt-vis'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; import markdownComponents from './config'; @@ -24,7 +23,11 @@ function AgentMessages({ data }: Props) { {data.map((item, index) => (
- {item.model ? :
} + {item.model ? ( + + ) : ( +
+ )}
{item.sender} @@ -32,11 +35,17 @@ function AgentMessages({ data }: Props) {
- + {item.markdown} - +
- {item.resource && item.resource !== 'null' && } + {item.resource && item.resource !== "null" && ( + + )}
))} diff --git a/web/components/chat/chat-content/agent-plans.tsx b/web/components/chat/chat-content/agent-plans.tsx index 73f9850bd..4ae774db8 100644 --- a/web/components/chat/chat-content/agent-plans.tsx +++ b/web/components/chat/chat-content/agent-plans.tsx @@ -1,6 +1,6 @@ import { CaretRightOutlined, CheckOutlined, ClockCircleOutlined } from '@ant-design/icons'; import { Collapse } from 'antd'; -import ReactMarkdown from 'react-markdown'; +import { GPTVis } from '@antv/gpt-vis'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; @@ -32,7 +32,7 @@ function AgentPlans({ data }: Props) { {item.name} - {item.agent} - {item.status === 'complete' ? ( + {item.status === "complete" ? ( ) : ( @@ -40,9 +40,13 @@ function AgentPlans({ data }: Props) {
), children: ( - + {item.markdown} - + ), }; })} diff --git a/web/components/chat/chat-content/config.tsx b/web/components/chat/chat-content/config.tsx index 43898c0ff..40702714f 100644 --- a/web/components/chat/chat-content/config.tsx +++ b/web/components/chat/chat-content/config.tsx @@ -1,146 +1,241 @@ -import { AutoChart, BackEndChartType, getChartType } from '@/components/chart'; -import { LinkOutlined, ReadOutlined, SyncOutlined } from '@ant-design/icons'; -import { Datum } from '@antv/ava'; -import { Image, Table, Tabs, TabsProps, Tag } from 'antd'; -import ReactMarkdown from 'react-markdown'; -import rehypeRaw from 'rehype-raw'; -import remarkGfm from 'remark-gfm'; +import { LinkOutlined, ReadOutlined, SyncOutlined } from "@ant-design/icons"; +import { GPTVis, withDefaultChartCode } from "@antv/gpt-vis"; +import { Table, Image, Tag, Tabs, TabsProps } from "antd"; +import { AutoChart, BackEndChartType, getChartType } from "@/components/chart"; +import { Datum } from "@antv/ava"; +import rehypeRaw from "rehype-raw"; +import remarkGfm from "remark-gfm"; +import AgentMessages from "./agent-messages"; +import AgentPlans from "./agent-plans"; +import { CodePreview } from "./code-preview"; +import ReferencesContent from "./ReferencesContent"; +import VisChart from "./vis-chart"; +import VisCode from "./vis-code"; +import VisConvertError from "./vis-convert-error"; +import VisDashboard from "./vis-dashboard"; +import VisPlugin from "./vis-plugin"; +import VisAppLink from "./VisAppLink"; +import VisChatLink from "./VisChatLink"; +import VisResponse from "./VisResponse"; +import { formatSql } from "@/utils"; -import AgentMessages from './agent-messages'; -import AgentPlans from './agent-plans'; -import { CodePreview } from './code-preview'; -import ReferencesContent from './ReferencesContent'; -import VisChart from './vis-chart'; -import VisCode from './vis-code'; -import VisConvertError from './vis-convert-error'; -import VisDashboard from './vis-dashboard'; -import VisPlugin from './vis-plugin'; -import VisAppLink from './VisAppLink'; -import VisChatLink from './VisChatLink'; -import VisResponse from './VisResponse'; -import { formatSql } from '@/utils'; +type MarkdownComponent = Parameters["0"]["components"]; -type MarkdownComponent = Parameters['0']['components']; - -const customeTags: (keyof JSX.IntrinsicElements)[] = ['custom-view', 'chart-view', 'references', 'summary']; +const customeTags: (keyof JSX.IntrinsicElements)[] = [ + "custom-view", + "chart-view", + "references", + "summary", +]; function matchCustomeTagValues(context: string) { const matchValues = customeTags.reduce((acc, tagName) => { - const tagReg = new RegExp(`<${tagName}[^>]*\/?>`, 'gi'); + const tagReg = new RegExp(`<${tagName}[^>]*\/?>`, "gi"); context = context.replace(tagReg, (matchVal) => { acc.push(matchVal); - return ''; + return ""; }); return acc; }, []); return { context, matchValues }; } +const codeComponents = { + /** + * @description + * Custom code block rendering, which can be used to render custom components in the code block. + * Is it defined in gpt-vis, and the default rendering contains `vis-chart`. + */ + code: withDefaultChartCode({ + languageRenderers: { + "agent-plans": ({ + node, + className, + children, + style, + }) => { + const content = String(children); + /** + * @description + * In some cases, tags are nested within code syntax, + * so it is necessary to extract the tags present in the code block and render them separately. + */ + const lang = className?.replace("language-", "") || "javascript"; + try { + const data = JSON.parse(content) as Parameters< + typeof AgentPlans + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + "agent-messages": ({ + node, + className, + children, + style, + }) => { + const content = String(children); + const lang = className?.replace("language-", "") || "javascript"; + try { + const data = JSON.parse(content) as Parameters< + typeof AgentMessages + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + "vis-convert-error": ({ + node, + className, + children, + style, + }) => { + const content = String(children); + const lang = className?.replace("language-", "") || "javascript"; + try { + const data = JSON.parse(content) as Parameters< + typeof VisConvertError + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + "vis-dashboard": ({ + node, + className, + children, + style, + }) => { + const content = String(children); + const lang = className?.replace("language-", "") || "javascript"; + try { + const data = JSON.parse(content) as Parameters< + typeof VisDashboard + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + "vis-chart": ({ node, className, children, style }) => { + const content = String(children); + const lang = className?.replace("language-", "") || "javascript"; + try { + const data = JSON.parse(content) as Parameters< + typeof VisChart + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + "vis-plugin": ({ + node, + className, + children, + style, + }) => { + const content = String(children); + const lang = className?.replace("language-", "") || "javascript"; + try { + const data = JSON.parse(content) as Parameters< + typeof VisPlugin + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + "vis-code": ({ node, className, children, style, ...props }) => { + const content = String(children); + const lang = className?.replace("language-", "") || "javascript"; + + try { + const data = JSON.parse(content) as Parameters< + typeof VisCode + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + "vis-app-link": ({ + node, + className, + children, + style, + ...props + }) => { + const content = String(children); + const lang = className?.replace("language-", "") || "javascript"; + try { + const data = JSON.parse(content) as Parameters< + typeof VisAppLink + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + "vis-api-response": ({ + node, + className, + children, + style, + ...props + }) => { + const content = String(children); + const lang = className?.replace("language-", "") || "javascript"; + try { + const data = JSON.parse(content) as Parameters< + typeof VisResponse + >[0]["data"]; + return ; + } catch (e) { + return ; + } + }, + }, + defaultRenderer({ node, className, children, style, ...props }) { + + const content = String(children); + const lang = className?.replace("language-", "") || ""; + const { context, matchValues } = matchCustomeTagValues(content); + + + console.log(111, { node, className, children, style, ...props }, lang); + return ( + <> + {lang ? ( + + ) : ( + + {children} + + )} + + {matchValues.join("\n")} + + + ); + }, + }), +}; + const basicComponents: MarkdownComponent = { - code({ inline, node, className, children, style, ...props }) { - const content = String(children); - /** - * @description - * In some cases, tags are nested within code syntax, - * so it is necessary to extract the tags present in the code block and render them separately. - */ - const { context, matchValues } = matchCustomeTagValues(content); - const lang = className?.replace('language-', '') || 'javascript'; - - if (lang === 'agent-plans') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - - if (lang === 'agent-messages') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - - if (lang === 'vis-convert-error') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - - if (lang === 'vis-dashboard') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - - if (lang === 'vis-chart') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - - if (lang === 'vis-plugin') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - - if (lang === 'vis-code') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - - if (lang === 'vis-app-link') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - if (lang === 'vis-api-response') { - try { - const data = JSON.parse(content) as Parameters[0]['data']; - return ; - } catch (e) { - return ; - } - } - return ( - <> - {!inline ? ( - - ) : ( - - {children} - - )} - - {matchValues.join('\n')} - - - ); - }, + ...codeComponents, ul({ children }) { return
    {children}
; }, @@ -148,22 +243,46 @@ const basicComponents: MarkdownComponent = { return
    {children}
; }, li({ children, ordered }) { - return
  • {children}
  • ; + return ( +
  • + {children} +
  • + ); }, table({ children }) { - return {children}
    ; + return ( + + {children} +
    + ); }, thead({ children }) { - return {children}; + return ( + + {children} + + ); }, th({ children }) { return {children}; }, td({ children }) { - return {children}; + return ( + + {children} + + ); }, h1({ children }) { - return

    {children}

    ; + return ( +

    + {children} +

    + ); }, h2({ children }) { return

    {children}

    ; @@ -209,8 +328,8 @@ const basicComponents: MarkdownComponent = { ); }, button({ children, className, ...restProps }) { - if (className === 'chat-link') { - const msg = (restProps as any)?.['data-msg']; + if (className === "chat-link") { + const msg = (restProps as any)?.["data-msg"]; return {children}; } return ( @@ -223,32 +342,32 @@ const basicComponents: MarkdownComponent = { const returnSqlVal = (val: string) => { const punctuationMap: any = { - ',': ',', - '。': '.', - '?': '?', - '!': '!', - ':': ':', - ';': ';', - '“': '"', - '”': '"', - '‘': "'", - '’': "'", - '(': '(', - ')': ')', - '【': '[', - '】': ']', - '《': '<', - '》': '>', - '—': '-', - '、': ',', - '…': '...', + ",": ",", + "。": ".", + "?": "?", + "!": "!", + ":": ":", + ";": ";", + "“": '"', + "”": '"', + "‘": "'", + "’": "'", + "(": "(", + ")": ")", + "【": "[", + "】": "]", + "《": "<", + "》": ">", + "—": "-", + "、": ",", + "…": "...", }; - const regex = new RegExp(Object.keys(punctuationMap).join('|'), 'g'); + const regex = new RegExp(Object.keys(punctuationMap).join("|"), "g"); return val.replace(regex, (match) => punctuationMap[match]); }; const extraComponents: MarkdownComponent = { - 'chart-view': function ({ content, children }) { + "chart-view": function ({ content, children }) { let data: { data: Datum[]; type: BackEndChartType; @@ -259,11 +378,12 @@ const extraComponents: MarkdownComponent = { } catch (e) { console.log(e, content); data = { - type: 'response_table', - sql: '', + type: "response_table", + sql: "", data: [], }; } + console.log(111, data); const columns = data?.data?.[0] ? Object.keys(data?.data?.[0])?.map((item) => { @@ -276,25 +396,46 @@ const extraComponents: MarkdownComponent = { : []; const ChartItem = { - key: 'chart', - label: 'Chart', - children: , + key: "chart", + label: "Chart", + children: ( + + ), }; const SqlItem = { - key: 'sql', - label: 'SQL', - children: , + key: "sql", + label: "SQL", + children: ( + + ), }; const DataItem = { - key: 'data', - label: 'Data', - children: , + key: "data", + label: "Data", + children: ( +
    + ), }; - const TabItems: TabsProps['items'] = data?.type === 'response_table' ? [DataItem, SqlItem] : [ChartItem, SqlItem, DataItem]; + const TabItems: TabsProps["items"] = + data?.type === "response_table" + ? [DataItem, SqlItem] + : [ChartItem, SqlItem, DataItem]; return (
    - + {children}
    ); diff --git a/web/components/chat/chat-content/index.tsx b/web/components/chat/chat-content/index.tsx index b6db80cc5..961deeeb4 100644 --- a/web/components/chat/chat-content/index.tsx +++ b/web/components/chat/chat-content/index.tsx @@ -1,6 +1,6 @@ import { PropsWithChildren, ReactNode, memo, useContext, useMemo } from 'react'; import { CheckOutlined, ClockCircleOutlined, CloseOutlined, CodeOutlined, LoadingOutlined, RobotOutlined, UserOutlined } from '@ant-design/icons'; -import ReactMarkdown from 'react-markdown'; +import { GPTVis } from '@antv/gpt-vis'; import { IChatDialogueMessageSchema } from '@/types/chat'; import rehypeRaw from 'rehype-raw'; import classNames from 'classnames'; @@ -22,7 +22,7 @@ interface Props { onLinkClick?: () => void; } -type MarkdownComponent = Parameters['0']['components']; +type MarkdownComponent = Parameters["0"]["components"]; type DBGPTView = { name: string; @@ -112,15 +112,23 @@ function ChatContent({ children, content, isChartChat, onLinkClick }: PropsWithC const { bgClass, icon } = pluginViewStatusMapper[status] ?? {}; return (
    -
    +
    {name} {icon}
    {result ? (
    - - {result ?? ''} - + + {result ?? ""} +
    ) : (
    {err_msg}
    @@ -136,32 +144,48 @@ function ChatContent({ children, content, isChartChat, onLinkClick }: PropsWithC return (
    - {isRobot ? renderModelIcon(model_name) || : } + {isRobot ? ( + renderModelIcon(model_name) || + ) : ( + + )}
    {/* User Input */} - {!isRobot && typeof context === 'string' && context} + {!isRobot && typeof context === "string" && context} {/* Render Report */} - {isRobot && isChartChat && typeof context === 'object' && ( + {isRobot && isChartChat && typeof context === "object" && (
    {`[${context.template_name}]: `} - + - {context.template_introduce || 'More Details'} + {context.template_introduce || "More Details"}
    )} {/* Markdown */} - {isRobot && typeof context === 'string' && ( - + {isRobot && typeof context === "string" && ( + {formatMarkdownVal(value)} - + )} {!!relations?.length && (
    diff --git a/web/components/chat/chat-content/vis-code.tsx b/web/components/chat/chat-content/vis-code.tsx index bd4db9089..f2c8cf32f 100644 --- a/web/components/chat/chat-content/vis-code.tsx +++ b/web/components/chat/chat-content/vis-code.tsx @@ -1,4 +1,4 @@ -import ReactMarkdown from 'react-markdown'; +import { GPTVis } from '@antv/gpt-vis'; import remarkGfm from 'remark-gfm'; import markdownComponents from './config'; import { CodePreview } from './code-preview'; @@ -29,9 +29,12 @@ function VisCode({ data }: Props) { {data.code.map((item, index) => (
    { setShow(index); }} @@ -53,13 +56,18 @@ function VisCode({ data }: Props) {
    - {t('Terminal')} {data.exit_success ? : } + {t("Terminal")}{" "} + {data.exit_success ? ( + + ) : ( + + )}
    - + {data.log} - +
    diff --git a/web/components/chat/chat-content/vis-plugin.tsx b/web/components/chat/chat-content/vis-plugin.tsx index 17d34c166..a4976ab84 100644 --- a/web/components/chat/chat-content/vis-plugin.tsx +++ b/web/components/chat/chat-content/vis-plugin.tsx @@ -1,7 +1,7 @@ import { CheckOutlined, ClockCircleOutlined, CloseOutlined, LoadingOutlined } from '@ant-design/icons'; import classNames from 'classnames'; import { ReactNode } from 'react'; -import ReactMarkdown from 'react-markdown'; +import { GPTVis } from '@antv/gpt-vis'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; @@ -47,15 +47,24 @@ function VisPlugin({ data }: Props) { return (
    -
    +
    {data.name} {icon}
    {data.result ? (
    - - {data.result ?? ''} - + + {data.result ?? ""} +
    ) : (
    {data.err_msg}
    diff --git a/web/new-components/chat/content/ChatContent.tsx b/web/new-components/chat/content/ChatContent.tsx index 21c86a33d..3e98505f2 100644 --- a/web/new-components/chat/content/ChatContent.tsx +++ b/web/new-components/chat/content/ChatContent.tsx @@ -7,7 +7,7 @@ import Image from 'next/image'; import { useSearchParams } from 'next/navigation'; import React, { memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import ReactMarkdown from 'react-markdown'; +import { GPTVis } from '@antv/gpt-vis'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; @@ -42,7 +42,7 @@ type DBGPTView = { err_msg?: string; }; -type MarkdownComponent = Parameters['0']['components']; +type MarkdownComponent = Parameters["0"]["components"]; const pluginViewStatusMapper: Record = { todo: { @@ -143,15 +143,24 @@ const ChatContent: React.FC<{ const { bgClass, icon } = pluginViewStatusMapper[status] ?? {}; return (
    -
    +
    {name} {icon}
    {result ? (
    - - {result ?? ''} - + + {result ?? ""} +
    ) : (
    {err_msg}
    @@ -163,45 +172,68 @@ const ChatContent: React.FC<{ [cachePluginContext], ); - return (
    {/* icon */} -
    {isRobot ? : }
    -
    +
    + {isRobot ? : } +
    +
    {/* 用户提问 */} - {!isRobot &&
    {typeof context === 'string' && context}
    } + {!isRobot && ( +
    + {typeof context === "string" && context} +
    + )} {/* ai回答 */} {isRobot && (
    - {typeof context === 'object' && ( + {typeof context === "object" && (
    {`[${context.template_name}]: `} - + - {context.template_introduce || 'More Details'} + {context.template_introduce || "More Details"}
    )} - {typeof context === 'string' && scene === 'chat_agent' && ( - - {formatMarkdownValForAgent(value)} - - )} - {typeof context === 'string' && scene !== 'chat_agent' && ( - - {formatMarkdownVal(value)} - + {formatMarkdownValForAgent(value)} + + )} + {typeof context === "string" && scene !== "chat_agent" && ( +
    + + {formatMarkdownVal(value)} + +
    )} {/* 正在思考 */} {thinking && !context && (
    - {t('thinking')} + + {t("thinking")} +
    diff --git a/web/new-components/common/MarkdownContext.tsx b/web/new-components/common/MarkdownContext.tsx index 62b629aae..d92346e89 100644 --- a/web/new-components/common/MarkdownContext.tsx +++ b/web/new-components/common/MarkdownContext.tsx @@ -1,14 +1,18 @@ import markdownComponents from '@/components/chat/chat-content/config'; import React from 'react'; -import ReactMarkdown from 'react-markdown'; +import { GPTVis } from '@antv/gpt-vis'; import rehypeRaw from 'rehype-raw'; import remarkGfm from 'remark-gfm'; const MarkDownContext: React.FC<{ children: string }> = ({ children }) => { return ( - + {children} - + ); }; diff --git a/web/next.config.js b/web/next.config.js index 4ee768cca..58c398879 100644 --- a/web/next.config.js +++ b/web/next.config.js @@ -46,7 +46,7 @@ const nextConfig = { } }; -const withTM = require('next-transpile-modules')(['@berryv/g2-react','@antv/g2','react-syntax-highlighter']); +const withTM = require('next-transpile-modules')(['@berryv/g2-react','@antv/g2','react-syntax-highlighter', '@antv/gpt-vis']); module.exports = withTM({ ...nextConfig, diff --git a/web/package.json b/web/package.json index 8178d0168..0a3974ba3 100644 --- a/web/package.json +++ b/web/package.json @@ -16,6 +16,7 @@ "@ant-design/icons": "^5.2.5", "@antv/ava": "3.5.0-alpha.4", "@antv/g2": "^5.1.8", + "@antv/gpt-vis": "^0.0.5", "@antv/s2": "^1.51.2", "@berryv/g2-react": "^0.1.0", "@emotion/react": "^11.11.4", @@ -55,13 +56,12 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-i18next": "^13.2.0", - "react-markdown": "^8.0.7", "react-markdown-editor-lite": "^1.3.4", "react-syntax-highlighter": "^15.5.0", "react-virtualized": "^9.22.5", "reactflow": "^11.10.3", - "rehype-raw": "6.1.1", - "remark-gfm": "^3.0.1", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.0", "sequelize": "^6.33.0", "sql-formatter": "^12.2.4", "tailwindcss": "3.3.2", @@ -69,8 +69,8 @@ "typescript": "5.1.3" }, "devDependencies": { - "@types/cytoscape": "^3.21.0", "@types/crypto-js": "^4.1.2", + "@types/cytoscape": "^3.21.0", "@types/google-one-tap": "^1.2.4", "@types/lodash": "^4.14.195", "@types/markdown-it": "^14.1.1", @@ -94,5 +94,20 @@ }, "author": "", "license": "ISC", - "repository": "https://github.com/eosphoros-ai/DB-GPT-Web.git" + "repository": "https://github.com/eosphoros-ai/DB-GPT-Web.git", + "resolutions": { + "d3-color": "2", + "d3-array": "2", + "d3-shape": "2", + "d3-path": "2", + "d3-dsv": "2", + "d3-hierarchy": "2", + "d3-scale-chromatic": "2", + "d3-format": "2", + "d3-timer": "2", + "d3-dispatch": "2", + "d3-quadtree": "2", + "d3-force": "2", + "d3-geo": "2" + } }