chatInput.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { useState } from "react";
  2. import TextInputBar from "./TextInputBar";
  3. import VoiceInputBar from "./VoiceInputBar";
  4. import { textChat } from "@/service/bot";
  5. import { useTextChat } from "@/store/textChat";
  6. import { TAgentDetail } from "@/types/agent";
  7. import { delay, getLoginId, isSuccess } from "@/utils";
  8. import { EAI_MODEL } from "@/consts/enum";
  9. import { useUnload } from "@tarojs/taro";
  10. import { EChatRole, EContentType } from "@/types/bot";
  11. import { saveMessageToServer } from './message'
  12. import { getRecommendPrompt } from "@/service/bot"
  13. interface Props {
  14. agent: TAgentDetail | null;
  15. setShowWelcome?: (b: boolean) => void;
  16. setIsVoice?: (b: boolean) => void;
  17. setDisabled?: (b: boolean) => void;
  18. }
  19. let stopReceiveChunk: (() => void) | undefined;
  20. export const useChatInput = ({ agent, setShowWelcome, setDisabled, }: Props) => {
  21. const {
  22. pushRobotMessage,
  23. updateRobotMessage,
  24. getCurrentRobotMessage,
  25. updateRobotReasoningMessage,
  26. pushMessage,
  27. updateMessage,
  28. deleteMessage,
  29. setQuestions,
  30. questions,
  31. } = useTextChat();
  32. let myMsgUk = '';
  33. let mySessionId = '';
  34. const chatWithGpt = async (message: string, sessionId: string, msgUk: string) => {
  35. setShowWelcome?.(false)
  36. setQuestions([])
  37. let currentRobotMsgUk = "";
  38. await delay(300);
  39. setDisabled?.(true);
  40. if (!agent?.agentId) {
  41. return;
  42. }
  43. const loginId = getLoginId();
  44. if (!loginId) {
  45. return;
  46. }
  47. // const greeting = "欢迎光临我的智能体,你想问什么?";
  48. // {
  49. // content: greeting,
  50. // contentType: EContentType.TextPlain,
  51. // role: EChatRole.System,
  52. // },
  53. const newMsg = {
  54. content: message,
  55. contentType: EContentType.TextPlain,
  56. role: EChatRole.User,
  57. }
  58. saveMessageToServer({
  59. loginId,
  60. messages: [{
  61. ...newMsg,
  62. isStreaming: false,
  63. msgUk,
  64. }],
  65. agentId: agent.agentId,
  66. sessionId,
  67. })
  68. // 发起文本聊天
  69. stopReceiveChunk = textChat({
  70. params: {
  71. agentId: agent.agentId,
  72. isEnableOutputAudioStream: false,
  73. isEnableSearch: false,
  74. isEnableThinking: false,
  75. loginId,
  76. messages: [newMsg],
  77. sessionId,
  78. },
  79. onStart: () => {
  80. currentRobotMsgUk = pushRobotMessage({
  81. role: EChatRole.Assistant,
  82. saveStatus: 2,
  83. content: "",
  84. reasoningContent: "",
  85. robot: {
  86. avatar: agent?.avatarUrl ?? "",
  87. name: agent?.name ?? "",
  88. agentId: agent?.agentId ?? "",
  89. },
  90. });
  91. },
  92. onReceived: (m) => {
  93. console.log("received:", m);
  94. if (m.reasoningContent) {
  95. updateRobotReasoningMessage(
  96. currentRobotMsgUk,
  97. m.reasoningContent,
  98. m.body,
  99. );
  100. } else {
  101. updateRobotMessage(m.content, m.body);
  102. }
  103. },
  104. onFinished: async () => {
  105. const currentRobotMessage = getCurrentRobotMessage();
  106. console.log("回复完毕 ok, 当前robotmessage: ", currentRobotMessage);
  107. if(!agent.agentId){
  108. return
  109. }
  110. setDisabled?.(false);
  111. // 如果没有任何回答,则显示
  112. if (!currentRobotMessage?.content?.length) {
  113. updateRobotMessage("服务器繁忙...");
  114. return
  115. }
  116. // 将智能体的回答保存至服务器
  117. // currentRobotMessage.content 保存的是当前完整的智能体回复信息文本
  118. await saveMessageToServer({
  119. loginId,
  120. messages: [{
  121. content: currentRobotMessage.content ?? currentRobotMessage?.body?.content,
  122. contentType: currentRobotMessage?.body?.contentType ?? EContentType.TextPlain,
  123. isStreaming: false,
  124. role: currentRobotMessage.role,
  125. msgUk: currentRobotMessage.msgUk,
  126. }],
  127. agentId: agent.agentId,
  128. sessionId,
  129. })
  130. const response = await getRecommendPrompt({
  131. agentId: agent.agentId,
  132. sessionId,
  133. })
  134. // todo: 如果用户快速输入需要将前面的问题答案丢弃,根据 currentRobotMessage.msgUk 来设置 questions
  135. if(isSuccess(response.status)){
  136. setQuestions(response.data.questions)
  137. }
  138. },
  139. onError: () => {
  140. deleteMessage(currentRobotMsgUk);
  141. setDisabled?.(false);
  142. },
  143. });
  144. };
  145. const handleVoiceSend = (message: string) => {
  146. updateMessage(message, myMsgUk);
  147. chatWithGpt(message, mySessionId, myMsgUk);
  148. };
  149. const handleOnSend = async (message: string) => {
  150. if(!agent?.agentId){
  151. return
  152. }
  153. const {sessionId, msgUk} = pushMessage(message);
  154. chatWithGpt(message, sessionId, msgUk);
  155. };
  156. // 推一个自己的空气泡框
  157. const handleBeforeSend = () => {
  158. if(!agent?.agentId){
  159. return
  160. }
  161. const {sessionId, msgUk} = pushMessage("");
  162. myMsgUk = msgUk
  163. mySessionId = sessionId
  164. };
  165. // 发生主意识别错误时,删除当前自己发出的气泡框
  166. const handleVoiceError = () => {
  167. deleteMessage(myMsgUk);
  168. };
  169. useUnload(() => {
  170. if (stopReceiveChunk) {
  171. stopReceiveChunk();
  172. }
  173. });
  174. return {
  175. setQuestions,
  176. handleVoiceSend,
  177. handleOnSend,
  178. questions,
  179. handleBeforeSend,
  180. handleVoiceError,
  181. }
  182. }