diff --git a/web/package-lock.json b/web/package-lock.json index 7c5bfe1264b95ec2a84ff83c34b20b13ffc87983..4c91d5f50ee84d91e45c6511ef1d24c35e025e25 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -25,6 +25,7 @@ "react-markdown": "^9.0.1", "react-pdf-highlighter": "^6.1.0", "react-string-replace": "^1.1.1", + "remark-gfm": "^4.0.0", "umi": "^4.0.90", "umi-request": "^1.4.0", "unist-util-visit-parents": "^6.0.1", @@ -11087,6 +11088,11 @@ "node": ">=0.10.0" } }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==" + }, "node_modules/mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmmirror.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -11103,6 +11109,25 @@ "safe-buffer": "^5.1.2" } }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + } + }, "node_modules/mdast-util-from-markdown": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", @@ -11122,6 +11147,77 @@ "unist-util-stringify-position": "^4.0.0" } }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + } + }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", @@ -11315,6 +11411,92 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", + "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", + "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", @@ -14952,6 +15134,19 @@ "node": ">= 0.10" } }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz", @@ -14975,6 +15170,16 @@ "vfile": "^6.0.0" } }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmmirror.com/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + } + }, "node_modules/remove-accents": { "version": "0.4.2", "resolved": "https://registry.npmmirror.com/remove-accents/-/remove-accents-0.4.2.tgz", diff --git a/web/package.json b/web/package.json index a2c6c15afadda4b038a35202dfcfac23c87dead4..251860cd9e61ca546187e71ba595ff801bad3212 100644 --- a/web/package.json +++ b/web/package.json @@ -29,6 +29,7 @@ "react-markdown": "^9.0.1", "react-pdf-highlighter": "^6.1.0", "react-string-replace": "^1.1.1", + "remark-gfm": "^4.0.0", "umi": "^4.0.90", "umi-request": "^1.4.0", "unist-util-visit-parents": "^6.0.1", diff --git a/web/src/pages/chat/chat-configuration-modal/index.tsx b/web/src/pages/chat/chat-configuration-modal/index.tsx index 8e0f523b730c9bc56fec9113f702c0bd0b2d5d6a..91281e56ce22ec48a1ae985a22ed6e61da9bcf4d 100644 --- a/web/src/pages/chat/chat-configuration-modal/index.tsx +++ b/web/src/pages/chat/chat-configuration-modal/index.tsx @@ -1,5 +1,9 @@ import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg'; import { IModalManagerChildrenProps } from '@/components/modal-manager'; +import { + ModelVariableType, + settledModelVariableMap, +} from '@/constants/knowledge'; import { IDialog } from '@/interfaces/database/chat'; import { Divider, Flex, Form, Modal, Segmented, UploadFile } from 'antd'; import { SegmentedValue } from 'antd/es/segmented'; @@ -130,6 +134,9 @@ const ChatConfigurationModal = ({ } form.setFieldsValue({ ...initialDialog, + llm_setting: + initialDialog.llm_setting ?? + settledModelVariableMap[ModelVariableType.Precise], icon: fileList, llm_id: initialDialog.llm_id ?? modelId, }); diff --git a/web/src/pages/chat/chat-configuration-modal/model-setting.tsx b/web/src/pages/chat/chat-configuration-modal/model-setting.tsx index 1324441c900920aef13c0e4d39082d5d43cd37fe..44d6a82a96b76354cff329ba677d681e80e52c35 100644 --- a/web/src/pages/chat/chat-configuration-modal/model-setting.tsx +++ b/web/src/pages/chat/chat-configuration-modal/model-setting.tsx @@ -75,7 +75,7 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'temperature']} noStyle - rules={[{ required: true, message: 'Province is required' }]} + rules={[{ required: true, message: 'Temperature is required' }]} > <Slider className={styles.variableSlider} max={1} step={0.01} /> </Form.Item> @@ -83,7 +83,7 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'temperature']} noStyle - rules={[{ required: true, message: 'Street is required' }]} + rules={[{ required: true, message: 'Temperature is required' }]} > <InputNumber className={styles.sliderInputNumber} @@ -103,7 +103,7 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'top_p']} noStyle - rules={[{ required: true, message: 'Province is required' }]} + rules={[{ required: true, message: 'Top_p is required' }]} > <Slider className={styles.variableSlider} max={1} step={0.01} /> </Form.Item> @@ -111,7 +111,7 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'top_p']} noStyle - rules={[{ required: true, message: 'Street is required' }]} + rules={[{ required: true, message: 'Top_p is required' }]} > <InputNumber className={styles.sliderInputNumber} @@ -135,7 +135,9 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'presence_penalty']} noStyle - rules={[{ required: true, message: 'Province is required' }]} + rules={[ + { required: true, message: 'Presence Penalty is required' }, + ]} > <Slider className={styles.variableSlider} max={1} step={0.01} /> </Form.Item> @@ -143,7 +145,9 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'presence_penalty']} noStyle - rules={[{ required: true, message: 'Street is required' }]} + rules={[ + { required: true, message: 'Presence Penalty is required' }, + ]} > <InputNumber className={styles.sliderInputNumber} @@ -167,7 +171,9 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'frequency_penalty']} noStyle - rules={[{ required: true, message: 'Province is required' }]} + rules={[ + { required: true, message: 'Frequency Penalty is required' }, + ]} > <Slider className={styles.variableSlider} max={1} step={0.01} /> </Form.Item> @@ -175,7 +181,9 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'frequency_penalty']} noStyle - rules={[{ required: true, message: 'Street is required' }]} + rules={[ + { required: true, message: 'Frequency Penalty is required' }, + ]} > <InputNumber className={styles.sliderInputNumber} @@ -195,7 +203,7 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'max_tokens']} noStyle - rules={[{ required: true, message: 'Province is required' }]} + rules={[{ required: true, message: 'Max Tokens is required' }]} > <Slider className={styles.variableSlider} max={2048} /> </Form.Item> @@ -203,7 +211,7 @@ const ModelSetting = ({ show, form }: ISegmentedContentProps) => { <Form.Item name={['llm_setting', 'max_tokens']} noStyle - rules={[{ required: true, message: 'Street is required' }]} + rules={[{ required: true, message: 'Max Tokens is required' }]} > <InputNumber className={styles.sliderInputNumber} diff --git a/web/src/pages/chat/chat-container/index.less b/web/src/pages/chat/chat-container/index.less index 14556a142d7798b1401b3e90483c972f6ebde00a..7a840f4ce5af8173da72ccb8f9ea57d7150fde2c 100644 --- a/web/src/pages/chat/chat-container/index.less +++ b/web/src/pages/chat/chat-container/index.less @@ -15,7 +15,7 @@ width: 70%; } .messageItemSectionRight { - width: 30%; + width: 40%; } .messageItemContent { display: inline-flex; diff --git a/web/src/pages/chat/chat-container/index.tsx b/web/src/pages/chat/chat-container/index.tsx index 34bb6ddf94097edc8cf6b55829fe973ebeb17ca7..1cca00fe8864f5ce0f37a7844cba38ecdeab0290 100644 --- a/web/src/pages/chat/chat-container/index.tsx +++ b/web/src/pages/chat/chat-container/index.tsx @@ -1,8 +1,14 @@ import { ReactComponent as AssistantIcon } from '@/assets/svg/assistant.svg'; +import Image from '@/components/image'; +import NewDocumentLink from '@/components/new-document-link'; +import DocumentPreviewer from '@/components/pdf-previewer'; import { MessageType } from '@/constants/chat'; +import { useSelectFileThumbnails } from '@/hooks/knowledgeHook'; import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; import { useSelectUserInfo } from '@/hooks/userSettingHook'; import { IReference, Message } from '@/interfaces/database/chat'; +import { IChunk } from '@/interfaces/database/knowledge'; +import { InfoCircleOutlined } from '@ant-design/icons'; import { Avatar, Button, @@ -16,7 +22,10 @@ import { } from 'antd'; import classNames from 'classnames'; import { ChangeEventHandler, useCallback, useMemo, useState } from 'react'; +import Markdown from 'react-markdown'; import reactStringReplace from 'react-string-replace'; +import remarkGfm from 'remark-gfm'; +import { visitParents } from 'unist-util-visit-parents'; import { useClickDrawer, useFetchConversationOnMount, @@ -24,14 +33,6 @@ import { useSendMessage, } from '../hooks'; -import Image from '@/components/image'; -import NewDocumentLink from '@/components/new-document-link'; -import DocumentPreviewer from '@/components/pdf-previewer'; -import { useSelectFileThumbnails } from '@/hooks/knowledgeHook'; -import { IChunk } from '@/interfaces/database/knowledge'; -import { InfoCircleOutlined } from '@ant-design/icons'; -import Markdown from 'react-markdown'; -import { visitParents } from 'unist-util-visit-parents'; import styles from './index.less'; const reg = /(#{2}\d+\${2})/g; @@ -178,6 +179,7 @@ const MessageItem = ({ {item.content !== '' ? ( <Markdown rehypePlugins={[rehypeWrapReference]} + remarkPlugins={[remarkGfm]} components={ { 'custom-typography': ({ @@ -243,7 +245,9 @@ const ChatContainer = () => { }; const handleInputChange: ChangeEventHandler<HTMLInputElement> = (e) => { - setValue(e.target.value); + const value = e.target.value.trim(); + const nextValue = value.replaceAll('\\n', '\n'); + setValue(nextValue); }; return (