@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.
Files changed (64) hide show
  1. package/.github/workflows/docker-community-push-latest.yml +23 -13
  2. package/.github/workflows/docker-image-tag-community-tag-push.yml +22 -12
  3. package/CHANGELOG.md +89 -2
  4. package/Dockerfile +4 -5
  5. package/angular.json +5 -2
  6. package/deploy_amazon_beta.sh +17 -7
  7. package/docs/changelog/this-branch.md +36 -0
  8. package/nginx.conf +22 -2
  9. package/package.json +4 -1
  10. package/src/app/app.component.ts +10 -9
  11. package/src/app/app.module.ts +11 -0
  12. package/src/app/component/conversation-detail/conversation/conversation.component.html +9 -2
  13. package/src/app/component/conversation-detail/conversation/conversation.component.scss +12 -2
  14. package/src/app/component/conversation-detail/conversation/conversation.component.ts +46 -5
  15. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +9 -5
  16. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +19 -1
  17. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +2 -0
  18. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +128 -80
  19. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +117 -13
  20. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +120 -8
  21. package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.html +43 -0
  22. package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.scss +79 -0
  23. package/src/app/component/conversation-detail/stream-audio-spectrum/stream-audio-spectrum.component.ts +192 -0
  24. package/src/app/component/last-message/last-message.component.ts +4 -1
  25. package/src/app/component/message/audio/audio.component.ts +0 -5
  26. package/src/app/component/message/audio-sync/audio-sync.component.html +18 -0
  27. package/src/app/component/message/audio-sync/audio-sync.component.scss +64 -0
  28. package/src/app/component/message/audio-sync/audio-sync.component.spec.ts +23 -0
  29. package/src/app/component/message/audio-sync/audio-sync.component.ts +558 -0
  30. package/src/app/component/message/bubble-message/bubble-message.component.html +6 -1
  31. package/src/app/component/message/bubble-message/bubble-message.component.ts +2 -1
  32. package/src/app/providers/global-settings.service.ts +21 -0
  33. package/src/app/providers/translator.service.ts +2 -0
  34. package/src/app/providers/tts-audio-playback-coordinator.service.ts +93 -0
  35. package/src/app/providers/voice/STT&TTS/openai-voice.config.ts +12 -0
  36. package/src/app/providers/voice/STT&TTS/openai-voice.provider.ts +171 -0
  37. package/src/app/providers/voice/STT&TTS/speech-provider.abstract.ts +39 -0
  38. package/src/app/providers/voice/audio.types.ts +34 -0
  39. package/src/app/providers/voice/vad.service.spec.ts +28 -0
  40. package/src/app/providers/voice/vad.service.ts +70 -0
  41. package/src/app/providers/voice/voice.service.spec.ts +60 -0
  42. package/src/app/providers/voice/voice.service.ts +376 -0
  43. package/src/app/sass/_variables.scss +3 -0
  44. package/src/app/shims/onnxruntime-web-wasm.ts +4 -0
  45. package/src/app/utils/conversation-sender-classifier.ts +21 -0
  46. package/src/app/utils/globals.ts +7 -1
  47. package/src/assets/i18n/en.json +1 -0
  48. package/src/assets/i18n/es.json +1 -0
  49. package/src/assets/i18n/fr.json +1 -0
  50. package/src/assets/i18n/it.json +1 -0
  51. package/src/assets/onnx/ort-wasm-simd-threaded.mjs +59 -0
  52. package/src/assets/onnx/ort-wasm-simd-threaded.wasm +0 -0
  53. package/src/assets/vad/silero_vad_legacy.onnx +0 -0
  54. package/src/assets/vad/vad.worklet.bundle.min.js +1 -0
  55. package/src/chat21-core/models/message.ts +2 -1
  56. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +3 -2
  57. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +12 -0
  58. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  59. package/src/chat21-core/utils/utils-message.ts +7 -0
  60. package/src/chat21-core/utils/utils.ts +5 -2
  61. package/src/launch.js +41 -32
  62. package/src/launch_template.js +41 -32
  63. package/tsconfig.json +5 -0
  64. 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
- - uses: actions/checkout@v2
16
- name: Check out the repo
17
- - uses: docker/build-push-action@v1
18
- with:
19
- username: ${{ secrets.DOCKERHUB_USERNAME }}
20
- password: ${{ secrets.DOCKERHUB_TOKEN }}
21
- repository: chat21/chat21-web-widget
22
- push: true
23
- tags: latest
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
- - '**' # Push events to every tag including hierarchical tags like
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
- - name: Check out the repo
14
- uses: actions/checkout@v2
15
- - name: Push to Docker Hub
16
- uses: docker/build-push-action@v1
17
- with:
18
- username: ${{ secrets.DOCKERHUB_USERNAME }}
19
- password: ${{ secrets.DOCKERHUB_TOKEN }}
20
- repository: chat21/chat21-web-widget
21
- push: true
22
- tag_with_ref: true
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.28
13
- - **bug fixed**: header option menu is deactivated on mobile
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", "-c", "envsubst < /usr/share/nginx/html/widget-config-template.json > /usr/share/nginx/html/widget-config.json && exec nginx -g 'daemon off;'"]
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,
@@ -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 max-age=300
29
- cd ..
30
-
31
- #aws cloudfront create-invalidation --distribution-id E3EJDWEHY08CZZ --paths "/*"
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.30",
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",
@@ -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 && this.isInitialized) {
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
 
@@ -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
  }