236236</template >
237237
238238<script setup lang="ts">
239- import { ref , computed , nextTick , watch , onMounted , reactive } from ' vue'
239+ import { ref , computed , nextTick , watch , onMounted , reactive , provide } from ' vue'
240240import { CircleCloseFilled , Paperclip , Promotion , VideoPause } from ' @element-plus/icons-vue'
241241import ContentList from ' ../content-list/index.vue'
242242import Loading from ' ../loading/index.vue'
@@ -364,10 +364,8 @@ const addFile = (file: File) => {
364364
365365 const uploadPromise = (async () => {
366366 try {
367- let cid = currentChatId .value
368- if (! cid ) {
369- cid = store .newChat ()
370- }
367+ // ๆฐๆงๅๅฝๅ chat_id๏ผๅน็ญ๏ผ๏ผไฟ่ฏๆไปถ source_id ไธๅ็ปญๅ้็ chat_id ไธ่ด
368+ const cid = store .getChatId ()
371369 const result = await store .uploadFile (file , cid )
372370 item .url = result .url
373371 const parts = result .url .split (' /' )
@@ -446,19 +444,15 @@ const send = async () => {
446444
447445 const text = question .value .content .trim ()
448446
449- // ๆฒกๆๅฝๅๅฏน่ฏๆถๆฌๅฐ็ๆ่็จฟ chat_id๏ผๅ็ซฏ้ฆๅๆถ open-if-missing๏ผ
450- if (! currentChatId .value ) {
451- store .newChat ()
452- }
453-
454- const cid = currentChatId .value
447+ // ๆฐๆงๅ chat_id๏ผๆ ๅๅ็ซฏ็ๆ๏ผๅ็ซฏ้ฆๅๆถ open-if-missing๏ผ
448+ const cid = store .getChatId ()
455449
456- // ้ฆๆกๆถๆฏ๏ผไน่งๆดๆฐ่็จฟๆ ้ข๏ผ่ฝๅบไบค็ปๆต็ปๆๅ็ๅๅฐ renameChat
450+ // ้ฆๆกๆถๆฏ๏ผๆญคๅปๆๆไผ่ฏ push ่ฟๅทฆไพงๅ่กจ๏ผๆฐๅปบๆถไธ push๏ผ๏ผๆ ้ข็จ question ๅ
ๅฎนไน่งๆดๆฐ๏ผ
451+ // ่ฝๅบไบค็ปๆต็ปๆๅ็ๅๅฐ renameChatใ
457452 const isFirstMessage = messages .value .length === 0
458453 const abstract = text .substring (0 , 256 )
459- if (isFirstMessage && text ) {
460- const conv = store .conversations .value .find ((c : any ) => c .id === cid )
461- if (conv ) conv .abstract = abstract
454+ if (isFirstMessage && ! store .conversations .value .some ((c : any ) => c .id === cid )) {
455+ store .conversations .value .unshift ({ id: cid , abstract: text ? abstract : ' ๆฐๅฏน่ฏ' })
462456 }
463457
464458 // ๅ็ฑปๆไปถ
@@ -478,54 +472,27 @@ const send = async () => {
478472 .filter ((f ) => ! isImage (f .name ) && ! isDocument (f .name ) && ! isAudio (f .name ) && ! isVideo (f .name ))
479473 .map ((f ) => ({ url: f .url , file_id: f .file_id , name: f .name }))
480474
481- // ๆๅปบ question content
475+ // ๆๅปบ question content๏ผUSER ๆฐๆณกๅฑ็คบ็จ๏ผไธ API message๏ผๅๅ็ซฏ็จ๏ผ
482476 const questionContent: any = { type: ' QUESTION' , content: text }
483- if (images .length ) questionContent .image_list = images
484- if (documents .length ) questionContent .document_list = documents
485- if (audio .length ) questionContent .audio_list = audio
486- if (video .length ) questionContent .video_list = video
487- if (other .length ) questionContent .other_list = other
488-
489- store .pushMessage ({
490- role: ' USER' ,
491- content: [questionContent ],
492- id: nanoid (),
493- })
494-
495- store .pushMessage (store .createAnswerMessage ())
496- const aiMsg = messages .value [messages .value .length - 1 ]
497- if (! aiMsg ) return
498-
499- // ๆๅปบ API payload
500477 const message: any = { content: text , type: ' QUESTION' }
501- if (images .length ) message .image_list = images
502- if (documents .length ) message .document_list = documents
503- if (audio .length ) message .audio_list = audio
504- if (video .length ) message .video_list = video
505- if (other .length ) message .other_list = other
506-
507- const payload: any = { message , stream: true , re_chat: false }
508-
509- loading .value = true
510- store .startStream ({
511- cid ,
512- request : () => store .chat (cid , payload ),
513- onStream : (chunk ) => {
514- store .appendChunk (aiMsg , chunk )
515- scrollToBottom ()
516- },
478+ if (images .length ) questionContent .image_list = message .image_list = images
479+ if (documents .length ) questionContent .document_list = message .document_list = documents
480+ if (audio .length ) questionContent .audio_list = message .audio_list = audio
481+ if (video .length ) questionContent .video_list = message .video_list = video
482+ if (other .length ) questionContent .other_list = message .other_list = other
483+
484+ // ๅงๆ้็จ sendMessage๏ผๆฐ้ฎ็ญ๏ผๆฐๅข USER ๆฐๆณก + ๆฐ answer ๆถๆฏ๏ผ๏ผ
485+ // ้ฆๆกๆถๆฏ่ฝๅบๅๆ็ๅฎๆ ้ขๅๅๅ็ซฏไบค็ป onFinishใ
486+ sendMessage ({
487+ message ,
488+ newQuestion: true ,
489+ questionContent ,
490+ reChat: false ,
517491 onFinish : () => {
518- scrollToBottom ()
519- loading .value = false
520- // ้ฆๆกๆถๆฏ่ฝๅบๅ๏ผๆ็ๅฎๆ ้ขๅๅๅ็ซฏ๏ผๆญคๆถไผ่ฏๅทฒ่ขซ open-if-missing ๅปบๅฅฝ๏ผ
521492 if (isFirstMessage && text ) {
522493 store .renameChat (cid , abstract ).catch (() => {})
523494 }
524495 },
525- onFailure : () => {
526- scrollToBottom ()
527- loading .value = false
528- },
529496 })
530497 question .value .content = ' '
531498 clearFiles ()
@@ -592,6 +559,79 @@ watch(
592559 },
593560)
594561
562+ // ๆฐๅปบ/ๅๆขไผ่ฏๆถๆธ
็ฉบๆๅญๆไปถไธ่พๅ
ฅ๏ผ้ฟๅ
ๆไปถ็ source_id ไธๆฐ chat_id ๅฏนไธไธ
563+ watch (
564+ () => store .composerResetSignal .value ,
565+ () => {
566+ clearFiles ()
567+ question .value .content = ' '
568+ },
569+ )
570+
571+ // โโ ้็จๅ่ตทๅฏน่ฏ๏ผๆณจๅ
ฅ็ปๅ
ๅฎน็ปไปถ๏ผ โโโโโโโโโโโโโโโโโโโโโโโโโโ
572+ // ่กจๅๆไบคใไปฅๅๆชๆฅไปปไฝโ่ฝๅ่ตทๅฏน่ฏโ็ๅ
ๅฎน็ปไปถ้ฝ้่ฟๅฎๅ่ตท/็ปญ่ทไธๆฌกๅฏน่ฏใ
573+ // ่ฐ็จๆนๅช้ๆพๅผๅฃฐๆ newQuestion๏ผๆฏๅฆๆฐๅขไธไธช question๏ผๆฐ USER ๆฐๆณก + ๆฐ answer ๆถๆฏ๏ผ๏ผ
574+ // ๅฆๅ็ปญ่ท่ๅๅๅทฒๅญๅจ็้ฃๆก assistant ๆถๆฏ๏ผๅ็ซฏๅค็จๅไธ chat_record๏ผใ
575+ interface SendMessageOptions {
576+ message: any // ๅ็ซฏ message dict {content,type,image_list?,...}
577+ newQuestion: boolean
578+ questionContent? : any // newQuestion=true ๆถ USER ๆฐๆณกๅฑ็คบ็ content ้กน๏ผ็ผบ็็จ message
579+ reChat? : boolean // ้ป่ฎค false๏ผๆฐๅผๆไธไป
ๅฝฑๅ็ฅ่ฏ่็นโๆข็ญๆกโๅป้
580+ formData? : Record <string , any >
581+ position? : any
582+ chatRecordId? : string | null
583+ chunkId? : string | null
584+ onFinish? : () => void // ๆถๅฐพ้ฉๅญ๏ผๅฆ้ฆๆกๆถๆฏ่ฝๅบๆนๆ ้ข๏ผ๏ผๅจๅ
็ฝฎ็ปๆ้ป่พๅ่ฐ็จ
585+ onFailure? : () => void
586+ }
587+
588+ const sendMessage = (opts : SendMessageOptions ) => {
589+ const cid = store .getChatId ()
590+
591+ // ๅฎไฝๆตๅผๅๅ
ฅ็ฎๆ ๆถๆฏ
592+ let target: any
593+ if (opts .newQuestion ) {
594+ store .pushMessage ({ role: ' USER' , content: [opts .questionContent ?? opts .message ], id: nanoid () })
595+ store .pushMessage (store .createAnswerMessage ())
596+ target = messages .value [messages .value .length - 1 ]
597+ } else {
598+ // ็ปญ่ท๏ผreload ๅๆ `${chat_record_id}_ASSISTANT` ๅฝไธญ๏ผๅฎๆถๆตไธญ answer ๆถๆฏ id ไธบ '' โ ๅ้ๆๅไธๆก
599+ target =
600+ messages .value .find ((m : any ) => m .id === ` ${opts .chatRecordId }_ASSISTANT ` ) ||
601+ messages .value [messages .value .length - 1 ]
602+ }
603+ if (! target ) return
604+
605+ const payload: any = { message: opts .message , stream: true , re_chat: opts .reChat ?? false }
606+ if (opts .formData ) payload .form_data = opts .formData
607+ if (opts .position !== undefined ) payload .position = opts .position
608+ if (opts .chatRecordId ) payload .chat_record_id = opts .chatRecordId
609+ if (opts .chunkId ) payload .chunk_id = opts .chunkId
610+
611+ loading .value = true
612+ store .startStream ({
613+ cid ,
614+ request : () => store .chat (cid , payload ),
615+ onStream : (chunk : any ) => {
616+ store .appendChunk (target , chunk )
617+ scrollToBottom ()
618+ },
619+ onFinish : () => {
620+ target .write_ed = true
621+ loading .value = false
622+ scrollToBottom ()
623+ opts .onFinish ?.()
624+ },
625+ onFailure : () => {
626+ target .write_ed = true
627+ loading .value = false
628+ opts .onFailure ?.()
629+ },
630+ })
631+ }
632+
633+ provide (' sendMessage' , sendMessage )
634+
595635defineExpose ({ scrollToBottom })
596636 </script >
597637
0 commit comments