diff --git a/.vscode/settings.json b/.vscode/settings.json index 34e6347a..829a7d0c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -71,5 +71,6 @@ }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" - } + }, + "cSpell.words": ["Chatdoc"] } diff --git a/CHANGELOG.json b/CHANGELOG.json index 7fe34ffc..0438aa5c 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -2,16 +2,46 @@ "name": "@acedatacloud/hub", "entries": [ { - "date": "Tue, 09 Jan 2024 19:15:08 GMT", + "date": "Mon, 29 Jan 2024 16:17:58 GMT", + "version": "1.0.1", + "tag": "@zhishuyun/hub_v1.0.1", + "comments": { + "patch": [ + { + "author": "cqc@germey.cn", + "package": "@zhishuyun/hub", + "commit": "5c925f97128e2fa12efe0e9f8d151419d1203dc3", + "comment": "fix chatdoc upload issue" + } + ] + } + }, + { + "date": "Sun, 28 Jan 2024 07:24:49 GMT", + "version": "1.0.0", + "tag": "@zhishuyun/hub_v1.0.0", + "comments": { + "major": [ + { + "author": "cqc@germey.cn", + "package": "@zhishuyun/hub", + "commit": "1a7fc4a59a1eeb11bbcdd668ff7fc325f940f5f0", + "comment": "add chatdoc feature" + } + ] + } + }, + { + "date": "Sun, 21 Jan 2024 03:37:14 GMT", "version": "0.12.2", - "tag": "@acedatacloud/hub_v0.12.2", + "tag": "@zhishuyun/hub_v0.12.2", "comments": { "patch": [ { - "author": "germey@acedata.cloud", - "package": "@acedatacloud/hub", - "commit": "f64be98a29b799cbce18c8b7c13e3385c7d065b3", - "comment": "migrate to acedata" + "author": "cqc@cuiqingcai.com", + "package": "@zhishuyun/hub", + "commit": "1dc324c35c1c9cf9b533a9e75eff8a25fda59f95", + "comment": "add docs for docker deploy" } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index c438b456..00fe72a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,32 @@ # Change Log - @acedatacloud/hub -This log was last generated on Tue, 09 Jan 2024 19:15:08 GMT and should not be manually modified. +This log was last generated on Mon, 29 Jan 2024 16:17:58 GMT and should not be manually modified. +## 1.0.1 + +Mon, 29 Jan 2024 16:17:58 GMT + +### Patches + +- fix chatdoc upload issue (cqc@germey.cn) + +## 1.0.0 + +Sun, 28 Jan 2024 07:24:49 GMT + +### Major changes + +- add chatdoc feature (cqc@germey.cn) + ## 0.12.2 -Tue, 09 Jan 2024 19:15:08 GMT +Sun, 21 Jan 2024 03:37:14 GMT ### Patches -- migrate to acedata (germey@acedata.cloud) +- add docs for docker deploy (cqc@cuiqingcai.com) ## 0.12.1 diff --git a/docs/deploy/Docker.md b/docs/deploy/Docker.md new file mode 100644 index 00000000..93ce71ef --- /dev/null +++ b/docs/deploy/Docker.md @@ -0,0 +1,109 @@ +# Docker Deployment + +## Requirements + +Install [Docker](https://www.docker.com/), to ensure you can execute `docker` command: + +``` +$ docker +Usage: docker [OPTIONS] COMMAND + +A self-sufficient runtime for containers + +Common Commands: + run Create and run a new container from an image + exec Execute a command in a running container + ps List containers + build Build an image from a Dockerfile + pull Download an image from a registry + push Upload an image to a registry +... +``` + +## Login to Docker + +Register an account in [Docker Hub](https://hub.docker.com/), then use command to login: + +``` +docker login +``` + +Then enter your username and password to login, then you will see like: + +``` +Login Succeeded +``` + +## Build with Docker + +``` +docker build -t / . +``` + +Replace `` to your username in Docker Hub, and replace `` with any name you want as the image name, like: + +``` +docker build -t foobar/hub . +``` + +Then you will see like this: + +``` +[+] Building 5.9s (8/16) docker:desktop-linux + => [build-stage 1/6] FROM docker.io/library/node:18@sha256:995a5f4314885452a4a785abc25a0fec40e26c346559e11e709d58bb7a927c 2.0s + => => resolve docker.io/library/node:18@sha256:995a5f4314885452a4a785abc25a0fec40e26c346559e11e709d58bb7a927cf4 0.0s + => => sha256:30d85599795460b2d9d24c6b87c53ec60555b601705cc83bea31632240500980 0B / 64.14MB 2.0s + => => sha256:995a5f4314885452a4a785abc25a0fec40e26c346559e11e709d58bb7a927cf4 1.21kB / 1.21kB 0.0s + => => sha256:084b3c822003a20d41f793237286e112d1b5a1c0c7b8b04cb53a17a963a76ed7 2.00kB / 2.00kB 0.0s + => => sha256:ef847f8b5ae3554df13851034f22683a8b9aef31b3659033211775d8d6cb6b79 7.34kB / 7.34kB + ... +=> [build-stage 4/6] RUN yarn 83.5s + => [build-stage 5/6] COPY . . 0.3s + => [build-stage 6/6] RUN yarn build 16.3s + => [production-stage 2/3] COPY --from=build-stage /app/dist /usr/share/nginx/html 0.0s + => [production-stage 3/3] COPY nginx.conf /etc/nginx/conf.d/default.conf 0.0s + => exporting to image 0.0s + => => exporting layers 0.0s + => => writing image sha256:f4e06895b43560b3cd43970c8942f35d56643959de5272eebee1a887a1b7798a 0.0s + => => naming to docker.io/germey/hub +``` + +## Push Docker + +``` +docker push / +``` + +Now you have pushed your image to Docker Hub, then you can deploy this image to any server. + +## Deploy Docker + +In your server machine, you can then pull this image and then run it + +``` +docker run -d -p 8000:80 / +``` + +Then visit [http://localhost:8000](http://localhost:8000) you will see it. + +## Configure HTTPS + +If you want to configure HTTPS and domain, like example.abc.com, you can install Nginx to forward the traffic from Docker: + +Apply the HTTPS cert for your domain, you will have 2 files, one is cert, the other is private key, like `example.abc.com.pem` and `example.abc.com.key`, change the nginx conf file as below: + +``` +server { + listen 443; + server_name example.abc.com; + + ssl_certificate /path/to/your/example.abc.com.pem; + ssl_certificate_key /path/to/your/example.abc.com.key; + + location / { + proxy_pass http://127.0.0.1:8000; + } +} +``` + +Also please set the Domain to server's ip address, then restart nginx, it will work. diff --git a/src/components/chat/Message.vue b/src/components/chat/Message.vue index 47ca3cf9..3e4c20d6 100644 --- a/src/components/chat/Message.vue +++ b/src/components/chat/Message.vue @@ -33,7 +33,7 @@ import AnsweringMark from './AnsweringMark.vue'; import copy from 'copy-to-clipboard'; import { ElAlert, ElButton } from 'element-plus'; import MarkdownRenderer from '@/components/common/MarkdownRenderer.vue'; -import { IApplication, IChatMessage, IChatMessageState, ROLE_ASSISTANT } from '@/operators'; +import { IApplication, IChatMessage, IChatMessageState } from '@/operators'; import CopyToClipboard from '../common/CopyToClipboard.vue'; import { ERROR_CODE_API_ERROR, @@ -43,7 +43,8 @@ import { ERROR_CODE_TIMEOUT, ERROR_CODE_TOO_MANY_REQUESTS, ERROR_CODE_UNKNOWN, - ERROR_CODE_USED_UP + ERROR_CODE_USED_UP, + ROLE_ASSISTANT } from '@/constants'; import message from '@/i18n/zh/common/message'; import { ROUTE_CONSOLE_APPLICATION_BUY } from '@/router'; @@ -125,9 +126,6 @@ export default defineComponent({ } }); } - // onStop() { - // this.$emit('stop'); - // } } }); diff --git a/src/components/chatdoc/AnsweringMark.vue b/src/components/chatdoc/AnsweringMark.vue new file mode 100644 index 00000000..91e9102a --- /dev/null +++ b/src/components/chatdoc/AnsweringMark.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/src/components/chatdoc/Conversations.vue b/src/components/chatdoc/Conversations.vue new file mode 100644 index 00000000..ec9851ce --- /dev/null +++ b/src/components/chatdoc/Conversations.vue @@ -0,0 +1,198 @@ + + + + + diff --git a/src/components/chatdoc/CreateRepository.vue b/src/components/chatdoc/CreateRepository.vue new file mode 100644 index 00000000..178ee1d9 --- /dev/null +++ b/src/components/chatdoc/CreateRepository.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/components/chatdoc/InputBox.vue b/src/components/chatdoc/InputBox.vue new file mode 100644 index 00000000..b5c0f7de --- /dev/null +++ b/src/components/chatdoc/InputBox.vue @@ -0,0 +1,155 @@ + + + + + + + diff --git a/src/components/chatdoc/Message.vue b/src/components/chatdoc/Message.vue new file mode 100644 index 00000000..23941d6f --- /dev/null +++ b/src/components/chatdoc/Message.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/src/components/chatdoc/SidePanel.vue b/src/components/chatdoc/SidePanel.vue new file mode 100644 index 00000000..c2f70a44 --- /dev/null +++ b/src/components/chatdoc/SidePanel.vue @@ -0,0 +1,192 @@ + + + + + diff --git a/src/components/chatdoc/UploadDocument.vue b/src/components/chatdoc/UploadDocument.vue new file mode 100644 index 00000000..da6e0278 --- /dev/null +++ b/src/components/chatdoc/UploadDocument.vue @@ -0,0 +1,108 @@ + + + + + diff --git a/src/components/common/Navigator.vue b/src/components/common/Navigator.vue index 73a2e71a..90b53e92 100644 --- a/src/components/common/Navigator.vue +++ b/src/components/common/Navigator.vue @@ -76,6 +76,10 @@ import { defineComponent } from 'vue'; import { ElButton, ElTooltip, ElMenu, ElMenuItem } from 'element-plus'; import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; import { + ROUTE_CHATDOC_INDEX, + ROUTE_CHATDOC_CONVERSATION, + ROUTE_CHATDOC_MANAGE, + ROUTE_CHATDOC_SETTING, ROUTE_CHAT_CONVERSATION, ROUTE_CHAT_CONVERSATION_NEW, ROUTE_CONSOLE_ROOT, @@ -106,7 +110,6 @@ export default defineComponent({ }, displayName: this.$t('common.nav.chat'), icon: 'fa-regular fa-comment', - image: 'https://cdn.acedata.cloud/9ad12c99b2.png/thumb_100x100', routes: [ROUTE_CHAT_CONVERSATION, ROUTE_CHAT_CONVERSATION_NEW] }); } @@ -117,11 +120,21 @@ export default defineComponent({ }, displayName: this.$t('common.nav.midjourney'), icon: 'fa-solid fa-palette', - image: 'https://cdn.acedata.cloud/83ee211091.png/thumb_100x100', routes: [ROUTE_MIDJOURNEY_INDEX, ROUTE_MIDJOURNEY_HISTORY] }); } + if (this.$config.navigation?.chatdoc) { + links.push({ + route: { + name: ROUTE_CHATDOC_INDEX + }, + displayName: this.$t('common.nav.chatdoc'), + icon: 'fa-solid fa-file-lines', + routes: [ROUTE_CHATDOC_INDEX, ROUTE_CHATDOC_CONVERSATION, ROUTE_CHATDOC_MANAGE, ROUTE_CHATDOC_SETTING] + }); + } + return { links, activeIndex: this.$route.name as string @@ -173,6 +186,7 @@ export default defineComponent({ await this.$store.dispatch('resetAll'); await this.$store.dispatch('chat/resetAll'); await this.$store.dispatch('midjourney/resetAll'); + await this.$store.dispatch('chatdoc/resetAll'); }, onConsole() { this.$router.push({ name: ROUTE_CONSOLE_ROOT }); diff --git a/src/config.ts b/src/config.ts index 95f056db..cdd15d9d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -43,6 +43,11 @@ export default { */ midjourney: true, + /** + * Show chatdoc entry in left navigation. + */ + chatdoc: true, + /** * Show console entry in left navigation. */ diff --git a/src/constants/action.ts b/src/constants/action.ts new file mode 100644 index 00000000..cc2601fc --- /dev/null +++ b/src/constants/action.ts @@ -0,0 +1,6 @@ +export const ACTION_CREATE = 'create'; +export const ACTION_UPDATE = 'update'; +export const ACTION_DELETE = 'delete'; +export const ACTION_RETRIEVE = 'retrieve'; +export const ACTION_RETRIEVE_BATCH = 'retrieve_batch'; +export const ACTION_RETRIEVE_ALL = 'retrieve_all'; diff --git a/src/constants/index.ts b/src/constants/index.ts index 37770926..3e85f69a 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,2 +1,4 @@ export * from './errorCode'; export * from './endpoint'; +export * from './role'; +export * from './action'; diff --git a/src/constants/role.ts b/src/constants/role.ts new file mode 100644 index 00000000..badc4577 --- /dev/null +++ b/src/constants/role.ts @@ -0,0 +1,3 @@ +export const ROLE_SYSTEM = 'system'; +export const ROLE_ASSISTANT = 'assistant'; +export const ROLE_USER = 'user'; diff --git a/src/i18n/zh/chatdoc/button.ts b/src/i18n/zh/chatdoc/button.ts new file mode 100644 index 00000000..77d211c6 --- /dev/null +++ b/src/i18n/zh/chatdoc/button.ts @@ -0,0 +1,3 @@ +export default { + uploadDocuments: '上传文档' +}; diff --git a/src/i18n/zh/chatdoc/field.ts b/src/i18n/zh/chatdoc/field.ts new file mode 100644 index 00000000..4d690507 --- /dev/null +++ b/src/i18n/zh/chatdoc/field.ts @@ -0,0 +1,13 @@ +export default { + fileName: '文件名', + createdAt: '创建时间', + fileExtension: '文件类型', + fileUrl: '文件链接', + fileSize: '文件大小', + state: '状态', + stateProcessing: '学习中', + stateCompleted: '学习完成', + stateFailed: '学习失败', + name: '名称', + description: '描述' +}; diff --git a/src/i18n/zh/chatdoc/index.ts b/src/i18n/zh/chatdoc/index.ts new file mode 100644 index 00000000..ea8125ce --- /dev/null +++ b/src/i18n/zh/chatdoc/index.ts @@ -0,0 +1,7 @@ +import message from './message'; +import title from './title'; +import nav from './nav'; +import field from './field'; +import button from './button'; + +export default { message, title, nav, field, button }; diff --git a/src/i18n/zh/chatdoc/message.ts b/src/i18n/zh/chatdoc/message.ts new file mode 100644 index 00000000..ded4d279 --- /dev/null +++ b/src/i18n/zh/chatdoc/message.ts @@ -0,0 +1,31 @@ +export default { + introductionForKnowledge: '知识库中可添加文档,在机器人回答时,可运用库中的知识进行回复。', + introductionForRepository: + '知识库是一组文档的集合,您可以在知识库中添加文档,机器人在回答时,会从知识库中的文档中进行回复。', + uploadDocumentsExceed: '上传文档数量超过限制', + uploadDocumentsError: '上传文档失败', + uploadDocumentsSuccess: '上传文档成功', + createDocumentSuccess: '学习文档成功', + startCreateDocument: '开始学习文档...', + createDocumentError: '学习文档失败', + dragOrClickToUpload: '拖拽或点击上传文档', + learningDocument: '学习中,请稍后...', + startNewChat: '开始新会话', + errorApiError: '回答失败,请稍后重试', + errorBadRequest: '请求内容不规范,请重新提问', + errorNoConversation: '对话内容不存在或者已经过期,请发起新的会话', + errorContentTooLarge: '问题内容过长,请缩短后重试', + errorTooManyRequests: '您的操作过于频繁,请稍后重试', + errorUsedUp: '您的套餐次数已经用完,请购买更多次数继续使用', + errorUnknown: '服务器出现未知错误,请稍后重试或联系客服', + errorTimeout: '回答问题超时,请稍后重试', + errorNotApplied: '您尚未申请该服务,请先申请再继续提问', + confirmDelete: '确定删除', + howToUse: '按 Shift+Enter 键可以换行', + createRepositorySuccess: '创建知识库成功', + createRepositoryFailed: '创建知识库失败', + deleteRepositorySuccess: '删除知识库成功', + deleteDocumentSuccess: '删除文档成功', + currentRepository: '当前知识库', + nameRequired: '名称不能为空' +}; diff --git a/src/i18n/zh/chatdoc/nav.ts b/src/i18n/zh/chatdoc/nav.ts new file mode 100644 index 00000000..074d9042 --- /dev/null +++ b/src/i18n/zh/chatdoc/nav.ts @@ -0,0 +1,5 @@ +export default { + chat: '对话', + setting: '设置', + manage: '管理' +}; diff --git a/src/i18n/zh/chatdoc/title.ts b/src/i18n/zh/chatdoc/title.ts new file mode 100644 index 00000000..55b480a2 --- /dev/null +++ b/src/i18n/zh/chatdoc/title.ts @@ -0,0 +1,5 @@ +export default { + manage: '管理知识库', + createRepository: '创建知识库', + repositories: '知识库列表' +}; diff --git a/src/i18n/zh/common/button.ts b/src/i18n/zh/common/button.ts index c7edd2bd..e01182bc 100644 --- a/src/i18n/zh/common/button.ts +++ b/src/i18n/zh/common/button.ts @@ -29,5 +29,6 @@ export default { buyMore: '购买更多', update: '更新', copy: '复制', - stop: '停止' + stop: '停止', + create: '创建' }; diff --git a/src/i18n/zh/common/nav.ts b/src/i18n/zh/common/nav.ts index efb0f05f..93831309 100644 --- a/src/i18n/zh/common/nav.ts +++ b/src/i18n/zh/common/nav.ts @@ -15,5 +15,6 @@ export default { console: '控制台', newChat: '新建对话', logOut: '退出登录', - distribution: '分销赚钱' + distribution: '分销赚钱', + chatdoc: 'AI 知识库' }; diff --git a/src/i18n/zh/index.ts b/src/i18n/zh/index.ts index 4a689165..5dc52174 100644 --- a/src/i18n/zh/index.ts +++ b/src/i18n/zh/index.ts @@ -8,9 +8,11 @@ import console from './console'; import order from './order'; import distribution from './distribution'; import user from './user'; +import chatdoc from './chatdoc'; export default { chat, + chatdoc, user, order, console, diff --git a/src/layouts/Chatdoc.vue b/src/layouts/Chatdoc.vue new file mode 100644 index 00000000..0dc27c04 --- /dev/null +++ b/src/layouts/Chatdoc.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/src/operators/chat/constants.ts b/src/operators/chat/constants.ts index 072fb288..c5a25f33 100644 --- a/src/operators/chat/constants.ts +++ b/src/operators/chat/constants.ts @@ -1,9 +1,5 @@ import { IChatModel } from './models'; -export const ROLE_SYSTEM = 'system'; -export const ROLE_ASSISTANT = 'assistant'; -export const ROLE_USER = 'user'; - export const CHAT_MODEL_NAME_CHATGPT = 'chatgpt'; export const CHAT_MODEL_NAME_CHATGPT4 = 'chatgpt4'; export const CHAT_MODEL_NAME_CHATGPT_16K = 'chatgpt-16k'; diff --git a/src/operators/chat/models.ts b/src/operators/chat/models.ts index fc04a9dc..905ad2f7 100644 --- a/src/operators/chat/models.ts +++ b/src/operators/chat/models.ts @@ -1,13 +1,11 @@ +import { ROLE_ASSISTANT, ROLE_SYSTEM, ROLE_USER } from '@/constants'; import { CHAT_MODEL_NAME_CHATGPT, CHAT_MODEL_NAME_CHATGPT4, CHAT_MODEL_NAME_CHATGPT4_BROWSING, CHAT_MODEL_NAME_CHATGPT4_VISION, CHAT_MODEL_NAME_CHATGPT_16K, - CHAT_MODEL_NAME_CHATGPT_BROWSING, - ROLE_ASSISTANT, - ROLE_SYSTEM, - ROLE_USER + CHAT_MODEL_NAME_CHATGPT_BROWSING } from './constants'; export type IChatModelName = @@ -25,7 +23,7 @@ export interface IChatModel { description: string; } -export interface IError { +interface IError { code: string; detail?: string; } diff --git a/src/operators/chatdoc/constants.ts b/src/operators/chatdoc/constants.ts new file mode 100644 index 00000000..60bf2841 --- /dev/null +++ b/src/operators/chatdoc/constants.ts @@ -0,0 +1,4 @@ +export const API_ID_CHATDOC_REPOSITORIES = 'e22e9e3f-5594-4c48-9284-c1847c22c65f'; +export const API_ID_CHATDOC_DOCUMENTS = 'afc7917f-d89f-4dc9-95c2-863936b02cad'; +export const API_ID_CHATDOC_CONVERSATIONS = 'afc7917f-d89f-4dc9-95c2-863936b02cad'; +export const API_ID_CHATDOC_CHAT = '099eafc8-8167-4557-b8f2-47867ca76e24'; diff --git a/src/operators/chatdoc/index.ts b/src/operators/chatdoc/index.ts new file mode 100644 index 00000000..4a6cbae5 --- /dev/null +++ b/src/operators/chatdoc/index.ts @@ -0,0 +1,2 @@ +export * from './models'; +export * from './operator'; diff --git a/src/operators/chatdoc/models.ts b/src/operators/chatdoc/models.ts new file mode 100644 index 00000000..ce07606e --- /dev/null +++ b/src/operators/chatdoc/models.ts @@ -0,0 +1,76 @@ +import { ACTION_CREATE, ACTION_DELETE, ACTION_UPDATE, ROLE_ASSISTANT, ROLE_SYSTEM, ROLE_USER } from '@/constants'; + +export interface IError { + code: string; + detail?: string; +} + +export interface IChatdocRepository { + id: string; + name?: string; + description?: string; + deleting?: boolean; + editing?: boolean; + documents?: IChatdocDocument[]; + conversations?: IChatdocConversation[]; +} + +export interface IChatdocDocument { + id: string; + repository_id: string; + file_url: string; + file_name: string; +} + +export interface IChatdocConversation { + id: string; + repository_id: string; + messages: IChatdocMessage[]; + editing?: boolean; + deleting?: boolean; +} + +export interface IChatdocMessage { + content?: string; + error?: IError; + state?: IChatdocMessageState; + role?: typeof ROLE_SYSTEM | typeof ROLE_ASSISTANT | typeof ROLE_USER; +} + +export enum IChatdocMessageState { + PENDING = 'pending', + ANSWERING = 'answering', + FINISHED = 'finished', + FAILED = 'failed' +} + +export interface IChatdocChatRequest { + repository_id: string; + messages: IChatdocMessage[]; + temperature?: number; + knowledge_fallback?: boolean; +} + +export interface IChatdocDocumentRequest extends IChatdocDocument { + action: typeof ACTION_CREATE | typeof ACTION_UPDATE | typeof ACTION_DELETE; + callback_url?: string; +} + +export interface IChatdocDocumentResponse extends IChatdocDocument {} + +export type IChatdocConversationsResponse = IChatdocConversation[]; + +export interface IChatdocRepositoryRequest extends IChatdocRepository { + action: typeof ACTION_CREATE | typeof ACTION_UPDATE | typeof ACTION_DELETE; +} + +export interface IChatdocRepositoryResponse extends IChatdocRepository {} +export type IChatdocRepositoriesResponse = IChatdocRepository[]; +export type IChatdocDocumentsResponse = IChatdocDocument[]; + +export interface IChatdocChatResponse { + answer: string; + delta_answer: string; + repository_id?: string; + conversation_id?: string; +} diff --git a/src/operators/chatdoc/operator.ts b/src/operators/chatdoc/operator.ts new file mode 100644 index 00000000..3837b3da --- /dev/null +++ b/src/operators/chatdoc/operator.ts @@ -0,0 +1,300 @@ +import axios, { AxiosProgressEvent, AxiosResponse } from 'axios'; +import { + IChatdocChatResponse, + IChatdocConversation, + IChatdocConversationsResponse, + IChatdocDocumentResponse, + IChatdocDocumentsResponse, + IChatdocRepositoriesResponse, + IChatdocRepositoryResponse +} from './models'; +import { ACTION_RETRIEVE_ALL, ACTION_UPDATE, BASE_URL_API } from '@/constants'; +import { ACTION_CREATE, ACTION_DELETE, ACTION_RETRIEVE, ACTION_RETRIEVE_BATCH } from '@/constants'; + +class ChatdocOperator { + async createRepository( + payload: { + name: string; + description?: string; + }, + options: { token: string } + ): Promise> { + return await axios.post( + `/chatdoc/repositories`, + { + action: ACTION_CREATE, + name: payload.name, + description: payload.description + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async deleteRepository(id: string, options: { token: string }): Promise> { + return await axios.post( + `/chatdoc/repositories`, + { + action: ACTION_DELETE, + id + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async getRepository(id: string, options: { token: string }): Promise> { + return await axios.post( + `/chatdoc/repositories`, + { + action: ACTION_RETRIEVE, + id + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async getAllRepositories(options: { token: string }): Promise> { + return await axios.post( + `/chatdoc/repositories`, + { + action: ACTION_RETRIEVE_ALL + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async getAllDocuments( + repositoryId: string, + options: { token: string } + ): Promise> { + return await axios.post( + `/chatdoc/documents`, + { + action: ACTION_RETRIEVE_ALL, + repository_id: repositoryId + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async getAllConversations(repositoryId: string): Promise> { + return await axios.post( + `/chatdoc/conversations`, + { + action: ACTION_RETRIEVE_ALL, + repository_id: repositoryId + }, + { + headers: { + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async getRepositories(ids: string[]): Promise> { + return await axios.post( + `/chatdoc/repositories`, + { + action: ACTION_RETRIEVE_BATCH, + ids + }, + { + headers: { + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async createDocument( + payload: { + repositoryId: string; + fileUrl: string; + fileName: string; + }, + options: { token: string } + ): Promise> { + return await axios.post( + `/chatdoc/documents`, + { + action: ACTION_CREATE, + repository_id: payload.repositoryId, + file_url: payload.fileUrl, + file_name: payload.fileName + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async retrieveDocument(id: string, options: { token: string }): Promise> { + return await axios.post( + `/chatdoc/documents`, + { + action: ACTION_RETRIEVE, + id + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async retrieveConversation(id: string, options: { token: string }): Promise> { + return await axios.post( + `/chatdoc/conversations`, + { + action: ACTION_RETRIEVE, + id + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async deleteDocument(id: string, options: { token: string }): Promise> { + return await axios.post( + `/chatdoc/documents`, + { + action: ACTION_DELETE, + id + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async updateConversation(payload: IChatdocConversation) { + return await axios.post( + `/chatdoc/conversations`, + { + action: ACTION_UPDATE, + id: payload.id, + messages: payload.messages + }, + { + headers: { + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async deleteConversation(id: string): Promise> { + return await axios.post( + `/chatdoc/conversations`, + { + action: ACTION_DELETE, + id + }, + { + headers: { + accept: 'application/json', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API + } + ); + } + + async chat( + payload: { repositoryId: string; question: string; conversationId?: string; knowledgeFallback?: boolean }, + options: { token: string; stream: (response: IChatdocChatResponse) => void } + ): Promise> { + return await axios.post( + `/chatdoc/chat`, + { + repository_id: payload.repositoryId, + question: payload.question, + conversation_id: payload.conversationId, + stateful: true + }, + { + headers: { + authorization: `Bearer ${options.token}`, + accept: 'application/x-ndjson', + 'content-type': 'application/json' + }, + baseURL: BASE_URL_API, + responseType: 'stream', + onDownloadProgress: ({ event }: AxiosProgressEvent) => { + const response = event.target.response; + const lines = response.split('\r\n').filter((line: string) => !!line); + const lastLine = lines[lines.length - 1]; + if (lastLine) { + const jsonData = JSON.parse(lastLine); + if (options?.stream) { + options?.stream(jsonData as IChatdocChatResponse); + } + } + } + } + ); + } +} + +export const chatdocOperator = new ChatdocOperator(); diff --git a/src/operators/index.ts b/src/operators/index.ts index d207241d..d8e4c031 100644 --- a/src/operators/index.ts +++ b/src/operators/index.ts @@ -7,3 +7,4 @@ export * from './usage'; export * from './api'; export * from './order'; export * from './distribution'; +export * from './chatdoc'; diff --git a/src/operators/midjourney/operator.ts b/src/operators/midjourney/operator.ts index be991e6d..334df2c2 100644 --- a/src/operators/midjourney/operator.ts +++ b/src/operators/midjourney/operator.ts @@ -1,4 +1,4 @@ -import axios, { AxiosResponse } from 'axios'; +import axios, { AxiosProgressEvent, AxiosResponse } from 'axios'; import { IMidjourneyImagineRequest, IMidjourneyImagineResponse, IMidjourneyImagineTask } from './models'; import { BASE_URL_API } from '@/constants'; @@ -54,7 +54,7 @@ class MidjourneyOperator { }, baseURL: options.endpoint, responseType: 'stream', - onDownloadProgress: (event) => { + onDownloadProgress: ({ event }: AxiosProgressEvent) => { const response = event.target.response; const lines = response.split('\r\n').filter((line: string) => !!line); const lastLine = lines[lines.length - 1]; diff --git a/src/pages/chat/Conversation.vue b/src/pages/chat/Conversation.vue index d674f1e4..3086e92c 100644 --- a/src/pages/chat/Conversation.vue +++ b/src/pages/chat/Conversation.vue @@ -39,9 +39,8 @@ import axios from 'axios'; import { defineComponent } from 'vue'; import Message from '@/components/chat/Message.vue'; +import { ROLE_ASSISTANT, ROLE_USER } from '@/constants'; import { - ROLE_ASSISTANT, - ROLE_USER, IChatModel, IApplication, IChatMessageState, diff --git a/src/pages/chatdoc/Conversation.vue b/src/pages/chatdoc/Conversation.vue new file mode 100644 index 00000000..d999f956 --- /dev/null +++ b/src/pages/chatdoc/Conversation.vue @@ -0,0 +1,291 @@ + + + + + diff --git a/src/pages/chatdoc/Index.vue b/src/pages/chatdoc/Index.vue new file mode 100644 index 00000000..303f22fe --- /dev/null +++ b/src/pages/chatdoc/Index.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/src/pages/chatdoc/Manage.vue b/src/pages/chatdoc/Manage.vue new file mode 100644 index 00000000..a70686a4 --- /dev/null +++ b/src/pages/chatdoc/Manage.vue @@ -0,0 +1,175 @@ + + + + + diff --git a/src/pages/chatdoc/Setting.vue b/src/pages/chatdoc/Setting.vue new file mode 100644 index 00000000..c4cf7fe8 --- /dev/null +++ b/src/pages/chatdoc/Setting.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/plugins/font-awesome.ts b/src/plugins/font-awesome.ts index 128feb1c..781d6fd7 100644 --- a/src/plugins/font-awesome.ts +++ b/src/plugins/font-awesome.ts @@ -51,13 +51,16 @@ import { faCube as faSolidCube, faShieldHalved as faSolidShieldHalved, faCubes as faSolidCubes, + faFileLines as faSolidFileLines, faLink as faSolidLink, faWandMagic as faSolidWandMagic } from '@fortawesome/free-solid-svg-icons'; + library.add(faRegularCopy); library.add(faSolidStore); library.add(faSolidChevronRight); library.add(faSolidCube); +library.add(faSolidFileLines); library.add(faSolidCompass); library.add(faSolidPaperclip); library.add(faSolidXmark); diff --git a/src/router/chatdoc.ts b/src/router/chatdoc.ts new file mode 100644 index 00000000..a9f858a7 --- /dev/null +++ b/src/router/chatdoc.ts @@ -0,0 +1,42 @@ +import { + ROUTE_CHATDOC_CONVERSATION, + ROUTE_CHATDOC_CONVERSATION_NEW, + ROUTE_CHATDOC_INDEX, + ROUTE_CHATDOC_MANAGE, + ROUTE_CHATDOC_SETTING +} from './constants'; + +export default { + path: '/chatdoc', + meta: { + auth: true + }, + component: () => import('@/layouts/Main.vue'), + children: [ + { + path: '', + name: ROUTE_CHATDOC_INDEX, + component: () => import('@/pages/chatdoc/Index.vue') + }, + { + path: 'repository/:repositoryId/conversation', + name: ROUTE_CHATDOC_CONVERSATION_NEW, + component: () => import('@/pages/chatdoc/Conversation.vue') + }, + { + path: 'repository/:repositoryId/conversation/:conversationId', + name: ROUTE_CHATDOC_CONVERSATION, + component: () => import('@/pages/chatdoc/Conversation.vue') + }, + { + path: 'repository/:repositoryId/manage', + name: ROUTE_CHATDOC_MANAGE, + component: () => import('@/pages/chatdoc/Manage.vue') + }, + { + path: 'repository/:repositoryId', + name: ROUTE_CHATDOC_SETTING, + component: () => import('@/pages/chatdoc/Setting.vue') + } + ] +}; diff --git a/src/router/constants.ts b/src/router/constants.ts index 14ac189a..b7d54b1b 100644 --- a/src/router/constants.ts +++ b/src/router/constants.ts @@ -9,6 +9,12 @@ export const ROUTE_CHAT_CONVERSATION_NEW = 'chat-conversation-new'; export const ROUTE_MIDJOURNEY_INDEX = 'midjourney-index'; export const ROUTE_MIDJOURNEY_HISTORY = 'midjourney-history'; +export const ROUTE_CHATDOC_INDEX = 'chatdoc-index'; +export const ROUTE_CHATDOC_CONVERSATION = 'chatdoc-conversation'; +export const ROUTE_CHATDOC_CONVERSATION_NEW = 'chatdoc-conversation-new'; +export const ROUTE_CHATDOC_SETTING = 'chatdoc-setting'; +export const ROUTE_CHATDOC_MANAGE = 'chatdoc-knowledge'; + export const ROUTE_CONSOLE_ROOT = 'console-root'; export const ROUTE_CONSOLE_ORDER_LIST = 'console-order-list'; export const ROUTE_CONSOLE_ORDER_DETAIL = 'console-order-detail'; diff --git a/src/router/index.ts b/src/router/index.ts index b2207ddc..da3e5a8c 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -4,6 +4,7 @@ import console from './console'; import chat from './chat'; import midjourney from './midjourney'; import distribution from './distribution'; +import chatdoc from './chatdoc'; import { ROUTE_CHAT_CONVERSATION_NEW, ROUTE_INDEX } from './constants'; @@ -16,6 +17,7 @@ const routes = [ } }, console, + chatdoc, auth, chat, midjourney, diff --git a/src/router/midjourney.ts b/src/router/midjourney.ts index c25dd2a8..89d7932b 100644 --- a/src/router/midjourney.ts +++ b/src/router/midjourney.ts @@ -2,6 +2,9 @@ import { ROUTE_MIDJOURNEY_HISTORY, ROUTE_MIDJOURNEY_INDEX } from './constants'; export default { path: '/midjourney', + meta: { + auth: true + }, component: () => import('@/layouts/Main.vue'), children: [ { diff --git a/src/store/chatdoc/actions.ts b/src/store/chatdoc/actions.ts new file mode 100644 index 00000000..21fb9cac --- /dev/null +++ b/src/store/chatdoc/actions.ts @@ -0,0 +1,274 @@ +import { IApplication, apiUsageOperator, applicationOperator } from '@/operators'; +import { IRootState, Status } from '../common/models'; +import { ActionContext } from 'vuex'; +import { log } from '@/utils/log'; +import { IChatdocState } from './models'; +import { IChatdocConversation, IChatdocDocument, IChatdocRepository } from '@/operators/chatdoc/models'; +import { chatdocOperator } from '@/operators/chatdoc/operator'; +import { + API_ID_CHATDOC_CHAT, + API_ID_CHATDOC_DOCUMENTS, + API_ID_CHATDOC_REPOSITORIES +} from '@/operators/chatdoc/constants'; + +export const setApplications = async ({ commit }: any, payload: IApplication[]): Promise => { + commit('setApplications', payload); +}; + +export const setRepository = async ({ commit }: any, payload: { repository: IChatdocRepository }): Promise => { + commit('setRepository', payload); +}; + +export const getApplications = async ({ + commit, + rootState +}: ActionContext): Promise => { + log(getApplications, 'start to get application for chat'); + commit('setGetApplicationsStatus', Status.Request); + const { data: applications } = await applicationOperator.getAll({ + user_id: rootState.user.id, + api_id: [API_ID_CHATDOC_REPOSITORIES, API_ID_CHATDOC_CHAT, API_ID_CHATDOC_DOCUMENTS] + }); + log(getApplications, 'get application for chat success', applications); + commit('setGetApplicationsStatus', Status.Success); + commit('setApplications', applications?.items); + return applications.items; +}; + +export const resetAll = ({ commit }: ActionContext): void => { + commit('resetAll'); +}; + +export const getRepositories = async ({ + commit, + state +}: ActionContext): Promise => { + log(getRepositories, 'start to get repositories'); + commit('setGetRepositoriesStatus', Status.Request); + const applications = state.applications; + console.log('applications', applications); + const application = applications?.find( + (application: IApplication) => application.api?.id === API_ID_CHATDOC_REPOSITORIES + ); + console.log('application', application); + const token = application?.credential?.token; + if (!token) { + commit('setRepositories', undefined); + return []; + } + const repositories = ( + await chatdocOperator.getAllRepositories({ + token + }) + ).data; + commit('setGetRepositoriesStatus', Status.Success); + log(getRepositories, 'get repositories success', repositories); + commit('setRepositories', repositories); + return repositories; +}; + +export const deleteRepository = async ( + { state }: ActionContext, + payload: { + id: string; + } +): Promise => { + log(deleteRepository, 'start to delete repository'); + const applications = state.applications; + console.log('applications', applications); + const application = applications?.find( + (application: IApplication) => application.api?.id === API_ID_CHATDOC_REPOSITORIES + ); + console.log('application', application); + const token = application?.credential?.token; + if (!token) { + return Promise.reject('no token'); + } + const repository = ( + await chatdocOperator.deleteRepository(payload.id, { + token + }) + ).data; + log(deleteRepository, 'delete repository success', repository); + return repository; +}; + +export const deleteDocument = async ( + { state }: ActionContext, + payload: { + id: string; + } +): Promise => { + log(deleteDocument, 'start to delete document'); + const applications = state.applications; + console.log('applications', applications); + const application = applications?.find( + (application: IApplication) => application.api?.id === API_ID_CHATDOC_DOCUMENTS + ); + console.log('application', application); + const token = application?.credential?.token; + if (!token) { + return Promise.reject('no token'); + } + const document = ( + await chatdocOperator.deleteDocument(payload.id, { + token + }) + ).data; + log(deleteRepository, 'delete document success', document); + return document; +}; + +export const createRepository = async ( + { state }: ActionContext, + payload: { + name: string; + description?: string; + } +): Promise => { + log(createRepository, 'start to create repository'); + const applications = state.applications; + console.log('applications', applications); + const application = applications?.find( + (application: IApplication) => application.api?.id === API_ID_CHATDOC_REPOSITORIES + ); + console.log('application', application); + const token = application?.credential?.token; + if (!token) { + return Promise.reject('no token'); + } + const repository = ( + await chatdocOperator.createRepository(payload, { + token + }) + ).data; + log(createRepository, 'create repository success', repository); + return repository; +}; + +export const createDocument = async ( + { state }: ActionContext, + payload: { + repositoryId: string; + fileUrl: string; + fileName: string; + } +): Promise => { + log(createDocument, 'start to create document'); + const applications = state.applications; + console.log('applications', applications); + const application = applications?.find( + (application: IApplication) => application.api?.id === API_ID_CHATDOC_DOCUMENTS + ); + console.log('application', application); + const token = application?.credential?.token; + if (!token) { + return Promise.reject('no token'); + } + const document = ( + await chatdocOperator.createDocument(payload, { + token + }) + ).data; + log(createDocument, 'create document success', document); + return document; +}; + +export const getDocuments = async ( + { commit, state }: ActionContext, + payload: { repositoryId: string } +): Promise => { + log(getRepositories, 'start to get documents'); + const applications = state.applications; + console.log('applications', applications); + const application = applications?.find( + (application: IApplication) => application.api?.id === API_ID_CHATDOC_DOCUMENTS + ); + console.log('application for getDocuments', application); + const token = application?.credential?.token; + if (!token) { + commit('setRepository', { + id: payload.repositoryId, + documents: [] + }); + return []; + } + const documents = ( + await chatdocOperator.getAllDocuments(payload.repositoryId, { + token + }) + ).data; + log(getRepositories, 'get documents success', documents); + commit('setRepository', { + id: payload.repositoryId, + documents: documents + }); + return documents; +}; + +export const getConversations = async ( + { commit, state }: ActionContext, + payload: { repositoryId: string } +): Promise => { + log(getConversations, 'start to get conversations'); + const applications = state.applications; + console.log('applications', applications); + const application = applications?.find((application: IApplication) => application.api?.id === API_ID_CHATDOC_CHAT); + console.log('application for getConversations', application); + const token = application?.credential?.token; + if (!token) { + commit('setRepository', { + id: payload.repositoryId, + conversations: [] + }); + return []; + } + const conversations = (await chatdocOperator.getAllConversations(payload.repositoryId)).data; + log(getConversations, 'get conversations success', conversations); + commit('setRepository', { + id: payload.repositoryId, + conversations: conversations + }); + return conversations; +}; + +export const getRepository = async ( + { commit, state }: ActionContext, + payload: { id: string } +): Promise => { + log(getRepository, 'start to get repository'); + // commit('setGetRepositoryStatus', Status.Request); + const applications = state.applications; + const application = applications?.find( + (application: IApplication) => application.api?.id === API_ID_CHATDOC_REPOSITORIES + ); + const token = application?.credential?.token; + if (!token) { + commit('setRepository', { id: payload.id }); + return Promise.reject('no token'); + } + const repository = ( + await chatdocOperator.getRepository(payload.id, { + token + }) + ).data; + // commit('setGetRepositoryStatus', Status.Success); + log(getRepository, 'get repository success', repository); + commit('setRepository', repository); + return repository; +}; + +export default { + createRepository, + setApplications, + getApplications, + getRepositories, + deleteRepository, + getRepository, + setRepository, + getConversations, + getDocuments, + resetAll, + createDocument, + deleteDocument +}; diff --git a/src/store/chatdoc/index.ts b/src/store/chatdoc/index.ts new file mode 100644 index 00000000..5e3daa32 --- /dev/null +++ b/src/store/chatdoc/index.ts @@ -0,0 +1,14 @@ +import { Module } from 'vuex'; +import actions from './actions'; +import mutations from './mutations'; +import state from './state'; +import { IChatdocState } from './models'; + +export const chatdoc: Module = { + namespaced: true, + state, + mutations, + actions +}; + +export default chatdoc; diff --git a/src/store/chatdoc/models.ts b/src/store/chatdoc/models.ts new file mode 100644 index 00000000..1c1b842c --- /dev/null +++ b/src/store/chatdoc/models.ts @@ -0,0 +1,10 @@ +import { IApplication } from '@/operators'; +import { Status } from '../common/models'; +import { IChatdocRepository } from '@/operators/chatdoc/models'; + +export interface IChatdocState { + applications: IApplication[] | undefined; + getApplicationsStatus: Status | undefined; + repositories: IChatdocRepository[] | undefined; + getRepositoriesStatus: Status | undefined; +} diff --git a/src/store/chatdoc/mutations.ts b/src/store/chatdoc/mutations.ts new file mode 100644 index 00000000..f22f1f86 --- /dev/null +++ b/src/store/chatdoc/mutations.ts @@ -0,0 +1,74 @@ +import { IApplication, IChatConversation, IChatModel } from '@/operators'; +import { IChatdocState } from './models'; +import { Status } from '../common/models'; +import { IChatdocRepository } from '@/operators/chatdoc/models'; +import { log } from '@/utils'; + +export const resetAll = (state: IChatdocState): void => { + state.applications = []; + state.getApplicationsStatus = Status.None; + state.repositories = []; +}; + +export const setApplications = (state: IChatdocState, payload: IApplication[]): void => { + state.applications = payload; +}; + +export const setGetApplicationsStatus = (state: IChatdocState, payload: Status): void => { + state.getApplicationsStatus = payload; +}; + +export const setRepositories = (state: IChatdocState, payload: IChatdocRepository[]): void => { + const currentRepositories = state.repositories; + if (currentRepositories) { + // merge current repositories into payload + payload.forEach((repository: IChatdocRepository) => { + const index = currentRepositories.findIndex((item: IChatdocRepository) => item.id === repository.id); + if (index !== -1) { + payload[index] = { + ...currentRepositories[index], + ...repository + }; + } + }); + state.repositories = payload; + return; + } else { + // set the repositories + state.repositories = payload; + } +}; + +export const setRepository = (state: IChatdocState, payload: IChatdocRepository): void => { + log(setRepository, 'mutation', payload); + // find the repository and set it + const repository = payload; + const repositories = state.repositories; + if (!repositories) { + log(setRepository, 'no repositories'); + return; + } + const index = repositories.findIndex((item: IChatdocRepository) => item.id === repository.id); + if (index === -1) { + log(setRepository, 'no repository found'); + return; + } + log(setRepository, 'set repository for index', index, repository); + repositories[index] = { + ...repositories[index], + ...repository + }; +}; + +export const setGetRepositoriesStatus = (state: IChatdocState, payload: Status): void => { + state.getRepositoriesStatus = payload; +}; + +export default { + setApplications, + setGetApplicationsStatus, + setRepositories, + setRepository, + setGetRepositoriesStatus, + resetAll +}; diff --git a/src/store/chatdoc/persist.ts b/src/store/chatdoc/persist.ts new file mode 100644 index 00000000..aae50635 --- /dev/null +++ b/src/store/chatdoc/persist.ts @@ -0,0 +1 @@ +export default ['chatdoc.repositories', 'chatdoc.applications']; diff --git a/src/store/chatdoc/state.ts b/src/store/chatdoc/state.ts new file mode 100644 index 00000000..bd2d2673 --- /dev/null +++ b/src/store/chatdoc/state.ts @@ -0,0 +1,10 @@ +import { IChatdocState } from './models'; + +export default (): IChatdocState => { + return { + applications: undefined, + getApplicationsStatus: undefined, + repositories: undefined, + getRepositoriesStatus: undefined + }; +}; diff --git a/src/store/common/models.ts b/src/store/common/models.ts index 073fe91c..82b04b68 100644 --- a/src/store/common/models.ts +++ b/src/store/common/models.ts @@ -1,6 +1,7 @@ import { IUser } from '@/operators'; import { IMidjourneyState } from '../midjourney/models'; import { IChatState } from '../chat/models'; +import { IChatdocState } from '../chatdoc/models'; export enum Status { Request = 'Request', @@ -28,4 +29,5 @@ export interface ICommonState { export interface IRootState extends ICommonState { midjourney: IMidjourneyState; chat: IChatState; + chatdoc: IChatdocState; } diff --git a/src/store/index.ts b/src/store/index.ts index 3a41d69b..afeb697e 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -2,20 +2,23 @@ import { createStore } from 'vuex'; import createPersistedState from 'vuex-persistedstate'; import midjourney from './midjourney'; import chat from './chat'; +import chatdoc from './chatdoc'; import root from './common'; import persistChat from './chat/persist'; import persistMidjourney from './midjourney/persist'; +import persistChatdoc from './chatdoc/persist'; import persistRoot from './common/persist'; const store = createStore({ ...root, modules: { midjourney, - chat + chat, + chatdoc }, plugins: [ createPersistedState({ - paths: [...persistRoot, ...persistChat, ...persistMidjourney] + paths: [...persistRoot, ...persistChat, ...persistMidjourney, ...persistChatdoc] }) ] });