You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import { MessageType, SharedFrom } from '@/constants/chat';
  2. import { useCreateNextSharedConversation } from '@/hooks/chat-hooks';
  3. import {
  4. useSelectDerivedMessages,
  5. useSendMessageWithSse,
  6. } from '@/hooks/logic-hooks';
  7. import { Message } from '@/interfaces/database/chat';
  8. import { message } from 'antd';
  9. import { get } from 'lodash';
  10. import trim from 'lodash/trim';
  11. import { useCallback, useEffect, useState } from 'react';
  12. import { useSearchParams } from 'umi';
  13. import { v4 as uuid } from 'uuid';
  14. import { useHandleMessageInputChange } from './hooks';
  15. const isCompletionError = (res: any) =>
  16. res && (res?.response.status !== 200 || res?.data?.code !== 0);
  17. export const useSendButtonDisabled = (value: string) => {
  18. return trim(value) === '';
  19. };
  20. export const useGetSharedChatSearchParams = () => {
  21. const [searchParams] = useSearchParams();
  22. const data_prefix = 'data_';
  23. const data = Object.fromEntries(
  24. searchParams
  25. .entries()
  26. .filter(([key, value]) => key.startsWith(data_prefix))
  27. .map(([key, value]) => [key.replace(data_prefix, ''), value]),
  28. );
  29. return {
  30. from: searchParams.get('from') as SharedFrom,
  31. sharedId: searchParams.get('shared_id'),
  32. locale: searchParams.get('locale'),
  33. data: data,
  34. visibleAvatar: searchParams.get('visible_avatar')
  35. ? searchParams.get('visible_avatar') !== '1'
  36. : true,
  37. };
  38. };
  39. export const useSendSharedMessage = () => {
  40. const {
  41. from,
  42. sharedId: conversationId,
  43. data: data,
  44. } = useGetSharedChatSearchParams();
  45. const { createSharedConversation: setConversation } =
  46. useCreateNextSharedConversation();
  47. const { handleInputChange, value, setValue } = useHandleMessageInputChange();
  48. const { send, answer, done } = useSendMessageWithSse(
  49. `/ss-ragflow-api/api/v1/${from === SharedFrom.Agent ? 'agentbots' : 'chatbots'}/${conversationId}/completions`,
  50. );
  51. const {
  52. derivedMessages,
  53. ref,
  54. removeLatestMessage,
  55. addNewestAnswer,
  56. addNewestQuestion,
  57. } = useSelectDerivedMessages();
  58. const [hasError, setHasError] = useState(false);
  59. const sendMessage = useCallback(
  60. async (message: Message, id?: string) => {
  61. const res = await send({
  62. conversation_id: id ?? conversationId,
  63. quote: true,
  64. question: message.content,
  65. session_id: get(derivedMessages, '0.session_id'),
  66. });
  67. if (isCompletionError(res)) {
  68. // cancel loading
  69. setValue(message.content);
  70. removeLatestMessage();
  71. }
  72. },
  73. [send, conversationId, derivedMessages, setValue, removeLatestMessage],
  74. );
  75. const handleSendMessage = useCallback(
  76. async (message: Message) => {
  77. if (conversationId !== '') {
  78. sendMessage(message);
  79. } else {
  80. const data = await setConversation('user id');
  81. if (data.code === 0) {
  82. const id = data.data.id;
  83. sendMessage(message, id);
  84. }
  85. }
  86. },
  87. [conversationId, setConversation, sendMessage],
  88. );
  89. const fetchSessionId = useCallback(async () => {
  90. const payload = { question: '' };
  91. const ret = await send({ ...payload, ...data });
  92. if (isCompletionError(ret)) {
  93. message.error(ret?.data.message);
  94. setHasError(true);
  95. }
  96. }, [send]);
  97. useEffect(() => {
  98. fetchSessionId();
  99. }, [fetchSessionId, send]);
  100. useEffect(() => {
  101. if (answer.answer) {
  102. addNewestAnswer(answer);
  103. }
  104. }, [answer, addNewestAnswer]);
  105. const handlePressEnter = useCallback(
  106. (documentIds: string[]) => {
  107. if (trim(value) === '') return;
  108. const id = uuid();
  109. if (done) {
  110. setValue('');
  111. addNewestQuestion({
  112. content: value,
  113. doc_ids: documentIds,
  114. id,
  115. role: MessageType.User,
  116. });
  117. handleSendMessage({
  118. content: value.trim(),
  119. id,
  120. role: MessageType.User,
  121. });
  122. }
  123. },
  124. [addNewestQuestion, done, handleSendMessage, setValue, value],
  125. );
  126. return {
  127. handlePressEnter,
  128. handleInputChange,
  129. value,
  130. sendLoading: !done,
  131. ref,
  132. loading: false,
  133. derivedMessages,
  134. hasError,
  135. };
  136. };