OvidijusParsiunas / deep-chat

Fully customizable AI chatbot component for your website
https://deepchat.dev
MIT License
1.43k stars 218 forks source link

Streaming with feedback #174

Closed ronald888 closed 5 months ago

ronald888 commented 5 months ago

Is it possible to have streaming enabled and have the feedback buttons displayed after streaming is complete?

When I add the feedback buttons inside the responseInterceptor along with the text, since it's streaming, it's displaying the feedback buttons multiple times.

I was thinking if there is a way to trigger an event when the stream is done, so as to add the buttons only after that happens.

OvidijusParsiunas commented 5 months ago

Hi @ronald888. You could use the onNewMessage event to listen to when the response message has finished streaming and then trigger the _addMessage method to add your feedback buttons. The _addMessage is a method that is not part of our official documentation and will be added to the main API on our next release, however it is still available in the current release. The way it works is it accepts a Response object as an argument and adds a message to the chat. E.g. deepChatRef._addMessage({text: 'hello'});.

ronald888 commented 5 months ago

This works great! Thank you. When the next release happens, will _addMessage will be available or will it be replaced with something else (like one without the underscore)?

OvidijusParsiunas commented 5 months ago

Hi @ronald888. It will simply be addMessage. You can also view this in our repository and the deep-chat-dev/deep-chat-react-dev packages.

venlon789 commented 2 weeks ago

Hello! I would like to ask for some advice on a current requirement. The design is as follows: I want the upper part to have a typewriter effect and render in Markdown format. However, when rendering, I used HTML, but the Markdown style did not take effect. Can you help me solve this problem? Here is my relevant code.

          onmessage(message) {
            console.log('onmessage')
            const data = JSON.parse(message.data)
            currentMesImportantInfo.id = data.id
            if (data.status_code === 'SUCCESS') {
              reference = {}
              if (data?.references?.doc?.length > 0) {
                // 引用部分
                const titleText = data.references.doc.map(item => `《${item.title}》`)
                const titleHtml =
                  `
                  <div style="font-size: 14px; background-color: #f2f6fc; padding: 11px 16px; border-radius: 8px; margin-top: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
                    <span style="color: #67696d;">引用:</span>
                    <span style="color: #728cb6;">
                      来源${titleText}
                    </span>
                  </div>
                  `
                signals.onResponse({ html: titleHtml })

                // 文件链接
                // ====盒子内部的html
                const linkContentHtml = data.references.doc.map(item => `
                  <a
                    onmouseover="this.style.color='#409eff'; this.style.textDecoration='underline';"
                    onmouseout="this.style.color='#606266'; this.style.textDecoration='none';"
                    style="font-size: 14px; color: #606266 ; margin-bottom: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none;" href="${item.documentUrl}"
                    target="_blank"
                  >
                    ${item.content}
                  </a>
                `).join('')
                // ===包裹文件链接的盒子的html
                const linkBoxHtml =
                `
                <div style="background-color: #f2f6fc; padding: 16px; border-radius: 8px; margin-top: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; flex-direction: column;">
                  ${linkContentHtml}
                </div>
                `
                signals.onResponse({ html: linkBoxHtml }) // 添加消息内容
                reference = data
              } else {
                textContent += data.message.content.replace(/\n/g, '<br />')
                signals.onResponse({ html: data.message.content.replace(/\n/g, '<br />') }) // 添加消息内容
              }
            } else {
              signals.onResponse({ error: data.message.content })
            }
          }
          async onclose() {
            await signals.onResponse({
              html: `
              <div style="margin-top: 15px; display: flex; display: flex; flex-direction: row; justify-content: flex-end">
                <svg id="${currentMesImportantInfo.id}up" conversationid="${currentMesImportantInfo.id}" class="icon icon-thumb-up" style="width: 1.5em;height: 1.5em; margin-right: 10px; vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" p-id="2208">
                  <path style="pointer-events: none;" d="M732.522667 840.832l122.197333-384H595.050667l51.349333-134.186667a85.333333 85.333333 0 0 0-29.056-99.2L580.053333 195.989333l-200.661333 260.864H337.066667v384h395.456z m76.586666 40.746667a64 64 0 0 1-60.970666 44.586666H251.733333v-554.666666h85.653334L525.162667 127.36a64 64 0 0 1 88.704-12.501333l54.101333 39.893333a170.666667 170.666667 0 0 1 58.133333 198.357333l-7.04 18.346667h135.658667c57.749333 0 98.816 56.192 81.322667 111.232l-126.933334 398.869333zM102.4 926.165333v-554.666666h85.333333v554.666666h-85.333333z" fill="#4E5969" p-id="2209"></path>
                </svg>
                <svg id="${currentMesImportantInfo.id}down" conversationid="${currentMesImportantInfo.id}" class="icon icon-thumb-down" style="width: 1.5em;height: 1.5em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" p-id="2238">
                  <path style="pointer-events: none;" d="M287.189333 192L165.013333 576h259.669334L373.333333 710.186667a85.333333 85.333333 0 0 0 29.056 99.2l37.290667 27.456L640.298667 576H682.666667V192H287.189333z m-76.586666-40.746667A64 64 0 0 1 271.616 106.666667H768v554.666666h-85.653333l-187.776 244.117334a64 64 0 0 1-88.704 12.48l-54.101334-39.872a170.666667 170.666667 0 0 1-58.133333-198.378667l7.04-18.346667H164.992c-57.749333 0-98.816-56.170667-81.322667-111.210666L210.624 151.253333zM917.333333 106.666667v554.666666h-85.333333V106.666667h85.333333z" fill="#4E5969" p-id="2239"></path>
                </svg>
              </div>
              `
            })
            signals.onClose()
            eventSourceInstance = null
            textContent = ''
          }

image