mirror of
https://github.com/leon-ai/leon.git
synced 2024-11-28 12:43:35 +03:00
feat: communicate suggestions to the client
This commit is contained in:
parent
192dd0a87a
commit
4b5a883510
@ -46,6 +46,11 @@ table {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
:root {
|
||||
--black-color: #151718;
|
||||
--white-color: #FFF;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
@ -55,8 +60,8 @@ ul li {
|
||||
}
|
||||
|
||||
body {
|
||||
color: #FFF;
|
||||
background-color: #151718;
|
||||
color: var(--white-color);
|
||||
background-color: var(--black-color);
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
@ -107,10 +112,10 @@ footer {
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
color: var(--white-color);
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-bottom: 2px solid #FFF;
|
||||
border-bottom: 2px solid var(--white-color);
|
||||
background: none;
|
||||
font-weight: 400;
|
||||
font-size: 4em;
|
||||
@ -118,7 +123,7 @@ input {
|
||||
}
|
||||
|
||||
small {
|
||||
color: #FFF;
|
||||
color: var(--white-color);
|
||||
font-size: .7em;
|
||||
}
|
||||
|
||||
@ -139,7 +144,7 @@ small {
|
||||
top: 10%;
|
||||
height: 50%;
|
||||
overflow-y: auto;
|
||||
border: 2px solid #FFF;
|
||||
border: 2px solid var(--white-color);
|
||||
border-radius: 12px;
|
||||
}
|
||||
#feed::-webkit-scrollbar {
|
||||
@ -172,7 +177,7 @@ small {
|
||||
border-radius: 50%;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: #FFF;
|
||||
background-color: var(--white-color);
|
||||
transform: scale(1);
|
||||
}
|
||||
#is-typing .circle:nth-child(1) {
|
||||
@ -181,7 +186,7 @@ small {
|
||||
}
|
||||
#is-typing .circle:nth-child(2) {
|
||||
animation: typing .2s .2s linear infinite alternate;
|
||||
background-color: #FFF;
|
||||
background-color: var(--white-color);
|
||||
}
|
||||
#is-typing .circle:nth-child(3) {
|
||||
animation: typing .2s linear infinite alternate;
|
||||
@ -215,12 +220,12 @@ small {
|
||||
}
|
||||
#feed .me .bubble {
|
||||
background-color: #1C75DB;
|
||||
color: #FFF;
|
||||
color: var(--white-color);
|
||||
right: 0;
|
||||
}
|
||||
#feed .leon .bubble {
|
||||
background-color: #EEE;
|
||||
color: #151718;
|
||||
color: var(--black-color);
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
100% {
|
||||
@ -228,10 +233,35 @@ small {
|
||||
}
|
||||
}
|
||||
|
||||
#suggestions-container {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
bottom: 36%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
column-gap: 8px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.suggestion {
|
||||
border: 1px solid var(--white-color);
|
||||
background-color: transparent;
|
||||
color: var(--white-color);
|
||||
border-radius: 8px;
|
||||
padding: 2px 8px;
|
||||
font-size: inherit;
|
||||
cursor: pointer;
|
||||
transition: background-color .2s, color .2s;
|
||||
}
|
||||
.suggestion:hover {
|
||||
color: var(--black-color);
|
||||
background-color: var(--white-color);
|
||||
}
|
||||
|
||||
#input-container {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: 25%;
|
||||
bottom: 22%;
|
||||
}
|
||||
|
||||
#mic-container {
|
||||
@ -244,7 +274,7 @@ small {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
button {
|
||||
#mic-button {
|
||||
position: absolute;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
@ -256,16 +286,16 @@ button {
|
||||
mask-image: url(../img/mic.svg);
|
||||
transition: background-color .2s;
|
||||
}
|
||||
button:not(.enabled) {
|
||||
#mic-button:not(.enabled) {
|
||||
margin-left: -26px;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #FFF;
|
||||
#mic-button:hover {
|
||||
background-color: var(--white-color);
|
||||
}
|
||||
button.enabled {
|
||||
#mic-button.enabled {
|
||||
background-color: #00E676;
|
||||
}
|
||||
button.enabled + #sonar {
|
||||
#mic-button.enabled + #sonar {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border-radius: 50%;
|
||||
|
@ -14,6 +14,7 @@
|
||||
You can start to interact with Leon, don't be shy.
|
||||
</p>
|
||||
</div>
|
||||
<div id="suggestions-container"></div>
|
||||
<div id="is-typing">
|
||||
<div class="circle"></div>
|
||||
<div class="circle"></div>
|
||||
@ -21,7 +22,7 @@
|
||||
</div>
|
||||
<div id="input-container">
|
||||
<div id="mic-container">
|
||||
<button></button>
|
||||
<button id="mic-button"></button>
|
||||
<div id="sonar"></div>
|
||||
</div>
|
||||
<label for="utterance"></label>
|
||||
|
@ -2,9 +2,10 @@ import { io } from 'socket.io-client'
|
||||
import Chatbot from './chatbot'
|
||||
|
||||
export default class Client {
|
||||
constructor (client, serverUrl, input, res) {
|
||||
constructor (client, serverUrl, input, suggestionsContainer, res) {
|
||||
this.client = client
|
||||
this._input = input
|
||||
this._suggestionContainer = suggestionsContainer
|
||||
this.serverUrl = serverUrl
|
||||
this.socket = io(this.serverUrl)
|
||||
this.history = localStorage.getItem('history')
|
||||
@ -43,6 +44,13 @@ export default class Client {
|
||||
this.chatbot.receivedFrom('leon', data)
|
||||
})
|
||||
|
||||
this.socket.on('suggest', (data) => {
|
||||
data.forEach((suggestion) => {
|
||||
this._suggestionContainer.innerHTML
|
||||
+= `<button class="suggestion">${suggestion}</button>`
|
||||
})
|
||||
})
|
||||
|
||||
this.socket.on('is-typing', (data) => {
|
||||
this.chatbot.isTyping('leon', data)
|
||||
})
|
||||
|
@ -26,10 +26,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
console.error(err.response.error.message)
|
||||
} else {
|
||||
const input = document.querySelector('#utterance')
|
||||
const mic = document.querySelector('button')
|
||||
const mic = document.querySelector('#mic-button')
|
||||
const v = document.querySelector('#version small')
|
||||
const logger = document.querySelector('#logger small')
|
||||
const client = new Client(config.app, serverUrl, input, res.body)
|
||||
const suggestionsContainer = document.querySelector('#suggestions-container')
|
||||
const client = new Client(config.app, serverUrl, input, suggestionsContainer, res.body)
|
||||
let rec = { }
|
||||
let chunks = []
|
||||
let sLogger = ' enabled, thank you.'
|
||||
|
@ -161,9 +161,14 @@ class Brain {
|
||||
const { nluDataFilePath, classification: { action: actionName } } = obj
|
||||
const { actions } = JSON.parse(fs.readFileSync(nluDataFilePath, 'utf8'))
|
||||
const action = actions[actionName]
|
||||
const { type: actionType } = action
|
||||
const { type: actionType, suggestions } = action
|
||||
const nextAction = action.next_action ? actions[action.next_action] : null
|
||||
|
||||
// Send suggestions to the client if this action does not contain an action loop
|
||||
if (suggestions && !action.loop) {
|
||||
this._socket.emit('suggest', suggestions)
|
||||
}
|
||||
|
||||
if (actionType === 'logic') {
|
||||
/**
|
||||
* "Logic" action skill execution
|
||||
|
@ -188,7 +188,9 @@ class Nlu {
|
||||
|
||||
const { actions } = JSON.parse(fs.readFileSync(nluDataFilePath, 'utf8'))
|
||||
const action = actions[this.nluResultObj.classification.action]
|
||||
const { name: expectedItemName, type: expectedItemType } = action.loop.expected_item
|
||||
const {
|
||||
name: expectedItemName, type: expectedItemType
|
||||
} = action.loop.expected_item
|
||||
let hasMatchingEntity = false
|
||||
let hasMatchingResolver = false
|
||||
|
||||
@ -244,6 +246,11 @@ class Nlu {
|
||||
|
||||
// Break the action loop and prepare for the next action if necessary
|
||||
if (processedData.core?.isInActionLoop === false) {
|
||||
// Send suggestions to the client only at the end of the action loop
|
||||
if (action.suggestions) {
|
||||
this.brain.socket.emit('suggest', action.suggestions)
|
||||
}
|
||||
|
||||
this.conv.activeContext.isInActionLoop = !!processedData.action.loop
|
||||
this.conv.activeContext.actionName = processedData.action.next_action
|
||||
this.conv.activeContext.intent = `${processedData.classification.skill}.${processedData.action.next_action}`
|
||||
|
@ -18,6 +18,10 @@
|
||||
"name": "number"
|
||||
}
|
||||
},
|
||||
"suggestions": [
|
||||
"Yes",
|
||||
"No thanks"
|
||||
],
|
||||
"next_action": "replay"
|
||||
},
|
||||
"replay": {
|
||||
|
@ -13,6 +13,11 @@
|
||||
"1, 2, 3, FIRE!",
|
||||
"Rock, paper, scissors..."
|
||||
],
|
||||
"suggestions": [
|
||||
"Rock ✊",
|
||||
"Paper ✋",
|
||||
"Scissors ✌"
|
||||
],
|
||||
"next_action": "play"
|
||||
},
|
||||
"play": {
|
||||
@ -23,6 +28,10 @@
|
||||
"name": "handsign"
|
||||
}
|
||||
},
|
||||
"suggestions": [
|
||||
"Yes",
|
||||
"No thanks"
|
||||
],
|
||||
"next_action": "rematch"
|
||||
},
|
||||
"rematch": {
|
||||
|
Loading…
Reference in New Issue
Block a user