utils.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { addFileInfos, sortAgentSorts } from '../../tools/utils'
  2. import { UUID_NIL } from './constants'
  3. import type { ChatItem } from './types'
  4. async function decodeBase64AndDecompress(base64String: string) {
  5. const binaryString = atob(base64String)
  6. const compressedUint8Array = Uint8Array.from(binaryString, char => char.charCodeAt(0))
  7. const decompressedStream = new Response(compressedUint8Array).body?.pipeThrough(new DecompressionStream('gzip'))
  8. const decompressedArrayBuffer = await new Response(decompressedStream).arrayBuffer()
  9. return new TextDecoder().decode(decompressedArrayBuffer)
  10. }
  11. function getProcessedInputsFromUrlParams(): Record<string, any> {
  12. const urlParams = new URLSearchParams(window.location.search)
  13. const inputs: Record<string, any> = {}
  14. urlParams.forEach(async (value, key) => {
  15. inputs[key] = await decodeBase64AndDecompress(decodeURIComponent(value))
  16. })
  17. return inputs
  18. }
  19. function getLastAnswer(chatList: ChatItem[]) {
  20. for (let i = chatList.length - 1; i >= 0; i--) {
  21. const item = chatList[i]
  22. if (item.isAnswer && !item.isOpeningStatement)
  23. return item
  24. }
  25. return null
  26. }
  27. function appendQAToChatList(chatList: ChatItem[], item: any) {
  28. // we append answer first and then question since will reverse the whole chatList later
  29. chatList.push({
  30. id: item.id,
  31. content: item.answer,
  32. agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
  33. feedback: item.feedback,
  34. isAnswer: true,
  35. citation: item.retriever_resources,
  36. message_files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
  37. })
  38. chatList.push({
  39. id: `question-${item.id}`,
  40. content: item.query,
  41. isAnswer: false,
  42. message_files: item.message_files?.filter((file: any) => file.belongs_to === 'user') || [],
  43. })
  44. }
  45. /**
  46. * Computes the latest thread messages from all messages of the conversation.
  47. * Same logic as backend codebase `api/core/prompt/utils/extract_thread_messages.py`
  48. *
  49. * @param fetchedMessages - The history chat list data from the backend, sorted by created_at in descending order. This includes all flattened history messages of the conversation.
  50. * @returns An array of ChatItems representing the latest thread.
  51. */
  52. function getPrevChatList(fetchedMessages: any[]) {
  53. const ret: ChatItem[] = []
  54. let nextMessageId = null
  55. for (const item of fetchedMessages) {
  56. if (!item.parent_message_id) {
  57. appendQAToChatList(ret, item)
  58. break
  59. }
  60. if (!nextMessageId) {
  61. appendQAToChatList(ret, item)
  62. nextMessageId = item.parent_message_id
  63. }
  64. else {
  65. if (item.id === nextMessageId || nextMessageId === UUID_NIL) {
  66. appendQAToChatList(ret, item)
  67. nextMessageId = item.parent_message_id
  68. }
  69. }
  70. }
  71. return ret.reverse()
  72. }
  73. export {
  74. getProcessedInputsFromUrlParams,
  75. getLastAnswer,
  76. getPrevChatList,
  77. }