@chat21/chat21-web-widget 5.1.30 → 5.1.32-rc13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/docker-community-push-latest.yml +23 -13
- package/.github/workflows/docker-image-tag-community-tag-push.yml +22 -12
- package/CHANGELOG.md +89 -2
- package/Dockerfile +4 -5
- package/angular.json +5 -2
- package/deploy_amazon_beta.sh +17 -7
- package/docs/changelog/this-branch.md +36 -0
- package/nginx.conf +22 -2
- package/package.json +4 -1
- package/src/app/app.component.ts +10 -9
- package/src/app/app.module.ts +11 -0
- package/src/app/component/conversation-detail/conversation/conversation.component.html +9 -2
- package/src/app/component/conversation-detail/conversation/conversation.component.scss +12 -2
- package/src/app/component/conversation-detail/conversation/conversation.component.ts +46 -5
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +9 -5
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +19 -1
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +2 -0
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +128 -80
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +117 -13
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +120 -8
- package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.html +43 -0
- package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.scss +79 -0
- package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.ts +192 -0
- package/src/app/component/last-message/last-message.component.ts +4 -1
- package/src/app/component/message/audio/audio.component.ts +0 -5
- package/src/app/component/message/audio-sync/audio-sync.component.html +18 -0
- package/src/app/component/message/audio-sync/audio-sync.component.scss +64 -0
- package/src/app/component/message/audio-sync/audio-sync.component.spec.ts +23 -0
- package/src/app/component/message/audio-sync/audio-sync.component.ts +558 -0
- package/src/app/component/message/bubble-message/bubble-message.component.html +6 -1
- package/src/app/component/message/bubble-message/bubble-message.component.ts +2 -1
- package/src/app/providers/global-settings.service.ts +21 -0
- package/src/app/providers/translator.service.ts +2 -0
- package/src/app/providers/tts-audio-playback-coordinator.service.ts +93 -0
- package/src/app/providers/voice/STT&TTS/openai-voice.config.ts +12 -0
- package/src/app/providers/voice/STT&TTS/openai-voice.provider.ts +171 -0
- package/src/app/providers/voice/STT&TTS/speech-provider.abstract.ts +39 -0
- package/src/app/providers/voice/audio.types.ts +34 -0
- package/src/app/providers/voice/vad.service.spec.ts +28 -0
- package/src/app/providers/voice/vad.service.ts +70 -0
- package/src/app/providers/voice/voice.service.spec.ts +60 -0
- package/src/app/providers/voice/voice.service.ts +376 -0
- package/src/app/sass/_variables.scss +3 -0
- package/src/app/shims/onnxruntime-web-wasm.ts +4 -0
- package/src/app/utils/conversation-sender-classifier.ts +21 -0
- package/src/app/utils/globals.ts +7 -1
- package/src/assets/i18n/en.json +1 -0
- package/src/assets/i18n/es.json +1 -0
- package/src/assets/i18n/fr.json +1 -0
- package/src/assets/i18n/it.json +1 -0
- package/src/assets/onnx/ort-wasm-simd-threaded.mjs +59 -0
- package/src/assets/onnx/ort-wasm-simd-threaded.wasm +0 -0
- package/src/assets/vad/silero_vad_legacy.onnx +0 -0
- package/src/assets/vad/vad.worklet.bundle.min.js +1 -0
- package/src/chat21-core/models/message.ts +2 -1
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +3 -2
- package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +12 -0
- package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
- package/src/chat21-core/utils/utils-message.ts +7 -0
- package/src/chat21-core/utils/utils.ts +5 -2
- package/src/launch.js +41 -32
- package/src/launch_template.js +41 -32
- package/tsconfig.json +5 -0
- package/deploy_amazon_prod.sh +0 -41
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
name: Docker Image Community latest CI
|
|
2
2
|
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
5
|
branches: [ master ]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
8
|
|
|
9
9
|
jobs:
|
|
10
10
|
push_to_registry:
|
|
@@ -12,12 +12,22 @@ jobs:
|
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
|
|
14
14
|
steps:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
- name: Check out the repo
|
|
16
|
+
uses: actions/checkout@v2
|
|
17
|
+
|
|
18
|
+
- name: Set up Docker Buildx
|
|
19
|
+
uses: docker/setup-buildx-action@v2
|
|
20
|
+
|
|
21
|
+
- name: Log in to Docker Hub
|
|
22
|
+
uses: docker/login-action@v2
|
|
23
|
+
with:
|
|
24
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
25
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
26
|
+
|
|
27
|
+
- name: Build and push multiarch Docker image
|
|
28
|
+
uses: docker/build-push-action@v3
|
|
29
|
+
with:
|
|
30
|
+
context: .
|
|
31
|
+
push: true
|
|
32
|
+
platforms: linux/amd64,linux/arm64
|
|
33
|
+
tags: chat21/chat21-web-widget:latest
|
|
@@ -3,20 +3,30 @@ name: Publish Docker Community image tags
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
tags:
|
|
6
|
-
- '**'
|
|
7
|
-
jobs:
|
|
6
|
+
- '**' # Trigger su qualsiasi tag
|
|
8
7
|
|
|
8
|
+
jobs:
|
|
9
9
|
push_to_registry:
|
|
10
10
|
name: Push Docker image to Docker Hub
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
|
+
|
|
12
13
|
steps:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
- name: Check out the repo
|
|
15
|
+
uses: actions/checkout@v2
|
|
16
|
+
|
|
17
|
+
- name: Set up Docker Buildx
|
|
18
|
+
uses: docker/setup-buildx-action@v2
|
|
19
|
+
|
|
20
|
+
- name: Log in to Docker Hub
|
|
21
|
+
uses: docker/login-action@v2
|
|
22
|
+
with:
|
|
23
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
24
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
25
|
+
|
|
26
|
+
- name: Build and push multiarch Docker image
|
|
27
|
+
uses: docker/build-push-action@v3
|
|
28
|
+
with:
|
|
29
|
+
context: .
|
|
30
|
+
push: true
|
|
31
|
+
platforms: linux/amd64,linux/arm64
|
|
32
|
+
tags: chat21/chat21-web-widget:${{ github.ref_name }}
|
package/CHANGELOG.md
CHANGED
|
@@ -6,11 +6,76 @@
|
|
|
6
6
|
### **Copyrigth**:
|
|
7
7
|
*Tiledesk SRL*
|
|
8
8
|
|
|
9
|
+
# 5.1.32-rc13
|
|
10
|
+
- **changed**: stream audio footer UI — stream button expands into a “Terminate” pill with animated level bars driven by mic intensity; recorder icon hidden while streaming; textarea width adjusted while streaming
|
|
11
|
+
- **changed**: `StreamAudioSpectrum` — consolidated stream spectrum + stream button visuals into a single component with improved silence vs speaking handling and volume-driven bar heights
|
|
12
|
+
- **changed**: conversation layout while streaming — adjusted received bubble sizing (`fullSizeMessage`) and loading spinner spacing (`fullSize`) for full-width stream mode
|
|
13
|
+
- **added**: VAD speech state events (`speechStart$`, `speechEnd$`) to improve UI/state transitions around user speech
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# 5.1.32-rc12
|
|
17
|
+
- **changed**: voice acquisition blocking during TTS response — pause VAD after user speech ends until the TTS response cycle completes; added safety timeout and `isAcquisitionBlocked$` to drive UI (e.g. greyed spectrum)
|
|
18
|
+
- **chore**: version bump to `5.1.32-rc12`
|
|
19
|
+
|
|
20
|
+
# 5.1.32-rc11
|
|
21
|
+
- **added**: global TTS stop — `TtsAudioPlaybackCoordinator.stopAll()` + `stopAllPlayback$` to abort current and queued TTS playback and reveal full message text
|
|
22
|
+
- **changed**: stop TTS playback when closing stream audio
|
|
23
|
+
- **chore**: version bump to `5.1.32-rc11`
|
|
24
|
+
|
|
25
|
+
# 5.1.32-rc10
|
|
26
|
+
- **added**: TTS playback state (`isTTSPlaying$`) to coordinate voice UI and suppress mic segment emission while the bot is speaking
|
|
27
|
+
- **changed**: stream spectrum theme color turns grey while TTS is playing
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# 5.1.32-rc9
|
|
31
|
+
- **added**: mic-triggered TTS interruption — when VAD detects user speech, stop current TTS playback, clear the queue, and reveal the full message text
|
|
32
|
+
- **added**: global TTS stop API (`TtsAudioPlaybackCoordinator.stopAll()` + `stopAllPlayback$`) to stop current + queued TTS playback from UI/events (e.g. close stream)
|
|
33
|
+
- **changed**: `chat-audio-sync` TTS playback now streams audio via authenticated POST to `message.metadata.src`, sending `voiceSettings` + `text` and `streaming: true`
|
|
34
|
+
- **changed**: stream UI spectrum — removed circular orb and stretched the spectrum line to fill the `#streamAudioAlert` width with 10px side padding
|
|
35
|
+
- **changed**: conversation content layout while streaming — adjusted received bubble left margin and loading spinner margins for full-size mode
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# 5.1.32-rc8
|
|
39
|
+
- **changed**: updated the dev environment defaults to align with the stage setup (remote config URL, API endpoints, logging level, storage prefix, and related settings)
|
|
40
|
+
|
|
41
|
+
# 5.1.32-rc7
|
|
42
|
+
- **added**: `StreamAudioSpectrum` component for audio visualization in the streaming footer UI
|
|
43
|
+
- **added**: TTS playback coordinator queue — ensures TTS messages play sequentially without interrupting the previous one
|
|
44
|
+
- **changed**: `chat-audio-sync` — updated TTS audio handling to support streaming playback and improved autoplay/animation timing
|
|
45
|
+
- **changed**: iframe loader (`launch.js`, `launch_template.js`) — streamlined loading logic and improved error handling, with fixes for localhost environments
|
|
46
|
+
|
|
47
|
+
# 5.1.32-rc4
|
|
48
|
+
- **added**: “Close stream” control (`.close-stream-button`) — content and sheet bottom offset in fullscreen using `--chat-footer-stream-button-height` only while the stream is listening (`isStreamAudioActive`); variables in `_variables.scss`.
|
|
49
|
+
- **added**: `VoiceService.discardCurrentRecordingSegment()` — when a message arrives from another sender during streaming, the current WebM segment is discarded (no upload) without stopping mic/VAD; `interruptStreamDueToPeerMessage()` in the footer no longer clears `isStreamAudioActive`.
|
|
50
|
+
- **changed**: `#streamAudioAlert` — band above the footer with a frosted-glass look (`backdrop-filter`, semi-transparent `color-mix`).
|
|
51
|
+
|
|
52
|
+
# 5.1.32-rc3
|
|
53
|
+
- **changed**: `nginx.conf` (Docker image) — explicit MIME types for `.mjs`, `.wasm`, `.onnx` and `default_type` at `http` level (avoids `text/plain` on ONNX/VAD modules behind containerized deploys).
|
|
54
|
+
- **chore**: removed deprecated Amazon beta/prod deploy scripts from the repository.
|
|
55
|
+
|
|
56
|
+
# 5.1.32-rc2
|
|
57
|
+
- **bug fixed**: minor streaming icon UI fixed
|
|
58
|
+
- **changed**: Refactor stream audio button UI in the conversation footer (layout / classes).
|
|
59
|
+
|
|
60
|
+
# 5.1.32-rc1
|
|
61
|
+
- **added**: Voice pipeline — VAD (`@ricky0123/vad-web`) with ONNX Runtime WASM served from `/assets/onnx` (`copy-onnx-wasm`), `VoiceService` with `audioSegment$` (WebM segments) and optional STT/TTS via unified OpenAI provider using `HttpClient`, transcript / error fields on segment payloads.
|
|
62
|
+
- **added**: Stream audio UI in conversation footer — toggle, real-time volume stream and animated waveform (`volume$`); mic session lifecycle wired to upload segments on speech end.
|
|
63
|
+
- **added**: `MessageModel.isJustRecived` — set when ingesting messages (MQTT/Firebase `addCommandMessage` for `command.type === "message"`, and default for non-command messages in `addedMessage` / `addedNew`) to distinguish “new in session” vs history.
|
|
64
|
+
- **added**: `chat-audio-sync` for TTS messages — karaoke-style word sync to audio, full `message` input, typography aligned with text bubbles; skips animation when `isJustRecived === false`; after playback ends sets `message.isJustRecived = false` so replays show full text without re-animating.
|
|
65
|
+
- **bug fixed**: `AnalyserNode.getByteFrequencyData` TypeScript error — `Uint8Array` created from an explicit `ArrayBuffer` for correct DOM typings.
|
|
66
|
+
- **bug fixed**: `isStreamAudioActive` no longer derived from per-frame mic level (`volume > 1`), which caused the stream button / active state to flash continuously while listening.
|
|
67
|
+
|
|
9
68
|
# 5.1.30
|
|
10
69
|
- **bug fixed**: startHidden is not working properly
|
|
11
70
|
|
|
12
|
-
# 5.1.
|
|
13
|
-
- **bug fixed**:
|
|
71
|
+
# 5.1.30-rc3
|
|
72
|
+
- **bug fixed**: bug fix user-typing with human is not available
|
|
73
|
+
|
|
74
|
+
# 5.1.30-rc2
|
|
75
|
+
- **bug fixed**: bug fix disabled user-typing with human
|
|
76
|
+
|
|
77
|
+
# 5.1.30-rc1
|
|
78
|
+
- **bug fixed**: startHidden is not working properly
|
|
14
79
|
|
|
15
80
|
# 5.1.28
|
|
16
81
|
- **bug fixed**: fixed Bot/Human conversation detection by correctly classifying bot replies
|
|
@@ -22,8 +87,22 @@
|
|
|
22
87
|
- **changed**: Set the default autoStart value to false
|
|
23
88
|
- **added**: Added the open widget loading spinner
|
|
24
89
|
- **changed**: Load the widget without authentication and display the speech bubble
|
|
90
|
+
|
|
91
|
+
# 5.1.27-rc3
|
|
92
|
+
- **bug fixed**: fixed Bot/Human conversation detection by correctly classifying bot replies
|
|
93
|
+
|
|
94
|
+
# 5.1.27-rc2
|
|
95
|
+
- **bug fixed**: centralized fullscreen management on mobile and handled the case of the closed widget that remained fullscreen
|
|
96
|
+
|
|
97
|
+
# 5.1.27-rc1
|
|
98
|
+
- **added**: closeChatInConversation parameters
|
|
99
|
+
- **added**: close chat button under textarea footer component
|
|
100
|
+
|
|
101
|
+
# 5.1.26-rc6
|
|
25
102
|
- **changed**: mobile always opens fullscreen and ignores legacy stored size”.
|
|
26
103
|
- **changed**: changed user-typing
|
|
104
|
+
|
|
105
|
+
# 5.1.26-rc5
|
|
27
106
|
- **changed**: Hide the resize-widget button when on mobile
|
|
28
107
|
- **added**: added "I'm thinking" when the bot responds
|
|
29
108
|
|
|
@@ -85,6 +164,14 @@
|
|
|
85
164
|
- **bug-fixed**: check showEmojiFooterButton to enable/disable emojii
|
|
86
165
|
- **bug-fixed**: markdown is fired as an emojii and blocked by isEmojii check fn
|
|
87
166
|
|
|
167
|
+
<<<<<<< HEAD
|
|
168
|
+
=======
|
|
169
|
+
# 5.1.7-rc7
|
|
170
|
+
- **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
|
|
171
|
+
|
|
172
|
+
# 5.1.7-rc6
|
|
173
|
+
- **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
|
|
174
|
+
>>>>>>> master-pre
|
|
88
175
|
|
|
89
176
|
# 5.1.7-rc5
|
|
90
177
|
- **bug-fixed**: bug fixed BUTTON STYLES
|
package/Dockerfile
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
### STAGE 1: Build ###
|
|
2
2
|
|
|
3
3
|
# We label our stage as ‘builder’
|
|
4
|
-
FROM node:20.12.2-alpine3.19 as builder
|
|
4
|
+
FROM --platform=$BUILDPLATFORM node:20.12.2-alpine3.19 as builder
|
|
5
5
|
|
|
6
6
|
COPY package.json package-lock.json ./
|
|
7
7
|
|
|
@@ -15,12 +15,11 @@ COPY . .
|
|
|
15
15
|
|
|
16
16
|
## Build the angular app in production mode and store the artifacts in dist folder
|
|
17
17
|
|
|
18
|
-
RUN npx ng build --configuration="prod" --output-path=dist --base-href=./ --output-hashing=none
|
|
19
18
|
|
|
19
|
+
RUN npx ng build --configuration="prod" --output-path=dist --base-href=./ --output-hashing=none
|
|
20
20
|
|
|
21
21
|
### STAGE 2: Setup ###
|
|
22
|
-
|
|
23
|
-
FROM nginx:1.14.1-alpine
|
|
22
|
+
FROM --platform=$BUILDPLATFORM nginx:1.14.1-alpine
|
|
24
23
|
|
|
25
24
|
## Copy our default nginx config
|
|
26
25
|
COPY nginx.conf /etc/nginx/nginx.conf
|
|
@@ -33,4 +32,4 @@ COPY --from=builder /ng-app/dist/browser /usr/share/nginx/html
|
|
|
33
32
|
|
|
34
33
|
RUN echo "Chat21 Web Widget Started!!"
|
|
35
34
|
|
|
36
|
-
CMD ["/bin/sh",
|
|
35
|
+
CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/widget-config-template.json > /usr/share/nginx/html/widget-config.json && exec nginx -g 'daemon off;'"]
|
package/angular.json
CHANGED
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"src/environments/real_data/widget-config-docker.json",
|
|
45
45
|
"src/environments/real_data/widget-config-native-mqtt.json",
|
|
46
46
|
"src/environments/real_data/widget-config-native-prod.json",
|
|
47
|
-
"src/environments/real_data/widget-config-aws-stage.json"
|
|
47
|
+
"src/environments/real_data/widget-config-aws-stage.json",
|
|
48
|
+
"src/environments/real_data/widget-config-aws-aruba.json"
|
|
48
49
|
],
|
|
49
50
|
"styles": [
|
|
50
51
|
"src/app/sass/styles.scss"
|
|
@@ -59,7 +60,9 @@
|
|
|
59
60
|
"idb",
|
|
60
61
|
"accept-language-parser",
|
|
61
62
|
"file-saver",
|
|
62
|
-
"dayjs"
|
|
63
|
+
"dayjs",
|
|
64
|
+
"onnxruntime-web",
|
|
65
|
+
"@ricky0123/vad-web"
|
|
63
66
|
],
|
|
64
67
|
"sourceMap": true,
|
|
65
68
|
"optimization": false,
|
package/deploy_amazon_beta.sh
CHANGED
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
version=`node -e 'console.log(require("./package.json").version)'`
|
|
3
3
|
echo "version $version"
|
|
4
4
|
|
|
5
|
+
npm i
|
|
6
|
+
|
|
7
|
+
cp src/environments/real_data/environment.pre.ts src/environments/environment.pre.ts
|
|
8
|
+
|
|
5
9
|
ng build --configuration="pre" --aot=true --base-href
|
|
6
10
|
|
|
11
|
+
### SET HASHING : START ###
|
|
12
|
+
cp ./src/launch_template.js ./dist/browser/launch.js
|
|
13
|
+
node ./src/build_launch.js
|
|
14
|
+
### SET HASHING : END ###
|
|
7
15
|
|
|
8
16
|
# ########## --->>>> NATIVE-MQTT folder START <<<<<------ ########## #
|
|
9
17
|
|
|
@@ -23,15 +31,17 @@ ng build --configuration="pre" --aot=true --base-href
|
|
|
23
31
|
|
|
24
32
|
|
|
25
33
|
# ########## --->>>> FIREBASE folder START <<<<<------ ########## #
|
|
26
|
-
cd dist
|
|
27
|
-
aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control max-age=300
|
|
28
|
-
aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
cd ..
|
|
34
|
+
cd dist/browser
|
|
35
|
+
aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control max-age=300 --exclude='launch.js' #7days
|
|
36
|
+
aws s3 sync . s3://tiledesk-widget-pre/v5/$version/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
|
|
37
|
+
aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control max-age=300 --exclude='launch.js' #7days
|
|
38
|
+
aws s3 sync . s3://tiledesk-widget-pre/v5/ --cache-control "no-store,no-cache,private" --exclude='*' --include='launch.js'
|
|
39
|
+
cd ../..
|
|
33
40
|
|
|
34
41
|
aws cloudfront create-invalidation --distribution-id E2V5O0YPR61V8P --paths "/*"
|
|
42
|
+
|
|
43
|
+
git restore src/environments/environment.pre.ts
|
|
44
|
+
|
|
35
45
|
# echo new version deployed $NEW_VER/$NEW_BUILD/ on s3://tiledesk-widget-pre/v2
|
|
36
46
|
echo new version deployed $version/ on s3://tiledesk-widget-pre/v5 and s3://tiledesk-widget-pre/v5/$version/
|
|
37
47
|
echo available on https://s3.eu-west-1.amazonaws.com/tiledesk-widget-pre/v5/index.html
|
|
@@ -45,3 +45,39 @@ Questo branch migliora il feedback in conversazione e rende il comportamento del
|
|
|
45
45
|
- Il callout non compare quando il widget e' aperto o quando la preview nuovo messaggio e' attiva.
|
|
46
46
|
- La UI della conversazione indica chiaramente se l'ultimo responder e' bot o umano.
|
|
47
47
|
- "Sto pensando..." compare solo nelle conversazioni bot e ha un comportamento prevedibile.
|
|
48
|
+
# This branch: identificazione bot o umano
|
|
49
|
+
|
|
50
|
+
## Obiettivo
|
|
51
|
+
|
|
52
|
+
In questo branch e' stata introdotta una logica esplicita per capire, all'apertura della conversazione, se l'ultimo responder lato server e' un **bot** oppure un **umano**.
|
|
53
|
+
|
|
54
|
+
## Come viene fatta l'identificazione
|
|
55
|
+
|
|
56
|
+
- La valutazione parte dai messaggi gia' caricati in conversazione.
|
|
57
|
+
- Viene cercato l'**ultimo messaggio ricevuto dal server** (non inviato dal client corrente).
|
|
58
|
+
- Quel messaggio viene classificato con una funzione dedicata (`classifyMessageSenderKind`) che usa piu' segnali:
|
|
59
|
+
- `attributes.flowAttributes.chatbot_id` (quando presente indica bot)
|
|
60
|
+
- pattern del mittente (es. `senderId` con prefisso bot, quando applicabile)
|
|
61
|
+
- informazioni del mittente (`sender_fullname` e metadati associati)
|
|
62
|
+
|
|
63
|
+
## Regola speciale per messaggi di sistema
|
|
64
|
+
|
|
65
|
+
Se l'ultimo messaggio utile e' di tipo `system`, viene fatto un controllo aggiuntivo:
|
|
66
|
+
|
|
67
|
+
- se in `attributes` e' presente un evento con `messagelabel.key = MEMBER_JOINED_GROUP`
|
|
68
|
+
- e rappresenta il passaggio della conversazione a un operatore
|
|
69
|
+
|
|
70
|
+
allora la conversazione viene forzata a **Umano** anche se altri indizi potrebbero suggerire bot.
|
|
71
|
+
|
|
72
|
+
## Risultato in UI
|
|
73
|
+
|
|
74
|
+
- In apertura conversazione viene mostrato un badge con stato:
|
|
75
|
+
- `Bot`
|
|
76
|
+
- `Umano`
|
|
77
|
+
- Questo stato viene ricalcolato al variare dei messaggi ricevuti.
|
|
78
|
+
|
|
79
|
+
## Effetto sui feedback utente
|
|
80
|
+
|
|
81
|
+
- Il messaggio temporaneo `"sto pensando..."` viene mostrato solo quando la conversazione risulta di tipo **Bot**.
|
|
82
|
+
- Alla ricezione della prima risposta dal server, `"sto pensando..."` viene nascosto **immediatamente**.
|
|
83
|
+
- Non e' previsto alcun tempo minimo di visualizzazione del messaggio.
|
package/nginx.conf
CHANGED
|
@@ -5,18 +5,38 @@ events {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
http {
|
|
8
|
+
include /etc/nginx/mime.types;
|
|
9
|
+
default_type application/octet-stream;
|
|
10
|
+
|
|
8
11
|
server {
|
|
9
12
|
listen 80;
|
|
10
13
|
server_name localhost;
|
|
11
14
|
|
|
12
15
|
root /usr/share/nginx/html;
|
|
13
16
|
index index.html index.htm;
|
|
14
|
-
include /etc/nginx/mime.types;
|
|
15
17
|
|
|
16
18
|
gzip on;
|
|
17
19
|
gzip_min_length 1000;
|
|
18
20
|
gzip_proxied expired no-cache no-store private auth;
|
|
19
|
-
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
|
21
|
+
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/wasm;
|
|
22
|
+
|
|
23
|
+
# ONNX Runtime (.mjs), WASM e modelli VAD: il browser rifiuta moduli ES con Content-Type: text/plain
|
|
24
|
+
location ~* \.mjs$ {
|
|
25
|
+
root /usr/share/nginx/html;
|
|
26
|
+
default_type application/javascript;
|
|
27
|
+
charset utf-8;
|
|
28
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
29
|
+
}
|
|
30
|
+
location ~* \.wasm$ {
|
|
31
|
+
root /usr/share/nginx/html;
|
|
32
|
+
default_type application/wasm;
|
|
33
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
34
|
+
}
|
|
35
|
+
location ~* \.onnx$ {
|
|
36
|
+
root /usr/share/nginx/html;
|
|
37
|
+
default_type application/octet-stream;
|
|
38
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
39
|
+
}
|
|
20
40
|
|
|
21
41
|
location / {
|
|
22
42
|
try_files $uri $uri/ /index.html;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chat21/chat21-web-widget",
|
|
3
3
|
"author": "Tiledesk SRL",
|
|
4
|
-
"version": "5.1.
|
|
4
|
+
"version": "5.1.32-rc13",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://www.tiledesk.com",
|
|
7
7
|
"repository": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"ng": "ng",
|
|
13
|
+
"copy-onnx-wasm": "mkdir -p src/assets/onnx && cp node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded.mjs node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded.wasm src/assets/onnx/",
|
|
13
14
|
"start": "ng serve",
|
|
14
15
|
"build": "ng build",
|
|
15
16
|
"test": "ng test",
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"@ctrl/ngx-emoji-mart": "^9.2.0",
|
|
33
34
|
"@ngx-translate/core": "^16.0.4",
|
|
34
35
|
"@ngx-translate/http-loader": "^16.0.1",
|
|
36
|
+
"@ricky0123/vad-web": "^0.0.30",
|
|
35
37
|
"accept-language-parser": "^1.5.0",
|
|
36
38
|
"bootstrap": "^5.1.3",
|
|
37
39
|
"dayjs": "^1.11.7",
|
|
@@ -40,6 +42,7 @@
|
|
|
40
42
|
"humanize-duration-ts": "^2.1.1",
|
|
41
43
|
"marked": "^16.3.0",
|
|
42
44
|
"ngx-logger": "^5.0.11",
|
|
45
|
+
"onnxruntime-web": "^1.24.3",
|
|
43
46
|
"replace": "^1.2.2",
|
|
44
47
|
"rxjs": "^7.8.2",
|
|
45
48
|
"source-map-explorer": "^2.5.3",
|
package/src/app/app.component.ts
CHANGED
|
@@ -106,17 +106,16 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
106
106
|
|
|
107
107
|
forceDisconnect: boolean = false;
|
|
108
108
|
|
|
109
|
+
//network status
|
|
110
|
+
isOnline: boolean = true;
|
|
111
|
+
loading: boolean = false;
|
|
112
|
+
private calloutScheduleTimeout: any = null;
|
|
113
|
+
|
|
109
114
|
// alert error message
|
|
110
115
|
isShowErrorMessage: boolean = false;
|
|
111
116
|
errorMessage: string = '';
|
|
112
117
|
errorKeyMessage: string = null;
|
|
113
118
|
errorParams: Record<string, any> = {};
|
|
114
|
-
|
|
115
|
-
//network status
|
|
116
|
-
isOnline: boolean = true;
|
|
117
|
-
|
|
118
|
-
loading: boolean = false;
|
|
119
|
-
private calloutScheduleTimeout: any = null;
|
|
120
119
|
|
|
121
120
|
private logger: LoggerService = LoggerInstance.getInstance();
|
|
122
121
|
constructor(
|
|
@@ -170,13 +169,13 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
170
169
|
if (conversation.attributes && conversation.attributes['subtype'] === 'info') {
|
|
171
170
|
return;
|
|
172
171
|
}
|
|
173
|
-
if (conversation.is_new &&
|
|
172
|
+
if (conversation.is_new && that.isInitialized) {
|
|
174
173
|
that.manageTabNotification(false, 'conv-added')
|
|
175
174
|
// this.soundMessage();
|
|
176
175
|
}
|
|
177
|
-
if(this.g.isOpen === false){
|
|
178
|
-
that.lastConversation = conversation;
|
|
176
|
+
if(this.g.isOpen === false && conversation.sender !== this.g.senderId && !isInfo(conversation)){
|
|
179
177
|
that.g.isOpenNewMessage = true;
|
|
178
|
+
that.lastConversation = conversation;
|
|
180
179
|
}
|
|
181
180
|
} else {
|
|
182
181
|
//widget closed
|
|
@@ -224,6 +223,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
224
223
|
that.lastConversation = conversation;
|
|
225
224
|
that.g.isOpenNewMessage = true;
|
|
226
225
|
that.logger.debug('[APP-COMP] lastconversationnn', that.lastConversation)
|
|
226
|
+
that.logger.debug('[APP-COMP] lastconversationnn message' + JSON.stringify(that.lastConversation?.attributes?.commands))
|
|
227
227
|
}
|
|
228
228
|
let badgeNewConverstionNumber = that.conversationsHandlerService.countIsNew()
|
|
229
229
|
that.g.setParameter('conversationsBadge', badgeNewConverstionNumber);
|
|
@@ -2319,6 +2319,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
2319
2319
|
this.el.nativeElement.style.setProperty('--chat-header-height', this.g.hideHeaderConversation? '0px': null)
|
|
2320
2320
|
this.el.nativeElement.style.setProperty('--font-size-bubble-message', this.g.fontSize)
|
|
2321
2321
|
this.el.nativeElement.style.setProperty('--font-family-bubble-message', this.g.fontFamily)
|
|
2322
|
+
this.el.nativeElement.style.setProperty('--chat-footer-close-button-height', this.g.closeChatInConversation? '30px': '0px')
|
|
2322
2323
|
|
|
2323
2324
|
}
|
|
2324
2325
|
|
package/src/app/app.module.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { ConversationFooterComponent } from './component/conversation-detail/con
|
|
|
16
16
|
import { ConversationInternalFrameComponent } from './component/conversation-detail/conversation-internal-frame/conversation-internal-frame.component';
|
|
17
17
|
import { ConversationPreviewComponent } from './component/conversation-detail/conversation-preview/conversation-preview.component';
|
|
18
18
|
import { ConversationAudioRecorderComponent } from './component/conversation-detail/conversation-audio-recorder/conversation-audio-recorder.component';
|
|
19
|
+
import { StreamAudioSpectrumComponent } from './component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component';
|
|
19
20
|
/** CONVERSATION-DETAIL COMPONENTS */
|
|
20
21
|
import { BubbleMessageComponent } from './component/message/bubble-message/bubble-message.component';
|
|
21
22
|
import { AvatarComponent } from './component/message/avatar/avatar.component';
|
|
@@ -25,6 +26,7 @@ import { InfoMessageComponent } from './component/message/info-message/info-mess
|
|
|
25
26
|
import { HtmlComponent } from './component/message/html/html.component';
|
|
26
27
|
import { FrameComponent } from './component/message/frame/frame.component';
|
|
27
28
|
import { AudioComponent } from './component/message/audio/audio.component';
|
|
29
|
+
import { AudioSyncComponent } from './component/message/audio-sync/audio-sync.component';
|
|
28
30
|
import { UserTypingComponent } from './../chat21-core/utils/user-typing/user-typing.component';
|
|
29
31
|
/** MESSAGE ATTACHMENTS COMPONENTS */
|
|
30
32
|
import { MessageAttachmentComponent } from './component/message-attachment/message-attachment.component';
|
|
@@ -136,6 +138,11 @@ import { Rules } from './utils/rules';
|
|
|
136
138
|
import { ScriptService } from 'src/chat21-core/providers/scripts/script.service';
|
|
137
139
|
import { CarouselComponent } from './component/message/carousel/carousel.component';
|
|
138
140
|
import { BrandService } from './providers/brand.service';
|
|
141
|
+
import { OpenAiVoiceProviderService } from './providers/voice/STT&TTS/openai-voice.provider';
|
|
142
|
+
import {
|
|
143
|
+
SpeechToTextProvider,
|
|
144
|
+
TextToSpeechProvider,
|
|
145
|
+
} from './providers/voice/STT&TTS/speech-provider.abstract';
|
|
139
146
|
import { ErrorAlertComponent } from './component/error-alert/error-alert.component';
|
|
140
147
|
import { ConfirmCloseComponent } from './modals/confirm-close/confirm-close.component';
|
|
141
148
|
|
|
@@ -288,6 +295,7 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
|
|
|
288
295
|
ConversationPreviewComponent,
|
|
289
296
|
ConversationInternalFrameComponent,
|
|
290
297
|
ConversationAudioRecorderComponent,
|
|
298
|
+
StreamAudioSpectrumComponent,
|
|
291
299
|
BubbleMessageComponent,
|
|
292
300
|
AvatarComponent,
|
|
293
301
|
FrameComponent,
|
|
@@ -300,6 +308,7 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
|
|
|
300
308
|
LinkButtonComponent,
|
|
301
309
|
TextButtonComponent,
|
|
302
310
|
AudioComponent,
|
|
311
|
+
AudioSyncComponent,
|
|
303
312
|
UserTypingComponent,
|
|
304
313
|
/**DIRECTIVES */
|
|
305
314
|
HtmlEntitiesEncodePipe,
|
|
@@ -405,6 +414,8 @@ export function uploadFactory(http: HttpClient, appConfig: AppConfigService, app
|
|
|
405
414
|
WaitingService,
|
|
406
415
|
ScriptService,
|
|
407
416
|
BrandService,
|
|
417
|
+
{ provide: SpeechToTextProvider, useExisting: OpenAiVoiceProviderService },
|
|
418
|
+
{ provide: TextToSpeechProvider, useExisting: OpenAiVoiceProviderService },
|
|
408
419
|
provideHttpClient(withInterceptorsFromDi())
|
|
409
420
|
],
|
|
410
421
|
bootstrap: [AppComponent]
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
<div id="chat21-conversation-component"
|
|
5
5
|
#afConversationComponent
|
|
6
6
|
tabindex="1500"
|
|
7
|
-
aria-modal="true"
|
|
7
|
+
aria-modal="true"
|
|
8
|
+
[class.chat21-conversation--close-stream-active]="closeStreamButtonActiveForSheetBottom()">
|
|
8
9
|
|
|
9
10
|
<!-- HEADER -->
|
|
10
11
|
<chat-conversation-header
|
|
@@ -64,7 +65,9 @@
|
|
|
64
65
|
[nameUserTypingNow]="nameUserTypingNow"
|
|
65
66
|
[typingLocation]="g?.typingLocation"
|
|
66
67
|
[showThinkingMessage]="showThinkingMessage"
|
|
68
|
+
[lastServerSenderKind]="lastServerSenderKind"
|
|
67
69
|
[fullscreenMode]="g?.fullscreenMode"
|
|
70
|
+
[isStreamAudioActive]="isStreamAudioActive"
|
|
68
71
|
[translationMap]="translationMapContent"
|
|
69
72
|
[stylesMap]="stylesMap"
|
|
70
73
|
(onBeforeMessageRender)="onBeforeMessageRenderFN($event)"
|
|
@@ -131,12 +134,14 @@
|
|
|
131
134
|
[showAttachmentFooterButton]="g?.showAttachmentFooterButton"
|
|
132
135
|
[showEmojiFooterButton]="g?.showEmojiFooterButton"
|
|
133
136
|
[showAudioRecorderFooterButton]="g?.showAudioRecorderFooterButton"
|
|
137
|
+
[showAudioStreamFooterButton]="g?.showAudioStreamFooterButton"
|
|
134
138
|
[hideTextAreaContent]="(g?.singleConversation && hideTextAreaContent) || (isConversationArchived && !g?.allowReopen)"
|
|
135
139
|
[isConversationArchived]="isConversationArchived"
|
|
136
140
|
[hideTextReply]="hideFooterTextReply"
|
|
137
141
|
[isMobile]="g?.isMobile"
|
|
138
142
|
[isEmojiiPickerShow]="isEmojiiPickerShow"
|
|
139
143
|
[footerMessagePlaceholder]="footerMessagePlaceholder"
|
|
144
|
+
[closeChatInConversation]="g?.closeChatInConversation"
|
|
140
145
|
[fileUploadAccept]="g?.fileUploadAccept"
|
|
141
146
|
[dropEvent]="dropEvent"
|
|
142
147
|
[poweredBy]="g?.poweredBy"
|
|
@@ -147,7 +152,9 @@
|
|
|
147
152
|
(onAfterSendMessage)="onAfterSendMessageFN($event)"
|
|
148
153
|
(onChangeTextArea)="onChangeTextArea($event)"
|
|
149
154
|
(onAttachmentFileButtonClicked)="onAttachmentFileButtonClicked($event)"
|
|
150
|
-
(onNewConversationButtonClicked)="onNewConversationButtonClickedFN($event)"
|
|
155
|
+
(onNewConversationButtonClicked)="onNewConversationButtonClickedFN($event)"
|
|
156
|
+
(onStreamAudioActiveChange)="onStreamAudioActiveChange($event)"
|
|
157
|
+
(onCloseChatButtonClicked)="onCloseChatButtonClickedFN($event)">
|
|
151
158
|
</chat-conversation-footer>
|
|
152
159
|
|
|
153
160
|
</div>
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
#dropZone_container{
|
|
138
138
|
position: absolute;
|
|
139
139
|
top: 52px;
|
|
140
|
-
bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height));
|
|
140
|
+
bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height) + var(--chat-footer-close-button-height));
|
|
141
141
|
left: 0;
|
|
142
142
|
right: 0;
|
|
143
143
|
background-color: rgba(240,248,255,0.6);
|
|
@@ -240,7 +240,17 @@ dialog:-internal-dialog-in-top-layer{
|
|
|
240
240
|
|
|
241
241
|
|
|
242
242
|
::ng-deep .chat21-sheet-content{
|
|
243
|
-
bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height) + 34px)!important;
|
|
243
|
+
bottom: calc(var(--chat-footer-logo-height) + var(--chat-footer-height) + var(--chat-footer-close-button-height) + 34px)!important;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* Con `.close-stream-button` (stream in ascolto): spazio per alert stream sopra il footer */
|
|
247
|
+
#chat21-conversation-component.chat21-conversation--close-stream-active ::ng-deep .chat21-sheet-content {
|
|
248
|
+
bottom: calc(
|
|
249
|
+
var(--chat-footer-logo-height) +
|
|
250
|
+
var(--chat-footer-height) +
|
|
251
|
+
var(--chat-footer-stream-button-height) +
|
|
252
|
+
34px
|
|
253
|
+
) !important;
|
|
244
254
|
}
|
|
245
255
|
|
|
246
256
|
}
|