class-rxjs-chat-completion.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import { Observable, from, of } from 'rxjs';
  2. import { switchMap, map, catchError, finalize } from 'rxjs/operators';
  3. import { ResultsPage } from '../../study/results/results.page';
  4. import{ParseObject} from'../../study/results/results-post'
  5. import Parse from "parse"
  6. Parse.initialize("dev");
  7. Parse.serverURL="http://web2023.fmode.cn:9999/parse";
  8. export interface TestRxjsChatMessage {
  9. role: string;
  10. content: string;
  11. }
  12. export class TestRxjsChatCompletion {
  13. messageList: Array<TestRxjsChatMessage>;
  14. messageAiReply = "";
  15. lastCompletionContent:string = ""; // 新增属性以保存最后的对话结果
  16. async SaveMessage()
  17. {
  18. let savemessage = new ResultsPage();
  19. let chatResult=this.lastCompletionContent;
  20. console.log(this.lastCompletionContent)
  21. console.log("savemessage.currentObjectId",ResultsPage.currentObjectId)
  22. async function SaveChatResult()
  23. {
  24. let YCX:any = new ParseObject("MagicMirror")
  25. YCX = await YCX.get(ResultsPage.currentObjectId)
  26. YCX.set(
  27. {
  28. result:chatResult,
  29. } )
  30. YCX.saveChat(ResultsPage.currentObjectId);
  31. // console.log(YCX);
  32. }
  33. SaveChatResult();
  34. }
  35. constructor(messageList: Array<TestRxjsChatMessage>) {
  36. this.messageList = messageList;
  37. }
  38. createCompletionByStream(options?:{
  39. model?:string
  40. }): Observable<{ content: string, cumulativeContent: string, done: boolean }> {
  41. const token = localStorage.getItem("token");
  42. const bodyJson = {
  43. "token": `Bearer ${token}`,
  44. "messages": this.messageList,
  45. "model": options?.model || "fmode-3.6-16k",
  46. "temperature": 0.5,
  47. "presence_penalty": 0,
  48. "frequency_penalty": 0,
  49. "top_p": 1,
  50. "stream": true
  51. };
  52. return from(fetch("https://test.fmode.cn/api/apig/aigc/gpt/v1/chat/completions", {
  53. "headers": {
  54. "accept": "text/event-stream",
  55. "sec-fetch-dest": "empty",
  56. "sec-fetch-mode": "cors",
  57. "sec-fetch-site": "same-site"
  58. },
  59. "referrer": "https://ai.fmode.cn/",
  60. "referrerPolicy": "strict-origin-when-cross-origin",
  61. "body": JSON.stringify(bodyJson),
  62. "method": "POST",
  63. "mode": "cors",
  64. "credentials": "omit"
  65. })).pipe(
  66. switchMap(response => {
  67. const reader = response.body?.getReader();
  68. if (!reader) {
  69. throw new Error("Failed to get the response reader.");
  70. }
  71. const decoder = new TextDecoder();
  72. let buffer = "";
  73. let messageAiReply = "";
  74. let messageIndex = this.messageList.length;
  75. return new Observable<{ content: string, cumulativeContent: string, done: boolean }>(observer => {
  76. const read = () => {
  77. reader.read().then(({ done, value }) => {
  78. if (done) {
  79. observer.next({ content: "", cumulativeContent: messageAiReply, done: true });
  80. observer.complete();
  81. return;
  82. }
  83. buffer += decoder.decode(value);
  84. let messages = buffer.split("\n");
  85. for (let i = 0; i < messages.length - 1; i++) {
  86. let message = messages[i];
  87. let dataText = message.replace("data: ", "");
  88. if (dataText.startsWith("{")) {
  89. try {
  90. let dataJson = JSON.parse(dataText);
  91. let content = dataJson?.choices?.[0]?.delta?.content || "";
  92. messageAiReply += content;
  93. this.lastCompletionContent = messageAiReply;
  94. this.messageList[messageIndex] = {
  95. role: "assistant",
  96. content: messageAiReply
  97. };
  98. observer.next({ content, cumulativeContent: messageAiReply, done: false });
  99. } catch (err) { }
  100. }
  101. if (dataText.startsWith("[")) {
  102. this.messageList[messageIndex] = {
  103. role: "assistant",
  104. content: messageAiReply
  105. };
  106. observer.next({ content: "", cumulativeContent: messageAiReply, done: true });
  107. }
  108. buffer = buffer.slice(message.length + 1);
  109. }
  110. read();
  111. }).catch(err => observer.error(err));
  112. };
  113. read();
  114. });
  115. }),
  116. catchError(err => {
  117. console.error(err);
  118. return of({ content: "", cumulativeContent: "", done: true });
  119. }),
  120. finalize(() => {
  121. console.log("Stream completed");
  122. console.log(this.lastCompletionContent)
  123. this.SaveMessage()
  124. })
  125. );
  126. }
  127. }